William Bowling is sharing code with you
Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.
Don't show this again1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | /*
* Adium is the legal property of its developers, whose names are listed in the copyright file included
* with this source distribution.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "AISoundController.h"
#import "ESAnnouncerAbstractDetailPane.h"
#import "ESAnnouncerPlugin.h"
#import <Adium/AIContactAlertsControllerProtocol.h>
#import <AIUtilities/AIMenuAdditions.h>
#import <Adium/AILocalizationButton.h>
@interface ESAnnouncerAbstractDetailPane ()
- (NSMenu *)voicesMenu;
@end
/*!
* @class ESAnnouncerAbstractDetailPane
* @brief Abstract superclass for Announcer action (Speak Event and Speak Text) detail panes
*/
@implementation ESAnnouncerAbstractDetailPane
/*!
* @brief View did load
*/
- (void)viewDidLoad
{
[super viewDidLoad];
[checkBox_speakEventTime setTitle:SPEAK_EVENT_TIME];
[checkBox_speakContactName setLocalizedString:AILocalizedString(@"Speak Name",nil)];
[checkBox_customPitch setLocalizedString:AILocalizedString(@"Use custom pitch:",nil)];
[checkBox_customRate setLocalizedString:AILocalizedString(@"Use custom rate:",nil)];
[label_voice setLocalizedString:AILocalizedString(@"Voice:", nil)];
[popUp_voices setMenu:[self voicesMenu]];
}
/*!
* @brief Configure for the action
*/
- (void)configureForActionDetails:(NSDictionary *)inDetails listObject:(AIListObject *)inObject
{
BOOL speakTime, speakContactName;
NSString *voice;
NSNumber *pitchNumber, *rateNumber;
if (!inDetails) inDetails = [adium.preferenceController preferenceForKey:[self defaultDetailsKey]
group:PREF_GROUP_ANNOUNCER];
speakTime = [[inDetails objectForKey:KEY_ANNOUNCER_TIME] boolValue];
speakContactName = [[inDetails objectForKey:KEY_ANNOUNCER_SENDER] boolValue];
if ((voice = [inDetails objectForKey:KEY_VOICE_STRING])) {
[popUp_voices selectItemWithTitle:voice];
} else {
[popUp_voices selectItemAtIndex:0]; //"Default"
}
if ((pitchNumber = [inDetails objectForKey:KEY_PITCH])) {
[slider_pitch setFloatValue:[pitchNumber floatValue]];
} else {
[slider_pitch setFloatValue:[adium.soundController defaultPitch]];
}
[checkBox_customPitch setState:[[inDetails objectForKey:KEY_PITCH_CUSTOM] boolValue]];
if ((rateNumber = [inDetails objectForKey:KEY_RATE])) {
[slider_rate setFloatValue:[rateNumber floatValue]];
} else {
[slider_rate setFloatValue:[adium.soundController defaultRate]];
}
[checkBox_customRate setState:[[inDetails objectForKey:KEY_RATE_CUSTOM] boolValue]];
[checkBox_speakEventTime setState:speakTime];
[checkBox_speakContactName setState:speakContactName];
[self configureControlDimming];
}
- (void)configureControlDimming
{
[super configureControlDimming];
[slider_rate setEnabled:[checkBox_customRate state]];
[slider_pitch setEnabled:[checkBox_customPitch state]];
}
/*!
* @brief Configure controls specially for message events.
*
* Speaking of the name is only disable-able for message events.
*/
- (void)configureForEventID:(NSString *)eventID listObject:(AIListObject *)inObject
{
if ([adium.contactAlertsController isMessageEvent:eventID]) {
[checkBox_speakContactName setEnabled:YES];
} else {
[checkBox_speakContactName setEnabled:NO];
[checkBox_speakContactName setState:NSOnState];
}
}
/*!
* @brief Return action details
*
* Should be overridden, with the subclass returning [self actionDetailsDromDict:actionDetails]
* where actionDetails is the dictionary of what it itself needs to store
*/
- (NSDictionary *)actionDetails
{
NSDictionary *actionDetails = [self actionDetailsFromDict:nil];
//Save the preferred settings for future use as defaults
[adium.preferenceController setPreference:actionDetails
forKey:[self defaultDetailsKey]
group:PREF_GROUP_ANNOUNCER];
return actionDetails;
}
/*!
* @brief Used by subclasses; adds the general information managed by the superclass to the details dictionary.
*/
- (NSDictionary *)actionDetailsFromDict:(NSMutableDictionary *)actionDetails
{
NSNumber *speakTime, *speakContactName, *pitch, *rate;
NSString *voice;
if (!actionDetails) actionDetails = [NSMutableDictionary dictionary];
speakTime = [NSNumber numberWithBool:([checkBox_speakEventTime state] == NSOnState)];
speakContactName = [NSNumber numberWithBool:([checkBox_speakContactName state] == NSOnState)];
voice = [[popUp_voices selectedItem] representedObject];
pitch = [NSNumber numberWithFloat:[slider_pitch floatValue]];
rate = [NSNumber numberWithFloat:[slider_rate floatValue]];
if (voice) {
[actionDetails setObject:voice
forKey:KEY_VOICE_STRING];
}
if ([pitch floatValue] != [adium.soundController defaultPitch]) {
[actionDetails setObject:pitch
forKey:KEY_PITCH];
}
if ([rate floatValue] != [adium.soundController defaultRate]) {
[actionDetails setObject:rate
forKey:KEY_RATE];
}
[actionDetails setObject:[NSNumber numberWithBool:[checkBox_customRate state]]
forKey:KEY_RATE_CUSTOM];
[actionDetails setObject:[NSNumber numberWithBool:[checkBox_customPitch state]]
forKey:KEY_PITCH_CUSTOM];
[actionDetails setObject:speakTime
forKey:KEY_ANNOUNCER_TIME];
[actionDetails setObject:speakContactName
forKey:KEY_ANNOUNCER_SENDER];
return actionDetails;
}
/*!
* @brief Key on which to store our defaults
*
* Must be overridden by subclasses
*/
- (NSString *)defaultDetailsKey
{
return nil;
}
/*!
* @brief Speech voices menu
*/
- (NSMenu *)voicesMenu
{
NSMenu *voicesMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
NSMenuItem *menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:AILocalizedString(@"Use System Default",nil)
target:nil
action:nil
keyEquivalent:@""] autorelease];
[voicesMenu addItem:menuItem];
[voicesMenu addItem:[NSMenuItem separatorItem]];
NSMutableDictionary *voices = [NSMutableDictionary dictionary];
NSArray *rawVoices = [[NSSpeechSynthesizer availableVoices] sortedArrayUsingSelector:@selector(compare:)];
for (NSString *voiceID in rawVoices) {
[voices setObject:[[NSSpeechSynthesizer attributesForVoice:voiceID] objectForKey:NSVoiceName] forKey:voiceID];
}
for (NSString *voiceID in rawVoices) {
menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:[voices objectForKey:voiceID]
target:nil
action:nil
keyEquivalent:@""] autorelease];
[menuItem setRepresentedObject:voiceID];
[voicesMenu addItem:menuItem];
}
return voicesMenu;
}
/*!
* @brief Preference changed
*/
-(IBAction)changePreference:(id)sender
{
NSString *voice = [[popUp_voices selectedItem] representedObject];
//If the Default voice is selected, also set the pitch and rate to defaults
if (sender == popUp_voices) {
if (!voice) {
[slider_pitch setFloatValue:[adium.soundController defaultPitch]];
[slider_rate setFloatValue:[adium.soundController defaultRate]];
voice = [NSSpeechSynthesizer defaultVoice];
}
}
if (sender == popUp_voices ||
(sender == slider_pitch || sender == checkBox_customPitch) ||
(sender == slider_rate || sender == checkBox_customRate)) {
[adium.soundController speakDemoTextForVoice:voice
withPitch:([checkBox_customPitch state] ? [slider_pitch floatValue] : 0.0)
andRate:([checkBox_customRate state] ? [slider_rate floatValue] : 0.0)];
}
[super changePreference:sender];
}
@end
|