Hi, long time ago ... * From: Jindrich Makovicka <makovick kmlinux fjfi cvut cz> * To: mc-devel gnome org * Subject: [patch] interruptible file search & viewer operations * Date: Sun, 04 May 2003 10:38:36 +0200
This is a reincarnation of patches I sent some time ago, but they weren't accepted due to code freeze before 4.6.0. I ported them to the current CVS and still hope you can find them useful. find.diff modifies file search so it handles events during searching the file contents, which results in much greater responsiveness of the interface. view.diff adds event checks to various places where the execution can get stuck - searching and file loading at the beginning and file loading in the growing view. There already were some checks in the search functions, but this patch allows using other keys than Ctrl-C, too (2xESC, Ctrl-G, F10). -- Jindrich Makovicka [END] I tried the find improvement. Responsibility is great (i.e. immediate). E.g. moving through buttons is possible, while searching through a large file. David
diff -X .diffignore -urNp mc/src/ChangeLog mc-find/src/ChangeLog --- mc/src/ChangeLog Tue Jul 1 19:53:15 CEST 2003 +++ mc-find/src/ChangeLog Tue Jul 1 19:53:15 CEST 2003 @@ -0,0 +1,7 @@ + + * file.c: New enum for find progress state. Add context vars + for last position. + (check_find_events): New func. + (search_content): Resume operation and return status to the caller. + (run_process): Init. + diff -X .diffignore -urNp mc/src/find.c mc-find/src/find.c --- mc/src/find.c Wed Apr 16 17:26:29 2003 +++ mc-find/src/find.c Tue Jul 1 19:42:37 2003 @@ -43,6 +43,7 @@ #include "wtools.h" #include "cmd.h" /* view_file_at_line */ #include "boxes.h" +#include "key.h" #include "../vfs/vfs.h" /* Size of the find parameters window */ @@ -64,6 +65,12 @@ enum { B_VIEW }; +typedef enum { + FIND_CONT, + FIND_SUSPEND, + FIND_ABORT +} FindProgressStatus; + /* List of directories to be ignored, separated by ':' */ char *find_ignore_dirs = 0; @@ -80,6 +87,11 @@ static int matches; /* Number of matche static int is_start; /* Status of the start/stop toggle button */ static char *old_dir; +/* Where did we stop */ +static int resuming; +static int last_line; +static int last_pos; + static Dlg_head *find_dlg; /* The dialog */ static WButton *stop_button; /* pointer to the stop button */ @@ -437,32 +449,61 @@ get_line_at (int file_fd, char *buf, int return buffer; } -/* +static FindProgressStatus +check_find_events(Dlg_head *h) +{ + Gpm_Event event; + int c; + + c = get_event (&event, h->mouse_status == MOU_REPEAT, 0); + if (c != EV_NONE) { + dlg_process_event (h, c, &event); + if (h->ret_value == B_ENTER + || h->ret_value == B_CANCEL + || h->ret_value == B_AGAIN + || h->ret_value == B_PANELIZE) { + /* dialog terminated */ + return FIND_ABORT; + } + if (!h->send_idle_msg) { + /* searching suspended */ + return FIND_SUSPEND; + } + } + + return FIND_CONT; +} + +/* * search_content: * * Search the global (FIXME) regexp compiled content_pattern string in the * DIRECTORY/FILE. It will add the found entries to the find listbox. + * + * returns 0 if do_search should look for another file + * 1 if do_search should exit and proceed to the event handler */ -static void +static int search_content (Dlg_head *h, char *directory, char *filename) { struct stat s; char buffer [BUF_SMALL]; char *fname; int file_fd; + int ret_val = 0; fname = concat_dir_and_file (directory, filename); if (mc_stat (fname, &s) != 0 || !S_ISREG (s.st_mode)){ g_free (fname); - return; + return 0; } file_fd = mc_open (fname, O_RDONLY); g_free (fname); if (file_fd == -1) - return; + return 0; g_snprintf (buffer, sizeof (buffer), _("Grepping in %s"), name_trunc (filename, FIND2_X_USE)); @@ -480,7 +521,15 @@ search_content (Dlg_head *h, char *direc char *p; int found = 0; - while ((p = get_line_at (file_fd, buffer, &pos, &n_read, sizeof (buffer), &has_newline))){ + if (resuming) { + /* We've been previously suspended, start from the previous positio n */ + resuming = 0; + line = last_line; + pos = last_pos; + } + + while ((p = get_line_at (file_fd, buffer, &pos, &n_read, sizeof (buffer), &has_newline)) + && (ret_val == 0)) { if (found == 0){ /* Search in binary line once */ if (regexec (r, p, 1, 0, 0) == 0){ g_free (p); @@ -494,10 +543,37 @@ search_content (Dlg_head *h, char *direc found = 0; } g_free (p); + + if ((line & 0xff) == 0) { + FindProgressStatus res; + + printf("\n\rLLLLLLLLLLLLLLLLLLLL***********"); + sleep(2); + + res = check_find_events(h); + switch (res) { + case FIND_ABORT: + stop_idle (h); + ret_val = 1; + break; + + case FIND_SUSPEND: + resuming = 1; + last_line = line; + last_pos = pos; + ret_val = 1; + break; + + default: + break; + } + } } } disable_interrupt_key (); mc_close (file_fd); + + return ret_val; } static int @@ -593,9 +669,12 @@ do_search (struct Dlg_head *h) } if (regexp_match (find_pattern, dp->d_name, match_file)){ - if (content_pattern) - search_content (h, directory, dp->d_name); - else + if (content_pattern) { + if (search_content (h, directory, dp->d_name)) { + g_free (tmp_name); + return 1; + } + } else find_add_match (h, directory, dp->d_name); } @@ -849,6 +928,7 @@ setup_gui (void) static int run_process (void) { + resuming = 0; set_idle_proc (find_dlg, 1); run_dlg (find_dlg); return find_dlg->ret_value;