home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UTranscriptView.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  21.3 KB  |  862 lines  |  [TEXT/MPS ]

  1. // UTranscriptView.cp 
  2. // copyright © 1985-1991 by Apple Computer, Inc.  All rights reserved.
  3.  
  4. #ifndef __STDIO__
  5. #include <StdIo.h>
  6. #endif
  7.  
  8. #ifndef __UGEOMETRY__
  9. #include <UGeometry.h>
  10. #endif
  11.  
  12. #ifndef __ALIASES__
  13. #include <Aliases.h>
  14. #endif
  15.  
  16. #ifndef __UFILE__
  17. #include <UFile.h>
  18. #endif
  19.  
  20. #ifndef __UEVENT__
  21. #include <UEvent.h>
  22. #endif
  23.  
  24. #ifndef __UCOMMAND__
  25. #include <UCommand.h>
  26. #endif
  27.  
  28. #ifndef __UDOCUMENT__
  29. #include <UDocument.h>
  30. #endif
  31.  
  32. #ifndef __USCROLLER__
  33. #include <UScroller.h>
  34. #endif
  35.  
  36. #ifndef __UFAILURE__
  37. #include <UFailure.h>
  38. #endif
  39.  
  40. #ifndef __UMACAPPUTILITIES__
  41. #include <UMacAppUtilities.h>
  42. #endif
  43.  
  44. #ifndef __DIALOGS__
  45. #include <Dialogs.h>
  46. #endif
  47.  
  48. #ifndef __UPATCH__
  49. #include <UPatch.h>
  50. #endif
  51.  
  52. #ifndef __UMEMORY__
  53. #include <UMemory.h>
  54. #endif
  55.  
  56. #ifndef __UMACAPPGLOBALS__
  57. #include <UMacAppGlobals.h>
  58. #endif
  59.  
  60. #ifndef __ERRORS__
  61. #include <Errors.h>
  62. #endif
  63.  
  64. #ifndef __UTRANSCRIPTVIEW__
  65. #include "UTranscriptView.h"
  66. #endif
  67.  
  68. #ifndef __EVENTS__
  69. #include "Events.h"
  70. #endif
  71.  
  72. #if !qDebugTheDebugger
  73. //$W+
  74. //$R-
  75. //$Init-
  76. //$OV-
  77. #endif
  78.  
  79. #if qNames
  80. //$D+
  81. #endif
  82.  
  83. short pInspectLine;                                // Used to maintain line breaks when 
  84. // inspecting object in DoToField 
  85.  
  86. //--------------------------------------------------------------------------------------------------
  87. #pragma segment WWSeg
  88.  
  89. pascal short TTranscriptView::RowToIndex(short row)
  90. // Returns the row as an index for fLineLengths and fLineStarts 
  91. {
  92.     if (fFirstLineIndex + row < fRows)
  93.         return fFirstLineIndex + row;
  94.     else
  95.         return fFirstLineIndex + row - fRows;
  96. }
  97.  
  98. //--------------------------------------------------------------------------------------------------
  99. #pragma segment WWSeg
  100.  
  101. pascal short TTranscriptView::IndexToRow(short index)
  102. // Returns the index as a row 
  103. {
  104.     if (index - fFirstLineIndex >= 0)
  105.         return index - fFirstLineIndex;
  106.     else
  107.         return index - fFirstLineIndex + fRows;
  108. }
  109.  
  110. //--------------------------------------------------------------------------------------------------
  111. #pragma segment WWSeg
  112.  
  113. pascal short TTranscriptView::IndexToLocal(short index)
  114. // returns the v-coordinate of the given row 
  115. {
  116.     return kVMargin + (this->IndexToRow(index) + 1) * fFontHeight - fFontInfo.leading - fFontInfo.descent;
  117. }
  118.  
  119. //--------------------------------------------------------------------------------------------------
  120. #pragma segment WWSeg
  121.  
  122. pascal short TTranscriptView::LocalToIndex(short local)
  123. // returns the line that contains the v coordinate 
  124. {
  125.     return this->RowToIndex(((local - kVMargin - fFontInfo.leading - fFontInfo.descent) + 1) / fFontHeight);
  126. }
  127.  
  128. //--------------------------------------------------------------------------------------------------
  129. #pragma segment WWSeg
  130.  
  131. pascal void TTranscriptView::InstallTextStyle(const TextStyle& theStyle)
  132. {
  133.     FontInfo aFontInfo;
  134.     short theFontHeight;
  135.  
  136.     GetTextStyleFontInfo(theStyle, aFontInfo, theFontHeight);
  137.     fTextStyle = theStyle;
  138.     fFontInfo = aFontInfo;
  139.     fFontHeight = theFontHeight;
  140.  
  141.     this->Resize(VPoint((2 * kVMargin) + (fFontHeight * (fInsertionPt.v + 1)), (2 * kHMargin) + (fCols * fFontInfo.widMax)), kInvalidate);
  142. }
  143.  
  144. //--------------------------------------------------------------------------------------------------
  145. #pragma segment WWSeg
  146.  
  147. pascal void TTranscriptView::IndexColToLocal(short index,
  148.                                                short col,
  149.                                                VPoint& localPoint)
  150. {
  151.     localPoint.v = this->IndexToLocal(index);
  152.     HLock((Handle)fText);
  153.     localPoint.h = kHMargin + TextWidth(*fText, (*fLineStarts)[index], col);
  154.     HUnlock((Handle)fText);
  155. }
  156.  
  157. //--------------------------------------------------------------------------------------------------
  158. #pragma segment WWSeg
  159.  
  160. pascal short TTranscriptView::LocalToCol(short local)
  161. // returns the line that contains the v coordinate 
  162. {
  163.     return ((local - kHMargin) + 1) / fFontInfo.widMax;
  164. }
  165.  
  166. //--------------------------------------------------------------------------------------------------
  167. #pragma segment WWSeg
  168.  
  169. pascal short TTranscriptView::PrevIndex(short ln)
  170. // returns the line previous to the line; wrapped circularly 
  171.  
  172. {
  173.     if (ln - 1 < 0)
  174.         return fRows - 1;
  175.     else
  176.         return ln - 1;
  177. }
  178.  
  179. //--------------------------------------------------------------------------------------------------
  180. #pragma segment WWSeg
  181.  
  182. pascal short TTranscriptView::SuccIndex(short ln)
  183. // returns the line succeeding the line; wrapped circularly 
  184.  
  185. {
  186.     if (ln + 1 >= fRows)
  187.         return 0;
  188.     else
  189.         return ln + 1;
  190. }
  191.  
  192. //--------------------------------------------------------------------------------------------------
  193. #pragma segment WWSeg
  194.  
  195. pascal void TTranscriptView::GetInsertionPointRect(VRect& itsRect)
  196. {
  197.     VPoint pt;
  198.     short insertionPtIndex = this->RowToIndex(fInsertionPt.v);
  199.     this->IndexColToLocal(insertionPtIndex, (*fLineLengths)[insertionPtIndex],pt);
  200.     itsRect = VRect(pt.h, pt.v - fFontInfo.ascent, pt.h + 1, pt.v + fFontInfo.descent);
  201. }
  202.  
  203. //--------------------------------------------------------------------------------------------------
  204. #pragma segment WWInit
  205.  
  206. pascal void TTranscriptView::CommonInit(TView*    /* itsSuperView */,
  207.                                         short /* outputFont */,
  208.                                         short /* outputSize */,
  209.                                         short numLines,
  210.                                         short numCharsPerLine)
  211. {
  212.     FailInfo fi;
  213.     short i;
  214.     VPoint VPt;
  215.  
  216.     fRows = numLines;                            // # lines in window 
  217.     fCols = numCharsPerLine;                    // chars / line 
  218.     fTotal = fRows * fCols;                        // total chars in window 
  219.  
  220.     if (fi.Try())
  221.     {
  222.         fText = (TextHandle)(NewPermHandle(fTotal));
  223.         fLineLengths = (LineLensHandle)(NewPermHandle(fRows * sizeof(short)));
  224.         fLineStarts = (LineLensHandle)(NewPermHandle(fRows * sizeof(short)));
  225.         fi.Success();
  226.     }
  227.     else                                        // Recover
  228.         {
  229.             this->Free();
  230.             fi.ReSignal();
  231.         }
  232.  
  233.     fUpdateRgn = MakeNewRgn();
  234.  
  235.     for (i = 0; i <= fRows - 1; ++i)
  236.         (*fLineLengths)[i] = 0;
  237.  
  238.     for (i = 0; i <= fRows - 1; ++i)
  239.         (*fLineStarts)[i] = 0;
  240.  
  241.     this->InstallTextStyle(gApplicationStyle);
  242.     this->SetIdleFreq(GetCaretTime());
  243. }
  244.  
  245. //--------------------------------------------------------------------------------------------------
  246. #pragma segment WWInit
  247.  
  248. pascal void TTranscriptView::ITranscriptView(TView* itsSuperView,
  249.                                              short outputFont,
  250.                                              short outputSize,
  251.                                              short numLines,
  252.                                              short numCharsPerLine)
  253. {
  254.     VPoint VPt;
  255.  
  256.     this->IView(NULL, itsSuperView, gZeroVPt, gZeroVPt, sizeFixed, sizeFixed);
  257.     this->CommonInit(itsSuperView, outputFont, outputSize, numLines, numCharsPerLine);
  258. }
  259.  
  260. //--------------------------------------------------------------------------------------------------
  261. #pragma segment WWInit
  262. pascal void TTranscriptView::Initialize(void)    // override 
  263. {
  264.  
  265.     inherited::Initialize();
  266.     fCols = 100;
  267.     fFirstLineIndex = 0;
  268.     fFontHeight = 9;
  269.  
  270.     //!!! fFontInfo:            FontInfo; 
  271.  
  272.     fForcePtr = 0;
  273.  
  274.     //!!! fForceStack:        ARRAY [1..kForceDepth] OF ForceState; 
  275.     fHelpProc = NULL;
  276.     fInsertionPointOn = FALSE;
  277.     fInsertionPt = gZeroPt;
  278.     fLastInsertionPointTime = 0;
  279.     fLineLengths = NULL;
  280.     fLineStarts = NULL;
  281.     fRows = 120;
  282.     fText = NULL;
  283.     fTextStyle = gApplicationStyle;
  284.     fTotal = fRows * fCols;                        // total chars in window 
  285.     fRedirectFile = NULL;
  286.     fUpdateRgn = NULL;
  287.     fWrToFile = TRUE;
  288.     fWrToWindow = TRUE;
  289.  
  290. }
  291.  
  292. //--------------------------------------------------------------------------------------------------
  293. #pragma segment WWInit
  294.  
  295. pascal void TTranscriptView::IRes(TDocument* itsDocument,
  296.                                   TView* itsSuperView,
  297.                                   Ptr& itsParams)
  298. {
  299.  
  300.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  301.     this->CommonInit(itsSuperView, 1, 9, 120, 100);
  302. }
  303.  
  304. //--------------------------------------------------------------------------------------------------
  305. #pragma segment MAHelp
  306.  
  307. pascal void TTranscriptView::DoHelp(TToolboxEvent*/* event */ ,
  308.                                     long&        /* message */)
  309. {
  310.     if (fHelpProc)
  311.         fHelpProc();
  312. }
  313.  
  314. //--------------------------------------------------------------------------------------------------
  315. #pragma segment WWSeg
  316.  
  317. pascal void TTranscriptView::RevealInsertionPoint(void)
  318. {
  319.     if (this->Focus())
  320.     {
  321.         VRect insertionRect;
  322.         
  323.         SetPortTextStyle(fTextStyle);
  324.         this->GetInsertionPointRect(insertionRect);
  325.         this->RevealRect(insertionRect, VPoint(fFontHeight + kVMargin, fFontInfo.widMax), kRedraw);
  326.     }
  327. }
  328.  
  329. //--------------------------------------------------------------------------------------------------
  330. #pragma segment WWSeg
  331.  
  332. pascal void TTranscriptView::RevealInsertionPointLine(void)
  333.  
  334. {
  335.     VRect vr;
  336.     
  337.     this->GetInsertionPointRect(vr);
  338.     vr.left = fLocation.h;
  339.  
  340.     this->RevealRect(vr, VPoint(fFontHeight + kVMargin, 0), kRedraw);
  341. }
  342.  
  343. //--------------------------------------------------------------------------------------------------
  344. #pragma segment WWSeg
  345.  
  346. pascal void TTranscriptView::AddText(Ptr textBuf,
  347.                                      short byteCount)
  348. {
  349.     unsigned char ch;
  350.     long count;
  351.     Boolean gotBS;
  352.     Boolean gotEOL;
  353.     VPoint pt;
  354.     Rect qdr;
  355.     short startCount;
  356.     Ptr startPtr;
  357.     VRect vr;
  358.     short newOffset;
  359.     short startLength;
  360.     TScroller * aScroller;
  361.     short insertionPtIndex;
  362.     Boolean doInfiniteScroll;
  363.  
  364.     if (fWrToFile && (fRedirectFile))
  365.     {
  366.         count = byteCount;
  367.         fRedirectFile->WriteData(textBuf, count);// Disregard the error for now 
  368.     }
  369.  
  370.     if (fWrToWindow)
  371.     // draw as many lines as we got 
  372.         while (byteCount)
  373.         {
  374.             gotEOL = FALSE;
  375.             gotBS = FALSE;
  376.             startPtr = textBuf;
  377.             startCount = byteCount;
  378.             insertionPtIndex = this->RowToIndex(fInsertionPt.v);
  379.             startLength = (*fLineLengths)[insertionPtIndex];
  380.  
  381.             // Scan for a chunk to save 
  382.             while ((byteCount) && ((*fLineLengths)[insertionPtIndex] < fCols) && (!gotEOL) && (!gotBS))
  383.             {
  384.                 --byteCount;
  385.                 switch (ch = *(textBuf++))
  386.                 {
  387.                     case kWWEol:
  388.                         gotEOL = TRUE;
  389.                         break;
  390.  
  391.                     case chBackspace:
  392.                         gotBS = TRUE;
  393.                         break;
  394.  
  395.                     default:
  396.                         (*fText)[(*fLineStarts)[insertionPtIndex] + ((*fLineLengths)[insertionPtIndex]++)] = ch;
  397.                 }
  398.             }
  399.  
  400.             // Draw the chunk if possible 
  401.             if (this->Focus())
  402.             {
  403.                 SetPortTextStyle(fTextStyle);
  404.                 if (!gotBS)
  405.                 {
  406.                     VPoint vp;
  407.                     this->IndexColToLocal(insertionPtIndex, startLength,vp);
  408.                     Point qdPoint = this->ViewToQDPt(vp);
  409.                     MoveTo(qdPoint.h, qdPoint.v);
  410.                     if (gotEOL)    // don't draw the EOL character
  411.                         DrawText(startPtr, 0, (startCount - byteCount) - 1);
  412.                     else
  413.                         DrawText(startPtr, 0, startCount - byteCount);
  414.                     
  415.                 }
  416.                 else
  417.                 {
  418.                     if ((*fLineLengths)[insertionPtIndex])/* don't backspace past beginning of line! */
  419.                     {
  420.                         VRect r2;
  421.                         VRect r;
  422.                         
  423.                         this->GetInsertionPointRect(r2);
  424.                         (*fLineLengths)[insertionPtIndex]--;
  425.                         this->GetInsertionPointRect(r);
  426.                         r.right = r2.right;
  427.                         this->InvalidateVRect(r);
  428.                     }
  429.                 }
  430.             }
  431.  
  432.             // handle newline and line wrap if any 
  433.             if (gotEOL || ((*fLineLengths)[insertionPtIndex] >= fCols))
  434.             {
  435.                 // set the starting offset of the next line in the buffer 
  436.                 newOffset = (*fLineStarts)[insertionPtIndex] + (*fLineLengths)[insertionPtIndex] + 1;
  437.                 if (newOffset >= (fTotal - fCols))// save space for a full line 
  438.                     newOffset = 0;
  439.  
  440.                 fInsertionPt.v++;
  441.                 if (fInsertionPt.v == fRows)
  442.                 {
  443.                     fInsertionPt.v = fRows - 1;
  444.                     fFirstLineIndex = this->SuccIndex(fFirstLineIndex);
  445.                     doInfiniteScroll = TRUE;
  446.                 }
  447.                 else
  448.                     doInfiniteScroll = FALSE;
  449.                 insertionPtIndex = this->SuccIndex(insertionPtIndex);
  450.  
  451.                 (*fLineStarts)[insertionPtIndex] = newOffset;// offset to store text at 
  452.                 (*fLineLengths)[insertionPtIndex] = 0;// new line starts out zero length 
  453.  
  454.                 if (this->Focus())
  455.                 {
  456.                     aScroller = this->GetScroller(FALSE);
  457.                     if (aScroller->fTranslation == aScroller->fMaxTranslation)    // already scrolled to max
  458.                     {
  459.                         if (doInfiniteScroll)
  460.                         {
  461.                             this->GetDrawableQDRect(qdr);
  462.                             ScrollRect(qdr, 0, -fFontHeight, fUpdateRgn);
  463.                         }
  464.                     }
  465.                     else
  466.                     {
  467.                         if (doInfiniteScroll)
  468.                         // pretend we're up a line 
  469.                         {
  470.                             fViewToQDOffset.v = Max(fViewToQDOffset.v - fFontHeight, 0);
  471.  
  472.                             aScroller->fTranslation.v = Max(aScroller->fTranslation.v - fFontHeight, 0);
  473.                         }
  474.                         this->RevealInsertionPointLine();
  475.                     }
  476.                 }
  477.  
  478.                 // Dynamic sizing of view 
  479.                 if (fInsertionPt.v < fRows)
  480.                     this->Resize(VPoint((2 * kVMargin) + (fFontHeight * (fInsertionPt.v + 1)), (2 * kHMargin) + (fCols * fFontInfo.widMax)), kDontInvalidate);
  481.  
  482.             }
  483.             this->Update();                        // Make sure everything is nice and visible 
  484.         }
  485. }
  486. //--------------------------------------------------------------------------------------------------
  487. #pragma segment WWSeg
  488.  
  489. pascal void TTranscriptView::EndForce(void)
  490. {
  491.     if (fForcePtr)
  492.     {
  493.         fWrToWindow = fForceStack[fForcePtr].toWindow;
  494.         fWrToFile = fForceStack[fForcePtr].toFile;
  495.         --fForcePtr;
  496.     }
  497. }
  498.  
  499. //--------------------------------------------------------------------------------------------------
  500. #pragma segment WWSeg
  501.  
  502. pascal void TTranscriptView::ForceOutput(WrForceOptions wrToWindow,
  503.                                          WrForceOptions wrToFile)
  504. {
  505.     if (fForcePtr < kForceDepth)
  506.     {
  507.         ++fForcePtr;
  508.  
  509.         fForceStack[fForcePtr].toWindow = fWrToWindow;
  510.         fForceStack[fForcePtr].toFile = fWrToFile;
  511.  
  512.         if (wrToWindow != WrForceUnchanged)
  513.             fWrToWindow = wrToWindow == WrForceOn;
  514.  
  515.         if (wrToFile != WrForceUnchanged)
  516.             fWrToFile = wrToFile == WrForceOn;
  517.     }
  518. }
  519.  
  520. //--------------------------------------------------------------------------------------------------
  521. #pragma segment WWSeg
  522.  
  523. pascal OSErr TTranscriptView::CloseRedirect(void)
  524. {
  525.     OSErr err;
  526.     long fileMark;
  527.  
  528.     err = noErr;
  529.     if (fRedirectFile)
  530.     {
  531.         err = fRedirectFile->GetDataMark(fileMark);
  532.         err = fRedirectFile->SetDataLength(fileMark);
  533.         err = fRedirectFile->CloseFile(TRUE);
  534.         if (err != noErr)
  535.             err = fRedirectFile->FlushVolume();
  536.         fRedirectFile = (TFile *)(FreeIfObject(fRedirectFile));
  537.     }
  538.     return err;
  539. }
  540.  
  541. //--------------------------------------------------------------------------------------------------
  542. #pragma segment WWSeg
  543.  
  544. pascal TFile* TTranscriptView::DoMakeFile(void)
  545. {
  546.     TFile * redirectFile;
  547.  
  548.     redirectFile = NewFile();
  549.     redirectFile->DefineFile('TEXT', 'MPS ', TRUE, FALSE, TRUE, FALSE);
  550.     redirectFile->SetPermissions(fsRdWrPerm, fsRdWrPerm);
  551.     return redirectFile;
  552. }
  553.  
  554. //--------------------------------------------------------------------------------------------------
  555. #pragma segment WWSeg
  556.  
  557. pascal OSErr TTranscriptView::Redirect(const Str255& fileName)
  558. {
  559.     OSErr err;
  560.     Boolean wantToAppend;
  561.     long fileLength;
  562.     OSType fileType;
  563.     Str255 aFileName;
  564.     OSErr result;
  565.  
  566.     result = noErr;
  567.  
  568.     err = this->CloseRedirect();
  569.  
  570.     if (fileName)
  571.     {
  572.         aFileName = fileName;
  573.         wantToAppend = aFileName.Pos(">>") == 1;
  574.         if (wantToAppend)
  575.         {
  576.             // aFileName = Copy((*fileName), 3, fileName.Length() - 2);
  577.             aFileName.Delete(1, 2);
  578.         }
  579.         else
  580.             aFileName = fileName;
  581.  
  582.         if (!aFileName.IsEmpty())
  583.         {
  584.             fRedirectFile = this->DoMakeFile();
  585.             if (fRedirectFile)
  586.             {
  587.                 err = fRedirectFile->IdentifyByTrio(0, 0, aFileName);
  588.                 err = fRedirectFile->CreateFile();
  589.  
  590.                 if (err == dupFNErr)
  591.                 {
  592.                     err = fRedirectFile->GetFileType(fileType);
  593.                     if (err == noErr)
  594.                         if (fileType != 'TEXT')
  595.                             err = dupFNErr;
  596.                 }
  597.  
  598.                 if (err == noErr)
  599.                 {
  600.                     err = fRedirectFile->OpenFile();
  601.  
  602.                     if (wantToAppend)
  603.                     {
  604.                         err = fRedirectFile->GetDataLength(fileLength);
  605.                         err = fRedirectFile->SetDataMark(fileLength, fsFromStart);
  606.                     }
  607.                 }
  608.                 else
  609.                     result = err;
  610.             }
  611.         }
  612.     }
  613.     return result;
  614. }
  615. //--------------------------------------------------------------------------------------------------
  616. #pragma segment WWSeg
  617.  
  618. pascal void TTranscriptView::Scroll(short howManyLines)
  619. {
  620.     if (howManyLines)
  621.         this->GetScroller(FALSE)->ScrollBy(VPoint(howManyLines * fFontHeight, 0), kRedraw);
  622. }
  623.  
  624. //--------------------------------------------------------------------------------------------------
  625. #pragma segment WWSeg
  626.  
  627. pascal void TTranscriptView::DoKeyCommand(TToolboxEvent* event)// override 
  628. {
  629.     long message;
  630.     Rect insertionPointQDRect;
  631.     VRect insertionRect;
  632.  
  633.     this->Focus();
  634.     this->GetInsertionPointRect(insertionRect);
  635.     this->ViewToQDRect(insertionRect, insertionPointQDRect);
  636.     EraseRect(insertionPointQDRect);
  637.  
  638.     switch (event->fCharacter)
  639.     {
  640.         case chPageUp:
  641.         case chPageDown:
  642.         case chHome:
  643.         case chEnd:
  644.             inherited::DoKeyCommand(event);
  645.             break;
  646.  
  647.         case chDown:
  648.             this->Scroll(1);
  649.             break;
  650.  
  651.         case chUp:
  652.             this->Scroll(-1);
  653.             break;
  654.  
  655.         case chHelp:
  656.             if (fHelpProc)
  657.                 this->DoHelp(event, message);
  658.             else
  659.                 inherited::DoKeyCommand(event);
  660.             break;
  661.  
  662.         default:
  663.             inherited::DoKeyCommand(event);
  664.             break;
  665.     }
  666. }
  667.  
  668. //--------------------------------------------------------------------------------------------------
  669. #pragma segment WWSeg
  670.  
  671. pascal Boolean TTranscriptView::DoIdle(IdlePhase phase)// override 
  672. {
  673.     Rect insertionPointQDRect;
  674.  
  675.     if ((phase == idleContinue) && this->Focus())
  676.     {
  677.         if (this->IsActive())
  678.             SetPortTextStyle(fTextStyle);
  679.         if ((TickCount() - fLastInsertionPointTime) >= GetCaretTime())
  680.         {
  681.             VRect insertionRect;
  682.             
  683.             this->GetInsertionPointRect(insertionRect);
  684.             this->ViewToQDRect(insertionRect, insertionPointQDRect);
  685.             fLastInsertionPointTime = TickCount();
  686.             if (fInsertionPointOn)
  687.                 EraseRect(insertionPointQDRect);
  688.             else
  689.                 FillRect(insertionPointQDRect, qd.black);
  690.             fInsertionPointOn =!fInsertionPointOn;
  691.         }
  692.     }
  693.     return FALSE;
  694. }
  695.  
  696. //--------------------------------------------------------------------------------------------------
  697. #pragma segment WWSeg
  698. //!!! Former nested routine 
  699. typedef pascal void(* PrintFieldType)(const Str255& theLabel,
  700.                                       const Str255& theString,
  701.                                       void* theData,
  702.                                       short theType,
  703.                                       void* staticLink);
  704. class CPrintField
  705. {
  706.     short fCols;
  707. public:
  708.     // Constructor
  709.     CPrintField(short cols) :
  710.         fCols(cols)
  711.     {
  712.     }
  713.  
  714.     pascal void PrintField(const Str255& theLabel,
  715.                            const Str255& theString,
  716.                            void*                /*theData*/,
  717.                            short                /*theType*/);
  718. };
  719.  
  720. #pragma segment WWSeg
  721. pascal void CPrintField::PrintField(const Str255& theLabel,
  722.                                     const Str255& theString,
  723.                                     void*        /*theData*/,
  724.                                     short        /*theType*/)
  725. {
  726.     short fieldSize;
  727.  
  728.     fieldSize = theLabel.Length() + theString.Length() + 2;
  729.     if ((pInspectLine + fieldSize + 2) >= fCols)
  730.     {
  731.         fprintf(stderr, "\n");
  732.         pInspectLine = 0;
  733.     }
  734.     else if (pInspectLine)                        // If not at the start of a line 
  735.     {
  736.         fprintf(stderr, "  ");
  737.         pInspectLine = pInspectLine + 2;
  738.     }
  739.  
  740.     if (theLabel.Length())
  741.         fprintf(stderr, "%s: ", (char*)theLabel);
  742.  
  743.     fprintf(stderr, "%s", (char*)theString);
  744.     pInspectLine = pInspectLine + fieldSize;
  745. }
  746.  
  747. #pragma segment WWSeg
  748. pascal void TTranscriptView::DoToField(const Str255& fieldName,
  749.                                        void* fieldAddr,
  750.                                        short fieldType)
  751. {
  752.     if (fieldType == bClass)
  753.     {
  754.         fprintf(stderr, "\n");
  755.         fprintf(stderr, "%s:\n", (char*)fieldName);
  756.         pInspectLine = 0;
  757.     }
  758.     else
  759.     {
  760.         CPrintField aCPrintField(fCols);
  761.  
  762.         FieldToString(fieldName, fieldAddr, fieldType, (PrintFieldType) & CPrintField::PrintField, &aCPrintField);
  763.     }
  764. }
  765.  
  766. //--------------------------------------------------------------------------------------------------
  767. #pragma segment WWSeg
  768.  
  769. pascal void TTranscriptView::Draw(const VRect& area)// override 
  770. {
  771.     short currIndex;                            // index of line to draw 
  772.     short y;                                    // y coord to draw at 
  773.     Rect qdArea;
  774.  
  775.     this->ViewToQDRect(area, qdArea);
  776.  
  777.     SetPortTextStyle(fTextStyle);
  778.  
  779.     currIndex = this->LocalToIndex(qdArea.top);
  780.     y = this->IndexToLocal(currIndex);            // initial y coordinate snapped to a row 
  781.  
  782.     HLock((Handle)fText);
  783.     do
  784.     {
  785.         MoveTo(kHMargin, y);
  786.         DrawText(*fText, (*fLineStarts)[currIndex], (*fLineLengths)[currIndex]);
  787.         currIndex = this->SuccIndex(currIndex);
  788.         y += fFontHeight;
  789.     } while (((y - fFontInfo.ascent) <= qdArea.bottom) && (currIndex != fFirstLineIndex));
  790.     HUnlock((Handle)fText);
  791.  
  792.     inherited::Draw(area);
  793. }
  794.  
  795. //--------------------------------------------------------------------------------------------------
  796. #pragma segment MAClose
  797.  
  798. pascal void TTranscriptView::Free(void)            // override 
  799. {
  800.     fText = (TextHandle)(DisposeIfHandle((Handle)fText));
  801.     fLineLengths = (LineLensHandle)(DisposeIfHandle((Handle)(fLineLengths)));
  802.     fLineStarts = (LineLensHandle)(DisposeIfHandle((Handle)(fLineStarts)));
  803.     fRedirectFile = (TFile *)(FreeIfObject(fRedirectFile));
  804.  
  805.     inherited::Free();
  806. }
  807.  
  808. //--------------------------------------------------------------------------------------------------
  809. #pragma segment BBFields
  810.  
  811. pascal void TTranscriptView::Fields(TObject* obj)// override 
  812. {
  813.     Str255 s;
  814.  
  815.  
  816.     obj->DoToField("TTranscriptView", NULL, bClass);
  817.  
  818.     obj->DoToField("fWrToWindow", &fWrToWindow, bBoolean);
  819.     obj->DoToField("fWrToFile", &fWrToFile, bBoolean);
  820.     obj->DoToField("fCols", &fCols, bInteger);
  821.     obj->DoToField("fRows", &fRows, bInteger);
  822.     obj->DoToField("fTotal", &fTotal, bInteger);
  823.     obj->DoToField("fText", &fText, bHandle);
  824.     obj->DoToField("fLineLengths", &fLineLengths, bHandle);
  825.     obj->DoToField("fLineStarts", &fLineStarts, bHandle);
  826.  
  827.     obj->DoToField("fFirstLineIndex", &fFirstLineIndex, bInteger);
  828.  
  829.     obj->DoToField("fTextStyle", &fTextStyle, bTextStyle);
  830.  
  831.     obj->DoToField("fFontHeight", &fFontHeight, bInteger);
  832.     obj->DoToField("fFontInfo", NULL, bTitle);
  833.     obj->DoToField("  ascent", &fFontInfo.ascent, bInteger);
  834.     obj->DoToField("  descent", &fFontInfo.descent, bInteger);
  835.     obj->DoToField("  widMax", &fFontInfo.widMax, bInteger);
  836.     obj->DoToField("  leading", &fFontInfo.leading, bInteger);
  837.  
  838.     obj->DoToField("fRedirectFile", &fRedirectFile, bObject);
  839.  
  840.     obj->DoToField("fHelpProc", &fHelpProc, bPointer);
  841.     obj->DoToField("fLastInsertionPointTime", &fLastInsertionPointTime, bLongInt);
  842.     obj->DoToField("fInsertionPointOn", &fInsertionPointOn, bBoolean);
  843.     obj->DoToField("fInsertionPt", &fInsertionPt, bPoint);
  844.     obj->DoToField("fUpdateRgn", &fUpdateRgn, bRgnHandle);
  845.  
  846.     obj->DoToField("fForcePtr", &fForcePtr, bInteger);
  847.     obj->DoToField("fForceStack", NULL, bTitle);
  848.     for (short i = 1; i <= kForceDepth; ++i)
  849.     {
  850.         ConcatNumber(" [", i, s);
  851.         s += "].toWindow";
  852.         obj->DoToField(s, &fForceStack[i].toWindow, bBoolean);
  853.         ConcatNumber(" [", i, s);
  854.         s += "].toFile";
  855.         obj->DoToField(s, &fForceStack[i].toFile, bBoolean);
  856.     }
  857.  
  858.     inherited::Fields(obj);
  859. }
  860.  
  861.  
  862.