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