📄 dirlist.c
字号:
/*
* Put a '\' in front of the current directory.
*/
prefix[0] = '\\';
prefix[1] = '\0';
assert( strlen( prefix ) + strlen( dbuff ) < MAX_COLS );
strcpy( cwd, prefix );
strcat( cwd, dbuff );
}
}
while (stop == FALSE) {
/*
* If we had enough memory, find all matching file names. Append
* '\\' at the end of subdirectory names so user will know if
* name is a directory. Might as well find everything, because
* i also forget subdirectory names, too.
*
* when we get here, we have already done: 1) my_findfirst and
* my_findnext, 2) counted the number of matching files, and
* 3) allocated space.
*/
p = flist;
cnt = 0;
rc = my_findfirst( &dta, dname, NORMAL | READ_ONLY | HIDDEN | SYSTEM |
SUBDIRECTORY | ARCHIVE );
if (rc != ERROR) {
/*
* p is pointer that walks down the file info structure.
* save the file name, file size, and directory character,
* if needed, for each matching file we find.
*/
assert( strlen( dta.name ) < 14 );
strcpy( p->fname, dta.name );
p->fsize = dta.size;
if (dta.attrib & SUBDIRECTORY)
strcat( p->fname, "\\" );
for (cnt=1; (rc = my_findnext( &dta )) == OK; ) {
++p;
assert( strlen( dta.name ) < 14 );
strcpy( p->fname, dta.name );
p->fsize = dta.size;
if (dta.attrib & SUBDIRECTORY)
strcat( p->fname, "\\" );
cnt++;
}
}
if (rc != ERROR) {
shell_sort( flist, cnt );
/*
* figure out number of rows, cols, etc... then display dir list
*/
setup_directory_window( &dir, cnt );
write_directory_list( flist, dir );
/*
* Let user select file name or another search directory.
* Save the choice in dbuff. rc == OK if user selected file or dir.
*/
rc = select_file( flist, stem, &dir );
assert( strlen( flist[dir.select].fname ) < MAX_COLS );
strcpy( dbuff, flist[dir.select].fname );
}
/*
* give memory back.
*/
free( flist );
if (rc == ERROR)
stop = TRUE;
else {
len = strlen( dbuff );
/*
* If the last character in a file name is '\' then let's
* do a dir on selected directory. See the matching
* else when the user selects a file.
*/
if (dbuff[len-1] == '\\') {
/*
* Stem has subdirectory path. dbuff has selected path.
* Create a new dname with stem and dbuff.
*/
assert( strlen( stem ) + strlen( dbuff ) < MAX_COLS );
strcpy( dname, stem );
strcat( dname, dbuff );
len = strlen( dname );
strcpy( dbuff, dname );
/*
* The last character in dbuff is '\', because we append the
* '\' to every directory entry in the file list. Replace
* it with a NULL char then we will have a valid path name.
*/
dbuff[len-1] = '\0';
/*
* now let's change to the selected subdirectory.
*/
rc = set_current_directory( dbuff );
if (rc == OK) {
/*
* Every time we change directories, we need to get the
* current directory so we will be sure to have the
* correct path.
*/
rc = get_current_directory( dbuff, drive );
if (rc == OK) {
assert( strlen( prefix ) + strlen( dbuff ) < MAX_COLS );
strcpy( dname, prefix );
strcat( dname, dbuff );
change_directory = TRUE;
}
}
/*
* Validate the new path and allocate memory for the
* matching files.
*/
if (rc == OK)
rc = validate_path( dname, stem );
if (rc == OK) {
rc = my_findfirst( &dta, dname, NORMAL | READ_ONLY | HIDDEN |
SYSTEM | SUBDIRECTORY | ARCHIVE );
if (rc != ERROR) {
for (cnt=1; (rc = my_findnext( &dta )) == OK;)
++cnt;
flist = (FTYPE *)calloc( cnt, sizeof(FTYPE) );
}
}
if (flist == NULL || rc == ERROR) {
stop = TRUE;
rc = ERROR;
}
} else {
/*
* user selected a file. store fname in dname and return.
*/
rc = OK;
stop = TRUE;
assert( strlen( stem ) + strlen( dbuff ) < MAX_COLS );
strcpy( dname, stem );
strcat( dname, dbuff );
}
}
}
/*
* Go back to the current directory if needed.
*/
if (change_directory)
set_current_directory( cwd );
if (window != NULL)
redraw_screen( window );
} else {
/*
* out of memory
*/
error( WARNING, window != NULL ? window->bottom_line : g_display.nlines,
dir3 );
rc = ERROR;
}
return( rc );
}
/*
* Name: setup_directory_window
* Purpose: set number of rows and cols in directory window
* Date: February 13, 1992
* Passed: dir: pointer to directory structure
* cnt: number of files
* Notes: set up stuff we need to know about how to display files.
*/
void setup_directory_window( DIRECTORY *dir, int cnt )
{
int i;
int wid;
char temp[MAX_COLS]; /* line to output */
/*
* setup the fixed vars used in dir display.
* dir->col = physical upper left column of dir screen
* dir->row = physical upper left row or line of dir screen
* dir->wid = width of physical screen
* dir->hgt = height of physical screen
* dir->max_cols number of columns of files in dir screen
* dir->max_lines number of lines of files in each column in dir screen
* dir->cnt number of files in list
*/
dir->col = 3;
dir->row = 5;
wid = dir->wid = 72;
dir->hgt = 16;
dir->max_cols = 5;
dir->max_lines = 9;
dir->cnt = cnt;
/*
* 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 maximun 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] + 14;
/*
* Now, draw the borders of the dir screen.
*/
for (i=0; i < dir->hgt; i++) {
if (i == 0 || i == dir->hgt-1) {
memset( temp, '
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -