⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 find.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    static int subdirs_left = 0;
    char *tmp_name;		/* For bulding file names */

    if (!h) { /* someone forces me to close dirp */
	if (dirp) {
	    mc_closedir (dirp);
	    dirp = 0;
	}
        dp = 0;
	return;
    }

 do_search_begin:
    while (!dp){

	if (dirp){
	    mc_closedir (dirp);
	    dirp = 0;
	}

	while (!dirp){
	    char *tmp;

#ifndef HAVE_X
	    attrset (REVERSE_COLOR);
#endif
	    while (1) {
		tmp = pop_directory ();
		if (!tmp){
		    running = 0;
		    label_set_text (status_label, _("Finished"));
		    set_idle_proc (h, 0);
		    return;
		}
		if (find_ignore_dirs){
		    char *temp_dir = copy_strings (":", tmp, ":", 0);
		    if (strstr (find_ignore_dirs, temp_dir))
			free (tmp);
		    else
			break;
		} else
		    break;
	    }

	    strcpy (directory, tmp);
	    free (tmp);

	    if (verbose){
		    char buffer [50];

		    sprintf (buffer, _("Searching %s"), name_trunc (directory, FIND2_X_USE));
		    label_set_text (status_label, buffer);
	    }
	    dirp = mc_opendir (directory);
	    mc_stat (directory, &tmp_stat);
	    subdirs_left = tmp_stat.st_nlink - 2;
	    /* Commented out as unnecessary
	       if (subdirs_left < 0)
	       subdirs_left = MAXINT;
	    */
	}
	dp = mc_readdir (dirp);
    }

    if (strcmp (dp->d_name, ".") == 0 ||
	strcmp (dp->d_name, "..") == 0){
	dp = mc_readdir (dirp);
#ifdef HAVE_XVIEW
	xv_post_proc (h, (void (*)(void *))do_search, (void *)h);
#endif
	return;
    }

    tmp_name = get_full_name (directory, dp->d_name);

    if (subdirs_left){
	mc_lstat (tmp_name, &tmp_stat);
	if (S_ISDIR (tmp_stat.st_mode)){
	    push_directory (tmp_name);
	    subdirs_left--;
	}
    }

    if (regexp_match (find_pattern, dp->d_name, match_file)){
	if (content_pattern)
	    search_content (h, directory, dp->d_name);
	else
	    find_add_match (h, directory, dp->d_name);
    }

    free (tmp_name);
    dp = mc_readdir (dirp);

    /* Displays the nice dot */
    count++;
    if (!(count & 31)){
	if (verbose){
#ifndef HAVE_X
	    pos = (pos + 1) % 4;
	    attrset (NORMALC);
	    dlg_move (h, FIND2_Y-6, FIND2_X - 4);
	    addch (rotating_dash [pos]);
	    mc_refresh ();
	}
    } else
	goto do_search_begin;
#else
        }
    }
#ifdef HAVE_XVIEW
    xv_post_proc (h, (void (*)(void *))do_search, (void *)h);
#endif
#endif
    x_flush_events ();
}

static int
view_edit_currently_selected_file (int unparsed_view, int edit)
{
    WLEntry *entry = find_list->current;
    char *dir, *fullname, *filename;
    int line;

    if (!entry)
        return MSG_NOT_HANDLED;

    dir = entry->data;

    if (!entry->text || !dir)
	return MSG_NOT_HANDLED;

    if (content_pattern){
	filename = strchr (entry->text + 4, ':') + 1;
	line = atoi (entry->text + 4);
    } else {
	 filename = entry->text + 4;
	 line = 0;
    }
    if (dir [0] == '.' && dir [1] == 0)
	 fullname = strdup (filename);
    else if (dir [0] == '.' && dir [1] == PATH_SEP)
	 fullname = get_full_name (dir+2, filename);
    else
	 fullname = get_full_name (dir, filename);

    if (edit)
	do_edit_at_line (fullname, line);
    else
        view_file_at_line (fullname, unparsed_view, use_internal_view, line);
    free (fullname);
    return MSG_HANDLED;
}

static int
find_callback (struct Dlg_head *h, int id, int Msg)
{
    switch (Msg){
#ifndef HAVE_X
    case DLG_DRAW:
        common_dialog_repaint (h);
	break;
#endif

    case DLG_KEY:
	if (id == KEY_F(3) || id == KEY_F(13)){
	    int unparsed_view = (id == KEY_F(13));
	    return view_edit_currently_selected_file (unparsed_view, 0);
	}
	if (id == KEY_F(4)){
	    return view_edit_currently_selected_file (0, 1);
	 }
	 return MSG_NOT_HANDLED;

     case DLG_IDLE:
	 do_search (h);
	 break;
     }
     return 0;
}

/* Handles the Stop/Start button in the find window */
static int
start_stop (int button, void *extra)
{
    running = is_start;
    set_idle_proc (find_dlg, running);
    is_start = !is_start;

    label_set_text (status_label, is_start ? _("Stopped") : _("Searching"));
    button_set_text (stop_button, fbuts [is_start].text);

    return 0;
}

/* Handle view command, when invoked as a button */
static int
find_do_view_file (int button, void *extra)
{
    view_edit_currently_selected_file (0, 0);
    return 0;
}

/* Handle edit command, when invoked as a button */
static int
find_do_edit_file (int button, void *extra)
{
    view_edit_currently_selected_file (0, 1);
    return 0;
}

static void
init_find_vars (void)
{
    char *dir;

    if (old_dir){
	free (old_dir);
	old_dir = 0;
    }
    count = 0;
    matches = 0;

    /* Remove all the items in the stack */
    while ((dir = pop_directory ()) != NULL)
	free (dir);
}

static int
find_file (char *start_dir, char *pattern, char *content, char **dirname,  char **filename)
{
    int return_value = 0;
    char *dir;
    char *dir_tmp, *file_tmp;

#ifdef ENABLE_NLS
	static int i18n_flag = 0;
	if (!i18n_flag)
	{
		register int i = sizeof (fbuts) / sizeof (fbuts[0]);
		while (i--)
			fbuts [i].len = strlen (fbuts [i].text = _(fbuts [i].text)) + 3;
		fbuts [2].len += 2; /* DEFPUSH_BUTTON */
		i18n_flag = 1;
	}
#endif /* ENABLE_NLS */

	/*
	 * Dynamically place buttons centered within current window size
	 */
	{
		int l0 = max (fbuts[0].len, fbuts[1].len);
		int l1 = fbuts[2].len + fbuts[3].len + l0 + fbuts[4].len;
		int l2 = fbuts[5].len + fbuts[6].len + fbuts[7].len;
		int r1, r2;

		FIND2_X = COLS - 16;

		/* Check, if both button rows fit within FIND2_X */
		if (l1 + 9 > FIND2_X) FIND2_X = l1 + 9;
		if (l2 + 8 > FIND2_X) FIND2_X = l2 + 8;

		/* compute amount of space between buttons for each row */
		r1 = (FIND2_X - 4 - l1) % 5;
		l1 = (FIND2_X - 4 - l1) / 5;
		r2 = (FIND2_X - 4 - l2) % 4;
		l2 = (FIND2_X - 4 - l2) / 4;

		/* ...and finally, place buttons */
		fbuts [2].x = 2 + r1/2 + l1;
		fbuts [3].x = fbuts [2].x + fbuts [2].len + l1;
		fbuts [0].x = fbuts [3].x + fbuts [3].len + l1;
		fbuts [4].x = fbuts [0].x + l0 + l1;
		fbuts [5].x = 2 + r2/2 + l2;
		fbuts [6].x = fbuts [5].x + fbuts [5].len + l2;
		fbuts [7].x = fbuts [6].x + fbuts [6].len + l2;
	}

    find_dlg = create_dlg (0, 0, FIND2_Y, FIND2_X, dialog_colors,
			   find_callback, "[Find File]", "mfind", DLG_CENTER | DLG_GRID);

    x_set_dialog_title (find_dlg, _("Find file"));

	add_widgetl (find_dlg,
		button_new (FIND2_Y-3, fbuts[7].x, B_VIEW, NORMAL_BUTTON,
			fbuts[7].text, find_do_edit_file, find_dlg, "button-edit"), 0);
	add_widgetl (find_dlg,
		button_new (FIND2_Y-3, fbuts[6].x, B_VIEW, NORMAL_BUTTON,
			fbuts[6].text, find_do_view_file, find_dlg, "button-view"), 0);
	add_widgetl (find_dlg,
		button_new (FIND2_Y-3, fbuts[5].x, B_PANELIZE, NORMAL_BUTTON,
			fbuts[5].text, 0, 0, "button-panelize"), XV_WLAY_CENTERROW);

	add_widgetl (find_dlg,
		button_new (FIND2_Y-4, fbuts[4].x, B_CANCEL, NORMAL_BUTTON,
			fbuts[4].text, 0, 0, "button-quit"), XV_WLAY_RIGHTOF);
    stop_button = button_new (FIND2_Y-4, fbuts[0].x, B_STOP, NORMAL_BUTTON,
		fbuts[0].text, start_stop, find_dlg, "start-stop");
	add_widgetl (find_dlg, stop_button, XV_WLAY_RIGHTOF);
	add_widgetl (find_dlg,
		button_new (FIND2_Y-4, fbuts[3].x, B_AGAIN, NORMAL_BUTTON,
			fbuts[3].text, 0, 0, "button-again"), XV_WLAY_RIGHTOF);
	add_widgetl (find_dlg,
		button_new (FIND2_Y-4, fbuts[2].x, B_ENTER, DEFPUSH_BUTTON,
			fbuts[2].text, 0, 0, "button-chdir"), XV_WLAY_CENTERROW);

    status_label = label_new (FIND2_Y-6, 4, _("Searching"), "label-search");
    add_widgetl (find_dlg, status_label, XV_WLAY_BELOWOF);

    find_list = listbox_new (2, 2, FIND2_X-4, FIND2_Y-9, listbox_finish, 0, "listbox");
    add_widgetl (find_dlg, find_list, XV_WLAY_EXTENDWIDTH);

    /* FIXME: Need to cleanup this, this ought to be passed non-globaly */
    find_pattern    = pattern;
    content_pattern = content;

    set_idle_proc (find_dlg, 1);
    init_find_vars ();
    push_directory (start_dir);

#ifdef HAVE_XVIEW
    xv_post_proc (find_dlg, (void (*)(void *))do_search, (void *)find_dlg);
#endif
    run_dlg (find_dlg);

    return_value = find_dlg->ret_value;

    /* Remove all the items in the stack */
    while ((dir = pop_directory ()) != NULL)
	free (dir);

    listbox_get_current (find_list, &file_tmp, &dir_tmp);

    if (dir_tmp)
	*dirname  = strdup (dir_tmp);
    if (file_tmp)
	*filename = strdup (file_tmp);
    if (return_value == B_PANELIZE && *filename){
	int status, link_to_dir, stalled_link;
	int next_free = 0;
	int i;
	struct stat buf;
	WLEntry *entry = find_list->list;
	dir_list *list = &cpanel->dir;
	char *dir, *name;

	for (i = 0; entry && i < find_list->count; entry = entry->next, i++){
	    char *filename;

	    if (content_pattern)
		filename = strchr (entry->text+4, ':')+1;
	    else
		filename = entry->text+4;

	    if (!entry->text || !entry->data)
		continue;
	    dir = entry->data;
	    if (dir [0] == '.' && dir [1] == 0)
		name = strdup (filename);
	    else if (dir [0] == '.' && dir [1] == PATH_SEP)
		name = get_full_name (dir + 2, filename);
	    else
		name = get_full_name (dir, filename);
	    status = handle_path (list, name, &buf, next_free, &link_to_dir,
	        &stalled_link);
	    if (status == 0) {
		free (name);
		continue;
	    }
	    if (status == -1) {
	        free (name);
		break;
	    }

	    /* don't add files more than once to the panel */
	    if (content_pattern && next_free > 0){
		if (strcmp (list->list [next_free-1].fname, name) == 0) {
		    free (name);
		    continue;
		}
	    }

	    if (!next_free) /* first turn i.e clean old list */
    		clean_dir (list, cpanel->count);
	    list->list [next_free].fnamelen = strlen (name);
	    list->list [next_free].fname = name;
	    list->list [next_free].cache = NULL;
	    file_mark (cpanel, next_free, 0);
	    list->list [next_free].f.link_to_dir = link_to_dir;
	    list->list [next_free].f.stalled_link = stalled_link;
	    list->list [next_free].buf = buf;
	    next_free++;
           if (!(next_free & 15))
	       rotate_dash ();
	}
	if (next_free){
	    cpanel->count = next_free;
	    cpanel->is_panelized = 1;
	    cpanel->dirs_marked = 0;
	    cpanel->has_dir_sizes = 0;
	    cpanel->marked = 0;
	    cpanel->total = 0;
	    cpanel->top_file = 0;
	    cpanel->selected = 0;

	    if (start_dir [0] == PATH_SEP){
		strcpy (cpanel->cwd, PATH_SEP_STR);
		chdir (PATH_SEP_STR);
	    }
	}
    }

    set_idle_proc (find_dlg, 0);
    destroy_dlg (find_dlg);
    do_search (0); /* force do_search to release resources */
    if (old_dir){
	free (old_dir);
	old_dir = 0;
    }
    return return_value;
}

void
do_find (void)
{
    char *start_dir, *pattern, *content;
    char *filename, *dirname;
    int  v, dir_and_file_set;
    int done = 0;

    while (!done){
	if (!find_parameters (&start_dir, &pattern, &content))
	    break;

	dirname = filename = NULL;
	is_start = 0;
	v = find_file (start_dir, pattern, content, &dirname, &filename);
	free (start_dir);
	free (pattern);

	if (v == B_ENTER){
	    if (dirname || filename){
		if (dirname){
		    do_cd (dirname, cd_exact);
		    if (filename)
			try_to_select (cpanel, filename + (content ?
			   (strchr (filename + 4, ':') - filename + 1) : 4) );
		} else if (filename)
		    do_cd (filename, cd_exact);
		paint_panel (cpanel);
		select_item (cpanel);
	    }
	    if (dirname)
		free (dirname);
	    if (filename)
		free (filename);
	    break;
	}
	if (content)
	    free (content);
	dir_and_file_set = dirname && filename;
	if (dirname)  free (dirname);
	if (filename) free (filename);
	if (v == B_CANCEL)
	    break;

	if (v == B_PANELIZE){
	    if (dir_and_file_set){
	        try_to_select (cpanel, NULL);
	        paint_panel (cpanel);
	    }
	    break;
	}
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -