home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / AlexNeXTSTEPSource / Source / Chapter10_Help / Words / Document.m < prev    next >
Encoding:
Text File  |  1992-11-15  |  3.8 KB  |  181 lines

  1. #import "Document.h"
  2. #import "TextController.h"
  3. #import <appkit/appkit.h>
  4.  
  5. #define    SAVE    NX_ALERTDEFAULT
  6. #define    CLOSE    NX_ALERTALTERNATE
  7. #define    CANCEL    NX_ALERTOTHER
  8.  
  9. @implementation Document
  10.  
  11. // initialize a new document
  12. - init
  13. {
  14.     [super init];
  15.     [NXApp loadNibSection:"Document.nib"
  16.         owner:self withNames:NO];
  17.     // make the document the delegate of the text
  18.     // every time a key is pressed, the delegate
  19.     // of the text object will receive a
  20.     // textDidGetKeys: isEmpty: message
  21.     // this allows us to update the window from
  22.     // a clean state to a dirty state
  23.     [window setDelegate:self];
  24.     // make the document the delegate of the window
  25.     // allows us to determine the current document
  26.     // in displaySavePanel:
  27.     [theText setDelegate:self];
  28.     return self;
  29. }
  30.  
  31. // load a document from a file
  32. - (BOOL)initDocumentFromFile:
  33.     (const char *)fullPathName
  34. {
  35.     NXStream *stream;
  36.     
  37.     // obtain a stream for an existing file
  38.     printf("in initDocumentFromFile:\n");
  39.     if (stream =
  40.         NXMapFile(fullPathName, NX_READONLY))
  41.         {
  42.         [self init];
  43.         // read text from stream
  44.         [theText readText:stream];
  45.         //update the window's title
  46.         [window setTitle:fullPathName];
  47.         // display the document
  48.         [self showDocument];
  49.         // free memory associated with stream
  50.         NXCloseMemory(stream, NX_FREEBUFFER);
  51.         return YES;
  52.         }
  53.     else
  54.         {
  55.         [self showError:"Can't open file"];
  56.         return NO;
  57.         }
  58. }
  59.  
  60. // display the document -- one improvement
  61. // is to stagger the window rather than display
  62. // each one on top of each other
  63. - showDocument
  64. {
  65.     // set the text selection to 1st char
  66.     [theText setSel:0 :0];
  67.     [window setTitle:"Untitled"];
  68.     [window makeKeyAndOrderFront:self];
  69.     return self;
  70. }
  71.  
  72. - setFilename:(const char *)fullPathName
  73. {
  74.     filename = fullPathName;
  75.     [window setTitle:fullPathName];
  76.     return self;
  77. }
  78.  
  79. - (const char *)filename
  80. {
  81.     return filename;
  82. }
  83.  
  84. // write the document to file
  85. - saveDocumentToFile:(const char*)fullPathName
  86. {
  87.     int fd;
  88.     NXStream *stream = NULL;
  89.  
  90.     // obtain a file descriptor first
  91.     if ((fd = open (fullPathName,
  92.         O_WRONLY|O_CREAT|O_TRUNC, 0644)) != -1)
  93.         {
  94.         // get a stream
  95.         stream = NXOpenFile(fd, NX_WRITEONLY);
  96.         // write text to stream
  97.         [theText writeText:stream];
  98.         // close stream to save stream to file
  99.         NXClose(stream);
  100.         // Release file descriptor
  101.         close(fd);
  102.         // set the name of the document
  103.         [self setFilename:fullPathName];
  104.         // update window to clean state
  105.         [window setDocEdited:NO];
  106.         }
  107.     else
  108.         [self showError:"Cant Write file"];
  109.     return self;
  110. }
  111.  
  112. // use an Alert panel to display error messages
  113. - showError:(const char *)errorMessage
  114. {
  115.     NXRunAlertPanel(NULL,
  116.         errorMessage, "OK", NULL, NULL);
  117.     return self;
  118. }
  119.  
  120. // called every time a key is pressed
  121. // if the window is dirty, we don't do
  122. // anything -- if it's not dirty, we set
  123. // it to dirty
  124. - textDidGetKeys:sender isEmpty:(BOOL)flag
  125. {
  126.     // if window is not edited, then set
  127.     // it to edited
  128.     if ([window isDocEdited] == NO)
  129.         [window setDocEdited:YES];
  130.     return self;
  131. }
  132.  
  133. - free
  134. {
  135.     // free the window since it's
  136.     // dynamically allocated
  137.     [window free];
  138.     // free everything allocated
  139.     // by the superclasses
  140.     return [super free];
  141. }
  142.  
  143. // since the document object is the delegate of
  144. // the window, the window will, before closing,
  145. // send a windowWillClose: message to
  146. // the document
  147. - windowWillClose:sender
  148. {
  149.     int result;
  150.     id savePanel = [textController savePanel];
  151.     
  152.     // display alert panel only if window
  153.     // is dirty
  154.     if ([window isDocEdited])
  155.         {
  156.         result = NXRunAlertPanel
  157.             ([NXApp appName],
  158.             "Unsaved changes. Close Anyway?\n",
  159.             "Save",
  160.             "Close anyway",
  161.             "Cancel");
  162.  
  163.         switch(result)
  164.             {
  165.             case SAVE:
  166.                 [self saveDocumentToFile:
  167.                     [savePanel filename]];
  168.                 break;
  169.             case CLOSE:
  170.                 // delay freeing the object until
  171.                 // we are done with the current
  172.                 // event (close:)
  173.                 return [NXApp delayedFree:self];
  174.             case CANCEL:
  175.                 return nil;
  176.             }
  177.         }
  178.     return self;
  179. }
  180.  
  181. @end