This is Controller.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "Controller.h" #import "NewWindow.h" #import <streams/streams.h> #import <objc/typedstream.h> #import <objc/NXStringTable.h> #import <strings.h> #define SAVE NX_ALERTDEFAULT #define CLOSE NX_ALERTALTERNATE #define CANCEL NX_ALERTOTHER @implementation Controller /*================= * load InfoPanel *=================*/ - infoPanel:sender { if (infoPanel == nil) { [NXApp loadNibSection:"InfoPanel.nib" owner:self]; } [infoPanel orderFront:sender]; return self; } /*================================================== * create a newWindow, or better said a new insert *==================================================*/ - newWindow:sender { id win; if ([NXApp loadNibSection:"NewWindow.nib" owner:self] == nil) { return nil; } if ([newInsert setUp]) { win = [newInsert window]; if (win) { NXRect frame; char buf[256]; [win getFrame: &frame]; NX_X(&frame) += offset; NX_Y(&frame) -= offset; if ((offset += 24.0) > 100.0) { offset = 0.0; } sprintf(buf, [win title], ++calcNum); [win setTitle: buf]; [win placeWindowAndDisplay: &frame]; [win makeKeyAndOrderFront:nil]; return newInsert; } } return nil; } /*============================ * manages the service stuff *============================*/ // This probably should be broken up into two funcs. One for an RTF message // and one for an ASCII message. Oh well, it works... - servicesMessage:(id)pasteboard userData:(const char *)sortArgs error:(char **)errorMessage { int length, currentType; const char *data; const char *const *ptypes; NXStream *stream; id contf = [newInsert contentfield]; ptypes=[pasteboard types]; //Look for RTF first... for (currentType=0; ptypes[currentType] ; currentType++ ){ if (!strcmp(ptypes[currentType],NXRTFPboardType)){ [pasteboard readType:ptypes[currentType] data:&data length:&length]; stream = NXOpenMemory(data, length, NX_READONLY); [[contf docView] readRichText:stream]; NXCloseMemory(stream, NX_FREEBUFFER); return self; } } for (currentType=0; ptypes[currentType] ; currentType++ ){ if (!strcmp(ptypes[currentType],NXAsciiPboardType)) { [pasteboard readType:ptypes[currentType] data:&data length:&length]; stream = NXOpenMemory(data, length, NX_READONLY); [[contf docView] readText:stream]; NXCloseMemory(stream, NX_FREEBUFFER); return self; } } return self; //should never be reached.... } /*============================== * printing and fieldtext copy *==============================*/ - doPrint:sender { id insert = [[NXApp mainWindow] delegate]; id gr = [insert group]; [gr printPSCode:self]; return self; } - copyText:sender { NXStream *stream; char *buffer; int buttontag, length, maxlength; id outp; // var to hold the main windows outputtitlefield // The next statement "id insert = [[NXApp mainWindow] delegate];" // is needed so we can access the actual (main) window's outlets, // otherwise if we would use "newInsert" the last created insert window // (which might not be the actual (main) window would receive the copied // string. Why? - The reason is that the "newInsert" instance var will be // overwritten each time we create a new insert window and so doesn't // remember the earlier created ones. Thus if we would use it, we were // only able to copy to the latest created window in the window list, even // if some earlier one's were on top of it. id insert = [[NXApp mainWindow] delegate]; outp = [insert outputtitlefield]; buttontag = [[sender selectedCell] tag]; stream = NXOpenMemory(NULL, 0, NX_WRITEONLY); if (buttontag == 0) [[inputTitleField docView] writeRichText:stream]; else [[outp docView] writeRichText:stream]; NXGetMemoryBuffer(stream, &buffer, &length, &maxlength); NXCloseMemory(stream, NX_SAVEBUFFER); stream = NXOpenMemory(buffer, length, NX_READONLY); // access the main windows outputtitlefield, see the above comments if (buttontag == 0) [[outp docView] readRichText:stream]; else [[inputTitleField docView] readRichText:stream]; NXCloseMemory(stream, NX_FREEBUFFER); return self; } /*======================== * load/save panel stuff *========================*/ - showError: (const char *)errorMessage { NXRunAlertPanel(NULL, errorMessage, [stringSet valueForStringKey:"OK"], NULL, NULL); return self; } - openRequest:sender { const char *const types[2] = {[stringSet valueForStringKey:"extension"], NULL}; if ([ [OpenPanel new] runModalForTypes:types]) { if ([self newWindow:self]) { [newInsert loadFile:[ [OpenPanel new] filename] ]; } } return self; } - (int) countEditedWindows { id winList; int i; int count = 0; winList = [NXApp windowList]; for (i=0; i<[winList count]; i++) { if ([ [winList objectAt: i] isDocEdited]) count++; } return count; } - saveAll:sender { id winList; int i; winList = [NXApp windowList]; for (i=0; i<[winList count]; i++) { id win = [winList objectAt: i]; id delegate = [win delegate]; if ([delegate isKindOf:[NewWindow class]]) { [win makeKeyAndOrderFront:nil]; [delegate save:win]; } } return self; } - (BOOL)menuActive:menuCell { BOOL shouldBeEnabled; shouldBeEnabled = [[[NXApp mainWindow] delegate] isKindOf:[NewWindow class]]; if([menuCell isEnabled] != shouldBeEnabled) { // Menu cell is either enabled and shouldn't be, // or it is not enabled and should be. // In any event, set the correct state. [menuCell setEnabled:shouldBeEnabled]; return YES; /* redisplay */ } return NO; /* no change */ } @end @implementation Controller(ApplicationDelegate) /*============================= * Application delegate stuff *=============================*/ - appDidInit:sender { id docMenu = [insertSubmenuCell target]; [saveMenuCell setUpdateAction: @selector(menuActive:) forMenu: docMenu]; [saveAsMenuCell setUpdateAction: @selector(menuActive:) forMenu: docMenu]; [saveAllMenuCell setUpdateAction: @selector(menuActive:) forMenu: docMenu]; [[NXApp appListener] setServicesDelegate:self]; opanel = [OpenPanel new]; [opanel allowMultipleFiles:YES]; /* if you always want an empty insertwindow at startup, un-comment the following line */ // [self newWindow:self]; [NXApp setAutoupdate: YES]; 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 "app:openFile:type:" method. - (BOOL) appAcceptsAnotherFile:sender { return (YES); } // app:openFile:type: is called to open the specified file. It is called // by the Application object in response to open requests from the Workspace. - (int) app:sender openFile:(const char *)filename type:(const char *)aType { if ([self newWindow:self]) { if ([newInsert loadFile:filename]) { return YES; } } return NO; } // appWillTerminate: is called by the Application object when the 'quit' // button is pressed. It checks for edited Windows which haven't be saved. - appWillTerminate:sender { if ([self countEditedWindows]>0) { int q = NXRunAlertPanel("Quit", "There are edited windows.", "Review Unsaved", "Quit Anyway", "Cancel"); if (q==1) { /* Review */ int i; id winList; winList = [NXApp windowList]; for(i=0; i<[winList count]; i++){ id win = [winList objectAt: i]; if([ [win delegate] isKindOf:[NewWindow class] ]){ [win performClose:nil]; } } return self; } if (q==-1) { /* cancel */ return nil; } } return self; /* quit */ } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.