source: trunk/third/xmh/tocfuncs.c @ 9658

Revision 9658, 25.8 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9657, which included commits to RCS files with non-trunk default branches.
RevLine 
[9657]1/*
2 * $XConsortium: tocfuncs.c,v 2.38 91/07/17 21:28:33 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/* tocfuncs.c -- action procedures concerning things in the toc widget. */
29
30#include "xmh.h"
31#include "tocutil.h"
32
33#define MAX_SYSTEM_LEN 510
34
35Boolean UserWantsAction(w, scrn) /* general action procedure "filter" */
36    Widget      w;
37    Scrn        scrn;
38{
39    /* Commands in the command menus invoke callbacks directly.
40     * Keyboard accelerators use the command menus as source widgets.
41     * Actions can also be specified in the translations for menu buttons.
42     * Actions can also be specified in the translations for menus.
43     * In fact, the user can attach actions to any (reasonable) widget.
44     *
45     * The purpose of this check is to prevent actions specified as
46     * translations for folder menus and for folder buttons from executing
47     * after the mouse pointer has left the folder button or the when the
48     * mouse button is released outside of the folder menu.
49     *
50     * The side effect of this routine is that it restricts keyboard
51     * accelerators from originating from folder buttons or folder menus.
52     */
53       
54    if (XtIsSubclass(w, menuButtonWidgetClass) && /* w is a menu button */
55        w != LastMenuButtonPressed)               /* pointer left the window */
56        return False;
57
58    if (XtIsSubclass(w, simpleMenuWidgetClass) &&       /* w is a menu */
59        (! XawSimpleMenuGetActiveEntry(w)) &&   /* no entry was selected */
60        (BBoxIsGrandparent(scrn->folderbuttons, w)))  /* w is a folder menu */
61        return False;
62
63    return True;
64}
65
66
67/*ARGSUSED*/
68static void NextAndPreviousView(scrn, next)
69    Scrn        scrn;
70    Boolean     next;   /* if true, next or forward; if false, previous */
71{
72    Toc         toc = scrn->toc;
73    MsgList     mlist;
74    FateType    fate;
75    Msg         msg;
76
77    if (toc == NULL) return;
78    mlist = TocCurMsgList(toc);
79    if (mlist->nummsgs)
80        msg = (next ? mlist->msglist[0] : mlist->msglist[mlist->nummsgs - 1]);
81    else {
82        msg = TocGetCurMsg(toc);
83        if (msg && msg == scrn->msg)
84            msg = (next ? TocMsgAfter(toc, msg) : TocMsgBefore(toc, msg));
85        if (msg) fate = MsgGetFate(msg, (Toc *)NULL);
86        while (msg && ((app_resources.skip_deleted && fate == Fdelete)
87                || (app_resources.skip_moved && fate == Fmove)
88                || (app_resources.skip_copied && fate == Fcopy))) {
89            msg = (next ? TocMsgAfter(toc, msg) : TocMsgBefore(toc, msg));
90            if (msg) fate = MsgGetFate(msg, (Toc *)NULL);
91        }
92    }
93
94    if (msg) {
95        XtCallbackRec   confirms[2];
96        if (next)
97            confirms[0].callback = (XtCallbackProc) DoNextView;
98        else
99            confirms[0].callback = (XtCallbackProc) DoPrevView;
100        confirms[0].closure = (XtPointer) scrn;
101        confirms[1].callback = (XtCallbackProc) NULL;
102        confirms[1].closure = (XtPointer) NULL;
103        if (MsgSetScrn(msg, scrn, confirms, (XtCallbackList) NULL) !=
104            NEEDS_CONFIRMATION) {
105            TocUnsetSelection(toc);
106            TocSetCurMsg(toc, msg);
107        }
108    }
109    FreeMsgList(mlist);
110}
111
112
113/*ARGSUSED*/
114void DoReverseReadOrder(widget, client_data, call_data)
115    Widget      widget;         /* the menu entry widget */
116    XtPointer   client_data;
117    XtPointer   call_data;
118{
119    app_resources.reverse_read_order =
120        (app_resources.reverse_read_order ? False : True);
121    ToggleMenuItem(widget, app_resources.reverse_read_order);
122}
123
124
125/*ARGSUSED*/
126void DoNextView(widget, client_data, call_data)
127    Widget      widget;         /* unused */
128    XtPointer   client_data;
129    XtPointer   call_data;      /* unused */
130{
131    NextAndPreviousView((Scrn) client_data,
132                        (app_resources.reverse_read_order ? False : True));
133}
134
135/*ARGSUSED*/
136void XmhViewNextMessage(w, event, params, num_params)
137    Widget      w;
138    XEvent      *event;
139    String      *params;
140    Cardinal    *num_params;
141{
142    Scrn scrn = ScrnFromWidget(w);
143    if (UserWantsAction(w, scrn))
144        DoNextView(w, (XtPointer) scrn, (XtPointer) NULL);
145}
146
147/*ARGSUSED*/
148void DoPrevView(widget, client_data, call_data)
149    Widget      widget;         /* unused */
150    XtPointer   client_data;   
151    XtPointer   call_data;      /* unused */
152{
153    NextAndPreviousView((Scrn) client_data,
154                        (app_resources.reverse_read_order ? True : False));
155}
156
157/*ARGSUSED*/
158void XmhViewPreviousMessage(w, event, params, num_params)
159    Widget      w;
160    XEvent      *event;
161    String      *params;
162    Cardinal    *num_params;
163{
164    Scrn scrn = ScrnFromWidget(w);
165    if (UserWantsAction(w, scrn))
166        DoPrevView(w, (XtPointer) scrn, (XtPointer) NULL);
167}
168
169
170/*ARGSUSED*/
171void DoViewNew(w, client_data, call_data)
172    Widget      w;
173    XtPointer   client_data;
174    XtPointer   call_data;
175{
176    Scrn        scrn = (Scrn) client_data;
177    Toc         toc = scrn->toc;
178    Scrn        vscrn;
179    MsgList     mlist;
180
181    if (toc == NULL) return;
182    mlist = CurMsgListOrCurMsg(toc);
183    if (mlist->nummsgs) {
184        vscrn = NewViewScrn();
185        (void) MsgSetScrn(mlist->msglist[0], vscrn, (XtCallbackList) NULL,
186                          (XtCallbackList) NULL);
187        MapScrn(vscrn);
188    }
189    FreeMsgList(mlist);
190}
191
192
193/*ARGSUSED*/
194void XmhViewInNewWindow(w, event, params, num_params)
195    Widget      w;
196    XEvent      *event;
197    String      *params;
198    Cardinal    *num_params;
199{
200    Scrn scrn = ScrnFromWidget(w);
201    if (UserWantsAction(w, scrn))
202        DoViewNew(w, (XtPointer) scrn, (XtPointer) NULL);
203}
204
205
206/*ARGSUSED*/
207void DoForward(w, client_data, call_data)
208    Widget      w;
209    XtPointer   client_data;
210    XtPointer   call_data;
211{
212    Scrn        scrn = (Scrn) client_data;
213    Toc         toc = scrn->toc;
214    MsgList     mlist;
215
216    if (toc == NULL) return;
217    mlist = CurMsgListOrCurMsg(toc);
218    if (mlist->nummsgs)
219        CreateForward(mlist);
220    FreeMsgList(mlist);
221}
222
223
224/*ARGSUSED*/
225void XmhForward(w, event, params, num_params)
226    Widget      w;
227    XEvent      *event;
228    String      *params;
229    Cardinal    *num_params;
230{
231    Scrn scrn = ScrnFromWidget(w);
232    if (UserWantsAction(w, scrn))
233        DoForward(w, (XtPointer) scrn, (XtPointer) NULL);
234}
235
236
237/*ARGSUSED*/
238void DoTocUseAsComp(w, client_data, call_data)
239    Widget      w;
240    XtPointer   client_data;
241    XtPointer   call_data;
242{
243    Scrn        scrn = (Scrn) client_data;
244    Toc         toc = scrn->toc;
245    Scrn        vscrn;
246    MsgList     mlist;
247    Msg         msg;
248
249    if (toc == NULL) return;
250    mlist = CurMsgListOrCurMsg(toc);
251    if (mlist->nummsgs) {
252        vscrn = NewCompScrn();
253        if (DraftsFolder == toc) {
254            msg = mlist->msglist[0];
255        } else {
256            msg = TocMakeNewMsg(DraftsFolder);
257            MsgLoadCopy(msg, mlist->msglist[0]);
258            MsgSetTemporary(msg);
259        }
260        MsgSetScrnForComp(msg, vscrn);
261        MapScrn(vscrn);
262    }
263    FreeMsgList(mlist);
264}
265
266
267/*ARGSUSED*/
268void XmhUseAsComposition(w, event, params, num_params)
269    Widget      w;
270    XEvent      *event;
271    String      *params;
272    Cardinal    *num_params;
273{
274    Scrn scrn = ScrnFromWidget(w);
275    if (UserWantsAction(w, scrn))
276        DoTocUseAsComp(w, (XtPointer) scrn, (XtPointer) NULL);
277}
278
279
280/* Utility: change the fate of a set of messages. */
281
282static MarkMessages(scrn, fate, skip)
283Scrn scrn;
284FateType fate;
285int skip;
286{
287    Toc toc = scrn->toc;
288    Toc desttoc;
289    int i;
290    MsgList mlist;
291    Msg msg;
292    if (toc == NULL) return;
293    if (fate == Fcopy || fate == Fmove)
294        desttoc = SelectedToc(scrn);
295    else
296        desttoc = NULL;
297    if (desttoc == toc)
298        Feep();
299    else {
300        mlist = TocCurMsgList(toc);
301        if (mlist->nummsgs == 0) {
302            msg = TocGetCurMsg(toc);
303            if (msg) {
304                MsgSetFate(msg, fate, desttoc);
305                if (skip)
306                    DoNextView(scrn->widget, (XtPointer) scrn,
307                               (XtPointer) NULL);
308            }
309        } else {
310            for (i = 0; i < mlist->nummsgs; i++)
311                MsgSetFate(mlist->msglist[i], fate, desttoc);
312        }
313        FreeMsgList(mlist);
314    }
315}
316
317
318/*ARGSUSED*/
319void XmhMarkDelete(w, event, params, num_params)
320    Widget      w;
321    XEvent      *event;
322    String      *params;
323    Cardinal    *num_params;
324{
325    Scrn scrn = ScrnFromWidget(w);
326    if (UserWantsAction(w, scrn))
327        DoDelete(w, (XtPointer) scrn, (XtPointer) NULL);
328}
329
330
331/*ARGSUSED*/
332void DoDelete(w, client_data, call_data)
333    Widget      w;
334    XtPointer   client_data;
335    XtPointer   call_data;
336{
337    Scrn scrn = (Scrn) client_data;
338    MarkMessages(scrn, Fdelete, app_resources.skip_deleted);
339}
340
341
342/*ARGSUSED*/
343void DoCopy(w, client_data, call_data)
344    Widget      w;
345    XtPointer   client_data;
346    XtPointer   call_data;
347{
348    Scrn scrn = (Scrn) client_data;
349    MarkMessages(scrn, Fcopy, app_resources.skip_copied);
350}
351
352
353/*ARGSUSED*/
354void XmhMarkCopy(w, event, params, num_params)
355    Widget      w;
356    XEvent      *event;
357    String      *params;
358    Cardinal    *num_params;
359{
360    Scrn scrn = ScrnFromWidget(w);
361    if (UserWantsAction(w, scrn))
362        DoCopy(w, (XtPointer) scrn, (XtPointer) NULL);
363}
364
365
366/*ARGSUSED*/
367void DoMove(w, client_data, call_data)
368    Widget      w;
369    XtPointer   client_data;
370    XtPointer   call_data;
371{
372    Scrn scrn = (Scrn) client_data;
373    MarkMessages(scrn, Fmove, app_resources.skip_moved);
374}
375
376
377/*ARGSUSED*/
378void XmhMarkMove(w, event, params, num_params)
379    Widget      w;
380    XEvent      *event;
381    String      *params;
382    Cardinal    *num_params;
383{
384    Scrn scrn = ScrnFromWidget(w);
385    if (UserWantsAction(w, scrn))
386        DoMove(w, (XtPointer) scrn, (XtPointer) NULL);
387}
388
389
390/*ARGSUSED*/
391void DoUnmark(w, client_data, call_data)
392    Widget      w;
393    XtPointer   client_data;
394    XtPointer   call_data;
395{
396    Scrn scrn = (Scrn) client_data;
397    MarkMessages(scrn, Fignore, FALSE);
398}
399
400
401/*ARGSUSED*/
402void XmhUnmark(w, event, params, num_params)
403    Widget      w;
404    XEvent      *event;
405    String      *params;
406    Cardinal    *num_params;
407{
408    Scrn scrn = ScrnFromWidget(w);
409    if (UserWantsAction(w, scrn))
410        DoUnmark(w, (XtPointer) scrn, (XtPointer) NULL);
411}
412
413
414/*ARGSUSED*/
415void DoCommit(w, client_data, call_data)
416    Widget      w;
417    XtPointer   client_data;
418    XtPointer    call_data;
419{
420    Scrn        scrn = (Scrn) client_data;
421    TocCommitChanges(w, (XtPointer) scrn->toc, (XtPointer) NULL);
422}
423
424
425/*ARGSUSED*/
426void XmhCommitChanges(w, event, params, num_params)
427    Widget      w;
428    XEvent      *event;
429    String      *params;
430    Cardinal    *num_params;
431{
432    Scrn scrn = ScrnFromWidget(w);
433    if (UserWantsAction(w, scrn))
434        TocCommitChanges(w, (XtPointer) scrn->toc, (XtPointer) NULL);
435}
436
437
438/*ARGSUSED*/
439void XmhShellCommand(w, event, params, num_params)
440    Widget      w;       /* any widget on same scrn as the messages */
441    XEvent      *event;  /* unused */
442    String      *params; /* shell command to execute with msgs appended */
443    Cardinal    *num_params;
444{
445    int         i, len, used;
446    MsgList     mlist;
447    String      *p;
448    Scrn        scrn = ScrnFromWidget(w);
449    char        str[MAX_SYSTEM_LEN];
450
451    if (! UserWantsAction(w, scrn) || ! scrn->toc)
452        return;
453    if (! *num_params) {
454        PopupError(scrn->parent, "XmhShellCommand: no command given.");
455        return;
456    }
457    used = 0;
458    p = params;
459    for (i = *num_params; --i >= 0; p++) {
460        len = strlen(*p);
461        if ((used + len + 1) >= MAX_SYSTEM_LEN) {
462            PopupError(scrn->parent, "XmhShellCommand: command too long.");
463            return;
464        }
465        strncpy(&str[used], *p, len);
466        str[(used += len)] = ' ';
467        used++;
468    }
469    str[used] = '\0';
470
471    mlist = CurMsgListOrCurMsg(scrn->toc);
472    if (mlist->nummsgs) {
473        char *msg;
474        int prefix = used;
475        i = 0;
476        while (i < mlist->nummsgs) {
477            used = prefix;
478            while (i < mlist->nummsgs &&
479                   (msg = MsgFileName(mlist->msglist[i])) &&
480                   (used + (len = strlen(msg)) + 1) < MAX_SYSTEM_LEN) {
481                strncpy(&str[used], msg, len);
482                str[(used += len)] = ' ';
483                used++;
484                i++;
485            }
486            if (used != prefix) {
487                char **argv;
488                str[used] = '\0';
489                DEBUG( str );
490                argv = MakeArgv(3);
491                argv[0] = "/bin/sh";
492                argv[1] = "-c"; /* commands are read from the next argument */
493                argv[2] = str;
494                (void) DoCommand(argv, (char*)NULL, (char*)NULL);
495                /* a "notice" popup should appear with stderr output */
496                XtFree((char*)argv);
497            }
498        }
499    } else
500        PopupError(scrn->parent, "XmhShellCommand: no messages selected.");
501
502    FreeMsgList(mlist);
503}
504
505
506void XmhPrint(w, event, params, num_params)
507    Widget      w;
508    XEvent      *event;
509    String      *params;
510    Cardinal    *num_params;
511{
512    if (! num_params || ! *num_params) {
513        /* use the print command specified in application resources */
514        Cardinal argc = 1;
515        String *argv = MakeArgv(argc);
516        argv[0] = app_resources.print_command;
517        XmhShellCommand(w, event, argv, &argc);
518        XtFree((char *) argv);
519    } else {
520        /* do whatever the user has specified as action parameters */
521        XmhShellCommand(w, event, params, num_params);
522    }
523}
524
525
526/*ARGSUSED*/
527void DoPrint(w, client_data, call_data)
528    Widget      w;
529    XtPointer   client_data;
530    XtPointer   call_data;      /* unused */
531{
532    Scrn        scrn = (Scrn) client_data;
533    Cardinal    num_params = 0;
534    /* The callback interface will not be entered unless the user requested
535     * the action, so pass a widget which will succeed the test in
536     * UserWantsAction.
537     */
538    XmhPrint(scrn->parent, (XEvent*)NULL, (String*)NULL, &num_params);
539}
540
541
542/*ARGSUSED*/
543void DoPack(widget, client_data, call_data)
544    Widget      widget;
545    XtPointer   client_data;
546    XtPointer   call_data;      /* unused */
547{
548    Scrn        scrn = (Scrn) client_data;
549    Toc         toc = scrn->toc;
550    XtCallbackRec confirms[2];
551    char        **argv;
552   
553    if (toc == NULL) return;
554    confirms[0].callback = (XtCallbackProc) DoPack;
555    confirms[0].closure = (XtPointer) scrn;
556    confirms[1].callback = (XtCallbackProc) NULL;
557    confirms[1].closure = (XtPointer) NULL;
558    if (TocConfirmCataclysm(toc, confirms, (XtCallbackRec *) NULL))
559        return;
560    argv = MakeArgv(4);
561    argv[0] = "folder";
562    argv[1] = TocMakeFolderName(toc);
563    argv[2] = "-pack";
564    argv[3] = "-fast";
565    if (app_resources.block_events_on_busy) ShowBusyCursor();
566
567    DoCommand(argv, (char *) NULL, (char *) NULL);
568    XtFree(argv[1]);
569    XtFree((char *) argv);
570    TocForceRescan(toc);
571
572    if (app_resources.block_events_on_busy) UnshowBusyCursor();
573
574}
575
576
577/*ARGSUSED*/
578void XmhPackFolder(w, event, params, num_params)
579    Widget      w;
580    XEvent      *event;
581    String      *params;
582    Cardinal    *num_params;
583{
584    Scrn scrn = ScrnFromWidget(w);
585    if (UserWantsAction(w, scrn))
586        DoPack(w, (XtPointer) scrn, (XtPointer) NULL);
587}
588
589
590/*ARGSUSED*/
591void DoSort(widget, client_data, call_data)
592    Widget      widget;
593    XtPointer   client_data;
594    XtPointer   call_data;      /* unused */
595{
596    Scrn        scrn = (Scrn) client_data;
597    Toc         toc = scrn->toc;
598    char **     argv;
599    XtCallbackRec confirms[2];
600
601    if (toc == NULL) return;
602    confirms[0].callback = (XtCallbackProc) DoSort;
603    confirms[0].closure = (XtPointer) scrn;
604    confirms[1].callback = (XtCallbackProc) NULL;
605    confirms[1].closure = (XtPointer) NULL;
606    if (TocConfirmCataclysm(toc, confirms, (XtCallbackRec *) NULL))
607        return;
608    argv = MakeArgv(3);
609    argv[0] = "sortm";
610    argv[1] = TocMakeFolderName(toc);
611    argv[2] = "-noverbose";
612    if (app_resources.block_events_on_busy) ShowBusyCursor();
613
614    DoCommand(argv, (char *) NULL, (char *) NULL);
615    XtFree(argv[1]);
616    XtFree((char *) argv);
617    TocForceRescan(toc);
618
619    if (app_resources.block_events_on_busy) UnshowBusyCursor();
620}
621
622
623/*ARGSUSED*/
624void XmhSortFolder(w, event, params, num_params)
625    Widget      w;
626    XEvent      *event;
627    String      *params;
628    Cardinal    *num_params;
629{
630    Scrn scrn = ScrnFromWidget(w);
631    if (UserWantsAction(w, scrn))
632        DoSort(w, (XtPointer) scrn, (XtPointer) NULL);
633}
634
635
636/*ARGSUSED*/
637void XmhForceRescan(w, event, params, num_params)
638    Widget      w;
639    XEvent      *event;
640    String      *params;
641    Cardinal    *num_params;
642{
643    Scrn scrn = ScrnFromWidget(w);
644    if (UserWantsAction(w, scrn))
645        DoForceRescan(w, (XtPointer) scrn, (XtPointer) NULL);
646}
647
648/*ARGSUSED*/
649void DoForceRescan(w, client_data, call_data)
650    Widget      w;
651    XtPointer   client_data;
652    XtPointer   call_data;
653{
654    Scrn        scrn = (Scrn) client_data;
655    Toc         toc = scrn->toc;
656    if (toc == NULL) return;
657    if (app_resources.block_events_on_busy) ShowBusyCursor();
658
659    TocForceRescan(toc);
660   
661    if (app_resources.block_events_on_busy) UnshowBusyCursor();
662}
663
664/*ARGSUSED*/
665void XmhCheckForNewMail(w, e, p, n)
666    Widget w;
667    XEvent *e;
668    String *p;
669    Cardinal *n;
670{
671    TocCheckForNewMail(True);
672}
673
674/* Incorporate new mail. */
675
676/*ARGSUSED*/
677void XmhIncorporateNewMail(w, event, params, num_params)
678    Widget      w;
679    XEvent      *event;
680    String      *params;
681    Cardinal    *num_params;
682{
683    Scrn scrn = ScrnFromWidget(w);
684    if (UserWantsAction(w, scrn)) {
685        if (TocCanIncorporate(scrn->toc))
686            DoIncorporateNewMail(w, (XtPointer) scrn, (XtPointer) NULL);
687    }
688}
689
690
691void DoIncorporateNewMail(w, client_data, call_data)
692    Widget      w;              /* unused */
693    XtPointer   client_data;    /* screen */
694    XtPointer   call_data;      /* unused */
695{
696    Scrn scrn = (Scrn) client_data;
697    Toc toc = scrn->toc;
698    int i;
699    int newmail;
700
701    if (! toc) return;
702    newmail = TocIncorporate(toc);
703
704    if (app_resources.show_on_inc && newmail)
705        DoNextView(w, client_data, call_data);
706
707    if (app_resources.new_mail_check)
708        /* update the folder button */
709        for (i=0; i < numScrns; i++) {
710            scrn = scrnList[i];
711            if (scrn->kind == STtocAndView)
712                /* give visual indication of no mail waiting */
713                BBoxMailFlag(scrn->folderbuttons, TocName(toc), False);
714        }
715
716    if (app_resources.mail_waiting_flag)
717        /* update the icon */
718        TocCheckForNewMail(False);
719}
720
721
722/*ARGSUSED*/
723void DoReply(w, client_data, call_data)
724    Widget      w;
725    XtPointer   client_data;
726    XtPointer   call_data;
727{
728    Scrn        scrn = (Scrn) client_data;
729    Toc         toc = scrn->toc;
730    Scrn        nscrn;
731    MsgList     mlist;
732    Msg         msg;
733
734    if (toc == NULL) return;
735    mlist = CurMsgListOrCurMsg(toc);
736    if (mlist->nummsgs) {
737        nscrn = NewCompScrn();
738        ScreenSetAssocMsg(nscrn, mlist->msglist[0]);
739        msg = TocMakeNewMsg(DraftsFolder);
740        MsgSetTemporary(msg);
741        MsgLoadReply(msg, mlist->msglist[0]);
742        MsgSetScrnForComp(msg, nscrn);
743        MapScrn(nscrn);
744    }
745    FreeMsgList(mlist);
746}
747   
748
749/*ARGSUSED*/
750void XmhReply(w, event, params, num_params)
751    Widget      w;
752    XEvent      *event;
753    String      *params;
754    Cardinal    *num_params;
755{
756    Scrn scrn = ScrnFromWidget(w);
757    if (UserWantsAction(w, scrn))
758        DoReply(w, (XtPointer) scrn, (XtPointer) NULL);
759}
760
761
762/*ARGSUSED*/
763void DoPickMessages(w, client_data, call_data)
764    Widget      w;
765    XtPointer   client_data;
766    XtPointer   call_data;
767{
768    Scrn        scrn = (Scrn) client_data;
769    Toc         toc = scrn->toc;
770    Scrn        nscrn;
771    char *      toseq;
772    Sequence    selectedseq;
773    Boolean     recycled;
774
775    if (toc == NULL) return;
776    if ((selectedseq = TocSelectedSequence(toc)) == NULL)
777        toseq = "temp";
778    else {
779        toseq = selectedseq->name;
780        if (strcmp(toseq, "all") == 0)
781            toseq = "temp";
782    }
783    nscrn = CreateNewScrn(STpick);
784    recycled = (nscrn->pick) ? True : False;
785    AddPick(nscrn, toc, (TocViewedSequence(toc))->name, toseq);
786    DEBUG("Realizing Pick...")
787    XtRealizeWidget(nscrn->parent);
788    DEBUG(" done.\n")
789    if (! recycled) {
790        InitBusyCursor(nscrn);
791        XDefineCursor(XtDisplay(nscrn->parent), XtWindow(nscrn->parent),
792                      app_resources.cursor);
793        (void) XSetWMProtocols(XtDisplay(toplevel), XtWindow(nscrn->parent),
794                               protocolList, XtNumber(protocolList));
795    }
796    MapScrn(nscrn);
797}
798
799
800/*ARGSUSED*/
801void XmhPickMessages(w, event, params, num_params)
802    Widget      w;
803    XEvent      *event;
804    String      *params;
805    Cardinal    *num_params;
806{
807    Scrn scrn = ScrnFromWidget(w);
808    if (UserWantsAction(w, scrn))
809        DoPickMessages(w, (XtPointer) scrn, (XtPointer) NULL);
810}
811
812
813/*ARGSUSED*/
814void DoSelectSequence(widget, client_data, call_data)
815    Widget      widget;         /* sequence menu entry object */
816    XtPointer   client_data;    /* the screen */
817    XtPointer   call_data;
818{
819    Scrn        scrn = (Scrn) client_data;
820    Toc         toc  = (Toc) scrn->toc;
821    Sequence    seq;
822
823    if ((seq = TocSelectedSequence(toc)) != NULL) {
824        Widget  item, menu;
825        Button  button;
826
827        button = BBoxFindButtonNamed
828            (scrn->mainbuttons, MenuBoxButtons[XMH_SEQUENCE].button_name);
829        menu = BBoxMenuOfButton(button);
830        if ((item = XtNameToWidget(menu, seq->name)) != NULL)
831            ToggleMenuItem(item, False);
832    }
833
834    ToggleMenuItem(widget, True);
835    TocSetSelectedSequence(toc, TocGetSeqNamed(toc, XtName(widget)));
836}
837
838
839/*ARGSUSED*/
840void DoOpenSeq(w, client_data, call_data)
841    Widget      w;
842    XtPointer   client_data;
843    XtPointer   call_data;
844{
845    Scrn        scrn = (Scrn) client_data;
846    Toc         toc = scrn->toc;
847    if (toc == NULL) return;
848    TocChangeViewedSeq(toc, TocSelectedSequence(toc));
849}
850
851
852/*ARGSUSED*/
853void XmhOpenSequence(w, event, params, num_params)
854    Widget      w;
855    XEvent      *event;
856    String      *params;
857    Cardinal    *num_params;
858{
859    Widget      entry_object;
860    Scrn        scrn = ScrnFromWidget(w);
861    Sequence    selected_sequence;
862
863    /* In case this action is called from translations defined by the
864     * user on folder menu buttons or on folder menu widgets.
865     */
866    if (! UserWantsAction(w, scrn))
867        return;
868
869    /* In case there is nothing to do anyway. */
870    if (! TocHasSequences(scrn->toc))
871        return;
872
873    /* In case the action was given the name of a sequence to open. */
874    if (*num_params) {
875        Toc     toc = scrn->toc;
876        if (selected_sequence = TocGetSeqNamed(toc, params[0])) {
877            TocSetSelectedSequence(toc, selected_sequence);
878            TocChangeViewedSeq(toc, selected_sequence);
879        }
880        return;
881    }
882
883    /* In case this action is a translation on the sequence menu.  */
884
885    if ((strcmp(XtName(w), "sequenceMenu") == 0) &&
886        (event->type == ButtonRelease)) {
887
888        /* The user released the mouse button.  We must distinguish between
889         * a button release on a selectable menu entry, and a button release
890         * occuring elsewhere.  The button releases occuring elsewhere are
891         * either outside of the menu, or on unselectable menu entries.
892         */
893
894        if ((entry_object = XawSimpleMenuGetActiveEntry(w)) == NULL)
895            return;
896
897        /* Some entry in the menu was selected.  The menu entry's callback
898         * procedure has already executed.  If a sequence name was selected,
899         * the callback procedure has caused that sequence to become the
900         * currently selected sequence.  If selected menu entry object's
901         * name matches the currently selected sequence, we should open
902         * that sequence.  Otherwise, the user must have selected a sequence
903         * manipulation command, such as Pick.  The assumptions here are that
904         * the name of a menu entry object which represents a sequence is
905         * identical to the name of the sequence, and in the translations,
906         * that the notify() action was specified before this action.
907         */
908
909        if ((selected_sequence = TocSelectedSequence(scrn->toc)) &&
910            (strcmp(XtName(entry_object), selected_sequence->name) == 0))
911            DoOpenSeq(w, (XtPointer) scrn, (XtPointer) NULL);
912        return;
913    }
914   
915    /* An accelerator open sequence function */
916
917    DoOpenSeq(w, (XtPointer) scrn, (XtPointer) NULL);
918}
919
920
921typedef enum {ADD, REMOVE, DELETE} TwiddleOperation;
922
923static TwiddleSequence(scrn, op)
924Scrn scrn;
925TwiddleOperation op;
926{
927    Toc toc = scrn->toc;
928    char **argv, str[100];
929    int i;
930    MsgList mlist;
931    Sequence    selectedseq;
932
933    if (toc == NULL || ((selectedseq = TocSelectedSequence(toc)) == NULL))
934        return;
935    if (strcmp(selectedseq->name, "all") == 0) {
936        Feep();
937        return;
938    }
939    if (op == DELETE)
940        mlist = MakeNullMsgList();
941    else {
942        mlist = CurMsgListOrCurMsg(toc);
943        if (mlist->nummsgs == 0) {
944            FreeMsgList(mlist);
945            Feep();
946            return;
947        }
948    }
949    argv = MakeArgv(6 + mlist->nummsgs);
950    argv[0] = "mark";
951    argv[1] = TocMakeFolderName(toc);
952    argv[2] = "-sequence";
953    argv[3] = selectedseq->name;
954    switch (op) {
955      case ADD:
956        argv[4] = "-add";
957        argv[5] = "-nozero";
958        break;
959      case REMOVE:
960        argv[4] = "-delete";
961        argv[5] = "-nozero";
962        break;
963      case DELETE:
964        argv[4] = "-delete";
965        argv[5] = "all";
966        break;
967    }
968    for (i = 0; i < mlist->nummsgs; i++) {
969        (void) sprintf(str, "%d", MsgGetId(mlist->msglist[i]));
970        argv[6 + i] = XtNewString(str);
971    }
972    DoCommand(argv, (char *) NULL, (char *) NULL);
973    for (i = 0; i < mlist->nummsgs; i++)
974        XtFree((char *) argv[6 + i]);
975    XtFree(argv[1]);
976    XtFree((char *) argv);
977    FreeMsgList(mlist);
978    TocReloadSeqLists(toc);
979}
980
981
982/*ARGSUSED*/
983void DoAddToSeq(w, client_data, call_data)
984    Widget      w;
985    XtPointer   client_data;
986    XtPointer   call_data;
987{
988    Scrn        scrn = (Scrn) client_data;
989    TwiddleSequence(scrn, ADD);
990}
991
992
993/*ARGSUSED*/
994void XmhAddToSequence(w, event, params, num_params)
995    Widget      w;
996    XEvent      *event;
997    String      *params;
998    Cardinal    *num_params;
999{
1000    Scrn scrn = ScrnFromWidget(w);
1001    if (! UserWantsAction(w, scrn))
1002        return;
1003    if ((strcmp(XtName(w), "sequenceMenu") == 0) &&
1004        (event->type == ButtonRelease) &&
1005        (XawSimpleMenuGetActiveEntry(w) == NULL))
1006        return;
1007    if (TocHasSequences(scrn->toc))
1008        TwiddleSequence(scrn, ADD);
1009}
1010
1011
1012/*ARGSUSED*/
1013void DoRemoveFromSeq(w, client_data, call_data)
1014    Widget      w;
1015    XtPointer   client_data;
1016    XtPointer   call_data;
1017{
1018    Scrn        scrn = (Scrn) client_data;
1019    TwiddleSequence(scrn, REMOVE);
1020}
1021
1022
1023/*ARGSUSED*/
1024void XmhRemoveFromSequence(w, event, params, num_params)
1025    Widget      w;
1026    XEvent      *event;
1027    String      *params;
1028    Cardinal    *num_params;
1029{
1030    Scrn scrn = ScrnFromWidget(w);
1031    if (UserWantsAction(w, scrn))
1032        if (TocHasSequences(scrn->toc))
1033            TwiddleSequence(scrn, REMOVE);
1034}
1035
1036
1037/*ARGSUSED*/
1038void DoDeleteSeq(w, client_data, call_data)
1039    Widget      w;
1040    XtPointer   client_data;
1041    XtPointer   call_data;
1042{
1043    Scrn        scrn = (Scrn) client_data;
1044    TwiddleSequence(scrn, DELETE);
1045    TUCheckSequenceMenu(scrn->toc);
1046}
1047
1048
1049/*ARGSUSED*/
1050void XmhDeleteSequence(w, event, params, num_params)
1051    Widget      w;
1052    XEvent      *event;
1053    String      *params;
1054    Cardinal    *num_params;
1055{
1056    Scrn scrn = ScrnFromWidget(w);
1057    if (! UserWantsAction(w, scrn))
1058        return;
1059    if ((strcmp(XtName(w), "sequenceMenu") == 0) &&
1060        (event->type == ButtonRelease) &&
1061        (XawSimpleMenuGetActiveEntry(w) == NULL))
1062        return;
1063    if (TocHasSequences(scrn->toc))
1064        DoDeleteSeq(w, (XtPointer) scrn, (XtPointer) NULL);
1065}
1066
Note: See TracBrowser for help on using the repository browser.