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