cog/Application/AppController.m

508 lines
16 KiB
Matlab
Raw Normal View History

2005-06-02 18:16:43 +00:00
#import "AppController.h"
#import "KFTypeSelectTableView.h""
#import "PlaybackController.h"
#import "PlaylistController.h"
#import "PlaylistView.h"
#import "FileTreeController.h"
#import "FileOutlineView.h"
#import "NDHotKeyEvent.h"
#import "AppleRemote.h"
#import "PlaylistLoader.h"
2005-06-02 18:16:43 +00:00
@implementation AppController
- (id)init
{
self = [super init];
if (self)
{
[self initDefaults];
/* Use KFTypeSelectTableView as our NSTableView base class to allow type-select searching of all
* table and outline views.
*/
[[KFTypeSelectTableView class] poseAsClass:[NSTableView class]];
2007-02-18 23:00:55 +00:00
remote = [[AppleRemote alloc] init];
[remote setDelegate: self];
}
return self;
}
2007-02-18 23:00:55 +00:00
// Listen to the remote in exclusive mode, only when Cog is the active application
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"remoteEnabled"] && [[NSUserDefaults standardUserDefaults] boolForKey:@"remoteOnlyOnActive"]) {
[remote startListening: self];
}
2007-02-18 23:00:55 +00:00
}
- (void)applicationDidResignActive:(NSNotification *)motification
{
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"remoteEnabled"] && [[NSUserDefaults standardUserDefaults] boolForKey:@"remoteOnlyOnActive"]) {
[remote stopListening: self];
}
2007-02-18 23:00:55 +00:00
}
/* Helper method for the remote control interface in order to trigger forward/backward and volume
increase/decrease as long as the user holds the left/right, plus/minus button */
- (void) executeHoldActionForRemoteButton: (NSNumber*) buttonIdentifierNumber
{
if (remoteButtonHeld)
{
switch([buttonIdentifierNumber intValue])
{
case kRemoteButtonRight_Hold:
//Seek forward?
break;
case kRemoteButtonLeft_Hold:
//Seek back
break;
case kRemoteButtonVolume_Plus_Hold:
//Volume Up
[playbackController volumeUp: self];
2007-02-18 23:00:55 +00:00
break;
case kRemoteButtonVolume_Minus_Hold:
//Volume Down
[playbackController volumeDown: self];
2007-02-18 23:00:55 +00:00
break;
}
if (remoteButtonHeld)
{
/* trigger event */
[self performSelector:@selector(executeHoldActionForRemoteButton:)
withObject:buttonIdentifierNumber
afterDelay:0.25];
}
}
}
/* Apple Remote callback */
- (void) appleRemoteButton: (AppleRemoteEventIdentifier)buttonIdentifier
pressedDown: (BOOL) pressedDown
clickCount: (unsigned int) count
{
switch( buttonIdentifier )
{
case kRemoteButtonPlay:
2007-02-18 23:06:23 +00:00
[self clickPlay];
2007-02-18 23:00:55 +00:00
break;
case kRemoteButtonVolume_Plus:
[playbackController volumeUp: self];
2007-02-18 23:00:55 +00:00
break;
case kRemoteButtonVolume_Minus:
[playbackController volumeDown: self];
2007-02-18 23:00:55 +00:00
break;
case kRemoteButtonRight:
2007-02-18 23:06:23 +00:00
[self clickNext];
2007-02-18 23:00:55 +00:00
break;
case kRemoteButtonLeft:
2007-02-18 23:06:23 +00:00
[self clickPrev];
2007-02-18 23:00:55 +00:00
break;
case kRemoteButtonRight_Hold:
case kRemoteButtonLeft_Hold:
case kRemoteButtonVolume_Plus_Hold:
case kRemoteButtonVolume_Minus_Hold:
/* simulate an event as long as the user holds the button */
remoteButtonHeld = pressedDown;
if( pressedDown )
{
NSNumber* buttonIdentifierNumber = [NSNumber numberWithInt: buttonIdentifier];
[self performSelector:@selector(executeHoldActionForRemoteButton:)
withObject:buttonIdentifierNumber];
}
break;
case kRemoteButtonMenu:
break;
default:
/* Add here whatever you want other buttons to do */
break;
}
}
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];
[p setCanChooseDirectories:YES];
[p setAllowsMultipleSelection:YES];
[p beginSheetForDirectory:nil file:nil types:[playlistLoader acceptableFileTypes] modalForWindow:mainWindow modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
// [p beginForDirectory:nil file:nil types:[playlistController acceptableFileTypes] modelessDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
2005-06-02 18:16:43 +00:00
2006-09-02 16:09:20 +00:00
/* if ([p runModalForTypes:[playlistController acceptableFileTypes]] == NSOKButton)
2005-06-02 18:16:43 +00:00
{
2006-09-02 16:09:20 +00:00
[playlistController addPaths:[p filenames] sort:YES];
2005-06-02 18:16:43 +00:00
}
2006-09-02 16:09:20 +00:00
*/
2005-06-02 18:16:43 +00:00
}
- (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
if (returnCode == NSOKButton)
{
[playlistLoader addURLs:[panel URLs] sort:YES];
2005-06-02 18:16:43 +00:00
}
2006-09-02 16:09:20 +00:00
// [panel release];
2005-06-02 18:16:43 +00:00
}
- (IBAction)addURL:(id)sender
{
[NSApp beginSheet:addURLPanel modalForWindow:mainWindow modalDelegate:self didEndSelector:nil contextInfo:nil];
}
- (IBAction)addURLSheetOK:(id)sender
{
NSURL *url = [NSURL URLWithString:[urlComboBox stringValue]];
[playlistLoader addURLs:[NSArray arrayWithObject:url] sort:NO];
[NSApp endSheet:addURLPanel];
[addURLPanel orderOut:self];
}
- (IBAction)addURLSheetCancel:(id)sender
{
NSLog(@"GONE!");
[NSApp endSheet:addURLPanel];
[addURLPanel orderOut:self];
}
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
{
// DBLog(@"W00t");
2005-06-02 18:16:43 +00:00
return [key isEqualToString:@"currentEntry"];
}
- (void)initShowColumn:(NSMenuItem *)showColumn withIdentifier:(NSString *)identifier
{
id tc = [playlistView tableColumnWithIdentifier:identifier];
NSArray *visibleColumnIdentifiers = [[NSUserDefaults standardUserDefaults] objectForKey:[playlistView columnVisibilitySaveName]];
if (visibleColumnIdentifiers) {
NSEnumerator *enumerator = [visibleColumnIdentifiers objectEnumerator];
id column;
while (column = [enumerator nextObject]) {
if ([visibleColumnIdentifiers containsObject:identifier]) {
[showColumn setState:NSOnState];
}
else {
[showColumn setState:NSOffState];
}
}
}
[showColumn setRepresentedObject: tc];
}
2005-06-02 18:16:43 +00:00
- (void)awakeFromNib
{
2005-07-11 20:27:47 +00:00
[playButton setToolTip:NSLocalizedString(@"PlayButtonTooltip", @"")];
[prevButton setToolTip:NSLocalizedString(@"PrevButtonTooltip", @"")];
[nextButton setToolTip:NSLocalizedString(@"NextButtonTooltip", @"")];
[infoButton setToolTip:NSLocalizedString(@"InfoButtonTooltip", @"")];
[shuffleButton setToolTip:NSLocalizedString(@"ShuffleButtonTooltip", @"")];
[repeatButton setToolTip:NSLocalizedString(@"RepeatButtonTooltip", @"")];
[self initShowColumn: showIndexColumn withIdentifier: @"index"];
[self initShowColumn: showTitleColumn withIdentifier: @"title"];
[self initShowColumn: showArtistColumn withIdentifier: @"artist"];
[self initShowColumn: showAlbumColumn withIdentifier: @"album"];
[self initShowColumn: showGenreColumn withIdentifier: @"genre"];
[self initShowColumn: showLengthColumn withIdentifier: @"length"];
[self initShowColumn: showTrackColumn withIdentifier: @"track"];
[self initShowColumn: showYearColumn withIdentifier: @"year"];
2006-09-02 16:09:20 +00:00
[self registerHotKeys];
//Init Remote
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"remoteEnabled"] && ![[NSUserDefaults standardUserDefaults] boolForKey:@"remoteOnlyOnActive"]) {
2007-02-19 00:44:06 +00:00
[remote startListening:self];
}
NSString *filename = @"~/Library/Application Support/Cog/Default.m3u";
[playlistLoader loadM3u:[filename stringByExpandingTildeInPath]];
2005-06-02 18:16:43 +00:00
}
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
2007-02-26 05:07:18 +00:00
[playbackController stop:self];
// DBLog(@"QUITTING");
2005-06-02 18:16:43 +00:00
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *folder = @"~/Library/Application Support/Cog/";
folder = [folder stringByExpandingTildeInPath];
if ([fileManager fileExistsAtPath: folder] == NO)
{
[fileManager createDirectoryAtPath: folder attributes: nil];
}
NSString *fileName = @"Default.m3u";
[playlistLoader saveM3u:[folder stringByAppendingPathComponent: fileName]];
2005-06-02 18:16:43 +00:00
}
- (IBAction)savePlaylist:(id)sender
{
[playlistLoader save];
2005-06-02 18:16:43 +00:00
}
- (IBAction)savePlaylistAs:(id)sender
{
NSSavePanel *p;
p = [NSSavePanel savePanel];
[p setAllowedFileTypes:[playlistLoader acceptablePlaylistTypes]];
2005-06-02 18:16:43 +00:00
if ([p runModalForDirectory:nil file:[[playlistLoader currentFile] lastPathComponent]] == NSOKButton)
2005-06-02 18:16:43 +00:00
{
[playlistLoader save:[p filename]];
2005-06-02 18:16:43 +00:00
}
}
2006-05-13 04:51:11 +00:00
2005-06-02 18:16:43 +00:00
- (IBAction)loadPlaylist:(id)sender
{
NSOpenPanel *p;
2006-05-13 04:51:11 +00:00
2005-06-02 18:16:43 +00:00
p = [NSOpenPanel openPanel];
2006-05-13 04:51:11 +00:00
2005-06-02 18:16:43 +00:00
[p setCanChooseDirectories:NO];
[p setAllowsMultipleSelection:NO];
2006-05-13 04:51:11 +00:00
if ([p runModalForTypes:[playlistLoader acceptablePlaylistTypes]] == NSOKButton)
2005-06-02 18:16:43 +00:00
{
[playlistLoader load:[p filename]];
2005-06-02 18:16:43 +00:00
}
2006-05-13 04:51:11 +00:00
2005-07-23 19:10:06 +00:00
[mainWindow makeKeyAndOrderFront:self];
2005-06-02 18:16:43 +00:00
}
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
// if (flag == NO)
[mainWindow makeKeyAndOrderFront:self];
return NO;
}
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
DBLog(@"Adding path: %@", filename);
[playlistLoader addURLs:[NSArray arrayWithObject:[NSURL fileURLWithPath:filename]] sort:NO];
2005-06-02 18:16:43 +00:00
return YES;
}
- (void)application:(NSApplication *)theApplication openFiles:(NSArray *)filenames
{
//Need to convert to urls
NSMutableArray *urls = [NSMutableArray array];
NSEnumerator *e = [filenames objectEnumerator];
NSString *filename;
while (filename = [e nextObject])
{
[urls addObject:[NSURL fileURLWithPath:filename]];
}
[playlistLoader addURLs:urls sort:YES];
2005-06-02 18:16:43 +00:00
[theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
}
2006-04-04 01:08:21 +00:00
- (IBAction)toggleInfoDrawer:(id)sender
{
[mainWindow makeKeyAndOrderFront:self];
2006-04-04 01:08:21 +00:00
[infoDrawer toggle:self];
}
2006-09-02 16:09:20 +00:00
- (IBAction)toggleFileDrawer:(id)sender
{
[mainWindow makeKeyAndOrderFront:self];
2006-09-02 16:09:20 +00:00
[fileDrawer toggle:self];
}
2006-04-04 01:08:21 +00:00
- (void)drawerDidOpen:(NSNotification *)notification
{
if ([notification object] == infoDrawer) {
2006-09-02 16:09:20 +00:00
[infoButton setState:NSOnState];
}
else if ([notification object] == fileDrawer) {
2006-09-02 16:09:20 +00:00
[fileButton setState:NSOnState];
[mainWindow makeFirstResponder: fileOutlineView];
}
2006-04-04 01:08:21 +00:00
}
- (void)drawerDidClose:(NSNotification *)notification
{
if ([notification object] == infoDrawer) {
2006-09-02 16:09:20 +00:00
[infoButton setState:NSOffState];
}
else if ([notification object] == fileDrawer) {
NSLog(@"CLOSED");
2006-09-02 16:09:20 +00:00
[fileButton setState:NSOffState];
[mainWindow makeFirstResponder: playlistView];
}
2006-04-04 01:08:21 +00:00
}
- (IBAction)donate:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://sourceforge.net/project/project_donations.php?group_id=140003"]];
}
2006-09-02 16:09:20 +00:00
- (void)initDefaults
{
NSMutableDictionary *userDefaultsValuesDict = [NSMutableDictionary dictionary];
2006-09-10 21:27:20 +00:00
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:35] forKey:@"hotKeyPlayKeyCode"];
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:(NSControlKeyMask|NSCommandKeyMask)] forKey:@"hotKeyPlayModifiers"];
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:'P'] forKey:@"hotKeyPlayCharacter"];
2006-09-02 16:09:20 +00:00
2006-09-10 21:27:20 +00:00
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:45] forKey:@"hotKeyNextKeyCode"];
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:(NSControlKeyMask|NSCommandKeyMask)] forKey:@"hotKeyNextModifiers"];
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:'N'] forKey:@"hotKeyNextCharacter"];
2006-09-02 16:09:20 +00:00
2006-09-10 21:27:20 +00:00
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:15] forKey:@"hotKeyPreviousKeyCode"];
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:(NSControlKeyMask|NSCommandKeyMask)] forKey:@"hotKeyPreviousModifiers"];
[userDefaultsValuesDict setObject:[NSNumber numberWithInt:'R'] forKey:@"hotKeyPreviousCharacter"];
[userDefaultsValuesDict setObject:[@"~/Music" stringByExpandingTildeInPath] forKey:@"fileDrawerRootPath"];
[userDefaultsValuesDict setObject:[NSNumber numberWithBool:YES] forKey:@"remoteEnabled"];
[userDefaultsValuesDict setObject:[NSNumber numberWithBool:YES] forKey:@"remoteOnlyOnActive"];
[userDefaultsValuesDict setObject:@"http://cogx.org/appcast/stable.xml" forKey:@"SUFeedURL"];
2006-09-02 16:09:20 +00:00
//Register and sync defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
[[NSUserDefaults standardUserDefaults] synchronize];
//Add observers
2006-09-10 21:27:20 +00:00
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.hotKeyPlayKeyCode" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.hotKeyPreviousKeyCode" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.hotKeyNextKeyCode" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.fileDrawerRootPath" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.fileDrawerRootPath" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.fileDrawerRootPath" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.fileDrawerRootPath" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.fileDrawerRootPath" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.remoteEnabled" options:0 context:nil];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.remoteOnlyOnActive" options:0 context:nil];
2006-09-02 16:09:20 +00:00
}
2006-09-10 21:27:20 +00:00
- (void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
2006-09-02 16:09:20 +00:00
{
2006-09-10 21:27:20 +00:00
if ([keyPath isEqualToString:@"values.hotKeyPlayKeyCode"]) {
[self registerHotKeys];
2006-09-02 16:09:20 +00:00
}
2006-09-10 21:27:20 +00:00
else if ([keyPath isEqualToString:@"values.hotKeyPreviousKeyCode"]) {
[self registerHotKeys];
2006-09-02 16:09:20 +00:00
}
2006-09-10 21:27:20 +00:00
else if ([keyPath isEqualToString:@"values.hotKeyNextKeyCode"]) {
[self registerHotKeys];
2006-09-02 16:09:20 +00:00
}
else if ([keyPath isEqualToString:@"values.fileDrawerRootPath"]) {
[fileTreeController setRootPath:[[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"fileDrawerRootPath"]];
}
else if ([keyPath isEqualToString:@"values.remoteEnabled"] || [keyPath isEqualToString:@"values.remoteOnlyOnActive"]) {
if([[NSUserDefaults standardUserDefaults] boolForKey:@"remoteEnabled"]) {
NSLog(@"Remote enabled...");
BOOL onlyOnActive = [[NSUserDefaults standardUserDefaults] boolForKey:@"remoteOnlyOnActive"];
if (!onlyOnActive || [NSApp isActive]) {
[remote startListening: self];
}
if (onlyOnActive && ![NSApp isActive]) { //Setting a preference without being active? *shrugs*
[remote stopListening: self];
}
}
else {
NSLog(@"DISABLE REMOTE");
[remote stopListening: self];
}
}
2006-09-02 16:09:20 +00:00
}
2006-09-10 21:27:20 +00:00
- (void)registerHotKeys
2006-09-02 16:09:20 +00:00
{
2006-09-10 21:27:20 +00:00
NSLog(@"REGISTERING HOTKEYS");
[playHotKey release];
playHotKey = [[NDHotKeyEvent alloc]
initWithKeyCode: [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"hotKeyPlayKeyCode"] intValue]
character: [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"hotKeyPlayCharacter"] intValue]
modifierFlags: [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"hotKeyPlayModifiers"] intValue]
];
[prevHotKey release];
prevHotKey = [[NDHotKeyEvent alloc]
initWithKeyCode: [[NSUserDefaults standardUserDefaults] integerForKey:@"hotKeyPreviousKeyCode"]
2006-09-10 21:27:20 +00:00
character: [[NSUserDefaults standardUserDefaults] integerForKey:@"hotKeyPreviousCharacter"]
modifierFlags: [[NSUserDefaults standardUserDefaults] integerForKey:@"hotKeyPreviousModifiers"]
];
[nextHotKey release];
nextHotKey = [[NDHotKeyEvent alloc]
initWithKeyCode: [[NSUserDefaults standardUserDefaults] integerForKey:@"hotKeyNextKeyCode"]
character: [[NSUserDefaults standardUserDefaults] integerForKey:@"hotKeyNextCharacter"]
modifierFlags: [[NSUserDefaults standardUserDefaults] integerForKey:@"hotKeyNextModifiers"]
];
[playHotKey setTarget:self selector:@selector(clickPlay)];
[prevHotKey setTarget:self selector:@selector(clickPrev)];
[nextHotKey setTarget:self selector:@selector(clickNext)];
[playHotKey setEnabled:YES];
[prevHotKey setEnabled:YES];
[nextHotKey setEnabled:YES];
2006-09-02 16:09:20 +00:00
}
- (void)clickPlay
{
[playButton performClick:nil];
}
- (void)clickPrev
{
NSLog(@"PREV");
[prevButton performClick:nil];
}
- (void)clickNext
{
NSLog(@"NEXT");
[nextButton performClick:nil];
}
2005-06-02 18:16:43 +00:00
@end