/* ** iTermDisplayProfileMgr.m ** ** Copyright (c) 2002, 2003, 2004 ** ** Author: Ujwal S. Setlur ** ** Project: iTerm ** ** Description: implements the display profile manager. ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #import static iTermDisplayProfileMgr *singleInstance = nil; @implementation iTermDisplayProfileMgr + (id) singleInstance { if(singleInstance == nil) { singleInstance = [[iTermDisplayProfileMgr alloc] init]; } return (singleInstance); } - (id) init { self = [super init]; if(!self) return (nil); profiles = [[NSMutableDictionary alloc] init]; return (self); } - (void) dealloc { [profiles release]; [super dealloc]; } - (NSMutableDictionary *) profiles { return (profiles); } - (void) setProfiles: (NSMutableDictionary *) aDict { NSEnumerator *keyEnumerator; NSMutableDictionary *mappingDict; NSString *profileName; NSDictionary *sourceDict; // recursively copy the dictionary to ensure mutability if(aDict != nil) { keyEnumerator = [aDict keyEnumerator]; while((profileName = [keyEnumerator nextObject]) != nil) { sourceDict = [aDict objectForKey: profileName]; mappingDict = [[NSMutableDictionary alloc] initWithDictionary: sourceDict]; [profiles setObject: mappingDict forKey: profileName]; [mappingDict release]; } } else // if we don't have any profile, create a default profile { NSMutableDictionary *aProfile; NSString *defaultName; defaultName = NSLocalizedStringFromTableInBundle(@"Default",@"iTerm", [NSBundle bundleForClass: [self class]], @"Display Profiles"); aProfile = [[NSMutableDictionary alloc] init]; [profiles setObject: aProfile forKey: defaultName]; [aProfile release]; [aProfile setObject: @"Yes" forKey: @"Default Profile"]; [self setColor: [NSColor textColor] forType: TYPE_FOREGROUND_COLOR forProfile: defaultName]; [self setColor: [NSColor textBackgroundColor] forType: TYPE_BACKGROUND_COLOR forProfile: defaultName]; [self setColor: [NSColor redColor] forType: TYPE_BOLD_COLOR forProfile: defaultName]; [self setColor: [NSColor selectedTextBackgroundColor] forType: TYPE_SELECTION_COLOR forProfile: defaultName]; [self setColor: [NSColor selectedTextColor] forType: TYPE_SELECTED_TEXT_COLOR forProfile: defaultName]; [self setColor: [NSColor textColor] forType: TYPE_CURSOR_COLOR forProfile: defaultName]; [self setColor: [NSColor textBackgroundColor] forType: TYPE_CURSOR_TEXT_COLOR forProfile: defaultName]; [self setColor: [NSColor blackColor] forType: TYPE_ANSI_0_COLOR forProfile: defaultName]; [self setColor: [NSColor redColor] forType: TYPE_ANSI_1_COLOR forProfile: defaultName]; [self setColor: [NSColor greenColor] forType: TYPE_ANSI_2_COLOR forProfile: defaultName]; [self setColor: [NSColor yellowColor] forType: TYPE_ANSI_3_COLOR forProfile: defaultName]; [self setColor: [NSColor blueColor] forType: TYPE_ANSI_4_COLOR forProfile: defaultName]; [self setColor: [NSColor magentaColor] forType: TYPE_ANSI_5_COLOR forProfile: defaultName]; [self setColor: [NSColor cyanColor] forType: TYPE_ANSI_6_COLOR forProfile: defaultName]; [self setColor: [NSColor whiteColor] forType: TYPE_ANSI_7_COLOR forProfile: defaultName]; [self setColor: [[NSColor blackColor] highlightWithLevel: 0.5] forType: TYPE_ANSI_8_COLOR forProfile: defaultName]; [self setColor: [[NSColor redColor] highlightWithLevel: 0.5] forType: TYPE_ANSI_9_COLOR forProfile: defaultName]; [self setColor: [[NSColor greenColor] highlightWithLevel: 0.5] forType: TYPE_ANSI_10_COLOR forProfile: defaultName]; [self setColor: [[NSColor yellowColor] highlightWithLevel: 0.5] forType: TYPE_ANSI_11_COLOR forProfile: defaultName]; [self setColor: [[NSColor blueColor] highlightWithLevel: 0.5] forType: TYPE_ANSI_12_COLOR forProfile: defaultName]; [self setColor: [[NSColor magentaColor] highlightWithLevel: 0.5] forType: TYPE_ANSI_13_COLOR forProfile: defaultName]; [self setColor: [[NSColor cyanColor] highlightWithLevel: 0.5] forType: TYPE_ANSI_14_COLOR forProfile: defaultName]; [self setColor: [[NSColor whiteColor] highlightWithLevel: 0.5] forType: TYPE_ANSI_15_COLOR forProfile: defaultName]; [self setWindowColumns: 80 forProfile: defaultName]; [self setWindowRows: 24 forProfile: defaultName]; [self setWindowAntiAlias: YES forProfile: defaultName]; [self setWindowHorizontalCharSpacing: 1.0 forProfile: defaultName]; [self setWindowVerticalCharSpacing: 1.0 forProfile: defaultName]; } } - (NSString *) defaultProfileName { NSDictionary *aProfile; NSEnumerator *keyEnumerator; NSString *aKey, *aProfileName; keyEnumerator = [profiles keyEnumerator]; aProfileName = nil; while ((aKey = [keyEnumerator nextObject])) { aProfile = [profiles objectForKey: aKey]; if([self isDefaultProfile: aKey]) { aProfileName = aKey; break; } } return (aProfileName); } - (void) addProfileWithName: (NSString *) newProfile copyProfile: (NSString *) sourceProfile { NSMutableDictionary *aMutableDict, *aProfile; if([sourceProfile length] > 0 && [newProfile length] > 0) { aProfile = [profiles objectForKey: sourceProfile]; aMutableDict = [[NSMutableDictionary alloc] initWithDictionary: aProfile]; [aMutableDict removeObjectForKey: @"Default Profile"]; [profiles setObject: aMutableDict forKey: newProfile]; [aMutableDict release]; } } - (void) deleteProfileWithName: (NSString *) profileName { if([profileName length] <= 0) return; [profiles removeObjectForKey: profileName]; } - (BOOL) isDefaultProfile: (NSString *) profileName { NSDictionary *aProfile; if([profileName length] <= 0) return (NO); aProfile = [profiles objectForKey: profileName]; return ([[aProfile objectForKey: @"Default Profile"] isEqualToString: @"Yes"]); } - (NSColor *) color: (int) type forProfile: (NSString *) profileName { NSDictionary *aProfile; NSDictionary *colorDict; NSColor *aColor; if([profileName length] <= 0) return (nil); aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return (nil); switch (type) { case TYPE_ANSI_0_COLOR: case TYPE_ANSI_1_COLOR: case TYPE_ANSI_2_COLOR: case TYPE_ANSI_3_COLOR: case TYPE_ANSI_4_COLOR: case TYPE_ANSI_5_COLOR: case TYPE_ANSI_6_COLOR: case TYPE_ANSI_7_COLOR: case TYPE_ANSI_8_COLOR: case TYPE_ANSI_9_COLOR: case TYPE_ANSI_10_COLOR: case TYPE_ANSI_11_COLOR: case TYPE_ANSI_12_COLOR: case TYPE_ANSI_13_COLOR: case TYPE_ANSI_14_COLOR: case TYPE_ANSI_15_COLOR: colorDict = [aProfile objectForKey: [NSString stringWithFormat: @"Ansi %d Color", type]]; break; case TYPE_FOREGROUND_COLOR: colorDict = [aProfile objectForKey: @"Foreground Color"]; break; case TYPE_BACKGROUND_COLOR: colorDict = [aProfile objectForKey: @"Background Color"]; break; case TYPE_BOLD_COLOR: colorDict = [aProfile objectForKey: @"Bold Color"]; break; case TYPE_SELECTION_COLOR: colorDict = [aProfile objectForKey: @"Selection Color"]; break; case TYPE_SELECTED_TEXT_COLOR: colorDict = [aProfile objectForKey: @"Selected Text Color"]; break; case TYPE_CURSOR_COLOR: colorDict = [aProfile objectForKey: @"Cursor Color"]; break; case TYPE_CURSOR_TEXT_COLOR: colorDict = [aProfile objectForKey: @"Cursor Text Color"]; break; default: colorDict = nil; break; } if(colorDict != nil) { float red, green, blue; NSNumber *aNumber; red = green = blue = 0; aNumber = [colorDict objectForKey: @"Red Component"]; if(aNumber != nil) red = [aNumber floatValue]; aNumber = [colorDict objectForKey: @"Green Component"]; if(aNumber != nil) green = [aNumber floatValue]; aNumber = [colorDict objectForKey: @"Blue Component"]; if(aNumber != nil) blue = [aNumber floatValue]; aColor = [NSColor colorWithCalibratedRed: red green: green blue: blue alpha: 1.0]; } else aColor = [NSColor blackColor]; return (aColor); } - (void) setColor: (NSColor *) aColor forType: (int) type forProfile: (NSString *) profileName { NSMutableDictionary *aProfile; NSString *key = nil; if(aColor == nil) return; if([profileName length] <= 0) return; aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return; switch (type) { case TYPE_ANSI_0_COLOR: case TYPE_ANSI_1_COLOR: case TYPE_ANSI_2_COLOR: case TYPE_ANSI_3_COLOR: case TYPE_ANSI_4_COLOR: case TYPE_ANSI_5_COLOR: case TYPE_ANSI_6_COLOR: case TYPE_ANSI_7_COLOR: case TYPE_ANSI_8_COLOR: case TYPE_ANSI_9_COLOR: case TYPE_ANSI_10_COLOR: case TYPE_ANSI_11_COLOR: case TYPE_ANSI_12_COLOR: case TYPE_ANSI_13_COLOR: case TYPE_ANSI_14_COLOR: case TYPE_ANSI_15_COLOR: key = [NSString stringWithFormat: @"Ansi %d Color", type]; break; case TYPE_FOREGROUND_COLOR: key = @"Foreground Color"; break; case TYPE_BACKGROUND_COLOR: key = @"Background Color"; break; case TYPE_BOLD_COLOR: key = @"Bold Color"; break; case TYPE_SELECTION_COLOR: key = @"Selection Color"; break; case TYPE_SELECTED_TEXT_COLOR: key = @"Selected Text Color"; break; case TYPE_CURSOR_COLOR: key = @"Cursor Color"; break; case TYPE_CURSOR_TEXT_COLOR: key = @"Cursor Text Color"; break; default: key = nil; break; } if(key != nil) { NSMutableDictionary *colorDict; NSColor *rgbColor; rgbColor = [aColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; if(rgbColor == nil) { NSLog(@"%s: could not convert color to RGB color!", __PRETTY_FUNCTION__); return; } colorDict = [[NSMutableDictionary alloc] init]; [colorDict setObject: [NSNumber numberWithFloat: [rgbColor redComponent]] forKey: @"Red Component"]; [colorDict setObject: [NSNumber numberWithFloat: [rgbColor greenComponent]] forKey: @"Green Component"]; [colorDict setObject: [NSNumber numberWithFloat: [rgbColor blueComponent]] forKey: @"Blue Component"]; [aProfile setObject: colorDict forKey: key]; [colorDict release]; } } - (float) transparencyForProfile: (NSString *) profileName { return ([self _floatValueForKey: @"Transparency" inProfile: profileName]); } - (void) setTransparency: (float) transparency forProfile: (NSString *) profileName { [self _setFloatValue: transparency forKey: @"Transparency" inProfile: profileName]; } - (NSString *) backgroundImageForProfile: (NSString *) profileName { NSDictionary *aProfile; if([profileName length] <= 0) return (nil); aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return (nil); return ([aProfile objectForKey: @"Background Image"]); } - (void) setBackgroundImage: (NSString *) imagePath forProfile: (NSString *) profileName { NSMutableDictionary *aProfile; if([profileName length] <= 0) return; aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return; if([imagePath length] > 0) [aProfile setObject: imagePath forKey: @"Background Image"]; else [aProfile removeObjectForKey: @"Background Image"]; } - (NSFont *) windowFontForProfile: (NSString *) profileName { NSDictionary *aProfile; float fontSize; const char *utf8String; char utf8FontName[128]; NSFont *aFont; if([profileName length] <= 0) return ([NSFont userFixedPitchFontOfSize: 0.0]); aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return ([NSFont userFixedPitchFontOfSize: 0.0]); if([aProfile objectForKey: @"Font"] == nil) return ([NSFont userFixedPitchFontOfSize: 0.0]); utf8String = [[aProfile objectForKey: @"Font"] UTF8String]; sscanf(utf8String, "%s %g", utf8FontName, &fontSize); aFont = [NSFont fontWithName: [NSString stringWithFormat: @"%s", utf8FontName] size: fontSize]; return (aFont); } - (void) setWindowFont: (NSFont *) font forProfile: (NSString *) profileName { NSMutableDictionary *aProfile; // NSLog(@"%s", __PRETTY_FUNCTION__); if([profileName length] <= 0 || font == nil) return; aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return; [aProfile setObject: [NSString stringWithFormat: @"%@ %g", [font fontName], [font pointSize]] forKey: @"Font"]; } - (NSFont *) windowNAFontForProfile: (NSString *) profileName { NSDictionary *aProfile; float fontSize; const char *utf8String; char utf8FontName[128]; NSFont *aFont; if([profileName length] <= 0) return ([NSFont userFixedPitchFontOfSize: 0.0]); aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return ([NSFont userFixedPitchFontOfSize: 0.0]); if([aProfile objectForKey: @"NAFont"] == nil) return ([NSFont userFixedPitchFontOfSize: 0.0]); utf8String = [[aProfile objectForKey: @"NAFont"] UTF8String]; sscanf(utf8String, "%s %g", utf8FontName, &fontSize); aFont = [NSFont fontWithName: [NSString stringWithFormat: @"%s", utf8FontName] size: fontSize]; return (aFont); } - (void) setWindowNAFont: (NSFont *) font forProfile: (NSString *) profileName { NSMutableDictionary *aProfile; // NSLog(@"%s", __PRETTY_FUNCTION__); if([profileName length] <= 0 || font == nil) return; aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return; [aProfile setObject: [NSString stringWithFormat: @"%@ %g", [font fontName], [font pointSize]] forKey: @"NAFont"]; } - (int) windowColumnsForProfile: (NSString *) profileName { return ([self _intValueForKey: @"Columns" inProfile: profileName]); } - (void) setWindowColumns: (int) columns forProfile: (NSString *) profileName { [self _setIntValue: columns forKey: @"Columns" inProfile: profileName]; } - (int) windowRowsForProfile: (NSString *) profileName { return ([self _intValueForKey: @"Rows" inProfile: profileName]); } - (void) setWindowRows: (int) rows forProfile: (NSString *) profileName { [self _setIntValue: rows forKey: @"Rows" inProfile: profileName]; } - (float) windowHorizontalCharSpacingForProfile: (NSString *) profileName { return ([self _floatValueForKey: @"Horizontal Character Spacing" inProfile: profileName]); } - (void) setWindowHorizontalCharSpacing: (float) spacing forProfile: (NSString *) profileName { [self _setFloatValue: spacing forKey: @"Horizontal Character Spacing" inProfile: profileName]; } - (float) windowVerticalCharSpacingForProfile: (NSString *) profileName { return ([self _floatValueForKey: @"Vertical Character Spacing" inProfile: profileName]); } - (void) setWindowVerticalCharSpacing: (float) spacing forProfile: (NSString *) profileName { [self _setFloatValue: spacing forKey: @"Vertical Character Spacing" inProfile: profileName]; } - (BOOL) windowAntiAliasForProfile: (NSString *) profileName { return ([self _intValueForKey: @"Anti Alias" inProfile: profileName]); } - (void) setWindowAntiAlias: (BOOL) antiAlias forProfile: (NSString *) profileName { [self _setIntValue: antiAlias forKey: @"Anti Alias" inProfile: profileName]; } - (BOOL) disableBoldForProfile: (NSString *) profileName { return ([self _intValueForKey: @"Disable Bold" inProfile: profileName]); } - (void) setDisableBold: (BOOL) bFlag forProfile: (NSString *) profileName { [self _setIntValue: bFlag forKey: @"Disable Bold" inProfile: profileName]; } @end @implementation iTermDisplayProfileMgr (Private) - (float) _floatValueForKey: (NSString *) key inProfile: (NSString *) profileName { NSDictionary *aProfile; NSNumber *aNumber; if([profileName length] <= 0 || [key length] <= 0) return (0.0); aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return (0.0); aNumber = [aProfile objectForKey: key]; if(aNumber == nil) return (0.0); return ([aNumber floatValue]); } - (void) _setFloatValue: (float) fval forKey: (NSString *) key inProfile: (NSString *) profileName { NSMutableDictionary *aProfile; NSNumber *aNumber; if([profileName length] <= 0 || [key length] <= 0) return; aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return; aNumber = [NSNumber numberWithFloat: fval]; [aProfile setObject: aNumber forKey: key]; } - (int) _intValueForKey: (NSString *) key inProfile: (NSString *) profileName { NSDictionary *aProfile; NSNumber *aNumber; if([profileName length] <= 0 || [key length] <= 0) return (0); aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return (0); aNumber = [aProfile objectForKey: key]; if(aNumber == nil) return (0); return ([aNumber intValue]); } - (void) _setIntValue: (int) ival forKey: (NSString *) key inProfile: (NSString *) profileName { NSMutableDictionary *aProfile; NSNumber *aNumber; if([profileName length] <= 0 || [key length] <= 0) return; aProfile = [profiles objectForKey: profileName]; if(aProfile == nil) return; aNumber = [NSNumber numberWithInt: ival]; [aProfile setObject: aNumber forKey: key]; } @end