tocutil.c revision c9e2be55
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 60c9e2be55Smrg/* 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]; 69c9e2be55Smrg 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 102c9e2be55Smrg 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. */ 112c9e2be55Smrg 113c9e2be55Smrg callbacks[0].closure = (XtPointer) scrn; 114c9e2be55Smrg 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 138c9e2be55Smrg (void) sprintf(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"; 145c9e2be55Smrg (void) sprintf(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 } 183c9e2be55Smrg (void) sprintf(str, 184c9e2be55Smrg "TUGetMsgPosition search failed! hi=%d, lo=%d, msgid=%d", 185c9e2be55Smrg 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 } 204c9e2be55Smrg (void) sprintf(str, "%s:%s", toc->foldername, 205c9e2be55Smrg toc->viewedseq->name); 206c9e2be55Smrg toc->needslabelupdate = FALSE; 207c9e2be55Smrg } 208c9e2be55Smrg ChangeLabel((Widget) scrn->toclabel, str); 209c9e2be55Smrg } 210c9e2be55Smrg} 211c9e2be55Smrg 212c9e2be55Smrg 213c9e2be55Smrg/* A major toc change has occured; 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; 269c9e2be55Smrg (void) sprintf(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++; 280c9e2be55Smrg toc->seqlist = (Sequence *) 281c9e2be55Smrg XtRealloc((char *) toc->seqlist, (Cardinal) 282c9e2be55Smrg toc->numsequences * sizeof(Sequence)); 283c9e2be55Smrg seq = toc->seqlist[toc->numsequences - 1] = 284c9e2be55Smrg XtNew(SequenceRec); 285c9e2be55Smrg seq->name = XtNewString(ptr); 286c9e2be55Smrg seq->mlist = StringToMsgList(toc, ptr2 + 1); 287c9e2be55Smrg if (strcmp(seq->name, viewed) == 0) { 288c9e2be55Smrg toc->viewedseq = seq; 289c9e2be55Smrg *viewed = 0; 290c9e2be55Smrg } 291c9e2be55Smrg if (strcmp(seq->name, selected) == 0) { 292c9e2be55Smrg toc->selectseq = seq; 293c9e2be55Smrg *selected = 0; 294c9e2be55Smrg } 295c9e2be55Smrg } 296c9e2be55Smrg } 297c9e2be55Smrg } 298c9e2be55Smrg (void) myfclose(fid); 299c9e2be55Smrg } 300c9e2be55Smrg} 301c9e2be55Smrg 302c9e2be55Smrg 303c9e2be55Smrg 304c9e2be55Smrg/* Refigure what messages are visible. */ 305c9e2be55Smrg 306c9e2be55Smrgvoid TURefigureWhatsVisible(Toc toc) 307c9e2be55Smrg{ 308c9e2be55Smrg MsgList mlist; 309c9e2be55Smrg Msg msg, oldcurmsg; 310c9e2be55Smrg int i; 311c9e2be55Smrg int w, changed, newval, msgid; 312c9e2be55Smrg Sequence seq = toc->viewedseq; 313c9e2be55Smrg mlist = seq->mlist; 314c9e2be55Smrg oldcurmsg = toc->curmsg; 315c9e2be55Smrg TocSetCurMsg(toc, (Msg)NULL); 316c9e2be55Smrg w = 0; 317c9e2be55Smrg changed = FALSE; 318c9e2be55Smrg 319c9e2be55Smrg for (i = 0; i < toc->nummsgs; i++) { 320c9e2be55Smrg msg = toc->msgs[i]; 321c9e2be55Smrg msgid = msg->msgid; 322c9e2be55Smrg while (mlist && mlist->msglist[w] && mlist->msglist[w]->msgid < msgid) 323c9e2be55Smrg w++; 324c9e2be55Smrg newval = (!mlist 325c9e2be55Smrg || (mlist->msglist[w] && mlist->msglist[w]->msgid == msgid)); 326c9e2be55Smrg if (newval != msg->visible) { 327c9e2be55Smrg changed = TRUE; 328c9e2be55Smrg msg->visible = newval; 329c9e2be55Smrg } 330c9e2be55Smrg } 331c9e2be55Smrg if (changed) { 332c9e2be55Smrg TURefigureTocPositions(toc); 333c9e2be55Smrg if (oldcurmsg) { 334c9e2be55Smrg if (!oldcurmsg->visible) { 335c9e2be55Smrg toc->curmsg = TocMsgAfter(toc, oldcurmsg); 336c9e2be55Smrg if (toc->curmsg == NULL) 337c9e2be55Smrg toc->curmsg = TocMsgBefore(toc, oldcurmsg); 338c9e2be55Smrg } else toc->curmsg = oldcurmsg; 339c9e2be55Smrg } 340c9e2be55Smrg for (i=0 ; i<toc->num_scrns ; i++) 341c9e2be55Smrg TURedisplayToc(toc->scrn[i]); 342c9e2be55Smrg } else TocSetCurMsg(toc, oldcurmsg); 343c9e2be55Smrg for (i=0 ; i<toc->num_scrns ; i++) 344c9e2be55Smrg TUResetTocLabel(toc->scrn[i]); 345c9e2be55Smrg} 346c9e2be55Smrg 347c9e2be55Smrg 348c9e2be55Smrg/* (Re)load the toc from the scanfile. If reloading, this makes efforts to 349c9e2be55Smrg keep the fates of msgs, and to keep msgs that are being edited. Note that 350c9e2be55Smrg this routine must know of all places that msg ptrs are stored; it expects 351c9e2be55Smrg them to be kept only in tocs, in scrns, and in msg sequences. */ 352c9e2be55Smrg 353c9e2be55Smrg#define SeemsIdentical(msg1, msg2) ((msg1)->msgid == (msg2)->msgid && \ 354c9e2be55Smrg ((msg1)->temporary || (msg2)->temporary ||\ 355c9e2be55Smrg strcmp((msg1)->buf, (msg2)->buf) == 0)) 356c9e2be55Smrg 357c9e2be55Smrgvoid TULoadTocFile(Toc toc) 358c9e2be55Smrg{ 359c9e2be55Smrg int maxmsgs, l, orignummsgs, i, j, origcurmsgid; 360c9e2be55Smrg FILEPTR fid; 361c9e2be55Smrg XawTextPosition position; 362c9e2be55Smrg char *ptr; 363c9e2be55Smrg Msg msg, curmsg; 364c9e2be55Smrg Msg *origmsgs; 365c9e2be55Smrg int bufsiz = app_resources.toc_width + 1; 366c9e2be55Smrg static char *buf; 367c9e2be55Smrg 368c9e2be55Smrg if (!buf) 369c9e2be55Smrg buf = XtMalloc((Cardinal) bufsiz); 370c9e2be55Smrg TocStopUpdate(toc); 371c9e2be55Smrg toc->lastreaddate = LastModifyDate(toc->scanfile); 372c9e2be55Smrg if (toc->curmsg) { 373c9e2be55Smrg origcurmsgid = toc->curmsg->msgid; 374c9e2be55Smrg TocSetCurMsg(toc, (Msg)NULL); 375c9e2be55Smrg } else origcurmsgid = 0; /* The "default" current msg; 0 means none */ 376c9e2be55Smrg fid = FOpenAndCheck(toc->scanfile, "r"); 377c9e2be55Smrg maxmsgs = orignummsgs = toc->nummsgs; 378c9e2be55Smrg if (maxmsgs == 0) maxmsgs = 100; 379c9e2be55Smrg toc->nummsgs = 0; 380c9e2be55Smrg origmsgs = toc->msgs; 381c9e2be55Smrg toc->msgs = (Msg *) XtMalloc((Cardinal) maxmsgs * sizeof(Msg)); 382c9e2be55Smrg position = 0; 383c9e2be55Smrg i = 0; 384c9e2be55Smrg curmsg = NULL; 385c9e2be55Smrg while ((ptr = fgets(buf, bufsiz, fid))) { 386c9e2be55Smrg toc->msgs[toc->nummsgs++] = msg = XtNew(MsgRec); 387c9e2be55Smrg bzero((char *) msg, sizeof(MsgRec)); 388c9e2be55Smrg msg->toc = toc; 389c9e2be55Smrg msg->position = position; 390c9e2be55Smrg msg->length = l = strlen(ptr); 391c9e2be55Smrg position += l; 392c9e2be55Smrg if (l == app_resources.toc_width && buf[bufsiz-2] != '\n') { 393c9e2be55Smrg buf[bufsiz-2] = '\n'; 394c9e2be55Smrg msg->buf = strcpy(XtMalloc((Cardinal) ++l), ptr); 395c9e2be55Smrg msg->msgid = atoi(ptr); 396c9e2be55Smrg do 397c9e2be55Smrg ptr = fgets(buf, bufsiz, fid); 398c9e2be55Smrg while (ptr && (int) strlen(ptr) == app_resources.toc_width 399c9e2be55Smrg && buf[bufsiz-2] != '\n'); 400c9e2be55Smrg } else { 401c9e2be55Smrg msg->buf = strcpy(XtMalloc((Cardinal) ++l), ptr); 402c9e2be55Smrg msg->msgid = atoi(ptr); 403c9e2be55Smrg } 404c9e2be55Smrg if (msg->msgid == origcurmsgid) 405c9e2be55Smrg curmsg = msg; 406c9e2be55Smrg msg->buf[MARKPOS] = ' '; 407c9e2be55Smrg msg->changed = FALSE; 408c9e2be55Smrg msg->fate = Fignore; 409c9e2be55Smrg msg->desttoc = NULL; 410c9e2be55Smrg msg->visible = TRUE; 411c9e2be55Smrg if (toc->nummsgs >= maxmsgs) { 412c9e2be55Smrg maxmsgs += 100; 413c9e2be55Smrg toc->msgs = (Msg *) XtRealloc((char *) toc->msgs, 414c9e2be55Smrg (Cardinal) maxmsgs * sizeof(Msg)); 415c9e2be55Smrg } 416c9e2be55Smrg while (i < orignummsgs && origmsgs[i]->msgid < msg->msgid) i++; 417c9e2be55Smrg if (i < orignummsgs) { 418c9e2be55Smrg origmsgs[i]->buf[MARKPOS] = ' '; 419c9e2be55Smrg if (SeemsIdentical(origmsgs[i], msg)) 420c9e2be55Smrg MsgSetFate(msg, origmsgs[i]->fate, origmsgs[i]->desttoc); 421c9e2be55Smrg } 422c9e2be55Smrg } 423c9e2be55Smrg toc->length = toc->origlength = toc->lastPos = position; 424c9e2be55Smrg toc->msgs = (Msg *) XtRealloc((char *) toc->msgs, 425c9e2be55Smrg (Cardinal) toc->nummsgs * sizeof(Msg)); 426c9e2be55Smrg (void) myfclose(fid); 427c9e2be55Smrg if ( (toc->source == NULL) && ( toc->num_scrns > 0 ) ) { 428c9e2be55Smrg Arg args[1]; 429c9e2be55Smrg 430c9e2be55Smrg XtSetArg(args[0], XtNtoc, toc); 431c9e2be55Smrg toc->source = XtCreateWidget("tocSource", tocSourceWidgetClass, 432c9e2be55Smrg toc->scrn[0]->tocwidget, 433c9e2be55Smrg args, (Cardinal) 1); 434c9e2be55Smrg } 435c9e2be55Smrg for (i=0 ; i<numScrns ; i++) { 436c9e2be55Smrg msg = scrnList[i]->msg; 437c9e2be55Smrg if (msg && msg->toc == toc) { 438c9e2be55Smrg for (j=0 ; j<toc->nummsgs ; j++) { 439c9e2be55Smrg if (SeemsIdentical(toc->msgs[j], msg)) { 440c9e2be55Smrg msg->position = toc->msgs[j]->position; 441c9e2be55Smrg msg->visible = TRUE; 442c9e2be55Smrg ptr = toc->msgs[j]->buf; 443c9e2be55Smrg l = toc->msgs[j]->length; 444c9e2be55Smrg *(toc->msgs[j]) = *msg; 445c9e2be55Smrg toc->msgs[j]->buf = ptr; 446c9e2be55Smrg toc->msgs[j]->length = l; 447c9e2be55Smrg scrnList[i]->msg = toc->msgs[j]; 448c9e2be55Smrg break; 449c9e2be55Smrg } 450c9e2be55Smrg } 451c9e2be55Smrg if (j >= toc->nummsgs) { 452c9e2be55Smrg msg->temporary = FALSE; /* Don't try to auto-delete msg. */ 453c9e2be55Smrg MsgSetScrnForce(msg, (Scrn) NULL); 454c9e2be55Smrg } 455c9e2be55Smrg } 456c9e2be55Smrg } 457c9e2be55Smrg for (i=0 ; i<orignummsgs ; i++) 458c9e2be55Smrg MsgFree(origmsgs[i]); 459c9e2be55Smrg XtFree((char *)origmsgs); 460c9e2be55Smrg TocSetCurMsg(toc, curmsg); 461c9e2be55Smrg TULoadSeqLists(toc); 462c9e2be55Smrg TocStartUpdate(toc); 463c9e2be55Smrg} 464c9e2be55Smrg 465c9e2be55Smrg 466c9e2be55Smrgvoid TUSaveTocFile(Toc toc) 467c9e2be55Smrg{ 468c9e2be55Smrg Msg msg; 469c9e2be55Smrg int fid; 470c9e2be55Smrg int i; 471c9e2be55Smrg XawTextPosition position; 472c9e2be55Smrg char c; 473c9e2be55Smrg if (toc->stopupdate) { 474c9e2be55Smrg toc->needscachesave = TRUE; 475c9e2be55Smrg return; 476c9e2be55Smrg } 477c9e2be55Smrg fid = -1; 478c9e2be55Smrg position = 0; 479c9e2be55Smrg for (i = 0; i < toc->nummsgs; i++) { 480c9e2be55Smrg msg = toc->msgs[i]; 481c9e2be55Smrg if (fid < 0 && msg->changed) { 482c9e2be55Smrg fid = myopen(toc->scanfile, O_RDWR, 0666); 483c9e2be55Smrg (void) lseek(fid, (long)position, 0); 484c9e2be55Smrg } 485c9e2be55Smrg if (fid >= 0) { 486c9e2be55Smrg c = msg->buf[MARKPOS]; 487c9e2be55Smrg msg->buf[MARKPOS] = ' '; 488c9e2be55Smrg (void) write(fid, msg->buf, msg->length); 489c9e2be55Smrg msg->buf[MARKPOS] = c; 490c9e2be55Smrg } 491c9e2be55Smrg position += msg->length; 492c9e2be55Smrg } 493c9e2be55Smrg if (fid < 0 && toc->length != toc->origlength) 494c9e2be55Smrg fid = myopen(toc->scanfile, O_RDWR, 0666); 495c9e2be55Smrg if (fid >= 0) { 496c9e2be55Smrg#if defined(SYSV) && (defined(i386) || defined(MOTOROLA)) 497c9e2be55Smrg (void) ftruncate_emu(fid, toc->length, toc->scanfile); 498c9e2be55Smrg#else 499c9e2be55Smrg (void) ftruncate(fid, toc->length); 500c9e2be55Smrg myclose(fid); 501c9e2be55Smrg#endif 502c9e2be55Smrg toc->origlength = toc->length; 503c9e2be55Smrg } 504c9e2be55Smrg toc->needscachesave = FALSE; 505c9e2be55Smrg toc->lastreaddate = LastModifyDate(toc->scanfile); 506c9e2be55Smrg} 507c9e2be55Smrg 508c9e2be55Smrg 509c9e2be55Smrgstatic Boolean UpdateScanFile( 510c9e2be55Smrg XtPointer client_data) /* Toc */ 511c9e2be55Smrg{ 512c9e2be55Smrg Toc toc = (Toc)client_data; 513c9e2be55Smrg int i; 514c9e2be55Smrg 515c9e2be55Smrg if (app_resources.block_events_on_busy) ShowBusyCursor(); 516c9e2be55Smrg 517c9e2be55Smrg TUScanFileForToc(toc); 518c9e2be55Smrg TULoadTocFile(toc); 519c9e2be55Smrg 520c9e2be55Smrg for (i=0 ; i<toc->num_scrns ; i++) 521c9e2be55Smrg TURedisplayToc(toc->scrn[i]); 522c9e2be55Smrg 523c9e2be55Smrg if (app_resources.block_events_on_busy) UnshowBusyCursor(); 524c9e2be55Smrg 525c9e2be55Smrg return True; 526c9e2be55Smrg} 527c9e2be55Smrg 528c9e2be55Smrg 529c9e2be55Smrgvoid TUEnsureScanIsValidAndOpen(Toc toc, Boolean delay) 530c9e2be55Smrg{ 531c9e2be55Smrg if (toc) { 532c9e2be55Smrg TUGetFullFolderInfo(toc); 533c9e2be55Smrg if (TUScanFileOutOfDate(toc)) { 534c9e2be55Smrg if (!delay) 535c9e2be55Smrg UpdateScanFile((XtPointer)toc); 536c9e2be55Smrg else { 537c9e2be55Smrg /* this is a hack to get the screen mapped before 538c9e2be55Smrg * spawning the subprocess (and blocking). 539c9e2be55Smrg * Need to make sure the scanfile exists at this point. 540c9e2be55Smrg */ 541c9e2be55Smrg int fid = myopen(toc->scanfile, O_RDWR|O_CREAT, 0666); 542c9e2be55Smrg myclose(fid); 543c9e2be55Smrg XtAppAddWorkProc(XtWidgetToApplicationContext(toplevel), 544c9e2be55Smrg UpdateScanFile, 545c9e2be55Smrg (XtPointer)toc); 546c9e2be55Smrg } 547c9e2be55Smrg } 548c9e2be55Smrg if (toc->source == NULL) 549c9e2be55Smrg TULoadTocFile(toc); 550c9e2be55Smrg } 551c9e2be55Smrg} 552c9e2be55Smrg 553c9e2be55Smrg 554c9e2be55Smrg 555c9e2be55Smrg/* Refigure all the positions, based on which lines are visible. */ 556c9e2be55Smrg 557c9e2be55Smrgvoid TURefigureTocPositions(Toc toc) 558c9e2be55Smrg{ 559c9e2be55Smrg int i; 560c9e2be55Smrg Msg msg; 561c9e2be55Smrg XawTextPosition position, length; 562c9e2be55Smrg position = length = 0; 563c9e2be55Smrg for (i=0; i<toc->nummsgs ; i++) { 564c9e2be55Smrg msg = toc->msgs[i]; 565c9e2be55Smrg msg->position = position; 566c9e2be55Smrg if (msg->visible) position += msg->length; 567c9e2be55Smrg length += msg->length; 568c9e2be55Smrg } 569c9e2be55Smrg toc->lastPos = position; 570c9e2be55Smrg toc->length = length; 571c9e2be55Smrg} 572c9e2be55Smrg 573c9e2be55Smrg 574c9e2be55Smrg 575c9e2be55Smrg/* Make sure we've loaded ALL the folder info for this toc, including its 576c9e2be55Smrg path and sequence lists. */ 577c9e2be55Smrg 578c9e2be55Smrgvoid TUGetFullFolderInfo(Toc toc) 579c9e2be55Smrg{ 580c9e2be55Smrg char str[500]; 581c9e2be55Smrg if (! toc->scanfile) { 582c9e2be55Smrg if (! toc->path) { 583c9e2be55Smrg /* usually preset by TocFolderExists */ 584c9e2be55Smrg (void) sprintf(str, "%s/%s", app_resources.mail_path, 585c9e2be55Smrg toc->foldername); 586c9e2be55Smrg toc->path = XtNewString(str); 587c9e2be55Smrg } 588c9e2be55Smrg (void) sprintf(str, "%s/.xmhcache", toc->path); 589c9e2be55Smrg toc->scanfile = XtNewString(str); 590c9e2be55Smrg toc->lastreaddate = LastModifyDate(toc->scanfile); 591c9e2be55Smrg if (TUScanFileOutOfDate(toc)) 592c9e2be55Smrg toc->validity = invalid; 593c9e2be55Smrg else { 594c9e2be55Smrg toc->validity = valid; 595c9e2be55Smrg TULoadTocFile(toc); 596c9e2be55Smrg } 597c9e2be55Smrg } 598c9e2be55Smrg} 599c9e2be55Smrg 600c9e2be55Smrg/* Append a message to the end of the toc. It has the given scan line. This 601c9e2be55Smrg routine will figure out the message number, and change the scan line 602c9e2be55Smrg accordingly. */ 603c9e2be55Smrg 604c9e2be55SmrgMsg TUAppendToc(Toc toc, char *ptr) 605c9e2be55Smrg{ 606c9e2be55Smrg Msg msg; 607c9e2be55Smrg int msgid; 608c9e2be55Smrg 609c9e2be55Smrg TUGetFullFolderInfo(toc); 610c9e2be55Smrg if (toc->validity != valid) 611c9e2be55Smrg return NULL; 612c9e2be55Smrg 613c9e2be55Smrg if (toc->nummsgs > 0) 614c9e2be55Smrg msgid = toc->msgs[toc->nummsgs - 1]->msgid + 1; 615c9e2be55Smrg else 616c9e2be55Smrg msgid = 1; 617c9e2be55Smrg (toc->nummsgs)++; 618c9e2be55Smrg toc->msgs = (Msg *) XtRealloc((char *) toc->msgs, 619c9e2be55Smrg (Cardinal) toc->nummsgs * sizeof(Msg)); 620c9e2be55Smrg toc->msgs[toc->nummsgs - 1] = msg = XtNew(MsgRec); 621c9e2be55Smrg bzero((char *) msg, (int) sizeof(MsgRec)); 622c9e2be55Smrg msg->toc = toc; 623c9e2be55Smrg msg->buf = XtNewString(ptr); 624c9e2be55Smrg if (msgid >= 10000) 625c9e2be55Smrg msgid %= 10000; 626c9e2be55Smrg (void)sprintf(msg->buf, "%4d", msgid); 627c9e2be55Smrg msg->buf[MARKPOS] = ' '; 628c9e2be55Smrg msg->msgid = msgid; 629c9e2be55Smrg msg->position = toc->lastPos; 630c9e2be55Smrg msg->length = strlen(ptr); 631c9e2be55Smrg msg->changed = TRUE; 632c9e2be55Smrg msg->fate = Fignore; 633c9e2be55Smrg msg->desttoc = NULL; 634c9e2be55Smrg if (toc->viewedseq == toc->seqlist[0]) { 635c9e2be55Smrg msg->visible = TRUE; 636c9e2be55Smrg toc->lastPos += msg->length; 637c9e2be55Smrg } 638c9e2be55Smrg else 639c9e2be55Smrg msg->visible = FALSE; 640c9e2be55Smrg toc->length += msg->length; 641c9e2be55Smrg if ( (msg->visible) && (toc->source != NULL) ) 642c9e2be55Smrg TSourceInvalid(toc, msg->position, msg->length); 643c9e2be55Smrg TUSaveTocFile(toc); 644c9e2be55Smrg return msg; 645c9e2be55Smrg} 646