diff options
Diffstat (limited to 'MxWorldSettings.m')
-rw-r--r-- | MxWorldSettings.m | 505 |
1 files changed, 505 insertions, 0 deletions
diff --git a/MxWorldSettings.m b/MxWorldSettings.m new file mode 100644 index 0000000..47b3817 --- /dev/null +++ b/MxWorldSettings.m @@ -0,0 +1,505 @@ +// +// MxWorldSettings.m +// Moxie +// +// Created by Brian Cully on Thu Jan 01 2004. +// Copyright (c) 2004 Brian Cully. All rights reserved. +// + +#import "MxWorldSettings.h" + +#include <Security/SecKeychain.h> +#include <Security/SecKeychainItem.h> +#include <Security/SecAccess.h> +#include <Security/SecTrustedApplication.h> +#include <Security/SecACL.h> + +#define MxHostnameSettingName ":HOSTNAME" +#define MxPortSettingName ":PORT" + +@implementation MxWorldSettings +- (NSMutableDictionary *)settings +{ + return theSettings; +} + +- (void)setSettings: (NSMutableDictionary *)someSettings +{ + [someSettings retain]; + [theSettings release]; + theSettings = someSettings; +} + ++ (MxWorldSettings *)settingsWithDictionary: (NSDictionary *)aDictionary +{ + MxWorldSettings *result; + + result = [[[MxWorldSettings alloc] init] autorelease]; + [result setSettings: [NSMutableDictionary dictionaryWithDictionary: aDictionary]]; + return result; +} + ++ (MxWorldSettings *)settingsFromDefaults +{ + MxWorldSettings *tmpSettings; + NSUserDefaults *defaults; + + tmpSettings = [[[MxWorldSettings alloc] init] autorelease]; + defaults = [NSUserDefaults standardUserDefaults]; + if ([defaults objectForKey: @":CONNECT-ON-OPEN"]) + [tmpSettings setConnectOnOpen: [[defaults objectForKey: @":CONNECT-ON-OPEN"] boolValue]]; + else + [tmpSettings setConnectOnOpen: NO]; + + if ([defaults objectForKey: @":TEXT-COLOR"]) + [tmpSettings setTextColor: + [NSUnarchiver unarchiveObjectWithData: [defaults objectForKey: @":TEXT-COLOR"]]]; + else + [tmpSettings setTextColor: [NSColor blackColor]]; + + if ([defaults objectForKey: @":BACKGROUND-COLOR"]) + [tmpSettings setBackgroundColor: + [NSUnarchiver unarchiveObjectWithData: [defaults objectForKey: @":BACKGROUND-COLOR"]]]; + else + [tmpSettings setBackgroundColor: [NSColor whiteColor]]; + + if ([defaults objectForKey: @":FONT"]) + [tmpSettings setFont: + [NSUnarchiver unarchiveObjectWithData: [defaults objectForKey: @":FONT"]]]; + else + [tmpSettings setFont: [NSFont fontWithName: @"Monaco" size: 10.0]]; + + [tmpSettings setLoggingEnabled: [defaults boolForKey: @":LOGGING-ENABLED"]]; + [tmpSettings setLogTimeStamp: [defaults boolForKey: @":LOG-TIME-STAMPS"]]; + [tmpSettings setLogInput: [defaults boolForKey: @":LOG-INPUT"]]; + + return tmpSettings; +} + +- (id)init +{ + self = [super init]; + if (self) { + [self setSettings: [NSMutableDictionary dictionary]]; + } + return self; +} + +- (void)dealloc +{ + [self setSettings: nil]; + + [super dealloc]; +} + +- (NSString *)description +{ + return [[self settings] description]; +} + +- (id)objectForKey: (NSString *)aKey +{ + id value; + + value = [[self settings] objectForKey: [LispSymbol symbolNamed: aKey]]; + if ([value isKindOfClass: [NSArray class]] && [value count] == 1) + return [value objectAtIndex: 0]; + return value; +} + +- (void)removeObjectForKey: (NSString *)aKey +{ + id oldObject; + + oldObject = [[self settings] objectForKey: [LispSymbol symbolNamed: aKey]]; + if (oldObject) { + NSDictionary *userInfo; + NSNotificationCenter *defaultCenter; + + userInfo = [NSDictionary dictionaryWithObjectsAndKeys: + aKey, MxSettingName, oldObject, MxSettingOldValue, nil]; + + [[self settings] removeObjectForKey: aKey]; + + defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter postNotificationName: MxWorldSettingsDidChangeNotification + object: self + userInfo: userInfo]; + + } +} + +- (void)setObject: (id)anObject forKey: (NSString *)aKey +{ + if (anObject) { + NSDictionary *userInfo; + NSNotificationCenter *defaultCenter; + id oldObject; + + userInfo = nil; + oldObject = [[self settings] objectForKey: [LispSymbol symbolNamed: aKey]]; + if (!(oldObject == anObject || [oldObject isEqual: anObject])) { + if (oldObject) + userInfo = [NSDictionary dictionaryWithObjectsAndKeys: + aKey, MxSettingName, oldObject, MxSettingOldValue, nil]; + + [[self settings] setObject: anObject forKey: [LispSymbol symbolNamed: aKey]]; + + defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter postNotificationName: MxWorldSettingsDidChangeNotification + object: self + userInfo: userInfo]; + } + } else + [self removeObjectForKey: aKey]; +} + +- (BOOL)boolForKey: (NSString *)aKey +{ + id value; + + value = [self objectForKey: aKey]; + if ([value isKindOfClass: [NSArray class]]) { + if ([value count] == 0) + return NO; + value = [value objectAtIndex: 0]; + } + + if ([value respondsToSelector: @selector(boolValue)]) { + NSInvocation *invocation; + NSMethodSignature *sig; + + sig = [value methodSignatureForSelector: @selector(boolValue)]; + if ([sig methodReturnLength] == sizeof(BOOL)) { + BOOL rc; + + invocation = [NSInvocation invocationWithMethodSignature: sig]; + [invocation setTarget: value]; + [invocation setSelector: @selector(boolValue)]; + [invocation invoke]; + [invocation getReturnValue: &rc]; + + return rc; + } + } + return NO; +} + +- (void)setBool: (BOOL)aValue forKey: (NSString *)aKey +{ + [self setObject: aValue ? [LispSymbol symbolT] : [LispSymbol symbolNIL] + forKey: aKey]; +} + +- (NSString *)stringForKey: (NSString *)aKey +{ + NSString *value; + + value = [[[self settings] objectForKey: aKey] objectAtIndex: 0]; + if ([value respondsToSelector: @selector(stringValue)]) + return [value performSelector: @selector(stringValue)]; + else + return value; +} +@end + +@implementation MxWorldSettings (MoxieSettings) +- (NSString *)hostname +{ + return [self stringForKey: @":HOSTNAME"]; +} + +- (void)setHostname: (NSString *)aHostname +{ + [self setObject: aHostname forKey: @":HOSTNAME"]; +} + +- (NSNumber *)port +{ + return [NSNumber numberWithInt: [[self objectForKey: @":PORT"] intValue]]; +} + +- (void)setPort: (NSNumber *)aPort +{ + [self setObject: aPort forKey: @":PORT"]; +} + +- (BOOL)connectOnOpen +{ + return [self boolForKey: @":CONNECT-ON-OPEN"]; +} + +- (void)setConnectOnOpen: (BOOL)shouldConnect +{ + [self setBool: shouldConnect forKey: @":CONNECT-ON-OPEN"]; +} + +- (NSString *)character +{ + return [self stringForKey: @":CHARACTER"]; +} + +- (void)setCharacter: (NSString *)aName +{ + [self setObject: aName forKey: @":CHARACTER"]; +} + +- (NSString *)password +{ + return [self stringForKey: @":PASSWORD"]; +} + +- (void)setPassword: (NSString *)aPassword +{ + [self setObject: aPassword forKey: @":PASSWORD"]; +} + +/* +- (NSString *)password +{ + if ([[self characterName] length] > 0 && + [[self hostname] length] > 0 && + [self port]) { + const char *serverName, *accountName; + void *pwData; + UInt32 pwLen; + + serverName = [[self hostname] UTF8String]; + accountName = [[self characterName] UTF8String]; + if (SecKeychainFindInternetPassword(NULL, strlen(serverName), serverName, 0, NULL, + strlen(accountName), accountName, 0, NULL, + [[self port] unsignedLongValue], + kSecProtocolTypeTelnet, kSecAuthenticationTypeDefault, + &pwLen, &pwData, NULL) == noErr) { + NSString *password; + + // We found a password in the keychain. + password = [NSString stringWithUTF8String: pwData]; + return password; + } + } + + return nil; +} + +- (void)setPassword: (NSString *)aPassword +{ + if ([[self characterName] length] > 0 && + [[self hostname] length] > 0 && + [self port]) { + const char *serverName, *accountName, *pwData; + UInt32 pwLen; + + serverName = [[self hostname] UTF8String]; + accountName = [[self characterName] UTF8String]; + pwData = [aPassword UTF8String]; + pwLen = strlen(pwData); + SecKeychainAddInternetPassword(NULL, strlen(serverName), serverName, 0, NULL, + strlen(accountName), accountName, 0, NULL, + [[self port] unsignedLongValue], + kSecProtocolTypeTelnet, kSecAuthenticationTypeDefault, + pwLen, pwData, NULL); + } +} +*/ + +- (NSColor *)textColor +{ + NSArray *rgbaVals; + + rgbaVals = [self objectForKey: @":TEXT-COLOR"]; + if (rgbaVals) { + return [NSColor colorWithCalibratedRed: [[rgbaVals objectAtIndex: 0] floatValue] + green: [[rgbaVals objectAtIndex: 1] floatValue] + blue: [[rgbaVals objectAtIndex: 2] floatValue] + alpha: [[rgbaVals objectAtIndex: 3] floatValue]]; + } + return nil; +} + +- (void)setTextColor: (NSColor *)aColor +{ + if (aColor == nil) + [self removeObjectForKey: @":TEXT-COLOR"]; + else { + NSColor *rgbColor; + float r, g, b, a; + + rgbColor = [aColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + [rgbColor getRed: &r green: &g blue: &b alpha: &a]; + [self setObject: [NSArray arrayWithObjects: + [NSNumber numberWithFloat: r], [NSNumber numberWithFloat: g], [NSNumber numberWithFloat: b], + [NSNumber numberWithFloat: a], nil] + forKey: @":TEXT-COLOR"]; + } +} + +- (NSColor *)backgroundColor +{ + NSArray *rgbaVals; + + rgbaVals = [self objectForKey: @":BACKGROUND-COLOR"]; + if (rgbaVals) { + return [NSColor colorWithCalibratedRed: [[rgbaVals objectAtIndex: 0] floatValue] + green: [[rgbaVals objectAtIndex: 1] floatValue] + blue: [[rgbaVals objectAtIndex: 2] floatValue] + alpha: [[rgbaVals objectAtIndex: 3] floatValue]]; + } + return nil; +} + +- (void)setBackgroundColor: (NSColor *)aColor +{ + if (aColor == nil) + [self removeObjectForKey: @":BACKGROUND-COLOR"]; + else { + NSColor *rgbColor; + float r, g, b, a; + + rgbColor = [aColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + [rgbColor getRed: &r green: &g blue: &b alpha: &a]; + [self setObject: [NSArray arrayWithObjects: + [NSNumber numberWithFloat: r], [NSNumber numberWithFloat: g], [NSNumber numberWithFloat: b], + [NSNumber numberWithFloat: a], nil] + forKey: @":BACKGROUND-COLOR"]; + } +} + +- (NSData *)textColorData +{ + return [NSArchiver archivedDataWithRootObject: [self textColor]]; +} + +- (void)setTextColorData: (NSData *)colorData +{ + return [self setTextColor: [NSUnarchiver unarchiveObjectWithData: colorData]]; +} + +- (NSData *)backgroundColorData +{ + return [NSArchiver archivedDataWithRootObject: [self backgroundColor]]; +} + +- (void)setBackgroundColorData: (NSData *)colorData +{ + return [self setBackgroundColor: [NSUnarchiver unarchiveObjectWithData: colorData]]; +} + +- (NSString *)fontDisplayName +{ + return [[self font] displayName]; +} + +// XXX: defaults probably shouldn't be here. +- (NSFont *)font +{ + NSArray *fontInfo; + + fontInfo = [self objectForKey: @":FONT"]; + if (fontInfo && [fontInfo count] == 2) { + NSFont *result; + + result = [NSFont fontWithName: [fontInfo objectAtIndex: 0] + size: [[fontInfo objectAtIndex: 1] floatValue]]; + if (!result) + result = [NSFont fontWithName: @"Monaco" size: 10.0]; + return result; + } + return nil; +} + +- (void)setFont: (NSFont *)aFont +{ + if (aFont == nil) + [self removeObjectForKey: @":FONT"]; + else { + NSArray *value = [NSArray arrayWithObjects: + [aFont fontName], [NSNumber numberWithFloat: [aFont pointSize]], nil]; + + [self setObject: value forKey: @":FONT"]; + } +} + +- (BOOL)loggingEnabled +{ + return [self boolForKey: @":LOGGING-ENABLED"]; +} + +- (void)setLoggingEnabled: (BOOL)isEnabled +{ + [self setBool: isEnabled forKey: @":LOGGING-ENABLED"]; +} + +- (BOOL)logTimeStamp +{ + return [self boolForKey: @":LOG-TIME-STAMP"]; +} + +- (void)setLogTimeStamp: (BOOL)isEnabled +{ + [self setBool: isEnabled forKey: @":LOG-TIME-STAMP"]; +} + +- (BOOL)logInput +{ + return [self boolForKey: @":LOG-INPUT"]; +} + +- (void)setLogInput: (BOOL)isEnabled +{ + [self setBool: isEnabled forKey: @":LOG-INPUT"]; +} + +- (NSRect)windowFrame +{ + NSArray *windowSize, *windowOrigin; + + windowSize = [self objectForKey: @":WINDOW-SIZE"]; + windowOrigin = [self objectForKey: @":WINDOW-ORIGIN"]; + if (!windowSize || ! windowOrigin || + [windowSize count] != 2 || [windowOrigin count] != 2) + return NSMakeRect(-1, -1, -1, -1); + + return NSMakeRect([[windowOrigin objectAtIndex: 0] floatValue], + [[windowOrigin objectAtIndex: 1] floatValue], + [[windowSize objectAtIndex: 0] floatValue], + [[windowSize objectAtIndex: 1] floatValue]); +} + +- (void)setWindowFrame: (NSRect)aFrame +{ + NSArray *origin = [NSArray arrayWithObjects: + [LispSymbol symbolNamed: [NSString stringWithFormat: @"%f", aFrame.origin.x]], + [LispSymbol symbolNamed: [NSString stringWithFormat: @"%f", aFrame.origin.y]], nil]; + NSArray *size = [NSArray arrayWithObjects: + [LispSymbol symbolNamed: [NSString stringWithFormat: @"%f", aFrame.size.width]], + [LispSymbol symbolNamed: [NSString stringWithFormat: @"%f", aFrame.size.height]], nil]; + + [self setObject: origin forKey: @":WINDOW-ORIGIN"]; + [self setObject: size forKey: @":WINDOW-SIZE"]; +} + +- (unsigned int)inputViewSize +{ + return [[self objectForKey: @":INPUT-VIEW-SIZE"] intValue]; +} + +- (void)setInputViewSize: (unsigned int)aSize +{ + [self setObject: [LispSymbol symbolNamed: [NSString stringWithFormat: @"%u", aSize]] + forKey: @":INPUT-VIEW-SIZE"]; +} +@end + +@implementation NSUserDefaults (MxWorldSettingsAdditions) +- (void)setDefaultsFromWorldSettings: (MxWorldSettings *)someSettings +{ + [self setObject: [someSettings objectForKey: @":CONNECT-ON-OPEN"] forKey: @":CONNECT-ON-OPEN"]; + [self setObject: [someSettings objectForKey: @":TEXT-COLOR"] forKey: @":TEXT-COLOR"]; + [self setObject: [someSettings objectForKey: @":BACKGROUND-COLOR"] forKey: @":BACKGROUND-COLOR"]; + [self setObject: [someSettings objectForKey: @":FONT"] forKey: @":FONT"]; + [self setObject: [someSettings objectForKey: @":LOGGING-ENABLED"] forKey: @":LOGGING-ENABLED"]; + [self setObject: [someSettings objectForKey: @":LOG-TIME-STAMP"] forKey: @":LOG-TIME-STAMP"]; + [self setObject: [someSettings objectForKey: @":LOG-INPUT"] forKey: @":LOG-INPUT"]; +} +@end
\ No newline at end of file |