Files
xsrc/external/mit/xmh/dist/tocfuncs.c

1079 lines
25 KiB
C

/*
* $XConsortium: tocfuncs.c /main/36 1996/02/02 14:27:42 kaleb $
*
*
* COPYRIGHT 1987, 1989
* DIGITAL EQUIPMENT CORPORATION
* MAYNARD, MASSACHUSETTS
* ALL RIGHTS RESERVED.
*
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
* SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
* DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
* ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
*
* IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT
* RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN
* ADDITION TO THAT SET FORTH ABOVE.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Digital Equipment Corporation not be
* used in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission.
*/
/* $XFree86: xc/programs/xmh/tocfuncs.c,v 1.3 2001/10/28 03:34:39 tsi Exp $ */
/* tocfuncs.c -- action procedures concerning things in the toc widget. */
#include "xmh.h"
#include "tocutil.h"
#include "actions.h"
#define MAX_SYSTEM_LEN 510
Boolean UserWantsAction(
Widget w,
Scrn scrn)
{
/* Commands in the command menus invoke callbacks directly.
* Keyboard accelerators use the command menus as source widgets.
* Actions can also be specified in the translations for menu buttons.
* Actions can also be specified in the translations for menus.
* In fact, the user can attach actions to any (reasonable) widget.
*
* The purpose of this check is to prevent actions specified as
* translations for folder menus and for folder buttons from executing
* after the mouse pointer has left the folder button or the when the
* mouse button is released outside of the folder menu.
*
* The side effect of this routine is that it restricts keyboard
* accelerators from originating from folder buttons or folder menus.
*/
if (XtIsSubclass(w, menuButtonWidgetClass) && /* w is a menu button */
w != LastMenuButtonPressed) /* pointer left the window */
return False;
if (XtIsSubclass(w, simpleMenuWidgetClass) && /* w is a menu */
(! XawSimpleMenuGetActiveEntry(w)) && /* no entry was selected */
(BBoxIsGrandparent(scrn->folderbuttons, w))) /* w is a folder menu */
return False;
return True;
}
/*ARGSUSED*/
static void NextAndPreviousView(
Scrn scrn,
Boolean next) /* if true, next or forward; if false, previous */
{
Toc toc = scrn->toc;
MsgList mlist;
FateType fate = Fignore;
Msg msg;
if (toc == NULL) return;
mlist = TocCurMsgList(toc);
if (mlist->nummsgs)
msg = (next ? mlist->msglist[0] : mlist->msglist[mlist->nummsgs - 1]);
else {
msg = TocGetCurMsg(toc);
if (msg && msg == scrn->msg)
msg = (next ? TocMsgAfter(toc, msg) : TocMsgBefore(toc, msg));
if (msg) fate = MsgGetFate(msg, (Toc *)NULL);
while (msg && ((app_resources.skip_deleted && fate == Fdelete)
|| (app_resources.skip_moved && fate == Fmove)
|| (app_resources.skip_copied && fate == Fcopy))) {
msg = (next ? TocMsgAfter(toc, msg) : TocMsgBefore(toc, msg));
if (msg) fate = MsgGetFate(msg, (Toc *)NULL);
}
}
if (msg) {
XtCallbackRec confirms[2];
if (next)
confirms[0].callback = (XtCallbackProc) DoNextView;
else
confirms[0].callback = (XtCallbackProc) DoPrevView;
confirms[0].closure = (XtPointer) scrn;
confirms[1].callback = (XtCallbackProc) NULL;
confirms[1].closure = (XtPointer) NULL;
if (MsgSetScrn(msg, scrn, confirms, (XtCallbackList) NULL) !=
NEEDS_CONFIRMATION) {
TocUnsetSelection(toc);
TocSetCurMsg(toc, msg);
}
}
FreeMsgList(mlist);
}
/*ARGSUSED*/
void DoReverseReadOrder(
Widget widget, /* the menu entry widget */
XtPointer client_data,
XtPointer call_data)
{
app_resources.reverse_read_order =
(app_resources.reverse_read_order ? False : True);
ToggleMenuItem(widget, app_resources.reverse_read_order);
}
/*ARGSUSED*/
void DoNextView(
Widget widget, /* unused */
XtPointer client_data,
XtPointer call_data) /* unused */
{
NextAndPreviousView((Scrn) client_data,
(app_resources.reverse_read_order ? False : True));
}
/*ARGSUSED*/
void XmhViewNextMessage(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoNextView(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoPrevView(
Widget widget, /* unused */
XtPointer client_data,
XtPointer call_data) /* unused */
{
NextAndPreviousView((Scrn) client_data,
(app_resources.reverse_read_order ? True : False));
}
/*ARGSUSED*/
void XmhViewPreviousMessage(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoPrevView(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoViewNew(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
Toc toc = scrn->toc;
Scrn vscrn;
MsgList mlist;
if (toc == NULL) return;
mlist = CurMsgListOrCurMsg(toc);
if (mlist->nummsgs) {
vscrn = NewViewScrn();
(void) MsgSetScrn(mlist->msglist[0], vscrn, (XtCallbackList) NULL,
(XtCallbackList) NULL);
MapScrn(vscrn);
}
FreeMsgList(mlist);
}
/*ARGSUSED*/
void XmhViewInNewWindow(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoViewNew(w, (XtPointer) scrn, (XtPointer) NULL);
}
static void DoForwardMsg(
Scrn scrn,
String *params,
Cardinal num_params)
{
Toc toc = scrn->toc;
MsgList mlist;
if (toc == NULL) return;
mlist = CurMsgListOrCurMsg(toc);
if (mlist->nummsgs)
CreateForward(mlist, params, num_params);
FreeMsgList(mlist);
}
/*ARGSUSED*/
void DoForward(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
DoForwardMsg((Scrn) client_data, (String *)NULL, (Cardinal)0);
}
/*ARGSUSED*/
void XmhForward(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoForwardMsg(scrn, params, *num_params);
}
/*ARGSUSED*/
void DoTocUseAsComp(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
Toc toc = scrn->toc;
Scrn vscrn;
MsgList mlist;
Msg msg;
if (toc == NULL) return;
mlist = CurMsgListOrCurMsg(toc);
if (mlist->nummsgs) {
vscrn = NewCompScrn();
if (DraftsFolder == toc) {
msg = mlist->msglist[0];
} else {
msg = TocMakeNewMsg(DraftsFolder);
MsgLoadCopy(msg, mlist->msglist[0]);
MsgSetTemporary(msg);
}
MsgSetScrnForComp(msg, vscrn);
MapScrn(vscrn);
}
FreeMsgList(mlist);
}
/*ARGSUSED*/
void XmhUseAsComposition(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoTocUseAsComp(w, (XtPointer) scrn, (XtPointer) NULL);
}
/* Utility: change the fate of a set of messages. */
static void MarkMessages(Scrn scrn, FateType fate, int skip)
{
Toc toc = scrn->toc;
Toc desttoc;
int i;
MsgList mlist;
Msg msg;
if (toc == NULL) return;
if (fate == Fcopy || fate == Fmove)
desttoc = SelectedToc(scrn);
else
desttoc = NULL;
if (desttoc == toc)
Feep(XkbBI_MinorError,0,None);
else {
mlist = TocCurMsgList(toc);
if (mlist->nummsgs == 0) {
msg = TocGetCurMsg(toc);
if (msg) {
MsgSetFate(msg, fate, desttoc);
if (skip)
DoNextView(scrn->widget, (XtPointer) scrn,
(XtPointer) NULL);
}
} else {
for (i = 0; i < mlist->nummsgs; i++)
MsgSetFate(mlist->msglist[i], fate, desttoc);
}
FreeMsgList(mlist);
}
}
/*ARGSUSED*/
void XmhMarkDelete(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoDelete(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoDelete(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
MarkMessages(scrn, Fdelete, app_resources.skip_deleted);
}
/*ARGSUSED*/
void DoCopy(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
MarkMessages(scrn, Fcopy, app_resources.skip_copied);
}
/*ARGSUSED*/
void XmhMarkCopy(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoCopy(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoMove(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
MarkMessages(scrn, Fmove, app_resources.skip_moved);
}
/*ARGSUSED*/
void XmhMarkMove(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoMove(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoUnmark(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
MarkMessages(scrn, Fignore, FALSE);
}
/*ARGSUSED*/
void XmhUnmark(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoUnmark(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoCommit(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
TocCommitChanges(w, (XtPointer) scrn->toc, (XtPointer) NULL);
}
/*ARGSUSED*/
void XmhCommitChanges(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
TocCommitChanges(w, (XtPointer) scrn->toc, (XtPointer) NULL);
}
/*ARGSUSED*/
void XmhShellCommand(
Widget w, /* any widget on same scrn as the messages */
XEvent *event, /* unused */
String *params, /* shell command to execute with msgs appended */
Cardinal *num_params)
{
int i, len, used;
MsgList mlist;
String *p;
Scrn scrn = ScrnFromWidget(w);
char str[MAX_SYSTEM_LEN];
if (! UserWantsAction(w, scrn) || ! scrn->toc)
return;
if (! *num_params) {
PopupError(scrn->parent, "XmhShellCommand: no command given.");
return;
}
used = 0;
p = params;
for (i = *num_params; --i >= 0; p++) {
len = strlen(*p);
if ((used + len + 1) >= MAX_SYSTEM_LEN) {
PopupError(scrn->parent, "XmhShellCommand: command too long.");
return;
}
strncpy(&str[used], *p, len);
str[(used += len)] = ' ';
used++;
}
str[used] = '\0';
mlist = CurMsgListOrCurMsg(scrn->toc);
if (mlist->nummsgs) {
char *msg;
int prefix = used;
i = 0;
while (i < mlist->nummsgs) {
used = prefix;
while (i < mlist->nummsgs &&
(msg = MsgFileName(mlist->msglist[i])) &&
(used + (len = strlen(msg)) + 1) < MAX_SYSTEM_LEN) {
strncpy(&str[used], msg, len);
str[(used += len)] = ' ';
used++;
i++;
}
if (used != prefix) {
char **argv;
str[used] = '\0';
DEBUG( str );
argv = MakeArgv(3);
argv[0] = "/bin/sh";
argv[1] = "-c"; /* commands are read from the next argument */
argv[2] = str;
(void) DoCommand(argv, (char*)NULL, (char*)NULL);
/* a "notice" popup should appear with stderr output */
XtFree((char*)argv);
}
}
} else
PopupError(scrn->parent, "XmhShellCommand: no messages selected.");
FreeMsgList(mlist);
}
void XmhPrint(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
if (! num_params || ! *num_params) {
/* use the print command specified in application resources */
Cardinal argc = 1;
String *argv = MakeArgv(argc);
argv[0] = app_resources.print_command;
XmhShellCommand(w, event, argv, &argc);
XtFree((char *) argv);
} else {
/* do whatever the user has specified as action parameters */
XmhShellCommand(w, event, params, num_params);
}
}
/*ARGSUSED*/
void DoPrint(
Widget w,
XtPointer client_data,
XtPointer call_data) /* unused */
{
Scrn scrn = (Scrn) client_data;
Cardinal num_params = 0;
/* The callback interface will not be entered unless the user requested
* the action, so pass a widget which will succeed the test in
* UserWantsAction.
*/
XmhPrint(scrn->parent, (XEvent*)NULL, (String*)NULL, &num_params);
}
/*ARGSUSED*/
void DoPack(
Widget widget,
XtPointer client_data,
XtPointer call_data) /* unused */
{
Scrn scrn = (Scrn) client_data;
Toc toc = scrn->toc;
XtCallbackRec confirms[2];
char **argv;
if (toc == NULL) return;
confirms[0].callback = (XtCallbackProc) DoPack;
confirms[0].closure = (XtPointer) scrn;
confirms[1].callback = (XtCallbackProc) NULL;
confirms[1].closure = (XtPointer) NULL;
if (TocConfirmCataclysm(toc, confirms, (XtCallbackRec *) NULL))
return;
argv = MakeArgv(4);
argv[0] = "folder";
argv[1] = TocMakeFolderName(toc);
argv[2] = "-pack";
argv[3] = "-fast";
if (app_resources.block_events_on_busy) ShowBusyCursor();
DoCommand(argv, (char *) NULL, (char *) NULL);
XtFree(argv[1]);
XtFree((char *) argv);
TocForceRescan(toc);
if (app_resources.block_events_on_busy) UnshowBusyCursor();
}
/*ARGSUSED*/
void XmhPackFolder(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoPack(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoSort(
Widget widget,
XtPointer client_data,
XtPointer call_data) /* unused */
{
Scrn scrn = (Scrn) client_data;
Toc toc = scrn->toc;
char ** argv;
XtCallbackRec confirms[2];
if (toc == NULL) return;
confirms[0].callback = (XtCallbackProc) DoSort;
confirms[0].closure = (XtPointer) scrn;
confirms[1].callback = (XtCallbackProc) NULL;
confirms[1].closure = (XtPointer) NULL;
if (TocConfirmCataclysm(toc, confirms, (XtCallbackRec *) NULL))
return;
argv = MakeArgv(3);
argv[0] = "sortm";
argv[1] = TocMakeFolderName(toc);
argv[2] = "-noverbose";
if (app_resources.block_events_on_busy) ShowBusyCursor();
DoCommand(argv, (char *) NULL, (char *) NULL);
XtFree(argv[1]);
XtFree((char *) argv);
TocForceRescan(toc);
if (app_resources.block_events_on_busy) UnshowBusyCursor();
}
/*ARGSUSED*/
void XmhSortFolder(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoSort(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void XmhForceRescan(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoForceRescan(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoForceRescan(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
Toc toc = scrn->toc;
if (toc == NULL) return;
if (app_resources.block_events_on_busy) ShowBusyCursor();
TocForceRescan(toc);
if (app_resources.block_events_on_busy) UnshowBusyCursor();
}
/*ARGSUSED*/
void XmhCheckForNewMail(
Widget w,
XEvent *e,
String *p,
Cardinal *n)
{
TocCheckForNewMail(True);
}
/* Incorporate new mail. */
/*ARGSUSED*/
void XmhIncorporateNewMail(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn)) {
if (TocCanIncorporate(scrn->toc))
DoIncorporateNewMail(w, (XtPointer) scrn, (XtPointer) NULL);
}
}
void DoIncorporateNewMail(
Widget w, /* unused */
XtPointer client_data, /* screen */
XtPointer call_data) /* unused */
{
Scrn scrn = (Scrn) client_data;
Toc toc = scrn->toc;
int i;
int newmail;
if (! toc) return;
newmail = TocIncorporate(toc);
if (app_resources.show_on_inc && newmail)
DoNextView(w, client_data, call_data);
if (app_resources.new_mail_check)
/* update the folder button */
for (i=0; i < numScrns; i++) {
scrn = scrnList[i];
if (scrn->kind == STtocAndView)
/* give visual indication of no mail waiting */
BBoxMailFlag(scrn->folderbuttons, TocName(toc), False);
}
if (app_resources.mail_waiting_flag)
/* update the icon */
TocCheckForNewMail(False);
}
static void DoReplyMsg(
Scrn scrn,
String *params,
Cardinal num_params)
{
Toc toc = scrn->toc;
Scrn nscrn;
MsgList mlist;
Msg msg;
if (toc == NULL) return;
mlist = CurMsgListOrCurMsg(toc);
if (mlist->nummsgs) {
nscrn = NewCompScrn();
ScreenSetAssocMsg(nscrn, mlist->msglist[0]);
msg = TocMakeNewMsg(DraftsFolder);
MsgSetTemporary(msg);
MsgLoadReply(msg, mlist->msglist[0], params, num_params);
MsgSetScrnForComp(msg, nscrn);
MapScrn(nscrn);
}
FreeMsgList(mlist);
}
/*ARGSUSED*/
void DoReply(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
DoReplyMsg((Scrn) client_data, (String *)NULL, (Cardinal)0);
}
/*ARGSUSED*/
void XmhReply(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoReplyMsg(scrn, params, *num_params);
}
/*ARGSUSED*/
void DoPickMessages(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
Toc toc = scrn->toc;
Scrn nscrn;
char * toseq;
Sequence selectedseq;
Boolean recycled;
if (toc == NULL) return;
if ((selectedseq = TocSelectedSequence(toc)) == NULL)
toseq = "temp";
else {
toseq = selectedseq->name;
if (strcmp(toseq, "all") == 0)
toseq = "temp";
}
nscrn = CreateNewScrn(STpick);
recycled = (nscrn->pick) ? True : False;
AddPick(nscrn, toc, (TocViewedSequence(toc))->name, toseq);
DEBUG("Realizing Pick...")
XtRealizeWidget(nscrn->parent);
DEBUG(" done.\n")
if (! recycled) {
InitBusyCursor(nscrn);
XDefineCursor(XtDisplay(nscrn->parent), XtWindow(nscrn->parent),
app_resources.cursor);
(void) XSetWMProtocols(XtDisplay(toplevel), XtWindow(nscrn->parent),
protocolList, XtNumber(protocolList));
}
MapScrn(nscrn);
}
/*ARGSUSED*/
void XmhPickMessages(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
DoPickMessages(w, (XtPointer) scrn, (XtPointer) NULL);
}
/*ARGSUSED*/
void DoSelectSequence(
Widget widget, /* sequence menu entry object */
XtPointer client_data, /* the screen */
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
Toc toc = (Toc) scrn->toc;
Sequence seq;
if ((seq = TocSelectedSequence(toc)) != NULL) {
Widget item, menu;
Button button;
button = BBoxFindButtonNamed
(scrn->mainbuttons, MenuBoxButtons[XMH_SEQUENCE].button_name);
menu = BBoxMenuOfButton(button);
if ((item = XtNameToWidget(menu, seq->name)) != NULL)
ToggleMenuItem(item, False);
}
ToggleMenuItem(widget, True);
TocSetSelectedSequence(toc, TocGetSeqNamed(toc, XtName(widget)));
}
/*ARGSUSED*/
void DoOpenSeq(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
Toc toc = scrn->toc;
if (toc == NULL) return;
TocChangeViewedSeq(toc, TocSelectedSequence(toc));
}
/*ARGSUSED*/
void XmhOpenSequence(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Widget entry_object;
Scrn scrn = ScrnFromWidget(w);
Sequence selected_sequence;
/* In case this action is called from translations defined by the
* user on folder menu buttons or on folder menu widgets.
*/
if (! UserWantsAction(w, scrn))
return;
/* In case there is nothing to do anyway. */
if (! TocHasSequences(scrn->toc))
return;
/* In case the action was given the name of a sequence to open. */
if (*num_params) {
Toc toc = scrn->toc;
if ((selected_sequence = TocGetSeqNamed(toc, params[0]))) {
TocSetSelectedSequence(toc, selected_sequence);
TocChangeViewedSeq(toc, selected_sequence);
}
return;
}
/* In case this action is a translation on the sequence menu. */
if ((strcmp(XtName(w), "sequenceMenu") == 0) &&
(event->type == ButtonRelease)) {
/* The user released the mouse button. We must distinguish between
* a button release on a selectable menu entry, and a button release
* occuring elsewhere. The button releases occuring elsewhere are
* either outside of the menu, or on unselectable menu entries.
*/
if ((entry_object = XawSimpleMenuGetActiveEntry(w)) == NULL)
return;
/* Some entry in the menu was selected. The menu entry's callback
* procedure has already executed. If a sequence name was selected,
* the callback procedure has caused that sequence to become the
* currently selected sequence. If selected menu entry object's
* name matches the currently selected sequence, we should open
* that sequence. Otherwise, the user must have selected a sequence
* manipulation command, such as Pick. The assumptions here are that
* the name of a menu entry object which represents a sequence is
* identical to the name of the sequence, and in the translations,
* that the notify() action was specified before this action.
*/
if ((selected_sequence = TocSelectedSequence(scrn->toc)) &&
(strcmp(XtName(entry_object), selected_sequence->name) == 0))
DoOpenSeq(w, (XtPointer) scrn, (XtPointer) NULL);
return;
}
/* An accelerator open sequence function */
DoOpenSeq(w, (XtPointer) scrn, (XtPointer) NULL);
}
typedef enum {ADD, REMOVE, DELETE} TwiddleOperation;
static void TwiddleSequence(Scrn scrn, TwiddleOperation op)
{
Toc toc = scrn->toc;
char **argv, str[100];
int i;
MsgList mlist;
Sequence selectedseq;
if (toc == NULL || ((selectedseq = TocSelectedSequence(toc)) == NULL))
return;
if (strcmp(selectedseq->name, "all") == 0) {
Feep(XkbBI_MinorError,0,None);
return;
}
if (op == DELETE)
mlist = MakeNullMsgList();
else {
mlist = CurMsgListOrCurMsg(toc);
if (mlist->nummsgs == 0) {
FreeMsgList(mlist);
Feep(XkbBI_MinorError,0,None);
return;
}
}
argv = MakeArgv(6 + mlist->nummsgs);
argv[0] = "mark";
argv[1] = TocMakeFolderName(toc);
argv[2] = "-sequence";
argv[3] = selectedseq->name;
switch (op) {
case ADD:
argv[4] = "-add";
argv[5] = "-nozero";
break;
case REMOVE:
argv[4] = "-delete";
argv[5] = "-nozero";
break;
case DELETE:
argv[4] = "-delete";
argv[5] = "all";
break;
}
for (i = 0; i < mlist->nummsgs; i++) {
(void) sprintf(str, "%d", MsgGetId(mlist->msglist[i]));
argv[6 + i] = XtNewString(str);
}
DoCommand(argv, (char *) NULL, (char *) NULL);
for (i = 0; i < mlist->nummsgs; i++)
XtFree((char *) argv[6 + i]);
XtFree(argv[1]);
XtFree((char *) argv);
FreeMsgList(mlist);
TocReloadSeqLists(toc);
}
/*ARGSUSED*/
void DoAddToSeq(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
TwiddleSequence(scrn, ADD);
}
/*ARGSUSED*/
void XmhAddToSequence(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (! UserWantsAction(w, scrn))
return;
if ((strcmp(XtName(w), "sequenceMenu") == 0) &&
(event->type == ButtonRelease) &&
(XawSimpleMenuGetActiveEntry(w) == NULL))
return;
if (TocHasSequences(scrn->toc))
TwiddleSequence(scrn, ADD);
}
/*ARGSUSED*/
void DoRemoveFromSeq(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
TwiddleSequence(scrn, REMOVE);
}
/*ARGSUSED*/
void XmhRemoveFromSequence(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (UserWantsAction(w, scrn))
if (TocHasSequences(scrn->toc))
TwiddleSequence(scrn, REMOVE);
}
/*ARGSUSED*/
void DoDeleteSeq(
Widget w,
XtPointer client_data,
XtPointer call_data)
{
Scrn scrn = (Scrn) client_data;
TwiddleSequence(scrn, DELETE);
TUCheckSequenceMenu(scrn->toc);
}
/*ARGSUSED*/
void XmhDeleteSequence(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params)
{
Scrn scrn = ScrnFromWidget(w);
if (! UserWantsAction(w, scrn))
return;
if ((strcmp(XtName(w), "sequenceMenu") == 0) &&
(event->type == ButtonRelease) &&
(XawSimpleMenuGetActiveEntry(w) == NULL))
return;
if (TocHasSequences(scrn->toc))
DoDeleteSeq(w, (XtPointer) scrn, (XtPointer) NULL);
}