1 /*   sequin5.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:  sequin5.c
27 *
28 * Author:  Jonathan Kans
29 *
30 * Version Creation Date:   8/26/97
31 *
32 * $Revision: 6.798 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date     Name        Description of modification
39 * -------  ----------  -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44 
45 #define USE_BLAST3
46 
47 #include "sequin.h"
48 #include <document.h>
49 #include <biosrc.h>
50 #include <jzcoll.h>
51 #include <objsub.h>
52 #ifdef USE_BLAST3
53 #include <netblap3.h>
54 #else
55 #include <netblap2.h>
56 #include <blast2.h>
57 #endif
58 #include <dust.h>
59 #include <pobutil.h>
60 #include <saledit.h>
61 #include <salstruc.h>
62 #include <salfiles.h>
63 #include <salign.h>
64 #include <salsap.h>
65 #include <gbfeat.h>
66 #include <gbftdef.h>
67 #include <satutil.h>
68 #include <rpsutil.h>
69 #include <subutil.h>
70 #include <explore.h>
71 #include <import.h>
72 #include <salutil.h>
73 
74 #include <asn2gnbp.h> /* added for  parse to flatfile */
75 #include <sqnutils.h> /* added to include SeqEdTranslateOneCDS */
76 #include <seqpanel.h>
77 #include <salpanel.h>
78 #include <tax3api.h> /* added for specific-host corrections */
79 #include <findrepl.h>
80 #include <valid.h> /* added for latloncountry conflict checking */
81 #include <vsmutil.h>
82 
83 #define NLM_GENERATED_CODE_PROTO
84 #include <objmacro.h>
85 #include <macroapi.h>
86 
87 
CommonLaunchBioseqViewer(SeqEntryPtr sep,CharPtr path,Boolean directToEditor)88 static void CommonLaunchBioseqViewer (SeqEntryPtr sep, CharPtr path, Boolean directToEditor)
89 
90 {
91   BioseqPtr     bsp;
92   BioseqSetPtr  bssp;
93   Pointer       dataptr;
94   Uint2         datatype;
95   Uint2         entityID;
96   Int2          handled;
97 
98   if (sep != NULL) {
99     if (IS_Bioseq (sep)) {
100       datatype = OBJ_BIOSEQ;
101     } else if (IS_Bioseq_set (sep)) {
102       datatype = OBJ_BIOSEQSET;
103     } else {
104       sep = SeqEntryFree (sep);
105       return;
106     }
107     dataptr = (Pointer) sep->data.ptrvalue;
108     entityID = ObjMgrRegister (datatype, dataptr);
109     if (dataptr != NULL && entityID > 0) {
110       if (datatype == OBJ_SEQSUB || datatype == OBJ_SEQENTRY ||
111           datatype == OBJ_BIOSEQ || datatype == OBJ_BIOSEQSET) {
112         WatchCursor ();
113         sep = GetTopSeqEntryForEntityID (entityID);
114         if (sep == NULL) {
115           sep = SeqEntryNew ();
116           if (sep != NULL) {
117             if (datatype == OBJ_BIOSEQ) {
118               bsp = (BioseqPtr) dataptr;
119               sep->choice = 1;
120               sep->data.ptrvalue = bsp;
121               SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
122             } else if (datatype == OBJ_BIOSEQSET) {
123               bssp = (BioseqSetPtr) dataptr;
124               sep->choice = 2;
125               sep->data.ptrvalue = bssp;
126               SeqMgrSeqEntry (SM_BIOSEQSET, (Pointer) bssp, sep);
127             } else {
128               sep = SeqEntryFree (sep);
129             }
130           }
131           sep = GetTopSeqEntryForEntityID (entityID);
132         }
133         if (sep != NULL) {
134           SeqEntryPack (sep);
135         }
136         if (directToEditor) {
137           handled = GatherProcLaunch (OMPROC_EDIT, FALSE, entityID, 1,
138                                       OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
139         } else {
140           if (sep != NULL) {
141             if (! leaveAsOldAsn) {
142               MySeqEntryToAsn3 (sep, TRUE, FALSE, FALSE);
143             }
144           }
145           seqviewprocs.filepath = path;
146           seqviewprocs.forceSeparateViewer = TRUE;
147           handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
148                                       OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
149           seqviewprocs.filepath = NULL;
150         }
151         ArrowCursor ();
152         if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
153           Message (MSG_FATAL, "Unable to launch viewer.");
154           SeqEntryFree (sep);
155           return;
156         } else {
157           SendHelpScrollMessage (helpForm, "Editing the Record", NULL);
158         }
159         ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
160         ObjMgrSetDirtyFlag (entityID, TRUE);
161       } else {
162         Message (MSG_ERROR, "Unable to process object type %d.", (int) datatype);
163         ObjMgrDelete (datatype, dataptr);
164       }
165     }
166   }
167 }
168 
169 #define BUFSIZE 128
170 
GetSequenceString(BioseqPtr bsp)171 static CharPtr GetSequenceString (BioseqPtr bsp)
172 
173 {
174   Char          buf [BUFSIZE + 5];
175   Int2          j;
176   ByteStorePtr  raw;
177   CharPtr       sequence = NULL;
178   SeqPortPtr    spp;
179   Uint1         u1Residue;
180 
181   if (bsp == NULL) return NULL;
182   if (! ISA_na (bsp->mol)) return NULL;
183   spp = SeqPortNew (bsp, 0, -1, 0, Seq_code_iupacna);
184   if (spp == NULL) return NULL;
185   raw = BSNew (bsp->length + 5);
186   if (raw == NULL) {
187     SeqPortFree (spp);
188     return NULL;
189   }
190 
191   j = 0;
192   buf [0] = '\0';
193   while ((u1Residue = SeqPortGetResidue (spp)) != SEQPORT_EOF) {
194     if (IS_residue (u1Residue)) {
195       u1Residue = TO_UPPER(u1Residue);
196       if (u1Residue == 'U') {
197         u1Residue = 'T';
198       }
199       buf [j] = (Char) u1Residue;
200       j++;
201       if (j >= BUFSIZE) {
202         BSWrite (raw, buf, j * sizeof (Char));
203         j = 0;
204       }
205     }
206   }
207   buf [j] = '\0';
208   if (j >= 0) {
209     BSWrite (raw, buf, j * sizeof (Char));
210   }
211   sequence = BSMerge (raw, NULL);
212   BSFree (raw);
213   SeqPortFree (spp);
214   return sequence;
215 }
216 
LookForSearchString(CharPtr title,CharPtr str,CharPtr tmp,size_t maxsize)217 static Boolean LookForSearchString (CharPtr title, CharPtr str, CharPtr tmp, size_t maxsize)
218 
219 {
220   CharPtr  ptr;
221 
222   ptr = StringISearch (title, str);
223   if (ptr != NULL) {
224     StringNCpy_0 (tmp, ptr + StringLen (str), maxsize);
225      ptr = StringChr (tmp, ']');
226      if (ptr != NULL) {
227        *ptr = '\0';
228      }
229     return TRUE;
230   }
231   return FALSE;
232 }
233 
234 typedef struct geneextendlist {
235   GeneRefPtr  grp;
236   SeqLocPtr   slp;
237   ObjMgrPtr   omp;
238   Boolean     rsult;
239   Char        label [41];
240 } GeneExtendList, PNTR GeneExtendPtr;
241 
GeneExtendFunc(GatherContextPtr gcp)242 static Boolean GeneExtendFunc (GatherContextPtr gcp)
243 
244 {
245   BioseqPtr      bsp;
246   GeneExtendPtr  gep;
247   GeneRefPtr     grp;
248   Boolean        hasNulls;
249   ObjMgrTypePtr  omtp;
250   SeqFeatPtr     sfp;
251   SeqLocPtr      slp;
252   Char           thislabel [41];
253 
254   if (gcp == NULL) return TRUE;
255 
256   gep = (GeneExtendPtr) gcp->userdata;
257   if (gep == NULL ) return TRUE;
258 
259   thislabel [0] = '\0';
260 
261   if (gcp->thistype == OBJ_SEQFEAT) {
262     sfp = (SeqFeatPtr) gcp->thisitem;
263     if (sfp != NULL && sfp->data.choice == SEQFEAT_GENE && sfp->data.value.ptrvalue != NULL) {
264       grp = (GeneRefPtr) sfp->data.value.ptrvalue;
265       omtp = ObjMgrTypeFind (gep->omp, gcp->thistype, NULL, NULL);
266       if (omtp == NULL) {
267         return TRUE;
268       }
269       if (omtp->labelfunc != NULL) {
270         (*(omtp->labelfunc)) (gcp->thisitem, thislabel, 40, OM_LABEL_CONTENT);
271       }
272       if (thislabel [0] != '\0') {
273         if (StringICmp (thislabel, gep->label) == 0) {
274           if (/* SeqLocCompare (gep->slp, sfp->location) != SLC_NO_MATCH */
275               SeqLocAinB (gep->slp, sfp->location) <= 0) {
276             bsp = GetBioseqGivenSeqLoc (sfp->location, gcp->entityID);
277             if (bsp != NULL) {
278               slp = SeqLocMerge (bsp, sfp->location, gep->slp, TRUE, FALSE, FALSE);
279               if (slp != NULL) {
280                 sfp->location = SeqLocFree (sfp->location);
281                 sfp->location = slp;
282                 if (bsp->repr == Seq_repr_seg) {
283                   slp = SegLocToPartsEx (bsp, sfp->location, TRUE);
284                   sfp->location = SeqLocFree (sfp->location);
285                   sfp->location = slp;
286                   hasNulls = LocationHasNullsBetween (sfp->location);
287                   sfp->partial = (sfp->partial || hasNulls);
288                 }
289                 FreeAllFuzz (slp);
290                 gep->rsult = TRUE;
291               }
292             }
293           }
294           return FALSE;
295         }
296       }
297     }
298   }
299   return TRUE;
300 }
301 
OligoExtendGene(GeneRefPtr grp,SeqEntryPtr nsep,SeqLocPtr slp)302 static Boolean OligoExtendGene (GeneRefPtr grp, SeqEntryPtr nsep, SeqLocPtr slp)
303 
304 {
305   GeneExtendList  gel;
306   GatherScope     gs;
307   ObjMgrTypePtr   omtp;
308   SeqFeatPtr      sfp;
309 
310   if (grp == NULL || nsep == NULL || slp == NULL) return FALSE;
311   gel.grp = grp;
312   gel.slp = slp;
313   gel.omp = ObjMgrGet ();
314   gel.label [0] = '\0';
315   gel.rsult = FALSE;
316   omtp = ObjMgrTypeFind (gel.omp, OBJ_SEQFEAT, NULL, NULL);
317   if (omtp != NULL && omtp->labelfunc != NULL) {
318     sfp = SeqFeatNew ();
319     if (sfp != NULL) {
320       sfp->data.choice = SEQFEAT_GENE;
321       sfp->data.value.ptrvalue = (Pointer) grp;
322       (*(omtp->labelfunc)) ((Pointer) sfp, gel.label, 40, OM_LABEL_CONTENT);
323       sfp->data.value.ptrvalue = NULL;
324       SeqFeatFree (sfp);
325     }
326   }
327   MemSet ((Pointer)(&gs), 0, sizeof (GatherScope));
328   gs.seglevels = 1;
329   gs.get_feats_location = TRUE;
330   MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
331   gs.ignore[OBJ_BIOSEQ] = FALSE;
332   gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
333   gs.ignore[OBJ_SEQFEAT] = FALSE;
334   gs.ignore[OBJ_SEQANNOT] = FALSE;
335   GatherSeqEntry (nsep, (Pointer) &gel, GeneExtendFunc, &gs);
336   return gel.rsult;
337 }
338 
AddGBQual(SeqFeatPtr sfp,CharPtr qual,CharPtr val)339 static void AddGBQual (SeqFeatPtr sfp, CharPtr qual, CharPtr val)
340 
341 {
342   GBQualPtr  gbq;
343   GBQualPtr  last;
344 
345   if (sfp == NULL || StringHasNoText (qual) || StringHasNoText (val)) return;
346   gbq = GBQualNew ();
347   if (gbq == NULL) return;
348   gbq->qual = StringSave (qual);
349   gbq->val = StringSave (val);
350   if (sfp->qual == NULL) {
351     sfp->qual = gbq;
352   } else {
353     last = sfp->qual;
354     while (last->next != NULL) {
355       last = last->next;
356     }
357     last->next = gbq;
358   }
359 }
360 
ProcessOligoDefline(SeqFeatPtr sfp,CharPtr title,SeqEntryPtr nsep)361 static void ProcessOligoDefline (SeqFeatPtr sfp, CharPtr title, SeqEntryPtr nsep)
362 
363 {
364   BioseqPtr   bsp;
365   GeneRefPtr  grp;
366   SeqFeatPtr  gsfp;
367   SeqLocPtr   gslp;
368   Boolean     hasNulls;
369   SeqIdPtr    sip;
370   Char        tmp [256];
371 
372   if (sfp == NULL || StringHasNoText (title) || nsep == NULL) return;
373   if (LookForSearchString (title, "[comment=", tmp, sizeof (tmp) - 1)) {
374     sfp->comment = StringSave (tmp);
375   }
376   if (LookForSearchString (title, "[stdname=", tmp, sizeof (tmp) - 1)) {
377     AddGBQual (sfp, "standard_name", tmp);
378   }
379   if (LookForSearchString (title, "[conditions=", tmp, sizeof (tmp) - 1)) {
380     AddGBQual (sfp, "PCR_conditions", tmp);
381   }
382   if (LookForSearchString (title, "[gene=", tmp, sizeof (tmp) - 1)) {
383     grp = CreateNewGeneRef (tmp, NULL, NULL, FALSE);
384     if (grp != NULL) {
385       /*
386       slp = AsnIoMemCopy ((Pointer) sfp->location,
387                           (AsnReadFunc) SeqLocAsnRead,
388                           (AsnWriteFunc) SeqLocAsnWrite);
389       if (slp != NULL || slp->choice == SEQLOC_INT) {
390         sintp = (SeqIntPtr) slp->data.ptrvalue;
391         if (sintp != NULL) {
392           if (sintp->strand == Seq_strand_minus) {
393             sintp->strand = Seq_strand_plus;
394           } else if (sintp->strand == Seq_strand_plus) {
395             sintp->strand = Seq_strand_minus;
396           }
397         }
398       }
399       */
400       if (OligoExtendGene (grp, nsep, sfp->location) /* || OligoExtendGene (grp, nsep, slp) */) {
401         grp = GeneRefFree (grp);
402       } else {
403         gsfp = CreateNewFeature (nsep, NULL, SEQFEAT_GENE, NULL);
404         if (gsfp != NULL) {
405           gsfp->data.value.ptrvalue = (Pointer) grp;
406           gsfp->location = SeqLocFree (gsfp->location);
407           gsfp->location = AsnIoMemCopy ((Pointer) sfp->location,
408                                         (AsnReadFunc) SeqLocAsnRead,
409                                         (AsnWriteFunc) SeqLocAsnWrite);
410           sip = SeqLocId (gsfp->location);
411           if (sip != NULL) {
412             bsp = BioseqFind (sip);
413           } else {
414             bsp = (BioseqPtr) nsep->data.ptrvalue;
415           }
416           if (bsp != NULL) {
417             gslp = SeqLocMerge (bsp, gsfp->location, NULL, TRUE, FALSE, FALSE);
418             if (gslp != NULL) {
419               gsfp->location = SeqLocFree (gsfp->location);
420               gsfp->location = gslp;
421               if (bsp->repr == Seq_repr_seg) {
422                 gslp = SegLocToPartsEx (bsp, gsfp->location, TRUE);
423                 gsfp->location = SeqLocFree (gsfp->location);
424                 gsfp->location = gslp;
425                 hasNulls = LocationHasNullsBetween (gsfp->location);
426                 gsfp->partial = (gsfp->partial || hasNulls);
427               }
428               FreeAllFuzz (gslp);
429             }
430           }
431         }
432       }
433       /* SeqLocFree (slp); */
434     }
435   }
436 }
437 
ProcessOligo(SeqEntryPtr sep,CharPtr sequence,CharPtr title)438 static void ProcessOligo (SeqEntryPtr sep, CharPtr sequence, CharPtr title)
439 
440 {
441   BioseqSetPtr  bssp;
442   ImpFeatPtr    ifp;
443   BioseqPtr     nbsp;
444   SeqEntryPtr   nsep;
445   SeqFeatPtr    sfp;
446   SeqLocPtr     slp;
447 
448   if (sep == NULL || sequence == NULL) return;
449   if (IS_Bioseq_set (sep)) {
450     bssp = (BioseqSetPtr) sep->data.ptrvalue;
451     if (bssp != NULL && (bssp->_class == 7 ||
452                          (IsPopPhyEtcSet (bssp->_class)))) {
453       for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
454         ProcessOligo (sep, sequence, title);
455       }
456       return;
457     }
458   }
459   nsep = FindNucSeqEntry (sep);
460   if (nsep == NULL) return;
461   if (! IS_Bioseq (nsep)) return;
462   nbsp = (BioseqPtr) nsep->data.ptrvalue;
463   if (nbsp == NULL) return;
464   slp = StringSearchInBioseq (nbsp->id, sequence);
465   if (slp == NULL) return;
466   ifp = ImpFeatNew ();
467   if (ifp != NULL) {
468     ifp->key = StringSave ("primer_bind");
469     sfp = CreateNewFeature (nsep, NULL, SEQFEAT_IMP, NULL);
470     if (sfp != NULL) {
471       sfp->data.value.ptrvalue = (Pointer) ifp;
472       sfp->location = SeqLocFree (sfp->location);
473       sfp->location = slp;
474       ProcessOligoDefline (sfp, title, nsep);
475     }
476   }
477 }
478 
479 
480 typedef struct edlocdata {
481   FORM_MESSAGE_BLOCK
482   SeqIdPtr      sip;
483   BioseqPtr     bsp;
484   TexT          locusname;
485   PrompT        accnnumber;
486   Boolean       refgene;
487 } EdLocData, PNTR EdLocPtr;
488 
AllToUpper(CharPtr str)489 static CharPtr AllToUpper (CharPtr str)
490 
491 {
492   Char          ch;
493   CharPtr       ptr;
494 
495   if (str != NULL) {
496     ptr = str;
497     ch = *ptr;
498     while (ch != '\0') {
499       *ptr = TO_UPPER (ch);
500       ptr++;
501       ch = *ptr;
502     }
503   }
504   return str;
505 }
506 
EditLocusActnProc(ForM f)507 static void EditLocusActnProc (ForM f)
508 
509 {
510   BioseqPtr     bsp;
511   Uint1         choice = SEQID_GENBANK;
512   Int2          count;
513   SeqIdPtr      id;
514   EdLocPtr      elp;
515   Int2          len;
516   Char          num [16];
517   BioseqPtr     part;
518   CharPtr       ptr;
519   Char          str [64];
520   SeqIdPtr      sip;
521   SeqLocPtr     slp;
522   Char          tmp [76];
523   TextSeqIdPtr  tsip;
524   ValNode       vn;
525 
526   elp = (EdLocPtr) GetObjectExtra (f);
527   if (elp != NULL) {
528     sip = elp->sip;
529     bsp = elp->bsp;
530     if (elp->refgene) {
531       choice = SEQID_OTHER;
532     }
533     if (indexerVersion && sip == NULL && bsp != NULL && bsp->id != NULL) {
534       id = bsp->id;
535       while (id->next != NULL) {
536         id = id->next;
537       }
538       tsip = TextSeqIdNew ();
539       if (tsip != NULL) {
540         sip = ValNodeNew (NULL);
541         if (sip != NULL) {
542           sip->choice = choice;
543           sip->data.ptrvalue = (Pointer) tsip;
544         } else {
545           TextSeqIdFree (tsip);
546         }
547         id->next = sip;
548         SeqMgrReplaceInBioseqIndex (bsp);
549       }
550     }
551     if (sip == NULL) return;
552     tsip = (TextSeqIdPtr) sip->data.ptrvalue;
553     if (tsip == NULL) return;
554     tsip->accession = MemFree (tsip->accession);
555     GetTitle (elp->accnnumber, str, sizeof (str) - 1);
556     TrimSpacesAroundString (str);
557     if (! StringHasNoText (str)) {
558       tsip->accession = StringSave (AllToUpper (str));
559     }
560     tsip->name = MemFree (tsip->name);
561     GetTitle (elp->locusname, str, sizeof (str) - 1);
562     if (str [0] != '\0') {
563       if (elp->refgene) {
564         tsip->name = StringSave (str);
565       } else {
566         tsip->name = StringSave (AllToUpper (str));
567       }
568     }
569     if (bsp != NULL && bsp->repr == Seq_repr_seg && bsp->seq_ext != NULL) {
570       if (StringNCmp (str, "SEG_", 4) != 0) {
571         sprintf (tmp, "SEG_%s", str);
572         tsip->name = MemFree (tsip->name);
573         tsip->name = StringSave (tmp);
574         SeqMgrReplaceInBioseqIndex (bsp);
575       }
576       vn.choice = SEQLOC_MIX;
577       vn.next = NULL;
578       vn.data.ptrvalue = bsp->seq_ext;
579       count = 0;
580       slp = SeqLocFindNext (&vn, NULL);
581       while (slp != NULL) {
582         if (slp->choice != SEQLOC_NULL) {
583           count++;
584         }
585         slp = SeqLocFindNext (&vn, slp);
586       }
587       if (count < 10) {
588         len = 1;
589       } else if (count < 100) {
590         len = 2;
591       } else {
592         len = 3;
593       }
594       count = 0;
595       slp = SeqLocFindNext (&vn, NULL);
596       while (slp != NULL) {
597         if (slp->choice != SEQLOC_NULL) {
598           count++;
599           sprintf (num, "%*d", (int) len, (int) count);
600           for (ptr = num; *ptr != '\0'; ptr++) {
601             if (*ptr == ' ') {
602               *ptr = '0';
603             }
604           }
605           sprintf (tmp, "%s%s", str, num);
606           sip = SeqLocId (slp);
607           if (sip != NULL) {
608             part = BioseqFind (sip);
609             if (part != NULL && part->id != NULL) {
610               id = part->id;
611               while (id->choice != choice && id->next != NULL) {
612                 id = id->next;
613               }
614               if (id->choice != choice) {
615                 tsip = TextSeqIdNew ();
616                 if (tsip != NULL) {
617                   sip = ValNodeNew (NULL);
618                   if (sip != NULL) {
619                     sip->choice = choice;
620                     sip->data.ptrvalue = (Pointer) tsip;
621                   } else {
622                     TextSeqIdFree (tsip);
623                   }
624                   id->next = sip;
625                   id = sip;
626                 }
627               }
628               if (id != NULL && id->choice == choice) {
629                 tsip = (TextSeqIdPtr) id->data.ptrvalue;
630                 if (tsip != NULL) {
631                   tsip->name = MemFree (tsip->name);
632                   if (tmp [0] != '\0') {
633                     if (elp->refgene) {
634                       tsip->name = StringSave (tmp);
635                     } else {
636                       tsip->name = StringSave (AllToUpper (tmp));
637                     }
638                   }
639                 }
640               }
641               SeqMgrReplaceInBioseqIndex (part);
642             }
643           }
644         }
645         slp = SeqLocFindNext (&vn, slp);
646       }
647     }
648     ObjMgrSetDirtyFlag (elp->input_entityID, TRUE);
649     ObjMgrSendMsg (OM_MSG_UPDATE, elp->input_entityID, 0, 0);
650   }
651 }
652 
EditLocusMessage(ForM f,Int2 mssg)653 static void EditLocusMessage (ForM f, Int2 mssg)
654 
655 {
656   EdLocPtr  elp;
657 
658   elp = (EdLocPtr) GetObjectExtra (f);
659   if (elp != NULL) {
660     switch (mssg) {
661       case VIB_MSG_CLOSE :
662         Remove (f);
663         break;
664       case VIB_MSG_CUT :
665         StdCutTextProc (NULL);
666         break;
667       case VIB_MSG_COPY :
668         StdCopyTextProc (NULL);
669         break;
670       case VIB_MSG_PASTE :
671         StdPasteTextProc (NULL);
672         break;
673       case VIB_MSG_DELETE :
674         StdDeleteTextProc (NULL);
675         break;
676       default :
677         if (elp->appmessage != NULL) {
678           elp->appmessage (f, mssg);
679         }
680         break;
681     }
682   }
683 }
684 
685 #define NUM_ORDER 16
686 
SeqIdFindGenBankOrOther(SeqIdPtr sip)687 static SeqIdPtr SeqIdFindGenBankOrOther (SeqIdPtr sip)
688 
689 {
690   Uint1  order [NUM_ORDER];
691 
692   SeqIdBestRank (order, NUM_ORDER);
693   order [SEQID_LOCAL] = 255;
694   order [SEQID_GENBANK] = 1;
695   order [SEQID_EMBL] = 2;
696   order [SEQID_PIR] = 255;
697   order [SEQID_SWISSPROT] = 255;
698   order [SEQID_DDBJ] = 3;
699   order [SEQID_PRF] = 255;
700   order [SEQID_PDB] = 255;
701   order [SEQID_PATENT] = 255;
702   order [SEQID_OTHER] = 2;
703   order [SEQID_GENERAL] = 255;
704   order [SEQID_GIBBSQ] = 255;
705   order [SEQID_GIBBMT] = 255;
706   order [SEQID_GIIM] = 255;
707   order [SEQID_GI] = 255;
708   return SeqIdSelect (sip, order, NUM_ORDER);
709 }
710 
EditLocusProc(IteM i)711 void EditLocusProc (IteM i)
712 
713 {
714   ButtoN             b;
715   BaseFormPtr        bfp;
716   BioseqPtr          bsp;
717   GrouP              c;
718   EdLocPtr           elp;
719   GrouP              g;
720   StdEditorProcsPtr  sepp;
721   SeqIdPtr           sip;
722   TextSeqIdPtr       tsip;
723   WindoW             w;
724 
725 #ifdef WIN_MAC
726   bfp = currentFormDataPtr;
727 #else
728   bfp = GetObjectExtra (i);
729 #endif
730   if (bfp == NULL) return;
731   if (bfp->input_itemtype != OBJ_BIOSEQ) return;
732   bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
733   if (bsp == NULL) return;
734   sip = SeqIdFindGenBankOrOther (bsp->id);
735   /*if (sip == NULL) return;*/
736   elp = (EdLocPtr) MemNew (sizeof (EdLocData));
737   if (elp == NULL) return;
738   w = MovableModalWindow (-50, -33, -10, -10,
739                           "Locus and Accession Number",
740                           StdCloseWindowProc);
741   SetObjectExtra (w, elp, StdCleanupFormProc);
742   elp->form = (ForM) w;
743   elp->actproc = EditLocusActnProc;
744   elp->formmessage = EditLocusMessage;
745 
746   elp->input_entityID = bfp->input_entityID;
747   elp->input_itemID = bfp->input_itemID;
748   elp->input_itemtype = bfp->input_itemtype;
749 
750 #ifndef WIN_MAC
751   CreateStdEditorFormMenus (w);
752 #endif
753 
754   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
755   if (sepp != NULL) {
756     SetActivate (w, sepp->activateForm);
757     elp->appmessage = sepp->handleMessages;
758   }
759 
760   g = HiddenGroup (w, 2, 0, NULL);
761   elp->sip = sip;
762   elp->bsp = bsp;
763   StaticPrompt (g, "Locus: ", 0, dialogTextHeight, systemFont, 'l');
764   elp->locusname = DialogText (g, "", 20, NULL);
765   StaticPrompt (g, "Accession: ", 0, stdLineHeight, systemFont, 'l');
766   elp->accnnumber = StaticPrompt (g, "", 20 * stdCharWidth, stdLineHeight, systemFont, 'l');
767   c = HiddenGroup (w, 2, 0, NULL);
768   b = DefaultButton (c, "Accept", StdAcceptFormButtonProc);
769   SetObjectExtra (b, elp, NULL);
770   PushButton (c, "Cancel", StdCancelButtonProc);
771   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
772   if (sip != NULL) {
773     tsip = (TextSeqIdPtr) sip->data.ptrvalue;
774     if (tsip != NULL) {
775       SetTitle (elp->locusname, tsip->name);
776       SetTitle (elp->accnnumber, tsip->accession);
777     }
778     if (sip->choice == SEQID_OTHER) {
779       elp->refgene = TRUE;
780     }
781   }
782   RealizeWindow (w);
783   Select (elp->locusname);
784   Show (w);
785   Select (w);
786   Update ();
787 }
788 
789 typedef struct accntolocal
790 {
791   Boolean make_secondary;
792   Boolean convert_prots;
793   Boolean convert_nucs;
794 } AccnToLocalData, PNTR AccnToLocalPtr;
795 
LocalSeqIdFromAccession(SeqIdPtr sip,CharPtr str,Int4 str_size)796 static SeqIdPtr LocalSeqIdFromAccession (SeqIdPtr sip, CharPtr str, Int4 str_size)
797 {
798   TextSeqIdPtr  tsip;
799   CharPtr       text;
800   SeqIdPtr      new_sip;
801   ObjectIdPtr   oip;
802 
803   if (sip == NULL || str == NULL || str_size < 1)
804   {
805     return NULL;
806   }
807   if (sip->choice != SEQID_GENBANK
808       && sip->choice != SEQID_EMBL
809       && sip->choice != SEQID_DDBJ)
810   {
811     return NULL;
812   }
813   if (sip->data.ptrvalue == NULL)
814   {
815     return NULL;
816   }
817   new_sip = ValNodeNew (NULL);
818   if (new_sip == NULL)
819   {
820     return NULL;
821   }
822   tsip = (TextSeqIdPtr) sip->data.ptrvalue;
823   text = NULL;
824   str [0] = '\0';
825   if (tsip->accession != NULL) {
826     text = tsip->accession;
827   } else if (tsip->name != NULL) {
828     text = tsip->name;
829   }
830   if (text != NULL) {
831     StringNCpy_0 (str, text, str_size);
832     oip = ObjectIdNew ();
833     if (oip != NULL) {
834       oip->str = StringSave (text);
835       new_sip->choice = SEQID_LOCAL;
836       new_sip->data.ptrvalue = (Pointer) oip;
837     }
838   }
839   return new_sip;
840 }
841 
SeqIdSwap(SeqIdPtr sip1,SeqIdPtr sip2)842 static void SeqIdSwap (SeqIdPtr sip1, SeqIdPtr sip2)
843 {
844   ValNode       tmp_sip;
845 
846   if (sip1 == NULL || sip2 == NULL)
847   {
848     return;
849   }
850 
851   tmp_sip.choice = sip1->choice;
852   tmp_sip.data.ptrvalue = sip1->data.ptrvalue;
853   sip1->choice = sip2->choice;
854   sip1->data.ptrvalue = sip2->data.ptrvalue;
855   sip2->choice = tmp_sip.choice;
856   sip2->data.ptrvalue = tmp_sip.data.ptrvalue;
857 }
858 
ConvertSeqIdListToLocalID(SeqIdPtr sip,SeqEntryPtr sep,AccnToLocalPtr atlp)859 static void ConvertSeqIdListToLocalID (SeqIdPtr sip, SeqEntryPtr sep, AccnToLocalPtr atlp)
860 
861 {
862   GBBlockPtr    gbp;
863   Char          str [32];
864   ValNodePtr    vnp;
865   BioseqPtr     bsp;
866   SeqIdPtr      new_sip = NULL;
867 
868   if (atlp == NULL) return;
869 
870   while (sip != NULL)
871   {
872     bsp = BioseqFind (sip);
873     if (bsp == NULL)
874     {
875       new_sip = LocalSeqIdFromAccession (sip, str, sizeof (str));
876       if (new_sip != NULL)
877       {
878         bsp = BioseqFind (new_sip);
879       }
880     }
881     if (bsp == NULL)
882     {
883       /* have to skip */
884     }
885     else if (ISA_na (bsp->mol) && !atlp->convert_nucs)
886     {
887       /* don't convert the nucleotide ID */
888     }
889     else if (ISA_aa (bsp->mol) && ! atlp->convert_prots)
890     {
891       /* don't convert the protein ID */
892     }
893     else if ((sip->choice == SEQID_GENBANK
894           || sip->choice == SEQID_EMBL
895           || sip->choice == SEQID_DDBJ)
896           && sip->data.ptrvalue != NULL)
897     {
898       new_sip = LocalSeqIdFromAccession (sip, str, sizeof (str));
899       if (new_sip != NULL)
900       {
901         /* replace old sip values with new  - new_sip will now be ready for freeing */
902         SeqIdSwap (sip, new_sip);
903 
904         /* make secondary if needed */
905         if (atlp->make_secondary && sep != NULL)
906         {
907           vnp = SeqEntryGetSeqDescr (sep, Seq_descr_genbank, NULL);
908           if (vnp == NULL) {
909             vnp = CreateNewDescriptor (sep, Seq_descr_genbank);
910             if (vnp != NULL) {
911               gbp = GBBlockNew ();
912               vnp->data.ptrvalue = (Pointer) gbp;
913             }
914           }
915           if (vnp != NULL) {
916             gbp = (GBBlockPtr) vnp->data.ptrvalue;
917             if (gbp != NULL) {
918               for (vnp = gbp->extra_accessions;
919                    vnp != NULL && StringICmp (vnp->data.ptrvalue, str) != 0;
920                    vnp = vnp->next) continue;
921               if (vnp == NULL) {
922                 vnp = ValNodeCopyStr (&(gbp->extra_accessions), 0, str);
923               }
924             }
925           }
926         }
927       }
928     }
929     new_sip = SeqIdFree (new_sip);
930     sip = sip->next;
931   }
932 }
933 
ConvertSeqLocListToLocalID(SeqLocPtr slp,AccnToLocalPtr atlp)934 static void ConvertSeqLocListToLocalID (SeqLocPtr slp, AccnToLocalPtr atlp)
935 
936 {
937   SeqLocPtr      loc;
938   PackSeqPntPtr  psp;
939   SeqBondPtr     sbp;
940   SeqIntPtr      sinp;
941   SeqIdPtr       sip;
942   SeqPntPtr      spp;
943 
944   while (slp != NULL) {
945     switch (slp->choice) {
946       case SEQLOC_NULL :
947         break;
948       case SEQLOC_EMPTY :
949       case SEQLOC_WHOLE :
950         sip = (SeqIdPtr) slp->data.ptrvalue;
951         ConvertSeqIdListToLocalID (sip, NULL, atlp);
952         break;
953       case SEQLOC_INT :
954         sinp = (SeqIntPtr) slp->data.ptrvalue;
955         if (sinp != NULL) {
956           sip = sinp->id;
957           ConvertSeqIdListToLocalID (sip, NULL, atlp);
958         }
959         break;
960       case SEQLOC_PNT :
961         spp = (SeqPntPtr) slp->data.ptrvalue;
962         if (spp != NULL) {
963           sip = spp->id;
964           ConvertSeqIdListToLocalID (sip, NULL, atlp);
965         }
966         break;
967       case SEQLOC_PACKED_PNT :
968         psp = (PackSeqPntPtr) slp->data.ptrvalue;
969         if (psp != NULL) {
970           sip = psp->id;
971           ConvertSeqIdListToLocalID (sip, NULL, atlp);
972         }
973         break;
974       case SEQLOC_PACKED_INT :
975       case SEQLOC_MIX :
976       case SEQLOC_EQUIV :
977         loc = (SeqLocPtr) slp->data.ptrvalue;
978         while (loc != NULL) {
979           ConvertSeqLocListToLocalID (loc, atlp);
980           loc = loc->next;
981         }
982         break;
983       case SEQLOC_BOND :
984         sbp = (SeqBondPtr) slp->data.ptrvalue;
985         if (sbp != NULL) {
986           spp = (SeqPntPtr) sbp->a;
987           if (spp != NULL) {
988             sip = spp->id;
989             ConvertSeqIdListToLocalID (sip, NULL, atlp);
990           }
991           spp = (SeqPntPtr) sbp->b;
992           if (spp != NULL) {
993             sip = spp->id;
994             ConvertSeqIdListToLocalID (sip, NULL, atlp);
995           }
996         }
997         break;
998       case SEQLOC_FEAT :
999         break;
1000       default :
1001         break;
1002     }
1003     slp = slp->next;
1004   }
1005 }
1006 
ChangeAccessionToLocalID(GatherContextPtr gcp)1007 static Boolean ChangeAccessionToLocalID (GatherContextPtr gcp)
1008 
1009 {
1010   BioseqPtr      bsp;
1011   AccnToLocalPtr atlp;
1012   SeqEntryPtr    sep;
1013   SeqFeatPtr     sfp;
1014   SeqIdPtr       sip;
1015   SeqLocPtr      slp;
1016 
1017   if (gcp == NULL || gcp->userdata == NULL) return TRUE;
1018   atlp = (AccnToLocalPtr) gcp->userdata;
1019   if (gcp->thisitem == NULL) return TRUE;
1020   switch (gcp->thistype) {
1021     case OBJ_BIOSEQ :
1022       sep = NULL;
1023       bsp = (BioseqPtr) gcp->thisitem;
1024       if (atlp->make_secondary)
1025       {
1026         sep = SeqMgrGetSeqEntryForData (bsp);
1027       }
1028       sip = bsp->id;
1029       ConvertSeqIdListToLocalID (sip, sep, atlp);
1030       SeqMgrReplaceInBioseqIndex (bsp);
1031       break;
1032     case OBJ_SEQFEAT :
1033       sfp = (SeqFeatPtr) gcp->thisitem;
1034       slp = sfp->location;
1035       ConvertSeqLocListToLocalID (slp, atlp);
1036       slp = sfp->product;
1037       ConvertSeqLocListToLocalID (slp, atlp);
1038       break;
1039     default :
1040       break;
1041   }
1042   return TRUE;
1043 }
1044 
ConvertToLocalProc(IteM i,Boolean convert_nucs,Boolean convert_prots)1045 static void ConvertToLocalProc (IteM i, Boolean convert_nucs, Boolean convert_prots)
1046 
1047 {
1048   MsgAnswer       ans;
1049   BaseFormPtr     bfp;
1050   GatherScope     gs;
1051   AccnToLocalData atld;
1052 
1053 #ifdef WIN_MAC
1054   bfp = currentFormDataPtr;
1055 #else
1056   bfp = GetObjectExtra (i);
1057 #endif
1058   if (bfp == NULL) return;
1059   if (bfp->input_itemtype != OBJ_BIOSEQ) return;
1060   ans = Message (MSG_OKC, "Are you sure you want to convert accessions to local IDs?");
1061   if (ans == ANS_CANCEL) return;
1062   ans = Message (MSG_OKC, "Are you REALLY sure you want to convert accessions to local IDs?");
1063   if (ans == ANS_CANCEL) return;
1064   ans = Message (MSG_YN, "Do you want to make the original accessions secondary?");
1065   atld.make_secondary = (Boolean) (ans == ANS_YES);
1066   atld.convert_nucs = convert_nucs;
1067   atld.convert_prots = convert_prots;
1068   MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
1069   gs.seglevels = 1;
1070   MemSet((Pointer) (gs.ignore), (int) (TRUE), (size_t) (OBJ_MAX * sizeof (Boolean)));
1071   gs.ignore[OBJ_BIOSEQ] = FALSE;
1072   gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
1073   gs.ignore[OBJ_SEQFEAT] = FALSE;
1074   gs.ignore[OBJ_SEQANNOT] = FALSE;
1075   GatherEntity (bfp->input_entityID, (Pointer) &atld, ChangeAccessionToLocalID, &gs);
1076   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1077   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1078 }
1079 
ConvertToLocalProcOnlyNucs(IteM i)1080 extern void ConvertToLocalProcOnlyNucs (IteM i)
1081 {
1082   ConvertToLocalProc (i, TRUE, FALSE);
1083 }
1084 
ConvertToLocalProcOnlyProts(IteM i)1085 extern void ConvertToLocalProcOnlyProts (IteM i)
1086 {
1087   ConvertToLocalProc (i, FALSE, TRUE);
1088 }
1089 
ConvertToLocalProcAll(IteM i)1090 extern void ConvertToLocalProcAll (IteM i)
1091 {
1092   ConvertToLocalProc (i, TRUE, TRUE);
1093 }
1094 
SeqIdFindBestForPromotion(SeqIdPtr sip)1095 static SeqIdPtr SeqIdFindBestForPromotion (SeqIdPtr sip)
1096 
1097 {
1098   return SeqIdFindBest (sip, 0);
1099 }
1100 
SeqIdFindWorstForPromotion(SeqIdPtr sip)1101 static SeqIdPtr SeqIdFindWorstForPromotion (SeqIdPtr sip)
1102 
1103 {
1104   return SeqIdFindWorst (sip);
1105 }
1106 
PromoteSeqId(SeqIdPtr sip,Boolean alsoCheckLocalAccn,Boolean findWorst)1107 static void PromoteSeqId (SeqIdPtr sip, Boolean alsoCheckLocalAccn, Boolean findWorst)
1108 
1109 {
1110   SeqIdPtr     bestid, newid, oldid;
1111   BioseqPtr    bsp;
1112   ObjectIdPtr  oip;
1113   TextSeqId    tsi;
1114   SeqId        vn;
1115 
1116   bsp = BioseqFind (sip);
1117   if (bsp == NULL && alsoCheckLocalAccn && sip->choice == SEQID_LOCAL) {
1118     oip = (ObjectIdPtr) sip->data.ptrvalue;
1119     if (oip != NULL && (! StringHasNoText (oip->str))) {
1120       MemSet ((Pointer) &vn, 0, sizeof (SeqId));
1121       MemSet ((Pointer) &tsi, 0, sizeof (TextSeqId));
1122       tsi.accession = oip->str;
1123       vn.choice = SEQID_GENBANK;
1124       vn.data.ptrvalue = (Pointer) &tsi;
1125       bsp = BioseqFind (&vn);
1126     }
1127   }
1128   if (bsp == NULL) return;
1129 
1130   if (findWorst) {
1131     bestid = SeqIdFindWorstForPromotion (bsp->id);
1132   } else {
1133     bestid = SeqIdFindBestForPromotion (bsp->id);
1134   }
1135   if (bestid == NULL) return;
1136   newid = SeqIdDup (bestid);
1137   if (newid == NULL) return;
1138 
1139   oldid = ValNodeNew (NULL);
1140   if (oldid == NULL) return;
1141 
1142   MemCopy (oldid, sip, sizeof (ValNode));
1143   oldid->next = NULL;
1144 
1145   sip->choice = newid->choice;
1146   sip->data.ptrvalue = newid->data.ptrvalue;
1147 
1148   SeqIdFree (oldid);
1149   ValNodeFree (newid);
1150 
1151   SeqIdStripLocus (sip);
1152 }
1153 
PromoteSeqIdList(SeqIdPtr sip,Boolean alsoCheckLocalAccn,Boolean findWorst)1154 static void PromoteSeqIdList (SeqIdPtr sip, Boolean alsoCheckLocalAccn, Boolean findWorst)
1155 
1156 {
1157   while (sip != NULL) {
1158     PromoteSeqId (sip, alsoCheckLocalAccn, findWorst);
1159     sip = sip->next;
1160   }
1161 }
1162 
PromoteSeqLocList(SeqLocPtr slp,Boolean alsoCheckLocalAccn,Boolean findWorst)1163 static void PromoteSeqLocList (SeqLocPtr slp, Boolean alsoCheckLocalAccn, Boolean findWorst)
1164 
1165 {
1166   SeqLocPtr      loc;
1167   PackSeqPntPtr  psp;
1168   SeqBondPtr     sbp;
1169   SeqIntPtr      sinp;
1170   SeqIdPtr       sip;
1171   SeqPntPtr      spp;
1172 
1173   while (slp != NULL) {
1174     switch (slp->choice) {
1175       case SEQLOC_NULL :
1176         break;
1177       case SEQLOC_EMPTY :
1178       case SEQLOC_WHOLE :
1179         sip = (SeqIdPtr) slp->data.ptrvalue;
1180         PromoteSeqIdList (sip, alsoCheckLocalAccn, findWorst);
1181         break;
1182       case SEQLOC_INT :
1183         sinp = (SeqIntPtr) slp->data.ptrvalue;
1184         if (sinp != NULL) {
1185           sip = sinp->id;
1186           PromoteSeqIdList (sip, alsoCheckLocalAccn, findWorst);
1187         }
1188         break;
1189       case SEQLOC_PNT :
1190         spp = (SeqPntPtr) slp->data.ptrvalue;
1191         if (spp != NULL) {
1192           sip = spp->id;
1193           PromoteSeqIdList (sip, alsoCheckLocalAccn, findWorst);
1194         }
1195         break;
1196       case SEQLOC_PACKED_PNT :
1197         psp = (PackSeqPntPtr) slp->data.ptrvalue;
1198         if (psp != NULL) {
1199           sip = psp->id;
1200           PromoteSeqIdList (sip, alsoCheckLocalAccn, findWorst);
1201         }
1202         break;
1203       case SEQLOC_PACKED_INT :
1204       case SEQLOC_MIX :
1205       case SEQLOC_EQUIV :
1206         loc = (SeqLocPtr) slp->data.ptrvalue;
1207         while (loc != NULL) {
1208           PromoteSeqLocList (loc, alsoCheckLocalAccn, findWorst);
1209           loc = loc->next;
1210         }
1211         break;
1212       case SEQLOC_BOND :
1213         sbp = (SeqBondPtr) slp->data.ptrvalue;
1214         if (sbp != NULL) {
1215           spp = (SeqPntPtr) sbp->a;
1216           if (spp != NULL) {
1217             sip = spp->id;
1218             PromoteSeqIdList (sip, alsoCheckLocalAccn, findWorst);
1219           }
1220           spp = (SeqPntPtr) sbp->b;
1221           if (spp != NULL) {
1222             sip = spp->id;
1223             PromoteSeqIdList (sip, alsoCheckLocalAccn, findWorst);
1224           }
1225         }
1226         break;
1227       case SEQLOC_FEAT :
1228         break;
1229       default :
1230         break;
1231     }
1232     slp = slp->next;
1233   }
1234 }
1235 
1236 
ChangeGBNameIDs(SeqIdPtr sip,Pointer userdata)1237 static void ChangeGBNameIDs (SeqIdPtr sip, Pointer userdata)
1238 
1239 {
1240   Char          buf [80];
1241   ObjectIdPtr   oip;
1242   TextSeqIdPtr  tsip;
1243 
1244   if (sip == NULL || sip->choice != SEQID_GENBANK) return;
1245   tsip = (TextSeqIdPtr) sip->data.ptrvalue;
1246   if (tsip == NULL) return;
1247   if (tsip->accession != NULL || StringHasNoText (tsip->name)) return;
1248   StringNCpy (buf, tsip->name, sizeof (buf));
1249   TrimSpacesAroundString (buf);
1250   oip = ObjectIdNew ();
1251   if (oip == NULL) return;
1252   oip->str = StringSave (buf);
1253   sip->choice = SEQID_LOCAL;
1254   sip->data.ptrvalue = (Pointer) oip;
1255   TextSeqIdFree (tsip);
1256 }
1257 
ChangeGBNameBioseq(BioseqPtr bsp,Pointer userdata)1258 static void ChangeGBNameBioseq (BioseqPtr bsp, Pointer userdata)
1259 
1260 {
1261   VisitSeqIdsInBioseq (bsp, userdata, ChangeGBNameIDs);
1262   SeqMgrReplaceInBioseqIndex (bsp);
1263 }
1264 
ChangeGBNameFeature(SeqFeatPtr sfp,Pointer userdata)1265 static void ChangeGBNameFeature (SeqFeatPtr sfp, Pointer userdata)
1266 
1267 {
1268   VisitSeqIdsInSeqFeat (sfp, userdata, ChangeGBNameIDs);
1269 }
1270 
ChangeGenBankNameToLocal(IteM i)1271 void ChangeGenBankNameToLocal (IteM i)
1272 
1273 {
1274   BaseFormPtr  bfp;
1275   SeqEntryPtr  oldscope, sep;
1276 
1277 #ifdef WIN_MAC
1278   bfp = currentFormDataPtr;
1279 #else
1280   bfp = GetObjectExtra (i);
1281 #endif
1282   if (bfp == NULL) return;
1283   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1284   if (sep == NULL) return;
1285 
1286   oldscope = SeqEntrySetScope (sep);
1287 
1288   VisitBioseqsInSep (sep, NULL, ChangeGBNameBioseq);
1289   VisitFeaturesInSep (sep, NULL, ChangeGBNameFeature);
1290 
1291   SeqEntrySetScope (oldscope);
1292 
1293   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1294   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1295 }
1296 
1297 
GetParentForSeqAnnot(SeqAnnotPtr sap)1298 static SeqEntryPtr GetParentForSeqAnnot (SeqAnnotPtr sap)
1299 {
1300   if (sap == NULL || sap->idx.parentptr == NULL) {
1301     return NULL;
1302   }
1303   if (sap->idx.parenttype == OBJ_BIOSEQSET) {
1304     return SeqMgrGetSeqEntryForData (sap->idx.parentptr);
1305   } else if (sap->idx.parenttype == OBJ_BIOSEQ) {
1306     return SeqMgrGetSeqEntryForData (sap->idx.parentptr);
1307   } else {
1308     return NULL;
1309   }
1310 }
1311 
1312 
PromoteAlignIDsProc(SeqAnnotPtr sp,Pointer data)1313 extern void PromoteAlignIDsProc (SeqAnnotPtr sp, Pointer data)
1314 
1315 {
1316   DenseDiagPtr  ddp;
1317   DenseSegPtr   dsp;
1318   PackSegPtr    psp;
1319   SeqAlignPtr   sap;
1320   SeqLocPtr     slp;
1321   StdSegPtr     ssp;
1322   SeqEntryPtr   orig_scope, new_scope = NULL;
1323 
1324   if (sp == NULL || sp->type != 2) {
1325     return;
1326   }
1327   sap = (SeqAlignPtr) sp->data;
1328   if (sap == NULL) return;
1329 
1330   new_scope = GetParentForSeqAnnot(sp);
1331 
1332   orig_scope = SeqEntrySetScope (new_scope);
1333 
1334   switch (sap->segtype) {
1335     case SAS_DENDIAG :
1336       for (ddp = sap->segs; ddp != NULL; ddp = ddp->next) {
1337         PromoteSeqIdList (ddp->id, TRUE, FALSE);
1338       }
1339       break;
1340     case SAS_DENSEG :
1341       dsp = sap->segs;
1342       if (dsp != NULL) {
1343         PromoteSeqIdList (dsp->ids, TRUE, FALSE);
1344       }
1345       break;
1346     case SAS_STD :
1347       for (ssp = sap->segs; ssp != NULL; ssp = ssp->next) {
1348         PromoteSeqIdList (ssp->ids, TRUE, FALSE);
1349         for (slp = ssp->loc; slp != NULL; slp = slp->next) {
1350           PromoteSeqLocList (slp, TRUE, FALSE);
1351         }
1352       }
1353       break;
1354     case SAS_PACKED :
1355       psp = (PackSegPtr) sap->segs;
1356       if (psp != NULL) {
1357         PromoteSeqIdList (psp->ids, TRUE, FALSE);
1358       }
1359       break;
1360     default :
1361       break;
1362   }
1363 
1364   SeqEntrySetScope (orig_scope);
1365 }
1366 
1367 
RemoveGBIDsProc(GatherObjectPtr gop)1368 static Boolean RemoveGBIDsProc (GatherObjectPtr gop)
1369 
1370 {
1371   BioseqPtr      bsp;
1372   SeqIdPtr       nextid, sip;
1373   SeqIdPtr PNTR  previd;
1374 
1375   if (gop->itemtype != OBJ_BIOSEQ) return TRUE;
1376   bsp = (BioseqPtr) gop->dataptr;
1377   if (bsp == NULL) return TRUE;
1378 
1379   previd = (SeqIdPtr PNTR) &(bsp->id);
1380   sip = bsp->id;
1381   while (sip != NULL) {
1382     nextid = sip->next;
1383     if (sip->choice == SEQID_GENBANK) {
1384       *previd = sip->next;
1385       sip->next = NULL;
1386       SeqIdFree (sip);
1387     } else {
1388       previd = (SeqIdPtr PNTR) &(sip->next);
1389     }
1390     sip = sip->next;
1391   }
1392 
1393   return TRUE;
1394 }
1395 
RemoveGBIDsFromBioseqs(IteM i)1396 void RemoveGBIDsFromBioseqs (IteM i)
1397 
1398 {
1399   MsgAnswer    ans;
1400   BaseFormPtr  bfp;
1401 
1402 #ifdef WIN_MAC
1403   bfp = currentFormDataPtr;
1404 #else
1405   bfp = GetObjectExtra (i);
1406 #endif
1407   if (bfp == NULL) return;
1408 
1409   ans = Message (MSG_OKC, "Currently deletes all GenBank SeqIDs");
1410   if (ans == ANS_CANCEL) return;
1411 
1412   GatherObjectsInEntity (bfp->input_entityID, 0, NULL, RemoveGBIDsProc, NULL, NULL);
1413 
1414   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1415   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1416 }
1417 
RemoveGBProtIDsProc(GatherObjectPtr gop)1418 static Boolean RemoveGBProtIDsProc (GatherObjectPtr gop)
1419 
1420 {
1421   BioseqPtr      bsp;
1422   SeqIdPtr       nextid, sip;
1423   SeqIdPtr PNTR  previd;
1424 
1425   if (gop->itemtype != OBJ_BIOSEQ) return TRUE;
1426   bsp = (BioseqPtr) gop->dataptr;
1427   if (bsp == NULL) return TRUE;
1428   if (! ISA_aa (bsp->mol)) return TRUE;
1429 
1430   previd = (SeqIdPtr PNTR) &(bsp->id);
1431   sip = bsp->id;
1432   while (sip != NULL) {
1433     nextid = sip->next;
1434     if (sip->choice == SEQID_GENBANK) {
1435       *previd = sip->next;
1436       sip->next = NULL;
1437       SeqIdFree (sip);
1438     } else {
1439       previd = (SeqIdPtr PNTR) &(sip->next);
1440     }
1441     sip = sip->next;
1442   }
1443 
1444   return TRUE;
1445 }
1446 
RemoveGBIDsFromProteins(IteM i)1447 void RemoveGBIDsFromProteins (IteM i)
1448 
1449 {
1450   MsgAnswer    ans;
1451   BaseFormPtr  bfp;
1452 
1453 #ifdef WIN_MAC
1454   bfp = currentFormDataPtr;
1455 #else
1456   bfp = GetObjectExtra (i);
1457 #endif
1458   if (bfp == NULL) return;
1459 
1460   ans = Message (MSG_OKC, "Currently deletes all GenBank SeqIDs");
1461   if (ans == ANS_CANCEL) return;
1462 
1463   GatherObjectsInEntity (bfp->input_entityID, 0, NULL, RemoveGBProtIDsProc, NULL, NULL);
1464 
1465   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1466   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1467 }
1468 
RemoveGIProc(GatherObjectPtr gop)1469 static Boolean RemoveGIProc (GatherObjectPtr gop)
1470 
1471 {
1472   BioseqPtr      bsp;
1473   SeqIdPtr       nextid, sip;
1474   SeqIdPtr PNTR  previd;
1475 
1476   if (gop->itemtype != OBJ_BIOSEQ) return TRUE;
1477   bsp = (BioseqPtr) gop->dataptr;
1478   if (bsp == NULL) return TRUE;
1479 
1480   previd = (SeqIdPtr PNTR) &(bsp->id);
1481   sip = bsp->id;
1482   while (sip != NULL) {
1483     nextid = sip->next;
1484     if (sip->choice == SEQID_GI) {
1485       *previd = sip->next;
1486       sip->next = NULL;
1487       SeqIdFree (sip);
1488     } else {
1489       previd = (SeqIdPtr PNTR) &(sip->next);
1490     }
1491     sip = sip->next;
1492   }
1493 
1494   return TRUE;
1495 }
1496 
RemoveGIsFromBioseqs(IteM i)1497 void RemoveGIsFromBioseqs (IteM i)
1498 
1499 {
1500   MsgAnswer    ans;
1501   BaseFormPtr  bfp;
1502 
1503 #ifdef WIN_MAC
1504   bfp = currentFormDataPtr;
1505 #else
1506   bfp = GetObjectExtra (i);
1507 #endif
1508   if (bfp == NULL) return;
1509 
1510   ans = Message (MSG_OKC, "Currently deletes all GI SeqIDs");
1511   if (ans == ANS_CANCEL) return;
1512 
1513   GatherObjectsInEntity (bfp->input_entityID, 0, NULL, RemoveGIProc, NULL, NULL);
1514 
1515   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1516   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1517 }
1518 
1519 
DoBuildContig(void)1520 extern Boolean DoBuildContig (void)
1521 
1522 {
1523   MsgAnswer    ans;
1524   BioseqPtr    bsp;
1525   Pointer      dataptr;
1526   Uint2        datatype;
1527   Uint2        entityID;
1528   FILE         *fp;
1529   Int2         handled;
1530   Char         path [PATH_MAX];
1531   SeqEntryPtr  sep;
1532 
1533   if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return FALSE;
1534   fp = FileOpen (path, "r");
1535   if (fp == NULL) return FALSE;
1536   ans = Message (MSG_YN, "Are coordinates on the master (as opposed to the individual accession)?");
1537   sep = ReadContigList (fp, (Boolean) (ans == ANS_YES));
1538   FileClose (fp);
1539   if (sep == NULL || sep->choice != 1) return FALSE;
1540 
1541   bsp = (BioseqPtr) sep->data.ptrvalue;
1542   if (bsp == NULL) return FALSE;
1543   datatype = OBJ_BIOSEQ;
1544   dataptr = (Pointer) bsp;
1545   entityID = ObjMgrRegister (datatype, dataptr);
1546   if (dataptr == NULL || entityID == 0) return FALSE;
1547 
1548   WatchCursor ();
1549   Update ();
1550   handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
1551                               OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
1552   ArrowCursor ();
1553   Update ();
1554 
1555   if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
1556     Message (MSG_FATAL, "Unable to launch viewer.");
1557     SeqEntryFree (sep);
1558     return FALSE;
1559   }
1560 
1561   ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
1562   ObjMgrSetDirtyFlag (entityID, TRUE);
1563   return TRUE;
1564 }
1565 
DoParseTrinomial(BioSourcePtr biop,Pointer userdata)1566 static void DoParseTrinomial (BioSourcePtr biop, Pointer userdata)
1567 
1568 {
1569   BinomialOrgNamePtr  bonp;
1570   OrgModPtr           omp;
1571   OrgNamePtr          onp;
1572   OrgRefPtr           orp;
1573   CharPtr             str;
1574 
1575   if (biop == NULL) return;
1576   orp = biop->org;
1577   if (orp == NULL) return;
1578   onp = orp->orgname;
1579   if (onp == NULL) return;
1580   if (onp->choice != 1) return;
1581   bonp = (BinomialOrgNamePtr) onp->data;
1582   if (bonp == NULL) return;
1583   if (StringHasNoText (bonp->subspecies)) return;
1584   for (omp = onp->mod; omp != NULL; omp = omp->next) {
1585     if (omp->subtype == ORGMOD_sub_species) return;
1586   }
1587   str = bonp->subspecies;
1588   if (StringNICmp (str, "subsp. ", 7) == 0) {
1589     str += 7;
1590     if (StringHasNoText (str)) return;
1591   }
1592   omp = OrgModNew ();
1593   if (omp == NULL) return;
1594   omp->subtype = ORGMOD_sub_species;
1595   omp->subname = StringSave (str);
1596   omp->next = onp->mod;
1597   onp->mod = omp;
1598 }
1599 
1600 extern void ParseTrinomial (IteM i);
ParseTrinomial(IteM i)1601 extern void ParseTrinomial (IteM i)
1602 
1603 {
1604   BaseFormPtr  bfp;
1605   SeqEntryPtr  sep;
1606 
1607 #ifdef WIN_MAC
1608   bfp = currentFormDataPtr;
1609 #else
1610   bfp = GetObjectExtra (i);
1611 #endif
1612   if (bfp == NULL) return;
1613   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1614   if (sep == NULL) return;
1615 
1616   VisitBioSourcesInSep (sep, NULL, DoParseTrinomial);
1617 
1618   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1619   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1620   Update ();
1621 }
1622 
1623 
1624 
1625 #define NUM_SITES 27
1626 static CharPtr siteString [NUM_SITES] = {
1627   "", "active site", "binding site", "cleavage site", "inhibition site", "modified site",
1628   "glycosylation site", "myristoylation site", "mutagenized site", "metal binding site",
1629   "phosphorylation site", "acetylation site", "amidation site", "methylation site",
1630   "hydroxylation site", "sulfatation site", "oxidative deamination site",
1631   "pyrrolidone carboxylic acid site", "gamma carboxyglutamic acid site",
1632   "blocked site", "lipid binding site", "np binding site", "DNA binding site",
1633   "signal peptide", "transit peptide", "transmembrane region", "nitrosylation"
1634 };
1635 
1636 /*=========================================================================*/
1637 /*                                                                         */
1638 /* SeqLocAdjustByOffset ()                                                 */
1639 /*                                                                         */
1640 /*=========================================================================*/
1641 
SeqLocAdjustByOffset(SeqLocPtr slp,Int4 offset)1642 extern void SeqLocAdjustByOffset (SeqLocPtr slp,
1643                   Int4 offset)
1644 {
1645   SeqIntPtr sinp;
1646 
1647   switch (slp->choice) {
1648   case SEQLOC_INT :
1649     sinp = (SeqIntPtr) slp->data.ptrvalue;
1650     if (NULL == sinp)
1651       break;
1652     sinp->from += offset;
1653     sinp->to   += offset;
1654     break;
1655   case SEQLOC_EMPTY :
1656   case SEQLOC_NULL :
1657   case SEQLOC_WHOLE :
1658   case SEQLOC_PNT :
1659   case SEQLOC_PACKED_PNT :
1660   case SEQLOC_PACKED_INT :
1661   case SEQLOC_MIX :
1662   case SEQLOC_EQUIV :
1663   case SEQLOC_BOND :
1664   case SEQLOC_FEAT :
1665   default :
1666     break;
1667   }
1668 }
1669 
1670 
ConvertImpToSpecialRNA(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1671 static Boolean ConvertImpToSpecialRNA
1672 (SeqFeatPtr sfp,
1673  Uint2      featdef_to,
1674  Pointer    extradata)
1675 {
1676   RnaRefPtr          rrp;
1677 
1678   if (sfp == NULL || sfp->data.choice != SEQFEAT_IMP)
1679   {
1680     return FALSE;
1681   }
1682   rrp = RnaRefNew ();
1683   if (rrp != NULL) {
1684     sfp->data.value.ptrvalue = ImpFeatFree ((ImpFeatPtr) sfp->data.value.ptrvalue);
1685     sfp->data.choice = SEQFEAT_RNA;
1686     sfp->data.value.ptrvalue = (Pointer) rrp;
1687     if (featdef_to == FEATDEF_precursor_RNA) {
1688       rrp->type = 1;
1689     } else {
1690       rrp->type = 255;
1691     }
1692   }
1693   return TRUE;
1694 }
1695 
ConvertRegionToRNA(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1696 static Boolean ConvertRegionToRNA
1697 (SeqFeatPtr sfp,
1698  Uint2      featdef_to,
1699  Pointer    extradata)
1700 {
1701   RnaRefPtr  rrp;
1702   CharPtr    str;
1703 
1704   if (sfp == NULL || sfp->data.choice != SEQFEAT_REGION)
1705   {
1706     return FALSE;
1707   }
1708 
1709   rrp = RnaRefNew ();
1710   if (NULL == rrp)
1711   {
1712     return FALSE;
1713   }
1714 
1715   str = (CharPtr) sfp->data.value.ptrvalue;
1716   sfp->data.choice = SEQFEAT_RNA;
1717   sfp->data.value.ptrvalue = (Pointer) rrp;
1718 
1719   if (featdef_to == FEATDEF_precursor_RNA) {
1720     rrp->type = 1;
1721   } else {
1722     rrp->type = 255;
1723   }
1724 
1725   if (! StringHasNoText (str)) {
1726     rrp->ext.choice = 1;
1727     rrp->ext.value.ptrvalue = str;
1728   }
1729   return TRUE;
1730 }
1731 
1732 
CommentShouldBeProduct(CharPtr comment)1733 static Boolean CommentShouldBeProduct (CharPtr comment)
1734 {
1735   CharPtr search1 = "internal transcribed spacer ";
1736   CharPtr search2 = "ITS";
1737   CharPtr found;
1738   Int4 len;
1739 
1740   if (StringHasNoText (comment)) {
1741     return FALSE;
1742   }
1743   if ((found = StringISearch (comment, search1)) != NULL
1744       && (len = StringLen (search1)) < StringLen (found)
1745       && (*(found + len) == '1' || *(found + len) == '2' || *(found + len) == '3')) {
1746     return TRUE;
1747   }
1748 
1749   if ((found = StringISearch (comment, search2)) != NULL
1750       && (len = StringLen (search2)) < StringLen (found)
1751       && (*(found + len) == '1' || *(found + len) == '2' || *(found + len) == '3')) {
1752     return TRUE;
1753   }
1754   return FALSE;
1755 }
1756 
1757 
ConvertImpToRNA(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1758 static Boolean ConvertImpToRNA
1759 (SeqFeatPtr sfp,
1760  Uint2      featdef_to,
1761  Pointer    extradata)
1762 {
1763   RnaRefPtr  rrp;
1764   RNAGenPtr  rgp;
1765   Boolean    was_misc_feat = FALSE;
1766 
1767   if (sfp == NULL || sfp->data.choice != SEQFEAT_IMP)
1768   {
1769     return FALSE;
1770   }
1771   if (sfp->idx.subtype == FEATDEF_misc_feature) {
1772     was_misc_feat = TRUE;
1773   }
1774 
1775   rrp = RnaRefNew ();
1776   if (NULL == rrp)
1777     return FALSE;
1778 
1779   sfp->data.value.ptrvalue =
1780     ImpFeatFree ((ImpFeatPtr) sfp->data.value.ptrvalue);
1781   sfp->data.choice = SEQFEAT_RNA;
1782   sfp->data.value.ptrvalue = (Pointer) rrp;
1783 
1784   switch (featdef_to) {
1785   case FEATDEF_preRNA :
1786     rrp->type = 1;
1787     break;
1788   case FEATDEF_mRNA :
1789     rrp->type = 2;
1790     break;
1791   case FEATDEF_tRNA :
1792     rrp->type = 3;
1793     break;
1794   case FEATDEF_rRNA :
1795     rrp->type = 4;
1796     break;
1797   case FEATDEF_snRNA :
1798     rrp->type = 5;
1799     break;
1800   case FEATDEF_scRNA :
1801     rrp->type = 6;
1802     break;
1803   case FEATDEF_snoRNA :
1804     rrp->type = 7;
1805     break;
1806   case FEATDEF_ncRNA :
1807     rrp->type = 8;
1808     rrp->ext.choice = 3;
1809     rrp->ext.value.ptrvalue = RNAGenNew ();
1810     break;
1811   case FEATDEF_tmRNA :
1812     rrp->type = 9;
1813     rrp->ext.choice = 3;
1814     rrp->ext.value.ptrvalue = RNAGenNew ();
1815     break;
1816   case FEATDEF_misc_RNA:
1817     rrp->type = 10;
1818     rrp->ext.choice = 3;
1819     rgp = RNAGenNew ();
1820     rrp->ext.value.ptrvalue = rgp;
1821     if (was_misc_feat && CommentShouldBeProduct(sfp->comment)) {
1822       rgp->product = sfp->comment;
1823       sfp->comment = NULL;
1824     }
1825     break;
1826   case FEATDEF_otherRNA :
1827     if (was_misc_feat && CommentShouldBeProduct(sfp->comment)) {
1828       rrp->type = 10;
1829       rrp->ext.choice = 3;
1830       rgp = RNAGenNew ();
1831       rrp->ext.value.ptrvalue = rgp;
1832       rgp->product = sfp->comment;
1833       sfp->comment = NULL;
1834     } else {
1835       rrp->type = 255;
1836       rrp->ext.choice = 1;
1837       rrp->ext.value.ptrvalue = StringSave ("misc_RNA");
1838     }
1839     break;
1840   default :
1841     break;
1842   }
1843   return TRUE;
1844 }
1845 
ConvertCommentToMiscFeat(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1846 static Boolean ConvertCommentToMiscFeat (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
1847 {
1848   ImpFeatPtr ifp;
1849 
1850   if (sfp == NULL || sfp->data.choice != SEQFEAT_COMMENT || sfp->data.value.ptrvalue != NULL)
1851   {
1852     return FALSE;
1853   }
1854 
1855   ifp = ImpFeatNew ();
1856   if (ifp != NULL) {
1857     ifp->key = StringSave ("misc_feature");
1858     sfp->data.choice = SEQFEAT_IMP;
1859     sfp->data.value.ptrvalue = (Pointer) ifp;
1860     return TRUE;
1861   }
1862   return FALSE;
1863 }
1864 
ConvertGeneToImpFeat(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1865 static Boolean ConvertGeneToImpFeat
1866 (SeqFeatPtr sfp,
1867  Uint2      featdef_to,
1868  Pointer    extradata)
1869 {
1870   return ConvertGeneToImpFeatFunc (sfp, featdef_to);
1871 }
1872 
ConvertRNAToMiscFeat(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1873 static Boolean ConvertRNAToMiscFeat
1874 (SeqFeatPtr sfp,
1875  Uint2      featdef_to,
1876  Pointer    extradata)
1877 {
1878   return ConvertRNAToImpFeat (sfp, featdef_to);
1879 }
1880 
ConvertSiteToMiscFeat(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1881 static Boolean ConvertSiteToMiscFeat
1882 (SeqFeatPtr sfp,
1883  Uint2      featdef_to,
1884  Pointer    extradata)
1885 {
1886   GBQualPtr  gbqual;
1887   ImpFeatPtr ifp;
1888   Int2       sitetype;
1889 
1890   if (sfp == NULL || sfp->data.choice != SEQFEAT_SITE)
1891   {
1892     return FALSE;
1893   }
1894 
1895   ifp = ImpFeatNew ();
1896   if (NULL == ifp)
1897   {
1898     return FALSE;
1899   }
1900 
1901   sitetype = (Int2) sfp->data.value.intvalue;
1902   sfp->data.choice = SEQFEAT_IMP;
1903   sfp->data.value.ptrvalue = (Pointer) ifp;
1904   ifp->key = StringSave ("misc_feature");
1905   if (sitetype > 0 && sitetype < NUM_SITES) {
1906     gbqual = GBQualNew ();
1907     if (gbqual != NULL) {
1908       gbqual->qual = StringSave ("note");
1909       gbqual->val = StringSave (siteString [sitetype]);
1910       gbqual->next = sfp->qual;
1911       sfp->qual = gbqual;
1912     }
1913   }
1914   return TRUE;
1915 }
1916 
ConvertProtToRegion(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1917 static Boolean ConvertProtToRegion
1918 (SeqFeatPtr sfp,
1919  Uint2      featdef_to,
1920  Pointer    extradata)
1921 {
1922   ProtRefPtr prp;
1923   ValNodePtr vnp;
1924   CharPtr    str;
1925 
1926   if (sfp == NULL || sfp->data.choice != SEQFEAT_PROT)
1927   {
1928     return FALSE;
1929   }
1930   prp = (ProtRefPtr) sfp->data.value.ptrvalue;
1931   if (NULL == prp)
1932   {
1933     return FALSE;
1934   }
1935 
1936   vnp = prp->name;
1937   if (vnp != NULL && vnp->next == NULL) {
1938     str = (CharPtr) vnp->data.ptrvalue;
1939     if (! StringHasNoText (str)) {
1940       vnp->data.ptrvalue = NULL;
1941       sfp->data.value.ptrvalue = ProtRefFree (prp);
1942       sfp->data.choice = SEQFEAT_REGION;
1943       sfp->data.value.ptrvalue = (Pointer) str;
1944     }
1945   }
1946   return TRUE;
1947 }
1948 
1949 
ConvertRegionToProt(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)1950 static Boolean ConvertRegionToProt
1951 (SeqFeatPtr sfp,
1952  Uint2      featdef_to,
1953  Pointer    extradata)
1954 {
1955   return ConvertRegionToProtFunc (sfp, featdef_to);
1956 }
1957 
1958 
ConvertRNAToNcRNA(SeqFeatPtr sfp)1959 static Boolean ConvertRNAToNcRNA
1960 (SeqFeatPtr sfp)
1961 {
1962   RnaRefPtr  rrp;
1963   tRNAPtr    trp;
1964   RNAGenPtr  rgp = NULL;
1965 
1966   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA) return FALSE;
1967 
1968   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
1969   if (NULL == rrp) {
1970     rrp = RnaRefNew ();
1971     sfp->data.value.ptrvalue = rrp;
1972   }
1973 
1974   if (rrp->ext.choice == 2) {
1975     trp = (tRNAPtr) rrp->ext.value.ptrvalue;
1976     if (trp != NULL) {
1977       trp->anticodon = SeqLocFree (trp->anticodon);
1978       trp = MemFree (trp);
1979       rrp->ext.value.ptrvalue = trp;
1980     }
1981     rrp->ext.choice = 0;
1982   }
1983 
1984   /* might be converting from other ncRNA, tmRNA, or misc_RNA */
1985   if (rrp->ext.choice == 1) {
1986     rgp = RNAGenNew ();
1987     rgp->product = rrp->ext.value.ptrvalue;
1988     rrp->ext.choice = 3;
1989     rrp->ext.value.ptrvalue = rgp;
1990   } else if (rrp->ext.choice == 0) {
1991     rgp = RNAGenNew ();
1992     rrp->ext.choice = 3;
1993     rrp->ext.value.ptrvalue = rgp;
1994   } else if (rrp->ext.choice == 3) {
1995     rgp = rrp->ext.value.ptrvalue;
1996     if (rgp == NULL) {
1997       rgp = RNAGenNew ();
1998       rrp->ext.value.ptrvalue = rgp;
1999     }
2000   }
2001 
2002   if (rgp != NULL) {
2003     if (rrp->type == 5) {
2004       rgp->_class = StringSave ("snRNA");
2005     } else if (rrp->type == 6) {
2006       rgp->_class = StringSave ("scRNA");
2007     } else if (rrp->type == 7) {
2008       rgp->_class = StringSave ("snoRNA");
2009     }
2010   }
2011 
2012   rrp->type = 8;
2013   return TRUE;
2014 }
2015 
2016 
ConvertFromncRNAtoMiscRNA(SeqFeatPtr sfp)2017 static void ConvertFromncRNAtoMiscRNA (SeqFeatPtr sfp)
2018 {
2019   RnaRefPtr rrp;
2020   RNAGenPtr rgp;
2021   CharPtr tmp;
2022 
2023   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA) return;
2024   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
2025   if (rrp == NULL || rrp->ext.choice != 3) {
2026     return;
2027   }
2028 
2029   rgp = (RNAGenPtr) rrp->ext.value.ptrvalue;
2030   if (rgp == NULL) {
2031     return;
2032   }
2033 
2034   /* if no product but has comment, promote comment to product */
2035   if (rgp->product == NULL && !StringHasNoText (sfp->comment)) {
2036     rgp->product = sfp->comment;
2037     sfp->comment = NULL;
2038   }
2039 
2040   /* move ncRNA_class elsewhere */
2041   if (!StringHasNoText (rgp->_class)) {
2042     if (StringCmp (rgp->_class, "other") == 0) {
2043       rgp->_class = MemFree (rgp->_class);
2044     } else if (rgp->product == NULL) {
2045       rgp->product = rgp->_class;
2046       rgp->_class = NULL;
2047     } else {
2048       if (StringHasNoText (sfp->comment)) {
2049         sfp->comment = MemFree (sfp->comment);
2050         sfp->comment = StringSave (rgp->_class);
2051       } else {
2052         tmp = (CharPtr) MemNew (sizeof (Char) * (StringLen (sfp->comment) + StringLen (rgp->_class) + 3));
2053         sprintf (tmp, "%s; %s", sfp->comment, rgp->_class);
2054         sfp->comment = MemFree (sfp->comment);
2055         sfp->comment = tmp;
2056       }
2057       rgp->_class = MemFree (rgp->_class);
2058     }
2059   }
2060 }
2061 
2062 
ConvertRNAToRNA(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2063 static Boolean ConvertRNAToRNA
2064 (SeqFeatPtr sfp,
2065  Uint2      featdef_to,
2066  Pointer    extradata)
2067 {
2068   RnaRefPtr  rrp;
2069   Boolean    from_misc = FALSE, to_misc = FALSE;
2070   GBQualPtr  gbq, gbq_p = NULL;
2071 
2072   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
2073   if (NULL == rrp)
2074     return FALSE;
2075 
2076   if (rrp->type == 255) {
2077     from_misc = TRUE;
2078   }
2079 
2080   switch (featdef_to) {
2081     case FEATDEF_preRNA :
2082       rrp->type = 1;
2083       break;
2084     case FEATDEF_mRNA :
2085       rrp->type = 2;
2086       break;
2087     case FEATDEF_tRNA :
2088       rrp->type = 3;
2089       break;
2090     case FEATDEF_rRNA :
2091       rrp->type = 4;
2092       break;
2093     case FEATDEF_snRNA :
2094       rrp->type = 5;
2095       to_misc = TRUE;
2096       break;
2097     case FEATDEF_scRNA :
2098       rrp->type = 6;
2099       to_misc = TRUE;
2100       break;
2101     case FEATDEF_snoRNA :
2102       rrp->type = 7;
2103       to_misc = TRUE;
2104       break;
2105     case FEATDEF_ncRNA :
2106       return ConvertRNAToNcRNA (sfp);
2107       break;
2108     case FEATDEF_otherRNA :
2109       rrp->type = 255;
2110       ConvertFromncRNAtoMiscRNA (sfp);
2111       break;
2112     default:
2113       break;
2114   }
2115   if (from_misc && !to_misc && rrp->ext.choice == 1 && StringCmp (rrp->ext.value.ptrvalue, "misc_RNA") == 0) {
2116     /* move product qual to string */
2117     gbq = sfp->qual;
2118     while (gbq != NULL && StringCmp (gbq->qual, "product") != 0) {
2119       gbq_p = gbq;
2120       gbq = gbq->next;
2121     }
2122     if (gbq == NULL) {
2123       rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
2124       rrp->ext.choice = 0;
2125     } else {
2126       rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
2127       rrp->ext.value.ptrvalue = gbq->val;
2128       gbq->val = NULL;
2129       if (gbq_p == NULL) {
2130         sfp->qual = gbq->next;
2131       } else {
2132         gbq_p->next = gbq->next;
2133       }
2134       gbq->next = NULL;
2135       gbq = GBQualFree (gbq);
2136     }
2137   }
2138   return TRUE;
2139 }
2140 
ConvertncRNAToMiscBinding(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2141 static Boolean ConvertncRNAToMiscBinding
2142 (SeqFeatPtr sfp,
2143  Uint2      featdef_to,
2144  Pointer    extradata)
2145 {
2146   RnaRefPtr  rrp;
2147   RNAGenPtr  rgp;
2148   Boolean    asked = TRUE, replace = FALSE, use_semicolon = TRUE;
2149   ImpFeatPtr ifp;
2150 
2151   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
2152   if (NULL == rrp)
2153     return FALSE;
2154 
2155   if (rrp->ext.choice == 1) {
2156     /* move product to note */
2157     AppendOrReplaceString (&(sfp->comment), rrp->ext.value.ptrvalue, &asked, &replace, &use_semicolon);
2158   } else if (rrp->ext.choice == 3 && (rgp = (RNAGenPtr) rrp->ext.value.ptrvalue) != NULL
2159              && !StringHasNoText (rgp->product)) {
2160     AppendOrReplaceString (&(sfp->comment), rgp->product, &asked, &replace, &use_semicolon);
2161   }
2162   rrp = RnaRefFree (rrp);
2163   sfp->data.choice = SEQFEAT_IMP;
2164   ifp = ImpFeatNew ();
2165   ifp->key = StringSave ("misc_binding");
2166   sfp->data.value.ptrvalue = ifp;
2167   sfp->idx.subtype = 0;
2168 
2169   return TRUE;
2170 }
2171 
ConvertProtToProt(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2172 static Boolean ConvertProtToProt
2173 (SeqFeatPtr sfp,
2174  Uint2      featdef_to,
2175  Pointer    extradata)
2176 {
2177   return ConvertProtToProtFunc (sfp, featdef_to);
2178 }
2179 
2180 
ConvertImpToProt(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2181 static Boolean ConvertImpToProt (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
2182 {
2183   return ConvertImpToProtFunc (sfp, featdef_to);
2184 }
2185 
2186 
ConvertProtToImp(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2187 static Boolean ConvertProtToImp (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
2188 {
2189   return ConvertProtToImpFunc (sfp, featdef_to);
2190 }
2191 
2192 
ConvertBioSrcToRepeatRegionEx(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2193 static Boolean ConvertBioSrcToRepeatRegionEx (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
2194 {
2195   return ConvertBioSrcToRepeatRegion (sfp, featdef_to);
2196 }
2197 
2198 
ConvertCDSToMatPeptide(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2199 static Boolean ConvertCDSToMatPeptide (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
2200 {
2201   return AutoConvertCDSToMiscFeat (sfp, extradata == NULL ? TRUE : !(*((BoolPtr) extradata)));
2202 }
2203 
2204 
ConvertMiscFeatureToCDSFunction(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2205 static Boolean ConvertMiscFeatureToCDSFunction (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
2206 {
2207   return ConvertMiscFeatToCodingRegion (sfp);
2208 }
2209 
2210 
ConvertmRNAToCodingRegionFunction(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2211 static Boolean ConvertmRNAToCodingRegionFunction (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
2212 {
2213   return ConvertmRNAToCodingRegion (sfp);
2214 }
2215 
2216 
ConverttRNAToGeneFunction(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2217 static Boolean ConverttRNAToGeneFunction (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
2218 {
2219   return ConverttRNAToGene (sfp);
2220 }
2221 
2222 
ConvertMiscFeatureToGeneFunction(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)2223 static Boolean ConvertMiscFeatureToGeneFunction (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
2224 {
2225   return ConvertMiscFeatToGene (sfp);
2226 }
2227 
2228 
2229 extern EnumFieldAssoc  enum_bond_alist [];
2230 extern EnumFieldAssoc  enum_site_alist [];
2231 
2232 
2233 static GbFeatName EditQualifierList[] = {
2234  {"allele", Class_text},
2235  {"anticodon", Class_pos_aa},
2236  {"bound_moiety", Class_text},
2237  {"chromosome", Class_text},
2238  {"citation", Class_bracket_int},
2239  {"codon", Class_seq_aa},
2240  {"codon_start", Class_int_or},
2241  {"compare", Class_text },
2242  {"cons_splice", Class_site},
2243  {"db_xref", Class_text},
2244  {"direction", Class_L_R_B},
2245  {"EC_number", Class_ecnum},
2246  {"evidence", Class_exper},
2247  {"exception", Class_text},
2248  {"experiment", Class_text},
2249  {"frequency", Class_text},
2250  {"function", Class_text},
2251  {"gene", Class_text},
2252  {"gdb_xref", Class_text},
2253  {"label", Class_token},
2254  {"map", Class_text},
2255  {"mobile_element", Class_text},
2256  {"mod_base", Class_token}, {"note", Class_note},
2257  {"number", Class_number},
2258 #ifdef INTERNAL_NCBI_SEQUIN
2259  {"old_locus_tag", Class_text},
2260 #endif
2261  {"operon", Class_text},
2262  {"organism", Class_text},
2263  {"partial", Class_none}, {"PCR_conditions", Class_text},
2264  {"phenotype", Class_text},
2265  {"plasmid", Class_text}, {"product", Class_text},
2266  {"pseudo", Class_none},
2267  {"rearranged", Class_none}, { "replace", Class_text},
2268  {"rpt_family", Class_text}, {"rpt_type", Class_rpt},
2269  {"rpt_unit", Class_token}, {"rpt_unit_seq", Class_token}, {"rpt_unit_range", Class_token},
2270  {"satellite", Class_text},
2271  {"sequenced_mol", Class_text},
2272  {"standard_name", Class_text},
2273  {"translation", Class_text}, {"transl_except", Class_pos_aa},
2274  {"transl_table", Class_int},
2275  {"usedin", Class_token},
2276  {"focus", Class_none},
2277  {"protein_id", Class_text},
2278  {"organelle", Class_text}, {"transcript_id", Class_text},
2279  {"transgenic", Class_none}, {"environmental_sample", Class_none},
2280  {"locus_tag", Class_text}, {"mol_type", Class_text},
2281  {"segment", Class_text}
2282 };
2283 
2284 const Int4 NumEditQualifiers = sizeof (EditQualifierList) / sizeof (GbFeatName);
2285 #define QUAL_EVIDENCE 13
2286 #define QUAL_EXPERIMENT 15
2287 
2288 
ENUM_ALIST(biosource_genome_alistX)2289 static ENUM_ALIST(biosource_genome_alistX)
2290   {" ",                    0},
2291   {"Apicoplast",          16},
2292   {"Chloroplast",          2},
2293   {"Chromatophore",       22},
2294   {"Chromoplast",          3},
2295   {"Chromosome",          21},
2296   {"Cyanelle",            12},
2297   {"Endogenous-virus",    19},
2298   {"Extrachromosomal",     8},
2299   {"Genomic",              1},
2300   {"Hydrogenosome",       20},
2301   {"Insertion Sequence",  11},
2302   {"Kinetoplast",          4},
2303   {"Leucoplast",          17},
2304   {"Macronuclear",         7},
2305   {"Mitochondrion",        5},
2306   {"Nucleomorph",         15},
2307   {"Plasmid",              9},
2308   {"Plastid",              6},
2309   {"Proplastid",          18},
2310   {"Proviral",            13},
2311   {"Transposon",          10},
2312 END_ENUM_ALIST
2313 
2314 static ENUM_ALIST(orgref_textfield_alist)
2315   {" ",                    0},
2316   {"Scientific Name",      1},
2317   {"Common Name",          2},
2318   {"Lineage",              3},
2319   {"Division",             4},
2320 END_ENUM_ALIST
2321 
2322 typedef struct sourceformdata {
2323   FEATURE_FORM_BLOCK
2324 
2325   Int2           type;
2326   ButtoN         applyToParts;
2327   TexT           onlyThisPart;
2328   GrouP          sourceGroup;
2329   GrouP          modGrp;
2330   GrouP          genGrp;
2331   GrouP          refGrp;
2332   GrouP          txtGrp;
2333   GrouP          originGrp;
2334   PopuP          frommod;
2335   PopuP          tomod;
2336   PopuP          fromgen;
2337   PopuP          togen;
2338   PopuP          fromref;
2339   PopuP          toref;
2340   PopuP          toorigin;
2341   PopuP          fromorigin;
2342   TexT           findthis;
2343   TexT           replacewith;
2344   GrouP          applyChoiceGrp;  /* This is the group for the radio buttons for the
2345                                    * constraint on which biosources to operate on.
2346                                    */
2347   PopuP          qual_to_have;    /* This is the control that indicates which qualifier
2348                                    * should be present to operate on a biosource.
2349                                    */
2350   TexT           text_to_have;    /* This is the control that indicates the text that
2351                                    * should be present in the biosource to be operated on.
2352                                    */
2353   Int4           applyChoiceVal;  /* This is the value of the applyChoiceGrp choice. */
2354   CharPtr        text_to_have_str;/* This is the contents of the text_to_have box. */
2355   Int4           qual_to_have_val;/* This is the subtype for the qual to have. */
2356 
2357   Int2           choice;
2358   Int2           fromval;
2359   Int2           toval;
2360   Int2           onlythis;
2361   CharPtr        findStr;
2362   CharPtr        replaceStr;
2363 
2364   Boolean        replaceOldAsked;
2365   Boolean        doReplaceAll;
2366   Boolean        use_semicolon;
2367   ButtoN         leaveDlgUp;
2368 } SourceFormData, PNTR SourceFormPtr;
2369 
2370 Uint2 mod_widths [] = {
2371   0, 25
2372 };
2373 
2374 Uint2 mod_types [] = {
2375   TAGLIST_POPUP, TAGLIST_TEXT
2376 };
2377 
2378 
FindTypeForModNameText(CharPtr cp)2379 extern Uint1 FindTypeForModNameText (CharPtr cp)
2380 {
2381   Uint1 subtype;
2382 
2383   subtype = EquivalentSubSourceEx (cp, TRUE);
2384   if (subtype == 0) {
2385     subtype = EquivalentOrgMod (cp);
2386     if (subtype > 200) {
2387       /* function that calls this expects less than 100 vals for orgmod */
2388       /* need to adjust for old-lineage and old-name */
2389       subtype -= 200;
2390     }
2391   } else {
2392     /* function that calls this uses >100 to decide if subsource */
2393     subtype += 100;
2394   }
2395   if (subtype == 0) {
2396     subtype = SUBSRC_other;
2397   }
2398   return subtype;
2399 }
2400 
2401 
AppendOrReplaceString(CharPtr PNTR string_loc,CharPtr new_value,Boolean PNTR asked_question,Boolean PNTR do_replace,Boolean PNTR use_semicolon)2402 extern void AppendOrReplaceString (
2403   CharPtr PNTR string_loc,
2404   CharPtr new_value,
2405   Boolean PNTR asked_question,
2406   Boolean PNTR do_replace,
2407   Boolean PNTR use_semicolon
2408 )
2409 {
2410   MsgAnswer ans;
2411   CharPtr   tmp_value, tmp_new_value;
2412 
2413   if (string_loc == NULL
2414     || new_value == NULL
2415     || asked_question == NULL
2416     || do_replace == NULL
2417     || use_semicolon == NULL)
2418   {
2419     return;
2420   }
2421 
2422   if (! *asked_question && !StringHasNoText (*string_loc))
2423   {
2424     *asked_question = TRUE;
2425     ArrowCursor ();
2426     ans = Message (MSG_YN, "Do you wish to overwrite existing content?");
2427     *do_replace = (Boolean) (ans == ANS_YES);
2428     if (! *use_semicolon)
2429     {
2430       if (! *do_replace)
2431       {
2432         ans = Message (MSG_YN, "Separate items with semicolon?");
2433         *use_semicolon = (Boolean) (ans == ANS_YES);
2434       }
2435     }
2436     WatchCursor ();
2437     Update ();
2438   }
2439   if (*do_replace || StringHasNoText (*string_loc))
2440   {
2441     MemFree (*string_loc);
2442     *string_loc = StringSave (new_value);
2443   }
2444   else
2445   {
2446     tmp_value = MemNew (StringLen (*string_loc) + StringLen ( new_value) + 3);
2447     if (tmp_value == NULL) return;
2448     StringCpy (tmp_value, *string_loc);
2449     TrimSpacesAroundString (tmp_value);
2450     if (*use_semicolon)
2451     {
2452       StringCat (tmp_value, "; ");
2453     }
2454     else
2455     {
2456       StringCat (tmp_value, " ");
2457     }
2458     tmp_new_value = StringSave (new_value);
2459     TrimSpacesAroundString (tmp_new_value);
2460     StringCat (tmp_value, tmp_new_value);
2461     MemFree (tmp_new_value);
2462     MemFree (*string_loc);
2463     *string_loc = tmp_value;
2464   }
2465 }
2466 
ENUM_ALIST(origin_alist)2467 static ENUM_ALIST(origin_alist)
2468 {" ",               ORG_DEFAULT    },
2469 {"Natural",         ORG_NATURAL    },
2470 {"Natural Mutant",  ORG_NATMUT     },
2471 {"Mutant",          ORG_MUT        },
2472 {"Artificial",      ORG_ARTIFICIAL },
2473 {"Synthetic",       ORG_SYNTHETIC  },
2474 {"Other",           ORG_OTHER      },
2475 END_ENUM_ALIST
2476 
2477 
2478 typedef struct setsample
2479 {
2480   GetFeatureFieldString    fieldstring_func;
2481   GetDescriptorFieldString descrstring_func;
2482   Uint2                    entityID;
2483   ValNodePtr               field_list;
2484   FreeValNodeProc          free_vn_proc;
2485   CopyValNodeDataProc      copy_vn_proc;
2486   MatchValNodeProc         match_vn_proc;
2487   NameFromValNodeProc      label_vn_proc;
2488 
2489   FilterSetPtr             fsp;
2490 } SetSampleData, PNTR SetSamplePtr;
2491 
IntValNodeCopy(ValNodePtr vnp)2492 static ValNodePtr IntValNodeCopy (ValNodePtr vnp)
2493 {
2494   ValNodePtr vnp_new;
2495 
2496   if (vnp == NULL)
2497   {
2498     return NULL;
2499   }
2500   vnp_new = ValNodeNew (NULL);
2501   if (vnp_new != NULL)
2502   {
2503     vnp_new->choice = vnp->choice;
2504     vnp_new->data.intvalue = vnp->data.intvalue;
2505   }
2506   return vnp_new;
2507 }
2508 
IntValNodeMatch(ValNodePtr vnp1,ValNodePtr vnp2)2509 static Boolean IntValNodeMatch (ValNodePtr vnp1, ValNodePtr vnp2)
2510 {
2511   if (vnp1 == NULL && vnp2 == NULL)
2512   {
2513     return TRUE;
2514   }
2515   else if (vnp1 == NULL || vnp2 == NULL)
2516   {
2517     return FALSE;
2518   }
2519   else if (vnp1->data.intvalue == vnp2->data.intvalue)
2520   {
2521     return TRUE;
2522   }
2523   else
2524   {
2525     return FALSE;
2526   }
2527 }
2528 
LocationConstraintXClearText(LocationConstraintXPtr lcp)2529 static void LocationConstraintXClearText (LocationConstraintXPtr lcp)
2530 {
2531   if (lcp != NULL)
2532   {
2533     lcp->left = -1;
2534     lcp->right = -1;
2535   }
2536 }
2537 
LocationConstraintXFree(LocationConstraintXPtr lcp)2538 static LocationConstraintXPtr LocationConstraintXFree (LocationConstraintXPtr lcp)
2539 {
2540   lcp = MemFree (lcp);
2541   return lcp;
2542 }
2543 
LocationConstraintXCopy(LocationConstraintXPtr lcp)2544 static LocationConstraintXPtr LocationConstraintXCopy (LocationConstraintXPtr lcp)
2545 {
2546   LocationConstraintXPtr lcp_new;
2547   if (lcp == NULL)
2548   {
2549     return NULL;
2550   }
2551   lcp_new = (LocationConstraintXPtr) MemNew (sizeof (LocationConstraintXData));
2552   if (lcp_new != NULL)
2553   {
2554     lcp_new->left = lcp->left;
2555     lcp_new->right = lcp->right;
2556     lcp_new->interval_end_choice = lcp->interval_end_choice;
2557     lcp_new->match_choice = lcp->match_choice;
2558     lcp_new->strand = lcp->strand;
2559     lcp_new->sequence_type = lcp->sequence_type;
2560   }
2561   return lcp_new;
2562 }
2563 
StringConstraintXFree(StringConstraintXPtr scp)2564 extern StringConstraintXPtr StringConstraintXFree (StringConstraintXPtr scp)
2565 {
2566   if (scp == NULL) return NULL;
2567   scp->match_text = MemFree (scp->match_text);
2568   scp = MemFree (scp);
2569   return scp;
2570 }
2571 
StringConstraintClearText(StringConstraintXPtr scp)2572 static void StringConstraintClearText (StringConstraintXPtr scp)
2573 {
2574   if (scp != NULL)
2575   {
2576     scp->match_text = MemFree (scp->match_text);
2577   }
2578 }
2579 
StringConstraintCopy(StringConstraintXPtr scp)2580 static StringConstraintXPtr StringConstraintCopy (StringConstraintXPtr scp)
2581 {
2582   StringConstraintXPtr scp_new;
2583   if (scp == NULL)
2584   {
2585     return NULL;
2586   }
2587 
2588   scp_new = (StringConstraintXPtr) MemNew (sizeof (StringConstraintData));
2589   if (scp_new != NULL)
2590   {
2591     scp_new->match_text = StringSave (scp->match_text);
2592     scp_new->match_location = scp->match_location;
2593     scp_new->insensitive = scp->insensitive;
2594     scp_new->whole_word = scp->whole_word;
2595     scp_new->not_present = scp->not_present;
2596   }
2597   return scp_new;
2598 }
2599 
ValNodeFuncFree(ValNodePtr vnp,FreeValNodeProc free_vn_proc)2600 extern ValNodePtr ValNodeFuncFree (ValNodePtr vnp, FreeValNodeProc free_vn_proc)
2601 {
2602   if (vnp == NULL)
2603   {
2604     return NULL;
2605   }
2606   vnp->next = ValNodeFuncFree (vnp->next, free_vn_proc);
2607   if (free_vn_proc != NULL)
2608   {
2609     free_vn_proc (vnp);
2610   }
2611   ValNodeFree (vnp);
2612   return NULL;
2613 }
2614 
ChoiceConstraintFree(ChoiceConstraintPtr scp)2615 extern ChoiceConstraintPtr ChoiceConstraintFree (ChoiceConstraintPtr scp)
2616 {
2617   if (scp == NULL) return NULL;
2618   scp->qual_choice = ValNodeFuncFree (scp->qual_choice, scp->free_vn_proc);
2619   scp->qual_choice_match = ValNodeFuncFree (scp->qual_choice, scp->free_vn_proc);
2620   scp->string_constraint = StringConstraintXFree (scp->string_constraint);
2621   scp->pseudo_constraint = MemFree (scp->pseudo_constraint);
2622   scp = MemFree (scp);
2623   return scp;
2624 }
2625 
QualChoiceCopy(ValNodePtr vnp,CopyValNodeDataProc copy_vn_proc)2626 static ValNodePtr QualChoiceCopy (ValNodePtr vnp, CopyValNodeDataProc copy_vn_proc)
2627 {
2628   ValNodePtr new_list = NULL;
2629 
2630   if (vnp == NULL || copy_vn_proc == NULL)
2631   {
2632     return NULL;
2633   }
2634 
2635   new_list = copy_vn_proc (vnp);
2636   new_list->next = QualChoiceCopy (vnp->next, copy_vn_proc);
2637   return new_list;
2638 }
2639 
ChoiceConstraintCopy(ChoiceConstraintPtr ccp)2640 static ChoiceConstraintPtr ChoiceConstraintCopy (ChoiceConstraintPtr ccp)
2641 {
2642   ChoiceConstraintPtr ccp_new;
2643   if (ccp == NULL || ccp->copy_vn_proc == NULL)
2644   {
2645     return NULL;
2646   }
2647   ccp_new = (ChoiceConstraintPtr) MemNew (sizeof (ChoiceConstraintData));
2648   if (ccp_new != NULL)
2649   {
2650     ccp_new->constraint_type = ccp->constraint_type;
2651     ccp_new->qual_choice = QualChoiceCopy (ccp->qual_choice, ccp->copy_vn_proc);
2652     ccp_new->qual_choice_match = QualChoiceCopy (ccp->qual_choice_match, ccp->copy_vn_proc);
2653     ccp_new->string_constraint = StringConstraintCopy (ccp->string_constraint);
2654     ccp_new->copy_vn_proc = ccp->copy_vn_proc;
2655     ccp_new->free_vn_proc = ccp->free_vn_proc;
2656   }
2657   return ccp_new;
2658 }
2659 
ChoiceConstraintClearText(ChoiceConstraintPtr scp)2660 static void ChoiceConstraintClearText (ChoiceConstraintPtr scp)
2661 {
2662   if (scp != NULL)
2663   {
2664     StringConstraintClearText (scp->string_constraint);
2665   }
2666 }
2667 
2668 
FilterSetClearText(FilterSetPtr fsp)2669 extern void FilterSetClearText (FilterSetPtr fsp)
2670 {
2671   if (fsp != NULL)
2672   {
2673     StringConstraintClearText (fsp->scp);
2674     ChoiceConstraintClearText (fsp->ccp);
2675     LocationConstraintXClearText (fsp->lcp);
2676     StringConstraintClearText (fsp->id_list);
2677   }
2678 }
2679 
FilterSetNew(void)2680 extern FilterSetPtr FilterSetNew (void)
2681 {
2682   FilterSetPtr fsp_new;
2683   fsp_new = (FilterSetPtr) MemNew (sizeof (FilterSetData));
2684   if (fsp_new != NULL)
2685   {
2686     fsp_new->scp = NULL;
2687     fsp_new->ccp = NULL;
2688     fsp_new->lcp = NULL;
2689     fsp_new->cgp = NULL;
2690     fsp_new->id_list = NULL;
2691   }
2692   return fsp_new;
2693 }
2694 
FilterSetFree(FilterSetPtr fsp)2695 extern FilterSetPtr FilterSetFree (FilterSetPtr fsp)
2696 {
2697   if (fsp != NULL)
2698   {
2699     fsp->scp = StringConstraintXFree (fsp->scp);
2700     fsp->ccp = ChoiceConstraintFree (fsp->ccp);
2701     fsp->lcp = LocationConstraintXFree (fsp->lcp);
2702     fsp->cgp = ChoiceConstraintFree (fsp->cgp);
2703     fsp->id_list = StringConstraintXFree (fsp->id_list);
2704     fsp = MemFree (fsp);
2705   }
2706   return fsp;
2707 }
2708 
FilterSetCopy(FilterSetPtr fsp)2709 static FilterSetPtr FilterSetCopy (FilterSetPtr fsp)
2710 {
2711   FilterSetPtr fsp_new;
2712 
2713   if (fsp == NULL)
2714   {
2715     return NULL;
2716   }
2717   fsp_new = (FilterSetPtr) MemNew (sizeof (FilterSetData));
2718   if (fsp_new != NULL)
2719   {
2720     fsp_new->scp = StringConstraintCopy (fsp->scp);
2721     fsp_new->ccp = ChoiceConstraintCopy (fsp->ccp);
2722     fsp_new->lcp = LocationConstraintXCopy (fsp->lcp);
2723     fsp_new->cgp = ChoiceConstraintCopy (fsp->cgp);
2724     fsp_new->id_list = StringConstraintCopy (fsp->id_list);
2725   }
2726   return fsp_new;
2727 }
2728 
2729 
SetSampleFree(SetSamplePtr ssp)2730 static SetSamplePtr SetSampleFree (SetSamplePtr ssp)
2731 {
2732   ValNodePtr vnp;
2733 
2734   if (ssp == NULL)
2735   {
2736     return NULL;
2737   }
2738   if (ssp->free_vn_proc != NULL)
2739   {
2740     for (vnp = ssp->field_list; vnp != NULL; vnp = vnp->next)
2741     {
2742       (ssp->free_vn_proc)(vnp);
2743     }
2744   }
2745   ssp->field_list = ValNodeFree (ssp->field_list);
2746 
2747   ssp = MemFree (ssp);
2748   return ssp;
2749 }
2750 
SetSampleCopy(SetSamplePtr ssp)2751 static SetSamplePtr SetSampleCopy (SetSamplePtr ssp)
2752 {
2753   SetSamplePtr ssp_new;
2754   ValNodePtr   vnp_old, vnp_new, vnp_last = NULL;
2755 
2756   if (ssp == NULL)
2757   {
2758     return NULL;
2759   }
2760   ssp_new = (SetSamplePtr) MemNew (sizeof (SetSampleData));
2761   if (ssp_new != NULL)
2762   {
2763     ssp_new->fieldstring_func = ssp->fieldstring_func;
2764     ssp_new->descrstring_func = ssp->descrstring_func;
2765     ssp_new->free_vn_proc = ssp->free_vn_proc;
2766     ssp_new->copy_vn_proc = ssp->copy_vn_proc;
2767     ssp_new->match_vn_proc = ssp->match_vn_proc;
2768     ssp_new->label_vn_proc = ssp->label_vn_proc;
2769 
2770     ssp_new->entityID = ssp->entityID;
2771     ssp_new->field_list = NULL;
2772     for (vnp_old = ssp->field_list; vnp_old != NULL; vnp_old = vnp_old->next)
2773     {
2774       vnp_new = (ssp_new->copy_vn_proc)(vnp_old);
2775       if (vnp_last == NULL)
2776       {
2777         ssp_new->field_list = vnp_new;
2778       }
2779       else
2780       {
2781         vnp_last->next = vnp_new;
2782       }
2783       vnp_last = vnp_new;
2784     }
2785     ssp_new->fsp = FilterSetCopy (ssp->fsp);
2786   }
2787   return ssp_new;
2788 }
2789 
2790 #define PARSE_FIELD_DEFLINE       1
2791 #define PARSE_FIELD_BIOSRC_STRING 2
2792 #define PARSE_FIELD_SOURCE_QUAL   3
2793 #define PARSE_FIELD_GENE_FIELD    4
2794 #define PARSE_FIELD_RNA_FIELD    5
2795 #define PARSE_FIELD_CDS_COMMENT   6
2796 #define PARSE_FIELD_PROTEIN_FIELD 7
2797 #define PARSE_FIELD_IMPORT_QUAL   8
2798 #define PARSE_FIELD_FEATURE_NOTE  9
2799 #define PARSE_FIELD_COMMENT_DESC  10
2800 #define PARSE_FIELD_DBXREF        11
2801 
2802 #define MAX_PARSE_FIELD_TYPE   11
2803 #define SEARCH_FIELD_PUBLICATION  12
2804 
2805 #define PARSE_FIELD_FIRST_FEATURE 4
2806 #define PARSE_FIELD_LAST_FEATURE  9
2807 
2808 extern Boolean DoesLocationMatchConstraint (SeqLocPtr slp, LocationConstraintXPtr lcp);
2809 
2810 typedef struct acceptpolicy
2811 {
2812   Boolean leave_dlg_up;
2813 } AcceptPolicyData, PNTR AcceptPolicyPtr;
2814 
2815 typedef struct acceptcanceldialog
2816 {
2817   DIALOG_MESSAGE_BLOCK
2818   Nlm_AcceptActnProc    accept_actn;
2819   Nlm_CancelActnProc    cancel_actn;
2820   Nlm_ClearActnProc     clear_actn;
2821   Nlm_ClearTextActnProc clear_text_actn;
2822   WindoW                w;
2823 
2824   ButtoN                accept_btn;
2825 
2826   ButtoN                leave_dlg_up_btn;
2827 } AcceptCancelDialogData, PNTR AcceptCancelDialogPtr;
2828 
AcceptCancelDialogAccept(ButtoN b)2829 static void AcceptCancelDialogAccept (ButtoN b)
2830 {
2831   AcceptCancelDialogPtr acdp;
2832 
2833   acdp = (AcceptCancelDialogPtr) GetObjectExtra (b);
2834   if (acdp == NULL) return;
2835 
2836   if (acdp->accept_actn != NULL)
2837   {
2838     if (!((acdp->accept_actn) (acdp->userdata)))
2839     {
2840       return;
2841     }
2842   }
2843   if (! GetStatus (acdp->leave_dlg_up_btn))
2844   {
2845     Remove (acdp->w);
2846   }
2847 }
2848 
AcceptCancelDialogCancel(ButtoN b)2849 static void AcceptCancelDialogCancel (ButtoN b)
2850 {
2851   AcceptCancelDialogPtr acdp;
2852 
2853   acdp = (AcceptCancelDialogPtr) GetObjectExtra (b);
2854   if (acdp == NULL) return;
2855 
2856   if (acdp->cancel_actn != NULL)
2857   {
2858     (acdp->cancel_actn) (acdp->userdata);
2859   }
2860   Remove (acdp->w);
2861 }
2862 
AcceptCancelDialogClear(ButtoN b)2863 static void AcceptCancelDialogClear (ButtoN b)
2864 {
2865   AcceptCancelDialogPtr acdp;
2866 
2867   acdp = (AcceptCancelDialogPtr) GetObjectExtra (b);
2868   if (acdp == NULL || acdp->clear_actn == NULL) return;
2869 
2870   (acdp->clear_actn) (acdp->userdata);
2871 }
2872 
AcceptCancelDialogClearText(ButtoN b)2873 static void AcceptCancelDialogClearText (ButtoN b)
2874 {
2875   AcceptCancelDialogPtr acdp;
2876 
2877   acdp = (AcceptCancelDialogPtr) GetObjectExtra (b);
2878   if (acdp == NULL || acdp->clear_text_actn == NULL) return;
2879 
2880   (acdp->clear_text_actn) (acdp->userdata);
2881 }
2882 
AcceptPolicyToAcceptCancelDialog(DialoG d,Pointer data)2883 static void AcceptPolicyToAcceptCancelDialog (DialoG d, Pointer data)
2884 
2885 {
2886   AcceptCancelDialogPtr   acdp;
2887   AcceptPolicyPtr         app;
2888 
2889   acdp = (AcceptCancelDialogPtr) GetObjectExtra (d);
2890   app = (AcceptPolicyPtr) data;
2891   if (acdp == NULL || app == NULL)
2892   {
2893     return;
2894   }
2895 
2896   SetStatus (acdp->leave_dlg_up_btn, app->leave_dlg_up);
2897 }
2898 
AcceptCancelDialogToAcceptPolicy(DialoG d)2899 static Pointer AcceptCancelDialogToAcceptPolicy (DialoG d)
2900 {
2901   AcceptCancelDialogPtr acdp;
2902   AcceptPolicyPtr       app;
2903 
2904   acdp = (AcceptCancelDialogPtr) GetObjectExtra (d);
2905   if (acdp == NULL)
2906   {
2907     return NULL;
2908   }
2909 
2910   app = (AcceptPolicyPtr) MemNew (sizeof (AcceptPolicyData));
2911   if (app != NULL)
2912   {
2913     app->leave_dlg_up = GetStatus (acdp->leave_dlg_up_btn);
2914   }
2915   return app;
2916 }
2917 
AcceptCancelMessage(DialoG d,Int2 mssg)2918 static void AcceptCancelMessage (DialoG d, Int2 mssg)
2919 
2920 {
2921   AcceptCancelDialogPtr acdp;
2922 
2923   acdp = (AcceptCancelDialogPtr) GetObjectExtra (d);
2924   if (acdp != NULL) {
2925     switch (mssg) {
2926       case VIB_MSG_INIT :
2927         /* reset accept policy */
2928         SetStatus (acdp->leave_dlg_up_btn, FALSE);
2929         break;
2930       case VIB_MSG_ENTER :
2931         Select (acdp->accept_btn);
2932         break;
2933       default :
2934         break;
2935     }
2936   }
2937 }
2938 
TestAcceptCancelDialog(DialoG d)2939 static ValNodePtr TestAcceptCancelDialog (DialoG d)
2940 
2941 {
2942   return NULL;
2943 }
2944 
AcceptCancelDialog(GrouP parent,Nlm_AcceptActnProc accept_actn,Nlm_CancelActnProc cancel_actn,Nlm_ClearActnProc clear_actn,Nlm_ClearTextActnProc clear_text_actn,Pointer userdata,WindoW w)2945 extern DialoG AcceptCancelDialog
2946 (GrouP                 parent,
2947  Nlm_AcceptActnProc    accept_actn,
2948  Nlm_CancelActnProc    cancel_actn,
2949  Nlm_ClearActnProc     clear_actn,
2950  Nlm_ClearTextActnProc clear_text_actn,
2951  Pointer               userdata,
2952  WindoW                w)
2953 {
2954   AcceptCancelDialogPtr acdp;
2955   GrouP                 grp, policy_grp = NULL, other_grp;
2956   ButtoN                b;
2957 
2958   acdp = (AcceptCancelDialogPtr) MemNew (sizeof (AcceptCancelDialogData));
2959   grp = HiddenGroup (parent, -1, 0, NULL);
2960   SetObjectExtra (grp, acdp, StdCleanupExtraProc);
2961   SetGroupSpacing (grp, 10, 10);
2962 
2963   acdp->dialog = (DialoG) grp;
2964   acdp->todialog = AcceptPolicyToAcceptCancelDialog;
2965   acdp->fromdialog = AcceptCancelDialogToAcceptPolicy;
2966   acdp->dialogmessage = AcceptCancelMessage;
2967   acdp->testdialog = TestAcceptCancelDialog;
2968 
2969   acdp->accept_actn             = accept_actn;
2970   acdp->cancel_actn             = cancel_actn;
2971   acdp->clear_actn              = clear_actn;
2972   acdp->clear_text_actn         = clear_text_actn;
2973   acdp->userdata                = userdata;
2974   acdp->w                       = w;
2975 
2976   policy_grp = HiddenGroup (grp, 3, 0, NULL);
2977   SetGroupSpacing (policy_grp, 10, 10);
2978 
2979   b = PushButton (policy_grp, "Clear", AcceptCancelDialogClear);
2980   SetObjectExtra (b, acdp, NULL);
2981 
2982   b = PushButton (policy_grp, "Clear Text", AcceptCancelDialogClearText);
2983   SetObjectExtra (b, acdp, NULL);
2984 
2985   acdp->leave_dlg_up_btn = CheckBox (policy_grp, "Leave Dialog Up", NULL);
2986 
2987   other_grp = HiddenGroup (grp, 5, 0, NULL);
2988   SetGroupSpacing (other_grp, 10, 10);
2989   acdp->accept_btn = PushButton (other_grp, "Accept", AcceptCancelDialogAccept);
2990   SetObjectExtra (acdp->accept_btn, acdp, NULL);
2991 
2992   b = PushButton (other_grp, "Cancel", AcceptCancelDialogCancel);
2993   SetObjectExtra (b, acdp, NULL);
2994 
2995   AlignObjects (ALIGN_CENTER, (HANDLE) policy_grp, (HANDLE) other_grp, NULL);
2996 
2997   return (DialoG) grp;
2998 }
2999 
3000 
EnableAcceptCancelDialogAccept(DialoG d)3001 extern void EnableAcceptCancelDialogAccept (DialoG d)
3002 {
3003   AcceptCancelDialogPtr acdp;
3004 
3005   acdp = (AcceptCancelDialogPtr) GetObjectExtra (d);
3006 
3007   if (acdp == NULL) return;
3008 
3009   InvalObject (acdp->accept_btn);
3010   SafeEnable (acdp->accept_btn);
3011   Update ();
3012 }
3013 
DisableAcceptCancelDialogAccept(DialoG d)3014 extern void DisableAcceptCancelDialogAccept (DialoG d)
3015 {
3016   AcceptCancelDialogPtr acdp;
3017 
3018   acdp = (AcceptCancelDialogPtr) GetObjectExtra (d);
3019 
3020   if (acdp == NULL) return;
3021 
3022   InvalObject (acdp->accept_btn);
3023   SafeDisable (acdp->accept_btn);
3024   Update ();
3025 }
3026 
3027 
3028 
3029 
3030 
ValNodeAppend(ValNodePtr list,ValNodePtr second_list)3031 static ValNodePtr ValNodeAppend (ValNodePtr list, ValNodePtr second_list)
3032 {
3033   ValNodePtr last_vnp;
3034 
3035   if (list == NULL)
3036   {
3037     list = second_list;
3038   }
3039   else if (second_list != NULL)
3040   {
3041     last_vnp = list;
3042     while (last_vnp != NULL && last_vnp->next != NULL)
3043     {
3044       last_vnp = last_vnp->next;
3045     }
3046     last_vnp->next = second_list;
3047   }
3048   return list;
3049 }
3050 
FindFeatureTypeCallback(SeqFeatPtr sfp,Pointer userdata)3051 static void FindFeatureTypeCallback (SeqFeatPtr sfp, Pointer userdata)
3052 {
3053   BoolPtr type_list;
3054 
3055   if (sfp == NULL || userdata == NULL) return;
3056 
3057   type_list = (BoolPtr) userdata;
3058   type_list[sfp->idx.subtype] = TRUE;
3059 }
3060 
3061 
AddFeatureToList(ValNodePtr PNTR list,FeatDefPtr curr)3062 static void AddFeatureToList (ValNodePtr PNTR list, FeatDefPtr curr)
3063 {
3064   Char        str [256];
3065 
3066   if (list == NULL || curr == NULL) return;
3067 
3068   if (curr->featdef_key == FEATDEF_PUB)
3069   {
3070     StringNCpy_0 (str, curr->typelabel, sizeof (str) - 15);
3071     StringCat (str, " (Publication)");
3072     ValNodeAddPointer (list, curr->featdef_key, StringSave (str));
3073   }
3074   else if (curr->featdef_key == FEATDEF_BIOSRC)
3075   {
3076     ValNodeAddPointer (list, FEATDEF_BIOSRC, StringSave ("BioSource"));
3077   }
3078   else if (curr->featdef_key == FEATDEF_otherRNA)
3079   {
3080     ValNodeAddPointer (list, FEATDEF_otherRNA, StringSave ("misc_RNA"));
3081   }
3082   else if (curr->featdef_key == FEATDEF_misc_RNA ||
3083            curr->featdef_key == FEATDEF_precursor_RNA ||
3084            curr->featdef_key == FEATDEF_mat_peptide ||
3085            curr->featdef_key == FEATDEF_sig_peptide ||
3086            curr->featdef_key == FEATDEF_transit_peptide ||
3087            curr->featdef_key == FEATDEF_Imp_CDS)
3088   {
3089     StringNCpy_0 (str, curr->typelabel, sizeof (str) - 10);
3090     StringCat (str, "_imp");
3091     ValNodeAddPointer (list, curr->featdef_key, StringSave (str));
3092   }
3093   else
3094   {
3095     ValNodeAddPointer (list, curr->featdef_key, StringSave (curr->typelabel));
3096   }
3097 }
3098 
BuildFeatureDialogList(Boolean list_most_used_first,SeqEntryPtr sep)3099 extern ValNodePtr BuildFeatureDialogList (Boolean list_most_used_first, SeqEntryPtr sep)
3100 {
3101   ValNodePtr  feature_choice_list = NULL;
3102   ValNodePtr  import_feature_list = NULL;
3103   ValNodePtr  least_liked_feature_list = NULL;
3104   ValNodePtr  most_used_feature_list = NULL;
3105   ValNodePtr  unused_list = NULL;
3106   FeatDefPtr  curr;
3107   Uint1       key;
3108   CharPtr     label = NULL;
3109   Boolean     feature_type_list[256];
3110   Boolean     only_most_used = TRUE;
3111   Int4        i;
3112 
3113   if (sep == NULL) {
3114       for (i = 0; i < 255; i++) {
3115           feature_type_list[i] = TRUE;
3116       }
3117   } else {
3118       for (i = 0; i < 255; i++) {
3119           feature_type_list[i] = FALSE;
3120       }
3121       VisitFeaturesInSep (sep, feature_type_list, FindFeatureTypeCallback);
3122   }
3123 
3124   curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
3125   while (curr != NULL) {
3126     if (key == FEATDEF_BAD
3127         || key == FEATDEF_Imp_CDS
3128         || key == FEATDEF_source
3129         || key == FEATDEF_ORG
3130         || IsUnwantedFeatureType (key)
3131         || IsRegulatorySubtype (key))
3132     {
3133       curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
3134       continue;
3135     }
3136     else if (!feature_type_list[key])
3137     {
3138       AddFeatureToList (&unused_list, curr);
3139       curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
3140       continue;
3141     }
3142 
3143     if (curr->featdef_key == FEATDEF_otherRNA) {
3144       AddFeatureToList (&feature_choice_list, curr);
3145       if (list_most_used_first) {
3146         AddFeatureToList (&most_used_feature_list, curr);
3147       }
3148     }
3149     else if (curr->featdef_key == FEATDEF_misc_RNA ||
3150             curr->featdef_key == FEATDEF_precursor_RNA ||
3151             curr->featdef_key == FEATDEF_mat_peptide ||
3152             curr->featdef_key == FEATDEF_sig_peptide ||
3153             curr->featdef_key == FEATDEF_transit_peptide ||
3154             curr->featdef_key == FEATDEF_Imp_CDS)
3155     {
3156       AddFeatureToList (&import_feature_list, curr);
3157     }
3158     else if (curr->featdef_key == FEATDEF_TXINIT)
3159     {
3160       AddFeatureToList (&least_liked_feature_list, curr);
3161     }
3162     else
3163     {
3164       ValNodeAddPointer (&feature_choice_list, curr->featdef_key, StringSave (curr->typelabel));
3165     }
3166 
3167     if (list_most_used_first)
3168     {
3169       /* also build most used list */
3170       if (curr->featdef_key == FEATDEF_CDS
3171           || curr->featdef_key == FEATDEF_exon
3172           || curr->featdef_key == FEATDEF_GENE
3173           || curr->featdef_key == FEATDEF_intron
3174           || curr->featdef_key == FEATDEF_mRNA
3175           || curr->featdef_key == FEATDEF_rRNA
3176           || curr->featdef_key == FEATDEF_PROT)
3177       {
3178         ValNodeAddPointer (&most_used_feature_list, curr->featdef_key,
3179                            StringSave (curr->typelabel));
3180       }
3181       else
3182       {
3183         only_most_used = FALSE;
3184       }
3185     }
3186 
3187     curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
3188   }
3189 
3190   most_used_feature_list = SortValNode (most_used_feature_list,
3191                                         CompareFeatureValNodeStrings);
3192   feature_choice_list = SortValNode (feature_choice_list,
3193                                      CompareFeatureValNodeStrings);
3194   import_feature_list = SortValNode (import_feature_list,
3195                                      CompareFeatureValNodeStrings);
3196   least_liked_feature_list = SortValNode (least_liked_feature_list,
3197                                           CompareFeatureValNodeStrings);
3198   unused_list = SortValNode (unused_list, CompareFeatureValNodeStrings);
3199 
3200   if (most_used_feature_list != NULL && only_most_used) {
3201     feature_choice_list = ValNodeFreeData (feature_choice_list);
3202     feature_choice_list = most_used_feature_list;
3203     least_liked_feature_list = ValNodeFreeData(least_liked_feature_list);
3204     import_feature_list = ValNodeFreeData(least_liked_feature_list);
3205   } else {
3206     feature_choice_list = ValNodeAppend (most_used_feature_list, feature_choice_list);
3207     feature_choice_list = ValNodeAppend (feature_choice_list, least_liked_feature_list);
3208     feature_choice_list = ValNodeAppend (feature_choice_list, import_feature_list);
3209   }
3210   feature_choice_list = ValNodeAppend (feature_choice_list, unused_list);
3211 
3212   return feature_choice_list;
3213 }
3214 
BuildImportList(void)3215 static ValNodePtr BuildImportList (void)
3216 {
3217   ValNodePtr  import_feature_list = NULL;
3218   FeatDefPtr  curr;
3219   Uint1       key;
3220   CharPtr     label = NULL;
3221   Char        str [256];
3222 
3223   curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
3224   while (curr != NULL) {
3225     if (FindFeatFromFeatDefType (key) == SEQFEAT_IMP && !IsUnwantedFeatureType(key))
3226     {
3227       ValNodeAddPointer (&import_feature_list, curr->featdef_key, StringSave (str));
3228     }
3229 
3230     curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
3231   }
3232   return import_feature_list;
3233 }
3234 
RemoveFeatureSelectionDuplicates(ValNodePtr orig_list)3235 static void RemoveFeatureSelectionDuplicates (ValNodePtr orig_list)
3236 {
3237   ValNodePtr vnp1, vnp2, prev_vnp, next_vnp;
3238 
3239   if (orig_list == NULL || orig_list->next == NULL)
3240   {
3241     return;
3242   }
3243 
3244   vnp1 = orig_list;
3245   while (vnp1 != NULL && vnp1->next != NULL)
3246   {
3247     vnp2 = vnp1->next;
3248     prev_vnp = vnp1;
3249     while (vnp2 != NULL)
3250     {
3251       next_vnp = vnp2->next;
3252       if (vnp2->choice == vnp1->choice)
3253       {
3254         prev_vnp->next = next_vnp;
3255         vnp2->next = NULL;
3256         vnp2 = ValNodeFreeData (vnp2);
3257       }
3258       else
3259       {
3260         prev_vnp = vnp2;
3261       }
3262       vnp2 = next_vnp;
3263     }
3264     vnp1 = vnp1->next;
3265   }
3266 }
3267 
FeatureSelectionRemap(ValNodePtr orig_list)3268 static ValNodePtr FeatureSelectionRemap (ValNodePtr orig_list)
3269 {
3270   ValNodePtr vnp, vnp_next, prev_vnp, repl_vnp = NULL;
3271 
3272   if (orig_list == NULL)
3273   {
3274     return NULL;
3275   }
3276 
3277   vnp = orig_list;
3278   prev_vnp = NULL;
3279   while (vnp != NULL && repl_vnp == NULL)
3280   {
3281     vnp_next = vnp->next;
3282     /* replace FEATDEF_IMP with list of import features */
3283     if (vnp->choice == FEATDEF_IMP)
3284     {
3285       /* build replacement list */
3286       repl_vnp = BuildImportList ();
3287 
3288       ValNodeLink (&repl_vnp, vnp->next);
3289 
3290       if (prev_vnp == NULL)
3291       {
3292         orig_list = repl_vnp;
3293       }
3294       else
3295       {
3296         prev_vnp->next = repl_vnp;
3297       }
3298 
3299       vnp->next = NULL;
3300       ValNodeFreeData (vnp);
3301     }
3302     else
3303     {
3304       prev_vnp = vnp;
3305     }
3306     vnp = vnp_next;
3307   }
3308 
3309   RemoveFeatureSelectionDuplicates (orig_list);
3310 
3311   return orig_list;
3312 }
3313 
3314 extern DialoG
FeatureSelectionDialogEx(GrouP h,Boolean allow_multi,SeqEntryPtr sep,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)3315 FeatureSelectionDialogEx
3316 (GrouP                    h,
3317  Boolean                  allow_multi,
3318  SeqEntryPtr              sep,
3319  Nlm_ChangeNotifyProc     change_notify,
3320  Pointer                  change_userdata)
3321 {
3322   DialoG      dlg;
3323   ValNodePtr  feature_choice_list, vnp, vnp_next, vnp_prev;
3324   Boolean     found_import = FALSE;
3325 
3326   feature_choice_list = BuildFeatureDialogList (TRUE, sep);
3327 
3328   if (!allow_multi)
3329   {
3330     /* remove Import option */
3331     vnp_prev = NULL;
3332     for (vnp = feature_choice_list; vnp != NULL && !found_import; vnp = vnp_next)
3333     {
3334       vnp_next = vnp->next;
3335       if (vnp->choice == FEATDEF_IMP)
3336       {
3337         if (vnp_prev == NULL)
3338         {
3339           feature_choice_list = vnp_next;
3340         }
3341         else
3342         {
3343           vnp_prev->next = vnp_next;
3344         }
3345         vnp->next = NULL;
3346         vnp = ValNodeFreeData (vnp);
3347         found_import = TRUE;
3348       }
3349       else
3350       {
3351         vnp_prev = vnp;
3352       }
3353     }
3354   }
3355 
3356   /* note - the ValNodeSelectionDialog will free the feature_choice_list when done */
3357 
3358   dlg = ValNodeSelectionDialogEx (h, feature_choice_list, TALL_SELECTION_LIST,
3359                                 ValNodeStringName,
3360                                 ValNodeSimpleDataFree, ValNodeStringCopy,
3361                                 ValNodeChoiceMatch, "feature list",
3362                                 change_notify, change_userdata, allow_multi, FALSE,
3363                                 allow_multi ? FeatureSelectionRemap : NULL);
3364   return dlg;
3365 }
3366 
3367 extern DialoG
FeatureSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)3368 FeatureSelectionDialog
3369 (GrouP                    h,
3370  Boolean                  allow_multi,
3371  Nlm_ChangeNotifyProc     change_notify,
3372  Pointer                  change_userdata)
3373 {
3374   return FeatureSelectionDialogEx(h, allow_multi, NULL, change_notify, change_userdata);
3375 }
3376 
3377 extern DialoG
DescriptorSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)3378 DescriptorSelectionDialog
3379 (GrouP                    h,
3380  Boolean                  allow_multi,
3381  Nlm_ChangeNotifyProc     change_notify,
3382  Pointer                  change_userdata)
3383 {
3384   ValNodePtr descriptor_list = BuildDescriptorValNodeList ();
3385   return ValNodeSelectionDialogEx (h, descriptor_list, TALL_SELECTION_LIST,
3386                                 ValNodeStringName,
3387                                 ValNodeSimpleDataFree, ValNodeStringCopy,
3388                                 ValNodeChoiceMatch, "descriptor list",
3389                                 change_notify, change_userdata, allow_multi, FALSE,
3390                                 NULL);
3391 }
3392 
3393 
SourceQualValNodeName(ValNodePtr vnp)3394 extern CharPtr SourceQualValNodeName (ValNodePtr vnp)
3395 {
3396   SourceQualDescPtr           sqdp;
3397 
3398   if (vnp == NULL || vnp->data.ptrvalue == NULL)
3399   {
3400     return NULL;
3401   }
3402   else if (vnp->choice == 0)
3403   {
3404     sqdp = (SourceQualDescPtr) vnp->data.ptrvalue;
3405     return StringSave (sqdp->name);
3406   }
3407   else
3408   {
3409     return StringSave (vnp->data.ptrvalue);
3410   }
3411 }
3412 
SourceQualValNodeDataCopy(ValNodePtr vnp)3413 extern ValNodePtr SourceQualValNodeDataCopy (ValNodePtr vnp)
3414 {
3415   SourceQualDescPtr           sqdp, new_sqdp = NULL;
3416   ValNodePtr                  vnp_copy = NULL;
3417 
3418   if (vnp != NULL && vnp->data.ptrvalue != NULL)
3419   {
3420     if (vnp->choice == 0)
3421     {
3422       sqdp = (SourceQualDescPtr) vnp->data.ptrvalue;
3423       new_sqdp = (SourceQualDescPtr) MemNew (sizeof (SourceQualDescData));
3424       if (new_sqdp != NULL)
3425       {
3426         MemCpy (new_sqdp, sqdp, sizeof (SourceQualDescData));
3427       }
3428       ValNodeAddPointer (&vnp_copy, vnp->choice, new_sqdp);
3429     }
3430     else
3431     {
3432       ValNodeAddPointer (&vnp_copy, vnp->choice, StringSave (vnp->data.ptrvalue));
3433     }
3434   }
3435   return vnp_copy;
3436 }
3437 
3438 
SourceQualValNodeCopy(ValNodePtr vnp)3439 NLM_EXTERN ValNodePtr LIBCALL SourceQualValNodeCopy (ValNodePtr vnp)
3440 {
3441   return SourceQualValNodeDataCopy(vnp);
3442 }
3443 
3444 
SourceQualValNodeMatch(ValNodePtr vnp1,ValNodePtr vnp2)3445 extern Boolean SourceQualValNodeMatch (ValNodePtr vnp1, ValNodePtr vnp2)
3446 {
3447   SourceQualDescPtr  sqdp1, sqdp2;
3448   Boolean            rval = FALSE;
3449 
3450   if (vnp1 == NULL || vnp2 == NULL
3451       || vnp1->data.ptrvalue == NULL || vnp2->data.ptrvalue == NULL)
3452   {
3453     rval = FALSE;
3454   }
3455   else if (vnp1->choice != vnp2->choice)
3456   {
3457     rval = FALSE;
3458   }
3459   else if (vnp1->choice == 0)
3460   {
3461     sqdp1 = (SourceQualDescPtr) vnp1->data.ptrvalue;
3462     sqdp2 = (SourceQualDescPtr) vnp2->data.ptrvalue;
3463 
3464     if (sqdp1->subtype == sqdp2->subtype
3465         && ((sqdp1->isOrgMod && sqdp2->isOrgMod)
3466             || (!sqdp1->isOrgMod && ! sqdp2->isOrgMod)))
3467     {
3468       rval = TRUE;
3469     }
3470     else
3471     {
3472       rval = FALSE;
3473     }
3474   }
3475   else
3476   {
3477     if (StringCmp (vnp1->data.ptrvalue, vnp2->data.ptrvalue) == 0)
3478     {
3479       rval = TRUE;
3480     }
3481     else
3482     {
3483       rval = FALSE;
3484     }
3485   }
3486   return rval;
3487 }
3488 
SourceQualTypeSelectionDialogEx(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Int2 list_height,Boolean show_discouraged,Boolean show_discontinued)3489 static DialoG SourceQualTypeSelectionDialogEx
3490 (GrouP h,
3491  Boolean                  allow_multi,
3492  Nlm_ChangeNotifyProc     change_notify,
3493  Pointer                  change_userdata,
3494  Int2                     list_height,
3495  Boolean                  show_discouraged,
3496  Boolean                  show_discontinued)
3497 
3498 {
3499   DialoG     dlg;
3500   ValNodePtr qual_choice_list;
3501 
3502   if (allow_multi)
3503   {
3504     qual_choice_list = ValNodeNew (NULL);
3505     qual_choice_list->choice = 1;
3506     qual_choice_list->data.ptrvalue = StringSave ("All Notes");
3507     qual_choice_list->next = GetSourceQualDescList (TRUE, TRUE, show_discouraged, show_discontinued);
3508   }
3509   else
3510   {
3511     qual_choice_list = GetSourceQualDescList (TRUE, TRUE, show_discouraged, show_discontinued);
3512   }
3513   /* note - the ValNodeSelectionDialog will free the qual_choice_list when done */
3514   dlg = ValNodeSelectionDialog (h, qual_choice_list, list_height, SourceQualValNodeName,
3515                                 ValNodeSimpleDataFree, SourceQualValNodeDataCopy,
3516                                 SourceQualValNodeMatch, "feature list",
3517                                 change_notify, change_userdata, allow_multi);
3518 
3519   return dlg;
3520 }
3521 
SourceQualTypeSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)3522 extern DialoG SourceQualTypeSelectionDialog
3523 (GrouP h,
3524  Boolean                  allow_multi,
3525  Nlm_ChangeNotifyProc     change_notify,
3526  Pointer                  change_userdata)
3527 
3528 {
3529   return SourceQualTypeSelectionDialogEx (h, allow_multi, change_notify,
3530                                           change_userdata, 6, FALSE, FALSE);
3531 }
3532 
SourceQualTypeDiscSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)3533 static DialoG SourceQualTypeDiscSelectionDialog
3534 (GrouP h,
3535  Boolean                  allow_multi,
3536  Nlm_ChangeNotifyProc     change_notify,
3537  Pointer                  change_userdata)
3538 
3539 {
3540   return SourceQualTypeSelectionDialogEx (h, allow_multi, change_notify,
3541                                           change_userdata, 6, TRUE, TRUE);
3542 }
3543 
SourceQualTypeConstraintSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)3544 static DialoG SourceQualTypeConstraintSelectionDialog
3545 (GrouP h,
3546  Boolean                  allow_multi,
3547  Nlm_ChangeNotifyProc     change_notify,
3548  Pointer                  change_userdata)
3549 
3550 {
3551   return SourceQualTypeSelectionDialogEx (h, allow_multi, change_notify,
3552                                           change_userdata, 4, TRUE, FALSE);
3553 }
3554 
SourceStringConstraintSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)3555 static DialoG SourceStringConstraintSelectionDialog
3556 (GrouP h,
3557  Boolean                  allow_multi,
3558  Nlm_ChangeNotifyProc     change_notify,
3559  Pointer                  change_userdata)
3560 
3561 {
3562   DialoG     dlg;
3563   ValNodePtr qual_choice_list = NULL;
3564 
3565   /* ignore allow_multi */
3566 
3567   ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Organism or Any Qual"));
3568   ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Organism"));
3569   qual_choice_list->next->next = GetSourceQualDescList (TRUE, TRUE, TRUE, FALSE);
3570   ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Lineage"));
3571   ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Location"));
3572 
3573   /* note - the ValNodeSelectionDialog will free the qual_choice_list when done */
3574   dlg = ValNodeSelectionDialog (h, qual_choice_list, 4, SourceQualValNodeName,
3575                                 ValNodeSimpleDataFree, SourceQualValNodeDataCopy,
3576                                 SourceQualValNodeMatch, "feature list",
3577                                 change_notify, change_userdata, FALSE);
3578 
3579   return dlg;
3580 }
3581 
OrgModSpecialMatch(OrgModPtr mod,FilterSetPtr fsp)3582 static Boolean OrgModSpecialMatch (OrgModPtr mod, FilterSetPtr fsp)
3583 {
3584   SourceQualDescPtr sqdp;
3585 
3586   if (mod == NULL)
3587   {
3588     return FALSE;
3589   }
3590   if (fsp == NULL
3591       || fsp->ccp == NULL
3592       || fsp->ccp->constraint_type != CHOICE_CONSTRAINT_STRING
3593       || fsp->ccp->string_constraint == NULL
3594       || fsp->ccp->qual_choice == NULL
3595       || fsp->ccp->qual_choice->data.ptrvalue == NULL)
3596   {
3597     return TRUE;
3598   }
3599 
3600   sqdp = (SourceQualDescPtr) fsp->ccp->qual_choice->data.ptrvalue;
3601   if (sqdp->subtype != mod->subtype)
3602   {
3603     return TRUE;
3604   }
3605 
3606   if (DoesStringMatchConstraintX (mod->subname, fsp->ccp->string_constraint))
3607   {
3608     if (fsp->ccp->string_constraint->not_present)
3609     {
3610       return FALSE;
3611     }
3612     else
3613     {
3614       return TRUE;
3615     }
3616   }
3617   else
3618   {
3619     if (fsp->ccp->string_constraint->not_present)
3620     {
3621       return TRUE;
3622     }
3623     else
3624     {
3625       return FALSE;
3626     }
3627   }
3628 }
3629 
SubSrcSpecialMatch(SubSourcePtr ssp,FilterSetPtr fsp)3630 static Boolean SubSrcSpecialMatch (SubSourcePtr ssp, FilterSetPtr fsp)
3631 {
3632   SourceQualDescPtr sqdp;
3633 
3634   if (ssp == NULL)
3635   {
3636     return FALSE;
3637   }
3638   if (fsp == NULL
3639       || fsp->ccp == NULL
3640       || fsp->ccp->constraint_type != CHOICE_CONSTRAINT_STRING
3641       || fsp->ccp->string_constraint == NULL
3642       || fsp->ccp->qual_choice == NULL
3643       || fsp->ccp->qual_choice->data.ptrvalue == NULL)
3644   {
3645     return TRUE;
3646   }
3647 
3648   sqdp = (SourceQualDescPtr) fsp->ccp->qual_choice->data.ptrvalue;
3649   if (sqdp->subtype != ssp->subtype)
3650   {
3651     return TRUE;
3652   }
3653   if (DoesStringMatchConstraintX (ssp->name, fsp->ccp->string_constraint))
3654   {
3655     if (fsp->ccp->string_constraint->not_present)
3656     {
3657       return FALSE;
3658     }
3659     else
3660     {
3661       return TRUE;
3662     }
3663   }
3664   else
3665   {
3666     if (fsp->ccp->string_constraint->not_present)
3667     {
3668       return TRUE;
3669     }
3670     else
3671     {
3672       return FALSE;
3673     }
3674   }
3675 }
3676 
3677 
GetSubfield(CharPtr str,Uint1 subfield)3678 static CharPtr GetSubfield (CharPtr str, Uint1 subfield)
3679 {
3680   CharPtr cp, cp2;
3681   Int4    num_colons = 0;
3682   CharPtr new_val = NULL;
3683 
3684   if (StringHasNoText (str)) {
3685     return NULL;
3686   }
3687 
3688   cp = StringChr (str, ':');
3689   while (cp != NULL) {
3690     num_colons ++;
3691     cp = StringChr (cp + 1, ':');
3692   }
3693 
3694   if (subfield == 0) {
3695     new_val = StringSave (str);
3696   } else if (subfield == 1) {
3697     if (num_colons == 0) {
3698       return NULL;
3699     } else {
3700       cp = StringChr (str, ':');
3701       new_val = (CharPtr) MemNew (sizeof (Char) * (cp - str + 1));
3702       StringNCpy (new_val, str, cp - str);
3703       new_val[cp - str] = 0;
3704     }
3705   } else if (subfield == 2) {
3706     if (num_colons == 0 || num_colons == 1) {
3707       return NULL;
3708     } else {
3709       cp = StringChr (str, ':');
3710       cp2 = StringChr (cp + 1, ':');
3711       new_val = (CharPtr) MemNew (sizeof (Char) * (cp2 - cp));
3712       StringNCpy (new_val, cp + 1, cp2 - cp - 1);
3713       new_val[cp2 - cp - 1] = 0;
3714     }
3715   } else {
3716     if (num_colons == 0) {
3717       new_val = StringSave (str);
3718     } else {
3719       cp = StringRChr (str, ':');
3720       new_val = StringSave (cp + 1);
3721     }
3722   }
3723   return new_val;
3724 }
3725 
3726 
3727 static CharPtr
GetSourceQualQualValueFromBiop(BioSourcePtr biop,SourceQualDescPtr sqdp,FilterSetPtr fsp)3728 GetSourceQualQualValueFromBiop
3729 (BioSourcePtr      biop,
3730  SourceQualDescPtr sqdp,
3731  FilterSetPtr      fsp)
3732 {
3733   CharPtr            str = NULL, field, tmp_str;
3734   OrgModPtr          mod;
3735   SubSourcePtr       ssp;
3736 
3737   if (biop == NULL || sqdp == NULL)
3738   {
3739     return NULL;
3740   }
3741 
3742   if (sqdp->isOrgMod)
3743   {
3744     if (biop->org != NULL && biop->org->orgname != NULL)
3745     {
3746       mod = biop->org->orgname->mod;
3747       while (mod != NULL)
3748       {
3749         if (mod->subtype == sqdp->subtype
3750             && !StringHasNoText (mod->subname)
3751             && OrgModSpecialMatch (mod, fsp))
3752         {
3753           field = GetSubfield (mod->subname, sqdp->subfield);
3754           if (!StringHasNoText (field)) {
3755             if (str == NULL) {
3756               str = field;
3757             } else {
3758               tmp_str = (CharPtr) MemNew ((StringLen (str) + StringLen (field) + 3) * sizeof (Char));
3759               StringCpy (tmp_str, str);
3760               StringCat (tmp_str, "; ");
3761               StringCat (tmp_str, field);
3762               field = MemFree (field);
3763               str = MemFree (str);
3764               str = tmp_str;
3765             }
3766           } else {
3767             field = MemFree (field);
3768           }
3769         }
3770         mod = mod->next;
3771       }
3772     }
3773   }
3774   else
3775   {
3776     ssp = biop->subtype;
3777     while (ssp != NULL)
3778     {
3779       if (ssp->subtype == sqdp->subtype
3780           && !StringHasNoText (ssp->name)
3781           && SubSrcSpecialMatch (ssp, fsp))
3782       {
3783         field = GetSubfield (ssp->name, sqdp->subfield);
3784         if (!StringHasNoText (field)) {
3785           if (str == NULL) {
3786             str = field;
3787           } else {
3788             tmp_str = (CharPtr) MemNew ((StringLen (str) + StringLen (field) + 3) * sizeof (Char));
3789             StringCpy (tmp_str, str);
3790             StringCat (tmp_str, "; ");
3791             StringCat (tmp_str, field);
3792             field = MemFree (field);
3793             str = MemFree (str);
3794             str = tmp_str;
3795           }
3796         } else {
3797           field = MemFree (field);
3798         }
3799       }
3800       ssp = ssp->next;
3801     }
3802   }
3803   return str;
3804 }
3805 
GetLocationFromSource(BioSourcePtr biop,ValNodePtr vnp)3806 static CharPtr GetLocationFromSource (BioSourcePtr biop, ValNodePtr vnp)
3807 {
3808   Nlm_EnumFieldAssocPtr eap;
3809 
3810   if (biop == NULL)
3811   {
3812     return NULL;
3813   }
3814 
3815   for (eap = biosource_genome_alistX;
3816        eap->name != NULL && eap->value != biop->genome;
3817        eap++)
3818   {
3819   }
3820 
3821   if (eap != NULL && eap->name != NULL && !StringHasNoText (eap->name))
3822   {
3823     return StringSave (eap->name);
3824   }
3825   else
3826   {
3827     return NULL;
3828   }
3829 }
3830 
GetLocationFromSourceFeature(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)3831 static CharPtr GetLocationFromSourceFeature (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
3832 {
3833   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
3834   {
3835     return GetLocationFromSource (sfp->data.value.ptrvalue, vnp);
3836   }
3837   else
3838   {
3839     return NULL;
3840   }
3841 }
3842 
3843 static CharPtr
GetLocationFromSourceDescriptor(SeqDescrPtr sdp,ValNodePtr vnp,FilterSetPtr fsp)3844 GetLocationFromSourceDescriptor
3845 (SeqDescrPtr  sdp,
3846  ValNodePtr   vnp,
3847  FilterSetPtr fsp)
3848 {
3849   if (sdp != NULL && sdp->choice == Seq_descr_source)
3850   {
3851     return GetLocationFromSource (sdp->data.ptrvalue, vnp);
3852   }
3853   else
3854   {
3855     return NULL;
3856   }
3857 }
3858 
GetOriginFromSource(BioSourcePtr biop,ValNodePtr vnp)3859 static CharPtr GetOriginFromSource (BioSourcePtr biop, ValNodePtr vnp)
3860 {
3861   Nlm_EnumFieldAssocPtr eap;
3862 
3863   if (biop == NULL)
3864   {
3865     return NULL;
3866   }
3867 
3868   for (eap = origin_alist;
3869        eap->name != NULL && eap->value != biop->origin;
3870        eap++)
3871   {
3872   }
3873 
3874   if (eap != NULL && eap->name != NULL && !StringHasNoText (eap->name))
3875   {
3876     return StringSave (eap->name);
3877   }
3878   else
3879   {
3880     return NULL;
3881   }
3882 }
3883 
3884 static CharPtr
GetOriginFromSourceFeature(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)3885 GetOriginFromSourceFeature
3886 (SeqFeatPtr   sfp,
3887  ValNodePtr   vnp,
3888  FilterSetPtr fsp)
3889 {
3890   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
3891   {
3892     return GetOriginFromSource (sfp->data.value.ptrvalue, vnp);
3893   }
3894   else
3895   {
3896     return NULL;
3897   }
3898 }
3899 
3900 static CharPtr
GetOriginFromSourceDescriptor(SeqDescrPtr sdp,ValNodePtr vnp,FilterSetPtr fsp)3901 GetOriginFromSourceDescriptor
3902 (SeqDescrPtr  sdp,
3903  ValNodePtr   vnp,
3904  FilterSetPtr fsp)
3905 {
3906   if (sdp != NULL && sdp->choice == Seq_descr_source)
3907   {
3908     return GetOriginFromSource (sdp->data.ptrvalue, vnp);
3909   }
3910   else
3911   {
3912     return NULL;
3913   }
3914 }
3915 
GetStringFromSource(BioSourcePtr biop,ValNodePtr vnp)3916 static CharPtr GetStringFromSource (BioSourcePtr biop, ValNodePtr vnp)
3917 {
3918   Nlm_EnumFieldAssocPtr eap;
3919 
3920   if (biop == NULL)
3921   {
3922     return NULL;
3923   }
3924 
3925   for (eap = orgref_textfield_alist;
3926        eap->name != NULL && StringCmp (vnp->data.ptrvalue, eap->name) != 0;
3927        eap++)
3928   {
3929   }
3930 
3931   if (eap != NULL && eap->name != NULL)
3932   {
3933     switch (eap->value)
3934     {
3935       case 1:
3936         if (biop->org != NULL && !StringHasNoText (biop->org->taxname))
3937         {
3938           return StringSave (biop->org->taxname);
3939         }
3940         break;
3941       case 2:
3942         if (biop->org != NULL && !StringHasNoText (biop->org->common))
3943         {
3944           return StringSave (biop->org->common);
3945         }
3946         break;
3947       case 3:
3948         if (biop->org != NULL && biop->org->orgname != NULL
3949             && !StringHasNoText (biop->org->orgname->lineage))
3950         {
3951           return StringSave (biop->org->orgname->lineage);
3952         }
3953         break;
3954       case 4:
3955         if (biop->org != NULL && biop->org->orgname != NULL
3956             && !StringHasNoText (biop->org->orgname->div))
3957         {
3958           return StringSave (biop->org->orgname->div);
3959         }
3960         break;
3961     }
3962   }
3963   return NULL;
3964 }
3965 
GetStringFromSourceFeature(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)3966 static CharPtr GetStringFromSourceFeature (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
3967 {
3968   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
3969   {
3970     return GetStringFromSource (sfp->data.value.ptrvalue, vnp);
3971   }
3972   else
3973   {
3974     return NULL;
3975   }
3976 }
3977 
StringAppend(CharPtr str1,CharPtr str2)3978 static CharPtr StringAppend (CharPtr str1, CharPtr str2)
3979 {
3980   CharPtr new_str;
3981 
3982   if (str1 == NULL && str2 == NULL)
3983   {
3984     return NULL;
3985   }
3986   else if (str1 == NULL)
3987   {
3988     return StringSave (str2);
3989   }
3990   else if (str2 == NULL)
3991   {
3992     return StringSave (str1);
3993   }
3994   else
3995   {
3996     new_str = (CharPtr) MemNew ((StringLen (str1) + StringLen (str2) + 3) * sizeof (Char));
3997     if (new_str != NULL)
3998     {
3999       sprintf (new_str, "%s; %s", str1, str2);
4000     }
4001     return new_str;
4002   }
4003 }
4004 
GetStringFromSourceDescriptor(SeqDescrPtr sdp,ValNodePtr vnp,FilterSetPtr fsp)4005 static CharPtr GetStringFromSourceDescriptor (SeqDescrPtr sdp, ValNodePtr vnp, FilterSetPtr fsp)
4006 {
4007   if (sdp != NULL && sdp->choice == Seq_descr_source)
4008   {
4009     return GetStringFromSource (sdp->data.ptrvalue, vnp);
4010   }
4011   else
4012   {
4013     return NULL;
4014   }
4015 }
4016 
4017 static CharPtr
GetSourceQualStringFromBioSource(BioSourcePtr biop,ValNodePtr vnp,FilterSetPtr fsp)4018 GetSourceQualStringFromBioSource
4019 (BioSourcePtr biop,
4020  ValNodePtr   vnp,
4021  FilterSetPtr fsp)
4022 {
4023   CharPtr            str = NULL, str1 = NULL, str2 = NULL;
4024   SourceQualDescData sqdd;
4025 
4026   if (biop == NULL || vnp == NULL)
4027   {
4028     return NULL;
4029   }
4030 
4031   while (vnp != NULL && str == NULL)
4032   {
4033     if (vnp->choice == 0)
4034     {
4035       str = GetSourceQualQualValueFromBiop (biop, vnp->data.ptrvalue, fsp);
4036     }
4037     else if (vnp->choice == 1)
4038     {
4039       if (StringCmp (vnp->data.ptrvalue, "Location") == 0)
4040       {
4041         str = GetLocationFromSource (biop, vnp);
4042       }
4043       else if (StringCmp (vnp->data.ptrvalue, "Origin") == 0)
4044       {
4045         str = GetOriginFromSource (biop, vnp);
4046       }
4047       else if (StringCmp (vnp->data.ptrvalue, "All Notes") == 0)
4048       {
4049         sqdd.name = "note";
4050         sqdd.isOrgMod = TRUE;
4051         sqdd.subtype = 255;
4052         str1 = GetSourceQualQualValueFromBiop (biop, &sqdd, fsp);
4053         sqdd.isOrgMod = FALSE;
4054         str2 = GetSourceQualQualValueFromBiop (biop, &sqdd, fsp);
4055         str = StringAppend (str1, str2);
4056         str1 = MemFree (str1);
4057         str2 = MemFree (str2);
4058       }
4059       else
4060       {
4061         str = GetStringFromSource (biop, vnp);
4062       }
4063     }
4064     vnp = vnp->next;
4065   }
4066   return str;
4067 }
4068 
4069 static CharPtr
GetSourceQualDescrString(SeqDescrPtr sdp,ValNodePtr vnp,FilterSetPtr fsp)4070 GetSourceQualDescrString
4071 (SeqDescrPtr  sdp,
4072  ValNodePtr   vnp,
4073  FilterSetPtr fsp)
4074 {
4075   if (sdp == NULL || sdp->choice != Seq_descr_source || vnp == NULL)
4076   {
4077     return NULL;
4078   }
4079   return GetSourceQualStringFromBioSource (sdp->data.ptrvalue, vnp, fsp);
4080 }
4081 
4082 static CharPtr
GetSourceQualFeatureString(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)4083 GetSourceQualFeatureString
4084 (SeqFeatPtr   sfp,
4085  ValNodePtr   vnp,
4086  FilterSetPtr fsp)
4087 {
4088   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || vnp == NULL)
4089   {
4090     return NULL;
4091   }
4092 
4093   return GetSourceQualStringFromBioSource (sfp->data.value.ptrvalue, vnp, fsp);
4094 }
4095 
ApplyLocationToBiop(BioSourcePtr biop,ApplyValuePtr avp)4096 static void ApplyLocationToBiop (BioSourcePtr biop, ApplyValuePtr avp)
4097 {
4098   if (biop == NULL || avp == NULL || avp->field_list == NULL)
4099   {
4100     return;
4101   }
4102 
4103   if (avp->etp == NULL
4104       || avp->etp->existing_text_choice == eExistingTextChoiceReplaceOld
4105       || biop->genome == 0)
4106   {
4107     biop->genome = avp->field_list->choice;
4108   }
4109 }
4110 
ApplyLocationToSourceFeature(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)4111 static void ApplyLocationToSourceFeature (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
4112 {
4113   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
4114   {
4115     ApplyLocationToBiop (sfp->data.value.ptrvalue, userdata);
4116   }
4117 }
4118 
ApplyLocationToSourceDescriptor(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)4119 static void ApplyLocationToSourceDescriptor (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
4120 {
4121   if (sdp != NULL && sdp->choice == Seq_descr_source)
4122   {
4123     ApplyLocationToBiop (sdp->data.ptrvalue, userdata);
4124   }
4125 }
4126 
RemoveLocationFromBiop(BioSourcePtr biop,ApplyValuePtr avp)4127 static void RemoveLocationFromBiop (BioSourcePtr biop, ApplyValuePtr avp)
4128 {
4129   if (biop == NULL || avp == NULL || avp->field_list == NULL)
4130   {
4131     return;
4132   }
4133 
4134   if (biop->genome == avp->field_list->choice)
4135   {
4136     biop->genome = 0;
4137   }
4138 }
4139 
RemoveLocationFromSourceFeature(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)4140 static void RemoveLocationFromSourceFeature (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
4141 {
4142   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
4143   {
4144     RemoveLocationFromBiop (sfp->data.value.ptrvalue, userdata);
4145   }
4146 }
4147 
RemoveLocationFromSourceDescriptor(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)4148 static void RemoveLocationFromSourceDescriptor (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
4149 {
4150   if (sdp != NULL && sdp->choice == Seq_descr_source)
4151   {
4152     RemoveLocationFromBiop (sdp->data.ptrvalue, userdata);
4153   }
4154 }
4155 
ApplyOriginToBiop(BioSourcePtr biop,ApplyValuePtr avp)4156 static void ApplyOriginToBiop (BioSourcePtr biop, ApplyValuePtr avp)
4157 {
4158   if (biop == NULL || avp == NULL || avp->field_list == NULL)
4159   {
4160     return;
4161   }
4162 
4163   if (avp->etp == NULL
4164       || avp->etp->existing_text_choice == eExistingTextChoiceReplaceOld
4165       || biop->origin == 0)
4166   {
4167     biop->origin = avp->field_list->choice;
4168   }
4169 }
4170 
ApplyOriginToSourceFeature(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)4171 static void ApplyOriginToSourceFeature (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
4172 {
4173   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
4174   {
4175     ApplyOriginToBiop (sfp->data.value.ptrvalue, userdata);
4176   }
4177 }
4178 
ApplyOriginToSourceDescriptor(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)4179 static void ApplyOriginToSourceDescriptor (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
4180 {
4181   if (sdp != NULL && sdp->choice == Seq_descr_source)
4182   {
4183     ApplyOriginToBiop (sdp->data.ptrvalue, userdata);
4184   }
4185 }
4186 
RemoveOriginFromBiop(BioSourcePtr biop,ApplyValuePtr avp)4187 static void RemoveOriginFromBiop (BioSourcePtr biop, ApplyValuePtr avp)
4188 {
4189   if (biop == NULL || avp == NULL || avp->field_list == NULL)
4190   {
4191     return;
4192   }
4193 
4194   if (biop->origin == avp->field_list->choice)
4195   {
4196     biop->origin = 0;
4197   }
4198 }
4199 
RemoveOriginFromSourceFeature(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)4200 static void RemoveOriginFromSourceFeature (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
4201 {
4202   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
4203   {
4204     RemoveOriginFromBiop (sfp->data.value.ptrvalue, userdata);
4205   }
4206 }
4207 
RemoveOriginFromSourceDescriptor(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)4208 static void RemoveOriginFromSourceDescriptor (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
4209 {
4210   if (sdp != NULL && sdp->choice == Seq_descr_source)
4211   {
4212     RemoveOriginFromBiop (sdp->data.ptrvalue, userdata);
4213   }
4214 }
4215 
ApplyStringToSource(BioSourcePtr biop,Pointer userdata)4216 static void ApplyStringToSource (BioSourcePtr biop, Pointer userdata)
4217 {
4218   ApplyValuePtr         avp;
4219 
4220   if (biop == NULL || userdata == NULL)
4221   {
4222     return;
4223   }
4224 
4225   avp = (ApplyValuePtr) userdata;
4226   if (avp == NULL || avp->field_list == NULL)
4227   {
4228     return;
4229   }
4230 
4231   if (StringHasNoText (avp->text_to_replace))
4232   {
4233     if (biop->org == NULL)
4234     {
4235       biop->org = OrgRefNew();
4236     }
4237     if (biop->org->orgname == NULL
4238         && (avp->field_list->choice == 3
4239             || avp->field_list->choice == 4))
4240     {
4241       biop->org->orgname = OrgNameNew ();
4242     }
4243   }
4244 
4245   switch (avp->field_list->choice)
4246   {
4247     case 1:
4248       biop->org->taxname = HandleApplyValue (biop->org->taxname, avp);
4249       break;
4250     case 2:
4251       biop->org->common = HandleApplyValue (biop->org->common, avp);
4252       break;
4253     case 3:
4254       biop->org->orgname->lineage = HandleApplyValue (biop->org->orgname->lineage, avp);
4255       break;
4256     case 4:
4257       biop->org->orgname->div = HandleApplyValue (biop->org->orgname->div, avp);
4258       break;
4259   }
4260 }
4261 
ApplyStringToSourceFeature(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)4262 static void ApplyStringToSourceFeature (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
4263 {
4264   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
4265   {
4266     ApplyStringToSource (sfp->data.value.ptrvalue, userdata);
4267   }
4268 }
4269 
ApplyStringToSourceDescriptor(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)4270 static void ApplyStringToSourceDescriptor (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
4271 {
4272   if (sdp != NULL && sdp->choice == Seq_descr_source)
4273   {
4274     ApplyStringToSource (sdp->data.ptrvalue, userdata);
4275   }
4276 }
4277 
RemoveStringFromSource(BioSourcePtr biop,Pointer userdata)4278 static void RemoveStringFromSource (BioSourcePtr biop, Pointer userdata)
4279 {
4280   ApplyValuePtr avp;
4281 
4282   if (biop == NULL || biop->org == NULL || userdata == NULL)
4283   {
4284     return;
4285   }
4286 
4287   avp = (ApplyValuePtr) userdata;
4288   if (avp == NULL || avp->field_list == NULL)
4289   {
4290     return;
4291   }
4292 
4293   switch (avp->field_list->choice)
4294   {
4295     case 1:
4296       biop->org->taxname = MemFree (biop->org->taxname);
4297       break;
4298     case 2:
4299       biop->org->common = MemFree (biop->org->common);
4300       break;
4301     case 3:
4302       if (biop->org->orgname != NULL)
4303       {
4304         biop->org->orgname->lineage = MemFree (biop->org->orgname->lineage);
4305       }
4306       break;
4307     case 4:
4308       if (biop->org->orgname != NULL)
4309       {
4310         biop->org->orgname->div = MemFree (biop->org->orgname->div);
4311       }
4312       break;
4313   }
4314 }
4315 
RemoveStringFromSourceFeature(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)4316 static void RemoveStringFromSourceFeature (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
4317 {
4318   if (sfp != NULL && sfp->data.choice == SEQFEAT_BIOSRC)
4319   {
4320     RemoveStringFromSource (sfp->data.value.ptrvalue, userdata);
4321   }
4322 }
4323 
RemoveStringFromSourceDescriptor(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)4324 static void RemoveStringFromSourceDescriptor (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
4325 {
4326   if (sdp != NULL && sdp->choice == Seq_descr_source)
4327   {
4328     RemoveStringFromSource (sdp->data.ptrvalue, userdata);
4329   }
4330 }
4331 
4332 static void SqnRemoveSourceQualFromBioSource (BioSourcePtr biop, Pointer userdata, FilterSetPtr fsp);
4333 
RemoveSubfield(CharPtr orig,Uint1 subfield)4334 static CharPtr RemoveSubfield (CharPtr orig, Uint1 subfield)
4335 {
4336   CharPtr cp, cp2;
4337   Int4    num_colons = 0;
4338   CharPtr new_val;
4339 
4340   cp = StringChr (orig, ':');
4341   while (cp != NULL) {
4342     num_colons ++;
4343     cp = StringChr (cp + 1, ':');
4344   }
4345   new_val = orig;
4346 
4347   if (subfield == 0) {
4348     new_val = MemFree (new_val);
4349   } else if (subfield == 1) {
4350     if (num_colons == 0) {
4351       /* no INST, just specID, nothing to remove */
4352     } else if (num_colons == 1) {
4353       cp = StringChr (orig, ':');
4354       new_val = StringSave (cp + 1);
4355       orig = MemFree (orig);
4356     } else {
4357       cp = StringChr (orig, ':');
4358       new_val = StringSave (cp);
4359       orig = MemFree (orig);
4360     }
4361   } else if (subfield == 2) {
4362     if (num_colons == 0 || num_colons == 1) {
4363       /* no COLL, nothing to remove */
4364     } else {
4365       cp = StringChr (orig, ':');
4366       cp2 = StringChr (cp + 1, ':');
4367       new_val = (CharPtr) MemNew (sizeof (Char) * (cp - orig + StringLen (cp2) + 1));
4368       StringNCpy (new_val, orig, cp - orig);
4369       StringCat (new_val, cp2);
4370       orig = MemFree (orig);
4371       if (StringCmp (new_val, ":") == 0) {
4372         new_val = MemFree (new_val);
4373       }
4374     }
4375   } else {
4376     /* specid */
4377     if (num_colons == 0) {
4378       new_val = MemFree (new_val);
4379     } else {
4380       cp = StringRChr (new_val, ':');
4381       *(cp + 1) = 0;
4382     }
4383   }
4384   return new_val;
4385 }
4386 
4387 
ApplyToSubfield(CharPtr orig,ApplyValuePtr avp,Uint1 subfield)4388 static CharPtr ApplyToSubfield (CharPtr orig, ApplyValuePtr avp, Uint1 subfield)
4389 {
4390   CharPtr cp, cp2;
4391   Int4    num_colons = 0, len;
4392   CharPtr new_field, new_val;
4393 
4394   cp = StringChr (orig, ':');
4395   while (cp != NULL) {
4396     num_colons ++;
4397     cp = StringChr (cp + 1, ':');
4398   }
4399 
4400   new_val = orig;
4401   if (subfield == 0) {
4402     /* whole field */
4403     new_val = HandleApplyValue (orig, avp);
4404   } else if (subfield == 1) {
4405     /* INST */
4406     if (num_colons == 0) {
4407       /* all we have is the specID, we are adding INST */
4408       new_field = HandleApplyValue (NULL, avp);
4409       if (!StringHasNoText (new_field)) {
4410         new_val = (CharPtr) MemNew (sizeof (Char) * (StringLen (new_field) + StringLen (orig) + 2));
4411         sprintf (new_val, "%s:%s", new_field, orig == NULL ? "" : orig);
4412         orig = MemFree (orig);
4413       } else {
4414         new_val = orig;
4415       }
4416       new_field = MemFree (new_field);
4417     } else {
4418       cp = StringChr (orig, ':');
4419       len = cp - orig + 1;
4420       new_field = (CharPtr) MemNew (sizeof (Char) * len);
4421       StringNCpy (new_field, orig, len - 1);
4422       new_field[len - 1] = 0;
4423       new_field = HandleApplyValue (new_field, avp);
4424       new_val = (CharPtr) MemNew (sizeof (Char) * (StringLen (new_field) + StringLen (cp) + 1));
4425       sprintf (new_val, "%s%s", new_field == NULL ? "" : new_field, cp);
4426       orig = MemFree (orig);
4427       new_field = MemFree (new_field);
4428     }
4429   } else if (subfield == 2) {
4430     /* COLL */
4431     if (num_colons == 0) {
4432       /* add blank INST, then COLL, then existing specID */
4433       new_field = HandleApplyValue (NULL, avp);
4434       if (!StringHasNoText (new_field)) {
4435         new_val = (CharPtr) MemNew (sizeof (Char) * (3 + StringLen (new_field) +  StringLen (orig)));
4436         sprintf (new_val, ":%s:%s", new_field, orig == NULL ? "" : orig);
4437         orig = MemFree (orig);
4438       } else {
4439         new_val = orig;
4440       }
4441       new_field = MemFree (new_field);
4442     } else if (num_colons == 1) {
4443       /* have INST and specID */
4444       new_field = HandleApplyValue (NULL, avp);
4445       if (!StringHasNoText (new_field)) {
4446         new_val = (CharPtr) MemNew (sizeof (Char) * (3 + StringLen (new_field) +  StringLen (orig)));
4447         cp = StringChr (orig, ':');
4448         len = cp - orig;
4449         StringNCpy (new_val, orig, len);
4450         StringCat (new_val, ":");
4451         StringCat (new_val, new_field);
4452         StringCat (new_val, cp);
4453         orig = MemFree (orig);
4454       } else {
4455         new_val = orig;
4456       }
4457       new_field = MemFree (new_field);
4458     } else {
4459       cp = StringChr (orig, ':');
4460       cp2 = StringChr (cp + 1, ':');
4461       len = cp2 - cp;
4462       new_field = (CharPtr) MemNew (sizeof (Char) * len);
4463       StringNCpy (new_field, cp + 1, len - 1);
4464       new_field[len - 1] = 0;
4465       new_field = HandleApplyValue (new_field, avp);
4466       new_val = (CharPtr) MemNew (sizeof (Char) * (cp - orig + 1 + StringLen (new_field) + StringLen (cp2) + 1));
4467       StringNCpy (new_val, orig, cp - orig + 1);
4468       StringCat (new_val, new_field);
4469       StringCat (new_val, cp2);
4470       orig = MemFree (orig);
4471       new_field = MemFree (new_field);
4472     }
4473   } else {
4474     /* specid */
4475     if (num_colons == 0) {
4476       new_val = HandleApplyValue (orig, avp);
4477     } else {
4478       cp = StringRChr (orig, ':');
4479       new_field = StringSave (cp + 1);
4480       new_field = HandleApplyValue (new_field, avp);
4481       new_val = (CharPtr) MemNew (sizeof (Char) + (cp - orig + 1 + StringLen (new_field) + 1));
4482       StringNCpy (new_val, orig, cp - orig + 1);
4483       StringCat (new_val, new_field);
4484       orig = MemFree (orig);
4485       new_field = MemFree (new_field);
4486     }
4487   }
4488   return new_val;
4489 }
4490 
4491 
ApplySourceQualBioSourceCallback(BioSourcePtr biop,Pointer userdata,FilterSetPtr fsp)4492 static void ApplySourceQualBioSourceCallback (BioSourcePtr biop, Pointer userdata, FilterSetPtr fsp)
4493 {
4494   ApplyValuePtr         avp;
4495   SourceQualDescPtr     sqdp;
4496   OrgModPtr             mod = NULL, last_mod = NULL;
4497   SubSourcePtr          ssp = NULL, last_ssp = NULL;
4498   Boolean               found = FALSE;
4499   Boolean               is_nontext;
4500 
4501   if (biop == NULL || userdata == NULL)
4502   {
4503     return;
4504   }
4505 
4506   avp = (ApplyValuePtr) userdata;
4507   if (avp->field_list == NULL || avp->field_list->data.ptrvalue == NULL)
4508   {
4509     return;
4510   }
4511 
4512   /* don't apply to All Notes */
4513   if (avp->field_list->choice != 0)
4514   {
4515     return;
4516   }
4517 
4518   sqdp = (SourceQualDescPtr) avp->field_list->data.ptrvalue;
4519 
4520   is_nontext = IsNonTextModifier (sqdp->name);
4521   if (is_nontext && StringHasNoText (avp->new_text))
4522   {
4523     SqnRemoveSourceQualFromBioSource (biop, avp, fsp);
4524     return;
4525   }
4526 
4527   if (!StringHasNoText (avp->text_to_replace))
4528   {
4529     found = TRUE;
4530   }
4531 
4532   if (sqdp->isOrgMod)
4533   {
4534     if (biop->org == NULL)
4535     {
4536       biop->org = OrgRefNew ();
4537     }
4538     if (biop->org != NULL && biop->org->orgname == NULL)
4539     {
4540       biop->org->orgname = OrgNameNew ();
4541     }
4542     if (biop->org != NULL && biop->org->orgname != NULL)
4543     {
4544       mod = biop->org->orgname->mod;
4545       while (mod != NULL)
4546       {
4547         if (mod->subtype == sqdp->subtype)
4548         {
4549           if (!is_nontext)
4550           {
4551             mod->subname = ApplyToSubfield (mod->subname, avp, sqdp->subfield);
4552           }
4553           found = TRUE;
4554         }
4555         last_mod = mod;
4556         mod = mod->next;
4557       }
4558       if (!found)
4559       {
4560         mod = OrgModNew ();
4561         mod->subtype = sqdp->subtype;
4562         if (is_nontext)
4563         {
4564           mod->subname = StringSave ("");
4565         }
4566         else
4567         {
4568           mod->subname = ApplyToSubfield (mod->subname, avp, sqdp->subfield);
4569         }
4570         if (last_mod == NULL)
4571         {
4572           biop->org->orgname->mod = mod;
4573         }
4574         else
4575         {
4576           last_mod->next = mod;
4577         }
4578       }
4579     }
4580   }
4581   else
4582   {
4583     ssp = biop->subtype;
4584     while (ssp != NULL)
4585     {
4586       if (ssp->subtype == sqdp->subtype)
4587       {
4588         if (! is_nontext)
4589         {
4590           ssp->name = ApplyToSubfield (ssp->name, avp, sqdp->subfield);
4591         }
4592         found = TRUE;
4593       }
4594       last_ssp = ssp;
4595       ssp = ssp->next;
4596     }
4597     if (!found)
4598     {
4599       ssp = SubSourceNew ();
4600       ssp->subtype = sqdp->subtype;
4601       if (is_nontext)
4602       {
4603         ssp->name = StringSave ("");
4604       }
4605       else
4606       {
4607         ssp->name = ApplyToSubfield (ssp->name, avp, sqdp->subfield);
4608       }
4609       if (last_ssp == NULL)
4610       {
4611         biop->subtype = ssp;
4612       }
4613       else
4614       {
4615         last_ssp->next = ssp;
4616       }
4617     }
4618   }
4619 }
4620 
ApplySourceQualFeatureCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)4621 static void ApplySourceQualFeatureCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
4622 {
4623   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || userdata == NULL)
4624   {
4625     return;
4626   }
4627   ApplySourceQualBioSourceCallback (sfp->data.value.ptrvalue, userdata, fsp);
4628 }
4629 
ApplySourceQualDescriptorCallback(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)4630 static void ApplySourceQualDescriptorCallback (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
4631 {
4632   if (sdp == NULL || sdp->choice != Seq_descr_source || userdata == NULL)
4633   {
4634     return;
4635   }
4636   ApplySourceQualBioSourceCallback (sdp->data.ptrvalue, userdata, fsp);
4637 }
4638 
RemoveOrgModFromBioSource(BioSourcePtr biop,Uint1 subtype,Uint1 subfield,FilterSetPtr fsp)4639 static void RemoveOrgModFromBioSource (BioSourcePtr biop, Uint1 subtype, Uint1 subfield, FilterSetPtr fsp)
4640 {
4641   OrgModPtr mod = NULL, prev_mod = NULL, next_mod;
4642 
4643   if (biop != NULL && biop->org != NULL && biop->org->orgname != NULL)
4644   {
4645     mod = biop->org->orgname->mod;
4646     while (mod != NULL)
4647     {
4648       next_mod = mod->next;
4649       if (mod->subtype == subtype
4650           && OrgModSpecialMatch (mod, fsp))
4651       {
4652         mod->subname = RemoveSubfield (mod->subname, subfield);
4653         if (StringHasNoText (mod->subname)) {
4654           if (prev_mod == NULL)
4655           {
4656             biop->org->orgname->mod = mod->next;
4657           }
4658           else
4659           {
4660             prev_mod->next = mod->next;
4661           }
4662           mod->next = NULL;
4663           OrgModFree (mod);
4664         } else {
4665           prev_mod = mod;
4666         }
4667       }
4668       else
4669       {
4670         prev_mod = mod;
4671       }
4672       mod = next_mod;
4673     }
4674   }
4675 }
4676 
RemoveSubSourceFromBioSource(BioSourcePtr biop,Uint2 subtype,Uint1 subfield,FilterSetPtr fsp)4677 static void RemoveSubSourceFromBioSource (BioSourcePtr biop, Uint2 subtype, Uint1 subfield, FilterSetPtr fsp)
4678 {
4679   SubSourcePtr ssp = NULL, prev_ssp = NULL, next_ssp;
4680 
4681   if (biop != NULL)
4682   {
4683     ssp = biop->subtype;
4684     while (ssp != NULL)
4685     {
4686       next_ssp = ssp->next;
4687       if (ssp->subtype == subtype
4688           && SubSrcSpecialMatch (ssp, fsp))
4689       {
4690         ssp->name = RemoveSubfield (ssp->name, subfield);
4691         if (StringHasNoText (ssp->name)) {
4692           if (prev_ssp == NULL)
4693           {
4694             biop->subtype = ssp->next;
4695           }
4696           else
4697           {
4698             prev_ssp->next = ssp->next;
4699           }
4700           ssp->next = NULL;
4701           SubSourceFree (ssp);
4702         } else {
4703           prev_ssp = ssp;
4704         }
4705       }
4706       else
4707       {
4708         prev_ssp = ssp;
4709       }
4710       ssp = next_ssp;
4711     }
4712   }
4713 }
4714 
SqnRemoveSourceQualFromBioSource(BioSourcePtr biop,Pointer userdata,FilterSetPtr fsp)4715 static void SqnRemoveSourceQualFromBioSource (BioSourcePtr biop, Pointer userdata, FilterSetPtr fsp)
4716 {
4717   ApplyValuePtr         avp;
4718   SourceQualDescPtr     sqdp;
4719 
4720   if (biop == NULL || userdata == NULL)
4721   {
4722     return;
4723   }
4724 
4725   avp = (ApplyValuePtr) userdata;
4726   if (avp->field_list == NULL || avp->field_list->data.ptrvalue == NULL)
4727   {
4728     return;
4729   }
4730   if (avp->field_list->choice == 0)
4731   {
4732     sqdp = (SourceQualDescPtr) avp->field_list->data.ptrvalue;
4733     if (sqdp->isOrgMod)
4734     {
4735       RemoveOrgModFromBioSource (biop, sqdp->subtype, sqdp->subfield, fsp);
4736     }
4737     else
4738     {
4739       RemoveSubSourceFromBioSource (biop, sqdp->subtype, sqdp->subfield, fsp);
4740     }
4741   }
4742   else if (avp->field_list->choice == 1
4743            && StringCmp (avp->field_list->data.ptrvalue, "All Notes") == 0)
4744   {
4745     RemoveOrgModFromBioSource (biop, 255, 0, fsp);
4746     RemoveSubSourceFromBioSource (biop, 255, 0, fsp);
4747   }
4748 }
4749 
RemoveSourceQualFromSourceFeature(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)4750 static void RemoveSourceQualFromSourceFeature (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
4751 {
4752   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || userdata == NULL)
4753   {
4754     return;
4755   }
4756   SqnRemoveSourceQualFromBioSource (sfp->data.value.ptrvalue, userdata, fsp);
4757 }
4758 
RemoveSourceQualFromSourceDescriptor(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)4759 static void RemoveSourceQualFromSourceDescriptor (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
4760 {
4761   if (sdp == NULL || sdp->choice != Seq_descr_source || userdata == NULL)
4762   {
4763     return;
4764   }
4765   SqnRemoveSourceQualFromBioSource (sdp->data.ptrvalue, userdata, fsp);
4766 }
4767 
SourceLocationSelectionDialogEx(GrouP h,Boolean allow_multi,Boolean allow_discontinued,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)4768 static DialoG SourceLocationSelectionDialogEx
4769 (GrouP h,
4770  Boolean                  allow_multi,
4771  Boolean                  allow_discontinued,
4772  Nlm_ChangeNotifyProc     change_notify,
4773  Pointer                  change_userdata)
4774 
4775 {
4776   DialoG     dlg;
4777   ValNodePtr choice_list = NULL;
4778   Nlm_EnumFieldAssocPtr eap = biosource_genome_alistX;
4779 
4780   if (eap == NULL)
4781   {
4782     return NULL;
4783   }
4784 
4785   while (eap->name != NULL)
4786   {
4787     if (!StringHasNoText (eap->name)
4788         && (allow_discontinued ||
4789             (StringCmp (eap->name, "Insertion Sequence") != 0
4790              && StringCmp (eap->name, "Transposon") != 0)))
4791     {
4792       ValNodeAddPointer (&choice_list, eap->value, StringSave (eap->name));
4793     }
4794     eap++;
4795   }
4796 
4797   /* note - the ValNodeSelectionDialog will free the qual_choice_list
4798    * when done */
4799   dlg = ValNodeSelectionDialog (h, choice_list, TALL_SELECTION_LIST,
4800                                 ValNodeStringName,
4801                                 ValNodeSimpleDataFree, ValNodeStringCopy,
4802                                 ValNodeChoiceMatch, "Location",
4803                                 change_notify, change_userdata, allow_multi);
4804 
4805   return dlg;
4806 }
4807 
4808 
SourceLocationSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)4809 static DialoG SourceLocationSelectionDialog
4810 (GrouP h,
4811  Boolean                  allow_multi,
4812  Nlm_ChangeNotifyProc     change_notify,
4813  Pointer                  change_userdata)
4814 {
4815   return SourceLocationSelectionDialogEx (h, allow_multi, FALSE,
4816                                           change_notify, change_userdata);
4817 }
4818 
4819 
SourceLocationDiscSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)4820 static DialoG SourceLocationDiscSelectionDialog
4821 (GrouP h,
4822  Boolean                  allow_multi,
4823  Nlm_ChangeNotifyProc     change_notify,
4824  Pointer                  change_userdata)
4825 {
4826   return SourceLocationSelectionDialogEx (h, allow_multi, TRUE,
4827                                           change_notify, change_userdata);
4828 }
4829 
4830 
SourceOriginSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)4831 static DialoG SourceOriginSelectionDialog
4832 (GrouP h,
4833  Boolean                  allow_multi,
4834  Nlm_ChangeNotifyProc     change_notify,
4835  Pointer                  change_userdata)
4836 
4837 {
4838   return EnumAssocSelectionDialog (h, origin_alist, "Origin",
4839                                    allow_multi, change_notify, change_userdata);
4840 }
4841 
SourceStringSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)4842 static DialoG SourceStringSelectionDialog
4843 (GrouP h,
4844  Boolean                  allow_multi,
4845  Nlm_ChangeNotifyProc     change_notify,
4846  Pointer                  change_userdata)
4847 
4848 {
4849   return EnumAssocSelectionDialog (h, orgref_textfield_alist, "string",
4850                                    allow_multi, change_notify, change_userdata);
4851 }
4852 
4853 
4854 static CharPtr
GetStringFromStringDescriptor(SeqDescrPtr sdp,ValNodePtr vnp,FilterSetPtr fsp)4855 GetStringFromStringDescriptor
4856 (SeqDescrPtr  sdp,
4857  ValNodePtr   vnp,
4858  FilterSetPtr fsp)
4859 {
4860   if (sdp == NULL || vnp == NULL || sdp->choice != vnp->data.intvalue)
4861   {
4862     return NULL;
4863   }
4864   return StringSave (sdp->data.ptrvalue);
4865 }
4866 
GBQualSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)4867 static DialoG GBQualSelectionDialog
4868 (GrouP                    h,
4869  Boolean                  allow_multi,
4870  Nlm_ChangeNotifyProc     change_notify,
4871  Pointer                  change_userdata)
4872 
4873 {
4874   DialoG                    dlg;
4875   ValNodePtr            choice_name_list = NULL;
4876   Int4                      i;
4877 
4878   for (i = 0; i < NumEditQualifiers; i++)
4879   {
4880     ValNodeAddPointer (&choice_name_list, 0, EditQualifierList[i].name);
4881   }
4882 
4883   dlg = SelectionDialog (h, change_notify, change_userdata,
4884                          allow_multi, "genbank qualifier",
4885                          choice_name_list, TALL_SELECTION_LIST);
4886   ValNodeFree (choice_name_list);
4887   return dlg;
4888 }
4889 
GetDbtagStringLen(DbtagPtr db_tag)4890 static Int4 GetDbtagStringLen (DbtagPtr db_tag)
4891 {
4892   Int4 len;
4893 
4894   if (db_tag == NULL)
4895   {
4896     return 0;
4897   }
4898 
4899   len = StringLen (db_tag->db) + 2;
4900   if (db_tag->tag != NULL)
4901   {
4902     if (db_tag->tag->str != NULL)
4903     {
4904       len += StringLen (db_tag->tag->str);
4905     }
4906     else
4907     {
4908       len += 10;
4909     }
4910   }
4911   return len;
4912 }
4913 
GetDbxrefString(SeqFeatPtr sfp)4914 static CharPtr GetDbxrefString (SeqFeatPtr sfp)
4915 {
4916   ValNodePtr vnp;
4917   Int4       len = 0;
4918   CharPtr    str = NULL, cp;
4919 
4920   if (sfp == NULL || sfp->dbxref == NULL)
4921   {
4922     return NULL;
4923   }
4924 
4925   for (vnp = sfp->dbxref; vnp != NULL; vnp = vnp->next)
4926   {
4927     len += GetDbtagStringLen (vnp->data.ptrvalue) + 1;
4928   }
4929 
4930   if (len == 0)
4931   {
4932     return NULL;
4933   }
4934 
4935   str = (CharPtr) MemNew ((len + 1) * sizeof (Char));
4936   if (str != NULL)
4937   {
4938     for (vnp = sfp->dbxref; vnp != NULL; vnp = vnp->next)
4939     {
4940       cp = GetDbtagString (vnp->data.ptrvalue);
4941       if (cp != NULL)
4942       {
4943         StringCat (str, cp);
4944         StringCat (str, ";");
4945       }
4946     }
4947   }
4948   if (StringLen (str) >1)
4949   {
4950     /* remove final semicolon */
4951     str [StringLen (str) - 2] = 0;
4952   }
4953   return str;
4954 }
4955 
GetGBQualString(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)4956 static CharPtr GetGBQualString (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
4957 {
4958   GBQualPtr  gbqual;
4959   CharPtr    str = NULL;
4960   Int4       field_choice;
4961   RnaRefPtr  rrp;
4962   GeneRefPtr grp;
4963 
4964   if (sfp == NULL)
4965   {
4966     return NULL;
4967   }
4968   while (vnp != NULL && str == NULL)
4969   {
4970     field_choice = vnp->data.intvalue;
4971     if (StringICmp (EditQualifierList[field_choice - 1].name, "note") == 0)
4972     {
4973       if (!StringHasNoText (sfp->comment))
4974       {
4975         str = StringSave (sfp->comment);
4976       }
4977     }
4978     else if (StringICmp (EditQualifierList[field_choice - 1].name, "exception") == 0)
4979     {
4980       if (!StringHasNoText (sfp->except_text))
4981       {
4982         str = StringSave (sfp->except_text);
4983       }
4984     }
4985     else if (StringICmp (EditQualifierList[field_choice - 1].name, "product") == 0
4986              && sfp->data.choice == SEQFEAT_RNA)
4987     {
4988       rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
4989       if (rrp != NULL && rrp->ext.choice == 1
4990           && !StringHasNoText (rrp->ext.value.ptrvalue))
4991       {
4992         str = StringSave (rrp->ext.value.ptrvalue);
4993       }
4994     }
4995     else if (StringICmp (EditQualifierList [field_choice - 1].name, "map") == 0
4996              && sfp->data.choice == SEQFEAT_GENE)
4997     {
4998       grp = (GeneRefPtr) sfp->data.value.ptrvalue;
4999       if (grp != NULL && !StringHasNoText (grp->maploc))
5000       {
5001         str = StringSave (grp->maploc);
5002       }
5003     }
5004     else if (StringICmp (EditQualifierList [field_choice - 1].name, "db_xref") == 0)
5005     {
5006         str = GetDbxrefString (sfp);
5007     }
5008     else if (StringICmp (EditQualifierList [field_choice - 1].name, "evidence") == 0)
5009     {
5010       if (sfp->exp_ev == 1)
5011       {
5012         str = StringSave ("experimental");
5013       }
5014       else if (sfp->exp_ev == 2)
5015       {
5016         str = StringSave ("non-experimental");
5017       }
5018     }
5019     else
5020     {
5021       gbqual = sfp->qual;
5022       while (gbqual != NULL && str == NULL)
5023       {
5024         if (field_choice > 0 && field_choice < NumEditQualifiers + 1
5025             && StringCmp (gbqual->qual, EditQualifierList[field_choice - 1].name) == 0
5026             && !StringHasNoText (gbqual->val))
5027         {
5028           str = StringSave (gbqual->val);
5029         }
5030         gbqual = gbqual->next;
5031       }
5032     }
5033     vnp = vnp->next;
5034   }
5035   return str;
5036 }
5037 
DbtagFromString(CharPtr str)5038 static DbtagPtr DbtagFromString (CharPtr str)
5039 {
5040   DbtagPtr db_tag;
5041   CharPtr  cp, idp;
5042   Boolean  use_id = TRUE;
5043 
5044   if (StringHasNoText (str))
5045   {
5046     return NULL;
5047   }
5048 
5049   cp = StringChr (str, ':');
5050   if (cp == NULL)
5051   {
5052     return NULL;
5053   }
5054 
5055   db_tag = DbtagNew ();
5056   if (db_tag != NULL)
5057   {
5058     db_tag->db = (CharPtr) MemNew ((cp - str + 1) * sizeof (Char));
5059     StringNCpy (db_tag->db, str, cp - str);
5060     db_tag->db [cp - str] = 0;
5061 
5062     idp = cp + 1;
5063     while (*idp != 0 && use_id)
5064     {
5065       if (!isdigit (*idp))
5066       {
5067         use_id = FALSE;
5068       }
5069       idp++;
5070     }
5071     db_tag->tag = ObjectIdNew ();
5072     if (use_id)
5073     {
5074       db_tag->tag->id = atoi (cp + 1);
5075       db_tag->tag->str = NULL;
5076     }
5077     else
5078     {
5079       db_tag->tag->id = 0;
5080       db_tag->tag->str = StringSave (cp + 1);
5081     }
5082   }
5083   return db_tag;
5084 }
5085 
HandleApplyValueForObjectID(ObjectIdPtr oip,ApplyValuePtr avp)5086 static void HandleApplyValueForObjectID (ObjectIdPtr oip, ApplyValuePtr avp)
5087 {
5088   CharPtr tmp_str = NULL;
5089   CharPtr cp;
5090   Boolean is_num = TRUE;
5091 
5092   if (oip == NULL || avp == NULL)
5093   {
5094     return;
5095   }
5096 
5097   if (oip->str == NULL)
5098   {
5099     tmp_str = (CharPtr) MemNew (10 * sizeof (Char));
5100     sprintf (tmp_str, "%d", oip->id);
5101 
5102   }
5103   else
5104   {
5105     tmp_str = oip->str;
5106     oip->str = NULL;
5107   }
5108   tmp_str = HandleApplyValue (tmp_str, avp);
5109 
5110   for (cp = tmp_str; cp != NULL && *cp != 0 && is_num; cp++)
5111   {
5112     if (!isdigit (*cp))
5113     {
5114       is_num = FALSE;
5115     }
5116   }
5117   if (is_num)
5118   {
5119     oip->id = atoi (tmp_str);
5120     tmp_str = MemFree (tmp_str);
5121   }
5122   else
5123   {
5124     oip->str = tmp_str;
5125   }
5126 }
5127 
EditDbxref(SeqFeatPtr sfp,ApplyValuePtr avp,FilterSetPtr fsp)5128 static void EditDbxref (SeqFeatPtr sfp, ApplyValuePtr avp, FilterSetPtr fsp)
5129 {
5130   ValNodePtr vnp;
5131   DbtagPtr   db_tag_new, db_tag_to_replace, db_tag;
5132   CharPtr    cp;
5133 
5134   if (sfp == NULL || avp == NULL)
5135   {
5136     return;
5137   }
5138 
5139   db_tag_new = DbtagFromString (avp->new_text);
5140   db_tag_to_replace = DbtagFromString (avp->text_to_replace);
5141 
5142   if (db_tag_new == NULL && db_tag_to_replace == NULL)
5143   {
5144     for (vnp = sfp->dbxref; vnp != NULL; vnp = vnp->next)
5145     {
5146       db_tag = (DbtagPtr) vnp->data.ptrvalue;
5147       if (db_tag != NULL)
5148       {
5149         db_tag->db = HandleApplyValue (db_tag->db, avp);
5150         HandleApplyValueForObjectID (db_tag->tag, avp);
5151       }
5152     }
5153   }
5154   else if (db_tag_new != NULL && db_tag_to_replace != NULL)
5155   {
5156     for (vnp = sfp->dbxref; vnp != NULL; vnp = vnp->next)
5157     {
5158       db_tag = (DbtagPtr) vnp->data.ptrvalue;
5159       if (db_tag != NULL)
5160       {
5161         cp = GetDbtagString (db_tag);
5162         cp = HandleApplyValue (cp, avp);
5163         db_tag = DbtagFree (db_tag);
5164         db_tag = DbtagFromString (cp);
5165         vnp->data.ptrvalue = db_tag;
5166         cp = MemFree (cp);
5167       }
5168     }
5169   }
5170 }
5171 
RemoveDbxrefList(ValNodePtr vnp)5172 static ValNodePtr RemoveDbxrefList (ValNodePtr vnp)
5173 
5174 {
5175   ValNodePtr  next;
5176 
5177   while (vnp != NULL) {
5178     next = vnp->next;
5179     DbtagFree ((DbtagPtr) vnp->data.ptrvalue);
5180     MemFree (vnp);
5181     vnp = next;
5182   }
5183   return NULL;
5184 }
5185 
SetDbxrefFromString(SeqFeatPtr sfp,ApplyValuePtr avp,FilterSetPtr fsp)5186 static void SetDbxrefFromString (SeqFeatPtr sfp, ApplyValuePtr avp, FilterSetPtr fsp)
5187 {
5188   DbtagPtr new_tag;
5189 
5190   if (sfp == NULL || avp == NULL)
5191   {
5192     return;
5193   }
5194 
5195   if (StringHasNoText (avp->text_to_replace))
5196   {
5197     /* this is an apply */
5198     if (avp->etp != NULL)
5199     {
5200       if (avp->etp->existing_text_choice == eExistingTextChoiceLeaveOld
5201           && sfp->dbxref != NULL)
5202       {
5203         return;
5204       }
5205       else if (avp->etp->existing_text_choice == eExistingTextChoiceReplaceOld)
5206       {
5207         sfp->dbxref = RemoveDbxrefList (sfp->dbxref);
5208       }
5209     }
5210 
5211     new_tag = DbtagFromString (avp->new_text);
5212     if (new_tag != NULL)
5213     {
5214       ValNodeAddPointer (&(sfp->dbxref), 0, new_tag);
5215     }
5216   }
5217   else
5218   {
5219     EditDbxref (sfp, avp, fsp);
5220   }
5221 
5222 }
5223 
5224 static void SetRNAProduct (SeqFeatPtr sfp, ApplyValuePtr avp);
5225 
SetGBQualString(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)5226 static void SetGBQualString (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
5227 {
5228   GBQualPtr     gbqual, gbqual_last = NULL;
5229   ApplyValuePtr avp;
5230   Boolean       found = FALSE;
5231   GeneRefPtr    grp;
5232 
5233   if (sfp == NULL || userdata == NULL)
5234   {
5235     return;
5236   }
5237   avp = (ApplyValuePtr) userdata;
5238   if (avp->field_list == NULL
5239       || avp->field_list->data.intvalue < 1
5240       || avp->field_list->data.intvalue >= NumEditQualifiers + 1)
5241   {
5242     return;
5243   }
5244 
5245   if (StringICmp (EditQualifierList[avp->field_list->data.intvalue - 1].name, "note") == 0)
5246   {
5247     sfp->comment = HandleApplyValue (sfp->comment, avp);
5248     return;
5249   }
5250   else if (StringICmp (EditQualifierList[avp->field_list->data.intvalue - 1].name, "exception") == 0)
5251   {
5252     sfp->except_text = HandleApplyValue (sfp->except_text, avp);
5253     return;
5254   }
5255   else if (StringICmp (EditQualifierList[avp->field_list->data.intvalue - 1].name, "product") == 0
5256            && sfp->data.choice == SEQFEAT_RNA)
5257   {
5258     SetRNAProduct (sfp, avp);
5259     return;
5260   }
5261   else if (StringICmp (EditQualifierList [avp->field_list->data.intvalue - 1].name, "map") == 0
5262            && sfp->data.choice == SEQFEAT_GENE)
5263   {
5264     grp = (GeneRefPtr) sfp->data.value.ptrvalue;
5265     if (grp != NULL)
5266     {
5267       grp->maploc = HandleApplyValue (grp->maploc, avp);
5268       return;
5269     }
5270   }
5271   else if (StringICmp (EditQualifierList [avp->field_list->data.intvalue - 1].name, "db_xref") == 0)
5272   {
5273     SetDbxrefFromString (sfp, avp, fsp);
5274     return;
5275   }
5276 
5277 
5278   if (!StringHasNoText (avp->text_to_replace))
5279   {
5280     found = TRUE;
5281   }
5282 
5283   gbqual = sfp->qual;
5284   while (gbqual != NULL)
5285   {
5286     gbqual_last = gbqual;
5287     if (StringCmp (gbqual->qual, EditQualifierList[avp->field_list->data.intvalue - 1].name) == 0)
5288     {
5289       gbqual->val = HandleApplyValue (gbqual->val, avp);
5290       found = TRUE;
5291     }
5292     gbqual = gbqual->next;
5293   }
5294   if (!found)
5295   {
5296     gbqual = GBQualNew ();
5297     if (gbqual != NULL)
5298     {
5299       gbqual->qual = StringSave (EditQualifierList[avp->field_list->data.intvalue - 1].name);
5300       gbqual->val = StringSave (avp->new_text);
5301       if (gbqual_last == NULL)
5302       {
5303         sfp->qual = gbqual;
5304       }
5305       else
5306       {
5307         gbqual_last->next = gbqual;
5308       }
5309     }
5310   }
5311 }
5312 
RemoveGBQualField(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)5313 static void RemoveGBQualField (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
5314 {
5315   GBQualPtr     gbqual, gbqual_last = NULL, gbqual_next;
5316   ApplyValuePtr avp;
5317   RnaRefPtr     rrp;
5318   GeneRefPtr    grp;
5319 
5320   if (sfp == NULL || userdata == NULL)
5321   {
5322     return;
5323   }
5324   avp = (ApplyValuePtr) userdata;
5325   if (avp->field_list == NULL
5326       || avp->field_list->data.intvalue < 1
5327       || avp->field_list->data.intvalue >= NumEditQualifiers + 1)
5328   {
5329     return;
5330   }
5331 
5332   if (StringICmp (EditQualifierList[avp->field_list->data.intvalue - 1].name, "note") == 0)
5333   {
5334     sfp->comment = MemFree (sfp->comment);
5335     return;
5336   }
5337   else if (StringICmp (EditQualifierList[avp->field_list->data.intvalue - 1].name, "exception") == 0)
5338   {
5339     sfp->except_text = MemFree (sfp->except_text);
5340     return;
5341   }
5342   else if (StringICmp (EditQualifierList[avp->field_list->data.intvalue - 1].name, "product") == 0
5343            && sfp->data.choice == SEQFEAT_RNA)
5344   {
5345     rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
5346     if (rrp != NULL && rrp->ext.choice == 1)
5347     {
5348       rrp->ext.choice = 0;
5349       rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
5350     }
5351     return;
5352   }
5353   else if (StringICmp (EditQualifierList [avp->field_list->data.intvalue - 1].name, "map") == 0
5354            && sfp->data.choice == SEQFEAT_GENE)
5355   {
5356     grp = (GeneRefPtr) sfp->data.value.ptrvalue;
5357     if (grp != NULL)
5358     {
5359       grp->maploc = MemFree (grp->maploc);
5360     }
5361   }
5362   else if (StringICmp (EditQualifierList [avp->field_list->data.intvalue - 1].name, "db_xref") == 0)
5363   {
5364     sfp->dbxref = RemoveDbxrefList (sfp->dbxref);
5365   }
5366 
5367 
5368   gbqual = sfp->qual;
5369   while (gbqual != NULL)
5370   {
5371     gbqual_next = gbqual->next;
5372     if (StringCmp (gbqual->qual, EditQualifierList[avp->field_list->data.intvalue - 1].name) == 0)
5373     {
5374       if (gbqual_last == NULL)
5375       {
5376         sfp->qual = gbqual->next;
5377       }
5378       else
5379       {
5380         gbqual_last->next = gbqual->next;
5381       }
5382       gbqual->next = NULL;
5383       GBQualFree (gbqual);
5384     }
5385     else
5386     {
5387       gbqual_last = gbqual;
5388     }
5389     gbqual = gbqual_next;
5390   }
5391 }
5392 
5393 
RemoveGoTerm(SeqFeatPtr sfp,CharPtr term_name)5394 static void RemoveGoTerm (SeqFeatPtr sfp, CharPtr term_name)
5395 {
5396   UserObjectPtr       uop;
5397   ObjectIdPtr         oip;
5398   UserFieldPtr  curr, curr_next, prev = NULL;
5399 
5400   if (sfp == NULL || sfp->ext == NULL || StringHasNoText (term_name))
5401   {
5402     return;
5403   }
5404 
5405   uop = (UserObjectPtr) sfp->ext;
5406   oip = uop->type;
5407   if (oip == NULL || StringICmp (oip->str, "GeneOntology") != 0) return;
5408 
5409   for (curr = uop->data; curr != NULL; curr = curr_next)
5410   {
5411     curr_next = curr->next;
5412     oip = curr->label;
5413     if (oip != NULL && StringICmp (oip->str, term_name) == 0)
5414     {
5415       if (prev == NULL)
5416       {
5417         uop->data = curr->next;
5418       }
5419       else
5420       {
5421         prev->next = curr->next;
5422       }
5423       curr->next = NULL;
5424       UserFieldFree (curr);
5425     }
5426     else
5427     {
5428       prev = curr;
5429     }
5430   }
5431 
5432   if (uop->data == NULL)
5433   {
5434     sfp->ext = UserObjectFree (sfp->ext);
5435   }
5436 
5437 }
5438 
5439 
RemoveGBQualByNameConstraint(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)5440 static void RemoveGBQualByNameConstraint (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
5441 {
5442   GBQualPtr           gbqual, gbqual_last = NULL, gbqual_next;
5443   RnaRefPtr           rrp;
5444   GeneRefPtr          grp;
5445   StringConstraintXPtr scp;
5446 
5447   if (sfp == NULL || userdata == NULL)
5448   {
5449     return;
5450   }
5451   scp = (StringConstraintXPtr) userdata;
5452   if (scp == NULL)
5453   {
5454     return;
5455   }
5456 
5457   if (DoesStringMatchConstraintX ("note", scp))
5458   {
5459     sfp->comment = MemFree (sfp->comment);
5460   }
5461 
5462   if (DoesStringMatchConstraintX ("exception", scp))
5463   {
5464     sfp->except_text = MemFree (sfp->except_text);
5465   }
5466 
5467   if (DoesStringMatchConstraintX ("product", scp) && sfp->data.choice == SEQFEAT_RNA)
5468   {
5469     rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
5470     if (rrp != NULL && rrp->ext.choice == 1)
5471     {
5472       rrp->ext.choice = 0;
5473       rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
5474     }
5475   }
5476 
5477   if (DoesStringMatchConstraintX ("map", scp) && sfp->data.choice == SEQFEAT_GENE)
5478   {
5479     grp = (GeneRefPtr) sfp->data.value.ptrvalue;
5480     if (grp != NULL)
5481     {
5482       grp->maploc = MemFree (grp->maploc);
5483     }
5484   }
5485 
5486   if (DoesStringMatchConstraintX ("db_xref", scp))
5487   {
5488     sfp->dbxref = RemoveDbxrefList (sfp->dbxref);
5489   }
5490 
5491   if (DoesStringMatchConstraintX ("go_process", scp))
5492   {
5493     RemoveGoTerm (sfp, "process");
5494   }
5495 
5496   if (DoesStringMatchConstraintX ("go_function", scp))
5497   {
5498     RemoveGoTerm (sfp, "function");
5499   }
5500 
5501   if (DoesStringMatchConstraintX ("go_component", scp))
5502   {
5503     RemoveGoTerm (sfp, "component");
5504   }
5505 
5506   gbqual = sfp->qual;
5507   while (gbqual != NULL)
5508   {
5509     gbqual_next = gbqual->next;
5510     if (DoesStringMatchConstraintX (gbqual->qual, scp))
5511     {
5512       if (gbqual_last == NULL)
5513       {
5514         sfp->qual = gbqual->next;
5515       }
5516       else
5517       {
5518         gbqual_last->next = gbqual->next;
5519       }
5520       gbqual->next = NULL;
5521       GBQualFree (gbqual);
5522     }
5523     else
5524     {
5525       gbqual_last = gbqual;
5526     }
5527     gbqual = gbqual_next;
5528   }
5529 }
5530 
5531 
GetFeatureNote(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)5532 static CharPtr GetFeatureNote (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
5533 {
5534   if (sfp == NULL || StringHasNoText (sfp->comment))
5535   {
5536     return NULL;
5537   }
5538   else
5539   {
5540     return StringSave (sfp->comment);
5541   }
5542 }
5543 
5544 
StripFieldNameFromText(CharPtr text,NameFromValNodeProc field_name_func,ValNodePtr field_vnp)5545 static void StripFieldNameFromText(CharPtr text,
5546                                    NameFromValNodeProc field_name_func,
5547                                    ValNodePtr          field_vnp)
5548 {
5549   CharPtr src, dst;
5550   CharPtr field_name = NULL;
5551   Uint4    field_name_len;
5552 
5553   if (StringHasNoText (text) || field_name_func == NULL)
5554   {
5555     return;
5556   }
5557 
5558   field_name = field_name_func(field_vnp);
5559   field_name_len = StringLen (field_name);
5560 
5561   if (!StringHasNoText (field_name) && StringNICmp(text, field_name, field_name_len) == 0
5562         && StringLen (text) > field_name_len
5563         && text[field_name_len] == ' ')
5564   {
5565     src = text + field_name_len + 1;
5566     while (*src == ' ')
5567     {
5568       src++;
5569     }
5570     dst = text;
5571     while (*src != 0)
5572     {
5573       *dst = *src;
5574       dst++;
5575       src++;
5576     }
5577     *dst = 0;
5578   }
5579   field_name = MemFree (field_name);
5580 }
5581 
5582 
ReplaceStringForParse(CharPtr src_text,TextPortionXPtr text_portion)5583 static CharPtr ReplaceStringForParse(CharPtr src_text, TextPortionXPtr text_portion)
5584 {
5585   CharPtr         found_loc;
5586   Int4            found_len;
5587   CharPtr         dst_txt = NULL, cp;
5588 
5589   if (src_text == NULL || text_portion == NULL) {
5590     return NULL;
5591   }
5592   /* for parse, replace the source text with the portion we want */
5593   found_loc = NULL;
5594   found_len = 0;
5595   FindTextPortionXInString (src_text, text_portion, &found_loc, &found_len);
5596   if (found_loc != NULL)
5597   {
5598     dst_txt = (CharPtr)MemNew (found_len + 1);
5599     StringNCpy (dst_txt, found_loc, found_len);
5600     dst_txt[found_len] = 0;
5601     cp = found_loc + found_len;
5602     while (*cp != 0) {
5603       *found_loc = *cp;
5604       found_loc++;
5605       cp++;
5606     }
5607     *found_loc = 0;
5608   }
5609   return dst_txt;
5610 }
5611 
5612 
ConvertFeatureFieldCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)5613 static void ConvertFeatureFieldCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
5614 {
5615   ConvertFieldPtr cfp;
5616   CharPtr         src_text;
5617   CharPtr         dst_text = NULL;
5618   ApplyValueData  avd;
5619 
5620   if (sfp == NULL || userdata == NULL)
5621   {
5622     return;
5623   }
5624 
5625   cfp = (ConvertFieldPtr) userdata;
5626 
5627   if (cfp->src_field_list == NULL || cfp->dst_field_list == NULL
5628       || cfp->get_str_func == NULL || cfp->set_str_func == NULL
5629       || cfp->remove_str_func == NULL)
5630   {
5631     return;
5632   }
5633 
5634   avd.text_to_replace = NULL;
5635   avd.where_to_replace = EditApplyFindLocation_anywhere;
5636   src_text = (cfp->get_str_func)(sfp, cfp->src_field_list, cfp->fsp);
5637 
5638   if (cfp->strip_name_from_text)
5639   {
5640     StripFieldNameFromText(src_text, cfp->name_field_func, cfp->dst_field_list);
5641   }
5642 
5643   if (StringHasNoText (src_text))
5644   {
5645     src_text = MemFree (src_text);
5646     return;
5647   }
5648 
5649   if (cfp->convert_type == CONVERT_TYPE_SWAP)
5650   {
5651     /* for swap, we already know what we're doing with existing text -
5652      * we're putting it where the new text used to be. */
5653     avd.etp = NULL;
5654     /* and we need to get the destination text before it's replaced */
5655     dst_text = (cfp->get_str_func)(sfp, cfp->dst_field_list, cfp->fsp);
5656     if (cfp->strip_name_from_text)
5657     {
5658       StripFieldNameFromText(dst_text, cfp->name_field_func, cfp->src_field_list);
5659     }
5660   }
5661   else if (cfp->convert_type == CONVERT_TYPE_PARSE)
5662   {
5663     /* for parse, replace the source text with the portion we want */
5664     dst_text = src_text;
5665     src_text = ReplaceStringForParse(src_text, cfp->text_portion);
5666     if (src_text == NULL)
5667     {
5668       dst_text = MemFree (dst_text);
5669       return;
5670     }
5671     if (!cfp->remove_parsed) {
5672       dst_text = MemFree (dst_text);
5673     }
5674     avd.etp = cfp->etp;
5675   }
5676   else
5677   {
5678     avd.etp = cfp->etp;
5679   }
5680 
5681 
5682   /* put src_text in the dst_field */
5683   avd.field_list = cfp->dst_field_list;
5684   avd.new_text = src_text;
5685   (cfp->set_str_func) (sfp, &avd, cfp->fsp);
5686 
5687   if (cfp->convert_type == CONVERT_TYPE_SWAP
5688       || (cfp->convert_type == CONVERT_TYPE_PARSE && cfp->remove_parsed))
5689   {
5690     /* put dst_text in the src_field */
5691     avd.field_list = cfp->src_field_list;
5692     avd.new_text = dst_text;
5693     (cfp->set_str_func) (sfp, &avd, cfp->fsp);
5694   }
5695   else if (cfp->convert_type == CONVERT_TYPE_MOVE)
5696   {
5697     /* remove old src_field */
5698     avd.etp = NULL;
5699     avd.field_list = cfp->src_field_list;
5700     avd.new_text = NULL;
5701     (cfp->remove_str_func) (sfp, &avd, cfp->fsp);
5702   }
5703 }
5704 
ConvertDescriptorFieldCallback(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)5705 static void ConvertDescriptorFieldCallback (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
5706 {
5707   ConvertFieldPtr cfp;
5708   CharPtr         src_text;
5709   CharPtr         dst_text;
5710   ApplyValueData  avd;
5711 
5712   if (sdp == NULL || userdata == NULL)
5713   {
5714     return;
5715   }
5716 
5717   cfp = (ConvertFieldPtr) userdata;
5718 
5719   if (cfp->src_field_list == NULL || cfp->dst_field_list == NULL
5720       || cfp->get_d_str_func == NULL || cfp->set_d_str_func == NULL
5721       || cfp->remove_d_str_func == NULL)
5722   {
5723     return;
5724   }
5725 
5726   avd.text_to_replace = NULL;
5727   avd.where_to_replace = EditApplyFindLocation_anywhere;
5728   src_text = (cfp->get_d_str_func)(sdp, cfp->src_field_list, cfp->fsp);
5729   if (cfp->strip_name_from_text)
5730   {
5731     StripFieldNameFromText(src_text, cfp->name_field_func, cfp->dst_field_list);
5732   }
5733 
5734   if (StringHasNoText (src_text))
5735   {
5736     src_text = MemFree (src_text);
5737     return;
5738   }
5739 
5740   if (cfp->convert_type == CONVERT_TYPE_SWAP)
5741   {
5742     /* for swap, we already know what we're doing with existing text -
5743      * we're putting it where the new text used to be. */
5744     avd.etp = NULL;
5745     /* and we need to get the destination text before it's replaced */
5746     dst_text = (cfp->get_d_str_func)(sdp, cfp->dst_field_list, cfp->fsp);
5747     if (cfp->strip_name_from_text)
5748     {
5749       StripFieldNameFromText(dst_text, cfp->name_field_func, cfp->src_field_list);
5750     }
5751 
5752   }
5753   else if (cfp->convert_type == CONVERT_TYPE_PARSE)
5754   {
5755     /* for parse, replace the source text with the portion we want */
5756     dst_text = src_text;
5757     src_text = ReplaceStringForParse(src_text, cfp->text_portion);
5758     if (src_text == NULL)
5759     {
5760       dst_text = MemFree (dst_text);
5761       return;
5762     }
5763     if (!cfp->remove_parsed) {
5764       dst_text = MemFree (dst_text);
5765     }
5766     avd.etp = cfp->etp;
5767   }
5768   else
5769   {
5770     avd.etp = cfp->etp;
5771   }
5772 
5773   /* put src_text in the dst_field */
5774   avd.field_list = cfp->dst_field_list;
5775   avd.new_text = src_text;
5776   (cfp->set_d_str_func) (sdp, &avd, cfp->fsp);
5777 
5778   if (cfp->convert_type == CONVERT_TYPE_SWAP
5779       || (cfp->convert_type == CONVERT_TYPE_PARSE && cfp->remove_parsed))
5780   {
5781     /* put dst_text in the src_field */
5782     avd.etp = NULL;
5783     avd.field_list = cfp->src_field_list;
5784     avd.new_text = dst_text;
5785     (cfp->set_d_str_func) (sdp, &avd, cfp->fsp);
5786   }
5787   else if (cfp->convert_type == CONVERT_TYPE_MOVE)
5788   {
5789     /* remove old src_field */
5790     avd.etp = NULL;
5791     avd.field_list = cfp->src_field_list;
5792     avd.new_text = NULL;
5793     (cfp->remove_d_str_func) (sdp, &avd, cfp->fsp);
5794   }
5795 }
5796 
ConvertNonTextFeatureFieldCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)5797 static void ConvertNonTextFeatureFieldCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
5798 {
5799   ConvertFieldPtr cfp;
5800   CharPtr         curr_val = NULL;
5801   CharPtr         src_val;
5802   ApplyValueData  avd;
5803 
5804   if (sfp == NULL || userdata == NULL)
5805   {
5806     return;
5807   }
5808 
5809   cfp = (ConvertFieldPtr) userdata;
5810 
5811   if (cfp->src_field_list == NULL || cfp->dst_field_list == NULL
5812       || cfp->get_str_func == NULL || cfp->set_str_func == NULL
5813       || cfp->name_field_func == NULL)
5814   {
5815     return;
5816   }
5817 
5818   curr_val = (cfp->get_str_func)(sfp, NULL, NULL);
5819   src_val = (cfp->name_field_func)(cfp->src_field_list);
5820   if (StringCmp (curr_val, src_val) == 0)
5821   {
5822     avd.where_to_replace = EditApplyFindLocation_anywhere;
5823     avd.field_list = cfp->dst_field_list;
5824     avd.etp = NULL;
5825     (cfp->set_str_func) (sfp, &avd, cfp->fsp);
5826   }
5827   curr_val = MemFree (curr_val);
5828   src_val = MemFree (src_val);
5829 }
5830 
ConvertNonTextDescriptorFieldCallback(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)5831 static void ConvertNonTextDescriptorFieldCallback (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
5832 {
5833   ConvertFieldPtr cfp;
5834   CharPtr         curr_val = NULL;
5835   CharPtr         src_val;
5836   ApplyValueData  avd;
5837 
5838   if (sdp == NULL || userdata == NULL)
5839   {
5840     return;
5841   }
5842 
5843   cfp = (ConvertFieldPtr) userdata;
5844 
5845   if (cfp->src_field_list == NULL || cfp->dst_field_list == NULL
5846       || cfp->get_d_str_func == NULL || cfp->set_d_str_func == NULL
5847       || cfp->name_field_func == NULL)
5848   {
5849     return;
5850   }
5851 
5852   curr_val = (cfp->get_d_str_func)(sdp, NULL, NULL);
5853   src_val = (cfp->name_field_func)(cfp->src_field_list);
5854   if (StringCmp (curr_val, src_val) == 0)
5855   {
5856     avd.where_to_replace = EditApplyFindLocation_anywhere;
5857     avd.field_list = cfp->dst_field_list;
5858     avd.etp = NULL;
5859     (cfp->set_d_str_func) (sdp, &avd, cfp->fsp);
5860   }
5861   curr_val = MemFree (curr_val);
5862   src_val = MemFree (src_val);
5863 }
5864 
5865 #define FEATUREFIELD_NONE        0
5866 
5867 typedef struct featurefieldselection
5868 {
5869   DIALOG_MESSAGE_BLOCK
5870   PopuP                    feature_field;
5871 
5872   Boolean                  allow_none;
5873   Int4                     num_fields;
5874   Nlm_ChangeNotifyProc     change_notify;
5875   Pointer                  change_userdata;
5876 } FeatureFieldSelectionData, PNTR FeatureFieldSelectionPtr;
5877 
5878 
FeatureFieldSelectionChange(PopuP p)5879 static void FeatureFieldSelectionChange (PopuP p)
5880 {
5881   FeatureFieldSelectionPtr  dlg;
5882 
5883   dlg = (FeatureFieldSelectionPtr) GetObjectExtra (p);
5884   if (dlg == NULL)
5885   {
5886     return;
5887   }
5888   if (dlg->change_notify != NULL)
5889   {
5890     (dlg->change_notify) (dlg->change_userdata);
5891   }
5892 }
5893 
ResetFeatureFieldSelection(FeatureFieldSelectionPtr dlg)5894 static void ResetFeatureFieldSelection (FeatureFieldSelectionPtr dlg)
5895 {
5896   if (dlg == NULL)
5897   {
5898     return;
5899   }
5900   SetValue (dlg->feature_field, 1);
5901   FeatureFieldSelectionChange (dlg->feature_field);
5902 }
5903 
FeatureFieldToDialog(DialoG d,Pointer data)5904 static void FeatureFieldToDialog (DialoG d, Pointer data)
5905 {
5906   FeatureFieldSelectionPtr  dlg;
5907   ValNodePtr             vnp;
5908   Int4                   feature_field;
5909 
5910   dlg = (FeatureFieldSelectionPtr) GetObjectExtra (d);
5911   if (dlg == NULL)
5912   {
5913     return;
5914   }
5915 
5916   vnp = (ValNodePtr) data;
5917   if (vnp == NULL)
5918   {
5919     ResetFeatureFieldSelection (dlg);
5920   }
5921   else
5922   {
5923     feature_field = vnp->data.intvalue;
5924     if (feature_field < FEATUREFIELD_NONE || feature_field > dlg->num_fields + 1)
5925     {
5926       feature_field = FEATUREFIELD_NONE;
5927     }
5928     if (dlg->allow_none)
5929     {
5930       feature_field ++;
5931     }
5932     SetValue (dlg->feature_field, feature_field);
5933   }
5934 }
5935 
DialogToFeatureField(DialoG d)5936 static Pointer DialogToFeatureField (DialoG d)
5937 {
5938   FeatureFieldSelectionPtr  dlg;
5939   ValNodePtr             vnp = NULL;
5940   Int4                   feature_field;
5941 
5942   dlg = (FeatureFieldSelectionPtr) GetObjectExtra (d);
5943   if (dlg == NULL)
5944   {
5945     return NULL;
5946   }
5947 
5948   feature_field = GetValue (dlg->feature_field);
5949   if (dlg->allow_none)
5950   {
5951     feature_field --;
5952   }
5953   if (feature_field > FEATUREFIELD_NONE)
5954   {
5955     vnp = ValNodeNew (NULL);
5956     if (vnp != NULL)
5957     {
5958       vnp->data.intvalue = feature_field;
5959     }
5960   }
5961   return vnp;
5962 }
5963 
FeatureFieldMessage(DialoG d,Int2 mssg)5964 static void FeatureFieldMessage (DialoG d, Int2 mssg)
5965 
5966 {
5967   FeatureFieldSelectionPtr  dlg;
5968 
5969   dlg = (FeatureFieldSelectionPtr) GetObjectExtra (d);
5970   if (dlg != NULL) {
5971     switch (mssg) {
5972       case VIB_MSG_INIT :
5973         /* reset list */
5974         ResetFeatureFieldSelection (dlg);
5975         break;
5976       case VIB_MSG_ENTER :
5977         Select (dlg->feature_field);
5978         break;
5979       default :
5980         break;
5981     }
5982   }
5983 }
5984 
TestFeatureFieldDialog(DialoG d)5985 static ValNodePtr TestFeatureFieldDialog (DialoG d)
5986 
5987 {
5988   return NULL;
5989 }
5990 
FeatureFieldSelectionDialogEx(GrouP h,Boolean allow_none,CharPtr none_txt,Int4 num_fields,CharPtr PNTR field_names,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)5991 static DialoG FeatureFieldSelectionDialogEx
5992 (GrouP                    h,
5993  Boolean                  allow_none,
5994  CharPtr                  none_txt,
5995  Int4                     num_fields,
5996  CharPtr PNTR             field_names,
5997  Nlm_ChangeNotifyProc     change_notify,
5998  Pointer                  change_userdata)
5999 {
6000   FeatureFieldSelectionPtr  dlg;
6001   GrouP                     p;
6002   Int4                      k;
6003 
6004   dlg = (FeatureFieldSelectionPtr) MemNew (sizeof (FeatureFieldSelectionData));
6005   if (dlg == NULL)
6006   {
6007     return NULL;
6008   }
6009 
6010   p = HiddenGroup (h, 1, 0, NULL);
6011   SetObjectExtra (p, dlg, StdCleanupExtraProc);
6012 
6013   dlg->dialog = (DialoG) p;
6014   dlg->todialog = FeatureFieldToDialog;
6015   dlg->fromdialog = DialogToFeatureField;
6016   dlg->dialogmessage = FeatureFieldMessage;
6017   dlg->testdialog = TestFeatureFieldDialog;
6018   dlg->allow_none = allow_none;
6019   dlg->num_fields = num_fields;
6020   dlg->change_notify = change_notify;
6021   dlg->change_userdata = change_userdata;
6022 
6023   dlg->feature_field = PopupList (p, TRUE, FeatureFieldSelectionChange);
6024   if (dlg->allow_none)
6025   {
6026     PopupItem (dlg->feature_field, none_txt);
6027   }
6028   for (k = 0; k < dlg->num_fields; k++)
6029   {
6030     PopupItem (dlg->feature_field, field_names[k]);
6031   }
6032   SetValue (dlg->feature_field, 1);
6033   SetObjectExtra (dlg->feature_field, dlg, NULL);
6034   return (DialoG) p;
6035 }
6036 
6037 extern DialoG
FeatureFieldSelectionDialog(GrouP h,Boolean allow_none,Int4 num_fields,CharPtr PNTR field_names,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)6038 FeatureFieldSelectionDialog
6039 (GrouP                    h,
6040  Boolean                  allow_none,
6041  Int4                     num_fields,
6042  CharPtr PNTR             field_names,
6043  Nlm_ChangeNotifyProc     change_notify,
6044  Pointer                  change_userdata)
6045 {
6046   return FeatureFieldSelectionDialogEx (h, allow_none, "None",
6047                                         num_fields, field_names,
6048                                         change_notify, change_userdata);
6049 }
6050 
FeatureFieldSelectionDialogAny(GrouP h,Boolean allow_none,Int4 num_fields,CharPtr PNTR field_names,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)6051 static DialoG FeatureFieldSelectionDialogAny
6052 (GrouP                    h,
6053  Boolean                  allow_none,
6054  Int4                     num_fields,
6055  CharPtr PNTR             field_names,
6056  Nlm_ChangeNotifyProc     change_notify,
6057  Pointer                  change_userdata)
6058 {
6059   return FeatureFieldSelectionDialogEx (h, allow_none, "Any Field",
6060                                         num_fields, field_names,
6061                                         change_notify, change_userdata);
6062 }
6063 
6064 
6065 static CharPtr gene_field_list [] =
6066 {
6067   "locus", "description", "comment", "allele", "maploc", "locus_tag", "synonym", "old_locus_tag"
6068 };
6069 
6070 #define GENEFIELD_LOCUS         1
6071 #define GENEFIELD_DESCRIPTION   2
6072 #define GENEFIELD_COMMENT       3
6073 #define GENEFIELD_ALLELE        4
6074 #define GENEFIELD_MAPLOC        5
6075 #define GENEFIELD_LOCUS_TAG     6
6076 #define GENEFIELD_SYNONYM       7
6077 #define GENEFIELD_OLD_LOCUS_TAG 8
6078 
6079 static int num_gene_fields = sizeof (gene_field_list) / sizeof (CharPtr);
6080 
6081 extern DialoG
GeneFieldSelectionDialog(GrouP h,Boolean allow_none,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)6082 GeneFieldSelectionDialog
6083 (GrouP                    h,
6084  Boolean                  allow_none,
6085  Nlm_ChangeNotifyProc     change_notify,
6086  Pointer                  change_userdata)
6087 {
6088   return FeatureFieldSelectionDialog (h, allow_none,
6089                                       num_gene_fields, gene_field_list,
6090                                       change_notify, change_userdata);
6091 }
6092 
6093 extern CharPtr
GetGeneFieldString(SeqFeatPtr sfp,ValNodePtr gene_field,FilterSetPtr fsp)6094 GetGeneFieldString
6095 (SeqFeatPtr   sfp,
6096  ValNodePtr   gene_field,
6097  FilterSetPtr fsp)
6098 {
6099   ValNodePtr vnp;
6100   CharPtr    str = NULL;
6101   GeneRefPtr grp;
6102   GBQualPtr  qual;
6103 
6104   if (sfp == NULL || gene_field == NULL)
6105   {
6106     return NULL;
6107   }
6108 
6109   if (sfp->data.choice == SEQFEAT_GENE)
6110   {
6111     grp = (GeneRefPtr) sfp->data.value.ptrvalue;
6112   }
6113   else
6114   {
6115     grp = SeqMgrGetGeneXref (sfp);
6116   }
6117 
6118   if (sfp->data.choice != SEQFEAT_GENE && grp != NULL)
6119   {
6120     vnp = NULL;
6121   }
6122 
6123   vnp = gene_field;
6124   while (vnp != NULL && vnp->data.intvalue != FEATUREFIELD_NONE && StringHasNoText (str))
6125   {
6126     str = NULL;
6127     switch (vnp->data.intvalue)
6128     {
6129       case GENEFIELD_LOCUS:
6130         if (grp != NULL)
6131         {
6132           str = grp->locus;
6133         }
6134         break;
6135       case GENEFIELD_DESCRIPTION:
6136         if (grp != NULL)
6137         {
6138           str = grp->desc;
6139         }
6140         break;
6141       case GENEFIELD_COMMENT:
6142         if (sfp->data.choice == SEQFEAT_GENE)
6143         {
6144           str = sfp->comment;
6145         }
6146         break;
6147       case GENEFIELD_ALLELE:
6148         if (grp != NULL)
6149         {
6150           str = grp->allele;
6151         }
6152         break;
6153       case GENEFIELD_MAPLOC:
6154         if (grp != NULL)
6155         {
6156           str = grp->maploc;
6157         }
6158         break;
6159       case GENEFIELD_SYNONYM:
6160         if (grp != NULL && grp->syn != NULL)
6161         {
6162           str = grp->syn->data.ptrvalue;
6163         }
6164         break;
6165       case GENEFIELD_LOCUS_TAG:
6166         if (grp != NULL)
6167         {
6168           str = grp->locus_tag;
6169         }
6170         break;
6171       case GENEFIELD_OLD_LOCUS_TAG:
6172         qual = sfp->qual;
6173         while (qual != NULL && StringICmp (qual->qual, "old_locus_tag") != 0)
6174         {
6175           qual = qual->next;
6176         }
6177         if (qual != NULL)
6178         {
6179           str = qual->val;
6180         }
6181         break;
6182     }
6183     vnp = vnp->next;
6184   }
6185   if (StringHasNoText (str))
6186   {
6187     str = NULL;
6188   }
6189   else
6190   {
6191     str = StringSave (str);
6192   }
6193   return str;
6194 }
6195 
RemoveGeneFieldString(SeqFeatPtr sfp,ValNodePtr gene_field)6196 extern void RemoveGeneFieldString (SeqFeatPtr sfp, ValNodePtr gene_field)
6197 {
6198   ValNodePtr vnp;
6199   Boolean    found_nonempty = FALSE;
6200   GeneRefPtr grp;
6201   ValNodePtr syn_remove;
6202   GBQualPtr  qual, prevqual;
6203 
6204   if (sfp == NULL || gene_field == NULL)
6205   {
6206     return;
6207   }
6208 
6209   if (sfp->data.choice == SEQFEAT_GENE)
6210   {
6211     grp = (GeneRefPtr) sfp->data.value.ptrvalue;
6212   }
6213   else
6214   {
6215     grp = SeqMgrGetGeneXref (sfp);
6216   }
6217 
6218   if (grp == NULL)
6219   {
6220     return;
6221   }
6222 
6223   vnp = gene_field;
6224   while (vnp != NULL && vnp->data.intvalue != FEATUREFIELD_NONE && !found_nonempty)
6225   {
6226     switch (vnp->data.intvalue)
6227     {
6228       case GENEFIELD_LOCUS:
6229         if (grp != NULL && !StringHasNoText (grp->locus))
6230         {
6231           found_nonempty = TRUE;
6232           if (vnp->choice != 0)
6233           {
6234             grp->locus = MemFree (grp->locus);
6235           }
6236         }
6237         break;
6238       case GENEFIELD_DESCRIPTION:
6239         if (grp != NULL && !StringHasNoText (grp->desc))
6240         {
6241           found_nonempty = TRUE;
6242           if (vnp->choice != 0)
6243           {
6244             grp->desc = MemFree (grp->desc);
6245           }
6246         }
6247         break;
6248       case GENEFIELD_COMMENT:
6249         if (!StringHasNoText (sfp->comment))
6250         {
6251           found_nonempty = TRUE;
6252           if (vnp->choice != 0)
6253           {
6254             sfp->comment = MemFree (sfp->comment);
6255           }
6256         }
6257         break;
6258       case GENEFIELD_ALLELE:
6259         if (grp != NULL && !StringHasNoText (grp->allele))
6260         {
6261           found_nonempty = TRUE;
6262           if (vnp->choice != 0)
6263           {
6264             grp->allele = MemFree (grp->allele);
6265           }
6266         }
6267         break;
6268       case GENEFIELD_MAPLOC:
6269         if (grp != NULL && !StringHasNoText (grp->maploc))
6270         {
6271           found_nonempty = TRUE;
6272           if (vnp->choice != 0)
6273           {
6274             grp->maploc = MemFree (grp->maploc);
6275           }
6276         }
6277         break;
6278       case GENEFIELD_SYNONYM:
6279         if (grp != NULL && grp->syn != NULL && !StringHasNoText (grp->syn->data.ptrvalue))
6280         {
6281           found_nonempty = TRUE;
6282           if (vnp->choice != 0)
6283           {
6284             syn_remove = grp->syn;
6285             grp->syn = grp->syn->next;
6286             syn_remove->next = NULL;
6287             ValNodeFreeData (syn_remove);
6288           }
6289         }
6290         break;
6291       case GENEFIELD_LOCUS_TAG:
6292         if (grp != NULL && !StringHasNoText (grp->locus_tag))
6293         {
6294           found_nonempty = TRUE;
6295           if (vnp->choice != 0)
6296           {
6297             grp->locus_tag = MemFree (grp->locus_tag);
6298           }
6299         }
6300         break;
6301       case GENEFIELD_OLD_LOCUS_TAG:
6302         prevqual = NULL;
6303         qual = sfp->qual;
6304         while (qual != NULL)
6305         {
6306           if (StringICmp (qual->qual, "old_locus_tag") == 0)
6307           {
6308             if (prevqual == NULL)
6309             {
6310               sfp->qual = qual->next;
6311               qual->next = NULL;
6312               qual = GBQualFree (qual);
6313               qual = sfp->qual;
6314             }
6315             else
6316             {
6317               prevqual->next = qual->next;
6318               qual->next = NULL;
6319               qual = GBQualFree (qual);
6320               qual = prevqual->next;
6321             }
6322           }
6323           else
6324           {
6325             prevqual = qual;
6326             qual = qual->next;
6327           }
6328         }
6329         break;
6330     }
6331     vnp = vnp->next;
6332   }
6333 }
6334 
SetGeneFieldString(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)6335 static void SetGeneFieldString (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
6336 {
6337   GeneRefPtr    grp;
6338   ApplyValuePtr avp;
6339   Boolean       found;
6340   GBQualPtr     qual, qual_last;
6341 
6342   if (sfp == NULL || userdata == NULL)
6343   {
6344     return;
6345   }
6346   avp = (ApplyValuePtr) userdata;
6347   if (avp->field_list == NULL)
6348   {
6349     return;
6350   }
6351 
6352   if (sfp->data.choice == SEQFEAT_GENE)
6353   {
6354     grp = (GeneRefPtr) sfp->data.value.ptrvalue;
6355   }
6356   else
6357   {
6358     grp = SeqMgrGetGeneXref (sfp);
6359   }
6360 
6361   if (grp == NULL && sfp->data.choice == SEQFEAT_GENE)
6362   {
6363     grp = GeneRefNew ();
6364     sfp->data.value.ptrvalue = grp;
6365   }
6366 
6367   if (grp == NULL)
6368   {
6369     return;
6370   }
6371 
6372   switch (avp->field_list->data.intvalue)
6373   {
6374     case GENEFIELD_LOCUS:
6375       grp->locus = HandleApplyValue (grp->locus, avp);
6376       break;
6377     case GENEFIELD_DESCRIPTION:
6378       grp->desc = HandleApplyValue (grp->desc, avp);
6379       break;
6380     case GENEFIELD_COMMENT:
6381       sfp->comment = HandleApplyValue (sfp->comment, avp);
6382       break;
6383     case GENEFIELD_ALLELE:
6384       grp->allele = HandleApplyValue (grp->allele, avp);
6385       break;
6386     case GENEFIELD_MAPLOC:
6387       grp->maploc = HandleApplyValue (grp->maploc, avp);
6388       break;
6389     case GENEFIELD_SYNONYM:
6390       if (grp->syn == NULL || !StringHasNoText (avp->text_to_replace)) {
6391         grp->syn = ApplyValueToValNodeStringList (grp->syn, 0, avp);
6392       } else {
6393         grp->syn->data.ptrvalue = HandleApplyValue (grp->syn->data.ptrvalue, avp);
6394       }
6395       break;
6396     case GENEFIELD_LOCUS_TAG:
6397       grp->locus_tag = HandleApplyValue (grp->locus_tag, avp);
6398       break;
6399     case GENEFIELD_OLD_LOCUS_TAG:
6400       qual = sfp->qual;
6401       qual_last = NULL;
6402       found = FALSE;
6403       while (qual != NULL && !found)
6404       {
6405         qual_last = qual;
6406         if (StringCmp (qual->qual, "old_locus_tag") == 0)
6407         {
6408           qual->val = HandleApplyValue (qual->val, avp);
6409           found = TRUE;
6410         }
6411         qual = qual->next;
6412       }
6413       if (!found)
6414       {
6415         qual = GBQualNew ();
6416         if (qual != NULL)
6417         {
6418           qual->qual = StringSave ("old_locus_tag");
6419           qual->val = StringSave (avp->new_text);
6420           if (qual_last == NULL)
6421           {
6422             sfp->qual = qual;
6423           }
6424           else
6425           {
6426             qual_last->next = qual;
6427           }
6428         }
6429       }
6430       break;
6431   }
6432 }
6433 
6434 static CharPtr mrna_field_list [] =
6435 {
6436   "product", "comment"
6437 };
6438 
6439 #define MRNAFIELD_PRODUCT     1
6440 #define MRNAFIELD_COMMENT     2
6441 
6442 static int num_mrna_fields = sizeof (mrna_field_list) / sizeof (CharPtr);
6443 
6444 extern DialoG
MRNAFieldSelectionDialog(GrouP h,Boolean allow_none,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)6445 MRNAFieldSelectionDialog
6446 (GrouP                    h,
6447  Boolean                  allow_none,
6448  Nlm_ChangeNotifyProc     change_notify,
6449  Pointer                  change_userdata)
6450 {
6451   return FeatureFieldSelectionDialog (h, allow_none,
6452                                       num_mrna_fields, mrna_field_list,
6453                                       change_notify, change_userdata);
6454 }
6455 
6456 extern CharPtr
GetmRNAFieldString(SeqFeatPtr sfp,ValNodePtr mrna_field,FilterSetPtr fsp)6457 GetmRNAFieldString
6458 (SeqFeatPtr   sfp,
6459  ValNodePtr   mrna_field,
6460  FilterSetPtr fsp)
6461 {
6462   ValNodePtr vnp;
6463   CharPtr    str = NULL;
6464   RnaRefPtr  rrp;
6465 
6466   if (sfp == NULL || mrna_field == NULL || sfp->idx.subtype != FEATDEF_mRNA)
6467   {
6468     return NULL;
6469   }
6470 
6471   vnp = mrna_field;
6472   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
6473 
6474   while (vnp != NULL && vnp->data.intvalue != FEATUREFIELD_NONE && StringHasNoText (str))
6475   {
6476     str = NULL;
6477     switch (vnp->data.intvalue)
6478     {
6479       case MRNAFIELD_PRODUCT:
6480         if (rrp != NULL)
6481         {
6482           str = rrp->ext.value.ptrvalue;
6483         }
6484         break;
6485       case MRNAFIELD_COMMENT:
6486         str = sfp->comment;
6487         break;
6488     }
6489     vnp = vnp->next;
6490   }
6491   if (StringHasNoText (str))
6492   {
6493     str = NULL;
6494   }
6495   else
6496   {
6497     str = StringSave (str);
6498   }
6499   return str;
6500 }
6501 
RemovemRNAFieldString(SeqFeatPtr sfp,ValNodePtr mrna_field)6502 extern void RemovemRNAFieldString (SeqFeatPtr sfp, ValNodePtr mrna_field)
6503 {
6504   ValNodePtr vnp;
6505   Boolean    found_nonempty = FALSE;
6506   RnaRefPtr  rrp;
6507 
6508   if (sfp == NULL || mrna_field == NULL || sfp->idx.subtype != FEATDEF_mRNA)
6509   {
6510     return;
6511   }
6512 
6513   vnp = mrna_field;
6514   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
6515   while (vnp != NULL && vnp->data.intvalue != FEATUREFIELD_NONE && !found_nonempty)
6516   {
6517     switch (vnp->data.intvalue)
6518     {
6519       case MRNAFIELD_PRODUCT:
6520         if (rrp != NULL && !StringHasNoText (rrp->ext.value.ptrvalue))
6521         {
6522           found_nonempty = TRUE;
6523           if (vnp->choice != 0)
6524           {
6525             rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
6526           }
6527         }
6528         break;
6529       case MRNAFIELD_COMMENT:
6530         if (!StringHasNoText (sfp->comment))
6531         {
6532           found_nonempty = TRUE;
6533           if (vnp->choice != 0)
6534           {
6535             sfp->comment = MemFree (sfp->comment);
6536           }
6537         }
6538         break;
6539     }
6540     vnp = vnp->next;
6541   }
6542 }
6543 
SetmRNAFieldString(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)6544 static void SetmRNAFieldString (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
6545 {
6546   RnaRefPtr     rrp;
6547   ApplyValuePtr avp;
6548   Int4          field_choice;
6549 
6550   if (sfp == NULL || userdata == NULL || sfp->idx.subtype != FEATDEF_mRNA)
6551   {
6552     return;
6553   }
6554 
6555   avp = (ApplyValuePtr) userdata;
6556   if (avp->field_list == NULL)
6557   {
6558     return;
6559   }
6560 
6561   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
6562   if (rrp == NULL)
6563   {
6564     rrp = RnaRefNew ();
6565     if (rrp == NULL)
6566     {
6567       return;
6568     }
6569     sfp->data.value.ptrvalue = rrp;
6570   }
6571   field_choice = avp->field_list->data.intvalue;
6572   switch (avp->field_list->data.intvalue)
6573   {
6574     case MRNAFIELD_PRODUCT:
6575       if (rrp->ext.choice == 0)
6576       {
6577         rrp->ext.choice = 1;
6578         rrp->ext.value.ptrvalue = NULL;
6579       }
6580       rrp->ext.value.ptrvalue = HandleApplyValue (rrp->ext.value.ptrvalue, avp);
6581       break;
6582     case MRNAFIELD_COMMENT:
6583       sfp->comment = HandleApplyValue (sfp->comment,avp);
6584       break;
6585   }
6586 }
6587 
GetCDSComment(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)6588 static CharPtr GetCDSComment (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
6589 {
6590   if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION || StringHasNoText (sfp->comment))
6591   {
6592     return NULL;
6593   }
6594   else
6595   {
6596     return StringSave (sfp->comment);
6597   }
6598 }
6599 
SetCDSComment(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)6600 static void SetCDSComment (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
6601 {
6602   ApplyValuePtr avp;
6603 
6604   if (sfp == NULL || userdata == NULL || sfp->data.choice != SEQFEAT_CDREGION)
6605   {
6606     return;
6607   }
6608 
6609   avp = (ApplyValuePtr) userdata;
6610 
6611   sfp->comment = HandleApplyValue (sfp->comment, avp);
6612 }
6613 
RemoveCDSComment(SeqFeatPtr sfp,ValNodePtr vnp)6614 static void RemoveCDSComment (SeqFeatPtr sfp, ValNodePtr vnp)
6615 {
6616   if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION)
6617   {
6618     return;
6619   }
6620   sfp->comment = MemFree (sfp->comment);
6621 }
6622 
6623 extern CharPtr
GetCDSFieldString(SeqFeatPtr sfp,ValNodePtr cds_field,FilterSetPtr fsp)6624 GetCDSFieldString
6625 (SeqFeatPtr   sfp,
6626  ValNodePtr   cds_field,
6627  FilterSetPtr fsp)
6628 {
6629   ValNodePtr vnp;
6630   CharPtr    str = NULL;
6631   BioseqPtr  prot_bsp;
6632   SeqFeatPtr prot_sfp;
6633   SeqMgrFeatContext prot_context;
6634   ProtRefPtr        prp;
6635 
6636   if (sfp == NULL || cds_field == NULL || sfp->idx.subtype != FEATDEF_CDS)
6637   {
6638     return NULL;
6639   }
6640 
6641   vnp = cds_field;
6642 
6643   while (vnp != NULL && vnp->data.intvalue != FEATUREFIELD_NONE && StringHasNoText (str))
6644   {
6645     str = NULL;
6646     switch (vnp->data.intvalue)
6647     {
6648       case MRNAFIELD_PRODUCT:
6649         prot_bsp = BioseqFind (SeqLocId (sfp->product));
6650         prot_sfp = SeqMgrGetNextFeature (prot_bsp, NULL, SEQFEAT_PROT, 0, &prot_context);
6651         if (prot_sfp != NULL && prot_sfp->data.value.ptrvalue != NULL) {
6652           prp = (ProtRefPtr) prot_sfp->data.value.ptrvalue;
6653           if (prp->name != NULL && !StringHasNoText (prp->name->data.ptrvalue)) {
6654             str = prp->name->data.ptrvalue;
6655           }
6656         }
6657         break;
6658       case MRNAFIELD_COMMENT:
6659         str = sfp->comment;
6660         break;
6661     }
6662     vnp = vnp->next;
6663   }
6664   if (StringHasNoText (str))
6665   {
6666     str = NULL;
6667   }
6668   else
6669   {
6670     str = StringSave (str);
6671   }
6672   return str;
6673 }
6674 
RemoveCDSFieldString(SeqFeatPtr sfp,ValNodePtr cds_field)6675 extern void RemoveCDSFieldString (SeqFeatPtr sfp, ValNodePtr cds_field)
6676 {
6677   ValNodePtr vnp;
6678   Boolean    found_nonempty = FALSE;
6679   BioseqPtr  prot_bsp;
6680   SeqFeatPtr prot_sfp;
6681   SeqMgrFeatContext prot_context;
6682   ProtRefPtr        prp;
6683 
6684   if (sfp == NULL || cds_field == NULL || sfp->idx.subtype != FEATDEF_CDS)
6685   {
6686     return;
6687   }
6688 
6689   vnp = cds_field;
6690   while (vnp != NULL && vnp->data.intvalue != FEATUREFIELD_NONE && !found_nonempty)
6691   {
6692     switch (vnp->data.intvalue)
6693     {
6694       case MRNAFIELD_PRODUCT:
6695         prot_bsp = BioseqFind (SeqLocId (sfp->product));
6696         prot_sfp = SeqMgrGetNextFeature (prot_bsp, NULL, SEQFEAT_PROT, 0, &prot_context);
6697         if (prot_sfp != NULL && prot_sfp->data.value.ptrvalue != NULL) {
6698           prp = (ProtRefPtr) prot_sfp->data.value.ptrvalue;
6699           if (prp->name != NULL && !StringHasNoText (prp->name->data.ptrvalue)) {
6700             found_nonempty = TRUE;
6701             if (vnp->choice != 0) {
6702               prp->name = ValNodeFreeData (prp->name);
6703             }
6704           }
6705         }
6706         break;
6707       case MRNAFIELD_COMMENT:
6708         if (!StringHasNoText (sfp->comment))
6709         {
6710           found_nonempty = TRUE;
6711           if (vnp->choice != 0)
6712           {
6713             sfp->comment = MemFree (sfp->comment);
6714           }
6715         }
6716         break;
6717     }
6718     vnp = vnp->next;
6719   }
6720 }
6721 
6722 #define PROTEINFIELD_NAME               1
6723 #define PROTEINFIELD_DESC               2
6724 #define PROTEINFIELD_EC_NUM             3
6725 #define PROTEINFIELD_ACTIVITY           4
6726 #define PROTEINFIELD_COMMENT            5
6727 #define PROTEINFIELD_MATPEPTIDE_NAME    6
6728 #define PROTEINFIELD_MATPEPTIDE_DESC    7
6729 #define PROTEINFIELD_MATPEPTIDE_COMMENT 8
6730 
6731 static CharPtr protein_field_list [] =
6732 {
6733   "name", "description", "E.C. number", "activity", "comment", "mat_peptide name", "mat_peptide description", "mat_peptide comment"
6734 };
6735 
6736 static int num_protein_fields = sizeof (protein_field_list) / sizeof (CharPtr);
6737 
6738 extern DialoG
ProteinFieldSelectionDialog(GrouP h,Boolean allow_none,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)6739 ProteinFieldSelectionDialog
6740 (GrouP                    h,
6741  Boolean                  allow_none,
6742  Nlm_ChangeNotifyProc     change_notify,
6743  Pointer                  change_userdata)
6744 {
6745   return FeatureFieldSelectionDialog (h, allow_none,
6746                                       num_protein_fields, protein_field_list,
6747                                       change_notify, change_userdata);
6748 }
6749 
GetProteinFieldString(SeqFeatPtr sfp,ValNodePtr protein_field,FilterSetPtr fsp)6750 extern CharPtr GetProteinFieldString (SeqFeatPtr sfp, ValNodePtr protein_field, FilterSetPtr fsp)
6751 {
6752   ValNodePtr     vnp, val_vnp;
6753   CharPtr        str = NULL;
6754   ProtRefPtr     prp = NULL;
6755   Int4           field_choice;
6756   SeqFeatXrefPtr xref;
6757 
6758   if (sfp == NULL || protein_field == NULL || (sfp->data.choice != SEQFEAT_PROT && sfp->data.choice != SEQFEAT_CDREGION))
6759   {
6760     return NULL;
6761   }
6762 
6763   vnp = protein_field;
6764   if (sfp->data.choice == SEQFEAT_PROT) {
6765       prp = (ProtRefPtr) sfp->data.value.ptrvalue;
6766   } else if (sfp->data.choice == SEQFEAT_CDREGION) {
6767       xref = sfp->xref;
6768       while (xref != NULL && xref->data.choice != SEQFEAT_PROT) {
6769           xref = xref->next;
6770       }
6771       if (xref != NULL) {
6772           prp = xref->data.value.ptrvalue;
6773       }
6774   }
6775 
6776 
6777   while (vnp != NULL && vnp->data.intvalue != FEATUREFIELD_NONE && StringHasNoText (str))
6778   {
6779     str = NULL;
6780     field_choice = vnp->data.intvalue;
6781     switch (field_choice)
6782     {
6783       case PROTEINFIELD_NAME:
6784         if (prp != NULL && prp->name != NULL && (sfp->idx.subtype == FEATDEF_PROT || sfp->idx.subtype == FEATDEF_CDS))
6785         {
6786           val_vnp = prp->name;
6787           str = val_vnp->data.ptrvalue;
6788         }
6789         break;
6790       case PROTEINFIELD_DESC:
6791         if (prp != NULL && sfp->idx.subtype == FEATDEF_PROT)
6792         {
6793           str = prp->desc;
6794         }
6795         break;
6796       case PROTEINFIELD_EC_NUM:
6797         if (prp != NULL && prp->ec != NULL && sfp->idx.subtype == FEATDEF_PROT)
6798         {
6799           val_vnp = prp->ec;
6800           str = val_vnp->data.ptrvalue;
6801         }
6802         break;
6803       case PROTEINFIELD_ACTIVITY:
6804         if (prp != NULL && prp->activity != NULL && sfp->idx.subtype == FEATDEF_PROT)
6805         {
6806           val_vnp = prp->activity;
6807           str = val_vnp->data.ptrvalue;
6808         }
6809         break;
6810       case PROTEINFIELD_COMMENT:
6811         if (sfp->idx.subtype == FEATDEF_PROT)
6812         {
6813           str = sfp->comment;
6814         }
6815         break;
6816       case PROTEINFIELD_MATPEPTIDE_NAME:
6817         if (prp != NULL && prp->name != NULL && sfp->idx.subtype == FEATDEF_mat_peptide_aa)
6818         {
6819           val_vnp = prp->name;
6820           str = val_vnp->data.ptrvalue;
6821         }
6822         break;
6823       case PROTEINFIELD_MATPEPTIDE_DESC:
6824         if (sfp->idx.subtype == FEATDEF_mat_peptide_aa && prp != NULL)
6825         {
6826            str = prp->desc;
6827         }
6828         break;
6829       case PROTEINFIELD_MATPEPTIDE_COMMENT:
6830         if (sfp->idx.subtype == FEATDEF_mat_peptide_aa)
6831         {
6832           str = sfp->comment;
6833         }
6834         break;
6835     }
6836     vnp = vnp->next;
6837   }
6838   if (StringHasNoText (str))
6839   {
6840     str = NULL;
6841   }
6842   else
6843   {
6844     str = StringSave (str);
6845   }
6846   return str;
6847 }
6848 
RemoveProteinFieldString(SeqFeatPtr sfp,ValNodePtr protein_field)6849 static void RemoveProteinFieldString (SeqFeatPtr sfp, ValNodePtr protein_field)
6850 {
6851   ValNodePtr vnp;
6852   ProtRefPtr prp = NULL;
6853   Int4       field_choice;
6854   SeqFeatXrefPtr xref = NULL, prev;
6855 
6856   if (sfp == NULL || protein_field == NULL)
6857   {
6858     return;
6859   }
6860 
6861   vnp = protein_field;
6862   if (sfp->idx.subtype == FEATDEF_PROT
6863       || sfp->idx.subtype == FEATDEF_mat_peptide_aa) {
6864       prp = (ProtRefPtr) sfp->data.value.ptrvalue;
6865   } else if (sfp->idx.subtype == FEATDEF_CDS) {
6866       xref = sfp->xref;
6867       while (xref != NULL && xref->data.choice != SEQFEAT_PROT) {
6868           xref = xref->next;
6869       }
6870       if (xref != NULL) {
6871           prp = xref->data.value.ptrvalue;
6872       }
6873   }
6874 
6875   while (vnp != NULL && vnp->data.intvalue != FEATUREFIELD_NONE)
6876   {
6877     field_choice = vnp->data.intvalue;
6878     switch (field_choice)
6879     {
6880       case PROTEINFIELD_NAME:
6881         if (prp != NULL && prp->name != NULL && sfp->idx.subtype == FEATDEF_PROT)
6882         {
6883           prp->name = ValNodeFreeData (prp->name);
6884         }
6885         break;
6886       case PROTEINFIELD_DESC:
6887         if (prp != NULL && sfp->idx.subtype == FEATDEF_PROT)
6888         {
6889           prp->desc = MemFree (prp->desc);
6890         }
6891         break;
6892       case PROTEINFIELD_EC_NUM:
6893         if (prp != NULL && prp->ec != NULL && sfp->idx.subtype == FEATDEF_PROT)
6894         {
6895           prp->ec = ValNodeFreeData (prp->ec);
6896         }
6897         break;
6898       case PROTEINFIELD_ACTIVITY:
6899         if (prp != NULL && prp->activity != NULL && sfp->idx.subtype == FEATDEF_PROT)
6900         {
6901           prp->activity = ValNodeFreeData (prp->activity);
6902         }
6903         break;
6904       case PROTEINFIELD_COMMENT:
6905         if (sfp->idx.subtype == FEATDEF_PROT)
6906         {
6907           sfp->comment = MemFree (sfp->comment);
6908         }
6909         break;
6910       case PROTEINFIELD_MATPEPTIDE_NAME:
6911         if (prp != NULL && prp->name != NULL && sfp->idx.subtype == FEATDEF_mat_peptide_aa)
6912         {
6913           prp->name = ValNodeFreeData (prp->name);
6914         }
6915         break;
6916       case PROTEINFIELD_MATPEPTIDE_DESC:
6917         if (prp != NULL && sfp->idx.subtype == FEATDEF_mat_peptide_aa)
6918         {
6919           prp->desc = MemFree (prp->desc);
6920         }
6921         break;
6922       case PROTEINFIELD_MATPEPTIDE_COMMENT:
6923         if (sfp->idx.subtype == FEATDEF_mat_peptide_aa)
6924         {
6925           sfp->comment = MemFree (sfp->comment);
6926         }
6927         break;
6928     }
6929     vnp = vnp->next;
6930   }
6931 
6932   /* remove protein xref if empty */
6933   if (prp != NULL && xref != NULL
6934       && prp->name == NULL
6935       && StringHasNoText (prp->desc)
6936       && prp->ec == NULL
6937       && prp->activity == NULL
6938       && prp->db == NULL) {
6939     prp = ProtRefFree(prp);
6940     xref->data.value.ptrvalue = NULL;
6941     if (sfp->xref == xref) {
6942         sfp->xref = xref->next;
6943     } else {
6944         prev = sfp->xref;
6945         while (prev != NULL && prev->next != xref) {
6946             prev = prev->next;
6947         }
6948         if (prev != NULL) {
6949             prev->next = xref->next;
6950         }
6951     }
6952     xref = SeqFeatXrefFree(xref);
6953   }
6954 }
6955 
6956 extern ValNodePtr ApplyValueToValNodeStringListAsText (ValNodePtr list, Int2 choice, ApplyValuePtr avp);
6957 
SetProteinFieldString(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)6958 static void SetProteinFieldString (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
6959 {
6960   ProtRefPtr    prp;
6961   ApplyValuePtr avp;
6962 
6963   if (sfp == NULL || userdata == NULL)
6964   {
6965     return;
6966   }
6967   if (sfp->idx.subtype != FEATDEF_PROT && sfp->idx.subtype != FEATDEF_mat_peptide_aa)
6968   {
6969     return;
6970   }
6971 
6972   avp = (ApplyValuePtr) userdata;
6973   if (avp->field_list == NULL)
6974   {
6975     return;
6976   }
6977 
6978   if (sfp->idx.subtype == FEATDEF_PROT)
6979   {
6980     if (avp->field_list->data.intvalue == PROTEINFIELD_MATPEPTIDE_NAME
6981         || avp->field_list->data.intvalue == PROTEINFIELD_MATPEPTIDE_DESC
6982         || avp->field_list->data.intvalue == PROTEINFIELD_MATPEPTIDE_COMMENT)
6983     {
6984       return;
6985     }
6986   }
6987   else if (sfp->idx.subtype == FEATDEF_mat_peptide_aa)
6988   {
6989     if (avp->field_list->data.intvalue != PROTEINFIELD_MATPEPTIDE_NAME
6990         && avp->field_list->data.intvalue != PROTEINFIELD_MATPEPTIDE_DESC
6991         && avp->field_list->data.intvalue != PROTEINFIELD_MATPEPTIDE_COMMENT)
6992     {
6993       return;
6994     }
6995   }
6996   else
6997   {
6998     return;
6999   }
7000 
7001   prp = (ProtRefPtr) sfp->data.value.ptrvalue;
7002   if (prp == NULL)
7003   {
7004     prp = ProtRefNew ();
7005     if (prp == NULL)
7006     {
7007       return;
7008     }
7009     sfp->data.value.ptrvalue = prp;
7010   }
7011 
7012   switch (avp->field_list->data.intvalue)
7013   {
7014     case PROTEINFIELD_NAME:
7015     case PROTEINFIELD_MATPEPTIDE_NAME:
7016       if (prp->name == NULL || !StringHasNoText(avp->text_to_replace))
7017       {
7018         prp->name = ApplyValueToValNodeStringList (prp->name, 0, avp);
7019       }
7020       else
7021       {
7022         prp->name->data.ptrvalue = HandleApplyValue (prp->name->data.ptrvalue, avp);
7023       }
7024       break;
7025     case PROTEINFIELD_DESC:
7026     case PROTEINFIELD_MATPEPTIDE_DESC:
7027       prp->desc = HandleApplyValue (prp->desc, avp);
7028       break;
7029     case PROTEINFIELD_EC_NUM:
7030       prp->ec = ApplyValueToValNodeStringListAsText (prp->ec, 0, avp);
7031       break;
7032     case PROTEINFIELD_ACTIVITY:
7033       if (prp->activity == NULL || !StringHasNoText(avp->text_to_replace))
7034       {
7035         prp->activity = ApplyValueToValNodeStringList (prp->activity, 0, avp);
7036       }
7037       else
7038       {
7039         prp->activity->data.ptrvalue = HandleApplyValue (prp->activity->data.ptrvalue, avp);
7040       }
7041       break;
7042     case PROTEINFIELD_COMMENT:
7043     case PROTEINFIELD_MATPEPTIDE_COMMENT:
7044       sfp->comment = HandleApplyValue (sfp->comment, avp);
7045       break;
7046   }
7047 }
7048 
BuildCDSGeneFieldList(Int4Ptr num_fields)7049 static CharPtr PNTR BuildCDSGeneFieldList (Int4Ptr num_fields)
7050 {
7051   CharPtr PNTR field_name_list;
7052   Int4         i, k;
7053   Char         tmp[100];
7054 
7055   if (num_fields == NULL)
7056   {
7057     return NULL;
7058   }
7059   *num_fields = 1 + num_gene_fields + num_mrna_fields + num_protein_fields;
7060   field_name_list = (CharPtr PNTR) MemNew (*num_fields * sizeof (CharPtr));
7061   if (field_name_list == NULL)
7062   {
7063     return NULL;
7064   }
7065 
7066   field_name_list [0] = StringSave ("CDS comment");
7067   k = 1;
7068   for (i = 0; i < num_gene_fields; i++)
7069   {
7070     sprintf (tmp, "Gene %s", gene_field_list [i]);
7071     field_name_list [k++] = StringSave (tmp);
7072   }
7073   for (i = 0; i < num_mrna_fields; i++)
7074   {
7075     sprintf (tmp, "mRNA %s", mrna_field_list [i]);
7076     field_name_list [k++] = StringSave (tmp);
7077   }
7078   for (i = 0; i < num_protein_fields; i++)
7079   {
7080     if (StringNCmp (protein_field_list [i], "mat_peptide", 11) == 0)
7081     {
7082       sprintf (tmp, "%s", protein_field_list [i]);
7083       tmp [0] = toupper (tmp [0]);
7084     }
7085     else
7086     {
7087       sprintf (tmp, "Protein %s", protein_field_list [i]);
7088     }
7089     field_name_list [k++] = StringSave (tmp);
7090   }
7091   return field_name_list;
7092 }
7093 
FreeCDSGeneFieldList(CharPtr PNTR field_name_list,Int4 num_fields)7094 static void FreeCDSGeneFieldList (CharPtr PNTR field_name_list, Int4 num_fields)
7095 {
7096   Int4 i;
7097 
7098   if (field_name_list == NULL || num_fields == 0)
7099   {
7100     return;
7101   }
7102 
7103   for (i = 0; i < num_fields; i++)
7104   {
7105     field_name_list [i] = MemFree (field_name_list [i]);
7106   }
7107   field_name_list = MemFree (field_name_list);
7108 }
7109 
7110 extern DialoG
CDSGeneProtFieldSelectionDialog(GrouP h,Boolean allow_none,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)7111 CDSGeneProtFieldSelectionDialog
7112 (GrouP                    h,
7113  Boolean                  allow_none,
7114  Nlm_ChangeNotifyProc     change_notify,
7115  Pointer                  change_userdata)
7116 {
7117   CharPtr PNTR field_name_list;
7118   Int4         num_fields = 0;
7119   DialoG       d;
7120 
7121   field_name_list = BuildCDSGeneFieldList (&num_fields);
7122 
7123   d = FeatureFieldSelectionDialog (h, allow_none,
7124                                       num_fields, field_name_list,
7125                                       change_notify, change_userdata);
7126   FreeCDSGeneFieldList (field_name_list, num_fields);
7127   return d;
7128 }
7129 
7130 static DialoG
CDSGeneProtFieldConstraintSelectionDialog(GrouP h,Boolean allow_none,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)7131 CDSGeneProtFieldConstraintSelectionDialog
7132 (GrouP                    h,
7133  Boolean                  allow_none,
7134  Nlm_ChangeNotifyProc     change_notify,
7135  Pointer                  change_userdata)
7136 {
7137   CharPtr PNTR field_name_list;
7138   Int4         num_fields = 0;
7139   DialoG       d;
7140 
7141   field_name_list = BuildCDSGeneFieldList (&num_fields);
7142 
7143   d = FeatureFieldSelectionDialogAny (h, allow_none,
7144                                       num_fields, field_name_list,
7145                                       change_notify, change_userdata);
7146   FreeCDSGeneFieldList (field_name_list, num_fields);
7147   return d;
7148 }
7149 
7150 
IsCDSetProteinProductChoice(ValNodePtr vnp)7151 extern Boolean IsCDSetProteinProductChoice (ValNodePtr vnp)
7152 {
7153   if (vnp != NULL && vnp->data.intvalue == 2 + num_gene_fields + num_mrna_fields) {
7154     return TRUE;
7155   } else {
7156     return FALSE;
7157   }
7158 }
7159 
7160 
IsCDSetProteinQualChoice(ValNodePtr vnp)7161 static Boolean IsCDSetProteinQualChoice (ValNodePtr vnp)
7162 {
7163   if (vnp != NULL
7164       && vnp->data.intvalue > 1 + num_gene_fields + num_mrna_fields
7165       && vnp->data.intvalue <= 1 + num_gene_fields + num_mrna_fields + num_protein_fields)
7166   {
7167     return TRUE;
7168   }
7169   else
7170   {
7171     return FALSE;
7172   }
7173 }
7174 
IsCDSetMatPeptideQualChoice(ValNodePtr vnp)7175 static Boolean IsCDSetMatPeptideQualChoice (ValNodePtr vnp)
7176 {
7177   if (IsCDSetProteinQualChoice (vnp)
7178       && StringNICmp (protein_field_list[vnp->data.intvalue - num_gene_fields - num_mrna_fields - 2],
7179                       "mat_peptide", 11) == 0)
7180   {
7181     return TRUE;
7182   }
7183   else
7184   {
7185     return FALSE;
7186   }
7187 }
7188 
IsCDSetMRNAQualChoice(ValNodePtr vnp)7189 static Boolean IsCDSetMRNAQualChoice (ValNodePtr vnp)
7190 {
7191   if (vnp != NULL
7192       && vnp->data.intvalue > 1 + num_gene_fields
7193       && vnp->data.intvalue <= 1 + num_gene_fields + num_mrna_fields)
7194   {
7195     return TRUE;
7196   }
7197   else
7198   {
7199     return FALSE;
7200   }
7201 }
7202 
IsCDSetGeneQualChoice(ValNodePtr vnp)7203 static Boolean IsCDSetGeneQualChoice (ValNodePtr vnp)
7204 {
7205   if (vnp != NULL
7206       && vnp->data.intvalue > 1
7207       && vnp->data.intvalue <= 1 + num_gene_fields)
7208   {
7209     return TRUE;
7210   }
7211   else
7212   {
7213     return FALSE;
7214   }
7215 }
7216 
IsCDSetCDSQualChoice(ValNodePtr vnp)7217 static Boolean IsCDSetCDSQualChoice (ValNodePtr vnp)
7218 {
7219   if (vnp != NULL && vnp->data.intvalue == 1)
7220   {
7221     return TRUE;
7222   }
7223   else
7224   {
7225     return FALSE;
7226   }
7227 }
7228 
GetCDSGeneProtField(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)7229 extern CharPtr GetCDSGeneProtField (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
7230 {
7231   CharPtr str = NULL;
7232   ValNode vn;
7233   Int4    field_choice;
7234 
7235   if (sfp == NULL || vnp == NULL)
7236   {
7237     return NULL;
7238   }
7239 
7240   while (vnp != NULL && str == NULL)
7241   {
7242     vn.choice = vnp->choice;
7243     vn.next = NULL;
7244 
7245     field_choice = vnp->data.intvalue;
7246 
7247     if (IsCDSetCDSQualChoice(vnp))
7248     {
7249       /* CDS Comment */
7250       str = GetCDSComment (sfp, NULL, NULL);
7251     }
7252     else if (IsCDSetGeneQualChoice (vnp))
7253     {
7254       vn.data.intvalue = vnp->data.intvalue - 1;
7255       str = GetGeneFieldString (sfp, &vn, NULL);
7256     }
7257     else if (IsCDSetMRNAQualChoice (vnp))
7258     {
7259       vn.data.intvalue = vnp->data.intvalue - num_gene_fields - 1;
7260       str = GetmRNAFieldString (sfp, &vn, NULL);
7261     }
7262     else if (IsCDSetProteinQualChoice (vnp))
7263     {
7264       vn.data.intvalue = vnp->data.intvalue - num_gene_fields - num_mrna_fields - 1;
7265       str = GetProteinFieldString (sfp, &vn, NULL);
7266     }
7267     vnp = vnp->next;
7268   }
7269   return str;
7270 }
7271 
7272 /* we could have multiple mat_peptides in a CDSset, some that match the constraint and some that do not */
DoesConstraintDisqualifyFeature(SeqFeatPtr sfp,ChoiceConstraintPtr ccp)7273 static Boolean DoesConstraintDisqualifyFeature (SeqFeatPtr sfp, ChoiceConstraintPtr ccp)
7274 {
7275   Boolean is_disqualified = FALSE;
7276   Boolean does_match = FALSE;
7277   CharPtr str;
7278 
7279   if (sfp == NULL || ccp == NULL
7280       || ccp->constraint_type == CHOICE_CONSTRAINT_ANY
7281       || sfp->idx.subtype != FEATDEF_mat_peptide_aa
7282       || !IsCDSetMatPeptideQualChoice(ccp->qual_choice))
7283   {
7284     is_disqualified = FALSE;
7285   }
7286   else if (ccp->constraint_type == CHOICE_CONSTRAINT_QUAL_PRESENT && ccp->qual_choice != NULL)
7287   {
7288     str = GetCDSGeneProtField (sfp, ccp->qual_choice, NULL);
7289     if (str == NULL)
7290     {
7291       is_disqualified = TRUE;
7292     }
7293     MemFree (str);
7294   }
7295   else if (ccp->constraint_type == CHOICE_CONSTRAINT_STRING)
7296   {
7297     str = GetCDSGeneProtField (sfp, ccp->qual_choice, NULL);
7298     does_match = DoesStringMatchConstraintX (str, ccp->string_constraint);
7299     MemFree (str);
7300     if (ccp->string_constraint != NULL && ccp->string_constraint->not_present)
7301     {
7302       does_match = ! does_match;
7303     }
7304     if (!does_match)
7305     {
7306       is_disqualified = TRUE;
7307     }
7308   }
7309   return is_disqualified;
7310 
7311 }
7312 
RemoveCDSGeneProtField(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)7313 extern void RemoveCDSGeneProtField (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
7314 {
7315   ValNode vn;
7316 
7317   if (sfp == NULL || vnp == NULL)
7318   {
7319     return;
7320   }
7321 
7322   if (fsp != NULL && fsp->cgp != NULL && DoesConstraintDisqualifyFeature (sfp, fsp->cgp))
7323   {
7324     return;
7325   }
7326 
7327   while (vnp != NULL)
7328   {
7329     vn.choice = vnp->choice;
7330     vn.next = NULL;
7331 
7332     if (vnp->data.intvalue == 1)
7333     {
7334       /* CDS Comment */
7335       RemoveCDSComment (sfp, NULL);
7336     }
7337     else if (vnp->data.intvalue <= 1 + num_gene_fields)
7338     {
7339       vn.data.intvalue = vnp->data.intvalue - 1;
7340       RemoveGeneFieldString (sfp, &vn);
7341     }
7342     else if (vnp->data.intvalue <= 1 + num_gene_fields + num_mrna_fields)
7343     {
7344       vn.data.intvalue = vnp->data.intvalue - num_gene_fields - 1;
7345       RemovemRNAFieldString (sfp, &vn);
7346     }
7347     else if (vnp->data.intvalue <= 1 + num_gene_fields + num_mrna_fields + num_protein_fields)
7348     {
7349       vn.data.intvalue = vnp->data.intvalue - num_gene_fields - num_mrna_fields - 1;
7350       RemoveProteinFieldString (sfp, &vn);
7351     }
7352     vnp = vnp->next;
7353   }
7354 }
7355 
7356 
FeatDefTypeFromFieldList(ValNodePtr vnp)7357 extern Uint2 FeatDefTypeFromFieldList (ValNodePtr vnp)
7358 {
7359   if (vnp == NULL)
7360   {
7361     return 0;
7362   }
7363   else if (IsCDSetCDSQualChoice(vnp))
7364   {
7365     return FEATDEF_CDS;
7366   }
7367   else if (IsCDSetGeneQualChoice (vnp))
7368   {
7369     return FEATDEF_GENE;
7370   }
7371   else if (IsCDSetMRNAQualChoice(vnp))
7372   {
7373     return FEATDEF_mRNA;
7374   }
7375   else if (IsCDSetProteinQualChoice (vnp))
7376   {
7377     if (IsCDSetMatPeptideQualChoice (vnp))
7378     {
7379       return FEATDEF_mat_peptide_aa;
7380     }
7381     else
7382     {
7383       return FEATDEF_PROT;
7384     }
7385   }
7386   else
7387   {
7388     return 0;
7389   }
7390 }
7391 
7392 
7393 /* return TRUE if actually set field, FALSE otherwise */
7394 extern Boolean
SetCDSGeneProtField(SeqFeatPtr sfp,ValNodePtr vnp,ApplyValuePtr avp,FilterSetPtr fsp)7395 SetCDSGeneProtField
7396 (SeqFeatPtr      sfp,
7397  ValNodePtr      vnp,
7398  ApplyValuePtr   avp,
7399  FilterSetPtr    fsp)
7400 {
7401   ValNode        vn;
7402   ApplyValueData local_avd;
7403   Uint2          choice;
7404 
7405   if (sfp == NULL || vnp == NULL || avp == NULL)
7406   {
7407     return FALSE;
7408   }
7409 
7410   choice = FeatDefTypeFromFieldList (vnp);
7411   if (FindFeatFromFeatDefType(choice) != sfp->data.choice)
7412   {
7413     return FALSE;
7414   }
7415 
7416   if (fsp != NULL && fsp->cgp != NULL && DoesConstraintDisqualifyFeature (sfp, fsp->cgp))
7417   {
7418     return FALSE;
7419   }
7420 
7421   vn.choice = vnp->choice;
7422   vn.next = NULL;
7423   local_avd.field_list = &vn;
7424   local_avd.new_text = avp->new_text;
7425   local_avd.etp = avp->etp;
7426   local_avd.text_to_replace = avp->text_to_replace;
7427   local_avd.where_to_replace = avp->where_to_replace;
7428 
7429   if (vnp->data.intvalue == 1)
7430   {
7431     /* CDS Comment */
7432     SetCDSComment (sfp, &local_avd, NULL);
7433   }
7434   else if (vnp->data.intvalue <= 1 + num_gene_fields)
7435   {
7436     vn.data.intvalue = vnp->data.intvalue - 1;
7437     SetGeneFieldString (sfp, &local_avd, NULL);
7438   }
7439   else if (vnp->data.intvalue <= 1 + num_gene_fields + num_mrna_fields)
7440   {
7441     vn.data.intvalue = vnp->data.intvalue - num_gene_fields - 1;
7442     SetmRNAFieldString (sfp, &local_avd, NULL);
7443   }
7444   else if (vnp->data.intvalue <= 1 + num_gene_fields + num_mrna_fields + num_protein_fields)
7445   {
7446     vn.data.intvalue = vnp->data.intvalue - num_gene_fields - num_mrna_fields - 1;
7447     SetProteinFieldString (sfp, &local_avd, NULL);
7448   }
7449 
7450   /* no need to free any part of local_avd */
7451 
7452   return TRUE;
7453 }
7454 
7455 #define RNAFIELD_PRODUCT           1
7456 #define RNAFIELD_COMMENT           2
7457 #define RNAFIELD_CODONS_RECOGNIZED 3
7458 #define RNAFIELD_NCRNA_CLASS       4
7459 #define RNAFIELD_ANTICODON         5
7460 #define RNAFIELD_TRANSCRIPT_ID     6
7461 
7462 static CharPtr rna_field_list [] =
7463 {
7464   "Product", "Comment", "Codons Recognized", "ncRNA class", "Anticodon", "Transcript ID"
7465 };
7466 
7467 static Int4 num_rna_fields = sizeof (rna_field_list) / sizeof (CharPtr);
7468 
GetRNAFieldName(ValNodePtr vnp)7469 static CharPtr GetRNAFieldName (ValNodePtr vnp)
7470 {
7471   CharPtr label = NULL;
7472 
7473   if (vnp != NULL && vnp->data.intvalue >= 1)
7474   {
7475     if (vnp->data.intvalue <= num_rna_fields)
7476     {
7477       label = StringSave (rna_field_list [vnp->data.intvalue - 1]);
7478     }
7479     else if (vnp->data.intvalue <= num_rna_fields + num_gene_fields)
7480     {
7481       label = (CharPtr) MemNew ((StringLen (gene_field_list [vnp->data.intvalue - 1 - num_rna_fields]) + 6) * sizeof (Char));
7482       if (label != NULL)
7483       {
7484         sprintf (label, "Gene %s", gene_field_list [vnp->data.intvalue - 1 - num_rna_fields]);
7485       }
7486     }
7487   }
7488   return label;
7489 }
7490 
7491 extern DialoG
RNAAddFieldSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)7492 RNAAddFieldSelectionDialog
7493 (GrouP                    h,
7494  Boolean                  allow_multi,
7495  Nlm_ChangeNotifyProc     change_notify,
7496  Pointer                  change_userdata)
7497 {
7498   ValNodePtr choice_list = NULL;
7499   DialoG     dlg;
7500   Int4       i;
7501 
7502   for (i = 0; i < 4; i++)
7503   {
7504     ValNodeAddInt (&choice_list, 0, i + 1);
7505   }
7506   for (i = 0; i < num_gene_fields; i++)
7507   {
7508     ValNodeAddInt (&choice_list, 0, i + num_rna_fields + 1);
7509   }
7510 
7511   dlg = ValNodeSelectionDialog (h, choice_list, TALL_SELECTION_LIST,
7512                                 GetRNAFieldName, NULL,
7513                                 IntValNodeCopy, IntValNodeMatch,
7514                                 "RNA field", change_notify, change_userdata,
7515                                 FALSE);
7516 
7517   return dlg;
7518 }
7519 
7520 extern DialoG
RNARemoveFieldSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)7521 RNARemoveFieldSelectionDialog
7522 (GrouP                    h,
7523  Boolean                  allow_multi,
7524  Nlm_ChangeNotifyProc     change_notify,
7525  Pointer                  change_userdata)
7526 {
7527   ValNodePtr choice_list = NULL;
7528   DialoG     dlg;
7529   Int4       i;
7530 
7531   for (i = 0; i < num_rna_fields; i++)
7532   {
7533     ValNodeAddInt (&choice_list, 0, i + 1);
7534   }
7535   for (i = 0; i < num_gene_fields; i++)
7536   {
7537     ValNodeAddInt (&choice_list, 0, i + num_rna_fields + 1);
7538   }
7539 
7540   dlg = ValNodeSelectionDialog (h, choice_list, TALL_SELECTION_LIST,
7541                                 GetRNAFieldName, NULL,
7542                                 IntValNodeCopy, IntValNodeMatch,
7543                                 "RNA field", change_notify, change_userdata,
7544                                 FALSE);
7545 
7546   return dlg;
7547 }
7548 
7549 extern DialoG
RNAFieldSelectionDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)7550 RNAFieldSelectionDialog
7551 (GrouP                    h,
7552  Boolean                  allow_multi,
7553  Nlm_ChangeNotifyProc     change_notify,
7554  Pointer                  change_userdata)
7555 {
7556   ValNodePtr choice_list = NULL;
7557   DialoG     dlg;
7558   Int4       i;
7559 
7560   for (i = 0; i < 4; i++)
7561   {
7562     ValNodeAddInt (&choice_list, 0, i + 1);
7563   }
7564   for (i = 0; i < num_gene_fields; i++)
7565   {
7566     ValNodeAddInt (&choice_list, 0, i + num_rna_fields + 1);
7567   }
7568 
7569   dlg = ValNodeSelectionDialog (h, choice_list, TALL_SELECTION_LIST,
7570                                 GetRNAFieldName, NULL,
7571                                 IntValNodeCopy, IntValNodeMatch,
7572                                 "RNA field", change_notify, change_userdata,
7573                                 FALSE);
7574 
7575   return dlg;
7576 }
7577 
7578 static CharPtr rna_subtype_list [] = { "misc_RNA", "preRna", "mRNA", "tRNA",
7579                                         "rRNA", "ncRNA", "tmRNA"};
7580 static Int2    num_rna_subtypes = sizeof (rna_subtype_list) / sizeof (CharPtr);
7581 
GetRNASubtypeName(ValNodePtr vnp)7582 static CharPtr GetRNASubtypeName (ValNodePtr vnp)
7583 {
7584   CharPtr label = NULL;
7585 
7586   if (vnp != NULL && vnp->choice < num_rna_subtypes)
7587   {
7588     label = StringSave (rna_subtype_list[vnp->choice]);
7589   }
7590   return label;
7591 }
7592 
RNASubtypeSelectionDialog(GrouP h,Boolean allow_multi,SeqEntryPtr sep,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)7593 static DialoG RNASubtypeSelectionDialog
7594 (GrouP                    h,
7595  Boolean                  allow_multi,
7596  SeqEntryPtr              sep,
7597  Nlm_ChangeNotifyProc     change_notify,
7598  Pointer                  change_userdata)
7599 {
7600   ValNodePtr choice_list = NULL;
7601   DialoG     dlg;
7602 
7603   ValNodeAddInt (&choice_list, 0, FEATDEF_otherRNA);
7604   ValNodeAddInt (&choice_list, 1, FEATDEF_preRNA);
7605   ValNodeAddInt (&choice_list, 2, FEATDEF_mRNA);
7606   ValNodeAddInt (&choice_list, 3, FEATDEF_tRNA);
7607   ValNodeAddInt (&choice_list, 4, FEATDEF_rRNA);
7608   ValNodeAddInt (&choice_list, 5, FEATDEF_ncRNA);
7609   ValNodeAddInt (&choice_list, 6, FEATDEF_tmRNA);
7610 
7611   dlg = ValNodeSelectionDialog (h, choice_list, TALL_SELECTION_LIST,
7612                                 GetRNASubtypeName, NULL,
7613                                 IntValNodeCopy, IntValNodeMatch,
7614                                 "RNA subtype", change_notify, change_userdata,
7615                                 allow_multi);
7616   return dlg;
7617 }
7618 
7619 
GetRNAFieldString(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)7620 extern CharPtr GetRNAFieldString (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
7621 {
7622   RnaRefPtr  rrp;
7623   CharPtr    str = NULL;
7624   ValNode    vn;
7625   GeneRefPtr grp;
7626   SeqFeatPtr gene;
7627   SeqMgrFeatContext context;
7628   Int4              field_choice;
7629   GBQualPtr         qual;
7630 
7631   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA || vnp == NULL)
7632   {
7633     return NULL;
7634   }
7635 
7636   rrp = sfp->data.value.ptrvalue;
7637 
7638   while (vnp != NULL && str == NULL)
7639   {
7640     field_choice = vnp->data.intvalue;
7641     switch (vnp->data.intvalue)
7642     {
7643       case RNAFIELD_PRODUCT :
7644         str = GetRNAProductString (sfp, NULL);
7645         break;
7646       case RNAFIELD_COMMENT :
7647         if (!StringHasNoText (sfp->comment))
7648         {
7649           str = StringSave (sfp->comment);
7650         }
7651         break;
7652       case RNAFIELD_NCRNA_CLASS :
7653         for (qual = sfp->qual; qual != NULL && str == NULL; qual = qual->next)
7654         {
7655           if (StringCmp (qual->qual, "ncRNA_class") == 0
7656               && !StringHasNoText (qual->val))
7657           {
7658             str = StringSave (qual->val);
7659           }
7660         }
7661         break;
7662       default:
7663         if (vnp->data.intvalue >= num_rna_fields + 1)
7664         {
7665           vn.choice = 0;
7666           vn.next = NULL;
7667           vn.data.intvalue = vnp->data.intvalue - num_rna_fields;
7668           grp = SeqMgrGetGeneXref (sfp);
7669           if (grp == NULL)
7670           {
7671             gene = SeqMgrGetOverlappingGene (sfp->location, &context);
7672             str = GetGeneFieldString (gene, &vn, NULL);
7673           }
7674           else
7675           {
7676             str = GetGeneFieldString (sfp, &vn, NULL);
7677           }
7678         }
7679         break;
7680 
7681     }
7682     vnp = vnp->next;
7683   }
7684   return str;
7685 }
7686 
7687 
IsParseabletRNAName(CharPtr name_string)7688 static Boolean IsParseabletRNAName (CharPtr name_string)
7689 {
7690   if (StringHasNoText(name_string))
7691   {
7692     return TRUE;
7693   }
7694   else if (StringNICmp (name_string, "trna-", 5) != 0)
7695   {
7696     return FALSE;
7697   }
7698   else if (StringLen (name_string) != 8)
7699   {
7700     return FALSE;
7701   }
7702   else if (ParseTRnaString (name_string, NULL, NULL, TRUE) == 0)
7703   {
7704     return FALSE;
7705   }
7706   else
7707   {
7708     return TRUE;
7709   }
7710 }
7711 
7712 
SettRNAName(SeqFeatPtr sfp,ApplyValuePtr avp)7713 static void SettRNAName (SeqFeatPtr sfp, ApplyValuePtr avp)
7714 {
7715   RnaRefPtr     rrp;
7716   tRNAPtr           trp;
7717   Uint1             new_aa;
7718   CharPtr           name_string;
7719   Boolean           justTrnaText = FALSE;
7720   Uint1             codon [6];
7721   GBQualPtr         gbqual, gbqual_last = NULL;
7722 
7723   if (sfp == NULL || sfp->data.value.ptrvalue == NULL
7724       || sfp->idx.subtype != FEATDEF_tRNA
7725       || avp == NULL)
7726   {
7727     return;
7728   }
7729 
7730   rrp = sfp->data.value.ptrvalue;
7731   if (rrp->ext.choice == 0)
7732   {
7733     trp = MemNew (sizeof (tRNA));
7734     trp->aatype = 0;
7735     MemSet (trp->codon, 255, sizeof (trp->codon));
7736     trp->anticodon = NULL;
7737     rrp->ext.value.ptrvalue = trp;
7738     rrp->ext.choice = 2;
7739   }
7740   if (rrp->ext.choice != 2)
7741   {
7742     return;
7743   }
7744   trp = (tRNAPtr) rrp->ext.value.ptrvalue;
7745 
7746   name_string = GetRNAProductString (sfp, NULL);
7747   name_string = HandleApplyValue (name_string, avp);
7748   if (!IsParseabletRNAName(name_string))
7749   {
7750     if (trp->anticodon == NULL
7751         && trp->codon[0] == 255
7752         && trp->codon[1] == 255
7753         && trp->codon[2] == 255
7754         && trp->codon[3] == 255
7755         && trp->codon[4] == 255
7756         && trp->codon[5] == 255)
7757     {
7758       trp = MemFree (trp);
7759       rrp->ext.choice = 1;
7760       rrp->ext.value.ptrvalue = name_string;
7761     }
7762     else
7763     {
7764       trp->aa = 0;
7765       gbqual = sfp->qual;
7766       while (gbqual != NULL)
7767       {
7768         gbqual_last = gbqual;
7769         gbqual = gbqual->next;
7770       }
7771       gbqual = GBQualNew ();
7772       gbqual->qual = StringSave ("product");
7773       gbqual->val = name_string;
7774       if (gbqual_last == NULL)
7775       {
7776         sfp->qual = gbqual;
7777       }
7778       else
7779       {
7780         gbqual->next = gbqual_last->next;
7781         gbqual_last->next = gbqual;
7782       }
7783     }
7784   }
7785   else
7786   {
7787     new_aa = ParseTRnaString (name_string, &justTrnaText, codon, TRUE);
7788     trp->aa = new_aa;
7789     trp->aatype = 2;
7790     name_string = MemFree (name_string);
7791   }
7792 }
7793 
7794 
SetRNAProduct(SeqFeatPtr sfp,ApplyValuePtr avp)7795 static void SetRNAProduct (SeqFeatPtr sfp, ApplyValuePtr avp)
7796 {
7797   RnaRefPtr rrp;
7798   GBQualPtr gbq, prev_gbq = NULL;
7799 
7800   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA || sfp->data.value.ptrvalue == NULL || avp == NULL)
7801   {
7802     return;
7803   }
7804 
7805   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
7806 
7807   gbq = sfp->qual;
7808   while (gbq != NULL && StringCmp (gbq->qual, "product") != 0)
7809   {
7810     prev_gbq = gbq;
7811     gbq = gbq->next;
7812   }
7813   if (gbq != NULL)
7814   {
7815     gbq->val = HandleApplyValue (gbq->val, avp);
7816     if (StringHasNoText (gbq->val))
7817     {
7818       if (prev_gbq == NULL)
7819       {
7820         sfp->qual = gbq->next;
7821       }
7822       else
7823       {
7824         prev_gbq->next = gbq->next;
7825       }
7826       gbq->next = NULL;
7827       gbq = GBQualFree (gbq);
7828     }
7829   }
7830   else if (sfp->idx.subtype == FEATDEF_tRNA || rrp->ext.choice == 2)
7831   {
7832     SettRNAName (sfp, avp);
7833   }
7834   else if (rrp->ext.choice == 1
7835            && (StringCmp (rrp->ext.value.ptrvalue, "ncRNA") == 0
7836                || StringCmp (rrp->ext.value.ptrvalue, "tmRNA") == 0
7837                || StringCmp (rrp->ext.value.ptrvalue, "misc_RNA") == 0))
7838   {
7839     gbq = GBQualNew();
7840     gbq->qual = StringSave ("product");
7841     gbq->val = HandleApplyValue (gbq->val, avp);
7842     gbq->next = sfp->qual;
7843     sfp->qual = gbq;
7844   }
7845   else if (rrp->ext.choice == 1 || rrp->ext.choice == 0)
7846   {
7847     rrp->ext.value.ptrvalue = HandleApplyValue (rrp->ext.value.ptrvalue, avp);
7848     if (StringHasNoText (rrp->ext.value.ptrvalue))
7849     {
7850       rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
7851       rrp->ext.choice = 0;
7852     }
7853     else
7854     {
7855       rrp->ext.choice = 1;
7856     }
7857   }
7858 }
7859 
7860 
SetRNAFieldString(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)7861 static void SetRNAFieldString (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
7862 {
7863   RnaRefPtr     rrp;
7864   ApplyValuePtr avp;
7865   SeqFeatPtr    gene;
7866   GeneRefPtr    grp;
7867   SeqMgrFeatContext context;
7868   GBQualPtr         qual;
7869   Boolean           found = FALSE;
7870 
7871   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA || userdata == NULL)
7872   {
7873     return;
7874   }
7875 
7876   avp = (ApplyValuePtr) userdata;
7877   if (avp->field_list == NULL)
7878   {
7879     return;
7880   }
7881 
7882   rrp = sfp->data.value.ptrvalue;
7883 
7884   switch (avp->field_list->data.intvalue)
7885   {
7886     case RNAFIELD_PRODUCT :
7887       SetRNAProduct (sfp, avp);
7888       break;
7889     case RNAFIELD_COMMENT :
7890       sfp->comment = HandleApplyValue (sfp->comment, avp);
7891       break;
7892     case RNAFIELD_NCRNA_CLASS :
7893       for (qual = sfp->qual; qual != NULL; qual = qual->next)
7894       {
7895         if (StringCmp (qual->qual, "ncRNA_class") == 0)
7896         {
7897           qual->val = HandleApplyValue (qual->val, avp);
7898           found = TRUE;
7899         }
7900       }
7901       if (!found)
7902       {
7903         qual = GBQualNew ();
7904         qual->qual = StringSave ("ncRNA_class");
7905         qual->val = StringSave (avp->new_text);
7906         qual->next = sfp->qual;
7907         sfp->qual = qual;
7908       }
7909       break;
7910     default:
7911       if (avp->field_list->data.intvalue >= num_rna_fields + 1)
7912       {
7913         avp->field_list->data.intvalue -= num_rna_fields;
7914         grp = SeqMgrGetGeneXref (sfp);
7915         if (grp == NULL)
7916         {
7917           gene = SeqMgrGetOverlappingGene (sfp->location, &context);
7918           SetGeneFieldString (gene, avp, fsp);
7919         }
7920         else
7921         {
7922           SetGeneFieldString (sfp, avp, fsp);
7923         }
7924         avp->field_list->data.intvalue += num_rna_fields;
7925       }
7926       break;
7927   }
7928 }
7929 
7930 
RemoveRNAProduct(SeqFeatPtr sfp)7931 static void RemoveRNAProduct (SeqFeatPtr sfp)
7932 {
7933   RnaRefPtr rrp;
7934   GBQualPtr gbq, prev_gbq = NULL;
7935   tRNAPtr     trp;
7936 
7937   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA || sfp->data.value.ptrvalue == NULL)
7938   {
7939     return;
7940   }
7941 
7942   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
7943 
7944   gbq = sfp->qual;
7945   while (gbq != NULL && StringCmp (gbq->qual, "product") != 0)
7946   {
7947     prev_gbq = gbq;
7948     gbq = gbq->next;
7949   }
7950   if (gbq != NULL)
7951   {
7952     if (prev_gbq == NULL)
7953     {
7954       sfp->qual = gbq->next;
7955     }
7956     else
7957     {
7958       prev_gbq->next = gbq->next;
7959     }
7960     gbq->next = NULL;
7961     gbq = GBQualFree (gbq);
7962   }
7963   else if (rrp->ext.choice == 1
7964            && (StringCmp (rrp->ext.value.ptrvalue, "ncRNA") == 0
7965                || StringCmp (rrp->ext.value.ptrvalue, "tmRNA") == 0
7966                || StringCmp (rrp->ext.value.ptrvalue, "misc_RNA") == 0))
7967   {
7968     /* do nothing - already have no product */
7969   }
7970   else if (rrp->ext.choice == 0)
7971   {
7972     /* do nothing - already have no product */
7973   }
7974   else if (rrp->ext.choice == 1)
7975   {
7976     rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
7977     rrp->ext.choice = 0;
7978   }
7979   else if (rrp->ext.choice == 2)
7980   {
7981     trp = (tRNAPtr) rrp->ext.value.ptrvalue;
7982     if (trp != NULL)
7983     {
7984       trp->aatype = 0;
7985     }
7986   }
7987 }
7988 
7989 
RemoveRNAField(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)7990 static void RemoveRNAField (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
7991 {
7992   RnaRefPtr     rrp;
7993   tRNAPtr       trp;
7994   ApplyValuePtr avp;
7995   SeqFeatPtr    gene;
7996   GeneRefPtr    grp;
7997   ValNode       vn;
7998   SeqMgrFeatContext context;
7999   GBQualPtr         qual, qual_prev = NULL, qual_next;
8000 
8001   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA || userdata == NULL)
8002   {
8003     return;
8004   }
8005 
8006   avp = (ApplyValuePtr) userdata;
8007   if (avp->field_list == NULL)
8008   {
8009     return;
8010   }
8011 
8012   rrp = sfp->data.value.ptrvalue;
8013 
8014   switch (avp->field_list->data.intvalue)
8015   {
8016     case RNAFIELD_PRODUCT :
8017       RemoveRNAProduct (sfp);
8018       break;
8019     case RNAFIELD_COMMENT :
8020       sfp->comment = MemFree (sfp->comment);
8021       break;
8022     case RNAFIELD_NCRNA_CLASS :
8023       qual = sfp->qual;
8024       while (qual != NULL)
8025       {
8026         qual_next = qual->next;
8027         if (StringCmp (qual->qual, "ncRNA_class") == 0)
8028         {
8029           if (qual_prev == NULL)
8030           {
8031             sfp->qual = qual_next;
8032           }
8033           else
8034           {
8035             qual_prev->next = qual_next;
8036           }
8037           qual->next = NULL;
8038           qual = GBQualFree (qual);
8039         }
8040         else
8041         {
8042           qual_prev = qual;
8043         }
8044         qual = qual_next;
8045       }
8046       break;
8047     case RNAFIELD_ANTICODON :
8048       if (rrp->ext.choice == 2) {
8049         trp = (tRNAPtr) rrp->ext.value.ptrvalue;
8050         if (trp != NULL && trp->anticodon != NULL) {
8051           trp->anticodon = SeqLocFree (trp->anticodon);
8052         }
8053       }
8054       break;
8055     case RNAFIELD_CODONS_RECOGNIZED :
8056       if (rrp->ext.choice == 2) {
8057         trp = (tRNAPtr) rrp->ext.value.ptrvalue;
8058         if (trp != NULL) {
8059           trp->codon [0] = 255;
8060           trp->codon [1] = 255;
8061           trp->codon [2] = 255;
8062           trp->codon [3] = 255;
8063           trp->codon [4] = 255;
8064           trp->codon [5] = 255;
8065         }
8066       }
8067       break;
8068     case RNAFIELD_TRANSCRIPT_ID :
8069       sfp->product = SeqLocFree (sfp->product);
8070       break;
8071     default:
8072       if (avp->field_list->data.intvalue >= num_rna_fields + 1)
8073       {
8074         vn.choice = 1;
8075         vn.next = NULL;
8076         vn.data.intvalue = avp->field_list->data.intvalue - num_rna_fields;
8077         grp = SeqMgrGetGeneXref (sfp);
8078         if (grp == NULL)
8079         {
8080           gene = SeqMgrGetOverlappingGene (sfp->location, &context);
8081           RemoveGeneFieldString (gene, &vn);
8082         }
8083         else
8084         {
8085           RemoveGeneFieldString (sfp, &vn);
8086         }
8087       }
8088       break;
8089   }
8090 }
8091 
8092 typedef struct exonfieldselection
8093 {
8094   DIALOG_MESSAGE_BLOCK
8095   PopuP                    exon_field;
8096 
8097   Boolean                  allow_none;
8098   Nlm_ChangeNotifyProc     change_notify;
8099   Pointer                  change_userdata;
8100 } ExonFieldSelectionData, PNTR ExonFieldSelectionPtr;
8101 
8102 #define EXONFIELD_ALLELE            1
8103 #define EXONFIELD_COMMENT           2
8104 #define EXONFIELD_EC_NUMBER         3
8105 #define EXONFIELD_FUNCTION          4
8106 #define EXONFIELD_OLD_LOCUS_TAG     5
8107 #define EXONFIELD_NUMBER            6
8108 #define EXONFIELD_PRODUCT           7
8109 
8110 static CharPtr exon_field_list [] =
8111 {
8112   "allele", "comment", "EC_number", "function", "old_locus_tag", "number", "product"
8113 };
8114 #define NUM_EXON_FIELDS 7
8115 
8116 extern DialoG
ExonFieldSelectionDialog(GrouP h,Boolean allow_none,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)8117 ExonFieldSelectionDialog
8118 (GrouP                    h,
8119  Boolean                  allow_none,
8120  Nlm_ChangeNotifyProc     change_notify,
8121  Pointer                  change_userdata)
8122 {
8123   return FeatureFieldSelectionDialog (h, allow_none,
8124                                       NUM_EXON_FIELDS, exon_field_list,
8125                                       change_notify, change_userdata);
8126 
8127 }
8128 
GetExonFieldString(SeqFeatPtr sfp,ValNodePtr exon_field)8129 extern CharPtr GetExonFieldString (SeqFeatPtr sfp, ValNodePtr exon_field)
8130 {
8131   ValNodePtr vnp;
8132   CharPtr    str = NULL;
8133   GBQualPtr  gbqual;
8134 
8135   if (sfp == NULL || exon_field == NULL || sfp->idx.subtype != FEATDEF_exon)
8136   {
8137     return NULL;
8138   }
8139 
8140   vnp = exon_field;
8141   while (vnp != NULL && StringHasNoText (str))
8142   {
8143     str = NULL;
8144     if (vnp->data.intvalue == EXONFIELD_COMMENT)
8145     {
8146       str = sfp->comment;
8147     }
8148     else
8149     {
8150       gbqual = sfp->qual;
8151       while (gbqual != NULL && StringHasNoText (str))
8152       {
8153         if (vnp->data.intvalue < NUM_EXON_FIELDS + 1
8154             && vnp->data.intvalue >= 1
8155             && StringCmp (gbqual->qual, exon_field_list[vnp->data.intvalue - 1]) == 0)
8156         {
8157           str = gbqual->val;
8158         }
8159         gbqual = gbqual->next;
8160       }
8161     }
8162     vnp = vnp->next;
8163   }
8164   if (StringHasNoText (str))
8165   {
8166     str = NULL;
8167   }
8168   else
8169   {
8170     str = StringSave (str);
8171   }
8172   return str;
8173 }
8174 
RemoveExonFieldString(SeqFeatPtr sfp,ValNodePtr exon_field)8175 extern void RemoveExonFieldString (SeqFeatPtr sfp, ValNodePtr exon_field)
8176 {
8177   ValNodePtr vnp;
8178   Boolean    found_nonempty = FALSE;
8179   GBQualPtr  gbqual, prev_qual;
8180 
8181   if (sfp == NULL || exon_field == NULL || sfp->idx.subtype != FEATDEF_exon)
8182   {
8183     return;
8184   }
8185 
8186   vnp = exon_field;
8187   while (vnp != NULL && !found_nonempty)
8188   {
8189     if (vnp->data.intvalue == EXONFIELD_COMMENT)
8190     {
8191       if (!StringHasNoText (sfp->comment))
8192       {
8193         found_nonempty = TRUE;
8194         if (vnp->choice != 0)
8195         {
8196           sfp->comment = MemFree (sfp->comment);
8197         }
8198       }
8199     }
8200     else
8201     {
8202       gbqual = sfp->qual;
8203       prev_qual = NULL;
8204       while (gbqual != NULL)
8205       {
8206         if (vnp->data.intvalue <= NUM_EXON_FIELDS + 1
8207             && vnp->data.intvalue >= 1
8208             && StringCmp (gbqual->qual, exon_field_list[vnp->data.intvalue - 1]) == 0)
8209         {
8210            if (!StringHasNoText (gbqual->val))
8211            {
8212             found_nonempty = TRUE;
8213             if (vnp->choice != 0)
8214             {
8215               if (prev_qual == NULL)
8216               {
8217                 sfp->qual = gbqual->next;
8218               } else {
8219                 prev_qual->next = gbqual->next;
8220               }
8221               gbqual->next = NULL;
8222               GBQualFree (gbqual);
8223               return;
8224             }
8225           }
8226         }
8227         prev_qual = gbqual;
8228         gbqual = gbqual->next;
8229       }
8230     }
8231     vnp = vnp->next;
8232   }
8233 }
8234 
8235 
8236 #define PARSE_FIELD_BIOSRC_TAXNAME  1
8237 #define PARSE_FIELD_BIOSRC_LINEAGE  2
8238 #define PARSE_FIELD_BIOSRC_DIVISION 3
8239 
8240 static CharPtr biosrc_string_list [] =
8241 {
8242   "Organism Name", "Lineage", "Division"
8243 };
8244 
8245 static int num_biosrc_strings = sizeof (biosrc_string_list) / sizeof (CharPtr);
8246 
BioSourceStringDialog(GrouP h,Boolean allow_multi,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)8247 extern DialoG BioSourceStringDialog
8248 (GrouP                    h,
8249  Boolean                  allow_multi,
8250  Nlm_ChangeNotifyProc     change_notify,
8251  Pointer                  change_userdata)
8252 {
8253   return FeatureFieldSelectionDialog (h, allow_multi,
8254                                       num_biosrc_strings, biosrc_string_list,
8255                                       change_notify, change_userdata);
8256 }
8257 
GetSourceStringFromBioSource(BioSourcePtr biop,ValNodePtr vnp)8258 static CharPtr GetSourceStringFromBioSource (BioSourcePtr biop, ValNodePtr vnp)
8259 {
8260   if (biop == NULL || vnp == NULL || biop->org == NULL)
8261   {
8262     return NULL;
8263   }
8264 
8265   if (vnp->data.intvalue == PARSE_FIELD_BIOSRC_TAXNAME
8266       && !StringHasNoText (biop->org->taxname))
8267   {
8268     return StringSave (biop->org->taxname);
8269   }
8270   else if (vnp->data.intvalue == PARSE_FIELD_BIOSRC_LINEAGE
8271            && biop->org->orgname != NULL
8272            && !StringHasNoText (biop->org->orgname->lineage))
8273   {
8274     return StringSave (biop->org->orgname->lineage);
8275   }
8276   else if (vnp->data.intvalue == PARSE_FIELD_BIOSRC_DIVISION
8277            && biop->org->orgname != NULL
8278            && !StringHasNoText (biop->org->orgname->div))
8279   {
8280     return StringSave (biop->org->orgname->div);
8281   }
8282   else
8283   {
8284     return NULL;
8285   }
8286 }
8287 
8288 static CharPtr
GetSourceFeatureString(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)8289 GetSourceFeatureString
8290 (SeqFeatPtr   sfp,
8291  ValNodePtr   vnp,
8292  FilterSetPtr fsp)
8293 {
8294   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || vnp == NULL)
8295   {
8296     return NULL;
8297   }
8298 
8299   return GetSourceStringFromBioSource (sfp->data.value.ptrvalue, vnp);
8300 }
8301 
8302 static CharPtr
GetSourceDescriptorString(SeqDescrPtr sdp,ValNodePtr vnp,FilterSetPtr fsp)8303 GetSourceDescriptorString
8304 (SeqDescrPtr  sdp,
8305  ValNodePtr   vnp,
8306  FilterSetPtr fsp)
8307 {
8308   if (sdp == NULL || sdp->choice != Seq_descr_source || vnp == NULL)
8309   {
8310     return NULL;
8311   }
8312   return GetSourceStringFromBioSource (sdp->data.ptrvalue, vnp);
8313 }
8314 
8315 
GetDbxrefFromBioSource(BioSourcePtr biop,ValNodePtr vnp)8316 static CharPtr GetDbxrefFromBioSource (BioSourcePtr biop, ValNodePtr vnp)
8317 {
8318   ValNodePtr dbx;
8319   DbtagPtr   dbtag;
8320   Char       buf[20];
8321 
8322   if (biop == NULL || vnp == NULL || vnp->data.ptrvalue == NULL || biop->org == NULL)
8323   {
8324     return NULL;
8325   }
8326 
8327   dbx = biop->org->db;
8328   while (dbx != NULL)
8329   {
8330     dbtag = (DbtagPtr) dbx->data.ptrvalue;
8331     if (dbtag != NULL && dbtag->tag != NULL
8332         && StringCmp (dbtag->db, vnp->data.ptrvalue) == 0)
8333     {
8334       if (dbtag->tag->str == NULL)
8335       {
8336         sprintf (buf, "%d", dbtag->tag->id);
8337         return StringSave (buf);
8338       }
8339       else
8340       {
8341         return StringSave (dbtag->tag->str);
8342       }
8343     }
8344     dbx = dbx->next;
8345   }
8346   return NULL;
8347 }
8348 
8349 static CharPtr
GetBioSourceFeatureDbxrefString(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)8350 GetBioSourceFeatureDbxrefString
8351 (SeqFeatPtr   sfp,
8352  ValNodePtr   vnp,
8353  FilterSetPtr fsp)
8354 {
8355   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || vnp == NULL)
8356   {
8357     return NULL;
8358   }
8359 
8360   return GetDbxrefFromBioSource (sfp->data.value.ptrvalue, vnp);
8361 }
8362 
8363 static CharPtr
GetBioSourceDescriptorDbxrefString(SeqDescrPtr sdp,ValNodePtr vnp,FilterSetPtr fsp)8364 GetBioSourceDescriptorDbxrefString
8365 (SeqDescrPtr  sdp,
8366  ValNodePtr   vnp,
8367  FilterSetPtr fsp)
8368 {
8369   if (sdp == NULL || sdp->choice != Seq_descr_source || vnp == NULL)
8370   {
8371     return NULL;
8372   }
8373   return GetDbxrefFromBioSource (sdp->data.ptrvalue, vnp);
8374 }
8375 
8376 
8377 #define TEXT_PORTION_START_AFTER 1
8378 #define TEXT_PORTION_START_WITH  2
8379 #define TEXT_PORTION_END_AFTER   1
8380 #define TEXT_PORTION_END_WITH    2
8381 
8382 typedef struct textportiondialog
8383 {
8384   DIALOG_MESSAGE_BLOCK
8385 
8386   GrouP  start_choice;
8387   TexT   start_text;
8388   GrouP  end_choice;
8389   TexT   end_text;
8390   ButtoN rem_before;
8391   ButtoN also_rem_before;
8392   ButtoN rem_after;
8393   ButtoN also_rem_after;
8394   ButtoN insensitive;
8395   ButtoN whole_word;
8396 
8397   Boolean inside;
8398 
8399   Nlm_ChangeNotifyProc     change_notify;
8400   Pointer                  change_userdata;
8401 } TextPortionXDialogData, PNTR TextPortionXDialogPtr;
8402 
8403 
OutsideEnableDisable(TextPortionXDialogPtr tp)8404 static void OutsideEnableDisable (TextPortionXDialogPtr tp)
8405 {
8406   if (tp == NULL || tp->inside)
8407   {
8408     return;
8409   }
8410   if (GetStatus (tp->rem_before))
8411   {
8412     Enable (tp->start_text);
8413     Enable (tp->also_rem_before);
8414   }
8415   else
8416   {
8417     Disable (tp->start_text);
8418     Disable (tp->also_rem_before);
8419   }
8420   if (GetStatus (tp->rem_after))
8421   {
8422     Enable (tp->end_text);
8423     Enable (tp->also_rem_after);
8424   }
8425   else
8426   {
8427     Disable (tp->end_text);
8428     Disable (tp->also_rem_after);
8429   }
8430 }
8431 
ResetTextPortionXDialog(TextPortionXDialogPtr tp)8432 static void ResetTextPortionXDialog (TextPortionXDialogPtr tp)
8433 {
8434   if (tp == NULL)
8435   {
8436     return;
8437   }
8438   if (tp->inside)
8439   {
8440     SetValue (tp->start_choice, TEXT_PORTION_START_AFTER);
8441     SetValue (tp->end_choice, TEXT_PORTION_END_AFTER);
8442   }
8443   else
8444   {
8445     SetStatus (tp->rem_before, FALSE);
8446     SetStatus (tp->also_rem_before, FALSE);
8447     SetStatus (tp->rem_after, FALSE);
8448     SetStatus (tp->also_rem_after, FALSE);
8449   }
8450   SetTitle (tp->start_text, "");
8451   SetTitle (tp->end_text, "");
8452   SetStatus (tp->insensitive, FALSE);
8453   SetStatus (tp->whole_word, FALSE);
8454   OutsideEnableDisable (tp);
8455 }
8456 
TextPortionXToDialog(DialoG d,Pointer data)8457 static void TextPortionXToDialog (DialoG d, Pointer data)
8458 {
8459   TextPortionXDialogPtr tdlg;
8460   TextPortionXPtr       tdata;
8461   Int4                 start_choice, end_choice;
8462 
8463   tdlg = (TextPortionXDialogPtr) GetObjectExtra (d);
8464   if (tdlg == NULL)
8465   {
8466     return;
8467   }
8468   tdata = (TextPortionXPtr) data;
8469   ResetTextPortionXDialog (tdlg);
8470   if (tdata != NULL)
8471   {
8472     start_choice = tdata->end_choice;
8473     end_choice = tdata->end_choice;
8474     if (start_choice < TEXT_PORTION_START_AFTER || start_choice > TEXT_PORTION_START_WITH)
8475     {
8476       start_choice = TEXT_PORTION_START_AFTER;
8477     }
8478     if (end_choice < TEXT_PORTION_END_AFTER || end_choice > TEXT_PORTION_END_WITH)
8479     {
8480       end_choice = TEXT_PORTION_END_AFTER;
8481     }
8482     if (tdlg->inside)
8483     {
8484       SetValue (tdlg->start_choice, start_choice);
8485       SetValue (tdlg->end_choice, end_choice);
8486     }
8487     else
8488     {
8489       SetStatus (tdlg->rem_before, StringHasNoText (tdata->start_text));
8490       SetStatus (tdlg->rem_after, StringHasNoText (tdata->end_text));
8491       if (start_choice == TEXT_PORTION_START_AFTER)
8492       {
8493         SetStatus (tdlg->also_rem_before, TRUE);
8494       }
8495       else
8496       {
8497         SetStatus (tdlg->also_rem_before, FALSE);
8498       }
8499       if (end_choice == TEXT_PORTION_END_AFTER)
8500       {
8501         SetStatus (tdlg->also_rem_after, TRUE);
8502       }
8503       else
8504       {
8505         SetStatus (tdlg->also_rem_after, FALSE);
8506       }
8507     }
8508     if (tdata->start_text != NULL)
8509     {
8510       SetTitle (tdlg->start_text, tdata->start_text);
8511     }
8512     if (tdata->end_text != NULL)
8513     {
8514       SetTitle (tdlg->end_text, tdata->end_text);
8515     }
8516     SetStatus (tdlg->insensitive, tdata->insensitive);
8517     SetStatus (tdlg->whole_word, tdata->whole_word);
8518   }
8519   OutsideEnableDisable (tdlg);
8520 }
8521 
DialogToTextPortionX(DialoG d)8522 static Pointer DialogToTextPortionX (DialoG d)
8523 {
8524   TextPortionXDialogPtr tdlg;
8525   TextPortionXPtr       tdata;
8526 
8527   tdlg = (TextPortionXDialogPtr) GetObjectExtra (d);
8528   if (tdlg == NULL)
8529   {
8530     return NULL;
8531   }
8532 
8533   tdata = (TextPortionXPtr) MemNew (sizeof (TextPortionXData));
8534   if (tdata != NULL)
8535   {
8536     if (tdlg->inside)
8537     {
8538       tdata->start_choice = GetValue (tdlg->start_choice);
8539       tdata->end_choice = GetValue (tdlg->end_choice);
8540       tdata->start_text = JustSaveStringFromText (tdlg->start_text);
8541       tdata->end_text = JustSaveStringFromText (tdlg->end_text);
8542     }
8543     else
8544     {
8545       if (GetStatus (tdlg->rem_before))
8546       {
8547         tdata->start_text = JustSaveStringFromText (tdlg->start_text);
8548       }
8549       else
8550       {
8551         tdata->start_text = NULL;
8552       }
8553       if (GetStatus (tdlg->rem_after))
8554       {
8555         tdata->end_text = JustSaveStringFromText (tdlg->end_text);
8556       }
8557       else
8558       {
8559         tdata->end_text = NULL;
8560       }
8561 
8562       if (GetStatus (tdlg->also_rem_before))
8563       {
8564         tdata->start_choice = TEXT_PORTION_START_AFTER;
8565       }
8566       else
8567       {
8568         tdata->start_choice = TEXT_PORTION_START_WITH;
8569       }
8570       if (GetStatus (tdlg->also_rem_after))
8571       {
8572         tdata->end_choice = TEXT_PORTION_END_AFTER;
8573       }
8574       else
8575       {
8576         tdata->end_choice = TEXT_PORTION_END_WITH;
8577       }
8578 
8579     }
8580 
8581     tdata->insensitive = GetStatus (tdlg->insensitive);
8582     tdata->whole_word = GetStatus (tdlg->whole_word);
8583   }
8584   return tdata;
8585 }
8586 
TextPortionXMessage(DialoG d,Int2 mssg)8587 static void TextPortionXMessage (DialoG d, Int2 mssg)
8588 
8589 {
8590   TextPortionXDialogPtr tp;
8591 
8592   tp = (TextPortionXDialogPtr) GetObjectExtra (d);
8593   if (tp != NULL) {
8594     switch (mssg) {
8595       case VIB_MSG_INIT :
8596         ResetTextPortionXDialog (tp);
8597         break;
8598       case VIB_MSG_ENTER :
8599         Select (tp->start_text);
8600         break;
8601       case NUM_VIB_MSG + 1 :
8602         SetTitle (tp->start_text, "");
8603         SetTitle (tp->end_text, "");
8604         break;
8605       default :
8606         break;
8607     }
8608   }
8609 }
8610 
TestTextPortionXDialog(DialoG d)8611 static ValNodePtr TestTextPortionXDialog (DialoG d)
8612 
8613 {
8614   return NULL;
8615 }
8616 
ChangeTextPortionXGroup(GrouP g)8617 static void ChangeTextPortionXGroup (GrouP g)
8618 {
8619   TextPortionXDialogPtr tp;
8620 
8621   tp = (TextPortionXDialogPtr) GetObjectExtra (g);
8622   if (tp == NULL) return;
8623 
8624   if (tp->change_notify != NULL)
8625   {
8626     (tp->change_notify) (tp->change_userdata);
8627   }
8628 }
8629 
ChangeTextPortionXText(TexT t)8630 static void ChangeTextPortionXText (TexT t)
8631 {
8632   TextPortionXDialogPtr tp;
8633 
8634   tp = (TextPortionXDialogPtr) GetObjectExtra (t);
8635   if (tp == NULL) return;
8636 
8637   if (tp->change_notify != NULL)
8638   {
8639     (tp->change_notify) (tp->change_userdata);
8640   }
8641 }
8642 
8643 
ChangeTextPortionXBtn(ButtoN b)8644 static void ChangeTextPortionXBtn (ButtoN b)
8645 {
8646   TextPortionXDialogPtr tp;
8647 
8648   tp = (TextPortionXDialogPtr) GetObjectExtra (b);
8649   if (tp == NULL) return;
8650   OutsideEnableDisable (tp);
8651 
8652   if (tp->change_notify != NULL)
8653   {
8654     (tp->change_notify) (tp->change_userdata);
8655   }
8656 }
8657 
8658 
8659 
TextPortionXDialogEx(GrouP h,Boolean inside,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)8660 extern DialoG TextPortionXDialogEx (GrouP h, Boolean inside, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
8661 {
8662   TextPortionXDialogPtr tp;
8663   GrouP                p, g1, g2;
8664 
8665   tp = (TextPortionXDialogPtr) MemNew (sizeof (TextPortionXDialogData));
8666   if (tp == NULL)
8667   {
8668     return NULL;
8669   }
8670 
8671   p = HiddenGroup (h, -1, 0, NULL);
8672   SetObjectExtra (p, tp, StdCleanupExtraProc);
8673 
8674   tp->dialog = (DialoG) p;
8675   tp->todialog = TextPortionXToDialog;
8676   tp->fromdialog = DialogToTextPortionX;
8677   tp->dialogmessage = TextPortionXMessage;
8678   tp->testdialog = TestTextPortionXDialog;
8679 
8680   tp->change_notify = change_notify;
8681   tp->change_userdata = change_userdata;
8682   tp->inside = inside;
8683 
8684   g1 = HiddenGroup (p, 3, 0, NULL);
8685   SetGroupSpacing (g1, 10, 10);
8686 
8687   if (inside)
8688   {
8689     StaticPrompt (g1, "Between", 0, popupMenuHeight, programFont, 'r');
8690     tp->start_choice = HiddenGroup (g1, 2, 0, ChangeTextPortionXGroup);
8691     RadioButton (tp->start_choice, "just after");
8692     RadioButton (tp->start_choice, "starting at");
8693     SetValue (tp->start_choice, TEXT_PORTION_START_AFTER);
8694     SetObjectExtra (tp->start_choice, tp, NULL);
8695 
8696     tp->start_text = DialogText (g1, "", 10, ChangeTextPortionXText);
8697     SetObjectExtra (tp->start_text, tp, NULL);
8698 
8699     StaticPrompt (g1, "And", 0, popupMenuHeight, programFont, 'r');
8700     tp->end_choice = HiddenGroup (g1, 2, 0, ChangeTextPortionXGroup);
8701     RadioButton (tp->end_choice, "up to");
8702     RadioButton (tp->end_choice, "including");
8703     SetValue (tp->end_choice, TEXT_PORTION_END_AFTER);
8704     SetObjectExtra (tp->end_choice, tp, NULL);
8705 
8706     tp->end_text = DialogText (g1, "", 10, ChangeTextPortionXText);
8707     SetObjectExtra (tp->end_text, tp, NULL);
8708   }
8709   else
8710   {
8711     tp->rem_before = CheckBox (g1, "Before", ChangeTextPortionXBtn);
8712     SetObjectExtra (tp->rem_before, tp, NULL);
8713     tp->start_text = DialogText (g1, "", 10, ChangeTextPortionXText);
8714     SetObjectExtra (tp->start_text, tp, NULL);
8715     tp->also_rem_before = CheckBox (g1, "Also Remove Entered Text", ChangeTextPortionXBtn);
8716 
8717     tp->rem_after = CheckBox (g1, "After", ChangeTextPortionXBtn);
8718     SetObjectExtra (tp->rem_after, tp, NULL);
8719     tp->end_text = DialogText (g1, "", 10, ChangeTextPortionXText);
8720     SetObjectExtra (tp->end_text, tp, NULL);
8721     tp->also_rem_after = CheckBox (g1, "Also Remove Entered Text", ChangeTextPortionXBtn);
8722   }
8723 
8724   g2 = HiddenGroup (p, 2, 0, NULL);
8725   tp->insensitive = CheckBox (g2, "Case insensitive", ChangeTextPortionXBtn);
8726   SetObjectExtra (tp->insensitive, tp, NULL);
8727   tp->whole_word = CheckBox (g2, "Whole word", ChangeTextPortionXBtn);
8728   SetObjectExtra (tp->whole_word, tp, NULL);
8729 
8730   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2, NULL);
8731 
8732   ResetTextPortionXDialog (tp);
8733   return (DialoG) p;
8734 }
8735 
TextPortionXDialog(GrouP h)8736 extern DialoG TextPortionXDialog (GrouP h)
8737 {
8738   return TextPortionXDialogEx (h, TRUE, NULL, NULL);
8739 }
8740 
TextPortionXFree(TextPortionXPtr tp)8741 extern TextPortionXPtr TextPortionXFree (TextPortionXPtr tp)
8742 {
8743   if (tp == NULL) return NULL;
8744   tp->start_text = MemFree (tp->start_text);
8745   tp->end_text = MemFree (tp->end_text);
8746   tp = MemFree (tp->end_text);
8747   return tp;
8748 }
8749 
8750 
TextPortionXNew(void)8751 static TextPortionXPtr TextPortionXNew (void)
8752 {
8753   TextPortionXPtr tp;
8754 
8755   tp = (TextPortionXPtr) MemNew (sizeof (TextPortionXData));
8756   return tp;
8757 }
8758 
8759 
IsWholeWordMatch(CharPtr start,CharPtr found,Int4 match_len)8760 static Boolean IsWholeWordMatch (CharPtr start, CharPtr found, Int4 match_len)
8761 {
8762   Boolean rval = TRUE;
8763   Char    char_after;
8764   Char    char_before;
8765 
8766   if (match_len == 0)
8767   {
8768     rval = TRUE;
8769   }
8770   else if (start == NULL || found == NULL)
8771   {
8772     rval = FALSE;
8773   }
8774   else
8775   {
8776       char_after = *(found + match_len);
8777     if (found != start)
8778       {
8779         char_before = *(found - 1);
8780         if (isalpha ((Int4) char_before) || isdigit ((Int4) char_before))
8781         {
8782           rval = FALSE;
8783         }
8784       }
8785       if (char_after != 0 && (isalpha ((Int4) char_after) || isdigit ((Int4)char_after)))
8786       {
8787         rval = FALSE;
8788       }
8789   }
8790   return rval;
8791 }
8792 
8793 extern void
FindTextPortionXInString(CharPtr str,TextPortionXPtr tp,CharPtr PNTR ploc,Int4Ptr plen)8794 FindTextPortionXInString
8795 (CharPtr        str,
8796  TextPortionXPtr tp,
8797  CharPtr PNTR   ploc,
8798  Int4Ptr        plen)
8799 {
8800   CharPtr found_start, found_end;
8801   Int4    found_len;
8802 
8803   if (ploc == NULL || plen == NULL || tp == NULL)
8804   {
8805     return;
8806   }
8807   *ploc = NULL;
8808   *plen = 0;
8809 
8810   if (str == NULL)
8811   {
8812     return;
8813   }
8814 
8815   if (tp->start_text == NULL || tp->start_text [0] == 0)
8816   {
8817     found_start = str;
8818   }
8819   else
8820   {
8821     if (tp->insensitive)
8822     {
8823       found_start = StringISearch (str, tp->start_text);
8824     }
8825     else
8826     {
8827       found_start = StringSearch (str, tp->start_text);
8828     }
8829 
8830     if (tp->whole_word && ! IsWholeWordMatch (str, found_start, StringLen (tp->start_text)))
8831     {
8832       found_start = NULL;
8833     }
8834   }
8835 
8836   if (found_start == NULL)
8837   {
8838     return;
8839   }
8840 
8841 
8842 
8843   if (tp->start_choice == TEXT_PORTION_START_AFTER)
8844   {
8845     found_start += StringLen (tp->start_text);
8846   }
8847 
8848   if (tp->end_text == NULL || tp->end_text [0] == 0)
8849   {
8850     found_len = StringLen (found_start);
8851   }
8852   else
8853   {
8854     if (tp->insensitive)
8855     {
8856       found_end = StringISearch (found_start, tp->end_text);
8857     }
8858     else
8859     {
8860       found_end = StringSearch (found_start, tp->end_text);
8861     }
8862     if (tp->whole_word && ! IsWholeWordMatch (str, found_end, StringLen (tp->end_text)))
8863     {
8864       found_end = NULL;
8865     }
8866 
8867     if (found_end == NULL)
8868     {
8869       found_len = 0;
8870     }
8871     else if (tp->end_choice == TEXT_PORTION_END_WITH)
8872     {
8873       found_len = (Int4)(found_end - found_start) + StringLen (tp->end_text);
8874     }
8875     else
8876     {
8877       found_len = found_end - found_start;
8878     }
8879   }
8880 
8881   if (found_len > 0)
8882   {
8883     *ploc = found_start;
8884     *plen = found_len;
8885   }
8886 }
8887 
ClearDialogBtn(ButtoN b)8888 static void ClearDialogBtn (ButtoN b)
8889 {
8890   DialoG d;
8891 
8892   d = (DialoG) GetObjectExtra (b);
8893 
8894   PointerToDialog (d, NULL);
8895 }
8896 
8897 typedef struct changecasedlg {
8898   DIALOG_MESSAGE_BLOCK
8899   GrouP change_case;
8900   GrouP options;
8901   ButtoN keep_cap_before_punct;
8902   ButtoN keep_cap_before_cap;
8903   ButtoN keep_cap_before_digit;
8904   ButtoN remove_comma;
8905 } ChangeCaseDlgData, PNTR ChangeCaseDlgPtr;
8906 
8907 typedef enum {
8908   eChangeCaseNone = 1,
8909   eChangeCaseAllLower,
8910   eChangeCaseCapFirst,
8911   eChangeCaseLowerFirstRestNoChange,
8912   eChangeCaseOptions
8913 } EChangeCaseRule;
8914 
8915 typedef struct changecase {
8916   EChangeCaseRule change;
8917   FixProductCapData fc;
8918 } ChangeCaseData, PNTR ChangeCasePtr;
8919 
8920 
ChangeCapitalizationChoice(GrouP g)8921 static void ChangeCapitalizationChoice (GrouP g)
8922 {
8923   ChangeCaseDlgPtr dlg;
8924 
8925   dlg = (ChangeCaseDlgPtr) GetObjectExtra (g);
8926   if (dlg == NULL) {
8927     return;
8928   }
8929 
8930   if (GetValue (dlg->change_case) == eChangeCaseOptions) {
8931     Enable (dlg->options);
8932   } else {
8933     Disable (dlg->options);
8934   }
8935 }
8936 
8937 
DataToChangeCaseDialog(DialoG d,Pointer data)8938 static void DataToChangeCaseDialog (DialoG d, Pointer data)
8939 {
8940   ChangeCasePtr    ccp = (ChangeCasePtr) data;
8941   ChangeCaseDlgPtr dlg = (ChangeCaseDlgPtr) GetObjectExtra (d);
8942   if (dlg == NULL) return;
8943 
8944   if (ccp == NULL || ccp->change == eChangeCaseNone) {
8945     SetValue (dlg->change_case, eChangeCaseNone);
8946   } else {
8947     SetValue (dlg->change_case, ccp->change);
8948     if (ccp->change == eChangeCaseOptions) {
8949       SetStatus (dlg->keep_cap_before_cap, ccp->fc.keep_cap_before_cap);
8950       SetStatus (dlg->keep_cap_before_punct, ccp->fc.keep_cap_before_punct);
8951       SetStatus (dlg->keep_cap_before_digit, ccp->fc.keep_cap_before_digit);
8952       if (StringChr (ccp->fc.remove_list, ',') == NULL) {
8953         SetStatus (dlg->remove_comma, FALSE);
8954       } else {
8955         SetStatus (dlg->remove_comma, TRUE);
8956       }
8957     }
8958   }
8959   ChangeCapitalizationChoice (dlg->options);
8960 }
8961 
ChangeCaseDialogToData(DialoG d)8962 static Pointer ChangeCaseDialogToData (DialoG d)
8963 {
8964   ChangeCaseDlgPtr dlg = (ChangeCaseDlgPtr) GetObjectExtra (d);
8965   ChangeCasePtr    ccp = (ChangeCasePtr) MemNew (sizeof (ChangeCaseData));
8966 
8967   if (dlg == NULL) {
8968     ccp->change = eChangeCaseNone;
8969     MemSet (&(ccp->fc), 0, sizeof (FixProductCapData));
8970   } else {
8971     ccp->change = GetValue (dlg->change_case);
8972     if (ccp->change == eChangeCaseOptions) {
8973       ccp->fc.keep_cap_before_cap = GetStatus (dlg->keep_cap_before_cap);
8974       ccp->fc.keep_cap_before_punct = GetStatus (dlg->keep_cap_before_punct);
8975       ccp->fc.keep_cap_before_digit = GetStatus (dlg->keep_cap_before_digit);
8976       if (GetStatus (dlg->remove_comma)) {
8977         ccp->fc.remove_list = ",";
8978       } else {
8979         ccp->fc.remove_list = NULL;
8980       }
8981     } else {
8982       MemSet (&(ccp->fc), 0, sizeof (FixProductCapData));
8983     }
8984   }
8985   return ccp;
8986 }
8987 
8988 
ChangeCaseDialog(GrouP h)8989 static DialoG ChangeCaseDialog (GrouP h)
8990 {
8991   ChangeCaseDlgPtr dlg;
8992   GrouP            p;
8993 
8994   dlg = (ChangeCaseDlgPtr) MemNew (sizeof (ChangeCaseDlgData));
8995   if (dlg == NULL)
8996   {
8997     return NULL;
8998   }
8999 
9000   p = HiddenGroup (h, -1, 0, NULL);
9001   SetObjectExtra (p, dlg, StdCleanupExtraProc);
9002   SetGroupSpacing (p, 10, 10);
9003 
9004   dlg->dialog = (DialoG) p;
9005   dlg->todialog = DataToChangeCaseDialog;
9006   dlg->fromdialog = ChangeCaseDialogToData;
9007   dlg->dialogmessage = NULL;
9008   dlg->testdialog = NULL;
9009 
9010   dlg->change_case = NormalGroup (p, 3, 0, "Capitalization", programFont, ChangeCapitalizationChoice);
9011   SetObjectExtra (dlg->change_case, dlg, NULL);
9012   SetGroupSpacing (dlg->change_case, 10, 10);
9013 
9014   RadioButton (dlg->change_case, "No change");
9015   RadioButton (dlg->change_case, "To lower");
9016   RadioButton (dlg->change_case, "First cap, rest lower");
9017   RadioButton (dlg->change_case, "First lower, rest no change");
9018   RadioButton (dlg->change_case, "Special options");
9019 
9020   dlg->options = HiddenGroup (p, 0, 4, NULL);
9021   dlg->keep_cap_before_punct = CheckBox (dlg->options, "Keep caps before punctuation", NULL);
9022   dlg->keep_cap_before_cap = CheckBox (dlg->options, "Keep caps before caps", NULL);
9023   dlg->keep_cap_before_digit = CheckBox (dlg->options, "Keep caps before numbers", NULL);
9024   dlg->remove_comma = CheckBox (dlg->options, "Remove comma", NULL);
9025 
9026   SetValue (dlg->change_case, eChangeCaseNone);
9027   Disable (dlg->options);
9028 
9029   return (DialoG) p;
9030 }
9031 
9032 
ChangeCase(CharPtr PNTR pText,ChangeCasePtr ccp,ValNodePtr orgnames)9033 static void ChangeCase (CharPtr PNTR pText, ChangeCasePtr ccp, ValNodePtr orgnames)
9034 {
9035   if (ccp != NULL) {
9036     switch (ccp->change) {
9037       case eChangeCaseNone:
9038         break;
9039       case eChangeCaseAllLower:
9040         FixCapitalizationInTitle (pText, FALSE, orgnames);
9041         break;
9042       case eChangeCaseCapFirst:
9043         FixCapitalizationInTitle (pText, TRUE, orgnames);
9044         break;
9045       case eChangeCaseLowerFirstRestNoChange:
9046         if (pText != NULL && *pText != NULL && isalpha (**pText)) {
9047           **pText = tolower (**pText);
9048         }
9049         break;
9050       case eChangeCaseOptions:
9051         FixProductCapitalizationInString (pText, &(ccp->fc));
9052         break;
9053     }
9054   }
9055 }
9056 
9057 typedef struct stringconstraintdialog
9058 {
9059   DIALOG_MESSAGE_BLOCK
9060   PopuP  match_choice;
9061   TexT   match_text;
9062   ButtoN insensitive;
9063   ButtoN whole_word;
9064 } StringConstraintDialogXData, PNTR StringConstraintDialogXPtr;
9065 
ResetStringConstraintDialogX(StringConstraintDialogXPtr scdp)9066 static void ResetStringConstraintDialogX (StringConstraintDialogXPtr scdp)
9067 {
9068   if (scdp == NULL) return;
9069 
9070   SetValue (scdp->match_choice, 1);
9071   SetTitle (scdp->match_text, "");
9072   SetStatus (scdp->insensitive, FALSE);
9073   SetStatus (scdp->whole_word, FALSE);
9074 }
9075 
9076 
GetPopupPosForStringConstraint(StringConstraintXPtr scp)9077 static Int4 GetPopupPosForStringConstraint (StringConstraintXPtr scp)
9078 {
9079   Int4 rval = 1;
9080 
9081   if (scp == NULL) return 1;
9082 
9083   switch (scp->match_location)
9084   {
9085     case eStringConstraintContains:
9086       if (scp->not_present)
9087       {
9088         rval = 2;
9089       } else {
9090         rval = 1;
9091       }
9092       break;
9093     case eStringConstraintEquals:
9094       if (scp->not_present) {
9095         rval = 4;
9096       } else {
9097         rval = 3;
9098       }
9099       break;
9100     case eStringConstraintStarts:
9101       if (scp->not_present) {
9102         rval = 9;
9103       } else {
9104         rval = 5;
9105       }
9106       break;
9107     case eStringConstraintEnds:
9108       if (scp->not_present) {
9109         rval = 10;
9110       } else {
9111         rval = 6;
9112       }
9113       break;
9114     case eStringConstraintInList:
9115       if (scp->not_present) {
9116         rval = 8;
9117       } else {
9118         rval = 7;
9119       }
9120       break;
9121   }
9122   return rval;
9123 }
9124 
9125 
StringConstraintToDialog(DialoG d,Pointer data)9126 static void StringConstraintToDialog (DialoG d, Pointer data)
9127 
9128 {
9129   StringConstraintDialogXPtr scdp;
9130   StringConstraintXPtr       scp;
9131 
9132   scdp = (StringConstraintDialogXPtr) GetObjectExtra (d);
9133   scp = (StringConstraintXPtr) data;
9134   if (scdp == NULL)
9135   {
9136     return;
9137   }
9138 
9139   if (scp == NULL)
9140   {
9141     ResetStringConstraintDialogX (scdp);
9142   }
9143   else
9144   {
9145     SetValue (scdp->match_choice, GetPopupPosForStringConstraint (scp));
9146 
9147     if (StringHasNoText (scp->match_text))
9148     {
9149       SetTitle (scdp->match_text, " ");
9150     }
9151     else
9152     {
9153       SetTitle (scdp->match_text, scp->match_text);
9154     }
9155 
9156     SetStatus (scdp->insensitive, scp->insensitive);
9157     SetStatus (scdp->whole_word, scp->whole_word);
9158   }
9159 }
9160 
DialogToStringConstraint(DialoG d)9161 static Pointer DialogToStringConstraint (DialoG d)
9162 
9163 {
9164   StringConstraintDialogXPtr scdp;
9165   StringConstraintXPtr       scp;
9166   Int4                      match_choice;
9167 
9168   scdp = (StringConstraintDialogXPtr) GetObjectExtra (d);
9169   if (scdp == NULL)
9170   {
9171     return NULL;
9172   }
9173   scp = (StringConstraintXPtr) MemNew (sizeof (StringConstraintData));
9174   if (scp != NULL)
9175   {
9176     scp->match_text = SaveStringFromText (scdp->match_text);
9177     scp->insensitive = GetStatus (scdp->insensitive);
9178     scp->whole_word = GetStatus (scdp->whole_word);
9179     match_choice = GetValue (scdp->match_choice);
9180     switch (match_choice)
9181     {
9182       case 1:
9183         scp->match_location = eStringConstraintContains;
9184         scp->not_present = FALSE;
9185         break;
9186       case 2:
9187         scp->match_location = eStringConstraintContains;
9188         scp->not_present = TRUE;
9189         break;
9190       case 3:
9191         scp->match_location = eStringConstraintEquals;
9192         scp->not_present = FALSE;
9193         break;
9194       case 4:
9195         scp->match_location = eStringConstraintEquals;
9196         scp->not_present = TRUE;
9197         break;
9198       case 5:
9199         scp->match_location = eStringConstraintStarts;
9200         scp->not_present = FALSE;
9201         break;
9202       case 6:
9203         scp->match_location = eStringConstraintEnds;
9204         scp->not_present = FALSE;
9205         break;
9206       case 7:
9207         scp->match_location = eStringConstraintInList;
9208         scp->not_present = FALSE;
9209         break;
9210       case 8:
9211         scp->match_location = eStringConstraintInList;
9212         scp->not_present = TRUE;
9213         break;
9214       case 9:
9215         scp->match_location = eStringConstraintStarts;
9216         scp->not_present = TRUE;
9217         break;
9218       case 10:
9219         scp->match_location = eStringConstraintEnds;
9220         scp->not_present = TRUE;
9221         break;
9222       default:
9223         scp->match_location = eStringConstraintContains;
9224         scp->not_present = FALSE;
9225         break;
9226     }
9227   }
9228   return scp;
9229 }
9230 
StringConstraintMessage(DialoG d,Int2 mssg)9231 static void StringConstraintMessage (DialoG d, Int2 mssg)
9232 
9233 {
9234   StringConstraintDialogXPtr scdp;
9235 
9236   scdp = (StringConstraintDialogXPtr) GetObjectExtra (d);
9237   if (scdp != NULL) {
9238     switch (mssg) {
9239       case VIB_MSG_INIT :
9240         ResetStringConstraintDialogX (scdp);
9241         break;
9242       case VIB_MSG_ENTER :
9243         Select (scdp->match_text);
9244         break;
9245       default :
9246         break;
9247     }
9248   }
9249 }
9250 
TestStringConstraintDialogX(DialoG d)9251 static ValNodePtr TestStringConstraintDialogX (DialoG d)
9252 
9253 {
9254   return NULL;
9255 }
9256 
StringConstraintDialogX(GrouP h,CharPtr label,Boolean clear_btn)9257 extern DialoG StringConstraintDialogX (GrouP h, CharPtr label, Boolean clear_btn)
9258 
9259 {
9260   StringConstraintDialogXPtr scdp;
9261   GrouP                     p, g, k;
9262   ButtoN                    b = NULL;
9263 
9264   scdp = (StringConstraintDialogXPtr) MemNew (sizeof (StringConstraintDialogXData));
9265   if (scdp == NULL)
9266   {
9267     return NULL;
9268   }
9269 
9270   p = HiddenGroup (h, -1, 0, NULL);
9271   SetObjectExtra (p, scdp, StdCleanupExtraProc);
9272 
9273   scdp->dialog = (DialoG) p;
9274   scdp->todialog = StringConstraintToDialog;
9275   scdp->fromdialog = DialogToStringConstraint;
9276   scdp->dialogmessage = StringConstraintMessage;
9277   scdp->testdialog = TestStringConstraintDialogX;
9278 
9279   g = HiddenGroup (p, 3, 0, NULL);
9280   SetGroupSpacing (g, 10, 10);
9281 
9282   if (!StringHasNoText (label))
9283   {
9284     StaticPrompt (g, label, 0, dialogTextHeight, systemFont, 'l');
9285   }
9286 
9287   scdp->match_choice = PopupList (g, TRUE, NULL);
9288   PopupItem (scdp->match_choice, "Contains");
9289   PopupItem (scdp->match_choice, "Does not contain");
9290   PopupItem (scdp->match_choice, "Equals");
9291   PopupItem (scdp->match_choice, "Does not equal");
9292   PopupItem (scdp->match_choice, "Starts with");
9293   PopupItem (scdp->match_choice, "Ends with");
9294   PopupItem (scdp->match_choice, "Is one of");
9295   PopupItem (scdp->match_choice, "Is not one of");
9296   PopupItem (scdp->match_choice, "Does not start with");
9297   PopupItem (scdp->match_choice, "Does not end with");
9298   SetValue (scdp->match_choice, 1);
9299   scdp->match_text = DialogText (g, "", 15, NULL);
9300 
9301   k = HiddenGroup (p, 3, 0, NULL);
9302   SetGroupSpacing (k, 10, 10);
9303   scdp->insensitive = CheckBox (k, "Case Insensitive", NULL);
9304   scdp->whole_word = CheckBox (k, "Whole Word", NULL);
9305 
9306   if (clear_btn)
9307   {
9308     b = PushButton (p, "Clear Constraint", ClearDialogBtn);
9309     SetObjectExtra (b, p, NULL);
9310   }
9311 
9312   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) k, (HANDLE) b, NULL);
9313 
9314   return (DialoG) p;
9315 }
9316 
9317 
9318 typedef struct pseudoconstraintdialog
9319 {
9320   DIALOG_MESSAGE_BLOCK
9321   GrouP  pseudo_choice;
9322   DialoG feature_choice;
9323 } PseudoConstraintDialogData, PNTR PseudoConstraintDialogPtr;
9324 
ENUM_ALIST(pseudoconstraint_alist)9325 static ENUM_ALIST(pseudoconstraint_alist)
9326 {"Any Feature",   FEATDEF_ANY  },
9327 {"CDS",   FEATDEF_CDS  },
9328 {"Gene",  FEATDEF_GENE },
9329 {"mRNA",  FEATDEF_mRNA },
9330 END_ENUM_ALIST
9331 
9332 static void ResetPseudoConstraintDialog (PseudoConstraintDialogPtr pcdp)
9333 {
9334   if (pcdp != NULL)
9335   {
9336     SetValue (pcdp->pseudo_choice, 1);
9337     SendMessageToDialog (pcdp->feature_choice, VIB_MSG_INIT);
9338   }
9339 }
9340 
PseudoConstraintToDialog(DialoG d,Pointer data)9341 static void PseudoConstraintToDialog (DialoG d, Pointer data)
9342 {
9343   PseudoConstraintDialogPtr pcdp;
9344   PseudoConstraintPtr       pcp;
9345   ValNode                   vn;
9346 
9347   pcdp = (PseudoConstraintDialogPtr) GetObjectExtra (d);
9348 
9349   if (pcdp != NULL)
9350   {
9351     ResetPseudoConstraintDialog (pcdp);
9352     pcp = (PseudoConstraintPtr) data;
9353     if (pcp != NULL)
9354     {
9355       if (pcp->is_pseudo)
9356       {
9357         SetValue (pcdp->pseudo_choice, 1);
9358       }
9359       else
9360       {
9361         SetValue (pcdp->pseudo_choice, 2);
9362       }
9363       vn.choice = pcp->featdef_type;
9364       vn.data.ptrvalue = NULL;
9365       vn.next = NULL;
9366       PointerToDialog (pcdp->feature_choice, &vn);
9367     }
9368   }
9369 }
9370 
DialogToPseudoConstraint(DialoG d)9371 static Pointer DialogToPseudoConstraint (DialoG d)
9372 {
9373   PseudoConstraintDialogPtr pcdp;
9374   PseudoConstraintPtr       pcp;
9375   ValNodePtr                vnp;
9376 
9377   pcdp = (PseudoConstraintDialogPtr) GetObjectExtra (d);
9378   if (pcdp == NULL) return NULL;
9379   pcp = (PseudoConstraintPtr) MemNew (sizeof (PseudoConstraintData));
9380   if (pcp != NULL)
9381   {
9382     if (GetValue (pcdp->pseudo_choice) == 1)
9383     {
9384       pcp->is_pseudo = TRUE;
9385     }
9386     else
9387     {
9388       pcp->is_pseudo = FALSE;
9389     }
9390     vnp = DialogToPointer (pcdp->feature_choice);
9391     if (vnp == NULL)
9392     {
9393       pcp->featdef_type = FEATDEF_ANY;
9394     }
9395     else
9396     {
9397       pcp->featdef_type = vnp->choice;
9398     }
9399     ValNodeFreeData (vnp);
9400   }
9401   return pcp;
9402 }
9403 
PseudoConstraintMessage(DialoG d,Int2 mssg)9404 static void PseudoConstraintMessage (DialoG d, Int2 mssg)
9405 
9406 {
9407   PseudoConstraintDialogPtr pcdp;
9408 
9409   pcdp = (PseudoConstraintDialogPtr) GetObjectExtra (d);
9410   if (pcdp != NULL) {
9411     switch (mssg) {
9412       case VIB_MSG_INIT :
9413         ResetPseudoConstraintDialog (pcdp);
9414         break;
9415       case VIB_MSG_ENTER :
9416         Select (pcdp->feature_choice);
9417         break;
9418       default :
9419         break;
9420     }
9421   }
9422 }
9423 
TestPseudoConstraintDialog(DialoG d)9424 static ValNodePtr TestPseudoConstraintDialog (DialoG d)
9425 
9426 {
9427   return NULL;
9428 }
9429 
PseudoConstraintDialog(GrouP h)9430 static DialoG PseudoConstraintDialog (GrouP h)
9431 {
9432   PseudoConstraintDialogPtr pcdp;
9433   GrouP                     p;
9434 
9435   pcdp = (PseudoConstraintDialogPtr) MemNew (sizeof (PseudoConstraintDialogData));
9436   if (pcdp == NULL)
9437   {
9438     return NULL;
9439   }
9440 
9441   p = HiddenGroup (h, 2, 0, NULL);
9442   SetObjectExtra (p, pcdp, StdCleanupExtraProc);
9443   SetGroupSpacing (p, 10, 10);
9444 
9445   pcdp->dialog = (DialoG) p;
9446   pcdp->todialog = PseudoConstraintToDialog;
9447   pcdp->fromdialog = DialogToPseudoConstraint;
9448   pcdp->dialogmessage = PseudoConstraintMessage;
9449   pcdp->testdialog = TestPseudoConstraintDialog;
9450 
9451   pcdp->feature_choice = EnumAssocSelectionDialog (p, pseudoconstraint_alist,
9452                                                    "feature", FALSE, NULL, NULL);
9453 
9454   pcdp->pseudo_choice = HiddenGroup (p, 2, 0, NULL);
9455   RadioButton (pcdp->pseudo_choice, "Is Pseudo");
9456   RadioButton (pcdp->pseudo_choice, "Is Not Pseudo");
9457   SetValue (pcdp->pseudo_choice, 1);
9458 
9459   return (DialoG) p;
9460 }
9461 
9462 typedef struct choiceconstraintdialog
9463 {
9464   DIALOG_MESSAGE_BLOCK
9465   GrouP               constraint_type;
9466   DialoG              present_qual_choice;
9467   DialoG              string_qual_choice;
9468   DialoG              string_constraint;
9469   DialoG              pseudo_constraint;
9470   DialoG              match_1;
9471   DialoG              match_2;
9472   FreeValNodeProc     free_vn_proc;
9473   CopyValNodeDataProc copy_vn_proc;
9474 } ChoiceConstraintDialogData, PNTR ChoiceConstraintDialogPtr;
9475 
ChangeChoiceConstraintType(GrouP p)9476 static void ChangeChoiceConstraintType (GrouP p)
9477 {
9478   ChoiceConstraintDialogPtr scdp;
9479   Int4                      constraint_type;
9480 
9481   scdp = (ChoiceConstraintDialogPtr) GetObjectExtra (p);
9482   if (scdp == NULL)
9483   {
9484     return;
9485   }
9486 
9487   constraint_type = GetValue (scdp->constraint_type);
9488   if (constraint_type == CHOICE_CONSTRAINT_QUAL_PRESENT)
9489   {
9490     Enable (scdp->present_qual_choice);
9491     Disable (scdp->string_qual_choice);
9492     Disable (scdp->string_constraint);
9493     Disable (scdp->match_1);
9494     Disable (scdp->match_2);
9495     SafeDisable (scdp->pseudo_constraint);
9496   }
9497   else if (constraint_type == CHOICE_CONSTRAINT_STRING)
9498   {
9499     Enable (scdp->string_qual_choice);
9500     Enable (scdp->string_constraint);
9501     Disable (scdp->present_qual_choice);
9502     Disable (scdp->match_1);
9503     Disable (scdp->match_2);
9504     SafeDisable (scdp->pseudo_constraint);
9505   }
9506   else if (constraint_type == CHOICE_CONSTRAINT_MATCH)
9507   {
9508     Enable (scdp->match_1);
9509     Enable (scdp->match_2);
9510     Disable (scdp->string_qual_choice);
9511     Disable (scdp->string_constraint);
9512     Disable (scdp->present_qual_choice);
9513     SafeDisable (scdp->pseudo_constraint);
9514   }
9515   else if (constraint_type == CHOICE_CONSTRAINT_PSEUDO)
9516   {
9517     Disable (scdp->present_qual_choice);
9518     Disable (scdp->string_qual_choice);
9519     Disable (scdp->string_constraint);
9520     Disable (scdp->match_1);
9521     Disable (scdp->match_2);
9522     Enable (scdp->pseudo_constraint);
9523   }
9524   else
9525   {
9526     Disable (scdp->present_qual_choice);
9527     Disable (scdp->string_qual_choice);
9528     Disable (scdp->string_constraint);
9529     Disable (scdp->match_1);
9530     Disable (scdp->match_2);
9531     SafeDisable (scdp->pseudo_constraint);
9532   }
9533 }
9534 
ResetChoiceConstraintDialog(ChoiceConstraintDialogPtr scdp)9535 static void ResetChoiceConstraintDialog (ChoiceConstraintDialogPtr scdp)
9536 {
9537   if (scdp != NULL)
9538   {
9539     SetValue (scdp->constraint_type, CHOICE_CONSTRAINT_ANY);
9540     PointerToDialog (scdp->present_qual_choice, NULL);
9541     PointerToDialog (scdp->string_qual_choice, NULL);
9542     PointerToDialog (scdp->string_constraint, NULL);
9543     PointerToDialog (scdp->pseudo_constraint, NULL);
9544     ChangeChoiceConstraintType (scdp->constraint_type);
9545   }
9546 }
9547 
ChoiceConstraintToDialog(DialoG d,Pointer data)9548 static void ChoiceConstraintToDialog (DialoG d, Pointer data)
9549 {
9550   ChoiceConstraintDialogPtr src_dlg;
9551   ChoiceConstraintPtr       src_data;
9552   Int4 constraint_type;
9553 
9554   src_dlg = (ChoiceConstraintDialogPtr) GetObjectExtra (d);
9555   if (src_dlg == NULL)
9556   {
9557     return;
9558   }
9559   src_data = (ChoiceConstraintPtr) data;
9560   if (src_data == NULL)
9561   {
9562     ResetChoiceConstraintDialog (src_dlg);
9563   }
9564   else
9565   {
9566     constraint_type = src_data->constraint_type;
9567     if (constraint_type < CHOICE_CONSTRAINT_ANY || constraint_type > CHOICE_CONSTRAINT_PSEUDO)
9568     {
9569       constraint_type = CHOICE_CONSTRAINT_ANY;
9570     }
9571     SetValue (src_dlg->constraint_type, constraint_type);
9572     if (constraint_type == CHOICE_CONSTRAINT_QUAL_PRESENT)
9573     {
9574       PointerToDialog (src_dlg->present_qual_choice, src_data->qual_choice);
9575     }
9576     else if (constraint_type == CHOICE_CONSTRAINT_STRING)
9577     {
9578       PointerToDialog (src_dlg->string_qual_choice, src_data->qual_choice);
9579       PointerToDialog (src_dlg->string_constraint, src_data->string_constraint);
9580     }
9581     else if (constraint_type == CHOICE_CONSTRAINT_MATCH)
9582     {
9583       PointerToDialog (src_dlg->match_1, src_data->qual_choice);
9584       PointerToDialog (src_dlg->match_2, src_data->qual_choice_match);
9585     }
9586     else if (constraint_type == CHOICE_CONSTRAINT_PSEUDO)
9587     {
9588       PointerToDialog (src_dlg->pseudo_constraint, src_data->pseudo_constraint);
9589     }
9590     ChangeChoiceConstraintType (src_dlg->constraint_type);
9591   }
9592 }
9593 
DialogToChoiceConstraint(DialoG d)9594 static Pointer DialogToChoiceConstraint (DialoG d)
9595 {
9596   ChoiceConstraintDialogPtr src_dlg;
9597   ChoiceConstraintPtr       src_data;
9598 
9599   src_dlg = (ChoiceConstraintDialogPtr) GetObjectExtra (d);
9600   if (src_dlg == NULL)
9601   {
9602     return NULL;
9603   }
9604 
9605   src_data = (ChoiceConstraintPtr) MemNew (sizeof (ChoiceConstraintData));
9606   if (src_data != NULL)
9607   {
9608     src_data->constraint_type = GetValue (src_dlg->constraint_type);
9609     if (src_data->constraint_type == CHOICE_CONSTRAINT_QUAL_PRESENT)
9610     {
9611       src_data->qual_choice = DialogToPointer (src_dlg->present_qual_choice);
9612     }
9613     else if (src_data->constraint_type == CHOICE_CONSTRAINT_STRING)
9614     {
9615       src_data->qual_choice = DialogToPointer (src_dlg->string_qual_choice);
9616       src_data->string_constraint = DialogToPointer (src_dlg->string_constraint);
9617     }
9618     else if (src_data->constraint_type == CHOICE_CONSTRAINT_MATCH)
9619     {
9620       src_data->qual_choice = DialogToPointer (src_dlg->match_1);
9621       src_data->qual_choice_match = DialogToPointer (src_dlg->match_2);
9622     }
9623     else if (src_data->constraint_type == CHOICE_CONSTRAINT_PSEUDO)
9624     {
9625       src_data->pseudo_constraint = DialogToPointer (src_dlg->pseudo_constraint);
9626     }
9627     src_data->free_vn_proc = src_dlg->free_vn_proc;
9628     src_data->copy_vn_proc = src_dlg->copy_vn_proc;
9629   }
9630   return src_data;
9631 }
9632 
ChoiceConstraintMessage(DialoG d,Int2 mssg)9633 static void ChoiceConstraintMessage (DialoG d, Int2 mssg)
9634 
9635 {
9636   ChoiceConstraintDialogPtr scdp;
9637 
9638   scdp = (ChoiceConstraintDialogPtr) GetObjectExtra (d);
9639   if (scdp != NULL) {
9640     switch (mssg) {
9641       case VIB_MSG_INIT :
9642         ResetChoiceConstraintDialog (scdp);
9643         break;
9644       case VIB_MSG_ENTER :
9645         Select (scdp->constraint_type);
9646         break;
9647       default :
9648         break;
9649     }
9650   }
9651 }
9652 
TestChoiceConstraintDialog(DialoG d)9653 static ValNodePtr TestChoiceConstraintDialog (DialoG d)
9654 
9655 {
9656   return NULL;
9657 }
9658 
9659 extern DialoG
ConstraintChoiceDialog(GrouP h,FeatureFieldSelectionProc func_present,FeatureFieldSelectionProc func_string,FreeValNodeProc free_vn_proc,CopyValNodeDataProc copy_vn_proc,CharPtr any_name,CharPtr present_name,Boolean clear_btn,Boolean use_pseudo)9660 ConstraintChoiceDialog
9661 (GrouP                     h,
9662  FeatureFieldSelectionProc func_present,
9663  FeatureFieldSelectionProc func_string,
9664  FreeValNodeProc           free_vn_proc,
9665  CopyValNodeDataProc       copy_vn_proc,
9666  CharPtr                   any_name,
9667  CharPtr                   present_name,
9668  Boolean                   clear_btn,
9669  Boolean                   use_pseudo)
9670 {
9671   ChoiceConstraintDialogPtr scdp;
9672   GrouP                     p, q;
9673   ButtoN                    b = NULL;
9674 
9675   scdp = (ChoiceConstraintDialogPtr) MemNew (sizeof (ChoiceConstraintDialogData));
9676   if (scdp == NULL)
9677   {
9678     return NULL;
9679   }
9680 
9681   p = HiddenGroup (h, -1, 0, NULL);
9682   SetObjectExtra (p, scdp, StdCleanupExtraProc);
9683   SetGroupSpacing (p, 10, 10);
9684 
9685   scdp->dialog = (DialoG) p;
9686   scdp->todialog = ChoiceConstraintToDialog;
9687   scdp->fromdialog = DialogToChoiceConstraint;
9688   scdp->dialogmessage = ChoiceConstraintMessage;
9689   scdp->testdialog = TestChoiceConstraintDialog;
9690 
9691   scdp->constraint_type = HiddenGroup (p, 2, 0, ChangeChoiceConstraintType);
9692   RadioButton (scdp->constraint_type, any_name);
9693   StaticPrompt (scdp->constraint_type, "", 0, dialogTextHeight, systemFont, 'l');
9694 
9695   RadioButton (scdp->constraint_type, present_name);
9696   scdp->present_qual_choice = func_present (scdp->constraint_type, FALSE, NULL, NULL);
9697 
9698   RadioButton (scdp->constraint_type, "When");
9699   q = HiddenGroup (scdp->constraint_type, 2, 0, NULL);
9700   scdp->string_qual_choice = func_string (q, TRUE, NULL, NULL);
9701   scdp->string_constraint = StringConstraintDialogX (q, NULL, FALSE);
9702 
9703   RadioButton (scdp->constraint_type, "When");
9704   q = HiddenGroup (scdp->constraint_type, 3, 0, NULL);
9705   scdp->match_1 = func_string (q, TRUE, NULL, NULL);
9706   StaticPrompt (q, "Equals", 0, dialogTextHeight, systemFont, 'l');
9707   scdp->match_2 = func_string (q, TRUE, NULL, NULL);
9708 
9709   if (use_pseudo)
9710   {
9711     RadioButton (scdp->constraint_type, "When");
9712     scdp->pseudo_constraint = PseudoConstraintDialog (scdp->constraint_type);
9713   }
9714   else
9715   {
9716     scdp->pseudo_constraint = NULL;
9717   }
9718 
9719   SetValue (scdp->constraint_type, CHOICE_CONSTRAINT_ANY);
9720   SetObjectExtra (scdp->constraint_type, scdp, NULL);
9721 
9722   Disable (scdp->present_qual_choice);
9723   Disable (scdp->string_qual_choice);
9724   Disable (scdp->string_constraint);
9725   Disable (scdp->match_1);
9726   Disable (scdp->match_2);
9727 
9728   scdp->free_vn_proc = free_vn_proc;
9729   scdp->copy_vn_proc = copy_vn_proc;
9730 
9731   if (clear_btn)
9732   {
9733     b = PushButton (p, "Clear Constraint", ClearDialogBtn);
9734     SetObjectExtra (b, p, NULL);
9735   }
9736 
9737   AlignObjects (ALIGN_CENTER, (HANDLE) scdp->constraint_type, (HANDLE) b, NULL);
9738 
9739   return (DialoG) p;
9740 }
9741 
SourceConstraintDialogX(GrouP h,Boolean clear_btn)9742 extern DialoG SourceConstraintDialogX (GrouP h, Boolean clear_btn)
9743 {
9744   return ConstraintChoiceDialog (h, SourceQualTypeConstraintSelectionDialog,
9745                                  SourceStringConstraintSelectionDialog,
9746                                  ValNodeSimpleDataFree,
9747                                  SourceQualValNodeDataCopy,
9748                                  "For any source", "When qualifier present:",
9749                                  clear_btn,
9750                                  FALSE);
9751 }
9752 
9753 
CDSGeneProtConstraintDialog(GrouP h,Boolean clear_btn)9754 extern DialoG CDSGeneProtConstraintDialog (GrouP h, Boolean clear_btn)
9755 {
9756   return ConstraintChoiceDialog (h, CDSGeneProtFieldSelectionDialog,
9757                                  CDSGeneProtFieldConstraintSelectionDialog,
9758                                  NULL, IntValNodeCopy,
9759                                  "For any CDS-Gene-Prot-mRNA set",
9760                                  "When field present:",
9761                                  clear_btn, TRUE);
9762 }
9763 
9764 typedef struct LocationConstraintXdialog
9765 {
9766   DIALOG_MESSAGE_BLOCK
9767   PopuP  interval_end_choice;
9768   PopuP  interval_match_choice;
9769   PopuP  endpoint_match_choice;
9770   TexT   only_val;
9771   TexT   first_val;
9772   TexT   second_val;
9773   PrompT second_val_prompt;
9774   PopuP  strand;
9775   PopuP  sequence_type;
9776   Boolean show_interval_controls;
9777 } LocationConstraintXDialogData, PNTR LocationConstraintXDialogPtr;
9778 
ShowLocationChoiceControls(PopuP p)9779 static void ShowLocationChoiceControls (PopuP p)
9780 
9781 {
9782   LocationConstraintXDialogPtr lcdp;
9783   Int4                        match_choice;
9784 
9785   lcdp = (LocationConstraintXDialogPtr) GetObjectExtra (p);
9786   if (lcdp == NULL || lcdp->interval_end_choice == NULL) return;
9787 
9788   if (GetValue (lcdp->interval_end_choice) == LOCATION_CONSTRAINT_WHOLE_INTERVAL)
9789   {
9790     Show (lcdp->interval_match_choice);
9791     Hide (lcdp->endpoint_match_choice);
9792     if (p == lcdp->interval_end_choice)
9793     {
9794       SetValue (lcdp->interval_match_choice, GetValue (lcdp->endpoint_match_choice));
9795     }
9796     match_choice = GetValue (lcdp->interval_match_choice);
9797   }
9798   else
9799   {
9800     Hide (lcdp->interval_match_choice);
9801     Show (lcdp->endpoint_match_choice);
9802     if (p == lcdp->interval_end_choice)
9803     {
9804       SetValue (lcdp->endpoint_match_choice, GetValue (lcdp->interval_match_choice));
9805     }
9806     match_choice = GetValue (lcdp->endpoint_match_choice);
9807   }
9808 
9809   switch (match_choice)
9810   {
9811     case LOCATION_CONSTRAINT_ANY :
9812       Hide (lcdp->only_val);
9813       Hide (lcdp->first_val);
9814       Hide (lcdp->second_val_prompt);
9815       Hide (lcdp->second_val);
9816       break;
9817     case LOCATION_CONSTRAINT_UPSTREAM :
9818     case LOCATION_CONSTRAINT_DOWNSTREAM :
9819       Show (lcdp->only_val);
9820       Hide (lcdp->first_val);
9821       Hide (lcdp->second_val_prompt);
9822       Hide (lcdp->second_val);
9823       break;
9824     case LOCATION_CONSTRAINT_CONTAINED :
9825     case LOCATION_CONSTRAINT_NOT_IN :
9826     case LOCATION_CONSTRAINT_OVERLAP :
9827     case LOCATION_CONSTRAINT_EQUAL :
9828       Hide (lcdp->only_val);
9829       Show (lcdp->first_val);
9830       Show (lcdp->second_val_prompt);
9831       Show (lcdp->second_val);
9832       break;
9833   }
9834 }
9835 
ResetLocationConstraintXDialog(LocationConstraintXDialogPtr lcdp)9836 static void ResetLocationConstraintXDialog (LocationConstraintXDialogPtr lcdp)
9837 {
9838   if (lcdp == NULL) return;
9839 
9840   SafeSetValue (lcdp->interval_end_choice, LOCATION_CONSTRAINT_WHOLE_INTERVAL);
9841   SafeSetValue (lcdp->interval_match_choice, LOCATION_CONSTRAINT_ANY);
9842   SafeSetTitle (lcdp->only_val, "");
9843   SafeSetTitle (lcdp->first_val, "");
9844   SafeSetTitle (lcdp->second_val, "");
9845   SetValue (lcdp->strand, LOCATION_CONSTRAINT_ANY_STRAND);
9846   SetValue (lcdp->sequence_type, LOCATION_CONSTRAINT_ANY_SEQ);
9847   ShowLocationChoiceControls (lcdp->interval_end_choice);
9848 }
9849 
LocationConstraintXToDialog(DialoG d,Pointer data)9850 static void LocationConstraintXToDialog (DialoG d, Pointer data)
9851 
9852 {
9853   LocationConstraintXDialogPtr lcdp;
9854   LocationConstraintXPtr       lcp;
9855   Int4                        interval_end_choice;
9856   Int4                        match_choice;
9857   Char                        tmp [15];
9858   Int4                        strand;
9859   Int4                        sequence_type;
9860 
9861   lcdp = (LocationConstraintXDialogPtr) GetObjectExtra (d);
9862   if (lcdp == NULL)
9863   {
9864     return;
9865   }
9866   lcp = (LocationConstraintXPtr) data;
9867 
9868   ResetLocationConstraintXDialog (lcdp);
9869   if (lcp != NULL)
9870   {
9871     interval_end_choice = lcp->interval_end_choice;
9872     if (interval_end_choice < LOCATION_CONSTRAINT_WHOLE_INTERVAL
9873         || interval_end_choice > LOCATION_CONSTRAINT_STOP_ENDPOINT)
9874     {
9875       interval_end_choice = LOCATION_CONSTRAINT_WHOLE_INTERVAL;
9876     }
9877     match_choice = lcp->match_choice;
9878     if (match_choice < LOCATION_CONSTRAINT_ANY)
9879     {
9880       match_choice = LOCATION_CONSTRAINT_ANY;
9881     }
9882     else if (match_choice > LOCATION_CONSTRAINT_EQUAL)
9883     {
9884       match_choice = LOCATION_CONSTRAINT_EQUAL;
9885     }
9886     if (match_choice > LOCATION_CONSTRAINT_NOT_IN && interval_end_choice != LOCATION_CONSTRAINT_WHOLE_INTERVAL)
9887     {
9888       interval_end_choice = LOCATION_CONSTRAINT_WHOLE_INTERVAL;
9889     }
9890 
9891     SetValue (lcdp->interval_end_choice, interval_end_choice);
9892     if (interval_end_choice == LOCATION_CONSTRAINT_WHOLE_INTERVAL)
9893     {
9894       SetValue (lcdp->interval_match_choice, match_choice);
9895     }
9896     else
9897     {
9898       SetValue (lcdp->endpoint_match_choice, match_choice);
9899     }
9900     switch (match_choice)
9901     {
9902       case LOCATION_CONSTRAINT_ANY :
9903         break;
9904       case LOCATION_CONSTRAINT_UPSTREAM :
9905       case LOCATION_CONSTRAINT_DOWNSTREAM :
9906         if (lcp->left >= 0)
9907         {
9908           sprintf (tmp, "%d", lcp->left + 1);
9909           SetTitle (lcdp->only_val, tmp);
9910         }
9911         break;
9912       case LOCATION_CONSTRAINT_CONTAINED :
9913       case LOCATION_CONSTRAINT_NOT_IN :
9914       case LOCATION_CONSTRAINT_OVERLAP :
9915       case LOCATION_CONSTRAINT_EQUAL :
9916         if (lcp->left >= 0)
9917         {
9918           sprintf (tmp, "%d", lcp->left + 1);
9919           SetTitle (lcdp->first_val, tmp);
9920         }
9921         if (lcp->right >= 0)
9922         {
9923           sprintf (tmp, "%d", lcp->right + 1);
9924           SetTitle (lcdp->second_val, tmp);
9925         }
9926         break;
9927     }
9928     strand = lcp->strand;
9929     if (strand < LOCATION_CONSTRAINT_ANY_STRAND || strand > LOCATION_CONSTRAINT_MINUS_STRAND)
9930     {
9931       strand = LOCATION_CONSTRAINT_ANY_STRAND;
9932     }
9933     SetValue (lcdp->strand, strand);
9934     sequence_type = lcp->sequence_type;
9935     if (sequence_type < LOCATION_CONSTRAINT_ANY_SEQ || sequence_type > LOCATION_CONSTRAINT_PROT_SEQ)
9936     {
9937       sequence_type = LOCATION_CONSTRAINT_ANY_SEQ;
9938     }
9939     SetValue (lcdp->sequence_type, LOCATION_CONSTRAINT_ANY_SEQ);
9940   }
9941   ShowLocationChoiceControls (lcdp->interval_match_choice);
9942 }
9943 
DialogToLocationConstraintX(DialoG d)9944 static Pointer DialogToLocationConstraintX (DialoG d)
9945 
9946 {
9947   LocationConstraintXDialogPtr lcdp;
9948   LocationConstraintXPtr       lcp;
9949   CharPtr                     tmp;
9950 
9951   lcdp = (LocationConstraintXDialogPtr) GetObjectExtra (d);
9952   if (lcdp == NULL)
9953   {
9954     return NULL;
9955   }
9956   lcp = (LocationConstraintXPtr) MemNew (sizeof (LocationConstraintXData));
9957   if (lcp != NULL)
9958   {
9959     if (lcdp->show_interval_controls)
9960     {
9961       lcp->interval_end_choice = GetValue (lcdp->interval_end_choice);
9962       if (lcp->interval_end_choice == LOCATION_CONSTRAINT_WHOLE_INTERVAL)
9963       {
9964         lcp->match_choice = GetValue (lcdp->interval_match_choice);
9965       }
9966       else
9967       {
9968         lcp->match_choice = GetValue (lcdp->endpoint_match_choice);
9969       }
9970       switch (lcp->match_choice)
9971       {
9972         case LOCATION_CONSTRAINT_ANY :
9973           break;
9974         case LOCATION_CONSTRAINT_UPSTREAM :
9975         case LOCATION_CONSTRAINT_DOWNSTREAM :
9976           tmp = SaveStringFromText (lcdp->only_val);
9977           if (StringHasNoText (tmp))
9978           {
9979             lcp->left = 0;
9980           }
9981           else
9982           {
9983             lcp->left = atoi (tmp) - 1;
9984           }
9985           tmp = MemFree (tmp);
9986           break;
9987         case LOCATION_CONSTRAINT_CONTAINED :
9988         case LOCATION_CONSTRAINT_NOT_IN :
9989         case LOCATION_CONSTRAINT_OVERLAP :
9990         case LOCATION_CONSTRAINT_EQUAL :
9991           tmp = SaveStringFromText (lcdp->first_val);
9992           if (StringHasNoText (tmp))
9993           {
9994             lcp->left = 0;
9995           }
9996           else
9997           {
9998             lcp->left = atoi (tmp) - 1;
9999           }
10000           tmp = MemFree (tmp);
10001           tmp = SaveStringFromText (lcdp->second_val);
10002           if (StringHasNoText (tmp))
10003           {
10004             lcp->right = 0;
10005           }
10006           else
10007           {
10008             lcp->right = atoi (tmp) - 1;
10009           }
10010           tmp = MemFree (tmp);
10011           break;
10012       }
10013     }
10014     else
10015     {
10016       lcp->match_choice = LOCATION_CONSTRAINT_ANY;
10017       lcp->left = 0;
10018       lcp->right = 0;
10019     }
10020     lcp->strand = GetValue (lcdp->strand);
10021     lcp->sequence_type = GetValue (lcdp->sequence_type);
10022   }
10023   return lcp;
10024 }
10025 
LocationConstraintXMessage(DialoG d,Int2 mssg)10026 static void LocationConstraintXMessage (DialoG d, Int2 mssg)
10027 
10028 {
10029   LocationConstraintXDialogPtr lcdp;
10030 
10031   lcdp = (LocationConstraintXDialogPtr) GetObjectExtra (d);
10032   if (lcdp != NULL) {
10033     switch (mssg) {
10034       case VIB_MSG_INIT :
10035         ResetLocationConstraintXDialog (lcdp);
10036         break;
10037       case VIB_MSG_ENTER :
10038         if (lcdp->show_interval_controls)
10039         {
10040           Select (lcdp->interval_end_choice);
10041         }
10042         else
10043         {
10044           Select (lcdp->strand);
10045         }
10046         break;
10047       default :
10048         break;
10049     }
10050   }
10051 }
10052 
TestLocationConstraintXDialog(DialoG d)10053 static ValNodePtr TestLocationConstraintXDialog (DialoG d)
10054 
10055 {
10056   return NULL;
10057 }
10058 
10059 
10060 extern DialoG
LocationConstraintXDialog(GrouP h,Boolean show_interval_controls,Boolean clear_btn)10061 LocationConstraintXDialog
10062 (GrouP   h,
10063  Boolean show_interval_controls,
10064  Boolean clear_btn)
10065 
10066 {
10067   LocationConstraintXDialogPtr lcdp;
10068   GrouP                       p, g, k, val_grp, strand_grp, g2, g3, g4;
10069   ButtoN                      b = NULL;
10070 
10071   lcdp = (LocationConstraintXDialogPtr) MemNew (sizeof (LocationConstraintXDialogData));
10072   if (lcdp == NULL)
10073   {
10074     return NULL;
10075   }
10076 
10077   p = HiddenGroup (h, -1, 0, NULL);
10078   SetObjectExtra (p, lcdp, StdCleanupExtraProc);
10079 
10080   lcdp->dialog = (DialoG) p;
10081   lcdp->todialog = LocationConstraintXToDialog;
10082   lcdp->fromdialog = DialogToLocationConstraintX;
10083   lcdp->dialogmessage = LocationConstraintXMessage;
10084   lcdp->testdialog = TestLocationConstraintXDialog;
10085 
10086   lcdp->show_interval_controls = show_interval_controls;
10087 
10088   if (lcdp->show_interval_controls)
10089   {
10090     g = HiddenGroup (p, 6, 0, NULL);
10091     SetGroupSpacing (g, 10, 10);
10092     lcdp->interval_end_choice = PopupList (g, TRUE, ShowLocationChoiceControls);
10093     PopupItem (lcdp->interval_end_choice, "Entire location");
10094     PopupItem (lcdp->interval_end_choice, "Start");
10095     PopupItem (lcdp->interval_end_choice, "Stop");
10096     SetValue (lcdp->interval_end_choice, 1);
10097     SetObjectExtra (lcdp->interval_end_choice, lcdp, NULL);
10098 
10099     StaticPrompt (g, "is", 0, dialogTextHeight, systemFont, 'l');
10100 
10101     k = HiddenGroup (g, 0, 0, NULL);
10102     lcdp->interval_match_choice = PopupList (k, TRUE, ShowLocationChoiceControls);
10103     PopupItem (lcdp->interval_match_choice, "Any location");
10104     PopupItem (lcdp->interval_match_choice, "Upstream from");
10105     PopupItem (lcdp->interval_match_choice, "Downstream from");
10106     PopupItem (lcdp->interval_match_choice, "Contained in");
10107     PopupItem (lcdp->interval_match_choice, "Not in");
10108     PopupItem (lcdp->interval_match_choice, "Overlaps");
10109     PopupItem (lcdp->interval_match_choice, "Equal to");
10110     SetValue (lcdp->interval_match_choice, 1);
10111     SetObjectExtra (lcdp->interval_match_choice, lcdp, NULL);
10112 
10113     lcdp->endpoint_match_choice = PopupList (k, TRUE, ShowLocationChoiceControls);
10114     PopupItem (lcdp->endpoint_match_choice, "Any location");
10115     PopupItem (lcdp->endpoint_match_choice, "Upstream from");
10116     PopupItem (lcdp->endpoint_match_choice, "Downstream from");
10117     PopupItem (lcdp->endpoint_match_choice, "Contained in");
10118     PopupItem (lcdp->endpoint_match_choice, "Not in");
10119     SetValue (lcdp->endpoint_match_choice, 1);
10120     SetObjectExtra (lcdp->endpoint_match_choice, lcdp, NULL);
10121 
10122     g2 = HiddenGroup (g, 2, 0, NULL);
10123     SetGroupSpacing (g2, 10, 10);
10124     val_grp = HiddenGroup (g2, 0, 0, NULL);
10125     lcdp->only_val = DialogText (val_grp, "", 5, NULL);
10126     g3 = HiddenGroup (val_grp, 3, 0, NULL);
10127     lcdp->first_val = DialogText (g3, "", 5, NULL);
10128     lcdp->second_val_prompt = StaticPrompt (g3, "to", 0, dialogTextHeight, systemFont, 'l');
10129     lcdp->second_val = DialogText (g3, "", 5, NULL);
10130     AlignObjects (ALIGN_CENTER, (HANDLE) lcdp->only_val, (HANDLE) g3, NULL);
10131   }
10132   else
10133   {
10134     g = HiddenGroup (p, 2, 0, NULL);
10135   }
10136 
10137   strand_grp = HiddenGroup (g, 2, 0, NULL);
10138   StaticPrompt (strand_grp, "on", 0, dialogTextHeight, systemFont, 'l');
10139   lcdp->strand = PopupList (strand_grp, TRUE, NULL);
10140   PopupItem (lcdp->strand, "Any strand");
10141   PopupItem (lcdp->strand, "Plus strand");
10142   PopupItem (lcdp->strand, "Minus strand");
10143   SetValue (lcdp->strand, LOCATION_CONSTRAINT_ANY_STRAND);
10144 
10145   g4 = HiddenGroup (g, 3, 0, NULL);
10146   SetGroupSpacing (g4, 10, 10);
10147   StaticPrompt (g4, "on", 0, dialogTextHeight, systemFont, 'l');
10148   lcdp->sequence_type = PopupList (g4, TRUE, NULL);
10149   PopupItem (lcdp->sequence_type, "nucleotide and protein sequences");
10150   PopupItem (lcdp->sequence_type, "nucleotide sequences only");
10151   PopupItem (lcdp->sequence_type, "protein sequences only");
10152   SetValue (lcdp->sequence_type, LOCATION_CONSTRAINT_ANY_SEQ);
10153 
10154   if (clear_btn)
10155   {
10156     b = PushButton (p, "Clear Constraint", ClearDialogBtn);
10157     SetObjectExtra (b, p, NULL);
10158   }
10159 
10160   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) b, NULL);
10161 
10162   ShowLocationChoiceControls (lcdp->interval_match_choice);
10163   return (DialoG) p;
10164 }
10165 
DoesStrandMatchConstraint(SeqLocPtr slp,LocationConstraintXPtr lcp)10166 static Boolean DoesStrandMatchConstraint (SeqLocPtr slp, LocationConstraintXPtr lcp)
10167 {
10168   Uint2 strand;
10169   Boolean rval = FALSE;
10170 
10171   if (slp == NULL)
10172   {
10173     rval = FALSE;
10174   }
10175   else if (lcp == NULL || lcp->strand == LOCATION_CONSTRAINT_ANY_STRAND)
10176   {
10177     rval = TRUE;
10178   }
10179   else
10180   {
10181     strand = SeqLocStrand (slp);
10182     if (strand == Seq_strand_minus)
10183     {
10184       if (lcp->strand == LOCATION_CONSTRAINT_MINUS_STRAND)
10185       {
10186         rval = TRUE;
10187       }
10188       else
10189       {
10190         rval = FALSE;
10191       }
10192     }
10193     else
10194     {
10195       if (lcp->strand == LOCATION_CONSTRAINT_PLUS_STRAND)
10196       {
10197         rval = TRUE;
10198       }
10199       else
10200       {
10201         rval = FALSE;
10202       }
10203     }
10204   }
10205   return rval;
10206 }
10207 
DoesSequenceTypeMatchContraint(SeqLocPtr slp,LocationConstraintXPtr lcp)10208 static Boolean DoesSequenceTypeMatchContraint (SeqLocPtr slp, LocationConstraintXPtr lcp)
10209 {
10210   Boolean   rval = FALSE;
10211   BioseqPtr bsp;
10212 
10213   if (slp == NULL)
10214   {
10215     rval = FALSE;
10216   }
10217   else if (lcp == NULL || lcp->sequence_type == LOCATION_CONSTRAINT_ANY_SEQ)
10218   {
10219     rval = TRUE;
10220   }
10221   else
10222   {
10223     bsp = BioseqFindFromSeqLoc (slp);
10224     if (bsp != NULL)
10225     {
10226       if (ISA_na (bsp->mol) && lcp->sequence_type == LOCATION_CONSTRAINT_NUC_SEQ)
10227       {
10228         rval = TRUE;
10229       }
10230       else if (ISA_aa (bsp->mol) && lcp->sequence_type == LOCATION_CONSTRAINT_PROT_SEQ)
10231       {
10232         rval = TRUE;
10233       }
10234     }
10235   }
10236   return rval;
10237 }
10238 
DoesLocationMatchConstraint(SeqLocPtr slp,LocationConstraintXPtr lcp)10239 extern Boolean DoesLocationMatchConstraint (SeqLocPtr slp, LocationConstraintXPtr lcp)
10240 
10241 {
10242   Boolean rval = FALSE;
10243   Int4    loc_start, loc_stop, endpoint = 0;
10244 
10245   if (slp == NULL)
10246   {
10247     return FALSE;
10248   }
10249 
10250   if (lcp == NULL)
10251   {
10252     rval = TRUE;
10253   }
10254   else if (! DoesStrandMatchConstraint (slp, lcp))
10255   {
10256     rval = FALSE;
10257   }
10258   else if (! DoesSequenceTypeMatchContraint (slp, lcp))
10259   {
10260     rval = FALSE;
10261   }
10262   else
10263   {
10264     switch (lcp->match_choice)
10265     {
10266       case LOCATION_CONSTRAINT_ANY :
10267         rval = TRUE;
10268         break;
10269       case LOCATION_CONSTRAINT_UPSTREAM :
10270         if (lcp->interval_end_choice == LOCATION_CONSTRAINT_WHOLE_INTERVAL
10271             || lcp->interval_end_choice == LOCATION_CONSTRAINT_STOP_ENDPOINT)
10272         {
10273           endpoint = SeqLocStop (slp);
10274         }
10275         else
10276         {
10277           endpoint = SeqLocStart (slp);
10278         }
10279         if (endpoint < lcp->left)
10280         {
10281           rval = TRUE;
10282         }
10283         break;
10284       case LOCATION_CONSTRAINT_DOWNSTREAM :
10285         if (lcp->interval_end_choice == LOCATION_CONSTRAINT_WHOLE_INTERVAL
10286             || lcp->interval_end_choice == LOCATION_CONSTRAINT_START_ENDPOINT)
10287         {
10288           endpoint = SeqLocStart (slp);
10289         }
10290         else
10291         {
10292           endpoint = SeqLocStop (slp);
10293         }
10294         if (endpoint > lcp->left)
10295         {
10296           rval = TRUE;
10297         }
10298         break;
10299       case LOCATION_CONSTRAINT_CONTAINED :
10300         if (lcp->interval_end_choice == LOCATION_CONSTRAINT_WHOLE_INTERVAL)
10301         {
10302           loc_start = SeqLocStart (slp);
10303           loc_stop = SeqLocStop (slp);
10304         }
10305         else
10306         {
10307           if (lcp->interval_end_choice == LOCATION_CONSTRAINT_START_ENDPOINT)
10308           {
10309             endpoint = SeqLocStart (slp);
10310           }
10311           else
10312           {
10313             endpoint = SeqLocStop (slp);
10314           }
10315           loc_start = endpoint;
10316           loc_stop = endpoint;
10317         }
10318         if (loc_start >= lcp->left && loc_stop <= lcp->right)
10319         {
10320           rval = TRUE;
10321         }
10322         break;
10323       case LOCATION_CONSTRAINT_NOT_IN :
10324         if (lcp->interval_end_choice == LOCATION_CONSTRAINT_WHOLE_INTERVAL)
10325         {
10326           loc_start = SeqLocStart (slp);
10327           loc_stop = SeqLocStop (slp);
10328         }
10329         else
10330         {
10331           if (lcp->interval_end_choice == LOCATION_CONSTRAINT_START_ENDPOINT)
10332           {
10333             endpoint = SeqLocStart (slp);
10334           }
10335           else
10336           {
10337             endpoint = SeqLocStop (slp);
10338           }
10339           loc_start = endpoint;
10340           loc_stop = endpoint;
10341         }
10342         if (loc_stop <= lcp->left || loc_start >= lcp->right)
10343         {
10344           rval = TRUE;
10345         }
10346         break;
10347       case LOCATION_CONSTRAINT_OVERLAP :
10348         loc_start = SeqLocStart (slp);
10349         loc_stop = SeqLocStop (slp);
10350         if (loc_start <= lcp->left && loc_stop >= lcp->left)
10351         {
10352           rval = TRUE;
10353         }
10354         else if (loc_start <= lcp->right && loc_stop >= lcp->right)
10355         {
10356           rval = TRUE;
10357         }
10358         else if (loc_start >= lcp->left && loc_stop <= lcp->right)
10359         {
10360           rval = TRUE;
10361         }
10362         break;
10363       case LOCATION_CONSTRAINT_EQUAL :
10364         loc_start = SeqLocStart (slp);
10365         loc_stop = SeqLocStop (slp);
10366         if (loc_start == lcp->left && loc_stop == lcp->right)
10367         {
10368           rval = TRUE;
10369         }
10370         break;
10371     }
10372   }
10373   return rval;
10374 }
10375 
10376 typedef struct filterform
10377 {
10378   DIALOG_MESSAGE_BLOCK
10379 
10380   DialoG string_constraint;
10381   DialoG source_constraint;
10382   DialoG location_constraint;
10383   DialoG cds_gene_prot_constraint;
10384   DialoG id_list_constraint;
10385 
10386   DialoG tbs;
10387   DialoG pages[6];
10388   Int4   current_page;
10389 
10390 } FilterFormData, PNTR FilterFormPtr;
10391 
FilterToDialog(DialoG d,Pointer userdata)10392 static void FilterToDialog (DialoG d, Pointer userdata)
10393 {
10394   FilterFormPtr dlg;
10395   FilterSetPtr dlg_data;
10396 
10397   dlg = (FilterFormPtr) GetObjectExtra (d);
10398 
10399   if (dlg == NULL)
10400   {
10401     return;
10402   }
10403   dlg_data = (FilterSetPtr) userdata;
10404   PointerToDialog (dlg->string_constraint, NULL);
10405   PointerToDialog (dlg->source_constraint, NULL);
10406   PointerToDialog (dlg->location_constraint, NULL);
10407   PointerToDialog (dlg->cds_gene_prot_constraint, NULL);
10408   PointerToDialog (dlg->id_list_constraint, NULL);
10409 
10410   if (dlg_data != NULL)
10411   {
10412     PointerToDialog (dlg->string_constraint, dlg_data->scp);
10413     PointerToDialog (dlg->source_constraint, dlg_data->ccp);
10414     PointerToDialog (dlg->location_constraint, dlg_data->lcp);
10415     PointerToDialog (dlg->cds_gene_prot_constraint, dlg_data->cgp);
10416     PointerToDialog (dlg->id_list_constraint, dlg_data->id_list);
10417   }
10418 }
10419 
ApplyNthPage(FilterFormPtr dlg,FilterSetPtr dlg_data,Int4 page)10420 static void ApplyNthPage (FilterFormPtr dlg, FilterSetPtr dlg_data, Int4 page)
10421 {
10422   if (page < 0) return;
10423 
10424   /* adjust page value to reflect missing pages */
10425   if (dlg->source_constraint == NULL)
10426   {
10427     page++;
10428   }
10429   if (dlg->string_constraint == NULL && page >= 1)
10430   {
10431     page++;
10432   }
10433   if (dlg->location_constraint == NULL && page >= 2)
10434   {
10435     page++;
10436   }
10437   if (dlg->cds_gene_prot_constraint == NULL && page >= 3)
10438   {
10439     page++;
10440   }
10441   if (dlg->id_list_constraint == NULL && page >= 4)
10442   {
10443     page++;
10444   }
10445 
10446   switch (page)
10447   {
10448     case 0:
10449       dlg_data->ccp = DialogToPointer (dlg->source_constraint);
10450       break;
10451     case 1:
10452       dlg_data->scp = DialogToPointer (dlg->string_constraint);
10453       break;
10454     case 2:
10455       dlg_data->lcp = DialogToPointer (dlg->location_constraint);
10456       break;
10457     case 3:
10458       dlg_data->cgp = DialogToPointer (dlg->cds_gene_prot_constraint);
10459       break;
10460     case 4:
10461       dlg_data->id_list = DialogToPointer (dlg->id_list_constraint);
10462       break;
10463   }
10464 
10465 }
10466 
10467 
DialogToFilter(DialoG d)10468 static Pointer DialogToFilter (DialoG d)
10469 {
10470   FilterFormPtr dlg;
10471   FilterSetPtr dlg_data;
10472 
10473   dlg = (FilterFormPtr) GetObjectExtra (d);
10474 
10475   if (dlg == NULL)
10476   {
10477     return NULL;
10478   }
10479   dlg_data = (FilterSetPtr) MemNew (sizeof (FilterSetData));
10480 
10481   if (dlg_data != NULL)
10482   {
10483     if (dlg->tbs == NULL)
10484     {
10485       dlg_data->scp = DialogToPointer (dlg->string_constraint);
10486       dlg_data->ccp = DialogToPointer (dlg->source_constraint);
10487       dlg_data->lcp = DialogToPointer (dlg->location_constraint);
10488       dlg_data->cgp = DialogToPointer (dlg->cds_gene_prot_constraint);
10489       dlg_data->id_list = DialogToPointer (dlg->id_list_constraint);
10490     }
10491     else
10492     {
10493       /* only take one value */
10494       ApplyNthPage (dlg, dlg_data, dlg->current_page);
10495     }
10496   }
10497   return dlg_data;
10498 }
10499 
FilterFormMessage(DialoG d,Int2 mssg)10500 static void FilterFormMessage (DialoG d, Int2 mssg)
10501 
10502 {
10503 }
10504 
TestFilterFormDialog(DialoG d)10505 static ValNodePtr TestFilterFormDialog (DialoG d)
10506 
10507 {
10508   return NULL;
10509 }
10510 
ChangeFilterPage(VoidPtr data,Int2 newval,Int2 oldval)10511 static void ChangeFilterPage (VoidPtr data, Int2 newval, Int2 oldval)
10512 
10513 {
10514   FilterFormPtr ffp;
10515 
10516   ffp = (FilterFormPtr) data;
10517   if (ffp != NULL) {
10518     ffp->current_page = newval;
10519     SafeHide (ffp->pages [oldval]);
10520     Update ();
10521     SafeShow (ffp->pages [newval]);
10522     Update ();
10523   }
10524 }
10525 
ClearAllConstraints(ButtoN b)10526 static void ClearAllConstraints (ButtoN b)
10527 {
10528   FilterFormPtr ffp;
10529 
10530   ffp = (FilterFormPtr) GetObjectExtra (b);
10531   if (ffp != NULL)
10532   {
10533     PointerToDialog (ffp->dialog, NULL);
10534   }
10535 }
10536 
10537 extern DialoG
FilterGroup(GrouP h,Boolean has_string_constraint,Boolean has_source_constraint,Boolean has_location_constraint,Boolean has_cds_gene_prot_constraint,Boolean has_id_list_constraint,CharPtr string_constraint_label)10538 FilterGroup
10539 (GrouP h,
10540  Boolean has_string_constraint,
10541  Boolean has_source_constraint,
10542  Boolean has_location_constraint,
10543  Boolean has_cds_gene_prot_constraint,
10544  Boolean has_id_list_constraint,
10545  CharPtr string_constraint_label)
10546 {
10547   GrouP         g, k;
10548   FilterFormPtr ffp;
10549   Int4          num_pages = 0;
10550   CharPtr       filterTabs[5];
10551   Int4          i;
10552   ButtoN        clear_constraints = NULL;
10553 
10554   if (! has_string_constraint
10555       && ! has_source_constraint
10556       && ! has_location_constraint
10557       && ! has_cds_gene_prot_constraint
10558       && ! has_id_list_constraint)
10559   {
10560     return NULL;
10561   }
10562 
10563   ffp = (FilterFormPtr) MemNew (sizeof (FilterFormData));
10564   if (ffp == NULL)
10565   {
10566     return NULL;
10567   }
10568 
10569   g = NormalGroup (h, -1, 0, NULL, programFont, NULL);
10570   SetObjectExtra (g, ffp, StdCleanupExtraProc);
10571 
10572   ffp->dialog = (DialoG) g;
10573   ffp->todialog = FilterToDialog;
10574   ffp->fromdialog = DialogToFilter;
10575   ffp->dialogmessage = FilterFormMessage;
10576   ffp->testdialog = TestFilterFormDialog;
10577 
10578   ffp->current_page = 0;
10579 
10580   if (has_source_constraint)
10581   {
10582     filterTabs [num_pages++] = "Source Constraint";
10583   }
10584   if (has_string_constraint)
10585   {
10586     filterTabs [num_pages++] = "String Constraint";
10587   }
10588   if (has_location_constraint)
10589   {
10590     filterTabs [num_pages++] = "Location Constraint";
10591   }
10592   if (has_cds_gene_prot_constraint)
10593   {
10594     filterTabs [num_pages++] = "CDS-Gene-Prot-mRNA Set Constraint";
10595   }
10596   if (has_id_list_constraint)
10597   {
10598     filterTabs [num_pages++] = "Sequence ID Constraint";
10599   }
10600   filterTabs [num_pages] = NULL;
10601 
10602   if (num_pages > 1)
10603   {
10604 
10605     ffp->tbs = CreateFolderTabs (g, filterTabs, 0,
10606                                  0, 0, PROGRAM_FOLDER_TAB,
10607                                  ChangeFilterPage, (Pointer) ffp);
10608     k = HiddenGroup (g, 0, 0, NULL);
10609     num_pages = 0;
10610     if (has_source_constraint)
10611     {
10612       ffp->source_constraint = SourceConstraintDialogX (k, FALSE);
10613       ffp->pages [num_pages++] = ffp->source_constraint;
10614     }
10615     if (has_string_constraint)
10616     {
10617       ffp->string_constraint = StringConstraintDialogX (k, string_constraint_label, FALSE);
10618       ffp->pages [num_pages++] = ffp->string_constraint;
10619     }
10620     if (has_location_constraint)
10621     {
10622       ffp->location_constraint = LocationConstraintXDialog (k, FALSE, FALSE);
10623       ffp->pages [num_pages++] = ffp->location_constraint;
10624     }
10625     if (has_cds_gene_prot_constraint)
10626     {
10627       ffp->cds_gene_prot_constraint = CDSGeneProtConstraintDialog (k, FALSE);
10628       ffp->pages [num_pages++] = ffp->cds_gene_prot_constraint;
10629     }
10630     if (has_id_list_constraint)
10631     {
10632       ffp->id_list_constraint = StringConstraintDialogX (k, "Where sequence ID", FALSE);
10633       ffp->pages[num_pages++] = ffp->id_list_constraint;
10634     }
10635     for (i = 1; i < num_pages; i++)
10636     {
10637       Hide (ffp->pages [i]);
10638     }
10639     AlignObjects (ALIGN_CENTER, (HANDLE) ffp->pages [0],
10640                                 (HANDLE) ffp->pages [1],
10641                                 (HANDLE) ffp->pages [2],
10642                                 (HANDLE) ffp->pages [3],
10643                                 NULL);
10644     clear_constraints = PushButton (g, "Clear Constraints", ClearAllConstraints);
10645     SetObjectExtra (clear_constraints, ffp, NULL);
10646     AlignObjects (ALIGN_CENTER, (HANDLE) ffp->tbs, (HANDLE) k, (HANDLE) clear_constraints, NULL);
10647   }
10648   else
10649   {
10650     if (has_source_constraint)
10651     {
10652       ffp->source_constraint = SourceConstraintDialogX (g, TRUE);
10653     }
10654     else if (has_string_constraint)
10655     {
10656       ffp->string_constraint = StringConstraintDialogX (g, string_constraint_label, TRUE);
10657     }
10658     else if (has_location_constraint)
10659     {
10660       ffp->location_constraint = LocationConstraintXDialog (g, FALSE, TRUE);
10661     }
10662     else if (has_cds_gene_prot_constraint)
10663     {
10664       ffp->cds_gene_prot_constraint = CDSGeneProtConstraintDialog (g, TRUE);
10665     }
10666     else if (has_id_list_constraint)
10667     {
10668       ffp->id_list_constraint = StringConstraintDialogX (g, "Where sequence ID", TRUE);
10669     }
10670   }
10671   return (DialoG) g;
10672 }
10673 
10674 /* Operations on constrained features and descriptors */
10675 typedef struct objecthasstring
10676 {
10677   StringConstraintXPtr scp;
10678   Boolean             found;
10679 } ObjectHasStringData, PNTR ObjectHasStringPtr;
10680 
10681 typedef struct constraintop
10682 {
10683   FilterSetPtr           fsp;
10684   ObjMgrPtr              omp;
10685   ObjMgrTypePtr          omtp;
10686   AsnIoPtr               aip;
10687   Uint2                  entityID;
10688   ObjectHasStringData    ohsd;
10689   Pointer                userdata;
10690   FeatureActionProc      feature_action;
10691   Uint1                  seqFeatChoice;
10692   Uint1                  featDefChoice;
10693   DescriptorActionProc   descriptor_action;
10694   Uint1                  descriptorChoice;
10695 } ConstraintOpData, PNTR ConstraintOpPtr;
10696 
DoesStringMatchConstraintX(CharPtr pchSource,StringConstraintXPtr scp)10697 extern Boolean DoesStringMatchConstraintX (CharPtr pchSource, StringConstraintXPtr scp)
10698 {
10699   CharPtr pFound;
10700   Boolean rval = FALSE;
10701   Char    char_after = 0;
10702 
10703   if (pchSource == NULL) return FALSE;
10704 
10705   if (scp == NULL || StringHasNoText (scp->match_text)) return TRUE;
10706 
10707   switch (scp->match_location)
10708   {
10709     case eStringConstraintContains:
10710         if (scp->insensitive)
10711         {
10712           pFound = StringISearch (pchSource, scp->match_text);
10713         }
10714         else
10715         {
10716           pFound = StringSearch (pchSource, scp->match_text);
10717         }
10718       if (pFound == NULL)
10719       {
10720         rval = FALSE;
10721       }
10722       else if (scp->whole_word)
10723       {
10724         rval = IsWholeWordMatch (pchSource, pFound, StringLen (scp->match_text));
10725         while (!rval && pFound != NULL)
10726         {
10727             if (scp->insensitive)
10728             {
10729               pFound = StringISearch (pFound + 1, scp->match_text);
10730             }
10731             else
10732             {
10733               pFound = StringSearch (pFound + 1, scp->match_text);
10734             }
10735           if (pFound != NULL)
10736           {
10737             rval = IsWholeWordMatch (pchSource, pFound, StringLen (scp->match_text));
10738           }
10739         }
10740       }
10741       else
10742       {
10743         rval = TRUE;
10744       }
10745       break;
10746     case eStringConstraintStarts:
10747         if (scp->insensitive)
10748         {
10749           pFound = StringISearch (pchSource, scp->match_text);
10750         }
10751         else
10752         {
10753           pFound = StringSearch (pchSource, scp->match_text);
10754         }
10755       if (pFound == pchSource)
10756       {
10757         if (scp->whole_word)
10758         {
10759           rval = IsWholeWordMatch (pchSource, pFound, StringLen (scp->match_text));
10760         }
10761         else
10762         {
10763           rval = TRUE;
10764         }
10765       }
10766       break;
10767     case eStringConstraintEnds:
10768         if (scp->insensitive)
10769         {
10770           pFound = StringISearch (pchSource, scp->match_text);
10771         }
10772         else
10773         {
10774           pFound = StringSearch (pchSource, scp->match_text);
10775         }
10776       while (pFound != NULL && !rval) {
10777           char_after = *(pFound + StringLen (scp->match_text));
10778         if (char_after == 0)
10779         {
10780           if (scp->whole_word)
10781           {
10782             rval = IsWholeWordMatch (pchSource, pFound, StringLen (scp->match_text));
10783           }
10784           else
10785           {
10786             rval = TRUE;
10787           }
10788           /* stop the search, we're at the end of the string */
10789           pFound = NULL;
10790         }
10791         else
10792         {
10793             if (scp->insensitive)
10794             {
10795               pFound = StringISearch (pFound + 1, scp->match_text);
10796             }
10797             else
10798             {
10799               pFound = StringSearch (pFound + 1, scp->match_text);
10800             }
10801         }
10802       }
10803       break;
10804     case eStringConstraintEquals:
10805       if (scp->insensitive)
10806       {
10807         if (StringICmp (pchSource, scp->match_text) == 0)
10808         {
10809           rval = TRUE;
10810         }
10811       }
10812       else
10813       {
10814         if (StringCmp (pchSource, scp->match_text) == 0)
10815         {
10816           rval = TRUE;
10817         }
10818       }
10819       break;
10820     case eStringConstraintInList:
10821         if (scp->insensitive)
10822         {
10823           pFound = StringISearch (scp->match_text, pchSource);
10824         }
10825         else
10826         {
10827           pFound = StringSearch (scp->match_text, pchSource);
10828         }
10829       if (pFound == NULL)
10830       {
10831         rval = FALSE;
10832       }
10833       else
10834       {
10835         rval = IsWholeWordMatch (scp->match_text, pFound, StringLen (pchSource));
10836         while (!rval && pFound != NULL)
10837         {
10838             if (scp->insensitive)
10839             {
10840               pFound = StringISearch (pFound + 1, pchSource);
10841             }
10842             else
10843             {
10844               pFound = StringSearch (pFound + 1, pchSource);
10845             }
10846           if (pFound != NULL)
10847           {
10848             rval = IsWholeWordMatch (scp->match_text, pFound, StringLen (pchSource));
10849           }
10850         }
10851       }
10852       if (!rval) {
10853         /* look for spans */
10854         rval = IsStringInSpanInList (pchSource, scp->match_text);
10855       }
10856       break;
10857     }
10858     return rval;
10859 }
10860 
AsnWriteConstraintCallBack(AsnExpOptStructPtr pAEOS)10861 static void LIBCALLBACK AsnWriteConstraintCallBack (AsnExpOptStructPtr pAEOS)
10862 
10863 {
10864   CharPtr            pchSource;
10865   ObjectHasStringPtr ohsp;
10866 
10867   ohsp = (ObjectHasStringPtr) pAEOS->data;
10868   if (ISA_STRINGTYPE (AsnFindBaseIsa (pAEOS->atp)))
10869   {
10870       pchSource = (CharPtr) pAEOS->dvp->ptrvalue;
10871       ohsp->found |= DoesStringMatchConstraintX (pchSource, ohsp->scp);
10872   }
10873 }
10874 
10875 static Boolean
DoesObjectMatchStringConstraint(ObjMgrTypePtr omtp,AsnIoPtr aip,Pointer ptr,ObjectHasStringPtr ohsp)10876 DoesObjectMatchStringConstraint
10877 (ObjMgrTypePtr      omtp,
10878  AsnIoPtr           aip,
10879  Pointer            ptr,
10880  ObjectHasStringPtr ohsp)
10881 
10882 {
10883   SeqFeatPtr        sfp;
10884   SeqMgrFeatContext fcontext;
10885   CharPtr           search_txt = NULL;
10886 
10887   if (omtp == NULL || ohsp == NULL)
10888   {
10889     return FALSE;
10890   }
10891   ohsp->found = FALSE;
10892   (omtp->asnwrite) (ptr, aip, NULL);
10893 
10894   if (!ohsp->found && omtp->datatype == OBJ_SEQFEAT)
10895   {
10896     sfp = (SeqFeatPtr) ptr;
10897     if (SeqMgrFeaturesAreIndexed(sfp->idx.entityID) == 0) {
10898       SeqMgrIndexFeatures (sfp->idx.entityID, NULL);
10899     }
10900 
10901     sfp = SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, sfp->idx.itemID, 0, sfp, &fcontext);
10902     ohsp->found = DoesStringMatchConstraintX (fcontext.label, ohsp->scp);
10903     if (!ohsp->found && sfp != NULL && sfp->idx.subtype == FEATDEF_tRNA)
10904     {
10905       search_txt = (CharPtr) MemNew ((StringLen (fcontext.label) + 6) * sizeof (Char));
10906       if (search_txt != NULL)
10907       {
10908         sprintf (search_txt, "tRNA-%s", fcontext.label);
10909         ohsp->found = DoesStringMatchConstraintX (search_txt, ohsp->scp);
10910         search_txt = MemFree (search_txt);
10911       }
10912     }
10913   }
10914   return ohsp->found;
10915 }
10916 
10917 
DoesSourceHaveOneQualPresent(BioSourcePtr biop,SourceQualDescPtr sqdp)10918 static Boolean DoesSourceHaveOneQualPresent (BioSourcePtr biop, SourceQualDescPtr sqdp)
10919 {
10920   OrgModPtr    mod;
10921   SubSourcePtr ssp;
10922   Boolean      is_present = FALSE;
10923 
10924   if (biop == NULL || sqdp == NULL)
10925   {
10926     return FALSE;
10927   }
10928 
10929   if (sqdp->isOrgMod)
10930   {
10931     if (biop->org != NULL && biop->org->orgname != NULL)
10932     {
10933       mod = biop->org->orgname->mod;
10934       while (mod != NULL && mod->subtype != sqdp->subtype)
10935       {
10936         mod = mod->next;
10937       }
10938       if (mod != NULL && mod->subtype == sqdp->subtype)
10939       {
10940         is_present = TRUE;
10941       }
10942     }
10943   }
10944   else
10945   {
10946     ssp = biop->subtype;
10947     while (ssp != NULL && ssp->subtype != sqdp->subtype)
10948     {
10949       ssp = ssp->next;
10950     }
10951     if (ssp != NULL && ssp->subtype == sqdp->subtype)
10952     {
10953       is_present = TRUE;
10954     }
10955   }
10956   return is_present;
10957 }
10958 
DoesSourceHaveQualPresent(BioSourcePtr biop,ValNodePtr qual_list)10959 static Boolean DoesSourceHaveQualPresent (BioSourcePtr biop, ValNodePtr qual_list)
10960 {
10961   ValNodePtr        vnp;
10962   Boolean           qual_found = FALSE;
10963 
10964   if (biop == NULL)
10965   {
10966     return FALSE;
10967   }
10968   if (qual_list == NULL)
10969   {
10970     return TRUE;
10971   }
10972 
10973   for (vnp = qual_list; vnp != NULL && !qual_found; vnp = vnp->next)
10974   {
10975     qual_found = DoesSourceHaveOneQualPresent (biop, (SourceQualDescPtr) vnp->data.ptrvalue);
10976   }
10977 
10978   return qual_found;
10979 }
10980 
IsMatchAny(ValNodePtr vnp)10981 static Boolean IsMatchAny (ValNodePtr vnp)
10982 {
10983   if (vnp == NULL
10984       || vnp->data.ptrvalue == NULL
10985       || (vnp->choice > 0 && StringICmp (vnp->data.ptrvalue, "Organism or Any Qual") == 0))
10986   {
10987     return TRUE;
10988   } else {
10989     return FALSE;
10990   }
10991 }
10992 
DoFieldsMatch(BioSourcePtr biop,ChoiceConstraintPtr ccp)10993 static Boolean DoFieldsMatch (BioSourcePtr biop, ChoiceConstraintPtr ccp)
10994 {
10995   ValNodePtr swap, swap2;
10996   ValNodePtr qual_choice_list = NULL, vnp1, vnp2;
10997   Boolean    rval = FALSE;
10998   ChoiceConstraintData tmp_const;
10999   StringConstraintData scd;
11000   SourceQualDescPtr sqdp;
11001   CharPtr    location;
11002   OrgModPtr              mod = NULL;
11003   SubSourcePtr           ssp;
11004 
11005   if (biop == NULL) return FALSE;
11006   if (ccp == NULL) return TRUE;
11007 
11008   /* Init temporary choice constraint */
11009   MemSet (&tmp_const, 0, sizeof (ChoiceConstraintData));
11010   MemSet (&scd, 0, sizeof (StringConstraintData));
11011   scd.match_location = eStringConstraintEquals;
11012   tmp_const.string_constraint = &scd;
11013   tmp_const.constraint_type = CHOICE_CONSTRAINT_STRING;
11014 
11015   if (IsMatchAny (ccp->qual_choice) && IsMatchAny (ccp->qual_choice_match)) {
11016     /* both are wildcards */
11017     ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Organism"));
11018     qual_choice_list->next = GetSourceQualDescList (TRUE, TRUE, TRUE, FALSE);
11019     ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Lineage"));
11020     ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Location"));
11021 
11022     /* save original wildcards */
11023     swap = ccp->qual_choice;
11024     swap2 = ccp->qual_choice_match;
11025     for (vnp1 = qual_choice_list; vnp1 != NULL && vnp1->next != NULL && !rval; vnp1 = vnp1->next) {
11026       ccp->qual_choice = vnp1;
11027       for (vnp2 = vnp1->next; vnp2 != NULL && !rval; vnp2 = vnp2->next) {
11028         ccp->qual_choice_match = vnp2;
11029         if (DoFieldsMatch (biop, ccp)) {
11030           rval = TRUE;
11031         }
11032       }
11033     }
11034     /* put original wildcards back */
11035     ccp->qual_choice = swap;
11036     ccp->qual_choice_match = swap2;
11037     qual_choice_list = ValNodeFreeData (qual_choice_list);
11038   } else if (IsMatchAny (ccp->qual_choice) || IsMatchAny (ccp->qual_choice_match)) {
11039     /* one is a wild card */
11040     ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Organism"));
11041     qual_choice_list->next = GetSourceQualDescList (TRUE, TRUE, TRUE, FALSE);
11042     ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Lineage"));
11043     ValNodeAddPointer (&qual_choice_list, 1, StringSave ("Location"));
11044 
11045     /* if one wild card, make it the first one */
11046     if (IsMatchAny (ccp->qual_choice_match)) {
11047       swap = ccp->qual_choice;
11048       ccp->qual_choice = ccp->qual_choice_match;
11049       ccp->qual_choice_match = swap;
11050     }
11051     /* save original wildcard */
11052     swap = ccp->qual_choice;
11053     for (vnp1 = qual_choice_list; vnp1 != NULL && !rval; vnp1 = vnp1->next) {
11054       if (SourceQualValNodeMatch (vnp1, ccp->qual_choice_match)) {
11055         /* don't compare something to itself */
11056         continue;
11057       } else {
11058         ccp->qual_choice = vnp1;
11059         rval = DoFieldsMatch (biop, ccp);
11060       }
11061     }
11062     /* put original wildcard back */
11063     ccp->qual_choice = swap;
11064     qual_choice_list = ValNodeFreeData (qual_choice_list);
11065   }
11066   else if (ccp->qual_choice->choice > 0)
11067   {
11068     tmp_const.qual_choice = ccp->qual_choice_match;
11069     if (StringICmp (ccp->qual_choice->data.ptrvalue, "Organism") == 0)
11070     {
11071       if (biop->org != NULL && !StringHasNoText (biop->org->taxname))
11072       {
11073         tmp_const.string_constraint->match_text = biop->org->taxname;
11074         rval = DoesOneSourceMatchConstraint (biop, &tmp_const);
11075       }
11076     }
11077     else if (StringICmp (ccp->qual_choice->data.ptrvalue, "Lineage") == 0)
11078     {
11079       if (biop->org != NULL && biop->org->orgname != NULL && !StringHasNoText (biop->org->orgname->lineage))
11080       {
11081         tmp_const.string_constraint->match_text = biop->org->orgname->lineage;
11082         rval = DoesOneSourceMatchConstraint (biop, &tmp_const);
11083       }
11084     }
11085     else if (StringICmp (ccp->qual_choice->data.ptrvalue, "Location") == 0)
11086     {
11087       location = GetLocationFromSource (biop, NULL);
11088       tmp_const.string_constraint->match_text = location;
11089       if (!StringHasNoText (location)) {
11090         rval = DoesOneSourceMatchConstraint (biop, &tmp_const);
11091       }
11092       location = MemFree (location);
11093     }
11094   }
11095   else
11096   {
11097     tmp_const.qual_choice = ccp->qual_choice_match;
11098     sqdp = (SourceQualDescPtr) ccp->qual_choice->data.ptrvalue;
11099     if (sqdp->isOrgMod)
11100     {
11101       if (biop->org != NULL && biop->org->orgname != NULL)
11102       {
11103         mod = biop->org->orgname->mod;
11104       }
11105       while (! rval && mod != NULL)
11106       {
11107         if (mod->subtype == sqdp->subtype && !StringHasNoText (mod->subname))
11108         {
11109           tmp_const.string_constraint->match_text = mod->subname;
11110           rval = DoesOneSourceMatchConstraint (biop, &tmp_const);
11111         }
11112         mod = mod->next;
11113       }
11114     }
11115     else
11116     {
11117       ssp = biop->subtype;
11118       while (!rval && ssp != NULL)
11119       {
11120         if (ssp->subtype == sqdp->subtype && !StringHasNoText (ssp->name))
11121         {
11122           tmp_const.string_constraint->match_text = ssp->name;
11123           rval = DoesOneSourceMatchConstraint (biop, &tmp_const);
11124         }
11125         ssp = ssp->next;
11126       }
11127     }
11128   }
11129   return rval;
11130 }
11131 
11132 extern Boolean
DoesOneSourceMatchConstraint(BioSourcePtr biop,ChoiceConstraintPtr scp)11133 DoesOneSourceMatchConstraint
11134 (BioSourcePtr biop, ChoiceConstraintPtr scp)
11135 {
11136   Boolean                does_match = FALSE;
11137   OrgModPtr              mod = NULL;
11138   SubSourcePtr           ssp;
11139   SourceQualDescPtr      sqdp;
11140   CharPtr                location;
11141 
11142   if (scp == NULL || scp->constraint_type == CHOICE_CONSTRAINT_ANY)
11143   {
11144     return TRUE;
11145   }
11146   if (biop == NULL)
11147   {
11148     return FALSE;
11149   }
11150 
11151   if (scp->constraint_type == CHOICE_CONSTRAINT_STRING)
11152   {
11153     if (IsMatchAny (scp->qual_choice))
11154     {
11155       if (biop->org != NULL)
11156       {
11157         does_match = DoesStringMatchConstraintX (biop->org->taxname, scp->string_constraint);
11158         if (biop->org->orgname != NULL)
11159         {
11160           mod = biop->org->orgname->mod;
11161         }
11162         while (! does_match && mod != NULL)
11163         {
11164           does_match = DoesStringMatchConstraintX (mod->subname, scp->string_constraint);
11165           mod = mod->next;
11166         }
11167       }
11168       ssp = biop->subtype;
11169       while (!does_match && ssp != NULL)
11170       {
11171         does_match = DoesStringMatchConstraintX (ssp->name, scp->string_constraint);
11172         ssp = ssp->next;
11173       }
11174     }
11175     else if (scp->qual_choice->choice > 0 && StringICmp (scp->qual_choice->data.ptrvalue, "Organism") == 0)
11176     {
11177       if (biop->org != NULL)
11178       {
11179         does_match = DoesStringMatchConstraintX (biop->org->taxname, scp->string_constraint);
11180       }
11181     }
11182     else if (scp->qual_choice->choice > 0 && StringICmp (scp->qual_choice->data.ptrvalue, "Lineage") == 0)
11183     {
11184       if (biop->org != NULL && biop->org->orgname != NULL)
11185       {
11186         does_match = DoesStringMatchConstraintX (biop->org->orgname->lineage,
11187                                                 scp->string_constraint);
11188       }
11189     }
11190     else if (scp->qual_choice->choice > 0 && StringICmp (scp->qual_choice->data.ptrvalue, "Location") == 0)
11191     {
11192       location = GetLocationFromSource (biop, NULL);
11193       does_match = DoesStringMatchConstraintX (location, scp->string_constraint);
11194       location = MemFree (location);
11195     }
11196     else
11197     {
11198       sqdp = (SourceQualDescPtr) scp->qual_choice->data.ptrvalue;
11199       if (sqdp->isOrgMod)
11200       {
11201         if (biop->org != NULL && biop->org->orgname != NULL)
11202         {
11203           mod = biop->org->orgname->mod;
11204         }
11205         while (! does_match && mod != NULL)
11206         {
11207           if (mod->subtype == sqdp->subtype)
11208           {
11209             does_match = DoesStringMatchConstraintX (mod->subname, scp->string_constraint);
11210           }
11211           mod = mod->next;
11212         }
11213       }
11214       else
11215       {
11216         ssp = biop->subtype;
11217         while (!does_match && ssp != NULL)
11218         {
11219           if (ssp->subtype == sqdp->subtype)
11220           {
11221             does_match = DoesStringMatchConstraintX (ssp->name, scp->string_constraint);
11222           }
11223           ssp = ssp->next;
11224         }
11225       }
11226     }
11227     if (scp->string_constraint->not_present)
11228     {
11229       does_match = ! does_match;
11230     }
11231   }
11232   else if (scp->constraint_type == CHOICE_CONSTRAINT_MATCH)
11233   {
11234     does_match = DoFieldsMatch (biop, scp);
11235   }
11236   else
11237   {
11238     does_match = DoesSourceHaveQualPresent (biop, scp->qual_choice);
11239   }
11240   return does_match;
11241 }
11242 
SeqEntryConstrainedFeaturesCallback(SeqFeatPtr sfp,Pointer userdata)11243 static void SeqEntryConstrainedFeaturesCallback (SeqFeatPtr sfp, Pointer userdata)
11244 {
11245   SeqMgrFeatContext fcontext;
11246   ConstraintOpPtr   cop;
11247   Boolean           feature_matches = TRUE;
11248 
11249   if (sfp == NULL || userdata == NULL) return;
11250   cop = (ConstraintOpPtr) userdata;
11251   sfp = SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, sfp->idx.itemID, 0, sfp, &fcontext);
11252   if (sfp == NULL) return;
11253 
11254   if (cop->seqFeatChoice != 0 && cop->seqFeatChoice != sfp->data.choice) return;
11255   if (cop->featDefChoice != 0 && cop->featDefChoice != sfp->idx.subtype) return;
11256 
11257   if (cop->fsp != NULL && cop->fsp->scp != NULL)
11258   {
11259     if (cop->fsp->scp->not_present)
11260     {
11261       if (DoesObjectMatchStringConstraint (cop->omtp, cop->aip, (Pointer) sfp, &(cop->ohsd))
11262           || DoesStringMatchConstraintX (fcontext.label, cop->fsp->scp))
11263       {
11264         feature_matches = FALSE;
11265       }
11266     }
11267     else
11268     {
11269       if (! DoesObjectMatchStringConstraint (cop->omtp, cop->aip, (Pointer) sfp, &(cop->ohsd))
11270           && ! DoesStringMatchConstraintX (fcontext.label, cop->fsp->scp))
11271       {
11272         feature_matches = FALSE;
11273       }
11274     }
11275   }
11276   if (cop->fsp != NULL && cop->fsp->lcp != NULL)
11277   {
11278     if (! DoesLocationMatchConstraint (sfp->location, cop->fsp->lcp))
11279     {
11280       feature_matches = FALSE;
11281     }
11282   }
11283 
11284   if (feature_matches)
11285   {
11286     (cop->feature_action) (sfp, cop->userdata, cop->fsp);
11287   }
11288 }
11289 
11290 
BioseqConstrainedFeaturesCallback(BioseqPtr bsp,Pointer userdata)11291 static void BioseqConstrainedFeaturesCallback (BioseqPtr bsp, Pointer userdata)
11292 {
11293   ConstraintOpPtr   cop;
11294   SeqFeatPtr        sfp;
11295   ObjMgrDataPtr     omdp;
11296   BioseqExtraPtr    bspextra;
11297   Int4              index;
11298 
11299   if (bsp == NULL || userdata == NULL) return;
11300   cop = (ConstraintOpPtr) userdata;
11301 
11302   omdp = SeqMgrGetOmdpForBioseq (bsp);
11303   if (omdp == NULL || omdp->datatype != OBJ_BIOSEQ) return;
11304 
11305   bspextra = (BioseqExtraPtr) omdp->extradata;
11306   if (bspextra == NULL) {
11307     SeqMgrIndexFeatures (bsp->idx.entityID, NULL);
11308     omdp = SeqMgrGetOmdpForBioseq (bsp);
11309     if (omdp == NULL || omdp->datatype != OBJ_BIOSEQ) return;
11310 
11311     bspextra = (BioseqExtraPtr) omdp->extradata;
11312   }
11313   if (bspextra == NULL) return;
11314 
11315   for (index = 0; index < bspextra->numfeats; index++)
11316   {
11317     sfp = bspextra->featsByPos[index]->sfp;
11318     SeqEntryConstrainedFeaturesCallback (sfp, userdata);
11319   }
11320 }
11321 
11322 
SeqEntryConstrainedDescriptorsCallback(SeqDescrPtr sdp,Pointer userdata)11323 static void SeqEntryConstrainedDescriptorsCallback (SeqDescrPtr sdp, Pointer userdata)
11324 {
11325   ConstraintOpPtr cop;
11326   Boolean         descriptor_matches = TRUE;
11327 
11328   if (sdp == NULL || userdata == NULL) return;
11329   cop = (ConstraintOpPtr) userdata;
11330 
11331   if (cop != NULL && cop->descriptorChoice != 0 && cop->descriptorChoice != sdp->choice)
11332   {
11333     return;
11334   }
11335 
11336   if (cop != NULL && cop->fsp != NULL && cop->fsp->scp != NULL)
11337   {
11338     if (cop->fsp->scp->not_present)
11339     {
11340       if (DoesObjectMatchStringConstraint (cop->omtp, cop->aip, (Pointer) sdp, &(cop->ohsd)))
11341       {
11342         descriptor_matches = FALSE;
11343       }
11344     }
11345     else
11346     {
11347       if (! DoesObjectMatchStringConstraint (cop->omtp, cop->aip, (Pointer) sdp, &(cop->ohsd)))
11348       {
11349         descriptor_matches = FALSE;
11350       }
11351     }
11352   }
11353   if (descriptor_matches)
11354   {
11355     (cop->descriptor_action) (sdp, cop->userdata, cop->fsp);
11356   }
11357 }
11358 
11359 
ConstrainedSourceCallback(SeqEntryPtr sep,ConstraintOpPtr cop)11360 static void ConstrainedSourceCallback (SeqEntryPtr sep, ConstraintOpPtr cop)
11361 {
11362   BioseqPtr       bsp;
11363   BioseqSetPtr    bssp = NULL;
11364   SeqAnnotPtr     sap = NULL;
11365   SeqDescrPtr     sdp = NULL;
11366   SeqFeatPtr      sfp;
11367   Boolean         found = FALSE;
11368 
11369   if (sep == NULL || sep->data.ptrvalue == NULL || cop == NULL || cop->fsp == NULL)
11370   {
11371     return;
11372   }
11373 
11374   if (IS_Bioseq (sep))
11375   {
11376     bsp = (BioseqPtr) sep->data.ptrvalue;
11377     sap = bsp->annot;
11378     sdp = bsp->descr;
11379   }
11380   else if (IS_Bioseq_set (sep))
11381   {
11382     bssp = (BioseqSetPtr) sep->data.ptrvalue;
11383     sap = bssp->annot;
11384     sdp = bssp->descr;
11385   }
11386   while (sap != NULL && !found)
11387   {
11388     if (sap->type == 1)
11389     {
11390       sfp = (SeqFeatPtr) sap->data;
11391       while (sfp != NULL && ! found)
11392       {
11393         if (sfp->data.choice == SEQFEAT_BIOSRC
11394             && DoesOneSourceMatchConstraint (sfp->data.value.ptrvalue, cop->fsp->ccp))
11395         {
11396           found = TRUE;
11397         }
11398         sfp = sfp->next;
11399       }
11400     }
11401     sap = sap->next;
11402   }
11403 
11404   while (sdp != NULL && !found)
11405   {
11406     if (sdp->choice == Seq_descr_source
11407         && DoesOneSourceMatchConstraint (sdp->data.ptrvalue, cop->fsp->ccp))
11408     {
11409       found = TRUE;
11410     }
11411     sdp = sdp->next;
11412   }
11413   if (found)
11414   {
11415     if (cop->feature_action != NULL)
11416     {
11417       cop->omtp = ObjMgrTypeFind (cop->omp, OBJ_SEQFEAT, NULL, NULL);
11418       if (cop->omtp != NULL)
11419       {
11420         VisitBioseqsInSep (sep, cop, BioseqConstrainedFeaturesCallback);
11421       }
11422     }
11423 
11424     if (cop->descriptor_action != NULL)
11425     {
11426       cop->omtp = ObjMgrTypeFind (cop->omp, OBJ_SEQDESC, NULL, NULL);
11427       if (cop->omtp != NULL)
11428       {
11429         VisitDescriptorsInSep (sep, cop, SeqEntryConstrainedDescriptorsCallback);
11430       }
11431     }
11432   }
11433   else if (bssp != NULL)
11434   {
11435     ConstrainedSourceCallback (bssp->seq_set, cop);
11436   }
11437   ConstrainedSourceCallback (sep->next, cop);
11438 }
11439 
11440 
ConstrainedBioseqCallback(SeqEntryPtr sep,ConstraintOpPtr cop)11441 static void ConstrainedBioseqCallback (SeqEntryPtr sep, ConstraintOpPtr cop)
11442 {
11443   BioseqPtr       bsp = NULL;
11444   BioseqSetPtr    bssp = NULL;
11445   SeqFeatPtr      sfp;
11446   SeqDescPtr      sdp;
11447   SeqMgrFeatContext fcontext;
11448   SeqMgrDescContext dcontext;
11449 
11450   if (sep == NULL || sep->data.ptrvalue == NULL || cop == NULL || cop->fsp == NULL)
11451   {
11452     return;
11453   }
11454 
11455   if (IS_Bioseq (sep))
11456   {
11457     bsp = (BioseqPtr) sep->data.ptrvalue;
11458   }
11459   else if (IS_Bioseq_set (sep))
11460   {
11461     bssp = (BioseqSetPtr) sep->data.ptrvalue;
11462   }
11463 
11464   if (bsp != NULL && DoesIDListMeetStringConstraint (bsp->id, cop->fsp->id_list))
11465   {
11466     if (cop->feature_action != NULL)
11467     {
11468       cop->omtp = ObjMgrTypeFind (cop->omp, OBJ_SEQFEAT, NULL, NULL);
11469       if (cop->omtp != NULL)
11470       {
11471         for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
11472              sfp != NULL;
11473              sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &fcontext))
11474         {
11475           SeqEntryConstrainedFeaturesCallback (sfp, cop);
11476         }
11477       }
11478     }
11479 
11480     if (cop->descriptor_action != NULL)
11481     {
11482       cop->omtp = ObjMgrTypeFind (cop->omp, OBJ_SEQDESC, NULL, NULL);
11483       if (cop->omtp != NULL)
11484       {
11485         for (sdp = SeqMgrGetNextDescriptor (bsp, NULL, 0, &dcontext);
11486              sdp != NULL;
11487              sdp = SeqMgrGetNextDescriptor (bsp, sdp, 0, &dcontext))
11488         {
11489           SeqEntryConstrainedDescriptorsCallback (sdp, cop);
11490         }
11491       }
11492     }
11493   }
11494   else if (bssp != NULL)
11495   {
11496     ConstrainedBioseqCallback (bssp->seq_set, cop);
11497   }
11498   ConstrainedBioseqCallback (sep->next, cop);
11499 }
11500 
11501 
11502 extern void
OperateOnSeqEntryConstrainedObjects(SeqEntryPtr sep,FilterSetPtr fsp,FeatureActionProc feature_action,DescriptorActionProc descriptor_action,Uint1 seqFeatChoice,Uint1 featDefChoice,Uint1 descriptorChoice,Pointer userdata)11503 OperateOnSeqEntryConstrainedObjects
11504 (SeqEntryPtr           sep,
11505  FilterSetPtr          fsp,
11506  FeatureActionProc     feature_action,
11507  DescriptorActionProc  descriptor_action,
11508  Uint1                 seqFeatChoice,
11509  Uint1                 featDefChoice,
11510  Uint1                 descriptorChoice,
11511  Pointer               userdata)
11512 {
11513   ConstraintOpData  cod;
11514   AsnExpOptPtr      aeop;
11515   SeqEntryPtr       old_scope;
11516   BioseqPtr         bsp = NULL;
11517   SeqFeatPtr        sfp;
11518   SeqDescrPtr       sdp;
11519   SeqMgrFeatContext fcontext;
11520   SeqMgrDescContext dcontext;
11521 
11522   if (sep == NULL) return;
11523   if (feature_action == NULL && descriptor_action == NULL) return;
11524 
11525   cod.omp = ObjMgrGet ();
11526   if (cod.omp == NULL) return;
11527 
11528   cod.fsp               = fsp;
11529   cod.feature_action    = feature_action;
11530   cod.descriptor_action = descriptor_action;
11531   cod.userdata          = userdata;
11532   cod.entityID          = SeqMgrGetEntityIDForSeqEntry (sep);
11533   cod.seqFeatChoice     = seqFeatChoice;
11534   cod.featDefChoice     = featDefChoice;
11535   cod.descriptorChoice  = descriptorChoice;
11536 
11537   old_scope = SeqEntrySetScope (sep);
11538 
11539   cod.aip = AsnIoNullOpen ();
11540   if (fsp == NULL)
11541   {
11542     cod.ohsd.scp = NULL;
11543   }
11544   else
11545   {
11546     cod.ohsd.scp = fsp->scp;
11547   }
11548 
11549   aeop = AsnExpOptNew (cod.aip, NULL, NULL, AsnWriteConstraintCallBack);
11550   if (aeop != NULL) {
11551     aeop->user_data = (Pointer) &(cod.ohsd);
11552   }
11553 
11554   if (IS_Bioseq (sep))
11555   {
11556     bsp = (BioseqPtr) sep->data.ptrvalue;
11557   }
11558 
11559   if (fsp == NULL || (fsp->ccp == NULL && fsp->id_list == NULL)
11560       || (fsp->ccp != NULL && fsp->ccp->constraint_type == CHOICE_CONSTRAINT_ANY)
11561       || (fsp->id_list != NULL && bsp != NULL && DoesIDListMeetStringConstraint (bsp->id, fsp->id_list)))
11562   {
11563     if (feature_action != NULL)
11564     {
11565       cod.omtp = ObjMgrTypeFind (cod.omp, OBJ_SEQFEAT, NULL, NULL);
11566       if (cod.omtp != NULL)
11567       {
11568         if (bsp == NULL)
11569         {
11570           VisitBioseqsInSep (sep, &cod, BioseqConstrainedFeaturesCallback);
11571         }
11572         else
11573         {
11574           sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
11575           while (sfp != NULL)
11576           {
11577             SeqEntryConstrainedFeaturesCallback (sfp, &cod);
11578             sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &fcontext);
11579           }
11580         }
11581       }
11582     }
11583 
11584     if (descriptor_action != NULL)
11585     {
11586       cod.omtp = ObjMgrTypeFind (cod.omp, OBJ_SEQDESC, NULL, NULL);
11587       if (cod.omtp != NULL)
11588       {
11589         if (bsp == NULL)
11590         {
11591           VisitDescriptorsInSep (sep, &cod, SeqEntryConstrainedDescriptorsCallback);
11592         }
11593         else
11594         {
11595           sdp = SeqMgrGetNextDescriptor (bsp, NULL, 0, &dcontext);
11596           while (sdp != NULL)
11597           {
11598             SeqEntryConstrainedDescriptorsCallback (sdp, &cod);
11599             sdp = SeqMgrGetNextDescriptor (bsp, sdp, 0, &dcontext);
11600           }
11601         }
11602       }
11603     }
11604   }
11605   else if (fsp->id_list != NULL)
11606   {
11607     ConstrainedBioseqCallback (sep, &cod);
11608   }
11609   else
11610   {
11611     ConstrainedSourceCallback (sep, &cod);
11612   }
11613 
11614   AsnIoClose (cod.aip);
11615   SeqEntrySetScope (old_scope);
11616 }
11617 
GetSampleNew(void)11618 extern GetSamplePtr GetSampleNew (void)
11619 {
11620   GetSamplePtr gsp;
11621 
11622   gsp = (GetSamplePtr) MemNew (sizeof (GetSampleData));
11623   if (gsp != NULL)
11624   {
11625     gsp->all_same = TRUE;
11626     gsp->sample_text = NULL;
11627     gsp->num_found = 0;
11628     gsp->feat_dest_list = NULL;
11629     gsp->descr_dest_list = NULL;
11630 
11631     gsp->fieldstring_func = NULL;
11632     gsp->descrstring_func = NULL;
11633     gsp->requested_field = NULL;
11634     gsp->free_vn_proc = NULL;
11635     gsp->copy_vn_proc = NULL;
11636   }
11637   return gsp;
11638 }
11639 
GetSampleFree(GetSamplePtr gsp)11640 extern GetSamplePtr GetSampleFree (GetSamplePtr gsp)
11641 {
11642   if (gsp != NULL)
11643   {
11644     gsp->sample_text = MemFree (gsp->sample_text);
11645     if (gsp->free_vn_proc != NULL)
11646     {
11647       (gsp->free_vn_proc)(gsp->requested_field);
11648     }
11649     gsp->requested_field = ValNodeFree (gsp->requested_field);
11650     gsp->feat_dest_list = ValNodeFree (gsp->feat_dest_list);
11651     gsp->descr_dest_list = ValNodeFree (gsp->descr_dest_list);
11652     gsp = MemFree (gsp);
11653   }
11654   return gsp;
11655 }
11656 
GetSampleCopy(GetSamplePtr gsp)11657 static GetSamplePtr GetSampleCopy (GetSamplePtr gsp)
11658 {
11659   GetSamplePtr copy_gsp;
11660   ValNodePtr   copy_vnp;
11661 
11662   if (gsp == NULL)
11663   {
11664     return NULL;
11665   }
11666 
11667   copy_gsp = (GetSamplePtr) MemNew (sizeof (GetSampleData));
11668   if (copy_gsp != NULL)
11669   {
11670     copy_gsp->fieldstring_func = gsp->fieldstring_func;
11671     copy_gsp->descrstring_func = gsp->descrstring_func;
11672     copy_gsp->free_vn_proc = gsp->free_vn_proc;
11673     copy_gsp->copy_vn_proc = gsp->copy_vn_proc;
11674     if (copy_gsp->copy_vn_proc != NULL)
11675     {
11676       copy_gsp->requested_field = (gsp->copy_vn_proc) (gsp->requested_field);
11677     }
11678     copy_gsp->sample_text = StringSave (gsp->sample_text);
11679     copy_gsp->num_found = gsp->num_found;
11680     copy_gsp->all_same = gsp->all_same;
11681 
11682     copy_vnp = gsp->feat_dest_list;
11683     copy_gsp->feat_dest_list = NULL;
11684     while (copy_vnp != NULL)
11685     {
11686       ValNodeAddPointer (&(copy_gsp->feat_dest_list), copy_vnp->choice, copy_vnp->data.ptrvalue);
11687       copy_vnp = copy_vnp->next;
11688     }
11689 
11690     copy_vnp = gsp->descr_dest_list;
11691     copy_gsp->descr_dest_list = NULL;
11692     while (copy_vnp != NULL)
11693     {
11694       ValNodeAddPointer (&(copy_gsp->descr_dest_list), copy_vnp->choice, copy_vnp->data.ptrvalue);
11695       copy_vnp = copy_vnp->next;
11696     }
11697 
11698   }
11699   return copy_gsp;
11700 }
11701 
AddValNodeLists(ValNodePtr vnp1,ValNodePtr vnp2)11702 static ValNodePtr AddValNodeLists (ValNodePtr vnp1, ValNodePtr vnp2)
11703 {
11704   ValNodePtr new_list = NULL, copy_vnp, check_vnp;
11705 
11706   /* copy first list */
11707   copy_vnp = vnp1;
11708   while (copy_vnp != NULL)
11709   {
11710     ValNodeAddPointer (&(new_list), copy_vnp->choice, copy_vnp->data.ptrvalue);
11711     copy_vnp = copy_vnp->next;
11712   }
11713 
11714   copy_vnp = vnp2;
11715   while (copy_vnp != NULL)
11716   {
11717     /* check to see if destination is already in the list */
11718       check_vnp = new_list;
11719        while (check_vnp != NULL && check_vnp->data.ptrvalue != copy_vnp->data.ptrvalue)
11720        {
11721       check_vnp = check_vnp->next;
11722     }
11723 
11724     if (check_vnp == NULL)
11725     {
11726       /* add to list if not present */
11727       ValNodeAddPointer (&new_list, copy_vnp->choice, copy_vnp->data.ptrvalue);
11728     }
11729     else if (check_vnp->choice < 250)
11730     {
11731       /* do not increase choice beyond 250 */
11732       check_vnp->choice ++;
11733     }
11734 
11735     copy_vnp = copy_vnp->next;
11736   }
11737   return new_list;
11738 }
11739 
GetSampleAdd(GetSamplePtr gsp1,GetSamplePtr gsp2)11740 static GetSamplePtr GetSampleAdd (GetSamplePtr gsp1, GetSamplePtr gsp2)
11741 {
11742   GetSamplePtr sum_gsp;
11743 
11744   if (gsp1 == NULL && gsp2 == NULL)
11745   {
11746     sum_gsp =  NULL;
11747   }
11748   else if (gsp1 == NULL)
11749   {
11750     sum_gsp =  GetSampleCopy (gsp2);
11751   }
11752   else if (gsp2 == NULL)
11753   {
11754     sum_gsp =  GetSampleCopy (gsp1);
11755   }
11756   else
11757   {
11758     sum_gsp = (GetSamplePtr) MemNew (sizeof (GetSampleData));
11759     if (sum_gsp != NULL)
11760     {
11761       sum_gsp->fieldstring_func = gsp1->fieldstring_func;
11762       sum_gsp->descrstring_func = gsp1->descrstring_func;
11763       sum_gsp->requested_field = gsp1->requested_field;
11764       gsp1->requested_field = NULL;
11765       sum_gsp->sample_text = StringSave (gsp1->sample_text);
11766       sum_gsp->num_found = gsp1->num_found + gsp2->num_found;
11767       if (gsp1->num_found == 0)
11768       {
11769         sum_gsp->all_same = gsp2->all_same;
11770       }
11771       else if (gsp2->num_found == 0)
11772       {
11773         sum_gsp->all_same = gsp1->all_same;
11774       }
11775       else if (!gsp1->all_same || ! gsp2->all_same)
11776       {
11777         sum_gsp->all_same = FALSE;
11778       }
11779       else if (StringCmp (gsp1->sample_text, gsp2->sample_text) == 0)
11780       {
11781         sum_gsp->all_same = TRUE;
11782       }
11783       else
11784       {
11785         sum_gsp->all_same = FALSE;
11786       }
11787 
11788       /* combine destination lists */
11789       sum_gsp->feat_dest_list = AddValNodeLists (gsp1->feat_dest_list, gsp2->feat_dest_list);
11790 
11791     }
11792   }
11793   return sum_gsp;
11794 }
11795 
11796 
GetSampleFeatureCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)11797 static void GetSampleFeatureCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
11798 {
11799   GetSamplePtr cp;
11800   CharPtr      str;
11801   ValNodePtr   check_vnp;
11802 
11803   if (sfp == NULL || userdata == NULL)
11804   {
11805     return;
11806   }
11807 
11808   cp = (GetSamplePtr) userdata;
11809   if (cp->fieldstring_func == NULL)
11810   {
11811     return;
11812   }
11813 
11814   check_vnp = cp->feat_dest_list;
11815   while (check_vnp != NULL && check_vnp->data.ptrvalue != sfp)
11816   {
11817     check_vnp = check_vnp->next;
11818   }
11819   if (check_vnp == NULL)
11820   {
11821     ValNodeAddPointer (&(cp->feat_dest_list), 1, sfp);
11822   }
11823   else
11824   {
11825     if (check_vnp->choice < 250)
11826     {
11827       check_vnp->choice ++;
11828     }
11829     return;
11830   }
11831 
11832   str = cp->fieldstring_func (sfp, cp->requested_field, NULL);
11833   if (!StringHasNoText (str) || (fsp != NULL && fsp->scp != NULL && fsp->scp->not_present))
11834   {
11835     cp->num_found ++;
11836     if (cp->sample_text == NULL)
11837     {
11838       cp->sample_text = str;
11839     }
11840     else
11841     {
11842       if (StringCmp (str, cp->sample_text) != 0)
11843       {
11844         cp->all_same = FALSE;
11845       }
11846       str = MemFree (str);
11847     }
11848   }
11849 }
11850 
GetSampleDescriptorCallback(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)11851 static void GetSampleDescriptorCallback (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
11852 {
11853   GetSamplePtr cp;
11854   CharPtr      str;
11855   ValNodePtr   check_vnp;
11856 
11857   if (sdp == NULL || userdata == NULL)
11858   {
11859     return;
11860   }
11861 
11862   cp = (GetSamplePtr) userdata;
11863   if (cp->descrstring_func == NULL)
11864   {
11865     return;
11866   }
11867 
11868   check_vnp = cp->descr_dest_list;
11869   while (check_vnp != NULL && check_vnp->data.ptrvalue != sdp)
11870   {
11871     check_vnp = check_vnp->next;
11872   }
11873   if (check_vnp == NULL)
11874   {
11875     ValNodeAddPointer (&(cp->descr_dest_list), 1, sdp);
11876   }
11877   else
11878   {
11879     if (check_vnp->choice < 250)
11880     {
11881       check_vnp->choice ++;
11882     }
11883     return;
11884   }
11885 
11886   str = cp->descrstring_func (sdp, cp->requested_field, NULL);
11887   if (!StringHasNoText (str))
11888   {
11889     cp->num_found ++;
11890     if (cp->sample_text == NULL)
11891     {
11892       cp->sample_text = str;
11893     }
11894     else
11895     {
11896       if (StringCmp (str, cp->sample_text) != 0)
11897       {
11898         cp->all_same = FALSE;
11899       }
11900       str = MemFree (str);
11901     }
11902   }
11903 }
11904 
CheckForExistingTextInSeqEntry(SeqEntryPtr sep,ValNodePtr requested_field,GetFeatureFieldString fieldstring_func,GetDescriptorFieldString descrstring_func,FreeValNodeProc free_vn_proc,CopyValNodeDataProc copy_vn_proc,FilterSetPtr fsp,Uint1 seqfeat_choice,Uint1 featdef_choice,Uint1 descr_choice)11905 static GetSamplePtr CheckForExistingTextInSeqEntry
11906 (SeqEntryPtr              sep,
11907  ValNodePtr               requested_field,
11908  GetFeatureFieldString    fieldstring_func,
11909  GetDescriptorFieldString descrstring_func,
11910  FreeValNodeProc          free_vn_proc,
11911  CopyValNodeDataProc      copy_vn_proc,
11912  FilterSetPtr             fsp,
11913  Uint1                    seqfeat_choice,
11914  Uint1                    featdef_choice,
11915  Uint1                    descr_choice)
11916 {
11917   GetSamplePtr gsp;
11918 
11919   gsp = (GetSamplePtr) MemNew (sizeof (GetSampleData));
11920   if (gsp != NULL)
11921   {
11922     gsp->sample_text = NULL;
11923     gsp->fieldstring_func = fieldstring_func;
11924     gsp->descrstring_func = descrstring_func;
11925     gsp->free_vn_proc = free_vn_proc;
11926     gsp->copy_vn_proc = copy_vn_proc;
11927     gsp->requested_field = (gsp->copy_vn_proc) (requested_field);
11928     gsp->num_found = 0;
11929     gsp->all_same = TRUE;
11930     OperateOnSeqEntryConstrainedObjects (sep, fsp, GetSampleFeatureCallback,
11931                                          GetSampleDescriptorCallback,
11932                                          seqfeat_choice, featdef_choice,
11933                                          descr_choice, gsp);
11934   }
11935   return gsp;
11936 }
11937 
CheckForExistingText(Uint2 entityID,ValNodePtr requested_field,GetFeatureFieldString fieldstring_func,GetDescriptorFieldString descrstring_func,FreeValNodeProc free_vn_proc,CopyValNodeDataProc copy_vn_proc,FilterSetPtr fsp,Uint1 seqfeat_choice,Uint1 featdef_choice,Uint1 descr_choice)11938 static GetSamplePtr CheckForExistingText
11939 (Uint2                    entityID,
11940  ValNodePtr               requested_field,
11941  GetFeatureFieldString    fieldstring_func,
11942  GetDescriptorFieldString descrstring_func,
11943  FreeValNodeProc          free_vn_proc,
11944  CopyValNodeDataProc      copy_vn_proc,
11945  FilterSetPtr             fsp,
11946  Uint1                    seqfeat_choice,
11947  Uint1                    featdef_choice,
11948  Uint1                    descr_choice)
11949 {
11950   SeqEntryPtr  sep;
11951 
11952   sep = GetTopSeqEntryForEntityID (entityID);
11953   return CheckForExistingTextInSeqEntry (sep, requested_field,
11954                                          fieldstring_func, descrstring_func,
11955                                          free_vn_proc, copy_vn_proc, fsp,
11956                                          seqfeat_choice, featdef_choice, descr_choice);
11957 }
11958 
HandleApplyValue(CharPtr orig_text,ApplyValuePtr avp)11959 extern CharPtr HandleApplyValue (CharPtr orig_text, ApplyValuePtr avp)
11960 {
11961   CharPtr new_str, cp_found;
11962   Int4    found_len, replace_len, new_len;
11963 
11964   if (avp == NULL)
11965   {
11966     return orig_text;
11967   }
11968   else if (StringHasNoText (orig_text))
11969   {
11970     if (StringHasNoText (avp->text_to_replace))
11971     {
11972       MemFree (orig_text);
11973       return StringSave (avp->new_text);
11974     }
11975     else
11976     {
11977       return orig_text;
11978     }
11979   }
11980   else if (StringHasNoText (avp->text_to_replace))
11981   {
11982     return HandleExistingText (orig_text, StringSave (avp->new_text), avp->etp);
11983   }
11984   else
11985   {
11986     found_len = StringLen (avp->text_to_replace);
11987     replace_len = StringLen (avp->new_text);
11988     cp_found = StringISearch (orig_text, avp->text_to_replace);
11989     if (avp->where_to_replace == EditApplyFindLocation_beginning
11990         && cp_found != orig_text) {
11991       cp_found = NULL;
11992     }
11993     while (cp_found != NULL)
11994     {
11995       if (avp->where_to_replace == EditApplyFindLocation_end
11996           && cp_found != orig_text + StringLen (orig_text) - found_len) {
11997         cp_found = StringISearch (cp_found + found_len, avp->text_to_replace);
11998       } else {
11999         new_len = StringLen (orig_text) + 1 - found_len + replace_len;
12000         new_str = (CharPtr) MemNew (new_len * sizeof (Char));
12001         if (new_str != NULL)
12002         {
12003           if (cp_found != orig_text)
12004           {
12005             StringNCpy (new_str, orig_text, cp_found - orig_text);
12006           }
12007           StringCat (new_str, avp->new_text);
12008           StringCat (new_str, cp_found + found_len);
12009           cp_found = new_str + (cp_found - orig_text) + replace_len;
12010           orig_text = MemFree (orig_text);
12011           orig_text = new_str;
12012         }
12013         cp_found = StringISearch (cp_found, avp->text_to_replace);
12014       }
12015     }
12016     return orig_text;
12017   }
12018 }
12019 
ApplyValueToValNodeStringList(ValNodePtr list,Int2 choice,ApplyValuePtr avp)12020 extern ValNodePtr ApplyValueToValNodeStringList (ValNodePtr list, Int2 choice, ApplyValuePtr avp)
12021 {
12022   ValNodePtr vnp;
12023 
12024   if (avp == NULL)
12025   {
12026     return NULL;
12027   }
12028 
12029   if (!StringHasNoText (avp->text_to_replace))
12030   {
12031     for (vnp = list; vnp != NULL; vnp = vnp->next)
12032     {
12033       vnp->data.ptrvalue = HandleApplyValue (vnp->data.ptrvalue, avp);
12034     }
12035   }
12036   else
12037   {
12038     ValNodeAddPointer (&list, choice, StringSave (avp->new_text));
12039   }
12040   return list;
12041 }
12042 
12043 
12044 
MakeSemicolonStringsIntoSeparateItems(ValNodePtr PNTR list)12045 static void MakeSemicolonStringsIntoSeparateItems (ValNodePtr PNTR list)
12046 {
12047   ValNodePtr prev = NULL, vnp_next, vnp, vnp_new;
12048   CharPtr    cp;
12049 
12050   if (list == NULL || *list == NULL) return;
12051 
12052   vnp = *list;
12053   while (vnp != NULL)
12054   {
12055     vnp_next = vnp->next;
12056     if (StringHasNoText (vnp->data.ptrvalue))
12057     {
12058       if (prev == NULL)
12059       {
12060         *list = vnp_next;
12061       }
12062       else
12063       {
12064         prev->next = vnp_next;
12065       }
12066       vnp->next = NULL;
12067       vnp = ValNodeFreeData (vnp);
12068     }
12069     else if ((cp = StringChr (vnp->data.ptrvalue, ';')) != NULL)
12070     {
12071       vnp_new = ValNodeNew (NULL);
12072       vnp_new->choice = vnp->choice;
12073       vnp_new->data.ptrvalue = StringSave (cp + 1);
12074       vnp_new->next = vnp_next;
12075       *cp = 0;
12076       vnp->next = vnp_new;
12077       vnp_next = vnp_new;
12078       prev = vnp;
12079     }
12080     else
12081     {
12082       prev = vnp;
12083     }
12084     vnp = vnp_next;
12085   }
12086 }
12087 
12088 
ApplyValueToValNodeStringListAsText(ValNodePtr list,Int2 choice,ApplyValuePtr avp)12089 extern ValNodePtr ApplyValueToValNodeStringListAsText (ValNodePtr list, Int2 choice, ApplyValuePtr avp)
12090 {
12091   ValNodePtr vnp;
12092 
12093   if (avp == NULL)
12094   {
12095     return NULL;
12096   }
12097 
12098   if (!StringHasNoText (avp->text_to_replace))
12099   {
12100     for (vnp = list; vnp != NULL; vnp = vnp->next)
12101     {
12102       vnp->data.ptrvalue = HandleApplyValue (vnp->data.ptrvalue, avp);
12103     }
12104   }
12105   else
12106   {
12107     if (avp->etp == NULL
12108         || avp->etp->existing_text_choice == eExistingTextChoiceReplaceOld)
12109     {
12110       list = ValNodeFree (list);
12111       ValNodeAddPointer (&list, choice, StringSave (avp->new_text));
12112     }
12113     else if (avp->etp->existing_text_choice == eExistingTextChoiceAppendSemi)
12114     {
12115       ValNodeAddPointer (&list, choice, StringSave (avp->new_text));
12116     }
12117     else if (avp->etp->existing_text_choice == eExistingTextChoicePrefixSemi)
12118     {
12119       vnp = ValNodeNew(NULL);
12120       vnp->choice = (Uint1) choice;
12121       vnp->data.ptrvalue = StringSave (avp->new_text);
12122       vnp->next = list;
12123       list = vnp;
12124     }
12125     else if (avp->etp->existing_text_choice == eExistingTextChoiceLeaveOld)
12126     {
12127       if (list == NULL)
12128       {
12129         ValNodeAddPointer (&list, choice, StringSave (avp->new_text));
12130       }
12131     } else {
12132       for (vnp = list; vnp != NULL; vnp = vnp->next)
12133       {
12134         vnp->data.ptrvalue = HandleApplyValue (vnp->data.ptrvalue, avp);
12135       }
12136     }
12137   }
12138 
12139   if (avp->etp == NULL || avp->etp->existing_text_choice != eExistingTextChoiceLeaveOld)
12140   {
12141     MakeSemicolonStringsIntoSeparateItems (&list);
12142   }
12143   return list;
12144 }
12145 
12146 
12147 typedef struct parsefielddialog
12148 {
12149   DIALOG_MESSAGE_BLOCK
12150   DialoG                   parse_field_type;
12151   DialoG                   biosrc_string_choice;
12152   DialoG                   source_qual_choice;
12153   DialoG                   gene_field;
12154   DialoG                   rna_subtype;
12155   DialoG                   rna_field;
12156   DialoG                   protein_field;
12157   DialoG                   import_feature;
12158   DialoG                   import_qual;
12159   DialoG                   feature;
12160   GrouP                    dbxref_grp;
12161   TexT                     dbxref_db;
12162   GrouP                    feat_or_desc;
12163   Nlm_ChangeNotifyProc     change_notify;
12164   Pointer                  change_userdata;
12165   Boolean                  is_search_field;
12166 } ParseFieldDialogData, PNTR ParseFieldDialogPtr;
12167 
ChangeParseFieldType(Pointer data)12168 static void ChangeParseFieldType (Pointer data)
12169 {
12170   ParseFieldDialogPtr dlg;
12171   ValNodePtr          vnp;
12172 
12173   dlg = (ParseFieldDialogPtr) data;
12174   if (dlg == NULL)
12175   {
12176     return;
12177   }
12178   vnp = DialogToPointer (dlg->parse_field_type);
12179   Hide (dlg->biosrc_string_choice);
12180   Hide (dlg->feat_or_desc);
12181   Hide (dlg->source_qual_choice);
12182   Hide (dlg->gene_field);
12183   Hide (dlg->rna_subtype);
12184   Hide (dlg->rna_field);
12185   Hide (dlg->protein_field);
12186   Hide (dlg->import_feature);
12187   Hide (dlg->import_qual);
12188   Hide (dlg->feature);
12189   Hide (dlg->dbxref_grp);
12190   if (vnp != NULL)
12191   {
12192     switch (vnp->choice)
12193     {
12194       case PARSE_FIELD_BIOSRC_STRING:
12195         Show (dlg->biosrc_string_choice);
12196         Show (dlg->feat_or_desc);
12197         break;
12198       case PARSE_FIELD_SOURCE_QUAL:
12199         Show (dlg->source_qual_choice);
12200         Show (dlg->feat_or_desc);
12201         break;
12202       case PARSE_FIELD_GENE_FIELD:
12203         Show (dlg->gene_field);
12204         break;
12205       case PARSE_FIELD_RNA_FIELD:
12206         Show (dlg->rna_subtype);
12207         Show (dlg->rna_field);
12208         break;
12209       case PARSE_FIELD_PROTEIN_FIELD:
12210         Show (dlg->protein_field);
12211         break;
12212       case PARSE_FIELD_IMPORT_QUAL:
12213         Show (dlg->import_feature);
12214         Show (dlg->import_qual);
12215         break;
12216       case PARSE_FIELD_FEATURE_NOTE:
12217         Show (dlg->feature);
12218         break;
12219       case PARSE_FIELD_DBXREF:
12220         Show (dlg->dbxref_grp);
12221         break;
12222     }
12223   }
12224   if (dlg->change_notify != NULL)
12225   {
12226     (dlg->change_notify)(dlg->change_userdata);
12227   }
12228 }
12229 
ResetParseFieldDialog(ParseFieldDialogPtr dlg)12230 static void ResetParseFieldDialog (ParseFieldDialogPtr dlg)
12231 {
12232   ValNode vn;
12233 
12234   if (dlg == NULL)
12235   {
12236     return;
12237   }
12238   vn.choice = PARSE_FIELD_DEFLINE;
12239   vn.data.ptrvalue = NULL;
12240   vn.next = NULL;
12241   PointerToDialog (dlg->parse_field_type, &vn);
12242   ChangeParseFieldType (dlg);
12243 }
12244 
ParseFieldToDialog(DialoG d,Pointer data)12245 static void ParseFieldToDialog (DialoG d, Pointer data)
12246 {
12247   ParseFieldDialogPtr dlg;
12248   ParseFieldPtr       parse_field;
12249   Int4                parse_field_type;
12250   ValNode             vn;
12251 
12252   dlg = (ParseFieldDialogPtr) GetObjectExtra (d);
12253   if (dlg == NULL)
12254   {
12255     return;
12256   }
12257   ResetParseFieldDialog (dlg);
12258   parse_field = (ParseFieldPtr) data;
12259   if (parse_field != NULL)
12260   {
12261     parse_field_type = parse_field->parse_field_type;
12262     if (parse_field_type < PARSE_FIELD_DEFLINE
12263         || (dlg->is_search_field && parse_field_type > SEARCH_FIELD_PUBLICATION)
12264         || (!dlg->is_search_field && parse_field_type > MAX_PARSE_FIELD_TYPE))
12265     {
12266       parse_field_type = PARSE_FIELD_DEFLINE;
12267     }
12268     vn.choice = parse_field_type;
12269     vn.data.ptrvalue = NULL;
12270     vn.next = NULL;
12271     PointerToDialog (dlg->parse_field_type, &vn);
12272     switch (parse_field_type)
12273     {
12274       case PARSE_FIELD_BIOSRC_STRING:
12275         PointerToDialog (dlg->biosrc_string_choice, parse_field->feature_field);
12276         if (parse_field->do_desc && parse_field->do_feat)
12277         {
12278           SetValue (dlg->feat_or_desc, 1);
12279         }
12280         else if (parse_field->do_desc)
12281         {
12282           SetValue (dlg->feat_or_desc, 2);
12283         }
12284         else if (parse_field->do_feat)
12285         {
12286           SetValue (dlg->feat_or_desc, 3);
12287         }
12288         else
12289         {
12290           SetValue (dlg->feat_or_desc, 1);
12291         }
12292         break;
12293       case PARSE_FIELD_SOURCE_QUAL:
12294         PointerToDialog (dlg->source_qual_choice, parse_field->feature_field);
12295         if (parse_field->do_desc && parse_field->do_feat)
12296         {
12297           SetValue (dlg->feat_or_desc, 1);
12298         }
12299         else if (parse_field->do_desc)
12300         {
12301           SetValue (dlg->feat_or_desc, 2);
12302         }
12303         else if (parse_field->do_feat)
12304         {
12305           SetValue (dlg->feat_or_desc, 3);
12306         }
12307         else
12308         {
12309           SetValue (dlg->feat_or_desc, 1);
12310         }
12311         break;
12312       case PARSE_FIELD_DBXREF:
12313         if (parse_field->feature_field == NULL || parse_field->feature_field->data.ptrvalue == NULL)
12314         {
12315           SetTitle (dlg->dbxref_db, "");
12316         }
12317         else
12318         {
12319           SetTitle (dlg->dbxref_db, parse_field->feature_field->data.ptrvalue);
12320         }
12321         if (parse_field->do_desc && parse_field->do_feat)
12322         {
12323           SetValue (dlg->feat_or_desc, 1);
12324         }
12325         else if (parse_field->do_desc)
12326         {
12327           SetValue (dlg->feat_or_desc, 2);
12328         }
12329         else if (parse_field->do_feat)
12330         {
12331           SetValue (dlg->feat_or_desc, 3);
12332         }
12333         else
12334         {
12335           SetValue (dlg->feat_or_desc, 1);
12336         }
12337         break;
12338       case PARSE_FIELD_GENE_FIELD:
12339         PointerToDialog (dlg->gene_field, parse_field->feature_field);
12340         break;
12341       case PARSE_FIELD_RNA_FIELD:
12342         PointerToDialog (dlg->rna_subtype, parse_field->feature_subtype);
12343         PointerToDialog (dlg->rna_field, parse_field->feature_field);
12344         break;
12345       case PARSE_FIELD_PROTEIN_FIELD:
12346         PointerToDialog (dlg->protein_field, parse_field->feature_field);
12347         break;
12348       case PARSE_FIELD_IMPORT_QUAL:
12349         PointerToDialog (dlg->import_feature, parse_field->feature_subtype);
12350         PointerToDialog (dlg->import_qual, parse_field->feature_field);
12351         break;
12352       case PARSE_FIELD_FEATURE_NOTE:
12353         PointerToDialog (dlg->feature, parse_field->feature_field);
12354         break;
12355       case SEARCH_FIELD_PUBLICATION:
12356         /* nothing to do here */
12357         break;
12358     }
12359   }
12360   ChangeParseFieldType (dlg);
12361 }
12362 
DialogToParseField(DialoG d)12363 static Pointer DialogToParseField (DialoG d)
12364 {
12365   ParseFieldDialogPtr dlg;
12366   ParseFieldPtr       parse_field;
12367   Int4                val;
12368   ValNodePtr          vnp;
12369 
12370   dlg = (ParseFieldDialogPtr) GetObjectExtra (d);
12371   if (dlg == NULL)
12372   {
12373     return NULL;
12374   }
12375   vnp = DialogToPointer (dlg->parse_field_type);
12376   if (vnp == NULL)
12377   {
12378     return NULL;
12379   }
12380 
12381   parse_field = (ParseFieldPtr) MemNew (sizeof (ParseFieldData));
12382   if (parse_field != NULL)
12383   {
12384     parse_field->parse_field_type = vnp->choice;
12385     parse_field->feature_field = NULL;
12386     switch (parse_field->parse_field_type)
12387     {
12388       case PARSE_FIELD_BIOSRC_STRING:
12389         parse_field->feature_field = DialogToPointer (dlg->biosrc_string_choice);
12390         val = GetValue (dlg->feat_or_desc);
12391         switch (val)
12392         {
12393           case 2:
12394             parse_field->do_desc = TRUE;
12395             parse_field->do_feat = FALSE;
12396             break;
12397           case 3:
12398             parse_field->do_desc = FALSE;
12399             parse_field->do_feat = TRUE;
12400             break;
12401           case 1:
12402           default:
12403             parse_field->do_desc = TRUE;
12404             parse_field->do_feat = TRUE;
12405             break;
12406         }
12407         break;
12408       case PARSE_FIELD_SOURCE_QUAL:
12409         parse_field->feature_field = DialogToPointer (dlg->source_qual_choice);
12410         val = GetValue (dlg->feat_or_desc);
12411         switch (val)
12412         {
12413           case 2:
12414             parse_field->do_desc = TRUE;
12415             parse_field->do_feat = FALSE;
12416             break;
12417           case 3:
12418             parse_field->do_desc = FALSE;
12419             parse_field->do_feat = TRUE;
12420             break;
12421           case 1:
12422           default:
12423             parse_field->do_desc = TRUE;
12424             parse_field->do_feat = TRUE;
12425             break;
12426         }
12427         break;
12428       case PARSE_FIELD_DBXREF:
12429         if (!TextHasNoText (dlg->dbxref_db))
12430         {
12431           ValNodeAddPointer (&(parse_field->feature_field), 0, SaveStringFromText (dlg->dbxref_db));
12432         }
12433         val = GetValue (dlg->feat_or_desc);
12434         switch (val)
12435         {
12436           case 2:
12437             parse_field->do_desc = TRUE;
12438             parse_field->do_feat = FALSE;
12439             break;
12440           case 3:
12441             parse_field->do_desc = FALSE;
12442             parse_field->do_feat = TRUE;
12443             break;
12444           case 1:
12445           default:
12446             parse_field->do_desc = TRUE;
12447             parse_field->do_feat = TRUE;
12448             break;
12449         }
12450         break;
12451       case PARSE_FIELD_GENE_FIELD:
12452         parse_field->feature_field = DialogToPointer (dlg->gene_field);
12453         break;
12454       case PARSE_FIELD_RNA_FIELD:
12455         parse_field->feature_subtype = DialogToPointer (dlg->rna_subtype);
12456         parse_field->feature_field = DialogToPointer (dlg->rna_field);
12457         break;
12458       case PARSE_FIELD_PROTEIN_FIELD:
12459         parse_field->feature_field = DialogToPointer (dlg->protein_field);
12460         break;
12461       case PARSE_FIELD_IMPORT_QUAL:
12462         parse_field->feature_subtype = DialogToPointer (dlg->import_feature);
12463         parse_field->feature_field = DialogToPointer (dlg->import_qual);
12464         break;
12465       case PARSE_FIELD_FEATURE_NOTE:
12466         parse_field->feature_field = DialogToPointer (dlg->feature);
12467         break;
12468       case SEARCH_FIELD_PUBLICATION:
12469         /* nothing to do here */
12470         break;
12471     }
12472   }
12473   vnp = ValNodeFreeData (vnp);
12474   return parse_field;
12475 }
12476 
ParseFieldMessage(DialoG d,Int2 mssg)12477 static void ParseFieldMessage (DialoG d, Int2 mssg)
12478 
12479 {
12480   ParseFieldDialogPtr dlg;
12481 
12482   dlg = (ParseFieldDialogPtr) GetObjectExtra (d);
12483   if (dlg != NULL) {
12484     switch (mssg) {
12485       case VIB_MSG_INIT :
12486         ResetParseFieldDialog (dlg);
12487         break;
12488       case VIB_MSG_ENTER :
12489         Select (dlg->parse_field_type);
12490         break;
12491       default :
12492         break;
12493     }
12494   }
12495 }
12496 
TestParseFieldDialog(DialoG d)12497 static ValNodePtr TestParseFieldDialog (DialoG d)
12498 
12499 {
12500   ValNodePtr          head = NULL;
12501   ParseFieldDialogPtr dlg;
12502   Int4                parse_field_type;
12503   ValNodePtr          vnp;
12504 
12505   dlg = (ParseFieldDialogPtr) GetObjectExtra (d);
12506 
12507   if (dlg != NULL)
12508   {
12509     vnp = DialogToPointer (dlg->parse_field_type);
12510     if (vnp == NULL)
12511     {
12512       head = AddStringToValNodeChain (head, "destination type", 1);
12513     }
12514     else
12515     {
12516       parse_field_type = vnp->choice;
12517       vnp = ValNodeFreeData (vnp);
12518       switch (parse_field_type)
12519       {
12520         case PARSE_FIELD_DEFLINE:
12521         case PARSE_FIELD_CDS_COMMENT:
12522         case PARSE_FIELD_COMMENT_DESC:
12523           /* don't need any extra information */
12524           break;
12525         case PARSE_FIELD_BIOSRC_STRING:
12526           vnp = DialogToPointer (dlg->biosrc_string_choice);
12527           if (vnp == NULL)
12528           {
12529             head = AddStringToValNodeChain (head, "biosrc string type", 1);
12530           }
12531           ValNodeFree (vnp);
12532           break;
12533         case PARSE_FIELD_SOURCE_QUAL:
12534           vnp = DialogToPointer (dlg->source_qual_choice);
12535           if (vnp == NULL)
12536           {
12537             head = AddStringToValNodeChain (head, "source qual type", 1);
12538           }
12539           ValNodeFree (vnp);
12540           break;
12541         case PARSE_FIELD_GENE_FIELD:
12542           vnp = DialogToPointer (dlg->gene_field);
12543           if (vnp == NULL || vnp->data.intvalue == FEATUREFIELD_NONE)
12544           {
12545             head = AddStringToValNodeChain (head, "gene field", 1);
12546           }
12547           ValNodeFree (vnp);
12548           break;
12549         case PARSE_FIELD_RNA_FIELD:
12550           vnp = DialogToPointer (dlg->rna_subtype);
12551           if (vnp == NULL)
12552           {
12553             head = AddStringToValNodeChain (head, "RNA subtype", 1);
12554           }
12555           ValNodeFree (vnp);
12556           vnp = DialogToPointer (dlg->rna_field);
12557           if (vnp == NULL || vnp->data.intvalue == FEATUREFIELD_NONE)
12558           {
12559             head = AddStringToValNodeChain (head, "RNA field", 1);
12560           }
12561           ValNodeFree (vnp);
12562           break;
12563         case PARSE_FIELD_PROTEIN_FIELD:
12564           vnp = DialogToPointer (dlg->protein_field);
12565           if (vnp == NULL || vnp->data.intvalue == FEATUREFIELD_NONE)
12566           {
12567             head = AddStringToValNodeChain (head, "protein field", 1);
12568           }
12569           ValNodeFree (vnp);
12570           break;
12571         case PARSE_FIELD_IMPORT_QUAL:
12572           vnp = DialogToPointer (dlg->import_qual);
12573           if (vnp == NULL)
12574           {
12575             ValNodeAddPointer (&head, 1, "import qualifier");
12576           }
12577           ValNodeFree (vnp);
12578           vnp = DialogToPointer (dlg->import_feature);
12579           if (vnp == NULL)
12580           {
12581             ValNodeAddPointer (&head, 1, "import feature");
12582           }
12583           ValNodeFree (vnp);
12584           break;
12585         case PARSE_FIELD_FEATURE_NOTE:
12586           vnp = DialogToPointer (dlg->feature);
12587           if (vnp == NULL)
12588           {
12589             ValNodeAddPointer (&head, 1, "feature");
12590             ValNodeFree (vnp);
12591           }
12592           break;
12593         case PARSE_FIELD_DBXREF:
12594           if (TextHasNoText (dlg->dbxref_db))
12595           {
12596             ValNodeAddPointer (&head, 1, "specify database");
12597           }
12598           break;
12599         case SEARCH_FIELD_PUBLICATION:
12600           if (!dlg->is_search_field)
12601           {
12602             head = AddStringToValNodeChain (head, "field type", 1);
12603           }
12604           break;
12605         default:
12606           head = AddStringToValNodeChain (head, "field type", 1);
12607           break;
12608       }
12609     }
12610   }
12611 
12612   return head;
12613 }
12614 
12615 
GetParseFieldDestList(Boolean include_pub,Boolean include_dbxref)12616 static ValNodePtr GetParseFieldDestList (Boolean include_pub, Boolean include_dbxref)
12617 {
12618   ValNodePtr list = NULL;
12619 
12620   ValNodeAddPointer (&list, PARSE_FIELD_DEFLINE, StringSave ("Definition Line"));
12621   ValNodeAddPointer (&list, PARSE_FIELD_BIOSRC_STRING, StringSave ("Biosource"));
12622   ValNodeAddPointer (&list, PARSE_FIELD_SOURCE_QUAL, StringSave ("Source Qualifier"));
12623   ValNodeAddPointer (&list, PARSE_FIELD_GENE_FIELD, StringSave ("Gene Field"));
12624   ValNodeAddPointer (&list, PARSE_FIELD_RNA_FIELD, StringSave ("RNA Field"));
12625   ValNodeAddPointer (&list, PARSE_FIELD_CDS_COMMENT, StringSave ("CDS Comment"));
12626   ValNodeAddPointer (&list, PARSE_FIELD_PROTEIN_FIELD, StringSave ("Protein Field"));
12627   ValNodeAddPointer (&list, PARSE_FIELD_IMPORT_QUAL, StringSave ("Import Feature"));
12628   ValNodeAddPointer (&list, PARSE_FIELD_FEATURE_NOTE, StringSave ("Feature Note"));
12629   ValNodeAddPointer (&list, PARSE_FIELD_COMMENT_DESC, StringSave ("Comment Descriptor"));
12630   if (include_dbxref)
12631   {
12632     ValNodeAddPointer (&list, PARSE_FIELD_DBXREF, StringSave ("Dbxref"));
12633   }
12634   if (include_pub)
12635   {
12636     ValNodeAddPointer (&list, SEARCH_FIELD_PUBLICATION, StringSave ("Publication"));
12637   }
12638   return list;
12639 }
12640 
12641 
ChangeParseFieldDestText(TexT t)12642 static void ChangeParseFieldDestText (TexT t)
12643 {
12644   ParseFieldDialogPtr dlg;
12645 
12646   dlg = (ParseFieldDialogPtr) GetObjectExtra (t);
12647   if (dlg != NULL && dlg->change_notify != NULL)
12648   {
12649     (dlg->change_notify) (dlg->change_userdata);
12650   }
12651 }
12652 
12653 
ParseFieldDestDialogEx(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Boolean is_search_field,Boolean include_dbxref)12654 extern DialoG ParseFieldDestDialogEx
12655 (GrouP                    h,
12656  Nlm_ChangeNotifyProc     change_notify,
12657  Pointer                  change_userdata,
12658  Boolean                  is_search_field,
12659  Boolean                  include_dbxref)
12660 {
12661   ParseFieldDialogPtr dlg;
12662   GrouP               p, m, g;
12663   GrouP               subgrp;
12664   ValNodePtr          choice_list;
12665   ValNode             vn;
12666 
12667   dlg = (ParseFieldDialogPtr) MemNew (sizeof (ParseFieldDialogData));
12668   if (dlg == NULL)
12669   {
12670     return NULL;
12671   }
12672 
12673   p = HiddenGroup (h, -1, 0, NULL);
12674   SetObjectExtra (p, dlg, StdCleanupExtraProc);
12675 
12676   dlg->dialog = (DialoG) p;
12677   dlg->todialog = ParseFieldToDialog;
12678   dlg->fromdialog = DialogToParseField;
12679   dlg->dialogmessage = ParseFieldMessage;
12680   dlg->testdialog = TestParseFieldDialog;
12681   dlg->change_notify = change_notify;
12682   dlg->change_userdata = change_userdata;
12683   dlg->is_search_field = is_search_field;
12684 
12685   m = HiddenGroup (p, 2, 0, NULL);
12686 
12687   choice_list = GetParseFieldDestList (is_search_field, include_dbxref);
12688   dlg->parse_field_type = ValNodeSelectionDialog (m, choice_list, TALL_SELECTION_LIST, ValNodeStringName,
12689                                 ValNodeSimpleDataFree, ValNodeStringCopy,
12690                                 ValNodeChoiceMatch, "parse destination",
12691                                 ChangeParseFieldType, dlg, FALSE);
12692 
12693   subgrp = HiddenGroup (m, 0, 0, NULL);
12694   dlg->biosrc_string_choice = BioSourceStringDialog (subgrp, FALSE, change_notify, change_userdata);
12695   Hide (dlg->biosrc_string_choice);
12696   dlg->source_qual_choice = SourceQualTypeSelectionDialog (subgrp, FALSE, change_notify, change_userdata);
12697   Hide (dlg->source_qual_choice);
12698   dlg->gene_field = GeneFieldSelectionDialog (subgrp, FALSE, change_notify, change_userdata);
12699   Hide (dlg->gene_field);
12700   g = HiddenGroup (subgrp, 2, 0, NULL);
12701   dlg->rna_subtype = RNASubtypeSelectionDialog (g, FALSE, NULL, change_notify, change_userdata);
12702   Hide (dlg->rna_subtype);
12703   dlg->rna_field = RNAFieldSelectionDialog (g, FALSE,
12704                                             change_notify,
12705                                             change_userdata);
12706   Hide (dlg->rna_field);
12707   dlg->protein_field = ProteinFieldSelectionDialog (subgrp, FALSE, change_notify, change_userdata);
12708   Hide (dlg->protein_field);
12709   g = HiddenGroup (subgrp, 2, 0, NULL);
12710   dlg->import_feature = FeatureSelectionDialog (g, TRUE, change_notify, change_userdata);
12711   Hide (dlg->import_feature);
12712   dlg->import_qual = GBQualSelectionDialog (g, FALSE, change_notify, change_userdata);
12713   Hide (dlg->import_qual);
12714   dlg->feature = FeatureSelectionDialog (subgrp, TRUE, change_notify, change_userdata);
12715   Hide (dlg->feature);
12716   if (include_dbxref)
12717   {
12718     dlg->dbxref_grp = HiddenGroup (subgrp, 2, 0, NULL);
12719     StaticPrompt (dlg->dbxref_grp, "Database:", 0, 0, programFont, 'r');
12720     dlg->dbxref_db = DialogText (dlg->dbxref_grp, "", 5, ChangeParseFieldDestText);
12721     SetObjectExtra (dlg->dbxref_db, dlg, NULL);
12722     Hide (dlg->dbxref_grp);
12723   }
12724   else
12725   {
12726     dlg->dbxref_db = NULL;
12727   }
12728 
12729   vn.choice = PARSE_FIELD_DEFLINE;
12730   vn.data.ptrvalue = NULL;
12731   vn.next = NULL;
12732   PointerToDialog (dlg->parse_field_type, &vn);
12733 
12734   dlg->feat_or_desc = HiddenGroup (p, 3, 0, NULL);
12735   RadioButton (dlg->feat_or_desc, "Descriptors and Features");
12736   RadioButton (dlg->feat_or_desc, "Descriptors Only");
12737   RadioButton (dlg->feat_or_desc, "Features Only");
12738   SetValue (dlg->feat_or_desc, 1);
12739   Hide (dlg->feat_or_desc);
12740 
12741   AlignObjects (ALIGN_CENTER, (HANDLE) m, (HANDLE) dlg->feat_or_desc, NULL);
12742 
12743   return (DialoG) p;
12744 }
12745 
ParseFieldDestDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)12746 extern DialoG ParseFieldDestDialog
12747 (GrouP                    h,
12748  Nlm_ChangeNotifyProc     change_notify,
12749  Pointer                  change_userdata)
12750 {
12751   return ParseFieldDestDialogEx (h, change_notify, change_userdata, FALSE, FALSE);
12752 }
12753 /* Search Field dialog is identical to ParseFieldDestDialog except that it allows
12754  * an additional option, Publication.
12755  */
SearchFieldDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)12756 extern DialoG SearchFieldDialog
12757 (GrouP                    h,
12758  Nlm_ChangeNotifyProc     change_notify,
12759  Pointer                  change_userdata)
12760 {
12761   return ParseFieldDestDialogEx (h, change_notify, change_userdata, TRUE, FALSE);
12762 }
12763 
12764 
12765 typedef enum
12766 {
12767  eParseFieldSrcDefLine = 1,
12768  eParseFieldSrcGenBankFlatFile,
12769  eParseFieldSrcLocalID,
12770  eParseFieldSrcTaxName,
12771  eParseFieldSrcSourceQual,
12772  eParseFieldSrcComment,
12773  eParseFieldSrcBankitComment,
12774  eParseFieldSrcStructuredComment,
12775  eParseFieldSrcTaxNameAfterNomial,
12776  eParseFieldSrcFileID
12777 } EParseFieldSrc;
12778 
12779 const Int4 MAX_PARSE_FIELD = eParseFieldSrcFileID;
12780 
12781 static CharPtr parse_src_field_list [] =
12782 {
12783   "Definition Line", "GenBank Flatfile", "Local ID", "Organism Name", "Source Qualifier", "Comment", "Bankit Comment",
12784   "Structured Comment", "Taxname after Binomial/Trinomial", "File ID"
12785 };
12786 
12787 static int num_parse_src_fields = sizeof (parse_src_field_list) / sizeof (CharPtr);
12788 
12789 typedef struct parsefieldsrc
12790 {
12791   Int4              parse_field;
12792   SourceQualDescPtr sqdp;
12793   CharPtr           comment_field;
12794 } ParseFieldSrcData, PNTR ParseFieldSrcPtr;
12795 
ParseFieldSrcFree(ParseFieldSrcPtr pfsp)12796 static ParseFieldSrcPtr ParseFieldSrcFree (ParseFieldSrcPtr pfsp)
12797 {
12798   if (pfsp != NULL) {
12799     pfsp->comment_field = MemFree (pfsp->comment_field);
12800     pfsp->sqdp = MemFree (pfsp->sqdp);
12801     pfsp = MemFree (pfsp);
12802   }
12803   return pfsp;
12804 }
12805 
12806 typedef struct parsefieldsrcdlg
12807 {
12808   DIALOG_MESSAGE_BLOCK
12809   DialoG     parse_field;
12810   PopuP      comment_field;
12811   ValNodePtr comment_field_list;
12812   DialoG     src_qual;
12813   Nlm_ChangeNotifyProc     change_notify;
12814   Pointer                  change_userdata;
12815 } ParseFieldSrcDlgData, PNTR ParseFieldSrcDlgPtr;
12816 
CleanupParseFieldSrcDialog(GraphiC g,VoidPtr data)12817 static void CleanupParseFieldSrcDialog (GraphiC g, VoidPtr data)
12818 {
12819   ParseFieldSrcDlgPtr dlg;
12820 
12821   dlg = (ParseFieldSrcDlgPtr) data;
12822   if (dlg != NULL) {
12823     dlg->comment_field_list = ValNodeFreeData(dlg->comment_field_list);
12824   }
12825   StdCleanupExtraProc (g, data);
12826 }
12827 
ResetParseFieldSourceDialog(ParseFieldSrcDlgPtr dlg)12828 static void ResetParseFieldSourceDialog (ParseFieldSrcDlgPtr dlg)
12829 {
12830   if (dlg == NULL) {
12831       return;
12832   }
12833   SendMessageToDialog (dlg->parse_field, VIB_MSG_INIT);
12834   SetValue (dlg->comment_field, 0);
12835   Hide (dlg->comment_field);
12836 }
12837 
ParseFieldSourceDialogMessage(DialoG d,Int2 mssg)12838 static void ParseFieldSourceDialogMessage (DialoG d, Int2 mssg)
12839 
12840 {
12841   ParseFieldSrcDlgPtr dlg;
12842 
12843   dlg = (ParseFieldSrcDlgPtr) GetObjectExtra (d);
12844   if (dlg != NULL) {
12845     switch (mssg) {
12846       case VIB_MSG_INIT :
12847         /* reset list */
12848         ResetParseFieldSourceDialog (dlg);
12849         break;
12850       default :
12851         break;
12852     }
12853   }
12854 }
12855 
ParseFieldChange(Pointer userdata)12856 static void ParseFieldChange (Pointer userdata)
12857 {
12858   ParseFieldSrcDlgPtr dlg;
12859   ValNodePtr          vnp;
12860 
12861   dlg = (ParseFieldSrcDlgPtr) userdata;
12862   if (dlg == NULL) return;
12863 
12864   vnp = DialogToPointer (dlg->parse_field);
12865   if (vnp == NULL || vnp->data.intvalue != eParseFieldSrcStructuredComment) {
12866     Hide (dlg->comment_field);
12867   } else {
12868     Show (dlg->comment_field);
12869   }
12870   if (vnp == NULL || vnp->data.intvalue != eParseFieldSrcSourceQual) {
12871     Hide (dlg->src_qual);
12872   } else {
12873     Show (dlg->src_qual);
12874   }
12875 
12876   if (dlg->change_notify != NULL) {
12877     (dlg->change_notify)(dlg->change_userdata);
12878   }
12879 }
12880 
FindCommentFieldPosition(CharPtr comment_field,ValNodePtr comment_list)12881 static Int4 FindCommentFieldPosition (CharPtr comment_field, ValNodePtr comment_list)
12882 {
12883   Int4       pos = 1;
12884   ValNodePtr vnp;
12885 
12886   if (StringHasNoText (comment_field) || comment_list == NULL) {
12887     return 0;
12888   }
12889 
12890   vnp = comment_list;
12891   while (vnp != NULL && StringCmp (comment_field, vnp->data.ptrvalue) != 0) {
12892     vnp = vnp->next;
12893     pos++;
12894   }
12895   if (vnp == NULL) {
12896     pos = 0;
12897   }
12898   return pos;
12899 }
12900 
DataToParseFieldSrcDialog(DialoG d,Pointer data)12901 static void DataToParseFieldSrcDialog(DialoG d, Pointer data)
12902 {
12903   ParseFieldSrcDlgPtr dlg;
12904   ParseFieldSrcPtr    pfsp;
12905   ValNode             vn;
12906 
12907   dlg = (ParseFieldSrcDlgPtr) GetObjectExtra (d);
12908   if (dlg != NULL) {
12909     pfsp = (ParseFieldSrcPtr) data;
12910     if (pfsp == NULL) {
12911       ResetParseFieldSourceDialog (dlg);
12912     } else {
12913       vn.data.intvalue = pfsp->parse_field;
12914       vn.next = NULL;
12915       vn.choice = 0;
12916       PointerToDialog (dlg->parse_field, &vn);
12917       SetValue (dlg->comment_field, FindCommentFieldPosition (pfsp->comment_field, dlg->comment_field_list));
12918       vn.data.ptrvalue = pfsp->sqdp;
12919       PointerToDialog (dlg->src_qual, &vn);
12920     }
12921   }
12922   ParseFieldChange (dlg);
12923 }
12924 
ParseFieldSrcDialogToData(DialoG d)12925 static Pointer ParseFieldSrcDialogToData(DialoG d)
12926 {
12927   ParseFieldSrcDlgPtr dlg;
12928   ParseFieldSrcPtr    pfsp;
12929   ValNodePtr          vnp;
12930   Int4                field_pos;
12931 
12932   dlg = (ParseFieldSrcDlgPtr) GetObjectExtra (d);
12933   if (dlg == NULL) {
12934     return NULL;
12935   }
12936 
12937   pfsp = (ParseFieldSrcPtr) MemNew (sizeof (ParseFieldSrcData));
12938   vnp = DialogToPointer (dlg->parse_field);
12939   if (vnp != NULL) {
12940     pfsp->parse_field = vnp->data.intvalue;
12941     vnp = ValNodeFree (vnp);
12942   }
12943   pfsp->comment_field = NULL;
12944   pfsp->sqdp = NULL;
12945   if (pfsp->parse_field == eParseFieldSrcStructuredComment) {
12946     field_pos = GetValue (dlg->comment_field);
12947     if (field_pos > 0) {
12948       vnp = dlg->comment_field_list;
12949       field_pos --;
12950       while (field_pos > 0 && vnp != NULL) {
12951         vnp = vnp->next;
12952         field_pos --;
12953       }
12954       if (vnp != NULL) {
12955         pfsp->comment_field = StringSave (vnp->data.ptrvalue);
12956       }
12957     }
12958   } else if (pfsp->parse_field == eParseFieldSrcSourceQual) {
12959     vnp = DialogToPointer (dlg->src_qual);
12960     if (vnp != NULL) {
12961       pfsp->sqdp = vnp->data.ptrvalue;
12962       vnp->data.ptrvalue = NULL;
12963       vnp = ValNodeFreeData (vnp);
12964     }
12965   }
12966 
12967   return pfsp;
12968 }
12969 
AddCommentFieldName(SeqDescrPtr sdp,Pointer userdata)12970 static void AddCommentFieldName (SeqDescrPtr sdp, Pointer userdata)
12971 {
12972   UserObjectPtr uop;
12973   ObjectIdPtr   oip;
12974   UserFieldPtr  ufp;
12975   ValNodePtr    vnp;
12976   Boolean       found;
12977   ValNodePtr PNTR comment_field_list = (ValNodePtr PNTR) userdata;
12978 
12979   if (comment_field_list == NULL
12980       || sdp->choice != Seq_descr_user
12981       || sdp->extended == 0
12982       || sdp->data.ptrvalue == NULL) {
12983     return;
12984   }
12985 
12986   uop = (UserObjectPtr) sdp->data.ptrvalue;
12987   oip = uop->type;
12988   if (oip != NULL && StringCmp (oip->str, "StructuredComment") == 0)
12989   {
12990     for (ufp = uop->data; ufp != NULL; ufp = ufp->next)
12991     {
12992       oip = ufp->label;
12993       if (oip != NULL && !StringHasNoText (oip->str))
12994       {
12995         found = FALSE;
12996         vnp = *comment_field_list;
12997         while (vnp != NULL && !found) {
12998           if (StringCmp (vnp->data.ptrvalue, oip->str) == 0) {
12999             found = TRUE;
13000           }
13001           vnp = vnp->next;
13002         }
13003         if (!found) {
13004           ValNodeAddPointer (comment_field_list, 0, StringSave (oip->str));
13005         }
13006       }
13007     }
13008   }
13009 }
13010 
13011 
TestParseFieldSource(DialoG d)13012 static ValNodePtr TestParseFieldSource (DialoG d)
13013 
13014 {
13015   ParseFieldSrcDlgPtr dlg;
13016   ValNodePtr          head = NULL, vnp, vnp2;
13017 
13018   dlg = (ParseFieldSrcDlgPtr) GetObjectExtra (d);
13019 
13020   vnp = DialogToPointer (dlg->parse_field);
13021   if (vnp == NULL)
13022   {
13023     head = AddStringToValNodeChain (head, "field choice", 1);
13024   }
13025   else if (vnp->data.intvalue == eParseFieldSrcSourceQual)
13026   {
13027     vnp2 = DialogToPointer (dlg->src_qual);
13028     if (vnp2 == NULL)
13029     {
13030       head = AddStringToValNodeChain (head, "source qual", 1);
13031     }
13032     vnp2 = ValNodeFree (vnp2);
13033   }
13034 
13035   vnp = ValNodeFree (vnp);
13036 
13037   return head;
13038 }
13039 
13040 
ParseFieldSourceDialog(GrouP h,SeqEntryPtr sep,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)13041 extern DialoG ParseFieldSourceDialog
13042 (GrouP                    h,
13043  SeqEntryPtr              sep,
13044  Nlm_ChangeNotifyProc     change_notify,
13045  Pointer                  change_userdata)
13046 {
13047   ParseFieldSrcDlgPtr dlg;
13048   GrouP               p, k;
13049   ValNodePtr          vnp;
13050 
13051   dlg = (ParseFieldSrcDlgPtr) MemNew (sizeof (ParseFieldSrcDlgData));
13052   if (dlg == NULL)
13053   {
13054     return NULL;
13055   }
13056 
13057   p = HiddenGroup (h, 2, 0, NULL);
13058 
13059   SetObjectExtra (p, dlg, CleanupParseFieldSrcDialog);
13060 
13061   dlg->dialog = (DialoG) p;
13062   dlg->todialog = DataToParseFieldSrcDialog;
13063   dlg->fromdialog = ParseFieldSrcDialogToData;
13064   dlg->dialogmessage = ParseFieldSourceDialogMessage;
13065   dlg->testdialog = TestParseFieldSource;
13066   dlg->change_notify = change_notify;
13067   dlg->change_userdata = change_userdata;
13068 
13069   dlg->parse_field = FeatureFieldSelectionDialog (p, FALSE,
13070                                                   num_parse_src_fields, parse_src_field_list,
13071                                                   ParseFieldChange, dlg);
13072 
13073   k = HiddenGroup (p, 0, 0, NULL);
13074   dlg->comment_field = PopupList (k, TRUE, NULL);
13075   dlg->src_qual = SourceQualTypeSelectionDialogEx (k, FALSE, change_notify,
13076                                                    change_userdata, 6, FALSE, FALSE);
13077   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->comment_field, (HANDLE) dlg->src_qual, NULL);
13078 
13079   /* Add to comment_field list all user fields found in SeqEntry sep */
13080   VisitDescriptorsInSep (sep, &(dlg->comment_field_list), AddCommentFieldName);
13081   for (vnp = dlg->comment_field_list; vnp != NULL; vnp = vnp->next) {
13082     PopupItem (dlg->comment_field, vnp->data.ptrvalue);
13083   }
13084 
13085   return (DialoG) p;
13086 }
13087 
13088 typedef struct sampledialog
13089 {
13090   DIALOG_MESSAGE_BLOCK
13091   DoC                doc;
13092   Int2               start_item;
13093   Int2               start_row;
13094   Int2               start_col;
13095   Int2               end_item;
13096   Int2               end_row;
13097   Int2               end_col;
13098   SetSamplePtr       ssp;
13099 } SampleDialogData, PNTR SampleDialogPtr;
13100 
TruncateStringAfterTwoLines(CharPtr str,Uint4 char_per_line)13101 static void TruncateStringAfterTwoLines (CharPtr str, Uint4 char_per_line)
13102 {
13103   CharPtr cp;
13104   Uint4    string_len;
13105 
13106   if (StringHasNoText (str))
13107   {
13108     return;
13109   }
13110 
13111   string_len = StringLen (str);
13112   if (string_len < char_per_line)
13113   {
13114     return;
13115   }
13116 
13117   cp = str + char_per_line;
13118   while (! isspace ((Int4)(*cp)) && cp > str)
13119   {
13120     cp--;
13121   }
13122   if (cp == str)
13123   {
13124     if (string_len > 2 * char_per_line)
13125     {
13126       str [2 * char_per_line] = 0;
13127     }
13128   }
13129   else
13130   {
13131     if (StringLen (cp) > char_per_line)
13132     {
13133       cp[char_per_line] = 0;
13134     }
13135   }
13136 
13137 }
13138 
13139 typedef struct exportsample
13140 {
13141   ValNodePtr   row_list;
13142   SetSamplePtr ssp;
13143 } ExportSampleData, PNTR ExportSamplePtr;
13144 
ExportSampleDialogCallback(BioseqPtr bsp,Pointer userdata)13145 static void ExportSampleDialogCallback (BioseqPtr bsp, Pointer userdata)
13146 {
13147   ExportSamplePtr   esp;
13148   SeqFeatPtr        sfp;
13149   SeqMgrFeatContext fcontext;
13150   SeqDescrPtr       sdp;
13151   SeqMgrDescContext dcontext;
13152   Char              tmp[128];
13153   CharPtr           val_str = NULL, new_val_str, tmp_val_str;
13154   ValNodePtr        sample_field, sample_field_next;
13155   ValNodePtr        new_row = NULL;
13156   SeqIdPtr          sip;
13157 
13158   if (bsp == NULL || userdata == NULL || ! ISA_na (bsp->mol))
13159   {
13160     return;
13161   }
13162 
13163   esp = (ExportSamplePtr) userdata;
13164 
13165   sip = SeqIdFindBest (bsp->id, 0);
13166   SeqIdWrite (sip, tmp, PRINTID_REPORT, sizeof (tmp));
13167 
13168   ValNodeAddPointer (&new_row, 0, StringSave (tmp));
13169 
13170   for (sample_field = esp->ssp->field_list;
13171        sample_field != NULL;
13172        sample_field = sample_field->next)
13173   {
13174     sample_field_next = sample_field->next;
13175     sample_field->next = NULL;
13176     val_str = NULL;
13177 
13178     if (esp->ssp->descrstring_func != NULL)
13179     {
13180       sdp = SeqMgrGetNextDescriptor (bsp, NULL, 0, &dcontext);
13181       while (sdp != NULL)
13182       {
13183         new_val_str = (esp->ssp->descrstring_func) (sdp, sample_field, NULL);
13184         tmp_val_str = StringAppend (val_str, new_val_str);
13185         val_str = MemFree (val_str);
13186         new_val_str = MemFree (new_val_str);
13187         val_str = tmp_val_str;
13188         tmp_val_str = NULL;
13189         sdp = SeqMgrGetNextDescriptor (bsp, sdp, 0, &dcontext);
13190       }
13191     }
13192     if (esp->ssp->fieldstring_func != NULL)
13193     {
13194       sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
13195       while (sfp != NULL)
13196       {
13197         new_val_str = (esp->ssp->fieldstring_func)(sfp, sample_field, NULL);
13198         tmp_val_str = StringAppend (val_str, new_val_str);
13199         val_str = MemFree (val_str);
13200         new_val_str = MemFree (new_val_str);
13201         val_str = tmp_val_str;
13202         tmp_val_str = NULL;
13203         sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &fcontext);
13204       }
13205     }
13206     ValNodeAddPointer (&new_row, 0, val_str);
13207     sample_field->next = sample_field_next;
13208   }
13209   ValNodeAddPointer (&(esp->row_list), 0, new_row);
13210 }
13211 
GetTableDataColumnWidths(ValNodePtr row_list)13212 static void GetTableDataColumnWidths (ValNodePtr row_list)
13213 {
13214   ValNodePtr row_vnp, col_vnp, header_vnp;
13215 
13216   if (row_list == NULL || row_list->next == NULL)
13217   {
13218     return;
13219   }
13220 
13221   /* only collect widths for data columns, not header, so we can detect empty rows */
13222   for (row_vnp = row_list->next; row_vnp != NULL; row_vnp = row_vnp->next)
13223   {
13224     for (col_vnp = row_vnp->data.ptrvalue, header_vnp = row_list->data.ptrvalue;
13225          col_vnp != NULL && header_vnp != NULL;
13226          col_vnp = col_vnp->next, header_vnp = header_vnp->next)
13227     {
13228       if (!StringHasNoText (col_vnp->data.ptrvalue))
13229       {
13230         header_vnp->choice = MAX (header_vnp->choice, StringLen (col_vnp->data.ptrvalue));
13231       }
13232     }
13233   }
13234 }
13235 
RemoveTableEmptyColumns(ValNodePtr row_list)13236 static void RemoveTableEmptyColumns (ValNodePtr row_list)
13237 {
13238   ValNodePtr row_vnp, col_vnp, header_vnp, col_vnp_next, col_vnp_prev;
13239   ValNodePtr column_list;
13240 
13241   if (row_list == NULL)
13242   {
13243     return;
13244   }
13245 
13246   /* remove data columns */
13247   for (row_vnp = row_list->next; row_vnp != NULL; row_vnp = row_vnp->next)
13248   {
13249     column_list = row_vnp->data.ptrvalue;
13250     col_vnp_prev = NULL;
13251     for (col_vnp = column_list, header_vnp = row_list->data.ptrvalue;
13252          col_vnp != NULL && header_vnp != NULL;
13253          col_vnp = col_vnp_next, header_vnp = header_vnp->next)
13254     {
13255       col_vnp_next = col_vnp->next;
13256       if (header_vnp->choice == 0)
13257       {
13258         if (col_vnp_prev == NULL)
13259         {
13260           row_vnp->data.ptrvalue = col_vnp_next;
13261           column_list = row_vnp->data.ptrvalue;
13262         }
13263         else
13264         {
13265           col_vnp_prev->next = col_vnp_next;
13266         }
13267         col_vnp->next = NULL;
13268         ValNodeFreeData (col_vnp);
13269       }
13270       else
13271       {
13272         col_vnp_prev = col_vnp;
13273       }
13274     }
13275   }
13276 
13277   /* remove headers for empty columns */
13278   col_vnp_prev = NULL;
13279   for (col_vnp = row_list->data.ptrvalue;
13280        col_vnp != NULL;
13281        col_vnp = col_vnp_next)
13282   {
13283     col_vnp_next = col_vnp->next;
13284     if (col_vnp->choice == 0)
13285     {
13286       if (col_vnp_prev == NULL)
13287       {
13288         row_list->data.ptrvalue = col_vnp_next;
13289       }
13290       else
13291       {
13292         col_vnp_prev->next = col_vnp_next;
13293       }
13294       col_vnp->next = NULL;
13295       ValNodeFreeData (col_vnp);
13296     }
13297     else
13298     {
13299       col_vnp_prev = col_vnp;
13300     }
13301   }
13302 }
13303 
ExportSampleDialogData(SampleDialogPtr dlg)13304 static void ExportSampleDialogData (SampleDialogPtr dlg)
13305 {
13306   Char             path [PATH_MAX];
13307   ExportSampleData esd;
13308   SeqEntryPtr      sep;
13309   CharPtr          sample_label;
13310   ValNodePtr       sample_field;
13311   FILE             *fp;
13312   ValNodePtr       new_row = NULL;
13313 
13314   if (dlg == NULL || dlg->ssp == NULL || dlg->ssp->label_vn_proc == NULL)
13315   {
13316     return;
13317   }
13318 
13319   sep = GetTopSeqEntryForEntityID (dlg->ssp->entityID);
13320   if (sep == NULL)
13321   {
13322     return;
13323   }
13324   if (! GetOutputFileName (path, sizeof (path), NULL)) return;
13325   fp = FileOpen (path, "w");
13326   if (fp == NULL)
13327   {
13328     Message (MSG_ERROR, "Unable to open %s", path);
13329     return;
13330   }
13331   WatchCursor ();
13332   Update ();
13333   esd.ssp = dlg->ssp;
13334   ValNodeAddPointer (&new_row, 0, StringSave ("Sequence"));
13335 
13336   for (sample_field = dlg->ssp->field_list;
13337        sample_field != NULL;
13338        sample_field = sample_field->next)
13339   {
13340     sample_label = (dlg->ssp->label_vn_proc) (sample_field);
13341     ValNodeAddPointer (&new_row, 0, StringSave (sample_label));
13342   }
13343   esd.row_list = NULL;
13344   ValNodeAddPointer (&(esd.row_list), 0, new_row);
13345 
13346   VisitBioseqsInSep (sep, &esd, ExportSampleDialogCallback);
13347 
13348   GetTableDataColumnWidths (esd.row_list);
13349   RemoveTableEmptyColumns (esd.row_list);
13350 
13351   PrintTableDisplayRowListToFile (esd.row_list, fp);
13352   esd.row_list = FreeTableDisplayRowList (esd.row_list);
13353 
13354   FileClose (fp);
13355   ArrowCursor();
13356   Update();
13357 }
13358 
RefreshSampleDialog(SampleDialogPtr dlg)13359 static void RefreshSampleDialog (SampleDialogPtr dlg)
13360 {
13361   SeqEntryPtr     sep;
13362   RecT            r;
13363   ParData         ParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
13364   ColData         ColFmt[] =
13365   {
13366     {0, 0, 80, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, FALSE},
13367     {0, 0, 80, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, FALSE},
13368     {0, 0, 80, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, TRUE}
13369   };
13370   GetSampleData   gsd;
13371   CharPtr         new_line;
13372   ValNodePtr      sample_field, sample_field_next;
13373   CharPtr         sample_label = NULL;
13374   Int4            max_char_per_line;
13375 
13376   if (dlg == NULL)
13377   {
13378     return;
13379   }
13380   Reset (dlg->doc);
13381   if (dlg->ssp == NULL || dlg->ssp->field_list == NULL
13382       || (dlg->ssp->fieldstring_func == NULL && dlg->ssp->descrstring_func == NULL))
13383   {
13384     return;
13385   }
13386 
13387   sep = GetTopSeqEntryForEntityID (dlg->ssp->entityID);
13388   if (sep == NULL)
13389   {
13390     return;
13391   }
13392   gsd.sample_text = NULL;
13393   gsd.fieldstring_func = dlg->ssp->fieldstring_func;
13394   gsd.descrstring_func = dlg->ssp->descrstring_func;
13395 
13396   ObjectRect (dlg->doc, &r);
13397   InsetRect (&r, 4, 4);
13398   ColFmt[0].pixWidth = (r.right - r.left) / 3;
13399   ColFmt[1].pixWidth = (r.right - r.left) / 4;
13400   ColFmt[2].pixWidth = (r.right - r.left)  - ColFmt[0].pixWidth - ColFmt[1].pixWidth;
13401 
13402   SelectFont (programFont);
13403   max_char_per_line = ColFmt[2].pixWidth / CharWidth ('0');
13404 
13405 
13406   for (sample_field = dlg->ssp->field_list; sample_field != NULL; sample_field = sample_field->next)
13407   {
13408     sample_field_next = sample_field->next;
13409     sample_field->next = NULL;
13410     gsd.requested_field = sample_field;
13411     gsd.num_found = 0;
13412     gsd.all_same = TRUE;
13413     gsd.feat_dest_list = NULL;
13414     gsd.descr_dest_list = NULL;
13415 
13416     OperateOnSeqEntryConstrainedObjects (sep, dlg->ssp->fsp, GetSampleFeatureCallback,
13417                                          GetSampleDescriptorCallback,
13418                                          0, 0, 0, &gsd);
13419     if (gsd.num_found > 0)
13420     {
13421       sample_label = (dlg->ssp->label_vn_proc) (sample_field);
13422       new_line = (CharPtr) MemNew (
13423            (StringLen (sample_label)
13424             + StringLen (gsd.sample_text) + 20)
13425             * sizeof (Char));
13426       if (new_line != NULL)
13427       {
13428         if (gsd.all_same)
13429         {
13430           sprintf (new_line, "%s\t(%d same)\t", sample_label, gsd.num_found);
13431         }
13432         else
13433         {
13434           sprintf (new_line, "%s\t(%d mixed)\t", sample_label, gsd.num_found);
13435         }
13436         if (!StringHasNoText (gsd.sample_text))
13437         {
13438           TruncateStringAfterTwoLines (gsd.sample_text, max_char_per_line);
13439           StringCat (new_line, gsd.sample_text);
13440         }
13441         StringCat (new_line, "\n");
13442           AppendText (dlg->doc, new_line, &ParFmt, ColFmt, programFont);
13443           MemFree (new_line);
13444       }
13445       sample_label = MemFree (sample_label);
13446     }
13447     gsd.sample_text = MemFree (gsd.sample_text);
13448     sample_field->next = sample_field_next;
13449   }
13450   InvalDocument (dlg->doc);
13451 }
13452 
PopulateSampleDialog(DialoG d,Pointer userdata)13453 static void PopulateSampleDialog (DialoG d, Pointer userdata)
13454 {
13455   SampleDialogPtr dlg;
13456   SetSamplePtr    ssp;
13457 
13458   dlg = (SampleDialogPtr) GetObjectExtra (d);
13459   if (dlg == NULL || userdata == NULL)
13460   {
13461     return;
13462   }
13463   ssp = (SetSamplePtr) userdata;
13464   dlg->ssp = SetSampleFree (dlg->ssp);
13465   dlg->ssp = SetSampleCopy (ssp);
13466 }
13467 
13468 static void
GetSampleDialogStartAndEnd(SampleDialogPtr dlg,Int2Ptr start_item,Int2Ptr start_row,Int2Ptr start_col,Int2Ptr end_item,Int2Ptr end_row,Int2Ptr end_col)13469 GetSampleDialogStartAndEnd
13470 (SampleDialogPtr dlg,
13471  Int2Ptr         start_item,
13472  Int2Ptr         start_row,
13473  Int2Ptr         start_col,
13474  Int2Ptr         end_item,
13475  Int2Ptr         end_row,
13476  Int2Ptr         end_col)
13477 {
13478   if (dlg == NULL || start_item == NULL || start_row == NULL
13479       || start_col == NULL || end_item == NULL
13480       || end_row == NULL || end_col == NULL)
13481   {
13482     return;
13483   }
13484 
13485   if (dlg->start_item < 0)
13486   {
13487     *start_item = -1;
13488     *start_row = -1;
13489     *start_col = -1;
13490     *end_item = -1;
13491     *end_row = -1;
13492     *end_col = -1;
13493   }
13494   else if (dlg->end_item < 0)
13495   {
13496     *start_item = dlg->start_item;
13497     *start_row = dlg->start_row;
13498     *start_col = dlg->start_col;
13499     *end_item = *start_item;
13500     *end_row = *start_row;
13501     *end_col = *start_col;
13502   }
13503   else if (dlg->start_item <= dlg->end_item)
13504   {
13505     *start_item = dlg->start_item;
13506     *end_item = dlg->end_item;
13507     if (dlg->start_row <= dlg->end_row)
13508     {
13509       *start_row = dlg->start_row;
13510       *end_row = dlg->end_row;
13511       if (dlg->start_col <= dlg->end_col)
13512       {
13513         *start_col = dlg->start_col;
13514         *end_col = dlg->end_col;
13515       }
13516       else
13517       {
13518         *start_col = dlg->end_col;
13519         *end_col = dlg->start_col;
13520       }
13521     }
13522     else
13523     {
13524       *start_row = dlg->end_row;
13525       *start_col = dlg->end_col;
13526       *end_row = dlg->start_row;
13527       *end_col = dlg->start_col;
13528     }
13529   }
13530   else
13531   {
13532     *start_item = dlg->end_item;
13533     *start_row = dlg->end_row;
13534     *start_col = dlg->end_col;
13535     *end_item = dlg->start_item;
13536     *end_row = dlg->start_row;
13537     *end_col = dlg->start_col;
13538   }
13539 
13540 }
13541 
SampleDialogCopy(SampleDialogPtr dlg)13542 static void SampleDialogCopy (SampleDialogPtr dlg)
13543 {
13544   Int2       start_row = 0, end_row = 0, tmp_row, first_row, last_row;
13545   Int2       start_col = 0, end_col = 0, first_col, last_col;
13546   Int2       start_item = 0, end_item = 0, tmp_item;
13547   CharPtr    str;
13548   ValNodePtr strings = NULL;
13549   Int2       num_rows, num_cols;
13550 
13551   if (dlg->start_row < 0)
13552   {
13553     return;
13554   }
13555 
13556   GetSampleDialogStartAndEnd (dlg, &start_item, &start_row, &start_col,
13557                               &end_item, &end_row, &end_col);
13558 
13559   first_row = start_row;
13560   first_col = start_col;
13561   for (tmp_item = start_item; tmp_item <= end_item; tmp_item++)
13562   {
13563     GetItemParams (dlg->doc, tmp_item, NULL, &num_rows, &num_cols, NULL, NULL);
13564     if (tmp_item == end_item)
13565     {
13566       last_row = end_row;
13567     }
13568     else
13569     {
13570       last_row = num_rows;
13571     }
13572     for (tmp_row = first_row; tmp_row <= last_row; tmp_row++)
13573     {
13574       if (tmp_row == last_row && tmp_item == end_item)
13575       {
13576         last_col = end_col;
13577       }
13578       else
13579       {
13580         last_col = num_cols;
13581       }
13582       str = GetDocText (dlg->doc, tmp_item, tmp_row, 3);
13583       ValNodeAddPointer (&strings, 0, str);
13584     }
13585     first_row = 1;
13586   }
13587   str = MergeValNodeStrings (strings, FALSE);
13588 
13589   StringToClipboard (str);
13590   MemFree (str);
13591   strings = ValNodeFreeData (strings);
13592 }
13593 
InvalidateSampleDialogRows(DoC d,Int2 start_item,Int2 end_item)13594 static void InvalidateSampleDialogRows (DoC d, Int2 start_item, Int2 end_item)
13595 {
13596   Int2 num_rows;
13597   if (d == NULL)
13598   {
13599     return;
13600   }
13601   if (start_item < 1)
13602   {
13603     start_item = 1;
13604   }
13605   if (end_item < 1)
13606   {
13607     end_item = start_item;
13608   }
13609   while (start_item <= end_item)
13610   {
13611     GetItemParams (d, start_item, NULL, &num_rows, NULL, NULL, NULL);
13612     InvalDocRows (d, start_item, 1, num_rows);
13613     start_item++;
13614   }
13615 }
13616 
SampleDialogOnClick(DoC d,PoinT pt)13617 static void SampleDialogOnClick (DoC d, PoinT pt)
13618 {
13619   SampleDialogPtr   dlg;
13620   Int2              pos_item, pos_row, pos_col;
13621   Int2              start_item = 0, start_row, start_col;
13622   Int2              end_item = -1, end_row, end_col;
13623 
13624   dlg = (SampleDialogPtr) GetObjectExtra (d);
13625   if (dlg == NULL) return;
13626 
13627   MapDocPoint (d, pt, &(pos_item), &(pos_row), &(pos_col), NULL);
13628   if (dlg->start_item == pos_item
13629       && dlg->start_row == pos_row
13630       && dlg->start_col == pos_col)
13631   {
13632     dlg->start_row = -1;
13633     dlg->start_col = -1;
13634 
13635   }
13636   else
13637   {
13638     if (dlg->start_item > -1)
13639     {
13640       GetSampleDialogStartAndEnd (dlg, &start_item, &start_row, &start_col,
13641                                   &end_item, &end_row, &end_col);
13642     }
13643     dlg->start_item = pos_item;
13644     dlg->start_row = pos_row;
13645     dlg->start_col = pos_col;
13646   }
13647   dlg->end_item = -1;
13648   dlg->end_row = -1;
13649   dlg->end_col = -1;
13650   InvalidateSampleDialogRows (d, start_item, end_item);
13651   InvalidateSampleDialogRows (d, pos_item, pos_item);
13652 }
13653 
SampleDialogOnDrag(DoC d,PoinT pt)13654 static void SampleDialogOnDrag (DoC d, PoinT pt)
13655 {
13656   SampleDialogPtr   dlg;
13657 
13658   dlg = (SampleDialogPtr) GetObjectExtra (d);
13659   if (dlg == NULL) return;
13660 
13661   MapDocPoint (d, pt, &(dlg->end_item), &(dlg->end_row), &(dlg->end_col), NULL);
13662   InvalDocument (d);
13663 }
13664 
SampleDialogOnRelease(DoC d,PoinT pt)13665 static void SampleDialogOnRelease (DoC d, PoinT pt)
13666 {
13667   SampleDialogPtr   dlg;
13668 
13669   dlg = (SampleDialogPtr) GetObjectExtra (d);
13670   if (dlg == NULL) return;
13671 
13672   MapDocPoint (d, pt, &(dlg->end_item), &(dlg->end_row), &(dlg->end_col), NULL);
13673   InvalDocument (d);
13674 }
13675 
SampleDialogInvert(DoC d,Int2 item,Int2 row,Int2 col)13676 static Boolean SampleDialogInvert (DoC d, Int2 item, Int2 row, Int2 col)
13677 {
13678   SampleDialogPtr   dlg;
13679   Int2              start_item = 0, start_row = 0, start_col = 0;
13680   Int2              end_item = 0, end_row = 0, end_col = 0;
13681   Boolean           rval = FALSE;
13682 
13683   dlg = (SampleDialogPtr) GetObjectExtra (d);
13684   if (dlg == NULL) return FALSE;
13685 
13686   if (dlg->start_row < 0)
13687   {
13688     return FALSE;
13689   }
13690 
13691   if (dlg->end_item == -1)
13692   {
13693     if(dlg->start_item == item
13694        && dlg->start_row == row
13695        && dlg->start_col == col)
13696     {
13697       return TRUE;
13698     }
13699     else
13700     {
13701       return FALSE;
13702     }
13703   }
13704   GetSampleDialogStartAndEnd (dlg, &start_item, &start_row, &start_col,
13705                               &end_item, &end_row, &end_col);
13706   if (start_item <= item && end_item >= item)
13707   {
13708     rval = TRUE;
13709     if (start_item == item)
13710     {
13711       if (start_row == row)
13712       {
13713         if (start_col > col)
13714         {
13715           rval = FALSE;
13716         }
13717       }
13718       else if (start_row > row)
13719       {
13720         rval = FALSE;
13721       }
13722     }
13723 
13724     if (end_item == item)
13725     {
13726       if (end_row == row)
13727       {
13728         if (end_col < col)
13729         {
13730           rval = FALSE;
13731         }
13732       }
13733       else if (end_row < row)
13734       {
13735         rval = FALSE;
13736       }
13737     }
13738   }
13739   if (col == 3)
13740   {
13741     return rval;
13742   }
13743   else
13744   {
13745     return FALSE;
13746   }
13747 }
13748 
SampleDialogOnKey(SlatE s,Char ch)13749 static void SampleDialogOnKey (SlatE s, Char ch)
13750 {
13751   DoC             d;
13752   SampleDialogPtr dlg;
13753 
13754   d = (DoC) s;
13755   Select (d);
13756   dlg = (SampleDialogPtr) GetObjectExtra (d);
13757   if (dlg == NULL) return;
13758   CaptureSlateFocus ((SlatE) s);
13759 
13760 #ifdef WIN_MSWIN
13761   if (ch == 3)
13762   {
13763     SampleDialogCopy (dlg);
13764   }
13765 #else
13766   if (ctrlKey)
13767   {
13768     if (ch == 'c')
13769     {
13770       SampleDialogCopy (dlg);
13771     }
13772   }
13773 #endif
13774 }
13775 
SampleDialogMessage(DialoG d,Int2 mssg)13776 static void SampleDialogMessage (DialoG d, Int2 mssg)
13777 
13778 {
13779   SampleDialogPtr dlg;
13780 
13781   dlg = (SampleDialogPtr) GetObjectExtra (d);
13782   if (dlg != NULL) {
13783     switch (mssg) {
13784       case VIB_MSG_INIT :
13785         /* reset list */
13786         RefreshSampleDialog (dlg);
13787         break;
13788       default :
13789         break;
13790     }
13791   }
13792 }
13793 
CleanupSampleDialog(GraphiC g,VoidPtr data)13794 static void CleanupSampleDialog (GraphiC g, VoidPtr data)
13795 {
13796   SampleDialogPtr dlg;
13797 
13798   dlg = (SampleDialogPtr) data;
13799   if (dlg != NULL) {
13800     dlg->ssp = SetSampleFree (dlg->ssp);
13801   }
13802   StdCleanupExtraProc (g, data);
13803 }
13804 
RefreshSampleBtn(ButtoN b)13805 static void RefreshSampleBtn (ButtoN b)
13806 {
13807   SampleDialogPtr dlg;
13808 
13809   dlg = (SampleDialogPtr) GetObjectExtra (b);
13810   RefreshSampleDialog (dlg);
13811 }
13812 
ExportSampleBtn(ButtoN b)13813 static void ExportSampleBtn (ButtoN b)
13814 {
13815   SampleDialogPtr dlg;
13816 
13817   dlg = (SampleDialogPtr) GetObjectExtra (b);
13818   ExportSampleDialogData (dlg);
13819 }
13820 
SampleDialog(GrouP h)13821 extern DialoG SampleDialog (GrouP h)
13822 {
13823   SampleDialogPtr dlg;
13824   GrouP           p, g;
13825   ButtoN          b;
13826 
13827   dlg = (SampleDialogPtr) MemNew (sizeof (SampleDialogData));
13828   if (dlg == NULL)
13829   {
13830     return NULL;
13831   }
13832 
13833   p = HiddenGroup (h, -1, 0, NULL);
13834 
13835   SetObjectExtra (p, dlg, CleanupSampleDialog);
13836 
13837   dlg->dialog = (DialoG) p;
13838   dlg->todialog = PopulateSampleDialog;
13839   dlg->fromdialog = NULL;
13840   dlg->dialogmessage = SampleDialogMessage;
13841   dlg->testdialog = NULL;
13842 
13843   dlg->doc = DocumentPanel (p, stdCharWidth * 27, stdLineHeight * 8);
13844   SetObjectExtra (dlg->doc, dlg, NULL);
13845   SetDocProcs (dlg->doc, SampleDialogOnClick, SampleDialogOnDrag, SampleDialogOnRelease, NULL);
13846   SetDocShade (dlg->doc, NULL, NULL, SampleDialogInvert, NULL);
13847   SetDocAutoAdjust (dlg->doc, TRUE);
13848   SetSlateChar ((SlatE) dlg->doc, SampleDialogOnKey);
13849 
13850   g = HiddenGroup (p, 2, 0, NULL);
13851   b = PushButton (g, "Refresh Qualifiers", RefreshSampleBtn);
13852   SetObjectExtra (b, dlg, NULL);
13853   b = PushButton (g, "Export Qualifiers", ExportSampleBtn);
13854   SetObjectExtra (b, dlg, NULL);
13855 
13856   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->doc, (HANDLE) g, NULL);
13857 
13858   return (DialoG) p;
13859 }
13860 
13861 typedef struct featurefieldchoicedialog
13862 {
13863   DIALOG_MESSAGE_BLOCK
13864   DialoG first_choice;
13865   DialoG second_choice;
13866   DialoG third_choice;
13867   ButtoN remove_first;
13868   ButtoN remove_second;
13869   ButtoN remove_third;
13870 
13871   Nlm_ChangeNotifyProc     change_notify;
13872   Pointer                  change_userdata;
13873 } FeatureFieldChoiceDialogData, PNTR FeatureFieldChoiceDialogPtr;
13874 
FeatureFieldChoiceChange(Pointer data)13875 static void FeatureFieldChoiceChange (Pointer data)
13876 {
13877   FeatureFieldChoiceDialogPtr dlg;
13878   ValNodePtr                  vnp;
13879 
13880   dlg = (FeatureFieldChoiceDialogPtr) data;
13881   if (dlg == NULL)
13882   {
13883     return;
13884   }
13885 
13886   Disable (dlg->remove_first);
13887   Disable (dlg->remove_second);
13888   Disable (dlg->remove_third);
13889 
13890   Disable (dlg->second_choice);
13891   Disable (dlg->third_choice);
13892 
13893   vnp = DialogToPointer (dlg->first_choice);
13894   if (vnp != NULL)
13895   {
13896     ValNodeFree (vnp);
13897     Enable (dlg->second_choice);
13898     Enable (dlg->remove_first);
13899     vnp = DialogToPointer (dlg->second_choice);
13900     if (vnp != NULL)
13901     {
13902       ValNodeFree (vnp);
13903       Enable (dlg->third_choice);
13904       Enable (dlg->remove_second);
13905       vnp = DialogToPointer (dlg->third_choice);
13906       if (vnp != NULL)
13907       {
13908         ValNodeFree (vnp);
13909         Enable (dlg->remove_third);
13910       }
13911     }
13912   }
13913   if (dlg->change_notify != NULL)
13914   {
13915     (dlg->change_notify)(dlg->change_userdata);
13916   }
13917 }
13918 
ResetFeatureFieldChoiceDialog(FeatureFieldChoiceDialogPtr dlg)13919 static void ResetFeatureFieldChoiceDialog (FeatureFieldChoiceDialogPtr dlg)
13920 {
13921   if (dlg == NULL)
13922   {
13923     return;
13924   }
13925   PointerToDialog (dlg->first_choice, NULL);
13926   PointerToDialog (dlg->second_choice, NULL);
13927   PointerToDialog (dlg->third_choice, NULL);
13928   if (dlg->remove_first != NULL)
13929   {
13930     SetStatus (dlg->remove_first, FALSE);
13931   }
13932   if (dlg->remove_second != NULL)
13933   {
13934     SetStatus (dlg->remove_second, FALSE);
13935   }
13936   if (dlg->remove_third != NULL)
13937   {
13938     SetStatus (dlg->remove_third, FALSE);
13939   }
13940   FeatureFieldChoiceChange (dlg);
13941 }
13942 
FeatureFieldChoiceToDialog(DialoG d,Pointer data)13943 static void FeatureFieldChoiceToDialog (DialoG d, Pointer data)
13944 {
13945   FeatureFieldChoiceDialogPtr dlg;
13946   ValNodePtr                  feature_field;
13947 
13948   dlg = (FeatureFieldChoiceDialogPtr) GetObjectExtra (d);
13949   if (dlg == NULL)
13950   {
13951     return;
13952   }
13953 
13954   ResetFeatureFieldChoiceDialog (dlg);
13955   feature_field = (ValNodePtr) data;
13956   if (feature_field != NULL)
13957   {
13958     PointerToDialog (dlg->first_choice, feature_field);
13959     if (feature_field->choice != 0 && dlg->remove_first != NULL)
13960     {
13961       SetStatus (dlg->remove_first, TRUE);
13962     }
13963     feature_field = feature_field->next;
13964     if (feature_field != NULL)
13965     {
13966       PointerToDialog (dlg->second_choice, feature_field);
13967       if (feature_field->choice != 0 && dlg->remove_second != NULL)
13968       {
13969         SetStatus (dlg->remove_second, TRUE);
13970       }
13971       feature_field = feature_field->next;
13972       if (feature_field != NULL)
13973       {
13974         if (feature_field->choice != 0 && dlg->remove_third != NULL)
13975         {
13976           SetStatus (dlg->remove_third, TRUE);
13977         }
13978         PointerToDialog (dlg->third_choice, feature_field);
13979       }
13980     }
13981   }
13982   FeatureFieldChoiceChange (dlg);
13983 }
13984 
DialogToFeatureFieldChoice(DialoG d)13985 static Pointer DialogToFeatureFieldChoice (DialoG d)
13986 {
13987   FeatureFieldChoiceDialogPtr dlg;
13988   ValNodePtr                  choice_list = NULL;
13989   ValNodePtr                  feature_field, vnp_prev;
13990 
13991   dlg = (FeatureFieldChoiceDialogPtr) GetObjectExtra (d);
13992   if (dlg == NULL)
13993   {
13994     return NULL;
13995   }
13996 
13997   feature_field = DialogToPointer (dlg->first_choice);
13998   if (feature_field != NULL)
13999   {
14000     if (dlg->remove_first != NULL && GetStatus (dlg->remove_first))
14001     {
14002       feature_field->choice = 1;
14003     }
14004     choice_list = feature_field;
14005 
14006     feature_field = DialogToPointer (dlg->second_choice);
14007     if (feature_field != NULL)
14008     {
14009       if (dlg->remove_second != NULL && GetStatus (dlg->remove_second))
14010       {
14011         feature_field->choice = 1;
14012       }
14013       choice_list->next = feature_field;
14014       vnp_prev = feature_field;
14015 
14016       feature_field = DialogToPointer (dlg->third_choice);
14017       if (feature_field != NULL)
14018       {
14019         if (dlg->remove_third != NULL && GetStatus (dlg->remove_third))
14020         {
14021           feature_field->choice = 1;
14022         }
14023         vnp_prev->next = feature_field;
14024       }
14025       else
14026       {
14027         ValNodeFree (feature_field);
14028       }
14029     }
14030     else
14031     {
14032       ValNodeFree (feature_field);
14033     }
14034   }
14035   else
14036   {
14037     ValNodeFree (feature_field);
14038   }
14039   return choice_list;
14040 }
14041 
FeatureFieldChoiceMessage(DialoG d,Int2 mssg)14042 static void FeatureFieldChoiceMessage (DialoG d, Int2 mssg)
14043 
14044 {
14045   FeatureFieldChoiceDialogPtr  dlg;
14046 
14047   dlg = (FeatureFieldChoiceDialogPtr) GetObjectExtra (d);
14048   if (dlg != NULL) {
14049     switch (mssg) {
14050       case VIB_MSG_INIT :
14051         /* reset list */
14052         ResetFeatureFieldChoiceDialog (dlg);
14053         break;
14054       case VIB_MSG_ENTER :
14055         Select (dlg->first_choice);
14056         break;
14057       default :
14058         break;
14059     }
14060   }
14061 }
14062 
TestFeatureFieldChoice(DialoG d)14063 static ValNodePtr TestFeatureFieldChoice (DialoG d)
14064 
14065 {
14066   FeatureFieldChoiceDialogPtr dlg;
14067   ValNodePtr                  head = NULL;
14068   ValNodePtr                  vnp;
14069 
14070   dlg = (FeatureFieldChoiceDialogPtr) GetObjectExtra (d);
14071   vnp = DialogToPointer (d);
14072   if (vnp == NULL)
14073   {
14074     head = AddStringToValNodeChain (head, "feature field choice", 1);
14075   }
14076   else
14077   {
14078     ValNodeFree (vnp);
14079   }
14080   return head;
14081 }
14082 
FeatureFieldChoiceDialog(GrouP h,FeatureFieldSelectionProc make_fieldlist_dlg,Boolean offer_to_remove,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)14083 extern DialoG FeatureFieldChoiceDialog
14084 (GrouP h,
14085  FeatureFieldSelectionProc make_fieldlist_dlg,
14086  Boolean                   offer_to_remove,
14087  Nlm_ChangeNotifyProc      change_notify,
14088  Pointer                   change_userdata)
14089 {
14090   FeatureFieldChoiceDialogPtr  dlg;
14091   GrouP                     p, g;
14092 
14093   if (make_fieldlist_dlg == NULL)
14094   {
14095     return NULL;
14096   }
14097 
14098   dlg = (FeatureFieldChoiceDialogPtr) MemNew (sizeof (FeatureFieldChoiceDialogData));
14099   if (dlg == NULL)
14100   {
14101     return NULL;
14102   }
14103 
14104   p = HiddenGroup (h, 0, 6, NULL);
14105   SetObjectExtra (p, dlg, StdCleanupExtraProc);
14106 
14107   dlg->dialog = (DialoG) p;
14108   dlg->todialog = FeatureFieldChoiceToDialog;
14109   dlg->fromdialog = DialogToFeatureFieldChoice;
14110   dlg->dialogmessage = FeatureFieldChoiceMessage;
14111   dlg->testdialog = TestFeatureFieldChoice;
14112   dlg->change_notify = change_notify;
14113   dlg->change_userdata = change_userdata;
14114 
14115   g = HiddenGroup (p, 3, 0, NULL);
14116   StaticPrompt (g, "1st Choice", 0, 0, programFont, 'c');
14117   dlg->first_choice = (make_fieldlist_dlg) (g, TRUE, FeatureFieldChoiceChange, dlg);
14118   if (offer_to_remove)
14119   {
14120     dlg->remove_first = CheckBox (g, "Remove if used", NULL);
14121     Disable (dlg->remove_first);
14122   }
14123   else
14124   {
14125     dlg->remove_first = NULL;
14126   }
14127 
14128   g = HiddenGroup (p, 3, 0, NULL);
14129   StaticPrompt (g, "2nd Choice", 0, 0, programFont, 'c');
14130   dlg->second_choice = (make_fieldlist_dlg) (g, TRUE, FeatureFieldChoiceChange, dlg);
14131   if (offer_to_remove)
14132   {
14133     dlg->remove_second = CheckBox (g, "Remove if used", NULL);
14134     Disable (dlg->remove_second);
14135   }
14136   else
14137   {
14138     dlg->remove_second = NULL;
14139   }
14140   Disable (dlg->second_choice);
14141 
14142   g = HiddenGroup (p, 3, 0, NULL);
14143   StaticPrompt (g, "3rd Choice", 0, 0, programFont, 'c');
14144   dlg->third_choice = (make_fieldlist_dlg) (g, TRUE, FeatureFieldChoiceChange, dlg);
14145   if (offer_to_remove)
14146   {
14147     dlg->remove_third = CheckBox (g, "Remove if used", NULL);
14148     Disable (dlg->remove_third);
14149   }
14150   else
14151   {
14152     dlg->remove_third = NULL;
14153   }
14154   Disable (dlg->third_choice);
14155 
14156   return (DialoG) p;
14157 }
14158 
14159 
14160 typedef ValNodePtr (*AdjustConvertFeatureListFunc) PROTO ((ValNodePtr, Pointer, BaseFormPtr, BoolPtr cancel));
14161 typedef Pointer (*CollectConvertFeatureOptionsFunc) PROTO ((ValNodePtr, BaseFormPtr, BoolPtr cancel));
14162 typedef Pointer (*FreeConvertFeatureOptionsFunc) PROTO ((Pointer));
14163 typedef Boolean (*ConvertFeatureTypeFunc) PROTO ((SeqFeatPtr, Uint2, Pointer));
14164 typedef void (*ConversionCleanupFunc) PROTO ((Uint2, Pointer));
14165 
14166 typedef struct convertfeatureprocs {
14167   Uint2 seqfeat_from;
14168   Uint2 featdef_from;
14169   Uint2 seqfeat_to;
14170   Uint2 featdef_to;
14171   AdjustConvertFeatureListFunc adjust_features;
14172   CollectConvertFeatureOptionsFunc collect_options;
14173   FreeConvertFeatureOptionsFunc    free_options;
14174   ConvertFeatureTypeFunc           convert_func;
14175   ConversionCleanupFunc            cleanup_func;
14176   CharPtr                          help_text;
14177 } ConvertFeatureProcsData, PNTR ConvertFeatureProcsPtr;
14178 
14179 static Pointer SimpleOptsFree (Pointer);
14180 static Boolean ConvertCDSToRNAEx (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14181 static Boolean ConvertGeneToRNAEx (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14182 static ValNodePtr AdjustConvertFeaturesForBioSrcToRepeatRegion (ValNodePtr feat_list, Pointer extradata, BaseFormPtr bfp, BoolPtr cancel);
14183 static Boolean ConvertBioSrcToRepeatRegionEx (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14184 static ValNodePtr AdjustCDSToMiscFeatList (ValNodePtr feat_list, Pointer extradata, BaseFormPtr bfp, BoolPtr cancel);
14185 static Pointer GetCDSConversionOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel);
14186 static Boolean CDSToMiscFeatConvertFunc (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14187 static void CDSToMiscFeatConversionCleanup (Uint2 entityID, Pointer extradata);
14188 static Boolean ConvertImpToProt (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14189 static Boolean ConvertProtToImp (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14190 static Boolean ConvertImpToSpecialRNA (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14191 static Boolean ConvertRegionToImp (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14192 static Boolean ConvertRegionToRNA (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14193 static Boolean ConvertImpToRNA (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14194 static Boolean ConvertCommentToMiscFeat (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14195 static Boolean ConvertGeneToImpFeat (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14196 static Boolean ConvertRNAToMiscFeat (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14197 static Boolean ConvertSiteToMiscFeat (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14198 static Boolean ConvertProtToRegion (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14199 static Boolean ConvertRegionToProt (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14200 static Pointer GetBondOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel);
14201 static Pointer GetSiteOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel);
14202 static Boolean ConvertToSiteOrBond (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14203 static Pointer GetRegionOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel);
14204 static ValNodePtr AdjustRegionConversionFeatures (ValNodePtr feat_list, Pointer extradata, BaseFormPtr bfp, BoolPtr cancel);
14205 static Boolean ConvertAnyToRegion (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14206 static Boolean ConvertImpToImp (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14207 static Boolean ConvertRNAToRNA (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14208 static Boolean ConvertProtToProt (SeqFeatPtr, Uint2 featdef_to, Pointer extradata);
14209 static Boolean ConvertCDSToMatPeptide (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata);
14210 static Boolean ConvertMiscFeatureToCDSFunction (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata);
14211 static Boolean ConvertMiscFeatureToGeneFunction (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata);
14212 static Boolean ConvertmRNAToCodingRegionFunction (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata);
14213 static Boolean ConverttRNAToGeneFunction (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata);
14214 
14215 static ConvertFeatureProcsData ConvertFeaturesTable[] = {
14216   { SEQFEAT_CDREGION, FEATDEF_CDS,                SEQFEAT_RNA,    FEATDEF_ANY,
14217         NULL,  GetCDSConversionOpts, SimpleOptsFree, ConvertCDSToRNAEx, NULL,
14218         "Delete protein product sequence.\nClear product field if transcript ID removal was requested.\nIf converting to tRNA and anticodon value can be parsed from label, set aa value, and add any text that could not be parsed into an anticodon value to the feature note.\nIf converting to other RNA, put label in RNA product." },
14219   { SEQFEAT_GENE,     FEATDEF_GENE,               SEQFEAT_RNA,    FEATDEF_ANY,
14220         NULL,  NULL,                   NULL,           ConvertGeneToRNAEx, NULL,
14221         "If converting to tRNA and anticodon value can be parsed from label, set aa value, and add any text that could not be parsed into an anticodon value to the feature note.  If converting to other RNA, put label in RNA product.  Also append gene locus, allele, description, map location, and locus tag to comment (as long as these values are not already in the label and therefore in the RNA product)." },
14222   { SEQFEAT_BIOSRC,   FEATDEF_BIOSRC,             SEQFEAT_IMP,    FEATDEF_repeat_region,
14223        AdjustConvertFeaturesForBioSrcToRepeatRegion, NULL, NULL, ConvertBioSrcToRepeatRegionEx, NULL,
14224         "Creates a repeat_region with mobile_element qualifiers for the transposon and/or insertion sequence qualifiers on the BioSource.  All other BioSource information is discarded." },
14225   { SEQFEAT_CDREGION, FEATDEF_CDS,                SEQFEAT_IMP,    FEATDEF_misc_feature,
14226        AdjustCDSToMiscFeatList, GetCDSConversionOpts, SimpleOptsFree, CDSToMiscFeatConvertFunc, CDSToMiscFeatConversionCleanup,
14227        "Copy comment from coding region to new misc_feature and remove product field.  If not pseudo coding region, add product name from protein feature to new misc_feature comment and delete product sequence." },
14228   { SEQFEAT_IMP,      FEATDEF_ANY,                SEQFEAT_PROT,   FEATDEF_ANY,
14229        NULL, NULL, NULL, ConvertImpToProt, NULL,
14230        "Original feature must be on nucleotide sequence and be contained in coding region location.  Coding region must have product protein sequence.  New feature is created on product protein sequence so that the translated location will be as close as possible to the original nucleotide location (may not be exact because of codon boundaries)." },
14231   { SEQFEAT_PROT,     FEATDEF_mat_peptide_aa,     SEQFEAT_IMP,    FEATDEF_ANY,
14232        NULL, NULL, NULL, ConvertProtToImp, NULL,
14233        "Original feature must be on a protein sequence that is a product of a coding region.\nNew feature will be created on same sequence as coding region.\n"
14234        "If protein feature has name, this will be saved as /product qualifier on new feature.\nIf protein feature does not have name but does have description, this will be saved as /product qualifier on new feature.\n"
14235        "EC_number values from the protein feature will be saved as /EC_number qualifiers on the new feature.\nActivity values will be saved as /function qualifiers on the new feature.\n"
14236        "Db_xref values from the protein feature will be saved as /db_xref qualifers on the new feature." },
14237   { SEQFEAT_PROT,     FEATDEF_sig_peptide_aa,     SEQFEAT_IMP,    FEATDEF_ANY,
14238        NULL, NULL, NULL, ConvertProtToImp, NULL,
14239        "Original feature must be on a protein sequence that is a product of a coding region.\nNew feature will be created on same sequence as coding region.\n"
14240        "If protein feature has name, this will be saved as /product qualifier on new feature.\nIf protein feature does not have name but does have description, this will be saved as /product qualifier on new feature.\n"
14241        "EC_number values from the protein feature will be saved as /EC_number qualifiers on the new feature.\nActivity values will be saved as /function qualifiers on the new feature.\n"
14242        "Db_xref values from the protein feature will be saved as /db_xref qualifers on the new feature." },
14243   { SEQFEAT_PROT,     FEATDEF_transit_peptide_aa, SEQFEAT_IMP,    FEATDEF_ANY,
14244        NULL, NULL, NULL, ConvertProtToImp, NULL,
14245        "Original feature must be on a protein sequence that is a product of a coding region.\nNew feature will be created on same sequence as coding region.\n"
14246        "If protein feature has name, this will be saved as /product qualifier on new feature.\nIf protein feature does not have name but does have description, this will be saved as /product qualifier on new feature.\n"
14247        "EC_number values from the protein feature will be saved as /EC_number qualifiers on the new feature.\nActivity values will be saved as /function qualifiers on the new feature.\n"
14248        "Db_xref values from the protein feature will be saved as /db_xref qualifers on the new feature." },
14249   { SEQFEAT_IMP,      FEATDEF_misc_feature,                SEQFEAT_CDREGION,    FEATDEF_CDS,
14250        NULL, NULL, NULL, ConvertMiscFeatureToCDSFunction, NULL,
14251        "Use misc_feature comment for coding region product name." },
14252   { SEQFEAT_RNA,      FEATDEF_mRNA,                        SEQFEAT_CDREGION,    FEATDEF_CDS,
14253        NULL, NULL, NULL, ConvertmRNAToCodingRegionFunction, NULL,
14254        "Convert mRNA to coding region, use mRNA product for protein feature" },
14255   { SEQFEAT_RNA,      FEATDEF_tRNA,                        SEQFEAT_GENE,    FEATDEF_GENE,
14256        NULL, NULL, NULL, ConverttRNAToGeneFunction, NULL,
14257        "Convert tRNA to gene, use tRNA product for gene description" },
14258   { SEQFEAT_IMP,      FEATDEF_misc_feature,                SEQFEAT_GENE,    FEATDEF_GENE,
14259        NULL, NULL, NULL, ConvertMiscFeatureToGeneFunction, NULL,
14260        "Use misc_feature comment for gene locus." },
14261   { SEQFEAT_IMP,      FEATDEF_ANY,                SEQFEAT_RNA,    FEATDEF_misc_RNA,
14262        NULL, NULL, NULL, ConvertImpToSpecialRNA, NULL,
14263        "Creates a misc_RNA.  Import feature key is discarded." },
14264   { SEQFEAT_IMP,      FEATDEF_ANY,                SEQFEAT_RNA,    FEATDEF_precursor_RNA,
14265        NULL, NULL, NULL, ConvertImpToSpecialRNA, NULL,
14266        "Creates a precursor RNA.  Import feature key is discarded." },
14267   { SEQFEAT_REGION,   FEATDEF_REGION,             SEQFEAT_IMP,    FEATDEF_ANY,
14268        NULL, NULL, NULL, ConvertRegionToImp, NULL,
14269        "Creates a misc_feature with the region name saved as a /note qualifier." },
14270   { SEQFEAT_REGION,   FEATDEF_REGION,             SEQFEAT_RNA,    FEATDEF_misc_RNA,
14271        NULL, NULL, NULL, ConvertRegionToRNA, NULL,
14272        "Creates a misc_RNA feature with the region name as the product name." },
14273   { SEQFEAT_REGION,   FEATDEF_REGION,             SEQFEAT_RNA,    FEATDEF_precursor_RNA,
14274        NULL, NULL, NULL, ConvertRegionToRNA, NULL,
14275        "Creates a precursor RNA feature with the region name as the product name." },
14276   { SEQFEAT_IMP,      FEATDEF_ANY,                SEQFEAT_RNA,    FEATDEF_ANY,
14277        NULL, NULL, NULL, ConvertImpToRNA, NULL,
14278        "Creates an RNA feature of the specified type." },
14279   { SEQFEAT_COMMENT,  FEATDEF_ANY,                SEQFEAT_IMP,    FEATDEF_misc_feature,
14280        NULL, NULL, NULL, ConvertCommentToMiscFeat, NULL,
14281        "Creates a misc_feature with the same note as the original.  Note the flatfile display for the feature is the same." },
14282   { SEQFEAT_GENE,     FEATDEF_GENE,               SEQFEAT_IMP,    FEATDEF_ANY,
14283        NULL, NULL, NULL, ConvertGeneToImpFeat, NULL,
14284        "Creates an import feature with the gene description and locus prepended to the original comment, separated by semicolons." },
14285   { SEQFEAT_RNA,      FEATDEF_ANY,                SEQFEAT_IMP,    FEATDEF_misc_feature,
14286        NULL, NULL, NULL, ConvertRNAToMiscFeat, NULL,
14287        "Creates a misc_feature and adds the RNA product name to the comment." } ,
14288   { SEQFEAT_SITE,     FEATDEF_ANY,                SEQFEAT_IMP,    FEATDEF_misc_feature,
14289        NULL, NULL, NULL, ConvertSiteToMiscFeat, NULL,
14290        "Creates a misc_feature with the site type name as a /note qualifier." } ,
14291   { SEQFEAT_PROT,     FEATDEF_mat_peptide_aa,     SEQFEAT_REGION, FEATDEF_REGION,
14292        NULL, NULL, NULL, ConvertProtToRegion, NULL,
14293        "Creates a Region feature with the protein name as the region name." },
14294   { SEQFEAT_PROT,     FEATDEF_sig_peptide_aa,     SEQFEAT_REGION, FEATDEF_REGION,
14295        NULL, NULL, NULL, ConvertProtToRegion, NULL,
14296        "Creates a Region feature with the protein name as the region name." },
14297   { SEQFEAT_PROT,     FEATDEF_transit_peptide_aa, SEQFEAT_REGION, FEATDEF_REGION,
14298        NULL, NULL, NULL, ConvertProtToRegion, NULL,
14299        "Creates a Region feature with the protein name as the region name." },
14300   { SEQFEAT_REGION,   FEATDEF_REGION,             SEQFEAT_PROT,   FEATDEF_mat_peptide_aa,
14301        NULL, NULL, NULL, ConvertRegionToProt, NULL,
14302        "If feature is on nucleotide sequence, will create feature on protein product sequence for overlapping coding region.  Protein name will be region name." },
14303   { SEQFEAT_REGION,   FEATDEF_REGION,             SEQFEAT_PROT,   FEATDEF_sig_peptide_aa,
14304        NULL, NULL, NULL, ConvertRegionToProt, NULL,
14305        "If feature is on nucleotide sequence, will create feature on protein product sequence for overlapping coding region.  Protein name will be region name." },
14306   { SEQFEAT_REGION,   FEATDEF_REGION,             SEQFEAT_PROT,   FEATDEF_transit_peptide_aa,
14307        NULL, NULL, NULL, ConvertRegionToProt, NULL,
14308        "If feature is on nucleotide sequence, will create feature on protein product sequence for overlapping coding region.  Protein name will be region name." },
14309   { SEQFEAT_REGION,   FEATDEF_REGION,             SEQFEAT_PROT,   FEATDEF_preprotein,
14310        NULL, NULL, NULL, ConvertRegionToProt, NULL,
14311        "If feature is on nucleotide sequence, will create feature on protein product sequence for overlapping coding region.  Protein name will be region name." },
14312   { 0,                FEATDEF_ANY,                SEQFEAT_BOND,    FEATDEF_BOND,
14313        NULL, GetBondOpts, SimpleOptsFree, ConvertToSiteOrBond, NULL,
14314        "Create Bond feature with specified bond type.  Location is a SeqLocBond with a point at the start of the original location and a point at the end of the original location.  All feature ID, partialness, except, comment, product, location, genbank qualifiers, title, citation, experimental evidence, gene xrefs, db xrefs, and pseudo-ness information is discarded." },
14315   { 0,                FEATDEF_ANY,                SEQFEAT_SITE,    FEATDEF_SITE,
14316        NULL, GetSiteOpts, SimpleOptsFree, ConvertToSiteOrBond, NULL,
14317        "Create Site feature with specified site type.  All feature ID, partialness, except, comment, product, location, genbank qualifiers, title, citation, experimental evidence, gene xrefs, db xrefs, and pseudo-ness information is discarded." },
14318   { 0,                FEATDEF_ANY,                SEQFEAT_REGION,    FEATDEF_REGION,
14319        AdjustRegionConversionFeatures, GetRegionOpts, SimpleOptsFree, ConvertAnyToRegion, NULL,
14320        "Create Region feature on nucleotide sequence or protein product sequence of overlapping coding region as specified.  Use comment on feature for region name.\n"
14321        "All feature ID, partialness, except, comment, product, location, genbank qualifiers, title, citation, experimental evidence, gene xrefs, db xrefs, and pseudo-ness information is discarded." },
14322   { SEQFEAT_IMP,      FEATDEF_ANY,                SEQFEAT_IMP,    FEATDEF_ANY,
14323        NULL, NULL, NULL, ConvertImpToImp, NULL,
14324        "Changes type of import feature." },
14325   { SEQFEAT_RNA,      FEATDEF_ANY,                SEQFEAT_RNA,    FEATDEF_ANY,
14326        NULL, NULL, NULL, ConvertRNAToRNA, NULL,
14327        "Changes type of RNA feature." },
14328   { SEQFEAT_RNA,      FEATDEF_ncRNA,              SEQFEAT_IMP,    FEATDEF_misc_binding,
14329        NULL, NULL, NULL, ConvertncRNAToMiscBinding, NULL,
14330        "Changes ncRNA to misc_binding." },
14331   { SEQFEAT_PROT,     FEATDEF_ANY,                SEQFEAT_PROT,   FEATDEF_ANY,
14332        NULL, NULL, NULL, ConvertProtToProt, NULL,
14333        "Changes type of protein feature." },
14334   { SEQFEAT_CDREGION, FEATDEF_CDS,                SEQFEAT_PROT,   FEATDEF_mat_peptide_aa,
14335        NULL, NULL, NULL, ConvertCDSToMatPeptide, NULL,
14336        "If coding region is overlapped by another coding region, will convert the coding region to a mat-peptide on the overlapping coding region's protein sequence, otherwise if you have checked \"Leave Original Feature\" it will create a mat-peptide with the same protein names and description on the protein sequence for the coding region." }
14337 };
14338 
14339 static Int4 num_convert_feature_table_lines = sizeof (ConvertFeaturesTable) / sizeof (ConvertFeatureProcsData);
14340 
GetConvertFeatureTableLine(Uint2 seqfeat_from,Uint2 featdef_from,Uint2 seqfeat_to,Uint2 featdef_to)14341 static Int4 GetConvertFeatureTableLine (Uint2 seqfeat_from, Uint2 featdef_from, Uint2 seqfeat_to, Uint2 featdef_to)
14342 {
14343   Int4 i, table_line_num = -1;
14344 
14345   for (i = 0; i < num_convert_feature_table_lines && table_line_num == -1; i++)
14346   {
14347     if ((ConvertFeaturesTable[i].seqfeat_from == 0 || ConvertFeaturesTable[i].seqfeat_from == seqfeat_from)
14348         && (ConvertFeaturesTable[i].featdef_from == FEATDEF_ANY || ConvertFeaturesTable[i].featdef_from == featdef_from)
14349         && (ConvertFeaturesTable[i].seqfeat_to == 0 || ConvertFeaturesTable[i].seqfeat_to == seqfeat_to)
14350         && (ConvertFeaturesTable[i].featdef_to == FEATDEF_ANY || ConvertFeaturesTable[i].featdef_to == featdef_to))
14351     {
14352       table_line_num = i;
14353     }
14354   }
14355   return table_line_num;
14356 }
14357 
14358 
14359 typedef struct featureselremconform
14360 {
14361   FORM_MESSAGE_BLOCK
14362   DialoG  feature_select;
14363   DialoG  constraints;
14364   DialoG  accept_cancel;
14365   PopuP   action_choice;
14366   DialoG  feature_select_to;
14367   PrompT  from_prompt;
14368   PrompT  to_prompt;
14369   DialoG  feature_select_from;
14370   GrouP   remove_grp;
14371   GrouP   convert_grp;
14372   ButtoN  clear_constraints_on_action_change;
14373   ButtoN  leave_original_feature_btn;  /* checkbox for conversion only */
14374 
14375   DoC     help_text; /* for conversion only - describes conversion */
14376 
14377   /* used for convert callback */
14378   Uint1      featdef_to;
14379   Boolean    renormalize_nucprot;
14380   Boolean    leave_original_feature;
14381   ValNodePtr feat_list;
14382   BaseFormPtr bfp;
14383 } FeatureSelRemConvFormData, PNTR FeatureSelRemConvFormPtr;
14384 
CleanupFeatureSelRemConvForm(GraphiC g,VoidPtr data)14385 static void CleanupFeatureSelRemConvForm (GraphiC g, VoidPtr data)
14386 
14387 {
14388   FeatureSelRemConvFormPtr  mrfp;
14389 
14390   mrfp = (FeatureSelRemConvFormPtr) data;
14391   if (mrfp != NULL) {
14392   }
14393   StdCleanupFormProc (g, data);
14394 }
14395 
FeatureRemoveClearText(Pointer data)14396 static void FeatureRemoveClearText (Pointer data)
14397 {
14398   FeatureSelRemConvFormPtr   mrfp;
14399   FilterSetPtr          fsp;
14400 
14401   mrfp = (FeatureSelRemConvFormPtr) data;
14402   if (mrfp == NULL) return;
14403 
14404   fsp = DialogToPointer (mrfp->constraints);
14405   FilterSetClearText (fsp);
14406   PointerToDialog (mrfp->constraints, fsp);
14407   FilterSetFree (fsp);
14408 }
14409 
FeatureRemoveClear(Pointer data)14410 static void FeatureRemoveClear (Pointer data)
14411 {
14412   FeatureSelRemConvFormPtr mrfp;
14413 
14414   mrfp = (FeatureSelRemConvFormPtr) data;
14415   if (mrfp == NULL) return;
14416 
14417   PointerToDialog (mrfp->feature_select, NULL);
14418   PointerToDialog (mrfp->constraints, NULL);
14419   PointerToDialog (mrfp->feature_select_to, NULL);
14420   PointerToDialog (mrfp->feature_select_from, NULL);
14421   SetStatus (mrfp->leave_original_feature_btn, FALSE);
14422 }
14423 
FeatureRemoveChangeNotify(Pointer userdata)14424 static void FeatureRemoveChangeNotify (Pointer userdata)
14425 {
14426   FeatureSelRemConvFormPtr mrfp;
14427   ValNodePtr          err_list = NULL, vnp_from, vnp_to;
14428   Int4                table_line;
14429   RecT                r;
14430   Boolean             need_original = FALSE;
14431 
14432   mrfp = (FeatureSelRemConvFormPtr) userdata;
14433   if (mrfp == NULL) return;
14434 
14435   if (mrfp->action_choice == NULL)
14436   {
14437     /* just the remove dialog */
14438     err_list = TestDialog (mrfp->feature_select);
14439   }
14440   else if (GetValue (mrfp->action_choice) == FEATURE_CONVERT)
14441   {
14442     /* convert dialog in choice */
14443     if (mrfp->feature_select_from != NULL)
14444     {
14445       err_list = TestDialog (mrfp->feature_select_from);
14446     }
14447     else
14448     {
14449       err_list = TestDialog (mrfp->feature_select);
14450     }
14451     if (err_list == NULL && mrfp->feature_select_to != NULL)
14452     {
14453       err_list = TestDialog (mrfp->feature_select_to);
14454     }
14455     /* set help text */
14456     Reset (mrfp->help_text);
14457     vnp_from = (ValNodePtr) DialogToPointer (mrfp->feature_select_from);
14458     vnp_to = (ValNodePtr) DialogToPointer (mrfp->feature_select_to);
14459     if (vnp_from == NULL || vnp_to == NULL)
14460     {
14461       AppendText (mrfp->help_text, "No conversion selected", NULL, NULL, systemFont);
14462     }
14463     else if (vnp_from->choice == vnp_to->choice)
14464     {
14465       AppendText (mrfp->help_text, "Can't convert from and to the same type", NULL, NULL, systemFont);
14466       ValNodeAddPointer (&err_list, 0, "Can't convert from and to the same type");
14467     }
14468     else
14469     {
14470       /* set help text */
14471       table_line = GetConvertFeatureTableLine (FindFeatFromFeatDefType (vnp_from->choice),
14472                                                vnp_from->choice,
14473                                                FindFeatFromFeatDefType (vnp_to->choice),
14474                                                vnp_to->choice);
14475       if (table_line < 0)
14476       {
14477         AppendText (mrfp->help_text, "Conversion not supported", NULL, NULL, systemFont);
14478       }
14479       else if (ConvertFeaturesTable[table_line].help_text == NULL)
14480       {
14481         AppendText (mrfp->help_text, "No description available", NULL, NULL, systemFont);
14482       }
14483       else
14484       {
14485         AppendText (mrfp->help_text, ConvertFeaturesTable[table_line].help_text, NULL, NULL, systemFont);
14486       }
14487 
14488       /* if converting from CDS to site, bond, or region, "leave original" must be checked */
14489       if ((vnp_from->choice == FEATDEF_CDS
14490            || vnp_from->choice == FEATDEF_ANY)
14491           && (vnp_to->choice == FEATDEF_SITE
14492               || vnp_to->choice == FEATDEF_BOND
14493               || vnp_to->choice == FEATDEF_REGION))
14494       {
14495         need_original = TRUE;
14496         AppendText (mrfp->help_text, "If converting from CDS to site or bond, or region, you must check Leave Original Feature.", NULL, NULL, systemFont);
14497       }
14498     }
14499     vnp_from = ValNodeFreeData (vnp_from);
14500     vnp_to = ValNodeFreeData (vnp_to);
14501     ObjectRect (mrfp->help_text, &r);
14502     InvalRect (&r);
14503 
14504   }
14505   else
14506   {
14507     /* single feature dialog in choice */
14508     if (mrfp->feature_select != NULL)
14509     {
14510       err_list = TestDialog (mrfp->feature_select);
14511     }
14512   }
14513 
14514   if (err_list == NULL && (!need_original || GetStatus (mrfp->leave_original_feature_btn)))
14515   {
14516     EnableAcceptCancelDialogAccept (mrfp->accept_cancel);
14517   }
14518   else
14519   {
14520     DisableAcceptCancelDialogAccept (mrfp->accept_cancel);
14521   }
14522   ValNodeFree (err_list);
14523 }
14524 
14525 
FeatureRemoveChangeButton(ButtoN b)14526 static void FeatureRemoveChangeButton (ButtoN b)
14527 {
14528   FeatureSelRemConvFormPtr mrfp;
14529 
14530   mrfp = (FeatureSelRemConvFormPtr) GetObjectExtra (b);
14531   if (mrfp == NULL) return;
14532   FeatureRemoveChangeNotify (mrfp);
14533 }
14534 
14535 
FeatureRemoveOrConvertCenterAction(PopuP p)14536 static void FeatureRemoveOrConvertCenterAction (PopuP p)
14537 {
14538   FeatureSelRemConvFormPtr mrfp;
14539 
14540   mrfp = (FeatureSelRemConvFormPtr) GetObjectExtra (p);
14541   if (mrfp == NULL) return;
14542 
14543   if (GetValue (p) == 2)
14544   {
14545     Hide (mrfp->remove_grp);
14546     Show (mrfp->convert_grp);
14547   }
14548   else
14549   {
14550     Show (mrfp->remove_grp);
14551     Hide (mrfp->convert_grp);
14552   }
14553 
14554   if (GetStatus (mrfp->clear_constraints_on_action_change))
14555   {
14556     PointerToDialog (mrfp->feature_select, NULL);
14557     PointerToDialog (mrfp->feature_select_from, NULL);
14558     PointerToDialog (mrfp->feature_select_to, NULL);
14559     PointerToDialog (mrfp->constraints, NULL);
14560   }
14561   FeatureRemoveChangeNotify ((Pointer) mrfp);
14562 }
14563 
14564 
14565 
SelectFeatureCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)14566 static void SelectFeatureCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
14567 
14568 {
14569   if (sfp == NULL) return;
14570   ObjMgrAlsoSelect (sfp->idx.entityID, sfp->idx.itemID, OBJ_SEQFEAT, 0, NULL);
14571 }
14572 
DeselectFeatureCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)14573 static void DeselectFeatureCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
14574 
14575 {
14576   if (sfp == NULL) return;
14577   ObjMgrDeSelect (sfp->idx.entityID, sfp->idx.itemID, OBJ_SEQFEAT, 0, NULL);
14578 }
14579 
14580 typedef struct removefeature
14581 {
14582   ValNodePtr bsplist;
14583   ValNodePtr bssplist;
14584 } RemoveFeatureData, PNTR RemoveFeaturePtr;
14585 
RemoveFeatureCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)14586 static void RemoveFeatureCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
14587 {
14588   RemoveFeaturePtr rfp;
14589   SeqIdPtr         sip;
14590   BioseqPtr        productbsp, productcdna;
14591   BioseqSetPtr     productnps;
14592 
14593   if (sfp == NULL || userdata == NULL) return;
14594   rfp = (RemoveFeaturePtr) userdata;
14595 
14596   sfp->idx.deleteme = TRUE;
14597   if (sfp->data.choice == SEQFEAT_CDREGION)
14598   {
14599     if (sfp->product != NULL)
14600     {
14601       sip = SeqLocId (sfp->product);
14602       if (sip != NULL)
14603       {
14604         productbsp = BioseqFind (sip);
14605         if (productbsp != NULL)
14606         {
14607           ValNodeAddPointer (&(rfp->bsplist), 0, (Pointer) productbsp);
14608         }
14609       }
14610     }
14611   }
14612   else if (sfp->data.choice == SEQFEAT_RNA)
14613   {
14614     if (sfp->product != NULL)
14615     {
14616       sip = SeqLocId (sfp->product);
14617       if (sip != NULL)
14618       {
14619         productcdna = BioseqFind (sip);
14620         if (productcdna != NULL && productcdna->idx.parenttype == OBJ_BIOSEQSET)
14621         {
14622           productnps = (BioseqSetPtr) productcdna->idx.parentptr;
14623           if (productnps != NULL && productnps->_class == BioseqseqSet_class_nuc_prot)
14624           {
14625             ValNodeAddPointer (&(rfp->bssplist), 0, (Pointer) productnps);
14626           }
14627         }
14628       }
14629     }
14630   }
14631 }
14632 
14633 
ConvertRegionToImp(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)14634 static Boolean ConvertRegionToImp (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
14635 {
14636   return ConvertRegionToImpFunc (sfp, featdef_to);
14637 }
14638 
14639 
14640 static Boolean
ConvertToBondSiteOrRegion(SeqFeatPtr sfp,Int4 site_or_bond_type,Uint2 featdef_to,Boolean create_prot_feats)14641 ConvertToBondSiteOrRegion
14642 (SeqFeatPtr sfp,
14643  Int4       site_or_bond_type,
14644  Uint2      featdef_to,
14645  Boolean    create_prot_feats)
14646 {
14647   BioseqPtr          bsp;
14648   SeqLocPtr          slp;
14649   SeqEntryPtr        sep;
14650   SeqMgrFeatContext  context;
14651   SeqFeatPtr         newsfp;
14652   SeqIdPtr           sip;
14653   CharPtr            comment;
14654   SeqBondPtr         sbp;
14655   SeqPntPtr          spp;
14656   Boolean            no_cds = FALSE;
14657 
14658   if (sfp == NULL)
14659   {
14660     return FALSE;
14661   }
14662 
14663   if (site_or_bond_type == -1 && featdef_to != FEATDEF_REGION)
14664   {
14665     return FALSE;
14666   }
14667 
14668   bsp = BioseqFindFromSeqLoc (sfp->location);
14669   sfp = SeqMgrGetDesiredFeature (0, bsp, 0, 0, sfp, &context);
14670   if (sfp == NULL || bsp == NULL) return FALSE;
14671 
14672   if (ISA_aa (bsp->mol))
14673   {
14674     if (create_prot_feats)
14675     {
14676       slp = (SeqLocPtr) AsnIoMemCopy (sfp->location, (AsnReadFunc) SeqLocAsnRead, (AsnWriteFunc) SeqLocAsnWrite);
14677     }
14678     else
14679     {
14680       slp = FindNucleotideLocationForProteinFeatureConversion (sfp->location);
14681     }
14682   }
14683   else if (create_prot_feats)
14684   {
14685     slp = GetProteinLocationForNucleotideFeatureConversion (sfp->location, &no_cds);
14686     if (no_cds) {
14687       Message (MSG_ERROR, "Unable to find CDS covering %s", context.label);
14688       return FALSE;
14689     }
14690   } else {
14691     slp = (SeqLocPtr) AsnIoMemCopy (sfp->location, (AsnReadFunc) SeqLocAsnRead, (AsnWriteFunc) SeqLocAsnWrite);
14692   }
14693 
14694   bsp = GetBioseqGivenSeqLoc (slp, context.entityID);
14695   if (bsp == NULL) {
14696     Message (MSG_ERROR, "Unable to find target %s bioseq for %s", create_prot_feats ? "protein" : "nucleotide", context.label);
14697     slp = SeqLocFree (slp);
14698     return FALSE;
14699   }
14700 
14701   sep = SeqMgrGetSeqEntryForData (bsp);
14702   if (sep == NULL) {
14703     Message (MSG_ERROR, "Unable to find target %s seq-entry for %s", create_prot_feats ? "protein" : "nucleotide", context.label);
14704     return FALSE;
14705   }
14706 
14707   comment = sfp->comment;
14708 
14709   newsfp = NULL;
14710   if (featdef_to == FEATDEF_BOND || featdef_to == FEATDEF_SITE) {
14711     newsfp = SeqFeatNew ();
14712     if (newsfp != NULL)
14713     {
14714       newsfp->data.choice = FindFeatFromFeatDefType(featdef_to);
14715       newsfp->data.value.intvalue = site_or_bond_type;
14716         sfp->comment = NULL;
14717     }
14718   } else if (featdef_to == FEATDEF_REGION) {
14719     newsfp = SeqFeatNew ();
14720     if (newsfp != NULL)
14721     {
14722       newsfp->data.choice = FindFeatFromFeatDefType(featdef_to);
14723       newsfp->data.value.ptrvalue = sfp->comment;
14724       sfp->comment = NULL;
14725         comment = NULL;
14726     }
14727   }
14728   if (newsfp != NULL) {
14729     sfp->idx.deleteme = TRUE;
14730     CreateNewFeature (sep, NULL, FindFeatFromFeatDefType(featdef_to), newsfp);
14731     newsfp->location = slp;
14732     newsfp->comment = comment;
14733     if (featdef_to == FEATDEF_BOND) {
14734       if (slp->choice != SEQLOC_BOND) {
14735         sip = SeqLocId (slp);
14736         if (sip != NULL) {
14737           sbp = SeqBondNew ();
14738           if (sbp != NULL) {
14739             slp = ValNodeNew (NULL);
14740             if (slp != NULL) {
14741               slp->choice = SEQLOC_BOND;
14742               slp->data.ptrvalue = (Pointer) sbp;
14743               spp = SeqPntNew ();
14744               if (spp != NULL) {
14745                 spp->strand = SeqLocStrand (newsfp->location);
14746                 spp->id = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (sip, 0)));
14747                 spp->point = SeqLocStart (newsfp->location);
14748                 sbp->a = spp;
14749               }
14750               spp = SeqPntNew ();
14751               if (spp != NULL) {
14752                 spp->strand = SeqLocStrand (newsfp->location);
14753                 spp->id = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (sip, 0)));
14754                 spp->point = SeqLocStop (newsfp->location);
14755                 sbp->b = spp;
14756               }
14757               newsfp->location = SeqLocFree (newsfp->location);
14758               newsfp->location = slp;
14759             }
14760           }
14761         }
14762       }
14763     }
14764   }
14765   if (newsfp == NULL)
14766   {
14767     return FALSE;
14768   }
14769   else
14770   {
14771     return TRUE;
14772   }
14773 }
14774 
14775 
14776 typedef struct origfeat
14777 {
14778   SeqEntryPtr sep;
14779   SeqFeatPtr  sfp;
14780 } OrigFeatData, PNTR OrigFeatPtr;
14781 
14782 
AddDuplicateFeature(SeqFeatPtr sfp_orig,ValNodePtr PNTR feat_list)14783 static ValNodePtr AddDuplicateFeature (SeqFeatPtr sfp_orig, ValNodePtr PNTR feat_list)
14784 {
14785   SeqEntryPtr sep;
14786   BioseqPtr   bsp;
14787   OrigFeatPtr ofp;
14788 
14789   if (sfp_orig == NULL || feat_list == NULL) return NULL;
14790   bsp = BioseqFindFromSeqLoc (sfp_orig->location);
14791   if (bsp == NULL) return NULL;
14792   sep = SeqMgrGetSeqEntryForData (bsp);
14793   if (sep == NULL) return NULL;
14794 
14795   ofp = (OrigFeatPtr) MemNew (sizeof (OrigFeatData));
14796   if (ofp == NULL) return NULL;
14797 
14798   ofp->sep = sep;
14799   ofp->sfp = (SeqFeatPtr) AsnIoMemCopy (sfp_orig, (AsnReadFunc) SeqFeatAsnRead,
14800                                                  (AsnWriteFunc) SeqFeatAsnWrite);
14801 
14802   return ValNodeAddPointer (feat_list, 0, ofp);
14803 }
14804 
SimpleOptsFree(Pointer data)14805 static Pointer SimpleOptsFree (Pointer data)
14806 {
14807   return MemFree (data);
14808 }
14809 
14810 static Boolean
ConvertCDSToRNAEx(SeqFeatPtr sfp,Uint2 toFeatSubType,Pointer extradata)14811 ConvertCDSToRNAEx
14812 (SeqFeatPtr  sfp,
14813  Uint2       toFeatSubType,
14814  Pointer     extradata)
14815 {
14816   CDSConversionOptsPtr   opts;
14817   Boolean     remove_mRNA = FALSE;
14818   Boolean     remove_gene = FALSE;
14819   Boolean     remove_transcript_id = FALSE;
14820   Boolean     remove_only_pseudo = FALSE;
14821 
14822 
14823   if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return FALSE;
14824 
14825   opts = (CDSConversionOptsPtr) extradata;
14826   if (opts != NULL) {
14827     remove_mRNA = opts->remove_mrna;
14828     remove_gene = opts->remove_gene;
14829     remove_transcript_id = opts->remove_transcript_id;
14830     remove_only_pseudo = opts->only_pseudo;
14831   }
14832   if (remove_only_pseudo && !sfp->pseudo) {
14833     return FALSE;
14834   }
14835   ApplyCDSOptionsToFeature (sfp, remove_mRNA, remove_gene, remove_transcript_id, FALSE);
14836   return ConvertCDSToRNA (sfp, toFeatSubType);
14837 }
14838 
14839 
ConvertGeneToRNAEx(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)14840 static Boolean ConvertGeneToRNAEx (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
14841 {
14842   return ConvertGeneToRNA (sfp, featdef_to);
14843 }
14844 
14845 
CreateClickableListForSourceFeats(ValNodePtr feat_list)14846 static ValNodePtr CreateClickableListForSourceFeats (ValNodePtr feat_list)
14847 {
14848   ValNodePtr transposon_only_list = NULL;
14849   ValNodePtr insertion_seq_only_list = NULL;
14850   ValNodePtr transposon_and_insertion_seq_list = NULL;
14851   ValNodePtr note_only_list = NULL;
14852   ValNodePtr no_data_list = NULL;
14853   ValNodePtr vnp;
14854   CharPtr transposon_txt, insertion_seq_txt, note_txt;
14855   SeqFeatPtr sfp;
14856   BioSourcePtr biop;
14857   Boolean is_transposon;
14858   Boolean is_insertion_seq;
14859   ClickableItemPtr cip;
14860   ValNodePtr clickable_list = NULL;
14861 
14862   for (vnp = feat_list; vnp != NULL; vnp = vnp->next) {
14863     sfp = (SeqFeatPtr) vnp->data.ptrvalue;
14864     biop = (BioSourcePtr) sfp->data.value.ptrvalue;
14865     is_transposon = FALSE;
14866     is_insertion_seq = FALSE;
14867     transposon_txt = SubSourceText (biop, SUBSRC_transposon_name, &is_transposon);
14868     insertion_seq_txt = SubSourceText (biop, SUBSRC_insertion_seq_name, &is_insertion_seq);
14869     note_txt = NoteText (biop, sfp->comment);
14870 
14871     if (is_transposon && is_insertion_seq) {
14872       ValNodeAddPointer (&transposon_and_insertion_seq_list, OBJ_SEQFEAT, vnp->data.ptrvalue);
14873     } else if (is_transposon) {
14874       ValNodeAddPointer (&transposon_only_list, OBJ_SEQFEAT, vnp->data.ptrvalue);
14875     } else if (is_insertion_seq) {
14876       ValNodeAddPointer (&insertion_seq_only_list, OBJ_SEQFEAT, vnp->data.ptrvalue);
14877     } else if (!StringHasNoText (note_txt)) {
14878       ValNodeAddPointer (&note_only_list, OBJ_SEQFEAT, vnp->data.ptrvalue);
14879     } else {
14880       ValNodeAddPointer (&no_data_list, OBJ_SEQFEAT, vnp->data.ptrvalue);
14881     }
14882   }
14883 
14884   if (transposon_and_insertion_seq_list != NULL) {
14885     cip = NewClickableItem (0, "%d source features have both transposon-name and insertion-seq-name.", transposon_and_insertion_seq_list);
14886     ValNodeAddPointer (&clickable_list, 0, cip);
14887   }
14888   if (transposon_only_list != NULL) {
14889     cip = NewClickableItem (0, "%d source features have transposon-name.", transposon_only_list);
14890     cip->chosen = TRUE;
14891     ValNodeAddPointer (&clickable_list, 0, cip);
14892   }
14893   if (insertion_seq_only_list != NULL) {
14894     cip = NewClickableItem (0, "%d source features have insertion-seq-name.", insertion_seq_only_list);
14895     cip->chosen = TRUE;
14896     ValNodeAddPointer (&clickable_list, 0, cip);
14897   }
14898   if (note_only_list != NULL) {
14899     cip = NewClickableItem (0, "%d source features have notes, but neither transposon-name nor insertion-seq-name.", note_only_list);
14900     ValNodeAddPointer (&clickable_list, 0, cip);
14901   }
14902   if (no_data_list != NULL) {
14903     cip = NewClickableItem (0, "%d source features have no notes, no transposon-name, and no insertion-seq-name.", no_data_list);
14904     ValNodeAddPointer (&clickable_list, 0, cip);
14905   }
14906 
14907   return clickable_list;
14908 }
14909 
14910 
AdjustConvertFeaturesForBioSrcToRepeatRegion(ValNodePtr feat_list,Pointer extradata,BaseFormPtr bfp,BoolPtr cancel)14911 static ValNodePtr AdjustConvertFeaturesForBioSrcToRepeatRegion (ValNodePtr feat_list, Pointer extradata, BaseFormPtr bfp, BoolPtr cancel)
14912 {
14913   ValNodePtr clickable_list;
14914 
14915   *cancel = FALSE;
14916   clickable_list = CreateClickableListForSourceFeats (feat_list);
14917   feat_list = ValNodeFree (feat_list);
14918   feat_list = ChooseFeaturesForConversion (clickable_list, bfp, "Available Data", "Features");
14919   /* NOTE - the clickable_list will be freed by the dialog  - do not free it again here */
14920   if (feat_list == NULL)
14921   {
14922     *cancel = TRUE;
14923   }
14924   return feat_list;
14925 }
14926 
14927 
RemoveNonPseudoFeatures(ValNodePtr PNTR feat_list)14928 static void RemoveNonPseudoFeatures (ValNodePtr PNTR feat_list)
14929 {
14930   ValNodePtr prev = NULL, next_vnp, vnp;
14931   SeqFeatPtr sfp;
14932 
14933   vnp = *feat_list;
14934   while (vnp != NULL) {
14935     next_vnp = vnp->next;
14936     sfp = (SeqFeatPtr) vnp->data.ptrvalue;
14937     if (sfp != NULL && !sfp->pseudo) {
14938       if (prev == NULL) {
14939         *feat_list = vnp->next;
14940       } else {
14941         prev->next = vnp->next;
14942       }
14943       vnp->next = NULL;
14944       vnp = ValNodeFree (vnp);
14945     } else {
14946       prev = vnp;
14947     }
14948     vnp = next_vnp;
14949   }
14950 }
14951 
14952 
GetCDSConversionOpts(ValNodePtr feat_list,BaseFormPtr bfp,BoolPtr cancel)14953 static Pointer GetCDSConversionOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel)
14954 {
14955   Boolean all_are_pseudo = TRUE, any_are_pseudo = FALSE, any_gps = FALSE;
14956   CDSConversionOptsPtr opts;
14957   ValNodePtr vnp;
14958   SeqFeatPtr sfp;
14959 
14960   for (vnp = feat_list; vnp != NULL; vnp = vnp->next)
14961   {
14962     sfp = (SeqFeatPtr) vnp->data.ptrvalue;
14963     if (sfp != NULL)
14964     {
14965       if (sfp->pseudo)
14966       {
14967         any_are_pseudo = TRUE;
14968       }
14969       else
14970       {
14971         all_are_pseudo = FALSE;
14972       }
14973       if (!any_gps)
14974       {
14975         any_gps = IsFeatInGPS (sfp);
14976       }
14977     }
14978   }
14979 
14980   opts = GetCDSConversionOptions (all_are_pseudo, any_are_pseudo, any_gps, cancel);
14981 
14982   return opts;
14983 }
14984 
14985 
AdjustCDSToMiscFeatList(ValNodePtr feat_list,Pointer extradata,BaseFormPtr bfp,BoolPtr cancel)14986 static ValNodePtr AdjustCDSToMiscFeatList (ValNodePtr feat_list, Pointer extradata, BaseFormPtr bfp, BoolPtr cancel)
14987 {
14988   CDSConversionOptsPtr opts;
14989 
14990   if (feat_list == NULL || extradata == NULL || cancel == NULL) return feat_list;
14991   opts = (CDSConversionOptsPtr) extradata;
14992   *cancel = FALSE;
14993   if (opts->only_pseudo) {
14994     /* remove features that are not pseudo */
14995     RemoveNonPseudoFeatures (&feat_list);
14996   }
14997   return feat_list;
14998 }
14999 
15000 
CDSToMiscFeatConversionCleanup(Uint2 entityID,Pointer extradata)15001 static void CDSToMiscFeatConversionCleanup (Uint2 entityID, Pointer extradata)
15002 {
15003   SeqEntryPtr sep;
15004 
15005   DeleteMarkedObjects (entityID, 0, NULL);
15006   sep = GetTopSeqEntryForEntityID (entityID);
15007   RenormalizeNucProtSets (sep, TRUE);
15008 }
15009 
15010 
CDSToMiscFeatConvertFunc(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)15011 static Boolean CDSToMiscFeatConvertFunc (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
15012 {
15013   CDSConversionOptsPtr opts;
15014   Boolean              rval = FALSE;
15015 
15016   opts = (CDSConversionOptsPtr) extradata;
15017   if (opts == NULL || sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION)
15018   {
15019     return FALSE;
15020   }
15021   else if (sfp->pseudo)
15022   {
15023     rval = ConvertOnePseudoCDSToMiscFeat (sfp);
15024   }
15025   else
15026   {
15027     /* do other here */
15028 
15029     rval = ConvertOneCDSToMiscFeat (sfp, FALSE, FALSE, opts);
15030   }
15031   return TRUE;
15032 }
15033 
15034 
15035 typedef struct siteorbond {
15036   Int4 site_or_bond_type;
15037 } SiteOrBondData, PNTR SiteOrBondPtr;
15038 
GetSiteOrBondOpts(ValNodePtr feat_list,BaseFormPtr bfp,BoolPtr cancel,Uint2 toFeat)15039 static Pointer GetSiteOrBondOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel, Uint2 toFeat)
15040 {
15041   EnumFieldAssocPtr  al;
15042   CharPtr            mssg;
15043   UIEnum             val;
15044   SiteOrBondPtr      opts = NULL;
15045 
15046   *cancel = FALSE;
15047   al = NULL;
15048   mssg = NULL;
15049   if (toFeat == FEATDEF_BOND) {
15050     al = enum_bond_alist;
15051     mssg = "Select type of bond";
15052   } else if (toFeat == FEATDEF_SITE) {
15053     al = enum_site_alist;
15054     mssg = "Select type of site";
15055   } else {
15056     *cancel = TRUE;
15057     return NULL;
15058   }
15059 
15060   if (al == NULL || ! AlistMessage (al, &val, 1, mssg))
15061   {
15062     *cancel = TRUE;
15063   }
15064   else
15065   {
15066     opts = (SiteOrBondPtr) MemNew (sizeof (SiteOrBondData));
15067     opts->site_or_bond_type = (Int4) val;
15068   }
15069   return opts;
15070 }
15071 
15072 
GetSiteOpts(ValNodePtr feat_list,BaseFormPtr bfp,BoolPtr cancel)15073 static Pointer GetSiteOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel)
15074 {
15075   return GetSiteOrBondOpts (feat_list, bfp, cancel, FEATDEF_SITE);
15076 }
15077 
15078 
GetBondOpts(ValNodePtr feat_list,BaseFormPtr bfp,BoolPtr cancel)15079 static Pointer GetBondOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel)
15080 {
15081   return GetSiteOrBondOpts (feat_list, bfp, cancel, FEATDEF_BOND);
15082 }
15083 
15084 
ConvertToSiteOrBond(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)15085 static Boolean ConvertToSiteOrBond (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
15086 {
15087   SiteOrBondPtr      opts = NULL;
15088 
15089   opts = (SiteOrBondPtr) extradata;
15090   if (sfp == NULL || opts == NULL) return FALSE;
15091 
15092   return ConvertToBondSiteOrRegion (sfp, opts->site_or_bond_type, featdef_to, TRUE);
15093 }
15094 
15095 typedef struct regionopts {
15096   Boolean create_prot_feats;
15097 } RegionOptsData, PNTR RegionOptsPtr;
15098 
15099 
GetBadProteinConversionFeatures(ValNodePtr feat_list)15100 static ValNodePtr GetBadProteinConversionFeatures (ValNodePtr feat_list)
15101 {
15102   ValNodePtr no_cds_list = NULL, bad_coordinates_list = NULL, err_list = NULL, vnp;
15103   Boolean    no_cds;
15104   SeqLocPtr  slp;
15105   SeqFeatPtr sfp;
15106   BioseqPtr  bsp;
15107 
15108   for (vnp = feat_list; vnp != NULL; vnp = vnp->next) {
15109     sfp = (SeqFeatPtr) vnp->data.ptrvalue;
15110     bsp = BioseqFindFromSeqLoc (sfp->location);
15111     if (bsp != NULL && ISA_aa (bsp->mol))
15112     {
15113       slp = FindNucleotideLocationForProteinFeatureConversion (sfp->location);
15114       if (slp == NULL)
15115       {
15116         no_cds = TRUE;
15117       }
15118     }
15119     else
15120     {
15121       slp = GetProteinLocationForNucleotideFeatureConversion (sfp->location, &no_cds);
15122     }
15123     if (slp == NULL) {
15124       if (no_cds) {
15125         ValNodeAddPointer (&no_cds_list, OBJ_SEQFEAT, sfp);
15126       } else {
15127         ValNodeAddPointer (&bad_coordinates_list, OBJ_SEQFEAT, sfp);
15128       }
15129     } else {
15130       slp = SeqLocFree (slp);
15131     }
15132   }
15133 
15134   if (no_cds_list != NULL) {
15135     ValNodeAddPointer (&err_list, 0, NewClickableItem (0, "%d features have no overlapping coding region", no_cds_list));
15136   }
15137   if (bad_coordinates_list != NULL) {
15138     ValNodeAddPointer (&err_list, 0, NewClickableItem (0, "%d features do not stop or start on codon boundaries", bad_coordinates_list));
15139   }
15140   return err_list;
15141 }
15142 
15143 
GetRegionOpts(ValNodePtr feat_list,BaseFormPtr bfp,BoolPtr cancel)15144 static Pointer GetRegionOpts (ValNodePtr feat_list, BaseFormPtr bfp, BoolPtr cancel)
15145 {
15146   ValNodePtr            err_list;
15147   WindoW                w;
15148   GrouP                 h, nuc_prot_choice, c;
15149   DialoG                bad_prot_feats = NULL;
15150   ButtoN                b;
15151   ModalAcceptCancelData acd;
15152   Boolean               rval = FALSE;
15153   RegionOptsPtr         opts = NULL;
15154 
15155   *cancel = FALSE;
15156 
15157   if (feat_list == NULL) return NULL;
15158 
15159   err_list = GetBadProteinConversionFeatures (feat_list);
15160 
15161   w = MovableModalWindow(-20, -13, -10, -10, "Create Nucleotide or Protein Features", NULL);
15162   h = HiddenGroup (w, -1, 0, NULL);
15163   SetGroupSpacing (h, 10, 10);
15164 
15165   if (err_list != NULL) {
15166     bad_prot_feats = CreateClickableListDialog (h, "Reasons", "Original Features",
15167                                                 ScrollToDiscrepancyItem, EditDiscrepancyItem, NULL,
15168                                                 GetDiscrepancyItemText);
15169     PointerToDialog (bad_prot_feats, err_list);
15170   }
15171 
15172   nuc_prot_choice = HiddenGroup (h, 0, 2, NULL);
15173   RadioButton (nuc_prot_choice, "Create Nucleotide Features");
15174   RadioButton (nuc_prot_choice, err_list == NULL ? "Create Protein Features" : "Create Protein Features (features listed above will be skipped)");
15175   SetValue (nuc_prot_choice, err_list == NULL ? 2 : 1);
15176 
15177   c = HiddenGroup (h, 2, 0, NULL);
15178   SetGroupSpacing (c, 10, 10);
15179   b = PushButton (c, "Accept", ModalAcceptButton);
15180   SetObjectExtra (b, &acd, NULL);
15181   b = PushButton (c, "Cancel", ModalCancelButton);
15182   SetObjectExtra (b, &acd, NULL);
15183   AlignObjects (ALIGN_CENTER, (HANDLE) nuc_prot_choice,
15184                               (HANDLE) c,
15185                               (HANDLE) bad_prot_feats,
15186                               NULL);
15187   Show (w);
15188   Select (w);
15189   acd.accepted = FALSE;
15190   acd.cancelled = FALSE;
15191   while (!acd.accepted && ! acd.cancelled)
15192   {
15193     ProcessExternalEvent ();
15194     Update ();
15195   }
15196   ProcessAnEvent ();
15197   if (acd.cancelled)
15198   {
15199     *cancel = TRUE;
15200   }
15201   else
15202   {
15203     opts = (RegionOptsPtr) MemNew (sizeof (RegionOptsData));
15204     if (GetValue (nuc_prot_choice) == 2)
15205     {
15206       opts->create_prot_feats = TRUE;
15207     }
15208     else
15209     {
15210       opts->create_prot_feats = FALSE;
15211     }
15212   }
15213   Remove (w);
15214 
15215   return opts;
15216 }
15217 
15218 
RemoveClickableItemFeaturesFromFeatureList(ClickableItemPtr cip,ValNodePtr PNTR feat_list)15219 static void RemoveClickableItemFeaturesFromFeatureList (ClickableItemPtr cip, ValNodePtr PNTR feat_list)
15220 {
15221   ValNodePtr vnp_i, vnp_p, vnp_r;
15222 
15223   if (cip == NULL || feat_list == NULL || *feat_list == NULL) return;
15224   for (vnp_i = cip->item_list; vnp_i != NULL; vnp_i = vnp_i->next) {
15225     if (vnp_i->choice != OBJ_SEQFEAT || vnp_i->data.ptrvalue == NULL) continue;
15226     vnp_p = NULL;
15227     vnp_r = *feat_list;
15228     while (vnp_r != NULL && vnp_r->data.ptrvalue != vnp_i->data.ptrvalue) {
15229       vnp_p = vnp_r;
15230       vnp_r = vnp_r->next;
15231     }
15232     if (vnp_r != NULL) {
15233       if (vnp_p == NULL) {
15234         *feat_list = vnp_r->next;
15235       } else {
15236         vnp_p->next = vnp_r->next;
15237       }
15238       vnp_r->next = NULL;
15239       vnp_r = ValNodeFree (vnp_r);
15240     }
15241   }
15242   for (vnp_i = cip->subcategories; vnp_i != NULL; vnp_i = vnp_i->next) {
15243     RemoveClickableItemFeaturesFromFeatureList (vnp_i->data.ptrvalue, feat_list);
15244   }
15245 }
15246 
15247 
AdjustRegionConversionFeatures(ValNodePtr feat_list,Pointer extradata,BaseFormPtr bfp,BoolPtr cancel)15248 static ValNodePtr AdjustRegionConversionFeatures (ValNodePtr feat_list, Pointer extradata, BaseFormPtr bfp, BoolPtr cancel)
15249 {
15250   RegionOptsPtr opts = (RegionOptsPtr) extradata;
15251   ValNodePtr    err_list, vnp_c;
15252 
15253   *cancel = FALSE;
15254   if (opts == NULL || !opts->create_prot_feats) return feat_list;
15255 
15256   err_list = GetBadProteinConversionFeatures (feat_list);
15257 
15258   for (vnp_c = err_list; vnp_c != NULL; vnp_c = vnp_c->next) {
15259     RemoveClickableItemFeaturesFromFeatureList (vnp_c->data.ptrvalue, &feat_list);
15260   }
15261   return feat_list;
15262 }
15263 
15264 
ConvertAnyToRegion(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)15265 static Boolean ConvertAnyToRegion (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
15266 {
15267   RegionOptsPtr opts = (RegionOptsPtr) extradata;
15268 
15269   if (opts == NULL || sfp == NULL) return FALSE;
15270   return ConvertToBondSiteOrRegion (sfp, 0, FEATDEF_REGION, opts->create_prot_feats);
15271 }
15272 
15273 
ConvertImpToImp(SeqFeatPtr sfp,Uint2 featdef_to,Pointer extradata)15274 static Boolean ConvertImpToImp (SeqFeatPtr sfp, Uint2 featdef_to, Pointer extradata)
15275 {
15276   return ConvertImpToImpFunc (sfp, featdef_to);
15277 }
15278 
15279 
CollectFeaturesToBeConverted(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)15280 static void CollectFeaturesToBeConverted (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
15281 {
15282   ValNodePtr PNTR feat_list = (ValNodePtr PNTR) userdata;
15283 
15284   ValNodeAddPointer (feat_list, OBJ_SEQFEAT, sfp);
15285 }
15286 
15287 
MoveInferenceToOverlappingGene(SeqFeatPtr sfp)15288 static void MoveInferenceToOverlappingGene (SeqFeatPtr sfp)
15289 {
15290   GBQualPtr qual, qual_prev= NULL, qual_next;
15291   SeqFeatPtr gene;
15292 
15293   if (sfp == NULL) return;
15294 
15295   gene = GetGeneForFeature (sfp);
15296   if (gene == NULL || gene->idx.deleteme || gene == sfp) return;
15297 
15298   qual = sfp->qual;
15299   while (qual != NULL) {
15300     qual_next = qual->next;
15301     if (StringCmp (qual->qual, "inference") == 0) {
15302       if (qual_prev == NULL) {
15303         sfp->qual = qual->next;
15304       } else {
15305         qual_prev->next = qual->next;
15306       }
15307       qual->next = NULL;
15308       qual->next = gene->qual;
15309       gene->qual = qual;
15310     } else {
15311       qual_prev = qual;
15312     }
15313     qual = qual_next;
15314   }
15315 }
15316 
15317 
NewConvertFeaturesByList(SeqEntryPtr sep,FilterSetPtr fsp,Uint1 featdef_from,FeatureSelRemConvFormPtr mrfp)15318 static Boolean NewConvertFeaturesByList (SeqEntryPtr sep, FilterSetPtr fsp, Uint1 featdef_from, FeatureSelRemConvFormPtr mrfp)
15319 {
15320   ValNodePtr feat_list = NULL, sel_feat_list = NULL, vnp;
15321   Boolean not_match = FALSE;
15322   Boolean    only_pseudo = FALSE;
15323   SelStructPtr sel;
15324   SeqFeatPtr   sfp;
15325   SeqMgrFeatContext fcontext;
15326   Int4              table_line_num = -1;
15327   Uint2             seqfeat_from, seqfeat_to;
15328   Pointer           extradata = NULL;
15329   Boolean           cancel = FALSE;
15330   ValNodePtr        dup_feat_vnp = NULL;
15331   OrigFeatPtr       ofp;
15332   Boolean           removed_cds = FALSE;
15333   BioseqPtr         protBsp;
15334 
15335   OperateOnSeqEntryConstrainedObjects (sep, fsp,
15336                                        CollectFeaturesToBeConverted,
15337                                        NULL, 0, featdef_from, 0, &feat_list);
15338   sel = ObjMgrGetSelected ();
15339   while (sel != NULL) {
15340     if (sel->entityID == mrfp->input_entityID && sel->itemtype == OBJ_SEQFEAT) {
15341       sfp = SeqMgrGetDesiredFeature (sel->entityID, NULL, sel->itemID, 0, NULL, &fcontext);
15342       if (sfp != NULL) {
15343         vnp = feat_list;
15344         while (vnp != NULL && vnp->data.ptrvalue != sfp) {
15345           vnp = vnp->next;
15346         }
15347         if (vnp == NULL) {
15348           not_match = TRUE;
15349         }
15350         ValNodeAddPointer (&sel_feat_list, OBJ_SEQFEAT, sfp);
15351       }
15352     }
15353     sel = sel->next;
15354   }
15355   if (sel_feat_list != NULL) {
15356     feat_list = ValNodeFree (feat_list);
15357     if (not_match
15358         && Message (MSG_YN,
15359                     "Selected feature%s do%s not match options - apply to selected feature anyway?",
15360                     sel_feat_list->next == NULL ? "" : "s",
15361                     sel_feat_list->next == NULL ? "es" : "") == ANS_NO) {
15362       sel_feat_list = ValNodeFree (sel_feat_list);
15363       return FALSE;
15364     }
15365     feat_list = sel_feat_list;
15366   }
15367 
15368   if (feat_list == NULL) {
15369     Message (MSG_ERROR, "No features of the specified type exist to be converted!");
15370     return FALSE;
15371   }
15372 
15373   /* find line in table that applies */
15374   seqfeat_from = FindFeatFromFeatDefType (featdef_from);
15375   seqfeat_to =   FindFeatFromFeatDefType (mrfp->featdef_to);
15376 
15377   table_line_num = GetConvertFeatureTableLine (seqfeat_from, featdef_from, seqfeat_to, mrfp->featdef_to);
15378   if (table_line_num < 0 || ConvertFeaturesTable[table_line_num].convert_func == NULL)
15379   {
15380     Message (MSG_ERROR, "This conversion not supported - contact"
15381          " sequindev for instructions.");
15382     return FALSE;
15383   }
15384 
15385   /* collect extra data if necessary */
15386   if (ConvertFeaturesTable[table_line_num].collect_options != NULL)
15387   {
15388     extradata = (ConvertFeaturesTable[table_line_num].collect_options) (feat_list, mrfp->bfp, &cancel);
15389     if (cancel)
15390     {
15391       feat_list = ValNodeFree (feat_list);
15392       /* free extradata */
15393       if (ConvertFeaturesTable[table_line_num].free_options != NULL)
15394       {
15395         (ConvertFeaturesTable[table_line_num].free_options) (extradata);
15396       }
15397       return FALSE;
15398     }
15399   }
15400   else if (featdef_from == FEATDEF_CDS && mrfp->featdef_to == FEATDEF_mat_peptide_aa)
15401   {
15402     extradata = &(mrfp->leave_original_feature);
15403   }
15404 
15405   /* adjust feature list if necessary */
15406   if (ConvertFeaturesTable[table_line_num].adjust_features != NULL)
15407   {
15408     feat_list = (ConvertFeaturesTable[table_line_num].adjust_features) (feat_list, extradata, mrfp->bfp, &cancel);
15409     if (cancel || feat_list == NULL)
15410     {
15411       feat_list = ValNodeFree (feat_list);
15412       /* free extradata */
15413       if (ConvertFeaturesTable[table_line_num].free_options != NULL)
15414       {
15415         (ConvertFeaturesTable[table_line_num].free_options) (extradata);
15416       }
15417       return FALSE;
15418     }
15419   }
15420 
15421   /* process list */
15422   for (vnp = feat_list; vnp != NULL; vnp = vnp->next)
15423   {
15424     sfp = (SeqFeatPtr) vnp->data.ptrvalue;
15425     if (sfp == NULL) continue;
15426     protBsp = NULL;
15427     if (sfp->data.choice == SEQFEAT_CDREGION && !mrfp->leave_original_feature)
15428     {
15429       protBsp = BioseqFindFromSeqLoc (sfp->product);
15430       if (protBsp != NULL)
15431       {
15432         protBsp->idx.deleteme = TRUE;
15433       }
15434       removed_cds = TRUE;
15435     }
15436 
15437     dup_feat_vnp = NULL;
15438     if (mrfp->leave_original_feature)
15439     {
15440       /* need a list of duplicate features that we can add to the appropriate SeqEntrys
15441        * when we are done with the conversions.
15442        */
15443       dup_feat_vnp = AddDuplicateFeature (sfp, &(mrfp->feat_list));
15444     }
15445 
15446     if (ConvertFeaturesTable[table_line_num].convert_func (sfp, mrfp->featdef_to, extradata))
15447     {
15448       /* set the subtype to zero so that it will be reindexed */
15449       sfp->idx.subtype = 0;
15450       if (mrfp->featdef_to == FEATDEF_misc_feature)
15451       {
15452         MoveInferenceToOverlappingGene (sfp);
15453       }
15454     }
15455     else if (dup_feat_vnp != NULL && dup_feat_vnp->data.ptrvalue != NULL)
15456     {
15457       /* feature wasn't removed, for whatever reason */
15458       /* remove the duplicate feature from the list to be added later */
15459       ofp = (OrigFeatPtr) dup_feat_vnp->data.ptrvalue;
15460       ofp->sfp = SeqFeatFree (ofp->sfp);
15461       ofp->sep = NULL;
15462 
15463       /* don't remove protein product if feature wasn't removed */
15464       if (protBsp != NULL)
15465       {
15466         protBsp->idx.deleteme = FALSE;
15467       }
15468     }
15469     else if (sfp->data.choice == SEQFEAT_CDREGION)
15470     {
15471       /* failed to convert feature, don't remove product */
15472       if (protBsp != NULL)
15473       {
15474         protBsp->idx.deleteme = FALSE;
15475       }
15476     }
15477   }
15478 
15479   feat_list = ValNodeFree (feat_list);
15480 
15481   /* do cleanup tasks */
15482   if (ConvertFeaturesTable[table_line_num].cleanup_func != NULL)
15483   {
15484     (ConvertFeaturesTable[table_line_num].cleanup_func) (mrfp->input_entityID, extradata);
15485   }
15486 
15487   /* free extradata */
15488   if (ConvertFeaturesTable[table_line_num].free_options != NULL)
15489   {
15490     (ConvertFeaturesTable[table_line_num].free_options) (extradata);
15491   }
15492 
15493   if (removed_cds)
15494   {
15495     DeleteMarkedObjects (mrfp->input_entityID, 0, NULL);
15496     RenormalizeNucProtSets (sep, TRUE);
15497   }
15498 
15499   return TRUE;
15500 }
15501 
15502 
RemoveProteinProducts(ValNodePtr bsplist,Uint2 entityID,SeqEntryPtr sep)15503 static void RemoveProteinProducts (ValNodePtr bsplist, Uint2 entityID, SeqEntryPtr sep)
15504 {
15505   MsgAnswer  ans;
15506   ValNodePtr tmp;
15507   BioseqPtr  bsp;
15508   Uint4      itemID;
15509   OMProcControl  ompc;
15510 
15511   if (bsplist == NULL)
15512   {
15513     return;
15514   }
15515   ans = Message (MSG_YN, "Remove protein products?");
15516   if (ans == ANS_YES) {
15517     for (tmp = bsplist; tmp != NULL; tmp = tmp->next) {
15518       bsp = (BioseqPtr) tmp->data.ptrvalue;
15519       itemID = GetItemIDGivenPointer (entityID, OBJ_BIOSEQ, (Pointer) bsp);
15520       if (itemID > 0) {
15521         MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
15522         ompc.do_not_reload_from_cache = TRUE;
15523         ompc.input_entityID = entityID;
15524         ompc.input_itemID = itemID;
15525         ompc.input_itemtype = OBJ_BIOSEQ;
15526         if (! DetachDataForProc (&ompc, FALSE)) {
15527           Message (MSG_POSTERR, "DetachDataForProc failed");
15528         }
15529         SeqMgrDeleteFromBioseqIndex (bsp);
15530       }
15531     }
15532     ans = Message (MSG_YN, "Renormalize Nuc-Prot sets?");
15533     if (ans == ANS_YES)
15534     {
15535       RemoveOrphanProteins (entityID, sep);
15536       RenormalizeNucProtSets (sep, TRUE);
15537     }
15538   }
15539 }
15540 
RemoveCDNANucProtProducts(ValNodePtr bssplist,Uint2 entityID)15541 static void RemoveCDNANucProtProducts (ValNodePtr bssplist, Uint2 entityID)
15542 {
15543   MsgAnswer     ans;
15544   ValNodePtr    tmp;
15545   BioseqSetPtr  bssp;
15546   Uint4         itemID;
15547   OMProcControl ompc;
15548 
15549   if (bssplist == NULL)
15550   {
15551     return;
15552   }
15553 
15554   ans = Message (MSG_YN, "Remove cDNA nuc-prot products?");
15555   if (ans != ANS_YES)
15556   {
15557     return;
15558   }
15559 
15560   for (tmp = bssplist; tmp != NULL; tmp = tmp->next)
15561   {
15562     bssp = (BioseqSetPtr) tmp->data.ptrvalue;
15563     itemID = GetItemIDGivenPointer (entityID, OBJ_BIOSEQSET, (Pointer) bssp);
15564     if (itemID > 0) {
15565       MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
15566       ompc.do_not_reload_from_cache = TRUE;
15567       ompc.input_entityID = entityID;
15568       ompc.input_itemID = itemID;
15569       ompc.input_itemtype = OBJ_BIOSEQSET;
15570       if (! DetachDataForProc (&ompc, FALSE)) {
15571         Message (MSG_POSTERR, "DetachDataForProc failed");
15572       }
15573     }
15574   }
15575 }
15576 
15577 
FeatureRemoveOrConvertAction(Pointer userdata)15578 static Boolean FeatureRemoveOrConvertAction (Pointer userdata)
15579 {
15580   FeatureSelRemConvFormPtr   mrfp;
15581   FilterSetPtr          fsp;
15582   SeqEntryPtr           sep;
15583   ValNodePtr            feature_type_list, vnp;
15584   Int4                  window_action;
15585   Uint1                 feat_def_choice;
15586   RemoveFeatureData     rfd;
15587   OrigFeatPtr           ofp;
15588   SeqFeatPtr            sfp;
15589   Boolean               rval = TRUE;
15590   SeqEntryPtr           create_sep;
15591 
15592   if (userdata == NULL) return FALSE;
15593 
15594   mrfp = (FeatureSelRemConvFormPtr) userdata;
15595   window_action = GetValue (mrfp->action_choice);
15596 
15597   fsp = (FilterSetPtr) DialogToPointer (mrfp->constraints);
15598 
15599   sep = GetTopSeqEntryForEntityID (mrfp->input_entityID);
15600   if (sep == NULL) return FALSE;
15601 
15602   if (window_action == FEATURE_CONVERT)
15603   {
15604     vnp = (ValNodePtr) DialogToPointer (mrfp->feature_select_to);
15605     if (vnp == NULL)
15606     {
15607       FilterSetFree (fsp);
15608       return FALSE;
15609     }
15610     mrfp->featdef_to = vnp->choice;
15611     /* NOTE - I do not need to use ValNodeFreeData because I'm using
15612      * the data.ptrvalue in mrfp->featname_to and will free it when I free
15613      * mrfp.
15614      */
15615     vnp = ValNodeFree (vnp);
15616     feature_type_list = (ValNodePtr) DialogToPointer (mrfp->feature_select_from);
15617     mrfp->leave_original_feature = GetStatus (mrfp->leave_original_feature_btn);
15618   }
15619   else
15620   {
15621     feature_type_list = (ValNodePtr) DialogToPointer (mrfp->feature_select);
15622   }
15623   if (feature_type_list == NULL)
15624   {
15625     FilterSetFree (fsp);
15626     return FALSE;
15627   }
15628 
15629   for (vnp = feature_type_list; vnp != NULL; vnp = vnp->next)
15630   {
15631     feat_def_choice = vnp->choice;
15632     if (feat_def_choice == 255)
15633     {
15634       feat_def_choice = 0;
15635     }
15636     switch (window_action)
15637     {
15638       case FEATURE_CONVERT:
15639         rval = NewConvertFeaturesByList (sep, fsp, feat_def_choice, mrfp);
15640         break;
15641       case FEATURE_REMOVE:
15642         rfd.bsplist = NULL;
15643         rfd.bssplist = NULL;
15644         OperateOnSeqEntryConstrainedObjects (sep, fsp,
15645                                              RemoveFeatureCallback,
15646                                              NULL, 0, feat_def_choice, 0, &rfd);
15647         RemoveProteinProducts (rfd.bsplist, mrfp->input_entityID, sep);
15648         RemoveCDNANucProtProducts (rfd.bssplist, mrfp->input_entityID);
15649         rfd.bsplist = ValNodeFree (rfd.bsplist);
15650         rfd.bssplist = ValNodeFree (rfd.bssplist);
15651         break;
15652       case FEATURE_SELECT:
15653         OperateOnSeqEntryConstrainedObjects (sep, fsp,
15654                                              SelectFeatureCallback,
15655                                              NULL, 0, feat_def_choice, 0, NULL);
15656         break;
15657       case FEATURE_DESELECT:
15658         OperateOnSeqEntryConstrainedObjects (sep, fsp,
15659                                              DeselectFeatureCallback,
15660                                              NULL, 0, feat_def_choice, 0, NULL);
15661         break;
15662     }
15663   }
15664 
15665   ValNodeFree (feature_type_list);
15666   FilterSetFree (fsp);
15667 
15668   if (window_action == FEATURE_REMOVE || window_action == FEATURE_CONVERT)
15669   {
15670     DeleteMarkedObjects (mrfp->input_entityID, 0, NULL);
15671   }
15672 
15673   if (window_action == FEATURE_CONVERT && mrfp->leave_original_feature)
15674   {
15675     for (vnp = mrfp->feat_list; vnp != NULL; vnp = vnp->next)
15676     {
15677       ofp = (OrigFeatPtr) vnp->data.ptrvalue;
15678       if (ofp == NULL || ofp->sep == NULL || ofp->sfp == NULL)
15679       {
15680         continue;
15681       }
15682       if (IS_Bioseq_set (ofp->sep)) {
15683         create_sep = FindNucSeqEntry (ofp->sep);
15684       } else {
15685         create_sep = ofp->sep;
15686       }
15687       sfp = CreateNewFeature (create_sep, NULL, ofp->sfp->data.choice, ofp->sfp);
15688     }
15689   }
15690   mrfp->feat_list = ValNodeFreeData (mrfp->feat_list);
15691 
15692   if (mrfp->renormalize_nucprot) {
15693     RenormalizeNucProtSets (sep, TRUE);
15694   }
15695 
15696   ObjMgrSetDirtyFlag (mrfp->input_entityID, TRUE);
15697   ObjMgrSendMsg (OM_MSG_UPDATE, mrfp->input_entityID, 0, 0);
15698   Update ();
15699   return rval;
15700 }
15701 
FeatureRemoveOrConvertBaseForm(BaseFormPtr bfp,Int4 first_action)15702 NLM_EXTERN void FeatureRemoveOrConvertBaseForm (BaseFormPtr bfp, Int4 first_action)
15703 {
15704   FeatureSelRemConvFormPtr mrfp;
15705   WindoW              w;
15706   GrouP               h, k, g, n;
15707   SeqEntryPtr         sep;
15708 
15709   if (bfp == NULL) return;
15710 
15711   mrfp = (FeatureSelRemConvFormPtr) MemNew (sizeof (FeatureSelRemConvFormData));
15712   if (mrfp == NULL) return;
15713 
15714   mrfp->bfp = bfp;
15715 
15716   w = FixedWindow (-50, -33, -10, -10, "Remove or Convert Features", StdCloseWindowProc);
15717   SetObjectExtra (w, mrfp, CleanupFeatureSelRemConvForm);
15718   mrfp->form = (ForM) w;
15719   mrfp->input_entityID = bfp->input_entityID;
15720 
15721   sep = GetTopSeqEntryForEntityID(bfp->input_entityID);
15722 
15723   h = HiddenGroup (w, -1, 0, NULL);
15724   SetGroupSpacing (h, 10, 10);
15725 
15726   if (first_action < FEATURE_REMOVE || first_action > FEATURE_DESELECT)
15727   {
15728     first_action = FEATURE_REMOVE;
15729   }
15730   mrfp->action_choice = PopupList (h, TRUE, FeatureRemoveOrConvertCenterAction);
15731   PopupItem (mrfp->action_choice, "Remove Features");
15732   PopupItem (mrfp->action_choice, "Convert Features");
15733   SetValue (mrfp->action_choice, first_action);
15734   SetObjectExtra (mrfp->action_choice, mrfp, NULL);
15735 
15736   mrfp->clear_constraints_on_action_change = CheckBox (h, "Clear when changing actions", NULL);
15737   SetStatus (mrfp->clear_constraints_on_action_change, TRUE);
15738 
15739   n = HiddenGroup (h, 0, 0, NULL);
15740   mrfp->remove_grp = HiddenGroup (n, 0, 1, NULL);
15741   mrfp->feature_select =  FeatureSelectionDialogEx (mrfp->remove_grp, TRUE, sep,
15742                                                   FeatureRemoveChangeNotify,
15743                                                   mrfp);
15744 
15745   mrfp->convert_grp = HiddenGroup (n, 3, 0, NULL);
15746   k = HiddenGroup (mrfp->convert_grp, 0, 2, NULL);
15747   mrfp->from_prompt = StaticPrompt (k, "From", 0, dialogTextHeight, systemFont, 'l');
15748   mrfp->feature_select_from =  FeatureSelectionDialogEx (k, FALSE, sep,
15749                                                   FeatureRemoveChangeNotify,
15750                                                   mrfp);
15751   AlignObjects (ALIGN_CENTER, (HANDLE) mrfp->from_prompt, (HANDLE) mrfp->feature_select_from, NULL);
15752   k = HiddenGroup (mrfp->convert_grp, 0, 2, NULL);
15753   mrfp->to_prompt = StaticPrompt (k, "To", 0, dialogTextHeight, systemFont, 'l');
15754   mrfp->feature_select_to =  FeatureSelectionDialog (k, FALSE,
15755                                                   FeatureRemoveChangeNotify,
15756                                                   mrfp);
15757   AlignObjects (ALIGN_CENTER, (HANDLE) mrfp->to_prompt, (HANDLE) mrfp->feature_select_to, NULL);
15758   AlignObjects (ALIGN_CENTER, (HANDLE) mrfp->remove_grp, (HANDLE) mrfp->convert_grp, NULL);
15759 
15760   g = HiddenGroup (mrfp->convert_grp, 0, 2, NULL);
15761   StaticPrompt (g, "Conversion Function", 0, dialogTextHeight, systemFont, 'c');
15762   SelectFont (systemFont);
15763   mrfp->help_text = DocumentPanel (g, stdCharWidth * 12, LineHeight () * (TALL_SELECTION_LIST + 1));
15764 
15765   mrfp->leave_original_feature_btn = CheckBox (mrfp->convert_grp, "Leave Original Feature", FeatureRemoveChangeButton);
15766   SetObjectExtra (mrfp->leave_original_feature_btn, mrfp, NULL);
15767   SetStatus (mrfp->leave_original_feature_btn, FALSE);
15768   AlignObjects (ALIGN_CENTER, (HANDLE) k, (HANDLE) mrfp->leave_original_feature_btn, NULL);
15769 
15770   mrfp->feat_list = NULL;
15771   mrfp->constraints = FilterGroup (h, TRUE, FALSE, TRUE, FALSE, TRUE, "Where feature text");
15772   mrfp->accept_cancel = AcceptCancelDialog (h, FeatureRemoveOrConvertAction, NULL, FeatureRemoveClear, FeatureRemoveClearText, (Pointer)mrfp, w);
15773   AlignObjects (ALIGN_CENTER, (HANDLE) mrfp->action_choice,
15774                               (HANDLE) mrfp->clear_constraints_on_action_change,
15775                               (HANDLE) n,
15776                               (HANDLE) mrfp->constraints,
15777                               (HANDLE) mrfp->accept_cancel, NULL);
15778 
15779   FeatureRemoveOrConvertCenterAction (mrfp->action_choice);
15780 
15781   Show (w);
15782 }
15783 
15784 
FeatureRemoveOrConvert(IteM i,Int4 first_action)15785 static void FeatureRemoveOrConvert (IteM i, Int4 first_action)
15786 {
15787   BaseFormPtr         bfp;
15788 
15789 #ifdef WIN_MAC
15790   bfp = currentFormDataPtr;
15791 #else
15792   bfp = GetObjectExtra (i);
15793 #endif
15794   FeatureRemoveOrConvertBaseForm (bfp, first_action);
15795 }
15796 
15797 
FeatureRemove(IteM i)15798 extern void FeatureRemove (IteM i)
15799 {
15800   FeatureRemoveOrConvert (i, FEATURE_REMOVE);
15801 }
15802 
ConvertFeatures(IteM i)15803 extern void ConvertFeatures (IteM i)
15804 {
15805   FeatureRemoveOrConvert (i, FEATURE_CONVERT);
15806 }
15807 
SelectFeatureAction(Pointer userdata)15808 static Boolean SelectFeatureAction (Pointer userdata)
15809 {
15810   FeatureSelRemConvFormPtr   mrfp;
15811   FilterSetPtr          fsp;
15812   SeqEntryPtr           sep;
15813   ValNodePtr            feature_type_list, vnp;
15814   Uint1                 feat_def_choice;
15815 
15816   if (userdata == NULL) return FALSE;
15817 
15818   mrfp = (FeatureSelRemConvFormPtr) userdata;
15819   fsp = (FilterSetPtr) DialogToPointer (mrfp->constraints);
15820 
15821   sep = GetTopSeqEntryForEntityID (mrfp->input_entityID);
15822   if (sep == NULL) return FALSE;
15823 
15824   feature_type_list = (ValNodePtr) DialogToPointer (mrfp->feature_select);
15825   if (feature_type_list == NULL)
15826   {
15827     FilterSetFree (fsp);
15828     return FALSE;
15829   }
15830 
15831   for (vnp = feature_type_list; vnp != NULL; vnp = vnp->next)
15832   {
15833     feat_def_choice = vnp->choice;
15834     if (feat_def_choice == 255)
15835     {
15836       feat_def_choice = 0;
15837     }
15838     OperateOnSeqEntryConstrainedObjects (sep, fsp,
15839                                          SelectFeatureCallback,
15840                                          NULL, 0, feat_def_choice, 0, NULL);
15841   }
15842 
15843   ValNodeFree (feature_type_list);
15844   FilterSetFree (fsp);
15845 
15846   ObjMgrSetDirtyFlag (mrfp->input_entityID, TRUE);
15847   ObjMgrSendMsg (OM_MSG_UPDATE, mrfp->input_entityID, 0, 0);
15848   Update ();
15849   return TRUE;
15850 }
15851 
SelectFeatures(IteM i)15852 extern void SelectFeatures (IteM i)
15853 {
15854   BaseFormPtr              bfp;
15855   FeatureSelRemConvFormPtr mrfp;
15856   WindoW                   w;
15857   GrouP                    h;
15858   SeqEntryPtr              sep;
15859 
15860 #ifdef WIN_MAC
15861   bfp = currentFormDataPtr;
15862 #else
15863   bfp = GetObjectExtra (i);
15864 #endif
15865   if (bfp == NULL) return;
15866 
15867   mrfp = (FeatureSelRemConvFormPtr) MemNew (sizeof (FeatureSelRemConvFormData));
15868   if (mrfp == NULL) return;
15869 
15870   w = FixedWindow (-50, -33, -10, -10, "Select Features", StdCloseWindowProc);
15871   SetObjectExtra (w, mrfp, CleanupFeatureSelRemConvForm);
15872   mrfp->form = (ForM) w;
15873   mrfp->input_entityID = bfp->input_entityID;
15874   sep = GetTopSeqEntryForEntityID(bfp->input_entityID);
15875 
15876   h = HiddenGroup (w, -1, 0, NULL);
15877   SetGroupSpacing (h, 10, 10);
15878 
15879   mrfp->feature_select =  FeatureSelectionDialogEx (h, TRUE, sep,
15880                                                   FeatureRemoveChangeNotify,
15881                                                   mrfp);
15882 
15883   mrfp->constraints = FilterGroup (h, TRUE, FALSE, TRUE, FALSE, FALSE, "Where feature text");
15884   mrfp->accept_cancel = AcceptCancelDialog (h, SelectFeatureAction, NULL, FeatureRemoveClear, FeatureRemoveClearText, (Pointer)mrfp, w);
15885   AlignObjects (ALIGN_CENTER, (HANDLE) mrfp->feature_select,
15886                               (HANDLE) mrfp->constraints,
15887                               (HANDLE) mrfp->accept_cancel, NULL);
15888 
15889   Show (w);
15890 }
15891 
15892 
15893 typedef struct reverseintervalsform
15894 {
15895   FORM_MESSAGE_BLOCK
15896   DialoG  feature_select;
15897   DialoG  constraints;
15898   DialoG  accept_cancel;
15899 
15900   ValNodePtr feat_list;
15901   BaseFormPtr bfp;
15902 } ReverseIntervalsFormData, PNTR ReverseIntervalsFormPtr;
15903 
ReverseIntervalsChangeNotify(Pointer userdata)15904 static void ReverseIntervalsChangeNotify (Pointer userdata)
15905 {
15906   ReverseIntervalsFormPtr fp;
15907   ValNodePtr          err_list;
15908 
15909   fp = (ReverseIntervalsFormPtr) userdata;
15910   if (fp == NULL) return;
15911 
15912   err_list = TestDialog (fp->feature_select);
15913 
15914   if (err_list == NULL)
15915   {
15916     EnableAcceptCancelDialogAccept (fp->accept_cancel);
15917   }
15918   else
15919   {
15920     DisableAcceptCancelDialogAccept (fp->accept_cancel);
15921   }
15922   ValNodeFree (err_list);
15923 }
15924 
ReverseIntervalsClearText(Pointer data)15925 static void ReverseIntervalsClearText (Pointer data)
15926 {
15927   ReverseIntervalsFormPtr   mrfp;
15928   FilterSetPtr          fsp;
15929 
15930   mrfp = (ReverseIntervalsFormPtr) data;
15931   if (mrfp == NULL) return;
15932 
15933   fsp = DialogToPointer (mrfp->constraints);
15934   FilterSetClearText (fsp);
15935   PointerToDialog (mrfp->constraints, fsp);
15936   FilterSetFree (fsp);
15937 }
15938 
ReverseIntervalsClear(Pointer data)15939 static void ReverseIntervalsClear (Pointer data)
15940 {
15941   ReverseIntervalsFormPtr mrfp;
15942 
15943   mrfp = (ReverseIntervalsFormPtr) data;
15944   if (mrfp == NULL) return;
15945 
15946   PointerToDialog (mrfp->feature_select, NULL);
15947   PointerToDialog (mrfp->constraints, NULL);
15948 }
15949 
ReverseLocationIntervalOrder(SeqLocPtr slp)15950 static void ReverseLocationIntervalOrder (SeqLocPtr slp)
15951 {
15952   SeqLocPtr     subslp_list = NULL, subslp, subslp_next;
15953   PackSeqPntPtr pspp;
15954   Int4 pnt_num, swap;
15955 
15956   if (slp == NULL
15957       || slp->choice == SEQLOC_NULL
15958       || slp->choice == SEQLOC_EMPTY
15959       || slp->choice == SEQLOC_WHOLE
15960       || slp->choice == SEQLOC_INT
15961       || slp->choice == SEQLOC_PNT
15962       || slp->choice == SEQLOC_BOND
15963       || slp->choice == SEQLOC_FEAT) {
15964     return;
15965   }
15966   if (slp->choice == SEQLOC_MIX
15967       || slp->choice == SEQLOC_PACKED_INT
15968       || slp->choice == SEQLOC_EQUIV) {
15969     for (subslp = slp->data.ptrvalue;
15970          subslp != NULL;
15971          subslp = subslp_next) {
15972       subslp_next = subslp->next;
15973       subslp->next = subslp_list;
15974       subslp_list = subslp;
15975       ReverseLocationIntervalOrder (subslp);
15976     }
15977     slp->data.ptrvalue = subslp_list;
15978   } else if (slp->choice == SEQLOC_PACKED_PNT) {
15979     pspp = (PackSeqPntPtr) slp->data.ptrvalue;
15980     if (pspp != NULL) {
15981       for (pnt_num = 0; pnt_num < pspp->used / 2; pnt_num++) {
15982         swap = pspp->pnts[pnt_num];
15983         pspp->pnts[pnt_num] = pspp->pnts[pspp->used - 1 - pnt_num];
15984         pspp->pnts[pspp->used - 1 - pnt_num] = swap;
15985       }
15986     }
15987   }
15988 }
15989 
ReverseIntervalsCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)15990 static void ReverseIntervalsCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
15991 
15992 {
15993   if (sfp == NULL || sfp->location == NULL) return;
15994 
15995   ReverseLocationIntervalOrder (sfp->location);
15996 }
15997 
15998 
ReverseIntervalsAction(Pointer userdata)15999 static Boolean ReverseIntervalsAction (Pointer userdata)
16000 {
16001   ReverseIntervalsFormPtr   mrfp;
16002   FilterSetPtr          fsp;
16003   SeqEntryPtr           sep;
16004   ValNodePtr            feature_type_list, vnp;
16005   Uint1                 feat_def_choice;
16006 
16007   if (userdata == NULL) return FALSE;
16008 
16009   mrfp = (ReverseIntervalsFormPtr) userdata;
16010   fsp = (FilterSetPtr) DialogToPointer (mrfp->constraints);
16011 
16012   sep = GetTopSeqEntryForEntityID (mrfp->input_entityID);
16013   if (sep == NULL) return FALSE;
16014 
16015   feature_type_list = (ValNodePtr) DialogToPointer (mrfp->feature_select);
16016   if (feature_type_list == NULL)
16017   {
16018     FilterSetFree (fsp);
16019     return FALSE;
16020   }
16021 
16022   for (vnp = feature_type_list; vnp != NULL; vnp = vnp->next)
16023   {
16024     feat_def_choice = vnp->choice;
16025     if (feat_def_choice == 255)
16026     {
16027       feat_def_choice = 0;
16028     }
16029     OperateOnSeqEntryConstrainedObjects (sep, fsp,
16030                                          ReverseIntervalsCallback,
16031                                          NULL, 0, feat_def_choice, 0, NULL);
16032   }
16033 
16034   ValNodeFree (feature_type_list);
16035   FilterSetFree (fsp);
16036 
16037   ObjMgrSetDirtyFlag (mrfp->input_entityID, TRUE);
16038   ObjMgrSendMsg (OM_MSG_UPDATE, mrfp->input_entityID, 0, 0);
16039   Update ();
16040   return TRUE;
16041 }
16042 
ReverseFeatureIntervals(IteM i)16043 extern void ReverseFeatureIntervals (IteM i)
16044 {
16045   BaseFormPtr              bfp;
16046   ReverseIntervalsFormPtr  fp;
16047   WindoW                   w;
16048   GrouP                    h;
16049   SeqEntryPtr              sep;
16050 
16051 #ifdef WIN_MAC
16052   bfp = currentFormDataPtr;
16053 #else
16054   bfp = GetObjectExtra (i);
16055 #endif
16056   if (bfp == NULL) return;
16057 
16058   fp = (ReverseIntervalsFormPtr) MemNew (sizeof (ReverseIntervalsFormData));
16059   if (fp == NULL) return;
16060 
16061   w = FixedWindow (-50, -33, -10, -10, "Reverse Feature Intervals", StdCloseWindowProc);
16062   SetObjectExtra (w, fp, StdCleanupFormProc);
16063   fp->form = (ForM) w;
16064   fp->input_entityID = bfp->input_entityID;
16065   sep = GetTopSeqEntryForEntityID(bfp->input_entityID);
16066 
16067   h = HiddenGroup (w, -1, 0, NULL);
16068   SetGroupSpacing (h, 10, 10);
16069 
16070   fp->feature_select =  FeatureSelectionDialogEx (h, TRUE, sep,
16071                                                   ReverseIntervalsChangeNotify,
16072                                                   fp);
16073 
16074   fp->constraints = FilterGroup (h, TRUE, FALSE, TRUE, FALSE, FALSE, "Where feature text");
16075   fp->accept_cancel = AcceptCancelDialog (h, ReverseIntervalsAction, NULL, ReverseIntervalsClear, ReverseIntervalsClearText, (Pointer)fp, w);
16076   AlignObjects (ALIGN_CENTER, (HANDLE) fp->feature_select,
16077                               (HANDLE) fp->constraints,
16078                               (HANDLE) fp->accept_cancel, NULL);
16079 
16080   Show (w);
16081 }
16082 
16083 
16084 
ParseFieldFree(ParseFieldPtr pfp)16085 extern ParseFieldPtr ParseFieldFree (ParseFieldPtr pfp)
16086 {
16087   if (pfp != NULL)
16088   {
16089     switch (pfp->parse_field_type) {
16090       case PARSE_FIELD_SOURCE_QUAL :
16091       case PARSE_FIELD_FEATURE_NOTE:
16092       case PARSE_FIELD_DBXREF:
16093         pfp->feature_field = ValNodeFreeData (pfp->feature_field);
16094         break;
16095       case PARSE_FIELD_DEFLINE:
16096       case PARSE_FIELD_BIOSRC_STRING:
16097       case PARSE_FIELD_GENE_FIELD:
16098       case PARSE_FIELD_RNA_FIELD:
16099       case PARSE_FIELD_CDS_COMMENT:
16100       case PARSE_FIELD_COMMENT_DESC:
16101       case PARSE_FIELD_IMPORT_QUAL:
16102       case PARSE_FIELD_PROTEIN_FIELD:
16103         pfp->feature_field = ValNodeFree (pfp->feature_field);
16104         break;
16105       default:
16106         pfp->feature_field = ValNodeFree (pfp->feature_field);
16107     }
16108 
16109     if (pfp->parse_field_type == PARSE_FIELD_RNA_FIELD)
16110     {
16111       pfp->feature_subtype = ValNodeFree (pfp->feature_subtype);
16112     }
16113     else
16114     {
16115       pfp->feature_subtype = ValNodeFreeData (pfp->feature_subtype);
16116     }
16117     pfp = MemFree (pfp);
16118   }
16119   return pfp;
16120 }
16121 
16122 
16123 #define AECR_APPLY   1
16124 #define AECR_EDIT    2
16125 #define AECR_CONVERT 3
16126 #define AECR_SWAP    4
16127 #define AECR_PARSE   5
16128 #define AECR_REMOVE  6
16129 #define NUM_AECR     6
16130 
16131 
FeatureEditor(IteM i,Int4 first_action)16132 static void FeatureEditor (IteM i, Int4 first_action)
16133 {
16134   BaseFormPtr     bfp;
16135 
16136 #ifdef WIN_MAC
16137   bfp = currentFormDataPtr;
16138 #else
16139   bfp = GetObjectExtra (i);
16140 #endif
16141   if (bfp == NULL) return;
16142   FeatureEditorBaseForm (bfp, first_action);
16143 }
16144 
16145 
FeatureEvidenceEditor(IteM i)16146 extern void FeatureEvidenceEditor (IteM i)
16147 {
16148   FeatureEditor(i, FEAT_ED_EVIDENCE);
16149 }
16150 
FeatureExceptionEditor(IteM i)16151 extern void FeatureExceptionEditor (IteM i)
16152 {
16153   FeatureEditor(i, FEAT_ED_EXCEPTION);
16154 }
16155 
FeaturePartialEditor(IteM i)16156 extern void FeaturePartialEditor (IteM i)
16157 {
16158   FeatureEditor(i, FEAT_ED_PARTIAL);
16159 }
16160 
FeatureStrandEditor(IteM i)16161 extern void FeatureStrandEditor (IteM i)
16162 {
16163   FeatureEditor(i, FEAT_ED_STRAND);
16164 }
16165 
FeatureCitationEditor(IteM i)16166 extern void FeatureCitationEditor (IteM i)
16167 {
16168   FeatureEditor(i, FEAT_ED_CITATION);
16169 }
16170 
FeatureExperimentEditor(IteM i)16171 extern void FeatureExperimentEditor (IteM i)
16172 {
16173   FeatureEditor(i, FEAT_ED_EXPERIMENT);
16174 }
16175 
FeatureInferenceEditor(IteM i)16176 extern void FeatureInferenceEditor (IteM i)
16177 {
16178   FeatureEditor(i, FEAT_ED_INFERENCE);
16179 }
16180 
FeaturePseudoEditor(IteM i)16181 extern void FeaturePseudoEditor (IteM i)
16182 {
16183   FeatureEditor (i, FEAT_ED_PSEUDO);
16184 }
16185 
16186 typedef struct cdset
16187 {
16188   ValNodePtr cds_list;
16189   ValNodePtr gene_list;
16190   ValNodePtr prot_list;
16191   ValNodePtr mrna_list;
16192 } CDSetData, PNTR CDSetPtr;
16193 
FreeCDSetList(ValNodePtr vnp)16194 static ValNodePtr FreeCDSetList (ValNodePtr vnp)
16195 {
16196   CDSetPtr cdsp;
16197 
16198   if (vnp != NULL)
16199   {
16200     FreeCDSetList (vnp->next);
16201     vnp->next = NULL;
16202     cdsp = (CDSetPtr) vnp->data.ptrvalue;
16203     if (cdsp != NULL)
16204     {
16205       cdsp->cds_list = ValNodeFree (cdsp->cds_list);
16206       cdsp->gene_list = ValNodeFree (cdsp->gene_list);
16207       cdsp->prot_list = ValNodeFree (cdsp->prot_list);
16208       cdsp->mrna_list = ValNodeFree (cdsp->mrna_list);
16209     }
16210     ValNodeFreeData (vnp);
16211   }
16212   return NULL;
16213 }
16214 
GetCDSGeneProtFieldName(ValNodePtr vnp)16215 extern CharPtr GetCDSGeneProtFieldName (ValNodePtr vnp)
16216 {
16217   CharPtr PNTR      field_name_list = NULL;
16218   Int4              num_fields = 0;
16219   CharPtr           label = NULL;
16220 
16221   field_name_list = BuildCDSGeneFieldList (&num_fields);
16222   if (field_name_list != NULL
16223       && vnp->data.intvalue > 0 && vnp->data.intvalue <= num_fields)
16224   {
16225     label = StringSave (field_name_list [vnp->data.intvalue - 1]);
16226   }
16227   FreeCDSGeneFieldList (field_name_list, num_fields);
16228   return label;
16229 }
16230 
GetCDSGeneProtSample(GrouP h,Uint2 entityID)16231 static DialoG GetCDSGeneProtSample (GrouP h, Uint2 entityID)
16232 {
16233   CharPtr PNTR      field_name_list = NULL;
16234   Int4              num_fields = 0, i;
16235   DialoG            d = NULL;
16236   SetSampleData     ssd;
16237 
16238   field_name_list = BuildCDSGeneFieldList (&num_fields);
16239   if (field_name_list != NULL)
16240   {
16241     ssd.entityID = entityID;
16242     ssd.field_list = NULL;
16243     for (i = 0; i < num_fields; i++)
16244     {
16245       ValNodeAddInt (&ssd.field_list, 0, i + 1);
16246     }
16247     ssd.fieldstring_func = GetCDSGeneProtField;
16248     ssd.descrstring_func = NULL;
16249     ssd.fsp = NULL;
16250     ssd.free_vn_proc = NULL;
16251     ssd.copy_vn_proc = IntValNodeCopy;
16252     ssd.match_vn_proc = IntValNodeMatch;
16253     ssd.label_vn_proc = GetCDSGeneProtFieldName;
16254 
16255 
16256     d = SampleDialog (h);
16257     PointerToDialog (d, &ssd);
16258     FreeCDSGeneFieldList (field_name_list, num_fields);
16259   }
16260   return d;
16261 }
16262 
16263 
16264 typedef struct buildcdset2
16265 {
16266   ValNodePtr cds_list;
16267   ValNodePtr mrna_list;
16268   ValNodePtr gene_list;
16269 } BuildCDSet2Data, PNTR BuildCDSet2Ptr;
16270 
BuildCDSet2Callback(SeqFeatPtr sfp,Pointer userdata)16271 static void BuildCDSet2Callback (SeqFeatPtr sfp, Pointer userdata)
16272 {
16273   BuildCDSet2Ptr b;
16274 
16275   if (sfp == NULL || sfp->idx.deleteme || userdata == NULL) return;
16276   b = (BuildCDSet2Ptr) userdata;
16277   if (sfp->data.choice == SEQFEAT_CDREGION)
16278   {
16279     ValNodeAddPointer (&(b->cds_list), OBJ_SEQFEAT, sfp);
16280   }
16281   else if (sfp->data.choice == SEQFEAT_GENE)
16282   {
16283     ValNodeAddPointer (&(b->gene_list), OBJ_SEQFEAT, sfp);
16284   }
16285   else if (sfp->idx.subtype == FEATDEF_mRNA)
16286   {
16287     ValNodeAddPointer (&(b->mrna_list), OBJ_SEQFEAT, sfp);
16288   }
16289   else if (SeqMgrGetGeneXref (sfp) != NULL)
16290   {
16291     ValNodeAddPointer (&(b->gene_list), OBJ_SEQFEAT, sfp);
16292   }
16293 }
16294 
16295 
UnmarkFeatureList(ValNodePtr list)16296 static void UnmarkFeatureList (ValNodePtr list)
16297 {
16298   SeqFeatPtr sfp;
16299 
16300   while (list != NULL)
16301   {
16302     sfp = list->data.ptrvalue;
16303     if (sfp != NULL)
16304     {
16305       sfp->idx.deleteme = FALSE;
16306     }
16307     list = list->next;
16308   }
16309 }
16310 
16311 
GetGeneForCDSetFeature(SeqFeatPtr sfp)16312 static SeqFeatPtr GetGeneForCDSetFeature (SeqFeatPtr sfp)
16313 {
16314   GeneRefPtr        grp;
16315   SeqFeatPtr        gene = NULL;
16316   SeqMgrFeatContext fcontext;
16317 
16318   grp = SeqMgrGetGeneXref (sfp);
16319   if (grp == NULL)
16320   {
16321     gene = SeqMgrGetOverlappingGene (sfp->location, &fcontext);
16322   }
16323   else if (!SeqMgrGeneIsSuppressed (grp))
16324   {
16325     if (!StringHasNoText (grp->locus_tag))
16326     {
16327       gene = SeqMgrGetGeneByLocusTag (BioseqFindFromSeqLoc (sfp->location), grp->locus_tag, &fcontext);
16328     }
16329   }
16330   return gene;
16331 }
16332 
16333 
BuildCDSetFromCodingRegion(SeqFeatPtr cds,BoolPtr indexing_needed)16334 static CDSetPtr BuildCDSetFromCodingRegion (SeqFeatPtr cds, BoolPtr indexing_needed)
16335 {
16336   SeqMgrFeatContext fcontext;
16337   SeqFeatPtr        gene = NULL, mrna, prot;
16338   BioseqPtr         protbsp;
16339   CDSetPtr          cdsp;
16340   ProtRefPtr        prp;
16341 
16342   if (cds == NULL || cds->data.choice != SEQFEAT_CDREGION) return NULL;
16343 
16344   cdsp = (CDSetPtr) MemNew (sizeof (CDSetData));
16345   ValNodeAddPointer (&(cdsp->cds_list), 0, cds);
16346 
16347   gene = GetGeneForCDSetFeature (cds);
16348   if (gene != NULL)
16349   {
16350     ValNodeAddPointer (&(cdsp->gene_list), 0, gene);
16351     /* mark gene, so that we'll know it isn't lonely */
16352     gene->idx.deleteme = TRUE;
16353   }
16354 
16355   mrna = SeqMgrGetOverlappingmRNA (cds->location, &fcontext);
16356   if (mrna != NULL)
16357   {
16358     ValNodeAddPointer (&(cdsp->mrna_list), 0, mrna);
16359     /* mark mrna, so that we'll know it's already in a set */
16360     mrna->idx.deleteme = TRUE;
16361   }
16362 
16363   if (cds->product != NULL)
16364   {
16365     protbsp = BioseqFindFromSeqLoc (cds->product);
16366     if (protbsp != NULL)
16367     {
16368       prot = SeqMgrGetNextFeature (protbsp, NULL, SEQFEAT_PROT, FEATDEF_PROT, &fcontext);
16369       /* if there is no full-length protein feature, make one */
16370       if (prot == NULL)
16371       {
16372         prp = ProtRefNew ();
16373         prot = CreateNewFeatureOnBioseq (protbsp, SEQFEAT_PROT, NULL);
16374         if (prot != NULL)
16375         {
16376           prot->data.value.ptrvalue = prp;
16377           if (indexing_needed != NULL)
16378           {
16379             *indexing_needed = TRUE;
16380           }
16381         }
16382       }
16383       if (prot != NULL)
16384       {
16385         ValNodeAddPointer (&(cdsp->prot_list), 0, prot);
16386       }
16387 
16388       /* also add in mat_peptides from protein feature */
16389       prot = SeqMgrGetNextFeature (protbsp, NULL, SEQFEAT_PROT, FEATDEF_mat_peptide_aa, &fcontext);
16390       while (prot != NULL)
16391       {
16392         ValNodeAddPointer (&(cdsp->prot_list), 0, prot);
16393         prot = SeqMgrGetNextFeature (protbsp, prot, SEQFEAT_PROT, FEATDEF_mat_peptide_aa, &fcontext);
16394       }
16395     }
16396   }
16397   return cdsp;
16398 }
16399 
16400 
BuildCDSetFrommRNA(SeqFeatPtr mrna)16401 static CDSetPtr BuildCDSetFrommRNA (SeqFeatPtr mrna)
16402 {
16403   SeqFeatPtr        gene;
16404   CDSetPtr          cdsp;
16405 
16406   if (mrna == NULL || mrna->idx.deleteme || mrna->idx.subtype != FEATDEF_mRNA) return NULL;
16407 
16408   cdsp = (CDSetPtr) MemNew (sizeof (CDSetData));
16409   ValNodeAddPointer (&(cdsp->mrna_list), 0, mrna);
16410 
16411   gene = GetGeneForCDSetFeature (mrna);
16412   if (gene != NULL)
16413   {
16414     ValNodeAddPointer (&(cdsp->gene_list), 0, gene);
16415     /* mark gene, so that we'll know it isn't lonely */
16416     gene->idx.deleteme = TRUE;
16417   }
16418 
16419   return cdsp;
16420 }
16421 
16422 
16423 static Boolean DoesCDSetMatchConstraint (CDSetPtr cdsp, ChoiceConstraintPtr ccp);
16424 
BuildCDSet2List(Uint2 entityID,ChoiceConstraintPtr ccp)16425 static ValNodePtr BuildCDSet2List (Uint2 entityID, ChoiceConstraintPtr  ccp)
16426 {
16427   SeqEntryPtr    sep;
16428   BuildCDSet2Data b;
16429   CDSetPtr       cdsp;
16430   ValNodePtr     vnp, vnp_next, vnp_prev;
16431   ValNodePtr     cdset_list = NULL;
16432   SeqFeatPtr     cds, gene, mrna;
16433   Boolean        need_indexing = FALSE;
16434 
16435   sep = GetTopSeqEntryForEntityID (entityID);
16436 
16437   b.cds_list = NULL;
16438   b.gene_list = NULL;
16439   b.mrna_list = NULL;
16440 
16441   VisitFeaturesInSep (sep, &b, BuildCDSet2Callback);
16442 
16443   /* build cdsets that have coding regions */
16444   for (vnp = b.cds_list; vnp != NULL; vnp = vnp->next)
16445   {
16446     cds = (SeqFeatPtr) vnp->data.ptrvalue;
16447     if (cds == NULL) continue;
16448     cdsp = BuildCDSetFromCodingRegion (cds, &need_indexing);
16449     if (cdsp != NULL)
16450     {
16451       ValNodeAddPointer (&cdset_list, 0, cdsp);
16452     }
16453   }
16454   if (need_indexing)
16455   {
16456     /* indexing because we have created full-length protein features */
16457     SeqMgrIndexFeatures (entityID, NULL);
16458   }
16459 
16460   /* build cdsets for mrna features that don't have coding regions */
16461   for (vnp = b.mrna_list; vnp != NULL; vnp = vnp->next)
16462   {
16463     mrna = (SeqFeatPtr) vnp->data.ptrvalue;
16464     if (mrna == NULL || mrna->idx.deleteme) continue;
16465     cdsp = BuildCDSetFrommRNA (mrna);
16466     if (cdsp != NULL)
16467     {
16468       ValNodeAddPointer (&cdset_list, 0, cdsp);
16469     }
16470   }
16471 
16472   /* build cdsets for lonely genes / features with gene xrefs that are not coding regions or mrnas */
16473   for (vnp = b.gene_list; vnp != NULL; vnp = vnp->next)
16474   {
16475     gene = (SeqFeatPtr) vnp->data.ptrvalue;
16476     if (gene == NULL || gene->idx.deleteme) continue;
16477     cdsp = (CDSetPtr) MemNew (sizeof (CDSetData));
16478     ValNodeAddPointer (&(cdsp->gene_list), 0, gene);
16479     ValNodeAddPointer (&cdset_list, 0, cdsp);
16480   }
16481 
16482   /* now unmark features */
16483   UnmarkFeatureList (b.cds_list);
16484   UnmarkFeatureList (b.mrna_list);
16485   UnmarkFeatureList (b.gene_list);
16486 
16487   b.cds_list = ValNodeFree (b.cds_list);
16488   b.mrna_list = ValNodeFree (b.mrna_list);
16489   b.gene_list = ValNodeFree (b.gene_list);
16490 
16491   /* now remove sets that don't match our choice constraint */
16492   vnp_prev = NULL;
16493   for (vnp = cdset_list; vnp != NULL; vnp = vnp_next)
16494   {
16495     vnp_next = vnp->next;
16496     if (!DoesCDSetMatchConstraint (vnp->data.ptrvalue, ccp))
16497     {
16498       if (vnp_prev == NULL)
16499       {
16500         cdset_list = vnp->next;
16501       }
16502       else
16503       {
16504         vnp_prev->next = vnp->next;
16505       }
16506       vnp->next = NULL;
16507       FreeCDSetList (vnp);
16508     }
16509     else
16510     {
16511       vnp_prev = vnp;
16512     }
16513   }
16514 
16515   return cdset_list;
16516 }
16517 
16518 typedef struct buildcdset
16519 {
16520   ValNodePtr cdset_list;
16521   ValNodePtr lonely_gene_list;
16522 } BuildCDSetData, PNTR BuildCDSetPtr;
16523 
16524 
GetCDSetField(CDSetPtr cdsp,ValNodePtr vnp)16525 static CharPtr GetCDSetField (CDSetPtr cdsp, ValNodePtr vnp)
16526 {
16527   ValNodePtr sfp_vnp;
16528   CharPtr    str = NULL;
16529 
16530   if (cdsp == NULL || vnp == NULL)
16531   {
16532     return NULL;
16533   }
16534 
16535   for (sfp_vnp = cdsp->cds_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16536   {
16537     str = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, NULL);
16538   }
16539   for (sfp_vnp = cdsp->gene_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16540   {
16541     str = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, NULL);
16542   }
16543   for (sfp_vnp = cdsp->prot_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16544   {
16545     str = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, NULL);
16546   }
16547   for (sfp_vnp = cdsp->mrna_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16548   {
16549     str = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, NULL);
16550   }
16551   return str;
16552 }
16553 
SetCDSetField(CDSetPtr cdsp,ValNodePtr vnp,ApplyValuePtr avp,FilterSetPtr fsp)16554 static Boolean SetCDSetField (CDSetPtr cdsp, ValNodePtr vnp, ApplyValuePtr avp, FilterSetPtr fsp)
16555 {
16556   ValNodePtr sfp_vnp;
16557   Boolean    rval = FALSE;
16558 
16559   if (cdsp == NULL || vnp == NULL || avp == NULL)
16560   {
16561     return FALSE;
16562   }
16563 
16564   for (sfp_vnp = cdsp->cds_list; sfp_vnp != NULL ; sfp_vnp = sfp_vnp->next)
16565   {
16566     rval |= SetCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, avp, fsp);
16567   }
16568   for (sfp_vnp = cdsp->gene_list; sfp_vnp != NULL; sfp_vnp = sfp_vnp->next)
16569   {
16570     if (sfp_vnp->choice == 0) /* don't set again if already set */
16571     {
16572       rval |= SetCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, avp, fsp);
16573     }
16574   }
16575   for (sfp_vnp = cdsp->prot_list; sfp_vnp != NULL; sfp_vnp = sfp_vnp->next)
16576   {
16577     rval |= SetCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, avp, fsp);
16578   }
16579   for (sfp_vnp = cdsp->mrna_list; sfp_vnp != NULL; sfp_vnp = sfp_vnp->next)
16580   {
16581     rval |= SetCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, avp, fsp);
16582   }
16583   return rval;
16584 }
16585 
RemoveCDSetField(CDSetPtr cdsp,ValNodePtr vnp,FilterSetPtr fsp)16586 static void RemoveCDSetField (CDSetPtr cdsp, ValNodePtr vnp, FilterSetPtr fsp)
16587 {
16588   ValNodePtr sfp_vnp;
16589   CharPtr    str = NULL;
16590 
16591   if (cdsp == NULL || vnp == NULL)
16592   {
16593     return;
16594   }
16595 
16596   for (sfp_vnp = cdsp->cds_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16597   {
16598     RemoveCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, fsp);
16599   }
16600   for (sfp_vnp = cdsp->gene_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16601   {
16602     RemoveCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, fsp);
16603   }
16604   for (sfp_vnp = cdsp->prot_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16605   {
16606     RemoveCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, fsp);
16607   }
16608   for (sfp_vnp = cdsp->mrna_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16609   {
16610     RemoveCDSGeneProtField (sfp_vnp->data.ptrvalue, vnp, fsp);
16611   }
16612 }
16613 
GetCDSetPseudoMatch(CDSetPtr cdsp,Int4 featdef_type,Boolean is_pseudo)16614 static Boolean GetCDSetPseudoMatch (CDSetPtr cdsp, Int4 featdef_type, Boolean is_pseudo)
16615 {
16616   ValNodePtr sfp_vnp;
16617   CharPtr    str = NULL;
16618   SeqFeatPtr sfp;
16619   GeneRefPtr grp;
16620   Boolean    gene_is_pseudo;
16621 
16622   if (cdsp == NULL)
16623   {
16624     return FALSE;
16625   }
16626 
16627   if (featdef_type == FEATDEF_CDS || featdef_type == FEATDEF_ANY)
16628   {
16629     for (sfp_vnp = cdsp->cds_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16630     {
16631       sfp = sfp_vnp->data.ptrvalue;
16632       if (sfp != NULL && ((is_pseudo && sfp->pseudo) || (!is_pseudo && ! sfp->pseudo)))
16633       {
16634         return TRUE;
16635       }
16636     }
16637   }
16638   if (featdef_type == FEATDEF_GENE || featdef_type == FEATDEF_ANY)
16639   {
16640     for (sfp_vnp = cdsp->gene_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16641     {
16642       sfp = sfp_vnp->data.ptrvalue;
16643       if (sfp != NULL)
16644       {
16645         gene_is_pseudo = FALSE;
16646         if (sfp->pseudo)
16647         {
16648           gene_is_pseudo = TRUE;
16649         }
16650         if (sfp->data.choice == SEQFEAT_GENE)
16651         {
16652           grp = (GeneRefPtr) sfp->data.value.ptrvalue;
16653           if (grp != NULL && grp->pseudo)
16654           {
16655             gene_is_pseudo = TRUE;
16656           }
16657         }
16658         if ((is_pseudo && gene_is_pseudo) || (!is_pseudo && ! gene_is_pseudo))
16659         {
16660           return TRUE;
16661         }
16662       }
16663     }
16664   }
16665   if (featdef_type == FEATDEF_mRNA || featdef_type == FEATDEF_ANY)
16666   {
16667     for (sfp_vnp = cdsp->mrna_list; sfp_vnp != NULL && str == NULL; sfp_vnp = sfp_vnp->next)
16668     {
16669       sfp = sfp_vnp->data.ptrvalue;
16670       if (sfp != NULL && ((is_pseudo && sfp->pseudo) || (!is_pseudo && ! sfp->pseudo)))
16671       {
16672         return TRUE;
16673       }
16674     }
16675   }
16676   return FALSE;
16677 }
16678 
DoCDSFieldsMatch(CDSetPtr cdsp,ValNodePtr qual_choice,ValNodePtr qual_choice_match)16679 static Boolean DoCDSFieldsMatch (CDSetPtr cdsp, ValNodePtr qual_choice, ValNodePtr qual_choice_match)
16680 {
16681   CharPtr str1, str2;
16682   Int4    field_choice, field_choice2;
16683   ValNode field_vn, field_vn2;
16684   Boolean does_match = FALSE;
16685 
16686   if (qual_choice == NULL && qual_choice_match == NULL)
16687   {
16688     /* both are wildcards */
16689     field_vn.next = NULL;
16690     field_vn.choice = 0;
16691     field_vn2.next = NULL;
16692     field_vn2.choice = 0;
16693 
16694     for (field_choice = 1;
16695          ! does_match && field_choice < num_gene_fields + num_mrna_fields + num_protein_fields;
16696          field_choice++)
16697     {
16698       field_vn.data.intvalue = field_choice;
16699       str1 = GetCDSetField (cdsp, &field_vn);
16700       if (!StringHasNoText (str1)) {
16701         for (field_choice2 = field_choice + 1;
16702              ! does_match && field_choice2 < 1 + num_gene_fields + num_mrna_fields + num_protein_fields;
16703              field_choice2++)
16704         {
16705           field_vn2.data.intvalue = field_choice2;
16706           str2 = GetCDSetField (cdsp, &field_vn2);
16707           if (StringCmp (str1, str2) == 0)
16708           {
16709             does_match = TRUE;
16710           }
16711           str2 = MemFree (str2);
16712         }
16713       }
16714       str1 = MemFree (str1);
16715     }
16716   }
16717   else if (qual_choice == NULL || qual_choice_match == NULL)
16718   {
16719     /* one is a wildcard */
16720     /* make sure it is the first one */
16721     if (qual_choice_match == NULL)
16722     {
16723       qual_choice_match = qual_choice;
16724       qual_choice = NULL;
16725     }
16726     field_vn.next = NULL;
16727     field_vn.choice = 0;
16728     str2 = GetCDSetField (cdsp, qual_choice_match);
16729     if (!StringHasNoText (str2)) {
16730       for (field_choice = 1;
16731            ! does_match && field_choice < num_gene_fields + num_mrna_fields + num_protein_fields;
16732            field_choice++)
16733       {
16734         if (field_choice != qual_choice_match->data.intvalue) {
16735           /* don't compare something to itself */
16736           field_vn.data.intvalue = field_choice;
16737           str1 = GetCDSetField (cdsp, &field_vn);
16738           if (StringCmp (str1, str2) == 0)
16739           {
16740             does_match = TRUE;
16741           }
16742           str1 = MemFree (str1);
16743         }
16744       }
16745     }
16746     str2 = MemFree (str2);
16747   } else {
16748     str1 = GetCDSetField (cdsp, qual_choice);
16749     str2 = GetCDSetField (cdsp, qual_choice_match);
16750     if (!StringHasNoText (str1) && StringCmp (str1, str2) == 0)
16751     {
16752       does_match = TRUE;
16753     }
16754     str1 = MemFree (str1);
16755     str2 = MemFree (str2);
16756   }
16757   return does_match;
16758 }
16759 
16760 
DoesCDSetMatchConstraint(CDSetPtr cdsp,ChoiceConstraintPtr ccp)16761 static Boolean DoesCDSetMatchConstraint (CDSetPtr cdsp, ChoiceConstraintPtr ccp)
16762 {
16763   Boolean                does_match = FALSE;
16764   CharPtr                str;
16765   Int4                   field_choice;
16766   ValNode                field_vn;
16767   ValNodePtr             sfp_vnp;
16768 
16769   if (cdsp == NULL)
16770   {
16771     return FALSE;
16772   }
16773   if (ccp == NULL || ccp->constraint_type == CHOICE_CONSTRAINT_ANY)
16774   {
16775     does_match = TRUE;
16776   }
16777   else if (ccp->constraint_type == CHOICE_CONSTRAINT_QUAL_PRESENT)
16778   {
16779     if (ccp->qual_choice == NULL)
16780     {
16781       does_match = TRUE;
16782     }
16783     else
16784     {
16785       str = GetCDSetField (cdsp, ccp->qual_choice);
16786       if (str != NULL)
16787       {
16788         MemFree (str);
16789         does_match = TRUE;
16790       }
16791     }
16792   }
16793   else if (ccp->constraint_type == CHOICE_CONSTRAINT_STRING)
16794   {
16795     if (ccp->qual_choice == NULL)
16796     {
16797       field_vn.next = NULL;
16798       field_vn.choice = 0;
16799       for (field_choice = 1;
16800            ! does_match && field_choice < 1 + num_gene_fields + num_mrna_fields + num_protein_fields;
16801            field_choice++)
16802       {
16803         field_vn.data.intvalue = field_choice;
16804         str = GetCDSetField (cdsp, &field_vn);
16805         does_match = DoesStringMatchConstraintX (str, ccp->string_constraint);
16806         MemFree (str);
16807       }
16808       if (ccp->string_constraint != NULL && ccp->string_constraint->not_present)
16809       {
16810         does_match = ! does_match;
16811       }
16812     }
16813     else if (IsCDSetMatPeptideQualChoice(ccp->qual_choice))
16814     {
16815       /* if we're matching protein fields, we need to look at all of them */
16816       for (sfp_vnp = cdsp->prot_list; sfp_vnp != NULL && !does_match; sfp_vnp = sfp_vnp->next)
16817       {
16818         str = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, ccp->qual_choice, NULL);
16819         does_match = DoesStringMatchConstraintX (str, ccp->string_constraint);
16820         if (ccp->string_constraint != NULL && ccp->string_constraint->not_present)
16821         {
16822           does_match = ! does_match;
16823         }
16824         MemFree (str);
16825       }
16826     }
16827     else
16828     {
16829       str = GetCDSetField (cdsp, ccp->qual_choice);
16830       does_match = DoesStringMatchConstraintX (str, ccp->string_constraint);
16831       MemFree (str);
16832       if (ccp->string_constraint != NULL && ccp->string_constraint->not_present)
16833       {
16834         does_match = ! does_match;
16835       }
16836     }
16837   }
16838   else if (ccp->constraint_type == CHOICE_CONSTRAINT_MATCH)
16839   {
16840     does_match = DoCDSFieldsMatch (cdsp, ccp->qual_choice, ccp->qual_choice_match);
16841   }
16842   else if (ccp->constraint_type == CHOICE_CONSTRAINT_PSEUDO)
16843   {
16844     if (ccp->pseudo_constraint == NULL)
16845     {
16846       does_match = TRUE;
16847     }
16848     else
16849     {
16850       does_match = GetCDSetPseudoMatch (cdsp,
16851                                         ccp->pseudo_constraint->featdef_type,
16852                                         ccp->pseudo_constraint->is_pseudo);
16853     }
16854   }
16855   return does_match;
16856 }
16857 
GetNewFeatureLocation(ValNodePtr feat_list,Uint2 choice,Uint2 choice_from)16858 static SeqLocPtr GetNewFeatureLocation(ValNodePtr feat_list, Uint2 choice, Uint2 choice_from)
16859 {
16860   ValNodePtr vnp;
16861   SeqFeatPtr sfp;
16862   BioseqPtr  bsp = NULL;
16863   SeqLocPtr  slp = NULL;
16864 
16865   for (vnp = feat_list; vnp != NULL && slp == NULL; vnp = vnp->next)
16866   {
16867     sfp = vnp->data.ptrvalue;
16868     if (sfp != NULL)
16869     {
16870       if (choice == FEATDEF_PROT || choice == FEATDEF_mat_peptide_aa)
16871       {
16872         bsp = BioseqFindFromSeqLoc (sfp->product);
16873         slp = SeqLocWholeNew (bsp);
16874       }
16875       else
16876       {
16877         if (choice_from == sfp->idx.subtype || (sfp->idx.subtype == FEATDEF_CDS && (choice_from == FEATDEF_PROT || choice_from == FEATDEF_mat_peptide_aa)))
16878         {
16879           slp = (SeqLocPtr) AsnIoMemCopy (sfp->location, (AsnReadFunc) SeqLocAsnRead, (AsnWriteFunc) SeqLocAsnWrite);
16880         }
16881         else
16882         {
16883           bsp = BioseqFindFromSeqLoc (sfp->location);
16884           slp = SeqLocWholeNew (bsp);
16885         }
16886       }
16887     }
16888   }
16889   return slp;
16890 }
16891 
16892 
BuildOneNewCDSGeneProtFeature(CDSetPtr cdsp,Uint2 choice,Uint2 choice_from)16893 static SeqFeatPtr BuildOneNewCDSGeneProtFeature (CDSetPtr cdsp, Uint2 choice, Uint2 choice_from)
16894 {
16895   BioseqPtr bsp = NULL;
16896   SeqLocPtr slp = NULL, slp_tmp, slp_sum;
16897   SeqFeatPtr sfp = NULL;
16898   RnaRefPtr  rrp;
16899   ProtRefPtr prp;
16900 
16901   if (cdsp == NULL)
16902   {
16903     return NULL;
16904   }
16905 
16906   if (choice == FEATDEF_PROT || choice == FEATDEF_mat_peptide_aa)
16907   {
16908     slp = GetNewFeatureLocation(cdsp->cds_list, choice, choice_from);
16909   }
16910   else
16911   {
16912     /* get location from CDS features */
16913     if (choice_from == 0 || choice_from == FEATDEF_CDS || choice_from == FEATDEF_PROT || choice_from == FEATDEF_mat_peptide_aa)
16914     {
16915       slp = GetNewFeatureLocation(cdsp->cds_list, choice, choice_from);
16916     }
16917 
16918     /* get location from mRNA features */
16919     if ((choice_from == 0 && slp == NULL) || choice_from == FEATDEF_mRNA)
16920     {
16921       slp_tmp = GetNewFeatureLocation(cdsp->mrna_list, choice, choice_from);
16922       if (slp == NULL)
16923       {
16924         slp = slp_tmp;
16925       }
16926       else
16927       {
16928         bsp = BioseqFindFromSeqLoc (sfp->location);
16929         if (bsp != NULL)
16930         {
16931           slp_sum = SeqLocMerge (bsp, slp_tmp, slp, TRUE, FALSE, FALSE);
16932           slp = SeqLocFree (slp);
16933           slp_tmp = SeqLocFree (slp_tmp);
16934           slp = slp_sum;
16935           slp_sum = NULL;
16936         }
16937       }
16938     }
16939 
16940     /* get location from gene features */
16941     if ((choice_from == 0 && slp == NULL) || choice_from == FEATDEF_GENE)
16942     {
16943       slp_tmp = GetNewFeatureLocation(cdsp->gene_list, choice, choice_from);
16944       if (slp == NULL)
16945       {
16946         slp = slp_tmp;
16947       }
16948       else
16949       {
16950         bsp = BioseqFindFromSeqLoc (sfp->location);
16951         if (bsp != NULL)
16952         {
16953           slp_sum = SeqLocMerge (bsp, slp_tmp, slp, TRUE, FALSE, FALSE);
16954           slp = SeqLocFree (slp);
16955           slp_tmp = SeqLocFree (slp_tmp);
16956           slp = slp_sum;
16957           slp_sum = NULL;
16958         }
16959       }
16960     }
16961   }
16962 
16963   bsp = BioseqFindFromSeqLoc (slp);
16964   if (bsp != NULL && slp != NULL)
16965   {
16966     sfp = CreateNewFeatureOnBioseq (bsp, FindFeatFromFeatDefType(choice), slp);
16967     switch (choice)
16968     {
16969       case FEATDEF_mRNA:
16970         rrp = RnaRefNew ();
16971         rrp->type = 2;
16972         sfp->data.value.ptrvalue = rrp;
16973         break;
16974       case FEATDEF_GENE:
16975         sfp->data.value.ptrvalue = GeneRefNew();
16976         break;
16977       case FEATDEF_CDS:
16978         sfp->data.value.ptrvalue = CdRegionNew();
16979         break;
16980       case FEATDEF_PROT:
16981       case FEATDEF_mat_peptide_aa:
16982         prp = ProtRefNew();
16983         if (choice == FEATDEF_mat_peptide_aa)
16984         {
16985           prp->processed = 2;
16986         }
16987         sfp->data.value.ptrvalue = prp;
16988         break;
16989     }
16990   }
16991   return sfp;
16992 }
16993 
BuildNewCDSGeneProtFeature(CDSetPtr cdsp,ValNodePtr vnp,ValNodePtr field_from)16994 static SeqFeatPtr BuildNewCDSGeneProtFeature (CDSetPtr cdsp, ValNodePtr vnp, ValNodePtr field_from)
16995 {
16996   SeqFeatPtr new_sfp = NULL, sfp;
16997   Uint2      choice_to, choice_from;
16998   ValNodePtr v;
16999   Boolean    found;
17000 
17001   if (cdsp == NULL || vnp == NULL)
17002   {
17003     return NULL;
17004   }
17005 
17006   choice_to = FeatDefTypeFromFieldList (vnp);
17007   choice_from = FeatDefTypeFromFieldList (field_from);
17008 
17009   switch (choice_to)
17010   {
17011     case FEATDEF_CDS:
17012       if (choice_from != 0 && cdsp->cds_list == NULL)
17013       {
17014         /* add new CDS */
17015         new_sfp = BuildOneNewCDSGeneProtFeature (cdsp, choice_to, choice_from);
17016         if (new_sfp != NULL)
17017         {
17018           ValNodeAddPointer (&(cdsp->cds_list), 0, new_sfp);
17019         }
17020       }
17021       break;
17022     case FEATDEF_GENE:
17023       if ((choice_from != 0 || vnp->data.intvalue - 1 == GENEFIELD_LOCUS) && cdsp->gene_list == NULL)
17024       {
17025         /* add new gene */
17026         new_sfp = BuildOneNewCDSGeneProtFeature (cdsp, choice_to, choice_from);
17027         if (new_sfp != NULL)
17028         {
17029           ValNodeAddPointer (&(cdsp->gene_list), 0, new_sfp);
17030         }
17031       }
17032       break;
17033     case FEATDEF_mRNA:
17034       if (choice_from != 0 && cdsp->mrna_list == NULL)
17035       {
17036         /* add new mrna */
17037         new_sfp = BuildOneNewCDSGeneProtFeature (cdsp, choice_to, choice_from);
17038         if (new_sfp != NULL)
17039         {
17040           ValNodeAddPointer (&(cdsp->mrna_list), 0, new_sfp);
17041         }
17042       }
17043       break;
17044     case FEATDEF_PROT:
17045     case FEATDEF_mat_peptide_aa:
17046       if (choice_from != 0 && cdsp->cds_list != NULL)
17047       {
17048         found = FALSE;
17049         for (v = cdsp->prot_list; v != NULL && !found; v = v->next)
17050         {
17051           sfp = (SeqFeatPtr) v->data.ptrvalue;
17052           if (sfp != NULL && sfp->idx.subtype == choice_to)
17053           {
17054             found = FALSE;
17055           }
17056         }
17057         if (!found)
17058         {
17059           new_sfp = BuildOneNewCDSGeneProtFeature (cdsp, choice_to, choice_from);
17060           if (new_sfp != NULL)
17061           {
17062             /* set subtype so other functions will work */
17063             new_sfp->idx.subtype = choice_to;
17064             ValNodeAddPointer (&(cdsp->mrna_list), 0, new_sfp);
17065           }
17066         }
17067       }
17068       break;
17069   }
17070   return new_sfp;
17071 }
17072 
CDSetOnBioseq(CDSetPtr cdsp,BioseqPtr bsp)17073 static Boolean CDSetOnBioseq (CDSetPtr cdsp, BioseqPtr bsp)
17074 {
17075   SeqFeatPtr sfp;
17076   Boolean    is_on_bioseq = FALSE;
17077   ValNodePtr sfp_vnp;
17078 
17079   if (cdsp == NULL || bsp == NULL) return FALSE;
17080 
17081   for (sfp_vnp = cdsp->cds_list; sfp_vnp != NULL && !is_on_bioseq; sfp_vnp = sfp_vnp->next)
17082   {
17083     sfp = sfp_vnp->data.ptrvalue;
17084     if (sfp != NULL && BioseqFindFromSeqLoc (sfp->location) == bsp) {
17085       is_on_bioseq = TRUE;
17086     }
17087   }
17088   for (sfp_vnp = cdsp->gene_list; sfp_vnp != NULL && !is_on_bioseq; sfp_vnp = sfp_vnp->next)
17089   {
17090     sfp = sfp_vnp->data.ptrvalue;
17091     if (sfp != NULL && BioseqFindFromSeqLoc (sfp->location) == bsp) {
17092       is_on_bioseq = TRUE;
17093     }
17094   }
17095   for (sfp_vnp = cdsp->mrna_list; sfp_vnp != NULL && !is_on_bioseq; sfp_vnp = sfp_vnp->next)
17096   {
17097     sfp = sfp_vnp->data.ptrvalue;
17098     if (sfp != NULL && BioseqFindFromSeqLoc (sfp->location) == bsp) {
17099       is_on_bioseq = TRUE;
17100     }
17101   }
17102   return is_on_bioseq;
17103 }
17104 
ValNodeDataAlreadyInValNodeList(ValNodePtr list,ValNodePtr findme)17105 static Boolean ValNodeDataAlreadyInValNodeList (ValNodePtr list, ValNodePtr findme)
17106 {
17107   if (findme == NULL) return FALSE;
17108   while (list != NULL)
17109   {
17110     if (list->data.ptrvalue == findme->data.ptrvalue)
17111     {
17112       return TRUE;
17113     }
17114     list = list->next;
17115   }
17116   return FALSE;
17117 }
17118 
BuildGeneForSegSet(BioseqSetPtr segset,ValNodePtr PNTR cdset_list,Boolean lonely_ok)17119 static void BuildGeneForSegSet (BioseqSetPtr segset, ValNodePtr PNTR cdset_list, Boolean lonely_ok)
17120 {
17121   SeqEntryPtr       this_sep, master_sep = NULL;
17122   BioseqSetPtr      part_set = NULL;
17123   SeqLocPtr         slp = NULL, slp_new, slp_last = NULL;
17124   SeqFeatPtr        sfp;
17125   SeqMgrFeatContext context;
17126   ValNodePtr        vnp, add_gene_to = NULL;
17127   Boolean           on_part;
17128   CDSetPtr          cdsp;
17129 
17130   if (segset == NULL || segset->seq_set == NULL)
17131   {
17132     return;
17133   }
17134 
17135   this_sep = segset->seq_set;
17136   while (this_sep != NULL && (part_set == NULL || master_sep == NULL))
17137   {
17138     if (IS_Bioseq_set (this_sep))
17139     {
17140       part_set = (BioseqSetPtr) this_sep->data.ptrvalue;
17141       if (part_set != NULL && part_set->_class != BioseqseqSet_class_parts)
17142       {
17143         part_set = NULL;
17144       }
17145     }
17146     else if (IS_Bioseq (this_sep))
17147     {
17148       master_sep = this_sep;
17149     }
17150     this_sep = this_sep->next;
17151   }
17152   if (part_set != NULL && master_sep != NULL)
17153   {
17154     this_sep = part_set->seq_set;
17155     sfp = SeqMgrGetNextFeature (master_sep->data.ptrvalue, NULL,
17156                                 SEQFEAT_GENE, FEATDEF_GENE, &context);
17157 
17158     while (this_sep != NULL && sfp == NULL)
17159     {
17160       if (IS_Bioseq (this_sep))
17161       {
17162         sfp = SeqMgrGetNextFeature (this_sep->data.ptrvalue, NULL,
17163                                     SEQFEAT_GENE, FEATDEF_GENE, &context);
17164       }
17165       this_sep = this_sep->next;
17166     }
17167     if (sfp != NULL)
17168     {
17169       return;
17170     }
17171 
17172     /* no other genes anywhere in segmented set.  Any cdsets? */
17173     for (vnp = *cdset_list; vnp != NULL; vnp = vnp->next)
17174     {
17175       cdsp = (CDSetPtr) vnp->data.ptrvalue;
17176       if (CDSetOnBioseq(cdsp, master_sep->data.ptrvalue)
17177           && !ValNodeDataAlreadyInValNodeList(add_gene_to, vnp))
17178       {
17179         ValNodeAddPointer (&add_gene_to, 0, cdsp);
17180       }
17181       else
17182       {
17183         on_part = FALSE;
17184         for (this_sep = part_set->seq_set; this_sep != NULL && !on_part; this_sep = this_sep->next)
17185         {
17186           if (CDSetOnBioseq(cdsp, this_sep->data.ptrvalue)
17187               && !ValNodeDataAlreadyInValNodeList(add_gene_to, vnp))
17188           {
17189             ValNodeAddPointer (&add_gene_to, 0, cdsp);
17190             on_part = TRUE;
17191           }
17192         }
17193       }
17194     }
17195 
17196     if (add_gene_to != NULL || lonely_ok) {
17197       /* create gene */
17198       this_sep = part_set->seq_set;
17199       while (this_sep != NULL)
17200       {
17201         if (IS_Bioseq (this_sep))
17202         {
17203           slp_new = SeqLocWholeNew (this_sep->data.ptrvalue);
17204           if (slp_new != NULL)
17205           {
17206             if (slp_last == NULL)
17207             {
17208               slp = slp_new;
17209             }
17210             else
17211             {
17212               slp_last = ValNodeNew (slp);
17213               slp_last->choice = SEQLOC_NULL;
17214               slp_last->next = slp_new;
17215             }
17216             slp_last = slp_new;
17217           }
17218         }
17219         this_sep = this_sep->next;
17220       }
17221       slp_new = ValNodeNew (NULL);
17222       slp_new->choice = SEQLOC_MIX;
17223       slp_new->data.ptrvalue = slp;
17224       sfp = CreateNewFeature (master_sep, NULL, SEQFEAT_GENE, NULL);
17225       sfp->location = SeqLocFree (sfp->location);
17226       sfp->location = slp_new;
17227       sfp->data.value.ptrvalue = GeneRefNew ();
17228 
17229       /* add to sets */
17230       if (add_gene_to == NULL)
17231       {
17232         cdsp = (CDSetPtr) MemNew (sizeof (CDSetData));
17233         MemSet (cdsp, 0, sizeof (CDSetData));
17234         ValNodeAddPointer (&(cdsp->gene_list), 0, sfp);
17235         ValNodeAddPointer (cdset_list, 0, cdsp);
17236       }
17237       else
17238       {
17239         for (vnp = add_gene_to; vnp != NULL; vnp = vnp->next)
17240         {
17241           cdsp = (CDSetPtr) vnp->data.ptrvalue;
17242           ValNodeAddPointer (&(cdsp->gene_list), 0, sfp);
17243         }
17244       }
17245     }
17246     add_gene_to = ValNodeFree (add_gene_to);
17247   }
17248 }
17249 
LoneGeneOkWithFilter(FilterSetPtr fsp)17250 static Boolean LoneGeneOkWithFilter (FilterSetPtr fsp)
17251 {
17252   if (fsp == NULL || fsp->cgp == NULL
17253       || fsp->cgp->constraint_type == CHOICE_CONSTRAINT_ANY
17254       || (fsp->cgp->constraint_type == CHOICE_CONSTRAINT_QUAL_PRESENT
17255           && fsp->cgp->qual_choice == NULL))
17256   {
17257     return TRUE;
17258   }
17259   else
17260   {
17261     return FALSE;
17262   }
17263 }
17264 
BuildNewGenes(SeqEntryPtr sep,ValNodePtr PNTR cdset_list,Boolean lonely_ok)17265 static void BuildNewGenes (SeqEntryPtr sep, ValNodePtr PNTR cdset_list, Boolean lonely_ok)
17266 {
17267   BioseqSetPtr      bssp = NULL;
17268   BioseqPtr         bsp = NULL;
17269   SeqFeatPtr        sfp;
17270   SeqMgrFeatContext context;
17271   SeqLocPtr         slp = NULL;
17272   ValNodePtr        vnp;
17273   CDSetPtr          cdsp;
17274   ValNodePtr        add_gene_to;
17275 
17276   if (sep == NULL)
17277   {
17278     return;
17279   }
17280 
17281   if (IS_Bioseq (sep))
17282   {
17283     bsp = (BioseqPtr) sep->data.ptrvalue;
17284     if (ISA_na (bsp->mol))
17285     {
17286       sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_GENE, FEATDEF_GENE, &context);
17287       if (sfp == NULL)
17288       {
17289         /* are there any sets already on this Bioseq? */
17290         add_gene_to = NULL;
17291         for (vnp = *cdset_list; vnp != NULL; vnp = vnp->next)
17292         {
17293           cdsp = (CDSetPtr) vnp->data.ptrvalue;
17294           if (CDSetOnBioseq(cdsp, bsp))
17295           {
17296             if (cdsp->gene_list == NULL)
17297             {
17298               ValNodeAddPointer (&add_gene_to, 0, cdsp);
17299             }
17300           }
17301         }
17302         if (add_gene_to != NULL || lonely_ok)
17303         {
17304           slp = SeqLocWholeNew (bsp);
17305           sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_GENE, slp);
17306           sfp->data.value.ptrvalue = GeneRefNew();
17307           if (add_gene_to == NULL)
17308           {
17309             cdsp = (CDSetPtr) MemNew (sizeof (CDSetData));
17310             MemSet (cdsp, 0, sizeof (CDSetData));
17311             ValNodeAddPointer (&(cdsp->gene_list), 0, sfp);
17312             ValNodeAddPointer (cdset_list, 0, cdsp);
17313           }
17314           else
17315           {
17316             for (vnp = add_gene_to; vnp != NULL; vnp = vnp->next)
17317             {
17318               cdsp = (CDSetPtr) vnp->data.ptrvalue;
17319               ValNodeAddPointer (&(cdsp->gene_list), 0, sfp);
17320             }
17321           }
17322         }
17323         add_gene_to = ValNodeFree (add_gene_to);
17324       }
17325     }
17326   }
17327   else if (IS_Bioseq_set (sep))
17328   {
17329     bssp = (BioseqSetPtr) sep->data.ptrvalue;
17330     if (bssp->_class == BioseqseqSet_class_segset)
17331     {
17332       BuildGeneForSegSet (bssp, cdset_list, lonely_ok);
17333     }
17334     else
17335     {
17336       BuildNewGenes (bssp->seq_set, cdset_list, lonely_ok);
17337     }
17338   }
17339   BuildNewGenes (sep->next, cdset_list, lonely_ok);
17340 }
17341 
17342 typedef Boolean (*Nlm_TestAECRChoiceProc) PROTO((Pointer));
17343 typedef DialoG  (*Nlm_AECRMakeDlgProc) PROTO ((GrouP, Int4, Nlm_ChangeNotifyProc, Pointer, Uint2));
17344 typedef DialoG  (*Nlm_SampleDialogProc) PROTO ((GrouP, Uint2));
17345 typedef DialoG  (*Nlm_FieldListDlgProc) PROTO ((GrouP, Boolean, Nlm_ChangeNotifyProc, Pointer));
17346 typedef DialoG  (*Nlm_SubtypeListDlgProc) PROTO ((GrouP, Boolean, SeqEntryPtr, Nlm_ChangeNotifyProc, Pointer));
17347 
17348 #define AECR_VIB_MSG_SET_DEFAULT (NUM_VIB_MSG + 1)
17349 #define AECR_VIB_MSG_CLEAR_TEXT  (NUM_VIB_MSG + 2)
17350 #define AECR_VIB_MSG_AUTOPOPULATE (NUM_VIB_MSG + 3)
17351 
17352 typedef void (*Nlm_ChangeAECRActionProc) PROTO ((DialoG, DialoG));
17353 
17354 typedef struct applyeditconvertremove
17355 {
17356   FORM_MESSAGE_BLOCK
17357   DialoG                   aecr_pages [NUM_AECR];
17358   DialoG                   accept_cancel;
17359   PopuP                    action_popup;
17360   DialoG                   constraints;
17361   ButtoN                   clear_constraints_on_action_change;
17362   Nlm_ChangeAECRActionProc change_action;
17363   Int4                     prev_page;
17364   Boolean                  crippled;
17365   Int4                     crippled_action;
17366 } ApplyEditConvertRemoveData, PNTR ApplyEditConvertRemovePtr;
17367 
ApplyEditConvertRemoveChangeNotify(Pointer userdata)17368 static void ApplyEditConvertRemoveChangeNotify (Pointer userdata)
17369 {
17370   ApplyEditConvertRemovePtr mp;
17371   Int4                      action_choice;
17372   ValNodePtr                err_list;
17373 
17374   mp = (ApplyEditConvertRemovePtr) userdata;
17375   if (mp == NULL)
17376   {
17377     return;
17378   }
17379 
17380   if (mp->crippled)
17381   {
17382     action_choice = mp->crippled_action;
17383   }
17384   else
17385   {
17386     action_choice = GetValue (mp->action_popup);
17387   }
17388 
17389   if (action_choice > 0 && action_choice <= NUM_AECR)
17390   {
17391     err_list = TestDialog (mp->aecr_pages [action_choice - 1]);
17392     if (err_list != NULL)
17393     {
17394       err_list = ValNodeFree (err_list);
17395       DisableAcceptCancelDialogAccept (mp->accept_cancel);
17396     }
17397     else
17398     {
17399       EnableAcceptCancelDialogAccept (mp->accept_cancel);
17400     }
17401   }
17402   else
17403   {
17404     DisableAcceptCancelDialogAccept (mp->accept_cancel);
17405     return;
17406   }
17407 }
17408 
17409 
ApplyEditConvertRemoveClearText(Pointer userdata)17410 static void ApplyEditConvertRemoveClearText (Pointer userdata)
17411 {
17412   ApplyEditConvertRemovePtr mp;
17413   FilterSetPtr              fsp;
17414   Int4                      i;
17415 
17416   mp = (ApplyEditConvertRemovePtr) userdata;
17417   if (mp != NULL)
17418   {
17419     for (i = 0; i < NUM_AECR; i++)
17420     {
17421       SendMessageToDialog (mp->aecr_pages[i], AECR_VIB_MSG_CLEAR_TEXT);
17422     }
17423     fsp = DialogToPointer (mp->constraints);
17424     FilterSetClearText (fsp);
17425     PointerToDialog (mp->constraints, fsp);
17426     FilterSetFree (fsp);
17427     ApplyEditConvertRemoveChangeNotify (mp);
17428   }
17429 }
17430 
ApplyEditConvertRemoveClear(Pointer userdata)17431 static void ApplyEditConvertRemoveClear (Pointer userdata)
17432 {
17433   ApplyEditConvertRemovePtr mp;
17434   Int4                      i;
17435 
17436   mp = (ApplyEditConvertRemovePtr) userdata;
17437   if (mp != NULL)
17438   {
17439     for (i = 0; i < NUM_AECR; i++)
17440     {
17441       PointerToDialog (mp->aecr_pages[i], NULL);
17442     }
17443     PointerToDialog (mp->constraints, NULL);
17444     ApplyEditConvertRemoveChangeNotify (mp);
17445   }
17446 }
17447 
17448 static void
ChangeApplyEditConvertRemoveAction(ApplyEditConvertRemovePtr mp,Int4 action_choice)17449 ChangeApplyEditConvertRemoveAction
17450 (ApplyEditConvertRemovePtr mp,
17451  Int4                      action_choice)
17452 {
17453   Int4 i;
17454 
17455   if (mp == NULL || action_choice < AECR_APPLY || action_choice > NUM_AECR)
17456   {
17457     return;
17458   }
17459 
17460   for (i = 0; i < NUM_AECR; i++)
17461   {
17462     if (i + 1 == action_choice)
17463     {
17464       Show (mp->aecr_pages[i]);
17465     }
17466     else
17467     {
17468       Hide (mp->aecr_pages[i]);
17469     }
17470   }
17471 
17472   if (GetStatus (mp->clear_constraints_on_action_change))
17473   {
17474     PointerToDialog (mp->constraints, NULL);
17475     PointerToDialog (mp->aecr_pages [action_choice - 1], NULL);
17476   }
17477 
17478   if (mp->change_action != NULL)
17479   {
17480     if (mp->prev_page < AECR_APPLY || mp->prev_page > NUM_AECR)
17481     {
17482       (mp->change_action) (NULL, mp->aecr_pages [action_choice - 1]);
17483     }
17484     else
17485     {
17486       (mp->change_action) (mp->aecr_pages [mp->prev_page - 1],
17487                            mp->aecr_pages [action_choice - 1]);
17488     }
17489   }
17490 
17491   mp->prev_page = action_choice;
17492 
17493   if (action_choice == AECR_APPLY)
17494   {
17495     SendMessageToDialog (mp->aecr_pages[AECR_APPLY - 1], AECR_VIB_MSG_AUTOPOPULATE);
17496   }
17497   else if (action_choice == AECR_EDIT)
17498   {
17499     SendMessageToDialog (mp->aecr_pages[AECR_EDIT - 1], AECR_VIB_MSG_AUTOPOPULATE);
17500   }
17501 
17502   ApplyEditConvertRemoveChangeNotify (mp);
17503 }
17504 
ChangeApplyEditConvertRemoveActionPopup(PopuP p)17505 static void ChangeApplyEditConvertRemoveActionPopup (PopuP p)
17506 {
17507   ApplyEditConvertRemovePtr mp;
17508   Int4                      action_choice;
17509 
17510   mp = (ApplyEditConvertRemovePtr) GetObjectExtra (p);
17511   if (mp == NULL)
17512   {
17513     return;
17514   }
17515 
17516   action_choice = GetValue (mp->action_popup);
17517   ChangeApplyEditConvertRemoveAction (mp, action_choice);
17518 }
17519 typedef struct samplebtn
17520 {
17521   Uint2                entityID;
17522   Nlm_SampleDialogProc make_sample_dlg;
17523   CharPtr              title;
17524 } SampleBtnData, PNTR SampleBtnPtr;
17525 
AECRSampleButton(ButtoN b)17526 static void AECRSampleButton (ButtoN b)
17527 {
17528   SampleBtnPtr sbp;
17529   WindoW       w;
17530 
17531   sbp = GetObjectExtra (b);
17532   if (sbp != NULL && sbp->make_sample_dlg != NULL)
17533   {
17534     w = FixedWindow (-50, -33, -10, -10, sbp->title, StdCloseWindowProc);
17535     (sbp->make_sample_dlg) (w, sbp->entityID);
17536     Show (w);
17537   }
17538 }
17539 
17540 static void
ApplyEditConvertRemoveCombo(IteM i,Int4 first_action_choice,Boolean crippled,CharPtr title,Nlm_AECRMakeDlgProc make_dlg,Boolean show_sample,Nlm_SampleDialogProc make_sample_dlg,Boolean string_constraint,Boolean source_constraint,Boolean location_constraint,Boolean cds_gene_prot_constraint,Boolean id_list_constraint,CharPtr string_constraint_label,Nlm_AcceptActnProc accept_actn,Nlm_CancelActnProc cancel_actn,Nlm_ChangeAECRActionProc change_action,OkToPreSample presample_check_proc)17541 ApplyEditConvertRemoveCombo
17542 (IteM                     i,
17543  Int4                     first_action_choice,
17544  Boolean                  crippled,
17545  CharPtr                  title,
17546  Nlm_AECRMakeDlgProc      make_dlg,
17547  Boolean                  show_sample,
17548  Nlm_SampleDialogProc     make_sample_dlg,
17549  Boolean                  string_constraint,
17550  Boolean                  source_constraint,
17551  Boolean                  location_constraint,
17552  Boolean                  cds_gene_prot_constraint,
17553  Boolean                  id_list_constraint,
17554  CharPtr                  string_constraint_label,
17555  Nlm_AcceptActnProc       accept_actn,
17556  Nlm_CancelActnProc       cancel_actn,
17557  Nlm_ChangeAECRActionProc change_action,
17558  OkToPreSample            presample_check_proc)
17559 {
17560   BaseFormPtr               bfp;
17561   ApplyEditConvertRemovePtr mp;
17562   WindoW                    w;
17563   GrouP                     h, g1, k, n, m;
17564   Int4                      page_num;
17565   SampleBtnPtr              sbp;
17566   ButtoN                    b;
17567   DialoG                    sample_dlg = NULL;
17568 
17569 #ifdef WIN_MAC
17570   bfp = currentFormDataPtr;
17571 #else
17572   bfp = GetObjectExtra (i);
17573 #endif
17574   if (bfp == NULL) return;
17575 
17576   mp = (ApplyEditConvertRemovePtr) MemNew (sizeof (ApplyEditConvertRemoveData));
17577   if (mp == NULL) return;
17578 
17579   if (first_action_choice < AECR_APPLY || first_action_choice > AECR_REMOVE)
17580   {
17581     first_action_choice = AECR_APPLY;
17582   }
17583   mp->crippled = crippled;
17584   mp->crippled_action = first_action_choice;
17585 
17586   w = FixedWindow (-50, -33, -10, -10, title, StdCloseWindowProc);
17587   SetObjectExtra (w, mp, StdCleanupExtraProc);
17588   SetObjectExtra (w, mp, NULL);
17589   mp->form = (ForM) w;
17590   mp->input_entityID = bfp->input_entityID;
17591 
17592 #ifndef WIN_MAC
17593   CreateStandardEditMenu (w);
17594 #endif
17595 
17596   n = HiddenGroup (w, -1, 0, NULL);
17597   SetGroupSpacing (n, 10, 10);
17598 
17599   k = HiddenGroup (n, 2, 0, NULL);
17600   SetGroupSpacing (k, 10, 10);
17601   if (show_sample && make_sample_dlg != NULL && ! mp->crippled)
17602   {
17603     sample_dlg = make_sample_dlg (k, mp->input_entityID);
17604   }
17605 
17606   h = HiddenGroup (k, -1, 0, NULL);
17607   SetGroupSpacing (h, 10, 10);
17608 
17609   if (!mp->crippled)
17610   {
17611     m = HiddenGroup (h, 2, 0, NULL);
17612     SetGroupSpacing (m, 10, 10);
17613 
17614     if (!show_sample && make_sample_dlg != NULL)
17615     {
17616       sbp = (SampleBtnPtr) MemNew (sizeof (SampleBtnData));
17617       sbp->entityID = mp->input_entityID;
17618       sbp->title = title;
17619       sbp->make_sample_dlg = make_sample_dlg;
17620       b = PushButton (m, "Show Qualifiers", AECRSampleButton);
17621       SetObjectExtra (b, sbp, StdCleanupExtraProc);
17622     }
17623 
17624     mp->action_popup = PopupList (m, TRUE, ChangeApplyEditConvertRemoveActionPopup);
17625     SetObjectExtra (mp->action_popup, mp, NULL);
17626     PopupItem (mp->action_popup, "Apply");
17627     PopupItem (mp->action_popup, "Edit");
17628     PopupItem (mp->action_popup, "Convert");
17629     PopupItem (mp->action_popup, "Swap");
17630     PopupItem (mp->action_popup, "Parse");
17631     PopupItem (mp->action_popup, "Remove");
17632     SetValue (mp->action_popup, first_action_choice);
17633 
17634     mp->change_action = change_action;
17635 
17636     mp->clear_constraints_on_action_change = CheckBox (h, "Clear when changing actions", NULL);
17637     SetStatus (mp->clear_constraints_on_action_change, TRUE);
17638   }
17639 
17640   g1 = HiddenGroup (h, 0, 0, NULL);
17641   for (page_num = 0; page_num < NUM_AECR; page_num++)
17642   {
17643     mp->aecr_pages [page_num] = make_dlg (g1, page_num + 1,
17644                                           ApplyEditConvertRemoveChangeNotify,
17645                                           mp, mp->input_entityID);
17646   }
17647   AlignObjects (ALIGN_CENTER, (HANDLE) mp->aecr_pages[0],
17648                               (HANDLE) mp->aecr_pages[1],
17649                               (HANDLE) mp->aecr_pages[2],
17650                               (HANDLE) mp->aecr_pages[3],
17651                               (HANDLE) mp->aecr_pages[4],
17652                               (HANDLE) mp->aecr_pages[5],
17653                                NULL);
17654 
17655   if (! mp->crippled)
17656   {
17657     AlignObjects (ALIGN_CENTER, (HANDLE) m,
17658                                 (HANDLE) mp->clear_constraints_on_action_change,
17659                                 (HANDLE) g1,
17660                                 (HANDLE) NULL);
17661     mp->constraints = FilterGroup (n, string_constraint, source_constraint,
17662                                    location_constraint, cds_gene_prot_constraint,
17663                                    id_list_constraint,
17664                                    string_constraint_label);
17665 
17666   }
17667 
17668   mp->accept_cancel = AcceptCancelDialog (n, accept_actn, cancel_actn,
17669                                           ApplyEditConvertRemoveClear,
17670                                           ApplyEditConvertRemoveClearText,
17671                                           (Pointer)mp, w);
17672 
17673   if (mp->crippled)
17674   {
17675     AlignObjects (ALIGN_CENTER, (HANDLE) k, (HANDLE) mp->accept_cancel, NULL);
17676   }
17677   else
17678   {
17679     AlignObjects (ALIGN_CENTER, (HANDLE) k,
17680                                 (HANDLE) mp->constraints,
17681                                 (HANDLE) mp->accept_cancel,
17682                                 NULL);
17683   }
17684 
17685   mp->prev_page = -1;
17686   ChangeApplyEditConvertRemoveAction (mp, first_action_choice);
17687   /* initialize sample values if conditions are met */
17688   if (sample_dlg != NULL && (presample_check_proc == NULL || presample_check_proc(mp->input_entityID))) {
17689     SendMessageToDialog (sample_dlg, VIB_MSG_INIT);
17690   }
17691   Show (w);
17692 }
17693 
17694 
CountFeaturesCallback(SeqFeatPtr sfp,Pointer userdata)17695 static void CountFeaturesCallback(SeqFeatPtr sfp, Pointer userdata)
17696 {
17697   Int4Ptr pTotal;
17698 
17699   if (userdata == NULL || sfp == NULL) {
17700       return;
17701   }
17702 
17703   pTotal = (Int4Ptr) userdata;
17704 
17705   (*pTotal) ++;
17706 }
17707 
17708 
CheckFeaturesForPresample(Uint2 entityID)17709 static Boolean CheckFeaturesForPresample (Uint2 entityID)
17710 {
17711   SeqEntryPtr sep;
17712   Int4        total = 0;
17713 
17714   sep = GetTopSeqEntryForEntityID(entityID);
17715   if (sep == NULL) {
17716     return FALSE;
17717   }
17718 
17719   VisitFeaturesInSep(sep, &total, CountFeaturesCallback);
17720 
17721   if (total > 1500) {
17722     return FALSE;
17723   } else {
17724     return TRUE;
17725   }
17726 }
17727 
17728 
17729 typedef struct conversionconflict
17730 {
17731   ConvertFieldPtr cfp;
17732   GetSamplePtr    gsp;
17733 } ConversionConflictData, PNTR ConversionConflictPtr;
17734 
GetConversionConflictsFeatureCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)17735 static void GetConversionConflictsFeatureCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
17736 {
17737   ConversionConflictPtr ccp;
17738   CharPtr               src_str, dst_str;
17739 
17740   if (sfp == NULL || userdata == NULL)
17741   {
17742     return;
17743   }
17744 
17745   ccp = (ConversionConflictPtr) userdata;
17746 
17747   if (ccp->cfp == NULL
17748       || ccp->cfp->src_field_list == NULL
17749       || ccp->cfp->dst_field_list == NULL
17750       || ccp->cfp->get_str_func == NULL
17751       || ccp->gsp == NULL)
17752   {
17753     return;
17754   }
17755 
17756   src_str = (ccp->cfp->get_str_func) (sfp, ccp->cfp->src_field_list, ccp->cfp->fsp);
17757 
17758   if (ccp->cfp->convert_type == CONVERT_TYPE_PARSE)
17759   {
17760     dst_str = src_str;
17761     src_str = ReplaceStringForParse(src_str, ccp->cfp->text_portion);
17762     dst_str = MemFree (dst_str);
17763     if (src_str == NULL)
17764     {
17765       return;
17766     }
17767   }
17768 
17769   if (!StringHasNoText (src_str))
17770   {
17771     dst_str = (ccp->cfp->get_str_func) (sfp, ccp->cfp->dst_field_list, ccp->cfp->fsp);
17772     if (!StringHasNoText (dst_str))
17773     {
17774       ccp->gsp->num_found ++;
17775       if (ccp->gsp->sample_text == NULL)
17776       {
17777         ccp->gsp->sample_text = dst_str;
17778       }
17779       else
17780       {
17781         if (StringCmp (dst_str, ccp->gsp->sample_text) != 0)
17782         {
17783           ccp->gsp->all_same = FALSE;
17784         }
17785         dst_str = MemFree (dst_str);
17786       }
17787     }
17788     src_str = MemFree (src_str);
17789   }
17790 }
17791 
GetConversionConflictsDescriptorCallback(SeqDescPtr sdp,Pointer userdata,FilterSetPtr fsp)17792 static void GetConversionConflictsDescriptorCallback (SeqDescPtr sdp, Pointer userdata, FilterSetPtr fsp)
17793 {
17794   ConversionConflictPtr ccp;
17795   CharPtr               src_str, dst_str;
17796 
17797   if (sdp == NULL || userdata == NULL)
17798   {
17799     return;
17800   }
17801 
17802   ccp = (ConversionConflictPtr) userdata;
17803 
17804   if (ccp->cfp == NULL
17805       || ccp->cfp->src_field_list == NULL
17806       || ccp->cfp->dst_field_list == NULL
17807       || ccp->cfp->get_d_str_func == NULL
17808       || ccp->gsp == NULL)
17809   {
17810     return;
17811   }
17812 
17813   src_str = (ccp->cfp->get_d_str_func) (sdp, ccp->cfp->src_field_list, ccp->cfp->fsp);
17814 
17815   if (ccp->cfp->convert_type == CONVERT_TYPE_PARSE)
17816   {
17817     dst_str = src_str;
17818     src_str = ReplaceStringForParse(src_str, ccp->cfp->text_portion);
17819     dst_str = MemFree (dst_str);
17820     if (src_str == NULL)
17821     {
17822       return;
17823     }
17824   }
17825 
17826   if (!StringHasNoText (src_str))
17827   {
17828     dst_str = (ccp->cfp->get_d_str_func) (sdp, ccp->cfp->dst_field_list, ccp->cfp->fsp);
17829     if (!StringHasNoText (dst_str))
17830     {
17831       ccp->gsp->num_found ++;
17832       if (ccp->gsp->sample_text == NULL)
17833       {
17834         ccp->gsp->sample_text = dst_str;
17835       }
17836       else
17837       {
17838         if (StringCmp (dst_str, ccp->gsp->sample_text) != 0)
17839         {
17840           ccp->gsp->all_same = FALSE;
17841         }
17842         dst_str = MemFree (dst_str);
17843       }
17844     }
17845     src_str = MemFree (src_str);
17846   }
17847 }
17848 
CheckForConversionExistingTextInSeqEntry(SeqEntryPtr sep,ConvertFieldPtr cfp,FilterSetPtr fsp,Uint1 seqfeat_choice,Uint1 featdef_choice,Uint1 descr_choice)17849 static GetSamplePtr CheckForConversionExistingTextInSeqEntry
17850 (SeqEntryPtr              sep,
17851  ConvertFieldPtr          cfp,
17852  FilterSetPtr             fsp,
17853  Uint1                    seqfeat_choice,
17854  Uint1                    featdef_choice,
17855  Uint1                    descr_choice)
17856 {
17857   ConversionConflictData ccd;
17858 
17859   ccd.cfp = cfp;
17860   ccd.gsp = (GetSamplePtr) MemNew (sizeof (GetSampleData));
17861   if (ccd.gsp != NULL)
17862   {
17863     ccd.gsp->sample_text = NULL;
17864     ccd.gsp->fieldstring_func = NULL;
17865     ccd.gsp->descrstring_func = NULL;
17866     ccd.gsp->free_vn_proc = NULL;
17867     ccd.gsp->copy_vn_proc = NULL;
17868     ccd.gsp->requested_field = NULL;
17869     ccd.gsp->num_found = 0;
17870     ccd.gsp->all_same = TRUE;
17871     OperateOnSeqEntryConstrainedObjects (sep, fsp, GetConversionConflictsFeatureCallback,
17872                                          GetConversionConflictsDescriptorCallback,
17873                                          seqfeat_choice, featdef_choice, descr_choice, &ccd);
17874   }
17875   return ccd.gsp;
17876 }
17877 
17878 NLM_EXTERN void
AddEditApplyDataToApplyValue(Int4 action_choice,EditApplyPtr edit_apply,ApplyValuePtr avp)17879 AddEditApplyDataToApplyValue
17880 (Int4 action_choice,
17881  EditApplyPtr edit_apply,
17882  ApplyValuePtr avp)
17883 {
17884   if (avp == NULL)
17885   {
17886     return;
17887   }
17888 
17889   if (edit_apply == NULL)
17890   {
17891     avp->text_to_replace = NULL;
17892     avp->new_text = NULL;
17893     avp->where_to_replace = EditApplyFindLocation_anywhere;
17894 
17895     return;
17896   }
17897 
17898   if (action_choice == AECR_EDIT)
17899   {
17900     avp->text_to_replace = StringSave (edit_apply->find_txt);
17901     avp->new_text = StringSave (edit_apply->repl_txt);
17902     avp->where_to_replace = edit_apply->find_location;
17903   }
17904   else if (action_choice == AECR_APPLY)
17905   {
17906     avp->new_text = StringSave (edit_apply->apply_txt);
17907     avp->text_to_replace = NULL;
17908     avp->where_to_replace = EditApplyFindLocation_anywhere;
17909   }
17910   else
17911   {
17912     avp->text_to_replace = NULL;
17913     avp->new_text = NULL;
17914     avp->where_to_replace = EditApplyFindLocation_anywhere;
17915   }
17916 }
17917 
17918 #define AECR_DATA_BLOCK \
17919   ValNodePtr      field_list;           \
17920   ValNodePtr      field_list_to;        \
17921   ValNodePtr      subtype_list;         \
17922   Boolean         leave_on_original;    \
17923   Boolean         strip_name_from_text; \
17924   EditApplyPtr    edit_apply;           \
17925   TextPortionXPtr  text_portion;         \
17926   Boolean         remove_parsed;        \
17927   FreeValNodeProc free_field_vn_proc;   \
17928   FreeValNodeProc free_subtype_vn_proc;
17929 
17930 typedef struct simpleaecr
17931 {
17932   AECR_DATA_BLOCK
17933 } SimpleAECRData, PNTR SimpleAECRPtr;
17934 
AECRDataBlockFreeContents(SimpleAECRPtr sp)17935 static void AECRDataBlockFreeContents (SimpleAECRPtr sp)
17936 {
17937   if (sp != NULL)
17938   {
17939     sp->field_list = ValNodeFuncFree (sp->field_list, sp->free_field_vn_proc);
17940     sp->field_list_to = ValNodeFuncFree (sp->field_list_to, sp->free_field_vn_proc);
17941     sp->subtype_list = ValNodeFuncFree (sp->subtype_list, sp->free_subtype_vn_proc);
17942     sp->edit_apply = EditApplyFree (sp->edit_apply);
17943     sp->text_portion = TextPortionXFree(sp->text_portion);
17944   }
17945 }
17946 
SimpleAECRFree(SimpleAECRPtr sp)17947 static SimpleAECRPtr SimpleAECRFree (SimpleAECRPtr sp)
17948 {
17949   if (sp != NULL)
17950   {
17951     AECRDataBlockFreeContents (sp);
17952     sp = MemFree (sp);
17953   }
17954   return sp;
17955 }
17956 
17957 /* This function is used to autopopulate the new_text and find fields */
17958 typedef CharPtr (*GetAutoPopulateTextFunc) PROTO ((ValNodePtr, ValNodePtr, Uint2));
17959 
17960 #define AECR_BLOCK \
17961   DIALOG_MESSAGE_BLOCK                                \
17962   DialoG          field_list;                         \
17963   DialoG          field_list_to;                      \
17964   DialoG          subtype_list;                       \
17965   ButtoN          leave_on_original;                  \
17966   ButtoN          strip_name_from_text;               \
17967   DialoG          edit_apply;                         \
17968   DialoG          text_portion;                       \
17969   ButtoN          remove_parsed;                      \
17970   Int4            action_choice;                      \
17971   /* These are necessary to produce the SimpleAECR structure for output */ \
17972   FreeValNodeProc free_field_vn_proc;                 \
17973   FreeValNodeProc free_subtype_vn_proc;               \
17974   /* These are used for autopopulating text fields */ \
17975   GetAutoPopulateTextFunc  get_autopopulate_text;     \
17976   Nlm_ChangeNotifyProc     change_notify;             \
17977   Pointer                  change_userdata;           \
17978   Uint2                    entityID;
17979 
17980 typedef struct simpleaecrdlg
17981 {
17982   AECR_BLOCK
17983 } SimpleAECRDlgData, PNTR SimpleAECRDlgPtr;
17984 
ClearTextSimpleAECRDlg(SimpleAECRDlgPtr dlg)17985 static void ClearTextSimpleAECRDlg (SimpleAECRDlgPtr dlg)
17986 {
17987   if (dlg != NULL)
17988   {
17989     PointerToDialog (dlg->edit_apply, NULL);
17990     PointerToDialog (dlg->text_portion, NULL);
17991   }
17992 }
17993 
ResetSimpleAECRDlg(SimpleAECRDlgPtr dlg)17994 static void ResetSimpleAECRDlg (SimpleAECRDlgPtr dlg)
17995 {
17996   if (dlg != NULL)
17997   {
17998     PointerToDialog (dlg->field_list, NULL);
17999     PointerToDialog (dlg->field_list_to, NULL);
18000     PointerToDialog (dlg->subtype_list, NULL);
18001     PointerToDialog (dlg->text_portion, NULL);
18002     SafeSetStatus (dlg->leave_on_original, FALSE);
18003     SafeSetStatus (dlg->strip_name_from_text, FALSE);
18004     SafeSetStatus (dlg->remove_parsed, FALSE);
18005     ClearTextSimpleAECRDlg (dlg);
18006   }
18007 }
18008 
SimpleAECRToDialog(DialoG d,Pointer userdata)18009 static void SimpleAECRToDialog (DialoG d, Pointer userdata)
18010 {
18011   SimpleAECRDlgPtr dlg;
18012   SimpleAECRPtr    data;
18013 
18014   dlg = (SimpleAECRDlgPtr) GetObjectExtra (d);
18015   if (dlg == NULL)
18016   {
18017     return;
18018   }
18019 
18020   ResetSimpleAECRDlg (dlg);
18021   data = (SimpleAECRPtr) userdata;
18022   if (data != NULL)
18023   {
18024     PointerToDialog (dlg->field_list, data->field_list);
18025     PointerToDialog (dlg->field_list_to, data->field_list_to);
18026     SendMessageToDialog (dlg->field_list_to, NUM_VIB_MSG + 1);
18027     PointerToDialog (dlg->subtype_list, data->subtype_list);
18028     PointerToDialog (dlg->edit_apply, data->edit_apply);
18029     PointerToDialog (dlg->text_portion, data->text_portion);
18030     SafeSetValue (dlg->leave_on_original, data->leave_on_original);
18031     SafeSetValue (dlg->strip_name_from_text, data->strip_name_from_text);
18032     SafeSetStatus (dlg->remove_parsed, data->remove_parsed);
18033     dlg->free_field_vn_proc = data->free_field_vn_proc;
18034     dlg->free_subtype_vn_proc = data->free_subtype_vn_proc;
18035   }
18036   else
18037   {
18038     SendMessageToDialog (dlg->field_list, NUM_VIB_MSG + 1);
18039     SendMessageToDialog (dlg->field_list_to, NUM_VIB_MSG + 1);
18040   }
18041 }
18042 
DialogToSimpleAECR(DialoG d)18043 static Pointer DialogToSimpleAECR (DialoG d)
18044 {
18045   SimpleAECRDlgPtr dlg;
18046   SimpleAECRPtr    data;
18047 
18048   dlg = (SimpleAECRDlgPtr) GetObjectExtra (d);
18049   if (dlg == NULL)
18050   {
18051     return NULL;
18052   }
18053 
18054   data = (SimpleAECRPtr) MemNew (sizeof (SimpleAECRData));
18055   if (data != NULL)
18056   {
18057     data->field_list = DialogToPointer (dlg->field_list);
18058     data->field_list_to = DialogToPointer (dlg->field_list_to);
18059     data->subtype_list = DialogToPointer (dlg->subtype_list);
18060     data->edit_apply = DialogToPointer (dlg->edit_apply);
18061     data->text_portion = DialogToPointer (dlg->text_portion);
18062     if (dlg->remove_parsed == NULL) {
18063       data->remove_parsed = FALSE;
18064     }
18065     else
18066     {
18067       data->remove_parsed = GetStatus (dlg->remove_parsed);
18068     }
18069     if (dlg->leave_on_original != NULL)
18070     {
18071       data->leave_on_original = GetStatus (dlg->leave_on_original);
18072     }
18073     else
18074     {
18075       data->leave_on_original = FALSE;
18076     }
18077     if (dlg->strip_name_from_text != NULL)
18078     {
18079       data->strip_name_from_text = GetStatus (dlg->strip_name_from_text);
18080     }
18081     else
18082     {
18083       data->strip_name_from_text = FALSE;
18084     }
18085     data->free_field_vn_proc = dlg->free_field_vn_proc;
18086     data->free_subtype_vn_proc = dlg->free_subtype_vn_proc;
18087   }
18088   return data;
18089 }
18090 
SimpleAECRDialogChangeNotify(Pointer userdata)18091 static void SimpleAECRDialogChangeNotify (Pointer userdata)
18092 {
18093   SimpleAECRDlgPtr dlg;
18094   CharPtr          autopopulate_text;
18095   EditApplyPtr     eap;
18096   ValNodePtr       subtype_list, field_list;
18097 
18098   dlg = (SimpleAECRDlgPtr) userdata;
18099   if (dlg == NULL)
18100   {
18101     return;
18102   }
18103 
18104   if (dlg->get_autopopulate_text != NULL
18105       && (dlg->action_choice == AECR_APPLY || dlg->action_choice == AECR_EDIT))
18106   {
18107     eap = DialogToPointer (dlg->edit_apply);
18108     subtype_list = DialogToPointer (dlg->subtype_list);
18109     field_list = DialogToPointer (dlg->field_list);
18110     autopopulate_text = (dlg->get_autopopulate_text) (subtype_list, field_list, dlg->entityID);
18111     subtype_list = ValNodeFuncFree (subtype_list, dlg->free_subtype_vn_proc);
18112     field_list = ValNodeFuncFree (field_list, dlg->free_field_vn_proc);
18113     if (dlg->action_choice == AECR_APPLY)
18114     {
18115       eap->apply_txt = MemFree (eap->find_txt);
18116       eap->apply_txt = autopopulate_text;
18117     }
18118     else
18119     {
18120       eap->find_txt = MemFree (eap->find_txt);
18121       eap->find_txt = autopopulate_text;
18122     }
18123     PointerToDialog (dlg->edit_apply, eap);
18124     EditApplyFree (eap);
18125   }
18126 
18127   if (dlg->change_notify != NULL)
18128   {
18129     (dlg->change_notify) (dlg->change_userdata);
18130   }
18131 }
18132 
18133 
SimpleAECRMessage(DialoG d,Int2 mssg)18134 static void SimpleAECRMessage (DialoG d, Int2 mssg)
18135 
18136 {
18137   SimpleAECRDlgPtr  dlg;
18138 
18139   dlg = (SimpleAECRDlgPtr) GetObjectExtra (d);
18140   if (dlg != NULL) {
18141     switch (mssg)
18142     {
18143       case VIB_MSG_INIT :
18144         /* reset list */
18145         ResetSimpleAECRDlg (dlg);
18146         break;
18147       case VIB_MSG_ENTER :
18148         if (dlg->subtype_list != NULL)
18149         {
18150           Select (dlg->subtype_list);
18151         }
18152         else
18153         {
18154           Select (dlg->field_list);
18155         }
18156         break;
18157       case AECR_VIB_MSG_SET_DEFAULT :
18158         SendMessageToDialog (dlg->field_list, AECR_VIB_MSG_SET_DEFAULT);
18159         SendMessageToDialog (dlg->field_list_to, AECR_VIB_MSG_SET_DEFAULT);
18160         SendMessageToDialog (dlg->subtype_list, AECR_VIB_MSG_SET_DEFAULT);
18161         ClearTextSimpleAECRDlg (dlg);
18162         break;
18163       case AECR_VIB_MSG_AUTOPOPULATE:
18164         SimpleAECRDialogChangeNotify (dlg);
18165         break;
18166       case AECR_VIB_MSG_CLEAR_TEXT :
18167         ClearTextSimpleAECRDlg (dlg);
18168         break;
18169       default :
18170         break;
18171     }
18172   }
18173 }
18174 
TestSimpleAECR(DialoG d)18175 static ValNodePtr TestSimpleAECR (DialoG d)
18176 {
18177   SimpleAECRDlgPtr dlg;
18178   ValNodePtr       err_list = NULL;
18179   ValNodePtr       total_err_list = NULL;
18180 
18181   dlg = (SimpleAECRDlgPtr) GetObjectExtra (d);
18182   if (dlg == NULL)
18183   {
18184     return FALSE;
18185   }
18186 
18187   total_err_list = TestDialog (dlg->field_list);
18188 
18189   if (dlg->subtype_list != NULL)
18190   {
18191     err_list = TestDialog (dlg->subtype_list);
18192     total_err_list = ValNodeAppend (total_err_list, err_list);
18193   }
18194 
18195   err_list = NULL;
18196   switch (dlg->action_choice)
18197   {
18198     case AECR_CONVERT:
18199     case AECR_SWAP:
18200       err_list = TestDialog (dlg->field_list_to);
18201       break;
18202     case AECR_APPLY:
18203     case AECR_EDIT:
18204       err_list = TestDialog (dlg->edit_apply);
18205       break;
18206   }
18207 
18208   total_err_list = ValNodeAppend (total_err_list, err_list);
18209 
18210   return total_err_list;
18211 }
18212 
SimpleAECRButtonChange(ButtoN b)18213 static void SimpleAECRButtonChange (ButtoN b)
18214 {
18215   SimpleAECRDlgPtr dlg;
18216 
18217   dlg = (SimpleAECRDlgPtr) GetObjectExtra (b);
18218   if (dlg == NULL) return;
18219 
18220   if (dlg->change_notify != NULL)
18221   {
18222     (dlg->change_notify) (dlg->change_userdata);
18223   }
18224 }
18225 
SimpleAECRDialogEx(GrouP h,Int4 action_choice,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,FreeValNodeProc free_field_vn_proc,FreeValNodeProc free_subtype_vn_proc,Nlm_FieldListDlgProc fieldlist_dlg_proc,Nlm_SubtypeListDlgProc subtypelist_dlg_proc,GetAutoPopulateTextFunc get_autopopulate_text,CharPtr field_label,CharPtr subtype_label,Boolean is_text,Boolean strip_name,Uint2 entityID)18226 static DialoG SimpleAECRDialogEx
18227 (GrouP                    h,
18228  Int4                     action_choice,
18229  Nlm_ChangeNotifyProc     change_notify,
18230  Pointer                  change_userdata,
18231  FreeValNodeProc          free_field_vn_proc,
18232  FreeValNodeProc          free_subtype_vn_proc,
18233  Nlm_FieldListDlgProc     fieldlist_dlg_proc,
18234  Nlm_SubtypeListDlgProc   subtypelist_dlg_proc,
18235  GetAutoPopulateTextFunc  get_autopopulate_text,
18236  CharPtr                  field_label,
18237  CharPtr                  subtype_label,
18238  Boolean                  is_text,
18239  Boolean                  strip_name,
18240  Uint2                    entityID)
18241 {
18242   SimpleAECRDlgPtr dlg;
18243   GrouP            p, g1;
18244   SeqEntryPtr      sep;
18245 
18246   dlg = (SimpleAECRDlgPtr) MemNew (sizeof (SimpleAECRDlgData));
18247   if (dlg == NULL)
18248   {
18249     return NULL;
18250   }
18251 
18252   p = HiddenGroup (h, -1, 0, NULL);
18253   SetObjectExtra (p, dlg, StdCleanupExtraProc);
18254   SetGroupSpacing (p, 10, 10);
18255 
18256   dlg->dialog = (DialoG) p;
18257   dlg->todialog = SimpleAECRToDialog;
18258   dlg->fromdialog = DialogToSimpleAECR;
18259   dlg->dialogmessage = SimpleAECRMessage;
18260   dlg->testdialog = TestSimpleAECR;
18261   dlg->action_choice = action_choice;
18262   dlg->free_field_vn_proc = free_field_vn_proc;
18263   dlg->free_subtype_vn_proc = free_subtype_vn_proc;
18264   dlg->change_notify = change_notify;
18265   dlg->change_userdata = change_userdata;
18266   dlg->get_autopopulate_text = get_autopopulate_text;
18267   dlg->entityID = entityID;
18268   dlg->strip_name_from_text = NULL;
18269 
18270   dlg->subtype_list = NULL;
18271 
18272   sep = GetTopSeqEntryForEntityID(entityID);
18273 
18274   if (action_choice == AECR_CONVERT || action_choice == AECR_SWAP || action_choice == AECR_PARSE)
18275   {
18276     if (subtypelist_dlg_proc == NULL)
18277     {
18278       g1 = HiddenGroup (p, 2, 0, NULL);
18279     }
18280     else
18281     {
18282       g1 = HiddenGroup (p, 3, 0, NULL);
18283       StaticPrompt (g1, subtype_label, 0, dialogTextHeight, systemFont, 'l');
18284     }
18285     StaticPrompt (g1, "From", 0, dialogTextHeight, systemFont, 'l');
18286     StaticPrompt (g1, "To", 0, dialogTextHeight, systemFont, 'l');
18287 
18288     if (subtypelist_dlg_proc != NULL)
18289     {
18290       dlg->subtype_list = (subtypelist_dlg_proc) (g1, TRUE, sep, change_notify, change_userdata);
18291     }
18292     dlg->field_list = fieldlist_dlg_proc (g1, FALSE,
18293                                           change_notify,
18294                                           change_userdata);
18295     dlg->field_list_to = fieldlist_dlg_proc (g1, FALSE,
18296                                              change_notify,
18297                                              change_userdata);
18298     if (action_choice == AECR_CONVERT && is_text)
18299     {
18300       dlg->leave_on_original = CheckBox (p, "Leave on original", SimpleAECRButtonChange);
18301       SetObjectExtra (dlg->leave_on_original, dlg, NULL);
18302     }
18303     if (strip_name)
18304     {
18305       dlg->strip_name_from_text = CheckBox (p, "Strip name from text", SimpleAECRButtonChange);
18306       SetObjectExtra (dlg->strip_name_from_text, dlg, NULL);
18307     }
18308   }
18309   else
18310   {
18311     if (subtypelist_dlg_proc == NULL)
18312     {
18313       g1 = HiddenGroup (p, 1, 0, NULL);
18314 
18315     }
18316     else
18317     {
18318       g1 = HiddenGroup (p, 2, 0, NULL);
18319       StaticPrompt (g1, subtype_label, 0, dialogTextHeight, systemFont, 'l');
18320     }
18321     StaticPrompt (g1, field_label, 0, dialogTextHeight, systemFont, 'l');
18322     if (action_choice == AECR_REMOVE)
18323     {
18324       if (subtypelist_dlg_proc != NULL)
18325       {
18326         dlg->subtype_list = (subtypelist_dlg_proc) (g1, TRUE, sep, change_notify, change_userdata);
18327       }
18328       dlg->field_list = fieldlist_dlg_proc (g1, TRUE,
18329                                             change_notify,
18330                                             change_userdata);
18331     }
18332     else
18333     {
18334       if (subtypelist_dlg_proc != NULL)
18335       {
18336         dlg->subtype_list = (subtypelist_dlg_proc) (g1, TRUE, sep,
18337                                                     SimpleAECRDialogChangeNotify,
18338                                                     dlg);
18339       }
18340       dlg->field_list = fieldlist_dlg_proc (g1, FALSE,
18341                                             SimpleAECRDialogChangeNotify,
18342                                             dlg);
18343     }
18344   }
18345 
18346   if (is_text && (action_choice == AECR_APPLY || action_choice == AECR_EDIT))
18347   {
18348     dlg->edit_apply = EditApplyDialog (p,
18349                                        action_choice == AECR_APPLY ? eEditApplyChoice_Apply : eEditApplyChoice_Edit,
18350                                        "New Text", NULL,
18351                                        change_notify, change_userdata);
18352     dlg->text_portion = NULL;
18353     dlg->remove_parsed = NULL;
18354   }
18355   else if (action_choice == AECR_PARSE)
18356   {
18357     dlg->edit_apply = NULL;
18358     if (is_text) {
18359         dlg->text_portion = TextPortionXDialog(p);
18360     }
18361     dlg->remove_parsed = CheckBox (p, "Remove from parsed field", SimpleAECRButtonChange);
18362     SetObjectExtra (dlg->remove_parsed, dlg, NULL);
18363   }
18364   else
18365   {
18366     dlg->edit_apply = NULL;
18367     dlg->text_portion = NULL;
18368     dlg->remove_parsed = NULL;
18369   }
18370 
18371   if (action_choice == AECR_CONVERT)
18372   {
18373     if (is_text)
18374     {
18375       AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->leave_on_original, (HANDLE) dlg->strip_name_from_text, NULL);
18376     }
18377     else
18378     {
18379       AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->strip_name_from_text, NULL);
18380     }
18381   }
18382   else if (action_choice == AECR_SWAP)
18383   {
18384     AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->strip_name_from_text, NULL);
18385   }
18386   else if (action_choice == AECR_PARSE)
18387   {
18388     AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->text_portion, (HANDLE) dlg->remove_parsed, NULL);
18389   }
18390   else
18391   {
18392     AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->edit_apply, NULL);
18393   }
18394   return (DialoG) p;
18395 }
18396 
SimpleAECRDialog(GrouP h,Int4 action_choice,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,FreeValNodeProc free_field_vn_proc,FreeValNodeProc free_subtype_vn_proc,Nlm_FieldListDlgProc fieldlist_dlg_proc,Nlm_SubtypeListDlgProc subtypelist_dlg_proc,GetAutoPopulateTextFunc get_autopopulate_text,CharPtr field_label,CharPtr subtype_label,Boolean is_text,Uint2 entityID)18397 static DialoG SimpleAECRDialog
18398 (GrouP                    h,
18399  Int4                     action_choice,
18400  Nlm_ChangeNotifyProc     change_notify,
18401  Pointer                  change_userdata,
18402  FreeValNodeProc          free_field_vn_proc,
18403  FreeValNodeProc          free_subtype_vn_proc,
18404  Nlm_FieldListDlgProc     fieldlist_dlg_proc,
18405  Nlm_SubtypeListDlgProc   subtypelist_dlg_proc,
18406  GetAutoPopulateTextFunc  get_autopopulate_text,
18407  CharPtr                  field_label,
18408  CharPtr                  subtype_label,
18409  Boolean                  is_text,
18410  Uint2                    entityID)
18411 {
18412   return SimpleAECRDialogEx(h, action_choice, change_notify, change_userdata,
18413                             free_field_vn_proc, free_subtype_vn_proc,
18414                             fieldlist_dlg_proc, subtypelist_dlg_proc,
18415                             get_autopopulate_text,
18416                             field_label, subtype_label,
18417                             is_text, FALSE, entityID);
18418 }
18419 
18420 static CharPtr
CDSGeneProtAutopopulate(ValNodePtr subtype_list,ValNodePtr field_list,Uint2 entityID)18421 CDSGeneProtAutopopulate
18422 (ValNodePtr subtype_list,
18423  ValNodePtr field_list,
18424  Uint2 entityID)
18425 {
18426   GetSamplePtr gsp;
18427   CharPtr      rval;
18428 
18429   gsp = CheckForExistingText (entityID, field_list,
18430                               GetCDSGeneProtField,
18431                               NULL,
18432                               NULL,
18433                               IntValNodeCopy,
18434                               NULL,
18435                               0, 0, 0);
18436   rval = gsp->sample_text;
18437   gsp->sample_text = NULL;
18438   GetSampleFree (gsp);
18439   return rval;
18440 }
18441 
18442 typedef struct cdsgeneprotaecrdlg
18443 {
18444   AECR_BLOCK
18445   ButtoN also_mrna;
18446 } CDSGeneProtAECRDlgData, PNTR CDSGeneProtAECRDlgPtr;
18447 
18448 typedef struct cdsgeneprotaecr
18449 {
18450   AECR_DATA_BLOCK
18451   Boolean also_mrna;
18452 } CDSGeneProtAECRData, PNTR CDSGeneProtAECRPtr;
18453 
18454 
CDSGeneProtAECRFree(CDSGeneProtAECRPtr sp)18455 static CDSGeneProtAECRPtr CDSGeneProtAECRFree (CDSGeneProtAECRPtr sp)
18456 {
18457   if (sp != NULL)
18458   {
18459     AECRDataBlockFreeContents ((SimpleAECRPtr) sp);
18460     sp = MemFree (sp);
18461   }
18462   return sp;
18463 }
18464 
18465 
PointerToCDSGeneProtAECRDialog(DialoG d,Pointer userdata)18466 static void PointerToCDSGeneProtAECRDialog (DialoG d, Pointer userdata)
18467 {
18468   CDSGeneProtAECRDlgPtr dlg;
18469   CDSGeneProtAECRPtr    data;
18470 
18471   dlg = (CDSGeneProtAECRDlgPtr) GetObjectExtra (d);
18472   if (dlg == NULL) return;
18473   data = (CDSGeneProtAECRPtr) userdata;
18474   SimpleAECRToDialog (d, userdata);
18475   if (data != NULL)
18476   {
18477     SetStatus (dlg->also_mrna, data->also_mrna);
18478   }
18479 
18480 }
18481 
18482 
ShowingProteinName(CDSGeneProtAECRDlgPtr dlg)18483 static Boolean ShowingProteinName (CDSGeneProtAECRDlgPtr dlg)
18484 {
18485   ValNodePtr vnp_from, vnp_to;
18486   Int4       protein_name_field_num = 2 + num_gene_fields + num_mrna_fields;
18487   Boolean    rval = FALSE;
18488 
18489   if (dlg == NULL) return FALSE;
18490 
18491   vnp_from = DialogToPointer (dlg->field_list);
18492   vnp_to = DialogToPointer (dlg->field_list_to);
18493 
18494   if ((vnp_from != NULL && vnp_from->data.intvalue == protein_name_field_num)
18495       || (vnp_to != NULL && vnp_to->data.intvalue == protein_name_field_num))
18496   {
18497     rval = TRUE;
18498   }
18499   vnp_from = ValNodeFree (vnp_from);
18500   vnp_to = ValNodeFree (vnp_to);
18501 
18502   return rval;
18503 }
18504 
18505 
CDSGeneProtAECRDialogToPointer(DialoG d)18506 static Pointer CDSGeneProtAECRDialogToPointer (DialoG d)
18507 {
18508   CDSGeneProtAECRDlgPtr dlg;
18509   SimpleAECRPtr         subset;
18510   CDSGeneProtAECRPtr    data = NULL;
18511 
18512   dlg = (CDSGeneProtAECRDlgPtr) GetObjectExtra (d);
18513   if (dlg == NULL) return NULL;
18514 
18515   subset = DialogToSimpleAECR (d);
18516   if (subset != NULL)
18517   {
18518     data = (CDSGeneProtAECRPtr) MemNew (sizeof (CDSGeneProtAECRData));
18519     MemCpy (data, subset, sizeof (SimpleAECRData));
18520     MemSet (subset, 0, sizeof (SimpleAECRData));
18521     subset = MemFree (subset);
18522     if (ShowingProteinName (dlg))
18523     {
18524       data->also_mrna = GetStatus (dlg->also_mrna);
18525     }
18526     else
18527     {
18528       data->also_mrna = FALSE;
18529     }
18530   }
18531   return data;
18532 }
18533 
18534 
CDSGeneProtAECRDialogChange(Pointer data)18535 static void CDSGeneProtAECRDialogChange (Pointer data)
18536 {
18537   CDSGeneProtAECRDlgPtr dlg;
18538 
18539   dlg = (CDSGeneProtAECRDlgPtr) data;
18540   if (dlg == NULL) return;
18541 
18542   if (ShowingProteinName (dlg))
18543   {
18544     Show (dlg->also_mrna);
18545   }
18546   else
18547   {
18548     Hide (dlg->also_mrna);
18549   }
18550 
18551   SimpleAECRDialogChangeNotify (dlg);
18552 }
18553 
18554 
CDSGeneProtAECRDialog(GrouP h,Int4 action_choice,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Uint2 entityID)18555 static DialoG CDSGeneProtAECRDialog
18556 (GrouP                    h,
18557  Int4                     action_choice,
18558  Nlm_ChangeNotifyProc     change_notify,
18559  Pointer                  change_userdata,
18560  Uint2                    entityID)
18561 {
18562   CDSGeneProtAECRDlgPtr dlg;
18563   GrouP                 p, g1;
18564   SeqEntryPtr           sep;
18565 
18566   dlg = (CDSGeneProtAECRDlgPtr) MemNew (sizeof (CDSGeneProtAECRDlgData));
18567   if (dlg == NULL)
18568   {
18569     return NULL;
18570   }
18571 
18572   p = HiddenGroup (h, -1, 0, NULL);
18573   SetObjectExtra (p, dlg, StdCleanupExtraProc);
18574   SetGroupSpacing (p, 10, 10);
18575 
18576   dlg->dialog = (DialoG) p;
18577   dlg->todialog = PointerToCDSGeneProtAECRDialog;
18578   dlg->fromdialog = CDSGeneProtAECRDialogToPointer;
18579   dlg->dialogmessage = SimpleAECRMessage;
18580   dlg->testdialog = TestSimpleAECR;
18581   dlg->action_choice = action_choice;
18582   dlg->free_field_vn_proc = NULL;
18583   dlg->free_subtype_vn_proc = NULL;
18584   dlg->change_notify = change_notify;
18585   dlg->change_userdata = change_userdata;
18586   dlg->get_autopopulate_text = CDSGeneProtAutopopulate;
18587   dlg->entityID = entityID;
18588   dlg->strip_name_from_text = NULL;
18589 
18590   dlg->subtype_list = NULL;
18591 
18592   sep = GetTopSeqEntryForEntityID(entityID);
18593 
18594   if (action_choice == AECR_CONVERT || action_choice == AECR_SWAP || action_choice == AECR_PARSE)
18595   {
18596     g1 = HiddenGroup (p, 2, 0, NULL);
18597     StaticPrompt (g1, "From", 0, dialogTextHeight, systemFont, 'l');
18598     StaticPrompt (g1, "To", 0, dialogTextHeight, systemFont, 'l');
18599 
18600     dlg->field_list = CDSGeneProtFieldSelectionDialog (g1, FALSE,
18601                                           CDSGeneProtAECRDialogChange,
18602                                           dlg);
18603     dlg->field_list_to = CDSGeneProtFieldSelectionDialog (g1, FALSE,
18604                                              CDSGeneProtAECRDialogChange,
18605                                              dlg);
18606     if (action_choice == AECR_CONVERT)
18607     {
18608       dlg->leave_on_original = CheckBox (p, "Leave on original", NULL);
18609     }
18610   }
18611   else
18612   {
18613     g1 = HiddenGroup (p, 1, 0, NULL);
18614     StaticPrompt (g1, "Field", 0, dialogTextHeight, systemFont, 'l');
18615     if (action_choice == AECR_REMOVE)
18616     {
18617       dlg->field_list = CDSGeneProtFieldSelectionDialog (g1, TRUE,
18618                                             CDSGeneProtAECRDialogChange,
18619                                             dlg);
18620     }
18621     else
18622     {
18623       dlg->field_list = CDSGeneProtFieldSelectionDialog (g1, FALSE,
18624                                             CDSGeneProtAECRDialogChange,
18625                                             dlg);
18626     }
18627   }
18628 
18629   if (action_choice == AECR_APPLY || action_choice == AECR_EDIT)
18630   {
18631     dlg->edit_apply = EditApplyDialog (p,
18632                                        action_choice == AECR_APPLY ? eEditApplyChoice_Apply : eEditApplyChoice_Edit,
18633                                        "New Text", NULL,
18634                                        change_notify, change_userdata);
18635     dlg->text_portion = NULL;
18636     dlg->remove_parsed = NULL;
18637   }
18638   else if (action_choice == AECR_PARSE)
18639   {
18640     dlg->edit_apply = NULL;
18641     dlg->text_portion = TextPortionXDialog(p);
18642     dlg->remove_parsed = CheckBox (p, "Remove from parsed field", NULL);
18643   }
18644   else
18645   {
18646     dlg->edit_apply = NULL;
18647     dlg->text_portion = NULL;
18648     dlg->remove_parsed = NULL;
18649   }
18650 
18651   dlg->also_mrna = CheckBox (p, "Make mRNA product match CDS protein name", NULL);
18652 
18653   if (action_choice == AECR_CONVERT)
18654   {
18655     AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->leave_on_original, (HANDLE) dlg->also_mrna, NULL);
18656   }
18657   else if (action_choice == AECR_SWAP)
18658   {
18659     AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->strip_name_from_text, (HANDLE) dlg->also_mrna, NULL);
18660   }
18661   else if (action_choice == AECR_PARSE)
18662   {
18663     AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->text_portion, (HANDLE) dlg->remove_parsed, (HANDLE) dlg->also_mrna, NULL);
18664   }
18665   else
18666   {
18667     AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->edit_apply, (HANDLE) dlg->also_mrna, NULL);
18668   }
18669   return (DialoG) p;
18670 }
18671 
18672 
AddStringToSample(CharPtr str,GetSamplePtr gsp)18673 static void AddStringToSample (CharPtr str, GetSamplePtr gsp)
18674 {
18675   if (gsp == NULL) return;
18676 
18677   if (str != NULL)
18678   {
18679     gsp->num_found ++;
18680   }
18681   if (gsp->sample_text == NULL)
18682   {
18683     gsp->sample_text = StringSave (str);
18684   }
18685   else
18686   {
18687     if (StringCmp (str, gsp->sample_text) != 0)
18688     {
18689       gsp->all_same = FALSE;
18690     }
18691   }
18692 }
18693 
18694 static GetSamplePtr
GetCDSGeneProtAECRSample(ValNodePtr cdset_list,ValNodePtr field_list,ValNodePtr field_list_to,FilterSetPtr fsp)18695 GetCDSGeneProtAECRSample
18696 (ValNodePtr cdset_list,
18697  ValNodePtr field_list,
18698  ValNodePtr field_list_to,
18699  FilterSetPtr fsp)
18700 {
18701   GetSamplePtr gsp;
18702   ValNodePtr   cdset_vnp, sfp_vnp;
18703   CharPtr      str;
18704   CDSetPtr       cdsp;
18705 
18706   gsp = (GetSamplePtr) MemNew (sizeof (GetSampleData));
18707   if (gsp == NULL)
18708   {
18709     return NULL;
18710   }
18711   gsp->free_vn_proc = NULL;
18712   gsp->copy_vn_proc = IntValNodeCopy;
18713   for (cdset_vnp = cdset_list; cdset_vnp != NULL; cdset_vnp = cdset_vnp->next)
18714   {
18715     cdsp = (CDSetPtr) cdset_vnp->data.ptrvalue;
18716     if (IsCDSetMatPeptideQualChoice(field_list) || IsCDSetMatPeptideQualChoice(field_list_to))
18717     {
18718       /* need to look at all mat_peptide features */
18719       for (sfp_vnp = cdsp->prot_list; sfp_vnp != NULL; sfp_vnp = sfp_vnp->next)
18720       {
18721         if (fsp != NULL && fsp->cgp != NULL && DoesConstraintDisqualifyFeature (sfp_vnp->data.ptrvalue, fsp->cgp))
18722         {
18723           /* this feature will be skipped in the action, so it should not be included in the sample */
18724         }
18725         else
18726         {
18727           str = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, field_list, fsp);
18728           if (str != NULL && field_list_to != NULL)
18729           {
18730             str = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, field_list_to, fsp);
18731           }
18732           AddStringToSample (str, gsp);
18733           str = MemFree (str);
18734         }
18735       }
18736     } else {
18737       str = GetCDSetField (cdsp, field_list);
18738       if (str != NULL && field_list_to != NULL)
18739       {
18740         str = MemFree (str);
18741         str = GetCDSetField (cdset_vnp->data.ptrvalue, field_list_to);
18742       }
18743       AddStringToSample (str, gsp);
18744       str = MemFree (str);
18745     }
18746   }
18747   return gsp;
18748 }
18749 
FeatureTypeMissingFromCDSet(CDSetPtr cdsp,Uint2 choice)18750 static Boolean FeatureTypeMissingFromCDSet (CDSetPtr cdsp, Uint2 choice)
18751 {
18752   ValNodePtr vnp;
18753   SeqFeatPtr sfp;
18754   Boolean    is_missing = TRUE;
18755 
18756   if (cdsp == NULL) return TRUE;
18757   switch (choice)
18758   {
18759     case FEATDEF_CDS:
18760       if (cdsp->cds_list != NULL)
18761       {
18762         is_missing = FALSE;
18763       }
18764       break;
18765     case FEATDEF_GENE:
18766       if (cdsp->gene_list != NULL)
18767       {
18768         is_missing = FALSE;
18769       }
18770       break;
18771     case FEATDEF_mRNA:
18772       if (cdsp->mrna_list != NULL)
18773       {
18774         is_missing = FALSE;
18775       }
18776       break;
18777     case FEATDEF_PROT:
18778     case FEATDEF_mat_peptide_aa:
18779       for (vnp = cdsp->prot_list; vnp != NULL; vnp = vnp->next)
18780       {
18781         sfp = (SeqFeatPtr) vnp->data.ptrvalue;
18782         if (sfp != NULL && sfp->idx.subtype == choice)
18783         {
18784           is_missing = FALSE;
18785         }
18786       }
18787       break;
18788   }
18789   return is_missing;
18790 }
18791 
18792 static Int4
CountMissingFeatures(ValNodePtr cdset_list,ValNodePtr field_list,ValNodePtr field_list_to,FilterSetPtr fsp)18793 CountMissingFeatures
18794 (ValNodePtr cdset_list,
18795  ValNodePtr field_list,
18796  ValNodePtr field_list_to,
18797  FilterSetPtr fsp)
18798 {
18799   ValNodePtr   cdset_vnp, sfp_vnp;
18800   CharPtr      str;
18801   CDSetPtr     cdsp;
18802   Uint2        choice_from, choice_to;
18803   Int4         num_missing = 0;
18804 
18805   choice_from = FeatDefTypeFromFieldList (field_list);
18806   choice_to = FeatDefTypeFromFieldList (field_list_to);
18807 
18808   if (choice_from == 0 || choice_to == 0 || choice_from == choice_to)
18809   {
18810     return 0;
18811   }
18812 
18813   for (cdset_vnp = cdset_list; cdset_vnp != NULL; cdset_vnp = cdset_vnp->next)
18814   {
18815     cdsp = (CDSetPtr) cdset_vnp->data.ptrvalue;
18816 
18817     if (choice_from == FEATDEF_mat_peptide_aa)
18818     {
18819       /* need to look at all mat_peptide features */
18820       for (sfp_vnp = cdsp->prot_list; sfp_vnp != NULL; sfp_vnp = sfp_vnp->next)
18821       {
18822         if (fsp != NULL && fsp->cgp != NULL && DoesConstraintDisqualifyFeature (sfp_vnp->data.ptrvalue, fsp->cgp))
18823         {
18824           /* this feature will be skipped in the action, so it doesn't count towards missing sets */
18825         }
18826         else
18827         {
18828           str = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, field_list, fsp);
18829           if (str != NULL)
18830           {
18831             if (FeatureTypeMissingFromCDSet (cdsp, choice_to))
18832             {
18833               num_missing++;
18834             }
18835           }
18836           str = MemFree (str);
18837         }
18838       }
18839     } else {
18840       str = GetCDSetField (cdsp, field_list);
18841       if (str != NULL)
18842       {
18843         if (FeatureTypeMissingFromCDSet (cdsp, choice_to))
18844         {
18845           num_missing++;
18846         }
18847       }
18848       str = MemFree (str);
18849     }
18850   }
18851   return num_missing;
18852 }
18853 
18854 
18855 /* things get tricksy when we're dealing with mat_peptides, because there
18856  * can be more than one of them in the CDS-mRNA-Gene-Prot group.
18857  */
18858 
CDSGeneProtApplyToAllThatMatchFilter(CharPtr str_src,CDSetPtr cdsp,ValNodePtr field_list_to,FilterSetPtr fsp,ExistingTextPtr etp)18859 static Boolean CDSGeneProtApplyToAllThatMatchFilter
18860 (CharPtr         str_src,
18861  CDSetPtr        cdsp,
18862  ValNodePtr      field_list_to,
18863  FilterSetPtr    fsp,
18864  ExistingTextPtr etp)
18865 {
18866   ApplyValueData avd;
18867 
18868   avd.where_to_replace = EditApplyFindLocation_anywhere;
18869 
18870   /* build gene if we're applying to gene but gene doesn't already exist */
18871   BuildNewCDSGeneProtFeature (cdsp, field_list_to, NULL);
18872   avd.field_list = NULL;
18873   avd.new_text = str_src;
18874   avd.text_to_replace = NULL;
18875   avd.etp = etp;
18876 
18877   return SetCDSetField (cdsp, field_list_to, &avd, fsp);
18878 }
18879 
CDSGeneProtApplyToOneFeature(CharPtr str_src,SeqFeatPtr sfp,ValNodePtr field_list_to,FilterSetPtr fsp,ExistingTextPtr etp)18880 static Boolean CDSGeneProtApplyToOneFeature
18881 (CharPtr         str_src,
18882  SeqFeatPtr      sfp,
18883  ValNodePtr      field_list_to,
18884  FilterSetPtr    fsp,
18885  ExistingTextPtr etp)
18886 {
18887   ApplyValueData avd;
18888 
18889   avd.where_to_replace = EditApplyFindLocation_anywhere;
18890 
18891   avd.field_list = NULL;
18892   avd.new_text = str_src;
18893   avd.text_to_replace = NULL;
18894   avd.etp = etp;
18895 
18896   return SetCDSGeneProtField (sfp, field_list_to, &avd, fsp);
18897 }
18898 
18899 
CopyProteinNameTomRNAName(CDSetPtr cdsp)18900 static void CopyProteinNameTomRNAName (CDSetPtr cdsp)
18901 {
18902   Int4    protein_name_field_num = 2 + num_gene_fields + num_mrna_fields;
18903   Int4    mrna_product_field_num = 2 + num_gene_fields;
18904   ValNode vn_src, vn_dst;
18905   ApplyValueData avd;
18906 
18907   vn_src.data.intvalue = protein_name_field_num;
18908   vn_src.next = NULL;
18909   vn_src.choice = 0;
18910 
18911   vn_dst.data.intvalue = mrna_product_field_num;
18912   vn_dst.next = NULL;
18913   vn_dst.choice = 0;
18914 
18915   avd.new_text = GetCDSetField (cdsp, &vn_src);
18916   avd.etp = NULL;
18917   avd.field_list = NULL;
18918   avd.text_to_replace = NULL;
18919   avd.where_to_replace = EditApplyFindLocation_anywhere;
18920   SetCDSetField (cdsp, &vn_dst, &avd, NULL);
18921 }
18922 
CDSGeneProtConvert(CDSetPtr cdsp,CDSGeneProtAECRPtr sp,FilterSetPtr fsp,ExistingTextPtr etp,Boolean build_missing)18923 static void CDSGeneProtConvert
18924 (CDSetPtr        cdsp,
18925  CDSGeneProtAECRPtr   sp,
18926  FilterSetPtr    fsp,
18927  ExistingTextPtr etp,
18928  Boolean         build_missing)
18929 {
18930   CharPtr        str_src = NULL;
18931   CharPtr        str_dst = NULL;
18932   ValNodePtr     sfp_vnp;
18933   SeqFeatPtr     sfp;
18934   Boolean        able_to_apply = FALSE;
18935   Boolean        change_made = FALSE;
18936 
18937   if (IsCDSetMatPeptideQualChoice(sp->field_list))
18938   {
18939     for (sfp_vnp = cdsp->prot_list; sfp_vnp != NULL; sfp_vnp = sfp_vnp->next)
18940     {
18941       sfp = sfp_vnp->data.ptrvalue;
18942       able_to_apply = FALSE;
18943       if (fsp == NULL || !DoesConstraintDisqualifyFeature(sfp, fsp->cgp)) {
18944         str_src = GetCDSGeneProtField (sfp_vnp->data.ptrvalue, sp->field_list, NULL);
18945         if (str_src != NULL)
18946         {
18947           if (IsCDSetMatPeptideQualChoice (sp->field_list_to))
18948           {
18949             CDSGeneProtApplyToOneFeature (str_src, sfp, sp->field_list_to, fsp, etp);
18950             change_made = TRUE;
18951           }
18952           else
18953           {
18954             if (build_missing)
18955             {
18956               BuildNewCDSGeneProtFeature (cdsp, sp->field_list_to, sp->field_list);
18957             }
18958             able_to_apply = CDSGeneProtApplyToAllThatMatchFilter (str_src, cdsp, sp->field_list_to, fsp, etp);
18959             if (able_to_apply)
18960             {
18961               change_made = TRUE;
18962             }
18963           }
18964           if (!sp->leave_on_original && able_to_apply)
18965           {
18966             sp->field_list->choice = 1;
18967             RemoveCDSGeneProtField (sfp, sp->field_list, fsp);
18968             change_made = TRUE;
18969           }
18970         }
18971       }
18972     }
18973   }
18974   else
18975   {
18976     str_src = GetCDSetField (cdsp, sp->field_list);
18977     if (str_src != NULL)
18978     {
18979       if (build_missing)
18980       {
18981         BuildNewCDSGeneProtFeature (cdsp, sp->field_list_to, sp->field_list);
18982       }
18983       able_to_apply = CDSGeneProtApplyToAllThatMatchFilter (str_src, cdsp, sp->field_list_to, fsp, etp);
18984       if (!sp->leave_on_original && able_to_apply)
18985       {
18986         sp->field_list->choice = 1;
18987         RemoveCDSetField (cdsp, sp->field_list, fsp);
18988       }
18989       if (able_to_apply)
18990       {
18991         change_made = TRUE;
18992       }
18993     }
18994   }
18995   if (sp->also_mrna && change_made)
18996   {
18997     CopyProteinNameTomRNAName (cdsp);
18998   }
18999 
19000 }
19001 
CDSGeneProtSwap(CDSetPtr cdsp,CDSGeneProtAECRPtr sp,FilterSetPtr fsp,ExistingTextPtr etp,Boolean build_missing)19002 static void CDSGeneProtSwap
19003 (CDSetPtr        cdsp,
19004  CDSGeneProtAECRPtr   sp,
19005  FilterSetPtr    fsp,
19006  ExistingTextPtr etp,
19007  Boolean         build_missing)
19008 {
19009   CharPtr        str_src = NULL;
19010   CharPtr        str_dst = NULL;
19011   ValNodePtr     sfp_vnp_src, sfp_vnp_dst, vnp_swap;
19012   SeqFeatPtr     sfp_src, sfp_dst;
19013   ApplyValueData avd;
19014   Uint2          choice_to, choice_from;
19015   Boolean        change_made = FALSE;
19016 
19017   avd.where_to_replace = EditApplyFindLocation_anywhere;
19018 
19019   choice_from = FeatDefTypeFromFieldList (sp->field_list);
19020   choice_to = FeatDefTypeFromFieldList (sp->field_list_to);
19021 
19022   if (choice_from == FEATDEF_mat_peptide_aa || choice_to == FEATDEF_mat_peptide_aa)
19023   {
19024     /* make sure mat_peptide qual if in field_list */
19025     if (!IsCDSetMatPeptideQualChoice(sp->field_list))
19026     {
19027       vnp_swap = sp->field_list;
19028       sp->field_list = sp->field_list_to;
19029       sp->field_list_to = vnp_swap;
19030     }
19031     for (sfp_vnp_src = cdsp->prot_list; sfp_vnp_src != NULL; sfp_vnp_src = sfp_vnp_src->next)
19032     {
19033       sfp_src = sfp_vnp_src->data.ptrvalue;
19034       if (fsp == NULL || !DoesConstraintDisqualifyFeature(sfp_src, fsp->cgp))
19035       {
19036         str_src = GetCDSGeneProtField (sfp_src, sp->field_list, NULL);
19037         if (IsCDSetMatPeptideQualChoice(sp->field_list_to))
19038         {
19039           for (sfp_vnp_dst = cdsp->prot_list; sfp_vnp_dst != NULL; sfp_vnp_dst = sfp_vnp_dst->next)
19040           {
19041             sfp_dst = sfp_vnp_dst->data.ptrvalue;
19042             if (fsp == NULL || !DoesConstraintDisqualifyFeature(sfp_dst, fsp->cgp))
19043             {
19044               str_dst = GetCDSGeneProtField (sfp_dst, sp->field_list_to, NULL);
19045               if (!StringHasNoText (str_src) || !StringHasNoText (str_dst))
19046               {
19047                 if (build_missing)
19048                 {
19049                   BuildNewCDSGeneProtFeature (cdsp, sp->field_list, sp->field_list_to);
19050                   BuildNewCDSGeneProtFeature (cdsp, sp->field_list_to, sp->field_list);
19051                 }
19052                 if (!FeatureTypeMissingFromCDSet(cdsp, choice_from)
19053                     && !FeatureTypeMissingFromCDSet(cdsp, choice_to))
19054                 {
19055                   avd.etp = NULL;
19056                   avd.text_to_replace = NULL;
19057                   avd.new_text = StringSave (str_src);
19058                   avd.field_list = NULL;
19059                   SetCDSGeneProtField (sfp_dst, sp->field_list_to, &avd, fsp);
19060                   avd.new_text = StringSave (str_dst);
19061                   SetCDSGeneProtField (sfp_src, sp->field_list, &avd, fsp);
19062                   change_made = TRUE;
19063                 }
19064               }
19065               str_dst = MemFree (str_dst);
19066             }
19067           }
19068         }
19069         else
19070         {
19071           str_dst = GetCDSetField (cdsp, sp->field_list_to);
19072           if (!StringHasNoText (str_src) || !StringHasNoText (str_dst))
19073           {
19074             if (build_missing)
19075             {
19076               BuildNewCDSGeneProtFeature (cdsp, sp->field_list, sp->field_list_to);
19077               BuildNewCDSGeneProtFeature (cdsp, sp->field_list_to, sp->field_list);
19078             }
19079             if (!FeatureTypeMissingFromCDSet(cdsp, choice_from)
19080                 && !FeatureTypeMissingFromCDSet(cdsp, choice_to))
19081             {
19082               avd.etp = NULL;
19083               avd.text_to_replace = NULL;
19084               avd.new_text = StringSave (str_src);
19085               avd.field_list = NULL;
19086               SetCDSetField (cdsp, sp->field_list_to, &avd, fsp);
19087               avd.new_text = StringSave (str_dst);
19088               SetCDSGeneProtField (sfp_src, sp->field_list, &avd, fsp);
19089               change_made = TRUE;
19090             }
19091           }
19092           str_dst = MemFree (str_dst);
19093         }
19094         str_src = MemFree (str_src);
19095       }
19096     }
19097   }
19098   else
19099   {
19100     str_src = GetCDSetField (cdsp, sp->field_list);
19101     str_dst = GetCDSetField (cdsp, sp->field_list_to);
19102     if (!StringHasNoText (str_src) || !StringHasNoText (str_dst))
19103     {
19104       if (build_missing)
19105       {
19106         BuildNewCDSGeneProtFeature (cdsp, sp->field_list, sp->field_list_to);
19107         BuildNewCDSGeneProtFeature (cdsp, sp->field_list_to, sp->field_list);
19108       }
19109       if (!FeatureTypeMissingFromCDSet(cdsp, choice_from)
19110           && !FeatureTypeMissingFromCDSet(cdsp, choice_to))
19111       {
19112         avd.etp = NULL;
19113         avd.text_to_replace = NULL;
19114         avd.new_text = str_src;
19115         avd.field_list = NULL;
19116         SetCDSetField (cdsp, sp->field_list_to, &avd, fsp);
19117         avd.new_text = str_dst;
19118         SetCDSetField (cdsp, sp->field_list, &avd, fsp);
19119         change_made = TRUE;
19120       }
19121     }
19122   }
19123   if (change_made && sp->also_mrna)
19124   {
19125     CopyProteinNameTomRNAName (cdsp);
19126   }
19127 }
19128 
19129 
CDSGeneProtParse(CDSetPtr cdsp,CDSGeneProtAECRPtr sp,FilterSetPtr fsp,ExistingTextPtr etp,Boolean build_missing)19130 static void CDSGeneProtParse
19131 (CDSetPtr        cdsp,
19132  CDSGeneProtAECRPtr   sp,
19133  FilterSetPtr    fsp,
19134  ExistingTextPtr etp,
19135  Boolean         build_missing)
19136 {
19137   CharPtr        str_src = NULL;
19138   CharPtr        str_dst = NULL;
19139   ValNodePtr     sfp_vnp;
19140   SeqFeatPtr     sfp;
19141   ApplyValueData avd;
19142   Boolean        able_to_apply;
19143   Boolean        change_made = FALSE;
19144 
19145   avd.where_to_replace = EditApplyFindLocation_anywhere;
19146 
19147   if (IsCDSetMatPeptideQualChoice(sp->field_list))
19148   {
19149     for (sfp_vnp = cdsp->prot_list; sfp_vnp != NULL; sfp_vnp = sfp_vnp->next)
19150     {
19151       sfp = sfp_vnp->data.ptrvalue;
19152       if (fsp == NULL || !DoesConstraintDisqualifyFeature(sfp, fsp->cgp))
19153       {
19154         str_src = GetCDSGeneProtField (sfp, sp->field_list, NULL);
19155         str_dst = str_src;
19156         str_src = ReplaceStringForParse(str_src, sp->text_portion);
19157         if (!sp->remove_parsed) {
19158           str_dst = MemFree (str_dst);
19159         }
19160 
19161         if (str_src != NULL) {
19162           if (build_missing)
19163           {
19164             BuildNewCDSGeneProtFeature (cdsp, sp->field_list_to, sp->field_list);
19165           }
19166           able_to_apply = FALSE;
19167           if (IsCDSetMatPeptideQualChoice (sp->field_list_to))
19168           {
19169             able_to_apply = CDSGeneProtApplyToOneFeature (str_src, sfp, sp->field_list_to, fsp, etp);
19170           }
19171           else
19172           {
19173             able_to_apply = CDSGeneProtApplyToAllThatMatchFilter (str_src, cdsp, sp->field_list_to, fsp, etp);
19174           }
19175           if (sp->remove_parsed && able_to_apply) {
19176             CDSGeneProtApplyToOneFeature (str_dst, sfp, sp->field_list, fsp, NULL);
19177           }
19178           if (able_to_apply)
19179           {
19180             change_made = TRUE;
19181           }
19182           str_src = MemFree (str_src);
19183         }
19184         str_dst = MemFree (str_dst);
19185       }
19186     }
19187   }
19188   else
19189   {
19190     str_src = GetCDSetField (cdsp, sp->field_list);
19191     str_dst = str_src;
19192     str_src = ReplaceStringForParse(str_src, sp->text_portion);
19193     if (!sp->remove_parsed) {
19194       str_dst = MemFree (str_dst);
19195     }
19196     if (str_src != NULL) {
19197       if (build_missing)
19198       {
19199         BuildNewCDSGeneProtFeature (cdsp, sp->field_list_to, sp->field_list);
19200       }
19201       able_to_apply = CDSGeneProtApplyToAllThatMatchFilter (str_src, cdsp, sp->field_list_to, fsp, etp);
19202       if (sp->remove_parsed && able_to_apply) {
19203         CDSGeneProtApplyToAllThatMatchFilter (str_dst, cdsp, sp->field_list, fsp, NULL);
19204       }
19205       if (able_to_apply)
19206       {
19207         change_made = TRUE;
19208       }
19209       str_src = MemFree (str_src);
19210     }
19211     str_dst = MemFree (str_dst);
19212   }
19213 
19214   if (sp->also_mrna && change_made)
19215   {
19216     CopyProteinNameTomRNAName (cdsp);
19217   }
19218 }
19219 
CDSGeneProtEdit(CDSetPtr cdsp,CDSGeneProtAECRPtr sp,FilterSetPtr fsp,ExistingTextPtr etp)19220 static void CDSGeneProtEdit
19221 (CDSetPtr        cdsp,
19222  CDSGeneProtAECRPtr   sp,
19223  FilterSetPtr    fsp,
19224  ExistingTextPtr etp)
19225 {
19226   ApplyValueData avd;
19227 
19228   avd.where_to_replace = EditApplyFindLocation_anywhere;
19229 
19230   avd.field_list = sp->field_list;
19231   avd.etp = NULL;
19232   AddEditApplyDataToApplyValue (AECR_EDIT, sp->edit_apply, &avd);
19233   SetCDSetField (cdsp, sp->field_list, &avd, fsp);
19234   avd.text_to_replace = MemFree (avd.text_to_replace);
19235   avd.new_text = MemFree (avd.new_text);
19236   if (sp->also_mrna)
19237   {
19238     CopyProteinNameTomRNAName (cdsp);
19239   }
19240 }
19241 
CollectCDSetList(Uint2 entityID,FilterSetPtr fsp)19242 static ValNodePtr CollectCDSetList (Uint2 entityID, FilterSetPtr fsp)
19243 {
19244   ValNodePtr cdset_list;
19245 
19246   /* need to create a list of sets */
19247   cdset_list = BuildCDSet2List (entityID, fsp == NULL || fsp->cgp == NULL ? NULL : fsp->cgp);
19248 
19249   return cdset_list;
19250 }
19251 
19252 
MarkAlreadyEditedGenes(CDSetPtr cdsp,ValNodePtr cdset_list)19253 static void MarkAlreadyEditedGenes (CDSetPtr cdsp, ValNodePtr cdset_list)
19254 {
19255   ValNodePtr gene_vnp, list_vnp, genecheck_vnp;
19256   CDSetPtr   check_cdsp;
19257 
19258   if (cdsp == NULL || cdset_list == NULL || cdsp->gene_list == NULL) return;
19259 
19260   for (gene_vnp = cdsp->gene_list; gene_vnp != NULL; gene_vnp = gene_vnp->next)
19261   {
19262     if (gene_vnp->choice > 0) continue;
19263     for (list_vnp = cdset_list; list_vnp != NULL; list_vnp = list_vnp->next)
19264     {
19265       check_cdsp = (CDSetPtr) list_vnp->data.ptrvalue;
19266       if (check_cdsp != NULL)
19267       {
19268         for (genecheck_vnp = check_cdsp->gene_list; genecheck_vnp != NULL; genecheck_vnp = genecheck_vnp->next)
19269         {
19270           if (genecheck_vnp->data.ptrvalue == gene_vnp->data.ptrvalue)
19271           {
19272             genecheck_vnp->choice = 1;
19273           }
19274         }
19275       }
19276     }
19277   }
19278 }
19279 
19280 
CDSGeneProtAECRAction(Pointer userdata)19281 static Boolean CDSGeneProtAECRAction (Pointer userdata)
19282 {
19283   ApplyEditConvertRemovePtr ap;
19284   CDSGeneProtAECRPtr        sp;
19285   Int4                      action_choice;
19286   SeqEntryPtr               sep;
19287   FilterSetPtr              fsp;
19288   GetSamplePtr              gsp = NULL;
19289   Boolean                   rval = TRUE;
19290   ValNodePtr                cdset_list, cdset_vnp;
19291   ExistingTextPtr           etp = NULL;
19292   Int4                      num_missing;
19293   Boolean                   build_missing = FALSE;
19294   MsgAnswer                 ans;
19295 
19296   ap = (ApplyEditConvertRemovePtr) userdata;
19297   if (ap == NULL)
19298   {
19299     return FALSE;
19300   }
19301 
19302   WatchCursor ();
19303   Update ();
19304 
19305   if (ap->crippled)
19306   {
19307     action_choice = ap->crippled_action;
19308   }
19309   else
19310   {
19311     action_choice = GetValue (ap->action_popup);
19312   }
19313   if (action_choice < 1 || action_choice > NUM_AECR)
19314   {
19315     return FALSE;
19316   }
19317   sp = (CDSGeneProtAECRPtr) DialogToPointer (ap->aecr_pages[action_choice - 1]);
19318 
19319   sep = GetTopSeqEntryForEntityID (ap->input_entityID);
19320   if (sp->field_list == NULL
19321       || ((action_choice == AECR_CONVERT || action_choice == AECR_SWAP)
19322            && sp->field_list == NULL))
19323   {
19324     sp = CDSGeneProtAECRFree (sp);
19325     ArrowCursor ();
19326     Update ();
19327     return FALSE;
19328   }
19329 
19330   fsp = (FilterSetPtr) DialogToPointer (ap->constraints);
19331 
19332   /* need to create a list of sets */
19333   cdset_list = CollectCDSetList (ap->input_entityID, fsp);
19334 
19335   /* find existing text and how to handle it */
19336   if (action_choice == AECR_CONVERT || action_choice == AECR_APPLY || action_choice == AECR_PARSE)
19337   {
19338     gsp = GetCDSGeneProtAECRSample (cdset_list, sp->field_list, sp->field_list_to, fsp);
19339     etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
19340     gsp = GetSampleFree (gsp);
19341     if (etp != NULL && etp->existing_text_choice == eExistingTextChoiceCancel)
19342     {
19343       rval = FALSE;
19344     }
19345   }
19346 
19347   num_missing = CountMissingFeatures (cdset_list, sp->field_list, sp->field_list_to, fsp);
19348   if (action_choice == AECR_SWAP)
19349   {
19350     num_missing += CountMissingFeatures (cdset_list, sp->field_list_to, sp->field_list, fsp);
19351   }
19352   if (num_missing > 0)
19353   {
19354     ans = Message (MSG_YNC, "There are %d fields where the feature to which the field should be applied does not exist.  Do you want to create these features?", num_missing);
19355     if (ans == ANS_CANCEL)
19356     {
19357       rval = FALSE;
19358     } else if (ans == ANS_YES) {
19359       build_missing = TRUE;
19360     }
19361   }
19362 
19363   if (rval)
19364   {
19365     /* if we are applying gene locus, we need to make sure every sequence has a gene
19366      * and we need to recollect the cdset_list
19367      */
19368     if ((action_choice == AECR_APPLY || action_choice == AECR_PARSE)
19369         && sp->field_list != NULL
19370         && sp->field_list->data.intvalue == 1 + GENEFIELD_LOCUS)
19371     {
19372       BuildNewGenes (sep, &cdset_list, LoneGeneOkWithFilter(fsp));
19373     }
19374 
19375     for (cdset_vnp = cdset_list; cdset_vnp != NULL; cdset_vnp = cdset_vnp->next)
19376     {
19377       if (action_choice == AECR_CONVERT)
19378       {
19379         CDSGeneProtConvert (cdset_vnp->data.ptrvalue, sp, fsp, etp, build_missing);
19380       }
19381       else if (action_choice == AECR_SWAP)
19382       {
19383         CDSGeneProtSwap (cdset_vnp->data.ptrvalue, sp, fsp, etp, build_missing);
19384       }
19385       else if (action_choice == AECR_PARSE)
19386       {
19387         CDSGeneProtParse (cdset_vnp->data.ptrvalue, sp, fsp, etp, build_missing);
19388       }
19389       else if (action_choice == AECR_APPLY)
19390       {
19391         CDSGeneProtApplyToAllThatMatchFilter (sp->edit_apply->apply_txt, cdset_vnp->data.ptrvalue, sp->field_list, fsp, etp);
19392       }
19393       else if (action_choice == AECR_REMOVE)
19394       {
19395         sp->field_list->choice = 1;
19396         RemoveCDSetField (cdset_vnp->data.ptrvalue, sp->field_list, fsp);
19397         if (sp->also_mrna)
19398         {
19399           CopyProteinNameTomRNAName (cdset_vnp->data.ptrvalue);
19400         }
19401       }
19402       else if (action_choice == AECR_EDIT)
19403       {
19404         CDSGeneProtEdit (cdset_vnp->data.ptrvalue, sp, fsp, etp);
19405       }
19406       if (((action_choice == AECR_APPLY || action_choice == AECR_EDIT) && IsCDSetGeneQualChoice (sp->field_list))
19407           || ((action_choice == AECR_PARSE || action_choice == AECR_CONVERT) && IsCDSetGeneQualChoice (sp->field_list_to))
19408           || (action_choice == AECR_SWAP && (IsCDSetGeneQualChoice (sp->field_list) || IsCDSetGeneQualChoice (sp->field_list_to))))
19409       {
19410         MarkAlreadyEditedGenes (cdset_vnp->data.ptrvalue, cdset_vnp->next);
19411       }
19412     }
19413   }
19414   FilterSetFree (fsp);
19415   sp = CDSGeneProtAECRFree (sp);
19416   FreeCDSetList (cdset_list);
19417 
19418   if (rval)
19419   {
19420     ObjMgrSetDirtyFlag (ap->input_entityID, TRUE);
19421     ObjMgrSendMsg (OM_MSG_UPDATE, ap->input_entityID, 0, 0);
19422   }
19423   ArrowCursor ();
19424   Update ();
19425 
19426   return rval;
19427 
19428 }
19429 
19430 static void
CDSGeneProtApplyEditConvertRemove(IteM i,Int4 first_action_choice,Boolean crippled)19431 CDSGeneProtApplyEditConvertRemove
19432 (IteM    i,
19433  Int4    first_action_choice,
19434  Boolean crippled)
19435 {
19436   ApplyEditConvertRemoveCombo (i, first_action_choice, crippled,
19437                                "CDS-Gene-Prot-mRNA",
19438                                CDSGeneProtAECRDialog,
19439                                TRUE, GetCDSGeneProtSample,
19440                                FALSE, FALSE, FALSE, TRUE, FALSE, NULL,
19441                                CDSGeneProtAECRAction, NULL, NULL,
19442                                CheckFeaturesForPresample);
19443 }
19444 
ApplyCDSGeneProt(IteM i)19445 extern void ApplyCDSGeneProt (IteM i)
19446 {
19447   CDSGeneProtApplyEditConvertRemove (i, AECR_APPLY, FALSE);
19448 }
19449 
PublicApplyCDSGeneProt(IteM i)19450 extern void PublicApplyCDSGeneProt (IteM i)
19451 {
19452   CDSGeneProtApplyEditConvertRemove (i, AECR_APPLY, TRUE);
19453 }
19454 
EditCDSGeneProt(IteM i)19455 extern void EditCDSGeneProt (IteM i)
19456 {
19457   CDSGeneProtApplyEditConvertRemove (i, AECR_EDIT, FALSE);
19458 }
19459 
PublicEditCDSGeneProt(IteM i)19460 extern void PublicEditCDSGeneProt (IteM i)
19461 {
19462   CDSGeneProtApplyEditConvertRemove (i, AECR_EDIT, TRUE);
19463 }
19464 
ConvertCDSGeneProt(IteM i)19465 extern void ConvertCDSGeneProt (IteM i)
19466 {
19467   CDSGeneProtApplyEditConvertRemove (i, AECR_CONVERT, FALSE);
19468 }
19469 
SwapCDSGeneProt(IteM i)19470 extern void SwapCDSGeneProt (IteM i)
19471 {
19472   CDSGeneProtApplyEditConvertRemove (i, AECR_SWAP, FALSE);
19473 }
19474 
RemoveCDSGeneProt(IteM i)19475 extern void RemoveCDSGeneProt (IteM i)
19476 {
19477   CDSGeneProtApplyEditConvertRemove (i, AECR_REMOVE, FALSE);
19478 }
19479 
19480 #define QUALKIND_SOURCE_QUAL 1
19481 #define QUALKIND_STRINGS     2
19482 #define QUALKIND_LOCATION    3
19483 #define QUALKIND_ORIGIN      4
19484 
19485 typedef struct sourcequalaecrdata
19486 {
19487   Int4          qual_kind;
19488   SimpleAECRPtr source_qual;
19489   SimpleAECRPtr location;
19490   SimpleAECRPtr origin;
19491   SimpleAECRPtr strings;
19492 
19493   TaxnameOptionsPtr taxname_options;
19494 } SourceQualAECRData, PNTR SourceQualAECRPtr;
19495 
SourceQualAECRFree(SourceQualAECRPtr sp)19496 static SourceQualAECRPtr SourceQualAECRFree (SourceQualAECRPtr sp)
19497 {
19498   if (sp != NULL)
19499   {
19500     sp->source_qual = SimpleAECRFree (sp->source_qual);
19501     sp->taxname_options = MemFree (sp->taxname_options);
19502     sp = MemFree (sp);
19503   }
19504   return sp;
19505 }
19506 
19507 typedef struct sourcequalaecrdlg
19508 {
19509   DIALOG_MESSAGE_BLOCK
19510   GrouP  qual_kind;
19511 
19512   DialoG source_qual;
19513   DialoG location;
19514   DialoG origin;
19515   DialoG strings;
19516 
19517   DialoG taxname_options;
19518 
19519   Int4   action_choice;
19520   Nlm_ChangeNotifyProc     change_notify;
19521   Pointer                  change_userdata;
19522 
19523 } SourceQualAECRDlgData, PNTR SourceQualAECRDlgPtr;
19524 
19525 
AreTaxNameOptionsRelevant(Int4 action_choice,SimpleAECRPtr sp)19526 static Boolean AreTaxNameOptionsRelevant (Int4 action_choice, SimpleAECRPtr sp)
19527 {
19528   Boolean relevant = FALSE;
19529   if (sp == NULL) return FALSE;
19530 
19531   switch (action_choice)
19532   {
19533     case AECR_APPLY:
19534     case AECR_EDIT:
19535     case AECR_REMOVE:
19536       if (sp->field_list != NULL && sp->field_list->choice == 1)
19537       {
19538         relevant = TRUE;
19539       }
19540       break;
19541     case AECR_SWAP:
19542       if ((sp->field_list != NULL && sp->field_list->choice == 1)
19543           || (sp->field_list_to != NULL && sp->field_list_to->choice == 1))
19544       {
19545         relevant = TRUE;
19546       }
19547       break;
19548     case AECR_CONVERT:
19549       if ((sp->field_list != NULL && sp->field_list->choice == 1 && !sp->leave_on_original)
19550           || (sp->field_list_to != NULL && sp->field_list_to->choice == 1))
19551       {
19552         relevant = TRUE;
19553       }
19554       break;
19555     case AECR_PARSE:
19556       if ((sp->field_list != NULL && sp->field_list->choice == 1 && sp->remove_parsed)
19557           || (sp->field_list_to != NULL && sp->field_list_to->choice == 1))
19558       {
19559         relevant = TRUE;
19560       }
19561       break;
19562     default:
19563       relevant = FALSE;
19564       break;
19565   }
19566   return relevant;
19567 }
19568 
ChangeQualKind(GrouP g)19569 static void ChangeQualKind (GrouP g)
19570 {
19571   SourceQualAECRDlgPtr dlg;
19572   Int4                 qual_kind;
19573   SimpleAECRPtr        sp;
19574 
19575   dlg = (SourceQualAECRDlgPtr) GetObjectExtra (g);
19576   if (dlg == NULL)
19577   {
19578     return;
19579   }
19580 
19581   Hide (dlg->source_qual);
19582   Hide (dlg->location);
19583   Hide (dlg->origin);
19584   Hide (dlg->strings);
19585   Hide (dlg->taxname_options);
19586   qual_kind = GetValue (dlg->qual_kind);
19587   switch (qual_kind)
19588   {
19589     case QUALKIND_SOURCE_QUAL :
19590       Show (dlg->source_qual);
19591       break;
19592     case QUALKIND_LOCATION :
19593       Show (dlg->location);
19594       break;
19595     case QUALKIND_ORIGIN :
19596       Show (dlg->origin);
19597       break;
19598     case QUALKIND_STRINGS :
19599       Show (dlg->strings);
19600       Show (dlg->taxname_options);
19601       sp = DialogToPointer (dlg->strings);
19602       if (AreTaxNameOptionsRelevant (dlg->action_choice, sp))
19603       {
19604         Enable (dlg->taxname_options);
19605       }
19606       else
19607       {
19608         Disable (dlg->taxname_options);
19609       }
19610       sp = SimpleAECRFree (sp);
19611       break;
19612   }
19613   if (dlg->change_notify != NULL)
19614   {
19615     (dlg->change_notify)(dlg->change_userdata);
19616   }
19617 }
19618 
ResetSourceQualAECRDlg(SourceQualAECRDlgPtr dlg)19619 static void ResetSourceQualAECRDlg (SourceQualAECRDlgPtr dlg)
19620 {
19621   if (dlg == NULL)
19622   {
19623     return;
19624   }
19625 
19626   PointerToDialog (dlg->source_qual, NULL);
19627   PointerToDialog (dlg->location, NULL);
19628   PointerToDialog (dlg->origin, NULL);
19629   PointerToDialog (dlg->strings, NULL);
19630   ChangeQualKind (dlg->qual_kind);
19631   PointerToDialog (dlg->taxname_options, NULL);
19632 }
19633 
ClearTextSourceQualAECRDlg(SourceQualAECRDlgPtr dlg)19634 static void ClearTextSourceQualAECRDlg (SourceQualAECRDlgPtr dlg)
19635 {
19636   if (dlg == NULL)
19637   {
19638     return;
19639   }
19640   SendMessageToDialog (dlg->source_qual, AECR_VIB_MSG_CLEAR_TEXT);
19641   SendMessageToDialog (dlg->location, AECR_VIB_MSG_CLEAR_TEXT);
19642   SendMessageToDialog (dlg->origin, AECR_VIB_MSG_CLEAR_TEXT);
19643   SendMessageToDialog (dlg->strings, AECR_VIB_MSG_CLEAR_TEXT);
19644 }
19645 
SourceQualAECRToDialog(DialoG d,Pointer userdata)19646 static void SourceQualAECRToDialog (DialoG d, Pointer userdata)
19647 {
19648   SourceQualAECRDlgPtr dlg;
19649   SourceQualAECRPtr    data;
19650 
19651   dlg = (SourceQualAECRDlgPtr) GetObjectExtra (d);
19652   if (dlg == NULL)
19653   {
19654     return;
19655   }
19656 
19657   ResetSourceQualAECRDlg (dlg);
19658 
19659   data = (SourceQualAECRPtr) userdata;
19660   if (data == NULL)
19661   {
19662     return;
19663   }
19664   PointerToDialog (dlg->source_qual, data->source_qual);
19665   PointerToDialog (dlg->location, data->location);
19666   PointerToDialog (dlg->origin, data->origin);
19667   PointerToDialog (dlg->strings, data->strings);
19668 
19669   if (data->qual_kind < QUALKIND_SOURCE_QUAL)
19670   {
19671     SetValue (dlg->qual_kind, QUALKIND_SOURCE_QUAL);
19672   }
19673   else if (data->qual_kind > QUALKIND_STRINGS
19674            && (dlg->action_choice == AECR_EDIT || dlg->action_choice == AECR_SWAP))
19675   {
19676     SetValue (dlg->qual_kind, QUALKIND_STRINGS);
19677     PointerToDialog (dlg->taxname_options, data->taxname_options);
19678   }
19679   else if (data->qual_kind > QUALKIND_ORIGIN)
19680   {
19681     SetValue (dlg->qual_kind, QUALKIND_ORIGIN);
19682   }
19683   else
19684   {
19685     SetValue (dlg->qual_kind, data->qual_kind);
19686   }
19687   ChangeQualKind (dlg->qual_kind);
19688 }
19689 
DialogToSourceQualAECR(DialoG d)19690 static Pointer DialogToSourceQualAECR (DialoG d)
19691 {
19692   SourceQualAECRDlgPtr dlg;
19693   SourceQualAECRPtr    data;
19694 
19695   dlg = (SourceQualAECRDlgPtr) GetObjectExtra (d);
19696   if (dlg == NULL)
19697   {
19698     return NULL;
19699   }
19700 
19701   data = (SourceQualAECRPtr) MemNew (sizeof (SourceQualAECRData));
19702   if (data != NULL)
19703   {
19704     data->taxname_options = NULL;
19705     data->qual_kind = GetValue (dlg->qual_kind);
19706     switch (data->qual_kind)
19707     {
19708       case QUALKIND_SOURCE_QUAL :
19709         data->source_qual = DialogToPointer (dlg->source_qual);
19710         break;
19711       case QUALKIND_LOCATION :
19712         data->location = DialogToPointer (dlg->location);
19713         break;
19714       case QUALKIND_ORIGIN :
19715         data->origin = DialogToPointer (dlg->origin);
19716         break;
19717       case QUALKIND_STRINGS :
19718         data->strings = DialogToPointer (dlg->strings);
19719         if (AreTaxNameOptionsRelevant (dlg->action_choice, data->strings))
19720         {
19721           data->taxname_options = DialogToPointer (dlg->taxname_options);
19722         }
19723         break;
19724     }
19725 
19726   }
19727   return data;
19728 }
19729 
SourceQualAECRMessage(DialoG d,Int2 mssg)19730 static void SourceQualAECRMessage (DialoG d, Int2 mssg)
19731 
19732 {
19733   SourceQualAECRDlgPtr  dlg;
19734 
19735   dlg = (SourceQualAECRDlgPtr) GetObjectExtra (d);
19736   if (dlg != NULL) {
19737     switch (mssg)
19738     {
19739       case VIB_MSG_INIT :
19740         /* reset list */
19741         ResetSourceQualAECRDlg (dlg);
19742         break;
19743       case VIB_MSG_ENTER :
19744         Select (dlg->qual_kind);
19745         break;
19746       case AECR_VIB_MSG_SET_DEFAULT :
19747         SetValue (dlg->qual_kind, QUALKIND_SOURCE_QUAL);
19748         SendMessageToDialog (dlg->source_qual, AECR_VIB_MSG_SET_DEFAULT);
19749         SendMessageToDialog (dlg->location, AECR_VIB_MSG_SET_DEFAULT);
19750         SendMessageToDialog (dlg->origin, AECR_VIB_MSG_SET_DEFAULT);
19751         SendMessageToDialog (dlg->strings, AECR_VIB_MSG_SET_DEFAULT);
19752         PointerToDialog (dlg->taxname_options, NULL);
19753         ChangeQualKind (dlg->qual_kind);
19754         break;
19755       case AECR_VIB_MSG_CLEAR_TEXT :
19756         ClearTextSourceQualAECRDlg (dlg);
19757         break;
19758       default :
19759         break;
19760     }
19761   }
19762 }
19763 
TestSourceQualAECR(DialoG d)19764 static ValNodePtr TestSourceQualAECR (DialoG d)
19765 {
19766   SourceQualAECRDlgPtr dlg;
19767   ValNodePtr           total_err_list = NULL;
19768   Int4                 qual_kind;
19769 
19770   dlg = (SourceQualAECRDlgPtr) GetObjectExtra (d);
19771   if (dlg == NULL)
19772   {
19773     return FALSE;
19774   }
19775 
19776   qual_kind = GetValue (dlg->qual_kind);
19777   switch (qual_kind)
19778   {
19779     case QUALKIND_SOURCE_QUAL :
19780       total_err_list = TestDialog (dlg->source_qual);
19781       break;
19782     case QUALKIND_LOCATION :
19783       total_err_list = TestDialog (dlg->location);
19784       break;
19785     case QUALKIND_ORIGIN :
19786       total_err_list = TestDialog (dlg->origin);
19787       break;
19788     case QUALKIND_STRINGS :
19789       total_err_list = TestDialog (dlg->strings);
19790       break;
19791     default:
19792       ValNodeAddPointer (&total_err_list, 0, "qual kind");
19793       break;
19794   }
19795   return total_err_list;
19796 }
19797 
19798 typedef struct applysourcequaldlg
19799 {
19800   DIALOG_MESSAGE_BLOCK
19801   DialoG               field_list;
19802   DialoG               edit_apply;
19803   PopuP                true_false;
19804   Nlm_ChangeNotifyProc change_notify;
19805   Pointer              change_userdata;
19806   Uint2                entityID;
19807 
19808 } ApplySourceQualDlgData, PNTR ApplySourceQualDlgPtr;
19809 
SourceQualChangeNotify(Pointer userdata)19810 static void SourceQualChangeNotify (Pointer userdata)
19811 {
19812   ApplySourceQualDlgPtr dlg;
19813   ValNodePtr            vnp;
19814   SourceQualDescPtr     sqdp;
19815 
19816   dlg = (ApplySourceQualDlgPtr) userdata;
19817   if (dlg == NULL)
19818   {
19819     return;
19820   }
19821 
19822   vnp = (ValNodePtr) DialogToPointer (dlg->field_list);
19823   if (vnp == NULL || vnp->data.ptrvalue == NULL)
19824   {
19825     Hide (dlg->edit_apply);
19826     Hide (dlg->true_false);
19827   }
19828   else
19829   {
19830     sqdp = (SourceQualDescPtr) vnp->data.ptrvalue;
19831     if (IsNonTextModifier (sqdp->name))
19832     {
19833       Hide (dlg->true_false);
19834       Hide (dlg->edit_apply);
19835     }
19836     else
19837     {
19838       Show (dlg->edit_apply);
19839       Hide (dlg->true_false);
19840     }
19841   }
19842   vnp = ValNodeFreeData (vnp);
19843 
19844   if (dlg->change_notify != NULL)
19845   {
19846     (dlg->change_notify) (dlg->change_userdata);
19847   }
19848 }
19849 
ClearTextApplySourceQualDialog(ApplySourceQualDlgPtr dlg)19850 static void ClearTextApplySourceQualDialog (ApplySourceQualDlgPtr dlg)
19851 {
19852   if (dlg != NULL)
19853   {
19854     PointerToDialog (dlg->edit_apply, NULL);
19855   }
19856 }
19857 
ResetApplySourceQualDialog(ApplySourceQualDlgPtr dlg)19858 static void ResetApplySourceQualDialog (ApplySourceQualDlgPtr dlg)
19859 {
19860   if (dlg == NULL)
19861   {
19862     return;
19863   }
19864   PointerToDialog (dlg->field_list, NULL);
19865   PointerToDialog (dlg->edit_apply, NULL);
19866   SetValue (dlg->true_false, 1);
19867   SourceQualChangeNotify (dlg);
19868 }
19869 
ApplySourceQualToDialog(DialoG d,Pointer data)19870 static void ApplySourceQualToDialog (DialoG d, Pointer data)
19871 {
19872   ApplySourceQualDlgPtr dlg;
19873   SimpleAECRPtr         sap;
19874   SourceQualDescPtr     sqdp;
19875 
19876   dlg = (ApplySourceQualDlgPtr) GetObjectExtra (d);
19877   if (dlg == NULL)
19878   {
19879     return;
19880   }
19881   ResetApplySourceQualDialog (dlg);
19882 
19883   sap = (SimpleAECRPtr) data;
19884   if (sap != NULL)
19885   {
19886     PointerToDialog (dlg->field_list, sap->field_list);
19887 
19888     if (sap->field_list != NULL && sap->field_list->data.ptrvalue != NULL)
19889     {
19890       sqdp = (SourceQualDescPtr) sap->field_list->data.ptrvalue;
19891       if (IsNonTextModifier (sqdp->name))
19892       {
19893         if (sap->edit_apply == NULL
19894             || StringHasNoText (sap->edit_apply->apply_txt))
19895         {
19896           SetValue (dlg->true_false, 2);
19897         }
19898         else
19899         {
19900           SetValue (dlg->true_false, 1);
19901         }
19902       }
19903       else
19904       {
19905         PointerToDialog (dlg->edit_apply, sap->edit_apply);
19906       }
19907     }
19908   }
19909   SourceQualChangeNotify (dlg);
19910 }
19911 
DialogToApplySourceQual(DialoG d)19912 static Pointer DialogToApplySourceQual (DialoG d)
19913 {
19914   ApplySourceQualDlgPtr dlg;
19915   SimpleAECRPtr         sap;
19916   SourceQualDescPtr     sqdp;
19917 
19918   dlg = (ApplySourceQualDlgPtr) GetObjectExtra (d);
19919   if (dlg == NULL)
19920   {
19921     return NULL;
19922   }
19923 
19924   sap = (SimpleAECRPtr) MemNew (sizeof (SimpleAECRData));
19925   if (sap == NULL)
19926   {
19927     return NULL;
19928   }
19929   sap->field_list = DialogToPointer (dlg->field_list);
19930   sap->edit_apply = DialogToPointer (dlg->edit_apply);
19931   if (sap->field_list != NULL && sap->field_list->data.ptrvalue != NULL)
19932   {
19933     sqdp = (SourceQualDescPtr) sap->field_list->data.ptrvalue;
19934     if (IsNonTextModifier (sqdp->name))
19935     {
19936       sap->edit_apply->apply_txt = MemFree (sap->edit_apply->apply_txt);
19937       if (GetValue (dlg->true_false) == 1)
19938       {
19939         sap->edit_apply->apply_txt = StringSave ("TRUE");
19940       }
19941     }
19942   }
19943 
19944   sap->free_field_vn_proc = ValNodeSimpleDataFree;
19945   sap->free_subtype_vn_proc = NULL;
19946   return sap;
19947 }
19948 
ApplySourceQualMessage(DialoG d,Int2 mssg)19949 static void ApplySourceQualMessage (DialoG d, Int2 mssg)
19950 
19951 {
19952   ApplySourceQualDlgPtr  dlg;
19953 
19954   dlg = (ApplySourceQualDlgPtr) GetObjectExtra (d);
19955   if (dlg != NULL) {
19956     switch (mssg)
19957     {
19958       case VIB_MSG_INIT :
19959         /* reset list */
19960         ResetApplySourceQualDialog (dlg);
19961         break;
19962       case VIB_MSG_ENTER :
19963         Select (dlg->field_list);
19964         break;
19965       case AECR_VIB_MSG_SET_DEFAULT :
19966         SendMessageToDialog (dlg->field_list, AECR_VIB_MSG_SET_DEFAULT);
19967         ClearTextApplySourceQualDialog (dlg);
19968         break;
19969       case AECR_VIB_MSG_CLEAR_TEXT :
19970         ClearTextApplySourceQualDialog (dlg);
19971         break;
19972       case AECR_VIB_MSG_AUTOPOPULATE:
19973         SourceQualChangeNotify (dlg);
19974         break;
19975       default :
19976         break;
19977     }
19978   }
19979 }
19980 
TestApplySourceQual(DialoG d)19981 static ValNodePtr TestApplySourceQual (DialoG d)
19982 {
19983   ApplySourceQualDlgPtr dlg;
19984   ValNodePtr            err_list = NULL;
19985   ValNodePtr            total_err_list = NULL;
19986   ValNodePtr            field_list;
19987   SourceQualDescPtr     sqdp;
19988 
19989   dlg = (ApplySourceQualDlgPtr) GetObjectExtra (d);
19990   if (dlg == NULL)
19991   {
19992     return NULL;
19993   }
19994 
19995   err_list = TestDialog (dlg->field_list);
19996   total_err_list = ValNodeAppend (total_err_list, err_list);
19997 
19998   field_list = DialogToPointer (dlg->field_list);
19999   if (field_list != NULL && field_list->data.ptrvalue != NULL)
20000   {
20001     sqdp = (SourceQualDescPtr) field_list->data.ptrvalue;
20002     if (IsNonTextModifier (sqdp->name))
20003     {
20004       /* any true or false value is valid */
20005     }
20006     else
20007     {
20008       err_list = TestDialog (dlg->edit_apply);
20009       total_err_list = ValNodeAppend (total_err_list, err_list);
20010     }
20011   }
20012   field_list = ValNodeFreeData (field_list);
20013 
20014   return total_err_list;
20015 }
20016 
ApplySourceQualDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Uint2 entityID)20017 static DialoG ApplySourceQualDialog
20018 (GrouP                    h,
20019  Nlm_ChangeNotifyProc     change_notify,
20020  Pointer                  change_userdata,
20021  Uint2                    entityID)
20022 {
20023   ApplySourceQualDlgPtr dlg;
20024   GrouP                 p, g1, g2;
20025 
20026   dlg = (ApplySourceQualDlgPtr) MemNew (sizeof (ApplySourceQualDlgData));
20027   if (dlg == NULL)
20028   {
20029     return NULL;
20030   }
20031 
20032   p = HiddenGroup (h, -1, 0, NULL);
20033   SetObjectExtra (p, dlg, StdCleanupExtraProc);
20034   SetGroupSpacing (p, 10, 10);
20035 
20036   dlg->dialog = (DialoG) p;
20037   dlg->todialog = ApplySourceQualToDialog;
20038   dlg->fromdialog = DialogToApplySourceQual;
20039   dlg->dialogmessage = ApplySourceQualMessage;
20040   dlg->testdialog = TestApplySourceQual;
20041   dlg->change_notify = change_notify;
20042   dlg->change_userdata = change_userdata;
20043   dlg->entityID = entityID;
20044 
20045   g1 = HiddenGroup (p, 1, 0, NULL);
20046   StaticPrompt (g1, "Qualifier", 0, dialogTextHeight, systemFont, 'l');
20047 
20048   dlg->field_list = SourceQualTypeSelectionDialog (g1, FALSE,
20049                                                 SourceQualChangeNotify,
20050                                                 dlg);
20051 
20052   g2 = HiddenGroup (p, 0, 0, NULL);
20053   dlg->edit_apply = EditApplyDialog (g2, eEditApplyChoice_Apply, "New Text", NULL,
20054                                      change_notify, change_userdata);
20055 
20056   dlg->true_false = PopupList (g2, TRUE, NULL);
20057   PopupItem (dlg->true_false, "TRUE");
20058   PopupItem (dlg->true_false, "FALSE");
20059   SetValue (dlg->true_false, 1);
20060 
20061   Hide (dlg->edit_apply);
20062   Hide (dlg->true_false);
20063 
20064   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->edit_apply, (HANDLE) dlg->true_false, NULL);
20065 
20066   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2, NULL);
20067 
20068   SourceQualChangeNotify (dlg);
20069 
20070   return (DialoG) p;
20071 }
20072 
ConvertSourceQualDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Uint2 entityID)20073 static DialoG ConvertSourceQualDialog
20074 (GrouP                    h,
20075  Nlm_ChangeNotifyProc     change_notify,
20076  Pointer                  change_userdata,
20077  Uint2                    entityID)
20078 {
20079   SimpleAECRDlgPtr dlg;
20080   GrouP            p, g1;
20081 
20082   dlg = (SimpleAECRDlgPtr) MemNew (sizeof (SimpleAECRDlgData));
20083   if (dlg == NULL)
20084   {
20085     return NULL;
20086   }
20087 
20088   p = HiddenGroup (h, -1, 0, NULL);
20089   SetObjectExtra (p, dlg, StdCleanupExtraProc);
20090   SetGroupSpacing (p, 10, 10);
20091 
20092   dlg->dialog = (DialoG) p;
20093   dlg->todialog = SimpleAECRToDialog;
20094   dlg->fromdialog = DialogToSimpleAECR;
20095   dlg->dialogmessage = SimpleAECRMessage;
20096   dlg->testdialog = TestSimpleAECR;
20097   dlg->action_choice = AECR_CONVERT;
20098   dlg->free_field_vn_proc = ValNodeSimpleDataFree;
20099   dlg->free_subtype_vn_proc = NULL;
20100   dlg->change_notify = change_notify;
20101   dlg->change_userdata = change_userdata;
20102   dlg->get_autopopulate_text = NULL;
20103   dlg->entityID = entityID;
20104 
20105   dlg->subtype_list = NULL;
20106 
20107   g1 = HiddenGroup (p, 2, 0, NULL);
20108   StaticPrompt (g1, "From", 0, dialogTextHeight, systemFont, 'l');
20109   StaticPrompt (g1, "To", 0, dialogTextHeight, systemFont, 'l');
20110 
20111   dlg->field_list = SourceQualTypeDiscSelectionDialog (g1, FALSE,
20112                                           change_notify,
20113                                           change_userdata);
20114   dlg->field_list_to = SourceQualTypeSelectionDialog (g1, FALSE,
20115                                              change_notify,
20116                                              change_userdata);
20117   dlg->leave_on_original = CheckBox (p, "Leave on original", NULL);
20118   dlg->strip_name_from_text = CheckBox (p, "Strip name from text", NULL);
20119 
20120   dlg->edit_apply = NULL;
20121 
20122   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->leave_on_original, (HANDLE) dlg->strip_name_from_text, NULL);
20123   return (DialoG) p;
20124 }
20125 
20126 
ConvertSourceLocationDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Uint2 entityID)20127 static DialoG ConvertSourceLocationDialog
20128 (GrouP                    h,
20129  Nlm_ChangeNotifyProc     change_notify,
20130  Pointer                  change_userdata,
20131  Uint2                    entityID)
20132 {
20133   SimpleAECRDlgPtr dlg;
20134   GrouP            p, g1;
20135 
20136   dlg = (SimpleAECRDlgPtr) MemNew (sizeof (SimpleAECRDlgData));
20137   if (dlg == NULL)
20138   {
20139     return NULL;
20140   }
20141 
20142   p = HiddenGroup (h, -1, 0, NULL);
20143   SetObjectExtra (p, dlg, StdCleanupExtraProc);
20144   SetGroupSpacing (p, 10, 10);
20145 
20146   dlg->dialog = (DialoG) p;
20147   dlg->todialog = SimpleAECRToDialog;
20148   dlg->fromdialog = DialogToSimpleAECR;
20149   dlg->dialogmessage = SimpleAECRMessage;
20150   dlg->testdialog = TestSimpleAECR;
20151   dlg->action_choice = AECR_CONVERT;
20152   dlg->free_field_vn_proc = ValNodeSimpleDataFree;
20153   dlg->free_subtype_vn_proc = NULL;
20154   dlg->change_notify = change_notify;
20155   dlg->change_userdata = change_userdata;
20156   dlg->get_autopopulate_text = NULL;
20157   dlg->entityID = entityID;
20158 
20159   dlg->subtype_list = NULL;
20160 
20161   g1 = HiddenGroup (p, 2, 0, NULL);
20162   StaticPrompt (g1, "From", 0, dialogTextHeight, systemFont, 'l');
20163   StaticPrompt (g1, "To", 0, dialogTextHeight, systemFont, 'l');
20164 
20165   dlg->field_list = SourceLocationDiscSelectionDialog (g1, FALSE,
20166                                           change_notify,
20167                                           change_userdata);
20168   dlg->field_list_to = SourceLocationSelectionDialog (g1, FALSE,
20169                                              change_notify,
20170                                              change_userdata);
20171   dlg->leave_on_original = CheckBox (p, "Leave on original", NULL);
20172 
20173   dlg->edit_apply = NULL;
20174 
20175   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->leave_on_original, NULL);
20176   return (DialoG) p;
20177 }
20178 
20179 
ChangeTaxonomyStrings(Pointer data)20180 static void ChangeTaxonomyStrings (Pointer data)
20181 {
20182   SourceQualAECRDlgPtr dlg;
20183   SimpleAECRPtr        sp;
20184 
20185   dlg = (SourceQualAECRDlgPtr) data;
20186   if (dlg == NULL) return;
20187 
20188   if (GetValue (dlg->qual_kind) == QUALKIND_STRINGS)
20189   {
20190     sp = DialogToPointer (dlg->strings);
20191     if (AreTaxNameOptionsRelevant (dlg->action_choice, sp))
20192     {
20193       Enable (dlg->taxname_options);
20194     }
20195     else
20196     {
20197       Disable (dlg->taxname_options);
20198     }
20199     sp = SimpleAECRFree (sp);
20200   }
20201   if (dlg->change_notify != NULL)
20202   {
20203     (dlg->change_notify)(dlg->change_userdata);
20204   }
20205 
20206 }
20207 
SourceQualAECRDialog(GrouP h,Int4 action_choice,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Uint2 entityID)20208 static DialoG SourceQualAECRDialog
20209 (GrouP                    h,
20210  Int4                     action_choice,
20211  Nlm_ChangeNotifyProc     change_notify,
20212  Pointer                  change_userdata,
20213  Uint2                    entityID)
20214 {
20215 
20216   SourceQualAECRDlgPtr dlg;
20217   GrouP                p, g1;
20218 
20219   dlg = (SourceQualAECRDlgPtr) MemNew (sizeof (SourceQualAECRDlgData));
20220   if (dlg == NULL)
20221   {
20222     return NULL;
20223   }
20224 
20225   p = HiddenGroup (h, -1, 0, NULL);
20226   SetObjectExtra (p, dlg, StdCleanupExtraProc);
20227   SetGroupSpacing (p, 10, 10);
20228 
20229   dlg->dialog = (DialoG) p;
20230   dlg->todialog = SourceQualAECRToDialog;
20231   dlg->fromdialog = DialogToSourceQualAECR;
20232   dlg->dialogmessage = SourceQualAECRMessage;
20233   dlg->testdialog = TestSourceQualAECR;
20234   dlg->action_choice = action_choice;
20235   dlg->change_notify = change_notify;
20236   dlg->change_userdata = change_userdata;
20237 
20238   dlg->qual_kind = HiddenGroup (p, 4, 0, ChangeQualKind);
20239   SetObjectExtra (dlg->qual_kind, dlg, NULL);
20240   RadioButton (dlg->qual_kind, "Qualifiers");
20241   RadioButton (dlg->qual_kind, "Taxonomy");
20242   if (action_choice != AECR_EDIT && action_choice != AECR_SWAP)
20243   {
20244     RadioButton (dlg->qual_kind, "Location");
20245     RadioButton (dlg->qual_kind, "Origin");
20246   }
20247   SetValue (dlg->qual_kind, QUALKIND_SOURCE_QUAL);
20248 
20249   g1 = HiddenGroup (p, 0, 0, NULL);
20250   /* Source Qualifiers dialog */
20251   if (action_choice == AECR_APPLY)
20252   {
20253     dlg->source_qual = ApplySourceQualDialog (g1,
20254                                               change_notify,
20255                                               change_userdata,
20256                                               entityID);
20257   }
20258   else if (action_choice == AECR_REMOVE)
20259   {
20260     dlg->source_qual = SimpleAECRDialog (g1, action_choice,
20261                            change_notify, change_userdata,
20262                            ValNodeSimpleDataFree, NULL,
20263                            SourceQualTypeDiscSelectionDialog, NULL, NULL,
20264                            "Qualifier", NULL, TRUE, entityID);
20265   }
20266   else if (action_choice == AECR_CONVERT)
20267   {
20268     dlg->source_qual = ConvertSourceQualDialog (g1,
20269                                                 change_notify,
20270                                                 change_userdata,
20271                                                 entityID);
20272   }
20273   else if (action_choice == AECR_SWAP)
20274   {
20275     dlg->source_qual = SimpleAECRDialogEx (g1, action_choice,
20276                            change_notify, change_userdata,
20277                            ValNodeSimpleDataFree, NULL,
20278                            SourceQualTypeSelectionDialog, NULL, NULL,
20279                            "Qualifier", NULL, TRUE, TRUE, entityID);
20280   }
20281   else
20282   {
20283     dlg->source_qual = SimpleAECRDialog (g1, action_choice,
20284                            change_notify, change_userdata,
20285                            ValNodeSimpleDataFree, NULL,
20286                            SourceQualTypeSelectionDialog, NULL, NULL,
20287                            "Qualifier", NULL, TRUE, entityID);
20288   }
20289 
20290   /* Taxonomy Strings dialog */
20291   dlg->strings = SimpleAECRDialog (g1, action_choice, ChangeTaxonomyStrings, dlg,
20292                            ValNodeSimpleDataFree, NULL,
20293                            SourceStringSelectionDialog, NULL, NULL,
20294                            "Taxonomy", NULL, TRUE, entityID);
20295 
20296   if (action_choice != AECR_EDIT && action_choice != AECR_SWAP)
20297   {
20298     /* Location Dialog */
20299     if (action_choice == AECR_APPLY)
20300     {
20301       dlg->location = SimpleAECRDialog (g1, action_choice,
20302                                         change_notify, change_userdata,
20303                                         ValNodeSimpleDataFree, NULL,
20304                                         SourceLocationSelectionDialog, NULL,
20305                                         NULL, "Location", NULL, FALSE, entityID);
20306     }
20307     else if (action_choice == AECR_CONVERT)
20308     {
20309       dlg->location = ConvertSourceLocationDialog (g1,
20310                                                     change_notify,
20311                                                     change_userdata,
20312                                                     entityID);
20313     }
20314     else
20315     {
20316       dlg->location = SimpleAECRDialog (g1, action_choice,
20317                                         change_notify, change_userdata,
20318                                         ValNodeSimpleDataFree, NULL,
20319                                         SourceLocationDiscSelectionDialog,
20320                                         NULL, NULL, "Location", NULL, FALSE,
20321                                         entityID);
20322     }
20323 
20324     /* Origin Dialog */
20325     dlg->origin = SimpleAECRDialog (g1, action_choice, change_notify, change_userdata,
20326                            ValNodeSimpleDataFree, NULL,
20327                            SourceOriginSelectionDialog, NULL, NULL,
20328                            "Origin", NULL, FALSE, entityID);
20329   }
20330 
20331   dlg->taxname_options = TaxnameOptionsDialog (p, change_notify, change_userdata);
20332 
20333   Disable (dlg->taxname_options);
20334 
20335   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->source_qual,
20336                               (HANDLE) dlg->location,
20337                               (HANDLE) dlg->origin,
20338                               (HANDLE) dlg->strings,
20339                               NULL);
20340 
20341   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->qual_kind,
20342                               (HANDLE) g1,
20343                               (HANDLE) dlg->taxname_options,
20344                               NULL);
20345 
20346   ChangeQualKind (dlg->qual_kind);
20347   return (DialoG) p;
20348 }
20349 
20350 
BioSourceHasMultipleQuals(BioSourcePtr biop,SourceQualDescPtr sqdp,FilterSetPtr fsp)20351 static Boolean BioSourceHasMultipleQuals (BioSourcePtr biop, SourceQualDescPtr sqdp, FilterSetPtr fsp)
20352 {
20353   OrgModPtr    mod;
20354   SubSourcePtr ssp;
20355   Boolean      found_one = FALSE;
20356 
20357   if (biop == NULL || sqdp == NULL) return FALSE;
20358 
20359   if (sqdp->isOrgMod)
20360   {
20361     if (biop->org != NULL && biop->org->orgname != NULL)
20362     {
20363       mod = biop->org->orgname->mod;
20364       while (mod != NULL)
20365       {
20366         if (mod->subtype == sqdp->subtype
20367             && !StringHasNoText (mod->subname)
20368             && OrgModSpecialMatch (mod, fsp))
20369         {
20370           if (found_one) {
20371             return TRUE;
20372           } else {
20373             found_one = TRUE;
20374           }
20375         }
20376         mod = mod->next;
20377       }
20378     }
20379   }
20380   else
20381   {
20382     ssp = biop->subtype;
20383     while (ssp != NULL)
20384     {
20385       if (ssp->subtype == sqdp->subtype
20386           && !StringHasNoText (ssp->name)
20387           && SubSrcSpecialMatch (ssp, fsp))
20388       {
20389         if (found_one) {
20390           return TRUE;
20391         } else {
20392           found_one = TRUE;
20393         }
20394       }
20395       ssp = ssp->next;
20396     }
20397   }
20398   return FALSE;
20399 }
20400 
CheckBioSrcListForMultipleQuals(ValNodePtr biosrc_list,SourceQualDescPtr sqdp,FilterSetPtr fsp)20401 static Boolean CheckBioSrcListForMultipleQuals (ValNodePtr biosrc_list, SourceQualDescPtr sqdp, FilterSetPtr fsp)
20402 {
20403   ValNodePtr   vnp;
20404   SeqFeatPtr   sfp;
20405   SeqDescrPtr  sdp;
20406   Boolean      has_multiple = FALSE;
20407 
20408   if (sqdp == NULL) return FALSE;
20409 
20410   for (vnp = biosrc_list; vnp != NULL && !has_multiple; vnp = vnp->next)
20411   {
20412     if (vnp->data.ptrvalue == NULL) continue;
20413     if (vnp->choice == OBJ_SEQFEAT)
20414     {
20415       sfp = (SeqFeatPtr) vnp->data.ptrvalue;
20416       if (sfp->data.choice == SEQFEAT_BIOSRC)
20417       {
20418         has_multiple = BioSourceHasMultipleQuals ((BioSourcePtr)sfp->data.value.ptrvalue, sqdp, fsp);
20419       }
20420     }
20421     else if (vnp->choice == OBJ_SEQDESC)
20422     {
20423       sdp = (SeqDescrPtr) vnp->data.ptrvalue;
20424       if (sdp->choice == Seq_descr_source)
20425       {
20426         has_multiple = BioSourceHasMultipleQuals ((BioSourcePtr)sdp->data.ptrvalue, sqdp, fsp);
20427       }
20428     }
20429   }
20430   return has_multiple;
20431 }
20432 
20433 
20434 typedef struct taxnameoptionsdlg
20435 {
20436   DIALOG_MESSAGE_BLOCK
20437   ButtoN               remove_taxref;
20438   ButtoN               remove_common;
20439   ButtoN               remove_old_name;
20440   Nlm_ChangeNotifyProc change_notify;
20441   Pointer              change_userdata;
20442 } TaxnameOptionsDlgData, PNTR TaxnameOptionsDlgPtr;
20443 
TaxnameOptionsToDialog(DialoG d,Pointer data)20444 static void TaxnameOptionsToDialog (DialoG d, Pointer data)
20445 {
20446   TaxnameOptionsDlgPtr dlg;
20447   TaxnameOptionsPtr    top;
20448 
20449   dlg = (TaxnameOptionsDlgPtr) GetObjectExtra (d);
20450   if (dlg == NULL) return;
20451 
20452   top = (TaxnameOptionsPtr) data;
20453   if (top == NULL)
20454   {
20455     SetStatus (dlg->remove_taxref, TRUE);
20456     SetStatus (dlg->remove_common, TRUE);
20457     SetStatus (dlg->remove_old_name, TRUE);
20458   }
20459   else
20460   {
20461     SetStatus (dlg->remove_taxref, top->remove_taxref);
20462     SetStatus (dlg->remove_common, top->remove_common);
20463     SetStatus (dlg->remove_old_name, top->remove_old_name);
20464   }
20465   if (dlg->change_notify != NULL)
20466   {
20467     (dlg->change_notify) (dlg->change_userdata);
20468   }
20469 }
20470 
TaxnameOptionsFromDialog(DialoG d)20471 static Pointer TaxnameOptionsFromDialog (DialoG d)
20472 {
20473   TaxnameOptionsDlgPtr dlg;
20474   TaxnameOptionsPtr    top;
20475 
20476   dlg = (TaxnameOptionsDlgPtr) GetObjectExtra (d);
20477   if (dlg == NULL) return NULL;
20478 
20479   top = (TaxnameOptionsPtr) MemNew (sizeof (TaxnameOptionsData));
20480   top->remove_taxref = GetStatus (dlg->remove_taxref);
20481   top->remove_common = GetStatus (dlg->remove_common);
20482   top->remove_old_name = GetStatus (dlg->remove_old_name);
20483   return top;
20484 }
20485 
20486 
ChangeTaxnameOptions(ButtoN b)20487 static void ChangeTaxnameOptions (ButtoN b)
20488 {
20489   TaxnameOptionsDlgPtr dlg;
20490 
20491   dlg = (TaxnameOptionsDlgPtr) GetObjectExtra (b);
20492   if (dlg != NULL && dlg->change_notify != NULL)
20493   {
20494     (dlg->change_notify) (dlg->change_userdata);
20495   }
20496 }
20497 
20498 
TaxnameOptionsDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)20499 extern DialoG TaxnameOptionsDialog (GrouP h, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
20500 {
20501   TaxnameOptionsDlgPtr dlg;
20502   GrouP                p;
20503 
20504   dlg = (TaxnameOptionsDlgPtr) MemNew (sizeof (TaxnameOptionsDlgData));
20505   if (dlg == NULL)
20506   {
20507     return NULL;
20508   }
20509 
20510   p = HiddenGroup (h, 3, 0, NULL);
20511   SetObjectExtra (p, dlg, StdCleanupExtraProc);
20512   SetGroupSpacing (p, 10, 10);
20513 
20514   dlg->dialog = (DialoG) p;
20515   dlg->todialog = TaxnameOptionsToDialog;
20516   dlg->fromdialog = TaxnameOptionsFromDialog;
20517   dlg->change_notify = change_notify;
20518   dlg->change_userdata = change_userdata;
20519 
20520   dlg->remove_taxref = CheckBox (p, "Remove taxonomy xref", ChangeTaxnameOptions);
20521   SetObjectExtra (dlg->remove_taxref, dlg, NULL);
20522   SetStatus (dlg->remove_taxref, TRUE);
20523   dlg->remove_common = CheckBox (p, "Remove GenBank common name", ChangeTaxnameOptions);
20524   SetObjectExtra (dlg->remove_common, dlg, NULL);
20525   SetStatus (dlg->remove_common, TRUE);
20526   dlg->remove_old_name = CheckBox (p, "Remove old_name qualifier", ChangeTaxnameOptions);
20527   SetObjectExtra (dlg->remove_old_name, dlg, NULL);
20528   SetStatus (dlg->remove_old_name, TRUE);
20529   return (DialoG) p;
20530 }
20531 
ApplyTaxnameOptionsToBioSource(BioSourcePtr biop,TaxnameOptionsPtr top)20532 extern void ApplyTaxnameOptionsToBioSource (BioSourcePtr biop, TaxnameOptionsPtr top)
20533 {
20534   if (biop == NULL || top == NULL) return;
20535 
20536   if (top->remove_taxref)
20537   {
20538     RemoveTaxRef (biop->org);
20539   }
20540   if (top->remove_old_name)
20541   {
20542     RemoveOldName (biop->org);
20543   }
20544   if (top->remove_common)
20545   {
20546     if (biop->org != NULL)
20547     {
20548       biop->org->common = MemFree (biop->org->common);
20549     }
20550   }
20551 }
20552 
HandleTaxnameOptionsFeature(SeqFeatPtr sfp,TaxnameOptionsPtr top)20553 static void HandleTaxnameOptionsFeature (SeqFeatPtr sfp, TaxnameOptionsPtr top)
20554 {
20555   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || top == NULL)
20556   {
20557     return;
20558   }
20559   ApplyTaxnameOptionsToBioSource (sfp->data.value.ptrvalue, top);
20560 }
20561 
HandleTaxnameOptionsDescriptorCallback(SeqDescrPtr sdp,TaxnameOptionsPtr top)20562 static void HandleTaxnameOptionsDescriptorCallback (SeqDescrPtr sdp, TaxnameOptionsPtr top)
20563 {
20564   if (sdp == NULL || sdp->choice != Seq_descr_source || top == NULL)
20565   {
20566     return;
20567   }
20568   ApplyTaxnameOptionsToBioSource (sdp->data.ptrvalue, top);
20569 }
20570 
20571 
HandleTaxnameOptionsForBioSourceList(ValNodePtr biosrc_list,TaxnameOptionsPtr top)20572 static void HandleTaxnameOptionsForBioSourceList (ValNodePtr biosrc_list, TaxnameOptionsPtr top)
20573 {
20574   ValNodePtr vnp;
20575 
20576   if (top == NULL) return;
20577   for (vnp = biosrc_list; vnp != NULL; vnp = vnp->next)
20578   {
20579     if (vnp->choice == OBJ_SEQFEAT)
20580     {
20581       HandleTaxnameOptionsFeature (vnp->data.ptrvalue, top);
20582     }
20583     else if (vnp->choice == OBJ_SEQDESC)
20584     {
20585       HandleTaxnameOptionsDescriptorCallback (vnp->data.ptrvalue, top);
20586     }
20587   }
20588 }
20589 
CollectBioSourceFeatureFieldCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)20590 static void CollectBioSourceFeatureFieldCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
20591 {
20592   if (sfp == NULL || userdata == NULL)
20593   {
20594     return;
20595   }
20596   ValNodeAddPointer ((ValNodePtr PNTR) userdata, OBJ_SEQFEAT, sfp);
20597 }
20598 
CollectBioSourceDescriptorFieldCallback(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)20599 static void CollectBioSourceDescriptorFieldCallback (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
20600 {
20601   if (sdp == NULL || userdata == NULL)
20602   {
20603     return;
20604   }
20605 
20606   ValNodeAddPointer ((ValNodePtr PNTR) userdata, OBJ_SEQDESC, sdp);
20607 }
20608 
20609 
RemoveSourceQualEditNonMatches(ValNodePtr PNTR biosrc_list,ApplyValuePtr avp)20610 static void RemoveSourceQualEditNonMatches (ValNodePtr PNTR biosrc_list, ApplyValuePtr avp)
20611 {
20612   ValNodePtr vnp_prev = NULL, vnp_next, vnp_this;
20613   CharPtr    val1, val2;
20614   Boolean    do_remove;
20615 
20616   if (biosrc_list == NULL || avp == NULL || StringHasNoText (avp->text_to_replace))
20617   {
20618     return;
20619   }
20620 
20621   vnp_this = *biosrc_list;
20622   while (vnp_this != NULL)
20623   {
20624     vnp_next = vnp_this->next;
20625     do_remove = FALSE;
20626     if (vnp_this->choice == OBJ_SEQFEAT)
20627     {
20628       val1 = GetSourceQualFeatureString (vnp_this->data.ptrvalue, avp->field_list, NULL);
20629     }
20630     else if (vnp_this->choice == OBJ_SEQDESC)
20631     {
20632       val1 = GetSourceQualDescrString (vnp_this->data.ptrvalue, avp->field_list, NULL);
20633     }
20634     else
20635     {
20636       val1 = NULL;
20637     }
20638     if (val1 == NULL)
20639     {
20640       do_remove = TRUE;
20641     }
20642     else
20643     {
20644       val2 = HandleApplyValue (StringSave (val1), avp);
20645       if (StringCmp (val1, val2) == 0)
20646       {
20647         do_remove = TRUE;
20648       }
20649       val1 = MemFree (val1);
20650       val2 = MemFree (val2);
20651     }
20652     if (do_remove)
20653     {
20654       if (vnp_prev == NULL)
20655       {
20656         *biosrc_list = vnp_this->next;
20657       }
20658       else
20659       {
20660         vnp_prev->next = vnp_this->next;
20661       }
20662       vnp_this->next = NULL;
20663       vnp_this = ValNodeFree (vnp_this);
20664     }
20665     else
20666     {
20667       vnp_prev = vnp_this;
20668     }
20669     vnp_this = vnp_next;
20670   }
20671 }
20672 
20673 
20674 static Boolean
SourceQualQualApplyEditConvertRemoveAction(ApplyEditConvertRemovePtr ap,SimpleAECRPtr sp,Int4 action_choice,SetFeatureFieldString feature_apply_action,SetDescriptorFieldString descriptor_apply_action,RemoveFeatureFieldString feature_remove_action,RemoveDescriptorFieldString descriptor_remove_action,CopyValNodeDataProc copy_vn_proc,GetFeatureFieldString fieldstring_func,GetDescriptorFieldString descrstring_func,Boolean non_text,NameFromValNodeProc name_field_func,TaxnameOptionsPtr top)20675 SourceQualQualApplyEditConvertRemoveAction
20676 (ApplyEditConvertRemovePtr   ap,
20677  SimpleAECRPtr               sp,
20678  Int4                        action_choice,
20679  SetFeatureFieldString       feature_apply_action,
20680  SetDescriptorFieldString    descriptor_apply_action,
20681  RemoveFeatureFieldString    feature_remove_action,
20682  RemoveDescriptorFieldString descriptor_remove_action,
20683  CopyValNodeDataProc         copy_vn_proc,
20684  GetFeatureFieldString       fieldstring_func,
20685  GetDescriptorFieldString    descrstring_func,
20686  Boolean                     non_text,
20687  NameFromValNodeProc         name_field_func,
20688  TaxnameOptionsPtr           top)
20689 
20690 {
20691   SeqEntryPtr               sep;
20692   ApplyValueData            avd;
20693   ConvertFieldData          cfd;
20694   FilterSetPtr              fsp;
20695   GetSamplePtr              gsp;
20696   Boolean                   rval = TRUE;
20697   ValNodePtr                vnp;
20698   CharPtr                   field_name = NULL;
20699   MsgAnswer                 ans;
20700   ValNodePtr                biosrc_list = NULL;
20701   SourceQualDescPtr         multi_sqdp = NULL;
20702 
20703   sep = GetTopSeqEntryForEntityID (ap->input_entityID);
20704   if (sp == NULL
20705       || sp->field_list == NULL
20706       || feature_apply_action == NULL
20707       || descriptor_apply_action == NULL
20708       || feature_remove_action == NULL
20709       || descriptor_remove_action == NULL
20710       || ((action_choice == AECR_CONVERT || action_choice == AECR_SWAP || action_choice == AECR_PARSE)
20711            && sp->field_list == NULL))
20712   {
20713     return FALSE;
20714   }
20715 
20716   WatchCursor ();
20717   Update ();
20718 
20719   avd.where_to_replace = EditApplyFindLocation_anywhere;
20720 
20721   fsp = (FilterSetPtr) DialogToPointer (ap->constraints);
20722 
20723   /* collect list of BioSources that will be acted upon */
20724   OperateOnSeqEntryConstrainedObjects (sep, fsp,
20725                                        CollectBioSourceFeatureFieldCallback,
20726                                        CollectBioSourceDescriptorFieldCallback,
20727                                        SEQFEAT_BIOSRC, 0, Seq_descr_source,
20728                                        &biosrc_list);
20729 
20730   if (action_choice == AECR_CONVERT || action_choice == AECR_SWAP || action_choice == AECR_PARSE)
20731   {
20732     /* check for multiple sources */
20733     if ((sp->field_list->choice == 0
20734          && (multi_sqdp = sp->field_list->data.ptrvalue) != NULL
20735          && CheckBioSrcListForMultipleQuals(biosrc_list, multi_sqdp, fsp))
20736         || (action_choice == AECR_SWAP && sp->field_list_to->choice == 0
20737             && (multi_sqdp = sp->field_list_to->data.ptrvalue) != NULL
20738             && CheckBioSrcListForMultipleQuals(biosrc_list, multi_sqdp, fsp))) {
20739       if (name_field_func != NULL) {
20740         if (action_choice == AECR_SWAP && multi_sqdp == sp->field_list_to->data.ptrvalue) {
20741           field_name = name_field_func(sp->field_list_to);
20742         } else {
20743           field_name = name_field_func(sp->field_list);
20744         }
20745       }
20746       if (field_name != NULL) {
20747         ans = Message (MSG_OKC, "One or more BioSources has multiple source quals.  These will be combined.  Do you want to continue?");
20748       } else {
20749         ans = Message (MSG_OKC, "One or more BioSources has multiple %s source quals.  These will be combined.  Do you want to continue?", field_name);
20750       }
20751       field_name = MemFree (field_name);
20752       if (ans == ANS_CANCEL) {
20753         FilterSetFree (fsp);
20754         ArrowCursor();
20755         Update();
20756         return FALSE;
20757       }
20758     }
20759     cfd.src_field_list = sp->field_list;
20760     cfd.dst_field_list = sp->field_list_to;
20761     cfd.etp = NULL;
20762     cfd.get_str_func = fieldstring_func;
20763     cfd.set_str_func = feature_apply_action;
20764     cfd.remove_str_func = feature_remove_action;
20765     cfd.get_d_str_func = descrstring_func;
20766     cfd.set_d_str_func = descriptor_apply_action;
20767     cfd.remove_d_str_func = descriptor_remove_action;
20768     cfd.fsp = fsp;
20769     cfd.strip_name_from_text = sp->strip_name_from_text;
20770     cfd.remove_parsed = sp->remove_parsed;
20771     cfd.name_field_func = name_field_func;
20772     cfd.text_portion = sp->text_portion;
20773     if (action_choice == AECR_CONVERT)
20774     {
20775       if (sp->leave_on_original)
20776       {
20777         cfd.convert_type = CONVERT_TYPE_COPY;
20778       }
20779       else
20780       {
20781         cfd.convert_type = CONVERT_TYPE_MOVE;
20782       }
20783     }
20784     else if (action_choice == AECR_SWAP)
20785     {
20786       cfd.convert_type = CONVERT_TYPE_SWAP;
20787     }
20788     else if (action_choice == AECR_PARSE)
20789     {
20790       cfd.convert_type = CONVERT_TYPE_PARSE;
20791     }
20792     if ((cfd.convert_type == CONVERT_TYPE_MOVE || cfd.convert_type == CONVERT_TYPE_COPY || cfd.convert_type == CONVERT_TYPE_PARSE)
20793         && ! non_text)
20794     {
20795       gsp = CheckForConversionExistingTextInSeqEntry (sep, &cfd, fsp,
20796                                                       SEQFEAT_BIOSRC, 0,
20797                                                       Seq_descr_source);
20798       cfd.etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, non_text);
20799       gsp = GetSampleFree (gsp);
20800       if (cfd.etp != NULL && cfd.etp->existing_text_choice == eExistingTextChoiceCancel)
20801       {
20802         rval = FALSE;
20803       }
20804     }
20805     else
20806     {
20807       cfd.etp = NULL;
20808     }
20809 
20810     if (rval)
20811     {
20812       if (non_text)
20813       {
20814         OperateOnSeqEntryConstrainedObjects (sep, fsp,
20815                                              ConvertNonTextFeatureFieldCallback,
20816                                              ConvertNonTextDescriptorFieldCallback,
20817                                              SEQFEAT_BIOSRC, 0, Seq_descr_source,
20818                                              &cfd);
20819       }
20820       else
20821       {
20822         OperateOnSeqEntryConstrainedObjects (sep, fsp,
20823                                              ConvertFeatureFieldCallback,
20824                                              ConvertDescriptorFieldCallback,
20825                                              SEQFEAT_BIOSRC, 0, Seq_descr_source,
20826                                              &cfd);
20827       }
20828 
20829     }
20830     cfd.etp = MemFree (cfd.etp);
20831   }
20832   else
20833   {
20834     avd.field_list = sp->field_list;
20835 
20836     /* get handling for existing text */
20837     if (action_choice == AECR_APPLY)
20838     {
20839       gsp = CheckForExistingText (ap->input_entityID,
20840                                   avd.field_list,
20841                                   fieldstring_func,
20842                                   descrstring_func,
20843                                   ValNodeSimpleDataFree,
20844                                   copy_vn_proc,
20845                                   fsp, SEQFEAT_BIOSRC, 0, Seq_descr_source);
20846       avd.etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, non_text);
20847       gsp = GetSampleFree (gsp);
20848 
20849       if (avd.etp != NULL
20850           && avd.etp->existing_text_choice == eExistingTextChoiceCancel)
20851       {
20852         rval = FALSE;
20853       }
20854     }
20855     else
20856     {
20857       avd.etp = NULL;
20858     }
20859 
20860     if (rval)
20861     {
20862       AddEditApplyDataToApplyValue (action_choice, sp->edit_apply, &avd);
20863 
20864       if (action_choice == AECR_EDIT)
20865       {
20866         /* remove items that don't contain text that will be replaced */
20867         RemoveSourceQualEditNonMatches (&biosrc_list, &avd);
20868       }
20869 
20870 
20871       if (action_choice == AECR_EDIT || action_choice == AECR_APPLY)
20872       {
20873         OperateOnSeqEntryConstrainedObjects (sep, fsp,
20874                                              feature_apply_action,
20875                                              descriptor_apply_action,
20876                                              SEQFEAT_BIOSRC, 0, Seq_descr_source, &avd);
20877       }
20878       else if (action_choice == AECR_REMOVE)
20879       {
20880         for (vnp = sp->field_list; vnp != NULL; vnp = vnp->next)
20881         {
20882           avd.field_list = vnp;
20883           OperateOnSeqEntryConstrainedObjects (sep, fsp,
20884                                                feature_remove_action,
20885                                                descriptor_remove_action,
20886                                                SEQFEAT_BIOSRC, 0, Seq_descr_source, &avd);
20887         }
20888       }
20889 
20890       avd.text_to_replace = MemFree (avd.text_to_replace);
20891       avd.new_text = MemFree (avd.new_text);
20892     }
20893     avd.etp = MemFree (avd.etp);
20894   }
20895 
20896   FilterSetFree (fsp);
20897 
20898   if (rval)
20899   {
20900     /* Handle taxname options */
20901     HandleTaxnameOptionsForBioSourceList (biosrc_list, top);
20902 
20903     ObjMgrSetDirtyFlag (ap->input_entityID, TRUE);
20904     ObjMgrSendMsg (OM_MSG_UPDATE, ap->input_entityID, 0, 0);
20905   }
20906   biosrc_list = ValNodeFree (biosrc_list);
20907   ArrowCursor ();
20908   Update ();
20909 
20910   return rval;
20911 }
20912 
SourceQualApplyEditConvertRemoveAction(Pointer userdata)20913 static Boolean SourceQualApplyEditConvertRemoveAction (Pointer userdata)
20914 {
20915   ApplyEditConvertRemovePtr ap;
20916   SourceQualAECRPtr         sp;
20917   Int4                      action_choice;
20918   Boolean                   rval = FALSE;
20919 
20920   ap = (ApplyEditConvertRemovePtr) userdata;
20921   if (ap == NULL)
20922   {
20923     return FALSE;
20924   }
20925 
20926   if (ap->crippled)
20927   {
20928     action_choice = ap->crippled_action;
20929   }
20930   else
20931   {
20932     action_choice = GetValue (ap->action_popup);
20933   }
20934   if (action_choice < 1 || action_choice > NUM_AECR)
20935   {
20936     return FALSE;
20937   }
20938   sp = (SourceQualAECRPtr) DialogToPointer (ap->aecr_pages[action_choice - 1]);
20939 
20940   switch (sp->qual_kind)
20941   {
20942     case QUALKIND_SOURCE_QUAL :
20943       rval = SourceQualQualApplyEditConvertRemoveAction (ap, sp->source_qual,
20944                                                          action_choice,
20945                                        ApplySourceQualFeatureCallback,
20946                                        ApplySourceQualDescriptorCallback,
20947                                        RemoveSourceQualFromSourceFeature,
20948                                        RemoveSourceQualFromSourceDescriptor,
20949                                        SourceQualValNodeDataCopy,
20950                                        GetSourceQualFeatureString,
20951                                        GetSourceQualDescrString,
20952                                        FALSE,
20953                                        SourceQualValNodeName,
20954                                        NULL);
20955       break;
20956     case QUALKIND_STRINGS :
20957       rval = SourceQualQualApplyEditConvertRemoveAction (ap, sp->strings,
20958                                                          action_choice,
20959                                        ApplyStringToSourceFeature,
20960                                        ApplyStringToSourceDescriptor,
20961                                        RemoveStringFromSourceFeature,
20962                                        RemoveStringFromSourceDescriptor,
20963                                        ValNodeStringCopy,
20964                                        GetStringFromSourceFeature,
20965                                        GetStringFromSourceDescriptor,
20966                                        FALSE,
20967                                        NULL,
20968                                        sp->taxname_options);
20969       break;
20970     case QUALKIND_LOCATION :
20971       rval = SourceQualQualApplyEditConvertRemoveAction (ap, sp->location,
20972                                                          action_choice,
20973                                        ApplyLocationToSourceFeature,
20974                                        ApplyLocationToSourceDescriptor,
20975                                        RemoveLocationFromSourceFeature,
20976                                        RemoveLocationFromSourceDescriptor,
20977                                        ValNodeStringCopy,
20978                                        GetLocationFromSourceFeature,
20979                                        GetLocationFromSourceDescriptor,
20980                                        TRUE,
20981                                        ValNodeStringName,
20982                                        NULL);
20983       break;
20984     case QUALKIND_ORIGIN :
20985       rval = SourceQualQualApplyEditConvertRemoveAction (ap, sp->origin,
20986                                                          action_choice,
20987                                        ApplyOriginToSourceFeature,
20988                                        ApplyOriginToSourceDescriptor,
20989                                        RemoveOriginFromSourceFeature,
20990                                        RemoveOriginFromSourceDescriptor,
20991                                        ValNodeStringCopy,
20992                                        GetOriginFromSourceFeature,
20993                                        GetOriginFromSourceDescriptor,
20994                                        TRUE,
20995                                        ValNodeStringName,
20996                                        NULL);
20997       break;
20998   }
20999   sp = SourceQualAECRFree (sp);
21000   return rval;
21001 }
21002 
ChangeSourceQualAction(DialoG prev_page,DialoG new_page)21003 static void ChangeSourceQualAction (DialoG prev_page, DialoG new_page)
21004 {
21005   SourceQualAECRPtr         prev_sp, new_sp;
21006 
21007   if (prev_page == NULL || new_page == NULL)
21008   {
21009     return;
21010   }
21011 
21012   prev_sp = (SourceQualAECRPtr) DialogToPointer (prev_page);
21013   new_sp = (SourceQualAECRPtr) DialogToPointer (new_page);
21014   if (prev_sp != NULL && new_sp != NULL)
21015   {
21016     new_sp->qual_kind = prev_sp->qual_kind;
21017     PointerToDialog (new_page, new_sp);
21018   }
21019   new_sp = SourceQualAECRFree (new_sp);
21020   prev_sp = SourceQualAECRFree (prev_sp);
21021 }
21022 
GetSourceQualSample(GrouP h,Uint2 entityID)21023 static DialoG GetSourceQualSample (GrouP h, Uint2 entityID)
21024 {
21025   DialoG                d;
21026   SetSampleData         ssd;
21027 
21028   d = SampleDialog (h);
21029   ssd.fieldstring_func = GetSourceQualFeatureString;
21030   ssd.descrstring_func = GetSourceQualDescrString;
21031   ssd.entityID = entityID;
21032   ssd.field_list = GetSourceQualDescList (TRUE, TRUE, TRUE, FALSE);
21033   ValNodeAddPointer (&(ssd.field_list), 1, StringSave ("Scientific Name"));
21034   ValNodeAddPointer (&(ssd.field_list), 1, StringSave ("Location"));
21035 
21036   ssd.fsp = NULL;
21037   ssd.free_vn_proc = ValNodeSimpleDataFree;
21038   ssd.copy_vn_proc = SourceQualValNodeDataCopy;
21039   ssd.match_vn_proc = SourceQualValNodeMatch;
21040   ssd.label_vn_proc = SourceQualValNodeName;
21041   PointerToDialog (d, &ssd);
21042   return d;
21043 }
21044 
21045 static void
SourceQualApplyEditConvertRemove(IteM i,Int4 first_action_choice,Boolean crippled)21046 SourceQualApplyEditConvertRemove
21047 (IteM    i,
21048  Int4    first_action_choice,
21049  Boolean crippled)
21050 {
21051   ApplyEditConvertRemoveCombo (i, first_action_choice, crippled,
21052                                "Source Qual",
21053                                SourceQualAECRDialog,
21054                                FALSE, GetSourceQualSample,
21055                                FALSE, TRUE, FALSE, FALSE, FALSE, NULL,
21056                                SourceQualApplyEditConvertRemoveAction, NULL,
21057                                ChangeSourceQualAction, NULL);
21058 }
21059 
ApplySourceQual(IteM i)21060 extern void ApplySourceQual (IteM i)
21061 {
21062   SourceQualApplyEditConvertRemove (i, AECR_APPLY, FALSE);
21063 }
21064 
PublicApplySourceQual(IteM i)21065 extern void PublicApplySourceQual (IteM i)
21066 {
21067   SourceQualApplyEditConvertRemove (i, AECR_APPLY, TRUE);
21068 }
21069 
EditSourceQual(IteM i)21070 extern void EditSourceQual (IteM i)
21071 {
21072   SourceQualApplyEditConvertRemove (i, AECR_EDIT, FALSE);
21073 }
21074 
PublicEditSourceQual(IteM i)21075 extern void PublicEditSourceQual (IteM i)
21076 {
21077   SourceQualApplyEditConvertRemove (i, AECR_EDIT, TRUE);
21078 }
21079 
ConvertSourceQual(IteM i)21080 extern void ConvertSourceQual (IteM i)
21081 {
21082   SourceQualApplyEditConvertRemove (i, AECR_CONVERT, FALSE);
21083 }
21084 
SwapSourceQual(IteM i)21085 extern void SwapSourceQual (IteM i)
21086 {
21087   SourceQualApplyEditConvertRemove (i, AECR_SWAP, FALSE);
21088 }
21089 
RemoveSourceQual(IteM i)21090 extern void RemoveSourceQual (IteM i)
21091 {
21092   SourceQualApplyEditConvertRemove (i, AECR_REMOVE, FALSE);
21093 }
21094 
21095 static CharPtr rna_sample_field_list [] = { "Product",
21096                                             "Comment" };
21097 static Int2    num_rna_sample_fields = sizeof (rna_sample_field_list) / sizeof (CharPtr);
21098 
21099 
GetRNASampleFieldString(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)21100 static CharPtr GetRNASampleFieldString (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
21101 {
21102   RnaRefPtr  rrp;
21103   CharPtr    str = NULL;
21104   Int2       rna_subtype, rna_field_type;
21105   GeneRefPtr grp;
21106   SeqFeatPtr gene;
21107   ValNode    vn;
21108   SeqMgrFeatContext    fcontext;
21109 
21110   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA || vnp == NULL)
21111   {
21112     return NULL;
21113   }
21114 
21115   rrp = sfp->data.value.ptrvalue;
21116 
21117   while (vnp != NULL && str == NULL)
21118   {
21119     rna_subtype = (vnp->data.intvalue - 1) / (num_rna_sample_fields + num_gene_fields);
21120     rna_field_type = (vnp->data.intvalue - 1) % (num_rna_sample_fields + num_gene_fields);
21121     switch (rna_subtype)
21122     {
21123       case 0:
21124         if (rrp->type != 255
21125             || (rrp->ext.choice == 1
21126                 && (StringCmp (rrp->ext.value.ptrvalue, "ncRNA") == 0
21127                     || StringCmp (rrp->ext.value.ptrvalue, "tmRNA") == 0)))
21128         {
21129           vnp = vnp->next;
21130           continue;
21131         }
21132         break;
21133       case 1:
21134       case 2:
21135       case 3:
21136       case 4:
21137         if (rna_subtype != rrp->type)
21138         {
21139           vnp = vnp->next;
21140           continue;
21141         }
21142         break;
21143       case 5:
21144         if (rrp->type != 255
21145             || rrp->ext.choice != 1
21146             || StringCmp (rrp->ext.value.ptrvalue, "ncRNA") != 0)
21147         {
21148           vnp = vnp->next;
21149           continue;
21150         }
21151         break;
21152       case 6:
21153         if (rrp->type != 255
21154             || rrp->ext.choice != 1
21155             || StringCmp (rrp->ext.value.ptrvalue, "tmRNA") != 0)
21156         {
21157           vnp = vnp->next;
21158           continue;
21159         }
21160         break;
21161     }
21162 
21163     switch (rna_field_type)
21164     {
21165       case 0 :
21166         str = GetRNAProductString (sfp, NULL);
21167         break;
21168       case 1 :
21169         if (!StringHasNoText (sfp->comment))
21170         {
21171           str = StringSave (sfp->comment);
21172         }
21173         break;
21174       default :
21175         vn.next = NULL;
21176         vn.choice = 0;
21177         vn.data.intvalue = rna_field_type - num_rna_sample_fields + 1;
21178         grp = SeqMgrGetGeneXref (sfp);
21179         if (grp == NULL)
21180         {
21181           gene = SeqMgrGetOverlappingGene (sfp->location, &fcontext);
21182           str = GetGeneFieldString (gene, &vn, NULL);
21183         }
21184         else
21185         {
21186           str = GetGeneFieldString (sfp, &vn, NULL);
21187         }
21188         break;
21189     }
21190     vnp = vnp->next;
21191   }
21192   return str;
21193 }
21194 
GetRNAQualSampleName(ValNodePtr vnp)21195 static CharPtr GetRNAQualSampleName (ValNodePtr vnp)
21196 {
21197   CharPtr label = NULL;
21198   Int2    rna_subtype, rna_field_type;
21199 
21200   if (vnp == NULL)
21201   {
21202     return NULL;
21203   }
21204   rna_subtype = (vnp->data.intvalue - 1) / (num_rna_sample_fields + num_gene_fields);
21205   rna_field_type = (vnp->data.intvalue - 1) % (num_rna_sample_fields + num_gene_fields);
21206 
21207   if (rna_field_type < num_rna_sample_fields)
21208   {
21209     label = (CharPtr) MemNew ((StringLen (rna_subtype_list [rna_subtype])
21210                               + StringLen (rna_sample_field_list[rna_field_type])
21211                               + 2) * sizeof (Char));
21212     if (label != NULL)
21213     {
21214       sprintf (label, "%s %s", rna_subtype_list [rna_subtype],
21215                rna_sample_field_list[rna_field_type]);
21216     }
21217   }
21218   else if (rna_field_type < num_rna_sample_fields + num_gene_fields)
21219   {
21220     label = (CharPtr) MemNew ((StringLen (rna_subtype_list [rna_subtype])
21221                               + StringLen (gene_field_list[rna_field_type - num_rna_sample_fields])
21222                               + 7) * sizeof (Char));
21223     if (label != NULL)
21224     {
21225       sprintf (label, "%s Gene %s", rna_subtype_list [rna_subtype],
21226                gene_field_list[rna_field_type - num_rna_sample_fields]);
21227     }
21228   }
21229   return label;
21230 }
21231 
GetRNAQualSample(GrouP h,Uint2 entityID)21232 static DialoG GetRNAQualSample (GrouP h, Uint2 entityID)
21233 {
21234   DialoG        d;
21235   SetSampleData ssd;
21236   Int2          rna_subtype, field_type;
21237   Int4          list_index;
21238 
21239   d = SampleDialog (h);
21240   ssd.fieldstring_func = GetRNASampleFieldString;
21241   ssd.descrstring_func = NULL;
21242   ssd.entityID = entityID;
21243 
21244   /* construct RNA field list for separate types of RNAs */
21245   ssd.free_vn_proc = NULL;
21246   ssd.copy_vn_proc = IntValNodeCopy;
21247   ssd.match_vn_proc = IntValNodeMatch;
21248   ssd.label_vn_proc = GetRNAQualSampleName;
21249 
21250   ssd.field_list = NULL;
21251   for (rna_subtype = 0; rna_subtype < num_rna_subtypes; rna_subtype++)
21252   {
21253     for (field_type = 0; field_type < num_rna_sample_fields; field_type++)
21254     {
21255       list_index = (rna_subtype * (num_rna_sample_fields + num_gene_fields)) + field_type;
21256       ValNodeAddInt (&ssd.field_list, 0, list_index + 1);
21257     }
21258     for (field_type = 0; field_type < num_gene_fields; field_type ++)
21259     {
21260       list_index = (rna_subtype * (num_rna_sample_fields + num_gene_fields))
21261                     + field_type + num_rna_sample_fields;
21262       ValNodeAddInt (&ssd.field_list, 0, list_index + 1);
21263     }
21264   }
21265   ssd.fsp = NULL;
21266   PointerToDialog (d, &ssd);
21267 
21268   /* now free up field list (SampleDialog maintains its own copy */
21269   ssd.field_list = ValNodeFree (ssd.field_list);
21270 
21271   return d;
21272 }
21273 
21274 typedef struct aecrrnaqual
21275 {
21276   ValNodePtr   field_list;
21277   ValNodePtr   field_list_to;
21278   RnaTypePtr   rna_type;
21279   EditApplyPtr edit_apply;
21280   ValNodePtr   codons;
21281   SeqLocPtr    anticodon;
21282   TextPortionXPtr text_portion;
21283   Boolean        leave_on_original;
21284   Boolean        remove_parsed;
21285 } AECRRNAQualData, PNTR AECRRNAQualPtr;
21286 
AECRRNAQualFree(AECRRNAQualPtr ap)21287 static AECRRNAQualPtr AECRRNAQualFree (AECRRNAQualPtr ap)
21288 {
21289   if (ap != NULL)
21290   {
21291     ap->field_list = ValNodeFree (ap->field_list);
21292     ap->field_list_to = ValNodeFree (ap->field_list_to);
21293     ap->rna_type = RnaTypeFree (ap->rna_type);
21294     ap->edit_apply = EditApplyFree (ap->edit_apply);
21295     ap->codons = ValNodeFreeData (ap->codons);
21296     ap = MemFree (ap);
21297   }
21298   return ap;
21299 }
21300 
21301 typedef struct aecrrnaqualdlg
21302 {
21303   DIALOG_MESSAGE_BLOCK
21304   DialoG               field_list;
21305   DialoG               field_list_to;
21306   DialoG               rna_type;
21307   DialoG               edit_apply;
21308   DialoG               codons;
21309   DialoG               ncrna_class;
21310   DialoG               text_portion;
21311   ButtoN               leave_on_original;
21312   ButtoN               remove_parsed;
21313 
21314   Nlm_ChangeNotifyProc change_notify;
21315   Pointer              change_userdata;
21316   Uint2                entityID;
21317 
21318   /* The following is used to create the anticodon location dialog */
21319   FeatureForm          ff;
21320   DialoG               anticodon;
21321 } AECRRNAQualDlgData, PNTR AECRRNAQualDlgPtr;
21322 
ClearTextAECRRNAQualDlg(AECRRNAQualDlgPtr dlg)21323 static void ClearTextAECRRNAQualDlg (AECRRNAQualDlgPtr dlg)
21324 {
21325   if (dlg != NULL)
21326   {
21327     PointerToDialog (dlg->edit_apply, NULL);
21328     PointerToDialog (dlg->codons, NULL);
21329     PointerToDialog (dlg->ncrna_class, NULL);
21330   }
21331 }
21332 
ResetAECRRNAQualDlg(AECRRNAQualDlgPtr dlg)21333 static void ResetAECRRNAQualDlg (AECRRNAQualDlgPtr dlg)
21334 {
21335   if (dlg != NULL)
21336   {
21337     PointerToDialog (dlg->field_list, NULL);
21338     PointerToDialog (dlg->field_list_to, NULL);
21339     SendMessageToDialog (dlg->field_list, NUM_VIB_MSG + 1);
21340     PointerToDialog (dlg->rna_type, NULL);
21341     PointerToDialog (dlg->text_portion, NULL);
21342     SafeSetStatus (dlg->leave_on_original, FALSE);
21343     SafeSetStatus (dlg->remove_parsed, FALSE);
21344     ClearTextAECRRNAQualDlg (dlg);
21345   }
21346 }
21347 
AECRRNAQualToDialog(DialoG d,Pointer userdata)21348 static void AECRRNAQualToDialog (DialoG d, Pointer userdata)
21349 {
21350   AECRRNAQualDlgPtr dlg;
21351   AECRRNAQualPtr    data;
21352 
21353   dlg = (AECRRNAQualDlgPtr) GetObjectExtra (d);
21354   if (dlg == NULL)
21355   {
21356     return;
21357   }
21358 
21359   ResetAECRRNAQualDlg (dlg);
21360   data = (AECRRNAQualPtr) userdata;
21361   if (data != NULL)
21362   {
21363     PointerToDialog (dlg->field_list, data->field_list);
21364     PointerToDialog (dlg->field_list_to, data->field_list_to);
21365     PointerToDialog (dlg->rna_type, data->rna_type);
21366     PointerToDialog (dlg->edit_apply, data->edit_apply);
21367     PointerToDialog (dlg->codons, data->codons);
21368     if (data->field_list != NULL && data->field_list->data.intvalue == RNAFIELD_NCRNA_CLASS) {
21369       if (data->edit_apply == NULL) {
21370         PointerToDialog (dlg->ncrna_class, NULL);
21371       } else {
21372         PointerToDialog (dlg->ncrna_class, data->edit_apply->apply_txt);
21373       }
21374     }
21375     PointerToDialog (dlg->anticodon, data->anticodon);
21376     PointerToDialog (dlg->text_portion, data->text_portion);
21377     SafeSetStatus (dlg->leave_on_original, data->leave_on_original);
21378     SafeSetStatus (dlg->remove_parsed, data->remove_parsed);
21379   }
21380 }
21381 
DialogToAECRRNAQual(DialoG d)21382 static Pointer DialogToAECRRNAQual (DialoG d)
21383 {
21384   AECRRNAQualDlgPtr dlg;
21385   AECRRNAQualPtr    data;
21386 
21387   dlg = (AECRRNAQualDlgPtr) GetObjectExtra (d);
21388   if (dlg == NULL)
21389   {
21390     return NULL;
21391   }
21392 
21393   data = (AECRRNAQualPtr) MemNew (sizeof (AECRRNAQualData));
21394   if (data != NULL)
21395   {
21396     data->field_list = DialogToPointer (dlg->field_list);
21397     data->field_list_to = DialogToPointer (dlg->field_list_to);
21398     data->rna_type = DialogToPointer (dlg->rna_type);
21399     if (data->field_list != NULL && data->field_list->data.intvalue == RNAFIELD_NCRNA_CLASS
21400         && dlg->ncrna_class != NULL) {
21401       data->edit_apply = EditApplyNew ();
21402       data->edit_apply->apply_txt = DialogToPointer (dlg->ncrna_class);
21403     } else {
21404       data->edit_apply = DialogToPointer (dlg->edit_apply);
21405     }
21406     data->codons = DialogToPointer (dlg->codons);
21407     data->anticodon = DialogToPointer (dlg->anticodon);
21408     data->text_portion = DialogToPointer (dlg->text_portion);
21409     data->leave_on_original = (dlg->leave_on_original == NULL) ? FALSE : GetStatus (dlg->leave_on_original);
21410     data->remove_parsed = (dlg->remove_parsed == NULL) ? FALSE : GetStatus (dlg->remove_parsed);
21411   }
21412   return data;
21413 }
21414 
21415 static ValNodePtr GetRNAFeatureList (SeqEntryPtr sep, FilterSetPtr fsp, RnaTypePtr rtp);
21416 static GetSamplePtr GetRnaExistingTextForList (ValNodePtr rna_list, ValNodePtr requested_field);
21417 
21418 static CharPtr
RNAQualAutopopulate(RnaTypePtr rna_type,ValNodePtr field_list,Uint2 entityID)21419 RNAQualAutopopulate
21420 (RnaTypePtr rna_type,
21421  ValNodePtr field_list,
21422  Uint2      entityID)
21423 {
21424   SeqEntryPtr  sep;
21425   GetSamplePtr gsp;
21426   ValNodePtr   rna_list;
21427   CharPtr      rval = NULL;
21428 
21429   sep = GetTopSeqEntryForEntityID (entityID);
21430   rna_list = GetRNAFeatureList (sep, NULL, rna_type);
21431   gsp = GetRnaExistingTextForList (rna_list, field_list);
21432   if (gsp != NULL && !StringHasNoText (gsp->sample_text))
21433   {
21434     rval = gsp->sample_text;
21435     gsp->sample_text = NULL;
21436   }
21437   GetSampleFree (gsp);
21438   rna_list = ValNodeFree (rna_list);
21439   return rval;
21440 }
21441 
RNAQualChangeNotify(Pointer userdata)21442 static void RNAQualChangeNotify (Pointer userdata)
21443 {
21444   AECRRNAQualDlgPtr  dlg;
21445   ValNodePtr         field_list = NULL;
21446   RnaTypePtr         rna_type;
21447   EditApplyPtr       eap;
21448   CharPtr            ncrna_class;
21449 
21450   dlg = (AECRRNAQualDlgPtr) userdata;
21451   if (dlg == NULL)
21452   {
21453     return;
21454   }
21455 
21456   field_list = DialogToPointer (dlg->field_list);
21457   if (field_list == NULL)
21458   {
21459     Hide (dlg->edit_apply);
21460     Hide (dlg->anticodon);
21461     Hide (dlg->codons);
21462     Hide (dlg->ncrna_class);
21463   }
21464   else if (field_list->data.intvalue == RNAFIELD_CODONS_RECOGNIZED)
21465   {
21466     Show (dlg->codons);
21467     Hide (dlg->edit_apply);
21468     Hide (dlg->anticodon);
21469     Hide (dlg->ncrna_class);
21470   }
21471   else if (field_list->data.intvalue == RNAFIELD_ANTICODON)
21472   {
21473     Show (dlg->anticodon);
21474     Hide (dlg->edit_apply);
21475     Hide (dlg->codons);
21476     Hide (dlg->ncrna_class);
21477   }
21478   else if (field_list->data.intvalue == RNAFIELD_NCRNA_CLASS && dlg->ncrna_class != NULL)
21479   {
21480     Show (dlg->ncrna_class);
21481     Hide (dlg->codons);
21482     Hide (dlg->edit_apply);
21483     Hide (dlg->anticodon);
21484     /* autopopulate */
21485     rna_type = DialogToPointer (dlg->rna_type);
21486     ncrna_class = RNAQualAutopopulate (rna_type, field_list, dlg->entityID);
21487     PointerToDialog (dlg->ncrna_class, ncrna_class);
21488     ncrna_class = MemFree (ncrna_class);
21489   }
21490   else
21491   {
21492     Show (dlg->edit_apply);
21493     Hide (dlg->codons);
21494     Hide (dlg->anticodon);
21495     Hide (dlg->ncrna_class);
21496 
21497     /* autopopulate text fields */
21498     if (dlg->edit_apply != NULL)
21499     {
21500       rna_type = DialogToPointer (dlg->rna_type);
21501       eap = DialogToPointer (dlg->edit_apply);
21502       eap->apply_txt = MemFree (eap->apply_txt);
21503       eap->apply_txt = RNAQualAutopopulate (rna_type, field_list, dlg->entityID);
21504       PointerToDialog (dlg->edit_apply, eap);
21505       EditApplyFree (eap);
21506       rna_type = RnaTypeFree (rna_type);
21507     }
21508   }
21509 
21510   field_list = ValNodeFree (field_list);
21511 
21512   if (dlg->change_notify != NULL)
21513   {
21514     (dlg->change_notify)(dlg->change_userdata);
21515   }
21516 }
21517 
AECRRNAQualMessage(DialoG d,Int2 mssg)21518 static void AECRRNAQualMessage (DialoG d, Int2 mssg)
21519 
21520 {
21521   AECRRNAQualDlgPtr  dlg;
21522 
21523   dlg = (AECRRNAQualDlgPtr) GetObjectExtra (d);
21524   if (dlg != NULL) {
21525     switch (mssg)
21526     {
21527       case VIB_MSG_INIT :
21528         /* reset list */
21529         ResetAECRRNAQualDlg (dlg);
21530         break;
21531       case VIB_MSG_ENTER :
21532         Select (dlg->rna_type);
21533         break;
21534       case AECR_VIB_MSG_SET_DEFAULT :
21535         SendMessageToDialog (dlg->field_list, AECR_VIB_MSG_SET_DEFAULT);
21536         SendMessageToDialog (dlg->rna_type, AECR_VIB_MSG_SET_DEFAULT);
21537         ClearTextAECRRNAQualDlg (dlg);
21538         break;
21539       case AECR_VIB_MSG_CLEAR_TEXT :
21540         ClearTextAECRRNAQualDlg (dlg);
21541         break;
21542       case AECR_VIB_MSG_AUTOPOPULATE:
21543         RNAQualChangeNotify (dlg);
21544         break;
21545       default :
21546         break;
21547     }
21548   }
21549 }
21550 
TestAECRRNAQual(DialoG d)21551 static ValNodePtr TestAECRRNAQual (DialoG d)
21552 {
21553   AECRRNAQualDlgPtr dlg;
21554   ValNodePtr         total_err_list = NULL;
21555   ValNodePtr         field_list;
21556 
21557   dlg = (AECRRNAQualDlgPtr) GetObjectExtra (d);
21558   if (dlg == NULL)
21559   {
21560     return NULL;
21561   }
21562 
21563   total_err_list = TestDialog (dlg->rna_type);
21564 
21565   ValNodeLink (&total_err_list, TestDialog (dlg->field_list));
21566 
21567   field_list = DialogToPointer (dlg->field_list);
21568   if (field_list != NULL) {
21569     if (field_list->data.intvalue == RNAFIELD_NCRNA_CLASS && dlg->ncrna_class != NULL) {
21570       ValNodeLink (&total_err_list, TestDialog (dlg->ncrna_class));
21571     } else if (field_list->data.intvalue != RNAFIELD_CODONS_RECOGNIZED) {
21572       ValNodeLink (&total_err_list, TestDialog (dlg->edit_apply));
21573     }
21574   }
21575 
21576   return total_err_list;
21577 }
21578 
21579 
AECRRNAQualButtonChange(ButtoN b)21580 static void AECRRNAQualButtonChange (ButtoN b)
21581 {
21582   AECRRNAQualDlgPtr dlg;
21583 
21584   dlg = (AECRRNAQualDlgPtr) GetObjectExtra (b);
21585   if (dlg == NULL) return;
21586 
21587   if (dlg->change_notify != NULL)
21588   {
21589     (dlg->change_notify) (dlg->change_userdata);
21590   }
21591 }
21592 
21593 
RNAQualListDialog(GrouP h,Int4 action_choice,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Uint2 entityID)21594 static DialoG RNAQualListDialog
21595 (GrouP                    h,
21596  Int4                     action_choice,
21597  Nlm_ChangeNotifyProc     change_notify,
21598  Pointer                  change_userdata,
21599  Uint2                    entityID)
21600 {
21601   AECRRNAQualDlgPtr dlg;
21602   GrouP              p, g1, g2 = NULL;
21603   SeqEntryPtr        sep;
21604 
21605   dlg = (AECRRNAQualDlgPtr) MemNew (sizeof (AECRRNAQualDlgData));
21606   if (dlg == NULL)
21607   {
21608     return NULL;
21609   }
21610 
21611   p = HiddenGroup (h, -1, 0, NULL);
21612   SetObjectExtra (p, dlg, StdCleanupExtraProc);
21613   SetGroupSpacing (p, 10, 10);
21614 
21615   dlg->dialog = (DialoG) p;
21616   dlg->todialog = AECRRNAQualToDialog;
21617   dlg->fromdialog = DialogToAECRRNAQual;
21618   dlg->dialogmessage = AECRRNAQualMessage;
21619   dlg->testdialog = TestAECRRNAQual;
21620   dlg->change_notify = change_notify;
21621   dlg->change_userdata = change_userdata;
21622   dlg->entityID = entityID;
21623 
21624 
21625   if (action_choice == AECR_CONVERT || action_choice == AECR_SWAP || action_choice == AECR_PARSE)
21626   {
21627     g1 = HiddenGroup (p, 3, 0, NULL);
21628     StaticPrompt (g1, "", 0, dialogTextHeight, systemFont, 'l');
21629     StaticPrompt (g1, "From", 0, dialogTextHeight, systemFont, 'l');
21630     StaticPrompt (g1, "To", 0, dialogTextHeight, systemFont, 'l');
21631     dlg->rna_type = RnaTypeDialog (g1, TRUE, RNAQualChangeNotify, dlg);
21632 
21633     dlg->field_list = RNAFieldSelectionDialog (g1, FALSE,
21634                                           change_notify,
21635                                           change_userdata);
21636     dlg->field_list_to = RNAFieldSelectionDialog (g1, FALSE,
21637                                              change_notify,
21638                                              change_userdata);
21639     if (action_choice == AECR_CONVERT)
21640     {
21641       dlg->leave_on_original = CheckBox (p, "Leave on original", AECRRNAQualButtonChange);
21642       SetObjectExtra (dlg->leave_on_original, dlg, NULL);
21643     }
21644   }
21645   else
21646   {
21647     g1 = HiddenGroup (p, 2, 0, NULL);
21648     StaticPrompt (g1, "", 0, dialogTextHeight, systemFont, 'l');
21649     StaticPrompt (g1, "RNA Field", 0, dialogTextHeight, systemFont, 'l');
21650     dlg->rna_type = RnaTypeDialog (g1, TRUE, RNAQualChangeNotify, dlg);
21651     if (action_choice == AECR_REMOVE)
21652     {
21653       dlg->field_list = RNARemoveFieldSelectionDialog (g1, TRUE,
21654                                             RNAQualChangeNotify, dlg);
21655     }
21656     else
21657     {
21658       dlg->field_list = RNAFieldSelectionDialog (g1, FALSE,
21659                                             RNAQualChangeNotify,
21660                                             dlg);
21661     }
21662   }
21663 
21664   if (action_choice == AECR_APPLY)
21665   {
21666     g2 = HiddenGroup (p, 0, 0, NULL);
21667     dlg->edit_apply = EditApplyDialog (g2, eEditApplyChoice_Apply, "New Text", NULL,
21668                                        change_notify, change_userdata);
21669 
21670     dlg->codons = CreateVisibleStringDialog (g2, 3, -1, 4);
21671 
21672     dlg->ncrna_class = CreatencRNAClassDialog (g2, FALSE, change_notify, change_userdata);
21673 
21674     sep = GetTopSeqEntryForEntityID (entityID);
21675 
21676     dlg->anticodon = NULL;
21677   /*
21678     dlg->anticodon = CreateIntervalEditorDialogEx (g2, NULL, 2, 2, sep, TRUE, FALSE,
21679                                                     TRUE, TRUE, FALSE,
21680                                                     &(dlg->ff),
21681                                                     NULL); */
21682 
21683     AlignObjects (ALIGN_CENTER, (HANDLE) dlg->edit_apply,
21684                                 (HANDLE) dlg->codons,
21685                                 (HANDLE) dlg->ncrna_class,
21686                                 (HANDLE) dlg->anticodon,
21687                                 NULL);
21688   }
21689   else if (action_choice == AECR_EDIT)
21690   {
21691     g2 = HiddenGroup (p, 1, 0, NULL);
21692     dlg->edit_apply = EditApplyDialog (g2, eEditApplyChoice_Edit,
21693                                        "New Text", NULL,
21694                                        change_notify, change_userdata);
21695     dlg->text_portion = NULL;
21696     dlg->remove_parsed = NULL;
21697   }
21698   else if (action_choice == AECR_PARSE)
21699   {
21700     g2 = HiddenGroup (p, -1, 0, NULL);
21701     dlg->edit_apply = NULL;
21702     dlg->text_portion = TextPortionXDialog(p);
21703     dlg->remove_parsed = CheckBox (p, "Remove from parsed field", SimpleAECRButtonChange);
21704     SetObjectExtra (dlg->remove_parsed, dlg, NULL);
21705     AlignObjects (ALIGN_CENTER, (HANDLE) dlg->edit_apply, (HANDLE) dlg->remove_parsed, NULL);
21706   }
21707   else
21708   {
21709     dlg->edit_apply = NULL;
21710     dlg->text_portion = NULL;
21711     dlg->remove_parsed = NULL;
21712   }
21713 
21714 
21715   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2, NULL);
21716 
21717   RNAQualChangeNotify (dlg);
21718 
21719   return (DialoG) p;
21720 }
21721 
21722 
ApplyRNACodonsCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)21723 static void ApplyRNACodonsCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
21724 {
21725   ValNodePtr codons;
21726   RnaRefPtr  rrp;
21727 
21728   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA)
21729   {
21730     return;
21731   }
21732 
21733   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
21734   codons = (ValNodePtr) userdata;
21735   if (rrp != NULL && rrp->type == 3 && rrp->ext.choice == 2)
21736   {
21737     AddCodonListTotRNA (rrp->ext.value.ptrvalue, codons);
21738   }
21739 }
21740 
ApplyRNAAnticodonCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)21741 static void ApplyRNAAnticodonCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
21742 {
21743   RnaRefPtr  rrp;
21744   tRNAPtr    trp;
21745   SeqLocPtr  anticodon_loc, slp;
21746 
21747   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA
21748       || sfp->data.value.ptrvalue == NULL)
21749   {
21750     return;
21751   }
21752 
21753   anticodon_loc = (SeqLocPtr) userdata;
21754 
21755   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
21756 
21757   if (rrp->ext.choice == 2)
21758   {
21759     trp = (tRNAPtr) rrp->ext.value.ptrvalue;
21760     if (trp != NULL)
21761     {
21762       trp->anticodon = SeqLocFree (trp->anticodon);
21763       if (anticodon_loc != NULL)
21764       {
21765         slp = (SeqLocPtr) AsnIoMemCopy (anticodon_loc,
21766                                         (AsnReadFunc) SeqLocAsnRead,
21767                                         (AsnWriteFunc) SeqLocAsnWrite);
21768 
21769         slp = SeqLocReplaceID (slp, SeqLocId (sfp->location));
21770         trp->anticodon = slp;
21771       }
21772     }
21773   }
21774 }
21775 
21776 
CollectRNAFeaturesCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)21777 static void CollectRNAFeaturesCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
21778 {
21779   if (sfp != NULL && sfp->data.choice == SEQFEAT_RNA && userdata != NULL)
21780   {
21781     ValNodeAddPointer ((ValNodePtr PNTR) userdata, OBJ_SEQFEAT, sfp);
21782   }
21783 
21784 }
21785 
21786 
GetRNAFeatureList(SeqEntryPtr sep,FilterSetPtr fsp,RnaTypePtr rtp)21787 static ValNodePtr GetRNAFeatureList (SeqEntryPtr sep, FilterSetPtr fsp, RnaTypePtr rtp)
21788 {
21789   ValNodePtr rna_list = NULL, vnp_rna;
21790   ValNodePtr not_match;
21791   SeqFeatPtr sfp;
21792   Boolean    matches;
21793 
21794   if (sep == NULL) return NULL;
21795 
21796   OperateOnSeqEntryConstrainedObjects (sep, fsp, CollectRNAFeaturesCallback,
21797                                        NULL, SEQFEAT_RNA, 0, 0, &rna_list);
21798 
21799   if (rtp != NULL)
21800   {
21801     for (vnp_rna = rna_list; vnp_rna != NULL; vnp_rna = vnp_rna->next)
21802     {
21803       matches = FALSE;
21804       sfp = vnp_rna->data.ptrvalue;
21805       if (!MatchesRnaType (sfp, rtp))
21806       {
21807         vnp_rna->choice = 0;
21808       }
21809     }
21810 
21811     not_match = ValNodeExtractList (&rna_list, 0);
21812     not_match = ValNodeFree (not_match);
21813   }
21814   return rna_list;
21815 }
21816 
21817 
GetRnaExistingTextForList(ValNodePtr rna_list,ValNodePtr requested_field)21818 static GetSamplePtr GetRnaExistingTextForList (ValNodePtr rna_list, ValNodePtr requested_field)
21819 {
21820   GetSamplePtr gsp;
21821   ValNodePtr   vnp;
21822   SeqFeatPtr   sfp;
21823 
21824   if (rna_list == NULL || requested_field == NULL) return NULL;
21825 
21826   gsp = GetSampleNew ();
21827   gsp->sample_text = NULL;
21828   gsp->fieldstring_func = GetRNAFieldString;
21829   gsp->descrstring_func = NULL;
21830   gsp->free_vn_proc = NULL;
21831   gsp->copy_vn_proc = IntValNodeCopy;
21832   gsp->requested_field = (gsp->copy_vn_proc) (requested_field);
21833   gsp->num_found = 0;
21834   gsp->all_same = TRUE;
21835 
21836   for (vnp = rna_list; vnp != NULL; vnp = vnp->next)
21837   {
21838     sfp = vnp->data.ptrvalue;
21839     GetSampleFeatureCallback (sfp, gsp, NULL);
21840   }
21841   return gsp;
21842 }
21843 
21844 
ApplyToRNAList(ValNodePtr rna_list,AECRRNAQualPtr rp,FilterSetPtr fsp)21845 static Boolean ApplyToRNAList (ValNodePtr rna_list, AECRRNAQualPtr rp, FilterSetPtr fsp)
21846 {
21847   ValNodePtr      vnp_rna;
21848   SeqFeatPtr      sfp;
21849   ApplyValueData  avd;
21850   Boolean         rval = TRUE;
21851   GetSamplePtr    gsp;
21852 
21853   if (rna_list == NULL || rp == NULL || rp->field_list == NULL)
21854   {
21855     return FALSE;
21856   }
21857 
21858   if (rp->field_list->data.intvalue == RNAFIELD_CODONS_RECOGNIZED)
21859   {
21860     for (vnp_rna = rna_list; vnp_rna != NULL; vnp_rna = vnp_rna->next)
21861     {
21862       sfp = vnp_rna->data.ptrvalue;
21863       if (sfp->idx.subtype == FEATDEF_tRNA)
21864       {
21865         ApplyRNACodonsCallback (sfp, rp->codons, fsp);
21866       }
21867     }
21868   }
21869   else if (rp->field_list->data.intvalue == RNAFIELD_ANTICODON)
21870   {
21871     for (vnp_rna = rna_list; vnp_rna != NULL; vnp_rna = vnp_rna->next)
21872     {
21873       sfp = vnp_rna->data.ptrvalue;
21874       if (sfp->idx.subtype == FEATDEF_tRNA)
21875       {
21876         ApplyRNAAnticodonCallback (sfp, rp->anticodon, fsp);
21877       }
21878     }
21879   }
21880   else
21881   {
21882     avd.field_list = rp->field_list;
21883     avd.where_to_replace = EditApplyFindLocation_anywhere;
21884 
21885     /* get handling for existing text */
21886     gsp = GetRnaExistingTextForList (rna_list, rp->field_list);
21887     avd.etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
21888     gsp = GetSampleFree (gsp);
21889 
21890     if (avd.etp != NULL
21891         && avd.etp->existing_text_choice == eExistingTextChoiceCancel)
21892     {
21893       rval = FALSE;
21894     }
21895 
21896     if (rval)
21897     {
21898       AddEditApplyDataToApplyValue (AECR_APPLY, rp->edit_apply, &avd);
21899 
21900       for (vnp_rna = rna_list; vnp_rna != NULL; vnp_rna = vnp_rna->next)
21901       {
21902         sfp = vnp_rna->data.ptrvalue;
21903         SetRNAFieldString (sfp, &avd, fsp);
21904       }
21905       avd.text_to_replace = MemFree (avd.text_to_replace);
21906       avd.new_text = MemFree (avd.new_text);
21907     }
21908     avd.etp = MemFree (avd.etp);
21909   }
21910   return rval;
21911 }
21912 
21913 
21914 static Boolean
RNAQualConvertSwapParseList(ValNodePtr rna_list,AECRRNAQualPtr rp,Int4 action_choice,FilterSetPtr fsp)21915 RNAQualConvertSwapParseList
21916 (ValNodePtr      rna_list,
21917  AECRRNAQualPtr  rp,
21918  Int4            action_choice,
21919  FilterSetPtr    fsp)
21920 {
21921   ConvertFieldData       cfd;
21922   ConversionConflictData ccd;
21923   ValNodePtr             vnp_rna;
21924   ApplyValueData         avd;
21925   Boolean                rval = TRUE;
21926   SeqFeatPtr             sfp;
21927 
21928   if (rna_list == NULL
21929       || rp == NULL
21930       || action_choice < AECR_EDIT
21931       || action_choice > NUM_AECR
21932       || rp->field_list == NULL
21933       || rp->field_list_to == NULL)
21934   {
21935     return FALSE;
21936   }
21937 
21938   avd.where_to_replace = EditApplyFindLocation_anywhere;
21939 
21940   cfd.src_field_list = rp->field_list;
21941   cfd.dst_field_list = rp->field_list_to;
21942   cfd.etp = NULL;
21943   cfd.convert_type = CONVERT_TYPE_MOVE;
21944   cfd.get_str_func = GetRNAFieldString;
21945   cfd.set_str_func = SetRNAFieldString;
21946   cfd.remove_str_func = RemoveRNAField;
21947   cfd.get_d_str_func = NULL;
21948   cfd.set_d_str_func = NULL;
21949   cfd.remove_d_str_func = NULL;
21950   cfd.fsp = fsp;
21951   cfd.strip_name_from_text = FALSE;
21952   cfd.name_field_func = NULL;
21953   cfd.text_portion = rp->text_portion;
21954   cfd.remove_parsed = rp->remove_parsed;
21955 
21956   if (action_choice == AECR_CONVERT)
21957   {
21958     if (rp->leave_on_original)
21959     {
21960       cfd.convert_type = CONVERT_TYPE_COPY;
21961     }
21962     else
21963     {
21964       cfd.convert_type = CONVERT_TYPE_MOVE;
21965     }
21966   }
21967   else if (action_choice == AECR_SWAP)
21968   {
21969     cfd.convert_type = CONVERT_TYPE_SWAP;
21970   }
21971   else if (action_choice == AECR_PARSE)
21972   {
21973     cfd.convert_type = CONVERT_TYPE_PARSE;
21974   }
21975 
21976   if (cfd.convert_type == CONVERT_TYPE_MOVE || cfd.convert_type == CONVERT_TYPE_COPY || cfd.convert_type == CONVERT_TYPE_PARSE)
21977   {
21978     /* get existing text sample */
21979     ccd.cfp = &cfd;
21980     ccd.gsp = GetSampleNew();
21981 
21982     for (vnp_rna = rna_list; vnp_rna != NULL; vnp_rna = vnp_rna->next)
21983     {
21984       sfp = vnp_rna->data.ptrvalue;
21985       GetConversionConflictsFeatureCallback (sfp, &ccd, fsp);
21986     }
21987     cfd.etp = GetExistingTextHandlerInfo (ccd.gsp == NULL ? 0 : ccd.gsp->num_found, FALSE);
21988     ccd.gsp = GetSampleFree (ccd.gsp);
21989     if (cfd.etp != NULL && cfd.etp->existing_text_choice == eExistingTextChoiceCancel)
21990     {
21991       rval = FALSE;
21992     }
21993   }
21994   else
21995   {
21996     cfd.etp = NULL;
21997   }
21998 
21999   if (rval)
22000   {
22001     for (vnp_rna = rna_list; vnp_rna != NULL; vnp_rna = vnp_rna->next)
22002     {
22003       sfp = vnp_rna->data.ptrvalue;
22004       ConvertFeatureFieldCallback (sfp, &cfd, fsp);
22005     }
22006   }
22007 
22008   return rval;
22009 }
22010 
22011 
RNAQualEditRemoveList(ValNodePtr rna_list,AECRRNAQualPtr rp,Int4 action_choice,FilterSetPtr fsp)22012 static Boolean RNAQualEditRemoveList
22013 (ValNodePtr    rna_list,
22014  AECRRNAQualPtr  rp,
22015  Int4          action_choice,
22016  FilterSetPtr  fsp)
22017 {
22018   SeqFeatPtr       sfp;
22019   ValNodePtr       vnp_rna;
22020   ApplyValueData   avd;
22021   Boolean          rval = TRUE;
22022 
22023   if (rna_list == NULL
22024       || rp == NULL
22025       || (action_choice != AECR_EDIT && action_choice != AECR_REMOVE)
22026       || rp->field_list == NULL)
22027   {
22028     return FALSE;
22029   }
22030 
22031   avd.where_to_replace = EditApplyFindLocation_anywhere;
22032   avd.field_list = rp->field_list;
22033   avd.etp = NULL;
22034   AddEditApplyDataToApplyValue (action_choice, rp->edit_apply, &avd);
22035 
22036   for (vnp_rna = rna_list; vnp_rna != NULL; vnp_rna = vnp_rna->next)
22037   {
22038     sfp = vnp_rna->data.ptrvalue;
22039     if (action_choice == AECR_EDIT)
22040     {
22041       SetRNAFieldString (sfp, &avd, fsp);
22042     }
22043     else if (action_choice == AECR_REMOVE)
22044     {
22045       RemoveRNAField (sfp, &avd, fsp);
22046     }
22047   }
22048 
22049   avd.text_to_replace = MemFree (avd.text_to_replace);
22050   avd.new_text = MemFree (avd.new_text);
22051   return TRUE;
22052 }
22053 
22054 
22055 
22056 
AcceptRNAQualApplyEditRemoveConvert(Pointer userdata)22057 static Boolean AcceptRNAQualApplyEditRemoveConvert (Pointer userdata)
22058 {
22059   ApplyEditConvertRemovePtr ap;
22060   AECRRNAQualPtr            rp;
22061   Int4                      action_choice;
22062   Boolean                   rval = TRUE;
22063   FilterSetPtr              fsp;
22064   ValNodePtr                rna_list;
22065   SeqEntryPtr               sep;
22066 
22067   ap = (ApplyEditConvertRemovePtr) userdata;
22068   if (ap == NULL)
22069   {
22070     return FALSE;
22071   }
22072 
22073   WatchCursor ();
22074   Update ();
22075 
22076   if (ap->crippled)
22077   {
22078     action_choice = ap->crippled_action;
22079   }
22080   else
22081   {
22082     action_choice = GetValue (ap->action_popup);
22083   }
22084 
22085   rp = (AECRRNAQualPtr) DialogToPointer (ap->aecr_pages[action_choice - 1]);
22086   if (rp == NULL) return FALSE;
22087 
22088   fsp = (FilterSetPtr) DialogToPointer (ap->constraints);
22089   sep = GetTopSeqEntryForEntityID (ap->input_entityID);
22090   rna_list = GetRNAFeatureList (sep, fsp, rp->rna_type);
22091 
22092   if (action_choice == AECR_APPLY)
22093   {
22094     rval = ApplyToRNAList (rna_list, rp, fsp);
22095   }
22096   else if (action_choice == AECR_CONVERT || action_choice == AECR_SWAP
22097            || action_choice == AECR_PARSE)
22098   {
22099     rval = RNAQualConvertSwapParseList (rna_list, rp, action_choice, fsp);
22100   }
22101   else if (action_choice > AECR_APPLY && action_choice <= NUM_AECR)
22102   {
22103     rval = RNAQualEditRemoveList (rna_list, rp, action_choice, fsp);
22104   }
22105 
22106   if (rval)
22107   {
22108     ObjMgrSetDirtyFlag (ap->input_entityID, TRUE);
22109     ObjMgrSendMsg (OM_MSG_UPDATE, ap->input_entityID, 0, 0);
22110   }
22111   ArrowCursor ();
22112   Update ();
22113 
22114   return rval;
22115 }
22116 
22117 static void
RNAQualApplyEditRemoveConvert(IteM i,Int4 first_action_choice,Boolean crippled)22118 RNAQualApplyEditRemoveConvert
22119 (IteM    i,
22120  Int4    first_action_choice,
22121  Boolean crippled)
22122 {
22123   ApplyEditConvertRemoveCombo (i, first_action_choice, crippled,
22124                                "RNA Qualifiers",
22125                                RNAQualListDialog, TRUE, GetRNAQualSample,
22126                                TRUE, FALSE, TRUE, FALSE, FALSE, "Where feature text",
22127                                AcceptRNAQualApplyEditRemoveConvert, NULL, NULL,
22128                                CheckFeaturesForPresample);
22129 }
22130 
PublicApplyRNAQual(IteM i)22131 extern void PublicApplyRNAQual (IteM i)
22132 {
22133   RNAQualApplyEditRemoveConvert (i, AECR_APPLY, TRUE);
22134 }
22135 
EditRNAQual(IteM i)22136 extern void EditRNAQual (IteM i)
22137 {
22138   RNAQualApplyEditRemoveConvert (i, AECR_EDIT, FALSE);
22139 }
22140 
PublicEditRNAQual(IteM i)22141 extern void PublicEditRNAQual (IteM i)
22142 {
22143   RNAQualApplyEditRemoveConvert (i, AECR_EDIT, TRUE);
22144 }
22145 
ConvertRNAQual(IteM i)22146 extern void ConvertRNAQual (IteM i)
22147 {
22148   RNAQualApplyEditRemoveConvert (i, AECR_CONVERT, FALSE);
22149 }
22150 
SwapRNAQual(IteM i)22151 extern void SwapRNAQual (IteM i)
22152 {
22153   RNAQualApplyEditRemoveConvert (i, AECR_SWAP, FALSE);
22154 }
22155 
RemoveRNAQual(IteM i)22156 extern void RemoveRNAQual (IteM i)
22157 {
22158   RNAQualApplyEditRemoveConvert (i, AECR_REMOVE, FALSE);
22159 }
22160 
22161 
22162 typedef struct removegbqualdlg
22163 {
22164   DIALOG_MESSAGE_BLOCK
22165   DialoG          field_list;
22166   DialoG          subtype_list;
22167   GrouP           list_or_txt_grp;
22168   DialoG          qual_name_constraint;
22169 
22170   /* These are necessary to produce the SimpleAECR structure for output */
22171   FreeValNodeProc free_field_vn_proc;
22172   FreeValNodeProc free_subtype_vn_proc;
22173 
22174   Nlm_ChangeNotifyProc     change_notify;
22175   Pointer                  change_userdata;
22176   Uint2                    entityID;
22177 
22178 } RemoveGBQualDlgData, PNTR RemoveGBQualDlgPtr;
22179 
22180 
22181 typedef struct removegbqual
22182 {
22183   ValNodePtr          field_list;
22184   ValNodePtr          subtype_list;
22185   StringConstraintXPtr scp;
22186   Boolean             use_field_list;
22187 } RemoveGBQualData, PNTR RemoveGBQualPtr;
22188 
RemoveGBQualFree(RemoveGBQualPtr ap)22189 static RemoveGBQualPtr RemoveGBQualFree (RemoveGBQualPtr ap)
22190 {
22191   if (ap != NULL)
22192   {
22193     ap->field_list = ValNodeFree (ap->field_list);
22194     ap->subtype_list = ValNodeFree (ap->subtype_list);
22195     ap->scp = StringConstraintXFree (ap->scp);
22196     ap = MemFree (ap);
22197   }
22198   return ap;
22199 }
22200 
22201 
ClearTextRemoveGBQualDlg(RemoveGBQualDlgPtr dlg)22202 static void ClearTextRemoveGBQualDlg (RemoveGBQualDlgPtr dlg)
22203 {
22204   if (dlg != NULL)
22205   {
22206     PointerToDialog (dlg->qual_name_constraint, NULL);
22207   }
22208 }
22209 
ResetRemoveGBQualDlg(RemoveGBQualDlgPtr dlg)22210 static void ResetRemoveGBQualDlg (RemoveGBQualDlgPtr dlg)
22211 {
22212   if (dlg != NULL)
22213   {
22214     PointerToDialog (dlg->field_list, NULL);
22215     SendMessageToDialog (dlg->field_list, NUM_VIB_MSG + 1);
22216     PointerToDialog (dlg->subtype_list, NULL);
22217     ClearTextRemoveGBQualDlg (dlg);
22218     SetValue (dlg->list_or_txt_grp, 1);
22219     Enable (dlg->subtype_list);
22220     Disable (dlg->qual_name_constraint);
22221   }
22222 }
22223 
22224 
RemoveGBQualToDialog(DialoG d,Pointer userdata)22225 static void RemoveGBQualToDialog (DialoG d, Pointer userdata)
22226 {
22227   RemoveGBQualDlgPtr dlg;
22228   RemoveGBQualPtr    data;
22229 
22230   dlg = (RemoveGBQualDlgPtr) GetObjectExtra (d);
22231   if (dlg == NULL)
22232   {
22233     return;
22234   }
22235 
22236   data = (RemoveGBQualPtr) userdata;
22237   if (data == NULL)
22238   {
22239     PointerToDialog (dlg->field_list, NULL);
22240     PointerToDialog (dlg->subtype_list, NULL);
22241     ClearTextRemoveGBQualDlg (dlg);
22242     SetValue (dlg->list_or_txt_grp, 1);
22243     Enable (dlg->subtype_list);
22244     Disable (dlg->qual_name_constraint);
22245   }
22246   else
22247   {
22248     PointerToDialog (dlg->field_list, data->field_list);
22249     PointerToDialog (dlg->subtype_list, data->subtype_list);
22250     PointerToDialog (dlg->qual_name_constraint, data->scp);
22251     if (data->use_field_list)
22252     {
22253       SetValue (dlg->list_or_txt_grp, 1);
22254       Enable (dlg->subtype_list);
22255       Disable (dlg->qual_name_constraint);
22256     }
22257     else
22258     {
22259       SetValue (dlg->list_or_txt_grp, 2);
22260       Disable (dlg->subtype_list);
22261       Enable (dlg->qual_name_constraint);
22262     }
22263   }
22264 }
22265 
22266 
DialogToRemoveGBQual(DialoG d)22267 static Pointer DialogToRemoveGBQual (DialoG d)
22268 {
22269   RemoveGBQualDlgPtr dlg;
22270   RemoveGBQualPtr    data;
22271 
22272   dlg = (RemoveGBQualDlgPtr) GetObjectExtra (d);
22273   if (dlg == NULL)
22274   {
22275     return NULL;
22276   }
22277 
22278   data = (RemoveGBQualPtr) MemNew (sizeof (RemoveGBQualData));
22279   if (data != NULL)
22280   {
22281     data->field_list = DialogToPointer (dlg->field_list);
22282     data->subtype_list = DialogToPointer (dlg->subtype_list);
22283     data->scp = DialogToPointer (dlg->qual_name_constraint);
22284     if (GetValue (dlg->list_or_txt_grp) == 1)
22285     {
22286       data->use_field_list = TRUE;
22287     }
22288     else
22289     {
22290       data->use_field_list = FALSE;
22291     }
22292   }
22293   return data;
22294 }
22295 
22296 
RemoveGBQualMessage(DialoG d,Int2 mssg)22297 static void RemoveGBQualMessage (DialoG d, Int2 mssg)
22298 
22299 {
22300   RemoveGBQualDlgPtr  dlg;
22301 
22302   dlg = (RemoveGBQualDlgPtr) GetObjectExtra (d);
22303   if (dlg != NULL) {
22304     switch (mssg)
22305     {
22306       case VIB_MSG_INIT :
22307         /* reset list */
22308         ResetRemoveGBQualDlg (dlg);
22309         break;
22310       case VIB_MSG_ENTER :
22311         if (dlg->subtype_list != NULL)
22312         {
22313           Select (dlg->subtype_list);
22314         }
22315         else
22316         {
22317           Select (dlg->field_list);
22318         }
22319         break;
22320       case AECR_VIB_MSG_SET_DEFAULT :
22321         SendMessageToDialog (dlg->field_list, AECR_VIB_MSG_SET_DEFAULT);
22322         SendMessageToDialog (dlg->subtype_list, AECR_VIB_MSG_SET_DEFAULT);
22323         ClearTextRemoveGBQualDlg (dlg);
22324         break;
22325       case AECR_VIB_MSG_CLEAR_TEXT :
22326         ClearTextRemoveGBQualDlg (dlg);
22327         break;
22328       case AECR_VIB_MSG_AUTOPOPULATE:
22329         break;
22330       default :
22331         break;
22332     }
22333   }
22334 }
22335 
TestRemoveGBQual(DialoG d)22336 static ValNodePtr TestRemoveGBQual (DialoG d)
22337 {
22338   RemoveGBQualDlgPtr dlg;
22339   ValNodePtr         err_list = NULL;
22340   ValNodePtr         total_err_list = NULL;
22341 
22342   dlg = (RemoveGBQualDlgPtr) GetObjectExtra (d);
22343   if (dlg == NULL)
22344   {
22345     return NULL;
22346   }
22347 
22348   total_err_list = TestDialog (dlg->subtype_list);
22349 
22350   if (GetValue (dlg->list_or_txt_grp) == 1)
22351   {
22352     err_list = TestDialog (dlg->field_list);
22353     total_err_list = ValNodeAppend (total_err_list, err_list);
22354   }
22355 
22356   return total_err_list;
22357 }
22358 
22359 
GBQualChangeNotify(GrouP b)22360 static void GBQualChangeNotify (GrouP b)
22361 {
22362   RemoveGBQualDlgPtr dlg;
22363 
22364   dlg = (RemoveGBQualDlgPtr) GetObjectExtra (b);
22365   if (dlg == NULL)
22366   {
22367     return;
22368   }
22369 
22370   if (GetValue (dlg->list_or_txt_grp) == 1)
22371   {
22372     Enable (dlg->field_list);
22373     Disable (dlg->qual_name_constraint);
22374   }
22375   else
22376   {
22377     Disable (dlg->field_list);
22378     Enable (dlg->qual_name_constraint);
22379   }
22380 
22381   if (dlg->change_notify != NULL)
22382   {
22383     (dlg->change_notify)(dlg->change_userdata);
22384   }
22385 }
22386 
22387 
GBQualRemoveDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Uint2 entityID)22388 static DialoG GBQualRemoveDialog
22389 (GrouP                    h,
22390  Nlm_ChangeNotifyProc     change_notify,
22391  Pointer                  change_userdata,
22392  Uint2                    entityID)
22393 {
22394   RemoveGBQualDlgPtr dlg;
22395   GrouP              p, g1;
22396   SeqEntryPtr        sep;
22397 
22398   dlg = (RemoveGBQualDlgPtr) MemNew (sizeof (RemoveGBQualDlgData));
22399   if (dlg == NULL)
22400   {
22401     return NULL;
22402   }
22403 
22404   p = HiddenGroup (h, -1, 0, NULL);
22405   SetObjectExtra (p, dlg, StdCleanupExtraProc);
22406   SetGroupSpacing (p, 10, 10);
22407 
22408   dlg->dialog = (DialoG) p;
22409   dlg->todialog = RemoveGBQualToDialog;
22410   dlg->fromdialog = DialogToRemoveGBQual;
22411   dlg->dialogmessage = RemoveGBQualMessage;
22412   dlg->testdialog = TestRemoveGBQual;
22413   dlg->change_notify = change_notify;
22414   dlg->change_userdata = change_userdata;
22415   dlg->entityID = entityID;
22416   sep = GetTopSeqEntryForEntityID(entityID);
22417 
22418   g1 = HiddenGroup (p, 2, 0, NULL);
22419   StaticPrompt (g1, "Feature", 0, dialogTextHeight, systemFont, 'l');
22420   StaticPrompt (g1, "Qualifier", 0, dialogTextHeight, systemFont, 'l');
22421   dlg->subtype_list = FeatureSelectionDialogEx (g1, TRUE, sep,
22422                                                  change_notify,
22423                                                  change_userdata);
22424   dlg->list_or_txt_grp = HiddenGroup (g1, 2, 0, GBQualChangeNotify);
22425   SetObjectExtra (dlg->list_or_txt_grp, dlg, NULL);
22426   RadioButton (dlg->list_or_txt_grp, "Choose from Standard List");
22427   RadioButton (dlg->list_or_txt_grp, "Select Qual Name Constraint");
22428   dlg->field_list = GBQualSelectionDialog (dlg->list_or_txt_grp, FALSE,
22429                                                 change_notify,
22430                                                 change_userdata);
22431   dlg->qual_name_constraint = StringConstraintDialogX (dlg->list_or_txt_grp, "Where qualifier name contains", FALSE);
22432   SetValue (dlg->list_or_txt_grp, 1);
22433   Disable (dlg->qual_name_constraint);
22434 
22435   return (DialoG) p;
22436 }
22437 
22438 
22439 static DialoG
GBQualListDialog(GrouP h,Int4 action_choice,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Uint2 entityID)22440 GBQualListDialog
22441 (GrouP                    h,
22442  Int4                     action_choice,
22443  Nlm_ChangeNotifyProc     change_notify,
22444  Pointer                  change_userdata,
22445  Uint2                    entityID)
22446 {
22447   if (action_choice == AECR_REMOVE)
22448   {
22449     return GBQualRemoveDialog (h, change_notify, change_userdata, entityID);
22450   }
22451   else
22452   {
22453     return SimpleAECRDialog (h, action_choice, change_notify, change_userdata,
22454                              NULL, ValNodeSimpleDataFree,
22455                              GBQualSelectionDialog, FeatureSelectionDialogEx, NULL,
22456                              "Qualifier", "Feature", TRUE, entityID);
22457   }
22458 }
22459 
22460 static GetSamplePtr
GetGBQualExistingText(SeqEntryPtr sep,ValNodePtr feature_type_list,ValNodePtr requested_field,FilterSetPtr fsp)22461 GetGBQualExistingText
22462 (SeqEntryPtr  sep,
22463  ValNodePtr   feature_type_list,
22464  ValNodePtr   requested_field,
22465  FilterSetPtr fsp)
22466 {
22467   ValNodePtr   vnp;
22468   GetSamplePtr gsp;
22469 
22470   if (sep == NULL || feature_type_list == NULL)
22471   {
22472     return NULL;
22473   }
22474 
22475   gsp = (GetSamplePtr) MemNew (sizeof (GetSampleData));
22476   if (gsp == NULL)
22477   {
22478     return NULL;
22479   }
22480   gsp->sample_text = NULL;
22481   gsp->fieldstring_func = GetGBQualString;
22482   gsp->descrstring_func = NULL;
22483   gsp->free_vn_proc = NULL;
22484   gsp->copy_vn_proc = IntValNodeCopy;
22485 
22486   gsp->requested_field = (gsp->copy_vn_proc) (requested_field);
22487   gsp->num_found = 0;
22488   gsp->all_same = TRUE;
22489   for (vnp = feature_type_list; vnp != NULL; vnp = vnp->next)
22490   {
22491     OperateOnSeqEntryConstrainedObjects (sep, fsp, GetSampleFeatureCallback,
22492                                          NULL,
22493                                          0, vnp->choice, 0, gsp);
22494   }
22495   return gsp;
22496 }
22497 
22498 
AcceptGBQualApplyEditRemoveConvert(Pointer userdata)22499 static Boolean AcceptGBQualApplyEditRemoveConvert (Pointer userdata)
22500 {
22501   ApplyEditConvertRemovePtr ap;
22502   SimpleAECRPtr             gp = NULL;
22503   RemoveGBQualPtr           rgp = NULL;
22504   Int4                      action_choice;
22505   SeqEntryPtr               sep;
22506   ApplyValueData            avd;
22507   ConvertFieldData          cfd;
22508   FilterSetPtr              fsp;
22509   GetSamplePtr              gsp = NULL, gsp_new, gsp_sum;
22510   ValNodePtr                vnp, qual_vnp;
22511   Boolean                   rval = TRUE;
22512 
22513   ValNodePtr                field_list = NULL;
22514   ValNodePtr                subtype_list = NULL;
22515   EditApplyPtr              eap = NULL;
22516 
22517 
22518   ap = (ApplyEditConvertRemovePtr) userdata;
22519   if (ap == NULL)
22520   {
22521     return FALSE;
22522   }
22523 
22524   if (ap->crippled)
22525   {
22526     action_choice = ap->crippled_action;
22527   }
22528   else
22529   {
22530     action_choice = GetValue (ap->action_popup);
22531   }
22532   if (action_choice < 1 || action_choice > NUM_AECR)
22533   {
22534     return FALSE;
22535   }
22536 
22537   avd.where_to_replace = EditApplyFindLocation_anywhere;
22538 
22539   if (action_choice == AECR_REMOVE)
22540   {
22541     rgp = (RemoveGBQualPtr) DialogToPointer (ap->aecr_pages[action_choice - 1]);
22542     if (rgp == NULL)
22543     {
22544       return FALSE;
22545     }
22546     field_list = rgp->field_list;
22547     subtype_list = rgp->subtype_list;
22548   }
22549   else
22550   {
22551     gp = (SimpleAECRPtr) DialogToPointer (ap->aecr_pages[action_choice - 1]);
22552     if (gp == NULL)
22553     {
22554       return FALSE;
22555     }
22556     field_list = gp->field_list;
22557     subtype_list = gp->subtype_list;
22558     eap = gp->edit_apply;
22559   }
22560 
22561   WatchCursor ();
22562   Update ();
22563 
22564   sep = GetTopSeqEntryForEntityID (ap->input_entityID);
22565   if (subtype_list == NULL || (action_choice != AECR_REMOVE && field_list == NULL)
22566       || (action_choice == AECR_REMOVE && rgp->use_field_list && field_list == NULL)
22567       || ((action_choice == AECR_CONVERT || action_choice == AECR_SWAP || action_choice == AECR_PARSE)
22568            && gp->field_list_to == NULL))
22569   {
22570     gp = SimpleAECRFree (gp);
22571     rgp = RemoveGBQualFree (rgp);
22572     ArrowCursor ();
22573     Update ();
22574     return FALSE;
22575   }
22576 
22577   fsp = (FilterSetPtr) DialogToPointer (ap->constraints);
22578 
22579   if (action_choice == AECR_CONVERT || action_choice == AECR_SWAP || action_choice == AECR_PARSE)
22580   {
22581     cfd.src_field_list = gp->field_list;
22582     cfd.dst_field_list = gp->field_list_to;
22583     cfd.etp = NULL;
22584     cfd.get_str_func = GetGBQualString;
22585     cfd.set_str_func = SetGBQualString;
22586     cfd.remove_str_func = RemoveGBQualField;
22587     cfd.get_d_str_func = NULL;
22588     cfd.set_d_str_func = NULL;
22589     cfd.remove_d_str_func = NULL;
22590     cfd.fsp = fsp;
22591     cfd.strip_name_from_text = gp->strip_name_from_text;
22592     cfd.remove_parsed = gp->remove_parsed;
22593     cfd.name_field_func = NULL;
22594     cfd.text_portion = gp->text_portion;
22595 
22596     if (action_choice == AECR_CONVERT)
22597     {
22598       if (gp->leave_on_original)
22599       {
22600         cfd.convert_type = CONVERT_TYPE_COPY;
22601       }
22602       else
22603       {
22604         cfd.convert_type = CONVERT_TYPE_MOVE;
22605       }
22606     }
22607     else if (action_choice == AECR_SWAP)
22608     {
22609       cfd.convert_type = CONVERT_TYPE_SWAP;
22610     }
22611     else if (action_choice == AECR_PARSE)
22612     {
22613       cfd.convert_type = CONVERT_TYPE_PARSE;
22614     }
22615 
22616     if (cfd.convert_type == CONVERT_TYPE_MOVE || cfd.convert_type == CONVERT_TYPE_COPY || cfd.convert_type == CONVERT_TYPE_PARSE)
22617     {
22618       /* get existing text data */
22619       gsp_sum = NULL;
22620       for (vnp = gp->subtype_list; vnp != NULL; vnp = vnp->next)
22621       {
22622         gsp = CheckForConversionExistingTextInSeqEntry (sep, &cfd, fsp,
22623                                                         0,
22624                                                         vnp->choice,
22625                                                         0);
22626         gsp_new = GetSampleAdd (gsp_sum, gsp);
22627         gsp = GetSampleFree (gsp);
22628         gsp_sum = GetSampleFree (gsp_sum);
22629         gsp_sum = gsp_new;
22630       }
22631       cfd.etp = GetExistingTextHandlerInfo (gsp_sum == NULL ? 0 : gsp_sum->num_found, FALSE);
22632       gsp_sum = GetSampleFree (gsp_sum);
22633       if (cfd.etp != NULL && cfd.etp->existing_text_choice == eExistingTextChoiceCancel)
22634       {
22635         rval = FALSE;
22636       }
22637     }
22638     else
22639     {
22640       cfd.etp = NULL;
22641     }
22642 
22643     if (rval)
22644     {
22645       for (vnp = gp->subtype_list; vnp != NULL; vnp = vnp->next)
22646       {
22647         OperateOnSeqEntryConstrainedObjects (sep, fsp, ConvertFeatureFieldCallback,
22648                                              NULL, 0, vnp->choice, 0, &cfd);
22649       }
22650     }
22651     cfd.etp = MemFree (cfd.etp);
22652   }
22653   else if (action_choice == AECR_REMOVE && rgp != NULL && ! rgp->use_field_list)
22654   {
22655     for (vnp = subtype_list; vnp != NULL; vnp = vnp->next)
22656     {
22657       OperateOnSeqEntryConstrainedObjects (sep, fsp, RemoveGBQualByNameConstraint,
22658                                            NULL, 0, vnp->choice, 0, rgp->scp);
22659     }
22660   }
22661   else
22662   {
22663     avd.field_list = field_list;
22664 
22665     /* get handling for existing text */
22666     if (action_choice == AECR_APPLY)
22667     {
22668       gsp = GetGBQualExistingText (sep, subtype_list,
22669                                    avd.field_list,
22670                                    fsp);
22671       avd.etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
22672       gsp = GetSampleFree (gsp);
22673 
22674       if (avd.etp != NULL
22675         && avd.etp->existing_text_choice == eExistingTextChoiceCancel)
22676       {
22677         rval = FALSE;
22678       }
22679     }
22680     else
22681     {
22682       avd.etp = NULL;
22683     }
22684 
22685     AddEditApplyDataToApplyValue (action_choice, eap, &avd);
22686 
22687     for (vnp = subtype_list; vnp != NULL; vnp = vnp->next)
22688     {
22689       if (action_choice == AECR_EDIT || action_choice == AECR_APPLY)
22690       {
22691         OperateOnSeqEntryConstrainedObjects (sep, fsp, SetGBQualString,
22692                                              NULL, 0, vnp->choice, 0, &avd);
22693       }
22694       else if (action_choice == AECR_REMOVE)
22695       {
22696         for (qual_vnp = field_list; qual_vnp != NULL; qual_vnp = qual_vnp->next)
22697         {
22698           avd.field_list = qual_vnp;
22699           OperateOnSeqEntryConstrainedObjects (sep, fsp, RemoveGBQualField,
22700                                                NULL, 0, vnp->choice, 0, &avd);
22701         }
22702       }
22703     }
22704 
22705     avd.text_to_replace = MemFree (avd.text_to_replace);
22706     avd.new_text = MemFree (avd.new_text);
22707   }
22708   FilterSetFree (fsp);
22709   gp = SimpleAECRFree (gp);
22710   rgp = RemoveGBQualFree (rgp);
22711 
22712   if (rval)
22713   {
22714     ObjMgrSetDirtyFlag (ap->input_entityID, TRUE);
22715     ObjMgrSendMsg (OM_MSG_UPDATE, ap->input_entityID, 0, 0);
22716   }
22717   ArrowCursor ();
22718   Update ();
22719 
22720   return rval;
22721 }
22722 
22723 
GetGBQualSampleName(ValNodePtr vnp)22724 static CharPtr GetGBQualSampleName (ValNodePtr vnp)
22725 {
22726   CharPtr    label = NULL;
22727   Int2       feature_subtype, gb_field_choice;
22728   ValNodePtr feature_list, f_vnp;
22729   Int4       num_feature_choices;
22730   CharPtr    feature_label = "";
22731 
22732   if (vnp == NULL)
22733   {
22734     return NULL;
22735   }
22736 
22737   feature_list = BuildFeatureDialogList (FALSE, NULL);
22738   num_feature_choices = ValNodeLen (feature_list);
22739 
22740   feature_subtype = (vnp->data.intvalue - 1) / NumEditQualifiers;
22741   gb_field_choice = (vnp->data.intvalue - 1) % NumEditQualifiers;
22742 
22743   for (f_vnp = feature_list; f_vnp != NULL; f_vnp = f_vnp->next)
22744   {
22745     if (f_vnp->choice == feature_subtype)
22746     {
22747       feature_label = f_vnp->data.ptrvalue;
22748     }
22749   }
22750 
22751 
22752   label = (CharPtr) MemNew ((StringLen (feature_label)
22753                             + StringLen (EditQualifierList[gb_field_choice].name)
22754                             + 2) * sizeof (Char));
22755   if (label != NULL)
22756   {
22757     sprintf (label, "%s %s", feature_label,
22758              EditQualifierList[gb_field_choice].name);
22759   }
22760   ValNodeFreeData (feature_list);
22761   return label;
22762 }
22763 
GetGBQualSampleFieldString(SeqFeatPtr sfp,ValNodePtr vnp,FilterSetPtr fsp)22764 static CharPtr GetGBQualSampleFieldString (SeqFeatPtr sfp, ValNodePtr vnp, FilterSetPtr fsp)
22765 {
22766   CharPtr   str = NULL;
22767   Int2      feature_subtype, gb_field_choice;
22768   ValNode   vn;
22769 
22770   if (sfp == NULL || vnp == NULL)
22771   {
22772     return NULL;
22773   }
22774 
22775   feature_subtype = (vnp->data.intvalue - 1) / NumEditQualifiers;
22776   gb_field_choice = (vnp->data.intvalue - 1) % NumEditQualifiers;
22777 
22778   if (feature_subtype != sfp->idx.subtype)
22779   {
22780     return NULL;
22781   }
22782 
22783   vn.next = NULL;
22784   vn.choice = 0;
22785   vn.data.intvalue = gb_field_choice + 1;
22786   str = GetGBQualString (sfp, &vn, NULL);
22787 
22788   return str;
22789 }
22790 
GetGBQualSample(GrouP h,Uint2 entityID)22791 static DialoG GetGBQualSample (GrouP h, Uint2 entityID)
22792 {
22793   DialoG        d;
22794   SetSampleData ssd;
22795   Int4          qual_choice, list_index;
22796   ValNodePtr    feature_list, f_vnp;
22797 
22798   d = SampleDialog (h);
22799   ssd.fieldstring_func = GetGBQualSampleFieldString;
22800   ssd.descrstring_func = NULL;
22801   ssd.entityID = entityID;
22802   ssd.free_vn_proc = NULL;
22803   ssd.copy_vn_proc = IntValNodeCopy;
22804   ssd.match_vn_proc = IntValNodeMatch;
22805   ssd.label_vn_proc = GetGBQualSampleName;
22806   ssd.fsp = NULL;
22807 
22808   /* construct list of Features and GBQualifiers */
22809   ssd.field_list = NULL;
22810 
22811   feature_list = BuildFeatureDialogList (FALSE, NULL);
22812 
22813   for (f_vnp = feature_list; f_vnp != NULL; f_vnp = f_vnp->next)
22814   {
22815     for (qual_choice = 0; qual_choice < NumEditQualifiers; qual_choice++)
22816     {
22817       list_index = f_vnp->choice * NumEditQualifiers
22818                    + qual_choice;
22819       ValNodeAddInt (&ssd.field_list, 0, list_index + 1);
22820     }
22821   }
22822 
22823   PointerToDialog (d, &ssd);
22824 
22825   /* now free up field list (SampleDialog maintains its own copy */
22826   ssd.field_list = ValNodeFree (ssd.field_list);
22827   feature_list = ValNodeFreeData (feature_list);
22828   return d;
22829 }
22830 
22831 static void
GBQualApplyEditRemoveConvert(IteM i,Int4 first_action_choice,Boolean crippled)22832 GBQualApplyEditRemoveConvert
22833 (IteM    i,
22834  Int4    first_action_choice,
22835  Boolean crippled)
22836 {
22837   ApplyEditConvertRemoveCombo (i, first_action_choice, crippled,
22838                                "Import Qualifiers",
22839                                GBQualListDialog, FALSE, GetGBQualSample,
22840                                TRUE, FALSE, TRUE, FALSE, FALSE, "Where feature text",
22841                                AcceptGBQualApplyEditRemoveConvert, NULL, NULL,
22842                                CheckFeaturesForPresample);
22843 }
22844 
ApplyGBQual(IteM i)22845 extern void ApplyGBQual (IteM i)
22846 {
22847   GBQualApplyEditRemoveConvert (i, AECR_APPLY, FALSE);
22848 }
22849 
PublicApplyGBQual(IteM i)22850 extern void PublicApplyGBQual (IteM i)
22851 {
22852   GBQualApplyEditRemoveConvert (i, AECR_APPLY, TRUE);
22853 }
22854 
EditGBQual(IteM i)22855 extern void EditGBQual (IteM i)
22856 {
22857   GBQualApplyEditRemoveConvert (i, AECR_EDIT, FALSE);
22858 }
22859 
PublicEditGBQual(IteM i)22860 extern void PublicEditGBQual (IteM i)
22861 {
22862   GBQualApplyEditRemoveConvert (i, AECR_EDIT, TRUE);
22863 }
22864 
ConvertGBQual(IteM i)22865 extern void ConvertGBQual (IteM i)
22866 {
22867   GBQualApplyEditRemoveConvert (i, AECR_CONVERT, FALSE);
22868 }
22869 
SwapGBQual(IteM i)22870 extern void SwapGBQual (IteM i)
22871 {
22872   GBQualApplyEditRemoveConvert (i, AECR_SWAP, FALSE);
22873 }
22874 
RemoveGBQual(IteM i)22875 extern void RemoveGBQual (IteM i)
22876 {
22877   GBQualApplyEditRemoveConvert (i, AECR_REMOVE, FALSE);
22878 }
22879 
22880 
22881 typedef enum
22882 {
22883   eAllTargetsAllActions_BioSource = 0,
22884   eAllTargetsAllActions_GBQual,
22885   eAllTargetsAllActions_RNAQual,
22886   eAllTargetsAllActions_CDSGeneProtmRNA,
22887   eNumAllTargetsAllActions
22888 } EAllTargetsAllActions;
22889 
22890 typedef struct allactionsalltargetsdlg
22891 {
22892   DIALOG_MESSAGE_BLOCK
22893   DialoG                   tbs; /* folder tab for switching between target types */
22894   Int2                     currentPage;
22895   GrouP                    target_pages [eNumAllTargetsAllActions];
22896   DialoG                   aecr_pages [NUM_AECR * eNumAllTargetsAllActions];
22897   PopuP                    action_popup;
22898 
22899   DialoG                   accept_cancel;
22900   DialoG                   constraints;
22901   ButtoN                   clear_constraints_on_action_change;
22902   Nlm_ChangeAECRActionProc change_action;
22903   Int4                     prev_page;
22904   Boolean                  crippled;
22905   Int4                     crippled_action;
22906   Uint2                    entityID;
22907   Nlm_ChangeNotifyProc     change_notify;
22908   Pointer                  change_userdata;
22909 } AllActionsAllTargetsDlgData, PNTR AllActionsAllTargetsDlgPtr;
22910 
22911 
AllActionsAllTargets(IteM i)22912 extern void AllActionsAllTargets (IteM i)
22913 {
22914 
22915 }
22916 
22917 typedef struct locustagtooldlocustag
22918 {
22919   FORM_MESSAGE_BLOCK
22920   DialoG         constraints;
22921   DialoG         accept_cancel;
22922 
22923   SeqEntryPtr    sep;
22924 } LocusTagToOldLocusTagData, PNTR LocusTagToOldLocusTagPtr;
22925 
LocusTagToOldLocusTagActionClear(Pointer userdata)22926 static void LocusTagToOldLocusTagActionClear (Pointer userdata)
22927 {
22928   LocusTagToOldLocusTagPtr mp;
22929 
22930   mp = (LocusTagToOldLocusTagPtr) userdata;
22931   if (mp == NULL)
22932   {
22933     return;
22934   }
22935   PointerToDialog (mp->constraints, NULL);
22936 }
22937 
LocusTagToOldLocusTagActionClearText(Pointer userdata)22938 static void LocusTagToOldLocusTagActionClearText (Pointer userdata)
22939 {
22940   LocusTagToOldLocusTagPtr mp;
22941   FilterSetPtr             fsp;
22942 
22943   mp = (LocusTagToOldLocusTagPtr) userdata;
22944   if (mp == NULL)
22945   {
22946     return;
22947   }
22948   fsp = (FilterSetPtr) DialogToPointer (mp->constraints);
22949   FilterSetClearText (fsp);
22950   PointerToDialog (mp->constraints, fsp);
22951   FilterSetFree (fsp);
22952 }
22953 
22954 
22955 static void
ConvertGeneLocusTagToOldLocusTagCallback(SeqFeatPtr gene,Pointer userdata,FilterSetPtr fsp)22956 ConvertGeneLocusTagToOldLocusTagCallback
22957 (SeqFeatPtr   gene,
22958  Pointer      userdata,
22959  FilterSetPtr fsp)
22960 {
22961   GeneRefPtr               grp;
22962   CharPtr                  locus_tag;
22963   GBQualPtr                new_qual, prev_qual;
22964   LocusTagToOldLocusTagPtr mp;
22965 
22966   if (gene == NULL || gene->data.choice != SEQFEAT_GENE || userdata == NULL) return;
22967 
22968   mp = (LocusTagToOldLocusTagPtr)userdata;
22969 
22970   grp = (GeneRefPtr) gene->data.value.ptrvalue;
22971   if (grp == NULL || StringHasNoText (grp->locus_tag))
22972   {
22973       return;
22974   }
22975   locus_tag = grp->locus_tag;
22976   grp->locus_tag = NULL;
22977 
22978   new_qual = GBQualNew ();
22979   if (new_qual == NULL) return;
22980   new_qual->qual = StringSave ("old_locus_tag");
22981   new_qual->val = locus_tag;
22982   new_qual->next = NULL;
22983 
22984   if (gene->qual == NULL)
22985   {
22986       gene->qual = new_qual;
22987   }
22988   else
22989   {
22990       for (prev_qual = gene->qual; prev_qual->next != NULL; prev_qual = prev_qual->next)
22991       {
22992       }
22993       prev_qual->next = new_qual;
22994   }
22995 }
22996 
LocusTagToOldLocusTagAction(Pointer userdata)22997 static Boolean LocusTagToOldLocusTagAction (Pointer userdata)
22998 {
22999   LocusTagToOldLocusTagPtr mp;
23000   FilterSetPtr             fsp;
23001 
23002   mp = (LocusTagToOldLocusTagPtr) userdata;
23003   if (mp == NULL)
23004   {
23005     return FALSE;
23006   }
23007 
23008   WatchCursor ();
23009   Update ();
23010 
23011   mp->sep = GetTopSeqEntryForEntityID (mp->input_entityID);
23012   fsp = (FilterSetPtr) DialogToPointer (mp->constraints);
23013   OperateOnSeqEntryConstrainedObjects (mp->sep, fsp, ConvertGeneLocusTagToOldLocusTagCallback,
23014                                        NULL, SEQFEAT_GENE, 0, 0, mp);
23015   ObjMgrSetDirtyFlag (mp->input_entityID, TRUE);
23016   ObjMgrSendMsg (OM_MSG_UPDATE, mp->input_entityID, 0, 0);
23017   ArrowCursor ();
23018   Update ();
23019   return TRUE;
23020 }
23021 
ConvertLocusTagToOldLocusTag(IteM i)23022 extern void ConvertLocusTagToOldLocusTag (IteM i)
23023 {
23024   BaseFormPtr         bfp;
23025   LocusTagToOldLocusTagPtr     mp;
23026   WindoW              w;
23027   GrouP               h;
23028 
23029 #ifdef WIN_MAC
23030   bfp = currentFormDataPtr;
23031 #else
23032   bfp = GetObjectExtra (i);
23033 #endif
23034   if (bfp == NULL) return;
23035 
23036   mp = (LocusTagToOldLocusTagPtr) MemNew (sizeof (LocusTagToOldLocusTagData));
23037   if (mp == NULL) return;
23038 
23039   w = FixedWindow (-50, -33, -10, -10, "Convert Locus Tag to Old Locus Tag", StdCloseWindowProc);
23040   SetObjectExtra (w, mp, StdCleanupExtraProc);
23041   SetObjectExtra (w, mp, NULL);
23042   mp->form = (ForM) w;
23043   mp->input_entityID = bfp->input_entityID;
23044 
23045   h = HiddenGroup (w, -1, 0, NULL);
23046   SetGroupSpacing (h, 10, 10);
23047 
23048   mp->constraints = FilterGroup (h, TRUE, FALSE, TRUE, FALSE, FALSE, "Where feature text");
23049   mp->accept_cancel = AcceptCancelDialog (h, LocusTagToOldLocusTagAction, NULL,
23050                                           LocusTagToOldLocusTagActionClear,
23051                                           LocusTagToOldLocusTagActionClearText,
23052                                           (Pointer)mp, w);
23053   AlignObjects (ALIGN_CENTER, (HANDLE) mp->constraints,
23054                               (HANDLE) mp->accept_cancel,
23055                               NULL);
23056   Show (w);
23057 }
23058 
GetLastLineageFromString(CharPtr lineage)23059 static CharPtr GetLastLineageFromString (CharPtr lineage)
23060 {
23061   CharPtr last_semicolon, lineage_start, penultimate_semicolon;
23062 
23063 
23064   if (StringHasNoText (lineage))
23065   {
23066     return lineage;
23067   }
23068 
23069   last_semicolon = StringRChr (lineage, ';');
23070   if (last_semicolon == NULL)
23071   {
23072     return lineage;
23073   }
23074 
23075   /* skip past semicolon */
23076   lineage_start = last_semicolon + 1;
23077 
23078   /* skip over whitespace */
23079   lineage_start += StringSpn (lineage_start, " \t");
23080 
23081   if (StringICmp (lineage_start, "environmental samples") == 0
23082       && last_semicolon != lineage)
23083   {
23084     *last_semicolon = 0;
23085     penultimate_semicolon = StringRChr (lineage, ';');
23086     if (penultimate_semicolon == NULL)
23087     {
23088       lineage_start = lineage;
23089     }
23090     else
23091     {
23092       lineage_start = penultimate_semicolon + 1;
23093     }
23094     lineage_start += StringSpn (lineage_start, " \t");
23095   }
23096   return lineage_start;
23097 }
23098 
ExportLastLineageCallback(BioseqPtr bsp,Pointer userdata)23099 static void ExportLastLineageCallback (BioseqPtr bsp, Pointer userdata)
23100 {
23101   LogInfoPtr        lip;
23102   SeqFeatPtr        sfp;
23103   SeqMgrFeatContext fcontext;
23104   SeqDescrPtr       sdp;
23105   SeqMgrDescContext dcontext;
23106   SeqIdPtr          sip;
23107   Char              tmp[128];
23108   CharPtr           val_str = NULL;
23109   ValNode           lineage_field;
23110   CharPtr           last_lineage;
23111   Boolean           found_text = FALSE;
23112 
23113   if (bsp == NULL || userdata == NULL || ISA_aa (bsp->mol))
23114   {
23115     return;
23116   }
23117 
23118   lip = (LogInfoPtr) userdata;
23119 
23120   sip = SeqIdFindBest (bsp->id, 0);
23121   SeqIdWrite (sip, tmp, PRINTID_REPORT, sizeof (tmp));
23122 
23123   fprintf (lip->fp, "%s", tmp);
23124 
23125   lineage_field.next = NULL;
23126   lineage_field.choice = 1;
23127   lineage_field.data.ptrvalue = "Lineage";
23128 
23129   sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
23130   while (sdp != NULL)
23131   {
23132     val_str = GetSourceQualDescrString (sdp, &lineage_field, NULL);
23133     last_lineage = GetLastLineageFromString (val_str);
23134     if (last_lineage != NULL)
23135     {
23136       if (found_text)
23137       {
23138         fprintf (lip->fp, ";%s", last_lineage);
23139       }
23140       else
23141       {
23142         fprintf (lip->fp, "\t%s", last_lineage);
23143       }
23144       val_str = MemFree (val_str);
23145       found_text = TRUE;
23146     }
23147     sdp = SeqMgrGetNextDescriptor (bsp, sdp, 0, &dcontext);
23148   }
23149 
23150   sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_BIOSRC, 0, &fcontext);
23151   while (sfp != NULL)
23152   {
23153     val_str = GetSourceQualFeatureString (sfp, &lineage_field, NULL);
23154     last_lineage = GetLastLineageFromString (val_str);
23155     if (last_lineage != NULL)
23156     {
23157       if (found_text)
23158       {
23159         fprintf (lip->fp, ";%s", last_lineage);
23160       }
23161       else
23162       {
23163         fprintf (lip->fp, "\t%s", last_lineage);
23164       }
23165       val_str = MemFree (val_str);
23166       found_text = TRUE;
23167     }
23168     sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_BIOSRC, 0, &fcontext);
23169   }
23170   fprintf (lip->fp, "\n");
23171   lip->data_in_log = TRUE;
23172 }
23173 
ExportLastLineage(IteM i)23174 extern void ExportLastLineage (IteM i)
23175 {
23176   BaseFormPtr         bfp;
23177   SeqEntryPtr         sep;
23178   LogInfoPtr          lip;
23179 
23180 #ifdef WIN_MAC
23181   bfp = currentFormDataPtr;
23182 #else
23183   bfp = GetObjectExtra (i);
23184 #endif
23185   if (bfp == NULL) return;
23186 
23187   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
23188   if (sep == NULL) return;
23189 
23190   lip = OpenLog ("Lineage");
23191   WatchCursor ();
23192   Update ();
23193   VisitBioseqsInSep (sep, lip, ExportLastLineageCallback);
23194   CloseLog (lip);
23195   lip = FreeLog (lip);
23196   ArrowCursor ();
23197   Update ();
23198 }
23199 
23200 typedef struct combinecds
23201 {
23202   FORM_MESSAGE_BLOCK
23203   GrouP               action_choice_grp;
23204   GrouP               new_cds_grp;
23205   ButtoN              cover_sequence_btn;
23206   DialoG              string_constraint_dlg;
23207 
23208   Int2                action_choice;
23209   Boolean             cover_sequence;
23210   StringConstraintXPtr string_constraint;
23211   LogInfoPtr          lip;
23212 
23213   /* for string constraint */
23214   ObjectHasStringData ohsd;
23215   ObjMgrTypePtr       omtp;
23216   AsnIoPtr            aip;
23217 
23218   /* for finding location for master CDS */
23219   Int4                left_end;
23220   Int4                right_end;
23221   Boolean             partial5;
23222   Boolean             partial3;
23223   Uint1               strand;
23224   SeqFeatPtr          first_cds;
23225 
23226   /* for product name for master CDS */
23227   GrouP               prod_name_choice_grp;
23228   TexT                prod_name_txt;
23229 } CombineCDSData, PNTR CombineCDSPtr;
23230 
23231 
GetProteinForCDS(SeqFeatPtr sfp)23232 static SeqFeatPtr GetProteinForCDS (SeqFeatPtr sfp)
23233 {
23234   BioseqPtr protbsp;
23235   SeqMgrFeatContext context;
23236 
23237   if (sfp == NULL
23238       || sfp->data.choice != SEQFEAT_CDREGION
23239       || sfp->product == NULL
23240       || (protbsp = BioseqFind(SeqLocId (sfp->product))) == NULL) {
23241     return NULL;
23242   }
23243   return SeqMgrGetNextFeature (protbsp, NULL, SEQFEAT_PROT, FEATDEF_PROT, &context);
23244 }
23245 
23246 
DoesCDSFieldMatchStringConstraint(SeqFeatPtr sfp,CombineCDSPtr ccp)23247 static Boolean DoesCDSFieldMatchStringConstraint (SeqFeatPtr sfp, CombineCDSPtr ccp)
23248 {
23249   SeqFeatPtr prot;
23250   SeqMgrFeatContext fcontext;
23251 
23252   if (sfp == NULL || ccp == NULL) {
23253     return FALSE;
23254   } else if (ccp->ohsd.scp == NULL) {
23255     return TRUE;
23256   } else if (DoesObjectMatchStringConstraint (ccp->omtp, ccp->aip, sfp, &(ccp->ohsd))) {
23257     return TRUE;
23258   } else if ((prot = GetProteinForCDS(sfp)) != NULL && DoesObjectMatchStringConstraint (ccp->omtp, ccp->aip, prot, &(ccp->ohsd))) {
23259     return TRUE;
23260   }
23261   sfp = SeqMgrGetDesiredFeature (ccp->input_entityID, NULL, 0, 0, sfp, &fcontext);
23262   if (sfp != NULL && DoesStringMatchConstraintX (fcontext.label, ccp->ohsd.scp))
23263   {
23264     return TRUE;
23265   }
23266   prot = SeqMgrGetDesiredFeature (ccp->input_entityID, NULL, 0, 0, prot, &fcontext);
23267   if (prot != NULL && DoesStringMatchConstraintX (fcontext.label, ccp->ohsd.scp))
23268   {
23269     return TRUE;
23270   }
23271   return FALSE;
23272 }
23273 
23274 
GetCombinedCDSLocationCallback(SeqFeatPtr sfp,Pointer userdata)23275 static void GetCombinedCDSLocationCallback (SeqFeatPtr sfp, Pointer userdata)
23276 {
23277   CombineCDSPtr     ccp;
23278   Int4              start, stop;
23279   Boolean           partial5, partial3;
23280   Uint1             strand;
23281 
23282   if (sfp == NULL
23283       || sfp->data.choice != SEQFEAT_CDREGION
23284       || sfp->location == NULL
23285       || userdata == NULL)
23286   {
23287     return;
23288   }
23289 
23290   ccp = (CombineCDSPtr) userdata;
23291 
23292   if (!DoesCDSFieldMatchStringConstraint(sfp, ccp)) {
23293     return;
23294   }
23295 
23296   start = SeqLocStart (sfp->location);
23297   stop = SeqLocStop (sfp->location);
23298   strand = SeqLocStrand (sfp->location);
23299   CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
23300   if (start < ccp->left_end)
23301   {
23302     ccp->first_cds = sfp;
23303     ccp->left_end = start;
23304     if (strand == Seq_strand_minus)
23305     {
23306       ccp->partial3 = partial3;
23307     }
23308     else
23309     {
23310       ccp->partial5 = partial5;
23311     }
23312     ccp->strand = strand;
23313   }
23314 
23315   if (stop > ccp->right_end)
23316   {
23317     ccp->right_end = stop;
23318     if (strand == Seq_strand_minus)
23319     {
23320       ccp->partial5 = partial5;
23321     }
23322     else
23323     {
23324       ccp->partial3 = partial3;
23325     }
23326     ccp->strand = strand;
23327   }
23328 }
23329 
23330 
ApplyProductName(CombineCDSPtr ccp,SeqFeatPtr new_cds)23331 static void ApplyProductName (CombineCDSPtr ccp, SeqFeatPtr new_cds)
23332 {
23333   BioseqPtr         first_prot_bsp, new_prot_bsp;
23334   SeqFeatPtr        first_prot = NULL;
23335   ProtRefPtr        prp;
23336   CharPtr           product_name = NULL;
23337 
23338   if (ccp == NULL || new_cds == NULL)
23339   {
23340     return;
23341   }
23342 
23343   if (GetValue (ccp->prod_name_choice_grp) == 1)
23344   {
23345     first_prot_bsp = BioseqFindFromSeqLoc (ccp->first_cds->product);
23346     if (first_prot_bsp != NULL)
23347     {
23348       first_prot = GetProtFeature (first_prot_bsp);
23349       if (first_prot != NULL)
23350       {
23351         prp = (ProtRefPtr) first_prot->data.value.ptrvalue;
23352         if (prp != NULL && prp->name != NULL
23353             && ! StringHasNoText (prp->name->data.ptrvalue))
23354         {
23355           product_name = StringSave (prp->name->data.ptrvalue);
23356         }
23357       }
23358     }
23359   }
23360   else
23361   {
23362     product_name = SaveStringFromText (ccp->prod_name_txt);
23363     if (StringHasNoText (product_name))
23364     {
23365       product_name = MemFree (product_name);
23366     }
23367   }
23368 
23369   if (product_name != NULL)
23370   {
23371     new_prot_bsp = BioseqFindFromSeqLoc (new_cds->product);
23372     if (new_prot_bsp != NULL)
23373     {
23374       first_prot = GetProtFeature (new_prot_bsp);
23375       if (first_prot != NULL)
23376       {
23377         prp = (ProtRefPtr) first_prot->data.value.ptrvalue;
23378         if (prp != NULL)
23379         {
23380           ValNodeAddPointer (&(prp->name), 0, product_name);
23381           product_name = NULL;
23382         }
23383       }
23384     }
23385   }
23386   product_name = MemFree (product_name);
23387 }
23388 
GetMasterCDSLocation(BioseqPtr bsp,CombineCDSPtr ccp)23389 static SeqLocPtr GetMasterCDSLocation (BioseqPtr bsp, CombineCDSPtr ccp)
23390 {
23391   SeqFeatPtr        sfp;
23392   SeqMgrFeatContext fcontext;
23393   SeqLocPtr         cover_loc;
23394 
23395   if (bsp == NULL || ! ISA_na (bsp->mol) || ccp == NULL)
23396   {
23397     return NULL;
23398   }
23399 
23400   /* create location for master CDS */
23401   ccp->left_end = bsp->length - 1;
23402   ccp->right_end = 0;
23403   ccp->partial5 = FALSE;
23404   ccp->partial3 = FALSE;
23405 
23406   sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &fcontext);
23407   if (sfp == NULL)
23408   {
23409     return NULL;
23410   }
23411   if (ccp->cover_sequence)
23412   {
23413     ccp->left_end = 0;
23414     ccp->right_end = bsp->length - 1;
23415     ccp->partial5 = FALSE;
23416     ccp->partial3 = FALSE;
23417     ccp->first_cds = sfp;
23418   }
23419   else
23420   {
23421     while (sfp != NULL)
23422     {
23423       GetCombinedCDSLocationCallback (sfp, ccp);
23424       sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &fcontext);
23425     }
23426     if (ccp->left_end > ccp->right_end || ccp->first_cds == NULL)
23427     {
23428       return NULL;
23429     }
23430   }
23431 
23432   cover_loc = SeqLocIntNew (ccp->left_end, ccp->right_end, ccp->strand, bsp->id);
23433   SetSeqLocPartial (cover_loc, ccp->partial5, ccp->partial3);
23434 
23435   return cover_loc;
23436 }
23437 
23438 
CreateMasterCodingRegions(BioseqPtr bsp,Pointer userdata)23439 static void CreateMasterCodingRegions (BioseqPtr bsp, Pointer userdata)
23440 {
23441   CombineCDSPtr ccp;
23442   SeqLocPtr     cover_loc;
23443   SeqFeatPtr    cds;
23444 
23445 
23446   if (bsp == NULL || userdata == NULL)
23447   {
23448     return;
23449   }
23450 
23451   ccp = (CombineCDSPtr) userdata;
23452 
23453   cover_loc = GetMasterCDSLocation (bsp,  ccp);
23454   if (cover_loc == NULL)
23455   {
23456     return;
23457   }
23458 
23459   cds = CreateNewFeatureOnBioseq (bsp, SEQFEAT_CDREGION, cover_loc);
23460   cds->partial = (ccp->partial5 | ccp->partial3);
23461 
23462   cds->data.value.ptrvalue = AsnIoMemCopy (ccp->first_cds->data.value.ptrvalue,
23463                                             (AsnReadFunc) CdRegionAsnRead,
23464                                             (AsnWriteFunc) CdRegionAsnWrite);
23465   RetranslateOneCDS (cds, ccp->first_cds->idx.entityID, TRUE, FALSE);
23466 
23467   ApplyProductName (ccp, cds);
23468 }
23469 
23470 
ConvertCDSToMatPeptideNoOverlap(SeqFeatPtr sfp,LogInfoPtr lip)23471 static Boolean ConvertCDSToMatPeptideNoOverlap (SeqFeatPtr sfp, LogInfoPtr lip)
23472 {
23473   SeqMgrFeatContext fcontext;
23474 
23475   if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) {
23476     return FALSE;
23477   }
23478   if (!CreateMatPeptideFromCDS (sfp)) {
23479     SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, sfp->idx.itemID, 0, sfp, &fcontext);
23480     if (lip != NULL && lip->fp != NULL) {
23481       fprintf (lip->fp, "Coding region %s has no product sequence\n", fcontext.label);
23482       lip->data_in_log = TRUE;
23483     } else {
23484       Message (MSG_ERROR, "Coding region %s has no product sequence\n", fcontext.label);
23485     }
23486     return FALSE;
23487   } else {
23488     return TRUE;
23489   }
23490 }
23491 
23492 
ConvertCDSToMatPeptideNoOverlapCallback(BioseqPtr bsp,Pointer userdata)23493 static void ConvertCDSToMatPeptideNoOverlapCallback (BioseqPtr bsp, Pointer userdata)
23494 {
23495   LogInfoPtr lip;
23496   SeqMgrFeatContext fcontext;
23497   SeqFeatPtr sfp;
23498 
23499   if (bsp == NULL || ISA_aa (bsp->mol)) {
23500     return;
23501   }
23502 
23503   lip = (LogInfoPtr) userdata;
23504   for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &fcontext);
23505        sfp != NULL;
23506        sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &fcontext)) {
23507     ConvertCDSToMatPeptideNoOverlap (sfp, lip);
23508   }
23509 }
23510 
23511 
ConvertCDSToMatPeptideOverlap(SeqFeatPtr sfp,SeqFeatPtr top_cds,LogInfoPtr lip)23512 static void ConvertCDSToMatPeptideOverlap (SeqFeatPtr sfp, SeqFeatPtr top_cds, LogInfoPtr lip)
23513 {
23514   SeqMgrFeatContext gene_context;
23515   SeqFeatPtr gene;
23516 
23517   if (sfp == NULL || top_cds == NULL || sfp->data.choice != SEQFEAT_CDREGION || top_cds->data.choice != SEQFEAT_CDREGION) {
23518     return;
23519   }
23520 
23521   if (!ConvertCDSToMatPeptideForOverlappingCDS (sfp, top_cds, TRUE)) {
23522     if (lip != NULL && lip->fp != NULL)
23523     {
23524       fprintf (lip->fp, "Invalid coordinates for mat_peptide conversion\n");
23525       lip->data_in_log = TRUE;
23526     }
23527     else
23528     {
23529       Message (MSG_ERROR, "Invalid coordinates for mat_peptide conversion");
23530     }
23531   } else {
23532     /* Mark gene with same location for deletion */
23533     gene = SeqMgrGetOverlappingGene (sfp->location, &gene_context);
23534     if (gene != NULL && SeqLocCompare (gene->location, sfp->location) == SLC_A_EQ_B)
23535     {
23536       gene->idx.deleteme = 1;
23537     }
23538   }
23539 }
23540 
23541 
ConvertInnerCDSsToMatPeptidesCallback(BioseqPtr bsp,Pointer userdata)23542 static void ConvertInnerCDSsToMatPeptidesCallback (BioseqPtr bsp, Pointer userdata)
23543 {
23544   LogInfoPtr        lip;
23545   SeqFeatPtr        sfp = NULL;
23546   ValNodePtr        top_level_cds_list = NULL;
23547   SeqMgrFeatContext context;
23548   ValNodePtr        vnp;
23549   SeqFeatPtr        top_cds;
23550 
23551   if (bsp == NULL || ! ISA_na (bsp->mol)) return;
23552   lip = (LogInfoPtr) userdata;
23553 
23554   sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &context);
23555   while (sfp != NULL)
23556   {
23557     top_cds = NULL;
23558     for (vnp = top_level_cds_list;
23559          vnp != NULL && top_cds == NULL;
23560          vnp = vnp->next)
23561     {
23562       top_cds = (SeqFeatPtr) vnp->data.ptrvalue;
23563       if (top_cds != NULL)
23564       {
23565         if (SeqLocCompare (top_cds->location, sfp->location) != SLC_B_IN_A)
23566         {
23567           top_cds = NULL;
23568         }
23569       }
23570     }
23571 
23572     if (top_cds == NULL)
23573     {
23574       /* add to list of top level CDSs */
23575       ValNodeAddPointer (&top_level_cds_list, 0, sfp);
23576     }
23577     else
23578     {
23579       ConvertCDSToMatPeptideOverlap (sfp, top_cds, lip);
23580     }
23581     sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &context);
23582   }
23583   ValNodeFree (top_level_cds_list);
23584 }
23585 
23586 
DoCombineCDS(ButtoN b)23587 static void DoCombineCDS (ButtoN b)
23588 {
23589   CombineCDSPtr      ccp;
23590   SeqEntryPtr        sep, old_scope;
23591   ObjMgrPtr          omp;
23592   AsnExpOptPtr       aeop;
23593 
23594   ccp = (CombineCDSPtr) GetObjectExtra (b);
23595   if (ccp == NULL)
23596   {
23597     return;
23598   }
23599 
23600   sep = GetTopSeqEntryForEntityID (ccp->input_entityID);
23601   if (NULL == sep)
23602     return;
23603 
23604   old_scope = SeqEntrySetScope (sep);
23605 
23606   omp = ObjMgrGet ();
23607   if (omp == NULL) return;
23608 
23609   ccp->action_choice = GetValue (ccp->action_choice_grp);
23610   ccp->cover_sequence = GetStatus (ccp->cover_sequence_btn);
23611   ccp->string_constraint = DialogToPointer (ccp->string_constraint_dlg);
23612 
23613   WatchCursor ();
23614   Update ();
23615 
23616   ccp->lip = OpenLog ("Combine CDS Features");
23617 
23618   if (ccp->string_constraint != NULL)
23619   {
23620     ccp->omtp = ObjMgrTypeFind (omp, OBJ_SEQFEAT, NULL, NULL);
23621     ccp->aip = AsnIoNullOpen ();
23622     ccp->ohsd.scp = ccp->string_constraint;
23623     aeop = AsnExpOptNew (ccp->aip, NULL, NULL, AsnWriteConstraintCallBack);
23624     if (aeop != NULL) {
23625       aeop->user_data = (Pointer) &(ccp->ohsd);
23626     }
23627   }
23628   else
23629   {
23630     ccp->omtp = NULL;
23631     ccp->aip = NULL;
23632     ccp->ohsd.scp = NULL;
23633     aeop = NULL;
23634   }
23635 
23636   if (ccp->action_choice == 2) {
23637     VisitBioseqsInSep (sep, ccp, CreateMasterCodingRegions);
23638     SeqMgrIndexFeatures (ccp->input_entityID, NULL);
23639   }
23640 
23641   if (ccp->action_choice == 1 || ccp->action_choice == 2) {
23642     VisitBioseqsInSep (sep, ccp->lip, ConvertInnerCDSsToMatPeptidesCallback);
23643   } else {
23644     VisitBioseqsInSep (sep, ccp->lip, ConvertCDSToMatPeptideNoOverlapCallback);
23645   }
23646 
23647   AsnIoClose (ccp->aip);
23648   SeqEntrySetScope (old_scope);
23649 
23650   CloseLog (ccp->lip);
23651   FreeLog (ccp->lip);
23652   ccp->string_constraint = StringConstraintXFree (ccp->string_constraint);
23653   Remove (ccp->form);
23654   DeleteMarkedObjects (ccp->input_entityID, 0, NULL);
23655   ObjMgrSetDirtyFlag (ccp->input_entityID, TRUE);
23656   ObjMgrSendMsg (OM_MSG_UPDATE, ccp->input_entityID, 0, 0);
23657   ArrowCursor ();
23658   Update ();
23659 }
23660 
EnableNewCDSControls(GrouP g)23661 static void EnableNewCDSControls (GrouP g)
23662 {
23663   CombineCDSPtr ccp;
23664 
23665   ccp = (CombineCDSPtr) GetObjectExtra (g);
23666   if (ccp == NULL) return;
23667 
23668   if (GetValue (ccp->action_choice_grp) == 2)
23669   {
23670     Enable (ccp->new_cds_grp);
23671   }
23672   else
23673   {
23674     Disable (ccp->new_cds_grp);
23675   }
23676 }
23677 
EnableProdName(GrouP g)23678 static void EnableProdName (GrouP g)
23679 {
23680   CombineCDSPtr ccp;
23681 
23682   ccp = (CombineCDSPtr) GetObjectExtra (g);
23683   if (ccp == NULL) return;
23684 
23685   if (GetValue (ccp->prod_name_choice_grp) == 1)
23686   {
23687     Disable (ccp->prod_name_txt);
23688   }
23689   else
23690   {
23691     Enable (ccp->prod_name_txt);
23692   }
23693 }
23694 
CombineMultipleCDS(IteM i)23695 extern void CombineMultipleCDS (IteM i)
23696 {
23697   BaseFormPtr   bfp;
23698   CombineCDSPtr ccp;
23699   WindoW        w;
23700   GrouP         h, c;
23701   ButtoN        b;
23702 
23703 #ifdef WIN_MAC
23704   bfp = currentFormDataPtr;
23705 #else
23706   bfp = GetObjectExtra (i);
23707 #endif
23708   if (bfp == NULL) return;
23709 
23710   ccp = (CombineCDSPtr) MemNew (sizeof (CombineCDSData));
23711   if (ccp == NULL) return;
23712 
23713   w = FixedWindow (-50, -33, -10, -10, "Convert CDS to Mat-peptide", StdCloseWindowProc);
23714   SetObjectExtra (w, ccp, StdCleanupExtraProc);
23715   ccp->form = (ForM) w;
23716   ccp->input_entityID = bfp->input_entityID;
23717 
23718   h = HiddenGroup (w, -1, 0, NULL);
23719   SetGroupSpacing (h, 10, 10);
23720 
23721   ccp->action_choice_grp = HiddenGroup (h, 0, 3, EnableNewCDSControls);
23722   RadioButton (ccp->action_choice_grp, "Convert inner CDSs to mat_peptides");
23723   RadioButton (ccp->action_choice_grp, "Merge multiple CDSs into one CDS and convert inner CDSs to mat_peptides");
23724   RadioButton (ccp->action_choice_grp, "Create mat-peptide from protein on each CDS");
23725   SetValue (ccp->action_choice_grp, 1);
23726   SetObjectExtra (ccp->action_choice_grp, ccp, NULL);
23727 
23728   ccp->new_cds_grp = HiddenGroup (h, -1, 0, NULL);
23729   ccp->cover_sequence_btn = CheckBox (ccp->new_cds_grp, "New CDS should cover entire sequence", NULL);
23730   SetStatus (ccp->cover_sequence_btn, FALSE);
23731 
23732   ccp->prod_name_choice_grp = HiddenGroup (ccp->new_cds_grp, 0, 2, EnableProdName);
23733   SetObjectExtra (ccp->prod_name_choice_grp, ccp, NULL);
23734   RadioButton (ccp->prod_name_choice_grp, "Use product name from first CDS");
23735   RadioButton (ccp->prod_name_choice_grp, "Use this product name:");
23736   StaticPrompt (ccp->prod_name_choice_grp, "", 0, 0, programFont, 'l');
23737   ccp->prod_name_txt = DialogText (ccp->prod_name_choice_grp, " ", 10, NULL);
23738   SetValue (ccp->prod_name_choice_grp, 1);
23739   Disable (ccp->prod_name_txt);
23740 
23741   ccp->string_constraint_dlg = StringConstraintDialogX (ccp->new_cds_grp, "Where CDS field", TRUE);
23742   Disable (ccp->new_cds_grp);
23743 
23744   AlignObjects (ALIGN_CENTER, (HANDLE) ccp->cover_sequence_btn,
23745                               (HANDLE) ccp->prod_name_choice_grp,
23746                               (HANDLE) ccp->string_constraint_dlg,
23747                               NULL);
23748 
23749   c = HiddenGroup (h, 2, 0, NULL);
23750   b = PushButton (c, "Accept", DoCombineCDS);
23751   SetObjectExtra (b, ccp, NULL);
23752   b = PushButton (c, "Cancel", StdCancelButtonProc);
23753 
23754   AlignObjects (ALIGN_CENTER, (HANDLE) ccp->action_choice_grp,
23755                               (HANDLE) ccp->new_cds_grp,
23756                               (HANDLE) c,
23757                               NULL);
23758   RealizeWindow (w);
23759   Show (w);
23760   Select (w);
23761   Update ();
23762 }
23763 
23764 
MoveToProteinSequenceCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)23765 static void MoveToProteinSequenceCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
23766 {
23767   SeqLocPtr         prot_loc;
23768   SeqFeatPtr        overlapping_cds, new_sfp;
23769   SeqMgrFeatContext cds_context, fcontext;
23770   Int4              offset;
23771   CdRegionPtr       crp;
23772   BioseqPtr         prot_bsp;
23773   LogInfoPtr        lip;
23774 
23775   if (sfp == NULL) {
23776     return;
23777   }
23778 
23779   lip = (LogInfoPtr) userdata;
23780 
23781   overlapping_cds = SeqMgrGetOverlappingCDS(sfp->location, &cds_context);
23782   if (overlapping_cds == NULL) {
23783     SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, sfp->idx.itemID, 0, sfp, &fcontext);
23784     if (lip != NULL && lip->fp != NULL)
23785     {
23786       fprintf (lip->fp, "No overlapping coding region for %s\n", fcontext.label);
23787       lip->data_in_log = TRUE;
23788     }
23789     else
23790     {
23791       Message (MSG_ERROR, "No overlapping coding region for %s\n", fcontext.label);
23792     }
23793     return;
23794   }
23795 
23796   prot_bsp = BioseqFindFromSeqLoc(overlapping_cds->product);
23797   if (prot_bsp == NULL) {
23798     if (lip != NULL && lip->fp != NULL)
23799     {
23800       fprintf (lip->fp, "No protein product for %s\n", cds_context.label);
23801       lip->data_in_log = TRUE;
23802     }
23803     else
23804     {
23805       Message (MSG_ERROR, "No protein product for %s\n", cds_context.label);
23806     }
23807     return;
23808   }
23809 
23810   offset = cds_context.left;
23811   crp = (CdRegionPtr) overlapping_cds->data.value.ptrvalue;
23812   if (crp != NULL) {
23813     if (crp->frame == 2)
23814     {
23815       offset += 1;
23816     }
23817     else if (crp->frame == 3)
23818     {
23819       offset += 2;
23820     }
23821   }
23822 
23823   prot_loc = BuildProtLoc (overlapping_cds, sfp->location, NULL);
23824   if (prot_loc == NULL)
23825   {
23826     SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, sfp->idx.itemID, 0, sfp, &fcontext);
23827     if (lip != NULL && lip->fp != NULL)
23828     {
23829       fprintf (lip->fp, "Unable to translate coordinates for %s\n", fcontext.label);
23830       lip->data_in_log = TRUE;
23831     }
23832     else
23833     {
23834       Message (MSG_ERROR, "Unable to translate coordinates for %s\n", fcontext.label);
23835     }
23836   }
23837   else
23838   {
23839     new_sfp = CreateNewFeatureOnBioseq (prot_bsp, sfp->data.choice, prot_loc);
23840     if (new_sfp != NULL)
23841     {
23842       new_sfp->data.value.ptrvalue = sfp->data.value.ptrvalue;
23843       sfp->data.value.ptrvalue = NULL;
23844       sfp->idx.deleteme = TRUE;
23845     }
23846   }
23847 
23848 }
23849 
23850 
23851 typedef struct maptoprotein {
23852   FORM_MESSAGE_BLOCK
23853   DialoG feature_selection;
23854   DialoG constraints;
23855 } MapToProteinData, PNTR MapToProteinPtr;
23856 
23857 
MapToProteinSequence(ButtoN b)23858 static void MapToProteinSequence(ButtoN b)
23859 {
23860   SeqEntryPtr     sep;
23861   MapToProteinPtr mtpp;
23862   FilterSetPtr    fsp;
23863   LogInfoPtr      lip;
23864   ValNodePtr      feature_type_list, vnp;
23865   Uint1           feat_def_choice;
23866 
23867   mtpp = (MapToProteinPtr) GetObjectExtra (b);
23868   if (mtpp == NULL) {
23869     return;
23870   }
23871 
23872   feature_type_list = (ValNodePtr) DialogToPointer (mtpp->feature_selection);
23873   if (feature_type_list != NULL)
23874   {
23875     sep = GetTopSeqEntryForEntityID (mtpp->input_entityID);
23876     fsp = DialogToPointer (mtpp->constraints);
23877     lip = OpenLog ("Map to Protein Sequence");
23878 
23879     for (vnp = feature_type_list; vnp != NULL; vnp = vnp->next)
23880     {
23881       feat_def_choice = vnp->choice;
23882       if (feat_def_choice == 255)
23883       {
23884         feat_def_choice = 0;
23885       }
23886       OperateOnSeqEntryConstrainedObjects (sep, fsp, MoveToProteinSequenceCallback,
23887                                            NULL, 0, feat_def_choice, 0, lip);
23888     }
23889     fsp = FilterSetFree (fsp);
23890     CloseLog (lip);
23891     lip = FreeLog (lip);
23892     DeleteMarkedObjects (mtpp->input_entityID, 0, NULL);
23893     ObjMgrSetDirtyFlag (mtpp->input_entityID, TRUE);
23894     ObjMgrSendMsg (OM_MSG_UPDATE, mtpp->input_entityID, 0, 0);
23895     Update ();
23896     Remove (mtpp->form);
23897     ValNodeFree (feature_type_list);
23898   }
23899 }
23900 
23901 
MapFeaturesToProteinSequence(IteM i)23902 extern void MapFeaturesToProteinSequence(IteM i)
23903 {
23904   ButtoN             b;
23905   BaseFormPtr        bfp;
23906   GrouP              c;
23907   GrouP              g;
23908   WindoW             w;
23909   MapToProteinPtr    mtpp;
23910   PrompT             p;
23911   SeqEntryPtr        sep;
23912 
23913 #ifdef WIN_MAC
23914   bfp = currentFormDataPtr;
23915 #else
23916   bfp = GetObjectExtra (i);
23917 #endif
23918   if (bfp == NULL) return;
23919 
23920   mtpp = (MapToProteinPtr) MemNew (sizeof (MapToProteinData));
23921   if (mtpp == NULL) return;
23922   mtpp->input_entityID = bfp->input_entityID;
23923   sep = GetTopSeqEntryForEntityID(bfp->input_entityID);
23924   w = MovableModalWindow (-50, -33, -10, -10,
23925                           "Map to Protein Sequence",
23926                           StdCloseWindowProc);
23927   SetObjectExtra (w, mtpp, StdCleanupFormProc);
23928   mtpp->form = (ForM) w;
23929 
23930   g = HiddenGroup (w, -1, 0, NULL);
23931   p = StaticPrompt (g, "Move features to protein of type", 0, dialogTextHeight, systemFont, 'l');
23932 
23933   mtpp->feature_selection = FeatureSelectionDialogEx (g, TRUE, sep, NULL, NULL);
23934   mtpp->constraints = FilterGroup (g, TRUE, FALSE, FALSE, FALSE, FALSE, "Where feature text");
23935   AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) mtpp->feature_selection, (HANDLE) mtpp->constraints, NULL);
23936 
23937   c = HiddenGroup (w, 2, 0, NULL);
23938   b = DefaultButton (c, "Accept", MapToProteinSequence);
23939   SetObjectExtra (b, mtpp, NULL);
23940   PushButton (c, "Cancel", StdCancelButtonProc);
23941   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
23942   RealizeWindow (w);
23943   Show (w);
23944   Select (w);
23945   Update ();
23946 }
23947 
23948 
23949 typedef struct uniquevaluecollection {
23950   ValNodePtr               requested_field;
23951   GetFeatureFieldString    fieldstring_func;
23952   GetDescriptorFieldString descrstring_func;
23953   FreeValNodeProc          free_vn_proc;
23954   CopyValNodeDataProc      copy_vn_proc;
23955   ValNodePtr               value_lists;
23956 } UniqueValueCollectionData, PNTR UniqueValueCollectionPtr;
23957 
23958 
FindExistingCategory(CharPtr description,ValNodePtr category_list)23959 static ClickableItemPtr FindExistingCategory (CharPtr description, ValNodePtr category_list)
23960 {
23961   ClickableItemPtr cip;
23962 
23963   while (category_list != NULL) {
23964     cip = (ClickableItemPtr) category_list->data.ptrvalue;
23965     if (cip != NULL &&
23966         (StringCmp (description, cip->description) == 0
23967          || (StringHasNoText (description) && StringHasNoText (cip->description)))) {
23968       return cip;
23969     }
23970     category_list = category_list->next;
23971   }
23972   return NULL;
23973 }
23974 
23975 
DataInValNodeList(ValNodePtr list,Uint1 choice,Pointer ptrvalue)23976 static ValNodePtr DataInValNodeList (ValNodePtr list, Uint1 choice, Pointer ptrvalue)
23977 {
23978   while (list != NULL) {
23979     if (choice == list->choice && ptrvalue == list->data.ptrvalue) {
23980       return list;
23981     }
23982     list = list->next;
23983   }
23984   return NULL;
23985 }
23986 
23987 
CombineClickableItemLists(ValNodePtr PNTR list1,ValNodePtr list2)23988 static void CombineClickableItemLists (ValNodePtr PNTR list1, ValNodePtr list2)
23989 {
23990   ValNodePtr add_vnp, prev_vnp = NULL, next_vnp;
23991 
23992   if (*list1 == NULL) {
23993     *list1 = list2;
23994     return;
23995   } else if (list2 == NULL) {
23996     return;
23997   }
23998 
23999   add_vnp = list2;
24000   while (add_vnp != NULL) {
24001     next_vnp = add_vnp->next;
24002     if (DataInValNodeList (*list1, add_vnp->choice, add_vnp->data.ptrvalue)) {
24003       if (prev_vnp == NULL) {
24004         list2 = next_vnp;
24005       } else {
24006         prev_vnp->next = next_vnp;
24007       }
24008       add_vnp->next = NULL;
24009       ValNodeFree (add_vnp);
24010     } else {
24011       prev_vnp = add_vnp;
24012     }
24013     add_vnp = next_vnp;
24014   }
24015   ValNodeLink (list1, list2);
24016 }
24017 
24018 
CombineClickableLists(ValNodePtr PNTR list1,ValNodePtr list2)24019 static void CombineClickableLists (ValNodePtr PNTR list1, ValNodePtr list2)
24020 {
24021   ClickableItemPtr cip1, cip2;
24022   ValNodePtr vnp;
24023   for (vnp = list2; vnp != NULL; vnp = vnp->next) {
24024     cip2 = vnp->data.ptrvalue;
24025     if (cip2 != NULL) {
24026       cip1 = FindExistingCategory (cip2->description, *list1);
24027       if (cip1 == NULL) {
24028         ValNodeAddPointer (list1, 0, cip2);
24029         vnp->data.ptrvalue = NULL;
24030       } else {
24031         CombineClickableItemLists (&(cip1->item_list), cip2->item_list);
24032         cip2->item_list = NULL;
24033       }
24034     }
24035   }
24036   list2 = FreeClickableList (list2);
24037 }
24038 
24039 
GetUniqueValuesFeatureCallback(SeqFeatPtr sfp,Pointer userdata,FilterSetPtr fsp)24040 static void GetUniqueValuesFeatureCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
24041 {
24042   UniqueValueCollectionPtr uvcp;
24043   CharPtr      str;
24044   ValNodePtr   check_vnp;
24045   ClickableItemPtr cip;
24046 
24047   if (sfp == NULL || userdata == NULL)
24048   {
24049     return;
24050   }
24051 
24052   uvcp = (UniqueValueCollectionPtr) userdata;
24053   if (uvcp->fieldstring_func == NULL)
24054   {
24055     return;
24056   }
24057 
24058   str = uvcp->fieldstring_func (sfp, uvcp->requested_field, NULL);
24059   if (str == NULL) {
24060     return;
24061   }
24062   cip = FindExistingCategory (str, uvcp->value_lists);
24063   if (cip == NULL) {
24064     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
24065     MemSet (cip, 0, sizeof (ClickableItemData));
24066     cip->description = str;
24067     ValNodeAddPointer (&cip->item_list, OBJ_SEQFEAT, sfp);
24068     ValNodeAddPointer (&(uvcp->value_lists), 0, cip);
24069   } else {
24070     str = MemFree (str);
24071     /* make sure feature isn't already in the list */
24072     for (check_vnp = cip->item_list; check_vnp != NULL; check_vnp = check_vnp->next) {
24073       if (check_vnp->choice == OBJ_SEQFEAT && sfp == check_vnp->data.ptrvalue) break;
24074     }
24075     if (check_vnp == NULL) {
24076       ValNodeAddPointer (&cip->item_list, OBJ_SEQFEAT, sfp);
24077     }
24078   }
24079 }
24080 
GetUniqueValuesDescriptorCallback(SeqDescrPtr sdp,Pointer userdata,FilterSetPtr fsp)24081 static void GetUniqueValuesDescriptorCallback (SeqDescrPtr sdp, Pointer userdata, FilterSetPtr fsp)
24082 {
24083   UniqueValueCollectionPtr uvcp;
24084   ClickableItemPtr         cip;
24085   CharPtr      str;
24086   ValNodePtr   check_vnp;
24087 
24088   if (sdp == NULL || userdata == NULL)
24089   {
24090     return;
24091   }
24092 
24093   uvcp = (UniqueValueCollectionPtr) userdata;
24094   if (uvcp->descrstring_func == NULL)
24095   {
24096     return;
24097   }
24098 
24099   str = uvcp->descrstring_func (sdp, uvcp->requested_field, NULL);
24100 
24101   cip = FindExistingCategory (str, uvcp->value_lists);
24102 
24103   if (cip == NULL) {
24104     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
24105     MemSet (cip, 0, sizeof (ClickableItemData));
24106     cip->description = str;
24107     ValNodeAddPointer (&cip->item_list, OBJ_SEQDESC, sdp);
24108     ValNodeAddPointer (&(uvcp->value_lists), 0, cip);
24109   } else {
24110     str = MemFree (str);
24111     /* make sure feature isn't already in the list */
24112     for (check_vnp = cip->item_list; check_vnp != NULL; check_vnp = check_vnp->next) {
24113       if (check_vnp->choice == OBJ_SEQDESC && sdp == check_vnp->data.ptrvalue) break;
24114     }
24115     if (check_vnp == NULL) {
24116       ValNodeAddPointer (&cip->item_list, OBJ_SEQDESC, sdp);
24117     }
24118   }
24119 }
24120 
24121 
CheckForUniqueValuesInSeqEntry(SeqEntryPtr sep,ValNodePtr requested_field,GetFeatureFieldString fieldstring_func,GetDescriptorFieldString descrstring_func,FreeValNodeProc free_vn_proc,CopyValNodeDataProc copy_vn_proc,FilterSetPtr fsp,Uint1 seqfeat_choice,Uint1 featdef_choice,Uint1 descr_choice)24122 static ValNodePtr CheckForUniqueValuesInSeqEntry
24123 (SeqEntryPtr              sep,
24124  ValNodePtr               requested_field,
24125  GetFeatureFieldString    fieldstring_func,
24126  GetDescriptorFieldString descrstring_func,
24127  FreeValNodeProc          free_vn_proc,
24128  CopyValNodeDataProc      copy_vn_proc,
24129  FilterSetPtr             fsp,
24130  Uint1                    seqfeat_choice,
24131  Uint1                    featdef_choice,
24132  Uint1                    descr_choice)
24133 {
24134   UniqueValueCollectionData uvcd;
24135 
24136   uvcd.fieldstring_func = fieldstring_func;
24137   uvcd.descrstring_func = descrstring_func;
24138   uvcd.free_vn_proc = free_vn_proc;
24139   uvcd.copy_vn_proc = copy_vn_proc;
24140   uvcd.requested_field = (copy_vn_proc) (requested_field);
24141   uvcd.value_lists = NULL;
24142   OperateOnSeqEntryConstrainedObjects (sep, fsp, GetUniqueValuesFeatureCallback,
24143                                          GetUniqueValuesDescriptorCallback,
24144                                          seqfeat_choice, featdef_choice,
24145                                          descr_choice, &uvcd);
24146   return uvcd.value_lists;
24147 }
24148 
24149 
24150 static ValNodePtr
GetUniqueValueListForSeqEntry(SeqEntryPtr sep,Uint2 entityID,ParseFieldPtr dst_field_data,FilterSetPtr fsp)24151 GetUniqueValueListForSeqEntry
24152 (SeqEntryPtr   sep,
24153  Uint2         entityID,
24154  ParseFieldPtr dst_field_data,
24155  FilterSetPtr  fsp)
24156 {
24157   ValNodePtr   unique_values = NULL;
24158   ValNodePtr   requested_field = NULL, vnp;
24159   SeqEntryPtr  orig_sep;
24160 
24161   if (sep == NULL || dst_field_data == NULL)
24162   {
24163     return NULL;
24164   }
24165 
24166   switch (dst_field_data->parse_field_type)
24167   {
24168     case PARSE_FIELD_SOURCE_QUAL :
24169       unique_values = CheckForUniqueValuesInSeqEntry (sep,
24170                                             dst_field_data->feature_field,
24171                                             GetSourceQualFeatureString,
24172                                             GetSourceQualDescrString,
24173                                             ValNodeSimpleDataFree,
24174                                             SourceQualValNodeDataCopy,
24175                                             fsp,
24176                                             SEQFEAT_BIOSRC, 0,
24177                                             Seq_descr_source);
24178       break;
24179     case PARSE_FIELD_DEFLINE:
24180       requested_field = ValNodeNew (NULL);
24181       requested_field->data.intvalue = Seq_descr_title;
24182       unique_values = CheckForUniqueValuesInSeqEntry (sep, requested_field,
24183                                             NULL,
24184                                             GetStringFromStringDescriptor,
24185                                             NULL, IntValNodeCopy,
24186                                             fsp, 0, 0, Seq_descr_title);
24187       requested_field = ValNodeFree (requested_field);
24188       break;
24189     case PARSE_FIELD_BIOSRC_STRING:
24190       unique_values = CheckForUniqueValuesInSeqEntry (sep,
24191                                             dst_field_data->feature_field,
24192                                             GetSourceFeatureString,
24193                                             GetSourceDescriptorString,
24194                                             NULL, IntValNodeCopy,
24195                                             fsp,
24196                                             SEQFEAT_BIOSRC, 0,
24197                                             Seq_descr_source);
24198       break;
24199     case PARSE_FIELD_DBXREF:
24200       unique_values = CheckForUniqueValuesInSeqEntry (sep, dst_field_data->feature_field,
24201                                             GetBioSourceFeatureDbxrefString,
24202                                             GetBioSourceDescriptorDbxrefString,
24203                                             ValNodeSimpleDataFree,
24204                                             ValNodeStringCopy,
24205                                             fsp,
24206                                             SEQFEAT_BIOSRC, 0, Seq_descr_source);
24207       break;
24208     case PARSE_FIELD_GENE_FIELD:
24209       unique_values = CheckForUniqueValuesInSeqEntry (sep,
24210                                             dst_field_data->feature_field,
24211                                             GetGeneFieldString,
24212                                             NULL,
24213                                             NULL, IntValNodeCopy,
24214                                             fsp,
24215                                             SEQFEAT_GENE, 0, 0);
24216       break;
24217     case PARSE_FIELD_RNA_FIELD:
24218       unique_values = CheckForUniqueValuesInSeqEntry (sep,
24219                                             dst_field_data->feature_field,
24220                                             GetRNAFieldString,
24221                                             NULL,
24222                                             NULL, IntValNodeCopy,
24223                                             fsp,
24224                                             SEQFEAT_RNA,
24225                                             dst_field_data->feature_subtype == NULL ? 0 : dst_field_data->feature_subtype->data.intvalue,
24226                                             0);
24227       break;
24228     case PARSE_FIELD_CDS_COMMENT:
24229       unique_values = CheckForUniqueValuesInSeqEntry (sep,
24230                                             NULL,
24231                                             GetCDSComment,
24232                                             NULL,
24233                                             NULL, IntValNodeCopy,
24234                                             fsp,
24235                                             SEQFEAT_CDREGION, FEATDEF_CDS, 0);
24236       break;
24237     case PARSE_FIELD_COMMENT_DESC:
24238       requested_field = ValNodeNew (NULL);
24239       requested_field->data.intvalue = Seq_descr_comment;
24240 
24241       unique_values = CheckForUniqueValuesInSeqEntry (sep, requested_field,
24242                                             NULL,
24243                                             GetStringFromStringDescriptor,
24244                                             NULL, IntValNodeCopy,
24245                                             fsp, 0, 0, Seq_descr_comment);
24246       requested_field = ValNodeFree (requested_field);
24247       break;
24248     case PARSE_FIELD_PROTEIN_FIELD:
24249       unique_values = CheckForUniqueValuesInSeqEntry (sep,
24250                                             dst_field_data->feature_field,
24251                                             GetProteinFieldString,
24252                                             NULL,
24253                                             NULL, IntValNodeCopy,
24254                                             fsp,
24255                                             SEQFEAT_PROT, 0, 0);
24256       break;
24257     case PARSE_FIELD_IMPORT_QUAL:
24258       orig_sep = sep;
24259       for (vnp = dst_field_data->feature_subtype; vnp != NULL; vnp = vnp->next)
24260       {
24261         CombineClickableLists (&unique_values,
24262                                CheckForUniqueValuesInSeqEntry (sep,
24263                                                                dst_field_data->feature_field,
24264                                                                GetGBQualString,
24265                                                                NULL,
24266                                                                NULL, IntValNodeCopy,
24267                                                                fsp, 0, vnp->choice, 0));
24268         /* if we are also looking at features other than mat_peptides, use
24269          * original SeqEntry */
24270         sep = orig_sep;
24271       }
24272       break;
24273     case PARSE_FIELD_FEATURE_NOTE:
24274       orig_sep = sep;
24275       for (vnp = dst_field_data->feature_field; vnp != NULL; vnp = vnp->next)
24276       {
24277         CombineClickableLists (&unique_values,
24278                                CheckForUniqueValuesInSeqEntry (sep, vnp,
24279                                                                GetFeatureNote,
24280                                                                NULL,
24281                                                                ValNodeSimpleDataFree,
24282                                                                ValNodeStringCopy,
24283                                                                fsp, 0, vnp->choice, 0));
24284         /* if we are also looking at features other than mat_peptides, use
24285          * original SeqEntry */
24286         sep = orig_sep;
24287       }
24288       break;
24289   }
24290   return unique_values;
24291 }
24292 
24293 
GetSeqEntryListForItem(ValNodePtr vnp)24294 static ValNodePtr GetSeqEntryListForItem (ValNodePtr vnp)
24295 {
24296   SeqFeatPtr       sfp;
24297   SeqDescrPtr      sdp;
24298   ObjValNodePtr    ovp;
24299   SeqEntryPtr      sep = NULL;
24300   BioseqPtr        bsp;
24301   BioseqSetPtr     bssp;
24302   ValNodePtr       sep_list = NULL;
24303 
24304   if (vnp == NULL || vnp->data.ptrvalue == NULL) return NULL;
24305 
24306   if (vnp->choice == OBJ_SEQFEAT) {
24307     sfp = vnp->data.ptrvalue;
24308     sep = GetBestTopParentForData (sfp->idx.entityID, BioseqFindFromSeqLoc (sfp->location));
24309     ValNodeAddPointer (&sep_list, OBJ_SEQENTRY, sep);
24310   } else if (vnp->choice == OBJ_SEQDESC) {
24311     sdp = vnp->data.ptrvalue;
24312     if (sdp->extended != 0) {
24313       ovp = (ObjValNodePtr) sdp;
24314       if (ovp->idx.parenttype == OBJ_BIOSEQSET) {
24315         bssp = (BioseqSetPtr) ovp->idx.parentptr;
24316         if (bssp != NULL) {
24317           /* nuc_prot sets, segsets, and members of parts should travel together */
24318           if (bssp->_class == BioseqseqSet_class_nuc_prot) {
24319             sep = SeqMgrGetSeqEntryForData (bssp);
24320             if (sep != NULL) {
24321               ValNodeAddPointer (&sep_list, OBJ_SEQENTRY, sep);
24322             }
24323           } else if (bssp->_class == BioseqseqSet_class_segset
24324                      || bssp->_class == BioseqseqSet_class_parts) {
24325             sep = bssp->seq_set;
24326             if (sep != NULL && IS_Bioseq (sep)) {
24327               bsp = sep->data.ptrvalue;
24328               sep = GetBestTopParentForData (bsp->idx.entityID, bsp);
24329               if (sep != NULL) {
24330                 ValNodeAddPointer (&sep_list, OBJ_SEQENTRY, sep);
24331               }
24332             }
24333           } else {
24334             sep = bssp->seq_set;
24335             while (sep != NULL) {
24336               ValNodeAddPointer (&sep_list, OBJ_SEQENTRY, sep);
24337               sep = sep->next;
24338             }
24339           }
24340         }
24341       } else if (ovp->idx.parenttype == OBJ_BIOSEQ) {
24342         sep = GetBestTopParentForData (ovp->idx.entityID, ovp->idx.parentptr);
24343         if (sep != NULL) {
24344           ValNodeAddPointer (&sep_list, OBJ_SEQENTRY, sep);
24345         }
24346       }
24347     }
24348   } else if (vnp->choice == OBJ_BIOSEQ) {
24349     bsp = (BioseqPtr) vnp->data.ptrvalue;
24350     sep = GetBestTopParentForData (bsp->idx.entityID, bsp);
24351     ValNodeAddPointer (&sep_list, OBJ_SEQENTRY, sep);
24352   } else if (vnp->choice == OBJ_SEQENTRY) {
24353     sep = vnp->data.ptrvalue;
24354     ValNodeAddPointer (&sep_list, OBJ_SEQENTRY, sep);
24355   }
24356   return sep_list;
24357 }
24358 
24359 
RemoveItemAndCategory(ClickableItemPtr cip,Uint1 choice,Pointer ptrvalue)24360 static Boolean RemoveItemAndCategory (ClickableItemPtr cip, Uint1 choice, Pointer ptrvalue)
24361 {
24362   ValNodePtr vnp, prev = NULL;
24363   Boolean    found = FALSE;
24364   CharPtr    description = NULL;
24365   ClickableItemPtr subcat;
24366 
24367   vnp = cip->item_list;
24368   while (vnp != NULL) {
24369     if (vnp->choice == choice && vnp->data.ptrvalue == ptrvalue) {
24370       found = TRUE;
24371       if (prev == NULL) {
24372         cip->item_list = vnp->next;
24373       } else {
24374         prev->next = vnp->next;
24375       }
24376       vnp->next = NULL;
24377       description = GetDiscrepancyItemText (vnp);
24378       vnp = ValNodeFree (vnp);
24379     } else {
24380       prev = vnp;
24381       vnp = vnp->next;
24382     }
24383   }
24384   if (found) {
24385     /* also remove subcategory */
24386     prev = NULL;
24387     vnp = cip->subcategories;
24388     while (vnp != NULL) {
24389       subcat = (ClickableItemPtr) vnp->data.ptrvalue;
24390       if (subcat != NULL && StringCmp (subcat->description, description) == 0) {
24391         if (prev == NULL) {
24392           cip->subcategories = vnp->next;
24393         } else {
24394           prev->next = vnp->next;
24395         }
24396         vnp->next = NULL;
24397         vnp = FreeClickableList (vnp);
24398       } else {
24399         prev = vnp;
24400         vnp = vnp->next;
24401       }
24402     }
24403   }
24404   return found;
24405 }
24406 
RearrangeForSeqEntriesInMultipleCategories(ValNodePtr value_lists)24407 static ValNodePtr RearrangeForSeqEntriesInMultipleCategories (ValNodePtr value_lists)
24408 {
24409   ClickableItemPtr cip1, cip2, existing_cat;
24410   ValNodePtr       vnp, check_vnp, last_vnp, vnp_item1, prev, vnp_next;
24411   Boolean          found;
24412   CharPtr          new_description;
24413 
24414   /* now check for SeqEntries that appear in multiple lists */
24415   for (vnp = value_lists; vnp != NULL && vnp->next != NULL; vnp = vnp->next) {
24416     if (vnp->data.ptrvalue == NULL) continue;
24417     last_vnp = vnp->next;
24418     while (last_vnp->next != NULL) {
24419       last_vnp = last_vnp->next;
24420     }
24421     cip1 = (ClickableItemPtr) vnp->data.ptrvalue;
24422     for (vnp_item1 = cip1->item_list;
24423          vnp_item1 != NULL;
24424          vnp_item1 = vnp_next) {
24425       vnp_next = vnp_item1->next;
24426       found = FALSE;
24427       if (vnp_item1->data.ptrvalue != NULL && vnp_item1->choice == OBJ_SEQENTRY) {
24428         check_vnp = vnp->next;
24429         while (check_vnp != NULL && !found) {
24430           if (check_vnp->data.ptrvalue != NULL) {
24431             cip2 = check_vnp->data.ptrvalue;
24432             found = RemoveItemAndCategory (cip2, vnp_item1->choice, vnp_item1->data.ptrvalue);
24433           }
24434           if (!found) {
24435             if (check_vnp == last_vnp) {
24436               check_vnp = NULL;
24437             } else {
24438               check_vnp = check_vnp->next;
24439             }
24440           }
24441         }
24442       }
24443       if (found) {
24444         /* need to take this SeqEntry out of both lists, put in new category */
24445         new_description = (CharPtr) MemNew (sizeof (Char) * (StringLen (cip1->description)
24446                                                              + StringLen (cip2->description) + 6));
24447         if (StringCmp (cip1->description, cip2->description) < 0) {
24448           sprintf (new_description, "%s AND %s", cip1->description, cip2->description);
24449         } else {
24450           sprintf (new_description, "%s AND %s", cip2->description, cip1->description);
24451         }
24452         existing_cat = FindExistingCategory (new_description, check_vnp->next);
24453         if (existing_cat == NULL) {
24454           /* make new category, add to end of list */
24455           existing_cat = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
24456           MemSet (existing_cat, 0, sizeof (ClickableItemData));
24457           existing_cat->description = new_description;
24458           ValNodeAddPointer (&value_lists, 0, existing_cat);
24459         } else {
24460           new_description = MemFree (new_description);
24461         }
24462         /* don't add item twice */
24463         if (!DataInValNodeList (existing_cat->item_list, vnp_item1->choice, vnp_item1->data.ptrvalue)) {
24464           ValNodeAddPointer (&(existing_cat->item_list), vnp_item1->choice, vnp_item1->data.ptrvalue);
24465         }
24466         /* remove from cip1 */
24467         RemoveItemAndCategory (cip1, vnp_item1->choice, vnp_item1->data.ptrvalue);
24468       }
24469     }
24470   }
24471 
24472   /* remove empty categories */
24473   for (vnp = value_lists, prev = NULL; vnp != NULL; vnp = vnp_next) {
24474     vnp_next = vnp->next;
24475     cip1 = (ClickableItemPtr) vnp->data.ptrvalue;
24476     if (cip1 == NULL || cip1->item_list == NULL) {
24477       if (prev == NULL) {
24478         value_lists = vnp->next;
24479       } else {
24480         prev->next = vnp->next;
24481       }
24482       vnp->next = NULL;
24483       vnp = FreeClickableList (vnp);
24484     } else {
24485       prev = vnp;
24486     }
24487   }
24488   return value_lists;
24489 }
24490 
24491 
ChangeUniqueValueListsToSeqEntryLists(ValNodePtr value_lists)24492 static ValNodePtr ChangeUniqueValueListsToSeqEntryLists (ValNodePtr value_lists)
24493 {
24494   ValNodePtr vnp, vnp_item, new_item_list, new_vnp, sep_list, sep_vnp;
24495   ClickableItemPtr cip, subcat;
24496   SeqEntryPtr      sep;
24497   CharPtr          description;
24498 
24499   /* First, add SeqEntry for each feature or descriptor to the item list */
24500   for (vnp = value_lists; vnp != NULL; vnp = vnp->next) {
24501     cip = (ClickableItemPtr) vnp->data.ptrvalue;
24502     new_item_list = NULL;
24503     if (cip != NULL) {
24504       for (vnp_item = cip->item_list; vnp_item != NULL; vnp_item = vnp_item->next) {
24505         if (vnp_item->data.ptrvalue == NULL) continue;
24506         sep_list = GetSeqEntryListForItem (vnp_item);
24507         for (sep_vnp = sep_list; sep_vnp != NULL; sep_vnp = sep_vnp->next) {
24508           sep = sep_vnp->data.ptrvalue;
24509           new_vnp = DataInValNodeList (new_item_list, OBJ_SEQENTRY, sep);
24510           /* add to list for this category */
24511           if (new_vnp == NULL) {
24512             new_vnp = ValNodeAddPointer (&new_item_list, OBJ_SEQENTRY, sep);
24513           }
24514           description = GetDiscrepancyItemText(new_vnp);
24515           subcat = FindExistingCategory (description, cip->subcategories);
24516           if (subcat == NULL) {
24517             subcat = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
24518             MemSet (subcat, 0, sizeof (ClickableItemData));
24519             subcat->description = description;
24520             ValNodeAddPointer (&(cip->subcategories), 0, subcat);
24521           } else {
24522             description = MemFree (description);
24523           }
24524           /* don't add item twice */
24525           if (!DataInValNodeList (subcat->item_list, vnp_item->choice, vnp_item->data.ptrvalue)) {
24526             ValNodeAddPointer (&(subcat->item_list), vnp_item->choice, vnp_item->data.ptrvalue);
24527           }
24528         }
24529         sep_list = ValNodeFree (sep_list);
24530       }
24531 
24532       cip->item_list = ValNodeFree (cip->item_list);
24533       cip->item_list = new_item_list;
24534     }
24535   }
24536   value_lists = RearrangeForSeqEntriesInMultipleCategories (value_lists);
24537   return value_lists;
24538 }
24539 
24540 
GetMolTypes(SeqDescrPtr sdp,Pointer userdata)24541 static void GetMolTypes (SeqDescrPtr sdp, Pointer userdata)
24542 {
24543   ValNodePtr PNTR   type_list;
24544   ClickableItemPtr  cip;
24545   CharPtr           str;
24546   MolInfoPtr        mip;
24547 
24548   if (sdp == NULL || sdp->choice != Seq_descr_molinfo || sdp->data.ptrvalue == NULL || userdata == NULL)
24549   {
24550     return;
24551   }
24552 
24553   type_list = (ValNodePtr PNTR) userdata;
24554 
24555   mip = (MolInfoPtr) sdp->data.ptrvalue;
24556   /* don't look for peptides */
24557   if (mip->biomol == 8) return;
24558 
24559   str = GetMoleculeTypeName (mip->biomol);
24560 
24561   cip = FindExistingCategory (str, *type_list);
24562 
24563   if (cip == NULL) {
24564     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
24565     MemSet (cip, 0, sizeof (ClickableItemData));
24566     cip->description = StringSave (str);
24567     ValNodeAddPointer (&cip->item_list, OBJ_SEQDESC, sdp);
24568     ValNodeAddPointer (type_list, 0, cip);
24569   } else {
24570     /* make sure feature isn't already in the list */
24571     if (DataInValNodeList (cip->item_list, OBJ_SEQDESC, sdp) == NULL) {
24572       ValNodeAddPointer (&cip->item_list, OBJ_SEQDESC, sdp);
24573     }
24574   }
24575 }
24576 
GetMolClasses(BioseqPtr bsp,Pointer userdata)24577 static void GetMolClasses (BioseqPtr bsp, Pointer userdata)
24578 {
24579   ValNodePtr PNTR   type_list;
24580   ClickableItemPtr  cip;
24581   CharPtr           str;
24582 
24583   if (bsp == NULL || ISA_aa(bsp->mol) || userdata == NULL)
24584   {
24585     return;
24586   }
24587 
24588   type_list = (ValNodePtr PNTR) userdata;
24589 
24590   str = GetMoleculeClassName (bsp->mol);
24591 
24592   cip = FindExistingCategory (str, *type_list);
24593 
24594   if (cip == NULL) {
24595     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
24596     MemSet (cip, 0, sizeof (ClickableItemData));
24597     cip->description = StringSave (str);
24598     ValNodeAddPointer (&cip->item_list, OBJ_BIOSEQ, bsp);
24599     ValNodeAddPointer (type_list, 0, cip);
24600   } else {
24601     /* make sure feature isn't already in the list */
24602     if (DataInValNodeList (cip->item_list, OBJ_BIOSEQ, bsp) == NULL) {
24603       ValNodeAddPointer (&cip->item_list, OBJ_BIOSEQ, bsp);
24604     }
24605   }
24606 }
24607 
GetMolTopologies(BioseqPtr bsp,Pointer userdata)24608 static void GetMolTopologies (BioseqPtr bsp, Pointer userdata)
24609 {
24610   ValNodePtr PNTR   type_list;
24611   ClickableItemPtr  cip;
24612   CharPtr           str;
24613 
24614   if (bsp == NULL || ISA_aa(bsp->mol) || userdata == NULL)
24615   {
24616     return;
24617   }
24618 
24619   type_list = (ValNodePtr PNTR) userdata;
24620 
24621   str = GetMoleculeTopologyName (bsp->topology);
24622 
24623   cip = FindExistingCategory (str, *type_list);
24624 
24625   if (cip == NULL) {
24626     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
24627     MemSet (cip, 0, sizeof (ClickableItemData));
24628     cip->description = StringSave (str);
24629     ValNodeAddPointer (&cip->item_list, OBJ_BIOSEQ, bsp);
24630     ValNodeAddPointer (type_list, 0, cip);
24631   } else {
24632     /* make sure feature isn't already in the list */
24633     if (DataInValNodeList (cip->item_list, OBJ_BIOSEQ, bsp) == NULL) {
24634       ValNodeAddPointer (&cip->item_list, OBJ_BIOSEQ, bsp);
24635     }
24636   }
24637 }
24638 
24639 
24640 typedef struct segfeatures {
24641   Uint2      featdef;
24642   ValNodePtr feature_list;
24643 } SegFeaturesData, PNTR SegFeaturesPtr;
24644 
FindFeaturesForSeg(SeqFeatPtr sfp,Pointer userdata)24645 static void FindFeaturesForSeg (SeqFeatPtr sfp, Pointer userdata)
24646 {
24647   SegFeaturesPtr fp;
24648 
24649   if (sfp == NULL || userdata == NULL) return;
24650 
24651   fp = (SegFeaturesPtr) userdata;
24652 
24653   if (sfp->idx.subtype == fp->featdef) {
24654     ValNodeAddPointer (&(fp->feature_list), OBJ_SEQFEAT, sfp);
24655   }
24656 }
24657 
24658 typedef struct segdescriptors {
24659   Uint2      desc_type;
24660   ValNodePtr descriptor_list;
24661 } SegDescriptorsData, PNTR SegDescriptorsPtr;
24662 
FindDescriptorsForSeg(SeqDescrPtr sdp,Pointer userdata)24663 static void FindDescriptorsForSeg (SeqDescrPtr sdp, Pointer userdata)
24664 {
24665   SegDescriptorsPtr fp;
24666 
24667   if (sdp == NULL || userdata == NULL) return;
24668 
24669   fp = (SegDescriptorsPtr) userdata;
24670 
24671   if (sdp->choice == fp->desc_type) {
24672     ValNodeAddPointer (&(fp->descriptor_list), OBJ_SEQDESC, sdp);
24673   }
24674 }
24675 
24676 
24677 extern ValNodePtr
CreateSeqEntryListsForUniqueValues(SeqEntryPtr sep,Uint2 entityID,ParseFieldPtr dst_field_data,FilterSetPtr fsp)24678 CreateSeqEntryListsForUniqueValues
24679 (SeqEntryPtr   sep,
24680  Uint2         entityID,
24681  ParseFieldPtr dst_field_data,
24682  FilterSetPtr  fsp)
24683 {
24684   ValNodePtr value_lists;
24685 
24686   value_lists = GetUniqueValueListForSeqEntry (sep, entityID, dst_field_data, fsp);
24687 
24688   value_lists = ChangeUniqueValueListsToSeqEntryLists (value_lists);
24689   return value_lists;
24690 }
24691 
AddPubFeatureWithText(SeqFeatPtr sfp,Pointer userdata)24692 static void AddPubFeatureWithText (SeqFeatPtr sfp, Pointer userdata)
24693 {
24694   ValNodePtr PNTR pub_list;
24695 
24696   if (sfp == NULL || userdata == NULL) return;
24697   pub_list = (ValNodePtr PNTR) userdata;
24698 
24699   ValNodeAddPointer (pub_list, OBJ_SEQFEAT, sfp);
24700 }
24701 
AddPubDescriptorWithText(SeqDescrPtr sdp,Pointer userdata)24702 static void AddPubDescriptorWithText (SeqDescrPtr sdp, Pointer userdata)
24703 {
24704   ValNodePtr PNTR pub_list;
24705 
24706   if (sdp == NULL || userdata == NULL || sdp->choice != Seq_descr_pub) return;
24707   pub_list = (ValNodePtr PNTR) userdata;
24708 
24709   ValNodeAddPointer (pub_list, OBJ_SEQDESC, sdp);
24710 }
24711 
GetTextPubListsForSeqEntry(SeqEntryPtr sep,CharPtr search_text)24712 static ValNodePtr GetTextPubListsForSeqEntry (SeqEntryPtr sep, CharPtr search_text)
24713 {
24714   FeaturesWithTextData    ftd;
24715   DescriptorsWithTextData dtd;
24716   ValNodePtr              obj_list = NULL;
24717 
24718   ftd.seqFeatChoice = SEQFEAT_PUB;
24719   ftd.featDefChoice = FEATDEF_PUB;
24720   ftd.search_text = search_text;
24721   ftd.act_when_string_not_present = FALSE;
24722   ftd.case_insensitive = TRUE;
24723   ftd.whole_word = FALSE;
24724   ftd.no_text = FALSE;
24725   ftd.callback = AddPubFeatureWithText;
24726   ftd.userdata = &obj_list;
24727 
24728   dtd.search_text = search_text;
24729   dtd.act_when_string_not_present = FALSE;
24730   dtd.case_insensitive = TRUE;
24731   dtd.whole_word = FALSE;
24732   dtd.no_text = FALSE;
24733   dtd.callback = AddPubDescriptorWithText;
24734   dtd.userdata = &obj_list;
24735 
24736   OperateOnSeqEntryFeaturesWithText (sep, &ftd);
24737   OperateOnSeqEntryDescriptorsWithText (sep, &dtd);
24738 
24739   return obj_list;
24740 }
24741 
GetTextSeqEntryListForSeqEntry(SeqEntryPtr sep,Uint2 entityID,CharPtr search_text,ParseFieldPtr dst_field_data)24742 static ValNodePtr GetTextSeqEntryListForSeqEntry (SeqEntryPtr sep, Uint2 entityID, CharPtr search_text, ParseFieldPtr dst_field_data)
24743 {
24744   ValNodePtr value_lists = NULL;
24745   ValNodePtr obj_list = NULL, tmp_list, vnp;
24746   ClickableItemPtr cip;
24747   CharPtr          desc_fmt = "%d sequences contain %s";
24748   StringConstraintData scd;
24749   ChoiceConstraintData ccd;
24750   FilterSetData        fsd;
24751 
24752   if (dst_field_data == NULL) {
24753     /* do nothing */
24754   } else if (dst_field_data->parse_field_type == SEARCH_FIELD_PUBLICATION) {
24755     obj_list = GetTextPubListsForSeqEntry(sep, search_text);
24756   } else {
24757     scd.match_text = search_text;
24758     scd.match_location = 1;
24759     scd.insensitive = TRUE;
24760     scd.whole_word = FALSE;
24761     scd.not_present = FALSE;
24762 
24763     ccd.constraint_type = CHOICE_CONSTRAINT_STRING;
24764     ccd.qual_choice =
24765     ccd.qual_choice_match = NULL;
24766     ccd.string_constraint = &scd;
24767     ccd.pseudo_constraint = NULL;
24768     ccd.free_vn_proc = NULL;
24769     ccd.copy_vn_proc = NULL;
24770 
24771     MemSet (&fsd, 0, sizeof (FilterSetData));
24772     fsd.ccp = &ccd;
24773 
24774     tmp_list = GetUniqueValueListForSeqEntry (sep, entityID, dst_field_data, NULL);
24775 
24776     for (vnp = tmp_list; vnp != NULL; vnp = vnp->next) {
24777       cip = (ClickableItemPtr) vnp->data.ptrvalue;
24778       if (cip != NULL && StringISearch (cip->description, search_text) != NULL) {
24779         ValNodeLink (&obj_list, cip->item_list);
24780         cip->item_list = NULL;
24781       }
24782     }
24783     tmp_list = FreeClickableList (tmp_list);
24784   }
24785   if (obj_list != NULL) {
24786     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
24787     MemSet (cip, 0, sizeof (ClickableItemData));
24788     cip->description = StringSave (search_text);
24789     cip->item_list = obj_list;
24790     cip->chosen = TRUE;
24791     ValNodeAddPointer (&value_lists, 0, cip);
24792     value_lists = ChangeUniqueValueListsToSeqEntryLists (value_lists);
24793     /* rename description */
24794     if (value_lists != NULL) {
24795       cip = value_lists->data.ptrvalue;
24796       if (cip != NULL) {
24797         cip->description = MemFree (cip->description);
24798         cip->description = (CharPtr) MemNew (sizeof(Char) * (StringLen (desc_fmt) + StringLen (search_text) + 15));
24799         sprintf (cip->description, desc_fmt, ValNodeLen (cip->item_list), search_text);
24800       }
24801     }
24802   }
24803 
24804   return value_lists;
24805 }
24806 
24807 typedef enum vectorhitlevel {
24808   eVectorHitLevelSuspect = 1,
24809   eVectorHitLevelWeak,
24810   eVectorHitLevelModerate,
24811   eVectorHitLevelStrong } EVectorHitLevel;
24812 
24813 typedef struct vectorcontaminationoptions {
24814   Int4    internal_level;
24815   Int4    end5_level;
24816   Int4    end3_level;
24817   ValNodePtr bioseq_list;
24818 } VectorContaminationOptionsData, PNTR VectorContaminationOptionsPtr;
24819 
24820 typedef struct vectorcontaminationoptionsdlg {
24821   DIALOG_MESSAGE_BLOCK
24822 
24823   ButtoN internal;
24824   ButtoN end5;
24825   ButtoN end3;
24826   GrouP  internal_level;
24827   GrouP  end5_level;
24828   GrouP  end3_level;
24829 
24830   Nlm_ChangeNotifyProc     change_notify;
24831   Pointer                  change_userdata;
24832 } VectorContaminationOptionsDlgData, PNTR VectorContaminationOptionsDlgPtr;
24833 
DataToVectorContaminationOptionsDlg(DialoG d,Pointer data)24834 static void DataToVectorContaminationOptionsDlg (DialoG d, Pointer data)
24835 {
24836   VectorContaminationOptionsDlgPtr dlg;
24837   VectorContaminationOptionsPtr    options;
24838 
24839   dlg = (VectorContaminationOptionsDlgPtr) GetObjectExtra (d);
24840   if (dlg == NULL) {
24841     return;
24842   }
24843 
24844   options = (VectorContaminationOptionsPtr) data;
24845   if (options == NULL) {
24846     SetStatus (dlg->internal, FALSE);
24847     SetStatus (dlg->end5, FALSE);
24848     SetStatus (dlg->end3, FALSE);
24849     SetValue (dlg->internal_level, eVectorHitLevelStrong);
24850     SetValue (dlg->end5_level, eVectorHitLevelStrong);
24851     SetValue (dlg->end3_level, eVectorHitLevelStrong);
24852   } else {
24853     if (options->internal_level == 0) {
24854       SetStatus (dlg->internal, FALSE);
24855     } else {
24856       SetStatus (dlg->internal, TRUE);
24857       SetValue (dlg->internal_level, options->internal_level);
24858     }
24859 
24860     if (options->end5_level == 0) {
24861       SetStatus (dlg->end5, FALSE);
24862     } else {
24863       SetStatus (dlg->end5, TRUE);
24864       SetValue (dlg->end5_level, options->end5_level);
24865     }
24866     if (options->end3_level == 0) {
24867       SetStatus (dlg->end3, FALSE);
24868     } else {
24869       SetStatus (dlg->end3, TRUE);
24870       SetValue (dlg->end3_level, options->end3_level);
24871     }
24872   }
24873 }
24874 
24875 
VectorContaminationOptionsDlgToData(DialoG d)24876 static Pointer VectorContaminationOptionsDlgToData (DialoG d)
24877 {
24878   VectorContaminationOptionsDlgPtr dlg;
24879   VectorContaminationOptionsPtr    options = NULL;
24880 
24881   dlg = (VectorContaminationOptionsDlgPtr) GetObjectExtra (d);
24882   if (dlg == NULL) {
24883     return NULL;
24884   }
24885 
24886   options = (VectorContaminationOptionsPtr) MemNew (sizeof (VectorContaminationOptionsData));
24887   if (GetStatus (dlg->internal)) {
24888     options->internal_level = GetValue (dlg->internal_level);
24889   } else {
24890     options->internal_level = 0;
24891   }
24892   if (GetStatus (dlg->end5)) {
24893     options->end5_level = GetValue (dlg->end5_level);
24894   } else {
24895     options->end5_level = 0;
24896   }
24897   if (GetStatus (dlg->end3)) {
24898     options->end3_level = GetValue (dlg->end3_level);
24899   } else {
24900     options->end3_level = 0;
24901   }
24902 
24903   options->bioseq_list = NULL;
24904   return (Pointer) options;
24905 }
24906 
24907 
ChangeVectorContaminationButton(ButtoN b)24908 static void ChangeVectorContaminationButton (ButtoN b)
24909 {
24910   VectorContaminationOptionsDlgPtr dlg;
24911 
24912   dlg = (VectorContaminationOptionsDlgPtr) GetObjectExtra (b);
24913   if (dlg == NULL) {
24914     return;
24915   }
24916 
24917   if (GetStatus (dlg->internal)) {
24918     Enable (dlg->internal_level);
24919   } else {
24920     Disable (dlg->internal_level);
24921   }
24922   if (GetStatus (dlg->end5)) {
24923     Enable (dlg->end5_level);
24924   } else {
24925     Disable (dlg->end5_level);
24926   }
24927   if (GetStatus (dlg->end3)) {
24928     Enable (dlg->end3_level);
24929   } else {
24930     Disable (dlg->end3_level);
24931   }
24932 
24933   if (dlg->change_notify != NULL) {
24934     (dlg->change_notify)(dlg->change_userdata);
24935   }
24936 }
24937 
24938 
ChangeVectorContaminationGroup(GrouP g)24939 static void ChangeVectorContaminationGroup (GrouP g)
24940 {
24941   VectorContaminationOptionsDlgPtr dlg;
24942 
24943   dlg = (VectorContaminationOptionsDlgPtr) GetObjectExtra (g);
24944   if (dlg != NULL && dlg->change_notify != NULL) {
24945     (dlg->change_notify)(dlg->change_userdata);
24946   }
24947 }
24948 
24949 
VectorContaminationOptionsDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)24950 static DialoG VectorContaminationOptionsDialog (GrouP h, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
24951 {
24952   VectorContaminationOptionsDlgPtr dlg;
24953   GrouP                     p;
24954 
24955   dlg = (VectorContaminationOptionsDlgPtr) MemNew (sizeof (VectorContaminationOptionsDlgData));
24956   if (dlg == NULL)
24957   {
24958     return NULL;
24959   }
24960 
24961   p = HiddenGroup (h, 2, 0, NULL);
24962   SetObjectExtra (p, dlg, StdCleanupExtraProc);
24963   SetGroupSpacing (p, 10, 10);
24964 
24965   dlg->dialog = (DialoG) p;
24966   dlg->todialog = DataToVectorContaminationOptionsDlg;
24967   dlg->fromdialog = VectorContaminationOptionsDlgToData;
24968   dlg->dialogmessage = NULL;
24969   dlg->testdialog = NULL;
24970   dlg->change_notify = change_notify;
24971   dlg->change_userdata = change_userdata;
24972 
24973   dlg->internal = CheckBox (p, "Internal", ChangeVectorContaminationButton);
24974   SetObjectExtra (dlg->internal, dlg, NULL);
24975   dlg->internal_level = HiddenGroup (p, 4, 0, ChangeVectorContaminationGroup);
24976   SetObjectExtra (dlg->internal_level, dlg, NULL);
24977   RadioButton (dlg->internal_level, "Suspect");
24978   RadioButton (dlg->internal_level, "Weak");
24979   RadioButton (dlg->internal_level, "Moderate");
24980   RadioButton (dlg->internal_level, "Strong");
24981   SetValue (dlg->internal_level, 1);
24982   Disable (dlg->internal_level);
24983 
24984   dlg->end5 = CheckBox (p, "5' End", ChangeVectorContaminationButton);
24985   SetObjectExtra (dlg->end5, dlg, NULL);
24986   dlg->end5_level = HiddenGroup (p, 4, 0, ChangeVectorContaminationGroup);
24987   SetObjectExtra (dlg->end5_level, dlg, NULL);
24988   RadioButton (dlg->end5_level, "Suspect");
24989   RadioButton (dlg->end5_level, "Weak");
24990   RadioButton (dlg->end5_level, "Moderate");
24991   RadioButton (dlg->end5_level, "Strong");
24992   SetValue (dlg->end5_level, 1);
24993   Disable (dlg->end5_level);
24994 
24995   dlg->end3 = CheckBox (p, "3' End", ChangeVectorContaminationButton);
24996   SetObjectExtra (dlg->end3, dlg, NULL);
24997   dlg->end3_level = HiddenGroup (p, 4, 0, ChangeVectorContaminationGroup);
24998   SetObjectExtra (dlg->end3_level, dlg, NULL);
24999   RadioButton (dlg->end3_level, "Suspect");
25000   RadioButton (dlg->end3_level, "Weak");
25001   RadioButton (dlg->end3_level, "Moderate");
25002   RadioButton (dlg->end3_level, "Strong");
25003   SetValue (dlg->end3_level, 1);
25004   Disable (dlg->end3_level);
25005 
25006   return (DialoG) p;
25007 }
25008 
25009 
25010 typedef struct chooseseqsbylen {
25011   ValNodePtr bsp_list;
25012   Int4 min;
25013   Int4 max;
25014 } ChooseSeqsByLenData, PNTR ChooseSeqsByLenPtr;
25015 
25016 
25017 typedef struct chooseseqsbylendlg {
25018   DIALOG_MESSAGE_BLOCK
25019   TexT min;
25020   TexT max;
25021   Nlm_ChangeNotifyProc     change_notify;
25022   Pointer                  change_userdata;
25023 } ChooseSeqsByLenDlgData, PNTR ChooseSeqsByLenDlgPtr;
25024 
25025 
DataToChooseSeqsByLenDlg(DialoG d,Pointer data)25026 static void DataToChooseSeqsByLenDlg (DialoG d, Pointer data)
25027 {
25028   ChooseSeqsByLenDlgPtr dlg;
25029   ChooseSeqsByLenPtr    options;
25030   Char                  buf[255];
25031 
25032   dlg = (ChooseSeqsByLenDlgPtr) GetObjectExtra (d);
25033   if (dlg == NULL) {
25034     return;
25035   }
25036 
25037   options = (ChooseSeqsByLenPtr) data;
25038   if (options == NULL) {
25039     SetTitle (dlg->min, "0");
25040     SetTitle (dlg->max, "0");
25041   } else {
25042     sprintf (buf, "%d", options->min);
25043     SetTitle (dlg->min, buf);
25044     sprintf (buf, "%d", options->max);
25045     SetTitle (dlg->max, buf);
25046   }
25047 }
25048 
25049 
ChooseSeqsByLenDlgToData(DialoG d)25050 static Pointer ChooseSeqsByLenDlgToData (DialoG d)
25051 {
25052   ChooseSeqsByLenDlgPtr dlg;
25053   ChooseSeqsByLenPtr    options = NULL;
25054   CharPtr               buf;
25055 
25056   dlg = (ChooseSeqsByLenDlgPtr) GetObjectExtra (d);
25057   if (dlg == NULL) {
25058     return NULL;
25059   }
25060 
25061   options = (ChooseSeqsByLenPtr) MemNew (sizeof (ChooseSeqsByLenData));
25062   if (TextHasNoText (dlg->min)) {
25063     options->min = 0;
25064   } else {
25065     buf = SaveStringFromText (dlg->min);
25066     options->min = atoi (buf);
25067     buf = MemFree (buf);
25068   }
25069   if (TextHasNoText (dlg->max)) {
25070     options->max = 0;
25071   } else {
25072     buf = SaveStringFromText (dlg->max);
25073     options->max = atoi (buf);
25074     buf = MemFree (buf);
25075   }
25076   return (Pointer) options;
25077 }
25078 
25079 
ChangeChooseSeqsByLenText(TexT t)25080 static void ChangeChooseSeqsByLenText (TexT t)
25081 {
25082   ChooseSeqsByLenDlgPtr dlg;
25083 
25084   dlg = (ChooseSeqsByLenDlgPtr) GetObjectExtra (t);
25085   if (dlg == NULL) {
25086     return;
25087   }
25088 
25089   if (dlg->change_notify != NULL) {
25090     (dlg->change_notify)(dlg->change_userdata);
25091   }
25092 }
25093 
25094 
ChooseSeqsByLenDialog(GrouP h,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)25095 static DialoG ChooseSeqsByLenDialog (GrouP h, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
25096 {
25097   ChooseSeqsByLenDlgPtr dlg;
25098   GrouP                     p;
25099 
25100   dlg = (ChooseSeqsByLenDlgPtr) MemNew (sizeof (ChooseSeqsByLenDlgData));
25101   if (dlg == NULL)
25102   {
25103     return NULL;
25104   }
25105 
25106   p = HiddenGroup (h, 2, 0, NULL);
25107   SetObjectExtra (p, dlg, StdCleanupExtraProc);
25108   SetGroupSpacing (p, 10, 10);
25109 
25110   dlg->dialog = (DialoG) p;
25111   dlg->todialog = DataToChooseSeqsByLenDlg;
25112   dlg->fromdialog = ChooseSeqsByLenDlgToData;
25113   dlg->dialogmessage = NULL;
25114   dlg->testdialog = NULL;
25115   dlg->change_notify = change_notify;
25116   dlg->change_userdata = change_userdata;
25117 
25118   StaticPrompt (p, "Minimum length", 0, dialogTextHeight, programFont, 'c');
25119   dlg->min = DialogText (p, "0", 10, ChangeChooseSeqsByLenText);
25120   SetObjectExtra (dlg->min, dlg, NULL);
25121   StaticPrompt (p, "Maximum length", 0, dialogTextHeight, programFont, 'c');
25122   dlg->max = DialogText (p, "50", 10, ChangeChooseSeqsByLenText);
25123   SetObjectExtra (dlg->max, dlg, NULL);
25124 
25125   return (DialoG) p;
25126 }
25127 
25128 
25129 typedef enum {
25130   eSegPageId = 1,
25131   eSegPageText,
25132   eSegPageField,
25133   eSegPageMolInfo,
25134   eSegPageFeatureType,
25135   eSegPageDescriptorType,
25136   eSegPageLength,
25137   eSegPageVectorContamination,
25138   eSegPageNumFinalSets,
25139   eSegPageFile,
25140   eSegPageConstraint,
25141   eSegPageStructuredCommentField,
25142   eNumSegPages
25143 } ESegPage;
25144 
25145 typedef struct segbyfield {
25146   FORM_MESSAGE_BLOCK
25147   GrouP        seg_choice_grp;
25148 
25149   GrouP        pages[eNumSegPages];
25150   /* for segregating by field */
25151   DialoG       field_dlg;
25152   DialoG       group_list_dlg;
25153 
25154   /* for segregating by molinfo */
25155   ButtoN       mol_type_btn;
25156   ButtoN       mol_class_btn;
25157   ButtoN       mol_topology_btn;
25158 
25159   /* for segregating by feature */
25160   DialoG       feature_select;
25161 
25162   /* for segregating by descriptor */
25163   DialoG       descriptor_select;
25164 
25165   /* for segregating by text */
25166   DialoG       search_field;
25167   TexT         search_text;
25168 
25169   /* for segregating by ID */
25170   DialoG       id_constraint_dlg;
25171 
25172   /* for segregating by length */
25173   DialoG       len_options;
25174 
25175   /* for segregating by vector contamination */
25176   DialoG       vector_options;
25177 
25178   /* for segregating into a specific number of sets */
25179   TexT         num_sets;
25180 
25181   /* for segregating by any constraint */
25182   DialoG       seq_constraint_dlg;
25183 
25184   /* for segregating by structured comment field */
25185   DialoG       struc_comm_field;
25186 
25187   Nlm_BtnActnProc actn;
25188   ButtoN       accept;
25189   ButtoN       leave_dlg_up;
25190   BioseqSetPtr target_set;
25191   ValNodePtr   value_lists;
25192 } SegByFieldData, PNTR SegByFieldPtr;
25193 
25194 static void ChangeSegChoice (GrouP g);
25195 
25196 
PullChosenIntoOneGroup(ValNodePtr PNTR value_list,ClickableItemPtr chosen)25197 static void PullChosenIntoOneGroup (ValNodePtr PNTR value_list, ClickableItemPtr chosen)
25198 {
25199   ValNodePtr vnp_prev = NULL, vnp_next, vnp_this;
25200   ClickableItemPtr cip;
25201 
25202   if (value_list == NULL || chosen == NULL) return;
25203 
25204   vnp_this = *value_list;
25205   while (vnp_this != NULL)
25206   {
25207     vnp_next = vnp_this->next;
25208     cip = (ClickableItemPtr) vnp_this->data.ptrvalue;
25209     if (cip == NULL)
25210     {
25211       vnp_this->next = NULL;
25212       if (vnp_prev == NULL)
25213       {
25214         *value_list = vnp_next;
25215       }
25216       else
25217       {
25218         vnp_prev->next = vnp_next;
25219       }
25220       vnp_this = ValNodeFree (vnp_this);
25221     }
25222     else if (cip->chosen)
25223     {
25224       vnp_this->next = NULL;
25225       if (vnp_prev == NULL)
25226       {
25227         *value_list = vnp_next;
25228       }
25229       else
25230       {
25231         vnp_prev->next = vnp_next;
25232       }
25233       ValNodeLink (&(chosen->item_list), cip->item_list);
25234       cip->item_list = NULL;
25235       vnp_this = FreeClickableList (vnp_this);
25236     }
25237     else
25238     {
25239       PullChosenIntoOneGroup (&(cip->subcategories), chosen);
25240       vnp_prev = vnp_this;
25241     }
25242     vnp_this = vnp_next;
25243   }
25244 }
25245 
25246 
NumChosenThatContainSequencesInAlignments(ValNodePtr value_lists,Boolean count_all)25247 static Int4 NumChosenThatContainSequencesInAlignments (ValNodePtr value_lists, Boolean count_all)
25248 {
25249   Int4 rval = 0;
25250   ClickableItemPtr cip;
25251   ValNodePtr vnp, vnp_item;
25252   BioseqPtr  bsp;
25253   BioseqSetPtr bssp;
25254   SeqEntryPtr sep;
25255 
25256   if (value_lists == NULL)
25257   {
25258     return 0;
25259   }
25260 
25261   for (vnp = value_lists; vnp != NULL; vnp = vnp->next)
25262   {
25263     cip = (ClickableItemPtr) vnp->data.ptrvalue;
25264     if (cip == NULL)
25265     {
25266       /* ignore */
25267     }
25268     else if (cip->chosen || count_all)
25269     {
25270       if (cip->item_list == NULL)
25271       {
25272         rval += NumChosenThatContainSequencesInAlignments (cip->subcategories, TRUE);
25273       }
25274       else
25275       {
25276         for (vnp_item = cip->item_list; vnp_item != NULL; vnp_item = vnp_item->next)
25277         {
25278           if (vnp_item->choice == OBJ_BIOSEQ)
25279           {
25280             bsp = (BioseqPtr) vnp_item->data.ptrvalue;
25281             if (bsp != NULL && IsBioseqInAnyAlignment (bsp, bsp->idx.entityID))
25282             {
25283               rval++;
25284             }
25285           }
25286           else if (vnp_item->choice == OBJ_BIOSEQSET)
25287           {
25288             bssp = (BioseqSetPtr) vnp_item->data.ptrvalue;
25289             if (bssp != NULL && AreAnyElementsOfSetInAnyAlignment (bssp, bssp->idx.entityID))
25290             {
25291               rval++;
25292             }
25293           }
25294           else if (vnp_item->choice == OBJ_SEQENTRY)
25295           {
25296             sep = vnp_item->data.ptrvalue;
25297             if (IS_Bioseq (sep))
25298             {
25299               bsp = (BioseqPtr) sep->data.ptrvalue;
25300               if (bsp != NULL && IsBioseqInAnyAlignment (bsp, bsp->idx.entityID))
25301               {
25302                 rval++;
25303               }
25304             }
25305             else if (IS_Bioseq_set(sep))
25306             {
25307               bssp = (BioseqSetPtr) sep->data.ptrvalue;
25308               if (bssp != NULL && AreAnyElementsOfSetInAnyAlignment (bssp, bssp->idx.entityID))
25309               {
25310                 rval++;
25311               }
25312             }
25313           }
25314         }
25315       }
25316     }
25317     else
25318     {
25319       rval += NumChosenThatContainSequencesInAlignments (cip->subcategories, FALSE);
25320     }
25321   }
25322 
25323   return rval;
25324 }
25325 
25326 
RemoveAlignmentsWithChosenSegregateSequences(ValNodePtr value_lists,Uint2 entityID,Boolean all_chosen)25327 static void RemoveAlignmentsWithChosenSegregateSequences (ValNodePtr value_lists, Uint2 entityID, Boolean all_chosen)
25328 {
25329   ClickableItemPtr cip;
25330   ValNodePtr vnp, vnp_item;
25331   BioseqPtr  bsp;
25332   SeqEntryPtr sep;
25333 
25334   if (value_lists == NULL)
25335   {
25336     return;
25337   }
25338 
25339   for (vnp = value_lists; vnp != NULL; vnp = vnp->next)
25340   {
25341     cip = (ClickableItemPtr) vnp->data.ptrvalue;
25342     if (cip == NULL)
25343     {
25344       /* ignore */
25345     }
25346     else if (cip->chosen || all_chosen)
25347     {
25348       if (cip->item_list == NULL)
25349       {
25350         RemoveAlignmentsWithChosenSegregateSequences (cip->subcategories, entityID, TRUE);
25351       }
25352       else
25353       {
25354         for (vnp_item = cip->item_list; vnp_item != NULL; vnp_item = vnp_item->next)
25355         {
25356           if (vnp_item->choice == OBJ_BIOSEQ)
25357           {
25358             bsp = (BioseqPtr) vnp_item->data.ptrvalue;
25359             RemoveAlignmentsWithSequence (bsp, entityID);
25360           }
25361           else if (vnp_item->choice == OBJ_BIOSEQSET)
25362           {
25363             RemoveAlignmentsWithElementsOfSet (vnp_item->data.ptrvalue, entityID);
25364           }
25365           else if (vnp_item->choice == OBJ_SEQENTRY)
25366           {
25367             sep = vnp_item->data.ptrvalue;
25368             if (IS_Bioseq (sep))
25369             {
25370               bsp = (BioseqPtr) sep->data.ptrvalue;
25371               RemoveAlignmentsWithSequence (bsp, entityID);
25372             }
25373             else if (IS_Bioseq_set(sep))
25374             {
25375               RemoveAlignmentsWithElementsOfSet (sep->data.ptrvalue, entityID);
25376             }
25377           }
25378 
25379         }
25380       }
25381     }
25382     else
25383     {
25384       RemoveAlignmentsWithChosenSegregateSequences (cip->subcategories, entityID, FALSE);
25385     }
25386   }
25387 }
25388 
PropagateDescriptorBeforeSegregate(SeqEntryPtr sep)25389 static void PropagateDescriptorBeforeSegregate(SeqEntryPtr sep)
25390 {
25391     BioseqSetPtr bssp;
25392 
25393     if (sep == NULL || !IS_Bioseq_set(sep)
25394         || (bssp = (BioseqSetPtr) sep->data.ptrvalue) == NULL
25395         || bssp->_class == BioseqseqSet_class_nuc_prot) {
25396         return;
25397     }
25398     SetDescriptorPropagate(bssp);
25399     for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
25400         PropagateDescriptorBeforeSegregate(sep);
25401     }
25402 }
25403 
25404 
SegregateByField_Callback(ButtoN b)25405 static void SegregateByField_Callback (ButtoN b)
25406 {
25407   SegByFieldPtr sfp;
25408   Int4          num_chosen = 0, num_in_align;
25409   ClickableItemPtr cip;
25410   Int2             val;
25411   MsgAnswer        ans;
25412   SeqEntryPtr      sep, orig_sep;
25413 
25414   sfp = (SegByFieldPtr) GetObjectExtra (b);
25415   if (sfp == NULL) return;
25416 
25417   num_chosen = CountChosenDiscrepancies (sfp->value_lists, FALSE);
25418   if (num_chosen < 1) {
25419     if (ANS_OK == Message (MSG_OKC, "You have not chosen any groups.  Create all?")) {
25420       ChooseAllDiscrepancies (sfp->value_lists);
25421     } else {
25422       return;
25423     }
25424   }
25425 
25426   sep = GetTopSeqEntryForEntityID (sfp->input_entityID);
25427   if (sep == NULL) {
25428     Message (MSG_ERROR, "No Seq-entry to segregate!");
25429   } else if (!IS_Bioseq_set(sep)) {
25430     Message (MSG_ERROR, "Cannot segregate a single sequence!");
25431   }
25432 
25433   orig_sep = SeqEntrySetScope (sep);
25434   num_in_align = NumChosenThatContainSequencesInAlignments(sfp->value_lists, FALSE);
25435   SeqEntrySetScope (orig_sep);
25436   if (num_in_align > 0) {
25437     ans = Message (MSG_YNC, "%d sequences are in alignments.  Do you want to remove the alignments?", num_in_align);
25438     if (ans == ANS_CANCEL) {
25439       ChangeSegChoice (sfp->seg_choice_grp);
25440       return;
25441     } else if (ans == ANS_YES) {
25442       RemoveAlignmentsWithChosenSegregateSequences (sfp->value_lists, sfp->input_entityID, FALSE);
25443     }
25444   }
25445 
25446   RemovePopsetTitles (sep);
25447   PropagateDescriptorBeforeSegregate (sep);
25448 
25449   val = GetValue (sfp->seg_choice_grp);
25450   if (val == eSegPageId || val == eSegPageVectorContamination || val == eSegPageLength || val == eSegPageConstraint) {
25451     /* put all selected sequences into one group */
25452     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
25453     cip->chosen = TRUE;
25454     PullChosenIntoOneGroup (&(sfp->value_lists), cip);
25455     ValNodeAddPointer (&(sfp->value_lists), 0, cip);
25456   }
25457 
25458   sfp->target_set = MakeGroupsForUniqueValues (sfp->target_set, sfp->value_lists);
25459 
25460   if (GetStatus (sfp->leave_dlg_up)) {
25461     ChangeSegChoice (sfp->seg_choice_grp);
25462   } else {
25463     Remove (sfp->form);
25464   }
25465 }
25466 
ChangeSegField(Pointer userdata)25467 static void ChangeSegField (Pointer userdata)
25468 {
25469   SegByFieldPtr sfp = (SegByFieldPtr) userdata;
25470   SeqEntryPtr   sep;
25471   ParseFieldPtr dst_field_data;
25472 
25473   if (sfp == NULL || sfp->target_set == NULL) return;
25474 
25475   WatchCursor();
25476   Update();
25477   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
25478 
25479   PointerToDialog (sfp->group_list_dlg, NULL);
25480   sfp->value_lists = FreeClickableList (sfp->value_lists);
25481 
25482   dst_field_data = DialogToPointer (sfp->field_dlg);
25483   if (dst_field_data == NULL) {
25484     Disable (sfp->accept);
25485     return;
25486   }
25487 
25488   sfp->value_lists = CreateSeqEntryListsForUniqueValues (sep, sfp->target_set->idx.entityID, dst_field_data, NULL);
25489   dst_field_data = ParseFieldFree (dst_field_data);
25490   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
25491   Enable (sfp->accept);
25492   ArrowCursor();
25493   Update();
25494 }
25495 
25496 
ChangeSegStructuredCommentField(Pointer userdata)25497 static void ChangeSegStructuredCommentField (Pointer userdata)
25498 {
25499   SegByFieldPtr sfp = (SegByFieldPtr) userdata;
25500   SeqEntryPtr   sep;
25501   ValNodePtr    vnp;
25502 
25503   if (sfp == NULL || sfp->target_set == NULL) return;
25504 
25505   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
25506 
25507   PointerToDialog (sfp->group_list_dlg, NULL);
25508   sfp->value_lists = FreeClickableList (sfp->value_lists);
25509 
25510   vnp = DialogToPointer (sfp->struc_comm_field);
25511   if (vnp == NULL) {
25512     Disable (sfp->accept);
25513     return;
25514   }
25515 
25516   WatchCursor();
25517   Update();
25518 
25519   sfp->value_lists = GetUniqueValuesForStructuredCommentField (sep, vnp->data.ptrvalue);
25520   sfp->value_lists = ChangeUniqueValueListsToSeqEntryLists (sfp->value_lists);
25521   vnp = ValNodeFreeData (vnp);
25522 
25523   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
25524   Enable (sfp->accept);
25525   ArrowCursor();
25526   Update();
25527 }
25528 
25529 
SegTextChangeNotify(Pointer userdata)25530 static void SegTextChangeNotify (Pointer userdata)
25531 {
25532   SegByFieldPtr sfp = (SegByFieldPtr) userdata;
25533   SeqEntryPtr   sep;
25534   ParseFieldPtr dst_field_data;
25535   CharPtr       search_text;
25536 
25537   if (sfp == NULL || sfp->target_set == NULL) return;
25538 
25539   WatchCursor();
25540   Update();
25541   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
25542 
25543   PointerToDialog (sfp->group_list_dlg, NULL);
25544   sfp->value_lists = FreeClickableList (sfp->value_lists);
25545 
25546   if (TextHasNoText (sfp->search_text)) {
25547     Disable (sfp->accept);
25548     ArrowCursor();
25549     Update();
25550     return;
25551   }
25552   dst_field_data = DialogToPointer (sfp->search_field);
25553   if (dst_field_data == NULL) {
25554     Disable (sfp->accept);
25555     ArrowCursor();
25556     Update();
25557     return;
25558   }
25559   search_text = SaveStringFromText (sfp->search_text);
25560 
25561   sfp->value_lists = GetTextSeqEntryListForSeqEntry (sep, sfp->target_set->idx.entityID, search_text, dst_field_data);
25562 
25563   search_text = MemFree (search_text);
25564 
25565   dst_field_data = ParseFieldFree (dst_field_data);
25566   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
25567   if (sfp->value_lists == NULL) {
25568     Disable(sfp->accept);
25569   } else {
25570     Enable (sfp->accept);
25571   }
25572   ArrowCursor();
25573   Update();
25574 }
25575 
SegTextChange(TexT t)25576 static void SegTextChange (TexT t)
25577 {
25578   SegByFieldPtr sfp;
25579 
25580   sfp = (SegByFieldPtr) GetObjectExtra (t);
25581 
25582   SegTextChangeNotify (sfp);
25583 
25584 }
25585 
25586 
IsBankitId(SeqIdPtr sip)25587 static Boolean IsBankitId (SeqIdPtr sip)
25588 {
25589   DbtagPtr dbtag;
25590 
25591   if (sip == NULL || sip->choice != SEQID_GENERAL) {
25592     return FALSE;
25593   }
25594   if ((dbtag = (DbtagPtr) sip->data.ptrvalue) == NULL) {
25595     return FALSE;
25596   }
25597   if (StringCmp (dbtag->db, "BankIt") == 0) {
25598     return TRUE;
25599   } else {
25600     return FALSE;
25601   }
25602 }
25603 
25604 
ClickableItemForBioseq(BioseqPtr bsp)25605 NLM_EXTERN ClickableItemPtr ClickableItemForBioseq (BioseqPtr bsp)
25606 {
25607   ClickableItemPtr cip = NULL;
25608   SeqIdPtr         sip, sip2;
25609   Char             id_str[3][100];
25610   Int4             num_id = 1, len = 0;
25611   Int4             i;
25612 
25613   if (bsp != NULL && ! ISA_aa (bsp->mol))
25614   {
25615     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
25616     sip = SeqIdFindBest (bsp->id, SEQID_GENBANK);
25617     SeqIdWrite (sip, id_str[0], PRINTID_REPORT, sizeof (id_str[0]) - 1);
25618     len = StringLen (id_str[0]) + 1;
25619     if (!IsBankitId(sip)) {
25620       sip2 = bsp->id;
25621       while (sip2 != NULL && !IsBankitId(sip2)) {
25622         sip2 = sip2->next;
25623       }
25624       if (sip2 != NULL) {
25625         SeqIdWrite (sip2, id_str[1], PRINTID_REPORT, sizeof (id_str[1]) - 1);
25626         len += StringLen (id_str[1]) + 1;
25627         num_id++;
25628       }
25629     }
25630     if (!IsNCBIFileID(sip)) {
25631       sip2 = bsp->id;
25632       while (sip2 != NULL && !IsNCBIFileID(sip2)) {
25633         sip2 = sip2->next;
25634       }
25635       if (sip2 != NULL) {
25636         SeqIdWrite (sip2, id_str[1], PRINTID_REPORT, sizeof (id_str[1]) - 1);
25637         len += StringLen (id_str[1]) + 1;
25638         num_id++;
25639       }
25640     }
25641 
25642     /* space for length */
25643     len += 20;
25644 
25645     cip->description = (CharPtr) MemNew (sizeof (Char) * len);
25646     sprintf (cip->description, "%s", id_str[0]);
25647     for (i = 1; i < num_id; i++) {
25648       StringCat (cip->description, "|");
25649       StringCat (cip->description, id_str[i]);
25650     }
25651     sprintf (cip->description + StringLen (cip->description), ":%d", bsp->length);
25652 
25653     ValNodeAddPointer (&(cip->item_list), OBJ_BIOSEQ, bsp);
25654   }
25655   return cip;
25656 }
25657 
25658 
ListAllSequences(BioseqPtr bsp,Pointer userdata)25659 extern void ListAllSequences (BioseqPtr bsp, Pointer userdata)
25660 {
25661   ClickableItemPtr cip;
25662 
25663   cip = ClickableItemForBioseq (bsp);
25664   if (cip != NULL)
25665   {
25666     ValNodeAddPointer ((ValNodePtr PNTR) userdata, 0, cip);
25667   }
25668 }
25669 
25670 
ChooseSegId(Pointer userdata)25671 static void ChooseSegId (Pointer userdata)
25672 {
25673   SegByFieldPtr sfp = (SegByFieldPtr) userdata;
25674   SeqEntryPtr   sep;
25675 
25676   if (sfp == NULL || sfp->target_set == NULL) return;
25677 
25678   WatchCursor();
25679   Update();
25680   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
25681 
25682   PointerToDialog (sfp->group_list_dlg, NULL);
25683   sfp->value_lists = FreeClickableList (sfp->value_lists);
25684 
25685   VisitBioseqsInSep (sep, &sfp->value_lists, ListAllSequences);
25686 
25687   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
25688   if (sfp->value_lists == NULL) {
25689     Disable(sfp->accept);
25690   } else {
25691     Enable (sfp->accept);
25692   }
25693   ArrowCursor();
25694   Update();
25695 }
25696 
25697 
DoesLevelStringMatchLevel(CharPtr str,Int4 level)25698 static Boolean DoesLevelStringMatchLevel (CharPtr str, Int4 level)
25699 {
25700   Boolean rval = FALSE;
25701 
25702   switch (level) {
25703     case eVectorHitLevelSuspect:
25704       if (StringISearch (str, "suspect") != NULL) {
25705         rval = TRUE;
25706       }
25707       /* note - absence of break is deliberate */
25708     case eVectorHitLevelWeak:
25709       if (StringISearch (str, "weak") != NULL) {
25710         rval = TRUE;
25711       }
25712       /* note - absence of break is deliberate */
25713     case eVectorHitLevelModerate:
25714       if (StringISearch (str, "moderate") != NULL) {
25715         rval = TRUE;
25716       }
25717       /* note - absence of break is deliberate */
25718     case eVectorHitLevelStrong:
25719       if (StringISearch (str, "strong") != NULL) {
25720         rval = TRUE;
25721       }
25722       break;
25723   }
25724   return rval;
25725 }
25726 
25727 
DoesVectorMatchOptions(ClickableItemPtr cip,VectorContaminationOptionsPtr options)25728 static Boolean DoesVectorMatchOptions (ClickableItemPtr cip, VectorContaminationOptionsPtr options)
25729 {
25730   Boolean rval = FALSE;
25731 
25732   if (cip == NULL || options == NULL || StringHasNoText (cip->description)) {
25733     return FALSE;
25734   }
25735 
25736   if (options->internal_level > 0
25737       && StringNICmp (cip->description, "Internal", 8) == 0
25738       && DoesLevelStringMatchLevel (cip->description, options->internal_level)) {
25739     rval = TRUE;
25740   } else if (options->end5_level > 0
25741       && StringNICmp (cip->description, "5'", 2) == 0
25742       && DoesLevelStringMatchLevel (cip->description, options->end5_level)) {
25743     rval = TRUE;
25744   } else if (options->end3_level > 0
25745       && StringNICmp (cip->description, "3'", 2) == 0
25746       && DoesLevelStringMatchLevel (cip->description, options->end3_level)) {
25747     rval = TRUE;
25748   }
25749   return rval;
25750 }
25751 
25752 
GetVectorBioseqList(BioseqPtr bsp,Pointer data)25753 static void GetVectorBioseqList (BioseqPtr bsp, Pointer data)
25754 {
25755   VectorContaminationOptionsPtr options;
25756   SeqFeatPtr                    sfp;
25757   SeqMgrFeatContext             fcontext;
25758   Boolean                       isvector;
25759   GBQualPtr                     gbq;
25760   Int4                          last_right;
25761   ClickableItemPtr              cip = NULL, cip_match;
25762   ValNodePtr                    vector_list = NULL, vnp;
25763   Int4                          desc_len = 0;
25764   Boolean                       is_match = FALSE;
25765 
25766   if (bsp == NULL || data == NULL) {
25767     return;
25768   }
25769 
25770   options = (VectorContaminationOptionsPtr) data;
25771 
25772   for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_IMP, FEATDEF_misc_feature, &fcontext);
25773        sfp != NULL;
25774        sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_IMP, FEATDEF_misc_feature, &fcontext)) {
25775     for (isvector = FALSE, gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
25776       if (StringCmp (gbq->qual, "standard_name") == 0) {
25777         if (StringCmp (gbq->val, "Vector Contamination") == 0) {
25778           isvector = TRUE;
25779         }
25780       }
25781     }
25782     if (isvector) {
25783       if (cip != NULL && last_right >= fcontext.left - 1) {
25784         ValNodeAddPointer (&(cip->item_list), OBJ_SEQFEAT, sfp);
25785         last_right = fcontext.right;
25786       } else {
25787         /* calculate description for previous list */
25788         CalculateVectorDescription (cip);
25789         cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
25790         if (cip != NULL) {
25791           cip->clickable_item_type = 0;
25792           cip->callback_func = NULL;
25793           cip->datafree_func = NULL;
25794           cip->callback_data = NULL;
25795           cip->item_list = NULL;
25796           cip->subcategories = NULL;
25797           cip->expanded = FALSE;
25798           cip->level = 0;
25799           cip->description = NULL;
25800 
25801           ValNodeAddPointer (&(cip->item_list), OBJ_SEQFEAT, sfp);
25802 
25803           ValNodeAddPointer (&vector_list, 0, cip);
25804           last_right = fcontext.right;
25805         }
25806       }
25807     }
25808   }
25809   /* calculate description for last item */
25810   CalculateVectorDescription (cip);
25811 
25812   /* now determine whether we have a hit that matches our requirements */
25813   for (vnp = vector_list; vnp != NULL; vnp = vnp->next) {
25814     cip = vnp->data.ptrvalue;
25815     if (DoesVectorMatchOptions (cip, options)) {
25816       is_match = TRUE;
25817     }
25818     desc_len += StringLen (cip->description) + 2;
25819   }
25820 
25821   if (is_match) {
25822     cip_match = MemNew (sizeof (ClickableItemData));
25823     cip_match->description = (CharPtr) MemNew (sizeof (Char) * desc_len);
25824     cip_match->description[0] = 0;
25825     for (vnp = vector_list; vnp != NULL; vnp = vnp->next) {
25826       cip = vnp->data.ptrvalue;
25827       StringCat (cip_match->description, cip->description);
25828       if (vnp->next != NULL) {
25829         StringCat (cip_match->description, ";");
25830       }
25831     }
25832     ValNodeAddPointer (&(cip_match->item_list), OBJ_BIOSEQ, bsp);
25833     cip_match->chosen = TRUE;
25834     ValNodeAddPointer (&(options->bioseq_list), 0, cip_match);
25835   }
25836   vector_list = FreeClickableList (vector_list);
25837 }
25838 
25839 
ChooseVectorSeqs(Pointer userdata)25840 static void ChooseVectorSeqs (Pointer userdata)
25841 {
25842   SegByFieldPtr sfp = (SegByFieldPtr) userdata;
25843   SeqEntryPtr   sep;
25844   VectorContaminationOptionsPtr options;
25845 
25846   if (sfp == NULL || sfp->target_set == NULL) return;
25847 
25848   WatchCursor();
25849   Update();
25850   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
25851 
25852   PointerToDialog (sfp->group_list_dlg, NULL);
25853   sfp->value_lists = FreeClickableList (sfp->value_lists);
25854 
25855   options = DialogToPointer (sfp->vector_options);
25856 
25857   VisitBioseqsInSep (sep, options, GetVectorBioseqList);
25858 
25859   sfp->value_lists = options->bioseq_list;
25860   options->bioseq_list = NULL;
25861 
25862   options = MemFree (options);
25863 
25864   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
25865   if (sfp->value_lists == NULL) {
25866     Disable(sfp->accept);
25867   } else {
25868     Enable (sfp->accept);
25869   }
25870   ArrowCursor();
25871   Update();
25872 }
25873 
25874 
SeqsByLenCallback(BioseqPtr bsp,Pointer userdata)25875 static void SeqsByLenCallback (BioseqPtr bsp, Pointer userdata)
25876 {
25877   ChooseSeqsByLenPtr p = (ChooseSeqsByLenPtr) userdata;
25878   ClickableItemPtr   cip_match;
25879   CharPtr            fmt = "%s %d";
25880   Char               id_str[45];
25881 
25882   if (bsp == NULL || ISA_aa (bsp->mol) || p == NULL) {
25883     return;
25884   }
25885 
25886   if (bsp->length >= p->min && bsp->length <= p->max) {
25887     cip_match = MemNew (sizeof (ClickableItemData));
25888 
25889     /* create description (use ID and length ) */
25890     SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, sizeof (id_str) - 1);
25891     cip_match->description = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (id_str) + 15));
25892     sprintf (cip_match->description, fmt, id_str, bsp->length);
25893 
25894     ValNodeAddPointer (&(cip_match->item_list), OBJ_BIOSEQ, bsp);
25895     cip_match->chosen = TRUE;
25896     ValNodeAddPointer (&(p->bsp_list), 0, cip_match);
25897   }
25898 }
25899 
25900 
ChooseSeqsByLen(Pointer userdata)25901 static void ChooseSeqsByLen (Pointer userdata)
25902 {
25903   SegByFieldPtr sfp = (SegByFieldPtr) userdata;
25904   SeqEntryPtr   sep;
25905   ChooseSeqsByLenPtr options;
25906 
25907   if (sfp == NULL || sfp->target_set == NULL) return;
25908 
25909   WatchCursor();
25910   Update();
25911   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
25912 
25913   PointerToDialog (sfp->group_list_dlg, NULL);
25914   sfp->value_lists = FreeClickableList (sfp->value_lists);
25915 
25916   options = DialogToPointer (sfp->len_options);
25917 
25918   VisitBioseqsInSep (sep, options, SeqsByLenCallback);
25919 
25920   sfp->value_lists = options->bsp_list;
25921   options->bsp_list = NULL;
25922 
25923   options = MemFree (options);
25924   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
25925   if (sfp->value_lists == NULL) {
25926     Disable(sfp->accept);
25927   } else {
25928     Enable (sfp->accept);
25929   }
25930   ArrowCursor();
25931   Update();
25932 }
25933 
25934 
ChangeMol(ButtoN b)25935 static void ChangeMol (ButtoN b)
25936 {
25937   SegByFieldPtr sfp;
25938   SeqEntryPtr   sep;
25939 
25940   sfp = (SegByFieldPtr) GetObjectExtra (b);
25941 
25942   if (sfp == NULL) return;
25943 
25944   WatchCursor ();
25945   Update();
25946   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
25947 
25948   PointerToDialog (sfp->group_list_dlg, NULL);
25949   sfp->value_lists = FreeClickableList (sfp->value_lists);
25950 
25951   if (GetStatus (sfp->mol_class_btn)) {
25952     VisitBioseqsInSep (sep, &(sfp->value_lists), GetMolClasses);
25953   }
25954   if (GetStatus (sfp->mol_type_btn)) {
25955     VisitDescriptorsInSep (sep, &(sfp->value_lists), GetMolTypes);
25956   }
25957   if (GetStatus (sfp->mol_topology_btn)) {
25958    VisitBioseqsInSep (sep, &(sfp->value_lists), GetMolTopologies);
25959   }
25960 
25961   sfp->value_lists = ChangeUniqueValueListsToSeqEntryLists (sfp->value_lists);
25962 
25963   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
25964   if (ValNodeLen (sfp->value_lists) < 2) {
25965     Disable(sfp->accept);
25966   } else {
25967     Enable (sfp->accept);
25968   }
25969   ArrowCursor();
25970   Update();
25971 }
25972 
25973 
SegFeatureChangeNotify(Pointer userdata)25974 static void SegFeatureChangeNotify (Pointer userdata)
25975 {
25976   SegByFieldPtr sfp = (SegByFieldPtr) userdata;
25977   SeqEntryPtr   sep;
25978   SegFeaturesData sfd;
25979   ClickableItemPtr cip;
25980   ValNodePtr       vnp;
25981   CharPtr          desc_fmt = "%d %ss";
25982 
25983   if (sfp == NULL) return;
25984 
25985   vnp = DialogToPointer (sfp->feature_select);
25986   if (vnp == NULL) {
25987     PointerToDialog (sfp->group_list_dlg, NULL);
25988     sfp->value_lists = FreeClickableList (sfp->value_lists);
25989     Disable (sfp->accept);
25990     return;
25991   }
25992 
25993   WatchCursor ();
25994   Update();
25995   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
25996 
25997   PointerToDialog (sfp->group_list_dlg, NULL);
25998   sfp->value_lists = FreeClickableList (sfp->value_lists);
25999 
26000   sfd.featdef = vnp->choice;
26001   sfd.feature_list = NULL;
26002   VisitFeaturesInSep (sep, &sfd, FindFeaturesForSeg);
26003 
26004   if (sfd.feature_list != NULL) {
26005     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
26006     MemSet (cip, 0, sizeof (ClickableItemData));
26007     cip->description = (CharPtr) MemNew (sizeof(Char) * (StringLen (desc_fmt) + StringLen (vnp->data.ptrvalue) + 15));
26008     sprintf (cip->description, desc_fmt, ValNodeLen (sfd.feature_list), vnp->data.ptrvalue);
26009     cip->item_list = sfd.feature_list;
26010     cip->chosen = TRUE;
26011     ValNodeAddPointer (&(sfp->value_lists), 0, cip);
26012     sfp->value_lists = ChangeUniqueValueListsToSeqEntryLists (sfp->value_lists);
26013   }
26014   vnp = ValNodeFree (vnp);
26015 
26016   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26017 
26018   if (sfp->value_lists == NULL) {
26019     Disable (sfp->accept);
26020   } else {
26021     Enable (sfp->accept);
26022   }
26023   ArrowCursor();
26024   Update();
26025 }
26026 
SegDescriptorChangeNotify(Pointer data)26027 static void SegDescriptorChangeNotify (Pointer data)
26028 {
26029   SegByFieldPtr      sfp;
26030   ValNodePtr         vnp;
26031   SegDescriptorsData sdd;
26032   ClickableItemPtr   cip;
26033   CharPtr            desc_fmt = "%d %ss";
26034   SeqEntryPtr        sep;
26035 
26036   sfp = (SegByFieldPtr) data;
26037   if (sfp == NULL) return;
26038 
26039   vnp = DialogToPointer (sfp->descriptor_select);
26040   if (vnp == NULL) {
26041     PointerToDialog (sfp->group_list_dlg, NULL);
26042     sfp->value_lists = FreeClickableList (sfp->value_lists);
26043     Disable (sfp->accept);
26044     return;
26045   }
26046 
26047   WatchCursor ();
26048   Update();
26049   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
26050 
26051   PointerToDialog (sfp->group_list_dlg, NULL);
26052   sfp->value_lists = FreeClickableList (sfp->value_lists);
26053 
26054   sdd.desc_type = vnp->choice;
26055   sdd.descriptor_list = NULL;
26056   VisitDescriptorsInSep (sep, &sdd, FindDescriptorsForSeg);
26057 
26058   if (sdd.descriptor_list != NULL) {
26059     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
26060     MemSet (cip, 0, sizeof (ClickableItemData));
26061     cip->description = (CharPtr) MemNew (sizeof(Char) * (StringLen (desc_fmt) + StringLen (vnp->data.ptrvalue) + 15));
26062     sprintf (cip->description, desc_fmt, ValNodeLen (sdd.descriptor_list), vnp->data.ptrvalue);
26063     cip->item_list = sdd.descriptor_list;
26064     cip->chosen = TRUE;
26065     ValNodeAddPointer (&(sfp->value_lists), 0, cip);
26066     sfp->value_lists = ChangeUniqueValueListsToSeqEntryLists (sfp->value_lists);
26067   }
26068   vnp = ValNodeFree (vnp);
26069 
26070   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26071 
26072   if (sfp->value_lists == NULL) {
26073     Disable (sfp->accept);
26074   } else {
26075     Enable (sfp->accept);
26076   }
26077   ArrowCursor();
26078   Update();
26079 
26080 }
26081 
ChooseSeqsForNumSets(Pointer data)26082 static void ChooseSeqsForNumSets (Pointer data)
26083 {
26084   SegByFieldPtr      sfp;
26085   SeqEntryPtr        sep;
26086   Int4               num_sets;
26087   CharPtr            str;
26088 
26089   sfp = (SegByFieldPtr) data;
26090   if (sfp == NULL) return;
26091 
26092   str = SaveStringFromText (sfp->num_sets);
26093   if (str == NULL) {
26094     Disable (sfp->accept);
26095     return;
26096   }
26097 
26098   num_sets = atoi (str);
26099   str = MemFree (str);
26100   if (num_sets < 1) {
26101     Disable (sfp->accept);
26102     return;
26103   }
26104 
26105   WatchCursor ();
26106   Update();
26107   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
26108 
26109   PointerToDialog (sfp->group_list_dlg, NULL);
26110   sfp->value_lists = FreeClickableList (sfp->value_lists);
26111 
26112   sfp->value_lists = PrepareSequenceListForSegregateByNumberOfSets (num_sets, sep);
26113 
26114   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26115 
26116   if (sfp->value_lists == NULL) {
26117     Disable (sfp->accept);
26118   } else {
26119     Enable (sfp->accept);
26120   }
26121   ArrowCursor();
26122   Update();
26123 }
26124 
SegNumSetsChange(TexT t)26125 static void SegNumSetsChange (TexT t)
26126 {
26127   SegByFieldPtr sfp;
26128 
26129   sfp = (SegByFieldPtr) GetObjectExtra (t);
26130 
26131   ChooseSeqsForNumSets (sfp);
26132 }
26133 
26134 
GroupSeqByFileCallback(BioseqPtr bsp,Pointer data)26135 static void GroupSeqByFileCallback (BioseqPtr bsp, Pointer data)
26136 {
26137   ValNodePtr PNTR list;
26138   ValNodePtr vnp;
26139   SeqIdPtr   sip;
26140   DbtagPtr   dbtag;
26141   Char       id_buf[15];
26142   CharPtr    id = NULL, last_slash;
26143   ClickableItemPtr cip;
26144   Boolean          found = FALSE;
26145 
26146   if (bsp == NULL || ISA_aa (bsp->mol) || (list = (ValNodePtr PNTR) data) == NULL) {
26147     return;
26148   }
26149 
26150   sip = bsp->id;
26151   while (sip != NULL && !IsNCBIFileID(sip)) {
26152     sip = sip->next;
26153   }
26154 
26155   if (sip != NULL && (dbtag = (DbtagPtr) sip->data.ptrvalue) != NULL) {
26156     if (dbtag->tag->id > 0) {
26157       sprintf (id_buf, "%d", dbtag->tag->id);
26158       id = id_buf;
26159     } else {
26160       id = dbtag->tag->str;
26161     }
26162     id = StringSave (id);
26163     if ((last_slash = StringRChr (id, '/')) != NULL) {
26164       *last_slash = 0;
26165     }
26166     for (vnp = *list; vnp != NULL && !found; vnp = vnp->next) {
26167       cip = (ClickableItemPtr) vnp->data.ptrvalue;
26168       if (cip != NULL && StringCmp (id, cip->description) == 0) {
26169         ValNodeAddPointer (&cip->item_list, OBJ_BIOSEQ, bsp);
26170         found = TRUE;
26171         id = MemFree (id);
26172       }
26173     }
26174     if (!found) {
26175       cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
26176       cip->description = id;
26177       ValNodeAddPointer (&cip->item_list, OBJ_BIOSEQ, bsp);
26178       ValNodeAddPointer (list, 0, cip);
26179     }
26180   }
26181 }
26182 
26183 
ChooseFile(SegByFieldPtr sfp)26184 static void ChooseFile (SegByFieldPtr sfp)
26185 {
26186   SeqEntryPtr        sep;
26187 
26188   if (sfp == NULL) return;
26189 
26190   WatchCursor ();
26191   Update();
26192   sep = SeqMgrGetSeqEntryForData (sfp->target_set);
26193 
26194   PointerToDialog (sfp->group_list_dlg, NULL);
26195   sfp->value_lists = FreeClickableList (sfp->value_lists);
26196 
26197   VisitBioseqsInSep (sep, &(sfp->value_lists), GroupSeqByFileCallback);
26198 
26199   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26200 
26201   if (sfp->value_lists == NULL) {
26202     Disable (sfp->accept);
26203   } else {
26204     Enable (sfp->accept);
26205   }
26206   ArrowCursor();
26207   Update();
26208 }
26209 
26210 
ChangeSegChoice(GrouP g)26211 static void ChangeSegChoice (GrouP g)
26212 {
26213   SegByFieldPtr sfp;
26214   Int4          seg_choice, i;
26215 
26216   sfp = (SegByFieldPtr) GetObjectExtra (g);
26217   if (sfp == NULL) return;
26218 
26219   seg_choice = GetValue (sfp->seg_choice_grp);
26220 
26221     for (i = 0; i < eNumSegPages; i++) {
26222     if (i != seg_choice - 1) {
26223         SafeHide (sfp->pages[i]);
26224       }
26225     }
26226     Update ();
26227 
26228     for (i = 0; i < eNumSegPages; i++) {
26229     if (i == seg_choice - 1) {
26230         SafeShow (sfp->pages[i]);
26231       }
26232     }
26233     Update ();
26234 
26235     switch (seg_choice) {
26236       case eSegPageField:
26237         ChangeSegField (sfp);
26238           break;
26239       case eSegPageMolInfo:
26240         ChangeMol(sfp->mol_class_btn);
26241         break;
26242       case eSegPageFeatureType:
26243         SegFeatureChangeNotify (sfp);
26244         break;
26245     case eSegPageDescriptorType:
26246         SegDescriptorChangeNotify (sfp);
26247         break;
26248     case eSegPageText:
26249         SegTextChangeNotify (sfp);
26250         break;
26251     case eSegPageId:
26252     case eSegPageConstraint:
26253         ChooseSegId (sfp);
26254         break;
26255     case eSegPageVectorContamination:
26256         ChooseVectorSeqs (sfp);
26257         break;
26258     case eSegPageLength:
26259         ChooseSeqsByLen (sfp);
26260         break;
26261     case eSegPageNumFinalSets:
26262         ChooseSeqsForNumSets (sfp);
26263         break;
26264     case eSegPageFile:
26265         ChooseFile(sfp);
26266         break;
26267     case eSegPageStructuredCommentField:
26268         ChangeSegStructuredCommentField (sfp);
26269         break;
26270   }
26271   if (seg_choice == eSegPageId || seg_choice == eSegPageConstraint
26272       || seg_choice == eSegPageVectorContamination || seg_choice == eSegPageLength) {
26273     SetClickableListDialogTitles (sfp->group_list_dlg, "Sequences for New Set", "",
26274                                                        "Use checkbox to mark sequences for new set",
26275                                                        "Single click to navigate to sequence in record");
26276     SetClickableListDisplayChosen (sfp->group_list_dlg, TRUE);
26277   } else {
26278     SetClickableListDialogTitles (sfp->group_list_dlg, "New Sets", "Sequences in Highlighted Set",
26279                                                        "Use checkbox to mark sets to create",
26280                                                        "");
26281     SetClickableListDisplayChosen (sfp->group_list_dlg, FALSE);
26282   }
26283 }
26284 
26285 
ChooseCategories(ValNodePtr value_list,Boolean do_choose)26286 extern void ChooseCategories (ValNodePtr value_list, Boolean do_choose)
26287 {
26288   ClickableItemPtr cip;
26289 
26290   while (value_list != NULL) {
26291     cip = (ClickableItemPtr) value_list->data.ptrvalue;
26292       if (cip != NULL) {
26293         cip->chosen = do_choose;
26294         ChooseCategories (cip->subcategories, FALSE);
26295       }
26296       value_list = value_list->next;
26297   }
26298 }
26299 
26300 
SelectSegCategories(ButtoN b)26301 static void SelectSegCategories (ButtoN b)
26302 {
26303   SegByFieldPtr sfp;
26304 
26305   sfp = (SegByFieldPtr) GetObjectExtra (b);
26306   if (sfp != NULL) {
26307     ChooseCategories (sfp->value_lists, TRUE);
26308     PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26309   }
26310 }
26311 
26312 
UnselectSegCategories(ButtoN b)26313 static void UnselectSegCategories (ButtoN b)
26314 {
26315   SegByFieldPtr sfp;
26316 
26317   sfp = (SegByFieldPtr) GetObjectExtra (b);
26318   if (sfp != NULL) {
26319     ChooseCategories (sfp->value_lists, FALSE);
26320     PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26321   }
26322 }
26323 
26324 
ResortMarkedSegCategories(ButtoN b)26325 static void ResortMarkedSegCategories (ButtoN b)
26326 {
26327   SegByFieldPtr sfp;
26328 
26329   sfp = (SegByFieldPtr) GetObjectExtra (b);
26330   if (sfp != NULL) {
26331     sfp->value_lists = ValNodeSort (sfp->value_lists, SortVnpByClickableItemChosen);
26332     PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26333   }
26334 }
26335 
26336 
SelectSequenceIDsForSegregate(ButtoN b)26337 static void SelectSequenceIDsForSegregate (ButtoN b)
26338 {
26339   SegByFieldPtr       sfp;
26340 
26341   sfp = (SegByFieldPtr) GetObjectExtra (b);
26342   if (sfp == NULL) return;
26343 
26344   ChooseCategoriesForSegregateIdDialog(sfp->id_constraint_dlg, sfp->value_lists);
26345   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26346 }
26347 
26348 
SelectSequenceIDsByConstraintForSegregate(ButtoN b)26349 static void SelectSequenceIDsByConstraintForSegregate (ButtoN b)
26350 {
26351   SegByFieldPtr       sfp;
26352 
26353   sfp = (SegByFieldPtr) GetObjectExtra (b);
26354   if (sfp == NULL) return;
26355 
26356   ChooseCategoriesForSegregateConstraintDialog(sfp->seq_constraint_dlg, sfp->value_lists);
26357   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26358 }
26359 
26360 
UnselectSequenceIdsByConstraintForSegregate(ButtoN b)26361 static void UnselectSequenceIdsByConstraintForSegregate (ButtoN b)
26362 {
26363   SegByFieldPtr       sfp;
26364 
26365   sfp = (SegByFieldPtr) GetObjectExtra (b);
26366   if (sfp == NULL) return;
26367 
26368   UnchooseCategoriesForSegregateConstraintDialog(sfp->seq_constraint_dlg, sfp->value_lists);
26369   PointerToDialog (sfp->group_list_dlg, sfp->value_lists);
26370 }
26371 
26372 
CleanupSegregateByFieldForm(GraphiC g,VoidPtr data)26373 static void CleanupSegregateByFieldForm (GraphiC g, VoidPtr data)
26374 
26375 {
26376   SegByFieldPtr      sfp;
26377 
26378   sfp = (SegByFieldPtr) data;
26379   if (sfp != NULL) {
26380     sfp->value_lists = FreeClickableList (sfp->value_lists);
26381   }
26382   StdCleanupFormProc (g, data);
26383 }
26384 
26385 
CreateSegregateFormMenus(WindoW w)26386 static void CreateSegregateFormMenus (WindoW w)
26387 
26388 {
26389   BaseFormPtr   bfp;
26390   MenU          m;
26391 
26392   bfp = (BaseFormPtr) GetObjectExtra (w);
26393   if (bfp != NULL) {
26394     m = PulldownMenu (w, "File");
26395     FormCommandItem (m, "Accept", bfp, VIB_MSG_ACCEPT);
26396     FormCommandItem (m, "Cancel", bfp, VIB_MSG_CLOSE);
26397   }
26398 }
26399 
SegregateFormMessage(ForM f,Int2 mssg)26400 static void SegregateFormMessage (ForM f, Int2 mssg)
26401 {
26402   SegByFieldPtr frm;
26403 
26404   frm = (SegByFieldPtr) GetObjectExtra (f);
26405   if (frm != NULL) {
26406     switch (mssg) {
26407       case VIB_MSG_ACCEPT :
26408         frm->actn(frm->accept);
26409         break;
26410       case VIB_MSG_CLOSE:
26411         Remove ((WindoW)(frm->form));
26412         break;
26413       default :
26414         break;
26415     }
26416   }
26417 }
26418 
26419 
NewSegregateBioseqSet(BioseqSetPtr bssp,Nlm_BtnActnProc actn,ESegPage default_type,CharPtr title)26420 static Int2 NewSegregateBioseqSet (BioseqSetPtr bssp, Nlm_BtnActnProc actn, ESegPage default_type, CharPtr title)
26421 {
26422   GrouP              c;
26423   SegByFieldPtr      cfp;
26424   GrouP              h, k, page_grp, g1, g2, g3;
26425   PrompT             p, p2;
26426   StdEditorProcsPtr  sepp;
26427   WindoW             w;
26428   ButtoN             b;
26429 
26430 
26431   /* Create a new window, and a struct */
26432   /* to pass around the data in.       */
26433 
26434   cfp = (SegByFieldPtr) MemNew (sizeof (SegByFieldData));
26435   if (cfp == NULL)
26436     return OM_MSG_RET_ERROR;
26437   cfp->target_set = bssp;
26438   cfp->actn = actn;
26439 
26440   w = FixedWindow (-50, -33, -10, -10, title,
26441            StdCloseWindowProc);
26442   SetObjectExtra (w, cfp, CleanupSegregateByFieldForm);
26443   cfp->form = (ForM) w;
26444 
26445   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
26446   if (sepp != NULL) {
26447     SetActivate (w, sepp->activateForm);
26448     cfp->appmessage = sepp->handleMessages;
26449   }
26450 
26451   cfp->input_entityID = bssp->idx.entityID;
26452   cfp->input_itemID = bssp->idx.itemID;
26453   cfp->input_itemtype = OBJ_BIOSEQSET;
26454   cfp->formmessage = SegregateFormMessage;
26455 
26456   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
26457   if (sepp != NULL) {
26458     SetActivate (w, sepp->activateForm);
26459     cfp->appmessage = sepp->handleMessages;
26460   }
26461 
26462   h = HiddenGroup (w, -1, 0, NULL);
26463   SetGroupSpacing (h, 10, 10);
26464 
26465   cfp->group_list_dlg = CreateClickableListDialogEx (h, "New Sets", "Sequences for New Set",
26466                                                       "Use checkbox to mark sets to create",
26467                                                       "",
26468                                                       ScrollToDiscrepancyItem, EditDiscrepancyItem, NULL,
26469                                                       GetDiscrepancyItemText,
26470                                                       stdCharWidth * 30,
26471                                                       stdCharWidth * 30 + 5,
26472                                                       TRUE, FALSE);
26473 
26474   g3 = NormalGroup (h, 2, 0, "", programFont, NULL);
26475   SetGroupSpacing (g3, 10, 10);
26476   StaticPrompt (g3, "Segregate Based on", 0, dialogTextHeight, programFont, 'c');
26477   cfp->seg_choice_grp = HiddenGroup (g3, eNumSegPages, 0, ChangeSegChoice);
26478   SetObjectExtra (cfp->seg_choice_grp, cfp, NULL);
26479   SetGroupSpacing (cfp->seg_choice_grp, 10, 10);
26480 
26481   RadioButton (cfp->seg_choice_grp, "ID");
26482   RadioButton (cfp->seg_choice_grp, "Text");
26483   RadioButton (cfp->seg_choice_grp, "Field");
26484   RadioButton (cfp->seg_choice_grp, "MolInfo");
26485   RadioButton (cfp->seg_choice_grp, "Feature Type");
26486   RadioButton (cfp->seg_choice_grp, "Descriptor Type");
26487   RadioButton (cfp->seg_choice_grp, "Nucleotide Sequence Length");
26488   RadioButton (cfp->seg_choice_grp, "Vector Contamination");
26489   RadioButton (cfp->seg_choice_grp, "Number of Sets");
26490   RadioButton (cfp->seg_choice_grp, "File Name");
26491   RadioButton (cfp->seg_choice_grp, "Constraint");
26492   RadioButton (cfp->seg_choice_grp, "Structured Comment Field");
26493 
26494   page_grp = HiddenGroup (h, 0, 0, NULL);
26495   /* identical fields */
26496   cfp->pages[eSegPageField - 1] = HiddenGroup (page_grp, 2, 0, NULL);
26497   SetGroupSpacing (cfp->pages[eSegPageField - 1], 10, 10);
26498   p = StaticPrompt (cfp->pages[eSegPageField - 1], "Segregate sequences with identical", 0, dialogTextHeight,
26499                     programFont, 'c');
26500   cfp->field_dlg = ParseFieldDestDialog (cfp->pages[eSegPageField - 1], ChangeSegField, cfp);
26501 
26502   /* molinfo */
26503   cfp->pages[eSegPageMolInfo - 1] = HiddenGroup (page_grp, 0, 4, NULL);
26504   SetGroupSpacing (cfp->pages[eSegPageMolInfo - 1], 10, 10);
26505   cfp->mol_class_btn = CheckBox (cfp->pages[eSegPageMolInfo - 1], "Molecule Class", ChangeMol);
26506   SetObjectExtra (cfp->mol_class_btn, cfp, NULL);
26507   SetStatus (cfp->mol_class_btn, TRUE);
26508   cfp->mol_type_btn = CheckBox (cfp->pages[eSegPageMolInfo - 1], "Molecule Type", ChangeMol);
26509   SetObjectExtra (cfp->mol_type_btn, cfp, NULL);
26510   SetStatus (cfp->mol_type_btn, TRUE);
26511   cfp->mol_topology_btn = CheckBox (cfp->pages[eSegPageMolInfo - 1], "Molecule Topology", ChangeMol);
26512   SetObjectExtra (cfp->mol_topology_btn, cfp, NULL);
26513   SetStatus (cfp->mol_topology_btn, TRUE);
26514 
26515   /* features */
26516   cfp->pages[eSegPageFeatureType - 1] = HiddenGroup (page_grp, 2, 0, NULL);
26517   SetGroupSpacing (cfp->pages[eSegPageFeatureType - 1], 10, 10);
26518   StaticPrompt (cfp->pages[eSegPageFeatureType - 1], "Segregate by Feature", 0, dialogTextHeight,
26519                 programFont, 'c');
26520   cfp->feature_select =  FeatureSelectionDialogEx (cfp->pages[eSegPageFeatureType - 1], FALSE, NULL,
26521                                                    SegFeatureChangeNotify,
26522                                                    cfp);
26523 
26524   /* descriptors */
26525   cfp->pages[eSegPageDescriptorType - 1] = HiddenGroup (page_grp, 2, 0, NULL);
26526   SetGroupSpacing (cfp->pages[eSegPageDescriptorType - 1], 10, 10);
26527   StaticPrompt (cfp->pages[eSegPageDescriptorType - 1], "Segregate by Descriptor", 0, dialogTextHeight,
26528                 programFont, 'c');
26529   cfp->descriptor_select = DescriptorSelectionDialog (cfp->pages[eSegPageDescriptorType - 1], FALSE,
26530                                                       SegDescriptorChangeNotify, cfp);
26531 
26532   /* text */
26533   cfp->pages[eSegPageText - 1] = HiddenGroup (page_grp, 4, 0, NULL);
26534   SetGroupSpacing (cfp->pages[eSegPageText - 1], 10, 10);
26535   StaticPrompt (cfp->pages[eSegPageText - 1], "Create set with sequences where", 0, dialogTextHeight, programFont, 'l');
26536   cfp->search_text = DialogText (cfp->pages[eSegPageText - 1], "", 10, SegTextChange);
26537   SetObjectExtra (cfp->search_text, cfp, NULL);
26538   StaticPrompt (cfp->pages[eSegPageText - 1], "appears in", 0, dialogTextHeight, programFont, 'l');
26539   cfp->search_field = SearchFieldDialog (cfp->pages[eSegPageText - 1], SegTextChangeNotify, cfp);
26540 
26541   /* id */
26542   cfp->pages[eSegPageId - 1] = HiddenGroup (page_grp, -1, 0, NULL);
26543   SetGroupSpacing (cfp->pages[eSegPageId - 1], 10, 10);
26544   p2 = StaticPrompt (cfp->pages[eSegPageId - 1], "Create set with marked sequences", 0, dialogTextHeight, programFont, 'l');
26545   g1 = HiddenGroup (cfp->pages[eSegPageId - 1], 3, 0, NULL);
26546   g2 = HiddenGroup (cfp->pages[eSegPageId - 1], 2, 0, NULL);
26547   cfp->id_constraint_dlg = SegregateIdDialog (g2);
26548   b = PushButton (g2, "Mark", SelectSequenceIDsForSegregate);
26549   SetObjectExtra (b, cfp, NULL);
26550   AlignObjects (ALIGN_CENTER, (HANDLE) p2, (HANDLE) g1, (HANDLE) g2, NULL);
26551 
26552   /* length */
26553   cfp->pages[eSegPageLength - 1] = HiddenGroup (page_grp, -1, 0, NULL);
26554   SetGroupSpacing (cfp->pages[eSegPageLength - 1], 10, 10);
26555   cfp->len_options = ChooseSeqsByLenDialog (cfp->pages[eSegPageLength - 1], ChooseSeqsByLen, cfp);
26556 
26557   /* vector contamination */
26558   cfp->pages[eSegPageVectorContamination - 1] = HiddenGroup (page_grp, -1, 0, NULL);
26559   SetGroupSpacing (cfp->pages[eSegPageVectorContamination - 1], 10, 10);
26560   cfp->vector_options = VectorContaminationOptionsDialog (cfp->pages[eSegPageVectorContamination - 1], ChooseVectorSeqs, cfp);
26561 
26562   /* number of sets */
26563   cfp->pages[eSegPageNumFinalSets - 1] = HiddenGroup (page_grp, 2, 0, NULL);
26564   SetGroupSpacing (cfp->pages[eSegPageNumFinalSets - 1], 10, 10);
26565   StaticPrompt (cfp->pages[eSegPageNumFinalSets - 1], "Number of sets to create", 0, dialogTextHeight, programFont, 'l');
26566   cfp->num_sets = DialogText (cfp->pages[eSegPageNumFinalSets - 1], "", 10, SegNumSetsChange);
26567   SetObjectExtra (cfp->num_sets, cfp, NULL);
26568 
26569   /* don't need controls for File */
26570   cfp->pages[eSegPageFile - 1] = NULL;
26571 
26572   /* constraint */
26573   cfp->pages[eSegPageConstraint- 1] = HiddenGroup (page_grp, -1, 0, NULL);
26574   SetGroupSpacing (cfp->pages[eSegPageConstraint - 1], 10, 10);
26575   p2 = StaticPrompt (cfp->pages[eSegPageConstraint - 1], "Create set with marked sequences", 0, dialogTextHeight, programFont, 'l');
26576   g1 = HiddenGroup (cfp->pages[eSegPageConstraint - 1], 2, 0, NULL);
26577   cfp->seq_constraint_dlg = SegregateConstraintDialog (g1);
26578   g2 = HiddenGroup (g1, 0, 2, NULL);
26579   SetGroupSpacing (g2, 10, 10);
26580   b = PushButton (g2, "Mark", SelectSequenceIDsByConstraintForSegregate);
26581   SetObjectExtra (b, cfp, NULL);
26582   b = PushButton (g2, "Unmark", UnselectSequenceIdsByConstraintForSegregate);
26583   SetObjectExtra (b, cfp, NULL);
26584   AlignObjects (ALIGN_CENTER, (HANDLE) p2, (HANDLE) g1, NULL);
26585 
26586   cfp->pages[eSegPageStructuredCommentField - 1] = HiddenGroup (page_grp, 2, 0, NULL);
26587   SetGroupSpacing (cfp->pages[eSegPageStructuredCommentField - 1], 10, 10);
26588   StaticPrompt (cfp->pages[eSegPageStructuredCommentField - 1], "Choose Structured Comment Field Name", 0, dialogTextHeight, programFont, 'l');
26589   cfp->struc_comm_field = ValNodeSelectionDialog (cfp->pages[eSegPageStructuredCommentField - 1],
26590                                                   GetStructuredCommentFieldNames(SeqMgrGetSeqEntryForData(bssp)),
26591                                                   8, ValNodeStringName, ValNodeSimpleDataFree,
26592                                                   ValNodeStringCopy, ValNodeStringMatch, "fieldname",
26593                                                   ChangeSegStructuredCommentField, cfp, FALSE);
26594 
26595   AlignObjects (ALIGN_CENTER, (HANDLE) cfp->pages[0],
26596                                 (HANDLE) cfp->pages[1],
26597                                 (HANDLE) cfp->pages[2],
26598                               (HANDLE) cfp->pages[3],
26599                               (HANDLE) cfp->pages[4],
26600                               (HANDLE) cfp->pages[5],
26601                               (HANDLE) cfp->pages[6],
26602                               (HANDLE) cfp->pages[7],
26603                               (HANDLE) cfp->pages[8],
26604                               (HANDLE) cfp->pages[9],
26605                               (HANDLE) cfp->pages[10],
26606                               (HANDLE) cfp->pages[11],
26607                               (HANDLE) cfp->pages[12],
26608                               NULL);
26609 
26610   SetValue (cfp->seg_choice_grp, default_type);
26611 
26612   /* add select all/unselect all buttons */
26613   k = HiddenGroup (h, 3, 0, NULL);
26614   b = PushButton (k, "Mark All", SelectSegCategories);
26615   SetObjectExtra (b, cfp, NULL);
26616   b = PushButton (k, "Unmark All", UnselectSegCategories);
26617   SetObjectExtra (b, cfp, NULL);
26618   b = PushButton (k, "Resort Marked", ResortMarkedSegCategories);
26619   SetObjectExtra (b, cfp, NULL);
26620 
26621   /* Add Accept and Cancel buttons */
26622 
26623   c = HiddenGroup (h, 3, 0, NULL);
26624   cfp->accept = DefaultButton (c, "Accept", actn);
26625   SetObjectExtra (cfp->accept, cfp, NULL);
26626   Disable (cfp->accept);
26627   PushButton (c, "Cancel", StdCancelButtonProc);
26628   cfp->leave_dlg_up = CheckBox (c, "Leave Dialog Up", NULL);
26629 
26630   /* Line things up nicely */
26631 
26632   AlignObjects (ALIGN_CENTER, (HANDLE) g3,
26633                               (HANDLE) cfp->group_list_dlg,
26634                               (HANDLE) page_grp,
26635                               (HANDLE) k,
26636                               (HANDLE) c, NULL);
26637 
26638   /* initialize the display */
26639   ChangeSegChoice (cfp->seg_choice_grp);
26640 
26641   /* Display the window now */
26642   CreateSegregateFormMenus(w);
26643   RealizeWindow (w);
26644   Show (w);
26645   Select (w);
26646   Select (cfp->accept);
26647   Update ();
26648   return OM_MSG_RET_OK;
26649 }
26650 
SegregateSetsByFieldEx(Pointer data,Nlm_BtnActnProc actn,ESegPage default_type,CharPtr title)26651 static Int2 LIBCALLBACK SegregateSetsByFieldEx (Pointer data, Nlm_BtnActnProc actn, ESegPage default_type, CharPtr title)
26652 {
26653   OMProcControlPtr   ompcp;
26654 
26655   /* Check parameters and get a pointer to the current data */
26656 
26657   ompcp = (OMProcControlPtr) data;
26658   if (ompcp == NULL
26659       || ompcp->input_itemtype != OBJ_BIOSEQSET
26660       || ompcp->input_data == NULL) {
26661     Message (MSG_ERROR, "You must select a set to segregate!");
26662     return OM_MSG_RET_ERROR;
26663   }
26664   return NewSegregateBioseqSet (ompcp->input_data, actn, default_type, title);
26665 }
26666 
26667 
SegregateSetsByField(Pointer data)26668 extern Int2 LIBCALLBACK SegregateSetsByField (Pointer data)
26669 {
26670   return SegregateSetsByFieldEx (data, SegregateByField_Callback, eSegPageText, "Segregate Sets");
26671 }
26672 
26673 
SegregateBioseqSetEntityID(Uint2 entityID)26674 NLM_EXTERN void SegregateBioseqSetEntityID (Uint2 entityID)
26675 {
26676   SeqEntryPtr sep;
26677 
26678   sep = GetTopSeqEntryForEntityID (entityID);
26679   if (sep == NULL || !IS_Bioseq_set (sep)) {
26680     Message (MSG_ERROR, "This record does not have a top-levelset!");
26681   } else {
26682     NewSegregateBioseqSet (FindTopLevelSetForDesktopFunction((BioseqSetPtr) sep->data.ptrvalue), SegregateByField_Callback, eSegPageText, "Segregate Sets");
26683   }
26684 }
26685 
26686 
NewSegregateBioseqSetMenuItem(IteM i)26687 extern void NewSegregateBioseqSetMenuItem (IteM i)
26688 {
26689   BaseFormPtr bfp;
26690 
26691 #ifdef WIN_MAC
26692   bfp = currentFormDataPtr;
26693 #else
26694   bfp = GetObjectExtra (i);
26695 #endif
26696   if (bfp == NULL) return;
26697 
26698   SegregateBioseqSetEntityID (bfp->input_entityID);
26699 }
26700 
26701 
26702 typedef struct unsequester{
26703   SeqEntryPtr  sep;
26704   BioseqSetPtr orig_parent;
26705   Int4         set_pos;
26706 } UnsequesterData, PNTR UnsequesterPtr;
26707 
26708 
UnsequesterNew(SeqEntryPtr sep,BioseqSetPtr parent,Int4 set_pos)26709 static UnsequesterPtr UnsequesterNew (SeqEntryPtr sep, BioseqSetPtr parent, Int4 set_pos)
26710 {
26711   UnsequesterPtr u;
26712 
26713   u = (UnsequesterPtr) MemNew (sizeof (UnsequesterData));
26714   u->sep = sep;
26715   u->orig_parent = parent;
26716   u->set_pos = set_pos;
26717   return u;
26718 }
26719 
26720 
GetUnsequesterForSep(SeqEntryPtr sep,ValNodePtr list)26721 static UnsequesterPtr GetUnsequesterForSep (SeqEntryPtr sep, ValNodePtr list)
26722 {
26723   UnsequesterPtr u;
26724 
26725   while (list != NULL) {
26726     if ((u = list->data.ptrvalue) != NULL && u->sep == sep) {
26727       return u;
26728     } else {
26729       list = list->next;
26730     }
26731   }
26732   return NULL;
26733 }
26734 
26735 
26736 static ValNodePtr unsequester_list = NULL;
26737 
26738 static BioseqSetPtr sequester_set = NULL;
26739 static const CharPtr SEQUESTER_BACKUP_FILE = "sequestr.bkp";
26740 static Boolean doReportAfterUnsequester = 0;
26741 
SetDoReportAfterUnsequester(Int4 report_type)26742 NLM_EXTERN void SetDoReportAfterUnsequester (Int4 report_type)
26743 {
26744   doReportAfterUnsequester = report_type;
26745 }
26746 
26747 
26748 static const CharPtr placeholder_id_string = "ABCDEFGHIJKLMNOPQRSTUVWXYZMagicCookiePlaceHolderABCDEFGHIJKLMNOPQRSTUVWXYZ";
26749 
PlaceholderBioseq(void)26750 static BioseqPtr PlaceholderBioseq (void)
26751 {
26752   BioseqPtr bsp;
26753   ObjectIdPtr oip;
26754 
26755   oip = ObjectIdNew ();
26756   oip->str = StringSave (placeholder_id_string);
26757   bsp = BioseqNew ();
26758   bsp->id = ValNodeNew (NULL);
26759   bsp->id->choice = SEQID_LOCAL;
26760   bsp->id->data.ptrvalue = oip;
26761   return bsp;
26762 }
26763 
26764 
IsPlaceholderBioseq(BioseqPtr bsp)26765 static Boolean IsPlaceholderBioseq (BioseqPtr bsp)
26766 {
26767   ObjectIdPtr oip;
26768 
26769   if (bsp == NULL || bsp->id == NULL
26770       || bsp->id->choice != SEQID_LOCAL
26771       || (oip = (ObjectIdPtr) bsp->id->data.ptrvalue) == NULL
26772       || StringCmp (oip->str, placeholder_id_string) != 0) {
26773     return FALSE;
26774   } else {
26775     return TRUE;
26776   }
26777 }
26778 
26779 
26780 /* sequesters is different from segregate - we aren't creating a permanent new set with
26781  * the combined descriptors of the previous set; we're creating a temporary holding set.
26782  */
SequesterCategorySeqEntries(BioseqSetPtr newset,ClickableItemPtr category)26783 static void SequesterCategorySeqEntries (BioseqSetPtr newset, ClickableItemPtr category)
26784 {
26785   ValNodePtr vnp_item;
26786   SeqEntryPtr sep, last_sep, prev_sep, remove_sep, set_sep, tmp_sep;
26787   BioseqSetPtr bssp, orig_parent, prev_new_parent = NULL, prev_orig_parent = NULL;
26788   BioseqPtr bsp;
26789   Int4      set_pos;
26790 
26791   if (newset == NULL || category == NULL || (category->item_list == NULL && category->subcategories == NULL)) return;
26792 
26793   if (category->chosen) {
26794     last_sep = newset->seq_set;
26795     while (last_sep != NULL && last_sep->next != NULL) {
26796       last_sep = last_sep->next;
26797     }
26798 
26799     for (vnp_item = category->item_list; vnp_item != NULL; vnp_item = vnp_item->next) {
26800       sep = GetBestSeqEntryForItem (vnp_item);
26801       if (sep == NULL || sep->data.ptrvalue == NULL) continue;
26802       orig_parent = NULL;
26803       if (IS_Bioseq (sep)) {
26804         bsp = sep->data.ptrvalue;
26805         if (bsp->idx.parenttype == OBJ_BIOSEQSET) {
26806           orig_parent = bsp->idx.parentptr;
26807           bsp->idx.parentptr = NULL;
26808         }
26809       } else if (IS_Bioseq_set (sep)) {
26810         bssp = sep->data.ptrvalue;
26811         if (bssp->idx.parenttype == OBJ_BIOSEQSET) {
26812           orig_parent = bssp->idx.parentptr;
26813           bssp->idx.parentptr = NULL;
26814         }
26815       } else {
26816         continue;
26817       }
26818 
26819       if (orig_parent == NULL) {
26820         continue;
26821       }
26822 
26823       /* remove this seq-entry from the original parent */
26824       prev_sep = NULL;
26825       set_pos = 0;
26826       for (remove_sep = orig_parent->seq_set;
26827             remove_sep != NULL && remove_sep != sep;
26828             remove_sep = remove_sep->next) {
26829         prev_sep = remove_sep;
26830         set_pos++;
26831       }
26832       if (remove_sep == sep) {
26833         if (prev_sep == NULL) {
26834           orig_parent->seq_set = orig_parent->seq_set->next;
26835           if (orig_parent->seq_set == NULL) {
26836             orig_parent->seq_set = SeqEntryNew ();
26837             orig_parent->seq_set->choice = 1;
26838             orig_parent->seq_set->data.ptrvalue = PlaceholderBioseq();
26839             SeqMgrLinkSeqEntry (orig_parent->seq_set, OBJ_BIOSEQSET, orig_parent);
26840           }
26841         } else {
26842           prev_sep->next = sep->next;
26843         }
26844         sep->next = NULL;
26845       }
26846 
26847       /* if this seq-entry is from the same parent as the previous one, just add this to
26848        * our current placeholder.
26849        */
26850       if (prev_orig_parent != orig_parent) {
26851         prev_new_parent = BioseqSetNew ();
26852         prev_new_parent->_class = orig_parent->_class;
26853         /* add descriptors from the orig_parent to the new parent */
26854         AddNewUniqueDescriptors (&(prev_new_parent->descr), orig_parent->descr);
26855 
26856         /* add annotations from the orig_parent to the new parent */
26857         AddNewUniqueAnnotations (&(prev_new_parent->annot), orig_parent->annot);
26858 
26859         /* add new parent to set */
26860         set_sep = SeqEntryNew ();
26861         set_sep->choice = 2;
26862         set_sep->data.ptrvalue = prev_new_parent;
26863 
26864         if (newset->seq_set == NULL) {
26865           newset->seq_set = set_sep;
26866         } else {
26867           for (tmp_sep = newset->seq_set; tmp_sep->next != NULL; tmp_sep = tmp_sep->next) {
26868           }
26869           tmp_sep->next = set_sep;
26870         }
26871         SeqMgrLinkSeqEntry (set_sep, OBJ_BIOSEQSET, newset);
26872         last_sep = NULL;
26873       }
26874       /* add seqentry to new parent */
26875       if (last_sep == NULL) {
26876         prev_new_parent->seq_set = sep;
26877       } else {
26878         last_sep->next = sep;
26879       }
26880       last_sep = sep;
26881 
26882       SeqMgrLinkSeqEntry (sep, OBJ_BIOSEQSET, prev_new_parent);
26883 
26884       /* create unsequester entry */
26885       ValNodeAddPointer (&unsequester_list, 0, UnsequesterNew (sep, orig_parent, set_pos));
26886 
26887       prev_orig_parent = orig_parent;
26888     }
26889   } else {
26890     for (vnp_item = category->subcategories; vnp_item != NULL; vnp_item = vnp_item->next) {
26891       SequesterCategorySeqEntries (newset, vnp_item->data.ptrvalue);
26892     }
26893   }
26894 }
26895 
26896 
RestoreSequesteredSets(ForM f)26897 static void RestoreSequesteredSets (ForM f)
26898 {
26899   Uint2 new_entityID;
26900   BaseFormPtr bfp;
26901   BioseqViewFormPtr vfp;
26902 
26903   bfp = GetBaseFormForEntityID (sequester_set->idx.entityID);
26904   if (bfp == NULL) {
26905     return;
26906   }
26907   SequinSeqViewFormMessage (f, VIB_MSG_CLOSE);
26908 
26909   new_entityID = RestoreEntityIDFromFile (SEQUESTER_BACKUP_FILE, bfp->input_entityID);
26910   if (new_entityID != 0) {
26911     bfp->input_entityID = new_entityID;
26912     ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
26913     ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
26914   }
26915   Show (bfp->form);
26916   vfp = (BioseqViewFormPtr) bfp;
26917   Show (vfp->toolForm);
26918 
26919   sequester_set = NULL;
26920 }
26921 
26922 
IsSeqDescInSet(SeqDescrPtr sdp,SeqDescrPtr set)26923 static Boolean IsSeqDescInSet (SeqDescrPtr sdp, SeqDescrPtr set)
26924 {
26925   while (set != NULL) {
26926     if (AsnIoMemComp (sdp, set, (AsnWriteFunc) SeqDescAsnWrite)) {
26927       return TRUE;
26928     } else {
26929       set = set->next;
26930     }
26931   }
26932   return FALSE;
26933 }
26934 
PropagateToSeqEntryIfNotDup(SeqEntryPtr sep,SeqDescrPtr sdp)26935 static SeqDescrPtr PropagateToSeqEntryIfNotDup (SeqEntryPtr sep, SeqDescrPtr sdp)
26936 {
26937   BioseqPtr    bsp;
26938   BioseqSetPtr bssp;
26939   SeqDescrPtr  new_sdp = NULL;
26940 
26941   if (sep != NULL && sep->data.ptrvalue != NULL) {
26942     if (IS_Bioseq (sep)) {
26943       bsp = (BioseqPtr) sep->data.ptrvalue;
26944       if (!IsSeqDescInSet (sdp, bsp->descr)) {
26945         new_sdp = AsnIoMemCopy ((Pointer) sdp,
26946                                 (AsnReadFunc) SeqDescrAsnRead,
26947                                 (AsnWriteFunc) SeqDescrAsnWrite);
26948         ValNodeLink (&(bsp->descr), new_sdp);
26949       }
26950     } else if (IS_Bioseq_set (sep)) {
26951       bssp = (BioseqSetPtr) sep->data.ptrvalue;
26952       if (!IsSeqDescInSet (sdp, bssp->descr)) {
26953         new_sdp = AsnIoMemCopy ((Pointer) sdp,
26954                                 (AsnReadFunc) SeqDescrAsnRead,
26955                                 (AsnWriteFunc) SeqDescrAsnWrite);
26956         ValNodeLink (&(bssp->descr), new_sdp);
26957       }
26958     }
26959   }
26960   return new_sdp;
26961 }
26962 
26963 
AddSepBackToSet(SeqEntryPtr add_back_sep,BioseqSetPtr bssp,SeqDescrPtr parent_descriptors,Int4 set_pos)26964 static void AddSepBackToSet (SeqEntryPtr add_back_sep, BioseqSetPtr bssp, SeqDescrPtr parent_descriptors, Int4 set_pos)
26965 {
26966   ObjMgrDataPtr  omdptop;
26967   ObjMgrData     omdata;
26968   Uint2          parenttype;
26969   Pointer        parentptr;
26970   SeqEntryPtr    sep, prev, tmp;
26971   SeqDescrPtr    sdp, new_sdp, sdp_tmp;
26972   ObjValNodePtr  ovp, new_ovp;
26973   Boolean        found;
26974   Int4           pos;
26975   BioseqPtr      bsp;
26976 
26977   /* any descriptors currently on bssp that are not in parent_descriptors must be propagated */
26978   /* mark parent descriptor as found, so we don't add it again */
26979   for (sdp = bssp->descr; sdp != NULL; sdp = sdp->next) {
26980     if (sdp->extended == 0) {
26981       continue;
26982     }
26983     /* don't copy set titles */
26984     if (sdp->choice == Seq_descr_title) {
26985       continue;
26986     }
26987     ovp = (ObjValNodePtr) sdp;
26988     found = FALSE;
26989     for (new_sdp = parent_descriptors; new_sdp != NULL && !found; new_sdp = new_sdp->next) {
26990       if (new_sdp->extended == 0) {
26991         continue;
26992       }
26993       new_ovp = (ObjValNodePtr) new_sdp;
26994       if (new_ovp->idx.deleteme) {
26995         continue;
26996       }
26997       if (AsnIoMemComp (sdp, new_sdp, (AsnWriteFunc) SeqDescAsnWrite)) {
26998         found = TRUE;
26999         new_ovp->idx.deleteme = TRUE;
27000       }
27001     }
27002     if (!found) {
27003       /* propagate descriptor to members of bssp */
27004       sdp_tmp = sdp->next;
27005       sdp->next = NULL;
27006       for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
27007         PropagateToSeqEntryIfNotDup (sep, sdp);
27008       }
27009       sdp->next = sdp_tmp;
27010       ovp->idx.deleteme = TRUE;
27011     }
27012   }
27013   /* now add any parent descriptors that weren't marked to the contents of add_back_sep
27014    * (and unmark those that were marked) */
27015   for (new_sdp = parent_descriptors; new_sdp != NULL; new_sdp = new_sdp->next) {
27016     if (new_sdp->extended == 0) {
27017       continue;
27018     }
27019     new_ovp = (ObjValNodePtr) new_sdp;
27020     if (new_ovp->idx.deleteme) {
27021       new_ovp->idx.deleteme = FALSE;
27022     } else {
27023       /* add to added_back_sep */
27024       PropagateToSeqEntryIfNotDup (add_back_sep, new_sdp);
27025     }
27026   }
27027 
27028   /* mark placeholders in destination set for removal */
27029   for (tmp = bssp->seq_set; tmp != NULL; tmp = tmp->next) {
27030     if (IS_Bioseq (tmp) && (bsp = tmp->data.ptrvalue) != NULL && IsPlaceholderBioseq (bsp)) {
27031       bsp->idx.deleteme = TRUE;
27032     }
27033   }
27034 
27035   sep = SeqMgrGetSeqEntryForData (bssp);
27036   SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
27037   GetSeqEntryParent (sep, &parentptr, &parenttype);
27038   prev = NULL;
27039   pos = 0;
27040   for (tmp = bssp->seq_set; tmp != NULL && pos < set_pos; tmp = tmp->next) {
27041     prev = tmp;
27042     pos++;
27043   }
27044   if (prev == NULL) {
27045     add_back_sep->next = bssp->seq_set;
27046     bssp->seq_set = add_back_sep;
27047   } else {
27048     add_back_sep->next = tmp;
27049     prev->next = add_back_sep;
27050   }
27051   SeqMgrLinkSeqEntry (add_back_sep, OBJ_BIOSEQSET, bssp);
27052 
27053   SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
27054   RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
27055 }
27056 
27057 
ReintegrateSequesteredSets(Uint2 entityID)27058 static void ReintegrateSequesteredSets (Uint2 entityID)
27059 {
27060   BaseFormPtr bfp;
27061   BioseqViewFormPtr vfp;
27062   SeqEntryPtr new_parent_sep, sep, add_back_sep, next_sep;
27063   BioseqSetPtr   top_bssp, bssp;
27064   UnsequesterPtr u;
27065 
27066   add_back_sep = GetTopSeqEntryForEntityID (entityID);
27067   if (!IS_Bioseq_set (add_back_sep)) {
27068     return;
27069   }
27070   bfp = GetBaseFormForEntityID (entityID);
27071   RemoveSeqEntryViewer (bfp->form);
27072 
27073   /* remove any popset titles created */
27074   RemovePopsetTitles (add_back_sep);
27075 
27076   /* we created a genbank set to hold the actual parent sets */
27077   top_bssp = (BioseqSetPtr) add_back_sep->data.ptrvalue;
27078 
27079  /* propagate any other descriptors that ended up on the top-level set
27080    * (like cit-sub-updates)
27081    */
27082   SetDescriptorPropagate(top_bssp);
27083 
27084   /* need to process entries in seq_set in reverse, so that the set_pos will be
27085    * correct relative to when the seq-entry was removed */
27086   ValNodeReverse (&(top_bssp->seq_set));
27087   new_parent_sep = top_bssp->seq_set;
27088 
27089   while (new_parent_sep != NULL) {
27090     bssp = new_parent_sep->data.ptrvalue;
27091     ValNodeReverse (&(bssp->seq_set));
27092     sep = bssp->seq_set;
27093 
27094     while (sep != NULL) {
27095       next_sep = sep->next;
27096       sep->next = NULL;
27097       u = GetUnsequesterForSep (sep, unsequester_list);
27098       if (u == NULL || u->orig_parent == NULL) {
27099         AddSepBackToSet (sep, sequester_set, bssp->descr, 0);
27100       } else {
27101         AddSepBackToSet (sep, u->orig_parent, bssp->descr, u->set_pos);
27102       }
27103       sep = next_sep;
27104     }
27105     bssp->seq_set = NULL;
27106     new_parent_sep = new_parent_sep->next;
27107   }
27108 
27109   ObjMgrDelete (OBJ_SEQENTRY, add_back_sep);
27110   top_bssp->seq_set = NULL;
27111   top_bssp->idx.deleteme = TRUE;
27112   DeleteMarkedObjects (entityID, 0, NULL);
27113 
27114   sep = GetTopSeqEntryForEntityID (sequester_set->idx.entityID);
27115   DeleteMarkedObjects (sequester_set->idx.entityID, 0, NULL);
27116   ObjMgrSetDirtyFlag (sequester_set->idx.entityID, TRUE);
27117   ObjMgrSendMsg (OM_MSG_UPDATE, sequester_set->idx.entityID, 0, 0);
27118 
27119   bfp = GetBaseFormForEntityID (sequester_set->idx.entityID);
27120   if (bfp != NULL) {
27121     Show (bfp->form);
27122     vfp = (BioseqViewFormPtr) bfp;
27123     Show (vfp->toolForm);
27124   }
27125 
27126 }
27127 
27128 
FinishedSequester(void)27129 static void FinishedSequester (void)
27130 {
27131   sequester_set = NULL;
27132   unsequester_list = ValNodeFreeData (unsequester_list);
27133   FileRemove(SEQUESTER_BACKUP_FILE);
27134   if (doReportAfterUnsequester > 0) {
27135     CreateReportWindow (doReportAfterUnsequester);
27136     doReportAfterUnsequester = 0;
27137   }
27138 }
27139 
27140 
SequesterShutdown(ForM f)27141 static void SequesterShutdown (ForM f)
27142 {
27143   MsgAnswer     ans;
27144   BaseFormPtr   bfp;
27145 
27146   bfp = (BaseFormPtr) GetObjectExtra (f);
27147   if (bfp != NULL) {
27148     ans = Message (MSG_YNC, "Accept changes and add sequences back to original set?  Hit No to continue working, Cancel to restore original set");
27149     if (ans == ANS_YES) {
27150       ReintegrateSequesteredSets (bfp->input_entityID);
27151       FinishedSequester();
27152     } else if (ans == ANS_CANCEL) {
27153       RestoreSequesteredSets (f);
27154       FinishedSequester();
27155     }
27156   }
27157 }
27158 
27159 
SequesterFormMessage(ForM f,Int2 mssg)27160 static void SequesterFormMessage (ForM f, Int2 mssg)
27161 
27162 {
27163   BaseFormPtr   bfp;
27164 
27165   bfp = (BaseFormPtr) GetObjectExtra (f);
27166   if (bfp != NULL) {
27167     switch (mssg) {
27168       case VIB_MSG_CLOSE :
27169       case VIB_MSG_QUIT :
27170       case VIB_MSG_ACCEPT :
27171         SequesterShutdown (f);
27172         break;
27173       default:
27174         SequinSeqViewFormMessage (f, mssg);
27175         break;
27176     }
27177   }
27178 }
27179 
27180 
SequesterSets(ButtoN b)27181 static void SequesterSets (ButtoN b)
27182 {
27183   SegByFieldPtr sfp;
27184   Int4          num_chosen = 0;
27185   ValNodePtr       vnp;
27186   ClickableItemPtr cip;
27187   Int2             val;
27188   SeqEntryPtr      top_sep, pulled_sep;
27189   BioseqSetPtr     new_set;
27190   ObjMgrDataPtr  omdptop;
27191   ObjMgrData     omdata;
27192   Uint2          parenttype;
27193   Pointer        parentptr;
27194   Uint2          entityID;
27195   FormMessageFunc old_message_handler;
27196   BaseFormPtr     bfp;
27197   BioseqViewFormPtr vfp;
27198 
27199   sfp = (SegByFieldPtr) GetObjectExtra (b);
27200   if (sfp == NULL) return;
27201 
27202   if (unsequester_list != NULL || sequester_set != NULL) {
27203     Message (MSG_ERROR, "You are already sequestering a set.  You cannot sequester until you have restored these sequences to the original set.");
27204     return;
27205   }
27206 
27207   WriteTheEntityID (sfp->input_entityID, SEQUESTER_BACKUP_FILE, FALSE);
27208 
27209   num_chosen = CountChosenDiscrepancies (sfp->value_lists, FALSE);
27210   if (num_chosen < 1) {
27211     if (ANS_OK == Message (MSG_OKC, "You have not chosen any groups.  Create all?")) {
27212       ChooseAllDiscrepancies (sfp->value_lists);
27213     } else {
27214       return;
27215     }
27216   }
27217 
27218   val = GetValue (sfp->seg_choice_grp);
27219   if (val == eSegPageId || val == eSegPageVectorContamination || val == eSegPageLength) {
27220     /* put all selected sequences into one group */
27221     cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
27222     cip->chosen = TRUE;
27223     PullChosenIntoOneGroup (&(sfp->value_lists), cip);
27224     ValNodeAddPointer (&(sfp->value_lists), 0, cip);
27225   }
27226 
27227   sequester_set = sfp->target_set;
27228 
27229   /* create a new set with just the chosen sequences */
27230   top_sep = SeqMgrGetSeqEntryForData (sfp->target_set);
27231   SaveSeqEntryObjMgrData (top_sep, &omdptop, &omdata);
27232   GetSeqEntryParent (top_sep, &parentptr, &parenttype);
27233 
27234   new_set = BioseqSetNew ();
27235   new_set->_class = BioseqseqSet_class_genbank;
27236 
27237   for (vnp = sfp->value_lists; vnp != NULL; vnp = vnp->next) {
27238     cip = (ClickableItemPtr) vnp->data.ptrvalue;
27239     if (cip == NULL || (!cip->chosen && ! AnyDiscrepanciesChosen (cip->subcategories))) {
27240       continue;
27241     }
27242 
27243     /* add SeqEntries for this category here */
27244     SequesterCategorySeqEntries (new_set, cip);
27245 
27246   }
27247 
27248   RestoreSeqEntryObjMgrData (top_sep, omdptop, &omdata);
27249   DeleteMarkedObjects (sfp->input_entityID, 0, NULL);
27250   ObjMgrSetDirtyFlag (sfp->input_entityID, TRUE);
27251   ObjMgrSendMsg (OM_MSG_UPDATE, sfp->input_entityID, 0, 0);
27252 
27253   pulled_sep = SeqEntryNew ();
27254   pulled_sep->choice = 2;
27255   pulled_sep->data.ptrvalue = new_set;
27256   SeqMgrLinkSeqEntry (pulled_sep, 0, NULL);
27257 
27258   entityID = ObjMgrRegister (OBJ_SEQENTRY, pulled_sep);
27259   seqviewprocs.filepath = NULL;
27260   seqviewprocs.forceSeparateViewer = TRUE;
27261   old_message_handler = seqviewprocs.handleMessages;
27262   seqviewprocs.handleMessages = SequesterFormMessage;
27263 
27264 
27265   SeqEntrySetScope (NULL);
27266   GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
27267                               OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
27268 
27269   seqviewprocs.handleMessages = old_message_handler;
27270 
27271   /* hide viewer with the remaining sequences */
27272   bfp = GetBaseFormForEntityID (sfp->input_entityID);
27273   if (bfp != NULL) {
27274     Hide (bfp->form);
27275     vfp = (BioseqViewFormPtr) bfp;
27276     Hide (vfp->toolForm);
27277   }
27278 
27279   if (GetStatus (sfp->leave_dlg_up)) {
27280     ChangeSegChoice (sfp->seg_choice_grp);
27281   } else {
27282     Remove (sfp->form);
27283   }
27284 }
27285 
OkToSequester(void)27286 NLM_EXTERN Boolean OkToSequester (void)
27287 {
27288   if (unsequester_list != NULL || sequester_set != NULL) {
27289     return FALSE;
27290   } else {
27291     return TRUE;
27292   }
27293 }
27294 
27295 
SequesterClickableItem(Uint2 entityID,ClickableItemPtr cip)27296 NLM_EXTERN Uint2 SequesterClickableItem (Uint2 entityID, ClickableItemPtr cip)
27297 {
27298   SeqEntryPtr sep;
27299   BioseqSetPtr bssp, new_set;
27300   ObjMgrDataPtr  omdptop;
27301   ObjMgrData     omdata;
27302   Uint2          parenttype;
27303   Pointer        parentptr;
27304   Uint2          new_entityID;
27305   FormMessageFunc old_message_handler;
27306   BaseFormPtr     bfp;
27307   BioseqViewFormPtr vfp;
27308   SeqEntryPtr       pulled_sep;
27309 
27310   if (unsequester_list != NULL || sequester_set != NULL) {
27311     Message (MSG_ERROR, "You are already sequestering a set.  You cannot sequester until you have restored these sequences to the original set.");
27312     return 0;
27313   }
27314 
27315   sep = GetTopSeqEntryForEntityID (entityID);
27316   if (sep == NULL || !IS_Bioseq_set (sep)) {
27317     Message (MSG_ERROR, "This record does not have a top-levelset!");
27318     return 0;
27319   }
27320 
27321   bssp = FindTopLevelSetForDesktopFunction((BioseqSetPtr) sep->data.ptrvalue);
27322   if (bssp == NULL) {
27323     Message (MSG_ERROR, "Unable to find top level set");
27324     return 0;
27325   }
27326 
27327   WriteTheEntityID (entityID, SEQUESTER_BACKUP_FILE, FALSE);
27328   sequester_set = bssp;
27329 
27330   /* create a new set with just the chosen sequences */
27331   SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
27332   GetSeqEntryParent (sep, &parentptr, &parenttype);
27333 
27334   new_set = BioseqSetNew ();
27335   new_set->_class = BioseqseqSet_class_genbank;
27336 
27337   SequesterCategorySeqEntries (new_set, cip);
27338 
27339   RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
27340   DeleteMarkedObjects (entityID, 0, NULL);
27341   ObjMgrSetDirtyFlag (entityID, TRUE);
27342   ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
27343 
27344   pulled_sep = SeqEntryNew ();
27345   pulled_sep->choice = 2;
27346   pulled_sep->data.ptrvalue = new_set;
27347   SeqMgrLinkSeqEntry (pulled_sep, 0, NULL);
27348 
27349   new_entityID = ObjMgrRegister (OBJ_SEQENTRY, pulled_sep);
27350   seqviewprocs.filepath = NULL;
27351   seqviewprocs.forceSeparateViewer = TRUE;
27352   old_message_handler = seqviewprocs.handleMessages;
27353   seqviewprocs.handleMessages = SequesterFormMessage;
27354 
27355 
27356   SeqEntrySetScope (NULL);
27357   GatherProcLaunch (OMPROC_VIEW, FALSE, new_entityID, 1,
27358                               OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
27359 
27360   seqviewprocs.handleMessages = old_message_handler;
27361 
27362   /* hide viewer with the remaining sequences */
27363   bfp = GetBaseFormForEntityID (entityID);
27364   if (bfp != NULL) {
27365     Hide (bfp->form);
27366     vfp = (BioseqViewFormPtr) bfp;
27367     Hide (vfp->toolForm);
27368   }
27369   return new_entityID;
27370 }
27371 
27372 
SequesterSequenceList(Uint2 entityID,ValNodePtr bsp_list)27373 NLM_EXTERN void LIBCALLBACK SequesterSequenceList (Uint2 entityID, ValNodePtr bsp_list)
27374 {
27375   ClickableItemData cid;
27376   Uint2          new_entityID;
27377   BaseFormPtr     bfp;
27378 
27379   if (bsp_list == NULL) {
27380     return;
27381   }
27382 
27383   MemSet (&cid, 0, sizeof (ClickableItemData));
27384   cid.chosen = TRUE;
27385   cid.item_list = bsp_list;
27386   if ((new_entityID = SequesterClickableItem (entityID, &cid)) > 0) {
27387     /* get rid of existing validator window, replace with validator for new sequences */
27388     FreeValidateWindow ();
27389     bfp = GetBaseFormForEntityID (new_entityID);
27390     ValSeqEntryForm (bfp->form);
27391   }
27392 }
27393 
27394 
SequesterSequences(Pointer data)27395 extern Int2 LIBCALLBACK SequesterSequences (Pointer data)
27396 {
27397   /* note - in future, will need to make sequester dialog modal. */
27398   return SegregateSetsByFieldEx (data, SequesterSets, eSegPageId, "Sequester Sets");
27399 }
27400 
27401 
SequesterSequencesEntityID(Uint2 entityID)27402 extern void SequesterSequencesEntityID (Uint2 entityID)
27403 {
27404   SeqEntryPtr sep;
27405 
27406   sep = GetTopSeqEntryForEntityID (entityID);
27407   if (sep == NULL || !IS_Bioseq_set (sep)) {
27408     Message (MSG_ERROR, "This record does not have a top-level set!");
27409   } else {
27410     NewSegregateBioseqSet (FindTopLevelSetForDesktopFunction((BioseqSetPtr) sep->data.ptrvalue), SequesterSets, eSegPageId, "Sequester Sets");
27411   }
27412 }
27413 
27414 
SequesterSequencesMenuItem(IteM i)27415 extern void SequesterSequencesMenuItem (IteM i)
27416 {
27417   BaseFormPtr bfp;
27418 
27419 #ifdef WIN_MAC
27420   bfp = currentFormDataPtr;
27421 #else
27422   bfp = GetObjectExtra (i);
27423 #endif
27424   if (bfp == NULL) return;
27425 
27426   SequesterSequencesEntityID (bfp->input_entityID);
27427 }
27428 
27429 
SegregateSequenceList(Uint2 entityID,ValNodePtr bsp_list)27430 NLM_EXTERN void LIBCALLBACK SegregateSequenceList (Uint2 entityID, ValNodePtr bsp_list)
27431 {
27432   SeqEntryPtr sep;
27433   BioseqSetPtr bssp;
27434   ClickableItemData cid;
27435   ValNodePtr list = NULL;
27436 
27437   if (bsp_list == NULL) {
27438     return;
27439   }
27440 
27441   sep = GetTopSeqEntryForEntityID (entityID);
27442   if (sep == NULL || !IS_Bioseq_set (sep)) {
27443     Message (MSG_ERROR, "This record does not have a top-level set!");
27444     return;
27445   }
27446 
27447   bssp = FindTopLevelSetForDesktopFunction((BioseqSetPtr) sep->data.ptrvalue);
27448   if (bssp == NULL) {
27449     Message (MSG_ERROR, "Unable to find top level set");
27450     return;
27451   }
27452 
27453   MemSet (&cid, 0, sizeof (ClickableItemData));
27454   cid.item_list = bsp_list;
27455   cid.chosen = TRUE;
27456   ValNodeAddPointer (&list, 0, &cid);
27457 
27458   MakeGroupsForUniqueValues (bssp, list);
27459   list = ValNodeFree (list);
27460 }
27461 
27462 
FormatBoxColumn(ColPtr col)27463 static void FormatBoxColumn (ColPtr col)
27464 {
27465   if (col == NULL) return;
27466   col->pixWidth = stdCharWidth;
27467   col->pixInset = 0;
27468   col->charWidth = 0;
27469   col->charInset = 0;
27470   col->font = NULL;
27471   col->just = 'l';
27472   col->wrap = 1;
27473   col->bar = 0;
27474   col->underline = 0;
27475   col->left = 0;
27476   col->last = FALSE;
27477 }
27478 
AllocateDocColumnsForFieldList(BulkEdFieldPtr field_list,Int4Ptr p_len,Int4 last_sorted_col,Int4 display_offset,Int4 columns_shown)27479 static ColPtr AllocateDocColumnsForFieldList (BulkEdFieldPtr field_list, Int4Ptr p_len, Int4 last_sorted_col, Int4 display_offset, Int4 columns_shown)
27480 {
27481   Int4   i, num_columns = 4, len = 0, col;
27482   ColPtr col_list;
27483 
27484   if (field_list == NULL) {
27485     return NULL;
27486   }
27487 
27488   /* set the font so that the pixwidth will be correct */
27489   SelectFont (programFont);
27490 
27491   /* start with 3 columns, one for expand/collapse and one for checkbox for row selection, one for right scroll, and one for final blank */
27492   for (i = 0; field_list[i].name != NULL; i++) {
27493     num_columns ++;
27494   }
27495   col_list = (ColPtr) MemNew (num_columns * sizeof (ColData));
27496   col = 0;
27497   FormatBoxColumn (col_list + col);
27498   len += col_list[col].pixWidth;
27499   col++;
27500 
27501   for (i = 0; field_list[i].name != NULL; i++) {
27502     if (i < display_offset) {
27503       continue;
27504     } else if (i >= display_offset + columns_shown) {
27505       break;
27506     }
27507     if (i == last_sorted_col) {
27508       FormatBoxColumn (col_list + col);
27509       len += col_list[col].pixWidth;
27510       col++;
27511     }
27512     len += (field_list[i].format_col_func) (col_list + col, field_list[i].name);
27513     col_list[col].last = FALSE;
27514     col++;
27515   }
27516 
27517   /* right scroll */
27518   FormatBoxColumn (col_list + col);
27519   len += col_list[col].pixWidth;
27520   col++;
27521 
27522   /* final blank column */
27523   col_list[col].pixWidth = 0;
27524   col_list[col].pixInset = 0;
27525   col_list[col].charWidth = 0;
27526   col_list[col].charInset = 0;
27527   col_list[col].font = NULL;
27528   col_list[col].just = 'l';
27529   col_list[col].wrap = 1;
27530   col_list[col].bar = 0;
27531   col_list[col].underline = 0;
27532   col_list[col].left = 0;
27533   col_list[col].last = TRUE;
27534   if (p_len != NULL) {
27535     *p_len = len;
27536   }
27537   return col_list;
27538 }
27539 
27540 typedef struct bulkeditorrow {
27541   ValNodePtr values_list;
27542   ValNodePtr object_list;
27543   struct bulkeditorrow PNTR subrows;
27544   Int4       copied_to_meta;
27545   Int4       copied_to_sub;
27546   Boolean    expanded;
27547   Boolean    selected;
27548 } BulkEditorRowData, PNTR BulkEditorRowPtr;
27549 
FreeBulkEditorValues(ValNodePtr values,BulkEdFieldPtr field_list)27550 static ValNodePtr FreeBulkEditorValues (ValNodePtr values, BulkEdFieldPtr field_list)
27551 {
27552   ValNodePtr       vnp;
27553   Int4             col;
27554 
27555   for (col = 0, vnp = values;
27556        vnp != NULL;
27557        col++, vnp = vnp->next) {
27558     if (field_list[col].free_func == NULL) {
27559       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
27560     } else {
27561       (field_list[col].free_func) (vnp->data.ptrvalue);
27562       vnp->data.ptrvalue = NULL;
27563     }
27564   }
27565   values = ValNodeFree (values);
27566   return values;
27567 }
27568 
FreeBulkEditorValuesList(ValNodePtr PNTR values_list,Int4 num_rows,BulkEdFieldPtr field_list)27569 static void FreeBulkEditorValuesList (ValNodePtr PNTR values_list, Int4 num_rows, BulkEdFieldPtr field_list)
27570 {
27571   Int4             i;
27572 
27573   if (values_list == NULL || field_list == NULL) return;
27574   for (i = 0; i < num_rows; i++) {
27575     values_list[i] = FreeBulkEditorValues (values_list[i], field_list);
27576   }
27577   values_list = MemFree (values_list);
27578 }
27579 
FreeBulkEditorRows(BulkEditorRowPtr rows,BulkEdFieldPtr field_list)27580 static BulkEditorRowPtr FreeBulkEditorRows (BulkEditorRowPtr rows, BulkEdFieldPtr field_list)
27581 {
27582   Int4 row_num;
27583 
27584   if (rows == NULL) return NULL;
27585   for (row_num = 0; rows[row_num].object_list != NULL; row_num++) {
27586     rows[row_num].values_list = FreeBulkEditorValues (rows[row_num].values_list, field_list);
27587     rows[row_num].object_list = ValNodeFree (rows[row_num].object_list);
27588     FreeBulkEditorRows (rows[row_num].subrows, field_list);
27589     rows[row_num].subrows = NULL;
27590   }
27591   rows = MemFree (rows);
27592   return rows;
27593 }
27594 
27595 
CopyToSingleBulkEditRow(BulkEditorRowPtr dst,BulkEditorRowPtr src,BulkEdFieldPtr field_list)27596 static void CopyToSingleBulkEditRow (BulkEditorRowPtr dst, BulkEditorRowPtr src, BulkEdFieldPtr field_list)
27597 {
27598   ValNodePtr vnp;
27599   Int4       col;
27600 
27601   if (dst == NULL || src == NULL) return;
27602 
27603   /* copy values */
27604   dst->values_list = NULL;
27605   for (vnp = src->values_list, col = 0; vnp != NULL; vnp = vnp->next, col++) {
27606     ValNodeAddPointer (&(dst->values_list), vnp->choice, field_list[col].copy_func(vnp->data.ptrvalue));
27607   }
27608 
27609   /* copy object */
27610   dst->object_list = NULL;
27611   ValNodeAddPointer (&(dst->object_list), src->object_list->choice, src->object_list->data.ptrvalue);
27612 
27613   /* copy selection */
27614   dst->selected = src->selected;
27615 }
27616 
27617 
ExpandAllBulkEditRows(BulkEditorRowPtr row_list)27618 static void ExpandAllBulkEditRows (BulkEditorRowPtr row_list)
27619 {
27620   Int4 row_num;
27621 
27622   if (row_list == NULL) return;
27623   for (row_num = 0; row_list[row_num].object_list != NULL; row_num++) {
27624     if (row_list[row_num].subrows != NULL) {
27625       row_list[row_num].expanded = TRUE;
27626     }
27627   }
27628 }
27629 
CollapseAllBulkEditRows(BulkEditorRowPtr row_list)27630 static void CollapseAllBulkEditRows (BulkEditorRowPtr row_list)
27631 {
27632   Int4 row_num;
27633 
27634   if (row_list == NULL) return;
27635   for (row_num = 0; row_list[row_num].object_list != NULL; row_num++) {
27636     if (row_list[row_num].subrows != NULL) {
27637       row_list[row_num].expanded = FALSE;
27638     }
27639   }
27640 }
27641 
27642 
27643 /* sort_col is zero-based data column, already corrected for selection and expansion columns */
GetTextForBulkEditorRow(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,Int4 sort_col,Int4 display_offset,Int4 columns_shown)27644 static CharPtr GetTextForBulkEditorRow (BulkEditorRowPtr berp, BulkEdFieldPtr field_list, Int4 sort_col, Int4 display_offset, Int4 columns_shown)
27645 {
27646   ValNodePtr column_values = NULL, vnp;
27647   Int4 text_len = 6, col;
27648   CharPtr str, line_text = NULL, tmp_str;
27649 
27650   if (berp == NULL) return NULL;
27651   for (vnp = berp->values_list, col = 0; vnp != NULL; vnp = vnp->next, col++) {
27652     if (col < display_offset) {
27653       continue;
27654     } else if (col >= display_offset + columns_shown) {
27655       break;
27656     }
27657     if (field_list[col].display_func == NULL) {
27658       str = NULL;
27659     } else {
27660       str = (field_list[col].display_func)(vnp->data.ptrvalue);
27661     }
27662     if (str == NULL) {
27663       str = StringSave ("");
27664     }
27665     if (berp->subrows != NULL && col == sort_col) {
27666       tmp_str = (CharPtr) MemNew (sizeof (Char) * (18 + StringLen (str)));
27667       sprintf (tmp_str, "%s%s(%d)", field_list[col].draw_col_func == NULL ? "" : " ",
27668                                     str, ValNodeLen (berp->object_list));
27669       str = MemFree (str);
27670       str = tmp_str;
27671     }
27672     ValNodeAddPointer (&column_values, 0, str);
27673     text_len += StringLen (str) + 1;
27674   }
27675   line_text = (CharPtr) MemNew (text_len * sizeof (Char));
27676   line_text[0] = 0;
27677   /* add blank column for row selector */
27678   StringCat (line_text, "\t");
27679   for (vnp = column_values, col = display_offset; vnp != NULL; vnp = vnp->next, col++) {
27680     if (col == sort_col) {
27681       /* add blank column for expand/collapse */
27682       StringCat (line_text, "\t");
27683     }
27684     StringCat (line_text, vnp->data.ptrvalue);
27685     StringCat (line_text, "\t");
27686   }
27687   column_values = ValNodeFreeData (column_values);
27688   /* add blank column at end, to allow last real column to be highlighted when blank */
27689   StringCat (line_text, "\t\n");
27690   return line_text;
27691 }
27692 
27693 
DataPosFromBulkEdDlgRow(Int2 row,BulkEditorRowPtr row_list,Int4Ptr pRowNum,Int4Ptr pSubNum)27694 static Boolean DataPosFromBulkEdDlgRow (Int2 row, BulkEditorRowPtr row_list, Int4Ptr pRowNum, Int4Ptr pSubNum)
27695 {
27696   Int4 row_num = 0, sub_num;
27697   Int2 display_row = 1;
27698 
27699   if (row < 1 || row_list == NULL || pRowNum == NULL || pSubNum == NULL) return FALSE;
27700 
27701   while (row_list[row_num].object_list != NULL) {
27702     if (display_row == row) {
27703       *pRowNum = row_num;
27704       *pSubNum = -1;
27705       return TRUE;
27706     }
27707     display_row++;
27708     if (row_list[row_num].subrows != NULL && row_list[row_num].expanded) {
27709       sub_num = 0;
27710       while (display_row != row && row_list[row_num].subrows[sub_num].object_list != NULL) {
27711         display_row++;
27712         sub_num++;
27713       }
27714       if (row_list[row_num].subrows[sub_num].object_list == NULL) {
27715         sub_num = -1;
27716       } else {
27717         if (display_row == row) {
27718           *pRowNum = row_num;
27719           *pSubNum = sub_num;
27720           return TRUE;
27721         }
27722       }
27723     }
27724     row_num++;
27725   }
27726   *pRowNum = -1;
27727   *pSubNum = -1;
27728   return FALSE;
27729 }
27730 
27731 
BulkEdDlgRowFromDataPos(Int4 row_num,Int4 sub_num,BulkEditorRowPtr row_list)27732 static Int4 BulkEdDlgRowFromDataPos (Int4 row_num, Int4 sub_num, BulkEditorRowPtr row_list)
27733 {
27734   Int4 i, j, display_row = 1;
27735 
27736   if (row_list == NULL) return 0;
27737   /* count subrows also passed */
27738   for (i = 0; row_list[i].object_list != NULL && i < row_num; i++) {
27739     display_row++;
27740     if (row_list[i].subrows != NULL && row_list[i].expanded) {
27741       for (j = 0; row_list[i].subrows[j].object_list != NULL; j++) {
27742         display_row++;
27743       }
27744     }
27745   }
27746   if (sub_num > -1) {
27747     display_row += sub_num + 1;
27748   }
27749   return display_row;
27750 }
27751 
27752 
BulkEdDataColumnFromDocColumn(Int4 doc_col,Int4 sort_col,Int4 display_offset)27753 static Int4 BulkEdDataColumnFromDocColumn (Int4 doc_col, Int4 sort_col, Int4 display_offset)
27754 {
27755   /* subtract offset (document maps first column to 1) */
27756   doc_col--;
27757   /* subtract selection column */
27758   doc_col--;
27759 
27760   /* skip over columns not shown */
27761   doc_col += display_offset;
27762 
27763   /* subtract expand/collapse column */
27764   if (doc_col > sort_col && sort_col >= display_offset) {
27765     doc_col--;
27766   }
27767   return doc_col;
27768 }
27769 
27770 
GetBulkEditorRowValueByColumn(BulkEditorRowPtr berp,Int4 col)27771 static ValNodePtr GetBulkEditorRowValueByColumn (BulkEditorRowPtr berp, Int4 col)
27772 {
27773   Int4       i;
27774   ValNodePtr vnp;
27775 
27776   if (col < 0) return NULL;
27777 
27778   for (i = 0, vnp = berp->values_list;
27779        i < col && vnp != NULL;
27780        i++, vnp = vnp->next) {}
27781   return vnp;
27782 }
27783 
27784 
SelectBulkEditorRows(BulkEditorRowPtr berp,Boolean val)27785 static void SelectBulkEditorRows (BulkEditorRowPtr berp, Boolean val)
27786 {
27787   if (berp == NULL) return;
27788 
27789   while (berp->object_list != NULL) {
27790     berp->selected = val;
27791     SelectBulkEditorRows (berp->subrows, val);
27792     berp++;
27793   }
27794 }
27795 
27796 
CountBulkEditorRowsSelected(BulkEditorRowPtr berp)27797 static Int4 CountBulkEditorRowsSelected (BulkEditorRowPtr berp)
27798 {
27799   Int4 num = 0;
27800   if (berp == NULL) return 0;
27801 
27802   while (berp->object_list != NULL) {
27803     if (berp->subrows == NULL) {
27804       if (berp->selected) {
27805         num++;
27806       }
27807     } else {
27808       num+= CountBulkEditorRowsSelected (berp->subrows);
27809     }
27810     berp++;
27811   }
27812   return num;
27813 }
27814 
27815 
GetBulkEditorSelectedObjects(BulkEditorRowPtr berp,ValNodePtr PNTR object_list)27816 static void GetBulkEditorSelectedObjects (BulkEditorRowPtr berp, ValNodePtr PNTR object_list)
27817 {
27818   ValNodePtr vnp;
27819   if (berp == NULL || object_list == NULL) return;
27820 
27821   while (berp->object_list != NULL) {
27822     if (berp->subrows == NULL) {
27823       if (berp->selected) {
27824         for (vnp = berp->object_list; vnp != NULL; vnp = vnp->next) {
27825           ValNodeAddPointer (object_list, vnp->choice, vnp->data.ptrvalue);
27826         }
27827       }
27828     } else {
27829       GetBulkEditorSelectedObjects (berp->subrows, object_list);
27830     }
27831     berp++;
27832   }
27833 }
27834 
27835 
AllBulkEditorRowsSelected(BulkEditorRowPtr berp)27836 static Boolean AllBulkEditorRowsSelected (BulkEditorRowPtr berp)
27837 {
27838   if (berp == NULL) return FALSE;
27839 
27840   while (berp->object_list != NULL) {
27841     /* note - don't need to check subrows, because metarow would
27842      * have been unselected if any subrows were unselected */
27843     if (!berp->selected) {
27844       return FALSE;
27845     }
27846     berp++;
27847   }
27848   return TRUE;
27849 }
27850 
27851 
SelectBulkEditorRowsByStringConstraint(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,Int4 col,StringConstraintXPtr scp,Boolean val)27852 static void SelectBulkEditorRowsByStringConstraint (BulkEditorRowPtr berp, BulkEdFieldPtr field_list, Int4 col, StringConstraintXPtr scp, Boolean val)
27853 {
27854   ValNodePtr vnp;
27855   CharPtr    str = NULL;
27856   Boolean    match;
27857 
27858   if (berp == NULL || field_list == NULL || col < 0 || field_list[col].display_func == NULL) return;
27859 
27860   while (berp->object_list != NULL) {
27861     if (berp->subrows == NULL) {
27862       vnp = GetBulkEditorRowValueByColumn (berp, col);
27863       if (vnp != NULL) {
27864         str = field_list[col].display_func(vnp->data.ptrvalue);
27865       }
27866       match = DoesStringMatchConstraintX (str, scp);
27867       str = MemFree (str);
27868       if (scp != NULL && scp->not_present) {
27869         match = !match;
27870       }
27871       if (match) {
27872         berp->selected = val;
27873       }
27874     } else {
27875       SelectBulkEditorRowsByStringConstraint (berp->subrows, field_list, col, scp, val);
27876       berp->selected = AllBulkEditorRowsSelected (berp->subrows);
27877     }
27878     berp++;
27879   }
27880 }
27881 
27882 
27883 /* call nulls and null values bigger */
27884 /* return 0 if a and b are equal, -1 if a is smaller, and 1 if b is smaller */
CompareBulkRowValues(Pointer val_a,Pointer val_b,BulkDisplayFieldFunc display_func)27885 static Int4 CompareBulkRowValues (Pointer val_a, Pointer val_b, BulkDisplayFieldFunc display_func)
27886 {
27887   CharPtr str_a, str_b;
27888   Int4    rval = 0;
27889 
27890   if (val_a == NULL && val_b == NULL) {
27891     rval = 0;
27892   } else if (val_a == NULL) {
27893     rval = 1;
27894   } else if (val_b == NULL) {
27895     rval = -1;
27896   } else if (display_func == NULL) {
27897     rval = 0;
27898   } else {
27899     str_a = display_func(val_a);
27900     str_b = display_func(val_b);
27901     rval = StringCmp (str_a, str_b);
27902   }
27903   return rval;
27904 }
27905 
27906 /* call nulls and null values bigger */
27907 /* return 0 if a and b are equal, -1 if a is smaller, and 1 if b is smaller */
CompareBulkRows(BulkEditorRowPtr row_a,BulkEditorRowPtr row_b,Int4 sort_column,BulkEdFieldPtr field_list)27908 static Int4 CompareBulkRows (BulkEditorRowPtr row_a, BulkEditorRowPtr row_b, Int4 sort_column, BulkEdFieldPtr field_list)
27909 {
27910   Int4 col;
27911   ValNodePtr vnp_a, vnp_b;
27912   Int4 rval = 0;
27913 
27914   if (row_a == NULL && row_b == NULL) {
27915     rval = 0;
27916   } else if (row_a == NULL) {
27917     rval = 1;
27918   } else if (row_b == NULL) {
27919     rval = -1;
27920   } else if (row_a->values_list == NULL && row_b->values_list == NULL) {
27921     rval = 0;
27922   } else if (row_a->values_list == NULL) {
27923     rval = 1;
27924   } else if (row_b->values_list == NULL) {
27925     rval = -1;
27926   } else {
27927     col = 0;
27928     vnp_a = GetBulkEditorRowValueByColumn (row_a, sort_column);
27929     vnp_b = GetBulkEditorRowValueByColumn (row_b, sort_column);
27930 
27931     if (vnp_a == NULL && vnp_b == NULL) {
27932       rval = 0;
27933     } else if (vnp_a == NULL) {
27934       rval = 1;
27935     } else if (vnp_b == NULL) {
27936       rval = -1;
27937     } else {
27938       rval = CompareBulkRowValues (vnp_a->data.ptrvalue, vnp_b->data.ptrvalue, field_list[sort_column].display_func);
27939     }
27940   }
27941   return rval;
27942 }
27943 
CountIndividualRows(BulkEditorRowPtr row_list)27944 static Int4 CountIndividualRows (BulkEditorRowPtr row_list)
27945 {
27946   Int4 num_rows = 0, row_num;
27947 
27948   if (row_list == NULL) return 0;
27949 
27950   for (row_num = 0; row_list[row_num].object_list != NULL; row_num++) {
27951     if (row_list[row_num].subrows == NULL) {
27952       num_rows++;
27953     } else {
27954       num_rows += CountIndividualRows(row_list[row_num].subrows);
27955     }
27956   }
27957   return num_rows;
27958 }
27959 
27960 
SetDefaultCopiedToValues(BulkEditorRowPtr row_list)27961 static void SetDefaultCopiedToValues (BulkEditorRowPtr row_list)
27962 {
27963   Int4 row_num;
27964 
27965   if (row_list == NULL) return;
27966 
27967   for (row_num = 0; row_list[row_num].object_list != NULL; row_num++) {
27968     row_list[row_num].copied_to_meta = -1;
27969     row_list[row_num].copied_to_sub = -1;
27970     if (row_list[row_num].subrows != NULL) {
27971       SetDefaultCopiedToValues(row_list[row_num].subrows);
27972     }
27973   }
27974 }
27975 
27976 
SummarizeOneSubrowSet(BulkEditorRowPtr row,Int4 last_sorted_col)27977 static void SummarizeOneSubrowSet (BulkEditorRowPtr row, Int4 last_sorted_col)
27978 {
27979   Int4       i, num_columns, row_num;
27980   ValNodePtr vnp;
27981   BoolPtr    all_present, any_present, all_same;
27982   CharPtr PNTR values;
27983 
27984   if (row == NULL || row->subrows == NULL)
27985   {
27986     return;
27987   }
27988   /* count columns */
27989   for (num_columns = 0, vnp = row->values_list; vnp != NULL; num_columns++, vnp = vnp->next)
27990   {}
27991 
27992   all_present = (BoolPtr) MemNew (sizeof (Boolean) * num_columns);
27993   any_present = (BoolPtr) MemNew (sizeof (Boolean) * num_columns);
27994   all_same = (BoolPtr) MemNew (sizeof (Boolean) * num_columns);
27995   values = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_columns);
27996 
27997   for (i = 0; i < num_columns; i++)
27998   {
27999     all_present[i] = TRUE;
28000     any_present[i] = FALSE;
28001     all_same[i] = TRUE;
28002     values[i] = NULL;
28003   }
28004 
28005   for (row_num = 0; row->subrows[row_num].object_list != NULL; row_num++)
28006   {
28007     for (i = 0, vnp = row->subrows[row_num].values_list; vnp != NULL && i < num_columns; i++, vnp = vnp->next)
28008     {
28009       if (StringHasNoText (vnp->data.ptrvalue))
28010       {
28011         all_present[i] = FALSE;
28012       }
28013       else
28014       {
28015         any_present[i] = TRUE;
28016         if (values[i] == NULL)
28017         {
28018           values[i] = vnp->data.ptrvalue;
28019         }
28020         else if (StringCmp (values[i], vnp->data.ptrvalue) != 0)
28021         {
28022           all_same[i] = FALSE;
28023         }
28024       }
28025     }
28026     while (i < num_columns)
28027     {
28028       all_present[i] = FALSE;
28029       i++;
28030     }
28031   }
28032 
28033   for (i = 0, vnp = row->values_list; vnp != NULL; i++, vnp = vnp->next)
28034   {
28035     if (i == last_sorted_col) {
28036       continue;
28037     }
28038     vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
28039     if (any_present[i]) {
28040       if (all_present[i]) {
28041         if (all_same[i]) {
28042           vnp->data.ptrvalue = StringSave (values[i]);
28043         } else {
28044           vnp->data.ptrvalue = StringSave ("All present, mixed");
28045         }
28046       } else if (all_same[i]) {
28047         vnp->data.ptrvalue = StringSave ("Some missing, one unique");
28048       } else {
28049         vnp->data.ptrvalue = StringSave ("Some missing, mixed");
28050       }
28051     }
28052   }
28053   all_present = MemFree (all_present);
28054   any_present = MemFree (any_present);
28055   all_same = MemFree (all_same);
28056   values = MemFree (values);
28057 }
28058 
28059 
AddSummaryInfoToMetaRows(BulkEditorRowPtr row_list,Int4 last_sorted_col)28060 static void AddSummaryInfoToMetaRows (BulkEditorRowPtr row_list, Int4 last_sorted_col)
28061 {
28062   Int4 row_num;
28063 
28064   if (row_list == NULL) return;
28065 
28066   for (row_num = 0; row_list[row_num].object_list != NULL; row_num++) {
28067     SummarizeOneSubrowSet(row_list + row_num, last_sorted_col);
28068     AddSummaryInfoToMetaRows(row_list[row_num].subrows, last_sorted_col);
28069   }
28070 }
28071 
28072 
28073 static BulkEdFieldPtr s_CurrentSortingFieldList;
28074 static Int4 s_CurrentSortColumn;
28075 
28076 
SortVnpByBulkEditorRow(VoidPtr ptr1,VoidPtr ptr2)28077 NLM_EXTERN int LIBCALLBACK SortVnpByBulkEditorRow (VoidPtr ptr1, VoidPtr ptr2)
28078 
28079 {
28080   BulkEditorRowPtr row1;
28081   BulkEditorRowPtr row2;
28082   ValNodePtr  vnp1;
28083   ValNodePtr  vnp2;
28084 
28085   if (ptr1 != NULL && ptr2 != NULL) {
28086     vnp1 = *((ValNodePtr PNTR) ptr1);
28087     vnp2 = *((ValNodePtr PNTR) ptr2);
28088     if (vnp1 != NULL && vnp2 != NULL) {
28089 
28090       row1 = (BulkEditorRowPtr) vnp1->data.ptrvalue;
28091       row2 = (BulkEditorRowPtr) vnp2->data.ptrvalue;
28092       if (row1 != NULL && row2 != NULL) {
28093         return CompareBulkRows (row1, row2, s_CurrentSortColumn, s_CurrentSortingFieldList);
28094       }
28095     }
28096   }
28097   return 0;
28098 }
28099 
28100 
FlatCopyRows(BulkEditorRowPtr new_rows,BulkEditorRowPtr orig_rows,BulkEdFieldPtr field_list)28101 static Int4 FlatCopyRows (BulkEditorRowPtr new_rows, BulkEditorRowPtr orig_rows, BulkEdFieldPtr field_list)
28102 {
28103   Int4 num_n = 0, num_o = 0;
28104 
28105   while (orig_rows[num_o].object_list != NULL) {
28106     if (orig_rows[num_o].subrows != NULL) {
28107       num_n += FlatCopyRows (new_rows + num_n, orig_rows[num_o].subrows, field_list);
28108     } else {
28109       CopyToSingleBulkEditRow (new_rows + num_n, orig_rows + num_o, field_list);
28110       num_n++;
28111     }
28112     num_o++;
28113   }
28114   return num_n;
28115 }
28116 
28117 
AddBulkEditorRowsToBlock(ValNodeBlockPtr vb,BulkEditorRowPtr rows)28118 static void AddBulkEditorRowsToBlock (ValNodeBlockPtr vb, BulkEditorRowPtr rows)
28119 {
28120   Int4 i = 0;
28121 
28122   if (rows == NULL) {
28123     return;
28124   }
28125   while (rows[i].object_list != NULL) {
28126     if (rows[i].subrows == NULL) {
28127       ValNodeAddPointerToEnd (vb, 0, rows + i);
28128     } else {
28129       AddBulkEditorRowsToBlock (vb, rows[i].subrows);
28130     }
28131     i++;
28132   }
28133 }
28134 
28135 
SortBulkEditorRowsByValue(BulkEditorRowPtr orig_rows,BulkEdFieldPtr field_list,Int4 new_sort_column)28136 static BulkEditorRowPtr SortBulkEditorRowsByValue (BulkEditorRowPtr orig_rows, BulkEdFieldPtr field_list, Int4 new_sort_column)
28137 {
28138   Int4         num_individual_rows = 0;
28139   ValNodeBlock vb;
28140   Int4         i;
28141   ValNodePtr   vnp;
28142   BulkEditorRowPtr new_rows;
28143 
28144   /* count individual rows (will need this many or fewer) */
28145   num_individual_rows = CountIndividualRows(orig_rows);
28146   new_rows = (BulkEditorRowPtr) MemNew (sizeof (BulkEditorRowData) * (num_individual_rows + 1));
28147   MemSet (new_rows, 0, sizeof (BulkEditorRowData) * (num_individual_rows + 1));
28148 
28149   InitValNodeBlock (&vb, NULL);
28150   AddBulkEditorRowsToBlock (&vb, orig_rows);
28151   s_CurrentSortingFieldList = field_list;
28152   s_CurrentSortColumn = new_sort_column;
28153 
28154   vb.head = ValNodeSort (vb.head, SortVnpByBulkEditorRow);
28155   for (vnp = vb.head, i = 0; vnp != NULL; vnp = vnp->next, i++) {
28156     CopyToSingleBulkEditRow (new_rows + i, vnp->data.ptrvalue, field_list);
28157   }
28158   return new_rows;
28159 }
28160 
28161 
ZeroOutBulkEditorRow(BulkEditorRowPtr row,BulkEdFieldPtr field_list)28162 static void ZeroOutBulkEditorRow (BulkEditorRowPtr row, BulkEdFieldPtr field_list)
28163 {
28164   row->values_list = FreeBulkEditorValues (row->values_list, field_list);
28165   row->object_list = ValNodeFree (row->object_list);
28166   FreeBulkEditorRows (row->subrows, field_list);
28167   row->subrows = NULL;
28168 }
28169 
28170 
ResortBulkEditorRows(BulkEditorRowPtr orig_rows,BulkEdFieldPtr field_list,Int4 new_sort_column)28171 static BulkEditorRowPtr ResortBulkEditorRows (BulkEditorRowPtr orig_rows, BulkEdFieldPtr field_list, Int4 new_sort_column)
28172 {
28173   Int4 num_individual_rows = 0;
28174   Int4 row_num, sub_num, last_inserted = 0, comp, col;
28175   Int4 smallest_pos = 0, insert_pos = 0;
28176   BulkEditorRowPtr new_rows = NULL, smallest = NULL;
28177   ValNodePtr       matches = NULL, vnp;
28178   Boolean          all_selected;
28179   BulkEditorRowData swap;
28180 
28181   new_rows = SortBulkEditorRowsByValue (orig_rows, field_list, new_sort_column);
28182   /* count individual rows (will need this many or fewer) */
28183   num_individual_rows = CountIndividualRows(orig_rows);
28184 
28185   for (row_num = 0; new_rows[row_num].object_list != NULL; row_num++) {
28186     if (smallest == NULL) {
28187       smallest = new_rows + row_num;
28188       smallest_pos = row_num;
28189     } else {
28190       comp = CompareBulkRows (new_rows + row_num, smallest, new_sort_column, field_list);
28191       if (comp == 0) {
28192         /* equal - will be combined into meta row after first non-match is found */
28193       } else {
28194         if (smallest_pos < row_num - 1) {
28195           /* move first match to temporary location */
28196           CopyToSingleBulkEditRow (&swap, smallest, field_list);
28197           /* create meta row */
28198           ZeroOutBulkEditorRow (new_rows + insert_pos, field_list);
28199           /* add value for only sort column */
28200           for (col = 0, vnp = swap.values_list; vnp != NULL; col++, vnp = vnp->next) {
28201             if (col == new_sort_column) {
28202               ValNodeAddPointer (&(new_rows[insert_pos].values_list), vnp->choice, field_list[col].copy_func(vnp->data.ptrvalue));
28203             } else {
28204               ValNodeAddPointer (&(new_rows[insert_pos].values_list), 0, NULL);
28205             }
28206           }
28207           /* add features and subrows */
28208           new_rows[insert_pos].subrows = (BulkEditorRowPtr) MemNew (sizeof(BulkEditorRowData) * (row_num - smallest_pos + 1));
28209           MemSet (new_rows[insert_pos].subrows, 0, sizeof(BulkEditorRowData) * (row_num - smallest_pos + 1));
28210           /* copy in swap row */
28211           sub_num = 0;
28212           ValNodeAddPointer (&(new_rows[insert_pos].object_list), swap.object_list->choice, swap.object_list->data.ptrvalue);
28213           CopyToSingleBulkEditRow (new_rows[insert_pos].subrows + sub_num, &swap, field_list);
28214           all_selected = swap.selected;
28215           sub_num++;
28216           while (sub_num + smallest_pos < row_num) {
28217             ValNodeAddPointer (&(new_rows[insert_pos].object_list), new_rows[smallest_pos + sub_num].object_list->choice, new_rows[smallest_pos + sub_num].object_list->data.ptrvalue);
28218             CopyToSingleBulkEditRow (new_rows[insert_pos].subrows + sub_num, new_rows + smallest_pos + sub_num, field_list);
28219             all_selected &= new_rows[smallest_pos + sub_num].selected;
28220             sub_num++;
28221           }
28222           new_rows[insert_pos].selected = all_selected;
28223         } else {
28224           if (insert_pos != row_num - 1) {
28225             ZeroOutBulkEditorRow (new_rows + insert_pos, field_list);
28226             CopyToSingleBulkEditRow (new_rows + insert_pos, new_rows + row_num - 1, field_list);
28227           }
28228         }
28229         insert_pos++;
28230         smallest_pos = row_num;
28231         smallest = new_rows + smallest_pos;
28232       }
28233     }
28234   }
28235 
28236   /* final row */
28237   if (smallest_pos < row_num - 1) {
28238     /* move first match to temporary location */
28239     CopyToSingleBulkEditRow (&swap, smallest, field_list);
28240     /* create meta row */
28241     ZeroOutBulkEditorRow (new_rows + insert_pos, field_list);
28242     /* add value for only sort column */
28243     for (col = 0, vnp = swap.values_list; vnp != NULL; col++, vnp = vnp->next) {
28244       if (col == new_sort_column) {
28245         ValNodeAddPointer (&(new_rows[insert_pos].values_list), vnp->choice, field_list[col].copy_func(vnp->data.ptrvalue));
28246       } else {
28247         ValNodeAddPointer (&(new_rows[insert_pos].values_list), 0, NULL);
28248       }
28249     }
28250     /* add features and subrows */
28251     new_rows[insert_pos].subrows = (BulkEditorRowPtr) MemNew (sizeof(BulkEditorRowData) * (row_num - smallest_pos + 1));
28252     MemSet (new_rows[insert_pos].subrows, 0, sizeof(BulkEditorRowData) * (row_num - smallest_pos + 1));
28253     /* copy in swap row */
28254     sub_num = 0;
28255     ValNodeAddPointer (&(new_rows[insert_pos].object_list), swap.object_list->choice, swap.object_list->data.ptrvalue);
28256     CopyToSingleBulkEditRow (new_rows[insert_pos].subrows + sub_num, &swap, field_list);
28257     all_selected = swap.selected;
28258     sub_num++;
28259     while (sub_num + smallest_pos < row_num) {
28260       ValNodeAddPointer (&(new_rows[insert_pos].object_list), new_rows[smallest_pos + sub_num].object_list->choice, new_rows[smallest_pos + sub_num].object_list->data.ptrvalue);
28261       CopyToSingleBulkEditRow (new_rows[insert_pos].subrows + sub_num, new_rows + smallest_pos + sub_num, field_list);
28262       all_selected &= new_rows[smallest_pos + sub_num].selected;
28263       sub_num++;
28264     }
28265     new_rows[insert_pos].selected = all_selected;
28266   } else {
28267     if (insert_pos != row_num - 1) {
28268       ZeroOutBulkEditorRow (new_rows + insert_pos, field_list);
28269       CopyToSingleBulkEditRow (new_rows + insert_pos, new_rows + row_num - 1, field_list);
28270     }
28271   }
28272   insert_pos++;
28273 
28274   while (insert_pos < num_individual_rows) {
28275     ZeroOutBulkEditorRow (new_rows + insert_pos, field_list);
28276     insert_pos++;
28277   }
28278 
28279   AddSummaryInfoToMetaRows (new_rows, new_sort_column);
28280   return new_rows;
28281 }
28282 
28283 
28284 /* sort_column is zero-based data column, already corrected for selection and expansion columns */
AllSubrowsSameValue(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,Int4 sort_column)28285 static Boolean AllSubrowsSameValue (BulkEditorRowPtr berp, BulkEdFieldPtr field_list, Int4 sort_column)
28286 {
28287   Int4 i;
28288   Boolean all_same = TRUE;
28289 
28290   if (berp == NULL || berp->subrows == NULL || berp->subrows[0].object_list == NULL) {
28291     return TRUE;
28292   }
28293 
28294   for (i = 1; berp->subrows[i].object_list != NULL && all_same; i++) {
28295     if (CompareBulkRows (berp->subrows + i - 1, berp->subrows + i, sort_column, field_list) != 0) {
28296       all_same = FALSE;
28297     }
28298   }
28299 
28300   return all_same;
28301 }
28302 
28303 
28304 /* sort_column is zero-based data column, already corrected for selection and expansion columns */
28305 /* look to see if data in columns is different from data in editor */
AnyChangeInBulkFields(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,DialoG editor,Int4 sort_column)28306 static Boolean AnyChangeInBulkFields (BulkEditorRowPtr berp, BulkEdFieldPtr field_list, DialoG editor, Int4 sort_column)
28307 {
28308   Pointer    m_data;
28309   ValNodePtr vnp;
28310   Int4       comp;
28311 
28312   if (berp == NULL || berp->subrows == NULL || berp->subrows[0].object_list == NULL) return FALSE;
28313   if (field_list == NULL || editor == NULL) return FALSE;
28314 
28315   if (!AllSubrowsSameValue (berp, field_list, sort_column)) {
28316     return TRUE;
28317   }
28318 
28319   /* find value for sort_column from first subrow */
28320   vnp = GetBulkEditorRowValueByColumn (berp, sort_column);
28321 
28322   if (vnp == NULL) return TRUE;
28323 
28324   /* compare with data from editor */
28325   m_data = DialogToPointer (editor);
28326 
28327   comp = CompareBulkRowValues (m_data, vnp->data.ptrvalue, field_list[sort_column].display_func);
28328 
28329   /* free data from editor */
28330   if (field_list[sort_column].free_func) {
28331     (field_list[sort_column].free_func)(m_data);
28332   }
28333 
28334   if (comp == 0) {
28335     return FALSE;
28336   } else {
28337     return TRUE;
28338   }
28339 }
28340 
28341 
28342 /* col is zero-based data column, already corrected for selection and expansion columns */
ApplyValueToOneBulkEditorRow(BulkEditorRowPtr berp,Int2 col,BulkEdFieldPtr field_list,DialoG editor)28343 static void ApplyValueToOneBulkEditorRow (BulkEditorRowPtr berp, Int2 col, BulkEdFieldPtr field_list, DialoG editor)
28344 {
28345   ValNodePtr vnp;
28346 
28347   if (berp == NULL || field_list == NULL ||  editor == NULL) return;
28348 
28349   vnp = GetBulkEditorRowValueByColumn (berp, col);
28350 
28351   if (vnp != NULL) {
28352     if (field_list[col].free_func == NULL) {
28353       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
28354     } else {
28355       (field_list[col].free_func) (vnp->data.ptrvalue);
28356       vnp->data.ptrvalue = NULL;
28357     }
28358     vnp->data.ptrvalue = DialogToPointer (editor);
28359   }
28360 }
28361 
28362 
PopulateSingleBulkEditRowFromData(BulkEditorRowPtr berp,Uint1 data_choice,Pointer data,BulkEdFieldPtr field_list,Pointer metadata)28363 static void PopulateSingleBulkEditRowFromData (BulkEditorRowPtr berp, Uint1 data_choice, Pointer data, BulkEdFieldPtr field_list, Pointer metadata)
28364 {
28365   Int4 col;
28366 
28367   /* add values for all columns */
28368   for (col = 0; field_list[col].name != NULL; col++) {
28369     ValNodeAddPointer (&(berp->values_list), 0, (field_list[col].get_func (data_choice, data, metadata)));
28370   }
28371   /* add feature */
28372   ValNodeAddPointer (&(berp->object_list), data_choice, data);
28373 }
28374 
MakeBulkEditorRowsFromObjectList(ValNodePtr object_list,BulkEdFieldPtr field_list,Int4 sort_column,Pointer metadata)28375 static BulkEditorRowPtr MakeBulkEditorRowsFromObjectList (ValNodePtr object_list, BulkEdFieldPtr field_list, Int4 sort_column, Pointer metadata)
28376 {
28377   ValNodePtr       vnp;
28378   BulkEditorRowPtr bulk_ed_rows = NULL, sorted_rows = NULL;
28379   Int4             num_rows, row_num;
28380 
28381   if (object_list == NULL || field_list == NULL) return NULL;
28382 
28383   /* first, create list with one row per object */
28384   num_rows = ValNodeLen (object_list);
28385 
28386   bulk_ed_rows = (BulkEditorRowPtr) MemNew (sizeof (BulkEditorRowData) * (num_rows + 1));
28387   MemSet (bulk_ed_rows, 0, sizeof (BulkEditorRowData) * (num_rows + 1));
28388 
28389   for (vnp = object_list, row_num = 0; vnp != NULL; vnp = vnp->next, row_num++)
28390   {
28391     PopulateSingleBulkEditRowFromData (bulk_ed_rows + row_num, vnp->choice, vnp->data.ptrvalue, field_list, metadata);
28392   }
28393 
28394   if (sort_column >= 0)
28395   {
28396     /* Now resort rows for column */
28397     sorted_rows = ResortBulkEditorRows (bulk_ed_rows, field_list, sort_column);
28398     bulk_ed_rows = FreeBulkEditorRows (bulk_ed_rows, field_list);
28399     bulk_ed_rows = sorted_rows;
28400   }
28401   return bulk_ed_rows;
28402 }
28403 
28404 
28405 static Boolean IsBulkEditorColumnEmpty (BulkEditorRowPtr row_list, Int4 column);
28406 
IsBulkEditorRowColumnEmpty(BulkEditorRowPtr row,Int4 column)28407 static Boolean IsBulkEditorRowColumnEmpty (BulkEditorRowPtr row, Int4 column)
28408 {
28409   ValNodePtr vnp;
28410   Int4 pos;
28411 
28412   if (row == NULL) {
28413     return TRUE;
28414   }
28415 
28416   for (pos = 0, vnp = row->values_list;
28417        pos < column && vnp != NULL;
28418        pos++, vnp = vnp->next)
28419   {
28420   }
28421   if (pos == column && vnp != NULL && !StringHasNoText (vnp->data.ptrvalue))
28422   {
28423     return FALSE;
28424   }
28425   else
28426   {
28427     return IsBulkEditorColumnEmpty(row->subrows, column);
28428   }
28429 }
28430 
28431 
IsBulkEditorColumnEmpty(BulkEditorRowPtr row_list,Int4 column)28432 static Boolean IsBulkEditorColumnEmpty (BulkEditorRowPtr row_list, Int4 column)
28433 {
28434   Boolean rval = TRUE;
28435   Int4    i;
28436 
28437   if (row_list == NULL)
28438   {
28439     return TRUE;
28440   }
28441   for (i = 0; row_list[i].object_list != NULL && rval; i++)
28442   {
28443     rval = IsBulkEditorRowColumnEmpty (row_list + i, column);
28444   }
28445   return rval;
28446 }
28447 
28448 
28449 static Int4
AddRowsToListBySelection(BulkEditorRowPtr dest,BulkEditorRowPtr src,BulkEdFieldPtr field_list,Int4 last_inserted,Boolean selected)28450 AddRowsToListBySelection
28451 (BulkEditorRowPtr dest,
28452  BulkEditorRowPtr src,
28453  BulkEdFieldPtr   field_list,
28454  Int4             last_inserted,
28455  Boolean          selected)
28456 {
28457   Int4 row_num;
28458 
28459   if (dest == NULL || src == NULL) return last_inserted;
28460 
28461   for (row_num = 0; src[row_num].object_list != NULL; row_num++) {
28462     if (src[row_num].subrows == NULL) {
28463       if ((src[row_num].selected && selected)
28464           || (!src[row_num].selected && !selected)) {
28465         CopyToSingleBulkEditRow (dest + last_inserted, src + row_num, field_list);
28466         src[row_num].copied_to_meta = last_inserted;
28467         src[row_num].copied_to_sub = 0;
28468         last_inserted++;
28469       }
28470     } else {
28471       last_inserted = AddRowsToListBySelection(dest, src[row_num].subrows, field_list, last_inserted, selected);
28472     }
28473   }
28474   return last_inserted;
28475 }
28476 
ResortBulkEditorRowsBySelected(BulkEditorRowPtr orig_rows,BulkEdFieldPtr field_list)28477 static BulkEditorRowPtr ResortBulkEditorRowsBySelected (BulkEditorRowPtr orig_rows, BulkEdFieldPtr field_list)
28478 {
28479   Int4 num_individual_rows;
28480   Int4 last_inserted = 0;
28481   BulkEditorRowPtr new_rows = NULL;
28482 
28483   /* count individual rows (will need this many or fewer) */
28484   num_individual_rows = CountIndividualRows(orig_rows);
28485 
28486   /* set default copied_to values */
28487   SetDefaultCopiedToValues (orig_rows);
28488 
28489   new_rows = (BulkEditorRowPtr) MemNew (sizeof (BulkEditorRowData) * (num_individual_rows + 1));
28490   MemSet (new_rows, 0, sizeof (BulkEditorRowData) * (num_individual_rows + 1));
28491 
28492   /* add selected rows first */
28493   last_inserted = AddRowsToListBySelection(new_rows, orig_rows, field_list, last_inserted, TRUE);
28494 
28495   /* add unselected rows */
28496   last_inserted = AddRowsToListBySelection(new_rows, orig_rows, field_list, last_inserted, FALSE);
28497 
28498   return new_rows;
28499 }
28500 
28501 
28502 
28503 
28504 
28505 typedef enum {
28506   eBulkApplyField = 1,
28507   eBulkEditField,
28508   eBulkConvertField,
28509   eBulkParseField,
28510   eBulkSwapField,
28511   eBulkRemoveField,
28512   eBulkCapitalizeField
28513 } EBulkAction;
28514 
GetFieldNumFromPopupValue(Int4 popup_val,BulkEdFieldPtr field_list,Boolean edit_only)28515 static Int4 GetFieldNumFromPopupValue (Int4 popup_val, BulkEdFieldPtr field_list, Boolean edit_only)
28516 {
28517   Int4 i, pval = 1;
28518 
28519   for (i = 0; field_list[i].name != NULL; i++) {
28520     if (field_list[i].create_dlg_func != NULL || (!edit_only && field_list[i].display_func != NULL)) {
28521       if (pval == popup_val) {
28522         return i;
28523       } else {
28524         pval++;
28525       }
28526     }
28527   }
28528   return -1;
28529 }
28530 
28531 
MakeBulkEditorFieldListPopup(GrouP g,BulkEdFieldPtr field_list,Boolean edit_only)28532 static PopuP MakeBulkEditorFieldListPopup (GrouP g, BulkEdFieldPtr field_list, Boolean edit_only)
28533 {
28534   PopuP p;
28535   Int4  i;
28536 
28537   if (field_list == NULL) return NULL;
28538 
28539   p = PopupList (g, TRUE, NULL);
28540   for (i = 0; field_list[i].name != NULL; i++) {
28541     if (field_list[i].create_dlg_func != NULL || (!edit_only && field_list[i].display_func != NULL)) {
28542       PopupItem (p, field_list[i].name);
28543     }
28544   }
28545   return p;
28546 }
28547 
28548 
MakeBulkEditorFieldListDialog(GrouP g,BulkEdFieldPtr field_list,Boolean edit_only)28549 static DialoG MakeBulkEditorFieldListDialog (GrouP g, BulkEdFieldPtr field_list, Boolean edit_only)
28550 {
28551   ValNodeBlock block;
28552   Int4  i;
28553 
28554   if (field_list == NULL) return NULL;
28555   InitValNodeBlock (&block, NULL);
28556 
28557   for (i = 0; field_list[i].name != NULL; i++) {
28558     if (field_list[i].create_dlg_func != NULL || (!edit_only && field_list[i].display_func != NULL)) {
28559       ValNodeAddPointerToEnd (&block, i, StringSave (field_list[i].name));
28560     }
28561   }
28562   return ValNodeSelectionDialog (g, block.head, TALL_SELECTION_LIST, ValNodeStringName, ValNodeSimpleDataFree, ValNodeStringCopy, ValNodeChoiceMatch, "field", NULL, NULL, FALSE);
28563 }
28564 
28565 
SetBulkEditorFieldListDialogValue(DialoG d,Int4 val)28566 static void SetBulkEditorFieldListDialogValue (DialoG d, Int4 val)
28567 {
28568   ValNode vn;
28569 
28570   MemSet (&vn, 0, sizeof (ValNode));
28571   vn.choice = val;
28572   PointerToDialog (d, &vn);
28573 }
28574 
28575 
ResetBulkEditorFieldListDialogValue(DialoG d,BulkEdFieldPtr field_list)28576 static void ResetBulkEditorFieldListDialogValue (DialoG d, BulkEdFieldPtr field_list)
28577 {
28578   SetBulkEditorFieldListDialogValue(d, GetFieldNumFromPopupValue(1, field_list, TRUE));
28579 }
28580 
28581 
GetBulkEditorFieldListDialogValue(DialoG d)28582 static Int4 GetBulkEditorFieldListDialogValue (DialoG d)
28583 {
28584   Int4 val = 0;
28585   ValNodePtr vnp;
28586 
28587   vnp = DialogToPointer (d);
28588   if (vnp != NULL) {
28589     val = vnp->choice;
28590     vnp = ValNodeFree (vnp);
28591   }
28592   return val;
28593 }
28594 
28595 
28596 
28597 typedef struct onefieldbulkedit
28598 {
28599   Int4          field;
28600   EditApplyPtr  edit_apply;
28601   ChangeCasePtr capitalization;
28602 } OneFieldBulkEditData, PNTR OneFieldBulkEditPtr;
28603 
28604 
OneFieldBulkEditNew(void)28605 static OneFieldBulkEditPtr OneFieldBulkEditNew (void)
28606 {
28607   OneFieldBulkEditPtr ofp;
28608 
28609   ofp = (OneFieldBulkEditPtr) MemNew (sizeof (OneFieldBulkEditData));
28610   return ofp;
28611 }
28612 
28613 
OneFieldBulkEditFree(OneFieldBulkEditPtr ofp)28614 static OneFieldBulkEditPtr OneFieldBulkEditFree (OneFieldBulkEditPtr ofp)
28615 {
28616   if (ofp != NULL) {
28617     ofp->edit_apply = EditApplyFree (ofp->edit_apply);
28618     ofp->capitalization = MemFree (ofp->capitalization);
28619     ofp = MemFree (ofp);
28620   }
28621   return ofp;
28622 }
28623 
28624 
GetDlgFieldNumFromMasterFieldNum(BulkEdFieldPtr master_field_list,BulkEdFieldPtr field_list,Int4 master_field)28625 static Int4 GetDlgFieldNumFromMasterFieldNum (BulkEdFieldPtr master_field_list, BulkEdFieldPtr field_list, Int4 master_field)
28626 {
28627   Int4 m = 0, f = 0;
28628 
28629   while (master_field_list[m].name != NULL && m < master_field) {
28630     if (StringCmp (master_field_list[m].name, field_list[f].name) == 0) {
28631       f++;
28632     }
28633     m++;
28634   }
28635 
28636   return f;
28637 }
28638 
28639 
GetMasterFieldNumFromDlgFieldNum(BulkEdFieldPtr master_field_list,BulkEdFieldPtr field_list,Int4 dlg_field)28640 static Int4 GetMasterFieldNumFromDlgFieldNum (BulkEdFieldPtr master_field_list, BulkEdFieldPtr field_list, Int4 dlg_field)
28641 {
28642   Int4 m = 0;
28643 
28644   while (master_field_list[m].name != NULL && StringCmp (master_field_list[m].name, field_list[dlg_field].name) != 0) {
28645     m++;
28646   }
28647 
28648   return m;
28649 
28650 }
28651 
28652 
AdjustOneFieldForMaster(OneFieldBulkEditPtr ofp,BulkEdFieldPtr master_field_list,BulkEdFieldPtr field_list)28653 static void AdjustOneFieldForMaster (OneFieldBulkEditPtr ofp, BulkEdFieldPtr master_field_list, BulkEdFieldPtr field_list)
28654 {
28655   if (ofp == NULL || master_field_list == NULL || field_list == NULL) {
28656     return;
28657   }
28658 
28659   ofp->field = GetDlgFieldNumFromMasterFieldNum (master_field_list, field_list, ofp->field);
28660 }
28661 
28662 
28663 typedef CharPtr  (*Nlm_GetAutopopulateTextProc) PROTO ((Pointer, Int4));
28664 
28665 typedef struct onefieldbulkeditdlg
28666 {
28667   DIALOG_MESSAGE_BLOCK
28668   Nlm_ChangeNotifyProc     change_notify;
28669   Pointer                  change_userdata;
28670   BulkEdFieldPtr           field_list;
28671   DialoG                   edit_apply;
28672   DialoG                   capitalization;
28673   DialoG                   field_dlg;
28674 
28675   Nlm_GetAutopopulateTextProc autopopulate_func;
28676   Pointer                     autopopulate_data;
28677 } OneFieldBulkEditDialogData, PNTR OneFieldBulkEditDialogPtr;
28678 
28679 
OneFieldBulkEditToDialog(DialoG d,Pointer data)28680 static void OneFieldBulkEditToDialog (DialoG d, Pointer data)
28681 {
28682   OneFieldBulkEditDialogPtr dlg;
28683   OneFieldBulkEditPtr       dlg_data;
28684 
28685   dlg = (OneFieldBulkEditDialogPtr) GetObjectExtra (d);
28686   if (dlg == NULL) return;
28687 
28688   dlg_data = (OneFieldBulkEditPtr) data;
28689   if (dlg_data == NULL) {
28690     ResetBulkEditorFieldListDialogValue (dlg->field_dlg, dlg->field_list);
28691     PointerToDialog (dlg->edit_apply, NULL);
28692     PointerToDialog (dlg->capitalization, NULL);
28693   } else {
28694     SetBulkEditorFieldListDialogValue (dlg->field_dlg, dlg_data->field);
28695     PointerToDialog (dlg->edit_apply, dlg_data->edit_apply);
28696     PointerToDialog (dlg->capitalization, dlg_data->capitalization);
28697   }
28698   if (dlg->change_notify != NULL) {
28699     (dlg->change_notify) (dlg->change_userdata);
28700   }
28701 }
28702 
28703 
OneFieldBulkEditDialogToPointer(DialoG d)28704 static Pointer OneFieldBulkEditDialogToPointer (DialoG d)
28705 {
28706   OneFieldBulkEditDialogPtr dlg;
28707   OneFieldBulkEditPtr       dlg_data;
28708 
28709   dlg = (OneFieldBulkEditDialogPtr) GetObjectExtra (d);
28710   if (dlg == NULL) return NULL;
28711 
28712   dlg_data = (OneFieldBulkEditPtr) MemNew (sizeof (OneFieldBulkEditData));
28713   dlg_data->field = GetBulkEditorFieldListDialogValue (dlg->field_dlg);
28714   dlg_data->edit_apply = DialogToPointer (dlg->edit_apply);
28715   dlg_data->capitalization = DialogToPointer (dlg->capitalization);
28716 
28717   return dlg_data;
28718 }
28719 
28720 
OneFieldBulkEditMsg(DialoG d,Int2 mssg)28721 static void OneFieldBulkEditMsg (DialoG d, Int2 mssg)
28722 
28723 {
28724   OneFieldBulkEditDialogPtr dlg;
28725 
28726   dlg = (OneFieldBulkEditDialogPtr) GetObjectExtra (d);
28727   if (dlg != NULL) {
28728     if (mssg == AECR_VIB_MSG_CLEAR_TEXT) {
28729       SendMessageToDialog (dlg->edit_apply, NUM_VIB_MSG + 1);
28730     }
28731   }
28732 }
28733 
28734 
OneFieldAutopopulate(ButtoN b)28735 static void OneFieldAutopopulate(ButtoN b)
28736 {
28737   OneFieldBulkEditDialogPtr dlg;
28738   CharPtr                   txt;
28739   EditApplyPtr  edit_apply;
28740   Int4          field;
28741 
28742   dlg = (OneFieldBulkEditDialogPtr) GetObjectExtra (b);
28743   if (dlg != NULL && dlg->autopopulate_func != NULL) {
28744     field = GetBulkEditorFieldListDialogValue (dlg->field_dlg);
28745     txt = (dlg->autopopulate_func) (dlg->autopopulate_data, field);
28746     edit_apply = DialogToPointer (dlg->edit_apply);
28747     if (edit_apply == NULL) {
28748       edit_apply = EditApplyNew();
28749     }
28750     edit_apply->find_txt = MemFree (edit_apply->find_txt);
28751     edit_apply->find_txt = StringSave (txt);
28752     edit_apply->apply_txt = MemFree (edit_apply->apply_txt);
28753     edit_apply->apply_txt = StringSave (txt);
28754     PointerToDialog (dlg->edit_apply, edit_apply);
28755     edit_apply = EditApplyFree (edit_apply);
28756     txt = MemFree (txt);
28757   }
28758 }
28759 
28760 
OneFieldClearText(ButtoN b)28761 static void OneFieldClearText(ButtoN b)
28762 {
28763   OneFieldBulkEditDialogPtr dlg;
28764   EditApplyPtr  edit_apply;
28765 
28766   dlg = (OneFieldBulkEditDialogPtr) GetObjectExtra (b);
28767   if (dlg != NULL) {
28768     edit_apply = DialogToPointer (dlg->edit_apply);
28769     if (edit_apply != NULL) {
28770       edit_apply->find_txt = MemFree (edit_apply->find_txt);
28771       edit_apply->repl_txt = MemFree (edit_apply->repl_txt);
28772       edit_apply->apply_txt = MemFree (edit_apply->apply_txt);
28773       PointerToDialog (dlg->edit_apply, edit_apply);
28774       edit_apply = EditApplyFree (edit_apply);
28775     }
28776   }
28777 }
28778 
28779 
OneFieldBulkEditDialog(GrouP h,EBulkAction action_choice,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,BulkEdFieldPtr field_list,Nlm_GetAutopopulateTextProc autopopulate_func,Pointer autopopulate_data)28780 static DialoG OneFieldBulkEditDialog
28781 (GrouP                    h,
28782  EBulkAction              action_choice,
28783  Nlm_ChangeNotifyProc     change_notify,
28784  Pointer                  change_userdata,
28785  BulkEdFieldPtr           field_list,
28786  Nlm_GetAutopopulateTextProc autopopulate_func,
28787  Pointer                     autopopulate_data
28788 )
28789 
28790 {
28791   OneFieldBulkEditDialogPtr dlg;
28792   GrouP                     p, g1, g2 = NULL;
28793   ButtoN                    b;
28794 
28795   dlg = (OneFieldBulkEditDialogPtr) MemNew (sizeof (OneFieldBulkEditDialogData));
28796   if (dlg == NULL)
28797   {
28798     return NULL;
28799   }
28800 
28801   p = HiddenGroup (h, -1, 0, NULL);
28802   SetObjectExtra (p, dlg, StdCleanupExtraProc);
28803   SetGroupSpacing (p, 10, 10);
28804 
28805   dlg->dialog = (DialoG) p;
28806   dlg->todialog = OneFieldBulkEditToDialog;
28807   dlg->fromdialog = OneFieldBulkEditDialogToPointer;
28808   dlg->dialogmessage = OneFieldBulkEditMsg;
28809   dlg->testdialog = NULL;
28810 
28811   dlg->field_list = field_list;
28812   dlg->autopopulate_func = autopopulate_func;
28813   dlg->autopopulate_data = autopopulate_data;
28814 
28815   g1 = HiddenGroup (p, 2, 0, NULL);
28816   SetGroupSpacing (g1, 10, 10);
28817   dlg->field_dlg = MakeBulkEditorFieldListDialog (g1, field_list, TRUE);
28818   ResetBulkEditorFieldListDialogValue (dlg->field_dlg, dlg->field_list);
28819 
28820   if (action_choice == eBulkApplyField)
28821   {
28822     dlg->edit_apply = EditApplyDialog (g1, eEditApplyChoice_Apply, NULL, NULL, NULL, NULL);
28823   }
28824   else if (action_choice == eBulkEditField)
28825   {
28826     dlg->edit_apply = EditApplyDialog (g1, eEditApplyChoice_Edit, NULL, NULL, NULL, NULL);
28827   }
28828   else if (action_choice == eBulkCapitalizeField)
28829   {
28830     dlg->capitalization = ChangeCaseDialog (g1);
28831   }
28832 
28833   if (autopopulate_func != NULL) {
28834     g2 = HiddenGroup (p, 2, 0, NULL);
28835     SetGroupSpacing (g2, 10, 10);
28836     b = PushButton (g2, "Autopopulate", OneFieldAutopopulate);
28837     SetObjectExtra (b, dlg, NULL);
28838     b = PushButton (g2, "Clear Text", OneFieldClearText);
28839     SetObjectExtra (b, dlg, NULL);
28840   }
28841   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2, NULL);
28842 
28843   return (DialoG) p;
28844 }
28845 
28846 
28847 typedef struct twofieldbulkedit
28848 {
28849   Int4 field_from;
28850   Int4 field_to;
28851   Boolean strip_name;
28852   Boolean leave_on_original;
28853   Boolean remove_parsed;
28854   TextPortionXPtr text_portion;
28855 } TwoFieldBulkEditData, PNTR TwoFieldBulkEditPtr;
28856 
28857 
TwoFieldBulkEditNew(void)28858 static TwoFieldBulkEditPtr TwoFieldBulkEditNew (void)
28859 {
28860   TwoFieldBulkEditPtr tfp;
28861 
28862   tfp = (TwoFieldBulkEditPtr) MemNew (sizeof (TwoFieldBulkEditData));
28863   return tfp;
28864 }
28865 
28866 
TwoFieldBulkEditFree(TwoFieldBulkEditPtr tfp)28867 static TwoFieldBulkEditPtr TwoFieldBulkEditFree (TwoFieldBulkEditPtr tfp)
28868 {
28869   if (tfp != NULL) {
28870     tfp->text_portion = TextPortionXFree (tfp->text_portion);
28871     tfp = MemFree (tfp);
28872   }
28873   return tfp;
28874 }
28875 
28876 
AdjustTwoFieldsForMaster(TwoFieldBulkEditPtr tfp,BulkEdFieldPtr master_field_list,BulkEdFieldPtr field_list)28877 static void AdjustTwoFieldsForMaster (TwoFieldBulkEditPtr tfp, BulkEdFieldPtr master_field_list, BulkEdFieldPtr field_list)
28878 {
28879   if (tfp == NULL || master_field_list == NULL || field_list == NULL) {
28880     return;
28881   }
28882 
28883   tfp->field_to = GetDlgFieldNumFromMasterFieldNum (master_field_list, field_list, tfp->field_to);
28884   tfp->field_from = GetDlgFieldNumFromMasterFieldNum (master_field_list, field_list, tfp->field_from);
28885 }
28886 
28887 
28888 typedef struct twofieldbulkeditdlg
28889 {
28890   DIALOG_MESSAGE_BLOCK
28891   Nlm_ChangeNotifyProc     change_notify;
28892   Pointer                  change_userdata;
28893   BulkEdFieldPtr           field_list;
28894   ButtoN                   strip_name;
28895   ButtoN                   leave_on_original;
28896   ButtoN                   remove_parsed;
28897   DialoG                   text_portion;
28898   DialoG                   field_from;
28899   DialoG                   field_to;
28900 
28901   Nlm_GetAutopopulateTextProc autopopulate_func;
28902   Pointer                     autopopulate_data;
28903 } TwoFieldBulkEditDialogData, PNTR TwoFieldBulkEditDialogPtr;
28904 
28905 
TwoFieldBulkEditToDialog(DialoG d,Pointer data)28906 static void TwoFieldBulkEditToDialog (DialoG d, Pointer data)
28907 {
28908   TwoFieldBulkEditDialogPtr dlg;
28909   TwoFieldBulkEditPtr       dlg_data;
28910 
28911   dlg = (TwoFieldBulkEditDialogPtr) GetObjectExtra (d);
28912   if (dlg == NULL) return;
28913 
28914   dlg_data = (TwoFieldBulkEditPtr) data;
28915   if (dlg_data == NULL) {
28916     ResetBulkEditorFieldListDialogValue (dlg->field_from, dlg->field_list);
28917     ResetBulkEditorFieldListDialogValue (dlg->field_to, dlg->field_list);
28918     if (dlg->leave_on_original != NULL) {
28919       SetStatus (dlg->leave_on_original, FALSE);
28920     }
28921     if (dlg->strip_name != NULL) {
28922       SetStatus (dlg->strip_name, FALSE);
28923     }
28924     if (dlg->remove_parsed != NULL) {
28925       SetStatus (dlg->remove_parsed, FALSE);
28926     }
28927     PointerToDialog (dlg->text_portion, NULL);
28928   } else {
28929     SetBulkEditorFieldListDialogValue (dlg->field_from, dlg_data->field_from);
28930     SetBulkEditorFieldListDialogValue (dlg->field_to, dlg_data->field_from);
28931     if (dlg->leave_on_original != NULL) {
28932       SetStatus (dlg->leave_on_original, dlg_data->leave_on_original);
28933     }
28934     if (dlg->strip_name != NULL) {
28935       SetStatus (dlg->strip_name, dlg_data->strip_name);
28936     }
28937     if (dlg->remove_parsed != NULL) {
28938       SetStatus (dlg->remove_parsed, dlg_data->remove_parsed);
28939     }
28940     PointerToDialog (dlg->text_portion, dlg_data->text_portion);
28941   }
28942   if (dlg->change_notify != NULL) {
28943     (dlg->change_notify) (dlg->change_userdata);
28944   }
28945 }
28946 
28947 
TwoFieldBulkEditDialogToPointer(DialoG d)28948 static Pointer TwoFieldBulkEditDialogToPointer (DialoG d)
28949 {
28950   TwoFieldBulkEditDialogPtr dlg;
28951   TwoFieldBulkEditPtr       dlg_data;
28952 
28953   dlg = (TwoFieldBulkEditDialogPtr) GetObjectExtra (d);
28954   if (dlg == NULL) return NULL;
28955 
28956   dlg_data = (TwoFieldBulkEditPtr) MemNew (sizeof (TwoFieldBulkEditData));
28957   dlg_data->field_from = GetBulkEditorFieldListDialogValue (dlg->field_from);
28958   dlg_data->field_to = GetBulkEditorFieldListDialogValue (dlg->field_to);
28959   dlg_data->leave_on_original = dlg->leave_on_original == NULL ? FALSE : GetStatus (dlg->leave_on_original);
28960   dlg_data->strip_name = dlg->strip_name == NULL ? FALSE : GetStatus (dlg->strip_name);
28961   dlg_data->remove_parsed = dlg->remove_parsed == NULL ? FALSE : GetStatus (dlg->remove_parsed);
28962   dlg_data->text_portion = DialogToPointer (dlg->text_portion);
28963 
28964   return dlg_data;
28965 }
28966 
28967 
TwoFieldBulkEditMsg(DialoG d,Int2 mssg)28968 static void TwoFieldBulkEditMsg (DialoG d, Int2 mssg)
28969 
28970 {
28971   TwoFieldBulkEditDialogPtr dlg;
28972 
28973   dlg = (TwoFieldBulkEditDialogPtr) GetObjectExtra (d);
28974   if (dlg != NULL) {
28975     if (mssg == AECR_VIB_MSG_CLEAR_TEXT) {
28976       SendMessageToDialog (dlg->text_portion, NUM_VIB_MSG + 1);
28977     }
28978   }
28979 }
28980 
28981 
TwoFieldAutopopulate(ButtoN b)28982 static void TwoFieldAutopopulate(ButtoN b)
28983 {
28984   TwoFieldBulkEditDialogPtr dlg;
28985   CharPtr                   txt;
28986   TextPortionXPtr  text_portion;
28987   Int4             field;
28988 
28989   dlg = (TwoFieldBulkEditDialogPtr) GetObjectExtra (b);
28990   if (dlg != NULL && dlg->autopopulate_func != NULL) {
28991     field = GetBulkEditorFieldListDialogValue (dlg->field_from);
28992     txt = (dlg->autopopulate_func) (dlg->autopopulate_data, field);
28993     text_portion = DialogToPointer (dlg->text_portion);
28994     if (text_portion == NULL) {
28995       text_portion = TextPortionXNew();
28996     }
28997     text_portion->start_text = MemFree (text_portion->start_text);
28998     text_portion->start_text = StringSave (txt);
28999     text_portion->end_text = MemFree (text_portion->end_text);
29000     text_portion->end_text = StringSave (txt);
29001     PointerToDialog (dlg->text_portion, text_portion);
29002     text_portion = TextPortionXFree (text_portion);
29003     txt = MemFree (txt);
29004   }
29005 }
29006 
29007 
TwoFieldClearText(ButtoN b)29008 static void TwoFieldClearText(ButtoN b)
29009 {
29010   TwoFieldBulkEditDialogPtr dlg;
29011   TextPortionXPtr  text_portion;
29012 
29013   dlg = (TwoFieldBulkEditDialogPtr) GetObjectExtra (b);
29014   if (dlg != NULL) {
29015     text_portion = DialogToPointer (dlg->text_portion);
29016     if (text_portion != NULL) {
29017       text_portion->start_text = MemFree (text_portion->start_text);
29018       text_portion->end_text = MemFree (text_portion->end_text);
29019       PointerToDialog (dlg->text_portion, text_portion);
29020       text_portion = TextPortionXFree (text_portion);
29021     }
29022   }
29023 }
29024 
29025 
TwoFieldBulkEditDialog(GrouP h,EBulkAction action_choice,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,BulkEdFieldPtr field_list,Boolean strip_name,Nlm_GetAutopopulateTextProc autopopulate_func,Pointer autopopulate_data)29026 static DialoG TwoFieldBulkEditDialog
29027 (GrouP                    h,
29028  EBulkAction              action_choice,
29029  Nlm_ChangeNotifyProc     change_notify,
29030  Pointer                  change_userdata,
29031  BulkEdFieldPtr           field_list,
29032  Boolean                  strip_name,
29033  Nlm_GetAutopopulateTextProc autopopulate_func,
29034  Pointer                     autopopulate_data
29035 )
29036 
29037 {
29038   TwoFieldBulkEditDialogPtr dlg;
29039   GrouP            p, g1, g2, g3 = NULL;
29040   ButtoN           b;
29041 
29042   dlg = (TwoFieldBulkEditDialogPtr) MemNew (sizeof (TwoFieldBulkEditDialogData));
29043   if (dlg == NULL)
29044   {
29045     return NULL;
29046   }
29047 
29048   p = HiddenGroup (h, -1, 0, NULL);
29049   SetObjectExtra (p, dlg, StdCleanupExtraProc);
29050   SetGroupSpacing (p, 10, 10);
29051 
29052   dlg->dialog = (DialoG) p;
29053   dlg->todialog = TwoFieldBulkEditToDialog;
29054   dlg->fromdialog = TwoFieldBulkEditDialogToPointer;
29055   dlg->dialogmessage = TwoFieldBulkEditMsg;
29056   dlg->testdialog = NULL;
29057 
29058   dlg->field_list = field_list;
29059   dlg->autopopulate_func = autopopulate_func;
29060   dlg->autopopulate_data = autopopulate_data;
29061 
29062   g1 = HiddenGroup (p, 2, 0, NULL);
29063   StaticPrompt (g1, "From", 0, dialogTextHeight, systemFont, 'l');
29064   StaticPrompt (g1, "To", 0, dialogTextHeight, systemFont, 'l');
29065 
29066   dlg->field_from = MakeBulkEditorFieldListDialog (g1, field_list, TRUE);
29067   ResetBulkEditorFieldListDialogValue (dlg->field_from, field_list);
29068   dlg->field_to = MakeBulkEditorFieldListDialog (g1, field_list, TRUE);
29069   ResetBulkEditorFieldListDialogValue (dlg->field_to, field_list);
29070 
29071   if (action_choice == eBulkParseField)
29072   {
29073     dlg->text_portion = TextPortionXDialog(p);
29074   }
29075 
29076   g2 = HiddenGroup (p, 3, 0, NULL);
29077 
29078   if (action_choice == eBulkParseField)
29079   {
29080     dlg->remove_parsed = CheckBox (g2, "Remove from parsed field", NULL);
29081 
29082     if (autopopulate_func != NULL) {
29083       g3 = HiddenGroup (p, 2, 0, NULL);
29084       SetGroupSpacing (g3, 10, 10);
29085       b = PushButton (g3, "Autopopulate", TwoFieldAutopopulate);
29086       SetObjectExtra (b, dlg, NULL);
29087       b = PushButton (g3, "Clear Text", TwoFieldClearText);
29088       SetObjectExtra (b, dlg, NULL);
29089     }
29090   }
29091 
29092   if (action_choice == eBulkConvertField)
29093   {
29094     dlg->leave_on_original = CheckBox (g2, "Leave on original", NULL);
29095   }
29096   if (strip_name)
29097   {
29098     dlg->strip_name = CheckBox (g2, "Strip name from text", NULL);
29099   }
29100 
29101   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE)g2, (HANDLE) dlg->text_portion, (HANDLE) g3, NULL);
29102   return (DialoG) p;
29103 }
29104 
29105 
BulkDrawCollapseExpand(Boolean val,RectPtr r)29106 static void BulkDrawCollapseExpand (Boolean val, RectPtr r)
29107 {
29108   RecT rct;
29109 
29110   if (r == NULL) return;
29111 
29112   rct = *r;
29113   rct.bottom = rct.top + stdLineHeight - 4;
29114   rct.right = rct.left + stdLineHeight - 4;
29115   InsetRect (&rct, 2, 2);
29116   FrameRect (&rct);
29117 
29118   Gray();
29119   if (val) {
29120     /* draw minus */
29121     MoveTo (rct.left, (rct.top + rct.bottom) / 2);
29122     LineTo (rct.right - 1, (rct.top + rct.bottom) / 2);
29123   } else {
29124     /* draw plus */
29125     MoveTo (rct.left, (rct.top + rct.bottom) / 2);
29126     LineTo (rct.right - 1, (rct.top + rct.bottom) / 2);
29127     MoveTo ((rct.left + rct.right) / 2, rct.top);
29128     LineTo ((rct.left + rct.right) / 2, rct.bottom);
29129   }
29130   Black();
29131 }
29132 
29133 
BulkDrawSelect(Boolean val,RectPtr r)29134 static void BulkDrawSelect (Boolean val, RectPtr r)
29135 {
29136   RecT rct;
29137 
29138   if (r == NULL) return;
29139 
29140   rct = *r;
29141   rct.bottom = rct.top + stdLineHeight - 4;
29142   rct.right = rct.left + stdLineHeight - 4;
29143   InsetRect (&rct, 2, 2);
29144   FrameRect (&rct);
29145 
29146   if (val) {
29147     /* draw X */
29148     MoveTo (rct.left, rct.top);
29149     LineTo (rct.right - 1, rct.bottom - 1);
29150     MoveTo (rct.right, rct.top);
29151     LineTo (rct.left, rct.bottom - 1);
29152   }
29153 }
29154 
29155 
29156 typedef struct bulkeditordlg {
29157   DIALOG_MESSAGE_BLOCK
29158   DoC               title_doc;
29159   DoC               doc;
29160   BulkEdFieldPtr    master_field_list;
29161   BulkEdFieldPtr    field_list;
29162   ColPtr            col_list;
29163   ParData           par_fmt;
29164   BulkEditorRowPtr  row_list;
29165   DialoG PNTR       editor_list;
29166   GrouP             ed_btn_grp;
29167   Int4              num_columns;
29168   Int4              num_master_columns;
29169   Int2              last_viewed_row;
29170   Int2              last_viewed_col;  /* this will always refer to the data column */
29171   Int2              last_sorted_col;  /* this will always refer to the data column */
29172   /* for columns shown in display when there are extra */
29173   Int4              display_offset;
29174   Int4              columns_shown;
29175 
29176   /* These are for the bulk edit actions */
29177   PopuP             bulk_action;
29178   GrouP             action_pages[8];
29179 
29180   DialoG            bulk_apply;
29181   DialoG            bulk_edit;
29182   DialoG            bulk_convert;
29183   DialoG            bulk_parse;
29184   DialoG            bulk_swap;
29185   DialoG            bulk_remove;
29186   DialoG            bulk_capitalize;
29187 
29188   GrouP             sel_unsel_grp;
29189   PopuP             check_constraint_field;
29190   DialoG            check_constraint;
29191   PrompT            check_status;
29192 
29193   Boolean           any_editing;
29194   Boolean           collapse_by_default;
29195   ClickableCallback single_click_func;
29196   ClickableCallback double_click_func;
29197   Pointer           metadata;
29198   SeqEntryPtr       sep;
29199 } BulkEditorDlgData, PNTR BulkEditorDlgPtr;
29200 
29201 
InitBulkEdTitleDoc(BulkEditorDlgPtr dlg,DoC doc)29202 static void InitBulkEdTitleDoc (BulkEditorDlgPtr dlg, DoC doc)
29203 {
29204   Int4       i, text_len = 9;
29205   CharPtr    line_text;
29206 
29207   if (dlg == NULL || doc == NULL) {
29208     return;
29209   }
29210 
29211   Reset (doc);
29212   for (i = 0; i < dlg->display_offset + dlg->columns_shown; i++) {
29213     if (i < dlg->display_offset) {
29214       continue;
29215     }
29216     text_len += StringLen (dlg->field_list[i].name) + 1;
29217   }
29218 
29219   line_text = (CharPtr) MemNew (text_len * sizeof (Char));
29220   line_text[0] = 0;
29221   /* add blank column for row selection/scrolling */
29222   if (dlg->display_offset > 0) {
29223     StringCat (line_text, "<");
29224   }
29225   StringCat (line_text, "\t");
29226 
29227   for (i = 0; i < dlg->display_offset + dlg->columns_shown - 1; i++) {
29228     if (i < dlg->display_offset) {
29229       continue;
29230     }
29231     if (i == dlg->last_sorted_col) {
29232       /* add blank column for expand/collapse */
29233       StringCat (line_text, "\t");
29234     }
29235     StringCat (line_text, dlg->field_list[i].name);
29236     StringCat (line_text, "\t");
29237   }
29238   if (i == dlg->last_sorted_col) {
29239     /* add blank column for expand/collapse */
29240     StringCat (line_text, "\t");
29241   }
29242   StringCat (line_text, dlg->field_list[i].name);
29243   /* add blank column at end */
29244   if (dlg->display_offset + dlg->columns_shown < dlg->num_columns) {
29245     StringCat (line_text, "\t>\n");
29246   } else {
29247     StringCat (line_text, "\t\n");
29248   }
29249 
29250   AppendText (doc, line_text, &(dlg->par_fmt), dlg->col_list, programFont);
29251   line_text = MemFree (line_text);
29252 }
29253 
29254 
29255 /* redraw, set scroll position */
UpdateBulkEdDisplay(BulkEditorDlgPtr dlg)29256 static void UpdateBulkEdDisplay (BulkEditorDlgPtr dlg)
29257 {
29258   Int4       i, text_len = 0, sub_num;
29259   CharPtr    line_text;
29260   BaR        sb;
29261   Int4       offset = 0;
29262   Int2       first_shown = 0;
29263 
29264   if (dlg == NULL) {
29265     return;
29266   }
29267 
29268   /* Get original scroll position */
29269   sb = GetSlateVScrollBar ((SlatE)dlg->doc);
29270   offset = 0;
29271   GetScrlParams4 (dlg->doc, &offset, &first_shown, NULL);
29272 
29273   Reset (dlg->doc);
29274 
29275   if (dlg->row_list == NULL) {
29276     return;
29277   }
29278 
29279   for (i = 0; dlg->row_list[i].object_list != NULL; i++) {
29280     line_text = GetTextForBulkEditorRow(dlg->row_list + i, dlg->field_list, dlg->last_sorted_col, dlg->display_offset, dlg->columns_shown);
29281     AppendText (dlg->doc, line_text, &(dlg->par_fmt), dlg->col_list, programFont);
29282     line_text = MemFree (line_text);
29283     if (dlg->row_list[i].subrows != NULL && dlg->row_list[i].expanded) {
29284       for (sub_num = 0; dlg->row_list[i].subrows[sub_num].object_list != NULL; sub_num++) {
29285         line_text = GetTextForBulkEditorRow(dlg->row_list[i].subrows + sub_num, dlg->field_list, dlg->last_sorted_col, dlg->display_offset, dlg->columns_shown);
29286           AppendText (dlg->doc, line_text, &(dlg->par_fmt), dlg->col_list, programFont);
29287         line_text = MemFree (line_text);
29288       }
29289     }
29290   }
29291 
29292   /* restore original scroll position */
29293   GetItemParams4 (dlg->doc, first_shown, &offset, NULL, NULL, NULL, NULL);
29294   offset = MIN (offset, GetBarMax (sb));
29295   SetScrlParams4 (dlg->doc, offset);
29296 }
29297 
29298 
RedrawAfterColumnShift(BulkEditorDlgPtr dlg)29299 static void RedrawAfterColumnShift (BulkEditorDlgPtr dlg)
29300 {
29301   RecT r;
29302   Int4 width = 0;
29303 
29304   ResetClip();
29305   /* reset column widths */
29306   dlg->col_list = MemFree (dlg->col_list);
29307   SelectFont (systemFont);
29308   dlg->col_list = AllocateDocColumnsForFieldList (dlg->field_list, &width, dlg->last_sorted_col, dlg->display_offset, dlg->columns_shown);
29309 
29310   /* set data */
29311   InitBulkEdTitleDoc (dlg, dlg->title_doc);
29312   UpdateBulkEdDisplay (dlg);
29313   /* redraw highlight etc. */
29314   ObjectRect (dlg->title_doc, &r);
29315   InvalRect (&r);
29316   ObjectRect (dlg->doc, &r);
29317   InvalRect (&r);
29318   Update ();
29319 }
29320 
29321 
29322 /* col is zero-based data column, already corrected for selection and expansion columns */
BulkEdDlgToField(Int2 row,Int2 col,BulkEditorDlgPtr dlg)29323 static void BulkEdDlgToField (Int2 row, Int2 col, BulkEditorDlgPtr dlg)
29324 {
29325   Int4       i;
29326   Int4       bulk_row, sub_num;
29327   Int2       edit_col, last_edit_col;
29328 
29329   if (row < 1 || col < 0 || dlg == NULL) return;
29330 
29331   if (!DataPosFromBulkEdDlgRow (row, dlg->row_list, &bulk_row, &sub_num)) return;
29332 
29333   /* don't apply values if editing master row and column other than sort */
29334   if (sub_num < 0 && col != dlg->last_sorted_col && dlg->row_list[bulk_row].subrows != NULL) return;
29335 
29336   edit_col = GetMasterFieldNumFromDlgFieldNum (dlg->master_field_list, dlg->field_list, col);
29337 
29338   if (dlg->editor_list[edit_col] == NULL) return;
29339 
29340   if (sub_num < 0) {
29341     /* if applying to all, get confirmation */
29342     if (dlg->row_list[bulk_row].subrows != NULL) {
29343       /* if nothing changed, no need to ask, nothing to do */
29344       last_edit_col = GetMasterFieldNumFromDlgFieldNum (dlg->master_field_list, dlg->field_list, dlg->last_sorted_col);
29345       if (!AnyChangeInBulkFields(dlg->row_list + bulk_row, dlg->field_list, dlg->editor_list[last_edit_col], dlg->last_sorted_col)) {
29346         return;
29347       } else if (ANS_CANCEL == Message (MSG_OKC, "Apply value to all features in collapsible group?")) {
29348         return;
29349       }
29350     }
29351     ApplyValueToOneBulkEditorRow (dlg->row_list + bulk_row, col, dlg->field_list, dlg->editor_list[edit_col]);
29352     if (dlg->row_list[bulk_row].subrows != NULL) {
29353       for (i = 0; dlg->row_list[bulk_row].subrows[i].object_list != NULL; i++) {
29354         ApplyValueToOneBulkEditorRow (dlg->row_list[bulk_row].subrows + i, col, dlg->field_list, dlg->editor_list[edit_col]);
29355       }
29356     }
29357   } else {
29358     ApplyValueToOneBulkEditorRow (dlg->row_list[bulk_row].subrows + sub_num, col, dlg->field_list, dlg->editor_list[edit_col]);
29359   }
29360   UpdateBulkEdDisplay (dlg);
29361 }
29362 
29363 
29364 /* col is zero-based data column, already corrected for selection and expansion columns */
29365 /* if col is -1, hide everything (sorted by selection) */
ShowBulkFieldEditor(BulkEditorDlgPtr dlg,Int4 bulk_row,Int4 sub_num,Int2 col)29366 static void ShowBulkFieldEditor (BulkEditorDlgPtr dlg, Int4 bulk_row, Int4 sub_num, Int2 col)
29367 {
29368   BulkEditorRowPtr berp;
29369   ValNodePtr       vnp;
29370   Int2             i;
29371   Int4             edit_col;
29372 
29373   for (i = 0; i < dlg->num_master_columns; i++) {
29374     SafeHide (dlg->editor_list[i]);
29375   }
29376   SafeHide (dlg->ed_btn_grp);
29377 
29378   if (col < 0) return;
29379 
29380   if (sub_num < 0) {
29381     berp = dlg->row_list + bulk_row;
29382   } else {
29383     berp = dlg->row_list[bulk_row].subrows + sub_num;
29384   }
29385 
29386   /* only show editor dialog if sorted column or not master row */
29387   if (col == dlg->last_sorted_col || berp->subrows == NULL) {
29388     vnp = GetBulkEditorRowValueByColumn (berp, col);
29389 
29390     edit_col = GetMasterFieldNumFromDlgFieldNum (dlg->master_field_list, dlg->field_list, col);
29391 
29392     if (vnp == NULL) {
29393       PointerToDialog (dlg->editor_list[edit_col], NULL);
29394     } else {
29395       PointerToDialog (dlg->editor_list[edit_col], vnp->data.ptrvalue);
29396     }
29397     if (dlg->editor_list[edit_col] != NULL) {
29398       Show (dlg->editor_list[edit_col]);
29399       Show (dlg->ed_btn_grp);
29400     }
29401   }
29402 }
29403 
29404 
SetBulkEditorSortColumn(DialoG dialog,Int4 col)29405 NLM_EXTERN void SetBulkEditorSortColumn (DialoG dialog, Int4 col)
29406 {
29407   BulkEditorDlgPtr dlg;
29408   Int4             bulk_row_num = -1, bulk_sub_num = -1;
29409   RecT             r;
29410   Int4             offset = 0, i;
29411   BulkEditorRowPtr sorted_rows;
29412 
29413   dlg = (BulkEditorDlgPtr) GetObjectExtra (dialog);
29414   if (dlg == NULL) return;
29415 
29416   if (col < -1 || col >= dlg->num_columns) return;
29417   ResetClip();
29418 
29419   /* save value of column listed */
29420   dlg->last_sorted_col = col;
29421 
29422   if (col < 0) {
29423     sorted_rows = ResortBulkEditorRowsBySelected (dlg->row_list, dlg->field_list);
29424   } else {
29425     sorted_rows = ResortBulkEditorRows (dlg->row_list, dlg->field_list, dlg->last_sorted_col);
29426     if (dlg->collapse_by_default) {
29427       CollapseAllBulkEditRows (sorted_rows);
29428     } else {
29429       ExpandAllBulkEditRows (sorted_rows);
29430     }
29431   }
29432   /* get new position from old row */
29433   if (DataPosFromBulkEdDlgRow (dlg->last_viewed_row, dlg->row_list, &bulk_row_num, &bulk_sub_num)) {
29434     if (bulk_sub_num > -1) {
29435       dlg->last_viewed_row = BulkEdDlgRowFromDataPos (dlg->row_list[bulk_row_num].subrows[bulk_sub_num].copied_to_meta,
29436                                                       dlg->row_list[bulk_row_num].subrows[bulk_sub_num].copied_to_sub,
29437                                                       sorted_rows);
29438     } else {
29439       dlg->last_viewed_row = BulkEdDlgRowFromDataPos (dlg->row_list[bulk_row_num].copied_to_meta,
29440                                                       dlg->row_list[bulk_row_num].copied_to_sub,
29441                                                       sorted_rows);
29442     }
29443     dlg->last_viewed_col = dlg->last_sorted_col;
29444   }
29445 
29446   dlg->row_list = FreeBulkEditorRows (dlg->row_list, dlg->field_list);
29447   dlg->row_list = sorted_rows;
29448 
29449 
29450   /* reformat the columns */
29451   dlg->col_list = AllocateDocColumnsForFieldList (dlg->field_list, NULL, dlg->last_sorted_col, dlg->display_offset, dlg->columns_shown);
29452   ResetClip();
29453   InitBulkEdTitleDoc (dlg, dlg->title_doc);
29454   ObjectRect (dlg->title_doc, &r);
29455   InvalRect (&r);
29456 
29457   UpdateBulkEdDisplay (dlg);
29458 
29459   if (dlg->last_viewed_row > 0) {
29460     /* show appropriate editor for highlighted item */
29461     if (DataPosFromBulkEdDlgRow (dlg->last_viewed_row, dlg->row_list, &bulk_row_num, &bulk_sub_num)) {
29462       ShowBulkFieldEditor (dlg, bulk_row_num, bulk_sub_num, dlg->last_sorted_col);
29463     } else {
29464       dlg->last_viewed_row = 0;
29465       dlg->last_viewed_col = 0;
29466       for (i = 0; i < dlg->num_master_columns; i++) {
29467         SafeHide (dlg->editor_list[i]);
29468       }
29469       Hide (dlg->ed_btn_grp);
29470     }
29471 
29472     /* scroll to new position of last_viewed */
29473     GetItemParams4 (dlg->doc, dlg->last_viewed_row, &offset, NULL, NULL, NULL, NULL);
29474     SetScrlParams4 (dlg->doc, offset);
29475   }
29476 
29477   /* redraw highlight etc. */
29478   ObjectRect (dlg->title_doc, &r);
29479   InvalRect (&r);
29480   ObjectRect (dlg->doc, &r);
29481   InvalRect (&r);
29482   Update ();
29483 }
29484 
29485 
29486 /* clicking on a column in the title indicates that we should sort by this column. */
ClickBulkTitle(DoC d,PoinT pt)29487 static void ClickBulkTitle (DoC d, PoinT pt)
29488 {
29489   BulkEditorDlgPtr dlg;
29490   Int2             item;
29491   Int2             row;
29492   Int2             col;
29493 
29494   MapDocPoint (d, pt, &item, &row, &col, NULL);
29495   if (item < 1) {
29496     return;
29497   }
29498   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
29499   if (dlg == NULL) return;
29500   if (col == 1) {
29501     if (dlg->display_offset > 0) {
29502       dlg->display_offset --;
29503       RedrawAfterColumnShift (dlg);
29504       return;
29505     }
29506   } else if (dlg->col_list[col].last) {
29507     if (dlg->display_offset < dlg->num_columns - dlg->columns_shown) {
29508         dlg->display_offset ++;
29509         RedrawAfterColumnShift(dlg);
29510     }
29511     return;
29512   }
29513 
29514 
29515   if (col - 2 == dlg->last_sorted_col) {
29516     /* clicked on checkbox column */
29517     col = -1;
29518   } else {
29519     col = BulkEdDataColumnFromDocColumn(col, dlg->last_sorted_col, dlg->display_offset);
29520   }
29521 
29522   SetBulkEditorSortColumn (dlg->dialog, col);
29523 }
29524 
29525 
UpdateCheckStatus(BulkEditorDlgPtr dlg)29526 static void UpdateCheckStatus (BulkEditorDlgPtr dlg)
29527 {
29528   Int4 num_selected;
29529   CharPtr status_fmt = "%d feature%s currently checked";
29530   Char status_str[50];
29531 
29532   if (dlg == NULL) return;
29533 
29534   num_selected = CountBulkEditorRowsSelected (dlg->row_list);
29535   sprintf (status_str, status_fmt, num_selected, num_selected == 1 ? "" : "s");
29536   SetTitle (dlg->check_status, status_str);
29537 }
29538 
29539 
29540 /* when clicking on field, show editor (if available), change selection, collapse/expand,
29541  * set last viewed row, populate data from previously displayed editor
29542  */
ClickBulkEdField(DoC d,PoinT pt)29543 static void ClickBulkEdField (DoC d, PoinT pt)
29544 {
29545   BulkEditorDlgPtr dlg;
29546   BulkEditorRowPtr berp;
29547   Int2            item;
29548   Int2            row;
29549   Int2            col;
29550   RecT            r;
29551   ValNodePtr      vnp;
29552   Int4            bulk_row = -1, sub_num = -1;
29553   Boolean         dblclick = dblClick;
29554 
29555   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
29556   if (dlg == NULL) return;
29557 
29558   MapDocPoint (d, pt, &item, &row, &col, NULL);
29559 
29560   if (!DataPosFromBulkEdDlgRow (item, dlg->row_list, &bulk_row, &sub_num)) {
29561     return;
29562   }
29563 
29564   if (sub_num < 0) {
29565     berp = dlg->row_list + bulk_row;
29566   } else {
29567     berp = dlg->row_list[bulk_row].subrows + sub_num;
29568   }
29569 
29570   if (col == 1) {
29571     /* do selection */
29572     berp->selected = !berp->selected;
29573     if (berp->subrows != NULL) {
29574       SelectBulkEditorRows (berp->subrows, berp->selected);
29575     } else if (sub_num > -1) {
29576       /* this is a subrow - metarow can no longer be selected
29577        * if this is not selected.
29578        */
29579       if (dlg->row_list[bulk_row].selected && !berp->selected) {
29580         dlg->row_list[bulk_row].selected = FALSE;
29581       } else if (AllBulkEditorRowsSelected(dlg->row_list[bulk_row].subrows)) {
29582         /* all child rows are now selected, so select metarow */
29583         dlg->row_list[bulk_row].selected = TRUE;
29584       }
29585     }
29586     UpdateCheckStatus (dlg);
29587     ObjectRect (dlg->doc, &r);
29588     InvalRect (&r);
29589     Update ();
29590     return;
29591   } else if (col == dlg->last_sorted_col + 2 - dlg->display_offset) {
29592     /* do expand/collapse */
29593     if (berp->subrows != NULL) {
29594       berp->expanded = !berp->expanded;
29595       UpdateBulkEdDisplay (dlg);
29596       ObjectRect (dlg->doc, &r);
29597       InvalRect (&r);
29598       Update ();
29599     }
29600     return;
29601   } else  {
29602     /* adjust to account for checkbox column */
29603     col = BulkEdDataColumnFromDocColumn(col, dlg->last_sorted_col, dlg->display_offset);
29604   }
29605   if (item < 1 || col < 0 || col >= dlg->num_columns) return;
29606   /* took out this line - use Apply button instead, less confusing */
29607   /*BulkEdDlgToField (dlg->last_viewed_row, dlg->last_viewed_col, dlg); */
29608   ResetClip();
29609 
29610   ShowBulkFieldEditor (dlg, bulk_row, sub_num, col);
29611 
29612   if (dlg->field_list[col].release_cell_func != NULL) {
29613     vnp = GetBulkEditorRowValueByColumn (berp, col);
29614     if (vnp != NULL) {
29615       vnp->data.ptrvalue = (dlg->field_list[col].release_cell_func) (vnp->data.ptrvalue);
29616     }
29617   }
29618   dlg->last_viewed_row = item;
29619   dlg->last_viewed_col = col;
29620 
29621   /* redraw highlight etc. */
29622   ObjectRect (dlg->doc, &r);
29623   InvalRect (&r);
29624   Update ();
29625 
29626 
29627   if (dblclick) {
29628     if (dlg->double_click_func != NULL) {
29629       (dlg->double_click_func) (berp->object_list, NULL);
29630     }
29631   } else {
29632     if (dlg->single_click_func != NULL) {
29633       (dlg->single_click_func) (berp->object_list, NULL);
29634     }
29635   }
29636 }
29637 
29638 
ApplyBulkEditingChange(ButtoN b)29639 static void ApplyBulkEditingChange (ButtoN b)
29640 {
29641   BulkEditorDlgPtr dlg;
29642   RecT r;
29643 
29644   dlg = (BulkEditorDlgPtr) GetObjectExtra (b);
29645   if (dlg == NULL) return;
29646 
29647   BulkEdDlgToField (dlg->last_viewed_row, dlg->last_viewed_col, dlg);
29648 
29649   /* redraw highlight etc. */
29650   Select (dlg->dialog);
29651   ObjectRect (dlg->doc, &r);
29652   InvalRect (&r);
29653   Update ();
29654 
29655 }
29656 
29657 
HighlightBulkEdField(DoC d,Int2 item,Int2 row,Int2 col)29658 static Boolean HighlightBulkEdField (DoC d, Int2 item, Int2 row, Int2 col)
29659 
29660 {
29661   BulkEditorDlgPtr dlg;
29662 
29663   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
29664   if (dlg == NULL) return FALSE;
29665 
29666   if (col == 1 || col == dlg->last_sorted_col + 1) {
29667     /* don't highlight selection column or expansion column */
29668     return FALSE;
29669   }
29670 
29671   col = BulkEdDataColumnFromDocColumn (col, dlg->last_sorted_col, dlg->display_offset);
29672 
29673   if (item == dlg->last_viewed_row && col == dlg->last_viewed_col) {
29674     return TRUE;
29675   } else {
29676     return FALSE;
29677   }
29678 }
29679 
DrawBulkEdCell(DoC d,RectPtr r,Int2 item,Int2 firstLine)29680 static void DrawBulkEdCell (DoC d, RectPtr r, Int2 item, Int2 firstLine)
29681 
29682 {
29683   Int2  lineHeight;
29684   RecT  rct;
29685   Int2  format_col, data_col;
29686   BulkEditorDlgPtr dlg;
29687   BulkEditorRowPtr berp;
29688   ValNodePtr       vnp;
29689   Int4             bulk_row_num = -1, bulk_sub_num = -1;
29690 
29691   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
29692   if (dlg == NULL || r == NULL || item <= 0 || firstLine != 0) {
29693     return;
29694   }
29695 
29696   GetItemParams (d, item, NULL, NULL, NULL, &lineHeight, NULL);
29697   rct = *r;
29698 
29699   if (!DataPosFromBulkEdDlgRow (item, dlg->row_list, &bulk_row_num, &bulk_sub_num)) {
29700     return;
29701   }
29702 
29703   /* draw lines at top of each row after the first that does not have subrows */
29704   if (bulk_row_num > 0 && bulk_sub_num < 0) {
29705     MoveTo (rct.left, rct.top);
29706     LineTo (rct.right, rct.top);
29707   }
29708 
29709   if (bulk_sub_num < 0) {
29710     berp = dlg->row_list + bulk_row_num;
29711   } else {
29712     berp = dlg->row_list[bulk_row_num].subrows + bulk_sub_num;
29713   }
29714 
29715   /* for column 0, draw selection box */
29716   format_col = 0;
29717   rct.right = rct.left + dlg->col_list[format_col].pixWidth - 1;
29718   BulkDrawSelect (berp->selected, &rct);
29719   rct.left = rct.right + 1;
29720   format_col++;
29721 
29722   for (data_col = 0, vnp = berp->values_list;
29723        data_col < dlg->num_columns && vnp != NULL;
29724        data_col++, vnp = vnp->next) {
29725 
29726     if (data_col < dlg->display_offset) {
29727       continue;
29728     } else if (data_col >= dlg->display_offset + dlg->columns_shown) {
29729       break;
29730     }
29731 
29732     rct.right = rct.left + dlg->col_list[format_col].pixWidth - 1;
29733     if (data_col == dlg->last_sorted_col) {
29734       /* draw box if expandable */
29735       if (bulk_sub_num == -1
29736           && dlg->row_list[bulk_row_num].subrows != NULL) {
29737         BulkDrawCollapseExpand (dlg->row_list[bulk_row_num].expanded, &rct);
29738       }
29739       rct.left = rct.right + 1;
29740       format_col++;
29741       rct.right = rct.left + dlg->col_list[format_col].pixWidth - 1;
29742     }
29743     if (dlg->field_list[data_col].draw_col_func != NULL) {
29744       (dlg->field_list[data_col].draw_col_func)(vnp->data.ptrvalue, &rct);
29745     }
29746     rct.left = rct.right + 1;
29747     format_col++;
29748   }
29749 }
29750 
29751 
GetFirstBulkEditValue(Pointer data,Int4 col)29752 static CharPtr GetFirstBulkEditValue (Pointer data, Int4 col)
29753 {
29754   BulkEditorDlgPtr dlg;
29755   CharPtr txt = NULL;
29756   Int4    i;
29757 
29758   if ((dlg = (BulkEditorDlgPtr) data) == NULL
29759       || col < 0 || col >= dlg->num_master_columns
29760       || dlg->master_field_list[col].get_func == NULL)
29761   {
29762     return NULL;
29763   }
29764 
29765   for (i = 0; dlg->row_list[i].object_list != NULL && txt == NULL; i++)
29766   {
29767     txt = (dlg->master_field_list[col].get_func)(dlg->row_list[i].object_list->choice, dlg->row_list[i].object_list->data.ptrvalue, dlg->metadata);
29768     if (StringHasNoText (txt)) {
29769       txt = MemFree (txt);
29770     }
29771   }
29772   return txt;
29773 }
29774 
29775 
CleanupBulkEditorDialog(GraphiC g,VoidPtr data)29776 static void CleanupBulkEditorDialog (GraphiC g, VoidPtr data)
29777 {
29778   BulkEditorDlgPtr dlg;
29779 
29780   dlg = (BulkEditorDlgPtr) data;
29781   if (dlg != NULL) {
29782     dlg->row_list = FreeBulkEditorRows(dlg->row_list, dlg->field_list);
29783     /* field list has pointers to non-freeable data, just free container */
29784     dlg->field_list = MemFree (dlg->field_list);
29785     /* col_list is structures */
29786     dlg->col_list = MemFree (dlg->col_list);
29787   }
29788   StdCleanupExtraProc (g, data);
29789 }
29790 
ApplyBulkEditorRowToObject(BulkEditorRowPtr berp,ValNodePtr target,BulkEdFieldPtr field_list,Pointer metadata,LogInfoPtr lip)29791 static void ApplyBulkEditorRowToObject (
29792   BulkEditorRowPtr berp,
29793   ValNodePtr        target,
29794   BulkEdFieldPtr   field_list,
29795   Pointer          metadata,
29796   LogInfoPtr       lip
29797 )
29798 {
29799   ValNodePtr vnp_val;
29800   Int4       i;
29801   Pointer    orig_val;
29802   CharPtr    orig_txt, new_txt, txt;
29803 
29804   if (berp == NULL || target == NULL || field_list == NULL) return;
29805 
29806   for (i = 0, vnp_val = berp->values_list;
29807        vnp_val != NULL;
29808        i++, vnp_val = vnp_val->next) {
29809     if (field_list[i].set_func != NULL) {
29810       if (lip != NULL) {
29811         orig_val = (field_list[i].get_func) (target->choice, target->data.ptrvalue, metadata);
29812         orig_txt = (field_list[i].display_func) (orig_val);
29813         new_txt = (field_list[i].display_func)(vnp_val->data.ptrvalue);
29814         if (StringCmp (orig_txt, new_txt) != 0) {
29815           txt = GetDiscrepancyItemText (target);
29816           fprintf (lip->fp, "Changed '%s' to '%s' for %s on %s\n",
29817                    orig_txt, new_txt, field_list[i].name, txt);
29818           txt = MemFree (txt);
29819           lip->data_in_log = TRUE;
29820         }
29821         orig_txt = MemFree (orig_txt);
29822         new_txt = MemFree (new_txt);
29823         field_list[i].free_func(orig_val);
29824       }
29825       (field_list[i].set_func) (target->data.ptrvalue, vnp_val->data.ptrvalue);
29826     }
29827   }
29828 }
29829 
ApplyBulkEditorToObjectList(DialoG d,Boolean do_log)29830 NLM_EXTERN void ApplyBulkEditorToObjectList (DialoG d, Boolean do_log)
29831 {
29832   BulkEditorDlgPtr dlg;
29833   Int4             row, i;
29834   LogInfoPtr       lip = NULL;
29835 
29836   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
29837   if (dlg == NULL) return;
29838 
29839   if (do_log) {
29840     lip = OpenLog ("Bulk Edit Changes");
29841   }
29842 
29843   for (row = 0; dlg->row_list[row].object_list != NULL; row++) {
29844     if (dlg->row_list[row].subrows == NULL) {
29845       ApplyBulkEditorRowToObject (dlg->row_list + row,
29846                                   dlg->row_list[row].object_list,
29847                                   dlg->field_list,
29848                                   dlg->metadata,
29849                                   lip);
29850     } else {
29851       for (i = 0; dlg->row_list[row].subrows[i].object_list != NULL; i++) {
29852         ApplyBulkEditorRowToObject (dlg->row_list[row].subrows + i,
29853                                     dlg->row_list[row].subrows[i].object_list,
29854                                     dlg->field_list,
29855                                     dlg->metadata,
29856                                     lip);
29857       }
29858     }
29859   }
29860   if (do_log) {
29861     CloseLog (lip);
29862     lip = FreeLog (lip);
29863   }
29864 }
29865 
29866 
ExportBulkEditorRow(BulkEditorRowPtr berp,ValNodePtr target,BulkEdFieldPtr field_list,Pointer metadata,FILE * fp)29867 static void ExportBulkEditorRow (
29868   BulkEditorRowPtr berp,
29869   ValNodePtr       target,
29870   BulkEdFieldPtr   field_list,
29871   Pointer          metadata,
29872   FILE *fp
29873 )
29874 {
29875   ValNodePtr vnp_val;
29876   Int4       i;
29877   Pointer    orig_val;
29878   CharPtr    orig_txt, new_txt;
29879 
29880   if (berp == NULL || target == NULL || field_list == NULL) return;
29881 
29882   /* first, print original values */
29883   for (i = 0, vnp_val = berp->values_list;
29884        vnp_val != NULL;
29885        i++, vnp_val = vnp_val->next) {
29886     orig_val = (field_list[i].get_func) (target->choice, target->data.ptrvalue, metadata);
29887     orig_txt = (field_list[i].display_func) (orig_val);
29888     fprintf (fp, "%s\t", orig_txt == NULL ? "" : orig_txt);
29889     orig_txt = MemFree (orig_txt);
29890     field_list[i].free_func(orig_val);
29891   }
29892 
29893   /* now print values that can be set */
29894   for (i = 0, vnp_val = berp->values_list;
29895        vnp_val != NULL;
29896        i++, vnp_val = vnp_val->next) {
29897     if (field_list[i].set_str_func != NULL && field_list[i].set_func != NULL) {
29898       new_txt = (field_list[i].display_func)(vnp_val->data.ptrvalue);
29899       fprintf (fp, "%s\t", new_txt == NULL ? "" : new_txt);
29900       new_txt = MemFree (new_txt);
29901     }
29902   }
29903   fprintf (fp, "\n");
29904 }
29905 
29906 
ExportBulkEditorTable(DialoG d)29907 NLM_EXTERN void ExportBulkEditorTable (DialoG d)
29908 {
29909   BulkEditorDlgPtr dlg;
29910   Int4             row, i;
29911   Char             path [PATH_MAX];
29912   FILE *fp;
29913 
29914   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
29915   if (dlg == NULL) return;
29916 
29917   if (! GetOutputFileName (path, sizeof (path), NULL)) return;
29918   fp = FileOpen (path, "w");
29919   if (fp == NULL)
29920   {
29921     Message (MSG_ERROR, "Unable to open %s", path);
29922     return;
29923   }
29924 
29925   /* print header */
29926   /* first, print original values */
29927   for (i = 0; dlg->field_list[i].name != NULL; i++) {
29928     fprintf (fp, "Original %s\t", dlg->field_list[i].name);
29929   }
29930   /* now print values that can be changed */
29931   for (i = 0; dlg->field_list[i].name != NULL; i++) {
29932     if (dlg->field_list[i].set_str_func != NULL && dlg->field_list[i].set_func != NULL) {
29933       fprintf (fp, "New %s\t", dlg->field_list[i].name);
29934     }
29935   }
29936   fprintf (fp, "\n");
29937 
29938   /* now print table values */
29939   for (row = 0; dlg->row_list[row].object_list != NULL; row++) {
29940     if (dlg->row_list[row].subrows == NULL) {
29941       ExportBulkEditorRow (dlg->row_list + row,
29942                                   dlg->row_list[row].object_list,
29943                                   dlg->field_list,
29944                                   dlg->metadata,
29945                                   fp);
29946     } else {
29947       for (i = 0; dlg->row_list[row].subrows[i].object_list != NULL; i++) {
29948         ExportBulkEditorRow (dlg->row_list[row].subrows + i,
29949                                     dlg->row_list[row].subrows[i].object_list,
29950                                     dlg->field_list,
29951                                     dlg->metadata,
29952                                     fp);
29953       }
29954     }
29955   }
29956   FileClose (fp);
29957 }
29958 
29959 
AddColumnValuesToRowList(BulkEditorRowPtr row_list,BulkEdFieldPtr master_field_list,Int4 master_pos,Int4 insert_pos,Pointer metadata)29960 static void AddColumnValuesToRowList (BulkEditorRowPtr row_list, BulkEdFieldPtr master_field_list, Int4 master_pos, Int4 insert_pos, Pointer metadata)
29961 {
29962   Int4 i, j;
29963   ValNodePtr vnp_prev, vnp;
29964 
29965   if (row_list == NULL || master_field_list == NULL) {
29966     return;
29967   }
29968 
29969   for (i = 0; row_list[i].object_list != NULL; i++) {
29970     vnp_prev = NULL;
29971     for (j = 0, vnp = row_list[i].values_list; j < insert_pos; j++, vnp = vnp->next) {
29972       vnp_prev = vnp;
29973     }
29974     vnp = ValNodeNew (NULL);
29975     vnp->choice = 0;
29976     if (row_list[i].subrows == NULL) {
29977       vnp->data.ptrvalue = master_field_list[master_pos].get_func (row_list[i].object_list->choice, row_list[i].object_list->data.ptrvalue, metadata);
29978     }
29979     if (vnp_prev == NULL) {
29980       vnp->next = row_list[i].values_list;
29981       row_list[i].values_list = vnp;
29982     } else {
29983       vnp->next = vnp_prev->next;
29984       vnp_prev->next = vnp;
29985     }
29986     AddColumnValuesToRowList (row_list[i].subrows, master_field_list, master_pos, insert_pos, metadata);
29987   }
29988 }
29989 
29990 
AddColumnToRowList(BulkEditorRowPtr row_list,BulkEdFieldPtr master_field_list,BulkEdFieldPtr PNTR p_field_list,Int4 field,Int4 last_sort_col,Pointer metadata)29991 static Int4 AddColumnToRowList (BulkEditorRowPtr row_list, BulkEdFieldPtr master_field_list, BulkEdFieldPtr PNTR p_field_list, Int4 field, Int4 last_sort_col, Pointer metadata)
29992 {
29993   Int4 i, m = 0, f = 0, num_columns = 1;
29994   BulkEdFieldPtr field_list, new_field_list;
29995 
29996   if (row_list == NULL || master_field_list == NULL || p_field_list == NULL || (field_list = *p_field_list) == NULL ||  field < 0) {
29997     return -1;
29998   }
29999 
30000   /* first, find insertion location */
30001   f = GetDlgFieldNumFromMasterFieldNum (master_field_list, *p_field_list, field);
30002   if (StringCmp (master_field_list[field].name, field_list[f].name) == 0) {
30003     /* already have column */
30004     return -1;
30005   }
30006 
30007   AddColumnValuesToRowList (row_list, master_field_list, field, f, metadata);
30008 
30009   /* insert column in field_list */
30010   for (i = 0; field_list[i].name != NULL; i++) {
30011     num_columns++;
30012   }
30013 
30014   num_columns++;
30015   new_field_list = (BulkEdFieldPtr) MemNew (sizeof (BulkEdFieldData) * num_columns);
30016   for (i = 0; i < f; i++) {
30017     new_field_list[i] = field_list[i];
30018   }
30019   new_field_list[i] = master_field_list[field];
30020   while (field_list[i].name != NULL) {
30021     new_field_list[i + 1] = field_list[i];
30022     i++;
30023   }
30024   new_field_list[i + 1] = field_list[i];
30025   field_list = MemFree (field_list);
30026   *p_field_list = new_field_list;
30027 
30028   AddSummaryInfoToMetaRows (row_list, last_sort_col);
30029 
30030   return f;
30031 }
30032 
30033 
ChangeBulkEditorAction(PopuP p)30034 static void ChangeBulkEditorAction (PopuP p)
30035 {
30036   BulkEditorDlgPtr dlg;
30037   Int4             page_num;
30038   Int4             num_pages;
30039 
30040   dlg = (BulkEditorDlgPtr) GetObjectExtra (p);
30041   if (dlg == NULL || !dlg->any_editing) return;
30042 
30043   num_pages = sizeof (dlg->action_pages) / sizeof (GrouP);
30044   for (page_num = 0; page_num < num_pages; page_num++) {
30045     Hide (dlg->action_pages[page_num]);
30046   }
30047   page_num = GetValue (dlg->bulk_action) - 1;
30048   if (page_num > -1 && page_num < num_pages) {
30049     Show (dlg->action_pages[page_num]);
30050   }
30051 }
30052 
RemoveColumnFromSelectedBulkEditRows(BulkEditorRowPtr row_list,Int4 col,BulkEdFieldPtr field_list,Boolean select_all)30053 static void RemoveColumnFromSelectedBulkEditRows (BulkEditorRowPtr row_list, Int4 col, BulkEdFieldPtr field_list, Boolean select_all)
30054 {
30055   ValNodePtr vnp;
30056 
30057   if (row_list == NULL || col < 0 || field_list == NULL) return;
30058   while (row_list->object_list != NULL) {
30059     if (row_list->selected || select_all) {
30060       if (row_list->subrows == NULL || AllBulkEditorRowsSelected(row_list->subrows) || select_all) {
30061         vnp = GetBulkEditorRowValueByColumn (row_list, col);
30062         if (vnp != NULL) {
30063           field_list[col].free_func(vnp->data.ptrvalue);
30064           vnp->data.ptrvalue = NULL;
30065         }
30066       }
30067     }
30068     RemoveColumnFromSelectedBulkEditRows (row_list->subrows, col, field_list, select_all);
30069     row_list++;
30070   }
30071 }
30072 
30073 static void
ApplyEditColumnFromSelectedBulkEditRows(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,Int4 col,ApplyValuePtr avp,Boolean select_all)30074 ApplyEditColumnFromSelectedBulkEditRows
30075 (BulkEditorRowPtr berp,
30076  BulkEdFieldPtr   field_list,
30077  Int4             col,
30078  ApplyValuePtr    avp,
30079  Boolean select_all)
30080 {
30081   ValNodePtr     vnp;
30082 
30083   if (berp == NULL) return;
30084 
30085   while (berp->object_list != NULL) {
30086     if (berp->selected || select_all) {
30087       if (berp->subrows == NULL || AllBulkEditorRowsSelected(berp->subrows) || select_all) {
30088         vnp = GetBulkEditorRowValueByColumn (berp, col);
30089         if (vnp != NULL) {
30090           vnp->data.ptrvalue = (field_list[col].set_str_func) (vnp->data.ptrvalue, avp);
30091         }
30092       }
30093     }
30094     ApplyEditColumnFromSelectedBulkEditRows (berp->subrows, field_list, col, avp, select_all);
30095     berp++;
30096   }
30097 }
30098 
30099 
30100 static void
CapitalizeColumnsForSelectedBulkEditRows(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,Int4 col,ChangeCasePtr capitalization,Boolean select_all)30101 CapitalizeColumnsForSelectedBulkEditRows
30102 (BulkEditorRowPtr berp,
30103  BulkEdFieldPtr   field_list,
30104  Int4             col,
30105  ChangeCasePtr    capitalization,
30106  Boolean          select_all)
30107 {
30108   ValNodePtr     vnp;
30109   CharPtr        val_str;
30110   ApplyValueData avd;
30111   SeqFeatPtr     sfp;
30112   SeqEntryPtr    sep, last_sep = NULL;
30113   ValNodePtr     orgname_list = NULL;
30114 
30115   if (berp == NULL) return;
30116 
30117   avd.field_list = NULL;
30118   avd.text_to_replace = NULL;
30119   avd.where_to_replace = EditApplyFindLocation_anywhere;
30120   avd.etp = NULL;
30121 
30122   while (berp->object_list != NULL) {
30123     if (berp->selected || select_all) {
30124       if (berp->subrows == NULL || AllBulkEditorRowsSelected(berp->subrows) || select_all) {
30125         vnp = GetBulkEditorRowValueByColumn (berp, col);
30126         if (vnp != NULL) {
30127           val_str = (field_list[col].display_func)(vnp->data.ptrvalue);
30128           if (!StringHasNoText (val_str)) {
30129             if (berp->object_list->choice == OBJ_SEQFEAT && berp->object_list->data.ptrvalue != NULL) {
30130               sfp = (SeqFeatPtr) berp->object_list->data.ptrvalue;
30131               sep = GetTopSeqEntryForEntityID (sfp->idx.entityID);
30132               if (sep != last_sep) {
30133                 orgname_list = ValNodeFree (orgname_list);
30134                 /* get org names to use in fixes */
30135                 VisitBioSourcesInSep (sep, &orgname_list, GetOrgNamesInRecordCallback);
30136                 last_sep = sep;
30137               }
30138             }
30139             ChangeCase (&val_str, capitalization, orgname_list);
30140             avd.new_text = val_str;
30141             vnp->data.ptrvalue = (field_list[col].set_str_func) (vnp->data.ptrvalue, &avd);
30142           }
30143           val_str = MemFree (val_str);
30144         }
30145       }
30146     }
30147     CapitalizeColumnsForSelectedBulkEditRows (berp->subrows, field_list, col, capitalization, select_all);
30148     berp++;
30149   }
30150   orgname_list = ValNodeFree (orgname_list);
30151 }
30152 
RemoveNameFromText(CharPtr orig,CharPtr remove)30153 static void RemoveNameFromText (CharPtr orig, CharPtr remove)
30154 {
30155   CharPtr cp, cp_dst;
30156   Int4    len;
30157 
30158   if (StringHasNoText (orig) || StringHasNoText (remove)) {
30159     return;
30160   }
30161   cp = StringISearch (orig, remove);
30162   if (cp != NULL) {
30163     len = StringLen (remove);
30164     cp_dst = cp;
30165     cp = cp + len;
30166     while (*cp != 0 && len > 0) {
30167       *cp_dst = *cp;
30168       cp_dst++;
30169       cp++;
30170       len--;
30171     }
30172     *cp_dst = 0;
30173   }
30174 }
30175 
ConvertColumnsForSelectedBulkEditRows(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,TwoFieldBulkEditPtr tfp,ExistingTextPtr etp,Boolean select_all)30176 static void ConvertColumnsForSelectedBulkEditRows
30177 (BulkEditorRowPtr    berp,
30178  BulkEdFieldPtr      field_list,
30179  TwoFieldBulkEditPtr tfp,
30180  ExistingTextPtr     etp,
30181  Boolean             select_all)
30182 {
30183   ValNodePtr vnp_from, vnp_to;
30184   CharPtr    val_from;
30185   ApplyValueData avd;
30186   if (berp == NULL || tfp == NULL) return;
30187 
30188   avd.field_list = NULL;
30189   avd.text_to_replace = NULL;
30190   avd.where_to_replace = EditApplyFindLocation_anywhere;
30191   avd.etp = etp;
30192 
30193   while (berp->object_list != NULL) {
30194     if ((berp->selected || select_all) && berp->subrows == NULL) {
30195       vnp_from = GetBulkEditorRowValueByColumn (berp, tfp->field_from);
30196       vnp_to   = GetBulkEditorRowValueByColumn (berp, tfp->field_to);
30197       if (vnp_from != NULL && vnp_to != NULL) {
30198         val_from = (field_list[tfp->field_from].display_func)(vnp_from->data.ptrvalue);
30199         if (StringDoesHaveText (val_from)) {
30200           if (tfp->strip_name) {
30201             RemoveNameFromText (val_from, field_list[tfp->field_to].name);
30202           }
30203 
30204           avd.new_text = val_from;
30205           vnp_to->data.ptrvalue = (field_list[tfp->field_to].set_str_func) (vnp_to->data.ptrvalue, &avd);
30206 
30207           if (!tfp->leave_on_original) {
30208             (field_list[tfp->field_from].free_func)(vnp_from->data.ptrvalue);
30209             vnp_from->data.ptrvalue = NULL;
30210           }
30211 
30212         }
30213         val_from = MemFree (val_from);
30214       }
30215     }
30216     ConvertColumnsForSelectedBulkEditRows (berp->subrows, field_list, tfp, etp, select_all);
30217     berp++;
30218   }
30219 }
30220 
30221 
ParseColumnsForSelectedBulkEditRows(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,TwoFieldBulkEditPtr tfp,ExistingTextPtr etp,Boolean select_all)30222 static void ParseColumnsForSelectedBulkEditRows
30223 (BulkEditorRowPtr    berp,
30224  BulkEdFieldPtr      field_list,
30225  TwoFieldBulkEditPtr tfp,
30226  ExistingTextPtr     etp,
30227  Boolean             select_all)
30228 {
30229   ValNodePtr vnp_from, vnp_to;
30230   CharPtr    val_from, val_to;
30231   ApplyValueData avd;
30232   if (berp == NULL || tfp == NULL) return;
30233 
30234   avd.field_list = NULL;
30235   avd.text_to_replace = NULL;
30236   avd.where_to_replace = EditApplyFindLocation_anywhere;
30237   avd.etp = etp;
30238 
30239   while (berp->object_list != NULL) {
30240     if ((berp->selected || select_all) && berp->subrows == NULL) {
30241       vnp_from = GetBulkEditorRowValueByColumn (berp, tfp->field_from);
30242       vnp_to   = GetBulkEditorRowValueByColumn (berp, tfp->field_to);
30243       if (vnp_from != NULL && vnp_to != NULL) {
30244         val_from = (field_list[tfp->field_from].display_func)(vnp_from->data.ptrvalue);
30245         val_to = NULL;
30246         if (StringDoesHaveText (val_from)) {
30247           val_to = ReplaceStringForParse(val_from, tfp->text_portion);
30248           if (StringDoesHaveText (val_to)) {
30249             avd.new_text = val_to;
30250             vnp_to->data.ptrvalue = (field_list[tfp->field_to].set_str_func) (vnp_to->data.ptrvalue, &avd);
30251           }
30252           if (tfp->remove_parsed) {
30253             avd.new_text = val_from;
30254             avd.etp = NULL;
30255             vnp_from->data.ptrvalue = (field_list[tfp->field_from].set_str_func) (vnp_from->data.ptrvalue, &avd);
30256             avd.etp = etp;
30257           }
30258         }
30259         val_from = MemFree (val_from);
30260         val_to = MemFree (val_to);
30261       }
30262     }
30263     ParseColumnsForSelectedBulkEditRows (berp->subrows, field_list, tfp, etp, select_all);
30264     berp++;
30265   }
30266 }
30267 
30268 
SwapColumnsForSelectedBulkEditRows(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,Int4 col_from,Int4 col_to,Boolean select_all)30269 static void SwapColumnsForSelectedBulkEditRows
30270 (BulkEditorRowPtr berp,
30271  BulkEdFieldPtr   field_list,
30272  Int4             col_from,
30273  Int4             col_to,
30274  Boolean          select_all)
30275 {
30276   ValNodePtr vnp_from, vnp_to;
30277   CharPtr    val_from, val_to;
30278   ApplyValueData avd;
30279   if (berp == NULL) return;
30280 
30281   avd.etp = NULL;
30282   avd.field_list = NULL;
30283   avd.text_to_replace = NULL;
30284   avd.where_to_replace = EditApplyFindLocation_anywhere;
30285 
30286   while (berp->object_list != NULL) {
30287     if ((berp->selected || select_all) && berp->subrows == NULL) {
30288       vnp_from = GetBulkEditorRowValueByColumn (berp, col_from);
30289       vnp_to   = GetBulkEditorRowValueByColumn (berp, col_to);
30290       if (vnp_from != NULL && vnp_to != NULL) {
30291         val_from = (field_list[col_from].display_func)(vnp_from->data.ptrvalue);
30292         val_to = (field_list[col_to].display_func)(vnp_to->data.ptrvalue);
30293         if (StringDoesHaveText (val_from) || StringDoesHaveText (val_to)) {
30294           avd.new_text = val_to;
30295           vnp_from->data.ptrvalue = (field_list[col_from].set_str_func) (vnp_from->data.ptrvalue, &avd);
30296 
30297           avd.new_text = val_from;
30298           vnp_to->data.ptrvalue = (field_list[col_to].set_str_func) (vnp_to->data.ptrvalue, &avd);
30299         }
30300         val_from = MemFree (val_from);
30301         val_to = MemFree (val_to);
30302       }
30303     }
30304     SwapColumnsForSelectedBulkEditRows (berp->subrows, field_list, col_from, col_to, select_all);
30305     berp++;
30306   }
30307 }
30308 
30309 
30310 
30311 static void
AddSampleDataForBulkEditorSelectedFeatures(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,Int4 col,Int4 col_src,GetSamplePtr gsp,TextPortionXPtr text_portion,Boolean select_all)30312 AddSampleDataForBulkEditorSelectedFeatures
30313 (BulkEditorRowPtr berp,
30314  BulkEdFieldPtr   field_list,
30315  Int4             col,
30316  Int4             col_src,
30317  GetSamplePtr     gsp,
30318  TextPortionXPtr   text_portion,
30319  Boolean           select_all)
30320 {
30321   CharPtr    str, str_src, str_parse;
30322   ValNodePtr vnp, vnp_src;
30323   Boolean    skip;
30324 
30325   if (berp == NULL || field_list == NULL || col < 0 || field_list[col].display_func == NULL || gsp == NULL) return;
30326 
30327   while (berp->object_list != NULL) {
30328     if (berp->subrows == NULL && (berp->selected || select_all)) {
30329       vnp = GetBulkEditorRowValueByColumn (berp, col);
30330       if (vnp != NULL) {
30331         str = (field_list[col]).display_func (vnp->data.ptrvalue);
30332         if (!StringHasNoText (str)) {
30333           skip = FALSE;
30334           /* only add values if col_src < 0 or data in col_src is not blank */
30335           if (col_src >= 0) {
30336             skip = TRUE;
30337             vnp_src = GetBulkEditorRowValueByColumn (berp, col_src);
30338             if (vnp_src != NULL) {
30339               str_src = (field_list[col_src]).display_func(vnp_src->data.ptrvalue);
30340               if (StringDoesHaveText (str_src)) {
30341                 if (text_portion == NULL) {
30342                   skip = FALSE;
30343                 } else {
30344                   str_parse = ReplaceStringForParse(str_src, text_portion);
30345                   if (StringDoesHaveText (str_parse)) {
30346                     skip = FALSE;
30347                   }
30348                   str_parse = MemFree (str_parse);
30349                 }
30350               }
30351               str_src = MemFree (str_src);
30352             }
30353           }
30354           if (!skip) {
30355             gsp->num_found++;
30356             if (gsp->sample_text == NULL) {
30357               gsp->sample_text = str;
30358               str = NULL;
30359             } else if (StringCmp (str, gsp->sample_text) != 0) {
30360               gsp->all_same = FALSE;
30361             }
30362           }
30363         }
30364         str = MemFree (str);
30365       }
30366     }
30367     AddSampleDataForBulkEditorSelectedFeatures (berp->subrows, field_list, col, col_src, gsp, text_portion, select_all);
30368     berp++;
30369   }
30370 }
30371 
30372 
30373 static GetSamplePtr
GetSampleDataForBulkEditorSelectedFeatures(BulkEditorRowPtr berp,BulkEdFieldPtr field_list,Int4 col,Int4 col_src,TextPortionXPtr text_portion,Boolean select_all)30374 GetSampleDataForBulkEditorSelectedFeatures
30375 (BulkEditorRowPtr berp,
30376  BulkEdFieldPtr   field_list,
30377  Int4             col,
30378  Int4             col_src,
30379  TextPortionXPtr   text_portion,
30380  Boolean           select_all)
30381 {
30382   GetSamplePtr gsp;
30383 
30384   if (berp == NULL || field_list == NULL || col < 0) return NULL;
30385 
30386   gsp = GetSampleNew ();
30387 
30388   AddSampleDataForBulkEditorSelectedFeatures(berp, field_list, col, col_src, gsp, text_portion, select_all);
30389 
30390   return gsp;
30391 }
30392 
30393 
AdjustBulkEditPositions(BulkEditorDlgPtr dlg,Int4 added_col)30394 static void AdjustBulkEditPositions (BulkEditorDlgPtr dlg, Int4 added_col)
30395 {
30396   if (added_col > -1) {
30397     if (added_col <= dlg->last_viewed_col) {
30398       dlg->last_viewed_col++;
30399     }
30400     if (added_col <= dlg->last_sorted_col) {
30401       dlg->last_sorted_col++;
30402     }
30403     dlg->num_columns++;
30404   }
30405 }
30406 
30407 
ApplyBulkEditCommon(BulkEditorDlgPtr dlg,Boolean select_all)30408 static void ApplyBulkEditCommon (BulkEditorDlgPtr dlg, Boolean select_all)
30409 {
30410   RecT             r;
30411   GetSamplePtr     gsp = NULL;
30412   ExistingTextPtr  etp = NULL;
30413   ApplyValueData   avd;
30414   OneFieldBulkEditPtr ofp = NULL;
30415   TwoFieldBulkEditPtr tfp = NULL;
30416   Int4                bulk_row_num, bulk_sub_num, i;
30417   Int4                added_col1 = -1, added_col2 = -1;
30418   Boolean             need_redraw = FALSE;
30419 
30420   if (dlg == NULL) return;
30421 
30422   switch (GetValue (dlg->bulk_action)) {
30423     case eBulkRemoveField:
30424       ofp = (OneFieldBulkEditPtr) DialogToPointer (dlg->bulk_remove);
30425       if (ofp != NULL) {
30426         added_col1 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), ofp->field, dlg->last_sorted_col, dlg->metadata);
30427         AdjustOneFieldForMaster (ofp, dlg->master_field_list, dlg->field_list);
30428         RemoveColumnFromSelectedBulkEditRows (dlg->row_list, ofp->field, dlg->field_list, select_all);
30429       }
30430       break;
30431     case eBulkApplyField:
30432       ofp = (OneFieldBulkEditPtr) DialogToPointer (dlg->bulk_apply);
30433       if (ofp != NULL) {
30434         /* add field to table, if it's not in the table yet */
30435         added_col1 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), ofp->field, dlg->last_sorted_col, dlg->metadata);
30436         AdjustOneFieldForMaster (ofp, dlg->master_field_list, dlg->field_list);
30437 
30438         /* warn about existing values */
30439         gsp = GetSampleDataForBulkEditorSelectedFeatures (dlg->row_list, dlg->field_list, ofp->field, -1, NULL, select_all);
30440         etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
30441         if (etp == NULL || etp->existing_text_choice != eExistingTextChoiceCancel) {
30442           avd.etp = etp;
30443           avd.field_list = NULL;
30444           AddEditApplyDataToApplyValue (AECR_APPLY, ofp->edit_apply, &avd);
30445           ApplyEditColumnFromSelectedBulkEditRows (dlg->row_list, dlg->field_list, ofp->field, &avd, select_all);
30446         }
30447       }
30448       break;
30449     case eBulkEditField:
30450       ofp = (OneFieldBulkEditPtr) DialogToPointer (dlg->bulk_edit);
30451       if (ofp != NULL) {
30452         added_col1 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), ofp->field, dlg->last_sorted_col, dlg->metadata);
30453         AdjustOneFieldForMaster (ofp, dlg->master_field_list, dlg->field_list);
30454         avd.etp = NULL;
30455         avd.field_list = NULL;
30456         AddEditApplyDataToApplyValue (AECR_EDIT, ofp->edit_apply, &avd);
30457         ApplyEditColumnFromSelectedBulkEditRows (dlg->row_list, dlg->field_list, ofp->field, &avd, select_all);
30458       }
30459       break;
30460     case eBulkCapitalizeField:
30461       ofp = (OneFieldBulkEditPtr) DialogToPointer (dlg->bulk_capitalize);
30462       if (ofp != NULL && ofp->capitalization != NULL && ofp->capitalization->change != eChangeCaseNone) {
30463         added_col1 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), ofp->field, dlg->last_sorted_col, dlg->metadata);
30464         AdjustOneFieldForMaster (ofp, dlg->master_field_list, dlg->field_list);
30465         CapitalizeColumnsForSelectedBulkEditRows (dlg->row_list, dlg->field_list, ofp->field, ofp->capitalization, select_all);
30466       }
30467       break;
30468     case eBulkConvertField:
30469       tfp = (TwoFieldBulkEditPtr) DialogToPointer (dlg->bulk_convert);
30470       if (tfp != NULL) {
30471         added_col1 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), tfp->field_to, dlg->last_sorted_col, dlg->metadata);
30472         added_col2 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), tfp->field_from, dlg->last_sorted_col, dlg->metadata);
30473         AdjustTwoFieldsForMaster (tfp, dlg->master_field_list, dlg->field_list);
30474 
30475         gsp = GetSampleDataForBulkEditorSelectedFeatures (dlg->row_list, dlg->field_list, tfp->field_to, tfp->field_from, NULL, select_all);
30476         etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
30477         if (etp == NULL || etp->existing_text_choice != eExistingTextChoiceCancel) {
30478           ConvertColumnsForSelectedBulkEditRows (dlg->row_list, dlg->field_list, tfp, etp, select_all);
30479         }
30480       }
30481       break;
30482     case eBulkParseField:
30483       tfp = (TwoFieldBulkEditPtr) DialogToPointer (dlg->bulk_parse);
30484       if (tfp != NULL) {
30485         added_col1 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), tfp->field_to, dlg->last_sorted_col, dlg->metadata);
30486         added_col2 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), tfp->field_from, dlg->last_sorted_col, dlg->metadata);
30487         AdjustTwoFieldsForMaster (tfp, dlg->master_field_list, dlg->field_list);
30488         gsp = GetSampleDataForBulkEditorSelectedFeatures (dlg->row_list, dlg->field_list, tfp->field_to, tfp->field_from, tfp->text_portion, select_all);
30489         etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
30490         if (etp == NULL || etp->existing_text_choice != eExistingTextChoiceCancel) {
30491           ParseColumnsForSelectedBulkEditRows (dlg->row_list, dlg->field_list, tfp, etp, select_all);
30492         }
30493       }
30494       break;
30495     case eBulkSwapField:
30496       tfp = (TwoFieldBulkEditPtr) DialogToPointer (dlg->bulk_swap);
30497       if (tfp != NULL) {
30498         added_col1 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), tfp->field_to, dlg->last_sorted_col, dlg->metadata);
30499         added_col2 = AddColumnToRowList (dlg->row_list, dlg->master_field_list, &(dlg->field_list), tfp->field_from, dlg->last_sorted_col, dlg->metadata);
30500         AdjustTwoFieldsForMaster (tfp, dlg->master_field_list, dlg->field_list);
30501         SwapColumnsForSelectedBulkEditRows (dlg->row_list, dlg->field_list, tfp->field_from, tfp->field_to, select_all);
30502       }
30503       break;
30504   }
30505 
30506   ofp = OneFieldBulkEditFree (ofp);
30507   tfp = TwoFieldBulkEditFree (tfp);
30508   gsp = GetSampleFree (gsp);
30509   etp = MemFree (etp);
30510 
30511   AdjustBulkEditPositions (dlg, added_col1);
30512   AdjustBulkEditPositions (dlg, added_col2);
30513 
30514   AddSummaryInfoToMetaRows (dlg->row_list, dlg->last_sorted_col);
30515 
30516   /* update individual field editor */
30517   if (dlg->last_viewed_row > 0) {
30518     /* show appropriate editor for highlighted item */
30519     if (DataPosFromBulkEdDlgRow (dlg->last_viewed_row, dlg->row_list, &bulk_row_num, &bulk_sub_num)) {
30520       ShowBulkFieldEditor (dlg, bulk_row_num, bulk_sub_num, dlg->last_viewed_col);
30521     } else {
30522       dlg->last_viewed_row = 0;
30523       dlg->last_viewed_col = 0;
30524       for (i = 0; i < dlg->num_master_columns; i++) {
30525         SafeHide (dlg->editor_list[i]);
30526       }
30527       Hide (dlg->ed_btn_grp);
30528     }
30529   }
30530 
30531   if (added_col1 > -1 || added_col2 > -1) {
30532     RedrawAfterColumnShift (dlg);
30533   } else {
30534     UpdateBulkEdDisplay (dlg);
30535     ObjectRect (dlg->doc, &r);
30536     InvalRect (&r);
30537     Update ();
30538   }
30539 }
30540 
30541 
ApplyBulkEditAll(ButtoN b)30542 static void ApplyBulkEditAll (ButtoN b)
30543 {
30544   BulkEditorDlgPtr dlg;
30545 
30546   dlg = (BulkEditorDlgPtr) GetObjectExtra (b);
30547   if (dlg == NULL) return;
30548 
30549   ApplyBulkEditCommon (dlg, TRUE);
30550 }
30551 
ApplyBulkEdit(ButtoN b)30552 static void ApplyBulkEdit (ButtoN b)
30553 {
30554   BulkEditorDlgPtr dlg;
30555   Boolean             select_all = FALSE;
30556 
30557   dlg = (BulkEditorDlgPtr) GetObjectExtra (b);
30558   if (dlg == NULL) return;
30559 
30560   if (CountBulkEditorRowsSelected(dlg->row_list) == 0) {
30561     if (ANS_CANCEL == Message (MSG_OKC, "No items selected!  Apply to all?")) {
30562       return;
30563     } else {
30564       select_all = TRUE;
30565     }
30566   }
30567 
30568   ApplyBulkEditCommon (dlg, select_all);
30569 }
30570 
30571 
BulkEditorCheckAllDialog(DialoG d)30572 extern void BulkEditorCheckAllDialog (DialoG d)
30573 {
30574   BulkEditorDlgPtr dlg;
30575   RecT             r;
30576 
30577   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
30578   if (dlg == NULL) return;
30579 
30580   SelectBulkEditorRows (dlg->row_list, TRUE);
30581   UpdateCheckStatus (dlg);
30582   ObjectRect (dlg->doc, &r);
30583   InvalRect (&r);
30584   Update ();
30585 }
30586 
BulkEditorCheckAll(ButtoN b)30587 static void BulkEditorCheckAll (ButtoN b)
30588 {
30589   BulkEditorDlgPtr dlg;
30590   RecT             r;
30591 
30592   dlg = (BulkEditorDlgPtr) GetObjectExtra (b);
30593   if (dlg == NULL) return;
30594 
30595   SelectBulkEditorRows (dlg->row_list, TRUE);
30596   UpdateCheckStatus (dlg);
30597   ObjectRect (dlg->doc, &r);
30598   InvalRect (&r);
30599   Update ();
30600 }
30601 
30602 
BulkEditorUncheckAll(ButtoN b)30603 static void BulkEditorUncheckAll (ButtoN b)
30604 {
30605   BulkEditorDlgPtr dlg;
30606   RecT             r;
30607 
30608   dlg = (BulkEditorDlgPtr) GetObjectExtra (b);
30609   if (dlg == NULL) return;
30610 
30611   SelectBulkEditorRows (dlg->row_list, FALSE);
30612   UpdateCheckStatus (dlg);
30613   ObjectRect (dlg->doc, &r);
30614   InvalRect (&r);
30615   Update ();
30616 }
30617 
BulkEditorStringConstraintCheck(ButtoN b)30618 static void BulkEditorStringConstraintCheck (ButtoN b)
30619 {
30620   BulkEditorDlgPtr    dlg;
30621   RecT                r;
30622   Int4                field_num;
30623   StringConstraintXPtr scp;
30624   Boolean             val;
30625 
30626   dlg = (BulkEditorDlgPtr) GetObjectExtra (b);
30627   if (dlg == NULL) return;
30628 
30629   field_num = GetFieldNumFromPopupValue(GetValue (dlg->check_constraint_field), dlg->field_list, FALSE);
30630   scp = DialogToPointer (dlg->check_constraint);
30631 
30632   if (GetValue (dlg->sel_unsel_grp) == 1) {
30633     val = TRUE;
30634   } else {
30635     val = FALSE;
30636   }
30637 
30638   SelectBulkEditorRowsByStringConstraint (dlg->row_list, dlg->field_list, field_num, scp, val);
30639 
30640   scp = StringConstraintXFree (scp);
30641   UpdateCheckStatus (dlg);
30642 
30643   ObjectRect (dlg->doc, &r);
30644   InvalRect (&r);
30645   Update ();
30646 }
30647 
30648 
ObjectListToBulkEditorDialog(DialoG d,Pointer data)30649 static void ObjectListToBulkEditorDialog (DialoG d, Pointer data)
30650 {
30651   BulkEditorDlgPtr dlg;
30652   ValNodePtr       object_list;
30653 
30654   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
30655   if (dlg == NULL) return;
30656   object_list = (ValNodePtr) data;
30657 
30658   dlg->row_list = FreeBulkEditorRows(dlg->row_list, dlg->field_list);
30659   dlg->row_list = MakeBulkEditorRowsFromObjectList (object_list, dlg->field_list, dlg->last_sorted_col, dlg->metadata);
30660   if (dlg->collapse_by_default) {
30661     CollapseAllBulkEditRows (dlg->row_list);
30662   } else {
30663     ExpandAllBulkEditRows (dlg->row_list);
30664   }
30665   ResetClip();
30666   UpdateBulkEdDisplay (dlg);
30667   UpdateCheckStatus (dlg);
30668 }
30669 
30670 
GetSelectedObjectsFromBulkEditorDialog(DialoG d)30671 static Pointer GetSelectedObjectsFromBulkEditorDialog (DialoG d)
30672 {
30673   BulkEditorDlgPtr dlg;
30674   ValNodePtr       object_list = NULL;
30675 
30676   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
30677   if (dlg == NULL) return NULL;
30678 
30679   GetBulkEditorSelectedObjects (dlg->row_list, &object_list);
30680   return (Pointer) object_list;
30681 }
30682 
30683 
CopyEditToClipboard(ButtoN b)30684 static void CopyEditToClipboard (ButtoN b)
30685 {
30686   BulkEditorDlgPtr dlg;
30687   CharPtr str;
30688   Int2    edit_col;
30689 
30690   dlg = (BulkEditorDlgPtr) GetObjectExtra (b);
30691   if (dlg == NULL) {
30692     return;
30693   }
30694   if (dlg->last_viewed_col < 0
30695     || dlg->last_viewed_col >= dlg->num_columns) {
30696     return;
30697   }
30698   edit_col = GetMasterFieldNumFromDlgFieldNum (dlg->master_field_list, dlg->field_list, dlg->last_viewed_col);
30699   if (dlg->editor_list[edit_col] == NULL) {
30700     return;
30701   }
30702   str = DialogToPointer (dlg->editor_list[edit_col]);
30703   if (!StringHasNoText (str)) {
30704     StringToClipboard (str);
30705   }
30706   str = MemFree (str);
30707 }
30708 
30709 
CopyEditFromClipboard(ButtoN b)30710 static void CopyEditFromClipboard (ButtoN b)
30711 {
30712   BulkEditorDlgPtr dlg;
30713   CharPtr str;
30714   Int2    edit_col;
30715 
30716   dlg = (BulkEditorDlgPtr) GetObjectExtra (b);
30717   if (dlg == NULL) {
30718     return;
30719   }
30720   if (dlg->last_viewed_col < 0
30721     || dlg->last_viewed_col >= dlg->num_columns) {
30722     return;
30723   }
30724   edit_col = GetMasterFieldNumFromDlgFieldNum (dlg->master_field_list, dlg->field_list, dlg->last_viewed_col);
30725   if (dlg->editor_list[edit_col] == NULL) {
30726     return;
30727   }
30728   str = ClipboardToString ();
30729   if (!StringHasNoText (str)) {
30730     PointerToDialog (dlg->editor_list[edit_col], str);
30731   }
30732   str = MemFree (str);
30733 }
30734 
30735 
GetPopulatedFieldsFromMasterList(BulkEdFieldPtr master_field_list,BulkEditorRowPtr row_list)30736 static BulkEdFieldPtr GetPopulatedFieldsFromMasterList (BulkEdFieldPtr master_field_list, BulkEditorRowPtr row_list)
30737 {
30738   Int4 i, num_fields = 0;
30739   BoolPtr empties;
30740   Int4 num_full = 0;
30741   BulkEdFieldPtr pop_fields;
30742 
30743   for (i = 0; master_field_list[i].name != NULL; i++) {
30744     num_fields++;
30745   }
30746 
30747   empties = (BoolPtr) MemNew (sizeof (Boolean) * num_fields);
30748   for (i = 0; i < num_fields; i++) {
30749     if (IsBulkEditorColumnEmpty (row_list, i)) {
30750       empties[i] = TRUE;
30751     } else {
30752       empties[i] = FALSE;
30753       num_full++;
30754     }
30755   }
30756 
30757   pop_fields = (BulkEdFieldPtr) MemNew (sizeof (BulkEdFieldData) * (num_full + 1));
30758   num_full = 0;
30759   for (i = 0; i < num_fields; i++) {
30760     if (!empties[i]) {
30761       pop_fields[num_full++] = master_field_list[i];
30762     }
30763   }
30764   pop_fields[num_full] = master_field_list[num_fields];
30765   empties = MemFree (empties);
30766   return pop_fields;
30767 }
30768 
30769 
CopyAllFieldsFromList(BulkEdFieldPtr master_field_list)30770 static BulkEdFieldPtr CopyAllFieldsFromList (BulkEdFieldPtr master_field_list)
30771 {
30772   Int4 i, num_fields = 0;
30773   Int4 num_full = 0;
30774   BulkEdFieldPtr pop_fields;
30775 
30776   for (i = 0; master_field_list[i].name != NULL; i++) {
30777     num_fields++;
30778   }
30779 
30780 
30781   pop_fields = (BulkEdFieldPtr) MemNew (sizeof (BulkEdFieldData) * (num_fields + 1));
30782   for (i = 0; i < num_fields; i++) {
30783     pop_fields[i] = master_field_list[i];
30784   }
30785   pop_fields[num_fields] = master_field_list[num_fields];
30786   return pop_fields;
30787 }
30788 
FinishBulkEditorDialogSetup(GrouP p,BulkEditorDlgPtr dlg)30789 static void FinishBulkEditorDialogSetup (GrouP p, BulkEditorDlgPtr dlg)
30790 {
30791   Int4             width, num_columns = 0;
30792   Int4             i, page_num;
30793   GrouP            ed_grp, ed2_grp, check_grp, action_grp, page_grp, box_grp;
30794   GrouP            g1, g2, a, g_tmp, g_tmp2;
30795   ButtoN           b;
30796 
30797   if (p == NULL || dlg == NULL) {
30798     return;
30799   }
30800 
30801   dlg->dialog = (DialoG) p;
30802   dlg->todialog = ObjectListToBulkEditorDialog;
30803   dlg->fromdialog = GetSelectedObjectsFromBulkEditorDialog;
30804   dlg->testdialog = NULL;
30805 
30806   /* look for editing functions */
30807   dlg->num_master_columns = 0;
30808   dlg->any_editing = FALSE;
30809   for (i = 0; dlg->master_field_list[i].name != NULL; i++) {
30810     if (dlg->master_field_list[i].create_dlg_func != NULL) {
30811       dlg->any_editing = TRUE;
30812     }
30813     dlg->num_master_columns++;
30814   }
30815   /* count columns */
30816   for (i = 0; dlg->field_list[i].name != NULL; i++) {
30817     num_columns++;
30818   }
30819 
30820   dlg->num_columns = num_columns;
30821   dlg->columns_shown = num_columns;
30822   dlg->display_offset = 0;
30823   /* populate values list */
30824 
30825   SelectFont (systemFont);
30826   dlg->col_list = AllocateDocColumnsForFieldList (dlg->field_list, &width, dlg->last_sorted_col, dlg->display_offset, dlg->columns_shown);
30827   dlg->par_fmt.minLines = 1;
30828   dlg->par_fmt.minHeight = 1;
30829 
30830   dlg->title_doc = DocumentPanel (p, width, stdLineHeight);
30831   InitBulkEdTitleDoc (dlg, dlg->title_doc);
30832   SetObjectExtra (dlg->title_doc, dlg, NULL);
30833   SetDocProcs (dlg->title_doc, ClickBulkTitle, NULL, NULL, NULL);
30834 
30835   dlg->doc = DocumentPanel (p, width, 10 * stdLineHeight);
30836   SetObjectExtra (dlg->doc, dlg, NULL);
30837   SetDocProcs (dlg->doc, ClickBulkEdField, NULL, NULL, NULL);
30838   SetDocShade (dlg->doc, DrawBulkEdCell, NULL, HighlightBulkEdField, NULL);
30839 
30840   ed_grp = HiddenGroup (p, 4, 0, NULL);
30841   SetGroupSpacing (ed_grp, 10, 10);
30842   ed2_grp = HiddenGroup (ed_grp, 0, 0, NULL);
30843   dlg->editor_list = (DialoG PNTR) MemNew (sizeof(DialoG) * dlg->num_master_columns);
30844   for (i = 0; dlg->master_field_list[i].name != NULL; i++) {
30845     if (dlg->master_field_list[i].create_dlg_func == NULL) {
30846       dlg->editor_list[i] = NULL;
30847     } else {
30848       dlg->editor_list[i] = (dlg->master_field_list[i].create_dlg_func) (ed2_grp, dlg->master_field_list[i].name, dlg->sep);
30849       Hide (dlg->editor_list[i]);
30850     }
30851   }
30852 
30853   dlg->ed_btn_grp = HiddenGroup (ed_grp, 1, 0, NULL);
30854   SetGroupSpacing (dlg->ed_btn_grp, 10, 10);
30855 
30856   b = PushButton (dlg->ed_btn_grp, "Apply Change", ApplyBulkEditingChange);
30857   SetObjectExtra (b, dlg, NULL);
30858   g_tmp = HiddenGroup (dlg->ed_btn_grp, 2, 0, NULL);
30859   SetGroupSpacing (g_tmp, 10, 10);
30860   b = PushButton (g_tmp, "Copy to Clipboard", CopyEditToClipboard);
30861   SetObjectExtra (b, dlg, NULL);
30862   b = PushButton (g_tmp, "Copy from Clipboard", CopyEditFromClipboard);
30863   SetObjectExtra (b, dlg, NULL);
30864   Hide (dlg->ed_btn_grp);
30865 
30866   box_grp = HiddenGroup (p, 0, 2, NULL);
30867 
30868   /* group that contains controls for checking and unchecking features */
30869   check_grp = NormalGroup (box_grp, -1, 0, "Check Features", programFont, NULL);
30870   SetGroupSpacing (check_grp, 10, 10);
30871   g1 = HiddenGroup (check_grp, 3, 0, NULL);
30872   SetGroupSpacing (g1, 10, 10);
30873   b = PushButton (g1, "Check All Features", BulkEditorCheckAll);
30874   SetObjectExtra (b, dlg, NULL);
30875   b = PushButton (g1, "Uncheck All Features", BulkEditorUncheckAll);
30876   SetObjectExtra (b, dlg, NULL);
30877 
30878   g2 = HiddenGroup (check_grp, 4, 0, NULL);
30879   dlg->sel_unsel_grp = HiddenGroup (g2, 0, 2, NULL);
30880   RadioButton (dlg->sel_unsel_grp, "Check features where");
30881   RadioButton (dlg->sel_unsel_grp, "Uncheck features where");
30882   SetValue (dlg->sel_unsel_grp, 1);
30883   dlg->check_constraint_field = MakeBulkEditorFieldListPopup (g2, dlg->field_list, FALSE);
30884   dlg->check_constraint = StringConstraintDialogX (g2, NULL, FALSE);
30885   b = PushButton (g2, "Apply", BulkEditorStringConstraintCheck);
30886   SetObjectExtra (b, dlg, NULL);
30887 
30888   if (dlg->any_editing) {
30889     /* group that contains controls for applying actions to check features */
30890     action_grp = NormalGroup (box_grp, -1, 0, "Action for Checked Features", programFont, NULL);
30891     a = HiddenGroup (action_grp, 2, 0, NULL);
30892     SetGroupSpacing (a, 10, 10);
30893     dlg->bulk_action = PopupList (a, TRUE, ChangeBulkEditorAction);
30894     SetObjectExtra (dlg->bulk_action, dlg, NULL);
30895     PopupItem (dlg->bulk_action, "Apply");
30896     PopupItem (dlg->bulk_action, "Edit");
30897     PopupItem (dlg->bulk_action, "Convert");
30898     PopupItem (dlg->bulk_action, "Parse");
30899     PopupItem (dlg->bulk_action, "Swap");
30900     PopupItem (dlg->bulk_action, "Remove");
30901     PopupItem (dlg->bulk_action, "Change Case");
30902     SetValue (dlg->bulk_action, 2);
30903     page_grp = HiddenGroup (a, 0, 0, NULL);
30904     page_num = 0;
30905     dlg->action_pages[page_num] = HiddenGroup (page_grp, 2, 0, NULL);
30906     dlg->bulk_apply = OneFieldBulkEditDialog (dlg->action_pages[page_num], eBulkApplyField, NULL, NULL, dlg->master_field_list, GetFirstBulkEditValue, dlg);
30907 
30908     page_num++;
30909     dlg->action_pages[page_num] = HiddenGroup (page_grp, 2, 0, NULL);
30910     dlg->bulk_edit = OneFieldBulkEditDialog (dlg->action_pages[page_num], eBulkEditField, NULL, NULL, dlg->master_field_list, GetFirstBulkEditValue, dlg);
30911 
30912     page_num++;
30913     dlg->action_pages[page_num] = HiddenGroup (page_grp, 2, 0, NULL);
30914     dlg->bulk_convert = TwoFieldBulkEditDialog (dlg->action_pages[page_num], eBulkConvertField, NULL, NULL, dlg->master_field_list, FALSE, NULL, NULL);
30915 
30916     page_num++;
30917     dlg->action_pages[page_num] = HiddenGroup (page_grp, 2, 0, NULL);
30918     dlg->bulk_parse = TwoFieldBulkEditDialog (dlg->action_pages[page_num], eBulkParseField, NULL, NULL, dlg->master_field_list, FALSE, GetFirstBulkEditValue, dlg);
30919 
30920     page_num++;
30921     dlg->action_pages[page_num] = HiddenGroup (page_grp, 2, 0, NULL);
30922     dlg->bulk_swap = TwoFieldBulkEditDialog (dlg->action_pages[page_num], eBulkSwapField, NULL, NULL, dlg->master_field_list, FALSE, NULL, NULL);
30923 
30924     page_num++;
30925     dlg->action_pages[page_num] = HiddenGroup (page_grp, 2, 0, NULL);
30926     dlg->bulk_remove = OneFieldBulkEditDialog (dlg->action_pages[page_num], eBulkRemoveField, NULL, NULL, dlg->master_field_list, NULL, NULL);
30927 
30928     page_num++;
30929     dlg->action_pages[page_num] = HiddenGroup (page_grp, 2, 0, NULL);
30930     dlg->bulk_capitalize = OneFieldBulkEditDialog (dlg->action_pages[page_num], eBulkCapitalizeField, NULL, NULL, dlg->master_field_list, NULL, NULL);
30931 
30932     AlignObjects (ALIGN_CENTER, (HANDLE) dlg->action_pages[0],
30933                                 (HANDLE) dlg->action_pages[1],
30934                                 (HANDLE) dlg->action_pages[2],
30935                                 (HANDLE) dlg->action_pages[3],
30936                                 (HANDLE) dlg->action_pages[4],
30937                                 (HANDLE) dlg->action_pages[5],
30938                                 (HANDLE) dlg->action_pages[6],
30939                                 NULL);
30940 
30941     dlg->check_status = StaticPrompt (action_grp, "0 features are checked", 20 * stdCharWidth, dialogTextHeight, programFont, 'l');
30942 
30943     g_tmp2 = HiddenGroup (action_grp, 3, 0, NULL);
30944     SetGroupSpacing (g_tmp2, 10, 10);
30945     b = PushButton (g_tmp2, "Apply to All Features", ApplyBulkEditAll);
30946     SetObjectExtra (b, dlg, NULL);
30947     b = PushButton (g_tmp2, "Apply to Checked Features", ApplyBulkEdit);
30948     SetObjectExtra (b, dlg, NULL);
30949 
30950     AlignObjects (ALIGN_CENTER, (HANDLE) a, (HANDLE) dlg->check_status, (HANDLE) g_tmp2, NULL);
30951   }
30952 
30953 
30954   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->title_doc, (HANDLE) dlg->doc, (HANDLE) ed_grp, (HANDLE) box_grp, NULL);
30955 
30956   UpdateBulkEdDisplay (dlg);
30957   UpdateCheckStatus (dlg);
30958   ChangeBulkEditorAction (dlg->bulk_action);
30959 }
30960 
30961 
30962 NLM_EXTERN DialoG
CreateBulkEditorDialogEx(GrouP h,BulkEdFieldPtr field_list,ValNodePtr feat_list,SeqEntryPtr sep,Boolean collapse_by_default,ClickableCallback single_click_func,ClickableCallback double_click_func,Pointer metadata,Boolean show_only_present)30963 CreateBulkEditorDialogEx
30964 (GrouP               h,
30965  BulkEdFieldPtr      field_list,
30966  ValNodePtr          feat_list,
30967  SeqEntryPtr         sep,
30968  Boolean             collapse_by_default,
30969  ClickableCallback   single_click_func,
30970  ClickableCallback   double_click_func,
30971  Pointer             metadata,
30972  Boolean             show_only_present)
30973 {
30974   GrouP            p;
30975   BulkEditorDlgPtr dlg;
30976 
30977   p = HiddenGroup (h, -1, 0, NULL);
30978   dlg = (BulkEditorDlgPtr) MemNew (sizeof (BulkEditorDlgData));
30979 
30980   SetObjectExtra (p, dlg, CleanupBulkEditorDialog); /* need to cleanup values_list */
30981 
30982   dlg->collapse_by_default = collapse_by_default;
30983   dlg->single_click_func = single_click_func;
30984   dlg->double_click_func = double_click_func;
30985   dlg->master_field_list = field_list;
30986   dlg->metadata = metadata;
30987   dlg->sep = sep;
30988 
30989   dlg->last_viewed_row = 0;
30990   dlg->last_viewed_col = 0;
30991   dlg->last_sorted_col = 0;
30992   dlg->row_list = MakeBulkEditorRowsFromObjectList(feat_list, dlg->master_field_list, dlg->last_sorted_col, dlg->metadata);
30993 
30994   /* need master list and actual list */
30995   if (show_only_present) {
30996     dlg->field_list = GetPopulatedFieldsFromMasterList (dlg->master_field_list, dlg->row_list);
30997     dlg->row_list = FreeBulkEditorRows(dlg->row_list, dlg->master_field_list);
30998     dlg->row_list = MakeBulkEditorRowsFromObjectList(feat_list, dlg->field_list, dlg->last_sorted_col, dlg->metadata);
30999   } else {
31000     dlg->field_list = CopyAllFieldsFromList (dlg->master_field_list);
31001   }
31002 
31003   if (dlg->collapse_by_default) {
31004     CollapseAllBulkEditRows (dlg->row_list);
31005   } else {
31006     ExpandAllBulkEditRows (dlg->row_list);
31007   }
31008 
31009   FinishBulkEditorDialogSetup (p, dlg);
31010 
31011   return (DialoG) p;
31012 }
31013 
31014 
31015 NLM_EXTERN DialoG
CreateBulkEditorDialog(GrouP h,BulkEdFieldPtr field_list,ValNodePtr feat_list,SeqEntryPtr sep,Boolean collapse_by_default,ClickableCallback single_click_func,ClickableCallback double_click_func)31016 CreateBulkEditorDialog
31017 (GrouP               h,
31018  BulkEdFieldPtr      field_list,
31019  ValNodePtr          feat_list,
31020  SeqEntryPtr         sep,
31021  Boolean             collapse_by_default,
31022  ClickableCallback   single_click_func,
31023  ClickableCallback   double_click_func)
31024 {
31025   return CreateBulkEditorDialogEx (h, field_list, feat_list, sep, collapse_by_default,
31026                                    single_click_func, double_click_func, NULL, FALSE);
31027 }
31028 
31029 
BulkGetLocation(Uint1 data_choice,Pointer data,Pointer metadata)31030 static Pointer BulkGetLocation (Uint1 data_choice, Pointer data, Pointer metadata)
31031 {
31032   SeqLocPtr slp;
31033   SeqFeatPtr sfp = (SeqFeatPtr) data;
31034 
31035   if (sfp == NULL) return NULL;
31036   slp = (SeqLocPtr) AsnIoMemCopy (sfp->location, (AsnReadFunc) SeqLocAsnRead, (AsnWriteFunc) SeqLocAsnWrite);
31037   return slp;
31038 }
31039 
BulkSetLocation(Pointer target,Pointer data)31040 static void BulkSetLocation (Pointer target, Pointer data)
31041 {
31042   SeqFeatPtr sfp = (SeqFeatPtr) target;
31043   SeqLocPtr slp = (SeqLocPtr) data;
31044   if (sfp == NULL) return;
31045   sfp->location = SeqLocFree (sfp->location);
31046   sfp->location = (SeqLocPtr) AsnIoMemCopy (slp, (AsnReadFunc) SeqLocAsnRead, (AsnWriteFunc) SeqLocAsnWrite);
31047 }
31048 
BulkFormatLocation(ColPtr col,CharPtr name)31049 static Int4 BulkFormatLocation (ColPtr col, CharPtr name)
31050 {
31051   if (col == NULL) return 0;
31052 
31053   col->pixWidth = MAX (15, StringLen (name)) * stdCharWidth;
31054   col->pixInset = 1;
31055   col->charWidth = 0;
31056   col->charInset = 0;
31057   col->font = NULL;
31058   col->just = 'l';
31059   col->wrap = 1;
31060   col->bar = 0;
31061   col->underline = 0;
31062   col->left = 0;
31063   return col->pixWidth;
31064 }
31065 
BulkFreeLocation(Pointer data)31066 static void BulkFreeLocation (Pointer data)
31067 {
31068   SeqLocPtr slp = (SeqLocPtr) data;
31069 
31070   slp = SeqLocFree (slp);
31071 }
31072 
BulkDisplayLocation(Pointer data)31073 static CharPtr BulkDisplayLocation (Pointer data)
31074 {
31075   SeqLocPtr slp = (SeqLocPtr) data;
31076 
31077   return SeqLocPrint (slp);
31078 }
31079 
BulkNucLocationDialog(GrouP g,CharPtr name,SeqEntryPtr sep)31080 static DialoG BulkNucLocationDialog (GrouP g, CharPtr name, SeqEntryPtr sep)
31081 {
31082   return CreateIntervalEditorDialog (g, NULL, 4, 2, sep, TRUE, FALSE);
31083 }
31084 
BulkCopyLocation(Pointer data)31085 static Pointer BulkCopyLocation (Pointer data)
31086 {
31087   SeqLocPtr orig = (SeqLocPtr) data;
31088   SeqLocPtr new_loc;
31089 
31090   if (orig == NULL) return NULL;
31091   new_loc = (SeqLocPtr) AsnIoMemCopy ((Pointer) orig,
31092                           (AsnReadFunc) SeqLocAsnRead,
31093                           (AsnWriteFunc) SeqLocAsnWrite);
31094 
31095   return new_loc;
31096 }
31097 
BulkFormatSimpleText(ColPtr col,CharPtr name)31098 NLM_EXTERN Int4 BulkFormatSimpleText (ColPtr col, CharPtr name)
31099 {
31100   if (col == NULL) return 0;
31101 
31102   col->pixWidth = (MAX (15, StringLen (name)) + 3) * MaxCharWidth();
31103   col->pixInset = 0;
31104   col->charWidth = 0;
31105   col->charInset = 0;
31106   col->font = NULL;
31107   col->just = 'l';
31108   col->wrap = 1;
31109   col->bar = 0;
31110   col->underline = 0;
31111   col->left = 0;
31112   return col->pixWidth;
31113 }
31114 
BulkFreeSimpleText(Pointer data)31115 NLM_EXTERN void BulkFreeSimpleText (Pointer data)
31116 {
31117   CharPtr str = (CharPtr) data;
31118 
31119   str = MemFree (str);
31120 }
31121 
BulkDisplaySimpleText(Pointer data)31122 NLM_EXTERN CharPtr BulkDisplaySimpleText (Pointer data)
31123 {
31124   CharPtr str = (CharPtr) data;
31125   if (StringHasNoText (str)) {
31126     return NULL;
31127   } else {
31128     return StringSave ((CharPtr) data);
31129   }
31130 }
31131 
31132 typedef struct bulksimpletext {
31133   DIALOG_MESSAGE_BLOCK
31134   TexT txt;
31135 } BulkSimpleTextData, PNTR BulkSimpleTextPtr;
31136 
StringToBulkSimpleTextDialog(DialoG d,Pointer data)31137 static void StringToBulkSimpleTextDialog (DialoG d, Pointer data)
31138 {
31139   BulkSimpleTextPtr dlg;
31140   CharPtr           str;
31141 
31142   dlg = (BulkSimpleTextPtr) GetObjectExtra (d);
31143   if (dlg == NULL) return;
31144 
31145   str = (CharPtr) data;
31146   if (str == NULL) {
31147     SetTitle (dlg->txt, "");
31148   } else {
31149     SetTitle (dlg->txt, str);
31150   }
31151 }
31152 
BulkSimpleTextDialogToString(DialoG d)31153 static Pointer BulkSimpleTextDialogToString (DialoG d)
31154 {
31155   BulkSimpleTextPtr dlg;
31156 
31157   dlg = (BulkSimpleTextPtr) GetObjectExtra (d);
31158   if (dlg == NULL) return NULL;
31159 
31160   return (Pointer) SaveStringFromText (dlg->txt);
31161 }
31162 
31163 
BulkSimpleTextDialogEx(GrouP g,CharPtr name,SeqEntryPtr sep,Boolean use_scroll)31164 static DialoG BulkSimpleTextDialogEx (GrouP g, CharPtr name, SeqEntryPtr sep, Boolean use_scroll)
31165 {
31166   BulkSimpleTextPtr dlg;
31167   GrouP           p;
31168 
31169   p = HiddenGroup (g, 4, 0, NULL);
31170   SetGroupSpacing (p, 10, 10);
31171   dlg = (BulkSimpleTextPtr) MemNew (sizeof(BulkSimpleTextData));
31172 
31173   SetObjectExtra (p, dlg, StdCleanupExtraProc);
31174   dlg->dialog = (DialoG) p;
31175   dlg->todialog = StringToBulkSimpleTextDialog;
31176   dlg->fromdialog = BulkSimpleTextDialogToString;
31177   dlg->testdialog = NULL;
31178 
31179   StaticPrompt (p, name, 0, dialogTextHeight, programFont, 'l');
31180   if (use_scroll) {
31181     dlg->txt = ScrollText (p, 20, 4, programFont, TRUE, NULL);
31182   } else {
31183     dlg->txt = DialogText (p, "", 20, NULL);
31184   }
31185 
31186   return (DialoG) p;
31187 }
31188 
BulkSimpleTextDialog(GrouP g,CharPtr name,SeqEntryPtr sep)31189 NLM_EXTERN DialoG BulkSimpleTextDialog (GrouP g, CharPtr name, SeqEntryPtr sep)
31190 {
31191   return BulkSimpleTextDialogEx (g, name, sep, FALSE);
31192 }
31193 
BulkSimpleTextScrollDialog(GrouP g,CharPtr name,SeqEntryPtr sep)31194 static DialoG BulkSimpleTextScrollDialog (GrouP g, CharPtr name, SeqEntryPtr sep)
31195 {
31196   return BulkSimpleTextDialogEx (g, name, sep, TRUE);
31197 }
31198 
BulkSimpleTextCopy(Pointer data)31199 NLM_EXTERN Pointer BulkSimpleTextCopy (Pointer data)
31200 {
31201   CharPtr orig = (CharPtr) data;
31202   CharPtr new_str = StringSave (orig);
31203   return new_str;
31204 }
31205 
BulkFormatTrueFalse(ColPtr col,CharPtr name)31206 static Int4 BulkFormatTrueFalse (ColPtr col, CharPtr name)
31207 {
31208   size_t box_width = stdLineHeight - 3;
31209   if (col == NULL) return 0;
31210 
31211   col->pixWidth = MAX (box_width, (StringLen (name) + 2) * MaxCharWidth());
31212   col->pixInset = 0;
31213   col->charWidth = 0;
31214   col->charInset = 0;
31215   col->font = NULL;
31216   col->just = 'l';
31217   col->wrap = 0;
31218   col->bar = 0;
31219   col->underline = 0;
31220   col->left = 0;
31221   return col->pixWidth;
31222 }
31223 
BulkDrawTrueFalse(Pointer p,RectPtr r)31224 static void BulkDrawTrueFalse (Pointer p, RectPtr r)
31225 {
31226   RecT rct;
31227 
31228   if (r == NULL) return;
31229 
31230   rct = *r;
31231   rct.bottom = rct.top + stdLineHeight - 4;
31232   rct.right = rct.left + stdLineHeight - 4;
31233   Gray();
31234   InsetRect (&rct, 2, 2);
31235   FrameRect (&rct);
31236 
31237   if (p != NULL) {
31238     MoveTo (rct.left, rct.top);
31239     LineTo (rct.right - 1, rct.bottom - 1);
31240     MoveTo (rct.left, rct.bottom - 1);
31241     LineTo (rct.right - 1, rct.top);
31242   }
31243   Black();
31244 }
31245 
BulkReleaseTrueFalse(Pointer p)31246 static Pointer BulkReleaseTrueFalse (Pointer p)
31247 {
31248   if (p == NULL) {
31249     p = (Pointer) StringSave ("TRUE");
31250   } else {
31251     p = MemFree (p);
31252   }
31253   return p;
31254 }
31255 
31256 
BulkSetPseudo(Pointer target,Pointer val)31257 static void BulkSetPseudo (Pointer target, Pointer val)
31258 {
31259   SeqFeatPtr sfp = (SeqFeatPtr) target;
31260   if (sfp == NULL) return;
31261   if (StringHasNoText ((CharPtr)val)) {
31262     sfp->pseudo = FALSE;
31263   } else {
31264     sfp->pseudo = TRUE;
31265   }
31266 }
31267 
BulkGetPseudo(Pointer data)31268 static Pointer BulkGetPseudo (Pointer data)
31269 {
31270   SeqFeatPtr sfp = (SeqFeatPtr) data;
31271   if (sfp == NULL || ! sfp->pseudo) {
31272     return NULL;
31273   } else {
31274     return StringSave ("TRUE");
31275   }
31276 }
31277 
BulkSetComment(Pointer target,Pointer data)31278 static void BulkSetComment (Pointer target, Pointer data)
31279 {
31280   CharPtr str = (CharPtr) data;
31281   SeqFeatPtr sfp = (SeqFeatPtr) target;
31282   if (sfp == NULL) return;
31283 
31284   sfp->comment = MemFree (sfp->comment);
31285   if (str != NULL) {
31286     sfp->comment = StringSave (str);
31287   }
31288 }
31289 
BulkGetComment(Uint1 data_choice,Pointer data,Pointer metadata)31290 static Pointer BulkGetComment (Uint1 data_choice, Pointer data, Pointer metadata)
31291 {
31292   SeqFeatPtr sfp = (SeqFeatPtr) data;
31293   if (sfp == NULL || StringHasNoText (sfp->comment)) {
31294     return NULL;
31295   } else {
31296     return (Pointer) StringSave (sfp->comment);
31297   }
31298 }
31299 
31300 
BulkCDSGetProtein(Uint1 data_choice,Pointer data,Pointer metadata)31301 static Pointer BulkCDSGetProtein (Uint1 data_choice, Pointer data, Pointer metadata)
31302 {
31303   SeqFeatXrefPtr xref;
31304   ProtRefPtr     prp = NULL;
31305   BioseqPtr      prot_bsp;
31306   SeqFeatPtr     prot_feat;
31307   SeqMgrFeatContext fcontext;
31308   ValNodePtr        prot_name_list = NULL, vnp;
31309   SeqFeatPtr        sfp = (SeqFeatPtr) data;
31310 
31311   if (sfp == NULL) return NULL;
31312 
31313   xref = sfp->xref;
31314   while (xref != NULL && xref->data.choice != SEQFEAT_PROT) {
31315     xref = xref->next;
31316   }
31317   if (xref != NULL) {
31318     prp = xref->data.value.ptrvalue;
31319   }
31320 
31321   if (prp == NULL) {
31322     if (sfp->data.choice == SEQFEAT_PROT) {
31323       prp = (ProtRefPtr) sfp->data.value.ptrvalue;
31324     } else if (sfp->data.choice == SEQFEAT_CDREGION) {
31325       prot_bsp = BioseqFindFromSeqLoc (sfp->product);
31326       prot_feat = SeqMgrGetNextFeature (prot_bsp, NULL, SEQFEAT_PROT, FEATDEF_PROT, &fcontext);
31327       if (prot_feat != NULL) {
31328         prp = (ProtRefPtr) prot_feat->data.value.ptrvalue;
31329       }
31330     }
31331   }
31332 
31333   if (prp != NULL) {
31334     for (vnp = prp->name; vnp != NULL; vnp = vnp->next) {
31335       ValNodeAddPointer (&prot_name_list, vnp->choice, StringSave (vnp->data.ptrvalue));
31336     }
31337   }
31338 
31339   return prot_name_list;
31340 }
31341 
BulkCDSCopyProtein(Pointer data)31342 static Pointer BulkCDSCopyProtein (Pointer data)
31343 {
31344   ValNodePtr        new_prot_name_list = NULL, prot_name_list, vnp;
31345 
31346   prot_name_list = (ValNodePtr) data;
31347 
31348   for (vnp = prot_name_list; vnp != NULL; vnp = vnp->next) {
31349     ValNodeAddPointer (&new_prot_name_list, vnp->choice, StringSave (vnp->data.ptrvalue));
31350   }
31351   return new_prot_name_list;
31352 }
31353 
BulkCDSFormatProtein(ColPtr col,CharPtr name)31354 static Int4 BulkCDSFormatProtein (ColPtr col, CharPtr name)
31355 {
31356   if (col == NULL) return 0;
31357 
31358   col->pixWidth = MAX (15, StringLen (name)) * MaxCharWidth();
31359   col->pixInset = 0;
31360   col->charWidth = 0;
31361   col->charInset = 0;
31362   col->font = NULL;
31363   col->just = 'l';
31364   col->wrap = 1;
31365   col->bar = 0;
31366   col->underline = 0;
31367   col->left = 0;
31368   return col->pixWidth;
31369 }
31370 
BulkCDSDisplayProtein(Pointer data)31371 static CharPtr BulkCDSDisplayProtein (Pointer data)
31372 {
31373   ValNodePtr prot_name_list, vnp;
31374   CharPtr    prot_text;
31375   Int4       text_len = 1;
31376 
31377   if (data == NULL) return NULL;
31378   prot_name_list = (ValNodePtr) data;
31379   for (vnp = prot_name_list; vnp != NULL; vnp = vnp->next) {
31380     text_len += StringLen (vnp->data.ptrvalue) + 1;
31381   }
31382   prot_text = (CharPtr) MemNew (sizeof (Char) * text_len);
31383   prot_text[0] = 0;
31384   for (vnp = prot_name_list; vnp != NULL; vnp = vnp->next) {
31385     StringCat (prot_text, vnp->data.ptrvalue);
31386     if (vnp->next != NULL) {
31387       StringCat (prot_text, ";");
31388     }
31389   }
31390   return prot_text;
31391 }
31392 
31393 
BulkCDSSetProteinString(Pointer curr_val,ApplyValuePtr avp)31394 static Pointer BulkCDSSetProteinString (Pointer curr_val, ApplyValuePtr avp)
31395 {
31396   CharPtr        curr_val_str;
31397   CharPtr        new_str, name_str, cp;
31398   ValNodePtr     name_list;
31399 
31400   name_list = (ValNodePtr) curr_val;
31401   curr_val_str = BulkCDSDisplayProtein (name_list);
31402   name_list = ValNodeFreeData (name_list);
31403 
31404   new_str = HandleApplyValue (curr_val_str, avp);
31405 
31406   name_str = new_str;
31407   cp = StringChr (name_str, ';');
31408   while (cp != NULL) {
31409     *cp = 0;
31410     ValNodeAddPointer (&name_list, 0, StringSave (name_str));
31411     *cp = ';';
31412     name_str = cp + 1;
31413     cp = StringChr (name_str, ';');
31414   }
31415   ValNodeAddPointer (&name_list, 0, StringSave (name_str));
31416   new_str = MemFree (new_str);
31417 
31418   return name_list;
31419 }
31420 
31421 
BulkCDSFreeProtein(Pointer data)31422 static void BulkCDSFreeProtein (Pointer data)
31423 {
31424   ValNodePtr prot_name_list = (ValNodePtr) data;
31425 
31426   ValNodeFreeData (prot_name_list);
31427 }
31428 
BulkCDSProteinDialog(GrouP g,CharPtr name,SeqEntryPtr sep)31429 static DialoG BulkCDSProteinDialog (GrouP g, CharPtr name, SeqEntryPtr sep)
31430 {
31431   return CreateVisibleStringDialog (g, 3, -1, 25);
31432 }
31433 
BulkCDSSetProteinDesc(Pointer target,Pointer data)31434 static void BulkCDSSetProteinDesc (Pointer target, Pointer data)
31435 {
31436   SeqFeatXrefPtr xref;
31437   ProtRefPtr     prp = NULL;
31438   BioseqPtr      prot_bsp;
31439   SeqFeatPtr     prot_feat;
31440   SeqMgrFeatContext fcontext;
31441   CharPtr           prot_desc;
31442   SeqFeatPtr sfp = (SeqFeatPtr) target;
31443   if (sfp == NULL) return;
31444 
31445   prot_desc = (CharPtr) data;
31446 
31447   xref = sfp->xref;
31448   while (xref != NULL && xref->data.choice != SEQFEAT_PROT) {
31449     xref = xref->next;
31450   }
31451   if (xref != NULL) {
31452     prp = xref->data.value.ptrvalue;
31453   }
31454 
31455   if (prp == NULL) {
31456     if (sfp->data.choice == SEQFEAT_PROT) {
31457       prp = (ProtRefPtr) sfp->data.value.ptrvalue;
31458     } else if (sfp->data.choice == SEQFEAT_CDREGION) {
31459       prot_bsp = BioseqFindFromSeqLoc (sfp->product);
31460       prot_feat = SeqMgrGetNextFeature (prot_bsp, NULL, SEQFEAT_PROT, FEATDEF_PROT, &fcontext);
31461       if (prot_feat == NULL && !StringHasNoText (prot_desc)) {
31462         prot_feat = CreateNewFeatureOnBioseq (prot_bsp, SEQFEAT_PROT, NULL);
31463         prp = ProtRefNew ();
31464         prot_feat->data.value.ptrvalue = prp;
31465           SeqMgrIndexFeatures (prot_bsp->idx.entityID, NULL);
31466       }
31467       if (prot_feat != NULL) {
31468         prp = (ProtRefPtr) prot_feat->data.value.ptrvalue;
31469       }
31470     }
31471   }
31472 
31473   if (prp == NULL && !StringHasNoText (prot_desc)) {
31474     xref = SeqFeatXrefNew ();
31475     prp = ProtRefNew ();
31476     xref->data.choice = SEQFEAT_PROT;
31477     xref->data.value.ptrvalue = prp;
31478     xref->next = sfp->xref;
31479     sfp->xref = xref;
31480   }
31481   if (prp != NULL) {
31482     prp->desc = StringSave (prot_desc);
31483   }
31484 
31485 }
31486 
31487 
BulkCDSGetProteinDesc(Uint1 data_choice,Pointer data,Pointer metadata)31488 static Pointer BulkCDSGetProteinDesc (Uint1 data_choice, Pointer data, Pointer metadata)
31489 {
31490   SeqFeatXrefPtr xref;
31491   ProtRefPtr     prp = NULL;
31492   BioseqPtr      prot_bsp;
31493   SeqFeatPtr     prot_feat;
31494   SeqMgrFeatContext fcontext;
31495   CharPtr           prot_desc = NULL;
31496   SeqFeatPtr sfp = (SeqFeatPtr) data;
31497 
31498   if (sfp == NULL) return NULL;
31499 
31500   xref = sfp->xref;
31501   while (xref != NULL && xref->data.choice != SEQFEAT_PROT) {
31502     xref = xref->next;
31503   }
31504   if (xref != NULL) {
31505     prp = xref->data.value.ptrvalue;
31506   }
31507 
31508   if (prp == NULL) {
31509     if (sfp->data.choice == SEQFEAT_PROT) {
31510       prp = (ProtRefPtr) sfp->data.value.ptrvalue;
31511     } else if (sfp->data.choice == SEQFEAT_CDREGION) {
31512       prot_bsp = BioseqFindFromSeqLoc (sfp->product);
31513       prot_feat = SeqMgrGetNextFeature (prot_bsp, NULL, SEQFEAT_PROT, FEATDEF_PROT, &fcontext);
31514       if (prot_feat != NULL) {
31515         prp = (ProtRefPtr) prot_feat->data.value.ptrvalue;
31516       }
31517     }
31518   }
31519 
31520   if (prp != NULL) {
31521     prot_desc = StringSave (prp->desc);
31522   }
31523 
31524   return prot_desc;
31525 }
31526 
31527 
BulkGeneSetLocus(Pointer target,Pointer data)31528 static void BulkGeneSetLocus (Pointer target, Pointer data)
31529 {
31530   CharPtr    str = (CharPtr) data;
31531   GeneRefPtr grp;
31532   SeqFeatPtr sfp = (SeqFeatPtr) target;
31533 
31534   if (sfp == NULL || sfp->idx.subtype != FEATDEF_GENE) return;
31535 
31536   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
31537   if (grp == NULL) {
31538     grp = GeneRefNew();
31539     sfp->data.value.ptrvalue = grp;
31540   }
31541   grp->locus = MemFree (grp->locus);
31542   if (str != NULL) {
31543     grp->locus = StringSave (str);
31544   }
31545 }
31546 
BulkGeneGetLocus(Uint1 data_choice,Pointer data,Pointer metadata)31547 static Pointer BulkGeneGetLocus (Uint1 data_choice, Pointer data, Pointer metadata)
31548 {
31549   GeneRefPtr grp;
31550   SeqFeatPtr sfp = (SeqFeatPtr) data;
31551 
31552   if (sfp == NULL || sfp->idx.subtype != FEATDEF_GENE || sfp->data.value.ptrvalue == NULL) {
31553     return NULL;
31554   }
31555   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
31556   if (StringHasNoText (grp->locus)) {
31557     return NULL;
31558   } else {
31559     return (Pointer) StringSave (grp->locus);
31560   }
31561 }
31562 
BulkGeneSetLocusTag(Pointer target,Pointer data)31563 static void BulkGeneSetLocusTag (Pointer target, Pointer data)
31564 {
31565   CharPtr    str = (CharPtr) data;
31566   GeneRefPtr grp;
31567   SeqFeatPtr sfp = (SeqFeatPtr) target;
31568 
31569   if (sfp == NULL || sfp->idx.subtype != FEATDEF_GENE) return;
31570 
31571   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
31572   if (grp == NULL) {
31573     grp = GeneRefNew();
31574     sfp->data.value.ptrvalue = grp;
31575   }
31576   grp->locus_tag = MemFree (grp->locus_tag);
31577   if (str != NULL) {
31578     grp->locus_tag = StringSave (str);
31579   }
31580 }
31581 
BulkGeneGetLocusTag(Uint1 data_choice,Pointer data,Pointer metadata)31582 static Pointer BulkGeneGetLocusTag (Uint1 data_choice, Pointer data, Pointer metadata)
31583 {
31584   GeneRefPtr grp;
31585   SeqFeatPtr sfp = (SeqFeatPtr) data;
31586 
31587   if (sfp == NULL || sfp->idx.subtype != FEATDEF_GENE || sfp->data.value.ptrvalue == NULL) {
31588     return NULL;
31589   }
31590   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
31591   if (StringHasNoText (grp->locus_tag)) {
31592     return NULL;
31593   } else {
31594     return (Pointer) StringSave (grp->locus_tag);
31595   }
31596 }
31597 
BulkGeneSetDescription(Pointer target,Pointer data)31598 static void BulkGeneSetDescription (Pointer target, Pointer data)
31599 {
31600   CharPtr    str = (CharPtr) data;
31601   GeneRefPtr grp;
31602   SeqFeatPtr sfp = (SeqFeatPtr) target;
31603 
31604   if (sfp == NULL || sfp->idx.subtype != FEATDEF_GENE) return;
31605 
31606   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
31607   if (grp == NULL) {
31608     grp = GeneRefNew();
31609     sfp->data.value.ptrvalue = grp;
31610   }
31611   grp->desc = MemFree (grp->desc);
31612   if (str != NULL) {
31613     grp->desc = StringSave (str);
31614   }
31615 }
31616 
BulkGeneGetDescription(Uint1 data_choice,Pointer data,Pointer metadata)31617 static Pointer BulkGeneGetDescription (Uint1 data_choice, Pointer data, Pointer metadata)
31618 {
31619   GeneRefPtr grp;
31620   SeqFeatPtr sfp = (SeqFeatPtr) data;
31621 
31622   if (sfp == NULL || sfp->idx.subtype != FEATDEF_GENE || sfp->data.value.ptrvalue == NULL) {
31623     return NULL;
31624   }
31625   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
31626   if (StringHasNoText (grp->desc)) {
31627     return NULL;
31628   } else {
31629     return (Pointer) StringSave (grp->desc);
31630   }
31631 }
31632 
31633 
BulkRNASetProduct(Pointer target,Pointer data)31634 static void BulkRNASetProduct (Pointer target, Pointer data)
31635 {
31636   RnaRefPtr  rrp;
31637   CharPtr    rna_product;
31638   SeqFeatPtr sfp = (SeqFeatPtr) target;
31639 
31640   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA) return;
31641 
31642   rna_product = (CharPtr) data;
31643 
31644   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
31645   if (rrp == NULL && !StringHasNoText (rna_product)) {
31646     rrp = RnaRefNew ();
31647     rrp->ext.choice = 1;
31648     sfp->data.value.ptrvalue = rrp;
31649   }
31650   if (rrp == NULL) return;
31651   if (rrp->ext.choice == 0 && !StringHasNoText (rna_product)) {
31652     rrp->ext.choice = 1;
31653   } else if (rrp->ext.choice == 1 && StringHasNoText (rna_product)) {
31654     rrp->ext.choice = 0;
31655     rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
31656   }
31657 
31658   if (rrp->ext.choice == 1) {
31659     rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
31660     rrp->ext.value.ptrvalue = StringSave (rna_product);
31661   }
31662 }
31663 
BulkRNAGetProduct(Uint1 data_choice,Pointer data,Pointer metadata)31664 static Pointer BulkRNAGetProduct (Uint1 data_choice, Pointer data, Pointer metadata)
31665 {
31666   RnaRefPtr  rrp;
31667   CharPtr    rna_product = NULL;
31668   SeqFeatPtr sfp = (SeqFeatPtr) data;
31669 
31670   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA) return NULL;
31671 
31672   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
31673   if (rrp != NULL) {
31674     if (rrp->ext.choice == 1) {
31675       rna_product = StringSave( rrp->ext.value.ptrvalue);
31676     }
31677   }
31678 
31679 
31680   return rna_product;
31681 }
31682 
IsBulkEditableRNA(SeqFeatPtr sfp)31683 static Boolean IsBulkEditableRNA (SeqFeatPtr sfp)
31684 {
31685   RnaRefPtr rrp;
31686 
31687   if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA) {
31688     return FALSE;
31689   }
31690   rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
31691   if (rrp != NULL && rrp->ext.choice != 1 && rrp->ext.choice != 0) {
31692     return FALSE;
31693   } else {
31694     return TRUE;
31695   }
31696 }
31697 
31698 
31699 /* template for setting simple text strings */
BulkSetSimpleTextString(Pointer curr_val,ApplyValuePtr avp)31700 NLM_EXTERN Pointer BulkSetSimpleTextString (Pointer curr_val, ApplyValuePtr avp)
31701 {
31702   CharPtr        curr_val_str;
31703 
31704   curr_val_str = (CharPtr)curr_val;
31705   return HandleApplyValue (curr_val_str, avp);
31706 }
31707 
31708 /* for now, disallow pseudo editing and display.  To add back, put in this line:
31709   { "pseudo", BulkSetPseudo, BulkGetPseudo, NULL, NULL, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, BulkReleaseTrueFalse },
31710 */
31711 /* for now, disallow location editing (but continue display).  To add back, use BulkNucLocationDialog in dialog. */
31712 static BulkEdFieldData bulk_cds_fields[] = {
31713   { "protein name                     ", BulkCDSSetProtein, BulkCDSSetProteinString, BulkCDSGetProtein, BulkCDSDisplayProtein, BulkCDSFreeProtein, BulkCDSProteinDialog, BulkCDSFormatProtein, NULL, NULL, BulkCDSCopyProtein },
31714   { "protein description", BulkCDSSetProteinDesc, BulkSetSimpleTextString, BulkCDSGetProteinDesc, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
31715   { "location", BulkSetLocation, NULL, BulkGetLocation, BulkDisplayLocation, BulkFreeLocation, NULL, BulkFormatLocation, NULL, NULL, BulkCopyLocation },
31716   { "comment", BulkSetComment, BulkSetSimpleTextString, BulkGetComment, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextScrollDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
31717   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
31718 
31719 static BulkEdFieldData bulk_gene_fields[] = {
31720   { "locus", BulkGeneSetLocus, BulkSetSimpleTextString, BulkGeneGetLocus, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
31721   { "locus_tag", BulkGeneSetLocusTag, BulkSetSimpleTextString, BulkGeneGetLocusTag, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
31722   { "description", BulkGeneSetDescription, BulkSetSimpleTextString, BulkGeneGetDescription, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
31723   { "location", BulkSetLocation, NULL, BulkGetLocation, BulkDisplayLocation, BulkFreeLocation, NULL, BulkFormatLocation, NULL, NULL, BulkCopyLocation },
31724   { "comment", BulkSetComment, BulkSetSimpleTextString, BulkGetComment, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextScrollDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
31725   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
31726 
31727 static BulkEdFieldData bulk_rna_fields[] = {
31728   { "product", BulkRNASetProduct, BulkSetSimpleTextString, BulkRNAGetProduct, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
31729   { "location", BulkSetLocation, NULL, BulkGetLocation, BulkDisplayLocation, BulkFreeLocation, NULL, BulkFormatLocation, NULL, NULL, BulkCopyLocation },
31730   { "comment", BulkSetComment, BulkSetSimpleTextString, BulkGetComment, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextScrollDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
31731   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
31732 
31733 
GetBulkEditorFieldListForFeature(SeqFeatPtr sfp)31734 static BulkEdFieldPtr GetBulkEditorFieldListForFeature (SeqFeatPtr sfp)
31735 {
31736   if (sfp == NULL) {
31737     return NULL;
31738   } else if (sfp->data.choice == SEQFEAT_CDREGION) {
31739     return bulk_cds_fields;
31740   } else if (sfp->data.choice == SEQFEAT_GENE) {
31741     return bulk_gene_fields;
31742   } else if (sfp->data.choice == SEQFEAT_RNA && IsBulkEditableRNA(sfp)) {
31743     /* Note - using FEATDEF_rRNA to represent all editable rRNA features */
31744     return bulk_rna_fields;
31745   } else {
31746     return NULL;
31747   }
31748 }
31749 
31750 
BulkSrcSetTaxNameDesc(Pointer target,Pointer data)31751 static void BulkSrcSetTaxNameDesc (Pointer target, Pointer data)
31752 {
31753   CharPtr      taxname;
31754   SeqDescrPtr  sdp = (SeqDescrPtr) target;
31755   BioSourcePtr biop;
31756 
31757   if (sdp == NULL || sdp->choice != Seq_descr_source || sdp->data.ptrvalue == NULL) return;
31758 
31759   biop = (BioSourcePtr) sdp->data.ptrvalue;
31760 
31761   taxname = (CharPtr) data;
31762 
31763   if (biop->org == NULL) {
31764     biop->org = OrgRefNew();
31765   }
31766   SetTaxNameAndRemoveTaxRef (biop->org, StringSave (taxname));
31767 }
31768 
31769 
31770 NLM_EXTERN BioSourcePtr GetBioSourceFromObject (Uint1 choice, Pointer data);
31771 
BulkSrcGetTaxNameDesc(Uint1 data_choice,Pointer data,Pointer metadata)31772 static Pointer BulkSrcGetTaxNameDesc (Uint1 data_choice, Pointer data, Pointer metadata)
31773 {
31774   CharPtr      taxname = NULL;
31775   BioSourcePtr biop = NULL;
31776 
31777   biop = GetBioSourceFromObject (data_choice, data);
31778   if (biop == NULL) return NULL;
31779 
31780   if (biop->org != NULL) {
31781     taxname = StringSave (biop->org->taxname);
31782   }
31783 
31784   return taxname;
31785 }
31786 
31787 
BulkSrcSetTaxNameFeat(Pointer target,Pointer data)31788 static void BulkSrcSetTaxNameFeat (Pointer target, Pointer data)
31789 {
31790   CharPtr      taxname;
31791   SeqFeatPtr   sfp = (SeqFeatPtr) target;
31792   BioSourcePtr biop;
31793 
31794   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || sfp->data.value.ptrvalue == NULL) return;
31795 
31796   biop = (BioSourcePtr) sfp->data.value.ptrvalue;
31797 
31798   taxname = (CharPtr) data;
31799 
31800   if (biop->org == NULL) {
31801     biop->org = OrgRefNew();
31802   }
31803   SetTaxNameAndRemoveTaxRef (biop->org, StringSave (taxname));
31804 }
31805 
31806 
BulkSrcGetTaxNameFeat(Uint1 data_choice,Pointer data,Pointer metadata)31807 static Pointer BulkSrcGetTaxNameFeat (Uint1 data_choice, Pointer data, Pointer metadata)
31808 {
31809   CharPtr      taxname = NULL;
31810   SeqFeatPtr   sfp = (SeqFeatPtr) data;
31811   BioSourcePtr biop;
31812 
31813   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || sfp->data.value.ptrvalue == NULL) return NULL;
31814 
31815   biop = (BioSourcePtr) sfp->data.value.ptrvalue;
31816 
31817   if (biop->org != NULL) {
31818     taxname = StringSave (biop->org->taxname);
31819   }
31820 
31821   return taxname;
31822 }
31823 
31824 
BulkSrcGetSubSrcModDesc(Uint1 data_choice,Pointer data,Uint2 mod_type)31825 static Pointer BulkSrcGetSubSrcModDesc (Uint1 data_choice, Pointer data, Uint2 mod_type)
31826 {
31827   CharPtr      val = NULL;
31828   BioSourcePtr biop = NULL;
31829   SubSourcePtr ssp;
31830 
31831   biop = GetBioSourceFromObject (data_choice, data);
31832   if (biop == NULL) return NULL;
31833 
31834   ssp = biop->subtype;
31835   while (ssp != NULL && ssp->subtype != mod_type) {
31836     ssp = ssp->next;
31837   }
31838   if (ssp != NULL) {
31839     val = StringSave (ssp->name);
31840   }
31841 
31842   return val;
31843 }
31844 
31845 
BulkSrcSetSubSrcModDesc(Pointer target,Pointer data,Uint2 mod_type)31846 static void BulkSrcSetSubSrcModDesc (Pointer target, Pointer data, Uint2 mod_type)
31847 {
31848   CharPtr      val;
31849   SeqDescrPtr  sdp = (SeqDescrPtr) target;
31850   BioSourcePtr biop;
31851   SubSourcePtr ssp, ssp_last = NULL;
31852 
31853   if (sdp == NULL || sdp->choice != Seq_descr_source || sdp->data.ptrvalue == NULL) return;
31854 
31855   biop = (BioSourcePtr) sdp->data.ptrvalue;
31856 
31857   val = (CharPtr) data;
31858 
31859   ssp = biop->subtype;
31860   while (ssp != NULL && ssp->subtype != mod_type) {
31861     ssp_last = ssp;
31862     ssp = ssp->next;
31863   }
31864   if (ssp == NULL) {
31865     ssp = SubSourceNew();
31866     ssp->subtype = mod_type;
31867     if (ssp_last == NULL) {
31868       biop->subtype = ssp;
31869     } else {
31870       ssp_last->next = ssp;
31871     }
31872   }
31873   ssp->name = MemFree (ssp->name);
31874   ssp->name = StringSave (val);
31875 }
31876 
31877 
31878 #define BULK_SRC_GET_AND_SET_SUBSRC(Name,Type) \
31879 static Pointer BulkSrcGet##Name (Uint1 data_choice, Pointer data, Pointer metadata) \
31880 { \
31881   return BulkSrcGetSubSrcModDesc(data_choice, data, SUBSRC_##Type); \
31882 } \
31883 static void BulkSrcSet##Name (Pointer target, Pointer data) \
31884 { \
31885   BulkSrcSetSubSrcModDesc(target, data, SUBSRC_##Type); \
31886 }
31887 
31888 
BulkSrcGetSubSrcModDescTF(Uint1 data_choice,Pointer data,Uint2 mod_type)31889 static Pointer BulkSrcGetSubSrcModDescTF (Uint1 data_choice, Pointer data, Uint2 mod_type)
31890 {
31891   CharPtr      val = NULL;
31892   BioSourcePtr biop = NULL;
31893   SubSourcePtr ssp;
31894 
31895   biop = GetBioSourceFromObject (data_choice, data);
31896   if (biop == NULL) return NULL;
31897 
31898   ssp = biop->subtype;
31899   while (ssp != NULL && ssp->subtype != mod_type) {
31900     ssp = ssp->next;
31901   }
31902   if (ssp != NULL) {
31903     val = StringSave ("TRUE");
31904   }
31905 
31906   return val;
31907 }
31908 
31909 
BulkSrcSetSubSrcModDescTF(Pointer target,Pointer data,Uint2 mod_type)31910 static void BulkSrcSetSubSrcModDescTF (Pointer target, Pointer data, Uint2 mod_type)
31911 {
31912   CharPtr      val;
31913   SeqDescrPtr  sdp = (SeqDescrPtr) target;
31914   BioSourcePtr biop;
31915   SubSourcePtr ssp, ssp_last = NULL;
31916 
31917   if (sdp == NULL || sdp->choice != Seq_descr_source || sdp->data.ptrvalue == NULL) return;
31918 
31919   biop = (BioSourcePtr) sdp->data.ptrvalue;
31920 
31921   val = (CharPtr) data;
31922 
31923   ssp = biop->subtype;
31924   while (ssp != NULL && ssp->subtype != mod_type) {
31925     ssp_last = ssp;
31926     ssp = ssp->next;
31927   }
31928   if (StringHasNoText ((CharPtr)val)) {
31929     if (ssp != NULL) {
31930       if (ssp_last == NULL) {
31931         biop->subtype = ssp->next;
31932       } else {
31933         ssp_last->next = ssp->next;
31934       }
31935       ssp->next = NULL;
31936       ssp = SubSourceFree (ssp);
31937     }
31938   } else {
31939     if (ssp == NULL) {
31940       ssp = SubSourceNew();
31941       ssp->subtype = mod_type;
31942       if (ssp_last == NULL) {
31943         biop->subtype = ssp;
31944       } else {
31945         ssp_last->next = ssp;
31946       }
31947     }
31948     ssp->name = MemFree (ssp->name);
31949     ssp->name = StringSave (" ");
31950   }
31951 }
31952 
31953 
31954 #define BULK_SRC_GET_AND_SET_SUBSRC_TF(Name,Type) \
31955 static Pointer BulkSrcGet##Name (Uint1 data_choice, Pointer data, Pointer metadata) \
31956 { \
31957   return BulkSrcGetSubSrcModDescTF(data_choice, data, SUBSRC_##Type); \
31958 } \
31959 static void BulkSrcSet##Name (Pointer target, Pointer data) \
31960 { \
31961   BulkSrcSetSubSrcModDescTF(target, data, SUBSRC_##Type); \
31962 }
31963 
31964 
BulkSrcGetOrgModDesc(Uint1 data_choice,Pointer data,Uint2 mod_type)31965 static Pointer BulkSrcGetOrgModDesc (Uint1 data_choice, Pointer data, Uint2 mod_type)
31966 {
31967   CharPtr      val = NULL;
31968   BioSourcePtr biop = NULL;
31969   OrgModPtr    mod;
31970 
31971   biop = GetBioSourceFromObject (data_choice, data);
31972   if (biop == NULL || biop->org == NULL || biop->org->orgname == NULL) return NULL;
31973 
31974   mod = biop->org->orgname->mod;
31975   while (mod != NULL && mod->subtype != mod_type) {
31976     mod = mod->next;
31977   }
31978   if (mod != NULL) {
31979     val = StringSave (mod->subname);
31980   }
31981 
31982   return val;
31983 }
31984 
31985 
BulkSrcSetOrgModDesc(Pointer target,Pointer data,Uint2 mod_type)31986 static void BulkSrcSetOrgModDesc (Pointer target, Pointer data, Uint2 mod_type)
31987 {
31988   CharPtr      val;
31989   SeqDescrPtr  sdp = (SeqDescrPtr) target;
31990   BioSourcePtr biop;
31991   OrgModPtr    mod, mod_last = NULL;
31992 
31993   if (sdp == NULL || sdp->choice != Seq_descr_source || sdp->data.ptrvalue == NULL) return;
31994 
31995   biop = (BioSourcePtr) sdp->data.ptrvalue;
31996 
31997   val = (CharPtr) data;
31998 
31999   if (biop->org == NULL) {
32000     biop->org = OrgRefNew ();
32001   }
32002   if (biop->org->orgname == NULL) {
32003     biop->org->orgname = OrgNameNew ();
32004   }
32005 
32006   mod = biop->org->orgname->mod;
32007   while (mod != NULL && mod->subtype != mod_type) {
32008     mod_last = mod;
32009     mod = mod->next;
32010   }
32011   if (mod == NULL) {
32012     mod = OrgModNew();
32013     mod->subtype = mod_type;
32014     if (mod_last == NULL) {
32015       biop->org->orgname->mod = mod;
32016     } else {
32017       mod_last->next = mod;
32018     }
32019   }
32020   mod->subname = MemFree (mod->subname);
32021   mod->subname = StringSave (val);
32022 }
32023 
32024 
32025 #define BULK_SRC_GET_AND_SET_ORGMOD(Name,Type) \
32026 static Pointer BulkSrcGet##Name (Uint1 data_choice, Pointer data, Pointer metadata) \
32027 { \
32028   return BulkSrcGetOrgModDesc(data_choice, data, ORGMOD_##Type); \
32029 } \
32030 static void BulkSrcSet##Name (Pointer target, Pointer data) \
32031 { \
32032   BulkSrcSetOrgModDesc(target, data, ORGMOD_##Type); \
32033 }
32034 
32035 
BulkSrcGetOrgModDescTF(Uint1 data_choice,Pointer data,Uint2 mod_type)32036 static Pointer BulkSrcGetOrgModDescTF (Uint1 data_choice, Pointer data, Uint2 mod_type)
32037 {
32038   CharPtr      val = NULL;
32039   BioSourcePtr biop = NULL;
32040   OrgModPtr    mod;
32041 
32042   biop = GetBioSourceFromObject (data_choice, data);
32043   if (biop == NULL || biop->org == NULL || biop->org->orgname == NULL) return NULL;
32044 
32045   mod = biop->org->orgname->mod;
32046   while (mod != NULL && mod->subtype != mod_type) {
32047     mod = mod->next;
32048   }
32049   if (mod != NULL) {
32050     val = StringSave ("TRUE");
32051   }
32052 
32053   return val;
32054 }
32055 
32056 
BulkSrcSetOrgModDescTF(Pointer target,Pointer data,Uint2 mod_type)32057 static void BulkSrcSetOrgModDescTF (Pointer target, Pointer data, Uint2 mod_type)
32058 {
32059   CharPtr      val;
32060   SeqDescrPtr  sdp = (SeqDescrPtr) target;
32061   BioSourcePtr biop;
32062   OrgModPtr    mod, mod_last = NULL;
32063 
32064   if (sdp == NULL || sdp->choice != Seq_descr_source || sdp->data.ptrvalue == NULL) return;
32065 
32066   biop = (BioSourcePtr) sdp->data.ptrvalue;
32067   if (biop == NULL) return;
32068 
32069   val = (CharPtr) data;
32070 
32071   if (biop->org == NULL) {
32072     biop->org = OrgRefNew ();
32073   }
32074   if (biop->org->orgname == NULL) {
32075     biop->org->orgname = OrgNameNew ();
32076   }
32077 
32078   mod = biop->org->orgname->mod;
32079   while (mod != NULL && mod->subtype != mod_type) {
32080     mod = mod->next;
32081   }
32082 
32083   if (StringHasNoText ((CharPtr)val)) {
32084     /* remove */
32085     if (mod != NULL) {
32086       if (mod_last == NULL) {
32087         biop->org->orgname->mod = mod->next;
32088       } else {
32089         mod_last->next = mod->next;
32090       }
32091       mod->next = NULL;
32092       mod = OrgModFree (mod);
32093     }
32094   } else {
32095     /* set */
32096     if (mod == NULL) {
32097       mod = OrgModNew();
32098       mod->subtype = mod_type;
32099       if (mod_last == NULL) {
32100         biop->org->orgname->mod = mod;
32101       } else {
32102         mod_last->next = mod;
32103       }
32104     }
32105     mod->subname = MemFree (mod->subname);
32106     mod->subname = StringSave (" ");
32107   }
32108 }
32109 
32110 
32111 #define BULK_SRC_GET_AND_SET_ORGMOD_TF(Name,Type) \
32112 static Pointer BulkSrcGet##Name (Uint1 data_choice, Pointer data, Pointer metadata) \
32113 { \
32114   return BulkSrcGetOrgModDescTF(data_choice, data, SUBSRC_##Type); \
32115 } \
32116 static void BulkSrcSet##Name (Pointer target, Pointer data) \
32117 { \
32118   BulkSrcSetOrgModDescTF(target, data, SUBSRC_##Type); \
32119 }
32120 
32121 
BULK_SRC_GET_AND_SET_ORGMOD(Acronym,acronym)32122 BULK_SRC_GET_AND_SET_ORGMOD(Acronym,acronym)
32123 BULK_SRC_GET_AND_SET_ORGMOD(Anamorph,anamorph)
32124 BULK_SRC_GET_AND_SET_ORGMOD(Authority,authority)
32125 BULK_SRC_GET_AND_SET_ORGMOD(Bio_material,bio_material)
32126 BULK_SRC_GET_AND_SET_ORGMOD(Biotype,biotype)
32127 BULK_SRC_GET_AND_SET_ORGMOD(Biovar,biovar)
32128 BULK_SRC_GET_AND_SET_ORGMOD(Breed,breed)
32129 BULK_SRC_GET_AND_SET_ORGMOD(Chemovar,chemovar)
32130 BULK_SRC_GET_AND_SET_ORGMOD(Common,common)
32131 BULK_SRC_GET_AND_SET_ORGMOD(Cultivar,cultivar)
32132 BULK_SRC_GET_AND_SET_ORGMOD(Culture_collection,culture_collection)
32133 BULK_SRC_GET_AND_SET_ORGMOD(Ecotype,ecotype)
32134 BULK_SRC_GET_AND_SET_ORGMOD(Forma,forma)
32135 BULK_SRC_GET_AND_SET_ORGMOD(Forma_specialis,forma_specialis)
32136 BULK_SRC_GET_AND_SET_ORGMOD(Group,group)
32137 BULK_SRC_GET_AND_SET_ORGMOD(Host,nat_host)
32138 BULK_SRC_GET_AND_SET_ORGMOD(Isolate,isolate)
32139 BULK_SRC_GET_AND_SET_ORGMOD(Metagenome_source,metagenome_source)
32140 BULK_SRC_GET_AND_SET_ORGMOD(Pathovar,pathovar)
32141 BULK_SRC_GET_AND_SET_ORGMOD(Serogroup,serogroup)
32142 BULK_SRC_GET_AND_SET_ORGMOD(Serotype,serotype)
32143 BULK_SRC_GET_AND_SET_ORGMOD(Serovar,serovar)
32144 BULK_SRC_GET_AND_SET_ORGMOD(Specimen_voucher,specimen_voucher)
32145 BULK_SRC_GET_AND_SET_ORGMOD(Strain,strain)
32146 BULK_SRC_GET_AND_SET_ORGMOD(Subgroup,subgroup)
32147 BULK_SRC_GET_AND_SET_ORGMOD(Sub_species,sub_species)
32148 BULK_SRC_GET_AND_SET_ORGMOD(Substrain,substrain)
32149 BULK_SRC_GET_AND_SET_ORGMOD(Subtype,subtype)
32150 BULK_SRC_GET_AND_SET_ORGMOD(Synonym,synonym)
32151 BULK_SRC_GET_AND_SET_ORGMOD(Teleomorph,teleomorph)
32152 BULK_SRC_GET_AND_SET_ORGMOD(Type,type)
32153 BULK_SRC_GET_AND_SET_ORGMOD(Variety,variety)
32154 BULK_SRC_GET_AND_SET_ORGMOD(OrgModNote,other)
32155 BULK_SRC_GET_AND_SET_SUBSRC(Cell_line,cell_line)
32156 BULK_SRC_GET_AND_SET_SUBSRC(Cell_type,cell_type)
32157 BULK_SRC_GET_AND_SET_SUBSRC(Chromosome,chromosome)
32158 BULK_SRC_GET_AND_SET_SUBSRC(Clone,clone)
32159 BULK_SRC_GET_AND_SET_SUBSRC(Clone_lib,clone_lib)
32160 BULK_SRC_GET_AND_SET_SUBSRC(Collected_by,collected_by)
32161 BULK_SRC_GET_AND_SET_SUBSRC(Collection_date,collection_date)
32162 BULK_SRC_GET_AND_SET_SUBSRC(Country,country)
32163 BULK_SRC_GET_AND_SET_SUBSRC(Dev_stage,dev_stage)
32164 BULK_SRC_GET_AND_SET_SUBSRC(Endogenous_virus_name,endogenous_virus_name)
32165 BULK_SRC_GET_AND_SET_SUBSRC_TF(Environmental_sample,environmental_sample)
32166 BULK_SRC_GET_AND_SET_SUBSRC(Frequency,frequency)
32167 BULK_SRC_GET_AND_SET_SUBSRC(Genotype,genotype)
32168 BULK_SRC_GET_AND_SET_SUBSRC_TF(Germline,germline)
32169 BULK_SRC_GET_AND_SET_SUBSRC(Haplogroup,haplogroup)
32170 BULK_SRC_GET_AND_SET_SUBSRC(Haplotype,haplotype)
32171 BULK_SRC_GET_AND_SET_SUBSRC(Identified_by,identified_by)
32172 BULK_SRC_GET_AND_SET_SUBSRC(Isolation_source,isolation_source)
32173 BULK_SRC_GET_AND_SET_SUBSRC(Lab_host,lab_host)
32174 BULK_SRC_GET_AND_SET_SUBSRC(Lat_Lon,lat_lon)
32175 BULK_SRC_GET_AND_SET_SUBSRC(Linkage_group,linkage_group)
32176 BULK_SRC_GET_AND_SET_SUBSRC(Map,map)
32177 BULK_SRC_GET_AND_SET_SUBSRC(Mating_type,mating_type)
32178 BULK_SRC_GET_AND_SET_SUBSRC_TF(Metagenomic,metagenomic)
32179 BULK_SRC_GET_AND_SET_SUBSRC(Plasmid_name,plasmid_name)
32180 BULK_SRC_GET_AND_SET_SUBSRC(Pop_variant,pop_variant)
32181 BULK_SRC_GET_AND_SET_SUBSRC_TF(Rearranged,rearranged)
32182 BULK_SRC_GET_AND_SET_SUBSRC(Segment,segment)
32183 BULK_SRC_GET_AND_SET_SUBSRC(Sex,sex)
32184 BULK_SRC_GET_AND_SET_SUBSRC(Subclone,subclone)
32185 BULK_SRC_GET_AND_SET_SUBSRC(Tissue_lib,tissue_lib)
32186 BULK_SRC_GET_AND_SET_SUBSRC(Tissue_type,tissue_type)
32187 BULK_SRC_GET_AND_SET_SUBSRC_TF(Transgenic,transgenic)
32188 BULK_SRC_GET_AND_SET_SUBSRC(SubSrcNote,other)
32189 
32190 
32191 #define BULK_SRC_SUBSRC_FIELD_TF(Name) \
32192  BulkSrcSet##Name, BulkSetSimpleTextString, BulkSrcGet##Name, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy
32193 
32194 
32195 static ValNodePtr StringsToDbxrefList (ValNodePtr strings)
32196 {
32197   ValNodePtr dbxref_list = NULL, vnp;
32198   DbtagPtr dbtag;
32199 
32200   for (vnp = strings; vnp != NULL; vnp = vnp->next)
32201   {
32202     dbtag = DbtagNew();
32203     SetDbtagString (dbtag, vnp->data.ptrvalue, ExistingTextOption_replace_old);
32204     ValNodeAddPointer (&dbxref_list, vnp->choice, dbtag);
32205   }
32206   return dbxref_list;
32207 }
32208 
32209 
DbxrefListToStrings(ValNodePtr dbxref_list)32210 static ValNodePtr DbxrefListToStrings (ValNodePtr dbxref_list)
32211 {
32212   ValNodePtr strings = NULL, vnp;
32213   DbtagPtr dbtag;
32214 
32215   for (vnp = dbxref_list; vnp != NULL; vnp = vnp->next)
32216   {
32217     dbtag = (DbtagPtr) vnp->data.ptrvalue;
32218     ValNodeAddPointer (&strings, vnp->choice, GetDbtagString (dbtag));
32219   }
32220   return strings;
32221 }
32222 
32223 
FreeDbxrefList(ValNodePtr list)32224 static ValNodePtr FreeDbxrefList (ValNodePtr list)
32225 {
32226   ValNodePtr vnp;
32227 
32228   for (vnp = list; vnp != NULL; vnp = vnp->next) {
32229     vnp->data.ptrvalue = DbtagFree (vnp->data.ptrvalue);
32230   }
32231   list = ValNodeFree (list);
32232   return list;
32233 }
32234 
32235 
32236 
32237 
BulkSrcGetDbxref(Uint1 data_choice,Pointer data,Pointer metadata)32238 static Pointer BulkSrcGetDbxref (Uint1 data_choice, Pointer data, Pointer metadata)
32239 {
32240   SeqDescrPtr  sdp = (SeqDescrPtr) data;
32241   BioSourcePtr biop;
32242   ValNodePtr   dbxref_list = NULL;
32243 
32244   if (sdp == NULL || sdp->choice != Seq_descr_source
32245       || (biop = (BioSourcePtr)sdp->data.ptrvalue) == NULL
32246       || biop->org == NULL)
32247   {
32248     return NULL;
32249   }
32250 
32251   dbxref_list = DbxrefListToStrings (biop->org->db);
32252 
32253   return dbxref_list;
32254 }
32255 
32256 
BulkSrcSetDbxref(Pointer target,Pointer data)32257 static void BulkSrcSetDbxref (Pointer target, Pointer data)
32258 {
32259   ValNodePtr   dbxref_list;
32260   SeqDescrPtr  sdp = (SeqDescrPtr) target;
32261   BioSourcePtr biop;
32262 
32263   if (sdp == NULL || sdp->choice != Seq_descr_source || sdp->data.ptrvalue == NULL) return;
32264 
32265   biop = (BioSourcePtr) sdp->data.ptrvalue;
32266   if (biop == NULL) return;
32267   dbxref_list = (ValNodePtr) data;
32268   if (biop->org == NULL && dbxref_list == NULL) {
32269     return;
32270   }
32271   if (biop->org == NULL) {
32272     biop->org = OrgRefNew();
32273   }
32274 
32275   /* erase previous dbxrefs */
32276   biop->org->db = FreeDbxrefList (biop->org->db);
32277   biop->org->db = StringsToDbxrefList (dbxref_list);
32278 }
32279 
32280 
BulkSrcFormatDbxref(ColPtr col,CharPtr name)32281 static Int4 BulkSrcFormatDbxref (ColPtr col, CharPtr name)
32282 {
32283   if (col == NULL) return 0;
32284 
32285   col->pixWidth = MAX (15, StringLen (name)) * MaxCharWidth();
32286   col->pixInset = 0;
32287   col->charWidth = 0;
32288   col->charInset = 0;
32289   col->font = NULL;
32290   col->just = 'l';
32291   col->wrap = 1;
32292   col->bar = 0;
32293   col->underline = 0;
32294   col->left = 0;
32295   return col->pixWidth;
32296 }
32297 
32298 
BulkSrcDisplayDbxref(Pointer data)32299 static CharPtr BulkSrcDisplayDbxref (Pointer data)
32300 {
32301   ValNodePtr dbxref_list, vnp;
32302   CharPtr    dbxref_text;
32303   Int4       text_len = 1;
32304 
32305   if (data == NULL) return NULL;
32306   dbxref_list = (ValNodePtr) data;
32307   for (vnp = dbxref_list; vnp != NULL; vnp = vnp->next) {
32308     text_len += StringLen (vnp->data.ptrvalue) + 1;
32309   }
32310   dbxref_text = (CharPtr) MemNew (sizeof (Char) * text_len);
32311   dbxref_text[0] = 0;
32312   for (vnp = dbxref_list; vnp != NULL; vnp = vnp->next) {
32313     StringCat (dbxref_text, vnp->data.ptrvalue);
32314     if (vnp->next != NULL) {
32315       StringCat (dbxref_text, ";");
32316     }
32317   }
32318   return dbxref_text;
32319 }
32320 
32321 
BulkSrcSetDbxrefString(Pointer curr_val,ApplyValuePtr avp)32322 static Pointer BulkSrcSetDbxrefString (Pointer curr_val, ApplyValuePtr avp)
32323 {
32324   CharPtr        curr_val_str;
32325   CharPtr        new_str, name_str, cp;
32326   ValNodePtr     name_list;
32327 
32328   name_list = (ValNodePtr) curr_val;
32329   curr_val_str = BulkSrcDisplayDbxref (name_list);
32330   name_list = ValNodeFreeData (name_list);
32331 
32332   new_str = HandleApplyValue (curr_val_str, avp);
32333 
32334   name_str = new_str;
32335   cp = StringChr (name_str, ';');
32336   while (cp != NULL) {
32337     *cp = 0;
32338     ValNodeAddPointer (&name_list, 0, StringSave (name_str));
32339     *cp = ';';
32340     name_str = cp + 1;
32341     cp = StringChr (name_str, ';');
32342   }
32343   ValNodeAddPointer (&name_list, 0, StringSave (name_str));
32344   new_str = MemFree (new_str);
32345 
32346   return name_list;
32347 }
32348 
32349 
BulkSrcFreeDbxref(Pointer data)32350 static void BulkSrcFreeDbxref (Pointer data)
32351 {
32352   ValNodePtr prot_name_list = (ValNodePtr) data;
32353 
32354   ValNodeFreeData (prot_name_list);
32355 }
32356 
32357 
BulkSrcCopyDbxref(Pointer data)32358 static Pointer BulkSrcCopyDbxref (Pointer data)
32359 {
32360   ValNodePtr new_list = NULL, list, vnp;
32361 
32362   list = (ValNodePtr) data;
32363 
32364   for (vnp = list; vnp != NULL; vnp = vnp->next) {
32365     ValNodeAddPointer (&new_list, vnp->choice, StringSave (vnp->data.ptrvalue));
32366   }
32367   return new_list;
32368 }
32369 
32370 
BulkSrcDbxrefDialog(GrouP g,CharPtr name,SeqEntryPtr sep)32371 static DialoG BulkSrcDbxrefDialog (GrouP g, CharPtr name, SeqEntryPtr sep)
32372 {
32373   return CreateVisibleStringDialog (g, 3, -1, 25);
32374 }
32375 
32376 
32377 static BulkEdFieldData bulk_src_desc_fields[] = {
32378   { "tax name", BulkSrcSetTaxNameDesc, BulkSetSimpleTextString, BulkSrcGetTaxNameDesc, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32379   { "acronym", BulkSrcSetAcronym, BulkSetSimpleTextString, BulkSrcGetAcronym, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32380   { "anamorph", BulkSrcSetAnamorph, BulkSetSimpleTextString, BulkSrcGetAnamorph, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32381   { "authority", BulkSrcSetAuthority, BulkSetSimpleTextString, BulkSrcGetAuthority, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32382   { "biotype", BulkSrcSetBiotype, BulkSetSimpleTextString, BulkSrcGetBiotype, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32383   { "biovar", BulkSrcSetBiovar, BulkSetSimpleTextString, BulkSrcGetBiovar, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32384   { "bio_material", BulkSrcSetBio_material, BulkSetSimpleTextString, BulkSrcGetBio_material, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32385   { "breed", BulkSrcSetBreed, BulkSetSimpleTextString, BulkSrcGetBreed, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32386   { "cell_line", BulkSrcSetCell_line, BulkSetSimpleTextString, BulkSrcGetCell_line, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32387   { "cell_type", BulkSrcSetCell_type, BulkSetSimpleTextString, BulkSrcGetCell_type, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32388   { "chemovar", BulkSrcSetChemovar, BulkSetSimpleTextString, BulkSrcGetChemovar, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32389   { "chromosome", BulkSrcSetChromosome, BulkSetSimpleTextString, BulkSrcGetChromosome, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32390   { "clone", BulkSrcSetClone, BulkSetSimpleTextString, BulkSrcGetClone, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32391   { "clone_lib", BulkSrcSetClone_lib, BulkSetSimpleTextString, BulkSrcGetClone_lib, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32392   { "collected_by", BulkSrcSetCollected_by, BulkSetSimpleTextString, BulkSrcGetCollected_by, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32393   { "collection_date", BulkSrcSetCollection_date, BulkSetSimpleTextString, BulkSrcGetCollection_date, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32394   { "common", BulkSrcSetCommon, BulkSetSimpleTextString, BulkSrcGetCommon, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32395   { "country", BulkSrcSetCountry, BulkSetSimpleTextString, BulkSrcGetCountry, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32396   { "cultivar", BulkSrcSetCultivar, BulkSetSimpleTextString, BulkSrcGetCultivar, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32397   { "culture_collection", BulkSrcSetCulture_collection, BulkSetSimpleTextString, BulkSrcGetCulture_collection, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32398   { "dbxref", BulkSrcSetDbxref, BulkSrcSetDbxrefString, BulkSrcGetDbxref, BulkSrcDisplayDbxref, BulkSrcFreeDbxref, BulkSrcDbxrefDialog, BulkSrcFormatDbxref, NULL, NULL, BulkSrcCopyDbxref },
32399   { "dev_stage", BulkSrcSetDev_stage, BulkSetSimpleTextString, BulkSrcGetDev_stage, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32400   { "ecotype", BulkSrcSetEcotype, BulkSetSimpleTextString, BulkSrcGetEcotype, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32401   { "endogenous_virus_name", BulkSrcSetEndogenous_virus_name, BulkSetSimpleTextString, BulkSrcGetEndogenous_virus_name, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32402   { "environmental-sample", BULK_SRC_SUBSRC_FIELD_TF(Environmental_sample) },
32403   { "forma", BulkSrcSetForma, BulkSetSimpleTextString, BulkSrcGetForma, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32404   { "forma_specialis", BulkSrcSetForma_specialis, BulkSetSimpleTextString, BulkSrcGetForma_specialis, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32405   { "frequency", BulkSrcSetFrequency, BulkSetSimpleTextString, BulkSrcGetFrequency, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32406   { "genotype", BulkSrcSetGenotype, BulkSetSimpleTextString, BulkSrcGetGenotype, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32407   { "germline", BULK_SRC_SUBSRC_FIELD_TF(Germline) },
32408   { "group", BulkSrcSetGroup, BulkSetSimpleTextString, BulkSrcGetGroup, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32409   { "haplogroup", BulkSrcSetHaplogroup, BulkSetSimpleTextString, BulkSrcGetHaplogroup, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32410   { "haplotype", BulkSrcSetHaplotype, BulkSetSimpleTextString, BulkSrcGetHaplotype, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32411   { "host", BulkSrcSetHost, BulkSetSimpleTextString, BulkSrcGetHost, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32412   { "identified_by", BulkSrcSetIdentified_by, BulkSetSimpleTextString, BulkSrcGetIdentified_by, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32413   { "isolate", BulkSrcSetIsolate, BulkSetSimpleTextString, BulkSrcGetIsolate, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32414   { "isolation_source", BulkSrcSetIsolation_source, BulkSetSimpleTextString, BulkSrcGetIsolation_source, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32415   { "lab_host", BulkSrcSetLab_host, BulkSetSimpleTextString, BulkSrcGetLab_host, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32416   { "lat_Lon", BulkSrcSetLat_Lon, BulkSetSimpleTextString, BulkSrcGetLat_Lon, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32417   { "linkage_group", BulkSrcSetLinkage_group, BulkSetSimpleTextString, BulkSrcGetLinkage_group, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32418   { "map", BulkSrcSetMap, BulkSetSimpleTextString, BulkSrcGetMap, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32419   { "mating_type", BulkSrcSetMating_type, BulkSetSimpleTextString, BulkSrcGetMating_type, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32420   { "metagenome_source", BulkSrcSetMetagenome_source, BulkSetSimpleTextString, BulkSrcGetMetagenome_source, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32421   { "metagenomic", BULK_SRC_SUBSRC_FIELD_TF(Metagenomic) },
32422   { "note (orgmod)", BulkSrcSetOrgModNote, BulkSetSimpleTextString, BulkSrcGetOrgModNote, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32423   { "note (subsrc)", BulkSrcSetSubSrcNote, BulkSetSimpleTextString, BulkSrcGetSubSrcNote, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32424   { "pathovar", BulkSrcSetPathovar, BulkSetSimpleTextString, BulkSrcGetPathovar, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32425   { "plasmid_name", BulkSrcSetPlasmid_name, BulkSetSimpleTextString, BulkSrcGetPlasmid_name, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32426   { "pop_variant", BulkSrcSetPop_variant, BulkSetSimpleTextString, BulkSrcGetPop_variant, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32427   { "rearranged", BULK_SRC_SUBSRC_FIELD_TF(Rearranged) } ,
32428   { "segment", BulkSrcSetSegment, BulkSetSimpleTextString, BulkSrcGetSegment, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32429   { "serogroup", BulkSrcSetSerogroup, BulkSetSimpleTextString, BulkSrcGetSerogroup, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32430   { "serotype", BulkSrcSetSerotype, BulkSetSimpleTextString, BulkSrcGetSerotype, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32431   { "serovar", BulkSrcSetSerovar, BulkSetSimpleTextString, BulkSrcGetSerovar, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32432   { "sex", BulkSrcSetSex, BulkSetSimpleTextString, BulkSrcGetSex, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32433   { "specimen_voucher", BulkSrcSetSpecimen_voucher, BulkSetSimpleTextString, BulkSrcGetSpecimen_voucher, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32434   { "strain", BulkSrcSetStrain, BulkSetSimpleTextString, BulkSrcGetStrain, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32435   { "subclone", BulkSrcSetSubclone, BulkSetSimpleTextString, BulkSrcGetSubclone, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32436   { "subgroup", BulkSrcSetSubgroup, BulkSetSimpleTextString, BulkSrcGetSubgroup, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32437   { "substrain", BulkSrcSetSubstrain, BulkSetSimpleTextString, BulkSrcGetSubstrain, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32438   { "subtype", BulkSrcSetSubtype, BulkSetSimpleTextString, BulkSrcGetSubtype, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32439   { "sub_species", BulkSrcSetSub_species, BulkSetSimpleTextString, BulkSrcGetSub_species, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32440   { "synonym", BulkSrcSetSynonym, BulkSetSimpleTextString, BulkSrcGetSynonym, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32441   { "teleomorph", BulkSrcSetTeleomorph, BulkSetSimpleTextString, BulkSrcGetTeleomorph, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32442   { "tissue_lib", BulkSrcSetTissue_lib, BulkSetSimpleTextString, BulkSrcGetTissue_lib, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32443   { "tissue_type", BulkSrcSetTissue_type, BulkSetSimpleTextString, BulkSrcGetTissue_type, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32444   { "transgenic", BULK_SRC_SUBSRC_FIELD_TF(Transgenic) },
32445   { "type", BulkSrcSetType, BulkSetSimpleTextString, BulkSrcGetType, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32446   { "variety", BulkSrcSetVariety, BulkSetSimpleTextString, BulkSrcGetVariety, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32447   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
32448 
32449 
32450 static BulkEdFieldData bulk_src_feat_fields[] = {
32451   { "tax name", BulkSrcSetTaxNameFeat, BulkSetSimpleTextString, BulkSrcGetTaxNameFeat, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
32452   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
32453 
32454 typedef struct bulkeditor {
32455   FORM_MESSAGE_BLOCK
32456   DialoG         bulk_ed;
32457   ButtoN         do_log;
32458   BulkEdFieldPtr field_list;
32459 } BulkEditorData, PNTR BulkEditorPtr;
32460 
32461 typedef struct collectfeat {
32462   Uint1 featdef;
32463   Uint1 featchoice;
32464   ValNodePtr feat_list;
32465 } CollectFeatData, PNTR CollectFeatPtr;
32466 
CollectFeaturesForBulkEditor(BioseqPtr bsp,Pointer data)32467 static void CollectFeaturesForBulkEditor (BioseqPtr bsp, Pointer data)
32468 {
32469   CollectFeatPtr cfp;
32470   SeqFeatPtr     sfp;
32471   SeqMgrFeatContext fcontext;
32472 
32473   if (bsp == NULL || data == NULL) return;
32474   cfp = (CollectFeatPtr) data;
32475 
32476   for (sfp = SeqMgrGetNextFeature (bsp, NULL, cfp->featchoice, cfp->featdef, &fcontext);
32477        sfp != NULL;
32478        sfp = SeqMgrGetNextFeature (bsp, sfp, cfp->featchoice, cfp->featdef, &fcontext)) {
32479     ValNodeAddPointer (&(cfp->feat_list), OBJ_SEQFEAT, sfp);
32480   }
32481 }
32482 
AcceptBulkEditor(ButtoN b)32483 static void AcceptBulkEditor (ButtoN b)
32484 {
32485   BulkEditorPtr      bep;
32486 
32487   bep = (BulkEditorPtr) GetObjectExtra (b);
32488   if (bep == NULL) return;
32489 
32490   WatchCursor();
32491   Update();
32492 
32493   ApplyBulkEditorToObjectList (bep->bulk_ed, bep->do_log == NULL ? FALSE : GetStatus (bep->do_log));
32494 
32495   ObjMgrSetDirtyFlag (bep->input_entityID, TRUE);
32496   ObjMgrSendMsg (OM_MSG_UPDATE, bep->input_entityID, 0, 0);
32497   ArrowCursor ();
32498   Update ();
32499   Remove (bep->form);
32500 }
32501 
GetSubtypeForBulkEdit(ValNodePtr feat_list)32502 extern Uint1 GetSubtypeForBulkEdit (ValNodePtr feat_list)
32503 {
32504   ValNodePtr vnp_check;
32505   SeqFeatPtr sfp;
32506   Uint1      subtype = FEATDEF_BAD;
32507 
32508   for (vnp_check = feat_list; vnp_check != NULL; vnp_check = vnp_check->next) {
32509     if (vnp_check->choice != OBJ_SEQFEAT) continue;
32510     sfp = vnp_check->data.ptrvalue;
32511     if (sfp->data.choice == SEQFEAT_RNA) {
32512       /* note - using FEATDEF_rRNA to represent all editable RNA features */
32513       if (!IsBulkEditableRNA(sfp)) {
32514         return FEATDEF_BAD;
32515       } else if (subtype == FEATDEF_BAD) {
32516         subtype = FEATDEF_rRNA;
32517       } else if (subtype != FEATDEF_rRNA) {
32518         return FEATDEF_BAD;
32519       }
32520     } else if (subtype == FEATDEF_BAD) {
32521       subtype = sfp->idx.subtype;
32522     } else if (subtype != sfp->idx.subtype) {
32523       return FEATDEF_BAD;
32524     }
32525   }
32526   return subtype;
32527 }
32528 
ExportBulkEditorTableBtn(ButtoN b)32529 static void ExportBulkEditorTableBtn (ButtoN b)
32530 {
32531   BulkEditorPtr bep;
32532 
32533   bep = (BulkEditorPtr) GetObjectExtra (b);
32534   if (bep == NULL) {
32535     return;
32536   }
32537 
32538   ExportBulkEditorTable (bep->bulk_ed);
32539 
32540 }
32541 
32542 
BulkEditorFeatList(Uint2 entityID,ValNodePtr feat_list)32543 extern void BulkEditorFeatList (Uint2 entityID, ValNodePtr feat_list)
32544 {
32545   GrouP              c, g;
32546   ButtoN             b;
32547   BulkEditorPtr      bep;
32548   GrouP              h;
32549   WindoW             w;
32550   SeqEntryPtr        sep;
32551   BulkEdFieldPtr     field_list = NULL;
32552   Uint1              subtype = 0;
32553   CharPtr            title = "Bulk Editor";
32554 
32555   if (feat_list == NULL) {
32556     Message (MSG_ERROR, "No features found!");
32557     return;
32558   }
32559   /* Create a new window, and a struct */
32560   /* to pass around the data in.       */
32561 
32562   sep = GetTopSeqEntryForEntityID (entityID);
32563 
32564   subtype = GetSubtypeForBulkEdit (feat_list);
32565   if (subtype == FEATDEF_BAD) {
32566     Message (MSG_ERROR, "Can't bulk edit a list of mixed feature types!");
32567     return;
32568   }
32569   if (subtype == FEATDEF_CDS) {
32570     title = "Bulk CDS Editor";
32571     field_list = bulk_cds_fields;
32572   } else if (subtype == FEATDEF_GENE) {
32573     title = "Bulk Gene Editor";
32574     field_list = bulk_gene_fields;
32575   } else if (subtype == FEATDEF_rRNA) {
32576     title = "Bulk RNA Editor";
32577     /* Note - using FEATDEF_rRNA to represent all editable rRNA features */
32578     field_list = bulk_rna_fields;
32579   } else if (subtype == FEATDEF_BIOSRC) {
32580     title = "Bulk Src Feat Editor";
32581     field_list = bulk_src_feat_fields;
32582   } else {
32583     Message (MSG_ERROR, "No bulk editor for this feature type!");
32584     return;
32585   }
32586 
32587   bep = (BulkEditorPtr) MemNew (sizeof (BulkEditorData));
32588   if (bep == NULL)
32589     return;
32590 
32591   bep->field_list = field_list;
32592 
32593   w = FixedWindow (-50, -33, -10, -10, title,
32594            StdCloseWindowProc);
32595   SetObjectExtra (w, bep, StdCleanupFormProc);
32596   bep->form = (ForM) w;
32597   bep->input_entityID = entityID;
32598 
32599   h = HiddenGroup (w, -1, 0, NULL);
32600   SetGroupSpacing (h, 10, 10);
32601 
32602   /* want: Document with columns for pseudo (when appropriate), location, fields */
32603   /* when user clicks on field, should be able to edit contents */
32604 
32605   bep->bulk_ed = CreateBulkEditorDialog (h, bep->field_list, feat_list, sep, TRUE, NULL, NULL);
32606 
32607   if (subtype == FEATDEF_CDS) {
32608     bep->do_log = CheckBox (h, "Log Changes", NULL);
32609   } else {
32610     bep->do_log = NULL;
32611   }
32612 
32613   g = HiddenGroup (h, 2, 0, NULL);
32614   b = PushButton (g, "Export Table", ExportBulkEditorTableBtn);
32615   SetObjectExtra (b, bep, NULL);
32616 
32617   /* Add Accept and Cancel buttons */
32618 
32619   c = HiddenGroup (h, 3, 0, NULL);
32620   b = PushButton (c, "Accept", AcceptBulkEditor);
32621   SetObjectExtra (b, bep, NULL);
32622   PushButton (c, "Cancel", StdCancelButtonProc);
32623 
32624   /* Line things up nicely */
32625 
32626   AlignObjects (ALIGN_CENTER, (HANDLE) bep->bulk_ed,
32627                               (HANDLE) c, (HANDLE) g,
32628                               (HANDLE) bep->do_log, NULL);
32629 
32630 
32631   /* Display the window now */
32632 
32633   RealizeWindow (w);
32634   Show (w);
32635   Select (w);
32636   Update ();
32637 }
32638 
32639 
GetSubtypeForBulkDescrEdit(ValNodePtr descr_list)32640 extern Uint1 GetSubtypeForBulkDescrEdit (ValNodePtr descr_list)
32641 {
32642   ValNodePtr vnp_check;
32643   SeqDescrPtr sdp;
32644   Uint1      subtype = 0;
32645 
32646   for (vnp_check = descr_list; vnp_check != NULL; vnp_check = vnp_check->next) {
32647     if (vnp_check->choice != OBJ_SEQDESC) continue;
32648     sdp = vnp_check->data.ptrvalue;
32649     if (subtype == 0) {
32650       subtype = sdp->choice;
32651     } else if (sdp->choice != subtype) {
32652       return 0;
32653     }
32654   }
32655   return subtype;
32656 }
32657 
32658 
BulkEditorDescrList(Uint2 entityID,ValNodePtr descr_list)32659 extern void BulkEditorDescrList (Uint2 entityID, ValNodePtr descr_list)
32660 {
32661   GrouP              c;
32662   ButtoN             b;
32663   BulkEditorPtr      bep;
32664   GrouP              h;
32665   WindoW             w;
32666   SeqEntryPtr        sep;
32667   BulkEdFieldPtr     field_list = NULL;
32668   Uint1              subtype = 0;
32669 
32670   if (descr_list == NULL) {
32671     Message (MSG_ERROR, "No descriptors found!");
32672     return;
32673   }
32674   /* Create a new window, and a struct */
32675   /* to pass around the data in.       */
32676 
32677   sep = GetTopSeqEntryForEntityID (entityID);
32678 
32679   subtype = GetSubtypeForBulkDescrEdit (descr_list);
32680   if (subtype == 0) {
32681     Message (MSG_ERROR, "Can't bulk edit a list of mixed descriptor types!");
32682     return;
32683   }
32684   if (subtype == Seq_descr_source) {
32685     field_list = bulk_src_desc_fields;
32686   } else {
32687     Message (MSG_ERROR, "No bulk editor for this descriptor type!");
32688     return;
32689   }
32690 
32691   bep = (BulkEditorPtr) MemNew (sizeof (BulkEditorData));
32692   if (bep == NULL)
32693     return;
32694 
32695   bep->field_list = field_list;
32696 
32697   w = FixedWindow (-50, -33, -10, -10, "Bulk Src Editor",
32698            StdCloseWindowProc);
32699   SetObjectExtra (w, bep, StdCleanupFormProc);
32700   bep->form = (ForM) w;
32701   bep->input_entityID = entityID;
32702 
32703   h = HiddenGroup (w, -1, 0, NULL);
32704   SetGroupSpacing (h, 10, 10);
32705 
32706   /* want: Document with columns for pseudo (when appropriate), location, fields */
32707   /* when user clicks on field, should be able to edit contents */
32708 
32709   bep->bulk_ed = CreateBulkEditorDialogEx (h, bep->field_list, descr_list, sep, TRUE, NULL, NULL, NULL, subtype == Seq_descr_source);
32710 
32711   /* Add Accept and Cancel buttons */
32712 
32713   c = HiddenGroup (h, 3, 0, NULL);
32714   b = PushButton (c, "Accept", AcceptBulkEditor);
32715   SetObjectExtra (b, bep, NULL);
32716   PushButton (c, "Cancel", StdCancelButtonProc);
32717 
32718   /* Line things up nicely */
32719 
32720   AlignObjects (ALIGN_CENTER, (HANDLE) bep->bulk_ed,
32721                               (HANDLE) c, NULL);
32722 
32723 
32724   /* Display the window now */
32725 
32726   RealizeWindow (w);
32727   Show (w);
32728   Select (w);
32729   Update ();
32730 }
32731 
32732 
BulkEditorObjectList(Uint2 entityID,CharPtr title,ValNodePtr feat_list,BulkEdFieldPtr field_list)32733 NLM_EXTERN void BulkEditorObjectList (Uint2 entityID, CharPtr title, ValNodePtr feat_list, BulkEdFieldPtr field_list)
32734 {
32735   GrouP              c;
32736   ButtoN             b;
32737   BulkEditorPtr      bep;
32738   GrouP              h;
32739   WindoW             w;
32740   SeqEntryPtr        sep;
32741   Uint1              subtype = 0;
32742 
32743   if (feat_list == NULL) {
32744     Message (MSG_ERROR, "No features found!");
32745     return;
32746   }
32747   /* Create a new window, and a struct */
32748   /* to pass around the data in.       */
32749 
32750   sep = GetTopSeqEntryForEntityID (entityID);
32751 
32752   bep = (BulkEditorPtr) MemNew (sizeof (BulkEditorData));
32753   if (bep == NULL)
32754     return;
32755 
32756   bep->field_list = field_list;
32757 
32758   w = FixedWindow (-50, -33, -10, -10, title,
32759            StdCloseWindowProc);
32760   SetObjectExtra (w, bep, StdCleanupFormProc);
32761   bep->form = (ForM) w;
32762   bep->input_entityID = entityID;
32763 
32764   h = HiddenGroup (w, -1, 0, NULL);
32765   SetGroupSpacing (h, 10, 10);
32766 
32767   /* want: Document with columns for pseudo (when appropriate), location, fields */
32768   /* when user clicks on field, should be able to edit contents */
32769 
32770   bep->bulk_ed = CreateBulkEditorDialog (h, bep->field_list, feat_list, sep, TRUE, NULL, NULL);
32771 
32772   /* Add Accept and Cancel buttons */
32773 
32774   c = HiddenGroup (h, 3, 0, NULL);
32775   b = PushButton (c, "Accept", AcceptBulkEditor);
32776   SetObjectExtra (b, bep, NULL);
32777   PushButton (c, "Cancel", StdCancelButtonProc);
32778 
32779   /* Line things up nicely */
32780 
32781   AlignObjects (ALIGN_CENTER, (HANDLE) bep->bulk_ed,
32782                               (HANDLE) c, NULL);
32783 
32784 
32785   /* Display the window now */
32786 
32787   RealizeWindow (w);
32788   Show (w);
32789   Select (w);
32790   Update ();
32791 }
32792 
32793 
BulkEditorBaseForm(BaseFormPtr bfp,Uint1 featchoice,Uint1 featdef)32794 static void BulkEditorBaseForm (BaseFormPtr bfp, Uint1 featchoice, Uint1 featdef)
32795 {
32796   SeqEntryPtr        sep;
32797   CollectFeatData    cfd;
32798   BulkEdFieldPtr     field_list = NULL;
32799 
32800   if (bfp == NULL) return;
32801 
32802   /* Create a new window, and a struct */
32803   /* to pass around the data in.       */
32804 
32805   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
32806 
32807   if (featchoice == SEQFEAT_CDREGION || featdef == FEATDEF_CDS) {
32808     field_list = bulk_cds_fields;
32809   } else if (featchoice == SEQFEAT_GENE || featdef == FEATDEF_GENE) {
32810     field_list = bulk_gene_fields;
32811   } else if (featchoice == SEQFEAT_RNA) {
32812     field_list = bulk_rna_fields;
32813   } else {
32814     Message (MSG_ERROR, "No bulk editor for this feature type!");
32815     return;
32816   }
32817 
32818   cfd.featchoice = featchoice;
32819   cfd.featdef = featdef;
32820   cfd.feat_list = NULL;
32821   VisitBioseqsInSep (sep, &cfd, CollectFeaturesForBulkEditor);
32822 
32823   if (cfd.feat_list == NULL) {
32824     Message (MSG_ERROR, "No features found!");
32825     return;
32826   }
32827 
32828   BulkEditorFeatList (bfp->input_entityID, cfd.feat_list);
32829 }
32830 
BulkEditor(IteM i,Uint1 featchoice,Uint1 featdef)32831 static void BulkEditor (IteM i, Uint1 featchoice, Uint1 featdef)
32832 {
32833   BaseFormPtr        bfp;
32834 
32835 #ifdef WIN_MAC
32836   bfp = currentFormDataPtr;
32837 #else
32838   bfp = GetObjectExtra (i);
32839 #endif
32840 
32841   BulkEditorBaseForm(bfp, featchoice, featdef);
32842 }
32843 
BulkEditCDS(IteM i)32844 NLM_EXTERN void BulkEditCDS (IteM i)
32845 {
32846   BulkEditor (i, SEQFEAT_CDREGION, FEATDEF_CDS);
32847 }
32848 
32849 
BulkEditCDSBaseForm(BaseFormPtr bfp)32850 NLM_EXTERN void BulkEditCDSBaseForm (BaseFormPtr bfp)
32851 {
32852   BulkEditorBaseForm (bfp, SEQFEAT_CDREGION, FEATDEF_CDS);
32853 }
32854 
32855 
BulkEditGene(IteM i)32856 extern void BulkEditGene (IteM i)
32857 {
32858   BulkEditor (i, SEQFEAT_GENE, FEATDEF_GENE);
32859 }
32860 
BulkEditRNA(IteM i)32861 extern void BulkEditRNA (IteM i)
32862 {
32863   BulkEditor (i, SEQFEAT_RNA, 0);
32864 }
32865 
32866 
GetBulkEditSourceCallback(SeqDescrPtr sdp,Pointer data)32867 static void GetBulkEditSourceCallback (SeqDescrPtr sdp, Pointer data)
32868 {
32869   if (sdp != NULL && sdp->choice == Seq_descr_source && data != NULL) {
32870     ValNodeAddPointer ((ValNodePtr PNTR) data, OBJ_SEQDESC, sdp);
32871   }
32872 }
32873 
32874 
BulkEditSourceBaseForm(BaseFormPtr bfp)32875 NLM_EXTERN void BulkEditSourceBaseForm (BaseFormPtr bfp)
32876 {
32877   SeqEntryPtr  sep;
32878   ValNodePtr   list = NULL;
32879 
32880   if (bfp == NULL) return;
32881   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
32882   if (sep == NULL) return;
32883   VisitDescriptorsInSep (sep, &list, GetBulkEditSourceCallback);
32884 
32885   BulkEditorDescrList (bfp->input_entityID, list);
32886 }
32887 
32888 
BulkEditSource(IteM i)32889 extern void BulkEditSource (IteM i)
32890 {
32891   BaseFormPtr  bfp;
32892 
32893 #ifdef WIN_MAC
32894   bfp = currentFormDataPtr;
32895 #else
32896   bfp = GetObjectExtra (i);
32897 #endif
32898   if (bfp == NULL) return;
32899   BulkEditSourceBaseForm (bfp);
32900 }
32901 
32902 
GetBarcodeTestBarcodeID(Uint1 data_choice,Pointer data,Pointer metadata)32903 static Pointer GetBarcodeTestBarcodeID (Uint1 data_choice, Pointer data, Pointer metadata)
32904 {
32905   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32906   if (res == NULL || res->bsp == NULL) {
32907     return NULL;
32908   } else {
32909     return BarcodeTestBarcodeIdString (res->bsp);
32910   }
32911 }
32912 
32913 
GetBarcodeTestGenbankID(Uint1 data_choice,Pointer data,Pointer metadata)32914 static Pointer GetBarcodeTestGenbankID (Uint1 data_choice, Pointer data, Pointer metadata)
32915 {
32916   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32917   if (res == NULL || res->bsp == NULL) {
32918     return NULL;
32919   } else {
32920     return BarcodeTestGenbankIdString (res->bsp);
32921   }
32922 }
32923 
32924 
GetBarcodeTestLengthResult(Uint1 data_choice,Pointer data,Pointer metadata)32925 static Pointer GetBarcodeTestLengthResult (Uint1 data_choice, Pointer data, Pointer metadata)
32926 {
32927   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32928   if (res == NULL || !res->failed_tests[eBarcodeTest_Length]) {
32929     return NULL;
32930   } else {
32931     return StringSave ("TRUE");
32932   }
32933 }
32934 
32935 
GetBarcodeTestPrimersResult(Uint1 data_choice,Pointer data,Pointer metadata)32936 static Pointer GetBarcodeTestPrimersResult (Uint1 data_choice, Pointer data, Pointer metadata)
32937 {
32938   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32939   if (res == NULL || !res->failed_tests[eBarcodeTest_Primers]) {
32940     return NULL;
32941   } else {
32942     return StringSave ("TRUE");
32943   }
32944 }
32945 
32946 
GetBarcodeTestCountryResult(Uint1 data_choice,Pointer data,Pointer metadata)32947 static Pointer GetBarcodeTestCountryResult (Uint1 data_choice, Pointer data, Pointer metadata)
32948 {
32949   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32950   if (res == NULL || !res->failed_tests[eBarcodeTest_Country]) {
32951     return NULL;
32952   } else {
32953     return StringSave ("TRUE");
32954   }
32955 }
32956 
32957 
GetBarcodeTestSpecimenVoucherResult(Uint1 data_choice,Pointer data,Pointer metadata)32958 static Pointer GetBarcodeTestSpecimenVoucherResult (Uint1 data_choice, Pointer data, Pointer metadata)
32959 {
32960   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32961   if (res == NULL || !res->failed_tests[eBarcodeTest_SpecimenVoucher]) {
32962     return NULL;
32963   } else {
32964     return StringSave ("TRUE");
32965   }
32966 }
32967 
32968 
GetBarcodeTestStructuredSpecimenVoucherResult(Uint1 data_choice,Pointer data,Pointer metadata)32969 static Pointer GetBarcodeTestStructuredSpecimenVoucherResult (Uint1 data_choice, Pointer data, Pointer metadata)
32970 {
32971   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32972   if (res == NULL || !res->failed_tests[eBarcodeTest_StructuredSpecimenVoucher]) {
32973     return NULL;
32974   } else {
32975     return StringSave ("TRUE");
32976   }
32977 }
32978 
32979 
GetBarcodeTestCollectionDateResult(Uint1 data_choice,Pointer data,Pointer metadata)32980 static Pointer GetBarcodeTestCollectionDateResult (Uint1 data_choice, Pointer data, Pointer metadata)
32981 {
32982   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32983   if (res == NULL || !res->failed_tests[eBarcodeTest_CollectionDate]) {
32984     return NULL;
32985   } else {
32986     return StringSave ("TRUE");
32987   }
32988 }
32989 
32990 
GetBarcodeTestOrderAssignmentResult(Uint1 data_choice,Pointer data,Pointer metadata)32991 static Pointer GetBarcodeTestOrderAssignmentResult (Uint1 data_choice, Pointer data, Pointer metadata)
32992 {
32993   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
32994   if (res == NULL || !res->failed_tests[eBarcodeTest_OrderAssignment]) {
32995     return NULL;
32996   } else {
32997     return StringSave ("TRUE");
32998   }
32999 }
33000 
33001 
GetBarcodeTestLowTraceResult(Uint1 data_choice,Pointer data,Pointer metadata)33002 static Pointer GetBarcodeTestLowTraceResult (Uint1 data_choice, Pointer data, Pointer metadata)
33003 {
33004   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
33005   if (res == NULL || !res->failed_tests[eBarcodeTest_LowTrace]) {
33006     return NULL;
33007   } else {
33008     return StringSave ("TRUE");
33009   }
33010 }
33011 
33012 
GetBarcodeTestFrameShiftResult(Uint1 data_choice,Pointer data,Pointer metadata)33013 static Pointer GetBarcodeTestFrameShiftResult (Uint1 data_choice, Pointer data, Pointer metadata)
33014 {
33015   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
33016   if (res == NULL || !res->failed_tests[eBarcodeTest_FrameShift]) {
33017     return NULL;
33018   } else {
33019     return StringSave ("TRUE");
33020   }
33021 }
33022 
33023 
GetBarcodeTestPercentNsResult(Uint1 data_choice,Pointer data,Pointer metadata)33024 static Pointer GetBarcodeTestPercentNsResult (Uint1 data_choice, Pointer data, Pointer metadata)
33025 {
33026   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
33027   Char txt[5];
33028   if (res == NULL || !res->failed_tests[eBarcodeTest_PercentN]) {
33029     return NULL;
33030   } else {
33031     sprintf (txt, "%.1f", res->n_percent);
33032     return StringSave (txt);
33033   }
33034 }
33035 
33036 
HasBarcodeKeyword(Uint1 data_choice,Pointer data,Pointer metadata)33037 static Pointer HasBarcodeKeyword (Uint1 data_choice, Pointer data, Pointer metadata)
33038 {
33039   Boolean rval = FALSE;
33040 
33041   BarcodeTestResultsPtr res = (BarcodeTestResultsPtr) data;
33042   if (res != NULL && res->bsp != NULL) {
33043     rval = BioseqHasBarcodeKeyword(res->bsp);
33044   }
33045   if (rval) {
33046     return StringSave ("TRUE");
33047   } else {
33048     return NULL;
33049   }
33050 }
33051 
33052 
33053 
BarcodeFormatBarcodeID(ColPtr col,CharPtr name)33054 static Int4 BarcodeFormatBarcodeID (ColPtr col, CharPtr name)
33055 {
33056   if (col == NULL) return 0;
33057 
33058   col->pixWidth = MAX (21, StringLen (name)) * MaxCharWidth();
33059   col->pixInset = 0;
33060   col->charWidth = 0;
33061   col->charInset = 0;
33062   col->font = NULL;
33063   col->just = 'l';
33064   col->wrap = 1;
33065   col->bar = 0;
33066   col->underline = 0;
33067   col->left = 0;
33068   return col->pixWidth;
33069 }
33070 
33071 
BarcodeFormatGenbankID(ColPtr col,CharPtr name)33072 static Int4 BarcodeFormatGenbankID (ColPtr col, CharPtr name)
33073 {
33074   if (col == NULL) return 0;
33075 
33076   col->pixWidth = MAX (10, StringLen (name)) * MaxCharWidth();
33077   col->pixInset = 0;
33078   col->charWidth = 0;
33079   col->charInset = 0;
33080   col->font = NULL;
33081   col->just = 'l';
33082   col->wrap = 1;
33083   col->bar = 0;
33084   col->underline = 0;
33085   col->left = 0;
33086   return col->pixWidth;
33087 }
33088 
33089 
BarcodeFormatPercentN(ColPtr col,CharPtr name)33090 static Int4 BarcodeFormatPercentN (ColPtr col, CharPtr name)
33091 {
33092   if (col == NULL) return 0;
33093 
33094   col->pixWidth = MAX (5, StringLen (name)) * MaxCharWidth();
33095   col->pixInset = 0;
33096   col->charWidth = 0;
33097   col->charInset = 0;
33098   col->font = NULL;
33099   col->just = 'l';
33100   col->wrap = 1;
33101   col->bar = 0;
33102   col->underline = 0;
33103   col->left = 0;
33104   return col->pixWidth;
33105 }
33106 
33107 
33108 static BulkEdFieldData barcode_test_fields[] = {
33109   { "Barcode ID", NULL, NULL, GetBarcodeTestBarcodeID, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BarcodeFormatBarcodeID, NULL, NULL, BulkSimpleTextCopy },
33110   { "Genbank Accession", NULL, NULL, GetBarcodeTestGenbankID, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BarcodeFormatGenbankID, NULL, NULL, BulkSimpleTextCopy },
33111   { "Length", NULL, NULL, GetBarcodeTestLengthResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33112   { "Primers", NULL, NULL, GetBarcodeTestPrimersResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33113   { "Country", NULL, NULL, GetBarcodeTestCountryResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33114   { "Voucher", NULL, NULL, GetBarcodeTestSpecimenVoucherResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33115   { "Structured Voucher", NULL, NULL, GetBarcodeTestStructuredSpecimenVoucherResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33116   { "Percent Ns", NULL, NULL, GetBarcodeTestPercentNsResult, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BarcodeFormatPercentN, NULL, NULL, BulkSimpleTextCopy },
33117   { "Collection Date", NULL, NULL, GetBarcodeTestCollectionDateResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33118   { "Order Assignment", NULL, NULL, GetBarcodeTestOrderAssignmentResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33119   { "Low Trace", NULL, NULL, GetBarcodeTestLowTraceResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33120   { "Frame Shift", NULL, NULL, GetBarcodeTestFrameShiftResult, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33121   { "Has BARCODE Keyword", NULL, NULL, HasBarcodeKeyword, NULL, BulkFreeSimpleText, NULL, BulkFormatTrueFalse, BulkDrawTrueFalse, NULL, BulkSimpleTextCopy },
33122   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
33123 
NavigateToBarcodeTestResultBioseq(ValNodePtr object,Pointer userdata)33124 static void NavigateToBarcodeTestResultBioseq (ValNodePtr object, Pointer userdata)
33125 {
33126   BaseFormPtr           bfp;
33127   BarcodeTestResultsPtr res;
33128 
33129   if (object == NULL) return;
33130 
33131   res = (BarcodeTestResultsPtr) object->data.ptrvalue;
33132 
33133   if (res == NULL || res->bsp == NULL) return;
33134   bfp = GetBaseFormForEntityID (res->bsp->idx.entityID);
33135   if (bfp != NULL) {
33136     Select (bfp->form);
33137     SetBioseqViewTargetByBioseq (bfp, res->bsp);
33138   }
33139 }
33140 
33141 
BarcodeTestResultsDisplay(GrouP h,BarcodeTestConfigPtr cfg)33142 extern DialoG BarcodeTestResultsDisplay (GrouP h, BarcodeTestConfigPtr cfg)
33143 {
33144   return CreateBulkEditorDialog (h, barcode_test_fields, NULL, NULL, FALSE, NavigateToBarcodeTestResultBioseq, NULL);
33145 }
33146 
GetCurrentLatLon(Uint1 data_choice,Pointer data,Pointer metadata)33147 static Pointer GetCurrentLatLon (Uint1 data_choice, Pointer data, Pointer metadata)
33148 {
33149   SubSourcePtr bad_ssp;
33150   BioSourcePtr biop;
33151 
33152   biop = GetBioSourceFromObject (data_choice, data);
33153   if (biop == NULL) return NULL;
33154 
33155   bad_ssp = FindBadLatLon (biop);
33156   if (bad_ssp == NULL)
33157   {
33158     return NULL;
33159   }
33160   else
33161   {
33162     return StringSave (bad_ssp->name);
33163   }
33164 }
33165 
33166 
GetCorrectedLatLon(Uint1 data_choice,Pointer data,Pointer metadata)33167 static Pointer GetCorrectedLatLon (Uint1 data_choice, Pointer data, Pointer metadata)
33168 {
33169   SubSourcePtr bad_ssp;
33170   CharPtr      fix;
33171   BioSourcePtr biop;
33172 
33173   biop = GetBioSourceFromObject (data_choice, data);
33174   if (biop == NULL) return NULL;
33175 
33176   bad_ssp = FindBadLatLon (biop);
33177   if (bad_ssp == NULL)
33178   {
33179     return NULL;
33180   }
33181   else
33182   {
33183     fix = FixLatLonFormat (bad_ssp->name);
33184     if (fix == NULL)
33185     {
33186       return StringSave ("Unable to autocorrect");
33187     }
33188     else
33189     {
33190       return fix;
33191     }
33192   }
33193 }
33194 
33195 
33196 static BulkEdFieldData latlon_fields[] = {
33197   { "Current Lat-lon", NULL, NULL, GetCurrentLatLon, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33198   { "Suggested Correction", NULL, NULL, GetCorrectedLatLon, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33199   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
33200 
LatLonTestResultsDisplay(GrouP h)33201 extern DialoG LatLonTestResultsDisplay (GrouP h)
33202 {
33203   return CreateBulkEditorDialog (h, latlon_fields, NULL, NULL, FALSE, ScrollToDiscrepancyItem, EditDiscrepancyItem);
33204 }
33205 
33206 
33207 static BulkEdFieldData trim_sequence_fields[] = {
33208   { "Current PercentN", NULL, NULL, GetCurrentPercentN, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33209   { "Bases to Remove", NULL, NULL, GetTrimRemove, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33210   { "Remaining Bases", NULL, NULL, GetTrimRemaining, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33211   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
33212 
TrimSequenceResultsDisplay(GrouP h)33213 extern DialoG TrimSequenceResultsDisplay (GrouP h)
33214 {
33215   return CreateBulkEditorDialog (h, trim_sequence_fields, NULL, NULL, FALSE, ScrollToTrimSequenceItem, NULL);
33216 }
33217 
33218 
DefaultCheckTrimSequenceResults(BulkEditorRowPtr berp)33219 static void DefaultCheckTrimSequenceResults (BulkEditorRowPtr berp)
33220 {
33221   ValNodePtr vnp;
33222 
33223   if (berp == NULL) {
33224     return;
33225   }
33226   while (berp->object_list != NULL) {
33227     if (berp->subrows == NULL) {
33228       vnp = berp->object_list;
33229       if (vnp != NULL) {
33230         if (TrimShouldDelete (vnp->choice, vnp->data.ptrvalue, NULL)) {
33231           berp->selected = FALSE;
33232         } else {
33233           berp->selected = TRUE;
33234         }
33235       }
33236     } else {
33237       DefaultCheckTrimSequenceResults (berp->subrows);
33238       berp->selected = AllBulkEditorRowsSelected (berp->subrows);
33239     }
33240 
33241     berp++;
33242   }
33243 }
33244 
33245 
DefaultCheckTrimSequenceResultsDisplay(DialoG d)33246 extern void DefaultCheckTrimSequenceResultsDisplay (DialoG d)
33247 {
33248   BulkEditorDlgPtr    dlg;
33249   RecT                r;
33250 
33251   dlg = (BulkEditorDlgPtr) GetObjectExtra (d);
33252   if (dlg == NULL) return;
33253 
33254   DefaultCheckTrimSequenceResults (dlg->row_list);
33255 
33256   UpdateCheckStatus (dlg);
33257 
33258   ObjectRect (dlg->doc, &r);
33259   InvalRect (&r);
33260   Update ();
33261 }
33262 
33263 
33264 static BulkEdFieldData trim_sequence_end_fields[] = {
33265   { "Accession", NULL, NULL, GetTrimAccession, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33266   { "Remove from 5'", NULL, NULL, GetTrim5, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33267   { "Remove from 3'", NULL, NULL, GetTrim3, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33268   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
33269 
TrimSequenceEndDisplay(GrouP h)33270 extern DialoG TrimSequenceEndDisplay (GrouP h)
33271 {
33272   return CreateBulkEditorDialog (h, trim_sequence_end_fields, NULL, NULL, FALSE, ScrollToTrimSequenceItem, NULL);
33273 }
33274 
33275 
33276 
GetTaxName(Uint1 data_choice,Pointer data,Pointer metadata)33277 static Pointer GetTaxName (Uint1 data_choice, Pointer data, Pointer metadata)
33278 {
33279   TaxFixItemPtr t;
33280 
33281   if ((t = (TaxFixItemPtr) data) == NULL || t->orig_org == NULL || t->orig_org->taxname == NULL) {
33282     return NULL;
33283   } else {
33284     return StringSave (t->orig_org->taxname);
33285   }
33286 }
33287 
33288 
IsTaxNameBad(OrgRefPtr org)33289 extern Boolean IsTaxNameBad (OrgRefPtr org)
33290 {
33291   Boolean rval = TRUE;
33292   T3DataPtr        tdp;
33293   Taxon3RequestPtr t3rq;
33294   Taxon3ReplyPtr   t3ry;
33295   T3ReplyPtr       trp;
33296   ValNodePtr       val;
33297   T3StatusFlagsPtr tfp;
33298 
33299   if (org == NULL) {
33300     return TRUE;
33301   }
33302   t3rq = CreateTaxon3Request (0, NULL, org);
33303   if (t3rq != NULL) {
33304     t3ry = Tax3SynchronousQuery (t3rq);
33305     Taxon3RequestFree (t3rq);
33306     if (t3ry != NULL) {
33307       for (trp = t3ry->reply; trp != NULL; trp = trp->next) {
33308         if (trp->choice == T3Reply_data) {
33309           tdp = (T3DataPtr) trp->data.ptrvalue;
33310           if (tdp != NULL) {
33311             for (tfp = tdp->status; tfp != NULL; tfp = tfp->next) {
33312               if (StringICmp (tfp->property, "is_species_level") == 0) {
33313                 val = tfp->Value_value;
33314                 if (val != NULL && val->choice == Value_value_bool) {
33315                   if (val->data.intvalue != 0) {
33316                     rval = FALSE;
33317                   }
33318                 }
33319               }
33320             }
33321           }
33322         }
33323       }
33324     }
33325   }
33326   return rval;
33327 }
33328 
33329 
GetTaxNameCorrection(Uint1 data_choice,Pointer data,Pointer metadata)33330 static Pointer GetTaxNameCorrection (Uint1 data_choice, Pointer data, Pointer metadata)
33331 {
33332   TaxFixItemPtr t;
33333 
33334   if ((t = (TaxFixItemPtr) data) == NULL || t->suggested_fix == NULL) {
33335     return NULL;
33336   } else {
33337     return StringSave (t->suggested_fix);
33338   }
33339 }
33340 
33341 
TaxFixSetSuggestedFix(Pointer target,Pointer data)33342 static void TaxFixSetSuggestedFix (Pointer target, Pointer data)
33343 {
33344   TaxFixItemPtr  t;
33345 
33346   t = (TaxFixItemPtr) target;
33347   t->suggested_fix = MemFree (t->suggested_fix);
33348   t->suggested_fix = StringSave((CharPtr) data);
33349 }
33350 
33351 
ScrollToTaxFixItem(ValNodePtr vnp,Pointer userdata)33352 static void ScrollToTaxFixItem (ValNodePtr vnp, Pointer userdata)
33353 {
33354   TaxFixItemPtr t;
33355   ValNode vn;
33356 
33357   if (vnp != NULL && (t = (TaxFixItemPtr) vnp->data.ptrvalue) != NULL) {
33358     vn.choice = t->data_choice;
33359     vn.data.ptrvalue = t->data;
33360     vn.next = NULL;
33361     ScrollToDiscrepancyItem (&vn, NULL);
33362   }
33363 }
33364 
33365 
EditTaxFixItem(ValNodePtr vnp,Pointer userdata)33366 static void EditTaxFixItem(ValNodePtr vnp, Pointer userdata)
33367 {
33368   TaxFixItemPtr t;
33369   ValNode vn;
33370 
33371   if (vnp != NULL && (t = (TaxFixItemPtr) vnp->data.ptrvalue) != NULL) {
33372     vn.choice = t->data_choice;
33373     vn.data.ptrvalue = t->data;
33374     vn.next = NULL;
33375     EditDiscrepancyItem (&vn, NULL);
33376   }
33377 }
33378 
33379 
33380 static BulkEdFieldData taxfix_fields[] = {
33381   { "Tax Name", NULL, NULL, GetTaxName, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33382   { "Suggested Correction", TaxFixSetSuggestedFix, BulkSetSimpleTextString, GetTaxNameCorrection, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33383   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
33384 
TaxFixDisplay(GrouP h)33385 extern DialoG TaxFixDisplay (GrouP h)
33386 {
33387   return CreateBulkEditorDialog (h, taxfix_fields, NULL, NULL, TRUE, ScrollToTaxFixItem, EditTaxFixItem);
33388 }
33389 
33390 
GetSubSource(Uint1 data_choice,Pointer data,Uint1 subtype)33391 static CharPtr GetSubSource (Uint1 data_choice, Pointer data, Uint1 subtype)
33392 {
33393   SubSourcePtr ssp;
33394   BioSourcePtr biop;
33395 
33396   biop = GetBioSourceFromObject (data_choice, data);
33397   if (biop == NULL) return NULL;
33398 
33399   for (ssp = biop->subtype; ssp != NULL && ssp->subtype != subtype; ssp = ssp->next)
33400   {}
33401 
33402   if (ssp == NULL)
33403   {
33404     return NULL;
33405   }
33406   else
33407   {
33408     return StringSave (ssp->name);
33409   }
33410 }
33411 
33412 
GetCountry(Uint1 data_choice,Pointer data,Pointer metadata)33413 static Pointer GetCountry (Uint1 data_choice, Pointer data, Pointer metadata)
33414 {
33415   return GetSubSource (data_choice, data, SUBSRC_country);
33416 }
33417 
GetLatLon(Uint1 data_choice,Pointer data,Pointer metadata)33418 static Pointer GetLatLon (Uint1 data_choice, Pointer data, Pointer metadata)
33419 {
33420   return GetSubSource (data_choice, data, SUBSRC_lat_lon);
33421 }
33422 
33423 
GetLatLonCountryCorrection(Uint1 data_choice,Pointer data,Pointer metadata)33424 extern Pointer GetLatLonCountryCorrection (Uint1 data_choice, Pointer data, Pointer metadata)
33425 {
33426   SubSourcePtr ssp;
33427   BioSourcePtr biop;
33428   CharPtr      country = NULL, cp;
33429   FloatHi      lat, lon;
33430   Boolean      found_lat_lon = FALSE;
33431   CharPtr      msg = NULL;
33432   CharPtr      guess_fmt = "Lat_lon does not map to '%s', but may be in '%s'";
33433   CharPtr      guess;
33434 
33435   biop = GetBioSourceFromObject (data_choice, data);
33436   if (biop == NULL) return NULL;
33437 
33438   for (ssp = biop->subtype; ssp != NULL && (country == NULL || !found_lat_lon); ssp = ssp->next)
33439   {
33440     if (ssp->subtype == SUBSRC_country && !StringHasNoText (ssp->name))
33441     {
33442       country = StringSave (ssp->name);
33443     }
33444     else if (ssp->subtype == SUBSRC_lat_lon)
33445     {
33446       if (ParseLatLon (ssp->name, &lat, &lon))
33447       {
33448         found_lat_lon = TRUE;
33449       }
33450     }
33451   }
33452 
33453   cp = StringChr (country, ':');
33454   if (cp != NULL)
33455   {
33456     *cp = 0;
33457   }
33458 
33459   if (country == NULL && !found_lat_lon)
33460   {
33461     msg = StringSave ("Country and lat-lon not specified");
33462   }
33463   else if (country == NULL)
33464   {
33465     msg = StringSave ("Country not specified");
33466   }
33467   else if (!found_lat_lon)
33468   {
33469     msg = StringSave ("Lat-lon not specified.");
33470   }
33471   else if (!IsCountryInLatLonList (country))
33472   {
33473     msg = StringSave ("Country not in lat-lon list");
33474   }
33475   else if (TestLatLonForCountry (country, lat, lon))
33476   {
33477     msg = StringSave ("No conflict");
33478   }
33479   else if (TestLatLonForCountry (country, -lat, lon))
33480   {
33481     if (lat < 0.0) {
33482       msg = StringSave ("Latitude should be set to N (northern hemisphere)");
33483     } else {
33484       msg = StringSave ("Latitude should be set to S (southern hemisphere)");
33485     }
33486   } else if (TestLatLonForCountry (country, lat, -lon)) {
33487     if (lon < 0.0) {
33488       msg = StringSave ("Longitude should be set to E (eastern hemisphere)");
33489     } else {
33490       msg = StringSave ("Longitude should be set to W (western hemisphere)");
33491     }
33492   } else if (TestLatLonForCountry (country, lon, lat)) {
33493     msg = StringSave ("Latitude and longitude values appear to be exchanged");
33494   } else {
33495     guess = GuessCountryForLatLon (lat, lon);
33496     if (guess == NULL)
33497     {
33498       msg = StringSave ("Lat-lon does not map to country");
33499     }
33500     else
33501     {
33502       msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (guess_fmt) + StringLen (country) + StringLen (guess)));
33503       sprintf (msg, guess_fmt, country, guess);
33504     }
33505   }
33506   return msg;
33507 }
33508 
33509 static BulkEdFieldData latloncountry_fields[] = {
33510   { "Lat-lon", NULL, NULL, GetLatLon, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33511   { "Country", NULL, NULL, GetCountry, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33512   { "Suggested Correction", NULL, NULL, GetLatLonCountryCorrection, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33513   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
33514 
LatLonCountryResultsDisplay(GrouP h)33515 extern DialoG LatLonCountryResultsDisplay (GrouP h)
33516 {
33517   return CreateBulkEditorDialog (h, latloncountry_fields, NULL, NULL, FALSE, ScrollToDiscrepancyItem, EditDiscrepancyItem);
33518 }
33519 
33520 
GetCurrentSpecificHost(Uint1 data_choice,Pointer data,Pointer metadata)33521 static Pointer GetCurrentSpecificHost (Uint1 data_choice, Pointer data, Pointer metadata)
33522 {
33523   SpecificHostFixPtr s = (SpecificHostFixPtr) data;
33524 
33525   if (s == NULL || StringHasNoText (s->bad_specific_host))
33526   {
33527     return NULL;
33528   }
33529   else
33530   {
33531     return StringSave (s->bad_specific_host);
33532   }
33533 }
33534 
33535 
GetCorrectedSpecificHost(Uint1 data_choice,Pointer data,Pointer metadata)33536 static Pointer GetCorrectedSpecificHost (Uint1 data_choice, Pointer data, Pointer metadata)
33537 {
33538   SpecificHostFixPtr s = (SpecificHostFixPtr) data;
33539   CharPtr            fmt = "Unable to suggest correction for '%s'";
33540   CharPtr            rval = NULL;
33541 
33542   if (s == NULL)
33543   {
33544     return NULL;
33545   }
33546   else if (StringHasNoText (s->new_taxname))
33547   {
33548     if (StringHasNoText (s->old_taxname)) {
33549       rval = StringSave ("Unable to suggest correction");
33550     } else {
33551       rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (s->old_taxname)));
33552       sprintf (rval, fmt, s->old_taxname);
33553     }
33554   }
33555   else
33556   {
33557     rval = StringSave (s->bad_specific_host);
33558     FindReplaceString (&rval, s->old_taxname, s->new_taxname, TRUE, TRUE);
33559   }
33560   return rval;
33561 }
33562 
33563 
GetSpecificHostCorrectionCategory(Uint1 data_choice,Pointer data,Pointer metadata)33564 static Pointer GetSpecificHostCorrectionCategory  (Uint1 data_choice, Pointer data, Pointer metadata)
33565 {
33566   SpecificHostFixPtr s = (SpecificHostFixPtr) data;
33567   CharPtr            fmt = "Unable to suggest correction for '%s'";
33568   CharPtr            rval = NULL;
33569 
33570   if (s == NULL)
33571   {
33572     return NULL;
33573   }
33574   else
33575   {
33576     switch (s->fix_type) {
33577       case eSpecificHostFix_unrecognized:
33578         rval = StringSave ("Unrecognized");
33579         break;
33580       case eSpecificHostFix_spelling:
33581         rval = StringSave ("Spelling");
33582         break;
33583       case eSpecificHostFix_capitalization:
33584         rval = StringSave ("Capitalization");
33585         break;
33586       case eSpecificHostFix_truncation:
33587         rval = StringSave ("Truncation");
33588         break;
33589       case eSpecificHostFix_replacement:
33590         rval = StringSave ("Replacement");
33591         break;
33592       case eSpecificHostFix_ambiguous:
33593         rval = StringSave ("Ambiguous");
33594         break;
33595     }
33596   }
33597   return rval;
33598 }
33599 
33600 
ScrollToSpecificHostFix(ValNodePtr vnp,Pointer userdata)33601 static void ScrollToSpecificHostFix (ValNodePtr vnp, Pointer userdata)
33602 {
33603   SpecificHostFixPtr s;
33604 
33605   if (vnp == NULL || vnp->data.ptrvalue == NULL) return;
33606 
33607   s = (SpecificHostFixPtr) vnp->data.ptrvalue;
33608   ScrollToDiscrepancyItem (s->feat_or_desc, NULL);
33609 }
33610 
33611 
EditSpecificHostFix(ValNodePtr vnp,Pointer userdata)33612 static void EditSpecificHostFix (ValNodePtr vnp, Pointer userdata)
33613 {
33614   SpecificHostFixPtr s;
33615 
33616   if (vnp == NULL || vnp->data.ptrvalue == NULL) return;
33617 
33618   s = (SpecificHostFixPtr) vnp->data.ptrvalue;
33619   EditDiscrepancyItem (s->feat_or_desc, NULL);
33620 }
33621 
33622 
33623 static BulkEdFieldData specifichost_fields[] = {
33624   { "Current Specific-host", NULL, NULL, GetCurrentSpecificHost, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33625   { "Suggested Correction", NULL, NULL, GetCorrectedSpecificHost, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33626   { "Category", NULL, NULL, GetSpecificHostCorrectionCategory, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
33627   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
33628 
SpecificHostResultsDisplay(GrouP h)33629 extern DialoG SpecificHostResultsDisplay (GrouP h)
33630 {
33631   return CreateBulkEditorDialog (h, specifichost_fields, NULL, NULL, FALSE, ScrollToSpecificHostFix, EditSpecificHostFix);
33632 }
33633 
33634 
33635