#include "xmh.h"
XmhMenuEntryRec folderMenu[] = {
{"open", DoOpenFolder},
{"openInNew", DoOpenFolderInNewWindow},
{"create", DoCreateFolder},
{"delete", DoDeleteFolder},
{"line", (XtCallbackProc) NULL},
{"close", DoClose},
};
XmhMenuEntryRec tocMenu[] = {
{"inc", DoIncorporateNewMail},
{"commit", DoCommit},
{"pack", DoPack},
{"sort", DoSort},
{"rescan", DoForceRescan},
};
XmhMenuEntryRec messageMenu[] = {
{"compose", DoComposeMessage},
{"next", DoNextView},
{"prev", DoPrevView},
{"delete", DoDelete},
{"move", DoMove},
{"copy", DoCopy},
{"unmark", DoUnmark},
{"viewNew", DoViewNew},
{"reply", DoReply},
{"forward", DoForward},
{"useAsComp", DoTocUseAsComp},
{"print", DoPrint},
};
XmhMenuEntryRec sequenceMenu[] = {
{"pick", DoPickMessages},
{"openSeq", DoOpenSeq},
{"addToSeq", DoAddToSeq},
{"removeFromSeq", DoRemoveFromSeq},
{"deleteSeq", DoDeleteSeq},
{"line", (XtCallbackProc) NULL},
{"all", DoSelectSequence},
};
XmhMenuEntryRec viewMenu[] = {
{"reply", DoViewReply},
{"forward", DoViewForward},
{"useAsComp", DoViewUseAsComposition},
{"edit", DoEditView},
{"save", DoSaveView},
{"print", DoPrintView},
};
XmhMenuEntryRec optionMenu[] = {
{"reverse", DoReverseReadOrder},
};
XmhMenuButtonDescRec MenuBoxButtons[] = {
{"folderButton", "folderMenu", XMH_FOLDER, folderMenu,
XtNumber(folderMenu) },
{"tocButton", "tocMenu", XMH_TOC, tocMenu,
XtNumber(tocMenu) },
{"messageButton", "messageMenu", XMH_MESSAGE, messageMenu,
XtNumber(messageMenu) },
{"sequenceButton", "sequenceMenu", XMH_SEQUENCE, sequenceMenu,
XtNumber(sequenceMenu) },
{"viewButton", "viewMenu", XMH_VIEW, viewMenu,
XtNumber(viewMenu) },
{"optionButton", "optionMenu", XMH_OPTION, optionMenu,
XtNumber(optionMenu) },
};
static void FillViewButtons(
Scrn scrn)
{
ButtonBox buttonbox = scrn->viewbuttons;
BBoxAddButton(buttonbox, "close", commandWidgetClass, True);
BBoxAddButton(buttonbox, "reply", commandWidgetClass, True);
BBoxAddButton(buttonbox, "forward", commandWidgetClass, True);
BBoxAddButton(buttonbox, "useAsComp", commandWidgetClass, True);
BBoxAddButton(buttonbox, "edit", commandWidgetClass, True);
BBoxAddButton(buttonbox, "save", commandWidgetClass, False);
BBoxAddButton(buttonbox, "print", commandWidgetClass, True);
BBoxAddButton(buttonbox, "delete", commandWidgetClass, True);
}
static void FillCompButtons(
Scrn scrn)
{
ButtonBox buttonbox = scrn->viewbuttons;
BBoxAddButton(buttonbox, "close", commandWidgetClass, True);
BBoxAddButton(buttonbox, "send", commandWidgetClass, True);
BBoxAddButton(buttonbox, "reset", commandWidgetClass, True);
BBoxAddButton(buttonbox, "compose", commandWidgetClass, True);
BBoxAddButton(buttonbox, "save", commandWidgetClass, True);
BBoxAddButton(buttonbox, "insert", commandWidgetClass, True);
}
static void MakeCommandMenu(
Scrn scrn,
XmhMenuButtonDesc mbd)
{
register Cardinal i;
Cardinal n;
Widget menu;
ButtonBox buttonbox = scrn->mainbuttons;
XmhMenuEntry e;
Boolean indent;
WidgetClass widgetclass;
Arg args[4];
static XtCallbackRec callbacks[] = {
{ (XtCallbackProc) NULL, (XtPointer) NULL},
{ (XtCallbackProc) NULL, (XtPointer) NULL},
{ (XtCallbackProc) NULL, (XtPointer) NULL},
};
n = 0;
if (mbd->id == XMH_SEQUENCE) {
XtSetArg(args[n], XtNallowShellResize, True); n++;
}
menu = XtCreatePopupShell(mbd->menu_name, simpleMenuWidgetClass,
scrn->widget, args, n);
indent = (mbd->id == XMH_SEQUENCE || mbd->id == XMH_OPTION) ? True : False;
e = mbd->entry;
for (i=0; i < mbd->num_entries; i++, e++) {
n = 0;
if (e->function) {
callbacks[0].callback = e->function;
callbacks[0].closure = (XtPointer) scrn;
callbacks[1].callback = (app_resources.sticky_menu
? (XtCallbackProc) DoRememberMenuSelection
: (XtCallbackProc) NULL);
XtSetArg(args[n], XtNcallback, callbacks); n++;
if (indent) { XtSetArg(args[n], XtNleftMargin, 18); n++; }
widgetclass = smeBSBObjectClass;
} else
widgetclass = smeLineObjectClass;
XtCreateManagedWidget(e->name, widgetclass, menu, args, n);
}
AttachMenuToButton( BBoxFindButtonNamed( buttonbox, mbd->button_name),
menu, mbd->menu_name);
if (mbd->id == XMH_OPTION && app_resources.reverse_read_order)
ToggleMenuItem(XtNameToWidget(menu, "reverse"), True);
}
static void MakeTocAndView(Scrn scrn)
{
register int i;
XmhMenuButtonDesc mbd;
ButtonBox buttonbox;
char *name;
static XawTextSelectType sarray[] = {XawselectLine,
XawselectPosition,
XawselectAll,
XawselectNull};
static Arg args[] = {
{ XtNselectTypes, (XtArgVal) sarray},
{ XtNdisplayCaret, (XtArgVal) False}
};
scrn->mainbuttons = BBoxCreate(scrn, "menuBox");
scrn->folderlabel = CreateTitleBar(scrn, "folderTitlebar");
scrn->folderbuttons = BBoxCreate(scrn, "folders");
scrn->toclabel = CreateTitleBar(scrn, "tocTitlebar");
scrn->tocwidget = CreateTextSW(scrn, "toc", args, XtNumber(args));
if (app_resources.command_button_count > 0)
scrn->miscbuttons = BBoxCreate(scrn, "commandBox");
scrn->viewlabel = CreateTitleBar(scrn, "viewTitlebar");
scrn->viewwidget = CreateTextSW(scrn, "view", args, (Cardinal) 0);
buttonbox = scrn->mainbuttons;
mbd = MenuBoxButtons;
for (i=0; i < XtNumber(MenuBoxButtons); i++, mbd++) {
name = mbd->button_name;
BBoxAddButton(buttonbox, name, menuButtonWidgetClass, True);
MakeCommandMenu(scrn, mbd);
}
buttonbox = scrn->folderbuttons;
for (i=0 ; i<numFolders ; i++) {
name = TocName(folderList[i]);
if (! IsSubfolder(name))
BBoxAddButton(buttonbox, name, menuButtonWidgetClass, True);
if (app_resources.new_mail_check &&
numScrns > 1 &&
TocCanIncorporate(folderList[i]))
BBoxMailFlag(buttonbox, name, TocHasMail(folderList[i]));
}
if (app_resources.command_button_count > 0) {
char name[12];
if (app_resources.command_button_count > 500)
app_resources.command_button_count = 500;
for (i=1; i <= app_resources.command_button_count; i++) {
sprintf(name, "button%d", i);
BBoxAddButton(scrn->miscbuttons, name, commandWidgetClass, True);
}
}
}
static void MakeView(Scrn scrn)
{
scrn->viewlabel = CreateTitleBar(scrn, "viewTitlebar");
scrn->viewwidget = CreateTextSW(scrn, "view", (ArgList)NULL, (Cardinal)0);
scrn->viewbuttons = BBoxCreate(scrn, "viewButtons");
FillViewButtons(scrn);
}
static void MakeComp(Scrn scrn)
{
scrn->viewlabel = CreateTitleBar(scrn, "composeTitlebar");
scrn->viewwidget = CreateTextSW(scrn, "comp", (ArgList)NULL, (Cardinal)0);
scrn->viewbuttons = BBoxCreate(scrn, "compButtons");
FillCompButtons(scrn);
}
Scrn CreateNewScrn(ScrnKind kind)
{
int i;
Scrn scrn;
static Arg arglist[] = {
{ XtNgeometry, (XtArgVal) NULL},
{ XtNinput, (XtArgVal) True}
};
for (i=0 ; i<numScrns ; i++)
if (scrnList[i]->kind == kind && !scrnList[i]->mapped)
return scrnList[i];
switch (kind) {
case STtocAndView: arglist[0].value =
(XtArgVal)app_resources.toc_geometry; break;
case STview: arglist[0].value =
(XtArgVal)app_resources.view_geometry; break;
case STcomp: arglist[0].value =
(XtArgVal)app_resources.comp_geometry; break;
case STpick: arglist[0].value =
(XtArgVal)app_resources.pick_geometry; break;
}
numScrns++;
scrnList = (Scrn *)
XtRealloc((char *) scrnList, (unsigned) numScrns*sizeof(Scrn));
scrn = scrnList[numScrns - 1] = XtNew(ScrnRec);
bzero((char *)scrn, sizeof(ScrnRec));
scrn->kind = kind;
if (numScrns == 1) scrn->parent = toplevel;
else scrn->parent = XtCreatePopupShell(
progName, topLevelShellWidgetClass,
toplevel, arglist, XtNumber(arglist));
XtAugmentTranslations(scrn->parent,
app_resources.wm_protocols_translations);
scrn->widget =
XtCreateManagedWidget(progName, panedWidgetClass, scrn->parent,
(ArgList) NULL, (Cardinal) 0);
switch (kind) {
case STtocAndView: MakeTocAndView(scrn); break;
case STview: MakeView(scrn); break;
case STcomp: MakeComp(scrn); break;
default: break;
}
if (kind != STpick) {
int theight, min, max;
Arg args[1];
DEBUG("Realizing...")
XtRealizeWidget(scrn->parent);
DEBUG(" done.\n")
switch (kind) {
case STtocAndView:
BBoxLockSize(scrn->mainbuttons);
BBoxLockSize(scrn->folderbuttons);
theight = GetHeight(scrn->tocwidget) + GetHeight(scrn->viewwidget);
theight = app_resources.toc_percentage * theight / 100;
XawPanedGetMinMax((Widget) scrn->tocwidget, &min, &max);
XawPanedSetMinMax((Widget) scrn->tocwidget, theight, theight);
XawPanedSetMinMax((Widget) scrn->tocwidget, min, max);
if (scrn->miscbuttons)
BBoxLockSize(scrn->miscbuttons);
case STview:
XtSetArg(args[0], XtNtranslations, &(scrn->edit_translations));
XtGetValues(scrn->viewwidget, args, (Cardinal) 1);
XtInstallAllAccelerators(scrn->widget, scrn->widget);
if (kind == STtocAndView)
XtInstallAllAccelerators(scrn->tocwidget, scrn->widget);
XtInstallAllAccelerators(scrn->viewwidget, scrn->widget);
XtSetArg(args[0], XtNtranslations, &(scrn->read_translations));
XtGetValues(scrn->viewwidget, args, (Cardinal) 1);
if (kind == STview)
BBoxLockSize(scrn->viewbuttons);
break;
case STcomp:
BBoxLockSize(scrn->viewbuttons);
XtInstallAllAccelerators(scrn->viewwidget, scrn->widget);
XtSetKeyboardFocus(scrn->parent, scrn->viewwidget);
break;
default:
break;
}
InitBusyCursor(scrn);
XDefineCursor(XtDisplay(scrn->parent), XtWindow(scrn->parent),
app_resources.cursor);
(void) XSetWMProtocols(XtDisplay(scrn->parent), XtWindow(scrn->parent),
protocolList, XtNumber(protocolList));
}
scrn->mapped = False;
return scrn;
}
Scrn NewViewScrn(void)
{
return CreateNewScrn(STview);
}
Scrn NewCompScrn(void)
{
Scrn scrn;
scrn = CreateNewScrn(STcomp);
scrn->assocmsg = (Msg)NULL;
return scrn;
}
void ScreenSetAssocMsg(Scrn scrn, Msg msg)
{
scrn->assocmsg = msg;
}
void DestroyScrn(Scrn scrn)
{
if (scrn->mapped) {
scrn->mapped = False;
XtPopdown(scrn->parent);
TocSetScrn((Toc) NULL, scrn);
MsgSetScrnForce((Msg) NULL, scrn);
lastInput.win = -1;
}
}
void MapScrn(Scrn scrn)
{
if (!scrn->mapped) {
XtPopup(scrn->parent, XtGrabNone);
scrn->mapped = True;
}
}
Scrn ScrnFromWidget(Widget w)
{
register int i;
while (w && ! XtIsTopLevelShell(w))
w = XtParent(w);
if (w) {
for (i=0 ; i<numScrns ; i++) {
if (w == (Widget) scrnList[i]->parent)
return scrnList[i];
}
}
Punt("ScrnFromWidget failed!");
return NULL;
}
static void EnableCallback(Widget w, XtPointer data, XtPointer junk)
{
EnableProperButtons( (Scrn) data);
}
#define SetButton(buttonbox, name, value) \
if (value) BBoxEnable(BBoxFindButtonNamed(buttonbox, name)); \
else BBoxDisable(BBoxFindButtonNamed(buttonbox, name));
void EnableProperButtons(Scrn scrn)
{
int value, changed, reapable;
Button button;
if (scrn) {
switch (scrn->kind) {
case STtocAndView:
button = BBoxFindButtonNamed
(scrn->mainbuttons, MenuBoxButtons[XMH_TOC].button_name);
value = TocCanIncorporate(scrn->toc);
SendMenuEntryEnableMsg(button, "inc", value);
button = BBoxFindButtonNamed
(scrn->mainbuttons, MenuBoxButtons[XMH_SEQUENCE].button_name);
value = TocHasSequences(scrn->toc);
SendMenuEntryEnableMsg(button, "openSeq", value);
SendMenuEntryEnableMsg(button, "addToSeq", value);
SendMenuEntryEnableMsg(button, "removeFromSeq", value);
SendMenuEntryEnableMsg(button, "deleteSeq", value);
button = BBoxFindButtonNamed
(scrn->mainbuttons, MenuBoxButtons[XMH_VIEW].button_name);
value = (scrn->msg != NULL && !MsgGetEditable(scrn->msg));
SendMenuEntryEnableMsg(button, "edit", value);
SendMenuEntryEnableMsg(button, "save",
scrn->msg != NULL && !value);
break;
case STview:
value = (scrn->msg != NULL && !MsgGetEditable(scrn->msg));
SetButton(scrn->viewbuttons, "edit", value);
SetButton(scrn->viewbuttons, "save", scrn->msg != NULL && !value);
break;
case STcomp:
if (scrn->msg != NULL) {
changed = MsgChanged(scrn->msg);
reapable = MsgGetReapable(scrn->msg);
SetButton(scrn->viewbuttons, "send", changed || !reapable);
SetButton(scrn->viewbuttons, "save", changed || reapable);
SetButton(scrn->viewbuttons, "insert",
scrn->assocmsg != NULL ? True : False);
if (!changed)
MsgSetCallOnChange(scrn->msg, EnableCallback,
(XtPointer) scrn);
else
MsgSetCallOnChange(scrn->msg, (XtCallbackProc) NULL,
(XtPointer) NULL);
} else {
BBoxDisable( BBoxFindButtonNamed(scrn->viewbuttons, "send"));
BBoxDisable( BBoxFindButtonNamed(scrn->viewbuttons, "save"));
BBoxDisable( BBoxFindButtonNamed(scrn->viewbuttons, "insert"));
}
break;
default:
break;
}
}
}