[patch] more sesponsive file search dialog



Hello,

Currently, during the file content search, no events are checked, which is very annoying when mc hits a big file and the UI freezes. This patch adds event checks to the code for searching the file contents. After applying, the Find File dialog works all the time during the search, so the searching can be stopped or suspended&resumed even in the middle of a file. For suspend&resume, the code is modified to make sure the search will continue where it previously ended.

This is about third time I try to submit this patch and hope it could be finally included in some form.

Regards,
--
Jindrich Makovicka
diff --exclude-from dontdiff -urN vanilla/mc/src/find.c mc/src/find.c
--- vanilla/mc/src/find.c	2004-08-17 17:51:29.000000000 +0200
+++ mc/src/find.c	2004-08-17 17:53:00.000000000 +0200
@@ -41,6 +41,7 @@
 #include "wtools.h"
 #include "cmd.h"		/* view_file_at_line */
 #include "boxes.h"
+#include "key.h"
 
 /* Size of the find parameters window */
 #define FIND_Y 14
@@ -61,6 +62,12 @@
     B_VIEW
 };
 
+typedef enum {
+    FIND_CONT,
+    FIND_SUSPEND,
+    FIND_ABORT
+} FindProgressStatus;
+
 /* List of directories to be ignored, separated by ':' */
 char *find_ignore_dirs = 0;
 
@@ -77,6 +84,11 @@
 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 */
@@ -434,32 +446,61 @@
     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->flags & DLG_WANT_IDLE)) {
+ 	    /* 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, const char *directory, const 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));
 
@@ -477,7 +518,14 @@
 	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 position */
+	    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);
@@ -491,10 +539,31 @@
 		found = 0;
 	    }
 	    g_free (p);
+ 
+ 	    if ((line & 0xff) == 0) {
+		FindProgressStatus res;
+		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
@@ -599,9 +668,11 @@
     }
 
     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)) {
+		return 1;
+	    }
+	} else 
 	    find_add_match (h, directory, dp->d_name);
     }
     
@@ -826,6 +897,7 @@
 static int
 run_process (void)
 {
+    resuming = 0;
     set_idle_proc (find_dlg, 1);
     run_dlg (find_dlg);
     return find_dlg->ret_value;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]