[BACK]Return to MyDocument.m CVS log [TXT][DIR] Up to [local] / OpenXM / src / cfep

Annotation of OpenXM/src/cfep/MyDocument.m, Revision 1.13

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>