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

📄 screen.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
    panel->user_format = strdup (DEFAULT_USER_FORMAT);

    for(i = 0; i < LIST_TYPES; i++)
	panel->user_status_format [i] = strdup (DEFAULT_USER_FORMAT);

    panel->search_buffer [0] = 0;
    panel->frame_size = frame_half;
    section = copy_strings ("Temporal:", panel->panel_name, 0);
    if (!profile_has_section (section, profile_name)){
	free (section);
	section = strdup (panel->panel_name);
    }
    panel_load_setup (panel, section);
    free (section);

    /* Load format strings */
    err = set_panel_formats (panel);
    if (err){
	if (err & 0x01){
	    free (panel->user_format);
	    panel->user_format = strdup (DEFAULT_USER_FORMAT);
	}
	if (err & 0x02){
	    free (panel->user_status_format [panel->list_type]);
	    panel->user_status_format [panel->list_type] = strdup (DEFAULT_USER_FORMAT);
	}
	set_panel_formats (panel);
    }

    /* Load the default format */
    panel->count = do_load_dir (&panel->dir, panel->sort_type,
				panel->reverse, panel->case_sensitive, panel->filter);
    return panel;
}

void
panel_reload (WPanel *panel)
{
    int i;
    struct stat current_stat;

    if (fast_reload
	&& !stat (panel->cwd, &current_stat)
	&& current_stat.st_ctime == panel->dir_stat.st_ctime
	&& current_stat.st_mtime == panel->dir_stat.st_mtime)
	return;

    while (mc_chdir (panel->cwd) == -1){
	char *last_slash;

	if (panel->cwd [0] == PATH_SEP && panel->cwd [1] == 0){
	    clean_dir (&panel->dir, panel->count);
	    panel->count = set_zero_dir (&panel->dir);
	    return;
	}
	last_slash = strrchr (panel->cwd, PATH_SEP);
	if (!last_slash || last_slash == panel->cwd)
	    strcpy (panel->cwd, PATH_SEP_STR);
	else
	    *last_slash = 0;
        bzero (&(panel->dir_stat), sizeof (panel->dir_stat));
	show_dir (panel);
    }

    panel->count = do_reload_dir (&panel->dir, panel->sort_type, panel->count,
				  panel->reverse, panel->case_sensitive, panel->filter);
    panel->marked = 0;
    panel->dirs_marked = 0;
    panel->total  = 0;
    panel->has_dir_sizes = 0;

    for (i = 0; i < panel->count; i++)
	if (panel->dir.list [i].f.marked){
	    /* do_file_mark will return immediately if newmark == oldmark.
	       So we have to first unmark it to get panel's summary information
	       updated. (Norbert) */
	    panel->dir.list [i].f.marked = 0;
	    do_file_mark (panel, i, 1);
	}
}

#ifndef PORT_HAS_PAINT_FRAME
void
paint_frame (WPanel *panel)
{
    int  header_len;
    int  spaces, extra;
    int  side, width;

    char *txt, buffer[30]; /*Hope that this is enough ;-) */
    if (!panel->split)
	adjust_top_file (panel);

    widget_erase (&panel->widget);
    show_dir (panel);

    widget_move (&panel->widget, 1, 1);

    for (side = 0; side <= panel->split; side++){
	format_e *format;

	if (side){
	    attrset (NORMAL_COLOR);
	    one_vline ();
	    width = panel->widget.cols - panel->widget.cols/2 - 1;
	} else if (panel->split)
	    width = panel->widget.cols/2 - 3;
	else
	    width = panel->widget.cols - 2;

	for (format = panel->format; format; format = format->next){
            if (format->string_fn){
                txt = format->title;

		header_len = strlen (txt);
		if (header_len > format->field_len){
		    strcpy (buffer, txt);
		    txt = buffer;
		    txt [format->field_len] = 0;
		    header_len = strlen (txt);
		}

                attrset (MARKED_COLOR);
                spaces = (format->field_len - header_len) / 2;
                extra  = (format->field_len - header_len) % 2;
		printw ("%*s%-s%*s", spaces, "",
			 txt, spaces+extra, "");
		width -= 2 * spaces + extra + header_len;
	    } else {
		attrset (NORMAL_COLOR);
		one_vline ();
		width --;
		continue;
	    }
	}

	if (width > 0)
	    printw ("%*s", width, "");
    }
}
#endif

static char *
parse_panel_size (WPanel *panel, char *format, int isstatus)
{
    int frame = frame_half;
    format = skip_separators (format);

    if (!strncmp (format, "full", 4)){
	frame = frame_full;
	format += 4;
    } else if (!strncmp (format, "half", 4)){
	frame = frame_half;
	format += 4;
    }

    if (!isstatus){
        panel->frame_size = frame;
        panel->split = 0;
    }

    /* Now, the optional column specifier */
    format = skip_separators (format);

    if (*format == '1' || *format == '2'){
	if (!isstatus)
	    panel->split = *format == '2';
	format++;
    }

    if (!isstatus)
        panel_update_cols (&(panel->widget), panel->frame_size);

    return skip_separators (format);
}

/* Format is:

   all              := panel_format? format
   panel_format     := [full|half] [1|2]
   format           := one_format_e
                     | format , one_format_e

   one_format_e     := just format.id [opt_size]
   just             := [<|>]
   opt_size         := : size [opt_expand]
   size             := [0-9]+
   opt_expand       := +

*/

format_e *
parse_display_format (WPanel *panel, char *format, char **error, int isstatus, int *res_total_cols)
{
    format_e *darr, *old, *home = 0;   	/* The formats we return */
    int  total_cols = 0;		/* Used columns by the format */
    int  set_justify;                  	/* flag: set justification mode? */
    int  justify = 0;                  	/* Which mode. */
    int  items = 0;			/* Number of items in the format */
    int  i;

    *error = 0;

    /*
     * This makes sure that the panel and mini status full/half mode
     * setting is equal
     */
    format = parse_panel_size (panel, format, isstatus);

    while (*format){       /* format can be an empty string */
	int found = 0;

        darr = xmalloc (sizeof (format_e), "parse_display_format");

        /* I'm so ugly, don't look at me :-) */
        if (!home)
            home = old = darr;

        old->next = darr;
        darr->next = 0;
        old = darr;

	format = skip_separators (format);

	if (*format == '<' || *format == '>'){
	    set_justify = 1;
	    justify = *format == '<' ? J_LEFT : J_RIGHT;
	    format = skip_separators (format+1);
	} else
	    set_justify = 0;

	for (i = 0; i < ELEMENTS(formats); i++){
	    int klen = strlen (formats [i].id);

	    if (strncmp (format, formats [i].id, klen) != 0)
		continue;

	    format += klen;

	    if (formats [i].use_in_gui)
	    	items++;

	    darr->use_in_gui          = formats [i].use_in_gui;
            darr->requested_field_len = formats [i].min_size;
            darr->string_fn           = formats [i].string_fn;
	    if (formats [i].title [0])
		    darr->title = _(formats [i].title);
	    else
		    darr->title = "";
            darr->id                  = formats [i].id;
	    darr->expand              = formats [i].expands;

	    if (set_justify)
		darr->just_mode = justify;
	    else
		darr->just_mode = formats [i].default_just;

	    found = 1;

	    format = skip_separators (format);

	    /* If we have a size specifier */
	    if (*format == ':'){
		int req_length;

		/* If the size was specified, we don't want
		 * auto-expansion by default
		 */
		darr->expand = 0;
		format++;
		req_length = atoi (format);
		darr->requested_field_len = req_length;

		format = skip_numbers (format);

		/* Now, if they insist on expansion */
		if (*format == '+'){
		    darr->expand = 1;
		    format++;
		}

	    }

	    break;
	}
	if (!found){
	    char old_char;

	    int pos = min (8, strlen (format));
	    delete_format (home);
	    old_char = format [pos];
	    format [pos] = 0;
	    *error = copy_strings(_("Unknow tag on display format: "), format, 0);
	    format [pos] = old_char;
	    return 0;
	}
	total_cols += darr->requested_field_len;
    }

    *res_total_cols = total_cols;
    if (home)
       home->items = items;
    return home;
}

format_e *
use_display_format (WPanel *panel, char *format, char **error, int isstatus)
{
#define MAX_EXPAND 4
    int  expand_top = 0;               /* Max used element in expand */
    int  usable_columns;               /* Usable columns in the panel */
    int  total_cols;
    char *expand_list [MAX_EXPAND];    /* Expand at most 4 fields. */
    int  i;
    format_e *darr, *home;

    if (!format)
	format = DEFAULT_USER_FORMAT;

    home = parse_display_format (panel, format, error, isstatus, &total_cols);

    if (*error)
	return 0;

    /* Status needn't to be split */
    usable_columns = ((panel->widget.cols-2)/((isstatus)
					      ? 1
					      : (panel->split+1))) - (!isstatus && panel->split);

    /* Clean expand list */
    for (i = 0; i < MAX_EXPAND; i++)
        expand_list [i] = '\0';


    /* Look for the expandable fields and set field_len based on the requested field len */
    for (darr = home; darr && expand_top < MAX_EXPAND; darr = darr->next){
	darr->field_len = darr->requested_field_len;
	if (darr->expand)
	    expand_list [expand_top++] = darr->id;
    }

    /* If we used more columns than the available columns, adjust that */
    if (total_cols > usable_columns){
	int pdif, dif = total_cols - usable_columns;

        while (dif){
	    pdif = dif;
	    for (darr = home; darr; darr = darr->next){
		if (dif && darr->field_len - 1){
		    darr->field_len--;
		    dif--;
		}
	    }

	    /* avoid endless loop if num fields > 40 */
	    if (pdif == dif)
		break;
	}
	total_cols  = usable_columns; /* give up, the rest should be truncated */
    }

    /* Expand the available space */
    if ((usable_columns > total_cols) && expand_top){
	int spaces = (usable_columns - total_cols) / expand_top;
	int extra  = (usable_columns - total_cols) % expand_top;

	for (i = 0, darr = home; darr && (i < expand_top); darr = darr->next)
		if (darr->expand){
			darr->field_len += (spaces + ((i == 0) ? extra : 0));
			i++;
		}
    }
    return home;
}

/* Switches the panel to the mode specified in the format 	    */
/* Seting up both format and status string. Return: 0 - on success; */
/* 1 - format error; 2 - status error; 3 - errors in both formats.  */
int
set_panel_formats (WPanel *p)
{
    format_e *form;
    char *err;
    int retcode = 0;

    form = use_display_format (p, panel_format (p), &err, 0);

    if (err){
        free (err);
        retcode = 1;
    }
    else {
        if (p->format)
    	    delete_format (p->format);

	p->format = form;
    }

    if (show_mini_info){

	form = use_display_format (p, mini_status_format (p), &err, 1);

	if (err){
	    free (err);
	    retcode += 2;
	}
	else {
	    if (p->status_format)
		delete_format (p->status_format);

	    p->status_format = form;
	}
    }

    panel_format_modified (p);
    panel_update_cols (&(p->widget), p->frame_size);

    return retcode;
}

/* Given the panel->view_type returns the format string to be parsed */
char *
panel_format (WPanel *panel)
{
    switch (panel->list_type){

    case list_long:
	return "full perm,space,nlink,space,owner,space,group,space,size,space,mtime,space,name";

    case list_brief:
	return "half 2,type,name";

    case list_user:
	return panel->user_format;

    default:
    case list_full:
	return "half type,name,|,size,|,mtime";
    }
}

char *
mini_status_format (WPanel *panel)
{
    if (panel->user_mini_status)
       return panel->user_status_format [panel->list_type];

    switch (panel->list_type){

    case list_long:
       return "full perm,space,nlink,space,owner,space,group,space,size,space,mtime,space,name";

    case list_brief:
       return "half type,name,space,bsize,space,perm,space";

    case list_full:
       return "half type,name";

    default:
    case list_user:
       return panel->user_format;
    }
}

/*                          */
/* Panel operation commands */
/*                          */

/* Returns the number of items in the given panel */
int
ITEMS (WPanel *p)
{
#ifdef HAVE_TK
    return p->widget.lines;
#else
    if (p->split)
	return llines (p) * 2;
    else
	return llines (p);
#endif
}

/* This function sets redisplays the selection */
void
select_item (WPanel *panel)
{
    int repaint = 0;
    int items = ITEMS (panel);

    /* Although currently all over the code we set the selection and
       top file to decent values before calling select_item, I could
       forget it someday, so it's better to do the actual fitting here */

#ifdef HAVE_X
    int old_top;
    old_top = panel->top_file;
#endif

    if (panel->top_file < 0){
	repaint = 1;
	panel->top_file = 0;
    }

⌨️ 快捷键说明

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