mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-03 01:54:24 +03:00
Export access to the treestore
Make gtkdtree use the treestore cache. Next step: store the ->scanned attribute of tree_entry (otherwise, no speedup will be noticed at all). It is a 10 minute hack, but I will go have dinner now. Miguel.
This commit is contained in:
parent
7bae04e59d
commit
4c6fef14d8
@ -1,3 +1,7 @@
|
|||||||
|
1999-01-10 Ilya Zakharevich <ilya@math.ohio-state.edu>
|
||||||
|
|
||||||
|
* gtkedit/edit.c (edit_load_file): Off-by-one error disabled editing.
|
||||||
|
|
||||||
1999-01-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
1999-01-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||||
|
|
||||||
* configure.in (REGEX_O): Always include regex.o as the code we
|
* configure.in (REGEX_O): Always include regex.o as the code we
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
1999-01-12 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||||
|
|
||||||
|
* gtkdtree.c: Now it uses the treestore code.
|
||||||
|
|
||||||
|
* treestore.c: Provide _opendir, _readdir, _closedir operations
|
||||||
|
for the tree cache.
|
||||||
|
|
||||||
|
Next step: load/save the tree_entry->scanned flag (without this,
|
||||||
|
you wont notice a big speedup).
|
||||||
|
|
||||||
1999-01-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
1999-01-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||||
|
|
||||||
* gutil.c (my_system_get_child_pid): Acknowledge new EXECUTE_WAIT
|
* gutil.c (my_system_get_child_pid): Acknowledge new EXECUTE_WAIT
|
||||||
|
112
gnome/gtkdtree.c
112
gnome/gtkdtree.c
@ -7,6 +7,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "treestore.h"
|
||||||
#include <gnome.h>
|
#include <gnome.h>
|
||||||
#include "gtkdtree.h"
|
#include "gtkdtree.h"
|
||||||
|
|
||||||
@ -14,7 +16,6 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "../vfs/vfs.h"
|
|
||||||
#include "dir-open.xpm"
|
#include "dir-open.xpm"
|
||||||
#include "dir-close.xpm"
|
#include "dir-close.xpm"
|
||||||
|
|
||||||
@ -101,46 +102,26 @@ gtk_dtree_contains (GtkDTree *dtree, GtkCTreeNode *parent, char *text)
|
|||||||
static gboolean
|
static gboolean
|
||||||
gtk_dtree_load_path (GtkDTree *dtree, char *path, GtkCTreeNode *parent, int level)
|
gtk_dtree_load_path (GtkDTree *dtree, char *path, GtkCTreeNode *parent, int level)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
tree_scan *dir;
|
||||||
struct dirent *dirent;
|
tree_entry *dirent;
|
||||||
|
|
||||||
g_assert (path);
|
g_assert (path);
|
||||||
g_assert (parent);
|
g_assert (parent);
|
||||||
g_assert (dtree);
|
g_assert (dtree);
|
||||||
|
|
||||||
dir = mc_opendir (path);
|
dir = tree_store_opendir (path);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (; (dirent = mc_readdir (dir)) != NULL; ){
|
for (; (dirent = tree_store_readdir (dir)) != NULL; ){
|
||||||
GtkCTreeNode *sibling;
|
GtkCTreeNode *sibling;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
char *full_name;
|
|
||||||
char *text [1];
|
char *text [1];
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (dirent->d_name [0] == '.'){
|
res = mc_stat (dirent->name, &s);
|
||||||
if (dirent->d_name [1] == '.'){
|
|
||||||
if (dirent->d_name [2] == 0)
|
|
||||||
continue;
|
|
||||||
} else if (dirent->d_name [1] == 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
full_name = g_concat_dir_and_file (path, dirent->d_name);
|
text [0] = x_basename (dirent->name);
|
||||||
res = mc_stat (full_name, &s);
|
|
||||||
|
|
||||||
if (res == -1){
|
|
||||||
g_free (full_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!S_ISDIR (s.st_mode)){
|
|
||||||
g_free (full_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
text [0] = dirent->d_name;
|
|
||||||
|
|
||||||
/* Do not insert duplicates */
|
/* Do not insert duplicates */
|
||||||
sibling = gtk_dtree_contains (dtree, parent, text [0]);
|
sibling = gtk_dtree_contains (dtree, parent, text [0]);
|
||||||
@ -158,15 +139,13 @@ gtk_dtree_load_path (GtkDTree *dtree, char *path, GtkCTreeNode *parent, int leve
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (level)
|
if (level)
|
||||||
gtk_dtree_load_path (dtree, full_name, sibling, level-1);
|
gtk_dtree_load_path (dtree, dirent->name, sibling, level-1);
|
||||||
|
|
||||||
g_free (full_name);
|
|
||||||
|
|
||||||
if (!level)
|
if (!level)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mc_closedir (dir);
|
tree_store_closedir (dir);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -195,7 +174,8 @@ gtk_dtree_select_row (GtkCTree *ctree, GtkCTreeNode *row, gint column)
|
|||||||
|
|
||||||
dtree->current_path = path;
|
dtree->current_path = path;
|
||||||
|
|
||||||
gtk_signal_emit (GTK_OBJECT (ctree), gtk_dtree_signals [DIRECTORY_CHANGED], path);
|
if (!dtree->internal)
|
||||||
|
gtk_signal_emit (GTK_OBJECT (ctree), gtk_dtree_signals [DIRECTORY_CHANGED], path);
|
||||||
|
|
||||||
gtk_dtree_load_path (dtree, path, row, 1);
|
gtk_dtree_load_path (dtree, path, row, 1);
|
||||||
#if 0
|
#if 0
|
||||||
@ -248,7 +228,8 @@ gtk_dtree_do_select_dir (GtkDTree *dtree, char *path)
|
|||||||
{
|
{
|
||||||
GtkCTreeNode *current_node;
|
GtkCTreeNode *current_node;
|
||||||
char *s, *current, *npath;
|
char *s, *current, *npath;
|
||||||
|
char *request;
|
||||||
|
|
||||||
g_return_val_if_fail (dtree != NULL, FALSE);
|
g_return_val_if_fail (dtree != NULL, FALSE);
|
||||||
g_return_val_if_fail (GTK_IS_DTREE (dtree), FALSE);
|
g_return_val_if_fail (GTK_IS_DTREE (dtree), FALSE);
|
||||||
g_return_val_if_fail (path != NULL, FALSE);
|
g_return_val_if_fail (path != NULL, FALSE);
|
||||||
@ -256,7 +237,7 @@ gtk_dtree_do_select_dir (GtkDTree *dtree, char *path)
|
|||||||
|
|
||||||
if (dtree->current_path && (strcmp (path, dtree->current_path) == 0))
|
if (dtree->current_path && (strcmp (path, dtree->current_path) == 0))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
s = alloca (strlen (path)+1);
|
s = alloca (strlen (path)+1);
|
||||||
strcpy (s, path);
|
strcpy (s, path);
|
||||||
current_node = dtree->root_node;
|
current_node = dtree->root_node;
|
||||||
@ -264,6 +245,7 @@ gtk_dtree_do_select_dir (GtkDTree *dtree, char *path)
|
|||||||
s++;
|
s++;
|
||||||
npath = g_strdup ("/");
|
npath = g_strdup ("/");
|
||||||
|
|
||||||
|
dtree->internal = 1;
|
||||||
while ((current = strtok (s, "/")) != NULL){
|
while ((current = strtok (s, "/")) != NULL){
|
||||||
char *full_path;
|
char *full_path;
|
||||||
GtkCTreeNode *node;
|
GtkCTreeNode *node;
|
||||||
@ -282,14 +264,12 @@ gtk_dtree_do_select_dir (GtkDTree *dtree, char *path)
|
|||||||
|
|
||||||
if (node){
|
if (node){
|
||||||
gtk_ctree_expand (GTK_CTREE (dtree), node);
|
gtk_ctree_expand (GTK_CTREE (dtree), node);
|
||||||
while (gtk_events_pending ())
|
|
||||||
gtk_main_iteration ();
|
|
||||||
current_node = node;
|
current_node = node;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
g_free (npath);
|
g_free (npath);
|
||||||
|
|
||||||
if (current_node){
|
if (current_node){
|
||||||
if (!gtk_ctree_node_is_visible (GTK_CTREE (dtree), current_node)){
|
if (!gtk_ctree_node_is_visible (GTK_CTREE (dtree), current_node)){
|
||||||
gtk_ctree_node_moveto (GTK_CTREE (dtree), current_node, 0, 0.5, 0.0);
|
gtk_ctree_node_moveto (GTK_CTREE (dtree), current_node, 0, 0.5, 0.0);
|
||||||
@ -306,6 +286,8 @@ gtk_dtree_do_select_dir (GtkDTree *dtree, char *path)
|
|||||||
dtree->requested_path = NULL;
|
dtree->requested_path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dtree->internal = 0;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,10 +313,9 @@ gtk_dtree_select_dir (GtkDTree *dtree, char *path)
|
|||||||
if (dtree->visible)
|
if (dtree->visible)
|
||||||
gtk_dtree_do_select_dir (dtree, path);
|
gtk_dtree_do_select_dir (dtree, path);
|
||||||
else {
|
else {
|
||||||
if (dtree->requested_path){
|
if (dtree->requested_path)
|
||||||
g_free (dtree->requested_path);
|
g_free (dtree->requested_path);
|
||||||
dtree->requested_path = g_strdup (path);
|
dtree->requested_path = g_strdup (path);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -344,7 +325,8 @@ static void
|
|||||||
gtk_dtree_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
|
gtk_dtree_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
|
||||||
{
|
{
|
||||||
GtkDTree *dtree = GTK_DTREE (widget);
|
GtkDTree *dtree = GTK_DTREE (widget);
|
||||||
|
char *request;
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
|
GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
|
||||||
if (allocation->width != 0 && allocation->height != 0)
|
if (allocation->width != 0 && allocation->height != 0)
|
||||||
dtree->visible = TRUE;
|
dtree->visible = TRUE;
|
||||||
@ -353,11 +335,23 @@ gtk_dtree_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
|
|||||||
|
|
||||||
if (!(dtree->visible && dtree->requested_path))
|
if (!(dtree->visible && dtree->requested_path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (strcmp (dtree->current_path, dtree->requested_path) != 0)
|
if (!dtree->visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gtk_dtree_do_select_dir (dtree, dtree->requested_path);
|
if (!dtree->requested_path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (strcmp (dtree->current_path, dtree->requested_path) == 0){
|
||||||
|
g_free (dtree->requested_path);
|
||||||
|
dtree->requested_path = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = dtree->requested_path;
|
||||||
|
dtree->requested_path = NULL;
|
||||||
|
gtk_dtree_do_select_dir (dtree, request);
|
||||||
|
g_free (request);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -481,11 +475,41 @@ gdk_dtree_load_pixmaps (GtkDTree *dtree)
|
|||||||
&dtree->pixmap_close, &dtree->bitmap_close);
|
&dtree->pixmap_close, &dtree->bitmap_close);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dirty_tag = -1;
|
||||||
|
|
||||||
|
static int
|
||||||
|
gtk_dtree_save_tree (void)
|
||||||
|
{
|
||||||
|
dirty_tag = -1;
|
||||||
|
mc_tree_store_save ();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_dtree_dirty_notify (int state)
|
||||||
|
{
|
||||||
|
if (dirty_tag != -1){
|
||||||
|
if (state)
|
||||||
|
return;
|
||||||
|
else {
|
||||||
|
gtk_timeout_remove (dirty_tag);
|
||||||
|
dirty_tag = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state)
|
||||||
|
dirty_tag = gtk_timeout_add (1000, (GtkFunction) gtk_dtree_save_tree, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_dtree_init (GtkDTree *dtree)
|
gtk_dtree_init (GtkDTree *dtree)
|
||||||
{
|
{
|
||||||
|
static int tree_inited;
|
||||||
|
|
||||||
dtree->current_path = NULL;
|
dtree->current_path = NULL;
|
||||||
dtree->auto_expanded_nodes = NULL;
|
dtree->auto_expanded_nodes = NULL;
|
||||||
|
|
||||||
|
tree_store_dirty_notify = gtk_dtree_dirty_notify;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -30,6 +30,8 @@ typedef struct {
|
|||||||
/* Masks */
|
/* Masks */
|
||||||
GdkBitmap *bitmap_open;
|
GdkBitmap *bitmap_open;
|
||||||
GdkBitmap *bitmap_close;
|
GdkBitmap *bitmap_close;
|
||||||
|
|
||||||
|
int internal;
|
||||||
} GtkDTree;
|
} GtkDTree;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -455,7 +455,7 @@ int do_load_dir(dir_list *list, sortfn *sort, int reverse, int case_sensitive, c
|
|||||||
struct stat buf;
|
struct stat buf;
|
||||||
int dotdot_found = 0;
|
int dotdot_found = 0;
|
||||||
|
|
||||||
tree_store_start_check ();
|
tree_store_start_check_cwd ();
|
||||||
|
|
||||||
dirp = mc_opendir (".");
|
dirp = mc_opendir (".");
|
||||||
if (!dirp){
|
if (!dirp){
|
||||||
@ -551,7 +551,7 @@ int do_reload_dir (dir_list *list, sortfn *sort, int count, int rev,
|
|||||||
int tmp_len; /* For optimisation */
|
int tmp_len; /* For optimisation */
|
||||||
int dotdot_found = 0;
|
int dotdot_found = 0;
|
||||||
|
|
||||||
tree_store_start_check ();
|
tree_store_start_check_cwd ();
|
||||||
dirp = mc_opendir (".");
|
dirp = mc_opendir (".");
|
||||||
if (!dirp) {
|
if (!dirp) {
|
||||||
clean_dir (list, count);
|
clean_dir (list, count);
|
||||||
|
24
src/main.c
24
src/main.c
@ -2810,6 +2810,28 @@ compatibility_move_mc_files (void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
mc_tree_store_load ()
|
||||||
|
{
|
||||||
|
char *tree_file;
|
||||||
|
|
||||||
|
tree_file = concat_dir_and_file (home_dir, MC_TREE);
|
||||||
|
tree_store_init ();
|
||||||
|
tree_store_load (tree_file);
|
||||||
|
free (tree_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mc_tree_store_save ()
|
||||||
|
{
|
||||||
|
char *tree_file;
|
||||||
|
|
||||||
|
printf ("Saving tree!\n");
|
||||||
|
tree_file = concat_dir_and_file (home_dir, MC_TREE);
|
||||||
|
tree_store_save (tree_file);
|
||||||
|
free (tree_file);
|
||||||
|
}
|
||||||
|
|
||||||
int main (int argc, char *argv [])
|
int main (int argc, char *argv [])
|
||||||
{
|
{
|
||||||
/* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */
|
/* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */
|
||||||
@ -2857,6 +2879,8 @@ int main (int argc, char *argv [])
|
|||||||
|
|
||||||
handle_args(argc, argv);
|
handle_args(argc, argv);
|
||||||
|
|
||||||
|
mc_tree_store_load ();
|
||||||
|
|
||||||
session_management_setup (argv [0]);
|
session_management_setup (argv [0]);
|
||||||
probably_finish_program ();
|
probably_finish_program ();
|
||||||
#endif
|
#endif
|
||||||
|
@ -187,11 +187,7 @@ void load_tree (WTree *tree)
|
|||||||
|
|
||||||
tree->selected_ptr = tree->store->tree_first;
|
tree->selected_ptr = tree->store->tree_first;
|
||||||
|
|
||||||
if (!v){
|
tree_chdir (tree, home_dir);
|
||||||
tree_store_add_entry (home_dir);
|
|
||||||
tree_chdir (tree, home_dir);
|
|
||||||
tree_store_rescan (home_dir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the .mc.tree file */
|
/* Save the .mc.tree file */
|
||||||
|
152
src/treestore.c
152
src/treestore.c
@ -53,6 +53,17 @@
|
|||||||
|
|
||||||
static TreeStore ts;
|
static TreeStore ts;
|
||||||
|
|
||||||
|
void (*tree_store_dirty_notify)(int state) = NULL;
|
||||||
|
|
||||||
|
void
|
||||||
|
tree_store_dirty (int state)
|
||||||
|
{
|
||||||
|
ts.dirty = state;
|
||||||
|
|
||||||
|
if (tree_store_dirty_notify)
|
||||||
|
(*tree_store_dirty_notify)(state);
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns number of common characters */
|
/* Returns number of common characters */
|
||||||
static int str_common (char *s1, char *s2)
|
static int str_common (char *s1, char *s2)
|
||||||
{
|
{
|
||||||
@ -240,6 +251,7 @@ tree_store_load (char *name)
|
|||||||
if (!ts.tree_first){
|
if (!ts.tree_first){
|
||||||
tree_store_add_entry (PATH_SEP_STR);
|
tree_store_add_entry (PATH_SEP_STR);
|
||||||
tree_store_rescan (PATH_SEP_STR);
|
tree_store_rescan (PATH_SEP_STR);
|
||||||
|
ts.loaded = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -314,6 +326,7 @@ tree_store_save (char *name)
|
|||||||
}
|
}
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
|
tree_store_dirty (FALSE);
|
||||||
fclose (file);
|
fclose (file);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -411,7 +424,8 @@ tree_store_add_entry (char *name)
|
|||||||
}
|
}
|
||||||
free (parent);
|
free (parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree_store_dirty (TRUE);
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,6 +495,7 @@ tree_store_remove_entry (char *name)
|
|||||||
remove_entry (old);
|
remove_entry (old);
|
||||||
}
|
}
|
||||||
remove_entry (base);
|
remove_entry (base);
|
||||||
|
tree_store_dirty (TRUE);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -531,24 +546,37 @@ 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 */
|
||||||
void
|
tree_entry *
|
||||||
tree_store_start_check (void)
|
tree_store_start_check (char *path)
|
||||||
{
|
{
|
||||||
tree_entry *current;
|
tree_entry *current, *retval;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!ts.loaded)
|
if (!ts.loaded)
|
||||||
return;
|
return NULL;
|
||||||
|
|
||||||
/* Search for the start of subdirectories */
|
|
||||||
mc_get_current_wd (ts.check_name, MC_MAXPATHLEN);
|
|
||||||
ts.check_start = NULL;
|
ts.check_start = NULL;
|
||||||
current = tree_store_whereis (ts.check_name);
|
|
||||||
|
/* Search for the start of subdirectories */
|
||||||
|
current = tree_store_whereis (path);
|
||||||
if (!current){
|
if (!current){
|
||||||
/* Cwd doesn't exist -> add it */
|
struct stat s;
|
||||||
current = tree_store_add_entry (ts.check_name);
|
|
||||||
return;
|
if (stat (path, &s) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!S_ISDIR (s.st_mode))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
current = tree_store_add_entry (path);
|
||||||
|
ts.check_name = strdup (path);
|
||||||
|
|
||||||
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ts.check_name = strdup (path);
|
||||||
|
|
||||||
|
retval = current;
|
||||||
|
|
||||||
/* Mark old subdirectories for delete */
|
/* Mark old subdirectories for delete */
|
||||||
ts.check_start = current->next;
|
ts.check_start = current->next;
|
||||||
@ -561,6 +589,17 @@ tree_store_start_check (void)
|
|||||||
current->mark = 1;
|
current->mark = 1;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree_entry *
|
||||||
|
tree_store_start_check_cwd (void)
|
||||||
|
{
|
||||||
|
char buffer [MC_MAXPATHLEN];
|
||||||
|
|
||||||
|
mc_get_current_wd (buffer, MC_MAXPATHLEN);
|
||||||
|
return tree_store_start_check (buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete subdirectories which still have the deletion mark */
|
/* Delete subdirectories which still have the deletion mark */
|
||||||
@ -585,27 +624,45 @@ tree_store_end_check (void)
|
|||||||
if (old->mark)
|
if (old->mark)
|
||||||
remove_entry (old);
|
remove_entry (old);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free (ts.check_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
tree_entry *
|
||||||
tree_store_rescan (char *dir)
|
tree_store_rescan (char *dir)
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
tree_entry *entry;
|
||||||
|
|
||||||
|
entry = tree_store_start_check (dir);
|
||||||
|
|
||||||
tree_store_start_check ();
|
if (!entry)
|
||||||
|
return NULL;
|
||||||
dirp = opendir (dir);
|
|
||||||
|
dirp = mc_opendir (dir);
|
||||||
if (dirp){
|
if (dirp){
|
||||||
for (dp = readdir (dirp); dp; dp = readdir (dirp)){
|
for (dp = mc_readdir (dirp); dp; dp = mc_readdir (dirp)){
|
||||||
lstat (dp->d_name, &buf);
|
char *full_name;
|
||||||
if (S_ISDIR (buf.st_mode))
|
|
||||||
tree_store_mark_checked (dp->d_name);
|
if (dp->d_name [0] == '.' &&
|
||||||
|
dp->d_name [1] == 0 || (dp->d_name [1] == '.' && dp->d_name [2] == 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
full_name = concat_dir_and_file (dir, dp->d_name);
|
||||||
|
if (lstat (full_name, &buf) != -1){
|
||||||
|
if (S_ISDIR (buf.st_mode))
|
||||||
|
tree_store_mark_checked (dp->d_name);
|
||||||
|
}
|
||||||
|
free (full_name);
|
||||||
}
|
}
|
||||||
closedir (dirp);
|
mc_closedir (dirp);
|
||||||
}
|
}
|
||||||
tree_store_end_check ();
|
tree_store_end_check ();
|
||||||
|
entry->scanned = 1;
|
||||||
|
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hook *remove_entry_hooks;
|
static Hook *remove_entry_hooks;
|
||||||
@ -629,3 +686,58 @@ tree_store_notify_remove (tree_entry *entry)
|
|||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree_scan *
|
||||||
|
tree_store_opendir (char *path)
|
||||||
|
{
|
||||||
|
tree_entry *entry;
|
||||||
|
tree_scan *scan;
|
||||||
|
|
||||||
|
entry = tree_store_whereis (path);
|
||||||
|
if (!entry || (entry && !entry->scanned)){
|
||||||
|
entry = tree_store_rescan (path);
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
scan = xmalloc (sizeof (tree_scan), "");
|
||||||
|
scan->base = entry;
|
||||||
|
scan->current = entry->next;
|
||||||
|
scan->sublevel = entry->next->sublevel;
|
||||||
|
|
||||||
|
scan->base_dir_len = strlen (path);
|
||||||
|
return scan;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree_entry *
|
||||||
|
tree_store_readdir (tree_scan *scan)
|
||||||
|
{
|
||||||
|
tree_entry *entry;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
g_assert (scan != NULL);
|
||||||
|
|
||||||
|
len = scan->base_dir_len;
|
||||||
|
entry = scan->current;
|
||||||
|
while (entry &&
|
||||||
|
(strncmp (entry->name, scan->base->name, len) == 0) &&
|
||||||
|
(entry->name [len] == 0 || entry->name [len] == PATH_SEP || len == 1)){
|
||||||
|
|
||||||
|
if (entry->sublevel == scan->sublevel){
|
||||||
|
scan->current = entry->next;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
entry = entry->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tree_store_closedir (tree_scan *scanner)
|
||||||
|
{
|
||||||
|
g_assert (scanner != NULL);
|
||||||
|
|
||||||
|
free (scanner);
|
||||||
|
}
|
||||||
|
@ -6,33 +6,50 @@ typedef struct tree_entry {
|
|||||||
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 */
|
||||||
char *subname; /* The last part of name (the actual name) */
|
char *subname; /* The last part of name (the actual name) */
|
||||||
int mark; /* Flag: Is this entry marked (e. g. for delete)? */
|
unsigned int mark:1; /* Flag: Is this entry marked (e. g. for delete)? */
|
||||||
|
unsigned int scanned:1; /* Flag: childs scanned or not */
|
||||||
struct tree_entry *next; /* Next item in the list */
|
struct tree_entry *next; /* Next item in the list */
|
||||||
struct tree_entry *prev; /* Previous item in the list */
|
struct tree_entry *prev; /* Previous item in the list */
|
||||||
} tree_entry;
|
} tree_entry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct tree_entry *base;
|
||||||
|
struct tree_entry *current;
|
||||||
|
int base_dir_len;
|
||||||
|
int sublevel;
|
||||||
|
} tree_scan;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int refcount;
|
int refcount;
|
||||||
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 [MC_MAXPATHLEN];/* Directory which is been checked */
|
char *check_name; /* Directory which is been checked */
|
||||||
int loaded;
|
unsigned int loaded : 1;
|
||||||
|
unsigned int dirty : 1;
|
||||||
} TreeStore;
|
} TreeStore;
|
||||||
|
|
||||||
TreeStore *tree_store_init (void);
|
extern void (*tree_store_dirty_notify)(int state);
|
||||||
int tree_store_load (char *name);
|
|
||||||
int tree_store_save (char *name);
|
TreeStore *tree_store_init (void);
|
||||||
tree_entry *tree_store_add_entry (char *name);
|
int tree_store_load (char *name);
|
||||||
void tree_store_remove_entry (char *name);
|
int tree_store_save (char *name);
|
||||||
void tree_store_destroy (void);
|
tree_entry *tree_store_add_entry (char *name);
|
||||||
void tree_store_start_check (void);
|
void tree_store_remove_entry (char *name);
|
||||||
void tree_store_mark_checked (const char *subname);
|
void tree_store_destroy (void);
|
||||||
void tree_store_end_check (void);
|
tree_entry *tree_store_start_check (char *path);
|
||||||
tree_entry *tree_store_whereis (char *name);
|
void tree_store_mark_checked (const char *subname);
|
||||||
void tree_store_rescan (char *dir);
|
void tree_store_end_check (void);
|
||||||
|
tree_entry *tree_store_whereis (char *name);
|
||||||
|
tree_entry *tree_store_rescan (char *dir);
|
||||||
|
|
||||||
typedef void (*tree_store_remove_fn)(tree_entry *tree, void *data);
|
typedef void (*tree_store_remove_fn)(tree_entry *tree, void *data);
|
||||||
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);
|
||||||
|
|
||||||
|
void tree_store_notify_remove (tree_entry *entry);
|
||||||
|
|
||||||
|
tree_scan *tree_store_opendir (char *path);
|
||||||
|
tree_entry *tree_store_readdir (tree_scan *scanner);
|
||||||
|
void tree_store_closedir (tree_scan *scanner);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user