2009-10-01 01:10:58 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* libwiigui Template
|
|
|
|
* Tantric 2009
|
|
|
|
*
|
|
|
|
* modified by dimok
|
|
|
|
*
|
|
|
|
* filebrowser.cpp
|
|
|
|
*
|
|
|
|
* Generic file routines - reading, writing, browsing
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include <gccore.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <wiiuse/wpad.h>
|
|
|
|
#include <sys/dir.h>
|
2009-10-05 12:53:19 +02:00
|
|
|
#include <sys/iosupport.h>
|
2009-10-01 01:10:58 +02:00
|
|
|
#include <malloc.h>
|
2009-10-05 12:53:19 +02:00
|
|
|
#include <algorithm>
|
2009-10-01 01:10:58 +02:00
|
|
|
|
|
|
|
#include "menu.h"
|
|
|
|
|
|
|
|
#include "listfiles.h"
|
|
|
|
#include "language/gettext.h"
|
|
|
|
#include "PromptWindows.h"
|
|
|
|
#include "libwiigui/gui.h"
|
|
|
|
#include "sys.h"
|
2009-10-05 12:53:19 +02:00
|
|
|
#include "filebrowser.h"
|
2009-10-01 01:10:58 +02:00
|
|
|
|
|
|
|
/*** Extern variables ***/
|
|
|
|
extern GuiWindow * mainWindow;
|
2010-01-19 11:48:50 +01:00
|
|
|
extern u8 shutdown;
|
|
|
|
extern u8 reset;
|
|
|
|
|
|
|
|
/*** Extern functions ***/
|
|
|
|
extern void ResumeGui();
|
|
|
|
extern void HaltGui();
|
2009-10-01 01:10:58 +02:00
|
|
|
|
2009-10-05 12:53:19 +02:00
|
|
|
static int curDevice = -1;
|
|
|
|
static std::vector<BROWSERINFO> browsers;
|
|
|
|
BROWSERINFO *browser = NULL;
|
|
|
|
|
|
|
|
|
2009-10-01 01:10:58 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
2009-10-05 12:53:19 +02:00
|
|
|
* FileFilterCallbacks
|
|
|
|
* return: 1-visible 0-hidden
|
2009-10-01 01:10:58 +02:00
|
|
|
***************************************************************************/
|
2010-09-19 01:16:05 +02:00
|
|
|
int noDIRS( BROWSERENTRY *Entry, void* Args )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
return !Entry->isdir;
|
2009-10-05 12:53:19 +02:00
|
|
|
}
|
2010-09-19 01:16:05 +02:00
|
|
|
int noFILES( BROWSERENTRY *Entry, void* Args )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
return Entry->isdir;
|
2009-10-05 12:53:19 +02:00
|
|
|
}
|
2010-09-19 01:16:05 +02:00
|
|
|
int noEXT( BROWSERENTRY *Entry, void* Args )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( !Entry->isdir )
|
|
|
|
{
|
|
|
|
char *cptr = strrchr( Entry->displayname, '.' );
|
|
|
|
if ( cptr && cptr != Entry->displayname ) *cptr = 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2009-10-01 01:10:58 +02:00
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
void ResetBrowser( BROWSERINFO *browser );
|
2009-10-01 01:10:58 +02:00
|
|
|
/****************************************************************************
|
2009-10-05 12:53:19 +02:00
|
|
|
* InitBrowsers()
|
|
|
|
* Clears the file browser memory, and allocates one initial entry
|
2009-10-01 01:10:58 +02:00
|
|
|
***************************************************************************/
|
2010-09-19 01:16:05 +02:00
|
|
|
int InitBrowsers()
|
|
|
|
{
|
|
|
|
curDevice = -1;
|
|
|
|
browsers.clear();
|
|
|
|
browser = NULL;
|
|
|
|
char rootdir[ROOTDIRLEN];
|
|
|
|
for ( int i = 3; i < STD_MAX; i++ )
|
|
|
|
{
|
|
|
|
if ( strcmp( devoptab_list[i]->name, "stdnull" ) && devoptab_list[i]->write_r != NULL )
|
|
|
|
{
|
|
|
|
snprintf( rootdir, sizeof( rootdir ) , "%s:/", devoptab_list[i]->name );
|
|
|
|
if ( DIR_ITER *dir = diropen( rootdir ) )
|
|
|
|
{
|
|
|
|
dirclose( dir );
|
|
|
|
BROWSERINFO browser;
|
|
|
|
browser.dir[0] = '\0';
|
|
|
|
strcpy( browser.rootdir, rootdir );
|
|
|
|
ResetBrowser( &browser );
|
|
|
|
browsers.push_back( browser );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !browsers.size() ) return -1;
|
|
|
|
curDevice = 0;
|
|
|
|
browser = &browsers[curDevice];
|
|
|
|
return 0;
|
2009-10-05 12:53:19 +02:00
|
|
|
}
|
|
|
|
/****************************************************************************
|
|
|
|
* ResetBrowser()
|
|
|
|
* Clears the file browser memory, and allocates one initial entry
|
|
|
|
***************************************************************************/
|
2010-09-19 01:16:05 +02:00
|
|
|
void ResetBrowser( BROWSERINFO *browser )
|
|
|
|
{
|
|
|
|
browser->pageIndex = 0;
|
|
|
|
browser->browserList.clear();
|
|
|
|
/*
|
|
|
|
// Clear any existing values
|
|
|
|
if (browser->browserList != NULL) {
|
|
|
|
free(browser->browserList);
|
|
|
|
browser->browserList = NULL;
|
|
|
|
}
|
|
|
|
// set aside space for 1 entry
|
|
|
|
browser->browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY));
|
|
|
|
if(browser->browserList)
|
|
|
|
memset(browser->browserList, 0, sizeof(BROWSERENTRY));
|
|
|
|
*/
|
2009-10-01 01:10:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* FileSortCallback
|
|
|
|
*
|
2009-10-05 12:53:19 +02:00
|
|
|
* sort callback to sort file entries with the following order:
|
2009-10-01 01:10:58 +02:00
|
|
|
* .
|
|
|
|
* ..
|
|
|
|
* <dirs>
|
|
|
|
* <files>
|
|
|
|
***************************************************************************/
|
2009-10-05 12:53:19 +02:00
|
|
|
//int FileSortCallback(const void *f1, const void *f2) {
|
2010-09-19 01:16:05 +02:00
|
|
|
bool operator< ( const BROWSERENTRY &f1, const BROWSERENTRY &f2 )
|
|
|
|
{
|
|
|
|
/* Special case for implicit directories */
|
|
|
|
if ( f1.filename[0] == '.' || f2.filename[0] == '.' )
|
|
|
|
{
|
|
|
|
if ( strcmp( f1.filename, "." ) == 0 )
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if ( strcmp( f2.filename, "." ) == 0 )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ( strcmp( f1.filename, ".." ) == 0 )
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if ( strcmp( f2.filename, ".." ) == 0 )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If one is a file and one is a directory the directory is first. */
|
|
|
|
if ( f1.isdir && !( f2.isdir ) ) return true;
|
|
|
|
if ( !( f1.isdir ) && f2.isdir ) return false;
|
|
|
|
|
|
|
|
return stricmp( f1.filename, f2.filename ) < 0;
|
2009-10-01 01:10:58 +02:00
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
int ParseFilter( FILTERCASCADE *Filter, BROWSERENTRY* Entry )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
while ( Filter )
|
|
|
|
{
|
|
|
|
if ( Filter->filter && Filter->filter( Entry, Filter->filter_args ) == 0 )
|
|
|
|
return 0;
|
|
|
|
Filter = Filter->next;
|
|
|
|
}
|
|
|
|
return 1;
|
2009-10-05 12:53:19 +02:00
|
|
|
}
|
2009-10-01 01:10:58 +02:00
|
|
|
/***************************************************************************
|
|
|
|
* Browse subdirectories
|
|
|
|
**************************************************************************/
|
2010-09-19 01:16:05 +02:00
|
|
|
int ParseDirectory( const char* Path, int Flags, FILTERCASCADE *Filter )
|
|
|
|
{
|
|
|
|
DIR_ITER *dir = NULL;
|
|
|
|
char fulldir[MAXPATHLEN];
|
|
|
|
char filename[MAXPATHLEN];
|
|
|
|
struct stat filestat;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
if ( curDevice == -1 )
|
|
|
|
if ( InitBrowsers() ) return -1; // InitBrowser fails
|
|
|
|
|
|
|
|
if ( Path ) // note in this codeblock use filename temporary
|
|
|
|
{
|
|
|
|
strlcpy( fulldir, Path, sizeof( fulldir ) );
|
|
|
|
if ( *fulldir && fulldir[strlen( fulldir )-1] != '/' ) // a file
|
|
|
|
{
|
|
|
|
char * chrp = strrchr( fulldir, '/' );
|
|
|
|
if ( chrp ) chrp[1] = 0;
|
|
|
|
}
|
|
|
|
if ( strchr( fulldir, ':' ) == NULL ) // Path has no device device
|
|
|
|
{
|
|
|
|
getcwd( filename, sizeof( filename ) ); // save the current working dir
|
|
|
|
if ( *fulldir == 0 ) // if path is empty
|
|
|
|
strlcpy( fulldir, filename, sizeof( fulldir ) ); // we use the current working dir
|
|
|
|
else
|
|
|
|
{ // path is not empty
|
|
|
|
if ( chdir( fulldir ) ); // sets the path to concatenate and validate
|
|
|
|
{
|
|
|
|
if ( Flags & ( FB_TRYROOTDIR | FB_TRYSTDDEV ) )
|
|
|
|
if ( chdir( "/" ) && !( Flags & FB_TRYSTDDEV ) )// try to set root if is needed
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ( getcwd( fulldir, sizeof( fulldir ) ) ) return -1; // gets the concatenated current working dir
|
|
|
|
chdir( filename ); // restore the saved cwd
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( i = 0; i < browsers.size(); i++ ) // searchs the browser who match the path
|
|
|
|
{
|
|
|
|
if ( strnicmp( fulldir, browsers[i].rootdir, strlen( browsers[i].rootdir ) - 1 /*means without trailing '/'*/ ) == 0 )
|
|
|
|
{
|
|
|
|
browser = &browsers[curDevice];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( i != browsers.size() ) // found browser
|
|
|
|
{
|
|
|
|
curDevice = i;
|
|
|
|
browser = &browsers[curDevice];
|
|
|
|
strcpy( browser->dir, &fulldir[strlen( browser->rootdir )] );
|
|
|
|
}
|
|
|
|
else if ( Flags & FB_TRYSTDDEV )
|
|
|
|
{
|
|
|
|
curDevice = 0;
|
|
|
|
browser = &browsers[curDevice]; // when no browser was found and
|
|
|
|
browser->dir[0] = 0; // we alowed try StdDevice and try RootDir
|
|
|
|
strlcpy( fulldir, browser->rootdir, sizeof( fulldir ) ); // set the first browser with root-dir
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
snprintf( fulldir, sizeof( fulldir ), "%s%s", browser->rootdir, browser->dir );
|
|
|
|
|
|
|
|
// reset browser
|
|
|
|
ResetBrowser( browser );
|
|
|
|
|
|
|
|
// open the directory
|
|
|
|
if ( ( dir = diropen( fulldir ) ) == NULL )
|
|
|
|
{
|
|
|
|
if ( Flags & FB_TRYROOTDIR )
|
|
|
|
{
|
|
|
|
browser->dir[0] = 0;
|
|
|
|
if ( ( dir = diropen( browser->rootdir ) ) == NULL )
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ( dirnext( dir, filename, &filestat ) == 0 )
|
|
|
|
{
|
|
|
|
if ( strcmp( filename, "." ) != 0 )
|
|
|
|
{
|
|
|
|
BROWSERENTRY newEntry;
|
|
|
|
memset( &newEntry, 0, sizeof( BROWSERENTRY ) ); // clear the new entry
|
|
|
|
strlcpy( newEntry.filename, filename, sizeof( newEntry.filename ) );
|
|
|
|
strlcpy( newEntry.displayname, filename, sizeof( newEntry.displayname ) );
|
|
|
|
newEntry.length = filestat.st_size;
|
|
|
|
newEntry.isdir = ( filestat.st_mode & S_IFDIR ) == 0 ? 0 : 1; // flag this as a dir
|
|
|
|
if ( ParseFilter( Filter, &newEntry ) )
|
|
|
|
browser->browserList.push_back( newEntry );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// close directory
|
|
|
|
dirclose( dir );
|
|
|
|
|
|
|
|
// Sort the file list
|
|
|
|
std::sort( browser->browserList.begin(), browser->browserList.end() );
|
|
|
|
return 0;
|
2009-10-01 01:10:58 +02:00
|
|
|
}
|
2010-09-19 01:16:05 +02:00
|
|
|
int ParseDirectory( int Device, int Flags, FILTERCASCADE *Filter )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( Device >= 0 && Device < ( int )browsers.size() )
|
|
|
|
{
|
|
|
|
int old_curDevice = curDevice;
|
|
|
|
curDevice = Device;
|
|
|
|
browser = &browsers[curDevice];
|
|
|
|
if ( ParseDirectory( ( char* )NULL, Flags, Filter ) == 0 ) return 0;
|
|
|
|
curDevice = old_curDevice;
|
|
|
|
browser = &browsers[old_curDevice];
|
|
|
|
}
|
|
|
|
return -1;
|
2009-10-01 01:10:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* BrowseDevice
|
2009-10-05 12:53:19 +02:00
|
|
|
* Displays a list of files on the selected path
|
2009-10-01 01:10:58 +02:00
|
|
|
***************************************************************************/
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
int BrowseDevice( char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*=NULL*/ )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
int result = -1;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if ( InitBrowsers() || ParseDirectory( Path, Flags, Filter ) )
|
|
|
|
{
|
|
|
|
WindowPrompt( tr( "Error" ), 0, tr( "OK" ) );
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int menu = MENU_NONE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
GuiText titleTxt("Browse Files", 28, (GXColor){0, 0, 0, 230});
|
|
|
|
titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
|
|
|
|
titleTxt.SetPosition(70,20);
|
|
|
|
*/
|
|
|
|
GuiTrigger trigA;
|
|
|
|
trigA.SetSimpleTrigger( -1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A );
|
|
|
|
GuiTrigger trigB;
|
|
|
|
trigB.SetButtonOnlyTrigger( -1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B );
|
|
|
|
|
|
|
|
GuiSound btnSoundOver( button_over_pcm, button_over_pcm_size, Settings.sfxvolume );
|
|
|
|
// because destroy GuiSound must wait while sound playing is finished, we use a global sound
|
|
|
|
if ( !btnClick2 ) btnClick2 = new GuiSound( button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume );
|
|
|
|
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
|
|
|
|
|
|
|
|
GuiImageData folderImgData( icon_folder_png );
|
|
|
|
GuiImage folderImg( &folderImgData );
|
|
|
|
GuiButton folderBtn( folderImg.GetWidth(), folderImg.GetHeight() );
|
|
|
|
folderBtn.SetAlignment( ALIGN_CENTRE, ALIGN_MIDDLE );
|
|
|
|
folderBtn.SetPosition( -210, -145 );
|
|
|
|
folderBtn.SetImage( &folderImg );
|
|
|
|
folderBtn.SetTrigger( &trigA );
|
|
|
|
folderBtn.SetEffectGrow();
|
|
|
|
|
|
|
|
char imgPath[100];
|
2010-09-19 22:25:12 +02:00
|
|
|
snprintf( imgPath, sizeof( imgPath ), "%sbutton_dialogue_box.png", Settings.theme_path );
|
2010-09-19 01:16:05 +02:00
|
|
|
GuiImageData btnOutline( imgPath, button_dialogue_box_png );
|
|
|
|
GuiText ExitBtnTxt( tr( "Cancel" ), 24, ( GXColor ) {0, 0, 0, 255} );
|
|
|
|
GuiImage ExitBtnImg( &btnOutline );
|
|
|
|
if ( Settings.wsprompt == yes )
|
|
|
|
{
|
2010-09-19 22:25:12 +02:00
|
|
|
ExitBtnTxt.SetWidescreen( Settings.widescreen );
|
|
|
|
ExitBtnImg.SetWidescreen( Settings.widescreen );
|
2010-09-19 01:16:05 +02:00
|
|
|
}
|
|
|
|
GuiButton ExitBtn( btnOutline.GetWidth(), btnOutline.GetHeight() );
|
|
|
|
ExitBtn.SetAlignment( ALIGN_RIGHT, ALIGN_BOTTOM );
|
|
|
|
ExitBtn.SetPosition( -40, -35 );
|
|
|
|
ExitBtn.SetLabel( &ExitBtnTxt );
|
|
|
|
ExitBtn.SetImage( &ExitBtnImg );
|
|
|
|
ExitBtn.SetTrigger( &trigA );
|
|
|
|
ExitBtn.SetTrigger( &trigB );
|
|
|
|
ExitBtn.SetEffectGrow();
|
|
|
|
|
|
|
|
GuiText usbBtnTxt( browsers[( curDevice+1 )%browsers.size()].rootdir, 24, ( GXColor ) {0, 0, 0, 255} );
|
|
|
|
GuiImage usbBtnImg( &btnOutline );
|
|
|
|
if ( Settings.wsprompt == yes )
|
|
|
|
{
|
2010-09-19 22:25:12 +02:00
|
|
|
usbBtnTxt.SetWidescreen( Settings.widescreen );
|
|
|
|
usbBtnImg.SetWidescreen( Settings.widescreen );
|
2010-09-19 01:16:05 +02:00
|
|
|
}
|
|
|
|
GuiButton usbBtn( btnOutline.GetWidth(), btnOutline.GetHeight() );
|
|
|
|
usbBtn.SetAlignment( ALIGN_CENTRE, ALIGN_BOTTOM );
|
|
|
|
usbBtn.SetPosition( 0, -35 );
|
|
|
|
usbBtn.SetLabel( &usbBtnTxt );
|
|
|
|
usbBtn.SetImage( &usbBtnImg );
|
|
|
|
usbBtn.SetTrigger( &trigA );
|
|
|
|
usbBtn.SetEffectGrow();
|
|
|
|
|
|
|
|
GuiText okBtnTxt( tr( "OK" ), 22, THEME.prompttext );
|
|
|
|
GuiImage okBtnImg( &btnOutline );
|
|
|
|
if ( Settings.wsprompt == yes )
|
|
|
|
{
|
2010-09-19 22:25:12 +02:00
|
|
|
okBtnTxt.SetWidescreen( Settings.widescreen );
|
|
|
|
okBtnImg.SetWidescreen( Settings.widescreen );
|
2010-09-19 01:16:05 +02:00
|
|
|
}
|
|
|
|
GuiButton okBtn( &okBtnImg, &okBtnImg, 0, 4, 40, -35, &trigA, &btnSoundOver, btnClick2, 1 );
|
|
|
|
okBtn.SetLabel( &okBtnTxt );
|
|
|
|
|
|
|
|
GuiFileBrowser fileBrowser( 396, 248 );
|
|
|
|
fileBrowser.SetAlignment( ALIGN_CENTRE, ALIGN_TOP );
|
|
|
|
fileBrowser.SetPosition( 0, 120 );
|
|
|
|
|
|
|
|
GuiImageData Address( addressbar_textbox_png );
|
|
|
|
GuiText AdressText( ( char* ) NULL, 20, ( GXColor ) { 0, 0, 0, 255} );
|
|
|
|
AdressText.SetTextf( "%s%s", browser->rootdir, browser->dir );
|
|
|
|
AdressText.SetAlignment( ALIGN_LEFT, ALIGN_MIDDLE );
|
|
|
|
AdressText.SetPosition( 20, 0 );
|
|
|
|
AdressText.SetMaxWidth( Address.GetWidth() - 40, SCROLL_HORIZONTAL );
|
|
|
|
GuiImage AdressbarImg( &Address );
|
|
|
|
GuiButton Adressbar( Address.GetWidth(), Address.GetHeight() );
|
|
|
|
Adressbar.SetAlignment( ALIGN_CENTRE, ALIGN_TOP );
|
|
|
|
Adressbar.SetPosition( 0, fileBrowser.GetTop() - 45 );
|
|
|
|
Adressbar.SetImage( &AdressbarImg );
|
|
|
|
Adressbar.SetLabel( &AdressText );
|
|
|
|
|
|
|
|
HaltGui();
|
|
|
|
GuiWindow w( screenwidth, screenheight );
|
|
|
|
w.Append( &ExitBtn );
|
|
|
|
// w.Append(&titleTxt);
|
|
|
|
w.Append( &fileBrowser );
|
|
|
|
w.Append( &Adressbar );
|
|
|
|
w.Append( &okBtn );
|
|
|
|
if ( !( Flags & FB_NOFOLDER_BTN ) )
|
|
|
|
w.Append( &folderBtn );
|
|
|
|
if ( browsers.size() > 1 && !( Flags & FB_NODEVICE_BTN ) )
|
|
|
|
w.Append( &usbBtn );
|
|
|
|
mainWindow->Append( &w );
|
|
|
|
ResumeGui();
|
|
|
|
int clickedIndex = -1;
|
|
|
|
while ( menu == MENU_NONE )
|
|
|
|
{
|
|
|
|
VIDEO_WaitVSync();
|
|
|
|
|
|
|
|
if ( shutdown == 1 )
|
|
|
|
Sys_Shutdown();
|
|
|
|
|
|
|
|
if ( reset == 1 )
|
|
|
|
Sys_Reboot();
|
|
|
|
|
|
|
|
for ( i = 0; i < FILEBROWSERSIZE; i++ )
|
|
|
|
{
|
|
|
|
if ( fileBrowser.fileList[i]->GetState() == STATE_CLICKED )
|
|
|
|
{
|
|
|
|
fileBrowser.fileList[i]->ResetState();
|
|
|
|
|
|
|
|
clickedIndex = browser->pageIndex + i;
|
|
|
|
bool pathCanged = false;
|
|
|
|
// check corresponding browser entry
|
|
|
|
if ( browser->browserList[clickedIndex].isdir )
|
|
|
|
{
|
|
|
|
/* go up to parent directory */
|
|
|
|
if ( strcmp( browser->browserList[clickedIndex].filename, ".." ) == 0 )
|
|
|
|
{
|
|
|
|
/* remove last subdirectory name */
|
|
|
|
int len = strlen( browser->dir );
|
|
|
|
while ( browser->dir[0] && browser->dir[len-1] == '/' )
|
|
|
|
browser->dir[--len] = '\0'; // remove all trailing '/'
|
|
|
|
char *cptr = strrchr( browser->dir, '/' );
|
|
|
|
if ( cptr ) *++cptr = 0; else browser->dir[0] = '\0'; // remove trailing dir
|
|
|
|
pathCanged = true;
|
|
|
|
}
|
|
|
|
/* Open a directory */
|
|
|
|
/* current directory doesn't change */
|
|
|
|
else if ( strcmp( browser->browserList[clickedIndex].filename, "." ) )
|
|
|
|
{
|
|
|
|
/* test new directory namelength */
|
|
|
|
if ( ( strlen( browser->dir ) + strlen( browser->browserList[clickedIndex].filename )
|
|
|
|
+ 1/*'/'*/ ) < MAXPATHLEN )
|
|
|
|
{
|
|
|
|
/* update current directory name */
|
|
|
|
sprintf( browser->dir, "%s%s/", browser->dir,
|
|
|
|
browser->browserList[clickedIndex].filename );
|
|
|
|
pathCanged = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( pathCanged )
|
|
|
|
{
|
|
|
|
LOCK( &fileBrowser );
|
|
|
|
ParseDirectory( ( char* )NULL, Flags, Filter );
|
|
|
|
fileBrowser.ResetState();
|
|
|
|
fileBrowser.TriggerUpdate();
|
|
|
|
AdressText.SetTextf( "%s%s", browser->rootdir, browser->dir );
|
|
|
|
}
|
|
|
|
clickedIndex = -1;
|
|
|
|
}
|
|
|
|
else /* isFile */
|
|
|
|
{
|
|
|
|
AdressText.SetTextf( "%s%s%s", browser->rootdir, browser->dir, browser->browserList[clickedIndex].filename );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ExitBtn.GetState() == STATE_CLICKED )
|
|
|
|
{
|
|
|
|
result = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if ( okBtn.GetState() == STATE_CLICKED )
|
|
|
|
{
|
|
|
|
if ( clickedIndex >= 0 )
|
|
|
|
snprintf( Path, Path_size, "%s%s%s", browser->rootdir, browser->dir, browser->browserList[clickedIndex].filename );
|
|
|
|
else
|
|
|
|
snprintf( Path, Path_size, "%s%s", browser->rootdir, browser->dir );
|
|
|
|
result = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if ( usbBtn.GetState() == STATE_CLICKED )
|
|
|
|
{
|
|
|
|
usbBtn.ResetState();
|
|
|
|
for ( u32 i = 1; i < browsers.size(); i++ )
|
|
|
|
{
|
|
|
|
LOCK( &fileBrowser );
|
|
|
|
if ( ParseDirectory( ( curDevice + i ) % browsers.size(), Flags, Filter ) == 0 )
|
|
|
|
{
|
|
|
|
fileBrowser.ResetState();
|
|
|
|
fileBrowser.TriggerUpdate();
|
|
|
|
AdressText.SetTextf( "%s%s", browser->rootdir, browser->dir );
|
|
|
|
usbBtnTxt.SetText( browsers[( curDevice+1 )%browsers.size()].rootdir );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( folderBtn.GetState() == STATE_CLICKED )
|
|
|
|
{
|
|
|
|
folderBtn.ResetState();
|
|
|
|
|
|
|
|
HaltGui();
|
|
|
|
mainWindow->Remove( &w );
|
|
|
|
ResumeGui();
|
|
|
|
char newfolder[100];
|
|
|
|
char oldfolder[100];
|
|
|
|
snprintf( newfolder, sizeof( newfolder ), "%s%s", browser->rootdir, browser->dir );
|
|
|
|
strcpy( oldfolder, newfolder );
|
|
|
|
|
|
|
|
int result = OnScreenKeyboard( newfolder, sizeof( newfolder ), strlen( browser->rootdir ) );
|
|
|
|
if ( result == 1 )
|
|
|
|
{
|
|
|
|
unsigned int len = strlen( newfolder );
|
|
|
|
if ( len > 0 && len + 1 < sizeof( newfolder ) && newfolder[len-1] != '/' )
|
|
|
|
{
|
|
|
|
newfolder[len] = '/';
|
|
|
|
newfolder[len+1] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
struct stat st;
|
|
|
|
if ( stat( newfolder, &st ) != 0 )
|
|
|
|
{
|
|
|
|
if ( WindowPrompt( tr( "Directory does not exist!" ), tr( "The entered directory does not exist. Would you like to create it?" ) , tr( "OK" ), tr( "Cancel" ) ) == 1 )
|
|
|
|
if ( subfoldercreate( newfolder ) == false )
|
|
|
|
WindowPrompt( tr( "Error !" ), tr( "Can't create directory" ), tr( "OK" ) );
|
|
|
|
}
|
|
|
|
if ( ParseDirectory( newfolder, Flags, Filter ) == 0 )
|
|
|
|
{
|
|
|
|
fileBrowser.ResetState();
|
|
|
|
fileBrowser.TriggerUpdate();
|
|
|
|
AdressText.SetTextf( "%s%s", browser->rootdir, browser->dir );
|
|
|
|
usbBtnTxt.SetText( browsers[( curDevice+1 )%browsers.size()].rootdir );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
HaltGui();
|
|
|
|
mainWindow->Append( &w );
|
|
|
|
ResumeGui();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
HaltGui();
|
|
|
|
mainWindow->Remove( &w );
|
|
|
|
ResumeGui();
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
return result;
|
2009-10-01 01:10:58 +02:00
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
int BrowseDevice( char * Path, int Path_size, int Flags, FILEFILTERCALLBACK Filter, void *FilterArgs )
|
2010-02-09 11:59:55 +01:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( Filter )
|
|
|
|
{
|
|
|
|
FILTERCASCADE filter = {Filter, FilterArgs, NULL};
|
|
|
|
return BrowseDevice( Path, Path_size, Flags, &filter );
|
|
|
|
}
|
|
|
|
return BrowseDevice( Path, Path_size, Flags );
|
2009-10-05 12:53:19 +02:00
|
|
|
}
|