mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-08 20:41:59 +03:00
Changed treestore functions to handle vfs_path_t objects.
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
fec5cd6c5d
commit
5480fe5f80
@ -918,7 +918,7 @@ tree_box (const char *current_dir)
|
|||||||
((Widget *) bar)->y = LINES - 1;
|
((Widget *) bar)->y = LINES - 1;
|
||||||
|
|
||||||
if (run_dlg (dlg) == B_ENTER)
|
if (run_dlg (dlg) == B_ENTER)
|
||||||
val = g_strdup (tree_selected_name (mytree));
|
val = vfs_path_to_str (tree_selected_name (mytree));
|
||||||
|
|
||||||
destroy_dlg (dlg);
|
destroy_dlg (dlg);
|
||||||
return val;
|
return val;
|
||||||
|
@ -553,7 +553,7 @@ do_load_dir (const char *path, dir_list * list, sortfn * sort, gboolean lc_rever
|
|||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree_store_start_check (path);
|
tree_store_start_check (vpath);
|
||||||
|
|
||||||
/* Do not add a ".." entry to the root directory */
|
/* Do not add a ".." entry to the root directory */
|
||||||
if ((path[0] == PATH_SEP) && (path[1] == '\0'))
|
if ((path[0] == PATH_SEP) && (path[1] == '\0'))
|
||||||
@ -637,8 +637,7 @@ do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int cou
|
|||||||
return set_zero_dir (list) ? 1 : 0;
|
return set_zero_dir (list) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_path = vfs_path_to_str (vpath);
|
tree_store_start_check (vpath);
|
||||||
tree_store_start_check (tmp_path);
|
|
||||||
|
|
||||||
marked_files = g_hash_table_new (g_str_hash, g_str_equal);
|
marked_files = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
alloc_dir_copy (list->size);
|
alloc_dir_copy (list->size);
|
||||||
@ -661,13 +660,15 @@ do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int cou
|
|||||||
|
|
||||||
/* Add ".." except to the root directory. The ".." entry
|
/* Add ".." except to the root directory. The ".." entry
|
||||||
(if any) must be the first in the list. */
|
(if any) must be the first in the list. */
|
||||||
if (!((tmp_path[0] == PATH_SEP) && (tmp_path[1] == '\0')))
|
tmp_path = vfs_path_get_by_index (vpath, 0)->path;
|
||||||
|
if (!
|
||||||
|
(vfs_path_elements_count (vpath) == 1 && (tmp_path[0] == PATH_SEP)
|
||||||
|
&& (tmp_path[1] == '\0')))
|
||||||
{
|
{
|
||||||
if (!set_zero_dir (list))
|
if (!set_zero_dir (list))
|
||||||
{
|
{
|
||||||
clean_dir (list, count);
|
clean_dir (list, count);
|
||||||
clean_dir (&dir_copy, count);
|
clean_dir (&dir_copy, count);
|
||||||
g_free (tmp_path);
|
|
||||||
return next_free;
|
return next_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,7 +677,6 @@ do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int cou
|
|||||||
|
|
||||||
next_free++;
|
next_free++;
|
||||||
}
|
}
|
||||||
g_free (tmp_path);
|
|
||||||
|
|
||||||
while ((dp = mc_readdir (dirp)))
|
while ((dp = mc_readdir (dirp)))
|
||||||
{
|
{
|
||||||
|
@ -1176,7 +1176,7 @@ panel_get_file (WPanel * panel)
|
|||||||
WTree *tree;
|
WTree *tree;
|
||||||
|
|
||||||
tree = (WTree *) get_panel_widget (get_current_index ());
|
tree = (WTree *) get_panel_widget (get_current_index ());
|
||||||
return tree_selected_name (tree);
|
return vfs_path_to_str (tree_selected_name (tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panel->marked != 0)
|
if (panel->marked != 0)
|
||||||
@ -1185,10 +1185,9 @@ panel_get_file (WPanel * panel)
|
|||||||
|
|
||||||
for (i = 0; i < panel->count; i++)
|
for (i = 0; i < panel->count; i++)
|
||||||
if (panel->dir.list[i].f.marked)
|
if (panel->dir.list[i].f.marked)
|
||||||
return panel->dir.list[i].fname;
|
return g_strdup (panel->dir.list[i].fname);
|
||||||
}
|
}
|
||||||
|
return g_strdup (panel->dir.list[panel->selected].fname);
|
||||||
return panel->dir.list[panel->selected].fname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -2627,12 +2626,13 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
|||||||
vfs_path_t *source_vpath;
|
vfs_path_t *source_vpath;
|
||||||
|
|
||||||
if (force_single)
|
if (force_single)
|
||||||
source = selection (panel)->fname;
|
source = g_strdup (selection (panel)->fname);
|
||||||
else
|
else
|
||||||
source = panel_get_file (panel);
|
source = panel_get_file (panel);
|
||||||
|
|
||||||
if (strcmp (source, "..") == 0)
|
if (strcmp (source, "..") == 0)
|
||||||
{
|
{
|
||||||
|
g_free (source);
|
||||||
message (D_ERROR, MSG_ERROR, _("Cannot operate on \"..\"!"));
|
message (D_ERROR, MSG_ERROR, _("Cannot operate on \"..\"!"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -2924,20 +2924,22 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
|||||||
/* Loop for every file, perform the actual copy operation */
|
/* Loop for every file, perform the actual copy operation */
|
||||||
for (i = 0; i < panel->count; i++)
|
for (i = 0; i < panel->count; i++)
|
||||||
{
|
{
|
||||||
|
const char *source2;
|
||||||
|
|
||||||
if (!panel->dir.list[i].f.marked)
|
if (!panel->dir.list[i].f.marked)
|
||||||
continue; /* Skip the unmarked ones */
|
continue; /* Skip the unmarked ones */
|
||||||
|
|
||||||
source = panel->dir.list[i].fname;
|
source2 = panel->dir.list[i].fname;
|
||||||
src_stat = panel->dir.list[i].st;
|
src_stat = panel->dir.list[i].st;
|
||||||
|
|
||||||
#ifdef WITH_FULL_PATHS
|
#ifdef WITH_FULL_PATHS
|
||||||
g_free (source_with_path_str);
|
g_free (source_with_path_str);
|
||||||
vfs_path_free (source_with_vpath);
|
vfs_path_free (source_with_vpath);
|
||||||
if (g_path_is_absolute (source))
|
if (g_path_is_absolute (source2))
|
||||||
source_with_vpath = vfs_path_from_str (source);
|
source_with_vpath = vfs_path_from_str (source2);
|
||||||
else
|
else
|
||||||
source_with_vpath =
|
source_with_vpath =
|
||||||
vfs_path_append_new (panel->cwd_vpath, source, (char *) NULL);
|
vfs_path_append_new (panel->cwd_vpath, source2, (char *) NULL);
|
||||||
source_with_path_str = vfs_path_to_str (source_with_vpath);
|
source_with_path_str = vfs_path_to_str (source_with_vpath);
|
||||||
#endif /* WITH_FULL_PATHS */
|
#endif /* WITH_FULL_PATHS */
|
||||||
|
|
||||||
@ -3074,6 +3076,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
|||||||
file_op_total_context_destroy (tctx);
|
file_op_total_context_destroy (tctx);
|
||||||
ret_fast:
|
ret_fast:
|
||||||
file_op_context_destroy (ctx);
|
file_op_context_destroy (ctx);
|
||||||
|
g_free (source);
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
@ -752,12 +752,14 @@ put_prog_name (void)
|
|||||||
if (get_current_type () == view_tree)
|
if (get_current_type () == view_tree)
|
||||||
{
|
{
|
||||||
WTree *tree = (WTree *) get_panel_widget (get_current_index ());
|
WTree *tree = (WTree *) get_panel_widget (get_current_index ());
|
||||||
tmp = tree_selected_name (tree);
|
|
||||||
|
tmp = vfs_path_to_str (tree_selected_name (tree));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tmp = selection (current_panel)->fname;
|
tmp = g_strdup (selection (current_panel)->fname);
|
||||||
|
|
||||||
command_insert (cmdline, tmp, TRUE);
|
command_insert (cmdline, tmp, TRUE);
|
||||||
|
g_free (tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
@ -55,7 +55,6 @@
|
|||||||
#include "lib/widget.h"
|
#include "lib/widget.h"
|
||||||
#include "lib/event.h" /* mc_event_raise() */
|
#include "lib/event.h" /* mc_event_raise() */
|
||||||
|
|
||||||
|
|
||||||
#include "src/setup.h" /* confirm_delete, panels_options */
|
#include "src/setup.h" /* confirm_delete, panels_options */
|
||||||
#include "src/keybind-defaults.h"
|
#include "src/keybind-defaults.h"
|
||||||
#include "src/history.h"
|
#include "src/history.h"
|
||||||
@ -188,10 +187,10 @@ save_tree (WTree * tree)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tree_remove_entry (WTree * tree, char *name)
|
tree_remove_entry (WTree * tree, const vfs_path_t * name_vpath)
|
||||||
{
|
{
|
||||||
(void) tree;
|
(void) tree;
|
||||||
tree_store_remove_entry (name);
|
tree_store_remove_entry (name_vpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -250,10 +249,14 @@ tree_show_mini_info (WTree * tree, int tree_lines, int tree_cols)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Show full name of selected directory */
|
/* Show full name of selected directory */
|
||||||
|
char *tmp_path;
|
||||||
|
|
||||||
tty_setcolor (tree->is_panel ? NORMAL_COLOR : TREE_NORMALC (h));
|
tty_setcolor (tree->is_panel ? NORMAL_COLOR : TREE_NORMALC (h));
|
||||||
tty_draw_hline (tree->widget.y + line, tree->widget.x + 1, ' ', tree_cols);
|
tty_draw_hline (tree->widget.y + line, tree->widget.x + 1, ' ', tree_cols);
|
||||||
widget_move (&tree->widget, line, 1);
|
widget_move (&tree->widget, line, 1);
|
||||||
tty_print_string (str_fit_to_term (tree->selected_ptr->name, tree_cols, J_LEFT_FIT));
|
tmp_path = vfs_path_to_str (tree->selected_ptr->name);
|
||||||
|
tty_print_string (str_fit_to_term (tmp_path, tree_cols, J_LEFT_FIT));
|
||||||
|
g_free (tmp_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,25 +304,33 @@ show_tree (WTree * tree)
|
|||||||
i = 0;
|
i = 0;
|
||||||
while (current->prev && i < tree->topdiff)
|
while (current->prev && i < tree->topdiff)
|
||||||
{
|
{
|
||||||
|
char *current_name;
|
||||||
|
|
||||||
current = current->prev;
|
current = current->prev;
|
||||||
|
current_name = vfs_path_to_str (current->name);
|
||||||
|
|
||||||
if (current->sublevel < tree->selected_ptr->sublevel)
|
if (current->sublevel < tree->selected_ptr->sublevel)
|
||||||
{
|
{
|
||||||
if (strncmp (current->name, tree->selected_ptr->name, strlen (current->name)) == 0)
|
if (vfs_path_cmp (current->name, tree->selected_ptr->name) == 0)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (current->sublevel == tree->selected_ptr->sublevel)
|
else if (current->sublevel == tree->selected_ptr->sublevel)
|
||||||
{
|
{
|
||||||
for (j = strlen (current->name) - 1; current->name[j] != PATH_SEP; j--);
|
for (j = strlen (current_name) - 1; current_name[j] != PATH_SEP; j--);
|
||||||
if (strncmp (current->name, tree->selected_ptr->name, j) == 0)
|
if (vfs_path_ncmp (current->name, tree->selected_ptr->name, j) == 0)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (current->sublevel == tree->selected_ptr->sublevel + 1
|
else
|
||||||
&& strlen (tree->selected_ptr->name) > 1)
|
|
||||||
{
|
{
|
||||||
if (strncmp (current->name, tree->selected_ptr->name,
|
if (current->sublevel == tree->selected_ptr->sublevel + 1
|
||||||
strlen (tree->selected_ptr->name)) == 0)
|
&& vfs_path_len (tree->selected_ptr->name) > 1)
|
||||||
i++;
|
{
|
||||||
|
if (vfs_path_ncmp (current->name, tree->selected_ptr->name,
|
||||||
|
vfs_path_len (tree->selected_ptr->name)) == 0)
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
g_free (current_name);
|
||||||
}
|
}
|
||||||
tree->topdiff = i;
|
tree->topdiff = i;
|
||||||
}
|
}
|
||||||
@ -345,8 +356,12 @@ show_tree (WTree * tree)
|
|||||||
if (current->sublevel == topsublevel)
|
if (current->sublevel == topsublevel)
|
||||||
{
|
{
|
||||||
/* Show full name */
|
/* Show full name */
|
||||||
|
char *current_name;
|
||||||
|
|
||||||
|
current_name = vfs_path_to_str (current->name);
|
||||||
tty_print_string (str_fit_to_term
|
tty_print_string (str_fit_to_term
|
||||||
(current->name, tree_cols + (tree->is_panel ? 0 : 1), J_LEFT_FIT));
|
(current_name, tree_cols + (tree->is_panel ? 0 : 1), J_LEFT_FIT));
|
||||||
|
g_free (current_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -388,22 +403,26 @@ show_tree (WTree * tree)
|
|||||||
{
|
{
|
||||||
if (current->sublevel < tree->selected_ptr->sublevel)
|
if (current->sublevel < tree->selected_ptr->sublevel)
|
||||||
{
|
{
|
||||||
if (strncmp (current->name, tree->selected_ptr->name,
|
if (vfs_path_ncmp (current->name, tree->selected_ptr->name,
|
||||||
strlen (current->name)) == 0)
|
vfs_path_len (current->name)) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (current->sublevel == tree->selected_ptr->sublevel)
|
else if (current->sublevel == tree->selected_ptr->sublevel)
|
||||||
{
|
{
|
||||||
for (j = strlen (current->name) - 1; current->name[j] != PATH_SEP; j--)
|
char *current_name;
|
||||||
|
|
||||||
|
current_name = vfs_path_to_str (current->name);
|
||||||
|
for (j = strlen (current_name) - 1; current_name[j] != PATH_SEP; j--)
|
||||||
;
|
;
|
||||||
if (strncmp (current->name, tree->selected_ptr->name, j) == 0)
|
g_free (current_name);
|
||||||
|
if (vfs_path_ncmp (current->name, tree->selected_ptr->name, j) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (current->sublevel == tree->selected_ptr->sublevel + 1
|
else if (current->sublevel == tree->selected_ptr->sublevel + 1
|
||||||
&& strlen (tree->selected_ptr->name) > 1)
|
&& vfs_path_len (tree->selected_ptr->name) > 1)
|
||||||
{
|
{
|
||||||
if (strncmp (current->name, tree->selected_ptr->name,
|
if (vfs_path_ncmp (current->name, tree->selected_ptr->name,
|
||||||
strlen (tree->selected_ptr->name)) == 0)
|
vfs_path_len (tree->selected_ptr->name)) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
current = current->next;
|
current = current->next;
|
||||||
@ -579,17 +598,21 @@ tree_event (WTree * tree, int y)
|
|||||||
static void
|
static void
|
||||||
tree_chdir_sel (WTree * tree)
|
tree_chdir_sel (WTree * tree)
|
||||||
{
|
{
|
||||||
|
char *tmp_path;
|
||||||
|
|
||||||
if (!tree->is_panel)
|
if (!tree->is_panel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
change_panel ();
|
change_panel ();
|
||||||
|
|
||||||
if (do_cd (tree->selected_ptr->name, cd_exact))
|
tmp_path = vfs_path_to_str (tree->selected_ptr->name);
|
||||||
|
if (do_cd (tmp_path, cd_exact))
|
||||||
select_item (current_panel);
|
select_item (current_panel);
|
||||||
else
|
else
|
||||||
message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"),
|
message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"),
|
||||||
tree->selected_ptr->name, unix_error_string (errno));
|
tmp_path, unix_error_string (errno));
|
||||||
|
|
||||||
|
g_free (tmp_path);
|
||||||
change_panel ();
|
change_panel ();
|
||||||
show_tree (tree);
|
show_tree (tree);
|
||||||
}
|
}
|
||||||
@ -713,27 +736,19 @@ static void
|
|||||||
tree_rescan (void *data)
|
tree_rescan (void *data)
|
||||||
{
|
{
|
||||||
WTree *tree = data;
|
WTree *tree = data;
|
||||||
char *old_dir;
|
int ret;
|
||||||
vfs_path_t *vpath = NULL;
|
vfs_path_t *old_vpath;
|
||||||
int r;
|
|
||||||
|
|
||||||
old_dir = vfs_get_current_dir ();
|
old_vpath = vfs_path_clone (vfs_get_raw_current_dir ());
|
||||||
if (old_dir == NULL)
|
if (old_vpath == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (tree->selected_ptr == NULL)
|
if (tree->selected_ptr != NULL && mc_chdir (tree->selected_ptr->name) == 0)
|
||||||
goto ret;
|
{
|
||||||
|
tree_store_rescan (tree->selected_ptr->name);
|
||||||
vpath = vfs_path_from_str (tree->selected_ptr->name);
|
ret = mc_chdir (old_vpath);
|
||||||
if (mc_chdir (vpath) != 0)
|
}
|
||||||
goto ret;
|
vfs_path_free (old_vpath);
|
||||||
|
|
||||||
tree_store_rescan (vpath);
|
|
||||||
vpath = vfs_path_from_str (old_dir);
|
|
||||||
r = mc_chdir (vpath);
|
|
||||||
ret:
|
|
||||||
vfs_path_free (vpath);
|
|
||||||
g_free (old_dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -752,13 +767,15 @@ static void
|
|||||||
tree_copy (WTree * tree, const char *default_dest)
|
tree_copy (WTree * tree, const char *default_dest)
|
||||||
{
|
{
|
||||||
char msg[BUF_MEDIUM];
|
char msg[BUF_MEDIUM];
|
||||||
char *dest;
|
char *dest, *selected_ptr_name;
|
||||||
|
|
||||||
if (tree->selected_ptr == NULL)
|
if (tree->selected_ptr == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
selected_ptr_name = vfs_path_to_str (tree->selected_ptr->name);
|
||||||
|
|
||||||
g_snprintf (msg, sizeof (msg), _("Copy \"%s\" directory to:"),
|
g_snprintf (msg, sizeof (msg), _("Copy \"%s\" directory to:"),
|
||||||
str_trunc (tree->selected_ptr->name, 50));
|
str_trunc (selected_ptr_name, 50));
|
||||||
dest = input_expand_dialog (Q_ ("DialogTitle|Copy"),
|
dest = input_expand_dialog (Q_ ("DialogTitle|Copy"),
|
||||||
msg, MC_HISTORY_FM_TREE_COPY, default_dest);
|
msg, MC_HISTORY_FM_TREE_COPY, default_dest);
|
||||||
|
|
||||||
@ -771,12 +788,13 @@ tree_copy (WTree * tree, const char *default_dest)
|
|||||||
tctx = file_op_total_context_new ();
|
tctx = file_op_total_context_new ();
|
||||||
file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_MULTI_ITEM);
|
file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_MULTI_ITEM);
|
||||||
tctx->ask_overwrite = FALSE;
|
tctx->ask_overwrite = FALSE;
|
||||||
copy_dir_dir (tctx, ctx, tree->selected_ptr->name, dest, TRUE, FALSE, FALSE, NULL);
|
copy_dir_dir (tctx, ctx, selected_ptr_name, dest, TRUE, FALSE, FALSE, NULL);
|
||||||
file_op_total_context_destroy (tctx);
|
file_op_total_context_destroy (tctx);
|
||||||
file_op_context_destroy (ctx);
|
file_op_context_destroy (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (dest);
|
g_free (dest);
|
||||||
|
g_free (selected_ptr_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -785,7 +803,7 @@ static void
|
|||||||
tree_move (WTree * tree, const char *default_dest)
|
tree_move (WTree * tree, const char *default_dest)
|
||||||
{
|
{
|
||||||
char msg[BUF_MEDIUM];
|
char msg[BUF_MEDIUM];
|
||||||
char *dest;
|
char *dest, *selected_ptr_name;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
FileOpContext *ctx;
|
FileOpContext *ctx;
|
||||||
FileOpTotalContext *tctx;
|
FileOpTotalContext *tctx;
|
||||||
@ -793,39 +811,38 @@ tree_move (WTree * tree, const char *default_dest)
|
|||||||
if (tree->selected_ptr == NULL)
|
if (tree->selected_ptr == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
selected_ptr_name = vfs_path_to_str (tree->selected_ptr->name);
|
||||||
|
|
||||||
g_snprintf (msg, sizeof (msg), _("Move \"%s\" directory to:"),
|
g_snprintf (msg, sizeof (msg), _("Move \"%s\" directory to:"),
|
||||||
str_trunc (tree->selected_ptr->name, 50));
|
str_trunc (selected_ptr_name, 50));
|
||||||
dest =
|
dest =
|
||||||
input_expand_dialog (Q_ ("DialogTitle|Move"), msg, MC_HISTORY_FM_TREE_MOVE, default_dest);
|
input_expand_dialog (Q_ ("DialogTitle|Move"), msg, MC_HISTORY_FM_TREE_MOVE, default_dest);
|
||||||
|
|
||||||
if (dest == NULL || *dest == '\0')
|
if (dest == NULL || *dest == '\0')
|
||||||
{
|
goto ret;
|
||||||
g_free (dest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat (dest, &buf))
|
if (stat (dest, &buf))
|
||||||
{
|
{
|
||||||
message (D_ERROR, MSG_ERROR, _("Cannot stat the destination\n%s"),
|
message (D_ERROR, MSG_ERROR, _("Cannot stat the destination\n%s"),
|
||||||
unix_error_string (errno));
|
unix_error_string (errno));
|
||||||
g_free (dest);
|
goto ret;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISDIR (buf.st_mode))
|
if (!S_ISDIR (buf.st_mode))
|
||||||
{
|
{
|
||||||
file_error (_("Destination \"%s\" must be a directory\n%s"), dest);
|
file_error (_("Destination \"%s\" must be a directory\n%s"), dest);
|
||||||
g_free (dest);
|
goto ret;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = file_op_context_new (OP_MOVE);
|
ctx = file_op_context_new (OP_MOVE);
|
||||||
tctx = file_op_total_context_new ();
|
tctx = file_op_total_context_new ();
|
||||||
file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM);
|
file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM);
|
||||||
move_dir_dir (tctx, ctx, tree->selected_ptr->name, dest);
|
move_dir_dir (tctx, ctx, selected_ptr_name, dest);
|
||||||
file_op_total_context_destroy (tctx);
|
file_op_total_context_destroy (tctx);
|
||||||
file_op_context_destroy (ctx);
|
file_op_context_destroy (ctx);
|
||||||
|
|
||||||
|
ret:
|
||||||
|
g_free (selected_ptr_name);
|
||||||
g_free (dest);
|
g_free (dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,30 +874,37 @@ tree_rmdir (void *data)
|
|||||||
WTree *tree = data;
|
WTree *tree = data;
|
||||||
FileOpContext *ctx;
|
FileOpContext *ctx;
|
||||||
FileOpTotalContext *tctx;
|
FileOpTotalContext *tctx;
|
||||||
|
char *selected_ptr_name;
|
||||||
|
|
||||||
if (!tree->selected_ptr)
|
if (!tree->selected_ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
selected_ptr_name = vfs_path_to_str (tree->selected_ptr->name);
|
||||||
|
|
||||||
if (confirm_delete)
|
if (confirm_delete)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
buf = g_strdup_printf (_("Delete %s?"), tree->selected_ptr->name);
|
buf = g_strdup_printf (_("Delete %s?"), selected_ptr_name);
|
||||||
result = query_dialog (Q_ ("DialogTitle|Delete"), buf, D_ERROR, 2, _("&Yes"), _("&No"));
|
result = query_dialog (Q_ ("DialogTitle|Delete"), buf, D_ERROR, 2, _("&Yes"), _("&No"));
|
||||||
g_free (buf);
|
g_free (buf);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
|
{
|
||||||
|
g_free (selected_ptr_name);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = file_op_context_new (OP_DELETE);
|
ctx = file_op_context_new (OP_DELETE);
|
||||||
tctx = file_op_total_context_new ();
|
tctx = file_op_total_context_new ();
|
||||||
|
|
||||||
file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM);
|
file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM);
|
||||||
if (erase_dir (tctx, ctx, tree->selected_ptr->name) == FILE_CONT)
|
if (erase_dir (tctx, ctx, selected_ptr_name) == FILE_CONT)
|
||||||
tree_forget (tree);
|
tree_forget (tree);
|
||||||
file_op_total_context_destroy (tctx);
|
file_op_total_context_destroy (tctx);
|
||||||
file_op_context_destroy (ctx);
|
file_op_context_destroy (ctx);
|
||||||
|
g_free (selected_ptr_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1267,21 +1291,23 @@ tree_new (int y, int x, int lines, int cols, gboolean is_panel)
|
|||||||
void
|
void
|
||||||
tree_chdir (WTree * tree, const char *dir)
|
tree_chdir (WTree * tree, const char *dir)
|
||||||
{
|
{
|
||||||
|
vfs_path_t *vpath;
|
||||||
tree_entry *current;
|
tree_entry *current;
|
||||||
|
|
||||||
current = tree_store_whereis (dir);
|
vpath = vfs_path_from_str (dir);
|
||||||
|
current = tree_store_whereis (vpath);
|
||||||
if (current != NULL)
|
if (current != NULL)
|
||||||
{
|
{
|
||||||
tree->selected_ptr = current;
|
tree->selected_ptr = current;
|
||||||
tree_check_focus (tree);
|
tree_check_focus (tree);
|
||||||
}
|
}
|
||||||
|
vfs_path_free (vpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/** Return name of the currently selected entry */
|
/** Return name of the currently selected entry */
|
||||||
|
|
||||||
char *
|
vfs_path_t *
|
||||||
tree_selected_name (const WTree * tree)
|
tree_selected_name (const WTree * tree)
|
||||||
{
|
{
|
||||||
return tree->selected_ptr->name;
|
return tree->selected_ptr->name;
|
||||||
|
@ -27,7 +27,7 @@ struct Dlg_head;
|
|||||||
WTree *tree_new (int y, int x, int lines, int cols, gboolean is_panel);
|
WTree *tree_new (int y, int x, int lines, int cols, gboolean is_panel);
|
||||||
|
|
||||||
void tree_chdir (WTree * tree, const char *dir);
|
void tree_chdir (WTree * tree, const char *dir);
|
||||||
char *tree_selected_name (const WTree * tree);
|
vfs_path_t *tree_selected_name (const WTree * tree);
|
||||||
|
|
||||||
void sync_tree (const char *pathname);
|
void sync_tree (const char *pathname);
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "lib/mcconfig.h"
|
#include "lib/mcconfig.h"
|
||||||
#include "lib/vfs/vfs.h"
|
#include "lib/vfs/vfs.h"
|
||||||
#include "lib/fileloc.h"
|
#include "lib/fileloc.h"
|
||||||
|
#include "lib/strescape.h"
|
||||||
#include "lib/hook.h"
|
#include "lib/hook.h"
|
||||||
#include "lib/util.h"
|
#include "lib/util.h"
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ static hook_t *remove_entry_hooks;
|
|||||||
/*** file scope functions ************************************************************************/
|
/*** file scope functions ************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static tree_entry *tree_store_add_entry (const char *name);
|
static tree_entry *tree_store_add_entry (const vfs_path_t * name);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -88,57 +89,85 @@ tree_store_dirty (int state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/** Returns the number of common bytes in the strings. */
|
/**
|
||||||
|
*
|
||||||
|
* @return the number of common bytes in the strings.
|
||||||
|
*/
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
str_common (const char *s1, const char *s2)
|
str_common (const vfs_path_t * s1_vpath, const vfs_path_t * s2_vpath)
|
||||||
{
|
{
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
|
char *s1, *fs1;
|
||||||
|
char *s2, *fs2;
|
||||||
|
|
||||||
|
s1 = fs1 = vfs_path_to_str (s1_vpath);
|
||||||
|
s2 = fs2 = vfs_path_to_str (s2_vpath);
|
||||||
|
|
||||||
while (*s1 != '\0' && *s2 != '\0' && *s1++ == *s2++)
|
while (*s1 != '\0' && *s2 != '\0' && *s1++ == *s2++)
|
||||||
result++;
|
result++;
|
||||||
|
|
||||||
|
g_free (fs1);
|
||||||
|
g_free (fs2);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/* The directory names are arranged in a single linked list in the same
|
/** The directory names are arranged in a single linked list in the same
|
||||||
order as they are displayed. When the tree is displayed the expected
|
* order as they are displayed. When the tree is displayed the expected
|
||||||
order is like this:
|
* order is like this:
|
||||||
/
|
* /
|
||||||
/bin
|
* /bin
|
||||||
/etc
|
* /etc
|
||||||
/etc/X11
|
* /etc/X11
|
||||||
/etc/rc.d
|
* /etc/rc.d
|
||||||
/etc.old/X11
|
* /etc.old/X11
|
||||||
/etc.old/rc.d
|
* /etc.old/rc.d
|
||||||
/usr
|
* /usr
|
||||||
|
*
|
||||||
i.e. the required collating sequence when comparing two directory names is
|
* i.e. the required collating sequence when comparing two directory names is
|
||||||
'\0' < PATH_SEP < all-other-characters-in-encoding-order
|
* '\0' < PATH_SEP < all-other-characters-in-encoding-order
|
||||||
|
*
|
||||||
Since strcmp doesn't fulfil this requirement we use pathcmp when
|
* Since strcmp doesn't fulfil this requirement we use pathcmp when
|
||||||
inserting directory names into the list. The meaning of the return value
|
* inserting directory names into the list. The meaning of the return value
|
||||||
of pathcmp and strcmp are the same (an integer less than, equal to, or
|
* of pathcmp and strcmp are the same (an integer less than, equal to, or
|
||||||
greater than zero if p1 is found to be less than, to match, or be greater
|
* greater than zero if p1 is found to be less than, to match, or be greater
|
||||||
than p2.
|
* than p2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pathcmp (const char *p1, const char *p2)
|
pathcmp (const vfs_path_t * p1_vpath, const vfs_path_t * p2_vpath)
|
||||||
{
|
{
|
||||||
|
int ret_val;
|
||||||
|
char *p1, *fp1;
|
||||||
|
char *p2, *fp2;
|
||||||
|
|
||||||
|
p1 = fp1 = vfs_path_to_str (p1_vpath);
|
||||||
|
p2 = fp2 = vfs_path_to_str (p2_vpath);
|
||||||
|
|
||||||
for (; *p1 == *p2; p1++, p2++)
|
for (; *p1 == *p2; p1++, p2++)
|
||||||
if (*p1 == '\0')
|
if (*p1 == '\0')
|
||||||
|
{
|
||||||
|
g_free (fp1);
|
||||||
|
g_free (fp2);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (*p1 == '\0')
|
if (*p1 == '\0')
|
||||||
return -1;
|
ret_val = -1;
|
||||||
if (*p2 == '\0')
|
else if (*p2 == '\0')
|
||||||
return 1;
|
ret_val = 1;
|
||||||
if (*p1 == PATH_SEP)
|
else if (*p1 == PATH_SEP)
|
||||||
return -1;
|
ret_val = -1;
|
||||||
if (*p2 == PATH_SEP)
|
else if (*p2 == PATH_SEP)
|
||||||
return 1;
|
ret_val = 1;
|
||||||
return (*p1 - *p2);
|
else
|
||||||
|
ret_val = (*p1 - *p2);
|
||||||
|
|
||||||
|
g_free (fp1);
|
||||||
|
g_free (fp2);
|
||||||
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -250,11 +279,17 @@ tree_store_load_from (char *name)
|
|||||||
different = strtok (NULL, "");
|
different = strtok (NULL, "");
|
||||||
if (different)
|
if (different)
|
||||||
{
|
{
|
||||||
vfs_path_t *vpath = vfs_path_from_str (oldname);
|
vfs_path_t *vpath;
|
||||||
|
|
||||||
|
vpath = vfs_path_from_str (oldname);
|
||||||
strcpy (oldname + common, different);
|
strcpy (oldname + common, different);
|
||||||
if (vfs_file_is_local (vpath))
|
if (vfs_file_is_local (vpath))
|
||||||
{
|
{
|
||||||
e = tree_store_add_entry (oldname);
|
vfs_path_t *tmp_vpath;
|
||||||
|
|
||||||
|
tmp_vpath = vfs_path_from_str (oldname);
|
||||||
|
e = tree_store_add_entry (tmp_vpath);
|
||||||
|
vfs_path_free (tmp_vpath);
|
||||||
e->scanned = scanned;
|
e->scanned = scanned;
|
||||||
}
|
}
|
||||||
vfs_path_free (vpath);
|
vfs_path_free (vpath);
|
||||||
@ -263,10 +298,12 @@ tree_store_load_from (char *name)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vfs_path_t *vpath = vfs_path_from_str (lc_name);
|
vfs_path_t *vpath;
|
||||||
|
|
||||||
|
vpath = vfs_path_from_str (lc_name);
|
||||||
if (vfs_file_is_local (vpath))
|
if (vfs_file_is_local (vpath))
|
||||||
{
|
{
|
||||||
e = tree_store_add_entry (lc_name);
|
e = tree_store_add_entry (vpath);
|
||||||
e->scanned = scanned;
|
e->scanned = scanned;
|
||||||
}
|
}
|
||||||
vfs_path_free (vpath);
|
vfs_path_free (vpath);
|
||||||
@ -281,7 +318,7 @@ tree_store_load_from (char *name)
|
|||||||
if (!ts.tree_first)
|
if (!ts.tree_first)
|
||||||
{
|
{
|
||||||
vfs_path_t *tmp_vpath = vfs_path_from_str (PATH_SEP_STR);
|
vfs_path_t *tmp_vpath = vfs_path_from_str (PATH_SEP_STR);
|
||||||
tree_store_add_entry (PATH_SEP_STR);
|
tree_store_add_entry (tmp_vpath);
|
||||||
tree_store_rescan (tmp_vpath);
|
tree_store_rescan (tmp_vpath);
|
||||||
vfs_path_free (tmp_vpath);
|
vfs_path_free (tmp_vpath);
|
||||||
ts.loaded = TRUE;
|
ts.loaded = TRUE;
|
||||||
@ -293,43 +330,14 @@ tree_store_load_from (char *name)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
encode (const char *string)
|
encode (const vfs_path_t * vpath, size_t offset)
|
||||||
{
|
{
|
||||||
int special_chars;
|
char *string, *ret_val;
|
||||||
const char *p;
|
|
||||||
char *q;
|
|
||||||
char *res;
|
|
||||||
|
|
||||||
for (special_chars = 0, p = string; *p; p++)
|
string = vfs_path_to_str (vpath);
|
||||||
{
|
ret_val = strutils_escape (string + offset, -1, "\n\\", FALSE);
|
||||||
if (*p == '\n' || *p == '\\')
|
g_free (string);
|
||||||
special_chars++;
|
return ret_val;
|
||||||
}
|
|
||||||
|
|
||||||
res = g_malloc (p - string + special_chars + 1);
|
|
||||||
for (p = string, q = res; *p; p++, q++)
|
|
||||||
{
|
|
||||||
if (*p != '\n' && *p != '\\')
|
|
||||||
{
|
|
||||||
*q = *p;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*q++ = '\\';
|
|
||||||
|
|
||||||
switch (*p)
|
|
||||||
{
|
|
||||||
case '\n':
|
|
||||||
*q = 'n';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\\':
|
|
||||||
*q = '\\';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*q = 0;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -351,21 +359,20 @@ tree_store_save_to (char *name)
|
|||||||
while (current)
|
while (current)
|
||||||
{
|
{
|
||||||
int i, common;
|
int i, common;
|
||||||
vfs_path_t *vpath = vfs_path_from_str (current->name);
|
|
||||||
|
|
||||||
if (vfs_file_is_local (vpath))
|
if (vfs_file_is_local (current->name))
|
||||||
{
|
{
|
||||||
/* Clear-text compression */
|
/* Clear-text compression */
|
||||||
if (current->prev && (common = str_common (current->prev->name, current->name)) > 2)
|
if (current->prev && (common = str_common (current->prev->name, current->name)) > 2)
|
||||||
{
|
{
|
||||||
char *encoded = encode (current->name + common);
|
char *encoded = encode (current->name, common);
|
||||||
|
|
||||||
i = fprintf (file, "%d:%d %s\n", current->scanned, common, encoded);
|
i = fprintf (file, "%d:%d %s\n", current->scanned, common, encoded);
|
||||||
g_free (encoded);
|
g_free (encoded);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *encoded = encode (current->name);
|
char *encoded = encode (current->name, 0);
|
||||||
|
|
||||||
i = fprintf (file, "%d:%s\n", current->scanned, encoded);
|
i = fprintf (file, "%d:%s\n", current->scanned, encoded);
|
||||||
g_free (encoded);
|
g_free (encoded);
|
||||||
@ -375,11 +382,9 @@ tree_store_save_to (char *name)
|
|||||||
{
|
{
|
||||||
fprintf (stderr, _("Cannot write to the %s file:\n%s\n"),
|
fprintf (stderr, _("Cannot write to the %s file:\n%s\n"),
|
||||||
name, unix_error_string (errno));
|
name, unix_error_string (errno));
|
||||||
vfs_path_free (vpath);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vfs_path_free (vpath);
|
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
tree_store_dirty (FALSE);
|
tree_store_dirty (FALSE);
|
||||||
@ -391,13 +396,12 @@ tree_store_save_to (char *name)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static tree_entry *
|
static tree_entry *
|
||||||
tree_store_add_entry (const char *name)
|
tree_store_add_entry (const vfs_path_t * name)
|
||||||
{
|
{
|
||||||
int flag = -1;
|
int flag = -1;
|
||||||
tree_entry *current = ts.tree_first;
|
tree_entry *current = ts.tree_first;
|
||||||
tree_entry *old = NULL;
|
tree_entry *old = NULL;
|
||||||
tree_entry *new;
|
tree_entry *new;
|
||||||
int i, len;
|
|
||||||
int submask = 0;
|
int submask = 0;
|
||||||
|
|
||||||
if (ts.tree_last && ts.tree_last->next)
|
if (ts.tree_last && ts.tree_last->next)
|
||||||
@ -452,15 +456,16 @@ tree_store_add_entry (const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate attributes */
|
/* Calculate attributes */
|
||||||
new->name = g_strdup (name);
|
new->name = vfs_path_clone (name);
|
||||||
len = strlen (new->name);
|
new->sublevel = vfs_path_tokens_count (new->name) + 1;
|
||||||
new->sublevel = 0;
|
{
|
||||||
for (i = 0; i < len; i++)
|
const char *new_name;
|
||||||
if (new->name[i] == PATH_SEP)
|
|
||||||
{
|
new_name = vfs_path_get_last_path_str (new->name);
|
||||||
new->sublevel++;
|
new->subname = strrchr (new_name, '/');
|
||||||
new->subname = new->name + i + 1;
|
if (new->subname == NULL)
|
||||||
}
|
new->subname = new_name;
|
||||||
|
}
|
||||||
if (new->next)
|
if (new->next)
|
||||||
submask = new->next->submask;
|
submask = new->next->submask;
|
||||||
else
|
else
|
||||||
@ -483,18 +488,11 @@ tree_store_add_entry (const char *name)
|
|||||||
if (new->sublevel > 1)
|
if (new->sublevel > 1)
|
||||||
{
|
{
|
||||||
/* Let's check if the parent directory is in the tree */
|
/* Let's check if the parent directory is in the tree */
|
||||||
char *parent = g_strdup (new->name);
|
vfs_path_t *tmp_vpath;
|
||||||
|
|
||||||
for (i = strlen (parent) - 1; i > 1; i--)
|
tmp_vpath = vfs_path_vtokens_get (new->name, 0, new->sublevel - 1);
|
||||||
{
|
tree_store_add_entry (tmp_vpath);
|
||||||
if (parent[i] == PATH_SEP)
|
vfs_path_free (tmp_vpath);
|
||||||
{
|
|
||||||
parent[i] = 0;
|
|
||||||
tree_store_add_entry (parent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_free (parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tree_store_dirty (TRUE);
|
tree_store_dirty (TRUE);
|
||||||
@ -587,11 +585,13 @@ process_special_dirs (GList ** special_dirs, char *file)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
should_skip_directory (const char *dir)
|
should_skip_directory (const vfs_path_t * vpath)
|
||||||
{
|
{
|
||||||
static GList *special_dirs = NULL;
|
static GList *special_dirs = NULL;
|
||||||
GList *l;
|
GList *l;
|
||||||
static gboolean loaded = FALSE;
|
static gboolean loaded = FALSE;
|
||||||
|
char *dir;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
if (!loaded)
|
if (!loaded)
|
||||||
{
|
{
|
||||||
@ -601,11 +601,16 @@ should_skip_directory (const char *dir)
|
|||||||
process_special_dirs (&special_dirs, global_profile_name);
|
process_special_dirs (&special_dirs, global_profile_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dir = vfs_path_to_str (vpath);
|
||||||
for (l = special_dirs; l != NULL; l = g_list_next (l))
|
for (l = special_dirs; l != NULL; l = g_list_next (l))
|
||||||
if (strncmp (dir, l->data, strlen (l->data)) == 0)
|
if (strncmp (dir, l->data, strlen (l->data)) == 0)
|
||||||
return TRUE;
|
{
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
g_free (dir);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -614,7 +619,7 @@ should_skip_directory (const char *dir)
|
|||||||
|
|
||||||
/* Searches for specified directory */
|
/* Searches for specified directory */
|
||||||
tree_entry *
|
tree_entry *
|
||||||
tree_store_whereis (const char *name)
|
tree_store_whereis (const vfs_path_t * name)
|
||||||
{
|
{
|
||||||
tree_entry *current = ts.tree_first;
|
tree_entry *current = ts.tree_first;
|
||||||
int flag = -1;
|
int flag = -1;
|
||||||
@ -705,36 +710,48 @@ tree_store_remove_entry_remove_hook (tree_store_remove_fn callback)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void
|
void
|
||||||
tree_store_remove_entry (const char *name)
|
tree_store_remove_entry (const vfs_path_t * name_vpath)
|
||||||
{
|
{
|
||||||
tree_entry *current, *base, *old;
|
tree_entry *current, *base, *old;
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
g_return_if_fail (name != NULL);
|
g_return_if_fail (name_vpath != NULL);
|
||||||
|
|
||||||
/* Miguel Ugly hack */
|
/* Miguel Ugly hack */
|
||||||
if (name[0] == PATH_SEP && name[1] == 0)
|
{
|
||||||
return;
|
char *name;
|
||||||
|
gboolean is_root;
|
||||||
|
|
||||||
|
name = vfs_path_to_str (name_vpath);
|
||||||
|
is_root = (name[0] == PATH_SEP && name[1] == '\0');
|
||||||
|
g_free (name);
|
||||||
|
if (is_root)
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Miguel Ugly hack end */
|
/* Miguel Ugly hack end */
|
||||||
|
|
||||||
base = tree_store_whereis (name);
|
base = tree_store_whereis (name_vpath);
|
||||||
if (!base)
|
if (!base)
|
||||||
return; /* Doesn't exist */
|
return; /* Doesn't exist */
|
||||||
|
|
||||||
len = strlen (base->name);
|
len = vfs_path_len (base->name);
|
||||||
current = base->next;
|
current = base->next;
|
||||||
while (current
|
while (current != NULL && vfs_path_ncmp (current->name, base->name, len) == 0)
|
||||||
&& strncmp (current->name, base->name, len) == 0
|
|
||||||
&& (current->name[len] == '\0' || current->name[len] == PATH_SEP))
|
|
||||||
{
|
{
|
||||||
|
char *current_name;
|
||||||
|
gboolean ok;
|
||||||
|
|
||||||
|
current_name = vfs_path_to_str (current->name);
|
||||||
|
ok = (current_name[len] == '\0' || current_name[len] == PATH_SEP);
|
||||||
|
g_free (current_name);
|
||||||
|
if (!ok)
|
||||||
|
break;
|
||||||
old = current;
|
old = current;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
remove_entry (old);
|
remove_entry (old);
|
||||||
}
|
}
|
||||||
remove_entry (base);
|
remove_entry (base);
|
||||||
tree_store_dirty (TRUE);
|
tree_store_dirty (TRUE);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -743,9 +760,10 @@ tree_store_remove_entry (const char *name)
|
|||||||
void
|
void
|
||||||
tree_store_mark_checked (const char *subname)
|
tree_store_mark_checked (const char *subname)
|
||||||
{
|
{
|
||||||
char *name;
|
vfs_path_t *name;
|
||||||
|
char *check_name;
|
||||||
tree_entry *current, *base;
|
tree_entry *current, *base;
|
||||||
int flag = 1, len;
|
int flag = 1;
|
||||||
if (!ts.loaded)
|
if (!ts.loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -755,10 +773,13 @@ tree_store_mark_checked (const char *subname)
|
|||||||
/* Calculate the full name of the subdirectory */
|
/* Calculate the full name of the subdirectory */
|
||||||
if (subname[0] == '.' && (subname[1] == 0 || (subname[1] == '.' && subname[2] == 0)))
|
if (subname[0] == '.' && (subname[1] == 0 || (subname[1] == '.' && subname[2] == 0)))
|
||||||
return;
|
return;
|
||||||
if (ts.check_name[0] == PATH_SEP && ts.check_name[1] == 0)
|
|
||||||
name = g_strconcat (PATH_SEP_STR, subname, (char *) NULL);
|
check_name = vfs_path_to_str (ts.check_name);
|
||||||
|
if (check_name[0] == PATH_SEP && check_name[1] == 0)
|
||||||
|
name = vfs_path_build_filename (PATH_SEP_STR, subname, NULL);
|
||||||
else
|
else
|
||||||
name = concat_dir_and_file (ts.check_name, subname);
|
name = vfs_path_append_new (ts.check_name, subname, NULL);
|
||||||
|
g_free (check_name);
|
||||||
|
|
||||||
/* Search for the subdirectory */
|
/* Search for the subdirectory */
|
||||||
current = ts.check_start;
|
current = ts.check_start;
|
||||||
@ -769,7 +790,7 @@ tree_store_mark_checked (const char *subname)
|
|||||||
{
|
{
|
||||||
/* Doesn't exist -> add it */
|
/* Doesn't exist -> add it */
|
||||||
current = tree_store_add_entry (name);
|
current = tree_store_add_entry (name);
|
||||||
ts.add_queue = g_list_prepend (ts.add_queue, g_strdup (name));
|
ts.add_queue_vpath = g_list_prepend (ts.add_queue_vpath, vfs_path_clone (name));
|
||||||
}
|
}
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
@ -777,13 +798,20 @@ tree_store_mark_checked (const char *subname)
|
|||||||
base = current;
|
base = current;
|
||||||
if (base)
|
if (base)
|
||||||
{
|
{
|
||||||
len = strlen (base->name);
|
size_t len;
|
||||||
|
|
||||||
|
len = vfs_path_len (base->name);
|
||||||
base->mark = 0;
|
base->mark = 0;
|
||||||
current = base->next;
|
current = base->next;
|
||||||
while (current
|
while (current != NULL && vfs_path_ncmp (current->name, base->name, len) == 0)
|
||||||
&& strncmp (current->name, base->name, len) == 0
|
|
||||||
&& (current->name[len] == '\0' || current->name[len] == PATH_SEP || len == 1))
|
|
||||||
{
|
{
|
||||||
|
gboolean ok;
|
||||||
|
|
||||||
|
check_name = vfs_path_to_str (current->name);
|
||||||
|
ok = (check_name[len] == '\0' || check_name[len] == PATH_SEP || len == 1);
|
||||||
|
g_free (check_name);
|
||||||
|
if (!ok)
|
||||||
|
break;
|
||||||
current->mark = 0;
|
current->mark = 0;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
@ -794,7 +822,7 @@ tree_store_mark_checked (const char *subname)
|
|||||||
/** Mark the subdirectories of the current directory for delete */
|
/** Mark the subdirectories of the current directory for delete */
|
||||||
|
|
||||||
tree_entry *
|
tree_entry *
|
||||||
tree_store_start_check (const char *path)
|
tree_store_start_check (const vfs_path_t * vpath)
|
||||||
{
|
{
|
||||||
tree_entry *current, *retval;
|
tree_entry *current, *retval;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -806,41 +834,42 @@ tree_store_start_check (const char *path)
|
|||||||
ts.check_start = NULL;
|
ts.check_start = NULL;
|
||||||
|
|
||||||
/* Search for the start of subdirectories */
|
/* Search for the start of subdirectories */
|
||||||
current = tree_store_whereis (path);
|
current = tree_store_whereis (vpath);
|
||||||
if (!current)
|
if (!current)
|
||||||
{
|
{
|
||||||
struct stat s;
|
struct stat s;
|
||||||
vfs_path_t *vpath = vfs_path_from_str (path);
|
|
||||||
|
|
||||||
if (mc_stat (vpath, &s) == -1)
|
if (mc_stat (vpath, &s) == -1)
|
||||||
{
|
|
||||||
vfs_path_free (vpath);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
vfs_path_free (vpath);
|
|
||||||
|
|
||||||
if (!S_ISDIR (s.st_mode))
|
if (!S_ISDIR (s.st_mode))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
current = tree_store_add_entry (path);
|
current = tree_store_add_entry (vpath);
|
||||||
ts.check_name = g_strdup (path);
|
ts.check_name = vfs_path_clone (vpath);
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
ts.check_name = g_strdup (path);
|
ts.check_name = vfs_path_clone (vpath);
|
||||||
|
|
||||||
retval = current;
|
retval = current;
|
||||||
|
|
||||||
/* Mark old subdirectories for delete */
|
/* Mark old subdirectories for delete */
|
||||||
ts.check_start = current->next;
|
ts.check_start = current->next;
|
||||||
len = strlen (ts.check_name);
|
len = vfs_path_len (ts.check_name);
|
||||||
|
|
||||||
current = ts.check_start;
|
current = ts.check_start;
|
||||||
while (current
|
while (current != NULL && vfs_path_cmp (current->name, ts.check_name) == 0)
|
||||||
&& strncmp (current->name, ts.check_name, len) == 0
|
|
||||||
&& (current->name[len] == '\0' || current->name[len] == PATH_SEP || len == 1))
|
|
||||||
{
|
{
|
||||||
|
char *current_name;
|
||||||
|
gboolean ok;
|
||||||
|
|
||||||
|
current_name = vfs_path_to_str (current->name);
|
||||||
|
ok = (current_name[len] == '\0' || (current_name[len] == PATH_SEP || len == 1));
|
||||||
|
g_free (current_name);
|
||||||
|
if (!ok)
|
||||||
|
break;
|
||||||
current->mark = 1;
|
current->mark = 1;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
@ -864,13 +893,20 @@ tree_store_end_check (void)
|
|||||||
g_return_if_fail (ts.check_name != NULL);
|
g_return_if_fail (ts.check_name != NULL);
|
||||||
|
|
||||||
/* Check delete marks and delete if found */
|
/* Check delete marks and delete if found */
|
||||||
len = strlen (ts.check_name);
|
len = vfs_path_len (ts.check_name);
|
||||||
|
|
||||||
current = ts.check_start;
|
current = ts.check_start;
|
||||||
while (current
|
while (current != NULL && vfs_path_ncmp (current->name, ts.check_name, len) == 0)
|
||||||
&& strncmp (current->name, ts.check_name, len) == 0
|
|
||||||
&& (current->name[len] == '\0' || current->name[len] == PATH_SEP || len == 1))
|
|
||||||
{
|
{
|
||||||
|
char *current_name;
|
||||||
|
gboolean ok;
|
||||||
|
|
||||||
|
current_name = vfs_path_to_str (current->name);
|
||||||
|
ok = (current_name[len] == '\0' || current_name[len] == PATH_SEP || len == 1);
|
||||||
|
g_free (current_name);
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
break;
|
||||||
old = current;
|
old = current;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
if (old->mark)
|
if (old->mark)
|
||||||
@ -878,13 +914,13 @@ tree_store_end_check (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get the stuff in the scan order */
|
/* get the stuff in the scan order */
|
||||||
ts.add_queue = g_list_reverse (ts.add_queue);
|
ts.add_queue_vpath = g_list_reverse (ts.add_queue_vpath);
|
||||||
the_queue = ts.add_queue;
|
the_queue = ts.add_queue_vpath;
|
||||||
ts.add_queue = NULL;
|
ts.add_queue_vpath = NULL;
|
||||||
g_free (ts.check_name);
|
g_free (ts.check_name);
|
||||||
ts.check_name = NULL;
|
ts.check_name = NULL;
|
||||||
|
|
||||||
g_list_foreach (the_queue, (GFunc) g_free, NULL);
|
g_list_foreach (the_queue, (GFunc) vfs_path_free, NULL);
|
||||||
g_list_free (the_queue);
|
g_list_free (the_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -897,23 +933,17 @@ tree_store_rescan (const vfs_path_t * vpath)
|
|||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
tree_entry *entry;
|
tree_entry *entry;
|
||||||
char *dir = vfs_path_to_str (vpath);
|
|
||||||
|
|
||||||
if (should_skip_directory (dir))
|
if (should_skip_directory (vpath))
|
||||||
{
|
{
|
||||||
entry = tree_store_add_entry (dir);
|
entry = tree_store_add_entry (vpath);
|
||||||
entry->scanned = 1;
|
entry->scanned = 1;
|
||||||
g_free (dir);
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = tree_store_start_check (dir);
|
entry = tree_store_start_check (vpath);
|
||||||
|
if (entry == NULL)
|
||||||
if (!entry)
|
|
||||||
{
|
|
||||||
g_free (dir);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
dirp = mc_opendir (vpath);
|
dirp = mc_opendir (vpath);
|
||||||
if (dirp)
|
if (dirp)
|
||||||
@ -940,7 +970,6 @@ tree_store_rescan (const vfs_path_t * vpath)
|
|||||||
}
|
}
|
||||||
tree_store_end_check ();
|
tree_store_end_check ();
|
||||||
entry->scanned = 1;
|
entry->scanned = 1;
|
||||||
g_free (dir);
|
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ typedef void (*tree_store_remove_fn) (struct tree_entry * tree, void *data);
|
|||||||
|
|
||||||
typedef struct tree_entry
|
typedef struct tree_entry
|
||||||
{
|
{
|
||||||
char *name; /* The full path of directory */
|
vfs_path_t *name; /* The full path of directory */
|
||||||
int sublevel; /* Number of parent directories (slashes) */
|
int sublevel; /* Number of parent directories (slashes) */
|
||||||
long submask; /* Bitmask of existing sublevels after this entry */
|
long submask; /* Bitmask of existing sublevels after this entry */
|
||||||
const char *subname; /* The last part of name (the actual name) */
|
const char *subname; /* The last part of name (the actual name) */
|
||||||
@ -36,8 +36,8 @@ struct TreeStore
|
|||||||
tree_entry *tree_first; /* First entry in the list */
|
tree_entry *tree_first; /* First entry in the list */
|
||||||
tree_entry *tree_last; /* Last entry in the list */
|
tree_entry *tree_last; /* Last entry in the list */
|
||||||
tree_entry *check_start; /* Start of checked subdirectories */
|
tree_entry *check_start; /* Start of checked subdirectories */
|
||||||
char *check_name;
|
vfs_path_t *check_name;
|
||||||
GList *add_queue; /* List of strings of added directories */
|
GList *add_queue_vpath; /* List of vfs_path_t objects of added directories */
|
||||||
unsigned int loaded:1;
|
unsigned int loaded:1;
|
||||||
unsigned int dirty:1;
|
unsigned int dirty:1;
|
||||||
};
|
};
|
||||||
@ -49,11 +49,11 @@ struct TreeStore
|
|||||||
struct TreeStore *tree_store_get (void);
|
struct TreeStore *tree_store_get (void);
|
||||||
int tree_store_load (void);
|
int tree_store_load (void);
|
||||||
int tree_store_save (void);
|
int tree_store_save (void);
|
||||||
void tree_store_remove_entry (const char *name);
|
void tree_store_remove_entry (const vfs_path_t * name_vpath);
|
||||||
tree_entry *tree_store_start_check (const char *path);
|
tree_entry *tree_store_start_check (const vfs_path_t * vpath);
|
||||||
void tree_store_mark_checked (const char *subname);
|
void tree_store_mark_checked (const char *subname);
|
||||||
void tree_store_end_check (void);
|
void tree_store_end_check (void);
|
||||||
tree_entry *tree_store_whereis (const char *name);
|
tree_entry *tree_store_whereis (const vfs_path_t * name);
|
||||||
tree_entry *tree_store_rescan (const vfs_path_t * vpath);
|
tree_entry *tree_store_rescan (const vfs_path_t * vpath);
|
||||||
|
|
||||||
void tree_store_add_entry_remove_hook (tree_store_remove_fn callback, void *data);
|
void tree_store_add_entry_remove_hook (tree_store_remove_fn callback, void *data);
|
||||||
|
Loading…
Reference in New Issue
Block a user