class library: Spawner - don't access PriorityQueue-array
[supercollider.git] / editors / scapp / CocoaFilePrimitives.M
blobfe1df55ae000c6e849a950cfc50cba77dcc6c851
1 /*
2 * FileDialogPrimitives.M
3 * SC3lang
5 * Created by cruxxial on Mon Nov 25 2002.
8 File utilties that depend on the Cocoa framework.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #import <Cocoa/Cocoa.h>
28 #import "PyrPrimitive.h"
29 #import "PyrObject.h"
30 #import "PyrKernel.h"
31 #import "VMGlobals.h"
32 #import "MyDocument.h"
33 #import "GC.h"
35 #import "SCDialog.h"
37 inline NSString* nsStringFromPyrSlot(PyrSlot *slot)
39 PyrString* pyrString = slotRawString(slot);
40 return [NSString stringWithCString: pyrString->s length: pyrString->size];
44 /** PRIMITIVES **/
45 int prGetPathsDialog(struct VMGlobals *g, int numArgsPushed);
46 int prGetPathsDialog(struct VMGlobals *g, int numArgsPushed)
48 if (!g->canCallOS) return errCantCallOS;
50 PyrSlot *receiver = g->sp - 1; // CocoaDialog class
51 PyrSlot *allowsMultiple = g->sp; // a bool
53 SCDialog *dialog = [SCDialog receiver: slotRawObject(receiver) result: nil ];
55 BOOL allows = IsTrue(allowsMultiple);
56 SEL selector = @selector(getPaths:);
57 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
58 [dialog methodSignatureForSelector: selector]];
59 [invocation setTarget:dialog];
60 [invocation setSelector: selector];
61 [invocation setArgument:&allows atIndex:2];
62 [invocation retainArguments];
64 [[SCVirtualMachine sharedInstance] defer: invocation];
66 return errNone;
69 int prSavePanel(struct VMGlobals *g, int numArgsPushed);
70 int prSavePanel(struct VMGlobals *g, int numArgsPushed)
72 if (!g->canCallOS) return errCantCallOS;
74 PyrSlot *receiver = g->sp - 1; // CocoaDialog class
75 PyrSlot *string = g->sp; // a string
77 SCDialog *dialog = [SCDialog receiver: slotRawObject(receiver) result: slotRawObject(string) ];
79 [dialog scvmDeferWithSelector:@selector(savePanel) ];
81 return errNone;
84 // NOTE: unused
85 int prStandardizePath(struct VMGlobals *g, int numArgsPushed);
86 int prStandardizePath(struct VMGlobals *g, int numArgsPushed)
88 if (!g->canCallOS) return errCantCallOS;
90 PyrSlot *string = g->sp;
91 PyrString *pyrString;
92 NSString *path = nsStringFromPyrSlot(string);
93 if([path length] != 0) {
94 path = [path stringByStandardizingPath];
95 pyrString = newPyrString(g->gc, [path fileSystemRepresentation], 0, true);
96 } else {
97 pyrString = newPyrString(g->gc, [path cString],0,true);
99 SetObject(string, pyrString);
100 return errNone;
103 int prGetPathsInDirectory(struct VMGlobals *g, int numArgsPushed);
104 int prGetPathsInDirectory(struct VMGlobals *g, int numArgsPushed)
106 if (!g->canCallOS) return errCantCallOS;
108 PyrSlot *receiver = g->sp - 3;
109 PyrSlot *directoryPath = g->sp - 2;
110 PyrSlot *extension = g->sp - 1;
111 PyrSlot *returnArray = g->sp;
113 if(IsNil(directoryPath)) return errWrongType;
115 PyrObject *returnObject = slotRawObject(returnArray);
117 NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager]
118 enumeratorAtPath:nsStringFromPyrSlot(directoryPath)];
119 NSString *pname;
120 int i=0;
121 int maxsize = MAXINDEXSIZE(returnObject);
122 if(IsNil(extension)) {
123 while (pname = [direnum nextObject]) {
124 if(i >= maxsize) return errIndexOutOfRange;
126 PyrString* pyrPathString = newPyrString(g->gc,[pname fileSystemRepresentation],0,true);
128 PyrSlot slot;
129 SetObject(&slot, pyrPathString);
130 slotCopy(&returnObject->slots[i], &slot);
131 g->gc->GCWrite(returnObject,pyrPathString);
132 returnObject->size = i+1;
133 i++;
135 } else {
137 NSString *nsextension;
138 nsextension = nsStringFromPyrSlot(extension);
139 while (pname = [direnum nextObject]) {
140 if (![[pname pathExtension] isEqualToString:nsextension]) {
141 //[direnum skipDescendents]; don't enumerate this directory
142 //} else {
143 PyrString* pyrPathString = newPyrString(g->gc,[pname fileSystemRepresentation],0,true);
145 PyrSlot slot;
146 SetObject(&slot, pyrPathString);
148 slotCopy(&returnObject->slots[i], &slot);
150 g->gc->GCWrite(returnObject,pyrPathString);
151 returnObject->size = i+1;
152 i++;
157 SetObject(receiver,returnObject);
158 return errNone;
162 NSDictionary *fattrs = [manager fileAttributesAtPath:fullpath traverseLink:YES];
163 //NSString *fileName = [pname lastPathComponent];
165 if ([fattrs objectForKey:NSFileType] != NSFileTypeDirectory)
170 int prHelpFileForString(struct VMGlobals *g, int numArgsPushed);
171 int prHelpFileForString(struct VMGlobals *g, int numArgsPushed)
173 if (!g->canCallOS) return errCantCallOS;
175 PyrSlot *a = g->sp;
176 PyrSlot *receiver = g->sp - 1;
178 // this function should be moved out of the MyDocument instance
179 NSString *path = pathOfHelpFileFor( nsStringFromPyrSlot(a));
181 if(path) {
182 PyrString* pyrPathString = newPyrString(g->gc,[path fileSystemRepresentation],0,true);
183 SetObject(receiver,pyrPathString);
184 } else {
185 SetNil(receiver);
187 return errNone;
191 these are a still experimental cocoa <-> sc bridge
192 an sc class: NSObjectHolder holds cocoa objects and lets you send and receive
193 messages.
195 prAllocInit { arg classname, initname,args;
196 _ObjC_allocinit;
197 ^this.primitiveFailed;
199 prDealloc {
200 _ObjC_dealloc;
204 int prAllocInit(struct VMGlobals *g, int numArgsPushed);
205 int prAllocInit(struct VMGlobals *g, int numArgsPushed)
207 PyrSlot *receiver = g->sp - 3;
208 PyrSlot *classname = g->sp - 2;
209 // PyrSlot *initname = g->sp - 1;
210 //PyrSlot *args = g->sp;
212 // have to put them in a specific pool so they can be released on command
214 // must defer in case of large loads and gui
215 id newThing = [[NSClassFromString( nsStringFromPyrSlot(classname) ) class] alloc];
216 [newThing init];
217 if(newThing) {
218 [newThing retain];
219 } else {
220 return errFailed;
222 //receiver set dataptr
223 SetInt( receiver, (int)newThing );
224 return errNone;
227 int prObjDo(struct VMGlobals *g, int numArgsPushed);
228 int prObjDo(struct VMGlobals *g, int numArgsPushed)
230 PyrSlot *receiver = g->sp - 3;
231 PyrSlot *dataptr = g->sp - 2;
232 PyrSlot *methodname = g->sp - 1;
233 PyrSlot *args = g->sp;
235 dumpObjectSlot(receiver);
236 dumpObjectSlot(dataptr);
237 dumpObjectSlot(methodname);
238 dumpObjectSlot(args);
240 // have to put them in a specific pool so they can be released on command
241 if(! IsInt(dataptr) ) return errWrongType;
243 // check retain count and return in case
244 SEL selector = NSSelectorFromString(nsStringFromPyrSlot(methodname));
245 //err if not found
247 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
248 [(id)slotRawInt(dataptr) methodSignatureForSelector: selector]];
249 [invocation setTarget:(id)slotRawInt(dataptr)];
250 [invocation setSelector: selector];
251 // check number of args is right
253 if (!isSubclassOf( slotRawObject(args)->classptr, class_sequenceable_collection ))
254 return errWrongType;
256 int i;
257 for(i = 0; i < slotRawObject(args)->size; i++) {
258 [invocation setArgument: nsCodableFromPyrSlot(&(slotRawObject(args)->slots[i])) atIndex: i + 2];
259 //setInvocationArgFromPyrSlot(invocation,i + 2,&(slotRawObject(args)->slots[i]));
261 [invocation retainArguments];
262 NSLog(@"invocation: %@",invocation);
263 [[SCVirtualMachine sharedInstance] defer: invocation];
265 return errNone;
268 int prDealloc(struct VMGlobals *g, int numArgsPushed);
269 int prDealloc(struct VMGlobals *g, int numArgsPushed)
271 //PyrSlot *receiver = g->sp - 1;
272 PyrSlot *dataptr = g->sp;
274 // have to put them in a specific pool so they can be released on command
275 if(! IsInt(dataptr) ) return errWrongType;
277 // check retain count and return in case
278 [(id)slotRawInt(dataptr) release];
279 return errNone;
283 void initCocoaFilePrimitives()
285 int base, index;
287 base = nextPrimitiveIndex();
288 index = 0;
290 definePrimitive(base, index++, "_Cocoa_GetPathsDialog", prGetPathsDialog, 2, 0);
291 definePrimitive(base, index++, "_Cocoa_SavePanel", prSavePanel, 2, 0);
292 //definePrimitive(base, index++, "_Cocoa_SaveAsPlist", prSaveAsPlist, 2, 0);
293 // definePrimitive(base, index++, "_Cocoa_StandardizePath", prStandardizePath, 1, 0);
294 definePrimitive(base, index++, "_Cocoa_GetPathsInDirectory", prGetPathsInDirectory, 4, 0);
295 definePrimitive(base, index++, "_Cocoa_HelpFileForString_", prHelpFileForString, 2, 0);
297 /* definePrimitive(base, index++, "_ObjC_AllocInit", prAllocInit, 4, 0);
298 definePrimitive(base, index++, "_ObjC_Dealloc", prDealloc, 2, 0);
299 definePrimitive(base, index++, "_ObjC_objectDo", prObjDo, 4, 0); */