#include #include #include #include #include #import "InitCtrl.h" int runRootScript(const char* , char** , id); @implementation InitCtrl NSTask *rTask; NSFileHandle *rTaskOutput, *rTaskInput, *rTaskErr; NSMutableArray *history; int hptr; int textMode=0, respLine=0; BOOL startRfailed=NO; BOOL startedX=NO; int readTableCounter=1; NSTask *xServerTask=nil, *xWMTask=nil; NSColor *colorCode, *colorReply, *colorErr, *colorInstall; NSString *initRString=@"options(error=expression(NULL),echo=FALSE,width=1000,device=\"X11\");\n"; - (void)typedCommand: (NSString*) s { NSRange r; int l; s=[s stringByAppendingString:@"\n"]; l=[s cStringLength]; r.length=0; r.location=[[mainEdit string] length]; [mainEdit replaceCharactersInRange: r withString:[@"\n> " stringByAppendingString: s]]; r.length=l+2; [mainEdit setTextColor:colorCode range:r]; r.location+=r.length; r.length=0; [mainEdit setSelectedRange: r]; [mainEdit setEditable: YES]; [mainEdit insertText: @""]; [mainEdit setEditable: NO]; respLine=0; if ([s characterAtIndex:0]=='?' || [s hasPrefix:@"help("]) { NSLog(@"helpCtrl: %@",helpCtrl); NSLog(@"helpWin: %@",helpWin); [helpCtrl resetHelp]; [helpWin makeKeyAndOrderFront: self]; textMode=1; } else textMode=0; [rTaskInput writeData:[NSData dataWithBytes: [s cString] length: l]]; } - (IBAction)fileOpen:(id)sender { int result; NSArray *fileTypes = [NSArray arrayWithObject:@"R"]; NSOpenPanel *oPanel = [NSOpenPanel openPanel]; [oPanel setAllowsMultipleSelection:YES]; result = [oPanel runModalForDirectory:NSHomeDirectory() file:nil types:fileTypes]; if (result == NSOKButton) { NSArray *filesToOpen = [oPanel filenames]; int i, count = [filesToOpen count]; for (i=0; i0) hptr--; if (hptr>=0) [editLine setStringValue:[history objectAtIndex:hptr]]; } - (void) moveDown:(NSEvent *)theEvent { if (hptr==-1) hptr=[history count]-1; hptr++; if (hptr<[history count]) [editLine setStringValue:[history objectAtIndex:hptr]]; else [editLine setStringValue:@""]; } - (BOOL) respondsToSelector: (SEL) aSelector { //NSLog(@"respondsToSelector: %@",NSStringFromSelector(aSelector)); return [super respondsToSelector:aSelector]; } - (BOOL) windowShouldClose: (id) sender { int res=NSRunAlertPanel(@"Closing R session",@"Do you want to save workspace image?", @"Save",@"Don't save",@"Cancel"); NSLog(@"alert returned %d",res); if (res==0) [self typedCommand: @"quit(\"no\")"]; if (res==1) [self typedCommand: @"quit(\"yes\")"]; return NO; } - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { int res=NSRunAlertPanel(@"Closing R session",@"Do you want to save workspace image?", @"Save",@"Don't save",@"Cancel"); NSLog(@"alert returned %d",res); if (res==0) [self typedCommand: @"quit(\"no\")"]; if (res==1) [self typedCommand: @"quit(\"yes\")"]; return NO; } - (void) awakeFromNib { chdir(getenv("HOME")); rTask=nil; colorCode=[NSColor blackColor]; colorReply=[NSColor blueColor]; colorErr=[NSColor redColor]; colorInstall=[NSColor darkGrayColor]; history=[[NSMutableArray alloc] init]; hptr=-1; [mainEdit setFieldEditor: TRUE]; [mainEdit setDelegate: self]; [mainEdit setRichText: TRUE]; [editLine setDelegate: self]; [mainEdit setFont:[NSFont fontWithName:@"Monaco" size:11.0]]; [NSThread detachNewThreadSelector:@selector(runR:) toTarget:self withObject:rTaskErr]; } - (void) errThread: (NSFileHandle *)rTaskErr { NSAutoreleasePool *pool; NSData *inData = nil; const char *c; int l; pool = [[NSAutoreleasePool alloc] init]; while ((inData = [rTaskErr availableData]) && [inData length]) { NSRange r; c = [inData bytes]; l = [inData length]; r.length=0; r.location=[[mainEdit string] length]; [mainEdit replaceCharactersInRange: r withString:[NSString stringWithCString:c length:l]]; r.length=l; [mainEdit setTextColor:colorErr range:r]; r.location+=l; r.length=0; [mainEdit setSelectedRange: r]; [mainEdit display]; [mainEdit setEditable: YES]; [mainEdit insertText: @""]; [mainEdit setEditable: NO]; hptr=-1; } [pool release]; } - (void)quitRGUI { NS_DURING { if (xServerTask!=nil) [xServerTask terminate]; if (xWMTask!=nil) [xWMTask terminate]; } NS_HANDLER ; NS_ENDHANDLER exit(0); } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { if (startRfailed) { NSRunAlertPanel(@"Cannot find R",@"R GUI was unable to start R. Please note that this version of R GUI requires R to be installed in\n/usr/local/lib/R\nas provided by the R MacOS X package.\n\nYou can download the correct package from\nhttp://stats.math.uni-augsburg.de/R-OSX",@"OK",nil,nil); [self quitRGUI]; } } - (void) runR: (id) dummy { NSAutoreleasePool *pool; NSMutableArray *args; NSPipe *pipeIn, *pipeOut, *pipeErr; NSData *inData = nil; const char *c; int l; pool = [[NSAutoreleasePool alloc] init]; [mainEdit setString: @"Loading R ...\n"]; args= [NSMutableArray array]; [args addObject:@"--no-save"]; [args addObject:@"--gui=X11"]; rTask = [[NSTask alloc] init]; pipeOut = [NSPipe pipe]; pipeIn = [NSPipe pipe]; pipeErr = [NSPipe pipe]; rTaskOutput = [pipeOut fileHandleForReading]; rTaskErr = [pipeErr fileHandleForReading]; rTaskInput = [pipeIn fileHandleForWriting]; [rTask setStandardOutput:pipeOut]; [rTask setStandardInput:pipeIn]; [rTask setStandardError:pipeErr]; [rTask setLaunchPath:@"/usr/local/lib/R/bin/R"]; [rTask setArguments:args]; setenv("DISPLAY",":0.0",1); NS_DURING xServerTask=[NSTask launchedTaskWithLaunchPath:@"/usr/X11R6/bin/Xquartz" arguments: [NSArray array]]; xWMTask=[NSTask launchedTaskWithLaunchPath:@"/usr/X11R6/bin/quartz-wm" arguments: [NSArray array]]; startedX=YES; NS_HANDLER startedX=NO; NS_ENDHANDLER //t=[NSklimtTask launchedklimtTaskWithLaunchPath:@"/usr/bin/java" arguments:args]; NS_DURING [rTask launch]; NS_HANDLER startRfailed=YES; return; NS_ENDHANDLER [NSThread detachNewThreadSelector:@selector(errThread:) toTarget:self withObject:rTaskErr]; [rTaskInput writeData:[NSData dataWithBytes: [initRString cString] length: l=[initRString cStringLength]]]; while ((inData = [rTaskOutput availableData]) && [inData length]) { NSRange r; c = [inData bytes]; l = [inData length]; if (textMode==1) [helpCtrl writeToHelpWindow: c length:l]; else { r.length=0; r.location=[[mainEdit string] length]; [mainEdit replaceCharactersInRange: r withString:[NSString stringWithCString:c length:l]]; r.length=l; [mainEdit setTextColor:colorReply range:r]; r.location+=l; r.length=0; [mainEdit setSelectedRange: r]; [mainEdit setEditable: YES]; [mainEdit insertText: @""]; [mainEdit setEditable: NO]; } } //[t waitUntilExit]; [self quitRGUI]; [pool release]; } - (void) installerOutput: (NSString*) str { NSRange r; r.length=0; r.location=[[mainEdit string] length]; [mainEdit replaceCharactersInRange: r withString:str]; r.length=[str length]; [mainEdit setTextColor:colorErr range:r]; r.location+=r.length; r.length=0; [mainEdit setSelectedRange: r]; [mainEdit setEditable: YES]; [mainEdit insertText: @""]; [mainEdit setEditable: NO]; } - (int)runRcmdInstall: (NSString*) file { NSAutoreleasePool *pool; NSMutableArray *args; NSPipe *pipeOut, *pipeErr; NSData *inData = nil; NSTask *rTask; NSFileHandle *rTaskOutput, *rTaskErr; const char *c; int l,ts; pool = [[NSAutoreleasePool alloc] init]; args= [NSMutableArray array]; [args addObject:@"CMD"]; [args addObject:@"INSTALL"]; [args addObject:file]; rTask = [[NSTask alloc] init]; pipeOut = [NSPipe pipe]; pipeErr = [NSPipe pipe]; rTaskOutput = [pipeOut fileHandleForReading]; rTaskErr = [pipeErr fileHandleForReading]; [rTask setStandardOutput:pipeOut]; [rTask setStandardError:pipeErr]; [rTask setLaunchPath:@"/usr/local/lib/R/bin/R"]; [rTask setArguments:args]; //t=[NSklimtTask launchedklimtTaskWithLaunchPath:@"/usr/bin/java" arguments:args]; [rTask launch]; [NSThread detachNewThreadSelector:@selector(errThread:) toTarget:self withObject:nil]; while ((inData = [rTaskOutput availableData]) && [inData length]) { NSRange r; c = [inData bytes]; l = [inData length]; r.length=0; r.location=[[mainEdit string] length]; [mainEdit replaceCharactersInRange: r withString:[NSString stringWithCString:c length:l]]; r.length=l; [mainEdit setTextColor:colorInstall range:r]; r.location+=l; r.length=0; [mainEdit setSelectedRange: r]; [mainEdit setEditable: YES]; [mainEdit insertText: @""]; [mainEdit setEditable: NO]; } [rTask waitUntilExit]; ts=[rTask terminationStatus]; [rTask release]; [pool release]; return ts; } - (void)installSourcePackageFromFile: (NSString*) fn { FILE *f; BOOL fixRights=NO; f=fopen("/usr/local/lib/R/library/Rgui.tmp","w"); if (!f) fixRights=YES; else { fclose(f); remove("/usr/local/lib/R/library/Rgui.tmp"); f=fopen("/usr/local/lib/R/doc/Rgui.tmp","w"); if (!f) fixRights=YES; else { fclose(f); remove("/usr/local/lib/R/doc/Rgui.tmp"); } } [progressText setStringValue: @"Installing source package. This may take a while, please be patient."]; [progressBar setUsesThreadedAnimation:YES]; [progressWin makeKeyAndOrderFront: self]; [progressBar startAnimation: self]; if (fixRights) { const char *args[2]; NSLog(@"Need to fix rights of library and doc"); f=fopen("/tmp/fixRights","w"); fputs("#!/bin/sh\nchgrp -R staff /usr/local/lib/R/library /usr/local/lib/R/doc\nchmod -R g+rw /usr/local/lib/R/library /usr/local/lib/R/doc\n",f); fclose(f); args[0]="/tmp/fixRights"; args[1]=0; runRootScript("/bin/sh",(char**)args,self); } [mainEdit setEditable: YES]; [mainEdit insertText: @"** Installing source package from file "]; [mainEdit insertText: fn]; [mainEdit insertText: @":\n"]; [mainEdit setEditable: NO]; [self runRcmdInstall: fn]; [progressBar stopAnimation: self]; [progressWin orderOut: self]; /* const char *args[6]; args[0]="/bin/sh"; args[1]="R"; args[2]="CMD"; args[3]="INSTALL"; args[4]=[fn cString]; args[5]=0; runRootScript("/usr/local/lib/R/bin/R",args+2,self); */ } /*================ Packages ACTIONS ======================*/ - (IBAction)installBinaryFromFile:(id)sender { } - (IBAction)installFromCRAN:(id)sender { } - (IBAction)installSourcesFromFile:(id)sender { int result; NSArray *fileTypes = [NSArray arrayWithObject:@"gz"]; NSOpenPanel *oPanel = [NSOpenPanel openPanel]; [oPanel setAllowsMultipleSelection:YES]; result = [oPanel runModalForDirectory:NSHomeDirectory() file:nil types:fileTypes]; if (result == NSOKButton) { NSArray *filesToOpen = [oPanel filenames]; int i, count = [filesToOpen count]; for (i=0; i