ProFUSE-Image-Opener/Image Opener/IODocument.m

293 lines
5.9 KiB
Objective-C

//
// IODocument.m
// Image Opener
//
// Created by Kelvin Sherlock on 8/17/2016.
//
//
#import "IODocument.h"
enum {
kTagLucky = 1,
kTag2MG,
kTagDC42,
kTagSDK,
kTagDavex,
kTagPO,
kTagDO
};
static const char *TagToFormat(NSInteger tag)
{
switch (tag)
{
case kTagPO:
default:
return "po";
case kTagDO:
return "do";
case kTag2MG:
return "2img";
case kTagDC42:
return "dc42";
case kTagDavex:
return "davex";
case kTagSDK:
return "sdk";
}
}
@implementation IODocument
@synthesize filePath = _filePath;
- (NSString *)windowNibName {
return @"IODocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController {
[super windowControllerDidLoadNib:aController];
[_nameView setStringValue: [_filePath lastPathComponent]];
NSString *ss = @"";
off_t size = [(NSNumber *)[_fileInfo objectForKey: NSFileSize] unsignedLongLongValue];
if (size < 1024)
ss = [NSString stringWithFormat: @"%u B", (unsigned)size];
else if (size < 1024 * 1024)
ss = [NSString stringWithFormat: @"%.1f KB", (double) size / 1024.0];
else ss = [NSString stringWithFormat: @"%.1f MB", (double) size / (1024.0 * 1024.0)];
[_sizeView setStringValue: ss];
[_ifMatrix selectCellWithTag: kTagLucky];
[_fsMatrix selectCellWithTag: 1]; // assume prodos.
}
-(BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError * _Nullable *)outError {
NSString *path = [url isFileURL] ? [url path] : nil;
//NSLog(@"%d %@", (int)result, path);
[self setFileInfo: nil];
[self setFilePath: nil];
if (path) {
NSFileManager *manager;
NSDictionary *dict;
NSError *error = nil;
_filePath = [path retain];
manager = [NSFileManager defaultManager];
dict = [manager attributesOfItemAtPath: path error: &error];
if (error) {
if (outError )*outError = error;
return NO;
}
_fileInfo = [dict retain];
return YES;
} else {
if (outError) *outError = [NSError errorWithDomain: NSURLErrorDomain code: 1 userInfo: nil];
return NO;
}
}
+(BOOL)autosavesInPlace {
// YES adds the rename drop down panel in the title bar!
return NO;
}
- (void)dealloc
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver: self];
[_task release];
[_handle release];
[_filePath release];
[_fileInfo release];
[super dealloc];
}
-(IBAction)mountButton: (id)sender
{
[_mountButton setEnabled: NO];
[self runTask];
}
-(void)appendString: (NSString *)string
{
if ([string length])
{
[[[_textView textStorage] mutableString] appendString: string];
}
}
-(void)runTask
{
NSPipe *pipe = [NSPipe pipe];
NSString *launchPath;
NSMutableArray *argv;
NSNotificationCenter *nc;
NSString *exe;
NSInteger tag;
_task = [[NSTask alloc] init];
[_task setStandardError: pipe];
[_task setStandardOutput: pipe];
[_task setStandardInput: [NSFileHandle fileHandleWithNullDevice]];
_handle = [[pipe fileHandleForReading] retain];
switch ([_fsMatrix selectedTag])
{
case 1:
default:
exe = @"profuse";
break;
case 2:
exe = @"fuse_pascal";
break;
}
launchPath = [[NSBundle mainBundle] pathForAuxiliaryExecutable: exe];
argv = [NSMutableArray arrayWithCapacity: 4];
[argv addObject: @"-r"]; // read-only.
tag = [_ifMatrix selectedTag];
if (tag != kTagLucky)
{
[argv addObject: [NSString stringWithFormat: @"--format=%s", TagToFormat(tag)]];
}
[argv addObject: _filePath];
[_task setLaunchPath: launchPath];
[_task setArguments: argv];
[self appendString: launchPath];
for (NSString *string in argv)
{
[self appendString: @" "];
[self appendString: string];
}
[self appendString: @"\n\n"];
nc = [NSNotificationCenter defaultCenter];
[nc addObserver: self
selector: @selector(taskComplete:)
name: NSTaskDidTerminateNotification
object: _task];
[nc addObserver: self
selector: @selector(readComplete:)
name: NSFileHandleReadCompletionNotification
object: _handle];
[_task launch];
[_handle readInBackgroundAndNotify];
}
#pragma mark -
#pragma mark Notifications
-(void)readComplete:(NSNotification *)notification
{
// read complete, queue up another.
NSDictionary *dict = [notification userInfo];
NSData *data = [dict objectForKey: NSFileHandleNotificationDataItem];
if ([data length])
{
NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
[self appendString: string];
[string release];
[_handle readInBackgroundAndNotify];
}
}
-(void)taskComplete: (NSNotification *)notification
{
BOOL ok = NO;
NSTaskTerminationReason reason;
int status;
NSString *string = nil;
reason = [_task terminationReason];
status = [_task terminationStatus];
if (reason == NSTaskTerminationReasonExit)
{
if (status == 0)
{
string = @"\n\n[Success]\n\n";
ok = YES;
}
else string = @"\n\n[An error occurred]\n\n";
}
else
{
string = @"\n\n[Caught signal]\n\n";
}
[self appendString: string];
[_handle release];
_handle = nil;
[_task release];
_task = nil;
if (!ok) [_mountButton setEnabled: YES];
}
@end