// // DockCamPrefs.m // DockCam // // Created by Nicholas Riley on Thu Jun 27 2002. // Copyright (c) 2002 Nicholas Riley. All rights reserved. // #import "DockCamPrefs.h" NSString * const DCImageLocation = @"DCImageLocation"; NSString * const DCImageSize = @"DCImageSize"; NSString * const DCImageRefreshEnabled = @"DCImageRefreshEnabled"; NSString * const DCImageRefreshInterval = @"DCImageRefreshInterval"; NSString * const DCShowImageInBackground = @"DCShowImageInBackground"; NSString * const DCShowStatus = @"DCShowStatus"; NSString * const DCPrefChangedNotification = @"DCPrefChangedNotification"; const NSTimeInterval DCDefaultImageRefreshInterval = 30; enum { DCImageRetrieveOnOpen = 2000, DCImageRetrieveOnTimer = 2001 }; enum { DCImageRefreshIntervalSeconds = 1, DCImageRefreshIntervalMinutes = 60, DCImageRefreshIntervalHours = 3600 }; NSUserDefaults *defaults; @implementation DockCamPrefs + (void)initialize; { NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: @"", DCImageLocation, [NSNumber numberWithInt: DCDefaultImageRefreshInterval], DCImageRefreshInterval, [NSNumber numberWithBool: NO], DCShowImageInBackground, [NSNumber numberWithBool: YES], DCShowStatus, nil]; defaults = [NSUserDefaults standardUserDefaults]; [defaults registerDefaults: appDefaults]; } + (void)_prefChanged:(NSString *)pref; { [[NSNotificationCenter defaultCenter] postNotificationName: DCPrefChangedNotification object: pref]; } #pragma mark preference getters + (BOOL)boolForPref:(NSString *)pref; { return [defaults boolForKey: pref]; } + (int)intForPref:(NSString *)pref; { return [defaults integerForKey: pref]; } + (NSString *)stringForPref:(NSString *)pref; { return [defaults stringForKey: pref]; } + (NSSize)sizeForPref:(NSString *)pref; { return NSSizeFromString([defaults stringForKey: pref]); } #pragma mark preference setters + (void)setBool:(BOOL)value forPref:(NSString *)pref; { BOOL oldValue = [self boolForPref: pref]; if (oldValue != value) { [defaults setBool: value forKey: pref]; [self _prefChanged: pref]; } } + (void)setInt:(int)value forPref:(NSString *)pref; { int oldValue = [self intForPref: pref]; if (oldValue != value) { [defaults setInteger: value forKey: pref]; [self _prefChanged: pref]; } } + (void)setString:(NSString *)value forPref:(NSString *)pref; { NSString *oldValue = [self stringForPref: pref]; if (![oldValue isEqualToString: value]) { [defaults setObject: value forKey: pref]; [self _prefChanged: pref]; } } + (void)setSize:(NSSize)value forPref:(NSString *)pref; { NSSize oldValue = [self sizeForPref: pref]; if (!NSEqualSizes(oldValue, value)) { [defaults setObject: NSStringFromSize(value) forKey: pref]; [self _prefChanged: pref]; } } #pragma mark complex interface-preference mapping - (BOOL)retrieveOnTimer; { return [[retrieveImageAutomatically selectedCell] tag] == DCImageRetrieveOnTimer; } - (NSTimeInterval)interval; { return [imageRefreshInterval intValue] * [[imageRefreshIntervalUnits selectedItem] tag]; } - (void)setInterval:(NSTimeInterval)interval; { // we assume that the tags are in ascending order in the array NSEnumerator *e = [[imageRefreshIntervalUnits itemArray] reverseObjectEnumerator]; NSMenuItem *i; int multiplierTag; while ( (i = [e nextObject]) != nil) { multiplierTag = [i tag]; if (((int)interval % multiplierTag) == 0) { [imageRefreshInterval setIntValue: interval / multiplierTag]; [imageRefreshIntervalUnits selectItem: i]; return; } } [imageRefreshIntervalUnits selectItemAtIndex: 0]; [imageRefreshInterval setIntValue: DCDefaultImageRefreshInterval]; } #pragma mark preference I/O - (void)readFromPrefs; { [imageLocation setStringValue: [DockCamPrefs stringForPref: DCImageLocation]]; [retrieveImageAutomatically selectCellWithTag: [DockCamPrefs boolForPref: DCImageRefreshEnabled] ? DCImageRetrieveOnTimer : DCImageRetrieveOnOpen]; [self setInterval: [DockCamPrefs intForPref: DCImageRefreshInterval]]; [showImageInBackground setState: [DockCamPrefs boolForPref: DCShowImageInBackground] ? NSOnState : NSOffState]; } - (IBAction)writeToPrefs:(id)sender; { [DockCamPrefs setString: [imageLocation stringValue] forPref: DCImageLocation]; [DockCamPrefs setBool: [self retrieveOnTimer] forPref: DCImageRefreshEnabled]; [DockCamPrefs setInt: [self interval] forPref: DCImageRefreshInterval]; [DockCamPrefs setBool: [showImageInBackground state] == NSOnState forPref: DCShowImageInBackground]; [defaults synchronize]; } #pragma mark interface maintenance - (IBAction)showWindow:(id)sender; { // XXX workaround for weird bug where combo box and text field alternately become first responder [super showWindow: sender]; [[[self window] initialFirstResponder] becomeFirstResponder]; } - (void)update; { BOOL enabled = [self retrieveOnTimer]; [imageRefreshInterval setEnabled: enabled]; [imageRefreshIntervalUnits setEnabled: enabled]; } - (IBAction)retrieveImageAutomatically:(id)sender; { [self update]; if ([self retrieveOnTimer]) [imageRefreshInterval becomeFirstResponder]; else [sender becomeFirstResponder]; } #pragma mark initialize-release - (id)init { self = [super initWithWindowNibName:@"Preferences"]; [self window]; // connect outlets [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(windowWillClose:) name: NSWindowWillCloseNotification object: [self window]]; [self readFromPrefs]; [self update]; return self; } @end @implementation DockCamPrefs (NSWindowNotifications) - (void)windowWillClose:(NSNotification *)notification; { [self writeToPrefs: self]; } @end