📄 fv.file.c
字号:
/* Remove folders marked for deletion by squeezing array. * Keep track of largest string width. */ ndeleted = 0; Widest_name = Fv_style & FV_DICON ? GLYPH_WIDTH : 0; l_p = Fv_file+Fv_nfiles; f_p = Fv_file; while (f_p < l_p) { if ((*f_p)->mtime == 1) { free((*f_p)->name); (*f_p)->mtime = 0; nf_p = f_p; deleted[ndeleted] = *f_p; ndeleted++; while (nf_p < l_p) *nf_p = *(nf_p+1), nf_p++; } else { if ((*f_p)->width > Widest_name) Widest_name = (*f_p)->width; f_p++; } } /* Put deleted structures at end */ Fv_nfiles -= ndeleted; l_p = Fv_file+Fv_nfiles; while (ndeleted) { ndeleted--; *l_p = deleted[ndeleted]; l_p++; } } display_folder(Fv_foldr.canvas, Fv_foldr.pw, (Rectlist *)0);}staticdisplay_folder(cnvs, pw, area) /* Display files in folder */ Canvas cnvs; /* Canvas handle */ PAINTWIN pw; /* Pixwin/Paint window */ Rectlist *area;{ Rect *r; /* Canvas dimensions */ if (Fv_dont_paint) return; if (area) r = &area->rl_bound; else { /* If null, the area is the entire window */ r = (Rect *)window_get(cnvs, WIN_RECT); r->r_top = GET_SCROLL_VIEW_START; }#ifdef SV1 pw_lock(pw, r);#endif pw_writebackground(pw, r->r_left, r->r_top, r->r_width, r->r_height, PIX_CLR); if (Fv_nfiles) if (!(Fv_style & FV_DICON) && Fv_style) display_list(pw, r); else display_icon(pw, r);#ifdef SV1 pw_unlock(pw);#endif}staticdisplay_list(pw, r) /* List style with at least one List option */ register PAINTWIN pw; /* Paint window */ register Rect *r; /* Repaint area */{ register int i, j; /* Indeces */ register int x, y; /* Coordinates */ register FV_FILE **f_p, **l_p; /* Files array pointers */ char buffer[256]; char *b_p; char *fmtmode(); time_t now, sixmonthsago, onehourfromnow; char *getname(), *getgroup(); i = (Fv_nfiles+1)*LIST_HEIGHT; if (i != Fv_foldr.height) /* New or enlarged folder */#ifdef SV1 set_canvas_height(i, r);#else if (set_canvas_height(i, r)) return;#endif if (Fv_style & FV_DDATE) { /* Allow for formatting the date sensibly... */ now = time((time_t *)0); sixmonthsago = now - SIX_MONTHS_IN_SECS; onehourfromnow = now + HOUR_IN_SECS; } j = r->r_top/LIST_HEIGHT; y = (j+1)*LIST_HEIGHT; f_p = Fv_file+j; j = r->r_height/LIST_HEIGHT; j++; /* One extra */ for (l_p=Fv_file+Fv_nfiles, i=0; f_p < l_p && i<j; f_p++, i++) { x = MARGIN; pw_rop(pw, x, y-15, 16, 16, PIX_SRC | PIX_COLOR((*f_p)->color), Fv_list_icon[(*f_p)->type], 0, 0); x += LIST_HEIGHT; if (Fv_style & FV_DPERMISSIONS) { b_p = buffer; *b_p++ = (*f_p)->type == FV_IFOLDER ? 'd' : '-'; b_p = fmtmode(b_p, (int)(*f_p)->mode); *b_p = NULL; pw_text(pw, x, y, PIX_SRC, Fv_font, buffer); x += Fv_fontsize.x*Permission_width[Fv_fixed]; } if (Fv_style & FV_DLINKS) { (void)sprintf(buffer, "%3d", (*f_p)->nlink); pw_text(pw, x, y, PIX_SRC, Fv_font, buffer); x += Fv_fontsize.x*Link_width[Fv_fixed]; } if (Fv_style & FV_DOWNER) { if ((b_p = getname((*f_p)->uid)) == 0) { (void)sprintf(buffer, "%d", (*f_p)->uid); b_p = buffer; } pw_text(pw, x, y, PIX_SRC, Fv_font, b_p); x += Fv_fontsize.x*Owner_width[Fv_fixed]; } if (Fv_style & FV_DGROUP) { if ((b_p = getgroup((*f_p)->gid)) == 0) { (void)sprintf(buffer, "%d", (*f_p)->gid); b_p = buffer; } pw_text(pw, x, y, PIX_SRC, Fv_font, b_p); x += Fv_fontsize.x*Group_width[Fv_fixed]; } if (Fv_style & FV_DSIZE) { (void)sprintf(buffer, "%-8ld", (*f_p)->size); pw_text(pw, x, y, PIX_SRC, Fv_font, buffer); x += Fv_fontsize.x*Size_width[Fv_fixed]; } if (Fv_style & FV_DDATE) { b_p = ctime(&((*f_p)->mtime)); if ( (*f_p)->mtime < sixmonthsago || (*f_p)->mtime > onehourfromnow ) (void)sprintf(buffer,"%-7.7s%-4.4s", b_p+4, b_p+20); else (void)sprintf(buffer,"%-12.12s", b_p+4); pw_text(pw, x, y, PIX_SRC, Fv_font, buffer); x += Fv_fontsize.x*Date_width[Fv_fixed]; } (*f_p)->x = x; pw_text(pw, x, y, PIX_SRC, Fv_font, (*f_p)->name); if ((*f_p)->selected) pw_rop(Fv_foldr.pw, MARGIN-1, y-16, 18, 18, (PIX_SRC^PIX_DST) | PIX_COLOR((*f_p)->color), (Pixrect *)0, 0, 0); y += LIST_HEIGHT; }}staticdisplay_icon(pw, r) register PAINTWIN pw; register Rect *r;{ register int i, j; /* Indeces */ register int x, y; /* Coordinates */ register int h; /* Height of icon */ int w; /* Name width */ register char c, c1; register char *p; int widest; /* For names widest than window */ int startx; /* Where to start display */ int incx; /* Increment, max x coord */ register FV_FILE **f_p, **l_p; /* Files array pointers */ /* Collect increments, starting positions, etc... */ /* Can't be wider than screen width */ widest = Widest_name; if (widest > Fv_maxwidth) widest = Fv_maxwidth; if (Fv_style==0) widest += LIST_HEIGHT; if (widest > Fv_tree.r.r_width) widest = Fv_tree.r.r_width-(GLYPH_WIDTH>>3); Incx = incx = widest + (GLYPH_WIDTH>>3); /* Must be at least one file per line */ if ((Maxfilesperline = Fv_tree.r.r_width/incx) == 0) Maxfilesperline = 1; /* Make left and right margins the same */ startx = Fv_tree.r.r_width%incx/2; if (Fv_style & FV_DICON) { /* Icons should be centered over text... */ if (GLYPH_WIDTH < widest) startx += (widest>>1)-(GLYPH_WIDTH>>1); /* Canvas height */ h = ICON_AREA_HEIGHT; i = h*((Fv_nfiles/Maxfilesperline)+1)+TOP_MARGIN; /* Starting positions */ j = (r->r_top-TOP_MARGIN)/h; if (j<0) j = 0; y = j*h+TOP_MARGIN; j *= Maxfilesperline; } else { h = LIST_HEIGHT; /* Mini-icon height */ i = h*((Fv_nfiles/Maxfilesperline)+1); /* Starting positions */ j = r->r_top/h; /* Portion of previous line may only be visible; repaint */ if (j) j--; y = (j+1)*h; j *= Maxfilesperline; } if (i != Fv_foldr.height) {#ifdef SV1 set_canvas_height(i, r);#else if (set_canvas_height(i, r)) return;#endif r->r_top = 0; j = 0; y = Fv_style ? TOP_MARGIN : LIST_HEIGHT; } Startx = x = startx; for (f_p=Fv_file+j, l_p=Fv_file+Fv_nfiles, i=0; f_p < l_p; f_p++) { if (Fv_style & FV_DICON) { pw_rop(pw, x, y, GLYPH_WIDTH, GLYPH_HEIGHT, PIX_SRC | PIX_COLOR((*f_p)->color), (*f_p)->icon>EMPTY && Fv_bind[(*f_p)->icon].icon ? Fv_bind[(*f_p)->icon].icon : Fv_icon[(*f_p)->type], 0, 0); if ((*f_p)->width > widest) { /* Name is too long; truncate it to max width * This is calculated in pixels for variable * width fonts. Indicate truncation with * arrow. */ if (Fv_fixed) { p = ((*f_p)->name+(widest/Fv_fontsize.x)); w = widest; } else { p = (*f_p)->name; w = Fv_fontwidth['>'-' ']; while (*p && w < widest) w += Fv_fontwidth[*p-' '], p++; } c = *p; c1 = *(p+1); *p = '>'; *(p+1) = 0; pw_text(pw, (x+(GLYPH_WIDTH>>1))-(w/2), y+Fv_fontsize.y+GLYPH_HEIGHT, PIX_SRC, Fv_font, (*f_p)->name); *p = c; *(p+1) = c1; } else pw_text(pw, (x+(GLYPH_WIDTH>>1))-((*f_p)->width/2), y+Fv_fontsize.y+GLYPH_HEIGHT, PIX_SRC, Fv_font, (*f_p)->name); } else { pw_rop(pw, x, y-15, 16, 16, PIX_SRC | PIX_COLOR((*f_p)->color), Fv_list_icon[(*f_p)->type], 0, 0); pw_text(pw, x+LIST_HEIGHT, y, PIX_SRC, Fv_font, (*f_p)->name); } (*f_p)->x = x; if ((*f_p)->selected) fv_reverse(i+j); x += incx; i++; if ((i % Maxfilesperline) == 0) { x = startx; y += h; if (y > r->r_top+r->r_height+LIST_HEIGHT) break; } }}staticset_canvas_height(i, r) int i; Rect *r;{#ifdef SV1 Fv_dont_paint = TRUE; if (i < (int)window_get(Fv_foldr.canvas, WIN_HEIGHT)) { if (window_get(Fv_foldr.canvas, WIN_VERTICAL_SCROLLBAR)) { /* Remove the scrollbar; no events */ scrollbar_scroll_to(Fv_foldr.vsbar, 0); /* Ensure we start at the top */ window_set(Fv_foldr.canvas, WIN_VERTICAL_SCROLLBAR, NULL, 0); /* Removing the scrollbar doesn't send a repaint event */ r->r_top = 0; pw_writebackground(Fv_foldr.pw, r->r_left, r->r_top, r->r_width+20, r->r_height, PIX_CLR); } } else { window_set(Fv_foldr.canvas, CANVAS_HEIGHT, i, 0); /* Apply scrollbar to canvas if not present already */ if (window_get(Fv_foldr.canvas, WIN_VERTICAL_SCROLLBAR)==0) window_set(Fv_foldr.canvas, WIN_VERTICAL_SCROLLBAR, Fv_foldr.vsbar, 0); } Fv_dont_paint = FALSE; Fv_foldr.height = i;#else if ((int)scrollbar_get(Fv_foldr.vsbar, SCROLL_VIEW_START)) scrollbar_scroll_to(Fv_foldr.vsbar, 0); window_set(Fv_foldr.canvas, CANVAS_HEIGHT, i, 0); Fv_foldr.height = i; return(i > window_get(Fv_foldr.canvas, WIN_HEIGHT));#endif}staticbuild_folder(mtime) time_t *mtime; /* Change date on folder */{ register FV_FILE **f_p, **l_p; /* File array pointers */ register int i, j; /* Indeces */ register struct dirent *dp; /* Directory content */ register DIR *dirp; /* Directory file pointer */ struct stat fstatus; /* File status */ register FILE *fp; /* Host's file pointer */ char buf[255]; /* Host folder buffer */ extern char Fv_hosts[]; /* Hosts file, display in /net */ /* Ensure that we're still in this folder, (we could * have changed to another by merely selecting a folder * in the tree...) */ if (Fv_treeview && Fv_tselected != Fv_current) { if (chdir(Fv_openfolder_path)==-1) return; (void)strcpy(Fv_path, Fv_openfolder_path); } /* Remember folder history */ if (Fv_nhistory < 2 || strcmp(Fv_openfolder_path, Fv_history[1])) { if (Fv_history[0] == NULL) { /* First slot in history array always contains * the home folder. (So the default selection * off the HOME menu works correctly.) */ Fv_history[0] = malloc((unsigned)strlen(Fv_home)+1); (void)strcpy(Fv_history[0], Fv_home); Fv_nhistory++; } /* Is this folder different than previous folders? */ for (i=0; i<Fv_nhistory; i++) if (strcmp(Fv_history[i], Fv_openfolder_path)==0) break; if (i==Fv_nhistory) { /* It's different; add it to our collection */ if (Fv_nhistory==FV_MAXHISTORY) free(Fv_history[Fv_nhistory-1]); else Fv_nhistory++; for (i=Fv_nhistory-1; i>=1; i--) Fv_history[i] = Fv_history[i-1]; Fv_history[1] = malloc((unsigned)strlen(Fv_openfolder_path)+1); if (Fv_history[1]) (void)strcpy(Fv_history[1], Fv_openfolder_path); } /* Update the namestripe */ if (Fv_treeview) fv_namestripe(); } /* Read directory */ if ( ((dirp=opendir(".")) == NULL) || fstat(dirp->dd_fd, &fstatus) ) { if (dirp) (void)closedir(dirp); fv_putmsg(TRUE, "Can't open current folder: %s", (int)sys_errlist[errno], 0); return; } *mtime = fstatus.st_mtime; /* To test against current node */ Fv_write_access = access(".", W_OK) == 0; /* Free old names */ for (f_p=Fv_file, l_p=Fv_file+Fv_nfiles; f_p != l_p; f_p++) free((*f_p)->name); Widest_name = Fv_style & FV_DICON ? GLYPH_WIDTH : 0; i = 0; f_p = Fv_file; Ncolors = 0; /* Read hosts file if we've changed to the automounter's folder */ if (Fv_automount && (strcmp(Fv_openfolder_path, "/net") == 0) && (fp = fopen(Fv_hosts, "r"))) { while (fgets(buf, sizeof(buf), fp)) { (*f_p)->type = FV_IFOLDER; j = strlen(buf); buf[--j] = NULL; /* Get rid of newline */ if (((*f_p)->name = fv_malloc((unsigned)j+1)) == NULL) return; (void)strcpy((*f_p)->name, buf); /* Get name length */ (*f_p)->width = (short)fv_strlen(buf); if ((*f_p)->width > Widest_name) Widest_name = (short)(*f_p)->width; (*f_p)->color = BLACK; (*f_p)->mode = S_IFDIR; (*f_p)->nlink = 0; (*f_p)->uid = 0; (*f_p)->gid = 0; (*f_p)->mtime = time((time_t *)0); (*f_p)->size = 0; f_p++; i++; } (void)fclose(fp); } else while (dp=readdir(dirp)) { if (Fv_color && strcmp(dp->d_name, COLOR_FILE) == 0) store_colors(); /* Always ignore dot and parent */ if (Fv_see_dot) { /* Always ignore ..* files */ if (dp->d_name[0] == '.' && (dp->d_name[1] == '.' || dp->d_name[1] == NULL)) continue; } else if (dp->d_name[0] == '.') continue; /* What type is it? */ /* XXX The permissions may change without our knowing! */ if (stat(dp->d_name, &fstatus) == 0) { if ((fstatus.st_mode & S_IFMT) == S_IFDIR) (*f_p)->type = FV_IFOLDER; else if ((fstatus.st_mode & S_IFMT) == S_IFREG) { if (fstatus.st_mode & S_IEXEC) (*f_p)->type = FV_IAPPLICATION; else if (fstatus.st_mode & S_IFREG) (*f_p)->type = FV_IDOCUMENT; } else (*f_p)->type = FV_ISYSTEM; } else (*f_p)->type = FV_IBROKENLINK; /* Apply filter...but we want to keep folders */ if (Fv_filter[0] && (*f_p)->type!=FV_IFOLDER) { j = fv_match(dp->d_name, Fv_filter); if (j==0) continue; else if (j==-1) /* Pattern in error, null it. */ Fv_filter[0] = NULL; } j = strlen(dp->d_name); if (((*f_p)->name = fv_malloc((unsigned)j+1)) == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -