Cog/Preferences/PreferencesWindow.m
Christopher Snowhill c23bece62c Reintroducing App Sandbox, and more
- Implemented App Sandboxing in a more friendly manner.
- All sandboxed paths will need to be set in Preferences. Set as loose
  a path as you want. The shortest path will be preferred.
- Removed Last.fm client support, as it was non-functional by now,
  unfortunately. Maybe something better can come in the future.
- Added support for insecure SSL to the HTTP/S reader, in case anyone
  needs streams which are "protected" by self-signed or expired
  certificates, without having to futz around by adding certificates to
  the system settings, especially for expired certificates that can't
  otherwise be dodged this way.

If you want to import your old playlists to the new version, copy the
contents of `~/Library/Application Support/Cog` to the alternate sandbox
path: `~/Library/Containers/org.cogx.cog/Data/Library/Application `...
...continued...`Support/Cog`. The preferences file will migrate to the
new version automatically.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-20 03:35:29 -07:00

181 lines
5 KiB
Objective-C

//
// PreferencesWindowController.m
// Cog
//
// Created by Vincent Spader on 3/7/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "PreferencesWindow.h"
#import "PreferencePanePlugin.h"
#import "Logging.h"
@interface PreferencesWindow ()
- (NSString *)lastPaneDefaultsKey;
- (BOOL)loadPaneNamed:(NSString *)name display:(BOOL)display;
- (void)createToolbar;
@end
@implementation PreferencesWindow {
NSMutableArray<NSToolbarItemIdentifier> *preferencePaneOrder;
NSMutableDictionary<NSToolbarItemIdentifier, id<PreferencePane>> *preferencePanes;
NSMutableDictionary<NSToolbarItemIdentifier, NSToolbarItem *> *toolbarItems;
}
- (instancetype)initWithPreferencePanes:(NSArray<id<PreferencePane>> *)panes {
NSWindowStyleMask windowStyleMask =
(NSWindowStyleMaskClosable | NSWindowStyleMaskTitled);
self = [super initWithContentRect:NSMakeRect(0, 0, 530, 300)
styleMask:windowStyleMask
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:NSLocalizedString(@"PreferencesTitle", @"")];
[self center];
if(@available(macOS 11, *)) {
[self setToolbarStyle:NSWindowToolbarStylePreference];
}
[self createToolbar];
}
return self;
}
- (NSString *)lastPaneDefaultsKey {
return @"LastPreferencePane";
}
- (void)setContentView:(NSView *)view animate:(BOOL)animate {
NSSize newSize = view.bounds.size;
NSSize oldSize = [self contentView].bounds.size;
CGFloat diff = newSize.height - oldSize.height;
NSRect newFrame = [self frame];
newFrame.size.height += diff;
newFrame.origin.y -= diff;
if(animate) {
[self setContentView:nil];
}
[self setFrame:newFrame display:animate animate:animate];
[self setContentView:view];
[self setContentSize:newSize];
}
- (BOOL)loadPaneNamed:(NSString *)name display:(BOOL)display {
id<PreferencePane> paneController = preferencePanes[name];
if(!paneController) {
return NO;
}
NSView *paneView = [paneController view];
if(!paneView || [self contentView] == paneView) {
return NO;
}
[self setContentView:paneView animate:display];
// 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[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[name] = item;
}
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];
}
- (void)show {
NSString *lastPane = [[NSUserDefaults standardUserDefaults] objectForKey:[self lastPaneDefaultsKey]];
// Previous pane names migrations.
if([lastPane isEqualToString:NSLocalizedPrefString(@"Growl")]) {
lastPane = NSLocalizedPrefString(@"Notifications");
}
if([lastPane isEqualToString:NSLocalizedPrefString(@"Last.fm")] ||
[lastPane isEqualToString:NSLocalizedPrefString(@"Scrobble")]) {
lastPane = NSLocalizedPrefString(@"General");
}
if(nil == lastPane) {
if(0 >= [preferencePaneOrder count]) {
ALog(@"Error: Preference panes not found!");
}
lastPane = preferencePaneOrder[0];
}
[self loadPaneNamed:lastPane display:NO];
[self makeKeyAndOrderFront:self];
}
// Close on Esc pressed.
- (void)cancelOperation:(id)sender {
[self close];
}
#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[itemIdentifier];
}
- (void)toolbarItemClicked:(NSToolbarItem *)item {
[self loadPaneNamed:[item itemIdentifier] display:YES];
}
@end