2005-06-02 18:16:43 +00:00
|
|
|
#import "AppController.h"
|
2016-05-05 20:05:39 +00:00
|
|
|
#import "FileTreeController.h"
|
2013-10-11 10:03:23 +00:00
|
|
|
#import "FileTreeViewController.h"
|
2016-05-05 20:05:39 +00:00
|
|
|
#import "FileTreeOutlineView.h"
|
2007-03-09 01:16:06 +00:00
|
|
|
#import "PlaybackController.h"
|
|
|
|
#import "PlaylistController.h"
|
|
|
|
#import "PlaylistView.h"
|
2013-10-09 09:02:49 +00:00
|
|
|
#import "PlaylistEntry.h"
|
2007-03-09 01:16:06 +00:00
|
|
|
#import "PlaylistLoader.h"
|
2007-05-26 14:43:31 +00:00
|
|
|
#import "OpenURLPanel.h"
|
2008-02-11 09:20:52 +00:00
|
|
|
#import "SpotlightWindowController.h"
|
2008-02-18 01:46:34 +00:00
|
|
|
#import "StringToURLTransformer.h"
|
2008-02-18 09:27:27 +00:00
|
|
|
#import "FontSizetoLineHeightTransformer.h"
|
2020-11-23 02:16:34 +00:00
|
|
|
#import "Cog-Swift.h"
|
2013-10-11 10:03:23 +00:00
|
|
|
#import "PathNode.h"
|
2013-10-09 09:02:49 +00:00
|
|
|
#import <CogAudio/Status.h>
|
2005-06-02 18:16:43 +00:00
|
|
|
|
2013-10-11 12:03:55 +00:00
|
|
|
#import "Logging.h"
|
2013-10-11 19:02:05 +00:00
|
|
|
#import "MiniModeMenuTitleTransformer.h"
|
|
|
|
#import "DualWindow.h"
|
2013-10-11 12:03:55 +00:00
|
|
|
|
2021-01-25 02:44:17 +00:00
|
|
|
#import <MASShortcut/Shortcut.h>
|
|
|
|
#import "Shortcuts.h"
|
|
|
|
|
2021-02-18 22:02:10 +00:00
|
|
|
void* kAppControllerContext = &kAppControllerContext;
|
|
|
|
|
|
|
|
|
2021-02-06 22:12:19 +00:00
|
|
|
@implementation AppController {
|
|
|
|
BOOL _isFullToolbarStyle;
|
|
|
|
}
|
2005-06-02 18:16:43 +00:00
|
|
|
|
2022-01-16 15:32:47 +00:00
|
|
|
@synthesize mainWindow;
|
|
|
|
@synthesize miniWindow;
|
|
|
|
|
2008-02-18 01:46:34 +00:00
|
|
|
+ (void)initialize
|
|
|
|
{
|
2008-02-18 09:27:27 +00:00
|
|
|
// Register transformers
|
2016-05-05 20:05:39 +00:00
|
|
|
NSValueTransformer *stringToURLTransformer = [[StringToURLTransformer alloc] init];
|
2008-02-18 01:46:34 +00:00
|
|
|
[NSValueTransformer setValueTransformer:stringToURLTransformer
|
|
|
|
forName:@"StringToURLTransformer"];
|
2008-02-18 09:27:27 +00:00
|
|
|
|
|
|
|
NSValueTransformer *fontSizetoLineHeightTransformer =
|
2016-05-05 20:05:39 +00:00
|
|
|
[[FontSizetoLineHeightTransformer alloc] init];
|
2008-02-18 09:27:27 +00:00
|
|
|
[NSValueTransformer setValueTransformer:fontSizetoLineHeightTransformer
|
|
|
|
forName:@"FontSizetoLineHeightTransformer"];
|
2013-10-11 19:02:05 +00:00
|
|
|
|
2016-05-05 20:05:39 +00:00
|
|
|
NSValueTransformer *miniModeMenuTitleTransformer = [[MiniModeMenuTitleTransformer alloc] init];
|
2013-10-11 19:02:05 +00:00
|
|
|
[NSValueTransformer setValueTransformer:miniModeMenuTitleTransformer
|
|
|
|
forName:@"MiniModeMenuTitleTransformer"];
|
2008-02-18 01:46:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-30 13:25:45 +00:00
|
|
|
- (id)init
|
|
|
|
{
|
|
|
|
self = [super init];
|
|
|
|
if (self)
|
|
|
|
{
|
|
|
|
[self initDefaults];
|
2007-11-01 01:53:52 +00:00
|
|
|
|
2008-03-01 18:29:14 +00:00
|
|
|
queue = [[NSOperationQueue alloc]init];
|
2006-09-30 13:25:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2006-09-02 16:09:20 +00:00
|
|
|
- (IBAction)openFiles:(id)sender
|
2005-06-02 18:16:43 +00:00
|
|
|
{
|
|
|
|
NSOpenPanel *p;
|
|
|
|
|
|
|
|
p = [NSOpenPanel openPanel];
|
|
|
|
|
2013-10-03 08:00:58 +00:00
|
|
|
[p setAllowedFileTypes:[playlistLoader acceptableFileTypes]];
|
2005-06-02 18:16:43 +00:00
|
|
|
[p setCanChooseDirectories:YES];
|
|
|
|
[p setAllowsMultipleSelection:YES];
|
2013-10-03 08:00:58 +00:00
|
|
|
[p setResolvesAliases:YES];
|
2005-06-02 18:16:43 +00:00
|
|
|
|
2013-10-03 08:00:58 +00:00
|
|
|
[p beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger result) {
|
2021-01-07 04:41:58 +00:00
|
|
|
if ( result == NSModalResponseOK ) {
|
2018-06-28 10:59:59 +00:00
|
|
|
[self->playlistLoader willInsertURLs:[p URLs] origin:URLOriginInternal];
|
|
|
|
[self->playlistLoader didInsertURLs:[self->playlistLoader addURLs:[p URLs] sort:YES] origin:URLOriginInternal];
|
2013-10-03 08:00:58 +00:00
|
|
|
} else {
|
|
|
|
[p close];
|
|
|
|
}
|
|
|
|
}];
|
2007-05-26 14:43:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)savePlaylist:(id)sender
|
|
|
|
{
|
|
|
|
NSSavePanel *p;
|
|
|
|
|
|
|
|
p = [NSSavePanel savePanel];
|
2021-04-09 18:16:12 +00:00
|
|
|
|
|
|
|
/* Yes, this is deprecated. Yes, this is required to give the dialog
|
|
|
|
* a default set of filename extensions to save, including adding an
|
|
|
|
* extension if the user does not supply one. */
|
|
|
|
[p setAllowedFileTypes:[NSArray arrayWithObjects:@"m3u", @"pls", nil]];
|
2005-06-02 18:16:43 +00:00
|
|
|
|
2013-10-03 08:00:58 +00:00
|
|
|
[p beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger result) {
|
2021-01-07 04:41:58 +00:00
|
|
|
if ( result == NSModalResponseOK ) {
|
2018-06-28 10:59:59 +00:00
|
|
|
[self->playlistLoader save:[[p URL] path]];
|
2013-10-03 08:00:58 +00:00
|
|
|
} else {
|
|
|
|
[p close];
|
|
|
|
}
|
|
|
|
}];
|
2007-03-02 01:36:52 +00:00
|
|
|
}
|
|
|
|
|
2007-05-26 14:43:31 +00:00
|
|
|
- (IBAction)openURL:(id)sender
|
2007-03-02 01:36:52 +00:00
|
|
|
{
|
2007-05-26 14:43:31 +00:00
|
|
|
OpenURLPanel *p;
|
2007-03-02 01:36:52 +00:00
|
|
|
|
2007-05-26 14:43:31 +00:00
|
|
|
p = [OpenURLPanel openURLPanel];
|
|
|
|
|
|
|
|
[p beginSheetWithWindow:mainWindow delegate:self didEndSelector:@selector(openURLPanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
|
2007-03-02 01:36:52 +00:00
|
|
|
}
|
|
|
|
|
2007-05-26 14:43:31 +00:00
|
|
|
- (void)openURLPanelDidEnd:(OpenURLPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
|
2007-03-02 01:36:52 +00:00
|
|
|
{
|
2021-01-07 04:41:58 +00:00
|
|
|
if (returnCode == NSModalResponseOK)
|
2007-05-26 14:43:31 +00:00
|
|
|
{
|
2020-03-10 09:17:19 +00:00
|
|
|
[playlistLoader willInsertURLs:[NSArray arrayWithObject:[panel url]] origin:URLOriginInternal];
|
|
|
|
[playlistLoader didInsertURLs:[playlistLoader addURLs:[NSArray arrayWithObject:[panel url]] sort:NO] origin:URLOriginInternal];
|
2007-05-26 14:43:31 +00:00
|
|
|
}
|
2007-03-02 01:36:52 +00:00
|
|
|
}
|
|
|
|
|
2005-06-02 18:16:43 +00:00
|
|
|
- (IBAction)delEntries:(id)sender
|
|
|
|
{
|
|
|
|
[playlistController remove:self];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (PlaylistEntry *)currentEntry
|
|
|
|
{
|
|
|
|
return [playlistController currentEntry];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)application:(NSApplication *)sender delegateHandlesKey:(NSString *)key
|
|
|
|
{
|
2007-10-03 22:26:39 +00:00
|
|
|
return [key isEqualToString:@"currentEntry"] || [key isEqualToString:@"play"];
|
2005-06-02 18:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)awakeFromNib
|
|
|
|
{
|
2007-11-24 20:16:27 +00:00
|
|
|
[[totalTimeField cell] setBackgroundStyle:NSBackgroundStyleRaised];
|
2021-02-20 22:38:52 +00:00
|
|
|
|
2021-02-18 22:44:05 +00:00
|
|
|
[self.infoButton setToolTip:NSLocalizedString(@"InfoButtonTooltip", @"")];
|
|
|
|
[self.infoButtonMini setToolTip:NSLocalizedString(@"InfoButtonTooltip", @"")];
|
2005-07-11 20:27:47 +00:00
|
|
|
[shuffleButton setToolTip:NSLocalizedString(@"ShuffleButtonTooltip", @"")];
|
|
|
|
[repeatButton setToolTip:NSLocalizedString(@"RepeatButtonTooltip", @"")];
|
2013-10-11 12:27:19 +00:00
|
|
|
[randomizeButton setToolTip:NSLocalizedString(@"RandomizeButtonTooltip", @"")];
|
2007-05-28 14:13:57 +00:00
|
|
|
[fileButton setToolTip:NSLocalizedString(@"FileButtonTooltip", @"")];
|
2006-04-13 03:20:31 +00:00
|
|
|
|
2006-09-02 16:09:20 +00:00
|
|
|
[self registerHotKeys];
|
|
|
|
|
2016-05-05 20:05:39 +00:00
|
|
|
(void) [spotlightWindowController init];
|
2007-02-19 00:42:12 +00:00
|
|
|
|
2008-02-10 18:34:23 +00:00
|
|
|
[[playlistController undoManager] disableUndoRegistration];
|
2021-12-24 09:01:21 +00:00
|
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
|
|
|
NSString *basePath = [[paths firstObject] stringByAppendingPathComponent:@"Cog"];
|
|
|
|
|
|
|
|
NSString *dbFilename = @"Default.sqlite";
|
|
|
|
|
2013-10-09 15:45:16 +00:00
|
|
|
NSString *oldFilename = @"Default.m3u";
|
|
|
|
NSString *newFilename = @"Default.xml";
|
|
|
|
|
2021-12-24 09:01:21 +00:00
|
|
|
if ([[NSFileManager defaultManager] fileExistsAtPath:[basePath stringByAppendingPathComponent:dbFilename]])
|
|
|
|
{
|
|
|
|
[playlistLoader addDatabase];
|
|
|
|
}
|
|
|
|
else if ([[NSFileManager defaultManager] fileExistsAtPath:[basePath stringByAppendingPathComponent:newFilename]])
|
2013-10-09 15:45:16 +00:00
|
|
|
{
|
|
|
|
[playlistLoader addURL:[NSURL fileURLWithPath:[basePath stringByAppendingPathComponent:newFilename]]];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[playlistLoader addURL:[NSURL fileURLWithPath:[basePath stringByAppendingPathComponent:oldFilename]]];
|
|
|
|
}
|
|
|
|
|
2008-02-10 18:34:23 +00:00
|
|
|
[[playlistController undoManager] enableUndoRegistration];
|
2013-10-09 09:02:49 +00:00
|
|
|
|
2017-03-22 05:08:35 +00:00
|
|
|
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"resumePlaybackOnStartup"])
|
2013-10-09 09:02:49 +00:00
|
|
|
{
|
2017-03-22 05:08:35 +00:00
|
|
|
int lastStatus = (int) [[NSUserDefaults standardUserDefaults] integerForKey:@"lastPlaybackStatus"];
|
|
|
|
int lastIndex = (int) [[NSUserDefaults standardUserDefaults] integerForKey:@"lastTrackPlaying"];
|
2013-10-11 09:09:26 +00:00
|
|
|
|
2021-02-06 21:20:03 +00:00
|
|
|
if (lastStatus != CogStatusStopped && lastIndex >= 0)
|
2017-03-22 05:08:35 +00:00
|
|
|
{
|
2021-12-26 12:35:54 +00:00
|
|
|
[playbackController playEntryAtIndex:lastIndex startPaused:(lastStatus == CogStatusPaused) andSeekTo:[NSNumber numberWithDouble:[[NSUserDefaults standardUserDefaults] floatForKey:@"lastTrackPosition"]]];
|
2017-03-22 05:08:35 +00:00
|
|
|
}
|
|
|
|
}
|
2013-10-11 19:02:05 +00:00
|
|
|
|
|
|
|
// Restore mini mode
|
|
|
|
[self setMiniMode:[[NSUserDefaults standardUserDefaults] boolForKey:@"miniMode"]];
|
|
|
|
|
2021-02-06 22:12:19 +00:00
|
|
|
[self setToolbarStyle:[[NSUserDefaults standardUserDefaults] boolForKey:@"toolbarStyleFull"]];
|
|
|
|
|
2021-03-02 21:04:59 +00:00
|
|
|
[self setFloatingMiniWindow:[[NSUserDefaults standardUserDefaults]
|
|
|
|
boolForKey:@"floatingMiniWindow"]];
|
|
|
|
|
2013-10-11 10:03:23 +00:00
|
|
|
// We need file tree view to restore its state here
|
|
|
|
// so attempt to access file tree view controller's root view
|
|
|
|
// to force it to read nib and create file tree view for us
|
|
|
|
//
|
|
|
|
// TODO: there probably is a more elegant way to do all this
|
|
|
|
// but i'm too stupid/tired to figure it out now
|
|
|
|
[fileTreeViewController view];
|
|
|
|
|
|
|
|
FileTreeOutlineView* outlineView = [fileTreeViewController outlineView];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nodeExpanded:) name:NSOutlineViewItemDidExpandNotification object:outlineView];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nodeCollapsed:) name:NSOutlineViewItemDidCollapseNotification object:outlineView];
|
2022-01-16 07:41:02 +00:00
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateDockMenu:) name:CogPlaybackDidBeginNotficiation object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateDockMenu:) name:CogPlaybackDidStopNotficiation object:nil];
|
|
|
|
|
|
|
|
[self updateDockMenu:nil];
|
2013-10-11 10:03:23 +00:00
|
|
|
|
|
|
|
NSArray *expandedNodesArray = [[NSUserDefaults standardUserDefaults] valueForKey:@"fileTreeViewExpandedNodes"];
|
|
|
|
|
|
|
|
if (expandedNodesArray)
|
|
|
|
{
|
|
|
|
expandedNodes = [[NSMutableSet alloc] initWithArray:expandedNodesArray];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
expandedNodes = [[NSMutableSet alloc] init];
|
|
|
|
}
|
|
|
|
|
2013-10-11 12:03:55 +00:00
|
|
|
DLog(@"Nodes to expand: %@", [expandedNodes description]);
|
2013-10-11 10:03:23 +00:00
|
|
|
|
2013-10-11 12:03:55 +00:00
|
|
|
DLog(@"Num of rows: %ld", [outlineView numberOfRows]);
|
2013-10-11 10:03:23 +00:00
|
|
|
|
|
|
|
if (!outlineView)
|
|
|
|
{
|
2013-10-11 12:03:55 +00:00
|
|
|
DLog(@"outlineView is NULL!");
|
2013-10-11 10:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[outlineView reloadData];
|
|
|
|
|
|
|
|
for (NSInteger i=0; i<[outlineView numberOfRows]; i++)
|
|
|
|
{
|
|
|
|
PathNode *pn = [outlineView itemAtRow:i];
|
|
|
|
NSString *str = [[pn URL] absoluteString];
|
|
|
|
|
|
|
|
if ([expandedNodes containsObject:str])
|
|
|
|
{
|
|
|
|
[outlineView expandItem:pn];
|
|
|
|
}
|
|
|
|
}
|
2021-02-18 22:02:10 +00:00
|
|
|
|
|
|
|
[self addObserver:self
|
2021-02-18 22:44:05 +00:00
|
|
|
forKeyPath:@"playlistController.currentEntry"
|
2021-02-18 22:02:10 +00:00
|
|
|
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
|
|
|
|
context:kAppControllerContext];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)observeValueForKeyPath:(NSString *)keyPath
|
|
|
|
ofObject:(id)object
|
|
|
|
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
|
|
|
|
context:(void *)context {
|
2021-02-18 22:44:05 +00:00
|
|
|
if (context != kAppControllerContext) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([keyPath isEqualToString:@"playlistController.currentEntry"]) {
|
|
|
|
PlaylistEntry *entry = playlistController.currentEntry;
|
|
|
|
if (!entry) {
|
|
|
|
miniWindow.title = @"Cog";
|
|
|
|
mainWindow.title = @"Cog";
|
|
|
|
if (@available(macOS 11.0, *)) {
|
|
|
|
miniWindow.subtitle = @"";
|
|
|
|
mainWindow.subtitle = @"";
|
|
|
|
}
|
|
|
|
|
|
|
|
self.infoButton.imageScaling = NSImageScaleNone;
|
|
|
|
self.infoButton.image = [NSImage imageNamed:@"infoTemplate"];
|
|
|
|
self.infoButtonMini.imageScaling = NSImageScaleNone;
|
|
|
|
self.infoButtonMini.image = [NSImage imageNamed:@"infoTemplate"];
|
|
|
|
}
|
|
|
|
|
2021-05-04 23:03:55 +00:00
|
|
|
if (entry.albumArt) {
|
|
|
|
self.infoButton.imageScaling = NSImageScaleProportionallyUpOrDown;
|
|
|
|
self.infoButton.image = playlistController.currentEntry.albumArt;
|
|
|
|
self.infoButtonMini.imageScaling = NSImageScaleProportionallyUpOrDown;
|
|
|
|
self.infoButtonMini.image = playlistController.currentEntry.albumArt;
|
|
|
|
} else {
|
|
|
|
self.infoButton.imageScaling = NSImageScaleNone;
|
|
|
|
self.infoButton.image = [NSImage imageNamed:@"infoTemplate"];
|
|
|
|
self.infoButtonMini.imageScaling = NSImageScaleNone;
|
|
|
|
self.infoButtonMini.image = [NSImage imageNamed:@"infoTemplate"];
|
|
|
|
}
|
|
|
|
|
2021-02-18 22:44:05 +00:00
|
|
|
if (@available(macOS 11.0, *)) {
|
|
|
|
NSString *title = @"Cog";
|
|
|
|
if (entry.title) {
|
|
|
|
title = entry.title;
|
|
|
|
}
|
|
|
|
miniWindow.title = title;
|
|
|
|
mainWindow.title = title;
|
|
|
|
|
|
|
|
NSString *subtitle = @"";
|
|
|
|
NSMutableArray<NSString *> *subtitleItems = [NSMutableArray array];
|
|
|
|
if (entry.album && ![entry.album isEqualToString:@""]) {
|
|
|
|
[subtitleItems addObject:entry.album];
|
|
|
|
}
|
|
|
|
if (entry.artist && ![entry.artist isEqualToString:@""]) {
|
|
|
|
[subtitleItems addObject:entry.artist];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([subtitleItems count]) {
|
|
|
|
subtitle = [subtitleItems componentsJoinedByString:@" - "];
|
|
|
|
}
|
|
|
|
|
|
|
|
miniWindow.subtitle = subtitle;
|
|
|
|
mainWindow.subtitle = subtitle;
|
|
|
|
} else {
|
|
|
|
NSString *title = @"Cog";
|
|
|
|
if (entry.display) {
|
|
|
|
title = entry.display;
|
|
|
|
}
|
|
|
|
miniWindow.title = title;
|
|
|
|
mainWindow.title = title;
|
|
|
|
}
|
2021-02-18 22:02:10 +00:00
|
|
|
}
|
2013-10-11 10:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)nodeExpanded:(NSNotification*)notification
|
|
|
|
{
|
|
|
|
PathNode* node = [[notification userInfo] objectForKey:@"NSObject"];
|
|
|
|
NSString* url = [[node URL] absoluteString];
|
|
|
|
|
|
|
|
[expandedNodes addObject:url];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)nodeCollapsed:(NSNotification*)notification
|
|
|
|
{
|
|
|
|
PathNode* node = [[notification userInfo] objectForKey:@"NSObject"];
|
|
|
|
NSString* url = [[node URL] absoluteString];
|
|
|
|
|
|
|
|
[expandedNodes removeObject:url];
|
2005-06-02 18:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
|
|
|
{
|
2021-02-06 21:20:03 +00:00
|
|
|
CogStatus currentStatus = [playbackController playbackStatus];
|
2021-04-30 01:16:24 +00:00
|
|
|
NSInteger lastTrackPlaying = -1;
|
2013-10-09 09:02:49 +00:00
|
|
|
double lastTrackPosition = 0;
|
|
|
|
|
2021-02-06 21:20:03 +00:00
|
|
|
if (currentStatus == CogStatusStopping)
|
|
|
|
currentStatus = CogStatusStopped;
|
2021-01-06 10:18:09 +00:00
|
|
|
|
2021-02-06 21:20:03 +00:00
|
|
|
if (currentStatus != CogStatusStopped)
|
2013-10-09 09:02:49 +00:00
|
|
|
{
|
|
|
|
PlaylistEntry * pe = [playlistController currentEntry];
|
|
|
|
lastTrackPlaying = [pe index];
|
|
|
|
lastTrackPosition = [pe currentPosition];
|
|
|
|
}
|
|
|
|
|
|
|
|
[[NSUserDefaults standardUserDefaults] setInteger:lastTrackPlaying forKey:@"lastTrackPlaying"];
|
|
|
|
[[NSUserDefaults standardUserDefaults] setDouble:lastTrackPosition forKey:@"lastTrackPosition"];
|
|
|
|
|
2007-02-26 05:07:18 +00:00
|
|
|
[playbackController stop:self];
|
|
|
|
|
2022-01-09 11:17:43 +00:00
|
|
|
[[NSUserDefaults standardUserDefaults] setInteger:currentStatus forKey:@"lastPlaybackStatus"];
|
|
|
|
|
2005-06-02 18:16:43 +00:00
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
2021-12-24 09:01:21 +00:00
|
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
|
|
|
NSString *folder = [[paths firstObject] stringByAppendingPathComponent:@"Cog"];
|
|
|
|
|
2005-06-02 18:16:43 +00:00
|
|
|
if ([fileManager fileExistsAtPath: folder] == NO)
|
|
|
|
{
|
2013-10-03 08:00:58 +00:00
|
|
|
[fileManager createDirectoryAtPath: folder withIntermediateDirectories:NO attributes:nil error:nil];
|
2005-06-02 18:16:43 +00:00
|
|
|
}
|
2021-04-09 18:09:18 +00:00
|
|
|
|
|
|
|
[playlistController clearFilterPredicate:self];
|
2005-06-02 18:16:43 +00:00
|
|
|
|
2013-10-09 15:45:16 +00:00
|
|
|
NSString * fileName = @"Default.xml";
|
|
|
|
|
2021-12-24 09:01:21 +00:00
|
|
|
NSError *error;
|
|
|
|
[[NSFileManager defaultManager] removeItemAtPath:[folder stringByAppendingPathComponent:fileName] error:&error];
|
|
|
|
|
2013-10-09 15:45:16 +00:00
|
|
|
fileName = @"Default.m3u";
|
|
|
|
|
|
|
|
[[NSFileManager defaultManager] removeItemAtPath:[folder stringByAppendingPathComponent:fileName] error:&error];
|
2013-10-11 10:03:23 +00:00
|
|
|
|
2013-10-11 12:03:55 +00:00
|
|
|
DLog(@"Saving expanded nodes: %@", [expandedNodes description]);
|
2013-10-11 10:03:23 +00:00
|
|
|
|
|
|
|
[[NSUserDefaults standardUserDefaults] setValue:[expandedNodes allObjects] forKey:@"fileTreeViewExpandedNodes"];
|
2021-02-14 00:09:59 +00:00
|
|
|
// Workaround window not restoring it's size and position.
|
|
|
|
[miniWindow setContentSize:NSMakeSize(miniWindow.frame.size.width, 1)];
|
2005-06-02 18:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
|
|
|
|
{
|
2007-07-05 23:08:10 +00:00
|
|
|
if (flag == NO)
|
2015-01-15 13:57:22 +00:00
|
|
|
[mainWindow makeKeyAndOrderFront:self]; // TODO: do we really need this? We never close the main window.
|
|
|
|
|
|
|
|
for(NSWindow* win in [NSApp windows]) // Maximizing all windows
|
|
|
|
if([win isMiniaturized])
|
|
|
|
[win deminiaturize:self];
|
2005-06-02 18:16:43 +00:00
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
|
|
|
{
|
2008-05-09 21:24:49 +00:00
|
|
|
NSArray* urls = [NSArray arrayWithObject:[NSURL fileURLWithPath:filename]];
|
2009-02-28 22:22:33 +00:00
|
|
|
[playlistLoader willInsertURLs:urls origin:URLOriginExternal];
|
|
|
|
[playlistLoader didInsertURLs:[playlistLoader addURLs:urls sort:NO] origin:URLOriginExternal];
|
2005-06-02 18:16:43 +00:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)application:(NSApplication *)theApplication openFiles:(NSArray *)filenames
|
|
|
|
{
|
2007-03-09 01:16:06 +00:00
|
|
|
//Need to convert to urls
|
|
|
|
NSMutableArray *urls = [NSMutableArray array];
|
|
|
|
|
2008-02-20 00:54:45 +00:00
|
|
|
for (NSString *filename in filenames)
|
2007-03-09 01:16:06 +00:00
|
|
|
{
|
|
|
|
[urls addObject:[NSURL fileURLWithPath:filename]];
|
|
|
|
}
|
2009-02-28 22:22:33 +00:00
|
|
|
[playlistLoader willInsertURLs:urls origin:URLOriginExternal];
|
|
|
|
[playlistLoader didInsertURLs:[playlistLoader addURLs:urls sort:YES] origin:URLOriginExternal];
|
2005-06-02 18:16:43 +00:00
|
|
|
[theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
|
|
|
|
}
|
|
|
|
|
2020-11-25 00:03:49 +00:00
|
|
|
- (IBAction)openLiberapayPage:(id)sender
|
2006-04-04 01:08:21 +00:00
|
|
|
{
|
2020-11-25 00:03:49 +00:00
|
|
|
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://liberapay.com/kode54"]];
|
2019-11-16 22:49:30 +00:00
|
|
|
}
|
|
|
|
|
2020-11-25 00:03:49 +00:00
|
|
|
- (IBAction)openPaypalPage:(id)sender
|
2020-05-02 07:53:08 +00:00
|
|
|
{
|
2020-11-25 00:03:49 +00:00
|
|
|
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.paypal.com/paypalme/kode54"]];
|
2020-05-02 07:53:08 +00:00
|
|
|
}
|
|
|
|
|
2020-11-25 00:03:49 +00:00
|
|
|
- (IBAction)openKofiPage:(id)sender
|
|
|
|
{
|
|
|
|
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://ko-fi.com/kode54"]];
|
|
|
|
}
|
|
|
|
|
2022-01-18 08:07:40 +00:00
|
|
|
- (IBAction)openPatreonPage:(id)sender
|
|
|
|
{
|
|
|
|
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.patreon.com/kode54"]];
|
|
|
|
}
|
|
|
|
|
2020-11-25 00:03:49 +00:00
|
|
|
|
2019-11-16 22:49:30 +00:00
|
|
|
- (IBAction)feedback:(id)sender
|
|
|
|
{
|
|
|
|
NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
|
|
|
|
|
2021-02-09 00:11:08 +00:00
|
|
|
NSArray<NSURLQueryItem *> *query = @[
|
|
|
|
[NSURLQueryItem queryItemWithName:@"labels" value:@"bug"],
|
|
|
|
[NSURLQueryItem queryItemWithName:@"template" value:@"bug_report.md"],
|
|
|
|
[NSURLQueryItem queryItemWithName:@"title"
|
|
|
|
value:[NSString stringWithFormat:@"[Cog %@] ", version]]
|
|
|
|
];
|
|
|
|
NSURLComponents *components =
|
|
|
|
[NSURLComponents componentsWithString:@"https://github.com/losnoco/Cog/issues/new"];
|
|
|
|
|
|
|
|
components.queryItems = query;
|
|
|
|
|
|
|
|
[[NSWorkspace sharedWorkspace] openURL:components.URL];
|
2006-04-04 01:08:21 +00:00
|
|
|
}
|
|
|
|
|
2006-09-02 16:09:20 +00:00
|
|
|
- (void)initDefaults
|
|
|
|
{
|
|
|
|
NSMutableDictionary *userDefaultsValuesDict = [NSMutableDictionary dictionary];
|
2007-02-19 00:42:12 +00:00
|
|
|
|
2008-02-18 00:11:38 +00:00
|
|
|
// Font defaults
|
2021-01-07 04:41:58 +00:00
|
|
|
float fFontSize = [NSFont systemFontSizeForControlSize:NSControlSizeSmall];
|
2008-02-18 00:11:38 +00:00
|
|
|
NSNumber *fontSize = [NSNumber numberWithFloat:fFontSize];
|
|
|
|
[userDefaultsValuesDict setObject:fontSize forKey:@"fontSize"];
|
2006-09-10 21:27:20 +00:00
|
|
|
|
2022-01-16 03:04:26 +00:00
|
|
|
NSString *feedURLdefault = @"https://cogcdn.cog.losno.co/mercury.xml";
|
2021-01-25 03:23:48 +00:00
|
|
|
[userDefaultsValuesDict setObject:feedURLdefault forKey:@"SUFeedURL"];
|
2008-05-09 21:24:49 +00:00
|
|
|
|
2008-05-18 09:38:53 +00:00
|
|
|
[userDefaultsValuesDict setObject:@"clearAndPlay" forKey:@"openingFilesBehavior"];
|
|
|
|
[userDefaultsValuesDict setObject:@"enqueue" forKey:@"openingFilesAlteredBehavior"];
|
2013-10-02 06:00:16 +00:00
|
|
|
|
|
|
|
[userDefaultsValuesDict setObject:@"albumGainWithPeak" forKey:@"volumeScaling"];
|
2014-03-27 04:49:31 +00:00
|
|
|
|
|
|
|
[userDefaultsValuesDict setObject:@"cubic" forKey:@"resampling"];
|
2013-10-04 11:16:09 +00:00
|
|
|
|
2022-01-11 12:00:34 +00:00
|
|
|
[userDefaultsValuesDict setObject:@"normal" forKey:@"outputResampling"];
|
|
|
|
|
2021-02-06 21:20:03 +00:00
|
|
|
[userDefaultsValuesDict setObject:[NSNumber numberWithInteger:CogStatusStopped] forKey:@"lastPlaybackStatus"];
|
2013-10-09 09:02:49 +00:00
|
|
|
[userDefaultsValuesDict setObject:[NSNumber numberWithInteger:-1] forKey:@"lastTrackPlaying"];
|
|
|
|
[userDefaultsValuesDict setObject:[NSNumber numberWithDouble:0] forKey:@"lastTrackPosition"];
|
2014-12-04 05:36:55 +00:00
|
|
|
|
2016-01-21 05:11:05 +00:00
|
|
|
[userDefaultsValuesDict setObject:@"dls appl" forKey:@"midi.plugin"];
|
|
|
|
|
2016-11-29 23:46:38 +00:00
|
|
|
[userDefaultsValuesDict setObject:@"default" forKey:@"midi.flavor"];
|
2016-04-13 04:16:25 +00:00
|
|
|
|
2017-03-22 05:08:35 +00:00
|
|
|
[userDefaultsValuesDict setObject:[NSNumber numberWithBool:NO] forKey:@"resumePlaybackOnStartup"];
|
|
|
|
|
2006-09-02 16:09:20 +00:00
|
|
|
//Register and sync defaults
|
|
|
|
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
|
|
|
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
2021-01-25 03:23:48 +00:00
|
|
|
|
2013-10-23 00:46:33 +00:00
|
|
|
//And if the existing feed URL is broken due to my ineptitude with the above defaults, fix it
|
2021-01-25 03:23:48 +00:00
|
|
|
NSSet<NSString *> *brokenFeedURLs = [NSSet setWithObjects:
|
|
|
|
@"https://kode54.net/cog/stable.xml",
|
|
|
|
@"https://kode54.net/cog/mercury.xml"
|
|
|
|
@"https://www.kode54.net/cog/mercury.xml",
|
2022-01-16 03:04:26 +00:00
|
|
|
@"https://f.losno.co/cog/mercury.xml",
|
2021-01-25 03:23:48 +00:00
|
|
|
nil];
|
|
|
|
NSString *feedURL = [[NSUserDefaults standardUserDefaults] stringForKey:@"SUFeedURL"];
|
|
|
|
if ([brokenFeedURLs containsObject:feedURL]) {
|
2013-10-23 00:46:33 +00:00
|
|
|
[[NSUserDefaults standardUserDefaults] setValue:feedURLdefault forKey:@"SUFeedURL"];
|
2021-01-25 03:23:48 +00:00
|
|
|
}
|
2021-05-04 01:25:58 +00:00
|
|
|
|
|
|
|
if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"midi.plugin"] isEqualToString:@"BASSMIDI"]) {
|
|
|
|
[[NSUserDefaults standardUserDefaults] setValue:@"FluidSynth" forKey:@"midi.plugin"];
|
|
|
|
}
|
2006-09-02 16:09:20 +00:00
|
|
|
}
|
|
|
|
|
2016-10-11 05:33:00 +00:00
|
|
|
/* Unassign previous handler first, so dealloc can unregister it from the global map before the new instances are assigned */
|
2006-09-10 21:27:20 +00:00
|
|
|
- (void)registerHotKeys
|
2006-09-02 16:09:20 +00:00
|
|
|
{
|
2021-01-25 02:44:17 +00:00
|
|
|
MASShortcutBinder *binder = [MASShortcutBinder sharedBinder];
|
|
|
|
[binder bindShortcutWithDefaultsKey:CogPlayShortcutKey toAction:^{
|
|
|
|
[self clickPlay];
|
|
|
|
}];
|
2013-10-04 11:16:09 +00:00
|
|
|
|
2021-01-25 02:44:17 +00:00
|
|
|
[binder bindShortcutWithDefaultsKey:CogNextShortcutKey toAction:^{
|
|
|
|
[self clickNext];
|
|
|
|
}];
|
|
|
|
|
|
|
|
[binder bindShortcutWithDefaultsKey:CogPrevShortcutKey toAction:^{
|
|
|
|
[self clickPrev];
|
|
|
|
}];
|
|
|
|
|
|
|
|
[binder bindShortcutWithDefaultsKey:CogSpamShortcutKey toAction:^{
|
|
|
|
[self clickSpam];
|
|
|
|
}];
|
2006-09-02 16:09:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)clickPlay
|
|
|
|
{
|
2008-01-23 03:03:46 +00:00
|
|
|
[playbackController playPauseResume:self];
|
2006-09-02 16:09:20 +00:00
|
|
|
}
|
|
|
|
|
2019-11-14 03:13:59 +00:00
|
|
|
- (void)clickPause
|
|
|
|
{
|
|
|
|
[playbackController pause:self];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)clickStop
|
|
|
|
{
|
|
|
|
[playbackController stop:self];
|
|
|
|
}
|
|
|
|
|
2006-09-02 16:09:20 +00:00
|
|
|
- (void)clickPrev
|
|
|
|
{
|
2008-01-23 03:03:46 +00:00
|
|
|
[playbackController prev:nil];
|
2006-09-02 16:09:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)clickNext
|
|
|
|
{
|
2008-01-23 03:03:46 +00:00
|
|
|
[playbackController next:nil];
|
2006-09-02 16:09:20 +00:00
|
|
|
}
|
|
|
|
|
2013-10-04 11:16:09 +00:00
|
|
|
- (void)clickSpam
|
|
|
|
{
|
2022-01-16 15:32:47 +00:00
|
|
|
[playbackController spam:nil];
|
2013-10-04 11:16:09 +00:00
|
|
|
}
|
|
|
|
|
2019-11-14 03:13:59 +00:00
|
|
|
- (void)clickSeek:(NSTimeInterval)position
|
|
|
|
{
|
|
|
|
[playbackController seek:self toTime:position];
|
|
|
|
}
|
|
|
|
|
2008-02-15 15:27:34 +00:00
|
|
|
- (void)changeFontSize:(float)size
|
|
|
|
{
|
2008-02-18 00:11:38 +00:00
|
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
|
|
float fCurrentSize = [defaults floatForKey:@"fontSize"];
|
|
|
|
NSNumber *newSize = [NSNumber numberWithFloat:(fCurrentSize + size)];
|
|
|
|
[defaults setObject:newSize forKey:@"fontSize"];
|
2008-02-15 15:27:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)increaseFontSize:(id)sender
|
|
|
|
{
|
|
|
|
[self changeFontSize:1];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)decreaseFontSize:(id)sender
|
|
|
|
{
|
|
|
|
[self changeFontSize:-1];
|
|
|
|
|
|
|
|
}
|
2008-03-01 18:29:14 +00:00
|
|
|
|
2013-10-11 19:02:05 +00:00
|
|
|
- (IBAction)toggleMiniMode:(id)sender
|
|
|
|
{
|
|
|
|
[self setMiniMode:(!miniMode)];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)miniMode
|
|
|
|
{
|
|
|
|
return miniMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setMiniMode:(BOOL)newMiniMode
|
|
|
|
{
|
|
|
|
miniMode = newMiniMode;
|
|
|
|
[[NSUserDefaults standardUserDefaults] setBool:miniMode forKey:@"miniMode"];
|
|
|
|
|
|
|
|
NSWindow *windowToShow = miniMode ? miniWindow : mainWindow;
|
|
|
|
NSWindow *windowToHide = miniMode ? mainWindow : miniWindow;
|
|
|
|
[windowToHide close];
|
|
|
|
[windowToShow makeKeyAndOrderFront:self];
|
|
|
|
}
|
|
|
|
|
2021-02-06 22:12:19 +00:00
|
|
|
- (IBAction)toggleToolbarStyle:(id)sender {
|
|
|
|
[self setToolbarStyle:!_isFullToolbarStyle];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setToolbarStyle:(BOOL)full {
|
|
|
|
_isFullToolbarStyle = full;
|
|
|
|
[[NSUserDefaults standardUserDefaults] setBool:full forKey:@"toolbarStyleFull"];
|
|
|
|
DLog("Changed toolbar style: %@", (full ? @"full" : @"compact"));
|
|
|
|
|
|
|
|
if (@available(macOS 11.0, *)) {
|
|
|
|
NSWindowToolbarStyle style =
|
2021-02-18 22:44:05 +00:00
|
|
|
full ? NSWindowToolbarStyleExpanded : NSWindowToolbarStyleUnified;
|
2021-02-06 22:12:19 +00:00
|
|
|
mainWindow.toolbarStyle = style;
|
|
|
|
miniWindow.toolbarStyle = style;
|
2021-02-18 22:44:05 +00:00
|
|
|
} else {
|
|
|
|
NSWindowTitleVisibility titleVisibility = full ? NSWindowTitleVisible : NSWindowTitleHidden;
|
|
|
|
mainWindow.titleVisibility = titleVisibility;
|
|
|
|
miniWindow.titleVisibility = titleVisibility;
|
2021-02-06 22:12:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fix empty area after changing toolbar style in mini window as it has no content view
|
|
|
|
[miniWindow setContentSize:NSMakeSize(miniWindow.frame.size.width, 0)];
|
|
|
|
}
|
|
|
|
|
2021-03-02 21:04:59 +00:00
|
|
|
- (void)setFloatingMiniWindow:(BOOL)floatingMiniWindow {
|
|
|
|
_floatingMiniWindow = floatingMiniWindow;
|
|
|
|
[[NSUserDefaults standardUserDefaults] setBool:floatingMiniWindow forKey:@"floatingMiniWindow"];
|
|
|
|
NSWindowLevel level = floatingMiniWindow ? NSFloatingWindowLevel : NSNormalWindowLevel;
|
|
|
|
[miniWindow setLevel:level];
|
|
|
|
}
|
|
|
|
|
2022-01-16 07:41:02 +00:00
|
|
|
- (void)updateDockMenu:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
PlaylistEntry *pe = [playlistController currentEntry];
|
|
|
|
|
|
|
|
BOOL hideItem = NO;
|
|
|
|
|
|
|
|
if ([[notification name] isEqualToString:CogPlaybackDidStopNotficiation] || !pe || ![pe artist] || [[pe artist] isEqualToString:@""])
|
|
|
|
hideItem = YES;
|
|
|
|
|
|
|
|
if (hideItem && [dockMenu indexOfItem:currentArtistItem] == 0) {
|
|
|
|
[dockMenu removeItem:currentArtistItem];
|
|
|
|
}
|
|
|
|
else if (!hideItem && [dockMenu indexOfItem:currentArtistItem] < 0) {
|
|
|
|
[dockMenu insertItem:currentArtistItem atIndex:0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-02 18:16:43 +00:00
|
|
|
@end
|