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

Last change on this file since 326 was 230, checked in by rchin, 18 years ago

Auto installation of F-Script as requested by Philippe Mougin. We'll optimize the FSA framework package later (not sure if it would be a good idea to remove headers in framework, etc.)

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}
57
58
59- (DeVercruesseProcess*)currentProcess
60{
61 ProcessSerialNumber sn;
62 DeVercruesseProcess *p, *q;
63
64
65 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
66
67 if( p = [DeVercruesseProcess processWithPSN:&sn] )
68 {
69 if( q = [processes member:p] )
70 p = q;
71// else
72// [processes addObject:p];
73 }
74
75 return p;
76}
77
78- (DeVercruesseProcess*)frontProcess
79{
80 ProcessSerialNumber sn;
81 DeVercruesseProcess *p, *q;
82
83
84 if( CPSGetFrontProcess( (CPSProcessSerNum*) &sn) != noErr )
85 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
86
87 if( p = [DeVercruesseProcess processWithPSN:&sn] )
88 {
89 if( q = [processes member:p] )
90 p = q;
91// else
92// [processes addObject:p];
93 }
94
95 return p;
96}
97
98- (DeVercruesseProcess*)nextToFrontProcess
99{
100 ProcessSerialNumber sn;
101 DeVercruesseProcess *p, *q;
102
103
104 if( CPSGetNextToFrontProcess( (CPSProcessSerNum*) &sn) != noErr )
105 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
106
107 if( p = [DeVercruesseProcess processWithPSN:&sn] )
108 {
109 if( q = [processes member:p] )
110 p = q;
111// else
112// [processes addObject:p];
113 }
114
115 return p;
116}
117
118- (DeVercruesseProcess*)anyNoBGOnlyProcess
119{
120 ProcessSerialNumber sn;
121 DeVercruesseProcess *p, *q;
122
123
124 sn.highLongOfPSN = 0;
125 sn.lowLongOfPSN = kNoProcess;
126
127 while( CPSGetNextProcess( (CPSProcessSerNum*) &sn) == noErr )
128 {
129 if( (p = [DeVercruesseProcess processWithPSN:&sn]) && ![p isBackgroundOnly] )
130 {
131 if( q = [processes member:p] )
132 p = q;
133// else
134// [processes addObject:p];
135
136 return p;
137 }
138 }
139
140 return nil;
141}
142
143
144- (NSArray*)processes
145{
146 [self update];
147
148 return [NSArray arrayWithArray:[processes allObjects]];
149}
150
151
152- (void)update
153{
154 ProcessSerialNumber sn;
155 NSMutableSet *temp;
156 DeVercruesseProcess *process, *existingProcess;
157 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
158
159 sn.highLongOfPSN = 0;
160 sn.lowLongOfPSN = kNoProcess;
161
162 temp = [[NSMutableSet alloc] initWithCapacity: 30];
163
164 while( CPSGetNextProcess( (CPSProcessSerNum*) &sn) == noErr )
165 {
166 // njr removed background-only check because we still get process launch notifications for background-only apps...
167 if ( (process = [[DeVercruesseProcess alloc] initWithPSN:&sn]) != nil) {
168 if ( (existingProcess = [processes member: process]) != nil ) {
169 [temp addObject: existingProcess];
170 } else {
171 [temp addObject: process];
172 }
173 [process release];
174 }
175 }
176
177 [processes setSet:[temp autorelease]];
178 [pool release];
179}
180
181
182- (void)showAll
183{
184 ProcessSerialNumber *psn;
185
186
187 psn = [[self frontProcess] psn];
188
189 CPSPostShowAllReq( (CPSProcessSerNum*) psn );
190 CPSPostShowReq( (CPSProcessSerNum*) psn );
191}
192
193- (void)hideOthers
194{
195 [self hideOthers:YES];
196}
197
198- (void)hideOthers:(BOOL)ignoreRules
199{
200 NSArray *p;
201 NSEnumerator *enumerator;
202 DeVercruesseProcess *process;
203
204
205 p = [[ProcessMgr processes] retain];
206
207 enumerator = [p objectEnumerator];
208
209 while( process = [enumerator nextObject] )
210 {
211 if( ![process isHidden] && ![process isEqualToFront] &&
212 (ignoreRules ||
213 ![self checkRule:@"optDontHide" withProcess:process]) )
214 {
215 [process hide];
216 }
217 }
218
219 [p release];
220}
221
222- (void)hideFront
223{
224 [[self frontProcess] hide];
225}
226
227- (void)setFront:(DeVercruesseProcess*)process
228{
229 [process makeFront];
230}
231
232// rules stuff
233
234- (void)setRules:(NSArray*)r
235{
236 NSEnumerator *enumerator;
237 NSDictionary *dict;
238 NSMutableSet *hasRules, *keys;
239 NSMutableDictionary *newRules;
240
241
242 newRules = [[NSMutableDictionary alloc] initWithCapacity:10];
243
244 hasRules = [[NSMutableSet alloc] initWithCapacity:10];
245 [newRules setObject:hasRules forKey:@"_hasRules"];
246 [hasRules release];
247
248 keys = [[NSMutableSet alloc] initWithCapacity:10];
249 [newRules setObject:keys forKey:@"_keys"];
250 [keys release];
251
252 enumerator = [r objectEnumerator];
253 while( dict = [enumerator nextObject] )
254 {
255 NSString *identifier, *key;
256 NSEnumerator *keyEnumerator;
257 NSDictionary *d2;
258
259 identifier = [[NSString alloc] initWithFormat:@"%@%.8X%.8X", [dict objectForKey:@"identifier"], [[dict objectForKey:@"type"] unsignedIntValue], [[dict objectForKey:@"creator"] unsignedIntValue]];
260 [hasRules addObject:identifier];
261 [identifier release];
262
263 d2 = [dict objectForKey:@"rules"];
264 keyEnumerator = [d2 keyEnumerator];
265 while( key = [keyEnumerator nextObject] )
266 {
267 NSMutableDictionary *d3;
268
269 if( !(d3 = [newRules objectForKey:key]) )
270 {
271 [keys addObject:key];
272
273 d3 = [[NSMutableDictionary alloc] initWithCapacity:10];
274 [newRules setObject:d3 forKey:key];
275 [d3 release];
276 }
277
278 [d3 setObject:[d2 objectForKey:key] forKey:identifier];
279 }
280 }
281
282 [rules release];
283 rules = [[NSDictionary alloc] initWithDictionary:newRules];
284
285 [newRules release];
286}
287
288- (BOOL)anyRulesForProcess:(DeVercruesseProcess*)process
289{
290 if( !process || !rules )
291 return NO;
292
293 return [[rules objectForKey:@"_hasRules"] containsObject:[process identifier]];
294}
295
296- (BOOL)checkRule:(NSString*)ruleKey withProcess:(DeVercruesseProcess*)process
297{
298 if( !ruleKey || !process || !rules )
299 return NO;
300
301 return [[rules objectForKey:ruleKey] containsObject:[process identifier]];
302}
303
304- (NSSet*)processIdentifiersForRule:(NSString*)ruleKey
305{
306 return [rules objectForKey:ruleKey];
307}
308
309- (int)optionsForRule:(NSString*)ruleKey withProcess:(DeVercruesseProcess*)process
310{
311 NSDictionary *rule;
312 NSNumber *options;
313
314
315 if( !(rule = [rules objectForKey:ruleKey]) )
316 return 2; // use global setting
317
318 if( !(options = [rule objectForKey:[process identifier]]) )
319 return 2; // use global setting
320
321 return [options intValue];
322}
323
324@end
Note: See TracBrowser for help on using the repository browser.