/* * PreferencesController.m * * $Header: /cvs/kfm/KerberosClients/KerberosApp/Sources/PreferencesController.m,v 1.12 2005/01/31 20:51:32 lxs Exp $ * * Copyright 2004 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #import "PreferencesController.h" #import "LifetimeSlider.h" #import "LifetimeFormatter.h" #import "Utilities.h" @implementation PreferencesController // --------------------------------------------------------------------------- - (id) init { if ((self = [super initWithWindowNibName: @"Preferences"])) { preferences = [Preferences sharedPreferences]; if (preferences == NULL) { [self release]; return NULL; } [preferences retain]; } return self; } // --------------------------------------------------------------------------- - (void) dealloc { dprintf ("PreferencesController deallocating ..."); [preferences release]; [super dealloc]; } - (void) windowDidLoad { dprintf ("PreferencesController %lx entering windowDidLoad:...", (long) self); [super windowDidLoad]; [self setWindowFrameAutosaveName: @"KAPreferencesWindowPosition"]; } // --------------------------------------------------------------------------- - (IBAction) showWindow: (id) sender { // Check to see if the window was closed before. ([self window] will load the window) if (![[self window] isVisible]) { dprintf ("PreferencesController %x displaying window...", (long) self); [self preferencesToWindow]; [[self window] setFrameUsingName: [self windowFrameAutosaveName]]; } [super showWindow: sender]; } // --------------------------------------------------------------------------- - (IBAction) apply: (id) sender { [self windowToPreferences]; } // --------------------------------------------------------------------------- - (IBAction) ok: (id) sender { if ([self windowToPreferences]) { // Only close on no error [self close]; } } // --------------------------------------------------------------------------- - (IBAction) cancel: (id) sender { [self close]; } // --------------------------------------------------------------------------- - (IBAction) defaultPrincipalRadioButtonWasHit: (id) sender { NSButtonCell *selectedCell = [defaultPrincipalRadioButtonMatrix selectedCell]; BOOL enabled = (selectedCell == defaultToThisPrincipalRadioButtonCell); NSColor *enabledColor = enabled ? [NSColor blackColor] : [NSColor grayColor]; [nameHeaderTextField setTextColor: enabledColor]; [realmHeaderTextField setTextColor: enabledColor]; [nameTextField setEnabled: enabled]; [realmComboBox setEnabled: enabled]; } // --------------------------------------------------------------------------- - (IBAction) defaultTicketOptionsRadioButtonWasHit: (id) sender { NSButtonCell *selectedCell = [defaultOptionsRadioButtonMatrix selectedCell]; BOOL enabled = (selectedCell == defaultToTheseOptionsRadioButtonCell); NSColor *enabledColor = enabled ? [NSColor blackColor] : [NSColor grayColor]; [lifetimeHeaderTextField setTextColor: enabledColor]; if ([lifetimeSlider maxValue] > [lifetimeSlider minValue]) { [lifetimeTextField setTextColor: enabledColor]; [lifetimeSlider setEnabled: enabled]; } [optionsHeaderTextField setTextColor: enabledColor]; [forwardableCheckbox setEnabled: enabled]; [addresslessCheckbox setEnabled: enabled]; [renewableCheckbox setEnabled: enabled]; if ([renewableSlider maxValue] > [renewableSlider minValue]) { [renewableTextField setTextColor: enabledColor]; [renewableSlider setEnabled: enabled]; } } // --------------------------------------------------------------------------- - (BOOL) tabView: (NSTabView *) tabView shouldSelectTabViewItem: (NSTabViewItem *) tabViewItem { BOOL shouldSelect = YES; if (tabView == preferencesTabView) { if ([tabView selectedTabViewItem] == timeRangesTabViewItem) { // we are switching away from the time ranges tab time_t lifetimeMaximum = [self lifetimeMaximum]; time_t lifetimeMinimum = [self lifetimeMinimum]; time_t renewableMaximum = [self renewableMaximum]; time_t renewableMinimum = [self renewableMinimum]; if ([self validateLifetimeMaximum: lifetimeMaximum lifetimeMinimum: lifetimeMinimum renewableMaximum: renewableMaximum renewableMinimum: renewableMinimum]) { // Ranges are acceptable. Update the sliders and proceed time_t lifetime = [[lifetimeTextField formatter] lifetimeForControl: lifetimeSlider]; time_t renewableLifetime = [[renewableTextField formatter] lifetimeForControl: renewableSlider]; SetupLifetimeSlider (lifetimeSlider, lifetimeTextField, lifetimeMaximum, lifetimeMinimum, lifetime); SetupLifetimeSlider (renewableSlider, renewableTextField, renewableMaximum, renewableMinimum, renewableLifetime); [self defaultPrincipalRadioButtonWasHit: self]; // set enabledness of controls [self defaultTicketOptionsRadioButtonWasHit: self]; // set enabledness of controls } else { shouldSelect = NO; } } } return shouldSelect; } // --------------------------------------------------------------------------- - (void) errorSheetDidEnd: (NSAlert *) alert returnCode: (int) returnCode contextInfo: (void *) contextInfo { // Do nothing. } // --------------------------------------------------------------------------- - (BOOL) preferencesToWindow { // Behavior [autoRenewCheckbox setState: [preferences autoRenewTickets] ? NSOnState : NSOffState]; [showTimeRemainingInDockCheckbox setState: [preferences showTimeInDockIcon] ? NSOnState : NSOffState]; [rememberTicketWindowPositionCheckbox setState: ![preferences ticketWindowDefaultPosition] ? NSOnState : NSOffState]; switch ([preferences launchAction]) { case LaunchActionAlwaysOpenTicketWindow: [launchActionMatrix selectCell: alwaysOpenListWindowRadioButtonCell]; break; case LaunchActionNeverOpenTicketWindow: [launchActionMatrix selectCell: neverOpenListWindowRadioButtonCell]; break; case LaunchActionRememberOpenTicketWindow: [launchActionMatrix selectCell: rememberTicketListWindowOpenessRadioButtonCell]; break; } // Default Principal if ([preferences rememberPrincipalFromLastLogin]) { [defaultPrincipalRadioButtonMatrix selectCell: rememberPrincipalRadioButtonCell]; } else { [defaultPrincipalRadioButtonMatrix selectCell: defaultToThisPrincipalRadioButtonCell]; } [nameTextField setObjectValue: [preferences defaultName]]; NSArray *realmsArray = [preferences realms]; unsigned int i; [realmComboBox removeAllItems]; for (i = 0; i < [realmsArray count]; i++) { NSString *realm = [realmsArray objectAtIndex: i]; [realmComboBox addItemWithObjectValue: realm]; } [realmComboBox selectItemWithObjectValue: [preferences defaultRealm]]; [realmComboBox setObjectValue: [realmComboBox numberOfItems] > 0 ? [realmComboBox objectValueOfSelectedItem] : @""]; [realmComboBox setNumberOfVisibleItems: [realmsArray count]]; [realmComboBox setCompletes: YES]; // Default Ticket Options if ([preferences rememberOptionsFromLastLogin]) { [defaultOptionsRadioButtonMatrix selectCell: rememberOptionsRadioButtonCell]; } else { [defaultOptionsRadioButtonMatrix selectCell: defaultToTheseOptionsRadioButtonCell]; } [forwardableCheckbox setState: [preferences defaultForwardable] ? NSOnState : NSOffState]; [addresslessCheckbox setState: [preferences defaultAddressless] ? NSOnState : NSOffState]; [renewableCheckbox setState: [preferences defaultRenewable] ? NSOnState : NSOffState]; // Time Ranges time_t lifetimeMaximum = [preferences lifetimeMaximum]; time_t lifetimeMinimum = [preferences lifetimeMinimum]; time_t renewableMaximum = [preferences renewableLifetimeMaximum]; time_t renewableMinimum = [preferences renewableLifetimeMinimum]; SetupLifetimeSlider (lifetimeSlider, lifetimeTextField, lifetimeMaximum, lifetimeMinimum, [preferences defaultLifetime]); SetupLifetimeSlider (renewableSlider, renewableTextField, renewableMaximum, renewableMinimum, [preferences defaultRenewableLifetime]); [lifetimeMaximumDaysTextField setObjectValue: [NSNumber numberWithInt: DAYS (lifetimeMaximum)]]; [lifetimeMaximumHoursTextField setObjectValue: [NSNumber numberWithInt: HOURS (lifetimeMaximum)]]; [lifetimeMaximumMinutesTextField setObjectValue: [NSNumber numberWithInt: ROUNDEDMINUTES (lifetimeMaximum)]]; [lifetimeMinimumDaysTextField setObjectValue: [NSNumber numberWithInt: DAYS (lifetimeMinimum)]]; [lifetimeMinimumHoursTextField setObjectValue: [NSNumber numberWithInt: HOURS (lifetimeMinimum)]]; [lifetimeMinimumMinutesTextField setObjectValue: [NSNumber numberWithInt: ROUNDEDMINUTES (lifetimeMinimum)]]; [renewableMaximumDaysTextField setObjectValue: [NSNumber numberWithInt: DAYS (renewableMaximum)]]; [renewableMaximumHoursTextField setObjectValue: [NSNumber numberWithInt: HOURS (renewableMaximum)]]; [renewableMaximumMinutesTextField setObjectValue: [NSNumber numberWithInt: ROUNDEDMINUTES (renewableMaximum)]]; [renewableMinimumDaysTextField setObjectValue: [NSNumber numberWithInt: DAYS (renewableMinimum)]]; [renewableMinimumHoursTextField setObjectValue: [NSNumber numberWithInt: HOURS (renewableMinimum)]]; [renewableMinimumMinutesTextField setObjectValue: [NSNumber numberWithInt: ROUNDEDMINUTES (renewableMinimum)]]; [preferencesTabView selectFirstTabViewItem: self]; [self defaultPrincipalRadioButtonWasHit: self]; // set enabledness of controls [self defaultTicketOptionsRadioButtonWasHit: self]; // set enabledness of controls return YES; // For now, always succeed because we don't get errors from Preferences yet } // --------------------------------------------------------------------------- - (BOOL) windowToPreferences { NSButtonCell *selectedCell; // Time Ranges time_t lifetimeMaximum = [self lifetimeMaximum]; time_t lifetimeMinimum = [self lifetimeMinimum]; time_t renewableMaximum = [self renewableMaximum]; time_t renewableMinimum = [self renewableMinimum]; if (![self validateLifetimeMaximum: lifetimeMaximum lifetimeMinimum: lifetimeMinimum renewableMaximum: renewableMaximum renewableMinimum: renewableMinimum]) { // note that the above function reports the error for us. return NO; } [preferences setLifetimeMaximum: lifetimeMaximum]; [preferences setLifetimeMinimum: lifetimeMinimum]; [preferences setRenewableLifetimeMaximum: renewableMaximum]; [preferences setRenewableLifetimeMinimum: renewableMinimum]; // Default Ticket Options selectedCell = [defaultOptionsRadioButtonMatrix selectedCell]; if (selectedCell == rememberOptionsRadioButtonCell) { [preferences setRememberOptionsFromLastLogin: YES]; } else if (selectedCell == defaultToTheseOptionsRadioButtonCell) { [preferences setRememberOptionsFromLastLogin: NO]; [preferences setDefaultForwardable: ([forwardableCheckbox state] == NSOnState)]; [preferences setDefaultAddressless: ([addresslessCheckbox state] == NSOnState)]; [preferences setDefaultRenewable: ([renewableCheckbox state] == NSOnState)]; LifetimeFormatter *lifetimeFormatter = [lifetimeTextField formatter]; LifetimeFormatter *renewableFormatter = [renewableTextField formatter]; [preferences setDefaultLifetime: [lifetimeFormatter lifetimeForControl: lifetimeSlider]]; [preferences setDefaultRenewableLifetime: [renewableFormatter lifetimeForControl: renewableSlider]]; } // Default Principal selectedCell = [defaultPrincipalRadioButtonMatrix selectedCell]; if (selectedCell == rememberPrincipalRadioButtonCell) { [preferences setRememberPrincipalFromLastLogin: YES]; } else if (selectedCell == defaultToThisPrincipalRadioButtonCell) { [preferences setRememberPrincipalFromLastLogin: NO]; [preferences setDefaultName: [nameTextField stringValue]]; [preferences setDefaultRealm: [realmComboBox stringValue]]; } // Behaviors [preferences setAutoRenewTickets: ([autoRenewCheckbox state] == NSOnState)]; [preferences setShowTimeInDockIcon: ([showTimeRemainingInDockCheckbox state] == NSOnState)]; [preferences setTicketWindowDefaultPosition: ([rememberTicketWindowPositionCheckbox state] != NSOnState)]; selectedCell = [launchActionMatrix selectedCell]; if (selectedCell == alwaysOpenListWindowRadioButtonCell) { [preferences setLaunchAction: LaunchActionAlwaysOpenTicketWindow]; } else if (selectedCell == neverOpenListWindowRadioButtonCell) { [preferences setLaunchAction: LaunchActionNeverOpenTicketWindow]; } else if (selectedCell == rememberTicketListWindowOpenessRadioButtonCell) { [preferences setLaunchAction: LaunchActionRememberOpenTicketWindow]; } // Post notification so the rest of the application notices that the preferences changed. [[NSNotificationCenter defaultCenter] postNotificationName: PreferencesDidChangeNotification object: self]; return YES; } // --------------------------------------------------------------------------- - (BOOL) validateLifetimeMaximum: (time_t) lifetimeMaximum lifetimeMinimum: (time_t) lifetimeMinimum renewableMaximum: (time_t) renewableMaximum renewableMinimum: (time_t) renewableMinimum { BOOL valid = YES; if (lifetimeMaximum < lifetimeMinimum) { [self displayError: @"KAppStringBadLifetimeRange"]; valid = NO; } else if (renewableMaximum < renewableMinimum) { [self displayError: @"KAppStringBadRenewableRange"]; valid = NO; } return valid; } // --------------------------------------------------------------------------- - (time_t) lifetimeMaximum { return ([lifetimeMaximumMinutesTextField intValue] * 60 + [lifetimeMaximumHoursTextField intValue] * 3600 + [lifetimeMaximumDaysTextField intValue] * 86400); } // --------------------------------------------------------------------------- - (time_t) lifetimeMinimum { return ([lifetimeMinimumMinutesTextField intValue] * 60 + [lifetimeMinimumHoursTextField intValue] * 3600 + [lifetimeMinimumDaysTextField intValue] * 86400); } // --------------------------------------------------------------------------- - (time_t) renewableMaximum { return ([renewableMaximumMinutesTextField intValue] * 60 + [renewableMaximumHoursTextField intValue] * 3600 + [renewableMaximumDaysTextField intValue] * 86400); } // --------------------------------------------------------------------------- - (time_t) renewableMinimum { return ([renewableMinimumMinutesTextField intValue] * 60 + [renewableMinimumHoursTextField intValue] * 3600 + [renewableMinimumDaysTextField intValue] * 86400); } // --------------------------------------------------------------------------- - (void) displayError: (NSString *) errorKey { NSAlert *alert = [[[NSAlert alloc] init] autorelease]; [alert addButtonWithTitle: NSLocalizedString (@"KAppStringOK", NULL)]; [alert setMessageText: NSLocalizedString (@"KAppStringInvalidTimeRanges", NULL)]; [alert setInformativeText: NSLocalizedString (errorKey, NULL)]; [alert setAlertStyle: NSWarningAlertStyle]; [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: @selector(errorSheetDidEnd:returnCode:contextInfo:) contextInfo: NULL]; } @end