home *** CD-ROM | disk | FTP | other *** search
- #import <appkit/appkit.h>
- #import "Document.h"
- #import "TextController.h"
-
- #define SAVE NX_ALERTDEFAULT
- #define CLOSE NX_ALERTALTERNATE
- #define CANCEL NX_ALERTOTHER
-
- #define SAVE_ERROR "Can't save file"
- #define OPEN_ERROR "Can't open file"
-
- @implementation Document
-
- // initialize a new document
- - init
- {
- [super init];
- [NXApp loadNibSection:"Document.nib"
- owner:self withNames:NO];
- // make the document the delegate of the window
- // allows us to determine the current document
- // in showSavePanel:
- [window setDelegate:self];
- // 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
- [theText setDelegate:self];
- return self;
- }
-
- // load a document from a file
- - initDocumentFromFile:
- (const char *)fullPathName
- {
- NXStream *stream;
-
- // obtain a stream for an existing file
- 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 self;
- }
- else
- {
- [self showError:OPEN_ERROR];
- return nil;
- }
- }
-
- // 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 makeKeyAndOrderFront:self];
- return self;
- }
-
- // write the document to file
- - saveDocumentToFile:(const char *)fullPathName
- {
- NXStream *stream = NULL;
- const char* title = [window title];
-
- // get a stream first
- if (stream =
- (NXOpenMemory(NULL, 0, NX_WRITEONLY)))
- {
- // write text into stream
- [theText writeText:stream];
- // write the stream to the file
- // and check for error code
- if (NXSaveToFile(stream, fullPathName) != 0)
- {
- [self showError:SAVE_ERROR];
- // free stream
- NXCloseMemory(stream, NX_FREEBUFFER);
- return nil;
- }
- else
- // save succeeded: update misc info
- {
- // update the title of the window
- [window setTitle:fullPathName];
- // update window to clean state
- [window setDocEdited:NO];
- // free stream
- NXCloseMemory(stream, NX_FREEBUFFER);
- }
- }
- else
- // Couldn't get stream
- {
- [self showError:SAVE_ERROR];
- return nil;
- }
- 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 marked 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 dirty, then set
- // it to dirty
- 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;
-
- // 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:
- // display savepanel;
- // showSavePanel: returns
- // nil if user presses Cancel
- // this prevents window from
- // closing
- return [textController
- showSavePanel:sender];
- break;
- case CLOSE:
- // delay freeing the object until
- // we are done with the current
- // event (closing the window)
- return [NXApp delayedFree:self];
- case CANCEL:
- // returning nil prevents the window
- // from closing
- return nil;
- }
- }
- return self;
- }
-
- - window
- {
- return window;
- }
-
- @end
-