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