ProFUSE-Image-Opener/Image Opener/WindowController.m
2011-03-03 22:32:37 -05:00

312 lines
6.5 KiB
Objective-C

//
// WindowController.m
// Image Opener
//
// Created by Kelvin Sherlock on 3/1/2011.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "WindowController.h"
@implementation WindowController
@synthesize filePath = _filePath;
static const char *TagToFormat(NSInteger tag)
{
switch (tag)
{
case 1:
default:
return "po";
case 2:
return "do";
case 3:
return "2img";
case 4:
return "dc42";
case 5:
return "davex";
}
}
+(id)new
{
return [[self alloc] initWithWindowNibName: @"Window"];
}
+(id)controllerWithFilePath: (NSString *)filePath
{
WindowController *controller = [[self alloc] initWithWindowNibName: @"Window"];
NSWindow *window = [controller window]; // force a load...
[controller setFilePath: filePath];
[window makeKeyAndOrderFront: nil];
[window makeFirstResponder: nil];
return controller;
}
- (void)dealloc
{
NSLog(@"%s %@", sel_getName(_cmd), self);
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver: self];
[_task release];
[_handle release];
[_filePath release];
[super dealloc];
}
- (void)windowDidLoad
{
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
#pragma mark -
-(void)setFilePath:(NSString *)filePath
{
NSString *ext;
NSFileManager *manager;
NSDictionary *dict;
NSError *error;
unsigned format;
if (_filePath == filePath) return;
[_filePath release];
_filePath = [filePath retain];
[[self window] setTitleWithRepresentedFilename: filePath];
[_nameView setStringValue: [_filePath lastPathComponent]];
manager = [NSFileManager defaultManager];
error = nil;
dict = [manager attributesOfItemAtPath: filePath error: &error];
if (error)
{
[_sizeView setStringValue: @""];
[_mountButton setEnabled: NO];
[_textView setString: [error localizedDescription]];
}
else
{
NSString *ss = @"";
size_t size = [(NSNumber *)[dict 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];
}
// set the default image format.
ext = [_filePath pathExtension];
ext = [ext lowercaseString];
format = 1;
if ([ext isEqualToString: @"po"] ||
[ext isEqualToString: @"raw"])
{
format = 1;
}
else if ([ext isEqualToString: @"do"] ||
[ext isEqualToString: @"dsk"])
{
format = 2;
}
else if ([ext isEqualToString: @"2mg"] ||
[ext isEqualToString: @"2img"])
{
format = 3;
}
else if ([ext isEqualToString: @"dc42"])
{
format = 4;
}
else if ([ext isEqualToString: @"davex"] ||
[ext isEqualToString: @"dvx"])
{
format = 5;
}
[_ifMatrix selectCellWithTag: format];
[_fsMatrix selectCellWithTag: 1]; // assume prodos.
}
-(IBAction)mountButton: (id)sender
{
[_mountButton setEnabled: NO];
[self runTask];
}
-(void)appendString: (NSString *)string
{
if ([string length])
{
[[[_textView textStorage] mutableString] appendString: string];
}
}
-(void)runTask
{
NSTask *task;
NSPipe *pipe = [NSPipe pipe];
NSString *launchPath;
NSArray *argv;
NSFileHandle *handle;
NSNotificationCenter *nc;
task = [[NSTask alloc] init];
[task setStandardError: pipe];
[task setStandardOutput: pipe];
[task setStandardInput: [NSFileHandle fileHandleWithNullDevice]];
handle = [pipe fileHandleForReading];
launchPath = @"launch path...";
launchPath = [[NSBundle mainBundle] pathForAuxiliaryExecutable: @"profuse"];
argv = [NSArray arrayWithObjects:
@"-r",
[NSString stringWithFormat: @"--format=%s", TagToFormat([_ifMatrix selectedTag])],
_filePath
, nil];
[task setLaunchPath: launchPath];
[task setArguments: argv];
[self appendString: launchPath];
for (NSString *string in argv)
{
[self appendString: string];
[self appendString: @" "];
}
[self appendString: @"\n\n"];
return;
nc = [NSNotificationCenter defaultCenter];
[nc addObserver: self
selector: @selector(taskComplete:)
name: NSTaskDidTerminateNotification
object: task];
[nc addObserver: self
selector: @selector(readComplete:)
name: NSFileHandleReadCompletionNotification
object: handle];
_task = task;
_handle = [handle retain];
[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];
[_handle readInBackgroundAndNotify];
}
}
-(void)taskComplete: (NSNotification *)notification
{
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";
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;
[_mountButton setEnabled: YES];
}
#pragma mark -
#pragma mark NSWindowDelegate
- (void)windowWillClose:(NSNotification *)notification
{
[self release];
}
@end