|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/desktop/dlgutil2.c |
source navigation diff markup identifier search freetext search file search |
1 /* dlgutil2.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: dlgutil2.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 1/22/95
31 *
32 * $Revision: 6.211 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44
45 #include <dlogutil.h>
46 #include <document.h>
47 #include <gather.h>
48 #include <subutil.h>
49 #include <objfdef.h>
50 #include <gbfeat.h>
51 #include <gbftdef.h>
52 #include <utilpub.h>
53 #include <objfeat.h>
54 #include <objseq.h>
55 #include <toasn3.h>
56 #include <explore.h>
57 #include <findrepl.h>
58 #ifdef WIN_MOTIF
59 #include <netscape.h>
60 #endif
61 #define NLM_GENERATED_CODE_PROTO
62 #include <objmacro.h>
63 #include <macroapi.h>
64
65 typedef struct datepage {
66 DIALOG_MESSAGE_BLOCK
67 TexT year;
68 PopuP year_popup;
69 Int4 start_year;
70 Int4 num_years;
71 PopuP month;
72 TexT day;
73 } DatePage, PNTR DatePagePtr;
74
75 extern CharPtr SaveStringFromTextAndStripNewlines (TexT t)
76
77 {
78 Char ch;
79 size_t len;
80 CharPtr ptr;
81 CharPtr str;
82
83 len = TextLength (t);
84 if (len > 0) {
85 str = MemNew (len + 1);
86 if (str != NULL) {
87 GetTitle (t, str, len + 1);
88 ptr = str;
89 ch = *ptr;
90 while (ch != '\0') {
91 if (ch < ' ') {
92 *ptr = ' ';
93 }
94 ptr++;
95 ch = *ptr;
96 }
97 TrimSpacesAroundString (str);
98 if (StringHasNoText (str)) {
99 str = MemFree (str);
100 }
101 return str;
102 } else {
103 return NULL;
104 }
105 } else {
106 return NULL;
107 }
108 }
109
110
111 extern CharPtr StripNewlines (CharPtr str)
112
113 {
114 Char ch;
115 size_t len;
116 CharPtr ptr;
117
118 if (str == NULL) return str;
119 len = StringLen (str);
120 if (len > 0) {
121 ptr = str;
122 ch = *ptr;
123 while (ch != '\0') {
124 if (ch < ' ') {
125 *ptr = ' ';
126 }
127 ptr++;
128 ch = *ptr;
129 }
130 TrimSpacesAroundString (str);
131 if (StringHasNoText (str)) {
132 str = MemFree (str);
133 }
134 } else {
135 str = MemFree (str);
136 }
137 return str;
138 }
139
140
141 extern void NewlinesToTildes (CharPtr str)
142
143 {
144 Uchar ch;
145 CharPtr ptr;
146
147 if (StringHasNoText (str)) return;
148 ptr = str;
149 ch = *ptr;
150 while (ch != '\0') {
151 if (ch < ' ') {
152 *ptr = '~';
153 }
154 ptr++;
155 ch = *ptr;
156 }
157 }
158
159
160 static void DatePtrToDatePage (DialoG d, Pointer data)
161
162 {
163 DatePtr dp;
164 DatePagePtr dpp;
165 Int2 day;
166 Char str [32];
167 Int2 year, val;
168
169
170 dpp = (DatePagePtr) GetObjectExtra (d);
171 dp = (DatePtr) data;
172 if (dpp != NULL) {
173 if (dp == NULL || dp->data[0] != 1) {
174 SafeSetValue (dpp->month, 1);
175 SafeSetTitle (dpp->day, "");
176 SafeSetTitle (dpp->year, "");
177 SafeSetValue (dpp->year_popup, 1);
178 } else {
179 /* set month */
180 SetEnumPopup (dpp->month, months_alist, (UIEnum) dp->data [2]);
181 /* set day */
182 day = (Int2) dp->data [3];
183 if (day > 0 && day <= 31) {
184 sprintf (str, "%d", (int) day);
185 SafeSetTitle (dpp->day, str);
186 } else {
187 SafeSetTitle (dpp->day, "");
188 }
189 /* set year */
190 year = (Int2) dp->data [1];
191 if (year > 0) {
192 if (dpp->year_popup == NULL) {
193 sprintf (str, "%d", (int) (year + 1900));
194 SafeSetTitle (dpp->year, str);
195 } else {
196 val = year + 1900 - dpp->start_year + 1;
197 if (val < 1 || val >= dpp->num_years) {
198 sprintf (str, "%d", (int) (year + 1900));
199 SafeSetTitle (dpp->year, str);
200 dpp->year_popup = NULL;
201 Show (dpp->year);
202 } else {
203 SetValue (dpp->year_popup, val);
204 }
205 }
206 } else {
207 if (dpp->year_popup == NULL) {
208 SafeSetTitle (dpp->year, "");
209 } else {
210 SetValue (dpp->year_popup, 1);
211 }
212 }
213 }
214 }
215 }
216
217 static Pointer DatePageToDatePtr (DialoG d)
218
219 {
220 DatePtr dp;
221 DatePagePtr dpp;
222 Int2 day;
223 UIEnum month;
224 Char str [32];
225 Int2 year = 0;
226
227 dp = NULL;
228 dpp = (DatePagePtr) GetObjectExtra (d);
229 if (dpp != NULL) {
230 dp = DateNew ();
231 if (dp != NULL) {
232 dp->data [0] = 1;
233 /* get year value */
234 if (dpp->year_popup != NULL) {
235 year = GetValue (dpp->year_popup);
236 if (year > 0) {
237 year += dpp->start_year - 1;
238 } else {
239 dp = DateFree (dp);
240 return NULL;
241 }
242 } else {
243 GetTitle (dpp->year, str, sizeof (str));
244 if (! StringHasNoText (str)) {
245 StrToInt (str, &year);
246 }
247 }
248 if (year >= 1900) {
249 dp->data [1] = (Uint1) (year - 1900);
250 } else {
251 dp = DateFree (dp);
252 return dp;
253 }
254 /* get month value */
255 if (GetEnumPopup (dpp->month, months_alist, &month)) {
256 dp->data [2] = (Uint1) month;
257 } else {
258 dp = DateFree (dp);
259 return dp;
260 }
261 /* get day value */
262 GetTitle (dpp->day, str, sizeof (str));
263 StrToInt (str, &day);
264 dp->data [3] = (Uint1) day;
265 }
266 }
267 return (Pointer) dp;
268 }
269
270 extern DialoG CreateDateDialogEx (GrouP prnt, CharPtr title, Int4 start_year, Int4 num_years)
271
272 {
273 DatePagePtr dpp;
274 GrouP f;
275 GrouP m;
276 GrouP p;
277 GrouP s;
278 GrouP year_grp;
279 Char year_buf[15];
280 Int4 i;
281
282 p = HiddenGroup (prnt, 1, 0, NULL);
283 SetGroupSpacing (p, 10, 10);
284
285 dpp = (DatePagePtr) MemNew (sizeof (DatePage));
286 if (dpp) {
287
288 SetObjectExtra (p, dpp, StdCleanupExtraProc);
289 dpp->dialog = (DialoG) p;
290 dpp->todialog = DatePtrToDatePage;
291 dpp->fromdialog = DatePageToDatePtr;
292 dpp->testdialog = NULL;
293
294 dpp->start_year = start_year;
295 dpp->num_years = num_years;
296
297 if (title != NULL && title [0] != '\0') {
298 s = NormalGroup (p, 0, -2, title, systemFont, NULL);
299 } else {
300 s = HiddenGroup (p, 0, -2, NULL);
301 }
302 m = HiddenGroup (s, -1, 0, NULL);
303 /*
304 SetGroupSpacing (m, 10, 10);
305 */
306
307 f = HiddenGroup (m, -6, 0, NULL);
308 StaticPrompt (f, "Month", 0, popupMenuHeight, programFont, 'l');
309 dpp->month = PopupList (f, TRUE, NULL);
310 InitEnumPopup (dpp->month, months_alist, NULL);
311 SetValue (dpp->month, 1);
312 StaticPrompt (f, "Day", 0, dialogTextHeight, programFont, 'l');
313 dpp->day = DialogText (f, "", 4, NULL);
314 StaticPrompt (f, "Year", 0, dialogTextHeight, programFont, 'l');
315 year_grp = HiddenGroup (f, 0, 0, NULL);
316 if (start_year > 0 && num_years > -1) {
317 dpp->year_popup = PopupList (year_grp, TRUE, NULL);
318 for (i = 0; i < num_years; i++) {
319 sprintf (year_buf, "%d", start_year + i);
320 PopupItem (dpp->year_popup, year_buf);
321 }
322 }
323 dpp->year = DialogText (year_grp, "", 6, NULL);
324 if (dpp->year_popup != NULL) {
325 SafeHide (dpp->year);
326 }
327 AlignObjects (ALIGN_CENTER, (HANDLE)dpp->year, (HANDLE)dpp->year_popup, NULL);
328 }
329
330 return (DialoG) p;
331 }
332
333
334 extern DialoG CreateDateDialog (GrouP prnt, CharPtr title)
335
336 {
337 return CreateDateDialogEx (prnt, title, -1, 0);
338 }
339
340
341 typedef struct featcit {
342 DIALOG_MESSAGE_BLOCK
343 DoC citdoc;
344 ValNodePtr pubset;
345 } FeatCitPage, PNTR FeatCitPagePtr;
346
347 static ParData cofParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
348 static ColData cofColFmt = {0, 0, 0, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, TRUE};
349
350 static ParData cofeParFmt = {TRUE, FALSE, FALSE, FALSE, FALSE, 0, 0};
351 static ColData cofeColFmt = {0, 0, 0, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, TRUE};
352
353 static Uint1 diamondSym [] = {
354 0x00, 0x10, 0x38, 0x7C, 0x38, 0x10, 0x00, 0x00
355 };
356
357 static void DrawCitOnFeat (DoC d, RectPtr r, Int2 item, Int2 firstLine)
358
359 {
360 Int2 lineHeight;
361 RecT rct;
362
363 if (d != NULL && r != NULL && item > 0 && firstLine == 0) {
364 if (item == 1) return; /* citonfeattxt or citonfeathdr explanatory text */
365 GetItemParams (d, item, NULL, NULL, NULL, &lineHeight, NULL);
366 rct = *r;
367 rct.left += 1;
368 rct.right = rct.left + 7;
369 rct.top += (lineHeight - 7) / 2;
370 rct.bottom = rct.top + 7;
371 CopyBits (&rct, diamondSym);
372 /*
373 x = r->left + 1;
374 y = r->top + lineHeight / 2;
375 MoveTo (x, y);
376 LineTo (x + 5, y);
377 */
378 }
379 }
380
381 static int LIBCALLBACK CompareStrings (VoidPtr ptr1, VoidPtr ptr2)
382
383 {
384 CharPtr str1;
385 CharPtr str2;
386
387 if (ptr1 != NULL && ptr2 != NULL) {
388 str1 = *((CharPtr PNTR) ptr1);
389 str2 = *((CharPtr PNTR) ptr2);
390 if (str1 != NULL && str2 != NULL) {
391 return StringICmp (str1, str2);
392 } else {
393 return 0;
394 }
395 } else {
396 return 0;
397 }
398 }
399
400 static CharPtr citonfeattxt =
401 "Press 'Edit Citations' to attach publications to this feature. \
402 Publications must first be added to the record. For biological \
403 justification, and not to credit the sequencer, create publication \
404 with the 'Cites a feature on the sequence' scope.\n";
405
406 static CharPtr citonfeathdr =
407 "Press 'Edit Citations' to change publications.\n\n";
408
409 static void PubsetPtrToFeatCitPage (DialoG d, Pointer data)
410
411 {
412 Int2 count;
413 FeatCitPagePtr fpp;
414 Int2 i;
415 Char label [128];
416 ObjMgrPtr omp;
417 ObjMgrTypePtr omtp;
418 ValNodePtr ppr;
419 ValNodePtr psp;
420 RecT r;
421 CharPtr PNTR strs;
422
423 fpp = (FeatCitPagePtr) GetObjectExtra (d);
424 psp = (ValNodePtr) data;
425 if (fpp != NULL) {
426 Reset (fpp->citdoc);
427 fpp->pubset = PubSetFree (fpp->pubset);
428 fpp->pubset = AsnIoMemCopy (data,
429 (AsnReadFunc) PubSetAsnRead,
430 (AsnWriteFunc) PubSetAsnWrite);
431 SetDocAutoAdjust (fpp->citdoc, FALSE);
432 ObjectRect (fpp->citdoc, &r);
433 InsetRect (&r, 4, 4);
434 cofColFmt.pixWidth = r.right - r.left;
435 cofColFmt.pixInset = 10;
436 omp = ObjMgrGet ();
437 if (omp == NULL) return;
438 omtp = ObjMgrTypeFind (omp, OBJ_SEQFEAT_CIT, NULL, NULL);
439 if (omtp == NULL || omtp->labelfunc == NULL) return;
440 if (psp != NULL && psp->data.ptrvalue != NULL) {
441 count = 0;
442 for (ppr = psp->data.ptrvalue; ppr != NULL; ppr = ppr->next) {
443 count++;
444 }
445 if (count > 0) {
446 strs = MemNew (sizeof (CharPtr) * (size_t) (count + 1));
447 if (strs != NULL) {
448 i = 0;
449 for (ppr = psp->data.ptrvalue; ppr != NULL; ppr = ppr->next) {
450 (*(omtp->labelfunc)) (ppr, label, 127, OM_LABEL_CONTENT);
451 strs [i] = StringSave (label);
452 i++;
453 }
454 HeapSort (strs, count, sizeof (CharPtr), CompareStrings);
455 AppendText (fpp->citdoc, citonfeathdr, &cofParFmt, NULL, programFont);
456 for (i = 0; i < count; i++) {
457 AppendText (fpp->citdoc, strs [i],
458 &cofParFmt, &cofColFmt, programFont);
459 }
460 for (i = 0; i < count; i++) {
461 strs [i] = MemFree (strs [i]);
462 }
463 MemFree (strs);
464 } else {
465 AppendText (fpp->citdoc, citonfeattxt, &cofParFmt, NULL, programFont);
466 }
467 }
468 } else {
469 AppendText (fpp->citdoc, citonfeattxt, &cofParFmt, NULL, programFont);
470 }
471 SetDocShade (fpp->citdoc, DrawCitOnFeat, NULL, NULL, NULL);
472 UpdateDocument (fpp->citdoc, 0, 0);
473 }
474 }
475
476 static Pointer FeatCitPageToPubsetPtr (DialoG d)
477
478 {
479 FeatCitPagePtr fpp;
480 ValNodePtr psp;
481
482 psp = NULL;
483 fpp = (FeatCitPagePtr) GetObjectExtra (d);
484 if (fpp != NULL) {
485 psp = AsnIoMemCopy (fpp->pubset,
486 (AsnReadFunc) PubSetAsnRead,
487 (AsnWriteFunc) PubSetAsnWrite);
488 }
489 return (Pointer) psp;
490 }
491
492 static void CleanupCitOnFeatProc (GraphiC g, VoidPtr data)
493
494 {
495 FeatCitPagePtr fpp;
496
497 fpp = (FeatCitPagePtr) data;
498 if (fpp != NULL) {
499 PubSetFree (fpp->pubset);
500 }
501 MemFree (data);
502 }
503
504 static DialoG CreateCitOnFeatDialog (GrouP h, CharPtr title)
505
506 {
507 FeatCitPagePtr fpp;
508 Int2 lineHeight;
509 GrouP m;
510 GrouP p;
511 GrouP s;
512
513 p = HiddenGroup (h, 1, 0, NULL);
514 SetGroupSpacing (p, 10, 10);
515
516 fpp = (FeatCitPagePtr) MemNew (sizeof (FeatCitPage));
517 if (fpp != NULL) {
518
519 SetObjectExtra (p, fpp, CleanupCitOnFeatProc);
520 fpp->dialog = (DialoG) p;
521 fpp->todialog = PubsetPtrToFeatCitPage;
522 fpp->fromdialog = FeatCitPageToPubsetPtr;
523 fpp->testdialog = NULL;
524
525 if (title != NULL && title [0] != '\0') {
526 s = NormalGroup (p, 0, -2, title, systemFont, NULL);
527 } else {
528 s = HiddenGroup (p, 0, -2, NULL);
529 }
530 m = HiddenGroup (s, -1, 0, NULL);
531 /*
532 SetGroupSpacing (m, 10, 10);
533 */
534
535 SelectFont (programFont);
536 lineHeight = LineHeight ();
537 SelectFont (systemFont);
538 cofParFmt.minHeight = lineHeight + 2;
539 StaticPrompt (m, "Citations on Feature", 25 * stdCharWidth, 0, programFont, 'c');
540 fpp->citdoc = DocumentPanel (m, 25 * stdCharWidth, 5 * cofParFmt.minHeight);
541 SetObjectExtra (fpp->citdoc, fpp, NULL);
542 SetDocAutoAdjust (fpp->citdoc, FALSE);
543 fpp->pubset = NULL;
544 }
545
546 return (DialoG) p;
547 }
548
549 typedef struct citlist {
550 Uint2 entityID;
551 Uint4 itemID;
552 Uint2 itemtype;
553 CharPtr label;
554 } CitListData, PNTR CitListDataPtr;
555
556 typedef struct featcitedit {
557 DIALOG_MESSAGE_BLOCK
558 DoC allcitdoc;
559 Int2 clickedItem;
560 Int2 clickedRow;
561 Int2 numitems;
562 Int2 lineheight;
563 Int2 index;
564 BoolPtr chosen;
565 ValNodePtr citlist;
566 ValNodePtr psp;
567 ObjMgrPtr omp;
568 Int2 entityID;
569 } FeatCitEdit, PNTR FeatCitEditPtr;
570
571 static void CleanupFeatCitForm (GraphiC g, VoidPtr data)
572
573 {
574 FeatCitEditPtr fcep;
575
576 fcep = (FeatCitEditPtr) data;
577 if (fcep != NULL) {
578 MemFree (fcep->chosen);
579 }
580 MemFree (data);
581 }
582
583 static void DrawFeatCit (DoC d, RectPtr r, Int2 item, Int2 firstLine)
584
585 {
586 FeatCitEditPtr fcep;
587 RecT rct;
588
589 fcep = (FeatCitEditPtr) GetObjectExtra (d);
590 if (fcep != NULL && r != NULL && item > 0 && firstLine == 0) {
591 rct = *r;
592 rct.left += 1;
593 rct.right = rct.left + fcep->lineheight;
594 rct.bottom = rct.top + (rct.right - rct.left);
595 FrameRect (&rct);
596 if (item > 0 && item <= fcep->numitems) {
597 if (fcep->chosen != NULL && fcep->chosen [item - 1]) {
598 MoveTo (rct.left, rct.top);
599 LineTo (rct.right - 1, rct.bottom - 1);
600 MoveTo (rct.left, rct.bottom - 1);
601 LineTo (rct.right - 1, rct.top);
602 }
603 }
604 }
605 }
606
607 static void ClickFeatCit (DoC d, PoinT pt)
608
609 {
610 }
611
612 static void ReleaseFeatCit (DoC d, PoinT pt)
613
614 {
615 Int2 col;
616 FeatCitEditPtr fcep;
617 Int2 item;
618 RecT rct;
619 Int2 row;
620
621 fcep = (FeatCitEditPtr) GetObjectExtra (d);
622 if (fcep != NULL && fcep->chosen != NULL) {
623 MapDocPoint (d, pt, &item, &row, &col, &rct);
624 rct.left += 1;
625 rct.right = rct.left + fcep->lineheight;
626 rct.bottom = rct.top + (rct.right - rct.left);
627 if (row == 1 && col == 1 && item > 0 && item <= fcep->numitems && PtInRect (pt, &rct)) {
628 if (fcep->chosen [item - 1]) {
629 fcep->chosen [item - 1] = FALSE;
630 } else {
631 fcep->chosen [item - 1] = TRUE;
632 }
633 InsetRect (&rct, -1, -1);
634 InvalRect (&rct);
635 Update ();
636 }
637 }
638 }
639
640 static Boolean GatherAllCits (GatherContextPtr gcp)
641
642 {
643 CitListDataPtr cldp;
644 FeatCitEditPtr fcep;
645 Char label [128];
646 ObjMgrTypePtr omtp;
647 PubdescPtr pdp;
648 ValNodePtr sdp;
649 SeqFeatPtr sfp;
650 ValNodePtr vnp;
651
652 if (gcp == NULL) return TRUE;
653 fcep = (FeatCitEditPtr) gcp->userdata;
654 if (fcep == NULL) return TRUE;
655 label [0] = '\0';
656 pdp = NULL;
657 if (gcp->thistype == OBJ_SEQDESC) {
658 sdp = (ValNodePtr) gcp->thisitem;
659 if (sdp == NULL || sdp->choice != Seq_descr_pub) return TRUE;
660 pdp = sdp->data.ptrvalue;
661 } else if (gcp->thistype == OBJ_SEQFEAT) {
662 sfp = (SeqFeatPtr) gcp->thisitem;
663 if (sfp == NULL || sfp->data.choice != SEQFEAT_PUB) return TRUE;
664 pdp = sfp->data.value.ptrvalue;
665 } else return TRUE;
666 if (pdp == NULL) return TRUE;
667 omtp = ObjMgrTypeFind (fcep->omp, gcp->thistype, NULL, NULL);
668 if (omtp == NULL || omtp->labelfunc == NULL) return TRUE;
669 (*(omtp->labelfunc)) (gcp->thisitem, label, 127, OM_LABEL_CONTENT);
670 cldp = (CitListDataPtr) MemNew (sizeof (CitListData));
671 if (cldp != NULL) {
672 vnp = ValNodeNew (fcep->citlist);
673 if (fcep->citlist == NULL) {
674 fcep->citlist = vnp;
675 }
676 if (vnp != NULL) {
677 vnp->data.ptrvalue = cldp;
678 cldp->entityID = gcp->entityID;
679 cldp->itemID = gcp->itemID;
680 cldp->itemtype = gcp->thistype;
681 cldp->label = StringSave (label);
682 (fcep->numitems)++;
683 } else {
684 MemFree (cldp);
685 return TRUE;
686 }
687 }
688 return TRUE;
689 }
690
691 static Boolean PrintCitOnFeatItem (GatherContextPtr gcp)
692
693 {
694 CharPtr PNTR rsultp;
695 ValNodePtr sdp;
696 SeqFeatPtr sfp;
697 Boolean success;
698
699 rsultp = (CharPtr PNTR) gcp->userdata;
700 if (rsultp != NULL) {
701 success = FALSE;
702 switch (gcp->thistype) {
703 case OBJ_SEQDESC :
704 sdp = (ValNodePtr) gcp->thisitem;
705 if (sdp->data.ptrvalue != NULL) {
706 success = StdFormatPrint ((Pointer) sdp, (AsnWriteFunc) SeqDescAsnWrite,
707 "StdSeqDesc", spop);
708 } else {
709 *rsultp = StringSave ("Empty Descriptor\n");
710 success = TRUE;
711 }
712 break;
713 case OBJ_SEQFEAT :
714 sfp = (SeqFeatPtr) gcp->thisitem;
715 if (sfp != NULL && (sfp->data.choice == 10 || sfp->data.value.ptrvalue != NULL)) {
716 success = StdFormatPrint ((Pointer) sfp, (AsnWriteFunc) SeqFeatAsnWrite,
717 "StdSeqFeat", spop);
718 } else {
719 *rsultp = StringSave ("Empty Feature\n");
720 success = TRUE;
721 }
722 break;
723 default :
724 break;
725 }
726 if (success) {
727 if (spop->ptr != NULL && *((CharPtr) (spop->ptr)) != '\0') {
728 *rsultp = spop->ptr;
729 spop->ptr = NULL;
730 } else {
731 *rsultp = StringSave ("Empty Data\n");
732 }
733 } else {
734 *rsultp = StringSave ("Data Failure\n");
735 }
736 }
737 return TRUE;
738 }
739
740 static CharPtr CitOnFeatPrintProc (DoC doc, Int2 item, Pointer data)
741
742 {
743 unsigned int entityID;
744 unsigned int itemID;
745 unsigned int itemtype;
746 CharPtr rsult;
747 CharPtr str;
748
749 rsult = NULL;
750 if (data != NULL) {
751 str = (CharPtr) data;
752 if (sscanf (str, "%u %u %u", &entityID, &itemID, &itemtype) == 3) {
753 GatherItem ((Uint2) entityID, (Uint2) itemID, (Uint2) itemtype,
754 (Pointer) &rsult, PrintCitOnFeatItem);
755 }
756 } else {
757 rsult = StringSave ("Null Data\n");
758 }
759 return rsult;
760 }
761
762 static int LIBCALLBACK CompareCitList (VoidPtr ptr1, VoidPtr ptr2)
763
764 {
765 CitListDataPtr cldp1;
766 CitListDataPtr cldp2;
767 CharPtr str1;
768 CharPtr str2;
769
770 if (ptr1 != NULL && ptr2 != NULL) {
771 cldp1 = (CitListDataPtr) ptr1;
772 cldp2 = (CitListDataPtr) ptr2;
773 if (cldp1 != NULL && cldp2 != NULL) {
774 str1 = cldp1->label;
775 str2 = cldp2->label;
776 if (str1 != NULL && str2 != NULL) {
777 return StringICmp (str1, str2);
778 } else {
779 return 0;
780 }
781 } else {
782 return 0;
783 }
784 } else {
785 return 0;
786 }
787 }
788
789 static Boolean MakeMinimalCitOnFeatItem (GatherContextPtr gcp)
790
791 {
792 PubdescPtr pdp;
793 ValNodePtr ppr;
794 ValNodePtr sdp;
795 SeqFeatPtr sfp;
796 ValNodePtr vnp;
797 ValNodePtr PNTR vnpp;
798
799 vnpp = (ValNodePtr PNTR) gcp->userdata;
800 if (vnpp != NULL) {
801 pdp = NULL;
802 switch (gcp->thistype) {
803 case OBJ_SEQDESC :
804 sdp = (ValNodePtr) gcp->thisitem;
805 if (sdp->data.ptrvalue != NULL) {
806 pdp = (PubdescPtr) sdp->data.ptrvalue;
807 }
808 break;
809 case OBJ_SEQFEAT :
810 sfp = (SeqFeatPtr) gcp->thisitem;
811 if (sfp != NULL && (sfp->data.choice == 10 || sfp->data.value.ptrvalue != NULL)) {
812 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
813 }
814 break;
815 default :
816 break;
817 }
818 if (pdp != NULL) {
819 ppr = NULL;
820 vnp = ValNodeNew (NULL);
821 if (vnp != NULL) {
822 vnp->choice = PUB_Equiv;
823 vnp->data.ptrvalue = pdp->pub;
824 ppr = MinimizePub (vnp);
825 ValNodeFree (vnp);
826 }
827 vnp = ValNodeNew (*vnpp);
828 if (*vnpp == NULL) {
829 *vnpp = vnp;
830 }
831 if (vnp != NULL) {
832 vnp->choice = PUB_Equiv;
833 vnp->data.ptrvalue = ppr;
834 }
835 }
836 }
837 return TRUE;
838 }
839
840 static Boolean MatchMinimalCits (GatherContextPtr gcp)
841
842 {
843 FeatCitEditPtr fcep;
844 PubdescPtr pdp;
845 ValNodePtr ppr;
846 ValNodePtr sdp;
847 SeqFeatPtr sfp;
848 ValNodePtr vnp;
849
850 fcep = (FeatCitEditPtr) gcp->userdata;
851 if (fcep != NULL) {
852 pdp = NULL;
853 switch (gcp->thistype) {
854 case OBJ_SEQDESC :
855 sdp = (ValNodePtr) gcp->thisitem;
856 if (sdp->data.ptrvalue != NULL) {
857 pdp = (PubdescPtr) sdp->data.ptrvalue;
858 }
859 break;
860 case OBJ_SEQFEAT :
861 sfp = (SeqFeatPtr) gcp->thisitem;
862 if (sfp != NULL && (sfp->data.choice == 10 || sfp->data.value.ptrvalue != NULL)) {
863 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
864 }
865 break;
866 default :
867 break;
868 }
869 if (pdp != NULL && fcep->psp != NULL) {
870 vnp = ValNodeNew (NULL);
871 if (vnp != NULL) {
872 vnp->choice = PUB_Equiv;
873 vnp->data.ptrvalue = pdp->pub;
874 for (ppr = fcep->psp->data.ptrvalue; ppr != NULL; ppr = ppr->next) {
875 if (PubLabelMatch (vnp, ppr) == 0) {
876 fcep->chosen [fcep->index] = TRUE;
877 }
878 }
879 ValNodeFree (vnp);
880 }
881 }
882 }
883 return TRUE;
884 }
885
886 static void CitListToDialog (DialoG d, Pointer userdata)
887 {
888 FeatCitEditPtr fcep;
889 CitListDataPtr cldp;
890 CitListDataPtr cldpp;
891 Int2 count;
892 GatherScope gs;
893 Int2 i;
894 Int2 j;
895 Char last [128];
896 CharPtr ptr;
897 RecT r;
898 Char str [34];
899 ValNodePtr vnp;
900
901 fcep = (FeatCitEditPtr) GetObjectExtra (d);
902 if (fcep == NULL)
903 {
904 return;
905 }
906 Reset (fcep->allcitdoc);
907
908 fcep->citlist = ValNodeFree (fcep->citlist);
909 fcep->numitems = 0;
910 fcep->chosen = MemFree (fcep->chosen);
911
912 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
913 MemSet ((Pointer) (gs.ignore), (int) (TRUE), (size_t) (OBJ_MAX * sizeof (Boolean)));
914 gs.ignore [OBJ_SEQDESC] = FALSE;
915 gs.ignore [OBJ_SEQANNOT] = FALSE;
916 gs.ignore [OBJ_SEQFEAT] = FALSE;
917 gs.seglevels = 1;
918 GatherEntity (fcep->entityID, (Pointer) fcep, GatherAllCits, &gs);
919 count = fcep->numitems;
920 cldpp = (CitListDataPtr) MemNew (sizeof (CitListData) * (size_t) (count + 1));
921 if (cldpp != NULL) {
922 for (i = 0, vnp = fcep->citlist; i < count && vnp != NULL; i++, vnp = vnp->next) {
923 cldp = vnp->data.ptrvalue;
924 if (cldp != NULL) {
925 cldpp [i] = *cldp;
926 cldp->label = NULL;
927 }
928 }
929 fcep->citlist = ValNodeFreeData (fcep->citlist);
930 HeapSort (cldpp, count, sizeof (CitListData), CompareCitList);
931 last [0] = '\0';
932 ObjectRect (fcep->allcitdoc, &r);
933 InsetRect (&r, 4, 4);
934 cofeColFmt.pixWidth = r.right - r.left;
935 cofeColFmt.pixInset = 20;
936 fcep->numitems = 0;
937 fcep->chosen = MemNew (sizeof (Boolean) * (size_t) (count + 1));
938
939 fcep->psp = (ValNodePtr) userdata;
940 for (i = 0, j = 0; i < count; i++) {
941 cldp = &(cldpp [i]);
942 if (cldp != NULL) {
943 if (last == NULL || StringCmp (cldp->label, last) != 0) {
944 sprintf (str, "%d %d %d", (int) cldp->entityID,
945 (int) cldp->itemID, (int) cldp->itemtype);
946 ptr = StringSave (str);
947 (fcep->numitems)++;
948 AppendItem (fcep->allcitdoc, CitOnFeatPrintProc, (Pointer) ptr,
949 TRUE, 5, &cofeParFmt, &cofeColFmt, programFont);
950 if (fcep->chosen != NULL) {
951 fcep->index = j;
952 GatherItem ((Uint2) cldp->entityID, (Uint2) cldp->itemID,
953 (Uint2) cldp->itemtype, (Pointer) fcep, MatchMinimalCits);
954 }
955 j++;
956 }
957 StringNCpy_0 (last, cldp->label, sizeof (last));
958 cldpp [i].label = MemFree (cldpp [i].label);
959 }
960 }
961 fcep->psp = NULL;
962 }
963 }
964
965 static Pointer DialogToMinimizedCitList (DialoG d)
966 {
967 FeatCitEditPtr fcep;
968 Pointer data;
969 unsigned int entityID;
970 Int2 i;
971 unsigned int itemID;
972 unsigned int itemtype;
973 Int2 numItems;
974 ValNodePtr ppr = NULL, psp = NULL;
975 CharPtr str;
976
977 fcep = (FeatCitEditPtr) GetObjectExtra (d);
978 if (fcep == NULL)
979 {
980 return NULL;
981 }
982
983 if (fcep->chosen != NULL) {
984 GetDocParams (fcep->allcitdoc, &numItems, NULL);
985 for (i = 1; i <= numItems; i++) {
986 if (fcep->chosen [i - 1]) {
987 GetItemParams (fcep->allcitdoc, i, NULL, NULL, NULL, NULL, &data);
988 if (data != NULL) {
989 str = (CharPtr) data;
990 if (sscanf (str, "%u %u %u", &entityID, &itemID, &itemtype) == 3) {
991 GatherItem ((Uint2) entityID, (Uint2) itemID, (Uint2) itemtype,
992 (Pointer) &ppr, MakeMinimalCitOnFeatItem);
993 }
994 }
995 }
996 }
997 }
998
999 if (ppr != NULL)
1000 {
1001 psp = ValNodeNew (NULL);
1002 if (psp != NULL) {
1003 psp->choice = 1;
1004 psp->data.ptrvalue = ppr;
1005 }
1006 }
1007 return psp;
1008 }
1009
1010 extern DialoG FeatCitEditDialog (GrouP parent, Uint2 entityID)
1011 {
1012 FeatCitEditPtr fcep;
1013 GrouP p;
1014
1015 fcep = (FeatCitEditPtr) MemNew (sizeof (FeatCitEdit));
1016 if (fcep == NULL)
1017 {
1018 return NULL;
1019 }
1020
1021 p = HiddenGroup (parent, -1, 0, NULL);
1022 SetObjectExtra (p, fcep, CleanupFeatCitForm);
1023
1024 fcep->dialog = (DialoG) p;
1025 fcep->todialog = CitListToDialog;
1026 fcep->fromdialog = DialogToMinimizedCitList;
1027 fcep->dialogmessage = NULL;
1028 fcep->testdialog = NULL;
1029
1030 fcep->entityID = entityID;
1031 fcep->omp = ObjMgrGet ();
1032 fcep->numitems = 0;
1033
1034 fcep->allcitdoc = DocumentPanel (p, 25 * stdCharWidth, 15 * stdLineHeight);
1035 SetObjectExtra (fcep->allcitdoc, fcep, NULL);
1036 SetDocProcs (fcep->allcitdoc, ClickFeatCit, NULL, ReleaseFeatCit, NULL);
1037 SetDocShade (fcep->allcitdoc, DrawFeatCit, NULL, NULL, NULL);
1038
1039 SelectFont (programFont);
1040 fcep->lineheight = LineHeight ();
1041 SelectFont (systemFont);
1042
1043 return (DialoG) p;
1044 }
1045
1046 typedef struct featcitationform
1047 {
1048 FeatureFormPtr ffp;
1049 DialoG citation_list;
1050
1051 } FeatCitationFormData, PNTR FeatCitationFormPtr;
1052
1053 static void AcceptFeatCit (ButtoN b)
1054
1055 {
1056 FeatCitationFormPtr fcfp;
1057 FeatureFormPtr ffp;
1058 ValNodePtr psp = NULL;
1059
1060 fcfp = (FeatCitationFormPtr) GetObjectExtra (b);
1061 if (fcfp == NULL)
1062 {
1063 return;
1064 }
1065
1066 psp = DialogToPointer (fcfp->citation_list);
1067 ffp = (FeatureFormPtr) fcfp->ffp;
1068 if (ffp != NULL) {
1069 PointerToDialog (ffp->featcits, (Pointer) psp);
1070 PubSetFree (psp);
1071 }
1072 Remove (ParentWindow (b));
1073 }
1074
1075 static void EditFeatCitsProc (ButtoN b)
1076
1077 {
1078 ButtoN btn;
1079 GrouP c;
1080 FeatCitationFormPtr fcfp;
1081 FeatureFormPtr ffp;
1082 WindoW w;
1083 ValNodePtr psp;
1084
1085 ffp = (FeatureFormPtr) GetObjectExtra (b);
1086 if (ffp == NULL)
1087 {
1088 return;
1089 }
1090 fcfp = (FeatCitationFormPtr) MemNew (sizeof (FeatCitationFormData));
1091 if (fcfp == NULL)
1092 {
1093 return;
1094 }
1095
1096 WatchCursor ();
1097 Update ();
1098 w = MovableModalWindow (-50, -33, -10, -10, "Citations", NULL);
1099 SetObjectExtra (w, fcfp, StdCleanupExtraProc);
1100
1101 fcfp->ffp = ffp;
1102 fcfp->citation_list = FeatCitEditDialog (w, ffp->input_entityID);
1103
1104 c = HiddenGroup (w, 4, 0, NULL);
1105 SetGroupSpacing (c, 10, 3);
1106 btn = PushButton (c, "Accept", AcceptFeatCit);
1107 SetObjectExtra (btn, fcfp, NULL);
1108 PushButton (c, "Cancel", StdCancelButtonProc);
1109 AlignObjects (ALIGN_CENTER, (HANDLE) fcfp->citation_list, (HANDLE) c, NULL);
1110 RealizeWindow (w);
1111
1112 psp = DialogToPointer (ffp->featcits);
1113 PointerToDialog (fcfp->citation_list, psp);
1114 PubSetFree (psp);
1115
1116 Show (w);
1117 Select (w);
1118 ArrowCursor ();
1119 Update ();
1120 }
1121
1122 static void ChangeGenePopupOrList (Handle gene)
1123
1124 {
1125 FeatureFormPtr ffp;
1126 Int2 val;
1127
1128 ffp = (FeatureFormPtr) GetObjectExtra (gene);
1129 if (ffp != NULL) {
1130 val = GetValue (ffp->gene);
1131 if (val == 1) {
1132 SafeHide (ffp->newGeneGrp);
1133 SafeHide (ffp->editGeneBtn);
1134 } else if (val == 2) {
1135 SafeHide (ffp->editGeneBtn);
1136 SafeShow (ffp->newGeneGrp);
1137 } else {
1138 SafeHide (ffp->newGeneGrp);
1139 SafeShow (ffp->editGeneBtn);
1140 }
1141 }
1142 }
1143
1144 static void ChangeSubGroup (VoidPtr data, Int2 newval, Int2 oldval)
1145
1146 {
1147 FeatureFormPtr ffp;
1148
1149 ffp = (FeatureFormPtr) data;
1150 if (ffp != NULL) {
1151 if (ffp->commonPage >= 0 && ffp->commonPage <= 6) {
1152 SafeHide (ffp->commonSubGrp [ffp->commonPage]);
1153 }
1154 ffp->commonPage = newval;
1155 if (ffp->commonPage >= 0 && ffp->commonPage <= 6) {
1156 SafeShow (ffp->commonSubGrp [ffp->commonPage]);
1157 }
1158 }
1159 }
1160
1161 typedef struct fieldpage {
1162 DIALOG_MESSAGE_BLOCK
1163 Int2 numfields;
1164 CharPtr PNTR fields;
1165 TexT PNTR values;
1166 ButtoN PNTR boxes;
1167 } FieldPage, PNTR FieldPagePtr;
1168
1169
1170 static Boolean ShouldSuppressGBQual(Uint1 subtype, CharPtr qual_name)
1171 {
1172 if (StringHasNoText (qual_name)) {
1173 return FALSE;
1174 }
1175
1176 /* always suppress experiment and inference quals */
1177 if (StringCmp (qual_name, "experiment") == 0 || StringCmp (qual_name, "inference") == 0) {
1178 return TRUE;
1179 }
1180
1181 if (subtype == FEATDEF_ncRNA) {
1182 if (StringCmp (qual_name, "product") == 0
1183 || StringCmp (qual_name, "ncRNA_class") == 0) {
1184 return TRUE;
1185 }
1186 } else if (subtype == FEATDEF_tmRNA) {
1187 if (StringCmp (qual_name, "product") == 0
1188 || StringCmp (qual_name, "tag_peptide") == 0) {
1189 return TRUE;
1190 }
1191 } else if (subtype == FEATDEF_otherRNA) {
1192 if (StringCmp (qual_name, "product") == 0) {
1193 return TRUE;
1194 }
1195 }
1196 return FALSE;
1197 }
1198
1199
1200 static Boolean ShouldBeAGBQual (Uint1 subtype, Int2 qual, Boolean allowProductGBQual)
1201
1202 {
1203 if (qual < 0) return FALSE;
1204 if (allowProductGBQual && qual == GBQUAL_product) return TRUE;
1205 if (qual == GBQUAL_citation ||
1206 qual == GBQUAL_db_xref ||
1207 qual == GBQUAL_evidence ||
1208 qual == GBQUAL_exception ||
1209 qual == GBQUAL_gene ||
1210 qual == GBQUAL_gene_synonym ||
1211 qual == GBQUAL_insertion_seq ||
1212 qual == GBQUAL_label ||
1213 qual == GBQUAL_locus_tag ||
1214 qual == GBQUAL_note ||
1215 qual == GBQUAL_partial ||
1216 qual == GBQUAL_product ||
1217 qual == GBQUAL_pseudo ||
1218 qual == GBQUAL_rpt_unit ||
1219 qual == GBQUAL_transposon ||
1220 qual == GBQUAL_experiment ||
1221 qual == GBQUAL_trans_splicing ||
1222 qual == GBQUAL_ribosomal_slippage ||
1223 qual == GBQUAL_inference) {
1224 return FALSE;
1225 }
1226 if (qual == GBQUAL_map && subtype != FEATDEF_ANY && subtype != FEATDEF_repeat_region && subtype != FEATDEF_gap) return FALSE;
1227 if (qual == GBQUAL_operon && subtype != FEATDEF_ANY && subtype != FEATDEF_operon) return FALSE;
1228 if (Nlm_GetAppProperty ("SequinUseEMBLFeatures") == NULL) {
1229 if (qual == GBQUAL_usedin) {
1230 return FALSE;
1231 }
1232 }
1233
1234 if (qual > -1 && ShouldSuppressGBQual (subtype, ParFlat_GBQual_names [qual].name)) {
1235 return FALSE;
1236 }
1237
1238 return TRUE;
1239 }
1240
1241 static CharPtr TrimCommasAndAtSignsAroundGBString (CharPtr str)
1242
1243 {
1244 Uchar ch; /* to use 8bit characters in multibyte languages */
1245 CharPtr dst;
1246 CharPtr ptr;
1247
1248 if (str != NULL && str [0] != '\0') {
1249 dst = str;
1250 ptr = str;
1251 ch = *ptr;
1252 while (ch != '\0' && (ch < ' ' || ch == '{' || ch == ',')) {
1253 ptr++;
1254 ch = *ptr;
1255 }
1256 while (ch != '\0') {
1257 *dst = ch;
1258 dst++;
1259 ptr++;
1260 ch = *ptr;
1261 }
1262 *dst = '\0';
1263 dst = NULL;
1264 ptr = str;
1265 ch = *ptr;
1266 while (ch != '\0') {
1267 if (ch != '}' && ch != ',') {
1268 dst = NULL;
1269 } else if (dst == NULL) {
1270 dst = ptr;
1271 }
1272 ptr++;
1273 ch = *ptr;
1274 }
1275 if (dst != NULL) {
1276 *dst = '\0';
1277 }
1278 }
1279 return str;
1280 }
1281
1282 static CharPtr CombineSplitGBQual (CharPtr origval, CharPtr newval)
1283
1284 {
1285 size_t len;
1286 CharPtr str = NULL;
1287
1288 if (StringStr (origval, newval) != NULL) return origval;
1289 len = StringLen (origval) + StringLen (newval) + 5;
1290 str = MemNew (sizeof (Char) * len);
1291 if (str == NULL) return origval;
1292 TrimCommasAndAtSignsAroundGBString (origval);
1293 TrimCommasAndAtSignsAroundGBString (newval);
1294 StringCpy (str, "{");
1295 StringCat (str, origval);
1296 StringCat (str, ",");
1297 StringCat (str, newval);
1298 StringCat (str, "}");
1299 /* free original string, knowing return value will replace it */
1300 MemFree (origval);
1301 return str;
1302 }
1303
1304 static void CombineTitle (TexT t, CharPtr val)
1305
1306 {
1307 CharPtr str;
1308
1309 if (t == NULL || StringHasNoText (val)) return;
1310 str = SaveStringFromText (t);
1311 if (StringDoesHaveText (str)) {
1312 str = CombineSplitGBQual (str, val);
1313 SetTitle (t, str);
1314 } else {
1315 SetTitle (t, val);
1316 }
1317 MemFree (str);
1318 }
1319
1320 static void GBQualPtrToFieldPage (DialoG d, Pointer data)
1321
1322 {
1323 Char empty [4];
1324 FieldPagePtr fpf;
1325 Int2 i;
1326 GBQualPtr list;
1327
1328 fpf = (FieldPagePtr) GetObjectExtra (d);
1329 list = (GBQualPtr) data;
1330 if (fpf != NULL) {
1331 while (list != NULL) {
1332 if (list->qual != NULL && list->val != NULL) {
1333 for (i = 0; i < fpf->numfields; i++) {
1334 if (StringICmp (list->qual, fpf->fields [i]) == 0) {
1335 if (fpf->values [i] != NULL) {
1336 if (*(list->val) == '\0') {
1337 empty [0] = '"';
1338 empty [1] = '"';
1339 empty [2] = '\0';
1340 SetTitle (fpf->values [i], empty);
1341 } else if (StringICmp (list->qual, "rpt_type") == 0 ||
1342 StringICmp (list->qual, "rpt_unit") == 0 ||
1343 StringICmp (list->qual, "rpt_unit_range") == 0 ||
1344 StringICmp (list->qual, "rpt_unit_seq") == 0 ||
1345 StringICmp (list->qual, "replace") == 0 ||
1346 StringICmp (list->qual, "compare") == 0 ||
1347 StringICmp (list->qual, "old_locus_tag") == 0 ||
1348 StringICmp (list->qual, "usedin") == 0) {
1349 CombineTitle (fpf->values [i], list->val);
1350 } else {
1351 SetTitle (fpf->values [i], list->val);
1352 }
1353 } else if (fpf->boxes [i] != NULL) {
1354 SetStatus (fpf->boxes [i], TRUE);
1355 }
1356 }
1357 }
1358 }
1359 list = list->next;
1360 }
1361 }
1362 }
1363
1364 extern void SeqFeatPtrToFieldPage (DialoG d, SeqFeatPtr sfp);
1365 extern void SeqFeatPtrToFieldPage (DialoG d, SeqFeatPtr sfp)
1366
1367 {
1368 /*
1369 FieldPagePtr fpf;
1370 Int2 i;
1371
1372 fpf = (FieldPagePtr) GetObjectExtra (d);
1373 if (fpf != NULL && sfp != NULL) {
1374 for (i = 0; i < fpf->numfields; i++) {
1375 if (StringICmp ("exception", fpf->fields [i]) == 0) {
1376 if (fpf->values [i] != NULL) {
1377 if (sfp->except_text == NULL || *(sfp->except_text) == '\0') {
1378 SetTitle (fpf->values [i], "");
1379 } else {
1380 SetTitle (fpf->values [i], sfp->except_text);
1381 }
1382 }
1383 } else if (StringICmp ("pseudo", fpf->fields [i]) == 0) {
1384 if (fpf->boxes [i] != NULL && (! GetStatus (fpf->boxes [i]))) {
1385 SetStatus (fpf->boxes [i], sfp->pseudo);
1386 }
1387 }
1388 }
1389 }
1390 */
1391
1392 }
1393
1394 static Pointer FieldPageToGBQualPtr (DialoG d)
1395
1396 {
1397 FieldPagePtr fpf;
1398 GBQualPtr gbq;
1399 GBQualPtr gbqlast;
1400 GBQualPtr head;
1401 Int2 i;
1402
1403 head = NULL;
1404 fpf = (FieldPagePtr) GetObjectExtra (d);
1405 if (fpf != NULL) {
1406 gbq = NULL;
1407 gbqlast = NULL;
1408 for (i = 0; i < fpf->numfields; i++) {
1409 if (fpf->fields [i] == NULL ||
1410 StringHasNoText (fpf->fields [i]) ||
1411 (fpf->values [i] == NULL && fpf->boxes [i] ==NULL) ||
1412 (fpf->values [i] != NULL && TextHasNoText (fpf->values [i]))) {
1413 } else if (fpf->boxes [i] != NULL && (! GetStatus (fpf->boxes [i]))) {
1414 } else {
1415 gbq = GBQualNew ();
1416 if (gbqlast == NULL) {
1417 head = gbq;
1418 } else {
1419 gbqlast->next = gbq;
1420 }
1421 gbqlast = gbq;
1422 if (gbq != NULL) {
1423 gbq->qual = StringSave (fpf->fields [i]);
1424 if (fpf->values [i] != NULL) {
1425 gbq->val = SaveStringFromText (fpf->values [i]);
1426 } else {
1427 gbq->val = StringSave ("");
1428 }
1429 }
1430 }
1431 }
1432 }
1433 return (Pointer) head;
1434 }
1435
1436 static void CleanupFieldsPage (GraphiC g, VoidPtr data)
1437
1438 {
1439 FieldPagePtr fpf;
1440 Int2 i;
1441
1442 fpf = (FieldPagePtr) data;
1443 if (fpf != NULL) {
1444 if (fpf->fields != NULL) {
1445 for (i = 0; i < fpf->numfields; i++) {
1446 MemFree (fpf->fields [i]);
1447 }
1448 }
1449 MemFree (fpf->fields);
1450 MemFree (fpf->values);
1451 MemFree (fpf->boxes);
1452 }
1453 MemFree (data);
1454 }
1455
1456 #define LEGAL_FEATURE 1
1457 #define ILLEGAL_FEATURE 2
1458
1459 extern DialoG CreateImportFields (GrouP h, CharPtr name, SeqFeatPtr sfp, Boolean allowProductGBQual)
1460
1461 {
1462 FieldPagePtr fpf;
1463 GrouP g;
1464 GBQualPtr gbq;
1465 Boolean hasillegal;
1466 Int2 i;
1467 ImpFeatPtr imp;
1468 Int2 index;
1469 Boolean is_gap = FALSE;
1470 Int2 j;
1471 Int2 max;
1472 Int2 num;
1473 GrouP p;
1474 PrompT ppt;
1475 Int2 qual;
1476 Int2 seen [ParFlat_TOTAL_GBQUAL];
1477 SematicFeatPtr sefp;
1478 Char str [64];
1479 Int2 wid;
1480
1481 p = HiddenGroup (h, 1, 0, NULL);
1482 fpf = (FieldPagePtr) MemNew (sizeof (FieldPage));
1483 if (fpf != NULL) {
1484
1485 SetObjectExtra (p, fpf, CleanupFieldsPage);
1486 fpf->dialog = (DialoG) p;
1487 fpf->todialog = GBQualPtrToFieldPage;
1488 fpf->fromdialog = FieldPageToGBQualPtr;
1489 fpf->testdialog = NULL;
1490
1491 if (sfp != NULL && sfp->data.choice == SEQFEAT_IMP) {
1492 imp = (ImpFeatPtr) sfp->data.value.ptrvalue;
1493 if (imp != NULL && StringICmp (imp->key, "gap") == 0) {
1494 is_gap = TRUE;
1495 }
1496 }
1497
1498 gbq = NULL;
1499 if (sfp != NULL) {
1500 gbq = sfp->qual;
1501 }
1502
1503 j = 0;
1504 hasillegal = FALSE;
1505 for (i = 0; i < ParFlat_TOTAL_GBQUAL; i++) {
1506 seen [i] = 0;
1507 }
1508 num = 0;
1509
1510 if (name != NULL) {
1511 index = GBFeatKeyNameValid (&name, FALSE);
1512 if (index >= 0) {
1513
1514 sefp = &(ParFlat_GBFeat [index]);
1515
1516 for (i = 0; i < sefp->mand_num; i++) {
1517 qual = sefp->mand_qual [i];
1518 if (qual > -1 && ShouldBeAGBQual (sfp == NULL ? FEATDEF_ANY : sfp->idx.subtype, qual, allowProductGBQual)) {
1519 seen [qual] = LEGAL_FEATURE;
1520 }
1521 }
1522 if (StringCmp (name, "repeat_region") == 0) {
1523 seen [GBQUAL_map] = TRUE;
1524 }
1525 if (StringCmp (name, "operon") == 0) {
1526 seen [GBQUAL_operon] = TRUE;
1527 }
1528 for (i = 0; i < sefp->opt_num; i++) {
1529 qual = sefp->opt_qual [i];
1530 if (qual > -1 && ShouldBeAGBQual (sfp == NULL ? FEATDEF_ANY : sfp->idx.subtype, qual, allowProductGBQual)) {
1531 seen [qual] = LEGAL_FEATURE;
1532 }
1533 }
1534 }
1535 } else if (sfp != NULL && sfp->data.choice == SEQFEAT_CDREGION) {
1536 /*
1537 seen [GBQUAL_exception] = LEGAL_FEATURE;
1538 seen [GBQUAL_pseudo] = LEGAL_FEATURE;
1539 */
1540 }
1541
1542 while (gbq != NULL) {
1543 qual = GBQualNameValid (gbq->qual);
1544 if (qual > -1) {
1545 if (seen [qual] == 0 && qual != GBQUAL_experiment && qual != GBQUAL_inference) {
1546 seen [qual] = ILLEGAL_FEATURE;
1547 hasillegal = TRUE;
1548 }
1549 }
1550 gbq = gbq->next;
1551 }
1552
1553 SelectFont (programFont);
1554 max = 0;
1555 for (i = 0; i < ParFlat_TOTAL_GBQUAL; i++) {
1556 if (seen [i] > 0) {
1557 num++;
1558 if (seen [i] == LEGAL_FEATURE) {
1559 StringNCpy_0 (str, ParFlat_GBQual_names [i].name, sizeof (str));
1560 wid = StringWidth (str) + 2;
1561 } else {
1562 str [0] = '\0';
1563 if (name != NULL) {
1564 StringCpy (str, "*");
1565 }
1566 StringNCat (str, ParFlat_GBQual_names [i].name, sizeof (str) - 2);
1567 wid = StringWidth (str) + 2;
1568 }
1569 if (wid > max) {
1570 max = wid;
1571 }
1572 }
1573 }
1574 SelectFont (systemFont);
1575
1576 fpf->numfields = num;
1577 fpf->fields = MemNew (sizeof (CharPtr) * (num + 1));
1578 fpf->values = MemNew (sizeof (TexT) * (num + 1));
1579 fpf->boxes = MemNew (sizeof (ButtoN) * (num + 1));
1580
1581 g = HiddenGroup (p, 2, 0, NULL);
1582 j = 0;
1583 for (i = 0; i < ParFlat_TOTAL_GBQUAL; i++) {
1584 if (seen [i] == LEGAL_FEATURE) {
1585 fpf->fields [j] = StringSave (ParFlat_GBQual_names [i].name);
1586 ppt = StaticPrompt (g, fpf->fields [j], max, dialogTextHeight, programFont, 'l');
1587 if (ParFlat_GBQual_names [i].gbclass != Class_none) {
1588 fpf->values [j] = DialogText (g, "", 20, NULL);
1589 /*
1590 if (i == GBQUAL_estimated_length && is_gap) {
1591 Disable (fpf->values [j]);
1592 }
1593 */
1594 } else {
1595 fpf->boxes [j] = CheckBox (g, "", NULL);
1596 AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) fpf->boxes [j], NULL);
1597 }
1598 j++;
1599 }
1600 }
1601 if (hasillegal && name != NULL) {
1602 StaticPrompt (p, "Illegal Qualifiers", 0, 0, programFont, 'c');
1603 }
1604 g = HiddenGroup (p, 2, 0, NULL);
1605 for (i = 0; i < ParFlat_TOTAL_GBQUAL; i++) {
1606 if (seen [i] == ILLEGAL_FEATURE) {
1607 fpf->fields [j] = StringSave (ParFlat_GBQual_names [i].name);
1608 str [0] = '\0';
1609 if (name != NULL) {
1610 StringCpy (str, "*");
1611 }
1612 StringNCat (str, fpf->fields [j], sizeof (str) - 2);
1613 ppt = StaticPrompt (g, str, max, dialogTextHeight, programFont, 'l');
1614 if (ParFlat_GBQual_names [i].gbclass != Class_none) {
1615 fpf->values [j] = DialogText (g, "", 20, NULL);
1616 } else {
1617 fpf->boxes [j] = CheckBox (g, "", NULL);
1618 AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) fpf->boxes [j], NULL);
1619 }
1620 j++;
1621 }
1622 }
1623
1624 if (j == 0) {
1625 StaticPrompt (p, "See Attributes page to set legal qualifiers for this feature.",
1626 0, 0, programFont, 'c');
1627 }
1628 }
1629 return (DialoG) p;
1630 }
1631
1632 static void ChangeCannedMessage (PopuP p)
1633
1634 {
1635 FeatureFormPtr ffp;
1636 Int2 val;
1637
1638 ffp = (FeatureFormPtr) GetObjectExtra (p);
1639 if (ffp == NULL) return;
1640 val = GetValue (p);
1641 switch (val) {
1642 case 1 :
1643 if (Message (MSG_YN, "Clear the explanation field?") == ANS_YES) {
1644 SetTitle (ffp->exceptText, "");
1645 if (Message (MSG_YN, "Clear the exception flag?") == ANS_YES) {
1646 SetStatus (ffp->exception, FALSE);
1647 }
1648 }
1649 break;
1650 case 2 :
1651 SetTitle (ffp->exceptText, "RNA editing");
1652 SetStatus (ffp->exception, TRUE);
1653 break;
1654 case 3 :
1655 SetTitle (ffp->exceptText, "reasons given in citation");
1656 SetStatus (ffp->exception, TRUE);
1657 break;
1658 case 4 :
1659 SetTitle (ffp->exceptText, "ribosomal slippage");
1660 SetStatus (ffp->exception, TRUE);
1661 break;
1662 case 5 :
1663 SetTitle (ffp->exceptText, "trans-splicing");
1664 SetStatus (ffp->exception, TRUE);
1665 break;
1666 case 6 :
1667 SetTitle (ffp->exceptText, "artificial frameshift");
1668 SetStatus (ffp->exception, TRUE);
1669 break;
1670 case 7 :
1671 SetTitle (ffp->exceptText, "nonconsensus splice site");
1672 SetStatus (ffp->exception, TRUE);
1673 break;
1674 case 8 :
1675 SetTitle (ffp->exceptText, "rearrangement required for product");
1676 SetStatus (ffp->exception, TRUE);
1677 break;
1678 case 9 :
1679 SetTitle (ffp->exceptText, "alternative start codon");
1680 SetStatus (ffp->exception, TRUE);
1681 break;
1682 case 10 :
1683 SetTitle (ffp->exceptText, "annotated by transcript or proteomic data");
1684 SetStatus (ffp->exception, TRUE);
1685 break;
1686 case 11 :
1687 SetTitle (ffp->exceptText, "heterogeneous population sequenced");
1688 SetStatus (ffp->exception, TRUE);
1689 break;
1690 case 12 :
1691 SetTitle (ffp->exceptText, "low-quality sequence region");
1692 SetStatus (ffp->exception, TRUE);
1693 break;
1694 case 13 :
1695 SetTitle (ffp->exceptText, "unextendable partial coding region");
1696 SetStatus (ffp->exception, TRUE);
1697 break;
1698 default :
1699 break;
1700 }
1701 }
1702
1703 static CharPtr crossRefWarn =
1704 "A gene mapped by cross-reference does not extend the range\n\
1705 of the indicated gene feature. Overlap is the usual case, and\n\
1706 it does extend the selected gene.";
1707
1708 static CharPtr suppressWarn =
1709 "This will suppress display of a gene qualifier even though\n\
1710 there is a gene feature that overlaps this one.";
1711
1712 static void GeneXrefWarn (GrouP g)
1713
1714 {
1715 Int2 val;
1716 Boolean indexerVersion;
1717
1718 indexerVersion = (Boolean) (GetAppProperty ("InternalNcbiSequin") != NULL);
1719 if (indexerVersion) return;
1720
1721 val = GetValue (g);
1722 if (val == 2) {
1723 Message (MSG_OK, "%s", crossRefWarn);
1724 } else if (val == 3) {
1725 Message (MSG_OK, "%s", suppressWarn);
1726 }
1727 }
1728
1729 static CharPtr commonRadioFormTabs [] = {
1730 "General", "Comment", "Citations", "Cross-Refs", "Evidence", "Identifiers", NULL, NULL
1731 };
1732
1733 static CharPtr commonNoCitFormTabs [] = {
1734 "General", "Comment", "Cross-Refs", "Evidence", "Identifiers", NULL, NULL
1735 };
1736
1737 static DialoG NewCreateInferenceDialog (GrouP prnt);
1738 extern void Nlm_LaunchGeneFeatEd (ButtoN b);
1739
1740
1741 static CharPtr GetNameForFeature (SeqFeatPtr sfp)
1742 {
1743 FeatDefPtr curr;
1744 Uint1 key;
1745 CharPtr label = NULL;
1746 CharPtr featname = NULL;
1747 CharPtr ptr;
1748 Char ch;
1749
1750 if (sfp != NULL) {
1751 curr = FeatDefFindNext (NULL, &key, &label, sfp->idx.subtype, TRUE);
1752 if (curr != NULL) {
1753 featname = StringSave (label);
1754 ptr = featname;
1755 ch = *ptr;
1756 while (ch != '\0') {
1757 if (IS_UPPER (ch)) {
1758 *ptr = TO_LOWER (ch);
1759 }
1760 ptr++;
1761 ch = *ptr;
1762 }
1763 }
1764 }
1765 return featname;
1766 }
1767
1768
1769 extern GrouP CreateCommonFeatureGroupEx (GrouP h, FeatureFormPtr ffp,
1770 SeqFeatPtr sfp, Boolean hasGeneControl,
1771 Boolean hasCitationTab, Boolean hasGeneSuppress)
1772
1773 {
1774 ButtoN b;
1775 GrouP c;
1776 PopuP canned;
1777 Boolean cdsQuals;
1778 GrouP f;
1779 GrouP g;
1780 GBQualPtr gbq;
1781 Boolean hasQuals;
1782 Boolean indexerVersion;
1783 Char just;
1784 GrouP k;
1785 GrouP m;
1786 GrouP p;
1787 Int2 page;
1788 PrompT ppt1, ppt2;
1789 ButtoN pseudo = NULL;
1790 GrouP q;
1791 GrouP r;
1792 GrouP t;
1793 GrouP v;
1794 GrouP x;
1795 GrouP y;
1796 CharPtr featname;
1797
1798 c = NULL;
1799 if (ffp != NULL) {
1800 hasQuals = FALSE;
1801 cdsQuals = FALSE;
1802 if (ffp->gbquals == NULL && sfp != NULL && sfp->qual != NULL) {
1803 for (gbq = sfp->qual; gbq != NULL && !hasQuals; gbq = gbq->next) {
1804 if (!ShouldSuppressGBQual(sfp->idx.subtype, gbq->qual)) {
1805 hasQuals = TRUE;
1806 }
1807 }
1808 /*
1809 if (GetAppProperty ("InternalNcbiSequin") != NULL) {
1810 if (sfp->data.choice == SEQFEAT_CDREGION) {
1811 cdsQuals = TRUE;
1812 }
1813 }
1814 */
1815 }
1816 m = HiddenGroup (h, -1, 0, NULL);
1817 SetGroupSpacing (m, 10, 10);
1818 ffp->commonPage = 0;
1819 if (cdsQuals) {
1820 } else if (hasQuals) {
1821 commonRadioFormTabs [6] = "Qualifiers";
1822 commonNoCitFormTabs [5] = "Qualifiers";
1823 }
1824 if (hasCitationTab) {
1825 ffp->commonRadio = CreateFolderTabs (m, commonRadioFormTabs, ffp->commonPage,
1826 0, 0, PROGRAM_FOLDER_TAB,
1827 ChangeSubGroup, (Pointer) ffp);
1828 } else {
1829 ffp->commonRadio = CreateFolderTabs (m, commonNoCitFormTabs, ffp->commonPage,
1830 0, 0, PROGRAM_FOLDER_TAB,
1831 ChangeSubGroup, (Pointer) ffp);
1832 }
1833 commonRadioFormTabs [6] = NULL;
1834 commonNoCitFormTabs [5] = NULL;
1835
1836 p = HiddenGroup (m, 0, 0, NULL);
1837
1838 c = HiddenGroup (p, -1, 0, NULL);
1839 SetGroupSpacing (c, 10, 10);
1840 f = HiddenGroup (c, -1, 0, NULL);
1841 r = HiddenGroup (f, 7, 0, NULL);
1842 StaticPrompt (r, "Flags", 0, popupMenuHeight, programFont, 'l');
1843 ffp->partial = CheckBox (r, "Partial", NULL);
1844 indexerVersion = (Boolean) (GetAppProperty ("InternalNcbiSequin") != NULL);
1845 if (! indexerVersion) {
1846 Disable (ffp->partial);
1847 }
1848 if (ffp->pseudo == NULL) {
1849 ffp->pseudo = CheckBox (r, "Pseudo", NULL);
1850 pseudo = ffp->pseudo; /* allows pseudo control on earlier feature-specific page */
1851 }
1852 if (indexerVersion) {
1853 StaticPrompt (r, "Evidence", 0, popupMenuHeight, programFont, 'l');
1854 ffp->evidence = PopupList (r, TRUE, NULL);
1855 PopupItem (ffp->evidence, " ");
1856 PopupItem (ffp->evidence, "Experimental");
1857 PopupItem (ffp->evidence, "Non-Experimental");
1858 }
1859 AlignObjects (ALIGN_MIDDLE, (HANDLE) ffp->partial,
1860 (HANDLE) pseudo, (HANDLE) ffp->evidence, NULL);
1861 r = HiddenGroup (f, -3, 0, NULL);
1862 ffp->exception = CheckBox (r, "Exception", NULL);
1863 StaticPrompt (r, "Explanation", 0, dialogTextHeight, programFont, 'l');
1864 ffp->exceptText = DialogText (r, "", 12, NULL);
1865 AlignObjects (ALIGN_MIDDLE, (HANDLE) ffp->exception,
1866 (HANDLE) ffp->exceptText, NULL);
1867 if (ffp->this_subtype == FEATDEF_CDS) {
1868 StaticPrompt (r, "Standard explanation", 0, popupMenuHeight, programFont, 'l');
1869 canned = PopupList (r, TRUE, ChangeCannedMessage);
1870 SetObjectExtra (canned, (Pointer) ffp, NULL);
1871 PopupItem (canned, " ");
1872 PopupItem (canned, "RNA editing");
1873 PopupItem (canned, "reasons given in citation");
1874 PopupItem (canned, "ribosomal slippage");
1875 PopupItem (canned, "trans-splicing");
1876 PopupItem (canned, "artificial frameshift");
1877 PopupItem (canned, "nonconsensus splice site");
1878 PopupItem (canned, "rearrangement required");
1879 PopupItem (canned, "alternative start codon");
1880 PopupItem (canned, "transcript or proteome data");
1881 PopupItem (canned, "heterogeneous population");
1882 PopupItem (canned, "low-quality sequence region");
1883 PopupItem (canned, "unextendable partial CDS");
1884 if (sfp != NULL && sfp->excpt) {
1885 if (StringICmp (sfp->except_text, "RNA editing") == 0) {
1886 SetValue (canned, 2);
1887 } else if (StringICmp (sfp->except_text, "reasons given in citation") == 0 ||
1888 StringICmp (sfp->except_text, "reasons cited in publication") == 0) {
1889 SetValue (canned, 3);
1890 } else if (StringICmp (sfp->except_text, "ribosomal slippage") == 0 ||
1891 StringICmp (sfp->except_text, "ribosome slippage") == 0) {
1892 SetValue (canned, 4);
1893 } else if (StringICmp (sfp->except_text, "trans-splicing") == 0 ||
1894 StringICmp (sfp->except_text, "trans splicing") == 0) {
1895 SetValue (canned, 5);
1896 } else if (StringICmp (sfp->except_text, "artificial frameshift") == 0) {
1897 SetValue (canned, 6);
1898 } else if (StringICmp (sfp->except_text, "non-consensus splice site") == 0 ||
1899 StringICmp (sfp->except_text, "nonconsensus splice site") == 0) {
1900 SetValue (canned, 7);
1901 } else if (StringICmp (sfp->except_text, "rearrangement required for product") == 0) {
1902 SetValue (canned, 8);
1903 } else if (StringICmp (sfp->except_text, "alternative start codon") == 0) {
1904 SetValue (canned, 9);
1905 } else if (StringICmp (sfp->except_text, "annotated by transcript or proteomic data") == 0) {
1906 SetValue (canned, 10);
1907 } else if (StringICmp (sfp->except_text, "heterogeneous population sequenced") == 0) {
1908 SetValue (canned, 11);
1909 } else if (StringICmp (sfp->except_text, "low-quality sequence region") == 0) {
1910 SetValue (canned, 12);
1911 } else if (StringICmp (sfp->except_text, "unextendable partial coding region") == 0) {
1912 SetValue (canned, 13);
1913 }
1914 } else {
1915 SetValue (canned, 1);
1916 }
1917 }
1918
1919 if (cdsQuals) {
1920 /*
1921 ffp->gbquals = CreateImportFields (c, NULL, sfp, FALSE);
1922 */
1923 }
1924
1925 g = NULL;
1926 k = NULL;
1927 ffp->gene = NULL;
1928 ffp->genePopup = NULL;
1929 ffp->geneList = NULL;
1930 ffp->geneNames = NULL;
1931 ffp->useGeneXref = NULL;
1932 ffp->newGeneGrp = NULL;
1933 ffp->geneSymbol = NULL;
1934 ffp->geneAllele = NULL;
1935 ffp->geneDesc = NULL;
1936 ffp->locusTag = NULL;
1937 ffp->geneSynonym = NULL;
1938 for (page = 0; page < 8; page++) {
1939 ffp->commonSubGrp [page] = NULL;
1940 }
1941 page = 0;
1942
1943 if (hasGeneControl) {
1944 g = HiddenGroup (c, -2, 0, NULL);
1945 StaticPrompt (g, "Gene", 0, popupMenuHeight, programFont, 'l');
1946 v = HiddenGroup (g, 0, 0, NULL);
1947 ffp->genePopup = PopupList (v, TRUE, (PupActnProc) ChangeGenePopupOrList);
1948 SetObjectExtra (ffp->genePopup, (Pointer) ffp, NULL);
1949 PopupItem (ffp->genePopup, " ");
1950 PopupItem (ffp->genePopup, "New:");
1951 SetValue (ffp->genePopup, 1);
1952 Hide (ffp->genePopup);
1953 ffp->geneList = SingleList (v, 6, 3, (LstActnProc) ChangeGenePopupOrList);
1954 SetObjectExtra (ffp->geneList, (Pointer) ffp, NULL);
1955 ListItem (ffp->geneList, " ");
1956 ListItem (ffp->geneList, "New:");
1957 SetValue (ffp->geneList, 1);
1958 Hide (ffp->geneList);
1959 k = HiddenGroup (c, 3, 0, NULL);
1960 StaticPrompt (k, "Map by", 0, stdLineHeight, programFont, 'l');
1961 ffp->useGeneXref = HiddenGroup (k, 3, 0, GeneXrefWarn);
1962 SetObjectExtra (ffp->useGeneXref, ffp, NULL);
1963 RadioButton (ffp->useGeneXref, "Overlap");
1964 RadioButton (ffp->useGeneXref, "Cross-reference");
1965 RadioButton (ffp->useGeneXref, "Suppress");
1966 SetValue (ffp->useGeneXref, 1);
1967 y = HiddenGroup (c, 0, 0, NULL);
1968 ffp->newGeneGrp = HiddenGroup (y, 2, 0, NULL);
1969 StaticPrompt (ffp->newGeneGrp, "Gene Symbol", 0, dialogTextHeight, programFont, 'l');
1970 ffp->geneSymbol = DialogText (ffp->newGeneGrp, "", 20, NULL);
1971 StaticPrompt (ffp->newGeneGrp, "Allele", 0, dialogTextHeight, programFont, 'l');
1972 ffp->geneAllele = DialogText (ffp->newGeneGrp, "", 20, NULL);
1973 StaticPrompt (ffp->newGeneGrp, "Description", 0, dialogTextHeight, programFont, 'l');
1974 ffp->geneDesc = DialogText (ffp->newGeneGrp, "", 20, NULL);
1975 StaticPrompt (ffp->newGeneGrp, "Locus Tag", 0, dialogTextHeight, programFont, 'l');
1976 ffp->locusTag = DialogText (ffp->newGeneGrp, "", 20, NULL);
1977 StaticPrompt (ffp->newGeneGrp, "Synonym", 0, dialogTextHeight, programFont, 'l');
1978 ffp->geneSynonym = DialogText (ffp->newGeneGrp, "", 20, NULL);
1979 Hide (ffp->newGeneGrp);
1980 ffp->editGeneBtn = PushButton (y, "Edit Gene Feature", Nlm_LaunchGeneFeatEd);
1981 SetObjectExtra (ffp->editGeneBtn, ffp, NULL);
1982 Hide (ffp->editGeneBtn);
1983 } else if (hasGeneSuppress) {
1984 k = HiddenGroup (c, 3, 0, NULL);
1985 StaticPrompt (k, "Map by", 0, stdLineHeight, programFont, 'l');
1986 ffp->useGeneXref = HiddenGroup (k, 3, 0, GeneXrefWarn);
1987 SetObjectExtra (ffp->useGeneXref, ffp, NULL);
1988 RadioButton (ffp->useGeneXref, "Overlap");
1989 b = RadioButton (ffp->useGeneXref, "Cross-reference");
1990 Disable (b);
1991 RadioButton (ffp->useGeneXref, "Suppress");
1992 SetValue (ffp->useGeneXref, 1);
1993 y = HiddenGroup (c, 0, 0, NULL);
1994 }
1995 ffp->commonSubGrp [page] = c;
1996 page++;
1997 AlignObjects (ALIGN_CENTER, (HANDLE) f, (HANDLE) g,
1998 (HANDLE) k, (HANDLE) ffp->newGeneGrp,
1999 (HANDLE) ffp->editGeneBtn, NULL);
2000
2001 c = HiddenGroup (p, -1, 0, NULL);
2002 SetGroupSpacing (c, 10, 10);
2003 q = HiddenGroup (c, 0, 2, NULL);
2004 StaticPrompt (q, "Comment", 25 * stdCharWidth, 0, programFont, 'c');
2005 if (GetAppProperty ("InternalNcbiSequin") != NULL) {
2006 ffp->comment = ScrollText (q, 25, 10, programFont, TRUE, NULL);
2007 } else {
2008 ffp->comment = ScrollText (q, 25, 5, programFont, TRUE, NULL);
2009 }
2010 ffp->commonSubGrp [page] = c;
2011 Hide (ffp->commonSubGrp [page]);
2012 page++;
2013
2014 if (hasCitationTab) {
2015 c = HiddenGroup (p, -1, 0, NULL);
2016 SetGroupSpacing (c, 10, 10);
2017 ffp->featcits = CreateCitOnFeatDialog (c, NULL);
2018 b = PushButton (c, "Edit Citations", EditFeatCitsProc);
2019 SetObjectExtra (b, ffp, NULL);
2020 ffp->commonSubGrp [page] = c;
2021 AlignObjects (ALIGN_CENTER, (HANDLE) ffp->featcits, (HANDLE) b, NULL);
2022 Hide (ffp->commonSubGrp [page]);
2023 page++;
2024 }
2025
2026 c = HiddenGroup (p, -1, 0, NULL);
2027 SetGroupSpacing (c, 10, 10);
2028 if (GetAppProperty ("ReadOnlyDbTags") == NULL) {
2029 just = 'c';
2030 } else {
2031 just = 'l';
2032 StaticPrompt (c, "This page is read-only", 15 * stdCharWidth, 0, programFont, 'c');
2033 }
2034 t = HiddenGroup (c, 2, 0, NULL);
2035 StaticPrompt (t, "Database", 7 * stdCharWidth, 0, programFont, just);
2036 StaticPrompt (t, "Object ID", 8 * stdCharWidth, 0, programFont, just);
2037 ffp->dbxrefs = CreateDbtagDialog (c, 3, -1, 7, 8);
2038 ffp->commonSubGrp [page] = c;
2039 Hide (ffp->commonSubGrp [page]);
2040 page++;
2041
2042 c = HiddenGroup (p, -1, 0, NULL);
2043 SetGroupSpacing (c, 10, 10);
2044 q = HiddenGroup (c, 0, -6, NULL);
2045 ppt1 = StaticPrompt (q, "Experiment", 0, 0, programFont, 'c');
2046 ffp->experiment = CreateVisibleStringDialog (q, 3, -1, 15);
2047 ppt2 = StaticPrompt (q, "Inference", 0, 0, programFont, 'c');
2048 /*
2049 ffp->inference = CreateInferenceDialog (q, 3, 2, 15);
2050 */
2051 ffp->inference = NewCreateInferenceDialog (q);
2052 AlignObjects (ALIGN_CENTER, (HANDLE) ppt1, (HANDLE) ffp->experiment,
2053 (HANDLE) ppt2, (HANDLE) ffp->inference, NULL);
2054 ffp->commonSubGrp [page] = c;
2055 Hide (ffp->commonSubGrp [page]);
2056 page++;
2057
2058 c = HiddenGroup (p, -1, 0, NULL);
2059 SetGroupSpacing (c, 10, 10);
2060 t = HiddenGroup (c, 2, 0, NULL);
2061 SetGroupSpacing (t, 10, 30);
2062 StaticPrompt (t, "Feature ID for this feature", 0, dialogTextHeight, programFont, 'l');
2063 ffp->featid = DialogText (t, "", 8, NULL);
2064 StaticPrompt (t, "ID Xref to associated feature", 0, dialogTextHeight, programFont, 'l');
2065 ffp->fidxref = DialogText (t, "", 8, NULL);
2066 if (! indexerVersion) {
2067 Disable (ffp->featid);
2068 Disable (ffp->fidxref);
2069 }
2070 ffp->commonSubGrp [page] = c;
2071 Hide (ffp->commonSubGrp [page]);
2072 page++;
2073
2074
2075 c = HiddenGroup (p, -1, 0, NULL);
2076 SetGroupSpacing (c, 10, 10);
2077 x = NULL;
2078 if (hasQuals && ffp->gbquals == NULL) {
2079 x = HiddenGroup (c, -1, 0, NULL);
2080 featname = GetNameForFeature (sfp);
2081 ffp->gbquals = NewCreateImportFields (x, featname, sfp, FALSE);
2082 featname = MemFree (featname);
2083 }
2084 ffp->commonSubGrp [page] = c;
2085 Hide (ffp->commonSubGrp [page]);
2086 page++;
2087
2088
2089 AlignObjects (ALIGN_CENTER, (HANDLE) ffp->commonRadio, (HANDLE) ffp->commonSubGrp [0],
2090 (HANDLE) ffp->commonSubGrp [1], (HANDLE) ffp->commonSubGrp [2],
2091 (HANDLE) ffp->commonSubGrp [3], (HANDLE) ffp->commonSubGrp [4],
2092 (HANDLE) ffp->commonSubGrp [5], (HANDLE) ffp->commonSubGrp [6],
2093 (HANDLE) ffp->commonSubGrp [7], NULL);
2094 }
2095 return c;
2096 }
2097
2098 extern GrouP CreateCommonFeatureGroup (GrouP h, FeatureFormPtr ffp,
2099 SeqFeatPtr sfp, Boolean hasGeneControl,
2100 Boolean hasCitationTab)
2101
2102 {
2103 return CreateCommonFeatureGroupEx (h, ffp, sfp, hasGeneControl, hasCitationTab, FALSE);
2104 }
2105
2106 static Boolean DlgutilFindBspItem (GatherContextPtr gcp)
2107
2108 {
2109 BioseqPtr PNTR bspp;
2110
2111 bspp = (BioseqPtr PNTR) gcp->userdata;
2112 if (bspp != NULL && gcp->thistype == OBJ_BIOSEQ) {
2113 *bspp = (BioseqPtr) gcp->thisitem;
2114 }
2115 return TRUE;
2116 }
2117
2118 extern void SetNewFeatureDefaultInterval (FeatureFormPtr ffp)
2119
2120 {
2121 BioseqPtr bsp;
2122 SelStructPtr sel;
2123 SeqIntPtr sip;
2124 SeqLocPtr slp;
2125
2126 if (ffp == NULL) return;
2127 bsp = NULL;
2128 GatherItem (ffp->input_entityID, ffp->input_itemID, ffp->input_itemtype,
2129 (Pointer) (&bsp), DlgutilFindBspItem);
2130 if (bsp == NULL) return;
2131 slp = NULL;
2132 sel = ObjMgrGetSelected ();
2133 if (sel != NULL && sel->next == NULL && sel->entityID == ffp->input_entityID &&
2134 sel->itemID == ffp->input_itemID && sel->itemtype == ffp->input_itemtype) {
2135 if (sel->regiontype == 1 && sel->region != NULL) {
2136 if (GetBioseqGivenSeqLoc ((SeqLocPtr) sel->region, ffp->input_entityID) == bsp) {
2137 slp = AsnIoMemCopy (sel->region,
2138 (AsnReadFunc) SeqLocAsnRead,
2139 (AsnWriteFunc) SeqLocAsnWrite);
2140 }
2141 }
2142 }
2143 if (slp == NULL) {
2144 slp = ValNodeNew (NULL);
2145 if (slp == NULL) return;
2146 sip = SeqIntNew ();
2147 if (sip == NULL) {
2148 slp = SeqLocFree (slp);
2149 return;
2150 }
2151 slp->choice = SEQLOC_INT;
2152 slp->data.ptrvalue = (Pointer) sip;
2153 sip->from = 0;
2154 sip->to = bsp->length - 1;
2155 sip->strand = Seq_strand_plus;
2156 sip->id = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0)));
2157 }
2158 if (slp != NULL) {
2159 PointerToDialog (ffp->location, (Pointer) slp);
2160 SeqLocFree (slp);
2161 }
2162 }
2163
2164 extern Boolean FileToScrollText (TexT t, CharPtr path)
2165
2166 {
2167 FILE *fp;
2168 Int8 len;
2169 Int4 read_len;
2170 Int4 max;
2171 CharPtr str;
2172 #ifdef WIN_MAC
2173 CharPtr p;
2174 #endif
2175 #if (defined(OS_DOS) || defined (OS_NT))
2176 CharPtr p;
2177 CharPtr q;
2178 #endif
2179
2180 if (t != NULL && path != NULL && *path != '\0') {
2181 len = FileLength (path);
2182 max = (Int4) INT2_MAX;
2183 #ifdef WIN_MOTIF
2184 max = INT4_MAX;
2185 #endif
2186 #ifdef WIN_MSWIN
2187 max = INT4_MAX;
2188 #endif
2189 #ifdef WIN_MAC
2190 #ifdef OS_UNIX_DARWIN
2191 max = INT4_MAX;
2192 #endif
2193 #endif
2194 if (len > 0 && len < max - 4) {
2195 str = MemNew (sizeof (char) * ((size_t)len + 3));
2196 if (str != NULL) {
2197 fp = FileOpen (path, "r");
2198 if (fp != NULL) {
2199 read_len = FileRead (str, sizeof (char), (size_t) len, fp);
2200 str [ read_len ] = 0;
2201 #if (defined(OS_DOS) || defined (OS_NT))
2202 p = str;
2203 q = str;
2204 while (*p) {
2205 if (*p == '\r') {
2206 p++;
2207 } else {
2208 *q = *p;
2209 p++;
2210 q++;
2211 }
2212 }
2213 *q = '\0';
2214 #endif
2215 #ifdef WIN_MAC
2216 p = str;
2217 while (*p) {
2218 if (*p == '\r' || *p == '\n') {
2219 *p = '\015';
2220 }
2221 p++;
2222 }
2223 #endif
2224 FileClose (fp);
2225 SetTitle (t, str);
2226 }
2227 MemFree (str);
2228 return TRUE;
2229 }
2230 }
2231 }
2232 return FALSE;
2233 }
2234
2235 extern void ScrollTextToFile (TexT t, CharPtr path)
2236
2237 {
2238 FILE *fp;
2239 size_t len;
2240 CharPtr str;
2241 #ifdef WIN_MAC
2242 CharPtr p;
2243 #endif
2244
2245 if (t != NULL && path != NULL && *path != '\0') {
2246 len = TextLength (t);
2247 if (len > 0) {
2248 #ifdef WIN_MAC
2249 fp = FileOpen (path, "r");
2250 if (fp != NULL) {
2251 FileClose (fp);
2252 } else {
2253 FileCreate (path, "TEXT", "ttxt");
2254 }
2255 #endif
2256 fp = FileOpen (path, "w");
2257 if (fp != NULL) {
2258 str = MemNew (sizeof (char) * (len + 3));
2259 if (str != NULL) {
2260 GetTitle (t, str, len + 1);
2261 #ifdef WIN_MAC
2262 p = str;
2263 while (*p) {
2264 if (*p == '\r' || *p == '\n') {
2265 *p = '\n';
2266 }
2267 p++;
2268 }
2269 #endif
2270 FileWrite (str, sizeof (char), len, fp);
2271 MemFree (str);
2272 }
2273 FileClose (fp);
2274 }
2275 }
2276 }
2277 }
2278
2279 extern void FileToClipboard (CharPtr path)
2280
2281 {
2282 FILE *fp;
2283 Int8 len;
2284 Int4 max;
2285 CharPtr str;
2286 #ifdef WIN_MAC
2287 CharPtr p;
2288 #endif
2289 #if (defined(OS_DOS) || defined (OS_NT))
2290 CharPtr p;
2291 CharPtr q;
2292 #endif
2293
2294 if (path != NULL && *path != '\0') {
2295 len = FileLength (path);
2296 #ifdef WIN_MOTIF
2297 max = INT4_MAX;
2298 #else
2299 max = (Int4) INT2_MAX;
2300 #endif
2301 if (len > 0 && len < max - 4) {
2302 str = MemNew (sizeof (char) * ((size_t)len + 3));
2303 if (str != NULL) {
2304 fp = FileOpen (path, "r");
2305 if (fp != NULL) {
2306 FileRead (str, sizeof (char), (size_t) len, fp);
2307 #if (defined(OS_DOS) || defined (OS_NT))
2308 p = str;
2309 q = str;
2310 while (*p) {
2311 if (*p == '\r') {
2312 p++;
2313 } else {
2314 *q = *p;
2315 p++;
2316 q++;
2317 }
2318 }
2319 *q = '\0';
2320 #endif
2321 #ifdef WIN_MAC
2322 p = str;
2323 while (*p) {
2324 if (*p == '\r' || *p == '\n') {
2325 *p = '\015';
2326 }
2327 p++;
2328 }
2329 #endif
2330 FileClose (fp);
2331 Nlm_StringToClipboard (str);
2332 }
2333 MemFree (str);
2334 }
2335 }
2336 }
2337 }
2338
2339 typedef struct textviewform {
2340 FORM_MESSAGE_BLOCK
2341
2342 DoC doc;
2343 TexT text;
2344
2345 TexT find;
2346 } TextViewForm, PNTR TextViewFormPtr;
2347
2348 static ParData txtParFmt = {FALSE, FALSE, FALSE, FALSE, TRUE, 0, 0};
2349 static ColData txtColFmt = {0, 0, 80, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, TRUE};
2350
2351 static void ResizeTextViewer (WindoW w)
2352
2353 {
2354 Int2 height;
2355 RecT r;
2356 RecT s;
2357 TextViewFormPtr tfp;
2358 Int2 width;
2359
2360 tfp = (TextViewFormPtr) GetObjectExtra (w);
2361 if (tfp != NULL) {
2362 WatchCursor ();
2363 ObjectRect (w, &r);
2364 width = r.right - r.left;
2365 height = r.bottom - r.top;
2366 if (tfp->doc != NULL) {
2367 GetPosition (tfp->doc, &s);
2368 s.right = width - s.left;
2369 s.bottom = height - s.left;
2370 SetPosition (tfp->doc, &s);
2371 AdjustPrnt (tfp->doc, &s, FALSE);
2372 txtColFmt.pixWidth = screenRect.right - screenRect.left;
2373 txtColFmt.pixInset = 8;
2374 if (Visible (tfp->doc) && AllParentsVisible (tfp->doc)) {
2375 UpdateDocument (tfp->doc, 0, 0);
2376 }
2377 }
2378 if (tfp->text != NULL) {
2379 GetPosition (tfp->text, &s);
2380 s.right = width - s.left;
2381 s.bottom = height - s.left;
2382 SetPosition (tfp->text, &s);
2383 AdjustPrnt (tfp->text, &s, FALSE);
2384 }
2385 ArrowCursor ();
2386 Update ();
2387 }
2388 }
2389
2390 static Boolean ExportTextViewForm (ForM f, CharPtr filename)
2391
2392 {
2393 FILE *fp;
2394 Char path [PATH_MAX];
2395 TextViewFormPtr tfp;
2396
2397 tfp = (TextViewFormPtr) GetObjectExtra (f);
2398 if (tfp != NULL && (tfp->doc != NULL || tfp->text != NULL)) {
2399 path [0] = '\0';
2400 StringNCpy_0 (path, filename, sizeof (path));
2401 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
2402 #ifdef WIN_MAC
2403 fp = FileOpen (path, "r");
2404 if (fp != NULL) {
2405 FileClose (fp);
2406 } else {
2407 FileCreate (path, "TEXT", "ttxt");
2408 }
2409 #endif
2410 if (tfp->doc != NULL) {
2411 fp = FileOpen (path, "w");
2412 if (fp != NULL) {
2413 SaveDocument (tfp->doc, fp);
2414 FileClose (fp);
2415 return TRUE;
2416 }
2417 } else if (tfp->text != NULL) {
2418 ScrollTextToFile (tfp->text, path);
2419 return TRUE;
2420 }
2421 }
2422 }
2423 return FALSE;
2424 }
2425
2426 static void LIBCALL PrintTextViewForm (Pointer formDataPtr)
2427
2428 {
2429 TextViewFormPtr tfp;
2430
2431 tfp = (TextViewFormPtr) formDataPtr;
2432 if (tfp != NULL && tfp->doc != NULL) {
2433 PrintDocument (tfp->doc);
2434 }
2435 }
2436
2437 static void TextViewFormMessage (ForM f, Int2 mssg)
2438
2439 {
2440 TextViewFormPtr tfp;
2441
2442 tfp = (TextViewFormPtr) GetObjectExtra (f);
2443 if (tfp != NULL) {
2444 switch (mssg) {
2445 case VIB_MSG_EXPORT :
2446 ExportTextViewForm (f, NULL);
2447 break;
2448 case VIB_MSG_CLOSE :
2449 Remove (f);
2450 break;
2451 case VIB_MSG_PRINT :
2452 PrintTextViewForm (tfp);
2453 break;
2454 case VIB_MSG_CUT :
2455 StdCutTextProc (NULL);
2456 break;
2457 case VIB_MSG_COPY :
2458 StdCopyTextProc (NULL);
2459 break;
2460 case VIB_MSG_PASTE :
2461 StdPasteTextProc (NULL);
2462 break;
2463 case VIB_MSG_DELETE :
2464 StdDeleteTextProc (NULL);
2465 break;
2466 default :
2467 if (tfp->appmessage != NULL) {
2468 tfp->appmessage (f, mssg);
2469 }
2470 break;
2471 }
2472 }
2473 }
2474
2475
2476 static void FindInGeneralText (ButtoN b)
2477
2478 {
2479 Int2 actual;
2480 Char buf [1030];
2481 Char ch;
2482 Int2 cnt;
2483 Int8 cntr;
2484 Int2 first;
2485 FILE *fp;
2486 Char lastch;
2487 Int4 line = 0;
2488 ValNodePtr matches;
2489 Int2 next;
2490 Int2 offset = 0;
2491 Char path [PATH_MAX];
2492 CharPtr ptr;
2493 Int4 state;
2494 CharPtr str;
2495 TextFsaPtr tbl;
2496 TextViewFormPtr tfp;
2497 Int4 max;
2498
2499 tfp = (TextViewFormPtr) GetObjectExtra (b);
2500 if (tfp == NULL) return;
2501 if (tfp->doc != NULL) {
2502 GetOffset (tfp->doc, NULL, &offset);
2503 } else if (tfp->text != NULL) {
2504 GetOffset (tfp->text, NULL, &offset);
2505 }
2506 first = -1;
2507 next = -1;
2508 max = INT2_MAX;
2509
2510 str = SaveStringFromText (tfp->find);
2511
2512 if (StringDoesHaveText (str)) {
2513 TmpNam (path);
2514 if (ExportForm (tfp->form, path)) {
2515 tbl = TextFsaNew ();
2516 if (tbl != NULL) {
2517 TextFsaAdd (tbl, str);
2518 fp = FileOpen (path, "r");
2519 if (fp != NULL) {
2520 line = 0;
2521 state = 0;
2522 cntr = FileLength (path);
2523 cnt = (Int2) MIN (cntr, 1024L);
2524 lastch = '\0';
2525 while (cnt > 0 && cntr > 0 && line <= max &&
2526 ((next == -1 && offset > first) || first == -1)) {
2527 actual = (Int2) FileRead (buf, 1, cnt, fp);
2528 if (actual > 0) {
2529 cnt = actual;
2530 buf [cnt] = '\0';
2531 ptr = buf;
2532 ch = *ptr;
2533 while (ch != '\0') {
2534 if (ch == '\n' || ch == '\r') {
2535 if (ch == '\n' && lastch == '\r') {
2536 /* do not increment line */
2537 } else if (ch == '\r' && lastch == '\n') {
2538 /* do not increment line */
2539 } else {
2540 line++;
2541 }
2542 }
2543 state = TextFsaNext (tbl, state, ch, &matches);
2544 if (matches != NULL) {
2545 if (first == -1) {
2546 first = line;
2547 }
2548 if (next == -1 && line > offset) {
2549 next = line;
2550 }
2551 }
2552 lastch = ch;
2553 ptr++;
2554 ch = *ptr;
2555 }
2556 cntr -= cnt;
2557 cnt = (Int2) MIN (cntr, 1024L);
2558 } else {
2559 cnt = 0;
2560 cntr = 0;
2561 }
2562 }
2563 }
2564 FileClose (fp);
2565 }
2566 TextFsaFree (tbl);
2567 }
2568 FileRemove (path);
2569 }
2570 MemFree (str);
2571 if (line > max) {
2572 Message (MSG_ERROR, "Too many lines for search");
2573 }
2574
2575 if (next >= 0) {
2576 offset = next;
2577 } else if (first >= 0) {
2578 offset = first;
2579 } else return;
2580 if (tfp->doc != NULL) {
2581 SetOffset (tfp->doc, 0, offset);
2582 Update ();
2583 } else if (tfp->text != NULL) {
2584 SetOffset (tfp->text, 0, offset);
2585 Update ();
2586 }
2587 }
2588
2589 typedef struct repopulateviewer
2590 {
2591 Nlm_RepopulateViewer repopulate_func;
2592 Pointer repopulate_data;
2593 Nlm_RepopulateDataFree free_data_func;
2594 TextViewFormPtr tfp;
2595 FonT fnt;
2596 } RepopulateViewerData, PNTR RepopulateViewerPtr;
2597
2598 static void CleanupRepopulateViewer (Nlm_GraphiC g, Nlm_VoidPtr data)
2599 {
2600 RepopulateViewerPtr rp;
2601
2602 rp = (RepopulateViewerPtr) data;
2603 if (rp != NULL && rp->free_data_func != NULL)
2604 {
2605 (rp->free_data_func)(rp->repopulate_data);
2606 }
2607
2608 StdCleanupExtraProc (g, data);
2609 }
2610
2611 static void RepopulateViewer (ButtoN b)
2612 {
2613 RepopulateViewerPtr rp;
2614 CharPtr new_path;
2615
2616 rp = (RepopulateViewerPtr) GetObjectExtra (b);
2617
2618 if (rp == NULL || rp->repopulate_func == NULL)
2619 {
2620 return;
2621 }
2622
2623 new_path = (rp->repopulate_func) (rp->repopulate_data);
2624 if (new_path == NULL)
2625 {
2626 return;
2627 }
2628
2629 if (rp->tfp->text != NULL)
2630 {
2631 FileToScrollText (rp->tfp->text, new_path);
2632 }
2633 else if (rp->tfp->doc != NULL)
2634 {
2635 txtColFmt.pixWidth = screenRect.right - screenRect.left;
2636 txtColFmt.pixInset = 8;
2637 DisplayFancy (rp->tfp->doc, new_path, &txtParFmt, &txtColFmt, rp->fnt, 0);
2638 }
2639 FileRemove (new_path);
2640 new_path = MemFree (new_path);
2641 }
2642
2643 static void
2644 LaunchGeneralTextViewerEx
2645 (CharPtr path,
2646 CharPtr title,
2647 Boolean useScrollText,
2648 Nlm_RepopulateViewer repopulate_func,
2649 Pointer repopulate_data,
2650 Nlm_RepopulateDataFree free_data_func)
2651
2652 {
2653 ButtoN b;
2654 FonT fnt;
2655 GrouP g;
2656 Int2 pixheight;
2657 Int2 pixwidth;
2658 StdEditorProcsPtr sepp;
2659 TextViewFormPtr tfp;
2660 TextViewProcsPtr tvpp;
2661 RepopulateViewerPtr rp;
2662 WindoW w;
2663 #ifndef WIN_MAC
2664 MenU m;
2665 #endif
2666
2667 tfp = (TextViewFormPtr) MemNew (sizeof (TextViewForm));
2668 if (tfp == NULL) return;
2669
2670 w = DocumentWindow (-50, -33, -10, -10, title, StdCloseWindowProc, ResizeTextViewer);
2671 SetObjectExtra (w, tfp, StdCleanupFormProc);
2672 tfp->form = (ForM) w;
2673 tfp->exportform = ExportTextViewForm;
2674 tfp->formmessage = TextViewFormMessage;
2675
2676 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2677 if (sepp != NULL) {
2678 SetActivate (w, sepp->activateForm);
2679 tfp->appmessage = sepp->handleMessages;
2680 }
2681
2682 fnt = programFont;
2683 pixwidth = 35 * stdCharWidth + 17;
2684 pixheight = 20 * stdLineHeight;
2685
2686 tvpp = (TextViewProcsPtr) GetAppProperty ("TextDisplayForm");
2687 if (tvpp != NULL) {
2688 pixwidth = MAX (pixwidth, tvpp->minPixelWidth);
2689 pixheight = MAX (pixheight, tvpp->minPixelHeight);
2690 if (tvpp->displayFont != NULL) {
2691 fnt = tvpp->displayFont;
2692 }
2693 if (tvpp->activateForm != NULL) {
2694 SetActivate (w, tvpp->activateForm);
2695 }
2696 }
2697
2698 #ifndef WIN_MAC
2699 m = PulldownMenu (w, "File");
2700 FormCommandItem (m, "Export...", (BaseFormPtr) tfp, VIB_MSG_EXPORT);
2701 SeparatorItem (m);
2702 FormCommandItem (m, "Close", (BaseFormPtr) tfp, VIB_MSG_CLOSE);
2703 if (tvpp != NULL && tvpp->useScrollText) {
2704 m = PulldownMenu (w, "Edit");
2705 FormCommandItem (m, CUT_MENU_ITEM, (BaseFormPtr) tfp, VIB_MSG_CUT);
2706 FormCommandItem (m, COPY_MENU_ITEM, (BaseFormPtr) tfp, VIB_MSG_COPY);
2707 FormCommandItem (m, PASTE_MENU_ITEM, (BaseFormPtr) tfp, VIB_MSG_PASTE);
2708 FormCommandItem (m, CLEAR_MENU_ITEM, (BaseFormPtr) tfp, VIB_MSG_DELETE);
2709 }
2710 #endif
2711
2712 #ifdef WIN_MAC
2713 if (useScrollText) {
2714 if (FileLength (path) > 32767) {
2715 /* text edit window has maximum length on Mac */
2716 useScrollText = FALSE;
2717 }
2718 }
2719 #endif
2720
2721 /* right now Find button is only in indexer Sequin */
2722 if (useScrollText) {
2723 g = HiddenGroup (w, 5, 0, NULL);
2724 b = PushButton (g, "Find", FindInGeneralText);
2725 SetObjectExtra (b, tfp, NULL);
2726 tfp->find = DialogText (g, "", 10, NULL);
2727 if (repopulate_func != NULL)
2728 {
2729 rp = (RepopulateViewerPtr) MemNew (sizeof (RepopulateViewerData));
2730 if (rp != NULL)
2731 {
2732 rp->repopulate_func = repopulate_func;
2733 rp->repopulate_data = repopulate_data;
2734 rp->free_data_func = free_data_func;
2735 rp->tfp = tfp;
2736 rp->fnt = fnt;
2737 b = PushButton (g, "Repopulate", RepopulateViewer);
2738 SetObjectExtra (b, rp, CleanupRepopulateViewer);
2739 }
2740 }
2741 }
2742
2743 if (useScrollText) {
2744 tfp->text = ScrollText (w, (pixwidth + stdCharWidth - 1) / stdCharWidth,
2745 (pixheight + stdLineHeight - 1) / stdLineHeight,
2746 fnt, FALSE, NULL);
2747 SetObjectExtra (tfp->text, tfp, NULL);
2748 RealizeWindow (w);
2749 if (! FileToScrollText (tfp->text, path)) {
2750 /* SetTitle (tfp->text, "(Text is too large to be displayed in this control.)"); */
2751 Remove (w);
2752 LaunchGeneralTextViewerEx (path, title, FALSE,
2753 repopulate_func, repopulate_data, free_data_func);
2754 return;
2755 }
2756 } else {
2757 tfp->doc = DocumentPanel (w, pixwidth, pixheight);
2758 SetObjectExtra (tfp->doc, tfp, NULL);
2759 RealizeWindow (w);
2760 txtColFmt.pixWidth = screenRect.right - screenRect.left;
2761 txtColFmt.pixInset = 8;
2762 DisplayFancy (tfp->doc, path, &txtParFmt, &txtColFmt, fnt, 0);
2763 /* document.c: SaveTableItem does not strip preceeding tabs if tabCount is 0 */
2764 }
2765 Show (w);
2766 Select (w);
2767 Update ();
2768 }
2769
2770 extern void LaunchGeneralTextViewerWithRepopulate
2771 (CharPtr path,
2772 CharPtr title,
2773 Nlm_RepopulateViewer repopulate_func,
2774 Pointer repopulate_data,
2775 Nlm_RepopulateDataFree free_data_func)
2776 {
2777 TextViewProcsPtr tvpp;
2778
2779 tvpp = (TextViewProcsPtr) GetAppProperty ("TextDisplayForm");
2780 if (tvpp != NULL && tvpp->useScrollText) {
2781 LaunchGeneralTextViewerEx (path, title, TRUE,
2782 repopulate_func, repopulate_data, free_data_func);
2783 } else {
2784 LaunchGeneralTextViewerEx (path, title, FALSE,
2785 repopulate_func, repopulate_data, free_data_func);
2786 }
2787 }
2788
2789 extern void LaunchGeneralTextViewer (CharPtr path, CharPtr title)
2790
2791 {
2792 TextViewProcsPtr tvpp;
2793
2794 tvpp = (TextViewProcsPtr) GetAppProperty ("TextDisplayForm");
2795 if (tvpp != NULL && tvpp->useScrollText) {
2796 LaunchGeneralTextViewerEx (path, title, TRUE, NULL, NULL, NULL);
2797 } else {
2798 LaunchGeneralTextViewerEx (path, title, FALSE, NULL, NULL, NULL);
2799 }
2800 }
2801
2802 extern void LaunchAsnTextViewer (Pointer from, AsnWriteFunc writefunc, CharPtr title)
2803
2804 {
2805 AsnIoPtr aip;
2806 Char path [PATH_MAX];
2807
2808 if (from == NULL || writefunc == NULL) return;
2809 if (StringHasNoText (title)) {
2810 title = "General ASN.1 Text Viewer";
2811 }
2812
2813 TmpNam (path);
2814 aip = AsnIoOpen (path, "w");
2815 if (aip != NULL) {
2816 (*writefunc) (from, aip, NULL);
2817 AsnIoClose (aip);
2818 LaunchGeneralTextViewer (path, title);
2819 }
2820 FileRemove (path);
2821 }
2822
2823 #ifndef WIN_MAC
2824 extern void CreateStdEditorFormMenus (WindoW w)
2825
2826 {
2827 BaseFormPtr bfp;
2828 MenU m;
2829
2830 bfp = (BaseFormPtr) GetObjectExtra (w);
2831 if (bfp != NULL) {
2832 m = PulldownMenu (w, "File");
2833 if (bfp->importform != NULL || bfp->exportform != NULL) {
2834 if (bfp->importform != NULL) {
2835 FormCommandItem (m, "Import...", bfp, VIB_MSG_IMPORT);
2836 }
2837 if (bfp->exportform != NULL) {
2838 FormCommandItem (m, "Export...", bfp, VIB_MSG_EXPORT);
2839 }
2840 SeparatorItem (m);
2841 }
2842 FormCommandItem (m, "Close", bfp, VIB_MSG_CLOSE);
2843 m = PulldownMenu (w, "Edit");
2844 FormCommandItem (m, CUT_MENU_ITEM, bfp, VIB_MSG_CUT);
2845 FormCommandItem (m, COPY_MENU_ITEM, bfp, VIB_MSG_COPY);
2846 FormCommandItem (m, PASTE_MENU_ITEM, bfp, VIB_MSG_PASTE);
2847 FormCommandItem (m, CLEAR_MENU_ITEM, bfp, VIB_MSG_DELETE);
2848 }
2849 }
2850 #endif
2851
2852 static Boolean DlgutilGetLowestStackSeqEntry (GatherContextPtr gcp)
2853
2854 {
2855 BaseFormPtr bfp;
2856 Int2 i;
2857
2858 if (gcp == NULL) return TRUE;
2859 bfp = (BaseFormPtr) gcp->userdata;
2860 if (bfp == NULL) return TRUE;
2861 if (gcp->gatherstack != NULL && gcp->numstack > 0) {
2862 for (i = 0; i < gcp->numstack; i++) {
2863 if (gcp->gatherstack [i].itemtype == OBJ_BIOSEQ ||
2864 gcp->gatherstack [i].itemtype == OBJ_BIOSEQSET) {
2865 bfp->input_itemID = gcp->gatherstack [i].itemID;
2866 bfp->input_itemtype = gcp->gatherstack [i].itemtype;
2867 }
2868 }
2869 }
2870 return FALSE;
2871 }
2872
2873 extern Boolean SetClosestParentIfDuplicating (BaseFormPtr bfp)
2874
2875 {
2876 Uint4 itemID;
2877 Uint2 itemtype;
2878 StdEditorProcsPtr sepp;
2879
2880 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2881 if (bfp == NULL || sepp == NULL || (! sepp->duplicateExisting)) return FALSE;
2882 itemID = bfp->input_itemID;
2883 itemtype = bfp->input_itemtype;
2884 GatherItem (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype,
2885 (Pointer) bfp, DlgutilGetLowestStackSeqEntry);
2886 if (itemID == bfp->input_itemID && itemtype == bfp->input_itemtype) {
2887 return FALSE;
2888 }
2889 return TRUE;
2890 }
2891
2892 /*****************************************************************************
2893 *
2894 * Bond and Point SeqLoc dialogs
2895 *
2896 *****************************************************************************/
2897
2898 typedef struct pointpage {
2899 DIALOG_MESSAGE_BLOCK
2900 TexT point;
2901 Int2 count;
2902 SeqEntryPtr PNTR bsptr;
2903 EnumFieldAssoc PNTR alist;
2904 PopuP strand;
2905 PopuP seqIdx;
2906 Boolean nucsOK;
2907 Boolean protsOK;
2908 Boolean showIdTags;
2909 } PointPage, PNTR PointPagePtr;
2910
2911 typedef struct bondpage {
2912 DIALOG_MESSAGE_BLOCK
2913 DialoG pointA;
2914 DialoG pointB;
2915 } BondPage, PNTR BondPagePtr;
2916
2917 static void FillInPointProducts (SeqEntryPtr sep, Pointer mydata,
2918 Int4 index, Int2 indent)
2919
2920 {
2921 BioseqPtr bsp;
2922 PointPagePtr ppp;
2923
2924 if (sep != NULL && mydata != NULL && sep->choice == 1) {
2925 ppp = (PointPagePtr) mydata;
2926 bsp = (BioseqPtr) sep->data.ptrvalue;
2927 if (bsp != NULL) {
2928 if ((ppp->nucsOK && ISA_na (bsp->mol)) ||
2929 (ppp->protsOK && ISA_aa (bsp->mol))) {
2930 ppp->count++;
2931 ppp->bsptr [ppp->count] = sep;
2932 }
2933 }
2934 }
2935 }
2936
2937 static ENUM_ALIST(strand_alist)
2938 {" ", Seq_strand_unknown}, /* 0 */
2939 {"Plus", Seq_strand_plus}, /* 1 */
2940 {"Minus", Seq_strand_minus}, /* 2 */
2941 /*
2942 {"Both", Seq_strand_both},
2943 {"Reverse", Seq_strand_both_rev},
2944 */
2945 {"Other", Seq_strand_other}, /* 255 */
2946 END_ENUM_ALIST
2947
2948 static void SeqPntPtrToPointPage (DialoG d, Pointer data)
2949
2950
2951 {
2952 BioseqPtr bsp;
2953 Int2 j;
2954 PointPagePtr ppp;
2955 SeqEntryPtr sep;
2956 Int2 seq;
2957 SeqPntPtr spp;
2958 Char str [16];
2959 Uint1 strand;
2960
2961 ppp = (PointPagePtr) GetObjectExtra (d);
2962 if (ppp == NULL) return;
2963 spp = (SeqPntPtr) data;
2964 if (spp != NULL) {
2965 sprintf (str, "%ld", (long) (spp->point + 1));
2966 SafeSetTitle (ppp->point, str);
2967 seq = 0;
2968 strand = 0;
2969 bsp = BioseqFind (spp->id);
2970 if (bsp != NULL) {
2971 strand = spp->strand;
2972 if (strand > Seq_strand_both_rev && strand != Seq_strand_other) {
2973 strand = Seq_strand_unknown;
2974 }
2975 if (ppp->bsptr != NULL) {
2976 for (j = 1; j <= ppp->count && seq == 0; j++) {
2977 sep = ppp->bsptr [j];
2978 if (sep != NULL && sep->choice == 1) {
2979 if (bsp == (BioseqPtr) sep->data.ptrvalue) {
2980 seq = j;
2981 }
2982 }
2983 }
2984 }
2985 }
2986 SetEnumPopup (ppp->strand, strand_alist, (UIEnum) strand);
2987 SetEnumPopup (ppp->seqIdx, ppp->alist, (UIEnum) seq);
2988 } else {
2989 SafeSetTitle (ppp->point, "");
2990 SafeSetValue (ppp->strand, 0);
2991 SafeSetValue (ppp->seqIdx, 0);
2992 }
2993 }
2994
2995 static Pointer PointPageToSeqPntPtr (DialoG d)
2996
2997 {
2998 BioseqPtr bsp;
2999 PointPagePtr ppp;
3000 SeqEntryPtr sep;
3001 UIEnum seq;
3002 SeqPntPtr spp;
3003 Char str [16];
3004 UIEnum strand;
3005 Int4 val;
3006
3007 ppp = (PointPagePtr) GetObjectExtra (d);
3008 if (ppp == NULL) return NULL;
3009 spp = NULL;
3010 GetTitle (ppp->point, str, sizeof (str) - 1);
3011 if (StrToLong (str, &val) && val > 0) {
3012 if (GetEnumPopup (ppp->seqIdx, ppp->alist, &seq) &&
3013 seq > 0 && seq <= ppp->count) {
3014 spp = SeqPntNew ();
3015 if (spp != NULL) {
3016 spp->point = val - 1;
3017 if (GetEnumPopup (ppp->strand, strand_alist, &strand)) {
3018 spp->strand = (Uint1) strand;
3019 }
3020 sep = ppp->bsptr [(Int2) seq];
3021 if (sep != NULL && sep->choice == 1) {
3022 bsp = (BioseqPtr) sep->data.ptrvalue;
3023 if (bsp != NULL) {
3024 spp->id = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0)));
3025 }
3026 }
3027 }
3028 }
3029 }
3030 return (Pointer) spp;
3031 }
3032
3033 static void PointEditorMessage (DialoG d, Int2 mssg)
3034
3035 {
3036 PointPagePtr ppp;
3037
3038 ppp = (PointPagePtr) GetObjectExtra (d);
3039 if (ppp != NULL) {
3040 if (mssg == VIB_MSG_INIT) {
3041 SeqPntPtrToPointPage (d, NULL);
3042 } else if (mssg == VIB_MSG_ENTER) {
3043 Select (ppp->point);
3044 } else if (mssg == VIB_MSG_RESET) {
3045 }
3046 }
3047 }
3048
3049 static void CleanupPointPage (GraphiC g, VoidPtr data)
3050
3051 {
3052 Int2 j;
3053 PointPagePtr ppp;
3054
3055 ppp = (PointPagePtr) data;
3056 if (ppp != NULL) {
3057 MemFree (ppp->bsptr);
3058 if (ppp->alist != NULL) {
3059 for (j = 0; j <= ppp->count + 1; j++) {
3060 MemFree (ppp->alist [j].name);
3061 }
3062 }
3063 MemFree (ppp->alist);
3064 }
3065 MemFree (data);
3066 }
3067
3068 static DialoG CreatePointEditorDialog (GrouP h, CharPtr title, SeqEntryPtr sep,
3069 Boolean nucsOK, Boolean protsOK)
3070
3071 {
3072 BioseqPtr bsp;
3073 Int4 count;
3074 GrouP f;
3075 Int2 j;
3076 GrouP m;
3077 GrouP p;
3078 PointPagePtr ppp;
3079 CharPtr ptr;
3080 GrouP s;
3081 Boolean showIdTags;
3082 SeqIdPtr sip;
3083 Char str [128];
3084
3085 p = HiddenGroup (h, 1, 0, NULL);
3086 SetGroupSpacing (p, 10, 10);
3087
3088 ppp = (PointPagePtr) MemNew (sizeof (PointPage));
3089 if (ppp != NULL) {
3090
3091 SetObjectExtra (p, ppp, CleanupPointPage);
3092 ppp->dialog = (DialoG) p;
3093 ppp->todialog = SeqPntPtrToPointPage;
3094 ppp->fromdialog = PointPageToSeqPntPtr;
3095 ppp->dialogmessage = PointEditorMessage;
3096 ppp->testdialog = NULL;
3097 ppp->importdialog = NULL;
3098 ppp->exportdialog = NULL;
3099
3100 if (title != NULL && title [0] != '\0') {
3101 s = NormalGroup (p, 0, -2, title, systemFont, NULL);
3102 } else {
3103 s = HiddenGroup (p, 0, -2, NULL);
3104 }
3105 m = HiddenGroup (s, -1, 0, NULL);
3106 /*
3107 SetGroupSpacing (m, 10, 10);
3108 */
3109
3110 ppp->nucsOK = nucsOK;
3111 ppp->protsOK = protsOK;
3112 ppp->showIdTags = FALSE;
3113 ppp->count = 0;
3114
3115 if (sep != NULL) {
3116 count = SeqEntryCount (sep);
3117 count += 4;
3118 ppp->bsptr = MemNew (sizeof (BioseqPtr) * (size_t) count);
3119 ppp->alist = MemNew (sizeof (EnumFieldAssoc) * (size_t) count);
3120 ppp->count = 0;
3121
3122 if (ppp->bsptr != NULL && ppp->alist != NULL) {
3123 SeqEntryExplore (sep, (Pointer) ppp, FillInPointProducts);
3124 j = 0;
3125 ppp->alist [j].name = StringSave (" ");
3126 ppp->alist [j].value = (UIEnum) 0;
3127 for (j = 1; j <= ppp->count; j++) {
3128 sep = ppp->bsptr [j];
3129 if (sep != NULL && sep->choice == 1 && sep->data.ptrvalue != NULL) {
3130 bsp = (BioseqPtr) sep->data.ptrvalue;
3131 sip = SeqIdFindWorst (bsp->id);
3132 SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
3133 ptr = StringChr (str, '|');
3134 showIdTags = FALSE;
3135 if (ptr == NULL) {
3136 ptr = str;
3137 } else if (showIdTags) {
3138 ptr = str;
3139 } else {
3140 ptr++;
3141 }
3142 ppp->alist [j].name = StringSave (ptr);
3143 ppp->alist [j].value = (UIEnum) j;
3144 }
3145 }
3146 j = ppp->count + 1;
3147 ppp->alist [j].name = NULL;
3148 ppp->alist [j].value = (UIEnum) 0;
3149 }
3150
3151 } else {
3152 ppp->alist = MemNew (sizeof (EnumFieldAssoc) * (size_t) 4);
3153 if (ppp->alist != NULL) {
3154 j = 0;
3155 ppp->alist [j].name = StringSave (" ");
3156 ppp->alist [j].value = (UIEnum) 0;
3157 j = 1;
3158 ppp->alist [j].name = NULL;
3159 ppp->alist [j].value = (UIEnum) 0;
3160
3161 }
3162 }
3163
3164 f = HiddenGroup (m, 6, 0, NULL);
3165 /*StaticPrompt (f, "Point", 0, dialogTextHeight, programFont, 'l');*/
3166 ppp->point = DialogText (f, "", 5, NULL);
3167 if (nucsOK) {
3168 /*StaticPrompt (f, "Strand", 0, popupMenuHeight, programFont, 'c');*/
3169 ppp->strand = PopupList (f, TRUE, NULL);
3170 InitEnumPopup (ppp->strand, strand_alist, NULL);
3171 }
3172 /*StaticPrompt (f, "SeqID", 0, popupMenuHeight, programFont, 'l');*/
3173 ppp->seqIdx = PopupList (f, TRUE, NULL);
3174 InitEnumPopup (ppp->seqIdx, ppp->alist, NULL);
3175 }
3176
3177 return (DialoG) p;
3178 }
3179
3180 static void SeqLocPtrToBondPage (DialoG d, Pointer data)
3181
3182
3183 {
3184 BondPagePtr bpp;
3185 SeqBondPtr sbp;
3186 SeqIdPtr sip;
3187 SeqLocPtr slp;
3188 SeqPnt sqp;
3189
3190 bpp = (BondPagePtr) GetObjectExtra (d);
3191 if (bpp == NULL) return;
3192 slp = (SeqLocPtr) data;
3193 if (slp != NULL) {
3194 if (slp->choice == SEQLOC_BOND) {
3195 sbp = (SeqBondPtr) slp->data.ptrvalue;
3196 if (sbp != NULL) {
3197 PointerToDialog (bpp->pointA, (Pointer) sbp->a);
3198 PointerToDialog (bpp->pointB, (Pointer) sbp->b);
3199 }
3200 } else {
3201 sip = SeqLocId (slp);
3202 if (sip != NULL) {
3203 sqp.strand = SeqLocStrand (slp);
3204 sqp.id = sip;
3205 sqp.point = SeqLocStart (slp);
3206 PointerToDialog (bpp->pointA, (Pointer) &sqp);
3207 sqp.point = SeqLocStop (slp);
3208 PointerToDialog (bpp->pointB, (Pointer) &sqp);
3209 }
3210 }
3211 }
3212 }
3213
3214 static Pointer BondPageToSeqLocPtr (DialoG d)
3215
3216 {
3217 BondPagePtr bpp;
3218 SeqBondPtr sbp;
3219 SeqLocPtr slp;
3220
3221 bpp = (BondPagePtr) GetObjectExtra (d);
3222 if (bpp == NULL) return NULL;
3223 slp = NULL;
3224 sbp = SeqBondNew ();
3225 if (sbp != NULL) {
3226 slp = ValNodeNew (NULL);
3227 if (slp != NULL) {
3228 slp->choice = SEQLOC_BOND;
3229 slp->data.ptrvalue = (Pointer) sbp;
3230 sbp->a = DialogToPointer (bpp->pointA);
3231 sbp->b = DialogToPointer (bpp->pointB);
3232 } else {
3233 SeqBondFree (sbp);
3234 }
3235 }
3236 return (Pointer) slp;
3237 }
3238
3239 static void BondEditorMessage (DialoG d, Int2 mssg)
3240
3241 {
3242 BondPagePtr bpp;
3243
3244 bpp = (BondPagePtr) GetObjectExtra (d);
3245 if (bpp != NULL) {
3246 if (mssg == VIB_MSG_INIT) {
3247 SeqLocPtrToBondPage (d, NULL);
3248 } else if (mssg == VIB_MSG_ENTER) {
3249 SendMessageToDialog (bpp->pointA, VIB_MSG_ENTER);
3250 } else if (mssg == VIB_MSG_RESET) {
3251 }
3252 }
3253 }
3254
3255 extern DialoG CreateBondEditorDialog (GrouP h, CharPtr title, SeqEntryPtr sep);
3256
3257 extern DialoG CreateBondEditorDialog (GrouP h, CharPtr title, SeqEntryPtr sep)
3258
3259 {
3260 BondPagePtr bpp;
3261 GrouP f;
3262 GrouP m;
3263 GrouP p;
3264 GrouP s;
3265
3266 p = HiddenGroup (h, 1, 0, NULL);
3267 SetGroupSpacing (p, 10, 10);
3268
3269 bpp = (BondPagePtr) MemNew (sizeof (BondPage));
3270 if (bpp != NULL) {
3271
3272 SetObjectExtra (p, bpp, StdCleanupExtraProc);
3273 bpp->dialog = (DialoG) p;
3274 bpp->todialog = SeqLocPtrToBondPage;
3275 bpp->fromdialog = BondPageToSeqLocPtr;
3276 bpp->dialogmessage = BondEditorMessage;
3277 bpp->testdialog = NULL;
3278 bpp->importdialog = NULL;
3279 bpp->exportdialog = NULL;
3280
3281 if (title != NULL && title [0] != '\0') {
3282 s = NormalGroup (p, 0, -2, title, systemFont, NULL);
3283 } else {
3284 s = HiddenGroup (p, 0, -2, NULL);
3285 }
3286 m = HiddenGroup (s, -1, 0, NULL);
3287 /*
3288 SetGroupSpacing (m, 10, 10);
3289 */
3290
3291 f = HiddenGroup (m, 2, 0, NULL);
3292 StaticPrompt (f, "From", 0, popupMenuHeight, programFont, 'l');
3293 bpp->pointA = CreatePointEditorDialog (f, NULL, sep, FALSE, TRUE);
3294 StaticPrompt (f, "(To)", 0, popupMenuHeight, programFont, 'l');
3295 bpp->pointB = CreatePointEditorDialog (f, NULL, sep, FALSE, TRUE);
3296 }
3297
3298 return (DialoG) p;
3299 }
3300
3301 void GetRidOfEmptyFeatsDescStrings (Uint2 entityID, SeqEntryPtr sep)
3302
3303 {
3304 if (entityID < 1 && sep == NULL) return;
3305 if (entityID > 0 && sep == NULL) {
3306 sep = GetTopSeqEntryForEntityID (entityID);
3307 }
3308 if (sep == NULL) return;
3309 SeqEntryExplore (sep, NULL, GetRidOfEmptyFeatsDescCallback);
3310 }
3311
3312 extern Int2 LIBCALLBACK StdVibrantEditorMsgFunc (OMMsgStructPtr ommsp)
3313
3314 {
3315 BaseFormPtr bfp;
3316 OMUserDataPtr omudp;
3317
3318 omudp = (OMUserDataPtr)(ommsp->omuserdata);
3319 if (omudp == NULL) return OM_MSG_RET_ERROR;
3320 bfp = (BaseFormPtr) omudp->userdata.ptrvalue;
3321 if (bfp == NULL) return OM_MSG_RET_ERROR;
3322 switch (ommsp->message) {
3323 case OM_MSG_DEL:
3324 Remove (bfp->form);
3325 Update ();
3326 break;
3327 default :
3328 break;
3329 }
3330 return OM_MSG_RET_OK;
3331 }
3332
3333 /* launch url section */
3334
3335 NLM_EXTERN void LaunchEntrezURL (CharPtr database, Int4 uid, CharPtr format)
3336
3337 {
3338 #ifdef WIN_MOTIF
3339 NS_Window window = NULL;
3340 #endif
3341
3342 Char url [256];
3343
3344 if (uid < 1 || StringHasNoText (database) || StringHasNoText (format)) return;
3345 sprintf (url,
3346 "http://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?cmd=Retrieve&db=%s&list_uids=%ld&dopt=%s",
3347 database, (long) uid, format);
3348
3349 #ifdef WIN_MAC
3350 Nlm_SendURLAppleEvent (url, "MOSS", NULL);
3351 #endif
3352 #ifdef WIN_MSWIN
3353 if (! Nlm_MSWin_OpenDocument (url)) {
3354 Message (MSG_POST, "Unable to launch browser");
3355 }
3356 #endif
3357 #ifdef WIN_MOTIF
3358 if (! NS_OpenURL (&window, url, NULL, TRUE)) {
3359 Message (MSG_POST, "Unable to launch browser");
3360 }
3361 NS_WindowFree (window);
3362 #endif
3363 }
3364
3365 extern void ModalAcceptButton (ButtoN b)
3366 {
3367 ModalAcceptCancelPtr acp;
3368
3369 acp = (ModalAcceptCancelPtr) GetObjectExtra (b);
3370 if (acp != NULL)
3371 {
3372 acp->accepted = TRUE;
3373 }
3374 }
3375
3376 extern void ModalCancelButton (ButtoN b)
3377 {
3378 ModalAcceptCancelPtr acp;
3379
3380 acp = (ModalAcceptCancelPtr) GetObjectExtra (b);
3381 if (acp != NULL)
3382 {
3383 acp->cancelled = TRUE;
3384 }
3385 }
3386
3387 extern void ModalThirdOptionButton (ButtoN b)
3388 {
3389 ModalAcceptCancelPtr acp;
3390
3391 acp = (ModalAcceptCancelPtr) GetObjectExtra (b);
3392 if (acp != NULL)
3393 {
3394 acp->third_option = TRUE;
3395 }
3396 }
3397
3398
3399 NLM_EXTERN Int4
3400 ThreeOptionsDlg
3401 (CharPtr title_txt,
3402 CharPtr explain_txt,
3403 CharPtr opt1,
3404 CharPtr opt2,
3405 CharPtr opt3)
3406 {
3407 WindoW w;
3408 GrouP h, c;
3409 ButtoN b;
3410 GrouP p;
3411 ModalAcceptCancelData acd;
3412
3413
3414 w = MovableModalWindow (-20, -13, -10, -10, title_txt, NULL);
3415 h = HiddenGroup(w, -1, 0, NULL);
3416 SetGroupSpacing (h, 10, 10);
3417
3418 p = MultiLinePrompt (h, explain_txt, 300, programFont);
3419
3420 c = HiddenGroup (h, 3, 0, NULL);
3421 b = PushButton (c, opt1, ModalAcceptButton);
3422 SetObjectExtra (b, &acd, NULL);
3423 b = PushButton (c, opt2, ModalCancelButton);
3424 SetObjectExtra (b, &acd, NULL);
3425
3426 if (!StringHasNoText (opt3)) {
3427 b = PushButton (c, opt3, ModalThirdOptionButton);
3428 SetObjectExtra (b, &acd, NULL);
3429 }
3430
3431 AlignObjects (ALIGN_CENTER, (HANDLE) p,
3432 (HANDLE) c,
3433 NULL);
3434
3435 Show (w);
3436 Select (w);
3437
3438 acd.cancelled = FALSE;
3439 acd.third_option = FALSE;
3440 acd.accepted = FALSE;
3441 while (!acd.accepted && ! acd.cancelled && !acd.third_option)
3442 {
3443 ProcessExternalEvent ();
3444 Update ();
3445 }
3446 ProcessAnEvent ();
3447 Remove (w);
3448
3449 if (acd.accepted)
3450 {
3451 return 1;
3452 }
3453 else if (acd.cancelled)
3454 {
3455 return 2;
3456 }
3457 else
3458 {
3459 return 3;
3460 }
3461 }
3462
3463
3464 typedef struct tabledisplay
3465 {
3466 DIALOG_MESSAGE_BLOCK
3467 PaneL panel;
3468 ValNodePtr row_list;
3469 Int4 frozen_header;
3470 Int4 frozen_left;
3471 Int4 table_inset;
3472 Int4 char_width;
3473 Int4 descent;
3474 FonT display_font;
3475 TableDisplayDblClick dbl_click;
3476 Pointer dbl_click_data;
3477 TableDisplayLeftInRed left_in_red;
3478 Pointer left_in_red_data;
3479 } TableDisplayData, PNTR TableDisplayPtr;
3480
3481 extern ValNodePtr FreeTableDisplayRowList (ValNodePtr row_list)
3482 {
3483 ValNodePtr row_vnp, column_list;
3484
3485 if (row_list != NULL)
3486 {
3487 /* free table text */
3488 for (row_vnp = row_list; row_vnp != NULL; row_vnp = row_vnp->next)
3489 {
3490 column_list = (ValNodePtr) row_vnp->data.ptrvalue;
3491 row_vnp->data.ptrvalue = ValNodeFreeData (column_list);
3492 }
3493 row_list = ValNodeFree (row_list);
3494 }
3495 return row_list;
3496 }
3497
3498 extern void PrintTableDisplayRowListToFile (ValNodePtr row_list, FILE *fp)
3499 {
3500 ValNodePtr row_vnp, col_vnp, column_list;
3501 CharPtr txt_val;
3502
3503 if (row_list == NULL || fp == NULL)
3504 {
3505 return;
3506 }
3507
3508 for (row_vnp = row_list; row_vnp != NULL; row_vnp = row_vnp->next)
3509 {
3510 column_list = (ValNodePtr) row_vnp->data.ptrvalue;
3511 for (col_vnp = column_list; col_vnp != NULL; col_vnp = col_vnp->next)
3512 {
3513 txt_val = (CharPtr) col_vnp->data.ptrvalue;
3514 if (!StringHasNoText (txt_val))
3515 {
3516 fprintf (fp, "%s", txt_val);
3517 }
3518 if (col_vnp->next == NULL)
3519 {
3520 fprintf (fp, "\n");
3521 }
3522 else
3523 {
3524 fprintf (fp, "\t");
3525 }
3526 }
3527 }
3528 }
3529
3530 static ValNodePtr ValNodeStringListCopy (ValNodePtr orig_list)
3531 {
3532 ValNodePtr new_list = NULL;
3533
3534 if (orig_list == NULL)
3535 {
3536 return NULL;
3537 }
3538
3539 new_list = ValNodeNew (NULL);
3540 new_list->choice = orig_list->choice;
3541 new_list->data.ptrvalue = StringSave (orig_list->data.ptrvalue);
3542 new_list->next = ValNodeStringListCopy (orig_list->next);
3543 return new_list;
3544 }
3545
3546 extern ValNodePtr CopyTableDisplayRowList (ValNodePtr row_list)
3547 {
3548 ValNodePtr new_row_list = NULL;
3549
3550 if (row_list == NULL)
3551 {
3552 return NULL;
3553 }
3554
3555 new_row_list = ValNodeNew (NULL);
3556 new_row_list->choice = row_list->choice;
3557 new_row_list->data.ptrvalue = ValNodeStringListCopy (row_list->data.ptrvalue);
3558 new_row_list->next = CopyTableDisplayRowList (row_list->next);
3559 return new_row_list;
3560 }
3561
3562 static void CleanupTableDisplayDialog (GraphiC g, VoidPtr data)
3563 {
3564 TableDisplayPtr dlg;
3565
3566 dlg = (TableDisplayPtr) data;
3567 if (dlg != NULL) {
3568 dlg->row_list = FreeTableDisplayRowList (dlg->row_list);
3569 }
3570 StdCleanupExtraProc (g, data);
3571 }
3572
3573 static void UpdateTableDisplayDialogScrollBars (TableDisplayPtr dlg)
3574 {
3575 BaR sb_vert;
3576 BaR sb_horiz;
3577 Int4 start_row, start_col;
3578 Int4 num_rows, num_columns, visible_rows;
3579 Int4 new_vmax, new_hmax, old_vmax, old_hmax;
3580 RecT r;
3581 Int4 x, y;
3582
3583 if (dlg == NULL)
3584 {
3585 return;
3586 }
3587
3588 sb_vert = GetSlateVScrollBar ((SlatE) dlg->panel);
3589 sb_horiz = GetSlateHScrollBar ((SlatE) dlg->panel);
3590
3591 start_row = GetBarValue (sb_vert) + dlg->frozen_header;
3592 start_col = GetBarValue (sb_horiz) + dlg->frozen_left;
3593
3594 if (dlg->row_list == NULL)
3595 {
3596 num_rows = 0;
3597 num_columns = 0;
3598 }
3599 else
3600 {
3601 num_rows = ValNodeLen (dlg->row_list);
3602 num_columns = ValNodeLen (dlg->row_list->data.ptrvalue);
3603 }
3604
3605 ObjectRect (dlg->panel, &r);
3606 InsetRect (&r, dlg->table_inset, dlg->table_inset);
3607 x = r.left + 1;
3608 y = r.top + stdLineHeight;
3609
3610 visible_rows = (r.bottom - r.top - 2 * dlg->table_inset) / stdLineHeight - dlg->frozen_header;
3611 new_vmax = num_rows - visible_rows - 1;
3612 new_hmax = num_columns - dlg->frozen_left - 1;
3613 if (new_vmax < 0)
3614 {
3615 new_vmax = 0;
3616 }
3617 if (new_hmax < 0)
3618 {
3619 new_hmax = 0;
3620 }
3621 old_vmax = GetBarMax (sb_vert);
3622 old_hmax = GetBarMax (sb_horiz);
3623
3624 if (old_vmax != new_vmax)
3625 {
3626 CorrectBarMax (sb_vert, new_vmax);
3627 if (start_row > new_vmax + dlg->frozen_header)
3628 {
3629 start_row = new_vmax + dlg->frozen_header;
3630 }
3631 CorrectBarValue (sb_vert, start_row - dlg->frozen_header);
3632 CorrectBarPage (sb_vert, 1, 1);
3633 }
3634
3635 if (old_hmax != new_hmax)
3636 {
3637 CorrectBarMax (sb_horiz, new_hmax);
3638 if (start_col > new_hmax + dlg->frozen_left)
3639 {
3640 start_col = new_hmax + dlg->frozen_left;
3641 }
3642 CorrectBarValue (sb_horiz, start_col - dlg->frozen_left);
3643 CorrectBarPage (sb_horiz, 1, 1);
3644 }
3645 }
3646
3647 static void RowsToTableDisplayDialog (DialoG d, Pointer userdata)
3648 {
3649 TableDisplayPtr dlg;
3650 RecT r;
3651 WindoW temport;
3652
3653 dlg = (TableDisplayPtr) GetObjectExtra (d);
3654 if (dlg == NULL)
3655 {
3656 return;
3657 }
3658
3659 dlg->row_list = FreeTableDisplayRowList (dlg->row_list);
3660 dlg->row_list = CopyTableDisplayRowList (userdata);
3661 UpdateTableDisplayDialogScrollBars (dlg);
3662 temport = SavePort (dlg->panel);
3663 Select (dlg->panel);
3664 ObjectRect (dlg->panel, &r);
3665 InvalRect (&r);
3666 Update ();
3667 RestorePort (temport);
3668 }
3669
3670 static Pointer TableDisplayDialogToRows (DialoG d)
3671 {
3672 TableDisplayPtr dlg;
3673
3674 dlg = (TableDisplayPtr) GetObjectExtra (d);
3675 if (dlg == NULL)
3676 {
3677 return NULL;
3678 }
3679
3680 return CopyTableDisplayRowList (dlg->row_list);
3681 }
3682
3683 static Int4
3684 PrepareTableDisplayTextBuffer
3685 (CharPtr buf,
3686 Int4 remaining_chars_in_row,
3687 Int4 col_width,
3688 CharPtr data)
3689 {
3690 Uint4 chars_to_paint = 0;
3691 if (buf == NULL)
3692 {
3693 return 0;
3694 }
3695
3696 if (remaining_chars_in_row < col_width)
3697 {
3698 chars_to_paint = remaining_chars_in_row;
3699 StringNCpy (buf, data, chars_to_paint);
3700 buf [chars_to_paint] = 0;
3701 }
3702 else
3703 {
3704 chars_to_paint = col_width;
3705 StringNCpy (buf, data, chars_to_paint);
3706 buf [chars_to_paint] = 0;
3707 if (StringLen (data) > chars_to_paint && chars_to_paint > 2)
3708 {
3709 buf [chars_to_paint - 1] = '.';
3710 buf [chars_to_paint - 2] = '.';
3711 buf [chars_to_paint - 3] = '.';
3712 }
3713 }
3714 return chars_to_paint;
3715 }
3716
3717 static void DrawTableDisplayLine (Int4 x, Int4 y,
3718 ValNodePtr header_row,
3719 ValNodePtr data_row,
3720 CharPtr buf,
3721 Int4 row_length,
3722 Int4 frozen_left,
3723 Int4 start_col,
3724 Int4 char_width,
3725 Int4 descent,
3726 Boolean left_in_red)
3727 {
3728 ValNodePtr header_vnp, data_vnp;
3729 Int4 x_offset, chars_to_paint, col_num;
3730 PoinT pt1, pt2;
3731 RecT rct;
3732
3733 /* draw left margin */
3734
3735 for (header_vnp = header_row, data_vnp = data_row, x_offset = 0, col_num = 0;
3736 header_vnp != NULL && data_vnp != NULL && x_offset < row_length && col_num < frozen_left;
3737 header_vnp = header_vnp->next, data_vnp = data_vnp->next, col_num++)
3738 {
3739 Gray ();
3740 InvertColors ();
3741 if (left_in_red)
3742 {
3743 Red ();
3744 }
3745 else
3746 {
3747 White ();
3748 }
3749 chars_to_paint = PrepareTableDisplayTextBuffer (buf,
3750 (row_length - x_offset) / char_width,
3751 header_vnp->choice,
3752 data_vnp->data.ptrvalue);
3753
3754 LoadRect (&rct, x + x_offset, y + descent,
3755 x + x_offset + (chars_to_paint + 2) * char_width,
3756 y - stdLineHeight + descent);
3757 EraseRect (&rct);
3758
3759 PaintStringEx ( (CharPtr)buf, x + x_offset, y);
3760 x_offset += (chars_to_paint + 2) * char_width;
3761 InvertColors ();
3762 Black ();
3763 }
3764
3765 if (frozen_left > 0)
3766 {
3767 pt1.x = x + x_offset - 1;
3768 pt1.y = y;
3769 pt2.x = x + x_offset - 1;
3770 pt2.y = y - stdLineHeight;
3771 DrawLine (pt1, pt2);
3772 }
3773
3774
3775 while (col_num < start_col && header_vnp != NULL && data_vnp != NULL)
3776 {
3777 col_num++;
3778 header_vnp = header_vnp->next;
3779 data_vnp = data_vnp->next;
3780 }
3781
3782 /* draw unfrozen columns */
3783 while (header_vnp != NULL && data_vnp != NULL && x_offset < row_length)
3784 {
3785 chars_to_paint = MIN (header_vnp->choice, (row_length - x_offset)/char_width);
3786 StringNCpy (buf, data_vnp->data.ptrvalue, chars_to_paint);
3787 buf [chars_to_paint] = 0;
3788 chars_to_paint = PrepareTableDisplayTextBuffer (buf,
3789 (row_length - x_offset) / char_width,
3790 header_vnp->choice,
3791 data_vnp->data.ptrvalue);
3792
3793 PaintStringEx ( (CharPtr)buf, x + x_offset, y);
3794 x_offset += (chars_to_paint + 2) * char_width;
3795 header_vnp = header_vnp->next;
3796 data_vnp = data_vnp->next;
3797 }
3798 }
3799
3800 static void OnDrawTableDisplay (PaneL p)
3801 {
3802 TableDisplayPtr dlg;
3803 BaR sb_vert, sb_horiz;
3804 Int4 start_row, start_col;
3805 RecT r;
3806 Int4 x, y, row, row_length;
3807 CharPtr row_buffer;
3808 ValNodePtr row_vnp;
3809 PoinT pt1, pt2;
3810 Boolean left_in_red;
3811
3812 dlg = (TableDisplayPtr) GetObjectExtra (p);
3813 if (dlg == NULL)
3814 {
3815 return;
3816 }
3817
3818 sb_vert = GetSlateVScrollBar ((SlatE) p);
3819 sb_horiz = GetSlateHScrollBar ((SlatE) p);
3820
3821 start_row = GetBarValue (sb_vert) + dlg->frozen_header;
3822 start_col = GetBarValue (sb_horiz) + dlg->frozen_left;
3823
3824 ObjectRect (p, &r);
3825 InsetRect (&r, dlg->table_inset, dlg->table_inset);
3826 x = r.left + 1;
3827 y = r.top + stdLineHeight;
3828
3829 SelectFont (programFont);
3830
3831 row_length = r.right - r.left - 2;
3832 row_buffer = (CharPtr) MemNew (((row_length / dlg->char_width) + 1) * sizeof (Char));
3833
3834 for (row = 0, row_vnp = dlg->row_list;
3835 row < dlg->frozen_header && y <= r.bottom - 2 * dlg->table_inset && row_vnp != NULL;
3836 row++, row_vnp = row_vnp->next)
3837 {
3838 DrawTableDisplayLine (x, y, dlg->row_list->data.ptrvalue, row_vnp->data.ptrvalue,
3839 row_buffer, row_length, dlg->frozen_left, start_col,
3840 dlg->char_width, dlg->descent, FALSE);
3841 y += stdLineHeight;
3842 }
3843
3844 while (row < start_row && row_vnp != NULL)
3845 {
3846 row++;
3847 row_vnp = row_vnp->next;
3848 }
3849
3850 while (row_vnp != NULL && y <= r.bottom - 2 * dlg->table_inset)
3851 {
3852 left_in_red = FALSE;
3853 if (dlg->left_in_red != NULL)
3854 {
3855 left_in_red = (dlg->left_in_red) (row, dlg->row_list, dlg->left_in_red_data);
3856 }
3857 DrawTableDisplayLine (x, y, dlg->row_list->data.ptrvalue, row_vnp->data.ptrvalue,
3858 row_buffer, row_length, dlg->frozen_left, start_col,
3859 dlg->char_width, dlg->descent, left_in_red);
3860 row_vnp = row_vnp->next;
3861 y += stdLineHeight;
3862 row++;
3863 }
3864
3865 /* draw line to separate header from remaining lines */
3866 if (dlg->frozen_header > 0)
3867 {
3868 Black ();
3869 pt1.x = x;
3870 pt1.y = r.top + stdLineHeight + dlg->descent;
3871 pt2.x = x + row_length;
3872 pt2.y = r.top + stdLineHeight + dlg->descent;
3873 DrawLine (pt1, pt2);
3874 }
3875
3876
3877 }
3878
3879 static void OnVScrollTableDisplay (BaR sb, SlatE s, Int4 newval, Int4 oldval)
3880 {
3881 RecT r;
3882 WindoW temport;
3883
3884 temport = SavePort (s);
3885 Select (s);
3886 ObjectRect (s, &r);
3887 InvalRect (&r);
3888 RestorePort (temport);
3889 Update ();
3890 }
3891
3892 static void OnHScrollTableDisplay (BaR sb, SlatE s, Int4 newval, Int4 oldval)
3893 {
3894 RecT r;
3895 WindoW temport;
3896
3897 temport = SavePort (s);
3898 Select (s);
3899 ObjectRect (s, &r);
3900 InvalRect (&r);
3901 RestorePort (temport);
3902 Update ();
3903 }
3904
3905 static PoinT GetTableDisplayCell (TableDisplayPtr dlg, PoinT pt)
3906 {
3907 BaR sb_horiz;
3908 BaR sb_vert;
3909 Int4 start_row, start_col;
3910 RecT r;
3911 PoinT cell_coord;
3912 Int4 x, y;
3913 ValNodePtr header_vnp;
3914 Int4 col_width;
3915
3916 cell_coord.x = 0;
3917 cell_coord.y = 0;
3918
3919 if (dlg == NULL || dlg->row_list == NULL)
3920 {
3921 return cell_coord;
3922 }
3923
3924 sb_vert = GetSlateVScrollBar ((SlatE) dlg->panel);
3925 sb_horiz = GetSlateHScrollBar ((SlatE) dlg->panel);
3926
3927 start_row = GetBarValue (sb_vert) + dlg->frozen_header;
3928 start_col = GetBarValue (sb_horiz) + dlg->frozen_left;
3929
3930 ObjectRect (dlg->panel, &r);
3931 InsetRect (&r, dlg->table_inset, dlg->table_inset);
3932 x = pt.x - r.left;
3933 y = pt.y - r.top;
3934
3935 cell_coord.y = y / stdLineHeight;
3936
3937 if (cell_coord.y >= dlg->frozen_header)
3938 {
3939 cell_coord.y += GetBarValue (sb_vert);
3940 }
3941
3942 header_vnp = dlg->row_list->data.ptrvalue;
3943
3944 col_width = 0;
3945 while (header_vnp != NULL && col_width + (header_vnp->choice + 2) * dlg->char_width < x
3946 && cell_coord.x < dlg->frozen_left)
3947 {
3948 cell_coord.x++;
3949 col_width += (header_vnp->choice + 2) * dlg->char_width;
3950 header_vnp = header_vnp->next;
3951 }
3952
3953 if (cell_coord.x >= dlg->frozen_left)
3954 {
3955 /* skip over unfrozen columns not currently displayed */
3956 while (header_vnp != NULL && cell_coord.x < start_col)
3957 {
3958 header_vnp = header_vnp->next;
3959 cell_coord.x++;
3960 }
3961
3962 while (header_vnp != NULL && col_width + (header_vnp->choice + 2) * dlg->char_width < x)
3963 {
3964 cell_coord.x++;
3965 col_width += (header_vnp->choice + 2) * dlg->char_width;
3966 header_vnp = header_vnp->next;
3967 }
3968 }
3969 return cell_coord;
3970 }
3971
3972 extern CharPtr GetRowListCellText (ValNodePtr row_list, Int4 row, Int4 column)
3973 {
3974 ValNodePtr row_vnp, col_vnp;
3975 Int4 row_num, col_num;
3976
3977 if (row_list == NULL || row < 0 || column < 0)
3978 {
3979 return NULL;
3980 }
3981
3982 for (row_vnp = row_list, row_num = 0;
3983 row_vnp != NULL && row_num < row;
3984 row_vnp = row_vnp->next, row_num++)
3985 {
3986 }
3987 if (row_num != row || row_vnp == NULL)
3988 {
3989 return NULL;
3990 }
3991 for (col_vnp = row_vnp->data.ptrvalue, col_num = 0;
3992 col_vnp != NULL && col_num < column;
3993 col_vnp = col_vnp->next, col_num++)
3994 {
3995 }
3996 if (col_num != column || col_vnp == NULL)
3997 {
3998 return NULL;
3999 }
4000 else
4001 {
4002 return StringSave (col_vnp->data.ptrvalue);
4003 }
4004 }
4005
4006 static CharPtr TableDisplayGetTextForCell (TableDisplayPtr dlg, PoinT pt)
4007 {
4008 if (dlg == NULL || dlg->row_list == NULL || pt.x < 0 || pt.y < 0)
4009 {
4010 return NULL;
4011 }
4012
4013 return GetRowListCellText (dlg->row_list, pt.y, pt.x);
4014 }
4015
4016 static void TableDisplayOnClick (PaneL p, PoinT pt)
4017 {
4018 TableDisplayPtr dlg;
4019 Boolean dbl_click;
4020 PoinT cell_coord;
4021 PoinT header_coord;
4022 CharPtr cell_text;
4023 CharPtr header_text;
4024
4025 dlg = (TableDisplayPtr) GetObjectExtra (p);
4026 if (dlg == NULL)
4027 {
4028 return;
4029 }
4030
4031 dbl_click = dblClick;
4032 if (dbl_click && dlg->dbl_click != NULL)
4033 {
4034 cell_coord = GetTableDisplayCell (dlg, pt);
4035 cell_text = TableDisplayGetTextForCell (dlg, cell_coord);
4036 header_coord.x = cell_coord.x;
4037 header_coord.y = 0;
4038 header_text = TableDisplayGetTextForCell (dlg, header_coord);
4039 (dlg->dbl_click) (cell_coord, header_text, cell_text, dlg->dbl_click_data);
4040 MemFree (cell_text);
4041 MemFree (header_text);
4042 }
4043 }
4044
4045 extern FonT GetTableDisplayDefaultFont (void)
4046 {
4047 FonT display_font = NULL;
4048
4049 #ifdef WIN_MAC
4050 display_font = ParseFont ("Monaco, 9");
4051 #endif
4052 #ifdef WIN_MSWIN
4053 display_font = ParseFont ("Courier, 9");
4054 #endif
4055 #ifdef WIN_MOTIF
4056 display_font = ParseFont ("fixed, 12");
4057 #endif
4058 return display_font;
4059 }
4060
4061 extern DialoG TableDisplayDialog (GrouP parent, Int4 width, Int4 height,
4062 Int4 frozen_header, Int4 frozen_left,
4063 TableDisplayDblClick dbl_click,
4064 Pointer dbl_click_data,
4065 TableDisplayLeftInRed left_in_red,
4066 Pointer left_in_red_data)
4067 {
4068 TableDisplayPtr dlg;
4069 GrouP p;
4070
4071 dlg = (TableDisplayPtr) MemNew (sizeof (TableDisplayData));
4072 if (dlg == NULL)
4073 {
4074 return NULL;
4075 }
4076 p = HiddenGroup (parent, -1, 0, NULL);
4077 SetObjectExtra (p, dlg, CleanupTableDisplayDialog);
4078
4079 dlg->dialog = (DialoG) p;
4080 dlg->todialog = RowsToTableDisplayDialog;
4081 dlg->fromdialog = TableDisplayDialogToRows;
4082 dlg->dialogmessage = NULL;
4083 dlg->testdialog = NULL;
4084
4085 dlg->row_list = NULL;
4086 dlg->frozen_header = frozen_header;
4087 dlg->frozen_left = frozen_left;
4088 dlg->table_inset = 4;
4089 dlg->dbl_click = dbl_click;
4090 dlg->dbl_click_data = dbl_click_data;
4091 dlg->left_in_red = left_in_red;
4092 dlg->left_in_red_data = left_in_red_data;
4093
4094 dlg->display_font = GetTableDisplayDefaultFont ();
4095
4096 SelectFont (dlg->display_font);
4097 dlg->char_width = CharWidth ('0');
4098 dlg->descent = Descent ();
4099
4100 dlg->panel = AutonomousPanel4 (p, width, height, OnDrawTableDisplay,
4101 OnVScrollTableDisplay, OnHScrollTableDisplay,
4102 sizeof (TableDisplayData), NULL, NULL);
4103 SetObjectExtra (dlg->panel, dlg, NULL);
4104 SetPanelClick(dlg->panel, TableDisplayOnClick, NULL, NULL, NULL);
4105
4106 return (DialoG) p;
4107 }
4108
4109 typedef struct multiselectdialog
4110 {
4111 DIALOG_MESSAGE_BLOCK
4112 DoC doc;
4113 ValNodePtr selected_list;
4114 ParData listPar;
4115 ColData listCol;
4116 Int4 num_choices;
4117 Nlm_ChangeNotifyProc change_notify;
4118 Pointer change_userdata;
4119 } MultiSelectDialogData, PNTR MultiSelectDialogPtr;
4120
4121 static void DataToMultiSelectionDialog (DialoG d, Pointer userdata)
4122 {
4123 MultiSelectDialogPtr dlg;
4124 ValNodePtr vnp;
4125 Boolean all_selected = FALSE;
4126
4127 dlg = (MultiSelectDialogPtr) GetObjectExtra (d);
4128 if (dlg == NULL) return;
4129
4130 dlg->selected_list = ValNodeFree (dlg->selected_list);
4131 for (vnp = (ValNodePtr) userdata; vnp != NULL && ! all_selected; vnp = vnp->next)
4132 {
4133 if (vnp->data.intvalue == 1)
4134 {
4135 all_selected = TRUE;
4136 }
4137 else
4138 {
4139 ValNodeAddInt (&(dlg->selected_list), vnp->data.intvalue, vnp->data.intvalue);
4140 }
4141 }
4142 if (all_selected)
4143 {
4144 dlg->selected_list = ValNodeFree (dlg->selected_list);
4145 ValNodeAddInt (&(dlg->selected_list), 1, 1);
4146 }
4147 InvalDocRows (dlg->doc, 0, 0, 0);
4148 }
4149
4150 static Pointer MultiSelectionDialogToData (DialoG d)
4151 {
4152 MultiSelectDialogPtr dlg;
4153 ValNodePtr output_list = NULL, vnp;
4154
4155 dlg = (MultiSelectDialogPtr) GetObjectExtra (d);
4156 if (dlg == NULL) return NULL;
4157
4158 for (vnp = dlg->selected_list; vnp != NULL; vnp = vnp->next)
4159 {
4160 ValNodeAddInt (&output_list, vnp->choice, vnp->data.intvalue);
4161 }
4162 return output_list;
4163 }
4164
4165 static void
4166 AddChoiceToSelection
4167 (Int2 choice_num,
4168 Boolean remove_other_choices,
4169 MultiSelectDialogPtr dlg)
4170 {
4171 ValNodePtr already_sel, vnp;
4172
4173 if (dlg == NULL || dlg->doc == NULL || choice_num < 1)
4174 {
4175 return;
4176 }
4177
4178 if (choice_num == 1)
4179 {
4180 remove_other_choices = TRUE;
4181 }
4182 else
4183 {
4184 /* if we have added a choice other than "All", remove the "All"
4185 * selection if it was present.
4186 */
4187 ValNodeFree (ValNodeExtractList (&(dlg->selected_list), 1));
4188 InvalDocRows (dlg->doc, 1, 1, 1);
4189 }
4190
4191 already_sel = ValNodeExtractList (&(dlg->selected_list), choice_num);
4192 if (already_sel == NULL)
4193 {
4194 if (remove_other_choices)
4195 {
4196 /* delete old selections */
4197 for (vnp = dlg->selected_list; vnp != NULL; vnp = vnp->next)
4198 {
4199 InvalDocRows (dlg->doc, vnp->choice, 1, 1);
4200 }
4201 dlg->selected_list = ValNodeFree (dlg->selected_list);
4202 ValNodeAddInt (&dlg->selected_list, choice_num, choice_num);
4203 InvalDocRows (dlg->doc, choice_num, 1, 1);
4204 }
4205 else
4206 {
4207 /* add new selection */
4208 ValNodeAddInt (&(dlg->selected_list), choice_num, choice_num);
4209 InvalDocRows (dlg->doc, choice_num, 1, 1);
4210 }
4211 }
4212 else
4213 {
4214 already_sel = ValNodeFree (already_sel);
4215 InvalDocRows (dlg->doc, choice_num, 1, 1);
4216 }
4217 if (dlg->change_notify != NULL)
4218 {
4219 (dlg->change_notify) (dlg->change_userdata);
4220 }
4221 }
4222
4223 static void SelectChoice (DoC d, PoinT pt)
4224 {
4225 Int2 item, row;
4226 Boolean remove_other_choices;
4227 MultiSelectDialogPtr dlg;
4228
4229 remove_other_choices = ! ctrlKey;
4230
4231 dlg = (MultiSelectDialogPtr) GetObjectExtra (d);
4232 if (dlg == NULL) return;
4233
4234 MapDocPoint (d, pt, &item, &row, NULL, NULL);
4235 AddChoiceToSelection (item, remove_other_choices, dlg);
4236 }
4237
4238 static Boolean ChoiceHighlight (DoC doc, Int2 item, Int2 row, Int2 col)
4239 {
4240 MultiSelectDialogPtr dlg;
4241 ValNodePtr vnp;
4242
4243 dlg = (MultiSelectDialogPtr) GetObjectExtra (doc);
4244 if (dlg == NULL) return FALSE;
4245
4246 for (vnp = dlg->selected_list; vnp != NULL; vnp = vnp->next)
4247 {
4248 if (vnp->data.intvalue == item)
4249 {
4250 return TRUE;
4251 }
4252 }
4253 return FALSE;
4254 }
4255
4256 static void ChoiceOnKey (SlatE s, Char ch)
4257 {
4258 MultiSelectDialogPtr dlg;
4259 CharPtr str;
4260 Int2 start_pos;
4261 Boolean found = FALSE;
4262 ValNodePtr vnp;
4263
4264 dlg = (MultiSelectDialogPtr) GetObjectExtra (s);
4265 if (dlg == NULL) return;
4266
4267 if ( (int) ch == 0 ) return;
4268
4269 if (isalpha (ch))
4270 {
4271 /* find the position of the last choice we added */
4272 for (vnp = dlg->selected_list; vnp != NULL && vnp->next != NULL; vnp = vnp->next)
4273 {}
4274
4275 if (vnp == NULL)
4276 {
4277 GetOffset (dlg->doc, NULL, &start_pos);
4278 /* start pos is one less than document row */
4279 start_pos ++;
4280 /* want to start at row after top row */
4281 start_pos ++;
4282 }
4283 else
4284 {
4285 /* want to start at row after currently selected row */
4286 start_pos = vnp->choice + 1;
4287 }
4288
4289 while (!found && start_pos <= dlg->num_choices)
4290 {
4291 str = GetDocText (dlg->doc, start_pos, 1, 1);
4292 if (tolower (str [0]) == tolower (ch))
4293 {
4294 SetOffset (dlg->doc, 0, start_pos - 1);
4295 AddChoiceToSelection (start_pos, TRUE, dlg);
4296 found = TRUE;
4297 }
4298 str = MemFree (str);
4299 start_pos ++;
4300 }
4301 if (!found)
4302 {
4303 /* start searching at the top of the list */
4304 start_pos = 1;
4305 while (!found && start_pos <= dlg->num_choices)
4306 {
4307 str = GetDocText (dlg->doc, start_pos, 1, 1);
4308 if (tolower (str [0]) == tolower (ch))
4309 {
4310 SetOffset (dlg->doc, 0, start_pos - 1);
4311 AddChoiceToSelection (start_pos, TRUE, dlg);
4312 found = TRUE;
4313 }
4314 str = MemFree (str);
4315 start_pos ++;
4316 }
4317 }
4318 }
4319 else if (ch == NLM_DOWN)
4320 {
4321 /* down key */
4322 if (dlg->selected_list == NULL)
4323 {
4324 GetOffset (dlg->doc, NULL, &start_pos);
4325 start_pos ++;
4326 }
4327 else
4328 {
4329 start_pos = dlg->selected_list->choice;
4330 }
4331 start_pos ++;
4332
4333 if (start_pos <= dlg->num_choices)
4334 {
4335 SetOffset (dlg->doc, 0, start_pos - 1);
4336 AddChoiceToSelection (start_pos, TRUE, dlg);
4337 InvalDocRows (dlg->doc, 0, 0, 0);
4338 }
4339 }
4340 else if (ch == NLM_UP)
4341 {
4342 /* up key */
4343 if (dlg->selected_list == NULL)
4344 {
4345 GetOffset (dlg->doc, NULL, &start_pos);
4346 start_pos ++;
4347 }
4348 else
4349 {
4350 start_pos = dlg->selected_list->choice;
4351 }
4352 start_pos --;
4353 if (start_pos > 0)
4354 {
4355 SetOffset (dlg->doc, 0, start_pos - 1);
4356 AddChoiceToSelection (start_pos, TRUE, dlg);
4357 InvalDocRows (dlg->doc, 0, 0, 0);
4358 }
4359 }
4360 }
4361
4362 static DialoG
4363 MultiSelectDialog
4364 (GrouP parent,
4365 ValNodePtr choice_list,
4366 Int4 list_height,
4367 Nlm_ChangeNotifyProc change_notify,
4368 Pointer change_userdata)
4369 {
4370 MultiSelectDialogPtr dlg;
4371 GrouP p;
4372 Int4 height;
4373 Int4 width;
4374 RecT r;
4375 ValNodePtr vnp;
4376
4377 if (choice_list == NULL)
4378 {
4379 return NULL;
4380 }
4381 dlg = (MultiSelectDialogPtr) MemNew (sizeof (MultiSelectDialogData));
4382 if (dlg == NULL)
4383 {
4384 return NULL;
4385 }
4386
4387 p = HiddenGroup (parent, -1, 0, NULL);
4388 SetObjectExtra (p, dlg, StdCleanupExtraProc);
4389
4390 dlg->dialog = (DialoG) p;
4391 dlg->todialog = DataToMultiSelectionDialog;
4392 dlg->fromdialog = MultiSelectionDialogToData;
4393 dlg->dialogmessage = NULL;
4394 dlg->testdialog = NULL;
4395
4396 dlg->selected_list = NULL;
4397 dlg->change_notify = change_notify;
4398 dlg->change_userdata = change_userdata;
4399
4400
4401 SelectFont (systemFont);
4402 width = 0;
4403 for (vnp = choice_list; vnp != NULL; vnp = vnp->next)
4404 {
4405 width = MAX (width, StringWidth (vnp->data.ptrvalue) + 2);
4406 }
4407
4408 dlg->num_choices = ValNodeLen (choice_list) + 1;
4409
4410 height = LineHeight ();
4411 dlg->doc = DocumentPanel (p, width, height * list_height);
4412 SetObjectExtra (dlg->doc, dlg, NULL);
4413
4414 dlg->listPar.openSpace = FALSE;
4415 dlg->listPar.keepWithNext = FALSE;
4416 dlg->listPar.keepTogether = FALSE;
4417 dlg->listPar.newPage = FALSE;
4418 dlg->listPar.tabStops = FALSE;
4419 dlg->listPar.minLines = 0;
4420 dlg->listPar.minHeight = 0;
4421
4422 ObjectRect (dlg->doc, &r);
4423 InsetRect (&r, 4, 4);
4424 dlg->listCol.pixWidth = r.right - r.left;
4425 dlg->listCol.pixInset = 0;
4426 dlg->listCol.charWidth = 160;
4427 dlg->listCol.charInset = 0;
4428 dlg->listCol.font = systemFont;
4429 dlg->listCol.just = 'l';
4430 dlg->listCol.wrap = FALSE;
4431 dlg->listCol.bar = FALSE;
4432 dlg->listCol.underline = FALSE;
4433 dlg->listCol.left = FALSE;
4434 dlg->listCol.last = TRUE;
4435
4436 AppendText (dlg->doc, "All", &(dlg->listPar), &(dlg->listCol), programFont);
4437 for (vnp = choice_list; vnp != NULL; vnp = vnp->next)
4438 {
4439 AppendText (dlg->doc, vnp->data.ptrvalue, &(dlg->listPar), &(dlg->listCol), programFont);
4440 }
4441 SetDocAutoAdjust (dlg->doc, FALSE);
4442 SetDocProcs (dlg->doc, SelectChoice, NULL, NULL, NULL);
4443 SetDocShade (dlg->doc, NULL, NULL, ChoiceHighlight, NULL);
4444 SetSlateChar ((SlatE) dlg->doc, ChoiceOnKey);
4445 InvalDocument (dlg->doc);
4446
4447 return (DialoG) p;
4448 }
4449
4450 typedef struct selectiondialog
4451 {
4452 DIALOG_MESSAGE_BLOCK
4453 DialoG multi_select_dlg;
4454 LisT list_ctrl;
4455 PopuP popup_ctrl;
4456 Int4 num_choices;
4457 CharPtr err_msg;
4458 Nlm_ChangeNotifyProc change_notify;
4459 Pointer change_userdata;
4460 } SelectionDialogData, PNTR SelectionDialogPtr;
4461
4462 static void ResetSelectionDialog (SelectionDialogPtr dlg)
4463 {
4464 if (dlg != NULL)
4465 {
4466 if (dlg->multi_select_dlg != NULL)
4467 {
4468 PointerToDialog (dlg->multi_select_dlg, NULL);
4469 }
4470 else if (dlg->list_ctrl != NULL)
4471 {
4472 SetValue (dlg->list_ctrl, 0);
4473 }
4474 else if (dlg->popup_ctrl != NULL)
4475 {
4476 SetValue (dlg->popup_ctrl, 0);
4477 }
4478 }
4479 }
4480
4481 static void SelectionDialogChanged (LisT l)
4482 {
4483 SelectionDialogPtr dlg;
4484
4485 dlg = (SelectionDialogPtr) GetObjectExtra (l);
4486 if (dlg == NULL)
4487 {
4488 return;
4489 }
4490
4491 if (dlg->change_notify != NULL)
4492 {
4493 (dlg->change_notify)(dlg->change_userdata);
4494 }
4495 }
4496
4497 static void SelectionDialogPopupChanged (PopuP p)
4498 {
4499 SelectionDialogPtr dlg;
4500
4501 dlg = (SelectionDialogPtr) GetObjectExtra (p);
4502 if (dlg == NULL)
4503 {
4504 return;
4505 }
4506
4507 if (dlg->change_notify != NULL)
4508 {
4509 (dlg->change_notify)(dlg->change_userdata);
4510 }
4511 }
4512
4513 static void SelectionListToSelectionDialog (DialoG d, Pointer userdata)
4514 {
4515 SelectionDialogPtr dlg;
4516 ValNodePtr selected_list;
4517
4518 dlg = (SelectionDialogPtr) GetObjectExtra (d);
4519 if (dlg == NULL)
4520 {
4521 return;
4522 }
4523
4524 ResetSelectionDialog (dlg);
4525 selected_list = (ValNodePtr) userdata;
4526 if (dlg->multi_select_dlg != NULL)
4527 {
4528 PointerToDialog (dlg->multi_select_dlg, selected_list);
4529 }
4530 else if (dlg->list_ctrl != NULL)
4531 {
4532 if (selected_list == NULL)
4533 {
4534 SetValue (dlg->list_ctrl, 0);
4535 }
4536 else
4537 {
4538 SetValue (dlg->list_ctrl, selected_list->data.intvalue);
4539 }
4540 }
4541 else if (dlg->popup_ctrl)
4542 {
4543 if (selected_list == NULL)
4544 {
4545 SetValue (dlg->popup_ctrl, 0);
4546 }
4547 else
4548 {
4549 SetValue (dlg->popup_ctrl, selected_list->data.intvalue);
4550 }
4551 }
4552 }
4553
4554
4555 static Pointer SelectionDialogToSelectionList (DialoG d)
4556 {
4557 SelectionDialogPtr dlg;
4558 ValNodePtr sel_list = NULL, vnp;
4559 Int4 i = 0;
4560
4561 dlg = (SelectionDialogPtr) GetObjectExtra (d);
4562 if (dlg == NULL)
4563 {
4564 return NULL;
4565 }
4566
4567 if (dlg->multi_select_dlg != NULL)
4568 {
4569 sel_list = (ValNodePtr) DialogToPointer (dlg->multi_select_dlg);
4570 if (sel_list != NULL && sel_list->choice == 1)
4571 {
4572 sel_list = ValNodeFree (sel_list);
4573 for (i = 2; i <= dlg->num_choices; i++)
4574 {
4575 ValNodeAddInt (&sel_list, 0, i - 1);
4576 }
4577 }
4578 else
4579 {
4580 for (vnp = sel_list; vnp != NULL; vnp = vnp->next)
4581 {
4582 vnp->choice = 0;
4583 vnp->data.intvalue = vnp->data.intvalue - 1;
4584 }
4585 }
4586 }
4587 else
4588 {
4589 if (dlg->list_ctrl != NULL)
4590 {
4591 i = GetValue (dlg->list_ctrl);
4592 }
4593 else if (dlg->popup_ctrl != NULL)
4594 {
4595 i = GetValue (dlg->popup_ctrl);
4596 }
4597 if (i > 0)
4598 {
4599 ValNodeAddInt (&sel_list, 0, i);
4600 }
4601 }
4602 return (Pointer) sel_list;
4603 }
4604
4605 static void SelectionDialogMessage (DialoG d, Int2 mssg)
4606
4607 {
4608 SelectionDialogPtr dlg;
4609 ValNode vn;
4610
4611 dlg = (SelectionDialogPtr) GetObjectExtra (d);
4612 if (dlg != NULL) {
4613 switch (mssg) {
4614 case VIB_MSG_INIT :
4615 /* reset list */
4616 ResetSelectionDialog (dlg);
4617 break;
4618 case VIB_MSG_ENTER :
4619 if (dlg->multi_select_dlg != NULL)
4620 {
4621 Select (dlg->multi_select_dlg);
4622 }
4623 else if (dlg->list_ctrl != NULL)
4624 {
4625 Select (dlg->list_ctrl);
4626 }
4627 else if (dlg->popup_ctrl != NULL)
4628 {
4629 Select (dlg->popup_ctrl);
4630 }
4631 break;
4632 case NUM_VIB_MSG + 1:
4633 if (dlg->multi_select_dlg != NULL)
4634 {
4635 vn.next = NULL;
4636 vn.choice = 1;
4637 vn.data.intvalue = 1;
4638 PointerToDialog (dlg->multi_select_dlg, &vn);
4639 }
4640 else if (dlg->list_ctrl != NULL)
4641 {
4642 SetItemStatus (dlg->list_ctrl, 1, TRUE);
4643 }
4644 else if (dlg->popup_ctrl != NULL)
4645 {
4646 SetValue (dlg->popup_ctrl, 1);
4647 }
4648 SelectionDialogChanged (dlg->list_ctrl);
4649 break;
4650 default :
4651 break;
4652 }
4653 }
4654 }
4655
4656 static ValNodePtr TestSelectionDialog (DialoG d)
4657
4658 {
4659 SelectionDialogPtr dlg;
4660 ValNodePtr head = NULL, vnp;
4661 Boolean any_selected = FALSE;
4662
4663 dlg = (SelectionDialogPtr) GetObjectExtra (d);
4664 if (dlg != NULL) {
4665 if (dlg->multi_select_dlg != NULL)
4666 {
4667 vnp = DialogToPointer (dlg->multi_select_dlg);
4668 if (vnp != NULL)
4669 {
4670 any_selected = TRUE;
4671 vnp = ValNodeFree (vnp);
4672 }
4673 }
4674 else if (dlg->list_ctrl != NULL)
4675 {
4676 if (GetValue (dlg->list_ctrl) > 0)
4677 {
4678 any_selected = TRUE;
4679 }
4680 }
4681 else if (dlg->popup_ctrl != NULL)
4682 {
4683 if (GetValue (dlg->popup_ctrl) > 0)
4684 {
4685 any_selected = TRUE;
4686 }
4687 }
4688 if (!any_selected)
4689 {
4690 head = AddStringToValNodeChain (head, dlg->err_msg, 1);
4691 }
4692 }
4693 return head;
4694 }
4695
4696 /* err_msg is the message to put in the results from TestDialog if nothing is selected */
4697 /* choice_list should be a valnode list of strings to use for the names of the choices. */
4698 /* All is automatically included as a choice if allow_multi is true. */
4699 /* The ValNodeList returned is a list of integers indicating the position of the item
4700 * in the list - 1 is the first item, 2 is the second item, etc. */
4701 extern DialoG SelectionDialogExEx
4702 (GrouP h,
4703 Nlm_ChangeNotifyProc change_notify,
4704 Pointer change_userdata,
4705 Boolean allow_multi,
4706 CharPtr err_msg,
4707 ValNodePtr choice_list,
4708 Int2 list_height,
4709 Boolean force_list,
4710 Boolean force_popup)
4711
4712 {
4713 SelectionDialogPtr dlg;
4714 GrouP p;
4715 ValNodePtr vnp;
4716 Int4 num_choices;
4717 Int4 list_width = 8, item_width;
4718
4719 if (choice_list == NULL)
4720 {
4721 return NULL;
4722 }
4723
4724 dlg = (SelectionDialogPtr) MemNew (sizeof (SelectionDialogData));
4725 if (dlg == NULL)
4726 {
4727 return NULL;
4728 }
4729
4730 p = HiddenGroup (h, 0, 2, NULL);
4731 SetObjectExtra (p, dlg, StdCleanupExtraProc);
4732
4733 dlg->dialog = (DialoG) p;
4734 dlg->todialog = SelectionListToSelectionDialog;
4735 dlg->fromdialog = SelectionDialogToSelectionList;
4736 dlg->dialogmessage = SelectionDialogMessage;
4737 dlg->testdialog = TestSelectionDialog;
4738 dlg->change_notify = change_notify;
4739 dlg->change_userdata = change_userdata;
4740 dlg->err_msg = err_msg;
4741
4742 num_choices = ValNodeLen (choice_list);
4743
4744 if (allow_multi)
4745 {
4746 dlg->multi_select_dlg = MultiSelectDialog (p, choice_list, list_height,
4747 change_notify, change_userdata);
4748 dlg->num_choices = num_choices + 1;
4749 }
4750 else
4751 {
4752 if (force_popup || (num_choices < 20 && ! force_list) || list_height == 1)
4753 {
4754 dlg->popup_ctrl = PopupList (p, TRUE, SelectionDialogPopupChanged);
4755 SetObjectExtra (dlg->popup_ctrl, dlg, NULL);
4756 for (vnp = choice_list; vnp != NULL; vnp = vnp->next) {
4757 PopupItem (dlg->popup_ctrl, vnp->data.ptrvalue);
4758 }
4759 }
4760 else
4761 {
4762 SelectFont (systemFont);
4763 for (vnp = choice_list; vnp != NULL; vnp = vnp->next) {
4764 item_width = StringWidth (vnp->data.ptrvalue);
4765 list_width = MAX (list_width, item_width);
4766 }
4767 /* add padding */
4768 list_width += StringWidth ("W");
4769 list_width = list_width / Nlm_stdCharWidth;
4770 dlg->list_ctrl = SingleList (p, list_width, list_height, SelectionDialogChanged);
4771 SetObjectExtra (dlg->list_ctrl, dlg, NULL);
4772 for (vnp = choice_list; vnp != NULL; vnp = vnp->next) {
4773 ListItem (dlg->list_ctrl, vnp->data.ptrvalue);
4774 }
4775 }
4776 dlg->num_choices = num_choices;
4777 }
4778
4779 return (DialoG) p;
4780 }
4781
4782
4783 extern DialoG SelectionDialogEx
4784 (GrouP h,
4785 Nlm_ChangeNotifyProc change_notify,
4786 Pointer change_userdata,
4787 Boolean allow_multi,
4788 CharPtr err_msg,
4789 ValNodePtr choice_list,
4790 Int2 list_height,
4791 Boolean force_list)
4792
4793 {
4794 return SelectionDialogExEx (h, change_notify, change_userdata, allow_multi, err_msg, choice_list, list_height, force_list, FALSE);
4795 }
4796
4797
4798 extern DialoG SelectionDialog
4799 (GrouP h,
4800 Nlm_ChangeNotifyProc change_notify,
4801 Pointer change_userdata,
4802 Boolean allow_multi,
4803 CharPtr err_msg,
4804 ValNodePtr choice_list,
4805 Int2 list_height)
4806 {
4807 return SelectionDialogEx (h, change_notify, change_userdata, allow_multi,
4808 err_msg, choice_list, list_height, FALSE);
4809 }
4810
4811 typedef struct valnodeselection
4812 {
4813 DIALOG_MESSAGE_BLOCK
4814 DialoG list_dlg;
4815 ValNodePtr choice_list;
4816
4817 Boolean is_multi;
4818 FreeValNodeProc free_vn_proc;
4819 CopyValNodeDataProc copy_vn_proc;
4820 MatchValNodeProc match_vn_proc;
4821 RemapValNodeProc remap_vn_proc;
4822
4823 } ValNodeSelectionData, PNTR ValNodeSelectionPtr;
4824
4825 static void ValNodeSelectionListToDialog (DialoG d, Pointer userdata)
4826 {
4827 ValNodeSelectionPtr dlg;
4828 ValNodePtr item_list, vnp_list, vnp_sel, pos_list = NULL;
4829 Int4 i;
4830 Boolean found;
4831
4832 dlg = (ValNodeSelectionPtr) GetObjectExtra (d);
4833 if (dlg == NULL)
4834 {
4835 return;
4836 }
4837
4838 /* reset list control */
4839 PointerToDialog (dlg->list_dlg, NULL);
4840
4841 item_list = (ValNodePtr) userdata;
4842 for (vnp_list = item_list; vnp_list != NULL; vnp_list = vnp_list->next)
4843 {
4844 found = FALSE;
4845 i = 1;
4846 if (dlg->is_multi) {
4847 i++;
4848 }
4849 for (vnp_sel = dlg->choice_list;
4850 vnp_sel != NULL && !found;
4851 vnp_sel = vnp_sel->next, i++)
4852 {
4853 if ((dlg->match_vn_proc)(vnp_sel, vnp_list))
4854 {
4855 found = TRUE;
4856 ValNodeAddInt (&pos_list, 0, i);
4857 }
4858 }
4859 }
4860 PointerToDialog (dlg->list_dlg, pos_list);
4861 ValNodeFree (pos_list);
4862 }
4863
4864 static Pointer ValNodeSelectionDialogToList (DialoG d)
4865 {
4866 ValNodeSelectionPtr dlg;
4867 ValNodePtr item_list = NULL, vnp_list, pos_list, vnp_pos;
4868 ValNodePtr vnp_copy, vnp_last = NULL, vnp_test;
4869 Int4 i;
4870 Boolean found;
4871
4872 dlg = (ValNodeSelectionPtr) GetObjectExtra (d);
4873 if (dlg == NULL)
4874 {
4875 return NULL;
4876 }
4877
4878 pos_list = DialogToPointer (dlg->list_dlg);
4879 for (vnp_pos = pos_list; vnp_pos != NULL; vnp_pos = vnp_pos->next)
4880 {
4881 for (i = 1, vnp_list = dlg->choice_list;
4882 i < vnp_pos->data.intvalue && vnp_list != NULL;
4883 i++, vnp_list = vnp_list->next)
4884 {
4885 }
4886 if (i == vnp_pos->data.intvalue && vnp_list != NULL)
4887 {
4888 /* make sure we don't already have this value in the list */
4889 for (vnp_test = item_list, found = FALSE;
4890 vnp_test != NULL && !found;
4891 vnp_test = vnp_test->next)
4892 {
4893 found = (dlg->match_vn_proc) (vnp_list, vnp_test);
4894 }
4895
4896 if (found)
4897 {
4898 continue;
4899 }
4900 vnp_copy = (dlg->copy_vn_proc) (vnp_list);
4901 if (vnp_last == NULL)
4902 {
4903 item_list = vnp_copy;
4904 }
4905 else
4906 {
4907 vnp_last->next = vnp_copy;
4908 }
4909 vnp_last = vnp_copy;
4910 }
4911 }
4912 if (dlg->remap_vn_proc != NULL)
4913 {
4914 item_list = (dlg->remap_vn_proc) (item_list);
4915 }
4916 return item_list;
4917 }
4918
4919 static void CleanupValNodeSelectionDialogForm (GraphiC g, VoidPtr data)
4920
4921 {
4922 ValNodeSelectionPtr dlg;
4923 ValNodePtr vnp;
4924
4925 dlg = (ValNodeSelectionPtr) data;
4926 if (dlg != NULL) {
4927 if (dlg->free_vn_proc != NULL)
4928 {
4929 for (vnp = dlg->choice_list; vnp != NULL; vnp = vnp->next)
4930 {
4931 (dlg->free_vn_proc) (vnp);
4932 }
4933 }
4934 dlg->choice_list = ValNodeFree (dlg->choice_list);
4935 }
4936 StdCleanupExtraProc (g, data);
4937 }
4938
4939 static void ValNodeSelectionDialogMessage (DialoG d, Int2 mssg)
4940
4941 {
4942 ValNodeSelectionPtr dlg;
4943
4944 dlg = (ValNodeSelectionPtr) GetObjectExtra (d);
4945 if (dlg != NULL) {
4946 switch (mssg) {
4947 case VIB_MSG_INIT :
4948 /* reset list */
4949 PointerToDialog (dlg->list_dlg, NULL);
4950 break;
4951 case VIB_MSG_SELECT:
4952 Select (dlg->list_dlg);
4953 break;
4954 case VIB_MSG_ENTER :
4955 Select (dlg->list_dlg);
4956 break;
4957 case NUM_VIB_MSG + 1:
4958 SendMessageToDialog (dlg->list_dlg, NUM_VIB_MSG + 1);
4959 break;
4960 default :
4961 break;
4962 }
4963 }
4964 }
4965
4966 static ValNodePtr TestValNodeSelectionDialog (DialoG d)
4967
4968 {
4969 ValNodeSelectionPtr dlg;
4970 ValNodePtr head = NULL;
4971
4972 dlg = (ValNodeSelectionPtr) GetObjectExtra (d);
4973 if (dlg != NULL) {
4974 head = TestDialog (dlg->list_dlg);
4975 }
4976 return head;
4977 }
4978
4979 extern DialoG ValNodeSelectionDialogExEx
4980 (GrouP h,
4981 ValNodePtr choice_list,
4982 Int2 list_height,
4983 NameFromValNodeProc name_proc,
4984 FreeValNodeProc free_vn_proc,
4985 CopyValNodeDataProc copy_vn_proc,
4986 MatchValNodeProc match_vn_proc,
4987 CharPtr err_name,
4988 Nlm_ChangeNotifyProc change_notify,
4989 Pointer change_userdata,
4990 Boolean allow_multi,
4991 Boolean force_list,
4992 Boolean force_popup,
4993 RemapValNodeProc remap_vn_proc)
4994 {
4995 ValNodeSelectionPtr dlg;
4996 GrouP p;
4997 ValNodePtr choice_name_list = NULL, vnp;
4998
4999 if (choice_list == NULL || name_proc == NULL
5000 || copy_vn_proc == NULL || match_vn_proc == NULL)
5001 {
5002 return NULL;
5003 }
5004
5005 dlg = (ValNodeSelectionPtr) MemNew (sizeof (ValNodeSelectionData));
5006 if (dlg == NULL)
5007 {
5008 return NULL;
5009 }
5010
5011 p = HiddenGroup (h, 1, 0, NULL);
5012 SetObjectExtra (p, dlg, CleanupValNodeSelectionDialogForm);
5013
5014 dlg->dialog = (DialoG) p;
5015 dlg->todialog = ValNodeSelectionListToDialog;
5016 dlg->fromdialog = ValNodeSelectionDialogToList;
5017 dlg->dialogmessage = ValNodeSelectionDialogMessage;
5018 dlg->testdialog = TestValNodeSelectionDialog;
5019
5020 dlg->choice_list = choice_list;
5021 dlg->free_vn_proc = free_vn_proc;
5022 dlg->copy_vn_proc = copy_vn_proc;
5023 dlg->match_vn_proc = match_vn_proc;
5024 dlg->remap_vn_proc = remap_vn_proc;
5025
5026 dlg->is_multi = allow_multi;
5027
5028 for (vnp = choice_list; vnp != NULL; vnp = vnp->next)
5029 {
5030 ValNodeAddPointer (&choice_name_list, 0, (name_proc) (vnp));
5031 }
5032
5033 dlg->list_dlg = SelectionDialogExEx (p, change_notify, change_userdata,
5034 allow_multi, err_name, choice_name_list,
5035 list_height, force_list, force_popup);
5036 ValNodeFreeData (choice_name_list);
5037
5038 return (DialoG) p;
5039 }
5040
5041
5042 extern DialoG ValNodeSelectionDialogEx
5043 (GrouP h,
5044 ValNodePtr choice_list,
5045 Int2 list_height,
5046 NameFromValNodeProc name_proc,
5047 FreeValNodeProc free_vn_proc,
5048 CopyValNodeDataProc copy_vn_proc,
5049 MatchValNodeProc match_vn_proc,
5050 CharPtr err_name,
5051 Nlm_ChangeNotifyProc change_notify,
5052 Pointer change_userdata,
5053 Boolean allow_multi,
5054 Boolean force_list,
5055 RemapValNodeProc remap_vn_proc)
5056 {
5057 return ValNodeSelectionDialogExEx (h, choice_list, list_height, name_proc, free_vn_proc, copy_vn_proc,
5058 match_vn_proc, err_name, change_notify, change_userdata, allow_multi,
5059 force_list, FALSE, remap_vn_proc);
5060 }
5061
5062
5063 extern DialoG ValNodeSelectionDialog
5064 (GrouP h,
5065 ValNodePtr choice_list,
5066 Int2 list_height,
5067 NameFromValNodeProc name_proc,
5068 FreeValNodeProc free_vn_proc,
5069 CopyValNodeDataProc copy_vn_proc,
5070 MatchValNodeProc match_vn_proc,
5071 CharPtr err_name,
5072 Nlm_ChangeNotifyProc change_notify,
5073 Pointer change_userdata,
5074 Boolean allow_multi)
5075 {
5076 return ValNodeSelectionDialogEx (h, choice_list, list_height,
5077 name_proc, free_vn_proc,
5078 copy_vn_proc, match_vn_proc, err_name,
5079 change_notify, change_userdata,
5080 allow_multi, FALSE, NULL);
5081 }
5082
5083 extern DialoG EnumAssocSelectionDialog
5084 (GrouP h,
5085 Nlm_EnumFieldAssocPtr eap,
5086 CharPtr err_name,
5087 Boolean allow_multi,
5088 Nlm_ChangeNotifyProc change_notify,
5089 Pointer change_userdata)
5090
5091 {
5092 DialoG dlg;
5093 ValNodePtr choice_list = NULL;
5094
5095 if (eap == NULL)
5096 {
5097 return NULL;
5098 }
5099
5100 while (eap->name != NULL)
5101 {
5102 if (!StringHasNoText (eap->name))
5103 {
5104 ValNodeAddPointer (&choice_list, eap->value, StringSave (eap->name));
5105 }
5106 eap++;
5107 }
5108
5109 /* note - the ValNodeSelectionDialog will free the qual_choice_list when done */
5110 dlg = ValNodeSelectionDialog (h, choice_list, TALL_SELECTION_LIST, ValNodeStringName,
5111 ValNodeSimpleDataFree, ValNodeStringCopy,
5112 ValNodeChoiceMatch, err_name,
5113 change_notify, change_userdata, allow_multi);
5114
5115 return dlg;
5116 }
5117
5118 extern CharPtr ValNodeStringName (ValNodePtr vnp)
5119 {
5120 if (vnp == NULL || vnp->data.ptrvalue == NULL)
5121 {
5122 return NULL;
5123 }
5124 else
5125 {
5126 return StringSave (vnp->data.ptrvalue);
5127 }
5128 }
5129
5130 extern void ValNodeSimpleDataFree (ValNodePtr vnp)
5131 {
5132 if (vnp != NULL && vnp->data.ptrvalue != NULL)
5133 {
5134 vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
5135 }
5136 }
5137
5138 extern ValNodePtr ValNodeStringCopy (ValNodePtr vnp)
5139 {
5140 ValNodePtr vnp_copy = NULL;
5141 if (vnp != NULL)
5142 {
5143 ValNodeAddPointer (&vnp_copy, vnp->choice, StringSave (vnp->data.ptrvalue));
5144 }
5145 return vnp_copy;
5146 }
5147
5148 extern Boolean ValNodeChoiceMatch (ValNodePtr vnp1, ValNodePtr vnp2)
5149 {
5150 if (vnp1 == NULL || vnp2 == NULL)
5151 {
5152 return FALSE;
5153 }
5154 if (vnp1->choice == vnp2->choice)
5155 {
5156 return TRUE;
5157 }
5158 else
5159 {
5160 return FALSE;
5161 }
5162 }
5163
5164 extern Boolean ValNodeStringMatch (ValNodePtr vnp1, ValNodePtr vnp2)
5165 {
5166 if (vnp1 == NULL || vnp2 == NULL)
5167 {
5168 return FALSE;
5169 }
5170 if (StringCmp (vnp1->data.ptrvalue, vnp2->data.ptrvalue) == 0)
5171 {
5172 return TRUE;
5173 }
5174 else
5175 {
5176 return FALSE;
5177 }
5178 }
5179
5180 typedef struct sequenceselection
5181 {
5182 DIALOG_MESSAGE_BLOCK
5183 DialoG sequence_list_dlg;
5184 ValNodePtr sequence_choice_list;
5185 } SequenceSelectionData, PNTR SequenceSelectionPtr;
5186
5187 static void CleanupSequenceSelectionDialogForm (GraphiC g, VoidPtr data)
5188
5189 {
5190 SequenceSelectionPtr dlg;
5191
5192 dlg = (SequenceSelectionPtr) data;
5193 if (dlg != NULL) {
5194 dlg->sequence_choice_list = ValNodeFree (dlg->sequence_choice_list);
5195 }
5196 StdCleanupExtraProc (g, data);
5197 }
5198
5199 static void ResetSequenceSelectionDialog (SequenceSelectionPtr dlg)
5200 {
5201 if (dlg != NULL)
5202 {
5203 PointerToDialog (dlg->sequence_list_dlg, NULL);
5204 }
5205 }
5206
5207 static void SequenceSelectionListToSequenceSelectionDialog (DialoG d, Pointer userdata)
5208 {
5209 SequenceSelectionPtr dlg;
5210 ValNodePtr sequence_list, vnp_list, vnp_sel, pos_list = NULL;
5211 Int4 i;
5212 SeqIdPtr sip;
5213 Boolean found;
5214
5215 dlg = (SequenceSelectionPtr) GetObjectExtra (d);
5216 if (dlg == NULL)
5217 {
5218 return;
5219 }
5220
5221 ResetSequenceSelectionDialog (dlg);
5222 sequence_list = (ValNodePtr) userdata;
5223 for (vnp_list = sequence_list; vnp_list != NULL; vnp_list = vnp_list->next)
5224 {
5225 sip = (SeqIdPtr) vnp_list->data.ptrvalue;
5226 found = FALSE;
5227 while (sip != NULL && ! found)
5228 {
5229 for (vnp_sel = dlg->sequence_choice_list, i = 1;
5230 vnp_sel != NULL && !found;
5231 vnp_sel = vnp_sel->next, i++)
5232 {
5233 found = SeqIdIn (sip, vnp_sel->data.ptrvalue);
5234 if (found)
5235 {
5236 ValNodeAddInt (&pos_list, 0, i);
5237 }
5238 }
5239 sip = sip->next;
5240 }
5241 }
5242 PointerToDialog (dlg->sequence_list_dlg, pos_list);
5243 ValNodeFree (pos_list);
5244 }
5245
5246 static Pointer SequenceSelectionDialogToSequenceSelectionList (DialoG d)
5247 {
5248 SequenceSelectionPtr dlg;
5249 ValNodePtr sequence_list = NULL, vnp_list, pos_list, vnp_pos;
5250 Int4 i;
5251
5252 dlg = (SequenceSelectionPtr) GetObjectExtra (d);
5253 if (dlg == NULL)
5254 {
5255 return NULL;
5256 }
5257
5258 pos_list = DialogToPointer (dlg->sequence_list_dlg);
5259 for (vnp_pos = pos_list; vnp_pos != NULL; vnp_pos = vnp_pos->next)
5260 {
5261 for (i = 1, vnp_list = dlg->sequence_choice_list;
5262 i < vnp_pos->data.intvalue && vnp_list != NULL;
5263 i++, vnp_list = vnp_list->next)
5264 {
5265 }
5266 if (i == vnp_pos->data.intvalue && vnp_list != NULL)
5267 {
5268 ValNodeAddPointer (&sequence_list, 0, vnp_list->data.ptrvalue);
5269 }
5270 }
5271 return sequence_list;
5272 }
5273
5274 static void
5275 GetSequenceChoiceList
5276 (SeqEntryPtr sep,
5277 ValNodePtr PNTR list,
5278 Boolean show_nucs,
5279 Boolean show_prots)
5280 {
5281 BioseqPtr bsp;
5282 BioseqSetPtr bssp;
5283
5284 if (sep == NULL) return;
5285
5286 if (IS_Bioseq (sep))
5287 {
5288 bsp = (BioseqPtr) sep->data.ptrvalue;
5289 if (bsp == NULL) return;
5290 if (!show_nucs && ISA_na (bsp->mol))
5291 {
5292 return;
5293 }
5294 if (!show_prots && ISA_aa (bsp->mol))
5295 {
5296 return;
5297 }
5298 ValNodeAddPointer (list, 0, bsp->id);
5299 }
5300 else
5301 {
5302 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5303 for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
5304 {
5305 GetSequenceChoiceList (sep, list, show_nucs, show_prots);
5306 }
5307 }
5308 }
5309
5310 static void SequenceSelectionDialogMessage (DialoG d, Int2 mssg)
5311
5312 {
5313 SequenceSelectionPtr dlg;
5314
5315 dlg = (SequenceSelectionPtr) GetObjectExtra (d);
5316 if (dlg != NULL) {
5317 switch (mssg) {
5318 case VIB_MSG_INIT :
5319 /* reset list */
5320 ResetSequenceSelectionDialog (dlg);
5321 break;
5322 case VIB_MSG_SELECT:
5323 Select (dlg->sequence_list_dlg);
5324 break;
5325 case VIB_MSG_ENTER :
5326 Select (dlg->sequence_list_dlg);
5327 break;
5328 case NUM_VIB_MSG + 1:
5329 SendMessageToDialog (dlg->sequence_list_dlg, NUM_VIB_MSG + 1);
5330 break;
5331 default :
5332 break;
5333 }
5334 }
5335 }
5336
5337 static ValNodePtr TestSequenceSelectionDialog (DialoG d)
5338
5339 {
5340 SequenceSelectionPtr dlg;
5341 ValNodePtr head = NULL;
5342
5343 dlg = (SequenceSelectionPtr) GetObjectExtra (d);
5344 if (dlg != NULL) {
5345 head = TestDialog (dlg->sequence_list_dlg);
5346 }
5347 return head;
5348 }
5349
5350
5351 extern DialoG SequenceSelectionDialogEx
5352 (GrouP h,
5353 Nlm_ChangeNotifyProc change_notify,
5354 Pointer change_userdata,
5355 Boolean allow_multi,
5356 Boolean allow_none,
5357 Boolean show_nucs,
5358 Boolean show_prots,
5359 Uint2 entityID,
5360 Int4 list_height)
5361
5362 {
5363 SequenceSelectionPtr dlg;
5364 GrouP p;
5365 ValNodePtr vnp;
5366 SeqEntryPtr sep;
5367 SeqIdPtr sip;
5368 Char tmp[128];
5369 ValNodePtr choice_name_list = NULL;
5370
5371 if (!show_nucs && ! show_prots)
5372 {
5373 return NULL;
5374 }
5375
5376 sep = GetTopSeqEntryForEntityID (entityID);
5377 if (sep == NULL)
5378 {
5379 return NULL;
5380 }
5381
5382 dlg = (SequenceSelectionPtr) MemNew (sizeof (SequenceSelectionData));
5383 if (dlg == NULL)
5384 {
5385 return NULL;
5386 }
5387
5388 p = HiddenGroup (h, 1, 0, NULL);
5389 SetObjectExtra (p, dlg, CleanupSequenceSelectionDialogForm);
5390
5391 dlg->dialog = (DialoG) p;
5392 dlg->todialog = SequenceSelectionListToSequenceSelectionDialog;
5393 dlg->fromdialog = SequenceSelectionDialogToSequenceSelectionList;
5394 dlg->dialogmessage = SequenceSelectionDialogMessage;
5395 dlg->testdialog = TestSequenceSelectionDialog;
5396
5397 if (allow_none) {
5398 dlg->sequence_choice_list = ValNodeNew (NULL);
5399 dlg->sequence_choice_list->choice = 0;
5400 dlg->sequence_choice_list->data.ptrvalue = NULL;
5401 } else {
5402 dlg->sequence_choice_list = NULL;
5403 }
5404 GetSequenceChoiceList (sep, &dlg->sequence_choice_list, show_nucs, show_prots);
5405
5406
5407 for (vnp = dlg->sequence_choice_list; vnp != NULL; vnp = vnp->next) {
5408 sip = SeqIdFindWorst ((SeqIdPtr) vnp->data.ptrvalue);
5409 if (sip == NULL) {
5410 sprintf (tmp, " ");
5411 } else {
5412 SeqIdWrite (sip, tmp, PRINTID_REPORT, sizeof (tmp));
5413 }
5414 ValNodeAddPointer (&choice_name_list, 0, StringSave (tmp));
5415 }
5416
5417 dlg->sequence_list_dlg = SelectionDialog (p, change_notify, change_userdata,
5418 allow_multi, "sequence",
5419 choice_name_list, list_height);
5420 ValNodeFreeData (choice_name_list);
5421 return (DialoG) p;
5422 }
5423
5424
5425 extern DialoG SequenceSelectionDialog
5426 (GrouP h,
5427 Nlm_ChangeNotifyProc change_notify,
5428 Pointer change_userdata,
5429 Boolean allow_multi,
5430 Boolean show_nucs,
5431 Boolean show_prots,
5432 Uint2 entityID)
5433 {
5434 return SequenceSelectionDialogEx (h, change_notify, change_userdata, allow_multi, FALSE, show_nucs, show_prots, entityID, TALL_SELECTION_LIST);
5435 }
5436
5437
5438 extern DialoG SubSourceTypeDialog
5439 (GrouP h,
5440 Int2 list_height,
5441 Nlm_ChangeNotifyProc change_notify,
5442 Pointer change_userdata,
5443 Boolean allow_multi,
5444 Boolean force_list,
5445 Boolean include_note)
5446 {
5447 ValNodePtr subsource_list = NULL;
5448 Int4 i;
5449
5450 for (i = 0; current_subsource_subtype_alist[i].name != NULL; i++) {
5451 ValNodeAddPointer (&subsource_list, current_subsource_subtype_alist[i].value, StringSave (current_subsource_subtype_alist[i].name));
5452 }
5453 if (include_note) {
5454 ValNodeAddPointer (&subsource_list, SUBSRC_other, StringSave ("Note"));
5455 }
5456
5457 return ValNodeSelectionDialogEx (h, subsource_list, list_height,
5458 ValNodeStringName,
5459 ValNodeSimpleDataFree,
5460 ValNodeStringCopy,
5461 ValNodeChoiceMatch, "subsource list",
5462 change_notify, change_userdata, allow_multi, force_list, NULL);
5463 }
5464
5465
5466 extern DialoG OrgModTypeDialog
5467 (GrouP h,
5468 Int2 list_height,
5469 Nlm_ChangeNotifyProc change_notify,
5470 Pointer change_userdata,
5471 Boolean allow_multi,
5472 Boolean force_list,
5473 Boolean include_note)
5474 {
5475 ValNodePtr orgmod_list = NULL;
5476 Int4 i;
5477
5478 for (i = 0; current_orgmod_subtype_alist[i].name != NULL; i++) {
5479 ValNodeAddPointer (&orgmod_list, current_orgmod_subtype_alist[i].value, StringSave (current_orgmod_subtype_alist[i].name));
5480 }
5481 if (include_note) {
5482 ValNodeAddPointer (&orgmod_list, ORGMOD_other, StringSave ("Note"));
5483 }
5484
5485 return ValNodeSelectionDialogEx (h, orgmod_list, list_height,
5486 ValNodeStringName,
5487 ValNodeSimpleDataFree,
5488 ValNodeStringCopy,
5489 ValNodeChoiceMatch, "orgmod list",
5490 change_notify, change_userdata, allow_multi, force_list, NULL);
5491 }
5492
5493
5494 /*
5495 static CharPtr inferencePrefix [] = {
5496 "",
5497 "similar to sequence",
5498 "similar to AA sequence",
5499 "similar to DNA sequence",
5500 "similar to RNA sequence",
5501 "similar to RNA sequence, mRNA",
5502 "similar to RNA sequence, EST",
5503 "similar to RNA sequence, other RNA",
5504 "profile",
5505 "nucleotide motif",
5506 "protein motif",
5507 "ab initio prediction",
5508 NULL
5509 };
5510
5511 ENUM_ALIST(inference_alist)
5512 { " ", 0 },
5513 { "similar to sequence", 1 },
5514 { "similar to protein", 2 },
5515 { "similar to DNA", 3 },
5516 { "similar to RNA", 4 },
5517 { "similar to mRNA", 5 },
5518 { "similar to EST", 6 },
5519 { "similar to other RNA", 7 },
5520 { "profile", 8 },
5521 { "nucleotide motif", 9 },
5522 { "protein motif", 10 },
5523 { "ab initio prediction", 11 },
5524 END_ENUM_ALIST
5525
5526 Uint2 inference_types [] = {
5527 TAGLIST_POPUP, TAGLIST_TEXT
5528 };
5529
5530 Uint2 inference_widths [] = {
5531 0, 0
5532 };
5533
5534 static EnumFieldAssocPtr inference_popups [] = {
5535 inference_alist, NULL
5536 };
5537
5538 extern void GBQualsToInferenceDialog (DialoG d, SeqFeatPtr sfp)
5539
5540 {
5541 Int2 best;
5542 Char ch;
5543 GBQualPtr gbq;
5544 ValNodePtr head = NULL;
5545 Int2 j;
5546 ValNodePtr last = NULL;
5547 size_t len;
5548 CharPtr rest;
5549 CharPtr str;
5550 TagListPtr tlp;
5551 Char tmp [32];
5552 ValNodePtr vnp;
5553
5554 tlp = (TagListPtr) GetObjectExtra (d);
5555 if (tlp == NULL) return;
5556
5557 if (sfp != NULL) {
5558 for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
5559 if (StringICmp (gbq->qual, "inference") != 0) continue;
5560 if (StringHasNoText (gbq->val)) continue;
5561 vnp = ValNodeNew (last);
5562 if (vnp == NULL) continue;
5563 if (head == NULL) {
5564 head = vnp;
5565 }
5566 last = vnp;
5567
5568 rest = NULL;
5569 best = -1;
5570 for (j = 0; inferencePrefix [j] != NULL; j++) {
5571 len = StringLen (inferencePrefix [j]);
5572 if (StringNICmp (gbq->val, inferencePrefix [j], len) != 0) continue;
5573 rest = gbq->val + len;
5574 best = j;
5575 }
5576 if (best >= 0 && inferencePrefix [best] != NULL) {
5577 if (rest != NULL) {
5578 ch = *rest;
5579 while (IS_WHITESP (ch) || ch == ':') {
5580 rest++;
5581 ch = *rest;
5582 }
5583 }
5584 len = StringLen (rest);
5585 str = MemNew (len + 16);
5586 if (str != NULL) {
5587 sprintf (tmp, "%d", (int) best);
5588 StringCpy (str, tmp);
5589 StringCat (str, "\t");
5590 StringCat (str, rest);
5591 StringCat (str, "\n");
5592 }
5593 vnp->data.ptrvalue = str;
5594 } else {
5595 len + StringLen (gbq->val);
5596 str = MemNew (len + 8);
5597 if (str != NULL) {
5598 StringCpy (str, "0");
5599 StringCat (str, "\t");
5600 StringCat (str, gbq->val);
5601 StringCat (str, "\n");
5602 }
5603 vnp->data.ptrvalue = str;
5604 }
5605 }
5606 }
5607
5608 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
5609 tlp->vnp = head;
5610 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
5611 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) continue;
5612 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
5613 CorrectBarMax (tlp->bar, tlp->max);
5614 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
5615 }
5616
5617 static void VisStringDialogToGbquals (SeqFeatPtr sfp, DialoG d, CharPtr qual)
5618
5619 {
5620 GBQualPtr gbq, gbqlast = NULL;
5621 ValNodePtr head = NULL, vnp;
5622 CharPtr str;
5623
5624 if (sfp == NULL || StringHasNoText (qual)) return;
5625 head = DialogToPointer (d);
5626 for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
5627 gbqlast = gbq;
5628 }
5629 for (vnp = head; vnp != NULL; vnp = vnp->next) {
5630 str = (CharPtr) vnp->data.ptrvalue;
5631 if (StringHasNoText (str)) continue;
5632 gbq = GBQualNew ();
5633 if (gbq == NULL) continue;
5634 gbq->qual = StringSave (qual);
5635 gbq->val = StringSave (str);
5636 if (gbqlast == NULL) {
5637 sfp->qual = gbq;
5638 } else {
5639 gbqlast->next = gbq;
5640 }
5641 gbqlast = gbq;
5642 }
5643 ValNodeFreeData (head);
5644 }
5645
5646 extern void InferenceDialogToGBQuals (DialoG d, SeqFeatPtr sfp)
5647
5648 {
5649 GBQualPtr gbq;
5650 GBQualPtr gbqlast = NULL;
5651 Int2 j;
5652 size_t len;
5653 CharPtr prefix;
5654 CharPtr ptr;
5655 CharPtr rest;
5656 CharPtr str;
5657 TagListPtr tlp;
5658 Int2 val;
5659 ValNodePtr vnp;
5660
5661 tlp = (TagListPtr) GetObjectExtra (d);
5662 if (tlp == NULL || sfp == NULL) return;
5663
5664 for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
5665 gbqlast = gbq;
5666 }
5667
5668 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
5669 if (StringHasNoText ((CharPtr) vnp->data.ptrvalue)) continue;
5670 ptr = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
5671 TrimSpacesAroundString (ptr);
5672 prefix = NULL;
5673 if (StrToInt (ptr, &val)) {
5674 for (j = 0; inferencePrefix [j] != NULL; j++) {
5675 if (j == val) {
5676 prefix = inferencePrefix [j];
5677 }
5678 }
5679 }
5680 MemFree (ptr);
5681 rest = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 1);
5682 TrimSpacesAroundString (rest);
5683 if (StringDoesHaveText (prefix)) {
5684 len = StringLen (prefix) + StringLen (rest);
5685 str = (CharPtr) MemNew (len + 8);
5686 if (str != NULL) {
5687 if (StringDoesHaveText (prefix)) {
5688 StringCpy (str, prefix);
5689 if (StringDoesHaveText (rest)) {
5690 if (StringNICmp (rest, "(same species)", 14) != 0) {
5691 StringCat (str, ":");
5692 } else {
5693 StringCat (str, " ");
5694 }
5695 }
5696 }
5697 if (StringDoesHaveText (rest)) {
5698 StringCat (str, rest);
5699 }
5700 gbq = GBQualNew ();
5701 if (gbq != NULL) {
5702 gbq->qual = StringSave ("inference");
5703 gbq->val = str;
5704 if (gbqlast == NULL) {
5705 sfp->qual = gbq;
5706 } else {
5707 gbqlast->next = gbq;
5708 }
5709 gbqlast = gbq;
5710 }
5711 }
5712 }
5713 MemFree (rest);
5714 }
5715 }
5716
5717 static DialoG CreateInferenceDialog (GrouP h, Uint2 rows, Int2 spacing, Int2 width)
5718
5719 {
5720 inference_widths [1] = width;
5721 return CreateTagListDialog (h, rows, 2, spacing,
5722 inference_types, inference_widths,
5723 inference_popups, NULL, NULL);
5724 }
5725 */
5726
5727 /* ************************ */
5728
5729 /* inference dialog controls, utility functions */
5730
5731 Uint2 accessionlist_types [] = {
5732 TAGLIST_POPUP, TAGLIST_TEXT
5733 };
5734
5735 Uint2 accessionlist_widths [] = {
5736 0, 10
5737 };
5738
5739 ENUM_ALIST(accn_type_alist)
5740 { " ", 0 },
5741 { "GenBank", 1 },
5742 { "EMBL", 2 },
5743 { "DDBJ", 3 },
5744 { "INSD", 4 },
5745 { "RefSeq", 5 },
5746 { "UniProt", 6 },
5747 { "Other", 7 },
5748 END_ENUM_ALIST
5749
5750 static EnumFieldAssocPtr accessionlist_popups [] = {
5751 accn_type_alist, NULL
5752 };
5753
5754 static CharPtr accnTypePrefix [] = {
5755 "",
5756 "GenBank",
5757 "EMBL",
5758 "DDBJ",
5759 "INSD",
5760 "RefSeq",
5761 "UniProt",
5762 "?",
5763 NULL
5764 };
5765
5766 const Int4 numAccnTypePrefixes = sizeof (accnTypePrefix) / sizeof (CharPtr);
5767
5768 static Int4 GetAccnTypeNum (CharPtr str)
5769 {
5770 Int4 i;
5771
5772 if (StringHasNoText (str)) return 0;
5773
5774 for (i = 1; i < numAccnTypePrefixes; i++)
5775 {
5776 if (StringCmp (accnTypePrefix[i], str) == 0)
5777 {
5778 return i;
5779 }
5780 }
5781 return 0;
5782 }
5783
5784
5785 static CharPtr ValForOneAccession (CharPtr str)
5786 {
5787 CharPtr cp, val_buf = NULL;
5788 CharPtr val_fmt = "%d\t%s";
5789 Int4 db;
5790
5791 if (!StringHasNoText (str))
5792 {
5793 cp = StringChr (str, '|');
5794 if (cp == NULL)
5795 {
5796 if ((db = GetAccnTypeNum(str)) > 0)
5797 {
5798 val_buf = MemNew (sizeof (Char) * StringLen (val_fmt));
5799 sprintf (val_buf, val_fmt, db, " ");
5800 }
5801 else
5802 {
5803 val_buf = MemNew (sizeof (Char) * (StringLen (val_fmt) + StringLen (str)));
5804 sprintf (val_buf, val_fmt, 0, str);
5805 }
5806 }
5807 else
5808 {
5809 *cp = 0;
5810 db = GetAccnTypeNum (str);
5811 val_buf = MemNew (sizeof (Char) * (StringLen (val_fmt) + StringLen (cp + 1)));
5812 sprintf (val_buf, val_fmt, db, cp + 1);
5813 *cp = '|';
5814 }
5815 }
5816 return val_buf;
5817 }
5818
5819 static void AccessionListDataToDialog (DialoG d, Pointer data)
5820 {
5821 TagListPtr tlp;
5822 CharPtr str, cp, val_buf;
5823 ValNodePtr new_list = NULL, vnp;
5824 Int4 j;
5825 Int2 scroll_pos;
5826
5827 tlp = (TagListPtr) GetObjectExtra (d);
5828
5829 if (tlp == NULL) return;
5830 str = (CharPtr) data;
5831
5832 cp = StringChr (str, ',');
5833 while (cp != NULL)
5834 {
5835 *cp = 0;
5836 val_buf = ValForOneAccession (str);
5837 if (val_buf != NULL)
5838 {
5839 ValNodeAddPointer (&new_list, 0, val_buf);
5840 }
5841 *cp = ',';
5842 str = cp + 1;
5843 cp = StringChr (str, ',');
5844 }
5845 val_buf = ValForOneAccession (str);
5846 if (val_buf != NULL)
5847 {
5848 ValNodeAddPointer (&new_list, 0, val_buf);
5849 }
5850
5851 scroll_pos = 0;
5852 if (tlp->bar != NULL)
5853 {
5854 scroll_pos = GetBarValue (tlp->bar);
5855 }
5856 else if (tlp->left_bar != NULL)
5857 {
5858 scroll_pos = GetBarValue (tlp->left_bar);
5859 }
5860
5861 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
5862 tlp->vnp = new_list;
5863 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
5864 }
5865 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
5866 CorrectBarMax (tlp->bar, tlp->max);
5867 CorrectBarPage (tlp->bar, (Int2) (tlp->rows-1), (Int2) (tlp->rows-1));
5868
5869 /* retain scroll position */
5870 if (scroll_pos > tlp->max) {
5871 scroll_pos = tlp->max;
5872 }
5873
5874 if (tlp->bar != NULL)
5875 {
5876 CorrectBarValue (tlp->bar, scroll_pos);
5877 }
5878 if (tlp->left_bar != NULL)
5879 {
5880 CorrectBarValue (tlp->left_bar, scroll_pos);
5881 }
5882
5883 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
5884 Update ();
5885
5886 }
5887
5888
5889 static Pointer AccessionListDialogToData (DialoG d)
5890 {
5891 TagListPtr tlp;
5892 ValNodePtr vnp;
5893 Int4 result_len = 0, db;
5894 CharPtr str, acc_str, result_str = NULL;
5895 Boolean first_item = TRUE;
5896
5897 tlp = (TagListPtr) GetObjectExtra (d);
5898
5899 if (tlp == NULL) return NULL;
5900
5901 for (vnp = tlp->vnp;
5902 vnp != NULL;
5903 vnp = vnp->next)
5904 {
5905 acc_str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 1);
5906 str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
5907 if (!StringHasNoText (acc_str) || !StringHasNoText (str))
5908 {
5909 result_len += StringLen (acc_str);
5910 result_len += 1; /* comma */
5911 db = atoi (str);
5912 if (db >= 0 && db < numAccnTypePrefixes)
5913 {
5914 result_len += MAX (StringLen (accnTypePrefix[db]), 1);
5915 }
5916 else
5917 {
5918 result_len ++; /* will represent with ? */
5919 }
5920 result_len ++; /* for db/accession separator */
5921 }
5922 acc_str = MemFree (acc_str);
5923 str = MemFree (str);
5924 }
5925
5926 if (result_len > 0)
5927 {
5928 result_str = (CharPtr) MemNew (sizeof (Char) * (result_len + 1));
5929 for (vnp = tlp->vnp;
5930 vnp != NULL;
5931 vnp = vnp->next)
5932 {
5933 acc_str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 1);
5934 str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
5935 db = (str == NULL ? 0 : atoi (str));
5936 str = MemFree (str);
5937 if (!StringHasNoText (acc_str) || db > 0)
5938 {
5939 if (first_item)
5940 {
5941 first_item = FALSE;
5942 }
5943 else
5944 {
5945 StringCat (result_str, ",");
5946 }
5947
5948 if (db > 0 && db < numAccnTypePrefixes)
5949 {
5950 StringCat (result_str, accnTypePrefix[db]);
5951 }
5952 else
5953 {
5954 StringCat (result_str, "?");
5955 }
5956 StringCat (result_str, "|");
5957 if (!StringHasNoText (result_str)) {
5958 StringCat (result_str, acc_str);
5959 }
5960 }
5961 acc_str = MemFree (acc_str);
5962 }
5963 result_str[result_len] = 0;
5964 }
5965
5966 return result_str;
5967 }
5968
5969
5970 static void RemoveEmptyAccessionStrings (CharPtr acc_list)
5971 {
5972 CharPtr cp_prev_end = NULL, cp_src, cp_dst;
5973
5974 if (acc_list == NULL) return;
5975
5976 cp_src = acc_list;
5977 cp_dst = acc_list;
5978 cp_prev_end = acc_list;
5979 while (*cp_src != 0)
5980 {
5981 if (*cp_src == '|' && (*(cp_src + 1) == ',' || *(cp_src + 1) == 0))
5982 {
5983 cp_dst = cp_prev_end;
5984 cp_prev_end = cp_dst;
5985 cp_src++;
5986 }
5987 else
5988 {
5989 *cp_dst = *cp_src;
5990 if (*cp_src == ',')
5991 {
5992 cp_prev_end = cp_dst;
5993 }
5994 cp_dst++;
5995 cp_src++;
5996 }
5997 }
5998 *cp_dst = 0;
5999 }
6000
6001
6002 static CharPtr insdmessage =
6003 "GenBank, EMBL, and DDBJ records are part of the International Nucleotide " \
6004 "Sequence Database collaboration.\nThe database prefix for the /inference " \
6005 "qualifier in these cases is INSD by collaboration policy.";
6006
6007
6008 static Boolean ReplaceDatabaseStrings (CharPtr PNTR str)
6009 {
6010 Boolean changed_db = FALSE;
6011
6012 if (str == NULL || *str == NULL) return FALSE;
6013
6014 if (StringSearch (*str, "GenBank|") != NULL)
6015 {
6016 changed_db = TRUE;
6017 FindReplaceString (str, "GenBank|", "INSD|", TRUE, FALSE);
6018 }
6019 if (StringSearch (*str, "EMBL|") != NULL)
6020 {
6021 changed_db = TRUE;
6022 FindReplaceString (str, "EMBL|", "INSD|", TRUE, FALSE);
6023 }
6024 if (StringSearch (*str, "DDBJ|") != NULL)
6025 {
6026 changed_db = TRUE;
6027 FindReplaceString (str, "DDBJ|", "INSD|", TRUE, FALSE);
6028 }
6029
6030 if (changed_db)
6031 {
6032 if (GetAppProperty ("InternalNcbiSequin") == NULL) {
6033 Message (MSG_OK, "%s", insdmessage);
6034 }
6035 }
6036
6037 return changed_db;
6038 }
6039
6040
6041 static void ChangeInferAccessionList (Pointer data);
6042 static TaglistCallback AccessionListCallbacks[] =
6043 { ChangeInferAccessionList, ChangeInferAccessionList };
6044
6045 typedef struct inferevid {
6046 CharPtr prefix; /* from inferencePrefix */
6047 Boolean species; /* optional (same species) */
6048 CharPtr database; /* INSD, RefSeq, etc. */
6049 CharPtr db_other; /* other database */
6050 CharPtr accession; /* accession.version */
6051 CharPtr program; /* common analysis program */
6052 CharPtr pr_other; /* other program */
6053 CharPtr version; /* program version */
6054 CharPtr basis1; /* profile or motif */
6055 CharPtr basis2; /* evidence_basis texts */
6056 CharPtr accession_list; /* accession list for alignment */
6057 } InferEvid, PNTR InferEvidPtr;
6058
6059 typedef struct inferdialog {
6060 DIALOG_MESSAGE_BLOCK
6061
6062 DoC inferdoc;
6063 Int2 currItem;
6064
6065 PopuP prefix;
6066 ButtoN species;
6067 PopuP database;
6068 TexT db_other;
6069 TexT accession;
6070 PopuP program;
6071 TexT pr_other;
6072 TexT version;
6073 TexT basis1;
6074 TexT basis2;
6075 PrompT inf_free_program_prompt;
6076 PrompT inf_free_version_prompt;
6077 PrompT accession_list_program_prompt;
6078 PrompT accession_list_version_prompt;
6079 PrompT accession_list_prompt;
6080 DialoG accession_list;
6081
6082 GrouP inf_accn_group;
6083 GrouP other_db_group;
6084 GrouP inf_prog_group;
6085 GrouP other_pr_group;
6086 GrouP inf_free_group;
6087
6088 Int2 numInf;
6089 InferEvidPtr evidence [128];
6090
6091 } InferDialog, PNTR InferDialogPtr;
6092
6093 static InferEvidPtr InferEvidNew (
6094 void
6095 )
6096
6097 {
6098 InferEvidPtr iep;
6099
6100 iep = MemNew (sizeof (InferEvid));
6101 if (iep == NULL) return NULL;
6102
6103 return iep;
6104 }
6105
6106 static InferEvidPtr InferEvidFree (
6107 InferEvidPtr iep
6108 )
6109
6110 {
6111 if (iep == NULL) return NULL;
6112
6113 MemFree (iep->prefix);
6114 MemFree (iep->database);
6115 MemFree (iep->accession);
6116 MemFree (iep->program);
6117 MemFree (iep->version);
6118 MemFree (iep->basis1);
6119 MemFree (iep->basis2);
6120 MemFree (iep->accession_list);
6121
6122 return MemFree (iep);
6123 }
6124
6125 static InferEvidPtr GetInferEvid (
6126 InferDialogPtr idp,
6127 Int2 item
6128 )
6129
6130 {
6131 InferEvidPtr iep;
6132
6133 if (idp == NULL || item < 0 || item > 127) return NULL;
6134 iep = idp->evidence [item];
6135 if (iep != NULL) return iep;
6136
6137 iep = InferEvidNew ();
6138 if (iep != NULL) {
6139 /*
6140 iep->prefix = StringSave (" ");
6141 iep->database = StringSave (" ");
6142 iep->db_other = StringSave ("");
6143 iep->accession = StringSave ("");
6144 iep->program = StringSave (" ");
6145 iep->pr_other = StringSave ("");
6146 iep->version = StringSave ("");
6147 iep->basis1 = StringSave ("");
6148 iep->basis2 = StringSave ("");
6149 */
6150 }
6151 idp->evidence [item] = iep;
6152 return iep;
6153 }
6154
6155 /* inference DoC object tables */
6156
6157 #define NUM_INFERENCE_LINES 3
6158
6159 static ParData inferParFmt = { FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0 };
6160
6161 static ColData inferColFmt [] = {
6162 {0, 5, 25, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE}, /* class */
6163 {0, 5, 25, 2, NULL, 'l', FALSE, TRUE, FALSE, FALSE, TRUE} /* specifics */
6164 };
6165
6166 static CharPtr inferencePrefix [] = {
6167 "",
6168 "similar to sequence",
6169 "similar to AA sequence",
6170 "similar to DNA sequence",
6171 "similar to RNA sequence",
6172 "similar to RNA sequence, mRNA",
6173 "similar to RNA sequence, EST",
6174 "similar to RNA sequence, other RNA",
6175 "profile",
6176 "nucleotide motif",
6177 "protein motif",
6178 "ab initio prediction",
6179 "alignment",
6180 NULL
6181 };
6182
6183 ENUM_ALIST(inference_alist)
6184 { " ", 0 },
6185 { "similar to sequence", 1 },
6186 { "similar to protein", 2 },
6187 { "similar to DNA", 3 },
6188 { "similar to RNA", 4 },
6189 { "similar to mRNA", 5 },
6190 { "similar to EST", 6 },
6191 { "similar to other RNA", 7 },
6192 { "profile", 8 },
6193 { "nucleotide motif", 9 },
6194 { "protein motif", 10 },
6195 { "ab initio prediction", 11 },
6196 { "alignment", 12 },
6197 END_ENUM_ALIST
6198
6199 static CharPtr programPrefix [] = {
6200 "",
6201 "tRNAscan",
6202 "Genscan",
6203 "?",
6204 NULL
6205 };
6206
6207 ENUM_ALIST(program_alist)
6208 { " ", 0 },
6209 { "tRNAscan", 1 },
6210 { "Genscan", 2 },
6211 { "Other", 3 },
6212 END_ENUM_ALIST
6213
6214 static CharPtr PrintInferTable (
6215 DoC d,
6216 Int2 item,
6217 Pointer data
6218 )
6219
6220 {
6221 CharPtr buf;
6222 InferDialogPtr idp;
6223 InferEvidPtr iep;
6224 size_t len;
6225
6226 idp = (InferDialogPtr) GetObjectExtra (d);
6227 if (idp == NULL || item < 1 || item > 127) return NULL;
6228 iep = GetInferEvid (idp, item);
6229 if (iep == NULL) return NULL;
6230
6231 len = StringLen (iep->prefix) + StringLen (iep->database) + StringLen (iep->db_other) + StringLen (iep->accession) +
6232 StringLen (iep->program) + StringLen (iep->pr_other) + StringLen (iep->version) + StringLen (iep->basis1) +
6233 StringLen (iep->basis2) + StringLen (iep->accession_list) + 50;
6234 buf = MemNew (len);
6235 if (buf == NULL) return NULL;
6236
6237 if (StringHasNoText (iep->prefix)) {
6238 StringCat (buf, " \t \n");
6239 return buf;
6240 }
6241
6242 StringCat (buf, iep->prefix);
6243
6244 StringCat (buf, "\t");
6245
6246 if (StringNICmp (iep->prefix, "similar to ", 11) == 0) {
6247 if (StringDoesHaveText (iep->accession)) {
6248 if (StringCmp (iep->database, "Other") == 0) {
6249 if (StringDoesHaveText (iep->db_other)) {
6250 StringCat (buf, iep->db_other);
6251 StringCat (buf, ":");
6252 }
6253 } else if (StringDoesHaveText (iep->database)) {
6254 StringCat (buf, iep->database);
6255 StringCat (buf, ":");
6256 }
6257 StringCat (buf, iep->accession);
6258 }
6259 } else if (StringNICmp (iep->prefix, "ab initio ", 10) == 0) {
6260 if (StringCmp (iep->program, "Other") == 0) {
6261 if (StringDoesHaveText (iep->pr_other)) {
6262 StringCat (buf, iep->pr_other);
6263 if (StringDoesHaveText (iep->version)) {
6264 StringCat (buf, ":");
6265 StringCat (buf, iep->version);
6266 }
6267 }
6268 } else if (StringDoesHaveText (iep->program)) {
6269 StringCat (buf, iep->program);
6270 if (StringDoesHaveText (iep->version)) {
6271 StringCat (buf, ":");
6272 StringCat (buf, iep->version);
6273 }
6274 }
6275 } else if (StringDoesHaveText (iep->basis1)) {
6276 StringCat (buf, iep->basis1);
6277 if (StringDoesHaveText (iep->basis2)) {
6278 StringCat (buf, ":");
6279 StringCat (buf, iep->basis2);
6280 if (StringCmp (iep->prefix, "alignment") == 0 &&
6281 StringDoesHaveText (iep->accession_list)) {
6282 StringCat (buf, ":");
6283 StringCat (buf, iep->accession_list);
6284 }
6285 }
6286 } else {
6287 StringCat (buf, " ");
6288 }
6289
6290 StringCat (buf, "\n");
6291 return buf;
6292 }
6293
6294 static void ShowInferenceGroup (
6295 InferDialogPtr idp
6296 )
6297
6298 {
6299 CharPtr str;
6300 UIEnum val;
6301
6302 if (idp == NULL) return;
6303 if (GetEnumPopup (idp->prefix, inference_alist, &val)) {
6304 if (val >= 1 && val <= 7) {
6305 SafeHide (idp->inf_prog_group);
6306 SafeHide (idp->inf_free_group);
6307 SafeShow (idp->inf_accn_group);
6308 SafeShow (idp->species);
6309 str = GetEnumPopupByName (idp->database, accn_type_alist);
6310 if (StringCmp (str, "Other") == 0) {
6311 SafeShow (idp->other_db_group);
6312 } else {
6313 SafeHide (idp->other_db_group);
6314 }
6315 MemFree (str);
6316 } else if (val >= 8 && val <= 10) {
6317 SafeHide (idp->inf_accn_group);
6318 SafeHide (idp->species);
6319 SafeHide (idp->inf_prog_group);
6320 SafeShow (idp->inf_free_group);
6321 SafeHide (idp->accession_list);
6322 SafeShow (idp->inf_free_program_prompt);
6323 SafeShow (idp->inf_free_version_prompt);
6324 SafeHide (idp->accession_list_program_prompt);
6325 SafeHide (idp->accession_list_version_prompt);
6326 SafeHide (idp->accession_list_prompt);
6327 } else if (val == 11) {
6328 SafeHide (idp->inf_accn_group);
6329 SafeHide (idp->species);
6330 SafeHide (idp->inf_free_group);
6331 SafeShow (idp->inf_prog_group);
6332 str = GetEnumPopupByName (idp->program, program_alist);
6333 if (StringCmp (str, "Other") == 0) {
6334 SafeShow (idp->other_pr_group);
6335 } else {
6336 SafeHide (idp->other_pr_group);
6337 }
6338 MemFree (str);
6339 } else if (val == 12) {
6340 SafeHide (idp->inf_accn_group);
6341 SafeHide (idp->species);
6342 SafeHide (idp->inf_prog_group);
6343 SafeShow (idp->inf_free_group);
6344 SafeShow (idp->accession_list);
6345 SafeHide (idp->inf_free_program_prompt);
6346 SafeHide (idp->inf_free_version_prompt);
6347 SafeShow (idp->accession_list_program_prompt);
6348 SafeShow (idp->accession_list_version_prompt);
6349 SafeShow (idp->accession_list_prompt);
6350 } else {
6351 SafeHide (idp->inf_accn_group);
6352 SafeHide (idp->species);
6353 SafeHide (idp->inf_prog_group);
6354 SafeHide (idp->inf_free_group);
6355 }
6356 } else {
6357 SafeHide (idp->inf_accn_group);
6358 SafeHide (idp->species);
6359 SafeHide (idp->inf_prog_group);
6360 SafeHide (idp->inf_free_group);
6361 }
6362 Update ();
6363 }
6364
6365 static void SafeSetEnumPopupByName (PopuP lst, EnumFieldAssocPtr al, CharPtr name)
6366
6367 {
6368 if (StringDoesHaveText (name)) {
6369 SetEnumPopupByName (lst, al, name);
6370 } else {
6371 SetEnumPopupByName (lst, al, " ");
6372 }
6373 }
6374
6375 static void ChangeInferTableSelect (
6376 DoC d,
6377 Int2 item,
6378 Int2 row,
6379 Int2 col,
6380 Boolean dblClck
6381 )
6382
6383 {
6384 InferDialogPtr idp;
6385 InferEvidPtr iep;
6386 Int2 itemOld1, itemOld2;
6387
6388 idp = (InferDialogPtr) GetObjectExtra (d);
6389 if (idp == NULL) return;
6390 if (item == 0 || row == 0 || col == 0) return;
6391
6392 GetDocHighlight (d, &itemOld1, &itemOld2);
6393 SetDocHighlight (d, item, item);
6394 UpdateDocument (d, itemOld1, itemOld2);
6395 UpdateDocument (d, item, item);
6396 idp->currItem = item;
6397
6398 iep = GetInferEvid (idp, item);
6399 if (iep != NULL) {
6400 ResetClip ();
6401 SafeSetEnumPopupByName (idp->prefix, inference_alist, iep->prefix);
6402
6403 SafeSetStatus (idp->species, iep->species);
6404 SafeSetEnumPopupByName (idp->database, accn_type_alist, iep->database);
6405 SafeSetTitle (idp->db_other, iep->db_other);
6406 SafeSetTitle (idp->accession, iep->accession);
6407
6408 SafeSetEnumPopupByName (idp->program, program_alist, iep->program);
6409 SafeSetTitle (idp->pr_other, iep->pr_other);
6410 SafeSetTitle (idp->version, iep->version);
6411
6412 SafeSetTitle (idp->basis1, iep->basis1);
6413 SafeSetTitle (idp->basis2, iep->basis2);
6414
6415 ReplaceDatabaseStrings (&(iep->accession_list));
6416 PointerToDialog (idp->accession_list, iep->accession_list);
6417
6418 ShowInferenceGroup (idp);
6419 }
6420
6421 Update ();
6422 }
6423
6424 static void CheckExtendInferTable (
6425 InferDialogPtr idp
6426 )
6427
6428 {
6429 Int2 numItems;
6430
6431 if (idp == NULL) return;
6432
6433 GetDocParams (idp->inferdoc, &numItems, NULL);
6434 if (idp->currItem == numItems) {
6435 AppendItem (idp->inferdoc, PrintInferTable, idp, FALSE, 1,
6436 &inferParFmt, inferColFmt, systemFont);
6437 }
6438
6439 Update ();
6440 }
6441
6442 static void ChangeInferPrefix (
6443 PopuP p
6444 )
6445
6446 {
6447 AlistDialogPtr adp;
6448 InferDialogPtr idp;
6449 InferEvidPtr iep;
6450 CharPtr str;
6451
6452 adp = (AlistDialogPtr) GetObjectExtra (p);
6453 if (adp == NULL) return;
6454 idp = (InferDialogPtr) adp->userdata;
6455 if (idp == NULL) return;
6456 iep = GetInferEvid (idp, idp->currItem);
6457 if (iep == NULL) return;
6458
6459 str = GetEnumPopupByName (idp->prefix, inference_alist);
6460 iep->prefix = MemFree (iep->prefix);
6461 iep->prefix = str; /* allocated by GetEnumPopupByName */
6462
6463 ShowInferenceGroup (idp);
6464
6465 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6466 Update ();
6467
6468 CheckExtendInferTable (idp);
6469 }
6470
6471 static void ChangeSameSpecies (
6472 ButtoN b
6473 )
6474
6475 {
6476 InferDialogPtr idp;
6477 InferEvidPtr iep;
6478
6479 idp = (InferDialogPtr) GetObjectExtra (b);
6480 if (idp == NULL) return;
6481 iep = GetInferEvid (idp, idp->currItem);
6482 if (iep == NULL) return;
6483
6484 iep->species = (Boolean) (GetStatus (b));
6485
6486 ShowInferenceGroup (idp);
6487
6488 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6489 Update ();
6490
6491 CheckExtendInferTable (idp);
6492 }
6493
6494 static void ChangeInferDatabase (
6495 PopuP p
6496 )
6497
6498
6499 {
6500 AlistDialogPtr adp;
6501 InferDialogPtr idp;
6502 InferEvidPtr iep;
6503 CharPtr str;
6504
6505 adp = (AlistDialogPtr) GetObjectExtra (p);
6506 if (adp == NULL) return;
6507 idp = (InferDialogPtr) adp->userdata;
6508 if (idp == NULL) return;
6509 iep = GetInferEvid (idp, idp->currItem);
6510 if (iep == NULL) return;
6511
6512 str = GetEnumPopupByName (idp->database, accn_type_alist);
6513 if (StringCmp (str, "GenBank") == 0 ||
6514 StringCmp (str, "EMBL") == 0 ||
6515 StringCmp (str, "DDBJ") == 0) {
6516 if (GetAppProperty ("InternalNcbiSequin") == NULL) {
6517 Message (MSG_OK, "%s", insdmessage);
6518 }
6519 SetEnumPopupByName (idp->database, accn_type_alist, "INSD");
6520 str = MemFree (str);
6521 str = StringSave ("INSD");
6522 }
6523 iep->database = MemFree (iep->database);
6524 iep->database = str; /* allocated by GetEnumPopupByName */
6525
6526 ShowInferenceGroup (idp);
6527
6528 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6529 Update ();
6530
6531 CheckExtendInferTable (idp);
6532 }
6533
6534 static void ChangeInferDbOther (
6535 TexT t
6536 )
6537
6538 {
6539 InferDialogPtr idp;
6540 InferEvidPtr iep;
6541
6542 idp = (InferDialogPtr) GetObjectExtra (t);
6543 if (idp == NULL) return;
6544 iep = GetInferEvid (idp, idp->currItem);
6545 if (iep == NULL) return;
6546
6547 iep->db_other = MemFree (iep->db_other);
6548 iep->db_other = SaveStringFromText (t);
6549
6550 ShowInferenceGroup (idp);
6551
6552 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6553 Update ();
6554
6555 CheckExtendInferTable (idp);
6556 }
6557
6558 static void ChangeInferAccession (
6559 TexT t
6560 )
6561
6562 {
6563 InferDialogPtr idp;
6564 InferEvidPtr iep;
6565
6566 idp = (InferDialogPtr) GetObjectExtra (t);
6567 if (idp == NULL) return;
6568 iep = GetInferEvid (idp, idp->currItem);
6569 if (iep == NULL) return;
6570
6571 iep->accession = MemFree (iep->accession);
6572 iep->accession = SaveStringFromText (t);
6573
6574 ShowInferenceGroup (idp);
6575
6576 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6577 Update ();
6578
6579 CheckExtendInferTable (idp);
6580 }
6581
6582 static void ChangeInferProgram (
6583 PopuP p
6584 )
6585
6586
6587 {
6588 AlistDialogPtr adp;
6589 InferDialogPtr idp;
6590 InferEvidPtr iep;
6591 CharPtr str;
6592
6593 adp = (AlistDialogPtr) GetObjectExtra (p);
6594 if (adp == NULL) return;
6595 idp = (InferDialogPtr) adp->userdata;
6596 if (idp == NULL) return;
6597 iep = GetInferEvid (idp, idp->currItem);
6598 if (iep == NULL) return;
6599
6600 str = GetEnumPopupByName (idp->program, program_alist);
6601 iep->program = MemFree (iep->program);
6602 iep->program = str; /* allocated by GetEnumPopupByName */
6603
6604 ShowInferenceGroup (idp);
6605
6606 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6607 Update ();
6608
6609 CheckExtendInferTable (idp);
6610 }
6611
6612 static void ChangeInferPrOther (
6613 TexT t
6614 )
6615
6616 {
6617 InferDialogPtr idp;
6618 InferEvidPtr iep;
6619
6620 idp = (InferDialogPtr) GetObjectExtra (t);
6621 if (idp == NULL) return;
6622 iep = GetInferEvid (idp, idp->currItem);
6623 if (iep == NULL) return;
6624
6625 iep->pr_other = MemFree (iep->pr_other);
6626 iep->pr_other = SaveStringFromText (t);
6627
6628 ShowInferenceGroup (idp);
6629
6630 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6631 Update ();
6632
6633 CheckExtendInferTable (idp);
6634 }
6635
6636 static void ChangeInferVersion (
6637 TexT t
6638 )
6639
6640 {
6641 InferDialogPtr idp;
6642 InferEvidPtr iep;
6643
6644 idp = (InferDialogPtr) GetObjectExtra (t);
6645 if (idp == NULL) return;
6646 iep = GetInferEvid (idp, idp->currItem);
6647 if (iep == NULL) return;
6648
6649 iep->version = MemFree (iep->version);
6650 iep->version = SaveStringFromText (t);
6651
6652 ShowInferenceGroup (idp);
6653
6654 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6655 Update ();
6656
6657 CheckExtendInferTable (idp);
6658 }
6659
6660 static void ChangeInferBasis1 (
6661 TexT t
6662 )
6663
6664 {
6665 InferDialogPtr idp;
6666 InferEvidPtr iep;
6667
6668 idp = (InferDialogPtr) GetObjectExtra (t);
6669 if (idp == NULL) return;
6670 iep = GetInferEvid (idp, idp->currItem);
6671 if (iep == NULL) return;
6672
6673 iep->basis1 = MemFree (iep->basis1);
6674 iep->basis1 = SaveStringFromText (t);
6675
6676 ShowInferenceGroup (idp);
6677
6678 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6679 Update ();
6680
6681 CheckExtendInferTable (idp);
6682 }
6683
6684 static void ChangeInferBasis2 (
6685 TexT t
6686 )
6687
6688 {
6689 InferDialogPtr idp;
6690 InferEvidPtr iep;
6691
6692 idp = (InferDialogPtr) GetObjectExtra (t);
6693 if (idp == NULL) return;
6694 iep = GetInferEvid (idp, idp->currItem);
6695 if (iep == NULL) return;
6696
6697 iep->basis2 = MemFree (iep->basis2);
6698 iep->basis2 = SaveStringFromText (t);
6699
6700 ShowInferenceGroup (idp);
6701
6702 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6703 Update ();
6704
6705 CheckExtendInferTable (idp);
6706 }
6707
6708
6709 static void ChangeInferAccessionList (Pointer data)
6710 {
6711 InferDialogPtr idp;
6712 InferEvidPtr iep;
6713
6714 idp = (InferDialogPtr) data;
6715 if (idp == NULL) return;
6716 iep = GetInferEvid (idp, idp->currItem);
6717 if (iep == NULL) return;
6718
6719 iep->accession_list = MemFree (iep->accession_list);
6720 iep->accession_list = DialogToPointer (idp->accession_list);
6721
6722 if (ReplaceDatabaseStrings (&(iep->accession_list)))
6723 {
6724 PointerToDialog (idp->accession_list, iep->accession_list);
6725 }
6726
6727 ShowInferenceGroup (idp);
6728
6729 UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
6730 Update ();
6731
6732 CheckExtendInferTable (idp);
6733 }
6734
6735
6736 static Boolean StringInList (CharPtr str, CharPtr PNTR list)
6737
6738 {
6739 Int2 i;
6740
6741 if (str == NULL || list == NULL) return FALSE;
6742
6743 for (i = 0; list [i] != NULL; i++) {
6744 if (StringICmp (str, list[i]) == 0) return TRUE;
6745 }
6746
6747 return FALSE;
6748 }
6749
6750 extern void GBQualsToInferenceDialog (DialoG d, SeqFeatPtr sfp)
6751
6752 {
6753 Int2 best;
6754 Char ch;
6755 GBQualPtr gbq;
6756 Int2 i, j, k;
6757 InferDialogPtr idp;
6758 InferEvidPtr iep;
6759 size_t len;
6760 CharPtr rest;
6761 CharPtr str;
6762 CharPtr tmp, tmp2;
6763
6764 idp = (InferDialogPtr) GetObjectExtra (d);
6765 if (idp == NULL) return;
6766
6767 if (sfp == NULL || sfp->qual == NULL) {
6768 Reset (idp->inferdoc);
6769 SetValue (idp->prefix, 0);
6770 SetStatus (idp->species, FALSE);
6771 SetValue (idp->database, 0);
6772 SetTitle (idp->db_other, "");
6773 SetTitle (idp->accession, "");
6774 SetValue (idp->program, 0);
6775 SetTitle (idp->pr_other, "");
6776 SetTitle (idp->version, "");
6777 SetTitle (idp->basis1, "");
6778 SetTitle (idp->basis2, "");
6779 SafeHide (idp->inf_accn_group);
6780 SafeHide (idp->inf_prog_group);
6781 SafeHide (idp->inf_free_group);
6782 idp->numInf = 0;
6783 idp->currItem = 1;
6784 for (i = 0; i < NUM_INFERENCE_LINES; i++) {
6785 AppendItem (idp->inferdoc, PrintInferTable, idp, FALSE, 1,
6786 &inferParFmt, inferColFmt, systemFont);
6787 }
6788 SetDocHighlight (idp->inferdoc, 1, 1);
6789 return;
6790 }
6791
6792 idp->numInf = 0;
6793 idp->currItem = 1;
6794 Reset (idp->inferdoc);
6795
6796 for (k = 0; k < 128; k++) {
6797 iep = idp->evidence [k];
6798 InferEvidFree (iep);
6799 idp->evidence [k] = NULL;
6800 }
6801
6802 for (gbq = sfp->qual, k = 0; gbq != NULL; gbq = gbq->next) {
6803 if (StringICmp (gbq->qual, "inference") != 0) continue;
6804 if (StringHasNoText (gbq->val)) continue;
6805
6806 rest = NULL;
6807 best = -1;
6808 for (j = 0; inferencePrefix [j] != NULL; j++) {
6809 len = StringLen (inferencePrefix [j]);
6810 if (StringNICmp (gbq->val, inferencePrefix [j], len) != 0) continue;
6811 rest = gbq->val + len;
6812 best = j;
6813 }
6814
6815 k++;
6816 iep = GetInferEvid (idp, k);
6817 if (iep == NULL) continue;
6818
6819 str = NULL;
6820 if (best > 0 && inferencePrefix [best] != NULL) {
6821 iep->prefix = MemFree (iep->prefix);
6822 iep->prefix = StringSave(GetEnumName ((UIEnum) best, inference_alist));
6823
6824 if (rest != NULL) {
6825 ch = *rest;
6826 while (IS_WHITESP (ch)) {
6827 rest++;
6828 ch = *rest;
6829 }
6830 if (StringNICmp (rest, "(same species)", 14) == 0) {
6831 iep->species = TRUE;
6832 rest += 14;
6833 } else {
6834 iep->species = FALSE;
6835 }
6836 ch = *rest;
6837 while (IS_WHITESP (ch) || ch == ':') {
6838 rest++;
6839 ch = *rest;
6840 }
6841 }
6842 if (StringDoesHaveText (rest)) {
6843 str = StringSave (rest);
6844 }
6845 tmp = StringChr (str, ':');
6846 if (tmp != NULL) {
6847 *tmp = '\0';
6848 tmp++;
6849 TrimSpacesAroundString (str);
6850 TrimSpacesAroundString (tmp);
6851 } else {
6852 TrimSpacesAroundString (str);
6853 }
6854 if (StringNICmp (iep->prefix, "similar to ", 11) == 0) {
6855 if (StringInList (str, accnTypePrefix)) {
6856 iep->database = MemFree (iep->database);
6857 iep->database = StringSaveNoNull (str);
6858 iep->accession = MemFree (iep->accession);
6859 iep->accession = StringSaveNoNull (tmp);
6860 } else if (tmp != NULL) {
6861 iep->database = MemFree (iep->database);
6862 iep->database = StringSaveNoNull ("Other");
6863 iep->db_other = MemFree (iep->db_other);
6864 iep->db_other = StringSaveNoNull (str);
6865 iep->accession = MemFree (iep->accession);
6866 iep->accession = StringSaveNoNull (tmp);
6867 } else {
6868 iep->database = MemFree (iep->database);
6869 iep->database = StringSaveNoNull (" ");
6870 iep->db_other = MemFree (iep->db_other);
6871 iep->accession = MemFree (iep->accession);
6872 iep->accession = StringSaveNoNull (str);
6873 }
6874 } else if (StringNICmp (iep->prefix, "ab initio ", 10) == 0) {
6875 if (StringInList (str, programPrefix)) {
6876 iep->program = MemFree (iep->program);
6877 iep->program = StringSaveNoNull (str);
6878 } else {
6879 iep->program = MemFree (iep->program);
6880 iep->program = StringSaveNoNull ("Other");
6881 iep->pr_other = MemFree (iep->pr_other);
6882 iep->pr_other = StringSaveNoNull (str);
6883 }
6884 iep->version = MemFree (iep->version);
6885 iep->version = StringSaveNoNull (tmp);
6886 } else {
6887 iep->basis1 = MemFree (iep->basis1);
6888 iep->basis1 = StringSaveNoNull (str);
6889 tmp2 = NULL;
6890 if (StringCmp (iep->prefix, "alignment") == 0)
6891 {
6892 tmp2 = StringChr (tmp, ':');
6893 if (tmp2 != NULL) {
6894 *tmp2 = 0;
6895 tmp2++;
6896 }
6897 }
6898 iep->basis2 = MemFree (iep->basis2);
6899 iep->basis2 = StringSaveNoNull (tmp);
6900 iep->accession_list = MemFree (iep->accession_list);
6901 iep->accession_list = StringSaveNoNull (tmp2);
6902 }
6903
6904 } else {
6905 iep->prefix = StringSave ("???");
6906 str = StringSave (gbq->val);
6907 tmp = StringChr (str, ':');
6908 if (tmp != NULL) {
6909 *tmp = '\0';
6910 tmp++;
6911 TrimSpacesAroundString (str);
6912 TrimSpacesAroundString (tmp);
6913 } else {
6914 TrimSpacesAroundString (str);
6915 }
6916 iep->basis1 = MemFree (iep->basis1);
6917 iep->basis1 = StringSaveNoNull (str);
6918 iep->basis2 = MemFree (iep->basis2);
6919 iep->basis2 = StringSaveNoNull (tmp);
6920 }
6921
6922 MemFree (str);
6923
6924 AppendItem (idp->inferdoc, PrintInferTable, idp, FALSE, 1,
6925 &inferParFmt, inferColFmt, systemFont);
6926
6927 (idp->numInf)++;
6928 }
6929
6930 AppendItem (idp->inferdoc, PrintInferTable, idp, FALSE, 1,
6931 &inferParFmt, inferColFmt, systemFont);
6932 k++;
6933
6934 while (k < NUM_INFERENCE_LINES) {
6935 AppendItem (idp->inferdoc, PrintInferTable, idp, FALSE, 1,
6936 &inferParFmt, inferColFmt, systemFont);
6937 k++;
6938 }
6939
6940 ShowInferenceGroup (idp);
6941
6942 UpdateDocument (idp->inferdoc, 0, 0);
6943
6944 ChangeInferTableSelect (idp->inferdoc, 1, 1, 1, FALSE);
6945
6946 Update ();
6947 }
6948
6949 extern void InferenceDialogToGBQuals (DialoG d, SeqFeatPtr sfp, Boolean convertBadToNote)
6950
6951 {
6952 CharPtr first = NULL, second = NULL, accession_list = NULL;
6953 GBQualPtr gbq, lastgbq;
6954 InferDialogPtr idp;
6955 InferEvidPtr iep;
6956 Int2 k, numItems;
6957 size_t len;
6958 CharPtr prefix = NULL;
6959 CharPtr speciesies = NULL;
6960 CharPtr str;
6961 UIEnum val;
6962
6963 idp = (InferDialogPtr) GetObjectExtra (d);
6964 if (idp == NULL || sfp == NULL) return;
6965
6966 lastgbq = NULL;
6967 for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
6968 lastgbq = gbq;
6969 }
6970
6971 GetDocParams (idp->inferdoc, &numItems, NULL);
6972 for (k = 1; k <= numItems; k++) {
6973 iep = GetInferEvid (idp, k);
6974 if (iep == NULL) continue;
6975
6976 if (StringHasNoText (iep->prefix)) continue;
6977 gbq = GBQualNew ();
6978 if (gbq == NULL) continue;
6979
6980 gbq->qual = StringSave ("inference");
6981
6982 if (WhereInEnumPopup (inference_alist, iep->prefix, &val)) {
6983 if (val > 0 && val <= 12) {
6984 prefix = inferencePrefix [(int) val];
6985 }
6986 }
6987 speciesies = NULL;
6988 if (StringNICmp (iep->prefix, "similar to ", 11) == 0) {
6989 if (iep->species) {
6990 speciesies = " (same species)";
6991 }
6992 if (StringDoesHaveText (iep->accession)) {
6993 if (StringCmp (iep->database, "Other") == 0) {
6994 if (StringDoesHaveText (iep->db_other)) {
6995 first = iep->db_other;
6996 }
6997 } else if (StringDoesHaveText (iep->database)) {
6998 first = iep->database;
6999 }
7000 second = iep->accession;
7001 }
7002 } else if (StringNICmp (iep->prefix, "ab initio ", 10) == 0) {
7003 if (StringCmp (iep->program, "Other") == 0) {
7004 if (StringDoesHaveText (iep->pr_other)) {
7005 first = iep->pr_other;
7006 }
7007 } else if (StringDoesHaveText (iep->program)) {
7008 first = iep->program;
7009 }
7010 second = iep->version;
7011 } else {
7012 if (StringDoesHaveText (iep->basis1)) {
7013 first = iep->basis1;
7014 second = iep->basis2;
7015 if (StringCmp (iep->prefix, "alignment") == 0) {
7016 accession_list = iep->accession_list;
7017 RemoveEmptyAccessionStrings (accession_list);
7018 ReplaceDatabaseStrings (&accession_list);
7019 }
7020 }
7021 }
7022
7023 len = StringLen (prefix) + StringLen (speciesies) + StringLen (first) + StringLen (second) + StringLen (accession_list);
7024 str = MemNew (len + 6);
7025 if (str != NULL) {
7026 StringCpy (str, prefix);
7027 StringCat (str, speciesies);
7028 StringCat (str, ":");
7029 StringCat (str, first);
7030 StringCat (str, ":");
7031 StringCat (str, second);
7032 if (StringCmp (prefix, "alignment") == 0 && accession_list != NULL) {
7033 StringCat (str, ":");
7034 StringCat (str, accession_list);
7035 }
7036 gbq->val = StringSave (str);
7037 MemFree (str);
7038 } else {
7039 gbq->val = StringSave ("?");
7040 }
7041
7042 /* do not allow saving of bad qualifier */
7043 if (convertBadToNote &&
7044 ValidateInferenceQualifier (gbq->val, FALSE) != VALID_INFERENCE) {
7045 if (StringNICmp (gbq->val, "similar to ", 11) == 0) {
7046 len = StringLen ("similar to ") + StringLen (first) + StringLen (second);
7047 str = MemNew (len + 5);
7048 if (str != NULL) {
7049 StringCpy (str, "similar to ");
7050 if (StringDoesHaveText (first)) {
7051 StringCat (str, first);
7052 if (StringDoesHaveText (second)) {
7053 StringCat (str, ":");
7054 StringCat (str, second);
7055 }
7056 } else if (StringDoesHaveText (second)) {
7057 StringCat (str, second);
7058 }
7059 gbq->val = MemFree (gbq->val);
7060 gbq->val = StringSave (str);
7061 MemFree (str);
7062 }
7063 }
7064 gbq->qual = MemFree (gbq->qual);
7065 gbq->qual = StringSave ("note");
7066 }
7067
7068 if (sfp->qual == NULL) {
7069 sfp->qual = gbq;
7070 }
7071 if (lastgbq != NULL) {
7072 lastgbq->next = gbq;
7073 }
7074 lastgbq = gbq;
7075 accession_list = NULL;
7076 }
7077 }
7078
7079 static void CleanupInferProc (GraphiC g, VoidPtr data)
7080
7081 {
7082 InferDialogPtr idp;
7083 InferEvidPtr iep;
7084 Int2 k;
7085
7086 idp = (InferDialogPtr) data;
7087 if (idp != NULL) {
7088 for (k = 0; k < 128; k++) {
7089 iep = idp->evidence [k];
7090 InferEvidFree (iep);
7091 idp->evidence [k] = NULL;
7092 }
7093 }
7094 StdCleanupExtraProc (g, data);
7095 }
7096
7097 static DialoG NewCreateInferenceDialog (
7098 GrouP prnt
7099 )
7100
7101 {
7102 GrouP cts, tbl, g0, g1, g2, g3, g4, g5, p, prompt_grp;
7103 FonT fnt;
7104 Int2 i, hgt, wid;
7105 InferDialogPtr idp;
7106
7107 idp = (InferDialogPtr) MemNew (sizeof (InferDialog));
7108 if (idp == NULL) return NULL;
7109
7110 p = HiddenGroup (prnt, -1, 0, NULL);
7111 SetGroupSpacing (p, 10, 10);
7112
7113 SetObjectExtra (p, idp, CleanupInferProc);
7114 idp->dialog = (DialoG) p;
7115 /*
7116 idp->todialog = GBQualToInferTable;
7117 idp->fromdialog = InferTableToGBQual;
7118 */
7119
7120 SelectFont (systemFont);
7121 hgt = LineHeight ();
7122 inferColFmt [0].pixWidth = MaxAlistWidths (inference_alist) + 5;
7123 inferColFmt [1].pixWidth = 25 * StringWidth ("X") + 5;
7124 SelectFont (systemFont);
7125
7126 wid = 0;
7127 for (i = 0; i < 2; i++) {
7128 wid += inferColFmt [i].pixWidth;
7129 }
7130
7131 tbl = HiddenGroup (p, -1, 0, NULL);
7132 SetGroupSpacing (tbl, 10, 5);
7133 SetGroupMargins (tbl, 5, 5);
7134
7135 g0 = HiddenGroup (tbl, 15, 0, NULL);
7136 SetGroupSpacing (g0, 0, 3);
7137 #ifdef WIN_MSWIN
7138 fnt = systemFont;
7139 #else
7140 fnt = programFont;
7141 #endif
7142 /*
7143 StaticPrompt (g0, "Category", inferColFmt [0].pixWidth, 0, fnt, 'c');
7144 StaticPrompt (g0, "Explanation", inferColFmt [1].pixWidth, 0, fnt, 'c');
7145 */
7146
7147 idp->inferdoc = DocumentPanel (tbl, wid + 2, NUM_INFERENCE_LINES * hgt + 2);
7148 SetObjectExtra (idp->inferdoc, idp, NULL);
7149 SetDocCache (idp->inferdoc, NULL, NULL, NULL);
7150 SetDocNotify (idp->inferdoc, ChangeInferTableSelect);
7151 idp->numInf = 0;
7152
7153 for (i = 0; i < NUM_INFERENCE_LINES; i++) {
7154 AppendItem (idp->inferdoc, PrintInferTable, idp, FALSE, 1,
7155 &inferParFmt, inferColFmt, systemFont);
7156 }
7157
7158 cts = HiddenGroup (p, -1, 0, NULL);
7159 SetGroupSpacing (cts, 10, 10);
7160 SetGroupMargins (cts, 5, 5);
7161
7162 g1 = HiddenGroup (cts, -10, 0, NULL);
7163 SetGroupSpacing (g1, 5, 5);
7164
7165 StaticPrompt (g1, "Category", 0, popupMenuHeight, programFont, 'l');
7166 idp->prefix = CreateEnumPopupDialog (g1, TRUE, ChangeInferPrefix, inference_alist, (UIEnum) 0, idp);
7167
7168 idp->species = CheckBox (g1, "(same species)", ChangeSameSpecies);
7169 SetObjectExtra (idp->species, idp, NULL);
7170 Hide (idp->species);
7171
7172 g2 = HiddenGroup (cts, 0, 0, NULL);
7173 SetGroupSpacing (g2, 5, 5);
7174
7175 g3 = HiddenGroup (g2, -3, 0, NULL);
7176 SetGroupSpacing (g3, 5, 5);
7177
7178 StaticPrompt (g3, "Database", 0, dialogTextHeight, programFont, 'l');
7179 idp->database = CreateEnumPopupDialog (g3, TRUE, ChangeInferDatabase, accn_type_alist, (UIEnum) 0, idp);
7180 idp->other_db_group = HiddenGroup (g3, -4, 0, NULL);
7181 StaticPrompt (idp->other_db_group, ":", 0, dialogTextHeight, programFont, 'l');
7182 idp->db_other = DialogText (idp->other_db_group, "", 8, ChangeInferDbOther);
7183 SetObjectExtra (idp->db_other, idp, NULL);
7184 Hide (idp->other_db_group);
7185
7186 StaticPrompt (g3, "Accession", 0, dialogTextHeight, programFont, 'l');
7187 idp->accession = DialogText (g3, "", 10, ChangeInferAccession);
7188 SetObjectExtra (idp->accession, idp, NULL);
7189
7190 idp->inf_accn_group = g3;
7191 Hide (idp->inf_accn_group);
7192
7193 g4 = HiddenGroup (g2, -3, 0, NULL);
7194 SetGroupSpacing (g4, 5, 5);
7195
7196 StaticPrompt (g4, "Program", 0, dialogTextHeight, programFont, 'l');
7197 idp->program = CreateEnumPopupDialog (g4, TRUE, ChangeInferProgram, program_alist, (UIEnum) 0, idp);
7198 idp->other_pr_group = HiddenGroup (g4, -4, 0, NULL);
7199 StaticPrompt (idp->other_pr_group, ":", 0, dialogTextHeight, programFont, 'l');
7200 idp->pr_other = DialogText (idp->other_pr_group, "", 8, ChangeInferPrOther);
7201 SetObjectExtra (idp->pr_other, idp, NULL);
7202 Hide (idp->other_pr_group);
7203
7204 StaticPrompt (g4, "Program Version", 0, dialogTextHeight, programFont, 'l');
7205 idp->version = DialogText (g4, "", 3, ChangeInferVersion);
7206 SetObjectExtra (idp->version, idp, NULL);
7207
7208 idp->inf_prog_group = g4;
7209 Hide (idp->inf_prog_group);
7210
7211 g5 = HiddenGroup (g2, 2, 0, NULL);
7212 SetGroupSpacing (g5, 5, 5);
7213
7214 prompt_grp = HiddenGroup (g5, 0, 0, NULL);
7215 idp->inf_free_program_prompt = StaticPrompt (prompt_grp, "Program or Database", 0, dialogTextHeight, programFont, 'l');
7216 idp->accession_list_program_prompt = StaticPrompt (prompt_grp, "Program", 0, dialogTextHeight, programFont, 'l');
7217 idp->basis1 = DialogText (g5, "", 10, ChangeInferBasis1);
7218 SetObjectExtra (idp->basis1, idp, NULL);
7219
7220 prompt_grp = HiddenGroup (g5, 0, 0, NULL);
7221 idp->inf_free_version_prompt = StaticPrompt (prompt_grp, "Version or Accession", 0, dialogTextHeight, programFont, 'l');
7222 idp->accession_list_version_prompt = StaticPrompt (prompt_grp, "Version", 0, dialogTextHeight, programFont, 'l');
7223
7224 idp->basis2 = DialogText (g5, "", 10, ChangeInferBasis2);
7225 SetObjectExtra (idp->basis2, idp, NULL);
7226
7227 idp->accession_list_prompt = StaticPrompt (g5, "Accessions", 0, dialogTextHeight, programFont, 'l');
7228 idp->accession_list = CreateTagListDialogEx3 (g5, 3, 2, 2,
7229 accessionlist_types, accessionlist_widths,
7230 accessionlist_popups, TRUE, FALSE, AccessionListDataToDialog, AccessionListDialogToData,
7231 AccessionListCallbacks, idp,
7232 FALSE, FALSE);
7233
7234 idp->inf_free_group = g5;
7235 Hide (idp->inf_free_group);
7236
7237 AlignObjects (ALIGN_CENTER, (HANDLE) tbl, (HANDLE) cts, NULL);
7238
7239 idp->numInf = 0;
7240 idp->currItem = 1;
7241 SetDocHighlight (idp->inferdoc, 1, 1);
7242
7243 return (DialoG) p;
7244 }
7245
7246
7247 /* ExistingText handling dialog and structures */
7248 typedef struct existingtextdlg
7249 {
7250 GrouP pre_app_grp;
7251 GrouP delim_grp;
7252 } ExistingTextDlgData, PNTR ExistingTextDlgPtr;
7253
7254 static void ChangePreAppIgnoreChoice (GrouP g)
7255 {
7256 ExistingTextDlgPtr etdp;
7257 Int4 handle_choice;
7258
7259 etdp = (ExistingTextDlgPtr) GetObjectExtra (g);
7260 if (etdp == NULL)
7261 {
7262 return;
7263 }
7264
7265 handle_choice = GetValue (etdp->pre_app_grp);
7266 if (handle_choice == 1 || handle_choice == 2)
7267 {
7268 Enable (etdp->delim_grp);
7269 }
7270 else
7271 {
7272 Disable (etdp->delim_grp);
7273 }
7274 }
7275
7276 extern ExistingTextPtr GetExistingTextHandlerInfo (Int4 num_found, Boolean non_text)
7277 {
7278 WindoW w;
7279 GrouP h, c;
7280 ExistingTextDlgData etdd;
7281 ButtoN b;
7282 ModalAcceptCancelData acd;
7283 ExistingTextPtr etp;
7284 Char txt [128];
7285 MsgAnswer ans;
7286 PrompT ppt;
7287 Int4 handle_choice;
7288
7289 if (num_found <= 0)
7290 {
7291 return NULL;
7292 }
7293
7294 sprintf (txt, "%d affected fields already contain a value. Do you wish to overwrite existing text?",
7295 num_found);
7296 ans = Message (MSG_YNC, txt, 0, dialogTextHeight, systemFont, 'l');
7297 if (ans == ANS_CANCEL)
7298 {
7299 etp = (ExistingTextPtr) MemNew (sizeof (ExistingTextData));
7300 etp->existing_text_choice = eExistingTextChoiceCancel;
7301 return etp;
7302 }
7303 else if (ans == ANS_YES)
7304 {
7305 etp = (ExistingTextPtr) MemNew (sizeof (ExistingTextData));
7306 etp->existing_text_choice = eExistingTextChoiceReplaceOld;
7307 return etp;
7308 }
7309
7310 w = MovableModalWindow(-20, -13, -10, -10, "How to Add New Text", NULL);
7311 h = HiddenGroup (w, -1, 0, NULL);
7312 SetGroupSpacing (h, 10, 10);
7313 etdd.pre_app_grp = HiddenGroup (h, 0, 3, ChangePreAppIgnoreChoice);
7314 SetGroupSpacing (etdd.pre_app_grp, 10, 10);
7315 RadioButton (etdd.pre_app_grp, "Append");
7316 RadioButton (etdd.pre_app_grp, "Prefix");
7317 RadioButton (etdd.pre_app_grp, "Ignore new text");
7318 SetValue (etdd.pre_app_grp, 1);
7319 SetObjectExtra (etdd.pre_app_grp, &etdd, NULL);
7320
7321 ppt = StaticPrompt (h, "Separate new text and old text with",
7322 0, dialogTextHeight, programFont, 'c');
7323 etdd.delim_grp = HiddenGroup (h, 0, 4, NULL);
7324 SetGroupSpacing (etdd.delim_grp, 10, 10);
7325 RadioButton (etdd.delim_grp, "Semicolon");
7326 RadioButton (etdd.delim_grp, "Space");
7327 RadioButton (etdd.delim_grp, "Colon");
7328 RadioButton (etdd.delim_grp, "Do not separate");
7329 SetValue (etdd.delim_grp, 1);
7330
7331 c = HiddenGroup (h, 2, 0, NULL);
7332 SetGroupSpacing (c, 10, 10);
7333 b = PushButton (c, "Accept", ModalAcceptButton);
7334 SetObjectExtra (b, &acd, NULL);
7335 b = PushButton (c, "Cancel", ModalCancelButton);
7336 SetObjectExtra (b, &acd, NULL);
7337 AlignObjects (ALIGN_CENTER, (HANDLE) etdd.pre_app_grp,
7338 (HANDLE) ppt,
7339 (HANDLE) etdd.delim_grp,
7340 (HANDLE) c,
7341 NULL);
7342 Show (w);
7343 Select (w);
7344 acd.accepted = FALSE;
7345 acd.cancelled = FALSE;
7346 while (!acd.accepted && ! acd.cancelled)
7347 {
7348 ProcessExternalEvent ();
7349 Update ();
7350 }
7351 ProcessAnEvent ();
7352 etp = (ExistingTextPtr) MemNew (sizeof (ExistingTextData));
7353 if (acd.cancelled)
7354 {
7355 etp->existing_text_choice = eExistingTextChoiceCancel;
7356 }
7357 else
7358 {
7359 handle_choice = GetValue (etdd.pre_app_grp);
7360 if (handle_choice == 1)
7361 {
7362 switch (GetValue (etdd.delim_grp))
7363 {
7364 case 1:
7365 etp->existing_text_choice = eExistingTextChoiceAppendSemi;
7366 break;
7367 case 2:
7368 etp->existing_text_choice = eExistingTextChoiceAppendSpace;
7369 break;
7370 case 3:
7371 etp->existing_text_choice = eExistingTextChoiceAppendColon;
7372 break;
7373 case 4:
7374 etp->existing_text_choice = eExistingTextChoiceAppendNone;
7375 break;
7376 }
7377 }
7378 else if (handle_choice == 2)
7379 {
7380 switch (GetValue (etdd.delim_grp))
7381 {
7382 case 1:
7383 etp->existing_text_choice = eExistingTextChoicePrefixSemi;
7384 break;
7385 case 2:
7386 etp->existing_text_choice = eExistingTextChoicePrefixSpace;
7387 break;
7388 case 3:
7389 etp->existing_text_choice = eExistingTextChoicePrefixColon;
7390 break;
7391 case 4:
7392 etp->existing_text_choice = eExistingTextChoicePrefixNone;
7393 break;
7394 }
7395 }
7396 else
7397 {
7398 etp->existing_text_choice = eExistingTextChoiceLeaveOld;
7399 }
7400 }
7401 Remove (w);
7402 return etp;
7403 }
7404
7405 extern CharPtr HandleExistingText (CharPtr existing_text, CharPtr new_text, ExistingTextPtr etp)
7406 {
7407 CharPtr rstring = NULL;
7408 Int4 len;
7409
7410 if (StringHasNoText (existing_text) || etp == NULL)
7411 {
7412 MemFree (existing_text);
7413 return new_text;
7414 }
7415 switch (etp->existing_text_choice)
7416 {
7417 case eExistingTextChoiceReplaceOld:
7418 /* replace current text with new text */
7419 MemFree (existing_text);
7420 rstring = new_text;
7421 break;
7422 case eExistingTextChoiceLeaveOld:
7423 /* do not change current text */
7424 MemFree (new_text);
7425 rstring = existing_text;
7426 break;
7427 case eExistingTextChoiceAppendSemi:
7428 /* Append new text to current text, separated by semicolon */
7429 len = StringLen (new_text) + StringLen (existing_text) + 4;
7430 rstring = MemNew (len);
7431 if (rstring != NULL) {
7432 StringCpy (rstring, existing_text);
7433 StringCat (rstring, "; ");
7434 StringCat (rstring, new_text);
7435 MemFree (new_text);
7436 MemFree (existing_text);
7437 }
7438 break;
7439 case eExistingTextChoiceAppendSpace:
7440 /* Append new text to current text, separated by space */
7441 len = StringLen (new_text) + StringLen (existing_text) + 3;
7442 rstring = MemNew (len);
7443 if (rstring != NULL) {
7444 StringCpy (rstring, existing_text);
7445 StringCat (rstring, " ");
7446 StringCat (rstring, new_text);
7447 MemFree (new_text);
7448 MemFree (existing_text);
7449 }
7450 break;
7451 case eExistingTextChoiceAppendColon:
7452 /* Append new text to current text, separated by colon */
7453 len = StringLen (new_text) + StringLen (existing_text) + 4;
7454 rstring = MemNew (len);
7455 if (rstring != NULL) {
7456 StringCpy (rstring, existing_text);
7457 StringCat (rstring, ": ");
7458 StringCat (rstring, new_text);
7459 MemFree (new_text);
7460 MemFree (existing_text);
7461 }
7462 break;
7463 case eExistingTextChoiceAppendNone:
7464 /* Append new text to current text, no delimiter */
7465 len = StringLen (new_text) + StringLen (existing_text) + 1;
7466 rstring = MemNew (len);
7467 if (rstring != NULL) {
7468 StringCpy (rstring, existing_text);
7469 StringCat (rstring, new_text);
7470 MemFree (new_text);
7471 MemFree (existing_text);
7472 }
7473 break;
7474 case eExistingTextChoicePrefixSemi:
7475 /* Prepend new text to current text, separated by semicolon */
7476 len = StringLen (new_text) + StringLen (existing_text) + 4;
7477 rstring = MemNew (len);
7478 if (rstring != NULL) {
7479 StringCpy (rstring, new_text);
7480 StringCat (rstring, "; ");
7481 StringCat (rstring, existing_text);
7482 MemFree (new_text);
7483 MemFree (existing_text);
7484 }
7485 break;
7486 case eExistingTextChoicePrefixSpace:
7487 /* Prepend new text to current text, separated by space */
7488 len = StringLen (new_text) + StringLen (existing_text) + 3;
7489 rstring = MemNew (len);
7490 if (rstring != NULL) {
7491 StringCpy (rstring, new_text);
7492 StringCat (rstring, " ");
7493 StringCat (rstring, existing_text);
7494 MemFree (new_text);
7495 MemFree (existing_text);
7496 }
7497 break;
7498 case eExistingTextChoicePrefixColon:
7499 /* Prepend new text to current text, separated by colon */
7500 len = StringLen (new_text) + StringLen (existing_text) + 4;
7501 rstring = MemNew (len);
7502 if (rstring != NULL) {
7503 StringCpy (rstring, new_text);
7504 StringCat (rstring, ": ");
7505 StringCat (rstring, existing_text);
7506 MemFree (new_text);
7507 MemFree (existing_text);
7508 }
7509 break;
7510 case eExistingTextChoicePrefixNone:
7511 /* prefix current text with new text */
7512 len = StringLen (new_text) + StringLen (existing_text) + 1;
7513 rstring = MemNew (len);
7514 if (rstring != NULL) {
7515 StringCpy (rstring, new_text);
7516 StringCat (rstring, existing_text);
7517 MemFree (new_text);
7518 MemFree (existing_text);
7519 }
7520 break;
7521 }
7522 return rstring;
7523 }
7524
7525
7526 /* Move EditApply data and dialog here */
7527 extern EditApplyPtr EditApplyFree (EditApplyPtr eap)
7528 {
7529 if (eap != NULL)
7530 {
7531 eap->find_txt = MemFree (eap->find_txt);
7532 eap->repl_txt = MemFree (eap->repl_txt);
7533 eap->apply_txt = MemFree (eap->apply_txt);
7534 eap = MemFree (eap);
7535 }
7536 return eap;
7537 }
7538
7539
7540 extern EditApplyPtr EditApplyNew (void)
7541 {
7542 EditApplyPtr eap;
7543
7544 eap = (EditApplyPtr) MemNew (sizeof (EditApplyData));
7545 eap->find_location = EditApplyFindLocation_anywhere;
7546 return eap;
7547 }
7548
7549
7550 typedef struct EditApplydlg
7551 {
7552 DIALOG_MESSAGE_BLOCK
7553 TexT find_txt;
7554 TexT repl_txt;
7555 TexT apply_txt;
7556
7557 DialoG find_dlg;
7558 DialoG repl_dlg;
7559 DialoG apply_dlg;
7560
7561 Int4 action_choice;
7562 GrouP location_choice;
7563 Nlm_ChangeNotifyProc change_notify;
7564 Pointer change_userdata;
7565 } EditApplyDlgData, PNTR EditApplyDlgPtr;
7566
7567 static void ResetEditApplyDlg (EditApplyDlgPtr dlg)
7568 {
7569 if (dlg != NULL)
7570 {
7571 if (dlg->find_txt != NULL)
7572 {
7573 SetTitle (dlg->find_txt, "");
7574 }
7575 if (dlg->repl_txt != NULL)
7576 {
7577 SetTitle (dlg->repl_txt, "");
7578 }
7579 if (dlg->apply_txt != NULL)
7580 {
7581 SetTitle (dlg->apply_txt, "");
7582 }
7583 if (dlg->location_choice != NULL) {
7584 SetValue (dlg->location_choice, EditApplyFindLocation_anywhere);
7585 }
7586
7587 PointerToDialog (dlg->find_dlg, NULL);
7588 PointerToDialog (dlg->repl_dlg, NULL);
7589 PointerToDialog (dlg->apply_dlg, NULL);
7590
7591 }
7592 }
7593
7594 static void EditApplyDialogChangeText (TexT t)
7595 {
7596 EditApplyDlgPtr dlg;
7597
7598 dlg = (EditApplyDlgPtr) GetObjectExtra (t);
7599 if (dlg != NULL && dlg->change_notify != NULL)
7600 {
7601 (dlg->change_notify)(dlg->change_userdata);
7602 }
7603 }
7604
7605 static void EditApplyToDialog (DialoG d, Pointer userdata)
7606 {
7607 EditApplyDlgPtr dlg;
7608 EditApplyPtr data;
7609 ValNode vn;
7610
7611 dlg = (EditApplyDlgPtr) GetObjectExtra (d);
7612 if (dlg == NULL)
7613 {
7614 return;
7615 }
7616
7617 ResetEditApplyDlg (dlg);
7618 data = (EditApplyPtr) userdata;
7619
7620 vn.next = NULL;
7621 vn.choice = 0;
7622
7623 if (data != NULL)
7624 {
7625 if (!StringHasNoText (data->find_txt))
7626 {
7627 if (dlg->find_txt != NULL)
7628 {
7629 SetTitle (dlg->find_txt, data->find_txt);
7630 }
7631 else if (dlg->find_dlg != NULL)
7632 {
7633 vn.data.ptrvalue = data->find_txt;
7634 PointerToDialog (dlg->find_dlg, &vn);
7635 }
7636 }
7637
7638 if (!StringHasNoText (data->repl_txt))
7639 {
7640 if (dlg->repl_txt != NULL)
7641 {
7642 SetTitle (dlg->repl_txt, data->repl_txt);
7643 }
7644 else if (dlg->repl_dlg != NULL)
7645 {
7646 vn.data.ptrvalue = data->repl_txt;
7647 PointerToDialog (dlg->repl_dlg, &vn);
7648 }
7649 }
7650
7651 if (!StringHasNoText (data->apply_txt))
7652 {
7653 if (dlg->apply_txt != NULL)
7654 {
7655 SetTitle (dlg->apply_txt, data->apply_txt);
7656 }
7657 else if (dlg->apply_dlg != NULL)
7658 {
7659 vn.data.ptrvalue = data->apply_txt;
7660 PointerToDialog (dlg->apply_dlg, &vn);
7661 }
7662 }
7663
7664 if (dlg->location_choice != NULL) {
7665 SetValue (dlg->location_choice, data->find_location);
7666 }
7667 }
7668 }
7669
7670 static Pointer DialogToEditApply (DialoG d)
7671 {
7672 EditApplyDlgPtr dlg;
7673 EditApplyPtr data;
7674 ValNodePtr vnp;
7675
7676 dlg = (EditApplyDlgPtr) GetObjectExtra (d);
7677 if (dlg == NULL)
7678 {
7679 return NULL;
7680 }
7681
7682 data = (EditApplyPtr) MemNew (sizeof (EditApplyData));
7683 if (data != NULL)
7684 {
7685 if (dlg->find_txt != NULL)
7686 {
7687 data->find_txt = JustSaveStringFromText (dlg->find_txt);
7688 }
7689 else if (dlg->find_dlg != NULL)
7690 {
7691 vnp = (ValNodePtr) DialogToPointer (dlg->find_dlg);
7692 if (vnp != NULL)
7693 {
7694 data->find_txt = StringSave (vnp->data.ptrvalue);
7695 }
7696 vnp = ValNodeFreeData (vnp);
7697 }
7698
7699 if (dlg->repl_txt != NULL)
7700 {
7701 data->repl_txt = JustSaveStringFromText (dlg->repl_txt);
7702 }
7703 else if (dlg->repl_dlg != NULL)
7704 {
7705 vnp = (ValNodePtr) DialogToPointer (dlg->repl_dlg);
7706 if (vnp != NULL)
7707 {
7708 data->repl_txt = StringSave (vnp->data.ptrvalue);
7709 }
7710 vnp = ValNodeFreeData (vnp);
7711 }
7712
7713 if (dlg->apply_txt != NULL)
7714 {
7715 data->apply_txt = JustSaveStringFromText (dlg->apply_txt);
7716 }
7717 else if (dlg->apply_dlg != NULL)
7718 {
7719 vnp = (ValNodePtr) DialogToPointer (dlg->apply_dlg);
7720 if (vnp != NULL)
7721 {
7722 data->apply_txt = StringSave (vnp->data.ptrvalue);
7723 }
7724 vnp = ValNodeFreeData (vnp);
7725 }
7726
7727 if (dlg->location_choice != NULL) {
7728 data->find_location = (EditApplyFindLocation) GetValue (dlg->location_choice);
7729 } else {
7730 data->find_location = EditApplyFindLocation_anywhere;
7731 }
7732 }
7733 return data;
7734 }
7735
7736
7737 static void EditApplyMessage (DialoG d, Int2 mssg)
7738
7739 {
7740 EditApplyDlgPtr dlg;
7741
7742 dlg = (EditApplyDlgPtr) GetObjectExtra (d);
7743 if (dlg != NULL) {
7744 switch (mssg)
7745 {
7746 case VIB_MSG_INIT :
7747 /* reset list */
7748 ResetEditApplyDlg (dlg);
7749 break;
7750 case VIB_MSG_ENTER :
7751 if (dlg->find_txt != NULL)
7752 {
7753 Select (dlg->find_txt);
7754 }
7755 else if (dlg->apply_txt != NULL)
7756 {
7757 Select (dlg->apply_txt);
7758 }
7759 else if (dlg->find_dlg != NULL)
7760 {
7761 Select (dlg->find_dlg);
7762 }
7763 else if (dlg->apply_dlg != NULL)
7764 {
7765 Select (dlg->apply_dlg);
7766 }
7767 break;
7768 default :
7769 break;
7770 }
7771 }
7772 }
7773
7774 static ValNodePtr TestEditApply (DialoG d)
7775 {
7776 EditApplyDlgPtr dlg;
7777 ValNodePtr total_err_list = NULL, err_list;
7778
7779 dlg = (EditApplyDlgPtr) GetObjectExtra (d);
7780 if (dlg == NULL)
7781 {
7782 return FALSE;
7783 }
7784
7785 if (dlg->action_choice == eEditApplyChoice_Apply)
7786 {
7787 if (dlg->apply_dlg == NULL)
7788 {
7789 if (TextHasNoText (dlg->apply_txt))
7790 {
7791 ValNodeAddPointer (&total_err_list, 0, StringSave ("apply text"));
7792 }
7793 }
7794 else
7795 {
7796 total_err_list = TestDialog (dlg->apply_dlg);
7797 }
7798 }
7799 else if (dlg->action_choice == eEditApplyChoice_Edit)
7800 {
7801 if (dlg->find_dlg == NULL)
7802 {
7803 if (TextHasNoText (dlg->find_txt))
7804 {
7805 ValNodeAddPointer (&total_err_list, 0, StringSave ("find text"));
7806 }
7807 }
7808 else
7809 {
7810 total_err_list = TestDialog (dlg->find_dlg);
7811 err_list = TestDialog (dlg->repl_dlg);
7812 ValNodeLink (&total_err_list, err_list);
7813 }
7814 }
7815 return total_err_list;
7816 }
7817
7818 static void EditApplyDialogCopy (ButtoN b)
7819 {
7820 EditApplyDlgPtr dlg;
7821 CharPtr str = NULL;
7822
7823 dlg = (EditApplyDlgPtr) GetObjectExtra (b);
7824 if (dlg == NULL)
7825 {
7826 return;
7827 }
7828 str = JustSaveStringFromText (dlg->find_txt);
7829 SetTitle (dlg->repl_txt, str);
7830 str = MemFree (str);
7831 }
7832
7833 extern DialoG EditApplyDialog
7834 (GrouP h,
7835 Int4 action_choice,
7836 CharPtr apply_label,
7837 ValNodePtr choice_list,
7838 Nlm_ChangeNotifyProc change_notify,
7839 Pointer change_userdata)
7840 {
7841 EditApplyDlgPtr dlg;
7842 GrouP p, p1 = NULL;
7843 ButtoN b;
7844 ValNodePtr cpy;
7845
7846 dlg = (EditApplyDlgPtr) MemNew (sizeof (EditApplyDlgData));
7847 if (dlg == NULL)
7848 {
7849 return NULL;
7850 }
7851
7852 p = HiddenGroup (h, -1, 0, NULL);
7853 SetObjectExtra (p, dlg, StdCleanupExtraProc);
7854 SetGroupSpacing (p, 10, 10);
7855
7856 dlg->dialog = (DialoG) p;
7857 dlg->todialog = EditApplyToDialog;
7858 dlg->fromdialog = DialogToEditApply;
7859 dlg->dialogmessage = EditApplyMessage;
7860 dlg->testdialog = TestEditApply;
7861 dlg->action_choice = action_choice;
7862 dlg->change_notify = change_notify;
7863 dlg->change_userdata = change_userdata;
7864
7865 if (choice_list == NULL)
7866 {
7867 p1 = HiddenGroup (p, 3, 0, NULL);
7868 SetGroupSpacing (p1, 10, 10);
7869
7870 if (action_choice == eEditApplyChoice_Apply)
7871 {
7872 StaticPrompt (p1, apply_label, 0, dialogTextHeight, systemFont, 'r');
7873 dlg->apply_txt = DialogText (p1, "", 20, EditApplyDialogChangeText);
7874 SetObjectExtra (dlg->apply_txt, dlg, NULL);
7875 dlg->location_choice = NULL;
7876 }
7877 else if (action_choice == eEditApplyChoice_Edit)
7878 {
7879 StaticPrompt (p1, "Find", 0, dialogTextHeight, systemFont, 'r');
7880 dlg->find_txt = DialogText (p1, "", 18, EditApplyDialogChangeText);
7881 SetObjectExtra (dlg->find_txt, dlg, NULL);
7882 b = PushButton (p1, "Copy", EditApplyDialogCopy);
7883 SetObjectExtra (b, dlg, NULL);
7884 Hide (b);
7885 StaticPrompt (p1, "Replace", 0, dialogTextHeight, systemFont, 'r');
7886 dlg->repl_txt = DialogText (p1, "", 18, EditApplyDialogChangeText);
7887 SetObjectExtra (dlg->repl_txt, dlg, NULL);
7888 b = PushButton (p1, "Copy", EditApplyDialogCopy);
7889 SetObjectExtra (b, dlg, NULL);
7890
7891 dlg->location_choice = HiddenGroup (p, 3, 0, NULL);
7892 RadioButton (dlg->location_choice, "Anywhere in field");
7893 RadioButton (dlg->location_choice, "At the beginning of the field");
7894 RadioButton (dlg->location_choice, "At the end of the field");
7895 SetValue (dlg->location_choice, EditApplyFindLocation_anywhere);
7896 }
7897 }
7898 else
7899 {
7900 if (action_choice == eEditApplyChoice_Apply)
7901 {
7902 p1 = HiddenGroup (p, 1, 0, NULL);
7903 SetGroupSpacing (p1, 10, 10);
7904 if (!StringHasNoText (apply_label))
7905 {
7906 StaticPrompt (p1, apply_label, 0, dialogTextHeight, systemFont, 'r');
7907 }
7908 cpy = ValNodeDupStringList (choice_list);
7909 dlg->apply_dlg = ValNodeSelectionDialog (p1, cpy, 6,
7910 ValNodeStringName,
7911 ValNodeSimpleDataFree,
7912 ValNodeStringCopy,
7913 ValNodeStringMatch,
7914 apply_label,
7915 dlg->change_notify, dlg->change_userdata, FALSE);
7916 }
7917 else if (action_choice == eEditApplyChoice_Edit)
7918 {
7919 p1 = HiddenGroup (p, 2, 0, NULL);
7920 SetGroupSpacing (p1, 10, 10);
7921 StaticPrompt (p1, "From", 0, dialogTextHeight, systemFont, 'r');
7922 StaticPrompt (p1, "To", 0, dialogTextHeight, systemFont, 'r');
7923
7924 cpy = ValNodeDupStringList (choice_list);
7925 dlg->find_dlg = ValNodeSelectionDialog (p1, cpy, 6,
7926 ValNodeStringName,
7927 ValNodeSimpleDataFree,
7928 ValNodeStringCopy,
7929 ValNodeStringMatch,
7930 "Original",
7931 dlg->change_notify, dlg->change_userdata, FALSE);
7932 cpy = ValNodeDupStringList (choice_list);
7933 dlg->repl_dlg = ValNodeSelectionDialog (p1, cpy, 6,
7934 ValNodeStringName,
7935 ValNodeSimpleDataFree,
7936 ValNodeStringCopy,
7937 ValNodeStringMatch,
7938 "New",
7939 dlg->change_notify, dlg->change_userdata, FALSE);
7940
7941 }
7942 dlg->location_choice = NULL;
7943 }
7944 AlignObjects (ALIGN_CENTER, (HANDLE) p1, (HANDLE) dlg->location_choice, NULL);
7945
7946 return (DialoG) p;
7947 }
7948
7949
7950 /* Global Inference Editor Dialog */
7951
7952 extern InferenceParsePtr ParseInferenceText (CharPtr inference)
7953 {
7954 CharPtr cp1, cp2;
7955 Int4 len;
7956 InferenceParsePtr ipp;
7957
7958 if (StringHasNoText (inference))
7959 {
7960 return NULL;
7961 }
7962
7963 cp1 = StringChr (inference, ':');
7964 if (cp1 == NULL)
7965 {
7966 return NULL;
7967 }
7968 cp2 = StringChr (cp1 + 1, ':');
7969 if (cp2 == NULL)
7970 {
7971 return NULL;
7972 }
7973
7974 ipp = (InferenceParsePtr) MemNew (sizeof (InferenceParseData));
7975 ipp->second_field = StringSave (cp2 + 1);
7976
7977 len = cp2 - cp1;
7978 ipp->first_field = (CharPtr) MemNew (sizeof (Char) * len);
7979 StringNCpy (ipp->first_field, cp1 + 1, len - 1);
7980 ipp->first_field[len - 1] = 0;
7981
7982 /* look for same species */
7983 cp2 = StringISearch (inference, "(same species)");
7984 if (cp2 != NULL && cp2 < cp1)
7985 {
7986 ipp->same_species = TRUE;
7987 cp1 = cp2;
7988 }
7989 else
7990 {
7991 ipp->same_species = FALSE;
7992 }
7993 len = cp1 - inference + 1;
7994 ipp->category = (CharPtr) MemNew (sizeof (Char) * len);
7995 StringNCpy (ipp->category, inference, len - 1);
7996 ipp->category[len - 1] = 0;
7997 TrimSpacesAroundString (ipp->category);
7998 TrimSpacesAroundString (ipp->first_field);
7999 TrimSpacesAroundString (ipp->second_field);
8000
8001 return ipp;
8002 }
8003
8004
8005 extern CharPtr InferenceTextFromStruct (InferenceParsePtr ipp)
8006 {
8007 Int4 len;
8008 CharPtr inference = NULL;
8009 CharPtr same_sp = " (same species)";
8010
8011 if (ipp == NULL) return NULL;
8012
8013 len = StringLen (ipp->category) + StringLen (ipp->first_field) + StringLen (ipp->second_field)
8014 + 3;
8015 if (ipp->same_species)
8016 {
8017 len += StringLen (same_sp);
8018 }
8019
8020 inference = (CharPtr) MemNew (sizeof (Char) * len);
8021 sprintf (inference, "%s%s:%s:%s", ipp->category == NULL ? "" : ipp->category,
8022 ipp->same_species ? same_sp : "",
8023 ipp->first_field == NULL ? "" : ipp->first_field,
8024 ipp->second_field == NULL ? "" : ipp->second_field);
8025 return inference;
8026 }
8027
8028
8029 typedef enum {
8030 eInferenceCategorySimilarTo = 0,
8031 eInferenceCategoryProgram,
8032 eInferenceCategoryAbInitio,
8033 eNumInferenceCategories } EInferenceCategoryType;
8034
8035
8036 static Int4 GetCategoryTypeFromNum (Int4 num)
8037 {
8038 if (num > 0 && num < 8)
8039 {
8040 return eInferenceCategorySimilarTo;
8041 }
8042 else if (num > 7 && num < 11)
8043 {
8044 return eInferenceCategoryProgram;
8045 }
8046 else if (num == 11)
8047 {
8048 return eInferenceCategoryAbInitio;
8049 }
8050 else
8051 {
8052 return -1;
8053 }
8054 }
8055
8056
8057 static Int4 GetCategoryNumFromName (CharPtr category)
8058 {
8059 Int4 i;
8060
8061 if (StringHasNoText (category))
8062 {
8063 return -1;
8064 }
8065
8066 for (i = 0; inference_alist[i].name != NULL; i++)
8067 {
8068 if (StringICmp (inference_alist[i].name, category) == 0)
8069 {
8070 return i;
8071 }
8072 }
8073 return -1;
8074 }
8075
8076
8077 extern InferenceFieldEditPtr InferenceFieldEditFree (InferenceFieldEditPtr ifep)
8078 {
8079 if (ifep != NULL)
8080 {
8081 ifep->edit_apply = EditApplyFree (ifep->edit_apply);
8082 ifep = MemFree (ifep);
8083 }
8084 return ifep;
8085 }
8086
8087 extern InferenceEditPtr InferenceEditFree (InferenceEditPtr iep)
8088 {
8089 if (iep != NULL)
8090 {
8091 iep->field_edit = InferenceFieldEditFree (iep->field_edit);
8092 iep = MemFree (iep);
8093 }
8094 return iep;
8095 }
8096
8097 typedef struct inferencefieldeditdialog
8098 {
8099 DIALOG_MESSAGE_BLOCK
8100
8101 PopuP field_category;
8102 PopuP field_list[eNumInferenceCategories];
8103 DialoG field_editors[eNumInferenceCategories * 2];
8104 Nlm_ChangeNotifyProc change_notify;
8105 Pointer change_userdata;
8106
8107 } InferenceFieldEditDialogData, PNTR InferenceFieldEditDialogPtr;
8108
8109
8110 static Pointer InferenceFieldEditDataFromDialog (DialoG d)
8111 {
8112 InferenceFieldEditDialogPtr dlg;
8113 UIEnum val;
8114 Int4 i, j;
8115 InferenceFieldEditPtr data = NULL;
8116
8117 dlg = (InferenceFieldEditDialogPtr) GetObjectExtra (d);
8118 if (dlg == NULL) return NULL;
8119
8120 if (GetEnumPopup (dlg->field_category, inference_alist, &val)
8121 && val > 0
8122 && (i = GetCategoryTypeFromNum (val)) > -1
8123 && (j = GetValue (dlg->field_list[i])) > 0
8124 && j < 3)
8125 {
8126 data = (InferenceFieldEditPtr) MemNew (sizeof (InferenceFieldEditData));
8127 data->field_category = inferencePrefix[val];
8128 data->field_choice = j - 1;
8129 data->edit_apply = DialogToPointer (dlg->field_editors[2 * i + j - 1]);
8130 }
8131 return data;
8132 }
8133
8134
8135 static void ChangeInferenceFieldChoice (PopuP p)
8136 {
8137 InferenceFieldEditDialogPtr dlg;
8138 UIEnum val;
8139 Int4 i, j;
8140
8141 dlg = (InferenceFieldEditDialogPtr) GetObjectExtra (p);
8142 if (dlg == NULL) return;
8143
8144 for (i = eInferenceCategorySimilarTo;
8145 i <= eInferenceCategoryAbInitio;
8146 i++)
8147 {
8148 Hide (dlg->field_list[i]);
8149 Hide (dlg->field_editors[2 * i]);
8150 Hide (dlg->field_editors[2 * i + 1]);
8151 }
8152
8153 if (GetEnumPopup (dlg->field_category, inference_alist, &val)
8154 && val > 0
8155 && (i = GetCategoryTypeFromNum (val)) > -1)
8156 {
8157 Show (dlg->field_list[i]);
8158 j = GetValue (dlg->field_list[i]);
8159 if (j > 0 && j < 3)
8160 {
8161 Show (dlg->field_editors[2 * i + j - 1]);
8162 }
8163 }
8164
8165 if (dlg->change_notify != NULL)
8166 {
8167 (dlg->change_notify)(dlg->change_userdata);
8168 }
8169 }
8170
8171 static ValNodePtr MakeValNodeListFromEnum ( EnumFieldAssocPtr al)
8172 {
8173 EnumFieldAssocPtr efap;
8174 ValNodePtr list;
8175
8176 efap = al;
8177 list = NULL;
8178 while (efap->name != NULL)
8179 {
8180 ValNodeAddStr (&list, efap->value, StringSave (efap->name));
8181 efap ++;
8182 }
8183 return list;
8184 }
8185
8186
8187 static DialoG
8188 CreateInferenceFieldEditApplyDialog
8189 (GrouP h,
8190 Int4 action_choice,
8191 Nlm_ChangeNotifyProc change_notify,
8192 Pointer change_userdata)
8193 {
8194 InferenceFieldEditDialogPtr dlg;
8195 GrouP p, k;
8196 Int4 i;
8197 ValNodePtr choice_list;
8198
8199 dlg = (InferenceFieldEditDialogPtr) MemNew (sizeof (InferenceFieldEditDialogData));
8200 if (dlg == NULL)
8201 {
8202 return NULL;
8203 }
8204 p = HiddenGroup (h, 3, 0, NULL);
8205 SetObjectExtra (p, dlg, StdCleanupExtraProc);
8206 SetGroupSpacing (p, 10, 10);
8207
8208 dlg->dialog = (DialoG) p;
8209 dlg->todialog = NULL;
8210 dlg->fromdialog = InferenceFieldEditDataFromDialog;
8211 dlg->dialogmessage = NULL;
8212 dlg->testdialog = NULL;
8213
8214 dlg->change_notify = change_notify;
8215 dlg->change_userdata = change_userdata;
8216
8217 StaticPrompt (p, "Category", 0, popupMenuHeight, programFont, 'c');
8218 StaticPrompt (p, "Field", 0, popupMenuHeight, programFont, 'c');
8219 if (action_choice == eEditApplyChoice_Apply)
8220 {
8221 StaticPrompt (p, "New Value", 0, popupMenuHeight, programFont, 'c');
8222 }
8223 else
8224 {
8225 StaticPrompt (p, "Convert", 0, popupMenuHeight, programFont, 'c');
8226 }
8227
8228 dlg->field_category = PopupList (p, TRUE, ChangeInferenceFieldChoice);
8229 SetObjectExtra (dlg->field_category, dlg, NULL);
8230 InitEnumPopup (dlg->field_category, inference_alist, NULL);
8231
8232
8233 k = HiddenGroup (p, 0, 0, NULL);
8234 dlg->field_list[eInferenceCategorySimilarTo] = PopupList (k, TRUE, ChangeInferenceFieldChoice);
8235 SetObjectExtra (dlg->field_list[eInferenceCategorySimilarTo], dlg, NULL);
8236 PopupItem (dlg->field_list[eInferenceCategorySimilarTo], "Database");
8237 PopupItem (dlg->field_list[eInferenceCategorySimilarTo], "Accession");
8238
8239 dlg->field_list[eInferenceCategoryProgram] = PopupList (k, TRUE, ChangeInferenceFieldChoice);
8240 SetObjectExtra (dlg->field_list[eInferenceCategoryProgram], dlg, NULL);
8241 PopupItem (dlg->field_list[eInferenceCategoryProgram], "Program or Database");
8242 PopupItem (dlg->field_list[eInferenceCategoryProgram], "Version or Accession");
8243
8244 dlg->field_list[eInferenceCategoryAbInitio] = PopupList (k, TRUE, ChangeInferenceFieldChoice);
8245 SetObjectExtra (dlg->field_list[eInferenceCategoryAbInitio], dlg, NULL);
8246 PopupItem (dlg->field_list[eInferenceCategoryAbInitio], "Program");
8247 PopupItem (dlg->field_list[eInferenceCategoryAbInitio], "Program Version");
8248
8249 k = HiddenGroup (p, 0, 0, NULL);
8250 i = 0;
8251 choice_list = MakeValNodeListFromEnum (accn_type_alist);
8252 dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", choice_list, change_notify, change_userdata);
8253 dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", NULL, change_notify, change_userdata);
8254 dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", NULL, change_notify, change_userdata);
8255 dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", NULL, change_notify, change_userdata);
8256 choice_list = MakeValNodeListFromEnum (program_alist);
8257 dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", choice_list, change_notify, change_userdata);
8258 dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", NULL, change_notify, change_userdata);
8259
8260 ChangeInferenceFieldChoice (dlg->field_category);
8261 return (DialoG) p;
8262 }
8263
8264
8265 typedef struct inferenceeditdialog {
8266 DIALOG_MESSAGE_BLOCK
8267 PopuP action;
8268 GrouP action_pages[eNumInferenceEditActions];
8269 PopuP category_from;
8270 PopuP category_to;
8271
8272 DialoG apply_field;
8273 DialoG edit_field;
8274
8275 Nlm_ChangeNotifyProc change_notify;
8276 Pointer change_userdata;
8277
8278 } InferenceEditDialogData, PNTR InferenceEditDialogPtr;
8279
8280
8281 static Pointer InferenceEditDataFromDialog (DialoG d)
8282 {
8283 InferenceEditDialogPtr dlg;
8284 InferenceEditPtr data;
8285 Int4 i;
8286
8287 dlg = (InferenceEditDialogPtr) GetObjectExtra (d);
8288 if (dlg == NULL) return NULL;
8289
8290 data = (InferenceEditPtr) MemNew (sizeof (InferenceEditData));
8291 if (data == NULL) return NULL;
8292
8293 data->action = (EInferenceEditAction) (GetValue (dlg->action) - 1);
8294
8295 switch (data->action)
8296 {
8297 case eInferenceRemove:
8298 /* no other data needed */
8299 break;
8300 case eInferenceEditCategory:
8301 i = GetValue (dlg->category_from);
8302 if (i <= 1)
8303 {
8304 data->category_from = NULL;
8305 }
8306 else
8307 {
8308 data->category_from = inferencePrefix[i - 2];
8309 }
8310 i = GetValue (dlg->category_to);
8311 if (i < 1)
8312 {
8313 data->category_to = NULL;
8314 }
8315 else
8316 {
8317 data->category_to = inferencePrefix[i - 1];
8318 }
8319 break;
8320 case eInferenceApplyCategoryFields:
8321 data->field_edit = DialogToPointer (dlg->apply_field);
8322 break;
8323 case eInferenceEditCategoryFields:
8324 data->field_edit = DialogToPointer (dlg->edit_field);
8325 break;
8326 default:
8327 break;
8328 }
8329
8330 return data;
8331 }
8332
8333
8334 static void ChangeInferenceEditAction (PopuP p)
8335 {
8336 InferenceEditDialogPtr dlg;
8337 Int4 i;
8338
8339 dlg = (InferenceEditDialogPtr) GetObjectExtra (p);
8340 if (dlg == NULL) return;
8341
8342 ResetClip();
8343 for (i = 0; i < eNumInferenceEditActions; i++)
8344 {
8345 Hide (dlg->action_pages[i]);
8346 }
8347
8348 i = GetValue (dlg->action);
8349 if (i > 0 && i <= eNumInferenceEditActions)
8350 {
8351 Show (dlg->action_pages[i - 1]);
8352 }
8353
8354 if (dlg->change_notify != NULL)
8355 {
8356 (dlg->change_notify) (dlg->change_userdata);
8357 }
8358 }
8359
8360
8361 static void ChangeInferenceCategoryChoice (PopuP p)
8362 {
8363 InferenceEditDialogPtr dlg;
8364
8365 dlg = (InferenceEditDialogPtr) GetObjectExtra (p);
8366 if (dlg == NULL) return;
8367
8368 if (dlg->change_notify != NULL)
8369 {
8370 (dlg->change_notify) (dlg->change_userdata);
8371 }
8372 }
8373
8374
8375 static ValNodePtr TestInferenceEditDialog (DialoG d)
8376 {
8377 ValNodePtr err_list = NULL;
8378 InferenceEditPtr iep;
8379
8380 iep = DialogToPointer (d);
8381 if (iep == NULL)
8382 {
8383 ValNodeAddPointer (&err_list, 0, "no values");
8384 }
8385 else
8386 {
8387 switch (iep->action)
8388 {
8389 case eInferenceRemove:
8390 /* nothing to check */
8391 break;
8392 case eInferenceEditCategory:
8393 if (StringHasNoText (iep->category_from))
8394 {
8395 ValNodeAddPointer (&err_list, 0, "missing category from");
8396 }
8397 if (StringHasNoText (iep->category_to))
8398 {
8399 ValNodeAddPointer (&err_list, 0, "missing category to");
8400 }
8401 break;
8402 case eInferenceApplyCategoryFields:
8403 case eInferenceEditCategoryFields:
8404 if (iep->field_edit == NULL)
8405 {
8406 ValNodeAddPointer (&err_list, 0, "missing edit data");
8407 }
8408 break;
8409 default:
8410 break;
8411 }
8412 }
8413 iep = InferenceEditFree (iep);
8414
8415 return err_list;
8416 }
8417
8418
8419 extern DialoG CreateInferenceEditDialog
8420 (GrouP h,
8421 Nlm_ChangeNotifyProc change_notify,
8422 Pointer change_userdata)
8423 {
8424 InferenceEditDialogPtr dlg;
8425 GrouP p, g;
8426 Int4 i;
8427 Nlm_EnumFieldAssocPtr eap;
8428
8429 dlg = (InferenceEditDialogPtr) MemNew (sizeof (InferenceEditDialogData));
8430 if (dlg == NULL)
8431 {
8432 return NULL;
8433 }
8434 p = HiddenGroup (h, -1, 0, NULL);
8435 SetObjectExtra (p, dlg, StdCleanupExtraProc);
8436 SetGroupSpacing (p, 10, 10);
8437
8438 dlg->dialog = (DialoG) p;
8439 dlg->todialog = NULL;
8440 dlg->fromdialog = InferenceEditDataFromDialog;
8441 dlg->dialogmessage = NULL;
8442 dlg->testdialog = TestInferenceEditDialog;
8443
8444 dlg->change_notify = change_notify;
8445 dlg->change_userdata = change_userdata;
8446
8447 dlg->action = PopupList (p, TRUE, ChangeInferenceEditAction);
8448 SetObjectExtra (dlg->action, dlg, NULL);
8449 PopupItem (dlg->action, "Remove");
8450 PopupItem (dlg->action, "Change Category");
8451 PopupItem (dlg->action, "Apply Category Fields");
8452 PopupItem (dlg->action, "Edit Category Fields");
8453 SetValue (dlg->action, eInferenceRemove + 1);
8454
8455 g = HiddenGroup (p, 0, 0, NULL);
8456 i = 0;
8457
8458 /* remove group */
8459 dlg->action_pages[i] = HiddenGroup (g, -1, 0, NULL);
8460 StaticPrompt (dlg->action_pages[i], "Hit Accept to Remove Inferences", 0, popupMenuHeight, programFont, 'c');
8461 i++;
8462
8463 /* edit category group */
8464 dlg->action_pages[i] = HiddenGroup (g, 2, 0, NULL);
8465 StaticPrompt (dlg->action_pages[i], "Original Category", 0, popupMenuHeight, programFont, 'c');
8466 dlg->category_from = PopupList (dlg->action_pages[i], TRUE, ChangeInferenceCategoryChoice);
8467 SetObjectExtra (dlg->category_from, dlg, NULL);
8468 PopupItem (dlg->category_from, "Any");
8469 eap = inference_alist;
8470 while (eap->name != NULL) {
8471 PopupItem (dlg->category_from, eap->name);
8472 eap++;
8473 }
8474
8475 StaticPrompt (dlg->action_pages[i], "New Category", 0, popupMenuHeight, programFont, 'c');
8476 dlg->category_to = PopupList (dlg->action_pages[i], TRUE, ChangeInferenceCategoryChoice);
8477 SetObjectExtra (dlg->category_to, dlg, NULL);
8478 InitEnumPopup (dlg->category_to, inference_alist, NULL);
8479 i++;
8480
8481 dlg->action_pages[i] = HiddenGroup (g, 0, 0, NULL);
8482 dlg->apply_field = CreateInferenceFieldEditApplyDialog (dlg->action_pages[i], eEditApplyChoice_Apply, change_notify, change_userdata);
8483 i++;
8484
8485 dlg->action_pages[i] = HiddenGroup (g, 0, 0, NULL);
8486 dlg->edit_field = CreateInferenceFieldEditApplyDialog (dlg->action_pages[i], eEditApplyChoice_Edit, change_notify, change_userdata);
8487 i++;
8488
8489 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->action_pages[0],
8490 (HANDLE) dlg->action_pages[1],
8491 (HANDLE) dlg->action_pages[2],
8492 (HANDLE) dlg->action_pages[3],
8493 NULL);
8494
8495 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->action, (HANDLE) g, NULL);
8496
8497 ChangeInferenceEditAction (dlg->action);
8498
8499 return (DialoG) p;
8500 }
8501
8502
8503 /* This section of code is for handling ClickableLists */
8504
8505 typedef struct clickableitemlist
8506 {
8507 DIALOG_MESSAGE_BLOCK
8508 DoC doc;
8509
8510 Nlm_ParData par_fmt;
8511 Nlm_ColData col_fmt [4];
8512
8513 ClickableCallback single_click_callback;
8514 ClickableCallback double_click_callback;
8515 Pointer click_callback_data;
8516 GetClickableItemText get_item_text;
8517 ValNodePtr item_list;
8518 Int2 selected;
8519 } ClickableItemListDlgData, PNTR ClickableItemListDlgPtr;
8520
8521 static void PointerToClickableItemListDlg (DialoG d, Pointer data)
8522 {
8523 ClickableItemListDlgPtr dlg;
8524 ValNodePtr vnp;
8525 CharPtr row_text;
8526 Int2 numItems;
8527 RecT r;
8528
8529 dlg = (ClickableItemListDlgPtr) GetObjectExtra (d);
8530 if (dlg == NULL) return;
8531
8532 Reset (dlg->doc);
8533
8534 if (dlg->get_item_text == NULL)
8535 {
8536 return;
8537 }
8538
8539 ObjectRect (dlg->doc, &r);
8540 InsetRect (&r, 4, 4);
8541
8542 dlg->col_fmt[0].pixWidth = 5 * stdCharWidth;
8543 dlg->col_fmt[1].pixWidth = (r.right - r.left - dlg->col_fmt[0].pixWidth) / 3;
8544 dlg->col_fmt[2].pixWidth = (r.right - r.left - dlg->col_fmt[0].pixWidth) / 3;
8545 dlg->col_fmt[3].pixWidth = (r.right - r.left - dlg->col_fmt[0].pixWidth) / 3;
8546
8547 dlg->item_list = ClickableItemObjectListFree (dlg->item_list);
8548 dlg->item_list = (ValNodePtr) data;
8549
8550 if (dlg->item_list == NULL)
8551 {
8552 AppendText (dlg->doc, "No items listed", NULL, NULL, programFont);
8553 } else {
8554 for (vnp = dlg->item_list; vnp != NULL; vnp = vnp->next) {
8555 row_text = dlg->get_item_text (vnp);
8556 if (row_text != NULL)
8557 {
8558 if (vnp->choice == OBJ_SEQFEAT)
8559 {
8560 AppendText (dlg->doc, row_text, &(dlg->par_fmt), dlg->col_fmt, programFont);
8561 }
8562 else
8563 {
8564 AppendText (dlg->doc, row_text, &(dlg->par_fmt), NULL, programFont);
8565 }
8566 row_text = MemFree (row_text);
8567 }
8568 }
8569 }
8570
8571 GetDocParams (dlg->doc, &numItems, NULL);
8572 UpdateDocument (dlg->doc, 0, numItems);
8573 }
8574
8575
8576 static void ClickClickableItemList (DoC d, PoinT pt)
8577
8578 {
8579 Int2 item, last_selected, numItems;
8580 Int2 row, i;
8581 ClickableItemListDlgPtr dlg;
8582 ValNodePtr vnp;
8583
8584 dlg = GetObjectExtra (d);
8585 if (dlg != NULL) {
8586 MapDocPoint (d, pt, &item, &row, NULL, NULL);
8587 if (item > 0 && row > 0) {
8588 i = 1;
8589 vnp = dlg->item_list;
8590 while (i < item && vnp != NULL) {
8591 i++;
8592 vnp = vnp->next;
8593 }
8594 if (vnp != NULL) {
8595 last_selected = dlg->selected;
8596 dlg->selected = item;
8597
8598 if (item != last_selected)
8599 {
8600 GetDocParams (d, &numItems, NULL);
8601 UpdateDocument (d, 0, numItems);
8602 }
8603
8604 if (dblClick)
8605 {
8606 if (dlg->double_click_callback != NULL) {
8607 (dlg->double_click_callback) (vnp, dlg->click_callback_data);
8608 }
8609 } else {
8610 if (dlg->single_click_callback != NULL) {
8611 (dlg->single_click_callback) (vnp, dlg->click_callback_data);
8612 }
8613 }
8614 }
8615 }
8616 }
8617 }
8618
8619
8620 static void DrawClickableItemList (DoC d, RectPtr r, Int2 item, Int2 firstLine)
8621
8622 {
8623 ClickableItemListDlgPtr dlg;
8624 RecT rct;
8625
8626 dlg = (ClickableItemListDlgPtr) GetObjectExtra (d);
8627 if (dlg != NULL && r != NULL && item > 0 && firstLine == 0) {
8628 rct = *r;
8629
8630 /* draw selection */
8631 if (item == dlg->selected) {
8632 rct = *r;
8633 rct.right = rct.left + 4;
8634 PaintRect (&rct);
8635 }
8636 }
8637 }
8638
8639
8640 static void CleanupClickableItemListDlg (GraphiC g, VoidPtr data)
8641 {
8642 ClickableItemListDlgPtr dlg;
8643
8644 dlg = (ClickableItemListDlgPtr) data;
8645 if (dlg != NULL) {
8646 dlg->item_list = ClickableItemObjectListFree (dlg->item_list);
8647 }
8648 StdCleanupExtraProc (g, data);
8649 }
8650
8651 static DialoG
8652 ClickableItemListDialog
8653 (GrouP h,
8654 Int4 width,
8655 GetClickableItemText get_item_text,
8656 ClickableCallback single_click_callback,
8657 ClickableCallback double_click_callback,
8658 Pointer click_callback_data)
8659 {
8660 ClickableItemListDlgPtr dlg;
8661 GrouP p;
8662 Int4 i;
8663
8664 dlg = (ClickableItemListDlgPtr) MemNew (sizeof (ClickableItemListDlgData));
8665 p = HiddenGroup (h, -1, 0, NULL);
8666 SetObjectExtra (p, dlg, CleanupClickableItemListDlg);
8667 dlg->dialog = (DialoG) p;
8668 dlg->todialog = PointerToClickableItemListDlg;
8669
8670 dlg->get_item_text = get_item_text;
8671 dlg->single_click_callback = single_click_callback;
8672 dlg->double_click_callback = double_click_callback;
8673 dlg->click_callback_data = click_callback_data;
8674 /* initialize paragraph format */
8675 dlg->par_fmt.openSpace = FALSE;
8676 dlg->par_fmt.keepWithNext = FALSE;
8677 dlg->par_fmt.keepTogether = FALSE;
8678 dlg->par_fmt.newPage = FALSE;
8679 dlg->par_fmt.tabStops = FALSE;
8680 dlg->par_fmt.minLines = 0;
8681 dlg->par_fmt.minHeight = 0;
8682
8683 /* initialize column format */
8684 for (i = 0; i < 4; i++) {
8685 dlg->col_fmt[i].pixWidth = 0;
8686 dlg->col_fmt[i].pixInset = 0;
8687 dlg->col_fmt[i].charWidth = 10;
8688 dlg->col_fmt[i].charInset = 0;
8689 dlg->col_fmt[i].font = NULL;
8690 dlg->col_fmt[i].just = 'l';
8691 dlg->col_fmt[i].wrap = 1;
8692 dlg->col_fmt[i].bar = 0;
8693 dlg->col_fmt[i].underline = 0;
8694 dlg->col_fmt[i].left = 0;
8695 dlg->col_fmt[i].last = FALSE;
8696 }
8697 dlg->col_fmt[0].pixInset = 5;
8698 dlg->col_fmt[3].last = TRUE;
8699
8700 dlg->doc = DocumentPanel (p, width, stdLineHeight * 20);
8701 SetObjectExtra (dlg->doc, dlg, NULL);
8702 SetDocAutoAdjust (dlg->doc, FALSE);
8703 SetDocProcs (dlg->doc, ClickClickableItemList, NULL, NULL, NULL);
8704 SetDocShade (dlg->doc, DrawClickableItemList, NULL, NULL, NULL);
8705
8706 return (DialoG) p;
8707 }
8708
8709 typedef struct clickablelist
8710 {
8711 DIALOG_MESSAGE_BLOCK
8712 DoC doc;
8713 DialoG clickable_item_list;
8714 PrompT title1;
8715 PrompT title2;
8716 PrompT help1;
8717 PrompT help2;
8718 TexT find_txt;
8719
8720 ClickableCallback item_single_click_callback;
8721 ClickableCallback item_double_click_callback;
8722 Pointer item_click_callback_data;
8723 GetClickableItemText get_item_text;
8724 Boolean dblClick;
8725 Int2 clicked;
8726 Int2 selected;
8727 Int2 item_selected;
8728 Int4 num_levels;
8729 ValNodePtr list_list;
8730 Nlm_ColPtr PNTR col_fmt_array_array;
8731
8732 Int2 text_select_item_start;
8733 Int2 text_select_row_start;
8734 Int2 text_select_char_start;
8735 Int2 text_select_item_stop;
8736 Int2 text_select_row_stop;
8737 Int2 text_select_char_stop;
8738 Int2 text_select_item_anchor;
8739 Int2 text_select_row_anchor;
8740 Int2 text_select_char_anchor;
8741
8742 Boolean display_chosen;
8743 } ClickableListData, PNTR ClickableListPtr;
8744
8745
8746 static Nlm_ParData clickableParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
8747 static Nlm_ColData clickableColFmt[2] = {{16, 0, 0, 0, NULL, 'l', 0,0,0,0, FALSE},
8748 {1000, 0, 0, 0, NULL, 'l', 1,0,0,0, TRUE}};
8749
8750
8751 static Nlm_ColPtr PNTR FreeColumnFormatArrays (Nlm_ColPtr PNTR col_fmt_array_array, Int4 num_levels)
8752 {
8753 Int4 n;
8754
8755 if (col_fmt_array_array == NULL || num_levels < 1)
8756 {
8757 return NULL;
8758 }
8759 for (n = 0; n < num_levels; n++)
8760 {
8761 col_fmt_array_array [n] = MemFree (col_fmt_array_array [n]);
8762 }
8763 col_fmt_array_array = MemFree (col_fmt_array_array);
8764 return col_fmt_array_array;
8765 }
8766
8767 static void CleanupClickableListDialog (GraphiC g, VoidPtr data)
8768
8769 {
8770 ClickableListPtr dlg;
8771
8772 dlg = (ClickableListPtr) data;
8773 if (dlg != NULL) {
8774 dlg->col_fmt_array_array = FreeColumnFormatArrays (dlg->col_fmt_array_array, dlg->num_levels);
8775 }
8776 StdCleanupExtraProc (g, data);
8777 }
8778
8779
8780 static ClickableItemPtr GetSubItem (ValNodePtr item_list, Int2Ptr pitem)
8781 {
8782 ClickableItemPtr cip = NULL;
8783
8784 if (item_list == NULL || pitem == NULL)
8785 {
8786 return NULL;
8787 }
8788 while (*pitem > 0 && item_list != NULL)
8789 {
8790 (*pitem)--;
8791 cip = (ClickableItemPtr) item_list->data.ptrvalue;
8792 if (*pitem > 0)
8793 {
8794 if (cip != NULL && cip->expanded)
8795 {
8796 cip = GetSubItem (cip->subcategories, pitem);
8797 }
8798 }
8799 item_list = item_list->next;
8800 }
8801 if (*pitem > 0)
8802 {
8803 cip = NULL;
8804 }
8805 return cip;
8806 }
8807
8808 static Int4 CountLevels (ValNodePtr item_list)
8809 {
8810 Int4 num, num_sublevels = 0;
8811 ValNodePtr vnp;
8812 ClickableItemPtr cip;
8813
8814 if (item_list == NULL)
8815 {
8816 return 0;
8817 }
8818
8819 for (vnp = item_list; vnp != NULL; vnp = vnp->next)
8820 {
8821 cip = (ClickableItemPtr) vnp->data.ptrvalue;
8822 if (cip == NULL || cip->subcategories == NULL || !cip->expanded)
8823 {
8824 continue;
8825 }
8826 num = CountLevels (cip->subcategories);
8827 if (num > num_sublevels) num_sublevels = num;
8828 }
8829
8830 /* one level for the top plus levels for the subcategories */
8831
8832 return 1 + num_sublevels;
8833 }
8834
8835
8836 static ClickableItemPtr GetSelectedClickableL