home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xmh / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-22  |  15.2 KB  |  521 lines

  1. /*
  2.  * $XConsortium: screen.c,v 2.62 91/07/22 21:23:25 converse Exp $
  3.  *
  4.  *
  5.  *                COPYRIGHT 1987, 1989
  6.  *           DIGITAL EQUIPMENT CORPORATION
  7.  *               MAYNARD, MASSACHUSETTS
  8.  *            ALL RIGHTS RESERVED.
  9.  *
  10.  * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
  11.  * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
  12.  * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
  13.  * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
  14.  *
  15.  * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT
  16.  * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN
  17.  * ADDITION TO THAT SET FORTH ABOVE.
  18.  *
  19.  * Permission to use, copy, modify, and distribute this software and its
  20.  * documentation for any purpose and without fee is hereby granted, provided
  21.  * that the above copyright notice appear in all copies and that both that
  22.  * copyright notice and this permission notice appear in supporting
  23.  * documentation, and that the name of Digital Equipment Corporation not be
  24.  * used in advertising or publicity pertaining to distribution of the software
  25.  * without specific, written prior permission.
  26.  */
  27.  
  28. /* scrn.c -- management of scrns. */
  29.  
  30. #include "xmh.h"
  31.  
  32. XmhMenuEntryRec    folderMenu[] = {
  33.     {"open",            DoOpenFolder},
  34.     {"openInNew",         DoOpenFolderInNewWindow},
  35.     {"create",            DoCreateFolder},
  36.     {"delete",            DoDeleteFolder},
  37.     {"line",            (XtCallbackProc) NULL},
  38.     {"close",            DoClose},
  39. };
  40.  
  41. XmhMenuEntryRec    tocMenu[] = {
  42.     {"inc",            DoIncorporateNewMail},
  43.     {"commit",            DoCommit},
  44.     {"pack",            DoPack},
  45.     {"sort",            DoSort},
  46.     {"rescan",            DoForceRescan},
  47. };
  48.  
  49. XmhMenuEntryRec    messageMenu[] = {
  50.     {"compose",            DoComposeMessage},
  51.     {"next",            DoNextView},
  52.     {"prev",            DoPrevView},
  53.     {"delete",            DoDelete},
  54.     {"move",            DoMove},
  55.     {"copy",            DoCopy},
  56.     {"unmark",            DoUnmark},
  57.     {"viewNew",            DoViewNew},
  58.     {"reply",            DoReply},
  59.     {"forward",            DoForward},
  60.     {"useAsComp",        DoTocUseAsComp},
  61.     {"print",            DoPrint},
  62. };
  63.  
  64. XmhMenuEntryRec    sequenceMenu[] = {
  65.     {"pick",            DoPickMessages},
  66.     {"openSeq",            DoOpenSeq},
  67.     {"addToSeq",        DoAddToSeq},
  68.     {"removeFromSeq",        DoRemoveFromSeq},
  69.     {"deleteSeq",        DoDeleteSeq},
  70.     {"line",            (XtCallbackProc) NULL},
  71.     {"all",            DoSelectSequence},
  72. };
  73.  
  74. XmhMenuEntryRec    viewMenu[] = {
  75.     {"reply",            DoViewReply},
  76.     {"forward",            DoViewForward},
  77.     {"useAsComp",        DoViewUseAsComposition},
  78.     {"edit",            DoEditView},
  79.     {"save",            DoSaveView},
  80.     {"print",            DoPrintView},
  81. };
  82.  
  83. XmhMenuEntryRec    optionMenu[] = {
  84.     {"reverse",            DoReverseReadOrder},
  85. };
  86.  
  87. XmhMenuButtonDescRec    MenuBoxButtons[] = {
  88.     {"folderButton",    "folderMenu",    XMH_FOLDER,    folderMenu,
  89.      XtNumber(folderMenu) },
  90.     {"tocButton",    "tocMenu",    XMH_TOC,    tocMenu,
  91.      XtNumber(tocMenu) },
  92.     {"messageButton",    "messageMenu",    XMH_MESSAGE,    messageMenu,
  93.      XtNumber(messageMenu) },
  94.     {"sequenceButton",    "sequenceMenu",    XMH_SEQUENCE,    sequenceMenu,
  95.      XtNumber(sequenceMenu) },
  96.     {"viewButton",    "viewMenu",    XMH_VIEW,    viewMenu,
  97.      XtNumber(viewMenu) },
  98.     {"optionButton",    "optionMenu",    XMH_OPTION,    optionMenu,
  99.      XtNumber(optionMenu) },
  100. };
  101.  
  102.  
  103. /* Fill in the buttons for the view commands. */
  104.  
  105. static void FillViewButtons(scrn)
  106. Scrn scrn;
  107. {
  108.     ButtonBox buttonbox = scrn->viewbuttons;
  109.     BBoxAddButton(buttonbox, "close", commandWidgetClass, True);
  110.     BBoxAddButton(buttonbox, "reply", commandWidgetClass, True);
  111.     BBoxAddButton(buttonbox, "forward", commandWidgetClass, True);
  112.     BBoxAddButton(buttonbox, "useAsComp", commandWidgetClass, True);
  113.     BBoxAddButton(buttonbox, "edit", commandWidgetClass, True);
  114.     BBoxAddButton(buttonbox, "save", commandWidgetClass, False);
  115.     BBoxAddButton(buttonbox, "print", commandWidgetClass, True);
  116.     BBoxAddButton(buttonbox, "delete", commandWidgetClass, True);
  117. }
  118.     
  119.  
  120.  
  121. static void FillCompButtons(scrn)
  122. Scrn scrn;
  123. {
  124.     ButtonBox buttonbox = scrn->viewbuttons;
  125.     BBoxAddButton(buttonbox, "close", commandWidgetClass, True);
  126.     BBoxAddButton(buttonbox, "send", commandWidgetClass, True);
  127.     BBoxAddButton(buttonbox, "reset", commandWidgetClass, True);
  128.     BBoxAddButton(buttonbox, "compose", commandWidgetClass, True);
  129.     BBoxAddButton(buttonbox, "save", commandWidgetClass, True);
  130.     BBoxAddButton(buttonbox, "insert", commandWidgetClass, True);
  131. }
  132.  
  133.  
  134. static void MakeCommandMenu(scrn, mbd)
  135.     Scrn        scrn;
  136.     XmhMenuButtonDesc    mbd;
  137. {
  138.     register int i;
  139.     Cardinal     n;
  140.     Widget    menu;
  141.     ButtonBox    buttonbox = scrn->mainbuttons;
  142.     XmhMenuEntry    e;
  143.     Boolean    indent;
  144.     WidgetClass    widgetclass;
  145.     Arg        args[4];
  146.     static XtCallbackRec callbacks[] = {
  147.     { (XtCallbackProc) NULL, (XtPointer) NULL},
  148.     { (XtCallbackProc) NULL, (XtPointer) NULL},
  149.     { (XtCallbackProc) NULL, (XtPointer) NULL},
  150.     };
  151.  
  152.     /* Menus are created as childen of the Paned widget of the scrn in order
  153.      * that they can be used both as pop-up and as pull-down menus.
  154.      */
  155.  
  156.     n = 0;
  157.     if (mbd->id == XMH_SEQUENCE) {
  158.     XtSetArg(args[n], XtNallowShellResize, True);     n++;
  159.     }
  160.     menu = XtCreatePopupShell(mbd->menu_name, simpleMenuWidgetClass,
  161.                   scrn->widget, args, n);
  162.  
  163.     indent = (mbd->id == XMH_SEQUENCE || mbd->id == XMH_OPTION) ? True : False;
  164.     e = mbd->entry;
  165.     for (i=0; i < mbd->num_entries; i++, e++) {
  166.     n = 0;
  167.     if (e->function) {
  168.         callbacks[0].callback = e->function;
  169.         callbacks[0].closure  = (XtPointer) scrn;
  170.         callbacks[1].callback = (app_resources.sticky_menu
  171.                      ? (XtCallbackProc) DoRememberMenuSelection
  172.                      : (XtCallbackProc) NULL);
  173.         XtSetArg(args[n], XtNcallback, callbacks);    n++;
  174.  
  175.         if (indent) { XtSetArg(args[n], XtNleftMargin, 18);    n++; }
  176.         widgetclass = smeBSBObjectClass;
  177.     } else 
  178.         widgetclass = smeLineObjectClass;
  179.     XtCreateManagedWidget(e->name, widgetclass, menu, args, n);
  180.     }
  181.  
  182.     AttachMenuToButton( BBoxFindButtonNamed( buttonbox, mbd->button_name),
  183.                menu, mbd->menu_name);
  184.     if (mbd->id == XMH_OPTION && app_resources.reverse_read_order)
  185.     ToggleMenuItem(XtNameToWidget(menu, "reverse"), True);
  186. }
  187.  
  188.  
  189. /* Create subwidgets for a toc&view window. */
  190.  
  191. static void MakeTocAndView(scrn)
  192. Scrn scrn;
  193. {
  194.     register int    i;
  195.     XmhMenuButtonDesc    mbd;
  196.     ButtonBox        buttonbox;
  197.     char        *name;
  198.     static XawTextSelectType sarray[] = {XawselectLine,
  199.                     XawselectPosition,
  200.                     XawselectAll,
  201.                     XawselectNull};
  202.     static Arg args[] = {
  203.     { XtNselectTypes,    (XtArgVal) sarray},
  204.     { XtNdisplayCaret,    (XtArgVal) False}
  205.     };
  206.  
  207.     scrn->mainbuttons   = BBoxCreate(scrn, "menuBox");
  208.     scrn->folderlabel   = CreateTitleBar(scrn, "folderTitlebar");
  209.     scrn->folderbuttons = BBoxCreate(scrn, "folders");
  210.     scrn->toclabel      = CreateTitleBar(scrn, "tocTitlebar");
  211.     scrn->tocwidget    = CreateTextSW(scrn, "toc", args, XtNumber(args));
  212.     if (app_resources.command_button_count > 0) 
  213.     scrn->miscbuttons = BBoxCreate(scrn, "commandBox");
  214.     scrn->viewlabel     = CreateTitleBar(scrn, "viewTitlebar");
  215.     scrn->viewwidget    = CreateTextSW(scrn, "view", args, (Cardinal) 0);
  216.  
  217.     /* the command buttons and menus */
  218.  
  219.     buttonbox = scrn->mainbuttons;
  220.     mbd = MenuBoxButtons;
  221.     for (i=0; i < XtNumber(MenuBoxButtons); i++, mbd++) {
  222.     name = mbd->button_name;
  223.     BBoxAddButton(buttonbox, name, menuButtonWidgetClass, True);
  224.     MakeCommandMenu(scrn, mbd);
  225.     }
  226.  
  227.     /* the folder buttons; folder menus are created on demand. */
  228.  
  229.     buttonbox = scrn->folderbuttons;
  230.     for (i=0 ; i<numFolders ; i++) {
  231.     name = TocName(folderList[i]);
  232.     if (! IsSubfolder(name))
  233.         BBoxAddButton(buttonbox, name, menuButtonWidgetClass, True);
  234.     if (app_resources.new_mail_check &&
  235.         numScrns > 1 &&
  236.         TocCanIncorporate(folderList[i]))
  237.         BBoxMailFlag(buttonbox, name, TocHasMail(folderList[i]));
  238.     }
  239.  
  240.     /* the optional miscellaneous command buttons */
  241.  
  242.     if (app_resources.command_button_count > 0) {
  243.     char    name[12];
  244.     if (app_resources.command_button_count > 500)
  245.         app_resources.command_button_count = 500;
  246.     for (i=1; i <= app_resources.command_button_count; i++) {
  247.         sprintf(name, "button%d", i);
  248.         BBoxAddButton(scrn->miscbuttons, name, commandWidgetClass, True);
  249.     }
  250.     }
  251. }
  252.  
  253. static void MakeView(scrn)
  254. Scrn scrn;
  255. {
  256.     scrn->viewlabel = CreateTitleBar(scrn, "viewTitlebar");
  257.     scrn->viewwidget = CreateTextSW(scrn, "view", (ArgList)NULL, (Cardinal)0);
  258.     scrn->viewbuttons = BBoxCreate(scrn, "viewButtons");
  259.     FillViewButtons(scrn);
  260. }
  261.  
  262.  
  263. static void MakeComp(scrn)
  264. Scrn scrn;
  265. {
  266.     scrn->viewlabel = CreateTitleBar(scrn, "composeTitlebar");
  267.     scrn->viewwidget = CreateTextSW(scrn, "comp", (ArgList)NULL, (Cardinal)0);
  268.     scrn->viewbuttons = BBoxCreate(scrn, "compButtons");
  269.     FillCompButtons(scrn);
  270. }
  271.  
  272.  
  273. /* Create a scrn of the given type. */
  274.  
  275. Scrn CreateNewScrn(kind)
  276. ScrnKind kind;
  277. {
  278.     int i;
  279.     Scrn scrn;
  280.     static Arg arglist[] = {
  281.     { XtNgeometry,    (XtArgVal) NULL},
  282.     { XtNinput,    (XtArgVal) True}
  283.     };
  284.  
  285.     for (i=0 ; i<numScrns ; i++)
  286.     if (scrnList[i]->kind == kind && !scrnList[i]->mapped)
  287.         return scrnList[i];
  288.     switch (kind) {
  289.        case STtocAndView: arglist[0].value =
  290.                (XtArgVal)app_resources.toc_geometry;    break;
  291.        case STview:      arglist[0].value =
  292.                (XtArgVal)app_resources.view_geometry;    break;
  293.        case STcomp:      arglist[0].value =
  294.                (XtArgVal)app_resources.comp_geometry;    break;
  295.        case STpick:      arglist[0].value =
  296.                (XtArgVal)app_resources.pick_geometry;    break;
  297.     }
  298.  
  299.     numScrns++;
  300.     scrnList = (Scrn *)
  301.     XtRealloc((char *) scrnList, (unsigned) numScrns*sizeof(Scrn));
  302.     scrn = scrnList[numScrns - 1] = XtNew(ScrnRec);
  303.     bzero((char *)scrn, sizeof(ScrnRec));
  304.     scrn->kind = kind;
  305.     if (numScrns == 1) scrn->parent = toplevel;
  306.     else scrn->parent = XtCreatePopupShell(
  307.                    progName, topLevelShellWidgetClass,
  308.                    toplevel, arglist, XtNumber(arglist));
  309.     XtAugmentTranslations(scrn->parent,
  310.               app_resources.wm_protocols_translations);
  311.     scrn->widget =
  312.     XtCreateManagedWidget(progName, panedWidgetClass, scrn->parent,
  313.                   (ArgList) NULL, (Cardinal) 0);
  314.  
  315.     switch (kind) {
  316.     case STtocAndView:     MakeTocAndView(scrn); break;
  317.     case STview:        MakeView(scrn); break;
  318.     case STcomp:        MakeComp(scrn);    break;
  319.     }
  320.  
  321.     if (kind != STpick) {
  322.     int    theight, min, max;
  323.     Arg    args[1];
  324.  
  325.     DEBUG("Realizing...")
  326.     XtRealizeWidget(scrn->parent);
  327.     DEBUG(" done.\n")
  328.  
  329.     switch (kind) {
  330.       case STtocAndView:
  331.         BBoxLockSize(scrn->mainbuttons);
  332.         BBoxLockSize(scrn->folderbuttons);
  333.         theight = GetHeight(scrn->tocwidget) + GetHeight(scrn->viewwidget);
  334.         theight = app_resources.toc_percentage * theight / 100;
  335.         XawPanedGetMinMax((Widget) scrn->tocwidget, &min, &max);
  336.         XawPanedSetMinMax((Widget) scrn->tocwidget, theight, theight);
  337.         XawPanedSetMinMax((Widget) scrn->tocwidget, min, max);
  338.         if (scrn->miscbuttons)
  339.         BBoxLockSize(scrn->miscbuttons);
  340.  
  341.         /* fall through */
  342.  
  343.       case STview:
  344.  
  345.         /* Install accelerators; not active while editing in the view */
  346.  
  347.         XtSetArg(args[0], XtNtranslations, &(scrn->edit_translations));
  348.         XtGetValues(scrn->viewwidget, args, (Cardinal) 1);
  349.         XtInstallAllAccelerators(scrn->widget, scrn->widget);
  350.         if (kind == STtocAndView)
  351.         XtInstallAllAccelerators(scrn->tocwidget, scrn->widget);
  352.         XtInstallAllAccelerators(scrn->viewwidget, scrn->widget);
  353.         XtSetArg(args[0], XtNtranslations, &(scrn->read_translations));
  354.         XtGetValues(scrn->viewwidget, args, (Cardinal) 1);
  355.  
  356.         if (kind == STview)
  357.         BBoxLockSize(scrn->viewbuttons);
  358.         break;
  359.  
  360.       case STcomp:
  361.         BBoxLockSize(scrn->viewbuttons);
  362.         XtInstallAllAccelerators(scrn->viewwidget, scrn->widget);
  363.         XtSetKeyboardFocus(scrn->parent, scrn->viewwidget);
  364.         break;
  365.     }
  366.  
  367.     InitBusyCursor(scrn);
  368.     XDefineCursor(XtDisplay(scrn->parent), XtWindow(scrn->parent),
  369.               app_resources.cursor);
  370.     (void) XSetWMProtocols(XtDisplay(scrn->parent), XtWindow(scrn->parent),
  371.                    protocolList, XtNumber(protocolList));
  372.     }
  373.     scrn->mapped = (numScrns == 1);
  374.     return scrn;
  375. }
  376.  
  377.  
  378. Scrn NewViewScrn()
  379. {
  380.     return CreateNewScrn(STview);
  381. }
  382.  
  383. Scrn NewCompScrn()
  384. {
  385.     Scrn scrn;
  386.     scrn = CreateNewScrn(STcomp);
  387.     scrn->assocmsg = (Msg)NULL;
  388.     return scrn;
  389. }
  390.  
  391. void ScreenSetAssocMsg(scrn, msg)
  392.   Scrn scrn;
  393.   Msg msg;
  394. {
  395.     scrn->assocmsg = msg;
  396. }
  397.  
  398. /* Destroy the screen.  If unsaved changes are in a msg, too bad. */
  399.  
  400. void DestroyScrn(scrn)
  401.   Scrn scrn;
  402. {
  403.     if (scrn->mapped) {
  404.     scrn->mapped = False;
  405.     XtPopdown(scrn->parent);
  406.     TocSetScrn((Toc) NULL, scrn);
  407.     MsgSetScrnForce((Msg) NULL, scrn);
  408.     lastInput.win = -1;
  409.     }
  410. }
  411.  
  412.  
  413. void MapScrn(scrn)
  414. Scrn scrn;
  415. {
  416.     if (!scrn->mapped) {
  417.     XtPopup(scrn->parent, XtGrabNone);
  418.     scrn->mapped = True;
  419.     }
  420. }
  421.  
  422.  
  423. Scrn ScrnFromWidget(w)        /* heavily used, should be efficient */
  424. Widget w;
  425. {
  426.     register int i;
  427.     while (w && (XtClass(w) != applicationShellWidgetClass) &&
  428.        (XtClass(w) != topLevelShellWidgetClass))
  429.     w = XtParent(w);
  430.     if (w) {
  431.     for (i=0 ; i<numScrns ; i++) {
  432.         if (w == (Widget) scrnList[i]->parent)
  433.         return scrnList[i];
  434.     }
  435.     }
  436.     Punt("ScrnFromWidget failed!");
  437.     /*NOTREACHED*/
  438. }
  439.  
  440.  
  441. /* Figure out which buttons should and shouldn't be enabled in the given
  442.  * screen.  This should be called whenever something major happens to the
  443.  * screen.
  444.  */
  445.  
  446.  
  447. /*ARGSUSED*/
  448. static void EnableCallback(w, data, junk)
  449. Widget w;
  450. XtPointer data, junk;
  451. {
  452.   EnableProperButtons( (Scrn) data);
  453. }  
  454.  
  455. static void EnableCallback();
  456.  
  457. #define SetButton(buttonbox, name, value) \
  458.     if (value) BBoxEnable(BBoxFindButtonNamed(buttonbox, name)); \
  459.     else BBoxDisable(BBoxFindButtonNamed(buttonbox, name));
  460.  
  461.  
  462. void EnableProperButtons(scrn)
  463. Scrn scrn;
  464. {
  465.     int value, changed, reapable;
  466.     Button    button;
  467.  
  468.     if (scrn) {
  469.     switch (scrn->kind) {
  470.       case STtocAndView:
  471.         button = BBoxFindButtonNamed
  472.         (scrn->mainbuttons, MenuBoxButtons[XMH_TOC].button_name);
  473.         value = TocCanIncorporate(scrn->toc);
  474.         SendMenuEntryEnableMsg(button, "inc", value);
  475.  
  476.         button = BBoxFindButtonNamed
  477.         (scrn->mainbuttons, MenuBoxButtons[XMH_SEQUENCE].button_name);
  478.         value = TocHasSequences(scrn->toc);
  479.         SendMenuEntryEnableMsg(button, "openSeq", value);
  480.         SendMenuEntryEnableMsg(button, "addToSeq", value);
  481.         SendMenuEntryEnableMsg(button, "removeFromSeq", value);
  482.         SendMenuEntryEnableMsg(button, "deleteSeq", value);
  483.  
  484.         button = BBoxFindButtonNamed
  485.          (scrn->mainbuttons, MenuBoxButtons[XMH_VIEW].button_name);
  486.         value = (scrn->msg != NULL && !MsgGetEditable(scrn->msg));
  487.         SendMenuEntryEnableMsg(button, "edit", value);
  488.         SendMenuEntryEnableMsg(button, "save",
  489.                    scrn->msg != NULL && !value);
  490.         break;
  491.       case STview:
  492.         value = (scrn->msg != NULL && !MsgGetEditable(scrn->msg));
  493.         SetButton(scrn->viewbuttons, "edit", value);
  494.         SetButton(scrn->viewbuttons, "save", scrn->msg != NULL && !value);
  495.         break;
  496.       case STcomp:
  497.         if (scrn->msg != NULL) {
  498.         changed = MsgChanged(scrn->msg);
  499.         reapable = MsgGetReapable(scrn->msg);
  500.         SetButton(scrn->viewbuttons, "send", changed || !reapable);
  501.         SetButton(scrn->viewbuttons, "save", changed || reapable);
  502.         SetButton(scrn->viewbuttons, "insert",
  503.               scrn->assocmsg != NULL ? True : False);
  504.  
  505.         if (!changed) 
  506.             MsgSetCallOnChange(scrn->msg, EnableCallback,
  507.                        (XtPointer) scrn);
  508.         else 
  509.             MsgSetCallOnChange(scrn->msg, (XtCallbackProc) NULL,
  510.                        (XtPointer) NULL);
  511.  
  512.         } else {
  513.         BBoxDisable( BBoxFindButtonNamed(scrn->viewbuttons, "send"));
  514.         BBoxDisable( BBoxFindButtonNamed(scrn->viewbuttons, "save"));
  515.         BBoxDisable( BBoxFindButtonNamed(scrn->viewbuttons, "insert"));
  516.         }
  517.         break;
  518.     }
  519.     }
  520. }
  521.