Archived
1
This repository has been archived on 2022-08-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ilyrics/iLyrics/MainController.m
Kim Wittenburg cf3b960d85 Release No. 1.1
Added Auto-Lyrics
Improved the preferences window
2012-06-17 01:06:46 +02:00

285 lines
11 KiB
Objective-C

//
// MainController.m
// iLyrics
//
// Created by Kim Wittenburg on 10.06.12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "MainController.h"
@implementation MainController {
NSMutableArray *data;
id<LyricsHoster> currentHoster;
BOOL lyricsSelected;
NSInteger selectedSavePanelButton;
NSURL *saveFile;
iTunesApplication *iTunes;
Lyrics *currentLyrics;
int selectedRow;
}
@synthesize iLyricsMenuItem;
@synthesize window;
@synthesize searchField;
@synthesize resultsOutline;
@synthesize loadMoreResultsButton;
@synthesize showPreviewCheckBox;
@synthesize previewPopover;
@synthesize previewTextArea;
@synthesize songLabel;
@synthesize artistLabel;
@synthesize sendToiTunesButton;
@synthesize downloadLyricsButton;
@synthesize lyricsArea;
-(id)init {
iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
data = [[NSMutableArray alloc] init];
currentHoster = [[Magistrix alloc] init];
return [super init];
}
#pragma mark -
#pragma mark Outline view Data Source and Delegate
-(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
return item == nil ? [data count] : 0;
}
-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
return [data objectAtIndex:index];
}
-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
return NO;
}
-(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
if ([[tableColumn identifier] isEqualToString:@"song"]) {
return [item name];
} else {
return [item artist];
}
return nil;
}
-(NSString *)outlineView:(NSOutlineView *)outlineView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn item:(id)item mouseLocation:(NSPoint)mouseLocation {
//item is an instance of SearchResult
[self shouldShowPreviewForCellRect:*rect searchResult:item];
return nil;
}
#pragma mark -
#pragma mark Responding to Lyrics Search
- (IBAction)getCurrentiTunesSong:(id)sender {
iTunesTrack *track = [iTunes currentTrack];
if (track == nil) {
NSBeginAlertSheet(NSLocalizedString(@"iTunes.messages.iTunesIdle.title", @""), NSLocalizedString(@"OK", @""), nil, nil, window, nil, nil, nil, nil, NSLocalizedString(@"iTunes.messages.iTunesIdle.detail", @""));
return;
}
NSString *name = [track name];
NSString *artist = [track artist];
if (name == nil) {
NSBeginAlertSheet(NSLocalizedString(@"iTunes.messages.noTrackPlaying.title", @""), NSLocalizedString(@"OK", @""), nil, nil, window, nil, nil, nil, nil, NSLocalizedString(@"iTunes.messages.noTrackPlaying.detail", @""));
return;
}
NSString *searchText = [NSString stringWithFormat:@"%@ - %@", name, artist];
[searchField setStringValue:searchText];
[searchField performClick:sender];
}
- (IBAction)startNewSearch:(id)sender {
[self resetLoadedResults:sender];
if ([[searchField stringValue] length] > 0) {
[currentHoster startNewSearchForQuery:[searchField stringValue]];
[self loadNextResults:sender];
}
}
- (IBAction)loadNextResults:(id)sender {
NSArray *nextResults = [currentHoster nextResults];
if (nextResults == nil) {
NSRunCriticalAlertPanel(NSLocalizedString(@"Hoster.messages.networkError.title", @""), NSLocalizedString(@"Hoster.messages.networkError.detail", @""), NSLocalizedString(@"OK", @""), nil, nil);
return;
}
if ([nextResults count] == 0) {
NSRunAlertPanel(NSLocalizedString(@"Hoster.messages.noResults.title", @""), NSLocalizedString(@"Hoster.messages.noResults.detail", @""), NSLocalizedString(@"OK", @""), nil, nil);
return;
}
[data addObjectsFromArray:nextResults];
[resultsOutline reloadData];
[loadMoreResultsButton setEnabled:[currentHoster hasMoreResults]];
}
-(IBAction)resetLoadedResults:(id)sender {
[currentHoster resetLoadedResults];
[data removeAllObjects];
[resultsOutline reloadData];
[loadMoreResultsButton setEnabled:[currentHoster hasMoreResults]];
[self lyricsSelectionChanged:resultsOutline];
}
- (IBAction)lyricsSelectionChanged:(NSOutlineView *)sender {
int index = [sender selectedRow];
if (index < 0) {
lyricsSelected = NO;
currentLyrics = nil;
NSString *noSelectionText = NSLocalizedString(@"iLyrics.text.noSelection", @"");
[songLabel setStringValue:noSelectionText];
[artistLabel setStringValue:noSelectionText];
[lyricsArea setString:noSelectionText];
[lyricsArea setEditable:NO];
} else {
if (selectedRow != index) {
lyricsSelected = YES;
SearchResult *result = [data objectAtIndex:index];
Lyrics *lyrics = [currentHoster lyricsBySearchResult:result];
currentLyrics = lyrics;
if (lyrics == nil) {
NSRunCriticalAlertPanel(NSLocalizedString(@"Hoster.messages.networkError.title", @""), NSLocalizedString(@"Hoster.messages.networkError.detail", @""), NSLocalizedString(@"OK", @""), nil, nil);
NSString *noNetwork = NSLocalizedString(@"Hoster.text.noNetwork", @"");
[songLabel setStringValue:noNetwork];
[artistLabel setStringValue:noNetwork];
[lyricsArea setString:noNetwork];
[lyricsArea setEditable:NO];
}
[songLabel setStringValue:[lyrics name]];
[artistLabel setStringValue:[lyrics artist]];
[lyricsArea setString:[lyrics lyrics]];
[lyricsArea setEditable:YES];
}
}
selectedRow = index;
[window update];
}
-(void) shouldShowPreviewForCellRect: (NSRect) rect searchResult: (SearchResult *) result {
if ([showPreviewCheckBox state] == NSOnState) {
NSString *lyrics = [result preview];
if (lyrics) {
rect.size.width = [resultsOutline frame].size.width;
[previewTextArea setString:lyrics];
[previewPopover showRelativeToRect:rect ofView:resultsOutline preferredEdge:NSMaxXEdge];
}
}
}
- (IBAction)sendLyricsToiTunes:(id)sender {
iTunesTrack *track = [iTunes currentTrack];
NSString *name = [track name];
if (name == nil) {
NSBeginAlertSheet(NSLocalizedString(@"iTunes.messages.noTrackPlaying.title", @""), NSLocalizedString(@"OK", @""), nil, nil, window, nil, nil, nil, nil, NSLocalizedString(@"iTunes.messages.noTrackPlaying.detail", @""));
return;
}
NSString *oldLyrics = [track lyrics];
if (oldLyrics != nil && [oldLyrics length] > 0) {
NSBeginAlertSheet(NSLocalizedString(@"iTunes.messages.replaceLyrics.title", @""), NSLocalizedString(@"Yes", @""), NSLocalizedString(@"No", @""), nil, window, self, @selector(replaceLyricsSheetDidEnd:returnCode:contextInfo:), nil, nil, NSLocalizedString(@"iTunes.messages.replaceLyrics.detail", @""));
} else {
[self replaceLyricsSheetDidEnd:nil returnCode:NSAlertDefaultReturn contextInfo:nil];
}
}
- (void)replaceLyricsSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
if (returnCode == NSAlertDefaultReturn) {
iTunesTrack *track = [iTunes currentTrack];
[track setLyrics:[lyricsArea string]];
[GrowlApplicationBridge notifyWithTitle:NSLocalizedString(@"Growl.messages.lyricsSent.title", @"") description:[NSString stringWithFormat:NSLocalizedString(@"Growl.messages.lyricsSent.detail", @""), [track name]] notificationName:@"Lyrics sent to iTunes" iconData:nil priority:0 isSticky:NO clickContext:nil];
}
}
- (IBAction)downloadLyrics:(id)sender {
NSSavePanel *savePanel = [NSSavePanel savePanel];
[savePanel setAllowedFileTypes:[NSArray arrayWithObject:@"txt"]];
[savePanel setAllowsOtherFileTypes:YES];
[savePanel setCanSelectHiddenExtension:YES];
[savePanel setExtensionHidden:YES];
[savePanel setNameFieldStringValue:[currentLyrics name]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(savePanelDidClose:) name:NSWindowDidEndSheetNotification object:window];
void (^handler) (NSInteger) = ^(NSInteger result) {
selectedSavePanelButton = result;
saveFile = [savePanel URL];
};
[savePanel beginSheetModalForWindow:window completionHandler:handler];
}
-(void) savePanelDidClose: (NSNotification *) notification{
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidEndSheetNotification object:window];
if (selectedSavePanelButton == NSOKButton) {
BOOL success = [[[lyricsArea string] dataUsingEncoding:NSUTF8StringEncoding] writeToURL:saveFile atomically:NO];
if (!success) {
NSBeginAlertSheet(NSLocalizedString(@"messages.error.saveLyrics.title", @""), NSLocalizedString(@"OK", @""), nil, nil, window, nil, nil, nil, nil, NSLocalizedString(@"messages.error.saveLyrics.detail", @""));
} else {
[GrowlApplicationBridge notifyWithTitle:NSLocalizedString(@"Growl.messages.lyricsSaved.title", @"") description:[NSString stringWithFormat:NSLocalizedString(@"Growl.messages.lyricsSaved.detail", @""), [saveFile path]] notificationName:@"Lyrics saved to File" iconData:nil priority:0 isSticky:NO clickContext:nil];
}
}
}
-(Lyrics *)currentLyrics {
return currentLyrics;
}
#pragma mark -
#pragma mark Show the window
- (IBAction)showiLyricsWindow:(id)sender {
[window makeKeyAndOrderFront:sender];
}
#pragma mark window delegate
-(BOOL)validateMenuItem:(NSMenuItem *)menuItem {
return [self validateUserInterfaceItem:menuItem];
}
-(BOOL)validateToolbarItem:(NSToolbarItem *)theItem {
return [self validateUserInterfaceItem:theItem];
}
-(BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
SEL action = [item action];
if (action == @selector(downloadLyrics:)) {
[downloadLyricsButton setEnabled:lyricsSelected];
return lyricsSelected;
}
if (action == @selector(sendLyricsToiTunes:)) {
BOOL enabled = lyricsSelected && [iTunes isRunning];
[sendToiTunesButton setEnabled:enabled];
return enabled;
}
if (action == @selector(getCurrentiTunesSong:)) {
return [iTunes isRunning];
}
if (action == @selector(showPreview:)) {
return [resultsOutline clickedRow] >= 0;
}
return [self respondsToSelector:[item action]];
}
-(void)windowDidBecomeMain:(NSNotification *)notification {
[iLyricsMenuItem setOffStateImage:nil];
[iLyricsMenuItem setState:NSOnState];
}
-(void)windowDidResignMain:(NSNotification *)notification {
[iLyricsMenuItem setOffStateImage:nil];
[iLyricsMenuItem setState:NSOffState];
}
-(void)windowDidMiniaturize:(NSNotification *)notification {
NSString *imgPath = [[NSBundle mainBundle] pathForImageResource:@"Diamond"];
NSImage *miniaturizedImage = [[NSImage alloc] initWithContentsOfFile:imgPath];
[iLyricsMenuItem setOffStateImage:miniaturizedImage];
[iLyricsMenuItem setState:NSOffState];
}
-(void)saveToDefalts:(NSUserDefaults *)defaults {
[defaults setBool:[showPreviewCheckBox state] == NSOnState forKey:@"Show preview"];
}
-(void)loadFromDefaults:(NSUserDefaults *)defaults {
[showPreviewCheckBox setState:[defaults boolForKey:@"Show preview"]?NSOnState:NSOffState];
}
@end