This is ImportApp.m in view mode; [Download] [Up]
/* * (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved. * * (b) If this Sample Code is distributed as part of the Display PostScript * System Software Development Kit from Adobe Systems Incorporated, * then this copy is designated as Development Software and its use is * subject to the terms of the License Agreement attached to such Kit. * * (c) If this Sample Code is distributed independently, then the following * terms apply: * * (d) This file may be freely copied and redistributed as long as: * 1) Parts (a), (d), (e) and (f) continue to be included in the file, * 2) If the file has been modified in any way, a notice of such * modification is conspicuously indicated. * * (e) PostScript, Display PostScript, and Adobe are registered trademarks of * Adobe Systems Incorporated. * * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO * CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED * AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED. * ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY * OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO * WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY) * WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY * DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. */ /* * ImportApp.m * * This class performs some of the global functions necessary to * manage the application. * * Several application wide resources are retained as * instance variables. Examples are the hitPoint and * upathBuffer buffers and the hitSetting value. * * Version: 2.0 * Author: Ken Fromm */ #import "ImportApp.h" #import "Document.h" #import "DrawingView.h" #import "ImportPanel.h" #import "Preferences.h" #import "SaveAsPanel.h" #import "DrawingViewWraps.h" #import <appkit/NXCursor.h> #import <appkit/NXImage.h> #import <appkit/Matrix.h> #import <appkit/Menu.h> #import <appkit/MenuCell.h> #import <appkit/defaults.h> #import <appkit/nextstd.h> #import <objc/List.h> #import <sys/param.h> #import <string.h> struct cursorRecord { char *name; NXPoint hotspot; }; const static struct cursorRecord cursors[] = { {NULL, 0.0, 0.0}, /* Select */ {"cursorZoomUp.tiff", 8.0, 8.0}, {"cursorRotate1.tiff", 8.0, 8.0}, {"cursorZoomDown.tiff", 8.0, 8.0}, {"cursorRotate2.tiff", 6.0, 4.0}, {"cursorImport.tiff", 2.0, 1.0}, {NULL, 0.0, 0.0} /* Place */ }; char ControlFont[ ] = "ControlPointsFont"; @implementation ImportApp /* * Sets the updateAction for every menu item which sends to the * First Responder (i.e. their target is nil). When autoupdate is on, * every event will be followed by an update of each of the menu items * which is visible. This keep all unavailable menu items dimmed out * so that the user knows what options are available at any given time. * Returns the activate menu if is found in this menu. */ static void initMenu(id menu) { int count; id matrix, cell; id matrixTarget, cellTarget; matrix = [menu itemList]; matrixTarget = [matrix target]; count = [matrix cellCount]; while (count--) { cell = [matrix cellAt:count :0]; cellTarget = [cell target]; if (!matrixTarget && !cellTarget) [cell setUpdateAction:@selector(menuItemUpdate:) forMenu:menu]; else if ([cell hasSubmenu]) initMenu(cellTarget); } } /* * Checks to see if the passed window's delegate is a Document * instance. If it is, it returns that document, otherwise it returns nil. */ static id documentInWindow(id window) { id document = [window delegate]; return [document isKindOf:[Document class]] ? document : nil; } /* * Searches the window list looking for a Document with the specified * name. Returns the window containing the document if found. * If name == NULL then the first document found is returned. */ static id findDocument(const char *name) { int count; id document, window, windowList; windowList = [NXApp windowList]; count = [windowList count]; while (count--) { window = [windowList objectAt:count]; document = documentInWindow(window); if (document && (!name || !strcmp([document filename], name))) return window; } return nil; } /* * Opens a file with the given name in the specified directory. * If we already have that file open, it is ordered front. * Returns the document if successful, nil otherwise. */ static id openFile(const char *directory, const char *name, BOOL display) { id window; char buffer[MAXPATHLEN+1], path[MAXPATHLEN+1]; if (name && *name) { if (!directory) { directory = "."; } else if (*directory != '/') { strcpy(buffer, "./"); strcat(buffer, directory); directory = buffer; } if (!chdir(directory) && getwd(path)) { strcat(path, "/"); strcat(path, name); window = findDocument(path); if (window) { if (display) [window makeKeyAndOrderFront:window]; return [window delegate]; } else return [Document newFromFile:path]; } else NXRunAlertPanel("Open", "Invalid path: %s", "OK", NULL, NULL, directory); } return nil; } /* * Allocate a buffer for use by any drawing view to send * data to the PostScript server. * * Allocate this buffer for use by any drawing view to * use as the hitdetection userpath. Initialize the description * since most of the components will remain the same. */ + new { int i; self = [super new]; [self setAutoupdate:YES]; PSWDefineFont(ControlFont); hitSetting = 4.0; contextFlag = imagingFlag = YES; NX_MALLOC(upathBuffer.pts, float, PTS_BUFFER); NX_MALLOC(upathBuffer.ops, char, OPS_BUFFER); NX_MALLOC(hitPoint.pts, float, PTS_HITPOINT); NX_MALLOC(hitPoint.ops, char, OPS_HITPOINT); for (i = 0; i < PTS_HITPOINT; i++) hitPoint.pts[i] = 0; hitPoint.num_pts = i; i = 0; hitPoint.ops[i++] = dps_setbbox; hitPoint.ops[i++] = dps_moveto; hitPoint.ops[i++] = dps_rlineto; hitPoint.ops[i++] = dps_rlineto; hitPoint.ops[i++] = dps_rlineto; hitPoint.ops[i++] = dps_closepath; hitPoint.num_ops = i; return self; } /* Initializes the defaults. */ + initialize { const NXDefaultsVector EpsfDefaults = { { "Quit", NULL }, { NULL, NULL } }; NXRegisterDefaults("Epsf", EpsfDefaults); return self; } - free { if (upathBuffer.pts) NX_FREE(upathBuffer.pts); if (upathBuffer.ops) NX_FREE(upathBuffer.ops); if (hitPoint.pts) NX_FREE(hitPoint.pts); if (hitPoint.ops) NX_FREE(hitPoint.ops); return [super free]; } - setToolPanel:anObject { toolpanelId = anObject; return self; } - setToolMatrix:anObject { toolmatrixId = anObject; return self; } - setSaveAccessory:anObject { [[SaveAsPanel new] setAccessoryView:anObject]; return self; } - setImportAccessory:anObject { [[ImportPanel new] setImportAccessory:anObject]; return self; } /* Calculate the position for the next window. */ - getPosition:(NXPoint *)location forSize:(NXSize *)winSize { int col, row; col = (numWindows/NUMPERCOL) % NUMCOLUMNS; row = numWindows % NUMPERCOL; location->x = WINDOWSTARTX + (col * OFFSETLEFT) + (row * OFFSETX); location->y = WINDOWSTARTY - winSize->height - (row * OFFSETY); numWindows++; return self; } /* * Teaching aids */ - setContextFlag:sender { if (!contextFlag) [[sender selectedCell] setTitle:"Separate Context On"]; else [[sender selectedCell] setTitle:"Separate Context Off"]; contextFlag = !contextFlag; return self; } - (BOOL) contextFlag { return contextFlag; } - setShowEpsfFlag:sender { if (!showEpsfFlag) [[sender selectedCell] setTitle:"Show Epsf On"]; else [[sender selectedCell] setTitle:"Show Epsf Off"]; showEpsfFlag = !showEpsfFlag; return self; } - (BOOL) showEpsfFlag { return showEpsfFlag; } - setShowBufferFlag:sender { if (!showBufferFlag) [[sender selectedCell] setTitle:"Show Buffer On"]; else [[sender selectedCell] setTitle:"Show Buffer Off"]; showBufferFlag = !showBufferFlag; if (showBufferFlag) [[[self currentDocument] drawingView] showBuffer:self]; else [[[self currentDocument] drawingView] hideBuffer:self]; return self; } - (BOOL) showBufferFlag { return showBufferFlag; } /* Change the menu title and toggle the trace boolean. */ - setTracingFlag:sender { if (!tracingFlag) [[sender selectedCell] setTitle:"Trace On"]; else [[sender selectedCell] setTitle:"Trace Off"]; tracingFlag = !tracingFlag; return self; } - (BOOL) tracingFlag { return tracingFlag; } - setImagingFlag:sender { imagingFlag = [sender state]; [[[self currentDocument] drawingView] display]; return self; } - (BOOL) imagingFlag { return imagingFlag; } - setHitSetting:sender { hitSetting = [sender floatValue]; return self; } - (float) hitSetting { return hitSetting; } - (UPath *) hitPoint; { return &hitPoint; } - (UPath *) upathBuffer; { return &upathBuffer; } - currentDocument { return documentInWindow(mainWindow); } - (const char *)currentDirectory { const char *retval = [[self currentDocument] directory]; if (!retval || !*retval) retval = [[OpenPanel new] directory]; return retval; } /* Open a new document. */ - new:sender { [Document new]; return self; } /* * Called by pressing Open... in the Window menu. */ - open:sender { id openpanel; char path[MAXPATHLEN+1]; const char *directory; const char *const *files; static const char *const filetype[2] = {"adb", NULL}; directory = NULL; directory = [[self currentDocument] directory]; if (!directory) if (getwd(path)) directory = path; openpanel = [[ImportPanel new] setOpen]; if ([openpanel runModalForDirectory:directory file:NULL types:filetype]) { files = [openpanel filenames]; directory = [openpanel directory]; while (files && *files) { openFile(directory, *files, YES); files++; } } return self; } /* * Sends a windowWillClose message to all open Documents * before the program terminates. */ - terminate:sender { int count; id window, document; count = [windowList count]; while (count--) { window = [windowList objectAt:count]; document = documentInWindow(window); if (document) { if ([document windowWillClose:window]) [window close]; else return self; } } return [super terminate:sender]; } - setTool:sender { [self setOperation:[sender selectedTag]]; return self; } - resourcePanel { if (!resourcePanel) [NXApp loadNibSection:"ResourcePanel.nib" owner:self withNames:NO]; return resourcePanel; } /* * Return the cursor for the appropriate index. Create * one if non-existent. */ - getCursor:(int) index { id imageId; if (!cursorIds[index]) { if (cursors[index].name) { imageId = [NXImage newFromSection:cursors[index].name]; cursorIds[index]= [NXCursor newFromImage:imageId]; [cursorIds[index] setHotSpot:&cursors[index].hotspot]; } } return cursorIds[index]; } - cursor { id imageId; if (!cursorIds[operation]) { if (cursors[operation].name) { imageId = [NXImage newFromSection:cursors[operation].name]; cursorIds[operation]= [NXCursor newFromImage:imageId]; [cursorIds[operation] setHotSpot:&cursors[operation].hotspot]; } else cursorIds[operation] = NXArrow; } return cursorIds[operation]; } - (int) operation { return operation; } - setOperation:(int) newOperation { id currentDoc; if (newOperation < OP_FIRST || newOperation > OP_LAST) newOperation = OP_SELECT; operation = newOperation; currentDoc = [self currentDocument]; [[currentDoc window] invalidateCursorRectsForView:[currentDoc drawingView]]; return self; } - clearOperation { [self setOperation:OP_SELECT]; [toolmatrixId selectCellWithTag:OP_SELECT]; return self; } /* * Application object delegate methods. * Messages that would be sent to the delegate are sent to the Application * object or a subclass if no delagate exists. */ /* * Initialize the menus. * Sets the tool palette so it never becomes the key window. * Check for files to open specified on the command line. * If there are no open documents, then open a blank one. */ - appDidInit:sender { id docId; int i; char buffer[MAXPATHLEN+1]; char *directory, *name, *ext; [toolpanelId removeFromEventMask:NX_KEYDOWNMASK|NX_KEYUPMASK]; [toolpanelId orderFront:self]; initMenu([NXApp mainMenu]); if (NXArgc > 1) { for (i = 1; i < NXArgc; i++) { strcpy(buffer, NXArgv[i]); ext = strrchr(buffer, '.'); if (!ext || strcmp(ext, ".adb")) strcat(buffer, ".adb"); name = strrchr(buffer, '/'); if (name) { *name++ = '\0'; directory = buffer; } else { name = buffer; directory = NULL; } docId = openFile(directory, name, YES); } } /* if none opened, open one */ if (!findDocument(NULL)) [self new:self]; if (NXGetDefaultValue([self appName], "Quit")) { [self activateSelf:YES]; NXPing(); [self terminate:self]; } return self; } /* * This method is performed whenever a user double-clicks on an icon * in the Workspace Manager representing an Epsf document. */ - (int)appOpenFile:(const char *)path type:(const char *)type { char *name; char directory[MAXPATHLEN+1]; if (type && !strcmp(type, "adb")) { strcpy(directory, path); name = strrchr(directory, '/'); if (name) { *name++ = '\0'; return (openFile(directory, name, YES) ? YES : NO); } } return NO; } /* We accept any number of appOpenFile:type: messages. */ - (BOOL)appAcceptsAnotherFile:sender { return YES; } /* Automatic update methods */ /* * Method called by all menu items which send their actions to the * First Responder. First, if the object which would respond were the * action sent down the responder chain also responds to the message * validateCommand:, then it is sent validateCommand: to determine * whether that command is valid now, otherwise, if there is a responder * to the message, then it is assumed that the item is valid. * The method returns YES if the cell has changed its appearance (so that * the caller (a Menu) knows to redraw it). */ - (BOOL)menuItemUpdate:menuCell { SEL action; id responder, target; BOOL enable; target = [menuCell target]; enable = [menuCell isEnabled]; if (!target) { action = [menuCell action]; responder = [self calcTargetForAction:action]; if ([responder respondsTo:@selector(validateCommand:)]) enable = [responder validateCommand:menuCell]; else enable = responder ? YES : NO; } if ([menuCell isEnabled] != enable) { [menuCell setEnabled:enable]; return YES; } else return NO; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.