(Cocoa) Remove unused cocoa_settings.m and cocoatouch_browser.m

This commit is contained in:
twinaphex 2015-08-13 21:34:53 +02:00
parent f373527856
commit 4ae73d2a1b
2 changed files with 0 additions and 969 deletions

View File

@ -1,386 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2013-2014 - Jason Fetters
* Copyright (C) 2011-2015 - Daniel De Matteis
*
* 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/>.
*/
#import <objc/runtime.h>
#include <compat/apple_compat.h>
#include <retro_miscellaneous.h>
#include "cocoa_common.h"
#include "../../../menu/menu_setting.h"
#include "../../../input/drivers/cocoa_input.h"
#include "../../../driver.h"
#include "../../../input/input_common.h"
#include "../../../input/input_keymaps.h"
static void* const associated_name_tag = (void*)&associated_name_tag;
@interface RAInputBinder : NSWindow
{
#if !__OBJC2__
NSTimer* _timer;
const rarch_setting_t *_setting;
#endif
}
@property (nonatomic, retain) NSTimer* timer;
@property (nonatomic, assign) const rarch_setting_t* setting;
@end
@implementation RAInputBinder
@synthesize timer = _timer;
@synthesize setting = _setting;
- (void)dealloc
{
[_timer release];
[super dealloc];
}
- (void)runForSetting:(const rarch_setting_t*)setting onWindow:(NSWindow*)window
{
self.setting = setting;
self.timer = [NSTimer timerWithTimeInterval:.1f target:self selector:@selector(checkBind:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSModalPanelRunLoopMode];
[NSApp beginSheet:self modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil];
}
- (IBAction)goAway:(id)sender
{
[self.timer invalidate];
self.timer = nil;
[NSApp endSheet:self];
[self orderOut:nil];
}
- (void)checkBind:(NSTimer*)send
{
int32_t value = 0;
int32_t idx = 0;
if (self.setting->index)
idx = self.setting->index - 1;
if ((value = cocoa_input_find_any_key()))
BINDFOR(*[self setting]).key = input_keymaps_translate_keysym_to_rk(value);
else if ((value = cocoa_input_find_any_button(idx)) >= 0)
BINDFOR(*[self setting]).joykey = value;
else if ((value = cocoa_input_find_any_axis(idx)))
BINDFOR(*[self setting]).joyaxis = (value > 0) ? AXIS_POS(value - 1) : AXIS_NEG(abs(value) - 1);
else
return;
[self goAway:self];
}
// Stop the annoying sound when pressing a key
- (void)keyDown:(NSEvent*)theEvent
{
}
@end
@interface RASettingsDelegate : NSObject
#ifdef MAC_OS_X_VERSION_10_6
<NSTableViewDataSource, NSTableViewDelegate,
NSOutlineViewDataSource, NSOutlineViewDelegate,
NSWindowDelegate>
#endif
{
#if !__OBJC2__
RAInputBinder* _binderWindow;
NSButtonCell* _booleanCell;
NSTextFieldCell* _binderCell;
NSTableView* _table;
NSOutlineView* _outline;
NSMutableArray* _settings;
NSMutableArray* _currentGroup;
#endif
}
@property (nonatomic, retain) RAInputBinder IBOutlet* binderWindow;
@property (nonatomic, retain) NSButtonCell IBOutlet* booleanCell;
@property (nonatomic, retain) NSTextFieldCell IBOutlet* binderCell;
@property (nonatomic, retain) NSTableView IBOutlet* table;
@property (nonatomic, retain) NSOutlineView IBOutlet* outline;
@property (nonatomic, retain) NSMutableArray* settings;
@property (nonatomic, retain) NSMutableArray* currentGroup;
@end
@implementation RASettingsDelegate
@synthesize binderWindow = _binderWindow;
@synthesize booleanCell = _booleanCell;
@synthesize binderCell = _binderCell;
@synthesize table = _table;
@synthesize outline = _outline;
@synthesize settings = _settings;
@synthesize currentGroup = _currentGroup;
- (void)dealloc
{
[_binderWindow release];
[_booleanCell release];
[_binderCell release];
[_table release];
[_outline release];
[_settings release];
[_currentGroup release];
[super dealloc];
}
- (void)awakeFromNib
{
int i;
NSMutableArray* thisGroup = nil;
NSMutableArray* thisSubGroup = nil;
driver_t *driver = driver_get_ptr();
const rarch_setting_t *setting_data = (const rarch_setting_t *)driver->menu->list_settings;
self.settings = [NSMutableArray array];
for (i = 0; setting_data[i].type; i ++)
{
switch (setting_data[i].type)
{
case ST_GROUP:
{
thisGroup = [NSMutableArray array];
#if defined(MAC_OS_X_VERSION_10_6)
/* FIXME - Rewrite this so that this is no longer an associated object - requires ObjC 2.0 runtime */
objc_setAssociatedObject(thisGroup, associated_name_tag, BOXSTRING(setting_data[i].name), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
#endif
break;
}
case ST_END_GROUP:
{
if (thisGroup)
[self.settings addObject:thisGroup];
thisGroup = nil;
break;
}
case ST_SUB_GROUP:
{
thisSubGroup = [NSMutableArray array];
#if defined(MAC_OS_X_VERSION_10_6)
/* FIXME - Rewrite this so that this is no longer an associated object - requires ObjC 2.0 runtime */
objc_setAssociatedObject(thisSubGroup, associated_name_tag, BOXSTRING(setting_data[i].name), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
#endif
break;
}
case ST_END_SUB_GROUP:
{
if (thisSubGroup)
[thisGroup addObject:thisSubGroup];
thisSubGroup = nil;
break;
}
default:
{
[thisSubGroup addObject:[NSNumber numberWithInt:i]];
break;
}
}
}
}
- (void)windowWillClose:(NSNotification *)notification
{
[NSApp stopModal];
}
#pragma mark Section Table
- (NSInteger)numberOfRowsInTableView:(NSTableView*)view
{
return self.settings.count;
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
#if defined(MAC_OS_X_VERSION_10_6)
return objc_getAssociatedObject([self.settings objectAtIndex:row], associated_name_tag);
#else
/* FIXME - Rewrite this so that this is no longer an associated object - requires ObjC 2.0 runtime */
return 0; /* stub */
#endif
}
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
{
self.currentGroup = [self.settings objectAtIndex:[self.table selectedRow]];
[self.outline reloadData];
}
#pragma mark Setting Outline
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
return (item == nil) ? [self.currentGroup count] : [item count];
}
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)idx ofItem:(id)item
{
return (item == nil) ? [self.currentGroup objectAtIndex:idx] : [item objectAtIndex:idx];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
return [item isKindOfClass:[NSArray class]];
}
- (BOOL)validateProposedFirstResponder:(NSResponder*)responder forEvent:(NSEvent*)event
{
return YES;
}
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
driver_t *driver = driver_get_ptr();
if (!tableColumn)
return nil;
if ([item isKindOfClass:[NSArray class]])
{
#ifdef MAC_OS_X_VERSION_10_6
/* FIXME - Rewrite this so that this is no longer an associated object - requires ObjC 2.0 runtime */
if ([[tableColumn identifier] isEqualToString:BOXSTRING("left")])
return objc_getAssociatedObject(item, associated_name_tag);
#endif
return BOXSTRING("");
}
else
{
char buffer[PATH_MAX_LENGTH];
rarch_setting_t *setting_data = (rarch_setting_t*)driver->menu->list_settings;
rarch_setting_t *setting = (rarch_setting_t*)&setting_data[[item intValue]];
if ([[tableColumn identifier] isEqualToString:BOXSTRING("left")])
return BOXSTRING(setting->short_description);
switch (setting->type)
{
case ST_BOOL:
return BOXINT(*setting->value.boolean);
default:
{
setting_get_string_representation(setting, buffer, sizeof(buffer));
if (buffer[0] == '\0')
strlcpy(buffer, "N/A", sizeof(buffer));
return BOXSTRING(buffer);
}
}
}
}
- (NSCell*)outlineView:(NSOutlineView *)outlineView dataCellForTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
const rarch_setting_t *setting_data, *setting;
driver_t *driver = driver_get_ptr();
if (!tableColumn)
return nil;
if ([item isKindOfClass:[NSArray class]])
return [tableColumn dataCell];
if ([[tableColumn identifier] isEqualToString:BOXSTRING("left")])
return [tableColumn dataCell];
setting_data = (const rarch_setting_t *)driver->menu->list_settings;
setting = (const rarch_setting_t *)&setting_data[[item intValue]];
switch (setting->type)
{
case ST_BOOL:
return self.booleanCell;
case ST_BIND:
return self.binderCell;
default:
break;
}
return tableColumn.dataCell;
}
- (IBAction)outlineViewClicked:(id)sender
{
id item;
driver_t *driver = driver_get_ptr();
if ([self.outline clickedColumn] != 1)
return;
item = [self.outline itemAtRow:[self.outline clickedRow]];
if (![item isKindOfClass:[NSNumber class]])
return;
{
rarch_setting_t *setting_data = (rarch_setting_t*)driver->menu->list_settings;
rarch_setting_t *setting = (rarch_setting_t*)&setting_data[[item intValue]];
switch (setting->type)
{
case ST_BOOL:
*setting->value.boolean = !*setting->value.boolean;
break;
case ST_BIND:
[self.binderWindow runForSetting:setting onWindow:[self.outline window]];
break;
default:
break;
}
if (setting->change_handler)
setting->change_handler(setting);
}
}
- (void)controlTextDidEndEditing:(NSNotification*)notification
{
id item;
NSText* editor = NULL;
driver_t *driver = driver_get_ptr();
if ([notification object] != self.outline)
return;
editor = [[notification userInfo] objectForKey:BOXSTRING("NSFieldEditor")];
item = [self.outline itemAtRow:[self.outline selectedRow]];
if (![item isKindOfClass:[NSNumber class]])
return;
{
rarch_setting_t *setting_data = (rarch_setting_t *)driver->menu->list_settings;
rarch_setting_t *setting = (rarch_setting_t*)&setting_data[[item intValue]];
NSString *editor_string = (NSString*)editor.string;
setting_set_with_string_representation(setting, editor_string.UTF8String);
}
}
@end

View File

@ -1,583 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2013-2014 - Jason Fetters
* Copyright (C) 2014-2015 - Jay McCarthy
*
* 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/>.
*/
#include <file/file_extract.h>
#include <file/dir_list.h>
#include <file/file_path.h>
#include <retro_miscellaneous.h>
#include <rhash.h>
#include "cocoa_common.h"
#include "../../../content.h"
#include "../../../general.h"
enum file_action
{
FA_DELETE = 10000,
FA_CREATE,
FA_MOVE,
FA_UNZIP
};
static const void* const associated_module_key = &associated_module_key;
static int zlib_extract_callback(const char *name, const char *valid_exts,
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
uint32_t crc32, void *userdata)
{
char path[PATH_MAX_LENGTH];
/* Make directory */
fill_pathname_join(path, (const char*)userdata, name, sizeof(path));
path_basedir(path);
if (!path_mkdir(path))
{
RARCH_ERR("Failed to create dir: %s.\n", path);
return false;
}
/* Ignore directories */
if (name[strlen(name) - 1] == '/')
return 1;
fill_pathname_join(path, (const char*)userdata, name, sizeof(path));
if (!zlib_perform_mode(path, valid_exts,
cdata, cmode, csize, size, crc32, userdata))
{
if (cmode == 0)
{
RARCH_ERR("Failed to write file: %s.\n", path);
return 0;
}
goto error;
}
return 1;
error:
RARCH_ERR("Failed to deflate to: %s.\n", path);
return 0;
}
static void unzip_file(const char* path, const char* output_directory)
{
if (!path_file_exists(path))
apple_display_alert("Could not locate zip file.", "Action Failed");
else if (path_is_directory(output_directory))
apple_display_alert("Output directory for zip must not already exist.", "Action Failed");
else if (!path_mkdir(output_directory))
apple_display_alert("Could not create output directory to extract zip.", "Action Failed");
else if (!zlib_parse_file(path, NULL, zlib_extract_callback, (void*)output_directory))
apple_display_alert("Could not process zip file.", "Action Failed");
}
static void file_action(enum file_action action, NSString* source, NSString* target)
{
NSError* error = nil;
bool result = false;
NSFileManager* manager = [NSFileManager defaultManager];
switch (action)
{
case FA_DELETE:
result = [manager removeItemAtPath:target error:&error];
break;
case FA_CREATE:
result = [manager createDirectoryAtPath:target withIntermediateDirectories:YES
attributes:nil error:&error];
break;
case FA_MOVE:
result = [manager moveItemAtPath:source toPath:target error:&error];
break;
case FA_UNZIP:
unzip_file(source.UTF8String, target.UTF8String);
break;
}
if (!result && error)
apple_display_alert(error.localizedDescription.UTF8String, "Action failed");
}
@implementation RADirectoryItem
+ (RADirectoryItem*)directoryItemFromPath:(NSString*)path
{
RADirectoryItem* item = [RADirectoryItem new];
if (!item)
return NULL;
item.path = path;
item.isDirectory = path_is_directory(path.UTF8String);
return item;
}
+ (RADirectoryItem*)directoryItemFromElement:(struct string_list_elem*)element
{
RADirectoryItem* item = [RADirectoryItem new];
if (!item)
return NULL;
item.path = BOXSTRING(element->data);
item.isDirectory = (element->attr.i == RARCH_DIRECTORY);
return item;
}
- (UITableViewCell*)cellForTableView:(UITableView *)tableView
{
static NSString* const cell_id = @"path_item";
static NSString* const icon_types[2] = { @"ic_file", @"ic_dir" };
uint32_t type_id = self.isDirectory ? 1 : 0;
UITableViewCell *result = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (!result)
result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_id];
result.textLabel.text = [self.path lastPathComponent];
result.imageView.image = [UIImage imageNamed:icon_types[type_id]];
return result;
}
- (void)wasSelectedOnTableView:(UITableView *)tableView ofController:(UIViewController *)controller
{
if (self.isDirectory)
[(id)controller browseTo:self.path];
else
[(id)controller chooseAction]((id)controller, self);
}
@end
/*********************************************/
/* RAMenuItemBasic */
/* A simple menu item that displays a text */
/* description and calls a block object when */
/* selected. */
/*********************************************/
@interface RAMenuItemBasic : NSObject
@property (nonatomic) NSString* description;
@property (nonatomic) id userdata;
@property (copy) void (^action)(id userdata);
@property (copy) NSString* (^detail)(id userdata);
+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action;
+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action detail:(NSString* (^)())detail;
+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description association:(id)userdata action:(void (^)())action detail:(NSString* (^)())detail;
@end
/*********************************************/
/* RAMenuItemBasic */
/* A simple menu item that displays a text */
/* description and calls a block object when */
/* selected. */
/*********************************************/
@implementation RAMenuItemBasic
@synthesize description;
@synthesize userdata;
@synthesize action;
@synthesize detail;
+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action
{
return [self itemWithDescription:description action:action detail:Nil];
}
+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action detail:(NSString* (^)())detail
{
return [self itemWithDescription:description association:nil action:action detail:detail];
}
+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description association:(id)userdata action:(void (^)())action detail:(NSString* (^)())detail
{
RAMenuItemBasic* item = [RAMenuItemBasic new];
item.description = description;
item.userdata = userdata;
item.action = action;
item.detail = detail;
return item;
}
- (UITableViewCell*)cellForTableView:(UITableView*)tableView
{
static NSString* const cell_id = @"text";
UITableViewCell* result = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (!result)
result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cell_id];
result.selectionStyle = UITableViewCellSelectionStyleNone;
result.textLabel.text = self.description;
result.detailTextLabel.text = self.detail ? self.detail(self.userdata) : nil;
return result;
}
- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller
{
if (self.action)
self.action(self.userdata);
}
@end
@implementation RADirectoryList
- (id)initWithPath:(NSString*)path extensions:(const char*)extensions
action:(void (^)(RADirectoryList* list, RADirectoryItem* item))action
{
if ((self = [super initWithStyle:UITableViewStylePlain]))
{
NSMutableArray *toolbarButtons;
self.path = path ? path : NSHomeDirectory();
self.chooseAction = action;
self.extensions = extensions ? BOXSTRING(extensions) : 0;
self.hidesHeaders = YES;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:BOXSTRING("Up") style:UIBarButtonItemStyleBordered target:self
action:@selector(gotoParent)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self
action:@selector(cancelBrowser)];
/* NOTE: The "App" and "Root" buttons aren't really needed for non-jailbreak devices. */
toolbarButtons = [NSMutableArray arrayWithObjects:
[[UIBarButtonItem alloc] initWithTitle:BOXSTRING("Home") style:UIBarButtonItemStyleBordered target:self
action:@selector(gotoHomeDir)],
[[UIBarButtonItem alloc] initWithTitle:BOXSTRING("App") style:UIBarButtonItemStyleBordered target:self
action:@selector(gotoAppDir)],
[[UIBarButtonItem alloc] initWithTitle:BOXSTRING("Root") style:UIBarButtonItemStyleBordered target:self
action:@selector(gotoRootDir)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self
action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self
action:@selector(refresh)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self
action:@selector(createNewFolder)],
nil
];
self.toolbarItems = toolbarButtons;
[self.tableView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(fileAction:)]];
}
return self;
}
- (void)cancelBrowser
{
[self.navigationController popViewControllerAnimated:YES];
}
- (void)gotoParent
{
[self browseTo:[self.path stringByDeletingLastPathComponent]];
}
- (void)gotoHomeDir
{
[self browseTo:NSHomeDirectory()];
}
- (void)gotoAppDir
{
[self browseTo:NSBundle.mainBundle.bundlePath];
}
- (void)gotoRootDir
{
[self browseTo:@"/"];
}
- (void)refresh
{
[self browseTo: self.path];
}
- (void)browseTo:(NSString*)path
{
NSString *i;
struct string_list *contents = NULL;
settings_t *settings = config_get_ptr();
self.path = path;
self.title = path.lastPathComponent;
/* Need one array per section. */
self.sections = [NSMutableArray array];
for (i in [self sectionIndexTitlesForTableView:self.tableView])
[self.sections addObject:[NSMutableArray arrayWithObject:i]];
/* List contents */
contents = dir_list_new(path.UTF8String,
settings->menu.navigation.browser.filter.supported_extensions_enable ? self.extensions.UTF8String : NULL, true);
if (contents)
{
ssize_t i;
RADirectoryList __weak* weakSelf = self;
if (self.allowBlank)
[self.sections[0] addObject:[RAMenuItemBasic itemWithDescription:BOXSTRING("[ Use Empty Path ]")
action:^{ weakSelf.chooseAction(weakSelf, nil); }]];
if (self.forDirectory)
[self.sections[0] addObject:[RAMenuItemBasic itemWithDescription:BOXSTRING("[ Use This Folder ]")
action:^{ weakSelf.chooseAction(weakSelf, [RADirectoryItem directoryItemFromPath:path]); }]];
dir_list_sort(contents, true);
for (i = 0; i < contents->size; i ++)
{
const char *basename = path_basename(contents->elems[i].data);
char is_directory = (contents->elems[i].attr.i == RARCH_DIRECTORY);
uint32_t section = is_directory ? 0 : isalpha(basename[0]) ? (toupper(basename[0]) - 'A') + 2 : 1;
if (! ( self.forDirectory && ! is_directory ))
[self.sections[section] addObject:[RADirectoryItem directoryItemFromElement:&contents->elems[i]]];
}
dir_list_free(contents);
}
else
{
[self gotoHomeDir];
return;
}
[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
[UIView transitionWithView:self.tableView duration:.25f options:UIViewAnimationOptionTransitionCrossDissolve
animations:
^{
[self.tableView reloadData];
} completion:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self browseTo: self.path];
}
- (NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView
{
static NSArray* names = nil;
if (!names)
names = @[@"/", @"#", @"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"];
return names;
}
/* File management
* Called as a selector from a toolbar button. */
- (void)createNewFolder
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:BOXSTRING("Enter new folder name") message:BOXSTRING("") delegate:self
cancelButtonTitle:BOXSTRING("Cancel") otherButtonTitles:BOXSTRING("OK"), nil];
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
alertView.tag = FA_CREATE;
[alertView show];
}
/* Called by the long press gesture recognizer. */
- (void)fileAction:(UILongPressGestureRecognizer*)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan)
{
CGPoint point = [gesture locationInView:self.tableView];
NSIndexPath* idx_path = [self.tableView indexPathForRowAtPoint:point];
if (idx_path)
{
int major, minor;
bool is_zip;
UIActionSheet *menu;
NSString *button4_name, *button5_name;
get_ios_version(&major, &minor);
button4_name = (major >= 7) ? BOXSTRING("AirDrop") : BOXSTRING("Delete");
button5_name = (major >= 7) ? BOXSTRING("Delete") : nil;
self.selectedItem = [self itemForIndexPath:idx_path];
is_zip = !(strcmp(self.selectedItem.path.pathExtension.UTF8String, "zip"));
menu = [[UIActionSheet alloc] initWithTitle:self.selectedItem.path.lastPathComponent delegate:self
cancelButtonTitle:BOXSTRING("Cancel") destructiveButtonTitle:nil
otherButtonTitles:is_zip ? BOXSTRING("Unzip") : BOXSTRING("Zip"), BOXSTRING("Move"), BOXSTRING("Rename"), button4_name, button5_name, nil];
[menu showFromToolbar:self.navigationController.toolbar];
}
}
}
#define FILEBROWSER_ACTION_UNZIP 0x0e3f899bU
#define FILEBROWSER_ACTION_MOVE 0x7c89307cU
#define FILEBROWSER_ACTION_RENAME 0xce87affdU
#define FILEBROWSER_ACTION_AIRDROP 0x8c6cdb56U
#define FILEBROWSER_ACTION_DELETE 0xadde7058U
#define FILEBROWSER_ACTION_CANCEL 0xab41f40bU
/* Called by the action sheet created in (void)fileAction: */
- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
uint32_t action_str_hash;
int major, minor;
NSString* target = self.selectedItem.path;
NSString* action = [actionSheet buttonTitleAtIndex:buttonIndex];
const char *action_str = action.UTF8String;
get_ios_version(&major, &minor);
action_str_hash = djb2_calculate(action_str);
(void)major;
(void)minor;
switch (action_str_hash)
{
case FILEBROWSER_ACTION_UNZIP:
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:BOXSTRING("Enter target directory") message:@"" delegate:self
cancelButtonTitle:BOXSTRING("Cancel") otherButtonTitles:BOXSTRING("OK"), nil];
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
alertView.tag = FA_UNZIP;
[alertView textFieldAtIndex:0].text = [[target lastPathComponent] stringByDeletingPathExtension];
[alertView show];
}
break;
case FILEBROWSER_ACTION_MOVE:
[self.navigationController pushViewController:[[RAFoldersList alloc] initWithFilePath:target] animated:YES];
break;
case FILEBROWSER_ACTION_RENAME:
{
UIAlertView* alertView = [[UIAlertView alloc]
initWithTitle:BOXSTRING("Enter new name") message:@""
delegate:self cancelButtonTitle:BOXSTRING("Cancel") otherButtonTitles:BOXSTRING("OK"), nil];
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
alertView.tag = FA_MOVE;
[alertView textFieldAtIndex:0].text = target.lastPathComponent;
[alertView show];
}
break;
case FILEBROWSER_ACTION_AIRDROP:
#ifdef __IPHONE_7_0
if ((major >= 7))
{
/* TODO: ZIP if not already zipped. */
NSURL *url = [NSURL fileURLWithPath:self.selectedItem.path isDirectory:self.selectedItem.isDirectory];
NSArray *items = [NSArray arrayWithObject:url];
UIActivityViewController* avc = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
[self presentViewController:avc animated:YES completion:nil];
}
#endif
break;
case FILEBROWSER_ACTION_DELETE:
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:BOXSTRING("Really delete?") message:@"" delegate:self cancelButtonTitle:BOXSTRING("Cancel") otherButtonTitles:BOXSTRING("OK"), nil];
alertView.tag = FA_DELETE;
[alertView show];
}
break;
case FILEBROWSER_ACTION_CANCEL:
apple_display_alert("Action not supported.", "Action Failed");
break;
}
}
/* Called by various alert views created in this class,
* the alertView.tag value is the action to take. */
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != alertView.firstOtherButtonIndex)
return;
if (alertView.tag == FA_DELETE)
file_action(FA_DELETE, nil, self.selectedItem.path);
else
{
NSString* text = [alertView textFieldAtIndex:0].text;
if (text.length)
file_action((enum file_action)alertView.tag, self.selectedItem.path, [self.path stringByAppendingPathComponent:text]);
}
[self browseTo: self.path];
}
@end
@interface RAFoldersList()
@property (nonatomic) NSString* path;
@end
@implementation RAFoldersList
- (id)initWithFilePath:(NSString*)path
{
if ((self = [super initWithStyle:UITableViewStyleGrouped]))
{
RAFoldersList* __weak weakSelf = self;
NSString *sourceItem = path.stringByDeletingLastPathComponent; /* Parent item */
RAMenuItemBasic *parentItem = [RAMenuItemBasic itemWithDescription:BOXSTRING("<Parent>") association:sourceItem.stringByDeletingLastPathComponent
action:^(id userdata){ [weakSelf moveInto:userdata]; } detail:NULL];
struct string_list *contents = dir_list_new([path stringByDeletingLastPathComponent].UTF8String, NULL, true);
NSMutableArray *items = [NSMutableArray arrayWithObject:BOXSTRING("")];
[self.sections addObject:@[BOXSTRING(""), parentItem]];
self.path = path;
if (contents)
{
size_t i;
dir_list_sort(contents, true);
for (i = 0; i < contents->size; i ++)
{
if (contents->elems[i].attr.i == RARCH_DIRECTORY)
{
const char* basename = path_basename(contents->elems[i].data);
RAMenuItemBasic* item = [RAMenuItemBasic itemWithDescription:BOXSTRING(basename) association:BOXSTRING(contents->elems[i].data)
action:^(id userdata){ [weakSelf moveInto:userdata]; } detail:NULL];
[items addObject:item];
}
}
dir_list_free(contents);
}
[self setTitle:[BOXSTRING("Move ") stringByAppendingString: self.path.lastPathComponent]];
[self.sections addObject:items];
}
return self;
}
- (void)moveInto:(NSString*)path
{
NSString* targetPath = [path stringByAppendingPathComponent:self.path.lastPathComponent];
file_action(FA_MOVE, self.path, targetPath);
[self.navigationController popViewControllerAnimated:YES];
}
@end