diff --git a/Ample/Base.lproj/LaunchWindow.xib b/Ample/Base.lproj/LaunchWindow.xib
index f323e54..70cde4a 100644
--- a/Ample/Base.lproj/LaunchWindow.xib
+++ b/Ample/Base.lproj/LaunchWindow.xib
@@ -573,6 +573,29 @@ Gw
+
+
+
+
+
+
-
diff --git a/Ample/LaunchWindowController.h b/Ample/LaunchWindowController.h
index cd76867..32f4e2c 100644
--- a/Ample/LaunchWindowController.h
+++ b/Ample/LaunchWindowController.h
@@ -10,7 +10,7 @@
NS_ASSUME_NONNULL_BEGIN
-@interface LaunchWindowController : NSWindowController
+@interface LaunchWindowController : NSWindowController
@end
diff --git a/Ample/LaunchWindowController.m b/Ample/LaunchWindowController.m
index 67f57ec..34b9806 100644
--- a/Ample/LaunchWindowController.m
+++ b/Ample/LaunchWindowController.m
@@ -79,6 +79,9 @@ static NSString *kContextMachine = @"kContextMachine";
@property (strong) IBOutlet NSWindow *addBookmarkWindow;
@property (strong) NSString *bookmarkName;
@property (weak) IBOutlet NSTextField *bookmarkTextField;
+
+@property BOOL optionKey;
+
@end
@interface LaunchWindowController (SoftwareList)
@@ -600,6 +603,62 @@ static NSString *ShellQuote(NSString *s) {
}
+
+- (IBAction)listMedia:(id)sender {
+
+ [[self window] makeFirstResponder: nil]; // in case text is being edited...
+ if (!_machine) return;
+
+ NSMutableArray *argv = [NSMutableArray new];
+
+ [argv addObject: _machine];
+ [argv addObject: @"-listmedia"];
+
+
+ NSArray *tmp;
+ tmp = [_slotController args];
+ if ([tmp count]) {
+ [argv addObjectsFromArray: tmp];
+ }
+
+#if 0
+ tmp = [_mediaController args];
+ if ([tmp count]) {
+ [argv addObjectsFromArray: tmp];
+ }
+#endif
+
+ [LogWindowController controllerForArgs: argv close: NO];
+}
+
+- (IBAction)listSlots:(id)sender {
+
+ [[self window] makeFirstResponder: nil]; // in case text is being edited...
+ if (!_machine) return;
+
+ NSMutableArray *argv = [NSMutableArray new];
+
+ [argv addObject: _machine];
+ [argv addObject: @"-listslots"];
+
+
+ NSArray *tmp;
+ tmp = [_slotController args];
+ if ([tmp count]) {
+ [argv addObjectsFromArray: tmp];
+ }
+
+#if 0
+ tmp = [_mediaController args];
+ if ([tmp count]) {
+ [argv addObjectsFromArray: tmp];
+ }
+#endif
+
+ [LogWindowController controllerForArgs: argv close: NO];
+}
+
+
-(IBAction)exportShellScript: (id)sender {
NSSavePanel *p = [NSSavePanel savePanel];
@@ -924,4 +983,12 @@ static NSString *ShellQuote(NSString *s) {
}
+#pragma mark - NSMenuDelegate
+
+-(void)menuNeedsUpdate:(NSMenu *)menu {
+ NSEventModifierFlags modifiers = [NSEvent modifierFlags];
+
+ [self setOptionKey: modifiers & NSEventModifierFlagOption ? YES : NO];
+}
+
@end
diff --git a/Ample/LogWindowController.h b/Ample/LogWindowController.h
index a94c1a3..75cd640 100644
--- a/Ample/LogWindowController.h
+++ b/Ample/LogWindowController.h
@@ -12,8 +12,13 @@ NS_ASSUME_NONNULL_BEGIN
@interface LogWindowController : NSWindowController
+#if 0
+(id)controllerForTask: (NSTask *)task;
++(id)controllerForTask: (NSTask *)task close: (BOOL)close;
+#endif
+
+(id)controllerForArgs: (NSArray *)args;
++(id)controllerForArgs: (NSArray *)args close: (BOOL)close;
@end
NS_ASSUME_NONNULL_END
diff --git a/Ample/LogWindowController.m b/Ample/LogWindowController.m
index 7843658..27c864a 100644
--- a/Ample/LogWindowController.m
+++ b/Ample/LogWindowController.m
@@ -19,6 +19,10 @@ static NSMutableSet *LogWindows;
@implementation LogWindowController {
NSTask *_task;
NSFileHandle *_handle;
+ NSFont *_font;
+
+ BOOL _close;
+ BOOL _eof;
}
+(void)initialize {
@@ -30,17 +34,14 @@ static NSMutableSet *LogWindows;
}
-+(id)controllerForTask: (NSTask *)task {
++(id)controllerForTask: (NSTask *)task close: (BOOL)close{
LogWindowController *controller = [[LogWindowController alloc] initWithWindowNibName: @"LogWindow"];
- [controller runTask: task];
+ [controller runTask: task close: close];
return controller;
}
-
-+(id)controllerForArgs: (NSArray *)args {
-
-// NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
++(id)controllerForArgs: (NSArray *)args close: (BOOL)close {
NSURL *url = MameURL();
@@ -64,15 +65,24 @@ static NSMutableSet *LogWindows;
[task setArguments: args];
- return [LogWindowController controllerForTask: task];
+ return [LogWindowController controllerForTask: task close: close];
+
+}
+
++(id)controllerForArgs: (NSArray *)args {
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ BOOL close = [defaults boolForKey: kAutoCloseLogWindow];
+ return [self controllerForArgs: args close: close];
}
- (void)windowDidLoad {
[super windowDidLoad];
[LogWindows addObject: self];
+
+ _font = [NSFont userFixedPitchFontOfSize: 0];
- // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
-(void)appendString: (NSString *)string
@@ -80,7 +90,10 @@ static NSMutableSet *LogWindows;
if ([string length])
{
// needs explicit color attribute for proper dark mode support.
- NSDictionary *attr = @{ NSForegroundColorAttributeName: [NSColor textColor] };
+ NSDictionary *attr = @{
+ NSForegroundColorAttributeName: [NSColor textColor],
+ NSFontAttributeName: _font,
+ };
NSAttributedString *astr = [[NSAttributedString alloc] initWithString: string attributes: attr];
[[_textView textStorage] appendAttributedString: astr];
}
@@ -93,10 +106,12 @@ static NSMutableSet *LogWindows;
}
}
--(NSError *)runTask: (NSTask *)task {
+-(NSError *)runTask: (NSTask *)task close: (BOOL)close {
if (_task) return nil;
+ _close = close;
+ _eof = NO;
NSPipe *pipe = [NSPipe pipe];
@@ -130,16 +145,6 @@ static NSMutableSet *LogWindows;
}
}
-#if 0
- if (error) {
-// NSURL *url = [task executableURL];
-// NSString *path = [NSString stringWithCString: [url fileSystemRepresentation] encoding: NSUTF8StringEncoding];
- NSLog(@"NSTask error. Path = %s error = %@", path, error);
-// [self appendString: path];
-// [self appendString: [error description]];
- return error;
- }
-#endif
_task = task;
NSString *title = [NSString stringWithFormat: @"Ample Log - %u", [task processIdentifier]];
[[self window] setTitle: title];
@@ -150,6 +155,7 @@ static NSMutableSet *LogWindows;
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+
[nc addObserver: self
selector: @selector(taskComplete:)
name: NSTaskDidTerminateNotification
@@ -160,6 +166,7 @@ static NSMutableSet *LogWindows;
object: _handle];
[_handle readInBackgroundAndNotify];
+
[[self window] setDocumentEdited: YES];
return nil;
}
@@ -172,21 +179,33 @@ static NSMutableSet *LogWindows;
// 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];
+ } else {
+ [self appendString: @"\n"]; // -listmedia sometimes causes display issues.
+ _eof = YES;
+ //[_textView setNeedsDisplay: YES]; // -listmedia sometimes weird.
}
-
}
+-(void)taskCompleteHack {
+
+}
+
+/* hask! task complete may occur while output still being processed. add a delay to compensate. */
-(void)taskComplete: (NSNotification *)notification
{
+ if (!_eof) {
+ [self performSelector: @selector(taskComplete:) withObject: notification afterDelay: 0.5];
+ return;
+ }
+
BOOL ok = NO;
NSTaskTerminationReason reason;
int status;
@@ -200,7 +219,7 @@ static NSMutableSet *LogWindows;
if (status == 0)
{
- string = @"\n\n[Success]\n\n";
+ //string = @"\n\n[Success]\n\n";
ok = YES;
}
else string = @"\n\n[An error occurred]\n\n";
@@ -209,18 +228,22 @@ static NSMutableSet *LogWindows;
{
string = [NSString stringWithFormat: @"\n\n[Caught signal %d (%s)]\n\n", status, strsignal(status)];
}
-
- [self appendString: string];
-
+ if (string) {
+ NSDictionary *attr = @{
+ NSForegroundColorAttributeName: [NSColor systemRedColor],
+ NSFontAttributeName: _font,
+ };
+ NSAttributedString *astr = [[NSAttributedString alloc] initWithString: string attributes: attr];
+ [self appendAttributedString: astr];
+ }
+
_handle = nil;
_task = nil;
[[self window] setDocumentEdited: NO];
- if (ok && [[NSUserDefaults standardUserDefaults] boolForKey: kAutoCloseLogWindow]) {
-
+ if (ok && _close) {
[[self window] close];
- //[LogWindows removeObject: self]; // close sends WindowWillClose notification.
}
}