📄 filebrowserform.c
字号:
/***********************************************************************
*
* Copyright (c) 2004 PalmOne, Inc. or its subsidiaries.
* All rights reserved.
*
***********************************************************************/
/***********************************************************************
*
* File:
* FileBrowserForm.c
*
* Description:
* File browsing form
*
*
***********************************************************************/
#include <PalmOS.h>
#include <VfsMgr.h>
#include <DataMgr.h>
#include <PalmUtils.h>
#include "Common.h"
#include "FileBrowserForm.h"
#include "FileBrowserFormRsrc.h"
/***********************************************************************
*
* Internal Defines
*
***********************************************************************/
#define dataBaseType 'temp'
#define dbCardNumber 0
/***********************************************************************
*
* Internal typedef
*
***********************************************************************/
typedef struct
{
Boolean selected;
UInt16 attribute;
UInt32 fileSize;
Char* fileName;
} FileBrowserFileInfo;
/***********************************************************************
*
* Internal functions
*
***********************************************************************/
Err PrvFormInit(FormType* frmP);
void PrvFormDeInit(FormType* frmP);
Err PrvEnumerate();
Err PrvEmptyDB();
Err PrvAddRecord(FileInfoType* fileInfoP, UInt32 fileSize);
Err PrvGetRecord(UInt16 index, FileBrowserFileInfo* fileInfoP, MemHandle* hP);
void PrvReleaseRecord(UInt16 index, MemHandle h);
void PrvDBSort();
void PrvListViewInit(FormType* frmP);
void PrvListViewDrawFile(void* tableP, Int16 row, Int16 column, RectangleType* boundsP);
void PrvListViewLoadTable(FormType* frmP, Boolean redraw);
void PrvDrawTableBorder(FormType* frmP);
void PrvSelectFile(UInt16 index);
/***********************************************************************
*
* Internal Globals
*
***********************************************************************/
static DmOpenRef gDB = NULL; // Global pointer to the database
static UInt16 gRowCount = 0; // Number of row in table/list view
static UInt16 gTopIndex = 0; // Top index item of the table
static UInt32 gFileCount = 0; // Number of files in database
static UInt16 gVolumeCount = 0; // Number of cards
static UInt16 gCurrentVolume = 0;
static Char gCurrentPath[MAX_PATH_LENGTH] = { NULL };
static Char gCurrentFile[MAX_FILENAME_LENGTH] = { NULL };
static WinHandle gDocumentWinH = 0; // Document Bitmap buffer
static WinHandle gFolderWinH = 0; // Folder Bitmap buffer
static UInt32 gReturnForm = 0; // Form to return to
static FileBrowserCallback gCallback = NULL; // Callback
static FileBrowserView gViewType = DIRECTORY | FILE; // Show files and folders
static FileBrowserSelection gSelectionType = SINGLE; // Single selection
#pragma mark ---------- File Browser Functions ----------
/***********************************************************************
*
* FUNCTION: FileBrowserFormHandleEvent
*
* DESCRIPTION: This routine handles the events for the File Browser Form
*
* PARAMETERS: eventP - The pointer to the event.
*
* RETURNED: True if handled.
*
***********************************************************************/
Boolean FileBrowserFormHandleEvent(EventType * eventP)
{
Boolean handled = false;
FormType * frmP = FrmGetActiveForm();
switch (eventP->eType)
{
case frmOpenEvent:
PrvFormInit(frmP);
FrmDrawForm(frmP);
PrvDrawTableBorder(frmP);
handled = true;
break;
case ctlSelectEvent:
switch(eventP->data.ctlSelect.controlID)
{
case FileBrowserCancelButton:
FrmGotoForm(gReturnForm);
handled = true;
break;
}
break;
case sclRepeatEvent:
gTopIndex += (eventP->data.sclRepeat.newValue - eventP->data.sclRepeat.value);
{
TablePtr tableP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, FileBrowserFileTable));
PrvListViewLoadTable(frmP, true);
TblUnhighlightSelection(tableP);
TblRedrawTable(tableP);
}
handled = false;
break;
case frmUpdateEvent:
PrvDrawTableBorder(frmP);
break;
case frmCloseEvent:
PrvFormDeInit(frmP);
handled = false;
break;
case tblEnterEvent:
break;
case tblSelectEvent:
if( gFileCount > eventP->data.tblSelect.row )
{
PrvSelectFile(TblGetRowID(eventP->data.tblSelect.pTable, eventP->data.tblSelect.row));
handled = true;
}
break;
default:
break;
}
return handled;
}
/***********************************************************************
*
* FUNCTION: FileBrowserSetCallback
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED:
*
***********************************************************************/
void FileBrowserSetCallback(FileBrowserCallback callback, UInt32 formID)
{
gCallback = callback;
gReturnForm = formID;
}
/***********************************************************************
*
* FUNCTION: FileBrowserIsCallbackSet
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED:
*
***********************************************************************/
Boolean FileBrowserIsCallbackSet()
{
return (gCallback)?true:false;
}
/***********************************************************************
*
* FUNCTION: FileBrowserIsReturnFormSet
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED:
*
***********************************************************************/
Boolean FileBrowserIsReturnFormSet()
{
return (gReturnForm)?true:false;
}
/***********************************************************************
*
* FUNCTION: FileBrowserEnumerateSelection
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED:
*
***********************************************************************/
Err FileBrowserEnumerateSelection(UInt16 *volume, Char* path, Char* file, fbIterator *iterator)
{
Err err = errNone;
if( *iterator == fbIteratorStop ) return fbErrNoMoreSelection;
// Find the first selection from the iterator
return err;
}
/***********************************************************************
*
* FUNCTION: FileBrowserRefresh
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED:
*
***********************************************************************/
void FileBrowserRefresh()
{
FormType *frmP = FrmGetActiveForm();
// Empty the current database
PrvEmptyDB();
// Load new files
gRowCount = 0;
gTopIndex = 0;
gFileCount = 0;
gVolumeCount = 0;
gCurrentVolume = 0;
*gCurrentPath = NULL;
*gCurrentFile = NULL;
// Redraw the form
if( frmP )
{
PrvFormInit(frmP);
FrmDrawForm(frmP);
PrvDrawTableBorder(frmP);
}
}
/***********************************************************************
*
* FUNCTION: PrvSelectFile
*
* DESCRIPTION:
*
* PARAMETERS:
*
* RETURNED:
*
***********************************************************************/
static void PrvSelectFile(UInt16 index)
{
MemHandle h;
FileBrowserFileInfo fileInfo;
FormType * frmP = FrmGetActiveForm();
PrvGetRecord(index, &fileInfo, &h);
if( fileInfo.attribute & vfsFileAttrDirectory )
{
if( !StrCompare("..", fileInfo.fileName) )
{
// One directory above
UInt32 strLen = StrLen(gCurrentPath);
// Skip last '/' <- always there
strLen -= 2;
while( gCurrentPath[strLen--] != '/' ) {}
// Don't delete the first '/'
strLen += 2;
gCurrentPath[strLen] = NULL;
}
else
{
// One directory below
StrCat(gCurrentPath, fileInfo.fileName);
StrCat(gCurrentPath, "/");
}
PrvReleaseRecord(index, h);
// Clean up database
PrvEmptyDB();
// Enumerate with the new path
PrvEnumerate();
// Display the path
{
FieldType *fieldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, FileBrowserPathField));
SetFieldTextFromStr(fieldP, gCurrentPath, false);
}
// Reload the table
PrvListViewLoadTable(frmP, true);
FrmDrawForm(frmP);
PrvDrawTableBorder(frmP);
}
else
{
StrCopy(gCurrentFile, fileInfo.fileName);
PrvReleaseRecord(index, h);
// Play it!
if( gCallback ) {
gCallback(gCurrentVolume, gCurrentPath, gCurrentFile);
}
if( gReturnForm ) {
FrmGotoForm(gReturnForm);
}
}
}
/***********************************************************************
*
* FUNCTION: PrvFormInit
*
* DESCRIPTION: This routine initialize the File Browser form.
*
* PARAMETERS: frmP - Pointer to the form.
*
* RETURNED: Error Code.
*
***********************************************************************/
static Err PrvFormInit(FormType *frmP)
{
Err err = errNone;
UInt32 volumeIterator;
Boolean enumerate = false;
LocalID dbId;
if( !gDB )
{
// Open the database
dbId = DmFindDatabase(fbCardNumber, fbDBName);
if( dbId )
{
// If exists open it
gDB = DmOpenDatabase(fbCardNumber, dbId, dmModeReadWrite);
if(!gDB) {
err = DmGetLastErr();
goto Done;
}
}
else
{
// Else create the database
err = DmCreateDatabase(fbCardNumber, fbDBName, fbCreatorID, 'temp', false);
if (err != errNone) return err;
dbId = DmFindDatabase(fbCardNumber, fbDBName);
if( !dbId ) {
err = DmGetLastErr();
goto Done;
}
gDB = DmOpenDatabase(fbCardNumber, dbId, dmModeReadWrite);
if( !gDB ) {
err = DmGetLastErr();
goto Done;
}
// Need to enumerate the files
enumerate = true;
}
}
//
// Get the first card if no volume selected
//
if( !gCurrentVolume )
{
volumeIterator = vfsIteratorStart;
err = VFSVolumeEnumerate(&gCurrentVolume, &volumeIterator);
if( err == expErrEnumerationEmpty ) {
gCurrentVolume = 0;
}
enumerate = true;
}
//
// Set path to the root if not set
//
if( !(*gCurrentPath) )
{
StrCopy((Char*)gCurrentPath, "/");
enumerate = true;
}
//
// No file selected for now
//
*gCurrentFile = NULL;
//
// Load the files in the Database if needed
//
if( enumerate ) {
PrvEnumerate();
}
//
// Load the bitmaps
//
{
MemHandle h;
BitmapType* bmpP;
Coord width, height;
WinHandle winH = WinGetDrawWindow();
Err err;
h = DmGet1Resource(bitmapRsc, FolderBitmapFamily);
bmpP = (BitmapType*)MemHandleLock(h);
BmpGetDimensions(bmpP, &width, &height, 0);
gFolderWinH = WinCreateOffscreenWindow(width, height, nativeFormat, &err);
WinSetDrawWindow(gFolderWinH);
WinDrawBitmap(bmpP, 0, 0);
MemHandleUnlock(h);
DmReleaseResource(h);
h = DmGet1Resource(bitmapRsc, DocumentBitmapFamily);
bmpP = (BitmapType*)MemHandleLock(h);
BmpGetDimensions(bmpP, &width, &height, 0);
gDocumentWinH = WinCreateOffscreenWindow(width, height, nativeFormat, &err);
WinSetDrawWindow(gDocumentWinH);
WinDrawBitmap(bmpP, 0, 0);
MemHandleUnlock(h);
DmReleaseResource(h);
WinSetDrawWindow(winH);
}
//
// Display the path
//
{
FieldType *fieldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, FileBrowserPathField));
SetFieldTextFromStr(fieldP, gCurrentPath, false);
}
Done:
//
// Setup the table
//
PrvListViewInit(frmP);
return err;
}
/***********************************************************************
*
* FUNCTION: PrvFormDeInit
*
* DESCRIPTION: This routine de-initialize the File Browser form.
*
* PARAMETERS: frmP - Pointer to the form.
*
* RETURNED: None.
*
***********************************************************************/
static void PrvFormDeInit(FormType* frmP)
{
// Release the offscreen windows
if( gFolderWinH ) {
WinDeleteWindow(gFolderWinH, false);
gFolderWinH = 0;
}
if( gDocumentWinH ) {
WinDeleteWindow(gDocumentWinH, false);
gDocumentWinH = 0;
}
// Close the database
if( gDB ) {
DmCloseDatabase(gDB);
gDB = NULL;
}
}
/***********************************************************************
*
* FUNCTION: PrvEnumerate
*
* DESCRIPTION: .
*
* PARAMETERS: None.
*
* RETURNED: N/A.
*
***********************************************************************/
Err PrvEnumerate()
{
Err err = errNone;
FileRef dirRef = 0;
FileRef fileRef = 0;
FileInfoType fileInfo;
UInt32 fileType = 0;
UInt32 fileSize = 0;
UInt32 fileIterator = 0;
Char *fileName = (Char*)MemPtrNew(MAX_FILENAME_LENGTH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -