home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Text⁄Files / MakeWrite / MakeWrite Folder / MWMenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  8.4 KB  |  490 lines  |  [TEXT/KAHL]

  1. # include    "TransSkel.h"
  2.  
  3. # include    "MakeWrite.h"
  4.  
  5.  
  6.  
  7. typedef enum        /* File menu item numbers */
  8. {
  9.     newMap = 1,
  10.     openMap,
  11.     appendMap,
  12.     saveMap,
  13.     saveMapAs,
  14.     close,
  15.     /* --- */
  16.     makeWrite = 8,
  17.     /* --- */
  18.     quit = 10
  19. };
  20.  
  21.  
  22. typedef enum        /* Edit menu item numbers */
  23. {
  24.     undo = 1,
  25.     /* --- */
  26.     cut = 3,
  27.     copy,
  28.     paste,
  29.     clear,
  30.     /* --- */
  31.     new = 8,
  32.     duplicate,
  33.     /* --- */
  34.     sort = 11,
  35.     squish
  36. };
  37.  
  38.  
  39. typedef enum            /* Special menu items */
  40. {
  41.     stdFontList = 1,
  42.     systemFontList,
  43.     /* --- */
  44.     pgraphStyle = 4,
  45.     /* --- */
  46.     conflicts = 6,
  47.     /* --- */
  48.     getInfo = 8,
  49.     /* --- */
  50.     debugOption = 10
  51. };
  52.  
  53.  
  54. static MenuHandle    fileMenu;
  55. static MenuHandle    editMenu;
  56. static MenuHandle    specialMenu;
  57.  
  58. static MapSpec        clipMSpec;                /* clipboard specification */
  59.  
  60.  
  61. /*
  62.  * Enable or disable menu or menu items, according to the string.
  63.  * First char of string is for entire menu, following chars are
  64.  * for successive items.  '0' disables, '1' enables.
  65.  *
  66.  * Return true if the status of the menu itself changed
  67.  * value, i.e., if the menu bar now needs redrawing.
  68.  */
  69.  
  70. static Boolean
  71. SetMenuStatus (MenuHandle m, StringPtr s)
  72. {
  73. short    i;
  74. short    menuState;
  75.  
  76.     menuState = ((**m).enableFlags & 1);    /* current state of menu */
  77.     for (i = 1; i <= s[0]; ++i)
  78.     {
  79.         if (s[i] == '0')
  80.             DisableItem (m, i - 1);
  81.         else
  82.             EnableItem (m, i - 1);
  83.     }
  84.     return (menuState != ((**m).enableFlags & 1));
  85. }
  86.  
  87.  
  88. /*
  89.  * Fix up menus to match window states.  There will always be some
  90.  * window.
  91.  *
  92.  * Note the handling of strings.  Those that may change need to be
  93.  * CopyString'ed into the string, otherwise the string constant
  94.  * itself will be changed.
  95.  *
  96.  * This routine is stupid about setting cut&paste types of items.
  97.  */
  98.  
  99. void
  100. FixMenus (void)
  101. {
  102. WindowPtr    frontWind;
  103. short        theKind;
  104. short        nLines;
  105. short        curLine;
  106. Boolean        drawBar = false;
  107. Str255        eString;
  108. StringPtr    fStr,
  109.             eStr = eString,        /* initial setting, may change */
  110.             oStr;
  111.  
  112.     curLine = mapList->curLine;
  113.     nLines = mapList->nLines;
  114.     frontWind = FrontWindow ();
  115.     theKind = ((WindowPeek) frontWind)->windowKind;
  116.  
  117.     if (frontWind == mapWind)
  118.     {
  119.         fStr = "\p11111100101";
  120.         oStr = "\p11101010101";
  121.         CopyString ("\p1101111011011", eStr);    /* points to eString */
  122.  
  123.         if (undoOp == noUndo)
  124.             eStr[undo + 1] = '0';
  125.  
  126.         if (curLine == noLine)
  127.         {
  128.             cpMarker = false;    /* no line - *can't* apply to marker */
  129.             eStr[cut + 1] = '0';
  130.             eStr[copy + 1] = '0';
  131.             eStr[clear + 1] = '0';
  132.             eStr[duplicate + 1] = '0';
  133.             if (havePasteMSpec == false)
  134.                 eStr[paste + 1] = '0';
  135.         }
  136.         else if (cpMarker == false)    /* line but c/p applies to map */
  137.         {
  138.             if (havePasteMSpec == false)
  139.                 eStr[paste + 1] = '0';
  140.         }
  141.  
  142.         if (nLines < 2)
  143.         {
  144.             eStr[sort + 1] = '0';
  145.             eStr[squish + 1] = '0';
  146.         }
  147.         else if (nLines >= mapList->maxLines)
  148.         {
  149.             if (cpMarker == false && curLine == noLine)
  150.                 eStr[paste + 1] = '0';
  151.             eStr[new + 1] = '0';
  152.             eStr[duplicate + 1] = '0';
  153.         }
  154.  
  155.         /*
  156.          * now figure out how to set the cut/paste indicators.  They're
  157.          * blank if there's no current line and can't paste.  Else set
  158.          * according to the current state of indicator flag.
  159.          */
  160.  
  161.         if (curLine == noLine && eStr[paste+1] == '0')
  162.             BlankCPCtrls ();
  163.         else
  164.             SetCPMarker (cpMarker);
  165.     }
  166.     else
  167.     {
  168.     /*
  169.      * Settings for File and Special menus are same for DA's and display
  170.      * windows
  171.      */
  172.         fStr = "\p10000010001";
  173.         oStr = "\p10001000101";
  174.  
  175.         if (theKind < 0)                /* DA in front */
  176.             eStr = "\p1101111000000";
  177.         else                            /* some display window in front */
  178.             eStr = "\p0";
  179.  
  180.         BlankCPCtrls ();
  181.     }
  182.  
  183.     drawBar = SetMenuStatus (fileMenu, fStr);
  184.     drawBar |= SetMenuStatus (editMenu, eStr);
  185.     drawBar |= SetMenuStatus (specialMenu, oStr);
  186.  
  187.     if (drawBar)
  188.         DrawMenuBar ();
  189. }
  190.  
  191.  
  192. /*
  193.  * Handle "About MakeWrite..." selection from Apple menu.
  194.  */
  195.  
  196. static pascal void
  197. DoAbout (short item)
  198. {
  199.     (void) SkelAlert (aboutAlrtNum, SkelDlogFilter (nil, true),
  200.                                                 skelPositionOnParentDevice);
  201.     SkelRmveDlogFilter ();
  202. }
  203.  
  204.  
  205. /*
  206.  * Process selection from File menu
  207.  */
  208.  
  209. static pascal void
  210. DoFileMenu (short item)
  211. {
  212.     switch (item)
  213.     {
  214.  
  215.     case newMap:
  216.         if (DiscardChanges ())
  217.         {
  218.             ClobberMap ();
  219.             ClearMapName ();
  220.             undoOp = noUndo;
  221.             mapModified = false;
  222.         }
  223.         break;
  224.  
  225.     case openMap:
  226.         if (DiscardChanges ())
  227.         {
  228.             if (OpenMap ())
  229.             {
  230.                 undoOp = noUndo;
  231.                 mapModified = false;
  232.             }
  233.         }
  234.         break;
  235.  
  236.     case appendMap:
  237.         if (AddMap ())
  238.         {
  239.             undoOp = noUndo;
  240.             mapModified = true;
  241.         }
  242.         break;
  243.  
  244.     case saveMap:
  245.         if (SaveMap (false))
  246.             mapModified = false;
  247.         break;
  248.  
  249.     case saveMapAs:
  250.         if (SaveMap (true))
  251.             mapModified = false;
  252.         break;
  253.     
  254.     case close:
  255.         SkelClose (FrontWindow ());
  256.         break;
  257.     
  258.     case makeWrite:
  259.         TextToWrite ();
  260.         break;
  261.     
  262.     case quit:
  263.         if (DiscardChanges ())
  264.             SkelStopEventLoop ();
  265.         break;
  266.     }
  267.     FixMenus ();
  268. }
  269.  
  270.  
  271. static void
  272. DoUndo (void)
  273. {
  274. MapSpec    tempSpec;
  275. StringHandle    hStr;
  276. Str255            tempStr;
  277. short            selStart, selEnd;
  278. Boolean            tmpCPMarker;
  279.  
  280.     tmpCPMarker = cpMarker;
  281.     cpMarker = undoCPMarker;
  282.     undoCPMarker = tmpCPMarker;
  283.  
  284.     InitMSpec (&tempSpec);
  285.     switch (undoOp)
  286.     {
  287.  
  288.     case undoInsert:
  289.         undoOp = undoDelete;
  290.         CopyMSpec (&mapSpec[undoPos], &undoMSpec);
  291.         DeleteMapping (undoPos);
  292.         break;
  293.  
  294.     case undoDelete:
  295.         undoOp = undoInsert;
  296.         InsertMapping (&undoMSpec, undoPos);
  297.         break;
  298.  
  299.     case undoPaste:
  300.         CopyMSpec (&mapSpec[undoPos], &tempSpec);
  301.         PasteMapping (&undoMSpec, undoPos);
  302.         CopyMSpec (&tempSpec, &undoMSpec);
  303.         break;
  304.  
  305.     case undoFieldChg:
  306.         SetMapFieldValue (undoFieldType, undoVal);
  307.         break;
  308.  
  309.     case undoTyping:
  310.     case undoMarkerOp:
  311.         undoOp = undoMarkerOp;
  312.         CopyMSpec (&mapSpec[undoPos], &tempSpec);
  313.         CopyMSpec (&undoMSpec, &mapSpec[undoPos]);
  314.         CopyMSpec (&tempSpec, &undoMSpec);
  315.  
  316.         hStr = mapSpec[undoPos].mark;
  317.         HLock ((Handle) hStr);
  318.         PasteField (mapList, undoPos, markField, *hStr);
  319.         HUnlock ((Handle) hStr);
  320.         SetSelectors (undoPos);
  321.         break;
  322.  
  323.     }
  324.     TermMSpec (&tempSpec);
  325. }
  326.  
  327.  
  328. /*
  329.  * Process selection from Edit menu
  330.  */
  331.  
  332. static pascal void
  333. DoEditMenu (short item)
  334. {
  335. short    curLine;
  336.  
  337.     if (SystemEdit (item - 1))
  338.         return;
  339.  
  340.     if (EditMarker (item))
  341.         return;                    /* it was a marker edit operation */
  342.  
  343.     curLine = mapList->curLine;
  344.     switch (item)
  345.     {
  346.     
  347.     case undo:
  348.         DoUndo ();
  349.         break;
  350.     
  351.     case cut:
  352.         undoCPMarker = cpMarker;
  353.         CopyMSpec (&mapSpec[curLine], &clipMSpec);
  354.         CopyMSpec (&clipMSpec, &undoMSpec);
  355.         undoOp = undoDelete;
  356.         undoPos = curLine;
  357.         havePasteMSpec = true;
  358.         DeleteMapping (curLine);
  359.         break;
  360.     
  361.     case copy:
  362.         CopyMSpec (&mapSpec[curLine], &clipMSpec);
  363.         havePasteMSpec = true;
  364.         break;
  365.     
  366.     case paste:
  367.         undoCPMarker = cpMarker;
  368.         if (curLine != noLine)
  369.         {
  370.             CopyMSpec (&mapSpec[curLine], &undoMSpec);
  371.             undoOp = undoPaste;
  372.             undoPos = curLine;
  373.             PasteMapping (&clipMSpec, curLine);
  374.         }
  375.         else                                        /* no selection; */
  376.         {                                            /* add at end */
  377.             undoOp = undoInsert;
  378.             undoPos = mapList->nLines;
  379.             if (InsertMapping (&clipMSpec, mapList->nLines) == false)
  380.                 undoOp = noUndo;
  381.         }
  382.         break;
  383.     
  384.     case clear:
  385.         undoCPMarker = cpMarker;
  386.         CopyMSpec (&mapSpec[curLine], &undoMSpec);
  387.         undoOp = undoDelete;
  388.         undoPos = curLine;
  389.         DeleteMapping (curLine);
  390.         break;
  391.     
  392.     case new:
  393.         undoCPMarker = cpMarker;
  394.         NewMapping ();
  395.         /*SetCPMarker (true);*/
  396.         undoOp = undoInsert;
  397.         break;
  398.     
  399.     case duplicate:
  400.         undoCPMarker = cpMarker;
  401.         DupMapping (curLine);    /* changes mapList->curLine */
  402.         SetCPMarker (true);
  403.         undoOp = undoInsert;
  404.         undoPos = mapList->curLine;
  405.         break;
  406.  
  407.     case sort:
  408.         SortMap ();
  409.         undoOp = noUndo;    /* can't undo this */
  410.         break;
  411.  
  412.     case squish:
  413.         SquishMap ();
  414.         undoOp = noUndo;    /* can't undo this */
  415.         break;
  416.  
  417.     }
  418.  
  419.     if (item != copy)
  420.         mapModified = true;
  421.     FixMenus ();
  422. }
  423.  
  424.  
  425. static pascal void
  426. DoSpecialMenu (short item)
  427. {
  428.     switch (item)
  429.     {
  430.  
  431.     case stdFontList:
  432.         StrFonts (true);
  433.         SetSelectors (mapList->curLine);
  434.         break;
  435.  
  436.     case systemFontList:
  437.         ResourceFonts (true);
  438.         SetSelectors (mapList->curLine);
  439.         break;
  440.  
  441.     case pgraphStyle:
  442.         DoParaDialog ();
  443.         break;
  444.  
  445.     case conflicts:
  446.         FindConflicts ();
  447.         break;
  448.  
  449.     case getInfo:
  450.         HelpWindow ();
  451.         break;
  452.  
  453. # ifdef    debug
  454.     case debugOption:
  455.         debugOut = !debugOut;
  456.         CheckItem (specialMenu, debugOption, debugOut);
  457.         break;
  458. # endif
  459.  
  460.     }
  461.     FixMenus ();
  462. }
  463.  
  464.  
  465. /*
  466.  * Menu initialization.
  467.  */
  468.  
  469. void
  470. SetupMenus (void)
  471. {
  472.     SkelApple ("\pAbout MakeWrite\311", DoAbout);    /* \311 = ellipsis */
  473.  
  474.     fileMenu = GetMenu (fileMenuNum);
  475.     SkelMenu (fileMenu, DoFileMenu, nil, false, false);
  476.  
  477.     editMenu = GetMenu (editMenuNum);
  478.     SkelMenu (editMenu, DoEditMenu, nil, false, false);
  479.  
  480.     specialMenu = GetMenu (specialMenuNum);
  481. # ifdef    debug
  482.     AppendMenu (specialMenu, "\p(-;Debug Output");
  483. # endif
  484.     SkelMenu (specialMenu, DoSpecialMenu, nil, false, false);
  485.     DrawMenuBar ();
  486.  
  487.     InitMSpec (&undoMSpec);
  488.     InitMSpec (&clipMSpec);
  489. }
  490.