1c9e2be55Smrg/* 2c9e2be55Smrg * $XConsortium: tocutil.c,v 2.60 95/01/09 16:52:53 swick Exp $ 3c9e2be55Smrg * $XFree86: xc/programs/xmh/tocutil.c,v 3.3 2001/10/28 03:34:40 tsi Exp $ 4c9e2be55Smrg * 5c9e2be55Smrg * 6c9e2be55Smrg * COPYRIGHT 1987, 1989 7c9e2be55Smrg * DIGITAL EQUIPMENT CORPORATION 8c9e2be55Smrg * MAYNARD, MASSACHUSETTS 9c9e2be55Smrg * ALL RIGHTS RESERVED. 10c9e2be55Smrg * 11c9e2be55Smrg * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND 12c9e2be55Smrg * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. 13c9e2be55Smrg * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR 14c9e2be55Smrg * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 15c9e2be55Smrg * 16c9e2be55Smrg * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT 17c9e2be55Smrg * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN 18c9e2be55Smrg * ADDITION TO THAT SET FORTH ABOVE. 19c9e2be55Smrg * 20c9e2be55Smrg * Permission to use, copy, modify, and distribute this software and its 21c9e2be55Smrg * documentation for any purpose and without fee is hereby granted, provided 22c9e2be55Smrg * that the above copyright notice appear in all copies and that both that 23c9e2be55Smrg * copyright notice and this permission notice appear in supporting 24c9e2be55Smrg * documentation, and that the name of Digital Equipment Corporation not be 25c9e2be55Smrg * used in advertising or publicity pertaining to distribution of the software 26c9e2be55Smrg * without specific, written prior permission. 27c9e2be55Smrg */ 28c9e2be55Smrg 29c9e2be55Smrg/* tocutil.c -- internal routines for toc stuff. */ 30c9e2be55Smrg 31c9e2be55Smrg#include "xmh.h" 32c9e2be55Smrg#include "toc.h" 33c9e2be55Smrg#include "tocutil.h" 34c9e2be55Smrg#include "tocintrnl.h" 35c9e2be55Smrg 36c9e2be55Smrg#ifdef X_NOT_POSIX 37c9e2be55Smrgextern long lseek(); 38c9e2be55Smrg#endif 39c9e2be55Smrg 40c9e2be55SmrgToc TUMalloc(void) 41c9e2be55Smrg{ 42c9e2be55Smrg Toc toc; 43c9e2be55Smrg toc = XtNew(TocRec); 44c9e2be55Smrg bzero((char *)toc, (int) sizeof(TocRec)); 45c9e2be55Smrg toc->msgs = (Msg *) NULL; 46c9e2be55Smrg toc->seqlist = (Sequence *) NULL; 47c9e2be55Smrg toc->validity = unknown; 48c9e2be55Smrg return toc; 49c9e2be55Smrg} 50c9e2be55Smrg 51c9e2be55Smrg 52c9e2be55Smrg/* Returns TRUE if the scan file for the given toc is out of date. */ 53c9e2be55Smrg 54c9e2be55Smrgint TUScanFileOutOfDate(Toc toc) 55c9e2be55Smrg{ 56c9e2be55Smrg return LastModifyDate(toc->path) > toc->lastreaddate; 57c9e2be55Smrg} 58c9e2be55Smrg 59c9e2be55Smrg 60d859ff80Smrg/* Make sure the sequence menu entries correspond exactly to the sequences 61c9e2be55Smrg * for this toc. 62c9e2be55Smrg */ 63c9e2be55Smrg 64c9e2be55Smrgvoid TUCheckSequenceMenu(Toc toc) 65c9e2be55Smrg{ 66c9e2be55Smrg Scrn scrn; 67c9e2be55Smrg register int i, n; 68c9e2be55Smrg Arg query_args[2]; 6966d665a3Smrg const char *name; 70c9e2be55Smrg Cardinal j; 71c9e2be55Smrg int numChildren; 72c9e2be55Smrg Widget menu, item; 73c9e2be55Smrg Button button; 74c9e2be55Smrg WidgetList children; 75c9e2be55Smrg 76c9e2be55Smrg static XtCallbackRec callbacks[] = { 77c9e2be55Smrg { DoSelectSequence, (XtPointer) NULL}, 78c9e2be55Smrg { (XtCallbackProc) NULL, (XtPointer) NULL}, 79c9e2be55Smrg }; 80c9e2be55Smrg static Arg args[] = { 81c9e2be55Smrg { XtNcallback, (XtArgVal) callbacks}, 82c9e2be55Smrg { XtNleftMargin, (XtArgVal) 18}, 83c9e2be55Smrg }; 84c9e2be55Smrg 85c9e2be55Smrg for (j=0; j < toc->num_scrns; j++) { 86c9e2be55Smrg scrn = toc->scrn[j]; 87c9e2be55Smrg 88c9e2be55Smrg /* Find the sequence menu and the number of entries in it. */ 89c9e2be55Smrg 90c9e2be55Smrg name = MenuBoxButtons[XMH_SEQUENCE].button_name; 91c9e2be55Smrg button = BBoxFindButtonNamed(scrn->mainbuttons, name); 92c9e2be55Smrg menu = BBoxMenuOfButton(button); 93c9e2be55Smrg XtSetArg(query_args[0], XtNnumChildren, &numChildren); 94c9e2be55Smrg XtSetArg(query_args[1], XtNchildren, &children); 95c9e2be55Smrg XtGetValues(menu, query_args, (Cardinal) 2); 96c9e2be55Smrg n = MenuBoxButtons[XMH_SEQUENCE].num_entries; 97c9e2be55Smrg if (strcmp(XtName(children[0]), "menuLabel") == 0) 98c9e2be55Smrg n++; 99c9e2be55Smrg 100c9e2be55Smrg /* Erase the current check mark. */ 101c9e2be55Smrg 102d859ff80Smrg for (i=(n-1); i < numChildren; i++) 103c9e2be55Smrg ToggleMenuItem(children[i], False); 104c9e2be55Smrg 105c9e2be55Smrg /* Delete any entries which should be deleted. */ 106c9e2be55Smrg 107c9e2be55Smrg for (i=n; i < numChildren; i++) 108c9e2be55Smrg if (! TocGetSeqNamed(toc, XtName(children[i]))) 109c9e2be55Smrg XtDestroyWidget(children[i]); 110c9e2be55Smrg 111c9e2be55Smrg /* Create any entries which should be created. */ 112d859ff80Smrg 113c9e2be55Smrg callbacks[0].closure = (XtPointer) scrn; 114d859ff80Smrg for (i=1; i < toc->numsequences; i++) 115c9e2be55Smrg if (! XtNameToWidget(menu, toc->seqlist[i]->name)) 116c9e2be55Smrg XtCreateManagedWidget(toc->seqlist[i]->name, smeBSBObjectClass, 117c9e2be55Smrg menu, args, XtNumber(args)); 118c9e2be55Smrg 119c9e2be55Smrg /* Set the check mark. */ 120c9e2be55Smrg 121c9e2be55Smrg name = toc->viewedseq->name; 122c9e2be55Smrg if ((item = XtNameToWidget(menu, name)) != NULL) 123c9e2be55Smrg ToggleMenuItem(item, True); 124c9e2be55Smrg } 125c9e2be55Smrg TocSetSelectedSequence(toc, toc->viewedseq); 126c9e2be55Smrg} 127c9e2be55Smrg 128c9e2be55Smrg 129c9e2be55Smrgvoid TUScanFileForToc(Toc toc) 130c9e2be55Smrg{ 131c9e2be55Smrg Scrn scrn; 132c9e2be55Smrg char **argv, str[100]; 133c9e2be55Smrg if (toc) { 134c9e2be55Smrg TUGetFullFolderInfo(toc); 135c9e2be55Smrg if (toc->num_scrns) scrn = toc->scrn[0]; 136c9e2be55Smrg else scrn = scrnList[0]; 137c9e2be55Smrg 13866d665a3Smrg snprintf(str, sizeof(str), "Rescanning %s", toc->foldername); 139c9e2be55Smrg ChangeLabel(scrn->toclabel, str); 140c9e2be55Smrg 141c9e2be55Smrg argv = MakeArgv(5); 142c9e2be55Smrg argv[0] = "scan"; 143c9e2be55Smrg argv[1] = TocMakeFolderName(toc); 144c9e2be55Smrg argv[2] = "-width"; 14566d665a3Smrg snprintf(str, sizeof(str), "%d", app_resources.toc_width); 146c9e2be55Smrg argv[3] = str; 147c9e2be55Smrg argv[4] = "-noheader"; 148c9e2be55Smrg DoCommand(argv, (char *) NULL, toc->scanfile); 149c9e2be55Smrg XtFree(argv[1]); 150c9e2be55Smrg XtFree((char *) argv); 151c9e2be55Smrg 152c9e2be55Smrg toc->needslabelupdate = True; 153c9e2be55Smrg toc->validity = valid; 154c9e2be55Smrg toc->curmsg = NULL; /* Get cur msg somehow! %%% */ 155c9e2be55Smrg } 156c9e2be55Smrg} 157c9e2be55Smrg 158c9e2be55Smrg 159c9e2be55Smrg 160c9e2be55Smrgint TUGetMsgPosition(Toc toc, Msg msg) 161c9e2be55Smrg{ 162c9e2be55Smrg int msgid, h = 0, l, m; 163c9e2be55Smrg char str[100]; 164c9e2be55Smrg static Boolean ordered = True; 165c9e2be55Smrg msgid = msg->msgid; 166c9e2be55Smrg if (ordered) { 167c9e2be55Smrg l = 0; 168c9e2be55Smrg h = toc->nummsgs - 1; 169c9e2be55Smrg while (l < h - 1) { 170c9e2be55Smrg m = (l + h) / 2; 171c9e2be55Smrg if (toc->msgs[m]->msgid > msgid) 172c9e2be55Smrg h = m; 173c9e2be55Smrg else 174c9e2be55Smrg l = m; 175c9e2be55Smrg } 176c9e2be55Smrg if (toc->msgs[l] == msg) return l; 177c9e2be55Smrg if (toc->msgs[h] == msg) return h; 178c9e2be55Smrg } 179c9e2be55Smrg ordered = False; 180c9e2be55Smrg for (l = 0; l < toc->nummsgs; l++) { 181c9e2be55Smrg if (msgid == toc->msgs[l]->msgid) return l; 182c9e2be55Smrg } 18366d665a3Smrg snprintf(str, sizeof(str), 18466d665a3Smrg "TUGetMsgPosition search failed! hi=%d, lo=%d, msgid=%d", 18566d665a3Smrg h, l, msgid); 186c9e2be55Smrg Punt(str); 187c9e2be55Smrg return 0; /* Keep lint happy. */ 188c9e2be55Smrg} 189c9e2be55Smrg 190c9e2be55Smrg 191c9e2be55Smrgvoid TUResetTocLabel(Scrn scrn) 192c9e2be55Smrg{ 193c9e2be55Smrg char str[500]; 194c9e2be55Smrg Toc toc; 195c9e2be55Smrg if (scrn) { 196c9e2be55Smrg toc = scrn->toc; 197c9e2be55Smrg if (toc == NULL) 198c9e2be55Smrg (void) strcpy(str, " "); 199c9e2be55Smrg else { 200c9e2be55Smrg if (toc->stopupdate) { 201c9e2be55Smrg toc->needslabelupdate = TRUE; 202c9e2be55Smrg return; 203c9e2be55Smrg } 20466d665a3Smrg snprintf(str, sizeof(str), "%s:%s", toc->foldername, 20566d665a3Smrg toc->viewedseq->name); 206c9e2be55Smrg toc->needslabelupdate = FALSE; 207c9e2be55Smrg } 208c9e2be55Smrg ChangeLabel((Widget) scrn->toclabel, str); 209c9e2be55Smrg } 210c9e2be55Smrg} 211c9e2be55Smrg 212c9e2be55Smrg 213d859ff80Smrg/* A major toc change has occurred; redisplay it. (This also should work even 214c9e2be55Smrg if we now have a new source to display stuff from.) */ 215c9e2be55Smrg 216c9e2be55Smrgvoid TURedisplayToc(Scrn scrn) 217c9e2be55Smrg{ 218c9e2be55Smrg Toc toc; 219c9e2be55Smrg Widget source; 220c9e2be55Smrg if (scrn != NULL && scrn->tocwidget != NULL) { 221c9e2be55Smrg toc = scrn->toc; 222c9e2be55Smrg if (toc) { 223c9e2be55Smrg if (toc->stopupdate) { 224c9e2be55Smrg toc->needsrepaint = TRUE; 225c9e2be55Smrg return; 226c9e2be55Smrg } 227c9e2be55Smrg XawTextDisableRedisplay(scrn->tocwidget); 228c9e2be55Smrg source = XawTextGetSource(scrn->tocwidget); 229c9e2be55Smrg if (toc->force_reset || source != toc->source) { 230c9e2be55Smrg XawTextSetSource(scrn->tocwidget, toc->source, 231c9e2be55Smrg (XawTextPosition) 0); 232c9e2be55Smrg toc->force_reset = False; /* %%% temporary */ 233c9e2be55Smrg } 234c9e2be55Smrg TocSetCurMsg(toc, TocGetCurMsg(toc)); 235c9e2be55Smrg XawTextEnableRedisplay(scrn->tocwidget); 236c9e2be55Smrg TUCheckSequenceMenu(toc); 237c9e2be55Smrg toc->needsrepaint = FALSE; 238c9e2be55Smrg } else { 239c9e2be55Smrg XawTextSetSource(scrn->tocwidget, PNullSource, (XawTextPosition) 0); 240c9e2be55Smrg } 241c9e2be55Smrg } 242c9e2be55Smrg} 243c9e2be55Smrg 244c9e2be55Smrg 245c9e2be55Smrgvoid TULoadSeqLists(Toc toc) 246c9e2be55Smrg{ 247c9e2be55Smrg Sequence seq; 248c9e2be55Smrg FILEPTR fid; 249c9e2be55Smrg char str[500], *ptr, *ptr2, viewed[500], selected[500]; 250c9e2be55Smrg int i; 251c9e2be55Smrg if (toc->viewedseq) (void) strcpy(viewed, toc->viewedseq->name); 252c9e2be55Smrg else *viewed = 0; 253c9e2be55Smrg if (toc->selectseq) (void) strcpy(selected, toc->selectseq->name); 254c9e2be55Smrg else *selected = 0; 255c9e2be55Smrg for (i = 0; i < toc->numsequences; i++) { 256c9e2be55Smrg seq = toc->seqlist[i]; 257c9e2be55Smrg XtFree((char *) seq->name); 258c9e2be55Smrg if (seq->mlist) FreeMsgList(seq->mlist); 259c9e2be55Smrg XtFree((char *)seq); 260c9e2be55Smrg } 261c9e2be55Smrg toc->numsequences = 1; 262c9e2be55Smrg toc->seqlist = (Sequence *) XtRealloc((char *) toc->seqlist, 263c9e2be55Smrg (Cardinal) sizeof(Sequence)); 264c9e2be55Smrg seq = toc->seqlist[0] = XtNew(SequenceRec); 265c9e2be55Smrg seq->name = XtNewString("all"); 266c9e2be55Smrg seq->mlist = NULL; 267c9e2be55Smrg toc->viewedseq = seq; 268c9e2be55Smrg toc->selectseq = seq; 26966d665a3Smrg snprintf(str, sizeof(str), "%s/.mh_sequences", toc->path); 270c9e2be55Smrg fid = myfopen(str, "r"); 271c9e2be55Smrg if (fid) { 272c9e2be55Smrg while ((ptr = ReadLine(fid))) { 273c9e2be55Smrg ptr2 = strchr(ptr, ':'); 274c9e2be55Smrg if (ptr2) { 275c9e2be55Smrg *ptr2 = 0; 276c9e2be55Smrg if (strcmp(ptr, "all") != 0 && 277c9e2be55Smrg strcmp(ptr, "cur") != 0 && 278c9e2be55Smrg strcmp(ptr, "unseen") != 0) { 279c9e2be55Smrg toc->numsequences++; 28066d665a3Smrg toc->seqlist = XtReallocArray(toc->seqlist, 28166d665a3Smrg toc->numsequences, sizeof(Sequence)); 282c9e2be55Smrg seq = toc->seqlist[toc->numsequences - 1] = 283c9e2be55Smrg XtNew(SequenceRec); 284c9e2be55Smrg seq->name = XtNewString(ptr); 285c9e2be55Smrg seq->mlist = StringToMsgList(toc, ptr2 + 1); 286c9e2be55Smrg if (strcmp(seq->name, viewed) == 0) { 287c9e2be55Smrg toc->viewedseq = seq; 288c9e2be55Smrg *viewed = 0; 289c9e2be55Smrg } 290c9e2be55Smrg if (strcmp(seq->name, selected) == 0) { 291c9e2be55Smrg toc->selectseq = seq; 292c9e2be55Smrg *selected = 0; 293c9e2be55Smrg } 294c9e2be55Smrg } 295c9e2be55Smrg } 296c9e2be55Smrg } 297c9e2be55Smrg (void) myfclose(fid); 298c9e2be55Smrg } 299c9e2be55Smrg} 300c9e2be55Smrg 301c9e2be55Smrg 302c9e2be55Smrg 303c9e2be55Smrg/* Refigure what messages are visible. */ 304c9e2be55Smrg 305c9e2be55Smrgvoid TURefigureWhatsVisible(Toc toc) 306c9e2be55Smrg{ 307c9e2be55Smrg MsgList mlist; 308c9e2be55Smrg Msg msg, oldcurmsg; 309c9e2be55Smrg int i; 310c9e2be55Smrg int w, changed, newval, msgid; 311c9e2be55Smrg Sequence seq = toc->viewedseq; 312c9e2be55Smrg mlist = seq->mlist; 313c9e2be55Smrg oldcurmsg = toc->curmsg; 314c9e2be55Smrg TocSetCurMsg(toc, (Msg)NULL); 315c9e2be55Smrg w = 0; 316c9e2be55Smrg changed = FALSE; 317c9e2be55Smrg 318c9e2be55Smrg for (i = 0; i < toc->nummsgs; i++) { 319c9e2be55Smrg msg = toc->msgs[i]; 320c9e2be55Smrg msgid = msg->msgid; 321c9e2be55Smrg while (mlist && mlist->msglist[w] && mlist->msglist[w]->msgid < msgid) 322c9e2be55Smrg w++; 323c9e2be55Smrg newval = (!mlist 324c9e2be55Smrg || (mlist->msglist[w] && mlist->msglist[w]->msgid == msgid)); 325c9e2be55Smrg if (newval != msg->visible) { 326c9e2be55Smrg changed = TRUE; 327c9e2be55Smrg msg->visible = newval; 328c9e2be55Smrg } 329c9e2be55Smrg } 330c9e2be55Smrg if (changed) { 331c9e2be55Smrg TURefigureTocPositions(toc); 332c9e2be55Smrg if (oldcurmsg) { 333c9e2be55Smrg if (!oldcurmsg->visible) { 334c9e2be55Smrg toc->curmsg = TocMsgAfter(toc, oldcurmsg); 335c9e2be55Smrg if (toc->curmsg == NULL) 336c9e2be55Smrg toc->curmsg = TocMsgBefore(toc, oldcurmsg); 337c9e2be55Smrg } else toc->curmsg = oldcurmsg; 338c9e2be55Smrg } 339c9e2be55Smrg for (i=0 ; i<toc->num_scrns ; i++) 340c9e2be55Smrg TURedisplayToc(toc->scrn[i]); 341c9e2be55Smrg } else TocSetCurMsg(toc, oldcurmsg); 342c9e2be55Smrg for (i=0 ; i<toc->num_scrns ; i++) 343c9e2be55Smrg TUResetTocLabel(toc->scrn[i]); 344c9e2be55Smrg} 345c9e2be55Smrg 346c9e2be55Smrg 347c9e2be55Smrg/* (Re)load the toc from the scanfile. If reloading, this makes efforts to 348c9e2be55Smrg keep the fates of msgs, and to keep msgs that are being edited. Note that 349c9e2be55Smrg this routine must know of all places that msg ptrs are stored; it expects 350c9e2be55Smrg them to be kept only in tocs, in scrns, and in msg sequences. */ 351c9e2be55Smrg 352c9e2be55Smrg#define SeemsIdentical(msg1, msg2) ((msg1)->msgid == (msg2)->msgid && \ 353c9e2be55Smrg ((msg1)->temporary || (msg2)->temporary ||\ 354c9e2be55Smrg strcmp((msg1)->buf, (msg2)->buf) == 0)) 355c9e2be55Smrg 356c9e2be55Smrgvoid TULoadTocFile(Toc toc) 357c9e2be55Smrg{ 358c9e2be55Smrg int maxmsgs, l, orignummsgs, i, j, origcurmsgid; 359c9e2be55Smrg FILEPTR fid; 360c9e2be55Smrg XawTextPosition position; 361c9e2be55Smrg char *ptr; 362c9e2be55Smrg Msg msg, curmsg; 363c9e2be55Smrg Msg *origmsgs; 364c9e2be55Smrg int bufsiz = app_resources.toc_width + 1; 365c9e2be55Smrg static char *buf; 366c9e2be55Smrg 367c9e2be55Smrg if (!buf) 368c9e2be55Smrg buf = XtMalloc((Cardinal) bufsiz); 369c9e2be55Smrg TocStopUpdate(toc); 370c9e2be55Smrg toc->lastreaddate = LastModifyDate(toc->scanfile); 371c9e2be55Smrg if (toc->curmsg) { 372c9e2be55Smrg origcurmsgid = toc->curmsg->msgid; 373c9e2be55Smrg TocSetCurMsg(toc, (Msg)NULL); 374c9e2be55Smrg } else origcurmsgid = 0; /* The "default" current msg; 0 means none */ 375c9e2be55Smrg fid = FOpenAndCheck(toc->scanfile, "r"); 376c9e2be55Smrg maxmsgs = orignummsgs = toc->nummsgs; 377c9e2be55Smrg if (maxmsgs == 0) maxmsgs = 100; 378c9e2be55Smrg toc->nummsgs = 0; 379c9e2be55Smrg origmsgs = toc->msgs; 38066d665a3Smrg toc->msgs = XtMallocArray((Cardinal) maxmsgs, sizeof(Msg)); 381c9e2be55Smrg position = 0; 382c9e2be55Smrg i = 0; 383c9e2be55Smrg curmsg = NULL; 384c9e2be55Smrg while ((ptr = fgets(buf, bufsiz, fid))) { 385c9e2be55Smrg toc->msgs[toc->nummsgs++] = msg = XtNew(MsgRec); 386c9e2be55Smrg bzero((char *) msg, sizeof(MsgRec)); 387c9e2be55Smrg msg->toc = toc; 388c9e2be55Smrg msg->position = position; 389c9e2be55Smrg msg->length = l = strlen(ptr); 390c9e2be55Smrg position += l; 391c9e2be55Smrg if (l == app_resources.toc_width && buf[bufsiz-2] != '\n') { 392c9e2be55Smrg buf[bufsiz-2] = '\n'; 393c9e2be55Smrg msg->buf = strcpy(XtMalloc((Cardinal) ++l), ptr); 394c9e2be55Smrg msg->msgid = atoi(ptr); 395d859ff80Smrg do 396c9e2be55Smrg ptr = fgets(buf, bufsiz, fid); 397c9e2be55Smrg while (ptr && (int) strlen(ptr) == app_resources.toc_width 398c9e2be55Smrg && buf[bufsiz-2] != '\n'); 399c9e2be55Smrg } else { 400c9e2be55Smrg msg->buf = strcpy(XtMalloc((Cardinal) ++l), ptr); 401c9e2be55Smrg msg->msgid = atoi(ptr); 402c9e2be55Smrg } 403c9e2be55Smrg if (msg->msgid == origcurmsgid) 404c9e2be55Smrg curmsg = msg; 405c9e2be55Smrg msg->buf[MARKPOS] = ' '; 406c9e2be55Smrg msg->changed = FALSE; 407c9e2be55Smrg msg->fate = Fignore; 408c9e2be55Smrg msg->desttoc = NULL; 409c9e2be55Smrg msg->visible = TRUE; 410c9e2be55Smrg if (toc->nummsgs >= maxmsgs) { 411c9e2be55Smrg maxmsgs += 100; 41266d665a3Smrg toc->msgs = XtReallocArray(toc->msgs, maxmsgs, sizeof(Msg)); 413c9e2be55Smrg } 414c9e2be55Smrg while (i < orignummsgs && origmsgs[i]->msgid < msg->msgid) i++; 415c9e2be55Smrg if (i < orignummsgs) { 416c9e2be55Smrg origmsgs[i]->buf[MARKPOS] = ' '; 417c9e2be55Smrg if (SeemsIdentical(origmsgs[i], msg)) 418c9e2be55Smrg MsgSetFate(msg, origmsgs[i]->fate, origmsgs[i]->desttoc); 419c9e2be55Smrg } 420c9e2be55Smrg } 421c9e2be55Smrg toc->length = toc->origlength = toc->lastPos = position; 42266d665a3Smrg toc->msgs = XtReallocArray(toc->msgs, toc->nummsgs, sizeof(Msg)); 423c9e2be55Smrg (void) myfclose(fid); 424c9e2be55Smrg if ( (toc->source == NULL) && ( toc->num_scrns > 0 ) ) { 425c9e2be55Smrg Arg args[1]; 426c9e2be55Smrg 427c9e2be55Smrg XtSetArg(args[0], XtNtoc, toc); 428c9e2be55Smrg toc->source = XtCreateWidget("tocSource", tocSourceWidgetClass, 429c9e2be55Smrg toc->scrn[0]->tocwidget, 430c9e2be55Smrg args, (Cardinal) 1); 431c9e2be55Smrg } 432c9e2be55Smrg for (i=0 ; i<numScrns ; i++) { 433c9e2be55Smrg msg = scrnList[i]->msg; 434c9e2be55Smrg if (msg && msg->toc == toc) { 435c9e2be55Smrg for (j=0 ; j<toc->nummsgs ; j++) { 436c9e2be55Smrg if (SeemsIdentical(toc->msgs[j], msg)) { 437c9e2be55Smrg msg->position = toc->msgs[j]->position; 438c9e2be55Smrg msg->visible = TRUE; 439c9e2be55Smrg ptr = toc->msgs[j]->buf; 440c9e2be55Smrg l = toc->msgs[j]->length; 441c9e2be55Smrg *(toc->msgs[j]) = *msg; 442c9e2be55Smrg toc->msgs[j]->buf = ptr; 443c9e2be55Smrg toc->msgs[j]->length = l; 444c9e2be55Smrg scrnList[i]->msg = toc->msgs[j]; 445c9e2be55Smrg break; 446c9e2be55Smrg } 447c9e2be55Smrg } 448c9e2be55Smrg if (j >= toc->nummsgs) { 449c9e2be55Smrg msg->temporary = FALSE; /* Don't try to auto-delete msg. */ 450c9e2be55Smrg MsgSetScrnForce(msg, (Scrn) NULL); 451c9e2be55Smrg } 452c9e2be55Smrg } 453c9e2be55Smrg } 454c9e2be55Smrg for (i=0 ; i<orignummsgs ; i++) 455c9e2be55Smrg MsgFree(origmsgs[i]); 456c9e2be55Smrg XtFree((char *)origmsgs); 457c9e2be55Smrg TocSetCurMsg(toc, curmsg); 458c9e2be55Smrg TULoadSeqLists(toc); 459c9e2be55Smrg TocStartUpdate(toc); 460c9e2be55Smrg} 461c9e2be55Smrg 462c9e2be55Smrg 463c9e2be55Smrgvoid TUSaveTocFile(Toc toc) 464c9e2be55Smrg{ 465c9e2be55Smrg Msg msg; 466c9e2be55Smrg int fid; 467c9e2be55Smrg int i; 46866d665a3Smrg off_t position; 469c9e2be55Smrg char c; 470c9e2be55Smrg if (toc->stopupdate) { 471c9e2be55Smrg toc->needscachesave = TRUE; 472c9e2be55Smrg return; 473c9e2be55Smrg } 474c9e2be55Smrg fid = -1; 475c9e2be55Smrg position = 0; 476c9e2be55Smrg for (i = 0; i < toc->nummsgs; i++) { 477c9e2be55Smrg msg = toc->msgs[i]; 478c9e2be55Smrg if (fid < 0 && msg->changed) { 479c9e2be55Smrg fid = myopen(toc->scanfile, O_RDWR, 0666); 48066d665a3Smrg (void) lseek(fid, position, SEEK_SET); 481c9e2be55Smrg } 482c9e2be55Smrg if (fid >= 0) { 483c9e2be55Smrg c = msg->buf[MARKPOS]; 484c9e2be55Smrg msg->buf[MARKPOS] = ' '; 485c9e2be55Smrg (void) write(fid, msg->buf, msg->length); 486c9e2be55Smrg msg->buf[MARKPOS] = c; 487c9e2be55Smrg } 488c9e2be55Smrg position += msg->length; 489c9e2be55Smrg } 490c9e2be55Smrg if (fid < 0 && toc->length != toc->origlength) 491c9e2be55Smrg fid = myopen(toc->scanfile, O_RDWR, 0666); 492c9e2be55Smrg if (fid >= 0) { 493c9e2be55Smrg (void) ftruncate(fid, toc->length); 494c9e2be55Smrg myclose(fid); 495c9e2be55Smrg toc->origlength = toc->length; 496c9e2be55Smrg } 497c9e2be55Smrg toc->needscachesave = FALSE; 498c9e2be55Smrg toc->lastreaddate = LastModifyDate(toc->scanfile); 499c9e2be55Smrg} 500c9e2be55Smrg 501c9e2be55Smrg 502c9e2be55Smrgstatic Boolean UpdateScanFile( 503c9e2be55Smrg XtPointer client_data) /* Toc */ 504c9e2be55Smrg{ 505c9e2be55Smrg Toc toc = (Toc)client_data; 506c9e2be55Smrg int i; 507c9e2be55Smrg 508c9e2be55Smrg if (app_resources.block_events_on_busy) ShowBusyCursor(); 509c9e2be55Smrg 510c9e2be55Smrg TUScanFileForToc(toc); 511c9e2be55Smrg TULoadTocFile(toc); 512c9e2be55Smrg 513c9e2be55Smrg for (i=0 ; i<toc->num_scrns ; i++) 514c9e2be55Smrg TURedisplayToc(toc->scrn[i]); 515c9e2be55Smrg 516c9e2be55Smrg if (app_resources.block_events_on_busy) UnshowBusyCursor(); 517c9e2be55Smrg 518c9e2be55Smrg return True; 519c9e2be55Smrg} 520c9e2be55Smrg 521c9e2be55Smrg 522c9e2be55Smrgvoid TUEnsureScanIsValidAndOpen(Toc toc, Boolean delay) 523c9e2be55Smrg{ 524c9e2be55Smrg if (toc) { 525c9e2be55Smrg TUGetFullFolderInfo(toc); 526c9e2be55Smrg if (TUScanFileOutOfDate(toc)) { 527c9e2be55Smrg if (!delay) 528c9e2be55Smrg UpdateScanFile((XtPointer)toc); 529c9e2be55Smrg else { 530c9e2be55Smrg /* this is a hack to get the screen mapped before 531c9e2be55Smrg * spawning the subprocess (and blocking). 532c9e2be55Smrg * Need to make sure the scanfile exists at this point. 533c9e2be55Smrg */ 534c9e2be55Smrg int fid = myopen(toc->scanfile, O_RDWR|O_CREAT, 0666); 535c9e2be55Smrg myclose(fid); 536c9e2be55Smrg XtAppAddWorkProc(XtWidgetToApplicationContext(toplevel), 537c9e2be55Smrg UpdateScanFile, 538c9e2be55Smrg (XtPointer)toc); 539c9e2be55Smrg } 540c9e2be55Smrg } 541c9e2be55Smrg if (toc->source == NULL) 542c9e2be55Smrg TULoadTocFile(toc); 543c9e2be55Smrg } 544c9e2be55Smrg} 545c9e2be55Smrg 546c9e2be55Smrg 547c9e2be55Smrg 548c9e2be55Smrg/* Refigure all the positions, based on which lines are visible. */ 549c9e2be55Smrg 550c9e2be55Smrgvoid TURefigureTocPositions(Toc toc) 551c9e2be55Smrg{ 552c9e2be55Smrg int i; 553c9e2be55Smrg Msg msg; 554c9e2be55Smrg XawTextPosition position, length; 555c9e2be55Smrg position = length = 0; 556c9e2be55Smrg for (i=0; i<toc->nummsgs ; i++) { 557c9e2be55Smrg msg = toc->msgs[i]; 558c9e2be55Smrg msg->position = position; 559c9e2be55Smrg if (msg->visible) position += msg->length; 560c9e2be55Smrg length += msg->length; 561c9e2be55Smrg } 562c9e2be55Smrg toc->lastPos = position; 563c9e2be55Smrg toc->length = length; 564c9e2be55Smrg} 565c9e2be55Smrg 566c9e2be55Smrg 567c9e2be55Smrg 568c9e2be55Smrg/* Make sure we've loaded ALL the folder info for this toc, including its 569c9e2be55Smrg path and sequence lists. */ 570c9e2be55Smrg 571c9e2be55Smrgvoid TUGetFullFolderInfo(Toc toc) 572c9e2be55Smrg{ 573c9e2be55Smrg if (! toc->scanfile) { 574c9e2be55Smrg if (! toc->path) { 575c9e2be55Smrg /* usually preset by TocFolderExists */ 57666d665a3Smrg XtAsprintf(&toc->path, "%s/%s", app_resources.mail_path, 57766d665a3Smrg toc->foldername); 578c9e2be55Smrg } 57966d665a3Smrg XtAsprintf(&toc->scanfile, "%s/.xmhcache", toc->path); 580c9e2be55Smrg toc->lastreaddate = LastModifyDate(toc->scanfile); 581c9e2be55Smrg if (TUScanFileOutOfDate(toc)) 582c9e2be55Smrg toc->validity = invalid; 583c9e2be55Smrg else { 584c9e2be55Smrg toc->validity = valid; 585c9e2be55Smrg TULoadTocFile(toc); 586c9e2be55Smrg } 587c9e2be55Smrg } 588c9e2be55Smrg} 589c9e2be55Smrg 590c9e2be55Smrg/* Append a message to the end of the toc. It has the given scan line. This 591c9e2be55Smrg routine will figure out the message number, and change the scan line 592c9e2be55Smrg accordingly. */ 593c9e2be55Smrg 59466d665a3SmrgMsg TUAppendToc(Toc toc, const char *ptr) 595c9e2be55Smrg{ 596c9e2be55Smrg Msg msg; 597c9e2be55Smrg int msgid; 598c9e2be55Smrg 599c9e2be55Smrg TUGetFullFolderInfo(toc); 600c9e2be55Smrg if (toc->validity != valid) 601c9e2be55Smrg return NULL; 602d859ff80Smrg 603c9e2be55Smrg if (toc->nummsgs > 0) 604c9e2be55Smrg msgid = toc->msgs[toc->nummsgs - 1]->msgid + 1; 605c9e2be55Smrg else 606c9e2be55Smrg msgid = 1; 607c9e2be55Smrg (toc->nummsgs)++; 60866d665a3Smrg toc->msgs = XtReallocArray(toc->msgs, toc->nummsgs, sizeof(Msg)); 609c9e2be55Smrg toc->msgs[toc->nummsgs - 1] = msg = XtNew(MsgRec); 610c9e2be55Smrg bzero((char *) msg, (int) sizeof(MsgRec)); 611c9e2be55Smrg msg->toc = toc; 612c9e2be55Smrg msg->buf = XtNewString(ptr); 613c9e2be55Smrg if (msgid >= 10000) 614c9e2be55Smrg msgid %= 10000; 61566d665a3Smrg snprintf(msg->buf, strlen(msg->buf) + 1, "%4d", msgid); 616c9e2be55Smrg msg->buf[MARKPOS] = ' '; 617c9e2be55Smrg msg->msgid = msgid; 618c9e2be55Smrg msg->position = toc->lastPos; 619c9e2be55Smrg msg->length = strlen(ptr); 620c9e2be55Smrg msg->changed = TRUE; 621c9e2be55Smrg msg->fate = Fignore; 622c9e2be55Smrg msg->desttoc = NULL; 623c9e2be55Smrg if (toc->viewedseq == toc->seqlist[0]) { 624c9e2be55Smrg msg->visible = TRUE; 625c9e2be55Smrg toc->lastPos += msg->length; 626c9e2be55Smrg } 627c9e2be55Smrg else 628c9e2be55Smrg msg->visible = FALSE; 629c9e2be55Smrg toc->length += msg->length; 630c9e2be55Smrg if ( (msg->visible) && (toc->source != NULL) ) 631c9e2be55Smrg TSourceInvalid(toc, msg->position, msg->length); 632c9e2be55Smrg TUSaveTocFile(toc); 633c9e2be55Smrg return msg; 634c9e2be55Smrg} 635