Speaker/SpeakerAppDelegate.m
2014-11-14 00:09:38 +01:00

245 lines
7.8 KiB
Objective-C

//
// SpeakerAppDelegate.m
// Speaker
//
// Created by Jeena on 24.09.10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "SpeakerAppDelegate.h"
@interface SpeakerAppDelegate (private)
- (void)initLanugageMenu;
@end
@implementation SpeakerAppDelegate
@synthesize languageMenu;
@synthesize languageMenuPopupButton;
@synthesize speakButton;
@synthesize synth;
@synthesize window, textView;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
synth.delegate = self;
oldRange = NSMakeRange(-1, -1);
isNewLocation = YES;
languages = nil;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *string = [defaults objectForKey:@"text"];
if (string) {
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:string];
[[textView textStorage] setAttributedString:attributedString];
NSRange aRange = NSMakeRange([defaults integerForKey:@"startLocation"], 0);
[textView setSelectedRange:aRange];
[textView scrollRangeToVisible:aRange];
}
float volume = [defaults floatForKey:@"volume"];
if (volume == 0.0) {
synth.volume = 1.0;
} else {
synth.volume = volume / 100;
}
[self initLanugageMenu];
}
- (void)initLanugageMenu
{
NSString *startName = [[NSUserDefaults standardUserDefaults] stringForKey:@"languageVoiceName"];
NSLocale *currentLocale = [NSLocale currentLocale];
NSArray *voices = [NSSpeechSynthesizer availableVoices];
[self.languageMenu removeAllItems];
NSMutableArray *langs = [NSMutableArray arrayWithCapacity:[voices count]];
NSMutableArray *defaultVoices = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:@"defaultVoices"];
for (NSInteger i = 0; i < [voices count]; i++)
{
NSDictionary *dict = [NSSpeechSynthesizer attributesForVoice:[voices objectAtIndex:i]];
NSString *countryString = [currentLocale displayNameForKey:NSLocaleIdentifier value:[dict objectForKey:@"VoiceLocaleIdentifier"]];
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[dict objectForKey:@"VoiceName"] action:@selector(changeLanguage:) keyEquivalent:@""];
NSMenuItem *country = [self.languageMenu itemWithTitle:countryString];
if (!country) {
country = [[NSMenuItem alloc] initWithTitle:countryString action:nil keyEquivalent:@""];
NSMenu *submenu = [[NSMenu alloc] init];
[country setSubmenu:submenu];
[self.languageMenu addItem:country];
[langs addObject:[[[dict objectForKey:@"VoiceLanguage"] componentsSeparatedByString:@"-"] objectAtIndex:0]];
}
item.tag = i;
[[country submenu] addItem:item];
if ([defaultVoices indexOfObjectIdenticalTo:item.title] != NSNotFound) {
item.state = NSOnState;
}
if ((![[NSUserDefaults standardUserDefaults] objectForKey:@"languageVoiceIndex"] && [[dict objectForKey:@"VoiceName"] isEqualToString:@"Alex"]) || [item.title isEqualToString:startName])
{
//startItem = item;
}
}
languages = langs;
}
- (void)changeLanguage:(id)sender
{
NSMenuItem *item = (NSMenuItem *)sender;
NSMenuItem *parent = item.parentItem;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *defaultVoices = [defaults mutableArrayValueForKey:@"defaultVoices"];
for (NSMenuItem *child in parent.submenu.itemArray) {
if (child.state == NSOnState) {
[defaultVoices removeObjectIdenticalTo:child.title];
child.state = NSOffState;
}
}
item.state = NSOnState;
[defaultVoices addObject:item.title];
[defaults synchronize];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:[textView selectedRange].location forKey:@"startLocation"];
[defaults setObject:[[textView textStorage] string] forKey:@"text"];
[defaults synchronize];
}
-(IBAction)speakAction:(id)sender {
if ([synth isSpeaking]) {
[self stopSpeaking];
speakButton.image = [NSImage imageNamed:@"play.png"];
} else {
[self startSpeaking];
speakButton.image = [NSImage imageNamed:@"pause.png"];
}
}
-(void)stopSpeaking {
[synth pauseSpeakingAtBoundary:NSSpeechWordBoundary];
[textView setEditable:YES];
}
-(void)startSpeaking {
[synth stopSpeaking];
[textView setEditable:NO];
NSRange range = [textView selectedRange];
if (range.location == [[[textView textStorage] string] length]) {
range.location = 0;
[textView setSelectedRange:NSMakeRange(0,0)];
[textView scrollRangeToVisible:NSMakeRange(0,0)];
}
NSString *wholeText = [[textView textStorage] string];
NSString *text = nil;
if (range.length > 0) { // selection
text = [wholeText substringWithRange:range];
} else { // only pointer
text = [wholeText substringWithRange:NSMakeRange(range.location, [wholeText length] - range.location)];
}
[self setVoiceForLanguage:[self findLanguageFromString:text]];
[synth startSpeakingString:text];
oldRange = range;
}
-(IBAction)seekForward:(id)sender {
// not working yet
[self stopSpeaking];
NSRange selected = [textView selectedRange];
NSString *wholeText = [[textView textStorage] string];
NSRange position = [wholeText rangeOfString:@". " options:NSLiteralSearch range:NSMakeRange(selected.location + 1, [wholeText length] - selected.location - 1)];
[textView setSelectedRange:NSMakeRange(position.location + 2, 0)];
[self startSpeaking];
}
-(IBAction)seekBack:(id)sender {
}
- (IBAction)setVolume:(NSSlider *)sender {
BOOL restart = NO;
if ([synth isSpeaking]) {
restart = YES;
[self stopSpeaking];
}
synth.volume = sender.floatValue / 100;
if (restart) {
[self startSpeaking];
}
}
- (void)speechSynthesizer:(NSSpeechSynthesizer *)sender willSpeakWord:(NSRange)wordToSpeak ofString:(NSString *)text {
NSRange range = NSMakeRange(oldRange.location + wordToSpeak.location, wordToSpeak.length);
[textView scrollRangeToVisible:range];
[textView setSelectedRange:NSMakeRange(range.location, 0)];
[textView showFindIndicatorForRange:range];
[textView display];
}
- (void)changeVoiceGender:(id)sender
{
}
- (void)speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)success {
[textView setEditable:YES];
}
- (NSString *)findLanguageFromString:(NSString *)text
{
NSArray *tagschemes = [NSArray arrayWithObjects:NSLinguisticTagSchemeLanguage, nil];
NSLinguisticTagger *tagger = [[NSLinguisticTagger alloc] initWithTagSchemes:tagschemes options:0];
[tagger setString:[[[text componentsSeparatedByCharactersInSet:[[NSCharacterSet letterCharacterSet] invertedSet]] componentsJoinedByString:@" "] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSString *language = [tagger tagAtIndex:0 scheme:NSLinguisticTagSchemeLanguage tokenRange:NULL sentenceRange:NULL];
return language;
}
- (void)setVoiceForLanguage:(NSString *)language
{
NSMenuItem *item;
NSMenuItem *languageItem;
for (NSInteger i = 0; i < [languages count]; i++)
{
if ([[languages objectAtIndex:i] isEqualToString:language]) {
languageItem = [[self.languageMenu itemArray] objectAtIndex:i];
for (item in [languageItem.submenu itemArray]) {
if (item.state == NSOnState) {
break;
}
}
item = [[languageItem.submenu itemArray] objectAtIndex:0];
}
}
if (languageItem && item) {
NSString *voice = [[NSSpeechSynthesizer attributesForVoice:[[NSSpeechSynthesizer availableVoices] objectAtIndex:item.tag]] objectForKey:@"VoiceIdentifier"];
[synth setVoice:voice];
[self.languageMenuPopupButton selectItem:languageItem];
}
}
@end