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