home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / DevTools / eText5 / Source / Bookmark.subproj / eTextContainer.m < prev    next >
Encoding:
Text File  |  1994-11-04  |  3.1 KB  |  107 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //    FILENAME:    eTextContainer.m
  3. //    SUMMARY:    Implementation of a general container for eText regions
  4. //    SUPERCLASS:    Object
  5. //    INTERFACE:    None
  6. //    PROTOCOLS:    None
  7. //    AUTHOR:        Rohit Khare
  8. //    COPYRIGHT:    (c) 1994 California Institure of Technology, eText Project
  9. ///////////////////////////////////////////////////////////////////////////////
  10. //  IMPLEMENTATION COMMENTS
  11. //        fragile. How to ensure that we have the only "live" handles to the
  12. //    various embedded objects
  13. ///////////////////////////////////////////////////////////////////////////////
  14. //    HISTORY
  15. //    05/08/94:    Created. First actual implementation.
  16. //    Late 93/4    Prototyped and tested in TextTest.app
  17. ///////////////////////////////////////////////////////////////////////////////
  18.  
  19. #import "eTextContainer.h"
  20.  
  21. @implementation eTextContainer
  22. //     id            theText
  23. //     char        *theChars;
  24. //     NXRunArray  *theRuns;
  25. //     int            nRuns, nChars;
  26.  
  27. - init
  28. {
  29.     [super init];
  30.     theText = nil;
  31.     theChars = NULL;
  32.     theRuns = NULL;
  33.     return self;
  34. }
  35.  
  36. - collapse:newText
  37. {
  38.     NXSelPt start, end;
  39.     int total = 0;
  40.     NXRun *currentRun, *nextRun;
  41.     int nextRunCnt;
  42.     
  43.  
  44.     // cut: the contents into a copy in our members
  45.     theText = newText;
  46.     [theText getSel:&start :&end];
  47.     nChars = end.cp - start.cp;
  48.     theChars = malloc((nChars+1)  * sizeof(wchar));
  49.     [theText getSubstring:theChars start:start.cp length:nChars];
  50.     if (!theChars[nChars-1]) { // this is for smartcopy/smartpaste
  51.         nChars--;
  52.         end.cp--;
  53.     }
  54.     if (!theRuns) theRuns = (NXRunArray *)NXChunkZoneMalloc(sizeof(NXRun), sizeof(NXRun), [self zone]);
  55.     theRuns->chunk.used = 0;
  56.     total = 0;
  57.     currentRun = [theText theRuns]->runs;
  58.     nRuns = nextRunCnt = 0;
  59.     while (total < end.cp) {
  60.         if ((total + currentRun->chars) > start.cp) {
  61.             // do we need to alloc more space?
  62.             if (theRuns->chunk.used == theRuns->chunk.allocated) {
  63.                 theRuns=(NXRunArray *)NXChunkZoneRealloc((NXChunk *)theRuns,[self zone]);
  64.             }
  65.             theRuns->chunk.used += sizeof(NXRun);
  66.             nextRun = (theRuns->runs) + nextRunCnt++; nRuns++;
  67.             *nextRun = *currentRun;
  68.             // how many characters are in our copy?
  69.             // the current run extends from total to total+chars
  70.             // we want chars from start.cp to end.cp.
  71.             // the end points are MAX(start.cp, total) and
  72.             // MIN(total+chars, end.cp) -- and the length is the diff.
  73.             nextRun->chars= MIN(total + currentRun->chars, end.cp) -
  74.                             MAX(total, start.cp);
  75.             // zero-out the info-fields so they don't get freed
  76.             currentRun->info = nil;
  77.         }
  78.         total += currentRun->chars;
  79.         currentRun++;
  80.     }
  81.     // In an undo-enabled system, we want to have a non-traceable delete:
  82.     [[theText undoManager] disableUndoRegistration];
  83.     [theText delete:self];
  84.     [[theText undoManager] reenableUndoRegistration];
  85.     return self;
  86. }
  87.  
  88. - expand:newText
  89. {
  90.     [[theText undoManager] disableUndoRegistration];
  91.     [theText replaceSel:theChars length:nChars runs:theRuns];
  92.     [[theText undoManager] reenableUndoRegistration];
  93.     free(theChars); theChars = NULL;
  94.     theRuns->chunk.used = 0;
  95.     theText = nil;
  96.     return self;
  97. }
  98.  
  99. - free
  100. {
  101.     if (theChars) free(theChars);
  102.     if (theRuns && theRuns->chunk.used != 0) {
  103.         free(theRuns);
  104.     }
  105.     return self = [super free];
  106. }
  107. @end