browse.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 833 行 · 第 1/2 页
C
833 行
#ifdef __QNX__
/* scan for next directory matching mask */
do {
direntp = my_readdir( dirptr, dptr );
} while( direntp != NULL && !IS_DIR( direntp )
&& !checkMask( direntp->d_name, mask ) );
#else
direntp = my_readdir( dirptr, dptr );
#endif
if( direntp == NULL ) break;
if( IS_DIR( direntp ) == flag ) ++count;
}
closedir( dptr );
}
if( add_mask ) {
strip( dirptr, NULL );
}
return( count );
}
static void InvalidDir( DIRECTORY *dirptr, VSCREEN *wptr )
/**********************************************************/
{
unsigned i;
int row;
DirEdit.scroll = 0;
uivtextput( wptr, 1, 0, UIData->attrs[ ATTR_NORMAL ],
"Invalid directory", wptr->area.width );
for( i = 1; i <= wptr->area.height-1; i ++ ) {
row = i - dirptr->index + dirptr->currrow;
if( ( row > 0 ) && ( row < wptr->area.height ) ) {
uivtextput( wptr, row, 0, UIData->attrs[ ATTR_NORMAL ], "",
wptr->area.width );
}
}
}
static int displaydir( wptr, dirptr )
/*************************************/
register VSCREEN *wptr;
register DIRECTORY *dirptr;
{
register int index;
register char *mask;
auto char buff[ DIR_MAX + 1 ];
void *tmp;
int ret;
struct stat blk;
Names = NULL;
index = 0;
mask = dirptr->mask;
ret = stat( dirptr->pathbuff, &blk );
if( ( ret == 0 ) && ( S_ISDIR( blk.st_mode ) ) ){
makedir( dirptr->pathbuff );
}
if( concat( dirptr, FullMask ) == FALSE ) {
index = dircount( dirptr, NULL, TRUE );
if( index != INVALID_DIR ) {
strip( dirptr, buff );
mask = buff;
} else {
strip( dirptr, buff );
mask = buff;
}
} else {
strip( dirptr, NULL );
}
index = dircount( dirptr, FullMask, TRUE );
if( index == INVALID_DIR ) {
InvalidDir( dirptr, wptr );
return( INVALID_DIR );
}
ret = dircount( dirptr, mask, 0 );
if( ret != INVALID_DIR ) {
index += ret;
}
dirptr->index = 0;
dirptr->currrow = 1;
if( index == 0 ) {
dirptr->dirsize = 1;
} else {
dirptr->dirsize = index;
}
tmp = (void *)malloc( dirptr->dirsize * sizeof( struct name ) );
if( tmp != NULL ) {
Names = tmp;
if( index == 0 ) {
strcpy( Names[ index ].str, "." );
} else {
index = addnames( dirptr, FullMask, TRUE, 0 );
addnames( dirptr, mask, 0, index );
}
concat( dirptr, mask );
outnames( wptr, dirptr, 0, wptr->area.height - 1 );
DirEdit.scroll = outdir( wptr, dirptr->pathbuff );
DirEdit.update = TRUE;
DirEdit.index = strlen( dirptr->pathbuff );
return( OK_DIR );
} else {
return( NO_MEM_4_DIR );
}
}
int initdir( wptr, dirptr )
/***************************/
register VSCREEN *wptr;
register DIRECTORY *dirptr;
{
int ret;
makedir( dirptr->pathbuff );
ret = displaydir( wptr, dirptr );
if( ret == NO_MEM_4_DIR ) {
return( FALSE );
} else {
return( TRUE );
}
}
static int getdir( wptr, dirptr, new_dir )
/*********************************/
register VSCREEN *wptr;
register DIRECTORY *dirptr;
bool *new_dir;
{
register char *str;
register int len;
register EVENT ev;
register EVENT new;
register ATTR attr;
auto char olddir[ DIR_MAX + 1 ];
int ret;
strcpy( olddir, dirptr->pathbuff );
DirEdit.attr = UIData->attrs[ ATTR_BRIGHT ];
DirEdit.fldlen = wptr->area.width;
DirEdit.length = dirptr->pathbufflen;
DirEdit.buffer = dirptr->pathbuff;
DirEdit.dirty = TRUE;
uipushlist( GetDirEvents );
dirptr->pathbuff[ DirEdit.length ] = '\0';
attr = UIData->attrs[ ATTR_NORMAL ];
new = EV_NO_EVENT;
DirEdit.update = TRUE;
*new_dir = FALSE;
do {
ev = uiveditline( wptr, &DirEdit );
switch( ev ) {
case EV_ESCAPE:
new = ev;
break;
case EV_RETURN:
finidir( wptr, dirptr );
len = 0;
while( dirptr->pathbuff[ len ] != ' '
&& dirptr->pathbuff[ len ] != '\0' ) {
++len;
}
dirptr->pathbuff[ len ] = '\0';
ret = displaydir( wptr, dirptr );
switch( ret ) {
case NO_MEM_4_DIR:
new = EV_ERROR;
break;
case OK_DIR:
strcpy( olddir, dirptr->pathbuff );
str = Names[ 0 ].str;
uivtextput( wptr, 1, 0, attr, str, wptr->area.width );
*new_dir = TRUE;
break;
case INVALID_DIR:
*new_dir = TRUE;
}
break;
case EV_CURSOR_DOWN:
strcpy( dirptr->pathbuff, olddir );
outdir( wptr, dirptr->pathbuff );
if( *new_dir ){
finidir( wptr, dirptr );
displaydir( wptr, dirptr );
}
new = ev;
break;
}
} while( new == EV_NO_EVENT );
uipoplist();
wptr->cursor = C_OFF;
return( new );
}
#define NO_ROW ((ORD)-1)
EVENT directory( wptr, dirptr )
/*******************************/
register VSCREEN *wptr;
register DIRECTORY *dirptr;
{
register EVENT ev;
register EVENT new;
SAREA area;
register int index;
ORD row, col;
bool got_new_dir;
uipushlist( DirEvents );
ev = uivgetevent( wptr );
uipoplist();
area.row = 0;
area.col = 0;
area.height = 1;
area.width = wptr->area.width;
new = EV_NO_EVENT;
index = dirptr->index;
got_new_dir = FALSE;
switch( ev ) {
case EV_CURSOR_UP :
if( index > 0 ) {
dirptr->index -= 1;
if( dirptr->currrow == 1 ) {
area.row = 1;
}
} else {
/* turn off highlighting while getting new directory */
dirptr->index ++;
dirptr->currrow ++;
outnames( wptr, dirptr, index, index );
dirptr->index --;
dirptr->currrow --;
new = getdir( wptr, dirptr, &got_new_dir );
if( !got_new_dir ) {
outnames( wptr, dirptr, index, index );
}
}
break;
case EV_CURSOR_DOWN :
if( index < dirptr->dirsize - 1 ) {
dirptr->index += 1;
if( dirptr->currrow == wptr->area.height - 1 ) {
area.row = 2;
}
}
break;
case EV_PAGE_UP:
if( index - ( wptr->area.height - 1 ) >= 0 ) {
dirptr->index -= wptr->area.height - 1;
} else {
dirptr->index = 0;
}
dirptr->currrow = 1;
area.row = NO_ROW;
break;
case EV_PAGE_DOWN:
if( index + wptr->area.height - 1 <= dirptr->dirsize - 1 ) {
dirptr->index += wptr->area.height - 1;
} else {
dirptr->index = dirptr->dirsize - 1;
}
dirptr->currrow = wptr->area.height - 1;
if( dirptr->currrow > dirptr->dirsize ) {
dirptr->currrow = dirptr->dirsize;
}
area.row = NO_ROW;
break;
case EV_MOUSE_PRESS:
if( wptr != uivmousepos( wptr, &row, &col ) ) {
new = EV_ESCAPE;
break;
}
case EV_MOUSE_DCLICK:
case EV_MOUSE_DRAG:
if( wptr == uivmousepos( wptr, &row, &col ) ){
dirptr->index += row - dirptr->currrow;
}
if( dirptr->index >= dirptr->dirsize )
dirptr->index = dirptr->dirsize - 1;
else if( dirptr->index < 0 ) {
dirptr->index = 0;
}
break;
case EV_MOUSE_RELEASE:
if( wptr != uivmousepos( wptr, &row, &col ) ){
break;
} else if( row == 0 ) {
/* turn off highlighting while getting new directory */
dirptr->index ++;
dirptr->currrow ++;
outnames( wptr, dirptr, index, index );
dirptr->index --;
dirptr->currrow --;
new = getdir( wptr, dirptr, &got_new_dir );
if( ! got_new_dir ) {
dirptr->currrow = 1;
outnames( wptr, dirptr, index, index );
}
break;
}
/* fall through */
ev = EV_RETURN;
case EV_RETURN :
if( Names[ index ].dir ) {
if( Names[ index ].str[NAME_START] == '.' ) {
if( Names[ index ].str[NAME_START+1] == '.' ) {
#ifdef __QNX__
char *start;
char *end;
char chr;
start = dirptr->pathbuff;
if( start[0] == '/' ) {
++start;
if( start[0] == '/' ) {
++start;
for( ;; ) {
chr = *start;
if( chr == '\0' ) break;
++start;
if( chr == '/' ) break;
}
}
}
end = &start[ strlen( start ) ];
while( end > start && *end != '/' ) --end;
*end = '\0';
finidir( wptr, dirptr );
if( displaydir( wptr, dirptr ) == NO_MEM_4_DIR ) {
return( EV_ERROR );
}
index = dirptr->index;
#else
//NYI: what to do for QNX?
strip( dirptr, NULL );
if( strip( dirptr, NULL ) ) {
finidir( wptr, dirptr ); /* frees up Names */
if( displaydir( wptr, dirptr ) == NO_MEM_4_DIR ) {
return( EV_ERROR );
}
index = dirptr->index;
} else {
new = ev;
}
#endif
}
} else {
#ifdef __QNX__
add_name( dirptr, &Names[ dirptr->index ].str[NAME_START], NULL );
#else
strip( dirptr, NULL );
concat( dirptr, Names[ dirptr->index ].str );
#endif
finidir( wptr, dirptr ); /* frees up Names */
if( initdir( wptr, dirptr ) == FALSE ) {
return( EV_ERROR );
}
index = dirptr->index;
}
} else {
#ifdef __QNX__
add_name( dirptr, &Names[ dirptr->index ].str[NAME_START], NULL );
#else
strip( dirptr, NULL );
concat( dirptr, Names[ dirptr->index ].str );
#endif
finidir( wptr, dirptr );
new = ev;
}
break;
default :
new = ev;
break;
}
if( !got_new_dir ) {
if( index != dirptr->index ) {
if( area.row == NO_ROW ) {
index = dirptr->index - dirptr->currrow;
outnames( wptr, dirptr, index, index + wptr->area.height- 1 );
} else if( area.row > 0 ) {
area.height = wptr->area.height - 2;
uivmoveblock( wptr, area, index - dirptr->index, 0 );
} else {
dirptr->currrow += dirptr->index - index;
}
outnames( wptr, dirptr, index, index );
outnames( wptr, dirptr, dirptr->index, dirptr->index );
}
}
return( new );
}
#pragma off(unreferenced);
void finidir( VSCREEN *wptr, DIRECTORY *dirptr )
/***********************************************/
#pragma on(unreferenced);
{
if( Names != NULL ) {
free( Names );
Names = NULL;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?