Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 301 lines (233 sloc) 9.034 kB
dc5be1c Initial check-in.
uli authored
1 //
2 // UKApplicationListController.m
3 // TalkingMoose (XC2)
4 //
5 // Created by Uli Kusterer on 2005-12-07.
720b0e7 @uliwitness Added licensing information to the source files.
authored
6 // Copyright 2005 Uli Kusterer.
7 //
8 // This software is provided 'as-is', without any express or implied
9 // warranty. In no event will the authors be held liable for any damages
10 // arising from the use of this software.
11 //
12 // Permission is granted to anyone to use this software for any purpose,
13 // including commercial applications, and to alter it and redistribute it
14 // freely, subject to the following restrictions:
15 //
16 // 1. The origin of this software must not be misrepresented; you must not
17 // claim that you wrote the original software. If you use this software
18 // in a product, an acknowledgment in the product documentation would be
19 // appreciated but is not required.
20 //
21 // 2. Altered source versions must be plainly marked as such, and must not be
22 // misrepresented as being the original software.
23 //
24 // 3. This notice may not be removed or altered from any source
25 // distribution.
dc5be1c Initial check-in.
uli authored
26 //
27
28 #import "UKApplicationListController.h"
29 #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
30 #import "UKSystemInfo.h"
31 #endif
32
33
34 @implementation UKApplicationListController
35
36 -(id) init
37 {
38 if( (self = [super init]) )
39 {
40 listOfApplications = [[NSMutableArray alloc] init];
41
42 // Instead of on dealloc (which isn't called when we're in MainMenu.nib), we listen for app will quit notifications to save our prefs:
43 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(applicationWillQuit:) name: NSApplicationWillTerminateNotification object: NSApp];
44 }
45
46 return self;
47 }
48
49 -(void) dealloc
50 {
51 [listOfApplications release];
52 listOfApplications = nil;
53
54 [[NSNotificationCenter defaultCenter] removeObserver: self];
55
56 [super dealloc];
57 }
58
59
60 -(void) awakeFromNib
61 {
62 // Load list of apps from prefs here!
63 NSDictionary* dict = [[NSUserDefaults standardUserDefaults] objectForKey: [self userDefaultsKey]];
64 if( dict ) // Have a list in prefs?
65 {
66 // Get rid of old one, add the one from prefs:
67 [listOfApplications autorelease];
68 listOfApplications = [dict mutableCopy];
69
70 // Make all entries in the array mutable:
273f12c Moose fixes: Don't modify the array during enumeration, enumerate the…
uli authored
71 NSEnumerator* appEntryEnny = [dict objectEnumerator];
dc5be1c Initial check-in.
uli authored
72 NSDictionary* currAppEntry = nil;
73 int x = 0;
74
75 while( (currAppEntry = [appEntryEnny nextObject]) )
76 [listOfApplications replaceObjectAtIndex: x++ withObject: [[currAppEntry mutableCopy] autorelease] ];
77 }
78
79 #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
80 #define NSSmallSquareBezelStyle 10
81 // Allow setting up as Square button for pre-10.4 and automatically fix
82 // so it shows Small Square on OS versions that have that new style:
83 if( UKSystemVersion() >= MAC_OS_X_VERSION_10_4 )
84 {
85 [addAppButton setBezelStyle: NSSmallSquareBezelStyle];
86 [removeAppButton setBezelStyle: NSSmallSquareBezelStyle];
87 }
88 #endif
89
90 [applicationListView reloadData];
91 [removeAppButton setEnabled: ([applicationListView selectedRow] >= 0) ];
92 }
93
94
95 -(void) applicationWillQuit: (NSNotification*)notif
96 {
97 // Save list of app dictionaries to prefs:
98 [[NSUserDefaults standardUserDefaults] setObject: listOfApplications forKey: [self userDefaultsKey]];
99 }
100
101
102 -(NSString*) userDefaultsKey
103 {
104 if( autosaveName )
105 return autosaveName;
106 else
107 return @"UKApplicationListController-Apps";
108 }
109
110
111 -(int) numberOfRowsInTableView: (NSTableView*)tableView
112 {
113 return [listOfApplications count];
114 }
115
116
117 -(id) tableView: (NSTableView*)tableView objectValueForTableColumn: (NSTableColumn*)tableColumn row: (int)row
118 {
119 NSMutableDictionary* dict = [listOfApplications objectAtIndex: row];
120
121 if( [[tableColumn identifier] isEqualToString: @"mustBeRunning"] )
122 return [NSNumber numberWithBool: ![[dict objectForKey: @"mustBeFrontmost"] boolValue]];
123 else
124 return [dict objectForKey: [tableColumn identifier]];
125 }
126
127
128 -(void) tableView: (NSTableView*)tableView setObjectValue: (id)object forTableColumn: (NSTableColumn*)tableColumn row: (int)row
129 {
130 NSMutableDictionary* dict = [listOfApplications objectAtIndex: row];
131
132 if( [[tableColumn identifier] isEqualToString: @"mustBeRunning"] )
133 [dict setObject: [NSNumber numberWithBool: ![object boolValue]] forKey: @"mustBeFrontmost"];
134 else
135 [dict setObject: object forKey: [tableColumn identifier]];
136 [tableView setNeedsDisplay: YES];
137 }
138
139
140 -(void) tableViewSelectionDidChange: (NSNotification*)notification
141 {
142 [removeAppButton setEnabled: ([applicationListView selectedRow] >= 0) ];
143 }
144
145
146 -(void) removeSelectedApp: (id)sender
147 {
148 int selRow = [applicationListView selectedRow];
149
150 if( selRow < 0 )
151 return;
152
153 [listOfApplications removeObjectAtIndex: selRow];
154 [applicationListView noteNumberOfRowsChanged];
155 }
156
157
158 -(BOOL) appInListIsRunning
159 {
160 NSEnumerator* appEnny = [listOfApplications objectEnumerator];
161 NSDictionary* currApp = nil;
162 NSArray* runningApps = [[[[NSWorkspace sharedWorkspace] launchedApplications] retain] autorelease];
163
164 while( (currApp = [appEnny nextObject]) )
165 {
166 NSEnumerator* runningAppsEnny = [runningApps objectEnumerator];
167 NSDictionary* currRunningApp = nil;
168
169 while( (currRunningApp = [runningAppsEnny nextObject]) )
170 {
171 if( [[currApp objectForKey: @"applicationPath"] isEqualToString: [currRunningApp objectForKey: @"NSApplicationPath"]] )
172 return YES;
173 }
174 }
175
176 return NO;
177 }
178
179
180 -(BOOL) appInListIsFrontmost
181 {
182 NSEnumerator* appEnny = [listOfApplications objectEnumerator];
183 NSDictionary* currApp = nil;
184 NSDictionary* currRunningApp = [[[[NSWorkspace sharedWorkspace] activeApplication] retain] autorelease];
185
624363c @uliwitness Turn off unneeded logging.
authored
186 //UKLog(@"currRunningApp: %@", currRunningApp);
dc5be1c Initial check-in.
uli authored
187
188 while( (currApp = [appEnny nextObject]) )
189 {
190 if( [[currApp objectForKey: @"applicationPath"] isEqualToString: [currRunningApp objectForKey: @"NSApplicationPath"]] )
191 return YES;
192 }
193
194 return NO;
195 }
196
197
198 -(BOOL) screenSaverRunning
199 {
200 NSDictionary* activeApp = [[NSWorkspace sharedWorkspace] activeApplication];
201 BOOL saverOrFullScreen = activeApp == nil;
202 if( activeApp && !saverOrFullScreen )
203 saverOrFullScreen = [[activeApp objectForKey: @"NSApplicationBundleIdentifier"] isEqualToString: @"com.apple.ScreenSaver.Engine"];
624363c @uliwitness Turn off unneeded logging.
authored
204 //UKLog(@"Screen Saver: %s, %@",(saverOrFullScreen?"YES":"NO"),activeApp);
dc5be1c Initial check-in.
uli authored
205 return( saverOrFullScreen );
206 }
207
208
209 -(BOOL) appInListMatches
210 {
211 NSEnumerator* appEnny = [listOfApplications objectEnumerator];
212 NSDictionary* currApp = nil;
213 NSDictionary* frontmostApp = [[[[NSWorkspace sharedWorkspace] activeApplication] retain] autorelease];
214 NSArray* runningApps = [[[[NSWorkspace sharedWorkspace] launchedApplications] retain] autorelease];
215 NSString* frontmostAppPath = [frontmostApp objectForKey: @"NSApplicationPath"];
216
217 while( (currApp = [appEnny nextObject]) )
218 {
219 NSString* currAppPath = [currApp objectForKey: @"applicationPath"];
220
221 if( [[currApp objectForKey: @"mustBeFrontmost"] boolValue] ) // Must be frontmost? Just compare against frontmost app:
222 {
223 if( [currAppPath isEqualToString: frontmostAppPath] )
224 return YES;
225 }
226 else // Matches when running, even if in back? Check all running apps whether they're this one:
227 {
228 NSEnumerator* runningAppsEnny = [runningApps objectEnumerator];
229 NSDictionary* currRunningApp = nil;
230
231 while( (currRunningApp = [runningAppsEnny nextObject]) )
232 {
233 NSString* currRunningAppPath = [currRunningApp objectForKey: @"NSApplicationPath"];
234
235 if( [currAppPath isEqualToString: currRunningAppPath] )
236 return YES;
237 }
238 }
239 }
240
241 return NO;
242 }
243
244
245
246
247
248 -(void) addApp: (id)sender
249 {
250 NSOpenPanel* appPicker = [NSOpenPanel openPanel];
251
252 [appPicker setCanChooseDirectories: NO];
253 [appPicker setAllowsMultipleSelection: YES];
254 [appPicker setCanChooseFiles: YES];
255 [appPicker setTreatsFilePackagesAsDirectories: NO];
256
257 [appPicker beginSheetForDirectory: @"/Applications" file: @"" types: [NSArray arrayWithObjects: @"app", nil]
258 modalForWindow: [applicationListView window] modalDelegate: self
259 didEndSelector: @selector(appPickerPanelEnded:returnCode:contextInfo:) contextInfo: nil];
260 }
261
262 -(void) appPickerPanelEnded: (NSOpenPanel*)sheet returnCode: (int)returnCode contextInfo: (void*)contextInf
263 {
264 if( returnCode == NSOKButton )
265 {
266 NSEnumerator* filenameEnny = [[sheet filenames] objectEnumerator];
267 NSString* currFilename = nil;
268
269 while( (currFilename = [filenameEnny nextObject]) )
270 {
271 NSBundle* currAppBundle = [NSBundle bundleWithPath: currFilename];
272
273 [listOfApplications addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
274 [NSNumber numberWithBool: YES], @"mustBeFrontmost",
275 currFilename, @"applicationPath",
276 [[NSFileManager defaultManager] displayNameAtPath: currFilename], @"applicationDisplayName",
277 [currAppBundle bundleIdentifier], @"bundleIdentifier",
278 nil]];
279 }
280 [applicationListView noteNumberOfRowsChanged];
281 }
282 }
283
284
285 -(NSString*) autosaveName
286 {
287 return [[autosaveName retain] autorelease];
288 }
289
290 -(void) setAutosaveName: (NSString*)anAutosaveName
291 {
292 if( autosaveName != anAutosaveName )
293 {
294 [autosaveName release];
295 autosaveName = [anAutosaveName copy];
296 }
297 }
298
299
300 @end
Something went wrong with that request. Please try again.