/*
* TFileList.cc
*
* Turbo Vision - Version 2.0
*
* Copyright (c) 1994 by Borland International
* All Rights Reserved.
*
* Modified by Sergio Sigala <sergio@sigala.it>
*/
#define Uses_MsgBox
#define Uses_TFileList
#define Uses_TRect
#define Uses_TSearchRec
#define Uses_TEvent
#define Uses_TGroup
#define Uses_TKeys
#include <tvision/tv.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <glob.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
void fexpand( char * );
TFileList::TFileList( const TRect& bounds,
TScrollBar *aScrollBar) :
TSortedListBox( bounds, 2, aScrollBar )
{
}
TFileList::~TFileList()
{
if ( list() )
destroy ( list() );
}
void TFileList::focusItem( short item )
{
TSortedListBox::focusItem( item );
message( owner, evBroadcast, cmFileFocused, list()->at(item) );
}
void TFileList::selectItem( short item )
{
message( owner, evBroadcast, cmFileDoubleClicked, list()->at(item) );
}
void TFileList::getData( void * )
{
}
void TFileList::setData( void * )
{
}
ushort TFileList::dataSize()
{
return 0;
}
void* TFileList::getKey( const char *s )
{
static TSearchRec sR;
if( (shiftState & kbShift) != 0 || *s == '.' )
sR.attr = FA_DIREC;
else
sR.attr = 0;
strcpy( sR.name, s );
/* SS: changed */
for (unsigned char *p = (unsigned char *)sR.name; *p != '\0'; p++) *p = toupper(*p);
return &sR;
}
void TFileList::getText( char *dest, short item, short maxChars )
{
TSearchRec *f = (TSearchRec *)(list()->at(item));
strncpy( dest, f->name, maxChars );
dest[maxChars] = '\0';
if( f->attr & FA_DIREC )
strcat( dest, "/" );
}
void TFileList::readDirectory( const char *dir, const char *wildCard )
{
char path[PATH_MAX];
strcpy( path, dir );
strcat( path, wildCard );
readDirectory( path );
}
struct DirSearchRec : public TSearchRec
{
/* SS: changed */
void readFf_blk(char *filename, struct stat &s)
{
attr = FA_ARCH;
if (S_ISDIR(s.st_mode)) attr |= FA_DIREC;
strcpy(name, filename);
size = s.st_size;
ftime t;
struct tm *broken = localtime(&s.st_mtime);
t.ft_tsec = broken->tm_sec / 2;
t.ft_min = broken->tm_min;
t.ft_hour = broken->tm_hour;
t.ft_day = broken->tm_mday;
/*
* Month value should begin at 1.
* Date: Thu, 23 Jan 1997 11:34:50 +0100 (MET)
*/
t.ft_month = broken->tm_mon + 1;
t.ft_year = broken->tm_year - 80;
time = *(long *) &t;
}
};
void TFileList::readDirectory( const char *aWildCard )
{
/* SS: changed */
DIR *dp;
DirSearchRec *p = NULL;
char dir[PATH_MAX];
char file[PATH_MAX];
char path[PATH_MAX];
char *np;
dirent *de;
glob_t gl;
struct stat s;
strcpy( path, aWildCard );
if (!isWild(path)) strcat(path, "*");
fexpand( path );
expandPath(path, dir, file);
TFileCollection *fileList = new TFileCollection( 5, 5 );
/* find all filenames that match our wildcards */
/*
* The use of 'glob' function was proposed by:
* Rainer Keuchel <r_keuchel@smaug.netwave.de>
* Date: 18 Jan 1997 22:52:12 +0000
*/
#ifdef GLOB_PERIOD
if (glob(path, GLOB_PERIOD, NULL, &gl) == 0)
#else
if (glob(path, 0, NULL, &gl) == 0)
#endif
for (int i = 0; i < gl.gl_pathc; i++)
{
/* is this a regular file ? */
if (stat(gl.gl_pathv[i], &s) == 0 && S_ISREG(s.st_mode))
{
if ((p = new DirSearchRec) == NULL) break;
/* strip directory part */
if ((np = strrchr(gl.gl_pathv[i], '/')) != NULL) np++;
else np = gl.gl_pathv[i];
p->readFf_blk(np, s);
fileList->insert( p );
}
}
globfree(&gl);
/* now read all directory names */
sprintf(path, "%s.", dir);
if ((dp = opendir(path)) != NULL)
{
while ((de = readdir(dp)) != NULL)
{
/* we don't want these directories */
if (strcmp(de->d_name, ".") == 0 ||
strcmp(de->d_name, "..") == 0) continue;
/* is it a directory ? */
sprintf(path, "%s%s", dir, de->d_name);
if (stat(path, &s) == 0 && S_ISDIR(s.st_mode))
{
if ((p = new DirSearchRec) == NULL) break;
p->readFf_blk(de->d_name, s);
fileList->insert( p );
}
}
closedir(dp);
}
if( strlen( dir ) > 1 )
{
p = new DirSearchRec;
if( p != 0 )
{
sprintf(path, "%s..", dir);
if (stat(path, &s) == 0) p->readFf_blk("..", s);
else
{
strcpy( p->name, ".." );
p->size = 0;
p->time = 0x210000uL;
p->attr = FA_DIREC;
}
fileList->insert( p );
}
}
if( p == 0 )
messageBox( tooManyFiles, mfOKButton | mfWarning );
newList(fileList);
if( list()->getCount() > 0 )
message( owner, evBroadcast, cmFileFocused, list()->at(0) );
else
{
static DirSearchRec noFile;
message( owner, evBroadcast, cmFileFocused, &noFile );
}
}
#if !defined(NO_STREAMABLE)
TStreamable *TFileList::build()
{
return new TFileList( streamableInit );
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1