2013-02-21 00:52:52 +00:00
/ * RetroArch - A frontend for libretro .
* Copyright ( C ) 2013 - Jason Fetters
*
* RetroArch is free software : you can redistribute it and / or modify it under the terms
* of the GNU General Public License as published by the Free Software Found -
* ation , either version 3 of the License , or ( at your option ) any later version .
*
* RetroArch is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE . See the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along with RetroArch .
* If not , see < http : // www . gnu . org / licenses / > .
* /
2013-02-21 04:30:56 +00:00
# include < dirent . h >
# include < sys / stat . h >
2013-06-14 04:45:35 +00:00
2013-09-05 05:20:56 +00:00
# import "apple/common/RetroArch_Apple.h"
2013-06-14 04:45:35 +00:00
# import "views.h"
2013-06-10 00:13:05 +00:00
# include "conf/config_file.h"
2013-06-14 04:45:35 +00:00
# include "file.h"
2013-02-21 04:30:56 +00:00
2013-06-10 00:13:05 +00:00
@ implementation RADirectoryItem
@ end
2013-02-21 00:45:51 +00:00
2013-06-06 03:12:22 +00:00
@ implementation RADirectoryList
2013-02-21 00:45:51 +00:00
{
2013-06-12 23:47:24 +00:00
NSString * _path ;
2013-06-14 04:45:35 +00:00
NSMutableArray * _sectionNames ;
2013-08-25 00:27:04 +00:00
id < RADirectoryListDelegate > _delegate ;
2013-02-21 00:45:51 +00:00
}
2013-04-04 05:54:33 +00:00
2013-08-25 00:27:04 +00:00
- ( id ) initWithPath : ( NSString * ) path delegate : ( id < RADirectoryListDelegate > ) delegate
2013-04-04 05:54:33 +00:00
{
2013-06-12 23:47:24 +00:00
_path = path ;
2013-08-25 00:27:04 +00:00
_delegate = delegate ;
2013-06-12 23:47:24 +00:00
2013-04-04 05:54:33 +00:00
self = [ super initWithStyle : UITableViewStylePlain ] ;
2013-06-14 04:45:35 +00:00
self . title = path . lastPathComponent ;
self . hidesHeaders = YES ;
2013-07-13 03:05:21 +00:00
2013-08-25 00:27:04 +00:00
NSMutableArray * toolbarButtons = [ [ NSMutableArray alloc ] initWithCapacity : 3 ] ;
2013-07-13 03:05:21 +00:00
2013-08-25 00:27:04 +00:00
UIBarButtonItem * refreshButton = [ [ UIBarButtonItem alloc ] initWithBarButtonSystemItem : UIBarButtonSystemItemRefresh target : self action : @ selector ( refresh ) ] ;
refreshButton . style = UIBarButtonItemStyleBordered ;
[ toolbarButtons addObject : refreshButton ] ;
2013-07-13 03:05:21 +00:00
2013-08-25 00:27:04 +00:00
UIBarButtonItem * flexibleSpace = [ [ UIBarButtonItem alloc ] initWithBarButtonSystemItem : UIBarButtonSystemItemFlexibleSpace target : self action : nil ] ;
[ toolbarButtons addObject : flexibleSpace ] ;
2013-07-13 03:05:21 +00:00
2013-08-25 00:27:04 +00:00
UIBarButtonItem * newFolderButton = [ [ UIBarButtonItem alloc ] initWithTitle : @ "New Folder" style : UIBarButtonItemStyleBordered target : self action : @ selector ( createNewFolder ) ] ;
[ toolbarButtons addObject : newFolderButton ] ;
2013-07-13 03:05:21 +00:00
2013-08-25 00:27:04 +00:00
[ [ [ RetroArch_iOS get ] toolbar ] setItems : toolbarButtons ] ;
[ self setToolbarItems : toolbarButtons ] ;
2013-04-04 05:54:33 +00:00
2013-06-13 00:00:25 +00:00
return self ;
}
2013-08-25 00:36:03 +00:00
- ( void ) viewWillAppear : ( BOOL ) animated
{
[ self refresh ] ;
}
- ( void ) viewDidDisappear : ( BOOL ) animated
{
[ self reset ] ;
}
2013-06-13 00:00:25 +00:00
- ( void ) refresh
{
2013-06-14 04:45:35 +00:00
static const char sectionNames [ 28 ] = { ' / ' , ' # ' , ' A ' , ' B ' , ' C ' , ' D ' , ' E ' , ' F ' , ' G ' , ' H ' , ' I ' , ' J ' , ' K ' , ' L ' ,
' M ' , ' N ' , ' O ' , ' P ' , ' Q ' , ' R ' , ' S ' , ' T ' , ' U ' , ' V ' , ' W ' , ' X ' , ' Y ' , ' Z ' } ;
static const uint32_t sectionCount = sizeof ( sectionNames ) / sizeof ( sectionNames [ 0 ] ) ;
2013-06-14 17:11:59 +00:00
self . sections = [ NSMutableArray array ] ;
2013-06-14 04:45:35 +00:00
2013-06-10 00:13:05 +00:00
// Need one array per section
2013-06-14 04:45:35 +00:00
NSMutableArray * sectionLists [ sectionCount ] ;
for ( int i = 0 ; i ! = sectionCount ; i + + )
sectionLists [ i ] = [ NSMutableArray arrayWithObject : [ NSString stringWithFormat : @ "%c" , sectionNames [ i ] ] ] ;
2013-06-10 00:13:05 +00:00
// List contents
2013-06-13 00:00:25 +00:00
struct string_list * contents = dir_list _new ( _path . UTF8String , 0 , true ) ;
2013-06-10 00:13:05 +00:00
if ( contents )
2013-06-06 03:12:22 +00:00
{
2013-06-10 00:13:05 +00:00
dir_list _sort ( contents , true ) ;
for ( int i = 0 ; i < contents -> size ; i + + )
{
const char * basename = path_basename ( contents -> elems [ i ] . data ) ;
if ( basename [ 0 ] = = ' . ' )
continue ;
uint32_t section = isalpha ( basename [ 0 ] ) ? ( toupper ( basename [ 0 ] ) - ' A ' ) + 2 : 1 ;
section = contents -> elems [ i ] . attr . b ? 0 : section ;
2013-06-14 04:45:35 +00:00
2013-06-10 00:13:05 +00:00
RADirectoryItem * item = RADirectoryItem . new ;
2013-09-09 23:25:34 +00:00
item . path = @ ( contents -> elems [ i ] . data ) ;
2013-06-10 00:13:05 +00:00
item . isDirectory = contents -> elems [ i ] . attr . b ;
2013-06-14 04:45:35 +00:00
[ sectionLists [ section ] addObject : item ] ;
2013-06-10 00:13:05 +00:00
}
dir_list _free ( contents ) ;
2013-06-14 04:45:35 +00:00
// Add the sections
_sectionNames = [ NSMutableArray array ] ;
for ( int i = 0 ; i ! = sectionCount ; i + + )
{
[ self . sections addObject : sectionLists [ i ] ] ;
[ _sectionNames addObject : sectionLists [ i ] [ 0 ] ] ;
}
2013-06-06 03:12:22 +00:00
}
else
2013-07-06 22:24:25 +00:00
apple_display _alert ( [ NSString stringWithFormat : @ "Browsed path is not a directory: %@" , _path ] , 0 ) ;
2013-04-04 05:54:33 +00:00
2013-06-13 00:00:25 +00:00
[ self . tableView reloadData ] ;
2013-04-04 05:54:33 +00:00
}
- ( void ) tableView : ( UITableView * ) tableView didSelectRowAtIndexPath : ( NSIndexPath * ) indexPath
{
2013-08-25 00:27:04 +00:00
[ _delegate directoryList : self itemWasSelected : [ self itemForIndexPath : indexPath ] ] ;
2013-04-04 05:54:33 +00:00
}
- ( UITableViewCell * ) tableView : ( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) indexPath
{
2013-08-25 00:36:03 +00:00
static NSString * const cell_types [ 2 ] = { @ "file" , @ "folder" } ;
static NSString * const icon_types [ 2 ] = { @ "ic_file" , @ "ic_dir" } ;
static const UITableViewCellAccessoryType accessory_types [ 2 ] = { UITableViewCellAccessoryDetailDisclosureButton ,
UITableViewCellAccessoryDisclosureIndicator } ;
RADirectoryItem * path = [ self itemForIndexPath : indexPath ] ;
uint32_t type_id = path . isDirectory ? 1 : 0 ;
UITableViewCell * cell = [ self . tableView dequeueReusableCellWithIdentifier : cell_types [ type_id ] ] ;
if ( ! cell )
{
cell = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier : cell_types [ type_id ] ] ;
cell . imageView . image = [ UIImage imageNamed : icon_types [ type_id ] ] ;
cell . accessoryType = accessory_types [ type_id ] ;
2013-07-09 02:13:20 +00:00
}
2013-08-25 00:36:03 +00:00
cell . textLabel . text = [ path . path lastPathComponent ] ;
2013-07-09 02:13:20 +00:00
2013-04-04 05:54:33 +00:00
return cell ;
}
2013-07-12 02:40:40 +00:00
- ( void ) tableView : ( UITableView * ) tableView accessoryButtonTappedForRowWithIndexPath : ( NSIndexPath * ) indexPath {
self . selectedItem = [ self itemForIndexPath : indexPath ] ;
UITableViewCell * cell = [ tableView cellForRowAtIndexPath : indexPath ] ;
UIActionSheet * menu = [ [ UIActionSheet alloc ] initWithTitle : cell . textLabel . text delegate : self cancelButtonTitle : @ "Cancel" destructiveButtonTitle : nil otherButtonTitles : @ "Move" , nil ] ;
[ menu showInView : [ self view ] ] ;
}
- ( void ) actionSheet : ( UIActionSheet * ) actionSheet clickedButtonAtIndex : ( NSInteger ) buttonIndex {
if ( buttonIndex = = 0 ) {
RAFoldersList * foldersListViewController = [ [ RAFoldersList alloc ] initWithFilePath : self . selectedItem . path ] ;
UINavigationController * navigationController = [ [ UINavigationController alloc ] initWithRootViewController : foldersListViewController ] ;
[ self presentViewController : navigationController animated : YES completion : nil ] ;
}
}
2013-05-30 23:25:42 +00:00
- ( NSArray * ) sectionIndexTitlesForTableView : ( UITableView * ) tableView
2013-04-04 05:54:33 +00:00
{
2013-06-14 04:45:35 +00:00
return _sectionNames ;
}
2013-07-09 02:55:55 +00:00
- ( void ) tableView : ( UITableView * ) tableView commitEditingStyle : ( UITableViewCellEditingStyle ) editingStyle forRowAtIndexPath : ( NSIndexPath * ) indexPath {
if ( editingStyle = = UITableViewCellEditingStyleDelete ) {
NSFileManager * fileManager = [ NSFileManager defaultManager ] ;
RADirectoryItem * path = ( RADirectoryItem * ) [ self itemForIndexPath : indexPath ] ;
BOOL didRemoveItem = [ fileManager removeItemAtPath : path . path error : nil ] ;
if ( didRemoveItem ) {
[ self refresh ] ;
} else {
2013-07-12 02:40:40 +00:00
apple_display _alert ( @ "It was not possible to delete file." , 0 ) ;
2013-07-09 02:55:55 +00:00
}
}
}
2013-07-09 19:51:02 +00:00
- ( void ) createNewFolder {
UIAlertView * alertView = [ [ UIAlertView alloc ] initWithTitle : @ "Enter new folder name" message : @ "" delegate : self cancelButtonTitle : @ "Cancel" otherButtonTitles : @ "OK" , nil ] ;
alertView . alertViewStyle = UIAlertViewStylePlainTextInput ;
[ alertView show ] ;
}
- ( void ) alertView : ( UIAlertView * ) alertView clickedButtonAtIndex : ( NSInteger ) buttonIndex {
NSString * text = [ [ alertView textFieldAtIndex : 0 ] text ] ;
if ( buttonIndex = = 1 && ! [ text isEqualToString : @ "" ] ) {
NSString * directoryPath = [ _path stringByAppendingPathComponent : text ] ;
BOOL didCreateFolder = [ [ NSFileManager defaultManager ] createDirectoryAtPath : directoryPath withIntermediateDirectories : YES attributes : nil error : nil ] ;
if ( didCreateFolder ) {
[ self refresh ] ;
} else {
2013-07-12 02:40:40 +00:00
apple_display _alert ( @ "It was not possible to create folder." , 0 ) ;
2013-07-09 19:51:02 +00:00
}
}
}
2013-06-14 04:45:35 +00:00
@ end
@ implementation RAModuleList
{
2013-08-25 00:27:04 +00:00
id < RAModuleListDelegate > _delegate ;
2013-06-14 04:45:35 +00:00
}
2013-08-25 00:27:04 +00:00
- ( id ) initWithGame : ( NSString * ) path delegate : ( id < RAModuleListDelegate > ) delegate
2013-06-14 04:45:35 +00:00
{
self = [ super initWithStyle : UITableViewStyleGrouped ] ;
2013-08-25 00:27:04 +00:00
[ self setTitle : path ? [ path lastPathComponent ] : @ "Cores" ] ;
_delegate = delegate ;
2013-06-14 04:45:35 +00:00
// Load the modules with their data
2013-09-09 23:25:34 +00:00
NSArray * moduleList = apple_get _modules ( ) ;
2013-06-14 04:45:35 +00:00
NSMutableArray * supported = [ NSMutableArray arrayWithObject : @ "Suggested Cores" ] ;
NSMutableArray * other = [ NSMutableArray arrayWithObject : @ "Other Cores" ] ;
for ( RAModuleInfo * i in moduleList )
{
2013-08-25 00:27:04 +00:00
if ( path && [ i supportsFileAtPath : path ] ) [ supported addObject : i ] ;
else [ other addObject : i ] ;
2013-06-14 04:45:35 +00:00
}
if ( supported . count > 1 )
[ self . sections addObject : supported ] ;
if ( other . count > 1 )
[ self . sections addObject : other ] ;
return self ;
}
- ( void ) tableView : ( UITableView * ) tableView didSelectRowAtIndexPath : ( NSIndexPath * ) indexPath
{
2013-08-25 00:27:04 +00:00
[ _delegate moduleList : self itemWasSelected : [ self itemForIndexPath : indexPath ] ] ;
2013-06-14 04:45:35 +00:00
}
- ( void ) infoButtonTapped : ( id ) sender
{
RAModuleInfo * info = objc_getAssociatedObject ( sender , "MODULE" ) ;
if ( info && info . data )
[ RetroArch_iOS . get pushViewController : [ [ RAModuleInfoList alloc ] initWithModuleInfo : info ] animated : YES ] ;
else
2013-07-06 22:24:25 +00:00
apple_display _alert ( @ "No information available." , 0 ) ;
2013-06-14 04:45:35 +00:00
}
- ( UITableViewCell * ) tableView : ( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) indexPath
{
UITableViewCell * cell = [ self . tableView dequeueReusableCellWithIdentifier : @ "module" ] ;
if ( ! cell )
{
cell = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier : @ "module" ] ;
UIButton * infoButton = [ UIButton buttonWithType : UIButtonTypeInfoDark ] ;
[ infoButton addTarget : self action : @ selector ( infoButtonTapped : ) forControlEvents : UIControlEventTouchUpInside ] ;
cell . accessoryView = infoButton ;
}
RAModuleInfo * info = ( RAModuleInfo * ) [ self itemForIndexPath : indexPath ] ;
2013-07-07 23:22:36 +00:00
cell . textLabel . text = info . description ;
2013-06-14 04:45:35 +00:00
objc_setAssociatedObject ( cell . accessoryView , "MODULE" , info , OBJC_ASSOCIATION _RETAIN _NONATOMIC ) ;
return cell ;
2013-04-04 05:54:33 +00:00
}
2013-07-12 02:40:40 +00:00
@ end
@ implementation RAFoldersList {
NSMutableArray * directories ;
NSString * currentDirectoryPath , * selectedFilePath , * fileName ;
}
- ( id ) initWithFilePath : ( NSString * ) path
{
self = [ super initWithStyle : UITableViewStyleGrouped ] ;
selectedFilePath = path ;
NSFileManager * fileManager = [ NSFileManager defaultManager ] ;
fileName = [ fileManager displayNameAtPath : path ] ;
currentDirectoryPath = [ path stringByDeletingLastPathComponent ] ;
NSArray * files = [ fileManager contentsOfDirectoryAtPath : currentDirectoryPath error : nil ] ;
directories = [ [ NSMutableArray alloc ] init ] ;
for ( int i = 0 ; i < files . count ; i + + ) {
NSString * filePath = [ currentDirectoryPath stringByAppendingPathComponent : files [ i ] ] ;
BOOL isDir ;
if ( [ fileManager fileExistsAtPath : filePath isDirectory : & isDir ] && isDir ) {
[ directories addObject : files [ i ] ] ;
}
}
[ self setTitle : [ @ "Move " stringByAppendingString : fileName ] ] ;
return self ;
}
- ( void ) viewDidLoad
{
[ super viewDidLoad ] ;
self . navigationItem . leftBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : @ "Cancel" style : UIBarButtonItemStyleBordered target : self action : @ selector ( dismissViewController ) ] ;
}
- ( void ) dismissViewController
{
[ self dismissViewControllerAnimated : YES completion : nil ] ;
}
- ( NSInteger ) numberOfSectionsInTableView : ( UITableView * ) tableView
{
return 1 ;
}
- ( NSInteger ) tableView : ( UITableView * ) tableView numberOfRowsInSection : ( NSInteger ) section
{
return directories . count ;
}
- ( UITableViewCell * ) tableView : ( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) indexPath
{
static NSString * CellIdentifier = @ "Directory" ;
UITableViewCell * cell = [ tableView dequeueReusableCellWithIdentifier : CellIdentifier ] ;
if ( cell = = nil ) {
cell = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleDefault reuseIdentifier : CellIdentifier ] ;
}
cell . textLabel . text = directories [ indexPath . row ] ;
return cell ;
}
- ( void ) tableView : ( UITableView * ) tableView didSelectRowAtIndexPath : ( NSIndexPath * ) indexPath
{
UITableViewCell * cell = [ tableView cellForRowAtIndexPath : indexPath ] ;
NSString * directoryPath = [ currentDirectoryPath stringByAppendingPathComponent : cell . textLabel . text ] ;
NSString * newPath = [ directoryPath stringByAppendingPathComponent : fileName ] ;
2013-08-25 00:36:03 +00:00
if ( ! [ [ NSFileManager defaultManager ] moveItemAtPath : selectedFilePath toPath : newPath error : nil ] )
2013-07-12 02:40:40 +00:00
apple_display _alert ( @ "It was not possible to move the file" , 0 ) ;
[ self dismissViewController ] ;
}
2013-04-04 05:54:33 +00:00
@ end