This is ExecScrollText.m in view mode; [Download] [Up]
// ------------------------------------------------------------------------------------- // ExecScrollText.m // (Indent:4, Tabs:4) // ------------------------------------------------------------------------------------- // Copyright 1996 Persistent Technologies, Inc. - all rights reserved // ------------------------------------------------------------------------------------- // This source code comes with no warranty of any kind, and the user assumes all // responsibility for its use. // ------------------------------------------------------------------------------------- #import <appkit/appkit.h> #import <libc.h> #import <mach/cthreads.h> #import <stdlib.h> #import <stdarg.h> #import <string.h> #import <pwd.h> #import <sys/types.h> #import <sys/wait.h> #import "ExecScrollText.h" // ------------------------------------------------------------------------------------- // null text attribute structure static NXColor nullColor = { 0 }; static textAttr_t nullAttr = { (id)nil, 0 }; #define isNullAttr(X) (!X.fontId && !X.colorMode) // ------------------------------------------------------------------------------------- // Object notified when command completes /* ExecScrollText delegate */ @interface Object(ExecScrollText_Delegate) - (void)monitorOutput:scrollId buffer:(const char*)buffer len:(int)len; @end // ------------------------------------------------------------------------------------- // ExecScrollText private methods @interface ExecScrollText(Private) - _setTextAttrFont:fontId color:(int)mode:(NXColor)color; - (BOOL)_appendTextToView:(const char*)buffer len:(int)len attr:(textAttr_t)tAttr; - _appendTextAndMakeVisible:(const char*)buffer attr:(textAttr_t)tAttr; @end // ------------------------------------------------------------------------------------- /* convert color to gray */ static float cvtColor2Gray(NXColor color) { float gray; NXConvertColorToGray(color, &gray); return gray; } // ------------------------------------------------------------------------------------- @implementation ExecScrollText // ------------------------------------------------------------------------------------- /* init */ - initExecScrollText:(id)anObject { [super init]; scrollView = anObject; textView = [scrollView docView]; wasEditable = [textView isEditable]; autoLf = NO; runAttr = nullAttr; //[textView setEditable:NO]; //[textView setMonoFont:NO]; return self; } /* initializes the outlet (to be executed by main thread only!) */ + newExecScrollText:(id)anObject { return [[self alloc] initExecScrollText:anObject]; } /* return textView id (docView) */ - docView { return textView; } /* return scroll view */ - scrollView { return scrollView; } /* set delegate */ - setDelegate:(id)theDelegate { delegate = theDelegate; return self; } /* return delegate */ - (id)delegate { return delegate; } /* set auto linefeed mode */ - setAutoLineFeed:(BOOL)mode { autoLf = mode; return self; } /* free object */ - free { // all pending commands should be killed here return [super free]; } // -------------------------------------------------------------------------------- /* set font */ - _setTextAttrFont:fontId color:(int)mode:(NXColor)color { textAttr_t tAttr = nullAttr; tAttr.fontId = fontId; tAttr.colorMode = mode; tAttr.color = color; [self _appendTextAndMakeVisible:(char*)nil attr:tAttr]; return self; } /* set font */ - setTextAttributeFont:fontId { return [self _setTextAttrFont:fontId color:0:nullColor]; } // -------------------------------------------------------------------------------- /* set gray */ - setTextAttributeGray:(float)aGray { return [self _setTextAttrFont:(id)nil color:1:NXConvertGrayToColor(aGray)]; } /* set gray */ - setTextAttributeColor:(NXColor)aColor { return [self _setTextAttrFont:(id)nil color:2:aColor]; } // -------------------------------------------------------------------------------- /* set default tabs */ - setTabStops:(float*)tabArray count:(int)c { NXTextStyle style = *((NXTextStyle*)[textView defaultParaStyle]); style.numTabs = (short)c; style.tabs = (NXTabStop*)malloc(sizeof(NXTabStop) * style.numTabs); while (--c >= 0) { style.tabs[c].kind = NX_LEFTTAB; style.tabs[c].x = tabArray[c]; } [textView setParaStyle:(void*)&style]; return self; } /* repeat given tab multiple times */ - setTab:(float)tabSize count:(int)c { int i; NXTextStyle style = *((NXTextStyle*)[textView defaultParaStyle]); style.numTabs = (short)c; style.tabs = (NXTabStop*)malloc(sizeof(NXTabStop) * style.numTabs); for (i = 0; i < c; i++) { style.tabs[i].kind = NX_LEFTTAB; style.tabs[i].x = (float)(i + 1) * tabSize; } [textView setParaStyle:(void*)&style]; return self; } // -------------------------------------------------------------------------------- /* clear text scroll view area */ - clearScrollText { [textView setEditable:YES]; [textView setText:""]; if (!wasEditable) [textView setEditable:NO]; [scrollView display]; return self; } - clear:sender { return [self clearScrollText]; } // -------------------------------------------------------------------------------- // append text to scroll view /* append buffer to view: return YES if text was visible */ - (BOOL)_appendTextToView:(const char*)buffer len:(int)len attr:(textAttr_t)tAttr { int txtLen; NXSelPt startPt, endPt; NXRect rect; /* check for font/gray change (save state) */ if (tAttr.fontId) { runAttr.fontId = tAttr.fontId; } if (tAttr.colorMode) { runAttr.colorMode = tAttr.colorMode; runAttr.color = tAttr.color; } if (!buffer || !*buffer || (len == 0)) return NO; /* get ready to print text */ [textView getVisibleRect:&rect]; // visible rectangle [textView setEditable:YES]; txtLen = [textView textLength]; [textView setSel:txtLen :txtLen]; [textView getSel:&startPt :&endPt]; // selected coordinates /* set text run attributes if specified */ if (!isNullAttr(runAttr)) { if ([textView isMonoFont]) [textView setMonoFont:NO]; if (!txtLen) { [textView replaceSel:" "]; [textView setSel:0 :1]; } if (runAttr.fontId) [textView setSelFont:runAttr.fontId]; if (runAttr.colorMode == 1) [textView setSelGray:cvtColor2Gray(runAttr.color)]; else if (runAttr.colorMode == 2) [textView setSelColor:runAttr.color]; runAttr = nullAttr; } /* print text */ if (len > 0) [textView replaceSel:buffer length:len]; else [textView replaceSel:buffer]; if (!wasEditable) [textView setEditable:NO]; /* delegate monitor of text written to textview */ if (delegate && [delegate respondsTo:@selector(monitorOutput:buffer:len:)]) { [delegate monitorOutput:self buffer:buffer len:len]; } return (rect.origin.y + rect.size.height > endPt.y); // was visible? } /* append text to view and scroll to visible */ - _appendTextAndMakeVisible:(const char*)buffer attr:(textAttr_t)tAttr { BOOL wasVisible; /* print buffer */ wasVisible = [self _appendTextToView:buffer len:-1 attr:tAttr]; if (autoLf && buffer) [self _appendTextToView:"\n" len:-1 attr:nullAttr]; if (wasVisible) [textView scrollSelToVisible]; return self; } // -------------------------------------------------------------------------------- // append a formatted text string message into a text view /* append text unformatted */ - (int)textPrint:(const char*)buffer { [self _appendTextAndMakeVisible:buffer attr:nullAttr]; return strlen(buffer); } /* append text with variable args into textView */ - (int)textPrintf:(const char*)fmt args:(va_list)args { char tempString[textStringSIZE] = { 0 }; int retVal = vsprintf(tempString, fmt, args); [self _appendTextAndMakeVisible:tempString attr:nullAttr]; return retVal; } /* append text with variable args into textView */ - (int)textPrintf:(const char*)fmt, ... { va_list args; int retVal; va_start(args, fmt); retVal = [self textPrintf:fmt args:args]; va_end(args); return retVal; } // -------------------------------------------------------------------------------- // executing commands within a shell, using the scroll text as output /* execute a command */ - (ExecRunCommand*)runCommand:(const char*)command user:(const char*)user { return [ExecRunCommand runCommand:command user:user output:self]; } /* execute a command (don't return until it's finished) */ - (int)system:(const char*)command user:(const char*)user { return [ExecRunCommand system:command user:user output:self]; } /* command output call-back */ - (void)commandOutput:(id)execId buffer:(const char*)buffer len:(int)len { if (delegate && [delegate respondsTo:@selector(commandOutput:buffer:len:)]) { [delegate commandOutput:execId buffer:buffer len:len]; } if ([self _appendTextToView:buffer len:len attr:nullAttr]) { [textView scrollSelToVisible]; } } /* command completion call-back */ - (void)commandDidComplete:(id)execId withError:(int)errorCode { if (delegate && [delegate respondsTo:@selector(commandDidComplete:withError:)]) { [delegate commandDidComplete:execId withError:errorCode]; } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.