This is Controller.m in view mode; [Download] [Up]
/* $Id: Controller.m,v 1.2 1996/10/12 14:30:34 vkyr Exp vkyr $ */ #import <streams/streams.h> #import <objc/typedstream.h> #import <objc/NXStringTable.h> #import <strings.h> #import "Controller.h" #import "DragImageView.h" #import "PrefsController.h" #import "Text_Fmt.h" @implementation Controller char linelen[100]; char str[100],str2[100]; static char *info_array[50]; int inf_cnt; /*========================================================== * initialisation methods *==========================================================*/ - appDidInit:sender { [super init]; [myWindow setDelegate: self]; openReq = [OpenPanel new]; dragImage = [[NXImage alloc] initFromSection:"man.tiff"]; [dragImageView setScaleState:YES]; [dragImageView setImage:dragImage]; [myWindow getFrame: &initViewSize]; [myUnits setTitle:[prefsController whatUnit]]; // Set to DefaultsDB value if ([prefsController shouldShowWin] == YES) // Startup window? [[myWindow display] makeKeyAndOrderFront:self]; [self setDummyWindow]; [self setFontsScrollView]; [self setDummyScrollView]; return self; } /*========================================================== * Supporting methods for accessing objects *==========================================================*/ - getMyWindow { return myWindow; } - getFonts { return fontsScrollView; } - getPages { return pagesField; } - getHeight { return heightField; } - getWidth { return widthField; } - getMyUnits { return myUnits; } - getOpenButton { return openButton; } /*============================================================ * Update units to be conform to the actual user selection *============================================================*/ - setMyUnits { const char *itemtitle = [[myUnits selectedCell] title]; if (strcasecmp(itemtitle, "Inches") == 0) [self inches:self]; if (strcasecmp(itemtitle, "Cms") == 0) [self cms:self]; if (strcasecmp(itemtitle, "Points") == 0) [self points:self]; if (strcasecmp(itemtitle, "Picas") == 0) [self picas:self]; return self; } - setDummyWindow { // Create an invisible dummy window NXSetRect(&aRect, 0.0, 0.0, 350.0, 150.0); dummyWindow = [ [Window alloc] initContent: &aRect style: NX_TITLEDSTYLE backing:NX_BUFFERED buttonMask:NX_MINIATURIZEBUTTONMASK defer:YES]; return self; } - setFontsScrollView { // Create a text scrollview that holds the list of used fonts NXSetRect(&aRect, 0, 0, 293, 180); // Don't change these sizes!!! fontsScrollView = [ [ScrollView alloc] initFrame: &aRect]; [fontsScrollView setVertScrollerRequired:YES]; [fontsScrollView setHorizScrollerRequired:NO]; [fontsScrollView setBorderType: NX_BEZEL]; //[[dummyWindow contentView] addSubview: fontsScrollView]; [fontsScrollView getContentSize: &aSize]; // create the text object for the fontsScrollView NXSetRect(&aRect, 2.0, 2.0, aSize.width-2.0, aSize.height-2.0); fontsText = [ [Text alloc] initFrame: &aRect text: NULL alignment: NX_LEFTALIGNED]; [fontsText setOpaque:YES]; // notify superview when frame rectangle changes -- allows scroller updates [fontsText notifyAncestorWhenFrameChanged:YES]; [fontsText setEditable: NO]; [fontsText setVertResizable:YES]; [fontsText setHorizResizable:NO]; // create min and max size of text aSize.width = 0.0; [fontsText setMinSize: &aSize]; aSize.height = 1000000; [fontsText setMaxSize: &aSize]; // set the text as docview of scrollview [fontsScrollView setDocView: fontsText]; [[dummyWindow contentView] addSubview: fontsScrollView]; return self; } - setDummyScrollView { // Create another text scrollview to hold formated stuff for printing NXSetRect(&aRect, 200.0, 300.0, 350.0, 150.0); dummyScrollView = [ [ScrollView alloc] initFrame: &aRect]; [dummyScrollView setVertScrollerRequired:YES]; [dummyScrollView setHorizScrollerRequired:NO]; //[[dummyWindow contentView] addSubview: dummyScrollView]; [dummyScrollView getContentSize:&aSize]; // Create another text object for this scrollview NXSetRect(&aRect, 0.0, 0.0, aSize.width, aSize.height); dummyText = [ [Text alloc] initFrame:&aRect text: NULL alignment: NX_LEFTALIGNED]; // notify superview when frame rectangle changes -- allows scroller updates [dummyText notifyAncestorWhenFrameChanged: YES]; [dummyText setVertResizable: YES]; [dummyText setHorizResizable: NO]; [dummyText setMonoFont:NO]; // create min and max size of text aSize.width = 0.0; [dummyText setMinSize: &aSize]; aSize.height = 1000000; [dummyText setMaxSize: &aSize]; // set the text as docview of scrollview [dummyScrollView setDocView: dummyText]; [[dummyWindow contentView] addSubview: dummyScrollView]; return self; } /*========================================================== * load InfoPanel *==========================================================*/ - infoPanel:sender { if (infoPanel == nil) { [NXApp loadNibSection:"Info.nib" owner:self]; } [infoPanel orderFront:sender]; return self; } /*========================================================== * Handle Error-Messages via stringSet *==========================================================*/ - showError: (const char *)errorMessage { NXRunAlertPanel(NULL, errorMessage, [stringSet valueForStringKey:"OK"], NULL, NULL); return self; } - selectAll:sender { int currentLength = [[fontsScrollView docView] textLength]; [[fontsScrollView docView] setSel:0 :currentLength]; return self; } // appAcceptsAnotherFile is an application delegate method which // returns whether it is OK for the application to try to open more files // with the appOpenFile:type: method. DviInfo needs this to open dvi-files // by double-clicking in the WM, so we return YES. -(BOOL) appAcceptsAnotherFile:sender { return (YES); } - openInTexview: sender { [[Application workspace] openFile: [myWindow title]]; return self; } /*======================================================================= * appOpenFile:type: is called to open the specified file. It is normally * called by the Application object in response to open requests from the * Workspace. Here we also route the open requests from the OpenPanel * to this method (see openRequest:). *=======================================================================*/ -(int) appOpenFile:(char *)fileName type:(char *)fileType { return [self openDviFile:fileName]; } /*======================================================================= * openRequest: opens a new file. It puts up a open panel, and, if the user * doesn't cancel, it reads the specified dvi file. If the selected file * is not a proper dvi file, then openRequest: will complain. *=======================================================================*/ - openRequest:sender { const char *fileName; const char *const types[2] = {[stringSet valueForStringKey:"extension"], NULL}; if ([openReq runModalForTypes:types] && (fileName = [openReq filename])) { [self openDviFile:fileName]; } else [self showError:[stringSet valueForStringKey:"errorOnOpenRequest"]]; return self; } /*========================================================== * The main openDviFile action-method *==========================================================*/ -(int) openDviFile:(const char *)fileName { FILE *dvi_file; int i; inf_cnt = 0; dvi_file = fopen(fileName, "rb"); if (dvi_file == NULL) { [self showError:[stringSet valueForStringKey:"errorOnOpen"]]; return NO; } else { [[fontsScrollView docView] setText:""]; [self process_dvi_file: dvi_file]; fclose(dvi_file); [myWindow setTitle:fileName]; [self setMyUnits]; // Setup correct values for the selected Unit [myUnits setEnabled: YES]; // Enable Units popupbutton [openButton setEnabled: YES]; // Enable TeXview pushbutton for (i = 0; i < inf_cnt; i++) [[fontsScrollView docView] printf: info_array[i]]; [[myWindow display] makeKeyAndOrderFront:self]; for (i = 0; i < inf_cnt; i++) free(info_array[i]); return YES; } } /*================================================= *** PLAIN DVI-FILE-FORMAT STUFF BEGINS HERE ...*** *================================================*/ #define post 248 #define post_post 249 #define dvi_id 2 #define nop 138 #define fnt_def1 243 #define fnt_def2 244 #define fnt_def3 245 #define fnt_def4 246 typedef unsigned long four_bytes; int cur_command; double unity; double val, val2; void print_dimen(four_bytes x) { val = unity*x / 10000.0; if (val > 10) { val /= 10; } } void print_dimen2(four_bytes x) { val2 = unity*x / 10000.0; if (val2 > 10) { val2 /= 10; } } four_bytes read_unsigned(df, bytes) FILE *df; int bytes; { four_bytes x; x = getc(df); while (bytes-- >1) { x *= 256; x += getc(df); } return(x); } int reverse_getc(df) FILE *df; { fseek(df, -2, SEEK_CUR); return(getc(df)); } - process_dvi_file:(FILE *)df { four_bytes design_size, at_size; four_bytes num, den, magnification; four_bytes page_width, page_height; int a, l, pages; double font_size; fpos_t post_loc; fseek(df,0,SEEK_END); /* File-end */ /* Ignore fillbytes i*/ while ((cur_command = reverse_getc(df)) == 223) ; if (cur_command != dvi_id) { [self showError:[stringSet valueForStringKey:"wrongIdByte"]]; return self; } /* Read backwards till post_post */ reverse_getc(df); reverse_getc(df); reverse_getc(df); reverse_getc(df); cur_command = reverse_getc(df); if (cur_command != post_post) { [self showError:[stringSet valueForStringKey:"noPostamblefound"]]; return self; } post_loc = (fpos_t)read_unsigned(df,4); /* Jump to postamble */ if (fseek(df,post_loc,SEEK_SET) != 0) { [self showError:[stringSet valueForStringKey:"seekError"]]; return self; } if ((cur_command = (int) read_unsigned(df,1)) != post) { [self showError:[stringSet valueForStringKey:"noPostamblefound"]]; return self; } read_unsigned(df,4); /* Pointer to the begin of the last page */ num = read_unsigned(df,4); den = read_unsigned(df,4); magnification = read_unsigned(df,4); unity = (num*((double) magnification/1000))/den; page_height = read_unsigned(df,4); page_width = read_unsigned(df,4); read_unsigned(df,2); /* Ignore stacksize */ pages = (int) read_unsigned(df,2); [pagesField setIntValue: pages]; print_dimen(page_width); [widthField setDoubleValue: val]; print_dimen2(page_height); [heightField setDoubleValue: val2]; info_array[inf_cnt] = (char *)malloc(sizeof(linelen)); while (cur_command != post_post) { int lc = 0; char ftemp[100]; cur_command = (int) read_unsigned(df,1); switch (cur_command) { case nop: case post_post : break; case fnt_def1 : case fnt_def2 : case fnt_def3 : case fnt_def4 : read_unsigned(df,cur_command-fnt_def1+1); read_unsigned(df,4); /* throw away checksum */ at_size = read_unsigned(df,4); design_size = read_unsigned(df,4); a = (int) read_unsigned(df,1); l = (int) read_unsigned(df,1); while (a-- > 0) info_array[inf_cnt][lc++] = getc(df); while (l-- > 0) info_array[inf_cnt][lc++] = getc(df); font_size = (at_size*((double)magnification/1000))/design_size; info_array[inf_cnt][lc] = '\0'; sprintf(ftemp, "\t\t at magnification \t %5.3f \n", font_size); strcat(info_array[inf_cnt++], ftemp); info_array[inf_cnt] = (char *)malloc(sizeof(linelen)); break; } } return self; } /*================================================ *** PLAIN DVI-FILE-FORMAT STUFF ENDS HERE ... *** *===============================================*/ /*======================================================================= * Print the invisibleView (textview) via printPSCode: *=======================================================================*/ - printRequest:sender { if ([[fontsScrollView docView] textLength] == 0) [self showError:[stringSet valueForStringKey:"errorOnPrintRequest"]]; else { [self copytext:self]; [[[NXApp printInfo] setHorizCentered:NO] setVertCentered:NO]; [[dummyScrollView docView] printPSCode:self]; } return self; } /*==================================================================== * copy formated text to invisibleView (activated from printRequest) *====================================================================*/ - copytext:sender { NXStream *stream; int pagecount, txtlen; double pagewidth, pageheight; const char *unitstr; pagecount = [pagesField intValue]; pagewidth = [widthField doubleValue]; pageheight = [heightField doubleValue]; unitstr = [[myUnits selectedCell] title]; // clear dummyScrollView [[dummyScrollView docView] setText:""]; [[dummyScrollView docView] printf:"Generated by DviInfo\n\n"]; [[dummyScrollView docView] printf: "File: %s\n\n", [myWindow title]]; [[dummyScrollView docView] printf:"Pages:\t\t%d\n", pagecount]; [[dummyScrollView docView] printf: "Page width:\t%5.3f %s\n", pagewidth, unitstr]; [[dummyScrollView docView] printf: "Page height:\t%5.3f %s\n\n", pageheight, unitstr]; txtlen = [[fontsScrollView docView] textLength]; if (txtlen != 0) [[dummyScrollView docView] printf: "Used fonts are:\n\n"]; /* Get the entire text, using the rich RTF format */ stream = NXOpenMemory(NULL, 0, NX_READWRITE); if (stream) [[fontsScrollView docView] writeRichText: stream]; // write to stream /* Stick the text from the fontsText into the dummyScrollView */ if (stream) { int currentLength = [[dummyScrollView docView] textLength]; [[dummyScrollView docView] setSel:currentLength :currentLength]; NXSeek(stream, 0L, NX_FROMSTART); [[dummyScrollView docView] replaceSelWithRichText: stream]; [[dummyScrollView docView] scrollSelToVisible]; NXCloseMemory(stream, NX_FREEBUFFER); } return self; } /*====================================================== * Methods which calculate the dvi-page units *======================================================*/ double unitval, newval, newval2; - cms:sender { unitval = 1; [widthField setDoubleValue: val]; [heightField setDoubleValue: val2]; return self; } - inches:sender { unitval = 0.3937; [widthField setDoubleValue: val*unitval]; [heightField setDoubleValue: val2*unitval]; return self; } - points:sender { unitval = 28.346; if ([prefsController shouldRoundUnit] == YES) { newval = rint(val*unitval); newval2 = rint(val2*unitval); } else { newval = val*unitval; newval2 = val2*unitval; } [widthField setDoubleValue: newval]; [heightField setDoubleValue: newval2]; return self; } - picas:sender { unitval = 2.3623; if ([prefsController shouldRoundUnit] == YES) { newval = rint(val*unitval); newval2 = rint(val2*unitval); } else { newval = val*unitval; newval2 = val2*unitval; } [widthField setDoubleValue: newval]; [heightField setDoubleValue: newval2]; return self; } /*============================================================= * Window resizing method which adds/hides the fonts scrollview *=============================================================*/ - resizeWindow:sender { NXRect fontsTextFrame, newWinFrame; [fontsScrollView getFrame: &fontsTextFrame]; NX_HEIGHT(&newWinFrame) = NX_HEIGHT(&initViewSize) + NX_HEIGHT(&fontsTextFrame); if ([resizeButton state] == 1) { [[myWindow contentView] addSubview: fontsScrollView]; [myWindow sizeWindow:NX_WIDTH(&initViewSize) :NX_HEIGHT(&newWinFrame) byCorner:3]; } else { [fontsScrollView removeFromSuperview]; [myWindow sizeWindow:NX_WIDTH(&initViewSize) :NX_HEIGHT(&initViewSize) byCorner:3]; } return self; } @end @implementation Window(Sizing) #define CORNER_UPPER_LEFT 0 #define CORNER_LOWER_LEFT 1 #define CORNER_UPPER_RIGHT 2 #define CORNER_LOWER_RIGHT 3 // Keep 'a' between x and y #define CLAMP(a,x,y) (MAX((x), MIN((y), (a)))) /*===================================================================== * This Method resizes the receiving window as if it was dragged with * the given corner. This method is useful when you want the window to * resize by a corner other that the default upper right. *=====================================================================*/ - sizeWindow:(NXCoord)width :(NXCoord)height byCorner:(int)corner { NXRect newFrame; NXSize minSize, maxSize; // Clamp width and height to their respective minimum and maximum values [self getMinSize:&minSize]; [self getMaxSize:&maxSize]; width = CLAMP(width, minSize.width, maxSize.width); height = CLAMP(height, minSize.height, maxSize.height); // Set newFrame from the old frame and the new sizes NXSetRect(&newFrame, NX_X(&frame), NX_Y(&frame), width, height); // Move the respective corner by the amount of growth and set newFrame switch(corner) { case CORNER_UPPER_LEFT: NX_X(&newFrame) -= width - NX_WIDTH(&frame); break; case CORNER_LOWER_LEFT: NX_X(&newFrame) -= width - NX_WIDTH(&frame); NX_Y(&newFrame) -= height - NX_HEIGHT(&frame); break; case CORNER_UPPER_RIGHT: break; case CORNER_LOWER_RIGHT: NX_Y(&newFrame) -= height - NX_HEIGHT(&frame); break; } [self placeWindowAndDisplay:&newFrame]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.