This is Document.m in view mode; [Download] [Up]
#import "Document.h" #import "TextController.h" #import <appkit/appkit.h> #define SAVE NX_ALERTDEFAULT #define CLOSE NX_ALERTALTERNATE #define CANCEL NX_ALERTOTHER @implementation Document // initialize a new document - init { [super init]; [NXApp loadNibSection:"Document.nib" owner:self withNames:NO]; // make the document the delegate of the text // every time a key is pressed, the delegate // of the text object will receive a // textDidGetKeys: isEmpty: message // this allows us to update the window from // a clean state to a dirty state [window setDelegate:self]; // make the document the delegate of the window // allows us to determine the current document // in displaySavePanel: [theText setDelegate:self]; return self; } // load a document from a file - (BOOL)initDocumentFromFile: (const char *)fullPathName { NXStream *stream; // obtain a stream for an existing file printf("in initDocumentFromFile:\n"); if (stream = NXMapFile(fullPathName, NX_READONLY)) { [self init]; // read text from stream [theText readText:stream]; //update the window's title [window setTitle:fullPathName]; // display the document [self showDocument]; // free memory associated with stream NXCloseMemory(stream, NX_FREEBUFFER); return YES; } else { [self showError:"Can't open file"]; return NO; } } // display the document -- one improvement // is to stagger the window rather than display // each one on top of each other - showDocument { // set the text selection to 1st char [theText setSel:0 :0]; [window setTitle:"Untitled"]; [window makeKeyAndOrderFront:self]; return self; } - setFilename:(const char *)fullPathName { filename = fullPathName; [window setTitle:fullPathName]; return self; } - (const char *)filename { return filename; } // write the document to file - saveDocumentToFile:(const char*)fullPathName { int fd; NXStream *stream = NULL; // obtain a file descriptor first if ((fd = open (fullPathName, O_WRONLY|O_CREAT|O_TRUNC, 0644)) != -1) { // get a stream stream = NXOpenFile(fd, NX_WRITEONLY); // write text to stream [theText writeText:stream]; // close stream to save stream to file NXClose(stream); // Release file descriptor close(fd); // set the name of the document [self setFilename:fullPathName]; // update window to clean state [window setDocEdited:NO]; } else [self showError:"Cant Write file"]; return self; } // use an Alert panel to display error messages - showError:(const char *)errorMessage { NXRunAlertPanel(NULL, errorMessage, "OK", NULL, NULL); return self; } // called every time a key is pressed // if the window is dirty, we don't do // anything -- if it's not dirty, we set // it to dirty - textDidGetKeys:sender isEmpty:(BOOL)flag { // if window is not edited, then set // it to edited if ([window isDocEdited] == NO) [window setDocEdited:YES]; return self; } - free { // free the window since it's // dynamically allocated [window free]; // free everything allocated // by the superclasses return [super free]; } // since the document object is the delegate of // the window, the window will, before closing, // send a windowWillClose: message to // the document - windowWillClose:sender { int result; id savePanel = [textController savePanel]; // display alert panel only if window // is dirty if ([window isDocEdited]) { result = NXRunAlertPanel ([NXApp appName], "Unsaved changes. Close Anyway?\n", "Save", "Close anyway", "Cancel"); switch(result) { case SAVE: [self saveDocumentToFile: [savePanel filename]]; break; case CLOSE: // delay freeing the object until // we are done with the current // event (close:) return [NXApp delayedFree:self]; case CANCEL: return nil; } } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.