home *** CD-ROM | disk | FTP | other *** search
/ AppleScript - The Beta Release / AppleScript - The Beta Release.iso / Development Tools / Sample Applications / MenuScripter 1.0d4.1 / MenuScripter Source / MSUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-24  |  16.1 KB  |  608 lines  |  [TEXT/MPS ]

  1. /*
  2.     MSUtils.c
  3.     
  4.     Version 1.0d4
  5.     
  6.     Copyright © Apple Computer UK Ltd. 1992
  7.     
  8.     All rights reserved.
  9.     
  10.     Produced by : UK Developer Technical Support
  11.     AppleLink   : UK.DTS
  12. */
  13.  
  14.  
  15. #include <PLStringFuncs.h>
  16. #include <Events.h>
  17. #include <Traps.h>
  18. #include <Dialogs.h>
  19. #include <Fonts.h>
  20. #include <Packages.h>
  21. #include <AppleEvents.h>
  22. #include "MSUtils.h"
  23.  
  24. /**-----------------------------------------------------------------------
  25.         Name:             LesserOf
  26.         Purpose:        Returns the Lesser of two longints.
  27.     -----------------------------------------------------------------------**/
  28. #pragma segment Utils
  29.         
  30. pascal long LesserOf(long A, long B)
  31.  {
  32.    if (A<B)
  33.        return(A);
  34.      else
  35.        return(B);
  36.  }   /*LesserOf*/
  37.             
  38. /**-----------------------------------------------------------------------
  39.         Name:             GreaterOf
  40.         Purpose:        Returns the Greater of two longints.
  41.     -----------------------------------------------------------------------**/
  42.     
  43. #pragma segment Utils
  44.         
  45. pascal long GreaterOf(long A, long B)
  46.  {
  47.    if (A>B)
  48.        return(A);
  49.      else
  50.        return(B);
  51.  }  /*GreaterOf*/
  52.             
  53. /**-----------------------------------------------------------------------
  54.         Name:             ShowError
  55.         Purpose:        Reports an error to the user as both string and number.
  56.     -----------------------------------------------------------------------**/
  57. #pragma segment Utils
  58.         
  59. pascal void ShowError(Str255  theError,
  60.                                           long    theErrorCode)
  61. {
  62.    short     alertResult;
  63.    Str255    theString;
  64.      OSErr     myErr;
  65.      
  66.      myErr = AEInteractWithUser(kAEDefaultTimeout, nil,nil);
  67.      
  68.      if (myErr == noErr)
  69.        {
  70.              SetCursor(&qd.arrow);
  71.              NumToString(theErrorCode, theString);
  72.              ParamText(theError, theString, "", "");
  73.              alertResult = Alert(300, nil);
  74.          }
  75. } /* ShowError */
  76.  
  77. /**-----------------------------------------------------------------------
  78.         Name:             Ours
  79.         Purpose:        Checks the frontmost window belongs to the app.
  80.     -----------------------------------------------------------------------**/
  81. #pragma segment Utils        
  82.     
  83. pascal Boolean Ours(WindowPtr aWindow)
  84.  {
  85.         if (aWindow)
  86.             if (((WindowPeek)aWindow)->windowKind == zoomDocProc)
  87.                 return(true);
  88.         return(false);
  89. } /* Ours */
  90.  
  91. /**-----------------------------------------------------------------------
  92.         Name:             SetShortMenus
  93.         Purpose:        Cuts the menus down to a minimum - Apple File Edit.
  94.                                 Greys out the unavailable options - used when no docs open
  95.     -----------------------------------------------------------------------**/
  96. #pragma segment Utils        
  97.  
  98. pascal void SetShortMenus()
  99.     DeleteMenu(mfontID);
  100.     DeleteMenu(sizeID);
  101.     DeleteMenu(styleID);
  102.     DeleteMenu(mscriptID);
  103.  
  104.     DisableItem(myMenus[fileM], fmClose);
  105.     DisableItem(myMenus[fileM], fmSave);
  106.     DisableItem(myMenus[fileM], fmSaveAs);
  107.     DisableItem(myMenus[fileM], fmRevert);
  108.     DisableItem(myMenus[fileM], fmPrint);
  109.     DisableItem(myMenus[fileM], fmPageSetUp);
  110.  
  111.     /* now the unnecessary items on the edit menu */
  112.                 
  113.     DisableItem(myMenus[editM], undoCommand);
  114.     DisableItem(myMenus[editM], cutCommand);
  115.     DisableItem(myMenus[editM], copyCommand);
  116.     DisableItem(myMenus[editM], clearCommand);
  117.     DisableItem(myMenus[editM], pasteCommand);
  118.     DisableItem(myMenus[editM], selectAllCommand);
  119.  
  120.     DrawMenuBar();
  121. }  /* SetShortMenus */
  122.  
  123. /**-----------------------------------------------------------------------
  124.         Name:             SetLongMenus
  125.         Purpose:        Reinstates the full menu bar - called when first document
  126.                     opened.
  127.     -----------------------------------------------------------------------**/
  128. #pragma segment Utils        
  129.  
  130. pascal void SetLongMenus()
  131.   {
  132.         InsertMenu(myMenus[fontM], 0);
  133.         InsertMenu(myMenus[sizeM], 0);
  134.         InsertMenu(myMenus[styleM], 0);
  135.         InsertMenu(myMenus[scriptM], 0);
  136.  
  137.         EnableItem(myMenus[fileM], fmClose);
  138.         EnableItem(myMenus[fileM], fmSave);
  139.         EnableItem(myMenus[fileM], fmSaveAs);
  140.         EnableItem(myMenus[fileM], fmRevert);
  141.         EnableItem(myMenus[fileM], fmPrint);
  142.         EnableItem(myMenus[fileM], fmPageSetUp);
  143.  
  144.         /* now the necessary items on the edit menu -
  145.             many other items fixed on each pass thru the main event
  146.             loop or before the window pulled down
  147.         */
  148.         
  149.         EnableItem(myMenus[editM], selectAllCommand);
  150.  
  151.         DrawMenuBar();
  152.     }  /* SetLongMenus */
  153.  
  154. /**-----------------------------------------------------------------------
  155.         Name:             SetStyleMenu
  156.         Purpose:        Sets the style menu checking to reflect the style of the
  157.                     first character of the current selection in the given
  158.                                 document.
  159.     -----------------------------------------------------------------------**/
  160. #pragma segment Utils        
  161.         
  162. pascal void SetStyleMenu(DPtr theDoc)
  163.   {
  164.     TextStyle        theTStyle;
  165.         short       contMode;
  166.         short       i;
  167.         
  168.         contMode = doFace;
  169.         
  170.         TEContinuousStyle(&contMode,&theTStyle,theDoc->theText);
  171.         
  172.         if ((contMode & doFace) != 0)
  173.             {
  174.                 CheckItem(myMenus[styleM], cPlain,     (theTStyle.tsFace == 0));
  175.                 CheckItem(myMenus[styleM], cBold,      (bold      & theTStyle.tsFace));
  176.                 CheckItem(myMenus[styleM], cItalic,    (italic    & theTStyle.tsFace));
  177.                 CheckItem(myMenus[styleM], cUnderline, (underline & theTStyle.tsFace));
  178.                 CheckItem(myMenus[styleM], cOutline,   (outline   & theTStyle.tsFace));
  179.                 CheckItem(myMenus[styleM], cShadow,    (shadow    & theTStyle.tsFace));
  180.                 CheckItem(myMenus[styleM], cCondense,  (condense  & theTStyle.tsFace));
  181.                 CheckItem(myMenus[styleM], cExtend,    (extend    & theTStyle.tsFace));
  182.           }
  183.         else
  184.             for (i=cPlain; i<= cExtend; i++)
  185.                 CheckItem(myMenus[styleM], i,     false);
  186.   }
  187.  
  188. /**-----------------------------------------------------------------------
  189.     Name:       SetSizeMenu
  190.     Purpose:    Outline all the items if the current font is an
  191.                 outline font. Check the size of the current selection
  192.   -----------------------------------------------------------------------**/
  193. #pragma segment Utils        
  194.  
  195. pascal void SetSizeMenu(DPtr theDoc)
  196.   {
  197.       short             i;
  198.         short                aSize;
  199.         short                max;
  200.     long                 theSize;
  201.     Str255        name;
  202.     Boolean       sizeinMenu;
  203.     Boolean       oldState;
  204.     Point         numer;
  205.     TextStyle        theStyle;
  206.         TEHandle    myText;
  207.         short       contMode;
  208.       
  209.     numer.h = 1;
  210.     numer.v = 1;
  211.  
  212.     myText = theDoc->theText;
  213.         
  214.         contMode = doSize+doFont;
  215.         
  216.         TEContinuousStyle(&contMode,&theStyle,theDoc->theText);
  217.         
  218.     sizeinMenu = false;
  219.     max = CountMItems(myMenus[sizeM]);
  220.         for (i = 1; i <= max - 5; i++)
  221.       {
  222.                 GetItem(myMenus[sizeM], i, &name);
  223.                 StringToNum(name, &theSize);
  224.                 aSize = (short)theSize;
  225.  
  226.                 if (RealFont(theStyle.tsFont, aSize) && (contMode & doFont) != 0) // there is only one font and this size exists
  227.                     SetItemStyle(myMenus[sizeM], i, outline);
  228.                 else
  229.                     SetItemStyle(myMenus[sizeM], i, 0);
  230.  
  231.                 if ((aSize == theStyle.tsSize) && (contMode & doSize) != 0)
  232.                     {
  233.                         sizeinMenu = true;
  234.                         CheckItem(myMenus[sizeM], i, true);
  235.                     }
  236.                 else
  237.                     CheckItem(myMenus[sizeM], i, false);
  238.             }
  239.         
  240.             /*
  241.                 if it's not a size in the menu,and there is only one size in the
  242.               selection range check the other item
  243.             */
  244.             
  245.             if (!sizeinMenu && (contMode & doSize) != 0)
  246.               CheckItem(myMenus[sizeM], max, true);
  247.             else
  248.                 CheckItem(myMenus[sizeM], max, false);
  249.  
  250.             /*if this is an outline font, set the rest of the items to outline style*/
  251.             /*RealFont will ensure that the sizes are outlined*/
  252.  
  253.             oldState = GetOutlinePreferred();
  254.             SetOutlinePreferred(true);
  255.             for (i = max-4; i <= max; i++)
  256.                 {
  257.                     if (IsOutline(numer, numer) && (contMode & doFont)!= 0)
  258.                         SetItemStyle(myMenus[sizeM], i, outline);
  259.                     else
  260.                         SetItemStyle(myMenus[sizeM], i, 0);
  261.                 }
  262.                 
  263.             SetOutlinePreferred(oldState);
  264.     }
  265.  
  266. /**-----------------------------------------------------------------------
  267.     Name:       SetEditMenu
  268.     Purpose:    Set the text of the edit menu according to the state of
  269.                                 current document.
  270.   -----------------------------------------------------------------------**/
  271.  
  272. #pragma segment Utils
  273.  
  274. pascal void SetEditMenu(DPtr theDoc)
  275.     {
  276.         if (theDoc->showBorders)
  277.             SetItem(myMenus[editM], cBorders, "\pHide Borders");
  278.         else
  279.             SetItem(myMenus[editM], cBorders, "\pShow Borders");
  280.     }  /* SetEditMenu */
  281.             
  282. /**-----------------------------------------------------------------------
  283.     Name:       SetFontMenu
  284.     Purpose:    Set the font menu according to the state of
  285.                                 current selection of the supplied document.
  286.   -----------------------------------------------------------------------**/
  287. #pragma segment Utils
  288.         
  289. pascal void SetFontMenu(DPtr theDoc)
  290.   {
  291.     MenuHandle        theMHandle;
  292.     short         theNumber;
  293.     short         i;
  294.     short                max;
  295.     Str255        name;
  296.     TextStyle     theStyle;
  297.         short         contMode;
  298.  
  299.         theMHandle = GetMHandle(mfontID);
  300.  
  301.         if (gFontMItem)
  302.       CheckItem(theMHandle, gFontMItem, false);
  303.             
  304.         max = CountMItems(theMHandle);
  305.  
  306.         contMode = doFont;
  307.         TEContinuousStyle(&contMode,&theStyle,theDoc->theText);
  308.  
  309.         gFontMItem = 0;
  310.         
  311.     if (contMode & doFont)
  312.             for (i=1; i<=max; i++)
  313.                 {
  314.                     GetItem(theMHandle, i, &name);
  315.                     GetFNum(name, &theNumber);
  316.                     if (theNumber == theStyle.tsFont)
  317.                         gFontMItem = i;
  318.                 }
  319.  
  320.     if (gFontMItem)
  321.       CheckItem(theMHandle, gFontMItem, true);
  322.             
  323.         SetSizeMenu(theDoc);
  324.         SetStyleMenu(theDoc);
  325.     }
  326.  
  327. /**-----------------------------------------------------------------------
  328.     Name:       GetTempFileName
  329.     Purpose:    Fills newstring with a temporary file name.
  330.   -----------------------------------------------------------------------**/
  331.  
  332. #pragma segment Utils
  333.  
  334. pascal void GetTempFileName(DPtr aDoc,
  335.                             Str255 newString)
  336.  
  337.     {
  338.        Str255        s;
  339.      Str255        fileName;
  340.  
  341.         if (aDoc->everSaved == false)
  342.           PLstrcpy(fileName, "\pTEXTra");
  343.         else
  344.             PLstrcpy(fileName, aDoc->theFileName);
  345.  
  346.     /*generate a unique(ish) temporary filename*/
  347.         
  348.         if (fileName[0] > 21)
  349.           fileName[0] = 21;
  350.                 
  351.         NumToString(TickCount(), s);
  352.         
  353.         PLstrcat(fileName, s);
  354.         
  355.         PLstrcpy(newString,fileName);
  356.     }
  357.  
  358. /**-----------------------------------------------------------------------
  359.     Name:       SetText
  360.     Purpose:    Sets the text of the supplied itemNo in aDialog to 
  361.                                 theString and select it.
  362.   -----------------------------------------------------------------------**/
  363.  
  364. #pragma segment Utils
  365.  
  366. pascal void SetText(DialogPtr aDialog,
  367.                     short     itemNo,
  368.                     Str255    theString)
  369.   {
  370.     Handle      itemHandle;
  371.     Rect        box;
  372.     short       kind;
  373.     TEHandle    theTEHandle;
  374.  
  375.         GetDItem(aDialog, itemNo, &kind, &itemHandle, &box);
  376.         SetIText(itemHandle, theString);
  377.         
  378.         theTEHandle = ((DialogPeek)aDialog)->textH;
  379.  
  380.         /*set all the text to be selected*/
  381.         if (theTEHandle)
  382.             TESetSelect(0, 255, theTEHandle);
  383.     }
  384.             
  385. /**-----------------------------------------------------------------------
  386.     Name:       RetrieveText
  387.     Purpose:    Returns the text of anItem in aDialog in aString.
  388.   -----------------------------------------------------------------------**/
  389.  
  390. #pragma segment Utils
  391.  
  392. pascal void RetrieveText(DialogPtr aDialog,
  393.                                                short     anItem,
  394.                                                Str255    aString)
  395.   {
  396.      short      kind;
  397.      Rect       box;
  398.      Handle     itemHandle;
  399.  
  400.          GetDItem(aDialog, anItem, &kind, &itemHandle, &box);
  401.          GetIText(itemHandle, aString);
  402.   }
  403.  
  404. /**-----------------------------------------------------------------------
  405.     Name:       DrawDefaultOutline
  406.     Purpose:    Draws an outline around theItem.
  407.                                 Called as a useritem Proc by the dialog manager.
  408.                                 To use place a useritem over the default item in the
  409.                                 dialog and install the address of this proc as the item
  410.                                 handle.
  411.   -----------------------------------------------------------------------**/
  412.  
  413. #pragma segment Utils
  414.  
  415. pascal void DrawDefaultOutline(DialogPtr theDialog, short theItem)
  416.   {
  417.       short       kind;
  418.     Handle      itemHandle;
  419.     Rect        box;
  420.                 
  421.     GetDItem(theDialog, theItem, &kind, &itemHandle, &box);
  422.     PenSize(3, 3);
  423.     InsetRect(&box, - 4, - 4);
  424.     FrameRoundRect(&box, 16, 16);
  425.     PenNormal();
  426.         
  427.     }  /* DrawDefaultOutline */
  428.             
  429. /**-----------------------------------------------------------------------
  430.     Name:       AdornDefaultButton
  431.     Purpose:    Installs DrawDefaultOutline as the useritem proc
  432.                     for the given item.
  433.   -----------------------------------------------------------------------**/
  434.  
  435. #pragma segment Utils
  436.         
  437. pascal void AdornDefaultButton(DialogPtr theDialog,short theItem)
  438.   {
  439.       short       kind;
  440.     Handle      itemHandle;
  441.     Rect        box;
  442.  
  443.         GetDItem(theDialog, theItem, &kind, &itemHandle, &box);
  444.         SetDItem(theDialog, theItem, kind, (Handle)&DrawDefaultOutline, &box);
  445.   }
  446.  
  447.     /*-------  Determining of Gestalt is available ---------------*/
  448.     /*The following routines come from the Inside Mac VI recommendations*/
  449.     /*about how to find if a trap is available*/
  450.          /*
  451.             The glue for Gestalt will be in MPW 3.2, so if it is available we will also
  452.              need to check the system version
  453.         */
  454.  
  455. pascal void GetRectOfDialogItem(DialogPtr theDialog, short theItem, Rect *theRect)
  456.     {
  457.       short       kind;
  458.     Handle      itemHandle;
  459.         
  460.         GetDItem(theDialog, theItem, &kind, &itemHandle, theRect);
  461.     }
  462.  
  463. #pragma segment Utils
  464.  
  465. pascal short NumToolboxTraps()
  466.   {
  467.         if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  468.             return(0x200);
  469.         else
  470.             return(0x400);
  471.     }
  472.  
  473. #pragma segment Utils
  474.  
  475. #define TrapMask  0x0800
  476.  
  477. pascal TrapType GetTrapType(short theTrap)
  478.   {
  479.         if ((theTrap & TrapMask) > 0)
  480.             return(ToolTrap);
  481.         else
  482.             return(OSTrap);
  483.     }
  484.  
  485. #pragma segment Utils
  486.  
  487. pascal Boolean TrapAvailable(short theTrap)
  488.   {
  489.         TrapType  tType;
  490.  
  491.         tType = GetTrapType(theTrap);
  492.         if (tType == ToolTrap)
  493.             {
  494.                 theTrap = theTrap & 0x07FF;
  495.                 if (theTrap >= NumToolboxTraps())
  496.                     theTrap = _Unimplemented;
  497.             }
  498.         return(NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented,ToolTrap));
  499.     }
  500.  
  501. #pragma segment Utils
  502.  
  503. #define _Gestalt 0xA1AD
  504.  
  505. pascal Boolean GestaltAvailable()
  506.   {
  507.         return(TrapAvailable(_Gestalt));
  508.     }
  509.  
  510. /**------  FeatureIsImplemented    ------------**/
  511. /*This is called to use Gestalt to determine if a feature is implemented.
  512.  This applies to only those referenced by OSType*/
  513.  
  514. #pragma segment Utils
  515.  
  516. pascal Boolean FeatureIsImplemented(OSType  theFeature,
  517.                                                           short   theTestBit)
  518.   {
  519.     OSErr     err;
  520.     long      result;
  521.  
  522.         err = Gestalt(theFeature, &result);
  523.         if (err == noErr)
  524.             if ((result & theTestBit) == theTestBit)
  525.                 return(true);
  526.                 
  527.       return(false);
  528.     }
  529.  
  530. #pragma segment Utils
  531.  
  532. pascal Boolean CheckEnvironment()
  533.   {
  534.         /*
  535.          first determine of Gestalt is available- if it isn't exit
  536.          as we only run under 7.0.  It could it present in 6.04 - so we need
  537.          to do some further checks for important features
  538.         */
  539.  
  540.         gGestaltAvailable = GestaltAvailable();
  541.         
  542.         if (!gGestaltAvailable)
  543.             return(false);
  544.  
  545.     /*first check if the Edition Manager is present*/
  546.                 
  547.     gEditionManagerImplemented = FeatureIsImplemented(gestaltEditionMgrAttr,
  548.                                                                                                           gestaltEditionMgrPresent);
  549.  
  550.         /*and for good measure- the Alias manager*/
  551.                 
  552.         gAliasManagerImplemented  = FeatureIsImplemented(gestaltAliasMgrAttr,
  553.                                                                                                          gestaltAliasMgrPresent);
  554.             
  555.         /*check for the AppleEvents manager - we certainly can't work without it*/
  556.         
  557.         gAppleEventsImplemented   = FeatureIsImplemented(gestaltAppleEventsAttr,
  558.                                                                                                          gestaltAppleEventsPresent);
  559.             
  560.         /*check for the Outline fonts*/
  561.         
  562.         gOutlineFontsImplemented  = FeatureIsImplemented(gestaltFontMgrAttr,
  563.                                                                                                          gestaltOutlineFonts);
  564.         
  565.         return (gEditionManagerImplemented &&
  566.                         gAliasManagerImplemented   &&
  567.                         gAppleEventsImplemented    &&
  568.                         gOutlineFontsImplemented);
  569.                                 
  570.     }  /* CheckEnvironment */
  571.             
  572.     /*
  573.         DoPageSetup returns true if the page setup of the document is altered
  574.     */
  575.     
  576.     pascal Boolean DoPageSetup(DPtr theDoc)
  577.         {
  578.             Boolean result = false;
  579.                 
  580.                 if (theDoc)
  581.                     {
  582.                         PrOpen();
  583.                         result =  PrStlDialog(theDoc->thePrintSetup);
  584.                         PrClose();
  585.                     }
  586.                     
  587.                 return(result);
  588.         }  /* DoPageSetup */
  589.  
  590. /*
  591.     Name:    CtrlKeyPressed
  592.     Purpose: Returns true if control key pressed during event
  593. */
  594. pascal Boolean CtrlKeyPressed(const EventRecord *theEvent)
  595.     {
  596.         return((theEvent->modifiers & controlKey) != 0);
  597.     }
  598.     
  599. /*
  600.     Name:    OptionKeyPressed
  601.     Purpose: Returns true if option key pressed during event
  602. */
  603. pascal Boolean OptionKeyPressed(const EventRecord *theEvent)
  604.     {
  605.         return((theEvent->modifiers & optionKey) != 0);
  606.     }
  607.