Annotation of OpenXM/src/cfep/MyDocument.m, Revision 1.1.1.1
1.1 takayama 1: //
2: // MyDocument.m
3: // cfep
4: //
5: // Created by Nobuki Takayama
6: // Copyright (c) 2006 OpenXM.org
7: //
8:
9: // [self setDefaultPeer BASH] or [self setDefaultPeer OX_TEXMACS]
10:
11: #include <signal.h>
12: #import "MyDocument.h"
13: #import "MyOutputWindowController.h"
14: #import "MyOpenGLController.h"
15:
16: int myDebug=0;
17: static int myDocumentSaidTheMessageAboutX = 0;
18:
19:
20: @implementation MyDocument
21:
22: - (void)dealloc {
23: MyOutputWindowController *mowc;
24: if (myDebug) NSLog(@"dealloc of MyDocument.\n");
25: if (myDebug) NSLog(@"retainCount of task=%d\n",[task retainCount]); // why is it 2?
26: [self closeMyModel];
27: // [task dealloc]; //BUG. if we do this, error happens.
28: mowc = [MyOutputWindowController sharedMyOutputWindowController: self];
29: if (mowc != nil) [mowc closeMyOutputWindow: self];
30: if (errorLines) { [errorLines autorelease]; errorLines = nil; }
31:
32: [myDecoder dealloc];
33:
34: [dataFromFile release];
35: [rtfDataFromFile release];
36: [textDataFromFile release];
37: if (myDebug) NSLog(@"Done: dealloc of MyDocument.\n");
38: [super dealloc];
39: }
40:
41: // The name of the nib file to load for this document.
42: - (NSString *)windowNibName
43: {
44: return @"MyDocument";
45: }
46:
47: // Loads up the data when the nib file is loaded.
48: - (void)windowControllerDidLoadNib:(NSWindowController *)aController {
49: [super windowControllerDidLoadNib:aController];
50:
51: if (dataFromFile) {
52: [self loadtextViewWithData:dataFromFile];
53: [dataFromFile release];
54: dataFromFile = nil;
55: } else if (rtfDataFromFile) {
56: [self loadtextViewWithRTFData: rtfDataFromFile];
57: [rtfDataFromFile release];
58: rtfDataFromFile = nil;
59: } else if (textDataFromFile) {
60: [self loadtextViewWithTextData: textDataFromFile];
61: [textDataFromFile release];
62: textDataFromFile = nil;
63: }
64: [self addMenuExec]; // adding the execution menu.
65: [textViewIn setAllowsUndo:YES];
66: [self sayTheMessageAboutX];
67: [self initAux];
68: }
69:
70: // Load the view with data given an NSData.
71: - (void)loadtextViewWithData:(NSData *)data {
72: [textViewIn replaceCharactersInRange:NSMakeRange(0, [[textViewIn string] length]) withRTFD:data];
73: }
74: - (void)loadtextViewWithRTFData:(NSData *)data {
75: [textViewIn replaceCharactersInRange:NSMakeRange(0, [[textViewIn string] length]) withRTF:data];
76: }
77: -(void) loadtextViewWithTextData:(NSData *)data {
78: [textViewIn replaceCharactersInRange: NSMakeRange(0,[[textViewIn string] length])
79: withString:[NSString stringWithCString: [data bytes] encoding:NSUTF8StringEncoding]];
80: }
81:
82: // Return an NSData representation of our document's view.
83: - (NSData *)dataRepresentationOfType:(NSString *)aType {
84: if ([@"RTFWithGraphics" compare: aType] == NSOrderedSame) {
85: return [textViewIn RTFDFromRange:NSMakeRange(0, [[textViewIn string] length])];
86: }else if ([@"RTF" compare: aType] == NSOrderedSame) {
87: return [textViewIn RTFFromRange:NSMakeRange(0, [[textViewIn string] length])];
88: }else {
89: return [[textViewIn string] dataUsingEncoding: NSUTF8StringEncoding];
90: }
91: }
92:
93: // If we're loading from a file just retain the data and it will be
94: // loaded when windowControllerDidLoadNib is invoked. If not, go
95: // ahead and load the view with the data.
96: // These paths are separate in order to support Revert where the
97: // data is reloaded but the nib is not.
98: - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType {
99: if ([@"RTFWithGraphics" compare: aType] == NSOrderedSame) {
100: if (textViewIn)
101: [self loadtextViewWithData:data];
102: else
103: dataFromFile = [data retain];
104: }else if ([@"RTF" compare: aType] == NSOrderedSame) {
105: if (textViewIn)
106: [self loadtextViewWithRTFData:data];
107: else
108: rtfDataFromFile = [data retain];
109: }else{
110: if (textViewIn)
111: [self loadtextViewWithTextData: data];
112: else
113: textDataFromFile = [data retain];
114: }
115:
116: return YES;
117: }
118:
119: // =======================================================================
120:
121: -(void) initAux {
122: static int serial;
123: MyEnvironment *myEnvironment;
124: myDocumentKey = [@"myDocumentNo" stringByAppendingString: [NSString stringWithFormat: @"%d",(++serial)]];
125: [myDocumentKey retain];
126:
127: onlySelectedArea = 0;
128: notebookMode = 0; // or = 1; // experimental.
129: oxEngine = 0; // experimental. For select engine menu.
130: errorLines = [NSMutableArray arrayWithCapacity: 10]; [errorLines retain];
131: debugMyTunnel = 0;
132: task = nil;
133: myEnvironment = [[MyEnvironment alloc] init]; [myEnvironment retain];
134:
135: myDefaultTypingAttributes = [myEnvironment getMyDefaultTypingAttributes];
136: [myDefaultTypingAttributes retain];
137: [textViewIn setTypingAttributes: myDefaultTypingAttributes];
138:
139: myDecoder = [[MyDecoder alloc] init]; [myDecoder retain];
140:
141: [self openMyModel: myEnvironment ];
142: }
143: -(int) getMyDocumentKey { return myDocumentKey; }
144:
145: -(id) openMyModel: (MyEnvironment *) myEnvironment {
146: [myEnvironment showForDebug]; // for debug.
147: OpenXM_HOME= [myEnvironment getOpenXM_HOME];
148: [OpenXM_HOME retain]; // without these SIGSEGV
149: inputCounter = outputCounter = 0;
150: redirectPrint = 0;
151: peer = [myEnvironment getPeer];
152: peerStartupString = [myEnvironment getPeerStartupString];
153: [peerStartupString retain];
154: peerEndEvaluteMark = [myEnvironment getPeerEndEvaluateMark];
155: [peerEndEvaluteMark retain];
156:
157: [self stopIndicator];
158: // Initialization to call /bin/bash
159: outboundPipe = [NSPipe pipe]; // since autorelease is called in pipe.
160: inboundPipe = [NSPipe pipe];
161: errPipe = [NSPipe pipe];
162: [outboundPipe retain]; [inboundPipe retain]; [errPipe retain];
163: outboundFileHandle = [outboundPipe fileHandleForWriting];
164: inboundFileHandle = [inboundPipe fileHandleForReading];
165: errFileHandle = [errPipe fileHandleForReading];
166:
167: NSLog(@"Starting /bin/bash\n");
168: task = [[NSTask alloc] init];
169: [task setStandardInput: outboundPipe];
170: [task setStandardOutput: inboundPipe];
171: [task setStandardError: errPipe];
172: [task setEnvironment: [myEnvironment getMyUnixEnvironment]];
173: //[task setArguments: [NSArray arrayWithObject: @"http://www.google.com"]];
174: //[task setLaunchPath: @"/usr/bin/open"];
175: //[task setLaunchPath: @"/Users/NobukiTakayama/OX4/OpenXM/bin/asir"];
176: //[task setLaunchPath: @"/bin/date"];
177: [task setLaunchPath: @"/bin/bash"];
178: // launch will be done after nib is loaded.
179: @try { // version >= 10.3, add option in info
180: [task launch];
181: } @catch (NSException *exception) {
182: NSLog(@"init task launch Caught %@: %@", [exception name], [exception reason]);
183: } @finally {
184: NSLog(@"/bin/bash is started.\n");
185: // fprintf(stderr,"pid = %d\n",[task processIdentifier]);
186: signal(SIGPIPE,SIG_IGN); //BUG. non-cocoa way.
187: [self oxEvaluateString: peerStartupString withMark: FALSE];
188: }
189:
190: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readInboundData:)
191: name:NSFileHandleDataAvailableNotification object: inboundFileHandle];
192: [inboundFileHandle waitForDataInBackgroundAndNotify];
193: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readErrData:)
194: name:NSFileHandleDataAvailableNotification object: errFileHandle];
195: [errFileHandle waitForDataInBackgroundAndNotify];
196:
197: return self;
198: }
199:
200: - (void) closeMyModel {
201: [self stopIndicator];
202: if (task == nil) {
203: NSLog(@"closeMyModel. Task is not running.\n"); return ;
204: }
205: [[NSNotificationCenter defaultCenter] removeObserver:self
206: name:NSFileHandleDataAvailableNotification object: inboundFileHandle];
207: [[NSNotificationCenter defaultCenter] removeObserver:self
208: name:NSFileHandleDataAvailableNotification object: errFileHandle];
209:
210: [inboundFileHandle closeFile];
211: [outboundFileHandle closeFile];
212: [errFileHandle closeFile];
213: [task terminate];
214: task = nil; //BUG. memory leak?
215: NSLog(@"Terminated the child process.\n");
216: }
217:
218: -(id) restartMyModel: (enum peer_type) peerType {
219: MyEnvironment *myEnvironment;
220: [self closeMyModel];
221: myEnvironment = [[MyEnvironment alloc] initFor: peerType]; //BUG. leak memory?
222: [myEnvironment retain];
223: [myEnvironment showForDebug]; // for debug.
224: [self openMyModel: myEnvironment ];
225: return self;
226: }
227:
228: // messenges
229: -(void) sayTheMessageAboutX {
230: NSLog(@"myDocumentSaidTheMessageAboutX=%d\n",myDocumentSaidTheMessageAboutX);
231: if (!myDocumentSaidTheMessageAboutX) {
232: if ([MyEnvironment checkX] != 1)
233: [self messageDialog:
234: NSLocalizedString(@"A few commands (plot, ...) cannot be used, because X11 is not running.",nil) with: 0];
235: myDocumentSaidTheMessageAboutX = 1;
236: }
237: }
238:
239: - (IBAction) oxEvaluate:(id) sender {
240: NSString* cmd0;
241: NSMutableString *cmd;
242: NSRange r;
243:
244: if (inEvaluation) {
245: NSLog(@"In evaluatioin. ");
246: [self messageDialog: NSLocalizedString(@"Evaluating...",nil) with: 0];
247: return;
248: }
249: if (notebookMode) doInsertNewInputCell=0;
250: else [[MyOutputWindowController sharedMyOutputWindowController: self] showUp];
251: ox_texmacs_level=0;
252: [self clearLines];
253:
254: [textViewIn setTypingAttributes: myDefaultTypingAttributes];
255:
256: if (notebookMode) {
257: cmd0 = [self getContentsOfInputCell];
258: [self prepareOutputCell];
259: }else if (onlySelectedArea) {
260: r = [textViewIn selectedRange];
261: // NSLog(@"r=(%d,%d)\n",r.location,r.length);
262: cmd0 = [textViewIn string];
263: if (r.length != 0) {
264: cmd0= [cmd0 substringWithRange: r];
265: }else{
266: int pos;
267: r = [cmd0 lineRangeForRange: r];
268: pos = r.location+r.length;
269: [textViewIn setSelectedRange: r]; // select the range containing the insertion point.
270: if (pos < [cmd0 length]) {
271: [textViewIn replaceCharactersInRange: NSMakeRange(pos+1,0) withString: @""];
272: }else{
273: [textViewIn replaceCharactersInRange: NSMakeRange(pos,0) withString: @"\n"];
274: }
275: cmd0 = [cmd0 substringWithRange:r ];
276: }
277: }else{
278: cmd0 = [textViewIn string];
279: MyOutputWindowController *mc;
280: mc = [MyOutputWindowController sharedMyOutputWindowController: self];
281: [mc clearOutputWindow];
282: }
283: cmd = [NSMutableString stringWithString: cmd0 ];
284:
285: [self changeInputCounterField: 1];
286: if (peer == OX_TEXMACS) [self startIndicator];
287: [self oxEvaluateString: cmd withMark: TRUE];
288: [self changeOutputCounterField: 1];
289: }
290:
291: - (IBAction) oxInterrupt:(id) sender {
292:
293: NSAlert *alert = [[NSAlert alloc] init];
294: [alert addButtonWithTitle: NSLocalizedString(@"OK",nil)];
295: [alert addButtonWithTitle: NSLocalizedString(@"Cancel",nil)];
296: [alert setMessageText: NSLocalizedString(@"Interrupt the ox server?",nil)];
297: [alert setInformativeText:NSLocalizedString(@"The OX-RFC-100 interruption protocol is used.",nil)];
298: [alert setAlertStyle:NSWarningAlertStyle];
299: if ([alert runModal] != NSAlertFirstButtonReturn) {
300: // Cancel clicked, return.
301: return;
302: }
303: [alert release];
304:
305: fprintf(stderr,"Trying to interrupt.\n");
306: [task interrupt];
307: inputCounter = outputCounter = 0;
308: [self stopIndicator];
309: [myDecoder reset];
310: }
311: -(IBAction) oxRenderOutput: (id) sender {
312: [self messageDialog: @"oxRenderOutput has not been implemented." with: 0];
313: }
314:
315: -(IBAction) oxEvaluateSelected: (id) sender {
316: // try or test something here
317: // end of try or test.
318: // fprintf(stderr,"OnlySelectedArea\n");
319: if (notebookMode && (onlySelectedArea == 0)) {
320: [self messageDialog: NSLocalizedString(@"Selection will be ignored in the notebook style.",nil) with: 0];
321: }
322: if (onlySelectedArea) onlySelectedArea = 0; else onlySelectedArea = 1;
323: }
324:
325: -(IBAction) oxEvaluateRegisteredString: (id) sender {
326: int ans;
327: NSAlert *alert = [[NSAlert alloc] init];
328: [alert addButtonWithTitle: NSLocalizedString(@"Cancel",nil)];
329: [alert addButtonWithTitle: NSLocalizedString(@"unix shell",nil)];
330: [alert addButtonWithTitle: NSLocalizedString(@"Risa/Asir",nil)];
331: [alert setMessageText: NSLocalizedString(@"Restart the computation server?",nil)];
332: //[alert setInformativeText:NSLocalizedString(@"",nil)];
333: [alert setAlertStyle:NSWarningAlertStyle];
334: ans = [alert runModal];
335: [alert release];
336: if (ans == NSAlertFirstButtonReturn) {
337: // Cancel clicked, return.
338: return ;
339: } else if (ans == NSAlertSecondButtonReturn) {
340: [self restartMyModel: BASH];
341: inputCounter = outputCounter = 0;
342: return ;
343: }else{
344: [self restartMyModel: OX_TEXMACS];
345: inputCounter = outputCounter = 0;
346: [myDecoder reset];
347: return;
348: }
349: }
350:
351: -(IBAction) checkSelectedArea: (id) sender {
352: int ans;
353: ans = [self selectIllegalCharacter];
354: if (ans) return;
355: [self selectBlockForward];
356: }
357:
358: -(int) oxEvaluateString: (NSString *) cmd withMark: (BOOL) yes {
359: NSData* cmdInData;
360: NSLog(@"Evaluating... ");
361: NSLog(@"%@",cmd);
362: // Evaluation is here.
363: cmdInData = [cmd dataUsingEncoding: NSUTF8StringEncoding];
364: @try {
365: //todo if (yes) [outboundFileHandle writeData: peerStartEvaluateMark];
366: [outboundFileHandle writeData: cmdInData];
367: if (yes) [outboundFileHandle writeData: peerEndEvaluteMark];
368: } @catch (NSException *exception) {
369: NSLog(@"oxEvalluateString Caught %@: %@", [exception name], [exception reason]);
370: [self messageDialog: NSLocalizedString(@"Error: Engine is not responding.",nil) with: 0];
371: return -1;
372: } @finally {
373: NSLog(@"writeData suceeded.\n");
374: }
375: // [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 10.0]];
376: NSLog(@"\nDone.\n");
377: return 0;
378: }
379:
380: - (void) outputString: (NSString *) amt {
381: NSRange myRange = NSMakeRange([[textViewOut textStorage] length],0);
382: if (myDebug) NSLog(@"Get in outputString\n");
383: [textViewOut replaceCharactersInRange: myRange withString: amt];
384: [textViewOut scrollRangeToVisible: NSMakeRange([[textViewOut textStorage] length],0)];
385: //[textViewOut replaceCharactersInRange: NSMakeRange(0,NSMakeRange(0,[textViewOut length])) withString: amt];
386: if (notebookMode) [self outputStringInNotebookMode: amt];
387: else {
388: MyOutputWindowController *mc;
389: mc = [MyOutputWindowController sharedMyOutputWindowController: self];
390: [mc outputStringToOutputWindow: amt];
391: }
392: }
393: - (void) outputErrorString: (NSString *) amt {
394: int oldEnd;
395: int newEnd;
396: oldEnd = [[textViewOut textStorage] length];
397: NSRange myRange = NSMakeRange(oldEnd,0);
398: [textViewOut replaceCharactersInRange: myRange withString: amt];
399: newEnd = [[textViewOut textStorage] length];
400: [textViewOut setTextColor: [NSColor orangeColor] range: NSMakeRange(oldEnd,newEnd-oldEnd)];
401: [textViewOut scrollRangeToVisible: NSMakeRange(newEnd,0)];
402: }
403:
404: - (void) printErrorMessage: (NSString *) amt {
405: MyOutputWindowController *mc;
406: if (notebookMode) [self outputErrorStringInNotebookMode: amt];
407: else {
408: mc = [MyOutputWindowController sharedMyOutputWindowController: self];
409: [mc printErrorMessageToOutputWindow: amt];
410: }
411: }
412: -(void)outputStringInNotebookMode: (NSString *)msg {
413: [self outputStringInNotebookMode: msg withColor: [NSColor blueColor]];
414: }
415: -(void)outputErrorStringInNotebookMode: (NSString *)msg {
416: [self outputStringInNotebookMode: msg withColor: [NSColor redColor]];
417: }
418: -(void)outputStringInNotebookMode: (NSString *)msg withColor: (NSColor *)color{
419: NSRange range;
420: int insertPos;
421: range=[textViewIn selectedRange];
422: insertPos = range.location+range.length;
423: range = NSMakeRange(insertPos,0);
424: [textViewIn replaceCharactersInRange: range withString: msg];
425: range = NSMakeRange(insertPos,[msg length]);
426: [textViewIn setTextColor: color range: range];
427: range=NSMakeRange(range.location+range.length,0);
428: [textViewIn scrollRangeToVisible: range];
429: [textViewIn setSelectedRange: range];
430: @synchronized(self) {
431: if (doInsertNewInputCell) {
432: if (![self getOutOfOutputCell]) [self insertInputCell];
433: doInsertNewInputCell = 0;
434: }
435: }
436: }
437:
438: -(IBAction) clearTextViewOut: (id) sender {
439: NSRange myRange = NSMakeRange(0,[[textViewOut textStorage] length]);
440: [textViewOut replaceCharactersInRange: myRange withString: @""];
441: [textViewOut replaceCharactersInRange: NSMakeRange(0,0) withString: @" \n \n \n"];
442: [textViewOut scrollRangeToVisible: NSMakeRange(0,[[textViewOut textStorage] length])];
443: }
444:
445: - (void) messageDialog: (NSString *)msg with: (int) no {
446: char s[256];
447: NSAlert *alert = [[NSAlert alloc] init];
448: sprintf(s,"%d",no);
449: [alert addButtonWithTitle: @"OK"];
450: [alert setMessageText: msg] ;
451: if (no) [alert setInformativeText: [NSString stringWithCString: (const char *) s]];
452: [alert setAlertStyle:NSWarningAlertStyle];
453: [alert runModal];
454: [alert release];
455: }
456:
457: -(void) printDocument: (id) sender {
458: int status;
459: NSAlert *alert = [[NSAlert alloc] init];
460: [alert addButtonWithTitle:NSLocalizedString(@"Cancel",nil)];
461: [alert addButtonWithTitle:NSLocalizedString(@"Print output view",nil)];
462: [alert addButtonWithTitle:NSLocalizedString(@"Print input view",nil)];
463: [alert setMessageText:NSLocalizedString(@"Which view will you print?",nil)];
464: [alert setAlertStyle:NSWarningAlertStyle];
465: status = [alert runModal];
466: switch(status) {
467: case NSAlertThirdButtonReturn:
468: [textViewIn print: sender]; break;
469: case NSAlertSecondButtonReturn:
470: [textViewOut print: sender]; break;
471: default:
472: // Cancel clicked, return.
473: return;
474: }
475: [alert release];
476: }
477:
478: -(void) showHelp: (id)sender {
479: BOOL ans;
480: NSString *path=nil;
481: //bug. temporary.
482: path = [OpenXM_HOME stringByAppendingString: @"/doc/cfep/intro-ja.html"];
483:
484: ans = [[NSWorkspace sharedWorkspace] openFile:path withApplication: @"Help Viewer"];
485: if (ans != YES) {
486: [self messageDialog: NSLocalizedString(@"Help file is not found at cfep.app/OpenXM/doc/cfep",nil) with: 0];
487: }
488: }
489:
490: -(void) changeInputCounterField: (int) inc {
491: NSString *ss;
492: ss = [NSString stringWithFormat: NSLocalizedString(@"Input%d",nil), inputCounter];
493: [inputCounterField setStringValue: ss];
494: inputCounter += inc;
495: return;
496: }
497: -(void) changeOutputCounterField: (int) inc {
498: NSString *ss;
499: ss = [NSString stringWithFormat: NSLocalizedString(@"Out%d",nil),outputCounter];
500: [outputCounterField setStringValue: ss];
501: outputCounter += inc;
502: return;
503: }
504: -(void) changeOutputCounterFieldWithString: (NSString *) ss {
505: [outputCounterField setStringValue: ss];
506: return;
507: }
508:
509: -(void) startIndicator {
510: if (inEvaluation) return ;
511: inEvaluation = 1;
512: [myIndicator startAnimation: self];
513: }
514: -(void) stopIndicator {
515: if (inEvaluation == 0) return ;
516: inEvaluation = 0;
517: [myIndicator stopAnimation: self];
518: }
519:
520:
521: int debugInbound = 0;
522: - (void)readInboundData:(NSNotification*)aNotification
523: {
524: static int state=0;
525: static int u0 = 0;
526: static int u1 = 0;
527: static int u2 = 0;
528: int n,i,j,k;
529: unsigned char *d;
530: unsigned char *d2;
531: int c;
532: NSMutableString* inboundString;
533: NSData* data;
534: NSMutableData* data2;
535: NSString *act;
536: int channel;
537: @synchronized (self) {
538: if (debugInbound) NSLog(@"Reading inboudData\n");
539: data=[ inboundFileHandle availableData ];
540: n = [data length]; d = (unsigned char *)[data bytes];
541: if (debugInbound) NSLog(@"n=%d\n",n);
542: // if (n < 30) { for (k=0; k<n; k++) printf("%2x ",d[k]); printf("\n"); }
543: if (n == 0) { NSLog(@"Broken pipe?\n"); [self messageDialog: @"Error: Engine is not responding." with: 0]; return ; }
544: data2 = [NSMutableData dataWithCapacity: (n+4)];
545: d2 = (unsigned char *)[data2 mutableBytes];
546: i = 0; d2[i] = 0;
547: for (j = 0; j< n; j++) {
548: c = d[j];
549: if (c == END_OF_EVALUATION_OF_OX_TEXMACS) {
550: [self stopIndicator];
551: ox_texmacs_level--;
552: if (ox_texmacs_level <= 0) doInsertNewInputCell = 1;
553: } else if (c == START_OF_RESULT_OF_OX_TEXMACS) {
554: ox_texmacs_level++;
555: }
556: switch(state) {
557: case 1:
558: u1 = d[j];
559: d2[i] = u0; i++; d2[i] = u1; i++; d2[i] = 0;
560: state = 0; break;
561: case 2:
562: u1 = d[j]; state = 3; break;
563: case 3:
564: u2 = d[j];
565: d2[i] = u0; i++; d2[i] = u1; i++; d2[i] = u2; i++ ; d2[i] = 0;
566: state = 0; break;
567: case 4: // MYDECODER
568: u1 = d[j]; state = 5; break;
569: case 5:
570: u2 = d[j];
571: c = ((u0 & 0x3) << 6) | (((u1 & 0x7) << 3) & 0x38) | (u2 & 0x7);
572: // NSLog(@"|%2x| ",c); // send it to myDecoder
573: act = [myDecoder myDecoder: c from: self];
574: if (act != nil) {
575: if (debugMyTunnel) [self outputErrorString: act]; // for debug.
576: channel = [myDecoder getChannel];
577: if (channel == 0) [self errorActionFor: act];
578: else if (channel == 1) [self openGLActionFor: act];
579: else if (channel == 2) [self openGLInitActionFor: act];
580: }
581: state = 0; break;
582: default:
583: c=d[j];
584: if ((c >> 5) == UTF8_2) { u0=c ; state=1; }
585: else if ((c >> 4) == UTF8_3) { u0 =c ; state = 2; }
586: else if ((c >> 2) == MYDECODER) { u0=c; state = 4; }
587: else if ( c & 0x80) {
588: state = 0; NSLog(@"err|%2x| ",c);
589: }else {
590: if (c > 5) {
591: d2[i] = c; i++; d2[i] = 0; state = 0;
592: }
593: }
594: }
595: }
596: }
597: if (i) {
598: inboundString = [NSString stringWithCString: d2 encoding: NSUTF8StringEncoding];
599: [self outputString: inboundString]; // do this out of the synchronized session.
600: }
601:
602: if (n) [[aNotification object] waitForDataInBackgroundAndNotify];
603: }
604:
605:
606: - (void)readErrData:(NSNotification*)aNotification
607: {
608: int n,i,j;
609: #define MD_SIZE 5000
610: unsigned char *d;
611: int c;
612: NSMutableString* inboundString;
613: NSData* inboundData ;
614: @synchronized (self) {
615: inboundString = [NSMutableString stringWithCapacity: (MD_SIZE+2)];
616:
617: // NSLog(@"(err) Reading inboudData\n");
618: inboundData=[ errFileHandle availableData ];
619: n = [inboundData length]; d = (unsigned char *)[inboundData bytes];
620: i = 0;
621: while (i < n ) {
622: for (j = 0; j<MD_SIZE ; j++ ) {
623: c = d[i]; // putchar(c);
624: [inboundString appendString: [NSString stringWithFormat: @"%c", (c & 0x7f)] ];
625: i++; if (i >= n) { j++; break;}
626: }
627: // NSLog( [NSString stringWithFormat: @"i=%d, j=%d\n", i, j] );
628: j++;
629: // NSLog(@"%@", inboundString );
630: [self outputErrorString: inboundString];
631: inboundString = [NSMutableString stringWithCapacity: (MD_SIZE+2)] ;
632: }
633: }
634: if (n) [[aNotification object] waitForDataInBackgroundAndNotify];
635:
636: }
637:
638: -(int) specialCharacterInNotebookMode: (int) c {
639: if (!notebookMode) return 0;
640: if (c == BEGIN_INPUT_CELL) return 1;
641: else if (c==BEGIN_OUTPUT_CELL) return 1;
642: else if (c==END_INPUT_CELL) return 1;
643: else if (c==END_OUTPUT_CELL) return 1;
644: return 0;
645: }
646: -(int) selectIllegalCharacter {
647: NSRange r;
648: NSString *in;
649: int i, n;
650: int state,offset;
651: int c,c2;
652: // 1: in /*
653: // 2: in //
654: // 3: in "
655: // 4: in '
656: in = [textViewIn string];
657: r = [textViewIn selectedRange];
658: //NSLog(@"%d, %d\n",r.location, r.length);
659: if (r.length < 1) {
660: offset = 0;
661: n = [in length];
662: }else{
663: offset = r.location;
664: n = offset + r.length;
665: }
666: state = 0;
667: for (i=offset; i<n; i++) {
668: c = [in characterAtIndex: i]; // NSLog(@"|%04x| ",c);
669: if (i != n-1) c2 = [in characterAtIndex: (i+1)];
670: else c2 = 0;
671: switch (state) {
672: case 0:
673: if ((c == 0x1b)) {
674: [textViewIn setSelectedRange: NSMakeRange(i,1)];
675: [self outputErrorString:
676: NSLocalizedString(@"Error: Illegal control character.\n",nil)];
677: return 1;
678: }
679: if ((c > 0x7e) && (![self specialCharacterInNotebookMode: c])) {
680: [textViewIn setSelectedRange: NSMakeRange(i,1)];
681: [self outputErrorString:
682: NSLocalizedString(@"Error: Program part must be written only by ascii characters.\n",nil)];
683: return 1;
684: }
685: if (((c == '/') && (c2 == '*')) || (notebookMode && (c == BEGIN_OUTPUT_CELL))) {
686: i++; state = 1;
687: }else if ((c == '/') && (c2 == '/')) {
688: i++; state = 2;
689: }else if (c == '"') {
690: state = 3;
691: }else if (c == '\'') {
692: state = 4;
693: }else state=0;
694: break;
695: case 1:
696: if (((c == '*') && (c2 == '/')) || (notebookMode && (c2 == END_OUTPUT_CELL))) {
697: i++; state = 0;
698: }
699: break;
700: case 2:
701: if (c == '\n') state = 0;
702: break;
703: case 3:
704: if (c == '"') state = 0;
705: else if (c == '\\') {
706: i++; //BUG. skip only one letter.
707: }
708: break;
709: case 4:
710: if (c == '\'') state = 0;
711: else if (c == '\\') {
712: i++; //BUG. skip only one letter.
713: }
714: break;
715: }
716: }
717: // [self outputErrorString: @"No illegal character.\n"];
718: return 0;
719: }
720:
721: -(NSRange) selectBlockForward {
722: NSRange r;
723: NSRange ans;
724: NSString *in;
725: int i, n;
726: int first, last,offset, state;
727: int c,c2;
728: static int prevStart = -1;
729:
730: first = last = 0;
731: ans = NSMakeRange(0,0);
732:
733: // 1: in /*
734: // 2: in //
735: // 3: in "
736: // 4: in '
737: in = [textViewIn string];
738: r = [textViewIn selectedRange];
739: if (r.length < 1) {
740: offset = 0;
741: } else {
742: offset = r.location;
743: }
744: if (offset == prevStart) {
745: offset = offset+1;
746: }
747: n = [in length];
748: if (offset >= n) offset = 0;
749: state = 0;
750: for (i=offset; i<n; i++) {
751: c = [in characterAtIndex: i];
752: if (i != n-1) c2 = [in characterAtIndex: (i+1)];
753: else c2 = 0;
754: switch (state) {
755: case 0:
756: if (c == '{') {
757: ans=[self selectBlockForwardFrom: i with: c and: '}'];
758: if (prevStart != ans.location) { prevStart = ans.location; }
759: return ans;
760: }else if (c == '(') {
761: ans=[self selectBlockForwardFrom: i with: c and: ')'];
762: if (prevStart != ans.location) { prevStart = ans.location; }
763: return ans;
764: }else if (c == '[') {
765: ans=[self selectBlockForwardFrom: i with: c and: ']'];
766: if (prevStart != ans.location) { prevStart = ans.location; }
767: return ans;
768: }
769: if ((c == '/') && (c2 == '*')) {
770: i++; state = 1;
771: }else if ((c == '/') && (c2 == '/')) {
772: i++; state = 2;
773: }else if (c == '"') {
774: state = 3;
775: }else if (c == '\'') {
776: state = 4;
777: }else state=0;
778: break;
779: case 1:
780: if ((c == '*') && (c2 == '/')) {
781: i++; state = 0;
782: }
783: break;
784: case 2:
785: if (c == '\n') state = 0;
786: break;
787: case 3:
788: if (c == '"') state = 0;
789: else if (c == '\\') {
790: i++; //BUG. skip only one letter.
791: }
792: break;
793: case 4:
794: if (c == '\'') state = 0;
795: else if (c == '\\') {
796: i++; //BUG. skip only one letter.
797: }
798: break;
799: }
800: }
801: return ans;
802: }
803: -(NSRange) selectBlockForwardFrom: (int) offset with: (int) first and: (int) last {
804: NSRange r;
805: NSRange ans;
806: NSString *in;
807: int i, n;
808: int state;
809: int c,c2;
810: int level;
811: int startpos;
812:
813: level = 0;
814: ans = NSMakeRange(0,0);
815:
816: // 1: in /*
817: // 2: in //
818: // 3: in "
819: // 4: in '
820: in = [textViewIn string];
821: r = [textViewIn selectedRange];
822: n = [in length];
823: state = 0;
824: for (i=offset; i<n; i++) {
825: c = [in characterAtIndex: i];
826: if (i != n-1) c2 = [in characterAtIndex: (i+1)];
827: else c2 = 0;
828: switch (state) {
829: case 0:
830: if (level == 0) {
831: if (c == first) {
832: level = 1; startpos = i;
833: }
834: } else if (level > 0) {
835: if (c == first) level++;
836: else if (c == last) level--;
837: else ;
838: if (level == 0) {
839: ans = NSMakeRange(startpos, i+1-startpos);
840: [textViewIn setSelectedRange: ans];
841: [textViewIn scrollRangeToVisible: NSMakeRange(startpos,0)];
842: return ans;
843: }
844: }
845:
846: if ((c == '/') && (c2 == '*')) {
847: i++; state = 1;
848: }else if ((c == '/') && (c2 == '/')) {
849: i++; state = 2;
850: }else if (c == '"') {
851: state = 3;
852: }else if (c == '\'') {
853: state = 4;
854: }else state=0;
855: break;
856: case 1:
857: if ((c == '*') && (c2 == '/')) {
858: i++; state = 0;
859: }
860: break;
861: case 2:
862: if (c == '\n') state = 0;
863: break;
864: case 3:
865: if (c == '"') state = 0;
866: else if (c == '\\') {
867: i++; //BUG. skip only one letter.
868: }
869: break;
870: case 4:
871: if (c == '\'') state = 0;
872: else if (c == '\\') {
873: i++; //BUG. skip only one letter.
874: }
875: break;
876: }
877: }
878: if (level > 0) {
879: [self outputErrorString: NSLocalizedString(@"Error: No right parenthesis.\n",nil)] ;
880: [textViewIn setSelectedRange: NSMakeRange(startpos,n-startpos)];
881: ans = NSMakeRange(startpos,-1);
882: return ans;
883: }
884: return ans;
885: }
886:
887: -(void) errorActionFor: (NSString *)cmd
888: {
889: NSArray *a;
890: NSRange r;
891: static NSRange r2;
892: static NSRange r3;
893: static int r2IsSet;
894: static int r3IsSet;
895: NSString *s;
896: int line,i, currentLine;
897: // NSLog(@"cmd=%@\n",cmd);
898: if ([cmd hasPrefix: @"Begin"] == YES) {
899: r3IsSet = 0; r2IsSet = 0;
900: }else if ([cmd hasPrefix: @"End"] == YES) {
901: if (r2IsSet) {
902: [textViewIn setSelectedRange: r2];
903: [textViewIn scrollRangeToVisible: r2];
904: r2IsSet = 0;
905: }
906: if (r3IsSet) { //gotoLine, xyz is stronger than findAndSelect.
907: [textViewIn setSelectedRange: r3];
908: [textViewIn scrollRangeToVisible: r3];
909: r3IsSet = 0;
910: }
911: }else if ([cmd hasPrefix: @"findAndSelect"] == YES) {
912: a = [cmd componentsSeparatedByString: @", "];
913: if ([a count] > 1) {
914: a = [[a objectAtIndex: 1] componentsSeparatedByString: @"\n"];
915: s = [a objectAtIndex: 0];
916: r2 = [[textViewIn string] rangeOfString: s];
917: r2IsSet = 1;
918: // selection will be done in End.
919: [self printErrorMessage: [NSLocalizedString(@"Error in executing ",nil) stringByAppendingString: s]];
920: [self printErrorMessage: @"\n"];
921: }
922: }else if ([cmd hasPrefix: @"findAndShow"] == YES) {
923: a = [cmd componentsSeparatedByString: @", "];
924: if ([a count] > 1) {
925: a = [[a objectAtIndex: 1] componentsSeparatedByString: @"\n"];
926: s = [a objectAtIndex: 0];
927: [self printErrorMessage: [NSLocalizedString(@"Error in executing ",nil) stringByAppendingString: s]];
928: [self printErrorMessage: @"\n"];
929: }
930: }else if ([cmd hasPrefix: @"printErrorMessage"] == YES) {
931: a = [cmd componentsSeparatedByString: @"ErrorMessage, "];
932: if ([a count] > 1) {
933: s = [a objectAtIndex: 1];
934: [self printErrorMessage: [NSLocalizedString(@"Error: ",nil) stringByAppendingString: s]];
935: [self printErrorMessage: @"\n"];
936: }
937: }else if ([cmd hasPrefix: @"gotoLine"] == YES) {
938: a = [cmd componentsSeparatedByString: @"Line, "];
939: if ([a count] > 1) {
940: s = [a objectAtIndex: 1];
941: [self printErrorMessage: [NSLocalizedString(@"Error at ",nil) stringByAppendingString: s]];
942: [self printErrorMessage: @"\n"];
943: line = [s intValue];
944: [self addLine: line];
945: // move the selection to the line.
946: i = [self gotoLine: line];
947: if (i >= 0) {
948: r3 = NSMakeRange(i,0); // NSLog(@"Goto the location=%d\n",i);
949: r3IsSet = 1;
950: }
951: }
952: }
953: }
954:
955: -(void) clearLines {
956: [errorLines removeAllObjects];
957: [self nextLine: -1];
958: }
959: -(void) addLine: (int) n {
960: [errorLines addObject: [NSNumber numberWithInt: n]];
961: }
962: -(int) nextLine: (int) n {
963: static int p = 0;
964: int v;
965: if (n < 0) { p = 0; return -1; }
966: if (p < [errorLines count]) ; else { p = 0; return -1;}
967: v = [[errorLines objectAtIndex: p] intValue];
968: p++;
969: return v;
970: }
971: -(int) gotoLine: (int) line {
972: NSString *s;
973: NSRange r;
974: NSRange r3;
975: int currentLine,i;
976: // move the selection to the line line.
977: s = [textViewIn string];
978: if (onlySelectedArea || notebookMode) r = [textViewIn selectedRange];
979: else r = NSMakeRange(0,[s length]);
980: // NSLog(@"r.location=%d",r.location);
981: currentLine = 1;
982: for (i=r.location; i< r.location+r.length; i++) {
983: if (currentLine == line) {
984: r3 = NSMakeRange(i,0); // NSLog(@"Goto the location=%d\n",i);
985: [textViewIn setSelectedRange: r3 ];
986: [textViewIn scrollRangeToVisible: r3];
987: return i; // set r3IsSet
988: break;
989: }
990: if ([s characterAtIndex: i] == '\n') ++currentLine;
991: }
992: return -1;
993: }
994: -(int) gotoNextError: (id) sender{
995: int n;
996: n = [self nextLine: 0];
997: if (n >= 0) { [self gotoLine: n]; return n;}
998: else return -1;
999: }
1000:
1001: /* act= 0;[glRectf,-0.5, ...] */
1002: -(int) openGLActionFor: (NSString *)act {
1003: NSArray *a;
1004: int gid;
1005: a=[act componentsSeparatedByString: @";"];
1006: if ([a count] < 2) {
1007: [self printErrorMessage: @"Invalid format in openGLActionFor. gid and command must be separated by ;\n"];
1008: return -1;
1009: }
1010: gid = [[a objectAtIndex: 0] intValue];
1011: [MyOpenGLController addOglComm: [a objectAtIndex: 1] to: gid from: self];
1012: return 0;
1013: }
1014: -(int) openGLInitActionFor: (NSString *) act {
1015: NSArray *a;
1016: int gid;
1017: a=[act componentsSeparatedByString: @";"];
1018: if ([a count] < 2) {
1019: [self printErrorMessage: @"Invalid format in openGLInitActionFor. gid and command must be separated by ;\n"];
1020: return -1;
1021: }
1022: gid = [[a objectAtIndex: 0] intValue];
1023: [MyOpenGLController addOglInitComm: [a objectAtIndex: 1] to: gid from: self];
1024: return 0;
1025: }
1026:
1027: -(void) setBasicStyle: (id) sender {
1028: notebookMode = 0;
1029: [self updateInterfaceStyleMenu];
1030: }
1031: -(void) setNotebookStyle: (id) sender {
1032: notebookMode = 1;
1033: [self updateInterfaceStyleMenu];
1034: [self insertInputCell];
1035: }
1036: -(void) updateInterfaceStyleMenu {
1037: if (!menuItemNotebookMode) return;
1038: if (!menuItemBasicMode) return;
1039: if (notebookMode) {
1040: [menuItemNotebookMode setState: NSOnState];
1041: [menuItemBasicMode setState: NSOffState];
1042: }else {
1043: [menuItemNotebookMode setState: NSOffState];
1044: [menuItemBasicMode setState: NSOnState];
1045: }
1046: }
1047: -(void) setEngineRisaAsir: (id) sender {
1048: oxEngine = 0;
1049: [self updateSelectEngineMenu];
1050: [self oxEvaluateString: @"!asir;" withMark: TRUE];
1051: }
1052: -(void) setEngineKanSm1: (id) sender {
1053: oxEngine = 1;
1054: [self updateSelectEngineMenu];
1055: [self oxEvaluateString: @"!sm1;" withMark: TRUE];
1056: }
1057: -(void) updateSelectEngineMenu {
1058: if (!menuItemRisaAsir) return;
1059: if (!menuItemKanSm1) return;
1060: if (oxEngine == 0) {
1061: [menuItemRisaAsir setState: NSOnState];
1062: [menuItemKanSm1 setState: NSOffState];
1063: }else if (oxEngine == 1) {
1064: [menuItemRisaAsir setState: NSOffState];
1065: [menuItemKanSm1 setState: NSOnState];
1066: }
1067: }
1068: -(void) setDebugMyTunnel: (id) sender {
1069: if (debugMyTunnel) {
1070: debugMyTunnel = 0;
1071: if (menuItemOutputDebugMessages) [menuItemOutputDebugMessages setState: NSOffState];
1072: } else {
1073: debugMyTunnel = 1;
1074: if (menuItemOutputDebugMessages) [menuItemOutputDebugMessages setState: NSOnState];
1075: }
1076: [MyUtil setDebugMyUtil];
1077: }
1078: -(void) mytest: (id) sender {
1079: // Add code here for testing.
1080: int n;
1081: n=[self gotoNextError: nil];
1082: NSLog(@"error line=%d\n",n);
1083: }
1084: -(void) addMenuExec {
1085: static int done=0;
1086: NSMenu *menuItem;
1087: NSMenu *menuExec;
1088: NSMenuItem *menuItemEvaluate;
1089: NSMenuItem *menuItemInterrupt;
1090: NSMenuItem *menuItemInterfaceStyle;
1091: NSMenuItem *menuItemSelectEngine;
1092: NSMenuItem *menuItemGotoNextError;
1093: NSMenuItem *menuItemForTest;
1094: if (done) return;
1095: done = 1;
1096: // oxEvalute
1097: menuExec = [[[NSMenu alloc] init] autorelease];
1098: [menuExec setTitle: NSLocalizedString(@"Execution",nil)];
1099: menuItemEvaluate = [[[NSMenuItem alloc] init] autorelease];
1100: [menuItemEvaluate setTitle: NSLocalizedString(@"Evaluate",nil)];
1101: [menuItemEvaluate setAction: @selector(oxEvaluate:)];
1102: [menuItemEvaluate setTarget: [[NSApp mainWindow] document]];
1103: [menuItemEvaluate setKeyEquivalentModifierMask: NSCommandKeyMask];
1104: [menuItemEvaluate setKeyEquivalent: @"\n"];
1105: [menuExec addItem: menuItemEvaluate];
1106: // oxInterrupt
1107: menuItemInterrupt = [[[NSMenuItem alloc] init] autorelease];
1108: [menuItemInterrupt setTitle: NSLocalizedString(@"Interrupt",nil)];
1109: [menuItemInterrupt setAction: @selector(oxInterrupt:)];
1110: [menuItemInterrupt setTarget: [[NSApp mainWindow] document]]; // do not use self.
1111: [menuExec addItem: menuItemInterrupt];
1112:
1113: // gotoNextError
1114: menuItemGotoNextError = [[[NSMenuItem alloc] init] autorelease];
1115: [menuItemGotoNextError setTitle: NSLocalizedString(@"Next error line",nil)];
1116: [menuItemGotoNextError setAction: @selector(gotoNextError:)];
1117: [menuItemGotoNextError setTarget: [[NSApp mainWindow] document]];
1118: [menuExec addItem: menuItemGotoNextError];
1119:
1120: // gotoNextError
1121: menuItemOutputDebugMessages = [[[NSMenuItem alloc] init] autorelease];
1122: [menuItemOutputDebugMessages setTitle: NSLocalizedString(@"Output debug messages",nil)];
1123: [menuItemOutputDebugMessages setAction: @selector(setDebugMyTunnel:)];
1124: [menuItemOutputDebugMessages setTarget: [[NSApp mainWindow] document]];
1125: [menuExec addItem: menuItemOutputDebugMessages];
1126:
1127: // interface style
1128: NSMenu *submenuInterfaceItem = [[[NSMenu alloc] init] autorelease];
1129: // basic-like
1130: NSMenuItem *menuItemBasicLike = [[[NSMenuItem alloc] init] autorelease];
1131: [menuItemBasicLike setTitle: NSLocalizedString(@"BASIC-like",nil)];
1132: [menuItemBasicLike setAction: @selector(setBasicStyle:)];
1133: [menuItemBasicLike setTarget: [[NSApp mainWindow] document]];
1134: menuItemBasicMode = menuItemBasicLike;
1135: [submenuInterfaceItem addItem: menuItemBasicLike];
1136: // notebook-like
1137: NSMenuItem *menuItemNotebookLike = [[[NSMenuItem alloc] init] autorelease];
1138: [menuItemNotebookLike setTitle: NSLocalizedString(@"Notebook-like",nil)];
1139: [menuItemNotebookLike setAction: @selector(setNotebookStyle:)];
1140: [menuItemNotebookLike setTarget: [[NSApp mainWindow] document]];
1141: menuItemNotebookMode = menuItemNotebookLike;
1142: [submenuInterfaceItem addItem: menuItemNotebookLike];
1143:
1144: menuItemInterfaceStyle = [[[NSMenuItem alloc] init] autorelease];
1145: [menuItemInterfaceStyle setTitle: NSLocalizedString(@"Interface style",nil)];
1146: [menuItemInterfaceStyle setSubmenu: submenuInterfaceItem];
1147: [menuExec addItem: menuItemInterfaceStyle];
1148: [self updateInterfaceStyleMenu];
1149:
1150: // select engine
1151: NSMenu *submenuSelectEngineItem = [[[NSMenu alloc] init] autorelease];
1152: // asir
1153: menuItemRisaAsir = [[[NSMenuItem alloc] init] autorelease];
1154: [menuItemRisaAsir setTitle: NSLocalizedString(@"Risa/Asir",nil)];
1155: [menuItemRisaAsir setAction: @selector(setEngineRisaAsir:)];
1156: [menuItemRisaAsir setTarget: [[NSApp mainWindow] document]];
1157: [submenuSelectEngineItem addItem: menuItemRisaAsir];
1158: // notebook-like
1159: menuItemKanSm1 = [[[NSMenuItem alloc] init] autorelease];
1160: [menuItemKanSm1 setTitle: NSLocalizedString(@"Kan/sm1",nil)];
1161: [menuItemKanSm1 setAction: @selector(setEngineKanSm1:)];
1162: [menuItemKanSm1 setTarget: [[NSApp mainWindow] document]];
1163: [submenuSelectEngineItem addItem: menuItemKanSm1];
1164:
1165: menuItemSelectEngine = [[[NSMenuItem alloc] init] autorelease];
1166: [menuItemSelectEngine setTitle: NSLocalizedString(@"Select engine",nil)];
1167: [menuItemSelectEngine setSubmenu: submenuSelectEngineItem];
1168: [menuExec addItem: menuItemSelectEngine];
1169: [self updateSelectEngineMenu];
1170:
1171:
1172: // test
1173: menuItemForTest = [[[NSMenuItem alloc] init] autorelease];
1174: [menuItemForTest setTitle: NSLocalizedString(@"For test",nil)];
1175: [menuItemForTest setAction: @selector(mytest:)];
1176: [menuItemForTest setTarget: [[NSApp mainWindow] document]];
1177: [menuExec addItem: menuItemForTest];
1178:
1179: menuItem = [[[NSMenuItem alloc] init] autorelease];
1180: [[NSApp mainMenu] insertItem: menuItem atIndex: 4];
1181: [menuItem setSubmenu: menuExec];
1182: }
1183:
1184: -(void) insertInputCell {
1185: NSRange r;
1186: NSString *ic;
1187: unichar uu[2];
1188: uu[0] = BEGIN_INPUT_CELL; uu[1] = END_INPUT_CELL;
1189: r = [textViewIn selectedRange]; r.length=0;
1190: ic = [NSString stringWithCharacters: uu length: 2];
1191: // NSLog(@"insertInputCell: r.location=%d, r.length=%d, %@\n",r.location,r.length,ic);
1192: [textViewIn replaceCharactersInRange: r withString: ic];
1193: r.location = r.location+1; r.length = 0;
1194: [textViewIn setSelectedRange: r ];
1195: r.location = r.location-1; r.length = 2;
1196: [textViewIn setTextColor: [NSColor blackColor] range: r];
1197: }
1198: -(NSString *) getContentsOfInputCell {
1199: int start,end,i,n;
1200: NSString *cmd0;
1201: NSRange r;
1202: cmd0 = [textViewIn string];
1203: start=0; end = n = [cmd0 length]; if (end > 0) end--;
1204: r = [textViewIn selectedRange];
1205: if (r.location < n) i = r.location; else i = n-1;
1206: if (i < 0) i=0;
1207: for (; i>=0; i--) {
1208: if ([cmd0 characterAtIndex: i] == BEGIN_INPUT_CELL) {
1209: start = i+1; break;
1210: }
1211: }
1212: for (i=start; i<n; i++) {
1213: if ([cmd0 characterAtIndex: i] == END_INPUT_CELL) {
1214: end = i-1; break;
1215: }
1216: }
1217: // NSLog(@"start=%d, end=%d\n",start,end);
1218: r.location = start; r.length = end-start+1;
1219: if (r.length > 0) {
1220: cmd0= [cmd0 substringWithRange: r];
1221: }else{
1222: cmd0 = @"";
1223: }
1224: if (end+2 <= n) r.location=end+2;
1225: r.length = 0;
1226: [textViewIn setSelectedRange: r];
1227: return cmd0;
1228: }
1229: // return 1 if there is the next inputCell
1230: -(int) getOutOfOutputCell {
1231: int start,end,i,n;
1232: NSString *cmd0;
1233: NSRange r;
1234: cmd0 = [textViewIn string];
1235: n = [cmd0 length];
1236: r = [textViewIn selectedRange];
1237: start = r.location;
1238: // NSLog(@"r.location=%d, r.length=%d\n",r.location,r.length);
1239: if (r.location < n) i = r.location; else i = n-1;
1240: if (i>0) i--;
1241: for (; i<n; i++) {
1242: if ([cmd0 characterAtIndex: i] == END_OUTPUT_CELL) {
1243: start = i+1; break;
1244: }else if ([cmd0 characterAtIndex: i] == BEGIN_INPUT_CELL) {
1245: r.location = i+1; r.length=0;
1246: [textViewIn setSelectedRange: r]; [textViewIn scrollRangeToVisible: r];
1247: return 1;
1248: }else if ([cmd0 characterAtIndex: i] == END_INPUT_CELL) {
1249: r.location = i-1; r.length=0;
1250: [textViewIn setSelectedRange: r]; [textViewIn scrollRangeToVisible: r];
1251: return 1;
1252: }
1253: }
1254: r.location = start; r.length = 0;
1255: [textViewIn setSelectedRange: r];
1256:
1257: for (i = start; i<n; i++) {
1258: // Try to find the next input cell.
1259: if ([cmd0 characterAtIndex: i] == BEGIN_INPUT_CELL) {
1260: r.location = i+1; r.length = 0;
1261: [textViewIn setSelectedRange: r]; [textViewIn scrollRangeToVisible: r];
1262: return 1;
1263: }else if ([cmd0 characterAtIndex: i] == END_INPUT_CELL) {
1264: // We are inside an input cell.
1265: r.location = i-1; r.length = 0;
1266: [textViewIn setSelectedRange: r]; [textViewIn scrollRangeToVisible: r];
1267: return 1;
1268: }
1269: }
1270: return 0;
1271: }
1272: -(void) prepareOutputCell {
1273: int start,end,i,j,n,m;
1274: NSString *cmd0;
1275: NSString *ic;
1276: unichar uu[7];
1277: NSRange r;
1278: start = -1; end = -1;
1279: cmd0 = [textViewIn string];
1280: n = [cmd0 length];
1281: r = [textViewIn selectedRange];
1282: i = r.location;
1283: if (i < 0) i = 0;
1284: if (i >= n) i = n-1;
1285: for (; i<n; i++) {
1286: if ([cmd0 characterAtIndex: i] == BEGIN_OUTPUT_CELL) {
1287: start = i;
1288: for (j=i; j>=0; j--) {
1289: if ([cmd0 characterAtIndex: j] <= ' ') {
1290: start = j;
1291: } else {
1292: if (start>0) start--;
1293: break;
1294: }
1295: }
1296: break;
1297: }else if ([cmd0 characterAtIndex: i] == BEGIN_INPUT_CELL) {
1298: start = i-1;
1299: if (start < 0) start = 0;
1300: end = -2;
1301: break;
1302: }
1303: }
1304: if (end == -2) {
1305: r.location = start; r.length=0;
1306: }else{
1307: end = start;
1308: i = start; if (i < 0) i = 0;
1309: for (; i<n; i++) {
1310: if ([cmd0 characterAtIndex: i] == END_OUTPUT_CELL) {
1311: end = i; break;
1312: }
1313: }
1314: if ((start == -1) || (end == -1)) {
1315: r.location = n; r.length=0;
1316: }else{
1317: r.location = start; r.length = end-start+1;
1318: }
1319: }
1320: [textViewIn replaceCharactersInRange: r withString: @""];
1321:
1322: uu[0] = '\n';
1323: uu[1] = BEGIN_OUTPUT_CELL; uu[2] = END_OUTPUT_CELL;
1324: m = 3;
1325: // If there is no next input cell, add a new one.
1326: for (i=r.location; i<n; i++) {
1327: if ([cmd0 characterAtIndex:i] == BEGIN_INPUT_CELL) {
1328: break;
1329: }
1330: }
1331: if ((i == n) || (r.location >= n)) {
1332: uu[3] = '\n'; uu[4] = BEGIN_INPUT_CELL; uu[5] = END_INPUT_CELL; m=6;
1333: }
1334: // NSLog(@"prepareOutputCell start=%d, length=%d, m=%d\n",start,r.length,m);
1335: r.length = 0;
1336: ic = [NSString stringWithCharacters: uu length: m];
1337: [textViewIn replaceCharactersInRange: r withString: ic];
1338: r.location = r.location+2; r.length = 0;
1339: [textViewIn setSelectedRange: r ];
1340: }
1341: @end
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>