2020-08-29 22:45:25 +00:00
|
|
|
//
|
|
|
|
// LogWindowController.m
|
|
|
|
// MA2ME
|
|
|
|
//
|
|
|
|
// Created by Kelvin Sherlock on 8/29/2020.
|
|
|
|
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "LogWindowController.h"
|
|
|
|
|
|
|
|
static NSMutableSet *LogWindows;
|
|
|
|
|
|
|
|
@interface LogWindowController ()
|
|
|
|
@property (unsafe_unretained) IBOutlet NSTextView *textView;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation LogWindowController {
|
|
|
|
NSTask *_task;
|
|
|
|
NSFileHandle *_handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
+(void)initialize {
|
|
|
|
LogWindows = [NSMutableSet set];
|
|
|
|
}
|
|
|
|
|
|
|
|
-(NSString *)windowNibName {
|
|
|
|
return @"LogWindow";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+(id)controllerForTask: (NSTask *)task {
|
|
|
|
LogWindowController *controller = [[LogWindowController alloc] initWithWindowNibName: @"LogWindow"];
|
|
|
|
[controller runTask: task];
|
|
|
|
return controller;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)windowDidLoad {
|
|
|
|
[super windowDidLoad];
|
|
|
|
|
|
|
|
[LogWindows addObject: self];
|
|
|
|
|
|
|
|
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
|
|
|
}
|
|
|
|
|
|
|
|
-(void)appendString: (NSString *)string
|
|
|
|
{
|
|
|
|
if ([string length])
|
|
|
|
{
|
|
|
|
[[[_textView textStorage] mutableString] appendString: string];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
-(NSError *)runTask: (NSTask *)task {
|
|
|
|
|
|
|
|
|
|
|
|
if (_task) return nil;
|
|
|
|
|
|
|
|
NSError *error = nil;
|
|
|
|
NSPipe *pipe = [NSPipe pipe];
|
|
|
|
|
|
|
|
[task setStandardError: pipe];
|
|
|
|
[task setStandardOutput: pipe];
|
|
|
|
[task launchAndReturnError: &error];
|
|
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
NSLog(@"launchAction: %@", error);
|
|
|
|
[self appendString: [error description]];
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
_task = task;
|
|
|
|
NSString *title = [NSString stringWithFormat: @"Log Window - %u", [task processIdentifier]];
|
|
|
|
[[self window] setTitle: title];
|
|
|
|
_handle = [pipe fileHandleForReading];
|
|
|
|
|
|
|
|
|
|
|
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
|
|
|
|
|
|
|
[nc addObserver: self
|
|
|
|
selector: @selector(taskComplete:)
|
|
|
|
name: NSTaskDidTerminateNotification
|
|
|
|
object: _task];
|
|
|
|
[nc addObserver: self
|
|
|
|
selector: @selector(readComplete:)
|
|
|
|
name: NSFileHandleReadCompletionNotification
|
|
|
|
object: _handle];
|
|
|
|
|
|
|
|
[_handle readInBackgroundAndNotify];
|
|
|
|
[[self window] setDocumentEdited: YES];
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#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
|
|
|
|
{
|
|
|
|
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 = nil;
|
|
|
|
_task = nil;
|
|
|
|
|
|
|
|
[[self window] setDocumentEdited: NO];
|
2020-08-30 02:23:59 +00:00
|
|
|
|
|
|
|
if (ok && [[NSUserDefaults standardUserDefaults] boolForKey: @"AutoCloseLogWindow"]) {
|
|
|
|
|
|
|
|
[[self window] close];
|
|
|
|
//[LogWindows removeObject: self]; // close sends WindowWillClose notification.
|
|
|
|
}
|
2020-08-29 22:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - NSWindowDelegate
|
|
|
|
|
|
|
|
|
|
|
|
-(void)windowWillClose:(NSNotification *)notification {
|
|
|
|
[LogWindows removeObject: self];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|