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