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;
}
@endThese are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.