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