diff --git a/src/diffviewer/ydiff.c b/src/diffviewer/ydiff.c index 6f7caf2395..b543186bd2 100644 --- a/src/diffviewer/ydiff.c +++ b/src/diffviewer/ydiff.c @@ -3460,6 +3460,12 @@ dview_diff_cmd (const void *f0, const void *f1) const file_entry_t *fe0, *fe1; fe0 = panel_current_entry (panel0); + if (fe0 == NULL) + { + message (D_ERROR, MSG_ERROR, "%s", _("File name is empty!")); + goto ret; + } + file0 = vfs_path_append_new (panel0->cwd_vpath, fe0->fname->str, (char *) NULL); is_dir0 = S_ISDIR (fe0->st.st_mode); if (is_dir0) @@ -3470,6 +3476,11 @@ dview_diff_cmd (const void *f0, const void *f1) } fe1 = panel_current_entry (panel1); + if (fe1 == NULL) + { + message (D_ERROR, MSG_ERROR, "%s", _("File name is empty!")); + goto ret; + } file1 = vfs_path_append_new (panel1->cwd_vpath, fe1->fname->str, (char *) NULL); is_dir1 = S_ISDIR (fe1->st.st_mode); if (is_dir1) diff --git a/src/filemanager/achown.c b/src/filemanager/achown.c index a4ef1f5bbd..df17e3c525 100644 --- a/src/filemanager/achown.c +++ b/src/filemanager/achown.c @@ -831,17 +831,6 @@ advanced_chown_done (gboolean need_update) /* --------------------------------------------------------------------------------------------- */ -static const GString * -next_file (const WPanel *panel) -{ - while (panel->dir.list[current_file].f.marked == 0) - current_file++; - - return panel->dir.list[current_file].fname; -} - -/* --------------------------------------------------------------------------------------------- */ - static gboolean try_advanced_chown (const vfs_path_t *p, mode_t m, uid_t u, gid_t g) { @@ -957,7 +946,7 @@ apply_advanced_chowns (WPanel *panel, vfs_path_t *vpath, struct stat *sf) { const GString *fname; - fname = next_file (panel); + fname = panel_find_marked_file (panel, ¤t_file); vpath = vfs_path_from_str (fname->str); ok = (mc_stat (vpath, sf) == 0); @@ -1017,10 +1006,9 @@ advanced_chown_cmd (WPanel *panel) need_update = FALSE; end_chown = FALSE; - if (panel->marked != 0) - fname = next_file (panel); /* next marked file */ - else - fname = panel_current_entry (panel)->fname; /* single file */ + fname = panel_get_marked_file (panel, ¤t_file); + if (fname == NULL) + break; vpath = vfs_path_from_str (fname->str); diff --git a/src/filemanager/chattr.c b/src/filemanager/chattr.c index 91159d4c41..269e2aadd1 100644 --- a/src/filemanager/chattr.c +++ b/src/filemanager/chattr.c @@ -1087,17 +1087,6 @@ chattr_done (gboolean need_update) /* --------------------------------------------------------------------------------------------- */ -static const GString * -next_file (const WPanel *panel) -{ - while (panel->dir.list[current_file].f.marked == 0) - current_file++; - - return panel->dir.list[current_file].fname; -} - -/* --------------------------------------------------------------------------------------------- */ - static gboolean try_chattr (const vfs_path_t *p, unsigned long m) { @@ -1173,7 +1162,7 @@ chattr_apply_mask (WPanel *panel, vfs_path_t *vpath, unsigned long m) { const GString *fname; - fname = next_file (panel); + fname = panel_find_marked_file (panel, ¤t_file); vpath = vfs_path_from_str (fname->str); ok = (mc_fgetflags (vpath, &m) == 0); @@ -1224,10 +1213,9 @@ chattr_cmd (WPanel *panel) need_update = FALSE; end_chattr = FALSE; - if (panel->marked != 0) - fname = next_file (panel); /* next marked file */ - else - fname = panel_current_entry (panel)->fname; /* single file */ + fname = panel_get_marked_file (panel, ¤t_file); + if (fname == NULL) + break; vpath = vfs_path_from_str (fname->str); diff --git a/src/filemanager/chmod.c b/src/filemanager/chmod.c index 7467b40435..8093d08ceb 100644 --- a/src/filemanager/chmod.c +++ b/src/filemanager/chmod.c @@ -410,17 +410,6 @@ chmod_done (gboolean need_update) /* --------------------------------------------------------------------------------------------- */ -static const GString * -next_file (const WPanel *panel) -{ - while (panel->dir.list[current_file].f.marked == 0) - current_file++; - - return panel->dir.list[current_file].fname; -} - -/* --------------------------------------------------------------------------------------------- */ - static gboolean try_chmod (const vfs_path_t *p, mode_t m) { @@ -496,7 +485,7 @@ apply_mask (WPanel *panel, vfs_path_t *vpath, struct stat *sf) { const GString *fname; - fname = next_file (panel); + fname = panel_find_marked_file (panel, ¤t_file); vpath = vfs_path_from_str (fname->str); ok = (mc_stat (vpath, sf) == 0); @@ -549,10 +538,9 @@ chmod_cmd (WPanel *panel) need_update = FALSE; end_chmod = FALSE; - if (panel->marked != 0) - fname = next_file (panel); /* next marked file */ - else - fname = panel_current_entry (panel)->fname; /* single file */ + fname = panel_get_marked_file (panel, ¤t_file); + if (fname == NULL) + break; vpath = vfs_path_from_str (fname->str); diff --git a/src/filemanager/chown.c b/src/filemanager/chown.c index 174b930492..132d52d49a 100644 --- a/src/filemanager/chown.c +++ b/src/filemanager/chown.c @@ -282,17 +282,6 @@ chown_done (gboolean need_update) /* --------------------------------------------------------------------------------------------- */ -static const GString * -next_file (const WPanel *panel) -{ - while (panel->dir.list[current_file].f.marked == 0) - current_file++; - - return panel->dir.list[current_file].fname; -} - -/* --------------------------------------------------------------------------------------------- */ - static gboolean try_chown (const vfs_path_t *p, uid_t u, gid_t g) { @@ -366,7 +355,7 @@ apply_chowns (WPanel *panel, vfs_path_t *vpath, uid_t u, gid_t g) const GString *fname; struct stat sf; - fname = next_file (panel); + fname = panel_find_marked_file (panel, ¤t_file); vpath = vfs_path_from_str (fname->str); ok = (mc_stat (vpath, &sf) == 0); @@ -418,10 +407,9 @@ chown_cmd (WPanel *panel) need_update = FALSE; end_chown = FALSE; - if (panel->marked != 0) - fname = next_file (panel); /* next marked file */ - else - fname = panel_current_entry (panel)->fname; /* single file */ + fname = panel_get_marked_file (panel, ¤t_file); + if (fname == NULL) + break; vpath = vfs_path_from_str (fname->str); diff --git a/src/filemanager/cmd.c b/src/filemanager/cmd.c index b1fd211422..acc53db608 100644 --- a/src/filemanager/cmd.c +++ b/src/filemanager/cmd.c @@ -125,6 +125,8 @@ do_view_cmd (WPanel *panel, gboolean plain_view) const file_entry_t *fe; fe = panel_current_entry (panel); + if (fe == NULL) + return; /* Directories are viewed by changing to them */ if (S_ISDIR (fe->st.st_mode) || link_isdir (fe)) @@ -576,12 +578,16 @@ view_cmd (WPanel *panel) void view_file_cmd (const WPanel *panel) { + const file_entry_t *fe; char *filename; vfs_path_t *vpath; + fe = panel_current_entry (panel); + if (fe == NULL) + return; + filename = - input_expand_dialog (_("View file"), _("Filename:"), - MC_HISTORY_FM_VIEW_FILE, panel_current_entry (panel)->fname->str, + input_expand_dialog (_("View file"), _("Filename:"), MC_HISTORY_FM_VIEW_FILE, fe->fname->str, INPUT_COMPLETE_FILENAMES); if (filename == NULL) return; @@ -609,7 +615,15 @@ view_filtered_cmd (const WPanel *panel) const char *initial_command; if (input_is_empty (cmdline)) - initial_command = panel_current_entry (panel)->fname->str; + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + initial_command = fe->fname->str; + } else initial_command = input_get_ctext (cmdline); @@ -673,9 +687,14 @@ edit_file_at_line (const vfs_path_t *what_vpath, gboolean internal, long start_l void edit_cmd (const WPanel *panel) { + const file_entry_t *fe; vfs_path_t *fname; - fname = vfs_path_from_str (panel_current_entry (panel)->fname->str); + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + fname = vfs_path_from_str (fe->fname->str); if (regex_command (fname, "Edit") == 0) do_edit (fname); vfs_path_free (fname, TRUE); @@ -687,9 +706,14 @@ edit_cmd (const WPanel *panel) void edit_cmd_force_internal (const WPanel *panel) { + const file_entry_t *fe; vfs_path_t *fname; - fname = vfs_path_from_str (panel_current_entry (panel)->fname->str); + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + fname = vfs_path_from_str (fe->fname->str); if (regex_command (fname, "Edit") == 0) edit_file_at_line (fname, TRUE, 1); vfs_path_free (fname, TRUE); @@ -736,6 +760,8 @@ mkdir_cmd (WPanel *panel) const char *name = ""; fe = panel_current_entry (panel); + if (fe == NULL) + return; /* If 'on' then automatically fills name with current item name */ if (auto_fill_mkdir_name && !DIR_IS_DOTDOT (fe->fname->str)) @@ -1055,11 +1081,11 @@ swap_cmd (void) void link_cmd (link_type_t link_type) { - const char *filename; + const file_entry_t *fe; - filename = panel_current_entry (current_panel)->fname->str; - if (filename != NULL) - do_link (link_type, filename); + fe = panel_current_entry (current_panel); + if (fe != NULL) + do_link (link_type, fe->fname->str); } /* --------------------------------------------------------------------------------------------- */ @@ -1071,6 +1097,9 @@ edit_symlink_cmd (void) const char *p; fe = panel_current_entry (current_panel); + if (fe == NULL) + return; + p = fe->fname->str; if (!S_ISLNK (fe->st.st_mode)) @@ -1218,7 +1247,8 @@ smart_dirsize_cmd (WPanel *panel) const file_entry_t *entry; entry = panel_current_entry (panel); - if ((S_ISDIR (entry->st.st_mode) && DIR_IS_DOTDOT (entry->fname->str)) || panel->dirs_marked) + if ((entry != NULL && S_ISDIR (entry->st.st_mode) && DIR_IS_DOTDOT (entry->fname->str)) + || panel->dirs_marked) dirsizes_cmd (panel); else single_dirsize_cmd (panel); @@ -1233,7 +1263,7 @@ single_dirsize_cmd (WPanel *panel) entry = panel_current_entry (panel); - if (S_ISDIR (entry->st.st_mode) && !DIR_IS_DOTDOT (entry->fname->str)) + if (entry != NULL && S_ISDIR (entry->st.st_mode) && !DIR_IS_DOTDOT (entry->fname->str)) { size_t dir_count = 0; size_t count = 0; diff --git a/src/filemanager/file.c b/src/filemanager/file.c index e1568095d4..cc0696055f 100644 --- a/src/filemanager/file.c +++ b/src/filemanager/file.c @@ -1751,6 +1751,8 @@ do_move_dir_dir (const WPanel *panel, file_op_total_context_t *tctx, file_op_con static const char * panel_get_file (const WPanel *panel) { + const file_entry_t *fe; + if (get_current_type () == view_tree) { WTree *tree; @@ -1770,7 +1772,9 @@ panel_get_file (const WPanel *panel) return panel->dir.list[i].fname->str; } - return panel_current_entry (panel)->fname->str; + fe = panel_current_entry (panel); + + return (fe == NULL ? NULL : fe->fname->str); } /* --------------------------------------------------------------------------------------------- */ @@ -1782,10 +1786,18 @@ check_single_entry (const WPanel *panel, gboolean force_single, struct stat *src gboolean ok; if (force_single) - source = panel_current_entry (panel)->fname->str; + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + source = fe == NULL ? NULL : fe->fname->str; + } else source = panel_get_file (panel); + if (source == NULL) + return NULL; + ok = !DIR_IS_DOTDOT (source); if (!ok) @@ -3529,9 +3541,12 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl else #endif /* ENABLE_BACKGROUND */ { + const file_entry_t *fe; + if (operation == OP_DELETE) dialog_type = FILEGUI_DIALOG_DELETE_ITEM; - else if (single_entry && S_ISDIR (panel_current_entry (panel)->st.st_mode)) + else if (single_entry + && ((fe = panel_current_entry (panel)) == NULL ? FALSE : S_ISDIR (fe->st.st_mode))) dialog_type = FILEGUI_DIALOG_MULTI_ITEM; else if (single_entry || force_single) dialog_type = FILEGUI_DIALOG_ONE_ITEM; diff --git a/src/filemanager/filemanager.c b/src/filemanager/filemanager.c index b31dda570a..7291b896ea 100644 --- a/src/filemanager/filemanager.c +++ b/src/filemanager/filemanager.c @@ -150,9 +150,14 @@ stop_dialogs (void) static void treebox_cmd (void) { + const file_entry_t *fe; char *sel_dir; - sel_dir = tree_box (panel_current_entry (current_panel)->fname->str); + fe = panel_current_entry (current_panel); + if (fe == NULL) + return; + + sel_dir = tree_box (fe->fname->str); if (sel_dir != NULL) { vfs_path_t *sel_vdir; @@ -720,7 +725,7 @@ put_link (WPanel *panel) fe = panel_current_entry (panel); - if (S_ISLNK (fe->st.st_mode)) + if (fe != NULL && S_ISLNK (fe->st.st_mode)) { char buffer[MC_MAXPATHLEN]; vfs_path_t *vpath; @@ -761,8 +766,6 @@ put_other_link (void) static void put_current_selected (void) { - const char *tmp; - if (!command_prompt) return; @@ -773,12 +776,16 @@ put_current_selected (void) tree = (WTree *) get_panel_widget (get_current_index ()); selected_name = tree_selected_name (tree); - tmp = vfs_path_as_str (selected_name); + command_insert (cmdline, vfs_path_as_str (selected_name), TRUE); } else - tmp = panel_current_entry (current_panel)->fname->str; + { + const file_entry_t *fe; - command_insert (cmdline, tmp, TRUE); + fe = panel_current_entry (current_panel); + if (fe != NULL) + command_insert (cmdline, fe->fname->str, TRUE); + } } /* --------------------------------------------------------------------------------------------- */ @@ -792,7 +799,13 @@ put_tagged (WPanel *panel) input_disable_update (cmdline); if (panel->marked == 0) - command_insert (cmdline, panel_current_entry (panel)->fname->str, TRUE); + { + const file_entry_t *fe; + + fe = panel_current_entry (current_panel); + if (fe != NULL) + command_insert (cmdline, fe->fname->str, TRUE); + } else { int i; diff --git a/src/filemanager/info.c b/src/filemanager/info.c index 419820e090..c8570d8fb0 100644 --- a/src/filemanager/info.c +++ b/src/filemanager/info.c @@ -138,6 +138,8 @@ info_show_info (WInfo *info) my_statfs (&myfs_stats, p_rp_cwd); fe = panel_current_entry (current_panel); + if (fe == NULL) + return; st = fe->st; diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c index 1f96c2dd14..43540ad21f 100644 --- a/src/filemanager/layout.c +++ b/src/filemanager/layout.c @@ -1199,7 +1199,13 @@ create_panel (int num, panel_view_mode_t type) new_widget = WIDGET (mcview_new (&r, TRUE)); the_other_panel = PANEL (panels[the_other].widget); if (the_other_panel != NULL) - file_name = panel_current_entry (the_other_panel)->fname->str; + { + const file_entry_t *fe; + + fe = panel_current_entry (the_other_panel); + if (fe != NULL) + file_name = fe->fname->str; + } mcview_load ((WView *) new_widget, 0, file_name, 0, 0, 0); break; diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 4506cbff6e..44b25bd416 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -837,7 +837,7 @@ format_file (WPanel *panel, int file_index, int width, file_attr_t attr, gboolea *field_length = 0; - if (file_index < panel->dir.len) + if (panel->dir.len != 0 && file_index < panel->dir.len) { fe = &panel->dir.list[file_index]; color = file_compute_color (attr, fe); @@ -1039,7 +1039,7 @@ display_mini_info (WPanel *panel) Widget *w = WIDGET (panel); const file_entry_t *fe; - if (!panels_options.show_mini_info || panel->current < 0) + if (!panels_options.show_mini_info) return; widget_gotoyx (w, panel_lines (panel) + 3, 1); @@ -1058,7 +1058,10 @@ display_mini_info (WPanel *panel) fe = panel_current_entry (panel); - if (S_ISLNK (fe->st.st_mode)) + if (fe == NULL) + /* NULL is in case of filter that doesn't match anything */ + repaint_status (panel); + else if (S_ISLNK (fe->st.st_mode)) { char link_target[MC_MAXPATHLEN]; vfs_path_t *lc_link_vpath; @@ -1375,8 +1378,8 @@ show_dir (const WPanel *panel) fe = panel_current_entry (panel); - /* Show size of curret file in the bottom of panel */ - if (S_ISREG (fe->st.st_mode)) + /* Show size of current file in the bottom of panel */ + if (fe != NULL && S_ISREG (fe->st.st_mode)) { char buffer[BUF_SMALL]; @@ -1408,25 +1411,21 @@ adjust_top_file (WPanel *panel) { int items; - /* Update panel->current to avoid out of range in panel->dir.list[panel->current] - * when panel is redrawing when directory is reloading, for example in path: - * dir_list_reload() -> mc_refresh() -> dialog_change_screen_size() -> - * midnight_callback (MSG_RESIZE) -> setup_panels() -> panel_callback(MSG_DRAW) -> - * display_mini_info() - */ - panel->current = CLAMP (panel->current, 0, panel->dir.len - 1); - items = panel_items (panel); - if (panel->dir.len <= items) + if (panel->dir.len <= items || panel->current < 0) { /* If all files fit, show them all. */ + /* panel->current < 0 is in case of filter that doesn't match anything, keep it. */ panel->top = 0; } else { int i; + /* Update panel->current to avoid out of range in panel->dir.list[panel->current]. */ + panel->current = CLAMP (panel->current, 0, panel->dir.len - 1); + /* top_file has to be in the range [current-items+1, current] so that the current file is visible. top_file should be in the range [0, count-items] so that there's @@ -2069,7 +2068,7 @@ maybe_cd (WPanel *panel, gboolean move_up_dir) fe = panel_current_entry (panel); - if (S_ISDIR (fe->st.st_mode) || link_isdir (fe)) + if (fe != NULL && (S_ISDIR (fe->st.st_mode) || link_isdir (fe))) { vfs_path_t *vpath; @@ -2100,11 +2099,14 @@ force_maybe_cd (WPanel *panel) /* --------------------------------------------------------------------------------------------- */ -static inline void +static void unselect_item (WPanel *panel) { + const file_entry_t *fe; + + fe = panel_current_entry (panel); repaint_file (panel, panel->current, - panel_current_entry (panel)->f.marked != 0 ? FATTR_MARKED : FATTR_NORMAL); + fe != NULL && fe->f.marked != 0 ? FATTR_MARKED : FATTR_NORMAL); } /* --------------------------------------------------------------------------------------------- */ @@ -2114,21 +2116,18 @@ static void panel_select_ext_cmd (WPanel *panel) { const file_entry_t *fe; - GString *filename; gboolean do_select; char *reg_exp, *cur_file_ext; mc_search_t *search; int i; fe = panel_current_entry (panel); - - filename = fe->fname; - if (filename == NULL) + if (fe == NULL) return; do_select = (fe->f.marked == 0); - cur_file_ext = str_regex_escape (extension (filename->str)); + cur_file_ext = str_regex_escape (extension (fe->fname->str)); if (cur_file_ext[0] != '\0') reg_exp = g_strconcat ("^.*\\.", cur_file_ext, "$", (char *) NULL); else @@ -2159,6 +2158,21 @@ panel_select_ext_cmd (WPanel *panel) /* --------------------------------------------------------------------------------------------- */ +static void +panel_set_current (WPanel *panel, int i) +{ + if (i != panel->current) + { + panel->dirty = TRUE; + panel->current = i; + panel->top = panel->current - (WIDGET (panel)->rect.lines - 2) / 2; + if (panel->top < 0) + panel->top = 0; + } +} + +/* --------------------------------------------------------------------------------------------- */ + static int panel_current_at_half (const WPanel *panel) { @@ -2181,7 +2195,7 @@ move_down (WPanel *panel) { int items; - if (panel->current + 1 == panel->dir.len) + if (panel->dir.len == 0 || panel->current + 1 == panel->dir.len) return; unselect_item (panel); @@ -2212,7 +2226,7 @@ move_down (WPanel *panel) static void move_up (WPanel *panel) { - if (panel->current == 0) + if (panel->dir.len == 0 || panel->current <= 0) return; unselect_item (panel); @@ -2245,6 +2259,9 @@ panel_move_current (WPanel *panel, int lines) int new_pos; gboolean adjust = FALSE; + if (panel->dir.len == 0 || panel->current < 0) + return; + new_pos = panel->current + lines; if (new_pos >= panel->dir.len) new_pos = panel->dir.len - 1; @@ -2313,7 +2330,7 @@ prev_page (WPanel *panel) { int items; - if (panel->current == 0 && panel->top == 0) + if (panel->dir.len == 0 || panel->current < 0 || (panel->current == 0 && panel->top == 0)) return; unselect_item (panel); @@ -2339,11 +2356,16 @@ goto_parent_dir (WPanel *panel) cd_up_dir (panel); else { + const file_entry_t *fe; GString *fname; const char *bname; vfs_path_t *dname_vpath; - fname = panel_current_entry (panel)->fname; + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + fname = fe->fname; if (g_path_is_absolute (fname->str)) fname = mc_g_string_dup (fname); @@ -2383,7 +2405,7 @@ next_page (WPanel *panel) { int items; - if (panel->current == panel->dir.len - 1) + if (panel->dir.len == 0 || panel->current < 0 || panel->current == panel->dir.len - 1) return; unselect_item (panel); @@ -2411,7 +2433,7 @@ goto_child_dir (WPanel *panel) fe = panel_current_entry (panel); - if (S_ISDIR (fe->st.st_mode) || link_isdir (fe)) + if (fe != NULL && (S_ISDIR (fe->st.st_mode) || link_isdir (fe))) { vfs_path_t *vpath; @@ -2426,6 +2448,9 @@ goto_child_dir (WPanel *panel) static void goto_top_file (WPanel *panel) { + if (panel->dir.len == 0 || panel->current < 0) + return; + unselect_item (panel); panel->current = panel->top; select_item (panel); @@ -2436,6 +2461,9 @@ goto_top_file (WPanel *panel) static void goto_middle_file (WPanel *panel) { + if (panel->dir.len == 0 || panel->current < 0) + return; + unselect_item (panel); panel->current = panel->top + panel_items (panel) / 2; select_item (panel); @@ -2446,6 +2474,9 @@ goto_middle_file (WPanel *panel) static void goto_bottom_file (WPanel *panel) { + if (panel->dir.len == 0 || panel->current < 0) + return; + unselect_item (panel); panel->current = panel->top + panel_items (panel) - 1; select_item (panel); @@ -2456,7 +2487,7 @@ goto_bottom_file (WPanel *panel) static void move_home (WPanel *panel) { - if (panel->current == 0) + if (panel->dir.len == 0 || panel->current <= 0) return; unselect_item (panel); @@ -2491,7 +2522,7 @@ move_home (WPanel *panel) static void move_end (WPanel *panel) { - if (panel->current == panel->dir.len - 1) + if (panel->dir.len == 0 || panel->current < 0 || panel->current == panel->dir.len - 1) return; unselect_item (panel); @@ -2525,7 +2556,13 @@ move_end (WPanel *panel) static void do_mark_file (WPanel *panel, mark_act_t do_move) { - do_file_mark (panel, panel->current, panel_current_entry (panel)->f.marked ? 0 : 1); + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + do_file_mark (panel, panel->current, fe->f.marked ? 0 : 1); if ((panels_options.mark_moves_down && do_move == MARK_DOWN) || do_move == MARK_FORCE_DOWN) move_down (panel); @@ -2565,7 +2602,15 @@ mark_file_right (WPanel *panel) int lines; if (state_mark < 0) - state_mark = panel_current_entry (panel)->f.marked ? 0 : 1; + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + state_mark = fe->f.marked ? 0 : 1; + } lines = panel_lines (panel); lines = MIN (lines, panel->dir.len - panel->current - 1); @@ -2585,7 +2630,15 @@ mark_file_left (WPanel *panel) int lines; if (state_mark < 0) - state_mark = panel_current_entry (panel)->f.marked ? 0 : 1; + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe == NULL) + return; + + state_mark = fe->f.marked ? 0 : 1; + } lines = panel_lines (panel); lines = MIN (lines, panel->current + 1); @@ -2889,7 +2942,7 @@ start_search (WPanel *panel) do_search (panel, 0); } - else + else if (panel->dir.len != 0) { panel->quick_search.active = TRUE; g_string_set_size (panel->quick_search.buffer, 0); @@ -2921,7 +2974,7 @@ stop_search (WPanel *panel) /** Return TRUE if the Enter key has been processed, FALSE otherwise */ static gboolean -do_enter_on_file_entry (WPanel *panel, file_entry_t *fe) +do_enter_on_file_entry (WPanel *panel, const file_entry_t *fe) { const char *fname = fe->fname->str; char *fname_quoted; @@ -2999,7 +3052,11 @@ do_enter_on_file_entry (WPanel *panel, file_entry_t *fe) static inline gboolean do_enter (WPanel *panel) { - return do_enter_on_file_entry (panel, panel_current_entry (panel)); + const file_entry_t *fe; + + fe = panel_current_entry (panel); + + return (fe == NULL ? FALSE : do_enter_on_file_entry (panel, fe)); } /* --------------------------------------------------------------------------------------------- */ @@ -3024,6 +3081,8 @@ chdir_other_panel (WPanel *panel) WPanel *p; entry = panel_current_entry (panel); + if (entry == NULL) + return; if (get_other_type () != view_listing) create_panel (get_other_index (), view_listing); @@ -3065,7 +3124,13 @@ panel_sync_other (const WPanel *panel) /* try to set current filename on the other panel */ if (!panel->is_panelized) - panel_set_current_by_name (other_panel, panel_current_entry (panel)->fname->str); + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe != NULL) + panel_set_current_by_name (other_panel, fe->fname->str); + } } /* --------------------------------------------------------------------------------------------- */ @@ -3087,7 +3152,7 @@ chdir_to_readlink (WPanel *panel) fe = panel_current_entry (panel); - if (!S_ISLNK (fe->st.st_mode)) + if (fe == NULL || !S_ISLNK (fe->st.st_mode)) return; i = readlink (fe->fname->str, buffer, MC_MAXPATHLEN - 1); @@ -3433,6 +3498,9 @@ panel_do_cd_int (WPanel *panel, const vfs_path_t *new_dir_vpath, enum cd_enum cd &panel->sort_info, &panel->filter)) message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); + if (panel->dir.len == 0) + panel_set_current (panel, -1); + panel_set_current_by_name (panel, get_parent_dir_name (panel->cwd_vpath, olddir_vpath)); load_hint (FALSE); @@ -3831,7 +3899,6 @@ panel_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *dat bb = buttonbar_find (h); midnight_set_buttonbar (bb); - widget_draw (WIDGET (bb)); return MSG_HANDLED; case MSG_UNFOCUS: @@ -3870,9 +3937,15 @@ panel_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *dat static void mouse_toggle_mark (WPanel *panel) { - do_mark_file (panel, MARK_DONT_MOVE); - mouse_marking = (panel_current_entry (panel)->f.marked != 0); - mouse_mark_panel = current_panel; + const file_entry_t *fe; + + fe = panel_current_entry (panel); + if (fe != NULL) + { + do_mark_file (panel, MARK_DONT_MOVE); + mouse_marking = fe->f.marked != 0; + mouse_mark_panel = current_panel; + } } /* --------------------------------------------------------------------------------------------- */ @@ -3885,11 +3958,13 @@ mouse_set_mark (WPanel *panel) const file_entry_t *fe; fe = panel_current_entry (panel); - - if (mouse_marking && fe->f.marked == 0) - do_mark_file (panel, MARK_DONT_MOVE); - else if (!mouse_marking && fe->f.marked != 0) - do_mark_file (panel, MARK_DONT_MOVE); + if (fe != NULL) + { + if (mouse_marking && fe->f.marked == 0) + do_mark_file (panel, MARK_DONT_MOVE); + else if (!mouse_marking && fe->f.marked != 0) + do_mark_file (panel, MARK_DONT_MOVE); + } } } @@ -4188,10 +4263,11 @@ update_one_panel_widget (WPanel *panel, panel_update_flags_t flags, const char * if (free_pointer) { - const GString *fname; + const file_entry_t *fe; - fname = panel_current_entry (panel)->fname; - my_current_file = g_strndup (fname->str, fname->len); + fe = panel_current_entry (panel); + if (fe != NULL) + my_current_file = g_strndup (fe->fname->str, fe->fname->len); current_file = my_current_file; } @@ -4225,21 +4301,6 @@ update_one_panel (int which, panel_update_flags_t flags, const char *current_fil /* --------------------------------------------------------------------------------------------- */ -static void -panel_set_current (WPanel *panel, int i) -{ - if (i != panel->current) - { - panel->dirty = TRUE; - panel->current = i; - panel->top = panel->current - (WIDGET (panel)->rect.lines - 2) / 2; - if (panel->top < 0) - panel->top = 0; - } -} - -/* --------------------------------------------------------------------------------------------- */ - /* event callback */ static gboolean event_update_panels (const gchar *event_group_name, const gchar *event_name, @@ -4268,8 +4329,13 @@ panel_save_current_file_to_clip_file (const gchar *event_group_name, const gchar (void) data; if (current_panel->marked == 0) - mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_to_file", - (gpointer) panel_current_entry (current_panel)->fname->str); + { + const file_entry_t *fe; + + fe = panel_current_entry (current_panel); + if (fe != NULL) + mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_to_file", (gpointer) fe->fname->str); + } else { int i; @@ -4371,12 +4437,33 @@ panel_dir_list_callback (dir_list_cb_state_t state, void *data) /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ +file_entry_t * +panel_current_entry (const WPanel *panel) +{ + file_entry_t *fe; + + if (panel->dir.len == 0 || panel->current < 0 || panel->current >= panel->dir.len) + return NULL; + + fe = &(panel->dir.list[panel->current]); + + return fe->fname == NULL ? NULL : fe; +} + +/* --------------------------------------------------------------------------------------------- */ + void panel_set_current_by_name (WPanel *panel, const char *name) { int i; char *subdir; + if (panel->dir.len == 0) + { + panel_set_current (panel, -1); + return; + } + if (name == NULL) { panel_set_current (panel, 0); @@ -4608,6 +4695,9 @@ panel_sized_with_dir_new (const char *panel_name, const WRect *r, const vfs_path &panel->sort_info, &panel->filter)) message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); + if (panel->dir.len == 0) + panel_set_current (panel, -1); + /* Restore old right path */ if (curdir != NULL) { @@ -4657,7 +4747,10 @@ panel_reload (WPanel *panel) message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); panel->dirty = TRUE; - if (panel->current >= panel->dir.len) + + if (panel->dir.len == 0) + panel_set_current (panel, -1); + else if (panel->current >= panel->dir.len) panel_set_current (panel, panel->dir.len - 1); recalculate_panel_summary (panel); @@ -4866,6 +4959,49 @@ file_mark (WPanel *panel, int lc_index, int val) } } +/* --------------------------------------------------------------------------------------------- */ +/** + * Find marked file starting from the given position. + * + * @param panel WPanel object + * @param curent_file a staring position to get current or search next marked file + * + * @return pointer to the name of find file or NULL if no file found or @current_file is out of range + */ + +const GString * +panel_find_marked_file (const WPanel *panel, int *current_file) +{ + while (panel->dir.list[*current_file].f.marked == 0 && *current_file < panel->dir.len) + (*current_file)++; + + return (*current_file >= panel->dir.len ? NULL : panel->dir.list[*current_file].fname); +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Get marked file clsest to the given position. + * + * @param panel WPanel object + * @param curent_file a staring position to get current or closest next marked file. If there are + * no marked files in @panel, @panel->current is used. + * + * @return pointer to the name of find file or NULL if no file found or @current_file is out of range. + */ + +const GString * +panel_get_marked_file (const WPanel *panel, int *current_file) +{ + const file_entry_t *fe; + + if (panel->marked != 0) + return panel_find_marked_file (panel, current_file); + + fe = panel_current_entry (panel); + + return (fe == NULL ? NULL : fe->fname); +} + /* --------------------------------------------------------------------------------------------- */ void @@ -4879,6 +5015,9 @@ panel_re_sort (WPanel *panel) return; fe = panel_current_entry (panel); + if (fe == NULL) + return; + filename = g_strndup (fe->fname->str, fe->fname->len); unselect_item (panel); dir_list_sort (&panel->dir, panel->sort_field->sort_routine, &panel->sort_info); @@ -4910,11 +5049,12 @@ panel_set_sort_order (WPanel *panel, const panel_field_t *sort_order) /* The directory is already sorted, we have to load the unsorted stuff */ if (sort_order->sort_routine == (GCompareFunc) unsorted) { - char *current_file; - const GString *fname; + const file_entry_t *fe; + char *current_file = NULL; - fname = panel_current_entry (panel)->fname; - current_file = g_strndup (fname->str, fname->len); + fe = panel_current_entry (panel); + if (fe != NULL) + current_file = g_strndup (fe->fname->str, fe->fname->len); panel_reload (panel); panel_set_current_by_name (panel, current_file); g_free (current_file); diff --git a/src/filemanager/panel.h b/src/filemanager/panel.h index 2f4d8d549e..fd84489213 100644 --- a/src/filemanager/panel.h +++ b/src/filemanager/panel.h @@ -171,6 +171,7 @@ int set_panel_formats (WPanel * p); void panel_set_filter (WPanel * panel, const file_filter_t * filter); +file_entry_t *panel_current_entry (const WPanel *panel); void panel_set_current_by_name (WPanel * panel, const char *name); void unmark_files (WPanel * panel); @@ -179,6 +180,8 @@ void select_item (WPanel * panel); void recalculate_panel_summary (WPanel * panel); void file_mark (WPanel * panel, int idx, int val); void do_file_mark (WPanel * panel, int idx, int val); +const GString *panel_find_marked_file (const WPanel *panel, int *current_file); +const GString *panel_get_marked_file (const WPanel *panel, int *current_file); gboolean panel_do_cd (WPanel * panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_type); MC_MOCKABLE gboolean panel_cd (WPanel * panel, const vfs_path_t * new_dir_vpath, @@ -275,12 +278,4 @@ panel_sized_new (const char *panel_name, const WRect *r) /* --------------------------------------------------------------------------------------------- */ -static inline file_entry_t * -panel_current_entry (const WPanel *panel) -{ - return &(panel->dir.list[panel->current]); -} - -/* --------------------------------------------------------------------------------------------- */ - #endif /* MC__PANEL_H */ diff --git a/src/usermenu.c b/src/usermenu.c index 5bfa999019..1ec9611538 100644 --- a/src/usermenu.c +++ b/src/usermenu.c @@ -173,10 +173,15 @@ extract_arg (char *p, char *arg, int size) static gboolean test_type (WPanel *panel, char *arg) { + const file_entry_t *fe; int result = 0; /* False by default */ mode_t st_mode; - st_mode = panel_current_entry (panel)->st.st_mode; + fe = panel_current_entry (panel); + if (fe == NULL) + return FALSE; + + st_mode = fe->st.st_mode; for (; *arg != '\0'; arg++) { @@ -268,9 +273,18 @@ test_condition (const Widget *edit_widget, char *p, gboolean *condition) } else #endif - *condition = panel != NULL && - mc_search (arg, DEFAULT_CHARSET, panel_current_entry (panel)->fname->str, - search_type); + { + if (panel == NULL) + *condition = FALSE; + else + { + const file_entry_t *fe; + + fe = panel_current_entry (panel); + *condition = fe != NULL + && mc_search (arg, DEFAULT_CHARSET, fe->fname->str, search_type); + } + } break; case 'y': /* syntax pattern */ #ifdef USE_INTERNAL_EDIT @@ -784,6 +798,8 @@ expand_format (const Widget *edit_widget, char c, gboolean do_quote) else #endif { + const file_entry_t *fe; + if (g_ascii_islower ((gchar) c)) panel = current_panel; else @@ -793,7 +809,8 @@ expand_format (const Widget *edit_widget, char c, gboolean do_quote) panel = other_panel; } - fname = panel_current_entry (panel)->fname->str; + fe = panel_current_entry (panel); + fname = fe == NULL ? NULL : fe->fname->str; } break; diff --git a/src/viewer/actions_cmd.c b/src/viewer/actions_cmd.c index b098086044..265224695e 100644 --- a/src/viewer/actions_cmd.c +++ b/src/viewer/actions_cmd.c @@ -168,6 +168,7 @@ mcview_hook (void *v) { WView *view = (WView *) v; WPanel *panel; + const file_entry_t *fe; /* If the user is busy typing, wait until he finishes to update the screen */ @@ -187,9 +188,13 @@ mcview_hook (void *v) else return; + fe = panel_current_entry (panel); + if (fe == NULL) + return; + mcview_done (view); mcview_init (view); - mcview_load (view, 0, panel_current_entry (panel)->fname->str, 0, 0, 0); + mcview_load (view, 0, fe->fname->str, 0, 0, 0); mcview_display (view); }