2 * FileDialogPrimitives.M
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"
32 #import "MyDocument.h"
37 inline NSString
* nsStringFromPyrSlot(PyrSlot
*slot
)
39 PyrString
* pyrString
= slotRawString(slot
);
40 return [NSString stringWithUTF8String
: pyrString
->s
];
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
];
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
) ];
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
;
92 NSString
*path
= nsStringFromPyrSlot(string
);
93 if([path length
] != 0) {
94 path
= [path stringByStandardizingPath
];
95 pyrString
= newPyrString(g
->gc
, [path fileSystemRepresentation
], 0, true);
97 pyrString
= newPyrString(g
->gc
, [path cStringUsingEncoding
:[NSString defaultCStringEncoding
]],0,true);
99 SetObject(string
, pyrString
);
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
)];
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);
129 SetObject(&slot
, pyrPathString
);
130 slotCopy(&returnObject
->slots
[i
], &slot
);
131 g
->gc
->GCWrite(returnObject
,pyrPathString
);
132 returnObject
->size
= i
+1;
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
143 PyrString* pyrPathString = newPyrString(g->gc,[pname fileSystemRepresentation],0,true);
146 SetObject(&slot, pyrPathString);
148 slotCopy(&returnObject->slots[i], &slot);
150 g->gc->GCWrite(returnObject,pyrPathString);
151 returnObject->size = i+1;
157 SetObject(receiver
,returnObject
);
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
;
176 PyrSlot
*receiver
= g
->sp
- 1;
178 // this function should be moved out of the MyDocument instance
179 NSString
*path
= pathOfHelpFileFor( nsStringFromPyrSlot(a
));
182 PyrString
* pyrPathString
= newPyrString(g
->gc
,[path fileSystemRepresentation
],0,true);
183 SetObject(receiver
,pyrPathString
);
191 these are a still experimental cocoa <-> sc bridge
192 an sc class: NSObjectHolder holds cocoa objects and lets you send and receive
195 prAllocInit { arg classname, initname,args;
197 ^this.primitiveFailed;
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];
222 //receiver set dataptr
223 SetInt( receiver, (int)newThing );
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));
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 ))
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];
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];
283 void initCocoaFilePrimitives()
287 base
= nextPrimitiveIndex();
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); */