home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / AlexNeXTSTEPSource / Source / Chapter9_Text / Words / Document.m < prev    next >
Encoding:
Text File  |  1993-04-08  |  4.0 KB  |  195 lines

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