📄 dirlist.c
字号:
/* * Set the actual width of the column to the largest possible. */ if (dir->max_cols == 5) dir->len = 12; else if (dir->max_cols == 4) dir->len = 16; else if (dir->max_cols == 3) dir->len = 22; else if (dir->max_cols == 2) dir->len = 35; else dir->len = 72;#endif } dir->col = (g_display.ncols - dir->wid) / 2; dir->row = (g_display.mode_line - dir->hgt) / 2; if (dir->col < 0) dir->col = 0; if (dir->row < 0) dir->row = 0; /* * Find out how many lines in each column are needed to display * matching files. */ dir->lines = dir->cnt / dir->max_cols + (dir->cnt % dir->max_cols ? 1 : 0); if (dir->lines > dir->max_lines) dir->lines = dir->max_lines; /* * Find out how many columns of file names we need. */ dir->cols = dir->cnt / dir->lines + (dir->cnt % dir->lines ? 1 : 0); if (dir->cols > dir->max_cols) dir->cols = dir->max_cols; /* * Find the maximum number of file names we can display in help screen. */ dir->avail = dir->lines * dir->cols; /* * Now find the number of file names we do have on the screen. Every * time we slide the "window", we have to calculate a new nfiles. */ dir->nfiles = dir->cnt > dir->avail ? dir->avail : dir->cnt; /* * A lot of times, the number of matching files will not fit evenly * in our help screen. The last column on the right will be partially * filled, hence the variable name prow (partial row). When there are * more file names than can fit on the screen, we have to calculate * prow every time we slide the "window" of files. */ dir->prow = dir->lines - (dir->avail - dir->nfiles); /* * Find out how many "virtual" columns of file names we have. If * all the files can fit in the dir screen, there will be no * virtual columns. */ if (dir->cnt <= dir->avail) dir->vcols = 0; else dir->vcols = (dir->cnt - dir->avail) / dir->max_lines + ((dir->cnt - dir->avail) % dir->max_lines ? 1 : 0); /* * Find the physical display column in dir screen. */ dir->flist_col[0] = dir->col + 2; for (i = 1; i < dir->max_cols; i++) dir->flist_col[i] = dir->flist_col[i-1] + dir->len + 3; if (g_status.command == GotoWindow) { fofs = 0; row_ofs = 0; } else if (g_status.command == SyntaxSelect) { fofs = 0; row_ofs = 4; } else { /* * Find the offset for the first file (ie. skip the directories). * If there are no files, point to the directories. */ for (fofs = 0; fofs < cnt; ++fofs) { if (list[fofs].name[strlen( list[fofs].name ) - 1] != '/') break; } if (fofs == cnt) fofs = 0; row_ofs = 5; } /* * Now, draw the borders of the dir screen. */ wid = dir->wid; if (g_status.command == GotoWindow) { create_frame( wid, dir->hgt, 0, NULL, dir->col, dir->row ); inner[0] = 0; inner[1] = dir->hgt - 1; fc1 = fc2 = (g_display.frame_style == 3) ? graphic_char[4] : graphic_char[g_display.frame_style]; } else if (g_status.command == SyntaxSelect) { inner[0] = DIR12_ROW + 1; inner[1] = dir->hgt - 1; create_frame( wid, dir->hgt, 1, inner, dir->col, dir->row ); if (g_display.frame_style == 3) { fc1 = graphic_char[1]; fc2 = graphic_char[4]; } else fc1 = fc2 = graphic_char[g_display.frame_style]; s_output( dir10, dir->row+DIR10_ROW, dir->col+DIR10_COL, Color(Dialog) ); s_output( dir11, dir->row+DIR11_ROW, dir->col+DIR11_COL, Color(Dialog) ); s_output( dir12, dir->row+DIR12_ROW, dir->col+DIR12_COL, Color(Dialog) ); i = sprintf( temp, "%s%d", dir13, dir->cnt ); s_output( temp, dir->row+DIR13_ROW, dir->col+wid-2-i, Color( Dialog ) ); } else { DIR8_ROW = dir->hgt - 2; inner[0] = DIR6_ROW + 1; inner[1] = DIR8_ROW - 1; create_frame( wid, dir->hgt, 2, inner, dir->col, dir->row ); fc1 = fc2 = (g_display.frame_style == 3) ? graphic_char[1] : graphic_char[g_display.frame_style]; /* * Write headings in help screen. */ s_output( dir3, dir->row+DIR3_ROW, dir->col+DIR3_COL, Color( Dialog ) ); s_output( dir4, dir->row+DIR4_ROW, dir->col+DIR4_COL, Color( Dialog ) ); s_output( dir5, dir->row+DIR5_ROW, dir->col+DIR5_COL, Color( Dialog ) ); s_output( dir6, dir->row+DIR6_ROW, dir->col+DIR6_COL, Color( Dialog ) ); s_output( dir8, dir->row+DIR8_ROW, dir->col+DIR8_COL, Color( Dialog ) ); /* * Display the file count right justified. */ i = sprintf( temp, "%s%d", dir7, dir->cnt ); s_output( temp, dir->row+DIR7_ROW, dir->col+wid-2-i, Color( Dialog ) ); } /* * Display the column separators. */ for (j = dir->len + 3; j < wid - 1; j += dir->len + 3) { c_output( fc1[TOP_T], dir->col+j, dir->row+inner[0], Color(Dialog) ); c_output( fc2[BOTTOM_T], dir->col+j, dir->row+inner[1], Color(Dialog) ); c_repeat( fc1[VERTICAL_LINE], inner[0]+1 - (inner[1]-1) - 1, dir->col+j, dir->row+inner[0]+1, Color( Dialog ) ); }}/* * Name: write_directory_list * Purpose: given directory list, display matching files * Date: February 13, 1992 * Passed: flist: pointer to list * dir: directory display structure * Notes: blank out the previous file name and display the new one. * * jmh 980523: Display the lines for each column, rather than the columns for * each line. This corrects a one-column bug. */void write_directory_list( LIST *flist, DIRECTORY *dir ){int i;int j;int k;int end;int line;int col;char temp[NAME_MAX+2]; end = FALSE; for (k = 1, j = 0; j < dir->cols; ++j) { col = dir->flist_col[j]; line = dir->row + row_ofs + 1; for (i = 0; i < dir->lines; ++k, ++flist, ++line, ++i) { /* * We need to blank out all lines and columns used to display * files, because there may be some residue from a previous dir */ c_repeat( ' ', dir->len, col, line, Color( Dialog ) ); if (!end) { s_output( reduce_string( temp, flist->name, dir->len, END ), line, col, flist->color ); if (k >= dir->nfiles) end = TRUE; } } }}/* * Name: select_file * Purpose: To let user select a file from dir list * Date: February 13, 1992 * Passed: flist: pointer to list of files * stem: base directory and wildcard pattern * dir: directory display stuff * Notes: let user move thru the file names with the cursor keys * * jmh 980527: display attribute as well, restructured. * jmh 980805: use SortBoxBlock to toggle between name and extension sorting. * jmh 021019: allow ":<letter>" or "<letter>:" to select a drive, returning * the (lowercase) letter (not in UNIX). * jmh 031202: display file date & time. * jmh 031203: press Tab to select a new directory (return TRUE). */int select_file( LIST *flist, char *stem, DIRECTORY *dir ){long ch; /* input character from user */int func; /* function of character input by user */int fno; /* index into flist of the file under cursor */int r; /* current row of cursor */int c; /* current column of cursor */int offset; /* offset into file list */int lastoffset; /* largest possible offset */int stop; /* stop indicator */int max_len; /* maximum allowed length of name */int color; /* color of help screen */int file_color; /* color of current file */int change; /* boolean, hilite another file? */int oldr; /* old row */int oldc; /* old column */int col; /* column to display directory, selected file, size */int len; /* length of file name to display */char temp[PATH_MAX];text_t prefix[PATH_MAX];/* consecutively typed letters */int prelen; /* length of above */clock_t ticks; /* time between letters */int name_row;/* * Convert the file list column and row into a screen column and row. */#define colrow(c, r) (c-1)*(dir->len+3)+dir->col+2, r+dir->row+row_ofs /* * initialise everything. */ color = Color( Dialog ); file_color = Color( Hilited_file ); fno = func = offset = 0; lastoffset = dir->vcols * dir->lines; c = r = oldc = oldr = 1; stop = FALSE; change = TRUE; prelen = 0; prefix[0] = '\0'; ticks = 0; /* * Some names could be quite long - let's truncate the ones that don't fit. * Assume the directory, selected file and file size messages (dir3 to 6) * are all equal length and in the same column. */ if (g_status.command == SyntaxSelect) { col = DIR10_COL + strlen( dir10 ); name_row = DIR10_ROW; } else { col = DIR3_COL + strlen( dir3 ); name_row = DIR4_ROW; } max_len = dir->wid - col - 2; col += dir->col; if (g_status.command != GotoWindow && g_status.command != SyntaxSelect) s_output( reduce_string( temp, stem, max_len, MIDDLE ), dir->row+DIR3_ROW, col, color ); while (stop == FALSE) { if (change) { hlight_line( colrow(oldc, oldr), dir->len, flist[fno].color ); hlight_line( colrow(c, r), dir->len, file_color ); fno = offset + (c-1)*dir->lines + (r-1); if (g_status.command != GotoWindow) { len = strlen( flist[fno].name ); if (len <= max_len) { s_output( flist[fno].name, dir->row+name_row, col, color); c_repeat( ' ', max_len-len, col+len, dir->row+name_row, color ); } else { int chop; if (len <= dir->len) /* * It was fully displayed in the list * so just truncate in the selected. */ chop = END; else if (len <= dir->len + max_len - 3) /* * The beginning of the name is in the list, the end of it * (and perhaps the end of the beginning) is in the selected. */ chop = BEGIN; else /* * list+selected is still not all the name. */ chop = MIDDLE; s_output( reduce_string( temp, flist[fno].name, max_len, chop ), dir->row+name_row, col, color ); } if (g_status.command == SyntaxSelect) { LTYPE *p = flist[fno].data; int plen = strlen( p->parent ); if (plen && len + 1 + 2 + plen <= max_len) { c_output( '(', col+len+1, dir->row+DIR10_ROW, color ); s_output( p->parent, dir->row+DIR10_ROW, col+len+2, color ); c_output( ')', col+len+2+plen, dir->row+DIR10_ROW, color ); } len = strlen( reduce_string( temp, p->pattern, max_len, END ) ); s_output( temp, dir->row+DIR11_ROW, col, color ); c_repeat( ' ', max_len-len, col+len, dir->row+DIR11_ROW, color); assert( (unsigned)p->icase < 3 ); s_output( dir14[p->icase], dir->row+DIR12_ROW, col, color ); } else { FTYPE *p = flist[fno].data; format_time( dir5a, temp, ftime_to_tm( &p->ftime ) ); s_output( temp, dir->row+DIR5_ROW, col, color ); n_output( p->fsize, 10, col, dir->row+DIR6_ROW, color ); s_output( str_fattr( temp, p->fattr ), dir->row+DIRA_ROW, dir->col+DIRA_COL, color ); } } change = FALSE; } oldr = r; oldc = c; ch = getkey( ); /* * User may have redefined the Enter and ESC keys. Make the Enter key * perform a Rturn in this function. Make the ESC key do an AbortCommand. */ func = (ch == RTURN) ? Rturn : (ch == ESC) ? AbortCommand : getfunc( ch ); /* * jmh 980523: if a normal character has been entered, search the file * list for a name starting with that character. * jmh 980805: made more awkward when sorting by extension, since the * names are no longer in order. * jmh 020630: allow more than one character (within half-a-second). */#if !defined( __UNIX__ ) if (g_status.command != GotoWindow && g_status.command != SyntaxSelect && ch == ':' && prelen <= 1) { long rc; if (prelen == 1) rc = bj_tolower( prefix[0] ); else rc = getkey( ); if (rc >= 'a' && rc <= 'z') return( (int)rc ); }#endif if (ch < 256) { text_ptr fn; int i = fno; int rc; /* * Borland defines CLOCKS_PER_SEC as 18.2; let's avoid floating point. */ if (clock() - ticks > (int)CLOCKS_PER_SEC / 2) { prefix[0] = (text_t)ch; prelen = 1; } else if ((text_t)ch != prefix[0] || (g_status.command == GotoWindow && bj_isdigit( *prefix ))) prefix[prelen++] = (text_t)ch; ticks = clock(); fn = (text_ptr)flist[i].name; if (g_status.command == GotoWindow) { if (bj_isdigit( *prefix )) { fn += 2; while (*fn == ' ') ++fn; } else fn += name_ofs; } /* * multiple instances of the first letter * cycle through that letter */ if ((rc = my_memcmp( fn, prefix, prelen )) == 0 && i >= fofs) { if (prelen == 1) { text_t let = sort.order_array[(int)ch]; if (mode.dir_sort == SORT_NAME && g_status.command != GotoWindow) { if (++i == dir->cnt || sort.order_array[(text_t)flist[i].name[0]] != let) i = dir->cnt; } else { while (++i < dir->cnt) { fn = (text_ptr)flist[i].name; if (g_status.command == GotoWindow) { if (bj_isdigit( *prefix )) { fn += 2; while (*fn == ' ') ++fn; } else fn += name_ofs; } if (sort.order_array[*fn] == let) break; } } if (i == dir->cnt) { for (i = fofs; ; ++i) { fn = (text_ptr)flist[i].name; if (g_status.command == GotoWindow) { if (bj_isdigit( *prefix )) { fn += 2; while (*fn == ' ') ++fn; } else fn += name_ofs; } if (sort.order_array[*fn] == let) break; } } } } else { if (mode.dir_sort == SORT_NAME && g_status.command != GotoWindow) { if (rc < 0) { while (++i < dir->cnt && ((rc = my_memcmp( (text_ptr)flist[i].name, prefix, prelen )) < 0 || (i < fofs && rc > 0))) ; if (i == dir->cnt) func = EndOfFile; } else for (i = fofs; my_memcmp( (text_ptr)flist[i].name, prefix, prelen ) < 0; ++i) ; } else { int start = i; while (++i < dir->cnt) { fn = (text_ptr)flist[i].name; if (g_status.command == GotoWindow) { if (bj_isdigit( *prefix )) { fn += 2; while (*fn == ' ') ++fn; } else fn += name_ofs; } if (my_memcmp( fn, prefix, prelen ) == 0) break; } if (i == dir->cnt) { for (i = fofs; i < start; ++i) { fn = (text_ptr)flist[i].name; if (g_status.command == GotoWindow) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -