Forgot to add/remove files for Preferences.

CQTexperiment
vspader 2009-03-07 18:38:25 -08:00
parent 2062f3e2d1
commit 4bed0971b3
6 changed files with 224 additions and 720 deletions

View File

@ -16,6 +16,7 @@
171B57DE0C091F2B00F6AFAF /* m4a.icns in Resources */ = {isa = PBXBuildFile; fileRef = 171B57DA0C091F2B00F6AFAF /* m4a.icns */; };
171B57DF0C091F2B00F6AFAF /* mp3.icns in Resources */ = {isa = PBXBuildFile; fileRef = 171B57DB0C091F2B00F6AFAF /* mp3.icns */; };
171B57E00C091F2B00F6AFAF /* ogg.icns in Resources */ = {isa = PBXBuildFile; fileRef = 171B57DC0C091F2B00F6AFAF /* ogg.icns */; };
171CB3DC0F63670D0047EF0A /* PreferencesWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 171CB3DB0F63670D0047EF0A /* PreferencesWindow.m */; };
171EFE8C0F59FEAE000ADC42 /* DockIconController.m in Sources */ = {isa = PBXBuildFile; fileRef = 171EFE8B0F59FEAE000ADC42 /* DockIconController.m */; };
17211A7E0D68B7C500911CA9 /* FileTree.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17211A7C0D68B7C500911CA9 /* FileTree.xib */; };
17249F0F0D82E17700F33392 /* ToggleQueueTitleTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 17249F0E0D82E17700F33392 /* ToggleQueueTitleTransformer.m */; };
@ -114,7 +115,6 @@
17D1B16A0F632ABB00694C57 /* SecondsFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D1B1670F632ABB00694C57 /* SecondsFormatter.m */; };
17D1B1DC0F6330D400694C57 /* Feedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B1DA0F6330D400694C57 /* Feedback.xib */; };
17D1B25D0F633A4F00694C57 /* PreferencePluginController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D1B25C0F633A4F00694C57 /* PreferencePluginController.m */; };
17D1B2600F633B1D00694C57 /* PreferencesWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D1B25F0F633B1D00694C57 /* PreferencesWindow.m */; };
17D1B27D0CF8B2830028F5B5 /* cue.icns in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B2760CF8B2830028F5B5 /* cue.icns */; };
17D1B27E0CF8B2830028F5B5 /* it.icns in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B2770CF8B2830028F5B5 /* it.icns */; };
17D1B27F0CF8B2830028F5B5 /* pls.icns in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B2780CF8B2830028F5B5 /* pls.icns */; };
@ -536,6 +536,8 @@
171B57DA0C091F2B00F6AFAF /* m4a.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = m4a.icns; sourceTree = "<group>"; };
171B57DB0C091F2B00F6AFAF /* mp3.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = mp3.icns; sourceTree = "<group>"; };
171B57DC0C091F2B00F6AFAF /* ogg.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = ogg.icns; sourceTree = "<group>"; };
171CB3DA0F63670D0047EF0A /* PreferencesWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PreferencesWindow.h; path = Preferences/PreferencesWindow.h; sourceTree = "<group>"; };
171CB3DB0F63670D0047EF0A /* PreferencesWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PreferencesWindow.m; path = Preferences/PreferencesWindow.m; sourceTree = "<group>"; };
171EFE8A0F59FEAE000ADC42 /* DockIconController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DockIconController.h; sourceTree = "<group>"; };
171EFE8B0F59FEAE000ADC42 /* DockIconController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DockIconController.m; sourceTree = "<group>"; };
17211A7D0D68B7C500911CA9 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/FileTree.xib; sourceTree = "<group>"; };
@ -676,8 +678,6 @@
17D1B1DB0F6330D400694C57 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/Feedback.xib; sourceTree = "<group>"; };
17D1B25B0F633A4F00694C57 /* PreferencePluginController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PreferencePluginController.h; path = Preferences/PreferencePluginController.h; sourceTree = "<group>"; };
17D1B25C0F633A4F00694C57 /* PreferencePluginController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PreferencePluginController.m; path = Preferences/PreferencePluginController.m; sourceTree = "<group>"; };
17D1B25E0F633B1D00694C57 /* PreferencesWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreferencesWindow.h; sourceTree = "<group>"; };
17D1B25F0F633B1D00694C57 /* PreferencesWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PreferencesWindow.m; sourceTree = "<group>"; };
17D1B2610F633D2C00694C57 /* PreferencePanePlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PreferencePanePlugin.h; path = Preferences/PreferencePanePlugin.h; sourceTree = "<group>"; };
17D1B2760CF8B2830028F5B5 /* cue.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = cue.icns; sourceTree = "<group>"; };
17D1B2770CF8B2830028F5B5 /* it.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = it.icns; sourceTree = "<group>"; };
@ -1349,10 +1349,10 @@
17D1B2610F633D2C00694C57 /* PreferencePanePlugin.h */,
17D1B25B0F633A4F00694C57 /* PreferencePluginController.h */,
17D1B25C0F633A4F00694C57 /* PreferencePluginController.m */,
17D1B25E0F633B1D00694C57 /* PreferencesWindow.h */,
17D1B25F0F633B1D00694C57 /* PreferencesWindow.m */,
8E07AB760AAC930B00A4B32F /* PreferencesController.h */,
8E07AB770AAC930B00A4B32F /* PreferencesController.m */,
171CB3DA0F63670D0047EF0A /* PreferencesWindow.h */,
171CB3DB0F63670D0047EF0A /* PreferencesWindow.m */,
);
name = Preferences;
sourceTree = "<group>";
@ -1915,7 +1915,7 @@
17D1B1690F632ABB00694C57 /* IndexFormatter.m in Sources */,
17D1B16A0F632ABB00694C57 /* SecondsFormatter.m in Sources */,
17D1B25D0F633A4F00694C57 /* PreferencePluginController.m in Sources */,
17D1B2600F633B1D00694C57 /* PreferencesWindow.m in Sources */,
171CB3DC0F63670D0047EF0A /* PreferencesWindow.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,22 @@
//
// PreferencesWindowController.h
// Cog
//
// Created by Vincent Spader on 3/7/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface PreferencesWindow : NSWindow {
NSMutableArray *preferencePaneOrder;
NSMutableDictionary *preferencePanes;
NSMutableDictionary *toolbarItems;
}
- (id)initWithPreferencePanes:(NSArray *)preferencePanes;
- (void)show;
@end

View File

@ -0,0 +1,196 @@
//
// PreferencesWindowController.m
// Cog
//
// Created by Vincent Spader on 3/7/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "PreferencesWindow.h"
#import "PreferencePanePlugin.h"
@interface PreferencesWindow()
- (NSString *)lastPaneDefaultsKey;
- (BOOL)loadPaneNamed:(NSString *)name display:(BOOL)display;
- (void)createToolbar;
@end
@implementation PreferencesWindow
- (id)initWithPreferencePanes:(NSArray *)panes
{
self = [super initWithContentRect:NSMakeRect(0, 0, 350, 200)
styleMask:(NSClosableWindowMask | NSResizableWindowMask)
backing:NSBackingStoreBuffered
defer:NO];
if (self)
{
preferencePaneOrder = [[NSMutableArray alloc] init];
preferencePanes = [[NSMutableDictionary alloc] init];
for (id<PreferencePane> pane in panes) {
[preferencePaneOrder addObject:[pane title]];
[preferencePanes setObject:pane forKey:[pane title]];
}
[self setReleasedWhenClosed:NO];
[self setTitle:@"Preferences"]; // initial default title
[self setShowsToolbarButton: NO];
[self setShowsResizeIndicator:NO];
[self center];
[self createToolbar];
}
return self;
}
- (void)dealloc
{
[preferencePanes release];
[toolbarItems release];
[super dealloc];
}
- (NSString *)lastPaneDefaultsKey
{
return @"LastPreferencePane";
}
-(NSRect)newFrameForNewContentView:(NSView *)view {
NSRect newFrame = [self frame];
newFrame.size.height = [view frame].size.height + ([self frame].size.height - [[self contentView] frame].size.height);
newFrame.size.width = [view frame].size.width;
newFrame.origin.y += ([[self contentView] frame].size.height - [view frame].size.height);
return newFrame;
}
- (void)setContentView:(NSView *)view animate:(BOOL)animate
{
if (animate) {
NSView *tempView = [[NSView alloc] initWithFrame:[[self contentView] frame]];
[self setContentView:tempView];
[tempView release];
}
NSRect newFrame = [self newFrameForNewContentView:view];
[self setFrame:newFrame display:animate animate:animate];
[self setContentView:view];
}
- (BOOL)loadPaneNamed:(NSString *)name display:(BOOL)display
{
id<PreferencePane> paneController = [preferencePanes objectForKey:name];
if (!paneController) {
return NO;
}
NSView *paneView = [paneController view];
if (!paneView) {
return NO;
}
[self setContentView:paneView animate:display];
[self setTitle:name];
// Update defaults
[[NSUserDefaults standardUserDefaults] setObject:name forKey:[self lastPaneDefaultsKey]];
[[self toolbar] setSelectedItemIdentifier:name];
return YES;
}
- (void)createToolbar
{
toolbarItems = [[NSMutableDictionary alloc] init];
for (NSString *name in preferencePaneOrder) {
id<PreferencePane> pane = [preferencePanes objectForKey:name];
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:name];
[item setPaletteLabel:name]; // item's label in the "Customize Toolbar" sheet (not relevant here, but we set it anyway)
[item setLabel:name]; // item's label in the toolbar
[item setToolTip:name];
[item setImage:[pane icon]];
[item setTarget:self];
[item setAction:@selector(toolbarItemClicked:)]; // action called when item is clicked
[toolbarItems setObject:item forKey:name];
[item release];
}
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:[bundleIdentifier stringByAppendingString:@" Preferences Toolbar"]];
[toolbar setDelegate:self];
[toolbar setAllowsUserCustomization:NO];
[toolbar setAutosavesConfiguration:NO];
[toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
[toolbar setSizeMode:NSToolbarSizeModeDefault];
[self setToolbar:toolbar];
[toolbar release];
}
- (void)show
{
NSString *lastPane = [[NSUserDefaults standardUserDefaults] objectForKey:[self lastPaneDefaultsKey]];
if (nil == lastPane) {
if (0 >= [preferencePaneOrder count]) {
NSLog(@"Error: Preference panes not found!");
}
lastPane = [preferencePaneOrder objectAtIndex:0];
}
[self loadPaneNamed:lastPane display:NO];
[self makeKeyAndOrderFront:self];
}
#pragma mark Delegate methods
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
{
return preferencePaneOrder;
}
- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
{
return preferencePaneOrder;
}
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
{
return preferencePaneOrder;
}
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
{
return [toolbarItems objectForKey:itemIdentifier];
}
- (void)toolbarItemClicked:(NSToolbarItem *)item
{
if (![[item itemIdentifier] isEqualToString:[self title]]) {
[self loadPaneNamed:[item itemIdentifier] display:YES];
}
}
@end

View File

@ -1,50 +0,0 @@
#import <Cocoa/Cocoa.h>
@protocol SS_PreferencePaneProtocol
// preferencePanes is called whenever the calling application wants to instantiate preference panes.
// This method returns an array of preference pane instances. This array is autoreleased,
// so the calling application needs to retain whatever it wants to keep.
// If no instances were generated, this returns nil.
+ (NSArray *)preferencePanes;
// paneView returns a preference pane's view. This must not be nil.
- (NSView *)paneView;
// paneName returns the name associated with a preference pane's view.
// This is used as the label of the pane's toolbar item in the Preferences window,
// and as the title of the Preferences window when the pane is selected.
// This must not be nil or an empty string.
- (NSString *)paneName;
// paneIcon returns a preference pane's icon as an NSImage.
// The icon will be scaled to the default size for a toolbar icon (if necessary),
// and shown in the toolbar in the Preferences window.
- (NSImage *)paneIcon;
// paneToolTip returns the ToolTip to be used for a preference pane's icon in the
// Preferences window's toolbar. You can return nil or an empty string to disable
// the ToolTip for this preference pane.
- (NSString *)paneToolTip;
// allowsHorizontalResizing and allowsVerticalResizing determine whether the Preferences window
// will be resizable in the respective directions when the receiver is the visible preference
// pane. The initial size of the receiver's view will be used as the minimum size of the
// Preferences window.
- (BOOL)allowsHorizontalResizing;
- (BOOL)allowsVerticalResizing;
@end

View File

@ -1,76 +0,0 @@
/* SS_PrefsController */
#import <Cocoa/Cocoa.h>
@interface SS_PrefsController : NSObject
{
NSWindow *prefsWindow;
NSMutableDictionary *preferencePanes;
NSMutableArray *panesOrder;
NSString *bundleExtension;
NSString *searchPath;
NSToolbar *prefsToolbar;
NSMutableDictionary *prefsToolbarItems;
NSToolbarDisplayMode toolbarDisplayMode;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2
NSToolbarSizeMode toolbarSizeMode;
#endif
BOOL usesTexturedWindow;
BOOL alwaysShowsToolbar;
BOOL alwaysOpensCentered;
BOOL debug;
}
// Convenience constructors
+ (id)preferencesWithPanesSearchPath:(NSString*)path bundleExtension:(NSString *)ext;
+ (id)preferencesWithBundleExtension:(NSString *)ext;
+ (id)preferencesWithPanesSearchPath:(NSString*)path;
+ (id)preferences;
// Designated initializer
- (id)initWithPanesSearchPath:(NSString*)path bundleExtension:(NSString *)ext;
- (id)initWithBundleExtension:(NSString *)ext;
- (id)initWithPanesSearchPath:(NSString*)path;
- (void)showPreferencesWindow;
- (void)createPreferencesWindowAndDisplay:(BOOL)shouldDisplay;
- (void)createPreferencesWindow;
- (void)destroyPreferencesWindow;
- (BOOL)loadPrefsPaneNamed:(NSString *)name display:(BOOL)disp;
- (BOOL)loadPreferencePaneNamed:(NSString *)name;
- (void)activatePane:(NSString*)path;
- (void)debugLog:(NSString*)msg;
float ToolbarHeightForWindow(NSWindow *window);
- (void)createPrefsToolbar;
- (void)prefsToolbarItemClicked:(NSToolbarItem*)item;
// Accessors
- (NSWindow *)preferencesWindow;
- (NSString *)bundleExtension;
- (NSString *)searchPath;
- (NSArray *)loadedPanes;
- (NSArray *)panesOrder;
- (void)setPanesOrder:(NSArray *)newPanesOrder;
- (BOOL)debug;
- (void)setDebug:(BOOL)newDebug;
- (BOOL)usesTexturedWindow;
- (void)setUsesTexturedWindow:(BOOL)newUsesTexturedWindow;
- (BOOL)alwaysShowsToolbar;
- (void)setAlwaysShowsToolbar:(BOOL)newAlwaysShowsToolbar;
- (BOOL)alwaysOpensCentered;
- (void)setAlwaysOpensCentered:(BOOL)newAlwaysOpensCentered;
- (NSToolbarDisplayMode)toolbarDisplayMode;
- (void)setToolbarDisplayMode:(NSToolbarDisplayMode)displayMode;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2
- (NSToolbarSizeMode)toolbarSizeMode;
- (void)setToolbarSizeMode:(NSToolbarSizeMode)sizeMode;
#endif
@end

View File

@ -1,588 +0,0 @@
#import "SS_PrefsController.h"
#import "SS_PreferencePaneProtocol.h"
@implementation SS_PrefsController
#define Last_Pane_Defaults_Key [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@"_Preferences_Last_Pane_Defaults_Key"]
// ************************************************
// version/init/dealloc/constructors
// ************************************************
+ (int)version
{
return 1; // 28th June 2003
}
+ (id)preferencesWithPanesSearchPath:(NSString*)path bundleExtension:(NSString *)ext
{
return [[[SS_PrefsController alloc] initWithPanesSearchPath:path bundleExtension:ext] autorelease];
}
+ (id)preferencesWithBundleExtension:(NSString *)ext
{
return [[[SS_PrefsController alloc] initWithBundleExtension:ext] autorelease];
}
+ (id)preferencesWithPanesSearchPath:(NSString*)path
{
return [[[SS_PrefsController alloc] initWithPanesSearchPath:path] autorelease];
}
+ (id)preferences
{
return [[[SS_PrefsController alloc] init] autorelease];
}
- (id)init
{
return [self initWithPanesSearchPath:nil bundleExtension:nil];
}
- (id)initWithPanesSearchPath:(NSString*)path
{
return [self initWithPanesSearchPath:path bundleExtension:nil];
}
- (id)initWithBundleExtension:(NSString *)ext
{
return [self initWithPanesSearchPath:nil bundleExtension:ext];
}
// Designated initializer
- (id)initWithPanesSearchPath:(NSString*)path bundleExtension:(NSString *)ext
{
if (self = [super init])
{
[self setDebug:NO];
preferencePanes = [[NSMutableDictionary alloc] init];
panesOrder = [[NSMutableArray alloc] init];
[self setToolbarDisplayMode:NSToolbarDisplayModeIconAndLabel];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2
[self setToolbarSizeMode:NSToolbarSizeModeDefault];
#endif
[self setUsesTexturedWindow:NO];
[self setAlwaysShowsToolbar:NO];
[self setAlwaysOpensCentered:YES];
if (!ext || [ext isEqualToString:@""]) {
bundleExtension = [[NSString alloc] initWithString:@"preferencePane"];
} else {
bundleExtension = [ext retain];
}
if (!path || [path isEqualToString:@""]) {
searchPath = [[NSString alloc] initWithString:[[NSBundle mainBundle] resourcePath]];
} else {
searchPath = [path retain];
}
// Read PreferencePanes
if (searchPath) {
NSEnumerator* enumerator = [[NSBundle pathsForResourcesOfType:bundleExtension inDirectory:searchPath] objectEnumerator];
NSString* panePath;
while ((panePath = [enumerator nextObject])) {
[self activatePane:panePath];
}
}
return self;
}
return nil;
}
- (void)dealloc
{
if (prefsWindow) {
[prefsWindow release];
}
if (prefsToolbar) {
[prefsToolbar release];
}
if (prefsToolbarItems) {
[prefsToolbarItems release];
}
if (preferencePanes) {
[preferencePanes release];
}
if (panesOrder) {
[panesOrder release];
}
if (bundleExtension) {
[bundleExtension release];
}
if (searchPath) {
[searchPath release];
}
[super dealloc];
}
// ************************************************
// Preferences methods
// ************************************************
- (void)showPreferencesWindow
{
[self createPreferencesWindowAndDisplay:YES];
}
- (void)createPreferencesWindow
{
[self createPreferencesWindowAndDisplay:YES];
}
- (void)createPreferencesWindowAndDisplay:(BOOL)shouldDisplay
{
if (prefsWindow) {
if (alwaysOpensCentered && ![prefsWindow isVisible]) {
[prefsWindow center];
}
[prefsWindow makeKeyAndOrderFront:nil];
return;
}
// Create prefs window
unsigned int styleMask = (NSClosableWindowMask | NSResizableWindowMask);
if (usesTexturedWindow) {
styleMask = (styleMask | NSTexturedBackgroundWindowMask);
}
prefsWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 350, 200)
styleMask:styleMask
backing:NSBackingStoreBuffered
defer:NO];
[prefsWindow setReleasedWhenClosed:NO];
[prefsWindow setTitle:@"Preferences"]; // initial default title
[prefsWindow setShowsToolbarButton: NO];
[prefsWindow center];
[self createPrefsToolbar];
// Register defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (panesOrder && ([panesOrder count] > 0)) {
NSMutableDictionary *defaultValues = [NSMutableDictionary dictionary];
[defaultValues setObject:[panesOrder objectAtIndex:0] forKey:Last_Pane_Defaults_Key];
[defaults registerDefaults:defaultValues];
}
// Load last view
NSString *lastViewName = [defaults objectForKey:Last_Pane_Defaults_Key];
if ([panesOrder containsObject:lastViewName] && [self loadPrefsPaneNamed:lastViewName display:NO]) {
if (shouldDisplay) {
[prefsWindow makeKeyAndOrderFront:nil];
}
return;
}
[self debugLog:[NSString stringWithFormat:@"Could not load last-used preference pane \"%@\". Trying to load another pane instead.", lastViewName]];
// Try to load each prefpane in turn if loading the last-viewed one fails.
NSEnumerator* panes = [panesOrder objectEnumerator];
NSString *pane;
while (pane = [panes nextObject]) {
if (![pane isEqualToString:lastViewName]) {
if ([self loadPrefsPaneNamed:pane display:NO]) {
if (shouldDisplay) {
[prefsWindow makeKeyAndOrderFront:nil];
}
return;
}
}
}
[self debugLog:[NSString stringWithFormat:@"Could not load any valid preference panes. The preference pane bundle extension was \"%@\" and the search path was: %@", bundleExtension, searchPath]];
// Show alert dialog.
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
NSRunAlertPanel(@"Preferences",
[NSString stringWithFormat:@"Preferences are not available for %@.", appName],
@"OK",
nil,
nil);
[prefsWindow release];
prefsWindow = nil;
}
- (void)destroyPreferencesWindow
{
if (prefsWindow) {
[prefsWindow release];
}
prefsWindow = nil;
}
- (void)activatePane:(NSString*)path {
NSBundle* paneBundle = [NSBundle bundleWithPath:path];
if (paneBundle) {
NSDictionary* paneDict = [paneBundle infoDictionary];
NSString* paneName = [paneDict objectForKey:@"NSPrincipalClass"];
if (paneName) {
Class paneClass = NSClassFromString(paneName);
if (!paneClass) {
paneClass = [paneBundle principalClass];
if ([paneClass conformsToProtocol:@protocol(SS_PreferencePaneProtocol)] && [paneClass isKindOfClass:[NSObject class]]) {
NSArray *panes = [paneClass preferencePanes];
NSEnumerator *enumerator = [panes objectEnumerator];
id <SS_PreferencePaneProtocol> aPane;
while (aPane = [enumerator nextObject]) {
[panesOrder addObject:[aPane paneName]];
[preferencePanes setObject:aPane forKey:[aPane paneName]];
}
} else {
[self debugLog:[NSString stringWithFormat:@"Did not load bundle: %@ because its Principal Class is either not an NSObject subclass, or does not conform to the PreferencePane Protocol.", paneBundle]];
}
} else {
[self debugLog:[NSString stringWithFormat:@"Did not load bundle: %@ because its Principal Class was already used in another Preference pane.", paneBundle]];
}
} else {
[self debugLog:[NSString stringWithFormat:@"Could not obtain name of Principal Class for bundle: %@", paneBundle]];
}
} else {
[self debugLog:[NSString stringWithFormat:@"Could not initialize bundle: %@", paneBundle]];
}
}
- (BOOL)loadPreferencePaneNamed:(NSString *)name
{
return [self loadPrefsPaneNamed:(NSString *)name display:YES];
}
- (NSArray *)loadedPanes
{
if (preferencePanes) {
return [preferencePanes allKeys];
}
return nil;
}
- (BOOL)loadPrefsPaneNamed:(NSString *)name display:(BOOL)disp
{
if (!prefsWindow) {
NSBeep();
[self debugLog:[NSString stringWithFormat:@"Could not load \"%@\" preference pane because the Preferences window seems to no longer exist.", name]];
return NO;
}
id tempPane = nil;
tempPane = [preferencePanes objectForKey:name];
if (!tempPane) {
[self debugLog:[NSString stringWithFormat:@"Could not load preference pane \"%@\", because that pane does not exist.", name]];
return NO;
}
NSView *prefsView = nil;
prefsView = [tempPane paneView];
if (!prefsView) {
[self debugLog:[NSString stringWithFormat:@"Could not load \"%@\" preference pane because its view could not be loaded from the bundle.", name]];
return NO;
}
// Get rid of old view before resizing, for display purposes.
if (disp) {
NSView *tempView = [[NSView alloc] initWithFrame:[[prefsWindow contentView] frame]];
[prefsWindow setContentView:tempView];
[tempView release];
}
// Preserve upper left point of window during resize.
NSRect newFrame = [prefsWindow frame];
newFrame.size.height = [prefsView frame].size.height + ([prefsWindow frame].size.height - [[prefsWindow contentView] frame].size.height);
newFrame.size.width = [prefsView frame].size.width;
newFrame.origin.y += ([[prefsWindow contentView] frame].size.height - [prefsView frame].size.height);
id <SS_PreferencePaneProtocol> pane = [preferencePanes objectForKey:name];
[prefsWindow setShowsResizeIndicator:([pane allowsHorizontalResizing] || [pane allowsHorizontalResizing])];
[prefsWindow setFrame:newFrame display:disp animate:disp];
[prefsWindow setContentView:prefsView];
// Set appropriate resizing on window.
NSSize theSize = [prefsWindow frame].size;
theSize.height -= ToolbarHeightForWindow(prefsWindow);
[prefsWindow setMinSize:theSize];
BOOL canResize = NO;
if ([pane allowsHorizontalResizing]) {
theSize.width = FLT_MAX;
canResize = YES;
}
if ([pane allowsVerticalResizing]) {
theSize.height = FLT_MAX;
canResize = YES;
}
[prefsWindow setMaxSize:theSize];
[prefsWindow setShowsResizeIndicator:canResize];
if ((prefsToolbarItems && ([prefsToolbarItems count] > 1)) || alwaysShowsToolbar) {
[prefsWindow setTitle:name];
}
// Update defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:name forKey:Last_Pane_Defaults_Key];
[prefsToolbar setSelectedItemIdentifier: name];
return YES;
}
- (void)debugLog:(NSString*)msg
{
if (debug) {
NSLog(@"[--- PREFERENCES DEBUG MESSAGE ---]\r%@\r\r", msg);
}
}
// ************************************************
// Prefs Toolbar methods
// ************************************************
float ToolbarHeightForWindow(NSWindow *window)
{
NSToolbar *toolbar;
float toolbarHeight = 0.0;
NSRect windowFrame;
toolbar = [window toolbar];
if(toolbar && [toolbar isVisible])
{
windowFrame = [NSWindow contentRectForFrameRect:[window frame]
styleMask:[window styleMask]];
toolbarHeight = NSHeight(windowFrame)
- NSHeight([[window contentView] frame]);
}
return toolbarHeight;
}
- (void)createPrefsToolbar
{
// Create toolbar items
prefsToolbarItems = [[NSMutableDictionary alloc] init];
NSEnumerator *itemEnumerator = [panesOrder objectEnumerator];
NSString *name;
NSImage *itemImage;
while (name = [itemEnumerator nextObject]) {
if ([preferencePanes objectForKey:name] != nil) {
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:name];
[item setPaletteLabel:name]; // item's label in the "Customize Toolbar" sheet (not relevant here, but we set it anyway)
[item setLabel:name]; // item's label in the toolbar
NSString *tempTip = [[preferencePanes objectForKey:name] paneToolTip];
if (!tempTip || [tempTip isEqualToString:@""]) {
[item setToolTip:nil];
} else {
[item setToolTip:tempTip];
}
itemImage = [[preferencePanes objectForKey:name] paneIcon];
[item setImage:itemImage];
[item setTarget:self];
[item setAction:@selector(prefsToolbarItemClicked:)]; // action called when item is clicked
[prefsToolbarItems setObject:item forKey:name]; // add to items
[item release];
} else {
[self debugLog:[NSString stringWithFormat:@"Could not create toolbar item for preference pane \"%@\", because that pane does not exist.", name]];
}
}
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
prefsToolbar = [[NSToolbar alloc] initWithIdentifier:[bundleIdentifier stringByAppendingString:@"_Preferences_Toolbar_Identifier"]];
[prefsToolbar setDelegate:self];
[prefsToolbar setAllowsUserCustomization:NO];
[prefsToolbar setAutosavesConfiguration:NO];
[prefsToolbar setDisplayMode:toolbarDisplayMode];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2
[prefsToolbar setSizeMode:toolbarSizeMode];
#endif
if ((prefsToolbarItems && ([prefsToolbarItems count] > 1)) || alwaysShowsToolbar) {
[prefsWindow setToolbar:prefsToolbar];
} else if (!alwaysShowsToolbar && prefsToolbarItems && ([prefsToolbarItems count] == 1)) {
[self debugLog:@"Not showing toolbar in Preferences window because there is only one preference pane loaded. You can override this behaviour using -[setAlwaysShowsToolbar:YES]."];
}
}
- (NSToolbarDisplayMode)toolbarDisplayMode
{
return toolbarDisplayMode;
}
- (void)setToolbarDisplayMode:(NSToolbarDisplayMode)displayMode
{
toolbarDisplayMode = displayMode;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2
- (NSToolbarSizeMode)toolbarSizeMode
{
return toolbarSizeMode;
}
- (void)setToolbarSizeMode:(NSToolbarSizeMode)sizeMode
{
toolbarSizeMode = sizeMode;
}
#endif
- (void)prefsToolbarItemClicked:(NSToolbarItem*)item
{
if (![[item itemIdentifier] isEqualToString:[prefsWindow title]]) {
[self loadPrefsPaneNamed:[item itemIdentifier] display:YES];
}
}
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
{
return panesOrder;
}
- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
{
return panesOrder;
}
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
{
return panesOrder;
}
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
{
return [prefsToolbarItems objectForKey:itemIdentifier];
}
// ************************************************
// Accessors
// ************************************************
- (NSWindow *)preferencesWindow
{
return prefsWindow;
}
- (NSString *)bundleExtension
{
return bundleExtension;
}
- (NSString *)searchPath
{
return searchPath;
}
- (NSArray *)panesOrder
{
return panesOrder;
}
- (void)setPanesOrder:(NSArray *)newPanesOrder
{
[panesOrder removeAllObjects];
NSEnumerator *enumerator = [newPanesOrder objectEnumerator];
NSString *name;
while (name = [enumerator nextObject]) {
if ([preferencePanes objectForKey:name] != nil) {
[panesOrder addObject:name];
} else {
[self debugLog:[NSString stringWithFormat:@"Did not add preference pane \"%@\" to the toolbar ordering array, because that pane does not exist.", name]];
}
}
}
- (BOOL)debug
{
return debug;
}
- (void)setDebug:(BOOL)newDebug
{
debug = newDebug;
}
- (BOOL)usesTexturedWindow
{
return usesTexturedWindow;
}
- (void)setUsesTexturedWindow:(BOOL)newUsesTexturedWindow
{
usesTexturedWindow = newUsesTexturedWindow;
}
- (BOOL)alwaysShowsToolbar
{
return alwaysShowsToolbar;
}
- (void)setAlwaysShowsToolbar:(BOOL)newAlwaysShowsToolbar
{
alwaysShowsToolbar = newAlwaysShowsToolbar;
}
- (BOOL)alwaysOpensCentered
{
return alwaysOpensCentered;
}
- (void)setAlwaysOpensCentered:(BOOL)newAlwaysOpensCentered
{
alwaysOpensCentered = newAlwaysOpensCentered;
}
@end