home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / lang / lsc_tran / DumbEdit.c next >
Text File  |  1989-02-18  |  10KB  |  545 lines

  1. /*
  2.     DumbEdit - Multiple-window TransEdit Demonstration.
  3.  
  4.     The project should include DumbEdit.c (this file), TransEdit.c (or
  5.     a project made from TransEdit.c), FakeAlert.c, TransSkel.c (or a
  6.     project made from TransSkel.c) and MacTraps.
  7.  
  8.     28 Oct 86 Paul DuBois
  9.     02 Feb 89 Modified to work with TransSkel 2.0 and TransEdit 2.0.
  10.               2-byte and 4-byte integer types are typedef'ed to
  11.               Integer and Longint to ease porting.
  12. */
  13.  
  14. # include    <MenuMgr.h>
  15. # include    <FontMgr.h>
  16. # include    "TransEdit.h"
  17.  
  18.  
  19. typedef    int        Integer;    /* compiler 2-byte integer type */
  20. typedef    long    Longint;    /* compiler 4-byte integer type */
  21.  
  22.  
  23. # define    maxSize        8        /* no. font sizes made available */
  24. # define    hSize        300        /* horiz, vert size of new windows */
  25. # define    vSize        205
  26. # define    aboutAlrt    1000
  27.  
  28.  
  29. typedef enum        /* File menu item numbers */
  30. {
  31.     new = 1,        /* begin new window */
  32.     open,            /* open existing file */
  33.     close,            /* close file */
  34.     /* --- */
  35.     save = 5,        /* save file */
  36.     saveAs,            /* save under another name */
  37.     saveCopy,        /* save a copy w/o switching file binding */
  38.     revert,            /* revert to version on disk */
  39.     /* --- */
  40.     quit = 10
  41. };
  42.  
  43.  
  44. typedef enum            /* Edit menu item numbers */
  45. {
  46.     undo = 1,
  47.     /* --- */
  48.     cut = 3,
  49.     copy,
  50.     paste,
  51.     clear
  52. };
  53.  
  54.  
  55.  
  56. typedef enum        /* Format menu item numbers */
  57. {
  58.     wordWrap = 1,
  59.     noWrap,
  60.     /* --- */
  61.     leftJust = 4,
  62.     centerJust,
  63.     rightJust
  64. };
  65.  
  66.  
  67. WindowPtr    lastFront = nil;    /* keeps track of front window */
  68. MenuHandle    fileMenu;
  69. MenuHandle    editMenu;
  70. MenuHandle    fontMenu;
  71. MenuHandle    sizeMenu;
  72. MenuHandle    formatMenu;
  73.  
  74. Integer    sizes[maxSize] = { 9, 10, 12, 14, 18, 20, 24, 48 };
  75.  
  76.  
  77. /*
  78.     Uncheck all the items in a menu
  79. */
  80.  
  81. UncheckMenu (theMenu)
  82. MenuHandle    theMenu;
  83. {
  84. register Integer    i, nItems;
  85.  
  86.     nItems = CountMItems (theMenu);
  87.  
  88.     for (i = 1; i <= nItems; ++i)
  89.     {
  90.         CheckItem (theMenu, i, false);
  91.         SetItemStyle (theMenu, i, 0);
  92.     }
  93. }
  94.  
  95.  
  96. /*
  97.     Set the Font, Size and Format menus so that the items corresponding
  98.     to the text characteristics of the window are checked.  If the
  99.     window isn't an edit window, dim all three menus.
  100. */
  101.  
  102. SetTextMenus (drawBar)
  103. Boolean        drawBar;
  104. {
  105. WindowPtr            theWind;
  106. Str255                wFontName;
  107. Str255                mFontName;
  108. register Integer    i, nItems;
  109. register TEHandle    te;
  110.  
  111.     theWind = FrontWindow ();
  112.     UncheckMenu (fontMenu);                /* toss current check marks */
  113.     UncheckMenu (sizeMenu);
  114.     UncheckMenu (formatMenu);
  115.  
  116.     if (!IsEWindow (theWind))            /* disable the menus */
  117.     {
  118.         DisableItem (fontMenu, 0);
  119.         DisableItem (sizeMenu, 0);
  120.         DisableItem (formatMenu, 0);
  121.     }
  122.     else
  123.     {
  124.         EnableItem (fontMenu, 0);
  125.         EnableItem (sizeMenu, 0);
  126.         EnableItem (formatMenu, 0);
  127.  
  128.         te = GetEWindowTE (theWind);
  129.  
  130. /*
  131.     Check appropriate word wrap item
  132. */
  133.  
  134.         CheckItem (formatMenu, (**te).crOnly < 0 ? noWrap : wordWrap, true);
  135.  
  136. /*
  137.     Check appropriate justification item
  138. */
  139.  
  140.         switch ((**te).just)
  141.         {
  142.  
  143.         case teJustLeft:
  144.             CheckItem (formatMenu, leftJust, true);
  145.             break;
  146.  
  147.         case teJustRight:
  148.             CheckItem (formatMenu, rightJust, true);
  149.             break;
  150.  
  151.         case teJustCenter:
  152.             CheckItem (formatMenu, centerJust, true);
  153.             break;
  154.  
  155.         }
  156.  
  157. /*
  158.     Check appropriate font size item, and outline items for sizes
  159.     present in resource files
  160. */
  161.  
  162.         for (i = 0; i < maxSize; ++i)
  163.         {
  164.             if ((**te).txSize == sizes[i])
  165.                 CheckItem (sizeMenu, i + 1, true);
  166.  
  167.             if (RealFont ((**te).txFont, sizes[i]))
  168.                 SetItemStyle (sizeMenu, i + 1, outline);
  169.             else
  170.                 SetItemStyle (sizeMenu, i + 1, 0);        /* plain */
  171.         }
  172.  
  173. /*
  174.     Check appropriate font name item
  175. */
  176.         
  177.         GetFontName ((**te).txFont, wFontName);    /* name of window font */
  178.         nItems = CountMItems (fontMenu);        /* # fonts in menu */
  179.         for (i = 1; i <= nItems; ++i)
  180.         {
  181.             GetItem (fontMenu, i, mFontName);    /* get font name */
  182.             if (EqualString (wFontName, mFontName, false, true))
  183.             {
  184.                 CheckItem (fontMenu, i, true);
  185.                 break;
  186.             }
  187.         }
  188.  
  189.     }
  190.  
  191.     if (drawBar)
  192.         DrawMenuBar ();
  193. }
  194.  
  195.  
  196.  
  197. /*
  198.     Set File/Edit menu items according to type of front window.
  199.  
  200.     The general behavior is:
  201.  
  202.     New and Open always enabled, since a new edit window can always be
  203.     opened.
  204.  
  205.     Close enabled when an edit or DA window in front (i.e., when there's
  206.     a window at all).
  207.  
  208.     Save enabled for edit windows not bound to a file, and edit windows
  209.     bound to a file when they're dirty (typed into, Edit menu used to
  210.     do something to them).
  211.  
  212.     Save As and Save a Copy As enabled for edit windows.
  213.  
  214.     Revert enabled for edit windows bound to a file when they're dirty.
  215.  
  216.     Undo disabled when there's an edit window in front.
  217. */
  218.  
  219. SetNonTextMenus ()
  220. {
  221. WindowPtr    theWind;
  222. Integer        theKind;
  223.  
  224.     DisableItem (fileMenu, close);    /* assume no window at all */
  225.     DisableItem (fileMenu, save);
  226.     DisableItem (fileMenu, saveAs);
  227.     DisableItem (fileMenu, saveCopy);
  228.     DisableItem (fileMenu, revert);
  229.     EnableItem (editMenu, undo);
  230.  
  231.     theKind = 0;
  232.     if ((theWind = FrontWindow ()) != nil)
  233.         theKind = ((WindowPeek) theWind)->windowKind;
  234.  
  235.     if (theKind < 0)                        /* DA in front */
  236.     {
  237.         EnableItem (fileMenu, close);
  238.     }
  239.     else if (IsEWindow (theWind))            /* edit window in front */
  240.     {
  241.         EnableItem (fileMenu, close);
  242.         EnableItem (fileMenu, saveAs);
  243.         EnableItem (fileMenu, saveCopy);
  244.         if (GetEWindowFile (theWind, nil) == false)    /* not bound to file */
  245.         {
  246.             EnableItem (fileMenu, save);
  247.         }
  248.         else if (IsEWindowDirty (theWind))    /* bound - is it dirty? */
  249.         {
  250.             EnableItem (fileMenu, save);
  251.             EnableItem (fileMenu, revert);
  252.         }
  253.         DisableItem (editMenu, undo);
  254.     }
  255. }
  256.  
  257.  
  258. /*
  259.     Got an activate or deactivate.  It doesn't matter which, really.
  260.     Set the text menus appropriately for the front window, and draw
  261.     the menu bar, as these menus might change state from enabled to
  262.     disabled or vice-versa.
  263. */
  264.  
  265. Activate (active)
  266. Boolean    active;
  267. {
  268.     CheckFront ();
  269. }
  270.  
  271.  
  272. /*
  273.     Got a keyclick in an edit window.
  274. */
  275.  
  276. Key ()
  277. {
  278.     SetNonTextMenus ();
  279. }
  280.  
  281.  
  282. /*
  283.     Close selected from File menu, or close box of edit window
  284.     clicked.
  285. */
  286.  
  287. Close ()
  288. {
  289. WindowPtr    theWind;
  290.  
  291.     GetPort (&theWind);
  292.     (void) EWindowClose (theWind);
  293.     CheckFront ();
  294. }
  295.  
  296.  
  297. MakeWind (bindToFile)
  298. Boolean    bindToFile;
  299. {
  300. Rect            r;
  301. static Integer    windCount = 0;
  302. Integer            offset;
  303.  
  304.     if (FrontWindow () == nil)
  305.         windCount = 0;
  306.     SetRect (&r, 0, 0, hSize, vSize);
  307.     offset = 50 + 25 * (windCount++ % 4);
  308.     OffsetRect (&r, offset, offset);
  309.     (void) NewEWindow (&r, nil, true, -1L, true, 0L, bindToFile);
  310. }
  311.  
  312.  
  313. /*
  314.     File menu handler
  315. */
  316.  
  317. DoFileMenu (item)
  318. Integer    item;
  319. {
  320. WindowPtr    theWind;
  321.  
  322.     theWind = FrontWindow ();
  323.     switch (item)
  324.     {
  325.  
  326.     case new:
  327.         MakeWind (false);
  328.         break;
  329.  
  330.     case open:
  331.         MakeWind (true);
  332.         break;
  333.  
  334.     case close:
  335.         if (IsEWindow (theWind))
  336.             (void) EWindowClose (theWind);
  337.         else
  338.             CloseDeskAcc (((WindowPeek) theWind)->windowKind);    /* DA in front */
  339.         break;
  340.  
  341.     case save:
  342.         (void) EWindowSave (theWind);
  343.         break;
  344.  
  345.     case saveAs:
  346.         (void) EWindowSaveAs (theWind);
  347.         break;
  348.  
  349.     case saveCopy:
  350.         (void) EWindowSaveCopy (theWind);
  351.         break;
  352.  
  353.     case revert:
  354.         (void) EWindowRevert (theWind);
  355.         break;
  356.  
  357.     case quit:
  358.         if (ClobberEWindows () == true)
  359.             SkelWhoa ();
  360.         break;
  361.  
  362.     }
  363.     SetNonTextMenus ();
  364. }
  365.  
  366.  
  367. /*
  368.     Handle Font menu items
  369. */
  370.  
  371. DoFontMenu (item)
  372. Integer    item;
  373. {
  374. Integer        font;
  375. TEHandle    te;
  376. WindowPtr    theWind;
  377. Str255        theFontName;
  378.  
  379.     theWind = FrontWindow ();
  380.     if ((te = GetEWindowTE (theWind)) == nil)
  381.         return;                /* not an edit window */
  382.     GetItem (fontMenu, item, theFontName);
  383.     GetFNum (theFontName, &font);
  384.     SetEWindowStyle (theWind, font, (**te).txSize, (**te).crOnly, (**te).just);
  385.     SetTextMenus (false);
  386.  
  387. }
  388.  
  389.  
  390. /*
  391.     Handle Size menu items
  392. */
  393.  
  394. DoSizeMenu (item)
  395. Integer    item;
  396. {
  397. TEHandle    te;
  398. WindowPtr    theWind;
  399.  
  400.     theWind = FrontWindow ();
  401.     if ((te = GetEWindowTE (theWind)) == nil)
  402.         return;                /* not an edit window */
  403.     SetEWindowStyle (theWind, (**te).txFont, sizes[item-1], (**te).crOnly, (**te).just);
  404.     SetTextMenus (false);
  405. }
  406.  
  407.  
  408. /*
  409.     Handle Format menu items
  410. */
  411.  
  412. DoFormatMenu (item)
  413. Integer    item;
  414. {
  415. Integer        font, size, just, wrap;
  416. TEHandle    te;
  417. WindowPtr    theWind;
  418.  
  419.     theWind = FrontWindow ();
  420.     if ((te = GetEWindowTE (theWind)) == nil)
  421.         return;                /* not an edit window */
  422.     font = (**te).txFont;
  423.     size = (**te).txSize;
  424.     just = (**te).just;
  425.     wrap = (**te).crOnly;
  426.  
  427.     switch (item)
  428.     {
  429.  
  430.     case wordWrap:
  431.         wrap = 0;
  432.         break;
  433.  
  434.     case noWrap:
  435.         wrap = -1;
  436.         break;
  437.  
  438.     case leftJust:
  439.         just = teJustLeft;
  440.         break;
  441.  
  442.     case centerJust:
  443.         just = teJustCenter;
  444.         break;
  445.  
  446.     case rightJust:
  447.         just = teJustRight;
  448.         break;
  449.     }
  450.     SetEWindowStyle (theWind, font, size, wrap, just);
  451.     SetTextMenus (false);
  452. }
  453.  
  454.  
  455. /*
  456.     Handle selection of About╔ item from Apple menu
  457. */
  458.  
  459. DoAbout ()
  460. {
  461.     (void) Alert (aboutAlrt, nil);
  462. }
  463.  
  464.  
  465. /*
  466.     Background procedure.  Check front window, reset menus if it
  467.     changes.  The menu bar doesn't need redrawing by SetTextMenus
  468.     if the previous and current front window are either both edit
  469.     windows or both not edit windows.  This check eliminates some
  470.     needless menu flashing.
  471. */
  472.  
  473. CheckFront ()
  474. {
  475.     if (FrontWindow () != lastFront)
  476.     {
  477.         SetNonTextMenus ();
  478.         if (IsEWindow (FrontWindow ()) == IsEWindow (lastFront))
  479.             SetTextMenus (false);
  480.         else
  481.             SetTextMenus (true);
  482.         lastFront = FrontWindow ();
  483.     }
  484. }
  485.  
  486.  
  487. main ()
  488. {
  489.  
  490. /*
  491.     Initialize TransSkel, create menus and install handlers.
  492. */
  493.  
  494.     SkelInit (6, nil);
  495.  
  496.     SkelApple ("\pAbout DumbEdit╔", DoAbout);
  497.  
  498.     fileMenu = NewMenu (1000, "\pFile");
  499.     AppendMenu (fileMenu, "\pNew/N;Open.../O;Close;(-;Save/S;Save As...");
  500.     AppendMenu (fileMenu, "\pSave a Copy As...;Revert/R;(-;Quit/Q");
  501.     (void) SkelMenu (fileMenu, DoFileMenu, nil, false);
  502.  
  503.     editMenu = NewMenu (1001, "\pEdit");
  504.     AppendMenu (editMenu, "\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear");
  505.     (void) SkelMenu (editMenu, EWindowEditOp, nil, false);
  506.  
  507.     fontMenu = NewMenu (1002, "\pFont");
  508.     DisableItem (fontMenu, 0);
  509.     AddResMenu (fontMenu, 'FONT');
  510.     (void) SkelMenu (fontMenu, DoFontMenu, nil, false);
  511.  
  512.     sizeMenu = NewMenu (1003, "\pSize");
  513.     DisableItem (sizeMenu, 0);
  514.     AppendMenu (sizeMenu, "\p9 Point;10 Point;12 Point;14 Point");
  515.     AppendMenu (sizeMenu, "\p18 Point;20 Point;24 Point; 48 Point");
  516.     (void) SkelMenu (sizeMenu, DoSizeMenu, nil, false);
  517.  
  518.     formatMenu = NewMenu (1004, "\pFormat");
  519.     DisableItem (formatMenu, 0);
  520.     AppendMenu (formatMenu, "\pWord Wrap;No Word Wrap;(-;Left;Center;Right");
  521.     (void) SkelMenu (formatMenu, DoFormatMenu, nil, true);
  522.  
  523.     SetNonTextMenus ();
  524.     SetTextMenus (true);
  525.  
  526. /*
  527.     Do TransEdit-specific setup:  set creator for any files created,
  528.     set default text style and event notification procedures for
  529.     new windows.
  530. */
  531.  
  532.     SetEWindowCreator ('DUMB');
  533.     SetEWindowStyle (nil, monaco, 9, 0, teJustLeft);
  534.     SetEWindowProcs (nil, Key, Activate, Close);
  535.  
  536. /*
  537.     Process events until user quits,
  538.     then clean up and exit
  539. */
  540.  
  541.     SkelBackground (CheckFront);
  542.     SkelMain ();
  543.     SkelClobber ();
  544. }
  545.