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