source: trunk/Cocoa/F-Script Anywhere/Source/DeVercruesseProcessManager.m

Last change on this file was 406, checked in by Nicholas Riley, 17 years ago

Source files are not executable.

File size: 7.6 KB
Line 
1//
2// DeVercruesseProcessManager.m
3//
4// Created by Frank Vercruesse on Wed Apr 04 2001.
5// Copyright (c) 2001 Frank Vercruesse.
6//
7//
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the GNU General Public License
10// as published by the Free Software Foundation; either version 2
11// of the License, or (at your option) any later version.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21// 02111-1307, USA.
22
23#import "DeVercruesseProcessManager.h"
24
25
26@implementation DeVercruesseProcessManager
27
28static DeVercruesseProcessManager *defaultManager = nil;
29
30+ (id)defaultManager
31{
32 return ( defaultManager ? defaultManager : [[self alloc] init] );
33}
34
35- (id)init
36{
37 if( defaultManager )
38 {
39 [self dealloc];
40 }
41 else if( [super init] )
42 {
43 processes = [[NSMutableSet alloc] initWithCapacity:30];
44 defaultManager = self;
45 }
46
47 return defaultManager;
48}
49
50- (void)dealloc
51{
52 [processes release];
53
54 if( self == defaultManager )
55 defaultManager = nil;
56 [super dealloc];
57}
58
59
60- (DeVercruesseProcess*)currentProcess
61{
62 ProcessSerialNumber sn;
63 DeVercruesseProcess *p, *q;
64
65
66 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
67
68 if( p = [DeVercruesseProcess processWithPSN:&sn] )
69 {
70 if( q = [processes member:p] )
71 p = q;
72// else
73// [processes addObject:p];
74 }
75
76 return p;
77}
78
79- (DeVercruesseProcess*)frontProcess
80{
81 ProcessSerialNumber sn;
82 DeVercruesseProcess *p, *q;
83
84
85 if( CPSGetFrontProcess( (CPSProcessSerNum*) &sn) != noErr )
86 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
87
88 if( p = [DeVercruesseProcess processWithPSN:&sn] )
89 {
90 if( q = [processes member:p] )
91 p = q;
92// else
93// [processes addObject:p];
94 }
95
96 return p;
97}
98
99- (DeVercruesseProcess*)nextToFrontProcess
100{
101 ProcessSerialNumber sn;
102 DeVercruesseProcess *p, *q;
103
104
105 if( CPSGetNextToFrontProcess( (CPSProcessSerNum*) &sn) != noErr )
106 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
107
108 if( p = [DeVercruesseProcess processWithPSN:&sn] )
109 {
110 if( q = [processes member:p] )
111 p = q;
112// else
113// [processes addObject:p];
114 }
115
116 return p;
117}
118
119- (DeVercruesseProcess*)anyNoBGOnlyProcess
120{
121 ProcessSerialNumber sn;
122 DeVercruesseProcess *p, *q;
123
124
125 sn.highLongOfPSN = 0;
126 sn.lowLongOfPSN = kNoProcess;
127
128 while( CPSGetNextProcess( (CPSProcessSerNum*) &sn) == noErr )
129 {
130 if( (p = [DeVercruesseProcess processWithPSN:&sn]) && ![p isBackgroundOnly] )
131 {
132 if( q = [processes member:p] )
133 p = q;
134// else
135// [processes addObject:p];
136
137 return p;
138 }
139 }
140
141 return nil;
142}
143
144
145- (NSArray*)processes
146{
147 [self update];
148
149 return [NSArray arrayWithArray:[processes allObjects]];
150}
151
152
153- (void)update
154{
155 ProcessSerialNumber sn;
156 NSMutableSet *temp;
157 DeVercruesseProcess *process, *existingProcess;
158 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
159
160 sn.highLongOfPSN = 0;
161 sn.lowLongOfPSN = kNoProcess;
162
163 temp = [[NSMutableSet alloc] initWithCapacity: 30];
164
165 while( CPSGetNextProcess( (CPSProcessSerNum*) &sn) == noErr )
166 {
167 // njr removed background-only check because we still get process launch notifications for background-only apps...
168 if ( (process = [[DeVercruesseProcess alloc] initWithPSN:&sn]) != nil) {
169 if ( (existingProcess = [processes member: process]) != nil ) {
170 [temp addObject: existingProcess];
171 } else {
172 [temp addObject: process];
173 }
174 [process release];
175 }
176 }
177
178 [processes setSet:[temp autorelease]];
179 [pool release];
180}
181
182
183- (void)showAll
184{
185 ProcessSerialNumber *psn;
186
187
188 psn = [[self frontProcess] psn];
189
190 CPSPostShowAllReq( (CPSProcessSerNum*) psn );
191 CPSPostShowReq( (CPSProcessSerNum*) psn );
192}
193
194- (void)hideOthers
195{
196 [self hideOthers:YES];
197}
198
199- (void)hideOthers:(BOOL)ignoreRules
200{
201 NSArray *p;
202 NSEnumerator *enumerator;
203 DeVercruesseProcess *process;
204
205
206 p = [[ProcessMgr processes] retain];
207
208 enumerator = [p objectEnumerator];
209
210 while( process = [enumerator nextObject] )
211 {
212 if( ![process isHidden] && ![process isEqualToFront] &&
213 (ignoreRules ||
214 ![self checkRule:@"optDontHide" withProcess:process]) )
215 {
216 [process hide];
217 }
218 }
219
220 [p release];
221}
222
223- (void)hideFront
224{
225 [[self frontProcess] hide];
226}
227
228- (void)setFront:(DeVercruesseProcess*)process
229{
230 [process makeFront];
231}
232
233// rules stuff
234
235- (void)setRules:(NSArray*)r
236{
237 NSEnumerator *enumerator;
238 NSDictionary *dict;
239 NSMutableSet *hasRules, *keys;
240 NSMutableDictionary *newRules;
241
242
243 newRules = [[NSMutableDictionary alloc] initWithCapacity:10];
244
245 hasRules = [[NSMutableSet alloc] initWithCapacity:10];
246 [newRules setObject:hasRules forKey:@"_hasRules"];
247 [hasRules release];
248
249 keys = [[NSMutableSet alloc] initWithCapacity:10];
250 [newRules setObject:keys forKey:@"_keys"];
251 [keys release];
252
253 enumerator = [r objectEnumerator];
254 while( dict = [enumerator nextObject] )
255 {
256 NSString *identifier, *key;
257 NSEnumerator *keyEnumerator;
258 NSDictionary *d2;
259
260 identifier = [[NSString alloc] initWithFormat:@"%@%.8X%.8X", [dict objectForKey:@"identifier"], [[dict objectForKey:@"type"] unsignedIntValue], [[dict objectForKey:@"creator"] unsignedIntValue]];
261 [hasRules addObject:identifier];
262 [identifier release];
263
264 d2 = [dict objectForKey:@"rules"];
265 keyEnumerator = [d2 keyEnumerator];
266 while( key = [keyEnumerator nextObject] )
267 {
268 NSMutableDictionary *d3;
269
270 if( !(d3 = [newRules objectForKey:key]) )
271 {
272 [keys addObject:key];
273
274 d3 = [[NSMutableDictionary alloc] initWithCapacity:10];
275 [newRules setObject:d3 forKey:key];
276 [d3 release];
277 }
278
279 [d3 setObject:[d2 objectForKey:key] forKey:identifier];
280 }
281 }
282
283 [rules release];
284 rules = [[NSDictionary alloc] initWithDictionary:newRules];
285
286 [newRules release];
287}
288
289- (BOOL)anyRulesForProcess:(DeVercruesseProcess*)process
290{
291 if( !process || !rules )
292 return NO;
293
294 return [[rules objectForKey:@"_hasRules"] containsObject:[process identifier]];
295}
296
297- (BOOL)checkRule:(NSString*)ruleKey withProcess:(DeVercruesseProcess*)process
298{
299 if( !ruleKey || !process || !rules )
300 return NO;
301
302 return [[rules objectForKey:ruleKey] containsObject:[process identifier]];
303}
304
305- (NSSet*)processIdentifiersForRule:(NSString*)ruleKey
306{
307 return [rules objectForKey:ruleKey];
308}
309
310- (int)optionsForRule:(NSString*)ruleKey withProcess:(DeVercruesseProcess*)process
311{
312 NSDictionary *rule;
313 NSNumber *options;
314
315
316 if( !(rule = [rules objectForKey:ruleKey]) )
317 return 2; // use global setting
318
319 if( !(options = [rule objectForKey:[process identifier]]) )
320 return 2; // use global setting
321
322 return [options intValue];
323}
324
325@end
Note: See TracBrowser for help on using the repository browser.