📄 filebrowserform.c
字号:
/***********************************************************************
*
* FUNCTION: PrvEnumerate
*
* DESCRIPTION: .
*
* PARAMETERS: None.
*
* RETURNED: N/A.
*
***********************************************************************/
Err PrvEnumerate()
{
Err err = errNone;
FileRef dirRef = 0;
FileInfoType fileInfo;
UInt32 fileType = 0;
UInt32 fileIterator = 0;
Char *fileName = (Char*)MemPtrNew(MAX_FILENAME_LENGTH);
fileInfo.nameP = fileName;
fileInfo.nameBufLen = MAX_FILENAME_LENGTH;
// Clean the database
PrvEmptyDB();
// If not the root, add UP directory
if( StrCompare( "/", gCurrentPath) )
{
StrCopy( fileName, "..");
fileInfo.attributes = vfsFileAttrDirectory;
PrvAddRecord(&fileInfo);
}
// Open at the current volume and path
err = VFSFileOpen(gCurrentVolume, gCurrentPath, vfsModeRead, &dirRef);
if( err == errNone )
{
fileIterator = vfsIteratorStart;
while( fileIterator != vfsIteratorStop )
{
err = VFSDirEntryEnumerate(dirRef, &fileIterator, &fileInfo);
if( err == errNone )
{
if( ! (fileInfo.attributes & UNWANTED_FILES) )
{
// Filter for .mp3, .mp2, .mp1
if( StrCaselessCompare(fileName + StrLen(fileName) - 4, ".mp3") == 0
|| StrCaselessCompare(fileName + StrLen(fileName) - 4, ".mp2") == 0
|| StrCaselessCompare(fileName + StrLen(fileName) - 4, ".mp1") == 0
|| fileInfo.attributes == vfsFileAttrDirectory )
{
PrvAddRecord(&fileInfo);
}
}
}
}
VFSFileClose( dirRef );
}
MemPtrFree(fileName);
gFileCount = DmNumRecords(gDB);
PrvDBSort();
return err;
}
/***********************************************************************
*
* FUNCTION: PrvDrawTableBorder
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED: N/A
*
***********************************************************************/
static void PrvDrawTableBorder(FormType *frmP)
{
RectangleType bounds;
TablePtr tableP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, FileBrowserFileTable));
TblGetBounds(tableP, &bounds);
WinDrawRectangleFrame(menuFrame, &bounds);
}
#pragma mark ---------- File Browser DB Functions ----------
/***********************************************************************
*
* FUNCTION: FileBrowserDeleteDB
*
* DESCRIPTION: This routine should be called when the app stops.
* It deletes the temporary database.
*
* PARAMETERS: None.
*
* RETURNED: Error Code.
*
***********************************************************************/
Err FileBrowserDeleteDB()
{
LocalID dbID;
UInt16 cardNo;
Err err = errNone;
if(!gDB)
{
// Open the database
dbID = DmFindDatabase(fbCardNumber, fbDBName);
if( dbID )
{
// If exists open it
gDB = DmOpenDatabase(fbCardNumber, dbID, dmModeReadWrite);
if(!gDB) {
err = DmGetLastErr();
return err;
}
}
else
return err;
}
err = DmOpenDatabaseInfo(gDB, &dbID, 0, 0, &cardNo, 0);
err = DmCloseDatabase(gDB);
err = DmDeleteDatabase(cardNo, dbID);
return err;
}
/***********************************************************************
*
* FUNCTION: PrvEmptyDB
*
* DESCRIPTION: This routine deletes all the records of the temp database.
*
* PARAMETERS: None.
*
* RETURNED: Error Code.
*
***********************************************************************/
static Err PrvEmptyDB()
{
Err err = errNone;
UInt16 index = DmNumRecords(gDB);
while (index--)
{
err = DmRemoveRecord(gDB, index);
}
return err;
}
/***********************************************************************
*
* FUNCTION: PrvAddRecord
*
* DESCRIPTION: This routine adds a record to the temp database
*
* PARAMETERS: fileInfoP - Pointer to a FileInfo Structure
*
* RETURNED: Error Code
*
***********************************************************************/
static Err PrvAddRecord(FileInfoType* fileInfoP)
{
Err err = errNone;
void* memLockP;
MemHandle recordHandle;
UInt32 recordSize;
UInt16 recordIndex = dmMaxRecordIndex;
FileBrowserFileInfo fbFileInfo;
// Local store
fbFileInfo.selected = false;
fbFileInfo.attribute = fileInfoP->attributes;
fbFileInfo.fileName = fileInfoP->nameP;
recordSize = (StrLen(fbFileInfo.fileName)+1);
recordHandle = DmNewRecord(gDB, &recordIndex, recordSize + sizeof(UInt16) + sizeof(Boolean));
if( !recordHandle )
{
err = DmGetLastErr();
return err;
}
memLockP = MemHandleLock(recordHandle);
// Write selection
err = DmWrite( memLockP, 0, &fbFileInfo.selected, sizeof(Boolean));
if( err == errNone )
{
err = DmWrite( memLockP, sizeof(Boolean), &fbFileInfo.attribute, sizeof(UInt16));
}
if( err == errNone )
{
err = DmWrite( memLockP, sizeof(UInt16) + sizeof(Boolean), fbFileInfo.fileName, recordSize);
}
MemHandleUnlock(recordHandle);
err = DmReleaseRecord(gDB, recordIndex, true);
if( err )
{
DmRemoveRecord(gDB, recordIndex);
}
return err;
}
/***********************************************************************
*
* FUNCTION: PrvGetRecord
*
* DESCRIPTION: This routine returns the file info for the given index
*
* PARAMETERS: index - File index in the database
* fileInfoP - File info Ptr
*
* RETURNED:
*
***********************************************************************/
static Err PrvGetRecord(UInt16 index, FileBrowserFileInfo* fileInfoP, MemHandle* hP)
{
Err err = errNone;
UInt8 *recP = NULL;
MemHandle myh;
myh = DmQueryRecord(gDB, index);
if (myh == NULL)
{
err = DmGetLastErr();
goto Done;
}
else
{
*hP = myh;
}
recP = (UInt8 *)MemHandleLock(*hP);
if (recP == NULL)
{
err = memErrChunkNotLocked;
goto Done;
}
fileInfoP->selected = (Boolean)*recP;
recP += sizeof(Boolean);
fileInfoP->attribute = MisalignedReadBEUInt16(recP, 0);
recP += sizeof(UInt16);
fileInfoP->fileName = (Char*)recP;
Done:
return err;
}
/***********************************************************************
*
* FUNCTION: PrvReleaseRecord
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED:
*
***********************************************************************/
static void PrvReleaseRecord(UInt16 index, MemHandle h)
{
MemHandleUnlock(h);
}
/***********************************************************************
*
* FUNCTION:
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED:
*
***********************************************************************/
static Int16 PrvDBCompareRecords( Char* r1P, Char* r2P,
Int16 UNUSED_PARAM(param), SortRecordInfoType* UNUSED_PARAM(info1),
SortRecordInfoType* UNUSED_PARAM(info2), MemHandle UNUSED_PARAM(appInfoH))
{
Int16 result;
FileBrowserFileInfo rec1, rec2;
rec1.selected = (Boolean)*r1P;
r1P += sizeof(Boolean);
rec1.attribute = MisalignedReadBEUInt16(r1P, 0);
r1P += sizeof(UInt16);
rec1.fileName = (Char*)r1P;
rec2.selected = (Boolean)*r2P;
r2P += sizeof(Boolean);
rec2.attribute = MisalignedReadBEUInt16(r2P, 0);
r2P += sizeof(UInt16);
rec2.fileName = (Char*)r2P;
// First check to display the folder first
if (rec1.attribute & vfsFileAttrDirectory)
{
if (!(rec2.attribute & vfsFileAttrDirectory))
return -1;
}
else if (rec2.attribute & vfsFileAttrDirectory)
return 1;
// Alphabetize;
result = TxtCompare( rec1.fileName, // const Char *s1
0xFFFF, // UInt16 s1Len,
NULL, // UInt16 *s1MatchLen,
rec2.fileName, // const Char *s2,
0xFFFF, // UInt16 s2Len,
NULL); // UInt16 *s2MatchLen
return result;
}
/************************************************************
*
* FUNCTION:
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNS:
*
*************************************************************/
static void PrvDBSort()
{
DmInsertionSort(gDB, (DmComparF *)&PrvDBCompareRecords, 0);
}
#pragma mark ---------- File Browser List View ----------
/***********************************************************************
*
* FUNCTION: PrvListViewInit
*
* DESCRIPTION: This routine initializes the table
*
* PARAMETERS: frmP - Pointer to a form
*
* RETURNED: N/A
*
***********************************************************************/
static void PrvListViewInit(FormType *frmP)
{
UInt16 rowCount;
TablePtr tableP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, FileBrowserFileTable));
gRowCount = rowCount = TblGetNumberOfRows(tableP);
// Init the row elements
while( rowCount-- )
{
TblSetRowUsable(tableP, rowCount, false);
TblSetItemStyle(tableP, rowCount, FILE_COLUMN, customTableItem);
}
TblHasScrollBar(tableP, true);
TblSetColumnUsable(tableP, FILE_COLUMN, true);
TblSetCustomDrawProcedure(tableP, FILE_COLUMN, PrvListViewDrawFile);
// Load the table
PrvListViewLoadTable(frmP, false);
}
/***********************************************************************
*
* FUNCTION: PrvListViewDrawFile
*
* DESCRIPTION: This routine draws a file in the table
*
* PARAMETERS: tableP - Pointer to the table
* row - The row to draw
* column - The column to draw
* boundsP - Pointer to the element bound
*
* RETURNED: N/A
*
***********************************************************************/
static void PrvListViewDrawFile(void *tableP, Int16 row, Int16 column, RectangleType *boundsP)
{
UInt16 index;
MemHandle h;
FileBrowserFileInfo fileInfo;
WinHandle winH;
Char * ptr;
UInt16 titleLen;
Err err = errNone;
index = TblGetRowID(tableP, row);
err = PrvGetRecord( index, &fileInfo, &h);
if( err ) goto Done;
// Draw icon
ptr = StrChr (fileInfo.fileName, linefeedChr);
titleLen = (ptr == NULL ? StrLen (fileInfo.fileName) : (UInt16) (ptr - fileInfo.fileName));
if( fileInfo.attribute & vfsFileAttrDirectory )
{
RectangleType rct;
winH = gFolderWinH;
WinGetWindowFrameRect(winH, &rct);
WinCopyRectangle(winH, 0, &rct, boundsP->topLeft.x, boundsP->topLeft.y + 1, winPaint);
}
else
{
RectangleType rct;
winH = gDocumentWinH;
WinGetWindowFrameRect(winH, &rct);
WinCopyRectangle(winH, 0, &rct, boundsP->topLeft.x, boundsP->topLeft.y + 1, winPaint);
}
// Draw Title
if( FntWidthToOffset (fileInfo.fileName, titleLen, boundsP->extent.x - 15, NULL, NULL) == titleLen)
{
WinDrawChars (fileInfo.fileName, titleLen, boundsP->topLeft.x + 15, boundsP->topLeft.y);
}
else
{
Int16 titleWidth;
titleLen = FntWidthToOffset (fileInfo.fileName, titleLen, boundsP->extent.x - 15 - FntCharWidth (chrEllipsis), NULL, &titleWidth);
WinDrawChars (fileInfo.fileName, titleLen, boundsP->topLeft.x + 15, boundsP->topLeft.y);
WinDrawChar (chrEllipsis, boundsP->topLeft.x + 15 + titleWidth, boundsP->topLeft.y);
}
// Release the record
PrvReleaseRecord(index, h);
Done:
return;
}
/***********************************************************************
*
* FUNCTION: PrvListViewLoadTable
*
* DESCRIPTION: This routine loads the table.
*
* PARAMETERS: frmP - Pointer to a form.
*
* RETURNED: N/A
*
***********************************************************************/
static void PrvListViewLoadTable(FormType *frmP, Boolean redraw)
{
UInt16 row;
UInt16 rowCount;
UInt16 displayCount;
TablePtr tableP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, FileBrowserFileTable));
ScrollBarPtr barP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, FileBrowserFileScrollBar));
rowCount = TblGetNumberOfRows(tableP);
displayCount = gFileCount - gTopIndex;
for(row = 0; row < gRowCount; row++)
{
if( row < displayCount )
{
TblSetRowID(tableP, row, row + gTopIndex);
TblSetRowUsable(tableP, row, true);
TblSetRowSelectable(tableP, row, true);
}
else
{
TblSetRowUsable(tableP, row, false);
TblSetRowSelectable(tableP, row, false);
}
}
if( redraw )
{
TblEraseTable(tableP);
TblDrawTable(tableP);
}
if( gFileCount <= gRowCount )
{
SclSetScrollBar(barP, 0, 0, 0, gRowCount);
}
else
{
SclSetScrollBar(barP, gTopIndex, 0, gFileCount - gRowCount, gRowCount);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -