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