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

Last change on this file since 219 was 7, checked in by Nicholas Riley, 20 years ago

F-Script Anywhere 1.1.2a1

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];
178    [pool release];
179    [temp 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.