home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / System Extensions / Macintosh Drag and Drop 1.1.1 / Demo Applications / DragText Sources / document.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-13  |  11.1 KB  |  484 lines  |  [TEXT/KAHL]

  1. /*
  2.  *
  3.  *        document.c
  4.  *
  5.  *        Document handling routines.
  6.  *        
  7.  *
  8.  *        Author:        Rob Johnston
  9.  *        Date:        Monday, February 10, 1992
  10.  *
  11.  *        Copyright © 1992 Apple Computer, Inc.
  12.  *
  13.  */
  14.  
  15.  
  16. #include <Drag.h>
  17. #include "globals.h"
  18. #include "prototypes.h"
  19. #include "resources.h"
  20.  
  21.  
  22. extern pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow,
  23.                                          void *handlerRefCon, DragReference theDrag);
  24.  
  25. extern pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, void *handlerRefCon,
  26.                                          DragReference theDrag);
  27.  
  28.  
  29. /*
  30.  *    AdjustDocumentView scrolls the document image by the appropriate amount
  31.  *    if the scroll bar value has changed.
  32.  */
  33.  
  34. void AdjustDocumentView(Document *theDocument)
  35.  
  36. {    short        delta, docTop, docTopLimit;
  37.  
  38.     delta = (theDocument->vScrollPos - GetCtlValue(theDocument->vScroll)) *
  39.                 ScrollResolution;
  40.  
  41.     if (delta) {
  42.         if (delta > 0) {
  43.             docTop = (**(theDocument->theTE)).destRect.top;
  44.             docTopLimit = (**(theDocument->theTE)).viewRect.top + TopMargin;
  45.             if (docTop + delta > docTopLimit) {
  46.                 delta = docTopLimit - docTop;
  47.             }
  48.         }
  49.         TEScroll(0, delta, theDocument->theTE);
  50.         theDocument->vScrollPos = GetCtlValue(theDocument->vScroll);
  51.     }
  52. }
  53.  
  54.  
  55. /*
  56.  *    AdjustScrollBar calculates the current position and maximum value of the
  57.  *    document's scroll bar given the current viewing position and document
  58.  *    text. This routine is called whenever the text is changed or the view
  59.  *    is auto-scrolled.
  60.  */
  61.  
  62. void AdjustScrollBar(Document *theDocument)
  63.  
  64. {    short        docTop, docBottom, viewTop, viewBottom;
  65.     short        offTop, offBottom;
  66.     RgnHandle    viewRgn;
  67.  
  68.     docTop = (**(theDocument->theTE)).destRect.top;
  69.     docBottom = docTop + TEGetHeight(32767, 0, theDocument->theTE);
  70.     viewTop = (**(theDocument->theTE)).viewRect.top;
  71.     viewBottom = (**(theDocument->theTE)).viewRect.bottom;
  72.  
  73.     offTop = ((viewTop - (docTop - TopMargin)) + ScrollResolution - 1) / ScrollResolution;
  74.     offBottom = (((docBottom + BottomMargin) - viewBottom) + ScrollResolution - 1) / ScrollResolution;
  75.     if (offTop < 0)
  76.         offTop = 0;
  77.     if (offBottom < 0)
  78.         offBottom = 0;
  79.  
  80.     theDocument->vScrollPos = offTop;
  81.  
  82.     SetCtlMax(theDocument->vScroll, offTop + offBottom);
  83.     SetCtlValue(theDocument->vScroll, offTop);
  84.  
  85.     viewRgn = NewRgn();
  86.     RectRgn(viewRgn, &(**(theDocument->theTE)).viewRect);
  87.     SectRgn(viewRgn, theDocument->hiliteRgn, theDocument->hiliteRgn);
  88.     DisposeRgn(viewRgn);
  89. }
  90.  
  91.  
  92. /*
  93.  *    This routine computes the size and location of the window's scroll bars
  94.  *    and the TextEdit field given the current size of the window. This routine
  95.  *    is called to initialize these components of the window and to update
  96.  *    the position of these components when the window is resized.
  97.  */
  98.  
  99. void PositionDocumentParts(Document *theDocument)
  100.  
  101. {    Rect        theRect;
  102.  
  103.     theRect = theDocument->theWindow->portRect;
  104.     theRect.left = theRect.right - 15;
  105.     theRect.right  += 1;
  106.     theRect.bottom -= 14;
  107.     theRect.top    -= 1;
  108.     (**(theDocument->vScroll)).contrlRect = theRect;
  109.  
  110.     theRect = theDocument->theWindow->portRect;
  111.     theRect.top = theRect.bottom - 15;
  112.     theRect.bottom += 1;
  113.     theRect.right  -= 14;
  114.     theRect.left   -= 1;
  115.     (**(theDocument->hScroll)).contrlRect = theRect;
  116.  
  117.     theRect = theDocument->theWindow->portRect;
  118.     theRect.right  -= 15;
  119.     theRect.bottom -= 15;
  120.     (**(theDocument->theTE)).viewRect = theRect;
  121.     (**(theDocument->theTE)).destRect.right = theRect.right - RightMargin;
  122.     TECalText(theDocument->theTE);
  123. }
  124.  
  125.  
  126. /*
  127.  *    NewDocument is called when a new document window is needed. Creation of
  128.  *    document data structures is handled here.
  129.  */
  130.  
  131. Document *NewDocument()
  132.  
  133. {    Document        *theDocument;
  134.     WindowPtr        theWindow;
  135.     Rect            theRect = { 0, 0, 16, 16 };
  136.     TextStyle        theStyle;
  137.     TEStyleHandle    theStyleHandle;
  138.     Point            thePoint;
  139. //    DragHandler        theHandler;
  140.     OSErr            result;
  141.  
  142.     if (gDocumentCount == MaxDocumentCount)
  143.         return((Document *) 0L);
  144.  
  145.     theDocument = gDocumentList[gDocumentCount++] =
  146.                             (Document *) NewPtr(sizeof(Document));
  147.  
  148.     theDocument->theWindow = theWindow = 
  149.                     GetNewWindow(WindowTemplateID, 0L, (WindowPtr) -1L);
  150.     ((WindowPeek) theWindow)->refCon = (long) theDocument;
  151.     SetPort(theWindow);
  152.  
  153.     thePoint = *((Point *) (&theWindow->portRect.top));
  154.     LocalToGlobal(&thePoint);
  155.     if (thePoint.h < 10) {
  156.         MoveWindow(theWindow, InitialH, InitialV, false);
  157.     }
  158.  
  159.     theDocument->vScroll = NewControl(theWindow, &theRect, "", true, 0, 0, 0,
  160.                                       scrollBarProc, (long) theDocument);
  161.     theDocument->hScroll = NewControl(theWindow, &theRect, "", true, 0, 0, 0,
  162.                                       scrollBarProc, (long) theDocument);
  163.  
  164.     theDocument->theTE = TEStylNew(&theRect, &theRect);
  165.     (**(theDocument->theTE)).destRect.top    = TopMargin;
  166.     (**(theDocument->theTE)).destRect.left   = LeftMargin;
  167.     (**(theDocument->theTE)).destRect.bottom = 32767;
  168.  
  169.     TEAutoView(true, theDocument->theTE);
  170.  
  171.     TEFeatureFlag(teFOutlineHilite, TEBitSet, theDocument->theTE);
  172.  
  173.     theDocument->hiliteRgn = NewRgn();
  174.     theStyleHandle = GetStylHandle(theDocument->theTE);
  175.     (**theStyleHandle).teRefCon = (long) theDocument;
  176.  
  177.     theStyle.tsFont = 21;
  178.     theStyle.tsSize = 12;
  179.     TESetStyle(doFont + doSize, &theStyle, false, theDocument->theTE);
  180.  
  181.     theDocument->vScrollPos = 0;
  182.     theDocument->fRefNum = 0;
  183.     theDocument->dirty = false;
  184.     theDocument->undoDragText = 0L;
  185.  
  186.     PositionDocumentParts(theDocument);
  187.  
  188.     InstallTrackingHandler(MyTrackingHandler, theWindow, (void *) theDocument);
  189.     InstallReceiveHandler(MyReceiveDropHandler, theWindow, (void *) theDocument);
  190.  
  191.     return(theDocument);
  192. }
  193.  
  194.  
  195. /*
  196.  *    CloseDocument is called when a document window is being closed. Storage
  197.  *    of the document file and disposal of document data structures is handled
  198.  *    here.
  199.  */
  200.  
  201. void CloseDocument(Document *theDocument)
  202.  
  203. {    short            result, index, response;
  204.     Str255            theName, theVerb;
  205.  
  206.     index = 0;
  207.     while ((gDocumentList[index] != theDocument) && (index < MaxDocumentCount))
  208.         index++;
  209.  
  210.     if (gDocumentList[index] == theDocument) {
  211.  
  212.         if (theDocument->dirty) {
  213.             GetWTitle(theDocument->theWindow, &theName);
  214.             GetIndString(&theVerb, FileStringsID, (gQuitting) ? slQuittingIndex : slClosingIndex);
  215.             ParamText(&theName, &theVerb, "", "");
  216.             SetCursor(&qd.arrow);
  217.             response = Alert(idSaveChangesALRT, 0L);
  218.  
  219.             if (response == 1) {            /* Save */
  220.                 if (! DoSaveDocument(theDocument)) {
  221.                     gQuitting = false;
  222.                     return;
  223.                 }
  224.             } else if (response == 3) {        /* Don't Save */
  225.                 ;
  226.             } else {                        /* Cancel */
  227.                 gQuitting = false;
  228.                 return;
  229.             }
  230.  
  231.         }
  232.  
  233.         if (theDocument->fRefNum) {
  234.             FSClose(theDocument->fRefNum);
  235.         }
  236.  
  237.         RemoveTrackingHandler(MyTrackingHandler, theDocument->theWindow);
  238.         RemoveReceiveHandler(MyReceiveDropHandler, theDocument->theWindow);
  239.  
  240.         DisposeRgn(theDocument->hiliteRgn);
  241.         TEDispose(theDocument->theTE);
  242.         DisposeWindow(theDocument->theWindow);
  243.  
  244.         if (theDocument->undoDragText) {
  245.             DisposHandle(theDocument->undoDragText);
  246.             theDocument->undoDragText = 0L;
  247.         }
  248.  
  249.         while (index < MaxDocumentCount) {
  250.             gDocumentList[index] = gDocumentList[index + 1];
  251.             index++;
  252.         }
  253.  
  254.         DisposPtr((Ptr) theDocument);
  255.         gDocumentCount--;
  256.     }
  257. }
  258.  
  259.  
  260. /*
  261.  *    DoActivateDocument is called when an event is received that reports that
  262.  *    a document window is being either activated or deactivated.
  263.  */
  264.  
  265. short DoActivateDocument(Document *theDocument, short activate)
  266.  
  267. {    WindowPtr        theWindow;
  268.  
  269.     if (theDocument) {
  270.         if (activate) {
  271.             TEActivate(theDocument->theTE);
  272.             HiliteControl(theDocument->vScroll, 0);
  273.             HiliteControl(theDocument->hScroll, 0);
  274.  
  275.             TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  276.  
  277.         } else {
  278.             TEDeactivate(theDocument->theTE);
  279.             HiliteControl(theDocument->vScroll, 255);
  280.             HiliteControl(theDocument->hScroll, 255);
  281.         }
  282.     }
  283. }
  284.  
  285.  
  286.  
  287. /*
  288.  *    Closes all document windows.
  289.  */
  290.  
  291. void CloseAllDocuments()
  292.  
  293. {
  294.     while (gDocumentCount) {
  295.         CloseDocument(gDocumentList[0]);
  296.     }
  297. }
  298.  
  299.  
  300. /*
  301.  *    If the given WindowPtr is a pointer to a document window, this function
  302.  *    returns a pointer to a document data structure. If the window is not
  303.  *    a document window, the function returns NULL.
  304.  */
  305.  
  306. Document *IsDocumentWindow(WindowPtr theWindow)
  307.  
  308. {    short        index = 0;
  309.     Document    *theDocument;
  310.  
  311.     theDocument = (Document *) (((WindowPeek) theWindow)->refCon);
  312.  
  313.     while ((gDocumentList[index] != theDocument) && (index < gDocumentCount))
  314.         index++;
  315.  
  316.     if (gDocumentList[index] == theDocument)
  317.         return(theDocument);
  318.     else
  319.         return((Document *) 0L);
  320. }
  321.  
  322.  
  323. /*
  324.  *    DoFontSelection is called when the user chooses a font from the font menu.
  325.  */
  326.  
  327. short DoFontSelection(short fontNumber)
  328.  
  329. {    TextStyle        theStyle;
  330.     WindowPtr        theWindow;
  331.     Document        *theDocument;
  332.  
  333.     if (theWindow = FrontWindow()) {
  334.         if (theDocument = IsDocumentWindow(theWindow)) {
  335.             theStyle.tsFont = fontNumber;
  336.             TESetStyle(doFont, &theStyle, true, theDocument->theTE);
  337.         }
  338.     }
  339. }
  340.  
  341.  
  342. /*
  343.  *    DoSizeSelection is called when the user selects a font size from the
  344.  *    Size menu.
  345.  */
  346.  
  347. short DoSizeSelection(short fontSize)
  348.  
  349. {    TextStyle        theStyle;
  350.     WindowPtr        theWindow;
  351.     Document        *theDocument;
  352.  
  353.     if (theWindow = FrontWindow()) {
  354.         if (theDocument = IsDocumentWindow(theWindow)) {
  355.             theStyle.tsSize = fontSize;
  356.             TESetStyle(doSize, &theStyle, true, theDocument->theTE);
  357.         }
  358.     }
  359. }
  360.  
  361.  
  362. /*
  363.  *    DoStyleSelection is called when the user chooses a style from the
  364.  *    Style menu.
  365.  */
  366.  
  367. short DoStyleSelection(short styleItem)
  368.  
  369. {    TextStyle        theStyle;
  370.     WindowPtr        theWindow;
  371.     Document        *theDocument;
  372.  
  373.     if (theWindow = FrontWindow()) {
  374.         if (theDocument = IsDocumentWindow(theWindow)) {
  375.             theStyle.tsFace = 0;
  376.             if (styleItem > 1) {
  377.                 BitSet(&theStyle.tsFace, 9 - styleItem);
  378.                 TESetStyle(doFace + doToggle, &theStyle, true, theDocument->theTE);
  379.             } else {
  380.                 TESetStyle(doFace, &theStyle, true, theDocument->theTE);
  381.             }
  382.         }
  383.     }
  384. }
  385.  
  386.  
  387. /*
  388.  *    DoSelectAllDocument is called when the Select All menu command is chosen.
  389.  */
  390.  
  391. short DoSelectAllDocument(Document *theDocument)
  392.  
  393. {
  394.     if (theDocument) {
  395.         TESetSelect(0, 32767, theDocument->theTE);
  396.     }
  397. }
  398.  
  399.  
  400. /*
  401.  *    DisableUndoDrag is called when the last drag can no longer be undone.
  402.  *    This routine disposes of undo text allocations.
  403.  */
  404.  
  405. short DisableUndoDrag()
  406.  
  407. {    short            index;
  408.     Document        *theDoc;
  409.  
  410.     gCanUndoDrag = slCantUndo;
  411.  
  412.     index = gDocumentCount;
  413.     while (index--) {
  414.         theDoc = gDocumentList[index];
  415.         if (theDoc->undoDragText) {
  416.             DisposHandle(theDoc->undoDragText);
  417.             theDoc->undoDragText = 0L;
  418.         }
  419.     }
  420. }
  421.  
  422.  
  423. /*
  424.  *    DoUndoDrag is called when the user chooses Undo Drag.
  425.  */
  426.  
  427. short DoUndoDrag()
  428.  
  429. {    short            index, selStart, selEnd;
  430.     Document        *theDoc;
  431.     Handle            theText;
  432.     long            theSize;
  433.     WindowPtr        theWindow;
  434.     Rect            theRect;
  435.  
  436.     if (gCanUndoDrag != slCantUndo) {
  437.  
  438.         theWindow = 0L;
  439.         index = gDocumentCount;
  440.         while (index--) {
  441.             theDoc = gDocumentList[index];
  442.             SetPort(theDoc->theWindow);
  443.     
  444.             if (theText = theDoc->undoDragText) {
  445.  
  446.                 theDoc->undoDragText = (**theDoc->theTE).hText;
  447.                 (**theDoc->theTE).hText = theText;
  448.  
  449.                 TECalText(theDoc->theTE);
  450.  
  451.                 selStart = theDoc->undoSelStart;
  452.                 selEnd   = theDoc->undoSelEnd;
  453.                 TESetSelect(selStart, selEnd, theDoc->theTE);
  454.                 theDoc->undoSelStart = theDoc->lastSelStart;
  455.                 theDoc->undoSelEnd   = theDoc->lastSelEnd;
  456.                 theDoc->lastSelStart = selStart;
  457.                 theDoc->lastSelEnd   = selEnd;
  458.  
  459.                 theRect = theDoc->theWindow->portRect;
  460.                 theRect.right  -= 15;
  461.                 theRect.bottom -= 15;
  462.                 EraseRect(&theRect);
  463.                 TEUpdate(&theRect, theDoc->theTE);
  464.             }
  465.         }
  466.  
  467.         if (gCanUndoDrag == slUndoDrag)
  468.             gCanUndoDrag = slRedoDrag;
  469.         else
  470.             gCanUndoDrag = slUndoDrag;
  471.  
  472.         theWindow = gUndoFrontmost;
  473.         gUndoFrontmost = gLastFrontmost;
  474.         gLastFrontmost = theWindow;
  475.     }
  476. }
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.