Finally fixed all the memory leaks, I hope. Fixed iTunesRemote to not
[MenuTunes.git] / StatusWindowController.m
1 #import "StatusWindowController.h"
2 #import "StatusWindow.h"
3 #import "PreferencesController.h"
4 #import "MainController.h"
5
6 #import <ITKit/ITTSWBackgroundView.h>
7 #import <ITKit/ITWindowEffect.h>
8 #import <ITKit/ITCutWindowEffect.h>
9 #import <ITKit/ITDissolveWindowEffect.h>
10 #import <ITKit/ITSlideHorizontallyWindowEffect.h>
11 #import <ITKit/ITSlideVerticallyWindowEffect.h>
12 #import <ITKit/ITPivotWindowEffect.h>
13
14 static StatusWindowController *sharedController;
15
16 @implementation StatusWindowController
17
18
19 + (StatusWindowController *)sharedController
20 {
21     if ( ! sharedController ) {
22         sharedController = [[StatusWindowController alloc] init];
23     }
24     
25     return sharedController;
26 }
27
28
29 - (id)init
30 {
31     if ( ( self = [super init] ) ) {
32         
33         float exitDelay;
34         NSString *entryClass;
35         NSString *exitClass;
36         NSArray  *classList = [ITWindowEffect effectClasses];
37         float entrySpeed;
38         float exitSpeed;
39         
40         NSData *colorData;
41         
42         ITWindowEffect *entryEffect;
43         ITWindowEffect *exitEffect;
44         
45         _window = [[StatusWindow sharedWindow] retain];
46         df = [[NSUserDefaults standardUserDefaults] retain];
47         
48         exitDelay  = [df floatForKey:@"statusWindowVanishDelay"];
49         entryClass = [df stringForKey:@"statusWindowAppearanceEffect"];
50         exitClass  = [df stringForKey:@"statusWindowVanishEffect"];
51         entrySpeed = [df floatForKey:@"statusWindowAppearanceSpeed"];
52         exitSpeed  = [df floatForKey:@"statusWindowVanishSpeed"];
53         
54         [_window setExitMode:ITTransientStatusWindowExitAfterDelay];
55         [_window setExitDelay:(exitDelay ? exitDelay : 4.0)];
56         
57         [_window setHorizontalPosition:[df integerForKey:@"statusWindowHorizontalPosition"]];
58         [_window setVerticalPosition:[df integerForKey:@"statusWindowVerticalPosition"]];
59         
60         [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
61         
62         if ( [classList containsObject:NSClassFromString(entryClass)] ) {
63             entryEffect = [[[NSClassFromString(entryClass) alloc] initWithWindow:_window] autorelease];
64         } else {
65             entryEffect = [[[ITCutWindowEffect alloc] initWithWindow:_window] autorelease];
66         }
67         
68         if ( [classList containsObject:NSClassFromString(exitClass)] ) {
69             exitEffect = [[[NSClassFromString(exitClass) alloc] initWithWindow:_window] autorelease];
70         } else {
71             exitEffect = [[[ITDissolveWindowEffect alloc] initWithWindow:_window] autorelease];
72         }
73         
74         [_window setEntryEffect:entryEffect];
75         [_window setExitEffect:exitEffect];
76         
77         [[_window entryEffect] setEffectTime:(entrySpeed ? entrySpeed : 0.8)];
78         [[_window exitEffect]  setEffectTime:(exitSpeed  ? exitSpeed  : 0.8)];
79         
80         [(ITTSWBackgroundView *)[_window contentView]setBackgroundMode:
81             (ITTSWBackgroundMode)[df integerForKey:@"statusWindowBackgroundMode"]];
82         
83         colorData = [df dataForKey:@"statusWindowBackgroundColor"];
84         
85         if ( colorData ) {
86             [(ITTSWBackgroundView *)[_window contentView] setBackgroundColor:
87                 (NSColor *)[NSUnarchiver unarchiveObjectWithData:colorData]];
88         } else {
89             [(ITTSWBackgroundView *)[_window contentView] setBackgroundColor:[NSColor blueColor]];
90         }
91     }
92     
93     return self;
94 }
95
96 - (void)dealloc
97 {
98     [_window release];
99     [super dealloc];
100 }
101
102 - (void)showSongInfoWindowWithSource:(ITMTRemotePlayerSource)source
103                                title:            (NSString *)title
104                                album:            (NSString *)album
105                               artist:            (NSString *)artist
106                             composer:            (NSString *)composer
107                                 time:            (NSString *)time  // FLOW: Should probably be NSDate or something.
108                                track:            (NSString *)track
109                               rating:                   (int)rating
110                            playCount:                   (int)playCount
111                                image:             (NSImage *)art
112 {
113     NSImage  *image = nil;
114     NSString *text  = title;
115     
116     if ( art != nil ) {
117         image = art;
118     } else if ( source == ITMTRemoteLibrarySource ) {
119         image = [NSImage imageNamed:@"Library"];
120     } else if ( source == ITMTRemoteCDSource ) {
121         image = [NSImage imageNamed:@"CD"];
122     } else if ( source == ITMTRemoteRadioSource ) {
123         image = [NSImage imageNamed:@"Radio"];
124     } else if ( source == ITMTRemoteiPodSource ) {
125         image = [NSImage imageNamed:@"iPod"];
126     } else if ( source == ITMTRemoteGenericDeviceSource ) {
127         image = [NSImage imageNamed:@"MP3Player"];
128     } else if ( source == ITMTRemoteSharedLibrarySource ) {
129         image = [NSImage imageNamed:@"Library"];
130     }
131     
132     [_window setImage:image];
133     
134     if ( album ) {
135         text = [text stringByAppendingString:[@"\n" stringByAppendingString:album]];
136     }
137     if ( artist ) {
138         text = [text stringByAppendingString:[@"\n" stringByAppendingString:artist]];
139     }
140     if ( composer ) {
141         text = [text stringByAppendingString:[@"\n" stringByAppendingString:composer]];
142     }
143     if ( time ) {
144         text = [text stringByAppendingString:[@"\n" stringByAppendingString:time]];
145     }
146     if ( track ) {
147         text = [text stringByAppendingString:[@"\n" stringByAppendingString:track]];
148     }
149     if (playCount > -1) {
150         text = [text stringByAppendingString:[NSString stringWithFormat:@"\nPlay Count: %i", playCount]];
151     }
152     if ( rating > -1 ) {
153
154         NSString *ratingString = [NSString string];
155         NSString *emptyChar    = [NSString stringWithUTF8String:"☆"];
156         NSString *fullChar     = [NSString stringWithUTF8String:"★"];
157         int       i;
158         
159         for ( i = 1; i < 6; i++ ) {
160                 
161             if ( rating >= i ) {
162                 ratingString = [ratingString stringByAppendingString:fullChar];
163             } else {
164                 ratingString = [ratingString stringByAppendingString:emptyChar];
165             }
166         }
167     
168         text = [text stringByAppendingString:[@"\n" stringByAppendingString:ratingString]];
169     }
170     
171     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
172     [_window buildTextWindowWithString:text];
173     [_window appear:self];
174 }
175
176 - (void)showUpcomingSongsWindowWithTitles:(NSArray *)titleStrings
177 {
178 //  NSString *bull = [NSString stringWithUTF8String:"‣ "];
179     NSString *bull = [NSString stringWithUTF8String:"♪ "];
180     NSString *end  = [@"\n" stringByAppendingString:bull];
181     [_window setImage:[NSImage imageNamed:@"Upcoming"]];
182     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
183     [_window buildTextWindowWithString:[bull stringByAppendingString:[titleStrings componentsJoinedByString:end]]];
184     [_window appear:self];
185 }
186
187 - (void)showVolumeWindowWithLevel:(float)level
188 {
189     [_window setImage:[NSImage imageNamed:@"Volume"]];
190     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
191     [_window buildMeterWindowWithCharacter:[NSString stringWithUTF8String:"▊"]
192                                       size:18
193                                      count:10
194                                     active:( ceil(level * 100) / 10 )];
195     [_window appear:self];
196 }
197
198 - (void)showRatingWindowWithRating:(float)rating
199 {
200     [_window setImage:[NSImage imageNamed:@"Rating"]];
201     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
202     [_window buildMeterWindowWithCharacter:[NSString stringWithUTF8String:"★"]
203                                       size:48
204                                      count:5
205                                     active:( ceil(rating * 100) / 20 )];
206     [_window appear:self];
207 }
208
209 - (void)showShuffleWindow:(BOOL)shuffle
210 {
211     [_window setImage:[NSImage imageNamed:@"Shuffle"]];
212     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
213     [_window buildTextWindowWithString:( shuffle ? @"Shuffle On" : @"Shuffle Off")];
214     [_window appear:self];
215 }
216
217 - (void)showRepeatWindowWithMode:(StatusWindowRepeatMode)mode
218 {
219     NSString *string = nil;
220     
221     if ( mode == StatusWindowRepeatNone ) {
222         string = @"Repeat Off";
223     } else if ( mode == StatusWindowRepeatGroup ) {
224         string = @"Repeat Playlist";
225     } else if ( mode == StatusWindowRepeatTrack ) {
226         string = @"Repeat One Track";
227     }
228     
229     [_window setImage:[NSImage imageNamed:@"Repeat"]];
230     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
231     [_window buildTextWindowWithString:string];
232     [_window appear:self];
233 }
234
235 - (void)showSetupQueryWindow
236 {
237     NSString *message = NSLocalizedString(@"autolaunch_msg", @"Would you like MenuTunes to launch\nautomatically at startup?");
238
239     [_window setImage:[NSImage imageNamed:@"Setup"]];
240     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
241     [_window buildDialogWindowWithMessage:message
242                             defaultButton:NSLocalizedString(@"launch_at_startup", @"Launch at Startup")
243                           alternateButton:NSLocalizedString(@"launch_manually", @"Launch Manually")
244                                    target:[PreferencesController sharedPrefs]
245                             defaultAction:@selector(autoLaunchOK)
246                           alternateAction:@selector(autoLaunchCancel)];
247
248     [_window appear:self];
249     [_window setLocked:YES];
250 }
251
252
253 - (void)showRegistrationQueryWindow
254 {
255     NSString *message = NSLocalizedString(@"trialexpired_msg", @"Your 7-day unlimited trial period has elapsed.\nYou must register to continue using MenuTunes.");
256
257     [_window setImage:[NSImage imageNamed:@"Register"]];
258     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
259     [_window buildDialogWindowWithMessage:message
260                             defaultButton:NSLocalizedString(@"registernow", @"Register Now")
261                           alternateButton:NSLocalizedString(@"quitmenutunes", @"Quit MenuTunes")
262                                    target:[MainController sharedController]
263                             defaultAction:@selector(registerNowOK)
264                           alternateAction:@selector(registerNowCancel)];
265
266     [_window appear:self];
267     [_window setLocked:YES];
268 }
269
270 - (void)showReconnectQueryWindow
271 {
272     NSString *message = NSLocalizedString(@"sharedplayeravailable_msg", @"The selected shared player is available again.\nWould you like to reconnect to it?");
273     [_window setLocked:NO];
274     [_window setImage:[NSImage imageNamed:@"Setup"]];
275     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
276     [_window buildDialogWindowWithMessage:message
277                             defaultButton:NSLocalizedString(@"reconnect", @"Reconnect")
278                           alternateButton:NSLocalizedString(@"ignore", @"Ignore")
279                                    target:[MainController sharedController]
280                             defaultAction:@selector(reconnect)
281                           alternateAction:@selector(cancelReconnect)];
282
283     [_window appear:self];
284     [_window setLocked:YES];
285 }
286
287 - (void)showNetworkErrorQueryWindow
288 {
289     NSString *message = NSLocalizedString(@"sharedplayerunreachable_msg", @"The remote MenuTunes server is unreachable.\nMenuTunes will revert back to the local player.");
290
291     [_window setImage:[NSImage imageNamed:@"Setup"]];
292     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
293     [_window buildDialogWindowWithMessage:message
294                             defaultButton:@" OK "
295                           alternateButton:nil
296                                    target:[MainController sharedController]
297                             defaultAction:@selector(cancelReconnect)
298                           alternateAction:nil];
299
300     [_window appear:self];
301     [_window setLocked:YES];
302 }
303
304 - (void)showPreferencesUpdateWindow
305 {
306     NSString *message = NSLocalizedString(@"reconfigureprefs_msg", @"The new features in this version of MenuTunes\nrequire you to reconfigure your preferences.");
307
308     [_window setImage:[NSImage imageNamed:@"Setup"]];
309     [_window setSizing:(ITTransientStatusWindowSizing)[df integerForKey:@"statusWindowSizing"]];
310     [_window buildDialogWindowWithMessage:message
311                             defaultButton:NSLocalizedString(@"showpreferences", @"Show Preferences")
312                           alternateButton:@"OK"
313                                    target:[MainController sharedController]
314                             defaultAction:@selector(showPreferencesAndClose)
315                           alternateAction:@selector(cancelReconnect)];
316
317     [_window appear:self];
318     [_window setLocked:YES];
319 }
320
321 @end