libgaim.framework [386] which has extensive debugging in the upnp module to try to...
[adiumx.git] / Source / ESEventSoundAlertDetailPane.m
blobff7b7d4efc620503e1da7e38d58be88e4ec085be
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 "AIEventSoundsPlugin.h"
18 #import <Adium/AIPreferenceControllerProtocol.h>
19 #import "AISoundController.h"
20 #import "ESEventSoundAlertDetailPane.h"
21 #import <AIUtilities/AIMenuAdditions.h>
22 #import <AIUtilities/AIStringAdditions.h>
23 #import <AIUtilities/AIImageAdditions.h>
24 #import <Adium/AISoundSet.h>
25 #import <Adium/AILocalizationTextField.h>
27 #define PLAY_A_SOUND                    AILocalizedString(@"Play a sound",nil)
28 #define KEY_DEFAULT_SOUND_DICT  @"Default Sound Dict"
30 @interface ESEventSoundAlertDetailPane (PRIVATE)
31 - (NSMenu *)soundListMenu;
32 - (void)addSound:(NSString *)soundPath toMenu:(NSMenu *)soundMenu;
33 @end
35 /*!
36  * @class ESEventSoundAlertDetailPane
37  * @brief Details pane for the Play Sound action
38  */
39 @implementation ESEventSoundAlertDetailPane
41 /*!
42  * @brief Nib name
43  */
44 - (NSString *)nibName{
45     return @"EventSoundContactAlert";    
48 /*!
49  * @brief Configure the detail view
50  */
51 - (void)viewDidLoad
53         [label_sound setLocalizedString:AILocalizedString(@"Sound:",nil)];
55         /* Loading and using the real file icons is slow, and all the sound files should have the same icons anyway.  So
56          * we can cheat and load a sound icon from our bundle here (for all the menu items) for a nice speed boost. */
57         if (!soundFileIcon) soundFileIcon = [[NSImage imageNamed:@"SoundFileIcon" forClass:[self class]] retain];
58         
59         //Prepare our sound menu
60     [popUp_actionDetails setMenu:[self soundListMenu]];
61         
62         [super viewDidLoad];
65 /*!
66  * @brief View will close
67  */
68 - (void)viewWillClose
70         [soundFileIcon release]; soundFileIcon = nil;
71         [super viewWillClose];
74 /*!
75  * @brief Configure for the action
76  */
77 - (void)configureForActionDetails:(NSDictionary *)inDetails listObject:(AIListObject *)inObject
79         NSString        *selectedSound;
80         int                     soundIndex;
81         
82         if (!inDetails) inDetails = [[adium preferenceController] preferenceForKey:KEY_DEFAULT_SOUND_DICT
83                                                                                                                                                 group:PREF_GROUP_SOUNDS];
85         //If the user has a custom sound selected, we need to create an entry in the menu for it
86         selectedSound = [inDetails objectForKey:KEY_ALERT_SOUND_PATH];
87         if (selectedSound) {
88                 if ([[popUp_actionDetails menu] indexOfItemWithRepresentedObject:selectedSound] == -1) {
89                         [self addSound:selectedSound toMenu:[popUp_actionDetails menu]];
90                 }
91                 
92                 //Set the menu to its previous setting if the stored event matches
93                 soundIndex = [popUp_actionDetails indexOfItemWithRepresentedObject:[inDetails objectForKey:KEY_ALERT_SOUND_PATH]];
94                 if (soundIndex >= 0 && soundIndex < [popUp_actionDetails numberOfItems]) {
95                         [popUp_actionDetails selectItemAtIndex:soundIndex];        
96                 }
97                 
98         } else {
99                 [popUp_actionDetails selectItemAtIndex:-1];
100         }       
104  * @brief Return our current configuration
105  */
106 - (NSDictionary *)actionDetails
108         NSString                *soundPath = [[popUp_actionDetails selectedItem] representedObject];
109         NSDictionary    *actionDetails = nil;
111         if (soundPath && [soundPath length]) {
112                 actionDetails = [NSDictionary dictionaryWithObject:soundPath forKey:KEY_ALERT_SOUND_PATH];
113         }
115         //Save the preferred settings for future use as defaults
116         [[adium preferenceController] setPreference:actionDetails
117                                                                                  forKey:KEY_DEFAULT_SOUND_DICT
118                                                                                   group:PREF_GROUP_SOUNDS];
119         
120         return actionDetails;
124 //Sound Menu -----------------------------------------------------------------------------------------------------------
125 #pragma mark Sound Menu
127  * @brief Builds and returns a sound list menu
129  * The menu is organized by sound set.
130  */
131 - (NSMenu *)soundListMenu
133         NSMenu                  *soundMenu = [[NSMenu alloc] init];
134         NSEnumerator    *enumerator;
135         AISoundSet              *soundSet;
136         NSMenuItem              *menuItem;
137         
138         //Add all soundsets to our menu
139         enumerator = [[[adium soundController] soundSets] objectEnumerator];
140         while ((soundSet = [enumerator nextObject])) {
141                 NSString        *soundSetName = nil;
142                 NSArray         *soundSetContents = nil;
143                 NSEnumerator    *soundEnumerator;
144                 NSString        *soundPath;
146                 soundSetName = [soundSet name];
147                 soundSetContents = [[soundSet sounds] allValues];
149                 NSAssert1(soundSetName != nil, @"Sound set does not have a name: %@", soundSet);
150                 
151                 if (soundSetContents && [soundSetContents count]) {
152                         NSMenu  *soundsetMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] init];
154                         //Add an item for the set
155                         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:soundSetName
156                                                                                                                                                          target:nil
157                                                                                                                                                          action:nil
158                                                                                                                                           keyEquivalent:@""] autorelease];
159                         
160                         //Add an item for each sound
161                         soundEnumerator = [soundSetContents objectEnumerator];
162                         while ((soundPath = [soundEnumerator nextObject])) {
163                                 [self addSound:soundPath toMenu:soundsetMenu];
164                         }
165                         
166                         [menuItem setSubmenu:soundsetMenu];
167                         [soundsetMenu release];
169                         [soundMenu addItem:menuItem];
170                 }
171         }
173         //Add a divider between the sets and Other...
174         [soundMenu addItem:[NSMenuItem separatorItem]];
176         //Add the "Other..." item
177         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:OTHER_ELLIPSIS
178                                                                                                                                          target:self
179                                                                                                                                          action:@selector(selectSound:)
180                                                                                                                           keyEquivalent:@""] autorelease];            
181         [soundMenu addItem:menuItem];
182         [soundMenu setAutoenablesItems:NO];
183         
184     return [soundMenu autorelease];
188  * @brief Add a sound menu item to a menu
189  */
190 - (void)addSound:(NSString *)soundPath toMenu:(NSMenu *)soundMenu
192         NSString        *soundTitle = [[soundPath lastPathComponent] stringByDeletingPathExtension];
193         NSMenuItem      *menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:soundTitle
194                                                                                                                                                                   target:self
195                                                                                                                                                                   action:@selector(selectSound:)
196                                                                                                                                                    keyEquivalent:@""] autorelease];
197         
198         [menuItem setRepresentedObject:[soundPath stringByCollapsingBundlePath]];
199         [menuItem setImage:soundFileIcon];
200         [soundMenu addItem:menuItem];
204  * @brief Add a soundPath to the menu root if it is not yet present, then select it
206  * @param The soundPath, which should have a collapsed bundle path (to match menuItem represented objects)
207  */
208 - (void)addAndSelectSoundPath:(NSString *)soundPath
210         NSMenu  *rootMenu = [popUp_actionDetails menu];
211         int             menuIndex;
212         
213         //Check for it currently being present in the root menu
214         menuIndex = [popUp_actionDetails indexOfItemWithRepresentedObject:soundPath];
215         if (menuIndex == -1) {
216                 //Add it if it wasn't found
217                 [self addSound:soundPath toMenu:rootMenu];
218                 menuIndex = [popUp_actionDetails indexOfItemWithRepresentedObject:soundPath];                   
219         }
220         
221         if (menuIndex != -1) {
222                 [popUp_actionDetails selectItemAtIndex:menuIndex];
223         }
227  * @brief A sound was selected from a sound popUp menu
229  * Update our header and play the sound.  If "Other..." is selected, allow selection of a file.
230  */
231 - (IBAction)selectSound:(id)sender
233     NSString    *soundPath = [sender representedObject];
234     
235     if (soundPath != nil && [soundPath length] != 0) {
236         [[adium soundController] playSoundAtPath:[soundPath stringByExpandingBundlePath]]; //Play the sound
238                 //Update the menu and and the selection
239                 [self addAndSelectSoundPath:soundPath];
241                 [self detailsForHeaderChanged];
242     } else { //selected "Other..."
243         NSOpenPanel *openPanel = [NSOpenPanel openPanel];
244         
245         [openPanel 
246             beginSheetForDirectory:nil
247                               file:nil
248                              types:[NSSound soundUnfilteredFileTypes] //allow all the sounds NSSound understands
249                     modalForWindow:[view window]
250                      modalDelegate:self
251                     didEndSelector:@selector(concludeOtherPanel:returnCode:contextInfo:)
252                        contextInfo:nil];  
254     }
258  * @brief Finish up the Other... panel
260  * Play the selected sound and update the menu.
261  */
262 - (void)concludeOtherPanel:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
264     if (returnCode == NSOKButton) {
265         NSString *soundPath = [[panel filenames] objectAtIndex:0];
266         
267         [[adium soundController] playSoundAtPath:soundPath]; //Play the sound
269         //Update the menu and and the selection
270                 [self addAndSelectSoundPath:soundPath];
272                 [self detailsForHeaderChanged];
273     }
276 @end