1 /*   sequin7.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:  sequin7.c
27 *
28 * Author:  Jonathan Kans
29 *
30 * Version Creation Date:   1/3/98
31 *
32 * $Revision: 6.443 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date     Name        Description of modification
39 * -------  ----------  -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44 
45 #ifndef CODECENTER
46 static char *date_of_compilation = __DATE__;
47 static char *time_of_compilation = __TIME__;
48 #else
49 static char *date_of_compilation = "today";
50 static char *time_of_compilation = "now";
51 #endif
52 
53 #include "sequin.h"
54 #include <gather.h>
55 #include <edutil.h>
56 #include <cdrgn.h>
57 #include <subutil.h>
58 #include <tofasta.h>
59 #include <vsm.h>
60 #include <document.h>
61 #include <maputil.h>
62 #include <asn2gnbp.h>
63 #include <bspview.h>
64 #include <findrepl.h>
65 #include <toasn3.h>
66 #include <toporg.h>
67 #include <utilpub.h>
68 #include <salsap.h>
69 #include <salptool.h>
70 #include <salutil.h>
71 #include <saledit.h>
72 #include <explore.h>
73 #include <seqpanel.h>
74 #include <alignmgr2.h>
75 #include <alignval.h>
76 #include <actutils.h>
77 #include <tax3api.h>
78 #include <algo/blast/api/blast_options_api.h>
79 #include <algo/blast/api/blast_seqalign.h>
80 #include <algo/blast/api/blast_api.h>
81 #include <salstruc.h>
82 #include <sqnutils.h>
83 #include <valid.h> /* added for latloncountry conflict checking */
84 #define NLM_GENERATED_CODE_PROTO
85 #include <objmacro.h>
86 #include <macrodlg.h>
87 #include <macroapi.h>
88 
89 #define CONVERT_TO_JOIN  1
90 #define CONVERT_TO_ORDER 2
91 #define DO_NOT_CONVERT   3
92 
93 NLM_EXTERN SeqEntryPtr FastaToSeqEntryInternal
94 (
95  VoidPtr input,          /* input pointer (file or memory) */
96  Int4 type,              /* type of inquiry FASTA_MEM_IO or FASTA_FILE_IO */
97  CharPtr PNTR last_char, /* returned pointer to next FASTA sequence */
98  Boolean is_na,          /* type of sequence */
99  CharPtr PNTR errormsg,  /* error messge for debugging */
100  Boolean parseSeqId,     /* Parse SeqID from def line */
101  CharPtr special_symbol     /* Returns special symbol if no SeqEntry */
102  );
103 
SequinFastaToSeqEntryExEx(FILE * fp,Boolean is_na,CharPtr PNTR errormsg,Boolean parseSeqId,CharPtr special_symbol,BoolPtr chars_stripped)104 NLM_EXTERN SeqEntryPtr SequinFastaToSeqEntryExEx
105   (
106     FILE *fp,               /* file to get sequence from */
107     Boolean is_na,          /* type of sequence */
108     CharPtr PNTR errormsg,  /* error message for debugginq */
109     Boolean parseSeqId,     /* Parse SeqID from def line */
110     CharPtr special_symbol, /* Returns special symbol if no SeqEntry */
111     BoolPtr chars_stripped  /* set to TRUE if characters other than digits
112                              * were stripped from the FASTA sequence data */
113   )
114 {
115   BioseqPtr    bsp;
116   FileCache    fc;
117   Boolean      forceNuc = FALSE;
118   Boolean      forceProt = FALSE;
119   Pointer      dataptr;
120   Uint2        datatype;
121   Char         line [128];
122   Int4         pos;
123   SeqEntryPtr  sep = NULL;
124   CharPtr      str;
125 
126   if (errormsg != NULL) {
127     *errormsg = NULL;
128   }
129   if (special_symbol != NULL) {
130     *special_symbol = NULLB;
131   }
132   if (is_na) {
133     forceNuc = TRUE;
134   } else {
135     forceProt = TRUE;
136   }
137   dataptr = ReadAsnFastaOrFlatFileEx (fp, &datatype, NULL, forceNuc, forceProt, parseSeqId, FALSE, chars_stripped);
138   if (dataptr != NULL) {
139     if (datatype == OBJ_BIOSEQ) {
140       bsp = (BioseqPtr) dataptr;
141       sep = SeqMgrGetSeqEntryForData (bsp);
142       if (sep == NULL) {
143         sep = SeqEntryNew ();
144         if (sep != NULL) {
145           sep->choice = 1;
146           sep->data.ptrvalue = bsp;
147           SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
148         }
149       }
150     }
151   } else if (special_symbol != NULL) {
152     /* look ahead to see what character caused inability to interpret line */
153     FileCacheSetup (&fc, fp);
154     /* pos = FileCacheTell (&fc); */
155     str = FileCacheReadLine (&fc, line, sizeof (line), NULL);
156     if (str != NULL && StringDoesHaveText (str)) {
157       TrimSpacesAroundString (str);
158     }
159     *special_symbol = line [0];
160     /* seek to start of next line after one that could not be interpreted */
161     pos = FileCacheTell (&fc);
162     FileCacheSetup (&fc, fp);
163     FileCacheSeek (&fc, pos);
164     fseek (fp, pos, SEEK_SET);
165   }
166   /* return FastaToSeqEntryInternal((void *)fp, 2, NULL,is_na, errormsg, parseSeqId, special_symbol); */
167   return sep;
168 }
169 
SequinFastaToSeqEntryEx(FILE * fp,Boolean is_na,CharPtr PNTR errormsg,Boolean parseSeqId,CharPtr special_symbol)170 NLM_EXTERN SeqEntryPtr SequinFastaToSeqEntryEx
171   (
172     FILE *fp,               /* file to get sequence from */
173     Boolean is_na,          /* type of sequence */
174     CharPtr PNTR errormsg,  /* error message for debugginq */
175     Boolean parseSeqId,     /* Parse SeqID from def line */
176     CharPtr special_symbol  /* Returns special symbol if no SeqEntry */
177   )
178 {
179   return SequinFastaToSeqEntryExEx (fp, is_na, errormsg, parseSeqId, special_symbol, NULL);
180 }
181 
182 static FonT  titleFont = NULL;
183 
184 #ifndef WIN_MAC
CreateSqnInitialFormMenus(WindoW w)185 NLM_EXTERN MenU CreateSqnInitialFormMenus (WindoW w)
186 
187 {
188   BaseFormPtr   bfp;
189   MenU          m;
190 
191   bfp = (BaseFormPtr) GetObjectExtra (w);
192   if (bfp != NULL) {
193     m = PulldownMenu (w, "File");
194     AddAboutAndHelpMenuItems (m);
195     if (bfp->importform != NULL || bfp->exportform != NULL) {
196       if (bfp->importform != NULL) {
197         FormCommandItem (m, "Import...", bfp, VIB_MSG_IMPORT);
198       }
199       if (bfp->exportform != NULL) {
200         FormCommandItem (m, "Export...", bfp, VIB_MSG_EXPORT);
201       }
202       SeparatorItem (m);
203     }
204     FormCommandItem (m, "Quit", bfp, VIB_MSG_QUIT);
205     m = PulldownMenu (w, "Edit");
206     FormCommandItem (m, CUT_MENU_ITEM, bfp, VIB_MSG_CUT);
207     FormCommandItem (m, COPY_MENU_ITEM, bfp, VIB_MSG_COPY);
208     FormCommandItem (m, PASTE_MENU_ITEM, bfp, VIB_MSG_PASTE);
209     FormCommandItem (m, CLEAR_MENU_ITEM, bfp, VIB_MSG_DELETE);
210     return m;
211   }
212   return NULL;
213 }
214 
215 #endif
216 
DefaultMessageProc(ForM f,Int2 mssg)217 static void DefaultMessageProc (ForM f, Int2 mssg)
218 
219 {
220   StdEditorProcsPtr  sepp;
221 
222   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
223   if (sepp != NULL) {
224     if (sepp->handleMessages != NULL) {
225       sepp->handleMessages (f, mssg);
226     }
227   }
228 }
229 
230 typedef struct startupform {
231   FORM_MESSAGE_BLOCK
232 } StartupForm, PNTR StartupFormPtr;
233 
ChangeDestination(GrouP g)234 static void ChangeDestination (GrouP g)
235 
236 {
237   Char  str [64];
238   Int2  val;
239 
240   val = GetValue (g);
241   switch (val) {
242     case 1 :
243       RemoveAppProperty ("SequinUseEMBLStyle");
244       RemoveAppProperty ("SequinUseDDBJStyle");
245       if (GetAppParam ("SEQUIN", "PREFERENCES", "DATABASE", NULL, str, sizeof (str))) {
246         if (! StringHasNoText (str)) {
247           if (StringICmp (str, "GenBank") != 0) {
248             WriteSequinAppParam ("PREFERENCES", "DATABASE", "GenBank");
249           }
250         }
251       }
252       break;
253     case 2 :
254       SetAppProperty ("SequinUseEMBLStyle", (void *) 1024);
255       RemoveAppProperty ("SequinUseDDBJStyle");
256       WriteSequinAppParam ("PREFERENCES", "DATABASE", "EMBL");
257       break;
258     case 3 :
259       RemoveAppProperty ("SequinUseEMBLStyle");
260       SetAppProperty ("SequinUseDDBJStyle", (void *) 1024);
261       WriteSequinAppParam ("PREFERENCES", "DATABASE", "DDBJ");
262       break;
263     default :
264       break;
265   }
266   SetupBioseqPageList ();
267 }
268 
CenterString(RectPtr rptr,CharPtr text,FonT fnt,Int2 inc)269 static void CenterString (RectPtr rptr, CharPtr text, FonT fnt, Int2 inc)
270 
271 {
272   if (fnt != NULL) {
273     SelectFont (fnt);
274   }
275   rptr->bottom = rptr->top + LineHeight ();
276   DrawString (rptr, text, 'c', FALSE);
277   rptr->top = rptr->bottom + inc;
278 }
279 
DrawAbout(PaneL p)280 extern void DrawAbout (PaneL p)
281 
282 {
283   RecT  r;
284 
285 
286   if (titleFont == NULL) {
287 #ifdef WIN_MAC
288     titleFont = GetFont ("Geneva", 18, TRUE, TRUE, FALSE, "");
289 #endif
290 #ifdef WIN_MSWIN
291     titleFont = GetFont ("Arial", 24, TRUE, TRUE, FALSE, "");
292 #endif
293 #ifdef WIN_MOTIF
294     titleFont = GetFont ("Courier", 24, TRUE, TRUE, FALSE, "");
295 #endif
296   }
297 
298   ObjectRect (p, &r);
299   InsetRect (&r, 4, 4);
300   r.top += 5;
301   Blue ();
302   CenterString (&r, "Sequin", titleFont, 5);
303   CenterString (&r, SEQUIN_VERSION, programFont, 5);
304   CenterString (&r, SEQUIN_SERVICES, programFont, 10);
305   CenterString (&r, "National Center for Biotechnology Information", systemFont, 5);
306   CenterString (&r, "National Library of Medicine", systemFont, 5);
307   CenterString (&r, "National Institutes of Health", systemFont, 10);
308   CenterString (&r, "(301) 496-2475", systemFont, 5);
309   CenterString (&r, "info@ncbi.nlm.nih.gov", systemFont, 0);
310 }
311 
AboutBoxWidth(void)312 extern Int2 AboutBoxWidth (void)
313 
314 {
315   Int2     max;
316   CharPtr  ptr;
317   Char     sequinServices [60];
318   Char     sequinVersion [60];
319   Int2     wid;
320 
321 
322   if (titleFont == NULL) {
323 #ifdef WIN_MAC
324     titleFont = GetFont ("Geneva", 18, TRUE, TRUE, FALSE, "");
325 #endif
326 #ifdef WIN_MSWIN
327     titleFont = GetFont ("Arial", 24, TRUE, TRUE, FALSE, "");
328 #endif
329 #ifdef WIN_MOTIF
330     titleFont = GetFont ("Courier", 24, TRUE, TRUE, FALSE, "");
331 #endif
332   }
333 
334   sprintf (sequinVersion, "Sequin Application Version %s", SEQUIN_APPLICATION);
335   ptr = "Standard Release";
336 /*#ifdef USE_ENTREZ*/
337   if (useEntrez || useBlast) {
338     ptr = "Network Aware";
339   }
340 /*#endif*/
341 /*#ifdef INTERNAL_NCBI_SEQUIN*/
342   if (indexerVersion) {
343     ptr = "Indexer Services";
344   }
345 /*#endif*/
346   if (genomeCenter != NULL) {
347     ptr = "Genome Center";
348   }
349   sprintf (sequinServices, "%s [%s]", ptr, date_of_compilation);
350 
351   SelectFont (titleFont);
352   max = StringWidth ("Sequin");
353   SelectFont (programFont);
354   wid = StringWidth (sequinVersion);
355   if (wid > max) {
356     max = wid;
357   }
358   wid = StringWidth (sequinServices);
359   if (wid > max) {
360     max = wid;
361   }
362   SelectFont (systemFont);
363   wid = StringWidth ("National Center for Biotechnology Information");
364   if (wid > max) {
365     max = wid;
366   }
367   max += 2 * stdCharWidth + 2;
368   return max;
369 }
370 
AboutBoxHeight(void)371 extern Int2 AboutBoxHeight (void)
372 
373 {
374   Int2  hgt;
375 
376   if (titleFont == NULL) {
377 #ifdef WIN_MAC
378     titleFont = GetFont ("Geneva", 18, TRUE, TRUE, FALSE, "");
379 #endif
380 #ifdef WIN_MSWIN
381     titleFont = GetFont ("Arial", 24, TRUE, TRUE, FALSE, "");
382 #endif
383 #ifdef WIN_MOTIF
384     titleFont = GetFont ("Courier", 24, TRUE, TRUE, FALSE, "");
385 #endif
386   }
387 
388   SelectFont (titleFont);
389   hgt = LineHeight () + 5;
390   SelectFont (programFont);
391   hgt += 2 * LineHeight () + 15;
392   SelectFont (systemFont);
393   hgt += 5 * LineHeight () + 25;
394   hgt += 18;
395   return hgt;
396 }
397 
DoNetConf(ButtoN b)398 static void DoNetConf (ButtoN b)
399 
400 {
401   NetConfigureProc ((IteM) b);
402 }
403 
CreateStartupForm(Int2 left,Int2 top,CharPtr title,BtnActnProc startFa2htgs,BtnActnProc startPhrap,BtnActnProc buildContig,BtnActnProc startNew,BtnActnProc readExisting,BtnActnProc fetchFromNet,BtnActnProc showHelp,BtnActnProc createSubmissionTemplate,BtnActnProc quitProgram,WndActnProc activateForm)404 extern ForM CreateStartupForm (Int2 left, Int2 top, CharPtr title,
405                                BtnActnProc startFa2htgs,
406                                BtnActnProc startPhrap,
407                                BtnActnProc buildContig,
408                                BtnActnProc startNew,
409                                BtnActnProc readExisting,
410                                BtnActnProc fetchFromNet,
411                                BtnActnProc showHelp,
412                                BtnActnProc createSubmissionTemplate,
413                                BtnActnProc quitProgram,
414                                WndActnProc activateForm)
415 
416 {
417   ButtoN          b;
418   GrouP           c;
419   GrouP           d;
420   GrouP           k;
421   PaneL           p;
422   StartupFormPtr  sfp;
423   Char            str [32];
424   WindoW          w;
425 #ifndef WIN_MAC
426   MenU            m;
427 #endif
428 
429   w = NULL;
430   sfp = MemNew (sizeof (StartupForm));
431   if (sfp != NULL) {
432     w = FixedWindow (left, top, -10, -10, title, NULL);
433     SetObjectExtra (w, sfp, StdCleanupFormProc);
434     sfp->form = (ForM) w;
435     sfp->formmessage = DefaultMessageProc;
436 
437 #ifndef WIN_MAC
438     m = PulldownMenu (w, "Misc");
439     CommandItem (m, "Net Configure...", NetConfigureProc);
440     if (useEntrez) {
441       /*
442       SeparatorItem (m);
443       CommandItem (m, "Entrez Query...", EntrezQueryProc);
444       SeparatorItem (m);
445       CommandItem (m, "Entrez2 Query...", Entrez2QueryProc);
446       */
447       if (extraServices) {
448         SeparatorItem (m);
449         CommandItem (m, "Process FASTA Nucleotide Updates", ParseInNucUpdates);
450       }
451     }
452     if (useDesktop) {
453       SeparatorItem (m);
454       VSMAddToMenu (m, VSM_DESKTOP);
455     }
456 #endif
457 
458     p = SimplePanel (w, AboutBoxWidth (), AboutBoxHeight (), DrawAbout);
459 
460     k = HiddenGroup (w, 4, 0, NULL);
461     SetGroupSpacing (k, 3, 10);
462     StaticPrompt (k, "Database for submission", 0, stdLineHeight, programFont, 'l');
463     d = HiddenGroup (k, 4, 0, ChangeDestination);
464     RadioButton (d, "GenBank");
465     RadioButton (d, "EMBL");
466     if (GetAppParam ("SEQUIN", "PREFERENCES", "DATABASE", NULL, str, sizeof (str))) {
467       if (StringICmp (str, "GenBank") == 0) {
468         SetValue (d, 1);
469       } else if (StringICmp (str, "EMBL") == 0) {
470         SetValue (d, 2);
471       } else {
472         SetValue (d, 1);
473       }
474     } else {
475       SetValue (d, 1);
476     }
477     ChangeDestination (d);
478 
479     c = HiddenGroup (w, 1, 0, NULL);
480     SetGroupSpacing (c, 10, 5);
481 
482     if (startFa2htgs != NULL) {
483       b = PushButton (c, "New FA2HTGS Submission", startFa2htgs);
484       SetObjectExtra (b, sfp, NULL);
485     }
486     if (startPhrap != NULL) {
487       b = PushButton (c, "New PHRAP Submission", startPhrap);
488       SetObjectExtra (b, sfp, NULL);
489     }
490     if (buildContig != NULL) {
491       b = PushButton (c, "Read CONTIG Instructions", buildContig);
492       SetObjectExtra (b, sfp, NULL);
493     }
494     b = PushButton (c, "Start New Submission", startNew);
495     SetObjectExtra (b, sfp, NULL);
496     b = PushButton (c, "Read Existing Record", readExisting);
497     SetObjectExtra (b, sfp, NULL);
498     if (fetchFromNet != NULL) {
499       b = PushButton (c, "Download From Entrez", fetchFromNet);
500       SetObjectExtra (b, sfp, NULL);
501     } else {
502       b = PushButton (c, "Network Configure", DoNetConf);
503       SetObjectExtra (b, sfp, NULL);
504     }
505     b = PushButton (c, "Show Help", showHelp);
506     SetObjectExtra (b, sfp, NULL);
507     if (createSubmissionTemplate != NULL)
508     {
509       b = PushButton (c, "Submission Template", createSubmissionTemplate);
510       SetObjectExtra (b, sfp, NULL);
511     }
512     b = PushButton (c, "Quit Program", quitProgram);
513     SetObjectExtra (b, sfp, NULL);
514 
515     AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) c, (HANDLE) k, NULL);
516 
517     RealizeWindow (w);
518 
519     if (activateForm != NULL) {
520       SetActivate (w, activateForm);
521     }
522   }
523   return (ForM) w;
524 }
525 
526 
527 typedef struct formatform {
528   FORM_MESSAGE_BLOCK
529 
530   GrouP           package;
531   GrouP           format;
532   GrouP           submType;
533   ButtoN          alignmentButton;
534   ButtoN          originalButton;
535   ButtoN          tpaButton;
536   TexT            numseqs;
537 
538   Int2            restoreFormatTo;
539 } FormatForm, PNTR FormatFormPtr;
540 
541 static Boolean allowGenomicPlusCDNA = FALSE;
542 
FormatBlockPtrToFormatForm(ForM f,Pointer data)543 static void FormatBlockPtrToFormatForm (ForM f, Pointer data)
544 
545 {
546   FormatBlockPtr  fbp;
547   FormatFormPtr   ffp;
548   Char            str [32];
549 
550   ffp = (FormatFormPtr) GetObjectExtra (f);
551   fbp = (FormatBlockPtr) data;
552   if (ffp == NULL) return;
553   if (fbp != NULL) {
554     if (fbp->seqPackage > 0 && fbp->seqPackage <= NUM_SEQ_PKG) {
555       if ((! allowGenomicPlusCDNA) && fbp->seqPackage >= SEQ_PKG_GENOMICCDNA) {
556         SafeSetValue (ffp->package, fbp->seqPackage - 1);
557       } else {
558         SafeSetValue (ffp->package, fbp->seqPackage);
559       }
560       if (fbp->seqPackage <= SEQ_PKG_GENOMICCDNA || fbp->seqPackage == SEQ_PKG_GENBANK || fbp->seqPackage == SEQ_PKG_TSA) {
561         SafeDisable (ffp->alignmentButton);
562       } else {
563         SafeEnable (ffp->alignmentButton);
564       }
565     } else {
566       SafeSetValue (ffp->package, SEQ_PKG_SINGLE);
567       SafeDisable (ffp->alignmentButton);
568     }
569     if (fbp->seqFormat > 0 && fbp->seqFormat <= NUM_SEQ_FMT) {
570       SafeSetValue (ffp->format, fbp->seqFormat);
571     } else {
572       SafeSetValue (ffp->format, SEQ_FMT_FASTA);
573     }
574     if (fbp->numSeqs > 0) {
575       IntToStr (fbp->numSeqs, str, 0, sizeof (str));
576       SafeSetTitle (ffp->numseqs, str);
577     } else {
578       SafeSetTitle (ffp->numseqs, "");
579     }
580   } else {
581     SafeSetValue (ffp->package, SEQ_PKG_SINGLE);
582     SafeDisable (ffp->alignmentButton);
583     SafeSetValue (ffp->format, SEQ_FMT_FASTA);
584     SafeSetTitle (ffp->numseqs, "");
585     ffp->restoreFormatTo = SEQ_FMT_FASTA;
586   }
587 }
588 
FormatFormToFormatBlockPtr(ForM f)589 static Pointer FormatFormToFormatBlockPtr (ForM f)
590 
591 {
592   FormatBlockPtr  fbp;
593   FormatFormPtr   ffp;
594   Char            str [32];
595   Int2            val;
596 
597   fbp = NULL;
598   ffp = (FormatFormPtr) GetObjectExtra (f);
599   if (ffp == NULL) return NULL;
600   fbp = (FormatBlockPtr) MemNew (sizeof (FormatBlock));
601   if (fbp == NULL) return NULL;
602   fbp->seqPackage = GetValue (ffp->package);
603   if ((! allowGenomicPlusCDNA) && fbp->seqPackage >= SEQ_PKG_GENOMICCDNA) {
604     (fbp->seqPackage)++;
605   }
606   fbp->seqFormat = GetValue (ffp->format);
607   fbp->submType = GetValue (ffp->submType);
608   GetTitle (ffp->numseqs, str, sizeof (str));
609   if (StrToInt (str, &val) && val > 0) {
610     fbp->numSeqs = val;
611   } else {
612     fbp->numSeqs = 0;
613   }
614   return (Pointer) fbp;
615 }
616 
EnableOrDisableFormats(GrouP g)617 static void EnableOrDisableFormats (GrouP g)
618 
619 {
620   FormatFormPtr  ffp;
621   Int2           val;
622 
623   ffp = (FormatFormPtr) GetObjectExtra (g);
624   if (ffp == NULL) return;
625   val = GetValue (g);
626   if ((! allowGenomicPlusCDNA) && val >= SEQ_PKG_GENOMICCDNA) {
627     val++;
628   }
629   if (val <= SEQ_PKG_GENOMICCDNA || val == SEQ_PKG_GENBANK || val == SEQ_PKG_TSA) {
630     if (Enabled (ffp->alignmentButton)) {
631       ffp->restoreFormatTo = GetValue (ffp->format);
632     }
633     SafeSetValue (ffp->format, SEQ_FMT_FASTA);
634     SafeDisable (ffp->alignmentButton);
635   } else {
636     if (! Enabled (ffp->alignmentButton)) {
637       SafeSetValue (ffp->format, ffp->restoreFormatTo);
638     }
639     SafeEnable (ffp->alignmentButton);
640   }
641 }
642 
ExportTemplateMenu(ForM f,CharPtr filename)643 static Boolean ExportTemplateMenu (ForM f, CharPtr filename)
644 {
645   WindoW                w;
646   GrouP                 h, g1, g2, c;
647   ButtoN                b;
648   DialoG                org_dlg;
649   TexT                  comment_txt;
650   ModalAcceptCancelData acd;
651   SeqEntryPtr           sep;
652   BioseqSetPtr          bssp;
653   BioSourcePtr          biop;
654   SeqDescrPtr           sdp;
655   CharPtr               org_name;
656   Boolean               done;
657 
658   if (ANS_NO == Message (MSG_YN, "Do you want to add an organism name and comment before saving the template?"))
659   {
660     bssp = BioseqSetNew ();
661     bssp->_class = BioseqseqSet_class_not_set;
662     sep = SeqEntryNew ();
663     sep->choice = 2;
664     sep->data.ptrvalue = bssp;
665 
666     done = ExportSubmitterBlockTemplate (sep, NULL);
667     if (!done)
668     {
669       /* if done were TRUE, sep would have been freed as part of the new SeqSubmit */
670       SeqEntryFree (sep);
671     }
672     return done;
673   }
674 
675   w = MovableModalWindow (-20, -13, -10, -10, "Submission Template", NULL);
676   h = HiddenGroup(w, -1, 0, NULL);
677   SetGroupSpacing (h, 10, 10);
678 
679   g1 = NormalGroup (h, 1, 0, "Organism Name", programFont, NULL);
680   org_dlg = OrganismSelectionDialog (g1, "");
681   g2 = NormalGroup (h, 2, 0, "Comment", programFont, NULL);
682   comment_txt = DialogText (g2, "", 30, NULL);
683 
684   c = HiddenGroup (h, 2, 0, NULL);
685   b = PushButton (c, "Accept", ModalAcceptButton);
686   SetObjectExtra (b, &acd, NULL);
687   b = PushButton (c, "Cancel", ModalCancelButton);
688   SetObjectExtra (b, &acd, NULL);
689 
690   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2,
691                               (HANDLE) c, (HANDLE) NULL);
692 
693   Show (w);
694   Select (w);
695   done = FALSE;
696   while (!done)
697   {
698     acd.accepted = FALSE;
699     acd.cancelled = FALSE;
700     while (!acd.accepted && ! acd.cancelled)
701     {
702       ProcessExternalEvent ();
703       Update ();
704     }
705     ProcessAnEvent ();
706 
707     if (acd.cancelled)
708     {
709       done = TRUE;
710     }
711     else
712     {
713       bssp = BioseqSetNew ();
714       sep = SeqEntryNew ();
715       sep->choice = 2;
716       sep->data.ptrvalue = bssp;
717       bssp->_class = BioseqseqSet_class_not_set;
718 
719       org_name = DialogToPointer (org_dlg);
720       if (!StringHasNoText (org_name))
721       {
722         biop = BioSourceNew ();
723         biop->org = OrgRefNew ();
724         biop->org->taxname = org_name;
725         sdp = CreateNewDescriptor (sep, Seq_descr_source);
726         sdp->data.ptrvalue = biop;
727       }
728       else
729       {
730         org_name = MemFree (org_name);
731       }
732 
733       sdp = NULL;
734       if (!TextHasNoText (comment_txt))
735       {
736         sdp = CreateNewDescriptor (sep, Seq_descr_comment);
737         sdp->data.ptrvalue = SaveStringFromText (comment_txt);
738       }
739 
740       done = ExportSubmitterBlockTemplate (sep, sdp);
741       if (!done)
742       {
743         /* if done were TRUE, sep would have been freed as part of the new SeqSubmit */
744         SeqEntryFree (sep);
745       }
746     }
747   }
748   Remove (w);
749   return acd.accepted;
750 }
751 
FormatFormMessage(ForM f,Int2 mssg)752 static void FormatFormMessage (ForM f, Int2 mssg)
753 
754 {
755   switch (mssg) {
756     case VIB_MSG_EXPORT :
757       ExportTemplateMenu (NULL, NULL);
758       break;
759     case VIB_MSG_CUT :
760       StdCutTextProc (NULL);
761       break;
762     case VIB_MSG_COPY :
763       StdCopyTextProc (NULL);
764       break;
765     case VIB_MSG_PASTE :
766       StdPasteTextProc (NULL);
767       break;
768     case VIB_MSG_DELETE :
769       StdDeleteTextProc (NULL);
770       break;
771     default :
772       DefaultMessageProc (f, mssg);
773       break;
774   }
775 }
776 
CreateFormatFormMenus(WindoW w)777 static void CreateFormatFormMenus (WindoW w)
778 {
779 #ifndef WIN_MAC
780   BaseFormPtr   bfp;
781   MenU          m;
782 
783   bfp = (BaseFormPtr) GetObjectExtra (w);
784   if (bfp != NULL) {
785     m = PulldownMenu (w, "File");
786     FormCommandItem (m, "Export Template...", bfp, VIB_MSG_EXPORT);
787   }
788 #endif
789 }
790 
InitFormatFormActivate(WindoW w)791 static void InitFormatFormActivate (WindoW w)
792 
793 {
794   IteM           exportItm;
795   FormatFormPtr  ffp;
796 
797   ffp = (FormatFormPtr) GetObjectExtra (w);
798   if (ffp != NULL) {
799     if (ffp->activate != NULL) {
800       ffp->activate (w);
801     }
802     exportItm = FindFormMenuItem ((BaseFormPtr) ffp, VIB_MSG_EXPORT);
803     SafeSetTitle (exportItm, "Export Template...");
804     SafeEnable (exportItm);
805   }
806 }
807 
CreateFormatForm(Int2 left,Int2 top,CharPtr title,BtnActnProc goToNext,BtnActnProc goBack,WndActnProc activateForm)808 extern ForM CreateFormatForm (Int2 left, Int2 top, CharPtr title,
809                               BtnActnProc goToNext,
810                               BtnActnProc goBack,
811                               WndActnProc activateForm)
812 
813 {
814   ButtoN         b;
815   GrouP          c;
816   FormatFormPtr  ffp;
817   GrouP          g1, g2, g3;
818   GrouP          h;
819   GrouP          wizards = NULL;
820   PrompT         ppt;
821   Char           str [32];
822   WindoW         w;
823 
824   w = NULL;
825   ffp = MemNew (sizeof (FormatForm));
826   if (ffp != NULL) {
827     w = FixedWindow (left, top, -10, -10, title, NULL);
828     SetObjectExtra (w, ffp, StdCleanupFormProc);
829     ffp->form = (ForM) w;
830     ffp->toform = FormatBlockPtrToFormatForm;
831     ffp->fromform = FormatFormToFormatBlockPtr;
832     ffp->formmessage = FormatFormMessage;
833     ffp->exportform = ExportTemplateMenu;
834 
835     SetGroupSpacing (w, 10, 10);
836 
837     CreateFormatFormMenus (w);
838 
839     h = HiddenGroup (w, -1, 0, NULL);
840     SetGroupSpacing (h, 3, 10);
841 
842     g1 = HiddenGroup (h, 2, 0, NULL);
843 
844     allowGenomicPlusCDNA = FALSE;
845     if (GetAppParam ("SEQUIN", "SETTINGS", "GENOMICPLUSTRANSCRIPTS", NULL, str, sizeof (str))) {
846       if (StringICmp (str, "TRUE") == 0) {
847         allowGenomicPlusCDNA = TRUE;
848       }
849     }
850 
851 
852     ppt = StaticPrompt (g1, "Submission type", 0, 0, programFont, 'l');
853     ffp->package = HiddenGroup (g1, 2, 0, EnableOrDisableFormats);
854     SetObjectExtra (ffp->package, ffp, NULL);
855     RadioButton (ffp->package, "Single Sequence");
856     RadioButton (ffp->package, "Gapped Sequence");
857     if (allowGenomicPlusCDNA) {
858       RadioButton (ffp->package, "Genomic + Transcripts");
859     }
860     RadioButton (ffp->package, "Population Study");
861     RadioButton (ffp->package, "Phylogenetic Study");
862     RadioButton (ffp->package, "Mutation Study");
863     RadioButton (ffp->package, "Environmental Samples");
864     RadioButton (ffp->package, "Batch Submission");
865     RadioButton (ffp->package, "Transcriptome Shotgun Assembly");
866     SetValue (ffp->package, SEQ_PKG_SINGLE);
867     AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) ffp->package, NULL);
868 
869     g2 = HiddenGroup (h, 2, 0, NULL);
870 
871     ppt = StaticPrompt (g2, "Sequence data format", 0, 0, programFont, 'l');
872     ffp->format = HiddenGroup (g2, -1, 0, NULL);
873     SetObjectExtra (ffp->format, ffp, NULL);
874     RadioButton (ffp->format, "FASTA (no alignment)");
875     ffp->alignmentButton = RadioButton (ffp->format, "Alignment (FASTA+GAP, NEXUS, PHYLIP, etc.)");
876     Disable (ffp->alignmentButton);
877     SetValue (ffp->format, SEQ_FMT_FASTA);
878     ffp->restoreFormatTo = SEQ_FMT_FASTA;
879     AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) ffp->format, NULL);
880 
881     g3 = HiddenGroup (h, 2, 0, NULL);
882 
883     ppt = StaticPrompt (g3, "Submission category", 0, 0, programFont, 'l');
884     ffp->submType = HiddenGroup (g3, -1, 0, NULL);
885     SetObjectExtra (ffp->submType, ffp, NULL);
886     ffp->originalButton = RadioButton (ffp->submType, "Original Submission");
887     ffp->tpaButton = RadioButton (ffp->submType, "Third Party Annotation");
888     SetValue (ffp->submType, SEQ_ORIG_SUBMISSION);
889     AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) ffp->submType, NULL);
890 
891     c = HiddenGroup (w, 4, 0, NULL);
892     SetGroupSpacing (c, 10, 2);
893     b = PushButton (c, " << Prev Form ", goBack);
894     SetObjectExtra (b, ffp, NULL);
895     b = PushButton (c, " Next Form >> ", goToNext);
896     SetObjectExtra (b, ffp, NULL);
897 
898     AlignObjects (ALIGN_LEFT, (HANDLE) g1, (HANDLE) g2, (HANDLE) g3, (HANDLE) wizards, NULL);
899     AlignObjects (ALIGN_CENTER, (HANDLE) h, (HANDLE) c, NULL);
900 
901     RealizeWindow (w);
902 
903     ffp->activate = activateForm;
904     SetActivate (w, InitFormatFormActivate);
905   }
906   return (ForM) w;
907 }
908 
SequinBlockFree(SequinBlockPtr sbp)909 extern SequinBlockPtr SequinBlockFree (SequinBlockPtr sbp)
910 
911 {
912   if (sbp != NULL) {
913     AuthorFree (sbp->contactperson);
914     AuthListFree (sbp->citsubauthors);
915     AffilFree (sbp->citsubaffil);
916     MemFree (sbp->citsubtitle);
917     DateFree (sbp->releasedate);
918     SeqDescrFree (sbp->descriptors);
919   }
920   return NULL;
921 }
922 
ExciseString(CharPtr str,CharPtr from,CharPtr to)923 extern void ExciseString (CharPtr str, CharPtr from, CharPtr to)
924 
925 {
926   Char     ch;
927   CharPtr  ptrf;
928   CharPtr  ptrt;
929 
930   if (str == NULL || from == NULL || to == NULL) return;
931   ptrf = StringISearch (str, from);
932   if (ptrf == NULL) return;
933   ptrt = StringISearch (ptrf, to);
934   if (ptrt == NULL) return;
935   ptrt += StringLen (to);
936   ch = *ptrt;
937   while (ch != '\0') {
938     *ptrf = ch;
939     ptrf++;
940     ptrt++;
941     ch = *ptrt;
942   }
943   *ptrf = '\0';
944 }
945 
946 typedef struct geneextendlist {
947   GeneRefPtr  grp;
948   SeqLocPtr   slp;
949   ObjMgrPtr   omp;
950   Boolean     rsult;
951   Char        label [41];
952 } GeneExtendList, PNTR GeneExtendPtr;
953 
GeneExtendFunc(GatherContextPtr gcp)954 static Boolean GeneExtendFunc (GatherContextPtr gcp)
955 
956 {
957   BioseqPtr      bsp;
958   GeneExtendPtr  gep;
959   GeneRefPtr     grp;
960   Boolean        hasNulls;
961   ObjMgrTypePtr  omtp;
962   SeqFeatPtr     sfp;
963   SeqLocPtr      slp;
964   Char           thislabel [41];
965 
966   if (gcp == NULL) return TRUE;
967 
968   gep = (GeneExtendPtr) gcp->userdata;
969   if (gep == NULL ) return TRUE;
970 
971   thislabel [0] = '\0';
972 
973   if (gcp->thistype == OBJ_SEQFEAT) {
974     sfp = (SeqFeatPtr) gcp->thisitem;
975     if (sfp != NULL && sfp->data.choice == SEQFEAT_GENE && sfp->data.value.ptrvalue != NULL) {
976       grp = (GeneRefPtr) sfp->data.value.ptrvalue;
977       omtp = ObjMgrTypeFind (gep->omp, gcp->thistype, NULL, NULL);
978       if (omtp == NULL) {
979         return TRUE;
980       }
981       if (omtp->labelfunc != NULL) {
982         (*(omtp->labelfunc)) (gcp->thisitem, thislabel, 40, OM_LABEL_CONTENT);
983       }
984       if (thislabel [0] != '\0') {
985         if (StringICmp (thislabel, gep->label) == 0) {
986           if (SeqLocCompare (gep->slp, sfp->location) != SLC_NO_MATCH) {
987             bsp = GetBioseqGivenSeqLoc (sfp->location, gcp->entityID);
988             if (bsp != NULL) {
989               slp = SeqLocMerge (bsp, sfp->location, gep->slp, TRUE, FALSE, FALSE);
990               if (slp != NULL) {
991                 sfp->location = SeqLocFree (sfp->location);
992                 sfp->location = slp;
993                 if (bsp->repr == Seq_repr_seg) {
994                   slp = SegLocToPartsEx (bsp, sfp->location, TRUE);
995                   sfp->location = SeqLocFree (sfp->location);
996                   sfp->location = slp;
997                   hasNulls = LocationHasNullsBetween (sfp->location);
998                   sfp->partial = (sfp->partial || hasNulls);
999                 }
1000                 FreeAllFuzz (slp);
1001                 gep->rsult = TRUE;
1002               }
1003             }
1004           }
1005           return FALSE;
1006         }
1007       }
1008     }
1009   }
1010   return TRUE;
1011 }
1012 
ExtendGene(GeneRefPtr grp,SeqEntryPtr nsep,SeqLocPtr slp)1013 extern Boolean ExtendGene (GeneRefPtr grp, SeqEntryPtr nsep, SeqLocPtr slp)
1014 
1015 {
1016   GeneExtendList  gel;
1017   GatherScope     gs;
1018   ObjMgrTypePtr   omtp;
1019   SeqFeatPtr      sfp;
1020 
1021   if (grp == NULL || nsep == NULL || slp == NULL) return FALSE;
1022   gel.grp = grp;
1023   gel.slp = slp;
1024   gel.omp = ObjMgrGet ();
1025   gel.label [0] = '\0';
1026   gel.rsult = FALSE;
1027   omtp = ObjMgrTypeFind (gel.omp, OBJ_SEQFEAT, NULL, NULL);
1028   if (omtp != NULL && omtp->labelfunc != NULL) {
1029     sfp = SeqFeatNew ();
1030     if (sfp != NULL) {
1031       sfp->data.choice = SEQFEAT_GENE;
1032       sfp->data.value.ptrvalue = (Pointer) grp;
1033       (*(omtp->labelfunc)) ((Pointer) sfp, gel.label, 40, OM_LABEL_CONTENT);
1034       sfp->data.value.ptrvalue = NULL;
1035       SeqFeatFree (sfp);
1036     }
1037   }
1038   MemSet ((Pointer)(&gs), 0, sizeof (GatherScope));
1039   gs.seglevels = 1;
1040   gs.get_feats_location = TRUE;
1041   MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
1042   gs.ignore[OBJ_BIOSEQ] = FALSE;
1043   gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
1044   gs.ignore[OBJ_SEQFEAT] = FALSE;
1045   gs.ignore[OBJ_SEQANNOT] = FALSE;
1046   GatherSeqEntry (nsep, (Pointer) &gel, GeneExtendFunc, &gs);
1047   return gel.rsult;
1048 }
1049 
1050 /*=====================================================================*/
1051 /*                                                                     */
1052 /* CreateGeneAndProtFeats() -                                          */
1053 /*                                                                     */
1054 /*=====================================================================*/
1055 
CreateGeneAndProtFeats(SeqEntryPtr nsep,SeqEntryPtr psep,SeqLocPtr slp,CdRegionPtr crp,CharPtr title,CharPtr best,size_t maxsize,CharPtr PNTR ttl)1056 static void CreateGeneAndProtFeats (SeqEntryPtr nsep, SeqEntryPtr psep,
1057                                     SeqLocPtr slp, CdRegionPtr crp, CharPtr title,
1058                                     CharPtr best, size_t maxsize, CharPtr PNTR ttl)
1059 
1060 {
1061   BioseqPtr   nbsp;
1062   BioseqPtr   pbsp;
1063   SeqFeatPtr  sfp;
1064   ProtRefPtr  prp = NULL;
1065   Boolean     partial5, partial3;
1066 
1067   if (nsep != NULL && psep != NULL && slp != NULL && crp != NULL && title != NULL) {
1068     if (best != NULL) {
1069       best [0] = '\0';
1070     }
1071     if (IS_Bioseq (nsep) && IS_Bioseq (psep)) {
1072       nbsp = (BioseqPtr) nsep->data.ptrvalue;
1073       pbsp = (BioseqPtr) psep->data.ptrvalue;
1074       if (nbsp != NULL && pbsp != NULL) {
1075 
1076         AddGeneFeatureFromTitle (nsep, title, slp);
1077 
1078         sfp = AddProteinFeatureFromDefline (psep, title);
1079         if (sfp != NULL && sfp->data.choice == SEQFEAT_PROT) {
1080           prp = sfp->data.value.ptrvalue;
1081           CheckSeqLocForPartial (slp, &partial5, &partial3);
1082           SetSeqLocPartial (sfp->location, partial5, partial3);
1083           sfp->partial = partial5 | partial3;
1084         }
1085 
1086         if (prp != NULL && best != NULL)
1087         {
1088           if (prp->name != NULL && !StringHasNoText (prp->name->data.ptrvalue))
1089           {
1090 	          StringNCpy_0 (best, prp->name->data.ptrvalue, maxsize);
1091           }
1092           else if (!StringHasNoText (prp->desc))
1093           {
1094 	          StringNCpy_0 (best, prp->desc, maxsize);
1095           }
1096         }
1097 
1098         AddCodingRegionFieldsFromProteinTitle (crp, title, ttl);
1099       }
1100     }
1101   }
1102 }
1103 
1104 static Boolean  intBoxUp;
1105 static Boolean  intBoxRsult;
1106 
AcceptAskProc(ButtoN b)1107 static void AcceptAskProc (ButtoN b)
1108 
1109 {
1110   intBoxRsult = TRUE;
1111   intBoxUp = FALSE;
1112 }
1113 
CancelAskProc(ButtoN b)1114 static void CancelAskProc (ButtoN b)
1115 
1116 {
1117   intBoxRsult = FALSE;
1118   intBoxUp = FALSE;
1119 }
1120 
AskForInterval(SeqEntryPtr sep,BioseqPtr nuc,BioseqPtr prot)1121 static SeqLocPtr AskForInterval (SeqEntryPtr sep, BioseqPtr nuc, BioseqPtr prot)
1122 
1123 {
1124   GrouP       c;
1125   DialoG      d;
1126   GrouP       g;
1127   GrouP       m;
1128   SeqIdPtr    sip;
1129   SeqLocPtr   slp;
1130   Char        str [128];
1131   ValNodePtr  vnp;
1132   WindoW      w;
1133 
1134   slp = NULL;
1135   if (sep == NULL || nuc == NULL || prot == NULL) return NULL;
1136 
1137   if (GetAppParam ("SEQUIN", "PREFERENCES", "ASKIFSUGGESTFAILED", NULL, str, sizeof (str))) {
1138     if (StringICmp (str, "FALSE") == 0) {
1139       sip = SeqIdFindWorst (prot->id);
1140       SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
1141       Message (MSG_POSTERR, "Suggest failure for %s", str);
1142       return NULL;
1143     }
1144   }
1145 
1146   w = MovableModalWindow (-50, -33, -10, -10, "Enter coding region interval", NULL);
1147   g = HiddenGroup (w, -1, 0, NULL);
1148   m = NULL;
1149   SetGroupSpacing (g, 3, 10);
1150   if (prot->descr != NULL) {
1151     vnp = ValNodeFindNext (prot->descr, NULL, Seq_descr_title);
1152     if (vnp != NULL && vnp->data.ptrvalue != NULL) {
1153       m = MultiLinePrompt (g, (CharPtr) vnp->data.ptrvalue, stdCharWidth * 28, programFont);
1154     }
1155   }
1156   d = CreateIntervalEditorDialog (g, NULL, 4, 2, sep, TRUE, FALSE);
1157   c = HiddenGroup (g, 2, 0, NULL);
1158   SetGroupSpacing (c, 10, 2);
1159   DefaultButton (c, "Accept", AcceptAskProc);
1160   PushButton (c, "Cancel", CancelAskProc);
1161   AlignObjects (ALIGN_CENTER, (HANDLE) d, (HANDLE) c, (HANDLE) m, NULL);
1162   Show (w);
1163   Select (w);
1164   intBoxUp = TRUE;
1165   intBoxRsult = FALSE;
1166   while (intBoxUp) {
1167     ProcessEventOrIdle ();
1168   }
1169   ProcessAnEvent ();
1170   if (intBoxRsult) {
1171     slp = (SeqLocPtr) DialogToPointer (d);
1172   }
1173   Remove (w);
1174   return slp;
1175 }
1176 
AutomaticProteinProcess(SeqEntryPtr esep,SeqEntryPtr psep,Int2 code,Boolean makeMRNA,SeqLocPtr use_this)1177 extern Boolean AutomaticProteinProcess (SeqEntryPtr esep, SeqEntryPtr psep,
1178                                         Int2 code, Boolean makeMRNA, SeqLocPtr use_this)
1179 
1180 {
1181   SeqFeatPtr   cds;
1182   CdRegionPtr  crp;
1183   Char         mRnaName [128];
1184   BioseqPtr    nbsp;
1185   SeqEntryPtr  nsep;
1186   BioseqPtr    pbsp;
1187   SeqFeatPtr   rna;
1188   RnaRefPtr    rrp;
1189   SeqLocPtr    slp;
1190   CharPtr      ttl;
1191   ValNodePtr   vnp;
1192   CharPtr      vnpstr;
1193   Boolean      partial5, partial3;
1194 
1195   if (esep == NULL || psep == NULL) return FALSE;
1196 
1197   nsep = FindNucSeqEntry (esep);
1198   if (nsep == NULL || (! IS_Bioseq (nsep)) || (! IS_Bioseq (psep))) return FALSE;
1199 
1200   nbsp = (BioseqPtr) nsep->data.ptrvalue;
1201   pbsp = (BioseqPtr) psep->data.ptrvalue;
1202   if (nbsp == NULL || pbsp == NULL) return FALSE;
1203 
1204   cds = NULL;
1205   WatchCursor ();
1206   Update ();
1207   if (use_this == NULL) {
1208     slp = PredictCodingRegion (nbsp, pbsp, code);
1209     if (slp == NULL) {
1210       ArrowCursor ();
1211       Update ();
1212       slp = AskForInterval (nsep, nbsp, pbsp);
1213     }
1214   } else {
1215     slp = use_this;
1216   }
1217   if (slp == NULL) return FALSE;
1218 
1219   mRnaName [0] = '\0';
1220   ttl = NULL;
1221   crp = CreateNewCdRgn (0, FALSE, code);
1222   if (crp != NULL) {
1223     if (pbsp->descr != NULL) {
1224       vnp = ValNodeFindNext (pbsp->descr, NULL, Seq_descr_title);
1225       if (vnp != NULL && vnp->data.ptrvalue != NULL) {
1226         vnpstr = (CharPtr) vnp->data.ptrvalue;
1227         CreateGeneAndProtFeats (nsep, psep, slp, crp, vnpstr, mRnaName, sizeof (mRnaName), &ttl);
1228         TrimSpacesAroundString (vnpstr);
1229         if (StringHasNoText (vnpstr)) {
1230           ValNodeExtract (&(pbsp->descr), Seq_descr_title);
1231         }
1232       }
1233     }
1234     if (makeMRNA) {
1235       rrp = RnaRefNew ();
1236       if (rrp != NULL) {
1237         rrp->type = 2;
1238         if (! StringHasNoText (mRnaName)) {
1239           rrp->ext.choice = 1;
1240           rrp->ext.value.ptrvalue = StringSave (mRnaName);
1241         }
1242         rna = CreateNewFeature (nsep, NULL, SEQFEAT_RNA, NULL);
1243         if (rna != NULL) {
1244           rna->data.value.ptrvalue = (Pointer) rrp;
1245           rna->location = SeqLocFree (rna->location);
1246           rna->location = AsnIoMemCopy ((Pointer) slp,
1247                                         (AsnReadFunc) SeqLocAsnRead,
1248                                         (AsnWriteFunc) SeqLocAsnWrite);
1249         }
1250       }
1251     }
1252     cds = CreateNewFeature (nsep, NULL, SEQFEAT_CDREGION, NULL);
1253     if (cds != NULL) {
1254       cds->data.value.ptrvalue = (Pointer) crp;
1255       cds->location = SeqLocFree (cds->location);
1256       cds->location = slp;
1257       slp = NULL;
1258       CheckSeqLocForPartial (cds->location, &partial5, &partial3);
1259       cds->partial |= partial5 | partial3;
1260       SetSeqFeatProduct (cds, pbsp);
1261       if (! StringHasNoText (ttl)) {
1262         cds->comment = ttl;
1263       }
1264     }
1265   }
1266 
1267   SeqLocFree (slp);
1268   return TRUE;
1269 }
1270 
1271 typedef struct fa2htgsform {
1272   FORM_MESSAGE_BLOCK
1273 
1274   SeqSubmitPtr       ssp;
1275   SeqEntryPtr        sep;
1276 
1277   GrouP              templateblock;
1278   GrouP              fastablock;
1279   GrouP              orderblock;
1280   GrouP              controlblock;
1281   GrouP              contigtype;
1282 
1283   DialoG             contigorder;
1284   EnumFieldAssocPtr  alists [1];
1285   GrouP              htgsphase;
1286   ButtoN             draft;
1287   ButtoN             fulltop;
1288   ButtoN             activefin;
1289   TexT               orgname;
1290   TexT               seqname;
1291   ButtoN             update;
1292   TexT               accession;
1293   TexT               knownlength;
1294   TexT               gaplength;
1295   TexT               remark;
1296   TexT               clone;
1297   TexT               strain;
1298   TexT               cultivar;
1299   TexT               chromosome;
1300   TexT               title;
1301   DialoG             secondaries;
1302 
1303   SeqEntryPtr        seplist;
1304 
1305   ButtoN             okBtn;
1306   BtnActnProc        finish;
1307   BtnActnProc        cancel;
1308   Boolean            readPhrap;
1309   Boolean            buildContig;
1310 
1311 } Fa2htgsForm, PNTR Fa2htgsFormPtr;
1312 
1313 /*------------- MakeAc2GBSeqId() -----------------------*/
1314 /***************************************************************
1315 *   MakeAc2GBSeqId:
1316 *   -- return NULL if acnum == null
1317 *                                             Hsiu-Chuan 4-18-97
1318 ****************************************************************/
SqnMakeAc2GBSeqId(CharPtr accession)1319 static SeqIdPtr  SqnMakeAc2GBSeqId(CharPtr accession)
1320 {
1321    TextSeqIdPtr tsip;
1322    SeqIdPtr sip;
1323 
1324    if (accession == NULL || *accession == '\0')
1325       return NULL;
1326 
1327    sip = ValNodeNew(NULL);
1328    sip->choice = SEQID_GENBANK;
1329    tsip = TextSeqIdNew();
1330    sip->data.ptrvalue = tsip;
1331    tsip->accession = StringSave(accession);
1332 
1333    return sip;
1334 
1335 } /* MakeAc2GBSeqId */
1336 
1337 /*----------- AddExtraAc2Entry() ----------------------------*/
1338 /***************************************************************
1339 *   AddExtraAc2Entry:
1340 *                                             Hsiu-Chuan 4-11-97, modified by JK
1341 ****************************************************************/
SqnAddDraft2Entry(SeqEntryPtr entry,CharPtr keyword)1342 static void SqnAddDraft2Entry (SeqEntryPtr entry, CharPtr keyword)
1343 
1344 {
1345    BioseqPtr  bsp;
1346    ValNodePtr vnp;
1347    GBBlockPtr gbp;
1348 
1349    if (entry == NULL) return;
1350 
1351    bsp = (BioseqPtr)(entry->data.ptrvalue);
1352 
1353    for (gbp= NULL, vnp = bsp->descr; vnp != NULL; vnp = vnp->next)
1354    {
1355        if (vnp->choice == Seq_descr_genbank)
1356        {
1357           gbp = vnp->data.ptrvalue;
1358           break;
1359        }
1360    }
1361 
1362    if (gbp == NULL)
1363    {
1364       vnp = (ValNodePtr) NewDescrOnSeqEntry (entry, Seq_descr_genbank);
1365       gbp = GBBlockNew();
1366       vnp->data.ptrvalue = (Pointer)gbp;
1367    }
1368 
1369    if (gbp != NULL) {
1370       ValNodeCopyStr (&gbp->keywords, 0, keyword);
1371    }
1372 }
1373 
SqnAddExtraAc2Entry(SeqEntryPtr entry,ValNodePtr extra_accs)1374 static Boolean SqnAddExtraAc2Entry (SeqEntryPtr entry , ValNodePtr extra_accs )
1375 {
1376    BioseqPtr  bsp;
1377    ValNodePtr vnp;
1378    GBBlockPtr gbp;
1379    Char       acnum[17];
1380    CharPtr    p;
1381    Int4       i, j;
1382    SeqHistPtr shp;
1383    SeqIdPtr   sip;
1384    ValNodePtr tmp;
1385 
1386    if ((entry == NULL) || (extra_accs == NULL))
1387       return FALSE;
1388 
1389    bsp = (BioseqPtr)(entry->data.ptrvalue);
1390 
1391    for (gbp= NULL, vnp = bsp->descr; vnp != NULL; vnp = vnp->next)
1392    {
1393        if (vnp->choice == Seq_descr_genbank)
1394        {
1395           gbp = vnp->data.ptrvalue;
1396           break;
1397        }
1398    }
1399 
1400    shp = bsp->hist;
1401 
1402    if (gbp == NULL)
1403    {
1404       vnp = (ValNodePtr) NewDescrOnSeqEntry (entry, Seq_descr_genbank);
1405       gbp = GBBlockNew();
1406       vnp->data.ptrvalue = (Pointer)gbp;
1407    }
1408 
1409    for (tmp = extra_accs; tmp != NULL; tmp = tmp->next)
1410    {
1411        p = (CharPtr) tmp->data.ptrvalue;
1412        if (p == NULL) continue;
1413        for (i = 0; isalnum((Int4)(*p)) && *p != '\0'; ++p, ++i)
1414            acnum[i] = *p;
1415        acnum[i] = '\0';
1416                /* check one_letter+5digits or two_letter+6digits */
1417        if (i == 6 || i == 8)
1418        {
1419           if (!isalpha((Int4)(acnum[0])) || (!(isdigit((Int4)(acnum[1])) && i == 6) &&
1420               !(isalpha((Int4)(acnum[1])) && i == 8)))
1421           {
1422              ErrPostEx(SEV_ERROR,0,0,
1423  "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
1424                                                            acnum);
1425              return FALSE;
1426           }
1427 
1428           for (j = 2; j < i; ++j)
1429           {
1430               if (!(isdigit((Int4)(acnum[j]))))
1431               {
1432                  ErrPostEx(SEV_ERROR,0,0,
1433  "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
1434                                                            acnum);
1435                  return FALSE;
1436               }
1437           }
1438 
1439           ValNodeCopyStr(&gbp->extra_accessions, 0, acnum);
1440           sip = SqnMakeAc2GBSeqId (acnum);
1441           if (shp == NULL)
1442           {
1443              shp = SeqHistNew();
1444              bsp->hist = shp;
1445           }
1446           ValNodeLink(&shp->replace_ids, sip);
1447        }
1448        else
1449        {
1450           ErrPostEx(SEV_ERROR,0,0,
1451  "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
1452                                                            acnum);
1453           return FALSE;
1454        }
1455 
1456        while (!isalnum((Int4)(*p)) && *p != '\0')
1457            ++p;
1458    }
1459 
1460    return TRUE;
1461 
1462 } /* AddExtraAc2Entry */
1463 
RescueSeqGraphs(BioseqPtr bsp,Int2 index,ValNodePtr PNTR vnpp)1464 static void RescueSeqGraphs (BioseqPtr bsp, Int2 index, ValNodePtr PNTR vnpp)
1465 
1466 {
1467   SeqAnnotPtr   nextsap;
1468   SeqGraphPtr   nextsgp;
1469   Pointer PNTR  prevsap;
1470   Pointer PNTR  prevsgp;
1471   SeqAnnotPtr   sap;
1472   SeqGraphPtr   sgp;
1473 
1474   if (bsp == NULL || vnpp == NULL) return;
1475   sap = bsp->annot;
1476   prevsap = (Pointer PNTR) &(bsp->annot);
1477   while (sap != NULL) {
1478     nextsap = sap->next;
1479     if (sap->type == 3) {
1480       sgp = (SeqGraphPtr) sap->data;
1481       prevsgp = (Pointer PNTR) &(sap->data);
1482       while (sgp != NULL) {
1483         nextsgp = sgp->next;
1484         *(prevsgp) = sgp->next;
1485         sgp->next = NULL;
1486         ValNodeAddPointer (vnpp, index, (Pointer) sgp);
1487         sgp = nextsgp;
1488       }
1489     }
1490     if (sap->data == NULL) {
1491       *(prevsap) = sap->next;
1492       sap->next = NULL;
1493       SeqAnnotFree (sap);
1494     } else {
1495       prevsap = (Pointer PNTR) &(sap->next);
1496     }
1497     sap = nextsap;
1498   }
1499 }
1500 
NewSeqAnnotType3(CharPtr name,SeqGraphPtr sgp)1501 static SeqAnnotPtr NewSeqAnnotType3 (CharPtr name, SeqGraphPtr sgp)
1502 
1503 {
1504   SeqAnnotPtr  sap = NULL;
1505 
1506   if (sgp == NULL) return NULL;
1507   sap = SeqAnnotNew ();
1508   if (sap == NULL) return NULL;
1509 
1510   if (! StringHasNoText (name)) {
1511     SeqDescrAddPointer (&(sap->desc), Annot_descr_name, StringSave (name));
1512   }
1513   sap->type = 3;
1514   sap->data = (Pointer) sgp;
1515 
1516   return sap;
1517 }
1518 
OffsetAndLinkSeqGraph(BioseqPtr bsp,SeqGraphPtr sgp,Int2 index)1519 static void OffsetAndLinkSeqGraph (BioseqPtr bsp, SeqGraphPtr sgp, Int2 index)
1520 
1521 {
1522   DeltaSeqPtr  dsp;
1523   SeqGraphPtr  lastsgp;
1524   Int4         len;
1525   SeqLitPtr    litp;
1526   SeqAnnotPtr  sap;
1527   SeqIntPtr    sintp;
1528   SeqLocPtr    slp;
1529 
1530   if (bsp == NULL || sgp == NULL || index < 1) return;
1531   len = 0;
1532   if (bsp->repr == Seq_repr_delta && bsp->seq_ext_type == 4) {
1533     for (dsp = (DeltaSeqPtr) (bsp->seq_ext);
1534          dsp != NULL && index > 1; dsp = dsp->next, index--) {
1535       if (dsp->choice == 1) {
1536         len += SeqLocLen ((SeqLocPtr) dsp->data.ptrvalue);
1537       } else if (dsp->choice == 2) {
1538         litp = (SeqLitPtr) dsp->data.ptrvalue;
1539         if (litp != NULL) {
1540           len += litp->length;
1541         }
1542       }
1543     }
1544   }
1545   slp = sgp->loc;
1546   if (slp != NULL && slp->choice == SEQLOC_INT) {
1547     sintp = (SeqIntPtr) slp->data.ptrvalue;
1548     if (sintp != NULL) {
1549       sintp->from += len;
1550       sintp->to += len;
1551       sintp->id = SeqIdFree (sintp->id);
1552       sintp->id = SeqIdDup (bsp->id);
1553     }
1554   }
1555   for (sap = bsp->annot; sap != NULL; sap = sap->next) {
1556     if (sap->type == 3) {
1557       for (lastsgp = sap->data; lastsgp->next != NULL; lastsgp = lastsgp->next) {
1558         continue;
1559       }
1560       lastsgp->next = sgp;
1561       break;
1562     }
1563   }
1564   if (sap == NULL) {
1565     if (bsp->annot != NULL) {
1566       for (sap = bsp->annot; sap->next != NULL; sap = sap->next) {
1567         continue;
1568       }
1569       sap->next = NewSeqAnnotType3 ("Graphs", sgp);
1570     } else {
1571       bsp->annot = NewSeqAnnotType3 ("Graphs", sgp);
1572     }
1573   }
1574 }
1575 
1576 static CharPtr phrapBoilerPlate = "Sequence Quality Assessment:~ \
1577 This entry has been annotated with sequence quality~ \
1578 estimates computed by the Phrap assembly program.~ \
1579 All manually edited bases have been reduced to quality zero.~ \
1580 Quality levels above 40 are expected to have less than ~ \
1581 1 error in 10,000 bp.~ \
1582 Base-by-base quality values are not generally visible from the~ \
1583 GenBank flat file format but are available as part~ \
1584 of this entry's ASN.1 file.~----------------------~";
1585 
ProcessFa2htgs(Fa2htgsFormPtr ffp,SeqSubmitPtr ssp)1586 static void ProcessFa2htgs (Fa2htgsFormPtr ffp, SeqSubmitPtr ssp)
1587 
1588 {
1589   SeqEntryPtr  sep = NULL, oldsep, the_entry, nextsep;
1590   NCBISubPtr nsp;
1591   Int2 htgs_phase = -1;
1592   Uint1 tech;
1593   CharPtr seqname = NULL, accession = NULL, orgname = NULL;
1594   CharPtr clone = NULL, strain = NULL, cultivar = NULL, chromosome = NULL;
1595   CharPtr remark = NULL, title = NULL, seqbuf = NULL;
1596   Int4 length = 0, cumlength = 0, gaplen;
1597   BioseqPtr bsp = NULL;
1598   BioseqSetPtr bssp;
1599   SeqLitPtr slp;
1600   ValNodePtr vnp, PNTR prevpnt, next, extra_accs;
1601   Boolean lastwasraw, draft, fulltop, activefin, usedelta = FALSE;
1602   Char str [64];
1603   long int val;
1604   Int2 index = 0;
1605   ValNodePtr rescuedsgps = NULL;
1606   ValNodePtr seqlitlist = NULL;
1607   IntFuzzPtr ifp;
1608   ObjectIdPtr    oip;
1609   UserFieldPtr   ufp;
1610   UserObjectPtr  uop;
1611   DatePtr dp;
1612 
1613   if (ffp == NULL || ssp == NULL) return;
1614 
1615   htgs_phase = GetValue (ffp->htgsphase) - 1;
1616   orgname = SaveStringFromText (ffp->orgname);
1617   seqname = SaveStringFromText (ffp->seqname);
1618   if (GetStatus (ffp->update)) {
1619     accession = SaveStringFromText (ffp->accession);
1620   }
1621   clone = SaveStringFromText (ffp->clone);
1622   strain = SaveStringFromText (ffp->strain);
1623   cultivar = SaveStringFromText (ffp->cultivar);
1624   chromosome = SaveStringFromText (ffp->chromosome);
1625   remark = SaveStringFromText (ffp->remark);
1626   title = SaveStringFromText (ffp->title);
1627   extra_accs = DialogToPointer (ffp->secondaries);
1628   draft = GetStatus (ffp->draft);
1629   fulltop = GetStatus (ffp->fulltop);
1630   activefin = GetStatus (ffp->activefin);
1631 
1632   length = 0;
1633 /* may need to really calculate length */
1634   GetTitle (ffp->knownlength, str, sizeof (str));
1635   if (! StringHasNoText (str)) {
1636     if (sscanf (str, "%ld", &val) == 1 && val > 0) {
1637       length = (Int4) val;
1638     }
1639   }
1640 
1641   gaplen = 0;
1642 /* now usually filling in with gaps of 100 bases */
1643   GetTitle (ffp->gaplength, str, sizeof (str));
1644   if (! StringHasNoText (str)) {
1645     if (sscanf (str, "%ld", &val) == 1 && val > 0) {
1646       gaplen = (Int4) val;
1647     }
1648   }
1649 
1650 /* modified from fa2htgs */
1651    oldsep = (SeqEntryPtr)(ssp->data);  /* clear out template */
1652    ssp->data = NULL;
1653    MemFree(ssp->sub->tool);
1654    sprintf (str, "Sequin %s", SEQUIN_APPLICATION);
1655    ssp->sub->tool = StringSave (str);
1656    nsp = MemNew(sizeof(NCBISub));
1657    nsp->ssp = ssp;
1658    nsp->submittor_key = StringSave (genomeCenter);
1659    /*
1660    MemFree(ssp->sub->cit->descr);
1661    ssp->sub->cit->descr = remark;
1662    */
1663 
1664    cumlength = 0;
1665    index = 0;
1666 
1667    sep = ffp->seplist;
1668    if (sep != NULL && sep->next != NULL) {
1669      usedelta = TRUE;
1670    }
1671 
1672    if (ffp->buildContig) {
1673      ssp->data = (Pointer) ffp->seplist;
1674      the_entry = ffp->seplist;
1675      sep = the_entry;
1676 
1677      oip = ObjectIdNew ();
1678      oip->str = StringSave ("info");
1679      uop = UserObjectNew ();
1680      uop->type = oip;
1681      uop->_class = StringSave ("Genomes");
1682 
1683      oip = ObjectIdNew ();
1684      oip->id = 0;
1685      ufp = UserFieldNew ();
1686      ufp->choice = 2;
1687      ufp->data.intvalue = 0;
1688      ufp->label = oip;
1689 
1690      uop->data = ufp;
1691 
1692      if (sep != NULL && IS_Bioseq (sep)) {
1693        bsp = (BioseqPtr) sep->data.ptrvalue;
1694        vnp = SeqDescrNew (NULL);
1695        vnp->choice = Seq_descr_user;
1696        vnp->data.ptrvalue = (Pointer) uop;
1697        vnp->next = bsp->descr;
1698        bsp->descr = vnp;
1699        cumlength = bsp->length;
1700      }
1701 
1702    }
1703    else if (htgs_phase < 3 || usedelta)
1704    {
1705       the_entry = AddDeltaSeqOnlyToSubmission (
1706                         nsp,
1707                         seqname,
1708                         NULL,
1709                         accession,
1710                         0,
1711                         MOLECULE_CLASS_DNA,
1712                         MOLECULE_TYPE_GENOMIC,
1713                         length,
1714                         TOPOLOGY_LINEAR,
1715                         STRANDEDNESS_DOUBLE);
1716 
1717       sep = ffp->seplist;
1718       lastwasraw = FALSE;
1719       while (sep != NULL)
1720       {
1721          nextsep = sep->next;
1722          sep->next = NULL;
1723          bsp = (BioseqPtr)(sep->data.ptrvalue);
1724          if (bsp->repr == Seq_repr_raw)
1725          {
1726             if (lastwasraw) {
1727                slp = AddFakeGapToDeltaSeq(nsp, the_entry, gaplen);
1728                ValNodeAddPointer (&seqlitlist, 0, (Pointer) slp);
1729                index++;
1730                cumlength += gaplen;
1731             }
1732             BioseqRawConvert(bsp, Seq_code_iupacna);
1733             seqbuf = BSMerge((ByteStorePtr)(bsp->seq_data), NULL);
1734             slp = AddLiteralToDeltaSeq(nsp, the_entry,
1735                bsp->length);
1736             AddBasesToLiteral(nsp, slp, seqbuf);
1737             MemFree(seqbuf);
1738             lastwasraw = TRUE;
1739             index++;
1740          }
1741          else
1742          {
1743             if (bsp->length < 0)
1744                bsp->length = 0;  /* -1 may be set */
1745             AddGapToDeltaSeq(nsp, the_entry,
1746                bsp->length);
1747             lastwasraw = FALSE;
1748             index++;
1749          }
1750          cumlength += bsp->length;
1751          RescueSeqGraphs (bsp, index, &rescuedsgps);
1752          SeqEntryFree(sep);
1753          sep = nextsep;
1754       }
1755    }
1756    else
1757    {
1758     the_entry = AddSeqOnlyToSubmission (
1759                         nsp,
1760                         seqname,
1761                         NULL,
1762                         accession,
1763                         0,
1764                         MOLECULE_CLASS_DNA,
1765                         MOLECULE_TYPE_GENOMIC,
1766                         length,
1767                         TOPOLOGY_LINEAR,
1768                         STRANDEDNESS_DOUBLE);
1769 
1770       sep = ffp->seplist;
1771       if (sep != NULL) {
1772         nextsep = sep->next;
1773         sep->next = NULL;
1774         bsp = (BioseqPtr)(sep->data.ptrvalue);
1775         if (bsp->repr == Seq_repr_raw)
1776         {
1777            BioseqRawConvert(bsp, Seq_code_iupacna);
1778            seqbuf = BSMerge((ByteStorePtr)(bsp->seq_data), NULL);
1779            AddBasesToBioseq(nsp, the_entry, seqbuf);
1780            MemFree(seqbuf);
1781            index++;
1782         }
1783         cumlength += bsp->length;
1784         RescueSeqGraphs (bsp, index, &rescuedsgps);
1785         SeqEntryFree(sep);
1786         if (nextsep != NULL) {
1787           ErrPostEx (SEV_ERROR ,0, 0, "Only the first contig was used for HTGS 3");
1788         }
1789         if (length > 0 && length != cumlength) {
1790           ErrPostEx (SEV_ERROR ,0, 0, "Length is exactly %ld, not %ld",
1791                      (long) cumlength, (long) length);
1792           length = cumlength;
1793         }
1794       }
1795    }
1796 
1797     /* get data from template: pub, organism, and comment */
1798    if (IS_Bioseq(oldsep))
1799    {
1800       bsp = (BioseqPtr)(oldsep->data.ptrvalue);
1801       prevpnt = &(bsp->descr);
1802    }
1803    else
1804    {
1805       bssp = (BioseqSetPtr)(oldsep->data.ptrvalue);
1806       prevpnt = &(bssp->descr);
1807    }
1808 
1809    if (the_entry != NULL) {
1810      bsp = (BioseqPtr)(the_entry->data.ptrvalue);
1811      if (bsp != NULL) {
1812        bsp->length = MAX (cumlength, length);
1813 
1814        for (vnp = *prevpnt; vnp != NULL; vnp = next)
1815        {
1816           next = vnp->next;
1817           if (vnp->choice == Seq_descr_pub)
1818           {
1819              *prevpnt = next;
1820              vnp->next = NULL;
1821              ValNodeLink(&(bsp->descr), vnp);
1822           }
1823           else
1824              prevpnt = &(vnp->next);
1825        }
1826        if (remark != NULL) {
1827          vnp = SeqDescrNew (NULL);
1828          if (vnp != NULL) {
1829            vnp->choice = Seq_descr_comment;
1830            vnp->data.ptrvalue = remark;
1831            ValNodeLink(&(bsp->descr), vnp);
1832          }
1833        }
1834      }
1835    }
1836 
1837    SeqEntryFree(oldsep);
1838 
1839    AddOrganismToEntryNew(nsp, the_entry, orgname, NULL, NULL, NULL,
1840                          NULL, NULL, NULL, NULL);
1841 
1842    AddGenomeToEntry(nsp, the_entry, 1);
1843    if (clone != NULL)
1844       AddSubSourceToEntry(nsp, the_entry, 3, clone);
1845    if (chromosome != NULL)
1846        AddSubSourceToEntry(nsp, the_entry, 1, chromosome);
1847    if (strain != NULL)
1848       AddOrgModToEntry(nsp, the_entry, 2, strain);
1849    if (cultivar != NULL)
1850       AddOrgModToEntry(nsp, the_entry, ORGMOD_cultivar, cultivar);
1851    if (title != NULL)
1852       AddTitleToEntry(nsp, the_entry, title);
1853    if (ffp->readPhrap) {
1854       AddCommentToEntry(nsp, the_entry, phrapBoilerPlate);
1855    }
1856 
1857    if (extra_accs != NULL) {
1858       SqnAddExtraAc2Entry(the_entry, extra_accs);
1859    }
1860 
1861    if (draft) {
1862       SqnAddDraft2Entry(the_entry, "HTGS_DRAFT");
1863    }
1864    if (fulltop) {
1865       SqnAddDraft2Entry(the_entry, "HTGS_FULLTOP");
1866    }
1867    if (activefin) {
1868       SqnAddDraft2Entry(the_entry, "HTGS_ACTIVEFIN");
1869    }
1870 
1871    AddBiomolToEntry(nsp, the_entry, 1);
1872    if (ffp->buildContig) {
1873    } else {
1874      switch (htgs_phase) {
1875        case 0 :
1876          tech = MI_TECH_htgs_0;
1877          break;
1878        case 1 :
1879          tech = MI_TECH_htgs_1;
1880          break;
1881        case 2 :
1882          tech = MI_TECH_htgs_2;
1883          break;
1884        case 3 :
1885          tech = MI_TECH_htgs_3;
1886          break;
1887        default :
1888          tech = MI_TECH_htgs_3;
1889          break;
1890      }
1891      AddTechToEntry(nsp, the_entry, tech);
1892    }
1893    vnp = NewDescrOnSeqEntry (the_entry, Seq_descr_create_date);
1894    if (vnp != NULL) {
1895      dp = DateCurr ();
1896      vnp->data.ptrvalue = (Pointer) dp;
1897    }
1898 
1899    if (bsp != NULL) {
1900      for (vnp = rescuedsgps; vnp != NULL; vnp = vnp->next) {
1901        OffsetAndLinkSeqGraph (bsp, (SeqGraphPtr) vnp->data.ptrvalue, (Int2) vnp->choice);
1902        vnp->data.ptrvalue = NULL;
1903      }
1904    }
1905    rescuedsgps = ValNodeFreeData (rescuedsgps);
1906 
1907    for (vnp = seqlitlist; vnp != NULL; vnp = vnp->next) {
1908      slp = (SeqLitPtr) vnp->data.ptrvalue;
1909      if (slp != NULL) {
1910        ifp = IntFuzzNew();
1911        ifp->choice = 4;    /* lim - unk*/
1912        slp->fuzz = ifp;
1913      }
1914    }
1915    seqlitlist = ValNodeFree (seqlitlist);
1916 
1917    MemFree (nsp);
1918 
1919 }
1920 
Fa2htgsToSeqSubmitPtr(ForM f)1921 static Pointer Fa2htgsToSeqSubmitPtr (ForM f)
1922 
1923 {
1924   Fa2htgsFormPtr  ffp;
1925   SeqSubmitPtr    ssp;
1926 
1927   ffp = (Fa2htgsFormPtr) GetObjectExtra (f);
1928   if (ffp == NULL) return NULL;
1929   ProcessFa2htgs (ffp, ffp->ssp);
1930   ssp = ffp->ssp;
1931   ffp->ssp = NULL;
1932   ffp->sep = NULL;
1933   ffp->seplist = NULL;
1934   return (Pointer) ssp;
1935 }
1936 
Fa2htgsFormMessage(ForM f,Int2 mssg)1937 static void Fa2htgsFormMessage (ForM f, Int2 mssg)
1938 
1939 {
1940   Fa2htgsFormPtr  ffp;
1941 
1942   ffp = (Fa2htgsFormPtr) GetObjectExtra (f);
1943   if (ffp) {
1944     switch (mssg) {
1945       case VIB_MSG_CUT :
1946         StdCutTextProc (NULL);
1947         break;
1948       case VIB_MSG_COPY :
1949         StdCopyTextProc (NULL);
1950         break;
1951       case VIB_MSG_PASTE :
1952         StdPasteTextProc (NULL);
1953         break;
1954       case VIB_MSG_DELETE :
1955         StdDeleteTextProc (NULL);
1956         break;
1957       default :
1958         if (ffp->appmessage != NULL) {
1959           ffp->appmessage (f, mssg);
1960         }
1961         break;
1962     }
1963   }
1964 }
1965 
1966 #ifndef WIN_MAC
CreateFa2htgsFormMenus(WindoW w)1967 static void CreateFa2htgsFormMenus (WindoW w)
1968 
1969 {
1970   BaseFormPtr  bfp;
1971   MenU         m;
1972 
1973   bfp = (BaseFormPtr) GetObjectExtra (w);
1974   if (bfp != NULL) {
1975     m = PulldownMenu (w, "File");
1976     AddAboutAndHelpMenuItems (m);
1977     FormCommandItem (m, "Quit", bfp, VIB_MSG_QUIT);
1978     m = PulldownMenu (w, "Edit");
1979     FormCommandItem (m, CUT_MENU_ITEM, bfp, VIB_MSG_CUT);
1980     FormCommandItem (m, COPY_MENU_ITEM, bfp, VIB_MSG_COPY);
1981     FormCommandItem (m, PASTE_MENU_ITEM, bfp, VIB_MSG_PASTE);
1982     FormCommandItem (m, CLEAR_MENU_ITEM, bfp, VIB_MSG_DELETE);
1983   }
1984 }
1985 #endif
1986 
FillInFa2htgsFields(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)1987 static void FillInFa2htgsFields (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
1988 
1989 {
1990   BioseqPtr       bsp;
1991   BioseqSetPtr    bssp;
1992   Fa2htgsFormPtr  ffp;
1993   ValNodePtr      sdp = NULL;
1994 
1995   if (sep == NULL || sep->data.ptrvalue == NULL) return;
1996   ffp = (Fa2htgsFormPtr) mydata;
1997   if (ffp == NULL) return;
1998   if (IS_Bioseq (sep)) {
1999     bsp = (BioseqPtr) sep->data.ptrvalue;
2000     sdp = bsp->descr;
2001   } else if (IS_Bioseq_set (sep)) {
2002     bssp = (BioseqSetPtr) sep->data.ptrvalue;
2003     sdp = bssp->descr;
2004   } else return;
2005   while (sdp != NULL) {
2006     if (sdp->choice == Seq_descr_comment) {
2007       SetTitle (ffp->remark, (CharPtr) sdp->data.ptrvalue);
2008     }
2009     sdp = sdp->next;
2010   }
2011 }
2012 
ReadTemplate(ButtoN b)2013 static void ReadTemplate (ButtoN b)
2014 
2015 {
2016   AsnIoPtr        aip;
2017   Fa2htgsFormPtr  ffp;
2018   Char            path [PATH_MAX];
2019   SeqEntryPtr     sep;
2020   SeqSubmitPtr    ssp;
2021   Char            str [128];
2022 
2023   ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2024   if (ffp == NULL) return;
2025   if (GetInputFileName (path, sizeof (path), "", "TEXT")) {
2026     ffp->ssp = SeqSubmitFree (ffp->ssp);
2027     aip = AsnIoOpen (path, "r");
2028     if (aip != NULL) {
2029       ffp->ssp = SeqSubmitAsnRead (aip, NULL);
2030     }
2031     AsnIoClose (aip);
2032   }
2033   if (ffp->ssp != NULL) {
2034     SafeShow (ffp->fastablock);
2035     SafeDisable (b);
2036     ssp = ffp->ssp;
2037     if (ssp->datatype == 1) {
2038       sep = (SeqEntryPtr) ssp->data;
2039       if (sep != NULL) {
2040         SeqEntryToGeneticCode (sep, NULL, str, sizeof (str));
2041         SetTitle (ffp->orgname, str);
2042         SeqEntryExplore (sep, (Pointer) ffp, FillInFa2htgsFields);
2043       }
2044     }
2045   }
2046 }
2047 
Fa2htgsFormOkay(Fa2htgsFormPtr ffp)2048 static Boolean Fa2htgsFormOkay (Fa2htgsFormPtr ffp)
2049 
2050 {
2051   if (ffp == NULL) return FALSE;
2052   if (ffp->ssp == NULL) return FALSE;
2053   if (ffp->seplist == NULL) return FALSE;
2054   if (GetValue (ffp->htgsphase) == 0 && (! ffp->buildContig)) return FALSE;
2055   if (TextHasNoText (ffp->orgname)) return FALSE;
2056   if (TextHasNoText (ffp->seqname)) return FALSE;
2057   return TRUE;
2058 }
2059 
ReadFastaHtgsFile(ButtoN b)2060 static void ReadFastaHtgsFile (ButtoN b)
2061 
2062 {
2063   Fa2htgsFormPtr  ffp;
2064   FILE            *fp;
2065   SeqEntryPtr     head;
2066   Char            path [PATH_MAX];
2067   SeqEntryPtr     sep;
2068   CharPtr         ttl;
2069 
2070   ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2071   if (ffp == NULL) return;
2072   if (! GetInputFileName (path, sizeof (path), "", "TEXT")) return;
2073   if (! StringHasNoText (path)) {
2074     fp = FileOpen (path, "r");
2075     if (fp != NULL) {
2076       head = NULL;
2077       sep = FastaToSeqEntry (fp, TRUE);
2078       while (sep != NULL) {
2079         ValNodeLink (&head, sep);
2080         sep = FastaToSeqEntry (fp, TRUE);
2081       }
2082       if (head != NULL) {
2083         ttl = SeqEntryGetTitle (head);
2084         SetTitle (ffp->title, ttl);
2085       }
2086       ffp->seplist = head;
2087     }
2088     FileClose (fp);
2089     if (ffp->seplist != NULL) {
2090       SafeShow (ffp->controlblock);
2091       SafeDisable (b);
2092       if (TextHasNoText (ffp->orgname)) {
2093         Select (ffp->orgname);
2094       } else {
2095         Select (ffp->seqname);
2096       }
2097       if (Fa2htgsFormOkay (ffp)) {
2098         SafeEnable (ffp->okBtn);
2099       } else {
2100         SafeDisable (ffp->okBtn);
2101       }
2102     }
2103   }
2104 }
2105 
MakePhrapAlists(SeqEntryPtr head)2106 static EnumFieldAssocPtr MakePhrapAlists (SeqEntryPtr head)
2107 
2108 {
2109   EnumFieldAssocPtr  alist = NULL;
2110   BioseqPtr          bsp;
2111   Int2               count;
2112   Int2               j;
2113   SeqEntryPtr        sep;
2114   SeqIdPtr           sip;
2115   Char               str [128];
2116 
2117   if (head == NULL) return NULL;
2118   count = ValNodeLen (head);
2119   alist = MemNew (sizeof (EnumFieldAssoc) * (size_t) (count + 4));
2120   if (alist == NULL) return NULL;
2121 
2122   j = 0;
2123   alist [j].name = StringSave ("                              ");
2124   alist [j].value = (UIEnum) 0;
2125   for (j = 1, sep = head; j <= count && sep != NULL; j++, sep = sep->next) {
2126     if (sep != NULL && sep->choice == 1 && sep->data.ptrvalue != NULL) {
2127       bsp = (BioseqPtr) sep->data.ptrvalue;
2128       sip = SeqIdFindWorst (bsp->id);
2129       SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
2130       str [30] = '\0';
2131       alist [j].name = StringSave (str);
2132       alist [j].value = (UIEnum) j;
2133     }
2134   }
2135   j = count + 1;
2136   alist [j].name = NULL;
2137   alist [j].value = (UIEnum) 0;
2138 
2139 
2140   return alist;
2141 }
2142 
ReadAPhrapFile(ButtoN b)2143 static void ReadAPhrapFile (ButtoN b)
2144 
2145 {
2146   PopuP           control;
2147   Int2            count;
2148   Fa2htgsFormPtr  ffp;
2149   FILE            *fp;
2150   SeqEntryPtr     head;
2151   Int2            i;
2152   Char            path [PATH_MAX];
2153   RecT            r;
2154   TagListPtr      tlp;
2155 
2156   ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2157   if (ffp == NULL) return;
2158   if (! GetInputFileName (path, sizeof (path), "", "TEXT")) return;
2159   if (! StringHasNoText (path)) {
2160     WatchCursor ();
2161     fp = FileOpen (path, "r");
2162     if (fp != NULL) {
2163       head = ReadPhrapFile (fp);
2164       ffp->seplist = head;
2165     }
2166     FileClose (fp);
2167     tlp = (TagListPtr) GetObjectExtra (ffp->contigorder);
2168     if (tlp != NULL) {
2169       ffp->alists [0] = MakePhrapAlists (ffp->seplist);
2170       tlp->alists = ffp->alists;
2171       for (i = 0; i < tlp->rows; i++) {
2172         control = (PopuP) tlp->control [i * MAX_TAGLIST_COLS + 0];
2173         if (control != NULL) {
2174           GetPosition (control, &r);
2175           Reset (control);
2176           InitEnumPopup (control, ffp->alists [0], NULL);
2177           SetEnumPopup (control, ffp->alists [0], 0);
2178           SetPosition (control, &r);
2179         }
2180       }
2181       count = ValNodeLen (ffp->seplist);
2182       for (i = 0; i < count; i++) {
2183         ValNodeCopyStr (&(tlp->vnp), 0, "0");
2184       }
2185       tlp->max = MAX ((Int2) 0, (Int2) (count - tlp->rows));
2186       CorrectBarMax (tlp->bar, tlp->max);
2187       CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
2188     }
2189     SafeShow (ffp->orderblock);
2190     SafeDisable (b);
2191     ArrowCursor ();
2192   }
2193 }
2194 
PhrapOrderChosen(ButtoN b)2195 static void PhrapOrderChosen (ButtoN b)
2196 
2197 {
2198   SeqEntryPtr     PNTR collision;
2199   Int2            count;
2200   Fa2htgsFormPtr  ffp;
2201   Int2            i;
2202   Int2            j;
2203   SeqEntryPtr     lastsep;
2204   SeqEntryPtr     nextsep;
2205   Boolean         okay;
2206   SeqEntryPtr     PNTR order;
2207   SeqEntryPtr     sep;
2208   CharPtr         str;
2209   TagListPtr      tlp;
2210   int             val;
2211   ValNodePtr      vnp;
2212   /*
2213   Char            contigs [256];
2214   Char            tmp [256];
2215   BioseqPtr       bsp;
2216   SeqIdPtr        sip;
2217   Boolean         notfirst;
2218   */
2219 
2220   ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2221   if (ffp == NULL) return;
2222   tlp = (TagListPtr) GetObjectExtra (ffp->contigorder);
2223   if (tlp == NULL) return;
2224   count = ValNodeLen (tlp->vnp);
2225   order = MemNew (sizeof (SeqEntryPtr) * (count + 1));
2226   if (order == NULL) return;
2227   collision = MemNew (sizeof (SeqEntryPtr) * (count + 1));
2228   if (collision == NULL) return;
2229 
2230   okay = TRUE;
2231   for (i = 0, vnp = tlp->vnp; i < count && vnp != NULL; i++, vnp = vnp->next) {
2232     str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
2233     if (str != NULL && sscanf (str, "%d", &val) == 1 && val > 0) {
2234       val--;
2235       for (j = 0, sep = ffp->seplist; j < (Int2) val && sep != NULL; j++, sep = sep->next) continue;
2236       if (sep != NULL) {
2237         if (collision [j] != NULL) {
2238           okay = FALSE;
2239         }
2240         collision [j] = sep;
2241         order [i] = sep;
2242       }
2243     }
2244     MemFree (str);
2245   }
2246   if (! okay) {
2247     Message (MSG_ERROR, "You must not select a contig more than once");
2248     MemFree (order);
2249     MemFree (collision);
2250     return;
2251   }
2252 
2253   okay = FALSE;
2254   for (i = 0; i < count; i++) {
2255     if (order [i] != NULL) {
2256       okay = TRUE;
2257     }
2258   }
2259   /* if no contigs selected, use all in order */
2260   if (! okay) {
2261     for (j = 0, sep = ffp->seplist; j < count && sep != NULL; j++, sep = sep->next) {
2262       order [j] = sep;
2263     }
2264     okay = TRUE;
2265   }
2266   /*
2267   if (! okay) {
2268     Message (MSG_ERROR, "You must select at least one contig");
2269     MemFree (order);
2270     MemFree (collision);
2271     return;
2272   }
2273   */
2274 
2275   /* use spreadsheet to reorder ffp->seplist, delete unwanted items */
2276 
2277   /*
2278   contigs [0] = '\0';
2279   notfirst = FALSE;
2280   for (i = 0; i < count; i++) {
2281     if (order [i] != NULL) {
2282       sep = order [i];
2283       bsp = (BioseqPtr) sep->data.ptrvalue;
2284       sip = SeqIdFindWorst (bsp->id);
2285       SeqIdWrite (sip, tmp, PRINTID_REPORT, sizeof (tmp));
2286       if (notfirst) {
2287         StringCat (contigs, " ");
2288       }
2289       StringCat (contigs, tmp);
2290       notfirst = TRUE;
2291     }
2292   }
2293   ffp->seplist = SetPhrapContigOrder (ffp->seplist, contigs);
2294   */
2295 
2296   for (i = 0; i < count; i++) {
2297     if (order [i] != NULL) {
2298       sep = ffp->seplist;
2299       lastsep = NULL;
2300       while (sep != NULL && sep != order [i]) {
2301         lastsep = sep;
2302         sep = sep->next;
2303       }
2304       if (sep != NULL) {
2305         if (lastsep != NULL) {
2306           lastsep->next = sep->next;
2307           sep->next = NULL;
2308         } else {
2309           ffp->seplist = sep->next;
2310           sep->next = NULL;
2311         }
2312       }
2313     }
2314   }
2315   sep = ffp->seplist;
2316   while (sep != NULL) {
2317     nextsep = sep->next;
2318     sep->next = NULL;
2319     SeqEntryFree (sep);
2320     sep = nextsep;
2321   }
2322   ffp->seplist = NULL;
2323 
2324   for (i = 0; i < count; i++) {
2325     if (order [i] != NULL) {
2326       ValNodeLink (&(ffp->seplist), order [i]);
2327     }
2328   }
2329 
2330   MemFree (order);
2331   MemFree (collision);
2332   SafeDisable (b);
2333   SafeHide (ffp->orderblock);
2334   SafeShow (ffp->controlblock);
2335   if (TextHasNoText (ffp->orgname)) {
2336     Select (ffp->orgname);
2337   } else {
2338     Select (ffp->seqname);
2339   }
2340   if (Fa2htgsFormOkay (ffp)) {
2341     SafeEnable (ffp->okBtn);
2342   } else {
2343     SafeDisable (ffp->okBtn);
2344   }
2345 }
2346 
ReadContigFile(ButtoN b)2347 static void ReadContigFile (ButtoN b)
2348 
2349 {
2350   BioseqPtr       bsp;
2351   Fa2htgsFormPtr  ffp;
2352   FILE            *fp;
2353   Boolean         onMaster;
2354   Char            path [PATH_MAX];
2355   SeqEntryPtr     sep = NULL;
2356 
2357   ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2358   if (ffp == NULL) return;
2359   if (! GetInputFileName (path, sizeof (path), "", "TEXT")) return;
2360   if (! StringHasNoText (path)) {
2361     WatchCursor ();
2362     fp = FileOpen (path, "r");
2363     if (fp != NULL) {
2364       onMaster = (Boolean) (GetValue (ffp->contigtype) == 2);
2365       sep = ReadContigList (fp, onMaster);
2366       if (sep != NULL && sep->choice == 1) {
2367         ffp->seplist = sep;
2368         bsp = (BioseqPtr) sep->data.ptrvalue;
2369         SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
2370       }
2371     }
2372     FileClose (fp);
2373     ArrowCursor ();
2374     if (ffp->seplist != NULL) {
2375       SafeShow (ffp->controlblock);
2376       SafeDisable (b);
2377       SafeDisable (ffp->contigtype);
2378       if (TextHasNoText (ffp->orgname)) {
2379         Select (ffp->orgname);
2380       } else {
2381         Select (ffp->seqname);
2382       }
2383       if (Fa2htgsFormOkay (ffp)) {
2384         SafeEnable (ffp->okBtn);
2385       } else {
2386         SafeDisable (ffp->okBtn);
2387       }
2388     }
2389   }
2390 }
2391 
AcceptFa2htgs(ButtoN b)2392 static void AcceptFa2htgs (ButtoN b)
2393 
2394 {
2395   Fa2htgsFormPtr  ffp;
2396 
2397   ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2398   if (ffp == NULL) return;
2399   Hide (ffp->form);
2400   Update ();
2401   if (ffp->finish != NULL) {
2402     ffp->finish (b);
2403   }
2404   SeqSubmitFree (ffp->ssp);
2405   SeqEntryFree (ffp->sep);
2406   Remove (ffp->form);
2407 }
2408 
CancelFa2htgs(ButtoN b)2409 static void CancelFa2htgs (ButtoN b)
2410 
2411 {
2412   Fa2htgsFormPtr  ffp;
2413 
2414   ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2415   if (ffp == NULL) return;
2416   Hide (ffp->form);
2417   Update ();
2418   if (ffp->cancel != NULL) {
2419     ffp->cancel (b);
2420   }
2421   SeqSubmitFree (ffp->ssp);
2422   SeqEntryFree (ffp->sep);
2423   Remove (ffp->form);
2424 }
2425 
SetFa2htgsAcceptBtn(Handle control)2426 static void SetFa2htgsAcceptBtn (Handle control)
2427 
2428 {
2429   Fa2htgsFormPtr  ffp;
2430 
2431   ffp = (Fa2htgsFormPtr) GetObjectExtra (control);
2432   if (ffp == NULL) return;
2433   if (Fa2htgsFormOkay (ffp)) {
2434     SafeEnable (ffp->okBtn);
2435   } else {
2436     SafeDisable (ffp->okBtn);
2437   }
2438 }
2439 
SetFa2htgsUpdate(ButtoN b)2440 static void SetFa2htgsUpdate (ButtoN b)
2441 
2442 {
2443   Fa2htgsFormPtr  ffp;
2444 
2445   ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2446   if (ffp == NULL) return;
2447   if (GetStatus (b)) {
2448     SafeEnable (ffp->accession);
2449   } else {
2450     SafeDisable (ffp->accession);
2451   }
2452   SetFa2htgsAcceptBtn ((Handle) b);
2453 }
2454 
CleanupGenomeCenterForm(GraphiC g,VoidPtr data)2455 static void CleanupGenomeCenterForm (GraphiC g, VoidPtr data)
2456 
2457 {
2458   Fa2htgsFormPtr  ffp;
2459   SeqEntryPtr     next;
2460   SeqEntryPtr     sep;
2461 
2462   ffp = (Fa2htgsFormPtr) data;
2463   if (ffp != NULL) {
2464     sep = ffp->seplist;
2465     while (sep != NULL) {
2466       next = sep->next;
2467       sep->next = NULL;
2468       SeqEntryFree (sep);
2469       sep = next;
2470     }
2471     if (ffp->alists [0] != NULL) {
2472       FreeEnumFieldAlist (ffp->alists [0]);
2473     }
2474   }
2475   StdCleanupFormProc (g, data);
2476 }
2477 
2478 static CharPtr secaccstrings [] = {"Secondary", "Accessions", NULL};
2479 
2480 static Uint2 contigorder_types [] = {
2481   TAGLIST_POPUP
2482 };
2483 
ENUM_ALIST(contigdefault_alist)2484 static ENUM_ALIST(contigdefault_alist)
2485   {"                              ", 0},
2486 END_ENUM_ALIST
2487 
2488 static EnumFieldAssocPtr contigdefault_alists [] = {
2489   contigdefault_alist
2490 };
2491 
2492 extern DialoG CreateTagListDialogEx (GrouP h, Uint2 rows, Uint2 cols,
2493                                      Int2 spacing, Uint2Ptr types,
2494                                      Uint2Ptr textWidths, EnumFieldAssocPtr PNTR alists,
2495                                      Boolean useBar, Boolean noExtend,
2496                                      ToDialogFunc tofunc, FromDialogFunc fromfunc);
2497 
CreateGenomeCenterForm(Int2 left,Int2 top,CharPtr title,BtnActnProc finish,BtnActnProc cancel,Boolean readPhrap,Boolean buildContig,WndActnProc activateForm)2498 extern ForM CreateGenomeCenterForm (Int2 left, Int2 top, CharPtr title,
2499                                     BtnActnProc finish,
2500                                     BtnActnProc cancel,
2501                                     Boolean readPhrap,
2502                                     Boolean buildContig,
2503                                     WndActnProc activateForm)
2504 
2505 {
2506   ButtoN             b;
2507   GrouP              c;
2508   Fa2htgsFormPtr     ffp;
2509   GrouP              g;
2510   GrouP              h;
2511   PrompT             ppt;
2512   GrouP              q;
2513   GrouP              sa;
2514   StdEditorProcsPtr  sepp;
2515   WindoW             w;
2516   Int2               wid;
2517   GrouP              x;
2518   GrouP              y;
2519 
2520   ffp = (Fa2htgsFormPtr) MemNew (sizeof (Fa2htgsForm));
2521   if (ffp == NULL) return NULL;
2522   ffp->finish = finish;
2523   ffp->cancel = cancel;
2524   ffp->readPhrap = readPhrap;
2525   ffp->buildContig = buildContig;
2526 
2527   w = FixedWindow (left, top, -10, -10, title, NULL);
2528   if (w == NULL) return NULL;
2529   SetObjectExtra (w, ffp, CleanupGenomeCenterForm);
2530 
2531   ffp->form = (ForM) w;
2532   ffp->toform = NULL;
2533   ffp->fromform = Fa2htgsToSeqSubmitPtr;
2534   ffp->formmessage = Fa2htgsFormMessage;
2535 
2536   ffp->ssp = NULL;
2537   ffp->sep = NULL;
2538   ffp->seplist = NULL;
2539   ffp->alists [0] = NULL;
2540 
2541 #ifndef WIN_MAC
2542   CreateFa2htgsFormMenus (w);
2543 #endif
2544 
2545   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2546   if (sepp != NULL) {
2547     ffp->appmessage = sepp->handleMessages;
2548   }
2549 
2550   SetGroupSpacing (w, 10, 10);
2551 
2552   h = HiddenGroup (w, -1, 0, NULL);
2553   SetGroupSpacing (h, 10, 10);
2554 
2555   ffp->templateblock = HiddenGroup (h, -1, 0, NULL);
2556   b = PushButton (ffp->templateblock, "Read Seq-submit Template", ReadTemplate);
2557   SetObjectExtra (b, ffp, NULL);
2558 
2559   ffp->fastablock = HiddenGroup (h, -1, 0, NULL);
2560   if (readPhrap) {
2561     b = PushButton (ffp->fastablock, "Read PHRAP File", ReadAPhrapFile);
2562   } else if (buildContig) {
2563     SetGroupSpacing (ffp->fastablock, 10, 10);
2564     y = HiddenGroup (ffp->fastablock, 1, 0, NULL);
2565     StaticPrompt (y, "Coordinates are on", 0, stdLineHeight, programFont, 'c');
2566     ffp->contigtype = HiddenGroup (y, 3, 0, NULL);
2567     RadioButton (ffp->contigtype, "Individual Accessions");
2568     RadioButton (ffp->contigtype, "Master Sequence");
2569     SetValue (ffp->contigtype, 1);
2570     b = PushButton (ffp->fastablock, "Read CONTIG Instructions", ReadContigFile);
2571     AlignObjects (ALIGN_CENTER, (HANDLE) y, (HANDLE) b, NULL);
2572   } else {
2573     b = PushButton (ffp->fastablock, "Read FASTA File", ReadFastaHtgsFile);
2574   }
2575   SetObjectExtra (b, ffp, NULL);
2576   Hide (ffp->fastablock);
2577 
2578   x = HiddenGroup (h, 0, 0, NULL);
2579 
2580   ffp->orderblock = HiddenGroup (x, -1, 0, NULL);
2581   SetGroupSpacing (ffp->orderblock, 5, 5);
2582   ppt = StaticPrompt (ffp->orderblock, "Enter contigs in desired order", 0, 0, programFont, 'c');
2583   ffp->contigorder = CreateTagListDialogEx (ffp->orderblock, 8, 1, 2,
2584                                             contigorder_types, NULL,
2585                                             contigdefault_alists,
2586                                             TRUE, TRUE, NULL, NULL);
2587   b = PushButton (ffp->orderblock, "Proceed", PhrapOrderChosen);
2588   SetObjectExtra (b, ffp, NULL);
2589   AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) ffp->contigorder,
2590                 (HANDLE) b, NULL);
2591   Hide (ffp->orderblock);
2592 
2593   ffp->controlblock = HiddenGroup (x, -1, 0, NULL);
2594   g = HiddenGroup (ffp->controlblock, 2, 0, NULL);
2595 
2596   ffp->htgsphase = NULL;
2597   if (! buildContig) {
2598     StaticPrompt (g, "Phase", 0, stdLineHeight, programFont, 'l');
2599     ffp->htgsphase = HiddenGroup (g, 4, 0, (GrpActnProc) SetFa2htgsAcceptBtn);
2600     SetObjectExtra (ffp->htgsphase, ffp, NULL);
2601     RadioButton (ffp->htgsphase, "HTGS-0");
2602     RadioButton (ffp->htgsphase, "HTGS-1");
2603     RadioButton (ffp->htgsphase, "HTGS-2");
2604     RadioButton (ffp->htgsphase, "HTGS-3");
2605     StaticPrompt (g, "HTGS_", 0, stdLineHeight, programFont, 'l');
2606     q = HiddenGroup (g, 3, 0, NULL);
2607     ffp->draft = CheckBox (q, "Draft", NULL);
2608     ffp->fulltop = CheckBox (q, "Fulltop", NULL);
2609     ffp->activefin = CheckBox (q, "Activefin", NULL);
2610   }
2611 
2612   StaticPrompt (g, "Organism", 0, dialogTextHeight, programFont, 'l');
2613   ffp->orgname = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2614   SetObjectExtra (ffp->orgname, ffp, NULL);
2615 
2616   StaticPrompt (g, "Sequence name", 0, dialogTextHeight, programFont, 'l');
2617   ffp->seqname = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2618   SetObjectExtra (ffp->seqname, ffp, NULL);
2619 
2620   StaticPrompt (g, "Length", 0, dialogTextHeight, programFont, 'l');
2621   ffp->knownlength = DialogText (g, "", 10, NULL);
2622   SetObjectExtra (ffp->knownlength, ffp, NULL);
2623 
2624   StaticPrompt (g, "Gap Length", 0, dialogTextHeight, programFont, 'l');
2625   ffp->gaplength = DialogText (g, "100", 10, NULL);
2626   SetObjectExtra (ffp->gaplength, ffp, NULL);
2627 
2628   ffp->update = CheckBox (g, "Update", SetFa2htgsUpdate);
2629   SetObjectExtra (ffp->update, ffp, NULL);
2630   ffp->accession = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2631   SetObjectExtra (ffp->accession, ffp, NULL);
2632   Disable (ffp->accession);
2633 
2634   StaticPrompt (g, "Chromosome", 0, dialogTextHeight, programFont, 'l');
2635   ffp->chromosome = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2636   SetObjectExtra (ffp->chromosome, ffp, NULL);
2637 
2638   StaticPrompt (g, "Clone", 0, dialogTextHeight, programFont, 'l');
2639   ffp->clone = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2640   SetObjectExtra (ffp->clone, ffp, NULL);
2641 
2642   StaticPrompt (g, "Strain", 0, dialogTextHeight, programFont, 'l');
2643   ffp->strain = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2644   SetObjectExtra (ffp->strain, ffp, NULL);
2645 
2646   StaticPrompt (g, "Cultivar", 0, dialogTextHeight, programFont, 'l');
2647   ffp->cultivar = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2648   SetObjectExtra (ffp->cultivar, ffp, NULL);
2649 
2650   wid = MaxStringWidths (secaccstrings) + 2;
2651   sa = MultiLinePrompt (g, "Secondary Accessions", wid, programFont);
2652   ffp->secondaries = CreateVisibleStringDialog (g, 3, -1, 15);
2653   AlignObjects (ALIGN_MIDDLE, (HANDLE) sa, (HANDLE) ffp->secondaries, NULL);
2654 
2655   q = HiddenGroup (ffp->controlblock, 1, 0, NULL);
2656 
2657   StaticPrompt (q, "Title", 0, 0, programFont, 'c');
2658   ffp->title = ScrollText (q, 20, 4, programFont, TRUE, (TxtActnProc) SetFa2htgsAcceptBtn);
2659   SetObjectExtra (ffp->title, ffp, NULL);
2660 
2661   StaticPrompt (q, "Remark", 0, 0, programFont, 'c');
2662   ffp->remark = ScrollText (q, 20, 4, programFont, TRUE, (TxtActnProc) SetFa2htgsAcceptBtn);
2663   SetObjectExtra (ffp->remark, ffp, NULL);
2664 
2665   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) q, NULL);
2666   Hide (ffp->controlblock);
2667 
2668   c = HiddenGroup (h, 2, 0, NULL);
2669   ffp->okBtn = DefaultButton (c, "Accept", AcceptFa2htgs);
2670   SetObjectExtra (ffp->okBtn, ffp, NULL);
2671   Disable (ffp->okBtn);
2672   b = PushButton (c, "Cancel", CancelFa2htgs);
2673   SetObjectExtra (b, ffp, NULL);
2674 
2675   AlignObjects (ALIGN_CENTER, (HANDLE) ffp->templateblock, (HANDLE) ffp->fastablock,
2676                 (HANDLE) ffp->orderblock, (HANDLE) ffp->controlblock, (HANDLE) c, NULL);
2677 
2678   RealizeWindow (w);
2679 
2680   if (activateForm != NULL) {
2681     SetActivate (w, activateForm);
2682   }
2683 
2684   Show (w);
2685   Select (w);
2686   Select (ffp->orgname);
2687 
2688   return (ForM) w;
2689 }
2690 
2691 typedef struct convcdsdata {
2692   FEATURE_FORM_BLOCK
2693 
2694   SeqEntryPtr    sep;
2695   TexT           geneName;
2696   TexT           protName;
2697   TexT           featcomment;
2698   ButtoN         retain;
2699   Uint2          subtype;
2700   Int2           errcount;
2701   Char           findThis [128];
2702   SeqLocPtr      slp;
2703   SeqEntryPtr    nsep;
2704   ObjMgrPtr      omp;
2705   ObjMgrTypePtr  omtp;
2706 } ConvCdsData, PNTR ConvCdsPtr;
2707 
CollectCDSAncestorGatherFunc(GatherContextPtr gcp)2708 static Boolean CollectCDSAncestorGatherFunc (GatherContextPtr gcp)
2709 
2710 {
2711   BioseqPtr      bsp;
2712   ConvCdsPtr     ccp;
2713   Boolean        noLeft;
2714   Boolean        noRight;
2715   ObjMgrTypePtr  omtp;
2716   SeqEntryPtr    sep;
2717   SeqFeatPtr     sfp;
2718   SeqLocPtr      slp;
2719   Uint2          subtype;
2720 
2721   if (gcp == NULL) return TRUE;
2722 
2723   ccp = (ConvCdsPtr) gcp->userdata;
2724   if (ccp == NULL ) return TRUE;
2725 
2726   if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
2727   omtp = ccp->omtp;
2728   if (omtp == NULL || omtp->subtypefunc == NULL) return TRUE;
2729 
2730   sfp = (SeqFeatPtr) gcp->thisitem;
2731   subtype = (*(omtp->subtypefunc)) ((Pointer) sfp);
2732   if (subtype != ccp->subtype) return TRUE;
2733 
2734   bsp = GetBioseqGivenSeqLoc (sfp->location, gcp->entityID);
2735   if (bsp == NULL) return TRUE;
2736   if (ISA_aa (bsp->mol)) return TRUE;
2737   if (bsp->repr != Seq_repr_seg) {
2738     sep = ccp->nsep;
2739     if (sep == NULL || sep->choice != 1) return TRUE;
2740     bsp = (BioseqPtr) sep->data.ptrvalue;
2741     if (bsp == NULL) return TRUE;
2742   }
2743   CheckSeqLocForPartial (sfp->location, &noLeft, &noRight);
2744   slp = SeqLocMerge (bsp, sfp->location, ccp->slp, FALSE, TRUE, FALSE);
2745   if (slp == NULL) return TRUE;
2746   SetSeqLocPartial (slp, noLeft, noRight);
2747 
2748   ccp->slp = SeqLocFree (ccp->slp);
2749   ccp->slp = slp;
2750 
2751   return TRUE;
2752 }
2753 
FinishConvertingToCDS(SeqEntryPtr sep,Uint2 entityID,ConvCdsPtr ccp)2754 static void FinishConvertingToCDS (SeqEntryPtr sep, Uint2 entityID, ConvCdsPtr ccp)
2755 
2756 {
2757   ByteStorePtr  bs;
2758   BioseqPtr     bsp;
2759   Char          ch;
2760   CdRegionPtr   crp;
2761   ValNodePtr    descr;
2762   Uint1         frame;
2763   Int2          genCode;
2764   Int2          i;
2765   Int4          len;
2766   Int4          lens [4];
2767   Int4          max;
2768   Boolean       noLeft;
2769   Boolean       noRight;
2770   MolInfoPtr    mip;
2771   SeqEntryPtr   nsep;
2772   SeqEntryPtr   old;
2773   CharPtr       prot;
2774   ProtRefPtr    prp;
2775   SeqEntryPtr   psep;
2776   CharPtr       ptr;
2777   SeqFeatPtr    sfp;
2778   Char          str [128];
2779   ValNodePtr    vnp;
2780 
2781   if (sep == NULL || ccp == NULL) return;
2782   genCode = SeqEntryToGeneticCode (sep, NULL, NULL, 0);
2783   crp = CreateNewCdRgn (1, FALSE, genCode);
2784   if (crp == NULL) return;
2785   sfp = CreateNewFeature (ccp->nsep, NULL, SEQFEAT_CDREGION, NULL);
2786   if (sfp == NULL) {
2787     CdRegionFree (crp);
2788     return;
2789   }
2790   sfp->data.value.ptrvalue = (Pointer) crp;
2791   sfp->location = SeqLocFree (sfp->location);
2792   sfp->location = AsnIoMemCopy ((Pointer) ccp->slp,
2793                                 (AsnReadFunc) SeqLocAsnRead,
2794                                 (AsnWriteFunc) SeqLocAsnWrite);
2795   CheckSeqLocForPartial (sfp->location, &noLeft, &noRight);
2796   sfp->partial = (sfp->partial || noLeft || noRight);
2797   if (! TextHasNoText (ccp->featcomment)) {
2798     sfp->comment = SaveStringFromTextAndStripNewlines (ccp->featcomment);
2799   }
2800   max = 0;
2801   frame = 0;
2802   for (i = 1; i <= 3; i++) {
2803     crp->frame = (Uint1) i;
2804     bs = ProteinFromCdRegionEx (sfp, FALSE, FALSE);
2805     len = BSLen (bs);
2806     BSFree (bs);
2807     lens [i] = len;
2808     if (len > max) {
2809       max = len;
2810       frame = (Uint1) i;
2811     }
2812   }
2813   for (i = 1; i <= 3; i++) {
2814     if (lens [i] == max && i != frame) {
2815       (ccp->errcount)++;
2816     }
2817   }
2818   crp->frame = frame;
2819   bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
2820   if (bs == NULL) return;
2821   prot = BSMerge (bs, NULL);
2822   bs = BSFree (bs);
2823   if (prot == NULL) return;
2824   ptr = prot;
2825   ch = *ptr;
2826   while (ch != '\0') {
2827     *ptr = TO_UPPER (ch);
2828     ptr++;
2829     ch = *ptr;
2830   }
2831   i = (Int2) StringLen (prot);
2832   if (i > 0 && prot [i - 1] == '*') {
2833     prot [i - 1] = '\0';
2834   }
2835   bs = BSNew (1000);
2836   if (bs != NULL) {
2837     ptr = prot;
2838     /*
2839     if (prot [0] == '-') {
2840       ptr++;
2841     }
2842     */
2843     BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
2844   }
2845   MemFree (prot);
2846   if (bs == NULL) return;
2847   bsp = BioseqNew ();
2848   if (bsp == NULL) return;
2849   bsp->repr = Seq_repr_raw;
2850   bsp->mol = Seq_mol_aa;
2851   bsp->seq_data_type = Seq_code_ncbieaa;
2852   bsp->seq_data = (SeqDataPtr) bs;
2853   bsp->length = BSLen (bs);
2854   bs = NULL;
2855   old = SeqEntrySetScope (sep);
2856   bsp->id = MakeNewProteinSeqId (sfp->location, NULL);
2857   SeqMgrAddToBioseqIndex (bsp);
2858   SeqEntrySetScope (old);
2859   psep = SeqEntryNew ();
2860   if (psep != NULL) {
2861     psep->choice = 1;
2862     psep->data.ptrvalue = (Pointer) bsp;
2863     SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, psep);
2864     mip = MolInfoNew ();
2865     if (mip != NULL) {
2866       mip->biomol = 8;
2867       mip->tech = 8;
2868       if (noLeft && noRight) {
2869         mip->completeness = 5;
2870       } else if (noLeft) {
2871         mip->completeness = 3;
2872       } else if (noRight) {
2873         mip->completeness = 4;
2874       }
2875       vnp = CreateNewDescriptor (psep, Seq_descr_molinfo);
2876       if (vnp != NULL) {
2877         vnp->data.ptrvalue = (Pointer) mip;
2878       }
2879     }
2880     descr = ExtractBioSourceAndPubs (sep);
2881     /*
2882     AddSeqEntryToSeqEntry (sep, psep, FALSE);
2883     */
2884     AddSeqEntryToSeqEntry (sep, psep, TRUE);
2885     nsep = FindNucSeqEntry (sep);
2886     ReplaceBioSourceAndPubs (sep, descr);
2887     SetSeqFeatProduct (sfp, bsp);
2888     GetTitle (ccp->protName, str, sizeof (str));
2889     if (! StringHasNoText (str)) {
2890       prp = CreateNewProtRef (str, NULL, NULL, NULL);
2891       if (prp != NULL) {
2892         sfp = CreateNewFeature (psep, NULL, SEQFEAT_PROT, NULL);
2893         if (sfp != NULL) {
2894           sfp->data.value.ptrvalue = (Pointer) prp;
2895           SetSeqLocPartial (sfp->location, noLeft, noRight);
2896           sfp->partial = (sfp->partial || noLeft || noRight);
2897         }
2898       }
2899     }
2900   }
2901 }
2902 
RemoveCDSAncestorCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)2903 static void RemoveCDSAncestorCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
2904 
2905 {
2906   BioseqPtr      bsp;
2907   BioseqSetPtr   bssp;
2908   ConvCdsPtr     ccp;
2909   SeqAnnotPtr    nextsap;
2910   SeqFeatPtr     nextsfp;
2911   ObjMgrTypePtr  omtp;
2912   Pointer PNTR   prevsap;
2913   Pointer PNTR   prevsfp;
2914   SeqAnnotPtr    sap;
2915   SeqFeatPtr     sfp;
2916   Uint2          subtype;
2917 
2918   if (sep == NULL || sep->data.ptrvalue == NULL) return;
2919   ccp = (ConvCdsPtr) mydata;
2920   if (ccp == NULL) return;
2921   omtp = ccp->omtp;
2922   if (omtp == NULL || omtp->subtypefunc == NULL) return;
2923   if (IS_Bioseq (sep)) {
2924     bsp = (BioseqPtr) sep->data.ptrvalue;
2925     sap = bsp->annot;
2926     prevsap = (Pointer PNTR) &(bsp->annot);
2927   } else if (IS_Bioseq_set (sep)) {
2928     bssp = (BioseqSetPtr) sep->data.ptrvalue;
2929     sap = bssp->annot;
2930     prevsap = (Pointer PNTR) &(bssp->annot);
2931   } else return;
2932   while (sap != NULL) {
2933     nextsap = sap->next;
2934     if (sap->type == 1) {
2935       sfp = (SeqFeatPtr) sap->data;
2936       prevsfp = (Pointer PNTR) &(sap->data);
2937       while (sfp != NULL) {
2938         nextsfp = sfp->next;
2939         subtype = (*(omtp->subtypefunc)) ((Pointer) sfp);
2940         if (subtype == ccp->subtype) {
2941           *(prevsfp) = sfp->next;
2942           sfp->next = NULL;
2943           SeqFeatFree (sfp);
2944         } else {
2945           prevsfp = (Pointer PNTR) &(sfp->next);
2946         }
2947         sfp = nextsfp;
2948       }
2949     }
2950     if (sap->data == NULL) {
2951       *(prevsap) = sap->next;
2952       sap->next = NULL;
2953       SeqAnnotFree (sap);
2954     } else {
2955       prevsap = (Pointer PNTR) &(sap->next);
2956     }
2957     sap = nextsap;
2958   }
2959 }
2960 
ConvertToCDSCallback(SeqEntryPtr sep,Uint2 entityID,ConvCdsPtr ccp)2961 static void ConvertToCDSCallback (SeqEntryPtr sep, Uint2 entityID, ConvCdsPtr ccp)
2962 
2963 {
2964   BioseqPtr     bsp;
2965   BioseqSetPtr  bssp;
2966   GeneRefPtr    grp;
2967   GatherScope   gs;
2968   SeqLocPtr     gslp;
2969   Boolean       hasNulls;
2970   Boolean       noLeft;
2971   Boolean       noRight;
2972   SeqEntryPtr   nsep;
2973   SeqFeatPtr    sfp;
2974   SeqIdPtr      sip;
2975   SeqLocPtr     slp;
2976   Char          str [128];
2977 
2978   if (sep == NULL || ccp == NULL) return;
2979   if (IS_Bioseq_set (sep)) {
2980     bssp = (BioseqSetPtr) sep->data.ptrvalue;
2981     if (bssp != NULL && (bssp->_class == 7 ||
2982                          (IsPopPhyEtcSet (bssp->_class)))) {
2983       for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
2984         ConvertToCDSCallback (sep, entityID, ccp);
2985       }
2986       return;
2987     }
2988   }
2989   ccp->nsep = FindNucSeqEntry (sep);
2990   if (ccp->nsep == NULL) return;
2991   MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
2992   gs.seglevels = 1;
2993   gs.get_feats_location = FALSE;
2994   MemSet ((Pointer) (gs.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
2995   gs.ignore[OBJ_BIOSEQ] = FALSE;
2996   gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
2997   gs.ignore[OBJ_SEQFEAT] = FALSE;
2998   gs.ignore[OBJ_SEQANNOT] = FALSE;
2999   gs.scope = sep;
3000   ccp->slp = NULL;
3001   GatherEntity (entityID, (Pointer) ccp, CollectCDSAncestorGatherFunc, &gs);
3002   if (ccp->slp != NULL) {
3003     CheckSeqLocForPartial (ccp->slp, &noLeft, &noRight);
3004     sip = SeqLocId (ccp->slp);
3005     if (sip != NULL) {
3006       bsp = BioseqFind (sip);
3007       if (bsp != NULL && ISA_na (bsp->mol)) {
3008         slp = SegLocToParts (bsp, ccp->slp);
3009         if (slp != NULL) {
3010           ccp->slp = SeqLocFree (ccp->slp);
3011           ccp->slp = slp;
3012           FreeAllFuzz (ccp->slp);
3013           SetSeqLocPartial (ccp->slp, noLeft, noRight);
3014         }
3015       }
3016     }
3017     FinishConvertingToCDS (sep, entityID, ccp);
3018     nsep = FindNucSeqEntry (sep);
3019     GetTitle (ccp->geneName, str, sizeof (str));
3020     if (! StringHasNoText (str)) {
3021       grp = CreateNewGeneRef (str, NULL, NULL, FALSE);
3022       if (grp != NULL) {
3023         if (ExtendGene (grp, nsep, ccp->slp)) {
3024           grp = GeneRefFree (grp);
3025         } else {
3026           sfp = CreateNewFeature (nsep, NULL, SEQFEAT_GENE, NULL);
3027           if (sfp != NULL) {
3028             sfp->data.value.ptrvalue = (Pointer) grp;
3029             sfp->location = SeqLocFree (sfp->location);
3030             sfp->location = AsnIoMemCopy ((Pointer) ccp->slp,
3031                                           (AsnReadFunc) SeqLocAsnRead,
3032                                           (AsnWriteFunc) SeqLocAsnWrite);
3033             sip = SeqLocId (sfp->location);
3034             if (sip != NULL) {
3035               bsp = BioseqFind (sip);
3036               if (bsp != NULL) {
3037                 gslp = SeqLocMerge (bsp, sfp->location, NULL, TRUE, FALSE, FALSE);
3038                 if (gslp != NULL) {
3039                   sfp->location = SeqLocFree (sfp->location);
3040                   sfp->location = gslp;
3041                   if (bsp->repr == Seq_repr_seg) {
3042                     gslp = SegLocToPartsEx (bsp, sfp->location, TRUE);
3043                     sfp->location = SeqLocFree (sfp->location);
3044                     sfp->location = gslp;
3045                     hasNulls = LocationHasNullsBetween (sfp->location);
3046                     sfp->partial = (sfp->partial || hasNulls);
3047                   }
3048                   FreeAllFuzz (gslp);
3049                   SetSeqLocPartial (sfp->location, noLeft, noRight);
3050                   sfp->partial = (sfp->partial || noLeft || noRight);
3051                 }
3052               }
3053             }
3054           }
3055         }
3056       }
3057     }
3058   }
3059   ccp->slp = SeqLocFree (ccp->slp);
3060 }
3061 
DoConvertToCDS(ButtoN b)3062 static void DoConvertToCDS (ButtoN b)
3063 
3064 {
3065   ConvCdsPtr  ccp;
3066   CharPtr     plural;
3067   Char        str [128];
3068 
3069   ccp = GetObjectExtra (b);
3070   if (ccp == NULL) {
3071     Remove (ParentWindow (b));
3072     return;
3073   }
3074   GetTitle (ccp->protName, str, sizeof (str));
3075   if (StringHasNoText (str)) {
3076     Message (MSG_OK, "Protein name is required");
3077     return;
3078   }
3079   Hide (ccp->form);
3080   WatchCursor ();
3081 
3082   ccp->omp = ObjMgrGet ();
3083   if (ccp->omp != NULL) {
3084     ccp->omtp = ObjMgrTypeFind (ccp->omp, OBJ_SEQFEAT, NULL, NULL);
3085     if (ccp->omtp != NULL && ccp->omtp->subtypefunc != NULL) {
3086       ConvertToCDSCallback (ccp->sep, ccp->input_entityID, ccp);
3087       if (! GetStatus (ccp->retain)) {
3088         SeqEntryExplore (ccp->sep, (Pointer) ccp, RemoveCDSAncestorCallback);
3089       }
3090     }
3091   }
3092 
3093   ArrowCursor ();
3094   Update ();
3095 
3096   if (ccp->errcount > 0) {
3097     if (ccp->errcount > 1) {
3098       plural = "records";
3099     } else {
3100       plural = "record";
3101     }
3102     Message (MSG_ERROR, "Possible ambiguous frames detected in %d %s",
3103              (int) ccp->errcount, plural);
3104   }
3105 
3106   ObjMgrSetDirtyFlag (ccp->input_entityID, TRUE);
3107   ObjMgrSendMsg (OM_MSG_UPDATE, ccp->input_entityID, 0, 0);
3108   Remove (ccp->form);
3109   Update ();
3110 }
3111 
PrepareToConvertToCDS(SeqEntryPtr sep,Uint2 entityID,Uint2 subtype,CharPtr findthis)3112 extern void PrepareToConvertToCDS (SeqEntryPtr sep, Uint2 entityID,
3113                                    Uint2 subtype, CharPtr findthis)
3114 
3115 {
3116   ButtoN             b;
3117   GrouP              c;
3118   ConvCdsPtr         ccp;
3119   GrouP              g;
3120   GrouP              h;
3121   StdEditorProcsPtr  sepp;
3122   WindoW             w;
3123 
3124   if (sep == NULL || entityID == 0 || subtype == 0) return;
3125 
3126   ccp = (ConvCdsPtr) MemNew (sizeof (ConvCdsData));
3127   if (ccp == NULL) return;
3128   w = FixedWindow (-50, -33, -10, -10, "Convert to CDS", StdCloseWindowProc);
3129   SetObjectExtra (w, ccp, StdCleanupFormProc);
3130   ccp->form = (ForM) w;
3131   ccp->formmessage = DefaultMessageProc;
3132 
3133   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3134   if (sepp != NULL) {
3135     SetActivate (w, sepp->activateForm);
3136     ccp->appmessage = sepp->handleMessages;
3137   }
3138 
3139   ccp->input_entityID = entityID;
3140 
3141   h = HiddenGroup (w, -1, 0, NULL);
3142   SetGroupSpacing (h, 10, 10);
3143 
3144   ccp->sep = sep;
3145   ccp->subtype = subtype;
3146   StringNCpy_0 (ccp->findThis, findthis, sizeof (ccp->findThis));
3147   ccp->errcount = 0;
3148 
3149   g = HiddenGroup (h, 2, 0, NULL);
3150   StaticPrompt (g, "Gene Symbol", 0, dialogTextHeight, programFont, 'l');
3151   ccp->geneName = DialogText (g, "", 20, NULL);
3152   StaticPrompt (g, "Protein Name", 0, dialogTextHeight, programFont, 'l');
3153   ccp->protName = DialogText (g, "", 20, NULL);
3154   StaticPrompt (g, "Comment", 0, 4 * Nlm_stdLineHeight, programFont, 'l');
3155   ccp->featcomment = ScrollText (g, 20, 4, programFont, TRUE, NULL);
3156 
3157   ccp->retain = CheckBox (h, "Retain original features", NULL);
3158 
3159   c = HiddenGroup (h, 4, 0, NULL);
3160   b = DefaultButton (c, "Accept", DoConvertToCDS);
3161   SetObjectExtra (b, ccp, NULL);
3162   PushButton (c, "Cancel", StdCancelButtonProc);
3163 
3164   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, (HANDLE) ccp->retain, NULL);
3165   RealizeWindow (w);
3166   Show (w);
3167   Select (ccp->geneName);
3168   Update ();
3169 }
3170 
3171 typedef struct geneprotfind {
3172   SeqFeatPtr     cds;
3173   SeqFeatPtr     gene;
3174   SeqFeatPtr     prot;
3175   SeqLocPtr      location;
3176   SeqLocPtr      product;
3177   Int4           mingene;
3178   Int4           minprot;
3179 } GeneProtFind, PNTR GeneProtPtr;
3180 
GeneProtFindFunc(GatherContextPtr gcp)3181 static Boolean GeneProtFindFunc (GatherContextPtr gcp)
3182 
3183 {
3184   Int4         diff;
3185   GeneProtPtr  gpp;
3186   SeqFeatPtr   sfp;
3187 
3188   if (gcp == NULL) return TRUE;
3189   gpp = (GeneProtPtr) gcp->userdata;
3190   if (gpp == NULL) return TRUE;
3191   if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
3192   sfp = (SeqFeatPtr) gcp->thisitem;
3193   if (sfp == NULL || sfp->data.value.ptrvalue == NULL) return TRUE;
3194   if (sfp->data.choice == SEQFEAT_GENE && gpp->location != NULL) {
3195     diff = SeqLocAinB (gpp->location, sfp->location);
3196     if (diff >= 0) {
3197       if (diff < gpp->mingene) {
3198         gpp->gene = sfp;
3199         gpp->mingene = diff;
3200       }
3201     }
3202   } else if (sfp->data.choice == SEQFEAT_PROT && gpp->product != NULL) {
3203     diff = SeqLocAinB (gpp->product, sfp->location);
3204     if (diff >= 0) {
3205       if (diff < gpp->minprot) {
3206         gpp->prot = sfp;
3207         gpp->minprot = diff;
3208       }
3209     }
3210   }
3211   return TRUE;
3212 }
3213 
FindGeneAndProtForCDS(Uint2 entityID,SeqFeatPtr cds,SeqFeatPtr PNTR gene,SeqFeatPtr PNTR prot)3214 void FindGeneAndProtForCDS (Uint2 entityID, SeqFeatPtr cds,
3215                             SeqFeatPtr PNTR gene, SeqFeatPtr PNTR prot)
3216 
3217 {
3218   GeneProtFind  gpf;
3219   GatherScope   gs;
3220 
3221   if (gene != NULL) {
3222     *gene = NULL;
3223   }
3224   if (prot != NULL) {
3225     *prot = NULL;
3226   }
3227   if (entityID == 0 || cds == NULL) return;
3228   MemSet ((Pointer) (&gpf), 0, sizeof (GeneProtFind));
3229   gpf.cds = cds;
3230   gpf.gene = NULL;
3231   gpf.prot = NULL;
3232   gpf.location = cds->location;
3233   gpf.product = cds->product;
3234   gpf.mingene = INT4_MAX;
3235   gpf.minprot = INT4_MAX;
3236   MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
3237   gs.seglevels = 1;
3238   gs.get_feats_location = FALSE;
3239   MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
3240   gs.ignore[OBJ_BIOSEQ] = FALSE;
3241   gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
3242   gs.ignore[OBJ_SEQFEAT] = FALSE;
3243   gs.ignore[OBJ_SEQANNOT] = FALSE;
3244   GatherEntity (entityID, (Pointer) &gpf, GeneProtFindFunc, &gs);
3245   if (gene != NULL) {
3246     *gene = gpf.gene;
3247   }
3248   if (prot != NULL) {
3249     *prot = gpf.prot;
3250   }
3251 }
3252 
3253 
3254 #define FIND_ASN   1
3255 #define FIND_FLAT  2
3256 #define FIND_GENE  3
3257 #define FIND_PROT  4
3258 #define FIND_POS   5
3259 
3260 typedef struct findform {
3261   FORM_MESSAGE_BLOCK
3262   TexT            findTxt;
3263   TexT            replaceTxt;
3264   ButtoN          caseCounts;
3265   ButtoN          wholeWord;
3266   ButtoN          doSeqIdLocal;
3267   ButtoN          findAllBtn;
3268   ButtoN          replaceAllBtn;
3269   Int2            type;
3270   ButtoN          findFirstBtn;
3271   ButtoN          findNextBtn;
3272   Int4            last_paragraph_found;
3273   ButtoN          auto_copy;
3274 } FindForm, PNTR FindFormPtr;
3275 
SearchForString(CharPtr str,CharPtr sub,Boolean case_counts,Boolean whole_word)3276 extern CharPtr SearchForString (CharPtr str, CharPtr sub, Boolean case_counts, Boolean whole_word)
3277 
3278 {
3279   CharPtr  ptr = NULL;
3280   CharPtr  tmp;
3281 
3282   if (case_counts) {
3283     ptr = StringSearch (str, sub);
3284   } else {
3285     ptr = StringISearch (str, sub);
3286   }
3287   if (ptr == NULL) return NULL;
3288   if (whole_word) {
3289     if (ptr > str) {
3290       tmp = ptr - 1;
3291       if (! IS_WHITESP (*tmp)) return NULL;
3292     }
3293     tmp = ptr + StringLen (sub);
3294     if (*tmp != '\0' && (! IS_WHITESP (*tmp))) return NULL;
3295   }
3296   return ptr;
3297 }
3298 
3299 
3300 static Int4
FindInFlatFileNext(Asn2gbJobPtr ajp,CharPtr sub,Boolean case_counts,Boolean whole_word,Boolean stop_after_one_found,Int4 start_index)3301 FindInFlatFileNext
3302 (Asn2gbJobPtr ajp,
3303  CharPtr sub,
3304  Boolean case_counts,
3305  Boolean whole_word,
3306  Boolean stop_after_one_found,
3307  Int4    start_index)
3308 {
3309   Int4             index;
3310   CharPtr          string;
3311   BaseBlockPtr     bbp;
3312   SelStructPtr     sel;
3313   unsigned int     entID;
3314   unsigned int     itmID;
3315   unsigned int     itmtype;
3316   Boolean          already = FALSE;
3317 
3318   if (ajp == NULL) return -1;
3319 
3320   for (index = start_index + 1; index < ajp->numParagraphs; index++) {
3321     string = asn2gnbk_format (ajp, (Int4) index);
3322     if (string != NULL && *string != '\0') {
3323       CompressSpaces (string);
3324       if (SearchForString (string, sub, case_counts, whole_word) != NULL) {
3325         bbp = ajp->paragraphArray [index];
3326         if (bbp != NULL) {
3327           entID = bbp->entityID;
3328           itmID = bbp->itemID;
3329           itmtype = bbp->itemtype;
3330           already = FALSE;
3331           for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
3332             if (sel->entityID == entID && sel->itemID == itmID && sel->itemtype == itmtype) {
3333               already = TRUE;
3334             }
3335           }
3336           if (! already) {
3337             ObjMgrAlsoSelect (entID, itmID, itmtype, 0, NULL);
3338             if (stop_after_one_found) return index;
3339           }
3340         }
3341       }
3342     }
3343   }
3344   return -1;
3345 }
3346 
3347 
3348 static Int4
FindInFlatFile(Uint2 entityID,Uint4 itemID,Uint2 itemtype,Uint1 format,Uint1 mode,CharPtr sub,Boolean case_counts,Boolean whole_word,Boolean stop_after_one,Int4 start_index)3349 FindInFlatFile
3350 (Uint2 entityID,
3351  Uint4 itemID,
3352  Uint2 itemtype,
3353  Uint1 format,
3354  Uint1 mode,
3355  CharPtr sub,
3356  Boolean case_counts,
3357  Boolean whole_word,
3358  Boolean stop_after_one,
3359  Int4 start_index)
3360 
3361 {
3362   Asn2gbJobPtr     ajp = NULL;
3363   BioseqPtr        bsp = NULL;
3364   BioseqSetPtr     bssp;
3365   ErrSev           level;
3366   SeqEntryPtr      oldsep;
3367   SeqEntryPtr      sep = NULL;
3368   SeqEntryPtr      topsep;
3369   SeqEntryPtr      usethetop = NULL;
3370   Int4             retval = -1;
3371   FlgType          flags = SHOW_CONTIG_FEATURES | SHOW_CONTIG_SOURCES | SHOW_FAR_TRANSLATION;
3372 
3373   if (itemID == 0) {
3374     sep = GetTopSeqEntryForEntityID (entityID);
3375     usethetop = sep;
3376   } else {
3377     bsp = GetBioseqGivenIDs (entityID, itemID, itemtype);
3378     if (bsp == NULL)
3379       return retval;
3380     sep = SeqMgrGetSeqEntryForData (bsp);
3381     if (bsp->repr == Seq_repr_seg) {
3382       sep = GetBestTopParentForData (entityID, bsp);
3383     }
3384   }
3385 
3386   if (sep == NULL)
3387     return retval;
3388 
3389   level = ErrSetMessageLevel (SEV_MAX);
3390   WatchCursor ();
3391   Update ();
3392 
3393   topsep = GetTopSeqEntryForEntityID (entityID);
3394   oldsep = SeqEntrySetScope (topsep);
3395 
3396   if (usethetop != NULL && IS_Bioseq_set (usethetop)) {
3397     bssp = (BioseqSetPtr) usethetop->data.ptrvalue;
3398     ajp = asn2gnbk_setup (NULL, bssp, NULL, (FmtType) format, (ModType) mode, NORMAL_STYLE, flags, (LckType) 0, (CstType) 0, NULL);
3399   } else if (bsp != NULL) {
3400     ajp = asn2gnbk_setup (bsp, NULL, NULL, (FmtType) format, (ModType) mode, NORMAL_STYLE, flags, (LckType) 0, (CstType) 0, NULL);
3401   }
3402   if (ajp != NULL) {
3403     retval = FindInFlatFileNext (ajp, sub, case_counts, whole_word, stop_after_one, start_index);
3404     asn2gnbk_cleanup (ajp);
3405   }
3406 
3407   SeqEntrySetScope (oldsep);
3408 
3409   ErrSetMessageLevel (level);
3410   ArrowCursor ();
3411   Update ();
3412   return retval;
3413 }
3414 
FindFlatProc(ButtoN b)3415 static void FindFlatProc (ButtoN b)
3416 
3417 {
3418   Boolean      caseCounts;
3419   FindFormPtr  ffp;
3420   CharPtr      findme;
3421   Boolean      wholeWord;
3422 
3423   ffp = (FindFormPtr) GetObjectExtra (b);
3424   if (ffp == NULL) return;
3425   findme = SaveStringFromText (ffp->findTxt);
3426   ObjMgrDeSelect (0, 0, 0, 0, NULL);
3427   caseCounts = GetStatus (ffp->caseCounts);
3428   wholeWord = GetStatus (ffp->wholeWord);
3429   CompressSpaces (findme);
3430   ffp->last_paragraph_found = FindInFlatFile (ffp->input_entityID, ffp->input_itemID,
3431                   ffp->input_itemtype, GENBANK_FMT, SEQUIN_MODE,
3432                   findme, caseCounts, wholeWord, FALSE, -1);
3433   MemFree (findme);
3434 }
3435 
FindFlatProcFirst(ButtoN b)3436 static void FindFlatProcFirst (ButtoN b)
3437 
3438 {
3439   Boolean      caseCounts;
3440   FindFormPtr  ffp;
3441   CharPtr      findme;
3442   Boolean      wholeWord;
3443 
3444   ffp = (FindFormPtr) GetObjectExtra (b);
3445   if (ffp == NULL) return;
3446   findme = SaveStringFromText (ffp->findTxt);
3447   ObjMgrDeSelect (0, 0, 0, 0, NULL);
3448   caseCounts = GetStatus (ffp->caseCounts);
3449   wholeWord = GetStatus (ffp->wholeWord);
3450   CompressSpaces (findme);
3451   ffp->last_paragraph_found = FindInFlatFile (ffp->input_entityID, ffp->input_itemID,
3452                   ffp->input_itemtype, GENBANK_FMT, SEQUIN_MODE,
3453                   findme, caseCounts, wholeWord, TRUE, -1);
3454   MemFree (findme);
3455 }
3456 
FindFlatProcNext(ButtoN b)3457 static void FindFlatProcNext (ButtoN b)
3458 
3459 {
3460   Boolean      caseCounts;
3461   FindFormPtr  ffp;
3462   CharPtr      findme;
3463   Boolean      wholeWord;
3464 
3465   ffp = (FindFormPtr) GetObjectExtra (b);
3466   if (ffp == NULL) return;
3467   findme = SaveStringFromText (ffp->findTxt);
3468   ObjMgrDeSelect (0, 0, 0, 0, NULL);
3469   caseCounts = GetStatus (ffp->caseCounts);
3470   wholeWord = GetStatus (ffp->wholeWord);
3471   CompressSpaces (findme);
3472   ffp->last_paragraph_found = FindInFlatFile (ffp->input_entityID, ffp->input_itemID,
3473                   ffp->input_itemtype, GENBANK_FMT, SEQUIN_MODE,
3474                   findme, caseCounts, wholeWord, TRUE, ffp->last_paragraph_found);
3475   MemFree (findme);
3476 }
3477 
FindTextProc(TexT t)3478 static void FindTextProc (TexT t)
3479 
3480 {
3481   FindFormPtr  ffp;
3482   CharPtr      str;
3483 
3484   ffp = (FindFormPtr) GetObjectExtra (t);
3485   if (ffp != NULL) {
3486     if (TextLength (t) > 0) {
3487       SafeEnable (ffp->findAllBtn);
3488       SafeEnable (ffp->replaceAllBtn);
3489       if (ffp->type == FIND_FLAT) {
3490         SafeEnable (ffp->findFirstBtn);
3491         SafeEnable (ffp->findNextBtn);
3492       }
3493       if (ffp->type == FIND_GENE || ffp->type == FIND_PROT) {
3494         SafeEnable (ffp->findFirstBtn);
3495       }
3496       if (ffp->auto_copy != NULL && GetStatus (ffp->auto_copy)) {
3497         str = SaveStringFromText (t);
3498         SetTitle (ffp->replaceTxt, str);
3499         str = MemFree (str);
3500       }
3501     } else {
3502       SafeDisable (ffp->findAllBtn);
3503       SafeDisable (ffp->replaceAllBtn);
3504       if (ffp->type == FIND_FLAT) {
3505         SafeDisable (ffp->findFirstBtn);
3506         SafeDisable (ffp->findNextBtn);
3507       }
3508       if (ffp->type == FIND_GENE || ffp->type == FIND_PROT) {
3509         SafeDisable (ffp->findFirstBtn);
3510       }
3511     }
3512   }
3513 }
3514 
CommonFindReplaceProc(ButtoN b,Boolean replace,Boolean replaceAll)3515 static void CommonFindReplaceProc (ButtoN b, Boolean replace, Boolean replaceAll)
3516 
3517 {
3518   Boolean      caseCounts;
3519   CharPtr      changeme;
3520   Boolean      doSeqIdLocal;
3521   FindFormPtr  ffp;
3522   CharPtr      findme;
3523   Boolean      wholeWord;
3524 
3525   ffp = (FindFormPtr) GetObjectExtra (b);
3526   if (ffp != NULL) {
3527     findme = JustSaveStringFromText (ffp->findTxt);
3528     ObjMgrDeSelect (0, 0, 0, 0, NULL);
3529     caseCounts = GetStatus (ffp->caseCounts);
3530     wholeWord = GetStatus (ffp->wholeWord);
3531     doSeqIdLocal = GetStatus (ffp->doSeqIdLocal);
3532     if (replace) {
3533       changeme = JustSaveStringFromText (ffp->replaceTxt);
3534       FindReplaceInEntity (ffp->input_entityID, findme, changeme, caseCounts, wholeWord, replaceAll,
3535                            FALSE, UPDATE_ONCE, NULL, NULL, NULL, doSeqIdLocal, NULL, NULL);
3536       GetRidOfEmptyFeatsDescStrings (ffp->input_entityID, NULL);
3537       ObjMgrSetDirtyFlag (ffp->input_entityID, TRUE);
3538       ObjMgrSendMsg (OM_MSG_UPDATE, ffp->input_entityID, 0, 0);
3539       MemFree (changeme);
3540     } else {
3541       FindReplaceInEntity (ffp->input_entityID, findme, NULL, caseCounts, wholeWord, FALSE,
3542                            TRUE, UPDATE_ONCE, NULL, NULL, NULL, doSeqIdLocal, NULL, NULL);
3543     }
3544     MemFree (findme);
3545     Update ();
3546   }
3547 }
3548 
FindAllProc(ButtoN b)3549 static void FindAllProc (ButtoN b)
3550 
3551 {
3552   CommonFindReplaceProc (b, FALSE, FALSE);
3553 }
3554 
ReplaceAllProc(ButtoN b)3555 static void ReplaceAllProc (ButtoN b)
3556 
3557 {
3558   CommonFindReplaceProc (b, TRUE, TRUE);
3559 }
3560 
3561 static SeqFeatPtr
FindNthFeatureOnBspByLabel(BioseqPtr bsp,CharPtr label,Uint1 seqFeatChoice,Uint1 featDefChoice,Int4 n,Int4 PNTR last_found,SeqMgrFeatContext PNTR context)3562 FindNthFeatureOnBspByLabel
3563 (BioseqPtr              bsp,
3564  CharPtr                label,
3565  Uint1                  seqFeatChoice,
3566  Uint1                  featDefChoice,
3567  Int4                   n,
3568  Int4 PNTR              last_found,
3569  SeqMgrFeatContext PNTR context)
3570 {
3571   SMFeatItemPtr PNTR  array;
3572   BioseqExtraPtr      bspextra;
3573   Uint2               entityID;
3574   SMFeatItemPtr       feat;
3575   Int4                L;
3576   Int4                mid;
3577   Int4                num;
3578   ObjMgrDataPtr       omdp;
3579   Int4                R;
3580   SeqFeatPtr          sfp;
3581   Uint1               seqfeattype;
3582   Int4                index = 0;
3583 
3584   if (context != NULL) {
3585     MemSet ((Pointer) context, 0, sizeof (SeqMgrFeatContext));
3586   }
3587   if (last_found != NULL) {
3588     *last_found = -1;
3589   }
3590 
3591   if (bsp == NULL || StringHasNoText (label)) return NULL;
3592 
3593   omdp = SeqMgrGetOmdpForBioseq (bsp);
3594   if (omdp == NULL || omdp->datatype != OBJ_BIOSEQ) return NULL;
3595 
3596   bspextra = (BioseqExtraPtr) omdp->extradata;
3597   if (bspextra == NULL) return NULL;
3598   array = bspextra->featsByLabel;
3599   num = bspextra->numfeats;
3600 
3601   if (array == NULL || num < 1) return NULL;
3602 
3603   if (n < 0 || n > bspextra->numfeats) return NULL;
3604 
3605   entityID = ObjMgrGetEntityIDForPointer (omdp->dataptr);
3606 
3607   /* binary search to leftmost candidate within the featsByLabel array */
3608 
3609   L = 0;
3610   R = num - 1;
3611   while (L < R) {
3612     mid = (L + R) / 2;
3613     feat = array [mid];
3614     if (feat != NULL && StringICmp (feat->label, label) < 0) {
3615       L = mid + 1;
3616     } else {
3617       R = mid;
3618     }
3619   }
3620 
3621   feat = array [R];
3622 
3623   /* linear scan to find desired label on desired feature type */
3624 
3625   while (R < num && feat != NULL && StringICmp (feat->label, label) == 0) {
3626     sfp = feat->sfp;
3627     if (sfp != NULL) {
3628       seqfeattype = sfp->data.choice;
3629       if ((seqFeatChoice == 0 || seqfeattype == seqFeatChoice) &&
3630           (featDefChoice == 0 || feat->subtype == featDefChoice) &&
3631           (! feat->ignore)) {
3632         if (context != NULL) {
3633           context->entityID = entityID;
3634           context->itemID = feat->itemID;
3635           context->sfp = sfp;
3636           context->sap = feat->sap;
3637           context->bsp = feat->bsp;
3638           context->label = feat->label;
3639           context->left = feat->left;
3640           context->right = feat->right;
3641           context->dnaStop = feat->dnaStop;
3642           context->partialL = feat->partialL;
3643           context->partialR = feat->partialR;
3644           context->farloc = feat->farloc;
3645           context->strand = feat->strand;
3646           context->seqfeattype = seqfeattype;
3647           context->featdeftype = feat->subtype;
3648           context->numivals = feat->numivals;
3649           context->ivals = feat->ivals;
3650           context->userdata = NULL;
3651           context->omdp = (Pointer) omdp;
3652           context->index = R + 1;
3653         }
3654         if (index == n) {
3655           if (last_found != NULL) {
3656             *last_found = index;
3657           }
3658           return sfp;
3659         } else {
3660           if (last_found != NULL) {
3661             *last_found = index;
3662           }
3663           index++;
3664         }
3665       }
3666     }
3667 
3668     R++;
3669     feat = array [R];
3670   }
3671 
3672   return NULL;
3673 }
3674 
3675 typedef struct findnthfeatdata {
3676   CharPtr                findme;
3677   Uint1                  seqFeatChoice;
3678   Uint1                  featDefChoice;
3679   Int4                   n;
3680   Int4                   passed_so_far;
3681   SeqMgrFeatContext PNTR context;
3682   SeqFeatPtr             sfp;
3683 } FindNthFeatData, PNTR FindNthFeatPtr;
3684 
FindNthFeatureByLabelInSeqEntryBspProc(BioseqPtr bsp,Pointer userdata)3685 static void FindNthFeatureByLabelInSeqEntryBspProc (BioseqPtr bsp, Pointer userdata)
3686 {
3687   FindNthFeatPtr fnfp;
3688   Int4           this_search_index;
3689   Int4           passed_this_bsp = 0;
3690 
3691   if (bsp == NULL || (fnfp = (FindNthFeatPtr)userdata) == NULL
3692       || fnfp->sfp != NULL) {
3693     return;
3694   }
3695 
3696   this_search_index = fnfp->n - fnfp->passed_so_far;
3697 
3698   if (fnfp->seqFeatChoice == SEQFEAT_GENE || fnfp->featDefChoice == FEATDEF_GENE) {
3699     fnfp->sfp = FindNthGeneOnBspByLabelOrLocusTag (bsp,
3700                                                    fnfp->findme,
3701                                                    this_search_index,
3702                                                    &passed_this_bsp,
3703                                                    fnfp->context);
3704   } else {
3705     fnfp->sfp = FindNthFeatureOnBspByLabel (bsp,
3706                                             fnfp->findme,
3707                                             fnfp->seqFeatChoice,
3708                                             fnfp->featDefChoice,
3709                                             this_search_index,
3710                                             &passed_this_bsp,
3711                                             fnfp->context);
3712   }
3713   if (fnfp->sfp == NULL) {
3714     fnfp->passed_so_far += passed_this_bsp;
3715   }
3716 }
3717 
FindNthFeatureByLabelInSeqEntry(SeqEntryPtr sep,CharPtr findme,Uint1 seqFeatChoice,Uint1 featDefChoice,Int4 n,SeqMgrFeatContext PNTR context)3718 static SeqFeatPtr FindNthFeatureByLabelInSeqEntry
3719 (SeqEntryPtr            sep,
3720  CharPtr                findme,
3721  Uint1                  seqFeatChoice,
3722  Uint1                  featDefChoice,
3723  Int4                   n,
3724  SeqMgrFeatContext PNTR context)
3725 {
3726   FindNthFeatData fnf;
3727 
3728   fnf.findme = findme;
3729   fnf.seqFeatChoice = seqFeatChoice;
3730   fnf.featDefChoice = featDefChoice;
3731   fnf.n = n;
3732   fnf.context = context;
3733   fnf.passed_so_far = 0;
3734   fnf.sfp = NULL;
3735 
3736   VisitBioseqsInSep (sep, &fnf, FindNthFeatureByLabelInSeqEntryBspProc);
3737 
3738   return fnf.sfp;
3739 }
3740 
FindByLabelOrPosProc(ButtoN b)3741 static void FindByLabelOrPosProc (ButtoN b)
3742 
3743 {
3744   Boolean            already;
3745   BioseqPtr          bsp = NULL;
3746   SeqMgrFeatContext  context;
3747   FindFormPtr        ffp;
3748   CharPtr            findme;
3749   SelStructPtr       sel;
3750   SeqEntryPtr        sep = NULL;
3751   SeqFeatPtr         sfp = NULL;
3752   Int4               val;
3753 
3754   ffp = (FindFormPtr) GetObjectExtra (b);
3755   if (ffp == NULL) return;
3756 
3757   if (ffp->input_itemID == 0) {
3758     sep = GetTopSeqEntryForEntityID (ffp->input_entityID);
3759   } else {
3760     bsp = GetBioseqGivenIDs (ffp->input_entityID, ffp->input_itemID, ffp->input_itemtype);
3761     if (bsp == NULL) return;
3762     sep = SeqMgrGetSeqEntryForData (bsp);
3763     if (bsp->repr == Seq_repr_seg) {
3764       sep = GetBestTopParentForData (ffp->input_entityID, bsp);
3765     }
3766   }
3767   if (sep == NULL) return;
3768 
3769   findme = SaveStringFromText (ffp->findTxt);
3770   ObjMgrDeSelect (0, 0, 0, 0, NULL);
3771   CompressSpaces (findme);
3772 
3773   switch (ffp->type) {
3774     case FIND_GENE :
3775       sfp = FindNthFeatureByLabelInSeqEntry (sep, findme, SEQFEAT_GENE, 0,
3776                                              ffp->last_paragraph_found + 1,
3777                                              &context);
3778       if (sfp == NULL) {
3779         if (ffp->last_paragraph_found > -1) {
3780           Message (MSG_OK, "No more found");
3781         } else {
3782           Message (MSG_OK, "No matches found");
3783         }
3784         ffp->last_paragraph_found = -1;
3785       } else {
3786         ffp->last_paragraph_found ++;
3787       }
3788       break;
3789     case FIND_PROT :
3790       sfp = FindNthFeatureByLabelInSeqEntry (sep, findme, SEQFEAT_CDREGION, 0,
3791                                              ffp->last_paragraph_found + 1,
3792                                              &context);
3793       if (sfp == NULL) {
3794         ffp->last_paragraph_found = -1;
3795       } else {
3796         ffp->last_paragraph_found ++;
3797       }
3798       break;
3799     case FIND_POS :
3800       if (StrToLong (findme, &val)) {
3801         if (bsp != NULL && val > 0 && val <= bsp->length) {
3802           val--;
3803           sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
3804           while (sfp != NULL) {
3805             if (context.left >= val) break;
3806             sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
3807           }
3808         }
3809       }
3810       break;
3811     default :
3812       break;
3813   }
3814 
3815   MemFree (findme);
3816 
3817   if (sfp == NULL) return;
3818 
3819   already = FALSE;
3820   for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
3821     if (sel->entityID == context.entityID &&
3822         sel->itemID == context.itemID &&
3823         sel->itemtype == OBJ_SEQFEAT) {
3824       already = TRUE;
3825     }
3826   }
3827   if (! already) {
3828     ObjMgrAlsoSelect (context.entityID, context.itemID, OBJ_SEQFEAT, 0, NULL);
3829   }
3830 
3831 }
3832 
FindByLabelOrPosProcFindFirst(ButtoN b)3833 static void FindByLabelOrPosProcFindFirst (ButtoN b)
3834 {
3835   FindFormPtr ffp;
3836 
3837   ffp = (FindFormPtr) GetObjectExtra (b);
3838   if (ffp == NULL) return;
3839   ffp->last_paragraph_found = -1;
3840   FindByLabelOrPosProc (b);
3841 }
3842 
ClearFindTextProc(ButtoN b)3843 static void ClearFindTextProc (ButtoN b)
3844 
3845 {
3846   FindFormPtr  ffp;
3847 
3848   ffp = (FindFormPtr) GetObjectExtra (b);
3849   if (ffp == NULL) return;
3850   SafeSetTitle (ffp->findTxt, "");
3851   SafeSetTitle (ffp->replaceTxt, "");
3852   if (ffp->type == FIND_FLAT) {
3853     ObjMgrDeSelect (0, 0, 0, 0, NULL);
3854     ffp->last_paragraph_found = -1;
3855   }
3856   FindTextProc (ffp->findTxt);
3857   Select (ffp->findTxt);
3858 }
3859 
FindFormMessage(ForM f,Int2 mssg)3860 static void FindFormMessage (ForM f, Int2 mssg)
3861 
3862 {
3863   FindFormPtr  ffp;
3864 
3865   ffp = (FindFormPtr) GetObjectExtra (f);
3866   if (ffp != NULL) {
3867     switch (mssg) {
3868       case VIB_MSG_CLOSE :
3869         Remove (f);
3870         break;
3871       case VIB_MSG_CUT :
3872         StdCutTextProc (NULL);
3873         break;
3874       case VIB_MSG_COPY :
3875         StdCopyTextProc (NULL);
3876         break;
3877       case VIB_MSG_PASTE :
3878         StdPasteTextProc (NULL);
3879         break;
3880       case VIB_MSG_DELETE :
3881         StdDeleteTextProc (NULL);
3882         break;
3883       default :
3884         if (ffp->appmessage != NULL) {
3885           ffp->appmessage (f, mssg);
3886         }
3887         break;
3888     }
3889   }
3890 }
3891 
CopyFindReplBtn(ButtoN b)3892 static void CopyFindReplBtn (ButtoN b)
3893 {
3894   FindFormPtr ffp;
3895   CharPtr     str;
3896 
3897   ffp = (FindFormPtr) GetObjectExtra (b);
3898   if (ffp == NULL)
3899   {
3900     return;
3901   }
3902   str = JustSaveStringFromText (ffp->findTxt);
3903   SetTitle (ffp->replaceTxt, str);
3904   str = MemFree (str);
3905 }
3906 
3907 
SetAutoCopy(ButtoN b)3908 static void SetAutoCopy (ButtoN b)
3909 {
3910   FindFormPtr ffp;
3911 
3912   ffp = (FindFormPtr) GetObjectExtra (b);
3913   if (ffp == NULL) {
3914     return;
3915   }
3916   if (GetStatus (ffp->auto_copy)) {
3917     SetAppParam ("SEQUINCUSTOM", "SETTINGS", "FIND_REPLACE_AUTOCOPY", "TRUE");
3918   } else {
3919     SetAppParam ("SEQUINCUSTOM", "SETTINGS", "FIND_REPLACE_AUTOCOPY", "FALSE");
3920   }
3921 }
3922 
3923 
CreateFindForm(Int2 left,Int2 top,CharPtr title,Uint2 entityID,Uint4 itemID,Uint2 itemtype,Int2 type)3924 static ForM CreateFindForm (Int2 left, Int2 top, CharPtr title,
3925                             Uint2 entityID, Uint4 itemID, Uint2 itemtype,
3926                             Int2 type)
3927 
3928 {
3929   ButtoN             b;
3930   GrouP              c;
3931   GrouP              g;
3932   FindFormPtr        ffp;
3933   GrouP              j;
3934   GrouP              q = NULL;
3935   StdEditorProcsPtr  sepp;
3936   WindoW             w;
3937   Char               str[100];
3938 
3939   w = NULL;
3940   ffp = MemNew (sizeof (FindForm));
3941   if (ffp != NULL) {
3942     w = FixedWindow (left, top, -10, -10, title, StdCloseWindowProc);
3943     SetObjectExtra (w, ffp, StdCleanupFormProc);
3944     ffp->form = (ForM) w;
3945     ffp->formmessage = FindFormMessage;
3946     ffp->input_entityID = entityID;
3947     ffp->input_itemID = itemID;
3948     ffp->input_itemtype = itemtype;
3949     ffp->type = type;
3950     ffp->last_paragraph_found = -1;
3951 
3952 #ifndef WIN_MAC
3953     CreateStdEditorFormMenus (w);
3954 #endif
3955 
3956     sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3957     if (sepp != NULL) {
3958       SetActivate (w, sepp->activateForm);
3959       ffp->appmessage = sepp->handleMessages;
3960     }
3961 
3962     j = HiddenGroup (w, -1, 0, NULL);
3963     SetGroupSpacing (j, 10, 10);
3964 
3965     g = HiddenGroup (j, 4, 0, NULL);
3966     StaticPrompt (g, "Find", 0, dialogTextHeight, programFont, 'l');
3967     ffp->findTxt = DialogText (g, "", 25, FindTextProc);
3968     SetObjectExtra (ffp->findTxt, ffp, NULL);
3969     StaticPrompt (g, "", 0, 0, programFont, 'l');
3970     StaticPrompt (g, "", 0, 0, programFont, 'l');
3971     if (type == FIND_ASN) {
3972       StaticPrompt (g, "Replace", 0, dialogTextHeight, programFont, 'l');
3973       ffp->replaceTxt = DialogText (g, "", 25, NULL);
3974       SetObjectExtra (ffp->replaceTxt, ffp, NULL);
3975       b = PushButton (g, "Copy", CopyFindReplBtn);
3976       SetObjectExtra (b, ffp, NULL);
3977       ffp->auto_copy = CheckBox (g, "Auto-copy", SetAutoCopy);
3978       SetObjectExtra (ffp->auto_copy, ffp, NULL);
3979       if (GetAppParam ("SEQUINCUSTOM", "SETTINGS", "FIND_REPLACE_AUTOCOPY", NULL, str, sizeof (str))) {
3980         if (StringICmp (str, "TRUE") == 0) {
3981           SetStatus (ffp->auto_copy, TRUE);
3982         } else {
3983           SetStatus (ffp->auto_copy, FALSE);
3984         }
3985       }
3986     }
3987 
3988     if (type == FIND_ASN || type == FIND_FLAT) {
3989       q = HiddenGroup (w, 3, 0, NULL);
3990       ffp->caseCounts = CheckBox (q, "Case Sensitive", NULL);
3991       ffp->wholeWord = CheckBox (q, "Entire Word", NULL);
3992       if (indexerVersion && type == FIND_ASN) {
3993         ffp->doSeqIdLocal = CheckBox (q, "SeqID LOCAL", NULL);
3994       }
3995     }
3996 
3997     c = HiddenGroup (w, 5, 0, NULL);
3998     SetGroupSpacing (c, 10, 2);
3999     if (type == FIND_ASN) {
4000       ffp->findAllBtn = DefaultButton (c, "Find All", FindAllProc);
4001       SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4002       Disable (ffp->findAllBtn);
4003       ffp->replaceAllBtn = PushButton (c, "Replace All", ReplaceAllProc);
4004       SetObjectExtra (ffp->replaceAllBtn, ffp, NULL);
4005       Disable (ffp->replaceAllBtn);
4006     } else if (type == FIND_FLAT) {
4007       ffp->findFirstBtn = PushButton (c, "Find First", FindFlatProcFirst);
4008       SetObjectExtra (ffp->findFirstBtn, ffp, NULL);
4009       Disable (ffp->findFirstBtn);
4010       ffp->findNextBtn = PushButton (c, "Find Next", FindFlatProcNext);
4011       SetObjectExtra (ffp->findNextBtn, ffp, NULL);
4012       Disable (ffp->findNextBtn);
4013       ffp->findAllBtn = DefaultButton (c, "Find All", FindFlatProc);
4014       SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4015       Disable (ffp->findAllBtn);
4016     } else if (type == FIND_GENE) {
4017       ffp->findFirstBtn = DefaultButton (c, "Find First Gene", FindByLabelOrPosProcFindFirst);
4018       SetObjectExtra (ffp->findFirstBtn, ffp, NULL);
4019       Disable (ffp->findFirstBtn);
4020       ffp->findAllBtn = PushButton (c, "Find Next Gene", FindByLabelOrPosProc);
4021       SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4022       Disable (ffp->findAllBtn);
4023     } else if (type == FIND_PROT) {
4024      ffp->findFirstBtn = DefaultButton (c, "Find First Protein", FindByLabelOrPosProcFindFirst);
4025       SetObjectExtra (ffp->findFirstBtn, ffp, NULL);
4026       Disable (ffp->findFirstBtn);
4027       ffp->findAllBtn = PushButton (c, "Find Next Protein", FindByLabelOrPosProc);
4028       SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4029       Disable (ffp->findAllBtn);
4030     } else if (type == FIND_POS) {
4031       ffp->findAllBtn = DefaultButton (c, "Find by Position", FindByLabelOrPosProc);
4032       SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4033       Disable (ffp->findAllBtn);
4034     }
4035     b = PushButton (c, "Clear", ClearFindTextProc);
4036     SetObjectExtra (b, ffp, NULL);
4037     PushButton (c, "Cancel", StdCancelButtonProc);
4038 
4039     AlignObjects (ALIGN_CENTER, (HANDLE) j, (HANDLE) c, (HANDLE) q, NULL);
4040 
4041     RealizeWindow (w);
4042     Select (ffp->findTxt);
4043   }
4044   return (ForM) w;
4045 }
4046 
FindStringProc(IteM i)4047 extern void FindStringProc (IteM i)
4048 
4049 {
4050   BaseFormPtr  bfp;
4051   ForM         w;
4052 
4053 #ifdef WIN_MAC
4054   bfp = currentFormDataPtr;
4055 #else
4056   bfp = GetObjectExtra (i);
4057 #endif
4058   if (bfp != NULL) {
4059     w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4060                         bfp->input_itemID, bfp->input_itemtype, FIND_ASN);
4061     Show (w);
4062     Select (w);
4063   }
4064 }
4065 
FindStringProcToolBtn(ButtoN b)4066 extern void FindStringProcToolBtn (ButtoN b)
4067 
4068 {
4069   BaseFormPtr  bfp;
4070   ForM         w;
4071 
4072   bfp = (BaseFormPtr) GetObjectExtra (b);
4073   if (bfp == NULL) return;
4074 
4075   w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4076                       bfp->input_itemID, bfp->input_itemtype, FIND_ASN);
4077   Show (w);
4078   Select (w);
4079 
4080 }
4081 
4082 
FindFlatfileProcToolBtn(ButtoN b)4083 extern void FindFlatfileProcToolBtn (ButtoN b)
4084 
4085 {
4086   BaseFormPtr  bfp;
4087   ForM         w;
4088 
4089   bfp = (BaseFormPtr) GetObjectExtra (b);
4090   if (bfp == NULL) return;
4091 
4092   w = CreateFindForm (-90, -66, "Flat File Find", bfp->input_entityID,
4093                       bfp->input_itemID, bfp->input_itemtype, FIND_FLAT);
4094   Show (w);
4095   Select (w);
4096 
4097 }
4098 
4099 
FindFlatfileProc(IteM i)4100 extern void FindFlatfileProc (IteM i)
4101 
4102 {
4103   BaseFormPtr  bfp;
4104   ForM         w;
4105 
4106 #ifdef WIN_MAC
4107   bfp = currentFormDataPtr;
4108 #else
4109   bfp = GetObjectExtra (i);
4110 #endif
4111   if (bfp != NULL) {
4112     w = CreateFindForm (-90, -66, "Flat File Find", bfp->input_entityID,
4113                         bfp->input_itemID, bfp->input_itemtype, FIND_FLAT);
4114     Show (w);
4115     Select (w);
4116   }
4117 }
4118 
FindGeneProc(IteM i)4119 extern void FindGeneProc (IteM i)
4120 
4121 {
4122   BaseFormPtr  bfp;
4123   ForM         w;
4124 
4125 #ifdef WIN_MAC
4126   bfp = currentFormDataPtr;
4127 #else
4128   bfp = GetObjectExtra (i);
4129 #endif
4130   if (bfp != NULL) {
4131     w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4132                         bfp->input_itemID, bfp->input_itemtype, FIND_GENE);
4133     Show (w);
4134     Select (w);
4135   }
4136 }
4137 
FindProtProc(IteM i)4138 extern void FindProtProc (IteM i)
4139 
4140 {
4141   BaseFormPtr  bfp;
4142   ForM         w;
4143 
4144 #ifdef WIN_MAC
4145   bfp = currentFormDataPtr;
4146 #else
4147   bfp = GetObjectExtra (i);
4148 #endif
4149   if (bfp != NULL) {
4150     w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4151                         bfp->input_itemID, bfp->input_itemtype, FIND_PROT);
4152     Show (w);
4153     Select (w);
4154   }
4155 }
4156 
FindPosProc(IteM i)4157 extern void FindPosProc (IteM i)
4158 
4159 {
4160   BaseFormPtr  bfp;
4161   ForM         w;
4162 
4163 #ifdef WIN_MAC
4164   bfp = currentFormDataPtr;
4165 #else
4166   bfp = GetObjectExtra (i);
4167 #endif
4168   if (bfp != NULL) {
4169     w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4170                         bfp->input_itemID, bfp->input_itemtype, FIND_POS);
4171     Show (w);
4172     Select (w);
4173   }
4174 }
4175 
RemoveRedundantSourceNote(CharPtr str,CharPtr keyword,CharPtr name)4176 static void RemoveRedundantSourceNote (CharPtr str, CharPtr keyword, CharPtr name)
4177 
4178 {
4179   Char     ch;
4180   Boolean  extract;
4181   CharPtr  tmp1, tmp2;
4182 
4183   if (str == NULL || keyword == NULL || name == NULL) return;
4184   while (str != NULL && *str != '\0') {
4185     extract = TRUE;
4186     tmp1 = str;
4187     ch = *tmp1;
4188     while (ch == ' ' || ch == ';') {
4189       tmp1++;
4190       ch = *tmp1;
4191     }
4192     tmp2 = keyword;
4193     ch = TO_UPPER (*tmp1);
4194     while (ch != '\0' && ch == TO_UPPER (*tmp2)) {
4195       tmp1++;
4196       tmp2++;
4197       ch = TO_UPPER (*tmp1);
4198     }
4199     if (*tmp2 == '\0' && ch == ' ') {
4200       while (ch != '\0' && ch == ' ') {
4201         tmp1++;
4202         ch = *tmp1;
4203       }
4204       tmp2 = name;
4205       while (ch != '\0' && ch == *tmp2) {
4206         tmp1++;
4207         tmp2++;
4208         ch = *tmp1;
4209       }
4210       if (*tmp2 == '\0' && (ch == '\0' || ch == ' ' || ch == ';')) {
4211         while (ch != '\0' && ch == ' ') {
4212           tmp1++;
4213           ch = *tmp1;
4214         }
4215         /* now ready to extract */
4216       } else {
4217         extract = FALSE;
4218       }
4219     } else {
4220       extract = FALSE;
4221     }
4222     if (extract) {
4223       while (ch == ' ' || ch == ';') {
4224         tmp1++;
4225         ch = *tmp1;
4226       }
4227       tmp2 = str;
4228       while (ch != '\0') {
4229         *tmp2 = ch;
4230         tmp1++;
4231         tmp2++;
4232         ch = *tmp1;
4233       }
4234       *tmp2 = '\0';
4235     } else {
4236       ch = *tmp1;
4237       while (ch != '\0' && ch != ';') {
4238         tmp1++;
4239         ch = *tmp1;
4240       }
4241       if (ch == ';') {
4242         tmp1++;
4243         ch = *tmp1;
4244       }
4245       while (ch != '\0' && (ch == ' ' || ch == ';')) {
4246         tmp1++;
4247         ch = *tmp1;
4248       }
4249       str = tmp1;
4250     }
4251   }
4252 }
4253 
TrimSpacesAndSemicolonsAroundString(CharPtr str)4254 static CharPtr TrimSpacesAndSemicolonsAroundString (CharPtr str)
4255 
4256 {
4257   Uchar    ch;	/* to use 8bit characters in multibyte languages */
4258   CharPtr  dst;
4259   CharPtr  ptr;
4260 
4261   if (str != NULL && str [0] != '\0') {
4262     dst = str;
4263     ptr = str;
4264     ch = *ptr;
4265     while (ch != '\0' && (ch <= ' ' || ch == ';')) {
4266       ptr++;
4267       ch = *ptr;
4268     }
4269     while (ch != '\0') {
4270       *dst = ch;
4271       dst++;
4272       ptr++;
4273       ch = *ptr;
4274     }
4275     *dst = '\0';
4276     dst = NULL;
4277     ptr = str;
4278     ch = *ptr;
4279     while (ch != '\0') {
4280       if (ch != ' ' && ch != ';') {
4281         dst = NULL;
4282       } else if (dst == NULL) {
4283         dst = ptr;
4284       }
4285       ptr++;
4286       ch = *ptr;
4287     }
4288     if (dst != NULL) {
4289       *dst = '\0';
4290     }
4291   }
4292   return str;
4293 }
4294 
4295 extern void GetRidOfRedundantSourceNotes (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent);
GetRidOfRedundantSourceNotes(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)4296 extern void GetRidOfRedundantSourceNotes (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4297 
4298 {
4299   BioSourcePtr       biop;
4300   BioseqPtr          bsp;
4301   BioseqSetPtr       bssp;
4302   OrgModPtr          mod;
4303   OrgNamePtr         onp;
4304   OrgRefPtr          orp;
4305   ValNodePtr         sdp;
4306   SubSourcePtr       ssp;
4307   CharPtr            str1, str2;
4308 
4309   if (sep == NULL || sep->data.ptrvalue == NULL) return;
4310   if (IS_Bioseq (sep)) {
4311     bsp = (BioseqPtr) sep->data.ptrvalue;
4312     sdp = bsp->descr;
4313   } else if (IS_Bioseq_set (sep)) {
4314     bssp = (BioseqSetPtr) sep->data.ptrvalue;
4315     sdp = bssp->descr;
4316   } else return;
4317   while (sdp != NULL) {
4318     if (sdp->choice == Seq_descr_source) {
4319       str1 = NULL;
4320       str2 = NULL;
4321       onp = NULL;
4322       biop = (BioSourcePtr) sdp->data.ptrvalue;
4323       if (biop != NULL) {
4324         orp = biop->org;
4325         if (orp != NULL) {
4326           onp = orp->orgname;
4327           if (onp != NULL) {
4328             mod = onp->mod;
4329             while (mod != NULL) {
4330               if (mod->subtype == 255) {
4331                 str1 = mod->subname;
4332               }
4333               mod = mod->next;
4334             }
4335           }
4336         }
4337         ssp = biop->subtype;
4338         while (ssp != NULL) {
4339           if (ssp->subtype == 255) {
4340             str2 = ssp->name;
4341           }
4342           ssp = ssp->next;
4343         }
4344         if (str1 != NULL || str2 != NULL) {
4345           if (onp != NULL) {
4346             mod = onp->mod;
4347             while (mod != NULL) {
4348               if (mod->subtype != 255) {
4349                 RemoveRedundantSourceNote (str1, GetOrgModQualName (mod->subtype), mod->subname);
4350                 RemoveRedundantSourceNote (str2, GetOrgModQualName (mod->subtype), mod->subname);
4351               }
4352               mod = mod->next;
4353             }
4354           }
4355           ssp = biop->subtype;
4356           while (ssp != NULL) {
4357             if (ssp->subtype != 255) {
4358               RemoveRedundantSourceNote (str1, GetSubsourceQualName (ssp->subtype), ssp->name);
4359               RemoveRedundantSourceNote (str2, GetSubsourceQualName (ssp->subtype), ssp->name);
4360             }
4361             ssp = ssp->next;
4362           }
4363         }
4364       }
4365       TrimSpacesAndSemicolonsAroundString (str1);
4366       TrimSpacesAndSemicolonsAroundString (str2);
4367     }
4368     sdp = sdp->next;
4369   }
4370 }
4371 
4372 typedef struct convaccdata {
4373   CharPtr        currID;
4374   CharPtr        newID;
4375 } ConvAccData, PNTR ConvAccPtr;
4376 
ChangeSeqIdListToAccLocalID(SeqIdPtr sip,CharPtr currID,CharPtr newID)4377 static void ChangeSeqIdListToAccLocalID (SeqIdPtr sip, CharPtr currID, CharPtr newID)
4378 
4379 {
4380   ObjectIdPtr   oip;
4381 
4382   while (sip != NULL) {
4383     switch (sip->choice) {
4384       case SEQID_LOCAL :
4385         oip = (ObjectIdPtr) sip->data.ptrvalue;
4386         if (oip != NULL) {
4387           if (StringCmp (oip->str, currID) == 0) {
4388             MemFree (oip->str);
4389             oip->str = StringSave (newID);
4390           }
4391         }
4392         break;
4393       default :
4394         break;
4395     }
4396     sip = sip->next;
4397   }
4398 }
4399 
ChangeSeqLocListToAccLocalID(SeqLocPtr slp,CharPtr currID,CharPtr newID)4400 static void ChangeSeqLocListToAccLocalID (SeqLocPtr slp, CharPtr currID, CharPtr newID)
4401 
4402 {
4403   SeqLocPtr      loc;
4404   PackSeqPntPtr  psp;
4405   SeqBondPtr     sbp;
4406   SeqIntPtr      sinp;
4407   SeqIdPtr       sip;
4408   SeqPntPtr      spp;
4409 
4410   while (slp != NULL) {
4411     switch (slp->choice) {
4412       case SEQLOC_NULL :
4413         break;
4414       case SEQLOC_EMPTY :
4415       case SEQLOC_WHOLE :
4416         sip = (SeqIdPtr) slp->data.ptrvalue;
4417         ChangeSeqIdListToAccLocalID (sip, currID, newID);
4418         break;
4419       case SEQLOC_INT :
4420         sinp = (SeqIntPtr) slp->data.ptrvalue;
4421         if (sinp != NULL) {
4422           sip = sinp->id;
4423           ChangeSeqIdListToAccLocalID (sip, currID, newID);
4424         }
4425         break;
4426       case SEQLOC_PNT :
4427         spp = (SeqPntPtr) slp->data.ptrvalue;
4428         if (spp != NULL) {
4429           sip = spp->id;
4430           ChangeSeqIdListToAccLocalID (sip, currID, newID);
4431         }
4432         break;
4433       case SEQLOC_PACKED_PNT :
4434         psp = (PackSeqPntPtr) slp->data.ptrvalue;
4435         if (psp != NULL) {
4436           sip = psp->id;
4437           ChangeSeqIdListToAccLocalID (sip, currID, newID);
4438         }
4439         break;
4440       case SEQLOC_PACKED_INT :
4441       case SEQLOC_MIX :
4442       case SEQLOC_EQUIV :
4443         loc = (SeqLocPtr) slp->data.ptrvalue;
4444         while (loc != NULL) {
4445           ChangeSeqIdListToAccLocalID (loc, currID, newID);
4446           loc = loc->next;
4447         }
4448         break;
4449       case SEQLOC_BOND :
4450         sbp = (SeqBondPtr) slp->data.ptrvalue;
4451         if (sbp != NULL) {
4452           spp = (SeqPntPtr) sbp->a;
4453           if (spp != NULL) {
4454             sip = spp->id;
4455             ChangeSeqIdListToAccLocalID (sip, currID, newID);
4456           }
4457           spp = (SeqPntPtr) sbp->b;
4458           if (spp != NULL) {
4459             sip = spp->id;
4460             ChangeSeqIdListToAccLocalID (sip, currID, newID);
4461           }
4462         }
4463         break;
4464       case SEQLOC_FEAT :
4465         break;
4466       default :
4467         break;
4468     }
4469     slp = slp->next;
4470   }
4471 }
4472 
ChangeAlignListToAccLocalID(SeqAlignPtr align,CharPtr currID,CharPtr newID)4473 static void ChangeAlignListToAccLocalID (SeqAlignPtr align, CharPtr currID, CharPtr newID)
4474 
4475 {
4476   DenseDiagPtr  ddp;
4477   DenseSegPtr   dsp;
4478   StdSegPtr     ssp;
4479 
4480   if (align == NULL) return;
4481   if (align->segtype == 1) {
4482     ddp = (DenseDiagPtr) align->segs;
4483     if (ddp != NULL) {
4484       ChangeSeqIdListToAccLocalID (ddp->id, currID, newID);
4485     }
4486   } else if (align->segtype == 2) {
4487     dsp = (DenseSegPtr) align->segs;
4488     if (dsp != NULL) {
4489       ChangeSeqIdListToAccLocalID (dsp->ids, currID, newID);
4490     }
4491   } else if (align->segtype == 3) {
4492     ssp = (StdSegPtr) align->segs;
4493     if (ssp != NULL) {
4494        ChangeSeqLocListToAccLocalID (ssp->loc, currID, newID);
4495     }
4496   }
4497 }
4498 
CopyAccToLocalCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)4499 static void CopyAccToLocalCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4500 
4501 {
4502   BioseqPtr     bsp;
4503   BioseqSetPtr  bssp;
4504   ConvAccPtr    cap;
4505   SeqAlignPtr   sal;
4506   SeqAnnotPtr   sap;
4507   SeqFeatPtr    sfp;
4508   SeqIdPtr      sip;
4509   SeqLocPtr     slp;
4510 
4511   if (sep == NULL || sep->data.ptrvalue == NULL) return;
4512   cap = (ConvAccPtr) mydata;
4513   if (cap == NULL) return;
4514   if (IS_Bioseq (sep)) {
4515     bsp = (BioseqPtr) sep->data.ptrvalue;
4516     sip = bsp->id;
4517     ChangeSeqIdListToAccLocalID (sip, cap->currID, cap->newID);
4518     SeqMgrReplaceInBioseqIndex (bsp);
4519     sap = bsp->annot;
4520   } else if (IS_Bioseq_set (sep)) {
4521     bssp = (BioseqSetPtr) sep->data.ptrvalue;
4522     sap = bssp->annot;
4523   } else return;
4524   while (sap != NULL) {
4525     if (sap->type == 1) {
4526       sfp = (SeqFeatPtr) sap->data;
4527       while (sfp != NULL) {
4528         slp = sfp->location;
4529         ChangeSeqLocListToAccLocalID (slp, cap->currID, cap->newID);
4530         slp = sfp->product;
4531         ChangeSeqLocListToAccLocalID (slp, cap->currID, cap->newID);
4532         sfp = sfp->next;
4533       }
4534     } else if (sap->type == 2) {
4535       sal = (SeqAlignPtr) sap->data;
4536       while (sal != NULL) {
4537         ChangeAlignListToAccLocalID (sal, cap->currID, cap->newID);
4538         sal = sal->next;
4539       }
4540     }
4541     sap = sap->next;
4542   }
4543 }
4544 
RecordAccToConvert(ValNodePtr PNTR vnpp,BioseqPtr bsp,CharPtr newID)4545 static void RecordAccToConvert (ValNodePtr PNTR vnpp, BioseqPtr bsp, CharPtr newID)
4546 
4547 {
4548   ConvAccPtr   cap;
4549   ObjectIdPtr  oip;
4550   SeqIdPtr     sip;
4551 
4552   if (vnpp == NULL || bsp == NULL || StringHasNoText (newID)) return;
4553   for (sip = bsp->id; sip != NULL; sip = sip->next) {
4554     if (sip->choice == SEQID_LOCAL) {
4555       oip = (ObjectIdPtr) sip->data.ptrvalue;
4556       if (oip != NULL) {
4557         if (! StringHasNoText (oip->str)) {
4558           cap = (ConvAccPtr) MemNew (sizeof (ConvAccData));
4559           if (cap == NULL) return;
4560           cap->currID = StringSave (oip->str);
4561           cap->newID = StringSave (newID);
4562           ValNodeAddPointer (vnpp, 0, (Pointer) cap);
4563           return;
4564         }
4565       }
4566     }
4567   }
4568 }
4569 
IsLegalAccession(CharPtr acnum,Int2 i)4570 static Boolean IsLegalAccession (CharPtr acnum, Int2 i)
4571 
4572 {
4573   Int2  j;
4574 
4575   if (! isalpha ((Int4)(acnum [0]))) return FALSE;
4576   if (!(isdigit((Int4)(acnum[1])) && i == 6) && !(isalpha((Int4)(acnum[1])) && i == 8)) return FALSE;
4577   for (j = 2; j < i; j++) {
4578     if (!(isdigit((Int4)(acnum[j])))) return FALSE;
4579   }
4580   return TRUE;
4581 }
4582 
FindAccInDefCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)4583 static void FindAccInDefCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4584 
4585 {
4586   Char         acnum [17];
4587   BioseqPtr    bsp;
4588   Int2         i;
4589   CharPtr      p;
4590   Char         str [128];
4591   ValNodePtr   ttl;
4592   ValNodePtr   PNTR vnpp;
4593 
4594   if (sep == NULL || sep->data.ptrvalue == NULL) return;
4595   if (! IS_Bioseq (sep)) return;
4596   vnpp = (ValNodePtr PNTR) mydata;
4597   if (vnpp == NULL) return;
4598   ttl = SeqEntryGetSeqDescr (sep, Seq_descr_title, NULL);
4599   while (ttl != NULL) {
4600     StringNCpy_0 (str, (CharPtr) ttl->data.ptrvalue, sizeof (str));
4601     TrimSpacesAroundString (str);
4602     if (! StringHasNoText (str)) {
4603       if (str [0] == 'a' && str [1] == 'c' && str [2] == 'c') {
4604         p = str + 3;
4605         for (i = 0; isalnum ((Int4)(*p)) && *p != '\0'; p++, i++) {
4606           acnum [i] = *p;
4607         }
4608         acnum [i] = '\0';
4609         if (i == 6 || i == 8) {
4610           if (IsLegalAccession (acnum, i)) {
4611             bsp = (BioseqPtr) sep->data.ptrvalue;
4612             RecordAccToConvert (vnpp, bsp, str);
4613           }
4614         }
4615       }
4616     }
4617     ttl = SeqEntryGetSeqDescr (sep, Seq_descr_title, ttl);
4618   }
4619 }
4620 
ConvertAccInDefToLocalIdProc(SeqEntryPtr sep)4621 static void ConvertAccInDefToLocalIdProc (SeqEntryPtr sep)
4622 
4623 {
4624   ConvAccPtr  cap;
4625   ValNodePtr  head;
4626   ValNodePtr  vnp;
4627 
4628   if (sep == NULL) return;
4629   head = NULL;
4630   SeqEntryExplore (sep, (Pointer) &head, FindAccInDefCallback);
4631   if (head == NULL) return;
4632   if (Message (MSG_YN, "Convert accLNNNNN or accLLNNNNNN in title to local ID?") == ANS_NO) return;
4633   for (vnp = head; vnp != NULL; vnp = vnp->next) {
4634     cap = (ConvAccPtr) vnp->data.ptrvalue;
4635     if (cap != NULL) {
4636       SeqEntryExplore (sep, (Pointer) cap, CopyAccToLocalCallback);
4637     }
4638   }
4639   for (vnp = head; vnp != NULL; vnp = vnp->next) {
4640     cap = (ConvAccPtr) vnp->data.ptrvalue;
4641     if (cap != NULL) {
4642       MemFree (cap->currID);
4643       MemFree (cap->newID);
4644       vnp->data.ptrvalue = MemFree (cap);
4645     }
4646   }
4647   ValNodeFree (head);
4648 }
4649 
4650 static Int2  taxonCount;
4651 
DoSeqEntryToAsn3(SeqEntryPtr sep,Boolean strip,Boolean correct,Boolean force,Boolean dotaxon,MonitorPtr mon,Boolean isEmblOrDdbj)4652 static Int4 DoSeqEntryToAsn3 (SeqEntryPtr sep, Boolean strip, Boolean correct,
4653                               Boolean force, Boolean dotaxon, MonitorPtr mon, Boolean isEmblOrDdbj)
4654 
4655 {
4656   BioseqSetPtr  bssp;
4657   SeqEntryPtr   oldscope;
4658   Int4          rsult;
4659   Char          str [32];
4660 
4661   rsult = 0;
4662   if (IS_Bioseq_set (sep)) {
4663     bssp = (BioseqSetPtr) sep->data.ptrvalue;
4664     if (bssp != NULL && (bssp->_class == 7 ||
4665                          (IsPopPhyEtcSet (bssp->_class)))) {
4666       for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
4667         rsult += DoSeqEntryToAsn3 (sep, strip, correct, force, dotaxon, mon, isEmblOrDdbj);
4668       }
4669       return rsult;
4670     }
4671   }
4672 /*#ifdef USE_TAXON*/
4673   if (dotaxon && mon != NULL) {
4674     taxonCount++;
4675     sprintf (str, "Processing Component %d", (int) taxonCount);
4676     MonitorStrValue (mon, str);
4677   }
4678 /*#endif*/
4679 /*#ifdef INTERNAL_NCBI_SEQUIN*/
4680   if (indexerVersion) {
4681     if ((! force) && (! NoBiosourceOrTaxonId (sep))) return 0;
4682   } else {
4683 /*#else*/
4684     if ((! force) && SeqEntryGetSeqDescr (sep, Seq_descr_source, NULL) != NULL) return 0;
4685   }
4686 /*#endif*/
4687   oldscope = SeqEntrySetScope (sep);
4688   if (dotaxon) {
4689     rsult = SeqEntryToAsn3Ex (sep, strip, correct, TRUE, NULL, Tax3MergeSourceDescr, FALSE, isEmblOrDdbj);
4690     DeleteMarkedObjects (0, OBJ_SEQENTRY, sep);
4691   } else {
4692     rsult = SeqEntryToAsn3Ex (sep, strip, correct, FALSE, NULL, NULL, FALSE, isEmblOrDdbj);
4693   }
4694   SeqEntrySetScope (oldscope);
4695   return rsult;
4696 }
4697 
4698 /* CheckSeqAlignCallback copied from salsa.c */
CheckSeqAlignCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)4699 static void CheckSeqAlignCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4700 {
4701   BioseqPtr          bsp;
4702   BioseqSetPtr       bssp;
4703   SeqAnnotPtr        sap,
4704                      pre;
4705 
4706   if (sep != NULL && sep->data.ptrvalue) {
4707      if (IS_Bioseq(sep)) {
4708         bsp = (BioseqPtr) sep->data.ptrvalue;
4709         if (bsp!=NULL) {
4710            pre=NULL;
4711            sap=bsp->annot;
4712            while (sap!= NULL)
4713            {
4714               if (sap->type == 2) {
4715                  if (is_dim1seqalign ((SeqAlignPtr) sap->data)) {
4716                     if (pre==NULL) {
4717                        bsp->annot=sap->next;
4718                        sap->next=NULL;
4719                        SeqAnnotFree (sap);
4720                        sap=bsp->annot;
4721                     }
4722                     else {
4723                        pre->next=sap->next;
4724                        pre=sap->next;
4725                        sap->next=NULL;
4726                        SeqAnnotFree (sap);
4727                        sap=pre;
4728                     }
4729                  }
4730                  else {
4731                     pre=sap;
4732                     sap=sap->next;
4733                  }
4734               }
4735               else {
4736                  pre=sap;
4737                  sap=sap->next;
4738               }
4739            }
4740         }
4741      }
4742      else if(IS_Bioseq_set(sep)) {
4743         bssp = (BioseqSetPtr)sep->data.ptrvalue;
4744         if (bssp!=NULL) {
4745            pre=NULL;
4746            sap=bssp->annot;
4747            while (sap!= NULL)
4748            {
4749               if (sap->type == 2) {
4750                  if (is_dim1seqalign ((SeqAlignPtr) sap->data)) {
4751                     if (pre==NULL) {
4752                        bssp->annot=sap->next;
4753                        sap->next=NULL;
4754                        SeqAnnotFree (sap);
4755                        sap=bssp->annot;
4756                     }
4757                     else {
4758                        pre=sap->next;
4759                        sap->next=NULL;
4760                        SeqAnnotFree (sap);
4761                        sap=sap->next;
4762                     }
4763                  }
4764                  else {
4765                     pre=sap;
4766                     sap=sap->next;
4767                  }
4768               }
4769               else {
4770                  pre=sap;
4771                  sap=sap->next;
4772               }
4773            }
4774         }
4775      }
4776   }
4777 }
4778 
4779 /* RemoveMultipleTitles currently removes FIRST title in chain */
4780 
RemoveMultipleTitles(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)4781 static void RemoveMultipleTitles (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4782 
4783 {
4784   BioseqPtr      bsp;
4785   BioseqSetPtr   bssp;
4786   SeqDescrPtr    descr = NULL;
4787   SeqDescrPtr    lasttitle = NULL;
4788   ObjValNodePtr  ovp;
4789   SeqDescrPtr    sdp;
4790 
4791   if (IS_Bioseq (sep)) {
4792     bsp = (BioseqPtr) sep->data.ptrvalue;
4793     if (bsp == NULL) return;
4794     descr = bsp->descr;
4795   } else if (IS_Bioseq_set (sep)) {
4796     bssp = (BioseqSetPtr) sep->data.ptrvalue;
4797     if (bssp == NULL) return;
4798     descr = bssp->descr;
4799   } else return;
4800   for (sdp = descr; sdp != NULL; sdp = sdp->next) {
4801     if (sdp->choice != Seq_descr_title) continue;
4802     if (lasttitle != NULL) {
4803       if (lasttitle->extended != 0) {
4804         ovp = (ObjValNodePtr) lasttitle;
4805         ovp->idx.deleteme = TRUE;
4806       }
4807       lasttitle = sdp;
4808     } else {
4809       lasttitle = sdp;
4810     }
4811   }
4812 }
4813 
MakeSequinCleanupObject(SeqEntryPtr sep)4814 static void MakeSequinCleanupObject (SeqEntryPtr sep)
4815 
4816 {
4817   DatePtr        dp;
4818   ValNodePtr     sdp;
4819   UserObjectPtr  uop;
4820 
4821   dp = DateCurr ();
4822   if (dp == NULL) return;
4823 
4824   uop = CreateNcbiCleanupUserObject ();
4825   if (uop == NULL) return;
4826 
4827   AddStringToNcbiCleanupUserObject (uop, "method", "SequinCleanup");
4828   AddIntegerToNcbiCleanupUserObject (uop, "version", NCBI_CLEANUP_VERSION);
4829 
4830   AddIntegerToNcbiCleanupUserObject (uop, "month", dp->data [2]);
4831   AddIntegerToNcbiCleanupUserObject (uop, "day", dp->data [3]);
4832   AddIntegerToNcbiCleanupUserObject (uop, "year", dp->data [1] + 1900);
4833 
4834   sdp = NewDescrOnSeqEntry (sep, Seq_descr_user);
4835   if (sdp == NULL) return;
4836   sdp->data.ptrvalue = uop;
4837 }
4838 
SqnCheckForEmblDdbjID(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)4839 static void SqnCheckForEmblDdbjID (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4840 
4841 {
4842   BioseqPtr  bsp;
4843   BoolPtr    isEmblOrDdbj;
4844   SeqIdPtr   sip;
4845 
4846   if (sep == NULL) return;
4847   if (IS_Bioseq (sep)) {
4848     bsp = (BioseqPtr) sep->data.ptrvalue;
4849     if (bsp == NULL) return;
4850     isEmblOrDdbj = (BoolPtr) mydata;
4851     if (isEmblOrDdbj == NULL) return;
4852     for (sip = bsp->id; sip != NULL; sip = sip->next) {
4853       switch (sip->choice) {
4854         case SEQID_EMBL :
4855         case SEQID_DDBJ :
4856           *isEmblOrDdbj = TRUE;
4857           break;
4858           break;
4859         default :
4860           break;
4861       }
4862     }
4863   }
4864 }
4865 
4866 extern Int4 MySeqEntryToAsn3Ex (SeqEntryPtr sep, Boolean strip, Boolean correct, Boolean force, Boolean dotaxon);
MySeqEntryToAsn3Ex(SeqEntryPtr sep,Boolean strip,Boolean correct,Boolean force,Boolean dotaxon)4867 extern Int4 MySeqEntryToAsn3Ex (SeqEntryPtr sep, Boolean strip, Boolean correct, Boolean force, Boolean dotaxon)
4868 
4869 {
4870   Uint2       entityID;
4871   Boolean     isEmblOrDdbj = FALSE;
4872   MonitorPtr  mon;
4873   Boolean     needstaxfix;
4874   Int4        rsult;
4875   ErrSev      sev;
4876 
4877   rsult = 0;
4878   sev = ErrSetMessageLevel (SEV_FATAL);
4879 
4880   RemoveAllNcbiCleanupUserObjects (sep);
4881 
4882   BasicSeqEntryCleanup (sep);
4883   EntryChangeImpFeat(sep);     /* change any CDS ImpFeat to real CdRegion */
4884   /* NormalizePeriodsOnInitials (sep); */ /* put periods on author initials */
4885   /* MoveRnaGBQualProductToName (sep); */ /* move rna gbqual product to rna-ref.ext.name */
4886   /* MoveProtGBQualProductToName (sep); */ /* move prot gbqual product to prot-ref.name */
4887   /* MoveCdsGBQualProductToName (sep); */ /* move cds gbqual product to prot-ref.name */
4888   /* MoveFeatGBQualsToFields (sep); */ /* move feature partial, exception to fields */
4889   if (indexerVersion) {
4890     /*
4891     StripTitleFromProtsInNucProts (sep);
4892     */
4893     MoveFeatsFromPartsSet (sep);
4894     move_cds (sep); /* move CDS features to nuc-prot set */
4895   }
4896   /* ExtendGeneFeatIfOnMRNA (0, sep); */ /* gene on mRNA is full length */
4897   entityID = ObjMgrGetEntityIDForChoice (sep);
4898   SeqMgrIndexFeatures (entityID, NULL);
4899   VisitBioseqsInSep (sep, NULL, ExtendSingleGeneOnMRNA);
4900   RemoveBioSourceOnPopSet (sep, NULL);
4901   /* SeqEntryExplore (sep, NULL, CleanupEmptyFeatCallback); */
4902   /* before deleting titles, promote common set titles up */
4903   PromoteCommonTitlesToSet (sep);
4904   SeqEntryExplore (sep, NULL, DeleteMultipleTitles); /* do it old way in Sequin */
4905   /*
4906   SeqEntryExplore (sep, NULL, RemoveMultipleTitles);
4907   DeleteMarkedObjects (0, OBJ_SEQENTRY, (Pointer) sep);
4908   */
4909   SeqEntryPack (sep);
4910   if (indexerVersion) {
4911     ConvertAccInDefToLocalIdProc (sep); /* if title is accXNNNNN, convert to seqID */
4912   }
4913   if (useEntrez) {
4914     ValidateSeqAlignandACCInSeqEntry (sep, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE); /* remove components with seqID accXNNNNN */
4915   }
4916   SeqEntryExplore (sep, NULL, CheckSeqAlignCallback); /* remove alignments with single dimension */
4917   SeqEntryExplore (sep, (Pointer) &isEmblOrDdbj, SqnCheckForEmblDdbjID);
4918   needstaxfix = FALSE;
4919   if (! force) {
4920     needstaxfix = NoBiosourceOrTaxonId (sep);
4921   }
4922   if ((! force) && (! needstaxfix)) {
4923     ConvertFullLenSourceFeatToDesc (sep);
4924     ConvertFullLenPubFeatToDesc (sep);
4925     /* EntryStripSerialNumber(sep); */ /* strip citation serial numbers */
4926     EntryChangeGBSource (sep);   /* at least remove redundant information in GBBlocks */
4927     EntryCheckGBBlock (sep);
4928     /* SeqEntryMoveDbxrefs (sep); */ /* db_xref gbqual to sfp->dbxref */
4929     EntryMergeDupBioSources (sep);
4930     GetRidOfEmptyFeatsDescStrings (0, sep);
4931     GetRidOfLocusInSeqIds (0, sep);
4932     /* reindex, since CdEndCheck (from CdCheck) gets best overlapping gene */
4933     entityID = ObjMgrGetEntityIDForChoice (sep);
4934     SeqMgrIndexFeatures (entityID, NULL);
4935     MakeSequinCleanupObject (sep);
4936     NormalizeDescriptorOrder (sep);
4937     SeqMgrIndexFeatures (entityID, NULL);
4938     CdCheck (sep, NULL);
4939     BasicSeqEntryCleanup (sep);
4940     ErrSetMessageLevel (sev);
4941     return rsult;
4942   }
4943   if (force && useTaxon) {
4944     dotaxon = TRUE;
4945   }
4946   mon = NULL;
4947   taxonCount = 0;
4948 /*#ifdef USE_TAXON*/
4949   if (dotaxon) {
4950     WatchCursor ();
4951     mon = MonitorStrNewEx ("Taxonomy Lookup", 40, FALSE);
4952     MonitorStrValue (mon, "Processing Organism Info");
4953     Update ();
4954   }
4955 /*#endif*/
4956 
4957   /* set dirty flag if no lineage or division in any biosource */
4958   if (dotaxon && needstaxfix) {
4959     entityID = ObjMgrGetEntityIDForChoice (sep);
4960     ObjMgrSetDirtyFlag (entityID, TRUE);
4961   }
4962 
4963   EntryMergeDupBioSources (sep); /* do before and after SE2A3 */
4964   if (dotaxon) {
4965     Taxon3ReplaceOrgInSeqEntry (sep, FALSE);
4966   }
4967   rsult = DoSeqEntryToAsn3 (sep, strip, correct, force, FALSE, mon, isEmblOrDdbj);
4968 /*#ifdef USE_TAXON*/
4969   if (dotaxon) {
4970     MonitorStrValue (mon, "Closing Taxon");
4971     Update ();
4972     MonitorFree (mon);
4973     ArrowCursor ();
4974     Update ();
4975   }
4976 /*#endif*/
4977   ConvertFullLenSourceFeatToDesc (sep);
4978   ConvertFullLenPubFeatToDesc (sep);
4979   /* EntryStripSerialNumber(sep); */ /* strip citation serial numbers */
4980   MovePopPhyMutPubs (sep);
4981   EntryChangeGBSource (sep);   /* remove redundant information in GBBlocks again */
4982   EntryCheckGBBlock (sep);
4983   /* SeqEntryMoveDbxrefs (sep); */ /* db_xref gbqual to sfp->dbxref */
4984   EntryMergeDupBioSources (sep);
4985   GetRidOfEmptyFeatsDescStrings (0, sep);
4986   GetRidOfLocusInSeqIds (0, sep);
4987   /* reindex, since CdEndCheck (from CdCheck) gets best overlapping gene */
4988   entityID = ObjMgrGetEntityIDForChoice (sep);
4989   SeqMgrClearFeatureIndexes (entityID, NULL);
4990   MakeSequinCleanupObject (sep);
4991   NormalizeDescriptorOrder (sep);
4992   SeqMgrIndexFeatures (entityID, NULL);
4993   CdCheck (sep, NULL);
4994   BasicSeqEntryCleanup (sep);
4995   ErrSetMessageLevel (sev);
4996   ErrClear ();
4997   ErrShow ();
4998   return rsult;
4999 }
5000 
5001 typedef struct partialformdata {
5002   FEATURE_FORM_BLOCK
5003 
5004   ValNodePtr         featlist;
5005   LisT               feature;
5006   PopuP              change5;
5007   PopuP              change3;
5008   PopuP              orderJoinState;
5009   GrouP              nucprotchoice;
5010   TexT               findThis;
5011   CharPtr            findThisStr;
5012   Int2               subtype;
5013   Int2               leftpolicy;
5014   Int2               rightpolicy;
5015   Int2               nucprotpolicy;
5016   Int2               orderjoinpolicy;
5017   ObjMgrPtr          omp;
5018   ObjMgrTypePtr      omtp;
5019   ButtoN             extend5_btn;
5020   ButtoN             extend3_btn;
5021   Boolean            extend5;
5022   Boolean            extend3;
5023   ButtoN             leaveDlgUp;
5024   Boolean            case_insensitive;
5025   ButtoN             case_insensitive_btn;
5026   Boolean            when_string_not_present;
5027   ButtoN             when_string_not_present_btn;
5028 } PartialFormData, PNTR PartialFormPtr;
5029 
CDSMeetsStringConstraint(SeqFeatPtr sfp,CharPtr findThisStr,Boolean case_insensitive)5030 static Boolean CDSMeetsStringConstraint (SeqFeatPtr sfp,
5031 				      CharPtr     findThisStr,
5032 				      Boolean     case_insensitive)
5033 {
5034   BioseqPtr		protbsp;
5035   SeqFeatPtr		protsfp;
5036   SeqMgrFeatContext	context;
5037   ProtRefPtr		prp;
5038 
5039   if (sfp == NULL) return FALSE;
5040   protbsp = BioseqFindFromSeqLoc (sfp->product);
5041   if (protbsp == NULL) return FALSE;
5042   protsfp = SeqMgrGetBestProteinFeature (protbsp, &context);
5043   if ((case_insensitive && StringISearch (context.label, findThisStr) != NULL)
5044     || (!case_insensitive && StringSearch (context.label, findThisStr) != NULL))
5045   {
5046     return TRUE;
5047   }
5048   if (protsfp == NULL) return FALSE;
5049   prp = (ProtRefPtr) protsfp->data.value.ptrvalue;
5050   if (prp->name != NULL)
5051   {
5052     if ((case_insensitive && StringISearch (prp->name->data.ptrvalue, findThisStr) != NULL)
5053       || (!case_insensitive && StringSearch (prp->name->data.ptrvalue, findThisStr) != NULL))
5054     {
5055       return TRUE;
5056     }
5057   }
5058   if (prp->desc != NULL)
5059   {
5060   	if ((case_insensitive && StringISearch (prp->desc, findThisStr) != NULL)
5061   	  || (!case_insensitive && StringSearch (prp->desc, findThisStr) != NULL))
5062   	{
5063   	  return TRUE;
5064   	}
5065   }
5066   return FALSE;
5067 }
5068 
MeetsStringConstraint(SeqFeatPtr sfp,CharPtr findThisStr,Boolean case_insensitive)5069 extern Boolean MeetsStringConstraint (SeqFeatPtr  sfp,
5070 				                      CharPtr     findThisStr,
5071 				                      Boolean     case_insensitive)
5072 {
5073   GBQualPtr         gbqp;
5074   GeneRefPtr        grp;
5075   RnaRefPtr         rrp;
5076   SeqMgrFeatContext context;
5077   Boolean           have_context = FALSE;
5078 
5079   /* If no string constraint, then everyone matches */
5080 
5081   if (NULL == findThisStr)
5082     return TRUE;
5083 
5084   /* Search for the string constraint */
5085   /* in the feature title field */
5086   if (StringISearch (sfp->title, findThisStr))
5087     return TRUE;
5088 
5089   /* Search for the string constraint */
5090   /* in the feature comment field.    */
5091 
5092   if (StringISearch (sfp->comment, findThisStr))
5093     return TRUE;
5094 
5095   /* Search for the string constraint */
5096   /* in GB qualifiers.                */
5097 
5098   gbqp = sfp->qual;
5099   while (NULL != gbqp)
5100     {
5101       if ((NULL != gbqp->val) && StringISearch (gbqp->val, findThisStr))
5102 	return TRUE;
5103       gbqp = gbqp->next;
5104     }
5105 
5106   if (SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, 0, 0, sfp, &context) != NULL)
5107   {
5108     if (!case_insensitive && StringSearch (context.label, findThisStr) != NULL)
5109     {
5110     	return TRUE;
5111     }
5112     else if (case_insensitive && StringISearch (context.label, findThisStr) != NULL)
5113   	{
5114   	  return TRUE;
5115   	}
5116   	have_context = TRUE;
5117   }
5118 
5119   if (sfp->data.choice == SEQFEAT_GENE)
5120   {
5121     grp = sfp->data.value.ptrvalue;
5122     if (!case_insensitive &&
5123         (StringSearch (grp->locus, findThisStr) != NULL
5124         || StringSearch (grp->desc, findThisStr) != NULL
5125         || StringSearch (grp->desc, findThisStr) != NULL
5126         || StringSearch (grp->locus_tag, findThisStr) != NULL))
5127     {
5128       return TRUE;
5129     }
5130     else if (case_insensitive &&
5131         (StringISearch (grp->locus, findThisStr) != NULL
5132         || StringISearch (grp->desc, findThisStr) != NULL
5133         || StringISearch (grp->desc, findThisStr) != NULL
5134         || StringISearch (grp->locus_tag, findThisStr) != NULL))
5135     {
5136       return TRUE;
5137     }
5138   }
5139   else if (sfp->data.choice == SEQFEAT_CDREGION)
5140   {
5141     if (CDSMeetsStringConstraint (sfp, findThisStr, case_insensitive))
5142       return TRUE;
5143   }
5144   else if (sfp->data.choice == SEQFEAT_RNA)
5145   {
5146     rrp = sfp->data.value.ptrvalue;
5147 
5148     if (rrp->ext.choice == 1) {
5149       if ((!case_insensitive && StringSearch ((CharPtr) rrp->ext.value.ptrvalue, findThisStr) != NULL)
5150         || (case_insensitive && StringISearch ((CharPtr) rrp->ext.value.ptrvalue, findThisStr) != NULL))
5151       {
5152         return TRUE;
5153       }
5154     }
5155     else if (rrp->type == 3 && rrp->ext.choice == 2 && have_context)
5156     {
5157       /* look for the label as it appears to the user */
5158       if ((!case_insensitive && StringNCmp(findThisStr, "tRNA-", 5) == 0
5159           && StringSearch (context.label, findThisStr + 5))
5160           || (case_insensitive && StringNICmp (findThisStr, "tRNA-", 5) == 0
5161           && StringISearch (context.label, findThisStr + 5)))
5162       {
5163       	return TRUE;
5164       }
5165     }
5166   }
5167 
5168   /* If we got to here, then the string constraint was not found */
5169 
5170   return FALSE;
5171 }
5172 
5173 
SetBestFrameByLocation(SeqFeatPtr sfp)5174 extern Boolean SetBestFrameByLocation (SeqFeatPtr sfp)
5175 {
5176   CdRegionPtr  crp;
5177   Uint1        new_frame = 0, i;
5178   ByteStorePtr bs;
5179   Int4         lens [3];
5180   Int4         max;
5181   Boolean      retval = TRUE;
5182 
5183   if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return FALSE;
5184 
5185   crp = sfp->data.value.ptrvalue;
5186   if (crp == NULL) return FALSE;
5187 
5188   max = 0;
5189   for (i = 1; i <= 3; i++) {
5190     crp->frame = i;
5191     bs = ProteinFromCdRegionEx (sfp, FALSE, FALSE);
5192     lens[i - 1] = BSLen (bs);
5193     BSFree (bs);
5194     if (lens[i - 1] > max) {
5195       max = lens[i - 1];
5196       new_frame = i;
5197     }
5198   }
5199   for (i = 1; i <= 3; i++) {
5200     if (lens [i - 1] == max && i != new_frame) {
5201       retval = FALSE;
5202     }
5203   }
5204   crp->frame = new_frame;
5205   return retval;
5206 }
5207 
5208 
SetBestFrame(SeqFeatPtr sfp)5209 extern void SetBestFrame (SeqFeatPtr sfp)
5210 {
5211   SeqAlignPtr  salp;
5212   CdRegionPtr  crp;
5213   BioseqPtr    old_prot, new_prot;
5214   ByteStorePtr bs = NULL;
5215   Int4         original_frame, test_frame;
5216   Boolean      revcomp;
5217   ErrSev       level;
5218   CharPtr      seq_str1, seq_str2;
5219   Int4         best_len = -1, new_aln_len;
5220   Int4         best_frame = -1;
5221 
5222   if (sfp == NULL || sfp->idx.subtype != FEATDEF_CDS) return;
5223 
5224   crp = sfp->data.value.ptrvalue;
5225   if (crp == NULL) return;
5226 
5227   old_prot = BioseqFindFromSeqLoc (sfp->product);
5228   if (old_prot == NULL) return;
5229 
5230   new_prot = BioseqNew ();
5231   new_prot->id = SeqIdParse ("lcl|CdRgnTransl");
5232   new_prot->repr = Seq_repr_raw;
5233   new_prot->mol = Seq_mol_aa;
5234   new_prot->seq_data_type = Seq_code_ncbieaa;
5235   bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
5236   new_prot->seq_data = (SeqDataPtr) bs;
5237   new_prot->length = BSLen (bs);
5238 
5239   original_frame = crp->frame;
5240 
5241   /* suppress BLAST error messages when no similarity is found */
5242   level = ErrSetMessageLevel (SEV_MAX);
5243   seq_str1 = BSMerge((ByteStorePtr)(old_prot->seq_data), NULL);
5244   seq_str2 = BSMerge((ByteStorePtr)(new_prot->seq_data), NULL);
5245 
5246   for (test_frame = 1; test_frame <= 3; test_frame ++)
5247   {
5248     new_prot->seq_data = SeqDataFree (new_prot->seq_data, new_prot->seq_data_type);
5249     crp->frame = test_frame;
5250     new_prot->seq_data = (SeqDataPtr) ProteinFromCdRegionEx (sfp, TRUE, FALSE);
5251     salp = Sequin_GlobalAlign2Seq (old_prot, new_prot, &revcomp);
5252     if (salp != NULL)
5253     {
5254       new_aln_len = SeqAlignLength (salp);
5255       if (new_aln_len > best_len)
5256       {
5257         best_len = new_aln_len;
5258         best_frame = test_frame;
5259       }
5260       salp = SeqAlignFree (salp);
5261     }
5262   }
5263 
5264   if (best_frame > -1)
5265   {
5266     crp->frame = best_frame;
5267   }
5268   else
5269   {
5270     crp->frame = original_frame;
5271   }
5272 
5273   ErrSetMessageLevel (level);
5274   BioseqFree (new_prot);
5275 }
5276 
5277 
5278 /*
5279 static Boolean AddOrgToDefGatherFunc (GatherContextPtr gcp)
5280 
5281 {
5282   CharPtr     def;
5283   CharPtr     ptr;
5284   ValNodePtr  sdp;
5285   CharPtr     str;
5286   CharPtr     text;
5287 
5288   if (gcp == NULL || gcp->thisitem == NULL) return TRUE;
5289   if (gcp->thistype != OBJ_SEQDESC) return TRUE;
5290   text = (CharPtr) gcp->userdata;
5291   if (text == NULL || StringHasNoText (text)) return TRUE;
5292   sdp = (ValNodePtr) gcp->thisitem;
5293   if (sdp->choice != Seq_descr_title) return TRUE;
5294   def = (CharPtr) sdp->data.ptrvalue;
5295   if (StringHasNoText (def)) return TRUE;
5296 
5297   ptr = StringISearch (def, text);
5298   if (ptr != NULL && ptr == def) return TRUE;
5299   str = MemNew ((StringLen (text) + StringLen (def) + 4) * sizeof (Char));
5300   if (str != NULL) {
5301     StringCpy (str, text);
5302     StringCat (str, " ");
5303     StringCat (str, def);
5304     sdp->data.ptrvalue = MemFree (sdp->data.ptrvalue);
5305     sdp->data.ptrvalue = str;
5306     ObjMgrSetDirtyFlag (gcp->entityID, TRUE);
5307   }
5308   return TRUE;
5309 }
5310 */
5311 
AppendOrgToString(Uint2 entityID,SeqDescrPtr sdp,CharPtr text)5312 static void AppendOrgToString (Uint2 entityID, SeqDescrPtr sdp, CharPtr text)
5313 
5314 {
5315   CharPtr     def;
5316   CharPtr     ptr;
5317   CharPtr     str;
5318 
5319   def = (CharPtr) sdp->data.ptrvalue;
5320   if (StringHasNoText (def)) return;
5321 
5322   ptr = StringISearch (def, text);
5323   if (ptr != NULL && ptr == def) return;
5324   str = MemNew ((StringLen (text) + StringLen (def) + 4) * sizeof (Char));
5325   if (str != NULL) {
5326     StringCpy (str, text);
5327     StringCat (str, " ");
5328     StringCat (str, def);
5329     sdp->data.ptrvalue = MemFree (sdp->data.ptrvalue);
5330     sdp->data.ptrvalue = str;
5331     ObjMgrSetDirtyFlag (entityID, TRUE);
5332   }
5333 }
5334 
AddOrgToDefElement(Uint2 entityID,SeqEntryPtr sep,Int2 orgmod,Int2 subsource)5335 static void AddOrgToDefElement (Uint2 entityID, SeqEntryPtr sep, Int2 orgmod, Int2 subsource)
5336 
5337 {
5338   BioSourcePtr       biop;
5339   BioseqPtr          bsp;
5340   BioseqSetPtr       bssp;
5341   Char               ch;
5342   SeqMgrDescContext  dcontext;
5343   OrgModPtr          mod;
5344   OrgNamePtr         onp;
5345   OrgRefPtr          orp;
5346   CharPtr            ptr;
5347   SeqDescrPtr        sdp;
5348   SubSourcePtr       ssp;
5349   Char               str [96];
5350   Char               text [64];
5351   CharPtr            title;
5352 
5353   if (sep == NULL) return;
5354   if (IS_Bioseq_set (sep)) {
5355     bssp = (BioseqSetPtr) sep->data.ptrvalue;
5356     if (bssp != NULL && (bssp->_class == 1 || bssp->_class == 2 ||
5357                          bssp->_class == 4)) {
5358       for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
5359         AddOrgToDefElement (entityID, sep, orgmod, subsource);
5360       }
5361       return;
5362     }
5363   }
5364   if (! IS_Bioseq (sep)) return;
5365   bsp = (BioseqPtr) sep->data.ptrvalue;
5366   biop = NULL;
5367   text [0] = '\0';
5368   str [0] = '\0';
5369   sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
5370   if (sdp != NULL) {
5371     biop = (BioSourcePtr) sdp->data.ptrvalue;
5372   }
5373   if (biop == NULL) return;
5374   /* SeqEntryToBioSource (sep, NULL, str, sizeof (str) - 1, &biop); */
5375   if (orgmod == 0 && subsource == 0) {
5376     orp = biop->org;
5377     if (orp == NULL) return;
5378     StringNCpy_0 (str, orp->taxname, sizeof (str));
5379     /*
5380     ptr = StringSearch (str, "(");
5381     if (ptr != NULL) {
5382       *ptr = '\0';
5383     }
5384     */
5385     TrimSpacesAroundString (str);
5386     if ((StringICmp (str, "Human immunodeficiency virus type 1") == 0) ||
5387 	(StringICmp (str, "Human immunodeficiency virus 1") == 0)) {
5388       StringCpy (str, "HIV-1");
5389     } else if ((StringICmp (str,"Human immunodeficiency virus type 2")==0) ||
5390 	       (StringICmp (str,"Human immunodeficiency virus 2") == 0)) {
5391       StringCpy (str, "HIV-2");
5392     }
5393     str [0] = TO_UPPER (str [0]);
5394   } else if (biop != NULL && biop->org != NULL) {
5395     text [0] = '\0';
5396     str [0] = '\0';
5397     orp = biop->org;
5398     if (orgmod > 0) {
5399       onp = orp->orgname;
5400       if (onp != NULL) {
5401         mod = onp->mod;
5402         while (mod != NULL) {
5403           if (mod->subtype == orgmod) {
5404             StringNCpy_0 (text, mod->subname, sizeof (text));
5405             StringNCpy_0 (str, GetOrgModQualName (mod->subtype), sizeof (str));
5406           }
5407           mod = mod->next;
5408         }
5409       }
5410     } else if (subsource > 0) {
5411       ssp = biop->subtype;
5412       while (ssp != NULL) {
5413         if (ssp->subtype == subsource) {
5414           StringNCpy_0 (text, ssp->name, sizeof (text));
5415           StringNCpy_0 (str, GetSubsourceQualName (ssp->subtype), sizeof (str));
5416         }
5417         ssp = ssp->next;
5418       }
5419     }
5420     if (StringHasNoText (text)) {
5421       str [0] = '\0';
5422       text [0] = '\0';
5423     } else {
5424       StringCat (str, " ");
5425       ptr = str;
5426       while (*ptr != '\0') {
5427         ch = *ptr;
5428         *ptr = TO_LOWER (ch);
5429         ptr++;
5430       }
5431       StringCat (str, text);
5432     }
5433   }
5434   /*
5435   MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
5436   gs.seglevels = 1;
5437   gs.get_feats_location = FALSE;
5438   MemSet ((Pointer) (gs.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
5439   gs.ignore[OBJ_BIOSEQ] = FALSE;
5440   gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
5441   gs.ignore[OBJ_SEQANNOT] = FALSE;
5442   gs.ignore[OBJ_SEQDESC] = FALSE;
5443   gs.scope = sep;
5444   GatherSeqEntry (sep, (Pointer) str, AddOrgToDefGatherFunc, &gs);
5445   */
5446   sdp = SeqEntryGetSeqDescr (sep, Seq_descr_title, NULL);
5447   if (sdp == NULL) {
5448     sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_title, &dcontext);
5449     if (sdp == NULL) return;
5450     title = (CharPtr) sdp->data.ptrvalue;
5451     if (title == NULL) return;
5452     sdp = SeqDescrAdd (&(bsp->descr));
5453     if (sdp == NULL) return;
5454     sdp->choice = Seq_descr_title;
5455     sdp->data.ptrvalue = StringSave (title);
5456   }
5457   if (sdp == NULL) return;
5458   AppendOrgToString (entityID, sdp, str);
5459 }
5460 
AddOrgToDef(Uint2 entityID,SeqEntryPtr sep,Int2 orgmod,Int2 subsource)5461 static void AddOrgToDef (Uint2 entityID, SeqEntryPtr sep, Int2 orgmod, Int2 subsource)
5462 
5463 {
5464   BioseqSetPtr       bssp;
5465 
5466   if (sep == NULL) return;
5467   if (IS_Bioseq_set (sep)) {
5468     bssp = (BioseqSetPtr) sep->data.ptrvalue;
5469     if (bssp != NULL && (bssp->_class == 7 ||
5470                          (IsPopPhyEtcSet (bssp->_class)))) {
5471       for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
5472         AddOrgToDef (entityID, sep, orgmod, subsource);
5473       }
5474       return;
5475     }
5476   }
5477   AddOrgToDefElement (entityID, sep, orgmod, subsource);
5478 }
5479 
CommonAddOrgOrModsToDefLines(IteM i,Int2 orgmod,Int2 subsource,ButtoN b)5480 extern void CommonAddOrgOrModsToDefLines (IteM i, Int2 orgmod, Int2 subsource, ButtoN b)
5481 
5482 {
5483   BaseFormPtr  bfp;
5484   SeqEntryPtr  sep;
5485 
5486   if (b != NULL) {
5487     bfp = GetObjectExtra (b);
5488   } else {
5489 #ifdef WIN_MAC
5490     bfp = currentFormDataPtr;
5491 #else
5492     bfp = GetObjectExtra (i);
5493 #endif
5494   }
5495   if (bfp == NULL) return;
5496   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5497   if (sep == NULL) return;
5498   WatchCursor ();
5499   Update ();
5500   AddOrgToDef (bfp->input_entityID, sep, orgmod, subsource);
5501   ArrowCursor ();
5502   Update ();
5503   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5504   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5505 }
5506 
RemoveAlignmentCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)5507 static void RemoveAlignmentCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
5508 
5509 {
5510   BioseqPtr      bsp;
5511   BioseqSetPtr   bssp;
5512   SeqAlignPtr    nextsalp;
5513   SeqAnnotPtr    nextsap;
5514   Pointer PNTR   prevsalp;
5515   Pointer PNTR   prevsap;
5516   SeqAlignPtr    salp;
5517   SeqAnnotPtr    sap;
5518 
5519   if (sep == NULL || sep->data.ptrvalue == NULL) return;
5520   if (IS_Bioseq (sep)) {
5521     bsp = (BioseqPtr) sep->data.ptrvalue;
5522     sap = bsp->annot;
5523     prevsap = (Pointer PNTR) &(bsp->annot);
5524   } else if (IS_Bioseq_set (sep)) {
5525     bssp = (BioseqSetPtr) sep->data.ptrvalue;
5526     sap = bssp->annot;
5527     prevsap = (Pointer PNTR) &(bssp->annot);
5528   } else return;
5529   while (sap != NULL) {
5530     nextsap = sap->next;
5531     if (sap->type == 2) {
5532       salp = (SeqAlignPtr) sap->data;
5533       prevsalp = (Pointer PNTR) &(sap->data);
5534       while (salp != NULL) {
5535         nextsalp = salp->next;
5536         *(prevsalp) = salp->next;
5537         salp->next = NULL;
5538         SeqAlignFree (salp);
5539         salp = nextsalp;
5540       }
5541     }
5542     if (sap->data == NULL) {
5543       *(prevsap) = sap->next;
5544       sap->next = NULL;
5545       SeqAnnotFree (sap);
5546     } else {
5547       prevsap = (Pointer PNTR) &(sap->next);
5548     }
5549     sap = nextsap;
5550   }
5551 }
5552 
RemoveAlignment(IteM i)5553 extern void RemoveAlignment (IteM i)
5554 
5555 {
5556   BaseFormPtr bfp;
5557   SeqEntryPtr  sep;
5558 
5559 #ifdef WIN_MAC
5560   bfp = currentFormDataPtr;
5561 #else
5562   bfp = GetObjectExtra (i);
5563 #endif
5564   if (bfp == NULL) return;
5565   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5566   if (sep == NULL) return;
5567   SeqEntryExplore (sep, NULL, RemoveAlignmentCallback);
5568   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5569   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5570   ObjMgrDeSelect (0, 0, 0, 0, NULL);
5571   Update ();
5572 }
5573 
RemoveGraphCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)5574 static void RemoveGraphCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
5575 
5576 {
5577   BioseqPtr      bsp;
5578   BioseqSetPtr   bssp;
5579   SeqAnnotPtr    nextsap;
5580   SeqGraphPtr    nextsgp;
5581   Pointer PNTR   prevsap;
5582   Pointer PNTR   prevsgp;
5583   SeqAnnotPtr    sap;
5584   SeqGraphPtr    sgp;
5585 
5586   if (sep == NULL || sep->data.ptrvalue == NULL) return;
5587   if (IS_Bioseq (sep)) {
5588     bsp = (BioseqPtr) sep->data.ptrvalue;
5589     sap = bsp->annot;
5590     prevsap = (Pointer PNTR) &(bsp->annot);
5591   } else if (IS_Bioseq_set (sep)) {
5592     bssp = (BioseqSetPtr) sep->data.ptrvalue;
5593     sap = bssp->annot;
5594     prevsap = (Pointer PNTR) &(bssp->annot);
5595   } else return;
5596   while (sap != NULL) {
5597     nextsap = sap->next;
5598     if (sap->type == 3) {
5599       sgp = (SeqGraphPtr) sap->data;
5600       prevsgp = (Pointer PNTR) &(sap->data);
5601       while (sgp != NULL) {
5602         nextsgp = sgp->next;
5603         if (sgp->flags [2] >= 1 && sgp->flags [2] <= 3) {
5604           *(prevsgp) = sgp->next;
5605           sgp->next = NULL;
5606           SeqGraphFree (sgp);
5607         } else {
5608           prevsgp = (Pointer PNTR) &(sgp->next);
5609         }
5610         sgp = nextsgp;
5611       }
5612     }
5613     if (sap->data == NULL) {
5614       *(prevsap) = sap->next;
5615       sap->next = NULL;
5616       SeqAnnotFree (sap);
5617     } else {
5618       prevsap = (Pointer PNTR) &(sap->next);
5619     }
5620     sap = nextsap;
5621   }
5622 }
5623 
RemoveGraph(IteM i)5624 extern void RemoveGraph (IteM i)
5625 
5626 {
5627   BaseFormPtr bfp;
5628   SeqEntryPtr  sep;
5629 
5630 #ifdef WIN_MAC
5631   bfp = currentFormDataPtr;
5632 #else
5633   bfp = GetObjectExtra (i);
5634 #endif
5635   if (bfp == NULL) return;
5636   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5637   if (sep == NULL) return;
5638   SeqEntryExplore (sep, NULL, RemoveGraphCallback);
5639   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5640   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5641   ObjMgrDeSelect (0, 0, 0, 0, NULL);
5642   Update ();
5643 }
5644 
5645 
MarkProteinCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)5646 static void MarkProteinCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
5647 
5648 {
5649   BioseqPtr        bsp;
5650   ValNodePtr PNTR  vnpp;
5651 
5652   if (mydata == NULL) return;
5653   if (sep == NULL || sep->data.ptrvalue == NULL) return;
5654   vnpp = (ValNodePtr PNTR) mydata;
5655   if (vnpp == NULL) return;
5656   if (IS_Bioseq (sep)) {
5657     bsp = (BioseqPtr) sep->data.ptrvalue;
5658     if (ISA_aa (bsp->mol)) {
5659       /*
5660       ValNodeAddPointer (vnpp, 0, (Pointer) bsp);
5661       */
5662       bsp->idx.deleteme = TRUE;
5663     }
5664   }
5665 }
5666 
RemoveProteinsAndOptionallyRenormalize(IteM i,Boolean renormalize)5667 static void RemoveProteinsAndOptionallyRenormalize (IteM i, Boolean renormalize)
5668 
5669 {
5670   BaseFormPtr    bfp;
5671   BioseqPtr      bsp;
5672   Uint4          itemID;
5673   ObjMgrDataPtr  omdptop;
5674   ObjMgrData     omdata;
5675   OMProcControl  ompc;
5676   Uint2          parenttype;
5677   Pointer        parentptr;
5678   SeqEntryPtr    sep;
5679   ValNodePtr     tmp;
5680   ValNodePtr     vnp;
5681 
5682 #ifdef WIN_MAC
5683   bfp = currentFormDataPtr;
5684 #else
5685   bfp = GetObjectExtra (i);
5686 #endif
5687   if (bfp == NULL) return;
5688   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5689   if (sep == NULL) return;
5690   SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
5691   GetSeqEntryParent (sep, &parentptr, &parenttype);
5692   vnp = NULL;
5693   SeqEntryExplore (sep, (Pointer) &vnp, MarkProteinCallback);
5694   /*
5695   for (tmp = vnp; tmp != NULL; tmp = tmp->next) {
5696     bsp = (BioseqPtr) tmp->data.ptrvalue;
5697     itemID = GetItemIDGivenPointer (bfp->input_entityID, OBJ_BIOSEQ, (Pointer) bsp);
5698     if (itemID > 0) {
5699       MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
5700       ompc.do_not_reload_from_cache = TRUE;
5701       ompc.input_entityID = bfp->input_entityID;
5702       ompc.input_itemID = itemID;
5703       ompc.input_itemtype = OBJ_BIOSEQ;
5704       if (! DetachDataForProc (&ompc, FALSE)) {
5705         Message (MSG_POSTERR, "DetachDataForProc failed");
5706       }
5707     }
5708   }
5709   */
5710   ValNodeFree (vnp);
5711   DeleteMarkedObjects (bfp->input_entityID, 0, NULL);
5712   SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
5713   RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
5714   if (renormalize)
5715   {
5716     RenormalizeNucProtSets (sep, TRUE);
5717   }
5718   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5719   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5720   ObjMgrDeSelect (0, 0, 0, 0, NULL);
5721   Update ();
5722 }
5723 
RemoveProteins(IteM i)5724 extern void RemoveProteins (IteM i)
5725 {
5726   RemoveProteinsAndOptionallyRenormalize (i, FALSE);
5727 }
5728 
RemoveProteinsAndRenormalize(IteM i)5729 extern void RemoveProteinsAndRenormalize (IteM i)
5730 {
5731   RemoveProteinsAndOptionallyRenormalize (i, TRUE);
5732 }
5733 
5734 #define EDIT_FIVE_PRIME  1
5735 #define EDIT_THREE_PRIME 2
5736 
5737 #define ADD_TO_END       1
5738 #define TRIM_FROM_END    2
5739 
5740 #define TRIM_BY_SEQUENCE 1
5741 #define TRIM_BY_COUNT    2
5742 
5743 typedef struct edseqendsdata {
5744   FEATURE_FORM_BLOCK
5745 
5746   TexT           seq;
5747   TexT           genename;
5748   GrouP          whichend;
5749   GrouP          addOrTrim;
5750   Int2           addOrTrimBool;
5751   GrouP          trimBy;
5752   Int2           trimByBool;
5753   Int4           trimCount;
5754   TexT           trimCountText;
5755   ButtoN         extendfeat;
5756   LisT           nuc_sequence_list_ctrl;
5757   ButtoN         addCitSub;
5758   CharPtr        seqstr;
5759   CharPtr        genestr;
5760   Int2           endval;
5761   Int2           frameshift;
5762   Boolean        adjustframe;
5763   Boolean        extendflag;
5764   BioseqPtr      extendedthis;
5765   SeqEntryPtr    sep;
5766   Boolean        rsult;
5767 } EditSeqEnds, PNTR EditSeqPtr;
5768 
GeneFindByNameFunc(GatherContextPtr gcp)5769 static Boolean GeneFindByNameFunc (GatherContextPtr gcp)
5770 
5771 {
5772   EditSeqPtr  esp;
5773   GeneRefPtr  grp;
5774   SeqFeatPtr  sfp;
5775 
5776   if (gcp == NULL) return TRUE;
5777   esp = (EditSeqPtr) gcp->userdata;
5778   if (esp == NULL) return TRUE;
5779   if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
5780   sfp = (SeqFeatPtr) gcp->thisitem;
5781   if (sfp == NULL) return TRUE;
5782   if (sfp->data.choice != SEQFEAT_GENE) return TRUE;
5783   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
5784   if (grp == NULL) return TRUE;
5785   if (StringICmp (grp->locus, esp->genestr) == 0) {
5786     esp->rsult = TRUE;
5787   }
5788   return TRUE;
5789 }
5790 
EditSeqEntryHasGene(BioseqPtr bsp,SeqEntryPtr sep,EditSeqPtr esp)5791 static Boolean EditSeqEntryHasGene (BioseqPtr bsp, SeqEntryPtr sep, EditSeqPtr esp)
5792 
5793 {
5794   GatherScope  gs;
5795 
5796   if (esp->input_entityID == 0 || esp->sep == NULL) return FALSE;
5797   if (StringHasNoText (esp->genestr)) return TRUE;
5798   esp->rsult = FALSE;
5799   MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
5800   gs.seglevels = 1;
5801   gs.get_feats_location = TRUE;
5802   gs.scope = sep;
5803   MemSet ((Pointer)(gs.ignore), (int) (TRUE), (size_t) (OBJ_MAX * sizeof (Boolean)));
5804   gs.ignore [OBJ_BIOSEQ] = FALSE;
5805   gs.ignore [OBJ_BIOSEQ_SEG] = FALSE;
5806   gs.ignore [OBJ_SEQFEAT] = FALSE;
5807   gs.ignore [OBJ_SEQANNOT] = FALSE;
5808   GatherEntity (esp->input_entityID, (Pointer) esp, GeneFindByNameFunc, &gs);
5809   gs.target = SeqLocFree (gs.target);
5810   return esp->rsult;
5811 }
5812 
FixACDSFunc(GatherContextPtr gcp)5813 static Boolean FixACDSFunc (GatherContextPtr gcp)
5814 
5815 {
5816   SeqFeatPtr    bestprot;
5817   ByteStorePtr  bs;
5818   BioseqPtr     bsp;
5819   Char          ch;
5820   CdRegionPtr   crp;
5821   EditSeqPtr    esp;
5822   Int2          frame;
5823   Boolean       partial5;
5824   Boolean       partial3;
5825   CharPtr       prot;
5826   CharPtr       ptr;
5827   SeqEntryPtr   sep;
5828   SeqFeatPtr    sfp;
5829   SeqIdPtr      sip;
5830   SeqLocPtr     slp;
5831 
5832   if (gcp == NULL) return TRUE;
5833   esp = (EditSeqPtr) gcp->userdata;
5834   if (esp == NULL) return TRUE;
5835   if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
5836   sfp = (SeqFeatPtr) gcp->thisitem;
5837   if (sfp == NULL) return TRUE;
5838   if (sfp->data.choice != SEQFEAT_CDREGION) return TRUE;
5839   slp = SeqLocFindNext (sfp->location, NULL);
5840   if (slp == NULL) return TRUE;
5841   CheckSeqLocForPartial (slp, &partial5, &partial3);
5842   sip = SeqLocId (slp);
5843   if (sip == NULL) return TRUE;
5844   bsp = BioseqFind (sip);
5845   if (bsp == NULL || bsp != esp->extendedthis) return TRUE;
5846   if (esp->adjustframe) {
5847     if (GetOffsetInBioseq (slp, bsp, SEQLOC_START) != 0) return TRUE;
5848     crp = (CdRegionPtr) sfp->data.value.ptrvalue;
5849     if (crp == NULL) return TRUE;
5850     frame = crp->frame;
5851     if (frame == 0)
5852       frame = 1;
5853     if (esp->addOrTrimBool == ADD_TO_END)
5854       {
5855 	frame--;
5856 	frame += esp->frameshift;
5857 	crp->frame = (frame % 3) + 1;
5858       }
5859     else if (esp->addOrTrimBool == TRIM_FROM_END)
5860       {
5861 	frame = ABS(frame - esp->frameshift);
5862 	crp->frame = 3 - (frame % 3);
5863       }
5864   } else {
5865     if (GetOffsetInBioseq (slp, bsp, SEQLOC_STOP) != bsp->length - 1)
5866       return TRUE;
5867   }
5868   sip = SeqLocId (sfp->product);
5869   if (sip == NULL) return TRUE;
5870   bsp = BioseqFind (sip);
5871   if (bsp == NULL) return TRUE;
5872   if (bsp->repr != Seq_repr_raw) return TRUE;
5873   if (bsp->mol != Seq_mol_aa) return TRUE;
5874   bestprot = FindBestProtein (esp->input_entityID, sfp->product);
5875   bs = ProteinFromCdRegionEx (sfp, FALSE, FALSE);
5876   if (bs == NULL) return TRUE;
5877   prot = BSMerge (bs, NULL);
5878   bs = BSFree (bs);
5879   if (prot == NULL) return TRUE;
5880   ptr = prot;
5881   ch = *ptr;
5882   while (ch != '\0') {
5883     *ptr = TO_UPPER (ch);
5884     ptr++;
5885     ch = *ptr;
5886   }
5887   bs = BSNew (1000);
5888   if (bs != NULL) {
5889     ptr = prot;
5890     /*
5891     if (prot [0] == '-') {
5892        ptr++;
5893     }
5894     */
5895     BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
5896     bsp->seq_data = SeqDataFree (bsp->seq_data, bsp->seq_data_type);
5897     bsp->seq_data = (SeqDataPtr) bs;
5898     bsp->length = BSLen (bs);
5899     bsp->seq_data_type = Seq_code_ncbieaa;
5900   }
5901   if (bestprot == NULL) return TRUE;
5902   sep = SeqMgrGetSeqEntryForData (bsp);
5903   bestprot->location = SeqLocFree (bestprot->location);
5904   bestprot->location = CreateWholeInterval (sep);
5905   SetSeqLocPartial (bestprot->location, partial5, partial3);
5906   return TRUE;
5907 }
5908 
FixAndRetranslateCDSs(BioseqPtr bsp,SeqEntryPtr sep,EditSeqPtr esp,Boolean adjustframe)5909 static void FixAndRetranslateCDSs (BioseqPtr bsp, SeqEntryPtr sep,
5910                                    EditSeqPtr esp, Boolean adjustframe)
5911 
5912 {
5913   GatherScope  gs;
5914 
5915   if (esp->input_entityID == 0 || esp->sep == NULL) return;
5916   esp->adjustframe = adjustframe;
5917   MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
5918   gs.seglevels = 1;
5919   gs.get_feats_location = FALSE;
5920   gs.scope = sep;
5921   MemSet ((Pointer)(gs.ignore), (int) (TRUE), (size_t) (OBJ_MAX * sizeof (Boolean)));
5922   gs.ignore [OBJ_BIOSEQ] = FALSE;
5923   gs.ignore [OBJ_BIOSEQ_SEG] = FALSE;
5924   gs.ignore [OBJ_SEQFEAT] = FALSE;
5925   gs.ignore [OBJ_SEQANNOT] = FALSE;
5926   GatherEntity (esp->input_entityID, (Pointer) esp, FixACDSFunc, &gs);
5927   gs.target = SeqLocFree (gs.target);
5928 }
5929 
CollectAndExtendSingleBaseFeatures(BioseqPtr bsp,Int2 whichend,Int4 len)5930 static ValNodePtr CollectAndExtendSingleBaseFeatures (BioseqPtr bsp, Int2 whichend, Int4 len)
5931 
5932 {
5933   SeqMgrFeatContext  context;
5934   ValNodePtr         head = NULL;
5935   SeqFeatPtr         sfp;
5936   SeqLocPtr          slp;
5937   SeqPntPtr          spp;
5938 
5939   sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
5940   while (sfp != NULL) {
5941     if (whichend == 1 && context.numivals == 1 && context.right == 0) {
5942       slp = sfp->location;
5943       if (slp != NULL && slp->choice == SEQLOC_PNT && slp->next == NULL) {
5944         spp = (SeqPntPtr) slp->data.ptrvalue;
5945         if (spp != NULL && spp->point == 0) {
5946           spp->point = 1;
5947           ValNodeAddPointer (&head, 1, (Pointer) sfp);
5948         }
5949       }
5950     } else if (whichend == 2 && context.numivals == 1 && context.left == bsp->length - 1) {
5951       slp = sfp->location;
5952       if (slp != NULL && slp->choice == SEQLOC_PNT && slp->next == NULL) {
5953         spp = (SeqPntPtr) slp->data.ptrvalue;
5954         if (spp != NULL && spp->point == bsp->length - 1) {
5955           spp->point = bsp->length - 2;
5956           ValNodeAddPointer (&head, 2, (Pointer) sfp);
5957         }
5958       }
5959     }
5960     sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
5961   }
5962 
5963   return head;
5964 }
5965 
ReadjustSingleBaseFeatures(ValNodePtr head,BioseqPtr bsp,Int2 whichend,Int4 len)5966 static void ReadjustSingleBaseFeatures (ValNodePtr head, BioseqPtr bsp, Int2 whichend, Int4 len)
5967 
5968 {
5969   SeqFeatPtr  sfp;
5970   SeqIntPtr   sintp;
5971   SeqLocPtr   slp;
5972   SeqPntPtr   spp;
5973   ValNodePtr  vnp;
5974 
5975   for (vnp = head; vnp != NULL; vnp = vnp->next) {
5976     sfp = (SeqFeatPtr) vnp->data.ptrvalue;
5977     if (sfp != NULL) {
5978       slp = sfp->location;
5979       if (slp != NULL && slp->choice == SEQLOC_PNT && slp->next == NULL) {
5980         spp = (SeqPntPtr) slp->data.ptrvalue;
5981         if (spp != NULL) {
5982           if (whichend == 1) {
5983             sintp = SeqIntNew ();
5984             if (sintp != NULL) {
5985               sintp->from = 0;
5986               sintp->to = spp->point - 1;
5987               sintp->strand = spp->strand;
5988               sintp->id = spp->id;
5989               spp->id = NULL;
5990               sintp->if_from = spp->fuzz;
5991               spp->fuzz = NULL;
5992               slp->choice = SEQLOC_INT;
5993               slp->data.ptrvalue = (Pointer) sintp;
5994               SeqPntFree (spp);
5995             }
5996           } else if (whichend == 2) {
5997             sintp = SeqIntNew ();
5998             if (sintp != NULL) {
5999               sintp->from = spp->point + 1;
6000               sintp->to = spp->point + 1 + len;
6001               sintp->strand = spp->strand;
6002               sintp->id = spp->id;
6003               spp->id = NULL;
6004               sintp->if_to = spp->fuzz;
6005               spp->fuzz = NULL;
6006               slp->choice = SEQLOC_INT;
6007               slp->data.ptrvalue = (Pointer) sintp;
6008               SeqPntFree (spp);
6009             }
6010           }
6011         }
6012       }
6013     }
6014   }
6015 }
6016 
TrimFromSequenceEnd(EditSeqPtr esp,SeqEntryPtr sep,BioseqPtr bsp)6017 static void TrimFromSequenceEnd (EditSeqPtr  esp,
6018 				 SeqEntryPtr sep,
6019 				 BioseqPtr   bsp)
6020 {
6021   CharPtr currSeqStr;
6022   Int2    length;
6023   Int4    pos;
6024   Int4    trim_length;
6025 
6026   /* Get the current sequence string */
6027 
6028   currSeqStr = GetSequenceByBsp (bsp);
6029 
6030   /* Trim from either the 5' end (i.e., */
6031   /* the beginning of the string...     */
6032 
6033   if (esp->endval == EDIT_FIVE_PRIME)
6034   {
6035     /* Find end point */
6036 
6037     if (esp->trimByBool == TRIM_BY_SEQUENCE)
6038 	  {
6039 	    length = StringLen (esp->seqstr);
6040 	    if (StringNICmp (esp->seqstr, currSeqStr, length) != 0)
6041 	      return;
6042 	    pos = length - 1;
6043       trim_length = length;
6044 	  }
6045     else  if (esp->trimByBool == TRIM_BY_COUNT)
6046     {
6047 	    pos = esp->trimCount - 1;
6048       trim_length = esp->trimCount;
6049     }
6050     else
6051 	    return;
6052 
6053     /* Trim from beginning of string to end point */
6054 
6055     esp->frameshift = trim_length;
6056     BioseqDelete (bsp->id, 0, pos, TRUE, FALSE);
6057     esp->extendedthis = bsp;
6058     FixAndRetranslateCDSs (bsp, sep, esp, TRUE);
6059 
6060     /* trim quality scores */
6061     TrimQualityScores (bsp, trim_length, TRUE);
6062   }
6063 
6064   /* .. or the 3' end (i.e., the */
6065   /* end of the string.          */
6066 
6067   else if (esp->endval == EDIT_THREE_PRIME)
6068   {
6069     /* Find trim point */
6070 
6071     if (esp->trimByBool == TRIM_BY_SEQUENCE)
6072 	  {
6073 	    length = StringLen (esp->seqstr);
6074 	    pos = bsp->length - length;
6075 	    if (StringICmp (esp->seqstr, &currSeqStr[pos]) != 0)
6076 	      return;
6077       trim_length = length;
6078 	  }
6079     else  if (esp->trimByBool == TRIM_BY_COUNT)
6080     {
6081 	    pos = bsp->length - esp->trimCount;
6082       trim_length = esp->trimCount;
6083     }
6084     else
6085 	    return;
6086 
6087     /* Trim from there to end of string */
6088 
6089     BioseqDelete (bsp->id, pos, bsp->length - 1, TRUE, FALSE);
6090     esp->extendedthis = bsp;
6091     FixAndRetranslateCDSs (bsp, sep, esp, FALSE);
6092 
6093     /* trim quality scores */
6094     TrimQualityScores (bsp, trim_length, FALSE);
6095   }
6096 }
6097 
6098 static void
AddToSequenceEnd(EditSeqPtr esp,SeqEntryPtr sep,BioseqPtr bsp,LogInfoPtr lip)6099 AddToSequenceEnd
6100 (EditSeqPtr  esp,
6101  SeqEntryPtr sep,
6102  BioseqPtr   bsp,
6103  LogInfoPtr lip)
6104 {
6105   ValNodePtr    head;
6106   Int4          len;
6107   Int4          pos;
6108   Uint1         residue;
6109   SeqPortPtr    spp;
6110   CharPtr       str;
6111   Char          terminal [2];
6112 
6113   pos = 0;
6114   if (esp->endval == 2) {
6115     pos = bsp->length;
6116   }
6117   if (esp->extendflag) {
6118     esp->frameshift = 0;
6119     terminal [0] = '\0';
6120     terminal [1] = '\0';
6121     residue = 0;
6122     if (esp->endval == 2) {
6123       spp = SeqPortNew (bsp, bsp->length - 1, -1, 0, Seq_code_iupacna);
6124     } else {
6125       spp = SeqPortNew (bsp, 0, -1, 0, Seq_code_iupacna);
6126     }
6127     if (spp != NULL) {
6128       residue = SeqPortGetResidue (spp);
6129       if (IS_residue (residue)) {
6130         terminal [0] = TO_LOWER ((Char) residue);
6131       }
6132     }
6133     SeqPortFree (spp);
6134     str = MemNew ((size_t) (StringLen (esp->seqstr) + 4));
6135     if (str != NULL) {
6136       head = NULL;
6137       if (esp->endval == 2) {
6138         esp->extendedthis = bsp;
6139         StringCpy (str, terminal);
6140         StringCat (str, esp->seqstr);
6141         len = StringLen (esp->seqstr);
6142         pos = bsp->length - 1;
6143         head = CollectAndExtendSingleBaseFeatures (bsp, 2, len);
6144         insertchar (str, pos, bsp->id, bsp->mol, FALSE);
6145         BioseqDelete (bsp->id, bsp->length - 1, bsp->length - 1,
6146 		      TRUE, FALSE);
6147         ReadjustSingleBaseFeatures (head, bsp, 2, len);
6148         FixAndRetranslateCDSs (bsp, sep, esp, FALSE);
6149       } else {
6150         esp->frameshift = (Int2) StringLen (esp->seqstr);
6151         esp->extendedthis = bsp;
6152         StringCpy (str, esp->seqstr);
6153         StringCat (str, terminal);
6154         len = StringLen (esp->seqstr);
6155         pos = 1;
6156         head = CollectAndExtendSingleBaseFeatures (bsp, 1, len);
6157         insertchar (str, pos, bsp->id, bsp->mol, FALSE);
6158         BioseqDelete (bsp->id, 0, 0, TRUE, FALSE);
6159         ReadjustSingleBaseFeatures (head, bsp, 1, len);
6160         FixAndRetranslateCDSs (bsp, sep, esp, TRUE);
6161       }
6162       ValNodeFree (head);
6163       if (lip != NULL) {
6164         RemoveQualityScores (bsp, lip->fp, &(lip->data_in_log));
6165       }
6166     }
6167     MemFree (str);
6168   } else {
6169     insertchar (esp->seqstr, pos, bsp->id, bsp->mol, FALSE);
6170     if (lip != NULL) {
6171       RemoveQualityScores (bsp, lip->fp, &(lip->data_in_log));
6172     }
6173   }
6174 }
6175 
6176 
DoEditSeqEndsProc(ButtoN b)6177 static void DoEditSeqEndsProc (ButtoN b)
6178 
6179 {
6180   Char        ch;
6181   EditSeqPtr  esp;
6182   CharPtr     p, q;
6183   CharPtr     tempStr;
6184   ValNodePtr  sip_list, vnp;
6185   SeqIdPtr    sip;
6186   BioseqPtr   bsp;
6187   SeqEntryPtr sep;
6188   Boolean     add_cit_subs = FALSE;
6189   LogInfoPtr  lip;
6190 
6191   esp = (EditSeqPtr) GetObjectExtra (b);
6192   if (esp == NULL) {
6193     Remove (ParentWindow (b));
6194     return;
6195   }
6196   sip_list = GetSelectedSequenceList (esp->nuc_sequence_list_ctrl);
6197   if (sip_list == NULL)
6198   {
6199     Message (MSG_ERROR, "You have not specified any sequences to edit!");
6200     return;
6201   }
6202 
6203   Hide (esp->form);
6204   Update ();
6205   esp->seqstr = SaveStringFromText  (esp->seq);
6206   p = esp->seqstr;
6207   if (p != NULL) {
6208     /* remove any non-sequence characters */
6209     q = p;
6210     ch = *p;
6211     while (ch != '\0') {
6212       if (IS_ALPHA (ch)) {
6213         *q = ch;
6214         q++;
6215       }
6216       p++;
6217       ch = *p;
6218     }
6219     *q = '\0';
6220   }
6221   esp->genestr       = SaveStringFromText  (esp->genename);
6222   esp->endval        = GetValue (esp->whichend);
6223   esp->extendflag    = GetStatus (esp->extendfeat);
6224   esp->addOrTrimBool = GetValue (esp->addOrTrim);
6225   esp->trimByBool    = GetValue (esp->trimBy);
6226   tempStr            = SaveStringFromText (esp->trimCountText);
6227   if (tempStr != NULL)
6228     esp->trimCount   = atoi (tempStr);
6229   else
6230     esp->trimCount   = 0;
6231 
6232   add_cit_subs = GetStatus (esp->addCitSub);
6233 
6234   lip = OpenLog ("Quality Scores Affected");
6235   for (vnp = sip_list; vnp != NULL; vnp = vnp->next)
6236   {
6237     sip = (SeqIdPtr) vnp->data.ptrvalue;
6238     bsp = BioseqFind (sip);
6239     sep = SeqMgrGetSeqEntryForData (bsp);
6240     if (bsp != NULL && sep != NULL && EditSeqEntryHasGene (bsp, sep, esp))
6241     {
6242       if (esp->addOrTrimBool == 1)
6243         AddToSequenceEnd (esp, sep, bsp, lip);
6244       else
6245         TrimFromSequenceEnd (esp, sep, bsp);
6246       if (add_cit_subs)
6247       {
6248         AddCitSubToUpdatedSequence (bsp, esp->input_entityID, kSubmitterUpdateText);
6249       }
6250     }
6251   }
6252   CloseLog (lip);
6253   lip = FreeLog (lip);
6254 
6255   MemFree (esp->seqstr);
6256   MemFree (esp->genestr);
6257   ObjMgrSetDirtyFlag (esp->input_entityID, TRUE);
6258   ObjMgrSendMsg (OM_MSG_UPDATE, esp->input_entityID, 0, 0);
6259   Remove (esp->form);
6260 }
6261 
EditSeqMessageProc(ForM f,Int2 mssg)6262 static void EditSeqMessageProc (ForM f, Int2 mssg)
6263 
6264 {
6265   EditSeqPtr  esp;
6266 
6267   esp = (EditSeqPtr) GetObjectExtra (f);
6268   if (esp != NULL) {
6269     if (esp->appmessage != NULL) {
6270       esp->appmessage (f, mssg);
6271     }
6272   }
6273 }
6274 
ChangeAddOrTrim_Callback(GrouP g)6275 static void ChangeAddOrTrim_Callback (GrouP g)
6276 
6277 {
6278   EditSeqPtr  esp;
6279   Int2        val;
6280   Int2        trimByState;
6281 
6282   val = GetValue (g);
6283   esp = GetObjectExtra (g);
6284 
6285   switch (val) {
6286     case ADD_TO_END :
6287       SafeDisable (esp->trimBy);
6288       SafeEnable (esp->extendfeat);
6289       SafeDisable (esp->trimCountText);
6290       SafeEnable (esp->seq);
6291       break;
6292     case TRIM_FROM_END :
6293       SafeDisable (esp->extendfeat);
6294       SafeEnable (esp->trimBy);
6295       trimByState = GetValue (esp->trimBy);
6296       switch (trimByState) {
6297         case TRIM_BY_SEQUENCE :
6298 	  SafeDisable (esp->trimCountText);
6299 	  SafeEnable (esp->seq);
6300 	  break;
6301         case TRIM_BY_COUNT :
6302 	  SafeEnable (esp->trimCountText);
6303 	  SafeDisable (esp->seq);
6304 	  break;
6305         default :
6306 	  break;
6307       }
6308       break;
6309     default :
6310       break;
6311   }
6312 }
6313 
ChangeTrimBy_Callback(GrouP g)6314 static void ChangeTrimBy_Callback (GrouP g)
6315 
6316 {
6317   EditSeqPtr  esp;
6318   Int2        val;
6319 
6320   val = GetValue (g);
6321   esp = GetObjectExtra (g);
6322 
6323   switch (val) {
6324     case TRIM_BY_SEQUENCE :
6325       SafeDisable (esp->trimCountText);
6326       SafeEnable (esp->seq);
6327       break;
6328     case TRIM_BY_COUNT :
6329       SafeEnable (esp->trimCountText);
6330       SafeDisable (esp->seq);
6331       break;
6332     default :
6333       break;
6334   }
6335 }
6336 
SelectAllSequencesForExtend(ButtoN b)6337 static void SelectAllSequencesForExtend (ButtoN b)
6338 {
6339   EditSeqPtr    esp;
6340 
6341   esp = (EditSeqPtr) GetObjectExtra (b);
6342   if (esp == NULL)
6343   {
6344     return;
6345   }
6346   SelectAllSequencesInListCtrl (esp->nuc_sequence_list_ctrl);
6347 }
6348 
UnSelectAllSequencesForExtend(ButtoN b)6349 static void UnSelectAllSequencesForExtend (ButtoN b)
6350 {
6351   EditSeqPtr    esp;
6352 
6353   esp = (EditSeqPtr) GetObjectExtra (b);
6354   if (esp == NULL)
6355   {
6356     return;
6357   }
6358   UnSelectAllSequencesInListCtrl (esp->nuc_sequence_list_ctrl);
6359 }
6360 
6361 extern void EditSeqEndsProc (IteM i);
6362 
EditSeqEndsProc(IteM i)6363 extern void EditSeqEndsProc (IteM i)
6364 
6365 {
6366   ButtoN             b;
6367   BaseFormPtr        bfp;
6368   GrouP              c;
6369   EditSeqPtr         esp;
6370   GrouP              g;
6371   GrouP              h;
6372   GrouP              k;
6373   GrouP              p;
6374   GrouP              q;
6375   GrouP              r;
6376   GrouP              s;
6377   SeqEntryPtr        sep;
6378   StdEditorProcsPtr  sepp;
6379   WindoW             w;
6380 
6381 #ifdef WIN_MAC
6382   bfp = currentFormDataPtr;
6383 #else
6384   bfp = GetObjectExtra (i);
6385 #endif
6386   if (bfp == NULL) return;
6387   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6388   if (sep == NULL) return;
6389   esp = (EditSeqPtr) MemNew (sizeof (EditSeqEnds));
6390   if (esp == NULL) return;
6391 
6392   w = FixedWindow (-50, -33, -10, -10, "Edit Sequence Ends", StdCloseWindowProc);
6393   SetObjectExtra (w, esp, StdCleanupFormProc);
6394   esp->form = (ForM) w;
6395   esp->formmessage = EditSeqMessageProc;
6396 
6397   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
6398   if (sepp != NULL) {
6399     SetActivate (w, sepp->activateForm);
6400     esp->appmessage = sepp->handleMessages;
6401   }
6402 
6403   esp->input_entityID = bfp->input_entityID;
6404   esp->input_itemID = bfp->input_itemID;
6405   esp->input_itemtype = bfp->input_itemtype;
6406 
6407   esp->sep = sep;
6408 
6409   h = HiddenGroup (w, -1, 0, NULL);
6410   SetGroupSpacing (h, 10, 10);
6411 
6412   g = HiddenGroup (h, 2, 0, NULL);
6413 
6414   StaticPrompt (g, "End", 0, stdLineHeight, programFont, 'l');
6415   esp->whichend = HiddenGroup (g, 2, 0, NULL);
6416   RadioButton (esp->whichend, "5'");
6417   RadioButton (esp->whichend, "3'");
6418   SetValue (esp->whichend, 1);
6419 
6420   esp->addOrTrim = HiddenGroup (h, 2, 0, ChangeAddOrTrim_Callback);
6421   SetObjectExtra (esp->addOrTrim, esp, NULL);
6422   RadioButton (esp->addOrTrim, "Add to end");
6423   RadioButton (esp->addOrTrim, "Trim from end");
6424   SetValue (esp->addOrTrim, 1);
6425 
6426   k = HiddenGroup (h, 0, -2, NULL);
6427   StaticPrompt (k, "Sequence", 0, 0, programFont, 'l');
6428   esp->seq = ScrollText (k, 25, 5, programFont, TRUE, NULL);
6429 
6430   q = HiddenGroup (h, 2, 0, NULL);
6431   StaticPrompt (q, "Optional gene constraint", 0, dialogTextHeight,
6432 		programFont, 'l');
6433   esp->genename = DialogText (q, "", 14, NULL);
6434 
6435   esp->extendfeat = CheckBox (h, "Extend features", NULL);
6436 
6437   esp->trimBy = HiddenGroup (h, 2, 0, ChangeTrimBy_Callback);
6438   SetObjectExtra (esp->trimBy, esp, NULL);
6439   RadioButton (esp->trimBy, "Trim by sequence");
6440   RadioButton (esp->trimBy, "Trim by count");
6441   SetValue (esp->trimBy, 1);
6442   SafeDisable (esp->trimBy);
6443 
6444   p = HiddenGroup (h, 2, 0, NULL);
6445   StaticPrompt (p, "Trim count", 0, dialogTextHeight, programFont, 'l');
6446   esp->trimCountText = DialogText (p, "", 5, NULL);
6447   SafeDisable (esp->trimCountText);
6448 
6449   s = NormalGroup (h, -1, 0, "Choose Sequences To Edit", programFont, NULL);
6450   esp->nuc_sequence_list_ctrl = MakeSequenceListControl (s, sep, NULL, NULL, TRUE, FALSE);
6451 
6452   r = HiddenGroup (s, 2, 0, NULL);
6453   b = PushButton (r, "Select All", SelectAllSequencesForExtend);
6454   SetObjectExtra (b, esp, NULL);
6455   b = PushButton (r, "Unselect All", UnSelectAllSequencesForExtend);
6456   SetObjectExtra (b, esp, NULL);
6457   AlignObjects (ALIGN_CENTER, (HANDLE) esp->nuc_sequence_list_ctrl,
6458                 (HANDLE) r, NULL);
6459 
6460   esp->addCitSub = CheckBox (h, "Add Cit Subs to edited sequences", NULL);
6461 
6462   c = HiddenGroup (h, 4, 0, NULL);
6463   b = DefaultButton (c, "Accept", DoEditSeqEndsProc);
6464   SetObjectExtra (b, esp, NULL);
6465   PushButton (c, "Cancel", StdCancelButtonProc);
6466 
6467   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) esp->extendfeat,
6468 		(HANDLE) esp->addOrTrim, (HANDLE) esp->trimBy,
6469 		(HANDLE) k, (HANDLE) q, (HANDLE) p,
6470 		(HANDLE) s, (HANDLE) esp->addCitSub, (HANDLE) c, NULL);
6471   RealizeWindow (w);
6472   Show (w);
6473   Select (w);
6474   Select (esp->seq);
6475   Update ();
6476 }
6477 
SetAlignmentDim(SeqAlignPtr salp)6478 static void SetAlignmentDim (SeqAlignPtr salp)
6479 {
6480   AMAlignIndex2Ptr amaip;
6481   DenseSegPtr      dsp;
6482 
6483   if (salp == NULL || salp->dim > 0 || salp->saip == NULL) return;
6484 
6485   if (salp->saip->indextype == INDEX_PARENT)
6486   {
6487     amaip = (AMAlignIndex2Ptr)(salp->saip);
6488     salp->dim = amaip->sharedaln->dim;
6489   }
6490   else if (salp->saip->indextype == INDEX_CHILD)
6491   {
6492     dsp = (DenseSegPtr)(salp->segs);
6493   	salp->dim = dsp->dim;
6494   }
6495 }
6496 
IndexAlignmentSet(SeqAlignPtr salp)6497 static void IndexAlignmentSet (SeqAlignPtr salp)
6498 {
6499   SeqAlignPtr tmp_salp, next_salp;
6500 
6501   if (salp == NULL || salp->saip != NULL) return;
6502 
6503   if (salp->next != NULL && salp->dim > 2)
6504   {
6505   	for (tmp_salp = salp; tmp_salp != NULL; tmp_salp = tmp_salp->next)
6506   	{
6507   	  next_salp = tmp_salp->next;
6508   	  tmp_salp->next = NULL;
6509       if (tmp_salp->segtype == SAS_DENSEG  &&  tmp_salp->next == NULL) {
6510         AlnMgr2IndexSingleChildSeqAlign(tmp_salp);
6511       } else {
6512         AlnMgr2IndexSeqAlign(tmp_salp);
6513       }
6514       SetAlignmentDim (tmp_salp);
6515       tmp_salp->next = next_salp;
6516   	}
6517   }
6518   else
6519   {
6520     if (salp->segtype == SAS_DENSEG  &&  salp->next == NULL) {
6521       AlnMgr2IndexSingleChildSeqAlign(salp);
6522     } else {
6523       AlnMgr2IndexSeqAlign(salp);
6524     }
6525     SetAlignmentDim (salp);
6526   }
6527 }
6528 
WriteSeqEntryAlignmentToFile(SeqEntryPtr sep,FILE * fp,Boolean Interleave)6529 static void WriteSeqEntryAlignmentToFile (SeqEntryPtr sep, FILE *fp, Boolean Interleave)
6530 {
6531   BioseqSetPtr bssp;
6532   SeqAnnotPtr  sap;
6533   SeqAlignPtr  salp = NULL;
6534 
6535   if (sep == NULL || ! IS_Bioseq_set (sep)) return;
6536   bssp = (BioseqSetPtr) sep->data.ptrvalue;
6537   if (bssp == NULL) return;
6538   for (sap = bssp->annot; sap != NULL; sap = sap->next) {
6539     if (sap->type == 2) {
6540       salp = SeqAlignListDup((SeqAlignPtr) sap->data);
6541       IndexAlignmentSet (salp);
6542 
6543       if (Interleave) {
6544         if (salp->next != NULL)
6545         {
6546           Message (MSG_ERROR, "Unable to write segmented alignments as interleave");
6547           return;
6548         }
6549         WriteAlignmentInterleaveToFile (salp, fp, 40, FALSE);
6550       } else {
6551         WriteAlignmentContiguousToFile (salp, fp, 40, FALSE);
6552       }
6553       SeqAlignFree (salp);
6554       salp = NULL;
6555     }
6556   }
6557 
6558   for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
6559     WriteSeqEntryAlignmentToFile (sep, fp, Interleave);
6560   }
6561 }
6562 
ExportAlignment(IteM i,Boolean Interleave)6563 static void ExportAlignment (IteM i, Boolean Interleave)
6564 {
6565   BaseFormPtr bfp;
6566   SeqEntryPtr sep;
6567   Char        path [PATH_MAX];
6568   FILE *      fp;
6569 
6570 #ifdef WIN_MAC
6571   bfp = currentFormDataPtr;
6572 #else
6573   bfp = GetObjectExtra (i);
6574 #endif
6575   if (bfp == NULL) return;
6576   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6577   if (sep == NULL) return;
6578 
6579   if (! GetOutputFileName (path, sizeof (path), "")) return;
6580   if (! StringHasNoText (path)) {
6581     fp = FileOpen (path, "w");
6582     if (fp != NULL) {
6583       WatchCursor ();
6584       Update();
6585       WriteSeqEntryAlignmentToFile (sep, fp, Interleave);
6586       ArrowCursor ();
6587       Update();
6588       FileClose (fp);
6589     } else {
6590       Message (MSG_ERROR, "Unable to open file");
6591     }
6592   }
6593 }
6594 
ExportAlignmentInterleave(IteM i)6595 extern void ExportAlignmentInterleave (IteM i)
6596 {
6597   ExportAlignment (i, TRUE);
6598 }
6599 
ExportAlignmentContiguous(IteM i)6600 extern void ExportAlignmentContiguous (IteM i)
6601 {
6602   ExportAlignment (i, FALSE);
6603 }
6604 
6605 
6606 typedef struct objstringdata
6607 {
6608   StringConstraintXPtr scp;
6609   Boolean found;
6610 } ObjStringData, PNTR ObjStringPtr;
6611 
AsnWriteStringConstraintCallBack(AsnExpOptStructPtr pAEOS)6612 static void LIBCALLBACK AsnWriteStringConstraintCallBack (AsnExpOptStructPtr pAEOS)
6613 
6614 {
6615   CharPtr        pchSource;
6616   ObjStringPtr   osp;
6617 
6618   osp = (ObjStringPtr) pAEOS->data;
6619   if (ISA_STRINGTYPE (AsnFindBaseIsa (pAEOS->atp)))
6620   {
6621 	  pchSource = (CharPtr) pAEOS->dvp->ptrvalue;
6622     if (DoesStringMatchConstraintX (pchSource, osp->scp))
6623     {
6624       osp->found = TRUE;
6625     }
6626   }
6627 }
6628 
DoesBioseqMatchStringConstraint(BioseqPtr bsp,StringConstraintXPtr scp)6629 static Boolean DoesBioseqMatchStringConstraint (BioseqPtr bsp, StringConstraintXPtr scp)
6630 
6631 {
6632   ObjMgrPtr         omp;
6633   ObjMgrTypePtr     omtp;
6634   AsnExpOptPtr      aeop;
6635   AsnIoPtr          aip;
6636   ObjStringData     osd;
6637 
6638   omp = ObjMgrGet ();
6639   if (omp == NULL) return FALSE;
6640   omtp = ObjMgrTypeFind (omp, OBJ_BIOSEQ, NULL, NULL);
6641   if (omtp == NULL) return FALSE;
6642 
6643   aip = AsnIoNullOpen ();
6644   aeop = AsnExpOptNew (aip, NULL, NULL, AsnWriteStringConstraintCallBack);
6645   if (aeop != NULL) {
6646     aeop->user_data = (Pointer) &osd;
6647   }
6648   osd.scp = scp;
6649 
6650   osd.found = FALSE;
6651   (omtp->asnwrite) (bsp, aip, NULL);
6652   AsnIoClose (aip);
6653 
6654   if (scp != NULL && scp->not_present)
6655   {
6656     osd.found = ! osd.found;
6657   }
6658 
6659   return osd.found;
6660 }
6661 
6662 
DoBioseqFeaturesMatchSequenceConstraintX(BioseqPtr bsp,ValNodePtr feat_list,StringConstraintXPtr scp)6663 extern Boolean DoBioseqFeaturesMatchSequenceConstraintX (BioseqPtr bsp, ValNodePtr feat_list, StringConstraintXPtr scp)
6664 {
6665   AsnExpOptPtr            aeop;
6666   AsnIoPtr                aip;
6667   ObjStringData           osd;
6668   SeqFeatPtr              sfp;
6669   ObjMgrPtr               omp;
6670   ObjMgrTypePtr           omtp;
6671   SeqMgrFeatContext       fcontext;
6672   ValNodePtr              vnp;
6673 
6674   if (bsp == NULL) return FALSE;
6675   if (scp == NULL) return TRUE;
6676   omp = ObjMgrGet ();
6677   if (omp == NULL) return FALSE;
6678   omtp = ObjMgrTypeFind (omp, OBJ_SEQFEAT, NULL, NULL);
6679   if (omtp == NULL) return FALSE;
6680 
6681   aip = AsnIoNullOpen ();
6682   osd.scp = scp;
6683 
6684   aeop = AsnExpOptNew (aip, NULL, NULL, AsnWriteStringConstraintCallBack);
6685   if (aeop != NULL) {
6686     aeop->user_data = (Pointer) &osd;
6687   }
6688 
6689   for (vnp = feat_list; vnp != NULL; vnp = vnp->next)
6690   {
6691     for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, vnp->choice, &fcontext);
6692          sfp != NULL;
6693          sfp = SeqMgrGetNextFeature (bsp, sfp, 0, vnp->choice, &fcontext))
6694     {
6695       osd.found = FALSE;
6696       (omtp->asnwrite) (sfp, aip, NULL);
6697       if (osd.found)
6698       {
6699         if (scp->not_present)
6700         {
6701           AsnIoClose (aip);
6702           return FALSE;
6703         }
6704         else
6705         {
6706           AsnIoClose (aip);
6707           return TRUE;
6708         }
6709       }
6710     }
6711   }
6712   AsnIoClose (aip);
6713   if (scp->not_present)
6714   {
6715     return TRUE;
6716   }
6717   else
6718   {
6719     return FALSE;
6720   }
6721 }
6722 
6723 
6724 typedef struct keywordform
6725 {
6726   FORM_MESSAGE_BLOCK
6727   DialoG constraint_dlg;
6728   TexT   keyword_txt;
6729 
6730   ParseFieldPtr pfp;
6731   FilterSetPtr  fsp;
6732   CharPtr       keyword;
6733   ValNodePtr    constraint;
6734 } KeywordFormData, PNTR KeywordFormPtr;
6735 
6736 
ApplyKeywordCallback(BioseqPtr bsp,Pointer userdata)6737 static void ApplyKeywordCallback (BioseqPtr bsp, Pointer userdata)
6738 {
6739   SeqEntryPtr             sep;
6740   ValNodePtr              vnp;
6741   KeywordFormPtr scfp;
6742   GBBlockPtr              gbp;
6743 
6744   sep = SeqMgrGetSeqEntryForData (bsp);
6745   if (sep == NULL)
6746   {
6747     return;
6748   }
6749 
6750   scfp = (KeywordFormPtr) userdata;
6751 
6752   if (!DoesObjectMatchConstraintChoiceSet (OBJ_BIOSEQ, bsp, scfp->constraint)) {
6753     return;
6754   }
6755 
6756 	vnp = GetDescrOnSeqEntry (sep, Seq_descr_genbank);
6757 	if (vnp == NULL) {
6758 		vnp = NewDescrOnSeqEntry (sep, Seq_descr_genbank);
6759 		if (vnp != NULL) {
6760 			vnp->data.ptrvalue = (Pointer) GBBlockNew ();
6761 		}
6762 	}
6763 	if (vnp == NULL) return;
6764 	gbp = (GBBlockPtr) vnp->data.ptrvalue;
6765 	if (gbp == NULL)
6766 	{
6767 	  gbp = GBBlockNew ();
6768 	  vnp->data.ptrvalue = gbp;
6769 	}
6770 	if (gbp == NULL) return;
6771 
6772 	for (vnp = gbp->keywords; vnp; vnp = vnp->next) {
6773 		if (StringCmp((CharPtr)vnp->data.ptrvalue, scfp->keyword) == 0) {
6774 			return;
6775 		}
6776 	}
6777 	ValNodeAddPointer (&(gbp->keywords), 0, StringSave (scfp->keyword));
6778 }
6779 
RemoveKeywordCallback(BioseqPtr bsp,Pointer userdata)6780 static void RemoveKeywordCallback (BioseqPtr bsp, Pointer userdata)
6781 {
6782   SeqEntryPtr             sep;
6783   ValNodePtr              vnp, prev_keyword, next_keyword;
6784   KeywordFormPtr scfp;
6785   GBBlockPtr              gbp;
6786   SeqDescPtr              sdp;
6787   SeqMgrDescContext       context;
6788 
6789   sep = SeqMgrGetSeqEntryForData (bsp);
6790   if (sep == NULL)
6791   {
6792     return;
6793   }
6794 
6795   scfp = (KeywordFormPtr) userdata;
6796 
6797   if (!DoesObjectMatchConstraintChoiceSet (OBJ_BIOSEQ, bsp, scfp->constraint)) {
6798     return;
6799   }
6800 
6801   sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_genbank, &context);
6802   while (sdp != NULL) {
6803 	gbp = (GBBlockPtr) sdp->data.ptrvalue;
6804 	/* No GBBlock, no keywords to remove */
6805     if (gbp != NULL) {
6806       prev_keyword = NULL;
6807 	  for (vnp = gbp->keywords; vnp; vnp = next_keyword) {
6808 	    next_keyword = vnp->next;
6809 		if (StringICmp((CharPtr)vnp->data.ptrvalue, scfp->keyword) == 0) {
6810 			if (prev_keyword == NULL)
6811 			{
6812 			  gbp->keywords = next_keyword;
6813 			}
6814 			else
6815 			{
6816 			  prev_keyword->next = next_keyword;
6817 			}
6818 			vnp->next = NULL;
6819 			ValNodeFreeData (vnp);
6820 		}
6821 		else
6822 		{
6823 		  prev_keyword = vnp;
6824 		}
6825 	  }
6826     }
6827     sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_genbank, &context);
6828   }
6829 }
6830 
ApplyKeyword(IteM i,CharPtr keyword)6831 static void ApplyKeyword (IteM i, CharPtr keyword)
6832 {
6833   BaseFormPtr     bfp;
6834   SeqEntryPtr     sep;
6835   KeywordFormData kfd;
6836 
6837 #ifdef WIN_MAC
6838   bfp = currentFormDataPtr;
6839 #else
6840   bfp = GetObjectExtra (i);
6841 #endif
6842   if (bfp == NULL) return;
6843   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6844   if (sep == NULL) return;
6845 
6846   kfd.pfp = NULL;
6847   kfd.fsp = NULL;
6848   kfd.keyword = keyword;
6849   kfd.constraint = NULL;
6850 
6851   VisitBioseqsInSep (sep, &kfd, ApplyKeywordCallback);
6852 
6853   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6854   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
6855   ArrowCursor ();
6856   Update ();
6857 }
6858 
ApplyGDSKeyword(IteM i)6859 extern void ApplyGDSKeyword (IteM i)
6860 {
6861   ApplyKeyword (i, "GDS");
6862 }
6863 
ApplyTPAInferentialKeyword(IteM i)6864 extern void ApplyTPAInferentialKeyword (IteM i)
6865 {
6866   ApplyKeyword (i, "TPA:inferential");
6867 }
6868 
ApplyTPAExperimentalKeyword(IteM i)6869 extern void ApplyTPAExperimentalKeyword (IteM i)
6870 {
6871   ApplyKeyword (i, "TPA:experimental");
6872 }
6873 
ApplyTPAReassemblyKeyword(IteM i)6874 extern void ApplyTPAReassemblyKeyword (IteM i)
6875 {
6876   ApplyKeyword (i, "TPA:assembly");
6877 }
6878 
DoRemoveKeywords(ButtoN b)6879 static void DoRemoveKeywords (ButtoN b)
6880 {
6881   KeywordFormPtr scfp;
6882   SeqEntryPtr    sep;
6883 
6884   scfp = (KeywordFormPtr) GetObjectExtra (b);
6885   if (scfp == NULL)
6886   {
6887     return;
6888   }
6889 
6890   scfp->constraint = DialogToPointer (scfp->constraint_dlg);
6891 
6892   scfp->keyword = SaveStringFromText (scfp->keyword_txt);
6893 
6894   sep = GetTopSeqEntryForEntityID (scfp->input_entityID);
6895   if (sep == NULL) return;
6896 
6897   VisitBioseqsInSep (sep, scfp, RemoveKeywordCallback);
6898 
6899   scfp->keyword = MemFree (scfp->keyword);
6900   scfp->constraint = ConstraintChoiceSetFree (scfp->constraint);
6901 
6902   ObjMgrSetDirtyFlag (scfp->input_entityID, TRUE);
6903   ObjMgrSendMsg (OM_MSG_UPDATE, scfp->input_entityID, 0, 0);
6904   ArrowCursor ();
6905   Update ();
6906   Remove (scfp->form);
6907 }
6908 
RemoveKeywordWithStringConstraint(IteM i)6909 extern void RemoveKeywordWithStringConstraint (IteM i)
6910 {
6911   BaseFormPtr    bfp;
6912   KeywordFormPtr scfp;
6913   WindoW         w;
6914   GrouP          h, g, c;
6915   ButtoN         b;
6916 
6917 #ifdef WIN_MAC
6918   bfp = currentFormDataPtr;
6919 #else
6920   bfp = GetObjectExtra (i);
6921 #endif
6922   if (bfp == NULL) return;
6923 
6924   scfp = (KeywordFormPtr) MemNew (sizeof (KeywordFormData));
6925   if (scfp == NULL) return;
6926 
6927   w = FixedWindow (-50, -33, -10, -10, "Remove Keywords", StdCloseWindowProc);
6928   SetObjectExtra (w, scfp, StdCleanupExtraProc);
6929   scfp->form = (ForM) w;
6930   scfp->input_entityID = bfp->input_entityID;
6931 
6932   h = HiddenGroup (w, -1, 0, NULL);
6933   SetGroupSpacing (h, 10, 10);
6934 
6935   g = HiddenGroup (h, 2, 0, NULL);
6936   SetGroupSpacing (g, 10, 10);
6937   StaticPrompt (g, "Remove Keyword", 0, 0, programFont, 'l');
6938   scfp->keyword_txt = DialogText (g, "", 30, NULL);
6939 
6940   scfp->constraint_dlg = ComplexConstraintDialog (h, NULL, NULL);
6941   ChangeComplexConstraintFieldType (scfp->constraint_dlg, FieldType_molinfo_field, NULL, 0);
6942 
6943   c = HiddenGroup (h, 2, 0, NULL);
6944   b = PushButton (c, "Accept", DoRemoveKeywords);
6945   SetObjectExtra (b, scfp, NULL);
6946   b = PushButton (c, "Cancel", StdCancelButtonProc);
6947 
6948   AlignObjects (ALIGN_CENTER, (HANDLE) g,
6949                               (HANDLE) scfp->constraint_dlg,
6950                               (HANDLE) c,
6951                               NULL);
6952   RealizeWindow (w);
6953   Show (w);
6954   Select (w);
6955   Update ();
6956 }
6957 
6958 
6959 static CharPtr RNAstrandcmd = NULL;
6960 
6961 typedef struct rnastrand
6962 {
6963   FORM_MESSAGE_BLOCK
6964 
6965   ParData rnaParFmt;
6966   ColData rnaColFmt[3];
6967 
6968   DoC        doc;
6969   ButtoN     rev_feats;
6970   ButtoN     use_smart_btn;
6971   SeqEntryPtr sep;
6972   ValNodePtr sequence_list;
6973   Int4       num_sequences;
6974   BoolPtr    selected;
6975   Int2       lineheight;
6976   CharPtr    database;
6977   Boolean    use_smart;
6978 } RNAStrandData, PNTR RNAStrandPtr;
6979 
6980 typedef enum
6981 {
6982   RNAstrand_PLUS = 1,
6983   RNAstrand_MINUS,
6984   RNAstrand_MIXED,
6985   RNAstrand_NO_HITS,
6986   RNAstrand_UNEXPECTED,
6987   RNAstrand_PARSE_ERROR,
6988   RNAstrand_IN_PROGRESS
6989 } ERNAstrand_return_val;
6990 
6991 static CharPtr RNAstrand_strings[] =
6992 { "Plus", "Minus", "Mixed", "No Hits", "Unexpected", "Parse Error", "In Progress" };
6993 
6994 
6995 typedef enum
6996 {
6997   RNASTRANDGRP_ERROR = 0,
6998   RNASTRANDGRP_NO_HITS,
6999   RNASTRANDGRP_MIXED,
7000   RNASTRANDGRP_MINUS,
7001   RNASTRANDGRP_PLUS
7002 } ERNAstrand_group_num;
7003 
GetRNAStrandGroupNum(ValNodePtr vnp)7004 static ERNAstrand_group_num GetRNAStrandGroupNum (ValNodePtr vnp)
7005 {
7006   if (vnp == NULL) return RNASTRANDGRP_ERROR;
7007   else if (vnp->choice == RNAstrand_NO_HITS) return RNASTRANDGRP_NO_HITS;
7008   else if (vnp->choice == RNAstrand_MINUS) return RNASTRANDGRP_MINUS;
7009   else if (vnp->choice == RNAstrand_MIXED) return RNASTRANDGRP_MIXED;
7010   else if (vnp->choice == RNAstrand_PLUS) return RNASTRANDGRP_PLUS;
7011   else return RNASTRANDGRP_ERROR;
7012 }
7013 
7014 
LimitAlignmentResults(SeqAlignPtr salp,Int4 num_results)7015 static void LimitAlignmentResults (SeqAlignPtr salp, Int4 num_results)
7016 {
7017   Int4        k = 0;
7018   SeqAlignPtr tmp_salp, last_salp = NULL;
7019 
7020   while (salp != NULL && k < num_results)
7021   {
7022     last_salp = salp;
7023     salp = salp->next;
7024     k++;
7025   }
7026   if (last_salp != NULL)
7027   {
7028     last_salp->next = NULL;
7029   }
7030   while (salp != NULL)
7031   {
7032     tmp_salp = salp->next;
7033     salp->next = NULL;
7034     salp = SeqAlignFree (salp);
7035     salp = tmp_salp;
7036   }
7037 }
7038 
7039 
7040 static SBlastOptions*
RNABlastOptionNew(void)7041 RNABlastOptionNew(void)
7042 
7043 {
7044 	SBlastOptions* options;
7045 	Int2           rval;
7046 	Blast_SummaryReturn *extra_returns;
7047 
7048 
7049   extra_returns = Blast_SummaryReturnNew();
7050   rval = SBlastOptionsNew("blastn", &options,
7051                           extra_returns);
7052 
7053 	if (options == NULL)
7054 		return NULL;
7055 
7056   /* This replaces:
7057    * options->expect_value = 1;
7058    */
7059   SBlastOptionsSetEvalue(options, 1);
7060 
7061   /* This replaces:
7062    * options->filter_string = StringSave("m L");
7063    */
7064   SBlastOptionsSetFilterString(options, "m L");
7065 
7066   /* This replaces the following:
7067    * options->mb_template_length = 18;
7068    * options->mb_disc_type = MB_WORD_CODING;
7069    * options->is_megablast_search = TRUE;
7070    * options->discontinuous = TRUE;
7071    */
7072   SBlastOptionsSetDiscMbParams(options, 18, MB_WORD_CODING);
7073 
7074   /* This replaces:
7075    * options->wordsize = 11; \
7076    */
7077 	SBlastOptionsSetWordSize (options, 11);
7078 
7079   /* This replaces:
7080    * options->hitlist_size = 20;
7081    */
7082   options->hit_options->hitlist_size = 20;
7083 
7084   /* This replaces the following:
7085    * options->multiple_hits_only  = TRUE;
7086    * options->window_size = 40;
7087    */
7088   options->word_options->window_size = 40;
7089 
7090   /* This replaces the following:
7091    * options->reward = 1;
7092 	 * options->penalty = -3;
7093 	 * options->gap_open = 5;
7094 	 * options->gap_extend = 2;
7095 	 */
7096   SBlastOptionsSetRewardPenaltyAndGapCosts(options, 2, -3, 5, 2, FALSE);
7097 
7098 	extra_returns = Blast_SummaryReturnFree(extra_returns);
7099 	return options;
7100 }
7101 
7102 #if 0
7103 const CharPtr kRNAStrandDatabaseName = "rRNAstrand";
7104 #else
7105 const CharPtr kRNAStrandDatabaseName = "rRNA_blast";
7106 #endif
7107 
7108 static Int4
RNAScreenSequence(BioseqPtr bsp,CharPtr database,SeqAlignPtr PNTR seqalign_ptr)7109 RNAScreenSequence(BioseqPtr bsp, CharPtr database, SeqAlignPtr PNTR seqalign_ptr)
7110 
7111 {
7112 	SBlastOptions *blast_options;
7113 	Int2 retval=0;
7114 	SeqAlignPtr seqalign = NULL;
7115 	SeqLocPtr   slp;
7116 	SBlastSeqalignArray* seqalign_arr = NULL;
7117 	Blast_SummaryReturn *extra_returns;
7118 
7119 	if (bsp == NULL)
7120 		return -1;
7121 
7122 	if (seqalign_ptr)
7123 		*seqalign_ptr = NULL;
7124 
7125 	blast_options = RNABlastOptionNew();
7126 	if (blast_options == NULL)
7127 		return -1;
7128 
7129 	slp = SeqLocWholeNew(bsp);
7130 	if (database == NULL)
7131 	  database = kRNAStrandDatabaseName;
7132 
7133 	extra_returns = Blast_SummaryReturnNew();
7134 
7135   retval = Blast_DatabaseSearch(slp, NULL, database, NULL, blast_options, NULL, &seqalign_arr, NULL, extra_returns);
7136 	extra_returns = Blast_SummaryReturnFree(extra_returns);
7137 	blast_options = SBlastOptionsFree(blast_options);
7138 
7139 	if (retval == 0 && seqalign_arr != NULL && seqalign_arr->num_queries >0)
7140 	{
7141 	  seqalign = seqalign_arr->array[0];
7142 	  seqalign_arr->array[0] = NULL;
7143 	}
7144 
7145 	seqalign_arr = SBlastSeqalignArrayFree(seqalign_arr);
7146 
7147 	/* limit results to first 20 alignments, as SMART does */
7148 	LimitAlignmentResults (seqalign, 20);
7149 
7150 	if (seqalign)
7151 	{
7152 		if (seqalign_ptr)
7153 			*seqalign_ptr = seqalign;
7154 	}
7155 
7156 
7157 	return retval;
7158 }
7159 
7160 
7161 typedef struct rnastrandcollection
7162 {
7163   ValNodePtr sequence_list;
7164   Char       path [PATH_MAX];
7165   CharPtr    database;
7166   Int4       count;
7167   Int4       total;
7168   MonitorPtr mon;
7169 } RNAStrandCollectionData, PNTR RNAStrandCollectionPtr;
7170 
GetStatusForAlignmentList(SeqAlignPtr salp)7171 static Uint1 GetStatusForAlignmentList (SeqAlignPtr salp)
7172 {
7173   Uint1 status = RNAstrand_NO_HITS;
7174   Uint1 strand;
7175 
7176   while (salp != NULL)
7177   {
7178     AlnMgr2IndexSingleChildSeqAlign(salp);
7179     strand = AlnMgr2GetNthStrand(salp, 1);
7180     if (status == RNAstrand_NO_HITS)
7181     {
7182       if (strand == Seq_strand_plus)
7183       {
7184         status = RNAstrand_PLUS;
7185       }
7186       else if (strand == Seq_strand_minus)
7187       {
7188         status = RNAstrand_MINUS;
7189       }
7190       else
7191       {
7192         return RNAstrand_UNEXPECTED;
7193       }
7194     }
7195     else if (strand == Seq_strand_plus)
7196     {
7197       if (status != RNAstrand_PLUS)
7198       {
7199         return RNAstrand_MIXED;
7200       }
7201     }
7202     else if (strand == Seq_strand_minus)
7203     {
7204       if (status != RNAstrand_MINUS)
7205       {
7206         return RNAstrand_MIXED;
7207       }
7208     }
7209     else
7210     {
7211       return RNAstrand_UNEXPECTED;
7212     }
7213     salp = salp->next;
7214   }
7215   return status;
7216 }
7217 
GetOneRNAStrandednessInfo(BioseqPtr bsp,Pointer userdata)7218 static void GetOneRNAStrandednessInfo (BioseqPtr bsp, Pointer userdata)
7219 {
7220   RNAStrandCollectionPtr rscp;
7221   SeqAlignPtr            salp = NULL;
7222 
7223   if (bsp == NULL || !ISA_na (bsp->mol) || userdata == NULL)
7224   {
7225     return;
7226   }
7227 
7228   rscp = (RNAStrandCollectionPtr) userdata;
7229 
7230   if (rscp->mon != NULL) {
7231     MonitorIntValue (rscp->mon, rscp->count);
7232   }
7233   (rscp->count)++;
7234 
7235   RNAScreenSequence(bsp, rscp->path, &salp);
7236 
7237   ValNodeAddPointer (&(rscp->sequence_list),
7238                      GetStatusForAlignmentList(salp),
7239                      SeqIdFindBest (bsp->id, SEQID_GENBANK));
7240   salp = SeqAlignFree (salp);
7241 }
7242 
CountRNASequences(BioseqPtr bsp,Pointer userdata)7243 static void CountRNASequences (BioseqPtr bsp, Pointer userdata)
7244 {
7245   RNAStrandCollectionPtr rscp;
7246 
7247   if (bsp == NULL || !ISA_na (bsp->mol) || userdata == NULL)
7248   {
7249     return;
7250   }
7251 
7252   rscp = (RNAStrandCollectionPtr) userdata;
7253 
7254   rscp->total++;
7255 }
7256 
GetRNAStrandednessFromLocalDatabase(SeqEntryPtr sep,CharPtr database)7257 static ValNodePtr GetRNAStrandednessFromLocalDatabase (SeqEntryPtr sep, CharPtr database)
7258 {
7259   RNAStrandCollectionData rscd;
7260 
7261   if (sep == NULL) return NULL;
7262 
7263   rscd.path [0] = '\0';
7264   GetAppParam ("NCBI", "NCBI", "DATA", "", rscd.path, sizeof (rscd.path));
7265   FileBuildPath (rscd.path, NULL, database);
7266 
7267   rscd.database = database;
7268   rscd.sequence_list = NULL;
7269   rscd.total = 0;
7270   rscd.count = 0;
7271   rscd.mon = NULL;
7272 
7273   VisitBioseqsInSep (sep, &rscd, CountRNASequences);
7274   if (rscd.total > 2)
7275   {
7276     rscd.mon = MonitorIntNewEx ("RNA Strand Progress", 0, rscd.total - 1, FALSE);
7277   }
7278 
7279   VisitBioseqsInSep (sep, &rscd, GetOneRNAStrandednessInfo);
7280 
7281   if (rscd.mon != NULL) {
7282     rscd.mon = MonitorFree (rscd.mon);
7283     Update ();
7284   }
7285 
7286   return rscd.sequence_list;
7287 }
7288 
GetAccessionList(BioseqPtr bsp,Pointer userdata)7289 static void GetAccessionList (BioseqPtr bsp, Pointer userdata)
7290 {
7291   ValNodePtr PNTR sequence_list;
7292   SeqIdPtr        sip;
7293 
7294   if (bsp == NULL || userdata == NULL) return;
7295 
7296   sequence_list = (ValNodePtr PNTR) userdata;
7297 
7298   for (sip = bsp->id; sip != NULL; sip = sip->next)
7299   {
7300     if (sip->choice == SEQID_GENBANK)
7301     {
7302       ValNodeAddPointer (sequence_list, 0, sip);
7303       return;
7304     }
7305   }
7306 }
7307 
7308 
7309 /* Looks at a portion of the list of sequences for strand correction.
7310  * Returns the number of sequences examined.
7311  */
7312 static Int4
GetSubListForRNAStrandCorrection(ValNodePtr start_list,Int4 num_seqs,CharPtr RNAstrandcmd)7313 GetSubListForRNAStrandCorrection
7314 (ValNodePtr start_list,
7315  Int4       num_seqs,
7316  CharPtr    RNAstrandcmd)
7317 {
7318   Int4                    seq_num, cmd_len = 0, k;
7319   ValNodePtr              vnp;
7320   FILE *                  fp;
7321   CharPtr                 args = NULL, cp, cp2, cmmd;
7322   Char                    tmp_id [256];
7323   Char                    path [PATH_MAX];
7324   Char                    file_line [256];
7325   Boolean                 found_id;
7326 #ifdef OS_MAC
7327   CharPtr                 cmd_format = "%s -a \'%s\' > %s"; /* just to allow compilation */
7328 #endif
7329 #ifdef OS_UNIX
7330   CharPtr                 cmd_format = "%s -a \'%s\' > %s";
7331 #endif
7332 #ifdef OS_MSWIN
7333   CharPtr                 cmd_format = "%s -a \"%s\" > %s";
7334 #endif
7335 
7336   if (start_list == NULL || num_seqs < 1 || StringHasNoText (RNAstrandcmd))
7337   {
7338     return 0;
7339   }
7340 
7341   TmpNam (path);
7342 
7343   /* calculate length of string needed for command */
7344   for (vnp = start_list, seq_num = 0;
7345            vnp != NULL && seq_num < num_seqs;
7346            vnp = vnp->next, seq_num++)
7347   {
7348     SeqIdWrite (vnp->data.ptrvalue, tmp_id, PRINTID_TEXTID_ACC_ONLY, sizeof (tmp_id) - 1);
7349     cmd_len += StringLen (tmp_id) + 3;
7350   }
7351 
7352   args = (CharPtr) MemNew (cmd_len * sizeof (Char));
7353   if (args == NULL)
7354   {
7355         Message (MSG_ERROR, "Unable to allocate memory for strand script argument list");
7356     return 0;
7357   }
7358 
7359   cp = args;
7360   for (vnp = start_list, seq_num = 0;
7361            vnp != NULL && seq_num < num_seqs;
7362            vnp = vnp->next, seq_num++)
7363   {
7364     SeqIdWrite (vnp->data.ptrvalue, cp, PRINTID_TEXTID_ACC_ONLY, cmd_len - (cp - args) - 1);
7365     cp += StringLen (cp);
7366     if (vnp->next != NULL && seq_num < num_seqs - 1)
7367     {
7368 #ifdef OS_UNIX
7369       StringCat (cp, ",");
7370       cp ++;
7371 #else
7372       StringCat (cp, ", ");
7373       cp += 2;
7374 #endif
7375     }
7376   }
7377 
7378 
7379   cmd_len += 3 + StringLen (cmd_format) + StringLen (RNAstrandcmd) + StringLen (path);
7380   cmmd = (CharPtr) MemNew (cmd_len * sizeof (Char));
7381   if (cmmd == NULL)
7382   {
7383     args = MemFree (args);
7384         Message (MSG_ERROR, "Unable to allocate memory for RNA strand script command");
7385     return 0;
7386   }
7387 
7388 #ifdef OS_UNIX
7389   sprintf (cmmd, cmd_format, RNAstrandcmd, args, path);
7390   system (cmmd);
7391 #endif
7392 #ifdef OS_MSWIN
7393   sprintf (cmmd, cmd_format, RNAstrandcmd, args, path);
7394   RunSilent (cmmd);
7395 #endif
7396 
7397   args = MemFree (args);
7398   cmmd = MemFree (cmmd);
7399 
7400   fp = FileOpen (path, "r");
7401   if (fp == NULL) {
7402     FileRemove (path);
7403     return 0;
7404   }
7405 
7406 
7407   while (fgets (file_line, sizeof (file_line) - 1, fp) != NULL)
7408   {
7409     /* find SeqId that matches file line */
7410     cp = StringChr (file_line, '\t');
7411     if (cp == NULL)
7412     {
7413       continue;
7414     }
7415     *cp = 0;
7416     cp++;
7417     cp2 = StringChr (cp, '\n');
7418     if (cp2 != NULL)
7419     {
7420       *cp2 = 0;
7421     }
7422     found_id = FALSE;
7423     for (vnp = start_list, seq_num = 0;
7424              vnp != NULL && seq_num < num_seqs;
7425              vnp = vnp->next, seq_num++)
7426         {
7427       SeqIdWrite (vnp->data.ptrvalue, tmp_id, PRINTID_TEXTID_ACC_ONLY, sizeof (tmp_id) - 1);
7428       if (StringCmp (tmp_id, file_line) == 0)
7429       {
7430         for (k = 1; k <= RNAstrand_IN_PROGRESS; k++)
7431         {
7432           if (StringCmp (cp, RNAstrand_strings [k - 1]) == 0
7433               || (k == RNAstrand_MIXED
7434                   && StringNCmp (cp, RNAstrand_strings [k - 1],
7435                                  StringLen (RNAstrand_strings[k - 1])) == 0))
7436           {
7437             vnp->choice = k;
7438           }
7439         }
7440       }
7441     }
7442   }
7443 
7444   FileClose (fp);
7445 
7446   FileRemove (path);
7447   return seq_num;
7448 }
7449 
7450 
GetStrandednessFromSMART(SeqEntryPtr sep)7451 static ValNodePtr GetStrandednessFromSMART (SeqEntryPtr sep)
7452 {
7453   Char                    file_line [256];
7454   ValNodePtr              sequence_list = NULL, vnp;
7455   Int4                    num_sequences = 0, num_inspected;
7456 
7457   if (sep == NULL) return NULL;
7458 
7459   if (RNAstrandcmd == NULL) {
7460     if (GetAppParam ("SEQUIN", "RNACORRECT", "RNASTRAND", NULL, file_line, sizeof (file_line))) {
7461         RNAstrandcmd = StringSaveNoNull (file_line);
7462     }
7463   }
7464   if (RNAstrandcmd == NULL)
7465   {
7466     Message (MSG_ERROR, "RNASTRAND not set in config file!");
7467     return NULL;
7468   }
7469 
7470 
7471   VisitBioseqsInSep (sep, &sequence_list, GetAccessionList);
7472 
7473   if (sequence_list == NULL)
7474   {
7475     Message (MSG_ERROR, "No sequences with accession numbers found!\n");
7476     return NULL;
7477   }
7478 
7479   vnp = sequence_list;
7480   while ((num_inspected = GetSubListForRNAStrandCorrection (vnp, 25, RNAstrandcmd)) != 0)
7481   {
7482     num_sequences += num_inspected;
7483         while (num_inspected > 0 && vnp != NULL)
7484         {
7485           vnp = vnp->next;
7486           num_inspected --;
7487         }
7488   }
7489 
7490   return sequence_list;
7491 }
7492 
7493 
DoOneReverse(ValNodePtr vnp,Boolean rev_feats,FILE * fp)7494 static void DoOneReverse (ValNodePtr vnp, Boolean rev_feats, FILE *fp)
7495 {
7496   BioseqPtr   bsp;
7497   Char        str [128];
7498   SeqEntryPtr sep;
7499 
7500   if (vnp == NULL)
7501   {
7502     return;
7503   }
7504 
7505   /* reverse sequence */
7506   bsp = BioseqFind (vnp->data.ptrvalue);
7507   BioseqRevComp (bsp);
7508   sep = GetTopSeqEntryForEntityID (bsp->idx.entityID);
7509   VisitAlignmentsInSep (sep, (Pointer) bsp, ReverseBioseqInAlignment);
7510 
7511   if (fp != NULL && bsp != NULL && bsp->id != NULL) {
7512     SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), str, PRINTID_REPORT, sizeof (str));
7513     fprintf (fp, "%s\n", str);
7514   }
7515 
7516   if (rev_feats)
7517   {
7518     ReverseBioseqFeatureStrands (bsp);
7519   }
7520 }
7521 
CheckForAlignmentsBeforeCorrection(RNAStrandPtr strand_info)7522 static Boolean CheckForAlignmentsBeforeCorrection (RNAStrandPtr strand_info)
7523 {
7524   ValNodePtr vnp, seq_in_aln = NULL, aln_bsp = NULL;
7525   BioseqPtr  bsp;
7526   Char       id_str[255];
7527   CharPtr    msg;
7528   MsgAnswer  ans;
7529   Boolean    retval = TRUE;
7530   Int4       strand_num = 0;
7531   Uint2      entityID = 0;
7532 
7533 
7534   if (strand_info == NULL || strand_info->sequence_list == NULL) return FALSE;
7535 
7536   for (vnp = strand_info->sequence_list, strand_num = 0; vnp != NULL; vnp = vnp->next, strand_num++) {
7537     if (!strand_info->selected [strand_num]) continue;
7538     bsp = BioseqFind (vnp->data.ptrvalue);
7539     if (bsp != NULL && IsBioseqInAnyAlignment (bsp, bsp->idx.entityID)) {
7540       entityID = bsp->idx.entityID;
7541       SeqIdWrite (vnp->data.ptrvalue, id_str, PRINTID_REPORT, sizeof (id_str) - 1);
7542       ValNodeAddPointer (&seq_in_aln, 0, StringSave (id_str));
7543       ValNodeAddPointer (&aln_bsp, 0, bsp);
7544     }
7545   }
7546   if (seq_in_aln != NULL) {
7547   	msg = CreateListMessage ("Sequence",
7548   	                         seq_in_aln->next == NULL
7549   	                         ? " is in an alignment, which will become invalid.  Do you want to remove the alignment?"
7550   	                         : " are in alignments, which will become invalid unless all of the sequences in these alignments are reversed.  Do you want to remove the alignments?",
7551   	                         seq_in_aln);
7552   	seq_in_aln = ValNodeFreeData (seq_in_aln);
7553     ans = Message (MSG_YNC, msg);
7554     msg = MemFree (msg);
7555     if (ans == ANS_YES) {
7556       /* remove the alignments */
7557       for (vnp = aln_bsp; vnp != NULL; vnp = vnp->next) {
7558           bsp = vnp->data.ptrvalue;
7559           RemoveAlignmentsWithSequence (bsp, bsp->idx.entityID);
7560           DeleteMarkedObjects (bsp->idx.entityID, 0, NULL);
7561       }
7562     } else if (ans == ANS_CANCEL) {
7563       retval = FALSE;
7564     } else {
7565       VisitAnnotsInSep (GetTopSeqEntryForEntityID (entityID), aln_bsp, FlipEntireAlignmentIfAllSequencesFlipped);
7566     }
7567     aln_bsp = ValNodeFree (aln_bsp);
7568   }
7569   return retval;
7570 }
7571 
DoRNACorrection(ButtoN b)7572 static void DoRNACorrection (ButtoN b)
7573 {
7574   RNAStrandPtr strand_info;
7575   Int4         strand_num = 0;
7576   ValNodePtr   vnp;
7577   Boolean      rev_feats;
7578   FILE         *fp;
7579   Char         path [PATH_MAX];
7580 
7581   strand_info = (RNAStrandPtr) GetObjectExtra (b);
7582   if (strand_info == NULL)
7583   {
7584     return;
7585   }
7586 
7587   rev_feats = GetStatus (strand_info->rev_feats);
7588 
7589   /* check for alignments */
7590   if (!CheckForAlignmentsBeforeCorrection (strand_info)) {
7591     return;
7592   }
7593 
7594   TmpNam (path);
7595   fp = FileOpen (path, "w");
7596   if (fp != NULL) {
7597     for (vnp = strand_info->sequence_list, strand_num = 0;
7598          vnp != NULL;
7599          vnp = vnp->next, strand_num++)
7600     {
7601       if (strand_info->selected [strand_num])
7602       {
7603         /* reverse sequence */
7604         DoOneReverse (vnp, rev_feats, fp);
7605       }
7606     }
7607 
7608     FileClose (fp);
7609     LaunchGeneralTextViewer (path, "Flipped Sequences");
7610     FileRemove (path);
7611   } else {
7612     Message (MSG_ERROR, "Unable to open file for flip report");
7613   }
7614 
7615   ObjMgrSetDirtyFlag (strand_info->input_entityID, TRUE);
7616   ObjMgrSendMsg (OM_MSG_UPDATE, strand_info->input_entityID, 0, 0);
7617   Remove (strand_info->form);
7618   Update ();
7619 }
7620 
CleanupRNAStrandFormProc(GraphiC g,Pointer data)7621 static void CleanupRNAStrandFormProc (GraphiC g, Pointer data)
7622 {
7623   RNAStrandPtr strand_info;
7624 
7625   if (data != NULL)
7626   {
7627     strand_info = (RNAStrandPtr) data;
7628     strand_info->sequence_list = ValNodeFree (strand_info->sequence_list);
7629     strand_info->selected = MemFree (strand_info->selected);
7630     strand_info = MemFree (strand_info);
7631   }
7632 }
7633 
GetSeqNumFromListPos(Int4 list_pos,ValNodePtr sequence_list)7634 static Int4 GetSeqNumFromListPos (Int4 list_pos, ValNodePtr sequence_list)
7635 {
7636   Int4       seq_num = 0, list_offset;
7637   ValNodePtr vnp;
7638   ERNAstrand_group_num group;
7639 
7640   if (sequence_list == NULL)
7641   {
7642     return 0;
7643   }
7644 
7645   list_offset = -1;
7646   for (group = RNASTRANDGRP_ERROR; group <= RNASTRANDGRP_PLUS && list_offset != list_pos; group++)
7647   {
7648     for (vnp = sequence_list, seq_num = -1;
7649          vnp != NULL && list_offset != list_pos;
7650          vnp = vnp->next, seq_num++)
7651     {
7652       if (GetRNAStrandGroupNum(vnp) == group)
7653       {
7654         list_offset ++;
7655       }
7656     }
7657   }
7658 
7659   return seq_num;
7660 }
7661 
ReleaseRNAStrand(DoC d,PoinT pt)7662 static void ReleaseRNAStrand (DoC d, PoinT pt)
7663 
7664 {
7665   Int2            col;
7666   RNAStrandPtr    strand_info;
7667   Int2            item;
7668   RecT            rct;
7669   Int2            row;
7670   Int4            seq_num;
7671 
7672   strand_info = (RNAStrandPtr) GetObjectExtra (d);
7673   if (strand_info != NULL && strand_info->selected != NULL) {
7674     MapDocPoint (d, pt, &item, &row, &col, &rct);
7675     rct.left += 1;
7676     rct.right = rct.left + strand_info->lineheight;
7677     rct.bottom = rct.top + (rct.right - rct.left);
7678     if (row == 1 && col == 3 && PtInRect (pt, &rct))
7679     {
7680       seq_num = GetSeqNumFromListPos (item - 1, strand_info->sequence_list);
7681       if (seq_num > -1 && seq_num < strand_info->num_sequences)
7682       {
7683         if (strand_info->selected [seq_num]) {
7684           strand_info->selected [seq_num] = FALSE;
7685         } else {
7686           strand_info->selected [seq_num] = TRUE;
7687         }
7688         InsetRect (&rct, -1, -1);
7689         InvalRect (&rct);
7690         Update ();
7691       }
7692     }
7693   }
7694 }
7695 
DrawRNAStrand(DoC d,RectPtr r,Int2 item,Int2 firstLine)7696 static void DrawRNAStrand (DoC d, RectPtr r, Int2 item, Int2 firstLine)
7697 
7698 {
7699   RNAStrandPtr strand_info;
7700   RecT         rct;
7701   RecT         doc_rect;
7702   Int4         seq_num;
7703 
7704   strand_info = (RNAStrandPtr) GetObjectExtra (d);
7705 
7706   if (strand_info == NULL || r == NULL
7707       || item < 1 || item > strand_info->num_sequences
7708       || firstLine != 0)
7709   {
7710     return;
7711   }
7712 
7713   rct = *r;
7714   rct.right --;
7715   rct.left = rct.right - strand_info->lineheight;
7716   rct.bottom = rct.top + (rct.right - rct.left);
7717 
7718   /* make sure we don't draw a box where we aren't drawing text */
7719   ObjectRect (strand_info->doc, &doc_rect);
7720   InsetRect (&doc_rect, 4, 4);
7721   if (rct.bottom > doc_rect.bottom)
7722   {
7723     return;
7724   }
7725 
7726   FrameRect (&rct);
7727 
7728   seq_num = GetSeqNumFromListPos (item - 1, strand_info->sequence_list);
7729   if (seq_num > -1 && seq_num < strand_info->num_sequences) {
7730     if (strand_info->selected != NULL && strand_info->selected [seq_num]) {
7731       MoveTo (rct.left, rct.top);
7732       LineTo (rct.right - 1, rct.bottom - 1);
7733       MoveTo (rct.left, rct.bottom - 1);
7734       LineTo (rct.right - 1, rct.top);
7735     }
7736   }
7737 }
7738 
GetRNAStrandDesc(ValNodePtr vnp,CharPtr doc_line)7739 static void GetRNAStrandDesc (ValNodePtr vnp, CharPtr doc_line)
7740 {
7741   if (vnp == NULL || doc_line == NULL) return;
7742 
7743   if (vnp->choice == RNAstrand_MINUS) {
7744     StringCat (doc_line, "\tMINUS\t\n");
7745   } else if (vnp->choice == RNAstrand_PLUS) {
7746     StringCat (doc_line, "\tPLUS\t\n");
7747   } else {
7748     StringCat (doc_line, "\t");
7749     if (vnp->choice == 0)
7750     {
7751       StringCat (doc_line, "Unknown error");
7752     }
7753     else
7754     {
7755       StringCat (doc_line, RNAstrand_strings [vnp->choice - 1]);
7756     }
7757     StringCat (doc_line, "\t\n");
7758   }
7759 }
7760 
RedrawRNAStrandDialog(RNAStrandPtr strand_info)7761 static void RedrawRNAStrandDialog (RNAStrandPtr strand_info)
7762 {
7763   Int4         strand_num;
7764   Char         doc_line [500];
7765   ValNodePtr   vnp;
7766   ERNAstrand_group_num group_num;
7767 
7768   if (strand_info == NULL)
7769   {
7770     return;
7771   }
7772 
7773   Reset (strand_info->doc);
7774 
7775   for (group_num = RNASTRANDGRP_ERROR;
7776        group_num <= RNASTRANDGRP_PLUS;
7777        group_num++)
7778   {
7779     for (vnp = strand_info->sequence_list, strand_num = 0;
7780          vnp != NULL;
7781          vnp = vnp->next, strand_num++)
7782     {
7783       if (GetRNAStrandGroupNum(vnp) != group_num) continue;
7784       SeqIdWrite (vnp->data.ptrvalue, doc_line, PRINTID_TEXTID_ACC_ONLY, 255);
7785       GetRNAStrandDesc (vnp, doc_line);
7786       AppendText (strand_info->doc, doc_line, &(strand_info->rnaParFmt), strand_info->rnaColFmt, programFont);
7787       if (group_num == RNASTRANDGRP_MINUS) strand_info->selected[strand_num] = TRUE;
7788     }
7789   }
7790 
7791   UpdateDocument (strand_info->doc, 0, 0);
7792 }
7793 
RefreshRNAStrandDialog(ButtoN b)7794 static void RefreshRNAStrandDialog (ButtoN b)
7795 {
7796   RNAStrandPtr strand_info;
7797   ValNodePtr   new_seq_list;
7798 
7799   strand_info = (RNAStrandPtr) GetObjectExtra (b);
7800   if (strand_info == NULL)
7801   {
7802     return;
7803   }
7804 
7805   if (strand_info->use_smart) {
7806     new_seq_list = GetStrandednessFromSMART (strand_info->sep);
7807   } else {
7808     new_seq_list = GetRNAStrandednessFromLocalDatabase (strand_info->sep, strand_info->database);
7809   }
7810 
7811   if (new_seq_list == NULL)
7812   {
7813     Message (MSG_ERROR, "Unable to refresh sequence list.");
7814     return;
7815   }
7816   strand_info->sequence_list = ValNodeFree (strand_info->sequence_list);
7817   strand_info->sequence_list = new_seq_list;
7818 
7819   RedrawRNAStrandDialog (strand_info);
7820 }
7821 
7822 
ChangeStrandSmart(ButtoN b)7823 static void ChangeStrandSmart (ButtoN b)
7824 {
7825   RNAStrandPtr strand_info;
7826 
7827   strand_info = (RNAStrandPtr) GetObjectExtra (b);
7828   if (strand_info == NULL)
7829   {
7830     return;
7831   }
7832   strand_info->use_smart = GetStatus (strand_info->use_smart_btn);
7833   RefreshRNAStrandDialog (strand_info->use_smart_btn);
7834 }
7835 
7836 
CorrectRNAStrandednessForEntityID(Uint2 entityID,Boolean use_smart)7837 NLM_EXTERN Int2 CorrectRNAStrandednessForEntityID (Uint2 entityID, Boolean use_smart)
7838 
7839 {
7840   SeqEntryPtr             sep;
7841   ValNodePtr              sequence_list = NULL;
7842   RNAStrandPtr            strand_info;
7843   WindoW                  w;
7844   GrouP                   h, c;
7845   ButtoN                  b;
7846   RecT                    r;
7847   ButtoN                  refresh_btn;
7848 
7849   sep = GetTopSeqEntryForEntityID (entityID);
7850   if (sep == NULL) return OM_MSG_RET_ERROR;
7851 
7852   if (use_smart)
7853   {
7854     sequence_list = GetStrandednessFromSMART (sep);
7855   }
7856   else
7857   {
7858     sequence_list = GetRNAStrandednessFromLocalDatabase (sep, kRNAStrandDatabaseName);
7859   }
7860 
7861   if (sequence_list == NULL)
7862   {
7863     return OM_MSG_RET_ERROR;
7864   }
7865 
7866   strand_info = (RNAStrandPtr) MemNew (sizeof (RNAStrandData));
7867   if (strand_info == NULL)
7868   {
7869     return OM_MSG_RET_ERROR;
7870   }
7871 
7872   strand_info->input_entityID = entityID;
7873   strand_info->sep = sep;
7874   strand_info->sequence_list = sequence_list;
7875   strand_info->num_sequences = ValNodeLen (sequence_list);
7876   strand_info->selected = (BoolPtr) MemNew (strand_info->num_sequences * sizeof (Boolean));
7877   strand_info->database = kRNAStrandDatabaseName;
7878   strand_info->use_smart = use_smart;
7879 
7880   /* initialize document paragraph format */
7881   strand_info->rnaParFmt.openSpace = FALSE;
7882   strand_info->rnaParFmt.keepWithNext = FALSE;
7883   strand_info->rnaParFmt.keepTogether = FALSE;
7884   strand_info->rnaParFmt.newPage = FALSE;
7885   strand_info->rnaParFmt.tabStops = FALSE;
7886   strand_info->rnaParFmt.minLines = 0;
7887   strand_info->rnaParFmt.minHeight = 0;
7888 
7889   /* initialize document column format */
7890   strand_info->rnaColFmt[0].pixWidth = 0;
7891   strand_info->rnaColFmt[0].pixInset = 0;
7892   strand_info->rnaColFmt[0].charWidth = 80;
7893   strand_info->rnaColFmt[0].charInset = 0;
7894   strand_info->rnaColFmt[0].font = NULL;
7895   strand_info->rnaColFmt[0].just = 'l';
7896   strand_info->rnaColFmt[0].wrap = TRUE;
7897   strand_info->rnaColFmt[0].bar = FALSE;
7898   strand_info->rnaColFmt[0].underline = FALSE;
7899   strand_info->rnaColFmt[0].left = FALSE;
7900   strand_info->rnaColFmt[0].last = FALSE;
7901   strand_info->rnaColFmt[1].pixWidth = 0;
7902   strand_info->rnaColFmt[1].pixInset = 0;
7903   strand_info->rnaColFmt[1].charWidth = 80;
7904   strand_info->rnaColFmt[1].charInset = 0;
7905   strand_info->rnaColFmt[1].font = NULL;
7906   strand_info->rnaColFmt[1].just = 'l';
7907   strand_info->rnaColFmt[1].wrap = TRUE;
7908   strand_info->rnaColFmt[1].bar = FALSE;
7909   strand_info->rnaColFmt[1].underline = FALSE;
7910   strand_info->rnaColFmt[1].left = FALSE;
7911   strand_info->rnaColFmt[1].last = FALSE;
7912   strand_info->rnaColFmt[2].pixWidth = 0;
7913   strand_info->rnaColFmt[2].pixInset = 0;
7914   strand_info->rnaColFmt[2].charWidth = 80;
7915   strand_info->rnaColFmt[2].charInset = 0;
7916   strand_info->rnaColFmt[2].font = NULL;
7917   strand_info->rnaColFmt[2].just = 'l';
7918   strand_info->rnaColFmt[2].wrap = TRUE;
7919   strand_info->rnaColFmt[2].bar = FALSE;
7920   strand_info->rnaColFmt[2].underline = FALSE;
7921   strand_info->rnaColFmt[2].left = FALSE;
7922   strand_info->rnaColFmt[2].last = TRUE;
7923 
7924   w = FixedWindow (50, 33, -10, -10, "Correct RNA Strandedness", NULL);
7925   SetObjectExtra (w, strand_info, CleanupRNAStrandFormProc);
7926   strand_info->form = (ForM) w;
7927 
7928   h = HiddenGroup (w, -1, 0, NULL);
7929   SetGroupSpacing (h, 10, 10);
7930 
7931   strand_info->doc = DocumentPanel (h, stdCharWidth * 27, stdLineHeight * 8);
7932   SetObjectExtra (strand_info->doc, strand_info, NULL);
7933   SetDocAutoAdjust (strand_info->doc, TRUE);
7934   SetDocProcs (strand_info->doc, NULL, NULL, ReleaseRNAStrand, NULL);
7935   SetDocShade (strand_info->doc, DrawRNAStrand, NULL, NULL, NULL);
7936 
7937   SelectFont (programFont);
7938   strand_info->lineheight = LineHeight ();
7939 
7940   ObjectRect (strand_info->doc, &r);
7941   InsetRect (&r, 4, 4);
7942   strand_info->rnaColFmt[0].pixWidth = (r.right - r.left - strand_info->lineheight) / 2;
7943   strand_info->rnaColFmt[1].pixWidth = (r.right - r.left - strand_info->lineheight) / 2;
7944   strand_info->rnaColFmt[2].pixWidth = strand_info->lineheight;
7945 
7946   refresh_btn = PushButton (h, "Refresh Strand Results", RefreshRNAStrandDialog);
7947   SetObjectExtra (refresh_btn, strand_info, NULL);
7948   strand_info->rev_feats = CheckBox (h, "Also reverse features", NULL);
7949   SetStatus (strand_info->rev_feats, FALSE);
7950   strand_info->use_smart_btn = CheckBox (h, "Use SMART for strand information", ChangeStrandSmart);
7951   SetObjectExtra (strand_info->use_smart_btn, strand_info, NULL);
7952   SetStatus (strand_info->use_smart_btn, strand_info->use_smart);
7953 
7954   c = HiddenGroup (h, 2, 0, NULL);
7955   b = PushButton (c, "Autocorrect Minus Strands", DoRNACorrection);
7956   SetObjectExtra (b, strand_info, NULL);
7957   b = PushButton (c, "Cancel", StdCancelButtonProc);
7958 
7959   AlignObjects (ALIGN_CENTER, (HANDLE) strand_info->doc,
7960                               (HANDLE) refresh_btn,
7961                               (HANDLE) strand_info->use_smart_btn,
7962                               (HANDLE) strand_info->rev_feats,
7963                               (HANDLE) c,
7964                               NULL);
7965   RedrawRNAStrandDialog (strand_info);
7966   Show (w);
7967   return OM_MSG_RET_OK;
7968 }
7969 
7970 
CorrectRNAStrandednessEx(Pointer data,Boolean use_smart)7971 static Int2 LIBCALLBACK CorrectRNAStrandednessEx (Pointer data, Boolean use_smart)
7972 {
7973   OMProcControlPtr ompcp;
7974 
7975   ompcp = (OMProcControlPtr) data;
7976   if (ompcp == NULL)
7977   {
7978     Message (MSG_ERROR, "You must select something!");
7979     return OM_MSG_RET_ERROR;
7980   }
7981 
7982   return CorrectRNAStrandednessForEntityID (ompcp->input_entityID, use_smart);
7983 }
7984 
7985 
CorrectRNAStrandedness(Pointer data)7986 extern Int2 LIBCALLBACK CorrectRNAStrandedness (Pointer data)
7987 {
7988   return CorrectRNAStrandednessEx (data, FALSE);
7989 }
CorrectRNAStrandednessUseSmart(Pointer data)7990 extern Int2 LIBCALLBACK CorrectRNAStrandednessUseSmart (Pointer data)
7991 {
7992   return CorrectRNAStrandednessEx (data, TRUE);
7993 }
7994 
CorrectRNAStrandednessMenuItem(IteM i)7995 extern void CorrectRNAStrandednessMenuItem (IteM i)
7996 {
7997   BaseFormPtr   bfp;
7998 
7999 #ifdef WIN_MAC
8000   bfp = currentFormDataPtr;
8001 #else
8002   bfp = GetObjectExtra (i);
8003 #endif
8004   if (bfp == NULL) return;
8005 
8006   CorrectRNAStrandednessForEntityID (bfp->input_entityID, TRUE);
8007 }
8008 
8009 
8010 /* collection_date has a controlled format.
8011  * It is YYYY or Mmm-YYYY or DD-Mmm-YYYY where Mmm = Jan, Feb, Mar, Apr, May,
8012  *                                                   Jun, Jul, Aug, Sep, Oct,
8013  *                                                   Nov, Dec
8014  * This function will convert other formats  to this format.
8015  * For instance, September 12, 2004 should be converted to 12-Sep-2004
8016  * 12/15/2003 should be converted to 15-Dec-2003.
8017  *
8018  * If the date supplied is ambiguous (01/03/05), can you allow the indexer to choose which field goes in Mmm and which in DD.
8019  */
8020 
8021 typedef struct parsecollectiondate
8022 {
8023   Int4    num_successful;
8024   Int4    num_unsuccessful;
8025   Boolean month_first;
8026 } ParseCollectionDateData, PNTR ParseCollectionDatePtr;
8027 
ParseCollectionDateCallback(BioSourcePtr biop,Pointer userdata)8028 static void ParseCollectionDateCallback (BioSourcePtr biop, Pointer userdata)
8029 {
8030   SubSourcePtr           ssp;
8031   CharPtr                reformatted_date = NULL;
8032   ParseCollectionDatePtr pcdp;
8033 
8034   if (biop == NULL || biop->subtype == NULL || userdata == NULL)
8035   {
8036     return;
8037   }
8038 
8039   pcdp = (ParseCollectionDatePtr) userdata;
8040 
8041   ssp = biop->subtype;
8042   while (ssp != NULL)
8043   {
8044     if (ssp->subtype == SUBSRC_collection_date)
8045     {
8046       reformatted_date = ReformatDateStringEx (ssp->name, pcdp->month_first, NULL);
8047       if (reformatted_date == NULL)
8048       {
8049         pcdp->num_unsuccessful ++;
8050       }
8051       else
8052       {
8053         ssp->name = MemFree (ssp->name);
8054         ssp->name = reformatted_date;
8055         pcdp->num_successful ++;
8056       }
8057     }
8058     ssp = ssp->next;
8059   }
8060 }
8061 
CountParseCollectionDateCallback(BioSourcePtr biop,Pointer userdata)8062 static void CountParseCollectionDateCallback (BioSourcePtr biop, Pointer userdata)
8063 {
8064   SubSourcePtr           ssp;
8065   CharPtr                reformatted_date = NULL;
8066   ParseCollectionDatePtr pcdp;
8067 
8068   if (biop == NULL || biop->subtype == NULL || userdata == NULL)
8069   {
8070     return;
8071   }
8072 
8073   pcdp = (ParseCollectionDatePtr) userdata;
8074 
8075   ssp = biop->subtype;
8076   while (ssp != NULL)
8077   {
8078     if (ssp->subtype == SUBSRC_collection_date)
8079     {
8080       reformatted_date = ReformatDateStringEx (ssp->name, pcdp->month_first, NULL);
8081       if (reformatted_date == NULL)
8082       {
8083         pcdp->num_unsuccessful++;
8084       }
8085       else
8086       {
8087         MemFree (reformatted_date);
8088         pcdp->num_successful ++;
8089       }
8090     }
8091     ssp = ssp->next;
8092   }
8093 }
8094 
ParseCollectionDate(IteM i,Boolean month_first)8095 static void ParseCollectionDate (IteM i, Boolean month_first)
8096 {
8097   BaseFormPtr             bfp;
8098   SeqEntryPtr             sep;
8099   ParseCollectionDateData pcdd;
8100 
8101 #ifdef WIN_MAC
8102   bfp = currentFormDataPtr;
8103 #else
8104   bfp = GetObjectExtra (i);
8105 #endif
8106   if (bfp == NULL) return;
8107 
8108   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
8109   WatchCursor ();
8110   Update ();
8111 
8112   pcdd.num_successful = 0;
8113   pcdd.num_unsuccessful = 0;
8114   pcdd.month_first = month_first;
8115 
8116   VisitBioSourcesInSep (sep, &pcdd, CountParseCollectionDateCallback);
8117   if (pcdd.num_unsuccessful > 0
8118       && ANS_NO == Message (MSG_YN,
8119                             "Sequin will be unable to reformat %d dates - do you want to continue?", pcdd.num_unsuccessful))
8120   {
8121     ArrowCursor ();
8122     Update ();
8123     return;
8124   }
8125 
8126   pcdd.num_successful = 0;
8127   pcdd.num_unsuccessful = 0;
8128   VisitBioSourcesInSep (sep, &pcdd, ParseCollectionDateCallback);
8129 
8130   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
8131   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
8132   ArrowCursor ();
8133   Update ();
8134 }
8135 
ParseCollectionDateMonthFirst(IteM i)8136 extern void ParseCollectionDateMonthFirst (IteM i)
8137 {
8138   ParseCollectionDate (i, TRUE);
8139 }
8140 
ParseCollectionDateDayFirst(IteM i)8141 extern void ParseCollectionDateDayFirst (IteM i)
8142 {
8143   ParseCollectionDate (i, FALSE);
8144 }
8145 
8146 
GetIDStringForSeqEntry(SeqEntryPtr sep)8147 static CharPtr GetIDStringForSeqEntry (SeqEntryPtr sep)
8148 {
8149   BioseqSetPtr bssp;
8150   BioseqPtr    bsp = NULL;
8151   SeqIdPtr     sip = NULL;
8152   Char         id_txt [100];
8153 
8154   if (sep == NULL || sep->data.ptrvalue == NULL)
8155   {
8156     return NULL;
8157   }
8158 
8159   if (IS_Bioseq_set (sep))
8160   {
8161     bssp = (BioseqSetPtr) sep->data.ptrvalue;
8162     if (bssp->_class == BioseqseqSet_class_nuc_prot
8163         || bssp->_class == BioseqseqSet_class_segset)
8164     {
8165       sep = bssp->seq_set;
8166       while (sep != NULL && (IS_Bioseq_set (sep) || sep->data.ptrvalue == NULL))
8167       {
8168         sep = sep->next;
8169       }
8170       if (sep != NULL)
8171       {
8172         bsp = (BioseqPtr) sep->data.ptrvalue;
8173       }
8174     }
8175   }
8176   else if (IS_Bioseq(sep))
8177   {
8178     bsp = (BioseqPtr) sep->data.ptrvalue;
8179   }
8180   if (bsp == NULL) return NULL;
8181   sip = SeqIdFindBest (bsp->id, SEQID_GENBANK);
8182   if (sip == NULL) return NULL;
8183 
8184   SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
8185   return StringSave (id_txt);
8186 }
8187 
8188 
SortSeqEntryByIDStr(VoidPtr ptr1,VoidPtr ptr2)8189 static int LIBCALLBACK SortSeqEntryByIDStr (VoidPtr ptr1, VoidPtr ptr2)
8190 
8191 {
8192   CharPtr     str1;
8193   CharPtr     str2;
8194   ValNodePtr  vnp1;
8195   ValNodePtr  vnp2;
8196   int         rval = 0;
8197 
8198   if (ptr1 != NULL && ptr2 != NULL) {
8199     vnp1 = *((ValNodePtr PNTR) ptr1);
8200     vnp2 = *((ValNodePtr PNTR) ptr2);
8201     if (vnp1 != NULL && vnp2 != NULL) {
8202       str1 = GetIDStringForSeqEntry (vnp1);
8203       str2 = GetIDStringForSeqEntry (vnp2);
8204       if (str1 != NULL && str2 != NULL) {
8205         rval = StringICmp (str1, str2);
8206       }
8207       str1 = MemFree (str1);
8208       str2 = MemFree (str2);
8209     }
8210   }
8211   return rval;
8212 }
8213 
ReorderBioseqSetByAccession(BioseqSetPtr bssp)8214 static void ReorderBioseqSetByAccession (BioseqSetPtr bssp)
8215 {
8216   SeqEntryPtr       sep;
8217   ObjMgrDataPtr     omdptop;
8218   ObjMgrData        omdata;
8219   Uint2             parenttype;
8220   Pointer           parentptr;
8221 
8222   sep = SeqMgrGetSeqEntryForData (bssp);
8223   SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
8224   GetSeqEntryParent (sep, &parentptr, &parenttype);
8225 
8226   bssp->seq_set = ValNodeSort (bssp->seq_set, SortSeqEntryByIDStr);
8227 
8228 
8229   SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
8230   RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
8231   ObjMgrSetDirtyFlag (bssp->idx.entityID, TRUE);
8232   ObjMgrSendMsg (OM_MSG_UPDATE, bssp->idx.entityID, 0, 0);
8233 }
8234 
8235 
ReorderSetByAccession(Pointer data)8236 extern Int2 LIBCALLBACK ReorderSetByAccession (Pointer data)
8237 {
8238   BioseqSetPtr      bssp;
8239   OMProcControlPtr  ompcp;
8240 
8241   /* Check parameters and get a pointer to the current data */
8242 
8243   ompcp = (OMProcControlPtr) data;
8244   if (ompcp == NULL)
8245     return OM_MSG_RET_ERROR;
8246 
8247   if (ompcp->input_itemtype != OBJ_BIOSEQSET || ompcp->input_data == NULL) {
8248     Message (MSG_ERROR, "Must select Bioseq Set!");
8249     return OM_MSG_RET_ERROR;
8250   }
8251 
8252   bssp = (BioseqSetPtr) ompcp->input_data;
8253 
8254   ReorderBioseqSetByAccession (bssp);
8255   return OM_MSG_RET_DONE;
8256 }
8257 
8258 
FindTopLevelSetForDesktopFunction(BioseqSetPtr bssp)8259 extern BioseqSetPtr FindTopLevelSetForDesktopFunction (BioseqSetPtr bssp)
8260 {
8261   if (bssp == NULL) {
8262     return NULL;
8263   } else if (bssp->_class != BioseqseqSet_class_genbank) {
8264     return bssp;
8265   } else if (bssp->seq_set != NULL && IS_Bioseq_set (bssp->seq_set) && bssp->seq_set->next == NULL) {
8266     return (BioseqSetPtr) bssp->seq_set->data.ptrvalue;
8267   } else {
8268     return bssp;
8269   }
8270 }
8271 
8272 
ReorderSetByAccessionMenuItem(IteM i)8273 extern void ReorderSetByAccessionMenuItem (IteM i)
8274 {
8275   BaseFormPtr   bfp;
8276   SeqEntryPtr   sep;
8277 
8278 #ifdef WIN_MAC
8279   bfp = currentFormDataPtr;
8280 #else
8281   bfp = GetObjectExtra (i);
8282 #endif
8283   if (bfp == NULL) return;
8284 
8285   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
8286   if (sep == NULL || !IS_Bioseq_set (sep)) {
8287     Message (MSG_ERROR, "This record does not have a top-levelset!");
8288   } else {
8289     ReorderBioseqSetByAccession (FindTopLevelSetForDesktopFunction((BioseqSetPtr) sep->data.ptrvalue));
8290   }
8291 }
8292 
8293 
DescriptorPropagateMenuItem(IteM i)8294 extern void DescriptorPropagateMenuItem (IteM i)
8295 {
8296   BaseFormPtr   bfp;
8297   SeqEntryPtr   sep;
8298 
8299 #ifdef WIN_MAC
8300   bfp = currentFormDataPtr;
8301 #else
8302   bfp = GetObjectExtra (i);
8303 #endif
8304   if (bfp == NULL) return;
8305 
8306   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
8307   if (sep == NULL || !IS_Bioseq_set (sep)) {
8308     Message (MSG_ERROR, "This record does not have a top-levelset!");
8309     return;
8310   }
8311 
8312   SetDescriptorPropagate (FindTopLevelSetForDesktopFunction((BioseqSetPtr) sep->data.ptrvalue));
8313 
8314   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
8315   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
8316 }
8317 
8318 
8319 typedef struct findcontig {
8320   FORM_MESSAGE_BLOCK
8321   DoC        doc;
8322   Int2       clicked;
8323   Boolean    dblClick;
8324   ValNodePtr id_list;
8325   BioseqPtr  con_bsp;
8326 } FindContigData, PNTR FindContigPtr;
8327 
ViewContigPiece(SeqIdPtr sip)8328 static void ViewContigPiece (SeqIdPtr sip)
8329 {
8330   SeqEntryPtr    sep = NULL;
8331   BioseqPtr      bsp;
8332   SeqEntryPtr    oldscope;
8333   Uint2          entityID = 0;
8334   Uint2          parenttype, last_parenttype;
8335   Pointer        parentptr, last_parentptr;
8336   OMUserDataPtr  omudp;
8337   BaseFormPtr    bfp;
8338 
8339   if (sip == NULL) {
8340     return;
8341   }
8342 
8343   oldscope = SeqEntrySetScope (NULL);
8344   bsp = BioseqFind (sip);
8345   SeqEntrySetScope (oldscope);
8346   if (bsp == NULL) {
8347     DownloadAndDisplay (sip);
8348   } else {
8349     if (bsp->idx.entityID == 0) {
8350       sep = SeqMgrGetSeqEntryForData (bsp);
8351       if (sep != NULL) {
8352         GetSeqEntryParent (sep, &parentptr, &parenttype);
8353         last_parentptr = parentptr;
8354         last_parenttype = parenttype;
8355         while (parentptr != NULL) {
8356           if (parenttype == OBJ_SEQENTRY) {
8357             sep = parentptr;
8358           } else if (parenttype == OBJ_BIOSEQ || parenttype == OBJ_BIOSEQSET) {
8359             sep = SeqMgrGetSeqEntryForData (parentptr);
8360           } else {
8361             sep = NULL;
8362           }
8363           if (sep != NULL) {
8364             last_parentptr = parentptr;
8365             last_parenttype = parenttype;
8366             GetSeqEntryParent (sep, &parentptr, &parenttype);
8367           }
8368         }
8369         if (last_parentptr == NULL) {
8370           entityID = ObjMgrRegister (OBJ_BIOSEQ, bsp);
8371         } else {
8372           entityID = ObjMgrRegister (last_parenttype, last_parentptr);
8373         }
8374       }
8375     } else {
8376       entityID = bsp->idx.entityID;
8377     }
8378     omudp = EntityAlreadyHasViewer (entityID);
8379     if (omudp == NULL) {
8380       LaunchDisplay (entityID);
8381       omudp = EntityAlreadyHasViewer (entityID);
8382     }
8383     if (omudp != NULL) {
8384       MakeViewerIndependent (entityID, omudp);
8385       bfp = (BaseFormPtr) omudp->userdata.ptrvalue;
8386       if (bfp != NULL && bfp->form != NULL) {
8387         Select (bfp->form);
8388         SeqEntrySetScope (GetTopSeqEntryForEntityID(entityID));
8389         SetBioseqViewTargetByBioseq (bfp, bsp);
8390       }
8391     }
8392   }
8393 }
8394 
ClickContigPiece(DoC d,PoinT pt)8395 static void ClickContigPiece (DoC d, PoinT pt)
8396 {
8397   Int2                      item;
8398   Int2                      row;
8399   Int2                      col;
8400   FindContigPtr  fcp;
8401   ValNodePtr     vnp;
8402 
8403   fcp = GetObjectExtra (d);
8404   if (fcp != NULL) {
8405     MapDocPoint (d, pt, &item, &row, &col, NULL);
8406     if (item > 0 && row > 0 && fcp->clicked == item) {
8407       fcp->dblClick = dblClick;
8408     } else {
8409       fcp->dblClick = FALSE;
8410     }
8411     fcp->clicked = 0;
8412     if (item > 0 && row > 0) {
8413       fcp->clicked = item;
8414     }
8415     if (item > 0 && row > 0 && dblClick)
8416     {
8417       vnp = fcp->id_list;
8418       while (item > 1 && vnp != NULL) {
8419         vnp = vnp->next;
8420         item--;
8421       }
8422       if (vnp != NULL) {
8423         ViewContigPiece(vnp->data.ptrvalue);
8424       }
8425     }
8426   }
8427 }
8428 
8429 static ParData contigParFmt = {TRUE, FALSE, FALSE, FALSE, FALSE, 0, 0};
8430 
8431 static Nlm_ColData contigColFmt [5] = {{0, 5, 10, 0, NULL, 'l', 1,0,0,0, FALSE},
8432                                          {0, 0, 10, 0, NULL, 'l', 1,1,0,0, FALSE},
8433                                          {0, 0, 10, 0, NULL, 'l', 1,1,0,0, FALSE},
8434                                          {0, 0, 10, 0, NULL, 'l', 1,1,0,0, FALSE},
8435                                          {0, 0, 10, 0, NULL, 'l', 1,1,0,0, TRUE}};
8436 
8437 
FindContigBtn(ButtoN b)8438 static void FindContigBtn (ButtoN b)
8439 {
8440   FindContigPtr     fcp;
8441   SelStructPtr      sel;
8442   SeqFeatPtr        sfp;
8443   SeqMgrFeatContext fcontext;
8444   BioseqPtr         bsp, piece_bsp;
8445   DeltaSeqPtr       dsp;
8446   SeqLocPtr         slp;
8447   SeqLitPtr         slip;
8448   Int4              seq_len, len, feat_start, feat_offset = 0;
8449   SeqIdPtr          sip;
8450   Char              str [128];
8451   Char              num_str [20];
8452   SeqEntryPtr       oldscope;
8453   CharPtr           location, row_text, label;
8454   CharPtr           header = "Feature\t\t\tAccession\tOffset\n";
8455   Boolean           some_missing = FALSE;
8456 
8457   fcp = (FindContigPtr) GetObjectExtra (b);
8458   if (fcp == NULL) {
8459     return;
8460   }
8461   Reset (fcp->doc);
8462 
8463   fcp->id_list = FreeSeqIdList (fcp->id_list);
8464 
8465   AppendText (fcp->doc, header, &contigParFmt, contigColFmt, programFont);
8466   ValNodeAddPointer (&fcp->id_list, 0, NULL);
8467 
8468   for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
8469     if (sel->itemtype == OBJ_SEQFEAT) {
8470       oldscope = SeqEntrySetScope (NULL);
8471       sfp = SeqMgrGetDesiredFeature (sel->entityID, NULL, sel->itemID, 0, NULL, &fcontext);
8472       SeqEntrySetScope (oldscope);
8473       if (sfp != NULL) {
8474         oldscope = SeqEntrySetScope (NULL);
8475         bsp = BioseqFindFromSeqLoc(sfp->location);
8476         SeqEntrySetScope (oldscope);
8477         sip = NULL;
8478         piece_bsp = NULL;
8479         if (SeqLocStrand (sfp->location) == Seq_strand_minus) {
8480           feat_start = SeqLocStop (sfp->location);
8481         } else {
8482           feat_start = SeqLocStart (sfp->location);
8483         }
8484         if (bsp == NULL) {
8485           some_missing = TRUE;
8486         } else if (bsp != fcp->con_bsp) {
8487           piece_bsp = bsp;
8488           sip = SeqIdFindBest (bsp->id, 0);
8489           feat_offset = feat_start;
8490         } else if (bsp->repr == Seq_repr_seg || bsp->repr == Seq_repr_delta) {
8491           seq_len = 0;
8492           if (bsp->seq_ext_type == 4) {
8493             for (dsp = (DeltaSeqPtr) (bsp->seq_ext);
8494                  dsp != NULL && seq_len <= feat_start && sip == NULL;
8495                  dsp = dsp->next)
8496             {
8497               len = 0;
8498               if (dsp->data.ptrvalue == NULL) {
8499                 continue;
8500               } else if (dsp->choice == 1) {
8501                 slp = (SeqLocPtr) dsp->data.ptrvalue;
8502                 len = SeqLocLen (slp);
8503                 if (seq_len <= feat_start && seq_len + len > feat_start) {
8504                   sip = SeqLocId (slp);
8505                   feat_offset = feat_start - seq_len;
8506                 }
8507               } else if (dsp->choice == 2) {
8508                 slip = (SeqLitPtr) dsp->data.ptrvalue;
8509                 len = slip->length;
8510               }
8511               seq_len += len;
8512             }
8513           } else if (bsp->seq_ext_type == 1) {
8514             slp = (SeqLocPtr) bsp->seq_ext;
8515             while (slp != NULL && seq_len <= feat_start && sip == NULL) {
8516               len = SeqLocLen (slp);
8517               if (seq_len <= feat_start && seq_len + len > feat_start) {
8518                 sip = SeqLocId (slp);
8519                 feat_offset = feat_start - seq_len;
8520               } else {
8521                 slp = slp->next;
8522               }
8523               seq_len += len;
8524             }
8525 		  } else {
8526 		    some_missing = TRUE;
8527 		  }
8528         }
8529 
8530         if (piece_bsp == NULL && sip != NULL) {
8531           oldscope = SeqEntrySetScope (NULL);
8532           piece_bsp = BioseqFind (sip);
8533           SeqEntrySetScope (oldscope);
8534         }
8535 
8536         if (sip == NULL || piece_bsp == NULL) {
8537           some_missing = TRUE;
8538         } else {
8539           sip = SeqIdFindBest (piece_bsp->id, SEQID_GENBANK);
8540           SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
8541           sprintf (num_str, "%d", (int) feat_offset + 1);
8542           location = SeqLocPrintUseBestID (sfp->location);
8543           label = (CharPtr) FeatDefTypeLabel(sfp);
8544           row_text = (CharPtr) MemNew (sizeof (Char) *
8545                                      (StringLen (label)
8546                                       + StringLen (fcontext.label)
8547                                       + StringLen (location)
8548                                       + StringLen (str)
8549                                       + StringLen (num_str)
8550                                       + 6));
8551           sprintf (row_text, "%s\t%s\t%s\t%s\t%s\n", label, fcontext.label, location, str, num_str);
8552           location = MemFree (location);
8553           AppendText (fcp->doc, row_text, &contigParFmt, contigColFmt, programFont);
8554           row_text = MemFree (row_text);
8555 
8556           ValNodeAddPointer (&(fcp->id_list), 0, SeqIdDup (sip));
8557         }
8558       }
8559     }
8560   }
8561   UpdateDocument (fcp->doc, 0, 0);
8562   if (some_missing) {
8563     Message (MSG_ERROR, "Some features are on sequences that are not far records!\n");
8564   }
8565 }
8566 
CleanupFindContigFormProc(GraphiC g,Pointer data)8567 static void CleanupFindContigFormProc (GraphiC g, Pointer data)
8568 {
8569   FindContigPtr fcp;
8570 
8571   if (data != NULL)
8572   {
8573     fcp = (FindContigPtr) data;
8574     fcp->id_list = FreeSeqIdList (fcp->id_list);
8575   }
8576   StdCleanupExtraProc (g, data);
8577 }
8578 
8579 
FindConRecordCallback(BioseqPtr bsp,Pointer userdata)8580 static void FindConRecordCallback (BioseqPtr bsp, Pointer userdata)
8581 {
8582   BioseqPtr *pbsp = (BioseqPtr *) userdata;
8583   if (bsp == NULL || userdata == NULL || ! ISA_na (bsp->mol)
8584       || (bsp->repr != Seq_repr_seg && bsp->repr != Seq_repr_delta)
8585       || *pbsp != NULL) {
8586       return;
8587   } else {
8588       *pbsp = bsp;
8589   }
8590 }
8591 
8592 
FindConRecord(Uint2 entityID)8593 static BioseqPtr FindConRecord (Uint2 entityID)
8594 {
8595   SeqEntryPtr sep;
8596   BioseqPtr   con_bsp = NULL;
8597 
8598   sep = GetTopSeqEntryForEntityID (entityID);
8599   VisitBioseqsInSep (sep, &con_bsp, FindConRecordCallback);
8600   return con_bsp;
8601 }
8602 
8603 
FindContig(IteM i)8604 extern void FindContig (IteM i)
8605 {
8606   BaseFormPtr   bfp;
8607   FindContigPtr fcp;
8608   WindoW        w;
8609   GrouP         h, c;
8610   ButtoN        b;
8611   RecT          r;
8612   Char          str [128];
8613   CharPtr       title;
8614   CharPtr       title_fmt = "Find Contig for Features in %s";
8615   BioseqPtr     con_bsp;
8616 
8617 #ifdef WIN_MAC
8618   bfp = currentFormDataPtr;
8619 #else
8620   bfp = GetObjectExtra (i);
8621 #endif
8622   if (bfp == NULL) return;
8623 
8624   con_bsp = FindConRecord (bfp->input_entityID);
8625   if (con_bsp == NULL) {
8626     Message (MSG_ERROR, "No con records found!");
8627     return;
8628   }
8629 
8630   fcp = MemNew (sizeof (FindContigData));
8631   if (fcp != NULL) {
8632     fcp->input_entityID = bfp->input_entityID;
8633     fcp->con_bsp = con_bsp;
8634     SeqIdWrite (SeqIdFindBest (fcp->con_bsp->id, SEQID_GENBANK), str, PRINTID_REPORT, sizeof (str));
8635     title = (CharPtr) MemNew (sizeof (Char) * (StringLen (str) + StringLen (title_fmt)));
8636     sprintf (title, title_fmt, str);
8637     w = FixedWindow (-50, -33, -10, -10, title, NULL);
8638     title = MemFree (title);
8639     SetObjectExtra (w, fcp, CleanupFindContigFormProc);
8640     fcp->form = (ForM) w;
8641     fcp->formmessage = DefaultMessageProc;
8642     h = HiddenGroup (w, -1, 0, NULL);
8643     SetGroupSpacing (h, 10, 10);
8644     fcp->doc = DocumentPanel (h, 50 * stdCharWidth, 20 * stdLineHeight);
8645     SetObjectExtra (fcp->doc, fcp, NULL);
8646     SetDocProcs (fcp->doc, ClickContigPiece, NULL, NULL, NULL);
8647 
8648     ObjectRect (fcp->doc, &r);
8649     InsetRect (&r, 4, 4);
8650 
8651     contigColFmt[0].pixWidth = 5 * stdCharWidth;
8652     contigColFmt[3].pixWidth = 7 * stdCharWidth;
8653     contigColFmt[4].pixWidth = 5 * stdCharWidth;
8654     contigColFmt[1].pixWidth = (r.right - r.left - contigColFmt[0].pixWidth - contigColFmt[3].pixWidth - contigColFmt[4].pixWidth) / 2;
8655     contigColFmt[2].pixWidth = (r.right - r.left - contigColFmt[0].pixWidth - contigColFmt[3].pixWidth - contigColFmt[4].pixWidth) / 2;
8656 
8657     c = HiddenGroup (h, 2, 0, NULL);
8658     b = PushButton (c, "Find Selected Contig", FindContigBtn);
8659     SetObjectExtra (b, fcp, NULL);
8660     FindContigBtn(b);
8661     b = PushButton (c, "Done", StdCancelButtonProc);
8662     AlignObjects (ALIGN_CENTER, (HANDLE) fcp->doc, (HANDLE) c, NULL);
8663     Show (w);
8664     Select (w);
8665   }
8666 }
8667 
8668 
ListDeltaCallback(BioseqPtr bsp,Pointer userdata)8669 static void ListDeltaCallback (BioseqPtr bsp, Pointer userdata)
8670 {
8671   ValNodePtr PNTR bsplist;
8672 
8673   if (bsp == NULL || bsp->repr != Seq_repr_delta || userdata == NULL) {
8674     return;
8675   }
8676 
8677   bsplist = (ValNodePtr PNTR) userdata;
8678   ValNodeAddPointer (bsplist, 0, bsp);
8679 }
8680 
8681 
ShowDeltaReport(SeqEntryPtr sep)8682 extern Boolean ShowDeltaReport (SeqEntryPtr sep)
8683 {
8684   ValNodePtr bsplist = NULL, vnp;
8685   FILE      *fp;
8686   Char       path [PATH_MAX];
8687   BioseqPtr  bsp;
8688   Char       str [128];
8689 
8690   if (sep == NULL) return FALSE;
8691 
8692   VisitBioseqsInSep (sep, &bsplist, ListDeltaCallback);
8693   if (bsplist == NULL) return FALSE;
8694 
8695   TmpNam (path);
8696   fp = FileOpen (path, "w");
8697   if (fp != NULL) {
8698     for (vnp = bsplist; vnp != NULL; vnp = vnp->next) {
8699       bsp = (BioseqPtr) vnp->data.ptrvalue;
8700       if (bsp != NULL && bsp->id != NULL) {
8701         SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), str, PRINTID_REPORT, sizeof (str));
8702         fprintf (fp, "%s\n", str);
8703       }
8704     }
8705     FileClose (fp);
8706     LaunchGeneralTextViewer (path, "Delta Sequences");
8707     FileRemove (path);
8708     ValNodeFree (bsplist);
8709   }
8710   return TRUE;
8711 }
8712 
8713 
FindLastExonForCDS(BioseqPtr bsp,SeqFeatPtr cds)8714 static SeqFeatPtr FindLastExonForCDS (BioseqPtr bsp, SeqFeatPtr cds)
8715 {
8716   SeqFeatPtr        exon, last_exon = NULL;
8717   SeqMgrFeatContext cds_context, exon_context;
8718   Int4              cds_stop;
8719 
8720   if (bsp == NULL || cds == NULL) return NULL;
8721 
8722   cds_stop = SeqLocStop (cds->location);
8723   exon = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_IMP, FEATDEF_exon, &exon_context);
8724   while (exon != NULL && exon_context.left < cds_stop) {
8725     if (SeqMgrGetOverlappingCDS (exon->location, &cds_context) == cds) {
8726       if (SeqLocStrand (cds->location) == Seq_strand_minus) {
8727         return exon;
8728       } else {
8729         last_exon = exon;
8730       }
8731     }
8732     exon = SeqMgrGetNextFeature (bsp, exon, SEQFEAT_IMP, FEATDEF_exon, &exon_context);
8733   }
8734   return last_exon;
8735 }
8736 
8737 
8738 typedef struct lastexonfix {
8739   FILE *fp;
8740   Boolean make_partial;
8741 } LastExonFixData, PNTR LastExonFixPtr;
8742 
FixLastExonLocCallback(BioseqPtr bsp,Pointer userdata)8743 static void FixLastExonLocCallback (BioseqPtr bsp, Pointer userdata)
8744 {
8745   SeqFeatPtr        cds, last_exon;
8746   SeqMgrFeatContext context;
8747   Int4              cds_stop, exon_stop;
8748   SeqIntPtr         sintp;
8749   LastExonFixPtr    lefp;
8750   Boolean           partial5, partial3;
8751   Boolean           was_changed;
8752   CharPtr           location;
8753 
8754   if (bsp == NULL || userdata == NULL) return;
8755   lefp = (LastExonFixPtr) userdata;
8756 
8757   for (cds = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, FEATDEF_CDS, &context);
8758        cds != NULL;
8759        cds = SeqMgrGetNextFeature (bsp, cds, SEQFEAT_CDREGION, FEATDEF_CDS, &context)) {
8760     /* only extend the last codon if the coding region ends with a stop codon */
8761     if (!DoesCDSEndWithStopCodon(cds)) continue;
8762     last_exon = FindLastExonForCDS (bsp, cds);
8763     /* if last_exon location doesn't match end of CDS, extend it */
8764     if (last_exon != NULL && last_exon->location != NULL && last_exon->location->choice == SEQLOC_INT) {
8765       was_changed = FALSE;
8766       location = NULL;
8767       if (SeqLocStrand (cds->location) == Seq_strand_minus) {
8768         cds_stop = SeqLocStart (cds->location);
8769         exon_stop = SeqLocStart (last_exon->location);
8770         /* only extend the last exon by three base pairs to cover the last exon */
8771         if (cds_stop == exon_stop - 3) {
8772           location = SeqLocPrintUseBestID (last_exon->location);
8773           sintp = (SeqIntPtr) last_exon->location->data.ptrvalue;
8774           sintp->from = cds_stop;
8775           was_changed = TRUE;
8776         }
8777       } else {
8778         cds_stop = SeqLocStop (cds->location);
8779         exon_stop = SeqLocStop (last_exon->location);
8780         /* only extend the last exon by three base pairs to cover the last exon */
8781         if (cds_stop == exon_stop + 3) {
8782           location = SeqLocPrintUseBestID (last_exon->location);
8783           sintp = (SeqIntPtr) last_exon->location->data.ptrvalue;
8784           sintp->to = cds_stop;
8785           was_changed = TRUE;
8786         }
8787       }
8788       /* if the location changed, and the make_partial flag is set, make the last exon 3' partial */
8789       if (was_changed && lefp->make_partial) {
8790         CheckSeqLocForPartial (last_exon->location, &partial5, &partial3);
8791         SetSeqLocPartial (last_exon->location, partial5, TRUE);
8792         last_exon->partial = TRUE;
8793       }
8794       if (location != NULL && lefp->fp != NULL) {
8795         fprintf (lefp->fp, "Exon at %s extended\n", location);
8796       }
8797       location = MemFree (location);
8798     }
8799   }
8800 }
8801 
FixLastExonLoc(IteM i,Boolean make_partial)8802 static void FixLastExonLoc (IteM i, Boolean make_partial)
8803 {
8804   BaseFormPtr     bfp;
8805   SeqEntryPtr     sep;
8806   LastExonFixData lefd;
8807   Char            path [PATH_MAX];
8808 
8809 #ifdef WIN_MAC
8810   bfp = currentFormDataPtr;
8811 #else
8812   bfp = GetObjectExtra (i);
8813 #endif
8814 
8815   if (bfp == NULL) return;
8816   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
8817   if (sep == NULL) return;
8818   WatchCursor ();
8819   Update ();
8820 
8821   lefd.make_partial = make_partial;
8822   TmpNam (path);
8823   lefd.fp = FileOpen (path, "w");
8824 
8825   VisitBioseqsInSep (sep, &lefd, FixLastExonLocCallback);
8826 
8827   FileClose (lefd.fp);
8828   LaunchGeneralTextViewer (path, "Last Exons");
8829   FileRemove (path);
8830 
8831   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
8832   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
8833   ArrowCursor ();
8834   Update ();
8835 }
8836 
FixLastExonLocNoPartial(IteM i)8837 extern void FixLastExonLocNoPartial (IteM i)
8838 {
8839   FixLastExonLoc (i, FALSE);
8840 }
8841 
8842 
FixLastExonLocMakePartial(IteM i)8843 extern void FixLastExonLocMakePartial (IteM i)
8844 {
8845   FixLastExonLoc (i, TRUE);
8846 }
8847 
8848 
8849 typedef struct removegenebyfeat
8850 {
8851   FORM_MESSAGE_BLOCK
8852   DialoG  feature_select;
8853   DialoG  constraints;
8854   DialoG  accept_cancel;
8855   DoC     item_list;
8856   ButtoN  skip_suppressed_btn;
8857   ButtoN  skip_other_btn;
8858   PrompT  num_genes;
8859 
8860   Boolean    skip_suppressed;
8861   Boolean    skip_other;
8862 
8863   ValNodePtr feature_type_list;
8864   ValNodePtr feature_list;
8865   Int2       clicked;
8866   Boolean    dblClick;
8867   BaseFormPtr bfp;
8868 } RemoveGeneByFeatData, PNTR RemoveGeneByFeatPtr;
8869 
AddGeneToList(SeqFeatPtr sfp,ValNodePtr PNTR list)8870 static void AddGeneToList (SeqFeatPtr sfp, ValNodePtr PNTR list)
8871 {
8872   ValNodePtr vnp;
8873 
8874   if (sfp == NULL || list == NULL) return;
8875   for (vnp = *list; vnp != NULL; vnp = vnp->next) {
8876     if (vnp->data.ptrvalue == sfp) return;
8877   }
8878   ValNodeAddPointer (list, OBJ_SEQFEAT, sfp);
8879 }
8880 
DoesGeneContainOtherFeatures(SeqFeatPtr gene,SeqFeatPtr one_feat)8881 static Boolean DoesGeneContainOtherFeatures (SeqFeatPtr gene, SeqFeatPtr one_feat)
8882 {
8883   BioseqPtr         bsp;
8884   SeqLocPtr slp;
8885   Int4              tmp;
8886   Int4              gene_left, gene_right;
8887   SeqFeatPtr        other_feat;
8888   SeqMgrFeatContext fcontext;
8889 
8890   if (gene == NULL) return FALSE;
8891 
8892   for (slp = SeqLocFindNext (gene->location, NULL); slp != NULL; slp = slp->next) {
8893     bsp = BioseqFindFromSeqLoc (gene->location);
8894     gene_left = SeqLocStart (slp);
8895     gene_right = SeqLocStop (slp);
8896     if (gene_left > gene_right) {
8897       tmp = gene_left;
8898       gene_left = gene_right;
8899       gene_right = tmp;
8900     }
8901     other_feat = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
8902     while (other_feat != NULL && fcontext.left <= gene_right) {
8903       if (other_feat != gene && other_feat != one_feat
8904           && TestFeatOverlap (other_feat, gene, CONTAINED_WITHIN) > -1) {
8905         return TRUE;
8906       }
8907       other_feat = SeqMgrGetNextFeature (bsp, other_feat, 0, 0, &fcontext);
8908     }
8909   }
8910   return FALSE;
8911 }
8912 
ReportGeneByFeatCallback(SeqFeatPtr sfp,Pointer userdata)8913 static void ReportGeneByFeatCallback (SeqFeatPtr sfp, Pointer userdata)
8914 {
8915   RemoveGeneByFeatPtr  dlg;
8916   GeneRefPtr           grp;
8917   SeqFeatPtr           overlap_gene;
8918   ValNodePtr           vnp;
8919   SeqMgrFeatContext    fcontext;
8920   Boolean              is_suppressed;
8921 
8922   if (sfp == NULL || userdata == NULL)
8923   {
8924     return;
8925   }
8926   dlg = (RemoveGeneByFeatPtr) userdata;
8927 
8928   grp = SeqMgrGetGeneXref (sfp);
8929   is_suppressed = SeqMgrGeneIsSuppressed (grp);
8930   if (dlg->skip_suppressed && grp != NULL && is_suppressed) return;
8931 
8932   for (vnp = dlg->feature_type_list; vnp != NULL; vnp = vnp->next)
8933   {
8934     if (vnp->choice == sfp->idx.subtype)
8935     {
8936       if (grp != NULL && !is_suppressed) {
8937         overlap_gene = SeqMgrGetGeneByLocusTag (BioseqFindFromSeqLoc(sfp->location), grp->locus_tag, &fcontext);
8938       } else {
8939         overlap_gene = SeqMgrGetOverlappingGene(sfp->location, &fcontext);
8940       }
8941       if (!dlg->skip_other || !DoesGeneContainOtherFeatures(overlap_gene, sfp)) {
8942         AddGeneToList(overlap_gene, &(dlg->feature_list));
8943       }
8944       return;
8945     }
8946   }
8947 }
8948 
8949 static Nlm_ParData removeGeneParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
8950 static Nlm_ColData removeGeneColFmt [3] = {{0, 5, 10, 0, NULL, 'l', 1,0,0,0, FALSE},
8951                                          {0, 0, 10, 0, NULL, 'l', 1,0,0,0, FALSE},
8952                                          {0, 0, 10, 0, NULL, 'l', 1,0,0,0, TRUE}};
8953 
PopulateRemoveGeneList(DoC doc,ValNodePtr feature_list)8954 static void PopulateRemoveGeneList (DoC doc, ValNodePtr feature_list)
8955 {
8956   ValNodePtr        vnp;
8957   Int2              numItems;
8958   CharPtr           row_text;
8959   RecT              r;
8960 
8961   if (doc == NULL)
8962   {
8963     return;
8964   }
8965   Reset (doc);
8966 
8967   if (feature_list == NULL)
8968   {
8969     AppendText (doc, "No genes listed", NULL, NULL, programFont);
8970   }
8971 
8972   ObjectRect (doc, &r);
8973   InsetRect (&r, 4, 4);
8974 
8975   removeGeneColFmt[0].pixWidth = 5 * stdCharWidth;
8976   removeGeneColFmt[1].pixWidth = (r.right - r.left - removeGeneColFmt[0].pixWidth) / 2;
8977   removeGeneColFmt[2].pixWidth = (r.right - r.left - removeGeneColFmt[0].pixWidth) / 2;
8978 
8979   vnp = feature_list;
8980 
8981   while (vnp != NULL)
8982   {
8983     row_text = GetDiscrepancyItemText (vnp);
8984     if (row_text != NULL)
8985     {
8986       if (vnp->choice == OBJ_SEQFEAT)
8987       {
8988         AppendText (doc, row_text, &removeGeneParFmt, removeGeneColFmt, programFont);
8989       }
8990       else
8991       {
8992         AppendText (doc, row_text, &removeGeneParFmt, NULL, programFont);
8993       }
8994       row_text = MemFree (row_text);
8995     }
8996     vnp = vnp->next;
8997   }
8998   GetDocParams (doc, &numItems, NULL);
8999   UpdateDocument (doc, 0, numItems);
9000 }
9001 
9002 const CharPtr num_genes_fmt = "%d gene%s to be removed";
9003 
9004 
RemoveGeneByFeatChangeNotify(Pointer userdata)9005 static void RemoveGeneByFeatChangeNotify (Pointer userdata)
9006 {
9007   RemoveGeneByFeatPtr dlg;
9008   SeqEntryPtr         sep;
9009   Char                num_genes_txt[100];
9010   Int4                num_genes;
9011 
9012   dlg = (RemoveGeneByFeatPtr) userdata;
9013   if (dlg == NULL)
9014   {
9015     return;
9016   }
9017 
9018   WatchCursor ();
9019   Update ();
9020 
9021   dlg->skip_suppressed = GetStatus (dlg->skip_suppressed_btn);
9022   dlg->skip_other = GetStatus (dlg->skip_other_btn);
9023 
9024   dlg->feature_type_list = ValNodeFree (dlg->feature_type_list);
9025   dlg->feature_type_list = (ValNodePtr) DialogToPointer (dlg->feature_select);
9026   sep = GetTopSeqEntryForEntityID(dlg->input_entityID);
9027   dlg->feature_list = ValNodeFree(dlg->feature_list);
9028   VisitFeaturesInSep (sep, dlg, ReportGeneByFeatCallback);
9029   PopulateRemoveGeneList (dlg->item_list, dlg->feature_list);
9030 
9031   num_genes = ValNodeLen (dlg->feature_list);
9032   sprintf (num_genes_txt, num_genes_fmt, num_genes, num_genes == 1 ? "" : "s");
9033   SetTitle (dlg->num_genes, num_genes_txt);
9034 
9035   if (dlg->feature_list == NULL)
9036   {
9037     DisableAcceptCancelDialogAccept (dlg->accept_cancel);
9038   }
9039   else
9040   {
9041     EnableAcceptCancelDialogAccept (dlg->accept_cancel);
9042   }
9043   ArrowCursor ();
9044   Update ();
9045 }
9046 
RemoveGeneByFeatChangeBtn(ButtoN b)9047 static void RemoveGeneByFeatChangeBtn (ButtoN b)
9048 {
9049   RemoveGeneByFeatPtr dlg;
9050 
9051   dlg = (RemoveGeneByFeatPtr) GetObjectExtra (b);
9052   RemoveGeneByFeatChangeNotify (dlg);
9053 }
9054 
RemoveGeneByFeatClear(Pointer data)9055 static void RemoveGeneByFeatClear (Pointer data)
9056 {
9057   RemoveGeneByFeatPtr dlg;
9058 
9059   dlg = (RemoveGeneByFeatPtr) data;
9060   if (dlg == NULL) return;
9061 
9062   PointerToDialog (dlg->feature_select, NULL);
9063   PointerToDialog (dlg->constraints, NULL);
9064 }
9065 
RemoveGeneByFeatAction(Pointer userdata)9066 static Boolean RemoveGeneByFeatAction (Pointer userdata)
9067 {
9068   RemoveGeneByFeatPtr dlg;
9069   SeqEntryPtr         sep;
9070   ValNodePtr          vnp;
9071   SeqFeatPtr          sfp;
9072 
9073   if (userdata == NULL) return FALSE;
9074 
9075   dlg = (RemoveGeneByFeatPtr) userdata;
9076 
9077   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
9078   if (sep == NULL) return FALSE;
9079 
9080   for (vnp = dlg->feature_list; vnp != NULL; vnp = vnp->next) {
9081     sfp = vnp->data.ptrvalue;
9082     if (sfp != NULL) {
9083       sfp->idx.deleteme = TRUE;
9084     }
9085   }
9086   DeleteMarkedObjects (dlg->input_entityID, 0, NULL);
9087   dlg->feature_list = ValNodeFree(dlg->feature_list);
9088 
9089   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
9090   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
9091   Update ();
9092   RemoveGeneByFeatChangeNotify(dlg);
9093   return TRUE;
9094 }
9095 
GetSelectedRemoveGene(ValNodePtr feature_list,Int2 item)9096 static SeqFeatPtr GetSelectedRemoveGene(ValNodePtr feature_list, Int2 item)
9097 {
9098     while (feature_list != NULL && item > 1) {
9099         feature_list = feature_list->next;
9100         item--;
9101     }
9102     if (feature_list == NULL) {
9103       return NULL;
9104     } else {
9105       return feature_list->data.ptrvalue;
9106     }
9107 }
9108 
ClickRemoveGene(DoC d,PoinT pt)9109 static void ClickRemoveGene (DoC d, PoinT pt)
9110 
9111 {
9112   Int2                      item, numItems;
9113   Int2                      row;
9114   Int2                col, last_selected;
9115   RemoveGeneByFeatPtr dlg;
9116   SeqFeatPtr          sfp;
9117   BioseqPtr           bsp;
9118 
9119   dlg = (RemoveGeneByFeatPtr)GetObjectExtra (d);
9120   if (dlg != NULL) {
9121     MapDocPoint (d, pt, &item, &row, &col, NULL);
9122     if (item > 0 && row > 0 && dlg->clicked == item) {
9123       dlg->dblClick = dblClick;
9124     } else {
9125       dlg->dblClick = FALSE;
9126     }
9127     last_selected = dlg->clicked;
9128     dlg->clicked = 0;
9129     if (item > 0 && row > 0) {
9130       dlg->clicked = item;
9131     }
9132 
9133     if (item != last_selected)
9134     {
9135       GetDocParams (d, &numItems, NULL);
9136       UpdateDocument (d, 0, numItems);
9137     }
9138 
9139     if (item > 0 && row > 0)
9140     {
9141       sfp = GetSelectedRemoveGene(dlg->feature_list, item);
9142       if (sfp != NULL) {
9143         if (dblClick)
9144         {
9145           GatherProcLaunch (OMPROC_EDIT, FALSE, sfp->idx.entityID, sfp->idx.itemID,
9146                             OBJ_SEQFEAT, 0, 0, OBJ_SEQFEAT, 0);
9147         }
9148         else
9149         {
9150           /* need to scroll to item */
9151           bsp = BioseqFindFromSeqLoc (sfp->location);
9152           SetBioseqViewTargetByBioseq (dlg->bfp, bsp);
9153           ObjMgrSelect (sfp->idx.entityID, sfp->idx.itemID, OBJ_SEQFEAT, 0, NULL);
9154         }
9155       }
9156     }
9157   }
9158 }
9159 
DrawRemoveGene(DoC d,RectPtr r,Int2 item,Int2 firstLine)9160 static void DrawRemoveGene (DoC d, RectPtr r, Int2 item, Int2 firstLine)
9161 
9162 {
9163   RemoveGeneByFeatPtr dlg;
9164   RecT                rct;
9165 
9166   dlg = (RemoveGeneByFeatPtr) GetObjectExtra (d);
9167   if (dlg != NULL && r != NULL && item > 0 && firstLine == 0) {
9168     rct = *r;
9169 
9170     /* draw selection */
9171     if (item == dlg->clicked) {
9172       rct = *r;
9173       rct.right = rct.left + 4;
9174       PaintRect (&rct);
9175     }
9176   }
9177 }
9178 
CleanupRemoveGeneForm(GraphiC g,VoidPtr data)9179 static void CleanupRemoveGeneForm (GraphiC g, VoidPtr data)
9180 
9181 {
9182   RemoveGeneByFeatPtr dlg;
9183 
9184   dlg = (RemoveGeneByFeatPtr) data;
9185   if (dlg != NULL) {
9186     dlg->feature_list = ValNodeFree (dlg->feature_list);
9187     dlg->feature_type_list = ValNodeFreeData (dlg->feature_type_list);
9188   }
9189   StdCleanupFormProc (g, data);
9190 }
9191 
RemoveGeneByUnderlyingFeatureType(IteM i)9192 extern void RemoveGeneByUnderlyingFeatureType(IteM i)
9193 {
9194   BaseFormPtr       bfp;
9195   RemoveGeneByFeatPtr dlg;
9196   WindoW            w;
9197   GrouP             h, k, g, feat_opts;
9198   SeqEntryPtr       sep;
9199   PrompT            p;
9200 
9201 #ifdef WIN_MAC
9202   bfp = currentFormDataPtr;
9203 #else
9204   bfp = GetObjectExtra (i);
9205 #endif
9206   if (bfp == NULL) return;
9207 
9208   dlg = (RemoveGeneByFeatPtr) MemNew (sizeof (RemoveGeneByFeatData));
9209   if (dlg == NULL) return;
9210 
9211   w = FixedWindow (-50, -33, -10, -10, "Remove Genes By Underlying Feature", StdCloseWindowProc);
9212   SetObjectExtra (w, dlg, CleanupRemoveGeneForm);
9213   dlg->form = (ForM) w;
9214   dlg->input_entityID = bfp->input_entityID;
9215   dlg->bfp = bfp;
9216 
9217   h = HiddenGroup (w, -1, 0, NULL);
9218   SetGroupSpacing (h, 10, 10);
9219 
9220   sep = GetTopSeqEntryForEntityID(bfp->input_entityID);
9221   k = HiddenGroup (h, 2, 0, NULL);
9222   SetGroupSpacing (k, 10, 10);
9223 
9224   dlg->item_list = DocumentPanel (k, stdCharWidth * 30 + 5, stdLineHeight * 20);
9225   SetObjectExtra (dlg->item_list, dlg, NULL);
9226   SetDocAutoAdjust (dlg->item_list, FALSE);
9227   SetDocProcs (dlg->item_list, ClickRemoveGene, NULL, NULL, NULL);
9228   SetDocShade (dlg->item_list, DrawRemoveGene, NULL, NULL, NULL);
9229 
9230   g = HiddenGroup (k, -1, 0, NULL);
9231   SetGroupSpacing (g, 10, 10);
9232   p = StaticPrompt (g, "Remove genes that contain features of type:", 0, dialogTextHeight, systemFont, 'l');
9233   dlg->feature_select =  FeatureSelectionDialogEx (g, TRUE, sep,
9234                                                  RemoveGeneByFeatChangeNotify,
9235                                                  dlg);
9236   feat_opts = HiddenGroup (g, -1, 0, NULL);
9237   dlg->skip_suppressed_btn = CheckBox (feat_opts, "Skip features with suppressed gene xrefs", RemoveGeneByFeatChangeBtn);
9238   SetObjectExtra (dlg->skip_suppressed_btn, dlg, NULL);
9239   SetStatus (dlg->skip_suppressed_btn, TRUE);
9240   dlg->skip_suppressed = TRUE;
9241   dlg->skip_other_btn = CheckBox (feat_opts, "Skip genes that contain other features", RemoveGeneByFeatChangeBtn);
9242   SetObjectExtra (dlg->skip_other_btn, dlg, NULL);
9243   SetStatus (dlg->skip_other_btn, TRUE);
9244   dlg->skip_other = TRUE;
9245 
9246   dlg->num_genes = StaticPrompt (g, "0 genes to be removed", 200, dialogTextHeight, systemFont, 'l');
9247 
9248   AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) dlg->feature_select, (HANDLE) feat_opts, NULL);
9249 
9250   dlg->accept_cancel = AcceptCancelDialog (h, RemoveGeneByFeatAction, NULL, RemoveGeneByFeatClear, NULL, (Pointer)dlg, w);
9251   AlignObjects (ALIGN_CENTER, (HANDLE) k, (HANDLE) dlg->accept_cancel, NULL);
9252 
9253   RemoveGeneByFeatChangeNotify(dlg);
9254   Show (w);
9255 }
9256 
9257 
9258 typedef struct intronadjust {
9259   Uint1 featdef;
9260   ValNodePtr bad_feature_list;
9261 } IntronAdjustData, PNTR IntronAdjustPtr;
9262 
9263 
RemoveIntronLocationsFromFeatureCallback(BioseqPtr bsp,Pointer userdata)9264 static void RemoveIntronLocationsFromFeatureCallback (BioseqPtr bsp, Pointer userdata)
9265 {
9266   SeqFeatPtr sfp, intron;
9267   SeqMgrFeatContext sfp_context, intron_context;
9268   IntronAdjustPtr iap;
9269   SeqLocPtr new_loc, tmp_loc;
9270   Boolean   partial5, partial3;
9271 
9272   if (bsp == NULL || userdata == NULL) return;
9273 
9274   iap = (IntronAdjustPtr)userdata;
9275 
9276   for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, iap->featdef, &sfp_context);
9277        sfp != NULL;
9278        sfp = SeqMgrGetNextFeature (bsp, sfp, 0, iap->featdef, &sfp_context)) {
9279     for (intron = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_IMP, FEATDEF_intron, &intron_context);
9280          intron != NULL && intron_context.left < sfp_context.right;
9281          intron = SeqMgrGetNextFeature (bsp, intron, SEQFEAT_IMP, FEATDEF_intron, &intron_context)) {
9282        if (intron_context.right < sfp_context.left) continue;
9283        CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
9284        tmp_loc = (SeqLocPtr) AsnIoMemCopy ((Pointer) sfp->location,
9285                                      (AsnReadFunc) SeqLocAsnRead,
9286                                      (AsnWriteFunc) SeqLocAsnWrite);
9287        tmp_loc = SeqLocSubtract (tmp_loc, intron->location);
9288        new_loc = SeqLocMerge (bsp, NULL, tmp_loc, FALSE, FALSE, FALSE);
9289        tmp_loc = SeqLocFree (tmp_loc);
9290        SetSeqLocPartial (new_loc, partial5, partial3);
9291 
9292        if (new_loc == NULL) {
9293          ValNodeAddPointer (&iap->bad_feature_list, OBJ_SEQFEAT, sfp);
9294        } else {
9295          sfp->location = SeqLocFree (sfp->location);
9296          sfp->location = new_loc;
9297        }
9298     }
9299   }
9300 }
9301 
9302 
9303 typedef void (*ReportClickableListCallback) PROTO ((ValNodePtr));
9304 typedef ValNodePtr (*RefreshClickableListCallback) PROTO ((Uint2));
9305 
9306 typedef struct clickableitemlistwindow {
9307   FORM_MESSAGE_BLOCK
9308   ValNodePtr      item_list;
9309   DialoG          clickable_list;
9310   BaseFormPtr     bfp;
9311   ReportClickableListCallback report_func;
9312   RefreshClickableListCallback refresh_func;
9313 
9314 } ClickableItemListWindowData, PNTR ClickableItemListWindowPtr;
9315 
CleanupClickableItemListWindow(GraphiC g,VoidPtr data)9316 static void CleanupClickableItemListWindow (GraphiC g, VoidPtr data)
9317 
9318 {
9319   ClickableItemListWindowPtr drfp;
9320 
9321   drfp = (ClickableItemListWindowPtr) data;
9322   if (drfp != NULL) {
9323     drfp->item_list = FreeClickableList (drfp->item_list);
9324     ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
9325   }
9326   StdCleanupFormProc (g, data);
9327 }
9328 
ClickableItemListWindowMessage(ForM f,Int2 mssg)9329 static void ClickableItemListWindowMessage (ForM f, Int2 mssg)
9330 
9331 {
9332   ClickableItemListWindowPtr drfp;
9333 
9334   drfp = (ClickableItemListWindowPtr) GetObjectExtra (f);
9335   if (drfp != NULL) {
9336     switch (mssg) {
9337       case VIB_MSG_CLOSE :
9338         Remove (f);
9339         break;
9340       case VIB_MSG_CUT :
9341 /*        CopyDiscrepancyReportToClipboard (drfp); */
9342         break;
9343       case VIB_MSG_COPY :
9344 /*        CopyDiscrepancyReportToClipboard (drfp); */
9345         break;
9346       case VIB_MSG_PASTE :
9347         break;
9348       case VIB_MSG_DELETE :
9349         drfp->item_list = FreeClickableList (drfp->item_list);
9350         PointerToDialog (drfp->clickable_list, NULL);
9351         break;
9352       default :
9353         if (drfp->appmessage != NULL) {
9354           drfp->appmessage (f, mssg);
9355         }
9356         break;
9357     }
9358   }
9359 }
9360 
ClickableItemListWindowMsgFunc(OMMsgStructPtr ommsp)9361 static Int2 LIBCALLBACK ClickableItemListWindowMsgFunc (OMMsgStructPtr ommsp)
9362 {
9363   WindoW                   currentport,
9364                            temport;
9365   OMUserDataPtr            omudp;
9366   ClickableItemListWindowPtr drfp = NULL;
9367 
9368   omudp = (OMUserDataPtr)(ommsp->omuserdata);
9369   if (omudp == NULL) return OM_MSG_RET_ERROR;
9370   drfp = (ClickableItemListWindowPtr) omudp->userdata.ptrvalue;
9371   if (drfp == NULL) return OM_MSG_RET_ERROR;
9372 
9373   currentport = ParentWindow (drfp->form);
9374   temport = SavePort (currentport);
9375   UseWindow (currentport);
9376   Select (drfp->form);
9377   switch (ommsp->message)
9378   {
9379       case OM_MSG_UPDATE:
9380           break;
9381       case OM_MSG_DESELECT:
9382           break;
9383 
9384       case OM_MSG_SELECT:
9385           break;
9386       case OM_MSG_DEL:
9387           Remove (drfp->form);
9388           break;
9389       case OM_MSG_HIDE:
9390           break;
9391       case OM_MSG_SHOW:
9392           break;
9393       case OM_MSG_FLUSH:
9394           Remove (drfp->form);
9395           break;
9396       default:
9397           break;
9398   }
9399   RestorePort (temport);
9400   UseWindow (temport);
9401   return OM_MSG_RET_OK;
9402 }
9403 
9404 #ifndef WIN_MAC
9405 extern void CreateStdValidatorFormMenus (WindoW w);
9406 #endif
9407 
9408 
ReportClickableList(ButtoN b)9409 static void ReportClickableList (ButtoN b)
9410 {
9411   ClickableItemListWindowPtr drfp;
9412   ValNodePtr                 item_list;
9413 
9414   drfp = (ClickableItemListWindowPtr) GetObjectExtra (b);
9415   if (drfp == NULL || drfp->report_func == NULL || drfp->item_list == NULL) return;
9416 
9417   item_list = DialogToPointer (drfp->clickable_list);
9418 
9419   if (item_list == NULL) {
9420     if (ANS_YES == Message (MSG_YN, "You have not selected any items - report all?"))
9421     {
9422       item_list = drfp->item_list;
9423     }
9424     else
9425     {
9426       return;
9427     }
9428 
9429   }
9430 
9431   (drfp->report_func) (item_list);
9432 
9433   if (item_list != drfp->item_list) {
9434     item_list = ValNodeFree (item_list);
9435   }
9436 }
9437 
9438 
RefreshClickableList(ButtoN b)9439 static void RefreshClickableList (ButtoN b)
9440 {
9441   ClickableItemListWindowPtr drfp;
9442 
9443   drfp = (ClickableItemListWindowPtr) GetObjectExtra (b);
9444   if (drfp == NULL || drfp->refresh_func == NULL) return;
9445   WatchCursor();
9446   Update();
9447 
9448   PointerToDialog (drfp->clickable_list, NULL);
9449   drfp->item_list = FreeClickableList (drfp->item_list);
9450 
9451   drfp->item_list = (drfp->refresh_func)(drfp->input_entityID);
9452   PointerToDialog (drfp->clickable_list, drfp->item_list);
9453   ArrowCursor();
9454   Update();
9455 }
9456 
9457 
9458 static void
ShowClickableItemListEx(ValNodePtr clickable_list,BaseFormPtr bfp,CharPtr win_title,CharPtr label1,CharPtr label2,ReportClickableListCallback report_func,RefreshClickableListCallback refresh_func)9459 ShowClickableItemListEx
9460 (ValNodePtr  clickable_list,
9461  BaseFormPtr bfp,
9462  CharPtr     win_title,
9463  CharPtr     label1,
9464  CharPtr     label2,
9465  ReportClickableListCallback report_func,
9466  RefreshClickableListCallback refresh_func)
9467 {
9468   ClickableItemListWindowPtr drfp;
9469   GrouP                    h;
9470   GrouP                    c;
9471   WindoW                   w;
9472   OMUserDataPtr            omudp;
9473   SeqEntryPtr              sep;
9474   ButtoN                   b;
9475 
9476   if (bfp == NULL) return;
9477 
9478   drfp = (ClickableItemListWindowPtr) MemNew (sizeof (ClickableItemListWindowData));
9479   if (drfp == NULL)
9480   {
9481     return;
9482   }
9483 
9484   drfp->bfp = bfp;
9485   drfp->input_entityID = bfp->input_entityID;
9486   sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
9487   w = FixedWindow (-50, -33, -10, -10, win_title, StdCloseWindowProc);
9488   SetObjectExtra (w, drfp, CleanupClickableItemListWindow);
9489   drfp->form = (ForM) w;
9490   drfp->formmessage = ClickableItemListWindowMessage;
9491 
9492   /* register to receive update messages */
9493   drfp->userkey = OMGetNextUserKey ();
9494   drfp->procid = 0;
9495   drfp->proctype = OMPROC_EDIT;
9496   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
9497   if (omudp != NULL) {
9498     omudp->userdata.ptrvalue = (Pointer) drfp;
9499     omudp->messagefunc = ClickableItemListWindowMsgFunc;
9500   }
9501 
9502 
9503 #ifndef WIN_MAC
9504   CreateStdValidatorFormMenus (w);
9505 #endif
9506 
9507   drfp->report_func = report_func;
9508   drfp->refresh_func = refresh_func;
9509 
9510   drfp->item_list = clickable_list;
9511 
9512   h = HiddenGroup (w, -1, 0, NULL);
9513   SetGroupSpacing (h, 10, 10);
9514 
9515   drfp->clickable_list = CreateClickableListDialog (h, label1, label1,
9516                                                     ScrollToDiscrepancyItem, EditDiscrepancyItem, bfp,
9517                                                     GetDiscrepancyItemText);
9518 
9519   PointerToDialog (drfp->clickable_list, drfp->item_list);
9520   c = HiddenGroup (h, 4, 0, NULL);
9521   SetGroupSpacing (c, 10, 10);
9522 
9523   if (drfp->report_func != NULL) {
9524     b = PushButton (c, "Make Report", ReportClickableList);
9525     SetObjectExtra (b, drfp, NULL);
9526   }
9527   if (drfp->refresh_func != NULL) {
9528     b = PushButton (c, "Refresh", RefreshClickableList);
9529     SetObjectExtra (b, drfp, NULL);
9530   }
9531   PushButton (c, "Dismiss", StdCancelButtonProc);
9532 
9533   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list, (HANDLE) c, NULL);
9534 
9535   RealizeWindow (w);
9536 
9537   Show (w);
9538 }
9539 
ShowClickableItemList(ValNodePtr clickable_list,BaseFormPtr bfp,CharPtr win_title,CharPtr label1,CharPtr label2)9540 extern void ShowClickableItemList (ValNodePtr clickable_list, BaseFormPtr bfp, CharPtr win_title, CharPtr label1, CharPtr label2)
9541 {
9542   ShowClickableItemListEx (clickable_list, bfp, win_title, label1, label2, NULL, NULL);
9543 }
9544 
RemoveIntronLocationsFromFeature(IteM i,Uint1 featdef)9545 static void RemoveIntronLocationsFromFeature (IteM i, Uint1 featdef)
9546 {
9547   BaseFormPtr             bfp;
9548   SeqEntryPtr             sep;
9549   IntronAdjustData        iad;
9550   ValNodePtr              item_list = NULL;
9551   ClickableItemPtr        cip;
9552 
9553 #ifdef WIN_MAC
9554   bfp = currentFormDataPtr;
9555 #else
9556   bfp = GetObjectExtra (i);
9557 #endif
9558   if (bfp == NULL) return;
9559 
9560   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9561   WatchCursor ();
9562   Update ();
9563 
9564   iad.featdef = featdef;
9565   iad.bad_feature_list = NULL;
9566 
9567   VisitBioseqsInSep (sep, &iad, RemoveIntronLocationsFromFeatureCallback);
9568 
9569   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9570   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9571   ArrowCursor ();
9572   Update ();
9573 
9574   if (iad.bad_feature_list != NULL) {
9575     cip = NewClickableItem (0, "%d features are completely covered by introns", iad.bad_feature_list);
9576     item_list = ValNodeAddPointer (&item_list, 0, cip);
9577     ShowClickableItemList (item_list, bfp, "Failed Intron Location Removal", "", "Unremoved Features");
9578   }
9579 }
9580 
9581 
RemoveIntronLocationsFromCDS(IteM i)9582 extern void RemoveIntronLocationsFromCDS (IteM i)
9583 {
9584   RemoveIntronLocationsFromFeature(i, FEATDEF_CDS);
9585 }
9586 
9587 
RemoveIntronLocationsFromrRNA(IteM i)9588 extern void RemoveIntronLocationsFromrRNA (IteM i)
9589 {
9590   RemoveIntronLocationsFromFeature(i, FEATDEF_rRNA);
9591 }
9592 
9593 
RemoveIntronLocationsFrommRNA(IteM i)9594 extern void RemoveIntronLocationsFrommRNA (IteM i)
9595 {
9596   RemoveIntronLocationsFromFeature(i, FEATDEF_mRNA);
9597 }
9598 
9599 
RemoveIntronLocationsFromtRNA(IteM i)9600 extern void RemoveIntronLocationsFromtRNA (IteM i)
9601 {
9602   RemoveIntronLocationsFromFeature(i, FEATDEF_tRNA);
9603 }
9604 
9605 
ChooseFeaturesForConversion(ValNodePtr clickable_list,BaseFormPtr bfp,CharPtr label1,CharPtr label2)9606 extern ValNodePtr ChooseFeaturesForConversion (ValNodePtr clickable_list, BaseFormPtr bfp, CharPtr label1, CharPtr label2)
9607 {
9608   ClickableItemListWindowData windata;
9609   GrouP                    h;
9610   GrouP                    c;
9611   ButtoN                   b;
9612   WindoW                   w;
9613   Boolean                  done;
9614   SeqEntryPtr              sep;
9615   ModalAcceptCancelData    acd;
9616   ValNodePtr               vnp_list, selected_feats = NULL;
9617   ClickableItemPtr         cip;
9618 
9619   if (bfp == NULL) return NULL;
9620 
9621   MemSet (&windata, 0, sizeof (ClickableItemListWindowData));
9622 
9623   windata.bfp = bfp;
9624   windata.input_entityID = bfp->input_entityID;
9625   sep = GetTopSeqEntryForEntityID (windata.input_entityID);
9626   w = MovableModalWindow (-50, -33, -10, -10,
9627                           "Choose Features for Conversion",
9628                           StdCloseWindowProc);
9629   SetObjectExtra (w, &windata, NULL);
9630   windata.form = (ForM) w;
9631 
9632   windata.item_list = clickable_list;
9633 
9634   h = HiddenGroup (w, -1, 0, NULL);
9635   SetGroupSpacing (h, 10, 10);
9636 
9637   windata.clickable_list = CreateClickableListDialog (h, label1, label1,
9638                                                     ScrollToDiscrepancyItem, EditDiscrepancyItem, bfp,
9639                                                     GetDiscrepancyItemText);
9640 
9641   PointerToDialog (windata.clickable_list, windata.item_list);
9642 
9643   c = HiddenGroup (h, 2, 0, NULL);
9644   SetGroupSpacing (c, 10, 10);
9645   b = PushButton (c, "Convert Selected Features", ModalAcceptButton);
9646   SetObjectExtra (b, &acd, NULL);
9647   b = PushButton (c, "Cancel", ModalCancelButton);
9648   SetObjectExtra (b, &acd, NULL);
9649 
9650   AlignObjects (ALIGN_CENTER, (HANDLE) windata.clickable_list, (HANDLE) c, NULL);
9651 
9652   RealizeWindow (w);
9653 
9654   Show (w);
9655   Select (w);
9656   done = FALSE;
9657   while (!done)
9658   {
9659     acd.accepted = FALSE;
9660     acd.cancelled = FALSE;
9661     while (!acd.accepted && ! acd.cancelled)
9662     {
9663       ProcessExternalEvent ();
9664       Update ();
9665     }
9666     ProcessAnEvent ();
9667 
9668     if (acd.cancelled)
9669     {
9670       done = TRUE;
9671     }
9672     else
9673     {
9674       for (vnp_list = windata.item_list; vnp_list != NULL; vnp_list = vnp_list->next) {
9675         cip = (ClickableItemPtr) vnp_list->data.ptrvalue;
9676         if (cip->chosen) {
9677           ValNodeLink (&selected_feats, cip->item_list);
9678           cip->item_list = NULL;
9679         }
9680       }
9681       if (selected_feats == NULL) {
9682         Message (MSG_ERROR, "You didn't select any features to convert!  Choose features or hit Cancel");
9683       } else {
9684         done = TRUE;
9685       }
9686     }
9687   }
9688   Remove (w);
9689   windata.item_list = FreeClickableList (windata.item_list);
9690   return selected_feats;
9691 }
9692 
RemoveBadPubsDescCallback(SeqDescPtr sdp,Pointer userdata)9693 static void RemoveBadPubsDescCallback (SeqDescPtr sdp, Pointer userdata)
9694 {
9695   ObjValNodePtr ovp;
9696 
9697   if (sdp == NULL || sdp->choice != Seq_descr_pub || sdp->extended == 0) {
9698     return;
9699   }
9700   if (IsPubContentBad (sdp->data.ptrvalue)) {
9701     ovp = (ObjValNodePtr) sdp;
9702     ovp->idx.deleteme = TRUE;
9703   }
9704 }
9705 
RemoveBadPubsFeatCallback(SeqFeatPtr sfp,Pointer userdata)9706 static void RemoveBadPubsFeatCallback (SeqFeatPtr sfp, Pointer userdata)
9707 {
9708 
9709   if (sfp == NULL || sfp->data.choice != SEQFEAT_PUB) {
9710     return;
9711   }
9712   if (IsPubContentBad (sfp->data.value.ptrvalue)) {
9713     sfp->idx.deleteme = TRUE;
9714   }
9715 }
9716 
RemoveBadPubs(IteM i)9717 extern void RemoveBadPubs (IteM i)
9718 {
9719   BaseFormPtr       bfp;
9720   SeqEntryPtr       sep;
9721 
9722 #ifdef WIN_MAC
9723   bfp = currentFormDataPtr;
9724 #else
9725   bfp = GetObjectExtra (i);
9726 #endif
9727   if (bfp == NULL) return;
9728   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9729   if (sep == NULL) return;
9730   WatchCursor ();
9731   Update ();
9732   VisitDescriptorsInSep (sep, NULL, RemoveBadPubsDescCallback);
9733   VisitFeaturesInSep (sep, NULL, RemoveBadPubsFeatCallback);
9734   DeleteMarkedObjects (0, OBJ_SEQENTRY, sep);
9735   ArrowCursor ();
9736   Update ();
9737   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9738   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9739 }
9740 
9741 
9742 
9743 /* VecScreen Tool */
9744 typedef struct vecscreentool {
9745   FORM_MESSAGE_BLOCK
9746   ValNodePtr      item_list;
9747   DialoG          clickable_list;
9748   BaseFormPtr     bfp;
9749   GrouP           sort_grp;
9750   GrouP           trim_options_grp;
9751   ButtoN          add_citsub_btn;
9752 
9753   SeqEntryPtr     top_sep;
9754   LogInfoPtr      lip;
9755   Int4            trim_option;
9756   ValNodePtr      trimmed_bsps;
9757 
9758 } VecScreenToolData, PNTR VecScreenToolPtr;
9759 
IsVector(SeqFeatPtr sfp)9760 static Boolean IsVector (SeqFeatPtr sfp)
9761 {
9762   Boolean          isvector;
9763   GBQualPtr        gbq;
9764 
9765   if (sfp == NULL || sfp->idx.subtype != FEATDEF_misc_feature) {
9766     return FALSE;
9767   }
9768   for (isvector = FALSE, gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
9769     if (StringCmp (gbq->qual, "standard_name") == 0) {
9770       if (StringCmp (gbq->val, "Vector Contamination") == 0) {
9771         isvector = TRUE;
9772       }
9773     }
9774   }
9775   return isvector;
9776 }
9777 
9778 
DeleteVectorCallback(SeqFeatPtr sfp,Pointer userdata)9779 static void DeleteVectorCallback (SeqFeatPtr sfp, Pointer userdata)
9780 {
9781   if (IsVector(sfp)) {
9782     sfp->idx.deleteme = TRUE;
9783   }
9784 }
9785 
9786 
CleanupVecScreenTool(GraphiC g,VoidPtr data)9787 static void CleanupVecScreenTool (GraphiC g, VoidPtr data)
9788 
9789 {
9790   VecScreenToolPtr drfp;
9791   SeqEntryPtr      sep;
9792 
9793   drfp = (VecScreenToolPtr) data;
9794   if (drfp != NULL) {
9795     drfp->item_list = FreeClickableList (drfp->item_list);
9796     ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
9797     sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
9798     VisitFeaturesInSep (sep, NULL, DeleteVectorCallback);
9799     DeleteMarkedObjects (drfp->input_entityID, 0, NULL);
9800     ObjMgrSetDirtyFlag (drfp->input_entityID, TRUE);
9801     ObjMgrSendMsg (OM_MSG_UPDATE, drfp->input_entityID, 0, 0);
9802   }
9803   StdCleanupFormProc (g, data);
9804 }
9805 
VecScreenToolMessage(ForM f,Int2 mssg)9806 static void VecScreenToolMessage (ForM f, Int2 mssg)
9807 
9808 {
9809   VecScreenToolPtr drfp;
9810 
9811   drfp = (VecScreenToolPtr) GetObjectExtra (f);
9812   if (drfp != NULL) {
9813     switch (mssg) {
9814       case VIB_MSG_CLOSE :
9815         Remove (f);
9816         break;
9817       case VIB_MSG_CUT :
9818 /*        CopyDiscrepancyReportToClipboard (drfp); */
9819         break;
9820       case VIB_MSG_COPY :
9821 /*        CopyDiscrepancyReportToClipboard (drfp); */
9822         break;
9823       case VIB_MSG_PASTE :
9824         break;
9825       case VIB_MSG_DELETE :
9826         drfp->item_list = FreeClickableList (drfp->item_list);
9827         PointerToDialog (drfp->clickable_list, NULL);
9828         break;
9829       default :
9830         if (drfp->appmessage != NULL) {
9831           drfp->appmessage (f, mssg);
9832         }
9833         break;
9834     }
9835   }
9836 }
9837 
VecScreenToolMsgFunc(OMMsgStructPtr ommsp)9838 static Int2 LIBCALLBACK VecScreenToolMsgFunc (OMMsgStructPtr ommsp)
9839 {
9840   WindoW                   currentport,
9841                            temport;
9842   OMUserDataPtr            omudp;
9843   VecScreenToolPtr drfp = NULL;
9844 
9845   omudp = (OMUserDataPtr)(ommsp->omuserdata);
9846   if (omudp == NULL) return OM_MSG_RET_ERROR;
9847   drfp = (VecScreenToolPtr) omudp->userdata.ptrvalue;
9848   if (drfp == NULL) return OM_MSG_RET_ERROR;
9849 
9850   currentport = ParentWindow (drfp->form);
9851   temport = SavePort (currentport);
9852   UseWindow (currentport);
9853   Select (drfp->form);
9854   switch (ommsp->message)
9855   {
9856       case OM_MSG_UPDATE:
9857           break;
9858       case OM_MSG_DESELECT:
9859           break;
9860 
9861       case OM_MSG_SELECT:
9862           break;
9863       case OM_MSG_DEL:
9864           Remove (drfp->form);
9865           break;
9866       case OM_MSG_HIDE:
9867           break;
9868       case OM_MSG_SHOW:
9869           break;
9870       case OM_MSG_FLUSH:
9871           Remove (drfp->form);
9872           break;
9873       default:
9874           break;
9875   }
9876   RestorePort (temport);
9877   UseWindow (temport);
9878   return OM_MSG_RET_OK;
9879 }
9880 
9881 
GetMatchType(SeqFeatPtr sfp)9882 static CharPtr GetMatchType (SeqFeatPtr sfp)
9883 {
9884   GBQualPtr gbq;
9885 
9886   if (sfp == NULL) return NULL;
9887   gbq = sfp->qual;
9888   while (gbq != NULL) {
9889     if (StringCmp (gbq->qual, "phenotype") == 0) {
9890       if (StringCmp (gbq->val, "Suspect origin") == 0) {
9891         return "suspect";
9892       } else if (StringCmp (gbq->val, "Weak match") == 0) {
9893         return "weak";
9894       } else if (StringCmp (gbq->val, "Strong match") == 0) {
9895         return "strong";
9896       } else if (StringCmp (gbq->val, "Moderate match") == 0) {
9897         return "moderate";
9898       } else {
9899         return gbq->val;
9900       }
9901     }
9902     gbq = gbq->next;
9903   }
9904   return NULL;
9905 }
9906 
9907 
GetFeatureListLoc(ValNodePtr feat_list,VecScreenToolPtr vstp,BioseqPtr bsp)9908 static SeqLocPtr GetFeatureListLoc (ValNodePtr feat_list, VecScreenToolPtr vstp, BioseqPtr bsp)
9909 {
9910   ValNodePtr vnp;
9911   SeqFeatPtr sfp;
9912   Int4       loc_left = -1, loc_right = -1, tmp, start, stop;
9913 
9914   if (feat_list == NULL) {
9915     return NULL;
9916   }
9917   if (bsp == NULL) {
9918     bsp = BioseqFindFromSeqLoc (((SeqFeatPtr)(feat_list->data.ptrvalue))->location);
9919   }
9920   if (bsp == NULL) {
9921     return NULL;
9922   }
9923   vnp = feat_list;
9924   while (vnp != NULL) {
9925     if (vnp->choice == OBJ_SEQFEAT && vnp->data.ptrvalue != NULL) {
9926       sfp = (SeqFeatPtr) vnp->data.ptrvalue;
9927       start = SeqLocStart (sfp->location);
9928       stop = SeqLocStop (sfp->location);
9929       if (!SeqIdIn (SeqLocId(sfp->location), bsp->id)) {
9930         /* quit - this is bad */
9931         return NULL;
9932       }
9933       if (start > stop) {
9934         tmp = stop;
9935         stop = start;
9936         start = tmp;
9937       }
9938       if (loc_left < 0) {
9939         loc_left = start;
9940         loc_right = stop;
9941       } else {
9942         loc_left = MIN (loc_left, start);
9943         loc_right = MAX (loc_right, stop);
9944       }
9945     }
9946     vnp = vnp->next;
9947   }
9948 
9949   if (vstp != NULL) {
9950     if (loc_left != 0 && loc_right != bsp->length - 1) {
9951       /* internal - fix location */
9952 
9953       if (vstp->trim_option == 1) {
9954         /* trim to closest end */
9955         if (loc_left - 0 < bsp->length - 1 - loc_right) {
9956           loc_left = 0;
9957         } else {
9958           loc_right = bsp->length - 1;
9959         }
9960       } else if (vstp->trim_option == 2) {
9961         /* trim to 5' end */
9962         loc_left = 0;
9963       } else {
9964         /* trim to 3' end */
9965         loc_right = bsp->length - 1;
9966       }
9967     }
9968   }
9969   return SeqLocIntNew (loc_left, loc_right, Seq_strand_plus, SeqIdDup (bsp->id));
9970 }
9971 
9972 
CalculateVectorDescriptionEx(ClickableItemPtr cip,BioseqPtr bsp)9973 NLM_EXTERN void CalculateVectorDescriptionEx (ClickableItemPtr cip, BioseqPtr bsp)
9974 {
9975   ValNodePtr vnp;
9976   Int4       len, loc_left, loc_right;
9977   SeqLocPtr  slp;
9978   CharPtr    internal_fmt = "Internal: %d from 5' end, %d from 3' end", cp;
9979   Char       str[256];
9980   SeqIdPtr   use_this_id;
9981 
9982   if (cip == NULL || cip->item_list == NULL) {
9983     return;
9984   }
9985 
9986   slp = GetFeatureListLoc (cip->item_list, NULL, bsp);
9987   if (slp == NULL) return;
9988   loc_left = SeqLocStart (slp);
9989   loc_right = SeqLocStop (slp);
9990   use_this_id = SeqLocId (slp);
9991   if (bsp == NULL) {
9992     bsp = BioseqFind (use_this_id);
9993     if (bsp == NULL) {
9994       /* bad news */
9995       return;
9996     }
9997   } else if (!SeqIdIn (use_this_id, bsp->id)) {
9998     /* bad news */
9999     return;
10000   } else {
10001     use_this_id = SeqIdFindBest (bsp->id, SEQID_GENBANK);
10002   }
10003 
10004   SeqIdWrite (use_this_id, str, PRINTID_REPORT, sizeof (str));
10005   len = StringLen (str) + 2;
10006 
10007   if (loc_left == 0) {
10008     len += 8;
10009   } else if (loc_right == bsp->length - 1) {
10010     len += 8;
10011   } else {
10012     len += StringLen (internal_fmt) + 30;
10013   }
10014   for (vnp = cip->item_list; vnp != NULL; vnp = vnp->next) {
10015     if (vnp->choice == OBJ_SEQFEAT && vnp->data.ptrvalue != NULL) {
10016       cp = GetMatchType (vnp->data.ptrvalue);
10017       if (!StringHasNoText (cp)) {
10018         len += StringLen (cp) + 1;
10019       }
10020     }
10021   }
10022   cip->description = MemFree (cip->description);
10023   cip->description = (CharPtr) MemNew (len * sizeof (Char));
10024   if (loc_left == 0) {
10025     StringCpy (cip->description, "5' End;");
10026   } else if (loc_right == bsp->length - 1) {
10027     StringCpy (cip->description, "3' End;");
10028   } else {
10029     sprintf (cip->description, internal_fmt, loc_left, bsp->length - loc_right);
10030   }
10031   StringCat (cip->description, str);
10032 
10033   for (vnp = cip->item_list; vnp != NULL; vnp = vnp->next) {
10034     if (vnp->choice == OBJ_SEQFEAT && vnp->data.ptrvalue != NULL) {
10035       cp = GetMatchType (vnp->data.ptrvalue);
10036       if (!StringHasNoText (cp)) {
10037         StringCat (cip->description, ";");
10038         StringCat (cip->description, cp);
10039       }
10040     }
10041   }
10042   slp = SeqLocFree (slp);
10043 }
10044 
10045 
CalculateVectorDescription(ClickableItemPtr cip)10046 extern void CalculateVectorDescription (ClickableItemPtr cip)
10047 {
10048   CalculateVectorDescriptionEx (cip, NULL);
10049 }
10050 
10051 
GetVectorContaminationList(BioseqPtr bsp,Pointer userdata)10052 static void GetVectorContaminationList (BioseqPtr bsp, Pointer userdata)
10053 {
10054   ClickableItemPtr cip = NULL;
10055   SeqFeatPtr       sfp;
10056   SeqMgrFeatContext fcontext;
10057   Int4              last_right;
10058 
10059   ValNodePtr PNTR feat_list = (ValNodePtr PNTR) userdata;
10060   if (bsp == NULL || feat_list == NULL) return;
10061 
10062   for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_IMP, FEATDEF_misc_feature, &fcontext);
10063        sfp != NULL;
10064        sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_IMP, FEATDEF_misc_feature, &fcontext)) {
10065     if (IsVector (sfp)) {
10066       if (cip != NULL && last_right >= fcontext.left - 1) {
10067         ValNodeAddPointer (&(cip->item_list), OBJ_SEQFEAT, sfp);
10068         last_right = fcontext.right;
10069       } else {
10070         /* calculate description for previous list */
10071         CalculateVectorDescription (cip);
10072         cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
10073         if (cip != NULL) {
10074           cip->clickable_item_type = 0;
10075           cip->callback_func = NULL;
10076           cip->datafree_func = NULL;
10077           cip->callback_data = NULL;
10078           cip->item_list = NULL;
10079           cip->subcategories = NULL;
10080           cip->expanded = FALSE;
10081           cip->level = 0;
10082           cip->description = NULL;
10083 
10084           ValNodeAddPointer (&(cip->item_list), OBJ_SEQFEAT, sfp);
10085 
10086           ValNodeAddPointer (feat_list, 0, cip);
10087           last_right = fcontext.right;
10088         }
10089       }
10090     }
10091   }
10092   /* calculate description for last item */
10093   CalculateVectorDescription (cip);
10094 }
10095 
10096 
VecScreenToolSelectAll(ValNodePtr vnp)10097 static void VecScreenToolSelectAll (ValNodePtr vnp)
10098 {
10099   ClickableItemPtr cip;
10100 
10101   while (vnp != NULL)
10102   {
10103     cip = (ClickableItemPtr) vnp->data.ptrvalue;
10104     if (cip != NULL)
10105     {
10106       cip->chosen = TRUE;
10107       VecScreenToolSelectAll (cip->subcategories);
10108     }
10109     vnp = vnp->next;
10110   }
10111 
10112 }
10113 
10114 
RedrawVecScreenTool(VecScreenToolPtr vstp)10115 static void RedrawVecScreenTool (VecScreenToolPtr vstp)
10116 {
10117   RecT     r;
10118 
10119   ObjectRect (vstp->clickable_list, &r);
10120   InsetRect (&r, -1, -1);
10121   InvalRect (&r);
10122 }
10123 
10124 
VecScreenToolSelectAllBtn(ButtoN b)10125 static void VecScreenToolSelectAllBtn (ButtoN b)
10126 {
10127   VecScreenToolPtr vstp;
10128 
10129   vstp = (VecScreenToolPtr) GetObjectExtra (b);
10130   if (vstp == NULL) return;
10131 
10132   VecScreenToolSelectAll (vstp->item_list);
10133   RedrawVecScreenTool (vstp);
10134 }
10135 
10136 
VecScreenToolUnselectAll(ValNodePtr vnp)10137 static void VecScreenToolUnselectAll (ValNodePtr vnp)
10138 {
10139   ClickableItemPtr cip;
10140 
10141   while (vnp != NULL)
10142   {
10143     cip = (ClickableItemPtr) vnp->data.ptrvalue;
10144     if (cip != NULL)
10145     {
10146       if (cip->chosen)
10147       {
10148         cip->chosen = FALSE;
10149       }
10150       VecScreenToolUnselectAll (cip->subcategories);
10151     }
10152     vnp = vnp->next;
10153   }
10154 
10155 }
10156 
10157 
VecScreenToolUnselectAllBtn(ButtoN b)10158 static void VecScreenToolUnselectAllBtn (ButtoN b)
10159 {
10160   VecScreenToolPtr vstp;
10161 
10162   vstp = (VecScreenToolPtr) GetObjectExtra (b);
10163   if (vstp == NULL) return;
10164 
10165   VecScreenToolUnselectAll (vstp->item_list);
10166   RedrawVecScreenTool (vstp);
10167 }
10168 
10169 
VecScreenToolUnselectInternal(ValNodePtr vnp)10170 static void VecScreenToolUnselectInternal (ValNodePtr vnp)
10171 {
10172   ClickableItemPtr cip;
10173 
10174   while (vnp != NULL)
10175   {
10176     cip = (ClickableItemPtr) vnp->data.ptrvalue;
10177     if (cip != NULL)
10178     {
10179       if (cip->chosen)
10180       {
10181         if (StringNCmp (cip->description, "Internal", 8) == 0) {
10182           cip->chosen = FALSE;
10183           VecScreenToolUnselectAll (cip->subcategories);
10184         }
10185       } else {
10186         VecScreenToolUnselectInternal (cip->subcategories);
10187       }
10188     }
10189     vnp = vnp->next;
10190   }
10191 }
10192 
VecScreenToolUnselectInternalBtn(ButtoN b)10193 static void VecScreenToolUnselectInternalBtn (ButtoN b)
10194 {
10195   VecScreenToolPtr vstp;
10196 
10197   vstp = (VecScreenToolPtr) GetObjectExtra (b);
10198   if (vstp == NULL) return;
10199   VecScreenToolUnselectInternal (vstp->item_list);
10200   RedrawVecScreenTool (vstp);
10201 }
10202 
10203 
VecScreenToolSelectStrongAndModerate(ValNodePtr vnp)10204 static void VecScreenToolSelectStrongAndModerate (ValNodePtr vnp)
10205 {
10206   ClickableItemPtr cip;
10207 
10208   while (vnp != NULL)
10209   {
10210     cip = (ClickableItemPtr) vnp->data.ptrvalue;
10211     if (cip != NULL)
10212     {
10213       if (StringISearch (cip->description, "strong") != NULL
10214           || StringISearch (cip->description, "moderate") != NULL) {
10215         cip->chosen = TRUE;
10216       }
10217       else
10218       {
10219         cip->chosen = FALSE;
10220       }
10221       VecScreenToolSelectStrongAndModerate (cip->subcategories);
10222     }
10223     vnp = vnp->next;
10224   }
10225 }
10226 
10227 
VecScreenToolSelectStrongAndModerateBtn(ButtoN b)10228 static void VecScreenToolSelectStrongAndModerateBtn (ButtoN b)
10229 {
10230   VecScreenToolPtr vstp;
10231 
10232   vstp = (VecScreenToolPtr) GetObjectExtra (b);
10233   if (vstp == NULL) return;
10234   VecScreenToolSelectStrongAndModerate (vstp->item_list);
10235   RedrawVecScreenTool (vstp);
10236 }
10237 
10238 
DeleteASequence(BioseqPtr bsp)10239 static void DeleteASequence (BioseqPtr bsp)
10240 {
10241   SeqFeatPtr sfp;
10242   SeqMgrFeatContext context;
10243   BioseqPtr  product;
10244 
10245   if (bsp == NULL) {
10246     return;
10247   }
10248   bsp->idx.deleteme = TRUE;
10249 
10250   for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &context);
10251        sfp != NULL;
10252        sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &context)) {
10253     product = BioseqFindFromSeqLoc (sfp->product);
10254     if (product != NULL) {
10255       product->idx.deleteme = TRUE;
10256     }
10257   }
10258 }
10259 
10260 
TrimFeatureList(ValNodePtr feat_list,VecScreenToolPtr vstp)10261 static void TrimFeatureList (ValNodePtr feat_list, VecScreenToolPtr vstp)
10262 {
10263   BioseqPtr  bsp = NULL;
10264   SeqLocPtr  delete_loc;
10265   Int4       len, loc_left = -1, loc_right = -1;
10266 
10267   /* create location to trim */
10268   delete_loc = GetFeatureListLoc (feat_list, vstp, NULL);
10269   if (delete_loc == NULL) return;
10270   bsp = BioseqFindFromSeqLoc (delete_loc);
10271   loc_left = SeqLocStart (delete_loc);
10272   loc_right = SeqLocStop (delete_loc);
10273   if (loc_left == 0 && loc_right >= bsp->length - 1) {
10274     DeleteASequence(bsp);
10275   } else {
10276     len = SeqLocLen (delete_loc);
10277 
10278     if (loc_left == 0) {
10279       TrimQualityScores (bsp, len, TRUE);
10280     } else if (loc_right == bsp->length - 1) {
10281       TrimQualityScores (bsp, len, FALSE);
10282     }
10283 
10284     if (vstp->top_sep != NULL) {
10285       SeqEntryExplore (vstp->top_sep, (Pointer) delete_loc, SeqAlignDeleteByLocCallback);
10286     }
10287     SeqDeleteByLocEx (delete_loc, TRUE, FALSE, TRUE);
10288   }
10289   delete_loc = SeqLocFree (delete_loc);
10290   ValNodeAddPointer (&(vstp->trimmed_bsps), OBJ_BIOSEQ, bsp);
10291 }
10292 
10293 
TrimSelected(ValNodePtr vnp,Boolean do_all,VecScreenToolPtr vstp)10294 static void TrimSelected (ValNodePtr vnp, Boolean do_all, VecScreenToolPtr vstp)
10295 {
10296   ClickableItemPtr cip;
10297 
10298   while (vnp != NULL)
10299   {
10300     cip = (ClickableItemPtr) vnp->data.ptrvalue;
10301     if (cip != NULL)
10302     {
10303       if (cip->chosen || do_all)
10304       {
10305         if (cip->expanded)
10306         {
10307           TrimSelected (cip->subcategories, TRUE, vstp);
10308         }
10309         else
10310         {
10311           TrimFeatureList (cip->item_list, vstp);
10312         }
10313       }
10314       else if (cip->expanded)
10315       {
10316         TrimSelected (cip->subcategories, FALSE, vstp);
10317       }
10318     }
10319     vnp = vnp->next;
10320   }
10321 }
10322 
CollectFeatureList(ValNodePtr feat_list,VecScreenToolPtr vstp,ValNodePtr PNTR loc_list)10323 static void CollectFeatureList (ValNodePtr feat_list, VecScreenToolPtr vstp, ValNodePtr PNTR loc_list)
10324 {
10325   SeqLocPtr  delete_loc;
10326 
10327   /* create location to trim */
10328   delete_loc = GetFeatureListLoc (feat_list, vstp, NULL);
10329   if (delete_loc == NULL) return;
10330   ValNodeAddPointer (loc_list, 0, delete_loc);
10331 }
10332 
10333 
CollectSelected(ValNodePtr vnp,Boolean do_all,VecScreenToolPtr vstp,ValNodePtr PNTR loc_list)10334 static void CollectSelected (ValNodePtr vnp, Boolean do_all, VecScreenToolPtr vstp, ValNodePtr PNTR loc_list)
10335 {
10336   ClickableItemPtr cip;
10337 
10338   while (vnp != NULL)
10339   {
10340     cip = (ClickableItemPtr) vnp->data.ptrvalue;
10341     if (cip != NULL)
10342     {
10343       if (cip->chosen || do_all)
10344       {
10345         if (cip->expanded)
10346         {
10347           CollectSelected (cip->subcategories, TRUE, vstp, loc_list);
10348         }
10349         else
10350         {
10351           CollectFeatureList (cip->item_list, vstp, loc_list);
10352         }
10353       }
10354       else if (cip->expanded)
10355       {
10356         CollectSelected (cip->subcategories, FALSE, vstp, loc_list);
10357       }
10358     }
10359     vnp = vnp->next;
10360   }
10361 }
10362 
SortVectorLoc(VoidPtr ptr1,VoidPtr ptr2)10363 static int LIBCALLBACK SortVectorLoc (VoidPtr ptr1, VoidPtr ptr2)
10364 
10365 {
10366   SeqLocPtr   slp1, slp2;
10367   BioseqPtr   bsp1, bsp2;
10368   Int4        start1, start2;
10369   Char        str1[256], str2[256];
10370   ValNodePtr  vnp1;
10371   ValNodePtr  vnp2;
10372   int         rval = 0;
10373 
10374   if (ptr1 != NULL && ptr2 != NULL) {
10375     vnp1 = *((ValNodePtr PNTR) ptr1);
10376     vnp2 = *((ValNodePtr PNTR) ptr2);
10377     if (vnp1 != NULL && vnp2 != NULL) {
10378       slp1 = vnp1->data.ptrvalue;
10379       slp2 = vnp2->data.ptrvalue;
10380 
10381       bsp1 = BioseqFindFromSeqLoc (slp1);
10382       bsp2 = BioseqFindFromSeqLoc (slp2);
10383       SeqIdWrite (SeqIdFindBest (bsp1->id, SEQID_GENBANK), str1, PRINTID_REPORT, sizeof (str1));
10384       SeqIdWrite (SeqIdFindBest (bsp2->id, SEQID_GENBANK), str2, PRINTID_REPORT, sizeof (str2));
10385       rval = StringCmp (str1, str2);
10386       if (rval == 0) {
10387         start1 = SeqLocStart (slp1);
10388         start2 = SeqLocStart (slp2);
10389         if (start1 > start2) {
10390           rval = 1;
10391         } else if (start1 < start2) {
10392           rval = -1;
10393         }
10394       }
10395     }
10396   }
10397   return rval;
10398 }
10399 
SortClickableItemLoc(VoidPtr ptr1,VoidPtr ptr2)10400 static int LIBCALLBACK SortClickableItemLoc (VoidPtr ptr1, VoidPtr ptr2)
10401 
10402 {
10403   ClickableItemPtr cip1, cip2;
10404   SeqFeatPtr       sfp1, sfp2;
10405   SeqLocPtr   slp1, slp2;
10406   BioseqPtr   bsp1, bsp2;
10407   Int4        start1, start2;
10408   Char        str1[256], str2[256];
10409   ValNodePtr  vnp1;
10410   ValNodePtr  vnp2;
10411   int         rval = 0;
10412 
10413   if (ptr1 != NULL && ptr2 != NULL) {
10414     vnp1 = *((ValNodePtr PNTR) ptr1);
10415     vnp2 = *((ValNodePtr PNTR) ptr2);
10416     if (vnp1 != NULL && vnp2 != NULL) {
10417       cip1 = vnp1->data.ptrvalue;
10418       cip2 = vnp2->data.ptrvalue;
10419 
10420       if (cip1 != NULL && cip2 != NULL
10421           && cip1->item_list != NULL && cip2->item_list != NULL
10422           && cip1->item_list->choice == OBJ_SEQFEAT
10423           && cip2->item_list->choice == OBJ_SEQFEAT) {
10424         sfp1 = (SeqFeatPtr) cip1->item_list->data.ptrvalue;
10425         sfp2 = (SeqFeatPtr) cip2->item_list->data.ptrvalue;
10426         if (sfp1 != NULL && sfp1->location != NULL
10427             && sfp2 != NULL && sfp2->location != NULL) {
10428           slp1 = sfp1->location;
10429           slp2 = sfp2->location;
10430           bsp1 = BioseqFindFromSeqLoc (slp1);
10431           bsp2 = BioseqFindFromSeqLoc (slp2);
10432           SeqIdWrite (SeqIdFindBest (bsp1->id, SEQID_GENBANK), str1, PRINTID_REPORT, sizeof (str1));
10433           SeqIdWrite (SeqIdFindBest (bsp2->id, SEQID_GENBANK), str2, PRINTID_REPORT, sizeof (str2));
10434           rval = StringCmp (str1, str2);
10435           if (rval == 0) {
10436             start1 = SeqLocStart (slp1);
10437             start2 = SeqLocStart (slp2);
10438             if (start1 > start2) {
10439               rval = 1;
10440             } else if (start1 < start2) {
10441               rval = -1;
10442             }
10443           }
10444         }
10445       }
10446     }
10447   }
10448   return rval;
10449 }
10450 
10451 
LogSelected(VecScreenToolPtr vstp)10452 static void LogSelected (VecScreenToolPtr vstp)
10453 {
10454   ValNodePtr loc_list = NULL, vnp;
10455 
10456   if (vstp == NULL) return;
10457 
10458   CollectSelected (vstp->item_list, FALSE, vstp, &loc_list);
10459   loc_list = ValNodeSort (loc_list, SortVectorLoc);
10460 
10461   for (vnp = loc_list; vnp != NULL; vnp = vnp->next) {
10462     LogTrimmedLocation (vstp->lip, vnp->data.ptrvalue);
10463     vnp->data.ptrvalue = SeqLocFree (vnp->data.ptrvalue);
10464   }
10465   loc_list = ValNodeFree (loc_list);
10466 }
10467 
10468 
SortVecScreenList(ValNodePtr item_list)10469 static ValNodePtr SortVecScreenList (ValNodePtr item_list)
10470 {
10471   ClickableItemPtr cip;
10472   ValNodePtr list_5 = NULL, list_3 = NULL, list_internal = NULL;
10473   ValNodePtr list_5_last = NULL, list_3_last = NULL, list_internal_last = NULL;
10474   ValNodePtr next_item, last_item;
10475 
10476   while (item_list != NULL) {
10477     next_item = item_list->next;
10478     item_list->next = NULL;
10479     cip = (ClickableItemPtr) item_list->data.ptrvalue;
10480     if (StringNCmp (cip->description, "5' End", 6) == 0) {
10481       if (list_5_last == NULL) {
10482         list_5 = item_list;
10483       } else {
10484         list_5_last->next = item_list;
10485       }
10486       list_5_last = item_list;
10487     } else if (StringNCmp (cip->description, "3' End", 6) == 0) {
10488       if (list_3_last == NULL) {
10489         list_3 = item_list;
10490       } else {
10491         list_3_last->next = item_list;
10492       }
10493       list_3_last = item_list;
10494     } else {
10495       if (list_internal_last == NULL) {
10496         list_internal = item_list;
10497       } else {
10498         list_internal_last->next = item_list;
10499       }
10500       list_internal_last = item_list;
10501     }
10502     item_list = next_item;
10503   }
10504 
10505   item_list = list_internal;
10506   last_item = list_internal_last;
10507 
10508   if (list_5 != NULL) {
10509     if (item_list == NULL) {
10510       item_list = list_5;
10511       last_item = list_5_last;
10512     } else {
10513       last_item->next = list_5;
10514       last_item = list_5_last;
10515     }
10516   }
10517 
10518   if (list_3 != NULL) {
10519     if (item_list == NULL) {
10520       item_list = list_3;
10521       last_item = list_3_last;
10522     } else {
10523       last_item->next = list_3;
10524       last_item = list_3_last;
10525     }
10526   }
10527 
10528   return item_list;
10529 }
10530 
10531 
SortVecScreenListByStrength(ValNodePtr item_list)10532 static ValNodePtr SortVecScreenListByStrength (ValNodePtr item_list)
10533 {
10534   ClickableItemPtr cip;
10535   ValNodePtr list_strong = NULL, list_moderate = NULL, list_weak = NULL, list_suspect = NULL, list_other = NULL;
10536   ValNodePtr list_strong_last = NULL, list_moderate_last = NULL, list_weak_last = NULL, list_suspect_last = NULL, list_other_last = NULL;
10537   ValNodePtr next_item, last_item;
10538 
10539   while (item_list != NULL) {
10540     next_item = item_list->next;
10541     item_list->next = NULL;
10542     cip = (ClickableItemPtr) item_list->data.ptrvalue;
10543     if (StringISearch (cip->description, "strong") != NULL) {
10544       if (list_strong_last == NULL) {
10545         list_strong = item_list;
10546       } else {
10547         list_strong_last->next = item_list;
10548       }
10549       list_strong_last = item_list;
10550     } else if (StringISearch (cip->description, "moderate") != NULL) {
10551       if (list_moderate_last == NULL) {
10552         list_moderate = item_list;
10553       } else {
10554         list_moderate_last->next = item_list;
10555       }
10556       list_moderate_last = item_list;
10557     } else if (StringISearch (cip->description, "weak") != NULL) {
10558       if (list_weak_last == NULL) {
10559         list_weak = item_list;
10560       } else {
10561         list_weak_last->next = item_list;
10562       }
10563       list_weak_last = item_list;
10564     } else if (StringISearch (cip->description, "suspect") != NULL) {
10565       if (list_suspect_last == NULL) {
10566         list_suspect = item_list;
10567       } else {
10568         list_suspect_last->next = item_list;
10569       }
10570       list_suspect_last = item_list;
10571     } else {
10572       if (list_other_last == NULL) {
10573         list_other = item_list;
10574       } else {
10575         list_other_last->next = item_list;
10576       }
10577       list_other_last = item_list;
10578     }
10579     item_list = next_item;
10580   }
10581 
10582   item_list = list_strong;
10583   last_item = list_strong_last;
10584 
10585   if (list_moderate != NULL) {
10586     if (item_list == NULL) {
10587       item_list = list_moderate;
10588     } else {
10589       last_item->next = list_moderate;
10590     }
10591     last_item = list_moderate_last;
10592   }
10593 
10594   if (list_weak != NULL) {
10595     if (item_list == NULL) {
10596       item_list = list_weak;
10597     } else {
10598       last_item->next = list_weak;
10599     }
10600     last_item = list_weak_last;
10601   }
10602 
10603   if (list_suspect != NULL) {
10604     if (item_list == NULL) {
10605       item_list = list_suspect;
10606     } else {
10607       last_item->next = list_suspect;
10608     }
10609     last_item = list_suspect_last;
10610   }
10611 
10612   if (list_other != NULL) {
10613     if (item_list == NULL) {
10614       item_list = list_other;
10615     } else {
10616       last_item->next = list_other;
10617     }
10618     last_item = list_other_last;
10619   }
10620 
10621   return item_list;
10622 }
10623 
10624 
RearrangeVecScreenForm(VecScreenToolPtr vstp)10625 static void RearrangeVecScreenForm (VecScreenToolPtr vstp)
10626 {
10627   Int2 val;
10628 
10629   if (vstp == NULL) return;
10630   val = GetValue (vstp->sort_grp);
10631   switch (val) {
10632     case 1:
10633       vstp->item_list = SortVecScreenList (vstp->item_list);
10634       break;
10635     case 2:
10636       vstp->item_list = SortVecScreenListByStrength (vstp->item_list);
10637       break;
10638     case 3:
10639       vstp->item_list = ValNodeSort (vstp->item_list, SortVnpByClickableItemChosen);
10640       break;
10641     case 4:
10642     default:
10643       vstp->item_list = ValNodeSort (vstp->item_list, SortClickableItemLoc);
10644       break;
10645   }
10646   PointerToDialog (vstp->clickable_list, vstp->item_list);
10647 
10648 }
10649 
10650 
RearrangeVecScreenList(GrouP g)10651 static void RearrangeVecScreenList (GrouP g)
10652 {
10653   VecScreenToolPtr vstp;
10654 
10655   vstp = (VecScreenToolPtr) GetObjectExtra (g);
10656 
10657   RearrangeVecScreenForm (vstp);
10658 }
10659 
10660 
RefreshVecScreenList(VecScreenToolPtr vstp)10661 static void RefreshVecScreenList (VecScreenToolPtr vstp)
10662 {
10663   if (vstp == NULL) return;
10664 
10665   PointerToDialog (vstp->clickable_list, NULL);
10666   vstp->item_list = FreeClickableList (vstp->item_list);
10667 
10668   VisitBioseqsInSep (vstp->top_sep, &(vstp->item_list), GetVectorContaminationList);
10669   VecScreenToolSelectAll (vstp->item_list);
10670   VecScreenToolUnselectInternal (vstp->item_list);
10671   RearrangeVecScreenForm(vstp);
10672 }
10673 
10674 
FindCompleteDeletions(ValNodePtr item_list,Boolean do_all,VecScreenToolPtr vstp)10675 static ValNodePtr FindCompleteDeletions (ValNodePtr item_list, Boolean do_all, VecScreenToolPtr vstp)
10676 {
10677   ClickableItemPtr cip;
10678   ValNodePtr       list = NULL, vnp;
10679   BioseqPtr        bsp = NULL;
10680   SeqLocPtr        delete_loc;
10681   Int4             loc_left = -1, loc_right = -1;
10682 
10683   vnp = item_list;
10684   while (vnp != NULL)
10685   {
10686     cip = (ClickableItemPtr) vnp->data.ptrvalue;
10687     if (cip != NULL)
10688     {
10689       if (cip->chosen || do_all)
10690       {
10691         if (cip->expanded)
10692         {
10693           ValNodeLink (&list, FindCompleteDeletions (cip->subcategories, TRUE, vstp));
10694         }
10695         else
10696         {
10697           /* find location to trim */
10698           delete_loc = GetFeatureListLoc (cip->item_list, vstp, NULL);
10699           if (delete_loc != NULL) {
10700             bsp = BioseqFindFromSeqLoc (delete_loc);
10701             if (bsp != NULL) {
10702               loc_left = SeqLocStart (delete_loc);
10703               loc_right = SeqLocStop (delete_loc);
10704               delete_loc = SeqLocFree (delete_loc);
10705               if (loc_left == 0 && loc_right >= bsp->length - 1) {
10706                 ValNodeAddPointer (&list, OBJ_BIOSEQ, bsp);
10707               }
10708             }
10709           }
10710         }
10711       }
10712       else if (cip->expanded)
10713       {
10714         ValNodeLink (&list, FindCompleteDeletions (cip->subcategories, FALSE, vstp));
10715       }
10716     }
10717     vnp = vnp->next;
10718   }
10719   return list;
10720 }
10721 
10722 
GetTrimmedCodingRegionList(VecScreenToolPtr vstp)10723 static ValNodePtr GetTrimmedCodingRegionList (VecScreenToolPtr vstp)
10724 {
10725   ValNodePtr loc_list = NULL, vnp;
10726   SeqLocPtr  slp;
10727   BioseqPtr  bsp;
10728   SeqFeatPtr sfp;
10729   SeqMgrFeatContext context;
10730   Int2       comp;
10731   ValNodePtr cds_list = NULL;
10732   SeqEntryPtr orig_scope, sep;
10733 
10734   if (vstp == NULL) return NULL;
10735 
10736   CollectSelected (vstp->item_list, FALSE, vstp, &loc_list);
10737   loc_list = ValNodeSort (loc_list, SortVectorLoc);
10738   sep = GetTopSeqEntryForEntityID (vstp->input_entityID);
10739   orig_scope = SeqEntrySetScope (sep);
10740   for (vnp = loc_list; vnp != NULL; vnp = vnp->next) {
10741     slp = (SeqLocPtr) vnp->data.ptrvalue;
10742 
10743     bsp = BioseqFindFromSeqLoc (slp);
10744     for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &context);
10745          sfp != NULL;
10746          sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &context)) {
10747       comp = SeqLocCompare (sfp->location, slp);
10748       if (comp == SLC_B_IN_A || comp == SLC_A_OVERLAP_B) {
10749         ValNodeAddPointer (&cds_list, OBJ_SEQFEAT, sfp);
10750       }
10751     }
10752     vnp->data.ptrvalue = SeqLocFree (vnp->data.ptrvalue);
10753   }
10754   loc_list = ValNodeFree (loc_list);
10755   cds_list = ValNodeSort (cds_list, SortVnpByChoiceAndPtrvalue);
10756   ValNodeUnique (&cds_list, SortVnpByChoiceAndPtrvalue, ValNodeFree);
10757   SeqEntrySetScope (orig_scope);
10758   return cds_list;
10759 }
10760 
10761 
TrimSelectedBtn(ButtoN b)10762 static void TrimSelectedBtn (ButtoN b)
10763 {
10764   VecScreenToolPtr vstp;
10765   ValNodePtr       vnp;
10766   ValNodePtr       complete_deletion = NULL;
10767   MsgAnswer        ans = ANS_OK;
10768   LogInfoPtr       lip;
10769   CharPtr          str;
10770   ValNodeBlock     id_block;
10771   Int4             msg_len = 0;
10772   CharPtr          submitter_msg_fmt = "The following %d sequences are 100%% matches to vector and will be deleted from your submission: ";
10773   CharPtr          submitter_msg;
10774   SeqEntryPtr      sep;
10775   ValNodePtr       cds_list;
10776 
10777   vstp = (VecScreenToolPtr) GetObjectExtra (b);
10778   if (vstp == NULL) return;
10779 
10780   complete_deletion = FindCompleteDeletions (vstp->item_list, FALSE, vstp);
10781   if (complete_deletion != NULL) {
10782     if (indexerVersion) {
10783       lip = OpenLog ("Sequences to be deleted");
10784       for (vnp = complete_deletion; vnp != NULL; vnp = vnp->next) {
10785         str = GetDiscrepancyItemText (vnp);
10786         fprintf (lip->fp, "%s", str);
10787         lip->data_in_log = TRUE;
10788       }
10789       CloseLog (lip);
10790       lip = FreeLog (lip);
10791       ans = Message (MSG_OKC, "%d sequences will be completely deleted - do you want to continue?",
10792                    ValNodeLen (complete_deletion));
10793     } else {
10794       InitValNodeBlock (&id_block, NULL);
10795       msg_len = StringLen (submitter_msg_fmt) + 15;
10796       for (vnp = complete_deletion; vnp != NULL; vnp = vnp->next) {
10797         str = GetDiscrepancyItemText (vnp);
10798         ValNodeAddPointerToEnd (&id_block, 0, str);
10799         msg_len += StringLen (str) + 2;
10800       }
10801       submitter_msg = (CharPtr) MemNew (sizeof (Char) * msg_len);
10802       sprintf (submitter_msg, submitter_msg_fmt, ValNodeLen (complete_deletion));
10803       for (vnp = id_block.head; vnp != NULL; vnp = vnp->next) {
10804         StringCat (submitter_msg, vnp->data.ptrvalue);
10805         if (vnp->next != NULL) {
10806           StringCat (submitter_msg, ", ");
10807         }
10808       }
10809       ans = Message (MSG_OKC, submitter_msg);
10810       id_block.head = ValNodeFreeData (id_block.head);
10811     }
10812     complete_deletion = ValNodeFree (complete_deletion);
10813   }
10814   if (ans == ANS_CANCEL) {
10815     return;
10816   }
10817 
10818   WatchCursor();
10819   Update();
10820 
10821   /* get list of coding regions to retranslate */
10822   cds_list = GetTrimmedCodingRegionList (vstp);
10823 
10824   vstp->trimmed_bsps = NULL;
10825   vstp->trim_option = GetValue (vstp->trim_options_grp);
10826   vstp->lip = OpenLog ("Trimmed Locations");
10827   LogSelected (vstp);
10828   TrimSelected (vstp->item_list, FALSE, vstp);
10829   CloseLog (vstp->lip);
10830   vstp->lip = FreeLog (vstp->lip);
10831 
10832   /* add cit-subs */
10833   if (GetStatus (vstp->add_citsub_btn)) {
10834     /* sort and unique first, to make sure we only create one per Bioseq */
10835     vstp->trimmed_bsps = ValNodeSort (vstp->trimmed_bsps, SortVnpByChoiceAndPtrvalue);
10836     ValNodeUnique (&(vstp->trimmed_bsps), SortVnpByChoiceAndPtrvalue, ValNodeFree);
10837     for (vnp = vstp->trimmed_bsps; vnp != NULL; vnp = vnp->next) {
10838       if (vnp->choice == OBJ_BIOSEQ) {
10839         AddCitSubToUpdatedSequence (vnp->data.ptrvalue, vstp->input_entityID, kIndexerUpdateVecScreenText);
10840       }
10841     }
10842   }
10843   vstp->trimmed_bsps = ValNodeFree (vstp->trimmed_bsps);
10844   /* now retranslate coding regions */
10845   for (vnp = cds_list; vnp != NULL; vnp = vnp->next) {
10846     RetranslateOneCDS (vnp->data.ptrvalue, vstp->input_entityID, TRUE, TRUE);
10847   }
10848   cds_list = ValNodeFree (cds_list);
10849 
10850   PointerToDialog (vstp->clickable_list, NULL);
10851   vstp->item_list = FreeClickableList (vstp->item_list);
10852   DeleteMarkedObjects (vstp->input_entityID, 0, NULL);
10853   sep = GetTopSeqEntryForEntityID (vstp->input_entityID);
10854   RenormalizeNucProtSets (sep, TRUE);
10855   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
10856   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
10857 
10858   RefreshVecScreenList(vstp);
10859   RedrawVecScreenTool (vstp);
10860   if (vstp->item_list == NULL) {
10861     Remove (vstp->form);
10862   }
10863   ArrowCursor();
10864   Update();
10865 }
10866 
10867 
RemoveSelectedFeatureList(ValNodePtr vnp)10868 static void RemoveSelectedFeatureList (ValNodePtr vnp)
10869 {
10870   SeqFeatPtr sfp;
10871 
10872   while (vnp != NULL) {
10873     if (vnp->choice == OBJ_SEQFEAT && vnp->data.ptrvalue != NULL) {
10874       sfp = (SeqFeatPtr) vnp->data.ptrvalue;
10875       sfp->idx.deleteme = TRUE;
10876     }
10877     vnp = vnp->next;
10878   }
10879 }
10880 
10881 
RemoveSelected(ValNodePtr vnp,Boolean do_all,VecScreenToolPtr vstp)10882 static void RemoveSelected (ValNodePtr vnp, Boolean do_all, VecScreenToolPtr vstp)
10883 {
10884   ClickableItemPtr cip;
10885 
10886   while (vnp != NULL)
10887   {
10888     cip = (ClickableItemPtr) vnp->data.ptrvalue;
10889     if (cip != NULL)
10890     {
10891       if (cip->chosen || do_all)
10892       {
10893         if (cip->expanded)
10894         {
10895           RemoveSelected (cip->subcategories, TRUE, vstp);
10896         }
10897         else
10898         {
10899           RemoveSelectedFeatureList (cip->item_list);
10900         }
10901       }
10902       else if (cip->expanded)
10903       {
10904         RemoveSelected (cip->subcategories, FALSE, vstp);
10905       }
10906     }
10907     vnp = vnp->next;
10908   }
10909 }
10910 
10911 
RemoveSelectedBtn(ButtoN b)10912 static void RemoveSelectedBtn (ButtoN b)
10913 {
10914   VecScreenToolPtr vstp;
10915 
10916   vstp = (VecScreenToolPtr) GetObjectExtra (b);
10917   if (vstp == NULL) return;
10918   WatchCursor();
10919   Update();
10920 
10921   RemoveSelected (vstp->item_list, FALSE, vstp);
10922   PointerToDialog (vstp->clickable_list, NULL);
10923   vstp->item_list = FreeClickableList (vstp->item_list);
10924   DeleteMarkedObjects (vstp->input_entityID, 0, NULL);
10925   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
10926   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
10927 
10928   RefreshVecScreenList(vstp);
10929   RedrawVecScreenTool (vstp);
10930   ArrowCursor();
10931   Update();
10932 }
10933 
ReportVecScreenDiscrepancies(LogInfoPtr lip,ValNodePtr item_list)10934 static void ReportVecScreenDiscrepancies (LogInfoPtr lip, ValNodePtr item_list)
10935 {
10936   ClickableItemPtr cip;
10937   if (item_list == NULL || lip == NULL || lip->fp == NULL) return;
10938 
10939   while (item_list != NULL)
10940   {
10941     cip = (ClickableItemPtr) item_list->data.ptrvalue;
10942     if (cip != NULL)
10943     {
10944       if (!StringHasNoText (cip->description))
10945       {
10946         fprintf (lip->fp, "%s\n", cip->description);
10947         lip->data_in_log = TRUE;
10948       }
10949       ReportVecScreenDiscrepancies (lip, cip->subcategories);
10950     }
10951     item_list = item_list->next;
10952   }
10953 }
10954 
10955 
MakeVecScreenReport(ButtoN b)10956 static void MakeVecScreenReport (ButtoN b)
10957 {
10958   VecScreenToolPtr vstp;
10959   LogInfoPtr       lip;
10960 
10961   vstp = (VecScreenToolPtr) GetObjectExtra (b);
10962   if (vstp == NULL) return;
10963 
10964   lip = OpenLog ("VecScreen Report");
10965   ReportVecScreenDiscrepancies (lip, vstp->item_list);
10966   CloseLog (lip);
10967   lip = FreeLog (lip);
10968 }
10969 
10970 
VecScreenTool(IteM i)10971 extern void VecScreenTool (IteM i)
10972 {
10973   BaseFormPtr              bfp;
10974   VecScreenToolPtr         drfp;
10975   SeqEntryPtr              sep;
10976   GrouP                    h, g;
10977   GrouP                    c, c2;
10978   ButtoN                   b, b1;
10979   WindoW                   w;
10980   OMUserDataPtr            omudp;
10981 
10982 #ifdef WIN_MAC
10983   bfp = currentFormDataPtr;
10984 #else
10985   bfp = GetObjectExtra (i);
10986 #endif
10987   if (bfp == NULL) return;
10988   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
10989   if (sep == NULL) return;
10990 
10991   drfp = (VecScreenToolPtr) MemNew (sizeof (VecScreenToolData));
10992   if (drfp == NULL)
10993   {
10994     return;
10995   }
10996 
10997   drfp->bfp = bfp;
10998   drfp->input_entityID = bfp->input_entityID;
10999   drfp->top_sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
11000   w = FixedWindow (-50, -33, -10, -10, "VecScreen Contamination", StdCloseWindowProc);
11001   SetObjectExtra (w, drfp, CleanupVecScreenTool);
11002   drfp->form = (ForM) w;
11003   drfp->formmessage = VecScreenToolMessage;
11004 
11005   /* register to receive update messages */
11006   drfp->userkey = OMGetNextUserKey ();
11007   drfp->procid = 0;
11008   drfp->proctype = OMPROC_EDIT;
11009   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
11010   if (omudp != NULL) {
11011     omudp->userdata.ptrvalue = (Pointer) drfp;
11012     omudp->messagefunc = VecScreenToolMsgFunc;
11013   }
11014 
11015 
11016 #ifndef WIN_MAC
11017   CreateStdValidatorFormMenus (w);
11018 #endif
11019 
11020   drfp->item_list = NULL;
11021 
11022   h = HiddenGroup (w, -1, 0, NULL);
11023   SetGroupSpacing (h, 10, 10);
11024 
11025   drfp->clickable_list = CreateClickableListDialog (h, "", "Location",
11026                                                     ScrollToDiscrepancyItem, EditDiscrepancyItem, bfp,
11027                                                     GetDiscrepancyItemText);
11028 
11029   drfp->sort_grp = NormalGroup (h, 4, 0, "Order By", programFont, RearrangeVecScreenList);
11030   SetObjectExtra (drfp->sort_grp, drfp, NULL);
11031   SetGroupSpacing (drfp->sort_grp, 10, 10);
11032   RadioButton (drfp->sort_grp, "Internal, 5', 3'");
11033   RadioButton (drfp->sort_grp, "Strength");
11034   RadioButton (drfp->sort_grp, "Marked");
11035   RadioButton (drfp->sort_grp, "Accession");
11036   SetValue (drfp->sort_grp, 1);
11037 
11038   RefreshVecScreenList(drfp);
11039 
11040   drfp->trim_options_grp = NormalGroup (h, 3, 0, "Internal Trim Options", programFont, NULL);
11041   SetGroupSpacing (drfp->trim_options_grp, 10, 10);
11042   RadioButton (drfp->trim_options_grp, "Trim to closest end");
11043   RadioButton (drfp->trim_options_grp, "Trim to 5' end");
11044   RadioButton (drfp->trim_options_grp, "Trim to 3' end");
11045   SetValue (drfp->trim_options_grp, 1);
11046 
11047   c2 = HiddenGroup (h, 4, 0, NULL);
11048   SetGroupSpacing (c2, 10, 10);
11049   b = PushButton (c2, "Select All", VecScreenToolSelectAllBtn);
11050   SetObjectExtra (b, drfp, NULL);
11051   b = PushButton (c2, "Unselect All", VecScreenToolUnselectAllBtn);
11052   SetObjectExtra (b, drfp, NULL);
11053   b = PushButton (c2, "Unselect Internal", VecScreenToolUnselectInternalBtn);
11054   SetObjectExtra (b, drfp, NULL);
11055   b = PushButton (c2, "Select Only Strong and Moderate", VecScreenToolSelectStrongAndModerateBtn);
11056   SetObjectExtra (b, drfp, NULL);
11057 
11058   g = HiddenGroup (h, 2, 0, NULL);
11059   SetGroupSpacing (g, 10, 10);
11060   b1 = PushButton (g, "Remove Selected misc_feats", RemoveSelectedBtn);
11061   SetObjectExtra (b1, drfp, NULL);
11062   MultiLinePrompt (g, "Removes misc_feats with VecScreen hits that you do not want to trim", stdCharWidth * 15, programFont);
11063 
11064   drfp->add_citsub_btn = CheckBox (h, "Add CitSub update to trimmed sequences", NULL);
11065 
11066   c = HiddenGroup (h, 4, 0, NULL);
11067   SetGroupSpacing (c, 10, 10);
11068 
11069   b = PushButton (c, "Make Report", MakeVecScreenReport);
11070   SetObjectExtra (b, drfp, NULL);
11071   b = PushButton (c, "Trim Selected Regions", TrimSelectedBtn);
11072   SetObjectExtra (b, drfp, NULL);
11073   PushButton (c, "Dismiss", StdCancelButtonProc);
11074 
11075   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list,
11076                               (HANDLE) drfp->sort_grp,
11077                               (HANDLE) drfp->trim_options_grp,
11078                               (HANDLE) c2,
11079                               (HANDLE) g,
11080                               (HANDLE) drfp->add_citsub_btn,
11081                               (HANDLE) c,
11082                               NULL);
11083 
11084   RealizeWindow (w);
11085 
11086   Show (w);
11087 }
11088 
11089 
VecScreenSearchBtn(ButtoN b)11090 static void VecScreenSearchBtn (ButtoN b)
11091 {
11092   VecScreenToolPtr  frm;
11093 
11094   frm = (VecScreenToolPtr) GetObjectExtra (b);
11095   if (frm == NULL) {
11096     return;
11097   }
11098 
11099   VecScreenAll (frm->input_entityID);
11100   RefreshVecScreenList(frm);
11101 }
11102 
11103 
GetVecScreenText(ValNodePtr vnp)11104 static CharPtr GetVecScreenText (ValNodePtr vnp)
11105 {
11106   SeqFeatPtr        sfp;
11107   CharPtr           location;
11108 
11109   if (vnp == NULL || vnp->choice != OBJ_SEQFEAT || (sfp = (SeqFeatPtr) vnp->data.ptrvalue) == NULL || sfp->location == NULL)
11110   {
11111     return StringSave ("ERROR");
11112   }
11113 
11114   location = SeqLocPrintUseBestID (sfp->location);
11115   if (location == NULL) {
11116     location = StringSave ("Unknown location");
11117   }
11118   return location;
11119 }
11120 
11121 
ExternalVecScreenTool(IteM i)11122 NLM_EXTERN void ExternalVecScreenTool (IteM i)
11123 {
11124   BaseFormPtr              bfp;
11125   VecScreenToolPtr         drfp;
11126   SeqEntryPtr              sep;
11127   GrouP                    h;
11128   GrouP                    c, c2;
11129   ButtoN                   b, b1;
11130   WindoW                   w;
11131   OMUserDataPtr            omudp;
11132 
11133 #ifdef WIN_MAC
11134   bfp = currentFormDataPtr;
11135 #else
11136   bfp = GetObjectExtra (i);
11137 #endif
11138   if (bfp == NULL) return;
11139   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
11140   if (sep == NULL) return;
11141 
11142   drfp = (VecScreenToolPtr) MemNew (sizeof (VecScreenToolData));
11143   if (drfp == NULL)
11144   {
11145     return;
11146   }
11147 
11148   drfp->bfp = bfp;
11149   drfp->input_entityID = bfp->input_entityID;
11150   drfp->top_sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
11151   w = FixedWindow (-50, -33, -10, -10, "VecScreen Contamination", StdCloseWindowProc);
11152   SetObjectExtra (w, drfp, CleanupVecScreenTool);
11153   drfp->form = (ForM) w;
11154   drfp->formmessage = VecScreenToolMessage;
11155 
11156   /* register to receive update messages */
11157   drfp->userkey = OMGetNextUserKey ();
11158   drfp->procid = 0;
11159   drfp->proctype = OMPROC_EDIT;
11160   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
11161   if (omudp != NULL) {
11162     omudp->userdata.ptrvalue = (Pointer) drfp;
11163     omudp->messagefunc = VecScreenToolMsgFunc;
11164   }
11165 
11166 
11167 #ifndef WIN_MAC
11168   CreateStdValidatorFormMenus (w);
11169 #endif
11170 
11171   drfp->item_list = NULL;
11172 
11173   h = HiddenGroup (w, -1, 0, NULL);
11174   SetGroupSpacing (h, 10, 10);
11175 
11176   drfp->clickable_list = CreateClickableListDialogExExEx (h, "Sequences with Vector Matches", "Location of Match", NULL, NULL,
11177                                                       ScrollToDiscrepancyItem, EditDiscrepancyItem, bfp,
11178                                                       GetVecScreenText, 1,
11179                                                       stdCharWidth * 30,
11180                                                       stdCharWidth * 30 + 5,
11181                                                       TRUE, FALSE, FALSE);
11182 
11183   RefreshVecScreenList(drfp);
11184 
11185   b1 = PushButton (h, "Search UniVec_Core", VecScreenSearchBtn);
11186   SetObjectExtra (b1, drfp, NULL);
11187 
11188   c2 = NormalGroup (h, 4, 0, "Select Sequences with Vector Matches to Trim", programFont, NULL);
11189   SetGroupSpacing (c2, 10, 10);
11190   b = PushButton (c2, "Select All", VecScreenToolSelectAllBtn);
11191   SetObjectExtra (b, drfp, NULL);
11192   b = PushButton (c2, "Select Only Strong and Moderate", VecScreenToolSelectStrongAndModerateBtn);
11193   SetObjectExtra (b, drfp, NULL);
11194   b = PushButton (c2, "Unselect All", VecScreenToolUnselectAllBtn);
11195   SetObjectExtra (b, drfp, NULL);
11196 
11197   c = HiddenGroup (h, 4, 0, NULL);
11198   SetGroupSpacing (c, 10, 10);
11199 
11200   b = PushButton (c, "Make Report", MakeVecScreenReport);
11201   SetObjectExtra (b, drfp, NULL);
11202   b = PushButton (c, "Trim Selected Sequences", TrimSelectedBtn);
11203   SetObjectExtra (b, drfp, NULL);
11204   PushButton (c, "Dismiss", StdCancelButtonProc);
11205 
11206   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list,
11207                               (HANDLE) b1,
11208                               (HANDLE) c2,
11209                               (HANDLE) c,
11210                               NULL);
11211 
11212   RealizeWindow (w);
11213 
11214   Show (w);
11215 }
11216 
11217 
DeleteMarkedFeaturesInSeqAnnot(SeqAnnotPtr sap)11218 static void DeleteMarkedFeaturesInSeqAnnot (SeqAnnotPtr sap)
11219 {
11220   SeqFeatPtr sfp, prev = NULL, sfp_next;
11221 
11222   if (sap == NULL || sap->type != 1) {
11223     return;
11224   }
11225 
11226   sfp = sap->data;
11227   while (sfp != NULL) {
11228     sfp_next = sfp->next;
11229     if (sfp->idx.deleteme) {
11230       if (prev == NULL) {
11231         sap->data = sfp_next;
11232       } else {
11233         prev->next = sfp_next;
11234       }
11235       sfp->next = NULL;
11236       sfp = SeqFeatFree (sfp);
11237     } else {
11238       prev = sfp;
11239     }
11240     sfp = sfp_next;
11241   }
11242 }
11243 
11244 
DeleteMarkedObjectsInSeqEntries(SeqEntryPtr PNTR p_sep)11245 static void DeleteMarkedObjectsInSeqEntries (SeqEntryPtr PNTR p_sep)
11246 {
11247   SeqEntryPtr  sep, prev = NULL, sep_next;
11248   BioseqPtr    bsp;
11249   BioseqSetPtr bssp;
11250   Boolean      remove;
11251 
11252   if (p_sep == NULL) {
11253     return;
11254   }
11255 
11256   sep = *p_sep;
11257   while (sep != NULL) {
11258     sep_next = sep->next;
11259     remove = FALSE;
11260     /* do something */
11261     if (IS_Bioseq (sep)) {
11262       bsp = (BioseqPtr) sep->data.ptrvalue;
11263       if (bsp->idx.deleteme) {
11264         remove = TRUE;
11265       } else {
11266         DeleteMarkedFeaturesInSeqAnnot (bsp->annot);
11267         if (bsp->annot != NULL && bsp->annot->data == NULL) {
11268           bsp->annot = SeqAnnotFree (bsp->annot);
11269         }
11270       }
11271     } else if (IS_Bioseq_set (sep)) {
11272       bssp = (BioseqSetPtr) sep->data.ptrvalue;
11273       DeleteMarkedObjectsInSeqEntries (&(bssp->seq_set));
11274       if (bssp->seq_set == NULL) {
11275         remove = TRUE;
11276       }
11277     }
11278     if (remove) {
11279       if (prev == NULL) {
11280         *p_sep = sep_next;
11281       } else {
11282         prev->next = sep_next;
11283       }
11284       sep->next = NULL;
11285       sep = SeqEntryFree (sep);
11286     } else {
11287       prev = sep;
11288     }
11289     sep = sep_next;
11290   }
11291 }
11292 
11293 
IsVecScreenAnnot(SeqAnnotPtr sap)11294 NLM_EXTERN Boolean IsVecScreenAnnot (SeqAnnotPtr sap)
11295 {
11296   if (sap == NULL) {
11297     return FALSE;
11298   }
11299   if (sap->type == 1 && sap->desc != NULL && sap->desc->choice == Annot_descr_name
11300       && StringICmp (sap->desc->data.ptrvalue, "VecScreen") == 0) {
11301     return TRUE;
11302   } else {
11303     return FALSE;
11304   }
11305 }
11306 
11307 
WizardGetVectorContaminationListForOneBioseq(BioseqPtr bsp,ValNodePtr PNTR feat_list)11308 static void WizardGetVectorContaminationListForOneBioseq (BioseqPtr bsp, ValNodePtr PNTR feat_list)
11309 {
11310   ClickableItemPtr cip = NULL;
11311   SeqFeatPtr       sfp;
11312   Int4             last_right, new_left, new_right, tmp;
11313   SeqAnnotPtr      sap;
11314 
11315   if (bsp == NULL || feat_list == NULL) return;
11316 
11317   for (sap = bsp->annot; sap != NULL; sap = sap->next) {
11318     if (IsVecScreenAnnot(sap)) {
11319       sfp = sap->data;
11320       while (sfp != NULL) {
11321         new_left = SeqLocStart (sfp->location);
11322         new_right = SeqLocStop (sfp->location);
11323         if (new_left > new_right) {
11324           tmp = new_left;
11325           new_left = new_right;
11326           new_right = tmp;
11327         }
11328         if (cip != NULL && last_right >= new_left - 1) {
11329           ValNodeAddPointer (&(cip->item_list), OBJ_SEQFEAT, sfp);
11330           last_right = new_right;
11331         } else {
11332           /* calculate description for previous list */
11333           CalculateVectorDescriptionEx (cip, bsp);
11334           cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
11335           if (cip != NULL) {
11336             cip->clickable_item_type = 0;
11337             cip->callback_func = NULL;
11338             cip->datafree_func = NULL;
11339             cip->callback_data = NULL;
11340             cip->item_list = NULL;
11341             cip->subcategories = NULL;
11342             cip->expanded = FALSE;
11343             cip->level = 0;
11344             cip->description = NULL;
11345 
11346             ValNodeAddPointer (&(cip->item_list), OBJ_SEQFEAT, sfp);
11347 
11348             ValNodeAddPointer (feat_list, 0, cip);
11349             last_right = new_right;
11350           }
11351         }
11352         sfp = sfp->next;
11353       }
11354     }
11355   }
11356   /* calculate description for last item */
11357   CalculateVectorDescriptionEx (cip, bsp);
11358 }
11359 
11360 
WizardGetVectorCominationList(SeqEntryPtr sep)11361 static ValNodePtr WizardGetVectorCominationList (SeqEntryPtr sep)
11362 {
11363   BioseqPtr bsp;
11364   BioseqSetPtr bssp;
11365   ValNodePtr   item_list = NULL;
11366 
11367   while (sep != NULL) {
11368     if (IS_Bioseq (sep)) {
11369       bsp = (BioseqPtr) sep->data.ptrvalue;
11370       WizardGetVectorContaminationListForOneBioseq(bsp, &item_list);
11371     } else if (IS_Bioseq_set (sep)) {
11372       bssp = (BioseqSetPtr) sep->data.ptrvalue;
11373       ValNodeLink (&item_list, WizardGetVectorCominationList(bssp->seq_set));
11374     }
11375     sep = sep->next;
11376   }
11377   return item_list;
11378 }
11379 
11380 
RefreshWizardVecScreenList(VecScreenToolPtr vstp)11381 static void RefreshWizardVecScreenList (VecScreenToolPtr vstp)
11382 {
11383   if (vstp == NULL) return;
11384 
11385   PointerToDialog (vstp->clickable_list, NULL);
11386   vstp->item_list = FreeClickableList (vstp->item_list);
11387 
11388   vstp->item_list = WizardGetVectorCominationList(vstp->top_sep);
11389   VecScreenToolSelectAll (vstp->item_list);
11390   VecScreenToolUnselectInternal (vstp->item_list);
11391   RearrangeVecScreenForm(vstp);
11392 }
11393 
11394 
WizardRemoveVecScreenAnnots(SeqEntryPtr sep)11395 NLM_EXTERN void WizardRemoveVecScreenAnnots (SeqEntryPtr sep)
11396 {
11397   BioseqPtr bsp;
11398   BioseqSetPtr bssp;
11399   SeqAnnotPtr sap, prev = NULL, sap_next;
11400 
11401   while (sep != NULL) {
11402     if (IS_Bioseq (sep)) {
11403       bsp = (BioseqPtr) sep->data.ptrvalue;
11404       for (sap = bsp->annot; sap != NULL; sap = sap_next) {
11405         sap_next = sap->next;
11406         if (IsVecScreenAnnot(sap)) {
11407           if (prev == NULL) {
11408             bsp->annot = sap_next;
11409           } else {
11410             prev->next = sap_next;
11411           }
11412           sap->next = NULL;
11413           sap = SeqAnnotFree (sap);
11414         }
11415       }
11416     } else if (IS_Bioseq_set (sep)) {
11417       bssp = (BioseqSetPtr) sep->data.ptrvalue;
11418       WizardRemoveVecScreenAnnots(bssp->seq_set);
11419     }
11420     sep = sep->next;
11421   }
11422 }
11423 
11424 
WizardVectorTrimSelected(VecScreenToolPtr vstp)11425 static void WizardVectorTrimSelected (VecScreenToolPtr vstp)
11426 {
11427   ValNodePtr       vnp;
11428   ValNodePtr       complete_deletion = NULL;
11429   MsgAnswer        ans = ANS_OK;
11430   LogInfoPtr       lip;
11431   CharPtr          str;
11432   ValNodeBlock     id_block;
11433   Int4             msg_len = 0;
11434   CharPtr          submitter_msg_fmt = "The following %d sequences are 100%% matches to vector and will be deleted from your submission: ";
11435   CharPtr          submitter_msg;
11436 
11437   if (vstp == NULL) return;
11438 
11439   complete_deletion = FindCompleteDeletions (vstp->item_list, FALSE, vstp);
11440   if (complete_deletion != NULL) {
11441     if (indexerVersion) {
11442       lip = OpenLog ("Sequences to be deleted");
11443       for (vnp = complete_deletion; vnp != NULL; vnp = vnp->next) {
11444         str = GetDiscrepancyItemText (vnp);
11445         fprintf (lip->fp, "%s", str);
11446         lip->data_in_log = TRUE;
11447       }
11448       CloseLog (lip);
11449       lip = FreeLog (lip);
11450       ans = Message (MSG_OKC, "%d sequences will be completely deleted - do you want to continue?",
11451                    ValNodeLen (complete_deletion));
11452     } else {
11453       InitValNodeBlock (&id_block, NULL);
11454       msg_len = StringLen (submitter_msg_fmt) + 15;
11455       for (vnp = complete_deletion; vnp != NULL; vnp = vnp->next) {
11456         str = GetDiscrepancyItemText (vnp);
11457         ValNodeAddPointerToEnd (&id_block, 0, str);
11458         msg_len += StringLen (str) + 2;
11459       }
11460       submitter_msg = (CharPtr) MemNew (sizeof (Char) * msg_len);
11461       sprintf (submitter_msg, submitter_msg_fmt, ValNodeLen (complete_deletion));
11462       for (vnp = id_block.head; vnp != NULL; vnp = vnp->next) {
11463         StringCat (submitter_msg, vnp->data.ptrvalue);
11464         if (vnp->next != NULL) {
11465           StringCat (submitter_msg, ", ");
11466         }
11467       }
11468       ans = Message (MSG_OKC, submitter_msg);
11469       id_block.head = ValNodeFreeData (id_block.head);
11470     }
11471     complete_deletion = ValNodeFree (complete_deletion);
11472   }
11473   if (ans == ANS_CANCEL) {
11474     return;
11475   }
11476 
11477   WatchCursor();
11478   Update();
11479 
11480   vstp->trimmed_bsps = NULL;
11481   vstp->trim_option = GetValue (vstp->trim_options_grp);
11482   vstp->lip = OpenLog ("Trimmed Locations");
11483   LogSelected (vstp);
11484   TrimSelected (vstp->item_list, FALSE, vstp);
11485   CloseLog (vstp->lip);
11486   vstp->lip = FreeLog (vstp->lip);
11487 
11488   vstp->trimmed_bsps = ValNodeFree (vstp->trimmed_bsps);
11489 
11490   PointerToDialog (vstp->clickable_list, NULL);
11491   vstp->item_list = FreeClickableList (vstp->item_list);
11492   DeleteMarkedObjectsInSeqEntries (&(vstp->top_sep));
11493 
11494   RefreshWizardVecScreenList(vstp);
11495   RedrawVecScreenTool (vstp);
11496 }
11497 
11498 
WizardVectorTool(SeqEntryPtr PNTR psep)11499 NLM_EXTERN void WizardVectorTool (SeqEntryPtr PNTR psep)
11500 {
11501   SeqEntryPtr           sep;
11502   VecScreenToolPtr      drfp;
11503   GrouP                 h;
11504   GrouP                 c, c2;
11505   ButtoN                b;
11506   WindoW                w;
11507   ModalAcceptCancelData acd;
11508   SeqEntryPtr           orig_scope;
11509 
11510   if (psep == NULL || (sep = *psep) == NULL) return;
11511 
11512   if (!VecScreenWizard (sep)) {
11513     Message (MSG_ERROR, "No vector contamination found!");
11514     return;
11515   }
11516 
11517   drfp = (VecScreenToolPtr) MemNew (sizeof (VecScreenToolData));
11518   if (drfp == NULL)
11519   {
11520     return;
11521   }
11522   orig_scope = SeqEntrySetScope (NULL);
11523 
11524   drfp->top_sep = sep;
11525   w = MovableModalWindow (-20, -13, -10, -10, "VecScreen Contamination", NULL);
11526   SetObjectExtra (w, drfp, CleanupVecScreenTool);
11527   drfp->form = (ForM) w;
11528 
11529   drfp->item_list = NULL;
11530 
11531   h = HiddenGroup (w, -1, 0, NULL);
11532   SetGroupSpacing (h, 10, 10);
11533 
11534   drfp->clickable_list = CreateClickableListDialogExExEx (h, "Sequences with Vector Matches", "Location of Match", NULL, NULL,
11535                                                       NULL, NULL, NULL,
11536                                                       GetVecScreenText, 1,
11537                                                       stdCharWidth * 30,
11538                                                       stdCharWidth * 30 + 5,
11539                                                       TRUE, FALSE, FALSE);
11540 
11541   RefreshWizardVecScreenList(drfp);
11542 
11543   c2 = NormalGroup (h, 4, 0, "Select Sequences with Vector Matches to Trim", programFont, NULL);
11544   SetGroupSpacing (c2, 10, 10);
11545   b = PushButton (c2, "Select All", VecScreenToolSelectAllBtn);
11546   SetObjectExtra (b, drfp, NULL);
11547   b = PushButton (c2, "Select Only Strong and Moderate", VecScreenToolSelectStrongAndModerateBtn);
11548   SetObjectExtra (b, drfp, NULL);
11549   b = PushButton (c2, "Unselect All", VecScreenToolUnselectAllBtn);
11550   SetObjectExtra (b, drfp, NULL);
11551 
11552   c = HiddenGroup (h, 4, 0, NULL);
11553   SetGroupSpacing (c, 10, 10);
11554 
11555   b = PushButton (c, "Make Report", MakeVecScreenReport);
11556   SetObjectExtra (b, drfp, NULL);
11557   b = PushButton (c, "Trim Selected Sequences", ModalAcceptButton);
11558   SetObjectExtra (b, &acd, NULL);
11559   b = PushButton (c, "Dismiss", ModalCancelButton);
11560   SetObjectExtra (b, &acd, NULL);
11561 
11562   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list,
11563                               (HANDLE) c2,
11564                               (HANDLE) c,
11565                               NULL);
11566 
11567   RealizeWindow (w);
11568 
11569   Show (w);
11570 
11571   acd.accepted = FALSE;
11572   acd.cancelled = FALSE;
11573   acd.third_option = FALSE;
11574   while (!acd.cancelled) {
11575     while (!acd.accepted && ! acd.cancelled)
11576     {
11577       ProcessExternalEvent ();
11578       Update ();
11579     }
11580     ProcessAnEvent ();
11581 
11582     if (acd.accepted)
11583     {
11584       WizardVectorTrimSelected (drfp);
11585       acd.accepted = FALSE;
11586       if (drfp->item_list == NULL)
11587       {
11588         acd.cancelled = TRUE;
11589       }
11590     }
11591   }
11592   *psep = drfp->top_sep;
11593   WizardRemoveVecScreenAnnots (*psep);
11594   StdCancelButtonProc (b);
11595   SeqEntrySetScope (orig_scope);
11596 }
11597 
11598 
11599 /* Barcode Test */
11600 typedef struct barcodeundoitem {
11601   ValNodePtr object_list;
11602 	struct barcodeundoitem PNTR next;  /* next in linked list */
11603 	struct barcodeundoitem PNTR prev;  /* prev in linked list */
11604 } BarcodeUndoItemData, PNTR BarcodeUndoItemPtr;
11605 
11606 typedef ValNodePtr (*BarcodeItemCopy) PROTO ((ValNodePtr));
11607 typedef ValNodePtr (*BarcodeItemFree) PROTO ((ValNodePtr));
11608 
BarcodeUndoItemNew(ValNodePtr object_list,BarcodeItemCopy copy_func)11609 static BarcodeUndoItemPtr BarcodeUndoItemNew (ValNodePtr object_list, BarcodeItemCopy copy_func)
11610 {
11611   BarcodeUndoItemPtr item;
11612   ValNodePtr         prev = NULL, next_object;
11613 
11614   if (object_list == NULL) return NULL;
11615 
11616   item = (BarcodeUndoItemPtr) MemNew (sizeof (BarcodeUndoItemData));
11617 
11618   item->next = NULL;
11619   item->prev = NULL;
11620   while (object_list != NULL)
11621   {
11622     if (copy_func == NULL)
11623     {
11624       next_object = ValNodeNew(NULL);
11625       next_object->choice = object_list->choice;
11626       next_object->data.ptrvalue = object_list->data.ptrvalue;
11627     }
11628     else
11629     {
11630       next_object = copy_func (object_list);
11631     }
11632     if (next_object != NULL)
11633     {
11634       if (prev == NULL)
11635       {
11636         item->object_list = next_object;
11637       }
11638       else
11639       {
11640         prev->next = next_object;
11641       }
11642       prev = next_object;
11643     }
11644     object_list = object_list->next;
11645   }
11646   return item;
11647 }
11648 
11649 
BarcodeUndoItemFree(BarcodeUndoItemPtr item,BarcodeItemFree free_func)11650 static BarcodeUndoItemPtr BarcodeUndoItemFree (BarcodeUndoItemPtr item, BarcodeItemFree free_func)
11651 {
11652   BarcodeUndoItemPtr item_next;
11653   ValNodePtr         object_next;
11654 
11655   while (item != NULL)
11656   {
11657     item_next = item->next;
11658     if (free_func == NULL)
11659     {
11660       item->object_list = ValNodeFree (item->object_list);
11661     }
11662     else
11663     {
11664       while (item->object_list != NULL)
11665       {
11666         object_next = item->object_list->next;
11667         item->object_list->next = NULL;
11668         item->object_list = free_func(item->object_list);
11669         item->object_list = object_next;
11670       }
11671     }
11672     item = MemFree (item);
11673     item = item_next;
11674   }
11675   return item;
11676 }
11677 
11678 
11679 typedef struct barcodeundolist {
11680   BarcodeUndoItemPtr list;
11681   BarcodeUndoItemPtr curr;
11682 
11683   BarcodeItemCopy    copy_func;
11684   BarcodeItemFree    free_func;
11685 } BarcodeUndoListData, PNTR BarcodeUndoListPtr;
11686 
11687 
BarcodeUndoListFree(BarcodeUndoListPtr undo_list)11688 static BarcodeUndoListPtr BarcodeUndoListFree (BarcodeUndoListPtr undo_list)
11689 {
11690 
11691   if (undo_list != NULL)
11692   {
11693     undo_list->list = BarcodeUndoItemFree (undo_list->list, undo_list->free_func);
11694     undo_list = MemFree (undo_list);
11695   }
11696   return undo_list;
11697 }
11698 
11699 
BarcodeUndoListNew(BarcodeItemCopy copy_func,BarcodeItemFree free_func)11700 static BarcodeUndoListPtr BarcodeUndoListNew (BarcodeItemCopy copy_func, BarcodeItemFree free_func)
11701 {
11702   BarcodeUndoListPtr undo_list;
11703 
11704   undo_list = (BarcodeUndoListPtr) MemNew (sizeof (BarcodeUndoListData));
11705   undo_list->list = NULL;
11706   undo_list->curr = NULL;
11707   undo_list->copy_func = copy_func;
11708   undo_list->free_func = free_func;
11709   return undo_list;
11710 }
11711 
11712 
AddToBarcodeUndoList(BarcodeUndoListPtr undo_list,ValNodePtr object_list)11713 static void AddToBarcodeUndoList (BarcodeUndoListPtr undo_list, ValNodePtr object_list)
11714 {
11715   BarcodeUndoItemPtr item_new;
11716 
11717   if (undo_list == NULL || object_list == NULL) return;
11718 
11719   item_new = BarcodeUndoItemNew (object_list, undo_list->copy_func);
11720   if (undo_list->curr == NULL)
11721   {
11722     /* if curr is NULL, there is nothing to undo.  list could still contain a list of
11723      * actions that had been undone.
11724      */
11725     undo_list->list = BarcodeUndoItemFree (undo_list->list, undo_list->free_func);
11726     undo_list->list = item_new;
11727   }
11728   else
11729   {
11730     undo_list->curr->next = BarcodeUndoItemFree (undo_list->curr->next, undo_list->free_func);
11731     undo_list->curr->next = item_new;
11732     item_new->prev = undo_list->curr;
11733   }
11734   undo_list->curr = item_new;
11735 }
11736 
11737 
GetUndoFromBarcodeUndoList(BarcodeUndoListPtr undo_list)11738 static ValNodePtr GetUndoFromBarcodeUndoList (BarcodeUndoListPtr undo_list)
11739 {
11740   ValNodePtr object_list = NULL;
11741   if (undo_list == NULL || undo_list->curr == NULL)
11742   {
11743     return NULL;
11744   }
11745   else
11746   {
11747     object_list = undo_list->curr->object_list;
11748     undo_list->curr = undo_list->curr->prev;
11749   }
11750   return object_list;
11751 }
11752 
11753 
GetRedoFromBarcodeUndoList(BarcodeUndoListPtr undo_list)11754 static ValNodePtr GetRedoFromBarcodeUndoList (BarcodeUndoListPtr undo_list)
11755 {
11756   ValNodePtr object_list = NULL;
11757 
11758   if (undo_list == NULL)
11759   {
11760     return NULL;
11761   }
11762   else
11763   {
11764     if (undo_list->curr == NULL)
11765     {
11766       undo_list->curr = undo_list->list;
11767     }
11768     else if (undo_list->curr->next == NULL)
11769     {
11770       return NULL;
11771     }
11772     else
11773     {
11774       undo_list->curr = undo_list->curr->next;
11775     }
11776     object_list = undo_list->curr->object_list;
11777   }
11778   return object_list;
11779 }
11780 
11781 
IsUndoAvailable(BarcodeUndoListPtr undo_list)11782 static Boolean IsUndoAvailable (BarcodeUndoListPtr undo_list)
11783 {
11784   if (undo_list == NULL || undo_list->curr == NULL)
11785   {
11786     return FALSE;
11787   }
11788   else
11789   {
11790     return TRUE;
11791   }
11792 }
11793 
11794 
IsRedoAvailable(BarcodeUndoListPtr undo_list)11795 static Boolean IsRedoAvailable (BarcodeUndoListPtr undo_list)
11796 {
11797   if (undo_list == NULL || undo_list->list == NULL)
11798   {
11799     return FALSE;
11800   }
11801 
11802   if (undo_list->curr == NULL || undo_list->curr->next != NULL)
11803   {
11804     return TRUE;
11805   }
11806   else
11807   {
11808     return FALSE;
11809   }
11810 }
11811 
11812 
BarcodeResultsVNCopyFunc(ValNodePtr vnp)11813 static ValNodePtr BarcodeResultsVNCopyFunc (ValNodePtr vnp)
11814 {
11815   BarcodeTestResultsPtr res1, res2;
11816   ValNodePtr            vnp_new;
11817 
11818   if (vnp == NULL || vnp->data.ptrvalue == NULL) return NULL;
11819 
11820   res1 = (BarcodeTestResultsPtr) vnp->data.ptrvalue;
11821   res2 = BarcodeTestResultsCopy (res1);
11822   vnp_new = ValNodeNew(NULL);
11823   vnp_new->data.ptrvalue = res2;
11824   vnp_new->choice = vnp->choice;
11825   return vnp_new;
11826 }
11827 
11828 
BarcodeResultsVNFreeFunc(ValNodePtr vnp)11829 static ValNodePtr BarcodeResultsVNFreeFunc (ValNodePtr vnp)
11830 {
11831   BarcodeTestResultsPtr res;
11832 
11833   if (vnp != NULL)
11834   {
11835     res = (BarcodeTestResultsPtr) vnp->data.ptrvalue;
11836     res = BarcodeTestResultsFree (res);
11837     vnp->next = BarcodeResultsVNFreeFunc (vnp->next);
11838     vnp = ValNodeFree (vnp);
11839   }
11840   return vnp;
11841 }
11842 
11843 
11844 /* Barcode Tool */
11845 struct barcodetool;
11846 
11847 typedef void (*RefreshBarcodeDataFunc) PROTO ((Pointer));
11848 
11849 #define BARCODE_TOOL_BLOCK \
11850   FORM_MESSAGE_BLOCK \
11851   DialoG          clickable_list; \
11852   BaseFormPtr     bfp; \
11853   PrompT          pass_fail_summary; \
11854   ButtoN          undo; \
11855   ButtoN          undo_all; \
11856   ButtoN          redo; \
11857   ValNodePtr      item_list; \
11858   SeqEntryPtr     top_sep; \
11859   LogInfoPtr      lip; \
11860   BarcodeTestConfigPtr cfg; \
11861   BarcodeUndoListPtr   undo_list; \
11862   RefreshBarcodeDataFunc refresh_func;
11863 
11864 typedef struct barcodetool {
11865 BARCODE_TOOL_BLOCK
11866 } BarcodeToolData, PNTR BarcodeToolPtr;
11867 
CleanupBarcodeTool(GraphiC g,VoidPtr data)11868 static void CleanupBarcodeTool (GraphiC g, VoidPtr data)
11869 
11870 {
11871   BarcodeToolPtr drfp;
11872 
11873   drfp = (BarcodeToolPtr) data;
11874   if (drfp != NULL) {
11875     drfp->item_list = BarcodeTestResultsListFree (drfp->item_list);
11876     drfp->undo_list = BarcodeUndoListFree (drfp->undo_list);
11877     ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
11878   }
11879   StdCleanupFormProc (g, data);
11880 }
11881 
BarcodeToolMessage(ForM f,Int2 mssg)11882 static void BarcodeToolMessage (ForM f, Int2 mssg)
11883 
11884 {
11885   BarcodeToolPtr drfp;
11886 
11887   drfp = (BarcodeToolPtr) GetObjectExtra (f);
11888   if (drfp != NULL) {
11889     switch (mssg) {
11890       case VIB_MSG_CLOSE :
11891         Remove (f);
11892         break;
11893       case VIB_MSG_CUT :
11894 /*        CopyDiscrepancyReportToClipboard (drfp); */
11895         break;
11896       case VIB_MSG_COPY :
11897 /*        CopyDiscrepancyReportToClipboard (drfp); */
11898         break;
11899       case VIB_MSG_PASTE :
11900         break;
11901       case VIB_MSG_DELETE :
11902         drfp->item_list = FreeClickableList (drfp->item_list);
11903         PointerToDialog (drfp->clickable_list, NULL);
11904         break;
11905       default :
11906         if (drfp->appmessage != NULL) {
11907           drfp->appmessage (f, mssg);
11908         }
11909         break;
11910     }
11911   }
11912 }
11913 
BarcodeToolMsgFunc(OMMsgStructPtr ommsp)11914 static Int2 LIBCALLBACK BarcodeToolMsgFunc (OMMsgStructPtr ommsp)
11915 {
11916   WindoW                   currentport,
11917                            temport;
11918   OMUserDataPtr            omudp;
11919   BarcodeToolPtr drfp = NULL;
11920 
11921   omudp = (OMUserDataPtr)(ommsp->omuserdata);
11922   if (omudp == NULL) return OM_MSG_RET_ERROR;
11923   drfp = (BarcodeToolPtr) omudp->userdata.ptrvalue;
11924   if (drfp == NULL) return OM_MSG_RET_ERROR;
11925 
11926   currentport = ParentWindow (drfp->form);
11927   temport = SavePort (currentport);
11928   UseWindow (currentport);
11929   Select (drfp->form);
11930   switch (ommsp->message)
11931   {
11932       case OM_MSG_UPDATE:
11933           break;
11934       case OM_MSG_DESELECT:
11935           break;
11936 
11937       case OM_MSG_SELECT:
11938           break;
11939       case OM_MSG_DEL:
11940           Remove (drfp->form);
11941           break;
11942       case OM_MSG_HIDE:
11943           break;
11944       case OM_MSG_SHOW:
11945           break;
11946       case OM_MSG_FLUSH:
11947           Remove (drfp->form);
11948           break;
11949       default:
11950           break;
11951   }
11952   RestorePort (temport);
11953   UseWindow (temport);
11954   return OM_MSG_RET_OK;
11955 }
11956 
11957 
RefreshBarcodeList(Pointer data)11958 static void RefreshBarcodeList (Pointer data)
11959 {
11960   BarcodeToolPtr vstp;
11961   ValNodePtr pass_list = NULL;
11962   Int4       num_fail = 0, num_pass = 0;
11963   Char       msg[30];
11964 
11965   vstp = (BarcodeToolPtr) data;
11966   if (vstp == NULL) return;
11967 
11968   PointerToDialog (vstp->clickable_list, NULL);
11969   vstp->item_list = BarcodeTestResultsListFree (vstp->item_list);
11970 
11971   vstp->item_list = GetBarcodePassFail(vstp->top_sep, vstp->cfg);
11972   pass_list = BarcodeTestResultsExtractPass(&(vstp->item_list));
11973   num_pass = ValNodeLen (pass_list);
11974   pass_list = BarcodeTestResultsListFree (pass_list);
11975   num_fail = ValNodeLen (vstp->item_list);
11976   PointerToDialog (vstp->clickable_list, vstp->item_list);
11977 
11978   sprintf (msg, "%d pass, %d fail", num_pass, num_fail);
11979   SetTitle (vstp->pass_fail_summary, msg);
11980 }
11981 
11982 
RedrawBarcodeTool(BarcodeToolPtr vstp)11983 static void RedrawBarcodeTool (BarcodeToolPtr vstp)
11984 {
11985   RecT     r;
11986 
11987   ObjectRect (vstp->clickable_list, &r);
11988   InsetRect (&r, -1, -1);
11989   InvalRect (&r);
11990 }
11991 
11992 
EnableUndoRedo(BarcodeToolPtr vstp)11993 static void EnableUndoRedo (BarcodeToolPtr vstp)
11994 {
11995   if (vstp == NULL) return;
11996 
11997   if (IsUndoAvailable (vstp->undo_list))
11998   {
11999     Enable (vstp->undo);
12000     Enable (vstp->undo_all);
12001   }
12002   else
12003   {
12004     Disable (vstp->undo);
12005     Disable (vstp->undo_all);
12006   }
12007 
12008   if (IsRedoAvailable (vstp->undo_list))
12009   {
12010     Enable (vstp->redo);
12011   }
12012   else
12013   {
12014     Disable (vstp->redo);
12015   }
12016 
12017 }
12018 
12019 
BarcodeUndoButton(ButtoN b)12020 static void BarcodeUndoButton (ButtoN b)
12021 {
12022   BarcodeToolPtr vstp;
12023   LogInfoPtr     lip;
12024   ValNodePtr     object_list;
12025 
12026   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12027   if (vstp == NULL) return;
12028 
12029   object_list = GetUndoFromBarcodeUndoList (vstp->undo_list);
12030   EnableUndoRedo (vstp);
12031 
12032   lip = OpenLog ("BARCODE Tech Put Back");
12033 
12034   ApplyBarcodeTech (lip->fp, object_list);
12035 
12036   RefreshBarcodeList (vstp);
12037   RedrawBarcodeTool (vstp);
12038 
12039   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
12040   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
12041   Update();
12042 
12043   lip->data_in_log = TRUE;
12044   CloseLog (lip);
12045   lip = FreeLog (lip);
12046 }
12047 
12048 
BarcodeUndoAllButton(ButtoN b)12049 static void BarcodeUndoAllButton (ButtoN b)
12050 {
12051   BarcodeToolPtr vstp;
12052   LogInfoPtr     lip;
12053   ValNodePtr     object_list;
12054 
12055   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12056   if (vstp == NULL) return;
12057 
12058   lip = OpenLog ("BARCODE Tech Put Back");
12059   while (IsUndoAvailable (vstp->undo_list))
12060   {
12061     object_list = GetUndoFromBarcodeUndoList (vstp->undo_list);
12062     ApplyBarcodeTech (lip->fp, object_list);
12063   }
12064 
12065   EnableUndoRedo (vstp);
12066   RefreshBarcodeList (vstp);
12067   RedrawBarcodeTool (vstp);
12068 
12069   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
12070   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
12071   Update();
12072 
12073   lip->data_in_log = TRUE;
12074   CloseLog (lip);
12075   lip = FreeLog (lip);
12076 }
12077 
12078 
12079 
12080 
BarcodeRedoButton(ButtoN b)12081 static void BarcodeRedoButton (ButtoN b)
12082 {
12083   BarcodeToolPtr vstp;
12084   LogInfoPtr     lip;
12085   ValNodePtr     object_list;
12086 
12087   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12088   if (vstp == NULL) return;
12089 
12090   object_list = GetRedoFromBarcodeUndoList (vstp->undo_list);
12091   EnableUndoRedo (vstp);
12092 
12093   lip = OpenLog ("BARCODE Tech Removed");
12094 
12095   RemoveBarcodeTech (lip->fp, object_list);
12096 
12097   RefreshBarcodeList (vstp);
12098   RedrawBarcodeTool (vstp);
12099 
12100   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
12101   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
12102   Update();
12103 
12104   lip->data_in_log = TRUE;
12105   CloseLog (lip);
12106   lip = FreeLog (lip);
12107 }
12108 
12109 
RemoveSelectedTechBtn(ButtoN b)12110 static void RemoveSelectedTechBtn (ButtoN b)
12111 {
12112   BarcodeToolPtr vstp;
12113   LogInfoPtr     lip;
12114   ValNodePtr     object_list;
12115 
12116   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12117   if (vstp == NULL) return;
12118 
12119   object_list = DialogToPointer (vstp->clickable_list);
12120 
12121   if (object_list == NULL)
12122   {
12123     if (ANS_YES == Message (MSG_YN, "You have not selected any Bioseqs - remove BARCODE tech from all?"))
12124     {
12125       object_list = vstp->item_list;
12126     }
12127     else
12128     {
12129       return;
12130     }
12131   }
12132 
12133   lip = OpenLog ("BARCODE Tech Removed");
12134   RemoveBarcodeTech (lip->fp, object_list);
12135 
12136   /* put in undo queue */
12137   AddToBarcodeUndoList (vstp->undo_list, object_list);
12138 
12139   EnableUndoRedo (vstp);
12140 
12141   if (object_list != vstp->item_list)
12142   {
12143     object_list = ValNodeFree (object_list);
12144   }
12145 
12146   RefreshBarcodeList (vstp);
12147   RedrawBarcodeTool (vstp);
12148 
12149   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
12150   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
12151   Update();
12152 
12153   lip->data_in_log = TRUE;
12154   CloseLog (lip);
12155   lip = FreeLog (lip);
12156 
12157 
12158 }
12159 
12160 
RemoveSelectedKeywordsBtn(ButtoN b)12161 static void RemoveSelectedKeywordsBtn (ButtoN b)
12162 {
12163   BarcodeToolPtr vstp;
12164   LogInfoPtr     lip;
12165   ValNodePtr     object_list;
12166 
12167   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12168   if (vstp == NULL) return;
12169 
12170   object_list = DialogToPointer (vstp->clickable_list);
12171 
12172   if (object_list == NULL)
12173   {
12174     if (ANS_YES == Message (MSG_YN, "You have not selected any Bioseqs - remove BARCODE keyword from all?"))
12175     {
12176       object_list = vstp->item_list;
12177     }
12178     else
12179     {
12180       return;
12181     }
12182   }
12183 
12184   lip = OpenLog ("BARCODE Keywords Removed");
12185   RemoveBarcodeKeywords (lip->fp, object_list);
12186 
12187   if (object_list != vstp->item_list)
12188   {
12189     object_list = ValNodeFree (object_list);
12190   }
12191 
12192   RefreshBarcodeList (vstp);
12193   RedrawBarcodeTool (vstp);
12194 
12195   DeleteMarkedObjects (vstp->input_entityID, 0, NULL);
12196   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
12197   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
12198   Update();
12199 
12200   lip->data_in_log = TRUE;
12201   CloseLog (lip);
12202   lip = FreeLog (lip);
12203 
12204 
12205 }
12206 
12207 
RemoveBarcodeKeywordsFromLowTrace(ButtoN b)12208 static void RemoveBarcodeKeywordsFromLowTrace (ButtoN b)
12209 {
12210   BarcodeToolPtr vstp;
12211   LogInfoPtr     lip;
12212   ValNodePtr     vnp;
12213   BarcodeTestResultsPtr res;
12214   Char                  id_txt[100];
12215 
12216   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12217   if (vstp == NULL) return;
12218 
12219   lip = OpenLog ("BARCODE Keywords Removed");
12220   for (vnp = vstp->item_list; vnp != NULL; vnp = vnp->next) {
12221     res = (BarcodeTestResultsPtr) vnp->data.ptrvalue;
12222     if (res->failed_tests[eBarcodeTest_LowTrace]) {
12223       if (RemoveBarcodeKeywordFromBioseq (res->bsp))
12224       {
12225         SeqIdWrite (SeqIdFindBest (res->bsp->id, SEQID_GENBANK), id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
12226         fprintf (lip->fp, "%s\n", id_txt);
12227       }
12228     }
12229   }
12230 
12231   RefreshBarcodeList (vstp);
12232   RedrawBarcodeTool (vstp);
12233 
12234   DeleteMarkedObjects (vstp->input_entityID, 0, NULL);
12235   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
12236   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
12237   Update();
12238 
12239   CloseLog (lip);
12240   lip = FreeLog (lip);
12241 }
12242 
12243 
ApplyBarcodeKeywordCallback(BioseqPtr bsp,Pointer data)12244 static void ApplyBarcodeKeywordCallback (BioseqPtr bsp, Pointer data)
12245 {
12246   LogInfoPtr lip;
12247   Char id_str[255];
12248 
12249   if (bsp == NULL || ISA_aa (bsp->mol)) {
12250     return;
12251   }
12252 
12253   if (HasBARCODETech(bsp)) {
12254     ApplyBarcodeKeywordToBioseq (bsp);
12255   } else if ((lip = (LogInfoPtr) data) != NULL && lip->fp != NULL) {
12256     SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_FASTA_SHORT, sizeof (id_str) - 1);
12257     fprintf (lip->fp, "%s does not have BARCODE tech, BARCODE keyword not added\n", id_str);
12258     lip->data_in_log = TRUE;
12259   }
12260 }
12261 
12262 
AddBarcodeKeywordBtn(ButtoN b)12263 static void AddBarcodeKeywordBtn (ButtoN b)
12264 {
12265   BarcodeToolPtr vstp;
12266   LogInfoPtr     lip;
12267   SeqEntryPtr    sep;
12268 
12269   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12270   if (vstp == NULL) return;
12271 
12272   sep = GetTopSeqEntryForEntityID (vstp->input_entityID);
12273   lip = OpenLog ("BARCODE Keywords Not Added");
12274   VisitBioseqsInSep (sep, lip, ApplyBarcodeKeywordCallback);
12275 
12276   RefreshBarcodeList (vstp);
12277   RedrawBarcodeTool (vstp);
12278 
12279   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
12280   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
12281   Update();
12282 
12283   CloseLog (lip);
12284   lip = FreeLog (lip);
12285 }
12286 
12287 
12288 
BarcodeRefreshButton(ButtoN b)12289 extern void BarcodeRefreshButton (ButtoN b)
12290 {
12291   BarcodeToolPtr vstp;
12292 
12293   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12294   if (vstp == NULL) return;
12295 
12296   WatchCursor();
12297   Update();
12298   if (vstp->refresh_func != NULL)
12299   {
12300     (vstp->refresh_func) (vstp);
12301   }
12302   RedrawBarcodeTool (vstp);
12303   ArrowCursor();
12304   Update();
12305 }
12306 
12307 
BarcodeReportButton(ButtoN b)12308 extern void BarcodeReportButton (ButtoN b)
12309 {
12310   BarcodeToolPtr vstp;
12311   LogInfoPtr     lip;
12312   ValNodePtr     object_list;
12313 
12314   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12315   if (vstp == NULL) return;
12316 
12317   object_list = (ValNodePtr) DialogToPointer (vstp->clickable_list);
12318   if (object_list == NULL)
12319   {
12320     if (ANS_YES == Message (MSG_YN, "You have not selected any Bioseqs - include all Bioseqs in report?"))
12321     {
12322       object_list = vstp->item_list;
12323     }
12324     else
12325     {
12326       return;
12327     }
12328   }
12329 
12330   lip = OpenLog ("BARCODE Discrepancies");
12331   WriteBarcodeFailureReport (lip->fp, object_list);
12332   lip->data_in_log = TRUE;
12333   CloseLog (lip);
12334   lip = FreeLog (lip);
12335   if (object_list != vstp->item_list)
12336   {
12337     object_list = ValNodeFree (object_list);
12338   }
12339 }
12340 
BarcodeTestComplianceReport(ButtoN b)12341 extern void BarcodeTestComplianceReport (ButtoN b)
12342 {
12343   BarcodeToolPtr vstp;
12344   ValNodePtr     object_list;
12345   LogInfoPtr     lip;
12346   Boolean        free_config = FALSE;
12347 
12348   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12349   if (vstp == NULL) return;
12350 
12351   if (vstp->cfg == NULL) {
12352     vstp->cfg = BarcodeTestConfigNew ();
12353     free_config = TRUE;
12354   }
12355   vstp->cfg->conf_list[eBarcodeTest_OrderAssignment] = FALSE;
12356   object_list = GetBarcodePassFail (vstp->top_sep, vstp->cfg);
12357   vstp->cfg->conf_list[eBarcodeTest_OrderAssignment] = TRUE;
12358   if (free_config) {
12359     vstp->cfg = BarcodeTestConfigFree (vstp->cfg);
12360   }
12361   lip = OpenLog ("BARCODE Compliance");
12362   WriteBarcodeTestCompliance (lip->fp, object_list);
12363   lip->data_in_log = TRUE;
12364   CloseLog (lip);
12365   lip = FreeLog (lip);
12366   object_list = BarcodeTestResultsListFree (object_list);
12367 }
12368 
12369 
BarcodeTestIbolComplianceReport(ButtoN b)12370 extern void BarcodeTestIbolComplianceReport (ButtoN b)
12371 {
12372   BarcodeToolPtr vstp;
12373   ValNodePtr     object_list;
12374   LogInfoPtr     lip;
12375 
12376   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12377   if (vstp == NULL) return;
12378 
12379   object_list = GetBarcodePassFail (vstp->top_sep, vstp->cfg);
12380   lip = OpenLog ("BARCODE Compliance");
12381   WriteBarcodeTestComplianceEx (lip->fp, object_list, TRUE);
12382   lip->data_in_log = TRUE;
12383   CloseLog (lip);
12384   lip = FreeLog (lip);
12385   object_list = BarcodeTestResultsListFree (object_list);
12386 }
12387 
12388 
BarcodeTestMissingPrimerAndCountryReport(ButtoN b)12389 static void BarcodeTestMissingPrimerAndCountryReport (ButtoN b)
12390 {
12391   BarcodeToolPtr vstp;
12392   ValNodePtr     object_list, vnp;
12393   BarcodeTestResultsPtr res;
12394   CharPtr               barcode_id, genbank_id, what;
12395   LogInfoPtr     lip;
12396 
12397   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12398   if (vstp == NULL) return;
12399 
12400   object_list = GetBarcodePassFail (vstp->top_sep, vstp->cfg);
12401   lip = OpenLog ("BARCODE Compliance");
12402   for (vnp = object_list; vnp != NULL; vnp = vnp->next)
12403   {
12404     res = (BarcodeTestResultsPtr) vnp->data.ptrvalue;
12405     barcode_id = BarcodeTestBarcodeIdString (res->bsp);
12406     genbank_id = BarcodeTestGenbankIdString (res->bsp);
12407     if (res->failed_tests[eBarcodeTest_Primers]) {
12408       if (res->failed_tests[eBarcodeTest_Country]) {
12409         what = "primers and country";
12410       } else {
12411         what = "primers";
12412       }
12413     } else if (res->failed_tests[eBarcodeTest_Country]) {
12414       what = "country";
12415     } else {
12416       what = NULL;
12417     }
12418 
12419     if (what != NULL) {
12420       fprintf (lip->fp, "%s\t%s\t Missing %s\n", barcode_id, genbank_id, what);
12421       lip->data_in_log = TRUE;
12422     }
12423 
12424     barcode_id = MemFree (barcode_id);
12425     genbank_id = MemFree (genbank_id);
12426   }
12427 
12428   if (!lip->data_in_log) {
12429     Message (MSG_OK, "No sequences are missing primers or country");
12430   }
12431   CloseLog (lip);
12432   lip = FreeLog (lip);
12433   object_list = BarcodeTestResultsListFree (object_list);
12434 }
12435 
12436 
BarcodeTestStructuredVoucherReport(ButtoN b)12437 static void BarcodeTestStructuredVoucherReport (ButtoN b)
12438 {
12439   BarcodeToolPtr vstp;
12440   ValNodePtr     object_list, vnp;
12441   BarcodeTestResultsPtr res;
12442   CharPtr               barcode_id, genbank_id, what;
12443   LogInfoPtr     lip;
12444 
12445   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12446   if (vstp == NULL) return;
12447 
12448   object_list = GetBarcodePassFail (vstp->top_sep, vstp->cfg);
12449   lip = OpenLog ("BARCODE Compliance");
12450   for (vnp = object_list; vnp != NULL; vnp = vnp->next)
12451   {
12452     res = (BarcodeTestResultsPtr) vnp->data.ptrvalue;
12453     barcode_id = BarcodeTestBarcodeIdString (res->bsp);
12454     genbank_id = BarcodeTestGenbankIdString (res->bsp);
12455     if (res->failed_tests[eBarcodeTest_StructuredSpecimenVoucher]) {
12456       what = "structured voucher";
12457     } else {
12458       what = NULL;
12459     }
12460 
12461     if (what != NULL) {
12462       fprintf (lip->fp, "%s\t%s\t Missing %s\n", barcode_id, genbank_id, what);
12463       lip->data_in_log = TRUE;
12464     }
12465 
12466     barcode_id = MemFree (barcode_id);
12467     genbank_id = MemFree (genbank_id);
12468   }
12469 
12470   if (!lip->data_in_log) {
12471     Message (MSG_OK, "No sequences have unstructured vouchers");
12472   }
12473   CloseLog (lip);
12474   lip = FreeLog (lip);
12475   object_list = BarcodeTestResultsListFree (object_list);
12476 }
12477 
12478 
12479 extern DialoG BarcodeTestResultsDisplay (GrouP h, BarcodeTestConfigPtr cfg);
12480 
BarcodeTestMakeTagTable(ButtoN b)12481 static void BarcodeTestMakeTagTable (ButtoN b)
12482 {
12483   BarcodeToolPtr vstp;
12484   ValNodePtr     object_list;
12485   LogInfoPtr     lip;
12486   WindoW         w;
12487   GrouP          h, g1, c;
12488   ButtoN         b2;
12489   TexT                  acc_list_txt;
12490   ModalAcceptCancelData acd;
12491   CharPtr               acc_list;
12492   ValNodePtr            id_list = NULL, vnp;
12493   CharPtr               genbank_id, barcode_id;
12494   Char                  id_str[128];
12495   BioseqPtr             bsp;
12496 
12497   vstp = (BarcodeToolPtr) GetObjectExtra (b);
12498   if (vstp == NULL) return;
12499 
12500   w = MovableModalWindow (-20, -13, -10, -10, "Create BARCODE Tag Table", NULL);
12501   h = HiddenGroup(w, -1, 0, NULL);
12502   SetGroupSpacing (h, 10, 10);
12503 
12504   g1 = NormalGroup (h, 3, 0, "Accessions", programFont, NULL);
12505   StaticPrompt (g1, "List Accessions", 0, dialogTextHeight, programFont, 'l');
12506   acc_list_txt = DialogText (g1, "", 30, NULL);
12507   StaticPrompt (g1, "(Leave blank to use all)", 0, dialogTextHeight, programFont, 'l');
12508 
12509   c = HiddenGroup (h, 2, 0, NULL);
12510   b2 = PushButton (c, "Accept", ModalAcceptButton);
12511   SetObjectExtra (b2, &acd, NULL);
12512   b2 = PushButton (c, "Cancel", ModalCancelButton);
12513   SetObjectExtra (b2, &acd, NULL);
12514 
12515   AlignObjects (ALIGN_CENTER, (HANDLE) g1,
12516                               (HANDLE) c, (HANDLE) NULL);
12517 
12518   Show (w);
12519   Select (w);
12520 
12521   acd.accepted = FALSE;
12522   acd.cancelled = FALSE;
12523   while (!acd.accepted && ! acd.cancelled)
12524   {
12525     ProcessExternalEvent ();
12526     Update ();
12527   }
12528   ProcessAnEvent ();
12529 
12530   if (!acd.cancelled)
12531   {
12532     lip = OpenLog ("BARCODE Tag Table");
12533     acc_list = SaveStringFromText (acc_list_txt);
12534     if (StringHasNoText (acc_list))
12535     {
12536       object_list = GetBarcodePassFail (vstp->top_sep, vstp->cfg);
12537       WriteBarcodeTagTable (lip->fp, object_list);
12538       object_list = BarcodeTestResultsListFree (object_list);
12539     }
12540     else
12541     {
12542       id_list = ParseAccessionNumberListFromString (acc_list, vstp->top_sep);
12543       for (vnp = id_list; vnp != NULL; vnp = vnp->next)
12544       {
12545         bsp = BioseqFind (vnp->data.ptrvalue);
12546         if (bsp == NULL)
12547         {
12548           SeqIdWrite (vnp->data.ptrvalue, id_str, PRINTID_REPORT, sizeof (id_str));
12549           fprintf (lip->fp, "%s\tNOT IN RECORD\t\n", id_str);
12550         }
12551         else
12552         {
12553           barcode_id = BarcodeTestBarcodeIdString (bsp);
12554           genbank_id = BarcodeTestGenbankIdString (bsp);
12555           fprintf (lip->fp, "%s\t%s\t\n", genbank_id, barcode_id);
12556           barcode_id = MemFree (barcode_id);
12557           genbank_id = MemFree (genbank_id);
12558         }
12559       }
12560       id_list = FreeSeqIdList (id_list);
12561     }
12562     acc_list = MemFree (acc_list);
12563 
12564     lip->data_in_log = TRUE;
12565     CloseLog (lip);
12566     lip = FreeLog (lip);
12567   }
12568   Remove (w);
12569 }
12570 
12571 
12572 typedef struct tagtable {
12573   BioseqPtr bsp;
12574   CharPtr   accession;
12575   CharPtr   old_tag;
12576   CharPtr   new_tag;
12577 } TagTableData, PNTR TagTablePtr;
12578 
TagTableFree(TagTablePtr ttp)12579 static TagTablePtr TagTableFree (TagTablePtr ttp)
12580 {
12581   if (ttp != NULL)
12582   {
12583     ttp->accession = MemFree (ttp->accession);
12584     ttp->old_tag = MemFree (ttp->old_tag);
12585     ttp->new_tag = MemFree (ttp->new_tag);
12586     ttp = MemFree (ttp);
12587   }
12588   return ttp;
12589 }
12590 
TagTableListFree(ValNodePtr vnp)12591 static ValNodePtr TagTableListFree (ValNodePtr vnp)
12592 {
12593   ValNodePtr vnp_next;
12594 
12595   while (vnp != NULL)
12596   {
12597     vnp_next = vnp->next;
12598     vnp->next = NULL;
12599     vnp->data.ptrvalue = TagTableFree (vnp->data.ptrvalue);
12600     vnp = ValNodeFree (vnp);
12601     vnp = vnp_next;
12602   }
12603   return vnp;
12604 }
12605 
12606 
SkipPastGnlUoguelph(CharPtr token)12607 static CharPtr SkipPastGnlUoguelph (CharPtr token)
12608 {
12609   Int4        uoguelph_len = StringLen ("uoguelph|");
12610 
12611   if (token == NULL) return NULL;
12612 
12613   if (StringNICmp (token, "gnl|", 4) == 0)
12614   {
12615     token += 4;
12616   }
12617   if (StringNICmp (token, "uoguelph|", uoguelph_len) == 0)
12618   {
12619     token += uoguelph_len;
12620   }
12621   return token;
12622 }
12623 
12624 
ReadReplaceTagTableLine(CharPtr line,SeqEntryPtr sep,LogInfoPtr lip)12625 static TagTablePtr ReadReplaceTagTableLine (CharPtr line, SeqEntryPtr sep, LogInfoPtr lip)
12626 {
12627   CharPtr  token, cp, delimiters = " \t,;";
12628   Int4     len;
12629   Char     ch;
12630   SeqIdPtr  sip;
12631   BioseqPtr bsp = NULL;
12632   CharPtr   accession = NULL, old_tag = NULL, new_tag = NULL;
12633   TagTablePtr ttp = NULL;
12634   Boolean     error = FALSE;
12635   Char        id_num[20];
12636   DbtagPtr    dbt;
12637 
12638   if (StringHasNoText (line) || lip == NULL || lip->fp == NULL) return NULL;
12639 
12640   token = line;
12641   while (*token != 0 && !error)
12642   {
12643     len = StringCSpn (token, delimiters);
12644     if (len == 0)
12645     {
12646       token += StringSpn (token, delimiters);
12647     }
12648     else
12649     {
12650       cp = token + len;
12651       ch = *cp;
12652       *cp = 0;
12653       if (bsp == NULL)
12654       {
12655         accession = StringSave (token);
12656         sip = CreateSeqIdFromText (token, sep);
12657         bsp = BioseqFind (sip);
12658         sip = SeqIdFree (sip);
12659         if (bsp == NULL)
12660         {
12661           fprintf (lip->fp, "No Bioseq found for %s\n", token);
12662           lip->data_in_log = TRUE;
12663           error = TRUE;
12664         }
12665       }
12666       else if (old_tag == NULL)
12667       {
12668         /* check for old tag matching what is found on sequence */
12669         sip = bsp->id;
12670         while (sip != NULL && !IsBarcodeID(sip))
12671         {
12672           sip = sip->next;
12673         }
12674         if (sip == NULL || (dbt = (DbtagPtr) sip->data.ptrvalue) == NULL || dbt->tag == NULL)
12675         {
12676           fprintf (lip->fp, "No BARCODE ID for %s\n", accession);
12677           error = TRUE;
12678         }
12679         else
12680         {
12681           token = SkipPastGnlUoguelph(token);
12682           if (dbt->tag->id > 0)
12683           {
12684             sprintf (id_num, "%d", dbt->tag->id);
12685             if (StringCmp (token, id_num) != 0)
12686             {
12687               fprintf (lip->fp, "Old Tag is incorrect for %s\n", accession);
12688               lip->data_in_log = TRUE;
12689               error = TRUE;
12690             }
12691           }
12692           else if (StringCmp (token, dbt->tag->str) != 0)
12693           {
12694             fprintf (lip->fp, "Old Tag is incorrect for %s\n", accession);
12695             lip->data_in_log = TRUE;
12696             error = TRUE;
12697           }
12698           if (!error)
12699           {
12700             old_tag = StringSave (token);
12701           }
12702         }
12703       }
12704       else if (new_tag == NULL)
12705       {
12706         token = SkipPastGnlUoguelph (token);
12707         new_tag = StringSave (token);
12708       }
12709       else
12710       {
12711         fprintf (lip->fp, "Warning!  Too many columns in table!\n");
12712         lip->data_in_log = TRUE;
12713       }
12714       *cp = ch;
12715       token = cp;
12716     }
12717   }
12718 
12719   if (!error)
12720   {
12721     if (old_tag == NULL)
12722     {
12723       fprintf (lip->fp, "No old tag for %s!\n", accession);
12724       lip->data_in_log = TRUE;
12725     }
12726     else if (new_tag == NULL)
12727     {
12728       fprintf (lip->fp, "No new tag for %s\n", accession);
12729       lip->data_in_log = TRUE;
12730     }
12731     else
12732     {
12733       ttp = (TagTablePtr) MemNew (sizeof (TagTableData));
12734       ttp->bsp = bsp;
12735       ttp->accession = accession;
12736       accession = NULL;
12737       ttp->old_tag = old_tag;
12738       old_tag = NULL;
12739       ttp->new_tag = new_tag;
12740       new_tag = NULL;
12741     }
12742   }
12743   accession = MemFree (accession);
12744   old_tag = MemFree (old_tag);
12745   new_tag = MemFree (new_tag);
12746   return ttp;
12747 }
12748 
12749 
ReadNewTagTableLine(CharPtr line,SeqEntryPtr sep,LogInfoPtr lip)12750 static TagTablePtr ReadNewTagTableLine (CharPtr line, SeqEntryPtr sep, LogInfoPtr lip)
12751 {
12752   CharPtr  token, cp, delimiters = " \t,;";
12753   Int4     len;
12754   Char     ch;
12755   SeqIdPtr  sip;
12756   BioseqPtr bsp = NULL;
12757   CharPtr   accession = NULL, new_tag = NULL;
12758   TagTablePtr ttp = NULL;
12759   Boolean     error = FALSE;
12760 
12761   if (StringHasNoText (line) || lip == NULL || lip->fp == NULL) return NULL;
12762 
12763   token = line;
12764   while (*token != 0 && !error)
12765   {
12766     len = StringCSpn (token, delimiters);
12767     if (len == 0)
12768     {
12769       token += StringSpn (token, delimiters);
12770     }
12771     else
12772     {
12773       cp = token + len;
12774       ch = *cp;
12775       *cp = 0;
12776       if (bsp == NULL)
12777       {
12778         accession = StringSave (token);
12779         sip = CreateSeqIdFromText (token, sep);
12780         bsp = BioseqFind (sip);
12781         sip = SeqIdFree (sip);
12782         if (bsp == NULL)
12783         {
12784           fprintf (lip->fp, "No Bioseq found for %s\n", token);
12785           lip->data_in_log = TRUE;
12786           error = TRUE;
12787         }
12788         else
12789         {
12790           /* check for old tag - there shouldn't be one */
12791           sip = bsp->id;
12792           while (sip != NULL && !IsBarcodeID(sip))
12793           {
12794             sip = sip->next;
12795           }
12796           if (sip != NULL)
12797           {
12798             fprintf (lip->fp, "%s already has BARCODE ID\n", accession);
12799             error = TRUE;
12800           }
12801         }
12802       }
12803       else if (new_tag == NULL)
12804       {
12805         token = SkipPastGnlUoguelph (token);
12806         new_tag = StringSave (token);
12807       }
12808       else
12809       {
12810         fprintf (lip->fp, "Warning!  Too many columns in table!\n");
12811         lip->data_in_log = TRUE;
12812       }
12813       *cp = ch;
12814       token = cp;
12815     }
12816   }
12817 
12818   if (!error)
12819   {
12820     if (new_tag == NULL)
12821     {
12822       fprintf (lip->fp, "No new tag for %s\n", accession);
12823       lip->data_in_log = TRUE;
12824     }
12825     else
12826     {
12827       ttp = (TagTablePtr) MemNew (sizeof (TagTableData));
12828       ttp->bsp = bsp;
12829       ttp->accession = accession;
12830       accession = NULL;
12831       ttp->old_tag = NULL;
12832       ttp->new_tag = new_tag;
12833       new_tag = NULL;
12834     }
12835   }
12836   accession = MemFree (accession);
12837   new_tag = MemFree (new_tag);
12838   return ttp;
12839 }
12840 
12841 
ReadTagTable(SeqEntryPtr sep,LogInfoPtr lip,Boolean replace)12842 static ValNodePtr ReadTagTable (SeqEntryPtr sep, LogInfoPtr lip, Boolean replace)
12843 {
12844   Char           path [PATH_MAX];
12845   ValNodePtr     line_list = NULL;
12846   ReadBufferData rbd;
12847   CharPtr        line;
12848   TagTablePtr    ttp;
12849 
12850   path [0] = '\0';
12851   if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return NULL;
12852 
12853   rbd.fp = FileOpen (path, "r");
12854   if (rbd.fp == NULL) return NULL;
12855   rbd.current_data = NULL;
12856 
12857   line = AbstractReadFunction (&rbd);
12858   while (line != NULL)
12859   {
12860     if (replace)
12861     {
12862       ttp = ReadReplaceTagTableLine (line, sep, lip);
12863     }
12864     else
12865     {
12866       ttp = ReadNewTagTableLine (line, sep, lip);
12867     }
12868     if (ttp != NULL)
12869     {
12870       ValNodeAddPointer (&line_list, 0, ttp);
12871     }
12872     line = MemFree (line);
12873     line = AbstractReadFunction (&rbd);
12874   }
12875 
12876   FileClose (rbd.fp);
12877   return line_list;
12878 }
12879 
12880 
ApplyTagTable(BarcodeToolPtr vstp,Boolean replace)12881 static void ApplyTagTable (BarcodeToolPtr vstp, Boolean replace)
12882 {
12883   TagTablePtr   ttp;
12884   ValNodePtr    tag_list, vnp;
12885   LogInfoPtr     lip;
12886   Boolean        errors;
12887   SeqIdPtr       sip;
12888   DbtagPtr       dbt;
12889 
12890   if (vstp == NULL) return;
12891 
12892   lip = OpenLog ("Tag Table Errors");
12893 
12894   tag_list = ReadTagTable (vstp->top_sep, lip, replace);
12895   errors = lip->data_in_log;
12896   CloseLog (lip);
12897   lip = FreeLog (lip);
12898 
12899   if (errors)
12900   {
12901     if (ANS_NO == Message (MSG_YN, "Errors in table.  Continue with matched rows only?"))
12902     {
12903       tag_list = TagTableListFree (tag_list);
12904       return;
12905     }
12906   }
12907 
12908   /* NOW DO SOMETHING USEFUL */
12909   for (vnp = tag_list; vnp != NULL; vnp = vnp->next)
12910   {
12911     ttp = (TagTablePtr) vnp->data.ptrvalue;
12912     if (replace)
12913     {
12914       sip = ttp->bsp->id;
12915       while (sip != NULL && !IsBarcodeID(sip))
12916       {
12917         sip = sip->next;
12918       }
12919     }
12920     else
12921     {
12922       sip = ValNodeNew (ttp->bsp->id);
12923       if (ttp->bsp->id == NULL)
12924       {
12925         ttp->bsp->id = sip;
12926       }
12927       sip->choice = SEQID_GENERAL;
12928       dbt = DbtagNew ();
12929       sip->data.ptrvalue = dbt;
12930       dbt->db = StringSave ("uoguelph");
12931       dbt->tag = ObjectIdNew ();
12932     }
12933     if (sip != NULL)
12934     {
12935       dbt = (DbtagPtr) sip->data.ptrvalue;
12936       dbt->tag->str = MemFree (dbt->tag->str);
12937       dbt->tag->id = 0;
12938       dbt->tag->str = StringSave (ttp->new_tag);
12939       SeqMgrReplaceInBioseqIndex (ttp->bsp);
12940     }
12941   }
12942 
12943   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
12944   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
12945 
12946   tag_list = TagTableListFree (tag_list);
12947 
12948   RefreshBarcodeList(vstp);
12949 }
12950 
12951 
BarcodeTestImportTagTable(ButtoN b)12952 static void BarcodeTestImportTagTable (ButtoN b)
12953 {
12954   ApplyTagTable (GetObjectExtra (b), TRUE);
12955 }
12956 
12957 
BarcodeTestApplyTagTable(ButtoN b)12958 static void BarcodeTestApplyTagTable (ButtoN b)
12959 {
12960   ApplyTagTable (GetObjectExtra (b), FALSE);
12961 }
12962 
12963 
BarcodeComprehensiveReportButton(ButtoN b)12964 static void BarcodeComprehensiveReportButton (ButtoN b)
12965 {
12966   BarcodeToolPtr         drfp;
12967   LogInfoPtr             lip;
12968   ValNodePtr             object_list;
12969   Boolean                free_config = FALSE;
12970 
12971   drfp = (BarcodeToolPtr) GetObjectExtra (b);
12972   if (drfp == NULL) return;
12973 
12974   lip = OpenLog ("BARCODE Discrepancies");
12975   if (drfp->cfg == NULL) {
12976     drfp->cfg = BarcodeTestConfigNew ();
12977     free_config = TRUE;
12978   }
12979   drfp->cfg->conf_list[eBarcodeTest_OrderAssignment] = FALSE;
12980   object_list = GetBarcodePassFail (drfp->top_sep, drfp->cfg);
12981   drfp->cfg->conf_list[eBarcodeTest_OrderAssignment] = TRUE;
12982   if (free_config) {
12983     drfp->cfg = BarcodeTestConfigFree (drfp->cfg);
12984   }
12985   WriteBarcodeTestComprehensive (lip->fp, object_list);
12986   lip->data_in_log = TRUE;
12987   CloseLog (lip);
12988   lip = FreeLog (lip);
12989   object_list = BarcodeTestResultsListFree (object_list);
12990 }
12991 
12992 
ReportPolymorphismCallback(BioseqPtr bsp,Pointer data)12993 static void ReportPolymorphismCallback (BioseqPtr bsp, Pointer data)
12994 {
12995   Int4 num_p;
12996   LogInfoPtr lip;
12997   Char       id_txt[100];
12998 
12999   if (bsp == NULL || data == NULL || !HasBARCODETech(bsp)) {
13000     return;
13001   }
13002 
13003   lip = (LogInfoPtr) data;
13004   num_p = CountPolymorphismsInBioseq (bsp);
13005   if (num_p > 0) {
13006     SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
13007     fprintf (lip->fp, "%s: %d polymophisms\n", id_txt, num_p);
13008     lip->data_in_log = TRUE;
13009   }
13010 
13011 }
13012 
13013 
BarcodeReportPolymorphism(ButtoN b)13014 static void BarcodeReportPolymorphism (ButtoN b)
13015 {
13016   BarcodeToolPtr         drfp;
13017   LogInfoPtr             lip;
13018 
13019   drfp = (BarcodeToolPtr) GetObjectExtra (b);
13020   if (drfp == NULL) return;
13021 
13022   lip = OpenLog ("Barcode Sequence Polymorphism");
13023   VisitBioseqsInSep (GetTopSeqEntryForEntityID (drfp->input_entityID), lip, ReportPolymorphismCallback);
13024   CloseLog (lip);
13025   if (!lip->data_in_log) {
13026     Message (MSG_OK, "No polymorphism found");
13027   }
13028   lip = FreeLog (lip);
13029 }
13030 
13031 
ApplyBarcodeDbxrefsBtn(ButtoN b)13032 static void ApplyBarcodeDbxrefsBtn (ButtoN b)
13033 {
13034   BarcodeToolPtr         drfp;
13035 
13036   drfp = (BarcodeToolPtr) GetObjectExtra (b);
13037   if (drfp == NULL) return;
13038 
13039   VisitBioseqsInSep (GetTopSeqEntryForEntityID (drfp->input_entityID), NULL, ApplyBarcodeDbxrefsToBioseq);
13040 
13041   ObjMgrSetDirtyFlag (drfp->input_entityID, TRUE);
13042   ObjMgrSendMsg (OM_MSG_UPDATE, drfp->input_entityID, 0, 0);
13043   Update();
13044 }
13045 
13046 
13047 typedef struct stripreport {
13048   CharPtr id;
13049   CharPtr reasons;
13050 } StripReportData, PNTR StripReportPtr;
13051 
StripReportNew(CharPtr id,CharPtr reasons)13052 static StripReportPtr StripReportNew (CharPtr id, CharPtr reasons)
13053 {
13054   StripReportPtr s = (StripReportPtr) MemNew (sizeof (StripReportData));
13055   s->id = StringSave (id);
13056   s->reasons = StringSave (reasons);
13057   return s;
13058 }
13059 
13060 
StripReportFree(StripReportPtr s)13061 static StripReportPtr StripReportFree (StripReportPtr s)
13062 {
13063   if (s != NULL) {
13064     s->id = MemFree (s->id);
13065     s->reasons = MemFree (s->reasons);
13066     s = MemFree (s);
13067   }
13068   return s;
13069 }
13070 
13071 
StripReportCopy(StripReportPtr s)13072 static StripReportPtr StripReportCopy (StripReportPtr s)
13073 {
13074   StripReportPtr cpy = NULL;
13075 
13076   if (s != NULL) {
13077     cpy = StripReportNew (s->id, s->reasons);
13078   }
13079   return cpy;
13080 }
13081 
13082 
CombineStripReports(StripReportPtr s1,StripReportPtr s2)13083 static StripReportPtr CombineStripReports (StripReportPtr s1, StripReportPtr s2)
13084 {
13085   StripReportPtr sum = NULL;
13086   CharPtr        tmp;
13087 
13088   if (s1 == NULL || StringHasNoText (s1->reasons)) {
13089     sum = StripReportCopy (s2);
13090   } else if (s2 == NULL || StringHasNoText (s2->reasons)) {
13091     sum = StripReportCopy (s1);
13092   } else if (StringCmp (s1->reasons, s2->reasons) == 0) {
13093     sum = StripReportCopy (s1);
13094   } else {
13095     sum = StripReportNew (s1->id, NULL);
13096     tmp = (CharPtr) MemNew (sizeof (Char) * (StringLen (s1->reasons) + StringLen (s2->reasons) + 3));
13097     if (StringICmp (s1->reasons, "frameshift") == 0) {
13098       sprintf (tmp, "%s, %s", s2->reasons, s1->reasons);
13099     } else {
13100       sprintf (tmp, "%s, %s", s1->reasons, s2->reasons);
13101     }
13102     sum->reasons = tmp;
13103   }
13104   return sum;
13105 }
13106 
13107 
SortVnpByStripReport(VoidPtr ptr1,VoidPtr ptr2)13108 static int LIBCALLBACK SortVnpByStripReport(VoidPtr ptr1, VoidPtr ptr2)
13109 
13110 {
13111   StripReportPtr str1;
13112   StripReportPtr str2;
13113   ValNodePtr     vnp1;
13114   ValNodePtr     vnp2;
13115   int            rval = 0;
13116 
13117   if (ptr1 != NULL && ptr2 != NULL) {
13118     vnp1 = *((ValNodePtr PNTR) ptr1);
13119     vnp2 = *((ValNodePtr PNTR) ptr2);
13120     if (vnp1 != NULL && vnp2 != NULL) {
13121       str1 = (StripReportPtr) vnp1->data.ptrvalue;
13122       str2 = (StripReportPtr) vnp2->data.ptrvalue;
13123       if (str1 != NULL && str2 != NULL) {
13124         rval = StringICmp (str1->id, str2->id);
13125         if (rval == 0) {
13126           if (str1->reasons == NULL) {
13127             if (str2->reasons == NULL) {
13128               rval = 0;
13129             } else {
13130               rval = -1;
13131             }
13132           } else if (str2->reasons == NULL) {
13133             rval = 1;
13134           } else {
13135             rval = StringICmp (str1->reasons, str2->reasons);
13136           }
13137         }
13138       }
13139     }
13140   }
13141   return rval;
13142 }
13143 
13144 
13145 typedef struct stripreportcollect {
13146   ValNodePtr strip_report_list;
13147   BarcodeTestConfigPtr cfg;
13148 } StripReportCollectData, PNTR StripReportCollectPtr;
13149 
13150 
ProcessOneFrameFindFile(CharPtr filename,Pointer userdata)13151 static void ProcessOneFrameFindFile (CharPtr filename, Pointer userdata)
13152 
13153 {
13154   ReadBufferData rbd;
13155   CharPtr line, id, comma;
13156   StripReportCollectPtr  s;
13157 
13158   if (StringHasNoText (filename) || (s = (StripReportCollectPtr) userdata) == NULL) {
13159     return;
13160   }
13161 
13162   rbd.fp = FileOpen (filename, "r");
13163   if (rbd.fp == NULL) {
13164     Message (MSG_POSTERR, "Failed to open '%s'", filename);
13165     return;
13166   }
13167 
13168   rbd.current_data = NULL;
13169 
13170   line = AbstractReadFunction (&rbd);
13171   while (line != NULL)
13172   {
13173     if (StringNCmp (line, "Gap: ", 5) == 0) {
13174       line = MemFree (line);
13175       line = AbstractReadFunction (&rbd);
13176       id = line;
13177       comma = StringChr(id, ',');
13178       while (comma != NULL) {
13179         *comma = 0;
13180         ValNodeAddPointer (&(s->strip_report_list), 0, StripReportNew(id, "frameshift"));
13181         id = comma + 1;
13182         comma = StringChr(id, ',');
13183       }
13184       if (*id != 0) {
13185         ValNodeAddPointer (&(s->strip_report_list), 0, StripReportNew(id, "frameshift"));
13186       }
13187     }
13188     line = MemFree (line);
13189     line = AbstractReadFunction (&rbd);
13190   }
13191   FileClose (rbd.fp);
13192 }
13193 
13194 
CollapseStripReportList(ValNodePtr list)13195 static void CollapseStripReportList (ValNodePtr list)
13196 {
13197   ValNodePtr vnp, prev, vnp_next;
13198   StripReportPtr s1, s2, sum;
13199 
13200   if (list == NULL || list->next == NULL) {
13201     return;
13202   }
13203   prev = list;
13204   vnp = prev->next;
13205   while (vnp != NULL) {
13206     vnp_next = vnp->next;
13207     s1 = prev->data.ptrvalue;
13208     s2 = vnp->data.ptrvalue;
13209     if (StringICmp (s1->id, s2->id) == 0) {
13210       sum = CombineStripReports (s1, s2);
13211       s1 = StripReportFree (s1);
13212       s2 = StripReportFree (s2);
13213       prev->data.ptrvalue = sum;
13214       prev->next = vnp->next;
13215       vnp->next = NULL;
13216       vnp = ValNodeFree (vnp);
13217     } else {
13218       prev = vnp;
13219     }
13220     vnp = vnp_next;
13221   }
13222 }
13223 
13224 
MakeBarcodeStripReport(ButtoN b)13225 static void MakeBarcodeStripReport (ButtoN b)
13226 {
13227   BarcodeToolPtr drfp;
13228   StripReportCollectData sd;
13229   ValNodePtr     list, vnp;
13230   SeqEntryPtr    sep;
13231   LogInfoPtr     lip;
13232   Char           path [PATH_MAX];
13233   CharPtr        cp;
13234   StripReportPtr sp;
13235   Boolean        require_keyword;
13236   BarcodeTestResultsPtr  res;
13237   CharPtr                reasons;
13238   Char                   id_buf[255];
13239 
13240   drfp = (BarcodeToolPtr) GetObjectExtra (b);
13241   if (drfp == NULL) return;
13242 
13243   sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
13244 
13245   MemSet (&sd, 0, sizeof (StripReportCollectData));
13246   sd.cfg = drfp->cfg;
13247   if (sd.cfg == NULL) {
13248     sd.cfg = BarcodeTestConfigNew();
13249   }
13250   require_keyword = sd.cfg->require_keyword;
13251   sd.cfg->require_keyword = FALSE;
13252   list = GetBarcodePassFail (sep, sd.cfg);
13253   sd.cfg->require_keyword = require_keyword;
13254   if (drfp->cfg == NULL) {
13255     sd.cfg = BarcodeTestConfigFree (sd.cfg);
13256   }
13257 
13258   for (vnp = list; vnp != NULL; vnp = vnp->next) {
13259     res = (BarcodeTestResultsPtr) vnp->data.ptrvalue;
13260     if (res != NULL && !BioseqHasBarcodeKeyword(res->bsp)) {
13261       reasons = GetBarcodeTestFailureReasons (res);
13262       SeqIdWrite (SeqIdFindBest (res->bsp->id, SEQID_GENBANK), id_buf, PRINTID_TEXTID_ACC_ONLY, sizeof (id_buf) - 1);
13263       ValNodeAddPointer (&(sd.strip_report_list), 0, StripReportNew(id_buf, reasons));
13264       reasons = MemFree (reasons);
13265     }
13266   }
13267   list = BarcodeTestResultsListFree(list);
13268 
13269   path [0] = '\0';
13270   if (GetInputFileName (path, sizeof (path), NULL, "TEXT")) {
13271     cp = StringRChr (path, '\\');
13272     if (cp == NULL) {
13273       cp = StringRChr (path, '/');
13274     }
13275     if (cp != NULL) {
13276       *cp = 0;
13277     }
13278     DirExplore (path, "", "", FALSE, ProcessOneFrameFindFile, (Pointer) &sd);
13279   }
13280 
13281   sd.strip_report_list = ValNodeSort (sd.strip_report_list, SortVnpByStripReport);
13282   CollapseStripReportList (sd.strip_report_list);
13283 
13284   lip = OpenLog ("Stripped Sequences");
13285 
13286   fprintf (lip->fp, "Total Sequences: %d\n\n", ValNodeLen (sd.strip_report_list));
13287   lip->data_in_log = TRUE;
13288   for (vnp = sd.strip_report_list; vnp != NULL; vnp = vnp->next) {
13289     if ((sp = (StripReportPtr)vnp->data.ptrvalue) != NULL) {
13290       fprintf (lip->fp, "%s: %s\n", sp->id, sp->reasons == NULL ? "Reason unknown" : sp->reasons);
13291       sp = StripReportFree (sp);
13292       vnp->data.ptrvalue = NULL;
13293     }
13294   }
13295   CloseLog(lip);
13296   lip = FreeLog (lip);
13297   sd.strip_report_list = ValNodeFree (sd.strip_report_list);
13298 }
13299 
13300 
BarcodeTestTool(IteM i)13301 extern void BarcodeTestTool (IteM i)
13302 {
13303   BaseFormPtr              bfp;
13304   BarcodeToolPtr         drfp;
13305   SeqEntryPtr              sep;
13306   GrouP                    h;
13307   GrouP                    c, c3, c4, c5;
13308   ButtoN                   b;
13309   WindoW                   w;
13310   OMUserDataPtr            omudp;
13311 
13312 #ifdef WIN_MAC
13313   bfp = currentFormDataPtr;
13314 #else
13315   bfp = GetObjectExtra (i);
13316 #endif
13317   if (bfp == NULL) return;
13318   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
13319   if (sep == NULL) return;
13320 
13321   drfp = (BarcodeToolPtr) MemNew (sizeof (BarcodeToolData));
13322   if (drfp == NULL)
13323   {
13324     return;
13325   }
13326 
13327   drfp->bfp = bfp;
13328   drfp->input_entityID = bfp->input_entityID;
13329   drfp->top_sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
13330   w = FixedWindow (-50, -33, -10, -10, "Barcode Test", StdCloseWindowProc);
13331   SetObjectExtra (w, drfp, CleanupBarcodeTool);
13332   drfp->form = (ForM) w;
13333   drfp->formmessage = BarcodeToolMessage;
13334   drfp->refresh_func = RefreshBarcodeList;
13335 
13336   /* register to receive update messages */
13337   drfp->userkey = OMGetNextUserKey ();
13338   drfp->procid = 0;
13339   drfp->proctype = OMPROC_EDIT;
13340   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
13341   if (omudp != NULL) {
13342     omudp->userdata.ptrvalue = (Pointer) drfp;
13343     omudp->messagefunc = BarcodeToolMsgFunc;
13344   }
13345 
13346 
13347 #ifndef WIN_MAC
13348   CreateStdValidatorFormMenus (w);
13349 #endif
13350 
13351   drfp->item_list = NULL;
13352   drfp->cfg = NULL;
13353   drfp->undo_list = BarcodeUndoListNew (BarcodeResultsVNCopyFunc, BarcodeResultsVNFreeFunc);
13354 
13355   h = HiddenGroup (w, -1, 0, NULL);
13356   SetGroupSpacing (h, 10, 10);
13357 
13358   drfp->clickable_list = BarcodeTestResultsDisplay (h, drfp->cfg);
13359 
13360   drfp->pass_fail_summary = StaticPrompt (h, "0 Pass, 0 Fail", 20 * stdCharWidth, dialogTextHeight, programFont, 'l');
13361   RefreshBarcodeList(drfp);
13362 
13363   c4 = HiddenGroup (h, 7, 0, NULL);
13364   SetGroupSpacing (c4, 10, 10);
13365 
13366   b = PushButton (c4, "Compliance Report", BarcodeTestIbolComplianceReport);
13367   SetObjectExtra (b, drfp, NULL);
13368   b = PushButton (c4, "Failure Report", BarcodeReportButton);
13369   SetObjectExtra (b, drfp, NULL);
13370   b = PushButton (c4, "Comprehensive Report", BarcodeComprehensiveReportButton);
13371   SetObjectExtra (b, drfp, NULL);
13372   b = PushButton (c4, "Report Polymorphism", BarcodeReportPolymorphism);
13373   SetObjectExtra (b, drfp, NULL);
13374   b = PushButton (c4, "Barcode Strip Report", MakeBarcodeStripReport);
13375   SetObjectExtra (b, drfp, NULL);
13376   b = PushButton (c4, "Missing Country and Primers Report", BarcodeTestMissingPrimerAndCountryReport);
13377   SetObjectExtra (b, drfp, NULL);
13378   b = PushButton (c4, "Structured Voucher Report", BarcodeTestStructuredVoucherReport);
13379   SetObjectExtra (b, drfp, NULL);
13380 
13381   c5 = HiddenGroup (h, 5, 0, NULL);
13382   SetGroupSpacing (c5, 10, 10);
13383   b = PushButton (c5, "Apply Dbxrefs", ApplyBarcodeDbxrefsBtn);
13384   SetObjectExtra (b, drfp, NULL);
13385   b = PushButton (c5, "Replace Tags", BarcodeTestImportTagTable);
13386   SetObjectExtra (b, drfp, NULL);
13387   b = PushButton (c5, "Add New Tags", BarcodeTestApplyTagTable);
13388   SetObjectExtra (b, drfp, NULL);
13389   b = PushButton (c5, "Make Tag Table", BarcodeTestMakeTagTable);
13390   SetObjectExtra (b, drfp, NULL);
13391   b = PushButton (c5, "Refresh List", BarcodeRefreshButton);
13392   SetObjectExtra (b, drfp, NULL);
13393 
13394   c3 = HiddenGroup (h, 4, 0, NULL);
13395   SetGroupSpacing (c3, 10, 10);
13396   b = PushButton (c3, "Remove BARCODE Keyword from Selected", RemoveSelectedKeywordsBtn);
13397   SetObjectExtra (b, drfp, NULL);
13398   b = PushButton (c3, "Add BARCODE Keyword to BARCODE Tech", AddBarcodeKeywordBtn);
13399   SetObjectExtra (b, drfp, NULL);
13400   b = PushButton (c3, "Remove BARCODE Tech from Selected", RemoveSelectedTechBtn);
13401   SetObjectExtra (b, drfp, NULL);
13402 #if 0
13403   b = PushButton (c3, "Remove BARCODE Keyword from Low Trace", RemoveBarcodeKeywordsFromLowTrace);
13404   SetObjectExtra (b, drfp, NULL);
13405 #endif
13406 
13407   c = HiddenGroup (h, 4, 0, NULL);
13408   SetGroupSpacing (c, 10, 10);
13409 
13410   drfp->undo = PushButton (c, "Undo", BarcodeUndoButton);
13411   SetObjectExtra (drfp->undo, drfp, NULL);
13412 
13413   drfp->undo_all = PushButton (c, "Undo All", BarcodeUndoAllButton);
13414   SetObjectExtra (drfp->undo_all, drfp, NULL);
13415 
13416   drfp->redo = PushButton (c, "Redo", BarcodeRedoButton);
13417   SetObjectExtra (drfp->redo, drfp, NULL);
13418   EnableUndoRedo (drfp);
13419 
13420   PushButton (c, "Dismiss", StdCancelButtonProc);
13421 
13422   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list,
13423                               (HANDLE) drfp->pass_fail_summary,
13424                               (HANDLE) c4,
13425                               (HANDLE) c5,
13426                               (HANDLE) c3,
13427                               (HANDLE) c,
13428                               NULL);
13429 
13430   RealizeWindow (w);
13431 
13432   Show (w);
13433 }
13434 
13435 
13436 typedef struct replaceid {
13437   SeqIdPtr orig_id;
13438   SeqIdPtr new_id;
13439 } ReplaceIdData, PNTR ReplaceIdPtr;
13440 
13441 /********************************************************************
13442 *
13443 * SeqLocReplaceID
13444 *   replaces the Seq-Id in a Seq-Loc (slp) with a new Seq-Id (new_sip)
13445 *
13446 **********************************************************************/
ReplaceSeqLocID(SeqLocPtr slp,SeqIdPtr orig_sip,SeqIdPtr new_sip)13447 static SeqLocPtr ReplaceSeqLocID (SeqLocPtr slp, SeqIdPtr orig_sip, SeqIdPtr new_sip)
13448 {
13449   SeqLocPtr        curr;
13450   PackSeqPntPtr    pspp;
13451   SeqIntPtr        target_sit;
13452   SeqBondPtr       sbp;
13453   SeqPntPtr        spp;
13454 
13455   if (slp == NULL || orig_sip == NULL || new_sip == NULL) return slp;
13456 
13457   switch (slp->choice) {
13458      case SEQLOC_PACKED_INT :
13459      case SEQLOC_MIX :
13460      case SEQLOC_EQUIV :
13461         curr = NULL;
13462         while ((curr = SeqLocFindNext (slp, curr)) != NULL) {
13463            curr = ReplaceSeqLocID (curr, orig_sip, new_sip);
13464         }
13465         break;
13466      case SEQLOC_PACKED_PNT :
13467         pspp = (PackSeqPntPtr) slp->data.ptrvalue;
13468         if (pspp != NULL) {
13469           if (SeqIdComp (orig_sip, pspp->id) == SIC_YES) {
13470             SeqIdFree (pspp->id);
13471             pspp->id = SeqIdDup (new_sip);
13472           }
13473         }
13474         break;
13475      case SEQLOC_EMPTY :
13476      case SEQLOC_WHOLE :
13477         if (SeqIdComp (orig_sip, slp->data.ptrvalue) == SIC_YES) {
13478           SeqIdFree ((SeqIdPtr) slp->data.ptrvalue);
13479           slp->data.ptrvalue = (Pointer) SeqIdDup (new_sip);
13480         }
13481         break;
13482      case SEQLOC_INT :
13483         target_sit = (SeqIntPtr) slp->data.ptrvalue;
13484         if (SeqIdComp (orig_sip, target_sit->id) == SIC_YES) {
13485           SeqIdFree (target_sit->id);
13486           target_sit->id = SeqIdDup (new_sip);
13487         }
13488         break;
13489      case SEQLOC_PNT :
13490         spp = (SeqPntPtr) slp->data.ptrvalue;
13491         if (SeqIdComp (orig_sip, spp->id) == SIC_YES) {
13492           SeqIdFree(spp->id);
13493           spp->id = SeqIdDup(new_sip);
13494         }
13495         break;
13496      case SEQLOC_BOND :
13497         sbp = (SeqBondPtr) slp->data.ptrvalue;
13498         if (sbp == NULL || sbp->a == NULL || sbp->b == NULL) break;
13499         if (SeqIdComp (orig_sip, sbp->a->id) == SIC_YES) {
13500           spp = sbp->a;
13501           SeqIdFree(spp->id);
13502           spp->id = SeqIdDup(new_sip);
13503         }
13504         if (SeqIdComp (orig_sip, sbp->b->id) == SIC_YES) {
13505           spp = sbp->b;
13506           SeqIdFree(spp->id);
13507           spp->id = SeqIdDup(new_sip);
13508         }
13509         break;
13510      default :
13511         break;
13512   }
13513   return slp;
13514 }
13515 
13516 
ReplaceCodingRegionLocationIds(CdRegionPtr crp,SeqIdPtr orig_sip,SeqIdPtr new_sip)13517 static void ReplaceCodingRegionLocationIds (CdRegionPtr crp, SeqIdPtr orig_sip, SeqIdPtr new_sip)
13518 {
13519   CodeBreakPtr cbp;
13520 
13521   if (crp == NULL) return;
13522   cbp = crp->code_break;
13523   while (cbp != NULL) {
13524     cbp->loc = ReplaceSeqLocID (cbp->loc, orig_sip, new_sip);
13525     cbp = cbp->next;
13526   }
13527 }
13528 
ReplaceRNALocationIds(RnaRefPtr rrp,SeqIdPtr orig_sip,SeqIdPtr new_sip)13529 static void ReplaceRNALocationIds (RnaRefPtr rrp, SeqIdPtr orig_sip, SeqIdPtr new_sip)
13530 {
13531   tRNAPtr trp;
13532 
13533   if (rrp != NULL && rrp->ext.choice == 2) {
13534     trp = (tRNAPtr) rrp->ext.value.ptrvalue;
13535     if (trp != NULL) {
13536       trp->anticodon = ReplaceSeqLocID (trp->anticodon, orig_sip, new_sip);
13537     }
13538   }
13539 }
13540 
13541 
13542 
ReplaceFeatureLocationIds(SeqFeatPtr sfp,Pointer userdata)13543 static void ReplaceFeatureLocationIds (SeqFeatPtr sfp, Pointer userdata)
13544 {
13545   ReplaceIdPtr rip;
13546 
13547   if (sfp == NULL || userdata == NULL) return;
13548   rip = (ReplaceIdPtr) userdata;
13549   if (rip->orig_id == NULL || rip->new_id == NULL) return;
13550 
13551   sfp->location = ReplaceSeqLocID (sfp->location, rip->orig_id, rip->new_id);
13552   sfp->product = ReplaceSeqLocID (sfp->product, rip->orig_id, rip->new_id);
13553 
13554   if (sfp->data.value.ptrvalue == NULL) return;
13555 
13556   if (sfp->data.choice == SEQFEAT_CDREGION) {
13557     ReplaceCodingRegionLocationIds (sfp->data.value.ptrvalue, rip->orig_id, rip->new_id);
13558   } else if (sfp->data.choice == SEQFEAT_RNA) {
13559     ReplaceRNALocationIds (sfp->data.value.ptrvalue, rip->orig_id, rip->new_id);
13560   }
13561 }
13562 
13563 
13564 typedef struct proteinidreplacement {
13565   BioseqPtr bsp;
13566   SeqIdPtr  new_id;
13567 } ProteinIdReplacementData, PNTR ProteinIdReplacementPtr;
13568 
13569 
13570 typedef struct proteinidreplacementlist {
13571   ValNodePtr id_list;
13572   CharPtr    db;
13573 } ProteinIdReplacementListData, PNTR ProteinIdReplacementListPtr;
13574 
GetLocusTagForProteinBioseq(BioseqPtr bsp)13575 static CharPtr GetLocusTagForProteinBioseq (BioseqPtr bsp)
13576 {
13577   GeneRefPtr grp = NULL;
13578   SeqFeatPtr cds, gene;
13579 
13580   if (bsp == NULL || !ISA_aa (bsp->mol)) {
13581     return NULL;
13582   }
13583   cds = SeqMgrGetCDSgivenProduct (bsp, NULL);
13584   if (cds == NULL) {
13585     return NULL;
13586   }
13587   grp = SeqMgrGetGeneXref (cds);
13588   if (grp == NULL) {
13589     gene = SeqMgrGetOverlappingGene (cds->location, NULL);
13590     if (gene != NULL) {
13591       grp = (GeneRefPtr) gene->data.value.ptrvalue;
13592     }
13593   }
13594 
13595   if (grp == NULL) {
13596     return NULL;
13597   } else {
13598     return grp->locus_tag;
13599   }
13600 }
13601 
GetDbtagId(BioseqPtr bsp)13602 static DbtagPtr GetDbtagId (BioseqPtr bsp)
13603 {
13604   SeqIdPtr sip;
13605   DbtagPtr dbt = NULL;
13606 
13607   if (bsp == NULL) return NULL;
13608   sip = bsp->id;
13609   for (sip = bsp->id; sip != NULL && dbt == NULL; sip = sip->next)
13610   {
13611     if (sip->choice == SEQID_GENERAL)
13612     {
13613       dbt = (DbtagPtr) sip->data.ptrvalue;
13614       if (dbt != NULL && StringICmp (dbt->db, "TMSMART") == 0)
13615       {
13616         dbt = NULL;
13617       }
13618     }
13619   }
13620   return dbt;
13621 }
13622 
13623 
BuildProteinIDList(BioseqPtr bsp,Pointer userdata)13624 static void BuildProteinIDList (BioseqPtr bsp, Pointer userdata)
13625 {
13626   ProteinIdReplacementListPtr pid_list;
13627   ProteinIdReplacementPtr     pid;
13628   CharPtr                     locus_tag;
13629   SeqIdPtr                    sip;
13630   DbtagPtr                    dbt;
13631 
13632   if (bsp == NULL || userdata == NULL ||!ISA_aa (bsp->mol)) {
13633     return;
13634   }
13635 
13636   dbt = GetDbtagId (bsp);
13637   if (dbt != NULL)
13638   {
13639     /* already has general ID */
13640     return;
13641   }
13642 
13643   pid_list = (ProteinIdReplacementListPtr) userdata;
13644   if (StringHasNoText (pid_list->db)) {
13645     return;
13646   }
13647 
13648   locus_tag = GetLocusTagForProteinBioseq (bsp);
13649 
13650   pid = (ProteinIdReplacementPtr) MemNew (sizeof (ProteinIdReplacementData));
13651   pid->bsp = bsp;
13652   pid->new_id = NULL;
13653   if (!StringHasNoText (locus_tag)) {
13654     dbt = DbtagNew ();
13655     dbt->db = StringSave (pid_list->db);
13656     dbt->tag = ObjectIdNew ();
13657     dbt->tag->id = 0;
13658     dbt->tag->str = StringSave (locus_tag);
13659     sip = ValNodeNew (NULL);
13660     sip->choice = SEQID_GENERAL;
13661     sip->data.ptrvalue = dbt;
13662     pid->new_id = sip;
13663   }
13664   ValNodeAddPointer (&(pid_list->id_list), 0, pid);
13665 }
13666 
FindLocusTagIdDb(BioseqPtr bsp,Pointer userdata)13667 static void FindLocusTagIdDb (BioseqPtr bsp, Pointer userdata)
13668 {
13669   CharPtr PNTR db;
13670   DbtagPtr     dbt;
13671 
13672   if (bsp == NULL || !ISA_aa (bsp->mol) || userdata == NULL) return;
13673   db = (CharPtr PNTR) userdata;
13674   if (*db != NULL) return;
13675 
13676   dbt = GetDbtagId (bsp);
13677   if (dbt == NULL || StringHasNoText (dbt->db)) return;
13678 
13679   *db = dbt->db;
13680 }
13681 
13682 
MakeGeneralIDsFromLocusTags(IteM i)13683 extern void MakeGeneralIDsFromLocusTags (IteM i)
13684 {
13685   BaseFormPtr                  bfp;
13686   SeqEntryPtr                  sep;
13687   CharPtr                      db = NULL;
13688   ProteinIdReplacementListData pird;
13689   ProteinIdReplacementPtr      pid;
13690   ValNodePtr                   duplicated_ids = NULL;
13691   ValNodePtr                   missing_ids = NULL;
13692   ValNodePtr                   vnp;
13693   BioseqPtr                    bsp;
13694   ClickableItemPtr             cip;
13695   ReplaceIdData                rid;
13696   ValNodePtr                   clickable_list = NULL;
13697 
13698 #ifdef WIN_MAC
13699   bfp = currentFormDataPtr;
13700 #else
13701   bfp = GetObjectExtra (i);
13702 #endif
13703   if (bfp == NULL || bfp->input_entityID == 0) return;
13704   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
13705   if (sep == NULL) return;
13706 
13707   VisitBioseqsInSep (sep, &db, FindLocusTagIdDb);
13708   if (StringHasNoText (db)) {
13709     Message (MSG_ERROR, "Unable to locate database tag!");
13710     return;
13711   }
13712 
13713   pird.db = db;
13714   pird.id_list = NULL;
13715 
13716   VisitBioseqsInSep (sep, &pird, BuildProteinIDList);
13717   if (pird.id_list == NULL) {
13718     Message (MSG_OK, "No IDs to replace!");
13719     return;
13720   }
13721 
13722   /* build list of errors */
13723   for (vnp = pird.id_list; vnp != NULL; vnp = vnp->next) {
13724     pid = (ProteinIdReplacementPtr) vnp->data.ptrvalue;
13725     if (pid->new_id == NULL) {
13726       ValNodeAddPointer (&missing_ids, OBJ_BIOSEQ, pid->bsp);
13727     } else {
13728       bsp = BioseqFind (pid->new_id);
13729       if (bsp != NULL) {
13730         cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
13731         MemSet (cip, 0, sizeof (ClickableItemData));
13732         cip->description = StringSave ("Conflicting locus_tag ID");
13733         ValNodeAddPointer (&(cip->item_list), OBJ_BIOSEQ, bsp);
13734         ValNodeAddPointer (&(cip->item_list), OBJ_BIOSEQ, pid->bsp);
13735         ValNodeAddPointer (&duplicated_ids, 0, cip);
13736       }
13737     }
13738   }
13739   if (duplicated_ids == NULL && missing_ids == NULL) {
13740     for (vnp = pird.id_list; vnp != NULL; vnp = vnp->next) {
13741       pid = (ProteinIdReplacementPtr) vnp->data.ptrvalue;
13742       rid.new_id = pid->new_id;
13743       rid.orig_id = pid->bsp->id;
13744       /* replace ID in feature locations */
13745       VisitFeaturesInSep (sep, &rid, ReplaceFeatureLocationIds);
13746       /* add ID to sequence ID list */
13747       ValNodeLink (&(pid->bsp->id), rid.new_id);
13748       SeqMgrReplaceInBioseqIndex (pid->bsp);
13749       /* add to list for display */
13750       ValNodeAddPointer (&clickable_list, OBJ_BIOSEQ, pid->bsp);
13751     }
13752     ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
13753     ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
13754     /* Show what was added */
13755     cip = NewClickableItem (0, "%d IDs were added", clickable_list);
13756     clickable_list = NULL;
13757     ValNodeAddPointer (&clickable_list, 0, cip);
13758     ShowClickableItemList (clickable_list, bfp, "New IDs", "", "Sequences");
13759   } else {
13760     if (missing_ids != NULL) {
13761       cip = NewClickableItem (0, "%d sequences do not have locus_tags", missing_ids);
13762       ValNodeAddPointer (&clickable_list, 0, cip);
13763     }
13764     if (duplicated_ids != NULL) {
13765       cip = NewClickableItem (0, "%d sequences have duplicated locus_tags", NULL);
13766       cip->subcategories = duplicated_ids;
13767       ValNodeAddPointer (&clickable_list, 0, cip);
13768     }
13769     Message (MSG_ERROR, "Problems generating IDs");
13770     ShowClickableItemList (clickable_list, bfp, "Unable to automatically generate IDs", "Error", "Sequences");
13771   }
13772   pird.id_list = ValNodeFreeData (pird.id_list);
13773 }
13774 
13775 
13776 extern Boolean
GetTableOptions(BaseFormPtr bfp,ValNodePtr clickable_list,CharPtr win_title,CharPtr label1,CharPtr label2,CharPtr skip_already_txt,CharPtr blanks_erase_txt,BoolPtr skip_already_has,BoolPtr blanks_erase)13777 GetTableOptions
13778 (BaseFormPtr bfp,
13779  ValNodePtr clickable_list,
13780  CharPtr win_title,
13781  CharPtr label1,
13782  CharPtr label2,
13783  CharPtr skip_already_txt,
13784  CharPtr blanks_erase_txt,
13785  BoolPtr skip_already_has,
13786  BoolPtr blanks_erase)
13787 {
13788   ClickableItemListWindowPtr drfp;
13789   GrouP                      h, opts = NULL;
13790   GrouP                      c;
13791   WindoW                     w;
13792   ButtoN                     b;
13793   SeqEntryPtr                sep;
13794   ModalAcceptCancelData      acd;
13795   ButtoN                     skip_already_btn = NULL, blanks_erase_btn = NULL;
13796   ValNodePtr                 vnp;
13797   ClickableItemPtr           cip;
13798   Boolean                    has_already = FALSE, has_blanks = FALSE;
13799   OMUserDataPtr              omudp;
13800 
13801   if (bfp == NULL) return FALSE;
13802 
13803   drfp = (ClickableItemListWindowPtr) MemNew (sizeof (ClickableItemListWindowData));
13804   if (drfp == NULL)
13805   {
13806     return FALSE;
13807   }
13808 
13809   drfp->bfp = bfp;
13810   drfp->input_entityID = bfp->input_entityID;
13811   sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
13812   w = MovableModalWindow(-20, -13, -10, -10, win_title, NULL);
13813   SetObjectExtra (w, drfp, CleanupClickableItemListWindow);
13814   drfp->form = (ForM) w;
13815   drfp->formmessage = ClickableItemListWindowMessage;
13816 
13817   drfp->item_list = clickable_list;
13818 
13819   /* register to receive update messages */
13820   drfp->userkey = OMGetNextUserKey ();
13821   drfp->procid = 0;
13822   drfp->proctype = OMPROC_EDIT;
13823   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
13824   if (omudp != NULL) {
13825     omudp->userdata.ptrvalue = (Pointer) drfp;
13826     omudp->messagefunc = ClickableItemListWindowMsgFunc;
13827   }
13828 
13829   h = HiddenGroup (w, -1, 0, NULL);
13830   SetGroupSpacing (h, 10, 10);
13831 
13832   drfp->clickable_list = CreateClickableListDialog (h, label1, label1,
13833                                                     ScrollToDiscrepancyItem, EditDiscrepancyItem, bfp,
13834                                                     GetDiscrepancyItemText);
13835 
13836   PointerToDialog (drfp->clickable_list, drfp->item_list);
13837 
13838   if (skip_already_has != NULL) {
13839     *skip_already_has = FALSE;
13840   }
13841   if (blanks_erase != NULL) {
13842     *blanks_erase = FALSE;
13843   }
13844 
13845   for (vnp = clickable_list; vnp != NULL && (!has_already || !has_blanks); vnp = vnp->next) {
13846     cip = vnp->data.ptrvalue;
13847     if (cip->clickable_item_type == TABLE_DATA_ALREADY_HAS) {
13848       has_already = TRUE;
13849     } else if (cip->clickable_item_type == TABLE_DATA_CELL_BLANK) {
13850       has_blanks = TRUE;
13851     }
13852   }
13853   if (has_already || has_blanks) {
13854     opts = HiddenGroup (h, 0, 2, NULL);
13855     SetGroupSpacing (h, 10, 10);
13856     if (has_already) {
13857       if (skip_already_txt == NULL) {
13858         skip_already_txt = "Skip sequences that already have data";
13859       }
13860       skip_already_btn = CheckBox (opts, skip_already_txt, NULL);
13861     }
13862     if (has_blanks) {
13863       if (blanks_erase_txt == NULL) {
13864         blanks_erase_txt = "Erase data when column is blank";
13865       }
13866       blanks_erase_btn = CheckBox (opts, blanks_erase_txt, NULL);
13867     }
13868   }
13869 
13870   c = HiddenGroup (h, 4, 0, NULL);
13871   SetGroupSpacing (c, 10, 10);
13872 
13873   b = PushButton (c, "Accept", ModalAcceptButton);
13874   SetObjectExtra (b, &acd, NULL);
13875   b = PushButton (c, "Cancel", ModalCancelButton);
13876   SetObjectExtra (b, &acd, NULL);
13877 
13878   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list, (HANDLE) c, (HANDLE) opts, NULL);
13879 
13880   Show (w);
13881   Select (w);
13882   acd.accepted = FALSE;
13883   acd.cancelled = FALSE;
13884   while (!acd.accepted && ! acd.cancelled)
13885   {
13886     ProcessExternalEvent ();
13887     Update ();
13888   }
13889   ProcessAnEvent ();
13890 
13891   if (skip_already_btn != NULL && skip_already_has != NULL) {
13892     *skip_already_has = GetStatus (skip_already_btn);
13893   }
13894   if (blanks_erase_btn != NULL && blanks_erase != NULL) {
13895     *blanks_erase = GetStatus (blanks_erase_btn);
13896   }
13897 
13898   Remove (w);
13899   if (acd.cancelled)
13900   {
13901     return FALSE;
13902   }
13903   else
13904   {
13905     return TRUE;
13906   }
13907 
13908 }
13909 
GetCDSListForInterval(Int4 int_left,Int4 int_right,Uint1 strand,SeqFeatPtr first_feat)13910 static ValNodePtr GetCDSListForInterval (Int4 int_left, Int4 int_right, Uint1 strand, SeqFeatPtr first_feat)
13911 {
13912   BioseqPtr         bsp;
13913   SeqMgrFeatContext fcontext;
13914   SeqFeatPtr        sfp;
13915   ValNodePtr        cds_list = NULL;
13916 
13917   if (first_feat == NULL) return NULL;
13918   bsp = BioseqFindFromSeqLoc (first_feat->location);
13919   if (bsp == NULL) return NULL;
13920 
13921   for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, FEATDEF_CDS, &fcontext);
13922        sfp != NULL && fcontext.left <= int_right;
13923        sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, FEATDEF_CDS, &fcontext)) {
13924     if (int_left <= fcontext.left
13925         && int_right >= fcontext.right
13926         && ((strand == Seq_strand_minus && fcontext.strand == Seq_strand_minus)
13927             || (strand != Seq_strand_minus && fcontext.strand != Seq_strand_minus))) {
13928       ValNodeAddPointer (&cds_list, OBJ_SEQFEAT, sfp);
13929     }
13930   }
13931   return cds_list;
13932 }
13933 
GetCDSListForGene(SeqFeatPtr sfp,ValNodePtr cds_list)13934 static ValNodePtr GetCDSListForGene (SeqFeatPtr sfp, ValNodePtr cds_list)
13935 {
13936   SeqFeatPtr        cds, gene;
13937   GeneRefPtr        grp;
13938   ValNodePtr        gene_cds_list = NULL;
13939   SeqMgrFeatContext fcontext;
13940 
13941   if (cds_list == NULL || sfp == NULL || sfp->data.choice != SEQFEAT_GENE) return NULL;
13942 
13943   while (cds_list != NULL) {
13944     cds = cds_list->data.ptrvalue;
13945     if (cds != NULL) {
13946       grp = SeqMgrGetGeneXref (cds);
13947       if (grp == NULL) {
13948         gene = SeqMgrGetOverlappingGene (sfp->location, &fcontext);
13949         if (gene == sfp) {
13950           ValNodeAddPointer (&gene_cds_list, OBJ_SEQFEAT, cds);
13951         }
13952       } else {
13953         if (!SeqMgrGeneIsSuppressed (grp) && GeneRefMatch (grp, sfp->data.value.ptrvalue)) {
13954           ValNodeAddPointer (&gene_cds_list, OBJ_SEQFEAT, cds);
13955         }
13956       }
13957     }
13958     cds_list = cds_list->next;
13959   }
13960   return gene_cds_list;
13961 }
13962 
13963 
GetProductLensFromProtRef(ProtRefPtr prp)13964 static Int4 GetProductLensFromProtRef (ProtRefPtr prp)
13965 {
13966   Int4       lens = 0;
13967   ValNodePtr vnp;
13968 
13969   if (prp == NULL) return 0;
13970   for (vnp = prp->name; vnp != NULL; vnp = vnp->next) {
13971     lens += StringLen (vnp->data.ptrvalue) + 1;
13972   }
13973   return lens;
13974 }
13975 
GetProductLens(ValNodePtr cds_list)13976 static Int4 GetProductLens (ValNodePtr cds_list)
13977 {
13978   SeqFeatPtr        cds, prot_feat;
13979   SeqFeatXrefPtr    xref;
13980   Int4              lens = 0;
13981   BioseqPtr         prot_bsp;
13982   SeqMgrFeatContext fcontext;
13983 
13984   while (cds_list != NULL) {
13985     cds = cds_list->data.ptrvalue;
13986     xref = cds->xref;
13987     while (xref != NULL) {
13988       if (xref->data.choice == SEQFEAT_PROT) {
13989         lens += GetProductLensFromProtRef ((ProtRefPtr) xref->data.value.ptrvalue) + 1;
13990       }
13991       xref = xref->next;
13992     }
13993     prot_bsp = BioseqFindFromSeqLoc (cds->product);
13994     prot_feat = SeqMgrGetNextFeature (prot_bsp, NULL, SEQFEAT_PROT, FEATDEF_PROT, &fcontext);
13995     if (prot_feat != NULL) {
13996       lens += GetProductLensFromProtRef ((ProtRefPtr) prot_feat->data.value.ptrvalue) + 1;
13997     }
13998     cds_list = cds_list->next;
13999   }
14000   return lens;
14001 }
14002 
AddPieceToNote(CharPtr piece,CharPtr new_note)14003 static void AddPieceToNote (CharPtr piece, CharPtr new_note)
14004 {
14005   CharPtr    cp;
14006   Int4       name_len;
14007 
14008   if (!StringHasNoText (piece)) {
14009     cp = StringSearch (new_note, piece);
14010     name_len = StringLen (piece);
14011     if (cp == NULL /* not found at all */
14012         || (cp != new_note && *(cp - 1) != ';') /* not at beginning or after semicolon */
14013         || (*(cp + name_len) != 0 && *(cp + name_len) != ';') /* not at end */) {
14014       StringCat (new_note, piece);
14015       /* only add semicolon if not already at end of note */
14016       if (piece[name_len - 1] != ';') {
14017         StringCat (new_note, ";");
14018       }
14019     }
14020   }
14021 }
14022 
AddProductNamesFromProtRef(ProtRefPtr prp,CharPtr new_note)14023 static void AddProductNamesFromProtRef (ProtRefPtr prp, CharPtr new_note)
14024 {
14025   ValNodePtr vnp;
14026 
14027   /* if product name other than "hypothetical protein" is available, do
14028    * not include "hypothetical protein" in list of product names
14029    */
14030   if (prp == NULL) return;
14031   for (vnp = prp->name; vnp != NULL; vnp = vnp->next) {
14032     if (StringCmp (vnp->data.ptrvalue, "hypothetical protein") == 0) {
14033       if (StringHasNoText (new_note)) {
14034         /* add because no other name found yet */
14035         AddPieceToNote (vnp->data.ptrvalue, new_note);
14036       }
14037     } else if (StringCmp (new_note, "hypothetical protein;") == 0) {
14038       /* replace "hypothetical protein" with new name */
14039       StringCpy (new_note, vnp->data.ptrvalue);
14040       StringCat (new_note, ";");
14041     } else {
14042       /* add as normal */
14043       AddPieceToNote (vnp->data.ptrvalue, new_note);
14044     }
14045   }
14046 }
14047 
AddProductNames(ValNodePtr cds_list,CharPtr new_note)14048 static void AddProductNames (ValNodePtr cds_list, CharPtr new_note)
14049 {
14050   SeqFeatPtr        cds, prot_feat;
14051   SeqFeatXrefPtr    xref;
14052   BioseqPtr         prot_bsp;
14053   SeqMgrFeatContext fcontext;
14054 
14055   while (cds_list != NULL) {
14056     cds = cds_list->data.ptrvalue;
14057     xref = cds->xref;
14058     while (xref != NULL) {
14059       if (xref->data.choice == SEQFEAT_PROT) {
14060         AddProductNamesFromProtRef((ProtRefPtr) xref->data.value.ptrvalue, new_note);
14061       }
14062       xref = xref->next;
14063     }
14064     prot_bsp = BioseqFindFromSeqLoc (cds->product);
14065     prot_feat = SeqMgrGetNextFeature (prot_bsp, NULL, SEQFEAT_PROT, FEATDEF_PROT, &fcontext);
14066     if (prot_feat != NULL) {
14067       AddProductNamesFromProtRef ((ProtRefPtr) prot_feat->data.value.ptrvalue, new_note);
14068     }
14069     cds_list = cds_list->next;
14070   }
14071 }
14072 
RemoveCDSandmRNAForGene(ValNodePtr cds_list)14073 static void RemoveCDSandmRNAForGene (ValNodePtr cds_list)
14074 {
14075   SeqFeatPtr        sfp, old_match;
14076   SeqFeatXrefPtr    xref, prev_xref, next_xref;
14077   Boolean           linked_by_xref;
14078   SeqMgrFeatContext fcontext;
14079   BioseqPtr         prot_bsp;
14080 
14081   while (cds_list != NULL) {
14082     sfp = cds_list->data.ptrvalue;
14083     sfp->idx.deleteme = TRUE;
14084     linked_by_xref = FALSE;
14085     xref = sfp->xref;
14086     prev_xref = NULL;
14087     while (xref != NULL) {
14088       next_xref = xref->next;
14089       if (xref->id.choice == 3 && xref->id.value.ptrvalue != NULL) {
14090         old_match = SeqMgrGetFeatureByFeatID (sfp->idx.entityID, NULL, NULL, xref, NULL);
14091         if (old_match != NULL) {
14092           RemoveFeatureLink (sfp, old_match);
14093           RemoveFeatureLink (old_match, sfp);
14094           old_match->idx.deleteme = TRUE;
14095         }
14096         linked_by_xref = TRUE;
14097       } else {
14098         prev_xref = xref;
14099       }
14100       xref = next_xref;
14101     }
14102     if (!linked_by_xref) {
14103       old_match = SeqMgrGetOverlappingmRNA (sfp->location, &fcontext);
14104       if (old_match != NULL) {
14105         old_match->idx.deleteme = TRUE;
14106       }
14107     }
14108     /* remove protein product */
14109     prot_bsp = BioseqFindFromSeqLoc (sfp->product);
14110     if (prot_bsp != NULL) {
14111       prot_bsp->idx.deleteme = TRUE;
14112     }
14113     cds_list = cds_list->next;
14114   }
14115 }
14116 
CombineToCreatePseudoGene(IteM i)14117 extern void CombineToCreatePseudoGene (IteM i)
14118 {
14119   BaseFormPtr                  bfp;
14120   SelStructPtr      sel;
14121   SeqFeatPtr        sfp, first_sfp;
14122   SeqMgrFeatContext fcontext;
14123   Boolean           ok_to_combine = TRUE;
14124   ValNodePtr        feat_list = NULL, tmp_feat;
14125   Int4              best_left, best_right;
14126   Int4              int_left = -1, int_right = -1;
14127   Uint1             int_strand;
14128   Int4              note_len, product_len;
14129   CharPtr           new_note = NULL, product_note = NULL;
14130   ValNodePtr        cds_list = NULL, gene_cds_list;
14131   GeneRefPtr        grp_first, grp;
14132   SeqIdPtr          sip;
14133   SeqEntryPtr       sep;
14134 
14135 #ifdef WIN_MAC
14136   bfp = currentFormDataPtr;
14137 #else
14138   bfp = GetObjectExtra (i);
14139 #endif
14140   if (bfp == NULL || bfp->input_entityID == 0) return;
14141 
14142   for (sel = ObjMgrGetSelected (); sel != NULL && ok_to_combine; sel = sel->next) {
14143     if (sel->entityID != bfp->input_entityID) {
14144       Message (MSG_ERROR, "You cannot combine genes from separate records.");
14145       ok_to_combine = FALSE;
14146     } else if (sel->itemtype != OBJ_SEQFEAT) {
14147       Message (MSG_ERROR, "You have selected an object that is not a feature.");
14148       ok_to_combine = FALSE;
14149     } else {
14150       sfp = SeqMgrGetDesiredFeature (bfp->input_entityID, NULL, sel->itemID, 0, NULL, &fcontext);
14151       if (sfp == NULL) {
14152         Message (MSG_ERROR, "Unable to locate selected feature.");
14153         ok_to_combine = FALSE;
14154       } else if (sfp->data.choice != SEQFEAT_GENE) {
14155         Message (MSG_ERROR, "You have selected a feature that is not a gene.");
14156         ok_to_combine = FALSE;
14157       } else if (feat_list == NULL
14158                  || best_left > fcontext.left
14159                  || best_left == fcontext.left && best_right < fcontext.right) {
14160         best_left = fcontext.left;
14161         best_right = fcontext.right;
14162         tmp_feat = ValNodeNew (NULL);
14163         tmp_feat->choice = OBJ_SEQFEAT;
14164         tmp_feat->data.ptrvalue = sfp;
14165         tmp_feat->next = feat_list;
14166         feat_list = tmp_feat;
14167       } else {
14168         ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
14169       }
14170 
14171       if (int_left == -1) {
14172         int_left = fcontext.left;
14173         int_right = fcontext.right;
14174         int_strand = fcontext.strand;
14175       } else {
14176         if ((int_strand == Seq_strand_minus && fcontext.strand != Seq_strand_minus)
14177             || (int_strand != Seq_strand_minus && fcontext.strand == Seq_strand_minus)) {
14178           Message (MSG_ERROR, "You cannot select genes on different strands!");
14179           ok_to_combine = FALSE;
14180         } else {
14181           if (int_left > fcontext.left) {
14182             int_left = fcontext.left;
14183           }
14184           if (int_right < fcontext.right) {
14185             int_right = fcontext.right;
14186           }
14187         }
14188       }
14189     }
14190   }
14191 
14192   if (ok_to_combine) {
14193     if (feat_list == NULL || feat_list->next == NULL) {
14194       Message (MSG_ERROR, "You must select at least two genes to combine!");
14195       ok_to_combine = FALSE;
14196     }
14197   }
14198 
14199   if (ok_to_combine) {
14200     first_sfp = feat_list->data.ptrvalue;
14201     grp_first = (GeneRefPtr) first_sfp->data.value.ptrvalue;
14202 
14203     /* get list of coding regions to use when searching for the coding regions for these genes */
14204     cds_list = GetCDSListForInterval (int_left, int_right, int_strand, first_sfp);
14205     /* get length of new gene note */
14206     note_len = StringLen (first_sfp->comment) + 1;
14207 
14208     gene_cds_list = GetCDSListForGene (first_sfp, cds_list);
14209     product_len = GetProductLens (gene_cds_list);
14210     note_len += product_len;
14211     gene_cds_list = ValNodeFree (gene_cds_list);
14212     /* get lengths of locus values, product names, and gene notes from genes after first, to use in gene note */
14213     for (tmp_feat = feat_list->next; tmp_feat != NULL; tmp_feat = tmp_feat->next) {
14214       sfp = tmp_feat->data.ptrvalue;
14215       grp = sfp->data.value.ptrvalue;
14216       if (StringCmp (grp_first->locus, grp->locus) != 0) {
14217         note_len += StringLen (grp->locus) + 1;
14218       }
14219       if (StringCmp (sfp->comment, first_sfp->comment) != 0) {
14220         note_len += StringLen (sfp->comment);
14221       }
14222       gene_cds_list = GetCDSListForGene (sfp, cds_list);
14223       note_len += GetProductLens (gene_cds_list) + 1;
14224       gene_cds_list = ValNodeFree (gene_cds_list);
14225     }
14226     new_note = (CharPtr) MemNew (sizeof (Char) * note_len);
14227     new_note[0] = 0;
14228     /* put locus tags first */
14229     for (tmp_feat = feat_list->next; tmp_feat != NULL; tmp_feat = tmp_feat->next) {
14230       sfp = tmp_feat->data.ptrvalue;
14231       grp = sfp->data.value.ptrvalue;
14232       if (StringCmp (grp_first->locus, grp->locus) != 0) {
14233         StringCat (new_note, grp->locus);
14234         StringCat (new_note, ";");
14235       }
14236     }
14237     /* add original gene note */\
14238     if (!StringHasNoText (first_sfp->comment)) {
14239       StringCat (new_note, first_sfp->comment);
14240       StringCat (new_note, ";");
14241     }
14242 
14243     /* add comments */
14244     for (tmp_feat = feat_list; tmp_feat != NULL; tmp_feat = tmp_feat->next) {
14245       sfp = tmp_feat->data.ptrvalue;
14246       AddPieceToNote (sfp->comment, new_note);
14247     }
14248 
14249     /* add product names */
14250     for (tmp_feat = feat_list; tmp_feat != NULL; tmp_feat = tmp_feat->next) {
14251       sfp = tmp_feat->data.ptrvalue;
14252       gene_cds_list = GetCDSListForGene (sfp, cds_list);
14253       product_note = (CharPtr) MemNew (sizeof (Char) * product_len);
14254       AddProductNames (gene_cds_list, product_note);
14255       AddPieceToNote (product_note, new_note);
14256       product_note = MemFree (product_note);
14257       gene_cds_list = ValNodeFree (gene_cds_list);
14258     }
14259 
14260     /* remove trailing semicolon, replace note */
14261     if (new_note[0] != 0) {
14262       new_note [StringLen (new_note) - 1] = 0;
14263       first_sfp->comment = MemFree (first_sfp->comment);
14264       first_sfp->comment = new_note;
14265     }
14266 
14267     /* set pseudo */
14268     first_sfp->pseudo = TRUE;
14269 
14270     /* set new location */
14271     sip = SeqIdDup (SeqLocId (first_sfp->location));
14272     first_sfp->location = SeqLocFree (first_sfp->location);
14273     first_sfp->location = SeqLocIntNew (int_left, int_right, int_strand, sip);
14274     sip = SeqIdFree (sip);
14275 
14276     /* remove cds and mrna for first gene */
14277     gene_cds_list = GetCDSListForGene (first_sfp, cds_list);
14278     RemoveCDSandmRNAForGene (gene_cds_list);
14279     gene_cds_list = MemFree (gene_cds_list);
14280 
14281     /* remove genes after first and related CDS and mRNA */
14282     for (tmp_feat = feat_list->next; tmp_feat != NULL; tmp_feat = tmp_feat->next) {
14283       sfp = tmp_feat->data.ptrvalue;
14284       gene_cds_list = GetCDSListForGene (sfp, cds_list);
14285       RemoveCDSandmRNAForGene (gene_cds_list);
14286       gene_cds_list = ValNodeFree (gene_cds_list);
14287       sfp->idx.deleteme = TRUE;
14288     }
14289 
14290     /* free interval cds list */
14291     cds_list = ValNodeFree (cds_list);
14292 
14293     /* delete objects, renormalize nuc-prot sets */
14294     DeleteMarkedObjects (bfp->input_entityID, 0, NULL);
14295     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
14296     RemoveOrphanProteins (bfp->input_entityID, sep);
14297     RenormalizeNucProtSets (sep, TRUE);
14298 
14299     ObjMgrSelect (0, 0, 0, 0, NULL);
14300 
14301     ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
14302     ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
14303     Update ();
14304   }
14305   feat_list = ValNodeFree (feat_list);
14306 }
14307 
14308 
FindBadLatLonSourceDesc(SeqDescrPtr sdp,Pointer userdata)14309 static void FindBadLatLonSourceDesc (SeqDescrPtr sdp, Pointer userdata)
14310 {
14311   if (sdp == NULL || sdp->choice != Seq_descr_source || userdata == NULL)
14312   {
14313     return;
14314   }
14315   if (FindBadLatLon (sdp->data.ptrvalue) != NULL)
14316   {
14317     ValNodeAddPointer ((ValNodePtr PNTR) userdata, OBJ_SEQDESC, sdp);
14318   }
14319 }
14320 
14321 
FindBadLatLonSourceFeat(SeqFeatPtr sfp,Pointer userdata)14322 static void FindBadLatLonSourceFeat (SeqFeatPtr sfp, Pointer userdata)
14323 {
14324   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC || userdata == NULL)
14325   {
14326     return;
14327   }
14328   if (FindBadLatLon (sfp->data.value.ptrvalue) != NULL)
14329   {
14330     ValNodeAddPointer ((ValNodePtr PNTR) userdata, OBJ_SEQFEAT, sfp);
14331   }
14332 }
14333 
14334 
14335 
RefreshLatLonTool(Pointer data)14336 static void RefreshLatLonTool (Pointer data)
14337 {
14338   BarcodeToolPtr vstp = (BarcodeToolPtr) data;
14339   if (vstp == NULL) return;
14340 
14341   PointerToDialog (vstp->clickable_list, NULL);
14342   vstp->item_list = ValNodeFree (vstp->item_list);
14343 
14344   VisitDescriptorsInSep (vstp->top_sep, &(vstp->item_list), FindBadLatLonSourceDesc);
14345 
14346   PointerToDialog (vstp->clickable_list, vstp->item_list);
14347 
14348 }
14349 
14350 
CleanupLatLonTool(GraphiC g,VoidPtr data)14351 static void CleanupLatLonTool (GraphiC g, VoidPtr data)
14352 
14353 {
14354   BarcodeToolPtr drfp;
14355 
14356   drfp = (BarcodeToolPtr) data;
14357   if (drfp != NULL) {
14358     drfp->item_list = ValNodeFree (drfp->item_list);
14359     ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
14360   }
14361   StdCleanupFormProc (g, data);
14362 }
14363 
14364 
LatLonAutocorrect(ButtoN b)14365 static void LatLonAutocorrect (ButtoN b)
14366 {
14367   BarcodeToolPtr    drfp;
14368   ValNodePtr        object_list;
14369   LogInfoPtr        lip;
14370 
14371   drfp = (BarcodeToolPtr) GetObjectExtra (b);
14372   if (drfp == NULL) return;
14373   object_list = DialogToPointer (drfp->clickable_list);
14374 
14375   if (object_list == NULL)
14376   {
14377     if (ANS_YES == Message (MSG_YN, "You have not selected any Lat-lon values - correct all?"))
14378     {
14379       object_list = drfp->item_list;
14380     }
14381     else
14382     {
14383       return;
14384     }
14385   }
14386 
14387   lip = OpenLog ("Lat-lon Values Corrected");
14388   LatLonAutocorrectList (lip->fp, object_list);
14389 
14390   if (object_list != drfp->item_list)
14391   {
14392     object_list = ValNodeFree (object_list);
14393   }
14394 
14395   RefreshLatLonTool (drfp);
14396   RedrawBarcodeTool (drfp);
14397 
14398   ObjMgrSetDirtyFlag (drfp->input_entityID, TRUE);
14399   ObjMgrSendMsg (OM_MSG_UPDATE, drfp->input_entityID, 0, 0);
14400   Update();
14401 
14402   lip->data_in_log = TRUE;
14403   CloseLog (lip);
14404   lip = FreeLog (lip);
14405 
14406 }
14407 
14408 
LatLonReport(ButtoN b)14409 static void LatLonReport (ButtoN b)
14410 {
14411   BarcodeToolPtr    drfp;
14412   ValNodePtr        vnp;
14413   LogInfoPtr        lip;
14414   SeqDescrPtr       sdp;
14415   BioSourcePtr      biop;
14416   SubSourcePtr      bad_ssp;
14417   CharPtr           fix;
14418 
14419   drfp = (BarcodeToolPtr) GetObjectExtra (b);
14420   if (drfp == NULL) return;
14421 
14422   lip = OpenLog ("Incorrectly Formatted Lat-lon Values");
14423 
14424   for (vnp = drfp->item_list; vnp != NULL; vnp = vnp->next)
14425   {
14426     if (vnp->choice != OBJ_SEQDESC) continue;
14427     sdp = vnp->data.ptrvalue;
14428     if (sdp != NULL && sdp->choice == Seq_descr_source)
14429     {
14430       biop = (BioSourcePtr) sdp->data.ptrvalue;
14431       bad_ssp = FindBadLatLon (biop);
14432       if (bad_ssp != NULL)
14433       {
14434         fix = FixLatLonFormat (bad_ssp->name);
14435         if (fix != NULL)
14436         {
14437           fprintf (lip->fp, "%s (Suggested correction: %s)\n", bad_ssp->name, fix);
14438           fix = MemFree (fix);
14439         }
14440         else
14441         {
14442           fprintf (lip->fp, "%s (No suggested correction)\n", bad_ssp->name);
14443         }
14444         lip->data_in_log = TRUE;
14445       }
14446     }
14447   }
14448 
14449   CloseLog (lip);
14450   lip = FreeLog (lip);
14451 
14452 }
14453 
14454 
MoveIncorrectlyFormattedLatLonToNote(ButtoN b)14455 static void MoveIncorrectlyFormattedLatLonToNote (ButtoN b)
14456 {
14457   BarcodeToolPtr vstp;
14458   ValNodePtr     vnp;
14459   SeqDescrPtr    sdp;
14460   BioSourcePtr   biop;
14461   SubSourcePtr   note_ssp, bad_ssp, prev_note;
14462   CharPtr        new_txt;
14463   ValNodePtr     object_list;
14464 
14465   vstp = (BarcodeToolPtr) GetObjectExtra (b);
14466   if (vstp == NULL) return;
14467 
14468   object_list = DialogToPointer (vstp->clickable_list);
14469 
14470   if (object_list == NULL)
14471   {
14472     if (ANS_YES == Message (MSG_YN, "You have not selected any Lat-lon values - move all to note?"))
14473     {
14474       object_list = vstp->item_list;
14475     }
14476     else
14477     {
14478       return;
14479     }
14480   }
14481 
14482   for (vnp = object_list; vnp != NULL; vnp = vnp->next)
14483   {
14484     if (vnp->choice != OBJ_SEQDESC) continue;
14485     sdp = vnp->data.ptrvalue;
14486     if (sdp != NULL && sdp->choice == Seq_descr_source)
14487     {
14488       biop = (BioSourcePtr) sdp->data.ptrvalue;
14489       bad_ssp = FindBadLatLon (biop);
14490       if (bad_ssp != NULL)
14491       {
14492         note_ssp = biop->subtype;
14493         prev_note = NULL;
14494         while (note_ssp != NULL && note_ssp->subtype != 255)
14495         {
14496           prev_note = note_ssp;
14497           note_ssp = note_ssp->next;
14498         }
14499         bad_ssp->subtype = 255;
14500 
14501         if (note_ssp != NULL)
14502         {
14503           new_txt = (CharPtr) MemNew (sizeof (Char) * (StringLen (note_ssp->name) + StringLen (bad_ssp->name) + 2));
14504           sprintf (new_txt, "%s;%s", note_ssp->name, bad_ssp->name);
14505           bad_ssp->name = MemFree (bad_ssp->name);
14506           bad_ssp->name = new_txt;
14507           if (prev_note == NULL)
14508           {
14509             biop->subtype = note_ssp->next;
14510           }
14511           else
14512           {
14513             prev_note->next = note_ssp->next;
14514           }
14515           note_ssp->next = NULL;
14516           note_ssp = SubSourceFree (note_ssp);
14517         }
14518       }
14519     }
14520   }
14521   if (object_list != vstp->item_list)
14522   {
14523     object_list = ValNodeFree (object_list);
14524   }
14525 
14526   ObjMgrSetDirtyFlag (vstp->input_entityID, TRUE);
14527   ObjMgrSendMsg (OM_MSG_UPDATE, vstp->input_entityID, 0, 0);
14528   RefreshLatLonTool (vstp);
14529   RedrawBarcodeTool (vstp);
14530 }
14531 
14532 
LatLonTool(IteM i)14533 extern void LatLonTool (IteM i)
14534 {
14535   BaseFormPtr       bfp;
14536   SeqEntryPtr       sep;
14537   ValNodePtr        biosources = NULL;
14538   BarcodeToolPtr    drfp;
14539   WindoW            w;
14540   GrouP             h, c;
14541   ButtoN            b;
14542   OMUserDataPtr            omudp;
14543 
14544 #ifdef WIN_MAC
14545   bfp = currentFormDataPtr;
14546 #else
14547   bfp = GetObjectExtra (i);
14548 #endif
14549   if (bfp == NULL || bfp->input_entityID == 0) return;
14550 
14551   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
14552 
14553   VisitDescriptorsInSep (sep, &biosources, FindBadLatLonSourceDesc);
14554 
14555   if (biosources == NULL)
14556   {
14557     Message (MSG_OK, "All lat-lon values are correctly formatted.");
14558     return;
14559   }
14560 
14561   biosources = ValNodeFree (biosources);
14562 
14563   drfp = (BarcodeToolPtr) MemNew (sizeof (BarcodeToolData));
14564   if (drfp == NULL)
14565   {
14566     return;
14567   }
14568 
14569   drfp->bfp = bfp;
14570   drfp->input_entityID = bfp->input_entityID;
14571   drfp->top_sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
14572   w = FixedWindow (-50, -33, -10, -10, "Lat-Lon Tool", StdCloseWindowProc);
14573   SetObjectExtra (w, drfp, CleanupLatLonTool);
14574   drfp->form = (ForM) w;
14575   drfp->formmessage = BarcodeToolMessage;
14576 
14577   drfp->refresh_func = RefreshLatLonTool;
14578   /* register to receive update messages */
14579   drfp->userkey = OMGetNextUserKey ();
14580   drfp->procid = 0;
14581   drfp->proctype = OMPROC_EDIT;
14582   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
14583   if (omudp != NULL) {
14584     omudp->userdata.ptrvalue = (Pointer) drfp;
14585     omudp->messagefunc = BarcodeToolMsgFunc;
14586   }
14587 
14588 
14589 #ifndef WIN_MAC
14590   CreateStdValidatorFormMenus (w);
14591 #endif
14592 
14593   drfp->item_list = NULL;
14594   drfp->cfg = NULL;
14595   drfp->undo_list = NULL;
14596 
14597   h = HiddenGroup (w, -1, 0, NULL);
14598   SetGroupSpacing (h, 10, 10);
14599 
14600   drfp->clickable_list = LatLonTestResultsDisplay (h);
14601 
14602   RefreshLatLonTool (drfp);
14603   BulkEditorCheckAllDialog (drfp->clickable_list);
14604 
14605   c = HiddenGroup (h, 5, 0, NULL);
14606   SetGroupSpacing (c, 10, 10);
14607 
14608   b = PushButton (c, "Autocorrect Values", LatLonAutocorrect);
14609   SetObjectExtra (b, drfp, NULL);
14610   b = PushButton (c, "Make Report", LatLonReport);
14611   SetObjectExtra (b, drfp, NULL);
14612   b = PushButton (c, "Refresh List", BarcodeRefreshButton);
14613   SetObjectExtra (b, drfp, NULL);
14614   b = PushButton (c, "Move to Note", MoveIncorrectlyFormattedLatLonToNote);
14615   SetObjectExtra (b, drfp, NULL);
14616 
14617   PushButton (c, "Dismiss", StdCancelButtonProc);
14618 
14619   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list, (HANDLE) c, NULL);
14620 
14621   RealizeWindow (w);
14622 
14623   Show (w);
14624 
14625 }
14626 
14627 
FindLatLonCountryConflicts(SeqDescrPtr sdp,Pointer data)14628 static void FindLatLonCountryConflicts (SeqDescrPtr sdp, Pointer data)
14629 {
14630   BioSourcePtr biop;
14631   SubSourcePtr ssp;
14632   CharPtr      orig_country = NULL, country = NULL, cp;
14633   Boolean      found_lat_lon = FALSE;
14634   FloatHi      lat, lon;
14635 
14636   if (sdp == NULL || sdp->choice != Seq_descr_source || sdp->data.ptrvalue == NULL || data == NULL) return;
14637   biop = (BioSourcePtr) sdp->data.ptrvalue;
14638 
14639   for (ssp = biop->subtype; ssp != NULL && (country == NULL || !found_lat_lon); ssp = ssp->next)
14640   {
14641     if (ssp->subtype == SUBSRC_country && !StringHasNoText (ssp->name))
14642     {
14643       orig_country = ssp->name;
14644       country = StringSave (orig_country);
14645     }
14646     else if (ssp->subtype == SUBSRC_lat_lon)
14647     {
14648       if (ParseLatLon (ssp->name, &lat, &lon))
14649       {
14650         found_lat_lon = TRUE;
14651       }
14652     }
14653   }
14654 
14655   cp = StringChr (country, ':');
14656   if (cp != NULL)
14657   {
14658     *cp = 0;
14659   }
14660 
14661   if (found_lat_lon && IsCountryInLatLonList (country))
14662   {
14663     if (!TestLatLonForCountry (country, lat, lon)
14664         && !TestLatLonForCountry (orig_country, lat, lon)
14665         && !StringContainsBodyOfWater (orig_country))
14666     {
14667       ValNodeAddPointer ((ValNodePtr PNTR) data, OBJ_SEQDESC, sdp);
14668     }
14669   }
14670   country = MemFree (country);
14671 }
14672 
14673 
RefreshLatLonCountryTool(Pointer data)14674 static void RefreshLatLonCountryTool (Pointer data)
14675 {
14676   BarcodeToolPtr vstp = (BarcodeToolPtr) data;
14677   if (vstp == NULL) return;
14678 
14679   PointerToDialog (vstp->clickable_list, NULL);
14680   vstp->item_list = ValNodeFree (vstp->item_list);
14681 
14682   VisitDescriptorsInSep (vstp->top_sep, &(vstp->item_list), FindLatLonCountryConflicts);
14683 
14684   PointerToDialog (vstp->clickable_list, vstp->item_list);
14685 
14686 }
14687 
14688 
GetBioseqForSeqdesc(SeqDescPtr sdp)14689 static BioseqPtr GetBioseqForSeqdesc (SeqDescPtr sdp)
14690 {
14691   ObjValNodePtr ovp;
14692   BioseqSetPtr  bssp;
14693   BioseqPtr     bsp = NULL;
14694   SeqEntryPtr   sep;
14695 
14696   if (sdp == NULL || sdp->extended == 0
14697       || (ovp = (ObjValNodePtr) sdp) == NULL
14698       || ovp->idx.parentptr == NULL) {
14699     return NULL;
14700   }
14701   if (ovp->idx.parenttype == OBJ_BIOSEQ) {
14702     bsp = ovp->idx.parentptr;
14703   } else if (ovp->idx.parenttype == OBJ_BIOSEQSET) {
14704     bssp = (BioseqSetPtr) ovp->idx.parentptr;
14705     for (sep = bssp->seq_set; sep != NULL && bsp == NULL; sep = sep->next) {
14706       bsp = GetFirstBioseqInSeqEntry (sep);
14707     }
14708   }
14709   return bsp;
14710 }
14711 
14712 
LatLonCountryReport(ButtoN b)14713 static void LatLonCountryReport (ButtoN b)
14714 {
14715   BarcodeToolPtr    drfp;
14716   ValNodePtr        vnp;
14717   LogInfoPtr        lip;
14718   SeqDescrPtr       sdp;
14719   BioSourcePtr      biop;
14720   SubSourcePtr      ssp;
14721   CharPtr           fix, country = NULL, lat_lon = NULL;
14722   BioseqPtr         bsp;
14723   Char              id_buf[PATH_MAX];
14724 
14725   drfp = (BarcodeToolPtr) GetObjectExtra (b);
14726   if (drfp == NULL) return;
14727 
14728   lip = OpenLog ("Incorrectly Formatted Lat-lon Values");
14729 
14730   for (vnp = drfp->item_list; vnp != NULL; vnp = vnp->next)
14731   {
14732     if (vnp->choice != OBJ_SEQDESC) continue;
14733     sdp = vnp->data.ptrvalue;
14734     if (sdp != NULL && sdp->choice == Seq_descr_source && sdp->data.ptrvalue != NULL)
14735     {
14736       biop = (BioSourcePtr) sdp->data.ptrvalue;
14737       country = NULL;
14738       lat_lon = NULL;
14739       for (ssp = biop->subtype; ssp != NULL && (country == NULL || lat_lon == NULL); ssp = ssp->next)
14740       {
14741         if (ssp->subtype == SUBSRC_country && country == NULL)
14742         {
14743           country = ssp->name;
14744         }
14745         else if (ssp->subtype == SUBSRC_lat_lon && lat_lon == NULL)
14746         {
14747           lat_lon = ssp->name;
14748         }
14749       }
14750       if (country == NULL) country = "missing";
14751       if (lat_lon == NULL) lat_lon = "missing";
14752       fix = GetLatLonCountryCorrection (OBJ_SEQDESC, sdp, NULL);
14753       bsp = GetBioseqForSeqdesc (sdp);
14754       if (bsp != NULL) {
14755         SeqIdWrite (SeqIdFindBest(bsp->id, SEQID_GENBANK), id_buf, PRINTID_REPORT, sizeof (id_buf) - 1);
14756         fprintf (lip->fp, "%s:", id_buf);
14757       }
14758       fprintf (lip->fp, "Country: %s\tLat-lon: %s\tCorrection: %s\n",
14759                country, lat_lon, fix == NULL ? "No suggestion" : fix);
14760       fix = MemFree (fix);
14761       lip->data_in_log = TRUE;
14762     }
14763   }
14764 
14765   CloseLog (lip);
14766   lip = FreeLog (lip);
14767 
14768 }
14769 
14770 
SkipNumberInString(CharPtr str)14771 static CharPtr SkipNumberInString (CharPtr str)
14772 {
14773   CharPtr cp;
14774 
14775   cp = str;
14776   while (isdigit (*cp))
14777   {
14778     cp++;
14779   }
14780   if (*cp == '.')
14781   {
14782     cp++;
14783   }
14784   while (isdigit (*cp))
14785   {
14786     cp++;
14787   }
14788   return cp;
14789 }
14790 
GetLatLonTokens(CharPtr str,CharPtr PNTR lat,CharPtr PNTR ns,CharPtr PNTR lon,CharPtr PNTR ew)14791 static Boolean GetLatLonTokens (CharPtr str, CharPtr PNTR lat, CharPtr PNTR ns, CharPtr PNTR lon, CharPtr PNTR ew)
14792 {
14793   CharPtr cp;
14794 
14795   if (StringHasNoText (str) || lat == NULL || ns == NULL || lon == NULL || ew == NULL) return FALSE;
14796 
14797   cp = str;
14798   while (isspace (*cp))
14799   {
14800     cp++;
14801   }
14802   if (!isdigit (*cp)) return FALSE;
14803   *lat = cp;
14804   cp = SkipNumberInString (cp);
14805 
14806   while (isspace (*cp))
14807   {
14808     cp++;
14809   }
14810 
14811   if (*cp != 'N' && *cp != 'S') return FALSE;
14812   *ns = cp;
14813   cp++;
14814 
14815   while (isspace (*cp))
14816   {
14817     cp++;
14818   }
14819 
14820   if (!isdigit (*cp)) return FALSE;
14821   *lon = cp;
14822   cp = SkipNumberInString (cp);
14823 
14824   while (isspace (*cp))
14825   {
14826     cp++;
14827   }
14828 
14829   if (*cp != 'E' && *cp != 'W') return FALSE;
14830   *ew = cp;
14831 
14832   return TRUE;
14833 }
14834 
MakeLatLonValue(CharPtr lat,Char ns,CharPtr lon,Char ew)14835 static CharPtr MakeLatLonValue (CharPtr lat, Char ns, CharPtr lon, Char ew)
14836 {
14837   CharPtr newval, cp;
14838   Int4 latlen, lonlen, len;
14839 
14840   if (StringHasNoText (lat) || StringHasNoText (lon))
14841   {
14842     return NULL;
14843   }
14844   cp = SkipNumberInString (lat);
14845   latlen = cp - lat;
14846   cp = SkipNumberInString (lon);
14847   lonlen = cp - lon;
14848 
14849   len = latlen + lonlen + 6;
14850 
14851   newval = (CharPtr) MemNew (sizeof (Char) * len);
14852 
14853   cp = newval;
14854   StringNCpy (newval, lat, latlen);
14855   cp += latlen;
14856   *(cp++) = ' ';
14857   *(cp++) = ns;
14858   *(cp++) = ' ';
14859   StringNCpy (cp, lon, lonlen);
14860   cp += lonlen;
14861   *(cp++) = ' ';
14862   *(cp++) = ew;
14863   *(cp++) = 0;
14864 
14865   return newval;
14866 }
14867 
14868 
LatLonCountryAutocorrectList(FILE * fp,ValNodePtr object_list)14869 static void LatLonCountryAutocorrectList (FILE *fp, ValNodePtr object_list)
14870 {
14871   ValNodePtr vnp;
14872   SeqDescrPtr sdp;
14873   BioSourcePtr biop;
14874   SubSourcePtr country_ssp, lat_lon_ssp, ssp;
14875   FloatHi      lat, lon;
14876   CharPtr      country, cp;
14877   CharPtr      fix;
14878 
14879   CharPtr      pLat, pNs, pLon, pEw;
14880 
14881   if (fp == NULL || object_list == NULL) return;
14882 
14883   for (vnp = object_list; vnp != NULL; vnp = vnp->next)
14884   {
14885     if (vnp->choice != OBJ_SEQDESC) continue;
14886     sdp = vnp->data.ptrvalue;
14887     if (sdp != NULL && sdp->choice == Seq_descr_source)
14888     {
14889       biop = (BioSourcePtr) sdp->data.ptrvalue;
14890       country_ssp = NULL;
14891       lat_lon_ssp = NULL;
14892       for (ssp = biop->subtype; ssp != NULL && (country_ssp == NULL || lat_lon_ssp == NULL); ssp = ssp->next)
14893       {
14894         if (StringHasNoText (ssp->name)) continue;
14895         if (ssp->subtype == SUBSRC_country && country_ssp == NULL)
14896         {
14897           country_ssp = ssp;
14898         }
14899         else if (ssp->subtype == SUBSRC_lat_lon && lat_lon_ssp == NULL && ParseLatLon (ssp->name, &lat, &lon))
14900         {
14901           lat_lon_ssp = ssp;
14902         }
14903       }
14904       if (country_ssp == NULL)
14905       {
14906         country = NULL;
14907       } else {
14908         country = StringSave (country_ssp->name);
14909         cp = StringChr (country, ':');
14910         if (cp != NULL) *cp = 0;
14911       }
14912       if (country != NULL && lat_lon_ssp != NULL
14913           && IsCountryInLatLonList (country)
14914           && !TestLatLonForCountry (country, lat, lon)
14915           && GetLatLonTokens (lat_lon_ssp->name, &pLat, &pNs, &pLon, &pEw))
14916       {
14917         fix = NULL;
14918         if (TestLatLonForCountry (country, -lat, lon))
14919         {
14920           fix = MakeLatLonValue (pLat, *pNs == 'N' ? 'S' : 'N',
14921                                  pLon, *pEw);
14922         }
14923         else if (TestLatLonForCountry (country, lat, -lon))
14924         {
14925           fix = MakeLatLonValue (pLat, *pNs,
14926                                  pLon, *pEw == 'E' ? 'W' : 'E');
14927         } else if (TestLatLonForCountry (country, lon, lat)) {
14928           fix = MakeLatLonValue (pLon, *pEw == 'E' ? 'N' : 'S',
14929                                  pLat, *pNs == 'N' ? 'E' : 'W');
14930         }
14931 
14932         if (fix != NULL)
14933         {
14934           fprintf (fp, "Corrected %s to %s\n", lat_lon_ssp->name, fix);
14935           lat_lon_ssp->name = MemFree (lat_lon_ssp->name);
14936           lat_lon_ssp->name = fix;
14937         }
14938         else
14939         {
14940           fprintf (fp, "Unable to correct %s\n", lat_lon_ssp->name);
14941         }
14942       }
14943       country = MemFree (country);
14944     }
14945   }
14946 }
14947 
14948 
LatLonCountryAutocorrect(ButtoN b)14949 static void LatLonCountryAutocorrect (ButtoN b)
14950 {
14951   BarcodeToolPtr    drfp;
14952   ValNodePtr        object_list;
14953   LogInfoPtr        lip;
14954 
14955   drfp = (BarcodeToolPtr) GetObjectExtra (b);
14956   if (drfp == NULL) return;
14957   object_list = DialogToPointer (drfp->clickable_list);
14958 
14959   if (object_list == NULL)
14960   {
14961     if (ANS_YES == Message (MSG_YN, "You have not selected any BioSources - correct all?"))
14962     {
14963       object_list = drfp->item_list;
14964     }
14965     else
14966     {
14967       return;
14968     }
14969   }
14970 
14971   lip = OpenLog ("Lat-lon Values Corrected");
14972 
14973   LatLonCountryAutocorrectList (lip->fp, object_list);
14974 
14975   if (object_list != drfp->item_list)
14976   {
14977     object_list = ValNodeFree (object_list);
14978   }
14979 
14980   RefreshLatLonCountryTool (drfp);
14981   RedrawBarcodeTool (drfp);
14982 
14983   ObjMgrSetDirtyFlag (drfp->input_entityID, TRUE);
14984   ObjMgrSendMsg (OM_MSG_UPDATE, drfp->input_entityID, 0, 0);
14985   Update();
14986 
14987   lip->data_in_log = TRUE;
14988   CloseLog (lip);
14989   lip = FreeLog (lip);
14990 }
14991 
14992 
14993 
LatLonCountryTool(IteM i)14994 extern void LatLonCountryTool (IteM i)
14995 {
14996   BaseFormPtr       bfp;
14997   SeqEntryPtr       sep;
14998   ValNodePtr        biosources = NULL;
14999   BarcodeToolPtr    drfp;
15000   WindoW            w;
15001   GrouP             h, c;
15002   ButtoN            b;
15003   OMUserDataPtr     omudp;
15004   PrompT            ppt;
15005 
15006 #ifdef WIN_MAC
15007   bfp = currentFormDataPtr;
15008 #else
15009   bfp = GetObjectExtra (i);
15010 #endif
15011   if (bfp == NULL || bfp->input_entityID == 0) return;
15012 
15013   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
15014 
15015   VisitDescriptorsInSep (sep, &biosources, FindLatLonCountryConflicts);
15016 
15017   if (biosources == NULL)
15018   {
15019     Message (MSG_OK, "No conflicts found.");
15020     return;
15021   }
15022 
15023   biosources = ValNodeFree (biosources);
15024 
15025   drfp = (BarcodeToolPtr) MemNew (sizeof (BarcodeToolData));
15026   if (drfp == NULL)
15027   {
15028     return;
15029   }
15030 
15031   drfp->bfp = bfp;
15032   drfp->input_entityID = bfp->input_entityID;
15033   drfp->top_sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
15034   w = FixedWindow (-50, -33, -10, -10, "Lat-Lon Country Conflict Tool", StdCloseWindowProc);
15035   SetObjectExtra (w, drfp, CleanupLatLonTool);
15036   drfp->form = (ForM) w;
15037   drfp->formmessage = BarcodeToolMessage;
15038 
15039   drfp->refresh_func = RefreshLatLonCountryTool;
15040 
15041   /* register to receive update messages */
15042   drfp->userkey = OMGetNextUserKey ();
15043   drfp->procid = 0;
15044   drfp->proctype = OMPROC_EDIT;
15045   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
15046   if (omudp != NULL) {
15047     omudp->userdata.ptrvalue = (Pointer) drfp;
15048     omudp->messagefunc = BarcodeToolMsgFunc;
15049   }
15050 
15051 
15052 #ifndef WIN_MAC
15053   CreateStdValidatorFormMenus (w);
15054 #endif
15055 
15056   drfp->item_list = NULL;
15057   drfp->cfg = NULL;
15058   drfp->undo_list = NULL;
15059 
15060   h = HiddenGroup (w, -1, 0, NULL);
15061   SetGroupSpacing (h, 10, 10);
15062 
15063   drfp->clickable_list = LatLonCountryResultsDisplay (h);
15064 
15065   RefreshLatLonCountryTool (drfp);
15066 
15067   ppt = StaticPrompt (h, "Note - only hemisphere transpositions and lat-lon transpositions can be corrected",
15068                       0, stdLineHeight, programFont, 'c');
15069 
15070   c = HiddenGroup (h, 5, 0, NULL);
15071   SetGroupSpacing (c, 10, 10);
15072 
15073   b = PushButton (c, "Autocorrect Values", LatLonCountryAutocorrect);
15074   SetObjectExtra (b, drfp, NULL);
15075   b = PushButton (c, "Make Report", LatLonCountryReport);
15076   SetObjectExtra (b, drfp, NULL);
15077   b = PushButton (c, "Refresh List", BarcodeRefreshButton);
15078   SetObjectExtra (b, drfp, NULL);
15079 
15080   PushButton (c, "Dismiss", StdCancelButtonProc);
15081 
15082   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list, (HANDLE) ppt, (HANDLE) c, NULL);
15083 
15084   RealizeWindow (w);
15085 
15086   Show (w);
15087 
15088 }
15089 
15090 
15091 typedef struct specifichosttool {
15092   BARCODE_TOOL_BLOCK
15093   ButtoN caps;
15094   ButtoN paren;
15095 } SpecificHostToolData, PNTR SpecificHostToolPtr;
15096 
CleanupSpecificHostTool(GraphiC g,VoidPtr data)15097 static void CleanupSpecificHostTool (GraphiC g, VoidPtr data)
15098 
15099 {
15100   SpecificHostToolPtr drfp;
15101 
15102   drfp = (SpecificHostToolPtr) data;
15103   if (drfp != NULL) {
15104     drfp->item_list = SpecificHostFixListFree (drfp->item_list);
15105     ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
15106   }
15107   StdCleanupFormProc (g, data);
15108 }
15109 
15110 
RefreshSpecificHostTool(Pointer data)15111 static void RefreshSpecificHostTool (Pointer data)
15112 {
15113   SpecificHostToolPtr vstp = (SpecificHostToolPtr) data;
15114   if (vstp == NULL) return;
15115 
15116   PointerToDialog (vstp->clickable_list, NULL);
15117   vstp->item_list = SpecificHostFixListFree (vstp->item_list);
15118 
15119   vstp->item_list = Taxon3GetSpecificHostFixesInSeqEntry (vstp->top_sep, GetStatus (vstp->caps), GetStatus (vstp->paren));
15120 
15121   PointerToDialog (vstp->clickable_list, vstp->item_list);
15122 
15123 }
15124 
15125 
SpecificHostAutocorrect(ButtoN b)15126 static void SpecificHostAutocorrect (ButtoN b)
15127 {
15128   SpecificHostToolPtr drfp;
15129   ValNodePtr          object_list, vnp;
15130   LogInfoPtr          lip;
15131   SpecificHostFixPtr  s;
15132 
15133   drfp = (SpecificHostToolPtr) GetObjectExtra (b);
15134   if (drfp == NULL) return;
15135   object_list = DialogToPointer (drfp->clickable_list);
15136 
15137   if (object_list == NULL)
15138   {
15139     if (ANS_YES == Message (MSG_YN, "You have not selected any Specific-host values - correct all?"))
15140     {
15141       object_list = drfp->item_list;
15142     }
15143     else
15144     {
15145       return;
15146     }
15147   }
15148 
15149   lip = OpenLog ("Specific-Host Values Corrected");
15150   for (vnp = object_list; vnp != NULL; vnp = vnp->next)
15151   {
15152     s = (SpecificHostFixPtr) vnp->data.ptrvalue;
15153     if (s == NULL || StringHasNoText (s->bad_specific_host)) continue;
15154     if (ApplyOneSpecificHostFix (vnp->data.ptrvalue))
15155     {
15156       fprintf (lip->fp, "Corrected %s (replaced %s with %s)\n",
15157                s->bad_specific_host, s->old_taxname, s->new_taxname);
15158     }
15159     else
15160     {
15161       fprintf (lip->fp, "Unable to correct %s\n", s->bad_specific_host);
15162     }
15163   }
15164 
15165   if (object_list != drfp->item_list)
15166   {
15167     object_list = ValNodeFree (object_list);
15168   }
15169 
15170   RefreshSpecificHostTool (drfp);
15171   RedrawBarcodeTool ((BarcodeToolPtr)drfp);
15172 
15173   ObjMgrSetDirtyFlag (drfp->input_entityID, TRUE);
15174   ObjMgrSendMsg (OM_MSG_UPDATE, drfp->input_entityID, 0, 0);
15175   Update();
15176 
15177   lip->data_in_log = TRUE;
15178   CloseLog (lip);
15179   lip = FreeLog (lip);
15180 
15181 }
15182 
15183 
SpecificHostReport(ButtoN b)15184 static void SpecificHostReport (ButtoN b)
15185 {
15186   SpecificHostToolPtr drfp;
15187   ValNodePtr          vnp;
15188   LogInfoPtr          lip;
15189   SpecificHostFixPtr  s;
15190   CharPtr             fix;
15191 
15192   drfp = (SpecificHostToolPtr) GetObjectExtra (b);
15193   if (drfp == NULL) return;
15194 
15195   lip = OpenLog ("Incorrect Specific-Host Values");
15196 
15197   for (vnp = drfp->item_list; vnp != NULL; vnp = vnp->next)
15198   {
15199     s = (SpecificHostFixPtr) vnp->data.ptrvalue;
15200     fix = NULL;
15201     if (StringHasNoText (s->bad_specific_host))
15202     {
15203       continue;
15204     }
15205     else if (!StringHasNoText (s->old_taxname) && !StringHasNoText (s->new_taxname))
15206     {
15207       fix = StringSave (s->bad_specific_host);
15208       FindReplaceString (&fix, s->old_taxname, s->new_taxname, TRUE, TRUE);
15209     }
15210     if (fix == NULL)
15211     {
15212       fprintf (lip->fp, "%s (No suggested correction)\n", s->bad_specific_host);
15213     }
15214     else
15215     {
15216       fprintf (lip->fp, "%s (Suggestion correction: %s)\n", s->bad_specific_host, fix);
15217     }
15218     lip->data_in_log = TRUE;
15219     fix = MemFree (fix);
15220   }
15221 
15222   CloseLog (lip);
15223   lip = FreeLog (lip);
15224 }
15225 
15226 
FixSpecificHostValues(IteM i)15227 extern void FixSpecificHostValues (IteM i)
15228 {
15229   BaseFormPtr         bfp;
15230   SeqEntryPtr         sep;
15231   SpecificHostToolPtr drfp;
15232   WindoW              w;
15233   GrouP               h, c;
15234   ButtoN              b;
15235   OMUserDataPtr       omudp;
15236   ValNodePtr          fix_list = NULL;
15237 
15238 #ifdef WIN_MAC
15239   bfp = currentFormDataPtr;
15240 #else
15241   bfp = GetObjectExtra (i);
15242 #endif
15243   if (bfp == NULL || bfp->input_entityID == 0) return;
15244 
15245   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
15246 
15247   fix_list = Taxon3GetSpecificHostFixesInSeqEntry (sep, FALSE, TRUE);
15248 
15249   if (fix_list == NULL)
15250   {
15251     Message (MSG_OK, "All specific host values look up correctly");
15252     return;
15253   }
15254 
15255   fix_list = SpecificHostFixListFree (fix_list);
15256 
15257   drfp = (SpecificHostToolPtr) MemNew (sizeof (SpecificHostToolData));
15258   if (drfp == NULL)
15259   {
15260     return;
15261   }
15262 
15263   drfp->bfp = bfp;
15264   drfp->input_entityID = bfp->input_entityID;
15265   drfp->top_sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
15266   w = FixedWindow (-50, -33, -10, -10, "Specific-Host Tool", StdCloseWindowProc);
15267   SetObjectExtra (w, drfp, CleanupSpecificHostTool);
15268   drfp->form = (ForM) w;
15269   drfp->formmessage = BarcodeToolMessage;
15270 
15271   drfp->refresh_func = RefreshSpecificHostTool;
15272 
15273   /* register to receive update messages */
15274   drfp->userkey = OMGetNextUserKey ();
15275   drfp->procid = 0;
15276   drfp->proctype = OMPROC_EDIT;
15277   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
15278   if (omudp != NULL) {
15279     omudp->userdata.ptrvalue = (Pointer) drfp;
15280     omudp->messagefunc = BarcodeToolMsgFunc;
15281   }
15282 
15283 
15284 #ifndef WIN_MAC
15285   CreateStdValidatorFormMenus (w);
15286 #endif
15287 
15288   drfp->item_list = NULL;
15289   drfp->cfg = NULL;
15290   drfp->undo_list = NULL;
15291 
15292   h = HiddenGroup (w, -1, 0, NULL);
15293   SetGroupSpacing (h, 10, 10);
15294 
15295   drfp->clickable_list = SpecificHostResultsDisplay (h);
15296   drfp->caps = CheckBox (h, "Only check specific host values that start with capital letters", BarcodeRefreshButton);
15297   SetObjectExtra (drfp->caps, drfp, NULL);
15298   SetStatus (drfp->caps, TRUE);
15299   drfp->paren = CheckBox (h, "Check text in parentheses", BarcodeRefreshButton);
15300   SetObjectExtra (drfp->paren, drfp, NULL);
15301   SetStatus (drfp->paren, FALSE);
15302 
15303   RefreshSpecificHostTool (drfp);
15304 
15305   c = HiddenGroup (h, 4, 0, NULL);
15306   SetGroupSpacing (c, 10, 10);
15307 
15308   b = PushButton (c, "Autocorrect Values", SpecificHostAutocorrect);
15309   SetObjectExtra (b, drfp, NULL);
15310   b = PushButton (c, "Make Report", SpecificHostReport);
15311   SetObjectExtra (b, drfp, NULL);
15312   b = PushButton (c, "Refresh List", BarcodeRefreshButton);
15313   SetObjectExtra (b, drfp, NULL);
15314 
15315   PushButton (c, "Dismiss", StdCancelButtonProc);
15316 
15317   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list, (HANDLE) drfp->caps, (HANDLE) drfp->paren, (HANDLE) c, NULL);
15318 
15319   RealizeWindow (w);
15320 
15321   Show (w);
15322 
15323 }
15324 
ReportFailedTaxonomyLookups(ValNodePtr clickable_list)15325 static void ReportFailedTaxonomyLookups (ValNodePtr clickable_list)
15326 {
15327   LogInfoPtr lip;
15328   ValNodePtr vnp;
15329   ClickableItemPtr cip;
15330 
15331   lip = OpenLog ("Failed Taxonomy Lookups");
15332 
15333   for (vnp = clickable_list; vnp != NULL; vnp = vnp->next) {
15334     cip = (ClickableItemPtr) vnp->data.ptrvalue;
15335     if (cip != NULL && !StringHasNoText (cip->description)) {
15336       fprintf (lip->fp, "%s\n", cip->description);
15337       lip->data_in_log = TRUE;
15338     }
15339   }
15340   CloseLog (lip);
15341   lip = FreeLog (lip);
15342 }
15343 
15344 
RefreshFailedTaxonomyLookups(Uint2 entityID)15345 static ValNodePtr RefreshFailedTaxonomyLookups (Uint2 entityID)
15346 {
15347   SeqEntryPtr       sep;
15348   ValNodePtr        failed_list, item_list = NULL, vnp;
15349   CharPtr           taxname = NULL;
15350   ClickableItemPtr  cip = NULL;
15351 
15352   sep = GetTopSeqEntryForEntityID (entityID);
15353 
15354   failed_list = GetOrganismTaxLookupFailuresInSeqEntry (sep);
15355 
15356   /* Make ClickableItem list */
15357   for (vnp = failed_list; vnp != NULL; vnp = vnp->next) {
15358     if (vnp->choice == 0) {
15359       if (cip != NULL) {
15360         /* set description for previous item */
15361         cip->description = (CharPtr) MemNew (sizeof (Char) * (StringLen (taxname) + 18));
15362         sprintf (cip->description, "%s (%d)", taxname, ValNodeLen (cip->item_list));
15363       }
15364       taxname = MemFree (taxname);
15365       /* get taxname to use for this list */
15366       taxname = vnp->data.ptrvalue;
15367       vnp->data.ptrvalue = NULL;
15368       cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
15369       cip->callback_func = BulkEditDiscrepancy;
15370       ValNodeAddPointer (&item_list, 0, cip);
15371     } else {
15372       /* add to clickable item list */
15373       if (cip != NULL) {
15374         ValNodeAddPointer (&(cip->item_list), vnp->choice, vnp->data.ptrvalue);
15375       }
15376     }
15377   }
15378   if (cip != NULL) {
15379     /* set description for last item */
15380     cip->description = (CharPtr) MemNew (sizeof (Char) * (StringLen (taxname) + 18));
15381     sprintf (cip->description, "%s (%d)", taxname, ValNodeLen (cip->item_list));
15382   }
15383   taxname = MemFree (taxname);
15384   failed_list = ValNodeFree (failed_list);
15385 
15386   return item_list;
15387 }
15388 
15389 
ListFailedTaxonomyLookups(IteM i)15390 extern void ListFailedTaxonomyLookups (IteM i)
15391 {
15392   BaseFormPtr       bfp;
15393   ValNodePtr        item_list = NULL;
15394 
15395 #ifdef WIN_MAC
15396   bfp = currentFormDataPtr;
15397 #else
15398   bfp = GetObjectExtra (i);
15399 #endif
15400   if (bfp == NULL || bfp->input_entityID == 0) return;
15401 
15402   item_list = RefreshFailedTaxonomyLookups (bfp->input_entityID);
15403   if (item_list == NULL) {
15404     Message (MSG_OK, "No failed lookups found!");
15405     return;
15406   }
15407 
15408   /* display list */
15409   ShowClickableItemListEx (item_list, bfp,
15410                            "Failed Taxonomy Lookups", "Organism Names", "BioSources",
15411                            ReportFailedTaxonomyLookups, RefreshFailedTaxonomyLookups);
15412 
15413 }
15414 
15415 
FindTaxnames(SeqDescrPtr sdp,Pointer data)15416 static void FindTaxnames (SeqDescrPtr sdp, Pointer data)
15417 {
15418   BioSourcePtr biop;
15419 
15420   if (sdp != NULL && data != NULL
15421       && sdp->choice == Seq_descr_source
15422       && (biop = (BioSourcePtr) sdp->data.ptrvalue) != NULL
15423       && biop->org != NULL
15424       && OkToTaxFix(biop->org->taxname)
15425       && (!HasTaxonomyID(biop) || StringNCmp (biop->org->taxname, "uncultured", 10) != 0)) {
15426     ValNodeAddPointer ((ValNodePtr PNTR) data, OBJ_SEQDESC, sdp);
15427   }
15428 }
15429 
15430 
FindTaxNameFixes(SeqEntryPtr sep)15431 static ValNodePtr FindTaxNameFixes (SeqEntryPtr sep)
15432 {
15433   ValNodePtr org_list = NULL, fix_list = NULL;
15434 
15435   VisitDescriptorsInSep (sep, &org_list, FindTaxnames);
15436   fix_list = Taxon3GetTaxFixList (org_list);
15437   org_list = ValNodeFree (org_list);
15438   return fix_list;
15439 }
15440 
15441 
RefreshTaxFixTool(Pointer data)15442 static void RefreshTaxFixTool (Pointer data)
15443 {
15444   BarcodeToolPtr vstp = (BarcodeToolPtr) data;
15445 
15446   if (vstp == NULL) return;
15447 
15448   PointerToDialog (vstp->clickable_list, NULL);
15449   vstp->item_list = TaxFixItemListFree (vstp->item_list);
15450 
15451   vstp->item_list = FindTaxNameFixes (vstp->top_sep);
15452 
15453   PointerToDialog (vstp->clickable_list, vstp->item_list);
15454 
15455 }
15456 
15457 NLM_EXTERN BioSourcePtr GetBioSourceFromObject (Uint1 choice, Pointer data);
15458 
15459 
TaxFixAutocorrectList(FILE * fp,ValNodePtr tax_fix_list)15460 static void TaxFixAutocorrectList (FILE *fp, ValNodePtr tax_fix_list)
15461 {
15462   ValNodePtr vnp;
15463   TaxFixItemPtr t;
15464   BioSourcePtr biop;
15465 
15466   if (fp == NULL || tax_fix_list == NULL) return;
15467 
15468   for (vnp = tax_fix_list; vnp != NULL; vnp = vnp->next)
15469   {
15470     t = (TaxFixItemPtr) vnp->data.ptrvalue;
15471     if (t == NULL || t->suggested_fix == NULL) {
15472       continue;
15473     }
15474     biop = GetBioSourceFromObject (t->data_choice, t->data);
15475     if (biop != NULL) {
15476       if (biop->org == NULL) {
15477         biop->org = OrgRefNew();
15478       }
15479       fprintf (fp, "Corrected %s to %s\n", biop->org->taxname == NULL ? "missing name" : biop->org->taxname, t->suggested_fix);
15480       RemoveOldName(biop->org);
15481       SetTaxNameAndRemoveTaxRef (biop->org, StringSave (t->suggested_fix));
15482       if (t->remove_species_specific) {
15483         RemoveSpeciesSpecific(biop);
15484         fprintf (fp, "Removed species-specific primer note for %s\n", t->suggested_fix);
15485       }
15486     }
15487   }
15488 }
15489 
15490 
TaxFixAutocorrect(ButtoN b)15491 static void TaxFixAutocorrect (ButtoN b)
15492 {
15493   BarcodeToolPtr    drfp;
15494   ValNodePtr        object_list;
15495   LogInfoPtr        lip;
15496 
15497   drfp = (BarcodeToolPtr) GetObjectExtra (b);
15498   if (drfp == NULL) return;
15499 
15500   ApplyBulkEditorToObjectList (drfp->clickable_list, FALSE);
15501 
15502   object_list = DialogToPointer (drfp->clickable_list);
15503 
15504   if (object_list == NULL)
15505   {
15506     if (ANS_YES == Message (MSG_YN, "You have not selected any taxname values - correct all?"))
15507     {
15508       object_list = drfp->item_list;
15509     }
15510     else
15511     {
15512       return;
15513     }
15514   }
15515 
15516   lip = OpenLog ("Taxname Values Corrected");
15517   TaxFixAutocorrectList (lip->fp, object_list);
15518 
15519   if (object_list != drfp->item_list)
15520   {
15521     object_list = ValNodeFree (object_list);
15522   }
15523 
15524   ForceCleanupEntityID (drfp->input_entityID);
15525   Select (drfp->form);
15526   RefreshTaxFixTool (drfp);
15527   RedrawBarcodeTool (drfp);
15528 
15529   ObjMgrSetDirtyFlag (drfp->input_entityID, TRUE);
15530   ObjMgrSendMsg (OM_MSG_UPDATE, drfp->input_entityID, 0, 0);
15531   Update();
15532 
15533   lip->data_in_log = TRUE;
15534   CloseLog (lip);
15535   lip = FreeLog (lip);
15536 
15537 }
15538 
15539 
TaxFixReport(ButtoN b)15540 static void TaxFixReport (ButtoN b)
15541 {
15542   BarcodeToolPtr    drfp;
15543   ValNodePtr        vnp;
15544   LogInfoPtr        lip;
15545   TaxFixItemPtr     t;
15546 
15547   drfp = (BarcodeToolPtr) GetObjectExtra (b);
15548   if (drfp == NULL) return;
15549 
15550   lip = OpenLog ("Tax Name Fixes");
15551 
15552   for (vnp = drfp->item_list; vnp != NULL; vnp = vnp->next)
15553   {
15554     if ((t = (TaxFixItemPtr) vnp->data.ptrvalue) == NULL) {
15555       continue;
15556     }
15557     if (t->suggested_fix == NULL) {
15558       fprintf (lip->fp, "%s (No suggested correction)\n", t->taxname);
15559     } else {
15560       fprintf (lip->fp, "%s (Suggested correction: %s)\n", t->taxname, t->suggested_fix);
15561       lip->data_in_log = TRUE;
15562     }
15563   }
15564 
15565   CloseLog (lip);
15566   lip = FreeLog (lip);
15567 }
15568 
15569 
AddTextToFix(CharPtr text,BarcodeToolPtr drfp)15570 static void AddTextToFix (CharPtr text, BarcodeToolPtr drfp)
15571 {
15572   ValNodePtr        vnp;
15573   TaxFixItemPtr     t;
15574   CharPtr           tmp;
15575 
15576   if (drfp == NULL || text == NULL) {
15577     return;
15578   }
15579 
15580   ApplyBulkEditorToObjectList (drfp->clickable_list, FALSE);
15581   PointerToDialog (drfp->clickable_list, NULL);
15582 
15583   for (vnp = drfp->item_list; vnp != NULL; vnp = vnp->next) {
15584     t = (TaxFixItemPtr) vnp->data.ptrvalue;
15585     if (t == NULL) {
15586       continue;
15587     }
15588     if (t->suggested_fix == NULL) {
15589       t->suggested_fix = (CharPtr) MemNew (sizeof (Char) * (StringLen (t->taxname) + StringLen (text) + 1));
15590       sprintf (t->suggested_fix, "%s%s", t->taxname, text);
15591     } else {
15592       tmp = (CharPtr) MemNew (sizeof (Char) * (StringLen (t->suggested_fix) + StringLen (text) + 1));
15593       sprintf (tmp, "%s%s", t->suggested_fix, text);
15594       t->suggested_fix = MemFree (t->suggested_fix);
15595       t->suggested_fix = tmp;
15596     }
15597   }
15598   PointerToDialog (drfp->clickable_list, drfp->item_list);
15599   RedrawBarcodeTool (drfp);
15600 
15601 }
15602 
15603 
TaxFixAddSp(ButtoN b)15604 static void TaxFixAddSp (ButtoN b)
15605 {
15606   BarcodeToolPtr    drfp;
15607   CharPtr           sp = " sp.";
15608 
15609   drfp = (BarcodeToolPtr) GetObjectExtra (b);
15610   if (drfp == NULL) return;
15611 
15612   AddTextToFix (sp, drfp);
15613 }
15614 
15615 
TaxFixAddBacterium(ButtoN b)15616 static void TaxFixAddBacterium (ButtoN b)
15617 {
15618   BarcodeToolPtr    drfp;
15619   CharPtr           bacterium = " bacterium";
15620 
15621   drfp = (BarcodeToolPtr) GetObjectExtra (b);
15622   if (drfp == NULL) return;
15623 
15624   AddTextToFix (bacterium, drfp);
15625 }
15626 
15627 
TaxFixCopyNameToCorrection(ButtoN b)15628 static void TaxFixCopyNameToCorrection (ButtoN b)
15629 {
15630   BarcodeToolPtr    drfp;
15631   ValNodePtr        vnp;
15632   TaxFixItemPtr     t;
15633 
15634   drfp = (BarcodeToolPtr) GetObjectExtra (b);
15635   if (drfp == NULL) return;
15636 
15637   ApplyBulkEditorToObjectList (drfp->clickable_list, FALSE);
15638   PointerToDialog (drfp->clickable_list, NULL);
15639 
15640   for (vnp = drfp->item_list; vnp != NULL; vnp = vnp->next) {
15641     t = (TaxFixItemPtr) vnp->data.ptrvalue;
15642     if (t == NULL) {
15643       continue;
15644     }
15645     t->suggested_fix = MemFree (t->suggested_fix);
15646     t->suggested_fix = StringSave (t->taxname);
15647   }
15648   PointerToDialog (drfp->clickable_list, drfp->item_list);
15649   RedrawBarcodeTool (drfp);
15650 }
15651 
15652 
15653 static CharPtr s_UntrimmableWords[] = { "sp.", "cf.", "aff.", "bacterium", "archaeon", NULL };
15654 
TrimTaxFix(ButtoN b)15655 static void TrimTaxFix (ButtoN b)
15656 {
15657   BarcodeToolPtr    drfp;
15658   ValNodePtr        vnp;
15659   TaxFixItemPtr     t;
15660   CharPtr           word_break;
15661   Int4              i;
15662   Boolean           no_fix;
15663 
15664   drfp = (BarcodeToolPtr) GetObjectExtra (b);
15665   if (drfp == NULL) return;
15666 
15667   ApplyBulkEditorToObjectList (drfp->clickable_list, FALSE);
15668   PointerToDialog (drfp->clickable_list, NULL);
15669 
15670   for (vnp = drfp->item_list; vnp != NULL; vnp = vnp->next) {
15671     t = (TaxFixItemPtr) vnp->data.ptrvalue;
15672     if (t == NULL) {
15673       continue;
15674     }
15675     no_fix = FALSE;
15676     word_break = StringRChr (t->suggested_fix, ' ');
15677     if (word_break == NULL
15678       || word_break == t->suggested_fix
15679       || word_break - t->suggested_fix == 10 && StringNICmp (t->suggested_fix, "uncultured ", 11) == 0) {
15680       /* not trimming this one */
15681       no_fix = TRUE;
15682     } else {
15683       for (i = 0; s_UntrimmableWords[i] != NULL && !no_fix; i++) {
15684         if (StringCmp (word_break + 1, s_UntrimmableWords[i]) == 0) {
15685           no_fix = TRUE;
15686         }
15687       }
15688     }
15689     if (!no_fix) {
15690       *word_break = 0;
15691     }
15692   }
15693 
15694   PointerToDialog (drfp->clickable_list, drfp->item_list);
15695   RedrawBarcodeTool (drfp);
15696 }
15697 
15698 
CleanupTaxFixTool(GraphiC g,VoidPtr data)15699 static void CleanupTaxFixTool (GraphiC g, VoidPtr data)
15700 
15701 {
15702   BarcodeToolPtr drfp;
15703 
15704   drfp = (BarcodeToolPtr) data;
15705   if (drfp != NULL) {
15706     drfp->item_list = TaxFixItemListFree (drfp->item_list);
15707     ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
15708   }
15709   StdCleanupFormProc (g, data);
15710 }
15711 
15712 
TaxFixToolBaseForm(BaseFormPtr bfp)15713 extern void TaxFixToolBaseForm (BaseFormPtr bfp)
15714 {
15715   SeqEntryPtr       sep;
15716   ValNodePtr        biosources = NULL;
15717   BarcodeToolPtr    drfp;
15718   WindoW            w;
15719   GrouP             h, c;
15720   ButtoN            b;
15721   OMUserDataPtr            omudp;
15722 
15723   if (bfp == NULL || bfp->input_entityID == 0) return;
15724 
15725   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
15726 
15727   biosources = FindTaxNameFixes (sep);
15728 
15729   if (biosources == NULL)
15730   {
15731     Message (MSG_OK, "No bad taxnames.");
15732     return;
15733   }
15734 
15735   biosources = TaxFixItemListFree (biosources);
15736 
15737   drfp = (BarcodeToolPtr) MemNew (sizeof (BarcodeToolData));
15738   if (drfp == NULL)
15739   {
15740     return;
15741   }
15742 
15743   drfp->bfp = bfp;
15744   drfp->input_entityID = bfp->input_entityID;
15745   drfp->top_sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
15746   w = FixedWindow (-50, -33, -10, -10, "Uncultured Tax Fix Tool", StdCloseWindowProc);
15747   SetObjectExtra (w, drfp, CleanupTaxFixTool);
15748   drfp->form = (ForM) w;
15749   drfp->formmessage = BarcodeToolMessage;
15750 
15751   drfp->refresh_func = RefreshTaxFixTool;
15752   /* register to receive update messages */
15753   drfp->userkey = OMGetNextUserKey ();
15754   drfp->procid = 0;
15755   drfp->proctype = OMPROC_EDIT;
15756   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
15757   if (omudp != NULL) {
15758     omudp->userdata.ptrvalue = (Pointer) drfp;
15759     omudp->messagefunc = BarcodeToolMsgFunc;
15760   }
15761 
15762 
15763 #ifndef WIN_MAC
15764   CreateStdValidatorFormMenus (w);
15765 #endif
15766 
15767   drfp->item_list = NULL;
15768   drfp->cfg = NULL;
15769   drfp->undo_list = NULL;
15770 
15771   h = HiddenGroup (w, -1, 0, NULL);
15772   SetGroupSpacing (h, 10, 10);
15773 
15774   drfp->clickable_list = TaxFixDisplay (h);
15775 
15776   RefreshTaxFixTool (drfp);
15777 
15778   c = HiddenGroup (h, 8, 0, NULL);
15779   SetGroupSpacing (c, 10, 10);
15780 
15781   b = PushButton (c, "Apply Corrections", TaxFixAutocorrect);
15782   SetObjectExtra (b, drfp, NULL);
15783   b = PushButton (c, "Make Report", TaxFixReport);
15784   SetObjectExtra (b, drfp, NULL);
15785   b = PushButton (c, "Refresh List", BarcodeRefreshButton);
15786   SetObjectExtra (b, drfp, NULL);
15787   b = PushButton (c, "Add sp.", TaxFixAddSp);
15788   SetObjectExtra (b, drfp, NULL);
15789   b = PushButton (c, "Add bacterium", TaxFixAddBacterium);
15790   SetObjectExtra (b, drfp, NULL);
15791   b = PushButton (c, "Trim Suggestion", TrimTaxFix);
15792   SetObjectExtra (b, drfp, NULL);
15793   b = PushButton (c, "Copy Taxname to Correction", TaxFixCopyNameToCorrection);
15794   SetObjectExtra (b, drfp, NULL);
15795 
15796   PushButton (c, "Dismiss", StdCancelButtonProc);
15797 
15798   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list, (HANDLE) c, NULL);
15799 
15800   RealizeWindow (w);
15801   SetBulkEditorSortColumn (drfp->clickable_list, 1);
15802 
15803   Show (w);
15804 
15805 }
15806 
15807 
TaxFixTool(IteM i)15808 extern void TaxFixTool (IteM i)
15809 {
15810   BaseFormPtr       bfp;
15811 
15812 #ifdef WIN_MAC
15813   bfp = currentFormDataPtr;
15814 #else
15815   bfp = GetObjectExtra (i);
15816 #endif
15817 
15818   TaxFixToolBaseForm (bfp);
15819 }
15820 
15821 
15822 /* Begin section of code for trimming sequences to contain correct percentage of Ns */
15823 typedef struct ntriminterval {
15824   Int4 start;
15825   Int4 stop;
15826   Int4 internal_ns;
15827   Int4 pct;
15828   BioseqPtr bsp;
15829 } NTrimIntervalData, PNTR NTrimIntervalPtr;
15830 
15831 
NTrimIntervalNew(Int4 start,BioseqPtr bsp)15832 static NTrimIntervalPtr NTrimIntervalNew (Int4 start, BioseqPtr bsp)
15833 {
15834   NTrimIntervalPtr n;
15835 
15836   n = (NTrimIntervalPtr) MemNew (sizeof (NTrimIntervalData));
15837   n->start = start;
15838   n->stop = -1;
15839   n->internal_ns = 0;
15840   n->pct = 0;
15841   n->bsp = bsp;
15842   return n;
15843 }
15844 
15845 
NTrimIntervalCopy(NTrimIntervalPtr orig)15846 static NTrimIntervalPtr NTrimIntervalCopy (NTrimIntervalPtr orig)
15847 {
15848   NTrimIntervalPtr n;
15849 
15850   if (orig == NULL) {
15851     return NULL;
15852   }
15853   n = (NTrimIntervalPtr) MemNew (sizeof (NTrimIntervalData));
15854   n->start = orig->start;
15855   n->stop = orig->stop;
15856   n->internal_ns = orig->internal_ns;
15857   n->pct = orig->pct;
15858   n->bsp = orig->bsp;
15859   return n;
15860 }
15861 
15862 
NTrimIntervalSetStop(NTrimIntervalPtr n,Int4 stop)15863 static void NTrimIntervalSetStop (NTrimIntervalPtr n, Int4 stop)
15864 {
15865   if (n != NULL) {
15866     n->stop = stop;
15867     n->pct = (1000 * n->internal_ns) / (n->stop - n->start + 1);
15868   }
15869 }
15870 
15871 
NTrimIntervalFree(NTrimIntervalPtr n)15872 static NTrimIntervalPtr NTrimIntervalFree (NTrimIntervalPtr n)
15873 {
15874   n = MemFree (n);
15875   return n;
15876 }
15877 
15878 
15879 static int s_MaxPct = 100;
15880 static int s_MinLen = 10;
15881 
SortVnpByNTrimInterval(VoidPtr ptr1,VoidPtr ptr2)15882 NLM_EXTERN int LIBCALLBACK SortVnpByNTrimInterval (VoidPtr ptr1, VoidPtr ptr2)
15883 
15884 {
15885   ValNodePtr  vnp1;
15886   ValNodePtr  vnp2;
15887   NTrimIntervalPtr n1, n2;
15888   Int4        rval = 0, len1, len2;
15889 
15890   if (ptr1 == NULL || ptr2 == NULL) return 0;
15891   vnp1 = *((ValNodePtr PNTR) ptr1);
15892   vnp2 = *((ValNodePtr PNTR) ptr2);
15893   if (vnp1 == NULL || vnp2 == NULL) return 0;
15894   if (vnp1->data.ptrvalue == NULL || vnp2->data.ptrvalue == NULL) return 0;
15895 
15896   n1 = vnp1->data.ptrvalue;
15897   n2 = vnp2->data.ptrvalue;
15898 
15899   len1 = n1->stop - n1->start + 1;
15900   len2 = n2->stop - n2->start + 1;
15901   if (n1->pct < s_MaxPct && n2->pct < s_MaxPct) {
15902     if (len1 > len2) {
15903       rval = -1;
15904     } else if (len1 < len2) {
15905       rval = 1;
15906     } else if (n1->pct < n2->pct) {
15907       rval = -1;
15908     } else if (n1->pct > n2->pct) {
15909       rval = 1;
15910     }
15911   } else if (n1->pct < n2->pct) {
15912     rval = -1;
15913   } else if (n1->pct > n2->pct) {
15914     rval = 1;
15915   } else {
15916     if (len1 > len2) {
15917       rval = -1;
15918     } else if (len1 < len2) {
15919       rval = 1;
15920     } else {
15921       rval = 0;
15922     }
15923   }
15924 
15925   return rval;
15926 }
15927 
15928 
GetTrimInterval(Uint1 data_choice,Pointer data,Pointer metadata)15929 extern Pointer GetTrimInterval (Uint1 data_choice, Pointer data, Pointer metadata)
15930 {
15931   NTrimIntervalPtr n_trim;
15932   CharPtr          fmt = "%d-%d (%.1f%%)";
15933   CharPtr          buffer;
15934 
15935   n_trim = (NTrimIntervalPtr) data;
15936   if (n_trim == NULL || n_trim->bsp == NULL) return NULL;
15937 
15938   if (n_trim->stop - n_trim->start + 1 < s_MinLen) {
15939     buffer = StringSave ("Delete");
15940   } else {
15941     buffer = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + 100));
15942     sprintf (buffer, fmt, n_trim->start + 1, n_trim->stop + 1, (float) n_trim->pct / 10.0);
15943   }
15944   return buffer;
15945 }
15946 
15947 
GetTrimRemove(Uint1 data_choice,Pointer data,Pointer metadata)15948 extern Pointer GetTrimRemove (Uint1 data_choice, Pointer data, Pointer metadata)
15949 {
15950   NTrimIntervalPtr n_trim;
15951   CharPtr          fmt = "%6d";
15952   CharPtr          buffer;
15953   Int4             len;
15954 
15955   n_trim = (NTrimIntervalPtr) data;
15956   if (n_trim == NULL || n_trim->bsp == NULL) return NULL;
15957 
15958   len = n_trim->stop - n_trim->start + 1;
15959 
15960   if (len < s_MinLen) {
15961     buffer = StringSave ("Delete");
15962   } else {
15963     buffer = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + 100));
15964     sprintf (buffer, fmt, n_trim->bsp->length - len);
15965   }
15966   return buffer;
15967 }
15968 
15969 
GetTrimRemaining(Uint1 data_choice,Pointer data,Pointer metadata)15970 extern Pointer GetTrimRemaining (Uint1 data_choice, Pointer data, Pointer metadata)
15971 {
15972   NTrimIntervalPtr n_trim;
15973   CharPtr          fmt = "%6d";
15974   CharPtr          buffer;
15975   Int4             len;
15976 
15977   n_trim = (NTrimIntervalPtr) data;
15978   if (n_trim == NULL || n_trim->bsp == NULL) return NULL;
15979 
15980   len = n_trim->stop - n_trim->start + 1;
15981   buffer = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + 100));
15982   sprintf (buffer, fmt, len);
15983 
15984   return buffer;
15985 }
15986 
15987 
TrimShouldDelete(Uint1 data_choice,Pointer data,Pointer metadata)15988 extern Boolean TrimShouldDelete (Uint1 data_choice, Pointer data, Pointer metadata)
15989 {
15990   NTrimIntervalPtr n_trim;
15991   Int4             len;
15992 
15993   n_trim = (NTrimIntervalPtr) data;
15994 
15995   if (n_trim == NULL) {
15996     return TRUE;
15997   }
15998   len = n_trim->stop - n_trim->start + 1;
15999   if (len < s_MinLen) {
16000     return TRUE;
16001   } else {
16002     return FALSE;
16003   }
16004 }
16005 
16006 
GetCurrentPercentN(Uint1 data_choice,Pointer data,Pointer metadata)16007 extern Pointer GetCurrentPercentN (Uint1 data_choice, Pointer data, Pointer metadata)
16008 {
16009   NTrimIntervalPtr n_trim;
16010   CharPtr          fmt = "%s:%.1f%%";
16011   CharPtr          buffer;
16012   Char             id_buf[255];
16013 
16014   n_trim = (NTrimIntervalPtr) data;
16015   if (n_trim == NULL || n_trim->bsp == NULL) return NULL;
16016 
16017   SeqIdWrite (SeqIdFindBest (n_trim->bsp->id, SEQID_GENBANK), id_buf, PRINTID_REPORT, sizeof (id_buf) - 1);
16018 
16019   buffer = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (id_buf) + 100));
16020   sprintf (buffer, fmt, id_buf, PercentNInBioseq(n_trim->bsp, FALSE));
16021   return buffer;
16022 }
16023 
16024 
GetTrimAccession(Uint1 data_choice,Pointer data,Pointer metadata)16025 extern Pointer GetTrimAccession (Uint1 data_choice, Pointer data, Pointer metadata)
16026 {
16027   NTrimIntervalPtr n_trim;
16028   Char             id_buf[255];
16029 
16030   n_trim = (NTrimIntervalPtr) data;
16031   if (n_trim == NULL || n_trim->bsp == NULL) return NULL;
16032 
16033   SeqIdWrite (SeqIdFindBest (n_trim->bsp->id, SEQID_GENBANK), id_buf, PRINTID_REPORT, sizeof (id_buf) - 1);
16034 
16035   return StringSave (id_buf);
16036 }
16037 
16038 
GetTrim5(Uint1 data_choice,Pointer data,Pointer metadata)16039 extern Pointer GetTrim5 (Uint1 data_choice, Pointer data, Pointer metadata)
16040 {
16041   NTrimIntervalPtr n_trim;
16042   Char             buffer[255];
16043 
16044   n_trim = (NTrimIntervalPtr) data;
16045   if (n_trim == NULL || n_trim->bsp == NULL) return NULL;
16046   sprintf (buffer, "%14d", n_trim->start);
16047 
16048   return StringSave (buffer);
16049 }
16050 
16051 
GetTrim3(Uint1 data_choice,Pointer data,Pointer metadata)16052 extern Pointer GetTrim3 (Uint1 data_choice, Pointer data, Pointer metadata)
16053 {
16054   NTrimIntervalPtr n_trim;
16055   Char             buffer[255];
16056 
16057   n_trim = (NTrimIntervalPtr) data;
16058   if (n_trim == NULL || n_trim->bsp == NULL) return NULL;
16059   sprintf (buffer, "%14d", n_trim->bsp->length - n_trim->stop - 1);
16060 
16061   return StringSave (buffer);
16062 }
16063 
16064 
ScrollToTrimSequenceItem(ValNodePtr vnp,Pointer userdata)16065 extern void ScrollToTrimSequenceItem (ValNodePtr vnp, Pointer userdata)
16066 {
16067   NTrimIntervalPtr n_trim;
16068   BaseFormPtr   bfp;
16069 
16070   if (vnp == NULL || (n_trim = vnp->data.ptrvalue) == NULL || n_trim->bsp == NULL)
16071   {
16072     return;
16073   }
16074 
16075   bfp = GetBaseFormForEntityID (n_trim->bsp->idx.entityID);
16076   if (bfp != NULL) {
16077     Select (bfp->form);
16078     SetBioseqViewTargetByBioseq (bfp, n_trim->bsp);
16079   }
16080 }
16081 
16082 
16083 typedef struct ntrimlist {
16084   ValNodePtr open_intervals;
16085   ValNodePtr closed_intervals;
16086   ValNodePtr start_list;
16087   Boolean last_was_n;
16088   Int4    pos;
16089   Int4    total_ns;
16090   BioseqPtr bsp;
16091 } NTrimListData, PNTR NTrimListPtr;
16092 
FindTrimEndpoints(CharPtr sequence,Pointer userdata)16093 static void LIBCALLBACK FindTrimEndpoints (CharPtr sequence, Pointer userdata)
16094 {
16095   Char          ch;
16096   NTrimListPtr  interval_list;
16097   CharPtr       ptr;
16098   ValNodePtr    vnp;
16099   NTrimIntervalPtr n_open, n_closed;
16100 
16101   if (sequence == NULL || userdata == NULL) return;
16102   interval_list = (NTrimListPtr) userdata;
16103 
16104   ptr = sequence;
16105   ch = *ptr;
16106 
16107   while (ch != '\0') {
16108     if (ch == 'N') {
16109       if (!interval_list->last_was_n) {
16110         /* add new stop */
16111         for (vnp = interval_list->open_intervals; vnp != NULL; vnp = vnp->next) {
16112           n_open = vnp->data.ptrvalue;
16113           n_closed = NTrimIntervalCopy (n_open);
16114           NTrimIntervalSetStop(n_closed, interval_list->pos - 1);
16115           ValNodeAddPointer (&(interval_list->closed_intervals), 0, n_closed);
16116         }
16117       }
16118       /* add Ns to all open intervals */
16119       for (vnp = interval_list->open_intervals; vnp != NULL; vnp = vnp->next) {
16120         n_open = vnp->data.ptrvalue;
16121         n_open->internal_ns ++;
16122       }
16123       interval_list->last_was_n = TRUE;
16124       interval_list->total_ns ++;
16125     } else {
16126       if (interval_list->last_was_n) {
16127         /* add new start */
16128         n_open = NTrimIntervalNew (interval_list->pos, interval_list->bsp);
16129         ValNodeAddPointer (&(interval_list->open_intervals), 0, n_open);
16130         interval_list->last_was_n = FALSE;
16131       }
16132     }
16133     interval_list->pos ++;
16134     ptr++;
16135     ch = *ptr;
16136   }
16137 }
16138 
16139 
FindTrimIntervalsForBioseq(BioseqPtr bsp)16140 static ValNodePtr FindTrimIntervalsForBioseq (BioseqPtr bsp)
16141 {
16142   NTrimListData interval_list;
16143   ValNodePtr    vnp;
16144   NTrimIntervalPtr n_open;
16145   int              orig_pct;
16146 
16147   if (bsp == NULL) return NULL;
16148   MemSet ((Pointer) &interval_list, 0, sizeof (NTrimListData));
16149 
16150   interval_list.bsp = bsp;
16151   interval_list.last_was_n = TRUE; /* need this to start interval at beginning (if sequence not starting with N) */
16152 
16153   SeqPortStream (bsp, EXPAND_GAPS_TO_DASHES | KNOWN_GAP_AS_PLUS, (Pointer) &interval_list, FindTrimEndpoints);
16154 
16155   /* finish up end of sequence intervals */
16156   if (!interval_list.last_was_n) {
16157     for (vnp = interval_list.open_intervals; vnp != NULL; vnp = vnp->next) {
16158       n_open = (NTrimIntervalPtr) vnp->data.ptrvalue;
16159       NTrimIntervalSetStop(n_open, interval_list.pos - 1);
16160     }
16161     ValNodeLink (&(interval_list.closed_intervals), interval_list.open_intervals);
16162     interval_list.open_intervals = NULL;
16163   } else {
16164     interval_list.open_intervals = ValNodeFreeData (interval_list.open_intervals);
16165   }
16166 
16167   interval_list.closed_intervals = ValNodeSort (interval_list.closed_intervals, SortVnpByNTrimInterval);
16168 
16169   orig_pct = (1000 * interval_list.total_ns) / bsp->length;
16170 
16171   if (orig_pct < s_MaxPct) {
16172     interval_list.closed_intervals = ValNodeFreeData (interval_list.closed_intervals);
16173   }
16174 
16175   return interval_list.closed_intervals;
16176 }
16177 
16178 
GetBestTrimIntervalForBioseq(BioseqPtr bsp,Pointer userdata)16179 static void GetBestTrimIntervalForBioseq (BioseqPtr bsp, Pointer userdata)
16180 {
16181   ValNodePtr PNTR best_list;
16182   ValNodePtr intervals;
16183 
16184   if (bsp == NULL || (best_list = (ValNodePtr PNTR) userdata) == NULL) {
16185     return;
16186   }
16187 
16188   intervals = FindTrimIntervalsForBioseq(bsp);
16189 
16190   if (intervals != NULL) {
16191     ValNodeAddPointer (best_list, 0, intervals->data.ptrvalue);
16192     intervals->data.ptrvalue = NULL;
16193     intervals = ValNodeFreeData (intervals);
16194   }
16195 }
16196 
16197 
16198 typedef struct trimnopts {
16199   ValNodePtr best_list;
16200   Int4 max_dist;
16201   Int4 min_stretch_len;
16202 } TrimNOptsData, PNTR TrimNOptsPtr;
16203 
GetTrimIntervalWithoutNStretchesAtEnds(BioseqPtr bsp,Pointer userdata)16204 static void GetTrimIntervalWithoutNStretchesAtEnds (BioseqPtr bsp, Pointer userdata)
16205 {
16206   TrimNOptsPtr opts;
16207   Int2       ctr;
16208   Int4       pos, i, begin = 0, chop5 = -1, chop3 = -1;
16209   Char       buf1[51];
16210   Int4       len = 50, this_stretch = 0;
16211   StreamFlgType flags = STREAM_CORRECT_INVAL | STREAM_EXPAND_GAPS;
16212   NTrimIntervalPtr ntrim;
16213 
16214   if (bsp == NULL || (opts = (TrimNOptsPtr) userdata) == NULL) {
16215     return;
16216   }
16217 
16218   pos = 0;
16219   while (pos < bsp->length) {
16220     ctr = SeqPortStreamInt (bsp, pos, MIN(pos + len - 1, bsp->length - 1), Seq_strand_plus,
16221                             flags, (Pointer) buf1, NULL);
16222     for (i = 0; i < ctr; i++) {
16223       if (buf1[i] == 'N') {
16224         if (this_stretch == 0) {
16225           begin = pos + i;
16226         }
16227         this_stretch++;
16228       } else {
16229         if (this_stretch >= opts->min_stretch_len) {
16230           i = i;
16231         }
16232         if (begin < opts->max_dist && this_stretch >= opts->min_stretch_len) {
16233           chop5 = pos + i;
16234         }
16235         if (pos + i > bsp->length - opts->max_dist && this_stretch >= opts->min_stretch_len) {
16236           chop3 = begin - 1;
16237         }
16238         this_stretch = 0;
16239       }
16240     }
16241     pos += len;
16242   }
16243   if (chop5 > -1 || chop3 > -1) {
16244     if (chop5 > -1 && chop3 > -1 && chop5 + chop3 > bsp->length - 200) {
16245       if (chop3 > chop5) {
16246         chop3 = -1;
16247       } else {
16248         chop5 = -1;
16249       }
16250     }
16251 
16252     ntrim = NTrimIntervalNew (chop5 > -1 ? chop5 : 0, bsp);
16253     NTrimIntervalSetStop (ntrim, chop3 > -1 ? chop3 : bsp->length - 1);
16254     ValNodeAddPointer (&(opts->best_list), 0, ntrim);
16255   }
16256 }
16257 
16258 
16259 typedef struct seqtrimtool {
16260   BARCODE_TOOL_BLOCK
16261   GrouP pages[2];
16262   GrouP page_choice;
16263   /* controls for percentage trimming */
16264   DialoG pct_display;
16265   TexT max_pct;
16266   TexT min_len;
16267   /* controls for end trimming */
16268   DialoG end_display;
16269   TexT max_dist;
16270   TexT min_stretch_len;
16271 } SeqTrimToolData, PNTR SeqTrimToolPtr;
16272 
16273 
CleanupSequenceTrimTool(GraphiC g,VoidPtr data)16274 static void CleanupSequenceTrimTool (GraphiC g, VoidPtr data)
16275 
16276 {
16277   SeqTrimToolPtr drfp;
16278 
16279   drfp = (SeqTrimToolPtr) data;
16280   if (drfp != NULL) {
16281     drfp->item_list = ValNodeFreeData (drfp->item_list);
16282     ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
16283   }
16284   StdCleanupFormProc (g, data);
16285 }
16286 
16287 
RefreshSequenceTrimTool(Pointer data)16288 static void RefreshSequenceTrimTool (Pointer data)
16289 {
16290   FloatHi val;
16291   CharPtr str;
16292   Char    buf[50];
16293   Int2    page;
16294   TrimNOptsData opts;
16295 
16296   SeqTrimToolPtr vstp = (SeqTrimToolPtr) data;
16297 
16298   if (vstp == NULL) return;
16299 
16300   page = GetValue (vstp->page_choice);
16301   if (page == 1) {
16302     str = SaveStringFromText (vstp->max_pct);
16303     val = atof (str);
16304     str = MemFree (str);
16305     s_MaxPct = (Int4) (val * 10);
16306     sprintf (buf, "%.1f", (FloatHi) s_MaxPct / 10.0);
16307     SetTitle (vstp->max_pct, buf);
16308 
16309     str = SaveStringFromText (vstp->min_len);
16310     s_MinLen = atoi (str);
16311     str = MemFree (str);
16312     sprintf (buf, "%d", s_MinLen);
16313     SetTitle (vstp->min_len, buf);
16314 
16315     PointerToDialog (vstp->clickable_list, NULL);
16316     vstp->item_list = ValNodeFreeData (vstp->item_list);
16317 
16318     VisitBioseqsInSep (vstp->top_sep, &(vstp->item_list), GetBestTrimIntervalForBioseq);
16319 
16320     PointerToDialog (vstp->clickable_list, vstp->item_list);
16321 
16322     DefaultCheckTrimSequenceResultsDisplay (vstp->clickable_list);
16323   } else {
16324     PointerToDialog (vstp->clickable_list, NULL);
16325     vstp->item_list = ValNodeFreeData (vstp->item_list);
16326 
16327     MemSet (&opts, 0, sizeof (TrimNOptsData));
16328     str = SaveStringFromText (vstp->max_dist);
16329     opts.max_dist = atoi (str);
16330     str = MemFree (str);
16331     str = SaveStringFromText (vstp->min_stretch_len);
16332     opts.min_stretch_len = atoi (str);
16333     str = MemFree (str);
16334     VisitBioseqsInSep (vstp->top_sep, &opts, GetTrimIntervalWithoutNStretchesAtEnds);
16335     vstp->item_list = opts.best_list;
16336 
16337     PointerToDialog (vstp->clickable_list, vstp->item_list);
16338 
16339     DefaultCheckTrimSequenceResultsDisplay (vstp->clickable_list);
16340   }
16341 }
16342 
16343 
TrimSequence(BioseqPtr bsp,Int4 start,Int4 stop,LogInfoPtr lip)16344 static void TrimSequence (BioseqPtr bsp, Int4 start, Int4 stop, LogInfoPtr lip)
16345 {
16346   SeqIdPtr       sip;
16347   SeqLocPtr      slp1 = NULL,
16348                  slp2 = NULL;
16349   SeqEntryPtr    sep;
16350 
16351   if (bsp == NULL || stop < start) {
16352     return;
16353   }
16354 
16355   sep = GetTopSeqEntryForEntityID (bsp->idx.entityID);
16356   sip = SeqIdFindBest (bsp->id, 0);
16357   /* trim 3' end first */
16358   if (stop < bsp->length) {
16359     slp1 = SeqLocIntNew (stop + 1, bsp->length - 1, Seq_strand_plus, sip);
16360     SeqDeleteByLoc (slp1, TRUE, FALSE);
16361     TrimQualityScores (bsp, bsp->length - 1 - stop, FALSE);
16362   }
16363   /* now trim 5' end */
16364   if (start > 0) {
16365     slp2 = SeqLocIntNew (0, start - 1, Seq_strand_plus, sip);
16366     SeqDeleteByLoc (slp2, TRUE, FALSE);
16367     TrimQualityScores (bsp, start, TRUE);
16368   }
16369   /* also trim alignments and log */
16370   if (slp1!=NULL) {
16371     LogTrimmedLocation (lip, slp1);
16372     if (sep!=NULL) {
16373       SeqEntryExplore (sep, (Pointer)slp1, SeqAlignDeleteByLocCallback);
16374     }
16375     slp1 = SeqLocFree (slp1);
16376   }
16377   if (slp2!=NULL) {
16378     LogTrimmedLocation (lip, slp2);
16379     if (sep!=NULL) {
16380       SeqEntryExplore (sep, (Pointer)slp2, SeqAlignDeleteByLocCallback);
16381     }
16382     slp2 = SeqLocFree (slp2);
16383   }
16384 }
16385 
16386 
AutoTrimList(LogInfoPtr lip,ValNodePtr list)16387 static void AutoTrimList (LogInfoPtr lip, ValNodePtr list)
16388 {
16389   ValNodePtr vnp;
16390   NTrimIntervalPtr n_trim;
16391   Char             id_buf[255];
16392 
16393   if (list == NULL) {
16394     return;
16395   }
16396 
16397   for (vnp = list; vnp != NULL; vnp = vnp->next) {
16398     n_trim = (NTrimIntervalPtr) vnp->data.ptrvalue;
16399     if (n_trim->stop - n_trim->start + 1 < s_MinLen) {
16400       /* delete it */
16401       n_trim->bsp->idx.deleteme = TRUE;
16402       if (lip != NULL && lip->fp != NULL) {
16403         SeqIdWrite (SeqIdFindBest (n_trim->bsp->id, SEQID_GENBANK), id_buf, PRINTID_REPORT, sizeof (id_buf) - 1);
16404         fprintf (lip->fp, "Deleted %s\n", id_buf);
16405         lip->data_in_log = TRUE;
16406       }
16407     } else {
16408       /* trim it */
16409       TrimSequence (n_trim->bsp, n_trim->start, n_trim->stop, lip);
16410     }
16411   }
16412 }
16413 
16414 
AutoTrim(ButtoN b)16415 static void AutoTrim (ButtoN b)
16416 {
16417   SeqTrimToolPtr    drfp;
16418   ValNodePtr        object_list;
16419   LogInfoPtr        lip;
16420 
16421   drfp = (SeqTrimToolPtr) GetObjectExtra (b);
16422   if (drfp == NULL) return;
16423   object_list = DialogToPointer (drfp->clickable_list);
16424 
16425   if (object_list == NULL)
16426   {
16427     if (ANS_YES == Message (MSG_YN, "You have not selected any sequences - correct all?"))
16428     {
16429       object_list = drfp->item_list;
16430     }
16431     else
16432     {
16433       return;
16434     }
16435   }
16436 
16437   WatchCursor();
16438   Update();
16439   lip = OpenLog ("Sequences Trimmed");
16440   AutoTrimList (lip, object_list);
16441 
16442   if (object_list != drfp->item_list)
16443   {
16444     object_list = ValNodeFree (object_list);
16445   }
16446 
16447   DeleteMarkedObjects (drfp->input_entityID, 0, NULL);
16448   ObjMgrSetDirtyFlag (drfp->input_entityID, TRUE);
16449   ObjMgrSendMsg (OM_MSG_UPDATE, drfp->input_entityID, 0, 0);
16450 
16451   RefreshSequenceTrimTool (drfp);
16452   RedrawBarcodeTool ((BarcodeToolPtr)drfp);
16453 
16454   ArrowCursor();
16455   Update();
16456 
16457   lip->data_in_log = TRUE;
16458   CloseLog (lip);
16459   lip = FreeLog (lip);
16460 
16461 }
16462 
16463 
ReportTrimNDelete(ButtoN b)16464 static void ReportTrimNDelete (ButtoN b)
16465 {
16466   SeqTrimToolPtr   drfp;
16467   ValNodePtr       vnp;
16468   LogInfoPtr       lip;
16469   NTrimIntervalPtr n_trim;
16470   Char             id_buf[255];
16471 
16472   drfp = (SeqTrimToolPtr) GetObjectExtra (b);
16473   if (drfp == NULL) return;
16474 
16475   lip = OpenLog ("Sequences that Should Be Deleted");
16476   for (vnp = drfp->item_list; vnp != NULL; vnp = vnp->next) {
16477     if (TrimShouldDelete (vnp->choice, vnp->data.ptrvalue, NULL)) {
16478       n_trim = (NTrimIntervalPtr)(vnp->data.ptrvalue);
16479       if (lip != NULL && lip->fp != NULL) {
16480         SeqIdWrite (SeqIdFindBest (n_trim->bsp->id, SEQID_GENBANK), id_buf, PRINTID_REPORT, sizeof (id_buf) - 1);
16481         fprintf (lip->fp, "%s\n", id_buf);
16482         lip->data_in_log = TRUE;
16483       }
16484     }
16485   }
16486   if (!lip->data_in_log) {
16487     fprintf (lip->fp, "No sequences were found for deletion\n");
16488     lip->data_in_log = TRUE;
16489   }
16490   CloseLog (lip);
16491   lip = FreeLog (lip);
16492 }
16493 
16494 
ChangeTrimToolChoice(GrouP g)16495 static void ChangeTrimToolChoice (GrouP g)
16496 {
16497   SeqTrimToolPtr   drfp;
16498 
16499   drfp = (SeqTrimToolPtr) GetObjectExtra (g);
16500   if (drfp == NULL) return;
16501   WatchCursor();
16502   Update();
16503 
16504   if (GetValue (g) == 1) {
16505     Show (drfp->pages[0]);
16506     Hide (drfp->pages[1]);
16507     drfp->clickable_list = drfp->pct_display;
16508   } else {
16509     Show (drfp->pages[1]);
16510     Hide (drfp->pages[0]);
16511     drfp->clickable_list = drfp->end_display;
16512   }
16513   RefreshSequenceTrimTool (drfp);
16514   ArrowCursor();
16515   Update();
16516 }
16517 
16518 
FindBestNTrimSites(IteM i)16519 NLM_EXTERN void FindBestNTrimSites (IteM i)
16520 {
16521   BaseFormPtr       bfp;
16522   ValNodePtr        trim_list = NULL;
16523   SeqTrimToolPtr    drfp;
16524   WindoW            w;
16525   GrouP             h, page_grp, c, opts;
16526   ButtoN            b;
16527   OMUserDataPtr     omudp;
16528   Char              buf[50];
16529 
16530 #ifdef WIN_MAC
16531   bfp = currentFormDataPtr;
16532 #else
16533   bfp = GetObjectExtra (i);
16534 #endif
16535   if (bfp == NULL || bfp->input_entityID == 0) return;
16536 
16537   drfp = (SeqTrimToolPtr) MemNew (sizeof (SeqTrimToolData));
16538   if (drfp == NULL)
16539   {
16540     return;
16541   }
16542 
16543   drfp->bfp = bfp;
16544   drfp->input_entityID = bfp->input_entityID;
16545   drfp->top_sep = GetTopSeqEntryForEntityID (drfp->input_entityID);
16546   w = FixedWindow (-50, -33, -10, -10, "Sequence Trim Tool", StdCloseWindowProc);
16547   SetObjectExtra (w, drfp, CleanupSequenceTrimTool);
16548   drfp->form = (ForM) w;
16549   drfp->formmessage = BarcodeToolMessage;
16550 
16551   drfp->refresh_func = RefreshSequenceTrimTool;
16552   /* register to receive update messages */
16553   drfp->userkey = OMGetNextUserKey ();
16554   drfp->procid = 0;
16555   drfp->proctype = OMPROC_EDIT;
16556   omudp = ObjMgrAddUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
16557   if (omudp != NULL) {
16558     omudp->userdata.ptrvalue = (Pointer) drfp;
16559     omudp->messagefunc = BarcodeToolMsgFunc;
16560   }
16561 
16562 
16563 #ifndef WIN_MAC
16564   CreateStdValidatorFormMenus (w);
16565 #endif
16566 
16567   drfp->item_list = NULL;
16568   drfp->cfg = NULL;
16569   drfp->undo_list = NULL;
16570 
16571   h = HiddenGroup (w, -1, 0, NULL);
16572   SetGroupSpacing (h, 10, 10);
16573 
16574   page_grp = HiddenGroup (h, 0, 0, NULL);
16575   drfp->pages[0] = HiddenGroup (page_grp, -1, 0, NULL);
16576   /* page for trimming for percentage */
16577   drfp->pct_display = TrimSequenceResultsDisplay (drfp->pages[0]);
16578 
16579   opts = HiddenGroup (drfp->pages[0], 2, 0, NULL);
16580   SetGroupSpacing (opts, 10, 10);
16581   StaticPrompt (opts, "Maximum N Percent", 0, dialogTextHeight, programFont, 'l');
16582   sprintf (buf, "%.1f", (FloatHi) s_MaxPct / 10.0);
16583   drfp->max_pct = DialogText (opts, buf, 10, NULL);
16584 
16585   StaticPrompt (opts, "Minimum Length", 0, dialogTextHeight, programFont, 'l');
16586   sprintf (buf, "%d", s_MinLen);
16587   drfp->min_len = DialogText (opts, buf, 10, NULL);
16588   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->pct_display, (HANDLE) opts, NULL);
16589 
16590   drfp->pages[1] = HiddenGroup (page_grp, -1, 0, NULL);
16591   /* page for trimming ends with stretches */
16592   drfp->end_display = TrimSequenceEndDisplay(drfp->pages[1]);
16593   opts = HiddenGroup (drfp->pages[1], 2, 0, NULL);
16594   SetGroupSpacing (opts, 10, 10);
16595   StaticPrompt (opts, "Maximum distance between N stretch and sequence end", 0, dialogTextHeight, programFont, 'r');
16596   drfp->max_dist =DialogText (opts, "50", 10, NULL);
16597   StaticPrompt (opts, "Minimum length of N stretch", 0, dialogTextHeight, programFont, 'r');
16598   drfp->min_stretch_len = DialogText (opts, "15", 10, NULL);
16599   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->end_display, (HANDLE) opts, NULL);
16600 
16601   AlignObjects (ALIGN_CENTER, (HANDLE) drfp->pages[0], (HANDLE) drfp->pages[1], NULL);
16602 
16603   drfp->page_choice = HiddenGroup (h, 2, 0, ChangeTrimToolChoice);
16604   SetObjectExtra (drfp->page_choice, drfp, NULL);
16605   RadioButton (drfp->page_choice, "Trim to interval with lower percentage");
16606   RadioButton (drfp->page_choice, "Trim ends with stretches of Ns");
16607   SetValue (drfp->page_choice, 1);
16608   ChangeTrimToolChoice (drfp->page_choice);
16609 
16610   c = HiddenGroup (h, 5, 0, NULL);
16611   SetGroupSpacing (c, 10, 10);
16612 
16613   b = PushButton (c, "Autotrim/Delete", AutoTrim);
16614   SetObjectExtra (b, drfp, NULL);
16615   b = PushButton (c, "Report Sequences for Deletion", ReportTrimNDelete);
16616   SetObjectExtra (b, drfp, NULL);
16617   b = PushButton (c, "Refresh List", BarcodeRefreshButton);
16618   SetObjectExtra (b, drfp, NULL);
16619 
16620   PushButton (c, "Dismiss", StdCancelButtonProc);
16621 
16622   AlignObjects (ALIGN_CENTER, (HANDLE) page_grp, (HANDLE) drfp->page_choice, (HANDLE) c, NULL);
16623 
16624   RealizeWindow (w);
16625 
16626   Show (w);
16627 
16628 }
16629 
16630 
16631 typedef struct tsatrimlist {
16632   ValNodePtr intervals;
16633   NTrimIntervalPtr last_int;
16634   Int4    this_stretch;
16635   Int4    pos;
16636   BioseqPtr bsp;
16637   Int4      run_length;
16638 } TSATrimListData, PNTR TSATrimListPtr;
16639 
16640 
FindIntervalsBetweenStretches(CharPtr sequence,Pointer userdata)16641 static void LIBCALLBACK FindIntervalsBetweenStretches(CharPtr sequence, Pointer userdata)
16642 {
16643   Char            ch;
16644   TSATrimListPtr  interval_list;
16645   CharPtr       ptr;
16646 
16647   if (sequence == NULL || userdata == NULL) return;
16648   interval_list = (TSATrimListPtr) userdata;
16649 
16650   ptr = sequence;
16651   ch = *ptr;
16652 
16653   while (ch != '\0') {
16654     if (ch == 'N') {
16655       interval_list->this_stretch ++;
16656       if (interval_list->this_stretch == interval_list->run_length) {
16657         /* close last interval */
16658         if (interval_list->last_int != NULL) {
16659           interval_list->last_int->stop = interval_list->pos - interval_list->this_stretch;
16660           interval_list->last_int = NULL;
16661         }
16662       }
16663     } else {
16664       if (interval_list->this_stretch > 0 || interval_list->pos == 0) {
16665         if (interval_list->last_int == NULL) {
16666           /* make new interval */
16667           interval_list->last_int = NTrimIntervalNew (interval_list->pos, interval_list->bsp);
16668           ValNodeAddPointer (&(interval_list->intervals), 0, interval_list->last_int);
16669         }
16670       }
16671       interval_list->this_stretch = 0;
16672     }
16673     interval_list->pos ++;
16674     ptr++;
16675     ch = *ptr;
16676   }
16677 }
16678 
16679 
AdjustTrimIntervalForPct(NTrimIntervalPtr ntrim,FloatLo n_pct)16680 static void AdjustTrimIntervalForPct (NTrimIntervalPtr ntrim, FloatLo n_pct)
16681 {
16682   NTrimListData    interval_list;
16683   ValNodePtr       vnp;
16684   NTrimIntervalPtr n_open, n_adjust;
16685   FloatLo          orig_pct;
16686 
16687   if (ntrim == NULL || ntrim->bsp == NULL) return;
16688   MemSet ((Pointer) &interval_list, 0, sizeof (NTrimListData));
16689 
16690   interval_list.bsp = ntrim->bsp;
16691   interval_list.last_was_n = TRUE; /* need this to start interval at beginning (if sequence not starting with N) */
16692   interval_list.pos = ntrim->start;
16693 
16694   SeqPortStreamInt (ntrim->bsp, ntrim->start, ntrim->stop, Seq_strand_plus, EXPAND_GAPS_TO_DASHES | KNOWN_GAP_AS_PLUS, (Pointer) &interval_list, FindTrimEndpoints);
16695 
16696   /* finish up end of sequence intervals */
16697   if (!interval_list.last_was_n) {
16698     for (vnp = interval_list.open_intervals; vnp != NULL; vnp = vnp->next) {
16699       n_open = (NTrimIntervalPtr) vnp->data.ptrvalue;
16700       NTrimIntervalSetStop(n_open, interval_list.pos - 1);
16701     }
16702     ValNodeLink (&(interval_list.closed_intervals), interval_list.open_intervals);
16703     interval_list.open_intervals = NULL;
16704   } else {
16705     interval_list.open_intervals = ValNodeFreeData (interval_list.open_intervals);
16706   }
16707 
16708   interval_list.closed_intervals = ValNodeSort (interval_list.closed_intervals, SortVnpByNTrimInterval);
16709 
16710   orig_pct = ((FloatLo)interval_list.total_ns) / ((FloatLo)(ntrim->stop - ntrim->start + 1));
16711   if (orig_pct < n_pct) {
16712     // do nothing
16713   } else if (interval_list.closed_intervals != NULL
16714      && (n_adjust = (NTrimIntervalPtr) interval_list.closed_intervals->data.ptrvalue) != NULL) {
16715     ntrim->start = n_adjust->start;
16716     ntrim->stop = n_adjust->stop;
16717     ntrim->internal_ns = n_adjust->internal_ns;
16718     ntrim->pct = n_adjust->pct;
16719   }
16720   interval_list.closed_intervals = ValNodeFree (interval_list.closed_intervals);
16721 }
16722 
16723 
TSATrimBioseq(BioseqPtr bsp,FloatLo n_pct,Int4 n_length,Int4 min_length,Int4Ptr trim5,Int4Ptr trim3)16724 NLM_EXTERN void TSATrimBioseq (BioseqPtr bsp, FloatLo n_pct, Int4 n_length, Int4 min_length, Int4Ptr trim5, Int4Ptr trim3)
16725 {
16726   TSATrimListData  interval_list;
16727   NTrimIntervalPtr ntrim;
16728   ValNodePtr       vnp, prev, vnp_next;
16729   Boolean          do_remove;
16730 
16731   if (bsp == NULL || trim5 == NULL || trim3 == NULL) {
16732     return;
16733   }
16734 
16735   *trim5 = 0;
16736   *trim3 = 0;
16737   MemSet (&interval_list, 0, sizeof (TSATrimListData));
16738   interval_list.bsp = bsp;
16739   interval_list.run_length = n_length;
16740 
16741   SeqPortStream (bsp, EXPAND_GAPS_TO_DASHES | KNOWN_GAP_AS_PLUS, (Pointer) &interval_list, FindIntervalsBetweenStretches);
16742   if (interval_list.last_int != NULL) {
16743     interval_list.last_int->stop = bsp->length - 1;
16744   }
16745   /* adjust for percentage, eliminate any intervals with length less than minimum */
16746   prev = NULL;
16747   for (vnp = interval_list.intervals; vnp != NULL; vnp = vnp_next) {
16748     vnp_next = vnp->next;
16749     do_remove = FALSE;
16750     if ((ntrim = (NTrimIntervalPtr) vnp->data.ptrvalue) == NULL) {
16751       do_remove = TRUE;
16752     } else if (ntrim->stop - ntrim->start + 1 < min_length) {
16753       do_remove = TRUE;
16754     } else {
16755       AdjustTrimIntervalForPct (ntrim, n_pct);
16756       if (ntrim->stop - ntrim->start + 1 < min_length) {
16757         do_remove = TRUE;
16758       }
16759     }
16760     if (do_remove) {
16761       if (prev == NULL) {
16762         interval_list.intervals = vnp_next;
16763       } else {
16764         prev->next = vnp_next;
16765       }
16766       vnp->next = NULL;
16767       vnp->data.ptrvalue = NTrimIntervalFree (ntrim);
16768       vnp = ValNodeFree (vnp);
16769     } else {
16770       prev = vnp;
16771     }
16772   }
16773   interval_list.intervals = ValNodeSort (interval_list.intervals, SortVnpByNTrimInterval);
16774   if (interval_list.intervals == NULL) {
16775     *trim5 = bsp->length - 1;
16776     *trim3 = 0;
16777   } else {
16778     ntrim = (NTrimIntervalPtr) interval_list.intervals->data.ptrvalue;
16779     *trim5 = ntrim->start;
16780     *trim3 = bsp->length - 1 - ntrim->stop;
16781   }
16782   interval_list.intervals = ValNodeFreeData (interval_list.intervals);
16783 }
16784 
16785 
16786 static SBlastOptions*
BarcodeBlastOptionNew(void)16787 BarcodeBlastOptionNew(void)
16788 
16789 {
16790 	SBlastOptions* options;
16791 	Int2           rval;
16792 	Blast_SummaryReturn *extra_returns;
16793 
16794 
16795   extra_returns = Blast_SummaryReturnNew();
16796   rval = SBlastOptionsNew("blastn", &options,
16797                           extra_returns);
16798 
16799 	if (options == NULL)
16800 		return NULL;
16801 
16802   /* This replaces:
16803    * options->expect_value = 1;
16804    */
16805   SBlastOptionsSetEvalue(options, 0.5);
16806 
16807   /* This replaces:
16808    * options->filter_string = StringSave("m L");
16809    */
16810   SBlastOptionsSetFilterString(options, "m L");
16811 
16812   /* This replaces the following:
16813    * options->mb_template_length = 18;
16814    * options->mb_disc_type = MB_WORD_CODING;
16815    * options->is_megablast_search = TRUE;
16816    * options->discontinuous = TRUE;
16817    */
16818   SBlastOptionsSetDiscMbParams(options, 18, MB_WORD_CODING);
16819 
16820   /* This replaces:
16821    * options->wordsize = 11; \
16822    */
16823 	SBlastOptionsSetWordSize (options, 11);
16824 
16825   /* This replaces:
16826    * options->hitlist_size = 20;
16827    */
16828   options->hit_options->hitlist_size = 20;
16829 
16830   /* This replaces the following:
16831    * options->multiple_hits_only  = TRUE;
16832    * options->window_size = 40;
16833    */
16834   options->word_options->window_size = 40;
16835 
16836   /* This replaces the following:
16837    * options->reward = 1;
16838 	 * options->penalty = -3;
16839 	 * options->gap_open = 5;
16840 	 * options->gap_extend = 2;
16841 	 */
16842   SBlastOptionsSetRewardPenaltyAndGapCosts(options, 2, -3, 5, 2, FALSE);
16843 
16844 	extra_returns = Blast_SummaryReturnFree(extra_returns);
16845 	return options;
16846 }
16847 
16848 
DoesOneBioseqMatchBarcodeDatabase(BioseqPtr bsp,CharPtr database)16849 static Boolean DoesOneBioseqMatchBarcodeDatabase (BioseqPtr bsp, CharPtr database)
16850 {
16851 	SBlastOptions *blast_options;
16852 	Int2 retval=0;
16853 	SeqAlignPtr seqalign = NULL;
16854 	SeqLocPtr   slp;
16855 	SBlastSeqalignArray* seqalign_arr = NULL;
16856 	Blast_SummaryReturn *extra_returns;
16857   Boolean found_match = FALSE;
16858 
16859 	if (bsp == NULL)
16860 		return FALSE;
16861 
16862 	blast_options = BarcodeBlastOptionNew();
16863 	if (blast_options == NULL)
16864 		return FALSE;
16865 
16866 	slp = SeqLocWholeNew(bsp);
16867 
16868 	extra_returns = Blast_SummaryReturnNew();
16869 
16870   retval = Blast_DatabaseSearch(slp, NULL, database, NULL, blast_options, NULL, &seqalign_arr, NULL, extra_returns);
16871 	extra_returns = Blast_SummaryReturnFree(extra_returns);
16872 	blast_options = SBlastOptionsFree(blast_options);
16873 
16874 	if (retval == 0 && seqalign_arr != NULL && seqalign_arr->num_queries >0)
16875 	{
16876 	  /* for now, call any hit a match - later, find better criteria */
16877     seqalign = seqalign_arr->array[0];
16878     if (seqalign != NULL && SeqAlignLength (seqalign) >= 414) {
16879       found_match = TRUE;
16880     }
16881 	}
16882 
16883 	seqalign_arr = SBlastSeqalignArrayFree(seqalign_arr);
16884 
16885 	return found_match;
16886 }
16887 
16888 
MarkBioseqGenesInList(ValNodePtr list,CharPtr gene)16889 static void MarkBioseqGenesInList (ValNodePtr list, CharPtr gene)
16890 {
16891   ValNodePtr vnp;
16892   BioseqPtr  bsp;
16893   SeqFeatPtr sfp;
16894   SeqMgrFeatContext context;
16895   Boolean found;
16896   GeneRefPtr grp;
16897 
16898   for (vnp = list; vnp != NULL; vnp = vnp->next) {
16899     bsp = (BioseqPtr) vnp->data.ptrvalue;
16900     found = FALSE;
16901     for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_GENE, 0, &context);
16902          sfp != NULL && !found;
16903          sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_GENE, 0, &context)) {
16904       grp = (GeneRefPtr) sfp->data.value.ptrvalue;
16905       if (grp != NULL && StringCmp (grp->locus, gene) == 0) {
16906         found = TRUE;
16907       }
16908     }
16909     if (found) {
16910       vnp->choice = 1;
16911     }
16912   }
16913 }
16914 
16915 
SetListChoice(ValNodePtr list,Uint1 choice)16916 static void SetListChoice (ValNodePtr list, Uint1 choice)
16917 {
16918   ValNodePtr vnp;
16919   for (vnp = list; vnp != NULL; vnp = vnp->next) {
16920     vnp->choice = choice;
16921   }
16922 }
16923 
16924 
MarkBarcodeDataBaseBioseqMatchesInList(ValNodePtr list,CharPtr database)16925 static void MarkBarcodeDataBaseBioseqMatchesInList (ValNodePtr list, CharPtr database)
16926 {
16927   ValNodePtr vnp;
16928   BioseqPtr  bsp;
16929   Char       path [PATH_MAX];
16930 
16931   path [0] = '\0';
16932   GetAppParam ("NCBI", "NCBI", "DATA", "", path, sizeof (path));
16933   FileBuildPath (path, NULL, database);
16934 
16935   for (vnp = list; vnp != NULL; vnp = vnp->next) {
16936     bsp = (BioseqPtr) vnp->data.ptrvalue;
16937     if (DoesOneBioseqMatchBarcodeDatabase (bsp, path)) {
16938       vnp->choice = 1;
16939     }
16940   }
16941 
16942 }
16943 
16944 
GetBioseqsForBarcodeScreenCallback(BioseqPtr bsp,Pointer userdata)16945 static void GetBioseqsForBarcodeScreenCallback (BioseqPtr bsp, Pointer userdata)
16946 {
16947   if (bsp != NULL && !ISA_aa (bsp->mol) && userdata != NULL) {
16948     ValNodeAddPointer ((ValNodePtr PNTR) userdata, 0, bsp);
16949   }
16950 }
16951 
16952 
ScreenBarcodePlant(IteM i)16953 NLM_EXTERN void ScreenBarcodePlant (IteM i)
16954 {
16955   BaseFormPtr  bfp;
16956   SeqEntryPtr  sep;
16957   ValNodePtr   list = NULL, rbcl, matk, matches, vnp;
16958   FILE         *fp;
16959   Char         path [PATH_MAX];
16960   BioseqPtr    bsp;
16961   Char         id[PATH_MAX];
16962 
16963 #ifdef WIN_MAC
16964   bfp = currentFormDataPtr;
16965 #else
16966   bfp = GetObjectExtra (i);
16967 #endif
16968   if (bfp == NULL || bfp->input_entityID == 0) return;
16969   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
16970   if (sep == NULL) return;
16971 
16972   WatchCursor ();
16973   Update();
16974   VisitBioseqsInSep (sep, &list, GetBioseqsForBarcodeScreenCallback);
16975   if (list == NULL) {
16976     Message (MSG_ERROR, "Found no nucleotide bioseqs!");
16977     ArrowCursor();
16978     Update();
16979     return;
16980   }
16981   MarkBioseqGenesInList (list, "rbcL");
16982   rbcl = ValNodeExtractList (&list, 1);
16983   SetListChoice (rbcl, 0);
16984   MarkBarcodeDataBaseBioseqMatchesInList (rbcl, "64-rbcL-FINAL-aligned-DNA.fas");
16985   matches = ValNodeExtractList (&rbcl, 1);
16986   matches = ValNodeFree (matches);
16987 
16988   MarkBioseqGenesInList (list, "matK");
16989   matk = ValNodeExtractList (&list, 1);
16990   SetListChoice (matk, 0);
16991   MarkBarcodeDataBaseBioseqMatchesInList (matk, "64-matK-FINAL-aligned-DNA.fas");
16992   matches = ValNodeExtractList (&matk, 1);
16993   matches = ValNodeFree (matches);
16994 
16995   ArrowCursor();
16996   Update();
16997   if (list == NULL && rbcl == NULL && matk == NULL) {
16998     Message (MSG_OK, "All sequences matched to BLAST database");
16999   } else {
17000     TmpNam (path);
17001     fp = FileOpen (path, "w");
17002     if (fp == NULL) {
17003       Message (MSG_ERROR, "Unable to open temporary file %s for error report", path);
17004     } else {
17005       if (list != NULL) {
17006         fprintf (fp, "Unable to detect gene for these sequences:\n");
17007         for (vnp = list;
17008              vnp != NULL;
17009              vnp = vnp->next)
17010         {
17011           bsp = (BioseqPtr) vnp->data.ptrvalue;
17012           SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id, PRINTID_REPORT, sizeof (id) - 1);
17013           fprintf (fp, "%s\n", id);
17014         }
17015       }
17016       if (rbcl != NULL) {
17017         fprintf (fp, "These sequences contain rbcL genes, but do not match to rbcL BLAST database:\n");
17018         for (vnp = rbcl;
17019              vnp != NULL;
17020              vnp = vnp->next)
17021         {
17022           bsp = (BioseqPtr) vnp->data.ptrvalue;
17023           SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id, PRINTID_REPORT, sizeof (id) - 1);
17024           fprintf (fp, "%s\n", id);
17025         }
17026       }
17027       if (matk != NULL) {
17028         fprintf (fp, "These sequences contain matK genes, but do not match to matK BLAST database:\n");
17029         for (vnp = matk;
17030              vnp != NULL;
17031              vnp = vnp->next)
17032         {
17033           bsp = (BioseqPtr) vnp->data.ptrvalue;
17034           SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id, PRINTID_REPORT, sizeof (id) - 1);
17035           fprintf (fp, "%s\n", id);
17036         }
17037       }
17038       FileClose (fp);
17039       LaunchGeneralTextViewer (path, "Unmatched Sequences");
17040       FileRemove (path);
17041     }
17042   }
17043   list = ValNodeFree (list);
17044   matk = ValNodeFree (matk);
17045   rbcl = ValNodeFree (rbcl);
17046 
17047 }
17048