File: [local] / OpenXM / src / cfep / MyDocument.m (download)
Revision 1.13, Fri Oct 7 05:13:42 2016 UTC (7 years, 11 months ago) by takayama
Branch: MAIN
CVS Tags: HEAD Changes since 1.12: +8 -2
lines
ox_asir must start after XQuartz gets in the running state.
Otherwise, ox_asir and ox_plot get stucked.
|
//
// MyDocument.m
// cfep
//
// Created by Nobuki Takayama
// Copyright (c) 2006 OpenXM.org
//
// [self setDefaultPeer BASH] or [self setDefaultPeer OX_TEXMACS]
#include <signal.h>
#import "MyDocument.h"
#import "MyOutputWindowController.h"
#import "MyOpenGLController.h"
int myDebug=0;
static int myDocumentSaidTheMessageAboutX = 0;
@implementation MyDocument
static int NoEngine = 0; // experimental.
static NSMenuItem *menuItemNoEngine = nil; // NoEngine
// For OnState or OffState in the execution menu
static NSMenuItem *menuItemNotebookMode = nil;
static NSMenuItem *menuItemBasicMode = nil;
static NSMenuItem *menuItemRisaAsir = nil;
static NSMenuItem *menuItemKanSm1 = nil;
static NSMenuItem *menuItemOutputDebugMessages = nil; //cf. debugMyTunnel;
static NSMenuItem *menuItemPrettyPrint = nil; // prettyPrint.
- (void)dealloc {
MyOutputWindowController *mowc;
if (myDebug) NSLog(@"dealloc of MyDocument.\n");
if (myDebug) NSLog(@"retainCount of task=%d\n",[task retainCount]); // why is it 2?
[self closeMyModel];
// [task dealloc]; //BUG. if we do this, error happens.
mowc = [MyOutputWindowController sharedMyOutputWindowController: self];
if (mowc != nil) [mowc closeMyOutputWindow: self];
if (errorLines) { [errorLines autorelease]; errorLines = nil; }
[myDecoder dealloc];
[dataFromFile release];
[rtfDataFromFile release];
[textDataFromFile release];
if (myDebug) NSLog(@"Done: dealloc of MyDocument.\n");
[super dealloc];
}
// The name of the nib file to load for this document.
- (NSString *)windowNibName
{
return @"MyDocument";
}
// Loads up the data when the nib file is loaded.
- (void)windowControllerDidLoadNib:(NSWindowController *)aController {
[super windowControllerDidLoadNib:aController];
if (dataFromFile) {
[self loadtextViewWithData:dataFromFile];
[dataFromFile release];
dataFromFile = nil;
} else if (rtfDataFromFile) {
[self loadtextViewWithRTFData: rtfDataFromFile];
[rtfDataFromFile release];
rtfDataFromFile = nil;
} else if (textDataFromFile) {
[self loadtextViewWithTextData: textDataFromFile];
[textDataFromFile release];
textDataFromFile = nil;
}
[self addMenuExec]; // adding the execution menu.
[textViewIn setAllowsUndo:YES];
if ([textViewIn isContinuousSpellCheckingEnabled]) [textViewIn toggleContinuousSpellChecking: self]; // Turn off the spell checking.
if ([textViewIn isAutomaticQuoteSubstitutionEnabled]) [textViewIn toggleAutomaticQuoteSubstitution: self]; // Turn off the smart quote.
if ([MyEnvironment isX11Installed] != 1)
[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];
// if ([MyEnvironment isGccInstalled] != 1)
// [self messageDialog: NSLocalizedString(@"gcc is not installed. To install it, insert MacOS DVD1 and open Xcode Tools->XcodeTools.mpkg",nil) with: 0];
[self sayTheMessageAboutX];
[self initAux];
}
// Load the view with data given an NSData.
- (void)loadtextViewWithData:(NSData *)data {
[textViewIn replaceCharactersInRange:NSMakeRange(0, [[textViewIn string] length]) withRTFD:data];
}
- (void)loadtextViewWithRTFData:(NSData *)data {
[textViewIn replaceCharactersInRange:NSMakeRange(0, [[textViewIn string] length]) withRTF:data];
}
-(void) loadtextViewWithTextData:(NSData *)data {
[textViewIn replaceCharactersInRange: NSMakeRange(0,[[textViewIn string] length])
withString:[NSString stringWithCString: [data bytes] encoding:NSUTF8StringEncoding]];
}
// Return an NSData representation of our document's view.
- (NSData *)dataRepresentationOfType:(NSString *)aType {
if ([@"RTFWithGraphics" compare: aType] == NSOrderedSame) {
return [textViewIn RTFDFromRange:NSMakeRange(0, [[textViewIn string] length])];
}else if ([@"RTF" compare: aType] == NSOrderedSame) {
return [textViewIn RTFFromRange:NSMakeRange(0, [[textViewIn string] length])];
}else {
return [[textViewIn string] dataUsingEncoding: NSUTF8StringEncoding];
}
}
// If we're loading from a file just retain the data and it will be
// loaded when windowControllerDidLoadNib is invoked. If not, go
// ahead and load the view with the data.
// These paths are separate in order to support Revert where the
// data is reloaded but the nib is not.
- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType {
if ([@"RTFWithGraphics" compare: aType] == NSOrderedSame) {
if (textViewIn)
[self loadtextViewWithData:data];
else
dataFromFile = [data retain];
}else if ([@"RTF" compare: aType] == NSOrderedSame) {
if (textViewIn)
[self loadtextViewWithRTFData:data];
else
rtfDataFromFile = [data retain];
}else{
if (textViewIn)
[self loadtextViewWithTextData: data];
else
textDataFromFile = [data retain];
}
return YES;
}
// =======================================================================
-(void) initAux {
static int serial;
MyEnvironment *myEnvironment;
myDocumentKey = [@"myDocumentNo" stringByAppendingString: [NSString stringWithFormat: @"%d",(++serial)]];
[myDocumentKey retain];
onlySelectedArea = 0;
notebookMode = 0; // or = 1; // experimental.
oxEngine = 0; // experimental. For select engine menu.
errorLines = [NSMutableArray arrayWithCapacity: 10]; [errorLines retain];
debugMyTunnel = 0;
task = nil;
myEnvironment = [[MyEnvironment alloc] init]; [myEnvironment retain];
myDefaultTypingAttributes = [myEnvironment getMyDefaultTypingAttributes];
[myDefaultTypingAttributes retain];
[textViewIn setTypingAttributes: myDefaultTypingAttributes];
myDecoder = [[MyDecoder alloc] init]; [myDecoder retain];
[self openMyModel: myEnvironment ];
[MyOpenGLController initMyOpenGLController]; // For the second execution, it will do nothing.
}
-(NSString *) getMyDocumentKey { return myDocumentKey; }
-(id) openMyModel: (MyEnvironment *) myEnvironment {
[myEnvironment showForDebug]; // for debug.
OpenXM_HOME= [myEnvironment getOpenXM_HOME];
[OpenXM_HOME retain]; // without these SIGSEGV
inputCounter = outputCounter = 0;
redirectPrint = 0;
peer = [myEnvironment getPeer];
peerStartupString = [myEnvironment getPeerStartupString];
[peerStartupString retain];
peerEndEvaluteMark = [myEnvironment getPeerEndEvaluateMark];
[peerEndEvaluteMark retain];
[self stopIndicator];
if (NoEngine && (!restartMode)) { task = nil; return self; }
// Initialization to call /bin/bash
outboundPipe = [NSPipe pipe]; // since autorelease is called in pipe.
inboundPipe = [NSPipe pipe];
errPipe = [NSPipe pipe];
[outboundPipe retain]; [inboundPipe retain]; [errPipe retain];
outboundFileHandle = [outboundPipe fileHandleForWriting];
inboundFileHandle = [inboundPipe fileHandleForReading];
errFileHandle = [errPipe fileHandleForReading];
NSLog(@"Starting /bin/bash\n");
task = [[NSTask alloc] init];
[task setStandardInput: outboundPipe];
[task setStandardOutput: inboundPipe];
[task setStandardError: errPipe];
[task setEnvironment: [myEnvironment getMyUnixEnvironment]];
//[task setArguments: [NSArray arrayWithObject: @"http://www.google.com"]];
//[task setLaunchPath: @"/usr/bin/open"];
//[task setLaunchPath: @"/Users/NobukiTakayama/OX4/OpenXM/bin/asir"];
//[task setLaunchPath: @"/bin/date"];
[task setLaunchPath: @"/bin/bash"];
// launch will be done after nib is loaded.
@try { // version >= 10.3, add option in info
[task launch];
} @catch (NSException *exception) {
NSLog(@"init task launch Caught %@: %@", [exception name], [exception reason]);
} @finally {
NSLog(@"/bin/bash is started.\n");
// fprintf(stderr,"pid = %d\n",[task processIdentifier]);
signal(SIGPIPE,SIG_IGN); //BUG. non-cocoa way.
[self oxEvaluateString: peerStartupString withMark: FALSE];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readInboundData:)
name:NSFileHandleDataAvailableNotification object: inboundFileHandle];
[inboundFileHandle waitForDataInBackgroundAndNotify];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readErrData:)
name:NSFileHandleDataAvailableNotification object: errFileHandle];
[errFileHandle waitForDataInBackgroundAndNotify];
return self;
}
- (void) closeMyModel {
[self stopIndicator];
if (task == nil) {
NSLog(@"closeMyModel. Task is not running.\n"); return ;
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSFileHandleDataAvailableNotification object: inboundFileHandle];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSFileHandleDataAvailableNotification object: errFileHandle];
[inboundFileHandle closeFile];
[outboundFileHandle closeFile];
[errFileHandle closeFile];
[task terminate];
task = nil; //BUG. memory leak?
NSLog(@"Terminated the child process.\n");
}
-(id) restartMyModel: (enum peer_type) peerType {
MyEnvironment *myEnvironment;
restartMode = 1;
[self closeMyModel];
myEnvironment = [[MyEnvironment alloc] initFor: peerType]; //BUG. leak memory?
[myEnvironment retain];
[myEnvironment showForDebug]; // for debug.
[self openMyModel: myEnvironment ];
return self;
}
// messenges
-(void) sayTheMessageAboutX {
NSLog(@"myDocumentSaidTheMessageAboutX=%d\n",myDocumentSaidTheMessageAboutX);
if (!myDocumentSaidTheMessageAboutX) {
// [[NSWorkspace sharedWorkspace] launchApplication: @"Console"]; // check if it works for apps in Utilities
if ([MyEnvironment checkX] != 1) {
// [self messageDialog:
// NSLocalizedString(@"A few commands (plot, ...) cannot be used, because X11 is not running.",nil) with: 0];
[self changeOutputCounterFieldWithString:
[NSLocalizedString(@"Output mini-view: ",nil) stringByAppendingString:
NSLocalizedString(@"Starting XQuartz(X11). Please wait.",nil)]];
if ([[NSWorkspace sharedWorkspace] launchApplication: @"XQuartz"]) {
NSLog(@"Starting XQuartz.\n");
}else{
NSLog(@"Starting XQuartz failed.\n");
[self messageDialog:
NSLocalizedString(@"Starting XQuartz(X11) failed. A few commands (plot, ...) cannot be used, because X11 is not running.",nil) with: 0];
}
while ([MyEnvironment checkX]!=1) {
sleep(1);
}
[self changeOutputCounterFieldWithString:
[NSLocalizedString(@"Output mini-view: ",nil) stringByAppendingString:
NSLocalizedString(@"Started XQuartz(X11)",nil)]];
}
myDocumentSaidTheMessageAboutX = 1;
}
}
- (IBAction) oxEvaluate:(id) sender {
NSString* cmd0;
NSMutableString *cmd;
NSRange r;
if (!task) return;
if (inEvaluation) {
NSLog(@"In evaluatioin. ");
[self messageDialog: NSLocalizedString(@"Evaluating...",nil) with: 0];
return;
}
if (notebookMode) doInsertNewInputCell=0;
else [[MyOutputWindowController sharedMyOutputWindowController: self] showUp];
ox_texmacs_level=0;
[self clearLines];
[textViewIn setTypingAttributes: myDefaultTypingAttributes];
if (notebookMode) {
cmd0 = [self getContentsOfInputCell];
[self prepareOutputCell];
}else if (onlySelectedArea) {
r = [textViewIn selectedRange];
// NSLog(@"r=(%d,%d)\n",r.location,r.length);
cmd0 = [textViewIn string];
if (r.length != 0) {
cmd0= [cmd0 substringWithRange: r];
}else{
int pos;
r = [cmd0 lineRangeForRange: r];
pos = r.location+r.length;
[textViewIn setSelectedRange: r]; // select the range containing the insertion point.
if (pos < [cmd0 length]) {
[textViewIn replaceCharactersInRange: NSMakeRange(pos+1,0) withString: @""];
}else{
[textViewIn replaceCharactersInRange: NSMakeRange(pos,0) withString: @"\n"];
}
cmd0 = [cmd0 substringWithRange:r ];
}
[self outputBorderLine: [NSColor magentaColor]];
[self outputString: cmd0];
if ([cmd0 length] > 0) {
if ([cmd0 characterAtIndex: ([cmd0 length]-1)] != 0xa) [self outputString: @"\n"];
}
[self outputBorderLine: [NSColor yellowColor]];
}else{
cmd0 = [textViewIn string];
MyOutputWindowController *mc;
mc = [MyOutputWindowController sharedMyOutputWindowController: self];
[mc clearOutputWindow];
}
cmd = [NSMutableString stringWithString: cmd0 ];
[self changeInputCounterField: 1];
if (peer == OX_TEXMACS) [self startIndicator];
[self oxEvaluateString: cmd withMark: TRUE];
[self changeOutputCounterField: 1];
}
- (IBAction) oxInterrupt:(id) sender {
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle: NSLocalizedString(@"OK",nil)];
[alert addButtonWithTitle: NSLocalizedString(@"Cancel",nil)];
[alert setMessageText: NSLocalizedString(@"Interrupt the ox server?",nil)];
[alert setInformativeText:NSLocalizedString(@"The OX-RFC-100 interruption protocol is used.",nil)];
[alert setAlertStyle:NSWarningAlertStyle];
if ([alert runModal] != NSAlertFirstButtonReturn) {
// Cancel clicked, return.
return;
}
[alert release];
fprintf(stderr,"Trying to interrupt.\n");
if (task) [task interrupt];
inputCounter = outputCounter = 0;
[self stopIndicator];
[myDecoder reset];
}
-(IBAction) oxRenderOutput: (id) sender {
[self messageDialog: @"oxRenderOutput has not been implemented." with: 0];
}
-(IBAction) oxEvaluateSelected: (id) sender {
// try or test something here
// end of try or test.
// fprintf(stderr,"OnlySelectedArea\n");
if (notebookMode && (onlySelectedArea == 0)) {
[self messageDialog: NSLocalizedString(@"Selection will be ignored in the notebook style.",nil) with: 0];
}
if (onlySelectedArea) onlySelectedArea = 0; else onlySelectedArea = 1;
}
-(IBAction) oxEvaluateRegisteredString: (id) sender {
int ans;
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle: NSLocalizedString(@"Cancel",nil)];
[alert addButtonWithTitle: NSLocalizedString(@"unix shell",nil)];
[alert addButtonWithTitle: NSLocalizedString(@"Risa/Asir",nil)];
[alert setMessageText: NSLocalizedString(@"Restart the computation server?",nil)];
//[alert setInformativeText:NSLocalizedString(@"",nil)];
[alert setAlertStyle:NSWarningAlertStyle];
ans = [alert runModal];
[alert release];
if (ans == NSAlertFirstButtonReturn) {
// Cancel clicked, return.
return ;
} else if (ans == NSAlertSecondButtonReturn) {
[self restartMyModel: BASH];
inputCounter = outputCounter = 0;
return ;
}else{
[self restartMyModel: OX_TEXMACS];
inputCounter = outputCounter = 0;
[myDecoder reset];
return;
}
}
-(IBAction) checkSelectedArea: (id) sender {
int ans;
ans = [self selectIllegalCharacter];
if (ans) return;
[self selectBlockForward];
}
-(int) oxEvaluateString: (NSString *) cmd withMark: (BOOL) yes {
NSData* cmdInData;
NSLog(@"Evaluating... ");
NSLog(@"%@",cmd);
// Evaluation is here.
if (!task) return -1;
cmdInData = [cmd dataUsingEncoding: NSUTF8StringEncoding];
@try {
//todo if (yes) [outboundFileHandle writeData: peerStartEvaluateMark];
[outboundFileHandle writeData: cmdInData];
if (yes) [outboundFileHandle writeData: peerEndEvaluteMark];
} @catch (NSException *exception) {
NSLog(@"oxEvalluateString Caught %@: %@", [exception name], [exception reason]);
[self messageDialog: NSLocalizedString(@"Error: Engine is not responding.",nil) with: 0];
return -1;
} @finally {
NSLog(@"writeData suceeded.\n");
}
// [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 10.0]];
NSLog(@"\nDone.\n");
return 0;
}
- (void) outputString: (NSString *) amt {
NSRange myRange = NSMakeRange([[textViewOut textStorage] length],0);
if (myDebug) NSLog(@"Get in outputString\n");
[textViewOut replaceCharactersInRange: myRange withString: amt];
[textViewOut scrollRangeToVisible: NSMakeRange([[textViewOut textStorage] length],0)];
//[textViewOut replaceCharactersInRange: NSMakeRange(0,NSMakeRange(0,[textViewOut length])) withString: amt];
if (notebookMode) [self outputStringInNotebookMode: amt];
else {
MyOutputWindowController *mc;
mc = [MyOutputWindowController sharedMyOutputWindowController: self];
if (prettyPrint) [mc outputStringToOutputWindow: amt withColor: [NSColor blueColor]];
else [mc outputStringToOutputWindow: amt];
}
}
-(void)outputBorderLine: (NSColor *)color {
MyOutputWindowController *mc;
mc = [MyOutputWindowController sharedMyOutputWindowController: self];
[mc outputStringToOutputWindow: @"----------------------------------------\n" withColor: color];
}
- (void) outputErrorString: (NSString *) amt {
int oldEnd;
int newEnd;
oldEnd = [[textViewOut textStorage] length];
NSRange myRange = NSMakeRange(oldEnd,0);
[textViewOut replaceCharactersInRange: myRange withString: amt];
newEnd = [[textViewOut textStorage] length];
[textViewOut setTextColor: [NSColor orangeColor] range: NSMakeRange(oldEnd,newEnd-oldEnd)];
[textViewOut scrollRangeToVisible: NSMakeRange(newEnd,0)];
}
- (void) printErrorMessage: (NSString *) amt {
MyOutputWindowController *mc;
if (notebookMode) [self outputErrorStringInNotebookMode: amt];
else {
mc = [MyOutputWindowController sharedMyOutputWindowController: self];
[mc printErrorMessageToOutputWindow: amt];
}
}
-(void)outputStringInNotebookMode: (NSString *)msg {
[self outputStringInNotebookMode: msg withColor: [NSColor blueColor]];
}
-(void)outputErrorStringInNotebookMode: (NSString *)msg {
[self outputStringInNotebookMode: msg withColor: [NSColor redColor]];
}
-(void)outputStringInNotebookMode: (NSString *)msg withColor: (NSColor *)color{
NSRange range;
int insertPos;
range=[textViewIn selectedRange];
insertPos = range.location+range.length;
range = NSMakeRange(insertPos,0);
[textViewIn replaceCharactersInRange: range withString: msg];
range = NSMakeRange(insertPos,[msg length]);
[textViewIn setTextColor: color range: range];
range=NSMakeRange(range.location+range.length,0);
[textViewIn scrollRangeToVisible: range];
[textViewIn setSelectedRange: range];
@synchronized(self) {
if (doInsertNewInputCell) {
if (![self getOutOfOutputCell]) [self insertInputCell];
doInsertNewInputCell = 0;
}
}
}
-(IBAction) clearTextViewOut: (id) sender {
NSRange myRange = NSMakeRange(0,[[textViewOut textStorage] length]);
[textViewOut replaceCharactersInRange: myRange withString: @""];
[textViewOut replaceCharactersInRange: NSMakeRange(0,0) withString: @" \n \n \n"];
[textViewOut scrollRangeToVisible: NSMakeRange(0,[[textViewOut textStorage] length])];
}
- (void) messageDialog: (NSString *)msg with: (int) no {
char s[256];
NSAlert *alert = [[NSAlert alloc] init];
sprintf(s,"%d",no);
[alert addButtonWithTitle: @"OK"];
[alert setMessageText: msg] ;
if (no) [alert setInformativeText: [NSString stringWithCString: (const char *) s]];
[alert setAlertStyle:NSWarningAlertStyle];
[alert runModal];
[alert release];
}
-(void) printDocument: (id) sender {
int status;
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:NSLocalizedString(@"Cancel",nil)];
[alert addButtonWithTitle:NSLocalizedString(@"Print output view",nil)];
[alert addButtonWithTitle:NSLocalizedString(@"Print input view",nil)];
[alert setMessageText:NSLocalizedString(@"Which view will you print?",nil)];
[alert setAlertStyle:NSWarningAlertStyle];
status = [alert runModal];
switch(status) {
case NSAlertThirdButtonReturn:
[textViewIn print: sender]; break;
case NSAlertSecondButtonReturn:
[textViewOut print: sender]; break;
default:
// Cancel clicked, return.
return;
}
[alert release];
}
-(void) showHelp: (id)sender {
BOOL ans;
NSString *path=nil;
//bug. temporary.
path = [OpenXM_HOME stringByAppendingString: @"/doc/cfep/intro-ja.html"];
ans = [[NSWorkspace sharedWorkspace] openFile:path withApplication: @"Safari"]; //We do not use Help Viewer
if (ans != YES) {
[self messageDialog: NSLocalizedString(@"Help file is not found at cfep.app/OpenXM/doc/cfep",nil) with: 0];
}
}
-(void) changeInputCounterField: (int) inc {
NSString *ss;
ss = [NSString stringWithFormat: NSLocalizedString(@"Input%d",nil), inputCounter];
[inputCounterField setStringValue: ss];
inputCounter += inc;
return;
}
-(void) changeOutputCounterField: (int) inc {
NSString *ss;
ss = [NSString stringWithFormat: NSLocalizedString(@"Out%d",nil),outputCounter];
[outputCounterField setStringValue: ss];
outputCounter += inc;
return;
}
-(void) changeOutputCounterFieldWithString: (NSString *) ss {
[outputCounterField setStringValue: ss];
return;
}
-(void) startIndicator {
if (inEvaluation) return ;
inEvaluation = 1;
[myIndicator startAnimation: self];
}
-(void) stopIndicator {
if (inEvaluation == 0) return ;
inEvaluation = 0;
[myIndicator stopAnimation: self];
}
int debugInbound = 0;
- (void)readInboundData:(NSNotification*)aNotification
{
static int state=0;
static int u0 = 0;
static int u1 = 0;
static int u2 = 0;
int n,i,j,k;
unsigned char *d;
unsigned char *d2;
int c;
NSMutableString* inboundString;
NSData* data;
NSMutableData* data2;
NSString *act;
int channel;
@synchronized (self) {
if (debugInbound) NSLog(@"Reading inboudData\n");
data=[ inboundFileHandle availableData ];
n = [data length]; d = (unsigned char *)[data bytes];
if (debugInbound) NSLog(@"n=%d\n",n);
// if (n < 30) { for (k=0; k<n; k++) printf("%2x ",d[k]); printf("\n"); }
if (n == 0) { NSLog(@"Broken pipe?\n"); [self messageDialog: @"Error: Engine is not responding." with: 0]; return ; }
data2 = [NSMutableData dataWithCapacity: (n+4)];
d2 = (unsigned char *)[data2 mutableBytes];
i = 0; d2[i] = 0;
for (j = 0; j< n; j++) {
c = d[j];
if (c == END_OF_EVALUATION_OF_OX_TEXMACS) {
[self stopIndicator];
ox_texmacs_level--;
if (ox_texmacs_level <= 0) doInsertNewInputCell = 1;
} else if (c == START_OF_RESULT_OF_OX_TEXMACS) {
ox_texmacs_level++;
}
switch(state) {
case 1:
u1 = d[j];
d2[i] = u0; i++; d2[i] = u1; i++; d2[i] = 0;
state = 0; break;
case 2:
u1 = d[j]; state = 3; break;
case 3:
u2 = d[j];
d2[i] = u0; i++; d2[i] = u1; i++; d2[i] = u2; i++ ; d2[i] = 0;
state = 0; break;
case 4: // MYDECODER
u1 = d[j]; state = 5; break;
case 5:
u2 = d[j];
c = ((u0 & 0x3) << 6) | (((u1 & 0x7) << 3) & 0x38) | (u2 & 0x7);
// NSLog(@"|%2x| ",c); // send it to myDecoder
act = [myDecoder myDecoder: c from: self];
if (act != nil) {
if (debugMyTunnel) [self outputErrorString: act]; // for debug.
channel = [myDecoder getChannel];
if (channel == 0) [self errorActionFor: act];
// cf. MyDecode.h for the list of channel numbers.
else if (channel == 1) [self openGLActionFor: act];
else if (channel == 2) [self openGLInitActionFor: act];
else if (channel == 10) [self pngActionFor: act];
}
state = 0; break;
default:
c=d[j];
if ((c >> 5) == UTF8_2) { u0=c ; state=1; }
else if ((c >> 4) == UTF8_3) { u0 =c ; state = 2; }
else if ((c >> 2) == MYDECODER) { u0=c; state = 4; }
else if ( c & 0x80) {
state = 0; NSLog(@"err|%2x| ",c);
}else {
if (c > 5) {
d2[i] = c; i++; d2[i] = 0; state = 0;
}
}
}
}
}
if (i) {
inboundString = [NSString stringWithCString: d2 encoding: NSUTF8StringEncoding];
[self outputString: inboundString]; // do this out of the synchronized session.
}
if (n) [[aNotification object] waitForDataInBackgroundAndNotify];
}
- (void)readErrData:(NSNotification*)aNotification
{
int n,i,j;
#define MD_SIZE 5000
unsigned char *d;
int c;
NSMutableString* inboundString;
NSData* inboundData ;
@synchronized (self) {
inboundString = [NSMutableString stringWithCapacity: (MD_SIZE+2)];
// NSLog(@"(err) Reading inboudData\n");
inboundData=[ errFileHandle availableData ];
n = [inboundData length]; d = (unsigned char *)[inboundData bytes];
i = 0;
while (i < n ) {
for (j = 0; j<MD_SIZE ; j++ ) {
c = d[i]; // putchar(c);
[inboundString appendString: [NSString stringWithFormat: @"%c", (c & 0x7f)] ];
i++; if (i >= n) { j++; break;}
}
// NSLog( [NSString stringWithFormat: @"i=%d, j=%d\n", i, j] );
j++;
// NSLog(@"%@", inboundString );
[self outputErrorString: inboundString];
inboundString = [NSMutableString stringWithCapacity: (MD_SIZE+2)] ;
}
}
if (n) [[aNotification object] waitForDataInBackgroundAndNotify];
}
-(int) specialCharacterInNotebookMode: (int) c {
if (!notebookMode) return 0;
if (c == BEGIN_INPUT_CELL) return 1;
else if (c==BEGIN_OUTPUT_CELL) return 1;
else if (c==END_INPUT_CELL) return 1;
else if (c==END_OUTPUT_CELL) return 1;
return 0;
}
-(int) selectIllegalCharacter {
NSRange r;
NSString *in;
int i, n;
int state,offset;
int c,c2;
// 1: in /*
// 2: in //
// 3: in "
// 4: in '
in = [textViewIn string];
r = [textViewIn selectedRange];
//NSLog(@"%d, %d\n",r.location, r.length);
if (r.length < 1) {
offset = 0;
n = [in length];
}else{
offset = r.location;
n = offset + r.length;
}
state = 0;
for (i=offset; i<n; i++) {
c = [in characterAtIndex: i]; // NSLog(@"|%04x| ",c);
if (i != n-1) c2 = [in characterAtIndex: (i+1)];
else c2 = 0;
switch (state) {
case 0:
if ((c == 0x1b)) {
[textViewIn setSelectedRange: NSMakeRange(i,1)];
[self outputErrorString:
NSLocalizedString(@"Error: Illegal control character.\n",nil)];
return 1;
}
if ((c > 0x7e) && (![self specialCharacterInNotebookMode: c])) {
[textViewIn setSelectedRange: NSMakeRange(i,1)];
[self outputErrorString:
NSLocalizedString(@"Error: Program part must be written only by ascii characters.\n",nil)];
return 1;
}
if (((c == '/') && (c2 == '*')) || (notebookMode && (c == BEGIN_OUTPUT_CELL))) {
i++; state = 1;
}else if ((c == '/') && (c2 == '/')) {
i++; state = 2;
}else if (c == '"') {
state = 3;
}else if (c == '\'') {
state = 4;
}else state=0;
break;
case 1:
if (((c == '*') && (c2 == '/')) || (notebookMode && (c2 == END_OUTPUT_CELL))) {
i++; state = 0;
}
break;
case 2:
if (c == '\n') state = 0;
break;
case 3:
if (c == '"') state = 0;
else if (c == '\\') {
i++; //BUG. skip only one letter.
}
break;
case 4:
if (c == '\'') state = 0;
else if (c == '\\') {
i++; //BUG. skip only one letter.
}
break;
}
}
// [self outputErrorString: @"No illegal character.\n"];
return 0;
}
-(NSRange) selectBlockForward {
NSRange r;
NSRange ans;
NSString *in;
int i, n;
int first, last,offset, state;
int c,c2;
static int prevStart = -1;
first = last = 0;
ans = NSMakeRange(0,0);
// 1: in /*
// 2: in //
// 3: in "
// 4: in '
in = [textViewIn string];
r = [textViewIn selectedRange];
if (r.length < 1) {
offset = 0;
} else {
offset = r.location;
}
if (offset == prevStart) {
offset = offset+1;
}
n = [in length];
if (offset >= n) offset = 0;
state = 0;
for (i=offset; i<n; i++) {
c = [in characterAtIndex: i];
if (i != n-1) c2 = [in characterAtIndex: (i+1)];
else c2 = 0;
switch (state) {
case 0:
if (c == '{') {
ans=[self selectBlockForwardFrom: i with: c and: '}'];
if (prevStart != ans.location) { prevStart = ans.location; }
return ans;
}else if (c == '(') {
ans=[self selectBlockForwardFrom: i with: c and: ')'];
if (prevStart != ans.location) { prevStart = ans.location; }
return ans;
}else if (c == '[') {
ans=[self selectBlockForwardFrom: i with: c and: ']'];
if (prevStart != ans.location) { prevStart = ans.location; }
return ans;
}
if ((c == '/') && (c2 == '*')) {
i++; state = 1;
}else if ((c == '/') && (c2 == '/')) {
i++; state = 2;
}else if (c == '"') {
state = 3;
}else if (c == '\'') {
state = 4;
}else state=0;
break;
case 1:
if ((c == '*') && (c2 == '/')) {
i++; state = 0;
}
break;
case 2:
if (c == '\n') state = 0;
break;
case 3:
if (c == '"') state = 0;
else if (c == '\\') {
i++; //BUG. skip only one letter.
}
break;
case 4:
if (c == '\'') state = 0;
else if (c == '\\') {
i++; //BUG. skip only one letter.
}
break;
}
}
return ans;
}
-(NSRange) selectBlockForwardFrom: (int) offset with: (int) first and: (int) last {
NSRange r;
NSRange ans;
NSString *in;
int i, n;
int state;
int c,c2;
int level;
int startpos;
level = 0;
ans = NSMakeRange(0,0);
// 1: in /*
// 2: in //
// 3: in "
// 4: in '
in = [textViewIn string];
r = [textViewIn selectedRange];
n = [in length];
state = 0;
for (i=offset; i<n; i++) {
c = [in characterAtIndex: i];
if (i != n-1) c2 = [in characterAtIndex: (i+1)];
else c2 = 0;
switch (state) {
case 0:
if (level == 0) {
if (c == first) {
level = 1; startpos = i;
}
} else if (level > 0) {
if (c == first) level++;
else if (c == last) level--;
else ;
if (level == 0) {
ans = NSMakeRange(startpos, i+1-startpos);
[textViewIn setSelectedRange: ans];
[textViewIn scrollRangeToVisible: NSMakeRange(startpos,0)];
return ans;
}
}
if ((c == '/') && (c2 == '*')) {
i++; state = 1;
}else if ((c == '/') && (c2 == '/')) {
i++; state = 2;
}else if (c == '"') {
state = 3;
}else if (c == '\'') {
state = 4;
}else state=0;
break;
case 1:
if ((c == '*') && (c2 == '/')) {
i++; state = 0;
}
break;
case 2:
if (c == '\n') state = 0;
break;
case 3:
if (c == '"') state = 0;
else if (c == '\\') {
i++; //BUG. skip only one letter.
}
break;
case 4:
if (c == '\'') state = 0;
else if (c == '\\') {
i++; //BUG. skip only one letter.
}
break;
}
}
if (level > 0) {
[self outputErrorString: NSLocalizedString(@"Error: No right parenthesis.\n",nil)] ;
[textViewIn setSelectedRange: NSMakeRange(startpos,n-startpos)];
ans = NSMakeRange(startpos,-1);
return ans;
}
return ans;
}
-(void) errorActionFor: (NSString *)cmd
{
NSArray *a;
NSRange r;
static NSRange r2;
static NSRange r3;
static int r2IsSet;
static int r3IsSet;
NSString *s;
int line,i, currentLine;
// NSLog(@"cmd=%@\n",cmd);
if ([cmd hasPrefix: @"Begin"] == YES) {
r3IsSet = 0; r2IsSet = 0;
}else if ([cmd hasPrefix: @"End"] == YES) {
if (r2IsSet) {
[textViewIn setSelectedRange: r2];
[textViewIn scrollRangeToVisible: r2];
r2IsSet = 0;
}
if (r3IsSet) { //gotoLine, xyz is stronger than findAndSelect.
[textViewIn setSelectedRange: r3];
[textViewIn scrollRangeToVisible: r3];
r3IsSet = 0;
}
}else if ([cmd hasPrefix: @"findAndSelect"] == YES) {
a = [cmd componentsSeparatedByString: @", "];
if ([a count] > 1) {
a = [[a objectAtIndex: 1] componentsSeparatedByString: @"\n"];
s = [a objectAtIndex: 0];
r2 = [[textViewIn string] rangeOfString: s];
r2IsSet = 1;
// selection will be done in End.
[self printErrorMessage: [NSLocalizedString(@"Error in executing ",nil) stringByAppendingString: s]];
[self printErrorMessage: @"\n"];
}
}else if ([cmd hasPrefix: @"findAndShow"] == YES) {
a = [cmd componentsSeparatedByString: @", "];
if ([a count] > 1) {
a = [[a objectAtIndex: 1] componentsSeparatedByString: @"\n"];
s = [a objectAtIndex: 0];
[self printErrorMessage: [NSLocalizedString(@"Error in executing ",nil) stringByAppendingString: s]];
[self printErrorMessage: @"\n"];
}
}else if ([cmd hasPrefix: @"printErrorMessage"] == YES) {
a = [cmd componentsSeparatedByString: @"ErrorMessage, "];
if ([a count] > 1) {
s = [a objectAtIndex: 1];
[self printErrorMessage: [NSLocalizedString(@"Error: ",nil) stringByAppendingString: s]];
[self printErrorMessage: @"\n"];
}
}else if ([cmd hasPrefix: @"gotoLine"] == YES) {
a = [cmd componentsSeparatedByString: @"Line, "];
if ([a count] > 1) {
s = [a objectAtIndex: 1];
[self printErrorMessage: [NSLocalizedString(@"Error at ",nil) stringByAppendingString: s]];
[self printErrorMessage: @"\n"];
line = [s intValue];
[self addLine: line];
// move the selection to the line.
i = [self gotoLine: line];
if (i >= 0) {
r3 = NSMakeRange(i,0); // NSLog(@"Goto the location=%d\n",i);
r3IsSet = 1;
}
}
}
}
-(void) clearLines {
[errorLines removeAllObjects];
[self nextLine: -1];
}
-(void) addLine: (int) n {
[errorLines addObject: [NSNumber numberWithInt: n]];
}
-(int) nextLine: (int) n {
static int p = 0;
int v;
if (n < 0) { p = 0; return -1; }
if (p < [errorLines count]) ; else { p = 0; return -1;}
v = [[errorLines objectAtIndex: p] intValue];
p++;
return v;
}
-(int) gotoLine: (int) line {
NSString *s;
NSRange r;
NSRange r3;
int currentLine,i;
[self outputErrorString: NSLocalizedString(@"Move to the line ",nil)];
[self outputErrorString: [NSString stringWithFormat: @"%d\n",line]];
// move the selection to the line line.
s = [textViewIn string];
if (onlySelectedArea || notebookMode) r = [textViewIn selectedRange];
else r = NSMakeRange(0,[s length]);
// NSLog(@"r.location=%d",r.location);
currentLine = 1;
for (i=r.location; i< r.location+r.length; i++) {
if (currentLine == line) {
r3 = NSMakeRange(i,0); // NSLog(@"Goto the location=%d\n",i);
[textViewIn setSelectedRange: r3 ];
[textViewIn scrollRangeToVisible: r3];
return i; // set r3IsSet
break;
}
if ([s characterAtIndex: i] == '\n') ++currentLine;
}
return -1;
}
-(int) gotoNextError: (id) sender{
int n;
if (onlySelectedArea || notebookMode)
[self outputErrorString: NSLocalizedString(@"The next error action will not work properly in this mode.\n",nil)];
n = [self nextLine: 0];
if (n >= 0) { [self gotoLine: n]; return n;}
else return -1;
}
/* act= 0;[glRectf,-0.5, ...] */
-(int) openGLActionFor: (NSString *)act {
NSArray *a;
int gid;
a=[act componentsSeparatedByString: @";"];
if ([a count] < 2) {
[self printErrorMessage: @"Invalid format in openGLActionFor. gid and command must be separated by ;\n"];
return -1;
}
gid = [[a objectAtIndex: 0] intValue];
if ([[a objectAtIndex: 1] hasPrefix: @"meta"]) {[self openGLMeta: [a objectAtIndex: 1] to: gid]; return 0; }
[MyOpenGLController addOglComm: [a objectAtIndex: 1] to: gid from: self];
return 0;
}
-(int) openGLInitActionFor: (NSString *) act {
NSArray *a;
int gid;
a=[act componentsSeparatedByString: @";"];
if ([a count] < 2) {
[self printErrorMessage: @"Invalid format in openGLInitActionFor. gid and command must be separated by ;\n"];
return -1;
}
gid = [[a objectAtIndex: 0] intValue];
[MyOpenGLController addOglInitComm: [a objectAtIndex: 1] to: gid from: self];
return 0;
}
-(void)openGLMeta: (NSString *) cmd to: (int) gid{
MyOpenGLController *oglc;
oglc = [MyOpenGLController getOglWindow: gid];
if (!oglc) {[self printErrorMessage:
[NSString stringWithFormat: @"Invalid gid %d in openGLMeta command %@\n",gid,cmd]]; return; }
if ([cmd hasPrefix: @"meta_showListOfOglComm"]) {
[self showListOfOglComm: gid]; return ;
}else if ([cmd hasPrefix: @"meta_removeAllInit"]) { // longer command must come first, because we use prefix.
[oglc removeAllOfOglInitComm];
}else if ([cmd hasPrefix: @"meta_removeLastInit"]) {
[oglc removeLastOfOglInitComm];
}else if ([cmd hasPrefix: @"meta_removeAll"]) {
[oglc removeAllOfOglComm];
}else if ([cmd hasPrefix: @"meta_removeLast"]) {
[oglc removeLastOfOglComm];
}else{
[self printErrorMessage: [NSString stringWithFormat: @"Unknown OpenGL meta command %@\n",cmd]];
}
}
-(void) showListOfOglComm: (int) gid {
MyDocument *md;
MyOpenGLController *oglc;
NSMutableArray *comm;
int i,n;
md = self;
oglc = [MyOpenGLController getOglWindow: gid];
if (!oglc) {[self outputErrorString: @"Invalid gid in showListOfOglComm\n"]; return; }
comm = [oglc getListOfOglInitComm];
n = [comm count];
[md outputString: NSLocalizedString(@"OpenGL init commands\n",nil)];
for (i=0; i<n; i++) {
[md outputString: [NSString stringWithFormat: @"%04d: ",i]];
[md outputString: [[comm objectAtIndex: i] toString]];
[md outputString: @"\n"];
}
comm = [oglc getListOfOglComm];
n = [comm count];
[md outputString: NSLocalizedString(@"OpenGL redraw commands\n",nil)];
for (i=0; i<n; i++) {
[md outputString: [NSString stringWithFormat: @"%04d: ",i]];
[md outputString: [[comm objectAtIndex: i] toString]];
[md outputString: @"\n"];
}
}
-(void) pngActionFor: (NSString *)act {
NSArray *a;
id typesetExpression;
MyOutputWindowController *mowc;
NSString *path;
int n;
a=[act componentsSeparatedByString: @","];
n = [a count];
if (n < 1) {
[self printErrorMessage: @"Invalid format in pngActionFor: \n"];
return;
}
// NSLog(@"%@",a);
if ([[a objectAtIndex: 0] hasPrefix: @"notAvailable"]) {
[self messageDialog:
NSLocalizedString(@"Typeset the output by TeX is not available. latex and dvipng must be installed.",nil) with: 0];
prettyPrint = 1; [self setPrettyPrint: nil];
return;
} else if ([[a objectAtIndex: 0] compare: @"showFile"] == NSOrderedSame) {
if (n < 2) [self printErrorMessage: @"showFile,filename filename is missing.\n"];
path = [MyUtil pruneThings: [a objectAtIndex: 1]]; // for buggy componentsSeparatedByString
typesetExpression = [MyUtil attributedStringWithPath: path];
if (typesetExpression) {
if (notebookMode) [textViewIn insertText: typesetExpression];
else {
mowc = [MyOutputWindowController sharedMyOutputWindowController: self];
[mowc insertText: typesetExpression];
}
}
return;
} else {
NSLog(@"pngActionFor: %@\n",act);
[self printErrorMessage: @"Unknown command for pngActionFor:\n"];
}
}
-(void) setBasicStyle: (id) sender {
notebookMode = 0;
[self updateInterfaceStyleMenu];
}
-(void) setNotebookStyle: (id) sender {
notebookMode = 1;
[self updateInterfaceStyleMenu];
[self insertInputCell];
}
-(void) updateInterfaceStyleMenu {
if (!menuItemNotebookMode) return;
if (!menuItemBasicMode) return;
if (notebookMode) {
[menuItemNotebookMode setState: NSOnState];
[menuItemBasicMode setState: NSOffState];
}else {
[menuItemNotebookMode setState: NSOffState];
[menuItemBasicMode setState: NSOnState];
}
}
-(void) setEngineRisaAsir: (id) sender {
oxEngine = 0;
[self updateSelectEngineMenu];
[self oxEvaluateString: @"!asir;" withMark: TRUE];
}
-(void) setEngineKanSm1: (id) sender {
oxEngine = 1;
[self updateSelectEngineMenu];
[self oxEvaluateString: @"!sm1;" withMark: TRUE];
}
// BUG: update* must be called when the focus is changed to "setState:"
-(void) updateSelectEngineMenu {
if (!menuItemRisaAsir) return;
if (!menuItemKanSm1) return;
if (oxEngine == 0) {
[menuItemRisaAsir setState: NSOnState];
[menuItemKanSm1 setState: NSOffState];
}else if (oxEngine == 1) {
[menuItemRisaAsir setState: NSOffState];
[menuItemKanSm1 setState: NSOnState];
}
}
-(void) setDebugMyTunnel: (id) sender {
if (debugMyTunnel) {
debugMyTunnel = 0;
if (menuItemOutputDebugMessages) [menuItemOutputDebugMessages setState: NSOffState];
} else {
debugMyTunnel = 1;
if (menuItemOutputDebugMessages) [menuItemOutputDebugMessages setState: NSOnState];
}
[MyUtil setDebugMyUtil];
}
//BUG: [self setPrettyPrint: nil] or update must be called when focus is changed to "setState:"
-(void) setPrettyPrint: (id) sender {
if (prettyPrint) {
prettyPrint = 0;
[self oxEvaluateString: @"!verbatim;" withMark: TRUE];
if (menuItemPrettyPrint) [menuItemPrettyPrint setState: NSOffState];
} else {
prettyPrint = 1;
if (!asir_contrib) [self loadAsirContrib: nil];
[self oxEvaluateString: @"!cfep_png;" withMark: TRUE];
if (menuItemPrettyPrint) [menuItemPrettyPrint setState: NSOnState];
}
}
-(void) setNoEngine: (id) sender {
if (NoEngine) {
NoEngine = 0;
if (menuItemNoEngine) [menuItemNoEngine setState: NSOffState];
} else {
NoEngine = 1;
if (menuItemNoEngine) [menuItemNoEngine setState: NSOnState];
}
}
-(void) loadAsirContrib: (id) sender {
NSString *com;
if (inEvaluation) {
[self messageDialog: NSLocalizedString(@"Evaluating...",nil) with: 0];
return;
}
asir_contrib = 1;
com = [@"load(\"" stringByAppendingString: OpenXM_HOME];
com = [com stringByAppendingString: @"/rc/asirrc\")$"];
if (notebookMode) { doInsertNewInputCell=0; [self getContentsOfInputCell]; [self prepareOutputCell];}
[self oxEvaluateString: com withMark: TRUE];
}
-(void) mytest: (id) sender {
// Add any code here for testing.
id typesetExpression;
typesetExpression = [MyUtil attributedStringWithPath: @"/Users/nobuki/OpenXM_tmp/1/work1.png"];
if (typesetExpression) [textViewIn insertText: typesetExpression];
else NSLog(@"typesetExpression is nil.\n");
}
-(NSMenuItem *) menuItemLoadLibrary: (int) oxengine {
NSMenuItem *menuItemAsirContrib;
NSMenuItem *menuItemCohom;
NSMenu *submenuLoadLibrary = [[[NSMenu alloc] init] autorelease];
switch(oxengine) {
case 0: /* asir */
menuItemAsirContrib = [[[NSMenuItem alloc] init] autorelease];
[menuItemAsirContrib setTitle: NSLocalizedString(@"Load asir-contrib",nil)];
[menuItemAsirContrib setAction: @selector(loadAsirContrib:)];
[menuItemAsirContrib setTarget: [[NSApp mainWindow] document]];
[submenuLoadLibrary addItem: menuItemAsirContrib];
break;
case 1: /* sm1 */
menuItemCohom = [[[NSMenuItem alloc] init] autorelease];
[menuItemCohom setTitle: NSLocalizedString(@"Load cohom.sm1",nil)];
[menuItemCohom setAction: @selector(loadCohom:)];
[menuItemCohom setTarget: [[NSApp mainWindow] document]];
[submenuLoadLibrary addItem: menuItemCohom];
break;
default:
break;
}
NSMenuItem *menuItemLoadLibrary = [[[NSMenuItem alloc] init] autorelease];
[menuItemLoadLibrary setTitle: NSLocalizedString(@"Load library",nil)];
[menuItemLoadLibrary setSubmenu: submenuLoadLibrary];
return menuItemLoadLibrary;
}
-(void) addMenuExec {
static int done=0;
NSMenu *menuItem;
NSMenu *menuExec;
NSMenuItem *menuItemEvaluate;
NSMenuItem *menuItemInterrupt;
NSMenuItem *menuItemInterfaceStyle;
NSMenuItem *menuItemSelectEngine;
NSMenuItem *menuItemGotoNextError;
NSMenuItem *menuItemForTest;
NSMenuItem *menuItemLoadLibrary;
if (done) return;
done = 1;
// oxEvalute
menuExec = [[[NSMenu alloc] init] autorelease];
[menuExec setTitle: NSLocalizedString(@"Execution",nil)];
menuItemEvaluate = [[[NSMenuItem alloc] init] autorelease];
[menuItemEvaluate setTitle: NSLocalizedString(@"Evaluate",nil)];
[menuItemEvaluate setAction: @selector(oxEvaluate:)];
[menuItemEvaluate setTarget: [[NSApp mainWindow] document]];
[menuItemEvaluate setKeyEquivalentModifierMask: NSCommandKeyMask];
[menuItemEvaluate setKeyEquivalent: @"\n"];
[menuExec addItem: menuItemEvaluate];
// oxInterrupt
menuItemInterrupt = [[[NSMenuItem alloc] init] autorelease];
[menuItemInterrupt setTitle: NSLocalizedString(@"Interrupt",nil)];
[menuItemInterrupt setAction: @selector(oxInterrupt:)];
[menuItemInterrupt setTarget: [[NSApp mainWindow] document]]; // do not use self.
[menuExec addItem: menuItemInterrupt];
// gotoNextError
menuItemGotoNextError = [[[NSMenuItem alloc] init] autorelease];
[menuItemGotoNextError setTitle: NSLocalizedString(@"Next error line",nil)];
[menuItemGotoNextError setAction: @selector(gotoNextError:)];
[menuItemGotoNextError setTarget: [[NSApp mainWindow] document]];
[menuExec addItem: menuItemGotoNextError];
// pretty print
menuItemPrettyPrint = [[[NSMenuItem alloc] init] autorelease]; [menuItemPrettyPrint retain]; // it is the static variable.
[menuItemPrettyPrint setTitle: NSLocalizedString(@"Typeset the output by TeX",nil)];
[menuItemPrettyPrint setAction: @selector(setPrettyPrint:)];
[menuItemPrettyPrint setTarget: [[NSApp mainWindow] document]];
[menuExec addItem: menuItemPrettyPrint];
// loadLibrary
[menuExec addItem: [self menuItemLoadLibrary: oxEngine]]; //bug. dynamic change.
// interface style
NSMenu *submenuInterfaceItem = [[[NSMenu alloc] init] autorelease];
// basic-like
NSMenuItem *menuItemBasicLike = [[[NSMenuItem alloc] init] autorelease];
[menuItemBasicLike setTitle: NSLocalizedString(@"BASIC-like",nil)];
[menuItemBasicLike setAction: @selector(setBasicStyle:)];
[menuItemBasicLike setTarget: [[NSApp mainWindow] document]];
menuItemBasicMode = menuItemBasicLike; [menuItemBasicMode retain];
[submenuInterfaceItem addItem: menuItemBasicLike];
// notebook-like
NSMenuItem *menuItemNotebookLike = [[[NSMenuItem alloc] init] autorelease];
[menuItemNotebookLike setTitle: NSLocalizedString(@"Notebook-like",nil)];
[menuItemNotebookLike setAction: @selector(setNotebookStyle:)];
[menuItemNotebookLike setTarget: [[NSApp mainWindow] document]];
menuItemNotebookMode = menuItemNotebookLike; [menuItemNotebookMode retain];
[submenuInterfaceItem addItem: menuItemNotebookLike];
menuItemInterfaceStyle = [[[NSMenuItem alloc] init] autorelease];
[menuItemInterfaceStyle setTitle: NSLocalizedString(@"Interface style",nil)];
[menuItemInterfaceStyle setSubmenu: submenuInterfaceItem];
[menuExec addItem: menuItemInterfaceStyle];
[self updateInterfaceStyleMenu];
// select engine
NSMenu *submenuSelectEngineItem = [[[NSMenu alloc] init] autorelease];
// asir
menuItemRisaAsir = [[[NSMenuItem alloc] init] autorelease]; [menuItemRisaAsir retain];
[menuItemRisaAsir setTitle: NSLocalizedString(@"Risa/Asir",nil)];
[menuItemRisaAsir setAction: @selector(setEngineRisaAsir:)];
[menuItemRisaAsir setTarget: [[NSApp mainWindow] document]];
[submenuSelectEngineItem addItem: menuItemRisaAsir];
// notebook-like
menuItemKanSm1 = [[[NSMenuItem alloc] init] autorelease]; [menuItemKanSm1 retain];
[menuItemKanSm1 setTitle: NSLocalizedString(@"Kan/sm1",nil)];
[menuItemKanSm1 setAction: @selector(setEngineKanSm1:)];
[menuItemKanSm1 setTarget: [[NSApp mainWindow] document]];
[submenuSelectEngineItem addItem: menuItemKanSm1];
menuItemSelectEngine = [[[NSMenuItem alloc] init] autorelease];
[menuItemSelectEngine setTitle: NSLocalizedString(@"Select engine",nil)];
[menuItemSelectEngine setSubmenu: submenuSelectEngineItem];
[menuExec addItem: menuItemSelectEngine];
[self updateSelectEngineMenu];
// outputDebugMessage
menuItemOutputDebugMessages = [[[NSMenuItem alloc] init] autorelease]; [menuItemOutputDebugMessages retain];
[menuItemOutputDebugMessages setTitle: NSLocalizedString(@"Output debug messages",nil)];
[menuItemOutputDebugMessages setAction: @selector(setDebugMyTunnel:)];
[menuItemOutputDebugMessages setTarget: [[NSApp mainWindow] document]];
[menuExec addItem: menuItemOutputDebugMessages];
// NoEngine
menuItemNoEngine = [[[NSMenuItem alloc] init] autorelease]; [menuItemNoEngine retain]; // it is the static variable.
[menuItemNoEngine setTitle: NSLocalizedString(@"Do not start engine at startup",nil)];
[menuItemNoEngine setAction: @selector(setNoEngine:)];
[menuItemNoEngine setTarget: [[NSApp mainWindow] document]];
[menuExec addItem: menuItemNoEngine];
// test
menuItemForTest = [[[NSMenuItem alloc] init] autorelease];
[menuItemForTest setTitle: NSLocalizedString(@"For test",nil)];
[menuItemForTest setAction: @selector(mytest:)];
[menuItemForTest setTarget: [[NSApp mainWindow] document]];
[menuExec addItem: menuItemForTest];
menuItem = [[[NSMenuItem alloc] init] autorelease];
[[NSApp mainMenu] insertItem: menuItem atIndex: 4];
[menuItem setSubmenu: menuExec];
}
-(void) insertInputCell {
NSRange r;
NSString *ic;
unichar uu[2];
uu[0] = BEGIN_INPUT_CELL; uu[1] = END_INPUT_CELL;
r = [textViewIn selectedRange]; r.length=0;
ic = [NSString stringWithCharacters: uu length: 2];
// NSLog(@"insertInputCell: r.location=%d, r.length=%d, %@\n",r.location,r.length,ic);
[textViewIn replaceCharactersInRange: r withString: ic];
r.location = r.location+1; r.length = 0;
[textViewIn setSelectedRange: r ];
r.location = r.location-1; r.length = 2;
[textViewIn setTextColor: [NSColor blackColor] range: r];
}
-(NSString *) getContentsOfInputCell {
int start,end,i,n;
NSString *cmd0;
NSRange r;
cmd0 = [textViewIn string];
start=0; end = n = [cmd0 length]; if (end > 0) end--;
r = [textViewIn selectedRange];
if (r.location < n) i = r.location; else i = n-1;
if (i < 0) i=0;
for (; i>=0; i--) {
if ([cmd0 characterAtIndex: i] == BEGIN_INPUT_CELL) {
start = i+1; break;
}
}
for (i=start; i<n; i++) {
if ([cmd0 characterAtIndex: i] == END_INPUT_CELL) {
end = i-1; break;
}
}
// NSLog(@"start=%d, end=%d\n",start,end);
r.location = start; r.length = end-start+1;
if (r.length > 0) {
cmd0= [cmd0 substringWithRange: r];
}else{
cmd0 = @"";
}
if (end+2 <= n) r.location=end+2;
r.length = 0;
[textViewIn setSelectedRange: r];
return cmd0;
}
// return 1 if there is the next inputCell
-(int) getOutOfOutputCell {
int start,end,i,n;
NSString *cmd0;
NSRange r;
cmd0 = [textViewIn string];
n = [cmd0 length];
r = [textViewIn selectedRange];
start = r.location;
// NSLog(@"r.location=%d, r.length=%d\n",r.location,r.length);
if (r.location < n) i = r.location; else i = n-1;
if (i>0) i--;
for (; i<n; i++) {
if ([cmd0 characterAtIndex: i] == END_OUTPUT_CELL) {
start = i+1; break;
}else if ([cmd0 characterAtIndex: i] == BEGIN_INPUT_CELL) {
r.location = i+1; r.length=0;
[textViewIn setSelectedRange: r]; [textViewIn scrollRangeToVisible: r];
return 1;
}else if ([cmd0 characterAtIndex: i] == END_INPUT_CELL) {
r.location = i-1; r.length=0;
[textViewIn setSelectedRange: r]; [textViewIn scrollRangeToVisible: r];
return 1;
}
}
r.location = start; r.length = 0;
[textViewIn setSelectedRange: r];
for (i = start; i<n; i++) {
// Try to find the next input cell.
if ([cmd0 characterAtIndex: i] == BEGIN_INPUT_CELL) {
r.location = i+1; r.length = 0;
[textViewIn setSelectedRange: r]; [textViewIn scrollRangeToVisible: r];
return 1;
}else if ([cmd0 characterAtIndex: i] == END_INPUT_CELL) {
// We are inside an input cell.
r.location = i-1; r.length = 0;
[textViewIn setSelectedRange: r]; [textViewIn scrollRangeToVisible: r];
return 1;
}
}
return 0;
}
-(void) prepareOutputCell {
int start,end,i,j,n,m;
NSString *cmd0;
NSString *ic;
unichar uu[7];
NSRange r;
start = -1; end = -1;
cmd0 = [textViewIn string];
n = [cmd0 length];
r = [textViewIn selectedRange];
i = r.location;
if (i < 0) i = 0;
if (i >= n) i = n-1;
for (; i<n; i++) {
if ([cmd0 characterAtIndex: i] == BEGIN_OUTPUT_CELL) {
start = i;
for (j=i; j>=0; j--) {
if ([cmd0 characterAtIndex: j] <= ' ') {
start = j;
} else {
if (start>0) start--;
break;
}
}
break;
}else if ([cmd0 characterAtIndex: i] == BEGIN_INPUT_CELL) {
start = i-1;
if (start < 0) start = 0;
end = -2;
break;
}
}
if (end == -2) {
r.location = start; r.length=0;
}else{
end = start;
i = start; if (i < 0) i = 0;
for (; i<n; i++) {
if ([cmd0 characterAtIndex: i] == END_OUTPUT_CELL) {
end = i; break;
}
}
if ((start == -1) || (end == -1)) {
r.location = n; r.length=0;
}else{
r.location = start; r.length = end-start+1;
}
}
[textViewIn replaceCharactersInRange: r withString: @""];
uu[0] = '\n';
uu[1] = BEGIN_OUTPUT_CELL; uu[2] = END_OUTPUT_CELL;
m = 3;
// If there is no next input cell, add a new one.
for (i=r.location; i<n; i++) {
if ([cmd0 characterAtIndex:i] == BEGIN_INPUT_CELL) {
break;
}
}
if ((i == n) || (r.location >= n)) {
uu[3] = '\n'; uu[4] = BEGIN_INPUT_CELL; uu[5] = END_INPUT_CELL; m=6;
}
// NSLog(@"prepareOutputCell start=%d, length=%d, m=%d\n",start,r.length,m);
r.length = 0;
ic = [NSString stringWithCharacters: uu length: m];
[textViewIn replaceCharactersInRange: r withString: ic];
r.location = r.location+2; r.length = 0;
[textViewIn setSelectedRange: r ];
}
@end