home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Frameworks / Hsoi's App Shell 1.0a4 / Hsoi's App Shell Source / HASMenus.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-28  |  50.1 KB  |  2,087 lines  |  [TEXT/CWIE]

  1. /*
  2.     HASMenus.c from Hsoi's App Shell. © 1995-1997 John C. Daub.  All rights reserved.
  3.     
  4.     This file deals with menus:  what to do when something is selected, adjusting
  5.     the menus, etc...if it's something to do with a menu, it's dealt with in
  6.     this file (more or less).
  7. */
  8.  
  9. #pragma mark ••• #includes •••
  10.  
  11. #ifndef _WASTE_
  12. #include "WASTE.h"
  13. #endif
  14. #include "WETabs.h"
  15. #ifndef _WASTEOBJECTS_
  16. #include "WASTE_Objects.h"
  17. #endif
  18. #include "HASGlobals.h"
  19. #ifndef __HSOIS_APP_SHELL__
  20. #include "HASMain.h"
  21. #endif
  22. #include "HASMenus.h"
  23. #include "HASMenuWindows.h"
  24. #include "HASDialogs.h"
  25. #include "HASUtilCursors.h"
  26. #include "HASHelp.h"
  27. #include "HASFiles.h"
  28. #include "HASMiscEvents.h"
  29. #include "HASPreferences.h"
  30. #include "HASWindows.h"
  31. #include "HASUtilities.h"
  32. #include "HASUtilPStrings.h"
  33. #include "HASPrinting.h"
  34. #include "HASSoundSpeech.h"
  35.  
  36. #if HAS_DEBUG
  37. #include "HASTest.h"
  38. #include "HASUtilTest.h"
  39. #endif
  40.  
  41. #pragma mark -
  42. #pragma mark ••• globals •••
  43.  
  44. static MenuCRsrcHandle    sColors;    // handle to the 'mctb' resource for the Color Menu
  45.  
  46.  
  47. #pragma mark -
  48. #pragma mark ••• Utility Routines •••
  49.  
  50. /*
  51.  *    HsoiEqualColor() does just that:  sees if 2 RGBColors are the same/equal
  52.  */
  53.  
  54.  
  55. Boolean    HsoiEqualColor( const RGBColor *rgb1, const RGBColor *rgb2 )
  56. {
  57.     return ( (rgb1->red == rgb2->red) && (rgb1->green == rgb2->green) && (rgb1->blue == rgb2->blue) );
  58. }
  59.  
  60.  
  61. /*
  62.  *    HsoiFindMenuItemText() will cycle through all the items in a given menu to find
  63.  *    some certain item.  Used to select fonts and font sizes.
  64.  */
  65.  
  66. short    HsoiFindMenuItemText( MenuRef menu, ConstStr255Param stringToFind )
  67. {
  68.     short        item;
  69.     Str255        itemString;
  70.     
  71.     for ( item = CountMenuItems( menu ); item >= 1; item-- )
  72.     {
  73.         GetMenuItemText( menu, item, itemString );
  74.         if ( EqualString( itemString, stringToFind, false, false ) )
  75.             break;
  76.     }
  77.     
  78.     return item;
  79. }
  80.  
  81.  
  82.  
  83.  
  84. /*    What this function does is make sure the font size menu works right and looks right.
  85.     Other functions deal with checkmarks and so forth, but what this will do is make
  86.     the Size menu's text be drawn in outline style or plain style.  Why do this?  Well,
  87.     A Size menu item displayed in outline style will let the user know that that size
  88.     is one that'll draw right.  With the advent of truetype and postscript fonts (and
  89.     other scalable fonts), this is probably outdated, but i'm sure people (i know i do)
  90.     will still have old bitmapped fonts lying around, so it'd be nice to know what
  91.     font sizes will look ok.
  92.     
  93.     Try it...find a bitmapped font that's on your system and find a truetype.  Select
  94.     the truetype from the Font menu...then check the size menu...everything (more or
  95.     less) should be in outline style.  Then, select the bitmapped font...only the
  96.     size(s) available of that bitmap should be in outline style.  For a further example,
  97.     check out TeachText/SimpleText...that works the same way, as probably does your
  98.     favorite word processing program (or it should)
  99. */
  100.  
  101. /*    Some "quirks" with this, which are also quirks with all the Text ment/sub-menu
  102.     things...if a range of text is selected (and also if that range might have
  103.     different attributes to it (different sizes, fonts, styles, etc.), stuff in the
  104.     text menus don't get checked, and the outlining of sizes i'm not 100% sure just
  105.     how it's determined, but i think it's done by whatever the first font in the
  106.     selection range is.  (like i typed some text...some in Monaco (TrueType)
  107.     and some in Adobe Garamond (didn't have a 9 point size, bitmap).  select all.
  108.     with the monaco stuff typed first (and first in the selection range), the size
  109.     menu drew all the sizes in outline.  but then i changed the monaco text to
  110.     garamond and vice versa, select all, and then the size menu drew in the
  111.     available sizes for garamond)
  112.     
  113.     According to Inside Macintosh (either Overview, Menus, or Text), you should try
  114.     to do more than just check things...like if 2 fonts are in a selection range,
  115.     use a hyphen - to show all the fonts that are in the active selection range.
  116.     
  117.     I'll probably work on that for a later release...if you get something working,
  118.     let me know!  I'd love to see the source!
  119. */
  120.  
  121.  
  122. void    HsoiMaintainFontMenu( void )
  123. {
  124.     MenuRef            menu;
  125.     short            numItems;
  126.     Boolean            temp;
  127.     short            mode = weDoFont; // get only the attributes we need...it'll save some processing time
  128.     TextStyle        ts;
  129.     WindowRef        window;
  130.     short            counter;
  131.     Str255            tempString;
  132.     long            theNumber;
  133.     
  134.     // get a window reference
  135.     
  136.     window = FrontWindow();
  137.     
  138.     //    we don't have to check what the front window is necessarily, cause the size
  139.     //    menu will only be able to be displayed if FrontWindow() == a window with a
  140.     //    WE instance...so, if the front window isn't as such, just return
  141.     //    (this is probably sloppy, but eh...) :\
  142.     
  143.     
  144.     
  145.     if ( ( window != nil ) && ( HsoiIsDocumentWindow( window ) ) )
  146.     {
  147.         //    get the style info associated with the WE instance
  148.         //    (this is being done similar to how Marco did the font/size/style/etc
  149.         //    menus in AdjustMenus()
  150.     
  151.         temp = WEContinuousStyle( (unsigned short *)&mode, &ts, HsoiGetWindowWE(window) );
  152.  
  153.         //    let's get ready to do the menu...
  154.         
  155.         //    i really shouldn't use constants (i.e. subtract 5 from the number of menu
  156.         //    items there are - for the "other" "smaller" "larger" and the 2 separator
  157.         //    lines) to make menu modification easier, but eh...
  158.         
  159.         //    furthermore, smaller, larger, and other should be outlined if these are
  160.         //    supported font sizes, e.g. it's a TrueType font.
  161.         
  162.         menu = GetMenuHandle( mSize );
  163.         
  164.         numItems = CountMenuItems( menu );
  165.         
  166.         //    here's the bad constant adjustment...
  167.         
  168.         numItems -= 5;
  169.         
  170.         //    now, go through all the menu items/font sizes, and see just which ones
  171.         //    to outline or not outline...gotta love RealFont().
  172.         
  173.         for ( counter = 1; counter <= numItems; counter++ )
  174.         {
  175.             GetMenuItemText( menu, counter, tempString );    // get the menu item text...
  176.             StringToNum( tempString, &theNumber );    // convert the menu item to a long
  177.             
  178.             // now, if that number size is a supported size, outline it, else plaintext.
  179.             // RealFont is the magic routine for this!
  180.             
  181.             if ( RealFont( ts.tsFont, theNumber ) )
  182.                 SetItemStyle( menu, counter, outline );
  183.             else
  184.                 SetItemStyle( menu, counter, kPlainStyle );
  185.         }
  186.         
  187.     } // it's not a WE window, so just return...
  188.     
  189.     else
  190.     {
  191.         return;
  192.     }
  193.     
  194.     return;
  195. }
  196.  
  197.  
  198. /*    This gets the menus created and up and running. */
  199.  
  200. void    HsoiSetUpMenus( void )
  201. {
  202.     Handle            menuBar = nil;
  203.     MenuRef            menu = nil;
  204.     short            count;
  205.     StringHandle    helpMenuString, endString;
  206.     
  207.     /*    With this menuBar stuff, do something to get the app's name from
  208.         the resource file...then change the About... name to it...e.g.
  209.         app name: The Killer App.  change menu item to: About The Killer App…
  210.  
  211.         remember to change the menu item properly to deal with meta chars
  212.     */
  213.     
  214.     #if HAS_DEBUG
  215.         menuBar = GetNewMBar( rTestMBAR );    //  Create the menu bar
  216.     #else
  217.         menuBar = GetNewMBar( rMenuBar );    // create the menu bar w/o testing stuff
  218.     #endif
  219.     
  220.     if ( menuBar )
  221.     {
  222.         SetMenuBar( menuBar );
  223.         HsoiForgetHandle( (Handle *)&menuBar );
  224.         AppendResMenu( GetMenuHandle( mApple ), TYPE_DESK_ACCESSORY ); // add Apple Menu Items
  225.         
  226.         menu = GetMenu( mFont );
  227.         AppendResMenu( menu, TYPE_FONT );
  228.         InsertMenu( menu, NOT_A_NORMAL_MENU );
  229.         
  230.         menu = GetMenu( mSize );
  231.         InsertMenu( menu, NOT_A_NORMAL_MENU );
  232.         
  233.         menu = GetMenu( mStyle );
  234.         InsertMenu( menu, NOT_A_NORMAL_MENU );
  235.         
  236.         menu = GetMenu( mJustification );
  237.         SetItemIcon( menu, iLeftAlign, rLeftJustIcon );
  238.         SetItemIcon( menu, iCenterAlign, rCenterJustIcon );
  239.         SetItemIcon( menu, iRightAlign, rRightJustIcon );
  240.         SetItemIcon( menu, iFullAlign, rFullJustIcon );
  241.         InsertMenu( menu, NOT_A_NORMAL_MENU );
  242.         
  243.         // load the menu color table for the color menu
  244.         
  245.         sColors = (MenuCRsrcHandle)GetResource( TYPE_MENU_COLOR_TABLE, mColor );
  246.         if ( ResError() != noErr )
  247.             return; //not the best error handling....
  248.             
  249.         // make sure this resource will not get purged..
  250.         
  251.         HNoPurge( (Handle)sColors );
  252.         
  253.         // and stick it in it's submenu place...
  254.         
  255.         menu = GetMenu( mColor );
  256.         InsertMenu( menu, NOT_A_NORMAL_MENU );
  257.         
  258.         // get the features menu up..
  259.         
  260.         menu = GetMenu( mFeatures );
  261.         InsertMenu( menu, NOT_A_NORMAL_MENU );
  262.         
  263.         menu = GetMenu( mHiliting );
  264.         InsertMenu( menu, NOT_A_NORMAL_MENU );
  265.         
  266.         // put our help stuff in the Help menu (the Balloon help thing in the upper right
  267.         // hand corner of the menu bar?)  Since we're running in System 7, help stuff
  268.         // should now always go under the help menu (not in the Apple Menu).  Your users
  269.         // will come to expect that
  270.         
  271.         // get the handle to the help menu
  272.         
  273.         HMGetHelpMenuHandle( &menu );
  274.         
  275.         // how many items are on it?
  276.         
  277.         count = CountMenuItems( menu );
  278.         
  279.         // the menu item's text will be the app's name + the word " Help..."
  280.         // get the app's name from the 'STR ' name resource (-16396)
  281.         
  282.         // get the name string
  283.         
  284.         helpMenuString = GetString( strAppNameString );
  285.         DetachResource( (Handle)helpMenuString );
  286.         
  287.         // append the " Help..." to it
  288.         
  289.         endString = GetString( strHelpMenuItemText );
  290.         DetachResource( (Handle)endString );
  291.         HsoiConcatString( *helpMenuString, *endString );
  292.         
  293.         // make sure it sticks around for the duration
  294.         
  295.         HNoPurge( (Handle)helpMenuString );
  296.         HLockHi( (Handle)helpMenuString );
  297.         
  298.         // add it to the help menu
  299.         
  300.         InsertMenuItem( menu, *helpMenuString, count + 1 );
  301.         
  302.         // it can go bye bye now if it wants to
  303.         
  304.         HUnlock( (Handle)helpMenuString );
  305.         HPurge( (Handle)helpMenuString );
  306.         
  307.         // remember what the help item number is for DoMenuCommand() stuff
  308.         
  309.         gHelpItem = CountMenuItems( menu );
  310.         
  311.         // set up the menus
  312.         
  313.         HsoiAdjustMenus();
  314.         
  315.         // draw the menu bar so all looks good :)
  316.         
  317.         DrawMenuBar();
  318.     }
  319.     else
  320.     {
  321.         HsoiDoError( rErrorStrings, errNoMenuBar, 0, kErrDeath );
  322.     }
  323.     
  324.     
  325.     return;
  326. }
  327.  
  328. #pragma mark -
  329. #pragma mark ••• Command Handler •••
  330.  
  331. /*
  332.  *    HsoiDoMenuCommand() is one of the most important functions in the shell.  Here
  333.  *    is where all the menu commands are dispatched from.
  334.  */
  335.  
  336.  
  337. void    HsoiDoMenuCommand( long menuResult )
  338. {
  339.     short                menuID;        // ID of selected menu
  340.     short                menuItem;    // item number in selected menu
  341.     Str255                daName, fontName;
  342.     TextStyle            ts;
  343.     WindowRef            window;
  344.     WEReference            we;
  345.     Point                where = { -1, -1 };
  346.     Str255                theWords = NIL_STRING;
  347.     RGBColor            newColor = { nil, nil, nil };
  348.     
  349.     //    menuResult is the value returned by MenuSelect().  From that, we can extract
  350.     //    which menu was selected (in the hi order bits), and which item in that menu
  351.     //    was selected (in the low order bits)
  352.     
  353.     menuID = HiWrd( menuResult );
  354.     menuItem = LoWrd( menuResult );
  355.     
  356.     // get the front window
  357.     
  358.     window = FrontWindow();
  359.     
  360.     // get the front window's associated WE instance
  361.     
  362.     we = HsoiGetWindowWE( window );
  363.     
  364.     //    now, a huge switch statement on which menu was selected.
  365.     
  366.     switch( menuID )
  367.     {
  368.         // the Apple menu.
  369.         
  370.         case mApple:
  371.         
  372.             switch( menuItem )
  373.             {
  374.                 case iAbout:    // display the about Box
  375.                 {
  376.                     HsoiDoAboutBox();                    
  377.                 }
  378.                 break;
  379.                 
  380.                 default:    // handle AppleMenuItem/DA selection
  381.                     GetMenuItemText( GetMenuHandle( mApple ), menuItem, daName );
  382.                     OpenDeskAcc( daName );
  383.                 break;
  384.             }
  385.         break;
  386.             // end case mApple
  387.         
  388.         
  389.         // the File menu
  390.         
  391.         case mFile:
  392.         
  393.             switch( menuItem )
  394.             {
  395.                 case iNew:
  396.                     HsoiCreateWindow( nil );
  397.                 break;
  398.                 
  399.                 case iOpen:
  400.                     HsoiDoOpen();
  401.                 break;
  402.                 
  403.                 case iClose:
  404.                     HsoiDoClose( closingWindow, savingAsk, window );
  405.                 break;
  406.             
  407.                 case iSave:
  408.                     
  409.                     HsoiDoSave( window );
  410.                     
  411.                 break;
  412.                 
  413.                 case iSaveAs:
  414.                     HsoiDoSaveAs( nil, window );
  415.                     
  416.                 break;
  417.                 
  418.                 case iRevert:
  419.                     HsoiDoRevert( window );
  420.                 break;
  421.                     
  422.                 case iPageSetup:
  423.                     HsoiDoPageSetup();                    
  424.                 break;
  425.                     
  426.                 case iPrint:
  427.                     HsoiDoPrint( window );
  428.                 break;
  429.                 
  430.                 case iPreferences:
  431.                     HsoiDoPrefsDialog();
  432.                 break;
  433.                 
  434.                 case iQuit:
  435.                     HsoiCleanUp( savingAsk );
  436.                 break;
  437.             }
  438.         break;
  439.         
  440.             // end case mFile
  441.         
  442.         // the Edit menu
  443.         
  444.         case mEdit:
  445.         
  446.             // if we don't have a window up at all, there's obviously nothing to
  447.             // edit, so just can things and leave.  but just in case the menuItem
  448.             // was iShowClipboard (in addition to window == nil), we need to let it
  449.             // fall through (Show Clipboard could still be a valid command)
  450.             
  451.             if ( (window == nil) && (menuItem != iShowClipboard) )
  452.                 break;
  453.             
  454.             switch( menuItem )
  455.             {                
  456.                 case iUndo:
  457.                 HsoiStartVBLSpinning();
  458.                     WEUndo( we );
  459.                 HsoiStopVBLSpinning();
  460.                 break;
  461.  
  462.             // since pasting/copying/cutting might take a long time (like if the scrap is HUGE)
  463.             // let's spin the cursor with my VBL cursor spinning.  if we didn't
  464.             // do this, cause WEPaste/WECut/WECopy can get intensive, the user might think
  465.             // their computer froze up.
  466.  
  467.                 
  468.                 case iCut:
  469.                     HsoiStartVBLSpinning();
  470.                     WECut( we );
  471.                     HsoiStopVBLSpinning();
  472.                 break;
  473.                 
  474.                 case iCopy:
  475.                     HsoiStartVBLSpinning();
  476.                     WECopy( we );
  477.                     HsoiStopVBLSpinning();
  478.                 break;
  479.                 
  480.                 case iPaste:
  481.                     HsoiStartVBLSpinning();
  482.                     //WEPaste( we );
  483.                     WEObjectsPaste( we );
  484.                     HsoiStopVBLSpinning();
  485.                 break;
  486.                 
  487.                 case iClear:
  488.                     HsoiStartVBLSpinning();
  489.                     WEDelete( we );
  490.                     HsoiStopVBLSpinning();
  491.                 break;
  492.                 
  493.                 case iSelectAll:
  494.                     WESetSelection( 0, MAXLONG, we );
  495.                 break;
  496.                 
  497.                 case iShowClipboard:
  498.                     HsoiShowClipboard();
  499.                 break;
  500.                 
  501.             }
  502.             
  503.             break;
  504.         
  505.             //    end case mEdit
  506.         
  507.         // this is if they select something from the Text menu.  There isn't much
  508.         // to do here since there really isn't anything on the Text menu to select
  509.         // (the entire menu just branches off into submenus, and it's from the submenus
  510.         // that stuff happens.  So, each submenu is handled further down in this function.
  511.         
  512.         case mText:
  513.         
  514.             switch( menuItem )
  515.             {
  516.                 case iFont:
  517.                 case iSize:
  518.                 case iStyle:
  519.                 case iJustification:
  520.                 case iColor:
  521.                 case iFeatures:
  522.                 {
  523.                     // don't do anything really...to deal with font/size/style/justification,
  524.                     // you need to deal with the associated submenu...we do that below
  525.                     
  526. //                    SysBeep(10);
  527.                 }
  528.                 break;
  529.             }
  530.             break;
  531.             
  532.             // end case mText
  533.         
  534.         
  535.         // so now, let's deal with each of those Text menu submenus.
  536.         
  537.         case mFont:
  538.         {            
  539.             // if we got a window, figure out the font they selected and change things.
  540.             
  541.             if ( window != nil )
  542.             {
  543.                 GetMenuItemText( GetMenuHandle( mFont ), menuItem, fontName );
  544.                 GetFNum( fontName, &ts.tsFont );
  545.                 WESetStyle( weDoFont, &ts, we );
  546.             }
  547.     
  548.         }
  549.         break;  // end case mFont
  550.         
  551.         
  552.         case mSize:
  553.         {
  554.             Str255        sizeString;
  555.             long        longSize;
  556.             short        mode;
  557.                         
  558.             if ( window != nil )
  559.             {
  560.                 if ( menuItem <= kSizeMenuLast ) // if they picked a number
  561.                 {
  562.                     GetMenuItemText( GetMenuHandle( mSize ), menuItem, sizeString );
  563.                     StringToNum( sizeString, &longSize );
  564.                     mode = weDoSize;
  565.                     ts.tsSize = longSize;
  566.                 }
  567.                 else if ( menuItem == iSizeSmaller )
  568.                 {
  569.                     mode = weDoAddSize;
  570.                     ts.tsSize = -1;
  571.                     longSize = 5; // arbitrary...just not 0
  572.                 }
  573.                 else if ( menuItem == iSizeLarger )
  574.                 {
  575.                     mode = weDoAddSize;
  576.                     ts.tsSize = +1;
  577.                     longSize = 5; // arbitrary....just not 0
  578.                 }
  579.                 else if ( menuItem == iSizeOther )
  580.                 {
  581.  
  582.                     longSize = HsoiDoOtherFontSize( window );
  583.                     
  584.                     if ( longSize != 0 )
  585.                     {
  586.                         ts.tsSize = longSize;
  587.                         mode = weDoSize;
  588.                     }
  589.                 }
  590.                 
  591.                 // all that stuff above went to figure out just what to do with
  592.                 // the font, and now we do it
  593.                 
  594.                 if ( longSize != 0 )
  595.                     WESetStyle( mode, &ts, we );
  596.             }
  597.         
  598.         
  599.         }
  600.         break;  // end case mSize
  601.         
  602.         
  603.         case mStyle:
  604.         {
  605.             
  606.             if ( window != nil )
  607.             {
  608.                 // figure out what face we want
  609.                 
  610.                 switch ( menuItem )
  611.                 {
  612.                     case iPlain:
  613.                         ts.tsFace = 0;
  614.                     break;
  615.                     
  616.                     case iBold:
  617.                         ts.tsFace = bold;
  618.                     break;
  619.                     
  620.                     case iItalic:
  621.                         ts.tsFace = italic;
  622.                     break;
  623.                     
  624.                     case iUnderline:
  625.                         ts.tsFace = underline;
  626.                     break;
  627.                     
  628.                     case iOutline:
  629.                         ts.tsFace = outline;
  630.                     break;
  631.                     
  632.                     case iShadow:
  633.                         ts.tsFace = shadow;
  634.                     break;
  635.                     
  636.                     case iCondensed:
  637.                         ts.tsFace = condense;
  638.                     break;
  639.                     
  640.                     case iExtended:
  641.                         ts.tsFace = extend;
  642.                     break;
  643.                             
  644.                 } // end switch menuItem (within case mStyle)
  645.         
  646.         
  647.             // and now set the face
  648.             
  649.             WESetStyle( weDoFace + weDoToggleFace, &ts, we );
  650.             
  651.             }     // end if ( window != nil )
  652.         
  653.         }
  654.         break;    // end case mStyle
  655.         
  656.         
  657.         case mJustification:
  658.         {
  659.             char    alignment;
  660.                         
  661.             if ( window != nil )
  662.             {
  663.                 // figure out what alignment they want
  664.                 
  665.                 switch ( menuItem )
  666.                 {
  667.                     case iDefaultJust:
  668.                         alignment = weFlushDefault;
  669.                     break;
  670.                     
  671.                     case iLeftAlign:
  672.                         alignment = weFlushLeft;
  673.                     break;
  674.                     
  675.                     case iCenterAlign:
  676.                         alignment = weCenter;
  677.                     break;
  678.                     
  679.                     case iRightAlign:
  680.                         alignment = weFlushRight;
  681.                     break;
  682.                     
  683.                     case iFullAlign:
  684.                         alignment = weJustify;
  685.                     break;
  686.  
  687.                 } // end switch( menuItem) within case mJustifiction
  688.             
  689.                 // set the alignment mode...this automatically redraws the text
  690.                 
  691.                 WESetAlignment( alignment, we );
  692.             
  693.             } // end if ( window != nil )
  694.         
  695.         
  696.         }
  697.         break; // end case mJustification
  698.         
  699.         
  700.         // how about neat-o colors?
  701.         
  702.         case mColor:
  703.         {
  704.             short            i;  // a counter variable
  705.             TextStyle        ts;
  706.                         
  707.             if ( window == nil)
  708.                 break;
  709.             
  710.             if ( HsoiIsDialogWindow(window))
  711.                 break;
  712.             
  713.             // find the color corresponding to the chosen menu item...
  714.  
  715.             // we subtract 1 from the (*sColors)->numEntries cause the
  716.             // 'mctb' resource really only has the 7 color entries.  the
  717.             // separator line and the "Other..." items are not part of
  718.             // the 'mctb' resource
  719.             // and the - 1 is so we can go to 0 for array happiness.
  720.             
  721.             for ( i = (*sColors)->numEntries - 1; i >= 0; i-- )
  722.             {
  723.                 if ( (*sColors)->mcEntryRecs[i].mctItem == menuItem )
  724.                 {
  725.                 
  726.                     // they picked a color from the menu
  727.                     
  728.                     ts.tsColor = (*sColors)->mcEntryRecs[i].mctRGB2;
  729.                     WESetStyle( weDoColor, &ts, we );
  730.                 }
  731.                 else if ( menuItem == iColorOther )
  732.                 {
  733.                     // they picked the "Other" item
  734.                     
  735.                     short        mode;
  736.                     TextStyle    tempTs;
  737.                     RGBColor    failed = { nil, nil, nil };
  738.                     
  739.                     // if there's a sound playing, stop it
  740.                     
  741.                     if ( SoundIsPlaying() )
  742.                         StopCurrentSound();
  743.                     
  744.                     // get the prompt string for the color picker dialog
  745.                     
  746.                     GetIndString( theWords, rGetColorStrings, strGetTextColor );
  747.                     
  748.                     // now to find the default color to display
  749.                     
  750.                     // with the advent of System 7.5 (or MacOS 7.5, whatever you want to
  751.                     // call it), there is a new system extension called the Color Picker.
  752.                     // the picker is a much more robust color wheel.  The neatest thing about
  753.                     // it is that it can be a movable modal dialog!  However, i've had a hard
  754.                     // time trying to find documentation on just how to use the picker
  755.                     // (but i do know the toolbox call is PickColor()).  We should use the
  756.                     // new picker, but until i figure it out....
  757.                     
  758.                     // however, if the user does have the Color Picker extension installed on
  759.                     // their system and the application calls GetColor(), GetColor() will
  760.                     // fall through and will call the new picker.  Of course, it'll be a
  761.                     // modal dialog...
  762.                     
  763.                     mode = weDoColor;
  764.                     WEContinuousStyle( (unsigned short *)&mode, &tempTs, we );
  765.                     
  766.                     // do the color dialog
  767.                     
  768.                     if ( GetColor( where, theWords,
  769.                                    ((mode & weDoColor) != 0 ? &tempTs.tsColor : &failed ), &newColor ) )
  770.                     
  771.                     // and based on it's outcome...
  772.                     
  773.                     {
  774.                         // we have a new color, so let's set the text right
  775.                         
  776.                         ts.tsColor = newColor;
  777.                         WESetStyle( weDoColor, &ts, we );
  778.                         HsoiDoUpdate( window ); // need to force an update
  779.                         goto byebye;
  780.                     }
  781.                     else // they canceled the GetColor dialog
  782.                     {
  783.                         HsoiDoUpdate( window ); // need for force and update
  784.                         goto byebye;
  785.                     }    
  786.                 } // end else if iColorOther
  787.             
  788.             } // end for loop    
  789.         
  790.         }
  791.         break; // end case mColor
  792.         
  793.         
  794.         case mFeatures:
  795.         {
  796.             short        feature, oldSetting;
  797.                         
  798.             if (window == nil)
  799.                 break;
  800.             
  801.             if ( HsoiIsDialogWindow(window) )
  802.                 break;
  803.             
  804.             switch( menuItem )
  805.             {
  806.                 case iTabHooks:
  807.                 {
  808.                     // install or remove our custom tab hooks
  809.                     
  810.                     if ( WEIsTabHooks( we ) == false )
  811.                     {
  812.                         // left-align the text (hooks only work with left-aligned text)
  813.                         
  814.                         WESetAlignment( weFlushLeft, we );
  815.                         
  816.                         // install them
  817.                         
  818.                         WEInstallTabHooks( we );
  819.                         
  820.                     }
  821.                     else
  822.                     {
  823.                         // remove them
  824.                         
  825.                         WERemoveTabHooks( we );
  826.                     }
  827.                     
  828.                     
  829.                     // turn the cursor into a wristwatch (this might be a nice place
  830.                     // to have a VBL spinning cursor instead...WECalText can take a while
  831.                     // to perform)
  832.                     
  833.                     SetCursor( *gWaitCursor );
  834.                     
  835.                     // recalculate the line breaks and redraw the text
  836.                     
  837.                     WECalText( we );
  838.                     
  839.                 
  840.                 }// end case iTabHooks
  841.                 
  842.                 break;
  843.                 
  844.                 // take care of other features
  845.                 
  846.                 case iAutoScroll:
  847.                     feature = weFAutoScroll;
  848.                 break;
  849.                 
  850.                 case iOutlineHilite:
  851.                     feature = weFOutlineHilite;
  852.                 break;
  853.                 
  854.                 case iReadOnly:
  855.                     feature = weFReadOnly;
  856.                 break;
  857.                 
  858.                 case iIntelligentCutAndPaste:
  859.                     feature = weFIntCutAndPaste;
  860.                 break;
  861.                 
  862.                 case iDragAndDropEditing:
  863.                     feature = weFDragAndDrop;
  864.                 break;
  865.                 
  866.                 case iOffscreenDrawing:
  867.                     feature = weFDrawOffscreen;                
  868.         
  869.             } // end switch ( menuItem ) in case mFeatures
  870.             
  871.             // toggle the specified feature
  872.             
  873.             if ( menuItem != iTabHooks )  // don't do it for tab hooks
  874.                 oldSetting = WEFeatureFlag( feature, weBitToggle, we );
  875.             
  876.         }
  877.         break; // end case mFeatures:
  878.         
  879.         case mDialogs:
  880.             switch( menuItem )
  881.             {
  882.                 case iModal:
  883.                     HsoiDoModalDialog();
  884.                 break;
  885.                 
  886.                 case iModeless:
  887.                     HsoiDoModelessDialog();
  888.                 break;
  889.                 
  890.                 case iMovable:
  891.                     HsoiDoMovableModalDialog();
  892.                 break;
  893.             }
  894.             break;
  895.             
  896.             // end case mDialogs
  897.         
  898.         case mWindows:
  899.         
  900.             switch( menuItem )
  901.             {
  902.                 case iTileWindows:
  903.                     HsoiDoTileWindows();
  904.                 break;
  905.                 
  906.                 case iStackWindows:
  907.                     HsoiDoStackWindows();
  908.                 break;
  909.                 
  910.                 // normally, we don't care about the seperator lines cause
  911.                 // they remain disabled..but since we use a "default" to handle
  912.                 // all the windows in the menu, we need to make sure we cover
  913.                 // this one just in case something funky happens...don't want this
  914.                 // getting passed to HsoiDoSelectFromWindowsMenu().  besides, all
  915.                 // we do is break.
  916.                 
  917.                 case iWindowMenuSeperator:
  918.                 break;
  919.                 
  920.                 // and by using "default", we can handle any menu item in the window's
  921.                 // menu, no matter how many windows/menu-items there might be
  922.                 
  923.                 default:
  924.                     HsoiDoSelectFromWindowsMenu( menuItem );
  925.                 break;
  926.                 
  927.             }
  928.             
  929.         break; // end case mWindows
  930.         
  931.         // all the sound stuff is currently partially implimented.  You can create the
  932.         // new sound objects fine, but i've run into problems in trying to get the
  933.         // current sound to stop playing.  It might be my code, it might be Kamprath's
  934.         // code.  I've tried contacting Michael about this, but so far, nothing
  935.         // figured out.
  936.         
  937.         
  938.         case mSound:
  939.         {
  940.             
  941.             switch( menuItem )
  942.             {
  943.                 // sounds...all use Michael Kamprath's WASTE Object Handler Library
  944.                 case iRecordNewSnd:
  945.                     // first, make sure no sounds are playing
  946.                     HsoiDoStop();
  947.                     // now create the new sound
  948.                     CreateNewSoundObject( we );
  949.                 break;
  950.                 
  951.                 case iPlaySnd:
  952.                     PlaySelectedSound( we );
  953.                 break;
  954.                 
  955.                 case iStopPlayingSnd:
  956.                     StopCurrentSound();
  957.                 break;
  958.  
  959.                 // text to speech stuff
  960.                 
  961.                 case iSpeakAll:
  962.                     HsoiDoReadDoc( window );
  963.                 break;
  964.                 
  965.                 case iSpeakFromCursor:
  966.                     HsoiDoReadFromCursor( window );
  967.                 break;
  968.                 
  969.                 case iSpeakSelection:
  970.                     HsoiDoReadSelection( window );
  971.                 break;
  972.                 
  973.                 case iStopSpeaking:
  974.                     HsoiDoStop();
  975.                 break;
  976.                 
  977.                 case iPauseSpeaking:
  978.                     HsoiDoPause();
  979.                 break;
  980.                 
  981.                 case iTurnSpeechOnOff:
  982.                     HsoiDoSpeechOnOff();
  983.                 break;
  984.                 
  985.                 case iAutoHiliting:
  986.                 // this should do nothing since it's a submenu
  987.                 break;
  988.             
  989.                 case iSpeechOptions:
  990.                     HsoiDoSpeechOptionsDialog();
  991.                 break;
  992.             
  993.             } // end switch(menuItem) in case mSound
  994.         }
  995.         break;    // end case mSound
  996.         
  997.         case mHiliting:
  998.             HsoiDoHiliteMenu( menuItem );
  999.         break;
  1000.         
  1001.         // end case mHiliting
  1002.         
  1003.         case kHMHelpMenuID:
  1004.             if ( menuItem == gHelpItem )
  1005.                 HsoiDoHelpStuff();
  1006.             
  1007.             break;
  1008.         
  1009. #if HAS_DEBUG
  1010.  
  1011.         case mTestMENU:
  1012.         {
  1013.             case iTestDoTest:
  1014.                 HsoiDoTest();
  1015.             break;
  1016.         }
  1017.         break;
  1018. #endif        
  1019.         
  1020.         
  1021.     }
  1022.  
  1023. byebye:  // for the goto statement
  1024.     
  1025.     HiliteMenu( 0 );
  1026.     
  1027.     return;
  1028. }
  1029.  
  1030.  
  1031.  
  1032. #pragma mark -
  1033. #pragma mark ••• Menu Adjustment •••
  1034.  
  1035. // our "public" menu adjuster routine.  call this whenever you need to have the
  1036. // menus get adjusted, and then from here, it'll dispatch and update the menus
  1037. // accordingly
  1038.  
  1039. void    HsoiAdjustMenus( void )
  1040. {
  1041.     WindowRef        window;
  1042.     Str255            itemString;
  1043.     
  1044.     // find out what window is in front (cause the menus's appearance is based (mostly)
  1045.     // upon the front window)
  1046.     
  1047.     window = FrontWindow();
  1048.     
  1049.     // by default the Undo menu item should read "Can't Undo" and be disabled
  1050.     
  1051.     GetIndString( itemString, rUndoStrings, strCantUndo );
  1052.     SetMenuItemText( GetMenuHandle( mEdit ), iUndo, itemString );
  1053.     DisableItem( GetMenuHandle( mEdit ), iUndo );
  1054.     
  1055.     // now let's see what we should do based upon FrontWindow()
  1056.     
  1057.     if ( window == nil )
  1058.     {
  1059.         // no windows at all, so adjust accordingly
  1060.         
  1061.         HsoiAdjustMenusNoWindow( window );
  1062.     }
  1063.     else if ( gInModalState )
  1064.     {
  1065.         // now if our gInModalState boolean is set, adjust accordingly
  1066.         // (gInModalState currently is set with the Help dialog, Other Font Size dialog,
  1067.         // and movable modal progress bar)
  1068.         
  1069.         if ( (DialogRef)window == gHelpDialog )
  1070.             HsoiAdjustMenusHelpDialog( window );
  1071.         else
  1072.             HsoiAdjustMenusDialog( window );
  1073.     }
  1074.     
  1075.     #if HAS_DEBUG
  1076.     
  1077.     else if ( window == gTestWindow )
  1078.     {
  1079.         HsoiAdjustMenusTestWindow( window );
  1080.     }
  1081.     
  1082.     #endif
  1083.     
  1084.     else if ( (DialogRef)window == gModelessDialog )
  1085.     {
  1086.         HsoiAdjustMenusFindDialog( window );
  1087.     }
  1088.     else if ( (DialogRef)window == gHelpDialog )
  1089.     {
  1090.         HsoiAdjustMenusHelpDialog( window );
  1091.     }
  1092.     else
  1093.     {
  1094.         switch ( GetWindowKind( window ) )
  1095.         {
  1096.             // handle our main document window.
  1097.             // we have our own unique windowKind for our document windows, but in case
  1098.             // we get (for some strange reason) a window with a userKind, let it get
  1099.             // handled in the same way.
  1100.             
  1101.             case userKind: // (same as kApplicationWindowKind)
  1102.             case kDocumentKind:
  1103.                 HsoiAdjustMenusDocumentWindow( window );
  1104.             break;
  1105.             
  1106.             // this handles "generic" dialogs (i.e. anything we don't want to
  1107.             // specifically handle ourselves)
  1108.             
  1109.             case dialogKind: // (same as kDialogWindowKind)
  1110.                 HsoiAdjustMenusDialog( window );
  1111.             break;
  1112.             
  1113.             // this adjusts things when the clipboard window is in front
  1114.             
  1115.             case kClipboardKind:
  1116.                 HsoiAdjustMenusClipboardWindow( window );
  1117.             break;        
  1118.         
  1119.         } // end: switch ( GetWindowKind( window ) )
  1120.     
  1121.     
  1122.     } // end: else (i.e. window != nil)
  1123.         
  1124.     DrawMenuBar();
  1125.     
  1126.     return;
  1127. }
  1128.  
  1129. void    HsoiAdjustMenusNoWindow( WindowRef window )
  1130. {
  1131.     MenuRef        menu;
  1132.     short        i;
  1133.     
  1134.     // Apple Menu -- enable it all
  1135.     
  1136.     menu = GetMenuHandle( mApple );
  1137.     
  1138.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1139.         EnableItem( menu, i );
  1140.     
  1141.     // File Menu  -- not much to do with no window...
  1142.     
  1143.     menu = GetMenuHandle( mFile );
  1144.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1145.         EnableItem( menu, i );
  1146.     
  1147.     DisableItem( menu, iClose );
  1148.     DisableItem( menu, iSave );
  1149.     DisableItem( menu, iSaveAs );
  1150.     DisableItem( menu, iRevert );
  1151.     DisableItem( menu, iPrint );
  1152.     
  1153.     // Edit Menu -- not much to do here either...
  1154.     
  1155.     menu = GetMenuHandle( mEdit );
  1156.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1157.         EnableItem( menu, i );
  1158.     
  1159.     DisableItem( menu, iUndo );
  1160.     DisableItem( menu, iCut );
  1161.     DisableItem( menu, iCopy );
  1162.     DisableItem( menu, iPaste );
  1163.     DisableItem( menu, iClear );
  1164.     DisableItem( menu, iSelectAll );
  1165.     
  1166.     // Text Menu (and it's submenus...cause this is pretty straight forward)
  1167.     // no window, nothing to do...disable them all!
  1168.     
  1169.     DisableItem( GetMenuHandle( mText ), 0 );
  1170.     DisableItem( GetMenuHandle( mFont ), 0 );
  1171.     DisableItem( GetMenuHandle( mSize ), 0 );
  1172.     DisableItem( GetMenuHandle( mStyle ), 0 );
  1173.     DisableItem( GetMenuHandle( mJustification ), 0 );
  1174.     DisableItem( GetMenuHandle( mColor ), 0 );
  1175.     DisableItem( GetMenuHandle( mFeatures ), 0 );
  1176.     
  1177.     // Dialogs Menu
  1178.     
  1179.     menu = GetMenuHandle( mDialogs );
  1180.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1181.         EnableItem( menu, i );
  1182.     
  1183.     // Windows menu -- no windows...it's moot!
  1184.     
  1185.     DisableItem( GetMenuHandle( mWindows ), 0 );
  1186.     HsoiAdjustWindowsMenu( window );
  1187.     
  1188.     // Sound menu
  1189.     
  1190.     HsoiAdjustSoundMenu( window );
  1191.     
  1192.     // Help menu
  1193.     
  1194.     HMGetHelpMenuHandle( &menu );
  1195.     
  1196.     if ( gHiliting )
  1197.         DisableItem( menu, 0 );
  1198.     else
  1199.     {
  1200.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1201.             EnableItem( menu, i );
  1202.     }
  1203.  
  1204. #if HAS_DEBUG
  1205.  
  1206.     // Test menu
  1207.     
  1208.     menu = GetMenuHandle( mTestMENU );
  1209.     if ( gHiliting )
  1210.         DisableItem( menu, 0 );
  1211.     else
  1212.     {
  1213.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1214.             EnableItem( menu, i );
  1215.     }
  1216.  
  1217. #endif        
  1218.  
  1219.     
  1220.     return;
  1221. }
  1222.  
  1223. void    HsoiAdjustMenusHelpDialog( WindowRef window )
  1224. {
  1225.     // pretty much disable everything since we're in a movable modal dialog.
  1226.     // however, due to the cool stuff we can do in our help menu, some editing
  1227.     // stuff might have to be enabled
  1228.  
  1229.     // however, until i get some funkyness worked out with the help dialog's
  1230.     // filter, we'll just call our generic dialog menu adjuster    
  1231.     
  1232.     HsoiAdjustMenusDialog( window );
  1233.  
  1234.     return;
  1235. }
  1236.  
  1237.  
  1238. // TESTING NOTE:  i think i can check to make sure this is called when the help dialog
  1239. // is up, the other font size, and/or the mmodal progress bar thing.  mostly, i'm
  1240. // curious to make sure the edit field check works
  1241.  
  1242. void    HsoiAdjustMenusDialog( WindowRef window )
  1243. {
  1244.     MenuRef        menu;
  1245.     short        i;
  1246.     
  1247.     // pretty much, everything ought to be disabled.  why?  well hopefully this
  1248.     // function will only be called when the window/dialog is a modal or movable modal
  1249.     // dialog, and we won't need many of the editing features, plus many things just
  1250.     // shouldn't be done when a dialog is up front (e.g. opening a new document window
  1251.     // just shouldn't be done).
  1252.     
  1253.     // one fun thing we do here is check for the presence of edit text items in the
  1254.     // dialog's DITL.  If there are, we can enable certain editing commands.
  1255.     
  1256.     // first, let's just disable everything...
  1257.     
  1258.     DisableItem( GetMenuHandle( mApple ), 0 );
  1259.     DisableItem( GetMenuHandle( mFile ), 0 );
  1260.     // skip the Edit menu
  1261.     DisableItem( GetMenuHandle( mText ), 0 );
  1262.     DisableItem( GetMenuHandle( mFont ), 0 );
  1263.     DisableItem( GetMenuHandle( mSize ), 0 );
  1264.     DisableItem( GetMenuHandle( mStyle ), 0 );
  1265.     DisableItem( GetMenuHandle( mJustification ), 0 );
  1266.     DisableItem( GetMenuHandle( mColor ), 0 );
  1267.     DisableItem( GetMenuHandle( mFeatures ), 0 );
  1268.     DisableItem( GetMenuHandle( mDialogs ), 0 );
  1269.     DisableItem( GetMenuHandle( mWindows ), 0 );
  1270.     HsoiAdjustWindowsMenu( window );
  1271.     HsoiAdjustSoundMenu( window );
  1272.     HMGetHelpMenuHandle( &menu );
  1273.     DisableItem( menu, 0 );
  1274.     
  1275. #if HAS_DEBUG
  1276.  
  1277.     DisableItem( GetMenuHandle( mTestMENU ), 0 );
  1278.  
  1279. #endif
  1280.     
  1281.     // and now, let's do our edit menu!
  1282.     
  1283.     menu = GetMenuHandle( mEdit );
  1284.         
  1285.     // let's see if the dialog has any edit fields...if so, then we can continue, else
  1286.     // we'll just disable the whole thing
  1287.     
  1288.     //•• Thinking about this some more, i wonder if this is really necessary....this
  1289.     // would be a "proper" way to check whether or not to enable the edit menu or
  1290.     // not for a dialog, but perhaps this ought to be something in the dialog's
  1291.     // filter instead of in here....
  1292.     
  1293.     if ( !gHiliting && (GetDialogKeyboardFocusItem( (DialogRef)window ) > 0) )
  1294.     {
  1295.     //    long    temp;
  1296.     
  1297.         // enable the whole menu
  1298.  
  1299.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1300.             EnableItem( menu, i );
  1301.         
  1302.         // now, we know there are some commands they just can't use
  1303.         
  1304.         DisableItem( menu, iUndo );
  1305.         DisableItem( menu, iShowClipboard );
  1306.         
  1307.         // and for now (while i write this thing), let's just leave the rest
  1308.         // (cut, copy, paste, clear, select all) to the dialog manager to deal
  1309.         // with...
  1310.         
  1311.         /*
  1312.             if ( HsoiHasSelectionRange( (DialogPeek)window ) )
  1313.             {
  1314.                 EnableItem( menu, iCut );
  1315.                 EnableItem( menu, iCopy );
  1316.                 EnableItem( menu, iClear );
  1317.             }
  1318.             
  1319.             // see if there's anything on the scrap to paste
  1320.             
  1321.             if ( GetScrap( nil, TYPE_TEXT, &temp ) )
  1322.                 EnableItem( menu, iPaste );
  1323.             
  1324.             // and for giggles, just enable select all
  1325.             
  1326.             EnableItem( menu, iSelectAll );
  1327.         
  1328.         
  1329.         */
  1330.     
  1331.     }
  1332.     else
  1333.     {
  1334.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1335.             DisableItem( menu, i );
  1336.                 
  1337.     }// end: if ( GetDialogKeyboardFocueItem( (DialogRef)window ) >= 0 )
  1338.     
  1339.     
  1340.     return;
  1341. }
  1342.  
  1343.  
  1344. void    HsoiAdjustMenusDocumentWindow( WindowRef window )
  1345. {
  1346.     MenuRef                menu;
  1347.     short                i;
  1348.     Str255                itemString, numString, workString;
  1349.     WEActionKind        actionKind;
  1350.     Boolean                temp;
  1351.     long                selStart, selEnd;
  1352.     TextStyle            ts;
  1353.     short                mode, item;
  1354.     short                menuItem;
  1355.     WEReference            we;
  1356.     
  1357.     // here's the fun one!  document windows!!!
  1358.     
  1359.     // since we know it's a document window, there will be a WE instance associated
  1360.     // with it.  let's grab it
  1361.     
  1362.     we = HsoiGetWindowWE( window );
  1363.     
  1364.     // Apple menu
  1365.     
  1366.     menu = GetMenuHandle( mApple );
  1367.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1368.         EnableItem( menu, i );
  1369.     
  1370.     // File menu
  1371.     
  1372.     menu = GetMenuHandle( mFile );
  1373.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1374.         EnableItem( menu, i );
  1375.     
  1376.     // if we have hit the max number of open document windows, we must disable New
  1377.     // and Open
  1378.     
  1379.     if ( gNumWindows >= kMaxNumberOfOpenWindows )
  1380.     {
  1381.         DisableItem( menu, iNew );
  1382.         DisableItem( menu, iOpen );
  1383.     }
  1384.     
  1385.     if ( WEGetModCount( we ) <= 0 )
  1386.     {
  1387.         DisableItem( menu, iSave );
  1388.         DisableItem( menu, iRevert );
  1389.     }
  1390.     
  1391.     // if the window is a new document, there is nothing to revert to
  1392.     
  1393.     if ( (*HsoiGetWindowDocument(window))->fileAlias == nil )
  1394.         DisableItem( menu, iRevert );
  1395.     
  1396.     // Edit menu
  1397.     
  1398.     // gotta remember read-onlys!
  1399.     
  1400.     menu = GetMenuHandle( mEdit );
  1401.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1402.         EnableItem( menu, i );
  1403.     
  1404.     // check for pastes
  1405.     
  1406.     if ( !WECanPaste( we ) )
  1407.         DisableItem( menu, iPaste );
  1408.     
  1409.     // get Undo all set right
  1410.     
  1411.     actionKind = WEGetUndoInfo( &temp, we );
  1412.     
  1413.     if ( actionKind != weAKNone )
  1414.     {
  1415.         // change the Undo menu item to "Undo/Redo" + name of action
  1416.         
  1417.         // the temp?1:0 thing is my attempt at replacing the pascal ORD() function
  1418.         // since this technique was taken from some Pascal source (perhaps it's not
  1419.         // even necessary, but it all works ok)
  1420.         
  1421.         GetIndString( itemString, rUndoStrings, 2 * actionKind + (temp ? 1 : 0) );
  1422.         SetMenuItemText( menu, iUndo, itemString );
  1423.     }
  1424.     else
  1425.     {
  1426.         DisableItem( menu, iUndo );
  1427.     }
  1428.     
  1429.     if ( WEGetTextLength( we ) <= 0 )
  1430.         DisableItem( menu, iSelectAll );
  1431.     
  1432.     WEGetSelection( &selStart, &selEnd, we );
  1433.     
  1434.     if ( selStart == selEnd )
  1435.     {
  1436.         DisableItem( menu, iCut );
  1437.         DisableItem( menu, iCopy );
  1438.         DisableItem( menu, iClear );
  1439.     }
  1440.     
  1441.     // and if we have read-only, make sure certain things are disabled
  1442.     
  1443.     if ( WEFeatureFlag( weFReadOnly, weBitTest, we ) )
  1444.     {
  1445.         DisableItem( menu, iUndo );
  1446.         DisableItem( menu, iCut );
  1447.         DisableItem( menu, iPaste );
  1448.         DisableItem( menu, iClear );
  1449.     }
  1450.     
  1451.     // Text menu
  1452.     
  1453.     // before we proceed, we need to determine which style attributes are continuous
  1454.     // over the current selection range (we need this information to check the
  1455.     // menus properly)
  1456.     
  1457.     mode = weDoAll;  // query about all attributes
  1458.     temp = WEContinuousStyle( (unsigned short *)&mode, &ts, we );
  1459.     
  1460.     menu = GetMenuHandle( mText );
  1461.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1462.         EnableItem( menu, i );
  1463.         
  1464.     // font submenu
  1465.     
  1466.     menu = GetMenuHandle( mFont );
  1467.     
  1468.     // if the window is read-only, disable it all, else enable it all
  1469.     
  1470.     if ( WEFeatureFlag( weFReadOnly, weBitTest, we ) )
  1471.     {
  1472.         DisableItem( menu, 0 );
  1473.     }
  1474.     else
  1475.     {
  1476.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1477.             EnableItem( menu, i );
  1478.     }
  1479.     
  1480.     // remove all the check marks
  1481.     
  1482.     for ( i = CountMenuItems( menu ); i >= 1; i-- )
  1483.         CheckItem( menu, i, false );
  1484.     
  1485.     // and if there is a continuous font over the selection range, check that item
  1486.     
  1487.     if ( (mode & weDoFont) != 0 )
  1488.     {
  1489.         GetFontName( ts.tsFont, itemString );
  1490.         CheckItem( menu, HsoiFindMenuItemText( menu, itemString ), true );
  1491.     }
  1492.     
  1493.     // Size submenu
  1494.     
  1495.     menu = GetMenuHandle( mSize );
  1496.     
  1497.     // again, if read only, disable the whole thing
  1498.     
  1499.     if ( WEFeatureFlag( weFReadOnly, weBitTest, we ) )
  1500.     {
  1501.         DisableItem( menu, 0 );
  1502.     }
  1503.     else
  1504.     {
  1505.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1506.             EnableItem( menu, i );
  1507.     }
  1508.     
  1509.     // remove the check marks
  1510.     
  1511.     for ( i = CountMenuItems( menu ); i >= 1; i-- )
  1512.         CheckItem( menu, i, false );
  1513.     
  1514.     // NOTE!  All this stuff with the font Size menu dealing with the "Other"
  1515.     // size menu item is as per Apple's "Macintosh Human Interface Guidelines"
  1516.     // (for once, I follow them) :)  It all seems strange, but it's what
  1517.     // should be done to be "proper". and perhaps there might be an easier
  1518.     // way to do this, but for now, this works fine
  1519.     
  1520.     // i ought to do this same sort of thing for the Font, Style, and Color
  1521.     // menus also (put hash marks or something to indicate multiple stuff)
  1522.     // (Ok, Style sorta does this, but if there are multiple styles, we should
  1523.     // have hash marks and not check marks....
  1524.     
  1525.     // if there is a continuous font size all over the selection range,
  1526.     // check the corresponding menu item
  1527.     
  1528.     if ( (mode & weDoSize) != 0 )
  1529.     {
  1530.         NumToString( ts.tsSize, itemString );
  1531.         menuItem = HsoiFindMenuItemText( menu, itemString );
  1532.         
  1533.         // if menuItem is 0, we didn't find the item, so we'll assume that it's
  1534.         // not a "supported" font size (9, 10, 12, 14, 18, 24, 36, 48... the sizes
  1535.         // in the size menu), therefore we should check the "Other" item.
  1536.         // Furthermore, this "odd" font size should be displayed in the Other
  1537.         // item's text...try it...you'll see what I mean
  1538.     
  1539.         if ( menuItem != 0 )
  1540.         {
  1541.             CheckItem( menu, menuItem, true );
  1542.             GetIndString( itemString, rOtherSizeStrings, strOtherSizeOtherOnly );
  1543.             SetMenuItemText( menu, CountMenuItems( menu ), itemString );
  1544.         }
  1545.         else
  1546.         {
  1547.             CheckItem( menu, CountMenuItems( menu ), true );
  1548.             GetIndString( itemString, rOtherSizeStrings, strOtherSizeOtherSpace );
  1549.             GetIndString( workString, rOtherSizeStrings, strOtherSizeLeftParen );
  1550.             HsoiConcatString( itemString, workString );
  1551.             NumToString( ts.tsSize, numString );
  1552.             HsoiConcatString( itemString, numString );
  1553.             GetIndString( workString, rOtherSizeStrings, strOtherSizeRightParen );
  1554.             HsoiConcatString( itemString, workString );
  1555.             
  1556.             SetMenuItemText( menu, CountMenuItems( menu ), itemString );
  1557.         }
  1558.     }
  1559.     else // not one continuous size
  1560.     {
  1561.         GetIndString( itemString, rOtherSizeStrings, strOtherSizeMixed );
  1562.         SetMenuItemText( menu, CountMenuItems( menu ), itemString );
  1563.         CheckItem( menu, CountMenuItems( menu ), true );
  1564.     }
  1565.     
  1566.     // Style submenu
  1567.  
  1568.     menu = GetMenuHandle( mStyle );
  1569.  
  1570.     if ( WEFeatureFlag( weFReadOnly, weBitTest, we ) )
  1571.         DisableItem( menu, 0 );
  1572.     else
  1573.     {
  1574.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1575.             EnableItem( menu, i );
  1576.     }
  1577.     
  1578.     for ( i = CountMenuItems( menu ); i >= 1; i-- )
  1579.         CheckItem( menu, i, false );
  1580.     
  1581.     if ( (mode & weDoFace) != 0 )
  1582.     {
  1583.         if ( ts.tsFace == 0 )
  1584.             CheckItem( menu, iPlain, true );
  1585.         if ( ts.tsFace & bold )
  1586.             CheckItem( menu, iBold, true );
  1587.         if ( ts.tsFace & italic )
  1588.             CheckItem( menu, iItalic, true );
  1589.         if ( ts.tsFace & underline )
  1590.             CheckItem( menu, iUnderline, true );
  1591.         if ( ts.tsFace & outline )
  1592.             CheckItem( menu, iOutline, true );
  1593.         if ( ts.tsFace & shadow )
  1594.             CheckItem( menu, iShadow, true );
  1595.         if ( ts.tsFace & condense )
  1596.             CheckItem( menu, iCondensed, true );
  1597.         if ( ts.tsFace & extend )
  1598.             CheckItem( menu, iExtended, true );
  1599.     }
  1600.  
  1601.     // Justification submenu
  1602.     
  1603.     menu = GetMenuHandle( mJustification );
  1604.     
  1605.     if ( WEFeatureFlag( weFReadOnly, weBitTest, we ) )
  1606.         DisableItem( menu, 0 );
  1607.     else
  1608.     {
  1609.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1610.             EnableItem( menu, i );
  1611.     }
  1612.     
  1613.     for ( i = CountMenuItems( menu ); i >= 1; i-- )
  1614.         CheckItem( menu, i, false );
  1615.     
  1616.     switch( WEGetAlignment( we ) )
  1617.     {
  1618.         case weFlushLeft:
  1619.             item = iLeftAlign;
  1620.         break;
  1621.         
  1622.         case weFlushRight:
  1623.             item = iRightAlign;
  1624.         break;
  1625.         
  1626.         case weFlushDefault:
  1627.             item = iDefaultJust;
  1628.         break;
  1629.         
  1630.         case weCenter:
  1631.             item = iCenterAlign;
  1632.         break;
  1633.         
  1634.         case weJustify:
  1635.             item = iFullAlign;
  1636.         break;
  1637.     }
  1638.     
  1639.     // check the menu item
  1640.     
  1641.     CheckItem( menu, item, true );
  1642.     
  1643.     // Color submenu
  1644.     
  1645.     menu = GetMenuHandle( mColor );
  1646.     
  1647.     // no color quickdraw, no color menu!
  1648.     
  1649.     if ( gHasColorQD )
  1650.     {
  1651.         if ( WEFeatureFlag( weFReadOnly, weBitTest, we ) )
  1652.             DisableItem( menu, 0 );
  1653.         else
  1654.         {
  1655.             for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1656.                 EnableItem( menu, i );
  1657.         }
  1658.             
  1659.         // remove the check marks
  1660.         
  1661.         for ( i = CountMenuItems( menu ); i >= 1; i-- )
  1662.             CheckItem( menu, i, false );
  1663.         
  1664.         /*    one thing to note about the color menu...
  1665.         
  1666.             the colors it picks not only to decide whether or not to check the
  1667.             menu item, but also the color it'll choose to draw text in is determined
  1668.             by the color of the menu item (so you could pick some strange shade of
  1669.             mauve in ResEdit when playing with the 'mctb' resource and you'll draw
  1670.             text in this color.)
  1671.             
  1672.             Now, if you open up a document that has a color that doesn't EXACTLY
  1673.             match the colors in the menu, the "Other" item should be checked,
  1674.             and when the color wheel is brought up, that color should be the
  1675.             "default" color in the wheel.
  1676.             
  1677.             Something that I didn't do, but probably might want to add (or you
  1678.             could add it..and it would go in HsoiAdjustMenus()) is that if
  1679.             there is another color as the default, draw the menu item text
  1680.             for "Other" in that color...sorta like how the Other font size menu
  1681.             item works...and if there were multiple/mixed colors in the selection
  1682.             range, just draw "other" in black.
  1683.             
  1684.         */
  1685.         
  1686.         if ( (mode & weDoColor) != 0 )
  1687.         {
  1688.             Boolean        otherColor = true;
  1689.             
  1690.             // for reasons why we subtract 1 from the numEntries, see the above
  1691.             // color handling stuff in DoMenuCommand()
  1692.             
  1693.             for ( i = (*sColors)->numEntries - 1; i >= 0; i-- )
  1694.             {
  1695.                 if ( HsoiEqualColor( &ts.tsColor, &(*sColors)->mcEntryRecs[i].mctRGB2 ) )
  1696.                 {
  1697.                     CheckItem( menu, (*sColors)->mcEntryRecs[i].mctItem, true );
  1698.                     otherColor = false;
  1699.                 }    
  1700.  
  1701.             } // end for loop
  1702.             
  1703.             if ( otherColor )
  1704.             {
  1705.                 // make sure there are no check marks anywhere
  1706.             
  1707.                 for ( i = CountMenuItems( menu ); i >= 1; i-- )
  1708.                 {
  1709.                     CheckItem( menu, i, false );
  1710.                 }
  1711.                 
  1712.                 // now check the Other menu
  1713.                 
  1714.                 CheckItem( menu, iColorOther, true );
  1715.             }            
  1716.                 
  1717.  
  1718.         }// end mode & weDoColor
  1719.         
  1720.     }
  1721.     else // no ColorQuickDraw
  1722.         DisableItem( menu, 0 );
  1723.         
  1724.     
  1725.     // Features submenu (this is getting long isn't it?)
  1726.     
  1727.     menu = GetMenuHandle( mFeatures );
  1728.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1729.         EnableItem( menu, i );
  1730.     
  1731.     // no removal of check marks here....the text of the menu items switches
  1732.     // depending on the state of the feature.  You could change this to having
  1733.     // just plain old check marks, but I like this way of doing things cause
  1734.     // it is a little more informative for the user, plus it can show you how
  1735.     // to change menu item text!
  1736.     
  1737.     if ( WEIsTabHooks( we ) )
  1738.     {
  1739.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureDisableTabHooks );
  1740.         SetMenuItemText( menu, iTabHooks, itemString );
  1741.  
  1742.         // tab hooks only work with left alignment, so don't allow this!        
  1743.         
  1744.         DisableItem( GetMenuHandle( mJustification ), 0 );
  1745.         DisableItem( GetMenuHandle( mText ), iJustification ); 
  1746.     }
  1747.     else
  1748.     {
  1749.         MenuRef    justMenu = GetMenuHandle( mJustification );
  1750.         
  1751.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureEnableTabHooks );
  1752.         SetMenuItemText( menu, iTabHooks, itemString );
  1753.         
  1754.         for ( i = 0; i <= CountMenuItems( justMenu ); i++ )
  1755.             EnableItem( justMenu, i );
  1756.             
  1757.         EnableItem( GetMenuHandle( mText ), iJustification );
  1758.     }
  1759.     
  1760.     if ( WEFeatureFlag( weFAutoScroll, weBitTest, we ) )
  1761.     {
  1762.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureDisableAutoScroll );
  1763.         SetMenuItemText( menu, iAutoScroll, itemString );
  1764.     }
  1765.     else
  1766.     {
  1767.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureEnableAutoScroll );
  1768.         SetMenuItemText( menu, iAutoScroll, itemString );
  1769.     }
  1770.         
  1771.     if ( WEFeatureFlag( weFOutlineHilite, weBitTest, we ) )
  1772.     {
  1773.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureDisableOutlineHilite );
  1774.         SetMenuItemText( menu, iOutlineHilite, itemString );
  1775.     }
  1776.     else
  1777.     {
  1778.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureEnableOutlineHilite );
  1779.         SetMenuItemText( menu, iOutlineHilite, itemString );
  1780.     }
  1781.     
  1782.     if ( WEFeatureFlag( weFReadOnly, weBitTest, we ) )
  1783.     {
  1784.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureDisableReadOnly );
  1785.         SetMenuItemText( menu, iReadOnly, itemString );
  1786.     }
  1787.     else
  1788.     {
  1789.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureEnableReadOnly );
  1790.         SetMenuItemText( menu, iReadOnly, itemString );
  1791.     }
  1792.     
  1793.     
  1794.     if ( WEFeatureFlag( weFIntCutAndPaste, weBitTest, we ) )
  1795.     {
  1796.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureDisableCutAndPaste );
  1797.         SetMenuItemText( menu, iIntelligentCutAndPaste, itemString );
  1798.     }
  1799.     else
  1800.     {
  1801.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureEnableCutAndPaste );
  1802.         SetMenuItemText( menu, iIntelligentCutAndPaste, itemString );
  1803.     }
  1804.                 
  1805.     // if the computer doesn't support Drag and Drop, we gotta dim this
  1806.     
  1807.     if ( gHasDragAndDrop )
  1808.     {
  1809.         // make sure the item is enabled
  1810.         
  1811.         EnableItem( menu, iDragAndDropEditing );
  1812.     
  1813.         // check it
  1814.         
  1815.         if ( WEFeatureFlag( weFDragAndDrop, weBitTest, we ) )
  1816.         {
  1817.             GetIndString( itemString, rFeaturesMenuStrings, strFeatureDisableDragAndDrop );
  1818.             SetMenuItemText( menu, iDragAndDropEditing, itemString );
  1819.         }
  1820.         else
  1821.         {
  1822.             GetIndString( itemString, rFeaturesMenuStrings, strFeatureEnableDragAndDrop );
  1823.             SetMenuItemText( menu, iDragAndDropEditing, itemString );
  1824.         }
  1825.     }
  1826.     else
  1827.     {
  1828.         // no drag and drop on the computer, so disable the item
  1829.         
  1830.         DisableItem( menu, iDragAndDropEditing );
  1831.         
  1832.         // set the menu item text to say we can't drag and drop on this 'puter
  1833.                         
  1834.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureCantDragAndDrop );
  1835.         SetMenuItemText( menu, iDragAndDropEditing, itemString );
  1836.     }
  1837.     
  1838.     if ( WEFeatureFlag( weFDrawOffscreen, weBitTest, we ) )
  1839.     {
  1840.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureDisableOffscreen );
  1841.         SetMenuItemText( menu, iOffscreenDrawing, itemString );
  1842.     }
  1843.     else
  1844.     {
  1845.         GetIndString( itemString, rFeaturesMenuStrings, strFeatureEnableOffscreen );
  1846.         SetMenuItemText( menu, iOffscreenDrawing, itemString );
  1847.     }
  1848.     
  1849.     
  1850.     // Dialogs menu
  1851.     
  1852.     menu = GetMenuHandle( mDialogs );
  1853.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1854.         EnableItem( menu, i );
  1855.     
  1856.     // Windows menu
  1857.     
  1858.     menu = GetMenuHandle( mWindows );
  1859.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1860.         EnableItem( menu, i );
  1861.     HsoiAdjustWindowsMenu( window );
  1862.     
  1863.     // Sound menu
  1864.         
  1865.     HsoiAdjustSoundMenu( window );
  1866.         
  1867.     // and finally!!!  our Help menu
  1868.     
  1869.     HMGetHelpMenuHandle( &menu );
  1870.     if ( gHiliting )
  1871.         DisableItem( menu, 0 );
  1872.     else
  1873.     {
  1874.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1875.             EnableItem( menu, i );
  1876.         }
  1877.  
  1878.  
  1879. #if HAS_DEBUG
  1880.  
  1881.     // Test menu
  1882.     
  1883.     menu = GetMenuHandle( mTestMENU );
  1884.     if ( gHiliting )
  1885.         DisableItem( menu, 0 );
  1886.     else
  1887.     {
  1888.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1889.             EnableItem( menu, i );
  1890.     }
  1891.  
  1892. #endif        
  1893.  
  1894.     
  1895.     // and just before we go, adjust the font size menu
  1896.     
  1897.     HsoiMaintainFontMenu();
  1898.  
  1899.     return;
  1900. }
  1901.  
  1902. void    HsoiAdjustMenusClipboardWindow( WindowRef window )
  1903. {
  1904.     MenuRef                menu;
  1905.     short                i;
  1906.     
  1907.     // similar but much simpler than HsoiAdjustMenusDocumentWindow()
  1908.     
  1909.     // Apple menu
  1910.     
  1911.     menu = GetMenuHandle( mApple );
  1912.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1913.         EnableItem( menu, i );
  1914.     
  1915.     // File menu
  1916.     
  1917.     menu = GetMenuHandle( mFile );
  1918.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1919.         EnableItem( menu, i );
  1920.     
  1921.     // disable New and Open if we've hit our max open windows
  1922.     
  1923.     if ( gNumWindows >= kMaxNumberOfOpenWindows )
  1924.     {
  1925.         DisableItem( menu, iNew );
  1926.         DisableItem( menu, iOpen );
  1927.     }
  1928.     
  1929.     DisableItem( menu, iSave );
  1930.     DisableItem( menu, iSaveAs );
  1931.     DisableItem( menu, iRevert );
  1932.     DisableItem( menu, iPrint );
  1933.     
  1934.     // Edit menu
  1935.     
  1936.     menu = GetMenuHandle( mEdit );
  1937.     EnableItem( menu, 0 );
  1938.     for ( i = CountMenuItems(menu) - 1; i >= 1; i-- )
  1939.         DisableItem( menu, i );
  1940.     EnableItem( menu, iShowClipboard );
  1941.     
  1942.     // and here's a pretty simple run to disable everything else
  1943.     
  1944.     DisableItem( GetMenuHandle( mText ), 0 );
  1945.     DisableItem( GetMenuHandle( mFont ), 0 );
  1946.     DisableItem( GetMenuHandle( mSize ), 0 );
  1947.     DisableItem( GetMenuHandle( mStyle ), 0 );
  1948.     DisableItem( GetMenuHandle( mJustification ), 0 );
  1949.     DisableItem( GetMenuHandle( mColor ), 0 );
  1950.     DisableItem( GetMenuHandle( mFeatures ), 0 );
  1951.     
  1952.     // enable the Dialogs menu'
  1953.     
  1954.     menu = GetMenuHandle( mDialogs );
  1955.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1956.         EnableItem( menu, i );
  1957.     
  1958.     // Windows menu
  1959.     
  1960.     menu = GetMenuHandle( mWindows );
  1961.     
  1962.     if ( gNumWindows <= 0 )
  1963.     {
  1964.         DisableItem( menu, 0 );
  1965.     }
  1966.     else
  1967.     {
  1968.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1969.             EnableItem( menu, i );
  1970.     }
  1971.     
  1972.     HsoiAdjustWindowsMenu( window );
  1973.     
  1974.     // Sound menu....since we can play sounds on the clipboard, let's make sure we set things up
  1975.     
  1976.     HsoiAdjustSoundMenu( window );
  1977.         
  1978.     // and finally!!!  our Help menu
  1979.     
  1980.     HMGetHelpMenuHandle( &menu );
  1981.     if ( gHiliting )
  1982.         DisableItem( menu, 0 );
  1983.     else
  1984.     {
  1985.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1986.             EnableItem( menu, i );
  1987.     }
  1988.  
  1989. #if HAS_DEBUG
  1990.  
  1991.     // Test menu
  1992.     
  1993.     menu = GetMenuHandle( mTestMENU );
  1994.     if ( gHiliting )
  1995.         DisableItem( menu, 0 );
  1996.     else
  1997.     {
  1998.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  1999.             EnableItem( menu, i );
  2000.     }
  2001.     
  2002. #endif        
  2003.  
  2004.         
  2005.     return;
  2006. }
  2007.  
  2008. void    HsoiAdjustMenusFindDialog( WindowRef window )
  2009. {
  2010. #pragma unused ( window )
  2011.  
  2012.     MenuRef        menu;
  2013.     short        i;
  2014.     
  2015.     // this is our modeless find/search dialog.  since it's a modeless dialog, this
  2016.     // routine is sorta a hybrid between our document and dialog adjusters.
  2017.     
  2018.     menu = GetMenuHandle( mApple );
  2019.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  2020.         EnableItem( menu, i );
  2021.     
  2022.     menu = GetMenuHandle( mFile );
  2023.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  2024.         EnableItem( menu, i );
  2025.     
  2026.     if ( gNumWindows >= kMaxNumberOfOpenWindows )
  2027.     {
  2028.         DisableItem( menu, iNew );
  2029.         DisableItem( menu, iOpen );
  2030.     }
  2031.  
  2032.     DisableItem( menu, iSave );
  2033.     DisableItem( menu, iSaveAs );
  2034.     DisableItem( menu, iRevert );
  2035.     DisableItem( menu, iPrint );
  2036.     
  2037.     menu = GetMenuHandle( mEdit );
  2038.     EnableItem( menu, 0 );
  2039.     for ( i = CountMenuItems(menu) - 1; i >= 1; i-- )
  2040.         DisableItem( menu, i );
  2041.     EnableItem( menu, iShowClipboard );
  2042.     
  2043.     DisableItem( GetMenuHandle( mText ), 0 );
  2044.     DisableItem( GetMenuHandle( mFont ), 0 );
  2045.     DisableItem( GetMenuHandle( mSize ), 0 );
  2046.     DisableItem( GetMenuHandle( mStyle ), 0 );
  2047.     DisableItem( GetMenuHandle( mJustification ), 0 );
  2048.     DisableItem( GetMenuHandle( mColor ), 0 );
  2049.     DisableItem( GetMenuHandle( mFeatures ), 0 );
  2050.  
  2051.     menu = GetMenuHandle( mDialogs );
  2052.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  2053.         EnableItem( menu, i );
  2054.  
  2055.     menu = GetMenuHandle( mWindows );
  2056.     for ( i = 0; i <= CountMenuItems( menu ); i++ )
  2057.         EnableItem( menu, i );
  2058.  
  2059.     HsoiAdjustSoundMenu( window );
  2060.     
  2061.     HMGetHelpMenuHandle( &menu );
  2062.     if ( gHiliting )
  2063.         DisableItem( menu, i );
  2064.     else
  2065.     {
  2066.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  2067.             EnableItem( menu, i );
  2068.     }
  2069.  
  2070. #if HAS_DEBUG
  2071.  
  2072.     // Test menu
  2073.     
  2074.     menu = GetMenuHandle( mTestMENU );
  2075.     if ( gHiliting )
  2076.         DisableItem( menu, 0 );
  2077.     else
  2078.     {
  2079.         for ( i = 0; i <= CountMenuItems( menu ); i++ )
  2080.             EnableItem( menu, i );
  2081.     }
  2082.  
  2083. #endif        
  2084.     
  2085.     return;
  2086. }
  2087.