home *** CD-ROM | disk | FTP | other *** search
/ Netscape Plug-Ins Developer's Kit / Netscape_Plug-Ins_Developers_Kit.iso / CGIPERL / MACPERL / MSRCE418.HQX / Perl Source ƒ / MacPerl / MPWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-27  |  30.7 KB  |  1,278 lines

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPWindow.c        -
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Language    :    MPW C
  10.  
  11. $Log: MPWindow.c,v $
  12. Revision 1.2  1994/05/04  02:52:40  neeri
  13. Inline Input.
  14.  
  15. Revision 1.1  1994/02/27  23:02:22  neeri
  16. Initial revision
  17.  
  18. Revision 0.4  1993/08/17  00:00:00  neeri
  19. A little more defensiveness
  20.  
  21. Revision 0.3  1993/08/06  00:00:00  neeri
  22. Draw pretty icons
  23.  
  24. Revision 0.2  1993/05/30  00:00:00  neeri
  25. Support Console Windows
  26.  
  27. Revision 0.1  1993/05/29  00:00:00  neeri
  28. Compiles correctly
  29.  
  30. *********************************************************************/
  31.  
  32. #include <Resources.h>
  33. #include <Scrap.h>
  34. #include <Packages.h>
  35. #include <PLStringFuncs.h>
  36. #include <Icons.h>
  37. #include "MPWindow.h"
  38. #include "MPConsole.h"
  39. #include "MPEditions.h"
  40.  
  41. #define    kControlInvisible    0
  42. #define    kControlVisible      0xFF
  43. #define    kScrollbarWidth        16
  44. #define    kScrollbarAdjust        (kScrollbarWidth - 1)
  45. #define    kScrollTweek           2
  46. #define    kTextOffset                5
  47. #define    kButtonScroll          10
  48.  
  49. #define    kMaxPages              1000 /* Assumes pages > 32 pixels high */
  50.  
  51. #define    kHOffset                        20   /* Stagger window offsets */
  52. #define    kVOffset                        20
  53.  
  54. #define    kTBarHeight                20
  55. #define    kMBarHeight                20
  56.  
  57. typedef short PageEndsArray[kMaxPages];
  58.  
  59. #if !defined(powerc) && !defined(__powerc)
  60. #pragma segment Window
  61. #endif
  62.  
  63. pascal DPtr DPtrFromWindowPtr(WindowPtr w)
  64. {
  65.     if (w && ((WindowPeek) w)->windowKind == PerlWindowKind)
  66.         return((DPtr)GetWRefCon(w));
  67.     else
  68.         return(nil);
  69. } /* DPtrFromWindowPtr */
  70.  
  71. #if !defined(powerc) && !defined(__powerc)
  72. #pragma segment Main
  73. #endif
  74.  
  75. /*
  76.   Scroll the TERec around to match up to the potentially updated scrollbar
  77.   values. This is really useful when the window resizes such that the
  78.   scrollbars become inactive and the TERec had been previously scrolled.
  79. */
  80. pascal void AdjustTE(DPtr theDoc)
  81. {
  82.     short    h;
  83.     short    v;
  84.     TEHandle myText;
  85.  
  86.     myText = theDoc->theText;
  87.     h =
  88.         ((*myText)->viewRect.left - (*myText)->destRect.left) -
  89.         GetCtlValue(theDoc->hScrollBar) + kTextOffset;
  90.  
  91.     v =
  92.         ((*myText)->viewRect.top - (*myText)->destRect.top) -
  93.         GetCtlValue(theDoc->vScrollBar) + kTextOffset;
  94.  
  95.     if (h || v) {
  96.         TEScroll(h, v, theDoc->theText);
  97.         DrawPageExtras(theDoc);
  98.     }
  99. }  /* AdjustTE */
  100.  
  101.  
  102. /*Calculate the new control maximum value and current value, whether it is the horizontal or
  103. vertical scrollbar. The vertical max is calculated by comparing the number of lines to the
  104. vertical size of the viewRect. The horizontal max is calculated by comparing the maximum document
  105. width to the width of the viewRect. The current values are set by comparing the offset between
  106. the view and destination rects. If necessary and we canRedraw, have the control be re-drawn by
  107. calling ShowControl.*/
  108.  
  109. /*TEStyleSample-vertical max originally used line by line calculations-lineheight was a
  110. constant value so it was easy to figure out what the range should be and pin the value
  111. within range. Now we need to use max and min values in pixels rather than in nlines*/
  112.  
  113. #if !defined(powerc) && !defined(__powerc)
  114. #pragma segment Main
  115. #endif
  116.  
  117. pascal void AdjustHV(
  118.     Boolean        isVert,
  119.     ControlHandle  control,
  120.     DPtr           theDoc,
  121.     Boolean        canRedraw)
  122. {
  123.     TEHandle    docTE;
  124.     short       value;
  125.     short           max;
  126.     short           oldValue;
  127.     short           oldMax;
  128.     Rect             sizeRect;
  129.  
  130.     sizeRect = theDoc->pageSize;
  131.     docTE    = theDoc->theText;
  132.  
  133.     oldValue = GetCtlValue(control);
  134.     oldMax   = GetCtlMax(control);
  135.     if (isVert)
  136.         max = (*docTE)->nLines*(*docTE)->lineHeight - ((*docTE)->viewRect.bottom - (*docTE)->viewRect.top);
  137.     else
  138.         max = sizeRect.right - ((*docTE)->viewRect.right - (*docTE)->viewRect.left);
  139.  
  140.     max += kTextOffset + kTextOffset; /* Allow over scroll by kTextOffset */
  141.  
  142.     if (max < 0)
  143.         max = 0; /* check for negative values */
  144.  
  145.     SetCtlMax(control, max);
  146.  
  147.     if (isVert)
  148.         value = (*docTE)->viewRect.top - (*docTE)->destRect.top;
  149.     else
  150.         value = (*docTE)->viewRect.left - (*docTE)->destRect.left;
  151.  
  152.     value += kTextOffset;
  153.  
  154.     if (value < 0) {
  155.         TEScroll(isVert ? 0 : value, isVert ? value : 0, docTE);
  156.         DrawPageExtras(theDoc);
  157.  
  158.         value = 0;
  159.     } else if (value > max) {
  160.         TEScroll(isVert ? 0 : value-max, isVert ? value-max : 0, docTE);
  161.         DrawPageExtras(theDoc);
  162.         
  163.         value = max; /* pin the value to within range */
  164.     }
  165.     SetCtlValue(control, value);
  166.     if (canRedraw && ((max != oldMax) || (value != oldValue)))
  167.         ShowControl(control); /* check to see if the control can be re-drawn */
  168. } /* AdjustHV */
  169.  
  170. #if !defined(powerc) && !defined(__powerc)
  171. #pragma segment Main
  172. #endif
  173.  
  174. pascal void AdjustScrollValues(DPtr theDoc, Boolean canRedraw)
  175. {
  176.     AdjustHV(true,  theDoc->vScrollBar, theDoc, canRedraw);
  177.     AdjustHV(false, theDoc->hScrollBar, theDoc, canRedraw);
  178. }        /* AdjustScrollValues */
  179.  
  180. pascal void GetTERect(WindowPtr window, Rect  *teRect)
  181. {
  182.      *teRect = window->portRect;
  183.      (*teRect).bottom -= kScrollbarAdjust; /* and for the scrollbars */
  184.      (*teRect).right  -= kScrollbarAdjust;
  185. }         /* GetTERect */
  186.  
  187. /* Re-calculate the position and size of the viewRect and the scrollbars.
  188.   kScrollTweek compensates for off-by-one requirements of the scrollbars
  189.   to have borders coincide with the growbox. */
  190.  
  191. pascal void AdjustScrollSizes(DPtr theDoc)
  192. {
  193.     Rect    teRect;
  194.     Rect    myPortRect;
  195.  
  196.     GetTERect(theDoc->theWindow, &teRect); /*start with teRect*/
  197.     myPortRect = theDoc->theWindow->portRect;
  198.  
  199.     (*(theDoc->theText))->viewRect = teRect;
  200.  
  201.     MoveControl(theDoc->vScrollBar, myPortRect.right - kScrollbarAdjust, -1);
  202.     SizeControl(
  203.         theDoc->vScrollBar,
  204.         kScrollbarWidth,
  205.         (myPortRect.bottom - myPortRect.top) - (kScrollbarAdjust - kScrollTweek));
  206.  
  207.     MoveControl(theDoc->hScrollBar, 31, myPortRect.bottom - kScrollbarAdjust);
  208.     SizeControl(
  209.         theDoc->hScrollBar,
  210.         (myPortRect.right - myPortRect.left) - (kScrollbarAdjust - kScrollTweek + 32),
  211.         kScrollbarWidth);
  212. }        /* AdjustScrollSizes */
  213.  
  214. #if !defined(powerc) && !defined(__powerc)
  215. #pragma segment Window
  216. #endif
  217.  
  218. /* Turn off the controls by jamming a zero into their contrlVis fields
  219.   (HideControl erases them and we don't want that). If the controls are to
  220.   be resized as well, call the procedure to do that, then call the procedure
  221.   to adjust the maximum and current values. Finally reset the controls
  222.   to be visible if not in background. */
  223.  
  224. pascal void AdjustScrollbars(DPtr theDoc, Boolean  needsResize)
  225. {
  226.     Boolean    background = gInBackground || theDoc->theWindow != gActiveWindow;
  227.     
  228.     (*(theDoc->vScrollBar))->contrlVis = kControlInvisible; /* turn them off */
  229.     (*(theDoc->hScrollBar))->contrlVis = kControlInvisible;
  230.  
  231.     if (needsResize) /* move and size if needed */
  232.         AdjustScrollSizes(theDoc);
  233.  
  234.     AdjustScrollValues(theDoc, !needsResize && !background); /* fool with max and current value */
  235.  
  236.      /* Now, restore visibility in case we never had to ShowControl during adjustment */
  237.  
  238.     if (!background) {
  239.         (*(theDoc->vScrollBar))->contrlVis = kControlVisible; /* turn them on */
  240.         (*(theDoc->hScrollBar))->contrlVis = kControlVisible;
  241.     } else { /* make sure they stay invisible */
  242.         if ((*(theDoc->vScrollBar))->contrlVis)
  243.             HideControl(theDoc->vScrollBar);
  244.         if ((*(theDoc->vScrollBar))->contrlVis)
  245.             HideControl(theDoc->hScrollBar);
  246.     }
  247. }        /* AdjustScrollbars */
  248.  
  249. #if !defined(powerc) && !defined(__powerc)
  250. #pragma segment Window
  251. #endif
  252.  
  253. pascal void GetWinContentRect(WindowPtr theWindow, Rect *r)
  254. {
  255.     *r         = theWindow->portRect;
  256.     r->right  -= kScrollbarAdjust;
  257.     r->bottom -= kScrollbarAdjust;
  258. }  /* GetWinContentRect */
  259.  
  260. #if !defined(powerc) && !defined(__powerc)
  261. #pragma segment Window
  262. #endif
  263.  
  264. pascal void InvalidateDocument(DPtr theDoc)
  265. {
  266.     GrafPtr oldPort;
  267.  
  268.     GetPort(&oldPort);
  269.     SetPort(theDoc->theWindow);
  270.     InvalRect(&theDoc->theWindow->portRect);
  271.     SetPort(oldPort);
  272. }
  273.  
  274. /* Called when the window has been resized to fix up the controls and content */
  275.  
  276. pascal void ResizeWindow(DPtr theDoc)
  277. {
  278.     AdjustScrollbars(theDoc, true);
  279.     AdjustTE(theDoc);
  280.     InvalidateDocument(theDoc);
  281. }         /* ResizeWindow */
  282.  
  283. /* Called when the window has been resized to fix up the controls and content */
  284.  
  285. pascal void ResizePageSetupForDocument(DPtr theDoc)
  286. {
  287.     theDoc->pageSize = (*(theDoc->thePrintSetup))->prInfo.rPage;
  288.  
  289.     OffsetRect(&(theDoc->pageSize), -theDoc->pageSize.left, -theDoc->pageSize.top);
  290.  
  291.     (*(theDoc->theText))->destRect.right = (*(theDoc->theText))->destRect.left +
  292.                                                         theDoc->pageSize.right;
  293.  
  294.     TECalText(theDoc->theText);
  295.  
  296.     ResizeWindow(theDoc);
  297. }         /* ResizePageSetupForDocument */
  298.  
  299. #if !defined(powerc) && !defined(__powerc)
  300. #pragma segment Main
  301. #endif
  302.  
  303. /* Common algorithm for setting the new value of a control. It returns the actual amount
  304. the value of the control changed. Note the pinning is done for the sake of returning
  305. the amount the control value changed. */
  306.  
  307. pascal void CommonAction(ControlHandle control, short *amount)
  308. {
  309.     short   value;
  310.     short   max;
  311.  
  312.     value   = GetCtlValue(control); /* get current value */
  313.     max     = GetCtlMax(control); /* and max value */
  314.     *amount = value - *amount;
  315.     if (*amount < 0)
  316.           *amount = 0;
  317.     else if (*amount > max)
  318.         *amount = max;
  319.  
  320.     SetCtlValue(control, *amount);
  321.     *amount = value - *amount; /* calculate true change */
  322. }         /* CommonAction */
  323.  
  324. #if !defined(powerc) && !defined(__powerc)
  325. #pragma segment Main
  326. #endif
  327.  
  328. /* Determines how much to change the value of the vertical scrollbar by and how
  329.   much to scroll the TE record. */
  330.  
  331. pascal void VActionProc(ControlHandle control, short part)
  332. {
  333.     short           amount;
  334.     WindowPtr       window;
  335.     DPtr            theDoc;
  336.  
  337.      if (part) {
  338.           window = (*control)->contrlOwner;
  339.         theDoc = DPtrFromWindowPtr(window);
  340.         switch (part) {
  341.         case inUpButton:
  342.         case inDownButton:
  343.             amount = 24;
  344.             break;
  345.  
  346.         case inPageUp:
  347.         case inPageDown:
  348.             amount = (*(theDoc->theText))->viewRect.bottom -
  349.                         (*(theDoc->theText))->viewRect.top;
  350.             break;
  351.         }   /* case */
  352.  
  353.         if (part == inDownButton || part == inPageDown)
  354.              amount = -amount; /* reverse direction */
  355.  
  356.         CommonAction(control, &amount);
  357.  
  358.         if (amount) {
  359.             TEScroll(0, amount, theDoc->theText);
  360.             DrawPageExtras(theDoc);
  361.         }
  362.     }     /* if */
  363. }  /* VActionProc */
  364.  
  365. #if USESROUTINEDESCRIPTORS
  366. RoutineDescriptor    uVActionProc = 
  367.         BUILD_ROUTINE_DESCRIPTOR(uppControlActionProcInfo, VActionProc);
  368. #else
  369. #define uVActionProc *(ControlActionUPP)&VActionProc
  370. #endif
  371.  
  372. #if !defined(powerc) && !defined(__powerc)
  373. #pragma segment Main
  374. #endif
  375.  
  376. /* Determines how much to change the value of the horizontal scrollbar by and how
  377.   much to scroll the TE record. */
  378.  
  379. pascal void HActionProc(ControlHandle control, short part)
  380. {
  381.     short      amount;
  382.     WindowPtr  window;
  383.     DPtr       theDoc;
  384.  
  385.     if (part) {
  386.         window = (*control)->contrlOwner;
  387.         theDoc = DPtrFromWindowPtr(window);
  388.         switch (part) {
  389.         case  inUpButton:
  390.         case  inDownButton:
  391.             amount = kButtonScroll; /* a few pixels */
  392.             break;
  393.         case  inPageUp:
  394.         case  inPageDown:
  395.             amount = (*(theDoc->theText))->viewRect.right -
  396.                         (*(theDoc->theText))->viewRect.left; /* a page */
  397.             break;
  398.         }   /* switch */
  399.         if (part == inDownButton || part == inPageDown)
  400.             amount = - amount; /* reverse direction */
  401.  
  402.         CommonAction(control, &amount);
  403.         if (amount) {
  404.             TEScroll(amount, 0, theDoc->theText);
  405.             DrawPageExtras(theDoc);
  406.         }
  407.     }     /* if */
  408. }         /* HActionProc */
  409.  
  410. #if USESROUTINEDESCRIPTORS
  411. RoutineDescriptor    uHActionProc = 
  412.         BUILD_ROUTINE_DESCRIPTOR(uppControlActionProcInfo, HActionProc);
  413. #else
  414. #define uHActionProc *(ControlActionUPP)&HActionProc
  415. #endif
  416.  
  417. /**-----------------------------------------------------------------------
  418.         Name:         ShowSelect
  419.         Purpose:        Scrolls the text selection into view.
  420.     -----------------------------------------------------------------------**/
  421.  
  422. #if !defined(powerc) && !defined(__powerc)
  423. #pragma segment Window
  424. #endif
  425.  
  426. pascal void ShowSelect(DPtr theDoc)
  427. {
  428.     if (!theDoc)
  429.         return;
  430.         
  431.      AdjustScrollbars(theDoc, false);
  432.  
  433.     /*
  434.         Let TextEdit do the hard work of keeping the selection visible╔
  435.     */
  436.  
  437.     TEAutoView(true, theDoc->theText);
  438.     TESelView(theDoc->theText);
  439.     TEAutoView(false, theDoc->theText);
  440.  
  441.     /*
  442.         Now rematch the text and the scrollbars╔
  443.     */
  444.  
  445.     SetCtlValue(
  446.         theDoc->hScrollBar,
  447.         (*(theDoc->theText))->viewRect.left -
  448.         (*(theDoc->theText))->destRect.left + kTextOffset);
  449.  
  450.     SetCtlValue(
  451.         theDoc->vScrollBar,
  452.         (*(theDoc->theText))->viewRect.top -
  453.         (*(theDoc->theText))->destRect.top  + kTextOffset);
  454. }  /* ShowSelect */
  455.  
  456. #if !defined(powerc) && !defined(__powerc)
  457. #pragma segment Window
  458. #endif
  459.  
  460. pascal void OffsetWindow(WindowPtr aWindow)
  461. {
  462.     short theWidth;
  463.     short theHeight;
  464.     short theHScreen;
  465.     short theVScreen;
  466.     short xWidth;
  467.     short xHeight;
  468.     short hMax;
  469.     short vMax;
  470.     short wLeft;
  471.     short wTop;
  472.  
  473.     theWidth  = aWindow->portRect.right - aWindow->portRect.left;
  474.     theHeight = aWindow->portRect.bottom - aWindow->portRect.top + kTBarHeight;
  475.  
  476.     theHScreen = qd.screenBits.bounds.right  - qd.screenBits.bounds.left;
  477.     theVScreen = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
  478.  
  479.     xWidth  = theHScreen - theWidth;
  480.     xHeight = theVScreen - (theHeight + kMBarHeight);
  481.  
  482.     hMax = (xWidth / kVOffset) + 1;
  483.     vMax = (xHeight / kVOffset) + 1;
  484.  
  485.     gWCount++;
  486.  
  487.     wLeft = (gWCount % hMax) * kVOffset;
  488.     wTop  = ((gWCount % vMax) * kVOffset) + kTBarHeight + kMBarHeight;
  489.  
  490.     MoveWindow(aWindow, wLeft, wTop, false);
  491. }
  492.  
  493.  
  494. /* Returns the update region in local coordinates */
  495.  
  496. pascal void GetLocalUpdateRgn(WindowPtr window, RgnHandle localRgn)
  497. {
  498.     CopyRgn(((WindowPeek)window)->updateRgn, localRgn); /* save old update region */
  499.     OffsetRgn(localRgn, window->portBits.bounds.left, window->portBits.bounds.top); /* convert to local coords */
  500. }          /* GetLocalUpdateRgn */
  501.  
  502. #if !defined(powerc) && !defined(__powerc)
  503. #pragma segment Window
  504. #endif
  505.  
  506. pascal void IssueZoomCommand(WindowPtr whichWindow, short whichPart);
  507. pascal void IssueSizeWindow(WindowPtr whichWindow,short newHSize, short newVSize);
  508.  
  509. pascal void MyGrowWindow(WindowPtr w, Point p)
  510. {
  511.     GrafPtr savePort;
  512.     long    theResult;
  513.     Rect    r;
  514.  
  515.     GetPort(&savePort);
  516.     SetPort(w);
  517.     SetRect(&r, 80, 80, qd.screenBits.bounds.right, qd.screenBits.bounds.bottom);
  518.     theResult = GrowWindow(w, p, &r);
  519.     if (theResult)
  520.         IssueSizeWindow(w, LoWord(theResult), HiWord(theResult));
  521.  
  522.     SetPort(savePort);
  523. }
  524.  
  525. #if !defined(powerc) && !defined(__powerc)
  526. #pragma segment Window
  527. #endif
  528.  
  529. pascal void DoZoom(WindowPtr w, short c, Point     p)
  530. {
  531.     GrafPtr savePort;
  532.  
  533.      GetPort(&savePort);
  534.     SetPort(w);
  535.      if (TrackBox(w, p, c)) {
  536.         EraseRect(&w->portRect);
  537.         IssueZoomCommand(w, c);
  538.     }
  539. }
  540.  
  541. #if !defined(powerc) && !defined(__powerc)
  542. #pragma segment Window
  543. #endif
  544.  
  545. pascal void DoContent(WindowPtr theWindow, EventRecord * theEvent)
  546. {
  547.     short         cntlCode;
  548.     short         part;
  549.     ControlHandle theControl;
  550.     GrafPtr       savePort;
  551.     Boolean       extend;
  552.     DPtr          theDoc;
  553.     short         value;
  554.  
  555.     GetPort(&savePort);
  556.     SetPort(theWindow);
  557.     theDoc = DPtrFromWindowPtr(theWindow);
  558.  
  559.     GlobalToLocal(&theEvent->where);
  560.     cntlCode = FindControl(theEvent->where, theWindow, &theControl);
  561.  
  562.     /*only extend the selection if the shiftkey is down*/
  563.     if (cntlCode == 0) {
  564.           extend = (theEvent->modifiers & shiftKey) != 0;
  565.  
  566.         if (PtInRect(theEvent->where, &(*(theDoc->theText))->viewRect))
  567.             TEClick(theEvent->where, extend, theDoc->theText);
  568.     } else if (cntlCode == inThumb) {
  569.         value = GetCtlValue(theControl);
  570.         part  = TrackControl(theControl, theEvent->where, nil);
  571.         if (part) {
  572.             value -= GetCtlValue(theControl);
  573.             if (value) {
  574.                 if (theControl == theDoc->vScrollBar)
  575.                     TEScroll(0, value, theDoc->theText);
  576.                 else
  577.                     TEScroll(value, 0, theDoc->theText);
  578.                 DrawPageExtras(theDoc);
  579.             }
  580.         } /* if */
  581.     } else
  582.         if (theControl == theDoc->vScrollBar)
  583.             part = TrackControl(theControl, theEvent->where, &uVActionProc);
  584.         else
  585.             part = TrackControl(theControl, theEvent->where, &uHActionProc);
  586.  
  587.     SetPort(savePort);
  588. }
  589.  
  590. #if !defined(powerc) && !defined(__powerc)
  591. #pragma segment Window
  592. #endif
  593.  
  594. pascal void AdjustScript(DPtr doc)
  595. {
  596.     ScriptCode    fontScript;
  597.     ScriptCode    keyScript;
  598.  
  599.     fontScript = FontToScript((*doc->theText)->txFont);
  600.     keyScript  = GetScriptManagerVariable(smKeyScript);
  601.     
  602.     /* White man's burden: A roman keyboard script fits everywhere. */
  603.     if (keyScript != fontScript && keyScript != smRoman) 
  604.         KeyScript(fontScript);
  605. }
  606.  
  607. #if !defined(powerc) && !defined(__powerc)
  608. #pragma segment Window
  609. #endif
  610.  
  611. pascal OSErr DoActivate(WindowPtr theWindow, Boolean   activate)
  612. {
  613.     OSErr err;
  614.     Rect  r;
  615.     DPtr  theDoc;
  616.  
  617.     err = noErr;
  618.  
  619.     if (theWindow) {
  620.         theDoc = DPtrFromWindowPtr(theWindow);
  621.         SetPort(theWindow);
  622.         DrawGrowIcon(theWindow);
  623.         GetWinContentRect(theWindow, &r);
  624.         InvalRect(&r);
  625.         if (activate) {
  626.             gActiveWindow = theWindow;
  627.             
  628.             TEActivate(theDoc->theText);
  629.             ShowControl(theDoc->vScrollBar);
  630.             ShowControl(theDoc->hScrollBar);
  631.             DisableItem(myMenus[editM], undoCommand);
  632.             err = TEFromScrap();
  633.             AdjustScript(theDoc);
  634. #ifndef RUNTIME
  635.             if (theDoc->tsmDoc)
  636.                 ActivateTSMDocument(theDoc->tsmDoc);
  637. #endif
  638.         } else {
  639. #ifndef RUNTIME
  640.             if (theDoc->tsmDoc)
  641.                 DeactivateTSMDocument(theDoc->tsmDoc);
  642. #endif
  643.  
  644.             gActiveWindow = nil;
  645.             
  646.             TEDeactivate(theDoc->theText);
  647.             HideControl(theDoc->vScrollBar);
  648.             HideControl(theDoc->hScrollBar);
  649.             err = ZeroScrap();
  650.             err = TEToScrap();
  651.         }
  652.     }
  653.  
  654.       return err;
  655. }
  656.  
  657. #if !defined(powerc) && !defined(__powerc)
  658. #pragma segment Window
  659. #endif
  660.  
  661. pascal void GetPageEnds(
  662.     short          pageHeight,
  663.     TEHandle       theText,
  664.     PageEndsArray  pageBounds,
  665.     short          *nPages)
  666. {
  667.     short  pageBase;      /* total pixel offset of pages so far */
  668.     short  thisLine;
  669.     short  lastLine;
  670.     short  pageSoFar;
  671.     short  thisPage;      /* Current page being calced */
  672.     short  thisLineH;     /* Height of text line */
  673.     short  pageFirstLine; /* Line # of top of page */
  674.  
  675.     pageBase   = 0;
  676.     thisLine   = 1;
  677.     lastLine   = (*theText)->nLines;
  678.  
  679.     thisPage   = 0;
  680.     pageSoFar  = 0;
  681.     while ((thisLine <= lastLine) || (pageSoFar!=0)) {
  682.         pageFirstLine = thisLine;
  683.         thisLineH     = TEGetHeight(thisLine, thisLine, theText);
  684.  
  685.         while ((thisLineH+pageSoFar<pageHeight) && (thisLine <= lastLine)) {
  686.             pageSoFar += thisLineH;
  687.             thisLine++;
  688.             thisLineH = TEGetHeight(thisLine, thisLine, theText);
  689.         }
  690.  
  691.         if (pageSoFar) {
  692.             pageBounds[thisPage] = pageSoFar+pageBase;
  693.             pageBase  = pageBounds[thisPage];
  694.             thisPage++;
  695.             pageSoFar = 0;
  696.         }
  697.  
  698.         /*
  699.             Special case text line taller than page
  700.         */
  701.  
  702.         if ((thisLine  == pageFirstLine) && (thisLineH > pageHeight)) {
  703.             do {
  704.                 pageBounds[thisPage] = pageBase+pageHeight;
  705.                 pageBase   = pageBounds[thisPage];
  706.                 thisPage  += 1;
  707.                 thisLineH -= pageHeight;
  708.             } while (thisLineH >= pageHeight);
  709.             pageSoFar = thisLineH; /* Carry bottom of large line to next page */
  710.             thisLine += 1; /* carry xs on as pageSoFar and start measuring next line */
  711.         }
  712.     }
  713.  
  714.     *nPages = thisPage;
  715. }  /* GetPageEnds */
  716.  
  717. pascal void DrawPageBreaks(DPtr theDoc)
  718. {
  719.     PageEndsArray    pageEnds;
  720.     short           nPages;
  721.     short           ctr;
  722.     short           lineBase;
  723.     short           pageHeight;
  724.     Rect            viewRect;
  725.  
  726.     pageHeight = theDoc->pageSize.bottom - theDoc->pageSize.top;
  727.  
  728.     GetPageEnds(pageHeight, theDoc->theText, pageEnds, &nPages);
  729.  
  730.     lineBase = (*(theDoc->theText))->destRect.top;
  731.     viewRect = (*(theDoc->theText))->viewRect;
  732.  
  733.     PenPat(&qd.gray);
  734.     for (ctr = 0; ctr<nPages-1; ctr++) {
  735.         MoveTo(viewRect.left, lineBase+pageEnds[ctr]);
  736.         LineTo(viewRect.right,lineBase+pageEnds[ctr]);
  737.     }
  738.     PenNormal();
  739. } /*    DrawPageBreaks */
  740.  
  741. pascal void DrawPageExtras(DPtr theDoc)
  742. {
  743.     GrafPtr       oldPort;
  744.     RgnHandle    oldClip;
  745.     Rect              rectToClip;
  746.  
  747.     GetPort(&oldPort);
  748.     SetPort(theDoc->theWindow);
  749.  
  750.     oldClip = NewRgn();
  751.     GetClip(oldClip);
  752.  
  753.     GetWinContentRect(theDoc->theWindow,&rectToClip);
  754.     ClipRect(&rectToClip);
  755.  
  756. #ifndef RUNTIME
  757.     /* draw the borders */
  758.  
  759.     if (theDoc->kind == kDocumentWindow && theDoc->u.reg.showBorders)
  760.         ShowSectionBorders(theDoc);
  761. #endif
  762.  
  763.     /* and then the page breaks */
  764.     /* DrawPageBreaks(theDoc);  Take the page breaks and shove 'em MN */
  765.  
  766.     SetClip(oldClip);
  767.  
  768.     DisposeRgn(oldClip);
  769.  
  770.     SetPort(oldPort);
  771. }  /* DrawPageExtras */
  772.  
  773. #ifndef RUNTIME
  774. #define PlotResMiniIcon(id, r)    PlotIconID(r, atNone, ttNone, id)
  775. #endif
  776.  
  777. pascal void DoUpdate(DPtr theDoc, WindowPtr theWindow)
  778. {
  779.     GrafPtr       savePort;
  780.     Rect             rectClip;
  781.     Rect             r;
  782.     short            icmVBase;
  783.  
  784.     GetPort(&savePort);
  785.     SetPort(theWindow);
  786.     BeginUpdate(theWindow);
  787.  
  788.     ClipRect(&theWindow->portRect);
  789.     EraseRect(&theWindow->portRect);
  790.     
  791.     if (theDoc) {
  792.         icmVBase = theWindow->portRect.bottom - 13;
  793.         
  794.         SetRect(&r, 2, icmVBase, 18, icmVBase+12);
  795.         switch (theDoc->lastState & 0x000F) {
  796.         case stateConsole:
  797.             PlotResMiniIcon(ConsoleSICNID, &r);
  798.             break;
  799.         case stateDocument:
  800.             PlotResMiniIcon(DocumentSICNID, &r);
  801.             break;
  802.         }
  803.         SetRect(&r, 18, icmVBase, 34, icmVBase+12);
  804.         switch (theDoc->lastState & 0x00F0) {
  805.         case stateRdWr:
  806.             PlotResMiniIcon(EnabledSICNID, &r);
  807.             break;
  808.         case stateRdOnly:
  809.             PlotResMiniIcon(ReadOnlySICNID, &r);
  810.             break;
  811.         case stateBlocked:
  812.             PlotResMiniIcon(BlockedSICNID, &r);
  813.             break;
  814.         }
  815.         
  816.         DrawControls(theWindow);
  817.         DrawGrowIcon(theWindow);
  818.     
  819.         GetWinContentRect(theWindow, &rectClip);
  820.         ClipRect(&rectClip);
  821.     
  822.         TEUpdate(&theWindow->portRect, theDoc->theText);
  823.     
  824.         DrawPageExtras(theDoc);
  825.     }
  826.     
  827.     EndUpdate(theWindow);
  828.     ClipRect(&theWindow->portRect);
  829.  
  830.     SetPort(savePort);
  831. } /* DoUpdate */
  832.  
  833. #if !defined(powerc) && !defined(__powerc)
  834. #pragma segment Window
  835. #endif
  836.  
  837. pascal DPtr NewDocument(Boolean isForOldDoc, WindowKind kind)
  838. {
  839.     short                resFile;
  840.     Rect           destRect;
  841.     Rect           viewRect;
  842.     Rect           vScrollRect;
  843.     Rect           hScrollRect;
  844.     DPtr           myDoc;
  845.     WindowPtr      myWindow;
  846.     ControlHandle  vScroll;
  847.     ControlHandle  hScroll;
  848.     Str255         theName;
  849.     Str255         newNumber;
  850. #ifndef RUNTIME
  851.     OSType            supportedInterfaces[1];
  852. #endif
  853.  
  854.     myDoc = nil;
  855.     myWindow = GetNewWindow(WindowTemplates+kind, nil, (WindowPtr)-1);
  856.  
  857.     if (!myWindow)
  858.         return nil;
  859.  
  860.     if (!isForOldDoc && kind == kDocumentWindow) {
  861.         GetWTitle(myWindow, theName);
  862.         NumToString(++gNewDocCount, newNumber);
  863.         if (gNewDocCount>1) {
  864.             PLstrcat(theName, (StringPtr) "\p #");
  865.             PLstrcat(theName, newNumber);
  866.             SetWTitle(myWindow, theName);
  867.         }
  868.     }
  869.  
  870.     OffsetWindow(myWindow);
  871.     SetPort(myWindow);
  872.  
  873.     myDoc = (DPtr)NewPtr(sizeof(DocRec));
  874.  
  875.     SetWRefCon(myWindow, (long)myDoc);
  876.     ((WindowPeek) myWindow)->windowKind = PerlWindowKind;
  877.  
  878.     myDoc->theWindow = myWindow;
  879.  
  880.     vScrollRect = myWindow->portRect;
  881.  
  882.     vScrollRect.left  = vScrollRect.right - kScrollbarAdjust;
  883.     vScrollRect.right = vScrollRect.left  + kScrollbarWidth;
  884.  
  885.     vScrollRect.bottom = vScrollRect.bottom - 14;
  886.     vScrollRect.top    = vScrollRect.top - 1;
  887.  
  888.     vScroll = NewControl(myWindow, &vScrollRect, (StringPtr) "\p", true, 0, 0, 0, scrollBarProc, 0);
  889.  
  890.     hScrollRect = myWindow->portRect;
  891.     hScrollRect.top = hScrollRect.bottom - kScrollbarAdjust;
  892.     hScrollRect.bottom = hScrollRect.top + kScrollbarWidth;
  893.  
  894.     hScrollRect.right = hScrollRect.right - 14;
  895.     hScrollRect.left  = hScrollRect.left + 31;
  896.     hScroll = NewControl(myWindow, &hScrollRect, (StringPtr) "\p", true, 0, 0, 0, scrollBarProc, 0);
  897.  
  898.     myDoc->vScrollBar = vScroll;
  899.     myDoc->hScrollBar = hScroll;
  900.     myDoc->type            = kPlainTextDoc;
  901.     myDoc->kind         = kind;
  902.     myDoc->dirty         = false;
  903.  
  904.     if (kind == kDocumentWindow) {
  905.         myDoc->u.reg.lastID            = 0;
  906.         myDoc->u.reg.firstSection    = nil;
  907.         myDoc->u.reg.lastSection    = nil;
  908.         myDoc->u.reg.numSections    = 0;
  909.         myDoc->u.reg.everSaved     = false;
  910.         myDoc->u.reg.everLoaded    = false;
  911.         myDoc->u.reg.showBorders     = false;
  912.         
  913.         myDoc->lastState                = stateDocument + stateRdWr;
  914.     } else {
  915.         myDoc->u.cons.next            = gConsoleList;
  916.         myDoc->u.cons.cookie            = nil;
  917.         myDoc->u.cons.fence            = 0;
  918.         myDoc->u.cons.memory            = 20000;
  919.         myDoc->u.cons.selected        = false;
  920.  
  921.         gConsoleList = myDoc;
  922.  
  923.         myDoc->lastState                = stateConsole + stateBlocked;
  924.     }
  925.  
  926.     GetTERect(myWindow, &viewRect);
  927.     destRect = viewRect;
  928.  
  929.     myDoc->thePrintSetup = (THPrint)NewHandle(sizeof(TPrint));
  930.  
  931.     resFile = CurResFile();
  932.     
  933.     PrOpen();
  934.     PrintDefault(myDoc->thePrintSetup);
  935.     PrClose();
  936.     
  937.     UseResFile(resFile);
  938.  
  939.     myDoc->pageSize = (*(myDoc->thePrintSetup))->prInfo.rPage;
  940.     OffsetRect(&myDoc->pageSize, -myDoc->pageSize.left, -myDoc->pageSize.top);
  941.  
  942.     destRect.right = destRect.left + myDoc->pageSize.right;
  943.  
  944.     OffsetRect(&destRect, kTextOffset, kTextOffset);
  945.  
  946.     TextFont(gFormat.font);
  947.     TextSize(gFormat.size);
  948.     TextFace(0);
  949.  
  950.     myDoc->theText = TENew(&destRect, &viewRect);
  951.     
  952.     (*myDoc->theText)->crOnly = -1;
  953.     myDoc->theFileName[0] = 0;
  954.     myDoc->theWindow      = myWindow;
  955.  
  956. #ifndef RUNTIME
  957.     myDoc->tsmDoc                =    nil;
  958.     myDoc->tsmTERecHandle    =    nil;
  959.     
  960.     if (gTSMTEImplemented) {
  961.         supportedInterfaces[0] = kTSMTEInterfaceType;
  962.         if (NewTSMDocument(1, supportedInterfaces, &myDoc->tsmDoc,
  963.                     (long) &myDoc->tsmTERecHandle) == noErr)
  964.         {
  965.             TSMTERecPtr tsmteRecPtr = *(myDoc->tsmTERecHandle);
  966.             
  967.             tsmteRecPtr->textH = myDoc->theText;
  968.             tsmteRecPtr->preUpdateProc = nil;
  969.             tsmteRecPtr->postUpdateProc = nil;
  970.             tsmteRecPtr->updateFlag = 0;
  971.             tsmteRecPtr->refCon = (long) myDoc->theWindow;
  972.             
  973.             UseInputWindow(myDoc->tsmDoc, !gPerlPrefs.inlineInput);
  974.         } else {
  975.             myDoc->tsmDoc                =    nil;
  976.             myDoc->tsmTERecHandle    =    nil;
  977.         }
  978.     }
  979. #endif
  980.         
  981.     ResizeWindow(myDoc);
  982.     
  983.     RegisterDocument(myDoc);
  984.     
  985.     return(myDoc);
  986. }
  987.  
  988. #if !defined(powerc) && !defined(__powerc)
  989. #pragma segment Window
  990. #endif
  991.  
  992. pascal void CloseMyWindow(WindowPtr aWindow)
  993. {
  994.     DPtr     aDocument;
  995.     TEHandle theText;
  996.  
  997.     DoHideWindow(aWindow);
  998.     aDocument = DPtrFromWindowPtr(aWindow);
  999.  
  1000.     UnregisterDocument(aDocument);
  1001.  
  1002. #ifndef RUNTIME
  1003.     if (aDocument->tsmDoc) {
  1004.         FixTSMDocument(aDocument->tsmDoc);
  1005.         // DeleteTSMDocument might cause crash if we don't deactivate first, so...
  1006.         DeactivateTSMDocument(aDocument->tsmDoc);
  1007.         DeleteTSMDocument(aDocument->tsmDoc);
  1008.     }
  1009. #endif
  1010.  
  1011.     if (aDocument->kind != kDocumentWindow) {
  1012.         CloseConsole(aDocument->u.cons.cookie);
  1013.         
  1014.         if (gConsoleList == aDocument)
  1015.             gConsoleList = aDocument->u.cons.next;
  1016.         else {
  1017.             DPtr doc = gConsoleList;
  1018.             while (doc->u.cons.next != aDocument)
  1019.                 doc = doc->u.cons.next;
  1020.             doc->u.cons.next = aDocument->u.cons.next;
  1021.         }
  1022.     }
  1023.     
  1024.     theText   = aDocument->theText;
  1025.     TEDispose(theText);
  1026.  
  1027.     if (aDocument->thePrintSetup)
  1028.         DisposHandle((Handle)aDocument->thePrintSetup);
  1029.  
  1030.     DisposPtr((Ptr)aDocument);
  1031.     DisposeWindow(aWindow);
  1032.  
  1033.     gWCount--;
  1034. }
  1035.  
  1036. /*
  1037.     Name     : PrintWindow
  1038.     Function : Prints the document supplied in theDoc. askUser controls interaction
  1039.                   with the user.
  1040.  
  1041.                          Uses extra memory equal to the size of the textedit use in the
  1042.                          printed document.
  1043. */
  1044.  
  1045. pascal void PrintWindow(DPtr theDoc, Boolean askUser)
  1046. {
  1047.     GrafPtr          oldPort;
  1048.     TEHandle         printerTE;
  1049.     TPPrPort         printerPort;
  1050.     Rect                 printView;
  1051.     PageEndsArray    pageBounds;
  1052.     short              nPages;
  1053.     short               pageCtr;
  1054.     Boolean             abort;
  1055.     short                resFile;
  1056.     Rect                 rectToClip;
  1057.     TPrStatus         thePrinterStatus;
  1058.     DialogPtr         progressDialog;
  1059.  
  1060.     abort = false;
  1061.  
  1062.     /*
  1063.         Preserve the current port
  1064.     */
  1065.     GetPort(&oldPort);
  1066.     resFile = CurResFile();
  1067.     PrOpen();
  1068.  
  1069.     if (askUser)
  1070.         if (abort = !PrJobDialog(theDoc->thePrintSetup)) {
  1071.             PrClose();
  1072.             
  1073.             goto done;
  1074.         }
  1075.  
  1076.     progressDialog = GetNewDialog(1005, nil, (WindowPtr)-1);
  1077.  
  1078.     DrawDialog(progressDialog);
  1079.  
  1080.     printerPort = PrOpenDoc(theDoc->thePrintSetup, nil, nil);
  1081.     SetPort((GrafPtr)printerPort);
  1082.  
  1083.     /*
  1084.         Put the window text into the printer port
  1085.     */
  1086.     TextFont((*theDoc->theText)->txFont);
  1087.     TextSize((*theDoc->theText)->txSize);
  1088.  
  1089.     printView = (*(theDoc->thePrintSetup))->prInfo.rPage;
  1090.     printerTE = TENew(&printView, &printView);
  1091.  
  1092.     HLock((Handle)((*(theDoc->theText))->hText));
  1093.  
  1094.     TESetText(*((*(theDoc->theText))->hText), (*(theDoc->theText))->teLength, printerTE);
  1095.  
  1096.     HUnlock((Handle)((*(theDoc->theText))->hText));
  1097.  
  1098.     /*
  1099.         Work out the offsets
  1100.     */
  1101.     (*printerTE)->destRect = printView; /* GetPageEnds calls TECalText */
  1102.  
  1103.     GetPageEnds(printView.bottom-printView.top, printerTE, pageBounds, &nPages);
  1104.  
  1105.     TEDeactivate(printerTE);
  1106.  
  1107.     for (pageCtr = 0; pageCtr <= nPages-1; pageCtr++)
  1108.         if (!abort) {
  1109.             PrOpenPage(printerPort, nil);
  1110.  
  1111.             rectToClip = printView;
  1112.  
  1113.             if (pageCtr > 0)
  1114.                 rectToClip.bottom = rectToClip.top + (pageBounds[pageCtr]-pageBounds[pageCtr-1]);
  1115.             else
  1116.                 rectToClip.bottom = rectToClip.top + pageBounds[pageCtr];
  1117.  
  1118.             ClipRect(&rectToClip);
  1119.  
  1120.             if (PrError() == iPrAbort)
  1121.                 abort = true;
  1122.  
  1123.             if (! abort)
  1124.                 TEUpdate(&printView, printerTE);
  1125.  
  1126.             if (PrError() == iPrAbort)
  1127.                 abort = true;
  1128.  
  1129.             PrClosePage(printerPort);
  1130.  
  1131.             TEScroll(0,rectToClip.top-rectToClip.bottom, printerTE);
  1132.         }
  1133.  
  1134.     TEDispose(printerTE);
  1135.     PrCloseDoc(printerPort);
  1136.  
  1137.     if (( (*(theDoc->thePrintSetup))->prJob.bJDocLoop == bSpoolLoop ) &&
  1138.             ( PrError() == noErr )  &&
  1139.             (! abort))
  1140.         PrPicFile( theDoc->thePrintSetup, nil, nil, nil, &thePrinterStatus);
  1141.  
  1142.     PrClose();
  1143.  
  1144.     DisposDialog(progressDialog);
  1145.  
  1146. done:
  1147.     SetPort(oldPort);
  1148.     UseResFile(resFile);
  1149.     InvalRect(&oldPort->portRect);
  1150. }
  1151.  
  1152. void ForceStatusRedraw(WindowPtr win)
  1153. {
  1154.     GrafPtr    oldPort;
  1155.     Rect        r;
  1156.     
  1157.     GetPort(&oldPort);
  1158.     SetPort(win);
  1159.  
  1160.     r = win->portRect;
  1161.     
  1162.     r.right = 30;
  1163.     r.top   = r.bottom - 13;
  1164.     
  1165.     InvalRect(&r);
  1166.     
  1167.     SetPort(oldPort);
  1168. }
  1169.  
  1170. pascal void ShowWindowStatus()
  1171. {
  1172.      DPtr           aDocument;
  1173.     WindowPeek    aWindow;
  1174.     WindowPeek    nextWindow;
  1175.     short            curState;
  1176.  
  1177.     for (aWindow = (WindowPeek) FrontWindow(); aWindow; aWindow = nextWindow) {
  1178.         nextWindow = aWindow->nextWindow;
  1179.         if (Ours((WindowPtr) aWindow)) {
  1180.             aDocument = DPtrFromWindowPtr((WindowPtr) aWindow);
  1181.  
  1182.             if (aDocument->kind == kDocumentWindow) 
  1183.                 curState = stateDocument + stateRdWr;
  1184.             else {
  1185.                 curState = stateConsole;
  1186.                 if (aDocument->u.cons.fence == 32767)
  1187.                     curState    += stateRdOnly;
  1188.                 else if (!gRunningPerl || !aDocument->u.cons.selected)
  1189.                     curState += stateBlocked;
  1190.                 else
  1191.                     curState += stateRdWr;
  1192.             }
  1193.             
  1194.             if (curState != aDocument->lastState) {
  1195.                 aDocument->lastState = curState;
  1196.                 ForceStatusRedraw((WindowPtr) aWindow);
  1197.             }
  1198.         }
  1199.     }
  1200. }
  1201.  
  1202. #ifndef RUNTIME
  1203. pascal void UseInlineInput(Boolean inline)
  1204. {
  1205.      DPtr           aDocument;
  1206.     WindowPeek    aWindow;
  1207.     WindowPeek    nextWindow;
  1208.  
  1209.     for (aWindow = (WindowPeek) FrontWindow(); aWindow; aWindow = nextWindow) {
  1210.         nextWindow = aWindow->nextWindow;
  1211.         if (Ours((WindowPtr) aWindow)) {
  1212.             aDocument = DPtrFromWindowPtr((WindowPtr) aWindow);
  1213.             if (aDocument->tsmDoc)
  1214.                 UseInputWindow(aDocument->tsmDoc, !inline);
  1215.         }
  1216.     }
  1217. }
  1218. #endif
  1219.  
  1220. pascal void DoShowWindow(WindowPtr win)
  1221. {
  1222.      WindowPeek    aWindow;
  1223.     WindowPeek    nextWindow;
  1224.  
  1225.     for (aWindow = (WindowPeek) FrontWindow(); aWindow; aWindow = nextWindow) {
  1226.         nextWindow = aWindow->nextWindow;
  1227.         if (Ours((WindowPtr) aWindow)) {
  1228.             goto done;
  1229.         }
  1230.     }
  1231.     
  1232.     SetLongMenus();
  1233. done:
  1234.     ShowWindow(win);
  1235. }
  1236.  
  1237. pascal void DoHideWindow(WindowPtr win)
  1238. {
  1239.      WindowPeek    aWindow;
  1240.     WindowPeek    nextWindow;
  1241.  
  1242.     HideWindow(win);
  1243.     
  1244.     for (aWindow = (WindowPeek) FrontWindow(); aWindow; aWindow = nextWindow) {
  1245.         nextWindow = aWindow->nextWindow;
  1246.         if (Ours((WindowPtr) aWindow)) {
  1247.             return;
  1248.         }
  1249.     }
  1250.     
  1251.     SetShortMenus();
  1252. }
  1253.  
  1254. pascal WindowPtr AlreadyOpen(FSSpec * spec, StringPtr name)
  1255. {
  1256.      DPtr           aDocument;
  1257.     WindowPeek    aWindow;
  1258.     WindowPeek    nextWindow;
  1259.     Str255        title;
  1260.  
  1261.     for (aWindow = (WindowPeek) FrontWindow(); aWindow; aWindow = nextWindow) {
  1262.         nextWindow = aWindow->nextWindow;
  1263.         if (Ours((WindowPtr) aWindow)) {
  1264.             aDocument = DPtrFromWindowPtr((WindowPtr) aWindow);
  1265.             if (aDocument->kind == kDocumentWindow && aDocument->u.reg.everSaved) {
  1266.                 if (SameFSSpec(spec, &aDocument->theFSSpec))
  1267.                     return (WindowPtr) aWindow;
  1268.             } else if (name) {
  1269.                 GetWTitle((WindowPtr) aWindow, title);
  1270.                 if (EqualString(title, name, false, true))
  1271.                     return (WindowPtr) aWindow;
  1272.             }
  1273.         }
  1274.     }
  1275.     
  1276.     return nil;
  1277. }
  1278.