add secret listmedia/listslots options in the right-click menu

when option key pressed.
also adjust log window to use monospace font, show error/signal in red, and don't mention a successful exit.
tweaks to file handling/task complete so task complete logic is delayed until file handle is drained.
This commit is contained in:
Kelvin Sherlock 2021-06-18 21:57:46 -04:00
parent 34fcc3b3ed
commit 3889b42c14
5 changed files with 152 additions and 32 deletions

View File

@ -573,6 +573,29 @@ Gw
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Iti-F9-p35"/>
<menuItem title="List Media…" id="M5h-4W-0nV">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="listMedia:" target="-2" id="IO7-MG-zud"/>
<binding destination="-2" name="hidden" keyPath="optionKey" id="LhL-2l-iss">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</menuItem>
<menuItem title="List Slots…" id="cNj-Sb-KkE">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="listSlots:" target="-2" id="3nb-mV-eUK"/>
<binding destination="-2" name="hidden" keyPath="optionKey" id="dwp-Kn-LfC">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="yZx-W2-lZg"/>
<menuItem title="Reset All" id="PQ0-yO-SKz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
@ -598,11 +621,13 @@ Gw
</connections>
</menuItem>
</items>
<connections>
<outlet property="delegate" destination="-2" id="wqC-IG-63F"/>
</connections>
<point key="canvasLocation" x="-121" y="-2"/>
</menu>
</objects>
<resources>
<image name="NSAppleMenuImage" width="11" height="14"/>
<image name="NSAppleMenuImage" width="128" height="128"/>
</resources>
</document>

View File

@ -10,7 +10,7 @@
NS_ASSUME_NONNULL_BEGIN
@interface LaunchWindowController : NSWindowController <NSBrowserDelegate>
@interface LaunchWindowController : NSWindowController <NSBrowserDelegate, NSMenuDelegate>
@end

View File

@ -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

View File

@ -12,8 +12,13 @@ NS_ASSUME_NONNULL_BEGIN
@interface LogWindowController : NSWindowController <NSWindowDelegate>
#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

View File

@ -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.
}
}