1 /*   sequin1.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:  sequin1.c
27 *
28 * Author:  Jonathan Kans
29 *
30 * Version Creation Date:   1/22/95
31 *
32 * $Revision: 6.1219 $
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 <vsm.h>
55 #include <vsmutil.h>
56 #include <valid.h>
57 #include <fstyle.h>
58 #include <biosrc.h>
59 #include <seqsub.h>
60 #include <cdrgn.h>
61 #include <import.h>
62 #include <medview.h>
63 #include <bspview.h>
64 #include <pubdesc.h>
65 #include <toasn3.h>
66 #include <utilpub.h>
67 #include <tofasta.h>
68 #include <saledit.h>
69 #include <salstruc.h>
70 #include <salfiles.h>
71 #include <salign.h>
72 #include <salsap.h>
73 #include <salutil.h>
74 #include <salpedit.h>
75 #include <salpanel.h>
76 #include <salptool.h>
77 #include <pobutil.h>
78 #include <accutils.h>
79 #include <netcnfg.h>
80 #include <objproj.h>
81 #include <suggslp.h>
82 #include <subutil.h>
83 #include <explore.h>
84 #include <actutils.h>
85 #include <pmfapi.h>
86 #include <accid1.h>
87 #include <ddvopen.h>
88 #include <dotseq.h>
89 #include <ingenwin.h>
90 #include <util/creaders/alnread.h>
91 #include <sqnutils.h>
92 #include <tax3api.h>
93 #include <validerr.h>
94 #include <algo/blast/api/blast_api.h>
95 #include <findrepl.h>
96 #include <ent2api.h>
97 #include <aliread.h>
98 
99 #ifdef WIN_MOTIF
100 #include <netscape.h>
101 #endif
102 
103 #define NLM_GENERATED_CODE_PROTO
104 #include <objmacro.h>
105 #include <macroapi.h>
106 
107 #include <macrodlg.h>
108 
109 /* USE_SMARTNET */
110 #ifdef USE_SMARTNET
111 #include <smartnet.h>
112 #endif
113 
114 /* USE_ENTREZ */
115 #include <accentr.h>
116 
117 #include <objmime.h>
118 #include <mmdbapi.h>
119 /*
120 #ifndef WIN16
121 #include <cn3dentr.h>
122 #include <cn3dopen.h>
123 #endif
124 */
125 
126 #include <entrez.h>
127 
128 /* USE_LOCAL */
129 #include <lsqfetch.h>
130 
131 /* USE_MEDARCH */
132 #include <medarch.h>
133 #include <medutil.h>
134 
135 #include <mla2api.h>
136 
137 #ifdef USE_SPELL
138 #include <spellapi.h>
139 #endif
140 
141 #ifdef OS_MAC
142 #include <Gestalt.h>
143 #endif
144 
145 #include <connect/ncbi_gnutls.h>
146 
147 #define SEQ_APP_VER "15.50"
148 
149 CharPtr SEQUIN_APPLICATION = SEQ_APP_VER;
150 CharPtr SEQUIN_SERVICES = NULL;
151 CharPtr SEQUIN_VERSION = NULL;
152 
153 Boolean  useDesktop = FALSE;
154 Boolean  useEntrez = FALSE;
155 Boolean  useSeqFetch = FALSE;
156 Boolean  useIdLookup = FALSE;
157 Boolean  useLocal = FALSE;
158 Boolean  useBlast = FALSE;
159 Boolean  useMedarch = FALSE;
160 Boolean  newMedarch = FALSE;
161 Boolean  useTaxon = FALSE;
162 Boolean  allowDownload = FALSE;
163 Boolean  extraServices = FALSE;
164 Boolean  indexerVersion = FALSE;
165 
166 Boolean  debugsmartnet = FALSE;
167 
168 CharPtr  genomeCenter = NULL;
169 
170 Boolean  leaveAsOldAsn = FALSE;
171 Boolean  newAlignReader = TRUE;
172 
173 SeqEntryPtr     globalsep = NULL;
174 Uint2           globalEntityID = 0;
175 Char            globalPath [PATH_MAX];
176 
177 static SequinBlockPtr  globalsbp = NULL;
178 
179 static Boolean useOldGraphicView = FALSE;
180 static Boolean useOldAlignmentView = FALSE;
181 static Boolean useOldSequenceView = FALSE;
182 /* static Boolean useUdv = FALSE; */
183 
184 static Boolean gphviewscorealigns = FALSE;
185 
186 ForM  startupForm = NULL;
187 
188 #ifdef WIN_MAC
189 Boolean  termListUp = FALSE;
190 Boolean  docSumUp = FALSE;
191 Boolean  bioseqViewUp = FALSE;
192 #endif
193 
194 #ifdef WIN_MAC
195 static IteM  openItem = NULL;
196 static IteM  closeItem = NULL;
197 static IteM  importItem = NULL;
198 static IteM  exportItem = NULL;
199 static IteM  duplicateViewItem = NULL;
200 static IteM  saveItem = NULL;
201 static IteM  saveAsItem = NULL;
202 static IteM  restoreItem = NULL;
203 static IteM  prepareItem = NULL;
204 static IteM  submitItem = NULL;
205 static IteM  loadUidItem = NULL;
206 static IteM  saveUidItem = NULL;
207 static IteM  printItem = NULL;
208 
209 static IteM  undoItem = NULL;
210 static IteM  cutItem = NULL;
211 static IteM  copyItem = NULL;
212 static IteM  pasteItem = NULL;
213 static IteM  deleteItem = NULL;
214 static IteM  duplicateItem = NULL;
215 
216 static IteM  orfItem = NULL;
217 static IteM  aluItem = NULL;
218 static IteM  targetItem = NULL;
219 static IteM  findItem = NULL;
220 static IteM  findFFItem = NULL;
221 static IteM  findGeneItem = NULL;
222 static IteM  findProtItem = NULL;
223 static IteM  findPosItem = NULL;
224 static IteM  validateItem = NULL;
225 static MenU  validateMenu = NULL;
226 static MenU  vecscreenMenu = NULL;
227 static IteM  spellItem = NULL;
228 static IteM  vectorScreenItem = NULL;
229 static MenU  cddSearchMenu = NULL;
230 static IteM  cddSearchItem = NULL;
231 static IteM  editsequenceitem = NULL;
232 static IteM  editseqalignitem = NULL;
233 static IteM  editseqdeleteitem = NULL;
234 static IteM  editseqsubitem = NULL;
235 static IteM  edithistoryitem = NULL;
236 static MenU  updateSeqMenu = NULL;
237 static MenU  updateSeqMenuIndexer = NULL;
238 static MenU  extendSeqMenu = NULL;
239 static MenU  addSeqMenu = NULL;
240 static IteM  featPropItem = NULL;
241 static IteM  parseFileItem = NULL;
242 static IteM  updalignitem = NULL;
243 static IteM  updalignidxitem = NULL;
244 
245 static IteM  docsumfontItem = NULL;
246 static IteM  displayfontItem = NULL;
247 static IteM  preferencesItem = NULL;
248 static IteM  clearUnusedItem = NULL;
249 static IteM  legendItem = NULL;
250 static ChoicE  queryChoice = NULL;
251 static ChoicE  neighborChoice = NULL;
252 static IteM  oldAsnItem = NULL;
253 
254 extern IteM  addSecondaryItem;
255 IteM  addSecondaryItem = NULL;
256 #endif
257 
258 static Int2  startupStyle = 0;
259 
260 static ForM  termListForm = NULL;
261 static ForM  docSumForm = NULL;
262 
263 static Boolean  loadSaveUidListOK = FALSE;
264 
265 static MedlineViewProcs    medviewprocs;
266 SeqViewProcs        seqviewprocs;
267 static EntrezGlobals       entrezglobals;
268 
269 static SeqEditViewProcs    seqedprocs;
270 static StdEditorProcs      stdedprocs;
271 static StdEditorProcs      valdtrprocs;
272 static TextViewProcs       txtviewprocs;
273 static PubdescEditProcs    pubedprocs;
274 static BioSourceEditProcs  biosrcedprocs;
275 
276 /*
277 static PRGD  prgdDict = NULL;
278 */
279 
280 static Boolean  workbenchMode = FALSE;
281 static Boolean  subtoolMode = FALSE;
282 static Boolean  stdinMode = FALSE;
283 static Boolean  bioseqsetMode = FALSE;
284 static Boolean  binseqentryMode = FALSE;
285 static Boolean  entrezMode = FALSE;
286 static Boolean  nohelpMode = FALSE;
287 static Boolean  backupMode = FALSE;
288 static Uint2    subtoolDatatype = 0;
289 static Uint2    subtoolEntityID = 0;
290 
291 static Boolean  smartnetMode = FALSE;
292 static Boolean  dirsubMode = FALSE;
293 
294 #ifdef WIN_MAC
295 static MenU     newDescMenu = NULL;
296 static MenU     newFeatMenu = NULL;
297 static MenU     advTableMenu = NULL;
298 static IteM     sucItem = NULL;
299 static MenU     newPubMenu = NULL;
300 static MenU     batchApplyMenu = NULL;
301 static MenU     batchEditMenu = NULL;
302 static MenU     specialMenu = NULL;
303 static MenU     projectsMenu = NULL;
304 static MenU     analysisMenu = NULL;
305 static Boolean  initialFormsActive = FALSE;
306 #endif
307 
308 static ForM  initSubmitForm = NULL;
309 static ForM  formatForm = NULL;
310 static ForM  wizardChoiceForm = NULL;
311 
312 static Int2     subtoolTimerLimit = 100;
313 static Int2     subtoolTimerCount = 0;
314 static Boolean  subtoolRecordDirty = FALSE;
315 
316 static Boolean  testLatLonSubregion = FALSE;
317 static Boolean  strictLatLonCountry = FALSE;
318 
319 
320 #ifdef USE_SMARTNET
321 static Int4 SMWriteBioseqObj(VoidPtr bio_data, SMUserDataPtr sm_usr_data,
322                              VoidPtr data);
323 static Int4 SMReadBioseqObj(VoidPtr data, CharPtr buffer,
324                             Int4 length, void* fd);
325 #define SMART_KEY 1313
326 #define DUMB_KEY 1314
327 #endif
328 
329 
330 static FormatBlock globalFormatBlock = {SEQ_PKG_SINGLE, SEQ_FMT_FASTA, 0, SEQ_ORIG_SUBMISSION};
331 
332 ForM  helpForm = NULL;
333 
334 static CharPtr validFailMsg =
335 "Submission failed validation test.  Continue?\n\
336 (Choose Validate in the Search menu to see errors.)";
337 
338 
GetSequinAppParam(CharPtr section,CharPtr type,CharPtr dflt,CharPtr buf,Int2 buflen)339 extern Int2 GetSequinAppParam (CharPtr section, CharPtr type, CharPtr dflt, CharPtr buf, Int2 buflen)
340 
341 {
342   Int2  rsult;
343 
344   rsult = GetAppParam ("SEQUINCUSTOM", section, type, NULL, buf, buflen);
345   if (rsult) return rsult;
346   rsult = GetAppParam ("SEQUIN", section, type, dflt, buf, buflen);
347   return rsult;
348 }
349 
WriteSequinAppParam(CharPtr section,CharPtr type,CharPtr value)350 extern Boolean WriteSequinAppParam (CharPtr section, CharPtr type, CharPtr value)
351 
352 {
353   MsgAnswer  ans;
354 
355   if (indexerVersion) {
356     if (section == NULL) {
357       section = "";
358     }
359     if (type == NULL) {
360       type = "";
361     }
362     if (value == NULL) {
363       value = "";
364     }
365     ans = Message (MSG_OKC, "Writing to local .sequinrc configuration file - [%s] %s = %s", section, type, value);
366     if (ans == ANS_CANCEL) return FALSE;
367   }
368   return SetAppParam ("SEQUIN", section, type, value);
369 }
370 
SetSequinAppParam(CharPtr section,CharPtr type,CharPtr value)371 static Boolean SetSequinAppParam (CharPtr section, CharPtr type, CharPtr value)
372 
373 {
374   Char  tmp [32];
375 
376   if (GetAppParam ("SEQUINCUSTOM", section, type, NULL, tmp, sizeof (tmp) - 1)) {
377     return SetAppParam ("SEQUINCUSTOM", section, type, value);
378   }
379   return WriteSequinAppParam (section, type, value);
380 }
381 
ShowWizardHelpText(CharPtr title,CharPtr PNTR msgs)382 static void ShowWizardHelpText (CharPtr title, CharPtr PNTR msgs)
383 {
384   Char         path [PATH_MAX];
385   FILE         *fp;
386   Int4         i;
387 
388   TmpNam (path);
389   fp = FileOpen (path, "wb");
390   if (fp != NULL) {
391     for (i = 0; msgs[i] != NULL; i++) {
392       fprintf (fp, "%s", msgs[i]);
393     }
394   }
395   FileClose (fp);
396   LaunchGeneralTextViewer (path, title);
397   FileRemove (path);
398 }
399 
400 
CheckForCookedBioseqs(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)401 static void CheckForCookedBioseqs (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
402 
403 {
404   BoolPtr    bp;
405   BioseqPtr  bsp;
406 
407   if (sep == NULL) return;
408   if (! IS_Bioseq (sep)) return;
409   bp = (BoolPtr) mydata;
410   if (bp == NULL) return;
411   bsp = (BioseqPtr) sep->data.ptrvalue;
412   if (bsp == NULL) return;
413   if (bsp->repr != Seq_repr_raw && bsp->repr != Seq_repr_seg &&
414   	bsp->repr != Seq_repr_delta && bsp->repr != Seq_repr_virtual) {
415     *bp = FALSE;
416   }
417 }
418 
419 static void TaxonValidate (SeqEntryPtr sep, ValidStructPtr vsp);
420 static void StructCommentTentativeNameValidate (SeqEntryPtr sep, ValidStructPtr vsp);
421 
422 
423 typedef enum {
424   eOkToWriteEntity_Cancel = 0,
425   eOkToWriteEntity_Continue,
426   eOkToWriteEntity_Validate
427 } EOkToWriteEntity;
428 
GetValidationCancelContinue(ValidStructPtr vsp,Boolean allow_review)429 static EOkToWriteEntity GetValidationCancelContinue (ValidStructPtr vsp, Boolean allow_review)
430 {
431   WindoW w;
432   GrouP  h, c, prompts;
433   PrompT p1, p2;
434   ButtoN b;
435   ModalAcceptCancelData acd;
436   CharPtr msg, msg_format = "Reject %d, Error %d, Warning %d, Info %d";
437   EOkToWriteEntity rval = eOkToWriteEntity_Cancel;
438 
439   acd.accepted = FALSE;
440   acd.cancelled = FALSE;
441   acd.third_option = FALSE;
442 
443   w = ModalWindow(-20, -13, -10, -10, NULL);
444   h = HiddenGroup (w, -1, 0, NULL);
445   SetGroupSpacing (h, 10, 10);
446 
447   prompts = HiddenGroup (h, -1, 0, NULL);
448   SetGroupSpacing (prompts, 10, 10);
449   p1 = StaticPrompt (prompts, "Submission failed validation test with:", 0, 0, programFont, 'l');
450 
451   msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (msg_format) + 75));
452   sprintf (msg, msg_format,
453               (int) vsp->errors [4], (int) vsp->errors [3],
454               (int) vsp->errors [2], (int) vsp->errors [1]);
455   p2 = StaticPrompt (h, msg, 0, 0, programFont, 'l');
456   msg = MemFree (msg);
457   AlignObjects (ALIGN_CENTER, (HANDLE) p1, (HANDLE) p2, NULL);
458 
459   c = HiddenGroup (h, 3, 0, NULL);
460   SetGroupSpacing (c, 10, 10);
461   b = PushButton (c, "Continue", ModalAcceptButton);
462   SetObjectExtra (b, &acd, NULL);
463   if (allow_review) {
464     b = PushButton (c, "Review Errors", ModalThirdOptionButton);
465     SetObjectExtra (b, &acd, NULL);
466   }
467   b = PushButton (c, "Cancel", ModalCancelButton);
468   SetObjectExtra (b, &acd, NULL);
469   AlignObjects (ALIGN_CENTER, (HANDLE) prompts, (HANDLE) c, NULL);
470 
471   Show(w);
472   Select (w);
473   while (!acd.accepted && ! acd.cancelled && ! acd.third_option)
474   {
475     ProcessExternalEvent ();
476     Update ();
477   }
478   ProcessAnEvent ();
479   Remove (w);
480   if (acd.third_option)
481   {
482     rval = eOkToWriteEntity_Validate;
483   }
484   else if (acd.accepted)
485   {
486     rval = eOkToWriteEntity_Continue;
487   }
488   else
489   {
490     rval = eOkToWriteEntity_Cancel;
491   }
492   return rval;
493 }
494 
495 
496 static Boolean SequinValidateSeqEntry (SeqEntryPtr sep, ValidStructPtr vsp);
497 
498 /*
499 static void SmartnetDebug (CharPtr str)
500 
501 {
502   if (! debugsmartnet) return;
503   if (StringHasNoText (str)) return;
504 
505   Message (MSG_POST, "%s", str);
506 }
507 */
508 
OkayToWriteTheEntity(Uint2 entityID,ForM f,Boolean allow_review)509 static EOkToWriteEntity OkayToWriteTheEntity (Uint2 entityID, ForM f, Boolean allow_review)
510 
511 {
512   Boolean          allRawOrSeg = TRUE;
513   EOkToWriteEntity rval = eOkToWriteEntity_Continue;
514   Int2             errors;
515   Int2             j;
516   ErrSev           oldErrSev;
517   SeqEntryPtr      sep;
518   Char             str [32];
519   ValidStructPtr   vsp;
520 
521   if (entityID < 1) return 0;
522   sep = GetTopSeqEntryForEntityID (entityID);
523   if (sep == NULL) return 0;
524 
525   if (!FixSpecialCharacters (entityID)) return 0;
526 
527   if (GetSequinAppParam ("PREFERENCES", "ASKBEFOREVALIDATE", NULL, str, sizeof (str))) {
528     if (StringICmp (str, "TRUE") == 0) {
529       if (! (subtoolMode ||smartnetMode || backupMode) ) {
530         if (Message (MSG_YN, "Do you wish to validate this entry?") == ANS_NO) return 1;
531       }
532     }
533   }
534 
535   WatchCursor ();
536   Update ();
537 
538   vsp = ValidStructNew ();
539   if (vsp != NULL) {
540     /*SetChecklistValue (checklistForm, 6);*/
541     SeqEntryExplore (sep, (Pointer) (&allRawOrSeg), CheckForCookedBioseqs);
542     if (allRawOrSeg) {
543       vsp->useSeqMgrIndexes = TRUE;
544     }
545     if (indexerVersion) {
546       vsp->alwaysRequireIsoJTA = TRUE;
547       if (smartnetMode) {
548         vsp->farFetchCDSproducts = TRUE;
549         vsp->farFetchMRNAproducts = TRUE;
550       }
551     }
552 
553     oldErrSev = ErrSetMessageLevel (SEV_MAX);
554     /*
555     vsp->validateAlignments = TRUE;
556     vsp->alignFindRemoteBsp = TRUE;
557     */
558     vsp->doSeqHistAssembly = FALSE;
559     if (smartnetMode) {
560       /*
561       vsp->doSeqHistAssembly = TRUE;
562       vsp->farIDsInAlignments = TRUE;
563       */
564       if (useEntrez) {
565         /*
566         LookupFarSeqIDs (sep, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
567         vsp->inferenceAccnCheck = TRUE;
568         */
569       }
570     }
571     /*
572     vsp->testLatLonSubregion = testLatLonSubregion;
573     vsp->strictLatLonCountry = strictLatLonCountry;
574     */
575     vsp->indexerVersion = indexerVersion;
576     for (j = 0; j < 6; j++) {
577       vsp->errors [j] = 0;
578     }
579 
580     SequinValidateSeqEntry (sep, vsp);
581     if (indexerVersion && useEntrez) {
582       TaxonValidate (sep, vsp);
583     }
584 
585     ErrSetMessageLevel (oldErrSev);
586     ErrClear ();
587     ErrShow ();
588     errors = 0;
589     if (subtoolMode || smartnetMode || backupMode) {
590       for (j = 0; j < 6; j++) {
591         errors += vsp->errors [j];
592       }
593     } else {
594       for (j = 3; j < 6; j++) {
595         errors += vsp->errors [j];
596       }
597     }
598 
599     UseWindow ((WindoW) f);
600     if (errors > 0) {
601       ArrowCursor ();
602       Update ();
603       if (subtoolMode || smartnetMode || backupMode) {
604         rval = GetValidationCancelContinue (vsp, allow_review);
605       } else {
606         if (Message (MSG_OKC, validFailMsg) == ANS_CANCEL) {
607           rval = eOkToWriteEntity_Cancel;
608         }
609       }
610     }
611     ValidStructFree (vsp);
612   }
613 
614   ArrowCursor ();
615   Update ();
616 
617   return rval;
618 }
619 
UncompressBsps(BioseqPtr bsp,Pointer userdata)620 static void UncompressBsps (BioseqPtr bsp, Pointer userdata)
621 
622 {
623   if (ISA_na (bsp->mol)) {
624     BioseqConvert (bsp, Seq_code_iupacna);
625   } else if (ISA_aa (bsp->mol)) {
626     BioseqConvert (bsp, Seq_code_ncbieaa);
627   }
628 }
629 
WriteTheEntityID(Uint2 entityID,CharPtr path,Boolean binary)630 extern Boolean WriteTheEntityID (Uint2 entityID, CharPtr path, Boolean binary)
631 
632 {
633   AsnIoPtr       aip;
634   BioseqPtr      bsp;
635   BioseqSetPtr   bssp;
636   ObjMgrDataPtr  omdp;
637   Boolean        rsult;
638   SeqEntryPtr    sep;
639   SeqSubmitPtr   ssp;
640   Char           str [16];
641 #ifdef WIN_MAC
642   FILE           *f;
643 #endif
644 
645   rsult = FALSE;
646   if (entityID < 1) return rsult;
647   if (path == NULL || path [0] == '\0') return rsult;
648   ssp = NULL;
649   sep = NULL;
650   bsp = NULL;
651   bssp = NULL;
652   omdp = ObjMgrGetData (entityID);
653   if (omdp == NULL) return rsult;
654   WatchCursor ();
655   Update ();
656 #ifdef WIN_MAC
657   f = FileOpen (path, "r");
658   if (f != NULL) {
659     FileClose (f);
660   } else {
661     FileCreate (path, "TEXT", "ttxt");
662   }
663 #endif
664   if (GetSequinAppParam ("PREFERENCES", "UNCOMPRESS", NULL, str, sizeof (str))) {
665     if (StringICmp (str, "TRUE") == 0) {
666       sep = GetTopSeqEntryForEntityID (entityID);
667       VisitBioseqsInSep (sep, NULL, UncompressBsps);
668       /*
669       SeqEntryConvert (sep, Seq_code_iupacna);
670       SeqEntryConvert (sep, Seq_code_ncbieaa);
671       */
672     }
673   }
674   if (binseqentryMode) {
675     aip = AsnIoOpen (path, "w");
676     sep = GetTopSeqEntryForEntityID (entityID);
677     rsult = SeqEntryAsnWrite (sep, aip, NULL);
678     AsnIoClose (aip);
679     ArrowCursor ();
680     Update ();
681     return rsult;
682   }
683   sep = NULL;
684   if (binary) {
685     aip = AsnIoOpen (path, "wb");
686   } else {
687     aip = AsnIoOpen (path, "w");
688   }
689   if (aip != NULL) {
690     switch (omdp->datatype) {
691       case OBJ_SEQSUB :
692         ssp = (SeqSubmitPtr) omdp->dataptr;
693         if (ssp != NULL && ssp->datatype == 1) {
694           rsult = SeqSubmitAsnWrite (ssp, aip, NULL);
695         }
696         break;
697       case OBJ_BIOSEQ :
698         sep = (SeqEntryPtr) omdp->choice;
699         if (sep != NULL && sep->choice == 1 && sep->data.ptrvalue != NULL) {
700           if (subtoolMode || bioseqsetMode) {
701             bsp = (BioseqPtr) sep->data.ptrvalue;
702             rsult = BioseqAsnWrite (bsp, aip, NULL);
703           } else {
704             rsult = SeqEntryAsnWrite (sep, aip, NULL);
705           }
706         }
707         break;
708       case OBJ_BIOSEQSET :
709         sep =  (SeqEntryPtr) omdp->choice;
710         if (sep != NULL && sep->choice == 2 && sep->data.ptrvalue != NULL) {
711           if (subtoolMode || bioseqsetMode) {
712             bssp = (BioseqSetPtr) sep->data.ptrvalue;
713             rsult = BioseqSetAsnWrite (bssp, aip, NULL);
714           } else {
715             rsult = SeqEntryAsnWrite (sep, aip, NULL);
716           }
717         }
718         break;
719       case OBJ_SEQENTRY :
720         sep =  (SeqEntryPtr) omdp->choice;
721         if (sep != NULL) {
722           rsult = SeqEntryAsnWrite (sep, aip, NULL);
723         }
724         break;
725       default :
726         break;
727     }
728     AsnIoClose (aip);
729     if (! smartnetMode) {
730       ObjMgrSetDirtyFlag (entityID, FALSE);
731     }
732   }
733   ArrowCursor ();
734   Update ();
735   return rsult;
736 }
737 
ExtractGivenSeqDescrUserObject(ValNodePtr PNTR headptr,CharPtr str,CharPtr cls)738 static ValNodePtr ExtractGivenSeqDescrUserObject (ValNodePtr PNTR headptr, CharPtr str, CharPtr cls)
739 
740 {
741   Boolean        extract_it;
742   ValNodePtr     last = NULL, vnp;
743   ObjectIdPtr    oip;
744   UserObjectPtr  uop;
745 
746   if (headptr == NULL) return NULL;
747   vnp = *headptr;
748 
749   while (vnp != NULL) {
750     extract_it = FALSE;
751     if (vnp->choice == Seq_descr_user) {
752       uop = (UserObjectPtr) vnp->data.ptrvalue;
753       if (uop != NULL) {
754         if (StringDoesHaveText (cls)) {
755           if (StringICmp (uop->_class, cls) == 0) {
756             extract_it = TRUE;
757           }
758         }
759         if (StringDoesHaveText (str)) {
760           oip = uop->type;
761           if (oip != NULL) {
762             if (StringICmp (oip->str, str) == 0) {
763               extract_it = TRUE;
764             }
765           }
766         }
767       }
768     }
769     if (extract_it) {
770       if (last == NULL) {
771         *headptr = vnp->next;
772       } else {
773         last->next = vnp->next;
774       }
775       vnp->next = NULL;
776       return vnp;
777     } else {
778       last = vnp;
779       vnp = vnp->next;
780     }
781   }
782 
783   return NULL;
784 }
785 
786 typedef struct propgenbankdata {
787   Boolean  ask;
788   Boolean  asked;
789   Boolean  bail;
790   Boolean  changed;
791 } PropGenbankData, PNTR PropGenBankPtr;
792 
DoPropagateFromGenBankBioseqSet(BioseqSetPtr seqset,Pointer userdata)793 static void DoPropagateFromGenBankBioseqSet (
794   BioseqSetPtr seqset,
795   Pointer userdata
796 )
797 
798 {
799   BioseqPtr       bsp;
800   BioseqSetPtr    bssp;
801   PropGenBankPtr  pgp;
802   SeqEntryPtr     seqentry;
803   ValNodePtr      smartuserobj;
804   ValNodePtr      sourcedescr;
805   UserObjectPtr   uop;
806 
807   if (seqset == NULL) return;
808   if (seqset->_class != BioseqseqSet_class_genbank) return;
809   pgp = (PropGenBankPtr) userdata;
810   if (pgp == NULL) return;
811 
812   seqentry = seqset->seq_set;
813   sourcedescr = seqset->descr;
814   if (sourcedescr == NULL) return;
815 
816   /* if only descriptor is tracking user object, skip */
817   if (sourcedescr->next == NULL && sourcedescr->choice == Seq_descr_user) {
818     uop = (UserObjectPtr) sourcedescr->data.ptrvalue;
819     if (uop != NULL && StringICmp (uop->_class, "SMART_V1.0") == 0) return;
820   }
821 
822   /* optionally ask if propagation is desired */
823   if (pgp->ask) {
824     if (! pgp->asked) {
825       if (Message (MSG_YN, "Propagate descriptors from top-level set?") == ANS_NO) {
826         pgp->bail = TRUE;
827       }
828       pgp->asked = TRUE;
829     }
830   }
831   if (pgp->bail) return;
832 
833   /* disconnect descriptors from parent bssp */
834   seqset->descr = NULL;
835 
836   /* extract tracking user object */
837   smartuserobj = ExtractGivenSeqDescrUserObject (&sourcedescr, NULL, "SMART_V1.0");
838 
839   while (seqentry != NULL) {
840     if (seqentry->data.ptrvalue != NULL) {
841       if (seqentry->choice == 1) {
842         bsp = (BioseqPtr) seqentry->data.ptrvalue;
843         ValNodeLink (&(bsp->descr),
844                      AsnIoMemCopy ((Pointer) sourcedescr,
845                                    (AsnReadFunc) SeqDescrAsnRead,
846                                    (AsnWriteFunc) SeqDescrAsnWrite));
847       } else if (seqentry->choice == 2) {
848         bssp = (BioseqSetPtr) seqentry->data.ptrvalue;
849         ValNodeLink (&(bssp->descr),
850                      AsnIoMemCopy ((Pointer) sourcedescr,
851                                    (AsnReadFunc) SeqDescrAsnRead,
852                                    (AsnWriteFunc) SeqDescrAsnWrite));
853       }
854       pgp->changed = TRUE;
855     }
856     seqentry = seqentry->next;
857   }
858 
859   /* free extracted original descriptors now that copies are propagated */
860   SeqDescrFree (sourcedescr);
861 
862   /* restore tracking user object */
863   if (smartuserobj != NULL) {
864     ValNodeLink (&(seqset->descr), smartuserobj);
865   }
866 
867   /* recurse */
868   VisitSetsInSet (seqset, userdata, DoPropagateFromGenBankBioseqSet);
869 }
870 
PropagateFromGenBankBioseqSet(SeqEntryPtr sep,Boolean ask)871 extern Boolean PropagateFromGenBankBioseqSet (SeqEntryPtr sep, Boolean ask)
872 
873 {
874   BioseqSetPtr     bssp;
875   PropGenbankData  pdp;
876 
877   if (sep == NULL) return FALSE;
878   if (! IS_Bioseq_set (sep)) return FALSE;
879 
880   bssp = (BioseqSetPtr) sep->data.ptrvalue;
881   if (bssp == NULL) return FALSE;
882   if (bssp->_class != BioseqseqSet_class_genbank) return FALSE;
883 
884   MemSet ((Pointer) &pdp, 0, sizeof (PropGenbankData));
885   pdp.ask = ask;
886   pdp.asked = FALSE;
887   pdp.bail = FALSE;
888   pdp.changed = FALSE;
889 
890   DoPropagateFromGenBankBioseqSet (bssp, (Pointer) &pdp);
891 
892   return pdp.changed;
893 }
894 
ForcePropagate(IteM i)895 static void ForcePropagate (IteM i)
896 
897 {
898   BaseFormPtr  bfp;
899   SeqEntryPtr  sep;
900 
901 #ifdef WIN_MAC
902   bfp = (BaseFormPtr) currentFormDataPtr;
903 #else
904   bfp = (BaseFormPtr) GetObjectExtra (i);
905 #endif
906   if (bfp == NULL) return;
907   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
908   if (sep == NULL) return;
909   PropagateFromGenBankBioseqSet (sep, FALSE);
910   NormalizeDescriptorOrder (sep);
911   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
912   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
913 }
914 
915 #define SEQUIN_EDIT_TEMP_FILE "sequinEdit.temp"
916 #define SEQUIN_EDIT_BACK_FILE "sequinEdit.back"
917 #define SEQUIN_EDIT_PREV_FILE "sequinEdit.prev"
918 #define SEQUIN_EDIT_ARCH_FILE "sequinEdit.arch"
919 
920 
ResetSubtoolTimerLimit(void)921 static void ResetSubtoolTimerLimit (void)
922 {
923   Char           str [80];
924   Int2           val;
925 
926   if (GetSequinAppParam ("SETTINGS", "TIMERLIMIT", NULL, str, sizeof (str))) {
927     if (StrToInt (str, &val) && val >= 0) {
928       subtoolTimerLimit = val;
929     }
930   } else {
931     subtoolTimerLimit = 100;
932   }
933 }
934 
SubtoolModeTimerProc(void)935 static void SubtoolModeTimerProc (void)
936 
937 {
938   ObjMgrDataPtr  omdp;
939   time_t write_start, write_stop, elapse;
940 
941   subtoolTimerCount++;
942   if (subtoolTimerCount > subtoolTimerLimit) {
943     subtoolTimerCount = 0;
944     if (subtoolRecordDirty) {
945       omdp = ObjMgrGetData (subtoolEntityID);
946       if (omdp != NULL) {
947         write_start = time(NULL);
948         if (WriteTheEntityID (subtoolEntityID, SEQUIN_EDIT_TEMP_FILE, FALSE)) {
949           FileRemove (SEQUIN_EDIT_PREV_FILE);
950           FileRename (SEQUIN_EDIT_BACK_FILE, SEQUIN_EDIT_PREV_FILE);
951           FileRename (SEQUIN_EDIT_TEMP_FILE, SEQUIN_EDIT_BACK_FILE);
952         } else {
953           Message (MSG_POSTERR, "Unable to save automatic temporary file");
954         }
955         write_stop = time(NULL);
956         elapse = write_stop - write_start;
957         if (elapse > .9 * subtoolTimerLimit) {
958           subtoolTimerLimit = (Int2) (3 * elapse);
959         } else if (subtoolTimerLimit > 100) {
960           ResetSubtoolTimerLimit ();
961         }
962       }
963       subtoolRecordDirty = FALSE;
964     }
965   }
966   SequinCheckSocketsProc ();
967 }
968 
SubtoolModeMsgFunc(OMMsgStructPtr ommsp)969 static Int2 LIBCALLBACK SubtoolModeMsgFunc (OMMsgStructPtr ommsp)
970 
971 {
972   switch (ommsp->message) {
973     case OM_MSG_DEL :
974     case OM_MSG_CREATE :
975     case OM_MSG_UPDATE :
976       subtoolRecordDirty = TRUE;
977       break;
978     default :
979       break;
980   }
981   return OM_MSG_RET_OK;
982 }
983 
BackupModeTimerProc(void)984 static void BackupModeTimerProc (void)
985 
986 {
987   ObjMgrDataPtr  omdp;
988 
989   subtoolTimerCount++;
990   if (subtoolTimerCount > subtoolTimerLimit) {
991     subtoolTimerCount = 0;
992     if (subtoolRecordDirty && subtoolEntityID > 0) {
993       omdp = ObjMgrGetData (subtoolEntityID);
994       if (omdp != NULL) {
995         if (WriteTheEntityID (subtoolEntityID, SEQUIN_EDIT_TEMP_FILE, FALSE)) {
996           FileRemove (SEQUIN_EDIT_PREV_FILE);
997           FileRename (SEQUIN_EDIT_BACK_FILE, SEQUIN_EDIT_PREV_FILE);
998           FileRename (SEQUIN_EDIT_TEMP_FILE, SEQUIN_EDIT_BACK_FILE);
999         } else {
1000           Message (MSG_POSTERR, "Unable to save automatic temporary file");
1001         }
1002       }
1003       subtoolRecordDirty = FALSE;
1004     }
1005   }
1006   SequinCheckSocketsProc ();
1007 }
1008 
BackupModeMsgFunc(OMMsgStructPtr ommsp)1009 static Int2 LIBCALLBACK BackupModeMsgFunc (OMMsgStructPtr ommsp)
1010 
1011 {
1012   switch (ommsp->message) {
1013     case OM_MSG_DEL :
1014     case OM_MSG_CREATE :
1015     case OM_MSG_UPDATE :
1016       subtoolRecordDirty = TRUE;
1017       break;
1018     default :
1019       break;
1020   }
1021   return OM_MSG_RET_OK;
1022 }
1023 
GetDefaultTitleFromForm(ForM f,CharPtr str,size_t maxsize,CharPtr filepath)1024 static void GetDefaultTitleFromForm (ForM f, CharPtr str, size_t maxsize, CharPtr filepath)
1025 
1026 {
1027   Char     ch;
1028   Char     dfault [64];
1029   Int2     j;
1030   Int2     k;
1031   CharPtr  ptr;
1032 
1033   if (f != NULL && str != NULL && maxsize > 0) {
1034     dfault [0] = '\0';
1035     if (StringHasNoText (filepath)) {
1036       GetTitle (f, dfault, sizeof (dfault));
1037     } else {
1038       ptr = StringRChr (filepath, DIRDELIMCHR);
1039       if (ptr != NULL) {
1040         ptr++;
1041         StringNCpy_0 (dfault, ptr, sizeof (dfault));
1042       } else {
1043         StringNCpy_0 (dfault, filepath, sizeof (dfault));
1044       }
1045     }
1046     j = 0;
1047     k = 0;
1048     ch = dfault [j];
1049     while (j < sizeof (dfault) && ch != '\0') {
1050       if (ch <= ' ') {
1051         j++;
1052       } else {
1053         dfault [k] = dfault [j];
1054         k++;
1055         j++;
1056       }
1057       ch = dfault [j];
1058     }
1059     dfault [k] = '\0';
1060 #ifdef WIN_MSWIN
1061     j = 0;
1062     ch = dfault [j];
1063     while (j < sizeof (dfault) && ch != '\0') {
1064       if (ch == '_' || IS_ALPHANUM (ch)) {
1065         j++;
1066         ch = dfault [j];
1067       } else {
1068         ch = '\0';
1069       }
1070     }
1071     dfault [j] = '\0';
1072 #endif
1073     StringNCpy_0 (str, dfault, maxsize);
1074   }
1075 }
1076 
1077 static CharPtr gbsub = "gb-sub@ncbi.nlm.nih.gov";
1078 static CharPtr emblsub = "datasubs@ebi.ac.uk";
1079 static CharPtr ddbjsub = "ddbjsub@ddbj.nig.ac.jp";
1080 
1081 static CharPtr gbupd = "gb-admin@ncbi.nlm.nih.gov";
1082 static CharPtr emblupd = "update@ebi.ac.uk";
1083 static CharPtr ddbjupd = "ddbjupdt@ddbj.nig.ac.jp";
1084 
ReturnSubmissionEmailAddress(Uint2 entityID)1085 static CharPtr ReturnSubmissionEmailAddress (Uint2 entityID)
1086 
1087 {
1088   ObjMgrDataPtr   omdp;
1089   CharPtr         rsult;
1090   SubmitBlockPtr  sbp;
1091   SeqSubmitPtr    ssp;
1092   Char            str [32];
1093   Boolean         update = FALSE;
1094 
1095   rsult = gbsub;
1096   omdp = ObjMgrGetData (entityID);
1097   if (omdp != NULL && omdp->datatype == OBJ_SEQSUB) {
1098     ssp = (SeqSubmitPtr) omdp->dataptr;
1099     if (ssp != NULL && ssp->datatype == 1) {
1100       sbp = ssp->sub;
1101       if (sbp != NULL && sbp->subtype == 2) {
1102         update = TRUE;
1103       }
1104     }
1105   }
1106   if (GetAppParam ("SEQUIN", "PREFERENCES", "DATABASE", NULL, str, sizeof (str))) {
1107     if (StringICmp (str, "GenBank") == 0) {
1108       if (update) {
1109         rsult = gbupd;
1110       } else {
1111         rsult = gbsub;
1112       }
1113     } else if (StringICmp (str, "EMBL") == 0) {
1114       if (update) {
1115         rsult = emblupd;
1116       } else {
1117         rsult = emblsub;
1118       }
1119     } else if (StringICmp (str, "DDBJ") == 0) {
1120       if (update) {
1121         rsult = ddbjupd;
1122       } else {
1123         rsult = ddbjsub;
1124       }
1125     }
1126   }
1127   return rsult;
1128 }
1129 
DoRemoveAlignmentFromRecord(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)1130 static void DoRemoveAlignmentFromRecord (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
1131 
1132 {
1133   BioseqPtr     bsp;
1134   BioseqSetPtr  bssp;
1135   SeqAnnotPtr   nextsap;
1136   Pointer PNTR  prevsap;
1137   SeqAnnotPtr   sap;
1138 
1139   if (IS_Bioseq (sep)) {
1140     bsp = (BioseqPtr) sep->data.ptrvalue;
1141     sap = bsp->annot;
1142     prevsap = (Pointer PNTR) &(bsp->annot);
1143   } else if (IS_Bioseq_set (sep)) {
1144     bssp = (BioseqSetPtr) sep->data.ptrvalue;
1145     sap = bssp->annot;
1146     prevsap = (Pointer PNTR) &(bssp->annot);
1147   } else return;
1148   while (sap != NULL) {
1149     nextsap = sap->next;
1150     if (sap->type == 2) {
1151       *(prevsap) = sap->next;
1152       sap->next = NULL;
1153       SeqAnnotFree (sap);
1154     } else {
1155       prevsap = (Pointer PNTR) &(sap->next);
1156     }
1157     sap = nextsap;
1158   }
1159 }
1160 
1161 extern void SubmitToNCBI (IteM i);
1162 
MissingAnnotCallback(BioseqPtr bsp,Pointer userdata)1163 static void MissingAnnotCallback (BioseqPtr bsp, Pointer userdata)
1164 {
1165   BoolPtr p_missing;
1166   SeqFeatPtr sfp;
1167   SeqMgrFeatContext fcontext;
1168 
1169   if (bsp == NULL || ISA_aa (bsp->mol) || userdata == NULL) {
1170     return;
1171   }
1172   p_missing = (BoolPtr) userdata;
1173   if (*p_missing) {
1174     return;
1175   }
1176   sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
1177   if (sfp == NULL) {
1178     *p_missing = TRUE;
1179   }
1180 }
1181 
1182 
IsAnySequenceMissingAnnotation(SeqEntryPtr sep)1183 static Boolean IsAnySequenceMissingAnnotation (SeqEntryPtr sep)
1184 {
1185   Boolean rval = FALSE;
1186 
1187   VisitBioseqsInSep (sep, &rval, MissingAnnotCallback);
1188   return rval;
1189 }
1190 
1191 
PrepareSeqSubmitProc(IteM i)1192 static void PrepareSeqSubmitProc (IteM i)
1193 
1194 {
1195   BaseFormPtr  bfp;
1196   Char         dfault [64];
1197   Char         path [PATH_MAX];
1198   CharPtr      ptr;
1199   SeqEntryPtr  sep;
1200   CharPtr      str, email_address;
1201   Boolean      update;
1202   CharPtr      fmt_file = "Submission is now written.  Please e-mail '%s' to %s.%s";
1203   CharPtr      fmt_no_file = "Submission is now written.  Please e-mail to %s.%s";
1204   CharPtr      missing_annot = "  Please include a brief summary of your submission within your correspondence.";
1205   CharPtr      note = "";
1206 
1207 #ifdef WIN_MAC
1208   bfp = (BaseFormPtr) currentFormDataPtr;
1209 #else
1210   bfp = (BaseFormPtr) GetObjectExtra (i);
1211 #endif
1212   update = FALSE;
1213   if (bfp != NULL) {
1214     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1215     if (sep != NULL) {
1216       SeqEntryPack (sep);
1217       EntryChangeGBSource (sep);
1218       EntryCheckGBBlock (sep);
1219       GetRidOfEmptyFeatsDescStrings (0, sep);
1220       GetRidOfLocusInSeqIds (0, sep);
1221       if (OkayToWriteTheEntity (bfp->input_entityID, bfp->form, FALSE) == eOkToWriteEntity_Continue) {
1222         /*SetChecklistValue (checklistForm, 7);*/
1223         path [0] = '\0';
1224         StringNCpy_0 (path, bfp->filepath, sizeof (path));
1225         dfault [0] = '\0';
1226         GetDefaultTitleFromForm (bfp->form, dfault, sizeof (dfault), bfp->filepath);
1227         ptr = StringRChr (dfault, '.');
1228         if (ptr != NULL) {
1229           *ptr = '\0';
1230         }
1231         if (StringLen (dfault) < sizeof (dfault) - 5) {
1232           StringCat (dfault, ".sqn");
1233         }
1234         if (GetOutputFileName (path, sizeof (path), dfault)) {
1235           update = PropagateFromGenBankBioseqSet (sep, TRUE);
1236           NormalizeDescriptorOrder (sep);
1237           update = TRUE; /* because of NormalizeDescriptorOrder */
1238           if (SeqEntryHasAligns (bfp->input_entityID, sep)) {
1239             if (Message (MSG_YN, "Remove alignments?") == ANS_YES) {
1240               SeqEntryExplore (sep, NULL, DoRemoveAlignmentFromRecord);
1241               update = TRUE;
1242             }
1243           }
1244           SeqMgrClearFeatureIndexes (bfp->input_entityID, NULL);
1245           if (WriteTheEntityID (bfp->input_entityID, path, FALSE)) {
1246             email_address = ReturnSubmissionEmailAddress (bfp->input_entityID);
1247             if (IsAnySequenceMissingAnnotation (sep)) {
1248               note = missing_annot;
1249             }
1250             /*SetChecklistValue (checklistForm, 5);*/
1251             ptr = StringRChr (path, DIRDELIMCHR);
1252             if (ptr != NULL) {
1253               ptr++;
1254               str = MemNew (sizeof (Char) * (StringLen (ptr) + StringLen (fmt_file) + StringLen (email_address) + StringLen (note)));
1255               if (str != NULL) {
1256                 sprintf (str, fmt_file, ptr, email_address, note);
1257                 UseWindow ((WindoW) bfp->form);
1258                 Message (MSG_OK, str);
1259                 MemFree (str);
1260                 if (update) {
1261                   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1262                 }
1263                 return;
1264               }
1265             }
1266             str = MemNew (sizeof (Char) * (StringLen (fmt_file) + StringLen (email_address) + StringLen (note)));
1267             if (str != NULL) {
1268               sprintf (str, fmt_no_file, email_address, note);
1269               UseWindow ((WindoW) bfp->form);
1270               Message (MSG_OK, str);
1271               MemFree (str);
1272             }
1273           } else {
1274             UseWindow ((WindoW) bfp->form);
1275             Message (MSG_ERROR, "Unable to write file.");
1276           }
1277         } else {
1278           /*SetChecklistValue (checklistForm, 5);*/
1279           UseWindow ((WindoW) bfp->form);
1280         }
1281       }
1282     }
1283     if (update) {
1284       ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1285     }
1286   }
1287 }
1288 
SaveSeqSubmitProc(BaseFormPtr bfp,Boolean saveAs)1289 extern Boolean SaveSeqSubmitProc (BaseFormPtr bfp, Boolean saveAs)
1290 
1291 {
1292   Char         dfault [32];
1293   Char         path [PATH_MAX];
1294   CharPtr      ptr;
1295   SeqEntryPtr  sep;
1296   Char         suffix [32];
1297   Char         tmp [32];
1298   Boolean      update;
1299 
1300   if (bfp != NULL) {
1301     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1302     if (sep != NULL) {
1303       SeqEntryPack (sep);
1304       EntryChangeGBSource (sep);
1305       EntryCheckGBBlock (sep);
1306       GetRidOfEmptyFeatsDescStrings (0, sep);
1307       GetRidOfLocusInSeqIds (0, sep);
1308       path [0] = '\0';
1309       StringNCpy_0 (path, bfp->filepath, sizeof (path));
1310       if (StringHasNoText (path) || saveAs) {
1311         dfault [0] = '\0';
1312         GetDefaultTitleFromForm (bfp->form, dfault, sizeof (dfault), bfp->filepath);
1313         ptr = StringRChr (dfault, '.');
1314         if (ptr != NULL) {
1315           *ptr = '\0';
1316         }
1317         suffix [0] = '\0';
1318         if (GetSequinAppParam ("PREFERENCES", "SUFFIX", ".sqn", tmp, sizeof (tmp))) {
1319           if (tmp [0] == '.') {
1320             StringNCpy_0 (suffix, tmp, sizeof (suffix));
1321           } else {
1322             StringCpy (suffix, ".");
1323             StringNCpy_0 (suffix + 1, tmp, sizeof (suffix) - 1);
1324           }
1325         }
1326         if (StringLen (dfault) < sizeof (dfault) - StringLen (suffix)) {
1327           StringCat (dfault, suffix);
1328         }
1329         if (! (GetOutputFileName (path, sizeof (path), dfault))) return FALSE;
1330       }
1331       update = PropagateFromGenBankBioseqSet (sep, TRUE);
1332       NormalizeDescriptorOrder (sep);
1333       update = TRUE; /* because of NormalizeDescriptorOrder */
1334       SeqMgrClearFeatureIndexes (bfp->input_entityID, NULL);
1335       if (WriteTheEntityID (bfp->input_entityID, path, FALSE)) {
1336         bfp->filepath = MemFree (bfp->filepath);
1337         bfp->filepath = StringSave (path);
1338         if (update) {
1339           ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1340         }
1341         return TRUE;
1342       } else {
1343         Message (MSG_ERROR, "Unable to write file.");
1344         if (update) {
1345           ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1346         }
1347         return FALSE;
1348       }
1349     }
1350   }
1351   return FALSE;
1352 }
1353 
SaveBinSeqEntry(IteM i)1354 static void SaveBinSeqEntry (IteM i)
1355 
1356 {
1357   BaseFormPtr  bfp;
1358   Char         dfault [32];
1359   Char         path [PATH_MAX];
1360   CharPtr      ptr;
1361   Boolean      saveAs = TRUE;
1362   SeqEntryPtr  sep;
1363   Boolean      update;
1364 
1365   bfp = (BaseFormPtr) GetObjectExtra (i);
1366   if (bfp != NULL) {
1367     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1368     if (sep != NULL) {
1369       SeqEntryPack (sep);
1370       EntryChangeGBSource (sep);
1371       EntryCheckGBBlock (sep);
1372       GetRidOfEmptyFeatsDescStrings (0, sep);
1373       GetRidOfLocusInSeqIds (0, sep);
1374       path [0] = '\0';
1375       StringNCpy_0 (path, bfp->filepath, sizeof (path));
1376       if (StringHasNoText (path) || saveAs) {
1377         dfault [0] = '\0';
1378         GetDefaultTitleFromForm (bfp->form, dfault, sizeof (dfault), bfp->filepath);
1379         ptr = StringRChr (dfault, '.');
1380         if (ptr != NULL) {
1381           *ptr = '\0';
1382         }
1383         if (StringLen (dfault) < sizeof (dfault) - 5) {
1384           StringCat (dfault, ".val");
1385         }
1386         if (! (GetOutputFileName (path, sizeof (path), dfault))) return;
1387       }
1388       update = PropagateFromGenBankBioseqSet (sep, TRUE);
1389       NormalizeDescriptorOrder (sep);
1390       update = TRUE; /* because of NormalizeDescriptorOrder */
1391       SeqMgrClearFeatureIndexes (bfp->input_entityID, NULL);
1392       if (WriteTheEntityID (bfp->input_entityID, path, TRUE)) {
1393         bfp->filepath = MemFree (bfp->filepath);
1394         bfp->filepath = StringSave (path);
1395         if (update) {
1396           ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1397         }
1398         return;
1399       } else {
1400         Message (MSG_ERROR, "Unable to write file.");
1401         if (update) {
1402           ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1403         }
1404       }
1405     }
1406   }
1407 }
1408 
1409 static CharPtr google_earth_1 =
1410   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
1411   "<kml xmlns=\"http://earth.google.com/kml/2.2\">\n" \
1412   "<Document>\n" \
1413   "  <name>KmlFile</name>\n" \
1414   "  <StyleMap id=\"default_copy0+nicon=http://maps.google.com/mapfiles/kml/pal3/icon60.png+hicon=http://maps.google.com/mapfiles/kml/pal3/icon52.png\">\n" \
1415   "    <Pair>\n" \
1416   "      <key>normal</key>\n" \
1417   "      <styleUrl>#default_copy0+icon=http://maps.google.com/mapfiles/kml/pal3/icon60.png</styleUrl>\n" \
1418   "    </Pair>\n" \
1419   "    <Pair>\n" \
1420   "      <key>highlight</key>\n" \
1421   "      <styleUrl>#default_copy0+icon=http://maps.google.com/mapfiles/kml/pal3/icon52.png</styleUrl>\n" \
1422   "    </Pair>\n" \
1423   "  </StyleMap>\n" \
1424   "  <Style id=\"default_copy0+icon=http://maps.google.com/mapfiles/kml/pal3/icon60.png\">\n" \
1425   "    <IconStyle>\n" \
1426   "      <Icon>\n" \
1427   "        <href>http://maps.google.com/mapfiles/kml/pal3/icon60.png</href>\n" \
1428   "      </Icon>\n" \
1429   "    </IconStyle>\n" \
1430   "  </Style>\n" \
1431   "  <Placemark>\n";
1432 
1433 static CharPtr google_earth_2 =
1434   "    <styleUrl>#default_copy0+nicon=http://maps.google.com/mapfiles/kml/pal3/icon60.png+hicon=http://maps.google.com/mapfiles/kml/pal3/icon52.png</styleUrl>\n" \
1435   "    <Point>\n";
1436 
1437 static CharPtr google_earth_3 =
1438   "    </Point>\n" \
1439   "  </Placemark>\n" \
1440   "</Document>\n" \
1441   "</kml>\n";
1442 
LaunchedGoogleEarth(Uint2 entityID,Uint4 itemID,Uint2 itemtype)1443 static Boolean LaunchedGoogleEarth (
1444   Uint2 entityID, Uint4 itemID, Uint2 itemtype
1445 )
1446 
1447 {
1448   BioSourcePtr       biop;
1449   SeqMgrDescContext  context;
1450   Boolean            format_ok = FALSE;
1451   FILE               *fp;
1452   FloatHi            lat = 0.0;
1453   FloatHi            lon = 0.0;
1454   CharPtr            lat_lon = NULL;
1455   Boolean            lat_in_range = FALSE;
1456   Boolean            lon_in_range = FALSE;
1457   Char               path [PATH_MAX];
1458   Boolean            precision_ok = FALSE;
1459   SeqDescPtr         sdp;
1460   SubSourcePtr       ssp;
1461 #ifdef OS_UNIX
1462   Char               cmmd [256];
1463 #endif
1464 
1465   if (itemtype != OBJ_SEQDESC) return FALSE;
1466 
1467   sdp = SeqMgrGetDesiredDescriptor (entityID, NULL, itemID, 0, NULL, &context);
1468   if (sdp != NULL && sdp->choice == Seq_descr_source) {
1469     biop = (BioSourcePtr) sdp->data.ptrvalue;
1470     if (biop != NULL) {
1471       for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next) {
1472         if (ssp->subtype != SUBSRC_lat_lon) continue;
1473         lat_lon = ssp->name;
1474         if (StringHasNoText (lat_lon)) continue;
1475         IsCorrectLatLonFormat (lat_lon, &format_ok, &precision_ok, &lat_in_range, &lon_in_range);
1476         if (! format_ok) continue;
1477         /*
1478         if (! precision_ok) continue;
1479         */
1480         if (! lat_in_range) continue;
1481         if (! lon_in_range) continue;
1482         if (! ParseLatLon (lat_lon, &lat, &lon)) continue;
1483         TmpNam (path);
1484         /* write to original temp file, so next temp file name will not collide */
1485         fp = FileOpen (path, "w");
1486         if (fp != NULL) {
1487           fprintf (fp, "\n");
1488           FileClose (fp);
1489           RememberSqnTempFile (path);
1490         }
1491         /* now append .kml extension so proper application is launched */
1492         StringCat (path, ".kml");
1493         fp = FileOpen (path, "w");
1494         if (fp != NULL) {
1495           fprintf (fp, "%s", google_earth_1);
1496           fprintf (fp, "    <name>%s</name>\n", lat_lon);
1497           fprintf (fp, "%s", google_earth_2);
1498           fprintf (fp, "      <coordinates>%lf,%lf</coordinates>\n", (double) lon, (double) lat);
1499           fprintf (fp, "%s", google_earth_3);
1500           FileClose (fp);
1501           RememberSqnTempFile (path);
1502 #ifdef OS_UNIX
1503           sprintf (cmmd, "open %s", path);
1504           system (cmmd);
1505 #endif
1506 #ifdef WIN_MSWIN
1507           Nlm_MSWin_OpenDocument (path);
1508 #endif
1509         }
1510         return TRUE;
1511       }
1512     }
1513   }
1514 
1515   return FALSE;
1516 }
1517 
ValidNotify(ErrSev sev,int errcode,int subcode,Uint2 entityID,Uint4 itemID,Uint2 itemtype,Boolean select,Boolean dblClick,Boolean shftKey)1518 static void LIBCALLBACK ValidNotify (ErrSev sev, int errcode, int subcode,
1519                                      Uint2 entityID, Uint4 itemID, Uint2 itemtype,
1520                                      Boolean select, Boolean dblClick, Boolean shftKey)
1521 
1522 {
1523   Int2  handled;
1524 
1525   if (dblClick && entityID > 0 && itemID > 0 && itemtype > 0) {
1526     if (itemtype == OBJ_SEQDESC && shftKey) {
1527       if (LaunchedGoogleEarth (entityID, itemID, itemtype)) return;
1528     }
1529 
1530     WatchCursor ();
1531     handled = GatherProcLaunch (OMPROC_EDIT, FALSE, entityID, itemID,
1532                                 itemtype, 0, 0, itemtype, 0);
1533     ArrowCursor ();
1534     if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
1535       Beep ();
1536     }
1537   }
1538 }
1539 
1540 #ifndef WIN_MAC
RemoveUpdateDates(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)1541 static void RemoveUpdateDates (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
1542 
1543 {
1544   BioseqPtr     bsp;
1545   BioseqSetPtr  bssp;
1546   ValNodePtr    nextsdp;
1547   Pointer PNTR  prevsdp;
1548   ValNodePtr    sdp;
1549 
1550   if (sep == NULL || sep->data.ptrvalue == NULL) return;
1551   if (IS_Bioseq (sep)) {
1552     bsp = (BioseqPtr) sep->data.ptrvalue;
1553     sdp = bsp->descr;
1554     prevsdp = (Pointer PNTR) &(bsp->descr);
1555   } else if (IS_Bioseq_set (sep)) {
1556     bssp = (BioseqSetPtr) sep->data.ptrvalue;
1557     sdp = bssp->descr;
1558     prevsdp = (Pointer PNTR) &(bssp->descr);
1559   } else return;
1560   while (sdp != NULL) {
1561     nextsdp = sdp->next;
1562     if (sdp->choice == Seq_descr_update_date) {
1563       *(prevsdp) = sdp->next;
1564       sdp->next = NULL;
1565       SeqDescFree (sdp);
1566     } else {
1567       prevsdp = (Pointer PNTR) &(sdp->next);
1568     }
1569     sdp = nextsdp;
1570   }
1571 }
1572 
1573 static CharPtr stillHasGBMsg =
1574 "Source information in a GenBank block should be in a BioSource.  Should I fixup?";
1575 
1576 #ifdef USE_SMARTNET
SmartResetProc(IteM i)1577 static void SmartResetProc (IteM i)
1578 {
1579     BaseFormPtr   bfp;
1580     ForM          f = NULL;
1581     Int4          status;
1582     ObjMgrDataPtr omdp;
1583     OMUserDataPtr omudp;
1584     SMUserDataPtr sm_usr_data;
1585 
1586     if((bfp = (BaseFormPtr) GetObjectExtra (i)) != NULL) {
1587         f = bfp->form;
1588 
1589         omudp = ObjMgrGetUserData(bfp->input_entityID, 0, 0, SMART_KEY);
1590         omdp = ObjMgrGetData (bfp->input_entityID);
1591 
1592         sm_usr_data = (SMUserDataPtr) omudp->userdata.ptrvalue;
1593 
1594         if(omdp->dirty == FALSE) {
1595             status = sm_usr_data->header->status;
1596             sm_usr_data->header->status = SMStatClosed;
1597             SMSendMsgToClient(sm_usr_data);
1598             sm_usr_data->header->status = (SMStatusCode)status;
1599             return;
1600         }
1601     }
1602     return;
1603 }
1604 #endif
1605 
1606 static void LaunchValidatorForDone (BaseFormPtr bfp, SeqEntryPtr sep, FormActnFunc revalProc, FormActnFunc continueProc);
1607 static Boolean SmallInferenceAccnVer (ForM f);
1608 static void ValSeqEntryFormExEx (ForM f, Boolean doAligns, Int2 limit, Boolean inferenceAccnCheck, FormActnFunc revalProc, FormActnFunc revalNoTaxProc, FormActnFunc doneProc);
1609 
1610 #ifdef USE_SMARTNET
AllGenBankOrRefSeq(BioseqPtr bsp,SeqMgrBioseqContextPtr bcontext)1611 static Boolean LIBCALLBACK AllGenBankOrRefSeq (BioseqPtr bsp, SeqMgrBioseqContextPtr bcontext)
1612 
1613 {
1614   SeqMgrDescContext  dcontext;
1615   MolInfoPtr         mip;
1616   BoolPtr            resetUpdateDate;
1617   ValNodePtr         sdp;
1618   SeqIdPtr           sip;
1619 
1620   resetUpdateDate = (BoolPtr) bcontext->userdata;
1621   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1622     if (sip->choice == SEQID_EMBL || sip->choice == SEQID_DDBJ) {
1623       *resetUpdateDate = FALSE;
1624     }
1625   }
1626   sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &dcontext);
1627   if (sdp != NULL) {
1628     mip = (MolInfoPtr) sdp->data.ptrvalue;
1629     if (mip != NULL) {
1630       if (mip->tech == MI_TECH_htgs_1 || mip->tech == MI_TECH_htgs_2 ||
1631           mip->tech == MI_TECH_htgs_3 || mip->tech == MI_TECH_htgs_0) {
1632         *resetUpdateDate = FALSE;
1633       }
1634     }
1635   }
1636   return TRUE;
1637 }
1638 
DoSmartReport(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)1639 static void DoSmartReport (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
1640 
1641 {
1642   BioseqPtr        bsp;
1643   BioseqSetPtr     bssp;
1644   Char             id [42];
1645   ValNodePtr PNTR  vnpp;
1646 
1647   vnpp = (ValNodePtr PNTR) mydata;
1648   if (sep == NULL || sep->data.ptrvalue == NULL) return;
1649   if (IS_Bioseq (sep)) {
1650     bsp = (BioseqPtr) sep->data.ptrvalue;
1651     SeqIdWrite (bsp->id, id, PRINTID_FASTA_LONG, sizeof (id) - 1);
1652     ValNodeCopyStr (vnpp, 0, id);
1653   } else if (IS_Bioseq_set (sep)) {
1654     bssp = (BioseqSetPtr) sep->data.ptrvalue;
1655     ValNodeAddInt (vnpp, bssp->_class, 0);
1656   }
1657 }
1658 
SmartStructureReport(SeqEntryPtr sep)1659 static VoidPtr SmartStructureReport (SeqEntryPtr sep)
1660 
1661 {
1662   ValNodePtr  vnp = NULL;
1663 
1664   SeqEntryExplore (sep, (Pointer) &vnp, DoSmartReport);
1665   return vnp;
1666 }
1667 
ValNodeListsDiffer(ValNodePtr vnp1,ValNodePtr vnp2)1668 static Boolean ValNodeListsDiffer (ValNodePtr vnp1, ValNodePtr vnp2)
1669 
1670 {
1671   while (vnp1 != NULL && vnp2 != NULL) {
1672     if (vnp1->choice != vnp2->choice) return TRUE;
1673     if (vnp1->choice == 0) {
1674       if (StringCmp (vnp1->data.ptrvalue, vnp2->data.ptrvalue) != 0) return TRUE;
1675     }
1676     vnp1 = vnp1->next;
1677     vnp2 = vnp2->next;
1678   }
1679   if (vnp1 != NULL || vnp2 != NULL) return TRUE;
1680   return FALSE;
1681 }
1682 
1683 static void SmartnetDoneFuncEx (BaseFormPtr bfp, Boolean validate);
1684 static void SmartnetDoneNoValidateFunc (ForM f);
1685 
SmartnetDoneValidateFunc(ForM f)1686 static void SmartnetDoneValidateFunc (ForM f)
1687 {
1688   Boolean  inferenceAccnCheck;
1689 
1690   inferenceAccnCheck = SmallInferenceAccnVer (f);
1691   ValSeqEntryFormExEx (f, TRUE, VALIDATE_ALL, inferenceAccnCheck, SmartnetDoneValidateFunc, NULL, SmartnetDoneNoValidateFunc);
1692 }
1693 
SmartnetDoneNoValidateFunc(ForM f)1694 static void SmartnetDoneNoValidateFunc (ForM f)
1695 {
1696   BaseFormPtr bfp;
1697 
1698   bfp = (BaseFormPtr) GetObjectExtra (f);
1699   if (bfp == NULL) return;
1700   SmartnetDoneFuncEx (bfp, FALSE);
1701 }
1702 
RemovePgcode(BioSourcePtr biop,Pointer userdata)1703 static void RemovePgcode (BioSourcePtr biop, Pointer userdata)
1704 
1705 {
1706   OrgNamePtr  onp;
1707   OrgRefPtr   orp;
1708 
1709   if (biop == NULL) return;
1710   orp = biop->org;
1711   if (orp == NULL) return;
1712   onp = orp->orgname;
1713   if (onp == NULL) return;
1714   onp->pgcode = 0;
1715 }
1716 
SmartnetDoneFuncEx(BaseFormPtr bfp,Boolean validate)1717 static void SmartnetDoneFuncEx (BaseFormPtr bfp, Boolean validate)
1718 
1719 {
1720     MsgAnswer     ans;
1721     ForM          f = NULL;
1722     Boolean       hasGBStuff;
1723     ValNodePtr    sdp;
1724     SeqEntryPtr   sep;
1725     Boolean       update;
1726 
1727     ObjMgrDataPtr omdp;
1728     ObjMgrPtr     omp;
1729     OMUserDataPtr omudp;
1730     SMUserDataPtr sm_usr_data;
1731 /*    Uint2         entityID; */
1732 
1733     Boolean       resetUpdateDate = TRUE;
1734     ValNodePtr    vnp;
1735     EOkToWriteEntity continue_cancel_validate;
1736 
1737     if(bfp != NULL) {
1738         f = bfp->form;
1739 
1740         omudp = ObjMgrGetUserData(bfp->input_entityID, 0, 0, SMART_KEY);
1741         if (omudp == NULL) return;
1742 
1743         /* for now set dirty flag to force validation in OkayToWriteTheEntity */
1744         ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1745 
1746         omdp = ObjMgrGetData (bfp->input_entityID);
1747         if (omdp == NULL) return;
1748 
1749         sm_usr_data = (SMUserDataPtr) omudp->userdata.ptrvalue;
1750         if (sm_usr_data == NULL) return;
1751 
1752         if(omdp->dirty == FALSE || (sm_usr_data->header->dirty & 0x02)) {
1753             sm_usr_data->header->status = SMStatClosed;
1754             SMSendMsgToClient(sm_usr_data);
1755 
1756             /*
1757             entityID = bfp->input_entityID;
1758             RemoveSeqEntryViewer (bfp->form);
1759             ObjMgrFreeUserData(entityID, 0, 0, SMART_KEY);
1760             */
1761 
1762             /* ObjMgrSendMsg (OM_MSG_DEL, entityID, 0, 0); */
1763 
1764             ObjMgrFree(omdp->datatype, omdp->dataptr);
1765 
1766             omp = ObjMgrGet ();
1767             ObjMgrReapOne (omp);
1768             SeqMgrClearBioseqIndex ();
1769             ObjMgrFreeCache (0);
1770             FreeSeqIdGiCache ();
1771 
1772             SeqEntrySetScope (NULL);
1773             return;
1774         }
1775 
1776         sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1777         if (sep != NULL) {
1778             if (EntrezASN1Detected (sep)) {
1779                 Message(MSG_OK,
1780                         "You may not commit entry retrieved from Entrez.\n"
1781                         "Please close this window instead");
1782                 return;
1783             }
1784 
1785             SeqEntryPack (sep);
1786             EntryChangeGBSource (sep);
1787             hasGBStuff = EntryCheckGBBlock (sep);
1788             GetRidOfEmptyFeatsDescStrings (0, sep);
1789             GetRidOfLocusInSeqIds (0, sep);
1790 
1791             if (hasGBStuff) {
1792                 /*  ans = Message (MSG_YNC, stillHasGBMsg);
1793                     if (ans == ANS_CANCEL) return;
1794                     if (ans == ANS_YES) { */
1795 
1796                 MySeqEntryToAsn3 (sep, TRUE, FALSE, FALSE);
1797                 /* } */
1798             }
1799 
1800             move_cds (sep);
1801             /* now instantiating protein titles */
1802             InstantiateProteinTitles (bfp->input_entityID, NULL);
1803 
1804             update = PropagateFromGenBankBioseqSet (sep, FALSE);
1805             NormalizeDescriptorOrder (sep);
1806             update = TRUE; /* because of NormalizeDescriptorOrder */
1807 
1808             SeqMgrClearFeatureIndexes (bfp->input_entityID, NULL);
1809 
1810             if (validate) {
1811               continue_cancel_validate = OkayToWriteTheEntity (bfp->input_entityID, f, TRUE);
1812               if (continue_cancel_validate == eOkToWriteEntity_Cancel) {
1813                   if (update && bfp != NULL) {
1814                       ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1815                   }
1816                   return;
1817               } else if (continue_cancel_validate == eOkToWriteEntity_Validate) {
1818                   /* launch validator */
1819                   LaunchValidatorForDone (bfp, sep, SmartnetDoneValidateFunc, SmartnetDoneNoValidateFunc);
1820                   return;
1821               }
1822             }
1823             /* ans = Message (MSG_YN, "Reset Update Date?"); */
1824             ans = ANS_YES;
1825 
1826             /* reset update date in smart mode if GenBank or RefGene, and not HTGS */
1827             SeqMgrExploreBioseqs (bfp->input_entityID, 0, (Pointer) &resetUpdateDate, AllGenBankOrRefSeq, TRUE, TRUE, TRUE);
1828             if (/* ans == ANS_YES */ resetUpdateDate) {
1829                 SeqEntryExplore (sep, NULL, RemoveUpdateDates);
1830                 sdp = CreateNewDescriptor (sep, Seq_descr_update_date);
1831                 if (sdp != NULL) {
1832                     sdp->data.ptrvalue = DateCurr ();
1833                 }
1834 
1835                 PropagateFromGenBankBioseqSet (sep, FALSE);
1836                 NormalizeDescriptorOrder (sep);
1837             }
1838 
1839             CdCheck (sep, NULL);
1840 
1841             omudp = ObjMgrGetUserData(bfp->input_entityID, 0, 0, DUMB_KEY);
1842             if (omudp != NULL) {
1843               vnp = SmartStructureReport (sep);
1844               if (ValNodeListsDiffer (vnp, omudp->userdata.ptrvalue)) {
1845                 sm_usr_data->header->dirty |= 0x04; /* set rearranged signal */
1846               }
1847               ValNodeFreeData (vnp);
1848             }
1849 
1850             SeqMgrClearFeatureIndexes (bfp->input_entityID, NULL);
1851             VisitBioSourcesInSep (sep, NULL, RemovePgcode);
1852         }
1853 
1854         if(sm_usr_data->header->format == OBJ_SEQENTRY) {
1855             SMWriteBioseqObj(sep, sm_usr_data, NULL);
1856         } else {
1857             sm_usr_data->header->format = omdp->datatype;
1858             SMWriteBioseqObj(omdp->dataptr, sm_usr_data, NULL);
1859         }
1860 
1861         /* ObjMgrDelete(omdp->datatype, omdp->dataptr); */
1862 
1863         omdp->dirty = FALSE;
1864 
1865         /*
1866         entityID = bfp->input_entityID;
1867         RemoveSeqEntryViewer (bfp->form);
1868         ObjMgrFreeUserData(entityID, 0, 0, SMART_KEY);
1869         */
1870 
1871         HideBioseqView ((WindoW) bfp->form);
1872 
1873         /* ObjMgrSendMsg (OM_MSG_DEL, entityID, 0, 0); */
1874         ObjMgrFree(omdp->datatype, omdp->dataptr);
1875 
1876         omp = ObjMgrGet ();
1877         ObjMgrReapOne (omp);
1878         SeqMgrClearBioseqIndex ();
1879         ObjMgrFreeCache (0);
1880         FreeSeqIdGiCache ();
1881 
1882         SeqEntrySetScope (NULL);
1883 
1884         subtoolRecordDirty = FALSE;
1885         FileRemove (SEQUIN_EDIT_TEMP_FILE);
1886         FileRemove (SEQUIN_EDIT_PREV_FILE);
1887         /* FileRemove (SEQUIN_EDIT_BACK_FILE); */
1888         FileRemove (SEQUIN_EDIT_ARCH_FILE);
1889 
1890         FileRename (SEQUIN_EDIT_BACK_FILE, SEQUIN_EDIT_ARCH_FILE);
1891         return;
1892 
1893     } else {
1894         Message(MSG_ERROR, "NULL pointer for brp ...? BUG!BUG!BUG!");
1895         return;
1896     }
1897 }
1898 
1899 
SmartnetDoneFunc(BaseFormPtr bfp)1900 static void SmartnetDoneFunc (BaseFormPtr bfp)
1901 {
1902   SmartnetDoneFuncEx (bfp, TRUE);
1903 }
1904 
1905 
SmartnetDoneProc(IteM i)1906 static void SmartnetDoneProc (IteM i)
1907 
1908 {
1909 	BaseFormPtr bfp;
1910 
1911 	bfp = (BaseFormPtr) GetObjectExtra (i);
1912 	SmartnetDoneFunc (bfp);
1913 }
1914 #endif
1915 
1916 
1917 static void SubtoolDoneFuncEx (ForM f, Boolean validate);
1918 static void SubtoolDoneNoValidateFunc (ForM f);
1919 
SubtoolDoneValidateFunc(ForM f)1920 static void SubtoolDoneValidateFunc (ForM f)
1921 {
1922   Boolean  inferenceAccnCheck;
1923 
1924   inferenceAccnCheck = SmallInferenceAccnVer (f);
1925   ValSeqEntryFormExEx (f, TRUE, VALIDATE_ALL, inferenceAccnCheck, SubtoolDoneValidateFunc, NULL, SubtoolDoneNoValidateFunc);
1926 }
1927 
1928 
SubtoolDoneNoValidateFunc(ForM f)1929 static void SubtoolDoneNoValidateFunc (ForM f)
1930 {
1931 	SubtoolDoneFuncEx (f, FALSE);
1932 }
1933 
1934 
SubtoolDoneFuncEx(ForM form,Boolean validate)1935 static void SubtoolDoneFuncEx (ForM form, Boolean validate)
1936 {
1937   MsgAnswer    ans;
1938   BaseFormPtr  bfp;
1939   ForM         f;
1940   Boolean      hasGBStuff;
1941   ValNodePtr   sdp;
1942   SeqEntryPtr  sep;
1943   Boolean      update;
1944   EOkToWriteEntity continue_review_cancel;
1945 
1946   if (subtoolEntityID > 0) {
1947     sep = GetTopSeqEntryForEntityID (subtoolEntityID);
1948     if (sep != NULL) {
1949       SeqEntryPack (sep);
1950       EntryChangeGBSource (sep);
1951       hasGBStuff = EntryCheckGBBlock (sep);
1952       GetRidOfEmptyFeatsDescStrings (0, sep);
1953       GetRidOfLocusInSeqIds (0, sep);
1954       if (hasGBStuff) {
1955         ans = Message (MSG_YNC, stillHasGBMsg);
1956         if (ans == ANS_CANCEL) return;
1957         if (ans == ANS_YES) {
1958           MySeqEntryToAsn3 (sep, TRUE, FALSE, FALSE);
1959         }
1960       }
1961       move_cds (sep);
1962       /* now instantiating protein titles */
1963       InstantiateProteinTitles (subtoolEntityID, NULL);
1964       update = PropagateFromGenBankBioseqSet (sep, FALSE);
1965       NormalizeDescriptorOrder (sep);
1966       update = TRUE; /* because of NormalizeDescriptorOrder */
1967       f = NULL;
1968       bfp = (BaseFormPtr) GetObjectExtra (form);
1969       if (bfp != NULL) {
1970         f = bfp->form;
1971       }
1972       SeqMgrClearFeatureIndexes (bfp->input_entityID, NULL);
1973       if (validate) {
1974         continue_review_cancel = OkayToWriteTheEntity (subtoolEntityID, f, validate);
1975         if (continue_review_cancel == eOkToWriteEntity_Cancel) {
1976           if (update && bfp != NULL) {
1977             ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1978           }
1979           return;
1980         } else if (continue_review_cancel == eOkToWriteEntity_Validate) {
1981           /* launch validator */
1982           LaunchValidatorForDone (bfp, sep, SubtoolDoneValidateFunc, SubtoolDoneNoValidateFunc);
1983           return;
1984         }
1985       }
1986       /* ans = Message (MSG_YN, "Reset Update Date?"); */
1987       ans = ANS_YES;
1988       if (ans == ANS_YES) {
1989         SeqEntryExplore (sep, NULL, RemoveUpdateDates);
1990         sdp = CreateNewDescriptor (sep, Seq_descr_update_date);
1991         if (sdp != NULL) {
1992           sdp->data.ptrvalue = DateCurr ();
1993         }
1994         PropagateFromGenBankBioseqSet (sep, FALSE);
1995         NormalizeDescriptorOrder (sep);
1996       }
1997       CdCheck (sep, NULL);
1998     }
1999     /*SetChecklistValue (checklistForm, 7);*/
2000     SeqMgrClearFeatureIndexes (bfp->input_entityID, NULL);
2001     if (WriteTheEntityID (subtoolEntityID, "stdout", FALSE)) {
2002       subtoolRecordDirty = FALSE;
2003       FileRemove (SEQUIN_EDIT_TEMP_FILE);
2004       FileRemove (SEQUIN_EDIT_PREV_FILE);
2005       /* FileRemove (SEQUIN_EDIT_BACK_FILE); */
2006       FileRemove (SEQUIN_EDIT_ARCH_FILE);
2007       FileRename (SEQUIN_EDIT_BACK_FILE, SEQUIN_EDIT_ARCH_FILE);
2008     } else {
2009       Message (MSG_POSTERR, "Unable to write ASN.1 file");
2010       return;
2011     }
2012     /*SetChecklistValue (checklistForm, 5);*/
2013   }
2014   QuitProgram ();
2015 }
2016 
2017 
SubtoolDoneProc(IteM i)2018 static void SubtoolDoneProc (IteM i)
2019 
2020 {
2021   BaseFormPtr  bfp;
2022 
2023   bfp = (BaseFormPtr) GetObjectExtra (i);
2024   if (bfp != NULL) {
2025     SubtoolDoneFuncEx (bfp->form, TRUE);
2026   }
2027 }
2028 #endif
2029 
ReviewErrorsForValidationFailure(void)2030 static Boolean ReviewErrorsForValidationFailure (void)
2031 {
2032   WindoW w;
2033   GrouP  h, c;
2034   PrompT p;
2035   ButtoN b;
2036   ModalAcceptCancelData acd;
2037 
2038   acd.accepted = FALSE;
2039   acd.cancelled = FALSE;
2040 
2041   w = ModalWindow(-20, -13, -10, -10, NULL);
2042   h = HiddenGroup (w, -1, 0, NULL);
2043   SetGroupSpacing (h, 10, 10);
2044 
2045   p = StaticPrompt (h, "Submission has validation errors.", 0, 0, programFont, 'l');
2046   c = HiddenGroup (h, 3, 0, NULL);
2047   SetGroupSpacing (c, 10, 10);
2048   b = PushButton (c, "Review Errors", ModalAcceptButton);
2049   SetObjectExtra (b, &acd, NULL);
2050   b = PushButton (c, "Continue", ModalCancelButton);
2051   SetObjectExtra (b, &acd, NULL);
2052   AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) c, NULL);
2053 
2054   Show(w);
2055   Select (w);
2056   while (!acd.accepted && ! acd.cancelled)
2057   {
2058     ProcessExternalEvent ();
2059     Update ();
2060   }
2061   ProcessAnEvent ();
2062   Remove (w);
2063   if (acd.accepted)
2064   {
2065     return TRUE;
2066   }
2067   else
2068   {
2069     return FALSE;
2070   }
2071 }
2072 
2073 
LaunchValidatorForDone(BaseFormPtr bfp,SeqEntryPtr sep,FormActnFunc revalProc,FormActnFunc continueProc)2074 static void LaunchValidatorForDone (BaseFormPtr bfp, SeqEntryPtr sep, FormActnFunc revalProc, FormActnFunc continueProc)
2075 {
2076   ValidStructPtr  vsp;
2077   Int2            verbosity = 2;
2078   Char            buf [32];
2079   Boolean         allRawOrSeg = TRUE;
2080   ErrHookProc     oldErrHook;
2081   ErrSev          oldErrSev;
2082   Int2            errors;
2083   Int2            j;
2084 
2085   WatchCursor ();
2086   Update ();
2087   vsp = ValidStructNew ();
2088   if (vsp != NULL) {
2089     /*SetChecklistValue (checklistForm, 6);*/
2090 
2091     verbosity = 2;
2092     if (GetSequinAppParam ("SETTINGS", "VALIDATEVERBOSITY", NULL, buf, sizeof (buf))) {
2093       if (! StrToInt (buf, &verbosity)) {
2094         verbosity = 2;
2095       }
2096     }
2097 
2098     CreateValidateWindowExEx (ValidNotify, "Sequin Validation Errors",
2099                             programFont, SEV_INFO, verbosity, bfp, revalProc, continueProc, TRUE);
2100     ClearValidateWindow ();
2101     SeqEntryExplore (sep, (Pointer) (&allRawOrSeg), CheckForCookedBioseqs);
2102     if (allRawOrSeg) {
2103       vsp->useSeqMgrIndexes = TRUE;
2104     }
2105     HideValidateDoc ();
2106     vsp->suppressContext = ShouldSetSuppressContext ();
2107     vsp->justShowAccession = ShouldSetJustShowAccession ();
2108     oldErrHook = ErrSetHandler (ValidErrHook);
2109     oldErrSev = ErrSetMessageLevel (SEV_NONE);
2110     vsp->validateAlignments = TRUE;
2111     vsp->alignFindRemoteBsp = TRUE;
2112     vsp->doSeqHistAssembly = FALSE;
2113     vsp->testLatLonSubregion = testLatLonSubregion;
2114     vsp->strictLatLonCountry = strictLatLonCountry;
2115     vsp->indexerVersion = indexerVersion;
2116     for (j = 0; j < 6; j++) {
2117       vsp->errors [j] = 0;
2118     }
2119     vsp->errfunc = ValidErrCallback;
2120     SequinValidateSeqEntry (sep, vsp);
2121     if (indexerVersion && useEntrez) {
2122       TaxonValidate (sep, vsp);
2123     }
2124     ErrSetMessageLevel (oldErrSev);
2125     ErrSetHandler (oldErrHook);
2126     ErrClear ();
2127     ShowValidateDoc ();
2128     errors = 0;
2129     for (j = 0; j < 6; j++) {
2130       errors += vsp->errors [j];
2131     }
2132     if (errors == 0) {
2133       ArrowCursor ();
2134       Message (MSG_OK, "Validation test succeeded.");
2135       FreeValidateWindow ();
2136     } else {
2137       RepopulateValidateFilter ();
2138     }
2139     ValidStructFree (vsp);
2140     /*SetChecklistValue (checklistForm, 5);*/
2141   }
2142   ArrowCursor ();
2143   Update ();
2144 }
2145 
2146 
ProcessDoneButton(ForM f)2147 static void ProcessDoneButton (ForM f)
2148 
2149 {
2150   Boolean         allRawOrSeg = TRUE;
2151   BaseFormPtr     bfp;
2152   Int2            errors;
2153   Int2            j;
2154   ErrSev          oldErrSev;
2155   SeqEntryPtr     sep;
2156   CharPtr         str;
2157   ValidStructPtr  vsp;
2158   CharPtr         fmt_no_file = "Submission is now written.  Please e-mail to %s.%s";
2159   CharPtr         missing_annot = "  Please include a brief summary of your submission within your correspondence.";
2160   CharPtr         note = "";
2161   CharPtr         email_address;
2162   MsgAnswer       ans;
2163 
2164   bfp = (BaseFormPtr) GetObjectExtra (f);
2165   if (bfp == NULL) return;
2166   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
2167   if (sep == NULL) return;
2168 #ifndef WIN_MAC
2169   if (smartnetMode) {
2170 #ifdef USE_SMARTNET
2171     SmartnetDoneProc ((IteM) f);
2172 #endif
2173     return;
2174   }
2175   if (subtoolMode || stdinMode || binseqentryMode) {
2176     SubtoolDoneProc ((IteM) f);
2177     return;
2178   }
2179 #endif
2180   WatchCursor ();
2181   Update ();
2182   vsp = ValidStructNew ();
2183   if (vsp != NULL) {
2184     SeqEntryExplore (sep, (Pointer) (&allRawOrSeg), CheckForCookedBioseqs);
2185     if (allRawOrSeg) {
2186       vsp->useSeqMgrIndexes = TRUE;
2187     }
2188     if (indexerVersion) {
2189       vsp->alwaysRequireIsoJTA = TRUE;
2190     }
2191     oldErrSev = ErrSetMessageLevel (SEV_MAX);
2192     vsp->validateAlignments = TRUE;
2193     vsp->alignFindRemoteBsp = TRUE;
2194     vsp->doSeqHistAssembly = FALSE;
2195     vsp->testLatLonSubregion = testLatLonSubregion;
2196     vsp->strictLatLonCountry = strictLatLonCountry;
2197     vsp->indexerVersion = indexerVersion;
2198     for (j = 0; j < 6; j++) {
2199       vsp->errors [j] = 0;
2200     }
2201     SequinValidateSeqEntry (sep, vsp);
2202     if (indexerVersion && useEntrez) {
2203       TaxonValidate (sep, vsp);
2204     }
2205     ErrSetMessageLevel (oldErrSev);
2206     ErrClear ();
2207     ErrShow ();
2208     errors = 0;
2209     for (j = 3; j < 6; j++) {
2210       errors += vsp->errors [j];
2211     }
2212     ValidStructFree (vsp);
2213     if (errors > 0) {
2214       ArrowCursor ();
2215       Update ();
2216       if (ReviewErrorsForValidationFailure ()) {
2217         LaunchValidatorForDone (bfp, sep, ProcessDoneButton, NULL);
2218         return;
2219       }
2220     }
2221     ArrowCursor ();
2222     Update ();
2223     if (Nlm_GetAppProperty ("SequinUseEMBLStyle") != NULL) {
2224       ans = Message (MSG_YN, "In order to submit to update@ebi.ak.uk, you must Export the EMBL format using the File menu.  Do you want to save the file in the ASN.1 format now (not the correct format for EBI)?");
2225     } else {
2226       ans = Message (MSG_YN, "Are you ready to save the record?");
2227     }
2228     if (ans == ANS_YES) {
2229       if (SaveSeqSubmitProc (bfp, TRUE)) {
2230         if (IsAnySequenceMissingAnnotation (sep)) {
2231           note = missing_annot;
2232         }
2233         email_address = ReturnSubmissionEmailAddress (bfp->input_entityID);
2234         str = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt_no_file) + StringLen (email_address) + StringLen (note)));
2235         if (str != NULL) {
2236           sprintf (str, fmt_no_file, email_address, note);
2237           UseWindow ((WindoW) bfp->form);
2238           Message (MSG_OK, str);
2239           MemFree (str);
2240         }
2241       }
2242     }
2243   }
2244   ArrowCursor ();
2245   Update ();
2246 }
2247 
CloseAboutWindowProc(WindoW w)2248 static void CloseAboutWindowProc (WindoW w)
2249 
2250 {
2251   Remove (w);
2252 }
2253 
CloseAboutPanelProc(PaneL p,PoinT pt)2254 static void CloseAboutPanelProc (PaneL p, PoinT pt)
2255 
2256 {
2257   WindoW  w;
2258 
2259   w = ParentWindow (p);
2260   Remove (w);
2261 }
2262 
AboutProc(IteM i)2263 static void AboutProc (IteM i)
2264 
2265 {
2266   PaneL   p;
2267   WindoW  w;
2268 
2269   w = ModalWindow (-50, -33, -1, -1, CloseAboutWindowProc);
2270   p = SimplePanel (w, AboutBoxWidth (), AboutBoxHeight (), DrawAbout);
2271   SetPanelClick (p, NULL, NULL, NULL, CloseAboutPanelProc);
2272   Show (w);
2273   Select (w);
2274 }
2275 
SequinEntrezInit(CharPtr appl_id,Boolean no_warnings,BoolPtr is_network)2276 extern Boolean SequinEntrezInit (CharPtr appl_id, Boolean no_warnings, BoolPtr is_network)
2277 
2278 {
2279   /*
2280   MonitorPtr  mon;
2281   Boolean     rsult;
2282 
2283   mon = MonitorStrNewEx ("Sequin", 30, FALSE);
2284   MonitorStrValue (mon, "Connecting to Entrez service");
2285   Update ();
2286   rsult = EntrezInit (appl_id, no_warnings, is_network);
2287   MonitorFree (mon);
2288   Update ();
2289   return rsult;
2290   */
2291   return FALSE;
2292 }
2293 
2294 /*
2295 #ifndef WIN16
2296 static void Cn3DWinShowProc (IteM i)
2297 {
2298   WindoW  w;
2299 
2300   if (! BiostrucAvail ()) return;
2301   if (! EntrezIsInited ()) {
2302     SequinEntrezInit ("Sequin", FALSE, NULL);
2303   }
2304   w = Cn3DWin_Entrez(NULL, useEntrez);
2305   if (w == NULL) return;
2306   Show (w);
2307   Select (w);
2308 }
2309 #endif
2310 */
2311 
2312 typedef struct tax3val {
2313   Uint2       entityID;
2314   Uint4       itemID;
2315   Uint2       itemtype;
2316   Uint1       organelle;
2317   OrgRefPtr   orp;
2318   BioseqPtr   bsp;
2319   SeqFeatPtr  sfp;
2320 } TaxVal, PNTR TaxValPtr;
2321 
2322 typedef struct tax3lst {
2323   ValNodePtr  head;
2324   ValNodePtr  tail;
2325 } TaxLst, PNTR TaxLstPtr;
2326 
RecordSrc(Uint2 entityID,Uint4 itemID,Uint2 itemtype,OrgRefPtr orp,Uint1 organelle,TaxLstPtr tlp,SeqDescrPtr sdp,SeqFeatPtr sfp)2327 static void RecordSrc (Uint2 entityID, Uint4 itemID, Uint2 itemtype, OrgRefPtr orp,
2328                        Uint1 organelle, TaxLstPtr tlp, SeqDescrPtr sdp, SeqFeatPtr sfp)
2329 
2330 {
2331   BioseqPtr      bsp;
2332   BioseqSetPtr   bssp;
2333   ObjValNodePtr  ovp;
2334   SeqEntryPtr    sep;
2335   TaxValPtr      tvp;
2336   ValNodePtr     vnp;
2337 
2338   if (orp == NULL || tlp == NULL) return;
2339 
2340   tvp = (TaxValPtr) MemNew (sizeof (TaxVal));
2341   if (tvp == NULL) return;
2342 
2343   vnp = ValNodeNew (tlp->tail);
2344   if (vnp == NULL) return;
2345 
2346   if (tlp->head == NULL) {
2347     tlp->head = vnp;
2348   }
2349   tlp->tail = vnp;
2350 
2351   tvp->entityID = entityID;
2352   tvp->itemID = itemID;
2353   tvp->itemtype = itemtype;
2354   tvp->organelle = organelle;
2355   tvp->orp = orp;
2356   if (sdp != NULL && sdp->extended != 0) {
2357     ovp = (ObjValNodePtr) sdp;
2358     if (ovp->idx.parenttype == OBJ_BIOSEQ) {
2359       bsp = (BioseqPtr) ovp->idx.parentptr;
2360       if (bsp != NULL) {
2361         tvp->bsp = bsp;
2362       }
2363     } else if (ovp->idx.parenttype == OBJ_BIOSEQSET) {
2364       bssp = (BioseqSetPtr) ovp->idx.parentptr;
2365       if (bssp != NULL) {
2366         sep = bssp->seqentry;
2367         if (sep != NULL) {
2368           sep = FindNthBioseq (sep, 1);
2369           if (sep != NULL) {
2370             bsp = (BioseqPtr) sep->data.ptrvalue;
2371             if (bsp != NULL) {
2372               tvp->bsp = bsp;
2373             }
2374           }
2375         }
2376       }
2377     }
2378   } else if (sfp != NULL) {
2379     tvp->sfp = sfp;
2380   }
2381 
2382   vnp->data.ptrvalue = tvp;
2383 }
2384 
GetSrcDesc(SeqDescrPtr sdp,Pointer userdata)2385 static void GetSrcDesc (SeqDescrPtr sdp, Pointer userdata)
2386 
2387 {
2388   BioSourcePtr   biop;
2389   ObjValNodePtr  ovp;
2390   TaxLstPtr      tlp;
2391 
2392   if (sdp == NULL || sdp->choice != Seq_descr_source) return;
2393   tlp = (TaxLstPtr) userdata;
2394 
2395   biop = (BioSourcePtr) sdp->data.ptrvalue;
2396   if (biop == NULL) return;
2397 
2398   if (sdp->extended != 0) {
2399     ovp = (ObjValNodePtr) sdp;
2400     RecordSrc (ovp->idx.entityID, ovp->idx.itemID, OBJ_SEQDESC, biop->org, biop->genome, tlp, sdp, NULL);
2401   }
2402 }
2403 
GetSrcFeat(SeqFeatPtr sfp,Pointer userdata)2404 static void GetSrcFeat (SeqFeatPtr sfp, Pointer userdata)
2405 
2406 {
2407   BioSourcePtr  biop;
2408   TaxLstPtr     tlp;
2409 
2410   if (sfp == NULL || sfp->data.choice != SEQFEAT_BIOSRC) return;
2411   tlp = (TaxLstPtr) userdata;
2412 
2413   biop = (BioSourcePtr) sfp->data.value.ptrvalue;
2414   if (biop == NULL) return;
2415 
2416   RecordSrc (sfp->idx.entityID, sfp->idx.itemID, OBJ_SEQFEAT, biop->org, biop->genome, tlp, NULL, sfp);
2417 }
2418 
2419 NLM_EXTERN void CDECL  ValidErr VPROTO((ValidStructPtr vsp, int severity, int code1, int code2, const char *fmt, ...));
2420 
2421 
ReportOneBadSpecificHost(ValNodePtr vnp,ValidStructPtr vsp,ErrSev sev,int code1,int code2,CharPtr msg_fmt)2422 static void ReportOneBadSpecificHost (ValNodePtr vnp, ValidStructPtr vsp, ErrSev sev, int code1, int code2, CharPtr msg_fmt)
2423 {
2424   ObjValNodePtr ovp;
2425   BioSourcePtr  biop;
2426   OrgModPtr     mod;
2427 
2428   if (vnp == NULL || vsp == NULL || StringHasNoText (msg_fmt)) return;
2429 
2430   vsp->sfp = NULL;
2431   vsp->descr = NULL;
2432   vsp->bsp = NULL;
2433   vsp->bssp = NULL;
2434   biop = NULL;
2435   mod = NULL;
2436 
2437   if (vnp->choice == OBJ_SEQFEAT)
2438   {
2439     vsp->sfp = (SeqFeatPtr) vnp->data.ptrvalue;
2440     vsp->gcp->entityID = vsp->sfp->idx.entityID;
2441     vsp->gcp->itemID = vsp->sfp->idx.itemID;
2442     vsp->gcp->thistype = OBJ_SEQFEAT;
2443     if (vsp->sfp->idx.parenttype == OBJ_BIOSEQ)
2444     {
2445       vsp->bsp = vsp->sfp->idx.parentptr;
2446     }
2447     else if (vsp->sfp->idx.parenttype == OBJ_BIOSEQSET)
2448     {
2449       vsp->bssp = vsp->sfp->idx.parentptr;
2450     }
2451     biop = (BioSourcePtr) vsp->sfp->data.value.ptrvalue;
2452   }
2453   else if (vnp->choice == OBJ_SEQDESC)
2454   {
2455     vsp->descr = (SeqDescrPtr) vnp->data.ptrvalue;
2456     if (vsp->descr != NULL && vsp->descr->extended != 0)
2457     {
2458       ovp = (ObjValNodePtr) vsp->descr;
2459       vsp->gcp->entityID = ovp->idx.entityID;
2460       vsp->gcp->itemID = ovp->idx.itemID;
2461       vsp->gcp->thistype = OBJ_SEQDESC;
2462 
2463       if (ovp->idx.parenttype == OBJ_BIOSEQ)
2464       {
2465         vsp->bsp = ovp->idx.parentptr;
2466       }
2467       else if (ovp->idx.parenttype == OBJ_BIOSEQSET)
2468       {
2469         vsp->bssp = ovp->idx.parentptr;
2470       }
2471     }
2472     if (vsp->descr != NULL) {
2473       biop = vsp->descr->data.ptrvalue;
2474     }
2475   }
2476 
2477   if (biop != NULL && biop->org != NULL && biop->org->orgname != NULL)
2478   {
2479     mod = biop->org->orgname->mod;
2480     while (mod != NULL && mod->subtype != ORGMOD_nat_host)
2481     {
2482       mod = mod->next;
2483     }
2484     if (mod != NULL)
2485     {
2486       ValidErr (vsp, sev, code1, code2, msg_fmt, mod->subname);
2487     }
2488   }
2489 }
2490 
2491 
ReportBadSpecificHostValues(SeqEntryPtr sep,ValidStructPtr vsp)2492 static void ReportBadSpecificHostValues (SeqEntryPtr sep, ValidStructPtr vsp)
2493 {
2494   ValNodePtr    misspelled = NULL, bad_caps = NULL, ambiguous = NULL, unrecognized = NULL, vnp;
2495 
2496   Taxon3ValidateSpecificHostsInSeqEntry (sep, &misspelled, &bad_caps, &ambiguous, &unrecognized);
2497 
2498   for (vnp = misspelled; vnp != NULL; vnp = vnp->next) {
2499     ReportOneBadSpecificHost (vnp, vsp, SEV_WARNING, ERR_SEQ_DESCR_BadSpecificHost, "Specific host value is misspelled: %s");
2500   }
2501   for (vnp = bad_caps; vnp != NULL; vnp = vnp->next) {
2502     ReportOneBadSpecificHost (vnp, vsp, SEV_WARNING, ERR_SEQ_DESCR_BadSpecificHost, "Specific host value is incorrectly capitalized: %s");
2503   }
2504   for (vnp = ambiguous; vnp != NULL; vnp = vnp->next) {
2505     ReportOneBadSpecificHost (vnp, vsp, SEV_INFO, ERR_SEQ_DESCR_AmbiguousSpecificHost, "Specific host value is ambiguous: %s");
2506   }
2507   for (vnp = unrecognized; vnp != NULL; vnp = vnp->next) {
2508     ReportOneBadSpecificHost (vnp, vsp, SEV_WARNING, ERR_SEQ_DESCR_BadSpecificHost, "Invalid value for specific host: %s");
2509   }
2510 
2511   misspelled = ValNodeFree (misspelled);
2512   bad_caps = ValNodeFree (bad_caps);
2513   unrecognized = ValNodeFree (unrecognized);
2514 }
2515 
2516 static Boolean log_tax_asn = FALSE;
2517 static Boolean log_tax_set = FALSE;
2518 
ReportBadTaxID(ValidStructPtr vsp,OrgRefPtr orig,OrgRefPtr reply)2519 static void ReportBadTaxID (ValidStructPtr vsp, OrgRefPtr orig, OrgRefPtr reply)
2520 {
2521   ValNodePtr vnp_o, vnp_r;
2522   DbtagPtr db_o = NULL, db_r = NULL;
2523   CharPtr tag1, tag2;
2524   Char    buf1[15];
2525   Char    buf2[15];
2526 
2527   if (vsp == NULL || orig == NULL || reply == NULL
2528       || orig->db == NULL || reply->db == NULL) {
2529     return;
2530   }
2531 
2532   for (vnp_o = orig->db; vnp_o != NULL && db_o == NULL; vnp_o = vnp_o->next) {
2533     if ((db_o = (DbtagPtr) vnp_o->data.ptrvalue) != NULL) {
2534       if (StringCmp (db_o->db, "taxon") != 0) {
2535         db_o = NULL;
2536       }
2537     }
2538   }
2539 
2540   if (db_o == NULL) {
2541     return;
2542   }
2543 
2544   for (vnp_r = reply->db; vnp_r != NULL && db_r == NULL; vnp_r = vnp_r->next) {
2545     if ((db_r = (DbtagPtr) vnp_r->data.ptrvalue) != NULL) {
2546       if (StringCmp (db_r->db, "taxon") != 0) {
2547         db_r = NULL;
2548       }
2549     }
2550   }
2551 
2552   if (db_r == NULL) {
2553     return;
2554   }
2555   if (db_o->tag->id > 0) {
2556     sprintf (buf1, "%d", db_o->tag->id);
2557     tag1 = buf1;
2558   } else if (db_o->tag->str == NULL) {
2559     buf1[0] = 0;
2560     tag1 = buf1;
2561   } else {
2562     tag1 = db_o->tag->str;
2563   }
2564   if (db_r->tag->id > 0) {
2565     sprintf (buf2, "%d", db_r->tag->id);
2566     tag2 = buf2;
2567   } else if (db_r->tag->str == NULL) {
2568     buf2[0] = 0;
2569     tag2 = buf2;
2570   } else {
2571     tag2 = db_r->tag->str;
2572   }
2573   if (!ObjectIdMatch (db_o->tag, db_r->tag)) {
2574     ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_TaxonomyLookupProblem,
2575       "Organism name is '%s', taxonomy ID should be '%s' but is '%s'", orig->taxname == NULL ? "" : orig->taxname,
2576                                                                         tag2, tag1);
2577   }
2578 }
2579 
2580 
IsINSDpatent(BioseqPtr bsp,Pointer userdata)2581 static void IsINSDpatent (BioseqPtr bsp, Pointer userdata)
2582 
2583 {
2584   BoolPtr   bp;
2585   Boolean   is_insd = FALSE;
2586   Boolean   is_patent = FALSE;
2587   SeqIdPtr  sip;
2588 
2589   if (bsp == NULL || userdata == NULL) return;
2590 
2591   for (sip = bsp->id; sip != NULL; sip = sip->next) {
2592     switch (sip->choice) {
2593       case SEQID_GENBANK :
2594       case SEQID_EMBL :
2595       case SEQID_DDBJ :
2596         is_insd = TRUE;
2597         break;
2598       case SEQID_PATENT :
2599         is_patent = TRUE;
2600         break;
2601       default :
2602         break;
2603     }
2604   }
2605 
2606   if (is_insd && is_patent) {
2607     bp = (BoolPtr) userdata;
2608     *bp = TRUE;
2609   }
2610 }
2611 
TaxonValidate(SeqEntryPtr sep,ValidStructPtr vsp)2612 static void TaxonValidate (SeqEntryPtr sep, ValidStructPtr vsp)
2613 
2614 {
2615   GatherContext     gc;
2616   Boolean           has_nucleomorphs;
2617   Boolean           is_insd_patent = FALSE;
2618   Boolean           is_nucleomorph;
2619   Boolean           is_species_level;
2620   Boolean           force_tax_consult;
2621   Boolean           has_plastids;
2622   ValNodePtr        last = NULL;
2623   OrgNamePtr        onp;
2624   OrgRefPtr         orp;
2625   ErrSev            sev;
2626   TaxLst            srclist;
2627   CharPtr           str;
2628   T3ErrorPtr        t3ep;
2629   Taxon3RequestPtr  t3rq;
2630   Taxon3ReplyPtr    t3ry;
2631   T3DataPtr         tdp;
2632   T3StatusFlagsPtr  tfp;
2633   T3ReplyPtr        trp;
2634   TaxValPtr         tvp;
2635   ValNodePtr        val;
2636   ValNodePtr        vnp;
2637   ValNodePtr        vnp2;
2638 
2639   if (sep == NULL || vsp == NULL) return;
2640   MemSet ((Pointer) &gc, 0, sizeof (GatherContext));
2641   vsp->gcp = &gc;
2642 
2643   VisitBioseqsInSep (sep, (Pointer) &is_insd_patent, IsINSDpatent);
2644 
2645   srclist.head = NULL;
2646   srclist.tail = NULL;
2647   VisitDescriptorsInSep (sep, (Pointer) &srclist, GetSrcDesc);
2648   VisitFeaturesInSep (sep, (Pointer) &srclist, GetSrcFeat);
2649   if (srclist.head == NULL) return;
2650 
2651   t3rq = Taxon3RequestNew ();
2652   if (t3rq == NULL) return;
2653 
2654   for (vnp = srclist.head; vnp != NULL; vnp = vnp->next) {
2655     tvp = (TaxValPtr) vnp->data.ptrvalue;
2656     if (tvp == NULL) continue;
2657     orp = AsnIoMemCopy (tvp->orp,
2658                         (AsnReadFunc) OrgRefAsnRead,
2659                         (AsnWriteFunc) OrgRefAsnWrite);
2660     vnp2 = ValNodeAddPointer (&last, 3, (Pointer) orp);
2661     if (orp != NULL) {
2662       onp = orp->orgname;
2663       if (onp != NULL) {
2664         onp->pgcode = 0;
2665       }
2666     }
2667     if (t3rq->request == NULL) {
2668       t3rq->request = vnp2;
2669     }
2670     last = vnp2;
2671   }
2672 
2673 #ifdef OS_UNIX
2674   if (! log_tax_set) {
2675     str = (CharPtr) getenv ("LOG_TAX_ASN");
2676     if (StringDoesHaveText (str)) {
2677       if (StringICmp (str, "TRUE") == 0) {
2678         log_tax_asn = TRUE;
2679       }
2680     }
2681     log_tax_set = TRUE;
2682   }
2683 #endif
2684 
2685   sev = ErrSetMessageLevel (SEV_WARNING);
2686   if (log_tax_asn) {
2687     LaunchAsnTextViewer ((Pointer) t3rq, (AsnWriteFunc) Taxon3RequestAsnWrite, "tax3 request");
2688   }
2689   t3ry = Tax3SynchronousQuery (t3rq);
2690   ErrSetMessageLevel (sev);
2691   Taxon3RequestFree (t3rq);
2692   if (t3ry == NULL) return;
2693   if (log_tax_asn) {
2694     LaunchAsnTextViewer ((Pointer) t3ry, (AsnWriteFunc) Taxon3ReplyAsnWrite, "tax3 result");
2695   }
2696 
2697   for (trp = t3ry->reply, vnp = srclist.head;
2698        trp != NULL && vnp != NULL;
2699        trp = trp->next, vnp = vnp->next) {
2700     tvp = (TaxValPtr) vnp->data.ptrvalue;
2701     if (tvp == NULL) continue;
2702     if (trp->choice == T3Reply_error) {
2703       t3ep = (T3ErrorPtr) trp->data.ptrvalue;
2704       if (t3ep != NULL) {
2705         str = t3ep->message;
2706         if (str == NULL) {
2707           str = "?";
2708         }
2709 
2710         vsp->bssp = NULL;
2711         vsp->bsp = tvp->bsp;
2712         vsp->sfp = tvp->sfp;
2713         vsp->descr = NULL;
2714 
2715         gc.entityID = tvp->entityID;
2716         gc.itemID = tvp->itemID;
2717         gc.thistype = tvp->itemtype;
2718 
2719         if (StringCmp (str, "Organism not found") == 0) {
2720           ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_OrganismNotFound, "Organism not found in taxonomy database");
2721         } else {
2722           ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_TaxonomyLookupProblem, "Taxonomy lookup failed with message '%s'", str);
2723         }
2724       }
2725     }
2726     if (trp->choice != T3Reply_data) continue;
2727     tdp = (T3DataPtr) trp->data.ptrvalue;
2728     if (tdp == NULL) continue;
2729 
2730     vsp->bssp = NULL;
2731     vsp->bsp = tvp->bsp;
2732     vsp->sfp = tvp->sfp;
2733     vsp->descr = NULL;
2734 
2735     ReportBadTaxID (vsp, tvp->orp, tdp->org);
2736 
2737     is_species_level = FALSE;
2738     has_nucleomorphs = FALSE;
2739     is_nucleomorph = FALSE;
2740     has_plastids = FALSE;
2741 
2742     for (tfp = tdp->status; tfp != NULL; tfp = tfp->next) {
2743 
2744       /*
2745       val = tfp->Value_value;
2746       if (val != NULL && val->choice == Value_value_bool) {
2747         str = tfp->property;
2748         if (str == NULL) {
2749           str = "?";
2750         }
2751         if (val->data.intvalue != 0) {
2752           ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_TaxonomyLookupProblem, "'%s' TRUE", str);
2753         } else {
2754           ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_TaxonomyLookupProblem, "'%s' FALSE", str);
2755         }
2756       }
2757       */
2758 
2759       if (StringICmp (tfp->property, "is_species_level") == 0) {
2760         val = tfp->Value_value;
2761         if (val != NULL && val->choice == Value_value_bool) {
2762           is_species_level = (Boolean) (val->data.intvalue != 0);
2763           if (! is_species_level) {
2764             gc.entityID = tvp->entityID;
2765             gc.itemID = tvp->itemID;
2766             gc.thistype = tvp->itemtype;
2767 
2768             if (! vsp->is_wp_in_sep) {
2769               ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_TaxonomyIsSpeciesProblem, "Taxonomy lookup reports is_species_level FALSE");
2770             }
2771           }
2772         }
2773       } else if (StringICmp (tfp->property, "force_consult") == 0) {
2774         val = tfp->Value_value;
2775         if (val != NULL && val->choice == Value_value_bool) {
2776           force_tax_consult = (Boolean) (val->data.intvalue != 0);
2777           if (force_tax_consult && is_insd_patent) {
2778             orp = (OrgRefPtr) tdp->org;
2779             if (orp != NULL) {
2780               if (StringICmp (orp->taxname, "unidentified") == 0) {
2781                 force_tax_consult = FALSE;
2782               }
2783             }
2784           }
2785           if (force_tax_consult) {
2786             gc.entityID = tvp->entityID;
2787             gc.itemID = tvp->itemID;
2788             gc.thistype = tvp->itemtype;
2789 
2790             ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_TaxonomyConsultRequired, "Taxonomy lookup reports taxonomy consultation needed");
2791           }
2792         }
2793       } else if (StringICmp (tfp->property, "has_nucleomorphs") == 0) {
2794         val = tfp->Value_value;
2795         if (val != NULL && val->choice == Value_value_bool) {
2796           has_nucleomorphs = (Boolean) (val->data.intvalue != 0);
2797           if (has_nucleomorphs) {
2798             is_nucleomorph = TRUE;
2799           }
2800         }
2801       } else if (StringICmp (tfp->property, "has_plastids") == 0) {
2802         val = tfp->Value_value;
2803         if (val != NULL && val->choice == Value_value_bool) {
2804           has_plastids = (Boolean) (val->data.intvalue != 0);
2805         }
2806       }
2807     }
2808     if (tvp->organelle == GENOME_nucleomorph && (! is_nucleomorph)) {
2809       ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_TaxonomyNucleomorphProblem, "Taxonomy lookup does not have expected nucleomorph flag");
2810     } else if (tvp->organelle == GENOME_plastid && (! has_plastids)) {
2811       ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_TaxonomyPlastidsProblem, "Taxonomy lookup does not have expected plastid flag");
2812     }
2813   }
2814 
2815   Taxon3ReplyFree (t3ry);
2816   ValNodeFreeData (srclist.head);
2817 
2818   /* also validate specific-host values */
2819 
2820   ReportBadSpecificHostValues (sep, vsp);
2821 
2822   StructCommentTentativeNameValidate (sep, vsp);
2823 }
2824 
RecordTentativeName(Uint2 entityID,Uint4 itemID,Uint2 itemtype,UserObjectPtr uop,TaxLstPtr tlp,SeqDescrPtr sdp,SeqFeatPtr sfp)2825 static void RecordTentativeName (Uint2 entityID, Uint4 itemID, Uint2 itemtype, UserObjectPtr uop,
2826                                  TaxLstPtr tlp, SeqDescrPtr sdp, SeqFeatPtr sfp)
2827 
2828 {
2829   BioseqPtr      bsp;
2830   BioseqSetPtr   bssp;
2831   UserFieldPtr   curr;
2832   CharPtr        field;
2833   ObjectIdPtr    oip;
2834   OrgRefPtr      orp;
2835   ObjValNodePtr  ovp;
2836   SeqEntryPtr    sep;
2837   CharPtr        str;
2838   CharPtr        taxname = NULL;
2839   TaxValPtr      tvp;
2840   ValNodePtr     vnp;
2841 
2842   if (uop == NULL || tlp == NULL) return;
2843 
2844   oip = uop->type;
2845   if (oip == NULL || StringICmp (oip->str, "StructuredComment") != 0) return;
2846   for (curr = uop->data; curr != NULL; curr = curr->next) {
2847     if (curr->choice != 1) continue;
2848     oip = curr->label;
2849     if (oip == NULL) continue;
2850     field = oip->str;
2851     if (StringHasNoText (field)) continue;
2852     if (StringCmp (field, "Tentative Name") != 0) continue;
2853     str = (CharPtr) curr->data.ptrvalue;
2854     if (StringHasNoText (str)) continue;
2855     if (StringCmp (str, "not provided") == 0) continue;
2856     taxname = str;
2857   }
2858   if (StringHasNoText (taxname)) return;
2859 
2860   tvp = (TaxValPtr) MemNew (sizeof (TaxVal));
2861   if (tvp == NULL) return;
2862 
2863   vnp = ValNodeNew (tlp->tail);
2864   if (vnp == NULL) return;
2865 
2866   if (tlp->head == NULL) {
2867     tlp->head = vnp;
2868   }
2869   tlp->tail = vnp;
2870 
2871   tvp->entityID = entityID;
2872   tvp->itemID = itemID;
2873   tvp->itemtype = itemtype;
2874   tvp->organelle = 0;
2875 
2876   orp = OrgRefNew ();
2877   if (orp == NULL) return;
2878   orp->taxname = StringSave (taxname);
2879 
2880   tvp->orp = orp;
2881   if (sdp != NULL && sdp->extended != 0) {
2882     ovp = (ObjValNodePtr) sdp;
2883     if (ovp->idx.parenttype == OBJ_BIOSEQ) {
2884       bsp = (BioseqPtr) ovp->idx.parentptr;
2885       if (bsp != NULL) {
2886         tvp->bsp = bsp;
2887       }
2888     } else if (ovp->idx.parenttype == OBJ_BIOSEQSET) {
2889       bssp = (BioseqSetPtr) ovp->idx.parentptr;
2890       if (bssp != NULL) {
2891         sep = bssp->seqentry;
2892         if (sep != NULL) {
2893           sep = FindNthBioseq (sep, 1);
2894           if (sep != NULL) {
2895             bsp = (BioseqPtr) sep->data.ptrvalue;
2896             if (bsp != NULL) {
2897               tvp->bsp = bsp;
2898             }
2899           }
2900         }
2901       }
2902     }
2903   } else if (sfp != NULL) {
2904     tvp->sfp = sfp;
2905   }
2906 
2907   vnp->data.ptrvalue = tvp;
2908 }
2909 
GetTentativeNameDesc(SeqDescrPtr sdp,Pointer userdata)2910 static void GetTentativeNameDesc (SeqDescrPtr sdp, Pointer userdata)
2911 
2912 {
2913   ObjValNodePtr  ovp;
2914   TaxLstPtr      tlp;
2915   UserObjectPtr  uop;
2916 
2917   if (sdp == NULL || sdp->choice != Seq_descr_user) return;
2918   tlp = (TaxLstPtr) userdata;
2919 
2920   uop = (UserObjectPtr) sdp->data.ptrvalue;
2921   if (uop == NULL) return;
2922 
2923   if (sdp->extended != 0) {
2924     ovp = (ObjValNodePtr) sdp;
2925     RecordTentativeName (ovp->idx.entityID, ovp->idx.itemID, OBJ_SEQDESC, uop, tlp, sdp, NULL);
2926   }
2927 }
2928 
GetTentativeNameFeat(SeqFeatPtr sfp,Pointer userdata)2929 static void GetTentativeNameFeat (SeqFeatPtr sfp, Pointer userdata)
2930 
2931 {
2932   TaxLstPtr      tlp;
2933   UserObjectPtr  uop;
2934 
2935   if (sfp == NULL || sfp->data.choice != SEQFEAT_USER) return;
2936   tlp = (TaxLstPtr) userdata;
2937 
2938   uop = (UserObjectPtr) sfp->data.value.ptrvalue;
2939   if (uop == NULL) return;
2940 
2941   RecordTentativeName (sfp->idx.entityID, sfp->idx.itemID, OBJ_SEQFEAT, uop, tlp, NULL, sfp);
2942 }
2943 
StructCommentTentativeNameValidate(SeqEntryPtr sep,ValidStructPtr vsp)2944 static void StructCommentTentativeNameValidate (SeqEntryPtr sep, ValidStructPtr vsp)
2945 
2946 {
2947   GatherContext     gc;
2948   ValNodePtr        last = NULL;
2949   OrgNamePtr        onp;
2950   OrgRefPtr         orp;
2951   ErrSev            sev;
2952   TaxLst            srclist;
2953   CharPtr           str;
2954   T3ErrorPtr        t3ep;
2955   Taxon3RequestPtr  t3rq;
2956   Taxon3ReplyPtr    t3ry;
2957   T3ReplyPtr        trp;
2958   TaxValPtr         tvp;
2959   ValNodePtr        vnp;
2960   ValNodePtr        vnp2;
2961 
2962   if (sep == NULL || vsp == NULL) return;
2963   MemSet ((Pointer) &gc, 0, sizeof (GatherContext));
2964   vsp->gcp = &gc;
2965 
2966   srclist.head = NULL;
2967   srclist.tail = NULL;
2968   VisitDescriptorsInSep (sep, (Pointer) &srclist, GetTentativeNameDesc);
2969   VisitFeaturesInSep (sep, (Pointer) &srclist, GetTentativeNameFeat);
2970   if (srclist.head == NULL) return;
2971 
2972   t3rq = Taxon3RequestNew ();
2973   if (t3rq == NULL) return;
2974 
2975   for (vnp = srclist.head; vnp != NULL; vnp = vnp->next) {
2976     tvp = (TaxValPtr) vnp->data.ptrvalue;
2977     if (tvp == NULL) continue;
2978     orp = AsnIoMemCopy (tvp->orp,
2979                         (AsnReadFunc) OrgRefAsnRead,
2980                         (AsnWriteFunc) OrgRefAsnWrite);
2981     vnp2 = ValNodeAddPointer (&last, 3, (Pointer) orp);
2982     if (orp != NULL) {
2983       onp = orp->orgname;
2984       if (onp != NULL) {
2985         onp->pgcode = 0;
2986       }
2987     }
2988     if (t3rq->request == NULL) {
2989       t3rq->request = vnp2;
2990     }
2991     last = vnp2;
2992   }
2993 
2994 #ifdef OS_UNIX
2995   if (! log_tax_set) {
2996     str = (CharPtr) getenv ("LOG_TAX_ASN");
2997     if (StringDoesHaveText (str)) {
2998       if (StringICmp (str, "TRUE") == 0) {
2999         log_tax_asn = TRUE;
3000       }
3001     }
3002     log_tax_set = TRUE;
3003   }
3004 #endif
3005 
3006   sev = ErrSetMessageLevel (SEV_WARNING);
3007   if (log_tax_asn) {
3008     LaunchAsnTextViewer ((Pointer) t3rq, (AsnWriteFunc) Taxon3RequestAsnWrite, "tax3 request");
3009   }
3010   t3ry = Tax3SynchronousQuery (t3rq);
3011   ErrSetMessageLevel (sev);
3012   Taxon3RequestFree (t3rq);
3013   if (t3ry == NULL) return;
3014   if (log_tax_asn) {
3015     LaunchAsnTextViewer ((Pointer) t3ry, (AsnWriteFunc) Taxon3ReplyAsnWrite, "tax3 result");
3016   }
3017 
3018   for (trp = t3ry->reply, vnp = srclist.head;
3019        trp != NULL && vnp != NULL;
3020        trp = trp->next, vnp = vnp->next) {
3021     tvp = (TaxValPtr) vnp->data.ptrvalue;
3022     if (tvp == NULL) continue;
3023     if (trp->choice == T3Reply_error) {
3024       t3ep = (T3ErrorPtr) trp->data.ptrvalue;
3025       if (t3ep != NULL) {
3026         str = NULL;
3027         orp = t3ep->org;
3028         if (orp != NULL) {
3029           str = orp->taxname;
3030         }
3031         if (str == NULL) {
3032           str = "?";
3033         }
3034 
3035         vsp->bssp = NULL;
3036         vsp->bsp = tvp->bsp;
3037         vsp->sfp = tvp->sfp;
3038         vsp->descr = NULL;
3039 
3040         gc.entityID = tvp->entityID;
3041         gc.itemID = tvp->itemID;
3042         gc.thistype = tvp->itemtype;
3043 
3044         ValidErr (vsp, SEV_WARNING, ERR_SEQ_DESCR_BadTentativeName, "Taxonomy lookup failed for Tentative Name '%s'", str);
3045       }
3046     }
3047   }
3048 
3049   Taxon3ReplyFree (t3ry);
3050   ValNodeFreeData (srclist.head);
3051 }
3052 
3053 
UseLessClickingOption(void)3054 NLM_EXTERN Boolean UseLessClickingOption (void)
3055 {
3056   Boolean less_clicking = FALSE;
3057   Char            str [32];
3058 
3059   if (GetSequinAppParam ("SETTINGS", "LESS_CLICKING", NULL, str, sizeof (str))) {
3060     if (StringICmp (str, "TRUE") == 0) {
3061       less_clicking = TRUE;
3062     }
3063   }
3064   return less_clicking;
3065 }
3066 
3067 
ValSeqEntryFormExEx(ForM f,Boolean doAligns,Int2 limit,Boolean inferenceAccnCheck,FormActnFunc revalProc,FormActnFunc revalNoTaxProc,FormActnFunc doneProc)3068 static void ValSeqEntryFormExEx (ForM f, Boolean doAligns, Int2 limit, Boolean inferenceAccnCheck, FormActnFunc revalProc, FormActnFunc revalNoTaxProc, FormActnFunc doneProc)
3069 
3070 {
3071   Boolean         allRawOrSeg = TRUE;
3072   BaseFormPtr     bfp;
3073   Char            buf [32];
3074   Int2            errors;
3075   Int2            j;
3076   ErrHookProc     oldErrHook;
3077   ErrSev          oldErrSev;
3078   SeqEntryPtr     sep;
3079   Char            str [32];
3080   WindoW          validatorWindow = NULL;
3081   Int2            verbosity;
3082   ValidStructPtr  vsp;
3083 
3084   bfp = (BaseFormPtr) GetObjectExtra (f);
3085   if (bfp != NULL) {
3086     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3087     if (sep != NULL) {
3088       /*
3089       if (! EntrezIsInited ()) {
3090         SequinEntrezInit ("Sequin", FALSE, NULL);
3091       }
3092       */
3093       vsp = ValidStructNew ();
3094       if (vsp != NULL) {
3095         WatchCursor ();
3096         Update ();
3097         /*SetChecklistValue (checklistForm, 6);*/
3098 
3099        verbosity = 1;
3100        if (GetSequinAppParam ("SETTINGS", "VALIDATEVERBOSITY", NULL, buf, sizeof (buf))) {
3101           if (! StrToInt (buf, &verbosity)) {
3102             verbosity = 1;
3103           }
3104         }
3105 
3106         validatorWindow = CreateValidateWindowExExEx (ValidNotify, "Sequin Validation Errors",
3107                                                   programFont, SEV_INFO, verbosity, bfp,
3108                                                   revalProc, revalNoTaxProc, doneProc,
3109                                                   doneProc == NULL && OkToSequester () ? SequesterSequenceList : NULL,
3110                                                   doneProc == NULL ? SegregateSequenceList : NULL,
3111                                                   TRUE);
3112         ClearValidateWindow ();
3113         SeqEntryExplore (sep, (Pointer) (&allRawOrSeg), CheckForCookedBioseqs);
3114         if (allRawOrSeg) {
3115           vsp->useSeqMgrIndexes = TRUE;
3116         }
3117         if (indexerVersion) {
3118           vsp->alwaysRequireIsoJTA = TRUE;
3119           vsp->farFetchCDSproducts = TRUE;
3120           vsp->farFetchMRNAproducts = TRUE;
3121         }
3122         vsp->validationLimit = limit;
3123         HideValidateDoc ();
3124         vsp->suppressContext = ShouldSetSuppressContext ();
3125         vsp->justShowAccession = ShouldSetJustShowAccession ();
3126         if (doAligns) {
3127           vsp->validateAlignments = TRUE;
3128           vsp->alignFindRemoteBsp = TRUE;
3129           vsp->doSeqHistAssembly = TRUE;
3130           vsp->farIDsInAlignments = (Boolean) (subtoolMode || smartnetMode || dirsubMode);
3131           if (GetSequinAppParam ("SETTINGS", "VALIDATEFARALIGNIDS", NULL, str, sizeof (str))) {
3132             if (StringICmp (str, "TRUE") == 0) {
3133               vsp->farIDsInAlignments = TRUE;
3134             }
3135           }
3136         }
3137         if (useEntrez && inferenceAccnCheck) {
3138           LookupFarSeqIDs (sep, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3139           vsp->inferenceAccnCheck = TRUE;
3140         }
3141         vsp->testLatLonSubregion = testLatLonSubregion;
3142         vsp->strictLatLonCountry = strictLatLonCountry;
3143         vsp->indexerVersion = indexerVersion;
3144         oldErrHook = ErrSetHandler (ValidErrHook);
3145         oldErrSev = ErrSetMessageLevel (SEV_NONE);
3146         for (j = 0; j < 6; j++) {
3147           vsp->errors [j] = 0;
3148         }
3149         vsp->errfunc = ValidErrCallback;
3150         SequinValidateSeqEntry (sep, vsp);
3151         if (indexerVersion && useEntrez && IsTaxValidationRequested(validatorWindow)) {
3152           SetTitle (validatorWindow, "Validating Taxonomy");
3153           Update ();
3154           TaxonValidate (sep, vsp);
3155           SetTitle (validatorWindow, "Sequin Validation Errors");
3156           Update ();
3157         }
3158         ErrSetMessageLevel (oldErrSev);
3159         ErrSetHandler (oldErrHook);
3160         ErrClear ();
3161         ShowValidateDoc ();
3162         errors = 0;
3163         for (j = 0; j < 6; j++) {
3164           errors += vsp->errors [j];
3165         }
3166         if (errors == 0) {
3167           ArrowCursor ();
3168           if (UseLessClickingOption()) {
3169             Message (MSG_POSTERR, "Validation test succeeded.");
3170           } else {
3171             Message (MSG_OK, "Validation test succeeded.");
3172           }
3173           FreeValidateWindow ();
3174         } else {
3175           RepopulateValidateFilter ();
3176         }
3177         ValidStructFree (vsp);
3178         /*SetChecklistValue (checklistForm, 5);*/
3179         ArrowCursor ();
3180         Update ();
3181       }
3182     }
3183   }
3184 }
3185 
3186 
ValSeqEntryFormEx(ForM f,Boolean doAligns,Int2 limit,Boolean inferenceAccnCheck)3187 static void ValSeqEntryFormEx (ForM f, Boolean doAligns, Int2 limit, Boolean inferenceAccnCheck)
3188 
3189 {
3190   ValSeqEntryFormExEx (f, doAligns, limit, inferenceAccnCheck, ValSeqEntryForm, ValSeqEntryForm, NULL);
3191 }
3192 
CountInfAccnVer(SeqFeatPtr sfp,Pointer userdata)3193 static void CountInfAccnVer (SeqFeatPtr sfp, Pointer userdata)
3194 
3195 {
3196   Int4Ptr    countP;
3197   GBQualPtr  gbq;
3198 
3199   if (sfp == NULL || userdata == NULL) return;
3200   countP = (Int4Ptr) userdata;
3201 
3202   for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
3203     if (StringICmp (gbq->qual, "inference") == 0) {
3204       (*countP)++;
3205     }
3206   }
3207 }
3208 
SmallInferenceAccnVer(ForM f)3209 static Boolean SmallInferenceAccnVer (ForM f)
3210 
3211 {
3212   BaseFormPtr  bfp;
3213   Int4         count = 0;
3214   SeqEntryPtr  sep;
3215 
3216   bfp = (BaseFormPtr) GetObjectExtra (f);
3217   if (bfp == NULL) return FALSE;
3218 
3219   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3220   if (sep == NULL) return FALSE;
3221 
3222   VisitFeaturesInSep (sep, (Pointer) &count, CountInfAccnVer);
3223 
3224   if (count < 100) return TRUE;
3225 
3226   if (indexerVersion) {
3227     Message (MSG_POST, "Validation skipping %ld inference accession.version tests",
3228              (long) count);
3229   }
3230 
3231   return FALSE;
3232 }
3233 
ValSeqEntryForm(ForM f)3234 extern void ValSeqEntryForm (ForM f)
3235 
3236 {
3237   Boolean  inferenceAccnCheck;
3238 
3239   inferenceAccnCheck = SmallInferenceAccnVer (f);
3240   ValSeqEntryFormEx (f, TRUE, VALIDATE_ALL, inferenceAccnCheck);
3241 }
3242 
3243 
ValSeqEntryProc(IteM i)3244 static void ValSeqEntryProc (IteM i)
3245 
3246 {
3247   BaseFormPtr  bfp;
3248   Boolean      inferenceAccnCheck;
3249 
3250 #ifdef WIN_MAC
3251   bfp = (BaseFormPtr) currentFormDataPtr;
3252 #else
3253   bfp = (BaseFormPtr) GetObjectExtra (i);
3254 #endif
3255   if (bfp != NULL) {
3256     inferenceAccnCheck = SmallInferenceAccnVer (bfp->form);
3257     ValSeqEntryFormEx (bfp->form, TRUE, VALIDATE_ALL, inferenceAccnCheck);
3258   }
3259 }
3260 
ValSeqEntryProcNoAln(IteM i)3261 static void ValSeqEntryProcNoAln (IteM i)
3262 
3263 {
3264   BaseFormPtr  bfp;
3265 
3266 #ifdef WIN_MAC
3267   bfp = (BaseFormPtr) currentFormDataPtr;
3268 #else
3269   bfp = (BaseFormPtr) GetObjectExtra (i);
3270 #endif
3271   if (bfp != NULL) {
3272     ValSeqEntryFormEx (bfp->form, FALSE, VALIDATE_ALL, FALSE);
3273   }
3274 }
3275 
ValSeqEntryProcInfAccn(IteM i)3276 static void ValSeqEntryProcInfAccn (IteM i)
3277 
3278 {
3279   BaseFormPtr  bfp;
3280 
3281 #ifdef WIN_MAC
3282   bfp = (BaseFormPtr) currentFormDataPtr;
3283 #else
3284   bfp = (BaseFormPtr) GetObjectExtra (i);
3285 #endif
3286   if (bfp != NULL) {
3287     ValSeqEntryFormEx (bfp->form, FALSE, VALIDATE_ALL, TRUE);
3288   }
3289 }
3290 
ValSeqEntryProcSpec(IteM i,Int2 limit)3291 static void ValSeqEntryProcSpec (IteM i, Int2 limit)
3292 
3293 {
3294   BaseFormPtr  bfp;
3295 
3296 #ifdef WIN_MAC
3297   bfp = (BaseFormPtr) currentFormDataPtr;
3298 #else
3299   bfp = (BaseFormPtr) GetObjectExtra (i);
3300 #endif
3301   if (bfp != NULL) {
3302     ValSeqEntryFormEx (bfp->form, FALSE, limit, FALSE);
3303   }
3304 }
3305 
ValSeqEntryProcInst(IteM i)3306 static void ValSeqEntryProcInst (IteM i)
3307 
3308 {
3309   ValSeqEntryProcSpec (i, VALIDATE_INST);
3310 }
3311 
ValSeqEntryProcHist(IteM i)3312 static void ValSeqEntryProcHist (IteM i)
3313 
3314 {
3315   ValSeqEntryProcSpec (i, VALIDATE_HIST);
3316 }
3317 
ValSeqEntryProcContext(IteM i)3318 static void ValSeqEntryProcContext (IteM i)
3319 
3320 {
3321   ValSeqEntryProcSpec (i, VALIDATE_CONTEXT);
3322 }
3323 
ValSeqEntryProcGraph(IteM i)3324 static void ValSeqEntryProcGraph (IteM i)
3325 
3326 {
3327   ValSeqEntryProcSpec (i, VALIDATE_GRAPH);
3328 }
3329 
ValSeqEntryProcSet(IteM i)3330 static void ValSeqEntryProcSet (IteM i)
3331 
3332 {
3333   ValSeqEntryProcSpec (i, VALIDATE_SET);
3334 }
3335 
ValSeqEntryProcFeat(IteM i)3336 static void ValSeqEntryProcFeat (IteM i)
3337 
3338 {
3339   ValSeqEntryProcSpec (i, VALIDATE_FEAT);
3340 }
3341 
ValSeqEntryProcDesc(IteM i)3342 static void ValSeqEntryProcDesc (IteM i)
3343 
3344 {
3345   ValSeqEntryProcSpec (i, VALIDATE_DESC);
3346 }
3347 
3348 
3349 extern Int4 MySeqEntryToAsn3Ex (SeqEntryPtr sep, Boolean strip, Boolean correct, Boolean force, Boolean dotaxon);
MySeqEntryToAsn3(SeqEntryPtr sep,Boolean strip,Boolean correct,Boolean force)3350 extern Int4 MySeqEntryToAsn3 (SeqEntryPtr sep, Boolean strip, Boolean correct, Boolean force)
3351 
3352 {
3353   Boolean  dotaxon;
3354 
3355   dotaxon = FALSE;
3356 /*#ifdef INTERNAL_NCBI_SEQUIN*/
3357   if (indexerVersion) {
3358     if (subtoolMode || smartnetMode) {
3359       dotaxon = TRUE;
3360     }
3361   }
3362 /*#endif*/
3363   return MySeqEntryToAsn3Ex (sep, strip, correct, force, dotaxon);
3364 }
3365 
3366 
MsgForDisplay(CharPtr intro,ValNodePtr list,CharPtr conclusion)3367 static CharPtr MsgForDisplay (CharPtr intro, ValNodePtr list, CharPtr conclusion)
3368 {
3369   Int4 len, num;
3370   CharPtr msg;
3371   ValNodePtr vnp;
3372 
3373   len = StringLen (intro) + StringLen (conclusion) + 1;
3374   for (vnp = list; vnp != NULL; vnp = vnp->next) {
3375     len += StringLen (vnp->data.ptrvalue) + 2;
3376   }
3377   msg = (CharPtr) MemNew (sizeof (Char) * len);
3378   StringCpy (msg, intro);
3379   for (vnp = list, num = 0; vnp != NULL; vnp = vnp->next, num++) {
3380     StringCat (msg, (CharPtr) vnp->data.ptrvalue);
3381     if (vnp->next == NULL) {
3382       StringCat (msg, "\n\n");
3383     } else if (num % 3 == 2) {
3384       StringCat (msg, ",\n");
3385     } else {
3386       StringCat (msg, ", ");
3387     }
3388   }
3389   StringCat (msg, conclusion);
3390   return msg;
3391 }
3392 
3393 
DisplayAndFreeTestResults(ValNodePtr head)3394 static Boolean DisplayAndFreeTestResults (ValNodePtr head)
3395 
3396 {
3397   MsgAnswer    ans;
3398   CharPtr      str;
3399   ValNodePtr   missing_list;
3400   ValNodePtr   warning_list;
3401   ValNodePtr   invalid_list;
3402   Boolean      rval = TRUE;
3403 
3404   if (head == NULL) {
3405     return TRUE;
3406   }
3407 
3408   warning_list = ValNodeExtractList (&head, TESTRESULT_WARN);
3409   missing_list = ValNodeExtractList (&head, TESTRESULT_MISSING);
3410   invalid_list = ValNodeExtractList (&head, TESTRESULT_INVALID);
3411 
3412   if (missing_list != NULL) {
3413     str = MsgForDisplay("The following essential information is missing:\n\n", missing_list, "Please fill in the essential information.");
3414     Message (MSG_OK, str);
3415     str = MemFree (str);
3416     rval = FALSE;
3417   } else if (invalid_list != NULL) {
3418     str = MsgForDisplay("The following essential information contains all punctuation:\n\n", invalid_list, "Please provide valid information for these fields.");
3419     Message (MSG_OK, str);
3420     str = MemFree (str);
3421     rval = FALSE;
3422   } else if (warning_list != NULL && (! indexerVersion)) {
3423     str = MsgForDisplay("The following desired information is missing:\n\n", warning_list, "Do you wish to proceed anyway?");
3424     ans = Message (MSG_YN, str);
3425     str = MemFree (str);
3426     if (ans == ANS_NO) rval = FALSE;
3427   }
3428   missing_list = ValNodeFreeData (missing_list);
3429   invalid_list = ValNodeFreeData (invalid_list);
3430   warning_list = ValNodeFreeData (warning_list);
3431 
3432   return rval;
3433 }
3434 
JustRegisterSeqEntry(BaseFormPtr bfp,Boolean freeit)3435 extern void JustRegisterSeqEntry (BaseFormPtr bfp, Boolean freeit)
3436 
3437 {
3438   Int2  handled;
3439 
3440   if (bfp != NULL) {
3441     Hide (bfp->form);
3442   }
3443   seqviewprocs.filepath = globalPath;
3444   seqviewprocs.forceSeparateViewer = TRUE;
3445   SeqEntrySetScope (NULL);
3446   handled = GatherProcLaunch (OMPROC_VIEW, FALSE, globalEntityID, 1,
3447                               OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
3448   seqviewprocs.filepath = NULL;
3449   ArrowCursor ();
3450   if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
3451     Message (MSG_FATAL, "Unable to launch viewer.");
3452   } else {
3453     SendHelpScrollMessage (helpForm, "Editing the Record", NULL);
3454   }
3455   ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, globalEntityID);
3456   ObjMgrSetDirtyFlag (globalEntityID, TRUE);
3457   if (bfp != NULL && freeit) {
3458     Remove (bfp->form);
3459   }
3460 }
3461 
JustRegisterSeqEntryBtn(ButtoN b)3462 extern void JustRegisterSeqEntryBtn (ButtoN b)
3463 
3464 {
3465   BaseFormPtr  bfp;
3466 
3467   bfp = (BaseFormPtr) GetObjectExtra (b);
3468   JustRegisterSeqEntry (bfp, TRUE);
3469 }
3470 
JustRegisterSeqEntryForm(ForM f)3471 static void JustRegisterSeqEntryForm (ForM f)
3472 
3473 {
3474   BaseFormPtr  bfp;
3475 
3476   bfp = (BaseFormPtr) GetObjectExtra (f);
3477   JustRegisterSeqEntry (bfp, FALSE);
3478 }
3479 
AddSubmitBlockToSeqEntry(ForM f)3480 extern void AddSubmitBlockToSeqEntry (ForM f)
3481 
3482 {
3483   AffilPtr        affil;
3484   AuthListPtr     authors;
3485   BaseFormPtr     bfp;
3486   CitSubPtr       csp;
3487   ValNodePtr      head;
3488   SubmitBlockPtr  sbp;
3489   SeqSubmitPtr    ssp;
3490   CitSubPtr       tmp;
3491 
3492   bfp = (BaseFormPtr) GetObjectExtra (f);
3493   if (bfp != NULL) {
3494     head = TestForm (bfp->form);
3495     if (! DisplayAndFreeTestResults (head)) {
3496       return;
3497     }
3498     Hide (bfp->form);
3499     /*
3500     globalsbp = (SequinBlockPtr) FormToPointer (bfp->form);
3501     if (globalsbp == NULL) {
3502       Message (MSG_OK, "Record will be a Seq-entry instead of a Seq-submit.");
3503     }
3504     */
3505     sbp = (SubmitBlockPtr) FormToPointer (bfp->form);
3506     if (sbp == NULL) {
3507       Message (MSG_OK, "Record will be a Seq-entry instead of a Seq-submit.");
3508     }
3509     Update ();
3510     /*
3511     globalEntityID = PackageFormResults (globalsbp, globalsep, FALSE);
3512     */
3513     globalEntityID = 0;
3514     if (globalsep != NULL) {
3515       if (sbp != NULL) {
3516         if (sbp->contact != NULL && sbp->cit != NULL) {
3517           tmp = CitSubFromContactInfo (sbp->contact);
3518           csp = sbp->cit;
3519           if (csp->authors != NULL) {
3520             authors = csp->authors;
3521             if (authors->affil == NULL) {
3522               if (tmp != NULL && tmp->authors != NULL) {
3523                 authors = tmp->authors;
3524                 affil = authors->affil;
3525                 authors->affil = NULL;
3526                 authors = csp->authors;
3527                 authors->affil = affil;
3528                 if (affil != NULL) {
3529                   affil->phone = MemFree (affil->phone);
3530                   affil->fax = MemFree (affil->fax);
3531                   affil->email = MemFree (affil->email);
3532                 }
3533               }
3534             }
3535           }
3536           CitSubFree (tmp);
3537         }
3538         ssp = SeqSubmitNew ();
3539         if (ssp != NULL) {
3540           ssp->datatype = 1;
3541           ssp->sub = sbp;
3542           ssp->data = (Pointer) globalsep;
3543           ObjMgrConnect (OBJ_SEQENTRY, globalsep->data.ptrvalue, OBJ_SEQSUB, (Pointer) ssp);
3544           if (! ObjMgrRegister (OBJ_SEQSUB, (Pointer) ssp)) {
3545             ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrRegister failed.");
3546           }
3547         } else {
3548           if (! ObjMgrRegister (OBJ_SEQENTRY, (Pointer) globalsep)) {
3549             ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrRegister failed.");
3550           }
3551         }
3552       } else {
3553         if (! ObjMgrRegister (OBJ_SEQENTRY, (Pointer) globalsep)) {
3554           ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrRegister failed.");
3555         }
3556       }
3557       if (EntrezASN1Detected (globalsep)) {
3558         ErrPostEx (SEV_WARNING, 0, 0, "This record was retrieved from Entrez.");
3559       }
3560       globalEntityID = ObjMgrGetEntityIDForChoice (globalsep);
3561     }
3562     globalsbp = NULL;
3563     globalsep = NULL;
3564     JustRegisterSeqEntryForm (f);
3565   }
3566 }
3567 
3568 #ifdef WIN_MAC
3569 static void SubmitBlockActivateProc (WindoW w);
3570 static void GenomeFormActivateProc (WindoW w);
3571 #else
3572 #define SubmitBlockActivateProc NULL
3573 #define GenomeFormActivateProc NULL
3574 #endif
3575 
3576 CharPtr repackageMsg =
3577 "Do you plan to submit this as an update to one of the databases?";
3578 
3579 extern Boolean ProcessOneNucleotideTitle (Int2 seqPackage,
3580                                           SeqEntryPtr nsep, SeqEntryPtr top);
3581 
LookForTaxonID(BioSourcePtr biop,Pointer userdata)3582 static void LookForTaxonID (BioSourcePtr biop, Pointer userdata)
3583 
3584 {
3585   DbtagPtr     dbt;
3586   BoolPtr      notaxid;
3587   ObjectIdPtr  oip;
3588   OrgRefPtr    orp;
3589   ValNodePtr   vnp;
3590 
3591   notaxid = (BoolPtr) userdata;
3592   if (biop == NULL) return;
3593   orp = biop->org;
3594   if (orp == NULL) return;
3595   for (vnp = orp->db; vnp != NULL; vnp = vnp->next) {
3596     dbt = (DbtagPtr) vnp->data.ptrvalue;
3597     if (dbt == NULL) continue;
3598     if (StringICmp (dbt->db, "taxon") != 0) continue;
3599     oip = dbt->tag;
3600     if (oip == NULL) continue;
3601     if (oip->id != 0) return;
3602   }
3603   *notaxid = TRUE;
3604 }
3605 
RnaProtTrailingCommaFix(SeqFeatPtr sfp,Pointer userdata)3606 static void RnaProtTrailingCommaFix (SeqFeatPtr sfp, Pointer userdata)
3607 
3608 {
3609   Char        ch;
3610   size_t      len;
3611   ProtRefPtr  prp;
3612   RnaRefPtr   rrp;
3613   CharPtr     str;
3614   ValNodePtr  vnp;
3615 
3616   if (sfp == NULL) return;
3617 
3618   if (sfp->data.choice == SEQFEAT_PROT) {
3619     prp = (ProtRefPtr) sfp->data.value.ptrvalue;
3620     /* turn trailing space into trailing underscore for validator */
3621     for (vnp = prp->name; vnp != NULL; vnp = vnp->next) {
3622       str = (CharPtr) vnp->data.ptrvalue;
3623       if (StringHasNoText (str)) continue;
3624       len = StringLen (str);
3625       if (len < 1) continue;
3626       ch = str [len - 1];
3627       while (ch == ' ' && len > 2) {
3628         len--;
3629         ch = str [len - 1];
3630       }
3631       if (ch == ',') {
3632         str [len - 1] = '_';
3633         str [len] = '\0';
3634       }
3635     }
3636   } else if (sfp->data.choice == SEQFEAT_RNA) {
3637     rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
3638     /* turn trailing space into trailing underscore for validator */
3639     if (rrp->ext.choice == 1) {
3640       str = rrp->ext.value.ptrvalue;
3641       if (StringDoesHaveText (str)) {
3642         len = StringLen (str);
3643         if (len > 0) {
3644           ch = str [len - 1];
3645           while (ch == ' ' && len > 2) {
3646             len--;
3647             ch = str [len - 1];
3648           }
3649           if (ch == ',') {
3650             str [len - 1] = '_';
3651             str [len] = '\0';
3652           }
3653         }
3654       }
3655     }
3656   }
3657 }
3658 
HandleOneNewAsnProcEx(BaseFormPtr bfp,Boolean removeold,Boolean askForSubmit,CharPtr path,Pointer dataptr,Uint2 datatype,Uint2 entityID,Uint2Ptr updateEntityIDPtr,ValNodePtr PNTR err_list)3659 static Boolean HandleOneNewAsnProcEx (BaseFormPtr bfp, Boolean removeold, Boolean askForSubmit,
3660                                     CharPtr path, Pointer dataptr, Uint2 datatype, Uint2 entityID,
3661                                     Uint2Ptr updateEntityIDPtr, ValNodePtr PNTR err_list)
3662 
3663 {
3664   BioseqPtr     bsp;
3665   BioseqSetPtr  bssp;
3666   Int2          handled;
3667   Boolean       notaxid;
3668   SeqEntryPtr   nsep;
3669   Boolean       processonenuc;
3670   SeqEntryPtr   sep;
3671   ForM          w;
3672 
3673   if (dataptr != NULL && entityID > 0) {
3674     if (datatype == OBJ_SEQSUB || datatype == OBJ_SEQENTRY ||
3675         datatype == OBJ_BIOSEQ || datatype == OBJ_BIOSEQSET) {
3676       WatchCursor ();
3677       sep = GetTopSeqEntryForEntityID (entityID);
3678       if (sep == NULL) {
3679         sep = SeqEntryNew ();
3680         if (sep != NULL) {
3681           if (datatype == OBJ_BIOSEQ) {
3682             bsp = (BioseqPtr) dataptr;
3683             sep->choice = 1;
3684             sep->data.ptrvalue = bsp;
3685             SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
3686           } else if (datatype == OBJ_BIOSEQSET) {
3687             bssp = (BioseqSetPtr) dataptr;
3688             sep->choice = 2;
3689             sep->data.ptrvalue = bssp;
3690             SeqMgrSeqEntry (SM_BIOSEQSET, (Pointer) bssp, sep);
3691           } else {
3692             sep = SeqEntryFree (sep);
3693           }
3694         }
3695         sep = GetTopSeqEntryForEntityID (entityID);
3696       }
3697       if (sep != NULL) {
3698         VisitFeaturesInSep (sep, NULL, RnaProtTrailingCommaFix);
3699         /*
3700         if (seqviewprocs.lockFarComponents) {
3701           bsplist = LockFarComponents (sep);
3702         }
3703         */
3704         nsep = FindNucSeqEntry (sep);
3705         processonenuc = TRUE;
3706         if (IS_Bioseq_set (sep)) {
3707           bssp = (BioseqSetPtr) sep->data.ptrvalue;
3708           if (bssp != NULL) {
3709             if (IsPopPhyEtcSet (bssp->_class)) {
3710               processonenuc = FALSE;
3711             } else if (bssp->_class == 7) {
3712               processonenuc = FALSE;
3713             } else if (bssp->_class == 1 || bssp->_class == 2) {
3714               processonenuc = FALSE;
3715             } else if (bssp->_class == BioseqseqSet_class_gen_prod_set) {
3716               processonenuc = FALSE;
3717             } else if (bssp->_class == 0) {
3718               processonenuc = FALSE;
3719             } else if (bssp->_class == 255) {
3720               processonenuc = FALSE;
3721             }
3722           }
3723         }
3724         if (processonenuc) {
3725           ProcessOneNucleotideTitle (SEQ_PKG_SINGLE, nsep, sep);
3726         }
3727         if (! leaveAsOldAsn) {
3728           notaxid = FALSE;
3729           VisitBioSourcesInSep (sep, (Pointer) &notaxid, LookForTaxonID);
3730           if (notaxid) {
3731             MySeqEntryToAsn3 (sep, TRUE, FALSE, FALSE);
3732           }
3733         }
3734       }
3735       if (sep != NULL) {
3736         if (EntrezASN1Detected (sep)) {
3737           ErrPostEx (SEV_WARNING, 0, 0, "This record was retrieved from Entrez");
3738         }
3739       }
3740       /* no longer support "Do you plan to submit this as an update" question */
3741       askForSubmit = FALSE;
3742       if ((! indexerVersion) && askForSubmit && datatype != OBJ_SEQSUB) {
3743         ArrowCursor ();
3744         Update ();
3745         if (Message (MSG_YN, repackageMsg) == ANS_YES) {
3746           /*
3747           UnlockFarComponents (bsplist);
3748           */
3749           globalEntityID = entityID;
3750           globalsep = sep;
3751           StringNCpy_0 (globalPath, path, sizeof (globalPath));
3752           WatchCursor ();
3753           Update ();
3754           w = CreateSubmitBlockForm (-50, -33, "Submitting Authors",
3755                                      FALSE, TRUE, NULL, JustRegisterSeqEntryBtn,
3756                                      AddSubmitBlockToSeqEntry);
3757           ArrowCursor ();
3758           if (w != NULL) {
3759             Show (w);
3760             Select (w);
3761             SendHelpScrollMessage (helpForm, "Submitting Authors Form", NULL);
3762             return TRUE;
3763           } else {
3764             Message (MSG_FATAL, "Unable to create window.");
3765             return FALSE;
3766           }
3767         }
3768       }
3769       seqviewprocs.filepath = path;
3770       seqviewprocs.forceSeparateViewer = TRUE;
3771       SeqEntrySetScope (NULL);
3772       handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
3773                                   OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
3774       seqviewprocs.filepath = NULL;
3775       /*
3776       UnlockFarComponents (bsplist);
3777       */
3778       ArrowCursor ();
3779       if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
3780         Message (MSG_FATAL, "Unable to launch viewer.");
3781         return FALSE;
3782       } else {
3783         SendHelpScrollMessage (helpForm, "Editing the Record", NULL);
3784       }
3785       ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
3786       ObjMgrSetDirtyFlag (entityID, TRUE);
3787       if (bfp != NULL && removeold) {
3788         Remove (bfp->form);
3789       }
3790       return TRUE;
3791     } else if (datatype == OBJ_SEQANNOT && dataptr != NULL) {
3792       entityID = 0;
3793       if (bfp != NULL) {
3794         entityID = bfp->input_entityID;
3795       }
3796       SeqEntrySetScope (NULL);
3797       entityID = SmartAttachSeqAnnotToSeqEntry (entityID, (SeqAnnotPtr) dataptr, err_list);
3798       ArrowCursor ();
3799       if (entityID != 0) {
3800         /* code to inhibit multiple updates when attaching multiple feature tables to the same entity */
3801         if (updateEntityIDPtr != NULL) {
3802           if (*updateEntityIDPtr == 0) {
3803             *updateEntityIDPtr = entityID;
3804             return TRUE;
3805           } else if (*updateEntityIDPtr == entityID) {
3806             return TRUE;
3807           }
3808         }
3809         ObjMgrSetDirtyFlag (entityID, TRUE);
3810         ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
3811         return TRUE;
3812       }
3813     } else if (datatype == OBJ_PROJECT && dataptr != NULL) {
3814       SeqEntrySetScope (NULL);
3815       HandleProjectAsn ((ProjectPtr) dataptr, entityID);
3816       ArrowCursor ();
3817       return TRUE;
3818     } else {
3819       Message (MSG_ERROR, "Unable to process object type %d.", (int) datatype);
3820       ObjMgrDelete (datatype, dataptr);
3821     }
3822   }
3823   return FALSE;
3824 }
3825 
HandleOneNewAsnProc(BaseFormPtr bfp,Boolean removeold,Boolean askForSubmit,CharPtr path,Pointer dataptr,Uint2 datatype,Uint2 entityID,Uint2Ptr updateEntityIDPtr)3826 static Boolean HandleOneNewAsnProc (BaseFormPtr bfp, Boolean removeold, Boolean askForSubmit,
3827                                     CharPtr path, Pointer dataptr, Uint2 datatype, Uint2 entityID,
3828                                     Uint2Ptr updateEntityIDPtr)
3829 {
3830   return HandleOneNewAsnProcEx (bfp, removeold, askForSubmit, path, dataptr, datatype, entityID,
3831                                 updateEntityIDPtr, NULL);
3832 }
3833 
3834 typedef struct multbioseqform {
3835   FORM_MESSAGE_BLOCK
3836 
3837   BaseFormPtr  bfp;
3838   Char         filename [PATH_MAX];
3839   Boolean      removeold;
3840   Boolean      askForSubmit;
3841   ValNodePtr   sephead;
3842 } MultBioseqForm, PNTR MultBioseqFormPtr;
3843 
CommonHandleMultBioseqs(ButtoN b,Int2 whichbutton)3844 static void CommonHandleMultBioseqs (ButtoN b, Int2 whichbutton)
3845 
3846 {
3847   BioseqPtr          bsp;
3848   BioseqSetPtr       bssp;
3849   Uint1              choice = 0;
3850   Uint2              datatype = 0;
3851   Uint2              entityID = 0;
3852   Boolean            is_na = TRUE;
3853   SeqEntryPtr        list;
3854   MultBioseqFormPtr  mfp;
3855   SeqEntryPtr        next;
3856   ValNodePtr         pip;
3857   ProjectPtr         proj;
3858   SeqEntryPtr        sep;
3859 
3860   mfp = (MultBioseqFormPtr) GetObjectExtra (b);
3861   if (mfp == NULL || mfp->sephead == NULL) return;
3862   Hide (mfp->form);
3863   Update ();
3864   switch (whichbutton) {
3865     case 1 :
3866       proj = ProjectNew ();
3867       if (proj != NULL) {
3868         pip = ValNodeNew (NULL);
3869         if (pip != NULL) {
3870           bsp = (BioseqPtr) mfp->sephead->data.ptrvalue;
3871           if (bsp != NULL) {
3872             is_na = (Boolean) ISA_na (bsp->mol);
3873           }
3874           if (is_na) {
3875             choice = ProjectItem_nucent;
3876           } else {
3877             choice = ProjectItem_protent;
3878           }
3879           pip->choice = choice;
3880           proj->data = pip;
3881           pip->data.ptrvalue = (Pointer) mfp->sephead;
3882           mfp->sephead = NULL;
3883           HandleProjectAsn (proj, 0);
3884         }
3885       }
3886       break;
3887     case 2 :
3888       list = mfp->sephead;
3889       sep = NULL;
3890       mfp->sephead = NULL;
3891       while (list != NULL) {
3892         next = list->next;
3893         list->next = NULL;
3894         if (sep != NULL) {
3895           AddSeqEntryToSeqEntry (sep, list, TRUE);
3896         } else {
3897           sep = list;
3898         }
3899         list = next;
3900       }
3901       if (sep != NULL) {
3902         if (sep->choice == 1) {
3903           datatype = OBJ_BIOSEQ;
3904         } else if (sep->choice == 2) {
3905           datatype = OBJ_BIOSEQSET;
3906         }
3907         entityID = ObjMgrRegister (datatype, (Pointer) sep->data.ptrvalue);
3908         HandleOneNewAsnProc (mfp->bfp, mfp->removeold, mfp->askForSubmit,
3909                              mfp->filename, (Pointer) sep, OBJ_SEQENTRY,
3910                              entityID, NULL);
3911       }
3912       break;
3913     case 3 :
3914       sep = ValNodeNew (NULL);
3915       if (sep != NULL) {
3916         bssp = BioseqSetNew ();
3917         if (bssp != NULL) {
3918           sep->choice = 2;
3919           sep->data.ptrvalue = (Pointer) bssp;
3920           bssp->_class = 14;
3921           bssp->seq_set = mfp->sephead;
3922           mfp->sephead = NULL;
3923           SeqMgrSeqEntry (SM_BIOSEQSET, (Pointer) bssp, sep);
3924           SeqMgrLinkSeqEntry (sep, 0, NULL);
3925           entityID = ObjMgrRegister (OBJ_SEQENTRY, (Pointer) sep);
3926           HandleOneNewAsnProc (mfp->bfp, mfp->removeold, mfp->askForSubmit,
3927                                mfp->filename, (Pointer) sep, OBJ_SEQENTRY,
3928                                entityID, NULL);
3929         }
3930       }
3931       break;
3932     default :
3933       break;
3934   }
3935   ArrowCursor ();
3936   Remove (mfp->form);
3937   Update ();
3938 }
3939 
MultToDocSum(ButtoN b)3940 static void MultToDocSum (ButtoN b)
3941 
3942 {
3943   CommonHandleMultBioseqs (b, 1);
3944 }
3945 
MultToSegSeq(ButtoN b)3946 static void MultToSegSeq (ButtoN b)
3947 
3948 {
3949   CommonHandleMultBioseqs (b, 2);
3950 }
3951 
MultToPopSet(ButtoN b)3952 static void MultToPopSet (ButtoN b)
3953 
3954 {
3955   CommonHandleMultBioseqs (b, 3);
3956 }
3957 
MultToSingleSeq(ButtoN b)3958 static void MultToSingleSeq (ButtoN b)
3959 
3960 {
3961   CommonHandleMultBioseqs (b, 2);
3962 }
3963 
MultBioseqFormMessage(ForM f,Int2 mssg)3964 static void MultBioseqFormMessage (ForM f, Int2 mssg)
3965 
3966 {
3967   MultBioseqFormPtr  mfp;
3968 
3969   mfp = (MultBioseqFormPtr) GetObjectExtra (f);
3970   if (mfp != NULL) {
3971     switch (mssg) {
3972       case VIB_MSG_CLOSE :
3973         Remove (f);
3974         break;
3975       default :
3976         if (mfp->appmessage != NULL) {
3977           mfp->appmessage (f, mssg);
3978         }
3979         break;
3980     }
3981   }
3982 }
3983 
ProcessMultipleBioseqs(BaseFormPtr bfp,CharPtr filename,Boolean removeold,Boolean askForSubmit,ValNodePtr sephead)3984 static Boolean ProcessMultipleBioseqs (BaseFormPtr bfp, CharPtr filename, Boolean removeold,
3985                                     Boolean askForSubmit, ValNodePtr sephead)
3986 
3987 {
3988   ButtoN             b;
3989   GrouP              c;
3990   MultBioseqFormPtr  mfp;
3991   StdEditorProcsPtr  sepp;
3992   WindoW             w;
3993 #ifndef WIN_MAC
3994   MenU               m;
3995 #endif
3996 
3997   mfp = (MultBioseqFormPtr) MemNew (sizeof (MultBioseqForm));
3998   if (mfp == NULL) return FALSE;
3999 
4000   if (!FixIDsAndTitles (sephead, NULL, TRUE)) {
4001     return FALSE;
4002   }
4003 
4004   w = FixedWindow (-50, -33, -10, -10, "Sequence Input", NULL);
4005   SetObjectExtra (w, mfp, StdCleanupFormProc);
4006   mfp->form = (ForM) w;
4007   mfp->formmessage = MultBioseqFormMessage;
4008 
4009   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4010   if (sepp != NULL) {
4011     SetActivate (w, sepp->activateForm);
4012     mfp->appmessage = sepp->handleMessages;
4013   }
4014 
4015   mfp->bfp = bfp;
4016   mfp->removeold = removeold;
4017   mfp->askForSubmit = askForSubmit;
4018   mfp->sephead = sephead;
4019   StringNCpy_0 (mfp->filename, filename, sizeof (mfp->filename));
4020 
4021 #ifndef WIN_MAC
4022   m = PulldownMenu (w, "File");
4023   FormCommandItem (m, "Close", (BaseFormPtr) mfp, VIB_MSG_CLOSE);
4024 #endif
4025 
4026   c = HiddenGroup (w, 0, 3, NULL);
4027   SetGroupSpacing (c, 10, 10);
4028   b = PushButton (c, "Load into Document Window", MultToDocSum);
4029   SetObjectExtra (b, mfp, NULL);
4030   if (sephead->next != NULL) {
4031     b = PushButton (c, "Load as Segmented Sequence", MultToSegSeq);
4032     SetObjectExtra (b, mfp, NULL);
4033     b = PushButton (c, "Load as Population Study", MultToPopSet);
4034     SetObjectExtra (b, mfp, NULL);
4035   } else {
4036     b = PushButton (c, "Load as Single Sequence", MultToSingleSeq);
4037     SetObjectExtra (b, mfp, NULL);
4038   }
4039 
4040   RealizeWindow (w);
4041   Show (w);
4042   Select (w);
4043   ArrowCursor ();
4044   Update ();
4045   return TRUE;
4046 }
4047 
ProcessMultipleSimpleSeqs(BaseFormPtr bfp,CharPtr filename,Boolean removeold,Boolean askForSubmit,ValNodePtr simples)4048 static void ProcessMultipleSimpleSeqs (BaseFormPtr bfp, CharPtr filename, Boolean removeold,
4049                                        Boolean askForSubmit, ValNodePtr simples)
4050 
4051 {
4052   EntrezGlobalsPtr  egp;
4053 
4054   egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
4055   if (egp == NULL || egp->retrieveSimpleProc == NULL) return;
4056   egp->retrieveSimpleProc (NULL, simples);
4057 }
4058 
HandledAnnotatedProteins(BaseFormPtr bfp,ValNodePtr bioseqs)4059 static Boolean HandledAnnotatedProteins (BaseFormPtr bfp, ValNodePtr bioseqs)
4060 
4061 {
4062   BioseqPtr    bsp;
4063   Int2         code;
4064   ValNodePtr   descr;
4065   MolInfoPtr   mip;
4066   BioseqPtr    nucbsp;
4067   ValNodePtr   sdp;
4068   SeqEntryPtr  sep;
4069   SeqLocPtr    slp;
4070   CharPtr      title;
4071   SeqEntryPtr  top = NULL;
4072   ValNode      vn;
4073   ValNodePtr   vnp;
4074 
4075   if (bfp == NULL || bioseqs == NULL) return FALSE;
4076   nucbsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
4077   if (nucbsp == NULL) return FALSE;
4078   if (! ISA_na (nucbsp->mol)) return FALSE;
4079   /* top = GetBestTopParentForData (bfp->input_entityID, nucbsp); */
4080   top = GetTopSeqEntryForEntityID (bfp->input_entityID);
4081   if (top == NULL) return FALSE;
4082   for (vnp = bioseqs; vnp != NULL; vnp = vnp->next) {
4083     bsp = (BioseqPtr) vnp->data.ptrvalue;
4084     if (bsp == NULL) return FALSE;
4085     if (! ISA_aa (bsp->mol)) return FALSE;
4086     title = BioseqGetTitle (bsp);
4087     if (title == NULL) return FALSE;
4088     if (StringChr (title, '[') == NULL) return FALSE;
4089   }
4090   code = SeqEntryToGeneticCode (top, NULL, NULL, 0);
4091   SetBatchSuggestNucleotide (nucbsp, code);
4092   descr = ExtractBioSourceAndPubs (top);
4093   vn.choice = SEQLOC_WHOLE;
4094   vn.data.ptrvalue = (Pointer) nucbsp->id;
4095   slp = &vn;
4096   for (vnp = bioseqs; vnp != NULL; vnp = vnp->next) {
4097     bsp = (BioseqPtr) vnp->data.ptrvalue;
4098     bsp->id = SeqIdFree (bsp->id);
4099     bsp->id = MakeNewProteinSeqId (slp, NULL);
4100     SeqMgrReplaceInBioseqIndex (bsp);
4101     sep = SeqMgrGetSeqEntryForData (bsp);
4102     if (sep != NULL) {
4103       mip = MolInfoNew ();
4104       if (mip != NULL) {
4105         mip->biomol = 8;
4106         mip->tech = 13;
4107         sdp = CreateNewDescriptor (sep, Seq_descr_molinfo);
4108         if (sdp != NULL) {
4109           sdp->data.ptrvalue = (Pointer) mip;
4110         }
4111       }
4112       AddSeqEntryToSeqEntry (top, sep, TRUE);
4113       AutomaticProteinProcess (top, sep, code, FALSE, NULL);
4114       ValNodeExtract (&(bsp->descr), Seq_descr_title);
4115     }
4116   }
4117   ClearBatchSuggestNucleotide ();
4118   ReplaceBioSourceAndPubs (top, descr);
4119   return TRUE;
4120 }
4121 
4122 
4123 typedef struct seqidlistdialog
4124 {
4125   DIALOG_MESSAGE_BLOCK
4126   DoC      doc;
4127   ParData  ParFmt;
4128   ColData  ColFmt;
4129   Int4     dlg_height;
4130   Int4     selected;
4131 } SeqIdListDialogData, PNTR SeqIdListDialogPtr;
4132 
ListToSeqIdListDialog(DialoG d,Pointer userdata)4133 static void ListToSeqIdListDialog (DialoG d, Pointer userdata)
4134 {
4135   SeqIdListDialogPtr dlg;
4136   ValNodePtr       idd_list;
4137   Char             id_txt [255];
4138 
4139   dlg = (SeqIdListDialogPtr) GetObjectExtra (d);
4140   if (dlg == NULL)
4141   {
4142     return;
4143   }
4144 
4145   Reset (dlg->doc);
4146 
4147   idd_list = (ValNodePtr) userdata;
4148   if (idd_list == NULL)
4149   {
4150     return;
4151   }
4152 
4153   while (idd_list != NULL)
4154   {
4155     /* add to sequence_selector doc */
4156     SeqIdWrite ((SeqIdPtr)(idd_list->data.ptrvalue), id_txt, PRINTID_FASTA_ALL, sizeof (id_txt) - 1);
4157   	AppendText (dlg->doc, id_txt, &(dlg->ParFmt), &(dlg->ColFmt), programFont);
4158     idd_list = idd_list->next;
4159   }
4160   InvalDocRows (dlg->doc, 0, 0, 0);
4161 }
4162 
4163 
4164 /* clicking on a column in the title indicates that we should sort by this column. */
ClickSeqIdList(DoC d,PoinT pt)4165 static void ClickSeqIdList (DoC d, PoinT pt)
4166 {
4167   SeqIdListDialogPtr dlg;
4168   Int2             item;
4169   Int2             row;
4170   Int2             col;
4171   RecT             r;
4172 
4173   MapDocPoint (d, pt, &item, &row, &col, NULL);
4174   if (item < 1) {
4175     return;
4176   }
4177   dlg = (SeqIdListDialogPtr) GetObjectExtra (d);
4178   if (dlg == NULL) return;
4179   if (dlg->selected == item) {
4180     dlg->selected = 0;
4181   } else {
4182     dlg->selected = item;
4183   }
4184   /* inval to redraw */
4185   ObjectRect (dlg->doc, &r);
4186   InvalRect (&r);
4187   Update ();
4188 }
4189 
4190 
HighlightSeqIdList(DoC d,Int2 item,Int2 row,Int2 col)4191 static Boolean HighlightSeqIdList (DoC d, Int2 item, Int2 row, Int2 col)
4192 
4193 {
4194   SeqIdListDialogPtr dlg;
4195 
4196   dlg = (SeqIdListDialogPtr) GetObjectExtra (d);
4197   if (dlg == NULL) return FALSE;
4198 
4199   if (item == dlg->selected) {
4200     return TRUE;
4201   } else {
4202     return FALSE;
4203   }
4204 }
4205 
4206 
4207 static DialoG
SeqIdListDialog(GrouP parent,CharPtr title,Int4 id_width)4208 SeqIdListDialog
4209 (GrouP           parent,
4210  CharPtr         title,
4211  Int4            id_width)
4212 {
4213   SeqIdListDialogPtr dlg;
4214   GrouP                      p;
4215   RecT                       r;
4216   PrompT                     ppt = NULL;
4217 
4218   dlg = (SeqIdListDialogPtr) MemNew (sizeof (SeqIdListDialogData));
4219   if (dlg == NULL)
4220   {
4221     return NULL;
4222   }
4223 
4224   p = HiddenGroup (parent, -1, 0, NULL);
4225   SetObjectExtra (p, dlg, StdCleanupExtraProc);
4226 
4227   dlg->dialog = (DialoG) p;
4228   dlg->todialog = ListToSeqIdListDialog;
4229 
4230   if (!StringHasNoText (title)) {
4231     ppt = StaticPrompt (p, title, 0, 0, programFont, 'l');
4232   }
4233 
4234   dlg->doc = DocumentPanel (p, stdCharWidth * 10 * MIN (id_width, 4), stdLineHeight * 5);
4235   SetObjectExtra (dlg->doc, dlg, NULL);
4236   SetDocProcs (dlg->doc, ClickSeqIdList, NULL, NULL, NULL);
4237   SetDocShade (dlg->doc, NULL, NULL, HighlightSeqIdList, NULL);
4238   dlg->selected = 0;
4239 
4240   /* initialize document paragraph format */
4241   dlg->ParFmt.openSpace = FALSE;
4242   dlg->ParFmt.keepWithNext = FALSE;
4243   dlg->ParFmt.keepTogether = FALSE;
4244   dlg->ParFmt.newPage = FALSE;
4245   dlg->ParFmt.tabStops = FALSE;
4246   dlg->ParFmt.minLines = 0;
4247   dlg->ParFmt.minHeight = 0;
4248 
4249   /* initialize document column format */
4250   ObjectRect (dlg->doc, &r);
4251   dlg->dlg_height = r.bottom - r.top;
4252   InsetRect (&r, 4, 4);
4253   dlg->ColFmt.pixWidth = r.right - r.left;
4254   dlg->ColFmt.pixInset = 0;
4255   dlg->ColFmt.charWidth = 80;
4256   dlg->ColFmt.charInset = 0;
4257   dlg->ColFmt.font = NULL;
4258   dlg->ColFmt.just = 'l';
4259   dlg->ColFmt.wrap = TRUE;
4260   dlg->ColFmt.bar = FALSE;
4261   dlg->ColFmt.underline = FALSE;
4262   dlg->ColFmt.left = FALSE;
4263   dlg->ColFmt.last = TRUE;
4264 
4265   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->doc, (HANDLE) ppt, NULL);
4266 
4267   return (DialoG) p;
4268 }
4269 
4270 
GetSeqIdListDialogSelection(DialoG d)4271 static Int4 GetSeqIdListDialogSelection (DialoG d)
4272 {
4273   SeqIdListDialogPtr dlg;
4274 
4275   dlg = (SeqIdListDialogPtr) GetObjectExtra (d);
4276   if (dlg == NULL) return -1;
4277 
4278   return dlg->selected - 1;
4279 }
4280 
4281 
4282 typedef struct ididmatch {
4283   ValNodePtr annot_id_list;
4284   ValNodePtr master_id_list;
4285 } IdIdMatchData, PNTR IdIdMatchPtr;
4286 
4287 
GetIdsInRecord(BioseqPtr bsp,Pointer data)4288 static void GetIdsInRecord (BioseqPtr bsp, Pointer data)
4289 {
4290   if (bsp != NULL && data != NULL && bsp->id != NULL) {
4291     ValNodeAddPointer ((ValNodePtr PNTR) data, 0, bsp->id);
4292   }
4293 }
4294 
4295 
4296 typedef struct idmatchdlg {
4297   DialoG sap_list;
4298   DialoG record_list;
4299   DoC    matches;
4300   DialoG match_location;
4301 
4302   IdIdMatchPtr idd;
4303   ValNodePtr   ids_in_record;
4304   SeqEntryPtr  sep;
4305 } IdMatchDlgData, PNTR IdMatchDlgPtr;
4306 
4307 static ParData idmatchParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
4308 static ColData idmatchColFmt[] =
4309 {
4310   {20, 0, 0, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, FALSE},
4311   {0, 0, 800, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, TRUE},
4312 };
4313 
PopulateIdMatch(IdMatchDlgPtr dlg)4314 static void PopulateIdMatch (IdMatchDlgPtr dlg)
4315 {
4316   ValNodePtr vnp_m, vnp_s;
4317   ValNodePtr sap_list = NULL;
4318   Char id1[30];
4319   Char id2[200];
4320   Char buf[250];
4321   RecT r;
4322 
4323   if (dlg == NULL)
4324   {
4325     return;
4326   }
4327 
4328   /* first, redraw list of matches, get list of still missing */
4329   Reset (dlg->matches);
4330 
4331   for (vnp_m = dlg->idd->master_id_list, vnp_s = dlg->idd->annot_id_list;
4332        vnp_m != NULL && vnp_s != NULL;
4333        vnp_m = vnp_m->next, vnp_s = vnp_s->next)
4334   {
4335     if (vnp_m->data.ptrvalue == NULL)
4336     {
4337       ValNodeAddPointer (&sap_list, 0, vnp_s->data.ptrvalue);
4338     }
4339     else
4340     {
4341       SeqIdWrite ((SeqIdPtr)(vnp_s->data.ptrvalue), id1, PRINTID_FASTA_ALL, sizeof (id1) - 1);
4342       SeqIdWrite ((SeqIdPtr)(vnp_m->data.ptrvalue), id2, PRINTID_FASTA_ALL, sizeof (id2) - 1);
4343       sprintf (buf, "\t%s->%s\n", id1, id2);
4344       AppendText (dlg->matches, buf, &idmatchParFmt, idmatchColFmt, programFont);
4345     }
4346   }
4347   /* inval to redraw */
4348   ObjectRect (dlg->matches, &r);
4349   InvalRect (&r);
4350 
4351   /* now repopulate list */
4352   PointerToDialog (dlg->sap_list, sap_list);
4353   sap_list = ValNodeFree (sap_list);
4354 
4355   Update ();
4356 }
4357 
4358 
MapSeqIdList(ButtoN b)4359 static void MapSeqIdList (ButtoN b)
4360 {
4361   IdMatchDlgPtr dlg;
4362   Int4  sap_pos, record_pos, i;
4363   ValNodePtr vnp_s, vnp_m, vnp_r;
4364 
4365   dlg = (IdMatchDlgPtr) GetObjectExtra (b);
4366   if (dlg == NULL) {
4367     return;
4368   }
4369 
4370   sap_pos = GetSeqIdListDialogSelection (dlg->sap_list);
4371   record_pos = GetSeqIdListDialogSelection (dlg->record_list);
4372   if (sap_pos < 0 || record_pos < 0) {
4373     return;
4374   }
4375 
4376   for (vnp_r = dlg->ids_in_record, i = 0; vnp_r != NULL && i < record_pos; vnp_r = vnp_r->next, i++)
4377   {
4378   }
4379   if (vnp_r == NULL) {
4380     return;
4381   }
4382 
4383   vnp_m = dlg->idd->master_id_list;
4384   vnp_s = dlg->idd->annot_id_list;
4385   i = 0;
4386   while (vnp_s != NULL && vnp_m != NULL && vnp_m->data.ptrvalue != NULL) {
4387     vnp_s = vnp_s->next;
4388     vnp_m = vnp_m->next;
4389   }
4390   while (i < sap_pos) {
4391     while (vnp_s != NULL && vnp_m != NULL && vnp_m->data.ptrvalue != NULL) {
4392       vnp_s = vnp_s->next;
4393       vnp_m = vnp_m->next;
4394     }
4395     i++;
4396   }
4397 
4398   if (vnp_m == NULL) {
4399     return;
4400   }
4401 
4402   vnp_m->data.ptrvalue = vnp_r->data.ptrvalue;
4403 
4404   /* now redraw matches, repopulate lists */
4405   PopulateIdMatch (dlg);
4406 }
4407 
4408 
DrawIdMatchDoc(DoC d,RectPtr r,Int2 item,Int2 firstLine)4409 static void DrawIdMatchDoc (DoC d, RectPtr r, Int2 item, Int2 firstLine)
4410 {
4411   RecT rct;
4412 
4413   if (r == NULL) return;
4414 
4415   rct = *r;
4416   rct.bottom = rct.top + stdLineHeight - 4;
4417   rct.right = rct.left + stdLineHeight - 4;
4418   InsetRect (&rct, 2, 2);
4419 
4420   MoveTo (rct.left, rct.top);
4421   LineTo (rct.right, rct.bottom);
4422   MoveTo (rct.left, rct.bottom);
4423   LineTo (rct.right, rct.top);
4424 }
4425 
4426 
ClickIdMatchDoc(DoC d,PoinT pt)4427 static void ClickIdMatchDoc (DoC d, PoinT pt)
4428 {
4429   IdMatchDlgPtr dlg;
4430   Int2            item;
4431   Int2            row;
4432   Int2            col;
4433   Int2            pos;
4434   ValNodePtr      vnp_s, vnp_m;
4435 
4436   dlg = (IdMatchDlgPtr) GetObjectExtra (d);
4437   if (dlg == NULL) return;
4438 
4439   MapDocPoint (d, pt, &item, &row, &col, NULL);
4440   if (col != 1) {
4441     return;
4442   }
4443 
4444   /* undo match for row */
4445   pos = 1;
4446 
4447   vnp_m = dlg->idd->master_id_list;
4448   vnp_s = dlg->idd->annot_id_list;
4449   while (vnp_s != NULL && vnp_m != NULL && vnp_m->data.ptrvalue == NULL)
4450   {
4451     vnp_s = vnp_s->next;
4452     vnp_m = vnp_m->next;
4453   }
4454   while (pos < item)
4455   {
4456     while (vnp_s != NULL && vnp_m != NULL && vnp_m->data.ptrvalue == NULL)
4457     {
4458       vnp_s = vnp_s->next;
4459       vnp_m = vnp_m->next;
4460     }
4461     pos++;
4462   }
4463 
4464   if (vnp_m != NULL)
4465   {
4466     vnp_m->data.ptrvalue = NULL;
4467   }
4468 
4469   /* now redraw matches, repopulate lists */
4470   PopulateIdMatch (dlg);
4471 }
4472 
4473 
AutoMatchRecordIdToLocalId(ButtoN b)4474 static void AutoMatchRecordIdToLocalId (ButtoN b)
4475 {
4476   IdMatchDlgPtr dlg;
4477   ValNodePtr vnp_s, vnp_m, vnp_r;
4478   Uint1 match_location;
4479   ValNodePtr query = NULL, responses;
4480   BioseqPtr bsp;
4481 
4482   dlg = (IdMatchDlgPtr) GetObjectExtra (b);
4483   if (dlg == NULL) {
4484     return;
4485   }
4486   match_location = GetMatchLocationFromIdMatchLocationDlg (dlg->match_location);
4487 
4488   for (vnp_m = dlg->idd->master_id_list, vnp_s = dlg->idd->annot_id_list;
4489        vnp_m != NULL && vnp_s != NULL;
4490        vnp_m = vnp_m->next, vnp_s = vnp_s->next)
4491   {
4492     if (vnp_m->data.ptrvalue == NULL)
4493     {
4494       ValNodeAddPointer (&query, 0, vnp_s->data.ptrvalue);
4495     }
4496   }
4497 
4498   responses = GetBioseqMatchesForSequenceIDs (query, match_location, dlg->sep);
4499 
4500   vnp_r = responses;
4501   for (vnp_m = dlg->idd->master_id_list, vnp_s = dlg->idd->annot_id_list;
4502        vnp_m != NULL && vnp_s != NULL;
4503        vnp_m = vnp_m->next, vnp_s = vnp_s->next)
4504   {
4505     if (vnp_m->data.ptrvalue == NULL)
4506     {
4507       if ((bsp = (BioseqPtr) vnp_r->data.ptrvalue) != NULL) {
4508         vnp_m->data.ptrvalue = bsp->id;
4509       }
4510       vnp_r = vnp_r->next;
4511     }
4512   }
4513 
4514   query = ValNodeFree (query);
4515 
4516   /* now redraw matches, repopulate lists */
4517   PopulateIdMatch (dlg);
4518 }
4519 
4520 
ResolveIDLists(IdIdMatchPtr idd,SeqEntryPtr sep)4521 static Boolean ResolveIDLists (IdIdMatchPtr idd, SeqEntryPtr sep)
4522 {
4523   WindoW w;
4524   GrouP  h, g1, g2, g3, c;
4525   PrompT p1, p2;
4526   ButtoN b;
4527   ModalAcceptCancelData acd;
4528   IdMatchDlgData dlg;
4529   Boolean        rval = FALSE;
4530 
4531   dlg.ids_in_record = NULL;
4532   VisitBioseqsInSep (sep, &(dlg.ids_in_record), GetIdsInRecord);
4533   dlg.sep = sep;
4534   dlg.idd = idd;
4535 
4536   acd.accepted = FALSE;
4537   acd.cancelled = FALSE;
4538   acd.third_option = FALSE;
4539 
4540   w = ModalWindow(-20, -13, -10, -10, NULL);
4541   h = HiddenGroup (w, -1, 0, NULL);
4542   SetGroupSpacing (h, 10, 10);
4543 
4544   p1 = StaticPrompt (h, "Feature Table IDs not found in record", 0, 0, programFont, 'l');
4545 
4546   g1 = HiddenGroup (h, 2, 0, NULL);
4547   SetGroupSpacing (g1, 10, 10);
4548   dlg.sap_list = SeqIdListDialog (g1, "Feature Table IDs", 1);
4549   dlg.record_list = SeqIdListDialog (g1, "IDs in record", 4);
4550   PointerToDialog (dlg.record_list, dlg.ids_in_record);
4551 
4552   g2 = HiddenGroup (h, 3, 0, NULL);
4553   SetGroupSpacing (g2, 10, 10);
4554   b = PushButton (g2, "Map Selected", MapSeqIdList);
4555   SetObjectExtra (b, &dlg, NULL);
4556 
4557   g3 = HiddenGroup (h, 3, 0, NULL);
4558   SetGroupSpacing (g3, 10, 10);
4559   b = PushButton (g3, "AutoMatch where table ID", AutoMatchRecordIdToLocalId);
4560   SetObjectExtra (b, &dlg, NULL);
4561   dlg.match_location = IdMatchLocationDlg (g3, NULL, NULL);
4562   StaticPrompt (g3, "record ID", 0, 0, programFont, 'l');
4563 
4564   p2 = StaticPrompt (h, "Selected matches", 0, 0, programFont, 'l');
4565   dlg.matches = DocumentPanel (h, stdCharWidth * 60, stdLineHeight * 5);
4566   SetObjectExtra (dlg.matches, &dlg, NULL);
4567   SetDocProcs (dlg.matches, ClickIdMatchDoc, NULL, NULL, NULL);
4568   SetDocShade (dlg.matches, DrawIdMatchDoc, NULL, NULL, NULL);
4569 
4570   c = HiddenGroup (h, 3, 0, NULL);
4571   SetGroupSpacing (c, 10, 10);
4572   b = PushButton (c, "Accept", ModalAcceptButton);
4573   SetObjectExtra (b, &acd, NULL);
4574   b = PushButton (c, "Cancel", ModalCancelButton);
4575   SetObjectExtra (b, &acd, NULL);
4576   AlignObjects (ALIGN_CENTER, (HANDLE) p1, (HANDLE) g1, (HANDLE) g2, (HANDLE) g3, (HANDLE) p2, (HANDLE) dlg.matches, (HANDLE) c, NULL);
4577 
4578   PopulateIdMatch (&dlg);
4579 
4580   Show(w);
4581   Select (w);
4582   while (!acd.accepted && ! acd.cancelled)
4583   {
4584     ProcessExternalEvent ();
4585     Update ();
4586   }
4587   ProcessAnEvent ();
4588   Remove (w);
4589   if (acd.accepted)
4590   {
4591     rval = TRUE;
4592   }
4593   dlg.ids_in_record = ValNodeFree (dlg.ids_in_record);
4594   return rval;
4595 }
4596 
4597 
FixSeqAnnotIds(Uint2 master_id,ValNodePtr read_list)4598 static void FixSeqAnnotIds (Uint2 master_id, ValNodePtr read_list)
4599 {
4600   SeqEntryPtr sep;
4601   ValNodePtr  vnp_s, vnp_m, vnp_a;
4602   SeqAnnotPtr sap;
4603   SeqFeatPtr  sfp;
4604   SeqIdPtr    a_sip, m_sip;
4605   IdIdMatchData idd;
4606   ValNodePtr  sap_repair = NULL;
4607   BioseqPtr   bsp;
4608   Boolean     any_missing = FALSE;
4609 
4610   if (master_id == 0 || (sep = GetTopSeqEntryForEntityID(master_id)) == NULL || read_list == NULL)
4611   {
4612     return;
4613   }
4614 
4615   idd.annot_id_list = NULL;
4616   idd.master_id_list = NULL;
4617 
4618   /* find Seq-ids in SeqAnnots */
4619   for (vnp_s = read_list; vnp_s != NULL; vnp_s = vnp_s->next) {
4620     if (vnp_s->choice == OBJ_SEQANNOT
4621         && (sap = (SeqAnnotPtr) vnp_s->data.ptrvalue) != NULL
4622         && sap->type == 1) {
4623       sfp = sap->data;
4624       a_sip = NULL;
4625       while (sfp != NULL && a_sip == NULL) {
4626         a_sip = SeqLocId (sfp->location);
4627         sfp = sfp->next;
4628       }
4629       bsp = BioseqFind (a_sip);
4630 
4631       if (bsp == NULL) {
4632         ValNodeAddPointer (&(idd.annot_id_list), 0, SeqIdDup(a_sip));
4633         ValNodeAddPointer (&(idd.master_id_list), 0, NULL);
4634         ValNodeAddPointer (&sap_repair, OBJ_SEQANNOT, sap);
4635         any_missing = TRUE;
4636       }
4637     }
4638   }
4639 
4640   if (any_missing)
4641   {
4642     if (ResolveIDLists(&idd, sep))
4643     {
4644       for (vnp_s = sap_repair, vnp_m = idd.master_id_list, vnp_a = idd.annot_id_list;
4645            vnp_s != NULL && vnp_m != NULL && vnp_a != NULL;
4646            vnp_s = vnp_s->next, vnp_m = vnp_m->next, vnp_a = vnp_a->next)
4647       {
4648         if (vnp_s->choice == OBJ_SEQANNOT
4649             && (sap = (SeqAnnotPtr) vnp_s->data.ptrvalue) != NULL
4650             && sap->type == 1
4651             && (a_sip = (SeqIdPtr) vnp_a->data.ptrvalue) != NULL
4652             && (m_sip = SeqIdFindWorst ((SeqIdPtr)vnp_m->data.ptrvalue)) != NULL)
4653         {
4654           for (sfp = sap->data; sfp != NULL; sfp = sfp->next)
4655           {
4656             ReplaceSeqIdWithSeqIdInFeat (a_sip, m_sip, sfp);
4657           }
4658         }
4659       }
4660     }
4661   }
4662 
4663   for (vnp_a = idd.annot_id_list; vnp_a != NULL; vnp_a = vnp_a->next)
4664   {
4665     vnp_a->data.ptrvalue = SeqIdFree (vnp_a->data.ptrvalue);
4666   }
4667   idd.annot_id_list = ValNodeFree (idd.annot_id_list);
4668   idd.master_id_list = ValNodeFree (idd.master_id_list);
4669 }
4670 
4671 
DoReadAnythingLoop(BaseFormPtr bfp,CharPtr filename,CharPtr path,Boolean removeold,Boolean askForSubmit,Boolean alwaysMult,Boolean parseFastaSeqId,Boolean fastaAsSimpleSeq)4672 static Boolean DoReadAnythingLoop (BaseFormPtr bfp, CharPtr filename, CharPtr path,
4673                                    Boolean removeold, Boolean askForSubmit, Boolean alwaysMult,
4674                                    Boolean parseFastaSeqId, Boolean fastaAsSimpleSeq)
4675 
4676 {
4677   ValNodePtr     bioseqs;
4678   BioseqPtr      bsp;
4679   Pointer        dataptr;
4680   Uint2          datatype;
4681   Boolean        each;
4682   Uint2          entityID;
4683   FILE           *fp;
4684   ValNodePtr     head = NULL;
4685   ValNodePtr     last = NULL;
4686   OMUserDataPtr  omudp;
4687   ValNodePtr     projects;
4688   Boolean        rsult;
4689   SeqEntryPtr    sep;
4690   SeqEntryPtr    sephead = NULL;
4691   ValNodePtr     simples;
4692   Uint2          updateEntityID;
4693   ValNodePtr     vnp, err_list, vnp_err;
4694   LogInfoPtr     lip;
4695   Boolean        any_feature_tables = FALSE;
4696   SeqAnnotPtr    sap;
4697 
4698   if (filename == NULL) return FALSE;
4699   fp = FileOpen (filename, "r");
4700   if (fp != NULL) {
4701     rsult = FALSE;
4702     while ((dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, NULL, FALSE, FALSE,
4703                                               parseFastaSeqId, fastaAsSimpleSeq)) != NULL) {
4704       vnp = ValNodeAddPointer (&last, datatype, dataptr);
4705       if (head == NULL) {
4706         head = vnp;
4707       }
4708       last = vnp;
4709     }
4710     FileClose (fp);
4711     bioseqs = ValNodeExtractList (&head, OBJ_BIOSEQ);
4712     projects = ValNodeExtractList (&head, OBJ_PROJECT);
4713     simples = ValNodeExtractList (&head, OBJ_FASTA);
4714 
4715     if (bfp != NULL && indexerVersion) {
4716       FixSeqAnnotIds (bfp->input_entityID, head);
4717     }
4718 
4719     updateEntityID = 0;
4720     lip = OpenLog ("Errors");
4721     if (head == NULL) {
4722       Message (MSG_ERROR, "Unable to read from file");
4723     }
4724     for (vnp = head; vnp != NULL; vnp = vnp->next) {
4725       datatype = vnp->choice;
4726       dataptr = vnp->data.ptrvalue;
4727       entityID = ObjMgrRegister (datatype, dataptr);
4728 
4729       err_list = NULL;
4730       each = HandleOneNewAsnProcEx (bfp, removeold, askForSubmit, path, dataptr, datatype, entityID, &updateEntityID, &err_list);
4731       if (err_list != NULL) {
4732         for (vnp_err = err_list; vnp_err != NULL; vnp_err = vnp_err->next) {
4733           fprintf (lip->fp, "%s\n", (CharPtr) vnp_err->data.ptrvalue);
4734           lip->data_in_log = TRUE;
4735         }
4736         err_list = ValNodeFreeData (err_list);
4737         if (datatype == OBJ_SEQANNOT) {
4738           ExportSeqAnnotFeatureTable (lip->fp, dataptr);
4739         }
4740       }
4741       removeold = FALSE;
4742       rsult = (Boolean) (rsult || each);
4743       if (backupMode) {
4744         subtoolEntityID = entityID;
4745         omudp = ObjMgrAddUserData (subtoolEntityID, 0, 0, 0);
4746         if (omudp != NULL) {
4747           omudp->messagefunc = BackupModeMsgFunc;
4748         }
4749         subtoolRecordDirty = TRUE;
4750       }
4751       if (datatype == OBJ_SEQANNOT) {
4752         sap = (SeqAnnotPtr) dataptr;
4753         if (sap != NULL && sap->type == 1) {
4754           any_feature_tables = TRUE;
4755         }
4756       }
4757     }
4758     CloseLog (lip);
4759     lip = FreeLog (lip);
4760     ValNodeFree (head);
4761     if (updateEntityID != 0) {
4762       ObjMgrSetDirtyFlag (updateEntityID, TRUE);
4763       ObjMgrSendMsg (OM_MSG_UPDATE, updateEntityID, 0, 0);
4764     }
4765     for (vnp = projects; vnp != NULL; vnp = vnp->next) {
4766       HandleProjectAsn ((ProjectPtr) vnp->data.ptrvalue, 0);
4767     }
4768     ValNodeFree (projects);
4769     if (bioseqs != NULL) {
4770       if (HandledAnnotatedProteins (bfp, bioseqs)) {
4771         rsult = TRUE;
4772         if (bfp != NULL) {
4773           ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
4774           ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
4775         }
4776       } else if (bioseqs->next == NULL && (! alwaysMult)) {
4777         bsp = (BioseqPtr) bioseqs->data.ptrvalue;
4778         bioseqs->data.ptrvalue = NULL;
4779         if (bsp != NULL) {
4780           sep = SeqMgrGetSeqEntryForData (bsp);
4781           if (sep == NULL) {
4782             sep = SeqEntryNew ();
4783             if (sep != NULL) {
4784               sep->choice = 1;
4785               sep->data.ptrvalue = bsp;
4786               SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
4787             }
4788           }
4789         }
4790         entityID = ObjMgrRegister (OBJ_BIOSEQ, (Pointer) bsp);
4791         each = HandleOneNewAsnProc (bfp, FALSE, FALSE, path, (Pointer) bsp, OBJ_BIOSEQ, entityID, NULL);
4792         removeold = FALSE;
4793         rsult = (Boolean) (rsult || each);
4794       } else {
4795         sephead = NULL;
4796         for (vnp = bioseqs; vnp != NULL; vnp = vnp->next) {
4797           bsp = (BioseqPtr) vnp->data.ptrvalue;
4798           if (bsp != NULL) {
4799             sep = SeqMgrGetSeqEntryForData (bsp);
4800             if (sep == NULL) {
4801               sep = SeqEntryNew ();
4802               if (sep != NULL) {
4803                 sep->choice = 1;
4804                 sep->data.ptrvalue = bsp;
4805                 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
4806               }
4807             }
4808             if (sep != NULL) {
4809               ValNodeLink (&sephead, sep);
4810             }
4811           }
4812         }
4813         if (ProcessMultipleBioseqs (bfp, filename, removeold, askForSubmit, sephead)) {
4814           bioseqs = NULL;
4815           rsult = TRUE;
4816         } else {
4817           for (vnp = bioseqs; vnp != NULL; vnp = vnp->next) {
4818             bsp = (BioseqPtr) vnp->data.ptrvalue;
4819             if (bsp != NULL) {
4820               bsp->idx.deleteme = TRUE;
4821             }
4822           }
4823           DeleteMarkedObjects (0, OBJ_SEQENTRY, sephead);
4824         }
4825       }
4826     }
4827     ValNodeFree (bioseqs);
4828     if (simples != NULL) {
4829       ProcessMultipleSimpleSeqs (bfp, filename, removeold, askForSubmit, simples);
4830       rsult = TRUE;
4831     }
4832     ValNodeFree (simples);
4833     if (any_feature_tables) {
4834       SeqMgrIndexFeatures(updateEntityID, NULL);
4835       SeqMgrExploreBioseqs (updateEntityID, 0, NULL, RemoveGeneXrefsOnBioseqs, TRUE, TRUE, TRUE);
4836     }
4837     return rsult;
4838   }
4839   return FALSE;
4840 }
4841 
4842 /* Sarah's stuff */
4843 
4844 #define SQACT_TXTALN 1
4845 #define SQACT_NOTTXTALN 2
4846 #define SQACT_UNPRINTABLECHARS 3
4847 
SQACT_GuessWhatIAm(FILE * fp)4848 static Int4 SQACT_GuessWhatIAm (FILE *fp)
4849 {
4850    Boolean  found;
4851    Int4     len;
4852    CharPtr  line;
4853    Int4     prevlen;
4854    Int4     seq;
4855    CharPtr  tmp;
4856    ValNodePtr current_data = NULL;
4857    CharPtr    cp;
4858 
4859    if (fp == NULL) return SQACT_NOTTXTALN;
4860    line = MyFGetLine (fp, &current_data);
4861    found = FALSE;
4862    while (line != NULL && !found) /* find first non-empty line */
4863    {
4864       if (!StringHasNoText(line))
4865       {
4866          if (StringLen(line) > 0)
4867             found = TRUE;
4868       }
4869       else
4870       {
4871          MemFree(line);
4872          line = MyFGetLine (fp, &current_data);
4873       }
4874    }
4875    if (!found)
4876    {
4877      FreeBufferedReadList (current_data);
4878      return -1;
4879    }
4880 
4881    /* look for unprintable characters */
4882    for (cp = line; *cp != 0; cp++)
4883    {
4884       if ((Int4)(*cp) < 0 || (Int4)(*cp) >= 256 || ! isprint ((Int4)(*cp)) && ! isspace ((Int4)(*cp)))
4885       {
4886          FreeBufferedReadList (current_data);
4887          return SQACT_UNPRINTABLECHARS;
4888       }
4889    }
4890 
4891    tmp = StringStr(line, "::="); /* ASN.1 */
4892    if (tmp != NULL)
4893    {
4894       MemFree(line);
4895       line = NULL;
4896       FreeBufferedReadList (current_data);
4897       return SQACT_NOTTXTALN;
4898    }
4899    tmp = StringStr(line, "LOCUS");  /* GenBank flat file */
4900    if (tmp != NULL)
4901    {
4902       MemFree(line);
4903       line = NULL;
4904       FreeBufferedReadList (current_data);
4905       return SQACT_NOTTXTALN;
4906    }
4907    if (line[0] == '>')  /* FASTA sequences or FASTA alignment */
4908    {
4909       if (StringNCmp (line, ">PubMed", 7) == 0 ||
4910           StringNCmp (line, ">Protein", 8) == 0 ||
4911           StringNCmp (line, ">Nucleotide", 11) == 0 ||
4912           StringNCmp (line, ">Structure", 10) == 0 ||
4913           StringNCmp (line, ">Genome", 7) == 0 ||
4914           StringNCmp (line, ">Feature", 8) == 0 ||
4915           StringNCmp (line, ">Vector", 7) == 0 ||
4916           StringNCmp (line, ">Restriction", 12) == 0 ||
4917           StringNCmp (line, ">Contig", 7) == 0 ||
4918           StringNCmp (line, ">Virtual", 8) == 0 ||
4919           StringNCmp (line, ">Message", 8) == 0) {
4920         MemFree(line);
4921         line = NULL;
4922         FreeBufferedReadList (current_data);
4923       	return SQACT_NOTTXTALN;
4924       }
4925       MemFree(line);
4926       line = MyFGetLine (fp, &current_data);
4927       prevlen = -1;
4928       len = 0;
4929       seq = 0;
4930       while (line != NULL)
4931       {
4932          seq++;
4933          while (line != NULL && line[0] != '>')
4934          {
4935             tmp = StringStr(line, "-");
4936             if (tmp != NULL)  /* found a gap -> alignment */
4937             {
4938                MemFree(line);
4939                line = NULL;
4940                FreeBufferedReadList (current_data);
4941                return SQACT_TXTALN;
4942             }
4943             len += StringLen(line);
4944             MemFree(line);
4945             line = MyFGetLine (fp, &current_data);
4946          }
4947          if (line != NULL)
4948          {
4949             MemFree(line);
4950             line = MyFGetLine (fp, &current_data);
4951          }
4952          if (prevlen == -1)
4953             prevlen = len;
4954          if (len != prevlen)  /* sequences of different length -> FASTA seq */
4955          {
4956             MemFree(line);
4957             line = NULL;
4958             FreeBufferedReadList (current_data);
4959             return SQACT_NOTTXTALN;
4960          }
4961       }
4962       MemFree (line);
4963       line = NULL;
4964       FreeBufferedReadList (current_data);
4965       current_data = NULL;
4966       if (seq > 1)
4967          return SQACT_TXTALN;
4968       else
4969          return SQACT_NOTTXTALN;
4970    } else
4971    {
4972       MemFree(line);
4973       line = NULL;
4974       FreeBufferedReadList (current_data);
4975       return SQACT_TXTALN;  /* NEXUS, PHYLIP, etc */
4976    }
4977 }
4978 
sq_transform_code(Uint1 res,Int4 which)4979 static Uint1 sq_transform_code(Uint1 res, Int4 which)
4980 {
4981    if (which == 4) /* ncbi2na */
4982    {
4983       if (res == 1)
4984          return 0;
4985       else if (res == 3)
4986          return 1;
4987       else if (res == 7)
4988          return 2;
4989       else if (res == 18)
4990          return 3;
4991       else
4992          return 0;
4993    } else if (which == 2) /* ncbi4na */
4994    {
4995       if (res == 1)
4996          return 1;
4997       else if (res == 3)
4998          return 2;
4999       else if (res == 12)
5000          return 3;
5001       else if (res == 7)
5002          return 4;
5003       else if (res == 16)
5004          return 5;
5005       else if (res == 17)
5006          return 6;
5007       else if (res == 19)
5008          return 7;
5009       else if (res == 18)
5010          return 8;
5011       else if (res == 20)
5012          return 9;
5013       else if (res == 22)
5014          return 10;
5015       else if (res == 8)
5016          return 11;
5017       else if (res == 10)
5018          return 12;
5019       else if (res == 4)
5020          return 13;
5021       else if (res == 2)
5022          return 14;
5023       else if (res == 13)
5024          return 15;
5025        else
5026          return 15;
5027    }
5028    return 0;
5029 }
5030 
SQACT_FixBioseqs(BioseqPtr bsp,Pointer userdata)5031 static void SQACT_FixBioseqs (BioseqPtr bsp, Pointer userdata)
5032 {
5033    Uint1Ptr           array;
5034    ByteStorePtr       bs;
5035    Int4               compact;
5036    SeqMgrDescContext  context;
5037    Int4               i;
5038    Int4               j;
5039    Int4               len;
5040    MolInfoPtr         mip;
5041    Uint1              res;
5042    Uint1              res1;
5043    Int4               shift;
5044    SeqPortPtr         spp;
5045    ValNodePtr         vnp;
5046 
5047    if (bsp == NULL)
5048       return;
5049    if (bsp->seq_data_type == Seq_code_gap) return;
5050    len = bsp->length-1;
5051    compact = 2;
5052    spp = SeqPortNew(bsp, 0, len, 0, Seq_code_ncbistdaa);
5053    while ((res = SeqPortGetResidue(spp)) != SEQPORT_EOF)
5054    {
5055       if (res != 1 && res != 3 && res != 0 && res != 18 && res != 7 && res != 13 && res != 24 && res != 21)
5056       {
5057          SeqPortFree(spp);
5058          return;
5059       } else if (res != 1 && res != 3 && res != 7 && res != 18)
5060          compact = 4;
5061    }
5062    SeqPortFree(spp);
5063    bs = BSNew((bsp->length+compact-1)/compact);
5064    array = (Uint1Ptr)MemNew((bsp->length+compact)*sizeof(Uint1));
5065    spp = SeqPortNew(bsp, 0, len, 0, Seq_code_ncbistdaa);
5066    for (i=0; i<bsp->length; i++)
5067    {
5068       res = SeqPortGetResidue(spp);
5069       array[i] = sq_transform_code(res, compact);
5070    }
5071    for (i=0; i<compact; i++)
5072       array[i+bsp->length] = 0;
5073    if (compact == 4)
5074       shift = 2;
5075    else
5076       shift = 4;
5077    for (j=0; j<bsp->length; j+=compact)
5078    {
5079       res = 0;
5080       res1 = 0;
5081       for (i=0; i<compact; i++)
5082       {
5083          res = array[j+i];
5084          res1<<=shift;
5085          res1 |= res;
5086       }
5087       BSPutByte(bs, res1);
5088    }
5089    MemFree(bsp->seq_data);
5090    bsp->seq_data = (SeqDataPtr) bs;
5091    if (compact == 4)
5092       bsp->seq_data_type = Seq_code_ncbi2na;
5093    else
5094       bsp->seq_data_type = Seq_code_ncbi4na;
5095    bsp->mol = Seq_mol_na;
5096    bsp->repr = Seq_repr_raw;
5097    SeqMgrIndexFeatures(0, (Pointer)(bsp));
5098    vnp = NULL;
5099    vnp = SeqMgrGetNextDescriptor(bsp, vnp, Seq_descr_molinfo, &context);
5100    if (vnp != NULL)
5101    {
5102       vnp = context.sdp;
5103       mip = (MolInfoPtr)(vnp->data.ptrvalue);
5104       mip->biomol = 1;
5105    }
5106    MemFree(array);
5107 }
5108 
CommonReadNewAsnProc(Handle obj,Boolean removeold,Boolean askForSubmit)5109 static Boolean CommonReadNewAsnProc (Handle obj, Boolean removeold, Boolean askForSubmit)
5110 
5111 {
5112   AsnIoPtr     aip;
5113   BaseFormPtr  bfp;
5114   Pointer      dataptr;
5115   Uint2        datatype;
5116   Uint2        entityID;
5117   FILE         *fp;
5118   Char         path [PATH_MAX];
5119   Boolean      rsult;
5120   SeqEntryPtr  sep;
5121   Int4         type;
5122   Uint2        updateEntityID;
5123 
5124 #ifdef WIN_MAC
5125   bfp = currentFormDataPtr;
5126 #else
5127   bfp = GetObjectExtra (obj);
5128 #endif
5129   rsult = FALSE;
5130   path [0] = '\0';
5131   if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
5132     Update ();
5133     fp = FileOpen (path, "r");
5134     if (fp == NULL) {
5135       ArrowCursor ();
5136       ErrPostEx (SEV_WARNING, 0, 0, "Unable to open file '%s'", path);
5137       return FALSE;
5138     }
5139     type = SQACT_GuessWhatIAm (fp);
5140     FileClose (fp);
5141     if (type == SQACT_UNPRINTABLECHARS || type == SQACT_TXTALN)
5142     {
5143       sep = NULL;
5144       if (type == SQACT_TXTALN)
5145       {
5146         sep = ReadAnyAlignment (TRUE, path);
5147       }
5148       if (sep == NULL)
5149       {
5150         aip = AsnIoOpen (path, "rb");
5151         if (aip != NULL) {
5152           sep = SeqEntryAsnRead (aip, NULL);
5153           AsnIoClose (aip);
5154         }
5155         if (sep == NULL)
5156         {
5157           ArrowCursor ();
5158           if (type == SQACT_UNPRINTABLECHARS)
5159           {
5160             ErrPostEx (SEV_WARNING, 0, 0, "File '%s' contains unprintable characters.  If this is a Word document, you need to save it as plain text.", path);
5161           }
5162           else
5163           {
5164             ErrPostEx (SEV_WARNING, 0, 0, "Error reading file");
5165           }
5166           return FALSE;
5167         }
5168       }
5169       VisitBioseqsInSep (sep, NULL, SQACT_FixBioseqs);
5170       if (IS_Bioseq (sep)) {
5171         datatype = OBJ_BIOSEQ;
5172       } else {
5173         datatype = OBJ_BIOSEQSET;
5174       }
5175       dataptr = (Pointer) sep->data.ptrvalue;
5176       entityID = ObjMgrRegister (datatype, dataptr);
5177       rsult = HandleOneNewAsnProc (bfp, FALSE, askForSubmit, path, dataptr, datatype, entityID, &updateEntityID);
5178       if (updateEntityID != 0)
5179       {
5180         ObjMgrSetDirtyFlag (updateEntityID, TRUE);
5181         ObjMgrSendMsg (OM_MSG_UPDATE, updateEntityID, 0, 0);
5182       }
5183     } else {
5184       rsult = DoReadAnythingLoop (bfp, path, path, removeold, askForSubmit, FALSE, TRUE, FALSE);
5185     }
5186   }
5187   ArrowCursor ();
5188   return rsult;
5189 }
5190 
FinishAlignmentRead(Handle obj,SeqEntryPtr sep,CharPtr path)5191 static void FinishAlignmentRead (Handle obj, SeqEntryPtr sep, CharPtr path) {
5192   BaseFormPtr  bfp;
5193   Pointer      dataptr;
5194   Uint2        datatype;
5195   Uint2        entityID;
5196   Boolean      rsult;
5197   Uint2        updateEntityID;
5198 
5199 #ifdef WIN_MAC
5200   bfp = currentFormDataPtr;
5201 #else
5202   bfp = GetObjectExtra (obj);
5203 #endif
5204 
5205   if (sep == NULL)
5206   {
5207     return;
5208   }
5209   VisitBioseqsInSep (sep, NULL, SQACT_FixBioseqs);
5210   if (IS_Bioseq (sep)) {
5211     datatype = OBJ_BIOSEQ;
5212   } else {
5213     datatype = OBJ_BIOSEQSET;
5214   }
5215   dataptr = (Pointer) sep->data.ptrvalue;
5216   entityID = ObjMgrRegister (datatype, dataptr);
5217   rsult = HandleOneNewAsnProc (bfp, FALSE, FALSE, path,
5218                                dataptr, datatype, entityID, &updateEntityID);
5219   if (updateEntityID != 0) {
5220     ObjMgrSetDirtyFlag (updateEntityID, TRUE);
5221     ObjMgrSendMsg (OM_MSG_UPDATE, updateEntityID, 0, 0);
5222   }
5223 }
5224 
5225 
5226 typedef struct alphabetformdata {
5227   FEATURE_FORM_BLOCK
5228 
5229   DialoG aln_settings;
5230   Handle obj;
5231   Char  path [PATH_MAX];
5232   FILE  *fp;
5233 } AlphabetFormData, PNTR AlphabetFormPtr;
5234 
5235 extern SeqEntryPtr
SeqEntryFromAlignmentFile(FILE * fp,TSequenceInfoPtr sequence_info,Uint1 moltype,CharPtr no_org_err_msg)5236 SeqEntryFromAlignmentFile
5237 (FILE *fp,
5238  TSequenceInfoPtr sequence_info,
5239  Uint1   moltype,
5240  CharPtr no_org_err_msg)
5241 {
5242   TErrorInfoPtr     error_list;
5243   ReadBufferData    rbd;
5244   TAlignmentFilePtr afp;
5245   SeqEntryPtr       sep = NULL;
5246 
5247   if (fp == NULL || sequence_info == NULL) return NULL;
5248 
5249   error_list = NULL;
5250   rbd.fp = fp;
5251   rbd.current_data = NULL;
5252   afp = ReadAlignmentFile ( AbstractReadFunction,
5253                             (Pointer) &rbd,
5254                             AbstractReportError,
5255                             (Pointer) &error_list,
5256                             sequence_info);
5257 
5258   ProduceAlignmentNotes (afp, error_list);
5259   ErrorInfoFree (error_list);
5260   if (afp != NULL) {
5261     if (afp->num_organisms == 0 && no_org_err_msg != NULL) {
5262       Message (MSG_ERROR, no_org_err_msg);
5263     } else if (afp->num_organisms != 0 && afp->num_organisms != afp->num_sequences && afp->num_organisms * afp->num_segments != afp->num_sequences) {
5264       Message (MSG_ERROR, "Number of organisms must match number of sequences!");
5265     } else if (! DoSequenceLengthsMatch (afp)) {
5266       Message (MSG_ERROR, "Your alignment is incorrectly formatted.  Sequence plus gaps should be the same length for all sequences.");
5267     } else {
5268       sep = MakeSequinDataFromAlignment (afp, moltype);
5269     }
5270   }
5271 
5272   AlignmentFileFree (afp);
5273   return sep;
5274 }
5275 
DoReadAlignment(ButtoN b)5276 static void DoReadAlignment (ButtoN b)
5277 {
5278   AlphabetFormPtr  abc;
5279   TAlignmentFilePtr afp;
5280   TErrorInfoPtr     error_list;
5281   TSequenceInfoPtr  sequence_info;
5282   SeqEntryPtr      sep;
5283   Uint1            moltype;
5284   ReadBufferData   rbd;
5285 
5286   abc = GetObjectExtra (b);
5287   if (abc == NULL) return;
5288   Hide (abc->form);
5289   Update ();
5290 
5291   sequence_info = (TSequenceInfoPtr) DialogToPointer (abc->aln_settings);
5292   if (sequence_info == NULL) return;
5293 
5294   WatchCursor ();
5295   Update ();
5296 
5297   if (StringCmp (sequence_info->alphabet, protein_alphabet) == 0) {
5298     moltype = Seq_mol_aa;
5299   } else {
5300     moltype = Seq_mol_na;
5301   }
5302 
5303   error_list = NULL;
5304   rbd.fp = abc->fp;
5305   rbd.current_data = NULL;
5306   afp = ReadAlignmentFile ( AbstractReadFunction,
5307                             (Pointer) &rbd,
5308                             AbstractReportError,
5309                             (Pointer) &error_list,
5310                             sequence_info);
5311   if (afp != NULL) {
5312       sep = MakeSequinDataFromAlignment (afp, moltype);
5313       FinishAlignmentRead (abc->obj, sep, abc->path);
5314   }
5315   ProduceAlignmentNotes (afp, error_list);
5316   ErrorInfoFree (error_list);
5317   SequenceInfoFree (sequence_info);
5318 
5319   AlignmentFileFree (afp);
5320   FileClose (abc->fp);
5321   abc->fp = NULL;
5322   ArrowCursor ();
5323   Update ();
5324   Remove (abc->form);
5325 }
5326 
5327 
5328 /* Need cleanup for Alphabet Dialog to close File Pointer */
CleanupAlphabetDialog(GraphiC g,VoidPtr data)5329 static void CleanupAlphabetDialog (GraphiC g, VoidPtr data)
5330 {
5331     AlphabetFormPtr afp;
5332 
5333     afp = (AlphabetFormPtr) data;
5334     if (afp != NULL && afp->fp != NULL) {
5335         FileClose (afp->fp);
5336         afp->fp = NULL;
5337     }
5338     StdCleanupFormProc (g, data);
5339 }
5340 
BuildGetAlphabetDialog(IteM i)5341 static void BuildGetAlphabetDialog (IteM i)
5342 {
5343   BaseFormPtr        bfp;
5344   ButtoN             b;
5345   GrouP              c, h;
5346   AlphabetFormPtr    afp;
5347   WindoW             w;
5348 
5349 #ifdef WIN_MAC
5350   bfp = currentFormDataPtr;
5351 #else
5352   bfp = GetObjectExtra (i);
5353 #endif
5354   if (bfp == NULL) return;
5355 
5356   afp = (AlphabetFormPtr) MemNew (sizeof (AlphabetFormData));
5357   if (afp == NULL) return;
5358   afp->obj = i;
5359 
5360   if (! GetInputFileName (afp->path, sizeof (afp->path), NULL, "TEXT")) return;
5361 
5362   afp->fp = FileOpen (afp->path, "r");
5363   if (afp->fp == NULL)
5364   {
5365     Message (MSG_ERROR, "Unable to open file");
5366     return;
5367   }
5368 
5369   w = FixedWindow (-50, -33, -10, -10, "Alignment Alphabet", StdCloseWindowProc);
5370   SetObjectExtra (w, afp, CleanupAlphabetDialog);
5371   afp->form = (ForM) w;
5372   afp->formmessage = NULL;
5373 
5374   h = HiddenGroup (w, -1, 0, NULL);
5375   SetGroupSpacing (h, 10, 10);
5376 
5377   afp->aln_settings = AlnSettingsDlg (h, TRUE);
5378 
5379   c = HiddenGroup (h, 4, 0, NULL);
5380   b = DefaultButton (c, "Accept", DoReadAlignment);
5381   SetObjectExtra (b, afp, NULL);
5382   PushButton (c, "Cancel", StdCancelButtonProc);
5383 
5384   AlignObjects (ALIGN_CENTER, (HANDLE) afp->aln_settings, (HANDLE) c, NULL);
5385   RealizeWindow (w);
5386   Show (w);
5387   Update ();
5388 }
5389 
ReadAlignment(IteM i)5390 extern void ReadAlignment (IteM i)
5391 {
5392   BuildGetAlphabetDialog (i);
5393 
5394 }
5395 
5396 
GetDefaultSequenceInfo(void)5397 extern TSequenceInfoPtr GetDefaultSequenceInfo (void)
5398 {
5399   TSequenceInfoPtr sequence_info = SequenceInfoNew();
5400 
5401   sequence_info->missing = MemFree (sequence_info->missing);
5402   sequence_info->missing = StringSave ("?Nn");
5403 
5404   sequence_info->beginning_gap = MemFree (sequence_info->beginning_gap);
5405   sequence_info->beginning_gap = StringSave ("-.Nn?");
5406 
5407   sequence_info->middle_gap = MemFree (sequence_info->middle_gap);
5408   sequence_info->middle_gap = StringSave ("-.");
5409 
5410   sequence_info->end_gap = MemFree (sequence_info->end_gap);
5411   sequence_info->end_gap = StringSave ("-.Nn?");
5412 
5413   sequence_info->match = MemFree (sequence_info->match);
5414   sequence_info->match = StringSave (":");
5415 
5416   sequence_info->alphabet = nucleotide_alphabet;
5417 
5418   return sequence_info;
5419 }
5420 
ReadNewAsnProc(IteM i)5421 static void ReadNewAsnProc (IteM i)
5422 
5423 {
5424   CommonReadNewAsnProc ((Handle) i, FALSE, FALSE);
5425 }
5426 
SequinOpenMimeFile(CharPtr filename)5427 extern Boolean LIBCALLBACK SequinOpenMimeFile (CharPtr filename)
5428 
5429 {
5430   Boolean  rsult = FALSE;
5431 
5432 #ifdef WIN_MAC
5433   SafeHide (startupForm); /* if just Hide, triggers MacDeactProc, does not reactivate */
5434   Update ();
5435 #endif
5436   rsult = DoReadAnythingLoop (NULL, filename, filename, FALSE, FALSE, FALSE, TRUE, FALSE);
5437   if (! rsult) {
5438 /*
5439 #ifndef WIN16
5440     if (BiostrucAvail () && OpenMimeFileWithDeletion (filename, FALSE)) {
5441       Handle   www_cn3d;
5442       www_cn3d = Cn3DWin_Entrez(NULL, useEntrez);
5443       Show (www_cn3d);
5444       Select (www_cn3d);
5445     } else {
5446       Show (startupForm);
5447       Select (startupForm);
5448     }
5449 #else
5450     Show (startupForm);
5451     Select (startupForm);
5452 #endif
5453 */
5454     Show (startupForm);
5455     Select (startupForm);
5456   }
5457 #ifdef OS_MAC
5458   /* the Web browsers on other platforms get upset if you delete the file, */
5459   /* but apparently on the Mac you must delete it - comment from cn3dmain.c */
5460   /* but here it's for response to apple events, so should not free this file */
5461   /* FileRemove (filename); */
5462 #endif
5463   return rsult;
5464 }
5465 
SequinOpenResultFile(CharPtr filename)5466 extern Boolean LIBCALLBACK SequinOpenResultFile (CharPtr filename)
5467 
5468 {
5469   return DoReadAnythingLoop (NULL, filename, NULL, FALSE, FALSE, FALSE, TRUE, FALSE);
5470 }
5471 
SequinHandleNetResults(CharPtr filename)5472 extern Boolean LIBCALLBACK SequinHandleNetResults (CharPtr filename)
5473 
5474 {
5475   return DoReadAnythingLoop (NULL, filename, NULL, FALSE, FALSE, TRUE, TRUE, TRUE);
5476 }
5477 
5478 #ifdef WIN_MAC
MacReadNewAsnProc(IteM i)5479 static void MacReadNewAsnProc (IteM i)
5480 
5481 {
5482   if (initialFormsActive) {
5483     CommonReadNewAsnProc ((Handle) i, TRUE, FALSE);
5484   } else {
5485     CommonReadNewAsnProc ((Handle) i, FALSE, FALSE);
5486   }
5487 }
5488 #endif
5489 
CountAlignmentsCallback(GatherContextPtr gcp)5490 static Boolean CountAlignmentsCallback (GatherContextPtr gcp)
5491 
5492 {
5493   Int4Ptr  rsultptr;
5494 
5495   if (gcp == NULL) return TRUE;
5496 
5497   rsultptr = (Int4Ptr) gcp->userdata;
5498   if (rsultptr == NULL ) return TRUE;
5499 
5500   switch (gcp->thistype) {
5501     case OBJ_SEQALIGN :
5502     case OBJ_SEQHIST_ALIGN :
5503       (*rsultptr)++;
5504       return TRUE;
5505     default :
5506       break;
5507   }
5508   return TRUE;
5509 }
5510 
CountSeqEntryAligns(Uint2 entityID,SeqEntryPtr sep)5511 static Int4 LIBCALL CountSeqEntryAligns (Uint2 entityID, SeqEntryPtr sep)
5512 
5513 {
5514   GatherScope  gs;
5515   Int4         rsult;
5516 
5517   rsult = 0;
5518   if (entityID == 0 || sep == NULL) return 0;
5519   MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
5520   gs.seglevels = 1;
5521   MemSet((Pointer) (gs.ignore), (int) (TRUE), (size_t) (OBJ_MAX * sizeof (Boolean)));
5522   gs.ignore[OBJ_BIOSEQ] = FALSE;
5523   gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
5524   gs.ignore[OBJ_SEQALIGN] = FALSE;
5525   gs.ignore[OBJ_SEQANNOT] = FALSE;
5526   gs.ignore[OBJ_SEQHIST] = FALSE;
5527   gs.ignore[OBJ_SEQHIST_ALIGN] = FALSE;
5528   gs.scope = sep;
5529   GatherEntity (entityID, (Pointer) (&rsult), CountAlignmentsCallback, &gs);
5530   return rsult;
5531 }
5532 
GetAlignmentSetForBioseq(BioseqPtr bsp,Uint2 entityID)5533 static BioseqSetPtr GetAlignmentSetForBioseq (BioseqPtr bsp, Uint2 entityID)
5534 {
5535   BioseqSetPtr bssp = NULL;
5536   SeqEntryPtr  sep, sep_top;
5537   Uint2        parenttype;
5538   Pointer      parentptr;
5539 
5540   if (bsp == NULL)
5541   {
5542     return NULL;
5543   }
5544 
5545   sep_top = GetTopSeqEntryForEntityID (entityID);
5546 
5547   sep = GetBestTopParentForData (entityID, bsp);
5548   GetSeqEntryParent (sep, &parentptr, &parenttype);
5549   if (parenttype == OBJ_BIOSEQSET)
5550   {
5551     bssp = (BioseqSetPtr) parentptr;
5552   }
5553   else if (sep != NULL && IS_Bioseq_set (sep))
5554   {
5555     bssp = (BioseqSetPtr) sep->data.ptrvalue;
5556   }
5557   else if (sep_top != NULL && IS_Bioseq_set (sep_top))
5558   {
5559     bssp = (BioseqSetPtr) sep_top->data.ptrvalue;
5560   }
5561   return bssp;
5562 }
5563 
EnableEditAlignItem(BaseFormPtr bfp)5564 static void EnableEditAlignItem (BaseFormPtr bfp)
5565 
5566 {
5567   BioseqPtr     bsp;
5568   BioseqSetPtr  bssp;
5569   IteM          editalign;
5570   IteM          editdup;
5571   IteM          editfeatprop;
5572   Int2          mssgalign;
5573   Int2          mssgdup;
5574   Int2          mssgfeatprop;
5575   Int4          num;
5576   SeqEntryPtr   sep;
5577   SelStructPtr  sel;
5578 
5579   if (bfp == NULL || bfp->input_entityID == 0) return;
5580   mssgalign = RegisterFormMenuItemName ("SequinEditAlignmentItem");
5581   mssgdup = RegisterFormMenuItemName ("SequinDuplicateItem");
5582   mssgfeatprop = RegisterFormMenuItemName ("SequinFeaturePropagate");
5583   editalign = FindFormMenuItem (bfp, mssgalign);
5584   editdup = FindFormMenuItem (bfp, mssgdup);
5585   editfeatprop = FindFormMenuItem (bfp, mssgfeatprop);
5586   sel = ObjMgrGetSelected ();
5587   sep = NULL;
5588   /*
5589   bsp =  GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
5590   if (bsp != NULL) {
5591     sep = GetBestTopParentForData (bfp->input_entityID, bsp);
5592   } else {
5593     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5594   }
5595   */
5596   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5597   num = CountSeqEntryAligns (bfp->input_entityID, sep);
5598   if (sep != NULL && num > 0) {
5599     if (sel != NULL && sel->entityID == bfp->input_entityID &&
5600         (sel->itemtype == OBJ_SEQALIGN || sel->itemtype == OBJ_SEQHIST_ALIGN)) {
5601       Enable (editalign);
5602     } else /* if (sel == NULL) */ {
5603       if (FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN) != NULL) {
5604         Enable (editalign);
5605       } else {
5606         Disable (editalign);
5607       }
5608     } /* else {
5609       Disable (editalign);
5610       Disable (editupwthaln);
5611     } */
5612   } else {
5613     Disable (editalign);
5614   }
5615   if (sel != NULL &&
5616       (sel->itemtype == OBJ_SEQDESC || sel->itemtype == OBJ_SEQFEAT)) {
5617     Enable (editdup);
5618   } else {
5619     Disable (editdup);
5620   }
5621   bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
5622   if (num > 0 && bsp != NULL && sep != NULL && IS_Bioseq_set (sep)) {
5623     bssp = GetAlignmentSetForBioseq (bsp, bfp->input_entityID);
5624     if (bssp != NULL) {
5625       if (IsPopPhyEtcSet (bssp->_class)) {
5626         Enable (editfeatprop);
5627       } else if (bssp->_class == 7 && indexerVersion) {
5628         Enable (editfeatprop);
5629       } else {
5630         Disable (editfeatprop);
5631       }
5632     } else {
5633       Disable (editfeatprop);
5634     }
5635   } else {
5636     Disable (editfeatprop);
5637   }
5638 }
5639 
EnableEditSeqAlignAndSubItems(BaseFormPtr bfp)5640 static void EnableEditSeqAlignAndSubItems (BaseFormPtr bfp)
5641 
5642 {
5643   BioseqPtr      bsp;
5644   BioseqSetPtr   bssp;
5645   IteM           editseq;
5646   IteM           editsub;
5647   MenU           editupd;
5648   MenU           editupd_idx = NULL;
5649   MenU           editext;
5650   MenU           editadd;
5651   Int2           mssgadd;
5652   Int2           mssgseq;
5653   Int2           mssgsub;
5654   Int2           mssgupd;
5655   Int2           mssgupd_idx = 0;
5656   Int2           mssgext;
5657   ObjMgrDataPtr  omdp;
5658   SeqEntryPtr    sep;
5659 
5660   if (bfp == NULL || bfp->input_entityID == 0) return;
5661   mssgseq = RegisterFormMenuItemName ("SequinEditSequenceItem");
5662   mssgsub = RegisterFormMenuItemName ("SequinEditSubmitterItem");
5663   mssgupd = RegisterFormMenuItemName ("SequinUpdateSeqSubmenu");
5664   if (indexerVersion) {
5665     mssgupd_idx = RegisterFormMenuItemName ("SequinUpdateSeqSubmenuIndexer");
5666   }
5667   mssgext = RegisterFormMenuItemName ("SequinExtendSeqSubmenu");
5668   mssgadd = RegisterFormMenuItemName ("SequinAddSeqSubmenu");
5669   editseq = FindFormMenuItem (bfp, mssgseq);
5670   editsub = FindFormMenuItem (bfp, mssgsub);
5671   editupd = (MenU) FindFormMenuItem (bfp, mssgupd);
5672   if (indexerVersion) {
5673     editupd_idx = (MenU) FindFormMenuItem (bfp, mssgupd_idx);
5674   }
5675   editext = (MenU) FindFormMenuItem (bfp, mssgext);
5676   editadd = (MenU) FindFormMenuItem (bfp, mssgadd);
5677   bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
5678   if (bsp != NULL) {
5679     Enable (editseq);
5680     Enable (editupd);
5681     if (indexerVersion) {
5682       Enable (editupd_idx);
5683     }
5684     Enable (editext);
5685     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5686     if (sep != NULL && IS_Bioseq_set (sep)) {
5687       bssp = (BioseqSetPtr) sep->data.ptrvalue;
5688       if (bssp != NULL && (bssp->_class == 7 || (IsPopPhyEtcSet (bssp->_class)))) {
5689         Enable (editadd);
5690       } else {
5691         Disable (editadd);
5692       }
5693     } else {
5694       Disable (editadd);
5695     }
5696 #ifdef WIN_MAC
5697     Enable (featPropItem);
5698 #endif
5699   } else {
5700     Disable (editseq);
5701     Disable (editupd);
5702     if (indexerVersion) {
5703       Disable (editupd_idx);
5704     }
5705     Disable (editext);
5706     Disable (editadd);
5707 #ifdef WIN_MAC
5708     Disable (featPropItem);
5709 #endif
5710   }
5711   omdp = ObjMgrGetData (bfp->input_entityID);
5712   if (omdp != NULL && omdp->datatype == OBJ_SEQSUB) {
5713     Enable (editsub);
5714 #ifdef WIN_MAC
5715     Enable (prepareItem);
5716     Enable (submitItem);
5717 #endif
5718   } else {
5719     Disable (editsub);
5720 #ifdef WIN_MAC
5721     Disable (prepareItem);
5722     Disable (submitItem);
5723 #endif
5724   }
5725   EnableEditAlignItem (bfp);
5726 }
5727 
5728 #ifdef WIN_MAC
MedlineViewFormActivated(WindoW w)5729 static void MedlineViewFormActivated (WindoW w)
5730 
5731 {
5732   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5733   initialFormsActive = FALSE;
5734   RepeatProcOnHandles (Enable,
5735                    (HANDLE) closeItem,
5736                    (HANDLE) duplicateViewItem,
5737                    (HANDLE) exportItem,
5738                    (HANDLE) printItem,
5739                    (HANDLE) copyItem,
5740                    (HANDLE) displayfontItem,
5741                    NULL);
5742 }
5743 
BioseqViewFormActivated(WindoW w)5744 static void BioseqViewFormActivated (WindoW w)
5745 
5746 {
5747   bioseqViewUp = TRUE;
5748   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5749   initialFormsActive = FALSE;
5750   /* SafeSetTitle (importItem, "Import Nucleotide FASTA..."); */
5751   RepeatProcOnHandles (Enable,
5752                    (HANDLE) openItem,
5753                    (HANDLE) closeItem,
5754                    (HANDLE) saveItem,
5755                    (HANDLE) saveAsItem,
5756                    (HANDLE) copyItem,
5757                    (HANDLE) deleteItem,
5758                    (HANDLE) findItem,
5759                    (HANDLE) findFFItem,
5760                    (HANDLE) findGeneItem,
5761                    (HANDLE) findProtItem,
5762                    (HANDLE) findPosItem,
5763                    (HANDLE) exportItem,
5764                    (HANDLE) duplicateViewItem,
5765                    (HANDLE) restoreItem,
5766                    (HANDLE) printItem,
5767                    (HANDLE) orfItem,
5768                    (HANDLE) targetItem,
5769                    (HANDLE) newDescMenu,
5770                    (HANDLE) newFeatMenu,
5771                    (HANDLE) advTableMenu,
5772                    (HANDLE) sucItem,
5773                    (HANDLE) newPubMenu,
5774                    (HANDLE) batchApplyMenu,
5775                    (HANDLE) batchEditMenu,
5776                    (HANDLE) prepareItem,
5777                    (HANDLE) edithistoryitem,
5778                    NULL);
5779   Enable (validateItem);
5780   Enable (validateMenu);
5781   Enable (vecscreenMenu);
5782   Enable (aluItem);
5783   Enable (submitItem);
5784   Enable (specialMenu);
5785   Enable (projectsMenu);
5786   Enable (analysisMenu);
5787   Enable (vectorScreenItem);
5788   Enable (cddSearchMenu);
5789   Enable (cddSearchItem);
5790   Enable (parseFileItem);
5791   Enable (spellItem);
5792   Enable (addSecondaryItem);
5793   Enable (displayfontItem);
5794   Disable (importItem);
5795   EnableFeaturesPerTarget ((BaseFormPtr) currentFormDataPtr);
5796   EnableAnalysisItems ((BaseFormPtr) currentFormDataPtr, FALSE);
5797   EnableEditSeqAlignAndSubItems ((BaseFormPtr) currentFormDataPtr);
5798 }
5799 
5800 /*
5801 static void TermSelectionActivateProc (WindoW w)
5802 
5803 {
5804   termListUp = TRUE;
5805   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5806   initialFormsActive = FALSE;
5807   if (UsingTextQuery ((ForM) w)) {
5808     SafeSetValue (queryChoice, 2);
5809   } else {
5810     SafeSetValue (queryChoice, 1);
5811   }
5812   RepeatProcOnHandles (Enable,
5813                    (HANDLE) importItem,
5814                    (HANDLE) exportItem,
5815                    (HANDLE) cutItem,
5816                    (HANDLE) copyItem,
5817                    (HANDLE) pasteItem,
5818                    (HANDLE) deleteItem,
5819                    (HANDLE) preferencesItem,
5820                    (HANDLE) queryChoice,
5821                    (HANDLE) clearUnusedItem,
5822                    NULL);
5823   Enable (loadUidItem);
5824   Enable (saveUidItem);
5825 }
5826 
5827 static void DocumentSummaryActivateProc (WindoW w)
5828 
5829 {
5830   docSumUp = TRUE;
5831   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5832   initialFormsActive = FALSE;
5833   if (UsingDelayedNeighbor ((ForM) w)) {
5834     SafeSetValue (neighborChoice, 2);
5835   } else {
5836     SafeSetValue (neighborChoice, 1);
5837   }
5838   RepeatProcOnHandles (Enable,
5839                    (HANDLE) saveAsItem,
5840                    (HANDLE) closeItem,
5841                    (HANDLE) importItem,
5842                    (HANDLE) exportItem,
5843                    (HANDLE) printItem,
5844                    (HANDLE) copyItem,
5845                    (HANDLE) preferencesItem,
5846                    (HANDLE) neighborChoice,
5847                    (HANDLE) docsumfontItem,
5848                    (HANDLE) analysisMenu,
5849                    NULL);
5850   Enable (loadUidItem);
5851   Enable (saveUidItem);
5852   EnableAnalysisItems ((BaseFormPtr) currentFormDataPtr, TRUE);
5853 }
5854 */
5855 
SeqEditFormActivated(WindoW w)5856 static void SeqEditFormActivated (WindoW w)
5857 
5858 {
5859   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5860   initialFormsActive = FALSE;
5861   RepeatProcOnHandles (Enable,
5862                    (HANDLE) openItem,
5863                    (HANDLE) closeItem,
5864                    (HANDLE) cutItem,
5865                    (HANDLE) copyItem,
5866                    (HANDLE) pasteItem,
5867                    (HANDLE) deleteItem,
5868                    (HANDLE) importItem,
5869                    (HANDLE) exportItem,
5870                    NULL);
5871 }
5872 
StdEditorFormActivated(WindoW w)5873 static void StdEditorFormActivated (WindoW w)
5874 
5875 {
5876   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5877   initialFormsActive = FALSE;
5878   RepeatProcOnHandles (Enable,
5879                    (HANDLE) openItem,
5880                    (HANDLE) closeItem,
5881                    (HANDLE) cutItem,
5882                    (HANDLE) copyItem,
5883                    (HANDLE) pasteItem,
5884                    (HANDLE) deleteItem,
5885                    (HANDLE) importItem,
5886                    (HANDLE) exportItem,
5887                    NULL);
5888 }
5889 
StdValidatorFormActivated(WindoW w)5890 static void StdValidatorFormActivated (WindoW w)
5891 
5892 {
5893   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5894   initialFormsActive = FALSE;
5895   RepeatProcOnHandles (Enable,
5896                    (HANDLE) openItem,
5897                    (HANDLE) closeItem,
5898                    (HANDLE) cutItem,
5899                    (HANDLE) copyItem,
5900                    (HANDLE) pasteItem,
5901                    (HANDLE) deleteItem,
5902                    (HANDLE) importItem,
5903                    (HANDLE) exportItem,
5904                    (HANDLE) printItem,
5905                    NULL);
5906 }
5907 
TextViewProcFormActivated(WindoW w)5908 static void TextViewProcFormActivated (WindoW w)
5909 
5910 {
5911   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5912   initialFormsActive = FALSE;
5913   RepeatProcOnHandles (Enable,
5914                    (HANDLE) openItem,
5915                    (HANDLE) closeItem,
5916                    (HANDLE) cutItem,
5917                    (HANDLE) copyItem,
5918                    (HANDLE) pasteItem,
5919                    (HANDLE) deleteItem,
5920                    (HANDLE) importItem,
5921                    (HANDLE) exportItem,
5922                    (HANDLE) printItem,
5923                    NULL);
5924 }
5925 
ConfigFormActivated(WindoW w)5926 static void ConfigFormActivated (WindoW w)
5927 
5928 {
5929   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5930   initialFormsActive = FALSE;
5931   RepeatProcOnHandles (Enable,
5932                    (HANDLE) cutItem,
5933                    (HANDLE) copyItem,
5934                    (HANDLE) pasteItem,
5935                    (HANDLE) deleteItem,
5936                    NULL);
5937 }
5938 
StartupActivateProc(WindoW w)5939 static void StartupActivateProc (WindoW w)
5940 
5941 {
5942   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5943   initialFormsActive = FALSE;
5944   Enable (openItem);
5945 }
5946 
FormatActivateProc(WindoW w)5947 static void FormatActivateProc (WindoW w)
5948 
5949 {
5950   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5951   initialFormsActive = TRUE;
5952   Enable (openItem);
5953 }
5954 
SubmitBlockActivateProc(WindoW w)5955 static void SubmitBlockActivateProc (WindoW w)
5956 
5957 {
5958   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5959   initialFormsActive = TRUE;
5960   RepeatProcOnHandles (Enable,
5961                    (HANDLE) openItem,
5962                    (HANDLE) cutItem,
5963                    (HANDLE) copyItem,
5964                    (HANDLE) pasteItem,
5965                    (HANDLE) deleteItem,
5966                    (HANDLE) importItem,
5967                    (HANDLE) exportItem,
5968                    NULL);
5969 }
5970 
GenomeFormActivateProc(WindoW w)5971 static void GenomeFormActivateProc (WindoW w)
5972 
5973 {
5974   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5975   initialFormsActive = TRUE;
5976   RepeatProcOnHandles (Enable,
5977                    (HANDLE) openItem,
5978                    (HANDLE) cutItem,
5979                    (HANDLE) copyItem,
5980                    (HANDLE) pasteItem,
5981                    (HANDLE) deleteItem,
5982                    (HANDLE) importItem,
5983                    (HANDLE) exportItem,
5984                    NULL);
5985 }
5986 
OrgAndSeqsActivateProc(WindoW w)5987 static void OrgAndSeqsActivateProc (WindoW w)
5988 
5989 {
5990   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
5991   initialFormsActive = TRUE;
5992   RepeatProcOnHandles (Enable,
5993                    (HANDLE) openItem,
5994                    (HANDLE) cutItem,
5995                    (HANDLE) copyItem,
5996                    (HANDLE) pasteItem,
5997                    (HANDLE) deleteItem,
5998                    (HANDLE) importItem,
5999                    (HANDLE) exportItem,
6000                    NULL);
6001 }
6002 
HelpActivateProc(WindoW w)6003 static void HelpActivateProc (WindoW w)
6004 
6005 {
6006   currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
6007   RepeatProcOnHandles (Enable,
6008                    (HANDLE) openItem,
6009                    (HANDLE) closeItem,
6010                    (HANDLE) cutItem,
6011                    (HANDLE) copyItem,
6012                    (HANDLE) pasteItem,
6013                    (HANDLE) deleteItem,
6014                    (HANDLE) exportItem,
6015                    (HANDLE) printItem,
6016                    NULL);
6017 }
6018 
MacDeactProc(WindoW w)6019 static void MacDeactProc (WindoW w)
6020 
6021 {
6022   termListUp = FALSE;
6023   docSumUp = FALSE;
6024   bioseqViewUp = FALSE;
6025   currentFormDataPtr = NULL;
6026   initialFormsActive = FALSE;
6027   Enable (openItem);
6028   SafeSetTitle (importItem, "Import...");
6029   SafeSetTitle (exportItem, "Export...");
6030   SafeSetValue (queryChoice, 0);
6031   SafeSetValue (neighborChoice, 0);
6032   RepeatProcOnHandles (Disable,
6033                    (HANDLE) saveItem,
6034                    (HANDLE) saveAsItem,
6035                    (HANDLE) closeItem,
6036                    (HANDLE) cutItem,
6037                    (HANDLE) copyItem,
6038                    (HANDLE) pasteItem,
6039                    (HANDLE) deleteItem,
6040                    (HANDLE) duplicateViewItem,
6041                    (HANDLE) importItem,
6042                    (HANDLE) exportItem,
6043                    (HANDLE) findItem,
6044                    (HANDLE) findFFItem,
6045                    (HANDLE) findGeneItem,
6046                    (HANDLE) findProtItem,
6047                    (HANDLE) findPosItem,
6048                    (HANDLE) orfItem,
6049                    (HANDLE) targetItem,
6050                    (HANDLE) newDescMenu,
6051                    (HANDLE) newFeatMenu,
6052                    (HANDLE) advTableMenu,
6053                    (HANDLE) sucItem,
6054                    (HANDLE) newPubMenu,
6055                    (HANDLE) batchApplyMenu,
6056                    (HANDLE) batchEditMenu,
6057                    (HANDLE) prepareItem,
6058                    (HANDLE) editsequenceitem,
6059                    (HANDLE) editseqalignitem,
6060                    (HANDLE) editseqsubitem,
6061                    (HANDLE) edithistoryitem,
6062                    (HANDLE) updateSeqMenu,
6063                    (HANDLE) extendSeqMenu,
6064                    (HANDLE) addSeqMenu,
6065                    (HANDLE) featPropItem,
6066                    (HANDLE) updalignitem,
6067                    (HANDLE) updalignidxitem,
6068                    NULL);
6069   Disable (validateItem);
6070   Disable (validateMenu);
6071   Disable (vecscreenMenu);
6072   Disable (aluItem);
6073   Disable (submitItem);
6074   Disable (vectorScreenItem);
6075   Disable (cddSearchMenu);
6076   Disable (cddSearchItem);
6077   Disable (parseFileItem);
6078   Disable (spellItem);
6079   Disable (docsumfontItem);
6080   Disable (queryChoice);
6081   Disable (clearUnusedItem);
6082   Disable (neighborChoice);
6083   Disable (legendItem);
6084   Disable (duplicateItem);
6085   Disable (addSecondaryItem);
6086   Disable (displayfontItem);
6087   Disable (printItem);
6088   Disable (restoreItem);
6089   Disable (specialMenu);
6090   Disable (projectsMenu);
6091   Disable (analysisMenu);
6092   Disable (loadUidItem);
6093   Disable (saveUidItem);
6094   if (indexerVersion) {
6095     Disable (updateSeqMenuIndexer);
6096   }
6097 }
6098 #endif
6099 
6100 #ifndef WIN_MAC
6101 #define MedlineViewFormActivated NULL
6102 #define BioseqViewFormActivated NULL
6103 #define TermSelectionActivateProc NULL
6104 #define DocumentSummaryActivateProc NULL
6105 #define SeqEditFormActivated NULL
6106 #define StdEditorFormActivated NULL
6107 #define StdValidatorFormActivated NULL
6108 #define TextViewProcFormActivated NULL
6109 #define ConfigFormActivated NULL
6110 #define StartupActivateProc NULL
6111 #define FormatActivateProc NULL
6112 #define SubmitBlockActivateProc NULL
6113 #define OrgAndSeqsActivateProc NULL
6114 #define GenomeFormActivateProc NULL
6115 #define HelpActivateProc NULL
6116 #endif
6117 
HideHelpForm(ButtoN b)6118 static void HideHelpForm (ButtoN b)
6119 
6120 {
6121   Hide (ParentWindow (b));
6122 }
6123 
DisplayHelpFormProc(IteM i)6124 static void DisplayHelpFormProc (IteM i)
6125 
6126 {
6127   if (helpForm == NULL) {
6128     WatchCursor ();
6129     helpForm = CreateHelpForm (-95, -5, "Sequin Help", "sequin.hlp",
6130                                HideHelpForm, HelpActivateProc);
6131     ArrowCursor ();
6132   }
6133   if (helpForm != NULL) {
6134     Show (helpForm);
6135     Select (helpForm);
6136   }
6137 }
6138 
6139 /*#ifdef USE_MEDARCH*/
6140 
LaunchXmlViewer(XmlObjPtr xop,CharPtr title)6141 static void LaunchXmlViewer (XmlObjPtr xop, CharPtr title)
6142 
6143 {
6144   Char  path [PATH_MAX];
6145   FILE  *fp;
6146 
6147   TmpNam (path);
6148 
6149   fp = FileOpen (path, "wb");
6150   if (fp == NULL) return;
6151 
6152   WriteXmlObject (xop, fp);
6153 
6154   FileClose (fp);
6155 
6156   LaunchGeneralTextViewer (path, title);
6157 
6158   FileRemove (path);
6159 }
6160 
6161 static Boolean debug_fix_pub_equiv = FALSE;
6162 static Boolean debug_fix_pub_set = FALSE;
6163 
6164 static Boolean log_mla_asn = FALSE;
6165 static Boolean log_mla_set = FALSE;
6166 
AddAuthorProc(NameStdPtr nsp,Pointer userdata)6167 static void AddAuthorProc (NameStdPtr nsp, Pointer userdata)
6168 
6169 {
6170   ValNodeBlockPtr  vnbp;
6171 
6172   if (nsp == NULL || userdata == NULL) return;
6173   vnbp = (ValNodeBlockPtr) userdata;
6174 
6175   if (StringHasNoText (nsp->names[0])) return;
6176 
6177   ValNodeCopyStrEx (&(vnbp->head), &(vnbp->tail), 0, nsp->names[0]);
6178 }
6179 
ConstructArticleQuery(ValNodePtr oldpep,Boolean useAuthors,Boolean useTitle,Boolean useJournal,Boolean useImprint)6180 static CharPtr ConstructArticleQuery (ValNodePtr oldpep, Boolean useAuthors, Boolean useTitle,
6181                                       Boolean useJournal, Boolean useImprint)
6182 
6183 {
6184   ValNodeBlock  blk;
6185   CitArtPtr     cap = NULL;
6186   CitJourPtr    cjp = NULL;
6187   DatePtr       dp;
6188   ImprintPtr    imp = NULL;
6189   Pubdesc       pd;
6190   CharPtr       query;
6191   CharPtr       str;
6192   ValNodePtr    vnp;
6193   Char          year [8];
6194 
6195   if (oldpep == NULL) return NULL;
6196 
6197   for (vnp = oldpep; vnp != NULL; vnp = vnp->next) {
6198     if (vnp->choice != PUB_Article) continue;
6199     cap = (CitArtPtr) vnp->data.ptrvalue;
6200   }
6201   if (cap == NULL) return NULL;
6202 
6203   if (cap->from == 1) {
6204     cjp = (CitJourPtr) cap->fromptr;
6205     if (cjp != NULL) {
6206       imp = cjp->imp;
6207     }
6208   }
6209 
6210   blk.head = NULL;
6211   blk.tail = NULL;
6212 
6213   if (useAuthors) {
6214     MemSet ((Pointer) &pd, 0, sizeof (Pubdesc));
6215     pd.pub = oldpep;
6216     VisitAuthorsInPub (&pd, (Pointer) &blk, AddAuthorProc);
6217   }
6218 
6219   if (useTitle) {
6220     for (vnp = cap->title; vnp != NULL; vnp = vnp->next) {
6221       if (vnp->choice != Cit_title_name) continue;
6222       str = (CharPtr) vnp->data.ptrvalue;
6223       if (StringHasNoText (str)) continue;
6224       ValNodeCopyStrEx (&blk.head, &blk.tail, 0, str);
6225       break;
6226     }
6227   }
6228 
6229   if (useJournal) {
6230     if (cjp != NULL) {
6231       for (vnp = cjp->title; vnp != NULL; vnp = vnp->next) {
6232         if (vnp->choice != Cit_title_jta && vnp->choice != Cit_title_iso_jta) continue;
6233         str = (CharPtr) vnp->data.ptrvalue;
6234         if (StringHasNoText (str)) continue;
6235         ValNodeCopyStrEx (&blk.head, &blk.tail, 0, str);
6236         break;
6237       }
6238     }
6239   }
6240 
6241   if (useImprint) {
6242     if (imp != NULL) {
6243       dp = imp->date;
6244       if (dp != NULL) {
6245         if (dp->data [0] == 1) {
6246           if (dp->data [1] != 0) {
6247             sprintf (year, "%ld", (long) (1900 + dp->data [1]));
6248             ValNodeCopyStrEx (&blk.head, &blk.tail, 0, year);
6249           }
6250         }
6251       }
6252       if (StringDoesHaveText (imp->volume)) {
6253         ValNodeCopyStrEx (&blk.head, &blk.tail, 0, imp->volume);
6254       }
6255       if (StringDoesHaveText (imp->issue)) {
6256         ValNodeCopyStrEx (&blk.head, &blk.tail, 0, imp->issue);
6257       }
6258       if (StringDoesHaveText (imp->pages)) {
6259         ValNodeCopyStrEx (&blk.head, &blk.tail, 0, imp->pages);
6260       }
6261     }
6262   }
6263 
6264   if (blk.head == NULL) return NULL;
6265 
6266   query = ValNodeMergeStrsEx (blk.head, "+");
6267   ValNodeFreeData (blk.head);
6268 
6269   return query;
6270 }
6271 
PerformArticleQuery(CharPtr query,CharPtr journalcheck,Int4Ptr numhits)6272 static Int4 PerformArticleQuery (CharPtr query, CharPtr journalcheck, Int4Ptr numhits)
6273 
6274 {
6275   XmlObjPtr        attr, tmp, xop;
6276   CitArtPtr        cap;
6277   CitJourPtr       cjp;
6278   ValNodePtr       head;
6279   CharPtr          idstr;
6280   CharPtr          jour;
6281   MedlineEntryPtr  mep;
6282   PubmedEntryPtr   pmep;
6283   Int4             pmid = 0;
6284   Int4             pmval;
6285   CharPtr          score;
6286   CharPtr          str;
6287   ValNodePtr       tail;
6288   long int         val;
6289   ValNodePtr       vnp;
6290   ValNodePtr       vnt;
6291   Boolean          debug_mode = FALSE;
6292 
6293   if (getenv ("DEBUG_LOOKUP_JOURNAL_EUTILS") != NULL) {
6294     debug_mode = TRUE;
6295   }
6296 
6297   if (numhits != NULL) {
6298     *numhits = 0;
6299   }
6300   if (StringHasNoText (query)) return 0;
6301 
6302   /*
6303   curl -s "http://intranet.ncbi.nlm.nih.gov/projects/hydra/hydra_search.cgi?search=pubmed_search_citation_top_20.1&query=..." | xlint
6304   */
6305 
6306   str = QUERY_UrlSynchronousQuery ("www.ncbi.nlm.nih.gov", 0,
6307                                    "/projects/hydra/hydra_search.cgi",
6308                                    "search=pubmed_search_citation_top_20.1&query=",
6309                                    /* "search=pmc_citation.1&query=", */
6310                                    query, NULL, NULL);
6311   if (str == NULL) return 0;
6312 
6313   xop = ParseXmlString (str);
6314   if (xop != NULL) {
6315 
6316     if (debug_mode) {
6317       LaunchXmlViewer (xop, "Citation match results");
6318     }
6319 
6320     head = NULL;
6321     tail = NULL;
6322 
6323     for (tmp = xop; tmp != NULL; tmp = tmp->successor) {
6324       if (XmlPathSuffixIs (tmp, "/IdList/Id")) {
6325         if (StringHasNoText (tmp->contents)) continue;
6326         /*
6327         score = NULL;
6328         */
6329         for (attr = tmp->attributes; attr != NULL; attr = attr->next) {
6330           if (StringICmp (attr->name, "score") != 0) continue;
6331           score = attr->contents;
6332           if (StringHasNoText (score)) continue;
6333           if (StringChr (score, '-') != NULL) continue;
6334           if (StringNCmp (score, "1", 1) == 0 || StringNCmp (score, "0.9", 3) == 0 || StringNCmp (score, "0.8", 3) == 0) {
6335             ValNodeCopyStrEx (&head, &tail, 0, tmp->contents);
6336           }
6337         }
6338       }
6339     }
6340 
6341     if (head != NULL) {
6342       if (numhits != NULL) {
6343         *numhits = ValNodeLen (head);
6344       }
6345       for (vnp = head; vnp != NULL && pmid == 0; vnp = vnp->next) {
6346         idstr = (CharPtr) vnp->data.ptrvalue;
6347         if (StringDoesHaveText (idstr)) {
6348           if (sscanf (idstr, "%ld", &val) == 1) {
6349             pmval = (Int4) val;
6350             if (pmval == 0) continue;
6351             pmep = PubMedSynchronousQuery (pmval);
6352             if (pmep != NULL) {
6353               mep = (MedlineEntryPtr) pmep->medent;
6354               if (mep != NULL) {
6355                 cap = mep->cit;
6356                 if (cap != NULL && cap->from == 1) {
6357                   cjp = (CitJourPtr) cap->fromptr;
6358                   if (cjp != NULL) {
6359                     for (vnt = cjp->title; vnt != NULL; vnt = vnt->next) {
6360                       if (vnt->choice != Cit_title_jta && vnt->choice != Cit_title_iso_jta) continue;
6361                       jour = (CharPtr) vnt->data.ptrvalue;
6362                       if (StringHasNoText (jour)) continue;
6363                       if (journalcheck == NULL || StringICmp (jour, journalcheck) == 0) {
6364                         pmid = pmval;
6365                       }
6366                     }
6367                   }
6368                 }
6369               }
6370               pmep = PubmedEntryFree (pmep);
6371             }
6372           }
6373         }
6374       }
6375       ValNodeFreeData (head);
6376     }
6377     FreeXmlObject (xop);
6378   }
6379 
6380   MemFree (str);
6381 
6382   return pmid;
6383 }
6384 
ConstructAndPerformQuery(ValNodePtr oldpep,Boolean useAuthors,Boolean useTitle,Boolean useJournal,Boolean useImprint,Int4Ptr numhits)6385 static Int4 ConstructAndPerformQuery (ValNodePtr oldpep, Boolean useAuthors, Boolean useTitle,
6386                                       Boolean useJournal, Boolean useImprint, Int4Ptr numhits)
6387 
6388 {
6389   Char     ch;
6390   CharPtr  journalcheck;
6391   Int4     pmid;
6392   CharPtr  ptr;
6393   CharPtr  query;
6394 
6395   if (oldpep == NULL) return 0;
6396 
6397   query = ConstructArticleQuery (oldpep, useAuthors, useTitle, useJournal, useImprint);
6398   if (query == NULL) return 0;
6399 
6400   /* remove ampersands in query string */
6401   ptr = query;
6402   ch = *ptr;
6403   while (ch != '\0') {
6404     if (ch == '&') {
6405       *ptr = ' ';
6406     }
6407     ptr++;
6408     ch = *ptr;
6409   }
6410 
6411   journalcheck = ConstructArticleQuery (oldpep, FALSE, FALSE, TRUE, FALSE);
6412 
6413   pmid = PerformArticleQuery (query, journalcheck, numhits);
6414 
6415   MemFree (query);
6416   MemFree (journalcheck);
6417 
6418   return pmid;
6419 }
6420 
LookupArticleByPmid(Int4 pmid,BoolPtr success)6421 static ValNodePtr LookupArticleByPmid (Int4 pmid, BoolPtr success)
6422 
6423 {
6424   CitArtPtr        cap;
6425   ArticleIdPtr     ids;
6426   MedlineEntryPtr  mep;
6427   PubmedEntryPtr   pep;
6428   ValNodePtr       pub = NULL;
6429 
6430   if (pmid > 0) {
6431     pep = GetPubMedForUid (pmid);
6432     if (pep != NULL) {
6433       mep = (MedlineEntryPtr) pep->medent;
6434       if (mep != NULL && mep->cit != NULL) {
6435         cap = AsnIoMemCopy ((Pointer) mep->cit,
6436                             (AsnReadFunc) CitArtAsnRead,
6437                             (AsnWriteFunc) CitArtAsnWrite);
6438         if (cap != NULL) {
6439           ChangeCitArtMLAuthorsToSTD (cap);
6440           for (ids = cap->ids; ids != NULL; ids = ids->next) {
6441             if (ids->choice != ARTICLEID_PUBMED) continue;
6442             if (ids->data.intvalue != pmid) {
6443               Message (MSG_POSTERR, "CitArt ID %ld does not match PMID %ld",
6444                        (long) ids->data.intvalue, (long) pmid);
6445             }
6446           }
6447           pub = ValNodeAddPointer (NULL, PUB_Article, (Pointer) cap);
6448           ValNodeAddInt (&pub, PUB_PMid, pmid);
6449           if (success != NULL) {
6450             *success = TRUE;
6451           }
6452         }
6453       }
6454       PubmedEntryFree (pep);
6455     }
6456   }
6457 
6458   return pub;
6459 }
6460 
LookupAnArticleFuncViaEUtils(ValNodePtr oldpep,BoolPtr success)6461 static ValNodePtr LookupAnArticleFuncViaEUtils (ValNodePtr oldpep, BoolPtr success)
6462 
6463 {
6464   CitArtPtr      cap = NULL;
6465   Int4           numhits;
6466   Int4           pmid = 0;
6467   ValNodePtr     pub = NULL;
6468   ValNodePtr     vnp;
6469 #ifdef OS_UNIX
6470   CharPtr        str;
6471 #endif
6472 
6473   if (success != NULL) {
6474     *success = FALSE;
6475   }
6476   if (oldpep == NULL) return NULL;
6477 
6478 #ifdef OS_UNIX
6479   if (! log_mla_set) {
6480     str = (CharPtr) getenv ("LOG_MLA_ASN");
6481     if (StringDoesHaveText (str)) {
6482       if (StringICmp (str, "TRUE") == 0) {
6483         log_mla_asn = TRUE;
6484       }
6485     }
6486     log_mla_set = TRUE;
6487   }
6488 #endif
6489 
6490   for (vnp = oldpep; vnp != NULL; vnp = vnp->next) {
6491     if (vnp->choice == PUB_Article) {
6492       cap = (CitArtPtr) vnp->data.ptrvalue;
6493     } else if (vnp->choice == PUB_PMid) {
6494       pmid = (Int4) vnp->data.intvalue;
6495     }
6496   }
6497 
6498   if (cap != NULL) {
6499     pmid = ConstructAndPerformQuery (oldpep, TRUE, TRUE, TRUE, TRUE, &numhits);
6500   }
6501 
6502   if (pmid > 0) {
6503     pub = LookupArticleByPmid (pmid, success);
6504   }
6505 
6506   return pub;
6507 }
6508 
LookupAnArticleFuncNew(ValNodePtr oldpep,BoolPtr success)6509 static ValNodePtr LookupAnArticleFuncNew (ValNodePtr oldpep, BoolPtr success)
6510 
6511 {
6512   CitArtPtr      cap = NULL;
6513   MlaBackPtr     mbp;
6514   MlaRequestPtr  mrp;
6515   Int4           pmid = 0;
6516   ValNodePtr     pub = NULL;
6517   ValNodePtr     vnp;
6518 #ifdef OS_UNIX
6519   CharPtr        str;
6520 #endif
6521 
6522   if (success != NULL) {
6523     *success = FALSE;
6524   }
6525   if (oldpep == NULL) return NULL;
6526 
6527 #ifdef OS_UNIX
6528   if (! log_mla_set) {
6529     str = (CharPtr) getenv ("LOG_MLA_ASN");
6530     if (StringDoesHaveText (str)) {
6531       if (StringICmp (str, "TRUE") == 0) {
6532         log_mla_asn = TRUE;
6533       }
6534     }
6535     log_mla_set = TRUE;
6536   }
6537 #endif
6538 
6539   for (vnp = oldpep; vnp != NULL; vnp = vnp->next) {
6540     if (vnp->choice == PUB_Article) {
6541       cap = (CitArtPtr) vnp->data.ptrvalue;
6542     } else if (vnp->choice == PUB_PMid) {
6543       pmid = (Int4) vnp->data.intvalue;
6544     }
6545   }
6546 
6547   if (cap != NULL) {
6548     mrp = Mla2CreateCitArtMatchRequest (cap);
6549     if (mrp != NULL) {
6550       if (log_mla_asn) {
6551         LaunchAsnTextViewer ((Pointer) mrp, (AsnWriteFunc) MlaRequestAsnWrite, "citart match request");
6552       }
6553       mbp = Mla2SynchronousQuery (mrp);
6554       mrp = MlaRequestFree (mrp);
6555       if (mbp != NULL) {
6556         if (log_mla_asn) {
6557           LaunchAsnTextViewer ((Pointer) mbp, (AsnWriteFunc) MlaBackAsnWrite, "citart match result");
6558         }
6559         pmid = Mla2ExtractCitMatchReply (mbp);
6560         mbp = MlaBackFree (mbp);
6561       }
6562     }
6563   }
6564 
6565   if (pmid > 0) {
6566     pub = LookupArticleByPmid (pmid, success);
6567   }
6568 
6569   return pub;
6570 }
6571 
LookupAnArticleFuncHybrid(ValNodePtr oldpep,BoolPtr success)6572 static ValNodePtr LookupAnArticleFuncHybrid (ValNodePtr oldpep, BoolPtr success)
6573 
6574 {
6575   ValNodePtr  pub = NULL;
6576 
6577   if (indexerVersion) {
6578     pub = LookupAnArticleFuncViaEUtils (oldpep, success);
6579     if (pub != NULL) return pub;
6580   }
6581 
6582   pub = LookupAnArticleFuncNew (oldpep, success);
6583 
6584   if (indexerVersion) {
6585     if (pub != NULL) {
6586       Message (MSG_POST, "LookupAnArticleFuncViaEUtils failed, LookupAnArticleFuncNew succeeded - contact MD and JM");
6587     }
6588   }
6589 
6590   return pub;
6591 }
6592 
6593 
GlobalArticleLookupPubdescCallback(PubdescPtr pdp,Pointer userdata)6594 static void GlobalArticleLookupPubdescCallback(PubdescPtr pdp, Pointer userdata)
6595 {
6596   ValNodePtr new_pub, vnp, tmp_pub;
6597   Boolean    success = FALSE;
6598   Int4       pmid = 0;
6599 
6600   if (pdp == NULL) {
6601     return;
6602   }
6603 
6604   for (vnp = pdp->pub; vnp != NULL; vnp = vnp->next) {
6605     if (vnp->choice == PUB_PMid) {
6606       pmid = (Int4) vnp->data.intvalue;
6607     }
6608   }
6609   if (pmid > 0) {
6610     tmp_pub = ValNodeNew (NULL);
6611     tmp_pub->choice = PUB_PMid;
6612     tmp_pub->data.intvalue = pmid;
6613     new_pub = LookupAnArticleFuncHybrid(tmp_pub, &success);
6614     tmp_pub = PubEquivFree(tmp_pub);
6615     if (success && new_pub != NULL) {
6616       pdp->pub = PubEquivFree (pdp->pub);
6617       pdp->pub = new_pub;
6618     }
6619   }
6620 }
6621 
6622 
GlobalArticleLookupDescCallback(SeqDescPtr sdp,Pointer userdata)6623 static void GlobalArticleLookupDescCallback(SeqDescPtr sdp, Pointer userdata)
6624 {
6625   if (sdp != NULL && sdp->choice == Seq_descr_pub) {
6626     GlobalArticleLookupPubdescCallback(sdp->data.ptrvalue, userdata);
6627   }
6628 }
6629 
6630 
GlobalArticleLookupFeatCallback(SeqFeatPtr sfp,Pointer userdata)6631 static void GlobalArticleLookupFeatCallback(SeqFeatPtr sfp, Pointer userdata)
6632 {
6633   if (sfp != NULL && sfp->data.choice == SEQFEAT_PUB) {
6634     GlobalArticleLookupPubdescCallback(sfp->data.value.ptrvalue, userdata);
6635   }
6636 }
6637 
6638 
GlobalArticleLookup(SeqEntryPtr sep)6639 static void GlobalArticleLookup (SeqEntryPtr sep)
6640 {
6641   Uint2 entityID;
6642 
6643   entityID = ObjMgrGetEntityIDForChoice (sep);
6644   VisitDescriptorsInSep(sep, NULL, GlobalArticleLookupDescCallback);
6645   VisitFeaturesInSep(sep, NULL, GlobalArticleLookupFeatCallback);
6646 
6647   ObjMgrSetDirtyFlag (entityID, TRUE);
6648   ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
6649 }
6650 
6651 
GLobalArticleLookupMenuItem(IteM i)6652 NLM_EXTERN void GLobalArticleLookupMenuItem (IteM i)
6653 {
6654   BaseFormPtr  bfp;
6655   SeqEntryPtr  sep;
6656 
6657 #ifdef WIN_MAC
6658   bfp = currentFormDataPtr;
6659 #else
6660   bfp = GetObjectExtra (i);
6661 #endif
6662   if (bfp == NULL) return;
6663 
6664   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6665   GlobalArticleLookup(sep);
6666 
6667   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6668   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
6669 }
6670 
6671 
LookupAnArticleFunc(ValNodePtr oldpep,BoolPtr success)6672 static ValNodePtr LookupAnArticleFunc (ValNodePtr oldpep, BoolPtr success)
6673 
6674 {
6675   FindPubOption  fpo;
6676   MonitorPtr     mon;
6677   Int4           muid = 0;
6678   ValNodePtr     pep;
6679   Int4           pmid = 0;
6680   ValNodePtr     pub;
6681   ValNodePtr     vnp;
6682 #ifdef OS_UNIX
6683   AsnIoPtr       aip;
6684   CharPtr        str;
6685 #endif
6686 
6687   pub = NULL;
6688   if (oldpep != NULL) {
6689     WatchCursor ();
6690     mon = MonitorStrNewEx ("Lookup Article", 40, FALSE);
6691     MonitorStrValue (mon, "Connecting to MedArch");
6692     Update ();
6693     if (MedArchInit ()) {
6694 #ifdef OS_UNIX
6695       if (! debug_fix_pub_set) {
6696         str = (CharPtr) getenv ("DEBUG_FIX_PUB_EQUIV");
6697         if (StringDoesHaveText (str)) {
6698           if (StringICmp (str, "TRUE") == 0) {
6699             debug_fix_pub_equiv = TRUE;
6700           }
6701         }
6702         debug_fix_pub_set = TRUE;
6703       }
6704 #endif
6705       pep = AsnIoMemCopy (oldpep, (AsnReadFunc) PubEquivAsnRead,
6706                           (AsnWriteFunc) PubEquivAsnWrite);
6707       fpo.always_look = TRUE;
6708       fpo.replace_cit = TRUE;
6709       fpo.lookups_attempted = 0;
6710       fpo.lookups_succeeded = 0;
6711       fpo.fetches_attempted = 0;
6712       fpo.fetches_succeeded = 0;
6713       MonitorStrValue (mon, "Performing Lookup");
6714       Update ();
6715 #ifdef OS_UNIX
6716       if (debug_fix_pub_equiv) {
6717         if (pep != NULL) {
6718           aip = AsnIoOpen ("origpubequiv.txt", "w");
6719           if (aip != NULL) {
6720             PubEquivAsnWrite (pep, aip, NULL);
6721             AsnIoClose (aip);
6722           }
6723         }
6724       }
6725 #endif
6726       pub = FixPubEquiv (pep, &fpo);
6727       if (fpo.fetches_succeeded && success != NULL) {
6728         *success = TRUE;
6729       }
6730 #ifdef OS_UNIX
6731       if (debug_fix_pub_equiv) {
6732         if (pub != NULL) {
6733           aip = AsnIoOpen ("fixpubequiv.txt", "w");
6734           if (aip != NULL) {
6735             PubEquivAsnWrite (pub, aip, NULL);
6736             AsnIoClose (aip);
6737           }
6738         }
6739       }
6740 #endif
6741       if (! fpo.fetches_succeeded) {
6742         ErrShow ();
6743         Update ();
6744       } else {
6745         for (vnp = pub; vnp != NULL; vnp = vnp->next) {
6746           if (vnp->choice == PUB_Muid) {
6747             muid = vnp->data.intvalue;
6748           } else if (vnp->choice == PUB_PMid) {
6749             pmid = vnp->data.intvalue;
6750           }
6751         }
6752         if (muid != 0 && pmid == 0) {
6753           pmid = MedArchMu2Pm (muid);
6754           if (pmid != 0) {
6755             ValNodeAddInt (&pub, PUB_PMid, pmid);
6756           }
6757         } else if (pmid != 0 && muid == 0) {
6758           muid = MedArchPm2Mu (pmid);
6759           if (muid != 0) {
6760             ValNodeAddInt (&pub, PUB_Muid, muid);
6761           }
6762         }
6763       }
6764       MonitorStrValue (mon, "Closing MedArch");
6765       Update ();
6766       MedArchFini ();
6767       MonitorFree (mon);
6768       ArrowCursor ();
6769       Update ();
6770     } else {
6771       ArrowCursor ();
6772       Message (MSG_ERROR, "Unable to connect to MedArch");
6773       MonitorFree (mon);
6774       Update ();
6775     }
6776   }
6777   return pub;
6778 }
6779 
6780 
LookupJournalEUtilsFunc(CharPtr title,size_t maxsize,Int1Ptr jtaType,ValNodePtr PNTR all_titlesP)6781 NLM_EXTERN Boolean LookupJournalEUtilsFunc (CharPtr title, size_t maxsize, Int1Ptr jtaType, ValNodePtr PNTR all_titlesP)
6782 
6783 {
6784   CharPtr       count = NULL, end, jids = NULL, iso = NULL, issn = NULL, name = NULL, str = NULL;
6785   Boolean       debug_mode = FALSE, is_issn = FALSE;
6786   ValNodePtr    head = NULL, shead, stail, tail = NULL;
6787   size_t        len;
6788   XmlObjPtr     nxt, sub, tmp, xop;
6789 
6790   if (getenv ("DEBUG_LOOKUP_JOURNAL_EUTILS") != NULL) {
6791     debug_mode = TRUE;
6792   }
6793 
6794   if (all_titlesP != NULL) {
6795     *all_titlesP = NULL;
6796   }
6797   if (jtaType != NULL) {
6798     *jtaType = 0;
6799   }
6800   if (StringHasNoText (title)) return FALSE;
6801 
6802   ConvertToTermListForm (title);
6803 
6804   if (LooksLikeISSN (title)) {
6805     is_issn = TRUE;
6806     if (title [4] == '+' || title [4] == ' ') {
6807       title [4] = '-';
6808     }
6809     if (title [8] == 'x') {
6810       title [8] = 'X';
6811     }
6812     str = QUERY_UrlSynchronousQuery ("eutils.ncbi.nlm.nih.gov", 0,
6813                                      "/entrez/eutils/esearch.fcgi",
6814                                      "db=nlmcatalog&retmax=200&term=",
6815                                      title, "%5Bissn%5D", NULL);
6816   }
6817 
6818   /*
6819   curl -s "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=nlmcatalog&retmax=200&term=J+Bacteriol%5Bmulti%5D+AND+ncbijournals%5Bsb%5D" | xlint
6820   */
6821 
6822   if (str == NULL) {
6823     str = QUERY_UrlSynchronousQuery ("eutils.ncbi.nlm.nih.gov", 0,
6824                                      "/entrez/eutils/esearch.fcgi",
6825                                      "db=nlmcatalog&retmax=200&term=",
6826                                      title, "%5Bmulti%5D+AND+ncbijournals%5Bsb%5D", NULL);
6827   }
6828 
6829   if (str == NULL) return FALSE;
6830 
6831   xop = ParseXmlString (str);
6832   MemFree (str);
6833   if (xop == NULL) return FALSE;
6834 
6835   if (debug_mode) {
6836     if (is_issn) {
6837       LaunchXmlViewer (xop, "ISSN Query");
6838     } else {
6839       LaunchXmlViewer (xop, "Multi Query");
6840     }
6841   }
6842 
6843   head = NULL;
6844   tail = NULL;
6845   count = NULL;
6846 
6847   for (tmp = xop; tmp != NULL; tmp = tmp->successor) {
6848     if (XmlPathSuffixIs (tmp, "/Id")) {
6849       ValNodeCopyStrEx (&head, &tail, 0, tmp->contents);
6850     } else if (XmlPathSuffixIs (tmp, "/eSearchResult/Count")) {
6851       count = StringSave (tmp->contents);
6852     }
6853   }
6854 
6855   FreeXmlObject (xop);
6856 
6857   if (StringCmp (count, "0") == 0 || head == NULL) {
6858     /*
6859     Message (MSG_POST, "[multi] failed");
6860     */
6861 
6862     count = MemFree (count);
6863     ValNodeFreeData (head);
6864 
6865     /*
6866     if [multi] failed, try [jour]
6867     Microbiology (Reading, Engl.)
6868     is indexed in [multi] as
6869     microbiology reading, england
6870     and in [jour] as
6871     microbiology reading, engl
6872     microbiology reading, england
6873     */
6874 
6875     str = QUERY_UrlSynchronousQuery ("eutils.ncbi.nlm.nih.gov", 0,
6876                                      "/entrez/eutils/esearch.fcgi",
6877                                      "db=nlmcatalog&retmax=200&term=",
6878                                      title, "%5Bjour%5D", NULL);
6879     if (str == NULL) return FALSE;
6880 
6881     xop = ParseXmlString (str);
6882     MemFree (str);
6883     if (xop == NULL) return FALSE;
6884 
6885     head = NULL;
6886     tail = NULL;
6887     count = NULL;
6888 
6889     for (tmp = xop; tmp != NULL; tmp = tmp->successor) {
6890       if (XmlPathSuffixIs (tmp, "/Id")) {
6891         ValNodeCopyStrEx (&head, &tail, 0, tmp->contents);
6892       } else if (XmlPathSuffixIs (tmp, "/eSearchResult/Count")) {
6893         count = StringSave (tmp->contents);
6894       }
6895     }
6896 
6897     if (debug_mode) {
6898       LaunchXmlViewer (xop, "Jour Query");
6899     }
6900 
6901     FreeXmlObject (xop);
6902   }
6903 
6904   MemFree (count);
6905 
6906   if (head != NULL) {
6907     jids = ValNodeMergeStrsEx (head, ",");
6908     ValNodeFreeData (head);
6909   }
6910 
6911   if (jids == NULL) return FALSE;
6912 
6913   /*
6914   curl -s http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?"db=nlmcatalog&version=2.0&id=101232377" | grep '<CurrentIndexingStatus>' | perl -nle 'print /(?<=<CurrentIndexingStatus>).*?(?=<\/CurrentIndexingStatus>)/g'
6915   */
6916 
6917   str = QUERY_UrlSynchronousQuery ("eutils.ncbi.nlm.nih.gov", 0,
6918                                    "/entrez/eutils/esummary.fcgi",
6919                                    "db=nlmcatalog&retmax=200&version=2.0&id=",
6920                                    jids, NULL, NULL);
6921   MemFree (jids);
6922   if (str == NULL) return FALSE;
6923 
6924   xop = ParseXmlString (str);
6925   MemFree (str);
6926   if (xop == NULL) return FALSE;
6927 
6928   if (debug_mode) {
6929     LaunchXmlViewer (xop, "DocumentSummary");
6930   }
6931 
6932   head = NULL;
6933   tail = NULL;
6934 
6935   for (tmp = xop; tmp != NULL; tmp = nxt) {
6936     nxt = tmp->successor;
6937     if (XmlPathSuffixIs (tmp, "/DocumentSummary")) {
6938       iso = NULL;
6939       issn = NULL;
6940       name = NULL;
6941       shead = NULL;
6942       stail = NULL;
6943       for (sub = tmp->successor; sub != NULL && sub->level > tmp->level; sub = sub->successor) {
6944         if (XmlPathSuffixIs (sub, "/ISSNInfo/issn")) {
6945           ValNodeCopyStrEx (&shead, &stail, 0, sub->contents);
6946         } else if (XmlPathSuffixIs (sub, "/ISOAbbreviation")) {
6947           iso = StringSave (sub->contents);
6948         } else if (XmlPathSuffixIs (sub, "/Title")) {
6949           name = StringSave (sub->contents);
6950         }
6951       }
6952       if (shead != NULL) {
6953         issn = (CharPtr) shead->data.ptrvalue;
6954         if (StringHasNoText (issn)) {
6955           issn = NULL;
6956         }
6957       }
6958       len = StringLen (iso) + StringLen (name) + StringLen (issn) + 10;
6959       str = (CharPtr) MemNew (sizeof (Char) * len);
6960       if (str != NULL) {
6961         if (iso == NULL) {
6962           /* must have ISO JTA - skip */
6963         } else if (name != NULL && issn != NULL) {
6964           sprintf (str, "%s||(%s:%s)", iso, name, issn);
6965         } else if (name != NULL) {
6966           sprintf (str, "%s||(%s)", iso, name);
6967        } else if (issn != NULL) {
6968           sprintf (str, "%s||(%s)", iso, issn);
6969         } else {
6970           sprintf (str, "%s", iso);
6971         }
6972       }
6973       MemFree (iso);
6974       MemFree (name);
6975       ValNodeFreeData (shead);
6976       if (StringDoesHaveText (str)) {
6977         ValNodeCopyStrEx (&head, &tail, Cit_title_iso_jta, str);
6978       }
6979       MemFree (str);
6980       nxt = sub;
6981     }
6982   }
6983 
6984   FreeXmlObject (xop);
6985 
6986   if (head == NULL) return FALSE;
6987 
6988   str = (CharPtr) head->data.ptrvalue;
6989   StringNCpy_0 (title, str, maxsize);
6990   end = StringSearch (title, "||");
6991   if (end != NULL) {
6992     *end = 0;
6993   }
6994   if (jtaType != NULL) {
6995     *jtaType = Cit_title_iso_jta;
6996   }
6997   if (all_titlesP == NULL) {
6998     ValNodeFreeData (head);
6999   } else {
7000     *all_titlesP = head;
7001     if (ValNodeLen (head) == 1) {
7002       str = (CharPtr) head->data.ptrvalue;
7003       end = StringSearch (str, "||");
7004       if (end != NULL) {
7005         *end = 0;
7006       }
7007     }
7008   }
7009 
7010   return TRUE;
7011 }
7012 
LookupJournalFuncViaEUtils(CharPtr title,size_t maxsize,Int1Ptr jtaType,ValNodePtr PNTR all_titlesP)7013 static Boolean LookupJournalFuncViaEUtils (CharPtr title, size_t maxsize, Int1Ptr jtaType, ValNodePtr PNTR all_titlesP)
7014 
7015 {
7016   Boolean  rsult;
7017 
7018   WatchCursor ();
7019   Update ();
7020 
7021   rsult = LookupJournalEUtilsFunc (title, maxsize, jtaType, all_titlesP);
7022 
7023   ArrowCursor ();
7024   Update ();
7025 
7026   return rsult;
7027 }
7028 
7029 #define USE_LOOKUPJOURNALFUNCNEW 0
7030 
7031 #if USE_LOOKUPJOURNALFUNCNEW
HasMoreThanOneISOJTA(TitleMsgPtr titles)7032 static Boolean HasMoreThanOneISOJTA (TitleMsgPtr titles)
7033 {
7034   TitleMsgPtr tmp;
7035   ValNodePtr  ttl;
7036   Int4 num_found = 0;
7037 
7038   for (tmp = titles; tmp != NULL; tmp = tmp->next) {
7039     for (ttl = tmp->title; ttl != NULL; ttl = ttl->next) {
7040       if (ttl->choice == Cit_title_iso_jta) {
7041         if (num_found > 0) {
7042           return TRUE;
7043         }
7044         num_found++;
7045         break;
7046       }
7047     }
7048   }
7049   return FALSE;
7050 }
7051 
7052 
GetExtendedDescription(TitleMsgPtr tmp)7053 static CharPtr GetExtendedDescription (TitleMsgPtr tmp)
7054 {
7055   CharPtr iso_jta = NULL, name = NULL, issn = NULL, extended = NULL;
7056   ValNodePtr ttl;
7057 
7058   if (tmp == NULL) {
7059     return NULL;
7060   }
7061 
7062   for (ttl = tmp->title; ttl != NULL; ttl = ttl->next) {
7063     if (ttl->choice == Cit_title_iso_jta) {
7064       iso_jta = ttl->data.ptrvalue;
7065     } else if (ttl->choice == Cit_title_name) {
7066       name = ttl->data.ptrvalue;
7067     } else if (ttl->choice == Cit_title_issn) {
7068       issn = ttl->data.ptrvalue;
7069     }
7070   }
7071   if (iso_jta == NULL) {
7072     return NULL;
7073   }
7074   if (name == NULL && issn == NULL) {
7075     extended = StringSave (iso_jta);
7076   } else if (name == NULL) {
7077     extended = (CharPtr) MemNew (sizeof (Char) * (StringLen (iso_jta) + StringLen (issn) + 5));
7078     sprintf (extended, "%s||(%s)", iso_jta, issn);
7079   } else if (issn == NULL) {
7080     extended = (CharPtr) MemNew (sizeof (Char) * (StringLen (iso_jta) + StringLen (name) + 5));
7081     sprintf (extended, "%s||(%s)", iso_jta, name);
7082   } else {
7083     extended = (CharPtr) MemNew (sizeof (Char) * (StringLen (iso_jta) + StringLen (name) + StringLen (issn) + 6));
7084     sprintf (extended, "%s||(%s:%s)", iso_jta, name, issn);
7085   }
7086   return extended;
7087 }
7088 
7089 
LookupJournalFuncNew(CharPtr title,size_t maxsize,Int1Ptr jtaType,ValNodePtr PNTR all_titlesP)7090 static Boolean LookupJournalFuncNew (CharPtr title, size_t maxsize, Int1Ptr jtaType, ValNodePtr PNTR all_titlesP)
7091 
7092 {
7093   ValNodePtr       first = NULL;
7094   ValNodePtr       last = NULL;
7095   MlaBackPtr       mbp;
7096   MlaRequestPtr    mrp;
7097   CharPtr          str, end;
7098   TitleMsgListPtr  tlp;
7099   TitleMsgPtr      tmp;
7100   ValNodePtr       ttl;
7101   ValNodePtr       vnp;
7102 
7103   if (all_titlesP != NULL) {
7104     *all_titlesP = NULL;
7105   }
7106   if (jtaType != NULL) {
7107     *jtaType = 0;
7108   }
7109   if (StringHasNoText (title)) return FALSE;
7110 
7111 #ifdef OS_UNIX
7112   if (! log_mla_set) {
7113     str = (CharPtr) getenv ("LOG_MLA_ASN");
7114     if (StringDoesHaveText (str)) {
7115       if (StringICmp (str, "TRUE") == 0) {
7116         log_mla_asn = TRUE;
7117       }
7118     }
7119     log_mla_set = TRUE;
7120   }
7121 #endif
7122 
7123   WatchCursor ();
7124   Update ();
7125 
7126   mrp = Mla2CreateJournalTitleRequest (title);
7127   if (mrp != NULL) {
7128   if (log_mla_asn) {
7129     LaunchAsnTextViewer ((Pointer) mrp, (AsnWriteFunc) MlaRequestAsnWrite, "lookup journal request");
7130   }
7131     mbp = Mla2SynchronousQuery (mrp);
7132     mrp = MlaRequestFree (mrp);
7133     if (mbp != NULL) {
7134       if (log_mla_asn) {
7135         LaunchAsnTextViewer ((Pointer) mbp, (AsnWriteFunc) MlaBackAsnWrite, "lookup journal result");
7136       }
7137       tlp = Mla2ExtractJournalTitleReply (mbp);
7138       if (tlp != NULL) {
7139         if (HasMoreThanOneISOJTA (tlp->titles)) {
7140           for (tmp = tlp->titles; tmp != NULL; tmp = tmp->next) {
7141             str = GetExtendedDescription (tmp);
7142             if (str != NULL) {
7143               ValNodeAddPointer (&first, 0, str);
7144             }
7145           }
7146         } else {
7147           for (tmp = tlp->titles; tmp != NULL; tmp = tmp->next) {
7148             for (ttl = tmp->title; ttl != NULL; ttl = ttl->next) {
7149               if (ttl->choice != Cit_title_iso_jta) continue;
7150               str = (CharPtr) ttl->data.ptrvalue;
7151               if (StringHasNoText (str)) continue;
7152               vnp = ValNodeCopyStr (&last, ttl->choice, str);
7153               if (first == NULL) {
7154                 first = vnp;
7155               }
7156               last = vnp;
7157             }
7158           }
7159         }
7160         if (first != NULL) {
7161           str = (CharPtr) first->data.ptrvalue;
7162           StringNCpy_0 (title, str, maxsize);
7163           end = StringSearch (title, "||");
7164           if (end != NULL) {
7165             *end = 0;
7166           }
7167           if (jtaType != NULL) {
7168             *jtaType = Cit_title_iso_jta;
7169           }
7170         }
7171         if (all_titlesP == NULL) {
7172           first = ValNodeFreeData (first);
7173         } else {
7174           *all_titlesP = first;
7175         }
7176         tlp = TitleMsgListFree (tlp);
7177       }
7178       mbp = MlaBackFree (mbp);
7179     }
7180   }
7181 
7182   ArrowCursor ();
7183   Update ();
7184 
7185   return TRUE;
7186 }
7187 #endif
7188 
LookupJournalFunc(CharPtr title,size_t maxsize,Int1Ptr jtaType,ValNodePtr PNTR all_titlesP)7189 static Boolean LookupJournalFunc (CharPtr title, size_t maxsize, Int1Ptr jtaType, ValNodePtr PNTR all_titlesP)
7190 
7191 {
7192   ValNodePtr  first = NULL;
7193   Int4        i;
7194   ValNodePtr  last = NULL;
7195   MonitorPtr  mon;
7196   Int4        num;
7197   Char        str [256];
7198   CharPtr     titles [20];
7199   Int1        types [20];
7200   ValNodePtr  vnp;
7201 
7202   WatchCursor ();
7203   mon = MonitorStrNewEx ("Lookup Journal", 40, FALSE);
7204   MonitorStrValue (mon, "Connecting to MedArch");
7205   Update ();
7206   if (MedArchInit ()) {
7207     StringNCpy_0 (str, title, sizeof (str));
7208     if (str [0] != '\0') {
7209       MonitorStrValue (mon, "Performing Lookup");
7210       Update ();
7211       num = MedArchGetTitles (titles, types, str, (Int1) Cit_title_jta,
7212                               Cit_title_iso_jta, 20);
7213       if (num > 0 && all_titlesP != NULL) {
7214         for (i = 0; i < num; i++) {
7215           vnp = ValNodeCopyStr (&last, types [i], titles [i]);
7216           if (first == NULL) {
7217             first = vnp;
7218           }
7219           last = vnp;
7220         }
7221         *all_titlesP = first;
7222       }
7223       if (num > 0 && types [0] == Cit_title_iso_jta) {
7224         StringNCpy_0 (title, titles [0], maxsize);
7225         if (jtaType != NULL) {
7226           *jtaType = types [0];
7227         }
7228         for (i = 0; i < num; i++) {
7229           MemFree (titles [i]);
7230         }
7231       } else {
7232         /*
7233         Message (MSG_OK, "Unable to match journal");
7234         */
7235       }
7236     }
7237     MonitorStrValue (mon, "Closing MedArch");
7238     Update ();
7239     MedArchFini ();
7240     MonitorFree (mon);
7241     ArrowCursor ();
7242     Update ();
7243     return TRUE;
7244   } else {
7245     ArrowCursor ();
7246     Message (MSG_ERROR, "Unable to connect to MedArch");
7247     MonitorFree (mon);
7248     Update ();
7249   }
7250   return FALSE;
7251 }
7252 /*#endif*/
7253 
7254 /*#ifdef USE_TAXON*/
LookupTaxonomyFunc(Uint2 entityID)7255 static Boolean LookupTaxonomyFunc (Uint2 entityID)
7256 
7257 {
7258   SeqEntryPtr  sep;
7259 
7260   if (entityID < 1) return FALSE;
7261   sep = GetTopSeqEntryForEntityID (entityID);
7262   if (sep == NULL) return FALSE;
7263   if (! leaveAsOldAsn) {
7264     MySeqEntryToAsn3 (sep, TRUE, FALSE, TRUE);
7265   }
7266   return TRUE;
7267 }
7268 /*#endif*/
7269 
7270 extern void QuitProc (void);
QuitProc(void)7271 extern void QuitProc (void)
7272 
7273 {
7274   Boolean        dirty;
7275   Uint4          j;
7276   Uint4          num;
7277   ObjMgrPtr      omp;
7278   ObjMgrDataPtr  PNTR omdpp;
7279   ObjMgrDataPtr  tmp;
7280 #ifdef USE_SMARTNET
7281   SMUserDataPtr  sm_usr_data = NULL;
7282   OMUserDataPtr  omudp;
7283 #endif
7284 
7285 #ifdef WIN_MAC
7286   if (initialFormsActive) {
7287     if (Message (MSG_YN,
7288         "This will end your session without saving any data.\nAre you sure you want to exit?") == ANS_YES) {
7289       QuitProgram ();
7290     }
7291     return;
7292   }
7293 #endif
7294 
7295   if (smartnetMode) {
7296 #ifdef USE_SMARTNET
7297 
7298       omp = ObjMgrGet ();
7299       num = omp->HighestEntityID;
7300       for(j = 1; j <= omp->HighestEntityID; j++) {
7301           if((omudp = ObjMgrGetUserData(j, 0,0, SMART_KEY)) != NULL) {
7302             if((sm_usr_data =
7303                 (SMUserDataPtr) omudp->userdata.ptrvalue) != NULL &&
7304                sm_usr_data->fd != 0) {
7305               sm_usr_data->header->status = SMStatClosed;
7306               SMSendMsgToClient(sm_usr_data);
7307             }
7308           }
7309       }
7310 #endif
7311       QuitProgram ();
7312       return;
7313   }
7314 
7315   dirty = FALSE;
7316   omp = ObjMgrGet ();
7317   num = omp->currobj;
7318   for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL; j++, omdpp++) {
7319     tmp = *omdpp;
7320     if (tmp->parentptr == NULL) {
7321       if (tmp->dirty) {
7322         dirty = TRUE;
7323       }
7324     }
7325   }
7326   if (dirty) {
7327     if (Message (MSG_YN,
7328         "Some data have not been saved.\nAre you sure you want to exit?") == ANS_NO) {
7329       return;
7330     }
7331   } else if (subtoolMode || smartnetMode) {
7332     if (Message (MSG_YN,
7333         "Are you sure you want to exit?") == ANS_NO) {
7334       return;
7335     }
7336   }
7337 #ifndef WIN_MAC
7338   if (subtoolMode || smartnetMode || backupMode) {
7339     subtoolRecordDirty = FALSE;
7340     FileRemove (SEQUIN_EDIT_TEMP_FILE);
7341     /* FileRemove (SEQUIN_EDIT_PREV_FILE); */
7342     FileRemove (SEQUIN_EDIT_BACK_FILE);
7343     FileRemove (SEQUIN_EDIT_ARCH_FILE);
7344     FileRename (SEQUIN_EDIT_PREV_FILE, SEQUIN_EDIT_ARCH_FILE);
7345     if (backupMode) {
7346       FileRemove (SEQUIN_EDIT_ARCH_FILE);
7347     }
7348   }
7349 #endif
7350   QuitProgram ();
7351 }
7352 
CloseProc(BaseFormPtr bfp)7353 static void CloseProc (BaseFormPtr bfp)
7354 
7355 {
7356   BioseqViewFormPtr  bvfp;
7357   Uint2              entityID;
7358   Boolean            freeEditors = FALSE;
7359   Int4               num_dirty;
7360   Uint4              j;
7361   Uint4              num;
7362   Boolean            numview;
7363   ObjMgrPtr          omp;
7364   ObjMgrDataPtr      PNTR omdpp;
7365   OMUserDataPtr      omudp;
7366   ObjMgrDataPtr      tmp;
7367   Uint2              userkey;
7368   ValNodePtr         vnp;
7369 #ifdef USE_SMARTNET
7370   SMUserDataPtr     sm_usr_data = NULL;
7371 #endif
7372 
7373 #ifdef WIN_MAC
7374   if (initialFormsActive) return;
7375 #endif
7376   if (bfp != NULL) {
7377     omp = ObjMgrGet ();
7378     num = omp->currobj;
7379     for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL; j++, omdpp++) {
7380       tmp = *omdpp;
7381       if (tmp->parentptr == NULL && tmp->EntityID == bfp->input_entityID) {
7382         num_dirty = 0;
7383         numview = 0;
7384         for (omudp = tmp->userdata; omudp != NULL; omudp = omudp->next) {
7385           if (omudp->proctype == OMPROC_VIEW) {
7386             numview++;
7387             if (tmp->dirty) {
7388               num_dirty++;
7389             }
7390           }
7391         }
7392         if (num_dirty == 1 && numview < 2) {
7393           if (Message (MSG_OKC,
7394               "Closing the window will lose unsaved data.") != ANS_OK) {
7395             return;
7396           }
7397         }
7398         if (numview < 2) {
7399           freeEditors = TRUE;
7400         }
7401       }
7402     }
7403     if (freeEditors) {
7404       bvfp = (BioseqViewFormPtr) bfp;
7405       if (bvfp->input_entityID > 0 && bvfp->userkey > 0) {
7406         /* need to unlock far components before freeing data */
7407         if (bvfp->bvd.bsplist != NULL) {
7408           bvfp->bvd.bsplist = UnlockFarComponents (bvfp->bvd.bsplist);
7409         }
7410         userkey = bvfp->userkey;
7411         bvfp->userkey = 0;
7412         /* ObjMgrFreeUserData (bvfp->input_entityID, bvfp->procid, bvfp->proctype, userkey); */
7413         /* this may trigger another remove, hence bvfp->userkey first set to 0 */
7414         for (vnp = bvfp->bvd.entityList; vnp != NULL; vnp = vnp->next) {
7415           if (bvfp->input_entityID != (Uint2) vnp->data.intvalue) {
7416             ObjMgrFreeUserData ((Uint2) vnp->data.intvalue, bvfp->procid, bvfp->proctype, userkey);
7417           }
7418         }
7419         bvfp->userkey = userkey;
7420       }
7421       if (bvfp->bvd.entityList != NULL) {
7422         bvfp->bvd.entityList = ValNodeFree (bvfp->bvd.entityList);
7423       }
7424     }
7425     numview = 0;
7426     for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL; j++, omdpp++) {
7427       tmp = *omdpp;
7428 
7429       if (tmp->parentptr == NULL) {
7430           for (omudp = tmp->userdata; omudp != NULL; omudp = omudp->next) {
7431 
7432               if (omudp->proctype == OMPROC_VIEW) {
7433                   numview++;
7434               }
7435           }
7436       }
7437     }
7438 
7439     entityID = bfp->input_entityID;
7440     if(!smartnetMode) {
7441         /* RemoveSeqEntryViewer (bfp->form); */ /* can go back to Remove */
7442         Remove (bfp->form);
7443         if (freeEditors) {
7444           ObjMgrSendMsg (OM_MSG_DEL, entityID, 0, 0);
7445         }
7446     }
7447 
7448     if (numview <= 1) {
7449         if (subtoolMode || stdinMode || binseqentryMode) {
7450             Message (MSG_OK, "No more viewers, quitting program.");
7451             QuitProgram ();
7452             return;
7453         } else if (smartnetMode) {
7454 #ifdef USE_SMARTNET
7455           if((omudp =
7456               ObjMgrGetUserData(bfp->input_entityID, 0, 0, SMART_KEY)) != NULL) {
7457               if((sm_usr_data =
7458                   (SMUserDataPtr) omudp->userdata.ptrvalue) != NULL &&
7459                  sm_usr_data->fd != (int) NULL) {
7460                   sm_usr_data->header->status = SMStatClosed;
7461                   SMSendMsgToClient(sm_usr_data);
7462               }
7463 
7464               RemoveSeqEntryViewer (bfp->form);
7465               ObjMgrFreeUserData(entityID, 0, 0, SMART_KEY);
7466               ObjMgrFreeUserData (entityID, 0, 0, DUMB_KEY);
7467               if (freeEditors) {
7468                 ObjMgrSendMsg (OM_MSG_DEL, entityID, 0, 0);
7469                 if (DeleteRemainingViews(entityID)) {
7470                   VSeqMgrShow();
7471                 }
7472               }
7473 
7474           }
7475           return;
7476 #endif
7477         }
7478 
7479         WatchCursor ();
7480         Update ();
7481         if (! workbenchMode) {
7482             if (termListForm != NULL || docSumForm != NULL) {
7483             } else {
7484                 Show (startupForm);
7485                 Select (startupForm);
7486                 SendHelpScrollMessage (helpForm, "Initial Entry", NULL);
7487             }
7488             ArrowCursor ();
7489             Update ();
7490         }
7491     } else { /* numview > 1 */
7492         if(smartnetMode) {
7493             entityID = bfp->input_entityID;
7494             RemoveSeqEntryViewer (bfp->form);
7495 #ifdef USE_SMARTNET
7496             /* sssddd   ObjMgrFreeUserData(entityID, 0, 0, SMART_KEY); */
7497 #endif
7498             if (freeEditors) {
7499               ObjMgrSendMsg (OM_MSG_DEL, entityID, 0, 0);
7500             }
7501         }
7502 
7503     }
7504   }
7505 }
7506 
EditSubmitBlock(BaseFormPtr bfp)7507 static void EditSubmitBlock (BaseFormPtr bfp)
7508 
7509 {
7510   Int2           handled;
7511   ObjMgrDataPtr  omdp;
7512 
7513   if (bfp != NULL && bfp->input_entityID != 0) {
7514     omdp = ObjMgrGetData (bfp->input_entityID);
7515     if (omdp != NULL) {
7516       if (omdp->datatype == OBJ_SEQSUB) {
7517         WatchCursor ();
7518         handled = GatherProcLaunch (OMPROC_EDIT, FALSE, bfp->input_entityID, 1,
7519                                     OBJ_SUBMIT_BLOCK, 0, 0, OBJ_SUBMIT_BLOCK, 0);
7520         ArrowCursor ();
7521         if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
7522           Message (MSG_FATAL, "Unable to launch editor.");
7523         }
7524       } else {
7525         Message (MSG_OK, "Record has no submit block.  This may be added when record is first read.");
7526       }
7527     }
7528   }
7529 }
7530 
7531 /*
7532 static void DisplayFontChangeProc (IteM i)
7533 
7534 {
7535   BaseFormPtr  bfp;
7536   FonT         fnt;
7537   FontSpec     fs;
7538 
7539 #ifdef WIN_MAC
7540   bfp = currentFormDataPtr;
7541 #else
7542   bfp = GetObjectExtra (i);
7543 #endif
7544   if (bfp != NULL) {
7545     MemSet ((Pointer) (&fs), 0, sizeof (FontSpec));
7546     fnt = programFont;
7547     if (seqviewprocs.displayFont != NULL) {
7548       fnt = seqviewprocs.displayFont;
7549     }
7550     GetFontSpec (fnt, &fs);
7551     if (ChooseFont (&fs, CFF_READ_FSP | CFF_MONOSPACE, NULL)) {
7552       seqviewprocs.displayFont = CreateFont (&fs);
7553       SendMessageToForm (bfp->form, VIB_MSG_REDRAW);
7554     }
7555   }
7556 }
7557 */
7558 
DuplicateViewProc(IteM i)7559 static void DuplicateViewProc (IteM i)
7560 
7561 {
7562   BaseFormPtr  bfp;
7563   Int2         handled;
7564   Uint4        itemID;
7565 
7566 #ifdef WIN_MAC
7567   bfp = currentFormDataPtr;
7568 #else
7569   bfp = GetObjectExtra (i);
7570 #endif
7571   if (bfp == NULL) return;
7572   if (bfp->input_itemtype == OBJ_BIOSEQ) {
7573     WatchCursor ();
7574     itemID = bfp->input_itemID;
7575     if (itemID == 0) {
7576       itemID = 1;
7577     }
7578     seqviewprocs.forceSeparateViewer = TRUE;
7579     SeqEntrySetScope (NULL);
7580     handled = GatherProcLaunch (OMPROC_VIEW, FALSE, bfp->input_entityID, itemID,
7581                                 OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
7582     ArrowCursor ();
7583     if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
7584       Message (MSG_ERROR, "Unable to launch additional viewer.");
7585     }
7586   } else if (bfp->input_itemtype == OBJ_MEDLINE_ENTRY) {
7587     WatchCursor ();
7588     itemID = bfp->input_itemID;
7589     if (itemID == 0) {
7590       itemID = 1;
7591     }
7592     handled = GatherProcLaunch (OMPROC_VIEW, FALSE, bfp->input_entityID, itemID,
7593                                 OBJ_MEDLINE_ENTRY, 0, 0, OBJ_MEDLINE_ENTRY, 0);
7594     ArrowCursor ();
7595     if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
7596       Message (MSG_ERROR, "Unable to launch additional viewer.");
7597     }
7598   }
7599 }
7600 
7601 
RestoreSeqEntryProc(IteM i)7602 static void RestoreSeqEntryProc (IteM i)
7603 
7604 {
7605   BaseFormPtr  bfp;
7606   Char         path [PATH_MAX];
7607   Uint2        new_entityID;
7608 
7609 #ifdef WIN_MAC
7610   bfp = currentFormDataPtr;
7611 #else
7612   bfp = GetObjectExtra (i);
7613 #endif
7614   if (bfp != NULL && bfp->input_itemtype == OBJ_BIOSEQ) {
7615     if (GetInputFileName (path, sizeof (path), "", "TEXT")) {
7616       new_entityID = RestoreEntityIDFromFile (path, bfp->input_entityID);
7617       if (new_entityID != 0) {
7618         bfp->input_entityID = new_entityID;
7619         ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
7620         ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
7621       }
7622     }
7623   }
7624 }
7625 
RestoreAndConvertSeqEntryProc(IteM i)7626 static void RestoreAndConvertSeqEntryProc (IteM i)
7627 
7628 {
7629   BaseFormPtr  bfp;
7630   Char         path [PATH_MAX];
7631   Uint2        new_entityID;
7632 
7633 #ifdef WIN_MAC
7634   bfp = currentFormDataPtr;
7635 #else
7636   bfp = GetObjectExtra (i);
7637 #endif
7638   if (bfp != NULL && bfp->input_itemtype == OBJ_BIOSEQ) {
7639     if (GetInputFileName (path, sizeof (path), "", "TEXT")) {
7640       new_entityID = RestoreEntityIDFromFileEx (path, bfp->input_entityID, TRUE);
7641       if (new_entityID != 0) {
7642         bfp->input_entityID = new_entityID;
7643         ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
7644         ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
7645       }
7646     }
7647   }
7648 }
7649 
AddAboutAndHelpMenuItems(MenU m)7650 void AddAboutAndHelpMenuItems (MenU m)
7651 
7652 {
7653   CommandItem (m, "About Sequin...", AboutProc);
7654   CommandItem (m, "Help...", DisplayHelpFormProc);
7655   SeparatorItem (m);
7656 }
7657 
FindOrf(IteM i)7658 static void FindOrf (IteM i)
7659 
7660 {
7661   BaseFormPtr  bfp;
7662   BioseqPtr    bsp;
7663 
7664 #ifdef WIN_MAC
7665   bfp = currentFormDataPtr;
7666 #else
7667   bfp = GetObjectExtra (i);
7668 #endif
7669   if (bfp == NULL) return;
7670   bsp =  GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
7671   if (bsp == NULL) return;
7672   LaunchOrfViewer (bsp, bfp->input_entityID, bfp->input_itemID, FALSE);
7673 }
7674 
7675 
7676 #define USE_FINDALU 0
7677 
7678 #if USE_FINDALU
FindAlu(IteM i)7679 static void FindAlu (IteM i)
7680 
7681 {
7682   MsgAnswer    ans;
7683   BaseFormPtr  bfp;
7684   BioseqPtr    bsp;
7685   Boolean      got_some;
7686 
7687 #ifdef WIN_MAC
7688   bfp = currentFormDataPtr;
7689 #else
7690   bfp = GetObjectExtra (i);
7691 #endif
7692   if (bfp == NULL) return;
7693   bsp =  GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
7694   if (bsp == NULL) return;
7695   if (bsp->length >= 100) {
7696     ans = Message (MSG_OKC, "This calculation may take a while");
7697     if (ans == ANS_CANCEL) return;
7698   }
7699   WatchCursor ();
7700   got_some = FindHumanRepeats (bsp, TRUE);
7701   ArrowCursor ();
7702   if (got_some) {
7703     Message (MSG_OK, "Repeat regions were found.");
7704     ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
7705     ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
7706   } else {
7707     Message (MSG_OK, "No Repeat regions found.");
7708   }
7709 }
7710 #endif
7711 
7712 typedef struct changetargetform {
7713   FORM_MESSAGE_BLOCK
7714   TexT               seqid;
7715   BaseFormPtr        base;
7716 } ChangeTargetForm, PNTR ChangeTargetFormPtr;
7717 
AcceptChangeTargetProc(ButtoN b)7718 static void AcceptChangeTargetProc (ButtoN b)
7719 
7720 {
7721   ChangeTargetFormPtr  cfp;
7722   CharPtr              str;
7723 
7724   cfp = (ChangeTargetFormPtr) GetObjectExtra (b);
7725   if (cfp == NULL) return;
7726   str = SaveStringFromText (cfp->seqid);
7727   SetBioseqViewTarget (cfp->base, str);
7728   str = MemFree (str);
7729 }
7730 
ClearTargetBtn(ButtoN b)7731 static void ClearTargetBtn (ButtoN b)
7732 
7733 {
7734   ChangeTargetFormPtr  cfp;
7735 
7736   cfp = (ChangeTargetFormPtr) GetObjectExtra (b);
7737   if (cfp == NULL) return;
7738   SetTitle (cfp->seqid, "");
7739 }
7740 
ChangeTargetMessageProc(ForM f,Int2 mssg)7741 static void ChangeTargetMessageProc (ForM f, Int2 mssg)
7742 
7743 {
7744   StdEditorProcsPtr  sepp;
7745 
7746   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
7747   if (sepp != NULL) {
7748     if (sepp->handleMessages != NULL) {
7749       sepp->handleMessages (f, mssg);
7750     }
7751   }
7752 }
7753 
ChangeTargetBaseForm(BaseFormPtr bfp)7754 extern void ChangeTargetBaseForm (BaseFormPtr bfp)
7755 {
7756   ButtoN               b;
7757   GrouP                c;
7758   ChangeTargetFormPtr  cfp;
7759   GrouP                g;
7760   StdEditorProcsPtr    sepp;
7761   WindoW               w;
7762 
7763   if (bfp == NULL) return;
7764 
7765   cfp = (ChangeTargetFormPtr) MemNew (sizeof (ChangeTargetForm));
7766   if (cfp == NULL) return;
7767   w = FixedWindow (-50, -33, -10, -10, "Select Target by SeqID", StdCloseWindowProc);
7768   SetObjectExtra (w, cfp, StdCleanupFormProc);
7769   cfp->form = (ForM) w;
7770   cfp->formmessage = ChangeTargetMessageProc;
7771 
7772   g = HiddenGroup (w, -1, 0, NULL);
7773   SetGroupSpacing (g, 10, 10);
7774 
7775   cfp->seqid = DialogText (g, "", 12, NULL);
7776   cfp->base = bfp;
7777   c = HiddenGroup (g, 3, 0, NULL);
7778   SetGroupSpacing (c, 10, 10);
7779   b = DefaultButton (c, "Accept", AcceptChangeTargetProc);
7780   SetObjectExtra (b, cfp, NULL);
7781   b = PushButton (c, "Clear", ClearTargetBtn);
7782   SetObjectExtra (b, cfp, NULL);
7783   PushButton (c, "Cancel", StdCancelButtonProc);
7784 
7785   AlignObjects (ALIGN_CENTER, (HANDLE) cfp->seqid, (HANDLE) c, NULL);
7786   RealizeWindow (w);
7787   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
7788   if (sepp != NULL) {
7789     SetActivate (w, sepp->activateForm);
7790   }
7791   Show (w);
7792   Select (w);
7793 }
7794 
DoChangeTarget(IteM i)7795 static void DoChangeTarget (IteM i)
7796 
7797 {
7798   BaseFormPtr          bfp;
7799 
7800 #ifdef WIN_MAC
7801   bfp = currentFormDataPtr;
7802 #else
7803   bfp = GetObjectExtra (i);
7804 #endif
7805   ChangeTargetBaseForm (bfp);
7806 }
7807 
ConfigFormMessage(ForM f,Int2 mssg)7808 static void ConfigFormMessage (ForM f, Int2 mssg)
7809 
7810 {
7811   BaseFormPtr        bfp;
7812   StdEditorProcsPtr  sepp;
7813 
7814   bfp = (BaseFormPtr) GetObjectExtra (f);
7815   if (bfp != NULL) {
7816     switch (mssg) {
7817       case VIB_MSG_CUT :
7818         StdCutTextProc (NULL);
7819         break;
7820       case VIB_MSG_COPY :
7821         StdCopyTextProc (NULL);
7822         break;
7823       case VIB_MSG_PASTE :
7824         StdPasteTextProc (NULL);
7825         break;
7826       case VIB_MSG_DELETE :
7827         StdDeleteTextProc (NULL);
7828         break;
7829       default :
7830         sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
7831         if (sepp != NULL && sepp->handleMessages != NULL) {
7832           sepp->handleMessages (f, mssg);
7833         }
7834         break;
7835     }
7836   }
7837 }
7838 
ConfigAccepted(void)7839 static void ConfigAccepted (void)
7840 
7841 {
7842   if (WriteSequinAppParam ("SETTINGS", "PUBLICNETWORKSEQUIN", "TRUE")) {
7843     Message (MSG_OK, "Setting will take affect when you restart Sequin");
7844   }
7845 }
7846 
ConfigCancelled(void)7847 static void ConfigCancelled (void)
7848 
7849 {
7850   Message (MSG_OK, "No changes to the network configuration have been made");
7851 }
7852 
ConfigTurnedOff(void)7853 static void ConfigTurnedOff (void)
7854 
7855 {
7856   if (WriteSequinAppParam ("SETTINGS", "PUBLICNETWORKSEQUIN", "FALSE")) {
7857     Message (MSG_OK, "Setting will take affect when you restart Sequin");
7858   }
7859 }
7860 
7861 
7862 #define USE_STYLE_MANAGER 0
7863 
7864 #if USE_STYLE_MANAGER
7865 
StyleManagerProc(IteM i)7866 static void StyleManagerProc (IteM i)
7867 
7868 {
7869   MuskStyleManager ();
7870 }
7871 
7872 
SetSequinAppParamTF(CharPtr section,CharPtr type,Boolean value)7873 static void SetSequinAppParamTF (CharPtr section, CharPtr type, Boolean value)
7874 
7875 {
7876   if (value) {
7877     SetSequinAppParam (section, type, "TRUE");
7878   } else {
7879     SetSequinAppParam (section, type, "FALSE");
7880   }
7881 }
7882 
7883 
ReplaceString(CharPtr PNTR target,CharPtr newstr)7884 static void ReplaceString (CharPtr PNTR target, CharPtr newstr)
7885 
7886 {
7887   if (target == NULL) return;
7888   MemFree (*target);
7889   *target = StringSaveNoNull (newstr);
7890 }
7891 
7892 
7893 typedef struct prefsform {
7894   FORM_MESSAGE_BLOCK
7895   DialoG             prefs;
7896 } PrefsForm, PNTR PrefsFormPtr;
7897 
7898 
AcceptPrefsProc(ButtoN b)7899 static void AcceptPrefsProc (ButtoN b)
7900 
7901 {
7902   EntrezPrefsPtr  epp;
7903   PrefsFormPtr    pfp;
7904 
7905   pfp = (PrefsFormPtr) GetObjectExtra (b);
7906   if (pfp == NULL) return;
7907   Hide (pfp->form);
7908   epp = (EntrezPrefsPtr) DialogToPointer (pfp->prefs);
7909   if (epp != NULL) {
7910     entrezglobals.persistDefault = epp->persistDefault;
7911     entrezglobals.alignDefault = epp->alignDefault;
7912     entrezglobals.lookupDirect = epp->lookupDirect;
7913     entrezglobals.showAsn = epp->showAsn;
7914     ReplaceString (&entrezglobals.initDatabase, epp->initDatabase);
7915     ReplaceString (&entrezglobals.initField, epp->initField);
7916     ReplaceString (&entrezglobals.initMode, epp->initMode);
7917     ReplaceString (&medviewprocs.initMedLabel, epp->initMedLabel);
7918     ReplaceString (&seqviewprocs.initNucLabel, epp->initNucLabel);
7919     ReplaceString (&seqviewprocs.initProtLabel, epp->initProtLabel);
7920     ReplaceString (&seqviewprocs.initGenomeLabel, epp->initGenomeLabel);
7921     SetSequinAppParamTF ("PREFERENCES", "PARENTSPERSIST", entrezglobals.persistDefault);
7922     SetSequinAppParamTF ("PREFERENCES", "ALIGNCHECKED", entrezglobals.alignDefault);
7923     SetSequinAppParamTF ("PREFERENCES", "LOOKUPDIRECT", entrezglobals.lookupDirect);
7924     SetSequinAppParamTF ("PREFERENCES", "SHOWASNPAGE", entrezglobals.showAsn);
7925     SetSequinAppParam ("SETTINGS", "DATABASE", entrezglobals.initDatabase);
7926     SetSequinAppParam ("SETTINGS", "FIELD", entrezglobals.initField);
7927     SetSequinAppParam ("SETTINGS", "MODE", entrezglobals.initMode);
7928     SetSequinAppParam ("SETTINGS", "MEDPAGE", medviewprocs.initMedLabel);
7929     SetSequinAppParam ("SETTINGS", "NUCPAGE", seqviewprocs.initNucLabel);
7930     SetSequinAppParam ("SETTINGS", "PRTPAGE", seqviewprocs.initProtLabel);
7931     SetSequinAppParam ("SETTINGS", "GENMPAGE", seqviewprocs.initGenomeLabel);
7932   }
7933   EntrezPrefsFree (epp);
7934   Remove (pfp->form);
7935 }
7936 
DefaultMessageProc(ForM f,Int2 mssg)7937 static void DefaultMessageProc (ForM f, Int2 mssg)
7938 
7939 {
7940   StdEditorProcsPtr  sepp;
7941 
7942   sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
7943   if (sepp != NULL) {
7944     if (sepp->handleMessages != NULL) {
7945       sepp->handleMessages (f, mssg);
7946     }
7947   }
7948 }
7949 #endif
7950 
7951 #ifdef WIN_MAC
PreferencesProc(IteM i)7952 static void PreferencesProc (IteM i)
7953 
7954 {
7955   /*
7956   ButtoN          b;
7957   GrouP           c;
7958   EntrezPrefsPtr  epp;
7959   GrouP           g;
7960   PrefsFormPtr    pfp;
7961   WindoW          w;
7962 
7963   pfp = (PrefsFormPtr) MemNew (sizeof (PrefsForm));
7964   if (pfp == NULL) return;
7965   if (! EntrezIsInited ()) {
7966     EntrezBioseqFetchEnable ("Sequin", TRUE);
7967     SequinEntrezInit ("Sequin", FALSE, NULL);
7968   }
7969   w = FixedWindow (-50, -33, -10, -10, "Preferences", StdCloseWindowProc);
7970   SetObjectExtra (w, pfp, StdCleanupFormProc);
7971   pfp->form = (ForM) w;
7972   pfp->formmessage = DefaultMessageProc;
7973   g = HiddenGroup (w, -1, 0, NULL);
7974   SetGroupSpacing (g, 10, 10);
7975   pfp->prefs = CreateEntrezPrefsDialog (g, NULL);
7976   c = HiddenGroup (g, 2, 0, NULL);
7977   b = DefaultButton (c, "Accept", AcceptPrefsProc);
7978   SetObjectExtra (b, pfp, NULL);
7979   PushButton (c, "Cancel", StdCancelButtonProc);
7980   AlignObjects (ALIGN_CENTER, (HANDLE) pfp->prefs, (HANDLE) c, NULL);
7981   RealizeWindow (w);
7982   epp = EntrezPrefsNew ();
7983   if (epp != NULL) {
7984     epp->persistDefault = entrezglobals.persistDefault;
7985     epp->alignDefault = entrezglobals.alignDefault;
7986     epp->lookupDirect = entrezglobals.lookupDirect;
7987     epp->showAsn = entrezglobals.showAsn;
7988     epp->initDatabase = StringSaveNoNull (entrezglobals.initDatabase);
7989     epp->initField = StringSaveNoNull (entrezglobals.initField);
7990     epp->initMode = StringSaveNoNull (entrezglobals.initMode);
7991     epp->initMedLabel = StringSaveNoNull (medviewprocs.initMedLabel);
7992     epp->initNucLabel = StringSaveNoNull (seqviewprocs.initNucLabel);
7993     epp->initProtLabel = StringSaveNoNull (seqviewprocs.initProtLabel);
7994     epp->initGenomeLabel = StringSaveNoNull (seqviewprocs.initGenomeLabel);
7995   }
7996   PointerToDialog (pfp->prefs, (Pointer) epp);
7997   EntrezPrefsFree (epp);
7998   Show (w);
7999   Select (w);
8000   */
8001 }
8002 #endif
8003 
NetConfigureProc(IteM i)8004 void NetConfigureProc (IteM i)
8005 
8006 {
8007   Boolean  netCurrentlyOn = FALSE;
8008   Char     str [32];
8009 
8010   if (GetSequinAppParam ("SETTINGS", "PUBLICNETWORKSEQUIN", NULL, str, sizeof (str))) {
8011     if (StringICmp (str, "TRUE") == 0) {
8012       netCurrentlyOn = TRUE;
8013     }
8014   }
8015   if (useEntrez) {
8016     netCurrentlyOn = TRUE;
8017   }
8018   SendHelpScrollMessage (helpForm, "Misc Menu", "Net Configure");
8019   ShowNetConfigForm (ConfigFormActivated, ConfigFormMessage,
8020                      ConfigAccepted, ConfigCancelled,
8021                      ConfigTurnedOff, netCurrentlyOn);
8022 }
8023 
8024 
SqnReadAlignView(BaseFormPtr bfp,BioseqPtr target_bsp,SeqEntryPtr source_sep,Boolean do_update)8025 extern void SqnReadAlignView (BaseFormPtr bfp, BioseqPtr target_bsp, SeqEntryPtr source_sep, Boolean do_update)
8026 
8027 {
8028   BioseqPtr  nbsp;
8029 
8030   if (target_bsp == NULL || source_sep == NULL) return;
8031   nbsp = FindNucBioseq (source_sep);
8032   if (nbsp == NULL) return;
8033 
8034   if (do_update) {
8035     UpdateSeqAfterDownload (bfp, target_bsp, nbsp);
8036   } else {
8037     ExtendSeqAfterDownload (bfp, target_bsp, nbsp);
8038   }
8039 }
8040 
8041 extern void NewFeaturePropagate (
8042   IteM i
8043 );
8044 
8045 NLM_EXTERN Int4 GenomeFromLocName (CharPtr loc_name);
8046 
8047 /*******COLOMBE ***********/
8048 
8049 
CommonAddSeq(IteM i,Int2 type)8050 static void CommonAddSeq (IteM i, Int2 type)
8051 
8052 {
8053   Nlm_QualNameAssocPtr qp;
8054   BaseFormPtr        bfp;
8055   Uint1              biomol;
8056   BioSourcePtr       biop = NULL;
8057   BioseqPtr          bsp;
8058   BioseqSetPtr       bssp;
8059   Pointer            dataptr;
8060   Uint2              datatype;
8061   FILE               *fp;
8062   MolInfoPtr         mip;
8063   MolInfoPtr         molinf = NULL;
8064   OrgRefPtr          orp;
8065   SeqEntryPtr        nuc;
8066   Char               path [PATH_MAX];
8067   CharPtr            ptr;
8068   SeqEntryPtr        sep;
8069   BioSourcePtr       src = NULL;
8070   Char               str [128];
8071   CharPtr            tax = NULL;
8072   CharPtr            title = NULL;
8073   SeqEntryPtr        top;
8074   ValNodePtr         vnp;
8075   Int4               tmp;
8076 
8077 #ifdef WIN_MAC
8078   bfp = currentFormDataPtr;
8079 #else
8080   bfp = GetObjectExtra (i);
8081 #endif
8082   if (bfp == NULL) return;
8083   top = GetTopSeqEntryForEntityID (bfp->input_entityID);
8084   if (top == NULL) return;
8085   if (type == 1 || type == 2) {
8086     if (! GetInputFileName (path, sizeof (path),"","TEXT")) return;
8087     fp = FileOpen (path, "r");
8088     if (fp == NULL) return;
8089     if (IS_Bioseq_set (top)) {
8090       bssp = (BioseqSetPtr) top->data.ptrvalue;
8091       if (bssp != NULL && bssp->_class != BioseqseqSet_class_phy_set) {
8092         sep = bssp->seq_set;
8093         vnp = SeqEntryGetSeqDescr (top, Seq_descr_source, NULL);
8094         if (vnp != NULL) {
8095           src = (BioSourcePtr) vnp->data.ptrvalue;
8096           if (src != NULL) {
8097             orp = src->org;
8098             if (orp != NULL) {
8099               tax = orp->taxname;
8100             }
8101           }
8102         }
8103       }
8104     }
8105     nuc = FindNucSeqEntry (top);
8106     vnp = SeqEntryGetSeqDescr (nuc, Seq_descr_molinfo, NULL);
8107     if (vnp != NULL) {
8108       molinf = (MolInfoPtr) vnp->data.ptrvalue;
8109     }
8110     while ((dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, NULL, FALSE, FALSE, TRUE, FALSE)) != NULL) {
8111       if (datatype == OBJ_BIOSEQ || datatype == OBJ_BIOSEQSET) {
8112         bsp = NULL;
8113         bssp = NULL;
8114         biop = NULL;
8115         sep = SeqMgrGetSeqEntryForData (dataptr);
8116         if (sep == NULL) {
8117           sep = SeqEntryNew ();
8118           if (datatype == OBJ_BIOSEQ) {
8119             bsp = (BioseqPtr) dataptr;
8120             sep->choice = 1;
8121             sep->data.ptrvalue = bsp;
8122             SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
8123           } else if (datatype == OBJ_BIOSEQSET) {
8124             bssp = (BioseqSetPtr) dataptr;
8125             sep->choice = 2;
8126             sep->data.ptrvalue = bssp;
8127             SeqMgrSeqEntry (SM_BIOSEQSET, (Pointer) bssp, sep);
8128           } else {
8129             sep = SeqEntryFree (sep);
8130           }
8131         }
8132         if (sep != NULL) {
8133           AddSeqEntryToSeqEntry (top, sep, TRUE);
8134           title = SeqEntryGetTitle (sep);
8135           vnp = SeqEntryGetSeqDescr (sep, Seq_descr_source, NULL);
8136           if (vnp == NULL || title != NULL) {
8137             ptr = StringISearch (title, "[org=");
8138             if (ptr != NULL) {
8139               StringNCpy_0 (str, ptr + 5, sizeof (str));
8140               ptr = StringChr (str, ']');
8141             } else {
8142               ptr = StringISearch (title, "[organism=");
8143               if (ptr != NULL) {
8144                 StringNCpy_0 (str, ptr + 10, sizeof (str));
8145                 ptr = StringChr (str, ']');
8146               }
8147             }
8148             if (ptr != NULL) {
8149               *ptr = '\0';
8150               biop = BioSourceNew ();
8151               if (biop != NULL) {
8152                 orp = OrgRefNew ();
8153                 biop->org = orp;
8154                 if (orp != NULL) {
8155                   SetTaxNameAndRemoveTaxRef (orp, StringSave (str));
8156                 }
8157                 vnp = CreateNewDescriptor (sep, Seq_descr_source);
8158                 if (vnp != NULL) {
8159                   vnp->data.ptrvalue = (Pointer) biop;
8160                 }
8161               }
8162             }
8163           }
8164           if (vnp == NULL && tax != NULL) {
8165             biop = BioSourceNew ();
8166             if (biop != NULL) {
8167               orp = OrgRefNew ();
8168               biop->org = orp;
8169               if (orp != NULL) {
8170                 SetTaxNameAndRemoveTaxRef (orp, tax);
8171               }
8172               vnp = CreateNewDescriptor (sep, Seq_descr_source);
8173               if (vnp != NULL) {
8174                 vnp->data.ptrvalue = (Pointer) biop;
8175               }
8176             }
8177           }
8178           vnp = SeqEntryGetSeqDescr (sep, Seq_descr_source, NULL);
8179           if (vnp != NULL) {
8180             biop = (BioSourcePtr) vnp->data.ptrvalue;
8181           }
8182           if (biop != NULL && title != NULL) {
8183             for (qp = current_orgmod_subtype_alist; qp->name != NULL; qp++) {
8184               MakeSearchStringFromAlist (str, qp->name);
8185               AddToOrgMod (biop, title, str, qp->value);
8186               ExciseString (title, str, "]");
8187             }
8188             for (qp = current_subsource_subtype_alist; qp->name != NULL; qp++) {
8189               MakeSearchStringFromAlist (str, qp->name);
8190               AddToSubSource (biop, title, str, qp->value);
8191               ExciseString (title, str, "]");
8192             }
8193             AddToOrgMod (biop, title, "[note=", 255);
8194             ExciseString (title, "[note=", "]");
8195             AddToSubSource (biop, title, "[subsource=", 255);
8196             ExciseString (title, "[subsource=", "]");
8197             ExciseString (title, "[org=", "]");
8198             ExciseString (title, "[organism=", "]");
8199             if (bsp != NULL) {
8200               ptr = StringISearch (title, "[molecule=");
8201               if (ptr != NULL) {
8202                 StringNCpy_0 (str, ptr + 10, sizeof (str));
8203                 ptr = StringChr (str, ']');
8204                 if (ptr != NULL) {
8205                   *ptr = '\0';
8206                   if (StringCmp (str, "dna") == 0) {
8207                     bsp->mol = Seq_mol_dna;
8208                   } else if (StringCmp (str, "rna") == 0) {
8209                     bsp->mol = Seq_mol_rna;
8210                   }
8211                 }
8212               }
8213             }
8214             ptr = StringISearch (title, "[location=");
8215             if (ptr != NULL) {
8216               StringNCpy_0 (str, ptr + 10, sizeof (str));
8217               ptr = StringChr (str, ']');
8218               if (ptr != NULL) {
8219                 *ptr = '\0';
8220                 if (StringICmp (str, "Mitochondrial") == 0) { /* alternative spelling */
8221                   biop->genome = 5;
8222                 }
8223                 tmp = GenomeFromLocName (str);
8224                 if (tmp > -1) {
8225                   biop->genome = tmp;
8226                 }
8227               }
8228             }
8229             ptr = StringISearch (title, "[moltype=");
8230             if (ptr != NULL) {
8231               biomol = 0;
8232               StringNCpy_0 (str, ptr + 8, sizeof (str));
8233               ptr = StringChr (str, ']');
8234               if (ptr != NULL) {
8235                 *ptr = '\0';
8236                 if (StringICmp (str, "genomic") == 0) {
8237                   biomol = MOLECULE_TYPE_GENOMIC;
8238                 } else if (StringICmp (str, "mRNA") == 0) {
8239                   biomol = MOLECULE_TYPE_MRNA;
8240                 }
8241                 if (biomol != 0) {
8242                   mip = MolInfoNew ();
8243                   if (mip != NULL) {
8244                     mip->biomol = biomol;
8245                     vnp = CreateNewDescriptor (sep, Seq_descr_molinfo);
8246                     if (vnp != NULL) {
8247                       vnp->data.ptrvalue = (Pointer) mip;
8248                     }
8249                   }
8250                 }
8251               }
8252             }
8253           }
8254           ExciseString (title, "[molecule=", "]");
8255           ExciseString (title, "[moltype=", "]");
8256           ExciseString (title, "[location=", "]");
8257           TrimSpacesAroundString (title);
8258           if (title != NULL && StringHasNoText (title)) {
8259             vnp = NULL;
8260             if (IS_Bioseq (sep)) {
8261               bsp = (BioseqPtr) sep->data.ptrvalue;
8262               vnp = ValNodeExtract (&(bsp->descr), Seq_descr_title);
8263             } else if (IS_Bioseq_set (sep)) {
8264               bssp = (BioseqSetPtr) sep->data.ptrvalue;
8265               vnp = ValNodeExtract (&(bssp->descr), Seq_descr_title);
8266             }
8267             if (vnp != NULL && StringHasNoText ((CharPtr) vnp->data.ptrvalue)) {
8268               vnp = ValNodeFreeData (vnp);
8269             }
8270           }
8271           sep = FindNucSeqEntry (sep);
8272           vnp = SeqEntryGetSeqDescr (sep, Seq_descr_molinfo, NULL);
8273           if (vnp == NULL && molinf != NULL) {
8274             mip = MolInfoNew ();
8275             if (mip != NULL) {
8276               vnp = CreateNewDescriptor (sep, Seq_descr_molinfo);
8277               if (vnp != NULL) {
8278                 vnp->data.ptrvalue = (Pointer) mip;
8279                 mip->biomol = molinf->biomol;
8280                 mip->tech = molinf->tech;
8281                 mip->completeness = molinf->completeness;
8282               }
8283             }
8284           }
8285         }
8286       }
8287     }
8288     FileClose (fp);
8289     ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
8290     ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
8291     Update ();
8292   } else {
8293     Message (MSG_OK, "Not yet implemented");
8294   }
8295 }
8296 
AddSeqWithFASTA(IteM i)8297 static void AddSeqWithFASTA (IteM i)
8298 
8299 {
8300   CommonAddSeq (i, 1);
8301 }
8302 
AddSeqWithRec(IteM i)8303 static void AddSeqWithRec (IteM i)
8304 
8305 {
8306   CommonAddSeq (i, 2);
8307 }
8308 
8309 
8310 #ifndef WIN_MAC
8311 extern void CreateNewLayoutMenu (MenU m, BaseFormPtr bp);
8312 
MedlineViewFormMenus(WindoW w)8313 static void MedlineViewFormMenus (WindoW w)
8314 
8315 {
8316   BaseFormPtr  bfp;
8317   IteM         i;
8318   MenU         m;
8319 
8320   bfp = (BaseFormPtr) GetObjectExtra (w);
8321   if (bfp != NULL) {
8322     m = PulldownMenu (w, "File");
8323     FormCommandItem (m, "Close", bfp, VIB_MSG_CLOSE);
8324     SeparatorItem (m);
8325     i = CommandItem (m, "Duplicate", DuplicateViewProc);
8326     SetObjectExtra (i, bfp, NULL);
8327     SeparatorItem (m);
8328     FormCommandItem (m, "Export...", bfp, VIB_MSG_EXPORT);
8329     SeparatorItem (m);
8330     /*
8331     FormCommandItem (m, "Save", bfp, VIB_MSG_SAVE);
8332     FormCommandItem (m, "Save As...", bfp, VIB_MSG_SAVE_AS);
8333     SeparatorItem (m);
8334     */
8335     FormCommandItem (m, "Print...", bfp, VIB_MSG_PRINT);
8336 
8337     m = PulldownMenu (w, "Edit");
8338     FormCommandItem (m, COPY_MENU_ITEM, bfp, VIB_MSG_COPY);
8339   }
8340 }
8341 
8342 
BioseqViewFormMenus(WindoW w)8343 static void BioseqViewFormMenus (WindoW w)
8344 
8345 {
8346   BaseFormPtr    bfp;
8347   IteM           i;
8348   MenU           m;
8349   Int2           mssgadd;
8350   Int2           mssgalign;
8351   Int2           mssgdelete;
8352   Int2           mssgdup;
8353   Int2           mssgfeatprop;
8354   Int2           mssgseq;
8355   Int2           mssgsub;
8356   Int2           mssgupd, mssgupd_idx;
8357   Int2           mssgext;
8358   ObjMgrDataPtr  omdp;
8359   MenU           sub;
8360 
8361   bfp = (BaseFormPtr) GetObjectExtra (w);
8362   if (bfp != NULL) {
8363     m = PulldownMenu (w, "File/ F");
8364 /*#ifdef INTERNAL_NCBI_SEQUIN*/
8365     if (indexerVersion) {
8366       if (subtoolMode || stdinMode || binseqentryMode) {
8367         FormCommandItem (m, "Abort Session", bfp, VIB_MSG_QUIT);
8368         SeparatorItem (m);
8369         CommandItem (m, "Accept Changes", SubtoolDoneProc);
8370         SeparatorItem (m);
8371       } else if (smartnetMode) {
8372 #ifdef USE_SMARTNET
8373         FormCommandItem (m, "Abort Session", bfp, VIB_MSG_CLOSE);
8374         SeparatorItem (m);
8375         i = CommandItem (m, "Accept Changes", SmartnetDoneProc);
8376         SetObjectExtra (i, bfp, NULL);
8377         SeparatorItem (m);
8378 #endif
8379       }
8380     }
8381 /*#endif*/
8382     AddAboutAndHelpMenuItems (m);
8383     i = CommandItem (m, "Open...", ReadNewAsnProc);
8384     SetObjectExtra (i, bfp, NULL);
8385     SeparatorItem (m);
8386     FormCommandItem (m, "Close", bfp, VIB_MSG_CLOSE);
8387     SeparatorItem (m);
8388     /* FormCommandItem (m, "Import Nucleotide FASTA...", bfp, VIB_MSG_IMPORT); */
8389     FormCommandItem (m, "Export...", bfp, VIB_MSG_EXPORT);
8390     SeparatorItem (m);
8391     i = CommandItem (m, "Duplicate View", DuplicateViewProc);
8392     SetObjectExtra (i, bfp, NULL);
8393     SeparatorItem (m);
8394     FormCommandItem (m, "Save", bfp, VIB_MSG_SAVE);
8395     FormCommandItem (m, "Save As...", bfp, VIB_MSG_SAVE_AS);
8396     i = CommandItem (m, "Save As Binary Seq-entry...", SaveBinSeqEntry);
8397     SetObjectExtra (i, bfp, NULL);
8398     SeparatorItem (m);
8399     i = CommandItem (m, "Restore...", RestoreSeqEntryProc);
8400     SetObjectExtra (i, bfp, NULL);
8401     if (indexerVersion) {
8402       i = CommandItem (m, "Restore and Convert SeqSubmit...", RestoreAndConvertSeqEntryProc);
8403       SetObjectExtra (i, bfp, NULL);
8404     }
8405     if ((! subtoolMode) && (! stdinMode) &&
8406         (! binseqentryMode) && (! smartnetMode)) {
8407       SeparatorItem (m);
8408       i = CommandItem (m, "Prepare Submission...", PrepareSeqSubmitProc);
8409       SetObjectExtra (i, bfp, NULL);
8410       omdp = ObjMgrGetData (bfp->input_entityID);
8411       if (omdp != NULL && omdp->datatype != OBJ_SEQSUB) {
8412         Disable (i);
8413       }
8414       /*
8415       i = CommandItem (m, "Submit to NCBI", SubmitToNCBI);
8416       SetObjectExtra (i, bfp, NULL);
8417       if (omdp != NULL && omdp->datatype != OBJ_SEQSUB) {
8418         Disable (i);
8419       }
8420       */
8421     }
8422 /*#ifdef INTERNAL_NCBI_SEQUIN*/
8423     if (indexerVersion) {
8424       if ((! subtoolMode) && (! stdinMode) &&
8425           (! binseqentryMode) && (! smartnetMode)) {
8426         SeparatorItem (m);
8427         FormCommandItem (m, "Print", bfp, VIB_MSG_PRINT);
8428         SeparatorItem (m);
8429         FormCommandItem (m, "Quit/Q", bfp, VIB_MSG_QUIT);
8430       } else {
8431         SeparatorItem (m);
8432         i = CommandItem (m, "Propagate Top Descriptors", ForcePropagate);
8433         SetObjectExtra (i, bfp, NULL);
8434         SeparatorItem (m);
8435         FormCommandItem (m, "Print", bfp, VIB_MSG_PRINT);
8436         if (smartnetMode) {
8437           SeparatorItem (m);
8438           FormCommandItem (m, "Quit/Q", bfp, VIB_MSG_QUIT);
8439         }
8440       }
8441     } else {
8442 /*#else*/
8443       if (subtoolMode || stdinMode || binseqentryMode) {
8444         FormCommandItem (m, "Print", bfp, VIB_MSG_PRINT);
8445         SeparatorItem (m);
8446         FormCommandItem (m, "Abort Session", bfp, VIB_MSG_QUIT);
8447         SeparatorItem (m);
8448         CommandItem (m, "Accept Changes", SubtoolDoneProc);
8449       } else if (smartnetMode) {
8450 #ifdef USE_SMARTNET
8451         FormCommandItem (m, "Print", bfp, VIB_MSG_PRINT);
8452         SeparatorItem (m);
8453         FormCommandItem (m, "Abort Session", bfp, VIB_MSG_CLOSE);
8454         SeparatorItem (m);
8455         i = CommandItem (m, "Accept Changes", SmartnetDoneProc);
8456         SetObjectExtra (i, bfp, NULL);
8457         SeparatorItem (m);
8458         FormCommandItem (m, "Quit/Q", bfp, VIB_MSG_QUIT);
8459 #endif
8460       } else {
8461         SeparatorItem (m);
8462         FormCommandItem (m, "Print", bfp, VIB_MSG_PRINT);
8463         SeparatorItem (m);
8464         FormCommandItem (m, "Quit/Q", bfp, VIB_MSG_QUIT);
8465       }
8466     }
8467 /*#endif*/
8468 
8469     m = PulldownMenu (w, "Edit/ E");
8470     if (subtoolMode || smartnetMode || backupMode) {
8471       FormCommandItem (m, UNDO_MENU_ITEM, bfp, VIB_MSG_UNDO);
8472       SeparatorItem (m);
8473     }
8474     FormCommandItem (m, COPY_MENU_ITEM, bfp, VIB_MSG_COPY);
8475     FormCommandItem (m, CLEAR_MENU_ITEM, bfp, VIB_MSG_DELETE);
8476     SeparatorItem (m);
8477     if (extraServices) {
8478       mssgdup = RegisterFormMenuItemName ("SequinDuplicateItem");
8479       FormCommandItem (m, "Duplicate...", bfp, mssgdup);
8480       SeparatorItem (m);
8481     }
8482     if (genomeCenter != NULL || indexerVersion) {
8483       SetupEditSecondary (m, bfp);
8484       SeparatorItem (m);
8485     }
8486     mssgseq = RegisterFormMenuItemName ("SequinEditSequenceItem");
8487     mssgalign = RegisterFormMenuItemName ("SequinEditAlignmentItem");
8488     mssgdelete = RegisterFormMenuItemName ("SequinDeleteSequencesItem");
8489     mssgsub = RegisterFormMenuItemName ("SequinEditSubmitterItem");
8490     mssgupd = RegisterFormMenuItemName ("SequinUpdateSeqSubmenu");
8491     if (indexerVersion)
8492     {
8493       mssgupd_idx = RegisterFormMenuItemName ("SequinUpdateSeqSubmenuIndexer");
8494     }
8495     mssgext = RegisterFormMenuItemName ("SequinExtendSeqSubmenu");
8496     mssgfeatprop = RegisterFormMenuItemName ("SequinFeaturePropagate");
8497     mssgadd = RegisterFormMenuItemName ("SequinAddSeqSubmenu");
8498     FormCommandItem (m, "Edit Sequence...", bfp, mssgseq);
8499     FormCommandItem (m, "Alignment Assistant...", bfp, mssgalign);
8500     FormCommandItem (m, "Sequence Deletion Tool", bfp, mssgdelete);
8501     FormCommandItem (m, "Edit Submitter Info...", bfp, mssgsub);
8502     if (indexerVersion) {
8503       SeparatorItem (m);
8504       i = CommandItem (m, "Edit History....", EditSequenceHistory);
8505       SetObjectExtra (i, bfp, NULL);
8506     }
8507     SeparatorItem (m);
8508 
8509     if (indexerVersion)
8510     {
8511       /* indexer version */
8512       sub = SubMenu (m, "Indexer Update Sequence");
8513       SetFormMenuItem (bfp, mssgupd_idx, (IteM) sub);
8514       i = CommandItem (sub, "Single Sequence", TestUpdateSequenceIndexer);
8515       SetObjectExtra (i, bfp, NULL);
8516       i = CommandItem (sub, "Single Sequence (from clipboard)", TestUpdateSequenceClipboardIndexer);
8517       SetObjectExtra (i, bfp, NULL);
8518       if (useEntrez) {
8519         i = CommandItem (sub, "Download Accession", UpdateSequenceViaDownloadIndexer);
8520         SetObjectExtra (i, bfp, NULL);
8521       }
8522       i = CommandItem (sub, "Multiple Sequences", TestUpdateSequenceSetIndexer);
8523       SetObjectExtra (i, bfp, NULL);
8524       i = CommandItem (sub, "Multiple Sequences (from clipboard)", TestUpdateSequenceSetClipboardIndexer);
8525       SetObjectExtra (i, bfp, NULL);
8526 
8527       /* public version */
8528       sub = SubMenu (m, "Public Update Sequence");
8529       i = CommandItem (sub, "Single Sequence", TestUpdateSequenceSubmitter);
8530       SetObjectExtra (i, bfp, NULL);
8531       if (useEntrez) {
8532         i = CommandItem (sub, "Download Accession", UpdateSequenceViaDownloadSubmitter);
8533         SetObjectExtra (i, bfp, NULL);
8534       }
8535       i = CommandItem (sub, "Multiple Sequences", TestUpdateSequenceSetSubmitter);
8536       SetObjectExtra (i, bfp, NULL);
8537 
8538       SeparatorItem (m);
8539     }
8540     else
8541     {
8542       sub = SubMenu (m, "Update Sequence");
8543       SetFormMenuItem (bfp, mssgupd, (IteM) sub);
8544       i = CommandItem (sub, "Single Sequence", TestUpdateSequenceSubmitter);
8545       SetObjectExtra (i, bfp, NULL);
8546       if (useEntrez) {
8547         i = CommandItem (sub, "Download Accession", UpdateSequenceViaDownloadSubmitter);
8548         SetObjectExtra (i, bfp, NULL);
8549       }
8550       i = CommandItem (sub, "Multiple Sequences", TestUpdateSequenceSetSubmitter);
8551       SetObjectExtra (i, bfp, NULL);
8552     }
8553 
8554     SeparatorItem (m);
8555     i = CommandItem (m, "Feature Propagate...", NewFeaturePropagate);
8556     SetObjectExtra (i, bfp, NULL);
8557     SetFormMenuItem (bfp, mssgfeatprop, i);
8558     SeparatorItem (m);
8559     sub = SubMenu (m, "Add Sequence");
8560     SetFormMenuItem (bfp, mssgadd, (IteM) sub);
8561     i = CommandItem (sub, "Add FASTA File...", AddSeqWithFASTA);
8562     SetObjectExtra (i, bfp, NULL);
8563     i = CommandItem (sub, "Add Sequence Record...", AddSeqWithRec);
8564     SetObjectExtra (i, bfp, NULL);
8565     if (! extraServices) {
8566       SeparatorItem (m);
8567       i = CommandItem (m, "Parse File to Source", ParseFileToSource);
8568       SetObjectExtra (i, bfp, NULL);
8569     }
8570 
8571     m = PulldownMenu (w, "Search/ R");
8572     i = CommandItem (m, "Find ASN.1.../ F", FindStringProc);
8573     SetObjectExtra (i, bfp, NULL);
8574     i = CommandItem (m, "Find FlatFile.../ G", FindFlatfileProc);
8575     SetObjectExtra (i, bfp, NULL);
8576     SeparatorItem (m);
8577     i = CommandItem (m, "Find by Gene...", FindGeneProc);
8578     SetObjectExtra (i, bfp, NULL);
8579     i = CommandItem (m, "Find by Protein...", FindProtProc);
8580     SetObjectExtra (i, bfp, NULL);
8581     i = CommandItem (m, "Find by Position...", FindPosProc);
8582     SetObjectExtra (i, bfp, NULL);
8583     SeparatorItem (m);
8584     if (indexerVersion) {
8585       sub = SubMenu (m, "Validate/ V");
8586       i = CommandItem (sub, "Validate Record/ R", ValSeqEntryProc);
8587       SetObjectExtra (i, bfp, NULL);
8588       i = CommandItem (sub, "Validate no Alignments/ A", ValSeqEntryProcNoAln);
8589       SetObjectExtra (i, bfp, NULL);
8590       i = CommandItem (sub, "Validate check Inference", ValSeqEntryProcInfAccn);
8591       SetObjectExtra (i, bfp, NULL);
8592       SeparatorItem (sub);
8593       i = CommandItem (sub, "Validate Inst", ValSeqEntryProcInst);
8594       SetObjectExtra (i, bfp, NULL);
8595       i = CommandItem (sub, "Validate Hist", ValSeqEntryProcHist);
8596       SetObjectExtra (i, bfp, NULL);
8597       i = CommandItem (sub, "Validate Context", ValSeqEntryProcContext);
8598       SetObjectExtra (i, bfp, NULL);
8599       i = CommandItem (sub, "Validate Graph", ValSeqEntryProcGraph);
8600       SetObjectExtra (i, bfp, NULL);
8601       i = CommandItem (sub, "Validate Set", ValSeqEntryProcSet);
8602       SetObjectExtra (i, bfp, NULL);
8603       i = CommandItem (sub, "Validate Feat", ValSeqEntryProcFeat);
8604       SetObjectExtra (i, bfp, NULL);
8605       i = CommandItem (sub, "Validate Desc", ValSeqEntryProcDesc);
8606       SetObjectExtra (i, bfp, NULL);
8607     } else {
8608       i = CommandItem (m, "Validate/ V", ValSeqEntryProc);
8609       SetObjectExtra (i, bfp, NULL);
8610     }
8611 /*#ifdef USE_BLAST*/
8612     /*
8613     if (useBlast) {
8614       SeparatorItem (m);
8615       if (extraServices) {
8616         sub = SubMenu (m, "CDD Search");
8617         i = CommandItem (sub, "Features", SimpleCDDSearchFeatProc);
8618         SetObjectExtra (i, bfp, NULL);
8619         i = CommandItem (sub, "Alignments", SimpleCDDSearchAlignProc);
8620         SetObjectExtra (i, bfp, NULL);
8621       } else {
8622         i = CommandItem (m, "CDD Search", SimpleCDDSearchFeatProc);
8623         SetObjectExtra (i, bfp, NULL);
8624       }
8625     }
8626     */
8627 /*#endif*/
8628     SeparatorItem (m);
8629     sub = SubMenu (m, "Vector Screen");
8630     i = CommandItem (sub, "UniVec", SimpleUniVecScreenProc);
8631     SetObjectExtra (i, bfp, NULL);
8632     if (indexerVersion) {
8633       i = CommandItem (sub, "UniVec Core", SimpleUniVecCoreScreenProc);
8634       SetObjectExtra (i, bfp, NULL);
8635     }
8636     i = CommandItem (sub, "Vector Search & Trim Tool", ExternalVecScreenTool);
8637     SetObjectExtra (i, bfp, NULL);
8638     SeparatorItem (m);
8639     i = CommandItem (m, "ORF Finder...", FindOrf);
8640     SetObjectExtra (i, bfp, NULL);
8641 #if USE_FINDALU
8642     i = CommandItem (m, "Repeat Finder...", FindAlu);
8643     SetObjectExtra (i, bfp, NULL);
8644 #endif
8645     SeparatorItem (m);
8646     i = CommandItem (m, "Select Target...", DoChangeTarget);
8647     SetObjectExtra (i, bfp, NULL);
8648 
8649     /*
8650     if (! indexerVersion) {
8651       m = PulldownMenu (w, "Options");
8652       sub = SubMenu (m, "Font Selection");
8653       i = CommandItem (sub, "Display Font...", DisplayFontChangeProc);
8654       SetObjectExtra (i, bfp, NULL);
8655       SeparatorItem (m);
8656       CreateLegendItem (m, bfp);
8657     }
8658     */
8659 
8660 /*#ifdef EXTRA_SERVICES*/
8661     if (extraServices) {
8662       m = PulldownMenu (w, "Special/ S");
8663       SetupSpecialMenu (m, bfp);
8664       m = PulldownMenu (w, "Projects");
8665       MakeSpecialProjectsMenu (m, bfp);
8666     }
8667 /*#endif*/
8668 
8669     m = PulldownMenu (w, "Misc");
8670 #if USE_STYLE_MANAGER
8671     CommandItem (m, "Style Manager...", StyleManagerProc);
8672     SeparatorItem (m);
8673 #endif
8674     CommandItem (m, "Net Configure...", NetConfigureProc);
8675     if (useEntrez) {
8676       /*
8677       SeparatorItem (m);
8678       CommandItem (m, "Entrez2 Query...", Entrez2QueryProc);
8679       */
8680 /*
8681 #ifndef WIN16
8682       if (BiostrucAvail ()) {
8683         SeparatorItem (m);
8684         CommandItem (m, "Cn3D Window...", Cn3DWinShowProc);
8685       }
8686 #endif
8687 */
8688     }
8689     if (useDesktop) {
8690       SeparatorItem (m);
8691       VSMAddToMenu (m, VSM_DESKTOP);
8692     }
8693 
8694     CreateAnalysisMenu (w, bfp, TRUE, FALSE);
8695 
8696     m = PulldownMenu (w, "Annotate/ A");
8697     SetupNewFeaturesMenu (m, bfp);
8698     SeparatorItem (m);
8699     sub = SubMenu (m, "Batch Feature Apply");
8700     SetupBatchApplyMenu (sub, bfp);
8701     sub = SubMenu (m, "Batch Feature Edit");
8702     SetupBatchEditMenu (sub, bfp);
8703     i = CommandItem (m, "Batch Apply Molecule Type", ExternalApplyMoleculeType);
8704     SetObjectExtra (i, bfp, NULL);
8705     i = CommandItem (m, "Batch Apply Genetic Code", BatchApplyGeneticCode);
8706     SetObjectExtra (i, bfp, NULL);
8707     i = CommandItem (m, "Add Keyword", ApplyKeywordWithStringConstraint);
8708     SetObjectExtra (i, bfp, NULL);
8709     i = CommandItem (m, "Set Release Date", SetReleaseDate);
8710     SetObjectExtra (i, bfp, NULL);
8711     SeparatorItem (m);
8712     i = CommandItem (m, "ORF Finder", FindOrf);
8713     SetObjectExtra (i, bfp, NULL);
8714     i = CommandItem (m, "Import Source Table", ParseFileToSource);
8715     SetObjectExtra (i, bfp, NULL);
8716     SeparatorItem (m);
8717     sub = SubMenu (m, "Publications");
8718     SetupNewPublicationsMenu (sub, bfp);
8719     SeparatorItem (m);
8720     sub = SubMenu (m, "Descriptors");
8721     SetupNewDescriptorsMenu (sub, bfp);
8722     SeparatorItem (m);
8723     sub = SubMenu (m, "Advanced Table Readers");
8724     i = CommandItem (sub, "Load Structured Comments from Table", SubmitterCreateStructuredComments);
8725     SetObjectExtra (i, bfp, NULL);
8726     i = CommandItem (m, "Sort Unique Count By Group", SUCSubmitterProc);
8727     SetObjectExtra (i, bfp, NULL);
8728 
8729     if (indexerVersion) {
8730       m = PulldownMenu (w, "Options");
8731       sub = SubMenu (m, "Font Selection");
8732       i = CommandItem (sub, "Display Font...", DisplayFontChangeProc);
8733       SetObjectExtra (i, bfp, NULL);
8734       /*
8735       SeparatorItem (m);
8736       CreateLegendItem (m, bfp);
8737       */
8738       SeparatorItem (m);
8739       sub = SubMenu (m, "Layout Override");
8740       CreateNewLayoutMenu (sub, bfp);
8741     }
8742   }
8743 }
8744 #endif
8745 
GetRidCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)8746 static void GetRidCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
8747 
8748 {
8749   BioseqPtr     bsp;
8750   BioseqSetPtr  bssp;
8751   SeqAnnotPtr   nextsap;
8752   Pointer PNTR  prevsap;
8753   SeqAnnotPtr   sap;
8754 
8755   if (sep == NULL || sep->data.ptrvalue == NULL) return;
8756   if (IS_Bioseq (sep)) {
8757     bsp = (BioseqPtr) sep->data.ptrvalue;
8758     sap = bsp->annot;
8759     prevsap = (Pointer PNTR) &(bsp->annot);
8760   } else if (IS_Bioseq_set (sep)) {
8761     bssp = (BioseqSetPtr) sep->data.ptrvalue;
8762     sap = bssp->annot;
8763     prevsap = (Pointer PNTR) &(bssp->annot);
8764   } else return;
8765   while (sap != NULL) {
8766     nextsap = sap->next;
8767     if (sap->data == NULL) {
8768       *(prevsap) = sap->next;
8769       sap->next = NULL;
8770       SeqAnnotFree (sap);
8771     } else {
8772       prevsap = (Pointer PNTR) &(sap->next);
8773     }
8774     sap = nextsap;
8775   }
8776 }
8777 
GetRidOfEmptyAnnotTables(Uint2 entityID)8778 static void GetRidOfEmptyAnnotTables (Uint2 entityID)
8779 
8780 {
8781   SeqEntryPtr  sep;
8782 
8783   if (entityID < 1) return;
8784   sep = GetTopSeqEntryForEntityID (entityID);
8785   if (sep == NULL) return;
8786   SeqEntryExplore (sep, NULL, GetRidCallback);
8787 }
8788 
8789 static CharPtr deleteProtMsg =
8790 "The protein product of a CDS (shown in the /translation qualifier)\n\
8791 is actually a separate data element in the record.  Unless explicitly\n\
8792 deleted, it will remain hidden in the record after you delete the CDS.";
8793 
8794 static CharPtr deleteGeneMsg =
8795 "The /gene qualifier is generated from an overlapping gene feature.\n\
8796 If you delete a CDS you may also want to delete this separate gene.";
8797 
8798 static CharPtr deleteCdnaMsg =
8799 "The cDNA product of an mRNA is actually a separate data element\n\
8800 in the record.  Unless explicitly deleted, it will remain hidden\n\
8801 in the record after you delete the mRNA.";
8802 
8803 typedef struct deletecdsoptions {
8804   Boolean delete_feature;
8805   Boolean delete_gene;
8806   Boolean delete_cdna;
8807   Boolean delete_protein;
8808 } DeleteCDSOptionsData, PNTR DeleteCDSOptionsPtr;
8809 
GetDeleteCDSOptions(DeleteCDSOptionsPtr dcop)8810 static void GetDeleteCDSOptions (DeleteCDSOptionsPtr dcop)
8811 {
8812   WindoW w;
8813   GrouP  h, g, c;
8814   ButtoN b;
8815   ModalAcceptCancelData acd;
8816   ButtoN delete_gene = NULL;
8817   ButtoN delete_cdna = NULL;
8818   ButtoN delete_protein = NULL;
8819 
8820   if (dcop == NULL) return;
8821   if (!dcop->delete_gene
8822       && !dcop->delete_cdna
8823       && !dcop->delete_protein) {
8824     return;
8825   }
8826 
8827   acd.accepted = FALSE;
8828   acd.cancelled = FALSE;
8829 
8830   w = ModalWindow(-20, -13, -10, -10, NULL);
8831   h = HiddenGroup (w, -1, 0, NULL);
8832   SetGroupSpacing (h, 10, 10);
8833 
8834   g = HiddenGroup (h, 2, 0, NULL);
8835   SetGroupSpacing (g, 10, 10);
8836   if (dcop->delete_gene) {
8837     delete_gene = CheckBox (g, "Delete overlapping gene", NULL);
8838     MultiLinePrompt (g, deleteGeneMsg, 30 * stdCharWidth, systemFont);
8839   }
8840 
8841   if (dcop->delete_cdna) {
8842     delete_cdna = CheckBox (g, "Delete cDNA", NULL);
8843     SetStatus (delete_cdna, TRUE);
8844     MultiLinePrompt (g, deleteCdnaMsg, 30 * stdCharWidth, systemFont);
8845   }
8846 
8847   if (dcop->delete_protein) {
8848     delete_protein = CheckBox (g, "Delete protein product", NULL);
8849     SetStatus (delete_protein, TRUE);
8850     MultiLinePrompt (g, deleteProtMsg, 30 * stdCharWidth, systemFont);
8851   }
8852 
8853   c = HiddenGroup (h, 3, 0, NULL);
8854   SetGroupSpacing (c, 10, 10);
8855   b = PushButton (c, "Accept", ModalAcceptButton);
8856   SetObjectExtra (b, &acd, NULL);
8857   b = PushButton (c, "Cancel", ModalCancelButton);
8858   SetObjectExtra (b, &acd, NULL);
8859   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
8860 
8861   Show(w);
8862   Select (w);
8863   while (!acd.accepted && ! acd.cancelled)
8864   {
8865     ProcessExternalEvent ();
8866     Update ();
8867   }
8868   ProcessAnEvent ();
8869   Remove (w);
8870   if (acd.accepted)
8871   {
8872     dcop->delete_feature = TRUE;
8873     dcop->delete_gene = delete_gene == NULL ? FALSE : GetStatus (delete_gene);
8874     dcop->delete_cdna = delete_cdna == NULL ? FALSE : GetStatus (delete_cdna);
8875     dcop->delete_protein = delete_protein == NULL ? FALSE : GetStatus (delete_protein);
8876   }
8877   else
8878   {
8879     dcop->delete_feature = FALSE;
8880     dcop->delete_gene = FALSE;
8881     dcop->delete_cdna = FALSE;
8882     dcop->delete_protein = FALSE;
8883   }
8884 }
8885 
DeleteSelectedFeatureOrDescriptor(GatherContextPtr gcp)8886 static Boolean DeleteSelectedFeatureOrDescriptor (GatherContextPtr gcp)
8887 
8888 {
8889   BioseqPtr       bsp;
8890   BioseqPtr       cdna;
8891   Uint2           entityID;
8892   SeqFeatPtr      gene;
8893   Uint4           itemID;
8894   Uint2           itemtype;
8895   BioseqSetPtr    nps;
8896   BioseqSetPtr    parent;
8897   SeqFeatPtr      sfp;
8898   SeqIdPtr        sip;
8899   DeleteCDSOptionsData dcod;
8900   SeqMgrFeatContext    fcontext;
8901   ObjValNodePtr        ovn;
8902   SeqDescrPtr          sdp;
8903 #ifdef USE_SMARTNET
8904   UserObjectPtr   uop;
8905 #endif
8906 
8907   if (gcp->thistype != OBJ_SEQDESC && gcp->thistype != OBJ_SEQFEAT) {
8908     /* This function should only handle descriptors and features */
8909     return FALSE;
8910   } else if (gcp->thisitem == NULL) {
8911     return TRUE;
8912   }
8913 
8914 #ifdef USE_SMARTNET
8915   /* This code will prevent from deletion SMART User Object */
8916 
8917   if(gcp->thistype == OBJ_SEQDESC) {
8918       if((sdp = (SeqDescrPtr) gcp->thisitem) != NULL) {
8919           if(sdp->choice == 14 &&
8920              ((uop = ( UserObjectPtr) sdp->data.ptrvalue) != NULL)) {
8921               if(!StringCmp(uop->_class, SMART_OBJECT_LABEL)) {
8922                   Message(MSG_ERROR, "You may not delete SMART Object Label");
8923                   return TRUE;
8924               }
8925           }
8926       }
8927   }
8928 #endif
8929 
8930   /* delete the descriptor */
8931   if (gcp->thistype == OBJ_SEQDESC) {
8932     sdp = (SeqDescrPtr) gcp->thisitem;
8933     if (sdp != NULL && sdp->extended != 0) {
8934       ovn = (ObjValNodePtr) sdp;
8935       ovn->idx.deleteme = TRUE;
8936       return TRUE;
8937     } else {
8938       return FALSE;
8939     }
8940   }
8941 
8942   /* because it wasn't a descriptor, this must be a feature */
8943   sfp = (SeqFeatPtr) gcp->thisitem;
8944   bsp = NULL;
8945   gene = NULL;
8946   cdna = NULL;
8947   nps = NULL;
8948   entityID = gcp->entityID;
8949   itemID = gcp->itemID;
8950   itemtype = gcp->thistype;
8951 
8952   /* When deleting some features, there are other objects that the user may wish to
8953    * remove at the same time.
8954    * When removing a coding region, the user may wish to also do the following:
8955    *   1) Remove the overlapping gene
8956    *   2) Remove the product protein
8957    * When removing an mRNA, the user may wish to also do the following:
8958    *   1) Remove the cDNA product
8959    *   2) Remove the nucprotset parent
8960    */
8961   if (sfp->idx.subtype == FEATDEF_mRNA && sfp->product != NULL) {
8962     sip = SeqLocId (sfp->product);
8963     if (sip != NULL) {
8964       cdna = BioseqFind (sip);
8965       if (cdna != NULL) {
8966         if (cdna->idx.parenttype == OBJ_BIOSEQSET) {
8967           parent = (BioseqSetPtr) cdna->idx.parentptr;
8968           while (parent != NULL) {
8969             if (parent->_class == BioseqseqSet_class_nuc_prot) {
8970               nps = parent;
8971             }
8972             if (parent->idx.parenttype == OBJ_BIOSEQSET) {
8973               parent = (BioseqSetPtr) parent->idx.parentptr;
8974             } else {
8975               parent = NULL;
8976             }
8977           }
8978         }
8979       }
8980     }
8981   } else if (sfp->idx.subtype == FEATDEF_CDS) {
8982     if (sfp->product != NULL) {
8983       sip = SeqLocId (sfp->product);
8984       if (sip != NULL) {
8985         bsp = BioseqFind (sip);
8986       }
8987     }
8988     if (SeqMgrGetGeneXref(sfp) == NULL) {
8989       gene = SeqMgrGetOverlappingGene (sfp->location, &fcontext);
8990     }
8991   }
8992 
8993   MemSet (&dcod, 0, sizeof (dcod));
8994   if (sfp != NULL) {
8995     dcod.delete_feature = TRUE;
8996   }
8997   if (nps != NULL || cdna != NULL) {
8998     dcod.delete_cdna = TRUE;
8999   }
9000   if (bsp != NULL) {
9001     dcod.delete_protein = TRUE;
9002   }
9003 
9004   if (gene != NULL) {
9005     dcod.delete_gene = TRUE;
9006   }
9007 
9008   GetDeleteCDSOptions (&dcod);
9009   if (!dcod.delete_feature) {
9010     return TRUE;
9011   }
9012 
9013 
9014   /* delete the feature */
9015   sfp->idx.deleteme = TRUE;
9016 
9017   /* delete cdna product */
9018   if (dcod.delete_cdna) {
9019     if (nps != NULL) {
9020       nps->idx.deleteme = TRUE;
9021     } else if (cdna != NULL) {
9022       cdna->idx.deleteme = TRUE;
9023     }
9024   }
9025 
9026   /* delete protein product */
9027   if (bsp != NULL && dcod.delete_protein) {
9028     bsp->idx.deleteme = TRUE;
9029   }
9030 
9031   /* delete overlapping gene */
9032   if (gene != NULL && dcod.delete_gene) {
9033     gene->idx.deleteme = TRUE;
9034   }
9035 
9036   /* Note - delete marked objects is called by the calling function */
9037 
9038   return TRUE;
9039 }
9040 
SequinMedlineFormMessage(ForM f,Int2 mssg)9041 static void SequinMedlineFormMessage (ForM f, Int2 mssg)
9042 
9043 {
9044   BaseFormPtr  bfp;
9045 
9046   bfp = (BaseFormPtr) GetObjectExtra (f);
9047   if (bfp != NULL) {
9048     switch (mssg) {
9049       case VIB_MSG_CLOSE :
9050         Remove (f);
9051         break;
9052       case VIB_MSG_QUIT :
9053         QuitProc ();
9054         break;
9055       default :
9056         break;
9057     }
9058   }
9059 }
9060 
9061 typedef struct seltbl {
9062   size_t             count;
9063   SelStructPtr PNTR  selarray;
9064   Boolean            geneasked;
9065   Boolean            productasked;
9066   Boolean            removegene;
9067   Boolean            removeproduct;
9068 } SelTbl, PNTR SelTblPtr;
9069 
MarkSelectedItem(GatherObjectPtr gop)9070 static Boolean MarkSelectedItem (GatherObjectPtr gop)
9071 
9072 {
9073   Int2           L, R, mid;
9074   SelStructPtr   ssp;
9075   SelTblPtr      tbl;
9076   MsgAnswer      ans;
9077   BioseqPtr      bsp;
9078   ObjValNodePtr  ovn;
9079   SeqAlignPtr    sap;
9080   SeqDescrPtr    sdp;
9081   SeqFeatPtr     sfp, gene;
9082   SeqGraphPtr    sgp;
9083 
9084   if (gop == NULL) return TRUE;
9085   tbl = (SelTblPtr) gop->userdata;
9086   if (tbl == NULL) return TRUE;
9087 
9088   L = 0;
9089   R = tbl->count - 1;
9090   while (L <= R) {
9091     mid = (L + R) / 2;
9092     ssp = tbl->selarray [mid];
9093     if (ssp == NULL) return TRUE;
9094     if (ssp->entityID > gop->entityID) {
9095       R = mid - 1;
9096     } else if (ssp->entityID < gop->entityID) {
9097       L = mid + 1;
9098     } else if (ssp->itemtype > gop->itemtype) {
9099       R = mid - 1;
9100     } else if (ssp->itemtype < gop->itemtype) {
9101       L = mid + 1;
9102     } else if (ssp->itemID > gop->itemID) {
9103       R = mid - 1;
9104     } else if (ssp->itemID < gop->itemID) {
9105       L = mid + 1;
9106     } else if (gop->dataptr != NULL &&
9107                ssp->entityID == gop->entityID &&
9108                ssp->itemtype == gop->itemtype &&
9109                ssp->itemID == gop->itemID) {
9110       switch (gop->itemtype) {
9111         case OBJ_SEQDESC :
9112           sdp = (SeqDescrPtr) gop->dataptr;
9113           if (sdp != NULL && sdp->extended != 0) {
9114             ovn = (ObjValNodePtr) sdp;
9115             ovn->idx.deleteme = TRUE;
9116           }
9117           break;
9118         case OBJ_SEQFEAT :
9119           sfp = (SeqFeatPtr) gop->dataptr;
9120           if (sfp != NULL) {
9121             sfp->idx.deleteme = TRUE;
9122             if (SeqMgrGetGeneXref (sfp) == NULL) {
9123               gene = SeqMgrGetOverlappingGene (sfp->location, NULL);
9124               if (gene != NULL) {
9125                 if (! tbl->geneasked) {
9126                   ans = Message (MSG_YN, "Remove overlapping gene?");
9127                   if (ans == ANS_YES) {
9128                     tbl->removegene = TRUE;
9129                   }
9130                   tbl->geneasked = TRUE;
9131                 }
9132                 if (tbl->removegene) {
9133                   gene->idx.deleteme = TRUE;
9134                 }
9135               }
9136             }
9137             if (sfp->data.choice == SEQFEAT_CDREGION) {
9138               bsp = BioseqFind (SeqLocId (sfp->product));
9139               if (bsp != NULL) {
9140                 if (! tbl->productasked) {
9141                   ans = Message (MSG_YN, "Remove protein products?");
9142                   if (ans == ANS_YES) {
9143                     tbl->removeproduct = TRUE;
9144                   }
9145                   tbl->productasked = TRUE;
9146                 }
9147                 if (tbl->removeproduct) {
9148                   bsp->idx.deleteme = TRUE;
9149                 }
9150               }
9151             }
9152           }
9153           break;
9154         case OBJ_SEQALIGN :
9155           sap = (SeqAlignPtr) gop->dataptr;
9156           if (sap != NULL) {
9157             sap->idx.deleteme = TRUE;
9158           }
9159           break;
9160         case OBJ_SEQGRAPH :
9161           sgp = (SeqGraphPtr) gop->dataptr;
9162           if (sgp != NULL) {
9163             sgp->idx.deleteme = TRUE;
9164           }
9165           break;
9166         default :
9167           break;
9168       }
9169       return TRUE;
9170     }
9171   }
9172 
9173   return TRUE;
9174 }
9175 
SortSelStructByIDs(VoidPtr ptr1,VoidPtr ptr2)9176 static int LIBCALLBACK SortSelStructByIDs (VoidPtr ptr1, VoidPtr ptr2)
9177 
9178 {
9179   SelStructPtr  ssp1, ssp2;
9180 
9181   if (ptr1 == NULL || ptr2 == NULL) return 0;
9182   ssp1 = *((SelStructPtr PNTR) ptr1);
9183   ssp2 = *((SelStructPtr PNTR) ptr2);
9184   if (ssp1 == NULL || ssp2 == NULL) return 0;
9185 
9186   if (ssp1->entityID > ssp2->entityID) return 1;
9187   if (ssp1->entityID < ssp2->entityID) return -1;
9188 
9189   if (ssp1->itemtype > ssp2->itemtype) return 1;
9190   if (ssp1->itemtype < ssp2->itemtype) return -1;
9191 
9192   if (ssp1->itemID > ssp2->itemID) return 1;
9193   if (ssp1->itemID < ssp2->itemID) return -1;
9194 
9195   return 0;
9196 }
9197 
DeleteMultipleSelections(Uint2 entityID,SelStructPtr selhead)9198 static void DeleteMultipleSelections (Uint2 entityID, SelStructPtr selhead)
9199 
9200 {
9201   size_t             count;
9202   SelStructPtr       sel;
9203   SelStructPtr PNTR  selarray;
9204   SelTbl             tbl;
9205 
9206   if (entityID < 1 || selhead == NULL) return;
9207 
9208   for (count = 0, sel = selhead; sel != NULL; sel = sel->next, count++) continue;
9209   if (count < 1) return;
9210 
9211   selarray = (SelStructPtr PNTR) MemNew (sizeof (SelStructPtr) * (size_t) (count + 1));
9212   if (selarray == NULL) return;
9213   for (count = 0, sel = selhead; sel != NULL; sel = sel->next, count++) {
9214     selarray [count] = sel;
9215   }
9216 
9217   HeapSort (selarray, (size_t) count, sizeof (SelStructPtr), SortSelStructByIDs);
9218 
9219   MemSet ((Pointer) &tbl, 0, sizeof (tbl));
9220   tbl.count = count;
9221   tbl.selarray = selarray;
9222 
9223   GatherObjectsInEntity (entityID, 0, NULL, MarkSelectedItem, (Pointer) &tbl, NULL);
9224 
9225   MemFree (selarray);
9226   DeleteMarkedObjects (entityID, 0, NULL);
9227 }
9228 
9229 
ClearSelectedItem(BaseFormPtr bfp)9230 NLM_EXTERN void ClearSelectedItem (BaseFormPtr bfp)
9231 {
9232   SelStructPtr  sel;
9233   MsgAnswer     ans;
9234   BioseqPtr     bsp;
9235   SeqIdPtr      sip;
9236   SeqEntryPtr   sep;
9237   Uint4         entityID;
9238   OMProcControl ompc;
9239 
9240   sel = ObjMgrGetSelected ();
9241   if (sel != NULL) {
9242     if (sel->itemtype == OBJ_BIOSEQ && sel->next == NULL) {
9243       if (! indexerVersion) {
9244         ans = Message (MSG_OKC, "Are you sure you want to delete this Bioseq?");
9245         if (ans == ANS_CANCEL) return;
9246         ans = Message (MSG_OKC, "Are you REALLY sure you want to delete this Bioseq?");
9247         if (ans == ANS_CANCEL) return;
9248       }
9249       bsp = GetBioseqGivenIDs (sel->entityID, sel->itemID, sel->itemtype);
9250       sip = SeqIdDup (bsp->id);
9251       entityID = sel->entityID;
9252       MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
9253       ompc.do_not_reload_from_cache = TRUE;
9254       ompc.input_entityID = sel->entityID;
9255       ompc.input_itemID = sel->itemID;
9256       ompc.input_itemtype = sel->itemtype;
9257       if (! DetachDataForProc (&ompc, FALSE)) {
9258         Message (MSG_ERROR, "DetachDataForProc failed");
9259       }
9260       sep = GetTopSeqEntryForEntityID (entityID);
9261       SeqAlignBioseqDeleteByIdFromSeqEntry (sep, sip);
9262       SeqIdFree (sip);
9263       /* see VSeqMgrDeleteProc - probably leaving one dangling SeqEntry */
9264       BioseqFree (bsp);
9265       ObjMgrSetDirtyFlag (entityID, TRUE);
9266       ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
9267       ObjMgrDeSelect (0, 0, 0, 0, NULL);
9268       Update ();
9269     }
9270     if (sel->itemtype == OBJ_SEQANNOT && sel->next == NULL && extraServices) {
9271       entityID = sel->entityID;
9272       MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
9273       ompc.do_not_reload_from_cache = TRUE;
9274       ompc.input_entityID = sel->entityID;
9275       ompc.input_itemID = sel->itemID;
9276       ompc.input_itemtype = sel->itemtype;
9277       if (! DetachDataForProc (&ompc, FALSE)) {
9278         Message (MSG_ERROR, "DetachDataForProc failed");
9279       }
9280       ObjMgrSetDirtyFlag (entityID, TRUE);
9281       ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
9282       ObjMgrDeSelect (0, 0, 0, 0, NULL);
9283       Update ();
9284     }
9285     if (sel->next == NULL && (sel->itemtype == OBJ_SEQDESC || sel->itemtype == OBJ_SEQFEAT)) {
9286       entityID = sel->entityID;
9287       GatherItem (sel->entityID, sel->itemID, sel->itemtype,
9288                   NULL, DeleteSelectedFeatureOrDescriptor);
9289       DeleteMarkedObjects (entityID, 0, NULL);
9290       GetRidOfEmptyAnnotTables (entityID);
9291       sep = GetTopSeqEntryForEntityID (entityID);
9292       RenormalizeNucProtSets (sep, TRUE);
9293       ObjMgrSetDirtyFlag (entityID, TRUE);
9294       ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
9295       ObjMgrDeSelect (0, 0, 0, 0, NULL);
9296       Update ();
9297     } else {
9298       /* Message (MSG_OK, "Unable to delete multiple objects"); */
9299       ans = Message (MSG_YN, "Are you sure you want to delete multiple objects?");
9300       if (ans == ANS_NO) return;
9301       entityID = bfp->input_entityID;
9302       DeleteMultipleSelections (entityID, sel);
9303       GetRidOfEmptyAnnotTables (entityID);
9304       sep = GetTopSeqEntryForEntityID (entityID);
9305       RenormalizeNucProtSets (sep, TRUE);
9306       ObjMgrSetDirtyFlag (entityID, TRUE);
9307       ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
9308       ObjMgrDeSelect (0, 0, 0, 0, NULL);
9309     }
9310   } else {
9311     Message (MSG_OK, "Nothing selected");
9312   }
9313 }
9314 
9315 
SequinSeqViewFormMessage(ForM f,Int2 mssg)9316 extern void SequinSeqViewFormMessage (ForM f, Int2 mssg)
9317 
9318 {
9319   BaseFormPtr   bfp;
9320   BioseqPtr     bsp;
9321   Uint4         itemID;
9322   Int2          mssgalign;
9323   Int2          mssgdelete;
9324   Int2          mssgdup;
9325   Int2          mssgseq;
9326   Int2          mssgsub;
9327   SeqEntryPtr   oldsep;
9328   SeqAnnotPtr   sap;
9329   SelStructPtr  sel;
9330   SeqEntryPtr   sep;
9331 
9332   bfp = (BaseFormPtr) GetObjectExtra (f);
9333   if (bfp != NULL) {
9334     switch (mssg) {
9335       case VIB_MSG_SAVE :
9336         if (FixSpecialCharacters (bfp->input_entityID))
9337         {
9338           SaveSeqSubmitProc (bfp, FALSE);
9339         }
9340         break;
9341       case VIB_MSG_SAVE_AS :
9342         if (FixSpecialCharacters (bfp->input_entityID))
9343         {
9344           SaveSeqSubmitProc (bfp, TRUE);
9345         }
9346         break;
9347       case VIB_MSG_CLOSE :
9348         CloseProc (bfp);
9349         break;
9350       case VIB_MSG_QUIT :
9351         QuitProc ();
9352         break;
9353       case VIB_MSG_ACCEPT :
9354         ProcessDoneButton (f);
9355         break;
9356       case VIB_MSG_RESET :
9357 #ifdef USE_SMARTNET
9358         SmartResetProc ((IteM)f);
9359 #endif
9360         break;
9361       case VIB_MSG_IMPORT :
9362         /* ReadFastaProc (); */
9363         break;
9364       case VIB_MSG_CUT :
9365         break;
9366       case VIB_MSG_COPY :
9367         break;
9368       case VIB_MSG_UNDO :
9369         if (subtoolMode || smartnetMode || backupMode) {
9370           if (FileLength (SEQUIN_EDIT_PREV_FILE) > 0) {
9371             sep = GetTopSeqEntryForEntityID (subtoolEntityID);
9372             if (Message (MSG_YN, "Restore from backup?") == ANS_YES) {
9373               oldsep = RestoreFromFile (SEQUIN_EDIT_PREV_FILE);
9374               ReplaceSeqEntryWithSeqEntry (sep, oldsep, TRUE);
9375               subtoolEntityID = ObjMgrGetEntityIDForChoice (sep);
9376               ObjMgrSetDirtyFlag (subtoolEntityID, TRUE);
9377               ObjMgrSendMsg (OM_MSG_UPDATE, subtoolEntityID, 0, 0);
9378             }
9379           }
9380         }
9381         break;
9382       case VIB_MSG_PASTE :
9383         break;
9384       case VIB_MSG_DELETE :
9385         ClearSelectedItem (bfp);
9386         break;
9387       case VIB_MSG_CHANGE :
9388         EnableFeaturesPerTarget (bfp);
9389         EnableAnalysisItems (bfp, FALSE);
9390         EnableEditSeqAlignAndSubItems (bfp);
9391         break;
9392       case VIB_MSG_SELECT :
9393         EnableEditAlignItem (bfp);
9394         break;
9395       default :
9396         mssgseq = RegisterFormMenuItemName ("SequinEditSequenceItem");
9397         mssgalign = RegisterFormMenuItemName ("SequinEditAlignmentItem");
9398         mssgdelete = RegisterFormMenuItemName ("SequinDeleteSequencesItem");
9399         mssgsub = RegisterFormMenuItemName ("SequinEditSubmitterItem");
9400         mssgdup = RegisterFormMenuItemName ("SequinDuplicateItem");
9401         if (mssg == mssgseq) {
9402           bsp =  GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
9403           if (bsp != NULL) {
9404             WatchCursor ();
9405             Update ();
9406             SeqEntrySetScope (NULL);
9407             GatherProcLaunch (OMPROC_EDIT, FALSE, bfp->input_entityID, bfp->input_itemID,
9408                               bfp->input_itemtype, 0, 0, bfp->input_itemtype, 0);
9409             ArrowCursor ();
9410             Update ();
9411           }
9412         } else if (mssg == mssgalign) {
9413           sel = ObjMgrGetSelected ();
9414           if (sel != NULL &&
9415               (sel->itemtype == OBJ_SEQALIGN || sel->itemtype == OBJ_SEQHIST_ALIGN)) {
9416             WatchCursor ();
9417             Update ();
9418             SeqEntrySetScope (NULL);
9419             GatherProcLaunch (OMPROC_EDIT, FALSE, sel->entityID, sel->itemID,
9420                               sel->itemtype, 0, 0, sel->itemtype, 0);
9421             ArrowCursor ();
9422             Update ();
9423           } else /* if (sel == NULL) */ {
9424             sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9425             sap  = (SeqAnnotPtr)FindSeqAlignInSeqEntry (sep, OBJ_SEQANNOT);
9426             if (sap) {
9427               itemID = GetItemIDGivenPointer (bfp->input_entityID, OBJ_SEQANNOT, (Pointer)sap);
9428               if (itemID != 0) {
9429                 WatchCursor ();
9430                 Update ();
9431                 SeqEntrySetScope (NULL);
9432                 GatherProcLaunch (OMPROC_EDIT, FALSE, bfp->input_entityID, itemID, OBJ_SEQANNOT, 0, 0, OBJ_SEQANNOT, 0);
9433                 ArrowCursor ();
9434                 Update ();
9435               }
9436             }
9437           }
9438         } else if (mssg == mssgdelete) {
9439           SubmitterRemoveSequencesFromRecordBaseForm (bfp);
9440         } else if (mssg == mssgsub) {
9441           EditSubmitBlock (bfp);
9442         } else if (mssg == mssgdup) {
9443           sel = ObjMgrGetSelected ();
9444           if (sel != NULL &&
9445               (sel->itemtype == OBJ_SEQDESC || sel->itemtype == OBJ_SEQFEAT)) {
9446             stdedprocs.duplicateExisting = TRUE;
9447             WatchCursor ();
9448             Update ();
9449             SeqEntrySetScope (NULL);
9450             GatherProcLaunch (OMPROC_EDIT, FALSE, sel->entityID, sel->itemID,
9451                               sel->itemtype, 0, 0, sel->itemtype, 0);
9452             ArrowCursor ();
9453             Update ();
9454             stdedprocs.duplicateExisting = FALSE;
9455           }
9456         }
9457         break;
9458     }
9459   }
9460 }
9461 
SequinSeqEditFormMessage(ForM f,Int2 mssg)9462 static void SequinSeqEditFormMessage (ForM f, Int2 mssg)
9463 
9464 {
9465   BaseFormPtr  bfp;
9466 
9467   bfp = (BaseFormPtr) GetObjectExtra (f);
9468   if (bfp != NULL) {
9469     switch (mssg) {
9470       case VIB_MSG_QUIT :
9471         QuitProc ();
9472         break;
9473       default :
9474         break;
9475     }
9476   }
9477 }
9478 
9479 /* from salfiles.c */
AccessionToGi(CharPtr string,CharPtr program)9480 static Int4 AccessionToGi (CharPtr string, CharPtr program)
9481 {
9482    /*
9483    CharPtr str;
9484    LinkSetPtr lsp;
9485    Int4 gi;
9486 
9487    EntrezInit (program, TRUE, NULL);
9488    str = MemNew (StringLen (string) + 10);
9489    sprintf (str, "\"%s\" [ACCN]", string);
9490    lsp = EntrezTLEvalString (str, TYP_NT, -1, NULL, NULL);
9491    MemFree (str);
9492    if (lsp == NULL)
9493        return 0;
9494    if (lsp->num <= 0) {
9495        LinkSetFree (lsp);
9496        return 0;
9497    }
9498    gi = lsp->uids [0];
9499    LinkSetFree (lsp);
9500    EntrezFini ();
9501    return gi;
9502    */
9503    return 0;
9504 }
9505 
SeqEdDownload(CharPtr program,CharPtr accession,Int4 uid,Boolean is_na,BoolPtr is_new)9506 static SeqEntryPtr LIBCALLBACK SeqEdDownload (CharPtr program, CharPtr accession,
9507                                               Int4 uid, Boolean is_na, BoolPtr is_new)
9508 
9509 {
9510   BioseqPtr    bsp;
9511   SeqEntryPtr  sep = NULL;
9512   SeqId        sid;
9513   /*
9514   LinkSetPtr   lsp;
9515   Int2         seqtype;
9516   Char         str [64];
9517   */
9518 
9519   if (is_new != NULL) {
9520      *is_new = TRUE;
9521   }
9522 /*********/
9523   if (uid==0 && ! StringHasNoText (accession))
9524     uid = AccessionToGi (accession, program);
9525   if (uid > 0) {
9526     sid.choice = SEQID_GI;
9527     sid.data.intvalue = uid;
9528     sid.next = NULL;
9529     bsp = BioseqFind (&sid);
9530     if (bsp) {
9531       sep = SeqMgrGetSeqEntryForData (bsp);
9532     }
9533   }
9534   if (sep) {
9535     if (is_new != NULL) {
9536       *is_new = FALSE;
9537     }
9538     return sep;
9539   }
9540 /********************/
9541   /*
9542   EntrezInit (program, TRUE, NULL);
9543   if (uid==0 && ! StringHasNoText (accession)) {
9544     if (is_na) {
9545       seqtype = TYP_NT;
9546     } else {
9547       seqtype = TYP_AA;
9548     }
9549     sprintf (str, "\"%s\" [ACCN]", accession);
9550     lsp = EntrezTLEvalString (str, seqtype, -1, NULL, NULL);
9551     if (lsp != NULL) {
9552       uid = lsp->uids [0];
9553     }
9554     LinkSetFree (lsp);
9555   }
9556   if (uid > 0) {
9557     sid.choice = SEQID_GI;
9558     sid.data.intvalue = uid;
9559     sid.next = NULL;
9560     bsp = BioseqLockById (&sid);
9561     if (bsp != NULL) {
9562       sep = SeqMgrGetSeqEntryForData (bsp);
9563       BioseqUnlock (bsp);
9564     } else {
9565       sep = EntrezSeqEntryGet (uid, 0);
9566       if (is_new != NULL) {
9567         *is_new = TRUE;
9568       }
9569     }
9570   }
9571   EntrezFini ();
9572   return sep;
9573   */
9574   return NULL;
9575 }
9576 
SequinStdEditorFormMessage(ForM f,Int2 mssg)9577 static void SequinStdEditorFormMessage (ForM f, Int2 mssg)
9578 
9579 {
9580   BaseFormPtr  bfp;
9581 
9582   bfp = (BaseFormPtr) GetObjectExtra (f);
9583   if (bfp != NULL) {
9584     switch (mssg) {
9585       case VIB_MSG_CLOSE :
9586         Remove (f);
9587         break;
9588       case VIB_MSG_QUIT :
9589         QuitProc ();
9590         break;
9591       case VIB_MSG_CUT :
9592         StdCutTextProc (NULL);
9593         break;
9594       case VIB_MSG_COPY :
9595         StdCopyTextProc (NULL);
9596         break;
9597       case VIB_MSG_PASTE :
9598         StdPasteTextProc (NULL);
9599         break;
9600       case VIB_MSG_DELETE :
9601         StdDeleteTextProc (NULL);
9602         break;
9603       default :
9604         break;
9605     }
9606   }
9607 }
9608 
ProcessHelpMessage(CharPtr heading,CharPtr section)9609 static void ProcessHelpMessage (CharPtr heading, CharPtr section)
9610 
9611 {
9612   SendHelpScrollMessage (helpForm, heading, section);
9613 }
9614 
9615 /*
9616 static void TermSelectionFormMessage (ForM f, Int2 mssg)
9617 
9618 {
9619   BaseFormPtr  bfp;
9620 
9621   bfp = (BaseFormPtr) GetObjectExtra (f);
9622   if (bfp != NULL) {
9623     switch (mssg) {
9624       case VIB_MSG_CLOSE :
9625         Hide (f);
9626         break;
9627       case VIB_MSG_QUIT :
9628         QuitProc ();
9629         break;
9630       default :
9631         break;
9632     }
9633   }
9634 }
9635 
9636 static void MakeTermListForm (void)
9637 
9638 {
9639   if (! EntrezIsInited ()) {
9640     EntrezBioseqFetchEnable ("Sequin", TRUE);
9641     SequinEntrezInit ("Sequin", FALSE, NULL);
9642   }
9643   if (termListForm != NULL) return;
9644   termListForm = CreateTermListForm (-50, -33, "Query",
9645                                      TermSelectionActivateProc,
9646                                      TermSelectionFormMessage);
9647 }
9648 
9649 static void DocumentSummaryFormMessage (ForM f, Int2 mssg)
9650 
9651 {
9652   BaseFormPtr  bfp;
9653 
9654   bfp = (BaseFormPtr) GetObjectExtra (f);
9655   if (bfp != NULL) {
9656     switch (mssg) {
9657       case VIB_MSG_CHANGE :
9658         EnableAnalysisItems (bfp, TRUE);
9659         break;
9660       case VIB_MSG_CLOSE :
9661         Hide (f);
9662         break;
9663       case VIB_MSG_QUIT :
9664         QuitProc ();
9665         break;
9666       default :
9667         break;
9668     }
9669   }
9670 }
9671 
9672 static void MakeDocSumForm (void)
9673 
9674 {
9675   if (! EntrezIsInited ()) {
9676     EntrezBioseqFetchEnable ("Sequin", TRUE);
9677     SequinEntrezInit ("Sequin", FALSE, NULL);
9678   }
9679   if (docSumForm != NULL) return;
9680   docSumForm = CreateDocSumForm (-10, -90, "Document",
9681                                  DocumentSummaryActivateProc,
9682                                  DocumentSummaryFormMessage);
9683   if (indexerVersion) {
9684     UseDelayedNeighbor (docSumForm, TRUE);
9685   }
9686 }
9687 */
9688 
EntrezQueryProc(IteM i)9689 void EntrezQueryProc (IteM i)
9690 
9691 {
9692   /*
9693   MakeTermListForm ();
9694   MakeDocSumForm ();
9695   Show (termListForm);
9696   Select (termListForm);
9697   Update ();
9698   */
9699 }
9700 
9701 #if defined(OS_MAC) || defined(OS_UNIX_DARWIN)
9702 extern Boolean Nlm_LaunchAppEx (CharPtr fileName, VoidPtr serialNumPtr, CharPtr sig);
9703 #endif
9704 
Entrez2QueryProc(IteM i)9705 void Entrez2QueryProc (IteM i)
9706 
9707 {
9708   WatchCursor ();
9709   Update ();
9710 
9711 #if defined(OS_MAC) || defined(OS_UNIX_DARWIN)
9712   Nlm_LaunchAppEx (NULL, NULL, "ENTZ");
9713 #else
9714 #if defined (OS_UNIX) || defined(WIN_MOTIF)
9715   system ("entrez2 &");
9716 #else
9717 #ifdef OS_MSWIN
9718   Nlm_MSWin_OpenApplication ("entrez2.exe", NULL);
9719 #endif
9720 #endif
9721 #endif
9722 
9723   ArrowCursor ();
9724 }
9725 
9726 /*
9727 *  The following callbacks process requests between forms.  This can be extended
9728 *  to have the application track multiple term list and docsum windows.
9729 */
9730 
9731 /*
9732 static void DoRetrieveDocuments (ForM f, Int2 num, Int2 parents, Int4Ptr uids, Int2 db)
9733 
9734 {
9735   if (useEntrez) {
9736     MakeTermListForm ();
9737     MakeDocSumForm ();
9738   }
9739   RetrieveDocuments (docSumForm, num, parents, uids, db);
9740 }
9741 
9742 static void DoRetrieveProject (ForM f, Pointer proj)
9743 
9744 {
9745   if (useEntrez) {
9746     MakeTermListForm ();
9747     MakeDocSumForm ();
9748   }
9749   PointerToForm (docSumForm, proj);
9750 }
9751 
9752 static void DoRetrieveSimple (ForM f, ValNodePtr simpleSeqs)
9753 
9754 {
9755   if (useEntrez) {
9756     MakeTermListForm ();
9757     MakeDocSumForm ();
9758   }
9759   RetrieveSimpleSeqs (docSumForm, simpleSeqs);
9760 }
9761 
9762 static void DoLoadNamedUidList (ForM f, CharPtr term, Int4 num, Int4Ptr uids, Int2 db)
9763 
9764 {
9765   if (useEntrez) {
9766     MakeTermListForm ();
9767     MakeDocSumForm ();
9768   }
9769   LoadNamedUidList (termListForm, term, num, uids, db);
9770 }
9771 
9772 static void DoLaunchRecordViewer (ForM f, Int4 uid, Int2 numAlign, Int4Ptr alignuids, Int2 db)
9773 
9774 {
9775   if (useEntrez) {
9776     MakeTermListForm ();
9777     MakeDocSumForm ();
9778   }
9779   LaunchRecordViewer (uid, numAlign, alignuids, db);
9780 }
9781 
9782 static GrouP DoMakeMedViewerLinkControls (GrouP prnt, BaseFormPtr bfp, Int2 doctype, Int4 uid)
9783 
9784 {
9785   if (useEntrez) {
9786     if (! EntrezIsInited ()) {
9787       EntrezBioseqFetchEnable ("Sequin", TRUE);
9788       SequinEntrezInit ("Sequin", FALSE, NULL);
9789     }
9790     return MakeViewerLinkControls (prnt, bfp, doctype, uid, FALSE);
9791   }
9792   return NULL;
9793 }
9794 
9795 static GrouP DoMakeSeqViewerLinkControls (GrouP prnt, BaseFormPtr bfp, Int2 doctype, Int4 uid)
9796 
9797 {
9798   if (useEntrez) {
9799     if (! EntrezIsInited ()) {
9800       EntrezBioseqFetchEnable ("Sequin", TRUE);
9801       SequinEntrezInit ("Sequin", FALSE, NULL);
9802     }
9803     return MakeViewerLinkControls (prnt, bfp, doctype, uid, TRUE);
9804   }
9805   return NULL;
9806 }
9807 */
9808 
9809 typedef struct aligngroup {
9810   DIALOG_MESSAGE_BLOCK
9811   BaseFormPtr        bfp;
9812   ButtoN             retrieve;
9813   PopuP              target;
9814   Int2               targetDb;
9815   Uint2              align_type;
9816   ButtoN             onlyFromThis;
9817 } AlignGroup, PNTR AlignGroupPtr;
9818 
RetrieveAligns(ButtoN b)9819 static void RetrieveAligns (ButtoN b)
9820 
9821 {
9822   AlignGroupPtr     agp;
9823   BaseFormPtr       bfp;
9824   BioseqPtr         bsp;
9825   EntrezGlobalsPtr  egp;
9826   ValNodePtr        head;
9827   Int2              i;
9828   Int4              num;
9829   SeqEntryPtr       sep;
9830   Int4Ptr           uids;
9831   ValNodePtr        vnp;
9832 
9833   agp = (AlignGroupPtr) GetObjectExtra (b);
9834   if (agp == NULL) return;
9835   bfp = agp->bfp;
9836   if (bfp == NULL) return;
9837   egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
9838   if (egp == NULL || egp->retrieveDocsProc == NULL) return;
9839   /*
9840   if (! EntrezIsInited ()) {
9841     SequinEntrezInit ("Sequin", FALSE, NULL);
9842   }
9843   */
9844   uids = NULL;
9845   sep = NULL;
9846   if (GetStatus (agp->onlyFromThis)) {
9847     bsp =  GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
9848     if (bsp != NULL) {
9849       sep = SeqMgrGetSeqEntryForData (bsp);
9850     }
9851   } else {
9852     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9853   }
9854   head = GetUidsForSeqEntryAligns (sep);
9855   num = 0;
9856   for (vnp = head; vnp != NULL; vnp = vnp->next) {
9857     if (vnp->choice == agp->align_type) {
9858       num++;
9859     }
9860   }
9861   if (num > 0) {
9862     uids = MemNew ((size_t) (num + 1) * sizeof (DocUid));
9863     if (uids != NULL) {
9864       i = 0;
9865       for (vnp = head; i < num && vnp != NULL; vnp = vnp->next) {
9866         if (vnp->choice == agp->align_type) {
9867           uids [i] = vnp->data.intvalue;
9868           i++;
9869         }
9870       }
9871     }
9872     egp->retrieveDocsProc (bfp->form, num, 0, uids, agp->targetDb);
9873     MemFree (uids);
9874   }
9875   ValNodeFree (head);
9876 }
9877 
DoUpdateFetchCounts(GrouP g,SeqEntryPtr sep)9878 static Boolean DoUpdateFetchCounts (GrouP g, SeqEntryPtr sep)
9879 
9880 {
9881   AlignGroupPtr  agp;
9882   BaseFormPtr    bfp;
9883   BioseqPtr      bsp;
9884   ValNodePtr     head;
9885   Int4           num;
9886   Int4           rsult;
9887   Char           tmp [32];
9888   Int2           val;
9889   ValNodePtr     vnp;
9890 
9891   agp = (AlignGroupPtr) GetObjectExtra (g);
9892   if (agp == NULL) return FALSE;
9893   bfp = agp->bfp;
9894   if (bfp == NULL) return FALSE;
9895   val = GetValue (agp->target);
9896   num = 0;
9897   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9898   head = GetIdStringsForSeqEntryAligns (sep);
9899   rsult = ValNodeLen (head);
9900   if (GetStatus (agp->onlyFromThis)) {
9901     head = ValNodeFreeData (head);
9902     bsp =  GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
9903     if (bsp != NULL) {
9904       sep = SeqMgrGetSeqEntryForData (bsp);
9905       head = GetIdStringsForSeqEntryAligns (sep);
9906     }
9907   }
9908   agp->align_type = 0;
9909   agp->targetDb = TYP_NT;
9910   val = GetValue (agp->target);
9911   switch (val) {
9912     case 1 :
9913       agp->align_type = ALIGN_BLASTN;
9914       agp->targetDb = TYP_NT;
9915       break;
9916     case 2 :
9917       agp->align_type = ALIGN_BLASTP;
9918       agp->targetDb = TYP_AA;
9919       break;
9920     case 3 :
9921       agp->align_type = ALIGN_BLASTX;
9922       agp->targetDb = TYP_AA;
9923       break;
9924     case 4 :
9925       agp->align_type = ALIGN_TBLASTN;
9926       agp->targetDb = TYP_NT;
9927       break;
9928     default :
9929       break;
9930   }
9931   num = 0;
9932   for (vnp = head; vnp != NULL; vnp = vnp->next) {
9933     if (vnp->choice == agp->align_type) {
9934       num++;
9935     }
9936   }
9937   ValNodeFreeData (head);
9938   sprintf (tmp, "Retrieve %ld", (long) num);
9939   SafeSetTitle (agp->retrieve, tmp);
9940   if (num > 0) {
9941     SafeEnable (agp->retrieve);
9942   } else {
9943     SafeDisable (agp->retrieve);
9944   }
9945   return (Boolean) (rsult > 0);
9946 }
9947 
ChangeAlignTarget(PopuP p)9948 static void ChangeAlignTarget (PopuP p)
9949 
9950 {
9951   AlignGroupPtr  agp;
9952   BaseFormPtr    bfp;
9953   SeqEntryPtr    sep;
9954 
9955   agp = (AlignGroupPtr) GetObjectExtra (p);
9956   if (agp == NULL) return;
9957   bfp = agp->bfp;
9958   if (bfp == NULL) return;
9959   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9960   DoUpdateFetchCounts ((GrouP) agp->dialog, sep);
9961 }
9962 
DoMakeViewerAlignBtn(GrouP prnt,BaseFormPtr bfp)9963 static GrouP DoMakeViewerAlignBtn (GrouP prnt, BaseFormPtr bfp)
9964 
9965 {
9966   AlignGroupPtr     agp;
9967   EntrezGlobalsPtr  egp;
9968   GrouP             g;
9969   Boolean           macLike;
9970   PrompT            ppt;
9971 
9972   if (useEntrez) {
9973     /*
9974     if (! EntrezIsInited ()) {
9975       SequinEntrezInit ("Sequin", FALSE, NULL);
9976     }
9977     */
9978     egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
9979     if (egp == NULL) return NULL;
9980     macLike = egp->popdownBehavior;
9981 
9982     agp = (AlignGroupPtr) MemNew (sizeof (AlignGroup));
9983     if (agp == NULL) return NULL;
9984 
9985     g = HiddenGroup (prnt, 5, 0, NULL);
9986     SetGroupSpacing (g, 10, 10);
9987     SetObjectExtra (g, agp, StdCleanupExtraProc);
9988 
9989     agp->dialog = (DialoG) g;
9990     agp->bfp = bfp;
9991     agp->retrieve = PushButton (g, "Retrieve 00000", RetrieveAligns);
9992     SetObjectExtra (agp->retrieve, agp, NULL);
9993     SetTitle (agp->retrieve, "Retrieve 0");
9994     SafeDisable (agp->retrieve);
9995 
9996     ppt = StaticPrompt (g, "Alignment:", 0, popupMenuHeight, programFont, 'l');
9997     agp->target = PopupList (g, macLike, (PupActnProc) ChangeAlignTarget);
9998     SetObjectExtra (agp->target, agp, NULL);
9999     PopupItem (agp->target, "BLASTN");
10000     PopupItem (agp->target, "BLASTP");
10001     PopupItem (agp->target, "BLASTX");
10002     PopupItem (agp->target, "TBLASTN");
10003     SetValue (agp->target, 1);
10004 
10005     agp->onlyFromThis = CheckBox (g, "Just from this sequence", (BtnActnProc) ChangeAlignTarget);
10006     SetObjectExtra (agp->onlyFromThis, agp, NULL);
10007     SetStatus (agp->onlyFromThis, TRUE);
10008     SafeHide (agp->onlyFromThis);
10009 
10010     AlignObjects (ALIGN_MIDDLE, (HANDLE) agp->retrieve, (HANDLE) ppt,
10011                   (HANDLE) agp->target, (HANDLE) agp->onlyFromThis, NULL);
10012 
10013     return g;
10014   }
10015   return NULL;
10016 }
10017 
SetupBioseqPageList(void)10018 extern void SetupBioseqPageList (void)
10019 
10020 {
10021   Char  str [32];
10022 
10023   seqviewprocs.pageSpecs = BioseqPageListFree (seqviewprocs.pageSpecs);
10024   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &mapPageData);
10025   /* AddBioseqPageToList (&(seqviewprocs.pageSpecs), &sumPageData); */
10026   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &asn2gphGphPageData);
10027   if (useOldGraphicView) {
10028     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &gphPageData);
10029   }
10030   if (useOldAlignmentView) {
10031     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &alnPageData);
10032   }
10033   /*
10034   if (useUdv) {
10035     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &udvPageData);
10036     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &ddvPageData);
10037   } else {
10038     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &seqPageData);
10039   }
10040   */
10041   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &seqpnlPageData);
10042   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &seqAlnPnlPageData);
10043   if (useOldSequenceView) {
10044     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &seqPageData);
10045   }
10046   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &gbgnPageData);
10047   if (Nlm_GetAppProperty ("SequinUseEMBLStyle") != NULL) {
10048     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &emblPageData);
10049     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &gnbkPageData);
10050     if (GetSequinAppParam ("SETTINGS", "NUCPAGE", "EMBL", str, sizeof (str))) {
10051       seqviewprocs.initNucLabel = MemFree (seqviewprocs.initNucLabel);
10052       seqviewprocs.initNucLabel = StringSaveNoNull (str);
10053     }
10054   } else if (Nlm_GetAppProperty ("SequinUseDDBJStyle") != NULL) {
10055     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &ddbjPageData);
10056     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &emblPageData);
10057     if (GetSequinAppParam ("SETTINGS", "NUCPAGE", "DDBJ", str, sizeof (str))) {
10058       seqviewprocs.initNucLabel = MemFree (seqviewprocs.initNucLabel);
10059       seqviewprocs.initNucLabel = StringSaveNoNull (str);
10060     }
10061   } else {
10062     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &gnbkPageData);
10063     AddBioseqPageToList (&(seqviewprocs.pageSpecs), &emblPageData);
10064     if (GetSequinAppParam ("SETTINGS", "NUCPAGE", "GenBank", str, sizeof (str))) {
10065       seqviewprocs.initNucLabel = MemFree (seqviewprocs.initNucLabel);
10066       seqviewprocs.initNucLabel = StringSaveNoNull (str);
10067     }
10068   }
10069   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &gnptPageData);
10070   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &ftblPageData);
10071   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &fstaPageData);
10072   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &qualPageData);
10073   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &asnPageData);
10074   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &xmlPageData);
10075   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &gbseqPageData);
10076 
10077   AddBioseqPageToList (&(seqviewprocs.pageSpecs), &dskPageData);
10078 }
10079 
SetupDesktop(void)10080 static void SetupDesktop (void)
10081 
10082 {
10083   Boolean     allowalign;
10084   Boolean     cdsMrnaOneToOne;
10085   FeatDefPtr  curr;
10086   Uint1       key;
10087   CharPtr     label = NULL;
10088   Char        proclabel [64];
10089   Char        procname [64];
10090   Boolean     readOnlyDbTags;
10091   Char        str [PATH_MAX];
10092   Uint2       subtype;
10093   Int2        val;
10094   Boolean     validateExons;
10095 
10096   SetAppProperty ("SequinAppVersion", SEQUIN_APPLICATION);
10097 
10098   MemSet ((Pointer) (&medviewprocs), 0, sizeof (MedlineViewProcs));
10099   medviewprocs.cleanupObjectPtr = FALSE;
10100   medviewprocs.activateForm = MedlineViewFormActivated;
10101   medviewprocs.closeForm = NULL;
10102   medviewprocs.useFolderTabs = CHANGE_VIEW_POPUP;
10103   /*
10104   medviewprocs.useFolderTabs = CHANGE_VIEW_RADIOBUTTONS;
10105   medviewprocs.initPage = CITATION_PAGE;
10106   */
10107 #ifndef WIN_MAC
10108   medviewprocs.createMenus = MedlineViewFormMenus;
10109 #endif
10110   medviewprocs.showAsnPage = TRUE;
10111   if (indexerVersion) {
10112     medviewprocs.useScrollText = TRUE;
10113   } else {
10114     medviewprocs.useScrollText = FALSE;
10115   }
10116   medviewprocs.handleMessages = SequinMedlineFormMessage;
10117   /*
10118   medviewprocs.makeControls = DoMakeMedViewerLinkControls;
10119   */
10120   SetAppProperty ("MedlineDisplayForm", &medviewprocs);
10121 
10122   MemSet ((Pointer) (&seqviewprocs), 0, sizeof (SeqViewProcs));
10123   seqviewprocs.hasTargetControl = TRUE;
10124   seqviewprocs.hasDoneButton = TRUE;
10125   seqviewprocs.launchEditors = TRUE;
10126   seqviewprocs.launchSubviewers = FALSE;
10127   seqviewprocs.sendSelectMessages = TRUE;
10128   seqviewprocs.highlightSelections = TRUE;
10129   seqviewprocs.cleanupObjectPtr = FALSE;
10130   seqviewprocs.activateForm = BioseqViewFormActivated;
10131   seqviewprocs.closeForm = StdSendCloseWindowMessageProc;
10132   seqviewprocs.useFolderTabs = CHANGE_VIEW_POPUP;
10133   /*
10134   seqviewprocs.initNucPage = NUCASN2FF_PAGE_1;
10135   seqviewprocs.initProtPage = PROTGENPEPT_PAGE;
10136   */
10137 #ifndef WIN_MAC
10138   seqviewprocs.createMenus = BioseqViewFormMenus;
10139 #endif
10140 #ifdef WIN_MOTIF
10141   if (indexerVersion) {
10142     if (GetSequinAppParam ("SETTINGS", "WGS", NULL, str, sizeof (str))
10143         && StringICmp (str, "TRUE") == 0) {
10144       seqviewprocs.createToolBar = BioseqViewFormWGSToolBar;
10145     } else if (GetSequinAppParam ("SETTINGS", "CUSTOMTOOLBAR", NULL, str, sizeof (str))
10146         && StringICmp (str, "TRUE") == 0) {
10147       seqviewprocs.createToolBar = BioseqViewFormCustomToolBar;
10148     } else {
10149       seqviewprocs.createToolBar = BioseqViewFormToolBar;
10150     }
10151   }
10152 #endif
10153 #ifdef WIN_MSWIN
10154   if (indexerVersion) {
10155     if (GetSequinAppParam ("SETTINGS", "WGS", NULL, str, sizeof (str))
10156         && StringICmp (str, "TRUE") == 0) {
10157       seqviewprocs.createToolBar = BioseqViewFormWGSToolBar;
10158     } else if (GetSequinAppParam ("SETTINGS", "CUSTOMTOOLBAR", NULL, str, sizeof (str))
10159         && StringICmp (str, "TRUE") == 0) {
10160       seqviewprocs.createToolBar = BioseqViewFormCustomToolBar;
10161     } else {
10162       seqviewprocs.createToolBar = BioseqViewFormToolBar;
10163     }
10164   }
10165 #endif
10166 /*#ifdef INTERNAL_NCBI_SEQUIN*/
10167   if (indexerVersion) {
10168     seqviewprocs.allowScrollText = TRUE;
10169     seqviewprocs.startInScrollText = FALSE;
10170   } else {
10171     seqviewprocs.allowScrollText = FALSE;
10172     seqviewprocs.startInScrollText = FALSE;
10173   }
10174 /*#endif*/
10175   seqviewprocs.handleMessages = SequinSeqViewFormMessage;
10176   /*
10177   seqviewprocs.makeControls = DoMakeSeqViewerLinkControls;
10178   seqviewprocs.updateControls = UpdateViewerLinkTarget;
10179   */
10180   seqviewprocs.makeAlignBtn = DoMakeViewerAlignBtn;
10181   seqviewprocs.updateCounts = DoUpdateFetchCounts;
10182   seqviewprocs.filepath = NULL;
10183 
10184   SetupBioseqPageList ();
10185 
10186   SetAppProperty ("SeqDisplayForm", &seqviewprocs);
10187 
10188   MemSet ((Pointer) (&seqedprocs), 0, sizeof (SeqEditViewProcs));
10189 #ifdef WIN_MAC
10190   seqedprocs.activateForm = SeqEditFormActivated;
10191 #endif
10192   seqedprocs.handleMessages = SequinSeqEditFormMessage;
10193   seqedprocs.minPixelWidth = 0;
10194   seqedprocs.minPixelHeight = 0;
10195   seqedprocs.showfeat = FALSE;
10196   seqedprocs.extended_align_menu = FALSE;
10197   seqedprocs.extended_dist_menu = FALSE;
10198   seqedprocs.extended_tree_menu = FALSE;
10199 
10200   if (useEntrez) {
10201     seqedprocs.download = SeqEdDownload;
10202   }
10203 
10204   SetAppProperty ("SeqEditDisplayForm", &seqedprocs);
10205 
10206   MemSet ((Pointer) (&stdedprocs), 0, sizeof (StdEditorProcs));
10207 #ifdef WIN_MAC
10208   stdedprocs.activateForm = StdEditorFormActivated;
10209 #endif
10210   stdedprocs.handleMessages = SequinStdEditorFormMessage;
10211   stdedprocs.duplicateExisting = FALSE;
10212   SetAppProperty ("StdEditorForm", &stdedprocs);
10213 
10214   MemSet ((Pointer) (&valdtrprocs), 0, sizeof (StdEditorProcs));
10215 #ifdef WIN_MAC
10216   valdtrprocs.activateForm = StdValidatorFormActivated;
10217 #endif
10218   valdtrprocs.handleMessages = SequinStdEditorFormMessage;
10219   valdtrprocs.duplicateExisting = FALSE;
10220   SetAppProperty ("StdValidatorForm", &valdtrprocs);
10221 
10222   MemSet ((Pointer) (&txtviewprocs), 0, sizeof (TextViewProcs));
10223 #ifdef WIN_MAC
10224   txtviewprocs.activateForm = TextViewProcFormActivated;
10225 #endif
10226   if (indexerVersion) {
10227     txtviewprocs.useScrollText = TRUE;
10228   } else {
10229     txtviewprocs.useScrollText = FALSE;
10230   }
10231   SetAppProperty ("TextDisplayForm", &txtviewprocs);
10232 
10233   SetAppProperty ("HelpMessageProc", (Pointer) ProcessHelpMessage);
10234 
10235   MemSet ((Pointer) (&pubedprocs), 0, sizeof (PubdescEditProcs));
10236   if (newMedarch) {
10237     /*
10238     pubedprocs.lookupArticle = LookupAnArticleFuncNew;
10239     pubedprocs.lookupArticle = LookupAnArticleFuncViaEUtils;
10240     */
10241     pubedprocs.lookupArticle = LookupAnArticleFuncHybrid;
10242 #if USE_LOOKUPJOURNALFUNCNEW
10243     pubedprocs.lookupJournal = LookupJournalFuncNew;
10244 #endif
10245     pubedprocs.lookupJournal = LookupJournalFuncViaEUtils;
10246   } else if (useMedarch) {
10247     pubedprocs.lookupArticle = LookupAnArticleFunc;
10248     pubedprocs.lookupJournal = LookupJournalFunc;
10249   }
10250 /*#ifdef REPLACE_THIS*/
10251   if (indexerVersion) {
10252     pubedprocs.replaceThis = TRUE;
10253   }
10254 /*#endif*/
10255   SetAppProperty ("PubdescEditForm", &pubedprocs);
10256 
10257   MemSet ((Pointer) (&biosrcedprocs), 0, sizeof (BioSourceEditProcs));
10258   if (useTaxon) {
10259     biosrcedprocs.lookupTaxonomy = LookupTaxonomyFunc;
10260   }
10261   SetAppProperty ("BioSourcEditForm", &biosrcedprocs);
10262 
10263   readOnlyDbTags = TRUE;
10264 
10265 /*#ifdef INTERNAL_NCBI_SEQUIN*/
10266   if (indexerVersion) {
10267     SetAppProperty ("InternalNcbiSequin", (void *) 1024);
10268     readOnlyDbTags = FALSE;
10269   }
10270 /*#endif*/
10271 
10272   if (genomeCenter != NULL) {
10273     SetAppProperty ("GenomeCenterSequin", (void *) 1024);
10274     readOnlyDbTags = FALSE;
10275   }
10276 
10277   if (readOnlyDbTags) {
10278     SetAppProperty ("ReadOnlyDbTags", (void *) 1024);
10279   }
10280 
10281   SetAppProperty ("NewSequinGraphicalViewer", (void *) 1024);
10282   SetAppProperty ("NewSequinLayoutOverride", (void *) 1024);
10283 
10284   if (GetSequinAppParam ("SETTINGS", "BROWSER", NULL, str, sizeof (str))) {
10285     SetAppProperty ("MedviewBrowserPath", (void *) StringSave (str));
10286   }
10287 
10288   if (GetSequinAppParam ("PREFERENCES", "MINPIXELWIDTH", NULL, str, sizeof (str))) {
10289     if (StrToInt (str, &val) && val > 0) {
10290       val = MIN (val, screenRect.right);
10291       medviewprocs.minPixelWidth = val;
10292       seqviewprocs.minPixelWidth = val;
10293     }
10294   }
10295 
10296   if (GetSequinAppParam ("PREFERENCES", "MINPIXELHEIGHT", NULL, str, sizeof (str))) {
10297     if (StrToInt (str, &val) && val > 0) {
10298       val = MIN (val, screenRect.bottom);
10299       medviewprocs.minPixelHeight = val;
10300       seqviewprocs.minPixelHeight = val;
10301     }
10302   }
10303 
10304   if (GetSequinAppParam ("PREFERENCES", "SEQEDPIXELWIDTH", NULL, str, sizeof (str))) {
10305     if (StrToInt (str, &val) && val > 0) {
10306       val = MIN (val, screenRect.right);
10307       seqedprocs.minPixelWidth = val;
10308     }
10309   }
10310 
10311   if (GetSequinAppParam ("PREFERENCES", "SEQEDPIXELHEIGHT", NULL, str, sizeof (str))) {
10312     if (StrToInt (str, &val) && val > 0) {
10313       val = MIN (val, screenRect.bottom);
10314       seqedprocs.minPixelHeight = val;
10315     }
10316   }
10317 
10318   if (indexerVersion) {
10319     if (seqviewprocs.minPixelWidth < 500) {
10320       seqviewprocs.minPixelWidth = 500;
10321     }
10322     if (seqviewprocs.minPixelHeight < 600) {
10323       seqviewprocs.minPixelHeight = 600;
10324     }
10325     if (txtviewprocs.minPixelWidth < 750) {
10326       txtviewprocs.minPixelWidth = 750;
10327     }
10328     if (txtviewprocs.minPixelHeight < 600) {
10329       txtviewprocs.minPixelHeight = 600;
10330     }
10331   }
10332 
10333   if (screenRect.bottom < 780) {
10334     if (seqviewprocs.minPixelHeight > 500) {
10335       seqviewprocs.minPixelHeight = 500;
10336     }
10337     if (txtviewprocs.minPixelHeight > 500) {
10338       txtviewprocs.minPixelHeight = 500;
10339     }
10340   }
10341 
10342   if (GetSequinAppParam ("PREFERENCES", "TEXTPIXELWIDTH", NULL, str, sizeof (str))) {
10343     if (StrToInt (str, &val) && val > 0) {
10344       val = MIN (val, screenRect.right);
10345       txtviewprocs.minPixelWidth = val;
10346     }
10347   }
10348 
10349   if (GetSequinAppParam ("PREFERENCES", "TEXTPIXELHEIGHT", NULL, str, sizeof (str))) {
10350     if (StrToInt (str, &val) && val > 0) {
10351       val = MIN (val, screenRect.bottom);
10352       txtviewprocs.minPixelHeight = val;
10353     }
10354   }
10355 
10356   if (GetSequinAppParam ("PREFERENCES", "SEQEDSHOWFEAT", NULL, str, sizeof (str))) {
10357     if (StringICmp (str, "TRUE") == 0) {
10358       seqedprocs.showfeat = TRUE;
10359     }
10360   }
10361 
10362   if (GetSequinAppParam ("PREFERENCES", "SEQEDEXTENDALIGN", NULL, str, sizeof (str))) {
10363     if (StringICmp (str, "TRUE") == 0) {
10364       seqedprocs.extended_align_menu = TRUE;
10365     }
10366   }
10367 
10368   if (GetSequinAppParam ("PREFERENCES", "SEQEDEXTENDDIST", NULL, str, sizeof (str))) {
10369     if (StringICmp (str, "TRUE") == 0) {
10370       seqedprocs.extended_dist_menu = TRUE;
10371     }
10372   }
10373 
10374   if (GetSequinAppParam ("PREFERENCES", "SEQEDEXTENDTREE", NULL, str, sizeof (str))) {
10375     if (StringICmp (str, "TRUE") == 0) {
10376       seqedprocs.extended_tree_menu = TRUE;
10377     }
10378   }
10379 
10380   if (GetSequinAppParam ("PREFERENCES", "USEOLDASN", NULL, str, sizeof (str))) {
10381     if (StringICmp (str, "TRUE") == 0) {
10382       leaveAsOldAsn = TRUE;
10383     }
10384   }
10385 
10386   if (GetSequinAppParam ("SETTINGS", "XMLPREFIX", NULL, str, sizeof (str))) {
10387     AsnSetXMLmodulePrefix (StringSave (str));
10388   }
10389 
10390   validateExons = TRUE;
10391   if (GetSequinAppParam ("PREFERENCES", "VALIDATEEXONS", NULL, str, sizeof (str))) {
10392     if (StringICmp (str, "FALSE") == 0) {
10393       validateExons = FALSE;
10394     }
10395   }
10396   if (validateExons) {
10397     SetAppProperty ("ValidateExons", (void *) 1024);
10398   }
10399   /*
10400   SetAppProperty ("SpliceValidateAsError", (void *) 1024);
10401   */
10402 
10403   cdsMrnaOneToOne = FALSE;
10404   if (GetSequinAppParam ("PREFERENCES", "VALIDATECDSMRNA", NULL, str, sizeof (str))) {
10405     if (StringICmp (str, "TRUE") == 0) {
10406       cdsMrnaOneToOne = FALSE;
10407     }
10408   }
10409   if (cdsMrnaOneToOne) {
10410     SetAppProperty ("ValidateCDSmRNAoneToOne", (void *) 1024);
10411   }
10412 
10413   testLatLonSubregion = FALSE;
10414   if (GetSequinAppParam ("PREFERENCES", "VALIDATELATLONSUBREGION", NULL, str, sizeof (str))) {
10415     if (StringICmp (str, "TRUE") == 0) {
10416       testLatLonSubregion = TRUE;
10417     }
10418   }
10419 
10420   strictLatLonCountry = FALSE;
10421   if (GetSequinAppParam ("PREFERENCES", "VALIDATELATLONSTRICT", NULL, str, sizeof (str))) {
10422     if (StringICmp (str, "TRUE") == 0) {
10423       strictLatLonCountry = TRUE;
10424     }
10425   }
10426 
10427   /*
10428   if (GetSequinAppParam ("SETTINGS", "NUCFIELD", NULL, str, sizeof (str))) {
10429     if (StrToInt (str, &val) && val >= 0) {
10430       seqviewprocs.initNucPage = val;
10431     }
10432   }
10433 
10434   if (GetSequinAppParam ("SETTINGS", "PRTFIELD", NULL, str, sizeof (str))) {
10435     if (StrToInt (str, &val) && val >= 0) {
10436       seqviewprocs.initProtPage = val;
10437     }
10438   }
10439   */
10440 
10441   if (GetSequinAppParam ("SETTINGS", "TARGETCONTROL", NULL, str, sizeof (str))) {
10442     if (StrToInt (str, &val) && val >= 0) {
10443       seqviewprocs.useFolderTabs = val;
10444     }
10445   }
10446 
10447   if (GetSequinAppParam ("SETTINGS", "ALLOWSCROLLTEXT", NULL, str, sizeof (str))) {
10448     if (StringICmp (str, "TRUE") == 0) {
10449       seqviewprocs.allowScrollText = TRUE;
10450       seqviewprocs.startInScrollText = FALSE;
10451     }
10452   }
10453 
10454   if (GetSequinAppParam ("SETTINGS", "MEDPAGE", "Abstract", str, sizeof (str))) {
10455     medviewprocs.initMedLabel = StringSaveNoNull (str);
10456   }
10457   if (GetSequinAppParam ("SETTINGS", "NUCPAGE", "GenBank", str, sizeof (str))) {
10458     seqviewprocs.initNucLabel = StringSaveNoNull (str);
10459   }
10460   if (GetSequinAppParam ("SETTINGS", "PRTPAGE", "GenPept", str, sizeof (str))) {
10461     seqviewprocs.initProtLabel = StringSaveNoNull (str);
10462   }
10463   if (GetSequinAppParam ("SETTINGS", "GENMPAGE", "Map", str, sizeof (str))) {
10464     seqviewprocs.initGenomeLabel = StringSaveNoNull (str);
10465   }
10466 
10467   if (useEntrez) {
10468     seqviewprocs.lockFarComponents = TRUE;
10469   }
10470   if (GetSequinAppParam ("SETTINGS", "LOCKFAR", NULL, str, sizeof (str))) {
10471     if (StringICmp (str, "FALSE") == 0) {
10472       seqviewprocs.lockFarComponents = FALSE;
10473     }
10474   }
10475 
10476   if (GetSequinAppParam ("PREFERENCES", "GPHVIEWSCOREALIGNS", NULL, str, sizeof (str))) {
10477     if (StringICmp (str, "TRUE") == 0) {
10478       gphviewscorealigns = TRUE;
10479     }
10480   }
10481   if (gphviewscorealigns) {
10482     SetAppProperty("GPHVIEWSCOREALIGNS", (void *) 1);
10483   }
10484 
10485   MemSet ((Pointer) (&entrezglobals), 0, sizeof (EntrezGlobals));
10486   /*
10487   entrezglobals.retrieveDocsProc = DoRetrieveDocuments;
10488   entrezglobals.retrieveProjectProc = DoRetrieveProject;
10489   entrezglobals.retrieveSimpleProc = DoRetrieveSimple;
10490   entrezglobals.loadNamedUidProc = DoLoadNamedUidList;
10491   entrezglobals.launchViewerProc = DoLaunchRecordViewer;
10492 #ifndef WIN_MAC
10493   entrezglobals.createTrmLstMenus = TermListFormMenus;
10494   entrezglobals.createDocSumMenus = DocSumFormMenus;
10495 #endif
10496   SetAppProperty ("EntrezGlobals", &entrezglobals);
10497   */
10498 
10499   entrezglobals.showAsn = TRUE;
10500 
10501   entrezglobals.persistDefault = TRUE;
10502   if (GetSequinAppParam ("PREFERENCES", "PARENTSPERSIST", NULL, str, sizeof (str) - 1)) {
10503     if (StringICmp (str, "FALSE") == 0) {
10504       entrezglobals.persistDefault = FALSE;
10505     }
10506   }
10507   entrezglobals.alignDefault = TRUE;
10508   if (GetSequinAppParam ("PREFERENCES", "ALIGNCHECKED", NULL, str, sizeof (str) - 1)) {
10509     if (StringICmp (str, "FALSE") == 0) {
10510       entrezglobals.alignDefault = FALSE;
10511     }
10512   }
10513   seqviewprocs.alignDefault = entrezglobals.alignDefault;
10514   if (GetSequinAppParam ("PREFERENCES", "POPDOWN", NULL, str, sizeof (str) - 1)) {
10515     if (StringICmp (str, "TRUE") == 0) {
10516       entrezglobals.popdownBehavior = TRUE;
10517     }
10518   }
10519   if (GetSequinAppParam ("PREFERENCES", "LOOKUPDIRECT", NULL, str, sizeof (str) - 1)) {
10520     if (StringICmp (str, "TRUE") == 0) {
10521       entrezglobals.lookupDirect = TRUE;
10522     }
10523   }
10524   entrezglobals.sortFields = TRUE;
10525   if (GetSequinAppParam ("PREFERENCES", "SORTFIELDS", NULL, str, sizeof (str) - 1)) {
10526     if (StringICmp (str, "FALSE") == 0) {
10527       entrezglobals.sortFields = FALSE;
10528     }
10529   }
10530   if (GetSequinAppParam ("SETTINGS", "DATABASE", "MEDLINE", str, sizeof (str))) {
10531     entrezglobals.initDatabase = StringSaveNoNull (str);
10532   }
10533   if (GetSequinAppParam ("SETTINGS", "FIELD", "All Fields", str, sizeof (str))) {
10534     entrezglobals.initField = StringSaveNoNull (str);
10535   }
10536   if (GetSequinAppParam ("SETTINGS", "MODE", "Automatic", str, sizeof (str))) {
10537     entrezglobals.initMode = StringSaveNoNull (str);
10538   }
10539 
10540 /*#ifdef INTERNAL_NCBI_SEQUIN*/
10541   if (indexerVersion) {
10542     allowalign = TRUE;
10543   } else {
10544 /*#else*/
10545     allowalign = FALSE;
10546   }
10547 /*#endif*/
10548   if (GetSequinAppParam ("SETTINGS", "ALLOWALIGNMENT", NULL, str, sizeof (str))) {
10549     if (StringICmp (str, "TRUE") == 0) {
10550       allowalign = TRUE;
10551     }
10552   }
10553   if (allowalign) {
10554     SetAppProperty ("AllowAlignment", (void *) 1024);
10555   }
10556 
10557   /* register types and functions first */
10558 
10559   if (smartnetMode) {
10560     REGISTER_SMART_SEQENTRY_VIEW;
10561   } else {
10562     REGISTER_NEW_SEQENTRY_VIEW;
10563   }
10564 
10565   curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
10566   while (curr != NULL) {
10567     if (key != FEATDEF_BAD && curr->seqfeat_key == SEQFEAT_IMP) {
10568       subtype = curr->featdef_key;
10569       if (subtype != FEATDEF_source) {
10570         sprintf (procname, "Edit %s", curr->menulabel);
10571         StringNCpy_0 (proclabel, curr->typelabel, sizeof (proclabel));
10572         if (proclabel [0] == '-') {
10573           proclabel [0] = '~';
10574         }
10575         REGISTER_IMPORT_EDIT(procname,proclabel,subtype);
10576       }
10577     }
10578     curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
10579   }
10580 
10581   curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
10582   while (curr != NULL) {
10583     if (key != FEATDEF_BAD && curr->seqfeat_key == SEQFEAT_RNA) {
10584       subtype = curr->featdef_key;
10585       sprintf (procname, "Edit %s", curr->menulabel);
10586       StringNCpy_0 (proclabel, curr->typelabel, sizeof (proclabel));
10587       if (proclabel [0] == '-') {
10588         proclabel [0] = '~';
10589       }
10590       REGISTER_RNA_EDIT(procname,proclabel,subtype);
10591     }
10592     curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
10593   }
10594 
10595   curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
10596   while (curr != NULL) {
10597     if (key != FEATDEF_BAD && curr->seqfeat_key == SEQFEAT_PROT) {
10598       subtype = curr->featdef_key;
10599       sprintf (procname, "Edit %s", curr->menulabel);
10600       StringNCpy_0 (proclabel, curr->typelabel, sizeof (proclabel));
10601       if (proclabel [0] == '-') {
10602         proclabel [0] = '~';
10603       }
10604       REGISTER_PROT_EDIT(procname,proclabel,subtype);
10605     }
10606     curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
10607   }
10608 
10609   REGISTER_GENE_EDIT;
10610   REGISTER_CDRGN_EDIT;
10611   REGISTER_RGNFEAT_EDIT;
10612   REGISTER_CMNTFEAT_EDIT;
10613   REGISTER_BIOSOURCE_FEAT_EDIT;
10614   REGISTER_BIOSOURCE_DESC_EDIT;
10615   REGISTER_MOLINFO_EDIT;
10616   REGISTER_PUBDESC_FEAT_EDIT;
10617   REGISTER_PUBDESC_DESC_EDIT;
10618   REGISTER_TITLE_EDIT;
10619   REGISTER_COMMENT_EDIT;
10620   REGISTER_NAME_EDIT;
10621   REGISTER_REGION_EDIT;
10622   REGISTER_BOND_EDIT;
10623   REGISTER_SITE_EDIT;
10624   REGISTER_PSEC_EDIT;
10625   REGISTER_GENBANK_EDIT;
10626   REGISTER_CREATE_DATE_EDIT;
10627   REGISTER_UPDATE_DATE_EDIT;
10628 
10629   if (indexerVersion) {
10630     REGISTER_INGENUE;
10631   }
10632   REGISTER_NEW_BIOSEQ_EDIT;
10633   REGISTER_DELTA_BIOSEQ_EDIT;
10634   REGISTER_NEW_SEQALIGN_EDIT;
10635   REGISTER_NEW_SEQANNOT_EDIT;
10636 
10637   REGISTER_BIOSEQ_SEG_EDIT;
10638   REGISTER_BIOSEQ_SET_EDIT;
10639   REGISTER_SUBMITBLOCK_EDIT;
10640   REGISTER_SEQSUBCIT_EDIT;
10641 
10642   SetupSequinFilters ();
10643 }
10644 
ChooseAFont(CharPtr param,CharPtr dfault)10645 static FonT ChooseAFont (CharPtr param, CharPtr dfault)
10646 
10647 {
10648   FonT  f;
10649   Char  str [128];
10650 
10651   f = NULL;
10652   if (GetSequinAppParam ("FONTS", param, NULL, str, sizeof (str))) {
10653     f = ParseFont (str);
10654   } else {
10655     if (! indexerVersion) {
10656       SetSequinAppParam ("FONTS", param, dfault);
10657     }
10658     f = ParseFont (dfault);
10659   }
10660   return f;
10661 }
10662 
SetupCommonFonts(void)10663 static void SetupCommonFonts (void)
10664 
10665 {
10666 #ifdef WIN_MAC
10667   medviewprocs.jourfnt = ChooseAFont ("JOURNAL", "Geneva,10,i");
10668   medviewprocs.volfnt = ChooseAFont ("VOLUME", "Geneva,10,b");
10669   medviewprocs.pagesfnt = ChooseAFont ("PAGES", "Geneva,10");
10670   medviewprocs.titlefnt = ChooseAFont ("TITLE", "Times,14,b");
10671   medviewprocs.authorsfnt = ChooseAFont ("AUTHORS", "Times,14");
10672   medviewprocs.affilfnt = ChooseAFont ("AFFILIATION", "Times,12");
10673   medviewprocs.abstractfnt = ChooseAFont ("ABSTRACT", "Geneva,10");
10674   medviewprocs.meshfnt = ChooseAFont ("MESH", "Monaco,9");
10675   medviewprocs.displayFont = ChooseAFont ("DISPLAY", "Monaco,9");
10676 #endif
10677 #ifdef WIN_MSWIN
10678   medviewprocs.jourfnt = ChooseAFont ("JOURNAL", "Arial,11,i");
10679   medviewprocs.volfnt = ChooseAFont ("VOLUME", "Arial,11,b");
10680   medviewprocs.pagesfnt = ChooseAFont ("PAGES", "Arial,11");
10681   medviewprocs.titlefnt = ChooseAFont ("TITLE", "Times New Roman,14,b");
10682   medviewprocs.authorsfnt = ChooseAFont ("AUTHORS", "Times New Roman,14");
10683   medviewprocs.affilfnt = ChooseAFont ("AFFILIATION", "Times New Roman,11");
10684   medviewprocs.abstractfnt = ChooseAFont ("ABSTRACT", "Times New Roman,11");
10685   medviewprocs.meshfnt = ChooseAFont ("MESH", "Times New Roman,9");
10686   medviewprocs.displayFont = ChooseAFont ("DISPLAY", "Courier New,10");
10687 #endif
10688 #ifdef WIN_MOTIF
10689   medviewprocs.jourfnt = ChooseAFont ("JOURNAL", "Helvetica,12,i");
10690   medviewprocs.volfnt = ChooseAFont ("VOLUME", "Helvetica,12,b");
10691   medviewprocs.pagesfnt = ChooseAFont ("PAGES", "Helvetica,12");
10692   medviewprocs.titlefnt = ChooseAFont ("TITLE", "Times,18,b");
10693   medviewprocs.authorsfnt = ChooseAFont ("AUTHORS", "Times,18");
10694   medviewprocs.affilfnt = ChooseAFont ("AFFILIATION", "Times,14");
10695   medviewprocs.abstractfnt = ChooseAFont ("ABSTRACT", "Times,14");
10696   medviewprocs.meshfnt = ChooseAFont ("MESH", "Times,12");
10697   medviewprocs.displayFont = ChooseAFont ("DISPLAY", "Courier,10");
10698 #endif
10699 
10700 #ifdef WIN_MAC
10701   seqviewprocs.displayFont = ChooseAFont ("DISPLAY", "Monaco,9");
10702 #endif
10703 #ifdef WIN_MSWIN
10704   if (indexerVersion) {
10705     seqviewprocs.displayFont = ChooseAFont ("DISPLAY", "Courier New,11");
10706   } else {
10707     seqviewprocs.displayFont = ChooseAFont ("DISPLAY", "Courier New,10");
10708   }
10709 #endif
10710 #ifdef WIN_MOTIF
10711   seqviewprocs.displayFont = ChooseAFont ("DISPLAY", "Courier,10");
10712 #endif
10713 
10714 #ifdef WIN_MAC
10715   entrezglobals.docsumFont = ChooseAFont ("FETCHED", "Monaco,9");
10716 #endif
10717 #ifdef WIN_MSWIN
10718   entrezglobals.docsumFont = ChooseAFont ("FETCHED", "Courier New,10");
10719 #endif
10720 #ifdef WIN_MOTIF
10721   entrezglobals.docsumFont = ChooseAFont ("FETCHED", "Courier,10");
10722 #endif
10723 
10724 #ifdef WIN_MAC
10725   txtviewprocs.displayFont = ChooseAFont ("DISPLAY", "Monaco,9");
10726 #endif
10727 #ifdef WIN_MSWIN
10728   txtviewprocs.displayFont = ChooseAFont ("DISPLAY", "Courier New,10");
10729 #endif
10730 #ifdef WIN_MOTIF
10731   txtviewprocs.displayFont = ChooseAFont ("DISPLAY", "Courier,10");
10732 #endif
10733 }
10734 
RevStringUpper(CharPtr str)10735 static void RevStringUpper (CharPtr str)
10736 {
10737 	CharPtr nd;
10738 	Char tmp;
10739 
10740 		if (str == NULL)
10741 			return;
10742     nd = str;
10743 	while (*nd != '\0')
10744 		nd++;
10745 	nd--;
10746 
10747 	while (nd > str)
10748 	{
10749 		tmp = TO_UPPER(*nd);
10750 		*nd = TO_UPPER(*str);
10751 		*str = tmp;
10752 		nd--; str++;
10753 	}
10754 
10755 	if (nd == str)
10756 		*nd = TO_UPPER(*nd);
10757 	return;
10758 }
10759 
ObjMgrReport(IteM i)10760 static void ObjMgrReport (IteM i)
10761 
10762 {
10763   BioseqPtr                  bsp;
10764   Char                       buf [41];
10765   FILE                       *fp;
10766   Uint4                      j, num;
10767   ObjMgrDataPtr              omdp;
10768   ObjMgrDataPtr PNTR         omdpp;
10769   ObjMgrPtr                  omp;
10770   Char                       path [PATH_MAX];
10771   SeqIdIndexElementPtr PNTR  sipp;
10772   SeqMgrPtr                  smp;
10773 
10774   omp = ObjMgrGet ();
10775   if (omp == NULL) return;
10776   smp = SeqMgrGet ();
10777   if (smp == NULL) return;
10778   TmpNam (path);
10779   fp = FileOpen (path, "w");
10780   if (fp == NULL) return;
10781   fprintf (fp, "totobj %d, currobj %d\n", (int) omp->totobj, (int) omp->currobj);
10782   omdpp = omp->datalist;
10783   if (omdpp != NULL) {
10784     num = omp->currobj;
10785     for (j = 0; j < num; j++) {
10786       omdp = omdpp [j];
10787       if (omdp != NULL && omdp->datatype == OBJ_BIOSEQ) {
10788         bsp = (BioseqPtr) omdp->dataptr;
10789         if (bsp != NULL) {
10790           SeqIdWrite (bsp->id, buf, PRINTID_REPORT, sizeof (buf) - 1);
10791           fprintf (fp, "%4ld %s\n", (long) j, buf);
10792         }
10793       }
10794     }
10795   }
10796   fprintf (fp, "seqid index count %ld\n", (long) smp->BioseqIndexCnt);
10797   num = smp->BioseqIndexCnt;
10798   sipp = smp->BioseqIndex;
10799   if (sipp != NULL) {
10800     for (j = 0; j < num; j++) {
10801       StringNCpy_0 (buf, sipp [j]->str, sizeof (buf));
10802       RevStringUpper (buf);
10803       fprintf (fp, "%4ld %s\n", (long) j, buf);
10804     }
10805   }
10806   FileClose (fp);
10807   LaunchGeneralTextViewer (path, "Object Manager Report");
10808   FileRemove (path);
10809 }
10810 
10811 #ifdef WIN_MAC
10812 
ToggleOldAsnProc(IteM i)10813 static void ToggleOldAsnProc (IteM i)
10814 
10815 {
10816   leaveAsOldAsn = GetStatus (i);
10817 }
10818 
SetupMacMenus(void)10819 static void SetupMacMenus (void)
10820 
10821 {
10822   MenU  m;
10823   Int2  mssgadd;
10824   Int2  mssgalign;
10825   Int2  mssgdelete;
10826   Int2  mssgdup;
10827   Int2  mssgfeatprop;
10828   Int2  mssgseq;
10829   Int2  mssgsub;
10830   Int2  mssgupd, mssgupd_idx = 0;
10831   Int2  mssgext;
10832   /*
10833   MenU  sub;
10834   */
10835 
10836   m = AppleMenu (NULL);
10837   AddAboutAndHelpMenuItems (m);
10838   DeskAccGroup (m);
10839 
10840   m = PulldownMenu (NULL, "File");
10841   openItem = CommandItem (m, "Open.../O", MacReadNewAsnProc);
10842   SetAppProperty (SEQFORM_OPEN_ITEM, openItem);
10843   closeItem = FormCommandItem (m, "Close", NULL, VIB_MSG_CLOSE);
10844   SetAppProperty (SEQFORM_CLOSE_ITEM, closeItem);
10845 
10846   SetAppProperty (SEQFORM_INIT_ACTIVE, &initialFormsActive);
10847 
10848   SeparatorItem (m);
10849   importItem = FormCommandItem (m, "Import.../I", NULL, VIB_MSG_IMPORT);
10850   exportItem = FormCommandItem (m, "Export.../E", NULL, VIB_MSG_EXPORT);
10851   SeparatorItem (m);
10852   duplicateViewItem = CommandItem (m, "Duplicate View", DuplicateViewProc);
10853   SeparatorItem (m);
10854   saveItem = FormCommandItem (m, "Save/S", NULL, VIB_MSG_SAVE);
10855   saveAsItem = FormCommandItem (m, "Save As...", NULL, VIB_MSG_SAVE_AS);
10856   SeparatorItem (m);
10857   restoreItem = CommandItem (m, "Restore...", RestoreSeqEntryProc);
10858   SeparatorItem (m);
10859   prepareItem = CommandItem (m, "Prepare Submission...", PrepareSeqSubmitProc);
10860   /*
10861   submitItem = CommandItem (m, "Submit to NCBI", SubmitToNCBI);
10862   */
10863   /*
10864   SeparatorItem (m);
10865   CommandItem (m, "Propagate Top Descriptors", ForcePropagate);
10866   */
10867   SeparatorItem (m);
10868   printItem = FormCommandItem (m, "Print", NULL, VIB_MSG_PRINT);
10869   SeparatorItem (m);
10870   FormCommandItem (m, "Quit/Q", NULL, VIB_MSG_QUIT);
10871 
10872   m = PulldownMenu (NULL, "Edit");
10873   undoItem = FormCommandItem (m, UNDO_MENU_ITEM, NULL, VIB_MSG_UNDO);
10874   Disable (undoItem);
10875   SeparatorItem (m);
10876   cutItem = FormCommandItem (m, CUT_MENU_ITEM, NULL, VIB_MSG_CUT);
10877   copyItem = FormCommandItem (m, COPY_MENU_ITEM, NULL, VIB_MSG_COPY);
10878   pasteItem = FormCommandItem (m, PASTE_MENU_ITEM, NULL, VIB_MSG_PASTE);
10879   deleteItem = FormCommandItem (m, CLEAR_MENU_ITEM, NULL, VIB_MSG_DELETE);
10880   SeparatorItem (m);
10881   if (extraServices) {
10882     mssgdup = RegisterFormMenuItemName ("SequinDuplicateItem");
10883     duplicateItem = FormCommandItem (m, "Duplicate...", NULL, mssgdup);
10884     SeparatorItem (m);
10885   }
10886   if (genomeCenter != NULL || indexerVersion) {
10887     SetupEditSecondary (m, NULL);
10888     SeparatorItem (m);
10889   }
10890   mssgseq = RegisterFormMenuItemName ("SequinEditSequenceItem");
10891   mssgalign = RegisterFormMenuItemName ("SequinEditAlignmentItem");
10892   mssgdelete = RegisterFormMenuItemName ("SequinDeleteSequencesItem");
10893   mssgsub = RegisterFormMenuItemName ("SequinEditSubmitterItem");
10894   mssgupd = RegisterFormMenuItemName ("SequinUpdateSeqSubmenu");
10895   if (indexerVersion)
10896   {
10897     mssgupd_idx = RegisterFormMenuItemName ("SequinUpdateSeqSubmenuIndexer");
10898   }
10899   mssgext = RegisterFormMenuItemName ("SequinExtendSeqSubmenu");
10900   mssgfeatprop = RegisterFormMenuItemName ("SequinFeaturePropagate");
10901   mssgadd = RegisterFormMenuItemName ("SequinAddSeqSubmenu");
10902   editsequenceitem = FormCommandItem (m, "Edit Sequence...", NULL, mssgseq);
10903   editseqdeleteitem = FormCommandItem (m, "Sequence Deletion Tool...", NULL, mssgdelete);
10904   editseqalignitem = FormCommandItem (m, "Alignment Assistant...", NULL, mssgalign);
10905   editseqsubitem = FormCommandItem (m, "Edit Submitter Info...", NULL, mssgsub);
10906   if (indexerVersion) {
10907     SeparatorItem (m);
10908     edithistoryitem = CommandItem (m, "Edit History....", EditSequenceHistory);
10909   }
10910   SeparatorItem (m);
10911 
10912   if (indexerVersion) {
10913     updateSeqMenuIndexer = SubMenu (m, "Indexer Update Sequence");
10914     SetFormMenuItem (NULL, mssgupd_idx, (IteM) updateSeqMenuIndexer);
10915     CommandItem (updateSeqMenuIndexer, "Single Sequence", TestUpdateSequenceIndexer);
10916     if (useEntrez) {
10917       CommandItem (updateSeqMenuIndexer, "Download Accession...", UpdateSequenceViaDownloadIndexer);
10918     }
10919     SeparatorItem (updateSeqMenuIndexer);
10920     CommandItem (updateSeqMenuIndexer, "Multiple Sequences", TestUpdateSequenceSetIndexer);
10921     CommandItem (updateSeqMenuIndexer, "Multiple Sequences (from clipboard)", TestUpdateSequenceSetClipboardIndexer);
10922 
10923     updateSeqMenu = SubMenu (m, "Public Update Sequence");
10924     SetFormMenuItem (NULL, mssgupd, (IteM) updateSeqMenu);
10925     CommandItem (updateSeqMenu, "Single Sequence", TestUpdateSequenceSubmitter);
10926     if (useEntrez) {
10927       CommandItem (updateSeqMenu, "Download Accession...", UpdateSequenceViaDownloadSubmitter);
10928     }
10929     SeparatorItem (updateSeqMenu);
10930     CommandItem (updateSeqMenu, "Multiple Sequences", TestUpdateSequenceSetSubmitter);
10931   }
10932   else
10933   {
10934     updateSeqMenu = SubMenu (m, "Update Sequence");
10935     SetFormMenuItem (NULL, mssgupd, (IteM) updateSeqMenu);
10936     CommandItem (updateSeqMenu, "Single Sequence", TestUpdateSequenceSubmitter);
10937     if (useEntrez) {
10938       CommandItem (updateSeqMenu, "Download Accession...", UpdateSequenceViaDownloadSubmitter);
10939     }
10940     SeparatorItem (updateSeqMenu);
10941     CommandItem (updateSeqMenu, "Multiple Sequences", TestUpdateSequenceSetSubmitter);
10942   }
10943 
10944   featPropItem = CommandItem (m, "Feature Propagate...", NewFeaturePropagate);
10945   SetFormMenuItem (NULL, mssgfeatprop, featPropItem);
10946   SeparatorItem (m);
10947   addSeqMenu = SubMenu (m, "Add Sequence");
10948   SetFormMenuItem (NULL, mssgadd, (IteM) addSeqMenu);
10949   CommandItem (addSeqMenu, "Add FASTA File...", AddSeqWithFASTA);
10950   CommandItem (addSeqMenu, "Add Sequence Record...", AddSeqWithRec);
10951   if (! extraServices) {
10952     SeparatorItem (m);
10953     parseFileItem = CommandItem (m, "Parse File to Source", ParseFileToSource);
10954   }
10955 
10956   m = PulldownMenu (NULL, "Search");
10957   findItem = CommandItem (m, "Find ASN.1.../F", FindStringProc);
10958   findFFItem = CommandItem (m, "Find FlatFile.../G", FindFlatfileProc);
10959   SeparatorItem (m);
10960   findGeneItem = CommandItem (m, "Find by Gene...", FindGeneProc);
10961   findProtItem = CommandItem (m, "Find by Protein...", FindProtProc);
10962   findPosItem = CommandItem (m, "Find by Position...", FindPosProc);
10963   SeparatorItem (m);
10964   if (indexerVersion) {
10965     validateMenu = SubMenu (m, "Validate");
10966     CommandItem (validateMenu, "Validate Record/ V", ValSeqEntryProc);
10967     CommandItem (validateMenu, "Validate no Alignments", ValSeqEntryProcNoAln);
10968     CommandItem (validateMenu, "Validate check Inference", ValSeqEntryProcInfAccn);
10969     SeparatorItem (validateMenu);
10970     CommandItem (validateMenu, "Validate Inst", ValSeqEntryProcInst);
10971     CommandItem (validateMenu, "Validate Hist", ValSeqEntryProcHist);
10972     CommandItem (validateMenu, "Validate Context", ValSeqEntryProcContext);
10973     CommandItem (validateMenu, "Validate Graph", ValSeqEntryProcGraph);
10974     CommandItem (validateMenu, "Validate Set", ValSeqEntryProcSet);
10975     CommandItem (validateMenu, "Validate Feat", ValSeqEntryProcFeat);
10976     CommandItem (validateMenu, "Validate Desc", ValSeqEntryProcDesc);
10977   } else {
10978     validateItem = CommandItem (m, "Validate", ValSeqEntryProc);
10979   }
10980 /*#ifdef USE_BLAST*/
10981   /*
10982   if (useBlast) {
10983     SeparatorItem (m);
10984     if (extraServices) {
10985       cddSearchMenu = SubMenu (m, "CDD Search");
10986       CommandItem (cddSearchMenu, "Features", SimpleCDDSearchFeatProc);
10987       CommandItem (cddSearchMenu, "Alignments", SimpleCDDSearchAlignProc);
10988     } else {
10989       cddSearchItem = CommandItem (m, "CDD Search", SimpleCDDSearchFeatProc);
10990     }
10991   }
10992   */
10993 /*#endif*/
10994   SeparatorItem (m);
10995   vecscreenMenu = SubMenu (m, "Vector Screen");
10996   CommandItem (vecscreenMenu, "UniVec", SimpleUniVecScreenProc);
10997   if (indexerVersion) {
10998     CommandItem (vecscreenMenu, "UniVec Core", SimpleUniVecCoreScreenProc);
10999   }
11000   CommandItem (vecscreenMenu, "Vector Search & Trim Tool", ExternalVecScreenTool);
11001   SeparatorItem (m);
11002   orfItem = CommandItem (m, "ORF Finder...", FindOrf);
11003   /*
11004   aluItem = CommandItem (m, "Repeat Finder...", FindAlu);
11005   */
11006   SeparatorItem (m);
11007   targetItem = CommandItem (m, "Select Target...", DoChangeTarget);
11008 
11009   m = PulldownMenu (NULL, "Options");
11010   if (useEntrez) {
11011     preferencesItem = CommandItem (m, "Preferences...", PreferencesProc);
11012     SeparatorItem (m);
11013   }
11014   /*
11015   sub = SubMenu (m, "Font Selection");
11016   if (useEntrez) {
11017     docsumfontItem = CommandItem (sub, "DocSum Font...", DocSumFontChangeProc);
11018   }
11019   displayfontItem = CommandItem (sub, "Display Font...", DisplayFontChangeProc);
11020   SeparatorItem (m);
11021   legendItem = CreateLegendItem (m, NULL);
11022   SeparatorItem (m);
11023   sub = SubMenu (m, "Query Style");
11024   queryChoice = CreateQueryTypeChoice (sub, NULL);
11025   clearUnusedItem = CreateClearUnusedItem (m, NULL);
11026   SeparatorItem (m);
11027   sub = SubMenu (m, "Neighbor Policy");
11028   neighborChoice = CreateNeighborDelayChoice (sub, NULL);
11029   SeparatorItem (m);
11030   LoadDocsumOptionsMenu (m);
11031   seqviewprocs.alignWithChecked = entrezglobals.alignWithChecked;
11032   seqviewprocs.alignDefault = entrezglobals.alignDefault;
11033   */
11034   if (indexerVersion) {
11035     /*
11036     SeparatorItem (m);
11037     */
11038     oldAsnItem = StatusItem (m, "Use Old ASN.1", ToggleOldAsnProc);
11039     SetStatus (oldAsnItem, leaveAsOldAsn);
11040   }
11041 
11042 /*#ifdef EXTRA_SERVICES*/
11043   if (extraServices) {
11044     specialMenu = PulldownMenu (NULL, "Special");
11045     SetupSpecialMenu (specialMenu, NULL);
11046     projectsMenu = PulldownMenu (NULL, "Projects");
11047     MakeSpecialProjectsMenu (projectsMenu, NULL);
11048 
11049   }
11050 /*#endif*/
11051 
11052   m = PulldownMenu (NULL, "Misc");
11053   /*
11054   CommandItem (m, "Style Manager...", StyleManagerProc);
11055   SeparatorItem (m);
11056   */
11057   CommandItem (m, "Net Configure...", NetConfigureProc);
11058   if (useEntrez) {
11059     /*
11060     SeparatorItem (m);
11061     CommandItem (m, "Entrez2 Query...", Entrez2QueryProc);
11062     */
11063 /*
11064 #ifndef WIN16
11065     if (BiostrucAvail ()) {
11066       SeparatorItem (m);
11067       CommandItem (m, "Cn3D Window...", Cn3DWinShowProc);
11068     }
11069 #endif
11070 */
11071   }
11072   if (useDesktop) {
11073     SeparatorItem (m);
11074     VSMAddToMenu (m, VSM_DESKTOP);
11075   }
11076 
11077   /*
11078   if (indexerVersion) {
11079     SeparatorItem (m);
11080     CommandItem (m, "Object Manager Report", ObjMgrReport);
11081   }
11082   */
11083 
11084   analysisMenu = CreateAnalysisMenu (NULL, NULL, TRUE, TRUE);
11085 
11086   newFeatMenu = PulldownMenu (NULL, "Annotate");
11087   SetupNewFeaturesMenu (newFeatMenu, NULL);
11088   SeparatorItem (newFeatMenu);
11089   batchApplyMenu = SubMenu (newFeatMenu, "Batch Feature Apply");
11090   SetupBatchApplyMenu (batchApplyMenu, NULL);
11091   batchEditMenu = SubMenu (newFeatMenu, "Batch Feature Edit");
11092   SetupBatchEditMenu (batchEditMenu, NULL);
11093   CommandItem (newFeatMenu, "Batch Apply Molecule Type", ExternalApplyMoleculeType);
11094   CommandItem (newFeatMenu, "Set Release Date", SetReleaseDate);
11095   SeparatorItem (newFeatMenu);
11096   CommandItem (newFeatMenu, "ORF Finder", FindOrf);
11097   CommandItem (newFeatMenu, "Import Source Table", ParseFileToSource);
11098   SeparatorItem (newFeatMenu);
11099   newPubMenu = SubMenu (newFeatMenu, "Publications");
11100   SetupNewPublicationsMenu (newPubMenu, NULL);
11101   SeparatorItem (newFeatMenu);
11102   newDescMenu = SubMenu (newFeatMenu, "Descriptors");
11103   SetupNewDescriptorsMenu (newDescMenu, NULL);
11104   SeparatorItem (newFeatMenu);
11105   advTableMenu = SubMenu (newFeatMenu, "Advanced Table Readers");
11106   CommandItem (advTableMenu, "Load Structured Comments from Table", SubmitterCreateStructuredComments);
11107   sucItem = CommandItem (newFeatMenu, "Sort Unique Count By Group", SUCSubmitterProc);
11108 }
11109 #endif
11110 
11111 extern Boolean allowUnableToProcessMessage;
11112 Boolean allowUnableToProcessMessage = TRUE;
11113 
11114 static CharPtr canfeatpropagate =
11115 "Since this record has an alignment, you can annotate features on " \
11116 "one record and then use use feature propagation to annotate the "\
11117 "equivalent features on the other records. This is much faster " \
11118 "than annotating everything manually.";
11119 
11120 extern Int2 LIBCALLBACK AssemblyUserGenFunc (Pointer data);
s_GetTpaInfo(SequencesFormPtr sqfp)11121 static void s_GetTpaInfo (SequencesFormPtr sqfp)
11122 {
11123 
11124   ObjMgrPtr      omp;
11125   OMProcControl  ompc;
11126   ObjMgrProcPtr  ompp;
11127   Int2           retval;
11128 
11129   omp = ObjMgrGet ();
11130   ompp = ObjMgrProcFind (omp, 0, "Edit Assembly User Desc", 0);
11131   MemSet ((Pointer) &ompc, 0, sizeof (OMProcControl));
11132   ompc.input_entityID = 1;
11133   ompc.input_itemID = 1;
11134   ompc.input_itemtype = OBJ_BIOSEQ;
11135   ompc.proc = ompp;
11136 
11137   retval = AssemblyUserGenFunc (&ompc);
11138   if (retval == OM_MSG_RET_ERROR) {
11139     ErrShow ();
11140   }
11141   Update ();
11142 }
11143 
11144 
AddStructuredCommentToSeqEntry(SeqEntryPtr sep,UserObjectPtr uop)11145 static void AddStructuredCommentToSeqEntry (SeqEntryPtr sep, UserObjectPtr uop)
11146 {
11147   BioseqSetPtr bssp;
11148   SeqDescPtr   sdp;
11149 
11150   while (sep != NULL)
11151   {
11152     if (IS_Bioseq (sep))
11153     {
11154       sdp = CreateNewDescriptor (sep, Seq_descr_user);
11155       if (sdp != NULL)
11156       {
11157         sdp->data.ptrvalue = (UserObjectPtr) AsnIoMemCopy (uop,
11158                                                            (AsnReadFunc) UserObjectAsnRead,
11159                                                            (AsnWriteFunc) UserObjectAsnWrite);
11160       }
11161     }
11162     else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL)
11163     {
11164       if (bssp->_class == BioseqseqSet_class_nuc_prot)
11165       {
11166         sdp = CreateNewDescriptor (sep, Seq_descr_user);
11167         if (sdp != NULL)
11168         {
11169           sdp->data.ptrvalue = (UserObjectPtr) AsnIoMemCopy (uop,
11170                                                              (AsnReadFunc) UserObjectAsnRead,
11171                                                              (AsnWriteFunc) UserObjectAsnWrite);
11172         }
11173       }
11174       else
11175       {
11176         AddStructuredCommentToSeqEntry (bssp->seq_set, uop);
11177       }
11178     }
11179     sep = sep->next;
11180   }
11181 }
11182 
11183 
AddStructuredCommentsFromWizard(SeqEntryPtr sep,ValNodePtr structured_comments)11184 static void AddStructuredCommentsFromWizard (SeqEntryPtr sep, ValNodePtr structured_comments)
11185 {
11186   ValNodePtr vnp;
11187 
11188   for (vnp = structured_comments; vnp != NULL; vnp = vnp->next)
11189   {
11190     AddStructuredCommentToSeqEntry (sep, (UserObjectPtr) vnp->data.ptrvalue);
11191   }
11192 }
11193 
11194 
11195 static CharPtr  tpaString = NULL;
11196 
FinishPuttingTogether(ForM f)11197 static void FinishPuttingTogether (ForM f)
11198 
11199 {
11200   BaseFormPtr       bfp;
11201   BioseqSetPtr      bssp;
11202   Uint2             entityID = 0;
11203   Int2              handled;
11204   ObjMgrDataPtr     omdp;
11205   SubmitBlockPtr    sbp;
11206   SeqEntryPtr       sep = NULL;
11207   SequencesFormPtr  sqfp;
11208   SeqSubmitPtr      ssp;
11209   ValNodePtr        bad_list = NULL;
11210   SeqEntryPtr       nuc_list;
11211   SequencingMethodInfoPtr info;
11212 
11213   bfp = (BaseFormPtr) GetObjectExtra (f);
11214   if (bfp == NULL) {
11215     return;
11216   }
11217   sqfp = (SequencesFormPtr) bfp;
11218 
11219   /* collect sequencing method information */
11220   info = DialogToPointer (sqfp->sequencing_method_dlg);
11221   if (info != NULL) {
11222     nuc_list = GetSequencesFormNucleotideList (bfp->form);
11223     AddStructuredCommentsFromWizard (nuc_list, info->structured_comments);
11224     info = SequencingMethodInfoFree (info);
11225   }
11226 
11227   sep = (SeqEntryPtr) FormToPointer (bfp->form);
11228   if (sep != NULL) {
11229 /*#ifdef USE_TAXON*/
11230     if (! leaveAsOldAsn) {
11231       MySeqEntryToAsn3 (sep, TRUE, FALSE, FALSE);
11232     }
11233 /*#endif*/
11234     entityID = PackageFormResults (globalsbp, sep, TRUE);
11235 
11236     /* remove special characters */
11237     StringActionInEntity (entityID, FALSE, UPDATE_NEVER, NULL, NULL, NULL, TRUE,
11238                           SpecialCharFindWithContext, NULL, &bad_list);\
11239     FixSpecialCharactersForStringsInList (bad_list,
11240             "You must replace non-ASCII characters.", TRUE);
11241     bad_list = FreeContextList (bad_list);
11242 
11243 
11244     sqfp = (SequencesFormPtr) bfp;
11245     if (SEQ_TPA_SUBMISSION == sqfp->submType && entityID > 0) {
11246       omdp = ObjMgrGetData (entityID);
11247       if (omdp != NULL && omdp->datatype == OBJ_SEQSUB) {
11248         ssp = (SeqSubmitPtr) omdp->dataptr;
11249         if (ssp != NULL && ssp->datatype == 1) {
11250           sbp = ssp->sub;
11251           if (sbp != NULL) {
11252             if (sbp->comment == NULL && StringDoesHaveText (tpaString)) {
11253               sbp->comment = tpaString;
11254               tpaString = NULL;
11255             }
11256           }
11257         }
11258       }
11259     }
11260     globalsbp = NULL;
11261     WatchCursor ();
11262     seqviewprocs.forceSeparateViewer = TRUE;
11263     SeqEntrySetScope (NULL);
11264     handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
11265                                 OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
11266     ArrowCursor ();
11267     if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
11268       Message (MSG_FATAL, "Unable to launch viewer.");
11269     } else {
11270       SendHelpScrollMessage (helpForm, "Editing the Record", NULL);
11271     }
11272     ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
11273     ObjMgrSetDirtyFlag (entityID, TRUE);
11274   } else if (allowUnableToProcessMessage) {
11275     Message (MSG_FATAL, "Unable to process Seq-entry.");
11276   }
11277   if (SEQ_TPA_SUBMISSION == sqfp->submType) {
11278     s_GetTpaInfo (sqfp);
11279   }
11280 
11281   /*SetChecklistValue (checklistForm, 5);*/
11282   Remove (bfp->form);
11283   if (sep != NULL && entityID > 0 && IS_Bioseq_set (sep)) {
11284     bssp = (BioseqSetPtr) sep->data.ptrvalue;
11285     if (bssp != NULL && (IsPopPhyEtcSet (bssp->_class))) {
11286       if (SeqEntryHasAligns (entityID, sep)) {
11287         Message (MSG_OK, "%s", canfeatpropagate);
11288       }
11289     }
11290   }
11291 }
11292 
11293 
CustomOkCancelMessage(CharPtr msg,CharPtr ok_label,CharPtr back_label)11294 static Boolean CustomOkCancelMessage (CharPtr msg, CharPtr ok_label, CharPtr back_label)
11295 {
11296   ModalAcceptCancelData acd;
11297   WindoW                w;
11298   GrouP                 h, c;
11299   GrouP                 txt;
11300   ButtoN                b;
11301   Boolean               rval = FALSE;
11302 
11303   acd.accepted = FALSE;
11304   acd.cancelled = FALSE;
11305   acd.third_option = FALSE;
11306 
11307   w = ModalWindow(-20, -13, -10, -10, NULL);
11308   h = HiddenGroup (w, -1, 0, NULL);
11309   SetGroupSpacing (h, 10, 10);
11310 
11311   txt = MultiLinePrompt (h, msg, 30 * stdCharWidth, systemFont);
11312 
11313   c = HiddenGroup (h, 3, 0, NULL);
11314   SetGroupSpacing (c, 10, 10);
11315   b = PushButton (c, ok_label, ModalAcceptButton);
11316   SetObjectExtra (b, &acd, NULL);
11317   b = PushButton (c, back_label, ModalCancelButton);
11318   SetObjectExtra (b, &acd, NULL);
11319   AlignObjects (ALIGN_CENTER, (HANDLE) txt, (HANDLE) c, NULL);
11320 
11321   Show(w);
11322   Select (w);
11323   while (!acd.accepted && ! acd.cancelled)
11324   {
11325     ProcessExternalEvent ();
11326     Update ();
11327   }
11328   ProcessAnEvent ();
11329   Remove (w);
11330   if (acd.accepted)
11331   {
11332     rval = TRUE;
11333   }
11334   return rval;
11335 }
11336 
SequencingMethodInfoNew(void)11337 NLM_EXTERN SequencingMethodInfoPtr SequencingMethodInfoNew (void)
11338 {
11339   SequencingMethodInfoPtr info;
11340 
11341   info = (SequencingMethodInfoPtr) MemNew (sizeof(SequencingMethodInfoData));
11342   return info;
11343 }
11344 
11345 
SequencingMethodInfoFree(SequencingMethodInfoPtr info)11346 NLM_EXTERN SequencingMethodInfoPtr SequencingMethodInfoFree (SequencingMethodInfoPtr info)
11347 {
11348   info = MemFree (info);
11349   return info;
11350 }
11351 
11352 
11353 static CharPtr s_AnnotationHelpMsgs[] = {
11354 "\
11355 Add Feature Annotation in the Record Viewer:\n\
11356 --------------------------------------------\n\
11357 \n\
11358 - Use the Annotate Menu \n\
11359 For more information, please see:\n\
11360 http://www.ncbi.nlm.nih.gov/Sequin/sequin.hlp.html#AnnotateMenu\n\
11361 \n\
11362 \n\
11363 - Upload a five-column, tab-delimited feature table.\n\
11364 ",
11365 "\
11366 Upload your table in the record viewer using \"Open\" in \n\
11367 the File menu.\n\
11368 \n\
11369 For more information about feature tables, please see:\n\
11370 http://www.ncbi.nlm.nih.gov/Sequin/table.html#Table Layout\n\
11371 \n\
11372 \n\
11373 - If you have questions about how to annotate your\n\
11374 records, please contact: info@ncbi.nlm.nih.gov\n\
11375 \n\
11376 ",
11377 NULL};
11378 
11379 static CharPtr multcomponent = "\
11380 ERROR - You may not enter multiple segments for a single sequence submission.\n\
11381 You should either clear the nucleotide and import a single FASTA record, or \n\
11382 return to the Sequence Format form and choose the proper submission type.";
11383 
11384 
11385 /*---------------------------------------------------------------------*/
11386 /*                                                                     */
11387 /* PutItTogether () --                                                 */
11388 /*                                                                     */
11389 /*---------------------------------------------------------------------*/
11390 
PutItTogether(ButtoN b)11391 static void PutItTogether (ButtoN b)
11392 
11393 {
11394   MsgAnswer    ans;
11395   BaseFormPtr  bfp;
11396   ValNodePtr   head;
11397   SeqEntryPtr  prot_list = NULL, nuc_list = NULL;
11398   SequencesFormPtr sqfp;
11399   SubmissionFeatureInfoPtr sfinfo;
11400   Boolean      ok_to_continue = TRUE;
11401 
11402   bfp = (BaseFormPtr) GetObjectExtra (b);
11403   if (bfp != NULL) {
11404     head = TestForm (bfp->form);
11405     if (! DisplayAndFreeTestResults (head)) {
11406       return;
11407     }
11408     if (SequencesFormHasTooManyNucleotides (bfp->form)) {
11409       Message (MSG_OK, "%s", multcomponent);
11410       return;
11411     }
11412 
11413     if (TRUE == HasZeroLengthSequence (bfp->form)) {
11414       Message (MSG_POSTERR, "One or more of the submitted sequences are "
11415 	       "zero length.  Zero-length sequences are not allowed. Your "
11416 	       "FASTA sequence may be missing a carriage return after the "
11417 	       "definition line, or may have other formatting problems. "
11418 	       "Please check your FASTA file.");
11419       return;
11420     }
11421 
11422     sqfp = (SequencesFormPtr) GetObjectExtra (bfp->form);
11423 
11424     /* check for proteins, create nucleotide-protein association */
11425     prot_list = GetSequencesFormProteinList (bfp->form);
11426     if (prot_list == NULL && ! SequencesFormHasProteins (bfp->form)) {
11427       if (IsAnnotTabEmpty (sqfp)) {
11428         ans = Message (MSG_OKC, "You have not entered proteins and have not created any features.  Is this correct?");
11429       } else {
11430         ans = Message (MSG_OKC, "You have not entered proteins.  Is this correct?");
11431       }
11432       if (ans == ANS_CANCEL)
11433       {
11434         ok_to_continue = FALSE;
11435       }
11436     }
11437     else if (prot_list != NULL)
11438     {
11439       nuc_list = GetSequencesFormNucleotideList (bfp->form);
11440       if (sqfp != NULL)
11441       {
11442         sqfp->nuc_prot_assoc_list = FreeAssociationList (sqfp->nuc_prot_assoc_list);
11443         sqfp->nuc_prot_assoc_list = AssignProteinsForSequenceSet (nuc_list, prot_list, FALSE);
11444         if (sqfp->nuc_prot_assoc_list == NULL)
11445         {
11446           ok_to_continue = FALSE;
11447         }
11448       }
11449     }
11450     else if (prot_list == NULL)
11451     {
11452       sqfp = (SequencesFormPtr) GetObjectExtra (bfp->form);
11453       sfinfo = GetSubmissionFeatureInfo (sqfp);
11454       if (sfinfo == NULL)
11455       {
11456         /* indicates that NONE was selected */
11457         if (CustomOkCancelMessage ("Please add annotation to your submission in the record viewer.", "Continue to record viewer", "Back to submission dialog"))
11458         {
11459           ShowWizardHelpText ("Adding Annotation", s_AnnotationHelpMsgs);
11460 
11461         }
11462         else
11463         {
11464           ok_to_continue = FALSE;
11465         }
11466       }
11467       else if (sfinfo->feature_type == FEATDEF_CDS
11468           && StringHasNoText (sfinfo->product))
11469       {
11470         ok_to_continue = FALSE;
11471         Message (MSG_ERROR, "You selected CDS annotation, but you did not provide a protein name. Please enter a protein name.");
11472       }
11473       sfinfo = SubmissionFeatureInfoFree (sfinfo);
11474     }
11475     if (!ok_to_continue)
11476     {
11477       return;
11478     }
11479 
11480     Hide (bfp->form);
11481     ConfirmSequencesFormParsing (bfp->form, FinishPuttingTogether);
11482   }
11483 }
11484 
11485 static void GetOrgAndSeq (ButtoN b);
11486 static void BackToStartup (ButtoN b);
BackToFormat(ButtoN b)11487 static void BackToFormat (ButtoN b)
11488 
11489 {
11490   MsgAnswer    ans;
11491   BaseFormPtr  bfp;
11492 
11493   bfp = (BaseFormPtr) GetObjectExtra (b);
11494   if (bfp != NULL) {
11495     ans = Message (MSG_OKC, "Are you sure?  Organism and sequence information will be lost.");
11496     if (ans == ANS_CANCEL) return;
11497     Remove (bfp->form);
11498     WatchCursor ();
11499     Update ();
11500     PointerToForm (formatForm, &globalFormatBlock);
11501     Show (formatForm);
11502     Select (formatForm);
11503     SendHelpScrollMessage (helpForm, "Sequence Format Form", NULL);
11504     ArrowCursor ();
11505     Update ();
11506   }
11507 }
11508 
FinishOrgAndSeq(void)11509 static void FinishOrgAndSeq (void)
11510 
11511 {
11512   MonitorPtr  mon;
11513   ForM        w;
11514 
11515   WatchCursor ();
11516   mon = MonitorStrNewEx ("Sequin New Submission", 30, FALSE);
11517   MonitorStrValue (mon, "Creating Sequences Form");
11518   Update ();
11519   w = CreateInitOrgNucProtForm (-5, -67, "Organism and Sequences",
11520                                 &globalFormatBlock,
11521                                 PutItTogether, BackToFormat,
11522                                 OrgAndSeqsActivateProc);
11523   ArrowCursor ();
11524   /*SetChecklistValue (checklistForm, 1);*/
11525   MonitorFree (mon);
11526   Update ();
11527   if (w != NULL) {
11528     Show (w);
11529     Select (w);
11530     if (globalFormatBlock.seqFormat == SEQ_FMT_ALIGNMENT) {
11531       SendHelpScrollMessage (helpForm, "Nucleotide Page", "Nucleotide Page for Aligned Data Formats");
11532     } else {
11533       SendHelpScrollMessage (helpForm, "Nucleotide Page", "Nucleotide Page for FASTA Data Format");
11534     }
11535   } else {
11536     Message (MSG_FATAL, "Unable to create window.");
11537   }
11538   Update ();
11539 }
11540 
BackToSubmitter(ButtoN b)11541 static void BackToSubmitter (ButtoN b)
11542 
11543 {
11544   MsgAnswer    ans;
11545 
11546   ans = Message (MSG_OKC, "Are you sure?  Format information will be lost.");
11547   if (ans == ANS_CANCEL) return;
11548 
11549   Hide (formatForm);
11550   Update ();
11551   if (indexerVersion) {
11552     Show (wizardChoiceForm);
11553     SendHelpScrollMessage (helpForm, "Preparing the Sequences", "");
11554     Update();
11555   } else {
11556     PointerToForm (initSubmitForm, globalsbp);
11557     globalsbp = SequinBlockFree (globalsbp);
11558     Show (initSubmitForm);
11559     Select (initSubmitForm);
11560     SendHelpScrollMessage (helpForm, "Submitting Authors Form", NULL);
11561     Update ();
11562     globalFormatBlock.seqPackage = SEQ_PKG_SINGLE;
11563     globalFormatBlock.seqFormat = SEQ_FMT_FASTA;
11564     globalFormatBlock.numSeqs = 0;
11565     globalFormatBlock.submType = SEQ_ORIG_SUBMISSION;
11566   }
11567 }
11568 
11569 
FixSpecialCharactersInSequinBlock(SequinBlockPtr sbp)11570 static void FixSpecialCharactersInSequinBlock (SequinBlockPtr sbp)
11571 {
11572   ValNodePtr find_list = NULL;
11573   SeqSubmitPtr ssp;
11574   SeqDescPtr sdp;
11575 
11576   ssp = SeqSubmitNew ();
11577   ssp->sub = SubmitBlockNew ();
11578   ssp->sub->contact = ContactInfoNew();
11579   ssp->sub->contact->contact = sbp->contactperson;
11580   ssp->sub->cit = CitSubNew();
11581   ssp->sub->cit->authors = sbp->citsubauthors;
11582   ssp->sub->cit->authors->affil = sbp->citsubaffil;
11583   ssp->sub->cit->descr = sbp->citsubtitle;
11584 
11585   StringActionForObject (OBJ_SEQSUB, ssp, 0, FALSE, UPDATE_NEVER,
11586                         SpecialCharFindWithContext, NULL, &find_list);
11587   for (sdp = sbp->descriptors; sdp != NULL; sdp = sdp->next) {
11588     StringActionForObject (OBJ_SEQDESC, sdp, 0, FALSE, UPDATE_NEVER,
11589                           SpecialCharFindWithContext, NULL, &find_list);
11590   }
11591 
11592   FixSpecialCharactersForStringsInList (find_list, "You must replace all non-ASCII characters.", TRUE);
11593   find_list = FreeContextList (find_list);
11594   ssp->sub->contact->contact = NULL;
11595   ssp->sub->contact = ContactInfoFree (ssp->sub->contact);
11596   ssp->sub->cit->authors->affil = NULL;
11597   ssp->sub->cit->authors = NULL;
11598   ssp->sub->cit->descr = NULL;
11599   ssp->sub->cit = CitSubFree (ssp->sub->cit);
11600   ssp = SeqSubmitFree (ssp);
11601 }
11602 
GetFormat(ButtoN b)11603 static void GetFormat (ButtoN b)
11604 
11605 {
11606   ValNodePtr   head;
11607 
11608   head = TestForm (initSubmitForm);
11609   if (! DisplayAndFreeTestResults (head)) {
11610     return;
11611   }
11612   Hide (initSubmitForm);
11613   globalsbp = (SequinBlockPtr) FormToPointer (initSubmitForm);
11614   /* check for special characters */
11615   FixSpecialCharactersInSequinBlock(globalsbp);
11616   if (globalsbp == NULL) {
11617     Message (MSG_OK, "Record will be a Seq-entry instead of a Seq-submit.");
11618   }
11619 
11620   Show (wizardChoiceForm);
11621   SendHelpScrollMessage (helpForm, "Preparing the Sequences", "");
11622   Select (wizardChoiceForm);
11623   Update ();
11624 }
11625 
11626 static WindoW   tpaWindow = NULL;
11627 static TexT     tpaText = NULL;
11628 static ButtoN   tpaNext = NULL;
11629 /* tpaString defined above FinishPuttingTogether */
11630 
TpaPrev(ButtoN b)11631 static void TpaPrev (ButtoN b)
11632 
11633 {
11634   Hide (tpaWindow);
11635   tpaString = MemFree (tpaString);
11636   SetTitle (tpaText, "");
11637   Show (formatForm);
11638   Select (formatForm);
11639   SendHelpScrollMessage (helpForm, "Sequence Format Form", NULL);
11640   Update ();
11641 }
11642 
TpaNext(ButtoN b)11643 static void TpaNext (ButtoN b)
11644 
11645 {
11646   tpaString = MemFree (tpaString);
11647   tpaString = SaveStringFromText (tpaText);
11648   if (StringHasNoText (tpaString)) {
11649     Message (MSG_OK, "The requested information is required in order for you to be able to proceed with a TPA submission");
11650     return;
11651   }
11652   Hide (tpaWindow);
11653   WatchCursor ();
11654   FinishOrgAndSeq ();
11655 }
11656 
TpaText(TexT t)11657 static void TpaText (TexT t)
11658 
11659 {
11660   if (TextHasNoText (t)) {
11661     SafeDisable (tpaNext);
11662   } else {
11663     SafeEnable (tpaNext);
11664   }
11665 }
11666 
11667 static CharPtr tpaMssg = "\
11668 Third party annotation records require a publication describing the biological \
11669 experiments used as evidence for the annotation.  Please provide information \
11670 regarding the nature of these experiments.";
11671 
DoTpaForm(void)11672 static void DoTpaForm (void)
11673 
11674 {
11675   GrouP   c, h, p;
11676 
11677   if (tpaWindow == NULL) {
11678     tpaWindow = FixedWindow (-50, -33, -10, -10, "TPA Evidence", NULL);
11679     h = HiddenGroup (tpaWindow, -1, 0, NULL);
11680     SetGroupSpacing (h, 10, 10);
11681 
11682     p = MultiLinePrompt (h, tpaMssg, 30 * stdCharWidth, programFont);
11683 
11684     tpaText = ScrollText (h, 30, 5, programFont, TRUE, TpaText);
11685 
11686     c = HiddenGroup (h, 2, 0, NULL);
11687     PushButton (c, "<< Prev Form", TpaPrev);
11688     tpaNext = PushButton (c, "Next Form >>", TpaNext);
11689 
11690     AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) tpaText, (HANDLE) c, NULL);
11691 
11692     RealizeWindow (tpaWindow);
11693   }
11694   tpaString = MemFree (tpaString);
11695   SafeSetTitle (tpaText, "");
11696   SafeDisable (tpaNext);
11697   Show (tpaWindow);
11698   Select (tpaWindow);
11699 }
11700 
GetOrgAndSeq(ButtoN b)11701 static void GetOrgAndSeq (ButtoN b)
11702 
11703 {
11704   /*
11705   MsgAnswer       ans;
11706   */
11707   FormatBlockPtr  fbp;
11708   Boolean         is_tpa = FALSE;
11709 
11710   Hide (formatForm);
11711   fbp = (FormatBlockPtr) FormToPointer (formatForm);
11712   if (fbp != NULL) {
11713     globalFormatBlock.seqPackage = fbp->seqPackage;
11714     globalFormatBlock.seqFormat = fbp->seqFormat;
11715     globalFormatBlock.numSeqs = fbp->numSeqs;
11716     globalFormatBlock.submType = fbp->submType;
11717     is_tpa = (Boolean) (globalFormatBlock.submType == SEQ_TPA_SUBMISSION);
11718   }
11719   MemFree (fbp);
11720   if (is_tpa) {
11721     DoTpaForm ();
11722     /*
11723     ans = Message (MSG_YN, "%s", tpaMssg);
11724     if (ans == ANS_YES) {
11725       WatchCursor ();
11726       FinishOrgAndSeq ();
11727     } else {
11728       Show (formatForm);
11729       Select (formatForm);
11730       SendHelpScrollMessage (helpForm, "Sequence Format Form", NULL);
11731       Update ();
11732     }
11733     */
11734   } else {
11735     WatchCursor ();
11736     FinishOrgAndSeq ();
11737   }
11738 }
11739 
BackToStartup(ButtoN b)11740 static void BackToStartup (ButtoN b)
11741 
11742 {
11743   MsgAnswer    ans;
11744 
11745   ans = Message (MSG_OKC, "Are you sure?  Submitter information will be lost.");
11746   if (ans == ANS_CANCEL) return;
11747   Hide (initSubmitForm);
11748   Update ();
11749   Show (startupForm);
11750   Select (startupForm);
11751   SendHelpScrollMessage (helpForm, "Introduction", NULL);
11752   Update ();
11753 }
11754 
ShowHelp(ButtoN b)11755 static void ShowHelp (ButtoN b)
11756 
11757 {
11758   if (helpForm == NULL) {
11759     WatchCursor ();
11760     helpForm = CreateHelpForm (-95, -5, "Sequin Help", "sequin.hlp",
11761                                HideHelpForm, HelpActivateProc);
11762     ArrowCursor ();
11763   }
11764   if (helpForm != NULL) {
11765     Show (helpForm);
11766     Select (helpForm);
11767   }
11768 }
11769 
StartNew(ButtoN b)11770 static void StartNew (ButtoN b)
11771 
11772 {
11773   Hide (startupForm);
11774   Update ();
11775   PointerToForm (initSubmitForm, NULL);
11776   Show (initSubmitForm);
11777   Select (initSubmitForm);
11778   SendHelpScrollMessage (helpForm, "Submitting Authors Form", NULL);
11779   Update ();
11780 }
11781 
CloseSubmissionTemplateEditor(Pointer userdata,WindoW w)11782 static void CloseSubmissionTemplateEditor (Pointer userdata, WindoW w)
11783 {
11784   Remove (w);
11785   Show (startupForm);
11786   Update ();
11787 }
11788 
CreateSubmissionTemplate(ButtoN b)11789 static void CreateSubmissionTemplate (ButtoN b)
11790 
11791 {
11792   WindoW w;
11793 
11794   Hide (startupForm);
11795   Update ();
11796 
11797   w = (WindoW) CreateSubmitTemplateEditorForm (-50, -33, "Submission Template Editor",
11798                                       CloseSubmissionTemplateEditor, NULL);
11799 
11800   Show (w);
11801 }
11802 
FinishGenome(ButtoN b)11803 static void FinishGenome (ButtoN b)
11804 
11805 {
11806   BaseFormPtr   bfp;
11807   Uint2         entityID;
11808   Int2          handled;
11809   SeqEntryPtr   sep;
11810   SeqSubmitPtr  ssp;
11811 
11812   bfp = (BaseFormPtr) GetObjectExtra (b);
11813   if (bfp == NULL) return;
11814   ssp = (SeqSubmitPtr) FormToPointer (bfp->form);
11815   if (ssp == NULL) return;
11816   if (ssp->datatype != 1) return;
11817   sep = (SeqEntryPtr) ssp->data;
11818   if (sep == NULL) return;
11819   ObjMgrConnect (OBJ_SEQENTRY, sep->data.ptrvalue, OBJ_SEQSUB, (Pointer) ssp);
11820   if (! ObjMgrRegister (OBJ_SEQSUB, (Pointer) ssp)) {
11821     ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrRegister failed.");
11822   }
11823   if (! leaveAsOldAsn) {
11824     MySeqEntryToAsn3 (sep, TRUE, FALSE, FALSE);
11825   }
11826   entityID = ObjMgrGetEntityIDForChoice (sep);
11827   WatchCursor ();
11828   seqviewprocs.forceSeparateViewer = TRUE;
11829   SeqEntrySetScope (NULL);
11830   handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
11831                               OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
11832   ArrowCursor ();
11833   if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
11834     Message (MSG_FATAL, "Unable to launch viewer.");
11835   } else {
11836     SendHelpScrollMessage (helpForm, "Editing the Record", NULL);
11837   }
11838   ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
11839   ObjMgrSetDirtyFlag (entityID, TRUE);
11840 }
11841 
CancelGenome(ButtoN b)11842 static void CancelGenome (ButtoN b)
11843 
11844 {
11845   Show (startupForm);
11846   Select (startupForm);
11847   SendHelpScrollMessage (helpForm, "Introduction", NULL);
11848   Update ();
11849 }
11850 
StartFa2htgs(ButtoN b)11851 static void StartFa2htgs (ButtoN b)
11852 
11853 {
11854   ForM  f;
11855 
11856   Hide (startupForm);
11857   Update ();
11858   f = CreateGenomeCenterForm (-50, -33, "HTGS Submission",
11859                               FinishGenome, CancelGenome, FALSE, FALSE,
11860                               GenomeFormActivateProc);
11861   if (f != NULL) {
11862     Show (f);
11863     Select (f);
11864   } else {
11865     Show (startupForm);
11866   }
11867   Update ();
11868 }
11869 
StartPhrap(ButtoN b)11870 static void StartPhrap (ButtoN b)
11871 
11872 {
11873   ForM  f;
11874 
11875   Hide (startupForm);
11876   Update ();
11877   f = CreateGenomeCenterForm (-50, -33, "PHRAP Submission",
11878                               FinishGenome, CancelGenome, TRUE, FALSE,
11879                               GenomeFormActivateProc);
11880   if (f != NULL) {
11881     Show (f);
11882     Select (f);
11883   } else {
11884     Show (startupForm);
11885   }
11886   Update ();
11887 }
11888 
BuildContig(ButtoN b)11889 static void BuildContig (ButtoN b)
11890 
11891 {
11892   ForM  f;
11893 
11894   Hide (startupForm);
11895   Update ();
11896   f = CreateGenomeCenterForm (-50, -33, "Contig Submission",
11897                               FinishGenome, CancelGenome, FALSE, TRUE,
11898                               GenomeFormActivateProc);
11899   if (f != NULL) {
11900     Show (f);
11901     Select (f);
11902   } else {
11903     Show (startupForm);
11904   }
11905   Update ();
11906 /*
11907   Hide (startupForm);
11908   Update ();
11909   if (! DoBuildContig ()) {
11910     Show (startupForm);
11911   }
11912   Update ();
11913 */
11914 }
11915 
ReadOld(ButtoN b)11916 static void ReadOld (ButtoN b)
11917 
11918 {
11919   Hide (startupForm);
11920   Update ();
11921   if (! CommonReadNewAsnProc (NULL, FALSE, TRUE)) {
11922     Show (startupForm);
11923     Select (startupForm);
11924   }
11925 }
11926 
ReadSettings(void)11927 static void ReadSettings (void)
11928 
11929 {
11930   Char  str [64];
11931 
11932   useDesktop = FALSE;
11933   useEntrez = FALSE;
11934   useLocal = FALSE;
11935   useIdLookup = FALSE;
11936   useBlast = FALSE;
11937   useMedarch = FALSE;
11938   newMedarch = FALSE;
11939   useTaxon = FALSE;
11940   allowDownload = FALSE;
11941   extraServices = FALSE;
11942   indexerVersion = FALSE;
11943 
11944   genomeCenter = NULL;
11945 
11946 #ifdef INTERNAL_NCBI_SEQUIN
11947   indexerVersion = TRUE;
11948   extraServices = TRUE;
11949   useDesktop = TRUE;
11950   useEntrez = TRUE;
11951   useLocal = TRUE;
11952   useIdLookup = TRUE;
11953   useBlast = TRUE;
11954   useMedarch = TRUE;
11955   newMedarch = TRUE;
11956   useTaxon = TRUE;
11957   allowDownload = TRUE;
11958 #endif
11959   if (GetSequinAppParam ("SETTINGS", "INDEXERVERSION", NULL, str, sizeof (str))) {
11960     if (StringICmp (str, "TRUE") == 0) {
11961       indexerVersion = TRUE;
11962       extraServices = TRUE;
11963       useDesktop = TRUE;
11964       useEntrez = TRUE;
11965       useLocal = TRUE;
11966       useIdLookup = TRUE;
11967       useBlast = TRUE;
11968       useMedarch = TRUE;
11969       newMedarch = TRUE;
11970       useTaxon = TRUE;
11971       allowDownload = TRUE;
11972     }
11973   }
11974 
11975 #ifdef PUBLIC_NETWORK_SEQUIN
11976   useDesktop = TRUE;
11977   useEntrez = TRUE;
11978   useLocal = TRUE;
11979   useIdLookup = TRUE;
11980   useBlast = TRUE;
11981   useMedarch = TRUE;
11982   newMedarch = TRUE;
11983   useTaxon = TRUE;
11984   allowDownload = TRUE;
11985 #endif
11986   if (GetSequinAppParam ("SETTINGS", "PUBLICNETWORKSEQUIN", NULL, str, sizeof (str))) {
11987     if (StringICmp (str, "TRUE") == 0) {
11988       useDesktop = TRUE;
11989       useEntrez = TRUE;
11990       useLocal = TRUE;
11991       useIdLookup = TRUE;
11992       useBlast = TRUE;
11993       useMedarch = TRUE;
11994       newMedarch = TRUE;
11995       useTaxon = TRUE;
11996       allowDownload = TRUE;
11997     }
11998   }
11999 
12000 #ifdef USE_DESKTOP
12001   useDesktop = TRUE;
12002 #endif
12003   if (GetSequinAppParam ("SETTINGS", "USEDESKTOP", NULL, str, sizeof (str))) {
12004     if (StringICmp (str, "TRUE") == 0) {
12005       useDesktop = TRUE;
12006     }
12007   }
12008 
12009 #ifdef USE_ENTREZ
12010   useEntrez = TRUE;
12011 #endif
12012   if (GetSequinAppParam ("SETTINGS", "USEENTREZ", NULL, str, sizeof (str))) {
12013     if (StringICmp (str, "TRUE") == 0) {
12014       useEntrez = TRUE;
12015     }
12016   }
12017 
12018 #ifdef USE_BLAST
12019   useBlast = TRUE;
12020 #endif
12021   if (GetSequinAppParam ("SETTINGS", "USEBLAST", NULL, str, sizeof (str))) {
12022     if (StringICmp (str, "TRUE") == 0) {
12023       useBlast = TRUE;
12024     }
12025   }
12026 
12027 #ifdef USE_MEDARCH
12028   useMedarch = TRUE;
12029   newMedarch = TRUE;
12030 #endif
12031   if (GetSequinAppParam ("SETTINGS", "USEMEDARCH", NULL, str, sizeof (str))) {
12032     if (StringICmp (str, "TRUE") == 0) {
12033       useMedarch = TRUE;
12034       newMedarch = TRUE;
12035     }
12036   }
12037   if (GetSequinAppParam ("SETTINGS", "NEWMEDARCH", NULL, str, sizeof (str))) {
12038     if (StringICmp (str, "FALSE") == 0) {
12039       newMedarch = FALSE;
12040     }
12041   }
12042 
12043 #ifdef USE_TAXON
12044   useTaxon = TRUE;
12045 #endif
12046   if (GetSequinAppParam ("SETTINGS", "USETAXON", NULL, str, sizeof (str))) {
12047     if (StringICmp (str, "TRUE") == 0) {
12048       useTaxon = TRUE;
12049     }
12050   }
12051 
12052 #ifdef ALLOW_DOWNLOAD
12053   allowDownload = TRUE;
12054 #endif
12055   if (GetSequinAppParam ("SETTINGS", "ALLOWDOWNLOAD", NULL, str, sizeof (str))) {
12056     if (StringICmp (str, "TRUE") == 0) {
12057       allowDownload = TRUE;
12058       useEntrez = TRUE;
12059     }
12060   }
12061 
12062 #ifdef EXTRA_SERVICES
12063   extraServices = TRUE;
12064 #endif
12065   if (GetSequinAppParam ("SETTINGS", "USEEXTRASERVICES", NULL, str, sizeof (str))) {
12066     if (StringICmp (str, "TRUE") == 0) {
12067       extraServices = TRUE;
12068     }
12069   }
12070 
12071   if (GetSequinAppParam ("SETTINGS", "SUPPRESSENTREZ", NULL, str, sizeof (str))) {
12072     if (StringICmp (str, "TRUE") == 0) {
12073       allowDownload = FALSE;
12074       useEntrez = FALSE;
12075       useMedarch = FALSE;
12076       useTaxon = FALSE;
12077     }
12078   }
12079 
12080   useSeqFetch = useEntrez;
12081 
12082   if (GetSequinAppParam ("SETTINGS", "SUPPRESSSEQFETCH", NULL, str, sizeof (str))) {
12083     if (StringICmp (str, "TRUE") == 0) {
12084       useSeqFetch = FALSE;
12085     }
12086   }
12087 
12088   if (GetSequinAppParam ("SETTINGS", "SUPPRESSIDLOOKUP", NULL, str, sizeof (str))) {
12089     if (StringICmp (str, "TRUE") == 0) {
12090       useIdLookup = FALSE;
12091     }
12092   }
12093 
12094 #ifdef USE_LOCAL
12095   useLocal = TRUE;
12096 #endif
12097   if (GetSequinAppParam ("SETTINGS", "USELOCAL", NULL, str, sizeof (str))) {
12098     if (StringICmp (str, "TRUE") == 0) {
12099       useLocal = TRUE;
12100     } else if (StringICmp (str, "FALSE") == 0) {
12101       useLocal = FALSE;
12102     }
12103   }
12104 
12105   if (GetSequinAppParam ("SETTINGS", "SUPPRESSLOCAL", NULL, str, sizeof (str))) {
12106     if (StringICmp (str, "TRUE") == 0) {
12107       useLocal = FALSE;
12108     }
12109   }
12110 
12111   if (GetSequinAppParam ("SETTINGS", "GENOMETAG", NULL, str, sizeof (str))) {
12112     TrimSpacesAroundString (str);
12113     if (! StringHasNoText (str)) {
12114       genomeCenter = StringSave (str);
12115       extraServices = TRUE;
12116     }
12117   } else if (GetSequinAppParam ("SETTINGS", "GENOMECENTER", NULL, str, sizeof (str))) {
12118     TrimSpacesAroundString (str);
12119     if (! StringHasNoText (str)) {
12120       genomeCenter = StringSave (str);
12121       extraServices = TRUE;
12122     }
12123   }
12124 
12125   loadSaveUidListOK = useEntrez;
12126   if (GetSequinAppParam ("PREFERENCES", "LOADSAVEUIDLIST", NULL, str, sizeof (str))) {
12127     if (StringICmp (str, "FALSE") == 0) {
12128       loadSaveUidListOK = FALSE;
12129     }
12130   }
12131 
12132   if (GetSequinAppParam ("SETTINGS", "USEOLDGRAPHICAL", NULL, str, sizeof (str))) {
12133     if (StringICmp (str, "TRUE") == 0) {
12134       useOldGraphicView = TRUE;
12135     }
12136   }
12137 
12138   if (GetSequinAppParam ("SETTINGS", "USEOLDALIGNMENT", NULL, str, sizeof (str))) {
12139     if (StringICmp (str, "TRUE") == 0) {
12140       useOldAlignmentView = TRUE;
12141     }
12142   }
12143 
12144   if (GetSequinAppParam ("SETTINGS", "USEOLDSEQVIEW", NULL, str, sizeof (str))) {
12145     if (StringICmp (str, "TRUE") == 0) {
12146       useOldSequenceView = TRUE;
12147     }
12148   }
12149 
12150   /*
12151   if (GetSequinAppParam ("SETTINGS", "USEUDV", NULL, str, sizeof (str))) {
12152     if (StringICmp (str, "TRUE") == 0) {
12153       useUdv = TRUE;
12154     }
12155   }
12156   */
12157 
12158   if (GetSequinAppParam ("SETTINGS", "EDITGBSOURCEQUALS", NULL, str, sizeof (str))) {
12159     if (StringICmp (str, "TRUE") == 0) {
12160       SetAppProperty ("EditGBSourceQuals", (void *) 1024);
12161     }
12162   }
12163 }
12164 
DoQuit(ButtoN b)12165 static void DoQuit (ButtoN b)
12166 
12167 {
12168   QuitProgram ();
12169 }
12170 
CleanupSequin(void)12171 static void CleanupSequin (void)
12172 
12173 {
12174   FiniSequinExtras ();
12175 
12176   ExitMuskStyles ();
12177   FreeOrganismTable ();
12178   FreeGeneticCodes ();
12179   GeneticCodeSingletonFini ();
12180   FreePrintOptions ();
12181 
12182 /*#ifdef USE_LOCAL*/
12183   if (useLocal) {
12184     LocalSeqFetchDisable ();
12185   }
12186 /*#endif*/
12187 
12188 /*#ifdef USE_ENTREZ*/
12189   if (useEntrez) {
12190     /* EntrezBioseqFetchDisable (); */
12191     /*
12192     if (EntrezIsInited ()) {
12193       EntrezFini ();
12194     }
12195     */
12196     /* ID1BioseqFetchDisable (); */
12197     PubSeqFetchDisable ();
12198   }
12199 /*#endif*/
12200 
12201   TransTableFreeAll ();
12202 
12203   ECNumberFSAFreeAll ();
12204 }
12205 
SubtoolModeAsnTextFileRead(CharPtr filename,Uint2Ptr datatypeptr,Uint2Ptr entityIDptr)12206 static Pointer SubtoolModeAsnTextFileRead (CharPtr filename,
12207                                            Uint2Ptr datatypeptr, Uint2Ptr entityIDptr)
12208 
12209 {
12210   AsnIoPtr       aip;
12211   BioseqSetPtr   bssp = NULL, bssp2;
12212   ObjMgrData     omdata;
12213   ObjMgrDataPtr  omdptop = NULL;
12214   Uint2          parenttype = 0;
12215   Pointer        parentptr = NULL;
12216   Pointer        ptr = NULL;
12217   SeqEntryPtr    sep = NULL, sep1, sep2;
12218 
12219   if (filename == NULL) return NULL;
12220   if (datatypeptr != NULL) *datatypeptr = 0;
12221   if (entityIDptr != NULL) *entityIDptr = 0;
12222 
12223   aip = AsnIoOpen (filename, "r");
12224   if (aip == NULL) return NULL;
12225   aip->scan_for_start = TRUE;
12226   while ((bssp2 = BioseqSetAsnRead (aip, NULL)) != NULL) {
12227     if (sep == NULL) {
12228       sep2 = SeqEntryNew ();
12229       if (sep2 != NULL) {
12230         sep2->choice = 2;
12231         sep2->data.ptrvalue = bssp2;
12232         SeqMgrSeqEntry (SM_BIOSEQSET, (Pointer) bssp2, sep2);
12233         sep = sep2;
12234         bssp = bssp2;
12235         SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
12236         GetSeqEntryParent (sep, &parentptr, &parenttype);
12237       }
12238     } else {
12239       for (sep1 = bssp->seq_set; sep1->next != NULL; sep1 = sep1->next) continue;
12240       sep1->next = bssp2->seq_set;
12241       bssp2->seq_set = NULL;
12242       BioseqSetFree (bssp2);
12243     }
12244   }
12245   if (sep != NULL) {
12246     SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
12247     RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
12248   }
12249   AsnIoClose (aip);
12250   ptr = (Pointer) bssp;
12251   if (ptr == NULL) {
12252     ErrPostEx (SEV_ERROR,0,0,"Couldn't read [%s], type [OBJ_BIOSEQSET]", filename);
12253   } else {
12254     if (datatypeptr != NULL) *datatypeptr = OBJ_BIOSEQSET;
12255     if (entityIDptr != NULL) *entityIDptr = ObjMgrRegister (OBJ_BIOSEQSET, ptr);
12256   }
12257   return ptr;
12258 }
12259 
12260 #ifdef USE_SMARTNET
12261 static CharPtr dirsubfetchproc = "DirSubBioseqFetch";
12262 
12263 static CharPtr dirsubfetchcmd = NULL;
12264 
12265 extern Pointer ReadFromDirSub (CharPtr accn, Uint2Ptr datatype, Uint2Ptr entityID);
ReadFromDirSub(CharPtr accn,Uint2Ptr datatype,Uint2Ptr entityID)12266 extern Pointer ReadFromDirSub (CharPtr accn, Uint2Ptr datatype, Uint2Ptr entityID)
12267 
12268 {
12269   Char     cmmd [256];
12270   Pointer  dataptr;
12271   FILE*    fp;
12272   Char     path [PATH_MAX];
12273 
12274   if (datatype != NULL) {
12275     *datatype = 0;
12276   }
12277   if (entityID != NULL) {
12278     *entityID = 0;
12279   }
12280   if (! dirsubMode) return NULL;
12281   if (StringHasNoText (accn)) return NULL;
12282 
12283   if (dirsubfetchcmd == NULL) {
12284     if (GetAppParam ("SEQUIN", "DIRSUB", "FETCHSCRIPT", NULL, cmmd, sizeof (cmmd))) {
12285     	dirsubfetchcmd = StringSaveNoNull (cmmd);
12286     }
12287   }
12288   if (dirsubfetchcmd == NULL) return NULL;
12289 
12290   TmpNam (path);
12291 
12292 #ifdef OS_UNIX
12293   sprintf (cmmd, "csh %s %s > %s", dirsubfetchcmd, accn, path);
12294   system (cmmd);
12295 #endif
12296 #ifdef OS_MSWIN
12297   sprintf (cmmd, "%s %s -o %s", dirsubfetchcmd, accn, path);
12298   RunSilent (cmmd);
12299 #endif
12300 
12301   fp = FileOpen (path, "r");
12302   if (fp == NULL) {
12303     FileRemove (path);
12304     return NULL;
12305   }
12306   dataptr = ReadAsnFastaOrFlatFile (fp, datatype, entityID, FALSE, FALSE, TRUE, FALSE);
12307   FileClose (fp);
12308   FileRemove (path);
12309   return dataptr;
12310 }
12311 
12312 
DirSubBioseqFetchFunc(Pointer data)12313 static Int2 LIBCALLBACK DirSubBioseqFetchFunc (Pointer data)
12314 
12315 {
12316   BioseqPtr         bsp;
12317   Char              cmmd [256];
12318   Pointer           dataptr;
12319   Uint2             datatype;
12320   Uint2             entityID;
12321   FILE*             fp;
12322   OMProcControlPtr  ompcp;
12323   ObjMgrProcPtr     ompp;
12324   Char              path [PATH_MAX];
12325   SeqEntryPtr       sep = NULL;
12326   SeqIdPtr          sip;
12327   TextSeqIdPtr      tsip;
12328 
12329   ompcp = (OMProcControlPtr) data;
12330   if (ompcp == NULL) return OM_MSG_RET_ERROR;
12331   ompp = ompcp->proc;
12332   if (ompp == NULL) return OM_MSG_RET_ERROR;
12333   sip = (SeqIdPtr) ompcp->input_data;
12334   if (sip == NULL) return OM_MSG_RET_ERROR;
12335 
12336   if (sip->choice != SEQID_GENBANK) return OM_MSG_RET_ERROR;
12337   tsip = (TextSeqIdPtr) sip->data.ptrvalue;
12338   if (tsip == NULL || StringHasNoText (tsip->accession)) return OM_MSG_RET_ERROR;
12339 
12340   if (dirsubfetchcmd == NULL) {
12341     if (GetAppParam ("SEQUIN", "DIRSUB", "FETCHSCRIPT", NULL, cmmd, sizeof (cmmd))) {
12342     	dirsubfetchcmd = StringSaveNoNull (cmmd);
12343     }
12344   }
12345   if (dirsubfetchcmd == NULL) return OM_MSG_RET_ERROR;
12346 
12347   TmpNam (path);
12348 
12349 #ifdef OS_UNIX
12350   sprintf (cmmd, "csh %s %s > %s", dirsubfetchcmd, tsip->accession, path);
12351   system (cmmd);
12352 #endif
12353 #ifdef OS_MSWIN
12354   sprintf (cmmd, "%s %s -o %s", dirsubfetchcmd, tsip->accession, path);
12355   RunSilent (cmmd);
12356 #endif
12357 
12358   fp = FileOpen (path, "r");
12359   if (fp == NULL) {
12360     FileRemove (path);
12361     return OM_MSG_RET_ERROR;
12362   }
12363   dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, &entityID, FALSE, FALSE, TRUE, FALSE);
12364   FileClose (fp);
12365   FileRemove (path);
12366 
12367   if (dataptr == NULL) return OM_MSG_RET_OK;
12368 
12369   sep = GetTopSeqEntryForEntityID (entityID);
12370   if (sep == NULL) return OM_MSG_RET_ERROR;
12371   bsp = BioseqFindInSeqEntry (sip, sep);
12372   ompcp->output_data = (Pointer) bsp;
12373   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
12374   return OM_MSG_RET_DONE;
12375 }
12376 
12377 #ifdef USE_SMARTNET
DirSubFetchEnable(void)12378 static Boolean DirSubFetchEnable (void)
12379 
12380 {
12381   ObjMgrProcLoad (OMPROC_FETCH, dirsubfetchproc, dirsubfetchproc,
12382                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
12383                   DirSubBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
12384   return TRUE;
12385 }
12386 #endif
12387 
12388 static CharPtr smartfetchproc = "SmartBioseqFetch";
12389 
12390 static CharPtr smartfetchcmd = NULL;
12391 
12392 extern Pointer ReadFromSmart (CharPtr accn, Uint2Ptr datatype, Uint2Ptr entityID);
ReadFromSmart(CharPtr accn,Uint2Ptr datatype,Uint2Ptr entityID)12393 extern Pointer ReadFromSmart (CharPtr accn, Uint2Ptr datatype, Uint2Ptr entityID)
12394 
12395 {
12396   Char     cmmd [256];
12397   Pointer  dataptr;
12398   FILE*    fp;
12399   Char     path [PATH_MAX];
12400 
12401   if (datatype != NULL) {
12402     *datatype = 0;
12403   }
12404   if (entityID != NULL) {
12405     *entityID = 0;
12406   }
12407   if (! dirsubMode) return NULL;
12408   if (StringHasNoText (accn)) return NULL;
12409 
12410   if (smartfetchcmd == NULL) {
12411     if (GetAppParam ("SEQUIN", "SMART", "FETCHSCRIPT", NULL, cmmd, sizeof (cmmd))) {
12412     	smartfetchcmd = StringSaveNoNull (cmmd);
12413     }
12414   }
12415   if (smartfetchcmd == NULL) return NULL;
12416 
12417   TmpNam (path);
12418 
12419 #ifdef OS_UNIX
12420   sprintf (cmmd, "csh %s %s > %s", smartfetchcmd, accn, path);
12421   system (cmmd);
12422 #endif
12423 #ifdef OS_MSWIN
12424   sprintf (cmmd, "%s %s -o %s", smartfetchcmd, accn, path);
12425   RunSilent (cmmd);
12426 #endif
12427 
12428   fp = FileOpen (path, "r");
12429   if (fp == NULL) {
12430     FileRemove (path);
12431     return NULL;
12432   }
12433   dataptr = ReadAsnFastaOrFlatFile (fp, datatype, entityID, FALSE, FALSE, TRUE, FALSE);
12434   FileClose (fp);
12435   FileRemove (path);
12436   return dataptr;
12437 }
12438 
12439 
12440 static Boolean AllowFarFetch = TRUE;
12441 static Boolean ToggleFarFetchForValidation = FALSE;
12442 static Boolean FarFetchToggleWaiterIsBuilt = FALSE;
12443 
TPAFarFetchMsgFunc(OMMsgStructPtr ommsp)12444 static Int2 LIBCALLBACK TPAFarFetchMsgFunc (OMMsgStructPtr ommsp)
12445 
12446 {
12447   if (ommsp != NULL && ommsp->message == OM_MSG_DEL && ommsp->itemtype == 0 && ommsp->itemID == 0) {
12448     ToggleFarFetchForValidation = FALSE;
12449   }
12450   return OM_MSG_RET_OK;
12451 }
12452 
DisAllowFarFetchForTPAValidation(IteM i)12453 NLM_EXTERN void DisAllowFarFetchForTPAValidation (IteM i)
12454 {
12455   OMUserDataPtr  omudp;
12456 
12457   ToggleFarFetchForValidation = TRUE;
12458 
12459   if (!FarFetchToggleWaiterIsBuilt) {
12460     omudp = ObjMgrAddUserData (0, 0, 0, 0);
12461     if (omudp != NULL) {
12462       omudp->messagefunc = TPAFarFetchMsgFunc;
12463     }
12464     FarFetchToggleWaiterIsBuilt = TRUE;
12465   }
12466 }
12467 
12468 
SmartBioseqFetchFunc(Pointer data)12469 static Int2 LIBCALLBACK SmartBioseqFetchFunc (Pointer data)
12470 
12471 {
12472   BioseqPtr         bsp;
12473   Char              cmmd [256];
12474   Pointer           dataptr;
12475   Uint2             datatype;
12476   Uint2             entityID;
12477   FILE*             fp;
12478   OMProcControlPtr  ompcp;
12479   ObjMgrProcPtr     ompp;
12480   Char              path [PATH_MAX];
12481   SeqEntryPtr       sep = NULL;
12482   SeqIdPtr          sip;
12483   TextSeqIdPtr      tsip;
12484   OMUserDataPtr     omudp;
12485 
12486   if (!AllowFarFetch) {
12487     return OM_MSG_RET_OK;
12488   }
12489   ompcp = (OMProcControlPtr) data;
12490   if (ompcp == NULL) return OM_MSG_RET_ERROR;
12491   ompp = ompcp->proc;
12492   if (ompp == NULL) return OM_MSG_RET_ERROR;
12493   sip = (SeqIdPtr) ompcp->input_data;
12494   if (sip == NULL) return OM_MSG_RET_ERROR;
12495 
12496   if (sip->choice != SEQID_GENBANK) return OM_MSG_RET_ERROR;
12497   tsip = (TextSeqIdPtr) sip->data.ptrvalue;
12498   if (tsip == NULL || StringHasNoText (tsip->accession)) return OM_MSG_RET_ERROR;
12499 
12500   if (smartfetchcmd == NULL) {
12501     if (GetAppParam ("SEQUIN", "SMART", "FETCHSCRIPT", NULL, cmmd, sizeof (cmmd))) {
12502     	smartfetchcmd = StringSaveNoNull (cmmd);
12503     }
12504   }
12505   if (smartfetchcmd == NULL) return OM_MSG_RET_ERROR;
12506 
12507   TmpNam (path);
12508 
12509 #ifdef OS_UNIX
12510   sprintf (cmmd, "csh %s %s > %s", smartfetchcmd, tsip->accession, path);
12511   system (cmmd);
12512 #endif
12513 #ifdef OS_MSWIN
12514   sprintf (cmmd, "%s %s -o %s", smartfetchcmd, tsip->accession, path);
12515   RunSilent (cmmd);
12516 #endif
12517 
12518   fp = FileOpen (path, "r");
12519   if (fp == NULL) {
12520     FileRemove (path);
12521     return OM_MSG_RET_ERROR;
12522   }
12523   dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, &entityID, FALSE, FALSE, TRUE, FALSE);
12524   FileClose (fp);
12525   FileRemove (path);
12526 
12527   if (dataptr == NULL) return OM_MSG_RET_OK;
12528 
12529   sep = GetTopSeqEntryForEntityID (entityID);
12530   if (sep == NULL) return OM_MSG_RET_ERROR;
12531   bsp = BioseqFindInSeqEntry (sip, sep);
12532   ompcp->output_data = (Pointer) bsp;
12533   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
12534 
12535   omudp = ObjMgrAddUserData(ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
12536 
12537 
12538   return OM_MSG_RET_DONE;
12539 }
12540 
SmartFetchEnable(void)12541 static Boolean SmartFetchEnable (void)
12542 
12543 {
12544   ObjMgrProcLoad (OMPROC_FETCH, smartfetchproc, smartfetchproc,
12545                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
12546                   SmartBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
12547   return TRUE;
12548 }
12549 
12550 static CharPtr hupfetchproc = "HUPBioseqFetch";
12551 
12552 static CharPtr hupfetchcmd = NULL;
12553 
12554 extern Pointer ReadFromHUP (CharPtr accn, Uint2Ptr datatype, Uint2Ptr entityID);
ReadFromHUP(CharPtr accn,Uint2Ptr datatype,Uint2Ptr entityID)12555 extern Pointer ReadFromHUP (CharPtr accn, Uint2Ptr datatype, Uint2Ptr entityID)
12556 
12557 {
12558   Char     cmmd [256];
12559   Pointer  dataptr;
12560   FILE*    fp;
12561   Char     path [PATH_MAX];
12562 
12563   if (datatype != NULL) {
12564     *datatype = 0;
12565   }
12566   if (entityID != NULL) {
12567     *entityID = 0;
12568   }
12569   if (! dirsubMode) return NULL;
12570   if (StringHasNoText (accn)) return NULL;
12571 
12572   if (hupfetchcmd == NULL) {
12573     if (GetAppParam ("SEQUIN", "HUP", "FETCHSCRIPT", NULL, cmmd, sizeof (cmmd))) {
12574     	hupfetchcmd = StringSaveNoNull (cmmd);
12575     }
12576   }
12577   if (hupfetchcmd == NULL) return NULL;
12578 
12579   TmpNam (path);
12580 
12581 #ifdef OS_UNIX
12582   sprintf (cmmd, "csh %s %s > %s", hupfetchcmd, accn, path);
12583   system (cmmd);
12584 #endif
12585 #ifdef OS_MSWIN
12586   sprintf (cmmd, "%s %s -o %s", hupfetchcmd, accn, path);
12587   RunSilent (cmmd);
12588 #endif
12589 
12590   fp = FileOpen (path, "r");
12591   if (fp == NULL) {
12592     FileRemove (path);
12593     return NULL;
12594   }
12595   dataptr = ReadAsnFastaOrFlatFile (fp, datatype, entityID, FALSE, FALSE, TRUE, FALSE);
12596   FileClose (fp);
12597   FileRemove (path);
12598   return dataptr;
12599 }
12600 
12601 
HUPBioseqFetchFunc(Pointer data)12602 static Int2 LIBCALLBACK HUPBioseqFetchFunc (Pointer data)
12603 
12604 {
12605   BioseqPtr         bsp;
12606   Char              cmmd [256];
12607   Pointer           dataptr;
12608   Uint2             datatype;
12609   Uint2             entityID;
12610   FILE*             fp;
12611   OMProcControlPtr  ompcp;
12612   ObjMgrProcPtr     ompp;
12613   Char              path [PATH_MAX];
12614   SeqEntryPtr       sep = NULL;
12615   SeqIdPtr          sip;
12616   TextSeqIdPtr      tsip;
12617   OMUserDataPtr     omudp;
12618 
12619   if (!AllowFarFetch) return OM_MSG_RET_OK;
12620 
12621   ompcp = (OMProcControlPtr) data;
12622   if (ompcp == NULL) return OM_MSG_RET_ERROR;
12623   ompp = ompcp->proc;
12624   if (ompp == NULL) return OM_MSG_RET_ERROR;
12625   sip = (SeqIdPtr) ompcp->input_data;
12626   if (sip == NULL) return OM_MSG_RET_ERROR;
12627 
12628   if (sip->choice != SEQID_GENBANK) return OM_MSG_RET_ERROR;
12629   tsip = (TextSeqIdPtr) sip->data.ptrvalue;
12630   if (tsip == NULL || StringHasNoText (tsip->accession)) return OM_MSG_RET_ERROR;
12631 
12632   if (hupfetchcmd == NULL) {
12633     if (GetAppParam ("SEQUIN", "HUP", "FETCHSCRIPT", NULL, cmmd, sizeof (cmmd))) {
12634     	hupfetchcmd = StringSaveNoNull (cmmd);
12635     }
12636   }
12637   if (hupfetchcmd == NULL) return OM_MSG_RET_ERROR;
12638 
12639   TmpNam (path);
12640 
12641 #ifdef OS_UNIX
12642   sprintf (cmmd, "csh %s %s > %s 2>&1", hupfetchcmd, tsip->accession, path);
12643   system (cmmd);
12644 #endif
12645 #ifdef OS_MSWIN
12646   sprintf (cmmd, "%s %s -o %s", hupfetchcmd, tsip->accession, path);
12647   RunSilent (cmmd);
12648 #endif
12649 
12650   fp = FileOpen (path, "r");
12651   if (fp == NULL) {
12652     FileRemove (path);
12653     return OM_MSG_RET_ERROR;
12654   }
12655   dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, &entityID, FALSE, FALSE, TRUE, FALSE);
12656   FileClose (fp);
12657   FileRemove (path);
12658 
12659   if (dataptr == NULL) return OM_MSG_RET_OK;
12660 
12661   sep = GetTopSeqEntryForEntityID (entityID);
12662   if (sep == NULL) return OM_MSG_RET_ERROR;
12663   bsp = BioseqFindInSeqEntry (sip, sep);
12664   ompcp->output_data = (Pointer) bsp;
12665   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
12666 
12667   omudp = ObjMgrAddUserData(ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
12668 
12669 
12670   return OM_MSG_RET_DONE;
12671 }
12672 
12673 
HUPFetchEnable(void)12674 static Boolean HUPFetchEnable (void)
12675 
12676 {
12677   ObjMgrProcLoad (OMPROC_FETCH, hupfetchproc, hupfetchproc,
12678                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
12679                   HUPBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
12680   return TRUE;
12681 }
12682 
12683 
12684 
12685 
IsBioseqTPA(BioseqPtr bsp,Pointer data)12686 static void IsBioseqTPA (BioseqPtr bsp, Pointer data)
12687 {
12688   if (bsp != NULL && data != NULL && HasTpaUserObject(bsp)) {
12689     *((BoolPtr) data) = TRUE;
12690   }
12691 }
12692 
12693 
IsSeqEntryTPA(SeqEntryPtr sep)12694 static Boolean IsSeqEntryTPA (SeqEntryPtr sep)
12695 {
12696   Boolean is_tpa = FALSE;
12697 
12698   VisitBioseqsInSep (sep, &is_tpa, IsBioseqTPA);
12699   return is_tpa;
12700 }
12701 
12702 
12703 static CharPtr tpasmartfetchproc = "TPASmartBioseqFetch";
12704 
12705 static CharPtr tpasmartfetchcmd = NULL;
12706 
12707 extern Pointer ReadFromTPASmart (CharPtr accn, Uint2Ptr datatype, Uint2Ptr entityID);
ReadFromTPASmart(CharPtr accn,Uint2Ptr datatype,Uint2Ptr entityID)12708 extern Pointer ReadFromTPASmart (CharPtr accn, Uint2Ptr datatype, Uint2Ptr entityID)
12709 
12710 {
12711   Char     cmmd [256];
12712   Pointer  dataptr;
12713   FILE*    fp;
12714   Char     path [PATH_MAX];
12715 
12716   if (datatype != NULL) {
12717     *datatype = 0;
12718   }
12719   if (entityID != NULL) {
12720     *entityID = 0;
12721   }
12722   if (! dirsubMode) return NULL;
12723   if (StringHasNoText (accn)) return NULL;
12724 
12725   if (tpasmartfetchcmd == NULL) {
12726     if (GetAppParam ("SEQUIN", "TPASMART", "FETCHSCRIPT", NULL, cmmd, sizeof (cmmd))) {
12727     	tpasmartfetchcmd = StringSaveNoNull (cmmd);
12728     }
12729   }
12730   if (tpasmartfetchcmd == NULL) return NULL;
12731 
12732   TmpNam (path);
12733 
12734 #ifdef OS_UNIX
12735   sprintf (cmmd, "csh %s %s > %s", tpasmartfetchcmd, accn, path);
12736   system (cmmd);
12737 #endif
12738 #ifdef OS_MSWIN
12739   sprintf (cmmd, "%s %s -o %s", tpasmartfetchcmd, accn, path);
12740   RunSilent (cmmd);
12741 #endif
12742 
12743   fp = FileOpen (path, "r");
12744   if (fp == NULL) {
12745     FileRemove (path);
12746     return NULL;
12747   }
12748   dataptr = ReadAsnFastaOrFlatFile (fp, datatype, entityID, FALSE, FALSE, TRUE, FALSE);
12749   FileClose (fp);
12750   FileRemove (path);
12751   return dataptr;
12752 }
12753 
12754 
TPASmartBioseqFetchFunc(Pointer data)12755 static Int2 LIBCALLBACK TPASmartBioseqFetchFunc (Pointer data)
12756 
12757 {
12758   BioseqPtr         bsp;
12759   Char              cmmd [256];
12760   Pointer           dataptr;
12761   Uint2             datatype;
12762   Uint2             entityID;
12763   FILE*             fp;
12764   OMProcControlPtr  ompcp;
12765   ObjMgrProcPtr     ompp;
12766   Char              path [PATH_MAX];
12767   SeqEntryPtr       sep = NULL;
12768   SeqIdPtr          sip;
12769   TextSeqIdPtr      tsip;
12770 
12771   if (!AllowFarFetch) {
12772     return OM_MSG_RET_OK;
12773   }
12774   ompcp = (OMProcControlPtr) data;
12775   if (ompcp == NULL) return OM_MSG_RET_ERROR;
12776   ompp = ompcp->proc;
12777   if (ompp == NULL) return OM_MSG_RET_ERROR;
12778   sip = (SeqIdPtr) ompcp->input_data;
12779   if (sip == NULL) return OM_MSG_RET_ERROR;
12780 
12781   if (sip->choice != SEQID_TPG) return OM_MSG_RET_ERROR;
12782   tsip = (TextSeqIdPtr) sip->data.ptrvalue;
12783   if (tsip == NULL || StringHasNoText (tsip->accession)) return OM_MSG_RET_ERROR;
12784 
12785   if (tpasmartfetchcmd == NULL) {
12786     if (GetAppParam ("SEQUIN", "TPASMART", "FETCHSCRIPT", NULL, cmmd, sizeof (cmmd))) {
12787     	tpasmartfetchcmd = StringSaveNoNull (cmmd);
12788     }
12789   }
12790   if (tpasmartfetchcmd == NULL) return OM_MSG_RET_ERROR;
12791 
12792   TmpNam (path);
12793 
12794 #ifdef OS_UNIX
12795   sprintf (cmmd, "csh %s %s > %s", tpasmartfetchcmd, tsip->accession, path);
12796   system (cmmd);
12797 #endif
12798 #ifdef OS_MSWIN
12799   sprintf (cmmd, "%s %s -o %s", tpasmartfetchcmd, tsip->accession, path);
12800   RunSilent (cmmd);
12801 #endif
12802 
12803   fp = FileOpen (path, "r");
12804   if (fp == NULL) {
12805     FileRemove (path);
12806     return OM_MSG_RET_ERROR;
12807   }
12808   dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, &entityID, FALSE, FALSE, TRUE, FALSE);
12809   FileClose (fp);
12810   FileRemove (path);
12811 
12812   if (dataptr == NULL) return OM_MSG_RET_OK;
12813 
12814   sep = GetTopSeqEntryForEntityID (entityID);
12815   if (sep == NULL) return OM_MSG_RET_ERROR;
12816   bsp = BioseqFindInSeqEntry (sip, sep);
12817   ompcp->output_data = (Pointer) bsp;
12818   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
12819   return OM_MSG_RET_DONE;
12820 }
12821 
TPASmartFetchEnable(void)12822 static Boolean TPASmartFetchEnable (void)
12823 
12824 {
12825   ObjMgrProcLoad (OMPROC_FETCH, tpasmartfetchproc, tpasmartfetchproc,
12826                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
12827                   TPASmartBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
12828   return TRUE;
12829 }
12830 
SmartUserDataFree(VoidPtr Pointer)12831 static VoidPtr LIBCALLBACK SmartUserDataFree (VoidPtr Pointer)
12832 {
12833     SMUserDataPtr sm_user_data = (SMUserDataPtr) Pointer;
12834 
12835     if(sm_user_data != NULL) {
12836         MemFree(sm_user_data->header);
12837         MemFree(sm_user_data);
12838     }
12839 
12840     return NULL;
12841 }
12842 
DumbUserDataFree(VoidPtr Pointer)12843 static VoidPtr LIBCALLBACK DumbUserDataFree (VoidPtr Pointer)
12844 
12845 {
12846   return ValNodeFreeData ((ValNodePtr) Pointer);
12847 }
12848 
SMCancelAllEdit(void)12849 static void SMCancelAllEdit(void)
12850 {
12851     ObjMgrPtr      omp;
12852     OMUserDataPtr  omudp;
12853     Int2           num;
12854     SMUserDataPtr  sm_usr_data = NULL;
12855     Uint2 j;
12856 
12857     omp = ObjMgrGet ();
12858     num = omp->HighestEntityID;
12859 
12860     for(j = 1; j <= omp->HighestEntityID; j++) {
12861         if((omudp = ObjMgrGetUserData(j, 0,0, SMART_KEY)) != NULL) {
12862             if((sm_usr_data =
12863                 (SMUserDataPtr) omudp->userdata.ptrvalue) != NULL &&
12864                sm_usr_data->fd != 0) {
12865                 sm_usr_data->header->status = SMStatClosed;
12866                 SMSendMsgToClient(sm_usr_data);
12867                 SmartUserDataFree(omudp->userdata.ptrvalue);
12868                 omudp->userdata.ptrvalue = NULL;
12869 
12870                 /* Deleting all */
12871                 ObjMgrSendMsg (OM_MSG_DEL, j, 0, 0);
12872             }
12873         }
12874         if ((omudp = ObjMgrGetUserData(j, 0,0, DUMB_KEY)) != NULL) {
12875           DumbUserDataFree (omudp->userdata.ptrvalue);
12876           omudp->userdata.ptrvalue = NULL;
12877         }
12878     }
12879 
12880     return;
12881 }
12882 
12883 extern ForM smartBioseqViewForm;
12884 
12885 
CountBioSources(BioSourcePtr biop,Pointer userdata)12886 static void CountBioSources (BioSourcePtr biop, Pointer userdata)
12887 {
12888   Int4Ptr count;
12889 
12890   if (biop == NULL || userdata == NULL) return;
12891   count = (Int4Ptr) userdata;
12892   (*count)++;
12893 }
12894 
SMReadBioseqObj(VoidPtr data,CharPtr buffer,Int4 length,void * fd)12895 static Int4 SMReadBioseqObj(VoidPtr data, CharPtr buffer, Int4 length, void* fd)
12896 {
12897     AsnIoMemPtr    aimp;
12898     BaseFormPtr    bfp;
12899     VoidPtr        bio_data;
12900     Int2           handled;
12901     Uint2          entityID = 0;
12902     OMUserDataPtr  omudp;
12903     SMMsgHeaderPtr header;
12904     Int4           headlen;
12905     BioseqPtr      bsp;
12906     BioseqSetPtr   bssp = NULL, bssp2;
12907     SeqEntryPtr    sep = NULL, sep1, sep2;
12908     ObjMgrData     omdata;
12909     ObjMgrDataPtr  omdptop = NULL;
12910     Uint2          parenttype = 0;
12911     Pointer        parentptr = NULL;
12912     SMUserDataPtr  sm_user_data;
12913     Int4           bio_type;
12914     Int4           num_srcs = 0;
12915     Boolean        do_taxlookup = TRUE;
12916 
12917     if(buffer == NULL || length < sizeof(SMMsgHeader))
12918         return -1;
12919 
12920     /* Reading request header */
12921 
12922     headlen = sizeof(SMMsgHeader);
12923     header = (SMMsgHeaderPtr) MemNew(headlen);
12924     MemCpy((Pointer) header, buffer, headlen);
12925 
12926     /* ----------------------- */
12927 
12928     switch(header->status) {
12929     case SMTaskEditBinary:
12930         aimp = AsnIoMemOpen("rb",
12931                             (UcharPtr) buffer+headlen, length - headlen);
12932         break;
12933     case SMTaskEditText:
12934         aimp = AsnIoMemOpen("r", (UcharPtr) buffer+headlen, length - headlen);
12935         break;
12936     case SMTaskCancel:
12937         SMCancelAllEdit();
12938         return TRUE;
12939     default:
12940         Message(MSG_ERROR, "This request type (%d) is not implemented yet",
12941                 header->status);
12942         return FALSE;
12943     }
12944 
12945     AsnIoSetErrorMsg(aimp->aip, SMAsnErrorFunc);
12946     bio_type = header->format;
12947 
12948     switch (header->format) {
12949     case OBJ_SEQSUB:
12950         SeqMgrHoldIndexing (TRUE);
12951         bio_data = (VoidPtr) SeqSubmitAsnRead(aimp->aip, NULL);
12952         SeqMgrHoldIndexing (FALSE);
12953         break;
12954     case OBJ_SEQENTRY:
12955         SeqMgrHoldIndexing (TRUE);
12956         bio_data = (VoidPtr) SeqEntryAsnRead(aimp->aip, NULL);
12957         SeqMgrHoldIndexing (FALSE);
12958         if((sep = (SeqEntryPtr) bio_data) != NULL) {
12959             if (sep->choice == 1) {
12960                 bio_type = OBJ_BIOSEQ;
12961             } else {
12962                 bio_type = OBJ_BIOSEQSET;
12963             }
12964         }
12965         break;
12966     case OBJ_BIOSEQ:
12967         SeqMgrHoldIndexing (TRUE);
12968         bio_data = (VoidPtr) BioseqAsnRead(aimp->aip, NULL);
12969         SeqMgrHoldIndexing (FALSE);
12970         bsp = (BioseqPtr) bio_data;
12971         sep = SeqEntryNew ();
12972         sep->choice = 1;
12973         sep->data.ptrvalue = bsp;
12974         SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
12975 
12976         break;
12977     case OBJ_BIOSEQSET:
12978 
12979         aimp->aip->scan_for_start = TRUE;
12980         SeqMgrHoldIndexing (TRUE);
12981         while ((bssp2 = BioseqSetAsnRead (aimp->aip, NULL)) != NULL) {
12982             if (sep == NULL) {
12983                 sep2 = SeqEntryNew ();
12984                 if (sep2 != NULL) {
12985                     sep2->choice = 2;
12986                     sep2->data.ptrvalue = bssp2;
12987                     SeqMgrSeqEntry (SM_BIOSEQSET, (Pointer) bssp2, sep2);
12988                     sep = sep2;
12989                     bssp = bssp2;
12990                     SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
12991                     GetSeqEntryParent (sep, &parentptr, &parenttype);
12992                 }
12993             } else {
12994                 for (sep1 = bssp->seq_set; sep1->next != NULL;
12995                      sep1 = sep1->next) continue;
12996                 sep1->next = bssp2->seq_set;
12997                 bssp2->seq_set = NULL;
12998                 BioseqSetFree (bssp2);
12999             }
13000         }
13001         SeqMgrHoldIndexing (FALSE);
13002         if (sep != NULL) {
13003             SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
13004             RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
13005         }
13006         bio_data = (Pointer) bssp;
13007         break;
13008     default:
13009         Message(MSG_OK, "This datatype: %d is not implemented yet",
13010                 header->format);
13011         AsnIoMemClose(aimp);
13012         return FALSE;
13013     }
13014 
13015     sm_user_data = MemNew(sizeof(SMUserData));
13016     sm_user_data->fd = (void*) fd;
13017     sm_user_data->header = header;
13018 
13019     if(bio_data == NULL) {
13020         Message(MSG_ERROR, "Error parcing or processing BLOB");
13021         sm_user_data->header->status = SMStatClosed;
13022         SMSendMsgToClient(sm_user_data);
13023         MemFree(sm_user_data->header);
13024         MemFree(sm_user_data);
13025     } else {
13026 
13027         if (smartBioseqViewForm != NULL) {
13028             bfp = (BaseFormPtr) GetObjectExtra (smartBioseqViewForm);
13029             if (bfp != NULL) {
13030                 /*
13031                 entityID = bfp->input_entityID;
13032                 RemoveSeqEntryViewerEx (bfp->form, FALSE);
13033                 ObjMgrSendMsg (OM_MSG_DEL, entityID, 0, 0);
13034                 bfp->input_entityID = 0;
13035                 */
13036                 seqviewprocs.keepSmartViewerVisible = TRUE;
13037                 SmartnetDoneFunc (bfp);
13038                 seqviewprocs.keepSmartViewerVisible = FALSE;
13039             }
13040         }
13041 
13042         entityID = ObjMgrRegister (bio_type, bio_data);
13043         subtoolEntityID = entityID;
13044 
13045         sep = GetTopSeqEntryForEntityID (entityID);
13046         VisitBioSourcesInSep (sep, &num_srcs, CountBioSources);
13047         if (num_srcs > 10000) {
13048           if (ANS_CANCEL == Message (MSG_OKC, "Record contains %d BioSources.  Do Taxlookup now?", num_srcs)) {
13049             do_taxlookup = FALSE;
13050           }
13051         }
13052         MySeqEntryToAsn3 (sep, TRUE, FALSE, do_taxlookup);
13053 
13054         /* now instantiating protein titles */
13055         InstantiateProteinTitles (entityID, NULL);
13056 
13057         if((omudp = ObjMgrGetUserData (entityID, 0, 0, SMART_KEY)) != NULL) {
13058             SmartUserDataFree(omudp->userdata.ptrvalue);
13059         } else {
13060             omudp = ObjMgrAddUserData (entityID, 0, 0, SMART_KEY);
13061         }
13062 
13063         ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
13064 
13065         /* We will set dirty flag from header info */
13066 
13067         if(header->dirty & 0x01) {
13068             ObjMgrSetDirtyFlag (entityID, TRUE);
13069         } else {
13070             ObjMgrSetDirtyFlag (entityID, FALSE);
13071         }
13072 
13073         if (omudp != NULL) {
13074             omudp->userdata.ptrvalue = (VoidPtr) sm_user_data;
13075             omudp->messagefunc = SubtoolModeMsgFunc; /* ? */
13076             omudp->freefunc = SmartUserDataFree;
13077         }
13078 
13079         if((omudp = ObjMgrGetUserData (entityID, 0, 0, DUMB_KEY)) != NULL) {
13080             DumbUserDataFree (omudp->userdata.ptrvalue);
13081         } else {
13082             omudp = ObjMgrAddUserData (entityID, 0, 0, DUMB_KEY);
13083         }
13084 
13085         if (omudp != NULL) {
13086             omudp->userdata.ptrvalue = (VoidPtr) SmartStructureReport (sep);
13087             omudp->messagefunc = NULL;
13088             omudp->freefunc = DumbUserDataFree;
13089         }
13090 
13091         seqviewprocs.forceSeparateViewer = FALSE;
13092         SeqEntrySetScope (NULL);
13093         handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
13094                                     OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
13095         ArrowCursor ();
13096 
13097         if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
13098             Message (MSG_FATAL, "Unable to launch viewer.");
13099             CleanupSequin ();
13100             return FALSE;
13101         }
13102     }
13103 
13104     AsnIoMemClose(aimp);
13105     return TRUE;
13106 }
13107 
SMWriteBioseqObj(VoidPtr bio_data,SMUserDataPtr sm_usr_data,VoidPtr data)13108 static Int4 SMWriteBioseqObj(VoidPtr bio_data,
13109                              SMUserDataPtr sm_usr_data,
13110                              VoidPtr data)
13111 {
13112     ByteStorePtr    bsp;
13113     AsnIoBSPtr      aibp;
13114     CharPtr buffer;
13115     Int4 length, totlen;
13116 
13117     bsp = BSNew(1024);
13118 
13119     if(sm_usr_data->header->status == SMTaskEditBinary) {
13120         aibp = AsnIoBSOpen("wb", bsp);
13121     } else {
13122         aibp = AsnIoBSOpen("w", bsp);
13123     }
13124 
13125     switch (sm_usr_data->header->format) {
13126     case OBJ_SEQSUB:
13127         SeqSubmitAsnWrite((SeqSubmitPtr) bio_data, aibp->aip, NULL);
13128         break;
13129     case OBJ_SEQENTRY:
13130         SeqEntryAsnWrite((SeqEntryPtr) bio_data, aibp->aip, NULL);
13131         break;
13132     case OBJ_BIOSEQ:
13133         BioseqAsnWrite((BioseqPtr) bio_data, aibp->aip, NULL);
13134         break;
13135     case OBJ_BIOSEQSET:
13136         BioseqSetAsnWrite((BioseqSetPtr) bio_data, aibp->aip, NULL);
13137         break;
13138     default:
13139         Message(MSG_OK, "This datatype: %d is not implemented yet");
13140         AsnIoBSClose(aibp);
13141         BSFree(bsp);
13142         return FALSE;
13143     }
13144 
13145     AsnIoBSClose(aibp);
13146 
13147     BSSeek(bsp, 0, SEEK_SET);
13148 
13149     length = BSLen(bsp);
13150     buffer = MemNew(length+1);
13151     BSRead(bsp, buffer, length);
13152 
13153     totlen = sizeof(SMMsgHeader) + length;
13154 
13155     if(SMWriteToClient(sm_usr_data->fd,
13156                        (CharPtr) &totlen, sizeof(Int4)) != SMNoError) {
13157         Message(MSG_OK, "Write error. Errno = %d", errno);
13158         return FALSE;
13159     }
13160 
13161     if(SMWriteToClient(sm_usr_data->fd, (CharPtr) sm_usr_data->header,
13162                        sizeof(SMMsgHeader)) != SMNoError) {
13163         Message(MSG_OK, "Write error. Errno = %d", errno);
13164         return FALSE;
13165     }
13166 
13167     if(SMWriteToClient(sm_usr_data->fd, buffer, length) != SMNoError) {
13168         Message(MSG_OK, "Write error. Errno = %d", errno);
13169         return FALSE;
13170     }
13171 
13172     BSFree(bsp);
13173     MemFree(buffer);
13174     return TRUE;
13175 }
13176 #endif
13177 
13178 
SequinValidateSeqEntry(SeqEntryPtr sep,ValidStructPtr vsp)13179 static Boolean SequinValidateSeqEntry (SeqEntryPtr sep, ValidStructPtr vsp)
13180 {
13181   Boolean rval;
13182 #ifdef USE_SMARTNET
13183   Boolean restore_hup = FALSE;
13184 #endif
13185 
13186 #ifdef USE_SMARTNET
13187   if (ToggleFarFetchForValidation && IsSeqEntryTPA(sep)) {
13188     restore_hup = TRUE;
13189     AllowFarFetch = FALSE;
13190   }
13191 #endif
13192   rval = ValidateSeqEntry (sep, vsp);
13193 #ifdef USE_SMARTNET
13194   if (restore_hup) {
13195     AllowFarFetch = TRUE;
13196   }
13197 #endif
13198   return rval;
13199 }
13200 
13201 
13202 
13203 static CharPtr comp_months [] = {
13204   "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
13205 };
13206 
MoreThanYearOld(void)13207 static Boolean MoreThanYearOld (void)
13208 
13209 {
13210   Int4      compday, compmonth, compyear, currday, currmonth, curryear;
13211   DayTime   dt;
13212   Int2      i;
13213   CharPtr   ptr, str;
13214   Char      tmp [80];
13215   long int  val;
13216 
13217   if (! GetDayTime (&dt)) return FALSE;
13218   currmonth = dt.tm_mon + 1;
13219   currday = dt.tm_mday;
13220   curryear = dt.tm_year + 1900;
13221 
13222   compmonth = 0;
13223   compday = 0;
13224   compyear = 0;
13225 
13226   sprintf (tmp, "%s", date_of_compilation);
13227 
13228   ptr = StringChr (tmp, ' ');
13229   if (ptr != NULL) {
13230     *ptr = '\0';
13231     ptr++;
13232     if (*ptr == ' ') {
13233       ptr++;
13234     }
13235     for (i = 0; i < 12; i++) {
13236       if (StringCmp (tmp, comp_months [i]) == 0) {
13237         compmonth = (Int4) i + 1;
13238         break;
13239       }
13240     }
13241     str = StringChr (ptr, ' ');
13242     if (str != NULL) {
13243       *str = '\0';
13244       str++;
13245       if (sscanf (ptr, "%ld", &val) == 1) {
13246         compday = (Int4) val;
13247       }
13248       if (sscanf (str, "%ld", &val) == 1) {
13249         compyear = (Int4) val;
13250       }
13251     }
13252   }
13253 
13254   if (compmonth == 0 || compyear == 0) return FALSE;
13255 
13256   if (curryear > compyear + 1) return TRUE;
13257   if (curryear == compyear + 1) {
13258     if (currmonth > compmonth) return TRUE;
13259     if (currmonth == compmonth) {
13260       if (currday > compday) return TRUE;
13261     }
13262   }
13263 
13264   return FALSE;
13265 }
13266 
13267 #include <ent2api.h>
13268 extern REG CORE_GetREG(void);
13269 
SetNetIdent(void)13270 static void SetNetIdent (void)
13271 
13272 {
13273   static const char kRevision [] = "$Revision: " SEQ_APP_VER;
13274   unsigned int major = 0, minor = 0;
13275   char progname [80];
13276   char buf [128];
13277   CharPtr s, bf, pn;
13278   int n;
13279   int res;
13280   size_t len;
13281 
13282   pn = (CharPtr) progname;
13283   bf = (CharPtr) buf;
13284   StringCpy (pn, "Sequin");
13285   s = StringChr (kRevision, ':');
13286   if (s != 0) {
13287     res = sscanf (s + 1, "%u.%u%n", &major, &minor, &n);
13288     if (res >= 2 && n > 0) {
13289       len = StringLen (pn);
13290       sprintf (pn + len, "-%u.%u", major, minor);
13291       REG_Set (CORE_GetREG (), DEF_CONN_REG_SECTION,
13292                REG_CONN_ARGS, pn, eREG_Transient);
13293       pn [len] = '/';
13294     }
13295   }
13296   EntrezSetProgramName (pn);
13297   sprintf (bf, "User-Agent: %s\r\n", pn);
13298   REG_Set (CORE_GetREG (), DEF_CONN_REG_SECTION,
13299            REG_CONN_HTTP_USER_HEADER, bf, eREG_Transient);
13300 }
13301 
13302 static ForM CreateWizardChoiceForm (void);
13303 
13304 extern CharPtr objPrtMemStr;
13305 
13306 extern void Nlm_SetMemFailFlag (Nlm_Boolean val);
13307 
SqnLogItemUse(CharPtr string)13308 static void SqnLogItemUse (CharPtr string)
13309 
13310 {
13311   Char  buf [256];
13312   Int4  count = 0;
13313 
13314   FreeConfigStruct ();
13315 
13316   buf[0] = 0;
13317   GetAppParam ("SEQUINCUSTOM", "USAGE", string, NULL, buf, sizeof (buf) - 1);
13318   if (StringDoesHaveText (buf)) {
13319     if (! StringIsAllDigits (buf)) return;
13320   }
13321   StrToLong (buf, &count);
13322   count++;
13323   sprintf (buf, "%ld", (long) count);
13324   SetAppParam ("SEQUINCUSTOM", "USAGE", string, buf);
13325 
13326   FreeConfigStruct ();
13327 }
13328 
SqnMenuAction(IteM i)13329 static void SqnMenuAction (IteM i)
13330 
13331 {
13332   Char  mnu [256];
13333 
13334   mnu [0] = '\0';
13335 
13336   GetTitle (i, mnu, sizeof (mnu));
13337   if (StringHasNoText (mnu)) return;
13338 
13339   SqnLogItemUse (mnu);
13340 }
13341 
SqnButtonAction(ButtoN b)13342 static void SqnButtonAction (ButtoN b)
13343 
13344 {
13345   Char    btn [256];
13346   Char    title [520];
13347   Char    wnd [256];
13348   WindoW  w;
13349 
13350   btn [0] = '\0';
13351   wnd [0] = '\0';
13352   title [0] = '\0';
13353 
13354   GetTitle (b, btn, sizeof (btn));
13355   if (StringHasNoText (btn)) return;
13356 
13357   w = ParentWindow (b);
13358   GetTitle (w, wnd, sizeof (wnd));
13359   if (StringHasNoText (wnd)) return;
13360 
13361   if (StringStr (wnd, "-- ToolBar") != NULL) {
13362     StringCpy (wnd, "ToolBar");
13363   }
13364 
13365   StringCpy (title, wnd);
13366   StringCat (title, " -- ");
13367   StringCat (title, btn);
13368 
13369   SqnLogItemUse (title);
13370 }
13371 
Main(void)13372 Int2 Main (void)
13373 
13374 {
13375   AsnIoPtr       aip;
13376   BioseqPtr      bsp;
13377   BioseqSetPtr   bssp;
13378   Pointer        dataptr = NULL;
13379   BtnActnProc    fetchProc;
13380   CharPtr        filename = NULL;
13381   FILE           *fp;
13382   Int2           handled;
13383   Boolean        notaxid;
13384   SeqEntryPtr    oldsep;
13385   /*
13386   ObjMgrPtr      omp;
13387   OMProcControl  ompc;
13388   ObjMgrProcPtr  ompp;
13389   */
13390   OMUserDataPtr  omudp;
13391   PaneL          p;
13392   CharPtr        ptr;
13393   SeqEntryPtr    sep;
13394   Int4           smartPort = 0;
13395   Char           str [80];
13396   Int2           val;
13397   WindoW         w;
13398 #if defined(OS_UNIX) || defined(WIN_MOTIF)
13399   Int2           i;
13400 #endif
13401 #ifdef WIN_MOTIF
13402   RecT           r;
13403 #endif
13404 #if defined(OS_MAC) && !defined(OS_UNIX_DARWIN)
13405   long           sysVer;
13406 #endif
13407 
13408   ErrSetFatalLevel (SEV_MAX);
13409   ErrClearOptFlags (EO_SHOW_USERSTR);
13410   ProcessUpdatesFirst (FALSE);
13411 
13412   SetNetIdent ();
13413 
13414   UseLocalAsnloadDataAndErrMsg ();
13415   ErrPathReset ();
13416 
13417   SOCK_SetupSSL(NcbiSetupGnuTls);
13418 
13419 #if defined(OS_MAC) && !defined(OS_UNIX_DARWIN)
13420   if ( Gestalt (gestaltSystemVersion, &sysVer) == noErr) {
13421     /* system version in low order word is hexadecimal */
13422     if (sysVer >= 4096) {
13423       Message (MSG_OK, "You are running on MacOS X and should use the native version of Sequin, not SequinOS9");
13424     }
13425   }
13426 #endif
13427 
13428   if (MoreThanYearOld ()) {
13429     Message (MSG_OK, "This copy of Sequin is more than a year old.  Please download the current version.");
13430   }
13431 
13432   ReadSettings ();
13433 
13434   if (indexerVersion) {
13435     if (Nlm_IsRemoteDesktop ()) {
13436       Nlm_UsePrimaryMonitor ();
13437     } else if (Nlm_HasDualScreen () && GetSequinAppParam ("SCREENS", "MONITOR", NULL, str, sizeof (str))) {
13438       if (StringICmp (str, "FULL") == 0) {
13439         Nlm_UseFullScreen ();
13440       } else if (StringICmp (str, "LEFT") == 0) {
13441         Nlm_UseLeftScreen ();
13442       } else if (StringICmp (str, "RIGHT") == 0) {
13443         Nlm_UseRightScreen ();
13444       } else if (StringICmp (str, "PRIMARY") == 0) {
13445         Nlm_UsePrimaryMonitor ();
13446       }
13447     }
13448     Nlm_SetMemFailFlag (TRUE);
13449   }
13450 
13451   sprintf (str, "Sequin Application Version %s", SEQUIN_APPLICATION);
13452   SEQUIN_VERSION = StringSave (str);
13453 
13454   ptr = "Standard Release";
13455   if (useEntrez || useBlast) {
13456     ptr = "Network Aware";
13457   }
13458   if (indexerVersion) {
13459     ptr = "Indexer Services";
13460   }
13461   if (genomeCenter != NULL) {
13462     ptr = "Genome Center";
13463   }
13464   if (indexerVersion) {
13465     sprintf (str, "%s [%s - %s]", ptr, date_of_compilation, time_of_compilation);
13466   } else {
13467     sprintf (str, "%s [%s]", ptr, date_of_compilation);
13468   }
13469   SEQUIN_SERVICES = StringSave (str);
13470 
13471   if (! indexerVersion) {
13472     ErrSetLogfile (NULL, 0);
13473   }
13474 
13475   w = FixedWindow (-50, -33, -10, -10, "Sequin", NULL);
13476   p = SimplePanel (w, AboutBoxWidth (), AboutBoxHeight (), DrawAbout);
13477   Show (w);
13478 #ifdef WIN_MOTIF
13479   Select (w);
13480   ObjectRect (p, &r);
13481   Select (p);
13482   InsetRect (&r, 3, 3);
13483   InvalRect (&r);
13484 #endif
13485   Update ();
13486 
13487   workbenchMode = FALSE;
13488   subtoolMode = FALSE;
13489   stdinMode = FALSE;
13490   bioseqsetMode = FALSE;
13491   binseqentryMode = FALSE;
13492   entrezMode = FALSE;
13493   nohelpMode = FALSE;
13494   subtoolDatatype = 0;
13495   subtoolEntityID = 0;
13496   leaveAsOldAsn = FALSE;
13497 
13498 #if defined(OS_UNIX) || defined(WIN_MOTIF)
13499   {{
13500     Nlm_Int4         argc = GetArgc();
13501     Nlm_CharPtr PNTR argv = GetArgv();
13502     for (i = 1;  i < argc;  i++)
13503       {
13504         if      (StringCmp (argv[i], "-s") == 0)
13505           subtoolMode = TRUE;
13506         else if (StringCmp (argv[i], "-w") == 0)
13507           workbenchMode = TRUE;
13508         else if (StringCmp (argv[i], "-x") == 0)
13509           stdinMode = TRUE;
13510         else if (StringCmp (argv[i], "-f") == 0 && i + 1 < argc) {
13511           stdinMode = TRUE;
13512           filename = argv [i + 1];
13513         } else if (StringCmp (argv[i], "-bse") == 0)
13514           binseqentryMode = TRUE;
13515         else if (StringCmp (argv[i], "-e") == 0)
13516           entrezMode = TRUE;
13517         else if (StringCmp (argv[i], "-h") == 0)
13518           nohelpMode = TRUE;
13519         /*
13520         else if (StringCmp (argv[i], "-udv") == 0)
13521           useUdv = TRUE;
13522         */
13523         else if (StringCmp (argv[i], "-oldgph") == 0)
13524           useOldGraphicView = TRUE;
13525         else if (StringCmp (argv[i], "-oldaln") == 0)
13526           useOldAlignmentView = TRUE;
13527         else if (StringCmp (argv[i], "-oldseq") == 0)
13528           useOldSequenceView = TRUE;
13529         else if (StringCmp (argv[i], "-gc") == 0) {
13530             indexerVersion = FALSE;
13531             extraServices = TRUE;
13532             genomeCenter = StringSave ("genome center tag goes here");
13533         }
13534         if (StringCmp (argv[i], "-b") == 0) {
13535           bioseqsetMode = TRUE;
13536         } else if (StringCmp (argv[i], "-oldaln") == 0) {
13537           newAlignReader = FALSE;
13538         } else if (StringCmp (argv[i], "-oldasn") == 0) {
13539           leaveAsOldAsn = TRUE;
13540         } else if (StringCmp (argv[i], "-oldsource") == 0) {
13541           SetAppProperty ("OldFlatfileSource", (void *) 1024);
13542         } else if (StringCmp (argv[i], "-a") == 0) {
13543           gphviewscorealigns = TRUE;
13544         } else if (StringCmp (argv[i], "-y") == 0) {
13545           backupMode = TRUE;
13546         } else if (StringCmp (argv[i], "-noseqfetch") == 0) {
13547           useSeqFetch = FALSE;
13548         } else if (StringCmp (argv[i], "-nolocalfetch") == 0) {
13549           useLocal = FALSE;
13550         } else if (StringCmp (argv[i], "-noseqidlookup") == 0) {
13551           useIdLookup = FALSE;
13552         } else if (StringCmp (argv[i], "-debugsmartnet") == 0) {
13553           debugsmartnet = TRUE;
13554         }
13555 #ifdef USE_SMARTNET
13556         else if (StringCmp (argv[i], "-ds") == 0) {
13557           dirsubMode = TRUE;
13558           nohelpMode = TRUE;
13559         }
13560         else if (StringNCmp (argv[i], "-z", 2) == 0) {
13561           smartnetMode = TRUE;
13562           dirsubMode = TRUE;
13563           if(*(argv[i]+2) != NULLB)
13564             smartPort = atoi(argv[i]+2);
13565           else
13566             smartPort = SM_SERVER_PORT;
13567         }
13568 #endif
13569       }
13570   }}
13571 #endif
13572 
13573 #ifdef WIN_MSWIN
13574   {{
13575     Nlm_Int2         i;
13576     Nlm_Int4         argc = GetArgc();
13577     Nlm_CharPtr PNTR argv = GetArgv();
13578     for (i = 1;  i < argc;  i++)
13579       {
13580         if (StringCmp (argv[i], "-x") == 0)
13581           stdinMode = TRUE;
13582         else if (StringCmp (argv[i], "-f") == 0 && i + 1 < argc) {
13583           stdinMode = TRUE;
13584           filename = argv [i + 1];
13585         } else if (StringCmp (argv[i], "-e") == 0)
13586           entrezMode = TRUE;
13587         else if (StringCmp (argv[i], "-h") == 0)
13588           nohelpMode = TRUE;
13589         else if (StringCmp (argv[i], "-noseqfetch") == 0)
13590           useSeqFetch = FALSE;
13591         else if (StringCmp (argv[i], "-nolocalfetch") == 0)
13592           useLocal = FALSE;
13593         else if (StringCmp (argv[i], "-noseqidlookup") == 0)
13594           useIdLookup = FALSE;
13595 #ifdef USE_SMARTNET
13596         else if (StringNCmp (argv[i], "-z", 2) == 0) {
13597           smartnetMode = TRUE;
13598           dirsubMode = TRUE;
13599           if(*(argv[i]+2) != NULLB)
13600             smartPort = atoi(argv[i]+2);
13601           else
13602             smartPort = SM_SERVER_PORT;
13603         }
13604 #endif
13605       }
13606   }}
13607 #endif
13608 
13609   if (subtoolMode || smartnetMode) {
13610     Char  tmp [PATH_MAX];
13611     ProgramPath (tmp, sizeof (tmp));
13612     ptr = StringRChr (tmp, DIRDELIMCHR);
13613     if (ptr != NULL) {
13614       ptr++;
13615     }
13616     if (smartPort > 0) {
13617       sprintf (str, "- %s %s (%ld) [%s - %s]", ptr, SEQUIN_APPLICATION, (long) smartPort, date_of_compilation, time_of_compilation);
13618     } else {
13619       sprintf (str, "- %s %s [%s - %s]", ptr, SEQUIN_APPLICATION, date_of_compilation, time_of_compilation);
13620     }
13621     SetAppProperty ("SmartSequinTimeStampTitle", StringSave (str));
13622   }
13623 
13624   if (GetSequinAppParam ("SETTINGS", "STDINMODE", NULL, str, sizeof (str))) {
13625     if (StringICmp (str, "TRUE") == 0) {
13626       stdinMode = TRUE;
13627     }
13628   }
13629   if (GetSequinAppParam ("SETTINGS", "HIDEHELPFORM", NULL, str, sizeof (str))) {
13630     if (StringICmp (str, "TRUE") == 0) {
13631       nohelpMode = TRUE;
13632     }
13633   }
13634 
13635   WatchCursor ();
13636 
13637   SetTitle (w, "Loading parse tables");
13638   if (! AllObjLoad ()) {
13639     ArrowCursor ();
13640     Message (MSG_FATAL, "AllObjLoad failed");
13641     return 0;
13642   }
13643   if (! SubmitAsnLoad ()) {
13644     ArrowCursor ();
13645     Message (MSG_FATAL, "SubmitAsnLoad failed");
13646     return 0;
13647   }
13648   if (! objprojAsnLoad ()) {
13649     ArrowCursor ();
13650     Message (MSG_FATAL, "ProjectAsnLoad failed");
13651     return 0;
13652   }
13653 
13654   SetTitle (w, "Loading print templates");
13655   /* objprt.prt still needed for Edit Citations button and Desktop view */
13656   if (! PrintTemplateSetLoadEx ("objprt.prt", objPrtMemStr)) {
13657     ArrowCursor ();
13658     Message (MSG_FATAL, "PrintTemplateSetLoad objprt.prt failed");
13659     return 0;
13660   }
13661 
13662   SetTitle (w, "Loading sequence alphabet converter");
13663   if (! SeqCodeSetLoad ()) {
13664     ArrowCursor ();
13665     Message (MSG_FATAL, "SeqCodeSetLoad failed");
13666     return 0;
13667   }
13668 
13669   SetTitle (w, "Loading organism table");
13670   if (! LoadOrganismTable ()) {
13671     ArrowCursor ();
13672     Message (MSG_POSTERR, "LoadOrganismTable failed");
13673   }
13674 
13675   SetTitle (w, "Loading genetic code table");
13676   if (! GeneticCodeTableLoad ()) {
13677     ArrowCursor ();
13678     Message (MSG_FATAL, "GeneticCodeTableLoad failed");
13679     return 0;
13680   }
13681 
13682   SetTitle (w, "Loading feature definitions");
13683   if (! FeatDefSetLoad ()) {
13684     ArrowCursor ();
13685     Message (MSG_FATAL, "FeatDefSetLoad failed");
13686     return 0;
13687   }
13688 
13689   SetupGeneticCodes ();
13690 
13691   GeneticCodeSingletonInit ();
13692 
13693   if (! SetupPrintOptions ()) {
13694     ArrowCursor ();
13695     Message (MSG_FATAL, "StdPrintOptionsNew failed");
13696     return 0;
13697   }
13698 
13699 /*
13700 #ifndef WIN16
13701   SetTitle (w, "Loading structure dictionary");
13702   if (OpenMMDBAPI ((POWER_VIEW ^ FETCH_ENTREZ), NULL)) {
13703     prgdDict = GetPRGDDictionary ();
13704     if (BiostrucAvail ()) {
13705       Cn3DWin_Entrez(NULL, useEntrez);
13706     }
13707   }
13708 #endif
13709 */
13710 
13711   SetTitle (w, "Creating menus");
13712   SetupDesktop ();
13713   SetupCommonFonts ();
13714 
13715   InitSequinExtras ();
13716 
13717   VSMFileInit ();
13718   VSeqMgrInit (FALSE);
13719   WatchCursor ();
13720 
13721   /* register fetch functions */
13722 
13723   if (useEntrez) {
13724     /* EntrezBioseqFetchEnable ("Sequin", FALSE); */
13725     if (useSeqFetch) {
13726       /* ID1BioseqFetchEnable ("Sequin", FALSE); */
13727       PubSeqFetchEnable ();
13728       PubMedFetchEnable ();
13729     } else if (useIdLookup) {
13730       PubSeqFetchEnableEx (FALSE, TRUE, TRUE, TRUE, TRUE, -1);
13731       PubMedFetchEnable ();
13732     } else {
13733       PubMedFetchEnable ();
13734     }
13735   }
13736 
13737 #ifdef USE_SMARTNET
13738   if (dirsubMode) {
13739     if (useSeqFetch) {
13740       /* DirSubFetchEnable (); */
13741       TPASmartFetchEnable ();
13742       SmartFetchEnable ();
13743       HUPFetchEnable ();
13744     }
13745   }
13746 #endif
13747 
13748   if (useLocal) {
13749     LocalSeqFetchInit (FALSE);
13750   }
13751 
13752 /*
13753 #ifdef USE_SMARTNET
13754   if (dirsubMode) {
13755     if (only_use_smart) {
13756       SmartFetchEnable ();
13757     } else {
13758       DirSubFetchEnable ();
13759       SmartFetchEnable ();
13760       TPASmartFetchEnable ();
13761     }
13762   }
13763 #endif
13764 
13765   if (! only_use_smart) {
13766     if (useEntrez) {
13767       if (useSeqFetch) {
13768         PubSeqFetchEnable ();
13769         PubMedFetchEnable ();
13770       } else {
13771         PubSeqFetchEnableEx (FALSE, TRUE, TRUE, TRUE, TRUE, -1);
13772         PubMedFetchEnable ();
13773       }
13774     }
13775 
13776     if (useLocal) {
13777       LocalSeqFetchInit (FALSE);
13778     }
13779   }
13780 */
13781 
13782 #ifdef WIN_MAC
13783   SetDeactivate (NULL, MacDeactProc);
13784   SetupMacMenus ();
13785 #endif
13786 
13787   SetTitle (w, "Creating window");
13788   InitMuskStyles ();
13789 
13790   startupStyle = 0;
13791   if (GetSequinAppParam ("SETTINGS", "DEFAULTSTYLE", NULL, str, sizeof (str))) {
13792     if (StrToInt (str, &val) && val >= 0) {
13793       startupStyle = val;
13794       SetMuskCurrentSt (GetMuskStyleName (val));
13795     }
13796   }
13797 
13798   /* SequinCheckSocketsProc is called by SubtoolModeTimerProc,
13799   so that can safely override the Metronome call */
13800 
13801   Metronome (SequinCheckSocketsProc);
13802 
13803   subtoolEntityID = 0;
13804   subtoolTimerLimit = 100;
13805   subtoolTimerCount = 0;
13806   subtoolRecordDirty = FALSE;
13807   if (subtoolMode || smartnetMode) {
13808     if (GetSequinAppParam ("SETTINGS", "TIMERLIMIT", NULL, str, sizeof (str))) {
13809       if (StrToInt (str, &val) && val >= 0) {
13810         subtoolTimerLimit = val;
13811       }
13812     }
13813   }
13814 
13815 /* -------------------------- SmartNet -------------------------- */
13816   if(smartnetMode) {
13817 /*
13818     omp = ObjMgrGet();
13819     MemSet((Pointer)(&ompc), 0, sizeof(OMProcControl));
13820     ompc.input_entityID = 0;
13821     ompc.input_itemID = 0;
13822     ompc.input_itemtype = OBJ_BIOSEQ;
13823     ompc.input_data = NULL;
13824     ompp = NULL;
13825     while (procval != OM_MSG_RET_DONE &&
13826            (ompp = ObjMgrProcFindNext (omp, OMPROC_VIEW, OBJ_BIOSEQ, OBJ_BIOSEQ, ompp)) != NULL) {
13827       if (! ompp->subinputtype) {
13828         ompc.proc = ompp;
13829         procval = (*(ompp->func))((Pointer)&ompc);
13830         if (procval == OM_MSG_RET_ERROR) {
13831           ErrShow ();
13832         }
13833       }
13834     }
13835 */
13836 
13837 #ifdef USE_SMARTNET
13838     Remove (w);
13839     ArrowCursor ();
13840 
13841     if(!SMListenRequests(NULL,
13842                          SMReadBioseqObj,
13843                          smartPort)) {
13844       Message(MSG_OK, "Cannot start accept thread");
13845       QuitProgram();
13846     }
13847     subtoolTimerCount = 0;
13848     subtoolRecordDirty = FALSE;
13849     Metronome (SubtoolModeTimerProc);
13850     if (GetSequinAppParam ("PREFERENCES", "SUPPRESSUSAGE", NULL, str, sizeof (str)) && StringICmp (str, "TRUE") == 0) {
13851     } else {
13852       SetMenuAction (SqnMenuAction);
13853       SetButtonAction (SqnButtonAction);
13854     }
13855 
13856     ProcessEvents();
13857 
13858     /* No more code in Main() for smartnet Mode */
13859     return 0;
13860 
13861 #endif
13862 /* --------------------------------------------------------------- */
13863 
13864   } else if (subtoolMode || stdinMode || binseqentryMode) {
13865     Remove (w);
13866     ArrowCursor ();
13867     if (subtoolMode) {
13868       dataptr = SubtoolModeAsnTextFileRead ("stdin", &subtoolDatatype, &subtoolEntityID);
13869     } else if (binseqentryMode) {
13870       dataptr = NULL;
13871       aip = AsnIoOpen ("stdin", "rb");
13872       SeqMgrHoldIndexing (TRUE);
13873       sep = SeqEntryAsnRead (aip, NULL);
13874       SeqMgrHoldIndexing (FALSE);
13875       AsnIoClose (aip);
13876       if (sep != NULL) {
13877         if (sep->choice == 1) {
13878           subtoolDatatype = OBJ_BIOSEQ;
13879           dataptr = (Pointer) sep->data.ptrvalue;
13880         } else if (sep->choice == 2) {
13881           subtoolDatatype = OBJ_BIOSEQSET;
13882           dataptr = (Pointer) sep->data.ptrvalue;
13883         }
13884         if (dataptr != NULL) {
13885           subtoolEntityID = ObjMgrRegister (subtoolDatatype, dataptr);
13886         }
13887       }
13888     } else {
13889       if (! StringHasNoText (filename)) {
13890         fp = FileOpen (filename, "r");
13891       } else {
13892         fp = FileOpen ("stdin", "r");
13893       }
13894       dataptr = ReadAsnFastaOrFlatFile (fp, &subtoolDatatype,  &subtoolEntityID, FALSE, FALSE, TRUE, FALSE);
13895       FileClose (fp);
13896       /*
13897       dataptr = ObjMgrGenericAsnTextFileRead ("stdin", &subtoolDatatype, &subtoolEntityID);
13898       */
13899       if (dataptr == NULL) {
13900         fseek (stdin, 0, SEEK_SET);
13901         aip = AsnIoOpen ("stdin", "rb");
13902         SeqMgrHoldIndexing (TRUE);
13903         sep = SeqEntryAsnRead (aip, NULL);
13904         SeqMgrHoldIndexing (FALSE);
13905         AsnIoClose (aip);
13906         if (sep != NULL) {
13907           if (sep->choice == 1) {
13908             subtoolDatatype = OBJ_BIOSEQ;
13909             dataptr = (Pointer) sep->data.ptrvalue;
13910           } else if (sep->choice == 2) {
13911             subtoolDatatype = OBJ_BIOSEQSET;
13912             dataptr = (Pointer) sep->data.ptrvalue;
13913           }
13914           if (dataptr != NULL) {
13915             subtoolEntityID = ObjMgrRegister (subtoolDatatype, dataptr);
13916           }
13917         }
13918       }
13919     }
13920     if (dataptr != NULL && subtoolEntityID > 0) {
13921       if (subtoolDatatype == OBJ_SEQSUB || subtoolDatatype == OBJ_SEQENTRY ||
13922           subtoolDatatype == OBJ_BIOSEQ || subtoolDatatype == OBJ_BIOSEQSET) {
13923         WatchCursor ();
13924         sep = GetTopSeqEntryForEntityID (subtoolEntityID);
13925         if (sep == NULL) {
13926           sep = SeqEntryNew ();
13927           if (sep != NULL) {
13928             if (subtoolDatatype == OBJ_BIOSEQ) {
13929               bsp = (BioseqPtr) dataptr;
13930               sep->choice = 1;
13931               sep->data.ptrvalue = bsp;
13932               SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
13933             } else if (subtoolDatatype == OBJ_BIOSEQSET) {
13934               bssp = (BioseqSetPtr) dataptr;
13935               sep->choice = 2;
13936               sep->data.ptrvalue = bssp;
13937               SeqMgrSeqEntry (SM_BIOSEQSET, (Pointer) bssp, sep);
13938             } else {
13939               sep = SeqEntryFree (sep);
13940             }
13941           }
13942           sep = GetTopSeqEntryForEntityID (subtoolEntityID);
13943         }
13944         if (sep != NULL) {
13945           if (EntrezASN1Detected (sep)) {
13946             ErrPostEx (SEV_WARNING, 0, 0, "This record was retrieved from Entrez");
13947           }
13948           if (! leaveAsOldAsn) {
13949             if (subtoolMode) {
13950               MySeqEntryToAsn3 (sep, TRUE, FALSE, TRUE);
13951 
13952               /* now instantiating protein titles */
13953               InstantiateProteinTitles (subtoolEntityID, NULL);
13954             } else {
13955               notaxid = FALSE;
13956               VisitBioSourcesInSep (sep, (Pointer) &notaxid, LookForTaxonID);
13957               if (notaxid) {
13958                 MySeqEntryToAsn3 (sep, TRUE, FALSE, FALSE);
13959               }
13960             }
13961           }
13962           if (subtoolMode) {
13963             if (sep->choice == 2 && sep->data.ptrvalue != NULL) {
13964               bssp = (BioseqSetPtr) sep->data.ptrvalue;
13965               if (bssp->_class != 7) {
13966                 Message (MSG_OK, "WARNING: Converting from bioseq set of class %d", (int) bssp->_class);
13967               }
13968               bssp->_class = 7;
13969             }
13970             if (FileLength (SEQUIN_EDIT_BACK_FILE) > 0) {
13971               if (Message (MSG_YN, "Restore from backup?") == ANS_YES) {
13972                 oldsep = RestoreFromFile (SEQUIN_EDIT_BACK_FILE);
13973                 ReplaceSeqEntryWithSeqEntry (sep, oldsep, TRUE);
13974                 subtoolEntityID = ObjMgrGetEntityIDForChoice (sep);
13975               }
13976             }
13977           }
13978         }
13979         if (stdinMode) {
13980           seqviewprocs.filepath = filename;
13981         }
13982         seqviewprocs.forceSeparateViewer = TRUE;
13983         SeqEntrySetScope (NULL);
13984         handled = GatherProcLaunch (OMPROC_VIEW, FALSE, subtoolEntityID, 1,
13985                                     OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
13986         seqviewprocs.filepath = NULL;
13987         ArrowCursor ();
13988         subtoolTimerCount = 0;
13989         subtoolRecordDirty = FALSE;
13990         if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
13991           Message (MSG_FATAL, "Unable to launch viewer.");
13992           CleanupSequin ();
13993           return 0;
13994         } else {
13995           if (! nohelpMode) {
13996             SetTitle (w, "Creating help window");
13997             if (helpForm == NULL) {
13998               helpForm = CreateHelpForm (-95, -5, "Sequin Help", "sequin.hlp",
13999                                          HideHelpForm, HelpActivateProc);
14000             }
14001           }
14002           SendHelpScrollMessage (helpForm, "Editing the Record", NULL);
14003         }
14004         ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, subtoolEntityID);
14005         if (! subtoolMode) {
14006           ObjMgrSetDirtyFlag (subtoolEntityID, TRUE);
14007         }
14008         if (subtoolMode) {
14009           Metronome (SubtoolModeTimerProc);
14010           omudp = ObjMgrAddUserData (subtoolEntityID, 0, 0, 0);
14011           if (omudp != NULL) {
14012             omudp->messagefunc = SubtoolModeMsgFunc;
14013           }
14014           subtoolRecordDirty = TRUE;
14015         }
14016       } else {
14017         Message (MSG_FATAL, "Unable to recognize ASN.1 type %d", (int) subtoolDatatype);
14018         CleanupSequin ();
14019         return 0;
14020       }
14021     } else {
14022       Message (MSG_FATAL, "Unable to read ASN.1 file");
14023       CleanupSequin ();
14024       return 0;
14025     }
14026   } else if (workbenchMode) {
14027     Remove (w);
14028     ArrowCursor ();
14029   } else if (entrezMode) {
14030     Remove (w);
14031     ArrowCursor ();
14032   } else {
14033     if (! nohelpMode) {
14034       SetTitle (w, "Creating help window");
14035       if (helpForm == NULL) {
14036         helpForm = CreateHelpForm (-95, -5, "Sequin Help", "sequin.hlp",
14037                                    HideHelpForm, HelpActivateProc);
14038       }
14039     }
14040     SetTitle (w, "Creating initial window");
14041     fetchProc = NULL;
14042     if (allowDownload) {
14043       fetchProc = FetchFromNet;
14044     }
14045     if (genomeCenter != NULL) {
14046       startupForm = CreateStartupForm (-5, -67, "Welcome to Sequin",
14047                                        StartFa2htgs, StartPhrap, BuildContig,
14048                                        StartNew, ReadOld, fetchProc,
14049                                        ShowHelp, CreateSubmissionTemplate, DoQuit, StartupActivateProc);
14050     } else {
14051       startupForm = CreateStartupForm (-5, -67, "Welcome to Sequin",
14052                                        NULL, NULL, NULL, StartNew, ReadOld, fetchProc,
14053                                        ShowHelp, NULL, DoQuit, StartupActivateProc);
14054     }
14055     globalFormatBlock.seqPackage = SEQ_PKG_SINGLE;
14056     globalFormatBlock.seqFormat = SEQ_FMT_FASTA;
14057     globalFormatBlock.numSeqs = 0;
14058     globalFormatBlock.submType = SEQ_ORIG_SUBMISSION;
14059     Remove (w);
14060     ArrowCursor ();
14061   }
14062 
14063   if (backupMode) {
14064     Metronome (BackupModeTimerProc);
14065   }
14066 
14067   if (indexerVersion) {
14068     str [0] = '\0';
14069     if (GetSequinAppParam ("PREFERENCES", "SUPPRESSUSAGE", NULL, str, sizeof (str)) && StringICmp (str, "TRUE") == 0) {
14070     } else {
14071       SetMenuAction (SqnMenuAction);
14072       SetButtonAction (SqnButtonAction);
14073     }
14074   }
14075 
14076   if (subtoolMode || stdinMode || binseqentryMode) {
14077   } else if (workbenchMode) {
14078   } else if (entrezMode) {
14079     /*
14080     MakeTermListForm ();
14081     if (termListForm != NULL) {
14082       Show (termListForm);
14083       Select (termListForm);
14084       Update ();
14085       MakeDocSumForm ();
14086       if (docSumForm != NULL) {
14087       } else {
14088         Message (MSG_FATAL, "Unable to create document window");
14089         CleanupSequin ();
14090         return 0;
14091       }
14092     } else {
14093       Message (MSG_FATAL, "Unable to create term list window");
14094       CleanupSequin ();
14095       return 0;
14096     }
14097     */
14098     Message (MSG_FATAL, "This mode is obsolete");
14099     CleanupSequin ();
14100     return 0;
14101   } else if (startupForm != NULL) {
14102     Show (startupForm);
14103     Select (startupForm);
14104     Update ();
14105     initSubmitForm = CreateInitSubmitterForm (-5, -67, "Submitting Authors",
14106                                               GetFormat, BackToStartup,
14107                                               SubmitBlockActivateProc);
14108     wizardChoiceForm = CreateWizardChoiceForm ();
14109 
14110     formatForm = CreateFormatForm (-5, -67, "Sequence Format",
14111                                    GetOrgAndSeq, BackToSubmitter, FormatActivateProc);
14112     if (! nohelpMode) {
14113       Update ();
14114       Show (helpForm);
14115       Select (helpForm);
14116       Update ();
14117       SendHelpScrollMessage (helpForm, "Introduction", NULL);
14118     }
14119   } else {
14120     Message (MSG_FATAL, "Unable to create window.");
14121     CleanupSequin ();
14122     return 0;
14123   }
14124 
14125 #if defined(WIN_MAC)  ||  defined(WIN_MSWIN)
14126   RegisterDropProc (SequinOpenMimeFile);
14127   RegisterResultProc (SequinOpenResultFile);
14128 #endif
14129 
14130   if (workbenchMode) {
14131     VSeqMgrRun ("NCBI Desktop", "Sequin Workbench");
14132   } else {
14133     ProcessEvents ();
14134   }
14135 
14136   WatchCursor ();
14137   val = GetMuskCurrentSt ();
14138   if (val < 0) {
14139     val = 0;
14140   }
14141   if (val >= GetMuskTotalSt ()) {
14142     val = 0;
14143   }
14144   if (val != startupStyle) {
14145     if (val > 0) {
14146       sprintf (str, "%d", (int) val);
14147       SetSequinAppParam ("SETTINGS", "DEFAULTSTYLE", str);
14148     } else {
14149       SetSequinAppParam ("SETTINGS", "DEFAULTSTYLE", "0");
14150     }
14151   }
14152 
14153   Remove (startupForm);
14154   Remove (initSubmitForm);
14155   Remove (formatForm);
14156   Remove (helpForm);
14157 
14158   FreeSqnTempFiles ();
14159 
14160   ArrowCursor ();
14161   Update ();
14162 
14163   CleanupSequin ();
14164 
14165   return 0;
14166 }
14167 
14168 extern SubmitBlockPtr ConvertSequinBlockToSubmitBlock (SequinBlockPtr sqp);
14169 
ExportSubmitterBlockTemplate(SeqEntryPtr sep,SeqDescrPtr sdp)14170 extern Boolean ExportSubmitterBlockTemplate (SeqEntryPtr sep, SeqDescrPtr sdp)
14171 {
14172   SeqSubmitPtr ssp;
14173   Char         path [PATH_MAX];
14174   AsnIoPtr     aip;
14175   FILE         *fp;
14176 
14177   if (globalsbp == NULL)
14178   {
14179     Message (MSG_ERROR, "No submit block!");
14180     return FALSE;
14181   }
14182 
14183   if (!GetOutputFileName (path, sizeof (path), NULL))
14184   {
14185     return FALSE;
14186   }
14187 
14188   fp = FileOpen (path, "w");
14189   if (fp == NULL)
14190   {
14191     Message (MSG_ERROR, "Unable to open %s", path);
14192     return FALSE;
14193   }
14194 
14195   ssp = SeqSubmitNew ();
14196   if (ssp == NULL)
14197   {
14198     Message (MSG_ERROR, "Unable to allocate memory for seq-submit");
14199     return FALSE;
14200   }
14201 
14202   ssp->datatype = 1;
14203   ssp->data = (Pointer) sep;
14204 
14205   /* need to store copy of globalbsp in form */
14206   PointerToForm (initSubmitForm, globalsbp);
14207   ssp->sub = ConvertSequinBlockToSubmitBlock (globalsbp);
14208   /* get globalbsp back */
14209   globalsbp = FormToPointer (initSubmitForm);
14210   aip = AsnIoNew(ASNIO_TEXT_OUT, fp, NULL, NULL, NULL);
14211   SeqSubmitAsnWrite(ssp, aip, NULL);
14212 
14213 	AsnIoFlush(aip);
14214   AsnIoReset(aip);
14215   if (sdp != NULL)
14216   {
14217     SeqDescAsnWrite (sdp, aip, NULL);
14218 	  AsnIoFlush(aip);
14219     AsnIoReset(aip);
14220   }
14221   AsnIoClose (aip);
14222 
14223   ssp = SeqSubmitFree (ssp);
14224 
14225   globalsbp = SequinBlockFree (globalsbp);
14226   Hide (initSubmitForm);
14227   Hide (formatForm);
14228   Update ();
14229   Show (startupForm);
14230   Select (startupForm);
14231   SendHelpScrollMessage (helpForm, "Introduction", NULL);
14232   Update ();
14233   return TRUE;
14234 }
14235 
14236 
MakeBadSpecificHostValueTable(IteM i)14237 extern void MakeBadSpecificHostValueTable (IteM i)
14238 {
14239   BaseFormPtr  bfp;
14240   SeqEntryPtr  sep;
14241   LogInfoPtr   lip;
14242   ValNodePtr    misspelled = NULL, bad_caps = NULL, ambiguous = NULL, unrecognized = NULL;
14243 
14244 #ifdef WIN_MAC
14245   bfp = currentFormDataPtr;
14246 #else
14247   bfp = GetObjectExtra (i);
14248 #endif
14249   if (bfp == NULL) return;
14250   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
14251   if (sep == NULL) return;
14252 
14253 
14254   Taxon3ValidateSpecificHostsInSeqEntry (sep, &misspelled, &bad_caps, &ambiguous, &unrecognized);
14255 
14256   if (misspelled == NULL && bad_caps == NULL && ambiguous == NULL && unrecognized == NULL)
14257   {
14258     Message (MSG_OK, "No bad specific-host values found!");
14259     return;
14260   }
14261   lip = OpenLog ("Bad Specific-Host Values");
14262 
14263   if (misspelled != NULL) {
14264     fprintf (lip->fp, "Mis-spelled Specific-Host Values\n");
14265     lip->data_in_log = WriteBadSpecificHostTable (misspelled, lip->fp);
14266     misspelled = ValNodeFree (misspelled);
14267   }
14268   if (bad_caps != NULL) {
14269     fprintf (lip->fp, "Incorrectly Capitalized Specific-Host Values\n");
14270     lip->data_in_log = WriteBadSpecificHostTable (bad_caps, lip->fp);
14271     bad_caps = ValNodeFree (bad_caps);
14272   }
14273   if (ambiguous != NULL) {
14274     fprintf (lip->fp, "Ambiguous Specific-Host Values\n");
14275     lip->data_in_log = WriteBadSpecificHostTable (ambiguous, lip->fp);
14276     ambiguous = ValNodeFree (ambiguous);
14277   }
14278   if (unrecognized != NULL) {
14279     fprintf (lip->fp, "Unrecognized Specific-Host Values\n");
14280     lip->data_in_log = WriteBadSpecificHostTable (unrecognized, lip->fp);
14281     unrecognized = ValNodeFree (unrecognized);
14282   }
14283   CloseLog (lip);
14284   lip = FreeLog (lip);
14285 }
14286 
14287 
14288 typedef struct updatefeaturesform {
14289   FORM_MESSAGE_BLOCK
14290   DialoG new_features;
14291   DialoG old_features;
14292 } UpdateFeaturesFormData, PNTR UpdateFeaturesFormPtr;
14293 
14294 
MoveFeatureToReplacement(ButtoN b)14295 static void MoveFeatureToReplacement (ButtoN b)
14296 {
14297   UpdateFeaturesFormPtr f;
14298   ValNodePtr            features;
14299 
14300   f = (UpdateFeaturesFormPtr) GetObjectExtra (b);
14301   if (f == NULL) return;
14302 
14303   features = RemoveSelectedFeaturesFromList (f->old_features);
14304   if (!AddFeaturesToReplaceList(f->new_features, features)) {
14305     features = ValNodeFree (features);
14306   }
14307 }
14308 
14309 
MoveAllFeaturesToReplacement(ButtoN b)14310 static void MoveAllFeaturesToReplacement (ButtoN b)
14311 {
14312   UpdateFeaturesFormPtr f;
14313   ValNodePtr            features;
14314 
14315   f = (UpdateFeaturesFormPtr) GetObjectExtra (b);
14316   if (f == NULL) return;
14317 
14318   features = (ValNodePtr) DialogToPointer (f->old_features);
14319   PointerToDialog (f->old_features, NULL);
14320   if (!AddFeaturesToReplaceList(f->new_features, features)) {
14321     features = ValNodeFree (features);
14322   }
14323 }
14324 
14325 
AutomatchFeaturesForReplacement(ButtoN b)14326 static void AutomatchFeaturesForReplacement (ButtoN b)
14327 {
14328   UpdateFeaturesFormPtr f;
14329   ValNodePtr            existing_features;
14330 
14331   f = (UpdateFeaturesFormPtr) GetObjectExtra (b);
14332   if (f == NULL) return;
14333 
14334   existing_features = DialogToPointer (f->old_features);
14335   PointerToDialog (f->old_features, NULL);
14336   if (AutomatchFeatures (f->new_features, &existing_features)) {
14337     PointerToDialog (f->old_features, existing_features);
14338   }
14339 
14340 }
14341 
14342 
MoveFeatureToSelection(ButtoN b)14343 static void MoveFeatureToSelection (ButtoN b)
14344 {
14345   UpdateFeaturesFormPtr f;
14346   ValNodePtr            features;
14347 
14348   f = (UpdateFeaturesFormPtr) GetObjectExtra (b);
14349   if (f == NULL) return;
14350 
14351   features = RemoveFeaturesFromReplaceList (f->new_features);
14352   AddFeaturesToList (f->old_features, features);
14353 }
14354 
14355 
DoUpdateFeatures(ButtoN b)14356 static void DoUpdateFeatures (ButtoN b)
14357 {
14358   UpdateFeaturesFormPtr f;
14359   ValNodePtr            feature_list;
14360 
14361   f = (UpdateFeaturesFormPtr) GetObjectExtra (b);
14362   if (f == NULL) return;
14363 
14364   feature_list = DialogToPointer (f->new_features);
14365   ActOnFeatureReplaceList (feature_list);
14366   feature_list = FeatureReplaceListFree (feature_list);
14367   DeleteMarkedObjects (f->input_entityID, 0, NULL);
14368   ObjMgrSetDirtyFlag (f->input_entityID, TRUE);
14369   ObjMgrSendMsg (OM_MSG_UPDATE, f->input_entityID, 0, 0);
14370 
14371   Remove (f->form);
14372 }
14373 
14374 
14375 
ScrollToReplacementFeature(Pointer data)14376 static void ScrollToReplacementFeature (Pointer data)
14377 {
14378   UpdateFeaturesFormPtr frm;
14379   SeqFeatPtr new_feat;
14380 
14381   frm = (UpdateFeaturesFormPtr) data;
14382   if (frm == NULL) {
14383     return;
14384   }
14385 
14386   /* find currently highlighted feature */
14387   new_feat = GetSelectedNewFeature (frm->new_features);
14388 
14389   /* find "auto" replacement feature */
14390   /* if found, highlight and scroll to it */
14391   /* otherwise scroll to first feature that overlaps this location */
14392   ScrollToMatchingFeatures (frm->old_features, new_feat);
14393 }
14394 
14395 
UpdateFeatures(IteM i)14396 extern void UpdateFeatures (IteM i)
14397 {
14398   BaseFormPtr  bfp;
14399   SeqEntryPtr  sep;
14400   Pointer        dataptr;
14401   Uint2          datatype;
14402   FILE           *fp;
14403   Char           path [PATH_MAX];
14404   SeqAnnotPtr    sap;
14405   SeqFeatPtr     sfp;
14406   ValNodePtr     new_feat_list = NULL, no_bsp_list = NULL, old_item_list = NULL;
14407   Int4           leftmost = -1, rightmost = -1, new_left, new_right, tmp;
14408   BioseqPtr      bsp = NULL, last_bsp = NULL;
14409   SeqLocPtr        slp;
14410   WindoW           w;
14411   GrouP            h, g2, k, c;
14412   ButtoN           b;
14413   UpdateFeaturesFormPtr f;
14414 
14415 
14416 #ifdef WIN_MAC
14417   bfp = currentFormDataPtr;
14418 #else
14419   bfp = GetObjectExtra (i);
14420 #endif
14421   if (bfp == NULL) return;
14422   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
14423   if (sep == NULL) return;
14424 
14425   path [0] = '\0';
14426   if (!GetInputFileName (path, sizeof (path), "", "TEXT")) {
14427     return;
14428   }
14429 
14430   fp = FileOpen (path, "r");
14431   if (fp == NULL) {
14432     Message (MSG_ERROR, "Unable to open file!");
14433     return;
14434   }
14435   dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, NULL, FALSE, FALSE,
14436                                     TRUE, TRUE);
14437   FileClose (fp);
14438   if (dataptr == NULL || datatype != OBJ_SEQANNOT) {
14439     Message (MSG_ERROR, "File does not contain feature table!");
14440     return;
14441   }
14442 
14443   sap = (SeqAnnotPtr) dataptr;
14444   if (sap->type != 1) {
14445     Message (MSG_ERROR, "File does not contain feature table!");
14446     sap = SeqAnnotFree (sap);
14447     return;
14448   }
14449 
14450   SortSeqFeatInAnnot (sap);
14451 
14452   /* get intervals for features for each bioseq */
14453   for (sfp = sap->data; sfp != NULL; sfp = sfp->next) {
14454     bsp = BioseqFindFromSeqLoc (sfp->location);
14455     if (bsp == NULL) {
14456       ValNodeAddPointer (&no_bsp_list, OBJ_SEQFEAT, sfp);
14457     } else {
14458       if (bsp != last_bsp) {
14459         if (last_bsp != NULL) {
14460           slp = SeqLocIntNew (leftmost, rightmost, Seq_strand_plus, SeqIdDup (SeqIdFindWorst (bsp->id)));
14461           ValNodeLink (&old_item_list, ListFeaturesOverlappingLocation (last_bsp, slp, 0, 0));
14462           slp = SeqLocFree (slp);
14463         }
14464         last_bsp = bsp;
14465         leftmost = -1;
14466         rightmost = -1;
14467       }
14468       new_left = SeqLocStart (sfp->location);
14469       new_right = SeqLocStop (sfp->location);
14470       if (new_left > new_right) {
14471         tmp = new_left;
14472         new_left = new_right;
14473         new_right = tmp;
14474       }
14475       if (leftmost == -1 || new_left < leftmost) {
14476         leftmost = new_left;
14477       }
14478       if (rightmost == -1 || new_right > rightmost) {
14479         rightmost = new_right;
14480       }
14481     }
14482   }
14483   if (last_bsp != NULL && bsp != NULL) {
14484     slp = SeqLocIntNew (leftmost, rightmost, Seq_strand_plus, SeqIdDup (SeqIdFindWorst (bsp->id)));
14485     ValNodeLink (&old_item_list, ListFeaturesOverlappingLocation (last_bsp, slp, 0, 0));
14486     slp = SeqLocFree (slp);
14487   }
14488 
14489   if (no_bsp_list != NULL) {
14490     Message (MSG_ERROR, "%d features in table are not found on a Bioseq in this record!", ValNodeLen (no_bsp_list));
14491     no_bsp_list = ValNodeFree (no_bsp_list);
14492   }
14493 
14494   new_feat_list = FeatureReplaceListFromSeqAnnot (sap);
14495   sap = SeqAnnotFree (sap);
14496 
14497   if (new_feat_list == NULL) {
14498     Message (MSG_ERROR, "No features found!");
14499     return;
14500   }
14501 
14502   /* Now create dialog to allow user to select new features to import and existing features to delete */
14503   f = (UpdateFeaturesFormPtr) MemNew (sizeof (UpdateFeaturesFormData));
14504   w = FixedWindow (-50, -33, -10, -10, "Update Features", StdCloseWindowProc);
14505   SetObjectExtra (w, f, StdCleanupFormProc);
14506   f->form = (ForM) w;
14507   f->input_entityID = bfp->input_entityID;
14508   h = HiddenGroup (w, -1, 0, NULL);
14509   SetGroupSpacing (h, 10, 10);
14510 
14511   g2 = HiddenGroup (h, 3, 0, NULL);
14512   StaticPrompt (g2, "Features to Import", 0, 0, programFont, 'c');
14513   StaticPrompt (g2, "", 0, 0, programFont, 'l');
14514   StaticPrompt (g2, "Existing Features that Overlap this Interval", 0, 0, programFont, 'c');
14515   f->new_features = FeatureReplaceListDialog (g2, 400, ScrollToReplacementFeature, f);
14516   PointerToDialog (f->new_features, new_feat_list);
14517   new_feat_list = FeatureReplaceListFree (new_feat_list);
14518   k = HiddenGroup (g2, 0, 3, NULL);
14519   b = PushButton (k, "<=", MoveFeatureToReplacement);
14520   SetObjectExtra (b, f, NULL);
14521   b = PushButton (k, "<<=", MoveAllFeaturesToReplacement);
14522   SetObjectExtra (b, f, NULL);
14523   b = PushButton (k, "=>", MoveFeatureToSelection);
14524   SetObjectExtra (b, f, NULL);
14525   f->old_features = FeatureSelectListDialog (g2, 400);
14526   PointerToDialog (f->old_features, old_item_list);
14527 
14528   c = HiddenGroup (h, 4, 0, NULL);
14529   b = PushButton (c, "Accept", DoUpdateFeatures);
14530   SetObjectExtra (b, f, NULL);
14531   b = PushButton (c, "Automatch", AutomatchFeaturesForReplacement);
14532   SetObjectExtra (b, f, NULL);
14533   PushButton (c, "Cancel", StdCancelButtonProc);
14534 
14535   AlignObjects (ALIGN_CENTER, (HANDLE) g2, (HANDLE) c, NULL);
14536   Show (w);
14537   Select (w);
14538 }
14539 
14540 
IsRNASpacer(CharPtr rna_name)14541 static Boolean IsRNASpacer (CharPtr rna_name)
14542 {
14543   CharPtr cp;
14544   Boolean rval = FALSE;
14545 
14546   if (StringHasNoText (rna_name)) {
14547     rval = FALSE;
14548   } else if (isdigit (*rna_name)) {
14549     cp = rna_name + 1;
14550     while (isdigit (*cp)) {
14551       cp++;
14552     }
14553     if (*cp == 'S' && *(cp + 1) == '-' && isdigit (*(cp + 2))) {
14554       cp += 3;
14555       while (isdigit (*cp)) {
14556         cp++;
14557       }
14558       if (StringCmp (cp, "S ribosomal RNA intergenic spacer") == 0) {
14559         rval = TRUE;
14560       } else {
14561         rval = FALSE;
14562       }
14563     } else {
14564       rval = FALSE;
14565     }
14566   }
14567   return rval;
14568 }
14569 
14570 
IsrRNAName(CharPtr rna_name)14571 static Boolean IsrRNAName(CharPtr rna_name)
14572 {
14573   CharPtr cp;
14574   Boolean rval = FALSE;
14575 
14576   if (StringHasNoText (rna_name)) {
14577     rval = FALSE;
14578   } else if (isdigit (*rna_name)) {
14579     cp = rna_name + 1;
14580     while (isdigit (*cp)) {
14581       cp++;
14582     }
14583     if (StringCmp (cp, "S ribosomal RNA") == 0) {
14584       rval = TRUE;
14585     } else {
14586       rval = FALSE;
14587     }
14588   } else if ((StringNCmp (rna_name, "large", 5) == 0 || StringNCmp (rna_name, "small", 5) == 0)
14589              && StringCmp (rna_name + 5, " subunit ribosomal RNA") == 0) {
14590     rval = TRUE;
14591   }
14592   return rval;
14593 }
14594 
14595 
AddChimeraComment(SeqEntryPtr sep,CharPtr program,CharPtr version)14596 static void AddChimeraComment (SeqEntryPtr sep, CharPtr program, CharPtr version)
14597 {
14598   SeqDescPtr   sdp;
14599   CharPtr      fmt = "Sequences were screened for chimeras by the submitter using %s%s%s";
14600   CharPtr      cmt;
14601 
14602   sdp = CreateNewDescriptor (sep, Seq_descr_comment);
14603   cmt = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (program) + StringLen (version)));
14604   sprintf (cmt, fmt, program, StringHasNoText (version) ? "" : " ", StringHasNoText (version) ? "" : version);
14605   sdp->data.ptrvalue = cmt;
14606 }
14607 
14608 
StripQuotesInNote(BioSourcePtr biop,Pointer data)14609 static void StripQuotesInNote (BioSourcePtr biop, Pointer data)
14610 {
14611   SubSourcePtr ssp;
14612   Int4         len;
14613   CharPtr      src, dst;
14614 
14615   if (biop == NULL) {
14616     return;
14617   }
14618   for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next) {
14619     if (ssp->subtype == SUBSRC_other && !StringHasNoText (ssp->name)) {
14620       len = StringLen (ssp->name);
14621       src = ssp->name;
14622       dst = ssp->name;
14623       if (ssp->name[0] == '\"') {
14624         src++;
14625         len--;
14626       }
14627       if (src[len - 1] == '\"') {
14628         len--;
14629       }
14630       StringNCpy (dst, src, len);
14631       dst[len] = 0;
14632     }
14633   }
14634 }
14635 
14636 
DefLineForSeqEntry(SeqEntryPtr sep)14637 static CharPtr DefLineForSeqEntry (SeqEntryPtr sep)
14638 {
14639   SeqDescPtr sdp = NULL;
14640   BioseqPtr  bsp;
14641 
14642   if (IS_Bioseq (sep) && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL) {
14643     sdp = bsp->descr;
14644     while (sdp != NULL && sdp->choice != Seq_descr_title) {
14645       sdp = sdp->next;
14646     }
14647   }
14648   if (sdp != NULL) {
14649     return sdp->data.ptrvalue;
14650   } else {
14651     return NULL;
14652   }
14653 }
14654 
14655 
14656 typedef Boolean (*PatternFunc) PROTO ((CharPtr val));
14657 
DoAnySequencesHaveModifierEx(IDAndTitleEditPtr iatep,CharPtr mod_name,PatternFunc match)14658 static Boolean DoAnySequencesHaveModifierEx (IDAndTitleEditPtr iatep, CharPtr mod_name, PatternFunc match)
14659 {
14660   CharPtr     val;
14661   Boolean     rval = FALSE;
14662   Int4        i;
14663 
14664   if (iatep == NULL) {
14665     return FALSE;
14666   }
14667 
14668   for (i = 0; i < iatep->num_sequences && !rval; i++) {
14669     val = FindValueFromPairInDefline (mod_name, iatep->title_list[i]);
14670     if (!StringHasNoText (val) && (match == NULL || match (val))) {
14671       rval = TRUE;
14672     }
14673     val = MemFree (val);
14674   }
14675   return rval;
14676 }
14677 
DoAnySequencesHaveModifier(IDAndTitleEditPtr iatep,CharPtr mod_name)14678 static Boolean DoAnySequencesHaveModifier (IDAndTitleEditPtr iatep, CharPtr mod_name)
14679 {
14680   return DoAnySequencesHaveModifierEx (iatep, mod_name, NULL);
14681 }
14682 
FindIdInIdAndTitleEdit(SeqIdPtr sip,IDAndTitleEditPtr iatep)14683 static Int4 FindIdInIdAndTitleEdit (SeqIdPtr sip, IDAndTitleEditPtr iatep)
14684 {
14685   Int4 i;
14686   CharPtr id_label;
14687 
14688   if (sip == NULL || iatep == NULL) {
14689     return -1;
14690   }
14691 
14692   if (sip->choice == SEQID_LOCAL) {
14693     id_label = SeqIdWholeLabel (sip, PRINTID_REPORT);
14694   } else {
14695     id_label = SeqIdWholeLabel (sip, PRINTID_FASTA_SHORT);
14696   }
14697 
14698   for (i = 0; i < iatep->num_sequences; i++) {
14699     if (StringCmp (id_label, iatep->id_list[i]) == 0) {
14700       return i;
14701     }
14702   }
14703   return -1;
14704 }
14705 
14706 /* source qual validation functions */
NotAllNumbers(CharPtr val,CharPtr name,Boolean general)14707 static CharPtr NotAllNumbers (CharPtr val, CharPtr name, Boolean general)
14708 {
14709   CharPtr cp;
14710   CharPtr rval = NULL;
14711   CharPtr specific_fmt = "%s should not be all numbers";
14712   CharPtr general_fmt = "The %s qualifier should have values like %s.  At least one of your %s values is all numbers.";
14713   CharPtr general_no_ex_fmt = "At least one of your %s values is all numbers.";
14714   CharPtr host_ex = "Homo sapiens, pig, potato, etc.";
14715   CharPtr country_ex = "Antarctica, Brazil, USA, etc.";
14716   CharPtr ex = NULL;
14717   CharPtr fmt = general_no_ex_fmt;
14718 
14719   if (val == NULL || *val == 0) {
14720     return NULL;
14721   }
14722   cp = val;
14723   while (*cp != 0 && isdigit (*cp)) {
14724     cp++;
14725   }
14726   if (*cp == 0) {
14727     if (general) {
14728       if (StringICmp (name, "host") == 0) {
14729         ex = host_ex;
14730         fmt = general_fmt;
14731       } else if (StringICmp (name, "country") == 0) {
14732         ex = country_ex;
14733         fmt = general_fmt;
14734       }
14735       if (ex == NULL) {
14736         rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (name)));
14737         sprintf (rval, fmt, name);
14738       } else {
14739         rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (ex) + 2 * StringLen (name)));
14740         sprintf (rval, fmt, name, ex, name);
14741       }
14742     } else {
14743       rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (specific_fmt) + StringLen (name)));
14744       sprintf (rval, specific_fmt, name);
14745     }
14746   }
14747   return rval;
14748 }
14749 
14750 
DateIsAmbiguous(CharPtr val,CharPtr name,Boolean general)14751 static CharPtr DateIsAmbiguous (CharPtr val, CharPtr name, Boolean general)
14752 {
14753   Boolean is_ambiguous = FALSE;
14754   CharPtr rval = NULL, tmp;
14755   CharPtr specific_fmt = "%s has ambiguous format";
14756   CharPtr general_fmt = "The collection-date qualifier should have values like 09-Aug-2000, Jun-1989, 2011, etc.  At least one of your collection-date values is ambiguous.";
14757   CharPtr general_no_ex_fmt = "At least one of your %s values is ambiguous.";
14758 
14759 
14760   if (val == NULL || *val == 0) {
14761     return NULL;
14762   }
14763   tmp = ReformatDateStringEx (val, FALSE, &is_ambiguous);
14764   if (tmp == NULL || is_ambiguous) {
14765     if (general) {
14766       if (StringICmp (name, "collection-date") == 0) {
14767         rval = StringSave (general_fmt);
14768       } else {
14769         rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (general_no_ex_fmt) + StringLen (name)));
14770         sprintf (rval, general_no_ex_fmt, name);
14771       }
14772     } else {
14773       rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (specific_fmt) + StringLen (name)));
14774       sprintf (rval, specific_fmt, name);
14775     }
14776   }
14777   tmp = MemFree (tmp);
14778   return rval;
14779 }
14780 
14781 
14782 CharPtr sBadUnculturedIsolationSources[] = {
14783   "uncultured bacterium",
14784   "uncultured bacteria",
14785   "uncultured fungus",
14786   "uncultured fungi",
14787   "uncultured bacterium clone",
14788   "uncultured bacteria clone",
14789   "uncultured fungus clone",
14790   "uncultured fungi clone",
14791   "isolation source",
14792   NULL
14793 };
14794 
14795 
ValueInList(CharPtr val,CharPtr PNTR list)14796 static CharPtr ValueInList (CharPtr val, CharPtr PNTR list)
14797 {
14798   Int4 i;
14799 
14800   for (i = 0; list[i] != NULL; i++) {
14801     if (StringICmp (val, list[i]) == 0) {
14802       return list[i];
14803     }
14804   }
14805   return NULL;
14806 }
14807 
14808 
IsolationSourceOk(CharPtr val,CharPtr name,Boolean general)14809 static CharPtr IsolationSourceOk (CharPtr val, CharPtr name, Boolean general)
14810 {
14811   Boolean is_ambiguous = FALSE;
14812   CharPtr rval = NULL;
14813   CharPtr specific_short_fmt = "isolation-source should have a value like seawater, soil, etc.  '%s' is suspiciously short";
14814   CharPtr general_short_fmt = "isolation-source should have a value like seawater, soil, etc.  At least one of your values is suspiciously short.";
14815   CharPtr specific_bad_fmt = "isolation-source should have a value like seawater, soil, etc. '%s' is not a valid isolation-source.";
14816   CharPtr general_bad_fmt = "isolation-source should have a value like seawater, soil, etc.  One or more isolation-source values you have provided are not valid.";
14817 
14818   if (StringHasNoText (val)) {
14819     return NULL;
14820   }
14821 
14822   if (StringLen (val) < 3) {
14823     if (general) {
14824       rval = StringSave (general_short_fmt);
14825     } else {
14826       rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (specific_short_fmt) + StringLen (val)));
14827       sprintf (rval, specific_short_fmt, val);
14828     }
14829   } else if (ValueInList(val, sBadUnculturedIsolationSources)) {
14830     if (general) {
14831       rval = StringSave (general_bad_fmt);
14832     } else {
14833       rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (general_bad_fmt) + StringLen (val)));
14834       sprintf (rval, general_bad_fmt, val);
14835     }
14836   }
14837   return rval;
14838 }
14839 
14840 
LaunchWebBrowser(CharPtr url)14841 static void LaunchWebBrowser (CharPtr url)
14842 {
14843 #ifdef WIN_MOTIF
14844   NS_Window  window = NULL;
14845 #endif
14846 
14847 #ifdef WIN_MAC
14848   Nlm_SendURLAppleEvent (url, "MOSS", NULL);
14849 #endif
14850 #ifdef WIN_MSWIN
14851   Nlm_MSWin_OpenDocument (url);
14852 #endif
14853 #ifdef WIN_MOTIF
14854   NS_OpenURL (&window, url, NULL, TRUE);
14855   NS_WindowFree (window);
14856 #endif
14857 }
14858 
14859 
14860 typedef enum {
14861   eVirusClass_Unknown = 0,
14862   eVirusClass_Generic,
14863   eVirusClass_FootAndMouth,
14864   eVirusClass_Influenza,
14865   eVirusClass_Caliciviridae,
14866   eVirusClass_Rotavirus
14867 } EVirusClass;
14868 
14869 typedef enum {
14870   eVirusFeat_None = 0,
14871   eVirusFeat_LTR,
14872   eVirusFeat_UTR5,
14873   eVirusFeat_UTR3,
14874   eVirusFeat_viroid_complete,
14875   eVirusFeat_viroid_partial,
14876   eVirusFeat_CDS,
14877   eVirusFeat_misc_feature
14878 } EVirusFeat;
14879 
14880 typedef enum {
14881   eCulturedKingdom_Unknown = 0,
14882   eCulturedKingdom_BacteriaArchea,
14883   eCulturedKingdom_CulturedFungus,
14884   eCulturedKingdom_VoucheredFungus,
14885   eCulturedKingdom_Other
14886 } ECulturedKingdom;
14887 
14888 typedef enum {
14889   eCulturedFeat_None = 0,
14890   eCulturedFeat_misc_feature
14891 } ECulturedFeat;
14892 
14893 typedef enum {
14894   eIGSSourceType_Unknown = 0,
14895   eIGSSourceType_CulturedFungus,
14896   eIGSSourceType_VoucheredFungus,
14897   eIGSSourceType_Plant,
14898   eIGSSourceType_Animal
14899 } EIGSSourceType;
14900 
14901 typedef enum {
14902   eWGSSourceType_Unknown = 0,
14903   eWGSSourceType_Bacteria,
14904   eWGSSourceType_Fungi,
14905   eWGSSourceType_OtherEuk
14906 } EWGSSourceType;
14907 
14908 static CharPtr wizard_names[] = {
14909   "",
14910   "Uncultured Sample Wizard",
14911   "Virus Wizard",
14912   "rRNA-ITS-IGS Wizard",
14913   "TSA Wizard",
14914   "IGS Wizard",
14915   "Microsatellite Wizard",
14916   "D-loop Wizard",
14917   "WGS Wizard"
14918 };
14919 
14920 
FormatWizardTitle(CharPtr fmt,EWizardType wizard_type)14921 static CharPtr FormatWizardTitle (CharPtr fmt, EWizardType wizard_type)
14922 {
14923   CharPtr title;
14924 
14925   title = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (wizard_names[wizard_type])));
14926   sprintf (title, fmt, wizard_names[wizard_type]);
14927   return title;
14928 }
14929 
14930 
14931 /* list of dialog titles - some are re-used, here for ease of changing formatting */
14932 /* three titles for each class of title */
14933 static CharPtr wizard_dlg_titles[] = {
14934   "Uncultured Sample Wizard Annotation",
14935   "Virus Wizard Annotation",
14936   "rRNA-ITS-IGS Wizard Annotation",
14937   "TSA Wizard Annotation",
14938   "IGS Wizard Annotation",
14939   "Microsatellite Wizard Annotation",
14940   "D-loop Wizard Annotation",
14941   "WGS Wizard Annotation",
14942 
14943   "Uncultured Sample Wizard Primer Type",
14944   "Virus Wizard Primer Type",
14945   "rRNA-ITS-IGS Wizard Primer Type",
14946   "TSA Wizard Primer Type",
14947   "IGS Wizard Primer Type",
14948   "Microsatellite Wizard Primer Type",
14949   "D-Loop Wizard Primer Type",
14950   "WGS Wizard Primer Type",
14951 
14952   "Uncultured Sample Wizard Source Information",
14953   "Virus Wizard Source Information",
14954   "rRNA-ITS-IGS Wizard Source Information",
14955   "TSA Wizard Source Information",
14956   "IGS Wizard Source Information",
14957   "Microsatellite Wizard Source Information",
14958   "D-Loop Wizard Source Information",
14959   "WGS Wizard Source Information",
14960 
14961   "Uncultured Sample Wizard Molecule Information",
14962   "Virus Wizard Molecule Information",
14963   "rRNA-ITS-IGS Wizard Molecule Information",
14964   "TSA Wizard Molecule Information",
14965   "IGS Wizard Molecule Information",
14966   "Microsatellite Wizard Molecule Type",
14967   "D-Loop Wizard Molecule Information",
14968   "WGS Wizard Molecule Information"
14969 };
14970 
14971 typedef enum {
14972   eWizardDlgTitle_Annotation = 0,
14973   eWizardDlgTitle_PrimerType,
14974   eWizardDlgTitle_Source,
14975   eWizardDlgTitle_Molecule
14976 } EWizardDlgTitle;
14977 
14978 
GetWizardDlgTitle(EWizardType wizard_type,EWizardDlgTitle title)14979 static CharPtr GetWizardDlgTitle (EWizardType wizard_type, EWizardDlgTitle title)
14980 {
14981   Int4 pos = (eNumWizardTypes * title) + (wizard_type - 1) ;
14982 
14983   if (pos < 0 || pos >= sizeof (wizard_dlg_titles) / sizeof (CharPtr)) {
14984     return "Wizard";
14985   } else {
14986     return wizard_dlg_titles[pos];
14987   }
14988 }
14989 
14990 
UserObjectListFree(ValNodePtr list)14991 static ValNodePtr UserObjectListFree (ValNodePtr list)
14992 {
14993   ValNodePtr vnp_next;
14994 
14995   while (list != NULL) {
14996     vnp_next = list->next;
14997     list->next = NULL;
14998     list->data.ptrvalue = UserObjectFree (list->data.ptrvalue);
14999     list = ValNodeFree (list);
15000     list = vnp_next;
15001   }
15002   return list;
15003 }
15004 
15005 
GetStructuredCommentFromList(ValNodePtr list,CharPtr tag)15006 static ValNodePtr  GetStructuredCommentFromList (ValNodePtr list, CharPtr tag)
15007 {
15008   ValNodePtr rval = NULL;
15009   ValNode    vn;
15010   CharPtr    db;
15011 
15012   MemSet (&vn, 0, sizeof (ValNode));
15013   vn.choice = StructuredCommentField_database;
15014 
15015   while (list != NULL && rval == NULL) {
15016     db = GetStructuredCommentFieldFromUserObject (list->data.ptrvalue, &vn, NULL);
15017     if (StringCmp (db, tag) == 0) {
15018       rval = list;
15019     }
15020     db = MemFree (db);
15021     list = list->next;
15022   }
15023   return rval;
15024 }
15025 
15026 
RemoveStructuredCommentFromList(ValNodePtr PNTR list,CharPtr tag)15027 static void RemoveStructuredCommentFromList (ValNodePtr PNTR list, CharPtr tag)
15028 {
15029   ValNodePtr vnp, prev = NULL, vnp_next;
15030   ValNode    vn;
15031   CharPtr    db;
15032 
15033   if (list == NULL || *list == NULL) {
15034     return;
15035   }
15036   MemSet (&vn, 0, sizeof (ValNode));
15037   vn.choice = StructuredCommentField_database;
15038 
15039   for (vnp = *list; vnp != NULL; vnp = vnp_next) {
15040     vnp_next = vnp->next;
15041     db = GetStructuredCommentFieldFromUserObject (vnp->data.ptrvalue, &vn, NULL);
15042     if (StringCmp (db, tag) == 0) {
15043       if (prev == NULL) {
15044         *list = vnp->next;
15045       } else {
15046         prev->next = vnp->next;
15047       }
15048       vnp->next = NULL;
15049       vnp->data.ptrvalue = UserObjectFree (vnp->data.ptrvalue);
15050       vnp = ValNodeFree (vnp);
15051     } else {
15052       prev = vnp;
15053     }
15054     db = MemFree (db);
15055   }
15056 }
15057 
15058 
15059 /* clicking text that looks like a URL launches a web browser. */
ClickDocURL(DoC d,PoinT pt)15060 static void ClickDocURL (DoC d, PoinT pt)
15061 {
15062   Int2             item;
15063   Int2             row;
15064   Int2             col;
15065   CharPtr          str;
15066 
15067   MapDocPoint (d, pt, &item, &row, &col, NULL);
15068   if (item < 1) {
15069     return;
15070   }
15071 
15072   str = GetDocText (d, item, 0, 0);
15073   if (StringNCmp (str, "http://", 7) == 0 ) {
15074     LaunchWebBrowser(str);
15075   }
15076   str = MemFree (str);
15077 }
15078 
15079 
15080 typedef enum {
15081   eWizardEditQual_None,
15082   eWizardEditQual_ApplyAll,
15083   eWizardEditQual_CopyFromId,
15084   eWizardEditQual_Range
15085 } EWizardEditQual;
15086 
15087 typedef CharPtr (*IsSrcQualFormatValid) PROTO ((CharPtr, CharPtr, Boolean));
15088 
15089 #define QUAL_BLOCK \
15090   CharPtr name; \
15091   CharPtr add_name; \
15092   EWizardEditQual edit_type; \
15093   Boolean required; \
15094   Boolean show; \
15095   Boolean valid_required; \
15096   CharPtr example; \
15097   Boolean problem_when_missing; \
15098   CharPtr linked;
15099 
15100 typedef struct wizardqual {
15101   QUAL_BLOCK
15102 } WizardQualData, PNTR WizardQualPtr;
15103 
15104 
ShowLinkedQuals(ValNodePtr extra_src_quals,CharPtr q_name)15105 static Int4 ShowLinkedQuals (ValNodePtr extra_src_quals, CharPtr q_name)
15106 {
15107   ValNodePtr vnp;
15108   WizardQualPtr q;
15109   Int4 num = 0;
15110 
15111   for (vnp = extra_src_quals; vnp != NULL; vnp = vnp->next) {
15112     q = (WizardQualPtr) vnp->data.ptrvalue;
15113     if (StringCmp (q->linked, q_name) == 0) {
15114       q->show = TRUE;
15115       num++;
15116     }
15117   }
15118   return num;
15119 }
15120 
15121 
15122 typedef struct wizardsrcqual {
15123   QUAL_BLOCK
15124   IsSrcQualFormatValid valid_func;
15125 } WizardSrcQualData, PNTR WizardSrcQualPtr;
15126 
15127 
15128 typedef struct examplepair {
15129   CharPtr qual_name;
15130   CharPtr example;
15131 } ExamplePairData, PNTR ExamplePairPtr;
15132 
15133 static ExamplePairData s_QualiferExamples[] = {
15134   { "Collection-date", "05-Feb-2005"} ,
15135   { "host", "Homo sapiens"},
15136   { "lat-lon", "39.00 N 77.10 W"},
15137   { "strain", "ABC123" },
15138   { "country", "USA: Ann Arbor, MI"},
15139   { "Isolation-source", "soil"},
15140   { "Isolate", "SDZ123"},
15141   { "Specimen-voucher", "USNM:12345"},
15142   { "sex", "female"},
15143   { "breed", "Holstein"},
15144   { "cultivar", "Granny Smith"},
15145   { NULL, NULL } };
15146 
GetDefaultExample(CharPtr name)15147 static CharPtr GetDefaultExample (CharPtr name)
15148 {
15149   Int4 i;
15150 
15151   for (i = 0; s_QualiferExamples[i].qual_name != NULL; i++) {
15152     if (StringICmp (s_QualiferExamples[i].qual_name, name) == 0) {
15153       return s_QualiferExamples[i].example;
15154     }
15155   }
15156   return NULL;
15157 }
15158 
15159 
15160 typedef struct formatpair {
15161   CharPtr qual_name;
15162   IsSrcQualFormatValid func;
15163 } FormatPairData, PNTR FormatPairPtr;
15164 
15165 static FormatPairData s_QualiferFormatCheck[] = {
15166   { "collection-date", DateIsAmbiguous },
15167   { "country", NotAllNumbers },
15168   { "host", NotAllNumbers },
15169   { "isolation-source", IsolationSourceOk },
15170   { NULL, NULL } };
15171 
GetDefaultValidator(CharPtr name)15172 static IsSrcQualFormatValid GetDefaultValidator (CharPtr name)
15173 {
15174   Int4 i;
15175 
15176   for (i = 0; s_QualiferFormatCheck[i].qual_name != NULL; i++) {
15177     if (StringICmp (s_QualiferFormatCheck[i].qual_name, name) == 0) {
15178       return s_QualiferFormatCheck[i].func;
15179     }
15180   }
15181   return NULL;
15182 }
15183 
15184 
WizardSrcQualNewEx(CharPtr name,EWizardEditQual edit_type,Boolean show,Boolean required,IsSrcQualFormatValid valid_func,Boolean valid_required,CharPtr example)15185 static WizardSrcQualPtr WizardSrcQualNewEx
15186 (CharPtr name,
15187  EWizardEditQual edit_type,
15188  Boolean show,
15189  Boolean required,
15190  IsSrcQualFormatValid valid_func,
15191  Boolean valid_required,
15192  CharPtr example)
15193 {
15194   WizardSrcQualPtr q;
15195 
15196   q = (WizardSrcQualPtr) MemNew (sizeof (WizardSrcQualData));
15197   q->name = name;
15198   q->add_name = name;
15199   q->edit_type = edit_type;
15200   q->show = show;
15201   q->required = required;
15202   q->problem_when_missing = FALSE;
15203   if (valid_func == NULL) {
15204     q->valid_func = GetDefaultValidator(name);
15205   } else {
15206     q->valid_func = valid_func;
15207   }
15208   q->valid_required = valid_required;
15209   q->example = example;
15210   q->linked = NULL;
15211   return q;
15212 }
15213 
WizardSrcQualNew(CharPtr name,EWizardEditQual edit_type,Boolean show,Boolean required)15214 static WizardSrcQualPtr WizardSrcQualNew (CharPtr name, EWizardEditQual edit_type, Boolean show, Boolean required)
15215 {
15216   return WizardSrcQualNewEx (name, edit_type, show, required, NULL, FALSE, NULL);
15217 
15218 }
15219 
15220 
TabTableLineFromSrcQuals(CharPtr title,ValNodePtr base_src_quals,ValNodePtr extra_src_quals)15221 static ValNodePtr TabTableLineFromSrcQuals (CharPtr title, ValNodePtr base_src_quals, ValNodePtr extra_src_quals)
15222 {
15223   CharPtr val;
15224   ValNodePtr vals = NULL, vnp;
15225   WizardSrcQualPtr q;
15226 
15227   for (vnp = base_src_quals; vnp != NULL; vnp = vnp->next) {
15228     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
15229     val = FindValueFromPairInDefline (q->name, title);
15230     ValNodeAddPointer (&vals, 0, val);
15231   }
15232   for (vnp = extra_src_quals; vnp != NULL; vnp = vnp->next) {
15233     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
15234     if (q->show) {
15235       val = FindValueFromPairInDefline (q->name, title);
15236       ValNodeAddPointer (&vals, 0, val);
15237     }
15238   }
15239   return vals;
15240 }
15241 
15242 
15243 typedef void (*ApplyFeatureQualFunc) PROTO ((SeqFeatPtr, CharPtr));
15244 typedef CharPtr (*GetFeatureQualFunc) PROTO ((SeqFeatPtr));
15245 typedef CharPtr (*GetWizardFeatureProblem) PROTO ((CharPtr, BioseqPtr));
15246 
15247 typedef CharPtr (*IsFeatQualFormatValid) PROTO ((CharPtr, CharPtr, BioseqPtr));
15248 
15249 
15250 typedef struct wizardfeatqual {
15251   QUAL_BLOCK
15252   IsFeatQualFormatValid valid_func;
15253   ApplyFeatureQualFunc  apply_func;
15254   GetFeatureQualFunc    get_func;
15255   GetWizardFeatureProblem problem_func;
15256   Boolean                 delete_if_invalid;
15257 } WizardFeatQualData, PNTR WizardFeatQualPtr;
15258 
WizardFeatQualNew(CharPtr name,EWizardEditQual edit_type,Boolean show,Boolean required,ApplyFeatureQualFunc apply_func,GetFeatureQualFunc get_func,GetWizardFeatureProblem problem_func,IsFeatQualFormatValid valid_func,Boolean valid_required,CharPtr example)15259 static WizardFeatQualPtr WizardFeatQualNew
15260 (CharPtr name,
15261  EWizardEditQual edit_type,
15262  Boolean show,
15263  Boolean required,
15264  ApplyFeatureQualFunc apply_func,
15265  GetFeatureQualFunc get_func,
15266  GetWizardFeatureProblem problem_func,
15267  IsFeatQualFormatValid valid_func,
15268  Boolean valid_required,
15269  CharPtr example)
15270 {
15271   WizardFeatQualPtr q;
15272 
15273   q = (WizardFeatQualPtr) MemNew (sizeof (WizardFeatQualData));
15274   q->name = name;
15275   q->add_name = name;
15276   q->edit_type = edit_type;
15277   q->show = show;
15278   q->required = required;
15279   q->problem_when_missing = FALSE;
15280   q->valid_func = valid_func;
15281   q->valid_required = valid_required;
15282   q->delete_if_invalid = FALSE;
15283   q->example = example;
15284   q->apply_func = apply_func;
15285   q->get_func = get_func;
15286   q->problem_func = problem_func;
15287   q->linked = NULL;
15288   return q;
15289 }
15290 
15291 
UniquenessListFree(ValNodePtr uniqueness_list)15292 static ValNodePtr UniquenessListFree (ValNodePtr uniqueness_list)
15293 {
15294   ValNodePtr vnp_i;
15295 
15296   for (vnp_i = uniqueness_list; vnp_i != NULL; vnp_i = vnp_i->next) {
15297     vnp_i->data.ptrvalue = ValNodeFreeData (vnp_i->data.ptrvalue);
15298   }
15299   uniqueness_list = ValNodeFree (uniqueness_list);
15300   return uniqueness_list;
15301 }
15302 
15303 
GetPositionForQual(WizardQualPtr srch,ValNodePtr base_src_quals,ValNodePtr extra_src_quals,ValNodePtr feat_quals)15304 static Int4 GetPositionForQual
15305 (WizardQualPtr srch,
15306  ValNodePtr base_src_quals,
15307  ValNodePtr extra_src_quals,
15308  ValNodePtr feat_quals)
15309 {
15310   Int4 pos = 1;
15311   WizardQualPtr q;
15312   ValNodePtr vnp;
15313 
15314   if (srch == NULL) {
15315     return 0;
15316   }
15317 
15318   for (vnp = base_src_quals; vnp != NULL; vnp = vnp->next) {
15319     q = (WizardQualPtr) vnp->data.ptrvalue;
15320     if (StringICmp (srch->name, q->name) == 0) {
15321       return pos;
15322     } else {
15323       pos++;
15324     }
15325   }
15326   for (vnp = extra_src_quals; vnp != NULL; vnp = vnp->next) {
15327     q = (WizardQualPtr) vnp->data.ptrvalue;
15328     if (q->show) {
15329       if (StringICmp (srch->name, q->name) == 0) {
15330         return pos;
15331       } else {
15332         pos++;
15333       }
15334     }
15335   }
15336 
15337   for (vnp = feat_quals; vnp != NULL; vnp = vnp->next) {
15338     q = (WizardQualPtr) vnp->data.ptrvalue;
15339     if (StringICmp (srch->name, q->name) == 0) {
15340       return pos;
15341     } else {
15342       pos++;
15343     }
15344   }
15345   return 0;
15346 }
15347 
15348 
GetNthField(ValNodePtr col,Int4 n)15349 static CharPtr GetNthField (ValNodePtr col, Int4 n)
15350 {
15351   Int4 i = 0;
15352 
15353   while (i < n && col != NULL) {
15354     i++;
15355     col = col->next;
15356   }
15357   if (col != NULL) {
15358     return col->data.ptrvalue;
15359   } else{
15360     return NULL;
15361   }
15362 }
15363 
15364 
AddDuplicateProblems(ValNodePtr PNTR list,CharPtr PNTR vals,CharPtr PNTR problems,Int4 num_sequences,CharPtr err_name)15365 static void AddDuplicateProblems (ValNodePtr PNTR list, CharPtr PNTR vals, CharPtr PNTR problems, Int4 num_sequences, CharPtr err_name)
15366 {
15367   ValNodePtr this_vnp, vnp;
15368   CharPtr    val;
15369   Int4       i;
15370   Boolean    found_dup;
15371 
15372   if (list == NULL || *list == NULL || (*list)->next == NULL) {
15373     return;
15374   }
15375 
15376   *list = ValNodeSort (*list, SortVnpByString);
15377   this_vnp = *list;
15378   while (this_vnp != NULL && this_vnp->next != NULL) {
15379     val = this_vnp->data.ptrvalue;
15380     vnp = this_vnp->next;
15381     found_dup = FALSE;
15382     while (vnp != NULL && StringCmp (val, vnp->data.ptrvalue) == 0) {
15383       found_dup = TRUE;
15384       vnp = vnp->next;
15385     }
15386     if (found_dup) {
15387       for (i = 0; i < num_sequences; i++) {
15388         if (StringCmp (val, vals[i]) == 0) {
15389           SetStringValue (&(problems[i]), err_name, ExistingTextOption_append_semi);
15390         }
15391       }
15392     }
15393     this_vnp = vnp;
15394   }
15395 }
15396 
15397 
15398 static void
GetUniquenessProblemsForTable(ValNodePtr table,ValNodePtr uniqueness_list,ValNodePtr base_src_quals,ValNodePtr extra_src_quals,ValNodePtr feat_quals,CharPtr PNTR problems)15399 GetUniquenessProblemsForTable
15400 (ValNodePtr table,
15401  ValNodePtr uniqueness_list,
15402  ValNodePtr base_src_quals,
15403  ValNodePtr extra_src_quals,
15404  ValNodePtr feat_quals,
15405  CharPtr PNTR problems)
15406 {
15407   ValNodePtr vnp_row, vnp_u, vnp_q, unique_list = NULL;
15408   CharPtr PNTR vals;
15409   CharPtr this_val;
15410   Int4 num_rows, row_num;
15411   Int4 num_quals, i, pos;
15412   Int4Ptr pos_list;
15413   CharPtr PNTR qual_names;
15414   BoolPtr any_qual;
15415   CharPtr dup_msg;
15416   CharPtr single_fmt = "Duplicate %s";
15417   CharPtr multiple_start = "Duplicate ";
15418   CharPtr multiple_end = " combination";
15419   Int4 dup_msg_len, num_quals_found;
15420   WizardQualPtr q;
15421 
15422   if (table == NULL || table->next == NULL) {
15423     return;
15424   }
15425   num_rows = ValNodeLen (table);
15426   vals = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_rows);
15427   for (vnp_u = uniqueness_list; vnp_u != NULL; vnp_u = vnp_u->next) {
15428     num_quals = 0;
15429     for (i = 0, vnp_q = vnp_u->data.ptrvalue; vnp_q != NULL; vnp_q = vnp_q->next, i++) {
15430       q = vnp_q->data.ptrvalue;
15431       pos = GetPositionForQual (q, base_src_quals, extra_src_quals, feat_quals);
15432       if (pos > 0) {
15433         num_quals++;
15434       }
15435     }
15436 
15437     num_quals = ValNodeLen (vnp_u->data.ptrvalue);
15438     pos_list = (Int4Ptr) MemNew (sizeof (Int4) * num_quals);
15439     any_qual = (BoolPtr) MemNew (sizeof (Boolean) * num_quals);
15440     qual_names = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_quals);
15441     dup_msg_len = 0;
15442     num_quals_found = 0;
15443     MemSet (any_qual, 0, sizeof (Boolean) * num_quals);
15444     for (i = 0, vnp_q = vnp_u->data.ptrvalue; vnp_q != NULL; vnp_q = vnp_q->next) {
15445       q = vnp_q->data.ptrvalue;
15446       pos_list[i] = GetPositionForQual (q, base_src_quals, extra_src_quals, feat_quals);
15447       if (pos_list[i] > 0) {
15448         qual_names[i] = q->name;
15449         i++;
15450       }
15451     }
15452     for (vnp_row = table, row_num = 0; vnp_row != NULL; vnp_row = vnp_row->next, row_num++) {
15453       vals[row_num] = NULL;
15454       for (i = 0; i < num_quals; i++) {
15455         this_val = GetNthField (vnp_row->data.ptrvalue, pos_list[i]);
15456         if (!StringHasNoText (this_val)) {
15457           if (!any_qual[i]) {
15458             dup_msg_len += StringLen (qual_names[i]) + 1;
15459             num_quals_found++;
15460             any_qual[i] = TRUE;
15461           }
15462         }
15463         SetStringValue (vals + row_num, this_val, ExistingTextOption_append_semi);
15464       }
15465     }
15466     if (num_quals_found == 0) {
15467       /* nothing found, don't bother */
15468     } else {
15469       for (row_num = 0; row_num < num_rows; row_num++) {
15470         ValNodeAddPointer (&unique_list, 0, vals[row_num]);
15471       }
15472       if (num_quals_found == 1) {
15473         dup_msg_len += StringLen (single_fmt);
15474         dup_msg = (CharPtr) MemNew (sizeof (CharPtr) * dup_msg_len);
15475         for (i = 0; i < num_quals; i++) {
15476           if (any_qual[i]) {
15477             sprintf (dup_msg, single_fmt, qual_names[i]);
15478             break;
15479           }
15480         }
15481       } else {
15482         dup_msg_len += StringLen (multiple_start) + StringLen (multiple_end);
15483         dup_msg = (CharPtr) MemNew (sizeof (CharPtr) * dup_msg_len);
15484         StringCpy (dup_msg, multiple_start);
15485         for (i = 0; i < num_quals; i++) {
15486           if (any_qual[i]) {
15487             StringCat (dup_msg, qual_names[i]);
15488             num_quals_found--;
15489             if (num_quals_found != 0) {
15490               StringCat (dup_msg, "/");
15491             }
15492           }
15493         }
15494         StringCat (dup_msg, multiple_end);
15495       }
15496       AddDuplicateProblems (&unique_list, vals, problems, num_rows, dup_msg);
15497       unique_list = ValNodeFree (unique_list);
15498       dup_msg = MemFree (dup_msg);
15499     }
15500     pos_list = MemFree (pos_list);
15501     any_qual = MemFree (any_qual);
15502     qual_names = MemFree (qual_names);
15503     for (row_num = 0; row_num < num_rows; row_num++) {
15504       vals[row_num] = MemFree (vals[row_num]);
15505     }
15506   }
15507 
15508 }
15509 
15510 
15511  typedef struct wizardtracker {
15512   EWizardType wizard_type;
15513   SeqEntryPtr sequences;
15514   Uint1       set_class;
15515   ValNodePtr  base_src_quals;
15516   ValNodePtr  extra_src_quals;
15517 
15518   /* for tab-delimited (not 5-col) feature table */
15519   ValNodePtr  feature_quals;
15520 
15521   /* virus class - used by virus wizard to determine required/recommended source quals */
15522   EVirusClass virus_class;
15523   /* virus feature */
15524   EVirusFeat  virus_feat;
15525   CharPtr     misc_feat_comment;
15526 
15527   /* molinfo - used by virus wizard and cultured samples wizard to store molinfo used for descriptor for each sequence */
15528   MolInfoPtr molinfo;
15529   Uint1      mol_class;
15530   CharPtr    molinfo_comment;
15531   Uint1      topology;
15532 
15533   /* cultured kingdom - used by cultured samples wizard to determine required/recommended source quals */
15534   ECulturedKingdom cultured_kingdom;
15535 
15536   /* IGS source type */
15537   EIGSSourceType igs_source_type;
15538 
15539   /* WGS source type */
15540   EWGSSourceType wgs_source_type;
15541   /* WGS AGP file */
15542   Boolean has_agp;
15543   /* WGS Ns message */
15544   CharPtr wgs_ns_msg;
15545 
15546   /* microsatellite flags */
15547   Boolean multiple_repeats;
15548 
15549   /* genome - used for source location */
15550   Uint1 genome;
15551 
15552   /* cultured_feat - used by cultured samples for feature type */
15553   ECulturedFeat cultured_feat;
15554 
15555 
15556   Boolean partial5;
15557   Boolean partial3;
15558 
15559   /* for coding regions */
15560   CharPtr prot_name;
15561   CharPtr cds_comment;
15562   CharPtr prot_desc;
15563   Boolean use_minus_strand;
15564 
15565   /* other features */
15566   CharPtr gene_name;
15567   CharPtr rna_name;
15568   Boolean spans_unknown;
15569 
15570   /* SeqAnnots from Feature Tables */
15571   ValNodePtr annot_list;
15572   ValNodePtr feat_qual_table;
15573 
15574   ValNodePtr uniqueness_list; /* this list uses choices to indicate the types of columns combined
15575                                 * to create uniqueness.
15576                                 * * 1 means a srcqual
15577                                 * * 2 means another featurequal
15578                                 */
15579 
15580   /* chimera program */
15581   CharPtr chimera_program;
15582   CharPtr chimera_version;
15583 
15584   /* list of structured comment objects to add */
15585   ValNodePtr structured_comments;
15586 
15587   /* breadcrumb trail indicates where we have been,
15588    * so that we can navigate back.
15589    */
15590   ValNodePtr breadcrumbs;
15591 
15592   /* extra comment with instructions for indexers */
15593   CharPtr comment;
15594 
15595   /* biosample/bioproject/srr */
15596   CharPtr bioproject;
15597   CharPtr biosample;
15598   CharPtr srr;
15599 
15600   Int4 assembled_choice;
15601   Boolean is_fasta;
15602   TSequenceInfoPtr aln_settings;
15603 
15604   Boolean add_span_note;
15605 
15606   /* sequence length */
15607   Int4 min_seq_length;
15608   Int4 recommended_seq_length;
15609 
15610   /* when leaving wizard to start sequin, use alternate message about adding features */
15611   Boolean use_alternate_leaving_msg;
15612 
15613   Boolean show_feature_table_help;
15614 
15615   Boolean quit_now;
15616 } WizardTrackerData, PNTR WizardTrackerPtr;
15617 
15618 
FreeAnnotList(ValNodePtr list)15619 static ValNodePtr FreeAnnotList (ValNodePtr list)
15620 {
15621   ValNodePtr vnp;
15622 
15623   for (vnp = list; vnp != NULL; vnp = vnp->next) {
15624     ObjMgrFree (vnp->choice, vnp->data.ptrvalue);
15625   }
15626   list = ValNodeFree (list);
15627   return list;
15628 }
15629 
15630 
ResetWizardTrackerVirusFeat(WizardTrackerPtr wiz)15631 static void ResetWizardTrackerVirusFeat (WizardTrackerPtr wiz)
15632 {
15633   if (wiz != NULL) {
15634     wiz->partial5 = FALSE;
15635     wiz->partial3 = FALSE;
15636     wiz->virus_feat = eVirusFeat_None;
15637     wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
15638     wiz->gene_name = MemFree (wiz->gene_name);
15639     wiz->rna_name = MemFree (wiz->rna_name);
15640     wiz->prot_name = MemFree (wiz->prot_name);
15641     wiz->annot_list = FreeAnnotList(wiz->annot_list);
15642     wiz->chimera_program = MemFree (wiz->chimera_program);
15643     wiz->chimera_version = MemFree (wiz->chimera_version);
15644     wiz->spans_unknown = FALSE;
15645     wiz->assembled_choice = 0;
15646   }
15647 }
15648 
15649 
ResetWizardTrackerCulturedSamplesFeat(WizardTrackerPtr wiz)15650 static void ResetWizardTrackerCulturedSamplesFeat (WizardTrackerPtr wiz)
15651 {
15652   if (wiz != NULL) {
15653     wiz->partial5 = FALSE;
15654     wiz->partial3 = FALSE;
15655     wiz->cultured_feat = eCulturedFeat_None;
15656     wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
15657     wiz->gene_name = MemFree (wiz->gene_name);
15658     wiz->rna_name = MemFree (wiz->rna_name);
15659     wiz->prot_name = MemFree (wiz->prot_name);
15660     wiz->chimera_program = MemFree (wiz->chimera_program);
15661     wiz->chimera_version = MemFree (wiz->chimera_version);
15662     wiz->spans_unknown = FALSE;
15663     wiz->assembled_choice = 0;
15664   }
15665 }
15666 
15667 
15668 static const CharPtr s_LeavingWizardMsg = "You will now be transferred to the record viewer.\nOnce you have opened the record viewer, you cannot return to the wizard.\nClick Cancel to continue editing your information in the wizard.";
15669 static const CharPtr s_AlternateLeavingWizardMsg = "You will now be transferred to the record viewer.\nAdd annotation using the menu options or a feature table.\nYou cannot return to the wizard once you open the record viewer.\n\nClick Cancel to continue editing your information in the wizard.";
15670 
15671 
StringFromUserField(UserFieldPtr ufp)15672 static CharPtr StringFromUserField (UserFieldPtr ufp)
15673 {
15674   CharPtr rval = NULL;
15675   Int4    i, len = 0;
15676   CharPtr PNTR cpp;
15677 
15678   if (ufp == NULL) {
15679     return NULL;
15680   } else if (ufp->choice == 1) {
15681     rval = StringSave (ufp->data.ptrvalue);
15682   } else if (ufp->choice == 7) {
15683     cpp = ufp->data.ptrvalue;
15684     for (i = 0; i < ufp->num; i++) {
15685       len += StringLen (cpp[i]) + 1;
15686     }
15687     rval = (CharPtr) MemNew (sizeof (Char) * len);
15688     rval[0] = 0;
15689     for (i = 0; i < ufp->num; i++) {
15690       StringCat (rval, cpp[i]);
15691       if (i < ufp->num - 1) {
15692         StringCat (rval, ",");
15693       }
15694     }
15695   }
15696   return rval;
15697 }
15698 
15699 
DescriptorsToWizard(WizardTrackerPtr wiz)15700 static void DescriptorsToWizard (WizardTrackerPtr wiz)
15701 {
15702   SeqDescPtr sdp, s_prev = NULL, s_next;
15703   UserObjectPtr uop;
15704   UserFieldPtr  ufp;
15705 
15706   if (globalsbp == NULL || wiz == NULL || globalsbp->descriptors == NULL) {
15707     return;
15708   }
15709   for (sdp = globalsbp->descriptors; sdp != NULL; sdp = s_next) {
15710     s_next = sdp->next;
15711     if (sdp->choice == Seq_descr_user
15712         && (uop = (UserObjectPtr) sdp->data.ptrvalue) != NULL
15713         && uop->type != NULL
15714         && StringICmp (uop->type->str, "DBLink") == 0) {
15715       for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
15716         if (ufp->label != NULL) {
15717           if (StringICmp (ufp->label->str, "BioProject") == 0) {
15718             wiz->bioproject = MemFree (wiz->bioproject);
15719             wiz->bioproject = StringFromUserField(ufp);
15720           } else if (StringICmp (ufp->label->str, "BioSample") == 0) {
15721             wiz->biosample = MemFree (wiz->biosample);
15722             wiz->biosample = StringFromUserField(ufp);
15723           } else if (StringICmp (ufp->label->str, "Sequence Read Archive") == 0) {
15724             wiz->srr = MemFree (wiz->srr);
15725             wiz->srr = StringFromUserField(ufp);
15726           }
15727         }
15728       }
15729       if (s_prev == NULL) {
15730         globalsbp->descriptors = s_next;
15731       } else {
15732         s_prev->next = s_next;
15733       }
15734       sdp->next = NULL;
15735       sdp = SeqDescFree (sdp);
15736     } else {
15737       s_prev = sdp;
15738     }
15739   }
15740 }
15741 
15742 
WizardTrackerNew(EWizardType wizard_type,SeqEntryPtr sequences)15743 static WizardTrackerPtr WizardTrackerNew (EWizardType wizard_type, SeqEntryPtr sequences)
15744 {
15745   WizardTrackerPtr wiz;
15746 
15747   wiz = (WizardTrackerPtr) MemNew (sizeof (WizardTrackerData));
15748   wiz->wizard_type = wizard_type;
15749   wiz->sequences = sequences;
15750   wiz->set_class = BioseqseqSet_class_genbank;
15751   wiz->base_src_quals = NULL;
15752   wiz->extra_src_quals = NULL;
15753   wiz->virus_class = eVirusClass_Unknown;
15754   if (wiz->wizard_type == eWizardType_WGS) {
15755     wiz->molinfo = MolInfoNew ();
15756     wiz->molinfo->biomol = MOLECULE_TYPE_GENOMIC;
15757     wiz->molinfo->tech = MI_TECH_wgs;
15758   } else {
15759     wiz->molinfo = NULL;
15760   }
15761   wiz->mol_class = Seq_mol_dna;
15762   wiz->molinfo_comment = NULL;
15763   wiz->topology = TOPOLOGY_LINEAR;
15764   ResetWizardTrackerVirusFeat (wiz);
15765   wiz->cultured_kingdom = eCulturedKingdom_Unknown;
15766   wiz->genome = GENOME_unknown;
15767   wiz->cultured_feat = eCulturedFeat_None;
15768   wiz->breadcrumbs = NULL;
15769   wiz->comment = NULL;
15770   wiz->cds_comment = NULL;
15771   wiz->prot_desc = NULL;
15772   wiz->use_minus_strand = FALSE;
15773   wiz->misc_feat_comment = NULL;
15774   wiz->gene_name = NULL;
15775   wiz->rna_name = NULL;
15776   wiz->prot_name = NULL;
15777   wiz->annot_list = NULL;
15778   wiz->chimera_program = NULL;
15779   wiz->chimera_version = NULL;
15780   wiz->spans_unknown = FALSE;
15781   wiz->structured_comments = NULL;
15782   wiz->bioproject = NULL;
15783   wiz->biosample = NULL;
15784   wiz->srr = NULL;
15785   wiz->assembled_choice = 0;
15786   wiz->is_fasta = TRUE;
15787   wiz->aln_settings = GetDefaultSequenceInfo();
15788   wiz->use_alternate_leaving_msg = FALSE;
15789   wiz->show_feature_table_help = FALSE;
15790   wiz->add_span_note = FALSE;
15791   wiz->wgs_source_type = eWGSSourceType_Unknown;
15792   wiz->wgs_ns_msg = NULL;
15793   wiz->uniqueness_list = NULL;
15794   wiz->quit_now = FALSE;
15795   if (wiz->wizard_type == eWizardType_Microsatellite) {
15796     wiz->min_seq_length = 50;
15797     wiz->recommended_seq_length = 50;
15798   } else {
15799     wiz->min_seq_length = 50;
15800     wiz->recommended_seq_length = 200;
15801   }
15802   DescriptorsToWizard (wiz);
15803   return wiz;
15804 }
15805 
15806 
WizardTrackerFree(WizardTrackerPtr wiz)15807 static WizardTrackerPtr WizardTrackerFree (WizardTrackerPtr wiz)
15808 {
15809   SeqEntryPtr sep, sep_next;
15810 
15811   if (wiz != NULL) {
15812     sep = wiz->sequences;
15813     wiz->sequences = NULL;
15814     while (sep != NULL) {
15815       sep_next = sep->next;
15816       sep->next = NULL;
15817       sep = SeqEntryFree (sep);
15818     }
15819     wiz->base_src_quals = ValNodeFreeData (wiz->base_src_quals);
15820     wiz->extra_src_quals = ValNodeFreeData (wiz->extra_src_quals);
15821     wiz->molinfo = MolInfoFree (wiz->molinfo);
15822     wiz->molinfo_comment = MemFree (wiz->molinfo_comment);
15823     wiz->breadcrumbs = ValNodeFree (wiz->breadcrumbs);
15824     wiz->comment = MemFree (wiz->comment);
15825     wiz->cds_comment = MemFree (wiz->cds_comment);
15826     wiz->prot_desc = MemFree (wiz->prot_desc);
15827     wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
15828     wiz->gene_name = MemFree (wiz->gene_name);
15829     wiz->rna_name = MemFree (wiz->rna_name);
15830     wiz->prot_name = MemFree (wiz->prot_name);
15831     wiz->annot_list = FreeAnnotList(wiz->annot_list);
15832     wiz->feat_qual_table = FreeTabTable (wiz->feat_qual_table);
15833     wiz->chimera_program = MemFree (wiz->chimera_program);
15834     wiz->chimera_version = MemFree (wiz->chimera_version);
15835     wiz->structured_comments = UserObjectListFree (wiz->structured_comments);
15836     wiz->bioproject = MemFree (wiz->bioproject);
15837     wiz->biosample = MemFree (wiz->biosample);
15838     wiz->srr = MemFree (wiz->srr);
15839     wiz->wgs_ns_msg = MemFree (wiz->wgs_ns_msg);
15840     wiz->uniqueness_list = UniquenessListFree (wiz->uniqueness_list);
15841     SequenceInfoFree (wiz->aln_settings);
15842     wiz = MemFree (wiz);
15843   }
15844   return wiz;
15845 }
15846 
15847 
AddRNAFromWizard(CharPtr rna_txt,WizardTrackerPtr wiz,SeqEntryPtr sep)15848 static void AddRNAFromWizard (CharPtr rna_txt, WizardTrackerPtr wiz, SeqEntryPtr sep)
15849 {
15850   BioseqPtr  bsp;
15851   SeqFeatPtr sfp;
15852   RnaRefPtr  rrp;
15853 
15854   bsp = FindNucBioseq (sep);
15855   sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_RNA, NULL);
15856   rrp = RnaRefNew ();
15857   sfp->data.value.ptrvalue = rrp;
15858   if (IsrRNAName(rna_txt)) {
15859     rrp->type = RNA_TYPE_rRNA;
15860     SetRNAProductString (sfp, NULL, rna_txt, ExistingTextOption_replace_old);
15861   } else if (IsRNASpacer (rna_txt)) {
15862     rrp->type = RNA_TYPE_other;
15863     SetRNAProductString (sfp, NULL, rna_txt, ExistingTextOption_replace_old);
15864   } else {
15865     rrp->type = RNA_TYPE_other;
15866     sfp->comment = StringSave (rna_txt);
15867   }
15868   SetSeqLocPartial (sfp->location, wiz->partial5, wiz->partial3);
15869 }
15870 
15871 
AddCodingRegionFromWizard(CharPtr prot,WizardTrackerPtr wiz,SeqEntryPtr sep)15872 static void AddCodingRegionFromWizard (CharPtr prot, WizardTrackerPtr wiz, SeqEntryPtr sep)
15873 {
15874   Int2               genCode;
15875   CdRegionPtr        crp;
15876   SeqFeatPtr         sfp, prot_sfp;
15877   ByteStorePtr       bs;
15878   CharPtr            prot_seq, ptr;
15879   Char               ch;
15880   BioseqPtr          bsp, prot_bsp;
15881   SeqEntryPtr        old, psep, nsep;
15882   MolInfoPtr         mip;
15883   ValNodePtr         vnp, descr;
15884   Int2               i;
15885   ProtRefPtr         prp;
15886 
15887   /*Create a new CDS feature */
15888 
15889   genCode = SeqEntryToGeneticCode (sep, NULL, NULL, 0);
15890   crp = CreateNewCdRgn (1, FALSE, genCode);
15891   if (NULL == crp)
15892     return;
15893 
15894   bsp = FindNucBioseq (sep);
15895   sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_CDREGION, NULL);
15896 
15897   if (NULL == sfp)
15898     return;
15899 
15900   sfp->data.value.ptrvalue = (Pointer) crp;
15901 
15902   SetSeqLocPartial (sfp->location, wiz->partial5, wiz->partial3);
15903   if (wiz->use_minus_strand) {
15904     SetSeqLocStrand (sfp->location, Seq_strand_minus);
15905   }
15906 
15907   if (!StringHasNoText(wiz->cds_comment)) {
15908     sfp->comment = StringSave(wiz->cds_comment);
15909   }
15910   SetBestFrameByLocation (sfp);
15911 
15912   /* Create corresponding protein sequence data for the CDS */
15913   bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
15914   if (NULL == bs)
15915     return;
15916 
15917   prot_seq = BSMerge (bs, NULL);
15918   bs = BSFree (bs);
15919   if (NULL == prot_seq)
15920     return;
15921 
15922   ptr = prot_seq;
15923   ch = *ptr;
15924   while (ch != '\0') {
15925     *ptr = TO_UPPER (ch);
15926     ptr++;
15927     ch = *ptr;
15928   }
15929   i = (Int2) StringLen (prot_seq);
15930   if (i > 0 && prot_seq [i - 1] == '*') {
15931     prot_seq [i - 1] = '\0';
15932   }
15933   bs = BSNew (1000);
15934   if (bs != NULL) {
15935     BSWrite (bs, (VoidPtr) prot_seq, (Int4) StringLen (prot_seq));
15936   }
15937 
15938   /* Create the product protein Bioseq */
15939 
15940   prot_bsp = BioseqNew ();
15941   if (NULL == prot_bsp)
15942     return;
15943 
15944   prot_bsp->repr = Seq_repr_raw;
15945   prot_bsp->mol = Seq_mol_aa;
15946   prot_bsp->seq_data_type = Seq_code_ncbieaa;
15947   prot_bsp->seq_data = (SeqDataPtr) bs;
15948   prot_bsp->length = BSLen (bs);
15949   bs = NULL;
15950   old = SeqEntrySetScope (sep);
15951   prot_bsp->id = MakeNewProteinSeqId (sfp->location, NULL);
15952   SeqMgrAddToBioseqIndex (prot_bsp);
15953   SeqEntrySetScope (old);
15954 
15955   /* Create a new SeqEntry for the Prot Bioseq */
15956 
15957   psep = SeqEntryNew ();
15958   if (NULL == psep)
15959     return;
15960 
15961   psep->choice = 1;
15962   psep->data.ptrvalue = (Pointer) prot_bsp;
15963   SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) prot_bsp, psep);
15964 
15965   /* Add a descriptor to the protein Bioseq */
15966 
15967   mip = MolInfoNew ();
15968   if (NULL == mip)
15969     return;
15970 
15971   mip->biomol = 8;
15972   mip->tech = 8;
15973 
15974   if (wiz->partial5 && wiz->partial3) {
15975     mip->completeness = 5;
15976   } else if (wiz->partial5) {
15977     mip->completeness = 3;
15978   } else if (wiz->partial3) {
15979     mip->completeness = 4;
15980   }
15981 
15982   vnp = CreateNewDescriptor (psep, Seq_descr_molinfo);
15983   if (NULL == vnp)
15984     return;
15985 
15986   vnp->data.ptrvalue = (Pointer) mip;
15987 
15988   descr = ExtractBioSourceAndPubs (sep);
15989 
15990   AddSeqEntryToSeqEntry (sep, psep, TRUE);
15991   nsep = FindNucSeqEntry (sep);
15992   ReplaceBioSourceAndPubs (sep, descr);
15993   SetSeqFeatProduct (sfp, prot_bsp);
15994 
15995   /* create a full-length protein feature for the new protein sequence */
15996   prp = CreateNewProtRef (prot, wiz->prot_desc, NULL, NULL);
15997 
15998   if (prp != NULL) {
15999     prot_sfp = CreateNewFeature (psep, NULL, SEQFEAT_PROT, NULL);
16000     if (prot_sfp != NULL) {
16001       prot_sfp->data.value.ptrvalue = (Pointer) prp;
16002       SetSeqLocPartial (prot_sfp->location, wiz->partial5, wiz->partial3);
16003       prot_sfp->partial = (wiz->partial5 || wiz->partial3);
16004     }
16005   }
16006 
16007   /* after the feature has been created, then adjust it for gaps */
16008   /* Note - this step may result in multiple coding regions being created. */
16009   AdjustCDSLocationsForUnknownGapsCallback (sfp, NULL);
16010 
16011 }
16012 
16013 
AddGeneFromWizard(CharPtr gene,WizardTrackerPtr wiz,SeqEntryPtr sep)16014 static void AddGeneFromWizard (CharPtr gene, WizardTrackerPtr wiz, SeqEntryPtr sep)
16015 {
16016   BioseqPtr  bsp;
16017   SeqFeatPtr sfp;
16018   GeneRefPtr grp;
16019 
16020   bsp = FindNucBioseq (sep);
16021   sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_GENE, NULL);
16022   grp = GeneRefNew ();
16023   grp->locus = StringSave (gene);
16024   sfp->data.value.ptrvalue = grp;
16025 
16026   SetSeqLocPartial (sfp->location, wiz->partial5, wiz->partial3);
16027   if (wiz->use_minus_strand) {
16028     SetSeqLocStrand (sfp->location, Seq_strand_minus);
16029   }
16030 }
16031 
16032 
FinishOneSeqEntry(SeqEntryPtr list,WizardTrackerPtr wiz)16033 static void FinishOneSeqEntry (SeqEntryPtr list, WizardTrackerPtr wiz)
16034 {
16035   SeqDescPtr   sdp;
16036   MolInfoPtr   mip;
16037 
16038   ProcessOneNucleotideTitle (globalFormatBlock.seqPackage, list, list);
16039   sdp = SeqEntryGetSeqDescr (list, Seq_descr_molinfo, NULL);
16040   if (sdp == NULL)
16041   {
16042     sdp = CreateNewDescriptor (list, Seq_descr_molinfo);
16043   }
16044   if (sdp != NULL)
16045   {
16046     mip = (MolInfoPtr) sdp->data.ptrvalue;
16047     if (mip == NULL)
16048     {
16049       mip = MolInfoNew ();
16050       sdp->data.ptrvalue = mip;
16051     }
16052   }
16053 
16054   /* add mRNA if requested */
16055   if (!StringHasNoText (wiz->rna_name)) {
16056     AddRNAFromWizard(wiz->rna_name, wiz, list);
16057   }
16058 
16059   /* add coding region if requested */
16060   if (!StringHasNoText (wiz->prot_name)) {
16061     AddCodingRegionFromWizard (wiz->prot_name, wiz, list);
16062   }
16063 
16064   /* add gene if requested */
16065   if (!StringHasNoText (wiz->gene_name)) {
16066     AddGeneFromWizard (wiz->gene_name, wiz, list);
16067   }
16068 
16069   /* add chimera program comment */
16070   if (!StringHasNoText (wiz->chimera_program) && StringCmp (wiz->chimera_program, "none") != 0) {
16071     AddChimeraComment (list, wiz->chimera_program, wiz->chimera_version);
16072   }
16073 
16074 }
16075 
16076 
IsGelBand(CharPtr val)16077 static Boolean IsGelBand (CharPtr val)
16078 {
16079   if (StringLen (val) < 6) {
16080     return FALSE;
16081   } else if (StringNICmp (val, "DGGE", 4) == 0 || StringNICmp (val, "TGGE", 4) == 0) {
16082     return TRUE;
16083   } else {
16084     return FALSE;
16085   }
16086 }
16087 
16088 
PreferentiallyAddWizardSrcQual(CharPtr choice1,CharPtr name1,CharPtr choice2,CharPtr name2,WizardTrackerPtr wiz,IDAndTitleEditPtr iatep)16089 static void PreferentiallyAddWizardSrcQual (CharPtr choice1, CharPtr name1, CharPtr choice2, CharPtr name2, WizardTrackerPtr wiz, IDAndTitleEditPtr iatep)
16090 {
16091   if (DoAnySequencesHaveModifierEx(iatep, choice1, NULL)) {
16092     ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNew (name1, eWizardEditQual_CopyFromId, TRUE, TRUE));
16093   } else if (DoAnySequencesHaveModifierEx(iatep, choice2, NULL)) {
16094     ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNew (name2, eWizardEditQual_CopyFromId, TRUE, TRUE));
16095   } else {
16096     ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNew (name1, eWizardEditQual_CopyFromId, TRUE, TRUE));
16097   }
16098 }
16099 
16100 
SetWizardSrcQualExample(CharPtr name,CharPtr example,WizardTrackerPtr wiz)16101 static void SetWizardSrcQualExample (CharPtr name, CharPtr example, WizardTrackerPtr wiz)
16102 {
16103   ValNodePtr vnp;
16104   WizardSrcQualPtr q;
16105 
16106   if (StringHasNoText (name) || wiz == NULL) {
16107     return;
16108   }
16109 
16110   for (vnp = wiz->base_src_quals; vnp != NULL; vnp = vnp->next) {
16111     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && StringICmp (q->name, name) == 0) {
16112       q->example = example;
16113     }
16114   }
16115 }
16116 
16117 
SetAllSrcQualsProblemWhenMissing(ValNodePtr qual_list,Boolean problem_when_missing)16118 static void SetAllSrcQualsProblemWhenMissing (ValNodePtr qual_list, Boolean problem_when_missing)
16119 {
16120   ValNodePtr vnp;
16121   WizardSrcQualPtr q;
16122 
16123   for (vnp = qual_list; vnp != NULL; vnp = vnp->next) {
16124     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && !q->required) {
16125       q->problem_when_missing = problem_when_missing;
16126     }
16127   }
16128 }
16129 
16130 
SetWizardTrackerBaseSrcQuals(WizardTrackerPtr wiz,IDAndTitleEditPtr iatep)16131 static void SetWizardTrackerBaseSrcQuals (WizardTrackerPtr wiz, IDAndTitleEditPtr iatep)
16132 {
16133   WizardSrcQualPtr wq;
16134 
16135   if (wiz == NULL) {
16136     return;
16137   }
16138   wiz->base_src_quals = ValNodeFreeData (wiz->base_src_quals);
16139 
16140   switch (wiz->wizard_type) {
16141     case eWizardType_UnculturedSamples:
16142       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Organism", eWizardEditQual_ApplyAll, TRUE, TRUE, NULL, FALSE, "uncultured bacterium"));
16143       if (DoAnySequencesHaveModifierEx(iatep, "isolate", IsGelBand)) {
16144         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNew ("Isolate", eWizardEditQual_CopyFromId, TRUE, TRUE));
16145       } else {
16146         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Clone", eWizardEditQual_CopyFromId, TRUE, TRUE, NULL, FALSE, "abc-1"));
16147       }
16148       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Isolation-source", eWizardEditQual_ApplyAll, TRUE, TRUE, NULL, FALSE, "diseased leaf"));
16149       break;
16150     case eWizardType_Viruses:
16151       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNew ("Organism", eWizardEditQual_ApplyAll, TRUE, TRUE));
16152       if (wiz->virus_class == eVirusClass_Influenza) {
16153         PreferentiallyAddWizardSrcQual ("strain", "Strain", "isolate", "Isolate", wiz, iatep);
16154       } else {
16155         PreferentiallyAddWizardSrcQual ("isolate", "Isolate", "strain", "Strain", wiz, iatep);
16156       }
16157       switch (wiz->virus_class) {
16158         case eVirusClass_Generic:
16159           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Country", eWizardEditQual_ApplyAll, TRUE, TRUE, NotAllNumbers, FALSE, "Finland"));
16160           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Collection-date", eWizardEditQual_ApplyAll, TRUE, FALSE, DateIsAmbiguous, FALSE, "01-Jan-2011"));
16161           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Host", eWizardEditQual_ApplyAll, TRUE, FALSE, NotAllNumbers, FALSE, "Microtus arvalis"));
16162           SetWizardSrcQualExample("organism", "Tula virus", wiz);
16163           SetWizardSrcQualExample("isolate", "rdx-1a", wiz);
16164           break;
16165         case eVirusClass_FootAndMouth:
16166           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Serotype", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "O"));
16167           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Collection-date", eWizardEditQual_ApplyAll, TRUE, FALSE, DateIsAmbiguous, FALSE, "05-Nov-2007"));
16168           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Host", eWizardEditQual_ApplyAll, TRUE, FALSE, NotAllNumbers, FALSE, "Bos taurus"));
16169           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Country", eWizardEditQual_ApplyAll, TRUE, FALSE, NotAllNumbers, FALSE, "Iran"));
16170           SetWizardSrcQualExample("isolate", "IND19", wiz);
16171           break;
16172         case eVirusClass_Influenza:
16173           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Serotype", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "H1N1"));
16174           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Collection-date", eWizardEditQual_ApplyAll, TRUE, TRUE, DateIsAmbiguous, FALSE, "02-Feb-2011"));
16175           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Host", eWizardEditQual_ApplyAll, TRUE, FALSE, NotAllNumbers, FALSE, "Homo sapiens; male"));
16176           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Country", eWizardEditQual_ApplyAll, TRUE, FALSE, NotAllNumbers, FALSE, "Italy"));
16177           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("segment", eWizardEditQual_ApplyAll, TRUE, TRUE, NULL, FALSE, "4"));
16178           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Passage History", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "E1"));
16179           SetWizardSrcQualExample("organism", "Influenza A virus", wiz);
16180           SetWizardSrcQualExample("strain", "A/Milan/2a18/2011", wiz);
16181           SetWizardSrcQualExample("isolate", "A/Milan/2a18/2011", wiz);
16182           break;
16183         case eVirusClass_Caliciviridae:
16184           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Collection-date", eWizardEditQual_ApplyAll, TRUE, TRUE, DateIsAmbiguous, FALSE, "09-Jan-2003"));
16185           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Country", eWizardEditQual_ApplyAll, TRUE, TRUE, NotAllNumbers, FALSE, "Brazil"));
16186           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Host", eWizardEditQual_ApplyAll, TRUE, FALSE, NotAllNumbers, FALSE, "Homo sapiens"));
16187           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Genotype", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "G1"));
16188           SetWizardSrcQualExample("organism", "Norovirus", wiz);
16189           SetWizardSrcQualExample("isolate", "Hu/G1/T65/BRA/2003", wiz);
16190           break;
16191         case eVirusClass_Rotavirus:
16192           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Collection-date", eWizardEditQual_ApplyAll, TRUE, TRUE, DateIsAmbiguous, FALSE, "15-Jul-2008"));
16193           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Country", eWizardEditQual_ApplyAll, TRUE, TRUE, NotAllNumbers, FALSE, "USA: Idaho"));
16194           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Host", eWizardEditQual_ApplyAll, TRUE, FALSE, NotAllNumbers, FALSE, "Bos taurus"));
16195           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Genotype", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "G1"));
16196           SetWizardSrcQualExample("organism", "Rotavirus A", wiz);
16197           SetWizardSrcQualExample("isolate", "cow/C1/USA/2008/G1", wiz);
16198           break;
16199       }
16200       SetAllSrcQualsProblemWhenMissing (wiz->base_src_quals, TRUE);
16201       break;
16202     case eWizardType_CulturedSamples:
16203       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNew ("Organism", eWizardEditQual_ApplyAll, TRUE, TRUE));
16204       switch (wiz->cultured_kingdom) {
16205         case eCulturedKingdom_BacteriaArchea:
16206           PreferentiallyAddWizardSrcQual ("strain", "Strain", "isolate", "Isolate", wiz, iatep);
16207           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Isolation-source", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "leaf surface"));
16208           SetWizardSrcQualExample("organism", "Bacillus cereus", wiz);
16209           SetWizardSrcQualExample("strain", "EX-A1", wiz);
16210           break;
16211         case eCulturedKingdom_CulturedFungus:
16212           PreferentiallyAddWizardSrcQual ("strain", "Strain", "isolate", "Isolate", wiz, iatep);
16213           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Isolation-source", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "soil under elm tree"));
16214           SetWizardSrcQualExample("organism", "Morchella esculenta", wiz);
16215           SetWizardSrcQualExample("strain", "EX-A1", wiz);
16216           break;
16217         case eCulturedKingdom_VoucheredFungus:
16218           SetWizardSrcQualExample("organism", "Morchella esculenta", wiz);
16219           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Specimen-voucher", eWizardEditQual_CopyFromId, TRUE, TRUE, NULL, FALSE, "AMNH 000000"));
16220           break;
16221         case eCulturedKingdom_Other:
16222           wq = WizardSrcQualNewEx ("Isolate", eWizardEditQual_CopyFromId, TRUE, FALSE, NULL, FALSE, "EX-A");
16223           wq->problem_when_missing = TRUE;
16224           ValNodeAddPointer (&(wiz->base_src_quals), 0, wq);
16225           ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Isolation-source", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "lake shoreline"));
16226           SetWizardSrcQualExample("organism", "Taxodium distichum", wiz);
16227           break;
16228       }
16229       break;
16230     case eWizardType_IGS:
16231       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNew ("Organism", eWizardEditQual_ApplyAll, TRUE, TRUE));
16232       if (wiz->igs_source_type == eIGSSourceType_CulturedFungus) {
16233         PreferentiallyAddWizardSrcQual ("strain", "Strain", "isolate", "Isolate", wiz, iatep);
16234         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Isolation-source", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "soil under elm tree"));
16235         SetWizardSrcQualExample("organism", "Morchella esculenta", wiz);
16236         SetWizardSrcQualExample("strain", "EX-A1", wiz);
16237       } else if (wiz->igs_source_type == eIGSSourceType_VoucheredFungus) {
16238         SetWizardSrcQualExample("organism", "Morchella esculenta", wiz);
16239         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Specimen-voucher", eWizardEditQual_CopyFromId, TRUE, TRUE, NULL, FALSE, "AMNH 000000"));
16240       } else {
16241         wq = WizardSrcQualNewEx ("Isolate", eWizardEditQual_CopyFromId, TRUE, FALSE, NULL, FALSE, "EX-A");
16242         wq->problem_when_missing = TRUE;
16243         ValNodeAddPointer (&(wiz->base_src_quals), 0, wq);
16244         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Isolation-source", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "lake shoreline"));
16245         SetWizardSrcQualExample("organism", "Taxodium distichum", wiz);
16246       }
16247       break;
16248     case eWizardType_Microsatellite:
16249       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Organism", eWizardEditQual_ApplyAll, TRUE, TRUE, NULL, FALSE, "Coffea arabica"));
16250       break;
16251     case eWizardType_DLoop:
16252       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Organism", eWizardEditQual_ApplyAll, TRUE, TRUE, NULL, FALSE, "Coffea arabica"));
16253       break;
16254     case eWizardType_WGS:
16255       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Organism", eWizardEditQual_ApplyAll, TRUE, TRUE, NULL, FALSE, "Dictyostelium discoideum"));
16256       if (wiz->wgs_source_type == eWGSSourceType_Bacteria) {
16257         SetWizardSrcQualExample("organism", "Bacillus cereus ABC123", wiz);
16258         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Strain", eWizardEditQual_ApplyAll, TRUE, TRUE, NULL, FALSE, GetDefaultExample("Strain")));
16259         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Culture-collection", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "ATCC 12345"));
16260       } else if (wiz->wgs_source_type == eWGSSourceType_Fungi) {
16261         SetWizardSrcQualExample("organism", "Morchella esculenta", wiz);
16262         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Strain", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, GetDefaultExample("Strain")));
16263         ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Culture-collection", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, "CBS 123"));
16264       }
16265       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Host", eWizardEditQual_ApplyAll, TRUE, FALSE,
16266                          NULL, FALSE, GetDefaultExample("Host")));
16267       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Isolation-source", eWizardEditQual_ApplyAll, TRUE, FALSE,
16268                          NULL, FALSE,
16269                          wiz->wgs_source_type == eWGSSourceType_Bacteria ? "blood OR soil" : GetDefaultExample("Isolation-source")));
16270 
16271       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Collection-date", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, GetDefaultExample("Collection-date")));
16272       ValNodeAddPointer (&(wiz->base_src_quals), 0, WizardSrcQualNewEx ("Country", eWizardEditQual_ApplyAll, TRUE, FALSE, NULL, FALSE, GetDefaultExample("Country")));
16273       break;
16274   }
16275 }
16276 
16277 
AddOneExtraSrcQual(WizardTrackerPtr wiz,CharPtr name,EWizardEditQual edit_type,CharPtr example,IDAndTitleEditPtr iatep)16278 static WizardSrcQualPtr AddOneExtraSrcQual (WizardTrackerPtr wiz, CharPtr name, EWizardEditQual edit_type, CharPtr example, IDAndTitleEditPtr iatep)
16279 {
16280   ValNodePtr vnp;
16281   WizardSrcQualPtr q;
16282   Boolean found = FALSE;
16283 
16284   if (wiz == NULL || StringHasNoText (name)) {
16285     return NULL;
16286   }
16287   for (vnp = wiz->base_src_quals; vnp != NULL && !found; vnp = vnp->next) {
16288     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL
16289         && StringICmp (q->name, name) == 0) {
16290       q->example = example;
16291       found = TRUE;
16292     }
16293   }
16294 
16295   for (vnp = wiz->extra_src_quals; vnp != NULL && !found; vnp = vnp->next) {
16296     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL
16297         && StringICmp (q->name, name) == 0) {
16298       q->example = example;
16299       found = TRUE;
16300     }
16301   }
16302 
16303   if (!found) {
16304     q = WizardSrcQualNew(name, edit_type, FALSE, FALSE);
16305     q->example = example;
16306     vnp = ValNodeAddPointer (&(wiz->extra_src_quals), 0, q);
16307   }
16308   if (q != NULL && DoAnySequencesHaveModifier(iatep, name)) {
16309     q->show = TRUE;
16310   }
16311   return q;
16312 }
16313 
16314 
SetWizardTrackerExtraSrcQuals(WizardTrackerPtr wiz,IDAndTitleEditPtr iatep)16315 static void SetWizardTrackerExtraSrcQuals (WizardTrackerPtr wiz, IDAndTitleEditPtr iatep)
16316 {
16317   WizardSrcQualPtr q_isolate, q_hap, q_spec, q_name, q_seq;
16318   if (wiz == NULL) {
16319     return;
16320   }
16321   switch (wiz->wizard_type) {
16322     case eWizardType_UnculturedSamples:
16323       AddOneExtraSrcQual (wiz, "host", eWizardEditQual_ApplyAll, NULL, iatep);
16324       SetWizardSrcQualExample ("host", "Cocos nucifera", wiz);
16325       break;
16326     case eWizardType_Viruses:
16327       /* depends on virus type */
16328       switch (wiz->virus_class) {
16329         case eVirusClass_Generic:
16330           AddOneExtraSrcQual (wiz, "isolation-source", eWizardEditQual_ApplyAll, "feces", iatep);
16331           AddOneExtraSrcQual (wiz, "serotype", eWizardEditQual_ApplyAll, "Ex1", iatep);
16332           AddOneExtraSrcQual (wiz, "genotype", eWizardEditQual_ApplyAll, "D9", iatep);
16333           AddOneExtraSrcQual (wiz, "segment", eWizardEditQual_ApplyAll, "10", iatep);
16334           break;
16335         case eVirusClass_FootAndMouth:
16336           AddOneExtraSrcQual (wiz, "genotype", eWizardEditQual_ApplyAll, "VII", iatep);
16337           AddOneExtraSrcQual (wiz, "isolation-source", eWizardEditQual_ApplyAll, "skin", iatep);
16338           break;
16339         case eVirusClass_Influenza:
16340           AddOneExtraSrcQual (wiz, "isolation-source", eWizardEditQual_ApplyAll, "nasal swab", iatep);
16341           break;
16342         case eVirusClass_Caliciviridae:
16343           AddOneExtraSrcQual (wiz, "isolation-source", eWizardEditQual_ApplyAll, "feces", iatep);
16344           AddOneExtraSrcQual (wiz, "serotype", eWizardEditQual_ApplyAll, "1", iatep);
16345           break;
16346         case eVirusClass_Rotavirus:
16347           AddOneExtraSrcQual (wiz, "serotype", eWizardEditQual_ApplyAll, "Ex2a", iatep);
16348           AddOneExtraSrcQual (wiz, "isolation-source", eWizardEditQual_ApplyAll, "feces", iatep);
16349           AddOneExtraSrcQual (wiz, "segment", eWizardEditQual_ApplyAll, "10", iatep);
16350           break;
16351       }
16352       break;
16353     case eWizardType_CulturedSamples:
16354       switch (wiz->cultured_kingdom) {
16355         case eCulturedKingdom_BacteriaArchea:
16356           AddOneExtraSrcQual (wiz, "host", eWizardEditQual_ApplyAll, "Nepenthes sp.", iatep);
16357           AddOneExtraSrcQual (wiz, "collection-date", eWizardEditQual_ApplyAll, "05-Feb-2005", iatep);
16358           AddOneExtraSrcQual (wiz, "lat-lon", eWizardEditQual_ApplyAll, "1.05 N 114.12 E", iatep);
16359           break;
16360         case eCulturedKingdom_CulturedFungus:
16361           AddOneExtraSrcQual (wiz, "host", eWizardEditQual_ApplyAll, "Ulmus sp.", iatep);
16362           AddOneExtraSrcQual (wiz, "collection-date", eWizardEditQual_ApplyAll, "05-Feb-2005", iatep);
16363           AddOneExtraSrcQual (wiz, "lat-lon", eWizardEditQual_ApplyAll, "47.22 N 92.18 W", iatep);
16364           break;
16365         case eCulturedKingdom_VoucheredFungus:
16366           AddOneExtraSrcQual (wiz, "host", eWizardEditQual_ApplyAll, "Ulmus sp.", iatep);
16367           AddOneExtraSrcQual (wiz, "collection-date", eWizardEditQual_ApplyAll, "05-Feb-2005", iatep);
16368           AddOneExtraSrcQual (wiz, "lat-lon", eWizardEditQual_ApplyAll, "47.22 N 92.18 W", iatep);
16369           AddOneExtraSrcQual (wiz, "isolate", eWizardEditQual_ApplyAll, "xyz1a", iatep);
16370           AddOneExtraSrcQual (wiz, "biomaterial", eWizardEditQual_CopyFromId, "", iatep);
16371           AddOneExtraSrcQual (wiz, "culture-collection", eWizardEditQual_CopyFromId, "", iatep);
16372           break;
16373         case eCulturedKingdom_Other:
16374           AddOneExtraSrcQual (wiz, "collection-date", eWizardEditQual_ApplyAll, "05-Feb-2005", iatep);
16375           AddOneExtraSrcQual (wiz, "lat-lon", eWizardEditQual_ApplyAll, "31.37 S 51.95 W", iatep);
16376           break;
16377       }
16378       break;
16379     case eWizardType_IGS:
16380       if (wiz->igs_source_type == eIGSSourceType_CulturedFungus) {
16381         AddOneExtraSrcQual (wiz, "host", eWizardEditQual_ApplyAll, "Ulmus sp.", iatep);
16382         AddOneExtraSrcQual (wiz, "collection-date", eWizardEditQual_ApplyAll, "05-Feb-2005", iatep);
16383         AddOneExtraSrcQual (wiz, "lat-lon", eWizardEditQual_ApplyAll, "47.22 N 92.18 W", iatep);
16384         AddOneExtraSrcQual (wiz, "isolate", eWizardEditQual_CopyFromId, "EX-A", iatep);
16385       } else if (wiz->igs_source_type == eIGSSourceType_VoucheredFungus) {
16386         AddOneExtraSrcQual (wiz, "host", eWizardEditQual_ApplyAll, "Ulmus sp.", iatep);
16387         AddOneExtraSrcQual (wiz, "collection-date", eWizardEditQual_ApplyAll, "05-Feb-2005", iatep);
16388         AddOneExtraSrcQual (wiz, "lat-lon", eWizardEditQual_ApplyAll, "47.22 N 92.18 W", iatep);
16389         AddOneExtraSrcQual (wiz, "isolate", eWizardEditQual_ApplyAll, "xyz1a", iatep);
16390         AddOneExtraSrcQual (wiz, "biomaterial", eWizardEditQual_CopyFromId, "", iatep);
16391         AddOneExtraSrcQual (wiz, "culture-collection", eWizardEditQual_CopyFromId, "", iatep);
16392       } else {
16393         AddOneExtraSrcQual (wiz, "collection-date", eWizardEditQual_ApplyAll, "05-Feb-2005", iatep);
16394         AddOneExtraSrcQual (wiz, "lat-lon", eWizardEditQual_ApplyAll, "31.37 S 51.95 W", iatep);
16395         AddOneExtraSrcQual (wiz, "specimen-voucher", eWizardEditQual_None, "AMNH 000000", iatep);
16396         AddOneExtraSrcQual (wiz, "biomaterial", eWizardEditQual_CopyFromId, "", iatep);
16397         AddOneExtraSrcQual (wiz, "culture-collection", eWizardEditQual_CopyFromId, "", iatep);
16398       }
16399       break;
16400     case eWizardType_Microsatellite:
16401       AddOneExtraSrcQual (wiz, "clone", eWizardEditQual_CopyFromId, "Ca-789", iatep);
16402       q_name = AddOneExtraSrcQual (wiz, "Fwd-PCR-primer-name", eWizardEditQual_ApplyAll, "ex1a-f", iatep);
16403       q_name->add_name = "PCR primer names";
16404       q_name->problem_when_missing = TRUE;
16405       q_name = AddOneExtraSrcQual (wiz, "Rev-PCR-primer-name", eWizardEditQual_ApplyAll, "ex1a-r", iatep);
16406       q_name->linked = "Fwd-PCR-primer-name";
16407       q_name->problem_when_missing = TRUE;
16408       q_seq = AddOneExtraSrcQual (wiz, "Fwd-PCR-primer-seq", eWizardEditQual_ApplyAll, "ATGCATGCATGC", iatep);
16409       q_seq->add_name = "PCR primer sequences";
16410       q_name->problem_when_missing = TRUE;
16411       q_seq = AddOneExtraSrcQual (wiz, "Rev-PCR-primer-seq", eWizardEditQual_ApplyAll, "GATCGATCGATC", iatep);
16412       q_seq->linked = "Fwd-PCR-primer-seq";
16413       q_name->problem_when_missing = TRUE;
16414       break;
16415     case eWizardType_DLoop:
16416       q_isolate = AddOneExtraSrcQual (wiz, "isolate", eWizardEditQual_CopyFromId, "xyz1a", iatep);
16417       q_hap = AddOneExtraSrcQual (wiz, "haplotype", eWizardEditQual_CopyFromId, "A1", iatep);
16418       q_spec = AddOneExtraSrcQual (wiz, "specimen-voucher", eWizardEditQual_CopyFromId, "A1", iatep);
16419       if (q_isolate->show) {
16420         q_hap->edit_type = eWizardEditQual_None;
16421         q_spec->edit_type = eWizardEditQual_None;
16422       } else if (q_hap->show) {
16423         q_isolate->edit_type = eWizardEditQual_None;
16424         q_spec->edit_type = eWizardEditQual_None;
16425       } else if (q_spec->show) {
16426         q_isolate->edit_type = eWizardEditQual_None;
16427         q_hap->edit_type = eWizardEditQual_None;
16428       }
16429       AddOneExtraSrcQual (wiz, "breed", eWizardEditQual_ApplyAll, NULL, iatep);
16430       AddOneExtraSrcQual (wiz, "cultivar", eWizardEditQual_ApplyAll, NULL, iatep);
16431       break;
16432     case eWizardType_WGS:
16433       if (wiz->wgs_source_type != eWGSSourceType_Bacteria) {
16434         AddOneExtraSrcQual (wiz, "strain", eWizardEditQual_ApplyAll, GetDefaultExample("strain"), iatep);
16435         AddOneExtraSrcQual (wiz, "specimen-voucher", eWizardEditQual_ApplyAll, GetDefaultExample("specimen-voucher"), iatep);
16436         AddOneExtraSrcQual (wiz, "isolate", eWizardEditQual_ApplyAll, GetDefaultExample("isolate"), iatep);
16437       }
16438       if (wiz->wgs_source_type == eWGSSourceType_OtherEuk) {
16439         AddOneExtraSrcQual (wiz, "sex", eWizardEditQual_ApplyAll, GetDefaultExample("sex"), iatep);
16440         AddOneExtraSrcQual (wiz, "breed", eWizardEditQual_ApplyAll, GetDefaultExample("breed"), iatep);
16441         AddOneExtraSrcQual (wiz, "cultivar", eWizardEditQual_ApplyAll, GetDefaultExample("cultivar"), iatep);
16442       }
16443       AddOneExtraSrcQual (wiz, "lat-lon", eWizardEditQual_ApplyAll, GetDefaultExample("lat-lon"), iatep);
16444       break;
16445   }
16446 }
16447 
16448 
16449 static CharPtr s_WizardVirusFeatureTableHelpMsgs[] = {
16450 "Options for Adding Feature Annotation in the Record Viewer:\n\
16451 -----------------------------------------------------------\n\
16452 \n\
16453 [1] Any single feature can be added using the lists in the Annotate Menu in the\n\
16454 record viewer, see: \n\
16455 ",
16456 "http://www.ncbi.nlm.nih.gov/Sequin/sequin.hlp.html#Features\n",
16457 "\
16458 [2] For a set or batch of sequences, the same feature can be added across the \n\
16459 entire span of each sequence by using the Batch Feature option under the Annotate\n\
16460 Menu in the record viewer. The feature must span the entire nucleotide sequence \n\
16461 of each record, you can not annotate specific nucleotide locations using this \n\
16462 option.  \n\
16463 \n\
16464 [3] Use a 5-column, tab-delimited feature table to annotate your sequences:\n\
16465 - Features tables for Influenza A and B sequences can be\n\
16466   created here:\n\
16467 ",
16468 "http://www.ncbi.nlm.nih.gov/genomes/FLU/Database/annotation.cgi\n",
16469 "\
16470 - The feature table must be a plain text file. \n\
16471 \n\
16472 - The header line begins with >Feature lcl| \n\
16473 \n\
16474 - The text following \"lcl|\" must contain the sequence ID of the sequences in your records.\n\
16475   For example: >Feature lcl|abc-1\n\
16476   In this example, abc-1 is the sequence ID. \n\
16477 \n\
16478 - The table is composed of 5, tab-separated columns:\n\
16479   Column 1- nucleotide position of the start of the feature\n\
16480   Column 2- nucleotide location of the end of a feature\n\
16481   Column 3- feature type (gene, CDS, etc.)\n\
16482   Column 4- feature qualifier (note, product, etc.)\n\
16483   Column 5- qualifier value (for example: gag protein)\n\
16484 \n\
16485 - The columns in the table MUST be separated by tabs. \n\
16486   Use the Tab key on your keyboard to separate each column.\n\
16487   The qualifiers follow on lines starting with three tabs. \n\
16488 \n\
16489 - For more feature table format information: \n\
16490 ",
16491 "http://www.ncbi.nlm.nih.gov/Sequin/table.html#Table Layout\n",
16492 "\
16493 - Questions about the feature table format? Write to: info@ncbi.nlm.nih.gov\n\
16494 ",
16495 "\
16496 --------------------------------------------------\n\
16497 How to load a feature table in the record viewer:\n\
16498 --------------------------------------------------\n\
16499 File-->Open menu item\n\
16500 \n\
16501 --------------------------------------------------\n\
16502 Example feature table for 2 sequences:\n\
16503 --------------------------------------------------\n\
16504 >Feature lcl|abc-1\n\
16505 24	1458	gene\n\
16506 			gene	PB2\n\
16507 24	1458	CDS\n\
16508 			product	polymerase PB2\n\
16509 >Feature lcl|abc-2\n\
16510 4	985	gene\n\
16511 			gene	M2\n\
16512 4	29	CDS\n\
16513 718	985\n\
16514 			product	matrix protein 2\n\
16515 4	762	gene\n\
16516 			gene	M1\n\
16517 4	762	CDS\n\
16518       product	matrix protein 1\
16519 \n\
16520 ", NULL};
16521 
16522 
16523 static CharPtr s_WizardIGSFeatureTableHelpMsgs[] = {
16524 "\
16525 Feature Table Format:\n\
16526 ---------------------\n\
16527 -The header line begins with >Feature lcl| \n\
16528 \n\
16529 -The text following \"lcl|\" must contain the sequence ID of the sequences in your records.\n\
16530  For example: >Feature lcl|abc-1\n\
16531  In this example, abc-1 is the sequence ID.  \n\
16532 \n\
16533 -The table is composed of five, tab-separated columns:\n\
16534 ",
16535 "\
16536   1- nucleotide position of the start of the feature\n\
16537   2- nucleotide location of the end of a feature\n\
16538   3- feature type (tRNA, CDS, etc.)\n\
16539   4- feature qualifier (product, note, etc.)\n\
16540   5- qualifier value (for example: tRNA-Leu)\n\
16541 \n\
16542 -The columns in the table MUST be separated by tabs. \n\
16543  Use the Tab key on your keyboard to separate each column. \n\
16544  The qualifiers follow on lines starting with three tabs.\n\
16545 \n\
16546 ",
16547 "\
16548 -For more feature table format information: \n\
16549  http://www.ncbi.nlm.nih.gov/Sequin/table.html#Table Layout\n\
16550 \n\
16551 -Questions about the feature table format? Write to: info@ncbi.nlm.nih.gov\n\
16552 \n\
16553 \n\
16554 --------------------------------------------------\n\
16555 How to load a feature table in the record viewer:\n\
16556 --------------------------------------------------\n\
16557 File-->Open menu item\n\
16558 ",
16559 "\
16560 \n\
16561 ----------------------------------------------------------\n\
16562 Example feature table for 3 sequences of tRNA/IGS regions:\n\
16563 ----------------------------------------------------------\n\
16564 \n\
16565 >Feature lcl|abc-2\n\
16566 <1	50	gene\n\
16567 			gene	trnL\n\
16568 <1	50	tRNA\n\
16569 			product	tRNA-Leu\n\
16570 ",
16571 "\
16572 51	200	misc_feature\n\
16573 			note	trnL-trnF intergenic spacer\n\
16574 201	>250	gene\n\
16575 			gene	trnF\n\
16576 201	>250	tRNA\n\
16577 			product	tRNA-Phe\n\
16578 >Feature lcl|def-2\n\
16579 <1	50	gene\n\
16580 			gene	trnL\n\
16581 <1	50	tRNA\n\
16582 ",
16583 "\
16584 			product	tRNA-Leu\n\
16585 51	200	misc_feature\n\
16586 			note	trnL-trnF intergenic spacer\n\
16587 201	>250	gene\n\
16588 			gene	trnF\n\
16589 201	>250	tRNA\n\
16590 			product	tRNA-Phe\n\
16591 >Feature lcl|def-3\n\
16592 <1	50	gene\n\
16593 			gene	trnL\n\
16594 ",
16595 "\
16596 <1	50	tRNA\n\
16597 			product	tRNA-Leu\n\
16598 51	200	misc_feature\n\
16599 			note	trnL-trnF intergenic spacer\n\
16600 201	>250	gene\n\
16601 			gene	trnF\n\
16602 201	>250	tRNA\n\
16603 			product	tRNA-Phe\n\
16604 \n\
16605 ", NULL};
16606 
16607 static CharPtr s_WizardMicrosatelliteFeatureTableHelpMsgs[] = {
16608 "\
16609 Feature Table Format:\n\
16610 ---------------------\n\
16611 -The header line begins with >Feature lcl| \n\
16612 \n\
16613 -The text following \"lcl|\" must contain the sequence ID of the sequences in your records.\n\
16614  For example: >Feature lcl|abc-1\n\
16615  In this example, abc-1 is the sequence ID.  \n\
16616 \n\
16617 -The table is composed of five, tab-separated columns:\n\
16618 ",
16619 "\
16620   1- nucleotide position of the start of the feature\n\
16621   2- nucleotide location of the end of a feature\n\
16622   3- feature type (repeat-region, etc.)\n\
16623   4- feature qualifier (rpt_unit_seq, rpt_unit_range, etc.)\n\
16624   5- qualifier value (for example: ggtt)\n\
16625 \n\
16626 -The columns in the table MUST be separated by tabs. \n\
16627  Use the Tab key on your keyboard to separate each column. \n\
16628  The qualifiers follow on lines starting with three tabs.\n\
16629 \n\
16630 ",
16631 "\
16632 -For more feature table format information: \n\
16633  http://www.ncbi.nlm.nih.gov/Sequin/table.html#Table Layout\n\
16634 \n\
16635 -Questions about the feature table format? Write to: info@ncbi.nlm.nih.gov\n\
16636 \n\
16637 \n\
16638 --------------------------------------------------\n\
16639 How to load a feature table in the record viewer:\n\
16640 --------------------------------------------------\n\
16641 File-->Open menu item\n\
16642 ",
16643 "\
16644 \n\
16645 ----------------------------------------------------------\n\
16646 Example feature table for 3 sequences of microsatellite regions:\n\
16647 ----------------------------------------------------------\n\
16648 \n\
16649 >Feature lcl|abc-1\n\
16650 42\t100\trepeat_region\n\
16651 \t\t\trpt_type\ttandem\n\
16652 \t\t\trpt_unit_range\t42..45\n\
16653 \t\t\trpt_unit_seq\tggtt\n\
16654 ",
16655 "\
16656 \t\t\tsatellite\tmicrosatellite:Ca123\n\
16657 150\t200\trepeat_region\n\
16658 \t\t\trpt_type\ttandem\n\
16659 \t\t\trpt_unit_range\t150..154\n\
16660 \t\t\trpt_unit_seq\tgacct\n\
16661 \t\t\tsatellite\tmicrosatellite:Ca124\n\
16662 >Feature lcl|abc-2\n\
16663 75\t125\trepeat_region\n\
16664 \t\t\trpt_type\ttandem\n\
16665 \t\t\trpt_unit_range\t75..78\n\
16666 ",
16667 "\
16668 \t\t\trpt_unit_seq\tttaa\n\
16669 \t\t\tsatellite\tmicrosatellite:Ca125\n\
16670 \n\
16671 \t\t\t\n\
16672 ",
16673 NULL};
16674 
16675 
AddWizardFeatureCallback(BioseqPtr bsp,Pointer data)16676 static void AddWizardFeatureCallback (BioseqPtr bsp, Pointer data)
16677 {
16678   WizardTrackerPtr wiz;
16679   SeqFeatPtr sfp;
16680   ImpFeatPtr imp;
16681 
16682   wiz = (WizardTrackerPtr) data;
16683   if (wiz == NULL) {
16684     return;
16685   }
16686 
16687   switch (wiz->virus_feat) {
16688     case eVirusFeat_LTR:
16689       sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
16690       imp = ImpFeatNew ();
16691       imp->key = StringSave ("LTR");
16692       sfp->data.value.ptrvalue = imp;
16693       SetSeqLocPartial (sfp->location, wiz->partial5, wiz->partial3);
16694       sfp->partial = wiz->partial5 || wiz->partial3;
16695       break;
16696     case eVirusFeat_UTR5:
16697       sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
16698       imp = ImpFeatNew ();
16699       imp->key = StringSave ("5'UTR");
16700       sfp->data.value.ptrvalue = imp;
16701       SetSeqLocPartial (sfp->location, wiz->partial5, wiz->partial3);
16702       sfp->partial = wiz->partial5 || wiz->partial3;
16703       break;
16704     case eVirusFeat_UTR3:
16705       sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
16706       imp = ImpFeatNew ();
16707       imp->key = StringSave ("3'UTR");
16708       sfp->data.value.ptrvalue = imp;
16709       SetSeqLocPartial (sfp->location, wiz->partial5, wiz->partial3);
16710       sfp->partial = wiz->partial5 || wiz->partial3;
16711       break;
16712     case eVirusFeat_viroid_complete:
16713       sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
16714       imp = ImpFeatNew ();
16715       imp->key = StringSave ("misc_feature");
16716       sfp->data.value.ptrvalue = imp;
16717       sfp->comment = StringSave ("viroid complete genome");
16718       break;
16719     case eVirusFeat_viroid_partial:
16720       sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
16721       imp = ImpFeatNew ();
16722       imp->key = StringSave ("misc_feature");
16723       sfp->data.value.ptrvalue = imp;
16724       sfp->comment = StringSave ("viroid partial genome");
16725       break;
16726     case eVirusFeat_misc_feature:
16727       sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
16728       imp = ImpFeatNew ();
16729       imp->key = StringSave ("misc_feature");
16730       sfp->data.value.ptrvalue = imp;
16731       sfp->comment = StringSave (wiz->misc_feat_comment);
16732       break;
16733   }
16734 
16735   if ((wiz->wizard_type == eWizardType_IGS
16736        || wiz->wizard_type == eWizardType_UnculturedSamples
16737        || wiz->wizard_type == eWizardType_DLoop)
16738       && !StringHasNoText (wiz->misc_feat_comment)) {
16739     sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
16740     imp = ImpFeatNew ();
16741     if (StringICmp (wiz->misc_feat_comment, "D-loop") == 0) {
16742       imp->key = StringSave ("D-loop");
16743     } else {
16744       imp->key = StringSave ("misc_feature");
16745       sfp->comment = StringSave (wiz->misc_feat_comment);
16746     }
16747     sfp->data.value.ptrvalue = imp;
16748     SetSeqLocPartial (sfp->location, wiz->partial5, wiz->partial3);
16749     sfp->partial = (wiz->partial5 || wiz->partial3);
16750   }
16751 
16752 }
16753 
16754 
AddWizardAnnots(WizardTrackerPtr wiz,SeqEntryPtr input_sep)16755 static SeqEntryPtr AddWizardAnnots (WizardTrackerPtr wiz, SeqEntryPtr input_sep)
16756 {
16757   BioseqPtr   bsp;
16758   SeqAnnotPtr sap;
16759   SeqAnnotPtr anp;
16760   ValNodePtr  vnp;
16761   Uint2       entityID;
16762   SeqEntryPtr sep;
16763   Int2        genCode;
16764   SeqFeatPtr  sfp = NULL;
16765   Boolean     failure;
16766   SeqEntryPtr orig_scope;
16767 
16768   if (wiz == NULL || input_sep == NULL || wiz->annot_list == NULL) {
16769     return input_sep;
16770   }
16771 
16772   entityID = ObjMgrGetEntityIDForChoice (input_sep);
16773   orig_scope = SeqEntrySetScope (NULL);
16774   for (vnp = wiz->annot_list; vnp != NULL; vnp = vnp->next) {
16775       sap = (SeqAnnotPtr) vnp->data.ptrvalue;
16776     bsp = GetBioseqReferencedByAnnot (sap, entityID);
16777     sep = SeqMgrGetSeqEntryForData (bsp);
16778     if (bsp->annot == NULL) {
16779       bsp->annot = sap;
16780     } else {
16781       anp = bsp->annot;
16782       while (anp->next != NULL) {
16783         anp = anp->next;
16784       }
16785       anp->next = sap;
16786     }
16787     if (sap->type == 1) {
16788       sfp = (SeqFeatPtr) sap->data;
16789       genCode = GetGenCodeForBsp (bsp);
16790       SetEmptyGeneticCodes (sap, genCode);
16791       PromoteXrefsExEx (sfp, bsp, entityID, TRUE, FALSE, FALSE, FALSE, &failure);
16792     }
16793 
16794     /* correct all idx parent pointers */
16795 
16796     AssignIDsInEntity (entityID, 0, NULL);
16797   }
16798   /* note - we free the list here because the objects are now in use */
16799   wiz->annot_list = ValNodeFree (wiz->annot_list);
16800   sep = GetTopSeqEntryForEntityID (entityID);
16801   SeqEntrySetScope (orig_scope);
16802   return sep;
16803 }
16804 
16805 
AddWizardFeatures(WizardTrackerPtr wiz,SeqEntryPtr sep)16806 static SeqEntryPtr AddWizardFeatures (WizardTrackerPtr wiz, SeqEntryPtr sep)
16807 {
16808   if (wiz == NULL || sep == NULL) {
16809     return sep;
16810   }
16811 
16812   if (wiz->wizard_type == eWizardType_IGS && StringHasNoText (wiz->misc_feat_comment)) {
16813     ShowWizardHelpText ("Feature Table Help", s_WizardIGSFeatureTableHelpMsgs);
16814   } else if (wiz->wizard_type == eWizardType_Microsatellite && wiz->show_feature_table_help) {
16815     ShowWizardHelpText ("Feature Table Help", s_WizardMicrosatelliteFeatureTableHelpMsgs);
16816   } else if ((wiz->wizard_type == eWizardType_Viruses || wiz->wizard_type == eWizardType_Microsatellite) && wiz->annot_list != NULL) {
16817     sep = AddWizardAnnots(wiz, sep);
16818   } else if (wiz->virus_feat == eVirusFeat_None && wiz->wizard_type == eWizardType_Viruses) {
16819     ShowWizardHelpText ("Feature Table Help", s_WizardVirusFeatureTableHelpMsgs);
16820   } else {
16821     VisitBioseqsInSep (sep, wiz, AddWizardFeatureCallback);
16822   }
16823   return sep;
16824 }
16825 
16826 
DBLinkFromWizard(WizardTrackerPtr wiz)16827 static UserObjectPtr DBLinkFromWizard (WizardTrackerPtr wiz)
16828 {
16829   UserObjectPtr uop;
16830 
16831   if (wiz == NULL) {
16832     return NULL;
16833   } else if (StringHasNoText (wiz->bioproject) && StringHasNoText (wiz->biosample) && StringHasNoText (wiz->srr)) {
16834     return NULL;
16835   }
16836   uop = CreateDBLinkUserObject ();
16837   if (!StringHasNoText (wiz->bioproject)) {
16838     AddFieldStringToDbLinkUserObject (wiz->bioproject, "BioProject", uop);
16839   }
16840   if (!StringHasNoText (wiz->biosample)) {
16841     AddFieldStringToDbLinkUserObject (wiz->biosample, "BioSample", uop);
16842   }
16843   if (!StringHasNoText (wiz->srr)) {
16844     AddFieldStringToDbLinkUserObject (wiz->srr, "Sequence Read Archive", uop);
16845   }
16846   return uop;
16847 }
16848 
16849 
AddWizardDescriptorsCallback(BioseqPtr bsp,Pointer data)16850 static void AddWizardDescriptorsCallback (BioseqPtr bsp, Pointer data)
16851 {
16852   WizardTrackerPtr wiz;
16853   SeqDescPtr sdp;
16854   MolInfoPtr mip;
16855   CharPtr    comment;
16856   CharPtr    comment_fmt = "Submitter Comment: %s";
16857   UserObjectPtr uop;
16858 
16859   wiz = (WizardTrackerPtr) data;
16860   if (wiz == NULL || bsp == NULL || ISA_aa(bsp->mol)) {
16861     return;
16862   }
16863 
16864   bsp->mol = wiz->mol_class;
16865   bsp->topology = wiz->topology;
16866 
16867   if (wiz->molinfo != NULL) {
16868     if (wiz->wizard_type == eWizardType_Viruses) {
16869       if (wiz->virus_feat == eVirusFeat_viroid_complete) {
16870         wiz->molinfo->completeness = 1;
16871       } else if (wiz->virus_feat == eVirusFeat_viroid_partial) {
16872         wiz->molinfo->completeness = 2;
16873       }
16874     }
16875 
16876     sdp = bsp->descr;
16877     while (sdp != NULL && sdp->choice != Seq_descr_molinfo) {
16878       sdp = sdp->next;
16879     }
16880 
16881     if (sdp == NULL) {
16882       sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_molinfo);
16883     }
16884 
16885     if ((mip = (MolInfoPtr)sdp->data.ptrvalue) == NULL) {
16886       mip = MolInfoNew ();
16887       sdp->data.ptrvalue = mip;
16888     }
16889 
16890     mip->biomol = wiz->molinfo->biomol;
16891     mip->completeness = wiz->molinfo->completeness;
16892     mip->tech = wiz->molinfo->tech;
16893   }
16894 
16895   if (wiz->comment != NULL) {
16896     if (wiz->wizard_type == eWizardType_WGS) {
16897       comment = StringSave (wiz->comment);
16898     } else {
16899       comment = (CharPtr) MemNew (sizeof(Char) * (StringLen (comment_fmt) + StringLen (wiz->comment)));
16900       sprintf (comment, comment_fmt, wiz->comment);
16901     }
16902     sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_comment);
16903     sdp->data.ptrvalue = comment;
16904   }
16905 
16906   uop = DBLinkFromWizard (wiz);
16907   if (uop != NULL) {
16908     sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_user);
16909     sdp->data.ptrvalue = uop;
16910   }
16911 
16912 }
16913 
16914 
AddWizardDescriptors(WizardTrackerPtr wiz,SeqEntryPtr sep)16915 static void AddWizardDescriptors (WizardTrackerPtr wiz, SeqEntryPtr sep)
16916 {
16917   if (wiz == NULL || sep == NULL) {
16918     return;
16919   }
16920 
16921   VisitBioseqsInSep (sep, wiz, AddWizardDescriptorsCallback);
16922 
16923 }
16924 
16925 
AddWizardSourceValuesCallback(BioSourcePtr biop,Pointer data)16926 static void AddWizardSourceValuesCallback (BioSourcePtr biop, Pointer data)
16927 {
16928   WizardTrackerPtr wiz;
16929 
16930   wiz = (WizardTrackerPtr) data;
16931   if (wiz == NULL || biop == NULL) {
16932     return;
16933   }
16934 
16935   biop->genome = wiz->genome;
16936 }
16937 
16938 
AddWizardSourceValues(WizardTrackerPtr wiz,SeqEntryPtr sep)16939 static void AddWizardSourceValues (WizardTrackerPtr wiz, SeqEntryPtr sep)
16940 {
16941   if (wiz == NULL || sep == NULL) {
16942     return;
16943   }
16944 
16945   if (wiz->wizard_type == eWizardType_CulturedSamples
16946       || wiz->wizard_type == eWizardType_IGS
16947       || wiz->wizard_type == eWizardType_DLoop
16948       || wiz->wizard_type == eWizardType_Microsatellite) {
16949     VisitBioSourcesInSep (sep, wiz, AddWizardSourceValuesCallback);
16950   }
16951 
16952 }
16953 
16954 
16955 static CharPtr AddNoteTextToOne (CharPtr orig_defline, CharPtr mod_name, CharPtr new_value, CharPtr PNTR list, Int4 num);
16956 static void TabTableToSeqAnnotList
16957 (ValNodePtr PNTR annot_list,
16958  ValNodePtr table,
16959  ValNodePtr base_src_quals,
16960  ValNodePtr extra_src_quals,
16961  ValNodePtr fquals,
16962  IDAndTitleEditPtr iatep,
16963  SeqEntryPtr sep_list);
16964 
16965 
WizardBioSourceCleanup(BioSourcePtr biop,Pointer data)16966 static void WizardBioSourceCleanup (BioSourcePtr biop, Pointer data)
16967 {
16968   WizardTrackerPtr wiz;
16969   OrgModPtr strain = NULL, serotype = NULL, mod;
16970   CharPtr   cp;
16971   Int4      len;
16972 
16973   if (biop == NULL || (wiz = (WizardTrackerPtr) data) == NULL) {
16974     return;
16975   }
16976   StripQuotesInNote (biop, NULL);
16977   if (wiz->wizard_type == eWizardType_Viruses && wiz->virus_class == eVirusClass_Influenza) {
16978     /* if strain ends with serotype in parentheses, remove parenthetized serotype from strain */
16979     if (biop->org != NULL && biop->org->orgname != NULL) {
16980       for (mod = biop->org->orgname->mod; mod != NULL && (strain == NULL || serotype == NULL); mod = mod->next) {
16981         if (mod->subtype == ORGMOD_strain) {
16982           strain = mod;
16983         } else if (mod->subtype == ORGMOD_serotype) {
16984           serotype = mod;
16985         }
16986       }
16987       if (strain != NULL && serotype != NULL) {
16988         if ((cp = (StringRChr (strain->subname, '('))) != NULL
16989             && (len = StringLen (serotype->subname)) > 0
16990             && StringNCmp (cp + 1, serotype->subname, len) == 0
16991             && StringCmp (cp + len + 1, ")") == 0) {
16992           *cp = 0;
16993         }
16994       }
16995     }
16996   }
16997 }
16998 
16999 
SpecialWizardCleanup(WizardTrackerPtr wiz,SeqEntryPtr sep)17000 static void SpecialWizardCleanup (WizardTrackerPtr wiz, SeqEntryPtr sep)
17001 {
17002   VisitBioSourcesInSep (sep, wiz, WizardBioSourceCleanup);
17003 }
17004 
17005 
GetWGSNote(WizardTrackerPtr wiz)17006 static CharPtr GetWGSNote (WizardTrackerPtr wiz)
17007 {
17008   CharPtr wizard_note = "[WGS wizard]";
17009   Int4    len = 0;
17010   CharPtr fmt = "[%s][WGS wizard]";
17011   CharPtr note;
17012 
17013   if (StringHasNoText (wiz->wgs_ns_msg)) {
17014     note = StringSave (wizard_note);
17015   } else {
17016     len = StringLen (wizard_note) + 1;
17017     if (!StringHasNoText (wiz->wgs_ns_msg)) {
17018       len += StringLen (wiz->wgs_ns_msg) + 2;
17019     }
17020     note = (CharPtr) MemNew (sizeof (Char) * len);
17021     StringCpy (note, wizard_note);
17022     if (!StringHasNoText (wiz->wgs_ns_msg)) {
17023       StringCat (note, "[");
17024       StringCat (note, wiz->wgs_ns_msg);
17025       StringCat (note, "]");
17026     }
17027   }
17028   return note;
17029 }
17030 
17031 
FinishWizardAndLaunchSequin(WizardTrackerPtr wiz)17032 static Boolean FinishWizardAndLaunchSequin (WizardTrackerPtr wiz)
17033 {
17034   BioseqSetPtr bssp;
17035   SeqEntryPtr  sep, next, tmp;
17036   SeqDescPtr   sdp;
17037   DatePtr      dp;
17038   Uint2        entityID;
17039   Int2         handled;
17040   IDAndTitleEditPtr iatep;
17041   Int4         i;
17042   CharPtr      val;
17043 
17044   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
17045 
17046   if (wiz->feat_qual_table != NULL) {
17047     TabTableToSeqAnnotList (&(wiz->annot_list), wiz->feat_qual_table, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals,
17048                             iatep, wiz->sequences);
17049   }
17050 
17051   for (i = 0; i < iatep->num_sequences; i++) {
17052     switch (wiz->wizard_type) {
17053       case eWizardType_UnculturedSamples:
17054         val = FindValueFromPairInDefline ("org", iatep->title_list[i]);
17055         /* set 'environmental-sample' value for all uncultured organism */
17056         if (StringNICmp (val, "uncultured", 10) == 0) {
17057           iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], "environmental-sample", "TRUE");
17058         }
17059         /* add uncultured subsource note */
17060         if (wiz->spans_unknown) {
17061           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[uncultured; wizard; spans unknown]", NULL, 0);
17062         } else {
17063           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[uncultured; wizard]", NULL, 0);
17064         }
17065         break;
17066       case eWizardType_Viruses:
17067         /* add viruses subsource note */
17068         iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[virus wizard]", NULL, 0);
17069         if (wiz->molinfo_comment != NULL) {
17070           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", wiz->molinfo_comment, NULL, 0);
17071         }
17072         if (wiz->virus_class == eVirusClass_Influenza) {
17073           val = FindValueFromPairInDefline ("passage history", iatep->title_list[i]);
17074           if (!StringHasNoText (val)) {
17075             SetStringValue (&val, "passage details", ExistingTextOption_prefix_colon);
17076             iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", val, NULL, 0);
17077             RemoveValueFromDefline ("passage history", iatep->title_list[i]);
17078           }
17079           val = MemFree (val);
17080         }
17081         break;
17082       case eWizardType_CulturedSamples:
17083         if (wiz->spans_unknown) {
17084           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[cultured; wizard; spans unknown]", NULL, 0);
17085         } else {
17086           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[cultured; wizard]", NULL, 0);
17087         }
17088         break;
17089       case eWizardType_IGS:
17090         if (wiz->spans_unknown) {
17091           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[intergenic wizard; spans unknown]", NULL, 0);
17092         } else {
17093           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[intergenic wizard]", NULL, 0);
17094         }
17095         break;
17096       case eWizardType_Microsatellite:
17097         if (wiz->multiple_repeats) {
17098           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[Microsatellite wizard; multiple repeats]", NULL, 0);
17099         } else {
17100           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[Microsatellite wizard]", NULL, 0);
17101         }
17102         break;
17103       case eWizardType_DLoop:
17104         if (wiz->add_span_note) {
17105           if (wiz->spans_unknown) {
17106             iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[D-loop wizard; spans unknown]", NULL, 0);
17107           } else {
17108             iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[D-loop wizard; spans known]", NULL, 0);
17109           }
17110         } else {
17111           iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", "[D-loop wizard]", NULL, 0);
17112         }
17113         break;
17114       case eWizardType_WGS:
17115         val = GetWGSNote(wiz);
17116         iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], "note-subsrc", val, NULL, 0);
17117         val = MemFree (val);
17118         break;
17119     }
17120   }
17121   ApplyIDAndTitleEditToSeqEntryList (wiz->sequences, iatep);
17122 
17123   if (iatep->num_sequences == 1) {
17124     globalFormatBlock.seqPackage = SEQ_PKG_SINGLE;
17125     FinishOneSeqEntry (wiz->sequences, wiz);
17126     sep = wiz->sequences;
17127     wiz->sequences = NULL;
17128   } else if (IS_Bioseq_set (wiz->sequences)) {
17129     /* imported an alignment, already a set */
17130     bssp = (BioseqSetPtr) wiz->sequences->data.ptrvalue;
17131     bssp->_class = wiz->set_class;
17132     for (tmp = bssp->seq_set; tmp != NULL; tmp = tmp->next) {
17133       FinishOneSeqEntry (tmp, wiz);
17134     }
17135     sep = wiz->sequences;
17136     wiz->sequences = NULL;
17137   } else {
17138     bssp = BioseqSetNew ();
17139     bssp->_class = wiz->set_class;
17140     sep = SeqEntryNew ();
17141     sep->choice = 2;
17142     sep->data.ptrvalue = (Pointer) bssp;
17143     tmp = wiz->sequences;
17144     wiz->sequences = NULL;
17145     while (tmp != NULL) {
17146       next = tmp->next;
17147       tmp->next = NULL;
17148       AddSeqEntryToSeqEntry (sep, tmp, TRUE);
17149 
17150       FinishOneSeqEntry (tmp, wiz);
17151       tmp = next;
17152     }
17153   }
17154   /* add structured comments */
17155   AddStructuredCommentsFromWizard (sep, wiz->structured_comments);
17156 
17157   iatep = IDAndTitleEditFree (iatep);
17158 
17159   if (sep != NULL) {
17160     dp = DateCurr ();
17161     if (dp != NULL) {
17162       sdp = CreateNewDescriptor (sep, Seq_descr_create_date);
17163       if (sdp != NULL) {
17164         sdp->data.ptrvalue = (Pointer) dp;
17165       }
17166     }
17167   }
17168 
17169   /* add other wizard features */
17170   sep = AddWizardFeatures (wiz, sep);
17171 
17172   /* if virus or cultured samples, add molinfo */
17173   AddWizardDescriptors (wiz, sep);
17174 
17175   /* if cultured, add genome info */
17176   AddWizardSourceValues (wiz, sep);
17177 
17178   MySeqEntryToAsn3 (sep, TRUE, FALSE, FALSE);
17179 
17180   entityID = PackageFormResults (globalsbp, sep, TRUE);
17181 
17182   SpecialWizardCleanup (wiz, sep);
17183 
17184   wiz = WizardTrackerFree (wiz);
17185 
17186   globalsbp = NULL;
17187   WatchCursor ();
17188   seqviewprocs.forceSeparateViewer = TRUE;
17189   SeqEntrySetScope (NULL);
17190   handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, 1,
17191                               OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
17192   ArrowCursor ();
17193   if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
17194     Message (MSG_FATAL, "Unable to launch viewer.");
17195   } else {
17196     SendHelpScrollMessage (helpForm, "Editing the Record", NULL);
17197   }
17198   ObjMgrSetOptions (OM_OPT_FREE_IF_NO_VIEW, entityID);
17199   ObjMgrSetDirtyFlag (entityID, TRUE);
17200   return TRUE;
17201 }
17202 
17203 
DoAllSequencesHaveModifierEx(IDAndTitleEditPtr iatep,CharPtr mod_name,PatternFunc match)17204 static Boolean DoAllSequencesHaveModifierEx (IDAndTitleEditPtr iatep, CharPtr mod_name, PatternFunc match)
17205 {
17206   CharPtr     val;
17207   Boolean     rval = TRUE;
17208   Int4        i;
17209 
17210   if (iatep == NULL) {
17211     return FALSE;
17212   }
17213   for (i = 0; i < iatep->num_sequences && rval; i++) {
17214     val = FindValueFromPairInDefline (mod_name, iatep->title_list[i]);
17215     if (StringHasNoText (val) || (match != NULL && !match(val))) {
17216       rval = FALSE;
17217     }
17218     val = MemFree (val);
17219   }
17220   return rval;
17221 }
17222 
17223 
DoAllSequencesHaveModifier(IDAndTitleEditPtr iatep,CharPtr mod_name)17224 static Boolean DoAllSequencesHaveModifier (IDAndTitleEditPtr iatep, CharPtr mod_name)
17225 {
17226   return DoAllSequencesHaveModifierEx (iatep, mod_name, NULL);
17227 }
17228 
17229 
StartsWithUncultured(CharPtr val)17230 static Boolean StartsWithUncultured (CharPtr val)
17231 {
17232   if (StringNICmp (val, "uncultured", 10) == 0) {
17233     return TRUE;
17234   } else {
17235     return FALSE;
17236   }
17237 }
17238 
17239 
DoAllOrgsStartWithUncultured(IDAndTitleEditPtr iatep)17240 static Boolean DoAllOrgsStartWithUncultured (IDAndTitleEditPtr iatep)
17241 {
17242   return DoAllSequencesHaveModifierEx (iatep, "org", StartsWithUncultured);
17243 }
17244 
17245 
RemoveNonUniqueingCharacters(CharPtr val)17246 static void RemoveNonUniqueingCharacters (CharPtr val)
17247 {
17248   CharPtr src, dst;
17249 
17250   if (val == NULL) {
17251     return;
17252   }
17253   src = val;
17254   dst = val;
17255   while (*src != 0) {
17256     if (*src != ' ' && *src != '-') {
17257       *dst = *src;
17258       dst++;
17259     }
17260     src++;
17261   }
17262   *dst = 0;
17263 }
17264 
17265 
DoAllSequencesHaveDifferentModifierValue(IDAndTitleEditPtr iatep,CharPtr mod_name)17266 static Boolean DoAllSequencesHaveDifferentModifierValue (IDAndTitleEditPtr iatep, CharPtr mod_name)
17267 {
17268   CharPtr     val;
17269   Boolean     rval = TRUE;
17270   ValNodePtr  list = NULL;
17271   Int4        num_before, num_after, i;
17272 
17273   if (iatep == NULL) {
17274     return FALSE;
17275   }
17276   for (i = 0; i < iatep->num_sequences && rval; i++) {
17277     val = FindValueFromPairInDefline (mod_name, iatep->title_list[i]);
17278     RemoveNonUniqueingCharacters(val);
17279     if (StringHasNoText (val)) {
17280       rval = FALSE;
17281       val = MemFree (val);
17282     } else {
17283       ValNodeAddPointer (&list, 0, val);
17284     }
17285   }
17286   if (rval) {
17287     num_before = ValNodeLen (list);
17288     list = ValNodeSort (list, SortVnpByString);
17289     ValNodeUnique (&list, SortVnpByString, ValNodeFreeData);
17290     num_after = ValNodeLen (list);
17291     if (num_after != num_before) {
17292       rval = FALSE;
17293     }
17294   }
17295   list = ValNodeFreeData (list);
17296   return rval;
17297 }
17298 
17299 
DoAllSequencesHaveSameModifierValue(SeqEntryPtr sep,CharPtr mod_name)17300 static Boolean DoAllSequencesHaveSameModifierValue (SeqEntryPtr sep, CharPtr mod_name)
17301 {
17302   CharPtr     first_val = NULL, val;
17303   Boolean     rval = TRUE;
17304 
17305   while (sep != NULL && rval) {
17306     val = FindValueFromPairInDefline (mod_name, DefLineForSeqEntry(sep));
17307     RemoveNonUniqueingCharacters(val);
17308     if (StringHasNoText (val)) {
17309       rval = FALSE;
17310     } else if (first_val == NULL) {
17311       first_val = val;
17312       val = NULL;
17313     } else if (StringICmp (val, first_val) != 0) {
17314       rval = FALSE;
17315     }
17316     val = MemFree (val);
17317     sep = sep->next;
17318   }
17319   return rval;
17320 }
17321 
17322 
DoAllSequencesHaveSameModiferValueIfPresent(IDAndTitleEditPtr iatep,CharPtr mod_name)17323 static Boolean DoAllSequencesHaveSameModiferValueIfPresent (IDAndTitleEditPtr iatep, CharPtr mod_name)
17324 {
17325   Int4 i;
17326   Boolean rval = TRUE;
17327   CharPtr first_val = NULL, val;
17328 
17329   if (iatep == NULL) {
17330     return TRUE;
17331   }
17332 
17333   for (i = 0; i < iatep->num_sequences && rval; i++) {
17334     val = FindValueFromPairInDefline (mod_name, iatep->title_list[i]);
17335     if (StringHasNoText (val)) {
17336       if (first_val != NULL) {
17337         rval = FALSE;
17338       }
17339     } else {
17340       if (i == 0) {
17341         first_val = val;
17342         val = NULL;
17343       } else if (first_val == NULL) {
17344         rval = FALSE;
17345       } else if (StringCmp (first_val, val)!= 0) {
17346         rval = FALSE;
17347       }
17348     }
17349     val = MemFree (val);
17350   }
17351   first_val = MemFree (first_val);
17352   return rval;
17353 }
17354 
17355 
HaveUniqueCombination(IDAndTitleEditPtr iatep,CharPtr name1,CharPtr name2)17356 static Boolean HaveUniqueCombination (IDAndTitleEditPtr iatep, CharPtr name1, CharPtr name2)
17357 {
17358   CharPtr     defline, val1, val2;
17359   Boolean     rval = TRUE, all1, all2;
17360   ValNodePtr  list = NULL;
17361   Int4        num_before, num_after, i;
17362 
17363   all1 = DoAllSequencesHaveModifierEx (iatep, name1, NULL);
17364   all2 = DoAllSequencesHaveModifierEx (iatep, name2, NULL);
17365   if (!all1 && !all2) {
17366     rval = FALSE;
17367   } else if (all1 && !all2) {
17368     rval = DoAllSequencesHaveDifferentModifierValue(iatep, name1);
17369   } else if (!all1 && all2) {
17370     rval = DoAllSequencesHaveDifferentModifierValue(iatep, name2);
17371   } else {
17372     for (i = 0; i < iatep->num_sequences && rval; i++) {
17373       defline = iatep->title_list[i];
17374       val1 = FindValueFromPairInDefline (name1, defline);
17375       RemoveNonUniqueingCharacters(val1);
17376       val2 = FindValueFromPairInDefline (name2, defline);
17377       RemoveNonUniqueingCharacters(val2);
17378       SetStringValue (&val1, val2, ExistingTextOption_append_semi);
17379       val2 = MemFree (val2);
17380       ValNodeAddPointer (&list, 0, val1);
17381     }
17382     num_before = ValNodeLen (list);
17383     list = ValNodeSort (list, SortVnpByString);
17384     ValNodeUnique (&list, SortVnpByString, ValNodeFreeData);
17385     num_after = ValNodeLen (list);
17386     if (num_after != num_before) {
17387       rval = FALSE;
17388     }
17389     list = ValNodeFreeData (list);
17390   }
17391   return rval;
17392 }
17393 
17394 
HaveUniqueCombinationOfQuals(IDAndTitleEditPtr iatep,ValNodePtr names)17395 static Boolean HaveUniqueCombinationOfQuals (IDAndTitleEditPtr iatep, ValNodePtr names)
17396 {
17397   CharPtr     defline, val1, val2;
17398   Boolean     rval = TRUE;
17399   ValNodePtr  list = NULL, vnp;
17400   Int4        num_before, num_after, i, num_all = 0;
17401   Int4        num_quals;
17402   CharPtr     first_all = NULL;
17403   Boolean     any_all = FALSE;
17404 
17405   if (iatep == NULL || names == NULL) {
17406     return FALSE;
17407   }
17408   num_quals = ValNodeLen (names);
17409   for (vnp = names; vnp != NULL; vnp = vnp->next) {
17410     if (DoAllSequencesHaveModifierEx (iatep, vnp->data.ptrvalue, NULL)) {
17411       any_all = TRUE;
17412       if (first_all == NULL) {
17413         first_all = vnp->data.ptrvalue;
17414       }
17415       num_all ++;
17416     }
17417   }
17418   if (!any_all) {
17419     rval = FALSE;
17420   } else if (num_all == 1) {
17421     rval = DoAllSequencesHaveDifferentModifierValue(iatep, first_all);
17422   } else {
17423     for (i = 0; i < iatep->num_sequences && rval; i++) {
17424       defline = iatep->title_list[i];
17425       val1 = NULL;
17426       for (vnp = names; vnp != NULL; vnp = vnp->next) {
17427         val2 = FindValueFromPairInDefline (vnp->data.ptrvalue, defline);
17428         RemoveNonUniqueingCharacters(val2);
17429         SetStringValue (&val1, val2, ExistingTextOption_append_semi);
17430         val2 = MemFree (val2);
17431       }
17432       ValNodeAddPointer (&list, 0, val1);
17433     }
17434     num_before = ValNodeLen (list);
17435     list = ValNodeSort (list, SortVnpByString);
17436     ValNodeUnique (&list, SortVnpByString, ValNodeFreeData);
17437     num_after = ValNodeLen (list);
17438     if (num_after != num_before) {
17439       rval = FALSE;
17440     }
17441     list = ValNodeFreeData (list);
17442   }
17443   return rval;
17444 }
17445 
17446 
DoAllSequencesHaveASourceQualOtherThanTaxname(IDAndTitleEditPtr iatep)17447 static Boolean DoAllSequencesHaveASourceQualOtherThanTaxname (IDAndTitleEditPtr iatep)
17448 {
17449   Int4              i, j;
17450   Boolean           rval = TRUE;
17451   Boolean           this_has_one;
17452   CharPtr           names, val, cp;
17453 
17454   for (i = 0; i < iatep->num_sequences && rval; i++) {
17455     this_has_one = FALSE;
17456     names = GetPresentModifierNames (iatep->title_list[i]);
17457     val = names;
17458     while (val != NULL && !this_has_one) {
17459       cp = StringChr (val, ',');
17460       if (cp != NULL) {
17461         *cp = 0;
17462       }
17463       TrimSpacesAroundString (val);
17464       if (StringICmp (val, "organism") != 0) {
17465         j = GetSourceQualTypeByName (val);
17466         if (j > -1) {
17467           this_has_one = TRUE;
17468         }
17469       }
17470       if (cp == NULL) {
17471         val = cp;
17472       } else {
17473         val = cp + 1;
17474       }
17475     }
17476     names = MemFree (names);
17477     if (!this_has_one) {
17478       rval = FALSE;
17479     }
17480   }
17481   return rval;
17482 }
17483 
17484 
GetNumValuesForMod(IDAndTitleEditPtr iatep,CharPtr mod_name)17485 static Int4 GetNumValuesForMod (IDAndTitleEditPtr iatep, CharPtr mod_name)
17486 {
17487   Int4 i, num = 0;
17488   CharPtr val;
17489 
17490   if (iatep == NULL) {
17491     return 0;
17492   }
17493 
17494   for (i = 0; i < iatep->num_sequences; i++) {
17495     val = FindValueFromPairInDefline (mod_name, iatep->title_list[i]);
17496     if (!StringHasNoText (val)) {
17497       num++;
17498     }
17499     val = MemFree (val);
17500   }
17501   return num;
17502 }
17503 
17504 
SetOneModValueForAllEx(SeqEntryPtr sep,CharPtr mod_name,CharPtr val,Boolean confirm_replacement)17505 static void SetOneModValueForAllEx (SeqEntryPtr sep, CharPtr mod_name, CharPtr val, Boolean confirm_replacement)
17506 {
17507   IDAndTitleEditPtr iatep;
17508   Int4              i, num;
17509 
17510   iatep = SeqEntryListToIDAndTitleEditEx (sep, TRUE);
17511 
17512   num = GetNumValuesForMod(iatep, mod_name);
17513   if (num > 0 && confirm_replacement) {
17514     if (ANS_OK != Message (MSG_OKC, "You already have %d values for %s - do you want to replace them?", num, mod_name)) {
17515       iatep = IDAndTitleEditFree (iatep);
17516       return;
17517     }
17518   }
17519 
17520   for (i = 0; i < iatep->num_sequences; i++) {
17521     if (StringHasNoText (val)) {
17522       RemoveValueFromDefline (mod_name, iatep->title_list[i]);
17523     } else {
17524       iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], mod_name, val);
17525     }
17526   }
17527   ApplyIDAndTitleEditToSeqEntryList (sep, iatep);
17528 
17529   iatep = IDAndTitleEditFree (iatep);
17530 }
17531 
17532 
SetOneModValueForAll(SeqEntryPtr sep,CharPtr mod_name,CharPtr val)17533 static void SetOneModValueForAll (SeqEntryPtr sep, CharPtr mod_name, CharPtr val)
17534 {
17535   SetOneModValueForAllEx (sep, mod_name, val, TRUE);
17536 }
17537 
17538 
AddNoteTextToOne(CharPtr orig_defline,CharPtr mod_name,CharPtr new_value,CharPtr PNTR list,Int4 num)17539 static CharPtr AddNoteTextToOne (CharPtr orig_defline, CharPtr mod_name, CharPtr new_value, CharPtr PNTR list, Int4 num)
17540 {
17541   CharPtr old_note, cp;
17542   Int4    i, len;
17543 
17544   old_note = GetValueFromTitle (mod_name, orig_defline);
17545 
17546   if (old_note == NULL) {
17547     old_note = StringSave (new_value);
17548   } else {
17549     if (list != NULL) {
17550       /* strip any old values */
17551       for (i = 0; i < num; i++) {
17552         if ((cp = StringSearch (old_note, list[i])) != NULL) {
17553           len = StringLen (list[i]);
17554           if (cp > old_note && *(cp - 1) == ';') {
17555             cp--;
17556             len++;
17557           } else if (cp - 1 > old_note && *(cp - 2) == ';' && *(cp - 1) == ' ') {
17558             cp -= 2;
17559             len += 2;
17560           }
17561           StringCpy (cp, cp + len);
17562         }
17563       }
17564     }
17565     if ((cp = StringSearch (old_note, new_value)) == NULL) {
17566       /* add new value */
17567       SetStringValue (&old_note, new_value, ExistingTextOption_append_semi);
17568     }
17569   }
17570   /* strip quotes */
17571   if (old_note != NULL) {
17572     FindReplaceString (&old_note, "\"", "", FALSE, FALSE);
17573   }
17574 
17575   if (StringHasNoText (old_note)) {
17576     RemoveValueFromDefline (mod_name, orig_defline);
17577   } else {
17578     orig_defline = ReplaceValueInOneDefLine (orig_defline, mod_name, old_note);
17579   }
17580   old_note = MemFree (old_note);
17581 
17582   return orig_defline;
17583 }
17584 
17585 
AddNoteTextToAll(SeqEntryPtr sep,CharPtr mod_name,CharPtr val,CharPtr PNTR list,Int4 num)17586 static void AddNoteTextToAll (SeqEntryPtr sep, CharPtr mod_name, CharPtr val, CharPtr PNTR list, Int4 num)
17587 {
17588   IDAndTitleEditPtr iatep;
17589   Int4              i;
17590 
17591   iatep = SeqEntryListToIDAndTitleEditEx (sep, TRUE);
17592 
17593   for (i = 0; i < iatep->num_sequences; i++) {
17594     iatep->title_list[i] = AddNoteTextToOne (iatep->title_list[i], mod_name, val, list, num);
17595   }
17596   ApplyIDAndTitleEditToSeqEntryList (sep, iatep);
17597 
17598   iatep = IDAndTitleEditFree (iatep);
17599 }
17600 
17601 
ModValInList(IDAndTitleEditPtr iatep,CharPtr mod_name,CharPtr PNTR list)17602 static CharPtr ModValInList (IDAndTitleEditPtr iatep, CharPtr mod_name, CharPtr PNTR list)
17603 {
17604   Int4              i;
17605   CharPtr           val, rval = NULL;
17606 
17607   if (iatep == NULL) {
17608     return NULL;
17609   }
17610   for (i = 0; i < iatep->num_sequences && rval == NULL; i++) {
17611     val = FindValueFromPairInDefline (mod_name, iatep->title_list[i]);
17612     if (!StringHasNoText (val)) {
17613       rval = ValueInList(val, list);
17614     }
17615     val = MemFree (val);
17616   }
17617   return rval;
17618 }
17619 
17620 
17621 
17622 typedef void (*DataFormFunc) PROTO ((Pointer data, WizardTrackerPtr wiz));
17623 typedef Boolean (*SequencesOkFunc) PROTO ((WizardTrackerPtr wiz));
17624 typedef Boolean (*CreateFormFunc) PROTO ((WizardTrackerPtr wiz));
17625 typedef CharPtr PNTR (*GetProblemListFunc) PROTO ((WizardTrackerPtr wiz));
17626 
17627 static Boolean CreateWizardFastaForm (WizardTrackerPtr wiz);
17628 
17629 #define WIZARD_BLOCK         \
17630   FORM_MESSAGE_BLOCK \
17631   SequencesOkFunc fwd_ok_func; \
17632   SequencesOkFunc back_ok_func; \
17633   DataFormFunc collect_func; \
17634   CreateFormFunc next_form; \
17635   WizardTrackerPtr wiz;
17636 
17637 typedef struct seqwizardform {
17638   WIZARD_BLOCK
17639 } WizardFormData, PNTR WizardFormPtr;
17640 
17641 
CleanupWizardForm(GraphiC g,Pointer data)17642 static void CleanupWizardForm (GraphiC g, Pointer data)
17643 {
17644   WizardFormPtr frm;
17645 
17646   if (data != NULL)
17647   {
17648     frm = (WizardFormPtr) data;
17649     frm->wiz = WizardTrackerFree(frm->wiz);
17650   }
17651   StdCleanupFormProc (g, data);
17652 }
17653 
17654 
AddToWizardBreadcrumbTrail(WizardTrackerPtr wiz,CreateFormFunc func)17655 static ValNodePtr AddToWizardBreadcrumbTrail (WizardTrackerPtr wiz, CreateFormFunc func)
17656 {
17657   ValNodePtr vnp;
17658 
17659   if (wiz == NULL || func == NULL) {
17660     return NULL;
17661   }
17662   vnp = ValNodeNew (NULL);
17663   vnp->data.ptrvalue = func;
17664   vnp->next = wiz->breadcrumbs;
17665   wiz->breadcrumbs = vnp;
17666   return vnp;
17667 }
17668 
17669 
RemoveFromWizardBreadcrumbTrail(WizardTrackerPtr wiz)17670 static ValNodePtr RemoveFromWizardBreadcrumbTrail (WizardTrackerPtr wiz)
17671 {
17672   ValNodePtr vnp;
17673 
17674   vnp = wiz->breadcrumbs;
17675   wiz->breadcrumbs = vnp->next;
17676   vnp->next = NULL;
17677   return vnp;
17678 }
17679 
17680 
WizardFormBack(ButtoN b)17681 static void WizardFormBack (ButtoN b)
17682 {
17683   WizardFormPtr frm;
17684   ValNodePtr    vnp = NULL;
17685   CreateFormFunc prev_form = NULL;
17686 
17687   frm = (WizardFormPtr) GetObjectExtra (b);
17688   if (frm == NULL) {
17689     return;
17690   }
17691   /* get data from page */
17692   if (frm->collect_func != NULL) {
17693     (frm->collect_func)(frm, frm->wiz);
17694   }
17695 
17696   if (frm->back_ok_func != NULL && !frm->back_ok_func(frm->wiz)) {
17697     return;
17698   }
17699 
17700   Hide (frm->form);
17701 
17702   if (frm->wiz->breadcrumbs != NULL) {
17703     /* take off the valnode that points to this form */
17704     vnp = RemoveFromWizardBreadcrumbTrail(frm->wiz);
17705   }
17706   if (frm->wiz->breadcrumbs != NULL) {
17707     prev_form = (CreateFormFunc) frm->wiz->breadcrumbs->data.ptrvalue;
17708   }
17709   if (prev_form == NULL) {
17710     /* go back to FASTA */
17711     prev_form = CreateWizardFastaForm;
17712   }
17713 
17714   if (prev_form(frm->wiz)) {
17715     frm->wiz = NULL;
17716     Remove (frm->form);
17717   } else {
17718     Show (frm->form);
17719     /* put breadcrumb back */
17720     if (vnp != NULL) {
17721       vnp->next = frm->wiz->breadcrumbs;
17722       frm->wiz->breadcrumbs = vnp;
17723       vnp = NULL;
17724     }
17725   }
17726 
17727   vnp = ValNodeFree (vnp);
17728 }
17729 
17730 
QuitFromWizard(ForM form)17731 NLM_EXTERN void QuitFromWizard (ForM form)
17732 {
17733   Remove (form);
17734   Hide (initSubmitForm);
17735   Update ();
17736   Show (startupForm);
17737   Select (startupForm);
17738   SendHelpScrollMessage (helpForm, "Introduction", NULL);
17739   Update ();
17740 }
17741 
17742 
WizardFormForward(ButtoN b)17743 static void WizardFormForward (ButtoN b)
17744 {
17745   WizardFormPtr frm;
17746   ValNodePtr    vnp;
17747 
17748   frm = (WizardFormPtr) GetObjectExtra (b);
17749   if (frm == NULL) {
17750     return;
17751   }
17752 
17753   /* get data from page */
17754   if (frm->collect_func != NULL) {
17755     (frm->collect_func)(frm, frm->wiz);
17756   }
17757 
17758   /* is it ok to go forward? */
17759   if (frm->fwd_ok_func != NULL && !(frm->fwd_ok_func)(frm->wiz)){
17760     if (frm->wiz->quit_now) {
17761       QuitFromWizard (frm->form);
17762     }
17763     return;
17764   }
17765 
17766   if (frm->next_form == NULL) {
17767     if (frm->fwd_ok_func == NULL) {
17768       Message (MSG_ERROR, "Please make a selection");
17769     }
17770     return;
17771   }
17772 
17773   Hide (frm->form);
17774 
17775   /* add to breadcrumb trail */
17776   vnp = AddToWizardBreadcrumbTrail (frm->wiz, frm->next_form);
17777 
17778   if ((frm->next_form)(frm->wiz)) {
17779     frm->wiz = NULL;
17780     Remove (frm->form);
17781   } else {
17782     Show (frm->form);
17783     /* remove from breadcrumb trail */
17784     vnp = RemoveFromWizardBreadcrumbTrail (frm->wiz);
17785     vnp = ValNodeFree (vnp);
17786   }
17787 }
17788 
MakeWizardNav(GrouP h,Pointer frmdata)17789 static GrouP MakeWizardNav (GrouP h, Pointer frmdata)
17790 {
17791   GrouP g;
17792   ButtoN b;
17793 
17794   g = HiddenGroup (h, 2, 0, NULL);
17795   SetGroupSpacing (g, 10, 10);
17796   b = PushButton (g, "Back", WizardFormBack);
17797   SetObjectExtra (b, frmdata, NULL);
17798   b = PushButton (g, "Next", WizardFormForward);
17799   SetObjectExtra (b, frmdata, NULL);
17800 
17801   return g;
17802 }
17803 
17804 
17805 typedef struct wizardchoice {
17806   CharPtr name;
17807   SequencesOkFunc fwd_ok_func;
17808   CreateFormFunc next_form;
17809 } WizardChoiceData, PNTR WizardChoicePtr;
17810 
17811 
17812 typedef struct wizardsinglechoiceform {
17813   WIZARD_BLOCK
17814 
17815   GrouP single_choice;
17816 
17817   WizardChoicePtr choice_list;
17818 } WizardSingleChoiceFormData, PNTR WizardSingleChoiceFormPtr;
17819 
17820 
MissingWizardSingleChoice(WizardTrackerPtr wiz)17821 static Boolean MissingWizardSingleChoice (WizardTrackerPtr wiz)
17822 {
17823   Message (MSG_ERROR, "You must make a selection!");
17824   return FALSE;
17825 }
17826 
17827 
SaveWizardSingleChoice(Pointer data,WizardTrackerPtr wiz)17828 static void SaveWizardSingleChoice (Pointer data, WizardTrackerPtr wiz)
17829 {
17830   WizardSingleChoiceFormPtr frm;
17831   Int2 val, i;
17832 
17833   frm = (WizardSingleChoiceFormPtr) data;
17834   if (frm == NULL) {
17835     return;
17836   }
17837 
17838   val = GetValue (frm->single_choice);
17839   for (i = 0; i < val - 1 && frm->choice_list[i].name != NULL; i++)
17840   {
17841   }
17842 
17843   if (i == val - 1 && frm->choice_list[i].name != NULL) {
17844     frm->fwd_ok_func = frm->choice_list[i].fwd_ok_func;
17845     frm->next_form = frm->choice_list[i].next_form;
17846   } else {
17847     frm->fwd_ok_func = MissingWizardSingleChoice;
17848     frm->next_form = NULL;
17849   }
17850 }
17851 
17852 
CreateWizardSingleChoiceForm(WizardTrackerPtr wiz,WizardChoicePtr choice_list,CharPtr dlg_title,CharPtr prompt)17853 static Boolean CreateWizardSingleChoiceForm (WizardTrackerPtr wiz, WizardChoicePtr choice_list, CharPtr dlg_title, CharPtr prompt)
17854 {
17855   WizardSingleChoiceFormPtr frm;
17856   WindoW  w;
17857   GrouP   h;
17858   GrouP   c;
17859   PrompT  ppt;
17860   Int4    i;
17861 
17862   frm = (WizardSingleChoiceFormPtr) MemNew (sizeof (WizardSingleChoiceFormData));
17863   frm->wiz = wiz;
17864   frm->collect_func = SaveWizardSingleChoice;
17865   frm->fwd_ok_func = NULL;
17866   frm->next_form = NULL;
17867   frm->choice_list = choice_list;
17868 
17869   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
17870   SetObjectExtra (w, frm, CleanupWizardForm);
17871   frm->form = (ForM) w;
17872 
17873   h = HiddenGroup (w, -1, -1, NULL);
17874   SetGroupSpacing (h, 10, 10);
17875 
17876   ppt = StaticPrompt (h, prompt, 0, 0, programFont, 'c');
17877 
17878   frm->single_choice = HiddenGroup (h, 0, 20, NULL);
17879   SetGroupSpacing (frm->single_choice, 10, 10);
17880   for (i = 0; frm->choice_list[i].name != NULL; i++) {
17881     RadioButton (frm->single_choice, frm->choice_list[i].name);
17882   }
17883 
17884   c = MakeWizardNav (h, frm);
17885 
17886   AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
17887                               (HANDLE) frm->single_choice,
17888                               (HANDLE) c,
17889                               NULL);
17890 
17891   Update();
17892   Show (w);
17893 
17894   return TRUE;
17895 }
17896 
17897 
17898 typedef struct wizardsubchoice {
17899   CharPtr name;
17900   CharPtr hidden_prompt;
17901   WizardChoiceData subchoices[5];
17902 } WizardSubChoiceData, PNTR WizardSubChoicePtr;
17903 
17904 
17905 typedef struct wizardmultichoiceform {
17906   WIZARD_BLOCK
17907 
17908   GrouP main_choice;
17909   GrouP PNTR subchoices;
17910 
17911   WizardSubChoicePtr choice_list;
17912 } WizardMultiChoiceFormData, PNTR WizardMultiChoiceFormPtr;
17913 
17914 
SaveWizardMultiChoice(Pointer data,WizardTrackerPtr wiz)17915 static void SaveWizardMultiChoice (Pointer data, WizardTrackerPtr wiz)
17916 {
17917   WizardMultiChoiceFormPtr frm;
17918   Int2 val, i, j;
17919 
17920   frm = (WizardMultiChoiceFormPtr) data;
17921   if (frm == NULL) {
17922     return;
17923   }
17924 
17925   val = GetValue (frm->main_choice);
17926   for (i = 0; i < val - 1 && frm->choice_list[i].name != NULL; i++)
17927   {
17928   }
17929 
17930   if (i == val - 1 && frm->choice_list[i].name != NULL) {
17931     if (frm->choice_list[i].subchoices[1].name == NULL) {
17932       frm->fwd_ok_func = frm->choice_list[i].subchoices[0].fwd_ok_func;
17933       frm->next_form = frm->choice_list[i].subchoices[0].next_form;
17934     } else {
17935       val = GetValue (frm->subchoices[i]);
17936       if (!StringHasNoText (frm->choice_list[i].hidden_prompt)) {
17937         val--;
17938       }
17939       for (j = 0; j < val - 1 && frm->choice_list[i].subchoices[j].name != NULL; j++)
17940       {
17941       }
17942       if (j == val - 1 && frm->choice_list[i].subchoices[j].name != NULL) {
17943         frm->fwd_ok_func = frm->choice_list[i].subchoices[j].fwd_ok_func;
17944         frm->next_form = frm->choice_list[i].subchoices[j].next_form;
17945       } else {
17946         frm->fwd_ok_func = MissingWizardSingleChoice;
17947         frm->next_form = NULL;
17948       }
17949     }
17950   } else {
17951     frm->fwd_ok_func = MissingWizardSingleChoice;
17952     frm->next_form = NULL;
17953   }
17954 }
17955 
17956 
ChangeWizardMultiChoice(GrouP g)17957 static void ChangeWizardMultiChoice (GrouP g)
17958 {
17959   WizardMultiChoiceFormPtr frm;
17960   Int2 val, i;
17961 
17962   frm = (WizardMultiChoiceFormPtr) GetObjectExtra (g);
17963   if (frm == NULL) {
17964     return;
17965   }
17966 
17967   for (i = 0; frm->choice_list[i].name != NULL; i++)
17968   {
17969     SafeHide (frm->subchoices[i]);
17970   }
17971   val = GetValue (frm->main_choice);
17972   if (val - 1 < i) {
17973     SafeShow (frm->subchoices[val - 1]);
17974   }
17975 }
17976 
17977 
CreateWizardMultiChoiceForm(WizardTrackerPtr wiz,WizardSubChoicePtr choice_list,CharPtr dlg_title,CharPtr prompt)17978 static Boolean CreateWizardMultiChoiceForm (WizardTrackerPtr wiz, WizardSubChoicePtr choice_list, CharPtr dlg_title, CharPtr prompt)
17979 {
17980   WizardMultiChoiceFormPtr frm;
17981   WindoW  w;
17982   GrouP   h, g;
17983   GrouP   c;
17984   PrompT  ppt;
17985   Int4    i, j, num_main = 0;
17986 
17987   frm = (WizardMultiChoiceFormPtr) MemNew (sizeof (WizardMultiChoiceFormData));
17988   frm->wiz = wiz;
17989   frm->collect_func = SaveWizardMultiChoice;
17990   frm->fwd_ok_func = NULL;
17991   frm->next_form = NULL;
17992   frm->choice_list = choice_list;
17993 
17994   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
17995   SetObjectExtra (w, frm, CleanupWizardForm);
17996   frm->form = (ForM) w;
17997 
17998   h = HiddenGroup (w, -1, -1, NULL);
17999   SetGroupSpacing (h, 10, 10);
18000 
18001   ppt = StaticPrompt (h, prompt, 0, 0, programFont, 'c');
18002 
18003   frm->main_choice = HiddenGroup (h, 0, 20, ChangeWizardMultiChoice);
18004   SetObjectExtra (frm->main_choice, frm, NULL);
18005   SetGroupSpacing (frm->main_choice, 10, 10);
18006 
18007   for (i = 0; frm->choice_list[i].name != NULL; i++) {
18008     num_main++;
18009   }
18010 
18011   for (i = 0; frm->choice_list[i].name != NULL; i++) {
18012     RadioButton (frm->main_choice, frm->choice_list[i].name);
18013     num_main++;
18014   }
18015 
18016   frm->subchoices = (GrouP PNTR) MemNew (sizeof (GrouP) * num_main);
18017 
18018   g = HiddenGroup (h, 0, 0, NULL);
18019   for (i = 0; frm->choice_list[i].name != NULL; i++) {
18020     if (frm->choice_list[i].subchoices[1].name != NULL
18021         || !StringHasNoText (frm->choice_list[i].hidden_prompt)) {
18022       frm->subchoices[i] = HiddenGroup (h, 0, 20, NULL);
18023       if (!StringHasNoText (frm->choice_list[i].hidden_prompt)) {
18024         StaticPrompt (frm->subchoices[i], frm->choice_list[i].hidden_prompt, 0, 0, programFont, 'c');
18025       }
18026       for (j = 0; frm->choice_list[i].subchoices[j].name != NULL; j++) {
18027         RadioButton (frm->subchoices[i], frm->choice_list[i].subchoices[j].name);
18028       }
18029       Hide (frm->subchoices[i]);
18030     }
18031   }
18032 
18033   c = MakeWizardNav (h, frm);
18034 
18035   AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
18036                               (HANDLE) frm->main_choice,
18037                               (HANDLE) g,
18038                               (HANDLE) c,
18039                               NULL);
18040 
18041   Update();
18042   Show (w);
18043 
18044   return TRUE;
18045 }
18046 
18047 
18048 /* Wizard Form Creation Functions */
18049 static Boolean CreateWizardSrcQualsForm (WizardTrackerPtr wiz);
18050 static Boolean CreateWizardMolInfoForm (WizardTrackerPtr wiz);
18051 static Boolean CreateWizardMolInfoExtraForm (WizardTrackerPtr wiz);
18052 static Boolean WizardSourceTypeForm (WizardTrackerPtr wiz);
18053 static Boolean SingleRNAOrgWindow(WizardTrackerPtr wiz);
18054 static Boolean MultRNAOrgWindow(WizardTrackerPtr wiz);
18055 static Boolean PrimerChoiceWindow(WizardTrackerPtr wiz);
18056 static void MultiModTableToSeqEntryList (SeqEntryPtr sep, DialoG d, CharPtr PNTR mod_names, Int4 num_mods);
18057 static void SeqEntryToMultiModTabTable (WizardTrackerPtr wiz, DialoG d, CharPtr PNTR mod_names, Int4 num_mods, GetProblemListFunc problem_func, Boolean show_all);
18058 static Boolean ChimeraWindow(WizardTrackerPtr wiz);
18059 static Boolean SingleBacteriaArchaeaFeat (WizardTrackerPtr wiz);
18060 static Boolean MultBacteriaArchaeaFeat (WizardTrackerPtr wiz);
18061 
18062 static Boolean CreateVirusAnnotationForm (WizardTrackerPtr wiz);
18063 static Boolean CreateVirusNoncodingForm (WizardTrackerPtr wiz);
18064 static Boolean CreateVirusFeatureTableForm (WizardTrackerPtr wiz);
18065 
18066 static Boolean CreateWizardGenomeForm (WizardTrackerPtr wiz);
18067 static Boolean CreateMicrosatelliteAnnotationTypeForm (WizardTrackerPtr wiz);
18068 static Boolean CreateWizardAnnotationChoiceForm (WizardTrackerPtr wiz);
18069 static Boolean CreateIGSWizardAnnotationChoiceForm (WizardTrackerPtr wiz);
18070 
18071 static Boolean SingleIGSFeat (WizardTrackerPtr wiz);
18072 static Boolean MultipleIGSFeatSpansUnknown (WizardTrackerPtr wiz);
18073 
18074 static Boolean CreateDLoopAnnotationChoiceForm (WizardTrackerPtr wiz);
18075 static Boolean SetSpansKnownAndContinueToSequin (WizardTrackerPtr wiz);
18076 
18077 static Boolean BioProjectBioSampleWindow(WizardTrackerPtr wiz);
18078 
18079 static Boolean CreateFeatureQualsForm (WizardTrackerPtr wiz);
18080 
18081 static Boolean CheckDLoopSequenceLengthAndOkToContinueToSequin (WizardTrackerPtr wiz);
18082 static Boolean MakeControlRegionAndContinueToSequin (WizardTrackerPtr wiz);
18083 static Boolean MakeDLoopAndContinueToSequin (WizardTrackerPtr wiz);
18084 
18085 /* WGS protos */
18086 static Boolean AskAboutWGSLocation (WizardTrackerPtr wiz);
18087 static Boolean SetPlasmidNames (WizardTrackerPtr wiz);
18088 static Boolean AskAboutChromosomes (WizardTrackerPtr wiz);
18089 
18090 
18091 static Boolean WizardCommentForm (WizardTrackerPtr wiz);
18092 static Boolean OkToContinueToSequin (WizardTrackerPtr wiz);
18093 
18094 static void RejoinMainSubmissionForm (SeqEntryPtr sep, Int4 page, WizardTrackerPtr wiz);
18095 
18096 static CharPtr s_RNAFeatTableMsgs[] = {"\
18097 Feature Table Format:\n\
18098 ---------------------\n\
18099 -The header line begins with >Feature lcl| \n\
18100 \n\
18101 -The text following \"lcl|\" must contain the sequence ID of the sequences in your records.\n\
18102  For example: >Feature lcl|abc-1\n\
18103  In this example, abc-1 is the sequence ID.  \n\
18104 ",
18105 "\
18106 \n\
18107 -The table is composed of five, tab-separated columns:\n\
18108   1- nucleotide position of the start of the feature\n\
18109   2- nucleotide location of the end of a feature\n\
18110   3- feature type (rRNA, misc_RNA, etc.)\n\
18111   4- feature qualifier (product, note, etc.)\n\
18112   5- qualifier value (for example: 16S ribosomal RNA)\n\
18113 ",
18114 "\
18115 \n\
18116 -The columns in the table MUST be separated by tabs. \n\
18117  Use the Tab key on your keyboard to separate each column. \n\
18118  The qualifiers follow on lines starting with three tabs.\n\
18119 \n\
18120 -For more feature table format information: \n\
18121  http://www.ncbi.nlm.nih.gov/Sequin/table.html#Table Layout\n\
18122 ",
18123 "\
18124 \n\
18125 -Questions about the feature table format? Write to: info@ncbi.nlm.nih.gov\n\
18126 \n\
18127 \n\
18128 --------------------------------------------------\n\
18129 How to load a feature table in the record viewer:\n\
18130 --------------------------------------------------\n\
18131 File-->Open menu item\n\
18132 ",
18133 "\
18134 \n\
18135 ----------------------------------------------------------------------------\n\
18136 Example feature table for 2 sequences of bacterial/archaeal rRNA/IGS regions:\n\
18137 ----------------------------------------------------------------------------\n\
18138 >Feature lcl|abc-1\n\
18139 <1	100	rRNA\n\
18140 			product	16S ribosomal RNA\n\
18141 101	200	misc_RNA\n\
18142 			product	16S-23S ribosomal RNA intergenic spacer\n\
18143 201	>300	rRNA\n\
18144 			product	23S ribosomal RNA\n\
18145 >Feature lcl|def-2\n\
18146 <1	100	rRNA\n\
18147 			product	16S ribosomal RNA\n\
18148 101	200	misc_RNA\n\
18149 			product	16S-23S ribosomal RNA intergenic spacer\n\
18150 201	>300	rRNA\n\
18151 			product	23S ribosomal RNA\n\
18152 ",
18153 "\
18154 \n\
18155 ------------------------------------------------------------------\n\
18156 Example feature table for 3 sequences of fungal rRNA/ITS regions:\n\
18157 ------------------------------------------------------------------\n\
18158 \n\
18159 >Feature lcl|abc-2\n\
18160 <1	100	rRNA\n\
18161 			product	18S ribosomal RNA\n\
18162 101	200	misc_RNA\n\
18163 			product	internal transcribed spacer 1\n\
18164 201	300	rRNA\n\
18165 			product	5.8S ribosomal RNA\n\
18166 301	400	misc_RNA\n\
18167 			product	internal transcribed spacer 2\n\
18168 401	>500	rRNA\n\
18169 			product	28S ribosomal RNA\n\
18170 >Feature lcl|def-2\n\
18171 <1	100	rRNA\n\
18172 			product	18S ribosomal RNA\n\
18173 101	200	misc_RNA\n\
18174 			product	internal transcribed spacer 1\n\
18175 201	300	rRNA\n\
18176 			product	5.8S ribosomal RNA\n\
18177 301	400	misc_RNA\n\
18178 			product	internal transcribed spacer 2\n\
18179 401	>500	rRNA\n\
18180 			product	28S ribosomal RNA\n\
18181 >Feature lcl|def-3\n\
18182 <1	100	rRNA\n\
18183 			product	18S ribosomal RNA\n\
18184 101	200	misc_RNA\n\
18185 			product	internal transcribed spacer 1\n\
18186 201	300	rRNA\n\
18187 			product	5.8S ribosomal RNA\n\
18188 301	400	misc_RNA\n\
18189 			product	internal transcribed spacer 2\n\
18190 401	>500	rRNA\n\
18191 			product	28S ribosomal RNA\n\
18192 ", NULL};
18193 
18194 
18195 static CharPtr s_CulturedRNAFeatTableMsgs[] = {
18196 "\
18197 Feature Table Format:\n\
18198 ---------------------\n\
18199 -The header line begins with >Feature lcl| \n\
18200 \n\
18201 -The text following \"lcl|\" must contain the sequence ID of the sequences in your records.\n\
18202  For example: >Feature lcl|abc-1\n\
18203  In this example, abc-1 is the sequence ID.  \n\
18204 \n\
18205 -The table is composed of five, tab-separated columns:\n\
18206 ",
18207 "\
18208   1- nucleotide position of the start of the feature\n\
18209   2- nucleotide location of the end of a feature\n\
18210   3- feature type (rRNA, misc_RNA, etc.)\n\
18211   4- feature qualifier (product, note, etc.)\n\
18212   5- qualifier value (for example: 16S ribosomal RNA)\n\
18213 \n\
18214 -The columns in the table MUST be separated by tabs. \n\
18215  Use the Tab key on your keyboard to separate each column. \n\
18216  The qualifiers follow on lines starting with three tabs.\n\
18217 \n\
18218 ",
18219 "\
18220 -For more feature table format information: \n\
18221  http://www.ncbi.nlm.nih.gov/Sequin/table.html#Table Layout\n\
18222 \n\
18223 -Questions about the feature table format? Write to: info@ncbi.nlm.nih.gov\n\
18224 \n\
18225 \n\
18226 --------------------------------------------------\n\
18227 How to load a feature table in the record viewer:\n\
18228 --------------------------------------------------\n\
18229 File-->Open menu item\n\
18230 ",
18231 "\
18232 \n\
18233 ----------------------------------------------------------------------------\n\
18234 Example feature table for 2 sequences of bacterial/archaeal rRNA/IGS regions:\n\
18235 ----------------------------------------------------------------------------\n\
18236 >Feature lcl|abc-1\n\
18237 <1      100     rRNA\n\
18238                         product 16S ribosomal RNA\n\
18239 101     200     misc_RNA\n\
18240                         product 16S-23S ribosomal RNA intergenic spacer\n\
18241 201     >300    rRNA\n\
18242 ",
18243 "\
18244                         product 23S ribosomal RNA\n\
18245 >Feature lcl|def-2\n\
18246 <1      100     rRNA\n\
18247                         product 16S ribosomal RNA\n\
18248 101     200     misc_RNA\n\
18249                         product 16S-23S ribosomal RNA intergenic spacer\n\
18250 201     >300    rRNA\n\
18251                         product 23S ribosomal RNA\n\
18252 \n\
18253 ------------------------------------------------------------------\n\
18254 ",
18255 "\
18256 Example feature table for 3 sequences of fungal rRNA/ITS regions:\n\
18257 ------------------------------------------------------------------\n\
18258 \n\
18259 >Feature lcl|abc-2\n\
18260 <1      100     rRNA\n\
18261                         product 18S ribosomal RNA\n\
18262 101     200     misc_RNA\n\
18263                         product internal transcribed spacer 1\n\
18264 201     300     rRNA\n\
18265                         product 5.8S ribosomal RNA\n\
18266 ",
18267 "\
18268 301     400     misc_RNA\n\
18269                         product internal transcribed spacer 2\n\
18270 401     >500    rRNA\n\
18271                         product 28S ribosomal RNA\n\
18272 >Feature lcl|def-2\n\
18273 <1      100     rRNA\n\
18274                         product 18S ribosomal RNA\n\
18275 101     200     misc_RNA\n\
18276                         product internal transcribed spacer 1\n\
18277 201     300     rRNA\n\
18278 ",
18279 "\
18280                         product 5.8S ribosomal RNA\n\
18281 301     400     misc_RNA\n\
18282                         product internal transcribed spacer 2\n\
18283 401     >500    rRNA\n\
18284                         product 28S ribosomal RNA\n\
18285 >Feature lcl|def-3\n\
18286 <1      100     rRNA\n\
18287                         product 18S ribosomal RNA\n\
18288 101     200     misc_RNA\n\
18289                         product internal transcribed spacer 1\n\
18290 ",
18291 "\
18292 201     300     rRNA\n\
18293                         product 5.8S ribosomal RNA\n\
18294 301     400     misc_RNA\n\
18295                         product internal transcribed spacer 2\n\
18296 401     >500    rRNA\n\
18297                         product 28S ribosomal RNA\n\
18298 ", NULL};
18299 
18300 
18301 static CharPtr s_DLoopFeatTableMsgs[] = {"\
18302 Feature Table Format:\n\
18303 ---------------------\n\
18304 -The header line begins with >Feature lcl| \n\
18305 \n\
18306 -The text following \"lcl|\" must contain the sequence ID of the sequences in your records.\n\
18307  For example: >Feature lcl|abc-1\n\
18308  In this example, abc-1 is the sequence ID. \n\
18309 \n\
18310 -The table is composed of five, tab-separated columns:\n\
18311 ",
18312 "\
18313   1- nucleotide position of the start of the feature\n\
18314   2- nucleotide location of the end of a feature\n\
18315   3- feature type (gene, CDS, etc.)\n\
18316   4- feature qualifier (note, product, etc.)\n\
18317   5- qualifier value (for example: amoA, NifH)\n\
18318 \n\
18319 -The columns in the table MUST be separated by tabs. \n\
18320  Use the Tab key on your keyboard to separate each column. \n\
18321  The qualifiers follow on lines starting with three tabs.\n\
18322 \n\
18323 ",
18324 "\
18325 -For more feature table format information: \n\
18326  http://www.ncbi.nlm.nih.gov/Sequin/table.html#Table Layout\n\
18327 \n\
18328 -Questions about the feature table format? Write to: info@ncbi.nlm.nih.gov\n\
18329 \n\
18330 -------------------------------------------------\n\
18331 How to load a feature table in the record viewer:\n\
18332 -------------------------------------------------\n\
18333 File-->Open menu item\n\
18334 \n\
18335 ",
18336 "\
18337 -----------------------------------------------------------------------\n\
18338 Example feature table for 2 sequences:\n\
18339 -----------------------------------------------------------------------\n\
18340 >Feature lcl|ABC1\n\
18341 <1\t50\ttRNA\n\
18342 \t\t\tproduct\ttRNA-Phe\n\
18343 51\t>592\tD-loop\n\
18344 >Feature lcl|ABC2\n\
18345 <1\t50\ttRNA\n\
18346 \t\t\tproduct\ttRNA-Phe\n\
18347 ",
18348 "\
18349 51\t>400\tmisc_feature\n\
18350 \t\t\tnote\tcontrol region\n\
18351 \n\
18352 ", NULL};
18353 
18354 
18355 static CharPtr s_MiscFeatTableMsgs[] = {"\
18356 Feature Table Format:\n\
18357 ---------------------\n\
18358 -The header line begins with >Feature lcl| \n\
18359 \n\
18360 -The text following \"lcl|\" must contain the sequence ID of the sequences in your records.\n\
18361  For example: >Feature lcl|abc-1\n\
18362  In this example, abc-1 is the sequence ID. \n\
18363 ",
18364 "\
18365 \n\
18366 -The table is composed of five, tab-separated columns:\n\
18367   1- nucleotide position of the start of the feature\n\
18368   2- nucleotide location of the end of a feature\n\
18369   3- feature type (gene, CDS, etc.)\n\
18370   4- feature qualifier (note, product, etc.)\n\
18371   5- qualifier value (for example: amoA, NifH)\n\
18372 ",
18373 "\
18374 \n\
18375 -The columns in the table MUST be separated by tabs. \n\
18376  Use the Tab key on your keyboard to separate each column. \n\
18377  The qualifiers follow on lines starting with three tabs.\n\
18378 ",
18379 "\
18380 \n\
18381 -For more feature table format information: \n\
18382  http://www.ncbi.nlm.nih.gov/Sequin/table.html#Table Layout\n\
18383 \n\
18384 -Questions about the feature table format? Write to: info@ncbi.nlm.nih.gov\n\
18385 ",
18386 "\
18387 \n\
18388 -------------------------------------------------\n\
18389 How to load a feature table in the record viewer:\n\
18390 -------------------------------------------------\n\
18391 File-->Open menu item\n\
18392 ",
18393 "\
18394 \n\
18395 -----------------------------------------------------------------------\n\
18396 Example feature table for 2 sequences of bacterial amoA coding regions:\n\
18397 -----------------------------------------------------------------------\n\
18398 >Feature lcl|abc-1\n\
18399 <1	>592	gene\n\
18400 			gene	amoA\n\
18401 <1	>592	CDS\n\
18402 			product	ammonia monooxygenase subunit A\n\
18403 >Feature lcl|abc-2\n\
18404 <1	>592	gene\n\
18405 			gene	amoA\n\
18406 <1	>592	CDS\n\
18407 			product	ammonia monooxygenase subunit A\n\
18408 ", NULL};
18409 
18410 
ShowHelpAndContinueToSequin(WizardTrackerPtr wiz,CharPtr title,CharPtr PNTR msgs)18411 static Boolean ShowHelpAndContinueToSequin (WizardTrackerPtr wiz, CharPtr title, CharPtr PNTR msgs)
18412 {
18413   ShowWizardHelpText (title, msgs);
18414 
18415   if (!OkToContinueToSequin(wiz)) {
18416     return FALSE;
18417   } else {
18418     FinishWizardAndLaunchSequin (wiz);
18419     return TRUE;
18420   }
18421 }
18422 
18423 
ShowCulturedRNAFeatTableHelpAndContinueToSequin(WizardTrackerPtr wiz)18424 static Boolean ShowCulturedRNAFeatTableHelpAndContinueToSequin (WizardTrackerPtr wiz)
18425 {
18426   return ShowHelpAndContinueToSequin (wiz, "RNA Feature Table Instructions", s_CulturedRNAFeatTableMsgs);
18427 }
18428 
18429 
ShowRNAFeatureTableInstructionsAndContinueToSequin(WizardTrackerPtr wiz)18430 static Boolean ShowRNAFeatureTableInstructionsAndContinueToSequin (WizardTrackerPtr wiz)
18431 {
18432   return ShowHelpAndContinueToSequin (wiz, "RNA Feature Table Instructions", s_RNAFeatTableMsgs);
18433 }
18434 
18435 
ShowDLoopFeatureTableInstructionsAndContinueToSequin(WizardTrackerPtr wiz)18436 static Boolean ShowDLoopFeatureTableInstructionsAndContinueToSequin (WizardTrackerPtr wiz)
18437 {
18438   return ShowHelpAndContinueToSequin (wiz, "Feature Table Instructions", s_DLoopFeatTableMsgs);
18439 }
18440 
18441 
ShowMiscFeatureTableInstructionsAndContinueToSequin(WizardTrackerPtr wiz)18442 static Boolean ShowMiscFeatureTableInstructionsAndContinueToSequin (WizardTrackerPtr wiz)
18443 {
18444   return ShowHelpAndContinueToSequin (wiz, "Feature Table Instructions", s_MiscFeatTableMsgs);
18445 
18446 }
18447 
18448 
WizardHasRNA(WizardTrackerPtr wiz)18449 static Boolean WizardHasRNA (WizardTrackerPtr wiz)
18450 {
18451   Boolean rval = TRUE;
18452 
18453   if (StringHasNoText (wiz->rna_name)) {
18454     Message (MSG_ERROR, "You must choose a feature type!");
18455     rval = FALSE;
18456   } else {
18457     wiz->partial5 = TRUE;
18458     wiz->partial3 = TRUE;
18459   }
18460   return rval;
18461 }
18462 
18463 
HasRNAOkToContinueToSequin(WizardTrackerPtr wiz)18464 static Boolean HasRNAOkToContinueToSequin (WizardTrackerPtr wiz)
18465 {
18466   Boolean rval;
18467 
18468   if (WizardHasRNA(wiz)) {
18469     rval = OkToContinueToSequin(wiz);
18470   } else {
18471     rval = FALSE;
18472   }
18473   return rval;
18474 }
18475 
18476 
OkToContinueToSequinWithMessage(WizardTrackerPtr wiz,CharPtr leaving_msg)18477 static Boolean OkToContinueToSequinWithMessage (WizardTrackerPtr wiz, CharPtr leaving_msg)
18478 {
18479   ModalAcceptCancelData acd;
18480   WindoW                w;
18481   GrouP                 h, c;
18482   GrouP                 txt;
18483   ButtoN                b;
18484   Boolean               rval = FALSE;
18485 
18486   acd.accepted = FALSE;
18487   acd.cancelled = FALSE;
18488   acd.third_option = FALSE;
18489 
18490   w = ModalWindow(-20, -13, -10, -10, NULL);
18491   h = HiddenGroup (w, -1, 0, NULL);
18492   SetGroupSpacing (h, 10, 10);
18493 
18494   if (leaving_msg == NULL) {
18495     leaving_msg = s_LeavingWizardMsg;
18496     if (wiz != NULL && wiz->breadcrumbs != NULL) {
18497       if (wiz->breadcrumbs->data.ptrvalue == CreateVirusAnnotationForm
18498           || wiz->breadcrumbs->data.ptrvalue == ShowMiscFeatureTableInstructionsAndContinueToSequin) {
18499         leaving_msg = s_AlternateLeavingWizardMsg;
18500       } else if (wiz->use_alternate_leaving_msg) {
18501         leaving_msg = s_AlternateLeavingWizardMsg;
18502       }
18503     }
18504   }
18505   txt = MultiLinePrompt (h, leaving_msg, 30 * stdCharWidth, systemFont);
18506 
18507   c = HiddenGroup (h, 3, 0, NULL);
18508   SetGroupSpacing (c, 10, 10);
18509   b = PushButton (c, "Open Record Viewer", ModalAcceptButton);
18510   SetObjectExtra (b, &acd, NULL);
18511   b = PushButton (c, "Cancel", ModalCancelButton);
18512   SetObjectExtra (b, &acd, NULL);
18513   AlignObjects (ALIGN_CENTER, (HANDLE) txt, (HANDLE) c, NULL);
18514 
18515   Show(w);
18516   Select (w);
18517   while (!acd.accepted && ! acd.cancelled)
18518   {
18519     ProcessExternalEvent ();
18520     Update ();
18521   }
18522   ProcessAnEvent ();
18523   Remove (w);
18524   if (acd.accepted)
18525   {
18526     rval = TRUE;
18527   }
18528   return rval;
18529 }
18530 
18531 
OkToContinueToSequin(WizardTrackerPtr wiz)18532 static Boolean OkToContinueToSequin (WizardTrackerPtr wiz)
18533 {
18534   return OkToContinueToSequinWithMessage (wiz, NULL);
18535 }
18536 
18537 
18538 /* RNA Annotation forms */
18539 
18540 typedef struct rnasinglechoice {
18541   WIZARD_BLOCK
18542   GrouP feat_choice;
18543   TexT  feat_name;
18544 
18545   CharPtr PNTR standard_names;
18546 } RNASingleChoiceFormData, PNTR RNASingleChoiceFormPtr;
18547 
AddRnaFeatLabel(Pointer data,WizardTrackerPtr wiz)18548 static void AddRnaFeatLabel (Pointer data, WizardTrackerPtr wiz)
18549 {
18550   RNASingleChoiceFormPtr frm;
18551   Int2 i, j;
18552   CharPtr rna_name;
18553 
18554   frm = (RNASingleChoiceFormPtr) data;
18555   if (frm == NULL) {
18556     return;
18557   }
18558 
18559   if (frm->feat_choice == NULL) {
18560     rna_name = SaveStringFromText (frm->feat_name);
18561   } else {
18562     i = GetValue (frm->feat_choice);
18563     if (i == 0) {
18564       rna_name = NULL;
18565     } else {
18566       for (j = 0; j < i - 1 && frm->standard_names[j] != NULL; j++) {
18567       }
18568       if (frm->standard_names[j] == NULL) {
18569         rna_name = SaveStringFromText (frm->feat_name);
18570       } else {
18571         rna_name = StringSave (frm->standard_names[j]);
18572       }
18573     }
18574   }
18575   frm->wiz->rna_name = MemFree (frm->wiz->rna_name);
18576   frm->wiz->rna_name = rna_name;
18577   if (StringICmp (rna_name, "16S ribosomal RNA") != 0) {
18578     frm->fwd_ok_func = HasRNAOkToContinueToSequin;
18579     frm->next_form = FinishWizardAndLaunchSequin;
18580   } else {
18581     frm->fwd_ok_func = WizardHasRNA;
18582     frm->next_form = ChimeraWindow;
18583   }
18584 }
18585 
18586 
ChangeRNAFeatChoice(GrouP g)18587 static void ChangeRNAFeatChoice (GrouP g)
18588 {
18589   RNASingleChoiceFormPtr frm;
18590   Int2 i;
18591 
18592   frm = (RNASingleChoiceFormPtr) GetObjectExtra (g);
18593   if (frm == NULL) {
18594     return;
18595   }
18596 
18597   i = GetValue (frm->feat_choice);
18598   if (frm->standard_names[i - 1] == NULL) {
18599     Enable (frm->feat_name);
18600   } else {
18601     Disable (frm->feat_name);
18602   }
18603 }
18604 
18605 
SingleRNAFeat(WizardTrackerPtr wiz,CharPtr PNTR standard_names)18606 static Boolean SingleRNAFeat (WizardTrackerPtr wiz, CharPtr PNTR standard_names)
18607 {
18608   RNASingleChoiceFormPtr frm;
18609   WindoW w;
18610   GrouP  h;
18611   PrompT p;
18612   GrouP  g;
18613   Int4   i;
18614   Char   option_name[255];
18615   CharPtr dlg_title, subtitle;
18616 
18617   frm = (RNASingleChoiceFormPtr) MemNew (sizeof (RNASingleChoiceFormData));
18618   frm->wiz = wiz;
18619 
18620   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
18621   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
18622   SetObjectExtra (w, frm, CleanupWizardForm);
18623   frm->form = (ForM) w;
18624 
18625   h = HiddenGroup (w, -1, -1, NULL);
18626   SetGroupSpacing (h, 10, 10);
18627 
18628   p = StaticPrompt (h, "What do your sequences contain?", 0, 0, programFont, 'c');
18629 
18630   if (standard_names != NULL) {
18631     frm->feat_choice = HiddenGroup (h, 0, 20, ChangeRNAFeatChoice);
18632     SetObjectExtra (frm->feat_choice, frm, NULL);
18633     SetGroupSpacing (frm->feat_choice, 10, 10);
18634     for (i = 0; standard_names[i] != NULL; i++) {
18635       sprintf (option_name, "Only contains %s", standard_names[i]);
18636       RadioButton (frm->feat_choice, option_name);
18637     }
18638     RadioButton (frm->feat_choice, "Something else");
18639   }
18640   frm->feat_name = DialogText (h, "", 15, NULL);
18641 
18642   if (standard_names != NULL) {
18643     Disable (frm->feat_name);
18644   }
18645 
18646   g = MakeWizardNav (h, frm);
18647 
18648   frm->next_form = NULL;
18649   frm->fwd_ok_func = NULL;
18650   frm->collect_func = AddRnaFeatLabel;
18651 
18652   frm->standard_names = standard_names;
18653 
18654   AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) frm->feat_name, (HANDLE) g, (HANDLE) frm->feat_choice, NULL);
18655 
18656   Update();
18657   Show (w);
18658   if (wiz->wizard_type == eWizardType_CulturedSamples) {
18659     subtitle = "Single rRNA or IGS/Single rRNA or ITS/Single rRNA";
18660   } else {
18661     subtitle = "Single rRNA, ITS, or IGS";
18662   }
18663   SendHelpScrollMessage (helpForm, dlg_title, subtitle);
18664 
18665   return TRUE;
18666 }
18667 
18668 
18669 typedef struct rnamultchoice {
18670   WIZARD_BLOCK
18671   ButtoN PNTR feats;
18672   TexT  misc;
18673 
18674   CharPtr PNTR standard_names;
18675 } RNAMultChoiceFormData, PNTR RNAMultChoiceFormPtr;
18676 
AddMultRnaFeatLabel(Pointer data,WizardTrackerPtr wiz)18677 static void AddMultRnaFeatLabel (Pointer data, WizardTrackerPtr wiz)
18678 {
18679   RNAMultChoiceFormPtr frm;
18680   CharPtr rna_name = NULL, misc = NULL;
18681   Int4 i, len = 0, last_feat = 0, first_feat = -1, num_feat = 0;
18682 
18683   frm = (RNAMultChoiceFormPtr) data;
18684   if (frm == NULL) {
18685     return;
18686   }
18687   for (i = 0; frm->standard_names[i] != NULL; i++) {
18688     if (GetStatus (frm->feats[i])) {
18689       len += StringLen (frm->standard_names[i]) + 3;
18690       last_feat = i;
18691       if (first_feat == -1) {
18692         first_feat = i;
18693       }
18694       num_feat++;
18695     }
18696   }
18697   /* collect misc */
18698   if (GetStatus (frm->feats[i]) && !TextHasNoText (frm->misc)) {
18699     misc = SaveStringFromText (frm->misc);
18700     len += StringLen (misc) + 3;
18701     last_feat = i;
18702     if (first_feat == -1) {
18703       first_feat = i;
18704     }
18705     num_feat++;
18706   }
18707   if (len > 0) {
18708     len += 9;
18709     if (num_feat > 1) {
18710       len += 4;
18711     }
18712     rna_name = (CharPtr) MemNew (sizeof (Char) * len);
18713     if (num_feat > 1) {
18714       sprintf (rna_name, "contains ");
18715     }
18716     for (i = 0; frm->standard_names[i] != NULL; i++) {
18717       if (GetStatus (frm->feats[i])) {
18718         if (i != first_feat && num_feat > 2) {
18719           StringCat (rna_name, ",");
18720         }
18721         if (i == last_feat && num_feat > 1) {
18722           StringCat (rna_name, " and");
18723         }
18724         if (i != first_feat) {
18725           StringCat (rna_name, " ");
18726         }
18727         StringCat (rna_name, frm->standard_names[i]);
18728       }
18729     }
18730     if (misc != NULL) {
18731       if (i != first_feat && num_feat > 2) {
18732         StringCat (rna_name, ",");
18733       }
18734       if (i == last_feat && num_feat > 1) {
18735         StringCat (rna_name, " and");
18736       }
18737       if (i != first_feat) {
18738         StringCat (rna_name, " ");
18739       }
18740       StringCat (rna_name, misc);
18741     }
18742   }
18743   misc = MemFree (misc);
18744 
18745   frm->wiz->rna_name = MemFree (frm->wiz->rna_name);
18746   frm->wiz->rna_name = rna_name;
18747   frm->wiz->spans_unknown = TRUE;
18748   if (StringICmp (rna_name, "16S ribosomal RNA") != 0) {
18749     frm->fwd_ok_func = HasRNAOkToContinueToSequin;
18750     frm->next_form = FinishWizardAndLaunchSequin;
18751   } else {
18752     frm->fwd_ok_func = WizardHasRNA;
18753     frm->next_form = ChimeraWindow;
18754   }
18755 
18756 }
18757 
18758 
18759 #define kNumSynonymsInList 3
18760 typedef struct synonymlist {
18761   CharPtr names[kNumSynonymsInList];
18762 } SynonymListData, PNTR SynonymListPtr;
18763 
18764 
18765 static SynonymListData rna_synonyms[] = {
18766   { { "18S ribosomal RNA", "small subunit ribosomal RNA", NULL } },
18767   { { "28S ribosomal RNA", "26S ribosomal RNA", "large subunit ribosomal RNA" } }
18768 };
18769 
18770 #define NUM_rna_synonyms sizeof (rna_synonyms) / sizeof (SynonymListData)
18771 
18772 
IsStringInSynonymList(CharPtr str,SynonymListPtr list)18773 static Boolean IsStringInSynonymList (CharPtr str, SynonymListPtr list)
18774 {
18775   Int4 k;
18776 
18777   if (StringHasNoText (str) || list == NULL) {
18778     return FALSE;
18779   }
18780   for (k = 0; k < kNumSynonymsInList && list->names[k] != NULL; k++) {
18781     if (StringCmp (str, list->names[k]) == 0) {
18782       return TRUE;
18783     }
18784   }
18785   return FALSE;
18786 }
18787 
18788 
FindSynonymList(CharPtr feat_name)18789 static SynonymListPtr FindSynonymList (CharPtr feat_name)
18790 {
18791   Int4 j;
18792 
18793   if (StringHasNoText (feat_name)) {
18794     return NULL;
18795   }
18796   for (j = 0; j < NUM_rna_synonyms; j++) {
18797     if (IsStringInSynonymList(feat_name, rna_synonyms + j)) {
18798       return rna_synonyms + j;
18799     }
18800   }
18801   return NULL;
18802 }
18803 
18804 
DisableRNASynonyms(ButtoN b)18805 static void DisableRNASynonyms (ButtoN b)
18806 {
18807   RNAMultChoiceFormPtr frm;
18808   Int4 i, j;
18809   CharPtr feat_name = NULL;
18810   SynonymListPtr syn_list;
18811   Boolean status;
18812 
18813   frm = (RNAMultChoiceFormPtr) GetObjectExtra (b);
18814   if (frm == NULL) {
18815     return;
18816   }
18817 
18818   /* which one just got checked? */
18819   for (i = 0; frm->standard_names[i] != NULL && feat_name == NULL; i++) {
18820     if (b == frm->feats[i]) {
18821       feat_name = frm->standard_names[i];
18822       syn_list = FindSynonymList (feat_name);
18823       if (syn_list != NULL) {
18824         /* if now checked, disable synonyms, if now unchecked, enable synonyms */
18825         status = GetStatus (b);
18826         for (j = 0; frm->standard_names[j] != NULL; j++) {
18827           if (j != i) {
18828             if (IsStringInSynonymList(frm->standard_names[j], syn_list)) {
18829               if (status) {
18830                 Disable (frm->feats[j]);
18831                 SetStatus (frm->feats[j], FALSE);
18832               } else {
18833                 Enable (frm->feats[j]);
18834               }
18835             }
18836           }
18837         }
18838       }
18839     }
18840   }
18841 }
18842 
18843 
EnableRNAMiscText(ButtoN b)18844 static void EnableRNAMiscText (ButtoN b)
18845 {
18846   RNAMultChoiceFormPtr frm;
18847   Int4 i;
18848 
18849   frm = (RNAMultChoiceFormPtr) GetObjectExtra (b);
18850   if (frm == NULL) {
18851     return;
18852   }
18853   for (i = 0; frm->standard_names[i] != NULL; i++) {
18854   }
18855   if (GetStatus (frm->feats[i])) {
18856     Enable (frm->misc);
18857   } else {
18858     Disable (frm->misc);
18859   }
18860 }
18861 
18862 
MultRNAFeat(WizardTrackerPtr wiz,CharPtr PNTR standard_names)18863 static Boolean MultRNAFeat (WizardTrackerPtr wiz, CharPtr PNTR standard_names)
18864 {
18865   RNAMultChoiceFormPtr frm;
18866   WindoW w;
18867   GrouP  h;
18868   PrompT p;
18869   GrouP  g1, g2;
18870   Int4   i, num_feat = 0;
18871   CharPtr dlg_title, subtitle;
18872 
18873   frm = (RNAMultChoiceFormPtr) MemNew (sizeof (RNAMultChoiceFormData));
18874   frm->wiz = wiz;
18875   frm->standard_names = standard_names;
18876 
18877   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
18878   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
18879   SetObjectExtra (w, frm, CleanupWizardForm);
18880   frm->form = (ForM) w;
18881 
18882   h = HiddenGroup (w, -1, -1, NULL);
18883   SetGroupSpacing (h, 10, 10);
18884 
18885   p = StaticPrompt (h, "What do your sequences contain?", 0, 0, programFont, 'c');
18886 
18887   /* count number of names */
18888   for (i = 0; frm->standard_names[i] != NULL; i++) {
18889     num_feat++;
18890   }
18891   /* add one for misc */
18892   num_feat++;
18893 
18894   /* allocate memory for buttons */
18895   frm->feats = (ButtoN PNTR) MemNew (sizeof (ButtoN) * num_feat);
18896 
18897   g1 = HiddenGroup (h, 0, 20, NULL);
18898   SetGroupSpacing (g1, 10, 10);
18899   for (i = 0; frm->standard_names[i] != NULL; i++) {
18900     frm->feats[i] = CheckBox (g1, frm->standard_names[i], DisableRNASynonyms);
18901     SetObjectExtra (frm->feats[i], frm, NULL);
18902   }
18903   frm->feats[i] = CheckBox (g1, "Something else", EnableRNAMiscText);
18904   SetObjectExtra (frm->feats[i], frm, NULL);
18905   frm->misc = DialogText (g1, "", 15, NULL);
18906   Disable (frm->misc);
18907 
18908   g2 = MakeWizardNav (h, frm);
18909 
18910   frm->next_form = NULL;
18911   frm->fwd_ok_func = NULL;
18912   frm->collect_func = AddMultRnaFeatLabel;
18913 
18914   AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) g1, (HANDLE) g2, NULL);
18915 
18916   Update();
18917   Show (w);
18918   if (wiz->wizard_type == eWizardType_CulturedSamples) {
18919     subtitle = "Multiple rRNA or IGS where spans are unknown/Multiple rRNA or I";
18920   } else {
18921     subtitle = "Multiple rRNA, ITS, or IGS regions where spans are unknown";
18922   }
18923 
18924   SendHelpScrollMessage (helpForm, dlg_title, subtitle);
18925 
18926   /* must set spans_unknown after this point, if backing through, unset */
18927   wiz->spans_unknown = FALSE;
18928 
18929   return TRUE;
18930 }
18931 
18932 
18933 static CharPtr BacteriaArchaeaFeatNames[] = {
18934   "16S ribosomal RNA",
18935   "16S-23S ribosomal RNA intergenic spacer",
18936   "23S ribosomal RNA",
18937   NULL };
18938 
18939 static CharPtr OrganelleFeatNames[] = {
18940   "small subunit ribosomal RNA",
18941   "large subunit ribosomal RNA",
18942   NULL };
18943 
18944 
18945 static CharPtr FungalFeatNames[] = {
18946   "18S ribosomal RNA",
18947   "small subunit ribosomal RNA",
18948   "internal transcribed spacer 1",
18949   "5.8S ribosomal RNA",
18950   "internal transcribed spacer 2",
18951   "28S ribosomal RNA",
18952   "26S ribosomal RNA",
18953   "large subunit ribosomal RNA",
18954   NULL };
18955 
18956 
SingleBacteriaArchaeaFeat(WizardTrackerPtr wiz)18957 static Boolean SingleBacteriaArchaeaFeat (WizardTrackerPtr wiz)
18958 {
18959   return SingleRNAFeat (wiz, BacteriaArchaeaFeatNames);
18960 }
18961 
18962 
SingleRNAFeatOther(WizardTrackerPtr wiz)18963 static Boolean SingleRNAFeatOther (WizardTrackerPtr wiz)
18964 {
18965   return SingleRNAFeat (wiz, NULL);
18966 }
18967 
18968 
SingleFungalFeat(WizardTrackerPtr wiz)18969 static Boolean SingleFungalFeat (WizardTrackerPtr wiz)
18970 {
18971   return SingleRNAFeat (wiz, FungalFeatNames);
18972 }
18973 
18974 
SingleOrganelleFeat(WizardTrackerPtr wiz)18975 static Boolean SingleOrganelleFeat (WizardTrackerPtr wiz)
18976 {
18977   return SingleRNAFeat (wiz, OrganelleFeatNames);
18978 }
18979 
18980 
MultBacteriaArchaeaFeat(WizardTrackerPtr wiz)18981 static Boolean MultBacteriaArchaeaFeat (WizardTrackerPtr wiz)
18982 {
18983   return MultRNAFeat (wiz, BacteriaArchaeaFeatNames);
18984 }
18985 
18986 
MultFungalFeat(WizardTrackerPtr wiz)18987 static Boolean MultFungalFeat (WizardTrackerPtr wiz)
18988 {
18989   return MultRNAFeat (wiz, FungalFeatNames);
18990 }
18991 
18992 
18993 typedef struct rnaorgform {
18994   WIZARD_BLOCK
18995   GrouP org_choice;
18996   Boolean is_single;
18997 } RNAOrgFormData, PNTR RNAOrgFormPtr;
18998 
18999 
ChangeRNAOrgChoice(GrouP g)19000 static void ChangeRNAOrgChoice (GrouP g)
19001 {
19002   RNAOrgFormPtr frm;
19003   Int2 val;
19004 
19005   frm = (RNAOrgFormPtr) GetObjectExtra (g);
19006   if (frm == NULL) {
19007     return;
19008   }
19009   val = GetValue (frm->org_choice);
19010   if (frm->is_single) {
19011     switch (val) {
19012       case 1:
19013         frm->next_form = SingleBacteriaArchaeaFeat;
19014         break;
19015       case 2:
19016         frm->next_form = SingleFungalFeat;
19017         break;
19018       case 3:
19019         frm->next_form = SingleRNAFeatOther;
19020         break;
19021       default:
19022         frm->next_form = FinishWizardAndLaunchSequin;
19023         break;
19024     }
19025   } else {
19026     switch (val) {
19027       case 1:
19028         frm->next_form = MultBacteriaArchaeaFeat;
19029         break;
19030       case 2:
19031         frm->next_form = MultFungalFeat;
19032         break;
19033       case 3:
19034         frm->next_form = SingleRNAFeatOther;
19035         break;
19036       default:
19037         frm->next_form = FinishWizardAndLaunchSequin;
19038         break;
19039     }
19040   }
19041 }
19042 
19043 
MustChooseOrganism(WizardTrackerPtr wiz)19044 static Boolean MustChooseOrganism (WizardTrackerPtr wiz)
19045 {
19046   Message (MSG_ERROR, "You must choose an organism!");
19047   return FALSE;
19048 }
19049 
19050 
RNAOrgWindow(WizardTrackerPtr wiz,Boolean is_single)19051 static Boolean RNAOrgWindow(WizardTrackerPtr wiz, Boolean is_single)
19052 {
19053   RNAOrgFormPtr frm;
19054   WindoW w;
19055   GrouP  h;
19056   PrompT p;
19057   GrouP  g;
19058   CharPtr dlg_title;
19059 
19060   frm = (RNAOrgFormPtr) MemNew (sizeof (RNAOrgFormData));
19061   frm->wiz = wiz;
19062 
19063   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
19064   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
19065   SetObjectExtra (w, frm, CleanupWizardForm);
19066   frm->form = (ForM) w;
19067 
19068   h = HiddenGroup (w, -1, -1, NULL);
19069   SetGroupSpacing (h, 10, 10);
19070 
19071   p = StaticPrompt (h, "What type of organism are your sequence(s) from?", 0, 0, programFont, 'c');
19072 
19073   frm->org_choice = HiddenGroup (h, 0, 5, ChangeRNAOrgChoice);
19074   SetObjectExtra (frm->org_choice, frm, NULL);
19075   SetGroupSpacing (frm->org_choice, 10, 10);
19076   RadioButton (frm->org_choice, "rRNA or IGS from Bacteria or Archaea");
19077   RadioButton (frm->org_choice, "rRNA or ITS from Fungi");
19078   RadioButton (frm->org_choice, "rRNA, ITS, or IGS from some other organism");
19079   frm->is_single = is_single;
19080 
19081   g = MakeWizardNav (h, frm);
19082 
19083   frm->next_form = MustChooseOrganism;
19084 
19085   AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) frm->org_choice, (HANDLE) g, NULL);
19086 
19087   Update();
19088   Show (w);
19089 
19090   /* must set spans_unknown after this point, if backing through, unset */
19091   wiz->spans_unknown = FALSE;
19092 
19093   SendHelpScrollMessage (helpForm, dlg_title, "");
19094   return TRUE;
19095 }
19096 
19097 
SingleRNAOrgWindow(WizardTrackerPtr wiz)19098 static Boolean SingleRNAOrgWindow(WizardTrackerPtr wiz)
19099 {
19100   return RNAOrgWindow(wiz, TRUE);
19101 }
19102 
19103 
MultRNAOrgWindow(WizardTrackerPtr wiz)19104 static Boolean MultRNAOrgWindow(WizardTrackerPtr wiz)
19105 {
19106   return RNAOrgWindow(wiz, FALSE);
19107 }
19108 
19109 static Boolean UnculturedSamplesCodingRegionForm (WizardTrackerPtr wiz);
19110 
19111 typedef struct chimera {
19112   WIZARD_BLOCK
19113   GrouP checked;
19114   TexT  program;
19115   TexT  version;
19116 
19117 } ChimeraFormData, PNTR ChimeraFormPtr;
19118 
19119 
GetChimeraProgram(Pointer data,WizardTrackerPtr wiz)19120 static void GetChimeraProgram (Pointer data, WizardTrackerPtr wiz)
19121 {
19122   ChimeraFormPtr frm;
19123   Int2 i;
19124 
19125   frm = (ChimeraFormPtr) data;
19126   if (frm == NULL) {
19127     return;
19128   }
19129 
19130   i = GetValue (frm->checked);
19131   frm->wiz->chimera_program = MemFree (frm->wiz->chimera_program);
19132   frm->wiz->chimera_version = MemFree (frm->wiz->chimera_version);
19133   if (i == 1) {
19134     frm->wiz->chimera_program = SaveStringFromText (frm->program);
19135     frm->wiz->chimera_version = SaveStringFromText (frm->version);
19136   } else if (i == 2) {
19137     frm->wiz->chimera_program = StringSave ("none");
19138   }
19139 }
19140 
19141 
ChimeraOk(WizardTrackerPtr wiz)19142 static Boolean ChimeraOk (WizardTrackerPtr wiz)
19143 {
19144   Boolean rval = TRUE;
19145 
19146   if (StringHasNoText (wiz->chimera_program)) {
19147     Message (MSG_ERROR, "You must provide the name of the chimera check tool, if you used one!");
19148     rval = FALSE;
19149   } else {
19150     rval = OkToContinueToSequin(wiz);
19151   }
19152   return rval;
19153 }
19154 
19155 
SetChimeraChoice(GrouP g)19156 static void SetChimeraChoice (GrouP g)
19157 {
19158   ChimeraFormPtr frm;
19159 
19160   frm = (ChimeraFormPtr) GetObjectExtra (g);
19161   if (GetValue (frm->checked) == 1) {
19162     Enable (frm->program);
19163     Enable (frm->version);
19164   } else {
19165     Disable (frm->program);
19166     Disable (frm->version);
19167   }
19168 }
19169 
19170 
19171 CharPtr chimera_msg =
19172 "Please verify the sequences in your submission file have been quality checked "
19173 "and anomalous sequences, including chimeras, vector, misassemblies and low quality "
19174 "sequences, have been removed or trimmed where appropriate.\n"
19175 "Did you screen your sequences for 16S rRNA artifacts and remove anomalous sequences "
19176 "prior to preparing this submission?";
19177 
ChimeraWindow(WizardTrackerPtr wiz)19178 static Boolean ChimeraWindow(WizardTrackerPtr wiz)
19179 {
19180   ChimeraFormPtr frm;
19181   WindoW w;
19182   GrouP  h, program;
19183   GrouP  g, p_warn;
19184 
19185   frm = (ChimeraFormPtr) MemNew (sizeof (ChimeraFormData));
19186   frm->wiz = wiz;
19187 
19188   w = FixedWindow (-50, -33, -10, -10, "Wizard rRNA Chimera Checking", NULL);
19189   SetObjectExtra (w, frm, CleanupWizardForm);
19190   frm->form = (ForM) w;
19191 
19192   h = HiddenGroup (w, -1, -1, NULL);
19193   SetGroupSpacing (h, 10, 10);
19194   p_warn = MultiLinePrompt (h, chimera_msg,
19195                             500, programFont);
19196 
19197   frm->checked = HiddenGroup (h, 2, 0, SetChimeraChoice);
19198   SetGroupSpacing (frm->checked, 10, 10);
19199   SetObjectExtra (frm->checked, frm, NULL);
19200   RadioButton (frm->checked, "Yes");
19201   RadioButton (frm->checked, "No");
19202   program = HiddenGroup (h, 2, 0, NULL);
19203   SetGroupSpacing (program, 10, 10);
19204   StaticPrompt (program, "Program", 0, 0, programFont, 'l');
19205   frm->program = DialogText (program, "", 10, NULL);
19206   StaticPrompt (program, "Version", 0, 0, programFont, 'l');
19207   frm->version = DialogText (program, "", 10, NULL);
19208   Disable (frm->program);
19209   Disable (frm->version);
19210 
19211   g = MakeWizardNav (h, frm);
19212 
19213   frm->collect_func = GetChimeraProgram;
19214   frm->fwd_ok_func = ChimeraOk;
19215   frm->next_form = FinishWizardAndLaunchSequin;
19216 
19217   AlignObjects (ALIGN_CENTER, (HANDLE) p_warn, (HANDLE) frm->checked, (HANDLE) program, (HANDLE) g, NULL);
19218 
19219   Update();
19220   Show (w);
19221   SendHelpScrollMessage (helpForm, "Wizard rRNA Chimera Checking", "");
19222   return TRUE;
19223 }
19224 
19225 
19226 typedef struct primerchoiceform {
19227   WIZARD_BLOCK
19228   GrouP primer_choice;
19229 } PrimerChoiceFormData, PNTR PrimerChoiceFormPtr;
19230 
19231 
AddPrimerChoiceLabel(Pointer data,WizardTrackerPtr wiz)19232 static void AddPrimerChoiceLabel (Pointer data, WizardTrackerPtr wiz)
19233 {
19234   PrimerChoiceFormPtr frm;
19235   Int2 i;
19236   CharPtr           note_list[] = {"[universal primers]", "[amplified with species-specific primers]"};
19237   Int4              num_notes = 2;
19238 
19239   frm = (PrimerChoiceFormPtr) data;
19240   if (frm == NULL) {
19241     return;
19242   }
19243 
19244   i = GetValue (frm->primer_choice);
19245   if (i == 1) {
19246     AddNoteTextToAll (wiz->sequences, "note-subsrc", "[universal primers]", note_list, num_notes);
19247   } else {
19248     AddNoteTextToAll (wiz->sequences, "note-subsrc", "[amplified with species-specific primers]", note_list, num_notes);
19249   }
19250 }
19251 
19252 
19253 
PrimerChoiceWindow(WizardTrackerPtr wiz)19254 static Boolean PrimerChoiceWindow(WizardTrackerPtr wiz)
19255 {
19256   PrimerChoiceFormPtr frm;
19257   WindoW w;
19258   GrouP  h;
19259   PrompT p;
19260   GrouP  g;
19261   CharPtr dlg_title;
19262 
19263   frm = (PrimerChoiceFormPtr) MemNew (sizeof (PrimerChoiceFormData));
19264   frm->wiz = wiz;
19265   frm->collect_func = AddPrimerChoiceLabel;
19266 
19267   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_PrimerType);
19268   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
19269   SetObjectExtra (w, frm, CleanupWizardForm);
19270   frm->form = (ForM) w;
19271 
19272   h = HiddenGroup (w, -1, -1, NULL);
19273   SetGroupSpacing (h, 10, 10);
19274 
19275   p = StaticPrompt (h, "These sequences were obtained using:", 0, 0, programFont, 'c');
19276 
19277   frm->primer_choice = HiddenGroup (h, 0, 5, NULL);
19278   SetObjectExtra (frm->primer_choice, frm, NULL);
19279   SetGroupSpacing (frm->primer_choice, 10, 10);
19280   RadioButton (frm->primer_choice, "universal primers");
19281   RadioButton (frm->primer_choice, "species-specific primers");
19282   SetValue (frm->primer_choice, 1);
19283 
19284   g = MakeWizardNav (h, frm);
19285 
19286   frm->next_form = CreateWizardAnnotationChoiceForm;
19287 
19288   AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) frm->primer_choice, (HANDLE) g, NULL);
19289 
19290   Update();
19291   Show (w);
19292   SendHelpScrollMessage (helpForm, dlg_title, "");
19293 
19294   return TRUE;
19295 }
19296 
19297 
AddBackDBLinkDescriptor(WizardTrackerPtr wiz)19298 static void AddBackDBLinkDescriptor (WizardTrackerPtr wiz)
19299 {
19300   UserObjectPtr uop;
19301   SeqDescPtr    sdp;
19302 
19303   uop = DBLinkFromWizard (wiz);
19304   if (uop != NULL) {
19305     sdp = SeqDescrNew (NULL);
19306     sdp->data.ptrvalue = uop;
19307     ValNodeLink (&(globalsbp->descriptors), sdp);
19308   }
19309 }
19310 
19311 
RejoinMainSubmissionForm(SeqEntryPtr sep,Int4 page,WizardTrackerPtr wiz)19312 static void RejoinMainSubmissionForm (SeqEntryPtr sep, Int4 page, WizardTrackerPtr wiz)
19313 {
19314   MonitorPtr  mon;
19315   ForM        w;
19316 
19317   WatchCursor ();
19318   mon = MonitorStrNewEx ("Sequin New Submission", 30, FALSE);
19319   MonitorStrValue (mon, "Creating Sequences Form");
19320   Update ();
19321   if (sep == NULL || sep->next == NULL) {
19322     globalFormatBlock.seqPackage = SEQ_PKG_SINGLE;
19323   }
19324   w = CreateInitOrgNucProtForm (-5, -67, "Organism and Sequences",
19325                                 &globalFormatBlock,
19326                                 PutItTogether, BackToFormat,
19327                                 OrgAndSeqsActivateProc);
19328 
19329   ArrowCursor ();
19330   /*SetChecklistValue (checklistForm, 1);*/
19331   MonitorFree (mon);
19332   Update ();
19333   if (w != NULL) {
19334     Show (w);
19335     Select (w);
19336     if (globalFormatBlock.seqFormat == SEQ_FMT_ALIGNMENT) {
19337       SendHelpScrollMessage (helpForm, "Nucleotide Page", "Nucleotide Page for Aligned Data Formats");
19338     } else {
19339       SendHelpScrollMessage (helpForm, "Nucleotide Page", "Nucleotide Page for FASTA Data Format");
19340     }
19341   } else {
19342     Message (MSG_FATAL, "Unable to create window.");
19343   }
19344   if (sep != NULL) {
19345     SetSequencesForSubmissionForm ((WindoW) w, sep, page);
19346   }
19347   Update ();
19348   if (wiz != NULL) {
19349     AddBackDBLinkDescriptor (wiz);
19350   }
19351 }
19352 
19353 
AddOneSourceQualDesc(ValNodePtr PNTR list,CharPtr name,Boolean is_orgmod,Uint1 subtype,Uint1 subfield)19354 NLM_EXTERN void AddOneSourceQualDesc (ValNodePtr PNTR list, CharPtr name, Boolean is_orgmod, Uint1 subtype, Uint1 subfield)
19355 {
19356   SourceQualDescPtr sqdp;
19357 
19358   sqdp = (SourceQualDescPtr) MemNew (sizeof (SourceQualDescData));
19359   sqdp->name = name;
19360   sqdp->isOrgMod = is_orgmod;
19361   sqdp->subtype = subtype;
19362   sqdp->subfield = subfield;
19363   ValNodeAddPointer (list, 0, sqdp);
19364 }
19365 
19366 
19367 static DialoG
AddMultiModifierTableEditor(GrouP parent,CharPtr PNTR mod_names,CharPtr PNTR examples,Int4 num_mods,Int4 num_seq,GrouP PNTR grp_list)19368 AddMultiModifierTableEditor
19369 (GrouP        parent,
19370  CharPtr PNTR mod_names,
19371  CharPtr PNTR examples,
19372  Int4         num_mods,
19373  Int4         num_seq,
19374  GrouP PNTR   grp_list)
19375 {
19376   GrouP  g;
19377   DialoG d;
19378   Uint2Ptr taglist_types;
19379   Uint2Ptr taglist_widths;
19380   Int4 j;
19381   Int4 num_extra = 2; /* sequence ID and problems */
19382 
19383   taglist_types = (Uint2Ptr) MemNew (sizeof (Uint2) * (num_mods + num_extra));
19384   taglist_widths = (Uint2Ptr) MemNew (sizeof (Uint2) * (num_mods + num_extra));
19385 
19386   g = HiddenGroup (parent, num_mods + num_extra, 0, NULL);
19387   SetGroupSpacing (g, 10, 10);
19388 
19389   grp_list[0] = HiddenGroup (g, 0, 2, NULL);
19390   SetGroupSpacing(grp_list[0], 10, 10);
19391   StaticPrompt (grp_list[0], "Seq ID", 0, 0, programFont, 'c');
19392   if (examples != NULL) {
19393     StaticPrompt (grp_list[0], "Examples", 0, 0, systemFont, 'c');
19394   }
19395 
19396   taglist_types[0] = TAGLIST_PROMPT;
19397   taglist_widths[0] = 6;
19398   for (j = 0; j < num_mods; j++) {
19399     grp_list[j + 1] = HiddenGroup (g, 0, 2, NULL);
19400     SetGroupSpacing (grp_list[j + 1], 10, 10);
19401     StaticPrompt (grp_list[j + 1], mod_names[j], 0, 0, programFont, 'c');
19402     taglist_types[j + 1] = TAGLIST_TEXT;
19403     if (StringLen (mod_names[j]) > 18) {
19404       taglist_widths[j + 1] = 11;
19405     } else if (StringLen (mod_names[j]) > 17) {
19406       taglist_widths[j + 1] = 10;
19407     } else if (StringLen (mod_names[j]) > 15) {
19408       taglist_widths[j + 1] = 9;
19409     } else {
19410       taglist_widths[j + 1] = 8;
19411     }
19412     if (examples != NULL) {
19413       StaticPrompt (grp_list[j + 1], examples[j], 0, 0, systemFont, 'c');
19414     }
19415   }
19416   grp_list[j + 1] = HiddenGroup (g, 0, 2, NULL);
19417   SetGroupSpacing (grp_list[j + 1], 10, 10);
19418   StaticPrompt (grp_list[j + 1], "*** Problems ***", 0, 0, programFont, 'c');
19419   if (examples != NULL) {
19420     StaticPrompt (grp_list[j + 1], "", 0, 0, systemFont, 'c');
19421   }
19422   taglist_types[j + 1] = TAGLIST_PROMPT;
19423   taglist_widths[j + 1] = 20;
19424 
19425 
19426 
19427   d = CreateTagListDialogEx (parent, MIN (5, num_seq), num_mods + num_extra, 2,
19428                              taglist_types, taglist_widths, NULL,
19429                              TRUE, TRUE, NULL, NULL);
19430   taglist_types = MemFree (taglist_types);
19431   taglist_widths = MemFree (taglist_widths);
19432   return d;
19433 }
19434 
19435 
MultiModTabTableLineFromTitle(CharPtr id,CharPtr title,CharPtr PNTR mod_names,Int4 num_mods,CharPtr problems)19436 static CharPtr MultiModTabTableLineFromTitle (CharPtr id, CharPtr title, CharPtr PNTR mod_names, Int4 num_mods, CharPtr problems)
19437 {
19438   CharPtr line = NULL, val;
19439   Int4 len = 0, i;
19440   ValNodePtr vals = NULL, vnp;
19441 
19442   len = StringLen (id) + StringLen (problems) + 4;
19443   for (i = 0; i < num_mods; i++) {
19444     val = FindValueFromPairInDefline (mod_names[i], title);
19445     ValNodeAddPointer (&vals, 0, val);
19446     len += StringLen (val) + 1;
19447   }
19448 
19449   line = (CharPtr) MemNew (sizeof (Char) * len);
19450   StringCpy (line, id);
19451   for (vnp = vals; vnp != NULL; vnp = vnp->next) {
19452     StringCat (line, "\t");
19453     StringCat (line, vnp->data.ptrvalue);
19454   }
19455   StringCat (line, "\t");
19456   StringCat (line, problems);
19457 
19458   StringCat (line, "\n");
19459   vals = ValNodeFreeData (vals);
19460   return line;
19461 }
19462 
19463 
SeqEntryToMultiModTabTable(WizardTrackerPtr wiz,DialoG d,CharPtr PNTR mod_names,Int4 num_mods,GetProblemListFunc problem_func,Boolean show_all)19464 static void SeqEntryToMultiModTabTable (WizardTrackerPtr wiz, DialoG d, CharPtr PNTR mod_names, Int4 num_mods, GetProblemListFunc problem_func, Boolean show_all)
19465 {
19466   CharPtr     line;
19467   ValNodePtr  list = NULL;
19468   TagListPtr  tlp;
19469   IDAndTitleEditPtr iatep;
19470   Int4        i, j;
19471   Int2        max = 0;
19472   CharPtr     PNTR problems = NULL;
19473 
19474   tlp = (TagListPtr) GetObjectExtra (d);
19475   if (tlp == NULL) {
19476     return;
19477   }
19478 
19479   if (problem_func == NULL) {
19480     show_all = TRUE;
19481   } else {
19482     problems = problem_func (wiz);
19483   }
19484 
19485   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
19486 
19487   for (i = 0; i < iatep->num_sequences; i++) {
19488     if (show_all || !StringHasNoText (problems[i])) {
19489       line = MultiModTabTableLineFromTitle(iatep->id_list[i], iatep->title_list[i], mod_names, num_mods, problems == NULL ? NULL : problems[i]);
19490       ValNodeAddPointer (&list, 0, line);
19491       max++;
19492     }
19493   }
19494 
19495 
19496   SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
19497   tlp->vnp = list;
19498   SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
19499   tlp->max = MAX ((Int2) 0, (Int2) (max - tlp->rows));
19500   CorrectBarMax (tlp->bar, tlp->max);
19501   CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
19502 
19503   /* hide controls we might not be using (if hiding sequences without errors) */
19504   for (i = 0; i < MIN (max, tlp->rows); i++) {
19505     for (j = 0; j < tlp->cols; j++) {
19506       SafeShow (tlp->control [i * MAX_TAGLIST_COLS + j]);
19507     }
19508   }
19509   if (tlp->max > 0) {
19510     SafeShow (tlp->bar);
19511     SafeShow (tlp->left_bar);
19512   } else {
19513     SafeHide (tlp->bar);
19514     SafeHide (tlp->left_bar);
19515     for (i = max; i < tlp->rows; i ++) {
19516       for (j = 0; j < tlp->cols; j++) {
19517         SafeHide (tlp->control [i * MAX_TAGLIST_COLS + j]);
19518       }
19519     }
19520   }
19521 
19522   if (problems != NULL) {
19523     for (i = 0; i < iatep->num_sequences; i++) {
19524       MemFree (problems[i]);
19525     }
19526     problems = MemFree (problems);
19527   }
19528 
19529   iatep = IDAndTitleEditFree (iatep);
19530 }
19531 
19532 
MultiModTableToSeqEntryList(SeqEntryPtr sep,DialoG d,CharPtr PNTR mod_names,Int4 num_mods)19533 static void MultiModTableToSeqEntryList (SeqEntryPtr sep, DialoG d, CharPtr PNTR mod_names, Int4 num_mods)
19534 {
19535   CharPtr     val = NULL;
19536   ValNodePtr  vnp;
19537   TagListPtr  tlp;
19538   IDAndTitleEditPtr iatep;
19539   Int4        i, j;
19540 
19541   tlp = (TagListPtr) GetObjectExtra (d);
19542   if (tlp == NULL) {
19543     return;
19544   }
19545 
19546   iatep = SeqEntryListToIDAndTitleEditEx (sep, TRUE);
19547   for (i = 0, vnp = tlp->vnp; i < iatep->num_sequences && vnp != NULL; vnp = vnp->next) {
19548     val = ExtractTagListColumn (vnp->data.ptrvalue, 0);
19549     while (i < iatep->num_sequences && StringCmp (val, iatep->id_list[i]) != 0) {
19550       i++;
19551     }
19552     val = MemFree (val);
19553     if (i < iatep->num_sequences) {
19554       for (j = 0; j < num_mods; j++) {
19555         val = ExtractTagListColumn (vnp->data.ptrvalue, j + 1);
19556         if (StringHasNoText (val)) {
19557           RemoveValueFromDefline (mod_names[j], iatep->title_list[i]);
19558         } else {
19559           iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], mod_names[j], val);
19560         }
19561         val = MemFree (val);
19562       }
19563     }
19564   }
19565 
19566   ApplyIDAndTitleEditToSeqEntryList (sep, iatep);
19567 
19568   iatep = IDAndTitleEditFree (iatep);
19569 }
19570 
19571 
19572 static CharPtr PNTR GetWizardQualifierProblems (WizardTrackerPtr wiz);
19573 
19574 #define WIZARD_QUALS_BLOCK         \
19575   WIZARD_BLOCK \
19576   DialoG qual_table; \
19577   GrouP PNTR ed_grps; \
19578   TexT  PNTR apply_all_txt; \
19579   ButtoN PNTR bulk_btns; \
19580   ButtoN PNTR extra_btns; \
19581   GrouP  show_all_grp; \
19582   CharPtr PNTR mod_names; \
19583   EWizardEditQual PNTR edit_types; \
19584   Int4         num_mods;
19585 
19586 
19587 typedef struct wizardqualsform {
19588 WIZARD_QUALS_BLOCK
19589 } WizardQualsFormData, PNTR WizardQualsFormPtr;
19590 
19591 
ShouldShowAll(WizardQualsFormPtr frm)19592 static Boolean ShouldShowAll (WizardQualsFormPtr frm)
19593 {
19594   if (GetValue (frm->show_all_grp) == 2) {
19595     return TRUE;
19596   } else {
19597     return FALSE;
19598   }
19599 }
19600 
19601 
19602 typedef struct wizardsrcqualsform {
19603 WIZARD_QUALS_BLOCK
19604 } WizardSrcQualsFormData, PNTR WizardSrcQualsFormPtr;
19605 
19606 
RedrawQualTableChange(WizardSrcQualsFormPtr frm,IDAndTitleEditPtr iatep)19607 static void RedrawQualTableChange (WizardSrcQualsFormPtr frm, IDAndTitleEditPtr iatep)
19608 {
19609   WizardTrackerPtr  wiz;
19610   Boolean           redraw = FALSE;
19611 
19612   if (frm == NULL || iatep == NULL) {
19613     return;
19614   }
19615 
19616   switch (frm->wiz->wizard_type) {
19617     case eWizardType_UnculturedSamples:
19618       /* if we now have isolates, switch to different view */
19619       if (DoAnySequencesHaveModifierEx (iatep, "isolate", IsGelBand) && StringCmp (frm->mod_names[1], "Isolate") != 0) {
19620         redraw = TRUE;
19621       }
19622       break;
19623     case eWizardType_Viruses:
19624       /* if the non-default version of strain vs. isolate is now present, switch to different view */
19625       if (frm->wiz->virus_class == eVirusClass_Influenza) {
19626         if (DoAnySequencesHaveModifierEx (iatep, "strain", NULL)) {
19627           if (StringCmp (frm->mod_names[1], "Strain") != 0) {
19628             redraw = TRUE;
19629           }
19630         } else if (DoAnySequencesHaveModifierEx (iatep, "isolate", NULL)) {
19631           if (StringCmp (frm->mod_names[1], "Isolate") != 0) {
19632             redraw = TRUE;
19633           }
19634         } else if (StringCmp (frm->mod_names[1], "Strain") != 0) {
19635           redraw = TRUE;
19636         }
19637       } else {
19638         if (DoAnySequencesHaveModifierEx (iatep, "isolate", NULL)) {
19639           if (StringCmp (frm->mod_names[1], "Isolate") != 0) {
19640             redraw = TRUE;
19641           }
19642         } else if (DoAnySequencesHaveModifierEx (iatep, "strain", NULL)) {
19643           if (StringCmp (frm->mod_names[1], "Strain") != 0) {
19644             redraw = TRUE;
19645           }
19646         } else if (StringCmp (frm->mod_names[1], "Isolate") != 0) {
19647           redraw = TRUE;
19648         }
19649       }
19650       break;
19651     case eWizardType_IGS:
19652       if (frm->wiz->igs_source_type == eIGSSourceType_CulturedFungus) {
19653         if (DoAnySequencesHaveModifierEx (iatep, "strain", NULL)) {
19654           if (StringCmp (frm->mod_names[1], "Strain") != 0) {
19655             redraw = TRUE;
19656           }
19657         } else if (DoAnySequencesHaveModifierEx (iatep, "isolate", NULL)) {
19658           if (StringCmp (frm->mod_names[1], "Isolate") != 0) {
19659             redraw = TRUE;
19660           }
19661         } else if (StringCmp (frm->mod_names[1], "Strain") != 0) {
19662           redraw = TRUE;
19663         }
19664       }
19665       break;
19666     case eWizardType_CulturedSamples:
19667       if (frm->wiz->cultured_kingdom == eCulturedKingdom_BacteriaArchea
19668           || frm->wiz->cultured_kingdom == eCulturedKingdom_CulturedFungus) {
19669         if (DoAnySequencesHaveModifierEx (iatep, "strain", NULL)) {
19670           if (StringCmp (frm->mod_names[1], "Strain") != 0) {
19671             redraw = TRUE;
19672           }
19673         } else if (DoAnySequencesHaveModifierEx (iatep, "isolate", NULL)) {
19674           if (StringCmp (frm->mod_names[1], "Isolate") != 0) {
19675             redraw = TRUE;
19676           }
19677         } else if (StringCmp (frm->mod_names[1], "Strain") != 0) {
19678           redraw = TRUE;
19679         }
19680       }
19681       break;
19682     default:
19683       break;
19684   }
19685   if (redraw) {
19686     /* redraw the window */
19687     wiz = frm->wiz;
19688     frm->wiz = NULL;
19689     Hide (frm->form);
19690     if (CreateWizardSrcQualsForm (wiz)) {
19691       Remove (frm->form);
19692     } else {
19693       frm->wiz = wiz;
19694     }
19695   } else {
19696     SeqEntryToMultiModTabTable (frm->wiz, frm->qual_table, frm->mod_names, frm->num_mods,
19697                                 GetWizardQualifierProblems, ShouldShowAll((WizardQualsFormPtr)frm));
19698   }
19699 }
19700 
19701 
CopyStrainFromOrganismAfterTableRead(IDAndTitleEditPtr iatep)19702 static void CopyStrainFromOrganismAfterTableRead (IDAndTitleEditPtr iatep)
19703 {
19704   Int4 i, s_len;
19705   CharPtr org, strain, new_strain, serotype, new_serotype, delim;
19706   CharPtr look_for = "virus (";
19707   Int4    num_strain_not_copied = 0, num_serotype_not_copied = 0;
19708 
19709   if (iatep == NULL) {
19710     return;
19711   }
19712 
19713   for (i = 0; i < iatep->num_sequences; i++) {
19714     org = FindValueFromPairInDefline ("organism", iatep->title_list[i]);
19715     strain = FindValueFromPairInDefline ("strain", iatep->title_list[i]);
19716     serotype = FindValueFromPairInDefline ("serotype", iatep->title_list[i]);
19717     if ((delim = StringSearch (org, look_for)) != NULL) {
19718       new_strain = StringSave (delim + StringLen (look_for));
19719       s_len = StringLen (new_strain);
19720       if (s_len > 1 && new_strain[s_len - 1] == ')') {
19721         new_strain[s_len - 1] = 0;
19722       }
19723       new_serotype = NULL;
19724       if ((delim = StringSearch (new_strain, "(")) != NULL) {
19725         new_serotype = StringSave (delim + 1);
19726         *delim = 0;
19727         s_len = StringLen (new_serotype);
19728         if (s_len > 1 && new_serotype[s_len - 1] == ')') {
19729           new_serotype[s_len - 1] = 0;
19730         }
19731       }
19732 
19733       if (StringHasNoText (strain) && !StringHasNoText (new_strain)) {
19734         iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], "strain", new_strain);
19735       } else if (StringCmp (strain, new_strain) != 0) {
19736         num_strain_not_copied++;
19737       }
19738       new_strain = MemFree (new_strain);
19739       if (StringHasNoText (serotype) && !StringHasNoText (new_serotype)) {
19740         iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], "serotype", new_serotype);
19741       } else if (StringCmp (serotype, new_serotype) != 0) {
19742         num_serotype_not_copied++;
19743       }
19744     }
19745     strain = MemFree (strain);
19746     org = MemFree (org);
19747   }
19748   if (num_strain_not_copied > 0 && num_serotype_not_copied > 0) {
19749     Message (MSG_OK, "%d existing strain values and %d existing serotype values were not copied from organism name",
19750              num_strain_not_copied, num_serotype_not_copied);
19751   } else if (num_strain_not_copied > 0) {
19752     Message (MSG_OK, "%d existing strain values were not copied from organism name", num_strain_not_copied);
19753   } else if (num_serotype_not_copied > 0) {
19754     Message (MSG_OK, "%d existing serotype values were not copied from organism name", num_serotype_not_copied);
19755   }
19756 }
19757 
19758 
ImportMultiModTable(ButtoN b)19759 static void ImportMultiModTable (ButtoN b)
19760 {
19761   IDAndTitleEditPtr iatep;
19762   Boolean           rval;
19763   WizardSrcQualsFormPtr frm;
19764   ValNodePtr        preferred_list = NULL;
19765 
19766   frm = (WizardSrcQualsFormPtr) GetObjectExtra (b);
19767   if (frm == NULL) {
19768     return;
19769   }
19770 
19771   MultiModTableToSeqEntryList (frm->wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
19772 
19773   iatep = SeqEntryListToIDAndTitleEditEx (frm->wiz->sequences, TRUE);
19774 
19775   ValNodeAddPointer (&preferred_list, 2, StringSave ("Organism"));
19776   if (frm->wiz->wizard_type == eWizardType_UnculturedSamples) {
19777     AddOneSourceQualDesc (&preferred_list, "Clone", FALSE, SUBSRC_clone, 0);
19778     AddOneSourceQualDesc (&preferred_list, "Isolation-source", TRUE, SUBSRC_isolation_source, 0);
19779   } else if (frm->wiz->wizard_type == eWizardType_Viruses) {
19780     AddOneSourceQualDesc (&preferred_list, "Collection-date", FALSE, SUBSRC_collection_date, 0);
19781     AddOneSourceQualDesc (&preferred_list, "Country", FALSE, SUBSRC_country, 0);
19782     AddOneSourceQualDesc (&preferred_list, "Host", TRUE, ORGMOD_nat_host, 0);
19783     AddOneSourceQualDesc (&preferred_list, "Isolate", TRUE, ORGMOD_isolate, 0);
19784     AddOneSourceQualDesc (&preferred_list, "Genotype", FALSE, SUBSRC_genotype, 0);
19785     AddOneSourceQualDesc (&preferred_list, "Segment", FALSE, SUBSRC_segment, 0);
19786     AddOneSourceQualDesc (&preferred_list, "Serotype", TRUE, ORGMOD_serotype, 0);
19787     AddOneSourceQualDesc (&preferred_list, "Strain", TRUE, ORGMOD_serotype, 0);
19788   }
19789   rval = ImportModifiersToIDAndTitleEditEx (iatep, preferred_list);
19790   preferred_list = ValNodeFreeData (preferred_list);
19791 
19792   if (rval)
19793   {
19794     if (frm->wiz->wizard_type == eWizardType_Viruses && frm->wiz->virus_class == eVirusClass_Influenza) {
19795       CopyStrainFromOrganismAfterTableRead (iatep);
19796     }
19797     ApplyIDAndTitleEditToSeqEntryList (frm->wiz->sequences, iatep);
19798     RedrawQualTableChange (frm, iatep);
19799   }
19800   iatep = IDAndTitleEditFree (iatep);
19801 }
19802 
19803 
ExportMultiModTable(ButtoN b)19804 static void ExportMultiModTable (ButtoN b)
19805 {
19806   IDAndTitleEditPtr iatep;
19807   WizardSrcQualsFormPtr frm;
19808   Int4                  i;
19809   ValNodePtr            table = NULL, header = NULL, line, vnp;
19810   Char                  path [PATH_MAX];
19811   WizardQualPtr         q;
19812   FILE *fp;
19813 
19814   frm = (WizardSrcQualsFormPtr) GetObjectExtra (b);
19815   if (frm == NULL) {
19816     return;
19817   }
19818 
19819   if (!GetOutputFileName (path, sizeof (path), NULL)) {
19820     return;
19821   }
19822   fp = FileOpen (path, "w");
19823   if (fp == NULL) {
19824     Message (MSG_ERROR, "Unable to open %s", path);
19825     return;
19826   }
19827 
19828   MultiModTableToSeqEntryList (frm->wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
19829   ValNodeAddPointer (&header, 0, StringSave ("SeqId"));
19830   for (vnp = frm->wiz->base_src_quals; vnp != NULL; vnp = vnp->next) {
19831     q = (WizardQualPtr) vnp->data.ptrvalue;
19832     ValNodeAddPointer (&header, 0, StringSave (q->name));
19833   }
19834   for (vnp = frm->wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
19835     q = (WizardQualPtr) vnp->data.ptrvalue;
19836     if (q->show) {
19837       ValNodeAddPointer (&header, 0, StringSave (q->name));
19838     }
19839   }
19840   ValNodeAddPointer (&table, 0, header);
19841 
19842   iatep = SeqEntryListToIDAndTitleEditEx (frm->wiz->sequences, TRUE);
19843   for (i = 0; i < iatep->num_sequences; i++) {
19844     line = ValNodeNew (NULL);
19845     line->data.ptrvalue = StringSave (iatep->id_list[i]);
19846     ValNodeLink (&line, TabTableLineFromSrcQuals (iatep->title_list[i], frm->wiz->base_src_quals, frm->wiz->extra_src_quals));
19847     ValNodeAddPointer (&table, 0, line);
19848   }
19849 
19850   WriteTabTableToFile (table, fp);
19851   FileClose (fp);
19852 }
19853 
19854 
SaveWizardSrcQuals(Pointer data,WizardTrackerPtr wiz)19855 static void SaveWizardSrcQuals (Pointer data, WizardTrackerPtr wiz)
19856 {
19857   WizardSrcQualsFormPtr frm;
19858 
19859   frm = (WizardSrcQualsFormPtr) data;
19860   if (frm == NULL) {
19861     return;
19862   }
19863 
19864   MultiModTableToSeqEntryList (wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
19865   SeqEntryToMultiModTabTable (wiz, frm->qual_table, frm->mod_names, frm->num_mods,
19866                               GetWizardQualifierProblems, ShouldShowAll((WizardQualsFormPtr)frm));
19867 }
19868 
19869 
19870 CharPtr sUnwiseSampleOrgNames[] = {
19871   "unknown",
19872   "uncultured organism",
19873   "uncultured sample",
19874   "uncultured",
19875   "unidentified",
19876   NULL
19877 };
19878 
AddDuplicateSingleQualifierProblems(IDAndTitleEditPtr iatep,CharPtr qual_name,CharPtr PNTR problems,CharPtr err_name)19879 static void AddDuplicateSingleQualifierProblems (IDAndTitleEditPtr iatep, CharPtr qual_name, CharPtr PNTR problems, CharPtr err_name)
19880 {
19881   Int4    i;
19882   CharPtr val;
19883   ValNodePtr unique_list = NULL;
19884   CharPtr PNTR      unique_vals;
19885 
19886   unique_vals = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences));
19887 
19888 
19889   for (i = 0; i < iatep->num_sequences; i++) {
19890     val = FindValueFromPairInDefline (qual_name, iatep->title_list[i]);
19891     if (val != NULL) {
19892       ValNodeAddPointer (&unique_list, 0, val);
19893       unique_vals[i] = val;
19894     }
19895   }
19896   AddDuplicateProblems (&unique_list, unique_vals, problems, iatep->num_sequences, err_name);
19897 
19898   /* note - unique_vals and unique_list both reference the same allocated strings,
19899    * only need to free it once, do so in ValNodeFreeData of unique_list
19900    */
19901   unique_vals = MemFree (unique_vals);
19902   unique_list = ValNodeFreeData (unique_list);
19903 }
19904 
19905 
GetUnculturedQualifiersProblems(WizardTrackerPtr wiz)19906 static CharPtr PNTR GetUnculturedQualifiersProblems (WizardTrackerPtr wiz)
19907 {
19908   IDAndTitleEditPtr iatep;
19909   CharPtr PNTR      problems;
19910   CharPtr PNTR      clone_vals;
19911   CharPtr PNTR      isolate_vals;
19912   CharPtr           org, clone, isolate, iso, host;
19913   ValNodePtr        clone_list = NULL, isolate_list = NULL;
19914   Boolean           any_clone = FALSE, any_isolate = FALSE;
19915   Int4              i;
19916 
19917   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
19918   problems = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences + 1));
19919   clone_vals = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences));
19920   isolate_vals = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences));
19921 
19922   for (i = 0; i < iatep->num_sequences; i++) {
19923     org = FindValueFromPairInDefline ("org", iatep->title_list[i]);
19924     if (StringHasNoText (org)) {
19925       SetStringValue (&(problems[i]), "Missing organism name", ExistingTextOption_append_semi);
19926     } else {
19927       if (ValueInList(org, sUnwiseSampleOrgNames)) {
19928         SetStringValue (&(problems[i]), "Ambiguous organism name", ExistingTextOption_append_semi);
19929       } else if (StringNICmp (org, "uncultured", 10) != 0) {
19930         SetStringValue (&(problems[i]), "Organism name does not start with uncultured", ExistingTextOption_append_semi);
19931       }
19932     }
19933     org = MemFree (org);
19934 
19935     clone = FindValueFromPairInDefline ("clone", iatep->title_list[i]);
19936     if (StringHasNoText (clone)) {
19937       clone = MemFree (clone);
19938     } else {
19939       ValNodeAddPointer (&clone_list, 0, clone);
19940       clone_vals[i] = clone;
19941       any_clone = TRUE;
19942     }
19943 
19944     isolate = FindValueFromPairInDefline ("isolate", iatep->title_list[i]);
19945     if (StringHasNoText (isolate)) {
19946       isolate = MemFree (isolate);
19947     } else {
19948       ValNodeAddPointer (&isolate_list, 0, isolate);
19949       isolate_vals[i] = isolate;
19950       any_isolate = TRUE;
19951     }
19952 
19953     iso = FindValueFromPairInDefline ("isolation-source", iatep->title_list[i]);
19954     if (StringHasNoText (iso)) {
19955       host = FindValueFromPairInDefline ("host", iatep->title_list[i]);
19956       if (StringHasNoText (host)) {
19957         SetStringValue (&(problems[i]), "Missing isolation source", ExistingTextOption_append_semi);
19958       }
19959       host = MemFree (host);
19960     } else if (StringLen (iso) < 3) {
19961       SetStringValue (&(problems[i]), "Suspiciously short isolation source", ExistingTextOption_append_semi);
19962     } else if (ValueInList(iso, sBadUnculturedIsolationSources)) {
19963       SetStringValue (&(problems[i]), "Invalid isolation source", ExistingTextOption_append_semi);
19964     }
19965     iso = MemFree (iso);
19966   }
19967 
19968   /* report missing clone or isolate values */
19969   for (i = 0; i < iatep->num_sequences; i++) {
19970     if (any_isolate) {
19971       if (isolate_vals[i] == NULL) {
19972         SetStringValue (&(problems[i]), "Missing isolate", ExistingTextOption_append_semi);
19973       } else if (!IsGelBand (isolate_vals[i])) {
19974         SetStringValue (&(problems[i]), "Wrong format for DGGE/TGGE gel band isolate", ExistingTextOption_append_semi);
19975       }
19976     } else {
19977       if (clone_vals[i] == NULL) {
19978         SetStringValue (&(problems[i]), "Missing clone", ExistingTextOption_append_semi);
19979       }
19980     }
19981   }
19982 
19983   /* now check for duplicate clone or isolate values */
19984   if (any_isolate) {
19985     AddDuplicateProblems (&isolate_list, isolate_vals, problems, iatep->num_sequences, "Duplicate isolate values");
19986   } else if (any_clone) {
19987     AddDuplicateProblems (&clone_list, clone_vals, problems, iatep->num_sequences, "Duplicate clone values");
19988   }
19989 
19990   /* note - clone_vals and clone_list both reference the same allocated strings,
19991    * only need to free it once, do so in ValNodeFreeData of clone_list
19992    */
19993   clone_vals = MemFree (clone_vals);
19994   clone_list = ValNodeFreeData (clone_list);
19995   /* note - isolate_vals and isolate_list both reference the same allocated strings,
19996    * only need to free it once, do so in ValNodeFreeData of isolate_list
19997    */
19998   isolate_vals = MemFree (isolate_vals);
19999   isolate_list = ValNodeFreeData (isolate_list);
20000 
20001   iatep = IDAndTitleEditFree (iatep);
20002 
20003   return problems;
20004 }
20005 
20006 
AddMissingProblems(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz,CharPtr PNTR problems,Boolean required)20007 static void AddMissingProblems (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz, CharPtr PNTR problems, Boolean required)
20008 {
20009   Int4 i;
20010   WizardSrcQualPtr q;
20011   CharPtr val;
20012   ValNodePtr vnp;
20013 
20014   for (i = 0; i < iatep->num_sequences; i++) {
20015     for (vnp = wiz->base_src_quals; vnp != NULL; vnp = vnp->next) {
20016       q = (WizardSrcQualPtr) vnp->data.ptrvalue;
20017       if ((q->required && required) || (!q->required && !required && q->problem_when_missing)) {
20018         val = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20019         if (StringHasNoText (val)) {
20020           SetStringValue (&(problems[i]), "Missing ", ExistingTextOption_append_semi);
20021           SetStringValue (&(problems[i]), q->name, ExistingTextOption_append_none);
20022         }
20023         val = MemFree (val);
20024       }
20025     }
20026     for (vnp = wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
20027       q = (WizardSrcQualPtr) vnp->data.ptrvalue;
20028       if (q->show && ((q->required && required) || (!q->required && !required && q->problem_when_missing))) {
20029         val = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20030         if (StringHasNoText (val)) {
20031           SetStringValue (&(problems[i]), "Missing ", ExistingTextOption_append_semi);
20032           SetStringValue (&(problems[i]), q->name, ExistingTextOption_append_none);
20033         }
20034         val = MemFree (val);
20035       }
20036     }
20037   }
20038 }
20039 
20040 
AddFormatProblems(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz,CharPtr PNTR problems,Boolean required)20041 static void AddFormatProblems (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz, CharPtr PNTR problems, Boolean required)
20042 {
20043   Int4 i;
20044   WizardSrcQualPtr q;
20045   CharPtr val, tmp;
20046   ValNodePtr vnp;
20047 
20048   for (i = 0; i < iatep->num_sequences; i++) {
20049     for (vnp = wiz->base_src_quals; vnp != NULL; vnp = vnp->next) {
20050       q = (WizardSrcQualPtr) vnp->data.ptrvalue;
20051       if ((q->required && required) || (!q->required && !required)) {
20052         val = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20053         if (!StringHasNoText (val) && q->valid_func != NULL && (tmp = q->valid_func(val, q->name, FALSE)) != NULL) {
20054           SetStringValue (&(problems[i]), tmp, ExistingTextOption_append_semi);
20055           tmp = MemFree (tmp);
20056         }
20057         val = MemFree (val);
20058       }
20059     }
20060     for (vnp = wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
20061       q = (WizardSrcQualPtr) vnp->data.ptrvalue;
20062       if (q->show && ((q->required && required) || (!q->required && !required))) {
20063         val = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20064         if (!StringHasNoText (val) && q->valid_func != NULL && (tmp = q->valid_func(val, q->name, FALSE)) != NULL) {
20065           SetStringValue (&(problems[i]), tmp, ExistingTextOption_append_semi);
20066           tmp = MemFree (tmp);
20067         }
20068         val = MemFree (val);
20069       }
20070     }
20071   }
20072 }
20073 
20074 
FindLinkedQual(WizardTrackerPtr wiz,CharPtr q_name)20075 static WizardQualPtr FindLinkedQual (WizardTrackerPtr wiz, CharPtr q_name)
20076 {
20077   WizardQualPtr q;
20078   ValNodePtr vnp;
20079 
20080   if (wiz == NULL) {
20081     return NULL;
20082   }
20083   for (vnp = wiz->base_src_quals; vnp != NULL; vnp = vnp->next) {
20084     q = (WizardQualPtr) vnp->data.ptrvalue;
20085     if (q != NULL && StringICmp (q->name, q_name) == 0) {
20086       return q;
20087     }
20088   }
20089   for (vnp = wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
20090     q = (WizardQualPtr) vnp->data.ptrvalue;
20091     if (q != NULL && StringICmp (q->name, q_name) == 0) {
20092       return q;
20093     }
20094   }
20095   for (vnp = wiz->feature_quals; vnp != NULL; vnp = vnp->next) {
20096     q = (WizardQualPtr) vnp->data.ptrvalue;
20097     if (q != NULL && StringICmp (q->name, q_name) == 0) {
20098       return q;
20099     }
20100   }
20101 
20102   return NULL;
20103 }
20104 
20105 
AddLinkedProblemsForQualList(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz,CharPtr PNTR problems,ValNodePtr list)20106 static void AddLinkedProblemsForQualList (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz, CharPtr PNTR problems, ValNodePtr list)
20107 {
20108   Int4 i;
20109   WizardQualPtr q, q_l;
20110   CharPtr val1, val2;
20111   ValNodePtr vnp;
20112 
20113   for (vnp = list; vnp != NULL; vnp = vnp->next) {
20114     q = (WizardQualPtr) vnp->data.ptrvalue;
20115     if (q->linked != NULL) {
20116       q_l = FindLinkedQual(wiz, q->linked);
20117       if (q_l != NULL) {
20118         for (i = 0; i < iatep->num_sequences; i++) {
20119           val1 = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20120           val2 = FindValueFromPairInDefline (q_l->name, iatep->title_list[i]);
20121           if ((StringHasNoText (val1) && !StringHasNoText (val2)) || (!StringHasNoText (val1) && StringHasNoText (val2))) {
20122             SetStringValue (&(problems[i]), "Must provide both  ", ExistingTextOption_append_semi);
20123             SetStringValue (&(problems[i]), q->name, ExistingTextOption_append_none);
20124             SetStringValue (&(problems[i]), " and ", ExistingTextOption_append_none);
20125             SetStringValue (&(problems[i]), q_l->name, ExistingTextOption_append_none);
20126           }
20127           val1 = MemFree (val1);
20128           val2 = MemFree (val2);
20129         }
20130       }
20131     }
20132   }
20133 }
20134 
20135 
AddLinkedProblems(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz,CharPtr PNTR problems)20136 static void AddLinkedProblems (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz, CharPtr PNTR problems)
20137 {
20138   AddLinkedProblemsForQualList (iatep, wiz, problems, wiz->base_src_quals);
20139   AddLinkedProblemsForQualList (iatep, wiz, problems, wiz->extra_src_quals);
20140 }
20141 
20142 
CheckLinkedQualsForOneQual(IDAndTitleEditPtr iatep,WizardQualPtr q)20143 static Boolean CheckLinkedQualsForOneQual (IDAndTitleEditPtr iatep, WizardQualPtr q)
20144 {
20145   Int4 i;
20146   CharPtr val1, val2;
20147   Boolean rval = TRUE;
20148 
20149   if (q->linked != NULL) {
20150     for (i = 0; i < iatep->num_sequences; i++) {
20151       val1 = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20152       val2 = FindValueFromPairInDefline (q->linked, iatep->title_list[i]);
20153       if ((StringHasNoText (val1) && !StringHasNoText (val2)) || (!StringHasNoText (val1) && StringHasNoText (val2))) {
20154         rval = FALSE;
20155       }
20156       val1 = MemFree (val1);
20157       val2 = MemFree (val2);
20158     }
20159   }
20160   return rval;
20161 }
20162 
20163 
ValidateLinkedQualsForQualList(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz,ValNodePtr list)20164 static Boolean ValidateLinkedQualsForQualList (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz, ValNodePtr list)
20165 {
20166   WizardQualPtr q;
20167   ValNodePtr vnp;
20168 
20169   for (vnp = list; vnp != NULL; vnp = vnp->next) {
20170     q = (WizardQualPtr) vnp->data.ptrvalue;
20171     if (q->linked != NULL) {
20172       if (!CheckLinkedQualsForOneQual(iatep, q)) {
20173         if (StringISearch (q->name, "PCR-primer") != NULL) {
20174           if (ANS_CANCEL == Message (MSG_OKC,
20175                "For each sequence, you must provide either both %s and %s, or neither.  Do not provide sequencing primers.  Choose OK to remove %s and %s values on sequences where one of these is missing, or choose Cancel to provide missing values.",
20176                q->name, q->linked, q->name, q->linked)) {
20177             return FALSE;
20178           }
20179         } else {
20180           Message (MSG_ERROR, "For each sequence, if %s is provided, %s must also be provided.", q->name, q->linked);
20181           return FALSE;
20182         }
20183       }
20184     }
20185   }
20186   return TRUE;
20187 }
20188 
20189 
ValidateLinkedQuals(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz)20190 static Boolean ValidateLinkedQuals (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz)
20191 {
20192   Boolean rval = ValidateLinkedQualsForQualList (iatep, wiz, wiz->base_src_quals);
20193 
20194   if (rval) {
20195     rval = ValidateLinkedQualsForQualList (iatep, wiz, wiz->extra_src_quals);
20196   }
20197   return rval;
20198 }
20199 
20200 
DiscardUnbalancedQualsInIatepForList(IDAndTitleEditPtr iatep,ValNodePtr list)20201 static void DiscardUnbalancedQualsInIatepForList (IDAndTitleEditPtr iatep, ValNodePtr list)
20202 {
20203   ValNodePtr    q_vnp;
20204   WizardQualPtr q;
20205   CharPtr       val1, val2;
20206   Int4          i;
20207 
20208   for (q_vnp = list; q_vnp != NULL; q_vnp = q_vnp->next) {
20209     q = (WizardQualPtr) q_vnp->data.ptrvalue;
20210     if (q->linked != NULL) {
20211       for (i = 0; i < iatep->num_sequences; i++) {
20212         val1 = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20213         val2 = FindValueFromPairInDefline (q->linked, iatep->title_list[i]);
20214         if ((StringHasNoText (val1) && !StringHasNoText (val2)) || (!StringHasNoText (val1) && StringHasNoText (val2))) {
20215           if (!StringHasNoText (val1)) {
20216             iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], q->name, NULL);
20217           }
20218           if (!StringHasNoText (val2)) {
20219             iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], q->linked, NULL);
20220           }
20221         }
20222         val1 = MemFree (val1);
20223         val2 = MemFree (val2);
20224       }
20225     }
20226   }
20227 }
20228 
20229 
DiscardInvalidQualsInIatep(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz)20230 static void DiscardInvalidQualsInIatep (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz)
20231 {
20232   if (iatep == NULL || wiz == NULL) {
20233     return;
20234   }
20235   DiscardUnbalancedQualsInIatepForList (iatep, wiz->base_src_quals);
20236   DiscardUnbalancedQualsInIatepForList (iatep, wiz->extra_src_quals);
20237 }
20238 
20239 
GetYearFromCollectionDateString(CharPtr collection_date,Boolean debug)20240 static Int4 GetYearFromCollectionDateString (CharPtr collection_date, Boolean debug)
20241 {
20242   CharPtr cp, cp2, reformatted;
20243   Boolean ambiguous = FALSE;
20244   Int4 year = -1;
20245 
20246   reformatted = ReformatDateStringEx (collection_date, TRUE, &ambiguous);
20247   if (debug) {
20248     Message (MSG_ERROR, "ReformatDateStringEx produced '%s'", reformatted == NULL ? "NULL" : reformatted);
20249   }
20250   if (ambiguous && debug) {
20251     Message (MSG_ERROR, "Date was determined to be ambiguous");
20252   }
20253   if (StringHasNoText (reformatted) || ambiguous) {
20254     /* do nothing */
20255   } else {
20256     cp = StringChr (reformatted, '-');
20257     if (cp == NULL) {
20258       year = GetYearFromToken (reformatted, StringLen (reformatted));
20259       if (year < 1 && debug) {
20260         Message (MSG_ERROR, "Year could not be parsed from '%s'", reformatted);
20261       }
20262     } else {
20263       if (reformatted != NULL && isdigit (*reformatted)) {
20264         cp++;
20265         cp2 = StringChr (cp, '-');
20266         if (cp2 != NULL) {
20267           year = GetYearFromToken (cp2 + 1, StringLen (cp2 + 1));
20268           if (year < 1 && debug) {
20269             Message (MSG_ERROR, "Year could not be parsed from '%s'", cp2 + 1);
20270           }
20271         } else {
20272           if (debug) {
20273             Message (MSG_ERROR, "'%s' does not contain a - but does not start with a digit", reformatted);
20274           }
20275         }
20276       }
20277       else
20278       {
20279         year = GetYearFromToken (cp + 1, StringLen (cp + 1));
20280         if (year < 1 && debug) {
20281           Message (MSG_ERROR, "Year could not be parsed from '%s'", cp + 1);
20282         }
20283       }
20284     }
20285   }
20286   reformatted = MemFree (reformatted);
20287   return year;
20288 }
20289 
20290 
CheckStrainAgainstSerotypeAndCollectionDateProblems(IDAndTitleEditPtr iatep,CharPtr PNTR problems)20291 static void CheckStrainAgainstSerotypeAndCollectionDateProblems (IDAndTitleEditPtr iatep, CharPtr PNTR problems)
20292 {
20293   Int4 i, len, year;
20294   CharPtr strain, serotype, collection_date;
20295   CharPtr cp;
20296 
20297   if (iatep == NULL || problems == NULL) {
20298     return;
20299   }
20300 
20301   for (i = 0; i < iatep->num_sequences; i++) {
20302     strain = FindValueFromPairInDefline ("strain", iatep->title_list[i]);
20303     if (strain != NULL && (len = StringLen (strain)) > 0) {
20304       serotype = FindValueFromPairInDefline ("serotype", iatep->title_list[i]);
20305       collection_date = FindValueFromPairInDefline ("collection-date", iatep->title_list[i]);
20306       cp = StringRChr (strain, ')');
20307       if (cp == strain + len - 1) {
20308         *cp = 0;
20309         cp --;
20310         len--;
20311         cp = StringRChr (strain, '(');
20312         if (cp != NULL) {
20313           if (serotype != NULL && StringCmp (serotype, cp + 1) != 0) {
20314             SetStringValue (&(problems[i]), "serotype and strain conflict", ExistingTextOption_append_semi);
20315           }
20316           *cp = 0;
20317           TrimSpacesAroundString (strain);
20318           len = StringLen (strain);
20319         }
20320       }
20321       if (collection_date != NULL) {
20322         cp = StringRChr (strain, '/');
20323         if (cp != NULL && cp == strain + len - 5 && StringIsAllDigits(cp + 1)) {
20324           year = GetYearFromCollectionDateString (collection_date, FALSE);
20325           if (year != -1 && year != atoi (cp + 1)) {
20326             SetStringValue (&(problems[i]), "collection-date and strain conflict", ExistingTextOption_append_semi);
20327           }
20328         } else {
20329           SetStringValue (&(problems[i]), "error in strain format", ExistingTextOption_append_semi);
20330         }
20331       }
20332       serotype = MemFree (serotype);
20333       collection_date = MemFree (collection_date);
20334     }
20335     strain = MemFree (strain);
20336   }
20337 }
20338 
20339 
GetVirusQualifiersProblems(WizardTrackerPtr wiz)20340 static CharPtr PNTR GetVirusQualifiersProblems (WizardTrackerPtr wiz)
20341 {
20342   IDAndTitleEditPtr iatep;
20343   CharPtr PNTR      problems;
20344   CharPtr PNTR      unique_vals;
20345   CharPtr           val, tmp, dup_msg;
20346   ValNodePtr        unique_list = NULL;
20347   Boolean           any_segment = FALSE, any_strain = FALSE, any_isolate = FALSE;
20348   Int4              i;
20349 
20350   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
20351   problems = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences + 1));
20352   unique_vals = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences));
20353   if (wiz->virus_class == eVirusClass_Influenza) {
20354     any_strain = DoAnySequencesHaveModifierEx (iatep, "strain", NULL);
20355     if (!any_strain) {
20356       any_isolate = DoAnySequencesHaveModifierEx (iatep, "isolate", NULL);
20357     }
20358   } else {
20359     any_isolate = DoAnySequencesHaveModifierEx (iatep, "isolate", NULL);
20360     if (!any_isolate) {
20361       any_strain = DoAnySequencesHaveModifierEx (iatep, "strain", NULL);
20362     }
20363   }
20364   any_segment = DoAnySequencesHaveModifierEx (iatep, "segment", NULL);
20365 
20366   /* look for qualifiers that are required and missing */
20367   AddMissingProblems (iatep, wiz, problems, TRUE);
20368 
20369   if (wiz->virus_class == eVirusClass_Caliciviridae
20370       || wiz->virus_class == eVirusClass_Rotavirus
20371       || wiz->virus_class == eVirusClass_Influenza) {
20372     /* Caliciviridae, Rotavirus, and influenza require either host or isolation source */
20373     for (i = 0; i < iatep->num_sequences; i++) {
20374       val = FindValueFromPairInDefline ("host", iatep->title_list[i]);
20375       if (StringHasNoText (val)) {
20376         val = MemFree (val);
20377         val = FindValueFromPairInDefline ("isolation-source", iatep->title_list[i]);
20378       }
20379       if (StringHasNoText (val)) {
20380         SetStringValue (&(problems[i]), "Missing host or isolation-source", ExistingTextOption_append_semi);
20381       }
20382       val = MemFree (val);
20383     }
20384   }
20385 
20386   /* isolate/strain combined with segment needs to be unique */
20387   if (any_isolate || any_strain || any_segment) {
20388     for (i = 0; i < iatep->num_sequences; i++) {
20389       val = NULL;
20390       if (any_isolate) {
20391         val = FindValueFromPairInDefline ("isolate", iatep->title_list[i]);
20392       } else if (any_strain) {
20393         val = FindValueFromPairInDefline ("strain", iatep->title_list[i]);
20394       }
20395       if (any_segment) {
20396         tmp = FindValueFromPairInDefline("segment", iatep->title_list[i]);
20397         SetStringValue (&val, tmp, ExistingTextOption_append_semi);
20398         tmp = MemFree (tmp);
20399       }
20400       if (val != NULL) {
20401         ValNodeAddPointer (&unique_list, 0, val);
20402         unique_vals[i] = val;
20403       }
20404       val = NULL;
20405     }
20406     if (any_isolate) {
20407       if (any_segment) {
20408         dup_msg = "Duplicate isolate/segment combination";
20409       } else {
20410         dup_msg = "Duplicate isolate values";
20411       }
20412     } else if (any_strain) {
20413       if (any_segment) {
20414         dup_msg = "Duplicate strain/segment combination";
20415       } else {
20416         dup_msg = "Duplicate strain values";
20417       }
20418     } else {
20419       dup_msg = "Duplicate segment values";
20420     }
20421 
20422     AddDuplicateProblems (&unique_list, unique_vals, problems, iatep->num_sequences, dup_msg);
20423   }
20424 
20425   /* report format problems for required items */
20426   AddFormatProblems (iatep, wiz, problems, TRUE);
20427 
20428   /* now report missing (but not required) modifiers */
20429   AddMissingProblems (iatep, wiz, problems, FALSE);
20430 
20431   /* report format problems for non-required items */
20432   AddFormatProblems (iatep, wiz, problems, FALSE);
20433 
20434   if (wiz->virus_class == eVirusClass_Influenza) {
20435     CheckStrainAgainstSerotypeAndCollectionDateProblems (iatep, problems);
20436   }
20437 
20438   /* note - unique_vals and unique_list both reference the same allocated strings,
20439    * only need to free it once, do so in ValNodeFreeData of unique_list
20440    */
20441   unique_vals = MemFree (unique_vals);
20442   unique_list = ValNodeFreeData (unique_list);
20443 
20444   iatep = IDAndTitleEditFree (iatep);
20445 
20446   return problems;
20447 }
20448 
20449 
GetCulturedSamplesQualifiersProblems(WizardTrackerPtr wiz)20450 static CharPtr PNTR GetCulturedSamplesQualifiersProblems (WizardTrackerPtr wiz)
20451 {
20452   IDAndTitleEditPtr iatep;
20453   CharPtr PNTR      problems;
20454   Boolean           any_strain = FALSE, any_isolate = FALSE, all_org;
20455 
20456   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
20457   problems = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences + 1));
20458   if (wiz->cultured_kingdom == eCulturedKingdom_BacteriaArchea
20459       || wiz->cultured_kingdom == eCulturedKingdom_CulturedFungus) {
20460     any_strain = DoAnySequencesHaveModifierEx (iatep, "strain", NULL);
20461     if (!any_strain) {
20462       any_isolate = DoAnySequencesHaveModifierEx (iatep, "isolate", NULL);
20463     }
20464   }
20465 
20466   /* look for qualifiers that are required and missing */
20467   AddMissingProblems (iatep, wiz, problems, TRUE);
20468 
20469   /* strain or isolate needs to be unique */
20470   if (any_strain) {
20471     AddDuplicateSingleQualifierProblems (iatep, "strain", problems, "Duplicate strain values");
20472   } else if (any_isolate) {
20473     AddDuplicateSingleQualifierProblems (iatep, "isolate", problems, "Duplicate isolate values");
20474   }
20475 
20476   if (wiz->cultured_kingdom == eCulturedKingdom_Other) {
20477     if (DoAllSequencesHaveDifferentModifierValue (iatep, "organism")
20478         || HaveUniqueCombination(iatep, "organism", "isolate")
20479         || HaveUniqueCombination(iatep, "organism", "specimen-voucher")
20480         || HaveUniqueCombination(iatep, "organism", "cultivar"))
20481     {
20482       /* something is unique */
20483     }
20484     else
20485     {
20486       all_org = DoAllSequencesHaveModifier (iatep, "org");
20487       /* if there aren't all organisms yet, don't bother with uniqueness of everything else */
20488       if (all_org)
20489       {
20490         AddDuplicateSingleQualifierProblems (iatep, "isolate", problems, "Duplicate isolate values");
20491         AddDuplicateSingleQualifierProblems (iatep, "specimen-voucher", problems, "Duplicate specimen-voucher values");
20492         AddDuplicateSingleQualifierProblems (iatep, "cultivar", problems, "Duplicate cultivar values");
20493       }
20494     }
20495   } else if (wiz->cultured_kingdom == eCulturedKingdom_VoucheredFungus) {
20496     AddDuplicateSingleQualifierProblems (iatep, "specimen-voucher", problems, "Duplicate specimen-voucher values");
20497   }
20498 
20499   /* report format problems for required items */
20500   AddFormatProblems (iatep, wiz, problems, TRUE);
20501 
20502   /* report format problems for non-required items */
20503   AddFormatProblems (iatep, wiz, problems, FALSE);
20504 
20505   /* look for qualifiers that are not required, are missing, and should be listed */
20506   AddMissingProblems (iatep, wiz, problems, FALSE);
20507 
20508   iatep = IDAndTitleEditFree (iatep);
20509 
20510   return problems;
20511 }
20512 
20513 
StandardProblemListing(WizardTrackerPtr wiz)20514 static CharPtr PNTR StandardProblemListing (WizardTrackerPtr wiz)
20515 {
20516   IDAndTitleEditPtr iatep;
20517   CharPtr PNTR      problems;
20518 
20519   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
20520   problems = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences + 1));
20521 
20522   /* look for qualifiers that are required and missing */
20523   AddMissingProblems (iatep, wiz, problems, TRUE);
20524 
20525   /* report format problems for required items */
20526   AddFormatProblems (iatep, wiz, problems, TRUE);
20527 
20528   /* report format problems for non-required items */
20529   AddFormatProblems (iatep, wiz, problems, FALSE);
20530 
20531   /* look for qualifiers that are not required, are missing, and should be listed */
20532   AddMissingProblems (iatep, wiz, problems, FALSE);
20533 
20534   /* look for missing paired qualifiers */
20535   AddLinkedProblems (iatep, wiz, problems);
20536 
20537   iatep = IDAndTitleEditFree (iatep);
20538 
20539   return problems;
20540 }
20541 
20542 
GetTSAQualifiersProblems(WizardTrackerPtr wiz)20543 static CharPtr PNTR GetTSAQualifiersProblems (WizardTrackerPtr wiz)
20544 {
20545   return StandardProblemListing(wiz);
20546 }
20547 
20548 
GetIGSQualifiersProblems(WizardTrackerPtr wiz)20549 static CharPtr PNTR GetIGSQualifiersProblems (WizardTrackerPtr wiz)
20550 {
20551   return StandardProblemListing(wiz);
20552 }
20553 
20554 
GetMicrosatelliteQualifiersProblems(WizardTrackerPtr wiz)20555 static CharPtr PNTR GetMicrosatelliteQualifiersProblems (WizardTrackerPtr wiz)
20556 {
20557   return StandardProblemListing(wiz);
20558 }
20559 
20560 
GetDLoopQualifiersProblems(WizardTrackerPtr wiz)20561 static CharPtr PNTR GetDLoopQualifiersProblems (WizardTrackerPtr wiz)
20562 {
20563   IDAndTitleEditPtr iatep;
20564   Boolean           all_org, any_isolate, any_hap, any_spec;
20565   CharPtr PNTR      problems;
20566 
20567   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
20568   problems = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (iatep->num_sequences + 1));
20569 
20570   /* look for qualifiers that are required and missing */
20571   AddMissingProblems (iatep, wiz, problems, TRUE);
20572 
20573   /* report format problems for required items */
20574   AddFormatProblems (iatep, wiz, problems, TRUE);
20575 
20576   /* report format problems for non-required items */
20577   AddFormatProblems (iatep, wiz, problems, FALSE);
20578 
20579   /* look for qualifiers that are not required, are missing, and should be listed */
20580   AddMissingProblems (iatep, wiz, problems, FALSE);
20581 
20582   /* org or org in combination needs to be unique */
20583   if (DoAllSequencesHaveDifferentModifierValue (iatep, "organism")
20584       || HaveUniqueCombination(iatep, "organism", "isolate")
20585       || HaveUniqueCombination(iatep, "organism", "specimen-voucher")
20586       || HaveUniqueCombination(iatep, "organism", "haplotype"))
20587   {
20588     /* something is unique */
20589   }
20590   else
20591   {
20592     all_org = DoAllSequencesHaveModifier (iatep, "org");
20593     /* if there aren't all organisms yet, don't bother with uniqueness of everything else */
20594     if (all_org)
20595     {
20596       any_isolate = DoAnySequencesHaveModifierEx (iatep, "isolate", NULL);
20597       any_hap = DoAnySequencesHaveModifierEx (iatep, "haplotype", NULL);
20598       any_spec = DoAnySequencesHaveModifierEx (iatep, "specimen-voucher", NULL);
20599       if (any_isolate) {
20600         AddDuplicateSingleQualifierProblems (iatep, "isolate", problems, "Duplicate isolate values");
20601       }
20602       if (any_spec) {
20603         AddDuplicateSingleQualifierProblems (iatep, "specimen-voucher", problems, "Duplicate specimen-voucher values");
20604       }
20605       if (any_hap) {
20606         AddDuplicateSingleQualifierProblems (iatep, "haplotype", problems, "Duplicate haplotype values");
20607       }
20608       if (!any_isolate && !any_hap && !any_spec) {
20609         AddDuplicateSingleQualifierProblems (iatep, "org", problems, "Duplicate organism name values");
20610       }
20611     }
20612   }
20613   iatep = IDAndTitleEditFree (iatep);
20614 
20615   return problems;
20616 }
20617 
20618 
GetWizardQualifierProblems(WizardTrackerPtr wiz)20619 static CharPtr PNTR GetWizardQualifierProblems (WizardTrackerPtr wiz)
20620 {
20621   CharPtr PNTR problems = NULL;
20622   if (wiz == NULL) {
20623     return NULL;
20624   }
20625 
20626   switch (wiz->wizard_type) {
20627     case eWizardType_UnculturedSamples:
20628       problems = GetUnculturedQualifiersProblems (wiz);
20629       break;
20630     case eWizardType_Viruses:
20631       problems = GetVirusQualifiersProblems (wiz);
20632       break;
20633     case eWizardType_CulturedSamples:
20634       problems = GetCulturedSamplesQualifiersProblems (wiz);
20635       break;
20636     case eWizardType_IGS:
20637       problems = GetIGSQualifiersProblems (wiz);
20638       break;
20639     case eWizardType_Microsatellite:
20640       problems = GetMicrosatelliteQualifiersProblems (wiz);
20641       break;
20642     case eWizardType_DLoop:
20643       problems = GetDLoopQualifiersProblems (wiz);
20644       break;
20645   }
20646   return problems;
20647 }
20648 
20649 
UnculturedQualifiersOk(WizardTrackerPtr wiz)20650 static Boolean UnculturedQualifiersOk (WizardTrackerPtr wiz)
20651 {
20652   CharPtr bad_name;
20653   Boolean rval = TRUE;
20654   IDAndTitleEditPtr        iatep;
20655   Int4                     i;
20656   CharPtr                  val, host;
20657   Boolean                  all_present = TRUE, long_enough = TRUE, bad_val = FALSE;
20658 
20659   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
20660 
20661   /* All sequences _must_ have an organism, it _should_ start with 'uncultured' */
20662   if (DoAllOrgsStartWithUncultured (iatep)) {
20663     if ((bad_name = ModValInList(iatep, "org", sUnwiseSampleOrgNames)) != NULL) {
20664       if (ANS_CANCEL == Message (MSG_OKC, "'%s' is an ambiguous organism name.  If you know more information about the source organism, please provide it.  For example, if you know the organism is bacterial, the organism name should be \"uncultured bacterium\".  Are you sure you want to continue?", bad_name)) {
20665         rval = FALSE;
20666       }
20667     }
20668   } else if (!DoAllSequencesHaveModifier (iatep, "org")) {
20669     Message (MSG_ERROR, "You must fill in an organism name for every sequence!");
20670     rval = FALSE;
20671   } else if (ANS_CANCEL == Message (MSG_OKC, "Not all of your organism names start with 'uncultured' - are you sure you want to continue?")) {
20672     rval = FALSE;
20673   } else if ((bad_name = ModValInList(iatep, "org", sUnwiseSampleOrgNames)) != NULL) {
20674     if (ANS_CANCEL == Message (MSG_OKC, "'%s' is an ambiguous organism name.  If you know more information about the source organism, please provide it.  For example, if you know the organism is bacterial, the organism name should be \"uncultured bacterium\".  Are you sure you want to continue?", bad_name)) {
20675       rval = FALSE;
20676     }
20677   }
20678 
20679   /* only keep checking if we haven't already found a problem */
20680   if (rval && !DoAllSequencesHaveDifferentModifierValue (iatep, "clone")) {
20681     /* check for gel band isolates instead */
20682     if (DoAnySequencesHaveModifierEx (iatep, "isolate", IsGelBand)) {
20683       if (DoAllSequencesHaveModifierEx (iatep, "isolate", IsGelBand)) {
20684         if (DoAllSequencesHaveDifferentModifierValue (iatep, "isolate")) {
20685           /* ok - have different gel band isolate value for every sequence */
20686         } else {
20687           Message (MSG_ERROR, "You have duplicate gel band isolate values!");
20688           rval = FALSE;
20689         }
20690       } else {
20691         Message (MSG_ERROR, "You are missing some gel band isolate values!");
20692         rval = FALSE;
20693       }
20694     } else {
20695       Message (MSG_ERROR, "You must supply a unique clone value for every sequence!");
20696       rval = FALSE;
20697     }
20698   }
20699 
20700   if (rval) {
20701     /* isolation source or host must be present for all sequences, but doesn't have to be unique */
20702     for (i = 0; i < iatep->num_sequences; i++) {
20703       val = FindValueFromPairInDefline ("isolation-source", iatep->title_list[i]);
20704       if (StringHasNoText (val)) {
20705         host = FindValueFromPairInDefline ("host", iatep->title_list[i]);
20706         if (StringHasNoText (host)) {
20707           all_present = FALSE;
20708         }
20709         host = MemFree (host);
20710       } else if (StringLen (val) < 3) {
20711         long_enough = FALSE;
20712       } else if (ValueInList(val, sBadUnculturedIsolationSources)) {
20713         bad_val = TRUE;
20714       }
20715       val = MemFree (val);
20716     }
20717 
20718     if (!all_present) {
20719       Message (MSG_ERROR, "You must supply an isolation source or host for each sequence!");
20720       rval = FALSE;
20721     } else if (!long_enough) {
20722       if (ANS_CANCEL == Message (MSG_OKC, "isolation source should have a value like seawater, soil, etc.  At least one of your values is suspiciously short.  Are you sure you want to continue?")) {
20723         rval = FALSE;
20724       }
20725     }
20726     if (rval && bad_val) {
20727       Message (MSG_ERROR, "Isolation source should have a value like seawater, soil, etc. One or more of values you have provided are not valid. Please provide the isolation-source.");
20728       rval = FALSE;
20729     }
20730   }
20731 
20732   /* check for presence of strain */
20733   if (rval) {
20734     if (DoAnySequencesHaveModifier(iatep, "strain")) {
20735       if (ANS_CANCEL == Message (MSG_OKC, "You have included strain names for these uncultured samples.  Are you sure you want to continue?")) {
20736         rval = FALSE;
20737       }
20738     }
20739   }
20740 
20741   iatep = IDAndTitleEditFree (iatep);
20742 
20743   return rval;
20744 }
20745 
20746 
HaveOneWizardSrcQualOrTheOtherEx(IDAndTitleEditPtr iatep,CharPtr choice1,CharPtr choice2,Boolean only_suggest_first,Boolean require_unique)20747 static Boolean HaveOneWizardSrcQualOrTheOtherEx (IDAndTitleEditPtr iatep, CharPtr choice1, CharPtr choice2, Boolean only_suggest_first, Boolean require_unique)
20748 {
20749   Boolean rval = TRUE;
20750 
20751   if (DoAllSequencesHaveModifierEx (iatep, choice1, NULL)) {
20752     if (require_unique && !DoAllSequencesHaveDifferentModifierValue(iatep, choice1)) {
20753       Message (MSG_ERROR, "You must fill in a unique %s value for every sequence!", choice1);
20754       rval = FALSE;
20755     }
20756   } else if (DoAllSequencesHaveModifierEx (iatep, choice2, NULL)) {
20757     if (require_unique && !DoAllSequencesHaveDifferentModifierValue(iatep, choice2)) {
20758       Message (MSG_ERROR, "You must fill in a unique %s value for every sequence!", choice2);
20759       rval = FALSE;
20760     }
20761   } else {
20762     if (DoAnySequencesHaveModifierEx (iatep, choice1, NULL)) {
20763       Message (MSG_ERROR, "You are missing some %s values!", choice1);
20764     } else if (DoAnySequencesHaveModifierEx (iatep, choice2, NULL)) {
20765       Message (MSG_ERROR, "You are missing some %s values!", choice2);
20766     } else {
20767       if (only_suggest_first) {
20768         Message (MSG_ERROR, "You must fill in a %s value for every sequence!", choice1);
20769       } else {
20770         Message (MSG_ERROR, "You must fill in a %s value for every sequence or a %s value for every sequence!", choice1, choice2);
20771       }
20772     }
20773     rval = FALSE;
20774   }
20775   return rval;
20776 }
20777 
20778 
HaveOneWizardSrcQualOrTheOther(IDAndTitleEditPtr iatep,CharPtr choice1,CharPtr choice2)20779 static Boolean HaveOneWizardSrcQualOrTheOther (IDAndTitleEditPtr iatep, CharPtr choice1, CharPtr choice2)
20780 {
20781   return HaveOneWizardSrcQualOrTheOtherEx (iatep, choice1, choice2, FALSE, FALSE);
20782 }
20783 
20784 
EachSequenceHasOneWizardSrcQualOrTheOther(IDAndTitleEditPtr iatep,CharPtr choice1,CharPtr choice2)20785 static Boolean EachSequenceHasOneWizardSrcQualOrTheOther (IDAndTitleEditPtr iatep, CharPtr choice1, CharPtr choice2)
20786 {
20787   Int4    i;
20788   CharPtr val;
20789   Boolean rval = TRUE;
20790 
20791   for (i = 0; i < iatep->num_sequences && rval; i++) {
20792     val = FindValueFromPairInDefline (choice1, iatep->title_list[i]);
20793     if (StringHasNoText (val)) {
20794       val = MemFree (val);
20795       val = FindValueFromPairInDefline (choice2, iatep->title_list[i]);
20796     }
20797     if (StringHasNoText (val)) {
20798       rval = FALSE;
20799     }
20800     val = MemFree (val);
20801   }
20802   return rval;
20803 }
20804 
20805 
CheckValidationRules(WizardTrackerPtr wiz,Boolean required)20806 static Boolean CheckValidationRules (WizardTrackerPtr wiz, Boolean required)
20807 {
20808   ValNodePtr vnp;
20809   WizardSrcQualPtr q;
20810   IDAndTitleEditPtr iatep;
20811   CharPtr tmp;
20812   Int4 i;
20813   CharPtr val;
20814   Boolean rval = TRUE;
20815   Boolean bad_qual_found;
20816 
20817   /* look for validation functions that fail */
20818   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
20819   for (vnp = wiz->base_src_quals; vnp != NULL && rval; vnp = vnp->next) {
20820     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
20821     if (q->valid_func != NULL && ((required && q->valid_required) || (!required && !q->valid_required))) {
20822       bad_qual_found = FALSE;
20823       for (i = 0; i < iatep->num_sequences && rval && !bad_qual_found; i++) {
20824         val = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20825         tmp = (q->valid_func)(val, q->name, TRUE);
20826         val = MemFree (val);
20827         if (tmp != NULL) {
20828           if (ANS_CANCEL == Message (MSG_OKC, "%s Are you sure you want to continue?", tmp)) {
20829             rval = FALSE;
20830           }
20831           tmp = MemFree (tmp);
20832           bad_qual_found = TRUE;
20833         }
20834       }
20835     }
20836   }
20837   for (vnp = wiz->extra_src_quals; vnp != NULL && rval; vnp = vnp->next) {
20838     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
20839     if (q->valid_func != NULL && ((required && q->valid_required) || (!required && !q->valid_required))) {
20840       bad_qual_found = FALSE;
20841       for (i = 0; i < iatep->num_sequences && rval && !bad_qual_found; i++) {
20842         val = FindValueFromPairInDefline (q->name, iatep->title_list[i]);
20843         tmp = (q->valid_func)(val, q->name, TRUE);
20844         val = MemFree (val);
20845         if (tmp != NULL) {
20846           if (ANS_CANCEL == Message (MSG_OKC, "%s Are you sure you want to continue?", tmp)) {
20847             rval = FALSE;
20848           }
20849           tmp = MemFree (tmp);
20850           bad_qual_found = TRUE;
20851         }
20852       }
20853     }
20854   }
20855   iatep = IDAndTitleEditFree (iatep);
20856   return rval;
20857 }
20858 
20859 
CheckStrainAgainstSerotypeAndCollectionDate(IDAndTitleEditPtr iatep)20860 static CharPtr CheckStrainAgainstSerotypeAndCollectionDate (IDAndTitleEditPtr iatep)
20861 {
20862   Int4 i, len, year;
20863   CharPtr strain, serotype, collection_date;
20864   CharPtr cp;
20865   CharPtr rval = NULL;
20866 
20867   if (iatep == NULL) {
20868     return NULL;
20869   }
20870 
20871   for (i = 0; i < iatep->num_sequences && rval == NULL; i++) {
20872     strain = FindValueFromPairInDefline ("strain", iatep->title_list[i]);
20873     if (strain != NULL && (len = StringLen (strain)) > 0) {
20874       serotype = FindValueFromPairInDefline ("serotype", iatep->title_list[i]);
20875       collection_date = FindValueFromPairInDefline ("collection-date", iatep->title_list[i]);
20876       cp = StringRChr (strain, ')');
20877       if (cp == strain + len - 1) {
20878         *cp = 0;
20879         cp --;
20880         len--;
20881         cp = StringRChr (strain, '(');
20882         if (cp != NULL) {
20883           if (serotype != NULL && StringCmp (serotype, cp + 1) != 0) {
20884             rval = "Serotype and strain values conflict.";
20885           }
20886           *cp = 0;
20887           TrimSpacesAroundString (strain);
20888           len = StringLen (strain);
20889         }
20890       }
20891       if (collection_date != NULL) {
20892         cp = StringRChr (strain, '/');
20893         if (cp != NULL && cp == strain + len - 5 && StringIsAllDigits(cp + 1)) {
20894           year = GetYearFromCollectionDateString (collection_date, FALSE);
20895           if (year == -1) {
20896             rval = "Error in collection date format.";
20897             /* Message (MSG_ERROR, "Tried and failed to parse year from collection date string '%s'", collection_date); */
20898             /* year = GetYearFromCollectionDateString (collection_date, TRUE); */
20899           } else if (year != atoi (cp + 1)) {
20900             rval = "Collection-date and strain values conflict.";
20901           }
20902         } else {
20903           rval = "Error in strain format.";
20904         }
20905       }
20906       serotype = MemFree (serotype);
20907       collection_date = MemFree (collection_date);
20908     }
20909     strain = MemFree (strain);
20910   }
20911   return rval;
20912 }
20913 
20914 
VirusQualsOk(WizardTrackerPtr wiz)20915 static Boolean VirusQualsOk (WizardTrackerPtr wiz)
20916 {
20917   Boolean rval = TRUE;
20918   IDAndTitleEditPtr iatep;
20919   CharPtr errmsg;
20920 
20921   if (wiz == NULL) {
20922     return FALSE;
20923   }
20924 
20925   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
20926   if (!DoAllSequencesHaveModifier (iatep, "org")) {
20927     Message (MSG_ERROR, "You must fill in an organism name for every sequence!");
20928     rval = FALSE;
20929   }
20930   if (rval) {
20931     switch (wiz->virus_class) {
20932       case eVirusClass_Generic:
20933         rval = HaveOneWizardSrcQualOrTheOther (iatep, "isolate", "strain");
20934         break;
20935       case eVirusClass_FootAndMouth:
20936         rval = HaveOneWizardSrcQualOrTheOther (iatep, "isolate", "strain");
20937         break;
20938       case eVirusClass_Influenza:
20939         if (!HaveOneWizardSrcQualOrTheOther (iatep, "strain", "isolate")) {
20940           rval = FALSE;
20941         } else if (!EachSequenceHasOneWizardSrcQualOrTheOther(iatep, "host", "isolation-source")) {
20942           Message (MSG_ERROR, "Each sequence must have a host value or an isolation-source value");
20943           rval = FALSE;
20944         } else if (!DoAllSequencesHaveModifierEx (iatep, "collection-date", NULL)) {
20945           Message (MSG_ERROR, "You must fill in an collection-date value for every sequence!");
20946           rval = FALSE;
20947         } else if (!DoAllSequencesHaveModifierEx (iatep, "segment", NULL)) {
20948           Message (MSG_ERROR, "You must fill in an segment value for every sequence!");
20949           rval = FALSE;
20950         } else if (!DoAllSequencesHaveModifierEx (iatep, "country", NULL)) {
20951           Message (MSG_ERROR, "You must fill in a country value for every sequence!");
20952           rval = FALSE;
20953         } else {
20954           rval = TRUE;
20955         }
20956         break;
20957       case eVirusClass_Caliciviridae:
20958         if (!HaveOneWizardSrcQualOrTheOther (iatep, "isolate", "strain")) {
20959           rval = FALSE;
20960         } else if (!DoAllSequencesHaveModifierEx (iatep, "collection-date", NULL)) {
20961           Message (MSG_ERROR, "You must fill in an collection-date value for every sequence!");
20962           rval = FALSE;
20963         } else if (!DoAllSequencesHaveModifierEx (iatep, "country", NULL)) {
20964           Message (MSG_ERROR, "You must fill in a country value for every sequence!");
20965           rval = FALSE;
20966         } else if (!EachSequenceHasOneWizardSrcQualOrTheOther(iatep, "host", "isolation-source")) {
20967           Message (MSG_ERROR, "Each sequence must have a host value or an isolation-source value");
20968           rval = FALSE;
20969         } else {
20970           rval = TRUE;
20971         }
20972         break;
20973       case eVirusClass_Rotavirus:
20974         if (!HaveOneWizardSrcQualOrTheOther (iatep, "isolate", "strain")) {
20975           rval = FALSE;
20976         } else if (!DoAllSequencesHaveModifierEx (iatep, "collection-date", NULL)) {
20977           Message (MSG_ERROR, "You must fill in an collection-date value for every sequence!");
20978           rval = FALSE;
20979         } else if (!DoAllSequencesHaveModifierEx (iatep, "country", NULL)) {
20980           Message (MSG_ERROR, "You must fill in a country value for every sequence!");
20981           rval = FALSE;
20982         } else if (!EachSequenceHasOneWizardSrcQualOrTheOther(iatep, "host", "isolation-source")) {
20983           Message (MSG_ERROR, "Each sequence must have a host value or an isolation-source value");
20984           rval = FALSE;
20985         } else {
20986           rval = TRUE;
20987         }
20988         break;
20989     }
20990   }
20991 
20992   if (rval) {
20993     if (!HaveUniqueCombination(iatep, "isolate", "segment")
20994         && !HaveUniqueCombination(iatep, "strain", "segment")) {
20995       if (ANS_CANCEL == Message (MSG_OKC, "WARNING - We noticed you did not provide unique source information for all of your sequences. If you are submitting sequences from the same gene region from different isolates, please go back and provide unique source information.  Are you sure you want to continue?")) {
20996         rval = FALSE;
20997       }
20998     }
20999   }
21000 
21001   if (rval) {
21002     rval = CheckValidationRules(wiz, FALSE);
21003   }
21004 
21005   if (rval && wiz->virus_class == eVirusClass_Influenza) {
21006     errmsg = CheckStrainAgainstSerotypeAndCollectionDate (iatep);
21007     if (errmsg != NULL) {
21008       Message (MSG_ERROR, errmsg);
21009       rval = FALSE;
21010     }
21011   }
21012   iatep = IDAndTitleEditFree (iatep);
21013 
21014   return rval;
21015 }
21016 
21017 
CulturedSamplesOk(WizardTrackerPtr wiz)21018 static Boolean CulturedSamplesOk (WizardTrackerPtr wiz)
21019 {
21020   Boolean rval = TRUE;
21021   IDAndTitleEditPtr iatep;
21022   ValNodePtr        qual_list = NULL;
21023 
21024   if (wiz == NULL) {
21025     return FALSE;
21026   }
21027 
21028   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
21029 
21030   if (!DoAllSequencesHaveModifier (iatep, "org")) {
21031     Message (MSG_ERROR, "You must fill in an organism name for every sequence!");
21032     rval = FALSE;
21033   }
21034 
21035   if (rval) {
21036     switch (wiz->cultured_kingdom) {
21037       case eCulturedKingdom_BacteriaArchea:
21038         if (!HaveOneWizardSrcQualOrTheOtherEx (iatep, "strain", "isolate", TRUE, TRUE)) {
21039           rval = FALSE;
21040         }
21041         break;
21042       case eCulturedKingdom_CulturedFungus:
21043         if (!HaveOneWizardSrcQualOrTheOtherEx (iatep, "strain", "isolate", TRUE, TRUE)) {
21044           rval = FALSE;
21045         }
21046         break;
21047       case eCulturedKingdom_VoucheredFungus:
21048         ValNodeAddPointer (&qual_list, 0, "organism");
21049         ValNodeAddPointer (&qual_list, 0, "specimen-voucher");
21050         ValNodeAddPointer (&qual_list, 0, "isolate");
21051         ValNodeAddPointer (&qual_list, 0, "biomaterial");
21052         ValNodeAddPointer (&qual_list, 0, "culture-collection");
21053         if (!DoAllSequencesHaveDifferentModifierValue (iatep, "organism")
21054             && !HaveUniqueCombinationOfQuals(iatep, qual_list)) {
21055           Message (MSG_ERROR, "Must have unique organism name or unique combination of organism name and specimen-voucher or unique combination of organism name, specimen voucher, and isolate!");
21056           rval = FALSE;
21057         }
21058         qual_list = ValNodeFree (qual_list);
21059         break;
21060       case eCulturedKingdom_Other:
21061         /* require either unique organism names, isolate, specimen-voucher, or cultivar */
21062         if (!DoAllSequencesHaveDifferentModifierValue (iatep, "organism")
21063             && !HaveUniqueCombination(iatep, "organism", "isolate")
21064             && !HaveUniqueCombination(iatep, "organism", "specimen-voucher")
21065             && !HaveUniqueCombination(iatep, "organism", "cultivar"))
21066         {
21067           Message (MSG_ERROR, "Must have unique organism name or unique combination of organism name and isolate, specimen-voucher, or cultivar for every sequence!");
21068           rval = FALSE;
21069         }
21070         break;
21071     }
21072   }
21073 
21074   if (rval) {
21075     rval = CheckValidationRules(wiz, FALSE);
21076   }
21077   iatep = IDAndTitleEditFree (iatep);
21078   return rval;
21079 }
21080 
21081 
IGSQualsOk(WizardTrackerPtr wiz)21082 static Boolean IGSQualsOk (WizardTrackerPtr wiz)
21083 {
21084   Boolean rval = TRUE;
21085   IDAndTitleEditPtr iatep;
21086   ValNodePtr qual_list = NULL;
21087 
21088   if (wiz == NULL) {
21089     return FALSE;
21090   }
21091 
21092   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
21093   if (!DoAllSequencesHaveModifier (iatep, "org")) {
21094     Message (MSG_ERROR, "You must fill in an organism name for every sequence!");
21095     rval = FALSE;
21096   }
21097 
21098   if (rval) {
21099     if (wiz->igs_source_type == eIGSSourceType_CulturedFungus) {
21100       if (!HaveOneWizardSrcQualOrTheOtherEx (iatep, "strain", "isolate", TRUE, TRUE)) {
21101         rval = FALSE;
21102       }
21103     } else if (wiz->igs_source_type == eIGSSourceType_VoucheredFungus) {
21104       ValNodeAddPointer (&qual_list, 0, "organism");
21105       ValNodeAddPointer (&qual_list, 0, "specimen-voucher");
21106       ValNodeAddPointer (&qual_list, 0, "isolate");
21107       ValNodeAddPointer (&qual_list, 0, "biomaterial");
21108       ValNodeAddPointer (&qual_list, 0, "culture-collection");
21109       if (!DoAllSequencesHaveDifferentModifierValue (iatep, "organism")
21110           && !HaveUniqueCombinationOfQuals(iatep, qual_list)) {
21111         Message (MSG_ERROR, "Must have unique organism name or unique combination of organism name and specimen-voucher or unique combination of organism name, specimen voucher, and isolate!");
21112         rval = FALSE;
21113       }
21114       qual_list = ValNodeFree (qual_list);
21115     } else {
21116       /* require either unique organism names, isolate, specimen-voucher, or cultivar */
21117       if (!DoAllSequencesHaveDifferentModifierValue (iatep, "organism")
21118           && !HaveUniqueCombination(iatep, "organism", "isolate")
21119           && !HaveUniqueCombination(iatep, "organism", "specimen-voucher")
21120           && !HaveUniqueCombination(iatep, "organism", "cultivar")
21121           && !HaveUniqueCombination(iatep, "organism", "biomaterial")
21122           && !HaveUniqueCombination(iatep, "organism", "culture-collection"))
21123       {
21124         Message (MSG_ERROR, "Must have unique organism name or unique combination of organism name and isolate, specimen-voucher, or cultivar for every sequence!");
21125         rval = FALSE;
21126       }
21127     }
21128   }
21129 
21130   if (rval) {
21131     rval = CheckValidationRules(wiz, FALSE);
21132   }
21133   iatep = IDAndTitleEditFree (iatep);
21134   return rval;
21135 }
21136 
21137 
StandardQualChecks(WizardTrackerPtr wiz)21138 static Boolean StandardQualChecks (WizardTrackerPtr wiz)
21139 {
21140   IDAndTitleEditPtr iatep;
21141   WizardSrcQualPtr q;
21142   ValNodePtr vnp;
21143   Boolean    rval = TRUE;
21144 
21145   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
21146 
21147   for (vnp = wiz->base_src_quals; vnp != NULL && rval; vnp = vnp->next) {
21148     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
21149     if (q->required && !DoAllSequencesHaveModifier (iatep, q->name)) {
21150       Message (MSG_ERROR, "You must fill in %s for every sequence!", q->name);
21151       rval = FALSE;
21152     }
21153   }
21154 
21155   for (vnp = wiz->base_src_quals; vnp != NULL && rval; vnp = vnp->next) {
21156     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
21157     if (!q->required && DoAnySequencesHaveModifier (iatep, q->name) && !DoAllSequencesHaveModifier (iatep, q->name)) {
21158       if (ANS_CANCEL == Message (MSG_OKC, "You have provided %s values for some but not all of your sequences.  Are you sure you want to continue?", q->name)) {
21159         rval = FALSE;
21160       }
21161     }
21162   }
21163 
21164   for (vnp = wiz->extra_src_quals; vnp != NULL && rval; vnp = vnp->next) {
21165     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
21166     if (DoAnySequencesHaveModifier (iatep, q->name) && !DoAllSequencesHaveModifier (iatep, q->name)) {
21167       if (ANS_CANCEL == Message (MSG_OKC, "You have provided %s values for some but not all of your sequences.  Are you sure you want to continue?", q->name)) {
21168         rval = FALSE;
21169       }
21170     }
21171   }
21172 
21173   if (rval) {
21174     rval = CheckValidationRules(wiz, FALSE);
21175   }
21176 
21177   if (rval) {
21178     rval = ValidateLinkedQuals (iatep, wiz);
21179   }
21180   iatep = IDAndTitleEditFree (iatep);
21181 
21182   return rval;
21183 }
21184 
21185 
MicrosatelliteQualsOk(WizardTrackerPtr wiz)21186 static Boolean MicrosatelliteQualsOk (WizardTrackerPtr wiz)
21187 {
21188   Boolean           rval = FALSE;
21189   IDAndTitleEditPtr iatep;
21190 
21191   if (StandardQualChecks(wiz)) {
21192     iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
21193     rval = DoAllSequencesHaveDifferentModifierValue (iatep, "clone");
21194     if (!rval) {
21195       Message (MSG_ERROR, "You must provide unique clone values!");
21196     }
21197 
21198     iatep = IDAndTitleEditFree (iatep);
21199   }
21200   return rval;
21201 }
21202 
21203 
DLoopQualsOk(WizardTrackerPtr wiz)21204 static Boolean DLoopQualsOk (WizardTrackerPtr wiz)
21205 {
21206   IDAndTitleEditPtr iatep;
21207   Boolean    rval = TRUE;
21208 
21209   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
21210 
21211   /* require either unique organism names, isolate, specimen-voucher, or cultivar */
21212   if (!DoAllSequencesHaveDifferentModifierValue (iatep, "organism")
21213       && !HaveUniqueCombination(iatep, "organism", "isolate")
21214       && !HaveUniqueCombination(iatep, "organism", "haplotype")
21215       && !HaveUniqueCombination(iatep, "organism", "specimen-voucher"))
21216   {
21217     Message (MSG_ERROR, "Must have unique organism name or unique combination of organism name and isolate, haplotype, or specimen-voucher for every sequence!");
21218     rval = FALSE;
21219   }
21220   iatep = IDAndTitleEditFree (iatep);
21221   if (rval) {
21222     rval = StandardQualChecks(wiz);
21223   }
21224   return rval;
21225 }
21226 
21227 
TSASrcQualsOk(WizardTrackerPtr wiz)21228 static Boolean TSASrcQualsOk (WizardTrackerPtr wiz)
21229 {
21230   Boolean rval = TRUE;
21231   IDAndTitleEditPtr iatep;
21232 
21233   if (wiz == NULL) {
21234     return FALSE;
21235   }
21236 
21237   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
21238   if (!DoAllSequencesHaveModifier (iatep, "org")) {
21239     Message (MSG_ERROR, "You must fill in an organism name for every sequence!");
21240     rval = FALSE;
21241   } else if (!DoAllSequencesHaveASourceQualOtherThanTaxname(iatep)) {
21242     if (Message (MSG_YN, "The library information should be annotated on the source feature.  For example, please include dev-stage, cell-line, cell-type, cultivar, or tissue-type if available.  Would you like to add more information about your source?") == ANS_YES) {
21243       rval = FALSE;
21244     }
21245   }
21246   iatep = IDAndTitleEditFree (iatep);
21247   return rval;
21248 }
21249 
21250 
AllQualsMatch(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz)21251 static Boolean AllQualsMatch (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz)
21252 {
21253   WizardSrcQualPtr q;
21254   ValNodePtr vnp;
21255   Boolean    rval = TRUE;
21256 
21257   for (vnp = wiz->base_src_quals; vnp != NULL && rval; vnp = vnp->next) {
21258     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
21259     if (!DoAllSequencesHaveSameModiferValueIfPresent (iatep, q->name)) {
21260       Message (MSG_ERROR, "You must provide the same value of %s for every sequence!", q->name);
21261       rval = FALSE;
21262     }
21263   }
21264 
21265   for (vnp = wiz->extra_src_quals; vnp != NULL && rval; vnp = vnp->next) {
21266     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
21267     if (q->show && !DoAllSequencesHaveSameModiferValueIfPresent (iatep, q->name)) {
21268       Message (MSG_ERROR, "You must provide the same value of %s for every sequence!", q->name);
21269       rval = FALSE;
21270     }
21271   }
21272 
21273   return rval;
21274 }
21275 
21276 
WGSQualsOk(WizardTrackerPtr wiz)21277 static Boolean WGSQualsOk (WizardTrackerPtr wiz)
21278 {
21279   Boolean rval = TRUE;
21280   IDAndTitleEditPtr iatep;
21281   CharPtr val;
21282   Boolean has_one = FALSE;
21283   CharPtr mutually_exclusive[] = {"strain", "breed", "isolate", "cultivar", NULL};
21284   Int4 i;
21285 
21286   if (wiz == NULL) {
21287     return FALSE;
21288   }
21289 
21290   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
21291 
21292   rval = AllQualsMatch (iatep, wiz);
21293   if (rval) {
21294     if (wiz->wgs_source_type == eWGSSourceType_Bacteria || wiz->wgs_source_type == eWGSSourceType_Fungi) {
21295       if (!DoAllSequencesHaveModifier (iatep, "host")
21296           && !DoAllSequencesHaveModifier (iatep, "isolation-source")
21297           && !DoAllSequencesHaveModifier (iatep, "culture collection")) {
21298         Message (MSG_ERROR, "You must provide host, isolation-source, or culture collection.");
21299         rval = FALSE;
21300       }
21301     } else {
21302       if (!DoAllSequencesHaveModifier (iatep, "host")
21303           && !DoAllSequencesHaveModifier (iatep, "isolation-source")) {
21304         Message (MSG_ERROR, "You must provide host or isolation-source.");
21305         rval = FALSE;
21306       }
21307     }
21308   }
21309   if (rval && wiz->wgs_source_type != eWGSSourceType_Bacteria) {
21310     if (!DoAllSequencesHaveModifier (iatep, "strain")
21311         && !DoAllSequencesHaveModifier (iatep, "specimen-voucher")
21312         && !DoAllSequencesHaveModifier (iatep, "isolate")) {
21313       Message (MSG_ERROR, "You must provide strain, specimen-voucher, or isolate.");
21314       rval = FALSE;
21315     }
21316   }
21317 
21318   /* strain, breed, isolate & cultivar are mutually exclusive */
21319   for (i = 0; mutually_exclusive[i] != NULL && rval; i++) {
21320     val = FindValueFromPairInDefline (mutually_exclusive[i], iatep->title_list[0]);
21321     if (!StringHasNoText (val)) {
21322       if (has_one) {
21323         Message (MSG_ERROR, "Strain, breed, isolate and cultivar are mutually exclusive.  You should only provide one of these.");
21324         rval = FALSE;
21325       } else {
21326         has_one = TRUE;
21327       }
21328     }
21329     val = MemFree (val);
21330   }
21331 
21332   iatep = IDAndTitleEditFree (iatep);
21333   if (rval) {
21334     rval = StandardQualChecks(wiz);
21335   }
21336   return rval;
21337 }
21338 
21339 
WizardSrcQualsOk(WizardTrackerPtr wiz)21340 static Boolean WizardSrcQualsOk (WizardTrackerPtr wiz)
21341 {
21342   Boolean rval = FALSE;
21343 
21344   if (wiz == NULL) {
21345     return FALSE;
21346   }
21347   switch (wiz->wizard_type) {
21348     case eWizardType_UnculturedSamples:
21349       rval = UnculturedQualifiersOk (wiz);
21350       break;
21351     case eWizardType_Viruses:
21352       rval = VirusQualsOk (wiz);
21353       break;
21354     case eWizardType_CulturedSamples:
21355       rval = CulturedSamplesOk (wiz);
21356       break;
21357     case eWizardType_IGS:
21358       rval = IGSQualsOk(wiz);
21359       break;
21360     case eWizardType_Microsatellite:
21361       rval = MicrosatelliteQualsOk(wiz);
21362       break;
21363     case eWizardType_DLoop:
21364       rval = DLoopQualsOk (wiz);
21365       break;
21366     case eWizardType_WGS:
21367       rval = WGSQualsOk (wiz);
21368       break;
21369   }
21370   return rval;
21371 }
21372 
21373 
RecheckUnculturedSourceErrors(ButtoN b)21374 static void RecheckUnculturedSourceErrors(ButtoN b)
21375 {
21376   WizardSrcQualsFormPtr frm;
21377 
21378   frm = (WizardSrcQualsFormPtr) GetObjectExtra (b);
21379   if (frm == NULL) {
21380     return;
21381   }
21382 
21383   MultiModTableToSeqEntryList (frm->wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
21384   SeqEntryToMultiModTabTable (frm->wiz, frm->qual_table, frm->mod_names, frm->num_mods,
21385                               GetWizardQualifierProblems, ShouldShowAll((WizardQualsFormPtr)frm));
21386 }
21387 
21388 
21389 static CharPtr s_UnculturedSrcTblHelpMsgs[] = {
21390 "\
21391 -------------------------\n\
21392 Importing a Source Table:\n\
21393 -------------------------\n\
21394 -Use the �Import Source Table� button to import a tab-delimited table\n\
21395  of the organism names, clone names, isolation source, and other relevant\n\
21396  source information (such as Country, Lat-lon, Collection_date, etc.).\n\
21397  \n\
21398 -The source table can be prepared in a spreadsheet program and saved as\n\
21399  tab-delimited text.  Saving as tab-delimited text is found in some programs\n\
21400 ",
21401 "\
21402  by selecting \"other format types\" and selecting the a tab-delimited file\n\
21403  type when saving your file.\n\
21404  \n\
21405 -Preparing the Source Table:\n\
21406  The first column in the table must contain the SeqIDs. \n\
21407  There must be a header row with the column labels.\n\
21408  The source information for each record follows on the rows \n\
21409  below the header line, like the following example.\n\
21410 \n\
21411 -------------------------------------------------------\n\
21412 ",
21413 "\
21414 Example Source Table:\n\
21415 Use the horizontal scroll bar to see more of the table.\n\
21416 -------------------------------------------------------\n\
21417 SeqID\tOrganism\tclone\tisolation_source\tcountry\tlat-lon\tFwd-PCR-primer-name\tFwd-PCR-primer-seq\tRev-PCR-primer-name\tRev-PCR-primer-seq\n\
21418 ABC1\tuncultured Genus sp.\tABC1\tsoil\tGreenland\t70.00 N 54.01 W\tExamplePrimer1-F\tTTTTTAAAATTGGGGGC\tExamplePrimer1-R\tAAAATTTTAAGGGGAC\n\
21419 ABC2\tuncultured Genus sp.\tABC2\tsoil\tGreenland\t70.00 N 54.01 W\t1Primer1-F, 2Primer-F\tTTTTTAAA, GGAATTTA\t1Primer-R, 2Primer-R\tAAAATTTT, GGAATT\n\
21420 \n\
21421 --------------------\n\
21422 Formatting examples:\n\
21423 --------------------\n\
21424 ",
21425 "\
21426 -DGGE/TGGE samples: If your sequences were isolated using DGGE or TGGE techniques, \n\
21427  the clone names need to be formatted like this: DGGE gel band <sample ID> \n\
21428  or TGGE gel band <sample ID>\n\
21429  For example, a gel band with a sample ID of A01 would have \"DGGE gel band A01\" in the\n\
21430  clone field.  We will convert the clone value to isolate for you during processing.\n\
21431 \n\
21432 -Host: Use the binomial name of the host, if known, followed by other \n\
21433  information relating to the host, such as age, sex, breed, cultivar, etc. \n\
21434  For example-\n\
21435  Homo sapiens\n\
21436 ",
21437 "\
21438  Homo sapiens; female; 56 years\n\
21439  Solanum lycopersicum cv. Micro-Tom\n\
21440  Canis sp.\n\
21441 \n\
21442 -Country: use the following format-\n\
21443  Country: free text with more specific geographic information, if known.\n\
21444  For example-\n\
21445  Australia: 5 km south of Sydney\n\
21446  Madagascar\n\
21447  Brazil: Rio de Janeiro\n\
21448 ",
21449 "\
21450 \n\
21451 -Collection-date: use one of the following formats-\n\
21452  DD-MMM-YYYY\n\
21453  MMM-YYYY\n\
21454  YYYY\n\
21455  For example-\n\
21456  09-Aug-1985\n\
21457  Dec-2008\n\
21458  2008\n\
21459 \n\
21460 ",
21461 "\
21462 -Latitude-Longitude (lat_lon): use decimal degree format.\n\
21463  If you are providing Country information, the country should agree with the lat_lon value.\n\
21464  The first number should refer to the latitude (north/south) and the second to the longitude (east/west).\n\
21465  For example-\n\
21466  70.01 N 54.01 W\n\
21467 \n\
21468 -Primers: Please only provide the primers that were used the PCR amplify your sample. \n\
21469  Do not provide sequencing primers.\n\
21470  If you are providing multiple primers, separate the primer seqs and/or names with a comma.\n\
21471  See the example source table for a formatting example.\n\
21472 ", NULL};
21473 
21474 
21475 static CharPtr s_VirusSrcTblHelpMsgs[] = {
21476 "\
21477 -------------------------\n\
21478 Importing a Source Table:\n\
21479 -------------------------\n\
21480 - Use the \"Import Source Table\" button to import a tab-delimited table\n\
21481   of the organism names, clone names, isolation source, and other relevant\n\
21482   source information (such as primers, Lat-lon, etc.).\n\
21483 \n\
21484 - Use a spreadsheet program to prepare your source table: \n\
21485   The source table can be prepared in a spreadsheet program and saved as  \n\
21486 ",
21487 "\
21488   tab-delimited text.  Saving as tab-delimited text is found in some \n\
21489   programs by selecting \"other format types\" and selecting the a \n\
21490   tab-delimited file type when saving your file.\n\
21491 \n\
21492 - Preparing the Source Table:\n\
21493   The first column in the table must contain the SeqIDs. \n\
21494   There must be a header row with the column labels.\n\
21495   The source information for each record follows on the rows \n\
21496   below the header line, like the following example.\n\
21497 \n\
21498 ",
21499 "\
21500 -------------------------------------------------------\n\
21501 Example Source Table\n\
21502 Use the horizontal scroll bar to see more of the table.\n\
21503 -------------------------------------------------------\n\
21504 SeqID\tOrganism\tisolate\thost\tcollection_date\tcountry\tgenotype\tFwd-PCR-primer-name\tFwd-PCR-primer-seq\tRev-PCR-primer-name\tRev-PCR-primer-seq\n\
21505 ABC1\tRotavirus A\tABC1\tHomo sapiens\t01-Jun-2009\tChina: Beijing\tG1P\tExamplePrimer1-F\tTTTTTAAAATTGGGGGC\tExamplePrimer1-R\tAAAATTTTAAGGGGAC\n\
21506 ABC2\tRotavirus A\tABC2\tHomo sapiens\t05-Nov-2001\tMalaysia\tG1P\t1Primer1-F, 2Primer-F\tTTTTTAAA, GGAATTTA\t1Primer-R, 2Primer-R\tAAAATTTT, GGAATT\n\
21507 \n\
21508 --------------------\n\
21509 Formatting examples:\n\
21510 ",
21511 "\
21512 --------------------\n\
21513 - Collection-date: use one of the following formats-\n\
21514   DD-MMM-YYYY\n\
21515   MMM-YYYY\n\
21516   YYYY\n\
21517   For example-\n\
21518   09-Aug-1985\n\
21519   Dec-2008\n\
21520   2008\n\
21521 \n\
21522 ",
21523 "\
21524 - Country: use the following format-\n\
21525   Country: free text with more specific geographic information, if known.\n\
21526   For example-\n\
21527   Australia: 5 km south of Sydney\n\
21528   Madagascar\n\
21529   Brazil: Rio de Janeiro\n\
21530 \n\
21531 - Host: Use the binomial name of the host, if known, followed by other \n\
21532   information relating to the host, such as age, sex, breed, cultivar, etc. \n\
21533   For example-\n\
21534 ",
21535 "\
21536   Homo sapiens\n\
21537   Homo sapiens; female; 56 years\n\
21538   Solanum lycopersicum cv. Micro-Tom\n\
21539   Canis sp.\n\
21540 \n\
21541 - Primers: Please only provide the primers that were used the PCR amplify your sample. \n\
21542   Do not provide sequencing primers.\n\
21543   If you are providing multiple primers, separate the primer seqs and/or names with a comma.\n\
21544   See the example source table for a formatting example.\n\
21545 ", NULL};
21546 
21547 static CharPtr s_CulturedBactFungusSrcTblHelpMsgs[] = {
21548 "\
21549 -------------------------\n\
21550 Importing a Source Table:\n\
21551 -------------------------\n\
21552 -Use the �Import Source Table� button to import a tab-delimited table\n\
21553  of the organism names, strain names, isolation source, and other relevant\n\
21554  source information (such as Country, Lat-lon, Collection_date, etc.).\n\
21555  \n\
21556 -The source table can be prepared in a spreadsheet program and saved as\n\
21557  tab-delimited text.  Saving as tab-delimited text is found in some programs\n\
21558 ",
21559 "\
21560  by selecting \"other format types\" and selecting the a tab-delimited file\n\
21561  type when saving your file.\n\
21562  \n\
21563 -Preparing the Source Table:\n\
21564  The first column in the table must contain the SeqIDs. \n\
21565  There must be a header row with the column labels.\n\
21566  The source information for each record follows on the rows \n\
21567  below the header line, like the following example.\n\
21568 \n\
21569 -------------------------------------------------------\n\
21570 ",
21571 "\
21572 Example Source Table:\n\
21573 Use the horizontal scroll bar to see more of the table.\n\
21574 -------------------------------------------------------\n\
21575 SeqID\tOrganism\tstrain\tisolation_source\tcountry\tlatitude-longitude\tFwd-PCR-primer-name\tFwd-PCR-primer-seq\tRev-PCR-primer-name\tRev-PCR-primer-seq\n\
21576 ABC1\tGenus sp.\tABC1\tsoil from 90 cm depth\tGreenland\t70.00 N 54.01 W\tExamplePrimer1-F\tTTTTTAAAATTGGGGGC\tExamplePrimer1-R\tAAAATTTTAAGGGGAC\n\
21577 ABC2\tGenus sp.\tABC2\tsoil from 90 cm depth\tGreenland\t70.00 N 54.01 W\t1Primer1-F, 2Primer-F\tTTTTTAAA, GGAATTTA\t1Primer-R, 2Primer-R\tAAAATTTT, GGAATT\n\
21578 \n\
21579 --------------------\n\
21580 Formatting examples:\n\
21581 --------------------\n\
21582 ",
21583 "\
21584 -Primers: Please only provide the primers that were used the PCR amplify your sample. \n\
21585  Do not provide sequencing primers.\n\
21586  If you are providing multiple primers, separate the primer seqs and/or names with a comma.\n\
21587  See the example source table for a formatting example.\n\
21588 \n\
21589 -Country: use the following format-\n\
21590  Country: free text with more specific geographic information, if known.\n\
21591  For example-\n\
21592  Australia: 5 km south of Sydney\n\
21593  Madagascar\n\
21594 ",
21595 "\
21596  Brazil: Rio de Janeiro\n\
21597 \n\
21598 -Collection-date: use one of the following formats-\n\
21599  DD-MMM-YYYY\n\
21600  MMM-YYYY\n\
21601  YYYY\n\
21602  For example-\n\
21603  09-Aug-1985\n\
21604  Dec-2008\n\
21605  2008\n\
21606 ",
21607 "\
21608 \n\
21609 -Host: Use the binomial name of the host, if known, followed by other \n\
21610  information relating to the host, such as age, sex, breed, cultivar, etc. \n\
21611  For example-\n\
21612  Homo sapiens\n\
21613  Homo sapiens; female; 56 years\n\
21614  Solanum lycopersicum cv. Micro-Tom\n\
21615  Canis sp.\n\
21616 \n\
21617 -Latitude-Longitude (lat_lon): use decimal degree format.\n\
21618 ",
21619 "\
21620  If you are providing Country information, the country should agree with the lat_lon value.\n\
21621  The first number should refer to the latitude (north/south) and the second to the longitude (east/west).\n\
21622  For example-\n\
21623  70.01 N 54.01 W\n\
21624 \n\
21625 ", NULL};
21626 
21627 static CharPtr s_CulturedOtherSrcTblHelpMsgs[] = {
21628 "\
21629 -------------------------\n\
21630 Importing a Source Table:\n\
21631 -------------------------\n\
21632 -Use the �Import Source Table� button to import a tab-delimited table\n\
21633  of the organism names, strain names, isolation source, and other relevant\n\
21634  source information (such as Country, Lat-lon, Collection_date, etc.).\n\
21635  \n\
21636 -The source table can be prepared in a spreadsheet program and saved as\n\
21637  tab-delimited text.  Saving as tab-delimited text is found in some programs\n\
21638 ",
21639 "\
21640  by selecting \"other format types\" and selecting the a tab-delimited file\n\
21641  type when saving your file.\n\
21642  \n\
21643 -Preparing the Source Table:\n\
21644  The first column in the table must contain the SeqIDs. \n\
21645  There must be a header row with the column labels.\n\
21646  The source information for each record follows on the rows \n\
21647  below the header line, like the following example.\n\
21648 \n\
21649 -------------------------------------------------------\n\
21650 ",
21651 "\
21652 Example Source Table:\n\
21653 Use the horizontal scroll bar to see more of the table.\n\
21654 -------------------------------------------------------\n\
21655 SeqID\tOrganism\tisolate\tlatitude-longitude\tFwd-PCR-primer-name\tFwd-PCR-primer-seq\tRev-PCR-primer-name\tRev-PCR-primer-seq\tCountry \n\
21656 ABC1\tGenus sp.\tABC1\t32.64 S 115.77 E\tExamplePrimer1-F\tTTTTTAAAATTGGGGGC\tExamplePrimer1-R\tAAAATTTTAAGGGGAC\tAustralia: Austin Bay Nature Reserve\n\
21657 ABC2\tGenus sp.\tABC2\t32.64 S 115.77 E\t1Primer1-F, 2Primer-F\tTTTTTAAA, GGAATTTA\t1Primer-R, 2Primer-R\tAAAATTTT, GGAATT\tAustralia: Austin Bay Nature Reserve\n\
21658 \n\
21659 --------------------\n\
21660 Formatting examples:\n\
21661 --------------------\n\
21662 ",
21663 "\
21664 -Primers: Please only provide the primers that were used the PCR amplify your sample. \n\
21665  Do not provide sequencing primers.\n\
21666  If you are providing multiple primers, separate the primer seqs and/or names with a comma.\n\
21667  See the example source table for a formatting example.\n\
21668 \n\
21669 -Country: use the following format-\n\
21670  Country: free text with more specific geographic information, if known.\n\
21671  For example-\n\
21672  Australia: 5 km south of Sydney\n\
21673  Madagascar\n\
21674 ",
21675 "\
21676  Brazil: Rio de Janeiro\n\
21677 \n\
21678 -Collection-date: use one of the following formats-\n\
21679  DD-MMM-YYYY\n\
21680  MMM-YYYY\n\
21681  YYYY\n\
21682  For example-\n\
21683  09-Aug-1985\n\
21684  Dec-2008\n\
21685  2008\n\
21686 ",
21687 "\
21688 \n\
21689 -Host: Use the binomial name of the host, if known, followed by other \n\
21690  information relating to the host, such as age, sex, breed, cultivar, etc. \n\
21691  For example-\n\
21692  Homo sapiens\n\
21693  Homo sapiens; female; 56 years\n\
21694  Solanum lycopersicum cv. Micro-Tom\n\
21695  Canis sp.\n\
21696 \n\
21697 -Latitude-Longitude (lat_lon): use decimal degree format.\n\
21698 ",
21699 "\
21700  If you are providing Country information, the country should agree with the lat_lon value.\n\
21701  The first number should refer to the latitude (north/south) and the second to the longitude (east/west).\n\
21702  For example-\n\
21703  70.01 N 54.01 W\n\
21704 \n\
21705 \n\
21706 ", NULL};
21707 
21708 
21709 static CharPtr s_TSASrcTblHelpMsgs[] = {
21710 "\
21711 -------------------------\n\
21712 Importing a Source Table:\n\
21713 -------------------------\n\
21714 -Use the \"Import Source Table\" button to import a tab-delimited table\n\
21715  of the organism names and other relevant source information (such as \n\
21716  dev-stage, cell-line, cell-type, cultivar, tissue-type, etc.).\n\
21717  \n\
21718 -The source table can be prepared in a spreadsheet program and saved as\n\
21719  tab-delimited text.  Saving as tab-delimited text is found in some programs\n\
21720 ",
21721 "\
21722  by selecting \"other format types\" and selecting the a tab-delimited file\n\
21723  type when saving your file.\n\
21724  \n\
21725 -Preparing the Source Table:\n\
21726  The first column in the table must contain the SeqIDs. \n\
21727  There must be a header row with the column labels.\n\
21728  The source information for each record follows on the rows \n\
21729  below the header line, like the following example.\n\
21730 \n\
21731 -------------------------------------------------------\n\
21732 ",
21733 "\
21734 Example Source Table:\n\
21735 -------------------------------------------------------\n\
21736 SeqID   Organism        dev-stage       cultivar        tissue-type\n\
21737 contig1 Genus sp.       30 days after bloom     Williams 825    leaf\n\
21738 contig2 Genus sp.       30 days after bloom     Williams 825    leaf\n\
21739 \n\
21740 --------------------\n\
21741 Formatting examples:\n\
21742 --------------------\n\
21743 -Host: Use the binomial name of the host, if known, followed by other \n\
21744 ",
21745 "\
21746  information relating to the host, such as age, sex, breed, cultivar, etc. \n\
21747  For example-\n\
21748  Homo sapiens\n\
21749  Homo sapiens; female; 56 years\n\
21750  Solanum lycopersicum cv. Micro-Tom\n\
21751  Canis sp.\n\
21752 \n\
21753 -Country: use the following format-\n\
21754  Country: free text with more specific geographic information, if known.\n\
21755  For example-\n\
21756 ",
21757 "\
21758  Australia: 5 km south of Sydney\n\
21759  Madagascar\n\
21760  Brazil: Rio de Janeiro\n\
21761 \n\
21762 -Collection-date: use one of the following formats-\n\
21763  DD-MMM-YYYY\n\
21764  MMM-YYYY\n\
21765  YYYY\n\
21766  For example-\n\
21767  09-Aug-1985\n\
21768 ",
21769 "\
21770  Dec-2008\n\
21771  2008\n\
21772 \n\
21773 -Latitude-Longitude (lat_lon): use decimal degree format.\n\
21774  If you are providing Country information, the country should agree with the lat_lon value.\n\
21775  The first number should refer to the latitude (north/south) and the second to the longitude (east/west).\n\
21776  For example-\n\
21777  70.01 N 54.01 W\n\
21778 \n\
21779 ", NULL};
21780 
21781 
21782 static CharPtr s_DLoopSrcTblHelpMsgs[] = {
21783 "\
21784 -------------------------\n\
21785 Importing a Source Table:\n\
21786 -------------------------\n\
21787 -Use the ?Import Source Table? button to import a tab-delimited table\n\
21788  of the organism names, clone names, isolation source, and other relevant\n\
21789  source information (such as Country, Lat-lon, Collection_date, etc.).\n\
21790  \n\
21791 -The source table can be prepared in a spreadsheet program and saved as\n\
21792  tab-delimited text.  Saving as tab-delimited text is found in some programs\n\
21793 ",
21794 "\
21795  by selecting \"other format types\" and selecting the a tab-delimited file\n\
21796  type when saving your file.\n\
21797  \n\
21798 -Preparing the Source Table:\n\
21799  The first column in the table must contain the SeqIDs. \n\
21800  There must be a header row with the column labels.\n\
21801  The source information for each record follows on the rows \n\
21802  below the header line, like the following example.\n\
21803 \n\
21804 -------------------------------------------------------\n\
21805 ",
21806 "\
21807 Example Source Table:\n\
21808 Use the horizontal scroll bar to see more of the table.\n\
21809 -------------------------------------------------------\n\
21810 SeqID\tOrganism\tisolate\tcountry\tlat-lon\tFwd-PCR-primer-name\tFwd-PCR-primer-seq\tRev-PCR-primer-name\tRev-PCR-primer-seq\n\
21811 ABC1\tCoffea arabica\tABC1\tUSA\t24.55 N 81.75 W\tExamplePrimer1-F\tTTTTTAAAATTGGGGGC\tExamplePrimer1-R\tAAAATTTTAAGGGGAC\n\
21812 ABC2\tCoffea arabica\tABC2\tUSA\t24.55 N 81.75 W\t1Primer1-F, 2Primer-F\tTTTTTAAA, GGAATTTA\t1Primer-R, 2Primer-R\tAAAATTTT, GGAATT\n\
21813 \n\
21814 --------------------\n\
21815 Formatting examples:\n\
21816 --------------------\n\
21817 ",
21818 "\
21819 -Latitude-Longitude (lat_lon): use decimal degree format.\n\
21820  If you are providing Country information, the country should agree with the lat_lon value.\n\
21821  The first number should refer to the latitude (north/south) and the second to the longitude (east/west).\n\
21822  For example-\n\
21823  70.01 N 54.01 W\n\
21824 \n\
21825 -Primers: Please only provide the primers that were used the PCR amplify your sample. \n\
21826  Do not provide sequencing primers.\n\
21827  If you are providing multiple primers, separate the primer seqs and/or names with a comma.\n\
21828  See the example source table for a formatting example.\n\
21829 ",
21830 "\
21831 \n\
21832 ", NULL};
21833 
21834 
21835 static CharPtr s_MicrosatelliteSrcTblHelpMsgs[] = {
21836 "\
21837 ------------------\n\
21838 Importing a Table:\n\
21839 ------------------\n\
21840 -Use the \"Import Table\" button to import a tab-delimited table\n\
21841  of the organism names, clone names, and any relevant source \n\
21842  information (such as primers, Country, etc.).\n\
21843 \n\
21844 -The table in this form can be exported by pressing the \n\
21845  \"Export this table\" button. If you edit the table in a text \n\
21846 ",
21847 "\
21848  editor, you must maintain the tab structure of the table. \n\
21849  Alternately, you may copy the exported table into a spreadsheet \n\
21850  program to add your information, however you must import the \n\
21851  table back into this form as tab-delimited text (.txt). \n\
21852  Saving as tab-delimited text is found in some spreadsheet \n\
21853  programs by selecting \"other format types\" and selecting \n\
21854  the a tab-delimited file type when saving your file.\n\
21855 \n\
21856 -The table can be prepared in a spreadsheet program and saved as\n\
21857  tab-delimited text.  Saving as tab-delimited text is found \n\
21858 ",
21859 "\
21860  in some programs by selecting \"other format types\" and selecting \n\
21861  the a tab-delimited file type when saving your file.\n\
21862  \n\
21863 -Preparing the Table:\n\
21864  The first column in the table must contain the SeqIDs. \n\
21865  There must be a header row with the column labels.\n\
21866  The information for each record follows on the rows \n\
21867  below the header line, like the following example.\n\
21868 \n\
21869 -------------------------------------------------------\n\
21870 ",
21871 "\
21872 Example Table:\n\
21873 Use the horizontal scroll bar to see more of the table.\n\
21874 -------------------------------------------------------\n\
21875 SeqID\tOrganism\tclone\tcountry\tlat-lon\tFwd-PCR-primer-name\tFwd-PCR-primer-seq\tRev-PCR-primer-name\tRev-PCR-primer-seq\n\
21876 ABC1\tCoffea arabica\tCa-123\tGreenland\t70.00 N 54.01 W\tExamplePrimer1-F\tTTTTTAAAATTGGGGGC\tExamplePrimer1-R\tAAAATTTTAAGGGGAC\n\
21877 ABC2\tCoffea arabica\tCa-234\tGreenland\t70.00 N 54.01 W\t1Primer1-F, 2Primer-F\tTTTTTAAA, GGAATTTA\t1Primer-R, 2Primer-R\tAAAATTTT, GGAATT\n\
21878 \n\
21879 --------------------\n\
21880 Formatting examples:\n\
21881 --------------------\n\
21882 -Host: Use the binomial name of the host, if known, followed by other \n\
21883  information relating to the host, such as age, sex, breed, cultivar, etc. \n\
21884  For example-\n\
21885  Homo sapiens\n\
21886  Homo sapiens; female; 56 years\n\
21887 ",
21888 "\
21889  Solanum lycopersicum cv. Micro-Tom\n\
21890  Canis sp.\n\
21891 \n\
21892 -Country: use the following format-\n\
21893  Country: free text with more specific geographic information, if known.\n\
21894  For example-\n\
21895  Australia: 5 km south of Sydney\n\
21896  Madagascar\n\
21897  Brazil: Rio de Janeiro\n\
21898 \n\
21899 ",
21900 "\
21901 -Collection-date: use one of the following formats-\n\
21902  DD-MMM-YYYY\n\
21903  MMM-YYYY\n\
21904  YYYY\n\
21905  For example-\n\
21906  09-Aug-1985\n\
21907  Dec-2008\n\
21908  2008\n\
21909 \n\
21910 -Latitude-Longitude (lat_lon): use decimal degree format.\n\
21911 ",
21912 "\
21913  If you are providing Country information, the country should agree with the lat_lon value.\n\
21914  The first number should refer to the latitude (north/south) and the second to the longitude (east/west).\n\
21915  For example-\n\
21916  70.01 N 54.01 W\n\
21917 \n\
21918 -Primers: Please only provide the primers that were used to PCR amplify your sample. \n\
21919  Do not provide sequencing primers.\n\
21920 ",
21921 "\
21922  If you are providing multiple primers, separate the primer seqs and/or names with a comma.\n\
21923  See the example source table for a formatting example.\n\
21924 \n\
21925 ", NULL};
21926 
21927 
ShowSourceTableHelp(ButtoN b)21928 static void ShowSourceTableHelp (ButtoN b)
21929 {
21930   WizardTrackerPtr wiz;
21931 
21932   wiz = (WizardTrackerPtr) GetObjectExtra (b);
21933   if (wiz == NULL) {
21934     return;
21935   }
21936   switch (wiz->wizard_type) {
21937     case eWizardType_UnculturedSamples:
21938       ShowWizardHelpText ("Source Table Help", s_UnculturedSrcTblHelpMsgs);
21939       break;
21940     case eWizardType_Viruses:
21941       ShowWizardHelpText ("Source Table Help", s_VirusSrcTblHelpMsgs);
21942       break;
21943     case eWizardType_CulturedSamples:
21944       switch (wiz->cultured_kingdom) {
21945         case eCulturedKingdom_CulturedFungus:
21946         case eCulturedKingdom_VoucheredFungus:
21947         case eCulturedKingdom_BacteriaArchea:
21948           ShowWizardHelpText ("Source Table Help", s_CulturedBactFungusSrcTblHelpMsgs);
21949           break;
21950         default:
21951           ShowWizardHelpText ("Source Table Help", s_CulturedOtherSrcTblHelpMsgs);
21952           break;
21953       }
21954       break;
21955     case eWizardType_IGS:
21956       switch (wiz->igs_source_type) {
21957         case eIGSSourceType_CulturedFungus:
21958         case eIGSSourceType_VoucheredFungus:
21959           ShowWizardHelpText ("Source Table Help", s_CulturedBactFungusSrcTblHelpMsgs);
21960           break;
21961         default:
21962           ShowWizardHelpText ("Source Table Help", s_CulturedOtherSrcTblHelpMsgs);
21963           break;
21964       }
21965       break;
21966     case eWizardType_DLoop:
21967       ShowWizardHelpText ("Source Table Help", s_DLoopSrcTblHelpMsgs);
21968       break;
21969     case eWizardType_Microsatellite:
21970       ShowWizardHelpText ("Source Table Help", s_MicrosatelliteSrcTblHelpMsgs);
21971       break;
21972     default:
21973       ShowWizardHelpText ("Source Table Help", s_UnculturedSrcTblHelpMsgs);
21974       break;
21975   }
21976 }
21977 
21978 
ApplyMoreSourceInfo(ButtoN b)21979 static void ApplyMoreSourceInfo (ButtoN b)
21980 {
21981   WizardSrcQualsFormPtr frm;
21982   Int4 doc_width;
21983   WizardTrackerPtr wiz;
21984   IDAndTitleEditPtr iatep;
21985 
21986   frm = (WizardSrcQualsFormPtr) GetObjectExtra (b);
21987   if (frm == NULL) {
21988     return;
21989   }
21990 
21991   MultiModTableToSeqEntryList (frm->wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
21992   SelectFont (GetTableDisplayDefaultFont ());
21993   doc_width = CharWidth ('0') * 40;
21994 
21995   if (SourceAssistantForDeflines (frm->wiz->sequences, doc_width, SEQ_PKG_ENVIRONMENT)) {
21996     /* if we now have isolates, switch to different view */
21997     iatep = SeqEntryListToIDAndTitleEditEx (frm->wiz->sequences, TRUE);
21998     if (DoAnySequencesHaveModifierEx (iatep, "isolate", IsGelBand) && StringCmp (frm->mod_names[1], "Isolate") != 0) {
21999       /* redraw the window */
22000       wiz = frm->wiz;
22001       frm->wiz = NULL;
22002       Hide (frm->form);
22003       if (CreateWizardSrcQualsForm (wiz)) {
22004         Remove (frm->form);
22005       } else {
22006         frm->wiz = wiz;
22007       }
22008     } else {
22009       SeqEntryToMultiModTabTable (frm->wiz, frm->qual_table, frm->mod_names, frm->num_mods,
22010                                   GetWizardQualifierProblems, ShouldShowAll((WizardQualsFormPtr)frm));
22011     }
22012     iatep = IDAndTitleEditFree (iatep);
22013   }
22014 }
22015 
22016 
AddExtraColumn(ButtoN b)22017 static void AddExtraColumn (ButtoN b)
22018 {
22019   WizardSrcQualsFormPtr frm;
22020   WizardTrackerPtr wiz;
22021   Int4 i;
22022   Boolean found = FALSE;
22023   WizardSrcQualPtr q;
22024   ValNodePtr vnp;
22025 
22026   frm = (WizardSrcQualsFormPtr) GetObjectExtra (b);
22027   if (frm == NULL) {
22028     return;
22029   }
22030 
22031   i = 0;
22032   for (vnp = frm->wiz->extra_src_quals; vnp != NULL && !found; vnp = vnp->next) {
22033     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && !q->show && q->linked == NULL) {
22034       if (b == frm->extra_btns[i]) {
22035         q->show = TRUE;
22036         found = TRUE;
22037         ShowLinkedQuals (frm->wiz->extra_src_quals, q->name);
22038       } else {
22039         i++;
22040       }
22041     }
22042   }
22043 
22044   if (!found) {
22045     return;
22046   }
22047 
22048   MultiModTableToSeqEntryList (frm->wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
22049   wiz = frm->wiz;
22050   frm->wiz = NULL;
22051   Hide (frm->form);
22052   if (CreateWizardSrcQualsForm (wiz)) {
22053     Remove (frm->form);
22054   } else {
22055     frm->wiz = wiz;
22056   }
22057 }
22058 
22059 
ShowAllQualSequences(GrouP g)22060 static void ShowAllQualSequences (GrouP g)
22061 {
22062   WizardSrcQualsFormPtr frm;
22063   Boolean     show_all = TRUE;
22064 
22065   frm = (WizardSrcQualsFormPtr) GetObjectExtra (g);
22066   if (frm == NULL) {
22067     return;
22068   }
22069 
22070   MultiModTableToSeqEntryList (frm->wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
22071   if (GetValue (frm->show_all_grp) == 1) {
22072     show_all = FALSE;
22073   }
22074 
22075   SeqEntryToMultiModTabTable (frm->wiz, frm->qual_table, frm->mod_names, frm->num_mods, GetWizardQualifierProblems, show_all);
22076 }
22077 
22078 
CleanupWizardSrcQualsForm(GraphiC g,Pointer data)22079 static void CleanupWizardSrcQualsForm (GraphiC g, Pointer data)
22080 {
22081   WizardSrcQualsFormPtr frm;
22082 
22083   if (data != NULL)
22084   {
22085     frm = (WizardSrcQualsFormPtr) data;
22086     frm->wiz = WizardTrackerFree(frm->wiz);
22087     frm->mod_names = MemFree (frm->mod_names);
22088     frm->edit_types = MemFree (frm->edit_types);
22089     frm->extra_btns = MemFree (frm->extra_btns);
22090     frm->ed_grps = MemFree (frm->ed_grps);
22091     frm->apply_all_txt = MemFree (frm->apply_all_txt);
22092     frm->bulk_btns = MemFree (frm->bulk_btns);
22093   }
22094   CleanupWizardForm (g, data);
22095 }
22096 
22097 
ApplyAllValueToModifierTable(ButtoN b)22098 static void ApplyAllValueToModifierTable (ButtoN b)
22099 {
22100   WizardSrcQualsFormPtr frm;
22101   Int4 i;
22102   CharPtr val;
22103 
22104   frm = (WizardSrcQualsFormPtr) GetObjectExtra (b);
22105   if (frm == NULL) {
22106     return;
22107   }
22108 
22109   for (i = 0; i < frm->num_mods; i++) {
22110     if (frm->bulk_btns[i] == b) {
22111       break;
22112     }
22113   }
22114 
22115   if (i < frm->num_mods) {
22116     MultiModTableToSeqEntryList (frm->wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
22117     val = SaveStringFromText (frm->apply_all_txt[i]);
22118     SetOneModValueForAll (frm->wiz->sequences, frm->mod_names[i], val);
22119     val = MemFree (val);
22120     SeqEntryToMultiModTabTable (frm->wiz, frm->qual_table, frm->mod_names, frm->num_mods,
22121                                 GetWizardQualifierProblems, ShouldShowAll((WizardQualsFormPtr)frm));
22122   }
22123 }
22124 
22125 
CopyValuesFromId(ButtoN b)22126 static void CopyValuesFromId (ButtoN b)
22127 {
22128   WizardSrcQualsFormPtr frm;
22129   IDAndTitleEditPtr iatep;
22130   Int4 pos, i, num;
22131 
22132   frm = (WizardSrcQualsFormPtr) GetObjectExtra (b);
22133   if (frm == NULL) {
22134     return;
22135   }
22136 
22137   for (pos = 0; pos < frm->num_mods; pos++) {
22138     if (frm->bulk_btns[pos] == b) {
22139       break;
22140     }
22141   }
22142 
22143   if (pos < frm->num_mods) {
22144     MultiModTableToSeqEntryList (frm->wiz->sequences, frm->qual_table, frm->mod_names, frm->num_mods);
22145 
22146     iatep = SeqEntryListToIDAndTitleEditEx (frm->wiz->sequences, TRUE);
22147     num = GetNumValuesForMod (iatep, frm->mod_names[pos]);
22148     if (num > 0) {
22149       if (ANS_OK != Message (MSG_OKC, "You already have %d values for %s - do you want to replace them?", num, frm->mod_names[pos])) {
22150         iatep = IDAndTitleEditFree (iatep);
22151         return;
22152       }
22153     }
22154     for (i = 0; i < iatep->num_sequences; i++) {
22155       iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], frm->mod_names[pos], iatep->id_list[i]);
22156     }
22157     ApplyIDAndTitleEditToSeqEntryList (frm->wiz->sequences, iatep);
22158 
22159     SeqEntryToMultiModTabTable (frm->wiz, frm->qual_table, frm->mod_names, frm->num_mods,
22160                                 GetWizardQualifierProblems, ShouldShowAll((WizardQualsFormPtr)frm));
22161     iatep = IDAndTitleEditFree (iatep);
22162   }
22163 }
22164 
22165 
GetExampleText(WizardTrackerPtr wiz,Int4 num_mods)22166 static CharPtr PNTR GetExampleText (WizardTrackerPtr wiz, Int4 num_mods)
22167 {
22168   CharPtr PNTR example_text;
22169   ValNodePtr vnp;
22170   WizardSrcQualPtr q;
22171   Boolean any = FALSE;
22172   Int4    i;
22173 
22174   example_text = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_mods);
22175   MemSet (example_text, 0, sizeof (CharPtr) * num_mods);
22176   for (vnp = wiz->base_src_quals, i = 0; vnp != NULL; vnp = vnp->next, i++) {
22177     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL
22178         && q->example != NULL) {
22179       any = TRUE;
22180       example_text[i] = q->example;
22181     }
22182   }
22183   for (vnp = wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
22184     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL) {
22185       if (q->show) {
22186         if (q->example != NULL) {
22187           any = TRUE;
22188           example_text[i] = q->example;
22189         }
22190         i++;
22191       }
22192     }
22193   }
22194 
22195   if (!any) {
22196     example_text = MemFree (example_text);
22197   }
22198   return example_text;
22199 }
22200 
22201 
MakeSrcQualHeaders(GrouP g,WizardSrcQualsFormPtr frm)22202 static void MakeSrcQualHeaders (GrouP g, WizardSrcQualsFormPtr frm)
22203 {
22204   Int4 i;
22205   TexT t;
22206   Int4 grp_len = 5;
22207 
22208   frm->ed_grps = (GrouP PNTR) MemNew (sizeof (GrouP) * frm->num_mods);
22209   frm->apply_all_txt = (TexT PNTR) MemNew (sizeof (TexT) * frm->num_mods);
22210   frm->bulk_btns = (ButtoN PNTR) MemNew (sizeof (ButtoN) * frm->num_mods);
22211 
22212   for (i = 0; i < frm->num_mods; i++) {
22213     frm->ed_grps[i] = HiddenGroup (g, 0, grp_len, NULL);
22214     SetGroupSpacing (frm->ed_grps[i], 10, 10);
22215     switch (frm->edit_types[i]) {
22216       case eWizardEditQual_ApplyAll:
22217         StaticPrompt (frm->ed_grps[i], "Set", 0, 0, programFont, 'c');
22218         StaticPrompt (frm->ed_grps[i], frm->mod_names[i], 0, 0, programFont, 'c');
22219         StaticPrompt (frm->ed_grps[i], "for All", 0, 0, programFont, 'c');
22220         frm->apply_all_txt[i] = DialogText (frm->ed_grps[i], "", 8, NULL);
22221         frm->bulk_btns[i] = PushButton (frm->ed_grps[i], "Apply", ApplyAllValueToModifierTable);
22222         SetObjectExtra (frm->bulk_btns[i], frm, NULL);
22223         break;
22224       case eWizardEditQual_CopyFromId:
22225         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
22226         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
22227         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
22228         t = DialogText (frm->ed_grps[i], "", 8, NULL);
22229         Hide (t);
22230         frm->bulk_btns[i] = PushButton (frm->ed_grps[i], "Copy from SeqId", CopyValuesFromId);
22231         SetObjectExtra (frm->bulk_btns[i], frm, NULL);
22232         break;
22233       default:
22234         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
22235         break;
22236     }
22237   }
22238 }
22239 
22240 
ClearWizardSrcQuals(ButtoN b)22241 static void ClearWizardSrcQuals (ButtoN b)
22242 {
22243   WizardSrcQualsFormPtr frm;
22244   IDAndTitleEditPtr iatep;
22245   Int4              i;
22246 
22247   frm = (WizardSrcQualsFormPtr) GetObjectExtra (b);
22248   if (frm == NULL) {
22249     return;
22250   }
22251   iatep = SeqEntryListToIDAndTitleEditEx (frm->wiz->sequences, TRUE);
22252   RemoveSourceModifiersFromIdAndTitleEdit (iatep);
22253   for (i = 0; i < iatep->num_sequences; i++) {
22254     RemoveValueFromDefline ("org", iatep->title_list [i]);
22255   }
22256 
22257   ApplyIDAndTitleEditToSeqEntryList (frm->wiz->sequences, iatep);
22258   RedrawQualTableChange (frm, iatep);
22259   iatep = IDAndTitleEditFree (iatep);
22260 }
22261 
22262 
SrcQualsOkAndOkToContinueToSequin(WizardTrackerPtr wiz)22263 static Boolean SrcQualsOkAndOkToContinueToSequin (WizardTrackerPtr wiz)
22264 {
22265   Boolean rval = WizardSrcQualsOk (wiz);
22266   IDAndTitleEditPtr iatep;
22267 
22268   if (rval) {
22269     rval = OkToContinueToSequin (wiz);
22270     if (rval && (wiz->wizard_type == eWizardType_Microsatellite || eWizardType_DLoop)) {
22271       iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
22272       DiscardInvalidQualsInIatep (iatep, wiz);
22273       ApplyIDAndTitleEditToSeqEntryList (wiz->sequences, iatep);
22274       iatep = IDAndTitleEditFree (iatep);
22275     }
22276   }
22277   return rval;
22278 }
22279 
22280 
CountSrcQualsToShow(ValNodePtr base_src_quals,ValNodePtr extra_src_quals)22281 static Int4 CountSrcQualsToShow (ValNodePtr base_src_quals, ValNodePtr extra_src_quals)
22282 {
22283   ValNodePtr vnp;
22284   Int4 num_mods;
22285   WizardSrcQualPtr q;
22286 
22287   num_mods = ValNodeLen (base_src_quals);
22288 
22289   /* add extras */
22290   for (vnp = extra_src_quals; vnp != NULL; vnp = vnp->next) {
22291     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL) {
22292       if (q->show) {
22293         num_mods++;
22294       }
22295     }
22296   }
22297   return num_mods;
22298 }
22299 
22300 
CountUnseenSrcQuals(ValNodePtr extra_src_quals)22301 static Int4 CountUnseenSrcQuals (ValNodePtr extra_src_quals)
22302 {
22303   ValNodePtr vnp;
22304   Int4 num_mods = 0;
22305   WizardSrcQualPtr q;
22306 
22307   for (vnp = extra_src_quals; vnp != NULL; vnp = vnp->next) {
22308     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL) {
22309       if (!q->show) {
22310         num_mods++;
22311       }
22312     }
22313   }
22314   return num_mods;
22315 }
22316 
22317 
22318 
MoveQualFromExtraToBase(ValNodePtr PNTR base,ValNodePtr PNTR extra,CharPtr name)22319 static WizardSrcQualPtr MoveQualFromExtraToBase (ValNodePtr PNTR base, ValNodePtr PNTR extra, CharPtr name)
22320 {
22321   WizardSrcQualPtr q = NULL;
22322   ValNodePtr vnp, vnp_prev = NULL;
22323 
22324   if (extra != NULL) {
22325     for (vnp = *extra; vnp != NULL; vnp = vnp->next) {
22326       if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && StringICmp (q->name, name) == 0) {
22327         break;
22328       } else {
22329         vnp_prev = vnp;
22330       }
22331     }
22332     if (vnp != NULL) {
22333       if (vnp_prev == NULL) {
22334         *extra = vnp->next;
22335       } else {
22336         vnp_prev->next = vnp->next;
22337       }
22338       vnp->next = NULL;
22339       ValNodeLink (base, vnp);
22340     }
22341   }
22342   return q;
22343 }
22344 
22345 
GetExtraButtonGroupSize(Int4 unseen_extras)22346 static Int4 GetExtraButtonGroupSize (Int4 unseen_extras)
22347 {
22348   Int4 j;
22349 
22350   if (unseen_extras + 1 <= 6) {
22351     return 6;
22352   }
22353   for (j = 8; j > 3; j--) {
22354     if ((unseen_extras + 1) % j == 0) {
22355       return j;
22356     }
22357   }
22358   return 6;
22359 }
22360 
22361 
22362 /* potential problems that need to be solved here:
22363  *   missing organism names
22364  *   missing or duplicate clone values
22365  *   missing isolation source values
22366  *
22367  * warnings to be issued:
22368  *   organism names that don't start with uncultured
22369  *   isolation source values less than three letters
22370  */
CreateWizardSrcQualsForm(WizardTrackerPtr wiz)22371 static Boolean CreateWizardSrcQualsForm (WizardTrackerPtr wiz)
22372 {
22373   WizardSrcQualsFormPtr frm;
22374   WindoW w;
22375   GrouP  h;
22376   GrouP  top_btns, table_btns, g, c;
22377   GrouP  qualtable_grp;
22378   ButtoN b;
22379   Int4   num_seq, i, unseen_extras = 0;
22380   TagListPtr tlp;
22381   PrompT     ppt;
22382   ValNodePtr vnp;
22383   WizardSrcQualPtr q;
22384   Char       buf[255];
22385   CharPtr PNTR example_text;
22386   CharPtr      dlg_title;
22387   GrouP PNTR   grp_list;
22388   IDAndTitleEditPtr iatep;
22389 
22390   frm = (WizardSrcQualsFormPtr) MemNew (sizeof (WizardSrcQualsFormData));
22391   frm->wiz = wiz;
22392   frm->collect_func = SaveWizardSrcQuals;
22393   frm->fwd_ok_func = WizardSrcQualsOk;
22394 
22395   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
22396   num_seq = iatep->num_sequences;
22397   SetWizardTrackerBaseSrcQuals (wiz, iatep);
22398   SetWizardTrackerExtraSrcQuals (wiz, iatep);
22399   iatep = IDAndTitleEditFree (iatep);
22400 
22401   switch (wiz->wizard_type) {
22402     case eWizardType_Viruses:
22403       frm->next_form = CreateWizardMolInfoForm;
22404       break;
22405     case eWizardType_CulturedSamples:
22406       if (wiz->cultured_kingdom == eCulturedKingdom_BacteriaArchea) {
22407         frm->next_form = CreateWizardAnnotationChoiceForm;
22408       } else {
22409         frm->next_form = CreateWizardGenomeForm;
22410       }
22411       break;
22412     case eWizardType_UnculturedSamples:
22413       frm->next_form = PrimerChoiceWindow;
22414       break;
22415     case eWizardType_IGS:
22416       frm->next_form = CreateWizardGenomeForm;
22417       break;
22418     case eWizardType_Microsatellite:
22419       /* if we're here, instead of the other dialog, then clone is required */
22420       q = MoveQualFromExtraToBase (&(frm->wiz->base_src_quals), &(frm->wiz->extra_src_quals), "clone");
22421       q->required = TRUE;
22422       frm->fwd_ok_func = SrcQualsOkAndOkToContinueToSequin;
22423       frm->next_form = FinishWizardAndLaunchSequin;
22424       break;
22425     case eWizardType_DLoop:
22426       frm->next_form = CreateWizardAnnotationChoiceForm;
22427       break;
22428   }
22429 
22430   frm->num_mods = CountSrcQualsToShow (wiz->base_src_quals, wiz->extra_src_quals);
22431   unseen_extras = CountUnseenSrcQuals (wiz->extra_src_quals);
22432 
22433   frm->mod_names = (CharPtr PNTR) MemNew (sizeof (CharPtr) * frm->num_mods);
22434   frm->edit_types = (EWizardEditQual PNTR) MemNew (sizeof (EWizardEditQual) * frm->num_mods);
22435   for (vnp = frm->wiz->base_src_quals, i = 0; vnp != NULL; vnp = vnp->next) {
22436     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL) {
22437       frm->mod_names[i] = q->name;
22438       frm->edit_types[i] = q->edit_type;
22439       i++;
22440     }
22441   }
22442 
22443   for (vnp = frm->wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
22444     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && q->show) {
22445       frm->mod_names[i] = q->name;
22446       frm->edit_types[i] = q->edit_type;
22447       i++;
22448     }
22449   }
22450 
22451   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Source);
22452   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
22453   SetObjectExtra (w, frm, CleanupWizardSrcQualsForm);
22454   frm->form = (ForM) w;
22455 
22456   h = HiddenGroup (w, -1, -1, NULL);
22457   SetGroupSpacing (h, 10, 10);
22458 
22459   ppt = StaticPrompt (h, "Please provide the required source information:", 0, 0, programFont, 'c');
22460   qualtable_grp = HiddenGroup (h, -1, 0, NULL);
22461 
22462   top_btns = HiddenGroup (qualtable_grp, frm->num_mods, 0, NULL);
22463   SetGroupSpacing (top_btns, 10, 10);
22464 
22465   MakeSrcQualHeaders (top_btns,frm);
22466 
22467   grp_list = (GrouP PNTR) MemNew (sizeof (GrouP) * (frm->num_mods + 2));
22468   example_text = GetExampleText(frm->wiz, frm->num_mods);
22469   frm->qual_table = AddMultiModifierTableEditor (qualtable_grp, frm->mod_names, example_text, frm->num_mods, num_seq, grp_list);
22470   example_text = MemFree (example_text);
22471 
22472   tlp = GetObjectExtra (frm->qual_table);
22473   AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[0], (HANDLE) tlp->control[0], NULL);
22474   for (i = 0; i < frm->num_mods; i++) {
22475     AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[i + 1], (HANDLE) tlp->control[i + 1], (HANDLE) frm->ed_grps[i], NULL);
22476   }
22477   /* align problems */
22478   AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[i + 1], (HANDLE) tlp->control[i + 1], NULL);
22479   grp_list = MemFree (grp_list);
22480 
22481   frm->show_all_grp = HiddenGroup (h, 2, 0, ShowAllQualSequences);
22482   SetObjectExtra (frm->show_all_grp, frm, NULL);
22483   RadioButton (frm->show_all_grp, "Show only sequences with errors");
22484   RadioButton (frm->show_all_grp, "Show all sequences in set");
22485   SetValue (frm->show_all_grp, 2);
22486 
22487   g = HiddenGroup (h, GetExtraButtonGroupSize(unseen_extras), 0, NULL);
22488   SetGroupSpacing (g, 10, 10);
22489   b = PushButton (g, "Apply/See More Source Information", ApplyMoreSourceInfo);
22490   SetObjectExtra (b, frm, NULL);
22491 
22492   frm->extra_btns = (ButtoN PNTR) MemNew (sizeof (ButtoN) * unseen_extras);
22493   i = 0;
22494   for (vnp = frm->wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
22495     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && !q->show && q->linked == NULL) {
22496       sprintf (buf, "Add %s", q->add_name);
22497       frm->extra_btns[i] = PushButton (g, buf, AddExtraColumn);
22498       SetObjectExtra (frm->extra_btns[i], frm, NULL);
22499       i++;
22500     }
22501   }
22502 
22503   table_btns = HiddenGroup (h, 5, 0, NULL);
22504   SetGroupSpacing (table_btns, 10, 10);
22505   b = PushButton (table_btns, "Import Source Table", ImportMultiModTable);
22506   SetObjectExtra (b, frm, NULL);
22507 
22508   b = PushButton (table_btns, "Export This Table", ExportMultiModTable);
22509   SetObjectExtra (b, frm, NULL);
22510 
22511   b = PushButton (table_btns, "Source Table Help", ShowSourceTableHelp);
22512   SetObjectExtra (b, frm->wiz, NULL);
22513 
22514   b = PushButton (table_btns, "Recheck Errors", RecheckUnculturedSourceErrors);
22515   SetObjectExtra (b, frm, NULL);
22516 
22517   b = PushButton (table_btns, "Clear Source Qualifiers", ClearWizardSrcQuals);
22518   SetObjectExtra (b, frm, NULL);
22519 
22520   c = MakeWizardNav (h, frm);
22521 
22522   AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
22523                               (HANDLE) qualtable_grp,
22524                               (HANDLE) frm->show_all_grp,
22525                               (HANDLE) table_btns,
22526                               (HANDLE) g,
22527                               (HANDLE) c,
22528                               NULL);
22529 
22530   Update();
22531   SeqEntryToMultiModTabTable(frm->wiz, frm->qual_table, frm->mod_names, frm->num_mods,
22532                              GetWizardQualifierProblems, ShouldShowAll((WizardQualsFormPtr)frm));
22533   Show (w);
22534   SendHelpScrollMessage (helpForm, "Wizard Source Organism Information", dlg_title);
22535 
22536   return TRUE;
22537 }
22538 
22539 
22540 
RangePairIsFullSeq(CharPtr begin_str,CharPtr end_str,BioseqPtr bsp)22541 static Boolean RangePairIsFullSeq (CharPtr begin_str, CharPtr end_str, BioseqPtr bsp)
22542 {
22543   Int4 begin, end, x;
22544 
22545   if (bsp == NULL || !StringIsAllDigits (end_str) || !StringIsAllDigits(begin_str)) {
22546     return FALSE;
22547   }
22548   begin = atoi (begin_str);
22549   end = atoi (end_str);
22550   if (begin > end) {
22551     x = begin;
22552     begin = end;
22553     end = x;
22554   }
22555   if (begin == 1 && end == bsp->length) {
22556     return TRUE;
22557   } else {
22558     return FALSE;
22559   }
22560 }
22561 
22562 
FeatureValidationChecks(WizardTrackerPtr wiz,Boolean required)22563 static Boolean FeatureValidationChecks (WizardTrackerPtr wiz, Boolean required)
22564 {
22565   Boolean rval = TRUE;
22566   ValNodePtr row_vnp, q_vnp;
22567   WizardFeatQualPtr q;
22568   Boolean bad_qual_found, bad_range_found, out_of_range_found, unbalanced_found;
22569   CharPtr val, tmp, range_start_str;
22570   Int4    j, start, seq_num;
22571   BioseqPtr bsp;
22572   Boolean   first_range = TRUE;
22573 
22574   if (wiz == NULL) {
22575     return FALSE;
22576   }
22577   start = CountSrcQualsToShow (wiz->base_src_quals, wiz->extra_src_quals);
22578   for (q_vnp = wiz->feature_quals, j = 1; q_vnp != NULL && rval; q_vnp = q_vnp->next, j++) {
22579     q = (WizardFeatQualPtr) q_vnp->data.ptrvalue;
22580     if (q->valid_func != NULL && ((required && q->valid_required) || (!required && !q->valid_required))) {
22581       bad_qual_found = FALSE;
22582       bad_range_found = FALSE;
22583       out_of_range_found = FALSE;
22584       unbalanced_found = FALSE;
22585       for (row_vnp = wiz->feat_qual_table, seq_num = 0;
22586            row_vnp != NULL && (!bad_qual_found || !bad_range_found || !out_of_range_found);
22587            row_vnp = row_vnp->next, seq_num++) {
22588         bsp = FindNthSequenceInSet (wiz->sequences, seq_num, NULL, TRUE);
22589         val = GetNthField(row_vnp->data.ptrvalue, j + start);
22590         tmp = (q->valid_func)(val, q->name, bsp);
22591         if (tmp != NULL) {
22592           if (!bad_qual_found) {
22593             if (q->valid_required) {
22594               Message (MSG_ERROR, tmp);
22595               rval = FALSE;
22596             } else if (ANS_CANCEL == Message (MSG_OKC, "%s Are you sure you want to continue?", tmp)) {
22597               rval = FALSE;
22598             }
22599             tmp = MemFree (tmp);
22600             bad_qual_found = TRUE;
22601           }
22602         } else if (q->edit_type == eWizardEditQual_Range) {
22603           if (!bad_range_found || !unbalanced_found) {
22604             if (!first_range) {
22605               range_start_str = GetNthField(row_vnp->data.ptrvalue, j + start - 1);
22606               if (StringHasNoText (range_start_str) && StringHasNoText (val)) {
22607                 /* no problem if empty */
22608               } else  if (StringHasNoText (range_start_str) || StringHasNoText (val)) {
22609                 if (!unbalanced_found) {
22610                   if (ANS_CANCEL == Message (MSG_OKC, "If one of rpt_unit_range begin or end is supplied, both must be supplied.\n\
22611 Click OK to proceed and remove unbalanced rpt_unit_range values.\n\
22612 Click Cancel to edit this information in the table.")) {
22613                     rval = FALSE;
22614                   }
22615                   unbalanced_found = TRUE;
22616                 }
22617               } else if (StringIsAllDigits (val) && StringIsAllDigits (range_start_str) && RangePairIsFullSeq(range_start_str, val, bsp)) {
22618                 if (ANS_CANCEL == Message (MSG_OKC, "Some of the values in rpt_unit_range are the same length as the sequence(s).\n\
22619 The rpt_unit_range should contain the nucleotide locations of one repeat unit.\n\
22620 Click OK to proceed and remove the bad rpt_unit_range values.\n\
22621 Click Cancel to edit this information in the table.")) {
22622                   rval = FALSE;
22623                 }
22624                 bad_range_found = TRUE;
22625               }
22626             }
22627           }
22628           if (!out_of_range_found && !StringHasNoText (val) && StringIsAllDigits(val) && (atoi (val) > bsp->length || atoi (val) < 1)) {
22629             if (ANS_CANCEL == Message (MSG_OKC, "Some of the values in rpt_unit_range are larger than the length of the sequence(s) or less than one.\n\
22630 Click OK to proceed and remove the bad rpt_unit_range values.\n\
22631 Click Cancel to edit this information in the table.")) {
22632                   rval = FALSE;
22633             }
22634             out_of_range_found = TRUE;
22635           }
22636         }
22637       }
22638     }
22639     if (q->edit_type == eWizardEditQual_Range && first_range) {
22640       first_range = FALSE;
22641     }
22642   }
22643 
22644   return rval;
22645 }
22646 
22647 
ValidateOneColumnPresence(WizardTrackerPtr wiz,CharPtr q_name,Boolean required,Int4 j)22648 static Boolean ValidateOneColumnPresence (WizardTrackerPtr wiz, CharPtr q_name, Boolean required, Int4 j)
22649 {
22650   Int4 num_missing = 0;
22651   Int4 num_present = 0;
22652   ValNodePtr row_vnp;
22653   Boolean rval = TRUE;
22654   CharPtr val;
22655 
22656   for (row_vnp = wiz->feat_qual_table; row_vnp != NULL; row_vnp = row_vnp->next) {
22657     val = GetNthField(row_vnp->data.ptrvalue, j);
22658     if (StringHasNoText (val)) {
22659       num_missing++;
22660     } else {
22661       num_present++;
22662     }
22663   }
22664   if (required) {
22665     if (num_missing > 0) {
22666       Message (MSG_ERROR, "%d %s values are missing.  Please provide these required fields.",
22667                num_missing, q_name);
22668       rval = FALSE;
22669     }
22670   }
22671   return rval;
22672 }
22673 
22674 
ValidateOneColumnLinkage(WizardTrackerPtr wiz,WizardQualPtr q,Int4 j)22675 static Boolean ValidateOneColumnLinkage (WizardTrackerPtr wiz, WizardQualPtr q, Int4 j)
22676 {
22677   Int4 pos_l;
22678   ValNodePtr row_vnp;
22679   CharPtr val1, val2;
22680   WizardQualPtr q_l;
22681 
22682   if (q == NULL || q->linked == NULL) {
22683     return TRUE;
22684   }
22685   q_l = FindLinkedQual(wiz, q->linked);
22686   if (q_l == NULL) {
22687     return TRUE;
22688   }
22689 
22690   pos_l = GetPositionForQual (q_l, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals);
22691 
22692   for (row_vnp = wiz->feat_qual_table; row_vnp != NULL; row_vnp = row_vnp->next) {
22693     val1 = GetNthField(row_vnp->data.ptrvalue, j);
22694     val2 = GetNthField(row_vnp->data.ptrvalue, pos_l);
22695     if ((StringHasNoText (val1) && !StringHasNoText (val2)) || (!StringHasNoText (val1) && StringHasNoText (val2))) {
22696       if (StringISearch (q->name, "PCR-primer") != NULL) {
22697         if (ANS_OK == Message (MSG_OKC,
22698              "For each sequence, you must provide either both %s and %s, or neither.  Do not provide sequencing primers.  Choose OK to remove %s and %s values on sequences where one of these is missing, or choose Cancel to provide missing values.",
22699              q->name, q->linked, q->name, q->linked)) {
22700           return TRUE;
22701         } else {
22702           return FALSE;
22703         }
22704       } else {
22705         Message (MSG_ERROR, "For each sequence, if %s is provided, %s must also be provided.", q->name, q->linked);
22706         return FALSE;
22707       }
22708     }
22709   }
22710   return TRUE;
22711 }
22712 
22713 
CheckFeatureQualsUniqueness(WizardTrackerPtr wiz)22714 static Boolean CheckFeatureQualsUniqueness (WizardTrackerPtr wiz)
22715 {
22716   ValNodePtr vnp_row, vnp_u, vnp_q, unique_list = NULL;
22717   CharPtr row_val;
22718   CharPtr this_val;
22719   Int4 num_rows, row_num;
22720   Int4 num_quals, i;
22721   Int4Ptr pos_list;
22722   CharPtr PNTR qual_names;
22723   BoolPtr any_qual;
22724   CharPtr dup_msg;
22725   CharPtr combo_fmt = "Must have unique combination of ";
22726   Int4 dup_msg_len, num_quals_found;
22727   WizardQualPtr q;
22728   Int4 num_before, num_after;
22729   Boolean rval = TRUE;
22730 
22731   if (wiz == NULL) {
22732     return FALSE;
22733   } else if (wiz->feat_qual_table == NULL || wiz->feat_qual_table->next == NULL) {
22734     return TRUE;
22735   }
22736   num_rows = ValNodeLen (wiz->feat_qual_table);
22737   for (vnp_u = wiz->uniqueness_list; vnp_u != NULL && rval; vnp_u = vnp_u->next) {
22738     unique_list = NULL;
22739     num_quals = ValNodeLen (vnp_u->data.ptrvalue);
22740     pos_list = (Int4Ptr) MemNew (sizeof (Int4) * num_quals);
22741     any_qual = (BoolPtr) MemNew (sizeof (Boolean) * num_quals);
22742     qual_names = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_quals);
22743     dup_msg_len = 0;
22744     num_quals_found = 0;
22745     MemSet (any_qual, 0, sizeof (Boolean) * num_quals);
22746     for (i = 0, vnp_q = vnp_u->data.ptrvalue; vnp_q != NULL; vnp_q = vnp_q->next, i++) {
22747       q = vnp_q->data.ptrvalue;
22748       pos_list[i] = GetPositionForQual (q, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals);
22749       if (pos_list[i] > 0) {
22750         qual_names[i] = q->name;
22751       }
22752     }
22753     for (vnp_row = wiz->feat_qual_table, row_num = 0; vnp_row != NULL; vnp_row = vnp_row->next, row_num++) {
22754       row_val = NULL;
22755       for (i = 0; i < num_quals; i++) {
22756         this_val = GetNthField (vnp_row->data.ptrvalue, pos_list[i]);
22757         if (!StringHasNoText (this_val)) {
22758           if (!any_qual[i]) {
22759             dup_msg_len += StringLen (qual_names[i]) + 6;
22760             num_quals_found++;
22761             any_qual[i] = TRUE;
22762           }
22763           SetStringValue (&row_val, this_val, ExistingTextOption_append_semi);
22764         }
22765       }
22766       ValNodeAddPointer (&unique_list, 0, row_val);
22767     }
22768     if (num_quals_found == 0) {
22769       /* nothing found, don't bother */
22770     } else {
22771       num_before = ValNodeLen (unique_list);
22772       unique_list = ValNodeSort (unique_list, SortVnpByString);
22773       ValNodeUnique (&unique_list, SortVnpByString, ValNodeFreeData);
22774       num_after = ValNodeLen (unique_list);
22775       if (num_after != num_before) {
22776         rval = FALSE;
22777         if (num_quals == 1) {
22778           Message (MSG_ERROR, "You must provide unique %s values!", qual_names[0]);
22779         } else {
22780           dup_msg_len += StringLen (combo_fmt) + 1;
22781           dup_msg = (CharPtr) MemNew (sizeof (Char) * dup_msg_len);
22782           StringCpy (dup_msg, combo_fmt);
22783           for (i = 0; i < num_quals - 1; i++) {
22784             StringCat (dup_msg, qual_names[i]);
22785             if (num_quals > 2) {
22786               StringCat (dup_msg, ", ");
22787             }
22788           }
22789           StringCat (dup_msg, "and ");
22790           StringCat (dup_msg, qual_names[i]);
22791           Message (MSG_ERROR, dup_msg);
22792           dup_msg = MemFree (dup_msg);
22793         }
22794       }
22795     }
22796     unique_list = ValNodeFreeData (unique_list);
22797     pos_list = MemFree (pos_list);
22798     any_qual = MemFree (any_qual);
22799     qual_names = MemFree (qual_names);
22800   }
22801   return rval;
22802 }
22803 
22804 
WizardFeatureQualsOk(WizardTrackerPtr wiz)22805 static Boolean WizardFeatureQualsOk (WizardTrackerPtr wiz)
22806 {
22807   Boolean rval = TRUE;
22808   ValNodePtr q_vnp;
22809   WizardQualPtr q;
22810   Int4    num_features;
22811   Int4    j;
22812 
22813   num_features = ValNodeLen (wiz->feat_qual_table);
22814   /* note that j starts at 1, to skip Seq-id column */
22815   for (q_vnp = wiz->base_src_quals, j = 1; q_vnp != NULL && rval; q_vnp = q_vnp->next, j++) {
22816     q = (WizardQualPtr) q_vnp->data.ptrvalue;
22817     rval = ValidateOneColumnPresence (wiz, q->name, q->required, j);
22818     if (rval) {
22819       rval = ValidateOneColumnLinkage (wiz, q, j);
22820     }
22821   }
22822   for (q_vnp = wiz->extra_src_quals; q_vnp != NULL && rval; q_vnp = q_vnp->next) {
22823     q = (WizardQualPtr) q_vnp->data.ptrvalue;
22824     if (q->show) {
22825       rval = ValidateOneColumnPresence (wiz, q->name, q->required, j);
22826       if (rval) {
22827         rval = ValidateOneColumnLinkage (wiz, q, j);
22828       }
22829       j++;
22830     }
22831   }
22832   for (q_vnp = wiz->feature_quals; q_vnp != NULL && rval; q_vnp = q_vnp->next, j++) {
22833     q = (WizardQualPtr) q_vnp->data.ptrvalue;
22834     rval = ValidateOneColumnPresence (wiz, q->name, q->required, j);
22835     if (rval) {
22836       rval = ValidateOneColumnLinkage (wiz, q, j);
22837     }
22838   }
22839   if (rval) {
22840     rval = CheckFeatureQualsUniqueness(wiz);
22841   }
22842   if (rval) {
22843     if (!FeatureValidationChecks (wiz, TRUE)) {
22844       rval = FALSE;
22845     } else if (!FeatureValidationChecks (wiz, FALSE)) {
22846       rval = FALSE;
22847     } else {
22848       rval = TRUE;
22849     }
22850   }
22851   return rval;
22852 }
22853 
22854 
BlankLinkedColumns(ValNodePtr table,Int4 q_pos,Int4 l_pos)22855 static void BlankLinkedColumns (ValNodePtr table, Int4 q_pos, Int4 l_pos)
22856 {
22857   ValNodePtr row_vnp, col_vnp, q_vnp = NULL, l_vnp = NULL;
22858   Int4 i;
22859 
22860   for (row_vnp = table; row_vnp != NULL; row_vnp = row_vnp->next) {
22861     for (i = 0, col_vnp = row_vnp->data.ptrvalue; col_vnp != NULL && (i <= q_pos || i <= l_pos); col_vnp = col_vnp->next, i++) {
22862       if (i == q_pos) {
22863         q_vnp = col_vnp;
22864       } else if (i == l_pos) {
22865         l_vnp = col_vnp;
22866       }
22867     }
22868     if (q_vnp != NULL && l_vnp != NULL) {
22869       if (StringHasNoText (q_vnp->data.ptrvalue) || StringHasNoText (l_vnp->data.ptrvalue)) {
22870         q_vnp->data.ptrvalue = MemFree (q_vnp->data.ptrvalue);
22871         l_vnp->data.ptrvalue = MemFree (l_vnp->data.ptrvalue);
22872       }
22873     } else if (q_vnp != NULL) {
22874       q_vnp->data.ptrvalue = MemFree (q_vnp->data.ptrvalue);
22875     } else if (l_vnp != NULL) {
22876       l_vnp->data.ptrvalue = MemFree (l_vnp->data.ptrvalue);
22877     }
22878   }
22879 }
22880 
22881 
DiscardOneUnmatchedLinkedQual(ValNodePtr table,WizardTrackerPtr wiz,Int4 j,WizardQualPtr q)22882 static void DiscardOneUnmatchedLinkedQual (ValNodePtr table, WizardTrackerPtr wiz, Int4 j, WizardQualPtr q)
22883 {
22884   Int4 pos_l;
22885   WizardQualPtr q_l;
22886 
22887   if (q == NULL || q->linked == NULL) {
22888     return;
22889   }
22890   q_l = FindLinkedQual(wiz, q->linked);
22891   if (q_l == NULL) {
22892     return;
22893   }
22894 
22895   pos_l = GetPositionForQual (q_l, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals);
22896   BlankLinkedColumns (wiz->feat_qual_table, j, pos_l);
22897 }
22898 
22899 
DiscardInvalidQuals(WizardTrackerPtr wiz)22900 static void DiscardInvalidQuals (WizardTrackerPtr wiz)
22901 {
22902   ValNodePtr row_vnp, q_vnp;
22903   WizardFeatQualPtr fq;
22904   WizardQualPtr q;
22905   CharPtr val, tmp, range_start_str;
22906   Int4    j, seq_num;
22907   BioseqPtr bsp = NULL;
22908   Boolean   first_range = TRUE;
22909 
22910   if (wiz == NULL) {
22911     return;
22912   }
22913   j = CountSrcQualsToShow (wiz->base_src_quals, wiz->extra_src_quals) + 1;
22914   for (q_vnp = wiz->feature_quals; q_vnp != NULL; q_vnp = q_vnp->next, j++) {
22915     fq = (WizardFeatQualPtr) q_vnp->data.ptrvalue;
22916     if (fq->edit_type == eWizardEditQual_Range || (fq->valid_func != NULL && fq->delete_if_invalid)) {
22917       for (row_vnp = wiz->feat_qual_table, seq_num = 0; row_vnp != NULL; row_vnp = row_vnp->next, seq_num++) {
22918         bsp = FindNthSequenceInSet (wiz->sequences, seq_num, NULL, TRUE);
22919         val = GetNthField(row_vnp->data.ptrvalue, j);
22920         if (fq->valid_func != NULL && fq->delete_if_invalid) {
22921           tmp = (fq->valid_func)(val, fq->name, bsp);
22922           if (tmp != NULL) {
22923             val[0] = 0;
22924             tmp = MemFree (tmp);
22925           }
22926         }
22927         if (fq->edit_type == eWizardEditQual_Range) {
22928           if (!first_range) {
22929             range_start_str = GetNthField(row_vnp->data.ptrvalue, j - 1);
22930             if (range_start_str[0] == 0) {
22931               val[0] = 0;
22932             } else if (val[0] == 0) {
22933               range_start_str[0] = 0;
22934             } else if (StringIsAllDigits (val) && StringIsAllDigits (range_start_str) && RangePairIsFullSeq(range_start_str, val, bsp)) {
22935               val[0] = 0;
22936               range_start_str[0] = 0;
22937             }
22938           }
22939         }
22940       }
22941     }
22942     if (fq->edit_type == eWizardEditQual_Range) {
22943       first_range = FALSE;
22944     }
22945   }
22946   /* note that j starts at 1, to skip Seq-id column */
22947   for (q_vnp = wiz->base_src_quals, j = 1; q_vnp != NULL; q_vnp = q_vnp->next, j++) {
22948     q = (WizardQualPtr) q_vnp->data.ptrvalue;
22949     DiscardOneUnmatchedLinkedQual (wiz->feat_qual_table, wiz, j, q);
22950   }
22951   for (q_vnp = wiz->extra_src_quals; q_vnp != NULL; q_vnp = q_vnp->next) {
22952     q = (WizardQualPtr) q_vnp->data.ptrvalue;
22953     if (q->show) {
22954       DiscardOneUnmatchedLinkedQual (wiz->feat_qual_table, wiz, j, q);
22955       j++;
22956     }
22957   }
22958   for (q_vnp = wiz->feature_quals; q_vnp != NULL; q_vnp = q_vnp->next, j++) {
22959     q = (WizardQualPtr) q_vnp->data.ptrvalue;
22960     DiscardOneUnmatchedLinkedQual (wiz->feat_qual_table, wiz, j, q);
22961   }
22962 
22963 }
22964 
22965 
WizardFeatureQualsOkAndOkToContinueToSequin(WizardTrackerPtr wiz)22966 static Boolean WizardFeatureQualsOkAndOkToContinueToSequin (WizardTrackerPtr wiz)
22967 {
22968   Boolean rval = WizardFeatureQualsOk (wiz);
22969 
22970   if (rval) {
22971     rval = OkToContinueToSequin (wiz);
22972   }
22973   if (rval) {
22974     /* discard invalid data */
22975     DiscardInvalidQuals(wiz);
22976   }
22977   return rval;
22978 }
22979 
22980 
22981 typedef struct wizardfeaturequalsform {
22982   WIZARD_QUALS_BLOCK
22983   Int4              num_src_quals;
22984   IDAndTitleEditPtr iatep;
22985   ValNodePtr        rows_displayed;
22986 } WizardFeatureQualsFormData, PNTR WizardFeatureQualsFormPtr;
22987 
22988 
OneSrcQualProblem(WizardSrcQualPtr sq,CharPtr val)22989 static CharPtr OneSrcQualProblem (WizardSrcQualPtr sq, CharPtr val)
22990 {
22991   CharPtr msg = NULL;
22992   CharPtr missing_fmt = "Missing %s";
22993   if (StringHasNoText (val)) {
22994     if (sq->required || sq->problem_when_missing) {
22995       msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (missing_fmt) + StringLen (sq->name)));
22996       sprintf (msg, missing_fmt, sq->name);
22997     }
22998   } else if (sq->valid_func != NULL) {
22999     msg = sq->valid_func(sq->name, val, FALSE);
23000   }
23001   return msg;
23002 }
23003 
23004 
GetLineProblems(ValNodePtr line,ValNodePtr base_src_quals,ValNodePtr extra_src_quals,ValNodePtr fquals,BioseqPtr bsp)23005 static CharPtr GetLineProblems (ValNodePtr line, ValNodePtr base_src_quals, ValNodePtr extra_src_quals, ValNodePtr fquals, BioseqPtr bsp)
23006 {
23007   ValNodePtr problem_list = NULL, vnp, val_vnp;
23008   CharPtr tmp, problem = NULL;
23009   WizardSrcQualPtr  sq;
23010   WizardFeatQualPtr fq, fq2;
23011   Int4    len = 0;
23012   CharPtr msg;
23013 
23014   for (vnp = base_src_quals, val_vnp = line->next; vnp != NULL; vnp = vnp->next) {
23015     sq = (WizardSrcQualPtr) vnp->data.ptrvalue;
23016     msg = OneSrcQualProblem (sq, val_vnp == NULL ? NULL : val_vnp->data.ptrvalue);
23017     if (msg != NULL) {
23018       ValNodeAddPointer (&problem_list, 0, msg);
23019       len += StringLen (msg) + 2;
23020     }
23021     if (val_vnp != NULL) {
23022       val_vnp = val_vnp->next;
23023     }
23024   }
23025 
23026   for (vnp = extra_src_quals; vnp != NULL; vnp = vnp->next) {
23027     sq = (WizardSrcQualPtr) vnp->data.ptrvalue;
23028     if (sq->show) {
23029       if (val_vnp != NULL) {
23030         msg = OneSrcQualProblem (sq, val_vnp->data.ptrvalue);
23031         if (msg != NULL) {
23032           ValNodeAddPointer (&problem_list, 0, msg);
23033           len += StringLen (msg) + 2;
23034         }
23035         val_vnp = val_vnp->next;
23036       }
23037     }
23038   }
23039 
23040   for (vnp = fquals; vnp != NULL; vnp = vnp->next) {
23041     fq = (WizardFeatQualPtr) vnp->data.ptrvalue;
23042     tmp = NULL;
23043     if (fq->problem_func != NULL) {
23044       if (val_vnp == NULL) {
23045         tmp = fq->problem_func(NULL, bsp);
23046       } else {
23047         tmp = fq->problem_func(val_vnp->data.ptrvalue, bsp);
23048       }
23049       if (tmp != NULL) {
23050         len += StringLen (tmp) + 2;
23051         ValNodeAddPointer (&problem_list, 0, tmp);
23052       }
23053     }
23054     if (fq->edit_type == eWizardEditQual_Range && vnp->next != NULL
23055         && (fq2 = (WizardFeatQualPtr) vnp->next->data.ptrvalue) != NULL
23056         && fq2->edit_type == eWizardEditQual_Range
23057         && RangePairIsFullSeq (val_vnp == NULL ? NULL : val_vnp->data.ptrvalue,
23058                                val_vnp == NULL ? NULL : val_vnp->next == NULL ? NULL : val_vnp->next->data.ptrvalue,
23059                                bsp)) {
23060       tmp = StringSave ("range includes entire sequence");
23061       len += StringLen (tmp) + 2;
23062       ValNodeAddPointer (&problem_list, 0, tmp);
23063     }
23064     if (val_vnp != NULL) {
23065       val_vnp = val_vnp->next;
23066     }
23067   }
23068   if (problem_list != NULL) {
23069     problem = (CharPtr) MemNew (sizeof (Char) * (len + 1));
23070     for (vnp = problem_list; vnp != NULL; vnp = vnp->next) {
23071       StringCat (problem, vnp->data.ptrvalue);
23072       if (vnp->next != NULL) {
23073         StringCat (problem, "; ");
23074       }
23075     }
23076     problem_list = ValNodeFreeData (problem_list);
23077   }
23078   return problem;
23079 }
23080 
23081 
AddLinkedProblemsForTableForQualList(ValNodePtr table,WizardTrackerPtr wiz,CharPtr PNTR problems,ValNodePtr list)23082 static void AddLinkedProblemsForTableForQualList (ValNodePtr table, WizardTrackerPtr wiz, CharPtr PNTR problems, ValNodePtr list)
23083 {
23084   Int4 i, pos_q, pos_l;
23085   WizardQualPtr q, q_l;
23086   CharPtr val1, val2;
23087   ValNodePtr vnp, vnp_row;
23088 
23089   for (vnp = list; vnp != NULL; vnp = vnp->next) {
23090     q = (WizardQualPtr) vnp->data.ptrvalue;
23091     pos_q = GetPositionForQual (q, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals);
23092     if (q->linked != NULL) {
23093       q_l = FindLinkedQual(wiz, q->linked);
23094       if (q_l != NULL) {
23095         pos_l = GetPositionForQual (q_l, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals);
23096         for (vnp_row = table, i = 0; vnp_row != NULL; vnp_row = vnp_row->next, i++) {
23097           val1 = GetNthField (vnp_row->data.ptrvalue, pos_q);
23098           val2 = GetNthField (vnp_row->data.ptrvalue, pos_l);
23099           if ((StringHasNoText (val1) && !StringHasNoText (val2)) || (!StringHasNoText (val1) && StringHasNoText (val2))) {
23100             SetStringValue (&(problems[i]), "Must provide both  ", ExistingTextOption_append_semi);
23101             SetStringValue (&(problems[i]), q->name, ExistingTextOption_append_none);
23102             SetStringValue (&(problems[i]), " and ", ExistingTextOption_append_none);
23103             SetStringValue (&(problems[i]), q_l->name, ExistingTextOption_append_none);
23104           }
23105         }
23106       }
23107     }
23108   }
23109 }
23110 
23111 
23112 static void
GetLinkedProblemsForTable(ValNodePtr table,WizardTrackerPtr wiz,CharPtr PNTR problems)23113 GetLinkedProblemsForTable
23114 (ValNodePtr table,
23115  WizardTrackerPtr wiz,
23116  CharPtr PNTR problems)
23117 {
23118   AddLinkedProblemsForTableForQualList (table, wiz, problems, wiz->base_src_quals);
23119   AddLinkedProblemsForTableForQualList (table, wiz, problems, wiz->extra_src_quals);
23120   AddLinkedProblemsForTableForQualList (table, wiz, problems, wiz->feature_quals);
23121 }
23122 
23123 static CharPtr PNTR
GetProblemsLists(ValNodePtr table,WizardTrackerPtr wiz,ValNodePtr uniqueness_list)23124 GetProblemsLists
23125 (ValNodePtr table,
23126  WizardTrackerPtr wiz,
23127  ValNodePtr uniqueness_list)
23128 {
23129   ValNodePtr        row_vnp, col_vnp;
23130   Int4              row_num, num_rows, i;
23131   CharPtr PNTR      problems;
23132   BioseqPtr         bsp;
23133   IDAndTitleEditPtr iatep;
23134 
23135   num_rows = ValNodeLen (table);
23136   problems = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_rows);
23137   MemSet (problems, 0, sizeof (CharPtr) * num_rows);
23138   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
23139 
23140   for (row_vnp = table, row_num = 0; row_vnp != NULL; row_vnp = row_vnp->next, row_num++) {
23141     col_vnp = row_vnp->data.ptrvalue;
23142     bsp = NULL;
23143     for (i = 0; i < iatep->num_sequences && bsp == NULL; i++) {
23144       if (StringCmp (col_vnp->data.ptrvalue, iatep->id_list[i]) == 0) {
23145         bsp = FindNthSequenceInSet (wiz->sequences, i, NULL, TRUE);
23146       }
23147     }
23148     problems[row_num] = GetLineProblems (row_vnp->data.ptrvalue, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals, bsp);
23149   }
23150 
23151   GetUniquenessProblemsForTable (table, uniqueness_list, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals, problems);
23152   GetLinkedProblemsForTable (table, wiz, problems);
23153   iatep = IDAndTitleEditFree (iatep);
23154   return problems;
23155 }
23156 
23157 
23158 /* Notes - for tab table to multimod table to work, need to store original position
23159  * (otherwise impossible to tell which items were added or deleted).
23160  * Use 1-based counting, 0 means row was added.
23161  */
TabTableToMultiModTabTable(ValNodePtr table,DialoG d,WizardTrackerPtr wiz,ValNodePtr uniqueness_list,Boolean show_all)23162 static ValNodePtr TabTableToMultiModTabTable
23163 (ValNodePtr table,
23164  DialoG d,
23165  WizardTrackerPtr wiz,
23166  ValNodePtr uniqueness_list,
23167  Boolean show_all)
23168 {
23169   CharPtr      line;
23170   ValNodePtr   list = NULL;
23171   TagListPtr   tlp;
23172   Int4         i, j;
23173   Int2         max = 0;
23174   CharPtr PNTR problems;
23175   ValNodePtr   row_vnp, col_vnp;
23176   Int4         row_len, row_num = 1, num_rows;
23177   ValNodePtr   rows_displayed = NULL;
23178   BioseqPtr    bsp = NULL;
23179 
23180   tlp = (TagListPtr) GetObjectExtra (d);
23181   if (tlp == NULL) {
23182     return rows_displayed;
23183   }
23184   num_rows = ValNodeLen (table);
23185 
23186   problems = GetProblemsLists (table, wiz, uniqueness_list);
23187   for (row_vnp = table, row_num = 0; row_vnp != NULL; row_vnp = row_vnp->next, row_num++) {
23188     /* TODO - change problem function to take list of values */
23189     if (show_all || !StringHasNoText (problems[row_num])) {
23190       row_len = 2 + StringLen (problems[row_num]);
23191       for (col_vnp = row_vnp->data.ptrvalue; col_vnp != NULL; col_vnp = col_vnp->next) {
23192         row_len += StringLen (col_vnp->data.ptrvalue) + 1;
23193       }
23194       line = (CharPtr) MemNew (sizeof (Char) * row_len);
23195       line[0] = 0;
23196       for (col_vnp = row_vnp->data.ptrvalue; col_vnp != NULL; col_vnp = col_vnp->next) {
23197         StringCat (line, col_vnp->data.ptrvalue);
23198         StringCat (line, "\t");
23199       }
23200       if (problems[row_num] != NULL) {
23201         StringCat (line, problems[row_num]);
23202       }
23203       ValNodeAddPointer (&list, 0, line);
23204       ValNodeAddInt (&rows_displayed, 0, row_num);
23205       max++;
23206     }
23207   }
23208   for (row_num = 0; row_num < num_rows; row_num++) {
23209     problems[row_num] = MemFree (problems[row_num]);
23210   }
23211   problems = MemFree (problems);
23212 
23213   SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
23214   tlp->vnp = list;
23215   SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
23216   tlp->max = MAX ((Int2) 0, (Int2) (max - tlp->rows));
23217   CorrectBarMax (tlp->bar, tlp->max);
23218   CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
23219 
23220   /* hide controls we might not be using (if hiding rows without errors) */
23221   for (i = 0; i < MIN (max, tlp->rows); i++) {
23222     for (j = 0; j < tlp->cols; j++) {
23223       SafeShow (tlp->control [i * MAX_TAGLIST_COLS + j]);
23224     }
23225   }
23226   if (tlp->max > 0) {
23227     SafeShow (tlp->bar);
23228     SafeShow (tlp->left_bar);
23229   } else {
23230     SafeHide (tlp->bar);
23231     SafeHide (tlp->left_bar);
23232     for (i = max; i < tlp->rows; i ++) {
23233       for (j = 0; j < tlp->cols; j++) {
23234         SafeHide (tlp->control [i * MAX_TAGLIST_COLS + j]);
23235       }
23236     }
23237   }
23238   return rows_displayed;
23239 }
23240 
23241 
MultiModTableToTabTable(ValNodePtr table,DialoG d,ValNodePtr rows_displayed,ValNodePtr base_src_quals,ValNodePtr extra_src_quals,ValNodePtr fquals)23242 static void MultiModTableToTabTable
23243 (ValNodePtr table,
23244  DialoG d,
23245  ValNodePtr rows_displayed,
23246  ValNodePtr base_src_quals,
23247  ValNodePtr extra_src_quals,
23248  ValNodePtr fquals)
23249 {
23250   CharPtr      val;
23251   ValNodePtr   vnp, vnp_row, q_vnp, vnp_col, vnp_x;
23252   TagListPtr   tlp;
23253   Int4         j;
23254   Int4         row_num = 0, edited_num;
23255   Int4         num_columns;
23256   WizardSrcQualPtr  sq;
23257   WizardFeatQualPtr fq;
23258 
23259   if (table == NULL) {
23260     return;
23261   }
23262   num_columns = ValNodeLen (base_src_quals) + ValNodeLen (fquals);
23263   for (vnp = extra_src_quals; vnp != NULL; vnp = vnp->next) {
23264     sq = (WizardSrcQualPtr) vnp->data.ptrvalue;
23265     if (sq->show) {
23266       num_columns++;
23267     }
23268   }
23269 
23270   tlp = (TagListPtr) GetObjectExtra (d);
23271   if (tlp == NULL) {
23272     return;
23273   }
23274 
23275   vnp_row = table;
23276   for (vnp = tlp->vnp, vnp_x = rows_displayed; vnp != NULL && vnp_x != NULL; vnp = vnp->next, vnp_x = vnp_x->next) {
23277     edited_num = vnp_x->data.intvalue;
23278     while (row_num < edited_num) {
23279       vnp_row = vnp_row->next;
23280       row_num++;
23281     }
23282 
23283     /* apply values */
23284     vnp_col = vnp_row->data.ptrvalue;
23285     /* first column, ID, stays, everything else goes */
23286     vnp_col->next = ValNodeFreeData (vnp_col->next);
23287     for (j = 0, q_vnp = base_src_quals; q_vnp != NULL; j++, q_vnp = q_vnp->next) {
23288       val = ExtractTagListColumn (vnp->data.ptrvalue, j + 1);
23289       sq = (WizardSrcQualPtr) q_vnp->data.ptrvalue;
23290       ValNodeAddPointer (&vnp_col, 0, val);
23291     }
23292     for (q_vnp = extra_src_quals; q_vnp != NULL; q_vnp = q_vnp->next) {
23293       val = ExtractTagListColumn (vnp->data.ptrvalue, j + 1);
23294       sq = (WizardSrcQualPtr) q_vnp->data.ptrvalue;
23295       if (sq->show) {
23296         ValNodeAddPointer (&vnp_col, 0, val);
23297         j++;
23298       }
23299     }
23300     for (q_vnp = fquals; q_vnp != NULL; j++, q_vnp = q_vnp->next) {
23301       val = ExtractTagListColumn (vnp->data.ptrvalue, j + 1);
23302       fq = (WizardFeatQualPtr) q_vnp->data.ptrvalue;
23303       ValNodeAddPointer (&vnp_col, 0, val);
23304     }
23305   }
23306 }
23307 
23308 
23309 
NewFeatForAnnotList(CharPtr id,IDAndTitleEditPtr iatep,SeqEntryPtr sep_list)23310 static SeqFeatPtr NewFeatForAnnotList (CharPtr id, IDAndTitleEditPtr iatep, SeqEntryPtr sep_list)
23311 {
23312   SeqFeatPtr sfp;
23313   SeqIntPtr  sint;
23314   BioseqPtr  bsp;
23315   Int4       pos;
23316 
23317   sint = SeqIntNew ();
23318   sint->id = MakeSeqID (id);
23319   sint->from = 0;
23320   pos = FindIdInIdAndTitleEdit (sint->id, iatep);
23321   bsp = FindNthSequenceInSet (sep_list, pos, NULL, TRUE);
23322   if (bsp != NULL) {
23323     sint->to = bsp->length - 1;
23324   }
23325   sfp = SeqFeatNew ();
23326   sfp->location = ValNodeNew (NULL);
23327   sfp->location->choice = SEQLOC_INT;
23328   sfp->location->data.ptrvalue = sint;
23329   return sfp;
23330 }
23331 
23332 
MakeSeqFeatMicrosatellite(SeqFeatPtr sfp)23333 static void MakeSeqFeatMicrosatellite (SeqFeatPtr sfp)
23334 {
23335   ImpFeatPtr imp;
23336   GBQualPtr gb, gb2;
23337 
23338   if (sfp == NULL) {
23339     return;
23340   }
23341 
23342   imp = ImpFeatNew ();
23343   imp->key = StringSave ("repeat_region");
23344   sfp->data.value.ptrvalue = imp;
23345   sfp->data.choice = SEQFEAT_IMP;
23346   gb = GBQualNew ();
23347   gb->qual = StringSave ("rpt_type");
23348   gb->val = StringSave ("tandem");
23349   sfp->qual = gb;
23350   gb2 = GBQualNew ();
23351   gb2->qual = StringSave ("satellite");
23352   gb2->val = StringSave ("microsatellite");
23353   gb->next = gb2;
23354 }
23355 
23356 
MakeSapIdIndex(ValNodePtr annot_list)23357 static CharPtr PNTR MakeSapIdIndex (ValNodePtr annot_list)
23358 {
23359   Int4 num_saps, i;
23360   CharPtr PNTR sap_ids = NULL;
23361   ValNodePtr sap_vnp;
23362   SeqAnnotPtr sap;
23363   SeqFeatPtr sfp;
23364 
23365   num_saps = ValNodeLen (annot_list);
23366   if (num_saps > 0) {
23367     sap_ids = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_saps);
23368     for (sap_vnp = annot_list, i = 0; sap_vnp != NULL && i < num_saps; sap_vnp = sap_vnp->next, i++) {
23369       sap = (SeqAnnotPtr) sap_vnp->data.ptrvalue;
23370       if (sap != NULL && sap->type == 1) {
23371         sfp = (SeqFeatPtr) sap->data;
23372         sap_ids[i] = SeqIdWholeLabel (SeqLocId (sfp->location), PRINTID_REPORT);
23373       }
23374     }
23375   }
23376   return sap_ids;
23377 }
23378 
23379 
FreeSapIdIndex(CharPtr PNTR sap_ids,Int4 num_saps)23380 static CharPtr PNTR FreeSapIdIndex (CharPtr PNTR sap_ids, Int4 num_saps)
23381 {
23382   Int4 i;
23383 
23384   for (i = 0; i < num_saps; i++) {
23385     sap_ids[i] = MemFree (sap_ids[i]);
23386   }
23387   sap_ids = MemFree (sap_ids);
23388   return sap_ids;
23389 }
23390 
23391 
TabTableToSeqAnnotList(ValNodePtr PNTR annot_list,ValNodePtr table,ValNodePtr base_src_quals,ValNodePtr extra_src_quals,ValNodePtr fquals,IDAndTitleEditPtr iatep,SeqEntryPtr sep_list)23392 static void TabTableToSeqAnnotList
23393 (ValNodePtr PNTR annot_list,
23394  ValNodePtr table,
23395  ValNodePtr base_src_quals,
23396  ValNodePtr extra_src_quals,
23397  ValNodePtr fquals,
23398  IDAndTitleEditPtr iatep,
23399  SeqEntryPtr sep_list)
23400 {
23401   CharPtr      this_id, last_id = NULL, val;
23402   ValNodePtr   sap_vnp = NULL, q_vnp, row_vnp, col_vnp;
23403   Int4         i = 0;
23404   Int4         num_saps;
23405   CharPtr PNTR sap_ids = NULL;
23406   SeqFeatPtr   sfp = NULL, last_sfp = NULL;
23407   SeqAnnotPtr  sap;
23408   WizardSrcQualPtr  sq;
23409   WizardFeatQualPtr fq;
23410 
23411   if (annot_list == NULL) {
23412     return;
23413   }
23414 
23415   num_saps = ValNodeLen (*annot_list);
23416   sap_ids = MakeSapIdIndex(*annot_list);
23417 
23418   for (row_vnp = table; row_vnp != NULL; row_vnp = row_vnp->next) {
23419     col_vnp = row_vnp->data.ptrvalue;
23420     this_id = col_vnp->data.ptrvalue;
23421     if (StringCmp (this_id, last_id) == 0) {
23422       if (last_sfp != NULL && last_sfp->next == NULL) {
23423         sfp = NewFeatForAnnotList (this_id, iatep, sep_list);
23424         MakeSeqFeatMicrosatellite (sfp);
23425         last_sfp->next = sfp;
23426       }
23427       if (last_sfp != NULL) {
23428         sfp = last_sfp->next;
23429       }
23430       this_id = MemFree (this_id);
23431     } else {
23432       i = 0;
23433       sap_vnp = *annot_list;
23434       while (i < num_saps && sap_vnp != NULL && StringCmp (this_id, sap_ids[i]) != 0) {
23435         i++;
23436         sap_vnp = sap_vnp->next;
23437       }
23438       if (sap_vnp == NULL) {
23439         sfp = NewFeatForAnnotList (this_id, iatep, sep_list);
23440         MakeSeqFeatMicrosatellite (sfp);
23441         sap = SeqAnnotNew ();
23442         sap->type = 1;
23443         sap->data = sfp;
23444         ValNodeAddPointer (annot_list, OBJ_SEQANNOT, sap);
23445         sap_ids = FreeSapIdIndex (sap_ids, num_saps);
23446         sap_ids = MakeSapIdIndex(*annot_list);
23447         num_saps++;
23448       } else {
23449         sap = sap_vnp->data.ptrvalue;
23450       }
23451       sfp = sap->data;
23452       last_id = this_id;
23453       this_id = NULL;
23454     }
23455 
23456     col_vnp = col_vnp->next;
23457     /* apply values to deflines */
23458     for (q_vnp = base_src_quals; q_vnp != NULL && col_vnp != NULL; q_vnp = q_vnp->next, col_vnp = col_vnp->next) {
23459       sq = (WizardSrcQualPtr) q_vnp->data.ptrvalue;
23460       val = col_vnp->data.ptrvalue;
23461       if (StringHasNoText (val)) {
23462         RemoveValueFromDefline (sq->name, iatep->title_list[i]);
23463       } else {
23464         iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], sq->name, val);
23465       }
23466     }
23467 
23468     for (q_vnp = extra_src_quals; q_vnp != NULL && col_vnp != NULL; q_vnp = q_vnp->next) {
23469       sq = (WizardSrcQualPtr) q_vnp->data.ptrvalue;
23470       if (sq->show) {
23471         val = col_vnp->data.ptrvalue;
23472         if (StringHasNoText (val)) {
23473           RemoveValueFromDefline (sq->name, iatep->title_list[i]);
23474         } else {
23475           iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], sq->name, val);
23476         }
23477         col_vnp = col_vnp->next;
23478       }
23479     }
23480 
23481     /* apply values to features */
23482     for (q_vnp = fquals; q_vnp != NULL && col_vnp != NULL; q_vnp = q_vnp->next, col_vnp = col_vnp->next) {
23483       val = col_vnp->data.ptrvalue;
23484       fq = (WizardFeatQualPtr) q_vnp->data.ptrvalue;
23485       (fq->apply_func) (sfp, val);
23486     }
23487   }
23488 
23489   sap_ids = FreeSapIdIndex (sap_ids, num_saps);
23490 }
23491 
23492 
SaveWizardFeatureQuals(Pointer data,WizardTrackerPtr wiz)23493 static void SaveWizardFeatureQuals (Pointer data, WizardTrackerPtr wiz)
23494 {
23495   WizardFeatureQualsFormPtr frm;
23496 
23497   frm = (WizardFeatureQualsFormPtr) data;
23498   if (frm == NULL) {
23499     return;
23500   }
23501   MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table, frm->rows_displayed, frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals);
23502 }
23503 
23504 
CountExistingTabValues(ValNodePtr table,Int4 col)23505 static Int4 CountExistingTabValues (ValNodePtr table, Int4 col)
23506 {
23507   ValNodePtr row_vnp;
23508   Int4       count = 0;
23509 
23510   for (row_vnp = table; row_vnp != NULL; row_vnp = row_vnp->next) {
23511     if (!StringHasNoText (GetNthField(row_vnp->data.ptrvalue, col))) {
23512       count++;
23513     }
23514   }
23515   return count;
23516 }
23517 
23518 
ApplyAllValueToFeatureQualsTable(ButtoN b)23519 static void ApplyAllValueToFeatureQualsTable (ButtoN b)
23520 {
23521   WizardFeatureQualsFormPtr frm;
23522   Int4 i, j, num_current;
23523   CharPtr val;
23524   ValNodePtr vnp_row, vnp_col, col_prev;
23525 
23526   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (b);
23527   if (frm == NULL) {
23528     return;
23529   }
23530 
23531   for (i = 0; i < frm->num_mods; i++) {
23532     if (frm->bulk_btns[i] == b) {
23533       break;
23534     }
23535   }
23536 
23537   if (i < frm->num_mods) {
23538     MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table,
23539                              frm->rows_displayed,
23540                              frm->wiz->base_src_quals, frm->wiz->extra_src_quals,
23541                              frm->wiz->feature_quals);
23542     num_current = CountExistingTabValues(frm->wiz->feat_qual_table, i + 1);
23543     if (num_current > 0) {
23544       if (ANS_OK != Message (MSG_OKC, "You already have %d values for %s - do you want to replace them?",
23545                              num_current, frm->mod_names[i])) {
23546         return;
23547       }
23548     }
23549 
23550     val = SaveStringFromText (frm->apply_all_txt[i]);
23551     for (vnp_row = frm->wiz->feat_qual_table; vnp_row != NULL; vnp_row = vnp_row->next) {
23552       for (vnp_col = vnp_row->data.ptrvalue, j = 0, col_prev = NULL;
23553            vnp_col != NULL && j < i + 1;
23554            vnp_col = vnp_col->next, j++) {
23555         col_prev = vnp_col;
23556       }
23557       while (j < i + 1) {
23558         /* add blanks to end of row if necessary */
23559         vnp_col = ValNodeNew (NULL);
23560         col_prev->next = vnp_col;
23561         col_prev = vnp_col;
23562         j++;
23563       }
23564       vnp_col->data.ptrvalue = MemFree (vnp_col->data.ptrvalue);
23565       vnp_col->data.ptrvalue = StringSave (val);
23566     }
23567     val = MemFree (val);
23568     TabTableToMultiModTabTable (frm->wiz->feat_qual_table, frm->qual_table,
23569                                 frm->wiz, frm->wiz->uniqueness_list,
23570                                 ShouldShowAll((WizardQualsFormPtr)frm));
23571   }
23572 }
23573 
23574 
CopyFeatureValuesFromId(ButtoN b)23575 static void CopyFeatureValuesFromId (ButtoN b)
23576 {
23577   WizardFeatureQualsFormPtr frm;
23578   Int4 i, j, num_current;
23579   CharPtr val;
23580   ValNodePtr vnp_row, vnp_col, col_prev;
23581 
23582   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (b);
23583   if (frm == NULL) {
23584     return;
23585   }
23586 
23587   for (i = 0; i < frm->num_mods; i++) {
23588     if (frm->bulk_btns[i] == b) {
23589       break;
23590     }
23591   }
23592 
23593   if (i < frm->num_mods) {
23594     MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table,
23595                              frm->rows_displayed,
23596                              frm->wiz->base_src_quals, frm->wiz->extra_src_quals,
23597                              frm->wiz->feature_quals);
23598 
23599     num_current = CountExistingTabValues(frm->wiz->feat_qual_table, i + 1);
23600     if (num_current > 0) {
23601       if (ANS_OK != Message (MSG_OKC, "You already have %d values for %s - do you want to replace them?",
23602                              num_current, frm->mod_names[i])) {
23603         return;
23604       }
23605     }
23606     for (vnp_row = frm->wiz->feat_qual_table; vnp_row != NULL; vnp_row = vnp_row->next) {
23607       vnp_col = vnp_row->data.ptrvalue;
23608       val = vnp_col->data.ptrvalue;
23609       for (vnp_col = vnp_row->data.ptrvalue, j = 0, col_prev = NULL;
23610            vnp_col != NULL && j < i + 1;
23611            vnp_col = vnp_col->next, j++) {
23612         col_prev = vnp_col;
23613       }
23614       while (j < i + 1) {
23615         /* add blanks to end of row if necessary */
23616         vnp_col = ValNodeNew (NULL);
23617         col_prev->next = vnp_col;
23618         col_prev = vnp_col;
23619         j++;
23620       }
23621       vnp_col->data.ptrvalue = MemFree (vnp_col->data.ptrvalue);
23622       vnp_col->data.ptrvalue = StringSave (val);
23623     }
23624     TabTableToMultiModTabTable (frm->wiz->feat_qual_table, frm->qual_table,
23625                                 frm->wiz, frm->wiz->uniqueness_list,
23626                                 ShouldShowAll((WizardQualsFormPtr)frm));
23627   }
23628 }
23629 
23630 
MakeFeatureQualHeaders(GrouP g,WizardFeatureQualsFormPtr frm)23631 static void MakeFeatureQualHeaders (GrouP g, WizardFeatureQualsFormPtr frm)
23632 {
23633   Int4 i;
23634   Int4 grp_len = 5;
23635   ValNodePtr vnp;
23636   TexT t;
23637   WizardFeatQualPtr q;
23638 
23639   frm->ed_grps = (GrouP PNTR) MemNew (sizeof (GrouP) * frm->num_mods);
23640   frm->apply_all_txt = (TexT PNTR) MemNew (sizeof (TexT) * frm->num_mods);
23641   frm->bulk_btns = (ButtoN PNTR) MemNew (sizeof (ButtoN) * frm->num_mods);
23642 
23643   for (i = 0; i < frm->num_src_quals; i++) {
23644     frm->ed_grps[i] = HiddenGroup (g, 0, grp_len, NULL);
23645     SetGroupSpacing (frm->ed_grps[i], 10, 10);
23646     switch (frm->edit_types[i]) {
23647       case eWizardEditQual_ApplyAll:
23648         StaticPrompt (frm->ed_grps[i], "Set", 0, 0, programFont, 'c');
23649         StaticPrompt (frm->ed_grps[i], frm->mod_names[i], 0, 0, programFont, 'c');
23650         StaticPrompt (frm->ed_grps[i], "for All", 0, 0, programFont, 'c');
23651         frm->apply_all_txt[i] = DialogText (frm->ed_grps[i], "", 8, NULL);
23652         frm->bulk_btns[i] = PushButton (frm->ed_grps[i], "Apply", ApplyAllValueToFeatureQualsTable);
23653         SetObjectExtra (frm->bulk_btns[i], frm, NULL);
23654         break;
23655       case eWizardEditQual_CopyFromId:
23656         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23657         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23658         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23659         t = DialogText (frm->ed_grps[i], "", 8, NULL);
23660         Hide (t);
23661         frm->bulk_btns[i] = PushButton (frm->ed_grps[i], "Copy from SeqId", CopyFeatureValuesFromId);
23662         SetObjectExtra (frm->bulk_btns[i], frm, NULL);
23663         break;
23664       default:
23665         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23666         break;
23667     }
23668   }
23669 
23670   for (vnp = frm->wiz->feature_quals; i < frm->num_mods && vnp != NULL; i++, vnp = vnp->next) {
23671     frm->ed_grps[i] = HiddenGroup (g, 0, grp_len, NULL);
23672     SetGroupSpacing (frm->ed_grps[i], 10, 10);
23673     q = (WizardFeatQualPtr) vnp->data.ptrvalue;
23674     switch (q->edit_type) {
23675       case eWizardEditQual_ApplyAll:
23676         StaticPrompt (frm->ed_grps[i], "Set", 0, 0, programFont, 'c');
23677         StaticPrompt (frm->ed_grps[i], q->name, 0, 0, programFont, 'c');
23678         StaticPrompt (frm->ed_grps[i], "for All", 0, 0, programFont, 'c');
23679         frm->apply_all_txt[i] = DialogText (frm->ed_grps[i], "", 8, NULL);
23680         frm->bulk_btns[i] = PushButton (frm->ed_grps[i], "Apply", ApplyAllValueToFeatureQualsTable);
23681         SetObjectExtra (frm->bulk_btns[i], frm, NULL);
23682         break;
23683       case eWizardEditQual_CopyFromId:
23684         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23685         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23686         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23687         t = DialogText (frm->ed_grps[i], "", 8, NULL);
23688         Hide (t);
23689         frm->bulk_btns[i] = PushButton (frm->ed_grps[i], "Copy from SeqId", CopyFeatureValuesFromId);
23690         SetObjectExtra (frm->bulk_btns[i], frm, NULL);
23691         break;
23692       case eWizardEditQual_Range:
23693         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23694         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23695         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23696         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23697         StaticPrompt (frm->ed_grps[i], q->name, 0, 0, programFont, 'c');
23698         break;
23699       default:
23700         StaticPrompt (frm->ed_grps[i], "", 0, 0, programFont, 'c');
23701         break;
23702     }
23703   }
23704 }
23705 
23706 
GetFeatureQualExampleText(WizardTrackerPtr wiz,Int4 num_mods)23707 static CharPtr PNTR GetFeatureQualExampleText (WizardTrackerPtr wiz, Int4 num_mods)
23708 {
23709   CharPtr PNTR example_text;
23710   ValNodePtr vnp;
23711   WizardFeatQualPtr fq;
23712   WizardSrcQualPtr  sq;
23713   Boolean any = FALSE;
23714   Int4    i;
23715 
23716   example_text = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_mods);
23717   MemSet (example_text, 0, sizeof (CharPtr) * num_mods);
23718 
23719   for (vnp = wiz->base_src_quals, i = 0; vnp != NULL; vnp = vnp->next) {
23720     if ((sq = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL) {
23721       if (sq->example != NULL) {
23722         any = TRUE;
23723         example_text[i] = sq->example;
23724       }
23725       i++;
23726     }
23727   }
23728 
23729   for (vnp = wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
23730     if ((sq = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && sq->show) {
23731       if (sq->example != NULL) {
23732         any = TRUE;
23733         example_text[i] = sq->example;
23734       }
23735       i++;
23736     }
23737   }
23738 
23739   for (vnp = wiz->feature_quals; vnp != NULL; vnp = vnp->next, i++) {
23740     if ((fq = (WizardFeatQualPtr) vnp->data.ptrvalue) != NULL
23741         && fq->example != NULL) {
23742       any = TRUE;
23743       example_text[i] = fq->example;
23744     }
23745   }
23746 
23747   if (!any) {
23748     example_text = MemFree (example_text);
23749   }
23750   return example_text;
23751 }
23752 
23753 
CleanupWizardFeatureQualsForm(GraphiC g,Pointer data)23754 static void CleanupWizardFeatureQualsForm (GraphiC g, Pointer data)
23755 {
23756   WizardFeatureQualsFormPtr frm;
23757 
23758   if (data != NULL)
23759   {
23760     frm = (WizardFeatureQualsFormPtr) data;
23761     frm->iatep = IDAndTitleEditFree (frm->iatep);
23762     frm->rows_displayed = ValNodeFree (frm->rows_displayed);
23763     frm->extra_btns = MemFree (frm->extra_btns);
23764     frm->ed_grps = MemFree (frm->ed_grps);
23765     frm->apply_all_txt = MemFree (frm->apply_all_txt);
23766     frm->bulk_btns = MemFree (frm->bulk_btns);
23767 
23768     frm->wiz = WizardTrackerFree(frm->wiz);
23769   }
23770   StdCleanupFormProc (g, data);
23771 }
23772 
23773 
ShowAllFeatureQualSequences(GrouP g)23774 static void ShowAllFeatureQualSequences (GrouP g)
23775 {
23776   WizardFeatureQualsFormPtr frm;
23777   Boolean     show_all = TRUE;
23778 
23779   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (g);
23780   if (frm == NULL) {
23781     return;
23782   }
23783 
23784   MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table, frm->rows_displayed,
23785                            frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals);
23786   if (GetValue (frm->show_all_grp) == 1) {
23787     show_all = FALSE;
23788   }
23789 
23790   frm->rows_displayed = ValNodeFree (frm->rows_displayed);
23791   frm->rows_displayed = TabTableToMultiModTabTable (frm->wiz->feat_qual_table, frm->qual_table,
23792                               frm->wiz,
23793                               frm->wiz->uniqueness_list,
23794                               ShouldShowAll((WizardQualsFormPtr)frm));
23795 }
23796 
23797 
RecheckFeatureQualErrors(ButtoN b)23798 static void RecheckFeatureQualErrors (ButtoN b)
23799 {
23800   WizardFeatureQualsFormPtr frm;
23801 
23802   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (b);
23803   if (frm == NULL) {
23804     return;
23805   }
23806 
23807   MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table,
23808                            frm->rows_displayed,
23809                            frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals);
23810 
23811   frm->rows_displayed = ValNodeFree (frm->rows_displayed);
23812   frm->rows_displayed = TabTableToMultiModTabTable(frm->wiz->feat_qual_table,
23813                            frm->qual_table,
23814                            frm->wiz,
23815                            frm->wiz->uniqueness_list,
23816                           ShouldShowAll((WizardQualsFormPtr)frm));
23817 
23818 }
23819 
23820 
InsertBlankColumnAfterN(ValNodePtr table,Int4 n)23821 static void InsertBlankColumnAfterN (ValNodePtr table, Int4 n)
23822 {
23823   ValNodePtr vnp_row, vnp_col, vnp_prev, vnp_new;
23824   Int4       i;
23825 
23826   for (vnp_row = table; vnp_row != NULL; vnp_row = vnp_row->next) {
23827     vnp_prev = NULL;
23828     for (vnp_col = vnp_row->data.ptrvalue, i = 0; vnp_col != NULL && i < n; vnp_col = vnp_col->next, i++) {
23829       vnp_prev = vnp_col;
23830     }
23831     if (vnp_col == NULL) {
23832       vnp_col = vnp_prev;
23833     }
23834     if (vnp_col != NULL) {
23835       vnp_new = ValNodeNew (NULL);
23836       vnp_new->next = vnp_col->next;
23837       vnp_col->next = vnp_new;
23838     }
23839   }
23840 }
23841 
23842 
AddExtraTabEditorColumn(ButtoN b)23843 static void AddExtraTabEditorColumn (ButtoN b)
23844 {
23845   WizardFeatureQualsFormPtr frm;
23846   WizardTrackerPtr wiz;
23847   Int4 i, j;
23848   Boolean found = FALSE;
23849   WizardSrcQualPtr q;
23850   ValNodePtr vnp;
23851   Int4 num_extra = 0;
23852 
23853   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (b);
23854   if (frm == NULL) {
23855     return;
23856   }
23857 
23858   MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table, frm->rows_displayed, frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals);
23859 
23860 
23861   i = 0, j = 0;
23862   for (vnp = frm->wiz->extra_src_quals; vnp != NULL && !found; vnp = vnp->next) {
23863     if ((q = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && !q->show && q->linked == NULL) {
23864       if (b == frm->extra_btns[i]) {
23865         q->show = TRUE;
23866         found = TRUE;
23867         num_extra = ShowLinkedQuals (frm->wiz->extra_src_quals, q->name);
23868       } else {
23869         i++;
23870       }
23871     } else if (q != NULL && q->show) {
23872       j++;
23873     }
23874   }
23875 
23876   if (!found) {
23877     return;
23878   }
23879 
23880   /* insert blank column in tab table */
23881   InsertBlankColumnAfterN (frm->wiz->feat_qual_table, ValNodeLen (frm->wiz->base_src_quals) + j);
23882   for (i = 0; i < num_extra; i++) {
23883     InsertBlankColumnAfterN (frm->wiz->feat_qual_table, ValNodeLen (frm->wiz->base_src_quals) + j);
23884   }
23885 
23886   wiz = frm->wiz;
23887   frm->wiz = NULL;
23888   Hide (frm->form);
23889 
23890   if (CreateFeatureQualsForm (wiz)) {
23891     Remove (frm->form);
23892   } else {
23893     frm->wiz = wiz;
23894   }
23895 }
23896 
23897 
ClearFeatureQuals(ButtoN b)23898 static void ClearFeatureQuals (ButtoN b)
23899 {
23900   WizardFeatureQualsFormPtr frm;
23901   ValNodePtr vnp_row, vnp_col;
23902 
23903   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (b);
23904   if (frm == NULL) {
23905     return;
23906   }
23907 
23908   for (vnp_row = frm->wiz->feat_qual_table; vnp_row != NULL; vnp_row = vnp_row->next) {
23909     vnp_col = vnp_row->data.ptrvalue;
23910     /* skip over first column, which contains IDs, clear all remaining values */
23911     for (vnp_col = vnp_col->next; vnp_col != NULL; vnp_col = vnp_col->next) {
23912       vnp_col->data.ptrvalue = MemFree (vnp_col->data.ptrvalue);
23913     }
23914   }
23915 
23916 
23917   TabTableToMultiModTabTable (frm->wiz->feat_qual_table, frm->qual_table,
23918                               frm->wiz, frm->wiz->uniqueness_list,
23919                               ShouldShowAll((WizardQualsFormPtr)frm));
23920 
23921 }
23922 
23923 
23924 static ValNodePtr SrcQualsAndSeqAnnotListToTabTable
23925 (IDAndTitleEditPtr iatep,
23926  ValNodePtr base_src_quals,
23927  ValNodePtr extra_src_quals,
23928  ValNodePtr annot_list,
23929  ValNodePtr fquals);
23930 
23931 
ApplyMoreFeatureInfo(ButtoN b)23932 static void ApplyMoreFeatureInfo (ButtoN b)
23933 {
23934   WizardFeatureQualsFormPtr frm;
23935   Int4 doc_width;
23936 
23937   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (b);
23938   if (frm == NULL) {
23939     return;
23940   }
23941 
23942   MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table, frm->rows_displayed, frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals);
23943   TabTableToSeqAnnotList (&(frm->wiz->annot_list), frm->wiz->feat_qual_table, frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals,
23944                             frm->iatep, frm->wiz->sequences);
23945   ApplyIDAndTitleEditToSeqEntryList (frm->wiz->sequences, frm->iatep);
23946   SelectFont (GetTableDisplayDefaultFont ());
23947   doc_width = CharWidth ('0') * 40;
23948 
23949   if (SourceAssistantForDeflines (frm->wiz->sequences, doc_width, SEQ_PKG_ENVIRONMENT)) {
23950     frm->iatep = IDAndTitleEditFree (frm->iatep);
23951     frm->iatep = SeqEntryListToIDAndTitleEditEx (frm->wiz->sequences, TRUE);
23952     frm->wiz->feat_qual_table = FreeTabTable (frm->wiz->feat_qual_table);
23953     frm->wiz->feat_qual_table = SrcQualsAndSeqAnnotListToTabTable (frm->iatep,
23954                                                               frm->wiz->base_src_quals,
23955                                                               frm->wiz->extra_src_quals,
23956                                                               frm->wiz->annot_list,
23957                                                               frm->wiz->feature_quals);
23958     TabTableToMultiModTabTable (frm->wiz->feat_qual_table, frm->qual_table,
23959                                 frm->wiz, frm->wiz->uniqueness_list,
23960                                 ShouldShowAll((WizardQualsFormPtr)frm));
23961 
23962   }
23963 }
23964 
23965 
GetWizardQualPos(CharPtr q_name,WizardTrackerPtr wiz)23966 static Int4 GetWizardQualPos (CharPtr q_name, WizardTrackerPtr wiz)
23967 {
23968   WizardQualPtr q;
23969   ValNodePtr    vnp;
23970   Int4          i = 1; /* note - starts with 1 because 0 is sequence ID */
23971 
23972   if (StringHasNoText (q_name) || wiz == NULL) {
23973     return -1;
23974   }
23975 
23976   for (vnp = wiz->base_src_quals; vnp != NULL; vnp = vnp->next, i++) {
23977     q = (WizardQualPtr) vnp->data.ptrvalue;
23978     if (q != NULL && StringsAreEquivalent (q->name, q_name)) {
23979       return i;
23980     } else if (q != NULL && q->edit_type == eWizardEditQual_Range) {
23981       if (StringsAreEquivalent (q_name, "begin")) {
23982         return i;
23983       } else if (StringsAreEquivalent (q_name, "end")) {
23984         return i + 1;
23985       }
23986       i++;
23987     }
23988   }
23989   for (vnp = wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
23990     q = (WizardQualPtr) vnp->data.ptrvalue;
23991     if (q != NULL && q->show) {
23992       if (StringsAreEquivalent (q->name, q_name)) {
23993         return i;
23994       } else if (q->edit_type == eWizardEditQual_Range) {
23995         if (StringsAreEquivalent (q_name, "begin")) {
23996           return i;
23997         } else if (StringsAreEquivalent (q_name, "end")) {
23998           return i + 1;
23999         }
24000         i+=2;
24001       } else {
24002         i++;
24003       }
24004     }
24005   }
24006   for (vnp = wiz->feature_quals; vnp != NULL; vnp = vnp->next, i++) {
24007     q = (WizardQualPtr) vnp->data.ptrvalue;
24008     if (q != NULL && StringsAreEquivalent (q->name, q_name)) {
24009       return i;
24010     } else if (q != NULL && q->edit_type == eWizardEditQual_Range) {
24011       if (StringsAreEquivalent (q_name, "begin")) {
24012         return i;
24013       } else if (StringsAreEquivalent (q_name, "end")) {
24014         return i + 1;
24015       }
24016       i++;
24017     }
24018   }
24019 
24020   return -1;
24021 }
24022 
24023 
InUnshownQuals(CharPtr val,ValNodePtr extra_src_quals)24024 static WizardQualPtr InUnshownQuals (CharPtr val, ValNodePtr extra_src_quals)
24025 {
24026   WizardQualPtr q;
24027   ValNodePtr vnp;
24028 
24029   for (vnp = extra_src_quals; vnp != NULL; vnp = vnp->next) {
24030     q = (WizardQualPtr) vnp->data.ptrvalue;
24031     if (!q->show && StringsAreEquivalent (val, q->name)) {
24032       return q;
24033     }
24034   }
24035   return NULL;
24036 }
24037 
24038 
AddColumnToTable(ValNodePtr table,CharPtr q_name,WizardTrackerPtr wiz)24039 static void AddColumnToTable (ValNodePtr table, CharPtr q_name, WizardTrackerPtr wiz)
24040 {
24041   Int4 start, pos;
24042   WizardQualPtr q;
24043   ValNodePtr vnp;
24044 
24045   start = ValNodeLen (wiz->base_src_quals);
24046   pos = start;
24047 
24048   for (vnp = wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
24049     q = vnp->data.ptrvalue;
24050     if (q->show) {
24051       pos++;
24052     } else if (StringICmp (q_name, q->name) == 0 || StringICmp (q_name, q->linked) == 0) {
24053       q->show = TRUE;
24054       InsertBlankColumnAfterN (wiz->feat_qual_table, pos);
24055       pos++;
24056     }
24057   }
24058 }
24059 
24060 
ValidateWizardColumnNames(ValNodePtr header,WizardTrackerPtr wiz,BoolPtr added_columns)24061 static ValNodePtr ValidateWizardColumnNames (ValNodePtr header, WizardTrackerPtr wiz, BoolPtr added_columns)
24062 {
24063   ValNodePtr col_vnp, vnp;
24064   Boolean rval = TRUE;
24065   Int4    pos, col_pos;
24066   ValNodePtr pos_list = NULL;
24067   ValNodePtr extra_columns = NULL;
24068   WizardQualPtr q;
24069   Int4          start;
24070 
24071   *added_columns = FALSE;
24072   /* check ID column */
24073   if (!IsSequenceIdColumnHeader(header->data.ptrvalue))
24074   {
24075     Message (MSG_ERROR, "Table file is missing header line!  Make sure first column header is seq_id");
24076     return NULL;
24077   }
24078   col_vnp = header->next;
24079   col_pos = 2;
24080   while (col_vnp != NULL && rval) {
24081     pos = GetWizardQualPos(col_vnp->data.ptrvalue, wiz);
24082     if (pos < 0) {
24083       if (StringHasNoText (col_vnp->data.ptrvalue)) {
24084         Message (MSG_ERROR, "No column header for column %d, please edit your file and try again.", col_pos);
24085         pos_list = ValNodeFree (pos_list);
24086         rval = FALSE;
24087       } else if ((q = InUnshownQuals(col_vnp->data.ptrvalue, wiz->extra_src_quals)) != NULL) {
24088         ValNodeAddPointer (&extra_columns, 0, q);
24089       } else if (GetSourceQualTypeByName (col_vnp->data.ptrvalue) > -1) {
24090         ValNodeAddPointer (&pos_list, 1, col_vnp->data.ptrvalue);
24091       } else {
24092         Message (MSG_ERROR, "Unable to recognize %s as valid column header, please edit your file and try again.", col_vnp->data.ptrvalue);
24093         pos_list = ValNodeFree (pos_list);
24094         rval = FALSE;
24095       }
24096     } else {
24097       ValNodeAddInt (&pos_list, 0, pos);
24098     }
24099     col_vnp = col_vnp->next;
24100     col_pos++;
24101   }
24102 
24103   if (rval && extra_columns != NULL) {
24104     pos_list = ValNodeFree (pos_list);
24105     start = ValNodeLen (wiz->base_src_quals);
24106 
24107     for (vnp = extra_columns, pos = start; vnp != NULL; vnp = vnp->next, pos++) {
24108       q = vnp->data.ptrvalue;
24109       AddColumnToTable (wiz->feat_qual_table, q->name, wiz);
24110     }
24111     col_vnp = header->next;
24112     col_pos = 2;
24113     while (col_vnp != NULL) {
24114       pos = GetWizardQualPos(col_vnp->data.ptrvalue, wiz);
24115       if (pos < 0) {
24116         ValNodeAddPointer (&pos_list, 1, col_vnp->data.ptrvalue);
24117       } else {
24118         ValNodeAddInt (&pos_list, 0, pos);
24119       }
24120       col_vnp = col_vnp->next;
24121       col_pos++;
24122     }
24123     *added_columns = TRUE;
24124   }
24125   return pos_list;
24126 }
24127 
24128 
ApplyRowValues(ValNodePtr values,ValNodePtr col_numbers,ValNodePtr data_row,IDAndTitleEditPtr iatep,Int4 row_num)24129 static void ApplyRowValues (ValNodePtr values, ValNodePtr col_numbers, ValNodePtr data_row, IDAndTitleEditPtr iatep, Int4 row_num)
24130 {
24131   ValNodePtr val_col, data_col, num_col;
24132   Int4 pos;
24133 
24134   /* skip first values and data columns, they are for sequence IDs */
24135   for (val_col = values->next, num_col = col_numbers; val_col != NULL && num_col != NULL; val_col = val_col->next, num_col = num_col->next)
24136   {
24137     pos = 1;
24138     data_col = data_row->next;
24139     if (num_col->choice == 1) {
24140       iatep->title_list[row_num] = ReplaceValueInOneDefLine (iatep->title_list[row_num], num_col->data.ptrvalue, val_col->data.ptrvalue);
24141     } else {
24142       while (pos < num_col->data.intvalue && data_col != NULL) {
24143         pos++;
24144         data_col = data_col->next;
24145       }
24146       if (data_col != NULL) {
24147         data_col->data.ptrvalue = MemFree (data_col->data.ptrvalue);
24148         data_col->data.ptrvalue = StringSave (val_col->data.ptrvalue);
24149       }
24150     }
24151   }
24152 }
24153 
24154 
ListInvisibleRows(ValNodePtr col_list)24155 static Boolean ListInvisibleRows (ValNodePtr col_list)
24156 {
24157   CharPtr msg;
24158   CharPtr msg_start = "Also applied values for ";
24159   CharPtr msg_end = " (not displayed in table)";
24160   Int4    len = 0, num_extra = 0, pos = 0;
24161   ValNodePtr vnp;
24162   Boolean    any_invisible = FALSE;
24163 
24164   for (vnp = col_list; vnp != NULL; vnp = vnp->next) {
24165     if (vnp->choice == 1) {
24166       len += StringLen (vnp->data.ptrvalue) + 2;
24167       num_extra++;
24168     }
24169   }
24170   if (num_extra > 0) {
24171     any_invisible = TRUE;
24172     len += StringLen (msg_start) + StringLen (msg_end) + 6;
24173     msg = (CharPtr) MemNew (sizeof (Char) * len);
24174     StringCpy (msg, msg_start);
24175     for (vnp = col_list; vnp != NULL; vnp = vnp->next) {
24176       if (vnp->choice == 1) {
24177         StringCat (msg, vnp->data.ptrvalue);
24178         pos++;
24179         if (num_extra > 1) {
24180           if (pos < num_extra) {
24181             if (num_extra > 2) {
24182               StringCat (msg, ", ");
24183             }
24184             if (pos == num_extra - 1) {
24185               if (num_extra == 2) {
24186                 StringCat (msg, " and ");
24187               } else {
24188                 StringCat (msg, "and ");
24189               }
24190             }
24191           }
24192         }
24193       }
24194     }
24195     StringCat (msg, msg_end);
24196     Message (MSG_OK, msg);
24197     msg = MemFree (msg);
24198   }
24199   return any_invisible;
24200 }
24201 
24202 
ImportFeatSrcTable(ButtoN b)24203 static void ImportFeatSrcTable (ButtoN b)
24204 {
24205   WizardFeatureQualsFormPtr frm;
24206   ValNodePtr        table, header, vnp_row, data_row;
24207   Int4              num_rows, seq_num, row_num;
24208   Int4Ptr           sequence_numbers;
24209   ValNodePtr        col_numbers;
24210   Boolean           added_columns = FALSE;
24211   WizardTrackerPtr  wiz;
24212 
24213   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (b);
24214   if (frm == NULL) {
24215     return;
24216   }
24217 
24218   MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table, frm->rows_displayed, frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals);
24219   TabTableToSeqAnnotList (&(frm->wiz->annot_list), frm->wiz->feat_qual_table, frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals,
24220                             frm->iatep, frm->wiz->sequences);
24221 
24222   table = ReadRowListFromFile ();
24223   if (table == NULL) {
24224     return;
24225   }
24226 
24227   num_rows = ValNodeLen (table->next);
24228   sequence_numbers = (Int4Ptr) MemNew (num_rows * sizeof (Int4));
24229 
24230   if (!ValidateModifierTableSequenceIDs (table, frm->iatep, sequence_numbers, &num_rows))
24231   {
24232     table = FreeTableDisplayRowList (table);
24233     sequence_numbers = MemFree (sequence_numbers);
24234     return;
24235   }
24236   header = table->data.ptrvalue;
24237   col_numbers = ValidateWizardColumnNames (header, frm->wiz, &added_columns);
24238   if (col_numbers == NULL) {
24239     table = FreeTableDisplayRowList (table);
24240     sequence_numbers = MemFree (sequence_numbers);
24241     return;
24242   }
24243 
24244 
24245   for (vnp_row = table->next, row_num = 0; vnp_row != NULL; vnp_row = vnp_row->next, row_num++) {
24246     seq_num = 0;
24247     data_row = frm->wiz->feat_qual_table;
24248     while (seq_num < sequence_numbers[row_num] && data_row != NULL) {
24249       seq_num++;
24250       data_row = data_row->next;
24251     }
24252     if (data_row != NULL) {
24253       ApplyRowValues (vnp_row->data.ptrvalue, col_numbers, data_row->data.ptrvalue, frm->iatep, seq_num);
24254     }
24255   }
24256   if (ListInvisibleRows (col_numbers)) {
24257     ApplyIDAndTitleEditToSeqEntryList (frm->wiz->sequences, frm->iatep);
24258   }
24259   col_numbers = ValNodeFree (col_numbers);
24260   table = FreeTableDisplayRowList (table);
24261   sequence_numbers = MemFree (sequence_numbers);
24262 
24263   frm->rows_displayed = ValNodeFree (frm->rows_displayed);
24264   frm->rows_displayed = TabTableToMultiModTabTable (frm->wiz->feat_qual_table, frm->qual_table,
24265                               frm->wiz, frm->wiz->uniqueness_list,
24266                               ShouldShowAll((WizardQualsFormPtr)frm));
24267 
24268   if (added_columns) {
24269     wiz = frm->wiz;
24270     frm->wiz = NULL;
24271     Hide (frm->form);
24272     if (CreateFeatureQualsForm (wiz)) {
24273       Remove (frm->form);
24274     } else {
24275       frm->wiz = wiz;
24276     }
24277   }
24278 }
24279 
24280 
ExportFeatSrcTable(ButtoN b)24281 static void ExportFeatSrcTable (ButtoN b)
24282 {
24283   WizardFeatureQualsFormPtr frm;
24284   ValNodePtr                table = NULL, header = NULL, vnp;
24285   Char                      path [PATH_MAX];
24286   WizardQualPtr             q;
24287   Boolean                   first_range = TRUE;
24288   FILE *fp;
24289 
24290   frm = (WizardFeatureQualsFormPtr) GetObjectExtra (b);
24291   if (frm == NULL) {
24292     return;
24293   }
24294 
24295   if (!GetOutputFileName (path, sizeof (path), NULL)) {
24296     return;
24297   }
24298   fp = FileOpen (path, "w");
24299   if (fp == NULL) {
24300     Message (MSG_ERROR, "Unable to open %s", path);
24301     return;
24302   }
24303 
24304   MultiModTableToTabTable (frm->wiz->feat_qual_table, frm->qual_table, frm->rows_displayed, frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals);
24305   TabTableToSeqAnnotList (&(frm->wiz->annot_list), frm->wiz->feat_qual_table, frm->wiz->base_src_quals, frm->wiz->extra_src_quals, frm->wiz->feature_quals,
24306                             frm->iatep, frm->wiz->sequences);
24307 
24308   ValNodeAddPointer (&header, 0, StringSave ("SeqId"));
24309   for (vnp = frm->wiz->base_src_quals; vnp != NULL; vnp = vnp->next) {
24310     q = (WizardQualPtr) vnp->data.ptrvalue;
24311     if (q->edit_type == eWizardEditQual_Range) {
24312       if (first_range) {
24313         ValNodeAddPointer (&header, 0, StringSave ("begin"));
24314         first_range = FALSE;
24315       } else {
24316         ValNodeAddPointer (&header, 0, StringSave ("end"));
24317         first_range = TRUE;
24318       }
24319     } else {
24320       ValNodeAddPointer (&header, 0, StringSave (q->name));
24321     }
24322   }
24323   for (vnp = frm->wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
24324     q = (WizardQualPtr) vnp->data.ptrvalue;
24325     if (q->show) {
24326       if (q->edit_type == eWizardEditQual_Range) {
24327         if (first_range) {
24328           ValNodeAddPointer (&header, 0, StringSave ("begin"));
24329           first_range = FALSE;
24330         } else {
24331           ValNodeAddPointer (&header, 0, StringSave ("end"));
24332           first_range = TRUE;
24333         }
24334       } else {
24335         ValNodeAddPointer (&header, 0, StringSave (q->name));
24336       }
24337     }
24338   }
24339   for (vnp = frm->wiz->feature_quals; vnp != NULL; vnp = vnp->next) {
24340     q = (WizardQualPtr) vnp->data.ptrvalue;
24341     if (q->edit_type == eWizardEditQual_Range) {
24342       if (first_range) {
24343         ValNodeAddPointer (&header, 0, StringSave ("begin"));
24344         first_range = FALSE;
24345       } else {
24346         ValNodeAddPointer (&header, 0, StringSave ("end"));
24347         first_range = TRUE;
24348       }
24349     } else {
24350       ValNodeAddPointer (&header, 0, StringSave (q->name));
24351     }
24352   }
24353   ValNodeAddPointer (&table, 0, header);
24354   WriteTabTableToFile (table, fp);
24355   WriteTabTableToFile (frm->wiz->feat_qual_table, fp);
24356   FileClose (fp);
24357 
24358 }
24359 
24360 
24361 static CharPtr s_MicrosatelliteSourceAndFeatureHelpMsgs[] = { "\
24362 ------------------\n\
24363 Importing a Table:\n\
24364 ------------------\n\
24365 -Use the \"Import Table\" button to import a tab-delimited table\n\
24366  of the organism names, microsatellite names, and any relevant \n\
24367  source information (such as primers, Country, etc.).\n\
24368 \n\
24369 -The table in this form can be exported by pressing the \n\
24370  \"Export this table\" button. If you edit the table in a text \n\
24371 ",
24372 "\
24373  editor, you must maintain the tab structure of the table. \n\
24374  Alternately, you may copy the exported table into a spreadsheet \n\
24375  program to add your information, however you must import the \n\
24376  table back into this form as tab-delimited text (.txt). \n\
24377  Saving as tab-delimited text is found in some spreadsheet \n\
24378  programs by selecting \"other format types\" and selecting \n\
24379  the a tab-delimited file type when saving your file.\n\
24380 \n\
24381 -The table can be prepared in a spreadsheet program and saved as\n\
24382  tab-delimited text.  Saving as tab-delimited text is found \n\
24383 ",
24384 "\
24385  in some programs by selecting \"other format types\" and selecting \n\
24386  the a tab-delimited file type when saving your file.\n\
24387  \n\
24388 -Preparing the Table:\n\
24389  The first column in the table must contain the SeqIDs. \n\
24390  There must be a header row with the column labels.\n\
24391  The information for each record follows on the rows \n\
24392  below the header line, like the following example.\n\
24393 \n\
24394 -------------------------------------------------------\n\
24395 ",
24396 "\
24397 Example Table:\n\
24398 Use the horizontal scroll bar to see more of the table.\n\
24399 -------------------------------------------------------\n\
24400 SeqID\tOrganism\tmicrosatellite name\trpt_unit_seq\tbegin\tend\tcountry\tlat-lon\tFwd-PCR-primer-name\tFwd-PCR-primer-seq\tRev-PCR-primer-name\tRev-PCR-primer-seq\n\
24401 ABC1\tCoffea arabica\tCa-123\tag\t24\t25\tGreenland\t70.00\tN 54.01 W\tExamplePrimer1-F\tTTTTTAAAATTGGGGGC\tExamplePrimer1-R\tAAAATTTTAAGGGGAC\n\
24402 ABC2\tCoffea arabica\tCa-234\taaatt\t33\t37\tGreenland\t70.00\tN 54.01 W\t1Primer1-F, 2Primer-F\tTTTTTAAA, GGAATTTA\t1Primer-R, 2Primer-R\tAAAATTTT, GGAATT\n\
24403 \n\
24404 --------------------\n\
24405 Formatting examples:\n\
24406 --------------------\n\
24407 -Host: Use the binomial name of the host, if known, followed by other \n\
24408  information relating to the host, such as age, sex, breed, cultivar, etc. \n\
24409  For example-\n\
24410  Homo sapiens\n\
24411 ",
24412 "\
24413  Homo sapiens; female; 56 years\n\
24414  Solanum lycopersicum cv. Micro-Tom\n\
24415  Canis sp.\n\
24416 \n\
24417 -Country: use the following format-\n\
24418  Country: free text with more specific geographic information, if known.\n\
24419  For example-\n\
24420  Australia: 5 km south of Sydney\n\
24421  Madagascar\n\
24422  Brazil: Rio de Janeiro\n\
24423 ",
24424 "\
24425 \n\
24426 -Collection-date: use one of the following formats-\n\
24427  DD-MMM-YYYY\n\
24428  MMM-YYYY\n\
24429  YYYY\n\
24430  For example-\n\
24431  09-Aug-1985\n\
24432  Dec-2008\n\
24433  2008\n\
24434 \n\
24435 ",
24436 "\
24437 -Latitude-Longitude (lat_lon): use decimal degree format.\n\
24438  If you are providing Country information, the country should agree with the lat_lon value.\n\
24439  The first number should refer to the latitude (north/south) and the second to the longitude (east/west).\n\
24440  For example-\n\
24441  70.01 N 54.01 W\n\
24442 \n\
24443 -Primers: Please only provide the primers that were used to PCR amplify your sample. \n\
24444 ",
24445 "\
24446  Do not provide sequencing primers.\n\
24447  If you are providing multiple primers, separate the primer seqs and/or names with a comma.\n\
24448  See the example source table for a formatting example.\n\
24449 \n\
24450 ",
24451 NULL};
24452 
24453 
ShowSourceAndFeatTableHelp(ButtoN b)24454 static void ShowSourceAndFeatTableHelp (ButtoN b)
24455 {
24456   WizardTrackerPtr wiz;
24457 
24458   wiz = (WizardTrackerPtr) GetObjectExtra (b);
24459   if (wiz == NULL) {
24460     return;
24461   }
24462   if (wiz->wizard_type == eWizardType_Microsatellite) {
24463     ShowWizardHelpText ("Source Table Help", s_MicrosatelliteSourceAndFeatureHelpMsgs);
24464   } else {
24465     ShowSourceTableHelp (b);
24466   }
24467 }
24468 
24469 
IsColumnAnyPresent(ValNodePtr table,Int4 column)24470 static Boolean IsColumnAnyPresent (ValNodePtr table, Int4 column)
24471 {
24472   ValNodePtr row_vnp;
24473   CharPtr    val;
24474   Boolean    rval = FALSE;
24475 
24476   for (row_vnp = table; row_vnp != NULL && !rval; row_vnp = row_vnp->next) {
24477     val = GetNthField(row_vnp->data.ptrvalue, column);
24478     if (!StringHasNoText (val)) {
24479       rval = TRUE;
24480     }
24481   }
24482   return rval;
24483 }
24484 
24485 
WarnAboutDataLoss(WizardTrackerPtr wiz)24486 static Boolean WarnAboutDataLoss (WizardTrackerPtr wiz)
24487 {
24488   IDAndTitleEditPtr iatep;
24489   Int4              start, j;
24490   ValNodePtr        vnp;
24491   Boolean           data_present = FALSE;
24492 
24493   if (wiz == NULL) {
24494     return FALSE;
24495   }
24496   start = CountSrcQualsToShow (wiz->base_src_quals, wiz->extra_src_quals);
24497   for (j = start + 1, vnp = wiz->feature_quals; vnp != NULL && !data_present; vnp = vnp->next, j++) {
24498     data_present = IsColumnAnyPresent(wiz->feat_qual_table, j);
24499   }
24500 
24501   if (data_present && ANS_CANCEL == Message (MSG_OKC, "You will lose information about individual microsatellites.  Are you sure you want to continue?")) {
24502     return FALSE;
24503   } else {
24504     iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
24505     TabTableToSeqAnnotList (&(wiz->annot_list), wiz->feat_qual_table, wiz->base_src_quals, wiz->extra_src_quals, wiz->feature_quals,
24506                               iatep, wiz->sequences);
24507     ApplyIDAndTitleEditToSeqEntryList (wiz->sequences, iatep);
24508     return TRUE;
24509   }
24510 }
24511 
24512 
CreateFeatureQualsForm(WizardTrackerPtr wiz)24513 static Boolean CreateFeatureQualsForm (WizardTrackerPtr wiz)
24514 {
24515   WizardFeatureQualsFormPtr frm;
24516   WindoW w;
24517   GrouP  h;
24518   GrouP  top_btns, table_btns, c;
24519   GrouP  qualtable_grp, g;
24520   ButtoN b;
24521   Int4   num_seq, i, unseen_extras = 0;
24522   TagListPtr tlp;
24523   PrompT     ppt;
24524   ValNodePtr vnp;
24525   WizardSrcQualPtr sq;
24526   WizardFeatQualPtr fq, fq_prev = NULL;
24527   CharPtr PNTR example_text;
24528   CharPtr      dlg_title;
24529   GrouP PNTR   grp_list;
24530   Char       buf[255];
24531 
24532   frm = (WizardFeatureQualsFormPtr) MemNew (sizeof (WizardFeatureQualsFormData));
24533   frm->wiz = wiz;
24534   frm->collect_func = SaveWizardFeatureQuals;
24535   frm->fwd_ok_func = WizardFeatureQualsOkAndOkToContinueToSequin;
24536   frm->back_ok_func = WarnAboutDataLoss;
24537   frm->next_form = FinishWizardAndLaunchSequin;
24538 
24539   frm->iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
24540   num_seq = frm->iatep->num_sequences;
24541 
24542   frm->num_src_quals = CountSrcQualsToShow (wiz->base_src_quals, wiz->extra_src_quals);
24543   unseen_extras = CountUnseenSrcQuals(wiz->extra_src_quals);
24544   frm->num_mods = ValNodeLen (wiz->feature_quals) + frm->num_src_quals;
24545 
24546   frm->mod_names = (CharPtr PNTR) MemNew (sizeof (CharPtr) * frm->num_mods);
24547   frm->edit_types = (EWizardEditQual PNTR) MemNew (sizeof (EWizardEditQual) * frm->num_mods);
24548 
24549   for (vnp = frm->wiz->base_src_quals, i = 0; vnp != NULL; vnp = vnp->next) {
24550     if ((sq = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL) {
24551       frm->mod_names[i] = sq->name;
24552       frm->edit_types[i] = sq->edit_type;
24553       i++;
24554     }
24555   }
24556 
24557   for (vnp = frm->wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
24558     if ((sq = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && sq->show) {
24559       frm->mod_names[i] = sq->name;
24560       frm->edit_types[i] = sq->edit_type;
24561       i++;
24562     }
24563   }
24564 
24565   for (vnp = frm->wiz->feature_quals; vnp != NULL; vnp = vnp->next) {
24566     if ((fq = (WizardFeatQualPtr) vnp->data.ptrvalue) != NULL) {
24567       if (fq->edit_type == eWizardEditQual_Range) {
24568         if (fq_prev != NULL && StringCmp (fq_prev->name, fq->name) == 0) {
24569           frm->mod_names[i] = "end";
24570         } else {
24571           frm->mod_names[i] = "begin";
24572         }
24573       } else {
24574         frm->mod_names[i] = fq->name;
24575       }
24576       frm->edit_types[i] = fq->edit_type;
24577       i++;
24578       fq_prev = fq;
24579     }
24580   }
24581 
24582   dlg_title = "Microsatellite Wizard Information";
24583 
24584   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
24585   SetObjectExtra (w, frm, CleanupWizardFeatureQualsForm);
24586   frm->form = (ForM) w;
24587 
24588   h = HiddenGroup (w, -1, -1, NULL);
24589   SetGroupSpacing (h, 10, 10);
24590 
24591   ppt = StaticPrompt (h, "Please provide the required information:", 0, 0, programFont, 'c');
24592   qualtable_grp = HiddenGroup (h, -1, 0, NULL);
24593 
24594   top_btns = HiddenGroup (qualtable_grp, frm->num_mods, 0, NULL);
24595   SetGroupSpacing (top_btns, 10, 10);
24596 
24597   MakeFeatureQualHeaders (top_btns,frm);
24598 
24599   grp_list = (GrouP PNTR) MemNew (sizeof (GrouP) * (frm->num_mods + 2));
24600   example_text = GetFeatureQualExampleText(frm->wiz, frm->num_mods);
24601   frm->qual_table = AddMultiModifierTableEditor (qualtable_grp, frm->mod_names, example_text, frm->num_mods, num_seq, grp_list);
24602   example_text = MemFree (example_text);
24603 
24604   tlp = GetObjectExtra (frm->qual_table);
24605   AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[0], (HANDLE) tlp->control[0], NULL);
24606   for (i = 0; i < frm->num_mods; i++) {
24607     AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[i + 1], (HANDLE) tlp->control[i + 1], (HANDLE) frm->ed_grps[i], NULL);
24608   }
24609   /* align problems */
24610   AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[i + 1], (HANDLE) tlp->control[i + 1], NULL);
24611   grp_list = MemFree (grp_list);
24612 
24613   frm->show_all_grp = HiddenGroup (h, 2, 0, ShowAllFeatureQualSequences);
24614   SetObjectExtra (frm->show_all_grp, frm, NULL);
24615   RadioButton (frm->show_all_grp, "Show only sequences with errors");
24616   RadioButton (frm->show_all_grp, "Show all sequences in set");
24617   SetValue (frm->show_all_grp, 2);
24618 
24619   g = HiddenGroup (h, 6, 0, NULL);
24620   SetGroupSpacing (g, 10, 10);
24621 
24622   b = PushButton (g, "Apply/See More Source Information", ApplyMoreFeatureInfo);
24623   SetObjectExtra (b, frm, NULL);
24624 
24625   frm->extra_btns = (ButtoN PNTR) MemNew (sizeof (ButtoN) * unseen_extras);
24626   i = 0;
24627   for (vnp = frm->wiz->extra_src_quals; vnp != NULL; vnp = vnp->next) {
24628     if ((sq = (WizardSrcQualPtr) vnp->data.ptrvalue) != NULL && !sq->show && sq->linked == NULL) {
24629       sprintf (buf, "Add %s", sq->add_name);
24630       frm->extra_btns[i] = PushButton (g, buf, AddExtraTabEditorColumn);
24631       SetObjectExtra (frm->extra_btns[i], frm, NULL);
24632       i++;
24633     }
24634   }
24635 
24636 
24637   table_btns = HiddenGroup (h, 5, 0, NULL);
24638   SetGroupSpacing (table_btns, 10, 10);
24639   b = PushButton (table_btns, "Import Table", ImportFeatSrcTable);
24640   SetObjectExtra (b, frm, NULL);
24641   b = PushButton (table_btns, "Export This Table", ExportFeatSrcTable);
24642   SetObjectExtra (b, frm, NULL);
24643   b = PushButton (table_btns, "Source Table Help", ShowSourceAndFeatTableHelp);
24644   SetObjectExtra (b, frm->wiz, NULL);
24645   b = PushButton (table_btns, "Recheck Errors", RecheckFeatureQualErrors);
24646   SetObjectExtra (b, frm, NULL);
24647   b = PushButton (table_btns, "Clear Qualifiers", ClearFeatureQuals);
24648   SetObjectExtra (b, frm, NULL);
24649 
24650   c = MakeWizardNav (h, frm);
24651 
24652   AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
24653                               (HANDLE) qualtable_grp,
24654                               (HANDLE) frm->show_all_grp,
24655                               (HANDLE) g,
24656                               (HANDLE) table_btns,
24657                               (HANDLE) c,
24658                               NULL);
24659 
24660   Update();
24661   frm->rows_displayed = ValNodeFree (frm->rows_displayed);
24662   frm->rows_displayed = TabTableToMultiModTabTable (wiz->feat_qual_table, frm->qual_table,
24663                               frm->wiz,
24664                               frm->wiz->uniqueness_list,
24665                               ShouldShowAll((WizardQualsFormPtr)frm));
24666   Show (w);
24667   SendHelpScrollMessage (helpForm, "Wizard Feature Information", dlg_title);
24668 
24669   return TRUE;
24670 }
24671 
24672 
ApplyMicrosatelliteName(SeqFeatPtr sfp,CharPtr val)24673 static void ApplyMicrosatelliteName (SeqFeatPtr sfp, CharPtr val)
24674 {
24675   ValNode vn;
24676   CharPtr new_val;
24677   CharPtr name_fmt = "microsatellite: %s";
24678 
24679   if (sfp == NULL) {
24680     return;
24681   }
24682 
24683   MemSet (&vn, 0, sizeof (ValNode));
24684   vn.choice = FeatQualChoice_legal_qual;
24685   vn.data.intvalue = Feat_qual_legal_satellite;
24686   if (!StringHasNoText (val)) {
24687     new_val = (CharPtr) MemNew (sizeof (Char) * (StringLen (name_fmt) + StringLen (val)));
24688     sprintf (new_val, name_fmt, val);
24689   } else {
24690     new_val = StringSave ("microsatellite");
24691   }
24692   SetStringInGBQualList (&(sfp->qual), &vn, NULL, new_val, ExistingTextOption_replace_old);
24693   new_val = MemFree (new_val);
24694 }
24695 
24696 
GetMicrosatelliteName(SeqFeatPtr sfp)24697 static CharPtr GetMicrosatelliteName (SeqFeatPtr sfp)
24698 {
24699   CharPtr rval = NULL;
24700 
24701   if (sfp == NULL) {
24702     return NULL;
24703   }
24704 
24705   rval = GetFirstGBQualMatch (sfp->qual, "satellite", 2, NULL);
24706   return rval;
24707 }
24708 
24709 
CheckMicrosatelliteName(CharPtr val,BioseqPtr bsp)24710 static CharPtr CheckMicrosatelliteName (CharPtr val, BioseqPtr bsp)
24711 {
24712   CharPtr rval = NULL;
24713 
24714   if (StringHasNoText (val)) {
24715     rval = StringSave ("Missing microsatellite name");
24716   }
24717   return rval;
24718 }
24719 
24720 
TabTableLineFromFeature(SeqFeatPtr sfp,ValNodePtr fquals)24721 static ValNodePtr TabTableLineFromFeature (SeqFeatPtr sfp, ValNodePtr fquals)
24722 {
24723   ValNodePtr line = NULL;
24724   CharPtr val;
24725   ValNodePtr vals = NULL, q_vnp;
24726   WizardFeatQualPtr q;
24727 
24728   for (q_vnp = fquals; q_vnp != NULL; q_vnp = q_vnp->next) {
24729     q = (WizardFeatQualPtr) q_vnp->data.ptrvalue;
24730     val = q->get_func(sfp);
24731     ValNodeAddPointer (&line, 0, val);
24732   }
24733 
24734   return line;
24735 }
24736 
24737 
SrcQualsAndSeqAnnotListToTabTable(IDAndTitleEditPtr iatep,ValNodePtr base_src_quals,ValNodePtr extra_src_quals,ValNodePtr annot_list,ValNodePtr fquals)24738 static ValNodePtr SrcQualsAndSeqAnnotListToTabTable
24739 (IDAndTitleEditPtr iatep,
24740  ValNodePtr base_src_quals,
24741  ValNodePtr extra_src_quals,
24742  ValNodePtr annot_list,
24743  ValNodePtr fquals)
24744 {
24745   ValNodePtr  table = NULL, line;
24746   CharPtr     id;
24747   SeqAnnotPtr sap;
24748   SeqFeatPtr  sfp;
24749   ValNodePtr  sap_vnp;
24750   Int4        i;
24751 
24752   for (sap_vnp = annot_list, i = 0; sap_vnp != NULL; sap_vnp = sap_vnp->next, i++) {
24753     sap = (SeqAnnotPtr) sap_vnp->data.ptrvalue;
24754     if (sap != NULL && sap->type == 1) {
24755       for (sfp = (SeqFeatPtr) sap->data; sfp != NULL; sfp = sfp->next) {
24756         id = SeqIdWholeLabel (SeqLocId (sfp->location), PRINTID_REPORT);
24757         line = ValNodeNew (NULL);
24758         line->data.ptrvalue = id;
24759         ValNodeLink (&line, TabTableLineFromSrcQuals (iatep->title_list[i], base_src_quals, extra_src_quals));
24760         ValNodeLink (&line, TabTableLineFromFeature (sfp, fquals));
24761         ValNodeAddPointer (&table, 0, line);
24762       }
24763     }
24764   }
24765   return table;
24766 }
24767 
24768 
PregenerateFeatures(WizardTrackerPtr wiz)24769 static void PregenerateFeatures (WizardTrackerPtr wiz)
24770 {
24771   IDAndTitleEditPtr iatep;
24772   Int4          i;
24773   SeqFeatPtr    sfp;
24774   SeqAnnotPtr   sap;
24775   CharPtr       PNTR problems = NULL;
24776   ValNodePtr    un1;
24777 
24778   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
24779   SetWizardTrackerBaseSrcQuals (wiz, iatep);
24780   SetWizardTrackerExtraSrcQuals (wiz, iatep);
24781   for (i = 0; i < iatep->num_sequences; i++) {
24782     sfp = NewFeatForAnnotList (iatep->id_list[i], iatep, wiz->sequences);
24783     MakeSeqFeatMicrosatellite (sfp);
24784     sap = SeqAnnotNew ();
24785     sap->type = 1;
24786     sap->data = sfp;
24787     ValNodeAddPointer (&(wiz->annot_list), OBJ_SEQANNOT, sap);
24788   }
24789 
24790   wiz->feat_qual_table = FreeTabTable (wiz->feat_qual_table);
24791   wiz->feat_qual_table = SrcQualsAndSeqAnnotListToTabTable (iatep, wiz->base_src_quals, wiz->extra_src_quals, wiz->annot_list, wiz->feature_quals);
24792 
24793   wiz->uniqueness_list = UniquenessListFree (wiz->uniqueness_list);
24794   un1 = ValNodeNew (NULL);
24795   if (DoAnySequencesHaveModifier(iatep, "clone")) {
24796     un1->data.ptrvalue = WizardSrcQualNew ("clone", eWizardEditQual_CopyFromId, TRUE, TRUE);
24797   } else {
24798     un1->data.ptrvalue = WizardFeatQualNew ("Microsatellite Name", eWizardEditQual_CopyFromId, TRUE, TRUE,
24799                        ApplyMicrosatelliteName, GetMicrosatelliteName, CheckMicrosatelliteName, NULL, FALSE, "Ca-123");
24800   }
24801   ValNodeAddPointer (&wiz->uniqueness_list, 0, un1);
24802 
24803   iatep = IDAndTitleEditFree (iatep);
24804 }
24805 
24806 
CheckRangeStart(CharPtr val,BioseqPtr bsp)24807 static CharPtr CheckRangeStart (CharPtr val, BioseqPtr bsp)
24808 {
24809   CharPtr rval = NULL;
24810   Int4    pos;
24811 
24812   if (StringHasNoText (val)) {
24813     rval = NULL;
24814   } else if (StringIsAllDigits (val)) {
24815     pos = atoi (val);
24816     if (pos < 1) {
24817       rval = StringSave ("rpt_unit_range values should be inside the sequence (must be 1 or greater).");
24818     } else if (bsp != NULL && pos > bsp->length) {
24819       rval = StringSave ("rpt_unit_range begin is larger than the length of the sequence");
24820     }
24821   } else {
24822     rval = StringSave ("The rpt_unit_range begin and end should have number values only. Please go back and edit this information or else it will be discarded. Do not use symbols or letters in these fields.");
24823   }
24824   return rval;
24825 }
24826 
24827 
CheckRangeStop(CharPtr val,BioseqPtr bsp)24828 static CharPtr CheckRangeStop (CharPtr val, BioseqPtr bsp)
24829 {
24830   CharPtr rval = NULL;
24831   Int4    pos;
24832 
24833   if (StringHasNoText (val)) {
24834     rval = NULL;
24835   } else if (StringIsAllDigits (val)) {
24836     pos = atoi (val);
24837     if (pos < 1) {
24838       rval = StringSave ("rpt_unit_range values should be inside the sequence (must be 1 or greater)");
24839     } else if (bsp != NULL && pos > bsp->length) {
24840       rval = StringSave ("rpt_unit_range end is larger than the length of the sequence");
24841     }
24842   } else {
24843     rval = StringSave ("The rpt_unit_range begin and end should have number values only. Please go back and edit this information or else it will be discarded. Do not use symbols or letters in these fields.");
24844   }
24845   return rval;
24846 }
24847 
24848 
IsLocStartFormatValid(CharPtr val,CharPtr qual_name,BioseqPtr bsp)24849 static CharPtr IsLocStartFormatValid (CharPtr val, CharPtr qual_name, BioseqPtr bsp)
24850 {
24851   CharPtr num_fmt = "The %s begin should have number values only. Please go back and edit this information or else it will be discarded. Do not use symbols or letters in these fields.";
24852   CharPtr under_range_fmt = "%s values should be inside the sequence (must be 1 or greater). Please go back and edit this information or else it will be discarded.";
24853   CharPtr over_range_fmt = "%s is larger than the length of the sequence. Please go back and edit this information or else it will be discarded.";
24854   CharPtr fmt = NULL;
24855   CharPtr err = NULL;
24856   Int4 pos;
24857 
24858   if (StringHasNoText (val)) {
24859     /* empty value, ok */
24860   } else if (!StringIsAllDigits (val)) {
24861     fmt = num_fmt;
24862   } else {
24863     pos = atoi (val);
24864     if (pos < 1) {
24865       fmt = under_range_fmt;
24866     } else if (bsp != NULL && pos > bsp->length) {
24867       fmt = over_range_fmt;
24868     }
24869   }
24870   if (fmt != NULL) {
24871     err = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (qual_name)));
24872     sprintf (err, fmt, qual_name);
24873   }
24874   return err;
24875 }
24876 
24877 
IsLocStopFormatValid(CharPtr val,CharPtr qual_name,BioseqPtr bsp)24878 static CharPtr IsLocStopFormatValid (CharPtr val, CharPtr qual_name, BioseqPtr bsp)
24879 {
24880   CharPtr num_fmt = "The %s end should have number values only. Please go back and edit this information or else it will be discarded. Do not use symbols or letters in these fields.";
24881   CharPtr under_range_fmt = "%s values should be inside the sequence (must be 1 or greater) at 1. Please go back and edit this information or else it will be discarded.";
24882   CharPtr over_range_fmt = "%s is larger than the length of the sequence. Please go back and edit this information or else it will be discarded.";
24883   CharPtr fmt = NULL;
24884   CharPtr err = NULL;
24885   Int4 pos;
24886 
24887   if (StringHasNoText (val)) {
24888     /* ok if empty */
24889   } else if (!StringIsAllDigits (val)) {
24890     fmt = num_fmt;
24891   } else {
24892     pos = atoi (val);
24893     if (pos < 1) {
24894       fmt = under_range_fmt;
24895     } else if (bsp != NULL && pos > bsp->length) {
24896       fmt = over_range_fmt;
24897     }
24898   }
24899   if (fmt != NULL) {
24900     err = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (qual_name)));
24901     sprintf (err, fmt, qual_name);
24902   }
24903 
24904   return err;
24905 }
24906 
24907 
ApplyRptUnitSeq(SeqFeatPtr sfp,CharPtr val)24908 static void ApplyRptUnitSeq (SeqFeatPtr sfp, CharPtr val)
24909 {
24910   ValNode vn;
24911 
24912   if (sfp == NULL) {
24913     return;
24914   }
24915 
24916   MemSet (&vn, 0, sizeof (ValNode));
24917   vn.choice = FeatQualChoice_legal_qual;
24918   vn.data.intvalue = Feat_qual_legal_rpt_unit_seq;
24919   if (!StringHasNoText (val)) {
24920     SetStringInGBQualList (&(sfp->qual), &vn, NULL, val, ExistingTextOption_replace_old);
24921   } else {
24922     RemoveGBQualMatch (&(sfp->qual), "rpt_unit_seq", 0, NULL);
24923   }
24924 }
24925 
24926 
GetRptUnitSeq(SeqFeatPtr sfp)24927 static CharPtr GetRptUnitSeq (SeqFeatPtr sfp)
24928 {
24929   CharPtr rval = NULL;
24930 
24931   if (sfp == NULL) {
24932     return NULL;
24933   }
24934 
24935   rval = GetFirstGBQualMatch (sfp->qual, "rpt_unit_seq", 0, NULL);
24936   return rval;
24937 }
24938 
24939 
CheckRptUnitSeq(CharPtr val,BioseqPtr bsp)24940 static CharPtr CheckRptUnitSeq (CharPtr val, BioseqPtr bsp)
24941 {
24942   return NULL;
24943 }
24944 
24945 
IsRptUnitSeqFormatValid(CharPtr val,CharPtr qual_name,BioseqPtr bsp)24946 static CharPtr IsRptUnitSeqFormatValid (CharPtr val, CharPtr qual_name, BioseqPtr bsp)
24947 {
24948   return NULL;
24949 }
24950 
24951 
ApplyRangeStart(SeqFeatPtr sfp,CharPtr val)24952 static void ApplyRangeStart (SeqFeatPtr sfp, CharPtr val)
24953 {
24954   ValNode vn;
24955   CharPtr cp;
24956   CharPtr existing_val, new_val;
24957 
24958   if (sfp == NULL) {
24959     return;
24960   }
24961 
24962   MemSet (&vn, 0, sizeof (ValNode));
24963   vn.choice = FeatQualChoice_legal_qual;
24964   vn.data.intvalue = Feat_qual_legal_rpt_unit_range;
24965   existing_val = GetFirstGBQualMatch (sfp->qual, "rpt_unit_range", 0, NULL);
24966   cp = StringSearch (existing_val, "..");
24967 
24968   if (StringHasNoText (val)) {
24969     if (cp == NULL) {
24970       RemoveGBQualMatch (&(sfp->qual), "rpt_unit_range", 0, NULL);
24971     } else {
24972       SetStringInGBQualList (&(sfp->qual), &vn, NULL, cp, ExistingTextOption_replace_old);
24973     }
24974   } else {
24975     if (cp == NULL) {
24976       SetStringInGBQualList (&(sfp->qual), &vn, NULL, val, ExistingTextOption_replace_old);
24977     } else {
24978       new_val = (CharPtr) MemNew (sizeof (Char) * (StringLen (val) + StringLen (cp) + 1));
24979       StringCpy (new_val, val);
24980       StringCat (new_val, cp);
24981       SetStringInGBQualList (&(sfp->qual), &vn, NULL, new_val, ExistingTextOption_replace_old);
24982       new_val = MemFree (new_val);
24983     }
24984   }
24985   existing_val = MemFree (existing_val);
24986 }
24987 
24988 
GetRangeStart(SeqFeatPtr sfp)24989 static CharPtr GetRangeStart (SeqFeatPtr sfp)
24990 {
24991   CharPtr rval = NULL, tmp;
24992   CharPtr cp;
24993 
24994   if (sfp == NULL) {
24995     return NULL;
24996   }
24997 
24998   rval = GetFirstGBQualMatch (sfp->qual, "rpt_unit_range", 0, NULL);
24999   cp = StringSearch (rval, "..");
25000   if (cp != NULL) {
25001     tmp = (CharPtr) MemNew (sizeof (Char) * ((cp - rval) + 1));
25002     StringNCpy (tmp, rval, cp - rval);
25003     tmp[cp - rval] = 0;
25004     rval = MemFree (rval);
25005     rval = tmp;
25006   }
25007   return rval;
25008 }
25009 
25010 
ApplyRangeStop(SeqFeatPtr sfp,CharPtr val)25011 static void ApplyRangeStop (SeqFeatPtr sfp, CharPtr val)
25012 {
25013   ValNode vn;
25014   CharPtr cp;
25015   CharPtr existing_val, new_val;
25016 
25017   if (sfp == NULL) {
25018     return;
25019   }
25020 
25021   MemSet (&vn, 0, sizeof (ValNode));
25022   vn.choice = FeatQualChoice_legal_qual;
25023   vn.data.intvalue = Feat_qual_legal_rpt_unit_range;
25024   existing_val = GetFirstGBQualMatch (sfp->qual, "rpt_unit_range", 0, NULL);
25025   cp = StringSearch (existing_val, "..");
25026 
25027   if (StringHasNoText (val)) {
25028     if (cp == NULL) {
25029       /* do nothing */
25030     } else {
25031       *cp = 0;
25032       SetStringInGBQualList (&(sfp->qual), &vn, NULL, existing_val, ExistingTextOption_replace_old);
25033     }
25034   } else {
25035     if (cp == NULL) {
25036       new_val = (CharPtr) MemNew (sizeof (Char) * (StringLen (existing_val) + 3 + StringLen (val)));
25037       StringCpy (new_val, existing_val);
25038       StringCat (new_val, "..");
25039       StringCat (new_val, val);
25040       SetStringInGBQualList (&(sfp->qual), &vn, NULL, new_val, ExistingTextOption_replace_old);
25041       new_val = MemFree (new_val);
25042     } else {
25043       new_val = (CharPtr) MemNew (sizeof (Char) * ((cp - val) + 3 + StringLen (val)));
25044       StringNCpy (new_val, val, 2 + cp - val);
25045       new_val[2 + cp - val] = 0;
25046       StringCat (new_val, val);
25047       SetStringInGBQualList (&(sfp->qual), &vn, NULL, new_val, ExistingTextOption_replace_old);
25048       new_val = MemFree (new_val);
25049     }
25050   }
25051   existing_val = MemFree (existing_val);
25052 }
25053 
25054 
GetRangeStop(SeqFeatPtr sfp)25055 static CharPtr GetRangeStop (SeqFeatPtr sfp)
25056 {
25057   CharPtr rval = NULL, tmp;
25058   CharPtr cp;
25059 
25060   if (sfp == NULL) {
25061     return NULL;
25062   }
25063 
25064   rval = GetFirstGBQualMatch (sfp->qual, "rpt_unit_range", 0, NULL);
25065   cp = StringSearch (rval, "..");
25066   if (cp == NULL) {
25067     rval = MemFree (rval);
25068   } else {
25069     tmp = StringSave (cp + 2);
25070     rval = MemFree (rval);
25071     rval = tmp;
25072   }
25073   return rval;
25074 }
25075 
25076 
25077 /* universal source information */
25078 
AddMissingQuals(CharPtr title,WizardTrackerPtr wiz)25079 static void AddMissingQuals (CharPtr title, WizardTrackerPtr wiz)
25080 {
25081   ValNodePtr    q_vnp;
25082   WizardSrcQualPtr q;
25083   Boolean       found;
25084   CharPtr       names, val, cp, qual_name;
25085   Uint1         subtype;
25086 
25087   names = GetPresentModifierNames (title);
25088   val = names;
25089   while (val != NULL) {
25090     cp = StringChr (val, ',');
25091     if (cp != NULL) {
25092       *cp = 0;
25093     }
25094     TrimSpacesAroundString (val);
25095     qual_name = NULL;
25096     if ((subtype = EquivalentOrgMod (val)) != 0) {
25097       qual_name = GetOrgModQualName (subtype);
25098     } else if ((subtype = EquivalentSubSource (val)) != 0) {
25099       qual_name = GetSubsourceQualName (subtype);
25100     }
25101 
25102     if (qual_name != NULL) {
25103       found = FALSE;
25104       for (q_vnp = wiz->base_src_quals; q_vnp != NULL && !found; q_vnp = q_vnp->next) {
25105         q = (WizardSrcQualPtr) q_vnp->data.ptrvalue;
25106         found = StringsAreEquivalent (q->name, qual_name);
25107       }
25108       for (q_vnp = wiz->extra_src_quals; q_vnp != NULL && !found; q_vnp = q_vnp->next) {
25109         q = (WizardSrcQualPtr) q_vnp->data.ptrvalue;
25110         found = StringsAreEquivalent (q->name, qual_name);
25111         if (found) {
25112           q->show = TRUE;
25113         }
25114       }
25115       if (!found) {
25116         q = WizardSrcQualNewEx (qual_name, eWizardEditQual_None, TRUE, TRUE, NULL, FALSE, NULL);
25117         ValNodeAddPointer (&(wiz->extra_src_quals), 0, q);
25118       }
25119     }
25120     if (cp == NULL) {
25121       val = cp;
25122     } else {
25123       val = cp + 1;
25124     }
25125   }
25126   names = MemFree (names);
25127 }
25128 
25129 typedef struct universalsrc {
25130   ValNodePtr id_list_list;
25131   ValNodePtr val_list;
25132 } UniversalSrcData, PNTR UniversalSrcPtr;
25133 
25134 
UniversalSrcNew(ValNodePtr id_list_list,ValNodePtr val_list)25135 static UniversalSrcPtr UniversalSrcNew (ValNodePtr id_list_list, ValNodePtr val_list)
25136 {
25137   UniversalSrcPtr u;
25138 
25139   u = (UniversalSrcPtr) MemNew (sizeof (UniversalSrcData));
25140   u->id_list_list = id_list_list;
25141   u->val_list = val_list;
25142   return u;
25143 }
25144 
UniversalSrcFree(UniversalSrcPtr u)25145 static UniversalSrcPtr UniversalSrcFree (UniversalSrcPtr u)
25146 {
25147   ValNodePtr vnp;
25148 
25149   if (u != NULL) {
25150     for (vnp = u->id_list_list; vnp != NULL; vnp = vnp->next) {
25151       vnp->data.ptrvalue = ValNodeFreeData (vnp->data.ptrvalue);
25152     }
25153     u->id_list_list = ValNodeFree (u->id_list_list);
25154     u->val_list = ValNodeFreeData (u->val_list);
25155     u = MemFree (u);
25156   }
25157   return u;
25158 }
25159 
25160 
UniversalSrcListFree(ValNodePtr list)25161 static ValNodePtr UniversalSrcListFree (ValNodePtr list)
25162 {
25163   ValNodePtr vnp_next;
25164 
25165   while (list != NULL) {
25166     vnp_next = list->next;
25167     list->next = NULL;
25168     list->data.ptrvalue= UniversalSrcFree (list->data.ptrvalue);
25169     list = ValNodeFree (list);
25170     list = vnp_next;
25171   }
25172   return list;
25173 }
25174 
25175 
RemoveNonUniversalQuals(ValNodePtr PNTR list)25176 static void RemoveNonUniversalQuals (ValNodePtr PNTR list)
25177 {
25178   ValNodePtr v_p = NULL, v_n, v;
25179   WizardQualPtr wq;
25180 
25181   if (list == NULL || *list == NULL) {
25182     return;
25183   }
25184   for (v = *list; v != NULL; v = v_n) {
25185     v_n = v->next;
25186     wq = (WizardQualPtr) v->data.ptrvalue;
25187     if (StringICmp (wq->name, "chromosome") == 0 || StringICmp (wq->name, "plasmid-name") == 0 || StringICmp (wq->name, "location") == 0) {
25188       if (v_p == NULL) {
25189         *list = v_n;
25190       } else {
25191         v_p->next = v_n;
25192       }
25193       v->next = NULL;
25194       v = ValNodeFreeData (v);
25195     } else {
25196       v_p = v;
25197     }
25198   }
25199 }
25200 
25201 
FindUniversalSourceInfo(IDAndTitleEditPtr iatep,WizardTrackerPtr wiz)25202 static ValNodePtr FindUniversalSourceInfo (IDAndTitleEditPtr iatep, WizardTrackerPtr wiz)
25203 {
25204   ValNodePtr table = NULL, line, row, row_cols;
25205   Int4       num_cols = 0, col, i;
25206   CharPtr    curr_val, this_val;
25207   ValNodePtr id_list = NULL;
25208   UniversalSrcPtr u;
25209   ValNodePtr summaries = NULL;
25210 
25211   for (i = 0; i < iatep->num_sequences; i++) {
25212     AddMissingQuals (iatep->title_list[i], wiz);
25213     RemoveNonUniversalQuals (&(wiz->base_src_quals));
25214     RemoveNonUniversalQuals (&(wiz->extra_src_quals));
25215   }
25216   for (i = 0; i < iatep->num_sequences; i++) {
25217     line = NULL;
25218     ValNodeAddPointer (&line, 0, StringSave (iatep->id_list[i]));
25219     ValNodeLink (&line, TabTableLineFromSrcQuals (iatep->title_list[i], wiz->base_src_quals, wiz->extra_src_quals));
25220     ValNodeAddPointer (&table, 0, line);
25221   }
25222 
25223   if (table != NULL) {
25224     num_cols = ValNodeLen (table->data.ptrvalue);
25225   }
25226 
25227   for (col = 1; col < num_cols; col++) {
25228     table = SortTableRowByAnyColumn (table, col + 1);
25229     row_cols = table->data.ptrvalue;
25230     curr_val = StringSave (GetNthField (row_cols, col));
25231     u = UniversalSrcNew (NULL, NULL);
25232     ValNodeAddPointer (&summaries, 0, u);
25233     ValNodeAddPointer (&(u->val_list), 0, curr_val);
25234     id_list = NULL;
25235     ValNodeAddPointer (&id_list, 0, StringSave (row_cols->data.ptrvalue));
25236     ValNodeAddPointer (&(u->id_list_list), 0, id_list);
25237     for (row = table->next; row != NULL; row = row->next) {
25238       row_cols = row->data.ptrvalue;
25239       this_val = GetNthField (row_cols, col);
25240       if (StringCmp (curr_val, this_val) == 0) {
25241         ValNodeAddPointer (&id_list, 0, StringSave (row_cols->data.ptrvalue));
25242       } else {
25243         ValNodeAddPointer (&(u->val_list), 0, StringSave (this_val));
25244         id_list = NULL;
25245         ValNodeAddPointer (&id_list, 0, StringSave (row_cols->data.ptrvalue));
25246         ValNodeAddPointer (&(u->id_list_list), 0, id_list);
25247         curr_val = this_val;
25248       }
25249     }
25250   }
25251 
25252   table = FreeTabTable (table);
25253   return summaries;
25254 }
25255 
25256 
GetBestValueFromSingleSourceSummary(UniversalSrcPtr u)25257 static CharPtr GetBestValueFromSingleSourceSummary (UniversalSrcPtr u)
25258 {
25259   Int4 best = -1, num;
25260   CharPtr best_val = NULL;
25261   ValNodePtr id, val;
25262 
25263   if (u == NULL || u->val_list == NULL) {
25264     best_val = NULL;
25265   } else if (u->id_list_list == NULL || u->id_list_list->next == NULL) {
25266     best_val = u->val_list->data.ptrvalue;
25267   } else {
25268     for (id = u->id_list_list, val = u->val_list;
25269          id != NULL && val != NULL;
25270          id = id->next, val = val->next) {
25271       num = ValNodeLen (id->data.ptrvalue);
25272       if (best < num) {
25273         best = num;
25274         best_val = val->data.ptrvalue;
25275       }
25276     }
25277   }
25278   return best_val;
25279 }
25280 
25281 
ExplainBestValueFromSingleSourceSummary(UniversalSrcPtr u)25282 static CharPtr ExplainBestValueFromSingleSourceSummary (UniversalSrcPtr u)
25283 {
25284   CharPtr rval = NULL;
25285   CharPtr part_fmt = "'%s' (%d)";
25286   CharPtr more = ", others";
25287   ValNodePtr vnp_i, vnp_v;
25288   Int4       len = 0;
25289 
25290   if (u == NULL || u->val_list->next == NULL) {
25291     return NULL;
25292   }
25293 
25294   for (vnp_i = u->id_list_list, vnp_v = u->val_list;
25295        vnp_i != NULL && vnp_v != NULL && len < 200;
25296        vnp_i = vnp_i->next, vnp_v = vnp_v->next) {
25297     len += StringLen (part_fmt) + 15 + StringLen (vnp_v->data.ptrvalue) + 2;
25298   }
25299   if (vnp_v != NULL) {
25300     len += StringLen (more);
25301   }
25302   rval = (CharPtr) MemNew (sizeof (Char) * len);
25303   rval[0] = 0;
25304   len = 0;
25305   for (vnp_i = u->id_list_list, vnp_v = u->val_list;
25306        vnp_i != NULL && vnp_v != NULL && len < 200;
25307        vnp_i = vnp_i->next, vnp_v = vnp_v->next) {
25308     if (len > 0) {
25309       StringCat (rval, ", ");
25310       len += 2;
25311     }
25312     sprintf (rval + len, part_fmt,
25313              vnp_v->data.ptrvalue == NULL ? "" : vnp_v->data.ptrvalue,
25314              ValNodeLen (vnp_i->data.ptrvalue));
25315     len = StringLen (rval);
25316   }
25317   if (vnp_v != NULL) {
25318     StringCat (rval, more);
25319   }
25320   return rval;
25321 }
25322 
25323 
25324 typedef struct wizardsinglesourceform {
25325   WIZARD_BLOCK
25326 
25327   PrompT PNTR name_prompts;
25328   TexT   PNTR vals;
25329   GrouP  PNTR prompts;
25330   Int4   num_quals;
25331 
25332   ButtoN PNTR add_btns;
25333   Int4   num_unseen;
25334 
25335   PrompT status_title;
25336 
25337   DialoG extra_quals;
25338 
25339   IDAndTitleEditPtr iatep;
25340 } WizardSingleSourceFormData, PNTR WizardSingleSourceFormPtr;
25341 
25342 
CleanupWizardSingleSourceForm(GraphiC g,Pointer data)25343 static void CleanupWizardSingleSourceForm (GraphiC g, Pointer data)
25344 {
25345   WizardSingleSourceFormPtr frm;
25346 
25347   if (data != NULL)
25348   {
25349     frm = (WizardSingleSourceFormPtr) data;
25350     frm->wiz = WizardTrackerFree(frm->wiz);
25351     frm->name_prompts = MemFree (frm->name_prompts);
25352     frm->vals = MemFree (frm->vals);
25353     frm->prompts = MemFree (frm->prompts);
25354     frm->iatep = IDAndTitleEditFree (frm->iatep);
25355   }
25356   StdCleanupFormProc (g, data);
25357 }
25358 
25359 
PopulateSingleSource(WizardSingleSourceFormPtr frm)25360 static void PopulateSingleSource (WizardSingleSourceFormPtr frm)
25361 {
25362   ValNodePtr summaries, vnp, t_vnp;
25363   Int4       i;
25364   CharPtr    exp, new_line;
25365   TagListPtr tlp;
25366   Boolean    has_status_info = FALSE;
25367 
25368   summaries = FindUniversalSourceInfo (frm->iatep, frm->wiz);
25369   for (vnp = summaries, i = 0;
25370        vnp != NULL && i < frm->num_quals;
25371        vnp = vnp->next, i++) {
25372     SetTitle (frm->vals[i], GetBestValueFromSingleSourceSummary(vnp->data.ptrvalue));
25373     exp = ExplainBestValueFromSingleSourceSummary (vnp->data.ptrvalue);
25374     SetTitle (frm->prompts[i], exp);
25375     if (!StringHasNoText (exp)) {
25376       has_status_info = TRUE;
25377     }
25378     exp = MemFree (exp);
25379   }
25380   tlp = (TagListPtr) GetObjectExtra (frm->extra_quals);
25381   t_vnp = tlp->vnp;
25382   while (vnp != NULL && t_vnp != NULL) {
25383     new_line = ReplaceTagListColumn (t_vnp->data.ptrvalue, GetBestValueFromSingleSourceSummary(vnp->data.ptrvalue), 1);
25384     t_vnp->data.ptrvalue = MemFree (t_vnp->data.ptrvalue);
25385     t_vnp->data.ptrvalue = new_line;
25386     vnp = vnp->next;
25387     t_vnp = t_vnp->next;
25388   }
25389 
25390   summaries = UniversalSrcListFree (summaries);
25391   if (has_status_info) {
25392     Show (frm->status_title);
25393   } else {
25394     Hide (frm->status_title);
25395   }
25396 }
25397 
25398 
SaveWizardSingleSource(Pointer data,WizardTrackerPtr wiz)25399 static void SaveWizardSingleSource (Pointer data, WizardTrackerPtr wiz)
25400 {
25401   WizardSingleSourceFormPtr frm;
25402   Int4 i, j, num_erase = 0;
25403   WizardSrcQualPtr q;
25404   CharPtr          val, qual_name;
25405   Char             one_name[100], tmp[100];
25406   TagListPtr       tlp;
25407   ValNodePtr       vnp;
25408 
25409   frm = (WizardSingleSourceFormPtr) data;
25410   if (frm == NULL || wiz == NULL) {
25411     return;
25412   }
25413 
25414   for (j = 0; j < frm->num_quals; j++) {
25415     if (TextHasNoText (frm->vals[j])) {
25416       GetTitle (frm->name_prompts[j], tmp, sizeof (tmp) - 1);
25417       if (DoAnySequencesHaveModifier(frm->iatep, tmp)) {
25418         num_erase++;
25419         GetTitle (frm->name_prompts[j], one_name, sizeof (one_name) - 1);
25420       }
25421     }
25422   }
25423   if (num_erase == 1) {
25424     if (ANS_NO == Message (MSG_YN, "You are about to erase values for %s.  Are you sure?", one_name)) {
25425       return;
25426     }
25427   } else if (num_erase > 0) {
25428     if (ANS_NO == Message (MSG_YN, "You are about to erase values for %d qualifiers.  Are you sure?", num_erase)) {
25429       return;
25430     }
25431   }
25432 
25433   for (j = 0, vnp = wiz->base_src_quals;
25434        vnp != NULL;
25435        vnp = vnp->next, j++) {
25436     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
25437     val = SaveStringFromText (frm->vals[j]);
25438     for (i = 0; i < frm->iatep->num_sequences; i++) {
25439       if (StringHasNoText (val)) {
25440         RemoveValueFromDefline (q->name, frm->iatep->title_list[i]);
25441       } else {
25442         frm->iatep->title_list[i] = ReplaceValueInOneDefLine (frm->iatep->title_list[i], q->name, val);
25443       }
25444     }
25445     val = MemFree (val);
25446   }
25447   for (vnp = wiz->extra_src_quals;
25448        vnp != NULL && j < frm->num_quals;
25449        vnp = vnp->next) {
25450     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
25451     if (q->show) {
25452       val = SaveStringFromText (frm->vals[j]);
25453       for (i = 0; i < frm->iatep->num_sequences; i++) {
25454         if (StringHasNoText (val)) {
25455           RemoveValueFromDefline (q->name, frm->iatep->title_list[i]);
25456         } else {
25457           frm->iatep->title_list[i] = ReplaceValueInOneDefLine (frm->iatep->title_list[i], q->name, val);
25458         }
25459       }
25460       val = MemFree (val);
25461       j++;
25462     }
25463   }
25464   /* remove extra quals previously shown */
25465   while (vnp != NULL) {
25466     q = (WizardSrcQualPtr) vnp->data.ptrvalue;
25467     if (q->show) {
25468       for (i = 0; i < frm->iatep->num_sequences; i++) {
25469         RemoveValueFromDefline (q->name, frm->iatep->title_list[i]);
25470       }
25471     }
25472     vnp = vnp->next;
25473   }
25474 
25475   tlp = (TagListPtr) GetObjectExtra (frm->extra_quals);
25476   for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
25477     qual_name = ExtractTagListColumn (vnp->data.ptrvalue, 0);
25478     if (!StringHasNoText (qual_name)) {
25479       val = ExtractTagListColumn (vnp->data.ptrvalue, 1);
25480       for (i = 0; i < frm->iatep->num_sequences; i++) {
25481         if (StringHasNoText (val)) {
25482           RemoveValueFromDefline (qual_name, frm->iatep->title_list[i]);
25483         } else {
25484           frm->iatep->title_list[i] = ReplaceValueInOneDefLine (frm->iatep->title_list[i], qual_name, val);
25485         }
25486       }
25487       val = MemFree (val);
25488     }
25489     qual_name = MemFree (qual_name);
25490   }
25491 
25492   ApplyIDAndTitleEditToSeqEntryList (wiz->sequences, frm->iatep);
25493   PopulateSingleSource (frm);
25494 }
25495 
25496 
HideUnseenTagListRows(TagListPtr tlp)25497 static void HideUnseenTagListRows (TagListPtr tlp)
25498 {
25499   Int4 len, i, j;
25500 
25501   len = ValNodeLen (tlp->vnp);
25502   if (len > tlp->rows) {
25503     Show (tlp->bar);
25504     for (i = 0; i < tlp->rows; i++) {
25505       for (j = 0; j < tlp->cols; j++) {
25506         Show (tlp->control[(i * MAX_TAGLIST_COLS) + j]);
25507       }
25508     }
25509   } else {
25510     Hide (tlp->bar);
25511     for (i = 0; i < len; i++) {
25512       for (j = 0; j < tlp->cols; j++) {
25513         Show (tlp->control[(i * MAX_TAGLIST_COLS) + j]);
25514       }
25515     }
25516     for ( ; i < tlp->rows; i++) {
25517       for (j = 0; j < tlp->cols; j++) {
25518         Hide (tlp->control[(i * MAX_TAGLIST_COLS) + j]);
25519       }
25520     }
25521   }
25522   CorrectBarMax (tlp->bar, tlp->max);
25523   CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
25524 }
25525 
25526 
AddSingleSourceQual(ButtoN b)25527 static void AddSingleSourceQual(ButtoN b)
25528 {
25529   WizardSingleSourceFormPtr frm;
25530   Int4          i, j, k = 0;
25531   ValNodePtr    vq, vq_prev = NULL;
25532   WizardSrcQualPtr wq;
25533   CharPtr       new_str;
25534   Char          qual_name[PATH_MAX];
25535   Int4          len;
25536   TagListPtr    tlp;
25537   Boolean       found = FALSE;
25538 
25539   frm = (WizardSingleSourceFormPtr) GetObjectExtra (b);
25540   for (i = 0; i < frm->num_unseen; i++) {
25541     if (b == frm->add_btns[i]) {
25542       /* found it */
25543       j = 0;
25544       for (vq = frm->wiz->extra_src_quals; vq != NULL; vq = vq->next) {
25545         wq = (WizardSrcQualPtr) vq->data.ptrvalue;
25546         if (!wq->show) {
25547           if (j == k) {
25548             /* found it, move it to the end and make it shown */
25549             found = TRUE;
25550             if (vq_prev == NULL) {
25551               frm->wiz->extra_src_quals = vq->next;
25552             } else {
25553               vq_prev->next = vq->next;
25554             }
25555             vq->next = NULL;
25556             ValNodeLink (&(frm->wiz->extra_src_quals), vq);
25557             wq->show = TRUE;
25558             break;
25559           } else {
25560             j++;
25561             vq_prev = vq;
25562           }
25563         } else {
25564           vq_prev = vq;
25565         }
25566       }
25567       if (!found) {
25568         GetTitle (b, qual_name, sizeof (qual_name) - 1);
25569         wq = WizardSrcQualNewEx (qual_name + 4, eWizardEditQual_ApplyAll, TRUE,
25570                                  FALSE, NULL, FALSE, GetDefaultExample (qual_name + 4));
25571         ValNodeAddPointer (&(frm->wiz->extra_src_quals), 0, wq);
25572       }
25573       /* add to taglist */
25574       tlp = (TagListPtr) GetObjectExtra (frm->extra_quals);
25575       len = StringLen (wq->name) + StringLen (wq->example) + 4;
25576       new_str = (CharPtr) MemNew (sizeof (Char) * len);
25577       sprintf (new_str, "%s\t\t%s\n", wq->name, wq->example == NULL ? "" : wq->example);
25578       ValNodeAddPointer (&(tlp->vnp), 0, new_str);
25579       SendMessageToDialog (frm->extra_quals, VIB_MSG_REDRAW);
25580       Disable (b);
25581       /* hide extra rows */
25582       Show (frm->extra_quals);
25583       HideUnseenTagListRows (tlp);
25584       break;
25585     }
25586     if (Enabled (frm->add_btns[i])) {
25587       k++;
25588     }
25589   }
25590 }
25591 
25592 
25593 Uint2 single_src_dlg_types [] = {
25594   TAGLIST_PROMPT, TAGLIST_TEXT, TAGLIST_PROMPT
25595 };
25596 
25597 Uint2 single_src_dlg_widths [] = {
25598   8, 10, 20
25599 };
25600 
25601 
ClearSingleSourceQuals(ButtoN b)25602 static void ClearSingleSourceQuals (ButtoN b)
25603 {
25604   WizardSingleSourceFormPtr frm;
25605   Int4                      i;
25606   TagListPtr                tlp;
25607   ValNodePtr                vnp;
25608   CharPtr                   new_line;
25609 
25610   frm = (WizardSingleSourceFormPtr) GetObjectExtra (b);
25611   if (frm == NULL) {
25612     return;
25613   }
25614 
25615   for (i = 0; i < frm->num_quals; i++) {
25616     SetTitle (frm->vals[i], "");
25617   }
25618 
25619   tlp = (TagListPtr) GetObjectExtra (frm->extra_quals);
25620   if (tlp != NULL) {
25621     for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
25622       if (!StringHasNoText (vnp->data.ptrvalue)) {
25623         new_line = ReplaceTagListColumn (vnp->data.ptrvalue, "", 1);
25624         vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
25625         vnp->data.ptrvalue = new_line;
25626       }
25627     }
25628   }
25629   SendMessageToDialog (frm->extra_quals, VIB_MSG_REDRAW);
25630 }
25631 
25632 
CreateWizardSingleSourceForm(WizardTrackerPtr wiz)25633 static Boolean CreateWizardSingleSourceForm (WizardTrackerPtr wiz)
25634 {
25635   WizardSingleSourceFormPtr frm;
25636   WindoW w;
25637   GrouP  h, quals_grp, g, add_grp = NULL;
25638   GrouP  c;
25639   CharPtr dlg_title, exp;
25640   ValNodePtr summaries, vnp, vq;
25641   WizardQualPtr wq;
25642   Int4          i;
25643   Int4          status_width = 200;
25644   Char          add_txt[PATH_MAX];
25645   ButtoN        clear_btn;
25646   Boolean       has_status_info = FALSE;
25647   PrompT        title_prompt;
25648 
25649   frm = (WizardSingleSourceFormPtr) MemNew (sizeof (WizardSingleSourceFormData));
25650   frm->wiz = wiz;
25651   frm->collect_func = SaveWizardSingleSource;
25652   frm->fwd_ok_func = WizardSrcQualsOk;
25653   frm->next_form = AskAboutWGSLocation;
25654   frm->iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
25655   wiz->base_src_quals = ValNodeFreeData (wiz->base_src_quals);
25656   SetWizardTrackerBaseSrcQuals (wiz, frm->iatep);
25657   wiz->extra_src_quals = ValNodeFreeData (wiz->extra_src_quals);
25658   SetWizardTrackerExtraSrcQuals (wiz, frm->iatep);
25659   summaries = FindUniversalSourceInfo (frm->iatep, wiz);
25660   frm->num_quals = CountSrcQualsToShow (wiz->base_src_quals, wiz->extra_src_quals);
25661   frm->name_prompts = (PrompT PNTR) MemNew (sizeof (PrompT) * frm->num_quals);
25662   frm->vals = (TexT PNTR) MemNew (sizeof (TexT) * frm->num_quals);
25663   frm->prompts = (GrouP PNTR) MemNew (sizeof (PrompT) * frm->num_quals);
25664   frm->num_unseen = CountUnseenSrcQuals (wiz->extra_src_quals);
25665   if (frm->num_unseen > 0) {
25666     frm->add_btns = (ButtoN PNTR) MemNew (sizeof (ButtoN) * frm->num_unseen);
25667   }
25668 
25669   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Source);
25670   SendHelpScrollMessage (helpForm, dlg_title, "");
25671 
25672   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
25673   SetObjectExtra (w, frm, CleanupWizardSingleSourceForm);
25674   frm->form = (ForM) w;
25675 
25676   h = HiddenGroup (w, -1, -1, NULL);
25677   SetGroupSpacing (h, 10, 10);
25678 
25679   title_prompt = StaticPrompt (h, "Please provide the required source information common to all of your sequences.", 0, 0, systemFont, 'c');
25680   StaticPrompt (h, "", 0, 0, systemFont, 'c');
25681   quals_grp = HiddenGroup (h, 1, 0, NULL);
25682   g = HiddenGroup (quals_grp, 4, 0, NULL);
25683   StaticPrompt (g, "Qualifier", 112, 0, systemFont, 'l');
25684   StaticPrompt (g, "Value", 0, 0, systemFont, 'c');
25685   StaticPrompt (g, "Example", 0, 0, systemFont, 'l');
25686   frm->status_title = StaticPrompt (g, "Existing Values", 0, 0, systemFont, 'c');
25687   StaticPrompt (g, "", single_src_dlg_widths[0], 0, systemFont, 'l');
25688   StaticPrompt (g, "", 0, 0, systemFont, 'c');
25689   StaticPrompt (g, "", 0, 0, systemFont, 'c');
25690   StaticPrompt (g, "", 0, 0, systemFont, 'c');
25691   for (vnp = summaries, vq = wiz->base_src_quals, i = 0;
25692        vnp != NULL && vq != NULL;
25693        vnp = vnp->next, vq = vq->next, i++) {
25694     wq = (WizardQualPtr) vq->data.ptrvalue;
25695     frm->name_prompts[i] = StaticPrompt (g, wq->name, 0, 0, systemFont, 'l');
25696     frm->vals[i] = DialogText (g, GetBestValueFromSingleSourceSummary(vnp->data.ptrvalue),
25697                                single_src_dlg_widths[1], NULL);
25698     StaticPrompt (g, wq->example, 0, 0, systemFont, 'l');
25699     exp = ExplainBestValueFromSingleSourceSummary (vnp->data.ptrvalue);
25700     frm->prompts[i] = MultiLinePrompt (g, exp, status_width, systemFont);
25701     if (!StringHasNoText (exp)) {
25702       has_status_info = TRUE;
25703     }
25704     exp = MemFree (exp);
25705   }
25706   for (vq = wiz->extra_src_quals;
25707        vnp != NULL && vq != NULL;
25708        vq = vq->next) {
25709     wq = (WizardQualPtr) vq->data.ptrvalue;
25710     if (wq->show) {
25711       frm->name_prompts[i] = StaticPrompt (g, wq->name, 0, 0, systemFont, 'l');
25712       frm->vals[i] = DialogText (g, GetBestValueFromSingleSourceSummary(vnp->data.ptrvalue),
25713                                  single_src_dlg_widths[1], NULL);
25714       StaticPrompt (g, wq->example, 0, 0, systemFont, 'l');
25715       exp = ExplainBestValueFromSingleSourceSummary (vnp->data.ptrvalue);
25716       frm->prompts[i] = MultiLinePrompt (g, exp, status_width, systemFont);
25717       if (!StringHasNoText (exp)) {
25718         has_status_info = TRUE;
25719       }
25720       exp = MemFree (exp);
25721       vnp = vnp->next;
25722       i++;
25723     }
25724   }
25725   summaries = UniversalSrcListFree (summaries);
25726 
25727   if (has_status_info) {
25728     Show (frm->status_title);
25729   } else {
25730     Hide (frm->status_title);
25731   }
25732 
25733   /* extra qualifiers */
25734   frm->extra_quals = CreateTagListDialogEx3 (quals_grp, 4, 3, 2,
25735                                       single_src_dlg_types, single_src_dlg_widths, NULL,
25736                                       TRUE, TRUE,
25737                                       NULL,
25738                                       NULL,
25739                                       NULL, NULL, FALSE, FALSE);
25740   Hide (frm->extra_quals);
25741 
25742 
25743   if (frm->num_unseen > 0) {
25744     add_grp = HiddenGroup (h, 6, 0, NULL);
25745     i = 0;
25746     for (vq = wiz->extra_src_quals;
25747          vq != NULL && i < frm->num_unseen;
25748          vq = vq->next) {
25749       wq = (WizardQualPtr) vq->data.ptrvalue;
25750       if (!wq->show) {
25751         sprintf (add_txt, "Add %s", wq->name);
25752         frm->add_btns[i] = PushButton (add_grp, add_txt, AddSingleSourceQual);
25753         SetObjectExtra (frm->add_btns[i], frm, NULL);
25754         i++;
25755       }
25756     }
25757   }
25758 
25759   clear_btn = PushButton (h, "Clear", ClearSingleSourceQuals);
25760   SetObjectExtra (clear_btn, frm, NULL);
25761 
25762   c = MakeWizardNav (h, frm);
25763 
25764   AlignObjects (ALIGN_CENTER, (HANDLE) title_prompt,
25765                               (HANDLE) quals_grp,
25766                               (HANDLE) clear_btn,
25767                               (HANDLE) c,
25768                               (HANDLE) add_grp,
25769                               NULL);
25770 
25771   Update();
25772   Show (w);
25773 
25774   return TRUE;
25775 }
25776 
25777 
25778 typedef struct wizardsourceavailabilityform {
25779   WIZARD_BLOCK
25780 
25781   TexT   org;
25782   TexT   dna;
25783 } WizardSourceAvailabilityFormData, PNTR WizardSourceAvailabilityFormPtr;
25784 
25785 
SaveWizardSourceAvailability(Pointer data,WizardTrackerPtr wiz)25786 static void SaveWizardSourceAvailability (Pointer data, WizardTrackerPtr wiz)
25787 {
25788   WizardSourceAvailabilityFormPtr frm;
25789   Int4 len = 0;
25790   CharPtr prefix = "Source Availability: ";
25791   CharPtr org_fmt = "organism available from %s";
25792   CharPtr dna_fmt = "DNA available from %s";
25793   CharPtr org = NULL, dna = NULL;
25794 
25795   frm = (WizardSourceAvailabilityFormPtr) data;
25796   if (frm == NULL || wiz == NULL) {
25797     return;
25798   }
25799 
25800   wiz->comment = MemFree (wiz->comment);
25801   if (TextHasNoText (frm->org) && TextHasNoText (frm->dna)) {
25802     return;
25803   }
25804 
25805   len += StringLen (prefix);
25806   if (!TextHasNoText (frm->org)) {
25807     org = SaveStringFromText (frm->org);
25808     len += StringLen (org_fmt) + StringLen (org);
25809   }
25810   if (!TextHasNoText (frm->dna)) {
25811     dna = SaveStringFromText (frm->dna);
25812     len += StringLen (dna_fmt) + StringLen (dna);
25813     if (!StringHasNoText (org)) {
25814       len += 2;
25815     }
25816   }
25817   wiz->comment = (CharPtr) MemNew (sizeof (Char) * len);
25818   StringCpy (wiz->comment, prefix);
25819   len = StringLen (prefix);
25820   if (!StringHasNoText (org)) {
25821     sprintf (wiz->comment + len, org_fmt, org);
25822     if (!StringHasNoText (dna)) {
25823       StringCat (wiz->comment, ", ");
25824     }
25825     len = StringLen (wiz->comment);
25826   }
25827   if (!StringHasNoText (dna)) {
25828     sprintf (wiz->comment + len, dna_fmt, dna);
25829   }
25830 
25831   org = MemFree (org);
25832   dna = MemFree (dna);
25833 }
25834 
25835 
CreateWizardSourceAvailabilityForm(WizardTrackerPtr wiz)25836 static Boolean CreateWizardSourceAvailabilityForm (WizardTrackerPtr wiz)
25837 {
25838   WizardSourceAvailabilityFormPtr frm;
25839   WindoW w;
25840   GrouP  h, g1, g;
25841   GrouP  c;
25842   PrompT p = NULL;
25843   CharPtr dlg_title;
25844 
25845   frm = (WizardSourceAvailabilityFormPtr) MemNew (sizeof (WizardSourceAvailabilityFormData));
25846   frm->wiz = wiz;
25847   frm->collect_func = SaveWizardSourceAvailability;
25848   frm->fwd_ok_func = NULL;
25849   frm->next_form = BioProjectBioSampleWindow;
25850 
25851   dlg_title = FormatWizardTitle("%s Source Availability", wiz->wizard_type);
25852   SendHelpScrollMessage (helpForm, dlg_title, "");
25853 
25854   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
25855   SetObjectExtra (w, frm, CleanupWizardForm);
25856   dlg_title = MemFree (dlg_title);
25857   frm->form = (ForM) w;
25858 
25859   h = HiddenGroup (w, -1, -1, NULL);
25860   SetGroupSpacing (h, 10, 10);
25861 
25862   g1 = NormalGroup (h, -1, 0, "Is the source organism available for other researchers?", programFont, NULL);
25863   SetGroupSpacing (g1, 10, 10);
25864   StaticPrompt (g1, "", 0, 0, programFont, 'l');
25865   if (frm->wiz->wgs_source_type == eWGSSourceType_Bacteria) {
25866     p = StaticPrompt (g1, "Provide a name and address of the lab or PI, or a culture collection identifier", 0, 0, programFont, 'l');
25867   }
25868   g = HiddenGroup (g1, 2, 0, NULL);
25869   SetGroupSpacing (g, 10, 10);
25870   switch (frm->wiz->wgs_source_type) {
25871     case eWGSSourceType_Bacteria:
25872       StaticPrompt (g, "Bacteria is available from", 0, 0, programFont, 'l');
25873       break;
25874     case eWGSSourceType_Fungi:
25875       StaticPrompt (g, "Fungus is available from", 0, 0, programFont, 'l');
25876       break;
25877     default:
25878       StaticPrompt (g, "Organism is available from", 0, 0, programFont, 'l');
25879       break;
25880   }
25881   frm->org = DialogText (g, "", 15, NULL);
25882   StaticPrompt (g, "Source DNA is available from", 0, 0, programFont, 'c');
25883   frm->dna = DialogText (g, "", 15, NULL);
25884   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) p, NULL);
25885 
25886   c = MakeWizardNav (h, frm);
25887 
25888   AlignObjects (ALIGN_CENTER, (HANDLE) g1,
25889                               (HANDLE) c,
25890                               NULL);
25891 
25892   Update();
25893   Show (w);
25894 
25895   return TRUE;
25896 }
25897 
25898 
25899 #define QUAL_BY_BY_LIST_WIZARD_BLOCK         \
25900   WIZARD_BLOCK \
25901   DialoG clickable_list_dlg; \
25902   TexT   mark_seqid_list; \
25903   ValNodePtr seq_list;
25904 
25905 typedef struct qualbylistwizardform {
25906   QUAL_BY_BY_LIST_WIZARD_BLOCK
25907 } QualByListWizardFormData, PNTR QualByListWizardFormPtr;
25908 
25909 
CleanupQualByListWizard(GraphiC g,Pointer data)25910 static void CleanupQualByListWizard (GraphiC g, Pointer data)
25911 {
25912   QualByListWizardFormPtr frm;
25913 
25914   if (data != NULL)
25915   {
25916     frm = (QualByListWizardFormPtr) data;
25917     frm->seq_list = FreeClickableList (frm->seq_list);
25918   }
25919   CleanupWizardForm (g, data);
25920 }
25921 
25922 
MarkSetQualListBtn(ButtoN b)25923 static void MarkSetQualListBtn (ButtoN b)
25924 {
25925   QualByListWizardFormPtr frm;
25926   CharPtr id_list;
25927 
25928   frm = (QualByListWizardFormPtr) GetObjectExtra (b);
25929   if (frm == NULL || TextHasNoText (frm->mark_seqid_list)) {
25930     return;
25931   }
25932 
25933   id_list = SaveStringFromText (frm->mark_seqid_list);
25934   ChooseCategoriesByIdList (frm->seq_list, id_list);
25935   id_list = MemFree (id_list);
25936   PointerToDialog (frm->clickable_list_dlg, frm->seq_list);
25937 }
25938 
25939 
UnselectAllSequencesForSetQual(ButtoN b)25940 static void UnselectAllSequencesForSetQual (ButtoN b)
25941 {
25942   QualByListWizardFormPtr frm;
25943 
25944   frm = (QualByListWizardFormPtr) GetObjectExtra (b);
25945   if (frm != NULL) {
25946     ChooseCategories (frm->seq_list, FALSE);
25947     PointerToDialog (frm->clickable_list_dlg, frm->seq_list);
25948   }
25949 }
25950 
25951 
25952 typedef struct setsrcqualwizardform {
25953   QUAL_BY_BY_LIST_WIZARD_BLOCK
25954   CharPtr qual;
25955   CharPtr val;
25956 } SetQualWizardFormData, PNTR SetQualWizardFormPtr;
25957 
25958 
CleanupSetQualWizardForm(GraphiC g,Pointer data)25959 static void CleanupSetQualWizardForm (GraphiC g, Pointer data)
25960 {
25961   SetQualWizardFormPtr frm;
25962 
25963   if (data != NULL)
25964   {
25965     frm = (SetQualWizardFormPtr) data;
25966     frm->qual = MemFree (frm->qual);
25967     frm->val = MemFree (frm->val);
25968   }
25969   CleanupQualByListWizard (g, data);
25970 }
25971 
25972 
SaveSetQual(Pointer data,WizardTrackerPtr wiz)25973 static void SaveSetQual (Pointer data, WizardTrackerPtr wiz)
25974 {
25975   SetQualWizardFormPtr frm;
25976   ValNodePtr           vnp, vnp_i;
25977   ClickableItemPtr     cip;
25978   BioseqPtr            bsp;
25979   SeqDescPtr           sdp;
25980   CharPtr              title;
25981   CharPtr              curr_val;
25982 
25983   frm = (SetQualWizardFormPtr) data;
25984   if (frm == NULL || wiz == NULL) {
25985     return;
25986   }
25987 
25988   for (vnp = frm->seq_list; vnp != NULL; vnp = vnp->next) {
25989     if ((cip = (ClickableItemPtr) (vnp->data.ptrvalue)) != NULL) {
25990       for (vnp_i = cip->item_list; vnp_i != NULL; vnp_i = vnp_i->next) {
25991         if (vnp_i->choice == OBJ_BIOSEQ && (bsp = (BioseqPtr) vnp_i->data.ptrvalue) != NULL) {
25992           sdp = bsp->descr;
25993           while (sdp != NULL && sdp->choice != Seq_descr_title) {
25994             sdp = sdp->next;
25995           }
25996           if (sdp == NULL) {
25997             sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_title);
25998           }
25999           title = sdp->data.ptrvalue;
26000           if (cip->chosen) {
26001             title = ReplaceValueInOneDefLine (title, frm->qual, frm->val);
26002           } else {
26003             curr_val = FindValueFromPairInDefline (frm->qual, title);
26004             if (StringICmp (frm->val, curr_val) == 0) {
26005               RemoveValueFromDefline (frm->qual, title);
26006             }
26007             curr_val = MemFree (curr_val);
26008           }
26009           sdp->data.ptrvalue = title;
26010         }
26011       }
26012     }
26013   }
26014 }
26015 
26016 
SetQualForSequencesFromWizardList(WizardTrackerPtr wiz,CharPtr qual,CharPtr val,CharPtr help,SequencesOkFunc ok_func,CreateFormFunc next_form)26017 NLM_EXTERN Boolean SetQualForSequencesFromWizardList (WizardTrackerPtr wiz, CharPtr qual, CharPtr val, CharPtr help, SequencesOkFunc ok_func, CreateFormFunc next_form)
26018 {
26019   WindoW w;
26020   SetQualWizardFormPtr frm;
26021   GrouP h, mark_grp, c;
26022   ButtoN b, unselect;
26023   ValNodeBlock change_list;
26024   SeqEntryPtr  sep;
26025   ClickableItemPtr cip;
26026   Boolean          rval = FALSE;
26027   CharPtr          dlg_title = val;
26028   CharPtr          title, curr_val;
26029   PrompT           p1, p2, p_top = NULL;
26030 
26031   if (wiz->sequences == NULL) {
26032     return FALSE;
26033   }
26034 
26035   frm = (SetQualWizardFormPtr) MemNew (sizeof (SetQualWizardFormData));
26036   frm->wiz = wiz;
26037   frm->collect_func = SaveSetQual;
26038   frm->fwd_ok_func = ok_func;
26039   frm->next_form = next_form;
26040   frm->qual = StringSave (qual);
26041   frm->val = StringSave (val);
26042   InitValNodeBlock (&change_list, NULL);
26043   for (sep = wiz->sequences; sep != NULL; sep = sep->next) {
26044     if (IS_Bioseq (sep)) {
26045       cip = ClickableItemForBioseq (sep->data.ptrvalue);
26046       title = BioseqGetTitle(sep->data.ptrvalue);
26047       curr_val = FindValueFromPairInDefline (qual, title);
26048       if (StringICmp (val, curr_val) == 0) {
26049         cip->chosen = TRUE;
26050       }
26051       curr_val = MemFree (curr_val);
26052       ValNodeAddPointerToEnd (&change_list, 0, cip);
26053     }
26054   }
26055 
26056   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
26057   frm->form = (ForM) w;
26058   SetObjectExtra (w, frm, CleanupSetQualWizardForm);
26059   frm->seq_list = change_list.head;
26060 
26061   h = HiddenGroup (w, -1, 0, NULL);
26062 
26063   if (!StringHasNoText (help)) {
26064     p_top = StaticPrompt (h, help, 0, 0, systemFont, 'c');
26065   }
26066 
26067   frm->clickable_list_dlg = CreateClickableListDialogExEx (h, "Sequences in your file", val,
26068                                                       NULL, NULL,
26069                                                       NULL, NULL, NULL,
26070                                                       GetDiscrepancyItemText,
26071                                                       stdCharWidth * 30,
26072                                                       stdCharWidth * 30 + 5,
26073                                                       TRUE, FALSE, TRUE);
26074   PointerToDialog (frm->clickable_list_dlg, frm->seq_list);
26075   mark_grp = HiddenGroup (h, 2, 0, NULL);
26076   SetGroupSpacing (mark_grp, 10, 10);
26077   b = PushButton (mark_grp, "Select sequences in this list:", MarkSetQualListBtn);
26078   SetObjectExtra (b, frm, NULL);
26079   frm->mark_seqid_list = DialogText (mark_grp, "", 30, NULL);
26080   p1 = StaticPrompt (h, "Paste a list of sequence IDs in the text box and click button: Select sequences in this list", 0, 0, systemFont, 'c');
26081   unselect = PushButton (h, "Unselect All Sequences", UnselectAllSequencesForSetQual);
26082   SetObjectExtra (unselect, frm, NULL);
26083   p2 = StaticPrompt (h, "", 0, 0, systemFont, 'c');
26084 
26085   c = MakeWizardNav (h, frm);
26086 
26087   AlignObjects (ALIGN_CENTER,
26088                 (HANDLE) frm->clickable_list_dlg,
26089                 (HANDLE) mark_grp,
26090                 (HANDLE) p1,
26091                 (HANDLE) unselect,
26092                 (HANDLE) p2,
26093                 (HANDLE) c,
26094                 (HANDLE) p_top,
26095                 NULL);
26096 
26097   RealizeWindow (w);
26098   Show (w);
26099   Update ();
26100   Select (w);
26101   return TRUE;
26102 }
26103 
26104 
IsStringPlasmid(CharPtr val)26105 static Boolean IsStringPlasmid (CharPtr val)
26106 {
26107   if (StringICmp (val, "plasmid") == 0) {
26108     return TRUE;
26109   } else {
26110     return FALSE;
26111   }
26112 }
26113 
26114 
AnyPlasmids(WizardTrackerPtr wiz)26115 static Boolean AnyPlasmids (WizardTrackerPtr wiz)
26116 {
26117   Boolean rval = FALSE;
26118   IDAndTitleEditPtr iatep;
26119 
26120   if (wiz == NULL || wiz->sequences == NULL) {
26121     return FALSE;
26122   }
26123   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
26124   if (DoAnySequencesHaveModifierEx (iatep, "location", IsStringPlasmid)) {
26125     rval = TRUE;
26126   }
26127   iatep = IDAndTitleEditFree (iatep);
26128   if (!rval) {
26129     Message (MSG_ERROR, "You have not selected any sequences as plasmids.");
26130   }
26131   return rval;
26132 }
26133 
26134 
SetPlasmids(WizardTrackerPtr wiz)26135 static Boolean SetPlasmids (WizardTrackerPtr wiz)
26136 {
26137   return SetQualForSequencesFromWizardList (wiz, "location", "plasmid",
26138           "Use checkboxes to select sequences that are derived from naturally-occurring plasmids or paste a list in the text box below.",
26139           AnyPlasmids, SetPlasmidNames);
26140 }
26141 
26142 
26143 typedef struct setlocationswizardform {
26144   QUAL_BY_BY_LIST_WIZARD_BLOCK
26145   PopuP location;
26146 } SetLocationsWizardFormData, PNTR SetLocationsWizardFormPtr;
26147 
26148 static CharPtr wizard_genomes[] = {
26149  "nucleus",
26150  "chloroplast",
26151  "mitochondrion",
26152  "apicoplast",
26153  "chromatophore",
26154  "chromoplast",
26155  "cyanelle",
26156  "hydrogenosome",
26157  "kinetoplast",
26158  "leucoplast",
26159  "macronuclear",
26160  "nucleomorph",
26161  "plastid",
26162  "proplastid",
26163  NULL};
26164 
26165 
SetLocationForChosen(ValNodePtr list,CharPtr genome,Boolean chosen)26166 static Boolean SetLocationForChosen (ValNodePtr list, CharPtr genome, Boolean chosen)
26167 {
26168   ValNodePtr                vnp, vnp_i;
26169   ClickableItemPtr          cip;
26170   BioseqPtr                 bsp;
26171   SeqDescPtr                sdp;
26172   CharPtr                   title;
26173   Boolean                   rval = FALSE;
26174 
26175   for (vnp = list; vnp != NULL; vnp = vnp->next) {
26176     cip = (ClickableItemPtr) vnp->data.ptrvalue;
26177     if (cip == NULL) continue;
26178     if (chosen || cip->chosen) {
26179       for (vnp_i = cip->item_list; vnp_i != NULL; vnp_i = vnp_i->next) {
26180         if (vnp_i->choice == OBJ_BIOSEQ && (bsp = (BioseqPtr) vnp_i->data.ptrvalue) != NULL) {
26181           sdp = bsp->descr;
26182           while (sdp != NULL && sdp->choice != Seq_descr_title) {
26183             sdp = sdp->next;
26184           }
26185           if (sdp == NULL) {
26186             sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_title);
26187             sdp->data.ptrvalue = StringSave ("");
26188           }
26189           title = sdp->data.ptrvalue;
26190           if (StringHasNoText (genome)) {
26191             RemoveValueFromDefline ("location", title);
26192           } else {
26193             title = ReplaceValueInOneDefLine (title, "location", genome);
26194           }
26195           sdp->data.ptrvalue = title;
26196           rval = TRUE;
26197         }
26198       }
26199       rval |= SetLocationForChosen (cip->subcategories, genome, TRUE);
26200     } else {
26201       rval |= SetLocationForChosen (cip->subcategories, genome, FALSE);
26202     }
26203   }
26204   return rval;
26205 }
26206 
26207 
GroupByGenome(SeqEntryPtr sequences)26208 static ValNodePtr GroupByGenome (SeqEntryPtr sequences)
26209 {
26210   ValNodeBlock change_list;
26211   SeqEntryPtr  sep;
26212   ValNodePtr   sorted_list, vnp, vnp_next, vnp_prev;
26213   BioseqPtr    bsp;
26214   CharPtr      title;
26215   CharPtr      genome;
26216   ClickableItemPtr cip, cip_last;
26217 
26218   InitValNodeBlock (&change_list, NULL);
26219   for (sep = sequences; sep != NULL; sep = sep->next) {
26220     if (IS_Bioseq (sep) && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL) {
26221       title = BioseqGetTitle(bsp);
26222       genome = FindValueFromPairInDefline ("location", title);
26223       if (StringHasNoText (genome)) {
26224         genome = MemFree (genome);
26225         genome = StringSave ("nucleus");
26226       }
26227       cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
26228       cip->description = genome;
26229       ValNodeAddPointer (&(cip->subcategories), 0, ClickableItemForBioseq(bsp));
26230       ValNodeAddPointerToEnd (&change_list, 0, cip);
26231     }
26232   }
26233 
26234   sorted_list = ValNodeSort (change_list.head, SortVnpByDiscrepancyDescription);
26235 
26236   cip_last = sorted_list->data.ptrvalue;
26237   vnp_prev = sorted_list;
26238   cip_last->expanded = TRUE;
26239   for (vnp = sorted_list->next; vnp != NULL; vnp = vnp_next) {
26240     vnp_next = vnp->next;
26241     cip = (ClickableItemPtr) vnp->data.ptrvalue;
26242     if (StringCmp (cip->description, cip_last->description) == 0) {
26243       ValNodeLink (&(cip_last->item_list), cip->item_list);
26244       cip->item_list = NULL;
26245       ValNodeLink (&(cip_last->subcategories), cip->subcategories);
26246       cip->subcategories = NULL;
26247       cip = ClickableItemFree (cip);
26248       vnp_prev->next = vnp_next;
26249       vnp->next = NULL;
26250       vnp = ValNodeFree (vnp);
26251     } else {
26252       vnp_prev = vnp;
26253       cip_last = cip;
26254       cip_last->expanded = TRUE;
26255     }
26256   }
26257   return sorted_list;
26258 }
26259 
26260 
AddLocationToSelectedSequences(ButtoN b)26261 static void AddLocationToSelectedSequences (ButtoN b)
26262 {
26263   SetLocationsWizardFormPtr frm;
26264   Uint1                     val;
26265   Boolean                   update = FALSE;
26266 
26267   frm = (SetLocationsWizardFormPtr) GetObjectExtra (b);
26268   if (frm == NULL) {
26269     return;
26270   }
26271 
26272   val = GetValue (frm->location);
26273   if (val < 1) {
26274     Message (MSG_ERROR, "Must select location!");
26275   } else if (val == 1) {
26276     if (SetLocationForChosen (frm->seq_list, NULL, FALSE)) {
26277       update = TRUE;
26278     } else {
26279       Message (MSG_ERROR, "Must select sequences!");
26280     }
26281   } else if (!SetLocationForChosen (frm->seq_list, wizard_genomes[val - 1], FALSE)) {
26282     Message (MSG_ERROR, "Must select sequences!");
26283   } else {
26284     update = TRUE;
26285   }
26286   if (update) {
26287     /* need to redo display */
26288     frm->seq_list = FreeClickableList (frm->seq_list);
26289     frm->seq_list = GroupByGenome(frm->wiz->sequences);
26290     PointerToDialog (frm->clickable_list_dlg, frm->seq_list);
26291   }
26292 }
26293 
26294 
RemoveAllOrganelles(ButtoN b)26295 static void RemoveAllOrganelles (ButtoN b)
26296 {
26297   SetLocationsWizardFormPtr frm;
26298 
26299   frm = (SetLocationsWizardFormPtr) GetObjectExtra (b);
26300   if (frm == NULL) {
26301     return;
26302   }
26303 
26304   SetLocationForChosen (frm->seq_list, NULL, TRUE);
26305   frm->seq_list = FreeClickableList (frm->seq_list);
26306   frm->seq_list = GroupByGenome(frm->wiz->sequences);
26307   PointerToDialog (frm->clickable_list_dlg, frm->seq_list);
26308 
26309 }
26310 
26311 
SetLocationsForSequencesFromWizardList(WizardTrackerPtr wiz,SequencesOkFunc ok_func,CreateFormFunc next_form)26312 NLM_EXTERN Boolean SetLocationsForSequencesFromWizardList (WizardTrackerPtr wiz, SequencesOkFunc ok_func, CreateFormFunc next_form)
26313 {
26314   WindoW w;
26315   SetLocationsWizardFormPtr frm;
26316   GrouP h, mark_grp, set_grp, remove_grp, c;
26317   ButtoN b;
26318   Int4             i;
26319   CharPtr          dlg_title = "WGS Wizard Organelle-Derived Sequences";
26320   PrompT           p1;
26321 
26322   if (wiz->sequences == NULL) {
26323     return FALSE;
26324   }
26325 
26326   frm = (SetLocationsWizardFormPtr) MemNew (sizeof (SetLocationsWizardFormData));
26327   frm->wiz = wiz;
26328   frm->collect_func = NULL;
26329   frm->fwd_ok_func = ok_func;
26330   frm->next_form = next_form;
26331 
26332   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
26333   frm->form = (ForM) w;
26334   SetObjectExtra (w, frm, CleanupQualByListWizard);
26335   frm->seq_list = GroupByGenome(wiz->sequences);
26336 
26337   h = HiddenGroup (w, -1, 0, NULL);
26338 
26339 
26340   frm->clickable_list_dlg = CreateClickableListDialogExEx (h, "Sequences in your file", "Sequences from organelle",
26341                                                       NULL, NULL,
26342                                                       NULL, NULL, NULL,
26343                                                       GetDiscrepancyItemText,
26344                                                       stdCharWidth * 30,
26345                                                       stdCharWidth * 30 + 5,
26346                                                       TRUE, FALSE, TRUE);
26347   PointerToDialog (frm->clickable_list_dlg, frm->seq_list);
26348 
26349   p1 = StaticPrompt (h, "Use checkboxes to select sequences from an organelle or paste the a list in the text box below.", 0, 0, systemFont, 'c');
26350   mark_grp = HiddenGroup (h, 2, 0, NULL);
26351   SetGroupSpacing (mark_grp, 10, 10);
26352   b = PushButton (mark_grp, "Select sequences in this list:", MarkSetQualListBtn);
26353   SetObjectExtra (b, frm, NULL);
26354   frm->mark_seqid_list = DialogText (mark_grp, "", 30, NULL);
26355 
26356 
26357   set_grp = HiddenGroup (h, 2, 0, NULL);
26358   SetGroupSpacing (set_grp, 10, 10);
26359   frm->location = PopupList (set_grp, TRUE, NULL);
26360   for (i = 0; wizard_genomes[i] != NULL; i++) {
26361     PopupItem (frm->location, wizard_genomes[i]);
26362   }
26363   SetValue (frm->location, 1);
26364   b = PushButton (set_grp, "Apply Location to Selected Sequences", AddLocationToSelectedSequences);
26365   SetObjectExtra (b, frm, NULL);
26366 
26367   remove_grp = HiddenGroup (h, 2, 0, NULL);
26368   SetGroupSpacing (remove_grp, 10, 10);
26369   b = PushButton (remove_grp, "Unselect All Sequences", UnselectAllSequencesForSetQual);
26370   SetObjectExtra (b, frm, NULL);
26371   b = PushButton (remove_grp, "Remove All Organelles", RemoveAllOrganelles);
26372   SetObjectExtra (b, frm, NULL);
26373 
26374   c = MakeWizardNav (h, frm);
26375 
26376   AlignObjects (ALIGN_CENTER,
26377                 (HANDLE) frm->clickable_list_dlg,
26378                 (HANDLE) p1,
26379                 (HANDLE) mark_grp,
26380                 (HANDLE) remove_grp,
26381                 (HANDLE) set_grp,
26382                 (HANDLE) c,
26383                 NULL);
26384 
26385   RealizeWindow (w);
26386   Show (w);
26387   Update ();
26388   Select (w);
26389   return TRUE;
26390 }
26391 
26392 
SetAllWizardLocations(WizardTrackerPtr wiz)26393 static Boolean SetAllWizardLocations (WizardTrackerPtr wiz)
26394 {
26395   return SetLocationsForSequencesFromWizardList (wiz, NULL, AskAboutChromosomes);
26396 }
26397 
26398 
26399 static WizardChoiceData wgs_location_bacteria_choice_list[] = {
26400   { "Yes", NULL, SetPlasmids } ,
26401   { "No", OkToContinueToSequin, FinishWizardAndLaunchSequin },
26402   { NULL, NULL, NULL }
26403 };
26404 
26405 
26406 static WizardChoiceData wgs_location_nonbacteria_choice_list[] = {
26407   { "Yes", NULL, SetAllWizardLocations } ,
26408   { "No", NULL, AskAboutChromosomes },
26409   { NULL, NULL, NULL }
26410 };
26411 
26412 
AskAboutWGSLocation(WizardTrackerPtr wiz)26413 static Boolean AskAboutWGSLocation (WizardTrackerPtr wiz)
26414 {
26415   IDAndTitleEditPtr iatep;
26416   Boolean           force_yes = FALSE;
26417 
26418   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
26419   if (wiz->wgs_source_type == eWGSSourceType_Bacteria) {
26420     if (DoAnySequencesHaveModifierEx (iatep, "location", IsStringPlasmid) || DoAnySequencesHaveModifier(iatep, "plasmid-name")) {
26421       force_yes = TRUE;
26422     }
26423   } else if (DoAnySequencesHaveModifier(iatep, "location")) {
26424     force_yes = TRUE;
26425   }
26426   iatep = IDAndTitleEditFree (iatep);
26427 
26428   if (wiz->wgs_source_type == eWGSSourceType_Bacteria) {
26429     if (force_yes) {
26430       return SetPlasmids (wiz);
26431     } else {
26432       return CreateWizardSingleChoiceForm (wiz, wgs_location_bacteria_choice_list,
26433                                            "Sequence Location", "Are any of your sequences derived from a naturally-occurring plasmid?");
26434     }
26435   } else {
26436     if (force_yes) {
26437       return SetAllWizardLocations (wiz);
26438     } else {
26439       return CreateWizardSingleChoiceForm (wiz, wgs_location_nonbacteria_choice_list,
26440                                          "WGS Wizard Sequence Location", "Are any of your sequences derived from an organelle (chloroplast, mitochondrion, etc.)?");
26441     }
26442   }
26443 }
26444 
26445 
26446 typedef struct wizardrelatedqualsform {
26447   WIZARD_BLOCK
26448   DialoG qual_table;
26449   GrouP PNTR ed_grps;
26450   TexT PNTR  apply_all_txt;
26451   ButtoN PNTR bulk_btns;
26452 
26453   IDAndTitleEditPtr iatep;
26454   ValNodePtr        rows_displayed;
26455   CharPtr           new_qual_name;
26456   CharPtr           related_qual_name;
26457   CharPtr           related_qual_val;
26458   CharPtr PNTR      mod_names;
26459   CharPtr PNTR      examples;
26460   Int4              num_mods;
26461 } WizardRelatedQualsFormData, PNTR WizardRelatedQualsFormPtr;
26462 
26463 
CleanupRelatedQuals(GraphiC g,Pointer data)26464 static void CleanupRelatedQuals (GraphiC g, Pointer data)
26465 {
26466   WizardRelatedQualsFormPtr frm;
26467   Int4 i;
26468 
26469   if (data != NULL)
26470   {
26471     frm = (WizardRelatedQualsFormPtr) data;
26472     for (i = 0; i < frm->num_mods; i++) {
26473       MemFree (frm->mod_names[i]);
26474       MemFree (frm->examples[i]);
26475     }
26476     frm->mod_names = MemFree (frm->mod_names);
26477     frm->examples = MemFree (frm->examples);
26478     frm->ed_grps = MemFree (frm->ed_grps);
26479     frm->apply_all_txt = MemFree (frm->apply_all_txt);
26480     frm->bulk_btns = MemFree (frm->bulk_btns);
26481   }
26482   CleanupWizardForm (g, data);
26483 }
26484 
26485 
ApplyAllValueToRelatedQuals(ButtoN b)26486 static void ApplyAllValueToRelatedQuals (ButtoN b)
26487 {
26488   WizardRelatedQualsFormPtr frm;
26489   TagListPtr tlp;
26490   Int4 i, num_existing = 0;
26491   ValNodePtr vnp;
26492   CharPtr  set_val, old_val, new_line;
26493 
26494   frm = (WizardRelatedQualsFormPtr) GetObjectExtra (b);
26495   if (frm == NULL) {
26496     return;
26497   }
26498   tlp = (TagListPtr) GetObjectExtra (frm->qual_table);
26499   if (tlp == NULL) {
26500     return;
26501   }
26502 
26503   for (i = 0; i < frm->num_mods; i++) {
26504     if (frm->bulk_btns[i] == b) {
26505       break;
26506     }
26507   }
26508 
26509   if (i < frm->num_mods) {
26510     for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
26511       old_val = ExtractTagListColumn (vnp->data.ptrvalue, i + 1);
26512       if (!StringHasNoText (old_val)) {
26513         num_existing++;
26514       }
26515       old_val = MemFree (old_val);
26516     }
26517     if (num_existing > 0 && ANS_CANCEL == Message (MSG_OKC, "Replace %d existing values?", num_existing)) {
26518       return;
26519     }
26520     set_val = SaveStringFromText (frm->apply_all_txt[i]);
26521     for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
26522       new_line = ReplaceTagListColumn (vnp->data.ptrvalue, set_val, i + 1);
26523       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
26524       vnp->data.ptrvalue = new_line;
26525     }
26526     SendMessageToDialog (frm->qual_table, VIB_MSG_REDRAW);
26527   }
26528 }
26529 
26530 
MakeRelatedQualHeaders(GrouP g,WizardRelatedQualsFormPtr frm)26531 static void MakeRelatedQualHeaders (GrouP g, WizardRelatedQualsFormPtr frm)
26532 {
26533   Int4 i;
26534   Int4 grp_len = 5;
26535 
26536   frm->ed_grps = (GrouP PNTR) MemNew (sizeof (GrouP) * frm->num_mods);
26537   frm->apply_all_txt = (TexT PNTR) MemNew (sizeof (TexT) * frm->num_mods);
26538   frm->bulk_btns = (ButtoN PNTR) MemNew (sizeof (ButtoN) * frm->num_mods);
26539 
26540   for (i = 0; i < frm->num_mods; i++) {
26541     frm->ed_grps[i] = HiddenGroup (g, 0, grp_len, NULL);
26542     SetGroupSpacing (frm->ed_grps[i], 10, 10);
26543     StaticPrompt (frm->ed_grps[i], "Set", 0, 0, programFont, 'c');
26544     StaticPrompt (frm->ed_grps[i], frm->mod_names[i], 0, 0, programFont, 'c');
26545     StaticPrompt (frm->ed_grps[i], "for All", 0, 0, programFont, 'c');
26546     frm->apply_all_txt[i] = DialogText (frm->ed_grps[i], "", 8, NULL);
26547     frm->bulk_btns[i] = PushButton (frm->ed_grps[i], "Apply", ApplyAllValueToRelatedQuals);
26548     SetObjectExtra (frm->bulk_btns[i], frm, NULL);
26549   }
26550 }
26551 
26552 
GetTableForRelatedQuals(SeqEntryPtr sequences,CharPtr related_qual_name,CharPtr related_qual_val,CharPtr new_qual_name)26553 static ValNodePtr GetTableForRelatedQuals (SeqEntryPtr sequences, CharPtr related_qual_name, CharPtr related_qual_val, CharPtr new_qual_name)
26554 {
26555   IDAndTitleEditPtr iatep;
26556   ValNodePtr        table = NULL;
26557   Int4              i;
26558   CharPtr           val, val2, line;
26559 
26560   iatep = SeqEntryListToIDAndTitleEditEx (sequences, TRUE);
26561   for (i = 0; i < iatep->num_sequences; i++) {
26562     val = FindValueFromPairInDefline (related_qual_name, iatep->title_list[i]);
26563     if (StringICmp (val, related_qual_val) == 0 || (StringHasNoText (val) && StringHasNoText (related_qual_val))) {
26564       val2 = FindValueFromPairInDefline (new_qual_name, iatep->title_list[i]);
26565       line = (CharPtr) MemNew (sizeof (Char) * (StringLen (iatep->id_list[i]) + StringLen (val2) + 5));
26566       sprintf (line, "%s\t%s\t\t\n", iatep->id_list[i], val2 == NULL ? "" : val2);
26567       ValNodeAddPointer (&table, 0, line);
26568       val2 = MemFree (val2);
26569     }
26570     val = MemFree (val);
26571   }
26572 
26573   iatep = IDAndTitleEditFree (iatep);
26574   return table;
26575 }
26576 
26577 
SaveRelatedQuals(Pointer data,WizardTrackerPtr wiz)26578 static void SaveRelatedQuals (Pointer data, WizardTrackerPtr wiz)
26579 {
26580   WizardRelatedQualsFormPtr frm;
26581   TagListPtr tlp;
26582   IDAndTitleEditPtr iatep;
26583   ValNodePtr vnp;
26584   CharPtr id, val;
26585   Int4    i;
26586 
26587   frm = (WizardRelatedQualsFormPtr) data;
26588   if (frm == NULL || wiz == NULL) {
26589     return;
26590   }
26591 
26592   tlp = (TagListPtr) GetObjectExtra (frm->qual_table);
26593   if (tlp == NULL) {
26594     return;
26595   }
26596   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
26597   vnp = tlp->vnp;
26598   i = 0;
26599   while (vnp != NULL && i < iatep->num_sequences) {
26600     id = ExtractTagListColumn (vnp->data.ptrvalue, 0);
26601     while (StringCmp (id, iatep->id_list[i]) != 0 && i < iatep->num_sequences) {
26602       i++;
26603     }
26604     id = MemFree (id);
26605     if (i < iatep->num_sequences) {
26606       val = ExtractTagListColumn (vnp->data.ptrvalue, 1);
26607       if (StringHasNoText (val)) {
26608         RemoveValueFromDefline (frm->new_qual_name, iatep->title_list[i]);
26609       } else {
26610         iatep->title_list[i] = ReplaceValueInOneDefLine (iatep->title_list[i], frm->new_qual_name, val);
26611       }
26612       val = MemFree (val);
26613     }
26614     vnp = vnp->next;
26615   }
26616   ApplyIDAndTitleEditToSeqEntryList (wiz->sequences, iatep);
26617   iatep = IDAndTitleEditFree (iatep);
26618 }
26619 
26620 
SetRelatedQualForLocation(WizardTrackerPtr wiz,CharPtr related_qual_name,CharPtr related_qual_val,CharPtr new_qual_name,SequencesOkFunc ok_func,CreateFormFunc next_form)26621 static Boolean SetRelatedQualForLocation (WizardTrackerPtr wiz, CharPtr related_qual_name, CharPtr related_qual_val, CharPtr new_qual_name, SequencesOkFunc ok_func, CreateFormFunc next_form)
26622 {
26623   WizardRelatedQualsFormPtr frm;
26624   WindoW w;
26625   GrouP  h;
26626   GrouP  c;
26627   CharPtr dlg_title = "X";
26628   GrouP PNTR grp_list;
26629   TagListPtr tlp;
26630   Int4       i, num_seq;
26631   ValNodePtr tbl_data;
26632 
26633   tbl_data = GetTableForRelatedQuals (wiz->sequences, related_qual_name, related_qual_val, new_qual_name);
26634   if (tbl_data == NULL) {
26635     return FALSE;
26636   }
26637 
26638   frm = (WizardRelatedQualsFormPtr) MemNew (sizeof (WizardRelatedQualsFormData));
26639   frm->wiz = wiz;
26640   frm->collect_func = SaveRelatedQuals;
26641   frm->fwd_ok_func = ok_func;
26642   frm->next_form = next_form;
26643   frm->num_mods = 1;
26644   frm->related_qual_name = StringSave (related_qual_name);
26645   frm->related_qual_val = StringSave (related_qual_val);
26646   frm->new_qual_name = StringSave (new_qual_name);
26647   frm->mod_names = (CharPtr PNTR) MemNew (sizeof (CharPtr) * frm->num_mods);
26648   frm->mod_names[0] = StringSave (frm->new_qual_name);
26649   frm->examples = (CharPtr PNTR) MemNew (sizeof (CharPtr) * frm->num_mods);
26650   frm->examples[0] = GetDefaultExample(frm->new_qual_name);
26651 
26652   SendHelpScrollMessage (helpForm, dlg_title, "");
26653 
26654   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
26655   SetObjectExtra (w, frm, CleanupRelatedQuals);
26656   frm->form = (ForM) w;
26657 
26658   h = HiddenGroup (w, -1, -1, NULL);
26659   SetGroupSpacing (h, 10, 10);
26660 
26661   MakeRelatedQualHeaders (h, frm);
26662   grp_list = (GrouP PNTR) MemNew (sizeof (GrouP) * (frm->num_mods + 2));
26663 
26664   num_seq = ValNodeLen (tbl_data);
26665   frm->qual_table = AddMultiModifierTableEditor (h, frm->mod_names, frm->examples, frm->num_mods, num_seq, grp_list);
26666 
26667   tlp = GetObjectExtra (frm->qual_table);
26668   tlp->vnp = tbl_data;
26669   tlp->max = MAX ((Int2) 0, (Int2) (num_seq - tlp->rows));
26670   CorrectBarMax (tlp->bar, tlp->max);
26671   CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
26672 
26673   AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[0], (HANDLE) tlp->control[0], NULL);
26674   for (i = 0; i < frm->num_mods; i++) {
26675     AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[i + 1], (HANDLE) tlp->control[i + 1], (HANDLE) frm->ed_grps[i], NULL);
26676   }
26677   /* align problems */
26678   AlignObjects (ALIGN_JUSTIFY, (HANDLE) grp_list[i + 1], (HANDLE) tlp->control[i + 1], NULL);
26679   grp_list = MemFree (grp_list);
26680 
26681   c = MakeWizardNav (h, frm);
26682 
26683   AlignObjects (ALIGN_CENTER, (HANDLE) frm->qual_table,
26684                               (HANDLE) c,
26685                               NULL);
26686 
26687   Update();
26688   Show (w);
26689   SendMessageToDialog (frm->qual_table, VIB_MSG_REDRAW);
26690   return TRUE;
26691 }
26692 
26693 
SetPlasmidNames(WizardTrackerPtr wiz)26694 static Boolean SetPlasmidNames (WizardTrackerPtr wiz)
26695 {
26696   return SetRelatedQualForLocation (wiz, "location", "plasmid", "plasmid-name", OkToContinueToSequin, FinishWizardAndLaunchSequin);
26697 }
26698 
26699 
GetChromosomeNumbers(WizardTrackerPtr wiz)26700 static Boolean GetChromosomeNumbers (WizardTrackerPtr wiz)
26701 {
26702   return SetRelatedQualForLocation (wiz, "location", "", "chromosome", OkToContinueToSequin, FinishWizardAndLaunchSequin);
26703 }
26704 
26705 
26706 static WizardChoiceData ask_chromosome_choice_list[] = {
26707   { "Yes", NULL, GetChromosomeNumbers } ,
26708   { "No", OkToContinueToSequin, FinishWizardAndLaunchSequin },
26709   { NULL, NULL, NULL }
26710 };
26711 
26712 
AskAboutChromosomes(WizardTrackerPtr wiz)26713 static Boolean AskAboutChromosomes (WizardTrackerPtr wiz)
26714 {
26715   Boolean           pick_chromosomes = FALSE;
26716   IDAndTitleEditPtr iatep;
26717 
26718   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
26719   if (DoAnySequencesHaveModifier(iatep, "chromosome")) {
26720     pick_chromosomes = TRUE;
26721   }
26722   iatep = IDAndTitleEditFree (iatep);
26723   if (pick_chromosomes) {
26724     return GetChromosomeNumbers (wiz);
26725   } else {
26726     return CreateWizardSingleChoiceForm (wiz, ask_chromosome_choice_list,
26727                                          "Sequence Location", "Do you want to provide chromosome number(s) for your sequences?");
26728   }
26729 }
26730 
26731 
26732 typedef struct virusmolinfoform {
26733   WIZARD_BLOCK
26734 
26735   PopuP mol_type;
26736   PopuP topology;
26737 } VirusMolInfoFormData, PNTR VirusMolInfoFormPtr;
26738 
26739 
SaveWizardMolInfo(Pointer data,WizardTrackerPtr wiz)26740 static void SaveWizardMolInfo (Pointer data, WizardTrackerPtr wiz)
26741 {
26742   VirusMolInfoFormPtr frm;
26743   Int2 val;
26744 
26745   frm = (VirusMolInfoFormPtr) data;
26746   if (frm == NULL || wiz == NULL) {
26747     return;
26748   }
26749 
26750   if (wiz->wizard_type == eWizardType_Viruses) {
26751     frm->next_form = CreateVirusAnnotationForm;
26752   } else {
26753     frm->next_form = CreateWizardAnnotationChoiceForm;
26754   }
26755   wiz->molinfo = MolInfoFree (wiz->molinfo);
26756   wiz->molinfo = MolInfoNew ();
26757   val = GetValue (frm->mol_type);
26758   switch (val) {
26759     case 1:
26760       wiz->molinfo->biomol = MOLECULE_TYPE_GENOMIC;
26761       wiz->mol_class = Seq_mol_dna;
26762       break;
26763     case 2:
26764       if (wiz->wizard_type == eWizardType_Viruses) {
26765         wiz->molinfo->biomol = MOLECULE_TYPE_GENOMIC;
26766         wiz->mol_class = Seq_mol_rna;
26767       } else {
26768         wiz->molinfo->biomol = MOLECULE_TYPE_MRNA;
26769         wiz->mol_class = Seq_mol_rna;
26770       }
26771       break;
26772     case 4:
26773       wiz->molinfo->biomol = MOLECULE_TYPE_MRNA;
26774       wiz->mol_class = Seq_mol_rna;
26775       frm->next_form = CreateWizardMolInfoExtraForm;
26776       break;
26777     case 3:
26778       wiz->molinfo->biomol = MOLECULE_TYPE_CRNA;
26779       wiz->mol_class = Seq_mol_rna;
26780       break;
26781     default:
26782       wiz->molinfo = MolInfoFree (wiz->molinfo);
26783       wiz->mol_class = Seq_mol_dna;
26784       break;
26785   }
26786 
26787   if (wiz->molinfo != NULL && frm->topology != NULL) {
26788     val = GetValue (frm->topology);
26789     if (val == 2) {
26790       wiz->topology = TOPOLOGY_CIRCULAR;
26791     } else {
26792       wiz->topology = TOPOLOGY_LINEAR;
26793     }
26794   }
26795 }
26796 
26797 
WizardMolInfoOk(WizardTrackerPtr wiz)26798 static Boolean WizardMolInfoOk (WizardTrackerPtr wiz)
26799 {
26800   if (wiz == NULL) {
26801     return FALSE;
26802   }
26803 
26804   if (wiz->molinfo == NULL) {
26805     Message (MSG_ERROR, "Need to specify molecule type!");
26806     return FALSE;
26807   } else {
26808     return TRUE;
26809   }
26810 }
26811 
26812 
CreateWizardMolInfoForm(WizardTrackerPtr wiz)26813 static Boolean CreateWizardMolInfoForm (WizardTrackerPtr wiz)
26814 {
26815   VirusMolInfoFormPtr frm;
26816   WindoW w;
26817   GrouP  h;
26818   GrouP  c;
26819   PrompT ppt;
26820   CharPtr dlg_title;
26821 
26822   frm = (VirusMolInfoFormPtr) MemNew (sizeof (VirusMolInfoFormData));
26823   frm->wiz = wiz;
26824   frm->collect_func = SaveWizardMolInfo;
26825   frm->fwd_ok_func = WizardMolInfoOk;
26826   frm->next_form = CreateVirusAnnotationForm;
26827 
26828   wiz->molinfo_comment = MemFree (wiz->molinfo_comment);
26829 
26830   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Molecule);
26831   SendHelpScrollMessage (helpForm, dlg_title, "");
26832 
26833   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
26834   SetObjectExtra (w, frm, CleanupWizardForm);
26835   frm->form = (ForM) w;
26836 
26837   h = HiddenGroup (w, -1, -1, NULL);
26838   SetGroupSpacing (h, 10, 10);
26839 
26840   ppt = StaticPrompt (h, "What molecule type was isolated?", 0, 0, programFont, 'c');
26841   frm->mol_type = PopupList (h, TRUE, NULL);
26842   PopupItem (frm->mol_type, "genomic DNA");
26843   if (wiz->wizard_type == eWizardType_Viruses) {
26844     PopupItem (frm->mol_type, "genomic RNA");
26845     PopupItem (frm->mol_type, "cRNA");
26846     PopupItem (frm->mol_type, "mRNA");
26847   } else {
26848     PopupItem (frm->mol_type, "mRNA (cDNA)");
26849   }
26850 
26851   if (wiz->wizard_type == eWizardType_Viruses
26852       || wiz->cultured_kingdom == eCulturedKingdom_BacteriaArchea) {
26853     frm->topology = PopupList (h, TRUE, NULL);
26854     PopupItem (frm->topology, "Linear");
26855     PopupItem (frm->topology, "Circular");
26856     SetValue (frm->topology, 1);
26857   }
26858 
26859   c = MakeWizardNav (h, frm);
26860 
26861   AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
26862                               (HANDLE) frm->mol_type,
26863                               (HANDLE) frm->topology,
26864                               (HANDLE) c,
26865                               NULL);
26866 
26867   Update();
26868   Show (w);
26869 
26870   return TRUE;
26871 }
26872 
26873 
26874 typedef struct virusmolinfoextraform {
26875   WIZARD_BLOCK
26876   GrouP cDNA_type;
26877   GrouP source_mat;
26878 } VirusMolInfoExtraFormData, PNTR VirusMolInfoExtraFormPtr;
26879 
26880 
26881 static CharPtr k_cDNA_type_choices [] = {
26882   "cDNA derived from mRNA",
26883   "cDNA derived from genomic RNA"};
26884 static const Int4 k_num_cDNA_type_choices = sizeof (k_cDNA_type_choices) / sizeof (CharPtr);
26885 
26886 static CharPtr k_source_mat_choices[] = {
26887   "purified viral particles",
26888   "whole cell/tissue lysate"};
26889 static const Int4 k_num_source_mat_choices = sizeof (k_source_mat_choices) / sizeof (CharPtr);
26890 
SaveWizardMolInfoExtra(Pointer data,WizardTrackerPtr wiz)26891 static void SaveWizardMolInfoExtra (Pointer data, WizardTrackerPtr wiz)
26892 {
26893   VirusMolInfoExtraFormPtr frm;
26894   Int2 val1, val2;
26895   CharPtr fmt = "[%s, %s]";
26896 
26897   frm = (VirusMolInfoExtraFormPtr) data;
26898   if (frm == NULL || wiz == NULL) {
26899     return;
26900   }
26901 
26902   wiz->molinfo_comment = MemFree (wiz->molinfo_comment);
26903 
26904   val1 = GetValue (frm->cDNA_type);
26905   val2 = GetValue (frm->source_mat);
26906   if (val1 > 0 && val1 <= k_num_cDNA_type_choices && val2 > 0 && val2 <= k_num_source_mat_choices) {
26907     wiz->molinfo_comment = (CharPtr) MemNew (sizeof (Char) * (StringLen (k_cDNA_type_choices[val1 - 1]) + StringLen (k_source_mat_choices[val2 - 1]) + StringLen (fmt)));
26908     sprintf (wiz->molinfo_comment, fmt, k_cDNA_type_choices[val1 - 1], k_source_mat_choices[val2 - 1]);
26909   }
26910 }
26911 
26912 
WizardMolInfoExtraOk(WizardTrackerPtr wiz)26913 static Boolean WizardMolInfoExtraOk (WizardTrackerPtr wiz)
26914 {
26915   if (wiz == NULL) {
26916     return FALSE;
26917   }
26918 
26919   if (wiz->molinfo_comment == NULL) {
26920     Message (MSG_ERROR, "Need to specify cDNA type and source material!");
26921     return FALSE;
26922   } else {
26923     return TRUE;
26924   }
26925 }
26926 
26927 
CreateWizardMolInfoExtraForm(WizardTrackerPtr wiz)26928 static Boolean CreateWizardMolInfoExtraForm (WizardTrackerPtr wiz)
26929 {
26930   VirusMolInfoExtraFormPtr frm;
26931   WindoW w;
26932   GrouP  h;
26933   GrouP  c;
26934   Int4   i;
26935   CharPtr dlg_title;
26936 
26937   frm = (VirusMolInfoExtraFormPtr) MemNew (sizeof (VirusMolInfoExtraFormData));
26938   frm->wiz = wiz;
26939   frm->collect_func = SaveWizardMolInfoExtra;
26940   frm->fwd_ok_func = WizardMolInfoExtraOk;
26941   frm->next_form = CreateVirusAnnotationForm;
26942 
26943   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Molecule);
26944   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
26945   SetObjectExtra (w, frm, CleanupWizardForm);
26946   frm->form = (ForM) w;
26947 
26948   h = HiddenGroup (w, -1, -1, NULL);
26949   SetGroupSpacing (h, 10, 10);
26950 
26951   frm->cDNA_type = NormalGroup (h, 0, 2, "What does this sequence represent?", programFont, NULL);
26952   for (i = 0; i < k_num_cDNA_type_choices; i++) {
26953     RadioButton (frm->cDNA_type, k_cDNA_type_choices[i]);
26954   }
26955 
26956   frm->source_mat = NormalGroup (h, 0, 2, "What is the source material for the virus?", programFont, NULL);
26957   for (i = 0; i < k_num_source_mat_choices; i++) {
26958     RadioButton (frm->source_mat, k_source_mat_choices[i]);
26959   }
26960 
26961   c = MakeWizardNav (h, frm);
26962 
26963   AlignObjects (ALIGN_CENTER, (HANDLE) frm->cDNA_type,
26964                               (HANDLE) frm->source_mat,
26965                               (HANDLE) c,
26966                               NULL);
26967 
26968   Update();
26969   Show (w);
26970 
26971   return TRUE;
26972 }
26973 
26974 
26975 typedef struct virusnoncodingform {
26976   WIZARD_BLOCK
26977 
26978   GrouP feature_type;
26979   GrouP partial;
26980   TexT  misc_feat_comment;
26981   ButtoN partial5;
26982   ButtoN partial3;
26983 } VirusNoncodingFormData, PNTR VirusNoncodingFormPtr;
26984 
26985 
SaveVirusNoncodingChoice(Pointer data,WizardTrackerPtr wiz)26986 static void SaveVirusNoncodingChoice (Pointer data, WizardTrackerPtr wiz)
26987 {
26988   VirusNoncodingFormPtr frm;
26989   Int2 val;
26990 
26991   frm = (VirusNoncodingFormPtr) data;
26992   if (frm == NULL) {
26993     return;
26994   }
26995 
26996   val = GetValue (frm->feature_type);
26997   switch (val) {
26998     case 1:
26999       wiz->partial5 = GetStatus (frm->partial5);
27000       wiz->partial3 = GetStatus (frm->partial3);
27001       wiz->virus_feat = eVirusFeat_LTR;
27002       break;
27003     case 2:
27004       wiz->partial5 = GetStatus (frm->partial5);
27005       wiz->partial3 = GetStatus (frm->partial3);
27006       wiz->virus_feat = eVirusFeat_UTR5;
27007       break;
27008     case 3:
27009       wiz->partial5 = GetStatus (frm->partial5);
27010       wiz->partial3 = GetStatus (frm->partial3);
27011       wiz->virus_feat = eVirusFeat_UTR3;
27012       break;
27013     case 4:
27014       wiz->virus_feat = eVirusFeat_viroid_complete;
27015       break;
27016     case 5:
27017       wiz->virus_feat = eVirusFeat_viroid_partial;
27018       break;
27019     case 6:
27020       wiz->virus_feat = eVirusFeat_misc_feature;
27021       wiz->misc_feat_comment = SaveStringFromText (frm->misc_feat_comment);
27022       break;
27023     default:
27024       break;
27025   }
27026 }
27027 
27028 
ChangeVirusNoncodingForm(GrouP g)27029 static void ChangeVirusNoncodingForm (GrouP g)
27030 {
27031   VirusNoncodingFormPtr frm;
27032   Int2 val;
27033 
27034   frm = (VirusNoncodingFormPtr) GetObjectExtra (g);
27035   if (frm == NULL) {
27036     return;
27037   }
27038 
27039   val = GetValue (frm->feature_type);
27040   if (val == 1 || val == 2 || val == 3) {
27041     Show (frm->partial);
27042   } else {
27043     Hide (frm->partial);
27044   }
27045   if (val == 6) {
27046     Show (frm->misc_feat_comment);
27047   } else {
27048     Hide (frm->misc_feat_comment);
27049   }
27050 }
27051 
27052 
CreateVirusNoncodingForm(WizardTrackerPtr wiz)27053 static Boolean CreateVirusNoncodingForm (WizardTrackerPtr wiz)
27054 {
27055   VirusNoncodingFormPtr frm;
27056   WindoW w;
27057   GrouP  h;
27058   GrouP  c;
27059   PrompT  ppt;
27060   CharPtr dlg_title;
27061 
27062   frm = (VirusNoncodingFormPtr) MemNew (sizeof (VirusNoncodingFormData));
27063   frm->wiz = wiz;
27064   frm->collect_func = SaveVirusNoncodingChoice;
27065   frm->fwd_ok_func = OkToContinueToSequin;
27066   frm->next_form = FinishWizardAndLaunchSequin;
27067 
27068   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
27069   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
27070   SetObjectExtra (w, frm, CleanupWizardForm);
27071   frm->form = (ForM) w;
27072 
27073   h = HiddenGroup (w, -1, -1, NULL);
27074   SetGroupSpacing (h, 10, 10);
27075 
27076   ppt = StaticPrompt (h, "What do your sequences contain?", 0, 0, programFont, 'c');
27077 
27078   frm->feature_type = HiddenGroup (h, 0, 6, ChangeVirusNoncodingForm);
27079   SetObjectExtra (frm->feature_type, frm, NULL);
27080   RadioButton (frm->feature_type, "Only contains Long Terminal Repeat (LTR)");
27081   RadioButton (frm->feature_type, "Only contains 5' Untranslated Region (UTR)");
27082   RadioButton (frm->feature_type, "Only contains 3' Untranslated Region (UTR)");
27083   RadioButton (frm->feature_type, "Viroid complete genome");
27084   RadioButton (frm->feature_type, "Viroid partial genome");
27085   RadioButton (frm->feature_type, "Something else");
27086 
27087   frm->misc_feat_comment = DialogText (h, "", 10, NULL);
27088   Hide (frm->misc_feat_comment);
27089 
27090   frm->partial = HiddenGroup (h, 0, 2, NULL);
27091   frm->partial5 = CheckBox (frm->partial, "Feature is 5' partial", NULL);
27092   frm->partial3 = CheckBox (frm->partial, "Feature is 3' partial", NULL);
27093   Hide (frm->partial);
27094 
27095   c = MakeWizardNav (h, frm);
27096 
27097   AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
27098                               (HANDLE) frm->feature_type,
27099                               (HANDLE) frm->misc_feat_comment,
27100                               (HANDLE) frm->partial,
27101                               (HANDLE) c,
27102                               NULL);
27103 
27104   Update();
27105   Show (w);
27106   SendHelpScrollMessage (helpForm, dlg_title, "");
27107 
27108   return TRUE;
27109 }
27110 
27111 
27112 typedef struct virusfeaturetableform {
27113   WIZARD_BLOCK
27114   DoC doc;
27115   ButtoN clear_btn;
27116 } VirusFeatureTableFormData, PNTR VirusFeatureTableFormPtr;
27117 
27118 
27119 static CharPtr s_VirusFeatureAnnotationHelp[] = {
27120 "For Influenza A and B submissions, use the Influenza Virus Resource Annotation\n\
27121 webtool to create a feature table:",
27122 "http://www.ncbi.nlm.nih.gov/genomes/FLU/Database/annotation.cgi",
27123 "\n\
27124 Directions:\n\
27125 1) Follow the directions in the webtool (paste/upload sequences & click annotate FASTA)\n\
27126 2) Copy & Save the feature table output from the webtool in a plain text file\n\
27127 or\n\
27128 In the webtool, select Display Feature Table File & Save\n\
27129 3) Click Upload Feature Table button below (in this window)\n\
27130 Select the file with your feature table",
27131       NULL};
27132 
SummarizeVirusFeatures(DoC d)27133 static void SummarizeVirusFeatures (DoC d)
27134 {
27135   WizardTrackerPtr wiz;
27136   Int4 feature_count = 0;
27137   Int4Ptr count_list;
27138   BoolPtr has_cds_list;
27139   IDAndTitleEditPtr iatep;
27140   Int4         pos, num;
27141   ValNodePtr   vnp;
27142   SeqAnnotPtr  sap;
27143   SeqFeatPtr   sfp;
27144   CharPtr      all_fmt = "Annotation contains %d features, which were added to %d out of %d sequences\n";
27145   CharPtr      has_cds_fmt = "%d out of %d sequences have coding regions\n";
27146   CharPtr      seq_fmt = "%s has %d features\n";
27147   CharPtr      without_cds_fmt = "Sequences without coding region annotation: ";
27148   CharPtr      without_any_fmt = "Sequences without any feature annotation: ";
27149   CharPtr      msg;
27150   Int4         no_cds_len = 0, none_len = 0;
27151   Int4         i;
27152 
27153   Reset (d);
27154   wiz = (WizardTrackerPtr) GetObjectExtra (d);
27155   if (wiz == NULL || wiz->annot_list == NULL) {
27156     for (i = 0; s_VirusFeatureAnnotationHelp[i] != NULL; i++) {
27157       AppendText (d, s_VirusFeatureAnnotationHelp[i], NULL, NULL, programFont);
27158     }
27159   } else {
27160     iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
27161     count_list = (Int4Ptr) MemNew (sizeof (Int4) * iatep->num_sequences);
27162     MemSet (count_list, 0, sizeof (Int4) * iatep->num_sequences);
27163     has_cds_list = (BoolPtr) MemNew (sizeof (Boolean) * iatep->num_sequences);
27164     MemSet (has_cds_list, 0, sizeof (Boolean) * iatep->num_sequences);
27165     for (vnp = wiz->annot_list; vnp != NULL; vnp = vnp->next) {
27166       sap = vnp->data.ptrvalue;
27167       if (sap->type == 1) {
27168         sfp = (SeqFeatPtr) sap->data;
27169         if (sfp != NULL) {
27170           /* find the sequence this annot refers to */
27171           pos = FindIdInIdAndTitleEdit (SeqLocId(sfp->location), iatep);
27172           while (sfp != NULL) {
27173             feature_count++;
27174             if (pos > -1) {
27175               count_list[pos]++;
27176               if (sfp->data.choice == SEQFEAT_CDREGION) {
27177                 has_cds_list[pos] = TRUE;
27178               }
27179             }
27180             sfp = sfp->next;
27181           }
27182         }
27183       }
27184     }
27185     msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (all_fmt) + 45));
27186     num = 0;
27187     for (pos = 0; pos < iatep->num_sequences; pos++) {
27188       if (count_list[pos] > 0) {
27189         num++;
27190       } else {
27191         none_len += StringLen (iatep->id_list[pos]) + 2;
27192       }
27193     }
27194     sprintf (msg, all_fmt, feature_count, num, iatep->num_sequences);
27195     AppendText (d, msg, NULL, NULL, programFont);
27196     msg = MemFree (msg);
27197     msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (has_cds_fmt) + 30));
27198     num = 0;
27199     for (pos = 0; pos < iatep->num_sequences; pos++) {
27200       if (has_cds_list[pos]) {
27201         num++;
27202       } else {
27203         no_cds_len += StringLen (iatep->id_list[pos]) + 2;
27204       }
27205     }
27206     sprintf (msg, has_cds_fmt, num, iatep->num_sequences);
27207     AppendText (d, msg, NULL, NULL, programFont);
27208     msg = MemFree (msg);
27209 
27210     // print sequences without coding regions
27211     if (no_cds_len > 0) {
27212       msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (without_cds_fmt) + no_cds_len + 2));
27213       StringCpy (msg, without_cds_fmt);
27214       for (pos = 0; pos < iatep->num_sequences; pos++) {
27215         if (!has_cds_list[pos]) {
27216           StringCat (msg, iatep->id_list[pos]);
27217           StringCat (msg, ", ");
27218         }
27219       }
27220       msg[StringLen (msg) - 2] = 0;
27221       AppendText (d, msg, NULL, NULL, programFont);
27222       msg = MemFree (msg);
27223     }
27224 
27225     // print sequences without any features
27226     if (none_len > 0) {
27227       msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (without_any_fmt) + none_len + 2));
27228       StringCpy (msg, without_any_fmt);
27229       for (pos = 0; pos < iatep->num_sequences; pos++) {
27230         if (count_list[pos] == 0) {
27231           StringCat (msg, iatep->id_list[pos]);
27232           StringCat (msg, ", ");
27233         }
27234       }
27235       msg[StringLen (msg) - 2] = 0;
27236       AppendText (d, msg, NULL, NULL, programFont);
27237       msg = MemFree (msg);
27238     }
27239 
27240     for (pos = 0; pos < iatep->num_sequences; pos++) {
27241       msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (seq_fmt) + 15 + StringLen (iatep->id_list[pos])));
27242       sprintf (msg, seq_fmt, iatep->id_list[pos], count_list[pos]);
27243       AppendText (d, msg, NULL, NULL, programFont);
27244       msg = MemFree (msg);
27245     }
27246     iatep = IDAndTitleEditFree (iatep);
27247   }
27248   UpdateDocument (d, 0, 0);
27249 }
27250 
27251 
UploadVirusFeatureTable(ButtoN b)27252 static void UploadVirusFeatureTable (ButtoN b)
27253 {
27254   VirusFeatureTableFormPtr frm;
27255   Char path[PATH_MAX];
27256   FILE * fp;
27257   Pointer        dataptr;
27258   Uint2          datatype;
27259   ValNodePtr     last = NULL, vnp;
27260   Boolean        failure = FALSE;
27261   Int4           linenum = 1, last_linenum = 1;
27262   SeqAnnotPtr    sap;
27263   BioseqPtr      bsp;
27264   SeqEntryPtr    orig_scope;
27265 
27266   frm = (VirusFeatureTableFormPtr) GetObjectExtra (b);
27267   if (frm == NULL) {
27268     return;
27269   }
27270   path[0] = 0;
27271   if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return;
27272 
27273   if (frm->wiz->annot_list != NULL) {
27274     if (ANS_YES == Message (MSG_YNC, "You already have a feature table - do you want to replace it (YES) or add features to it (NO)?")) {
27275       frm->wiz->annot_list = FreeAnnotList(frm->wiz->annot_list);
27276     }
27277   }
27278 
27279   fp = FileOpen (path, "r");
27280   if (fp == NULL) {
27281     Message (MSG_ERROR, "Unable to open file %s", path);
27282     return;
27283   }
27284   last = frm->wiz->annot_list;
27285   if (last != NULL) {
27286     while (last->next != NULL) {
27287       last = last->next;
27288     }
27289   }
27290 
27291   if (frm->input_entityID == 0) {
27292     frm->input_entityID = ObjMgrGetEntityIDForChoice (frm->wiz->sequences);
27293     AssignIDsInEntity (frm->input_entityID, 0, NULL);
27294   }
27295   orig_scope = SeqEntrySetScope (NULL);
27296 
27297   while ((! failure) && (dataptr = ReadFeatureTableFile (fp, &datatype, NULL, &linenum, &failure, TRUE)) != NULL) {
27298     if (datatype == OBJ_SEQANNOT) {
27299 
27300       sap = (SeqAnnotPtr) dataptr;
27301       bsp = GetBioseqReferencedByAnnot (sap, frm->input_entityID);
27302       if (bsp == NULL) {
27303         Message (MSG_POSTERR, "Unable to find matching sequence for feature table starting at line %d", last_linenum);
27304         ObjMgrFree (datatype, dataptr);
27305       } else {
27306         vnp = ValNodeAddPointer (&last, datatype, dataptr);
27307         if (frm->wiz->annot_list == NULL) {
27308           frm->wiz->annot_list = vnp;
27309         }
27310         last = vnp;
27311       }
27312     } else {
27313       Message (MSG_POSTERR, "File contains data other than feature tables, starting at line %d", linenum);
27314       ObjMgrFree (datatype, dataptr);
27315     }
27316     last_linenum = linenum;
27317   }
27318   FileClose (fp);
27319 
27320   /* TODO: verify results, change path forward to indicate we have features */
27321   SummarizeVirusFeatures(frm->doc);
27322   if (frm->wiz->annot_list == NULL) {
27323     Disable (frm->clear_btn);
27324   } else {
27325     Enable (frm->clear_btn);
27326   }
27327   SeqEntrySetScope (orig_scope);
27328 }
27329 
27330 
27331 static const CharPtr s_VirusNoAnnotLeavingMsg = "\
27332 We will request that you resubmit with annotation if you do not provide feature annotation with your submission.\n\n\
27333 Please provide feature annotation.";
27334 
27335 static const CharPtr s_VirusWithAnnotLeavingMsg = "\
27336 You will now be transferred to the record viewer.\n\
27337 Once you have opened the record viewer, you cannot return to the wizard.\n\
27338 Click Cancel to continue editing your information in the wizard.";
27339 
VirusFeatureTableOkToContinueToSequin(WizardTrackerPtr wiz)27340 static Boolean VirusFeatureTableOkToContinueToSequin(WizardTrackerPtr wiz)
27341 {
27342   if (wiz == NULL) {
27343     return FALSE;
27344   }
27345   if (wiz->annot_list == NULL) {
27346     return OkToContinueToSequinWithMessage (wiz, s_VirusNoAnnotLeavingMsg);
27347   } else {
27348     return OkToContinueToSequinWithMessage (wiz, s_VirusWithAnnotLeavingMsg);
27349   }
27350 }
27351 
27352 
ClearVirusFeatureTable(ButtoN b)27353 static void ClearVirusFeatureTable (ButtoN b)
27354 {
27355   VirusFeatureTableFormPtr frm;
27356 
27357   frm = (VirusFeatureTableFormPtr) GetObjectExtra (b);
27358   if (frm == NULL) {
27359     return;
27360   }
27361 
27362   frm->wiz->annot_list = FreeAnnotList(frm->wiz->annot_list);
27363   SummarizeVirusFeatures(frm->doc);
27364   Disable (frm->clear_btn);
27365 }
27366 
27367 
CreateVirusFeatureTableForm(WizardTrackerPtr wiz)27368 static Boolean CreateVirusFeatureTableForm (WizardTrackerPtr wiz)
27369 {
27370   VirusFeatureTableFormPtr frm;
27371   WindoW w;
27372   GrouP  h;
27373   GrouP  c, g;
27374   ButtoN  b;
27375   CharPtr dlg_title;
27376 
27377   frm = (VirusFeatureTableFormPtr) MemNew (sizeof (VirusFeatureTableFormData));
27378   frm->wiz = wiz;
27379   frm->fwd_ok_func = VirusFeatureTableOkToContinueToSequin;
27380   frm->next_form = FinishWizardAndLaunchSequin;
27381 
27382   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
27383   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
27384   SetObjectExtra (w, frm, CleanupWizardForm);
27385   frm->form = (ForM) w;
27386 
27387   h = HiddenGroup (w, -1, -1, NULL);
27388   SetGroupSpacing (h, 10, 10);
27389 
27390   /* create clickable help doc with link to feature table generator */
27391   frm->doc = DocumentPanel (h, stdCharWidth * 50, stdLineHeight * 12);
27392   SetObjectExtra (frm->doc, frm->wiz, NULL);
27393   SetDocProcs (frm->doc, ClickDocURL, NULL, NULL, NULL);
27394   SummarizeVirusFeatures(frm->doc);
27395 
27396   g = HiddenGroup (h, 2, 0, NULL);
27397   SetGroupSpacing (g, 10, 10);
27398   /* add button for uploading feature table file */
27399   b = PushButton (g, "Upload Feature Table", UploadVirusFeatureTable);
27400   SetObjectExtra (b, frm, NULL);
27401   frm->clear_btn = PushButton (g, "Clear Feature Table", ClearVirusFeatureTable);
27402   SetObjectExtra (frm->clear_btn, frm, NULL);
27403   Disable (frm->clear_btn);
27404 
27405   c = MakeWizardNav (h, frm);
27406 
27407   AlignObjects (ALIGN_CENTER, (HANDLE) frm->doc,
27408                               (HANDLE) g,
27409                               (HANDLE) c,
27410                               NULL);
27411 
27412   Update();
27413   Show (w);
27414   SendHelpScrollMessage (helpForm, dlg_title, "");
27415 
27416   return TRUE;
27417 }
27418 
27419 
27420 typedef struct unculturedsamplescodingregionform {
27421   WIZARD_BLOCK
27422   ButtoN partial_left;
27423   ButtoN partial_right;
27424   ButtoN use_minus_strand;
27425   TexT   product;
27426   TexT   desc;
27427   TexT   gene;
27428   TexT   comment;
27429 
27430 } UnculturedSamplesCodingRegionFormData, PNTR UnculturedSamplesCodingRegionFormPtr;
27431 
27432 
CollectCodingRegionFields(Pointer data,WizardTrackerPtr wiz)27433 static void CollectCodingRegionFields (Pointer data, WizardTrackerPtr wiz)
27434 {
27435   UnculturedSamplesCodingRegionFormPtr frm;
27436 
27437   frm = (UnculturedSamplesCodingRegionFormPtr) data;
27438   if (frm == NULL) {
27439     return;
27440   }
27441 
27442   wiz->prot_name = SaveStringFromText (frm->product);
27443   wiz->cds_comment = SaveStringFromText (frm->comment);
27444   if (StringHasNoText(wiz->cds_comment)) {
27445     wiz->cds_comment = MemFree (wiz->cds_comment);
27446   }
27447   wiz->prot_desc = SaveStringFromText (frm->desc);
27448   if (StringHasNoText(wiz->prot_desc)) {
27449     wiz->prot_desc = MemFree (wiz->prot_desc);
27450   }
27451   wiz->gene_name = SaveStringFromText (frm->gene);
27452   wiz->partial5 = GetStatus (frm->partial_left);
27453   wiz->partial3 = GetStatus (frm->partial_right);
27454   wiz->use_minus_strand = GetStatus (frm->use_minus_strand);
27455 }
27456 
27457 
HaveAllProductNames(WizardTrackerPtr wiz)27458 static Boolean HaveAllProductNames (WizardTrackerPtr wiz)
27459 {
27460   if (StringHasNoText (wiz->prot_name)) {
27461     Message (MSG_ERROR, "You must specify a protein name!");
27462     return FALSE;
27463   } else {
27464     return OkToContinueToSequin(wiz);
27465   }
27466 }
27467 
27468 
UnculturedSamplesCodingRegionForm(WizardTrackerPtr wiz)27469 static Boolean UnculturedSamplesCodingRegionForm (WizardTrackerPtr wiz)
27470 {
27471   UnculturedSamplesCodingRegionFormPtr frm;
27472   WindoW w;
27473   GrouP  h;
27474   GrouP  g1, g2, c;
27475   CharPtr dlg_title;
27476 
27477   frm = (UnculturedSamplesCodingRegionFormPtr) MemNew (sizeof (UnculturedSamplesCodingRegionFormData));
27478   frm->wiz = wiz;
27479   frm->collect_func = CollectCodingRegionFields;
27480   frm->fwd_ok_func = HaveAllProductNames;
27481   frm->next_form = FinishWizardAndLaunchSequin;
27482   if (wiz->wizard_type == eWizardType_Viruses) {
27483     wiz->virus_feat = eVirusFeat_CDS;
27484   }
27485 
27486   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
27487   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
27488   SetObjectExtra (w, frm, CleanupWizardForm);
27489   frm->form = (ForM) w;
27490 
27491   h = HiddenGroup (w, -1, -1, NULL);
27492   SetGroupSpacing (h, 10, 10);
27493 
27494   g1 = HiddenGroup (h, 2, 0, NULL);
27495   frm->partial_left = CheckBox (g1, "Incomplete at 5' end", NULL);
27496   frm->partial_right = CheckBox (g1, "Incomplete at 3' end", NULL);
27497   frm->use_minus_strand = CheckBox (h, "Coding region is on minus strand", NULL);
27498   g2 = HiddenGroup (h, 2, 0, NULL);
27499   StaticPrompt (g2, "Protein Name", 0, dialogTextHeight, programFont, 'l');
27500   frm->product = DialogText (g2, "", 20, NULL);
27501   StaticPrompt (g2, "Protein Description", 0, dialogTextHeight, programFont, 'l');
27502   frm->desc = DialogText (g2, "", 20, NULL);
27503   StaticPrompt (g2, "Gene Symbol", 0, dialogTextHeight, programFont, 'l');
27504   frm->gene = DialogText (g2, "", 20, NULL);
27505   StaticPrompt (g2, "Comment", 0, 3 * Nlm_stdLineHeight, programFont, 'l');
27506   frm->comment = ScrollText (g2, 20, 3, programFont, TRUE, NULL);
27507 
27508   c = MakeWizardNav (h, frm);
27509 
27510   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) frm->use_minus_strand, (HANDLE) g2, (HANDLE) c, NULL);
27511   Update();
27512   Show (w);
27513   SendHelpScrollMessage (helpForm, dlg_title, wiz->wizard_type == eWizardType_Viruses ? "Single coding region across the entire sequence" : "Coding Region (CDS)");
27514   return TRUE;
27515 }
27516 
27517 
27518 typedef struct wizardsettypeform {
27519   WIZARD_BLOCK
27520 
27521   GrouP set_type;
27522 
27523 } WizardSetTypeFormData, PNTR WizardSetTypeFormPtr;
27524 
27525 
CollectWizardSetType(Pointer data,WizardTrackerPtr wiz)27526 static void CollectWizardSetType (Pointer data, WizardTrackerPtr wiz)
27527 {
27528   WizardSetTypeFormPtr frm;
27529   Int2 val;
27530 
27531   frm = (WizardSetTypeFormPtr) data;
27532   if (frm == NULL) {
27533     return;
27534   }
27535 
27536   val = GetValue (frm->set_type);
27537 
27538   switch (wiz->wizard_type) {
27539     case eWizardType_UnculturedSamples:
27540       switch (val) {
27541         case 1:
27542           wiz->set_class = BioseqseqSet_class_eco_set;
27543           break;
27544         case 2:
27545           wiz->set_class = BioseqseqSet_class_genbank;
27546           break;
27547         default:
27548           wiz->set_class = BioseqseqSet_class_not_set;
27549           break;
27550       }
27551       break;
27552     case eWizardType_Viruses:
27553     case eWizardType_CulturedSamples:
27554     case eWizardType_IGS:
27555     case eWizardType_DLoop:
27556       switch (val) {
27557         case 1:
27558           wiz->set_class = BioseqseqSet_class_pop_set;
27559           break;
27560         case 2:
27561           wiz->set_class = BioseqseqSet_class_phy_set;
27562           break;
27563         case 3:
27564           wiz->set_class = BioseqseqSet_class_mut_set;
27565           break;
27566         case 4:
27567           wiz->set_class = BioseqseqSet_class_genbank;
27568           break;
27569         default:
27570           wiz->set_class = BioseqseqSet_class_not_set;
27571           break;
27572       }
27573       break;
27574   }
27575 }
27576 
27577 
HaveWizardSetType(WizardTrackerPtr wiz)27578 static Boolean HaveWizardSetType (WizardTrackerPtr wiz)
27579 {
27580   if (wiz->set_class == BioseqseqSet_class_not_set) {
27581     Message (MSG_ERROR, "Please select the submission type");
27582     return FALSE;
27583   } else {
27584     return TRUE;
27585   }
27586 }
27587 
27588 
WizardSetTypeForm(WizardTrackerPtr wiz)27589 static Boolean WizardSetTypeForm (WizardTrackerPtr wiz)
27590 {
27591   WizardSetTypeFormPtr frm;
27592   WindoW w;
27593   GrouP  h;
27594   GrouP  c;
27595 
27596   frm = (WizardSetTypeFormPtr) MemNew (sizeof (WizardSetTypeFormData));
27597   frm->wiz = wiz;
27598   frm->collect_func = CollectWizardSetType;
27599   frm->fwd_ok_func = HaveWizardSetType;
27600   if (wiz->wizard_type == eWizardType_Viruses
27601       || wiz->wizard_type == eWizardType_CulturedSamples
27602       || wiz->wizard_type == eWizardType_IGS) {
27603     frm->next_form = WizardSourceTypeForm;
27604   } else {
27605     frm->next_form = CreateWizardSrcQualsForm;
27606   }
27607 
27608   w = FixedWindow (-50, -33, -10, -10, "Submission Type", NULL);
27609   SetObjectExtra (w, frm, CleanupWizardForm);
27610   frm->form = (ForM) w;
27611 
27612   SendHelpScrollMessage (helpForm, "Sequence Format Form", "Submission Type");
27613 
27614   h = HiddenGroup (w, -1, -1, NULL);
27615   SetGroupSpacing (h, 10, 10);
27616 
27617   frm->set_type = NormalGroup (h, 0, 4, "What type of submission is this?", programFont, NULL);
27618   SetGroupSpacing (frm->set_type, 10, 10);
27619   if (wiz->wizard_type == eWizardType_UnculturedSamples) {
27620     RadioButton (frm->set_type, "Environmental set: a set of sequences that were derived by sequencing the same gene from a population of unclassified or unknown organisms.");
27621     RadioButton (frm->set_type, "Batch: Do not process as a set");
27622   } else if (wiz->wizard_type == eWizardType_Viruses
27623              || wiz->wizard_type == eWizardType_CulturedSamples
27624              || wiz->wizard_type == eWizardType_IGS
27625              || wiz->wizard_type == eWizardType_DLoop) {
27626     RadioButton (frm->set_type, "Pop set: Population Study: a set of sequences that were derived by sequencing the same gene from different isolates of the same organism.");
27627     RadioButton (frm->set_type, "Phy set: Phylogenetic Study: a set of sequences that were derived by sequencing the same gene from different organisms.");
27628     RadioButton (frm->set_type, "Mut set: Mutation Study: a set of sequences that were derived by sequencing multiple mutations of a single gene.");
27629     if (!IS_Bioseq_set (wiz->sequences)) {
27630       /* only allow batch if not submitting an alignment */
27631       RadioButton (frm->set_type, "Batch: Do not process as a set.");
27632     }
27633   }
27634 
27635   c = MakeWizardNav (h, frm);
27636 
27637   AlignObjects (ALIGN_CENTER, (HANDLE) frm->set_type, (HANDLE) c, NULL);
27638   Update();
27639   Show (w);
27640   return TRUE;
27641 }
27642 
27643 
27644 static CharPtr method_names[] = {
27645   "Sanger dideoxy sequencing",
27646   "454",
27647   "Helicos",
27648   "Illumina",
27649   "IonTorrent",
27650   "PacBio",
27651   "SOLiD",
27652   "Other"};
27653 
27654 #define kNumMethodNames (sizeof (method_names) / sizeof (CharPtr))
27655 
27656 typedef struct singleassemblyprogramdialog {
27657   DIALOG_MESSAGE_BLOCK
27658 
27659   TexT assembly_program;
27660   TexT version;
27661 } SingleAssemblyProgramDialogData, PNTR SingleAssemblyProgramDialogPtr;
27662 
27663 
AssemblyProgramToDialog(DialoG d,Pointer data)27664 static void AssemblyProgramToDialog (DialoG d, Pointer data)
27665 {
27666   SingleAssemblyProgramDialogPtr dlg;
27667   CharPtr val;
27668   CharPtr cp;
27669 
27670   dlg = (SingleAssemblyProgramDialogPtr) GetObjectExtra (d);
27671   if (dlg == NULL) {
27672     return;
27673   }
27674 
27675   val = (CharPtr) data;
27676   if (StringHasNoText (val)) {
27677     SetTitle (dlg->assembly_program, "");
27678     SetTitle (dlg->version, "");
27679   } else {
27680     cp = StringSearch (val, " v. ");
27681     if (cp == NULL) {
27682       SetTitle (dlg->assembly_program, val);
27683     } else {
27684       *cp = 0;
27685       SetTitle (dlg->assembly_program, val);
27686       SetTitle (dlg->version, cp + 4);
27687       *cp = ' ';
27688     }
27689   }
27690 }
27691 
AssemblyProgramFromDialog(DialoG d)27692 static Pointer AssemblyProgramFromDialog (DialoG d)
27693 {
27694   SingleAssemblyProgramDialogPtr dlg;
27695   CharPtr a, v, rval = NULL;
27696   CharPtr fmt = "%s v. %s";
27697 
27698   dlg = (SingleAssemblyProgramDialogPtr) GetObjectExtra (d);
27699   if (dlg == NULL) {
27700     return NULL;
27701   }
27702 
27703   if (TextHasNoText (dlg->assembly_program) || TextHasNoText (dlg->version)) {
27704     return NULL;
27705   }
27706   a = SaveStringFromText (dlg->assembly_program);
27707   v = SaveStringFromText (dlg->version);
27708   rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (a) + StringLen (v)));
27709   sprintf (rval, fmt, a, v);
27710   a = MemFree (a);
27711   v = MemFree (v);
27712   return rval;
27713 }
27714 
27715 
JustAssemblyProgramNameFromDialog(DialoG d)27716 static CharPtr JustAssemblyProgramNameFromDialog (DialoG d)
27717 {
27718   SingleAssemblyProgramDialogPtr dlg;
27719 
27720   dlg = (SingleAssemblyProgramDialogPtr) GetObjectExtra (d);
27721   if (dlg == NULL) {
27722     return NULL;
27723   } else if (TextHasNoText (dlg->assembly_program)) {
27724     return NULL;
27725   } else {
27726     return SaveStringFromText (dlg->assembly_program);
27727   }
27728 }
27729 
27730 
JustAssemblyProgramVersionFromDialog(DialoG d)27731 static CharPtr JustAssemblyProgramVersionFromDialog (DialoG d)
27732 {
27733   SingleAssemblyProgramDialogPtr dlg;
27734 
27735   dlg = (SingleAssemblyProgramDialogPtr) GetObjectExtra (d);
27736   if (dlg == NULL) {
27737     return NULL;
27738   } else if (TextHasNoText (dlg->version)) {
27739     return NULL;
27740   } else {
27741     return SaveStringFromText (dlg->version);
27742   }
27743 }
27744 
27745 
TestAssemblyProgramDialog(DialoG d)27746 static ValNodePtr TestAssemblyProgramDialog (DialoG d)
27747 {
27748   SingleAssemblyProgramDialogPtr dlg;
27749   ValNodePtr errs = 0;
27750 
27751   dlg = (SingleAssemblyProgramDialogPtr) GetObjectExtra (d);
27752   if (dlg == NULL) {
27753     return NULL;
27754   }
27755 
27756   if (TextHasNoText (dlg->assembly_program) && TextHasNoText (dlg->version)) {
27757     return NULL;
27758   } else if (TextHasNoText (dlg->assembly_program)) {
27759     ValNodeAddPointer (&errs, 0, "Program name is required");
27760   } else if (TextHasNoText (dlg->version)) {
27761     ValNodeAddPointer (&errs, 0, "Version is required");
27762   }
27763   return errs;
27764 }
27765 
27766 
CreateAssemblyProgramDialog(GrouP parent)27767 static DialoG CreateAssemblyProgramDialog (GrouP parent)
27768 {
27769   SingleAssemblyProgramDialogPtr dlg;
27770   GrouP  h;
27771 
27772   dlg = (SingleAssemblyProgramDialogPtr) MemNew (sizeof (SingleAssemblyProgramDialogData));
27773   if (dlg == NULL)
27774   {
27775     return NULL;
27776   }
27777 
27778   h = NormalGroup (parent, 2, 0, "What program(s) did you use to assemble your sequences?", programFont, NULL);
27779   SetGroupSpacing (h, 10, 10);
27780   SetObjectExtra (h, dlg, StdCleanupExtraProc);
27781   dlg->dialog = (DialoG) h;
27782   dlg->fromdialog = AssemblyProgramFromDialog;
27783   dlg->todialog = AssemblyProgramToDialog;
27784   dlg->testdialog = TestAssemblyProgramDialog;
27785 
27786   StaticPrompt (h, "Assembly program (required):", 0, 0, programFont, 'r');
27787   dlg->assembly_program = DialogText (h, "", 10, NULL);
27788   StaticPrompt (h, "Version or date (required):", 0, 0, programFont, 'r');
27789   dlg->version = DialogText (h, "", 10, NULL);
27790 
27791   return (DialoG) h;
27792 }
27793 
27794 
27795 static Uint2 assemblyprogram_types [] = {
27796   TAGLIST_TEXT, TAGLIST_TEXT
27797 };
27798 
27799 static Uint2 assemblyprogram_widths [] = {
27800   18, 18
27801 };
27802 
27803 
AssemblyProgramToTagListDialog(DialoG d,Pointer data)27804 static void AssemblyProgramToTagListDialog (DialoG d, Pointer data)
27805 {
27806   TagListPtr tlp;
27807   CharPtr    val;
27808   CharPtr    line, lf;
27809 
27810   tlp =(TagListPtr) GetObjectExtra (d);
27811   if (tlp == NULL) {
27812     return;
27813   }
27814 
27815   tlp->vnp = ValNodeFreeData (tlp->vnp);
27816   val = (CharPtr) data;
27817   if (!StringHasNoText (val)) {
27818     lf = StringChr (val, ';');
27819     while (lf != NULL) {
27820       *lf = 0;
27821       line = StringSave (val);
27822       FindReplaceString (&line, " v. ", "\t", FALSE, FALSE);
27823       ValNodeAddPointer (&tlp->vnp, 0, line);
27824       *lf = ';';
27825       val = lf + 1;
27826       lf = StringChr (val, ';');
27827     }
27828     line = StringSave (val);
27829     FindReplaceString (&line, " v. ", "\t", FALSE, FALSE);
27830     ValNodeAddPointer (&tlp->vnp, 0, line);
27831   }
27832   SendMessageToDialog (d, VIB_MSG_REDRAW);
27833 }
27834 
27835 
MultipleAssemblyProgramsOk(DialoG d)27836 static Boolean MultipleAssemblyProgramsOk (DialoG d)
27837 {
27838   TagListPtr tlp;
27839   ValNodePtr vnp;
27840   CharPtr    line, cp;
27841   Boolean    ok = TRUE;
27842 
27843   tlp =(TagListPtr) GetObjectExtra (d);
27844   if (tlp == NULL) {
27845     return TRUE;
27846   }
27847 
27848   /* are version and program both supplied for every "active" line? */
27849   for (vnp = tlp->vnp; vnp != NULL && ok; vnp = vnp->next) {
27850     line = (CharPtr) vnp->data.ptrvalue;
27851     if (!StringHasNoText (line)) {
27852       cp = StringChr (line, '\t');
27853       if (cp == NULL) {
27854         if (!StringHasNoText (line)) {
27855           ok = FALSE;
27856         }
27857       } else if (StringHasNoText (cp + 1)) {
27858         ok = FALSE;
27859       } else {
27860         *cp = 0;
27861         if (StringHasNoText (line)) {
27862           ok = FALSE;
27863         }
27864         *cp = '\t';
27865       }
27866     }
27867   }
27868   return ok;
27869 }
27870 
27871 
AssemblyProgramFromTagListDialog(DialoG d)27872 static Pointer AssemblyProgramFromTagListDialog (DialoG d)
27873 {
27874   TagListPtr tlp;
27875   ValNodePtr vnp;
27876   CharPtr    assembly_program = NULL;
27877   CharPtr    line, cp, lf;
27878   Boolean    ok = TRUE;
27879   Int4       len = 0;
27880 
27881   tlp =(TagListPtr) GetObjectExtra (d);
27882   if (tlp == NULL) {
27883     return NULL;
27884   }
27885 
27886   /* are version and program both supplied for every "active" line? */
27887   for (vnp = tlp->vnp; vnp != NULL && ok; vnp = vnp->next) {
27888     line = (CharPtr) vnp->data.ptrvalue;
27889     cp = StringChr (line, '\t');
27890     if (cp == NULL) {
27891       if (!StringHasNoText (line)) {
27892         ok = FALSE;
27893       }
27894     } else if (StringHasNoText (cp + 1)) {
27895       ok = FALSE;
27896     } else {
27897       *cp = 0;
27898       if (StringHasNoText (line)) {
27899         ok = FALSE;
27900       } else {
27901         len += StringLen (line) + StringLen (cp + 1) + 6;
27902       }
27903       *cp = '\t';
27904     }
27905   }
27906   if (len == 0) {
27907     return NULL;
27908   }
27909   if (ok) {
27910     assembly_program = (CharPtr) MemNew (sizeof (Char) * len);
27911     assembly_program[0] = 0;
27912     for (vnp = tlp->vnp; vnp != NULL && ok; vnp = vnp->next) {
27913       line = (CharPtr) vnp->data.ptrvalue;
27914       cp = StringChr (line, '\t');
27915       if (cp != NULL && !StringHasNoText (line)) {
27916         *cp = 0;
27917         if (assembly_program[0] != 0) {
27918           StringCat(assembly_program, "; ");
27919         }
27920         StringCat (assembly_program, line);
27921         StringCat (assembly_program, " v. ");
27922         lf = StringChr (cp + 1, '\t');
27923         if (lf != NULL) {
27924           *lf = 0;
27925         }
27926         StringCat (assembly_program, cp + 1);
27927         *cp = '\t';
27928         if (lf != NULL) {
27929           *lf = '\t';
27930         }
27931       }
27932     }
27933   }
27934 
27935   return assembly_program;
27936 }
27937 
27938 
27939 typedef struct stdassemblyprogramdialog {
27940   DIALOG_MESSAGE_BLOCK
27941 
27942   GrouP  single_assembly_program_grp;
27943   DialoG single_assembly_program;
27944   GrouP  mult_assembly_program_grp;
27945   DialoG assembly_programs;
27946   Boolean use_mult;
27947 
27948 } StdAssemblyProgramDialogData, PNTR StdAssemblyProgramDialogPtr;
27949 
27950 
StdAssemblyProgramFromDialog(DialoG d)27951 static Pointer StdAssemblyProgramFromDialog (DialoG d)
27952 {
27953   StdAssemblyProgramDialogPtr dlg;
27954 
27955   dlg = (StdAssemblyProgramDialogPtr) GetObjectExtra (d);
27956   if (dlg == NULL) {
27957     return NULL;
27958   }
27959   if (dlg->use_mult) {
27960     return DialogToPointer (dlg->assembly_programs);
27961   } else {
27962     return DialogToPointer (dlg->single_assembly_program);
27963   }
27964 }
27965 
27966 
StdAssemblyProgramToDialog(DialoG d,Pointer data)27967 static void StdAssemblyProgramToDialog (DialoG d, Pointer data)
27968 {
27969   StdAssemblyProgramDialogPtr dlg;
27970 
27971   dlg = (StdAssemblyProgramDialogPtr) GetObjectExtra (d);
27972   if (dlg == NULL) {
27973     return;
27974   }
27975   PointerToDialog (dlg->single_assembly_program, data);
27976   PointerToDialog (dlg->assembly_programs, data);
27977 }
27978 
27979 
AddAssemblyPrograms(ButtoN b)27980 static void AddAssemblyPrograms (ButtoN b)
27981 {
27982   StdAssemblyProgramDialogPtr dlg;
27983   CharPtr val, a, v;
27984   CharPtr fmt = "%s v. %s";
27985 
27986   dlg = (StdAssemblyProgramDialogPtr) GetObjectExtra (b);
27987   if (dlg == NULL) {
27988     return;
27989   }
27990 
27991   val = DialogToPointer (dlg->single_assembly_program);
27992   if (StringHasNoText (val)) {
27993     val = MemFree (val);
27994     a = JustAssemblyProgramNameFromDialog (dlg->single_assembly_program);
27995     v = JustAssemblyProgramVersionFromDialog (dlg->single_assembly_program);
27996     val = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (a) + StringLen (v)));
27997     sprintf (val, fmt, a == NULL ? "" : a, v == NULL ? "" : v);
27998     a = MemFree (a);
27999     v = MemFree (v);
28000   }
28001 
28002   Hide (dlg->single_assembly_program_grp);
28003   PointerToDialog (dlg->assembly_programs, val);
28004   val = MemFree (val);
28005   Show (dlg->mult_assembly_program_grp);
28006   dlg->use_mult = TRUE;
28007 }
28008 
28009 
TestStdAssemblyProgramDialog(DialoG d)28010 static ValNodePtr TestStdAssemblyProgramDialog (DialoG d)
28011 {
28012   StdAssemblyProgramDialogPtr dlg;
28013   ValNodePtr errs = NULL;
28014 
28015   dlg = (StdAssemblyProgramDialogPtr) GetObjectExtra (d);
28016   if (dlg == NULL) {
28017     return NULL;
28018   }
28019 
28020   if (dlg->use_mult) {
28021     if (!MultipleAssemblyProgramsOk(dlg->assembly_programs)) {
28022       ValNodeAddPointer (&errs, 0, "Program name and version are both required");
28023     }
28024   } else {
28025     errs = TestAssemblyProgramDialog (dlg->single_assembly_program);
28026   }
28027   return errs;
28028 }
28029 
28030 
CreateStdAssemblyProgramDialog(GrouP parent)28031 static DialoG CreateStdAssemblyProgramDialog (GrouP parent)
28032 {
28033   StdAssemblyProgramDialogPtr dlg;
28034   GrouP  h, g4;
28035   ButtoN add_prg;
28036 
28037   dlg = (StdAssemblyProgramDialogPtr) MemNew (sizeof (StdAssemblyProgramDialogData));
28038   if (dlg == NULL)
28039   {
28040     return NULL;
28041   }
28042 
28043   h = HiddenGroup (parent, 0, 0, NULL);
28044   SetGroupSpacing (h, 10, 10);
28045   SetObjectExtra (h, dlg, StdCleanupExtraProc);
28046   dlg->dialog = (DialoG) h;
28047   dlg->fromdialog = StdAssemblyProgramFromDialog;
28048   dlg->todialog = StdAssemblyProgramToDialog;
28049   dlg->testdialog = TestStdAssemblyProgramDialog;
28050   dlg->use_mult = FALSE;
28051 
28052   dlg->single_assembly_program_grp = HiddenGroup (h, -1, 0, NULL);
28053   dlg->single_assembly_program = CreateAssemblyProgramDialog(dlg->single_assembly_program_grp);
28054   add_prg = PushButton (dlg->single_assembly_program_grp, "Add More Assembly Programs", AddAssemblyPrograms);
28055   SetObjectExtra (add_prg, dlg, NULL);
28056   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->single_assembly_program, (HANDLE) add_prg, NULL);
28057 
28058   dlg->mult_assembly_program_grp = NormalGroup (h, -1, 0, "What program(s) did you use to assemble your sequences?", programFont, NULL);
28059   SetGroupSpacing (dlg->mult_assembly_program_grp, 10, 10);
28060   g4 = HiddenGroup (dlg->mult_assembly_program_grp, 2, 0, NULL);
28061   SetGroupSpacing (g4, 10, 10);
28062   StaticPrompt (g4, "Assembly program (required):", 0, 0, programFont, 'r');
28063   StaticPrompt (g4, "Version or date (required):", 0, 0, programFont, 'r');
28064   dlg->assembly_programs = CreateTagListDialog (dlg->mult_assembly_program_grp, 3, 2, 2, assemblyprogram_types, assemblyprogram_widths, NULL,
28065                                                 AssemblyProgramToTagListDialog, AssemblyProgramFromTagListDialog);
28066 
28067   Hide (dlg->mult_assembly_program_grp);
28068   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->single_assembly_program_grp, (HANDLE) dlg->mult_assembly_program_grp, NULL);
28069 
28070   return (DialoG) h;
28071 }
28072 
28073 
28074 
28075 static CharPtr wgs_programs[] = {
28076   "Newbler",
28077   "Celera Assembler",
28078   "SOAPdenovo",
28079   "Velvet",
28080   "ALLPATHS",
28081   "GS De Novo Assembler",
28082   "MIRA",
28083   "phredPhrap",
28084   "ABySS",
28085   "CLC NGS Cell",
28086   NULL
28087 };
28088 
28089 
28090 typedef struct wgsassemblyprogramdialog {
28091   DIALOG_MESSAGE_BLOCK
28092 
28093   ButtoN PNTR cv_programs;
28094   TexT   PNTR cv_versions;
28095   DialoG other_programs;
28096 
28097   Int4 num_cv_programs;
28098 } WGSAssemblyProgramDialogData, PNTR WGSAssemblyProgramDialogPtr;
28099 
28100 
SetOneWGSAssemblyProgramCheckbox(WGSAssemblyProgramDialogPtr dlg,CharPtr program,CharPtr version)28101 static Boolean SetOneWGSAssemblyProgramCheckbox (WGSAssemblyProgramDialogPtr dlg, CharPtr program, CharPtr version)
28102 {
28103   Int4 i;
28104   Boolean rval = FALSE;
28105   CharPtr tmp;
28106 
28107   for (i = 0; i < dlg->num_cv_programs && wgs_programs[i] != NULL && !rval; i++) {
28108     if (StringICmp (program, wgs_programs[i]) == 0) {
28109       if (GetStatus (dlg->cv_programs[i])) {
28110         tmp = SaveStringFromText (dlg->cv_versions[i]);
28111         /* don't list same program/version twice, if different version put in other */
28112         if (StringCmp (tmp, version) == 0) {
28113           rval = TRUE;
28114         }
28115         tmp = MemFree (tmp);
28116         return rval;
28117       }
28118       SetStatus (dlg->cv_programs[i], TRUE);
28119       Enable (dlg->cv_versions[i]);
28120       SetTitle (dlg->cv_versions[i], version);
28121       rval = TRUE;
28122     }
28123   }
28124   return rval;
28125 }
28126 
28127 
AddOneWGSAssemblyProgramToDialog(WGSAssemblyProgramDialogPtr dlg,CharPtr val,ValNodePtr PNTR others)28128 static void AddOneWGSAssemblyProgramToDialog (WGSAssemblyProgramDialogPtr dlg, CharPtr val, ValNodePtr PNTR others)
28129 {
28130   CharPtr line, cp;
28131 
28132   if (StringHasNoText (val)) {
28133     return;
28134   }
28135   line = StringSave (val);
28136   cp = StringISearch (line, " v. ");
28137   if (cp == NULL) {
28138     if (!SetOneWGSAssemblyProgramCheckbox (dlg, line, NULL)) {
28139       ValNodeAddPointer (others, 0, line);
28140     }
28141   } else {
28142     *cp = 0;
28143     if (!SetOneWGSAssemblyProgramCheckbox (dlg, line, cp + 4)) {
28144       *cp = ' ';
28145       FindReplaceString (&line, " v. ", "\t", FALSE, FALSE);
28146       ValNodeAddPointer (others, 0, line);
28147     }
28148   }
28149 }
28150 
28151 
WGSAssemblyProgramToDialog(DialoG d,Pointer data)28152 static void WGSAssemblyProgramToDialog (DialoG d, Pointer data)
28153 {
28154   WGSAssemblyProgramDialogPtr dlg;
28155   CharPtr val;
28156   CharPtr lf;
28157   Int4 i;
28158   TagListPtr tlp;
28159 
28160   dlg = (WGSAssemblyProgramDialogPtr) GetObjectExtra (d);
28161   if (dlg == NULL) {
28162     return;
28163   }
28164 
28165   tlp = (TagListPtr) GetObjectExtra (dlg->other_programs);
28166   if (tlp == NULL) {
28167     return;
28168   }
28169 
28170   for (i = 0; i < dlg->num_cv_programs; i++) {
28171     SetStatus (dlg->cv_programs[i], FALSE);
28172     SetTitle (dlg->cv_versions[i], "");
28173     Disable (dlg->cv_versions[i]);
28174   }
28175   tlp->vnp = ValNodeFreeData (tlp->vnp);
28176 
28177   val = (CharPtr) data;
28178   if (!StringHasNoText (val)) {
28179     lf = StringChr (val, ';');
28180     while (lf != NULL) {
28181       *lf = 0;
28182       AddOneWGSAssemblyProgramToDialog (dlg, val, &(tlp->vnp));
28183       *lf = ';';
28184       val = lf + 1;
28185       lf = StringChr (val, ';');
28186     }
28187     AddOneWGSAssemblyProgramToDialog (dlg, val, &(tlp->vnp));
28188   }
28189 
28190   SendMessageToDialog (dlg->other_programs, VIB_MSG_REDRAW);
28191 }
28192 
28193 
WGSAssemblyProgramFromDialog(DialoG d)28194 static Pointer WGSAssemblyProgramFromDialog (DialoG d)
28195 {
28196   WGSAssemblyProgramDialogPtr dlg;
28197   CharPtr v, rval = NULL, others;
28198   Int4 i;
28199 
28200   dlg = (WGSAssemblyProgramDialogPtr) GetObjectExtra (d);
28201   if (dlg == NULL) {
28202     return NULL;
28203   }
28204 
28205   for (i = 0; i < dlg->num_cv_programs; i++) {
28206     if (GetStatus (dlg->cv_programs[i])) {
28207       SetStringValue (&rval, wgs_programs[i], ExistingTextOption_append_semi);
28208       if (!TextHasNoText (dlg->cv_versions[i])) {
28209         v = SaveStringFromText (dlg->cv_versions[i]);
28210         SetStringValue (&rval, " v. ", ExistingTextOption_append_none);
28211         SetStringValue (&rval, v, ExistingTextOption_append_none);
28212         v = MemFree (v);
28213       }
28214     }
28215   }
28216   others = DialogToPointer (dlg->other_programs);
28217   if (!StringHasNoText (others)) {
28218     SetStringValue (&rval, others, ExistingTextOption_append_semi);
28219   }
28220   others = MemFree (others);
28221   return rval;
28222 }
28223 
28224 
CleanupWGSAssemblyProgramDialog(GraphiC g,Pointer data)28225 static void CleanupWGSAssemblyProgramDialog (GraphiC g, Pointer data)
28226 {
28227   WGSAssemblyProgramDialogPtr dlg;
28228 
28229   if (data != NULL)
28230   {
28231     dlg = (WGSAssemblyProgramDialogPtr) data;
28232     dlg->cv_programs = MemFree (dlg->cv_programs);
28233     dlg->cv_versions = MemFree (dlg->cv_versions);
28234   }
28235   StdCleanupExtraProc (g, data);
28236 }
28237 
28238 
WGSAssemblyBtn(ButtoN b)28239 static void WGSAssemblyBtn (ButtoN b)
28240 {
28241   WGSAssemblyProgramDialogPtr dlg;
28242   Int4 i;
28243 
28244   dlg = (WGSAssemblyProgramDialogPtr) GetObjectExtra (b);
28245   if (dlg == NULL) {
28246     return;
28247   }
28248 
28249   for (i = 0; i < dlg->num_cv_programs; i++) {
28250     if (GetStatus (dlg->cv_programs[i])) {
28251       Enable (dlg->cv_versions[i]);
28252     } else {
28253       Disable (dlg->cv_versions[i]);
28254     }
28255   }
28256 }
28257 
28258 
TestWGSAssemblyProgramDialog(DialoG d)28259 static ValNodePtr TestWGSAssemblyProgramDialog (DialoG d)
28260 {
28261   WGSAssemblyProgramDialogPtr dlg;
28262   Int4 i;
28263   ValNodePtr errs = NULL;
28264 
28265   dlg = (WGSAssemblyProgramDialogPtr) GetObjectExtra (d);
28266   if (dlg == NULL) {
28267     return NULL;
28268   }
28269   for (i = 0; i < dlg->num_cv_programs; i++) {
28270     if (GetStatus (dlg->cv_programs[i]) && TextHasNoText (dlg->cv_versions[i])) {
28271       ValNodeAddPointer (&errs, 0, "Version is required");
28272       break;
28273     }
28274   }
28275   if (errs == NULL) {
28276     if (!MultipleAssemblyProgramsOk(dlg->other_programs)) {
28277       ValNodeAddPointer (&errs, 0, "Program name and version are both required");
28278     }
28279   }
28280   return errs;
28281 }
28282 
28283 
CreateWGSAssemblyProgramDialog(GrouP parent)28284 static DialoG CreateWGSAssemblyProgramDialog (GrouP parent)
28285 {
28286   WGSAssemblyProgramDialogPtr dlg;
28287   GrouP  h, g, g2;
28288   Int4   i, div_width = 20;
28289 
28290   dlg = (WGSAssemblyProgramDialogPtr) MemNew (sizeof (WGSAssemblyProgramDialogData));
28291   if (dlg == NULL)
28292   {
28293     return NULL;
28294   }
28295 
28296   h = NormalGroup (parent, -1, 0, "What program(s) did you use to assemble your sequences?", programFont, NULL);
28297   SetGroupSpacing (h, 10, 10);
28298   SetObjectExtra (h, dlg, CleanupWGSAssemblyProgramDialog);
28299   dlg->dialog = (DialoG) h;
28300   dlg->fromdialog = WGSAssemblyProgramFromDialog;
28301   dlg->todialog = WGSAssemblyProgramToDialog;
28302   dlg->testdialog = TestWGSAssemblyProgramDialog;
28303 
28304   g = HiddenGroup (h, 5, 0, NULL);
28305   SetGroupSpacing (g, 10, 10);
28306   StaticPrompt (g, "", 0, 0, programFont, 'c');
28307   StaticPrompt (g, "Version or date", 0, 0, programFont, 'c');
28308   StaticPrompt (g, "", div_width, 0, programFont, 'c');
28309   StaticPrompt (g, "", 0, 0, programFont, 'c');
28310   StaticPrompt (g, "Version or date", 0, 0, programFont, 'c');
28311 
28312   dlg->num_cv_programs = 0;
28313   for (i = 0; wgs_programs[i] != NULL; i++) {
28314     dlg->num_cv_programs++;
28315   }
28316 
28317   dlg->cv_programs = (ButtoN PNTR) MemNew (sizeof (ButtoN) * dlg->num_cv_programs);
28318   dlg->cv_versions = (TexT PNTR) MemNew (sizeof (TexT) * dlg->num_cv_programs);
28319   for (i = 0; wgs_programs[i] != NULL; i++) {
28320     dlg->cv_programs[i] = CheckBox (g, wgs_programs[i], WGSAssemblyBtn);
28321     SetObjectExtra (dlg->cv_programs[i], dlg, NULL);
28322     dlg->cv_versions[i] = DialogText (g, "", 5, NULL);
28323     Disable (dlg->cv_versions[i]);
28324     if (i % 2 == 0) {
28325       StaticPrompt (g, "", div_width, 0, programFont, 'c');
28326     }
28327   }
28328 
28329   g2 = HiddenGroup (h, 2, 0, NULL);
28330   SetGroupSpacing (g2, 10, 10);
28331   StaticPrompt (g2, "Other assembly program", 200, 0, programFont, 'l');
28332   StaticPrompt (g2, "Version or date", 200, 0, programFont, 'l');
28333   dlg->other_programs = CreateTagListDialog (h, 3, 2, 2, assemblyprogram_types, assemblyprogram_widths, NULL,
28334                                                 AssemblyProgramToTagListDialog, AssemblyProgramFromTagListDialog);
28335 
28336   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) g2, (HANDLE) dlg->other_programs, NULL);
28337   return (DialoG) h;
28338 }
28339 
28340 
28341 typedef struct sequencingmethoddialog {
28342   DIALOG_MESSAGE_BLOCK
28343 
28344   ButtoN method_names[kNumMethodNames];
28345   TexT  method_text;
28346   GrouP is_assembled;
28347 
28348   DialoG assembly_program;
28349   GrouP  name_coverage;
28350   TexT   assembly_name;
28351   TexT coverage;
28352 
28353   EWizardType wizard_type;
28354 
28355 } SequencingMethodDialogData, PNTR SequencingMethodDialogPtr;
28356 
28357 
SequencingMethodToDialog(DialoG d,Pointer data)28358 static void SequencingMethodToDialog (DialoG d, Pointer data)
28359 {
28360   SequencingMethodDialogPtr dlg;
28361   SequencingMethodInfoPtr info;
28362 
28363   dlg = (SequencingMethodDialogPtr) GetObjectExtra (d);
28364   if (dlg == NULL) {
28365     return;
28366   }
28367   info = (SequencingMethodInfoPtr) data;
28368 
28369 
28370 }
28371 
28372 
SequencingMethodFromDialog(DialoG d)28373 static Pointer SequencingMethodFromDialog (DialoG d)
28374 {
28375   SequencingMethodDialogPtr dlg;
28376   SequencingMethodInfoPtr info;
28377   UserObjectPtr uop;
28378   Int4          i;
28379   CharPtr       tech = NULL, val = NULL, tmp, assembly_program, assembly_name = NULL;
28380 
28381   dlg = (SequencingMethodDialogPtr) GetObjectExtra (d);
28382   if (dlg == NULL) {
28383     return NULL;
28384   }
28385 
28386   info = SequencingMethodInfoNew();
28387   if (dlg->is_assembled == NULL) {
28388     info->assembled_choice = 0;
28389   } else {
28390     info->assembled_choice = GetValue (dlg->is_assembled);
28391   }
28392 
28393   if (dlg->assembly_name != NULL) {
28394     assembly_name = SaveStringFromText (dlg->assembly_name);
28395   }
28396 
28397   for (i = 0; i < kNumMethodNames - 1; i++) {
28398     if (GetStatus (dlg->method_names[i])) {
28399       SetStringValue (&tech, method_names[i], ExistingTextOption_append_semi);
28400     }
28401   }
28402   if (GetStatus (dlg->method_names[i]) && !TextHasNoText (dlg->method_text)) {
28403     tmp = SaveStringFromText (dlg->method_text);
28404     SetStringValue (&tech, tmp, ExistingTextOption_append_semi);
28405     tmp = MemFree (tmp);
28406   }
28407 
28408   assembly_program = DialogToPointer (dlg->assembly_program);
28409 
28410   if (!StringHasNoText (tech)
28411              || !StringHasNoText (assembly_program)
28412              || !TextHasNoText (dlg->coverage)
28413              || !StringHasNoText (assembly_name)) {
28414     if (dlg->wizard_type == eWizardType_WGS) {
28415       uop = CreateStructuredCommentUserObject ("##Genome-Assembly-Data-START##", "##Genome-Assembly-Data-END##");
28416     } else {
28417       uop = CreateStructuredCommentUserObject ("##Assembly-Data-START##", "##Assembly-Data-END##");
28418     }
28419     if (assembly_program != NULL) {
28420       AddItemStructuredCommentUserObject (uop, "Assembly Method", assembly_program);
28421     }
28422     if (!StringHasNoText (assembly_name)) {
28423       AddItemStructuredCommentUserObject (uop, "Assembly Name", assembly_name);
28424     }
28425     if (!TextHasNoText (dlg->coverage)) {
28426       val = SaveStringFromText (dlg->coverage);
28427       AddItemStructuredCommentUserObject (uop, dlg->wizard_type == eWizardType_WGS ? "Genome Coverage" : "Coverage", val);
28428       val = MemFree (val);
28429     }
28430     if (!StringHasNoText (tech)) {
28431       AddItemStructuredCommentUserObject (uop, "Sequencing Technology", tech);
28432     }
28433     ValNodeAddPointer (&(info->structured_comments), 0, uop);
28434   }
28435 
28436   tech = MemFree (tech);
28437   assembly_program = MemFree (assembly_program);
28438   assembly_name = MemFree (assembly_name);
28439 
28440   return info;
28441 }
28442 
28443 
ClearSequencingMethodDialog(ButtoN b)28444 static void ClearSequencingMethodDialog (ButtoN b)
28445 {
28446   SequencingMethodDialogPtr dlg;
28447   Int4 i;
28448 
28449   dlg = (SequencingMethodDialogPtr) GetObjectExtra (b);
28450   if (dlg == NULL) {
28451     return;
28452   }
28453   for (i = 0; i < kNumMethodNames - 1; i++) {
28454     SetStatus (dlg->method_names[i], FALSE);
28455   }
28456   SetStatus (dlg->method_names[i], FALSE);
28457   SetTitle (dlg->method_text, "");
28458   Disable (dlg->method_text);
28459   SetValue (dlg->is_assembled, 0);
28460   PointerToDialog (dlg->assembly_program, NULL);
28461   SetTitle (dlg->coverage, "");
28462   if (dlg->assembly_name != NULL) {
28463     SetTitle (dlg->assembly_name, "");
28464   }
28465 }
28466 
28467 
EnableSequencingMethodOptions(ButtoN b)28468 static void EnableSequencingMethodOptions (ButtoN b)
28469 {
28470   SequencingMethodDialogPtr dlg;
28471 
28472   dlg = (SequencingMethodDialogPtr) GetObjectExtra (b);
28473   if (dlg == NULL) {
28474     return;
28475   }
28476 
28477   if (GetStatus (dlg->method_names[kNumMethodNames - 1])) {
28478     Enable (dlg->method_text);
28479   } else {
28480     Disable (dlg->method_text);
28481   }
28482 
28483 }
28484 
28485 
SequencingMethodDialogIsEmpty(SequencingMethodDialogPtr dlg)28486 static Boolean SequencingMethodDialogIsEmpty (SequencingMethodDialogPtr dlg)
28487 {
28488   Int4 i;
28489   CharPtr tmp;
28490   Boolean rval = TRUE;
28491 
28492   if (dlg == NULL) {
28493     return TRUE;
28494   }
28495 
28496   for (i = 0; i < kNumMethodNames; i++) {
28497     if (GetStatus (dlg->method_names[i])) {
28498       return FALSE;
28499     }
28500   }
28501   if (dlg->is_assembled != NULL && GetValue (dlg->is_assembled) != 0) {
28502     return FALSE;
28503   }
28504   if ((dlg->assembly_name != NULL && !TextHasNoText (dlg->assembly_name))
28505       || !TextHasNoText (dlg->coverage)) {
28506     return FALSE;
28507   }
28508   tmp = DialogToPointer (dlg->assembly_program);
28509   if (!StringHasNoText (tmp)) {
28510     rval = FALSE;
28511   }
28512   tmp = MemFree (tmp);
28513   return rval;
28514 }
28515 
28516 
TestSequencingMethodDialog(DialoG d)28517 static ValNodePtr TestSequencingMethodDialog (DialoG d)
28518 {
28519   SequencingMethodDialogPtr dlg;
28520   ValNodePtr errs = NULL;
28521   Boolean    need_tech = TRUE;
28522   Int4       i;
28523 
28524   dlg = (SequencingMethodDialogPtr) GetObjectExtra (d);
28525   if (dlg == NULL) {
28526     return NULL;
28527   }
28528 
28529   if (dlg->wizard_type != eWizardType_WGS && SequencingMethodDialogIsEmpty(dlg)) {
28530     return NULL;
28531   }
28532 
28533   for (i = 0; i < kNumMethodNames - 1 && need_tech; i++) {
28534     if (GetStatus (dlg->method_names[i])) {
28535       need_tech = FALSE;
28536     }
28537   }
28538   if (GetStatus (dlg->method_names[i]) && !TextHasNoText (dlg->method_text)) {
28539     need_tech = FALSE;
28540   }
28541 
28542   if (need_tech) {
28543     ValNodeAddPointer (&errs, 0, "Please select the sequencing technology used to obtain these sequences.");
28544   }
28545 
28546   ValNodeLink (&errs, TestDialog (dlg->assembly_program));
28547   if (dlg->wizard_type == eWizardType_WGS) {
28548     if (TextHasNoText (dlg->assembly_name)) {
28549       ValNodeAddPointer (&errs, 0, "Assembly name is required");
28550     }
28551     if (TextHasNoText (dlg->coverage)) {
28552       ValNodeAddPointer (&errs, 0, "Genome coverage is required");
28553     }
28554   }
28555   return errs;
28556 }
28557 
28558 
SequencingMethodDialog(GrouP parent,EWizardType wizard_type)28559 NLM_EXTERN DialoG SequencingMethodDialog (GrouP parent, EWizardType wizard_type)
28560 {
28561   SequencingMethodDialogPtr dlg;
28562   GrouP  h, g1, g2;
28563   Int4   i;
28564   ButtoN b;
28565   CharPtr title = "Sequencing Method";
28566   CharPtr assembly_name_example = "Example: ""EscColABCD_1.0"" for the first version of the Escherichia coli ABCD assembly";
28567 
28568   dlg = (SequencingMethodDialogPtr) MemNew (sizeof (SequencingMethodDialogData));
28569   if (dlg == NULL)
28570   {
28571     return NULL;
28572   }
28573   dlg->wizard_type = wizard_type;
28574 
28575   h = HiddenGroup (parent, -1, -1, NULL);
28576   SetGroupSpacing (h, 10, 10);
28577   SetObjectExtra (h, dlg, StdCleanupExtraProc);
28578   dlg->dialog = (DialoG) h;
28579   dlg->todialog = SequencingMethodToDialog;
28580   dlg->fromdialog = SequencingMethodFromDialog;
28581   dlg->dialogmessage = NULL;
28582   dlg->testdialog = TestSequencingMethodDialog;
28583 
28584   g1 = NormalGroup (h, 0, kNumMethodNames/2, "What methods were used to obtain these sequences?", programFont, NULL);
28585   SetGroupSpacing (g1, 10, 10);
28586   for (i = 0; i < kNumMethodNames - 1; i++) {
28587     dlg->method_names[i] = CheckBox (g1, method_names[i], EnableSequencingMethodOptions);
28588     SetObjectExtra (dlg->method_names[i], dlg, NULL);
28589   }
28590   g2 = HiddenGroup (g1, 2, 0, NULL);
28591   SetGroupSpacing (g2, 10, 10);
28592   dlg->method_names[i] = CheckBox (g2, method_names[i], EnableSequencingMethodOptions);
28593   SetObjectExtra (dlg->method_names[i], dlg, NULL);
28594   dlg->method_text = DialogText (g2, "", 10, NULL);
28595   Disable (dlg->method_text);
28596 
28597   StaticPrompt (h, "", 0, 0, programFont, 'c');
28598 
28599   if (dlg->wizard_type != eWizardType_WGS) {
28600     dlg->is_assembled = NormalGroup (h, 2, 0, "Are these sequence(s):", programFont, NULL);
28601     RadioButton (dlg->is_assembled, "raw sequence reads (not assembled)");
28602     RadioButton (dlg->is_assembled, "assembled sequences");
28603     StaticPrompt (h, "", 0, 0, programFont, 'c');
28604   }
28605 
28606   if (dlg->wizard_type == eWizardType_WGS) {
28607     dlg->assembly_program = CreateWGSAssemblyProgramDialog (h);
28608   } else {
28609     dlg->assembly_program = CreateStdAssemblyProgramDialog (h);
28610   }
28611 
28612   dlg->name_coverage = HiddenGroup (h, dlg->wizard_type == eWizardType_WGS ? 3 : 2, 0, NULL);
28613   SetGroupSpacing (dlg->name_coverage, 10, 10);
28614   if (dlg->wizard_type == eWizardType_WGS) {
28615     if (dlg->wizard_type == eWizardType_WGS) {
28616       StaticPrompt (dlg->name_coverage, "Assembly Name (required):", 0, 0, programFont, 'l');
28617     } else {
28618       StaticPrompt (dlg->name_coverage, "Assembly Name (optional):", 0, 0, programFont, 'l');
28619     }
28620     dlg->assembly_name = DialogText(dlg->name_coverage, "", 10, NULL);
28621   }
28622   if (dlg->wizard_type == eWizardType_WGS) {
28623     MultiLinePrompt (dlg->name_coverage, assembly_name_example, 250, programFont);
28624     StaticPrompt (dlg->name_coverage, "Genome Coverage (required):", 0, 0, programFont, 'r');
28625   } else {
28626     StaticPrompt (dlg->name_coverage, "Coverage (optional):", 0, 0, programFont, 'r');
28627   }
28628   dlg->coverage = DialogText (dlg->name_coverage, "", 10, NULL);
28629   if (dlg->wizard_type == eWizardType_WGS) {
28630     StaticPrompt (dlg->name_coverage, "Example: 10X", 0, 0, programFont, 'l');
28631   }
28632 
28633   b = PushButton (h, "Clear", ClearSequencingMethodDialog);
28634   SetObjectExtra (b, dlg, NULL);
28635   SendHelpScrollMessage (helpForm, title, "");
28636 
28637   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->assembly_program, (HANDLE) dlg->name_coverage, (HANDLE) b, (HANDLE) dlg->is_assembled, NULL);
28638   EnableSequencingMethodOptions(dlg->method_names[0]);
28639   return (DialoG) h;
28640 }
28641 
28642 
28643 
28644 
28645 
28646 static CharPtr bad_methods[] = {
28647   "core",
28648   "core facility",
28649   "core lab",
28650   "Sequencing",
28651   "PCR",
28652   "PCR product",
28653   "Overlapping sequence",
28654   "Overlapping sequences",
28655   NULL };
28656 static CharPtr bad_assem[] = {
28657   "Assembly program",
28658   "No",
28659   "Yes",
28660   "Not Applicable",
28661   "N/A",
28662   "Sequencing",
28663   "PCR",
28664   "PCR product",
28665   "Overlapping sequence",
28666   "Overlapping sequences",
28667   NULL };
28668 
IsAssemblyMethodValid(CharPtr assem)28669 static Boolean IsAssemblyMethodValid (CharPtr assem)
28670 {
28671   Boolean rval = TRUE;
28672   CharPtr cp;
28673   Int4    i, len;
28674 
28675   if (StringHasNoText (assem)) {
28676     Message (MSG_ERROR, "Please provide the assembly program and version in the form.");
28677     rval = FALSE;
28678   } else if (StringISearch (assem, "BLAST") != NULL) {
28679     Message (MSG_ERROR, "BLAST is not an assembly program. Please provide valid assembly program information.");
28680     rval = FALSE;
28681   } else {
28682     cp = StringISearch (assem, " v. ");
28683     if (cp == NULL) {
28684       len = StringLen (assem);
28685     } else {
28686       len = cp - assem;
28687     }
28688     for (i = 0; bad_assem[i] != NULL && rval; i++) {
28689       if (StringNICmp (assem, bad_assem[i], len) == 0) {
28690         Message (MSG_ERROR, "The assembly program name is not valid. Please enter the name of the program used to assemble these sequences.");
28691         rval = FALSE;
28692       }
28693     }
28694   }
28695   return rval;
28696 }
28697 
28698 
GetSequencingMethodPrefixForWizardType(EWizardType wizard_type)28699 static CharPtr GetSequencingMethodPrefixForWizardType (EWizardType wizard_type)
28700 {
28701   if (wizard_type == eWizardType_WGS) {
28702     return "Genome-Assembly-Data";
28703   } else {
28704     return "Assembly-Data";
28705   }
28706 }
28707 
28708 
IsSpecialTech(CharPtr tech)28709 static Boolean IsSpecialTech (CharPtr tech)
28710 {
28711   CharPtr cp;
28712   Int4    len;
28713   Boolean rval = FALSE;
28714 
28715   if (StringHasNoText (tech)) {
28716     rval = FALSE;
28717   } else {
28718     rval = TRUE;
28719     cp = StringChr (tech, ';');
28720     while (cp != NULL && rval) {
28721       len = cp - tech;
28722       if (StringNCmp (tech, "Sanger dideoxy sequencing", len) != 0
28723           && StringNICmp (tech, "ABI", 3) != 0) {
28724         rval = FALSE;
28725       } else {
28726         tech = cp + 1;
28727         while (isspace(*tech)) {
28728           tech++;
28729         }
28730         cp = StringChr (tech, ';');
28731       }
28732     }
28733     if (StringCmp (tech, "Sanger dideoxy sequencing") != 0
28734         && StringNICmp (tech, "ABI", 3) != 0) {
28735       rval = FALSE;
28736     }
28737   }
28738   return rval;
28739 }
28740 
28741 
IsSequencingMethodInfoValid(SequencingMethodInfoPtr info,Int4 num_sequences,Boolean required,Int4 wizard_type)28742 NLM_EXTERN Boolean IsSequencingMethodInfoValid (SequencingMethodInfoPtr info, Int4 num_sequences, Boolean required, Int4 wizard_type)
28743 {
28744   Boolean    sequencing_method_required = FALSE;
28745   ValNodePtr sc;
28746   ValNode    vn;
28747   CharPtr    tech, assem, coverage, a_name;
28748   Int4       i, opt;
28749   Boolean    rval = FALSE;
28750 
28751   sequencing_method_required = required;
28752   if (!sequencing_method_required) {
28753     sequencing_method_required = WantSequencingMethod (num_sequences);
28754   }
28755   if (info == NULL) {
28756     if (sequencing_method_required) {
28757       return FALSE;
28758     } else {
28759       return TRUE;
28760     }
28761   }
28762 
28763   sc = GetStructuredCommentFromList (info->structured_comments,
28764                                      GetSequencingMethodPrefixForWizardType(wizard_type));
28765   if (sc == NULL) {
28766     if (sequencing_method_required) {
28767       Message (MSG_ERROR, "Please select the sequencing technology used to obtain these sequences.");
28768       rval = FALSE;
28769     } else if (info->assembled_choice == 0) {
28770       /* allow to continue, because form completely empty */
28771       rval = TRUE;
28772     } else {
28773       Message (MSG_ERROR, "Please select the sequencing technology used to obtain these sequences.");
28774       rval = FALSE;
28775     }
28776   } else {
28777     MemSet (&vn, 0, sizeof (ValNode));
28778     vn.choice = StructuredCommentField_named;
28779     vn.data.ptrvalue = "Sequencing Technology";
28780     tech = GetStructuredCommentFieldFromUserObject (sc->data.ptrvalue, &vn, NULL);
28781     vn.data.ptrvalue = "Assembly Method";
28782     assem = GetStructuredCommentFieldFromUserObject (sc->data.ptrvalue, &vn, NULL);
28783     if (wizard_type == eWizardType_WGS) {
28784       vn.data.ptrvalue = "Genome Coverage";
28785     } else {
28786       vn.data.ptrvalue = "Coverage";
28787     }
28788     coverage = GetStructuredCommentFieldFromUserObject (sc->data.ptrvalue, &vn, NULL);
28789     vn.data.ptrvalue = "Assembly Name";
28790     a_name = GetStructuredCommentFieldFromUserObject (sc->data.ptrvalue, &vn, NULL);
28791     if (StringHasNoText (tech)) {
28792       Message (MSG_ERROR, "Please select the sequencing technology used to obtain these sequences.");
28793       rval = FALSE;
28794     } else if (IsSpecialTech(tech) && wizard_type != eWizardType_WGS) {
28795       rval = TRUE;
28796     } else if (info->assembled_choice == 0 && wizard_type != eWizardType_WGS) {
28797       Message (MSG_ERROR, "You must select whether the sequences are assembled or raw.");
28798       rval = FALSE;
28799     } else if (info->assembled_choice == 1) {
28800       rval = FALSE;
28801       opt = ThreeOptionsDlg ("Please submit to SRA",
28802         "Raw sequence reads generated by next generation sequencing technologies should be submitted to the Sequence Read Archive (SRA), not GenBank. Please see: http://trace.ncbi.nlm.nih.gov/Traces/sra/sra.cgi",
28803         "Exit Submission",
28804         "Change Options",
28805         NULL);
28806       if (opt == 1) {
28807         LaunchWebBrowser ("http://trace.ncbi.nlm.nih.gov/Traces/sra/sra.cgi");
28808         info->quit_now = TRUE;
28809       }
28810     } else if (StringHasNoText (assem)) {
28811       Message (MSG_ERROR, "Please provide the assembly program and version in the form.");
28812       rval = FALSE;
28813     } else if (StringISearch (coverage, "BLAST") != NULL) {
28814       Message (MSG_ERROR, "BLAST is not an assembly program. Please provide valid assembly program information.");
28815       rval = FALSE;
28816     } else if (!IsAssemblyMethodValid (assem)) {
28817       rval = FALSE;
28818     } else if (StringICmp (tech, "Sequencing Technology") == 0) {
28819       Message (MSG_ERROR, "Sequencing technology is not a valid answer. Please enter the specific type of technology used to obtain these sequences.");
28820       rval = FALSE;
28821     } else if (wizard_type == eWizardType_WGS && StringHasNoText (a_name)) {
28822       Message (MSG_ERROR, "You must enter an assembly name.");
28823       rval = FALSE;
28824     } else if (wizard_type == eWizardType_WGS && StringHasNoText (coverage)) {
28825       Message (MSG_ERROR, "You must enter the coverage.");
28826       rval = FALSE;
28827     } else {
28828       rval = TRUE;
28829       for (i = 0; bad_methods[i] != NULL && rval; i++) {
28830         if (StringICmp (tech, bad_methods[i]) == 0) {
28831           if (ANS_CANCEL == Message (MSG_OKC, "'%s' is not a sequencing technology. Please only enter the type of technology that was used to generate your sequences.", bad_methods[i])) {
28832             rval = FALSE;
28833           }
28834         }
28835       }
28836     }
28837     tech = MemFree (tech);
28838     assem = MemFree (assem);
28839     coverage = MemFree (coverage);
28840     a_name = MemFree (a_name);
28841   }
28842   return rval;
28843 }
28844 
28845 
IsSequencingMethodValid(WizardTrackerPtr wiz)28846 static Boolean IsSequencingMethodValid (WizardTrackerPtr wiz)
28847 {
28848   Boolean    rval = FALSE;
28849   SequencingMethodInfoPtr info;
28850 
28851   if (wiz == NULL) {
28852     return FALSE;
28853   }
28854 
28855   info = SequencingMethodInfoNew ();
28856   info->assembled_choice = wiz->assembled_choice;
28857   info->structured_comments = GetStructuredCommentFromList (wiz->structured_comments,
28858                                                             GetSequencingMethodPrefixForWizardType(wiz->wizard_type));
28859   info->quit_now = FALSE;
28860   rval = IsSequencingMethodInfoValid (info, CountSequencesAndSegments (wiz->sequences, TRUE),
28861                                       (wiz->wizard_type == eWizardType_WGS),
28862                                       wiz->wizard_type);
28863   wiz->quit_now = info->quit_now;
28864   info->structured_comments = NULL;
28865   info = SequencingMethodInfoFree (info);
28866 
28867   return rval;
28868 }
28869 
28870 
28871 static CharPtr SequenceMethodKeywords[] = {
28872   "454",
28873   "Complete Genomics",
28874   "Helicos",
28875   "Illumina",
28876   "IonTorrent",
28877   "PacBio",
28878   "Pacific Biosciences",
28879   "SOLiD",
28880   "pyrosequencing",
28881   "HiSeq",
28882   "transcriptome",
28883   "solexa",
28884   "deep sequencing",
28885   "deep-sequencing",
28886   "transcriptom",
28887   "next-gen",
28888   "RNA-Seq",
28889   "RNASeq",
28890   "RNA Seq",
28891   "high-throughput",
28892   "high throughput",
28893   "metagenom",
28894   "assembl",
28895   "raw seq",
28896   "next gen",
28897   NULL
28898 };
28899 
WantSequencingMethod(Int4 num_sequences)28900 NLM_EXTERN Boolean WantSequencingMethod (Int4 num_sequences)
28901 {
28902   Int4 i;
28903 
28904   /* if there are more than 500 sequences, then yes */
28905   if (num_sequences >= 500) {
28906     return TRUE;
28907   }
28908 
28909   /* keywords */
28910   for (i = 0; SequenceMethodKeywords[i] != NULL; i++) {
28911     if (StringISearch (globalsbp->citsubtitle, SequenceMethodKeywords[i]) != NULL) {
28912       return TRUE;
28913     }
28914   }
28915 
28916   return FALSE;
28917 }
28918 
28919 
28920 typedef struct wizardsourcetypeform {
28921   WIZARD_BLOCK
28922 
28923   GrouP source_type;
28924 
28925   EnumFieldAssocPtr type_list;
28926 } WizardSourceTypeFormData, PNTR WizardSourceTypeFormPtr;
28927 
28928 
CollectWizardSourceType(Pointer data,WizardTrackerPtr wiz)28929 static void CollectWizardSourceType (Pointer data, WizardTrackerPtr wiz)
28930 {
28931   WizardSourceTypeFormPtr frm;
28932   Int2 val, i;
28933 
28934   frm = (WizardSourceTypeFormPtr) data;
28935   if (frm == NULL) {
28936     return;
28937   }
28938 
28939   val = GetValue (frm->source_type);
28940 
28941   if (frm->type_list != NULL) {
28942     for (i = 0; i < val - 1 && frm->type_list[i].name != NULL; i++);
28943     switch (wiz->wizard_type) {
28944       case eWizardType_UnculturedSamples:
28945         break;
28946       case eWizardType_Viruses:
28947         if (val == 0 || frm->type_list[i].name == NULL) {
28948           wiz->virus_class = eVirusClass_Unknown;
28949         } else {
28950           wiz->virus_class = frm->type_list[i].value;
28951         }
28952         break;
28953       case eWizardType_CulturedSamples:
28954         if (val == 0 || frm->type_list[i].name == NULL) {
28955           wiz->cultured_kingdom = eCulturedKingdom_Unknown;
28956         } else {
28957           wiz->cultured_kingdom = frm->type_list[i].value;
28958         }
28959         break;
28960       case eWizardType_IGS:
28961         if (val == 0 || frm->type_list[i].name == NULL) {
28962           wiz->igs_source_type = eIGSSourceType_Unknown;
28963         } else {
28964           wiz->igs_source_type = frm->type_list[i].value;
28965         }
28966         break;
28967     }
28968   }
28969   wiz->extra_src_quals = ValNodeFreeData(wiz->extra_src_quals);
28970 }
28971 
28972 
HaveWizardSourceType(WizardTrackerPtr wiz)28973 static Boolean HaveWizardSourceType (WizardTrackerPtr wiz)
28974 {
28975   Boolean rval = TRUE;
28976   switch (wiz->wizard_type) {
28977     case eWizardType_Viruses:
28978       if (wiz->virus_class == eVirusClass_Unknown) {
28979         rval = FALSE;
28980       }
28981       break;
28982     case eWizardType_CulturedSamples:
28983       if (wiz->cultured_kingdom == eCulturedKingdom_Unknown) {
28984         rval = FALSE;
28985       }
28986       break;
28987     case eWizardType_IGS:
28988       if (wiz->igs_source_type == eIGSSourceType_Unknown) {
28989         rval = FALSE;
28990       }
28991       break;
28992   }
28993   if (!rval) {
28994     Message (MSG_ERROR, "Please select source type");
28995   }
28996   return rval;
28997 }
28998 
28999 
ENUM_ALIST(virus_source_type_alist)29000 ENUM_ALIST(virus_source_type_alist)
29001   {"Norovirus, Sapovirus (Caliciviridae)",               eVirusClass_Caliciviridae },
29002   {"Foot-and-mouth disease virus",                       eVirusClass_FootAndMouth  },
29003   {"Influenza virus",                                    eVirusClass_Influenza     },
29004   {"Rotavirus",                                          eVirusClass_Rotavirus     },
29005   {"Not listed above or mixed set of different viruses", eVirusClass_Generic       },
29006 END_ENUM_ALIST
29007 
29008 ENUM_ALIST(cultured_sample_source_type_alist)
29009   {"Cultured Bacteria or Archaea",                      eCulturedKingdom_BacteriaArchea  },
29010   {"Cultured Fungus",                                   eCulturedKingdom_CulturedFungus  },
29011   {"Vouchered Fungus",                                  eCulturedKingdom_VoucheredFungus },
29012   {"Something else",                                    eCulturedKingdom_Other           },
29013 END_ENUM_ALIST
29014 
29015 ENUM_ALIST(igs_source_type_alist)
29016 {"Cultured fungal samples",                             eIGSSourceType_CulturedFungus },
29017 {"Vouchered fungal samples",                            eIGSSourceType_VoucheredFungus },
29018 {"Plant",                                               eIGSSourceType_Plant  },
29019 {"Animal",                                              eIGSSourceType_Animal },
29020 END_ENUM_ALIST
29021 
29022 static Boolean WizardSourceTypeForm (WizardTrackerPtr wiz)
29023 {
29024   WizardSourceTypeFormPtr frm;
29025   WindoW w;
29026   GrouP  h;
29027   GrouP  c;
29028   CharPtr title = "Wizard - Source Type";
29029   CharPtr question = "Source type?";
29030   Int4 i;
29031 
29032   frm = (WizardSourceTypeFormPtr) MemNew (sizeof (WizardSourceTypeFormData));
29033   frm->wiz = wiz;
29034   frm->collect_func = CollectWizardSourceType;
29035   frm->fwd_ok_func = HaveWizardSourceType;
29036   frm->next_form = CreateWizardSrcQualsForm;
29037 
29038   switch (wiz->wizard_type) {
29039     case eWizardType_Viruses:
29040       title = "Virus Wizard Type of Virus";
29041       question = "Are all of your sequences from any of these viruses?";
29042       frm->type_list = virus_source_type_alist;
29043       SendHelpScrollMessage (helpForm, "Virus Wizard Type of Virus", "");
29044       break;
29045     case eWizardType_CulturedSamples:
29046       title = "rRNA-ITS-IGS Wizard Type of Source";
29047       question = "What are these sequences from?";
29048       frm->type_list = cultured_sample_source_type_alist;
29049       break;
29050     case eWizardType_IGS:
29051       title = "IGS Wizard Type of Source";
29052       question = "What are these sequences from?";
29053       frm->type_list = igs_source_type_alist;
29054       break;
29055   }
29056   w = FixedWindow (-50, -33, -10, -10, title, NULL);
29057   SetObjectExtra (w, frm, CleanupWizardForm);
29058   frm->form = (ForM) w;
29059 
29060   h = HiddenGroup (w, -1, -1, NULL);
29061   SetGroupSpacing (h, 10, 10);
29062 
29063   frm->source_type = NormalGroup (h, 0, 5, question, programFont, NULL);
29064   SetGroupSpacing (frm->source_type, 10, 10);
29065   for (i = 0; frm->type_list[i].name != NULL; i++) {
29066     RadioButton (frm->source_type, frm->type_list[i].name);
29067   }
29068 
29069   c = MakeWizardNav (h, frm);
29070 
29071   AlignObjects (ALIGN_CENTER, (HANDLE) frm->source_type, (HANDLE) c, NULL);
29072   Update();
29073   Show (w);
29074   SendHelpScrollMessage (helpForm, title, "");
29075   return TRUE;
29076 }
29077 
29078 
29079 typedef struct wizardcommentform {
29080   WIZARD_BLOCK
29081 
29082   GrouP yes_no;
29083   TexT comment;
29084 
29085 } WizardCommentFormData, PNTR WizardCommentFormPtr;
29086 
29087 
CollectWizardComment(Pointer data,WizardTrackerPtr wiz)29088 static void CollectWizardComment (Pointer data, WizardTrackerPtr wiz)
29089 {
29090   WizardCommentFormPtr frm;
29091 
29092   frm = (WizardCommentFormPtr) data;
29093   if (frm == NULL) {
29094     return;
29095   }
29096 
29097   wiz->comment = MemFree (wiz->comment);
29098   if (frm->yes_no == NULL || GetValue (frm->yes_no) == 1) {
29099     wiz->comment = SaveStringFromText (frm->comment);
29100   }
29101 }
29102 
29103 
ChangeWizardCommentChoice(GrouP g)29104 static void ChangeWizardCommentChoice (GrouP g)
29105 {
29106   WizardCommentFormPtr frm;
29107 
29108   frm = (WizardCommentFormPtr) GetObjectExtra (g);
29109   if (frm == NULL) {
29110     return;
29111   }
29112 
29113   if (GetValue (frm->yes_no) == 1) {
29114     Show (frm->comment);
29115   } else {
29116     Hide (frm->comment);
29117   }
29118 }
29119 
29120 
29121 static const CharPtr s_WizardCommentTxt = "Is there any other information you want to provide? For example lineage, passage history, or other source information.";
29122 
WizardCommentForm(WizardTrackerPtr wiz)29123 static Boolean WizardCommentForm (WizardTrackerPtr wiz)
29124 {
29125   WizardCommentFormPtr frm;
29126   WindoW w;
29127   GrouP  h;
29128   GrouP  p_msg;
29129   GrouP  c;
29130 
29131   frm = (WizardCommentFormPtr) MemNew (sizeof (WizardCommentFormData));
29132   frm->wiz = wiz;
29133   frm->collect_func = CollectWizardComment;
29134   frm->fwd_ok_func = OkToContinueToSequin;
29135   frm->next_form = FinishWizardAndLaunchSequin;
29136 
29137   w = FixedWindow (-50, -33, -10, -10, "Extra Comments", NULL);
29138   SetObjectExtra (w, frm, CleanupWizardForm);
29139   frm->form = (ForM) w;
29140 
29141   h = HiddenGroup (w, -1, -1, NULL);
29142   SetGroupSpacing (h, 10, 10);
29143 
29144   p_msg = MultiLinePrompt (h, s_WizardCommentTxt, 750, systemFont);
29145 
29146   frm->yes_no = HiddenGroup (h, 2, 0, ChangeWizardCommentChoice);
29147   SetObjectExtra (frm->yes_no, frm, NULL);
29148   RadioButton (frm->yes_no, "Yes");
29149   RadioButton (frm->yes_no, "No");
29150   SetValue (frm->yes_no, 2);
29151   frm->comment = ScrollText (h, 25, 5, programFont, TRUE, NULL);
29152   Hide (frm->comment);
29153 
29154   c = MakeWizardNav (h, frm);
29155 
29156   AlignObjects (ALIGN_CENTER, (HANDLE) p_msg,
29157                               (HANDLE) frm->yes_no,
29158                               (HANDLE) frm->comment,
29159                               (HANDLE) c, NULL);
29160   Update();
29161   Show (w);
29162   return TRUE;
29163 }
29164 
29165 
HaveComment(WizardTrackerPtr wiz)29166 static Boolean HaveComment (WizardTrackerPtr wiz)
29167 {
29168   if (wiz == NULL) {
29169     return FALSE;
29170   }
29171   if (StringHasNoText (wiz->comment)) {
29172     Message (MSG_ERROR, "You must provide a description of the assembly.");
29173     return FALSE;
29174   } else {
29175     return TRUE;
29176   }
29177 }
29178 
29179 
WizardAssemblyDescriptionForm(WizardTrackerPtr wiz)29180 static Boolean WizardAssemblyDescriptionForm (WizardTrackerPtr wiz)
29181 {
29182   WizardCommentFormPtr frm;
29183   WindoW w;
29184   GrouP  h;
29185   GrouP  p_msg;
29186   GrouP  c;
29187   CharPtr dlg_title = "TSA Wizard Assembly Description";
29188 
29189   frm = (WizardCommentFormPtr) MemNew (sizeof (WizardCommentFormData));
29190   frm->wiz = wiz;
29191   frm->collect_func = CollectWizardComment;
29192   frm->fwd_ok_func = HaveComment;
29193   frm->next_form = BioProjectBioSampleWindow;
29194 
29195   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
29196   SetObjectExtra (w, frm, CleanupWizardForm);
29197   frm->form = (ForM) w;
29198 
29199   h = HiddenGroup (w, -1, -1, NULL);
29200   SetGroupSpacing (h, 10, 10);
29201 
29202   p_msg = MultiLinePrompt (h, "Please provide a description of your assembly", 750, systemFont);
29203 
29204   frm->comment = ScrollText (h, 25, 5, programFont, TRUE, NULL);
29205 
29206   c = MakeWizardNav (h, frm);
29207 
29208   AlignObjects (ALIGN_CENTER, (HANDLE) p_msg,
29209                               (HANDLE) frm->comment,
29210                               (HANDLE) c, NULL);
29211   Update();
29212   Show (w);
29213   SendHelpScrollMessage (helpForm, dlg_title, "");
29214 
29215   return TRUE;
29216 }
29217 
29218 
29219 typedef struct wizardgenomeform {
29220   WIZARD_BLOCK
29221 
29222   GrouP genome_type;
29223   PopuP extra_locations;
29224 } WizardGenomeFormData, PNTR WizardGenomeFormPtr;
29225 
29226 
ENUM_ALIST(genome_alist)29227 static ENUM_ALIST(genome_alist)
29228 {"chromoplast",         GENOME_chromoplast  },
29229 {"kinetoplast",         GENOME_kinetoplast  },
29230 {"plastid",             GENOME_plastid   },
29231 {"macronuclear",        GENOME_macronuclear   },
29232 {"cyanelle",            GENOME_cyanelle   },
29233 {"nucleomorph",         GENOME_nucleomorph   },
29234 {"apicoplast",          GENOME_apicoplast   },
29235 {"leucoplast",          GENOME_leucoplast    },
29236 {"proplastid",          GENOME_proplastid    },
29237 {"hydrogenosome",       GENOME_hydrogenosome    },
29238 {"chromatophore",       GENOME_chromatophore    },
29239 END_ENUM_ALIST
29240 
29241 static void SaveWizardGenomeChoice (Pointer data, WizardTrackerPtr wiz)
29242 {
29243   WizardGenomeFormPtr frm;
29244   Int2                         val;
29245   UIEnum                       other_val;
29246 
29247   frm = (WizardGenomeFormPtr) data;
29248   if (frm == NULL) {
29249     return;
29250   }
29251 
29252   val = GetValue (frm->genome_type);
29253   if ((wiz->cultured_kingdom == eCulturedKingdom_CulturedFungus || wiz->cultured_kingdom == eCulturedKingdom_VoucheredFungus)
29254        && val >= 3) {
29255     val++;
29256   }
29257   switch (val) {
29258     case 1:
29259       wiz->genome = GENOME_unknown;
29260       break;
29261     case 2:
29262       wiz->genome = GENOME_mitochondrion;
29263       break;
29264     case 3:
29265       wiz->genome = GENOME_chloroplast;
29266       break;
29267     case 4:
29268       if (GetEnumPopup (frm->extra_locations, genome_alist, &other_val)) {
29269         wiz->genome = (Uint1) other_val;
29270       }
29271       break;
29272     case 0:
29273       wiz->genome = 255;
29274       break;
29275     default:
29276       wiz->genome = GENOME_unknown;
29277       break;
29278   }
29279 }
29280 
29281 
ChangeWizardGenomeChoice(GrouP g)29282 static void ChangeWizardGenomeChoice (GrouP g)
29283 {
29284   WizardGenomeFormPtr frm;
29285   Int2 val;
29286 
29287   frm = (WizardGenomeFormPtr) GetObjectExtra (g);
29288   if (frm == NULL) {
29289     return;
29290   }
29291 
29292   val = GetValue (frm->genome_type);
29293   if ((frm->wiz->cultured_kingdom == eCulturedKingdom_CulturedFungus || frm->wiz->cultured_kingdom == eCulturedKingdom_VoucheredFungus) && val >= 3) {
29294     val++;
29295   }
29296   if (val == 4) {
29297     Enable (frm->extra_locations);
29298   } else {
29299     Disable (frm->extra_locations);
29300   }
29301 }
29302 
29303 
HaveWizardGenome(WizardTrackerPtr wiz)29304 static Boolean HaveWizardGenome (WizardTrackerPtr wiz)
29305 {
29306   if (wiz == NULL) {
29307     return FALSE;
29308   }
29309 
29310   if (wiz->genome == 255) {
29311     Message (MSG_ERROR, "You must select the genome.");
29312     return FALSE;
29313   } else {
29314     return TRUE;
29315   }
29316 }
29317 
29318 
CreateWizardGenomeForm(WizardTrackerPtr wiz)29319 static Boolean CreateWizardGenomeForm (WizardTrackerPtr wiz)
29320 {
29321   WizardGenomeFormPtr frm;
29322   WindoW  w;
29323   GrouP   h;
29324   GrouP   c;
29325   PrompT  ppt;
29326   CharPtr title = "Wizard Genome";
29327 
29328   if (wiz->wizard_type == eWizardType_CulturedSamples) {
29329     title = "rRNA-ITS-IGS Wizard Genome";
29330   } else if (wiz->wizard_type == eWizardType_IGS) {
29331     title = "IGS Wizard Genome";
29332   }
29333 
29334   frm = (WizardGenomeFormPtr) MemNew (sizeof (WizardGenomeFormData));
29335   frm->wiz = wiz;
29336   frm->collect_func = SaveWizardGenomeChoice;
29337   frm->fwd_ok_func = HaveWizardGenome;
29338   frm->next_form = CreateWizardAnnotationChoiceForm;
29339 
29340   w = FixedWindow (-50, -33, -10, -10, title, NULL);
29341   SetObjectExtra (w, frm, CleanupWizardForm);
29342   frm->form = (ForM) w;
29343 
29344   h = HiddenGroup (w, -1, -1, NULL);
29345   SetGroupSpacing (h, 10, 10);
29346 
29347   ppt = StaticPrompt (h, "Which genome are your sequences derived from?", 0, 0, programFont, 'c');
29348 
29349   frm->genome_type = HiddenGroup (h, 0, 5, ChangeWizardGenomeChoice);
29350   SetObjectExtra (frm->genome_type, frm, NULL);
29351   RadioButton (frm->genome_type, "Nuclear");
29352   RadioButton (frm->genome_type, "Mitochondrial");
29353   if (wiz->igs_source_type == eIGSSourceType_Plant
29354       || wiz->cultured_kingdom == eCulturedKingdom_BacteriaArchea
29355       || wiz->cultured_kingdom == eCulturedKingdom_Other) {
29356     RadioButton (frm->genome_type, "Chloroplast");
29357     /* TODO - add pulldown with other locations */
29358     RadioButton (frm->genome_type, "Other");
29359 
29360     frm->extra_locations = PopupList (frm->genome_type, TRUE, NULL);
29361     InitEnumPopup (frm->extra_locations, genome_alist, NULL);
29362     SetValue (frm->extra_locations, 1);
29363     Disable (frm->extra_locations);
29364   }
29365 
29366   wiz->genome = 255;
29367 
29368   c = MakeWizardNav (h, frm);
29369 
29370   AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
29371                               (HANDLE) frm->genome_type,
29372                               (HANDLE) c,
29373                               NULL);
29374 
29375   Update();
29376   Show (w);
29377   SendHelpScrollMessage (helpForm, title, "");
29378 
29379   return TRUE;
29380 }
29381 
29382 
29383 typedef struct wizardmoleculeform {
29384   WIZARD_BLOCK
29385 
29386   GrouP  question;
29387   GrouP  no_grp;
29388   PopuP  genomes;
29389   PopuP  types;
29390 } WizardMoleculeFormData, PNTR WizardMoleculeFormPtr;
29391 
29392 
ENUM_ALIST(molecule_genome_alist)29393 static ENUM_ALIST(molecule_genome_alist)
29394 {" ",                   255 } ,
29395 {"nucleus",             GENOME_genomic } ,
29396 {"mitochondrion",       GENOME_mitochondrion } ,
29397 {"chloroplast",         GENOME_chloroplast  },
29398 {"plastid",             GENOME_plastid   },
29399 END_ENUM_ALIST
29400 
29401 static void SaveWizardMoleculeChoice (Pointer data, WizardTrackerPtr wiz)
29402 {
29403   WizardMoleculeFormPtr frm;
29404   Int2                         val;
29405   UIEnum                       other_val;
29406 
29407   frm = (WizardMoleculeFormPtr) data;
29408   if (frm == NULL) {
29409     return;
29410   }
29411 
29412   val = GetValue (frm->question);
29413   if (val == 1) {
29414     if (wiz->molinfo == NULL) {
29415       wiz->molinfo = MolInfoNew ();
29416     }
29417     wiz->molinfo->biomol = MOLECULE_TYPE_GENOMIC;
29418     wiz->mol_class = Seq_mol_dna;
29419     wiz->genome = GENOME_genomic;
29420   } else if (val == 2) {
29421     val = GetValue (frm->types);
29422     if (val == 0) {
29423       wiz->genome = 255;
29424     } else if (GetEnumPopup (frm->genomes, molecule_genome_alist, &other_val) && other_val != 255) {
29425       wiz->genome = other_val;
29426       if (wiz->molinfo == NULL) {
29427         wiz->molinfo = MolInfoNew ();
29428       }
29429       if (val == 1) {
29430         wiz->molinfo->biomol = MOLECULE_TYPE_GENOMIC;
29431         wiz->mol_class = Seq_mol_dna;
29432       } else {
29433         wiz->molinfo->biomol = MOLECULE_TYPE_MRNA;
29434         wiz->mol_class = Seq_mol_rna;
29435       }
29436     } else {
29437       wiz->genome = 255;
29438     }
29439   } else {
29440     wiz->genome = 255;
29441   }
29442 }
29443 
29444 
ChangeWizardMoleculeChoice(GrouP g)29445 static void ChangeWizardMoleculeChoice (GrouP g)
29446 {
29447   WizardMoleculeFormPtr frm;
29448   Int2 val;
29449 
29450   frm = (WizardMoleculeFormPtr) GetObjectExtra (g);
29451   if (frm == NULL) {
29452     return;
29453   }
29454 
29455   val = GetValue (frm->question);
29456   if (val == 2) {
29457     Enable (frm->no_grp);
29458   } else {
29459     Disable (frm->no_grp);
29460   }
29461 }
29462 
29463 
HaveWizardMolecule(WizardTrackerPtr wiz)29464 static Boolean HaveWizardMolecule (WizardTrackerPtr wiz)
29465 {
29466   if (wiz == NULL) {
29467     return FALSE;
29468   }
29469 
29470   if (wiz->genome == 255) {
29471     Message (MSG_ERROR, "You must select the genome and molecule type.");
29472     return FALSE;
29473   } else {
29474     return TRUE;
29475   }
29476 }
29477 
29478 
CreateWizardMoleculeForm(WizardTrackerPtr wiz)29479 static Boolean CreateWizardMoleculeForm (WizardTrackerPtr wiz)
29480 {
29481   WizardMoleculeFormPtr frm;
29482   WindoW  w;
29483   GrouP   h, g;
29484   GrouP   c;
29485   GrouP   txt;
29486   PrompT  ppt;
29487   CharPtr title = GetWizardDlgTitle (wiz->wizard_type, eWizardDlgTitle_Molecule);
29488 
29489   frm = (WizardMoleculeFormPtr) MemNew (sizeof (WizardMoleculeFormData));
29490   frm->wiz = wiz;
29491   frm->collect_func = SaveWizardMoleculeChoice;
29492   frm->fwd_ok_func = HaveWizardMolecule;
29493   frm->next_form = CreateMicrosatelliteAnnotationTypeForm;
29494 
29495   w = FixedWindow (-50, -33, -10, -10, title, NULL);
29496   SetObjectExtra (w, frm, CleanupWizardForm);
29497   frm->form = (ForM) w;
29498 
29499   h = HiddenGroup (w, -1, -1, NULL);
29500   SetGroupSpacing (h, 10, 10);
29501 
29502   ppt = StaticPrompt (h, "Are these sequences from genomic DNA from the nucleus?", 0, 0, programFont, 'c');
29503   frm->question = HiddenGroup (h, 0, 2, ChangeWizardMoleculeChoice);
29504   SetObjectExtra (frm->question, frm, NULL);
29505   SetGroupSpacing (frm->question, 10, 10);
29506   RadioButton (frm->question, "Yes");
29507   RadioButton (frm->question, "No");
29508   SetValue (frm->question, 1);
29509 
29510   frm->no_grp = HiddenGroup (h, -1, -1, NULL);
29511   SetGroupSpacing (frm->no_grp, 10, 10);
29512   txt = MultiLinePrompt (frm->no_grp,
29513     "Please select the genome and type of molecule from which these sequences \
29514 are derived. For example, if you isolated chloroplast DNA, \
29515 select genome: chloroplast and molecule type: genomic DNA.",
29516      30 * stdCharWidth, systemFont);
29517   g = HiddenGroup (frm->no_grp, 2, 0, NULL);
29518   SetGroupSpacing (g, 10, 10);
29519   StaticPrompt (g, "Genome:", 0, 0, programFont, 'c');
29520   frm->genomes = PopupList (g, TRUE, NULL);
29521   InitEnumPopup (frm->genomes, molecule_genome_alist, NULL);
29522   StaticPrompt (g, "Molecule Type:", 0, 0, programFont, 'c');
29523   frm->types = PopupList (g, TRUE, NULL);
29524   PopupItem (frm->types, "genomic DNA");
29525   PopupItem (frm->types, "mRNA");
29526   Disable (frm->no_grp);
29527 
29528   AlignObjects (ALIGN_CENTER, (HANDLE) txt, (HANDLE) g, NULL);
29529 
29530   wiz->genome = 255;
29531 
29532   c = MakeWizardNav (h, frm);
29533 
29534   AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
29535                               (HANDLE) frm->question,
29536                               (HANDLE) frm->no_grp,
29537                               (HANDLE) c,
29538                               NULL);
29539 
29540   Update();
29541   Show (w);
29542   SendHelpScrollMessage (helpForm, title, "");
29543 
29544   return TRUE;
29545 }
29546 
29547 
29548 
29549 
29550 static WizardChoiceData virus_annotation_choice_list[] = {
29551   { "Single coding region across the entire sequence", NULL, UnculturedSamplesCodingRegionForm } ,
29552   { "Single non-coding feature across the entire sequence", NULL, CreateVirusNoncodingForm } ,
29553   { "Multiple features per sequence (coding regions, LTRs, etc.)", OkToContinueToSequin, FinishWizardAndLaunchSequin },
29554   { NULL, NULL, NULL }
29555 };
29556 
29557 static WizardChoiceData virus_annotation_influenza_single_segment_choice_list[] = {
29558   { "Single coding region across the entire sequence", NULL, UnculturedSamplesCodingRegionForm } ,
29559   { "Multiple features per sequence (coding regions, LTRs, etc.)", NULL, CreateVirusFeatureTableForm },
29560   { NULL, NULL, NULL }
29561 };
29562 
29563 
29564 
CreateVirusAnnotationForm(WizardTrackerPtr wiz)29565 static Boolean CreateVirusAnnotationForm (WizardTrackerPtr wiz)
29566 {
29567   CharPtr dlg_title;
29568   Boolean rval;
29569 
29570   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
29571   ResetWizardTrackerVirusFeat (wiz);
29572   if (wiz->virus_class == eVirusClass_Influenza) {
29573     if (DoAllSequencesHaveSameModifierValue (wiz->sequences, "segment")) {
29574       rval = CreateWizardSingleChoiceForm (wiz, virus_annotation_influenza_single_segment_choice_list,
29575                                            dlg_title, "What do your sequences contain?");
29576     } else {
29577       rval = CreateVirusFeatureTableForm (wiz);
29578     }
29579   } else {
29580     rval = CreateWizardSingleChoiceForm (wiz, virus_annotation_choice_list,
29581                                          dlg_title, "What do your sequences contain?");
29582   }
29583   SendHelpScrollMessage (helpForm, dlg_title, "");
29584   return rval;
29585 }
29586 
29587 
29588 static WizardChoiceData cultured_sample_bacteria_annotation_choice_list[] = {
29589   { "Single rRNA or IGS", NULL, SingleBacteriaArchaeaFeat } ,
29590   { "Multiple rRNA or IGS where spans are unknown", NULL, MultBacteriaArchaeaFeat } ,
29591   { "Multiple rRNA or IGS where spans are known", NULL, ShowCulturedRNAFeatTableHelpAndContinueToSequin } ,
29592   { "Something else", OkToContinueToSequin, FinishWizardAndLaunchSequin } ,
29593   { NULL, NULL, NULL }
29594 };
29595 
29596 
29597 static WizardChoiceData cultured_sample_nonbacteria_nonorganelle_annotation_choice_list[] = {
29598   { "Single rRNA or ITS", NULL, SingleFungalFeat } ,
29599   { "Multiple rRNA or ITS where spans are unknown", NULL, MultFungalFeat } ,
29600   { "Multiple rRNA or ITS where spans are known", NULL, ShowCulturedRNAFeatTableHelpAndContinueToSequin } ,
29601   { "Something else", OkToContinueToSequin, FinishWizardAndLaunchSequin } ,
29602   { NULL, NULL, NULL }
29603 };
29604 
29605 
29606 static WizardChoiceData cultured_sample_nonbacteria_organelle_annotation_choice_list[] = {
29607   { "Single rRNA", NULL, SingleOrganelleFeat } ,
29608   { "Something else", OkToContinueToSequin, FinishWizardAndLaunchSequin } ,
29609   { NULL, NULL, NULL }
29610 };
29611 
29612 
29613 static WizardChoiceData igs_annotation_choice_list[] = {
29614   { "Intergenic spacer only", NULL, SingleIGSFeat } ,
29615   { "Intergenic spacer and other features (gene, tRNA) where spans are unknown", NULL, MultipleIGSFeatSpansUnknown } ,
29616   { "Intergenic spacers and other features (gene, tRNA) where spans are known", OkToContinueToSequin, FinishWizardAndLaunchSequin },
29617   { "Something else", OkToContinueToSequin, FinishWizardAndLaunchSequin },
29618   { NULL, NULL, NULL }
29619 };
29620 
29621 
29622 static WizardChoiceData uncultured_annotation_choice_list[] = {
29623   { "Single rRNA, ITS, or IGS", NULL, SingleRNAOrgWindow } ,
29624   { "Multiple rRNA, ITS, or IGS regions where spans are unknown", NULL, MultRNAOrgWindow } ,
29625   { "Multiple rRNA, ITS, or IGS regions where spans are known", NULL, ShowRNAFeatureTableInstructionsAndContinueToSequin },
29626   { "Intergenic spacer (not rRNA-IGS)", NULL, CreateIGSWizardAnnotationChoiceForm },
29627   { "Coding Region (CDS)", NULL, UnculturedSamplesCodingRegionForm } ,
29628   { "Something else/multiple features", OkToContinueToSequin, FinishWizardAndLaunchSequin },
29629   { NULL, NULL, NULL }
29630 };
29631 
29632 
29633 static WizardChoiceData dloop_annotation_choice_list1 [] = {
29634   { "D-loop only", CheckDLoopSequenceLengthAndOkToContinueToSequin, MakeDLoopAndContinueToSequin } ,
29635   { "Control region only", CheckDLoopSequenceLengthAndOkToContinueToSequin, MakeControlRegionAndContinueToSequin } ,
29636   { "D-loop/Control Region and other features (tRNA, rRNA)", NULL, CreateDLoopAnnotationChoiceForm },
29637   { NULL, NULL, NULL }
29638 };
29639 
CreateIGSWizardAnnotationChoiceForm(WizardTrackerPtr wiz)29640 static Boolean CreateIGSWizardAnnotationChoiceForm (WizardTrackerPtr wiz)
29641 {
29642   Boolean rval;
29643   CharPtr dlg_title;
29644 
29645   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
29646   ResetWizardTrackerCulturedSamplesFeat (wiz);
29647   /* must set spans_unknown after this point, if backing through, unset */
29648   wiz->spans_unknown = FALSE;
29649   rval = CreateWizardSingleChoiceForm (wiz, igs_annotation_choice_list,
29650                                        dlg_title, "What do your sequences contain?");
29651   SendHelpScrollMessage (helpForm, dlg_title, "");
29652   return rval;
29653 }
29654 
29655 
CreateWizardAnnotationChoiceForm(WizardTrackerPtr wiz)29656 static Boolean CreateWizardAnnotationChoiceForm (WizardTrackerPtr wiz)
29657 {
29658   Boolean rval;
29659   CharPtr dlg_title;
29660 
29661   dlg_title = GetWizardDlgTitle(wiz->wizard_type, eWizardDlgTitle_Annotation);
29662   ResetWizardTrackerCulturedSamplesFeat (wiz);
29663   /* must set spans_unknown after this point, if backing through, unset */
29664   wiz->spans_unknown = FALSE;
29665   wiz->use_alternate_leaving_msg = FALSE;
29666 
29667   if (wiz->wizard_type == eWizardType_DLoop) {
29668       rval = CreateWizardSingleChoiceForm (wiz, dloop_annotation_choice_list1,
29669                                            dlg_title, "What do your sequences contain?");
29670   } else if (wiz->igs_source_type != eIGSSourceType_Unknown) {
29671     rval = CreateWizardSingleChoiceForm (wiz, igs_annotation_choice_list,
29672                                          dlg_title, "What do your sequences contain?");
29673   } else if (wiz->wizard_type == eWizardType_UnculturedSamples) {
29674     rval = CreateWizardSingleChoiceForm (wiz, uncultured_annotation_choice_list,
29675                                          dlg_title, "What do your sequences contain?");
29676   } else if (wiz->cultured_kingdom == eCulturedKingdom_BacteriaArchea) {
29677     rval = CreateWizardSingleChoiceForm (wiz, cultured_sample_bacteria_annotation_choice_list,
29678                                          dlg_title, "What do your sequences contain?");
29679   } else if (wiz->genome == GENOME_unknown) {
29680     rval = CreateWizardSingleChoiceForm (wiz, cultured_sample_nonbacteria_nonorganelle_annotation_choice_list,
29681                                          dlg_title, "What do your sequences contain?");
29682   } else {
29683     rval = CreateWizardSingleChoiceForm (wiz, cultured_sample_nonbacteria_organelle_annotation_choice_list,
29684                                          dlg_title, "What do your sequences contain?");
29685   }
29686   SendHelpScrollMessage (helpForm, dlg_title, "");
29687   return rval;
29688 }
29689 
29690 
WGSWizardBacteria(WizardTrackerPtr wiz)29691 static Boolean WGSWizardBacteria (WizardTrackerPtr wiz)
29692 {
29693   wiz->wgs_source_type = eWGSSourceType_Bacteria;
29694   return CreateWizardSourceAvailabilityForm(wiz);
29695 }
29696 
29697 
WGSWizardFungi(WizardTrackerPtr wiz)29698 static Boolean WGSWizardFungi (WizardTrackerPtr wiz)
29699 {
29700   wiz->wgs_source_type = eWGSSourceType_Fungi;
29701   return BioProjectBioSampleWindow(wiz);
29702 }
29703 
29704 
WGSWizardOtherEuk(WizardTrackerPtr wiz)29705 static Boolean WGSWizardOtherEuk (WizardTrackerPtr wiz)
29706 {
29707   wiz->wgs_source_type = eWGSSourceType_OtherEuk;
29708   return BioProjectBioSampleWindow(wiz);
29709 }
29710 
29711 
29712 static WizardChoiceData wgs_source_choice_list[] = {
29713   { "Bacteria", NULL, WGSWizardBacteria } ,
29714   { "Fungi", NULL, WGSWizardFungi },
29715   { "Other eukaryote", NULL, WGSWizardOtherEuk },
29716   { NULL, NULL, NULL }
29717 };
29718 
CreateWGSWizardSourceTypeForm(WizardTrackerPtr wiz)29719 static Boolean CreateWGSWizardSourceTypeForm (WizardTrackerPtr wiz)
29720 {
29721   return CreateWizardSingleChoiceForm (wiz, wgs_source_choice_list, "WGS Source Type", "What type of organism are your sequences from?");
29722 }
29723 
29724 
HasIGSFeatInfoAndOkToContinueToSequin(WizardTrackerPtr wiz)29725 static Boolean HasIGSFeatInfoAndOkToContinueToSequin (WizardTrackerPtr wiz)
29726 {
29727   if (wiz == NULL || StringHasNoText (wiz->misc_feat_comment)) {
29728     Message (MSG_ERROR, "Please complete the form");
29729     return FALSE;
29730   } else {
29731     return OkToContinueToSequin(wiz);
29732   }
29733 }
29734 
29735 
29736 typedef struct singleigsfeatform {
29737   WIZARD_BLOCK
29738   TexT gene_5;
29739   TexT gene_3;
29740   GrouP partial_choice;
29741 } SingleIGSFeatFormData, PNTR SingleIGSFeatFormPtr;
29742 
CollectSingleIGSFeat(Pointer data,WizardTrackerPtr wiz)29743 static void CollectSingleIGSFeat (Pointer data, WizardTrackerPtr wiz)
29744 {
29745   SingleIGSFeatFormPtr frm;
29746   CharPtr        gene5, gene3;
29747   CharPtr        fmt = "%s-%s intergenic spacer";
29748   Int4           len;
29749 
29750   frm = (SingleIGSFeatFormPtr) data;
29751   if (frm == NULL || wiz == NULL) {
29752     return;
29753   }
29754 
29755   wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
29756   if (TextHasNoText (frm->gene_5) || TextHasNoText (frm->gene_3) || GetValue (frm->partial_choice) == 0) {
29757     /* do nothing, insufficient information */
29758   } else {
29759     gene5 = SaveStringFromText (frm->gene_5);
29760     gene3 = SaveStringFromText (frm->gene_3);
29761     len = StringLen (gene5) + StringLen (gene3) + StringLen (fmt);
29762     wiz->misc_feat_comment = (CharPtr) MemNew (sizeof (Char) * len);
29763     sprintf (wiz->misc_feat_comment, fmt, gene5, gene3);
29764     gene5 = MemFree (gene5);
29765     gene3 = MemFree (gene3);
29766     switch (GetValue (frm->partial_choice)) {
29767       case 1:
29768         wiz->partial5 = FALSE;
29769         wiz->partial3 = FALSE;
29770         break;
29771       case 2:
29772         wiz->partial5 = TRUE;
29773         wiz->partial3 = TRUE;
29774         break;
29775       case 3:
29776         wiz->partial5 = TRUE;
29777         wiz->partial3 = FALSE;
29778         break;
29779       case 4:
29780         wiz->partial5 = FALSE;
29781         wiz->partial3 = TRUE;
29782         break;
29783     }
29784   }
29785 
29786 }
29787 
29788 
SingleIGSFeat(WizardTrackerPtr wiz)29789 static Boolean SingleIGSFeat(WizardTrackerPtr wiz)
29790 {
29791   SingleIGSFeatFormPtr frm;
29792   WindoW w;
29793   GrouP  h;
29794   GrouP  g, g_inside, c;
29795   CharPtr dlg_title;
29796 
29797   frm = (SingleIGSFeatFormPtr) MemNew (sizeof (SingleIGSFeatFormData));
29798   frm->wiz = wiz;
29799 
29800   dlg_title = "Intergenic Spacer Annotation";
29801   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
29802   SetObjectExtra (w, frm, CleanupWizardForm);
29803   frm->form = (ForM) w;
29804   frm->collect_func = CollectSingleIGSFeat;
29805   frm->fwd_ok_func = HasIGSFeatInfoAndOkToContinueToSequin;
29806   frm->next_form = FinishWizardAndLaunchSequin;
29807 
29808   h = HiddenGroup (w, -1, -1, NULL);
29809   SetGroupSpacing (h, 10, 10);
29810 
29811   g = NormalGroup (h, -1, 0, "What features flank the intergenic spacer?", programFont, NULL);
29812   SetGroupSpacing (g, 10, 10);
29813   StaticPrompt (g, " ", 0, 0, programFont, 'c');
29814   g_inside = HiddenGroup (g, 2, 0, NULL);
29815   SetGroupSpacing (g_inside, 10, 10);
29816   StaticPrompt (g_inside, "5' gene symbol", 0, 0, programFont, 'c');
29817   StaticPrompt (g_inside, "3' gene symbol", 0, 0, programFont, 'c');
29818   StaticPrompt (g_inside, "Example: trnL", 0, 0, programFont, 'c');
29819   StaticPrompt (g_inside, "Example: trnF", 0, 0, programFont, 'c');
29820   frm->gene_5 = DialogText (g_inside, "", 10, NULL);
29821   frm->gene_3 = DialogText (g_inside, "", 10, NULL);
29822 
29823   frm->partial_choice = NormalGroup (h, 1, 0, "Is the intergenic spacer complete or incomplete at the ends of your sequences?", programFont, NULL);
29824   RadioButton (frm->partial_choice, "All sequences are 5' and 3' complete");
29825   RadioButton (frm->partial_choice, "All sequences are 5' and 3' partial");
29826   RadioButton (frm->partial_choice, "All sequences are 5' partial, 3' complete");
29827   RadioButton (frm->partial_choice, "All sequences are 5' complete, 3' partial");
29828 
29829   c = MakeWizardNav (h, frm);
29830 
29831 
29832   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) frm->partial_choice, (HANDLE) c, NULL);
29833 
29834   Update();
29835   Show (w);
29836   SendHelpScrollMessage (helpForm, "IGS Wizard Annotation", "Intergenic spacer only");
29837   return TRUE;
29838 }
29839 
29840 
29841 typedef struct igsflankdlg {
29842   DIALOG_MESSAGE_BLOCK
29843   GrouP trna_or_prot;
29844   GrouP trna_grp;
29845   PopuP trna;
29846   GrouP prot_grp;
29847   TexT  gene;
29848   TexT  protein;
29849 } IGSFlankDlgData, PNTR IGSFlankDlgPtr;
29850 
29851 
PopulateAAPopup(PopuP trna)29852 static void PopulateAAPopup (PopuP trna)
29853 
29854 {
29855   Char             ch;
29856   Uint1            first;
29857   Uint1            i;
29858   Char             item [77];
29859   Uint1            last;
29860   SeqCodeTablePtr  sctp;
29861   CharPtr          str;
29862 
29863   sctp = SeqCodeTableFind (Seq_code_ncbieaa);
29864   first = FirstResidueInCode (sctp);
29865   last = LastResidueInCode (sctp);
29866   PopupItem (trna, " ");
29867   for (i = 65; i <= last; i++) {
29868     ch = GetSymbolForResidue (sctp, i);
29869     str = (CharPtr) GetNameForResidue (sctp, i);
29870     sprintf (item, "%c    %s", ch, str);
29871     PopupItem (trna, item);
29872   }
29873   SetValue (trna, 1);
29874 }
29875 
29876 
GeneSymbolFromIGSFlankDlg(DialoG d)29877 static CharPtr GeneSymbolFromIGSFlankDlg (DialoG d)
29878 {
29879   IGSFlankDlgPtr   dlg;
29880   SeqCodeTablePtr  sctp;
29881   Char             ch;
29882   CharPtr  name = NULL;
29883   Int2     i;
29884 
29885   dlg = (IGSFlankDlgPtr) GetObjectExtra(d);
29886   if (dlg == NULL) {
29887     return NULL;
29888   }
29889 
29890   switch (GetValue (dlg->trna_or_prot)) {
29891     case 1:
29892       /* trna */
29893       i = GetValue (dlg->trna) - 1;
29894       if (i > 0) {
29895         sctp = SeqCodeTableFind (Seq_code_ncbieaa);
29896         ch = GetSymbolForResidue (sctp, i + 64);
29897         name = (CharPtr) MemNew (sizeof(Char) * 5);
29898         sprintf (name, "trn%c", ch);
29899       }
29900       break;
29901     case 2:
29902       if (!TextHasNoText (dlg->gene)) {
29903         name = SaveStringFromText (dlg->gene);
29904       }
29905       break;
29906   }
29907   return name;
29908 }
29909 
29910 
NameFromIGSFlankDlg(DialoG d)29911 static Pointer NameFromIGSFlankDlg (DialoG d)
29912 {
29913   IGSFlankDlgPtr   dlg;
29914   CharPtr          name = NULL, gene, prot = NULL, sym;
29915   Int4             i;
29916   CharPtr          fmt = "%s (%s)";
29917   CharPtr          trn_fmt = "tRNA-%s";
29918 
29919   dlg = (IGSFlankDlgPtr) GetObjectExtra(d);
29920   if (dlg == NULL) {
29921     return NULL;
29922   }
29923 
29924   gene = GeneSymbolFromIGSFlankDlg(d);
29925   if (gene == NULL) {
29926     return NULL;
29927   }
29928 
29929   switch (GetValue (dlg->trna_or_prot)) {
29930     case 1:
29931       i = GetValue (dlg->trna) - 1;
29932       if (i > 0) {
29933         sym = GetLongSymbolForAA (i + 64);
29934         if (sym != NULL) {
29935           prot = (CharPtr) MemNew (sizeof (Char) * (StringLen (trn_fmt) + StringLen (sym)));
29936           sprintf (prot, trn_fmt, sym);
29937         }
29938       }
29939       break;
29940     case 2:
29941       if (!TextHasNoText (dlg->protein)) {
29942         prot = SaveStringFromText (dlg->protein);
29943       }
29944       break;
29945   }
29946   if (prot != NULL) {
29947     name = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (prot) + StringLen (gene)));
29948     sprintf (name, fmt, prot, gene);
29949     prot = MemFree (prot);
29950   }
29951 
29952   gene = MemFree (gene);
29953 
29954   return name;
29955 }
29956 
ChangeTrnaOrProt(GrouP g)29957 static void ChangeTrnaOrProt (GrouP g)
29958 {
29959   IGSFlankDlgPtr dlg;
29960 
29961   dlg = (IGSFlankDlgPtr) GetObjectExtra (g);
29962   if (dlg == NULL) {
29963     return;
29964   }
29965   switch (GetValue (dlg->trna_or_prot)) {
29966     case 1:
29967       Show (dlg->trna_grp);
29968       Hide (dlg->prot_grp);
29969       break;
29970     case 2:
29971       Show (dlg->prot_grp);
29972       Hide (dlg->trna_grp);
29973       break;
29974     default:
29975       Hide (dlg->prot_grp);
29976       Hide (dlg->trna_grp);
29977       break;
29978   }
29979 }
29980 
29981 
ClearIGSFlankDialog(DialoG d,Pointer data)29982 static void ClearIGSFlankDialog (DialoG d, Pointer data)
29983 {
29984   IGSFlankDlgPtr dlg;
29985 
29986   dlg = (IGSFlankDlgPtr) GetObjectExtra (d);
29987   if (dlg == NULL) {
29988     return;
29989   }
29990 
29991   SetValue (dlg->trna_or_prot, 0);
29992   SetTitle (dlg->gene, "");
29993   SetTitle (dlg->protein, "");
29994   SetValue (dlg->trna, 0);
29995   ChangeTrnaOrProt (dlg->trna_or_prot);
29996 }
29997 
29998 
IGSFlankDialog(GrouP h,CharPtr title)29999 static DialoG IGSFlankDialog (GrouP h, CharPtr title)
30000 {
30001   IGSFlankDlgPtr dlg;
30002   GrouP p, g;
30003 
30004   dlg = (IGSFlankDlgPtr) MemNew (sizeof (IGSFlankDlgData));
30005   if (StringHasNoText (title)) {
30006     p = HiddenGroup (h, 2, 0, NULL);
30007   } else {
30008     p = NormalGroup (h, 2, 0, title, programFont, NULL);
30009   }
30010   SetObjectExtra (p, dlg, StdCleanupExtraProc);
30011   SetGroupSpacing (p, 10, 10);
30012   dlg->dialog = (DialoG) p;
30013   dlg->todialog = ClearIGSFlankDialog;
30014 
30015   dlg->trna_or_prot = HiddenGroup (p, 0, 2, ChangeTrnaOrProt);
30016   SetObjectExtra (dlg->trna_or_prot, dlg, NULL);
30017   SetGroupSpacing (dlg->trna_or_prot, 10, 10);
30018   RadioButton (dlg->trna_or_prot, "tRNA");
30019   RadioButton (dlg->trna_or_prot, "protein coding gene");
30020 
30021   g = HiddenGroup (p, 0, 2, NULL);
30022   dlg->trna_grp = HiddenGroup (g, 2, 0, NULL);
30023   SetGroupSpacing (dlg->trna_grp, 10, 10);
30024   StaticPrompt (dlg->trna_grp, "Select tRNA:", 0, 0, systemFont, 'c');
30025   dlg->trna = PopupList (dlg->trna_grp, TRUE, NULL);
30026   PopulateAAPopup (dlg->trna);
30027 
30028   dlg->prot_grp = HiddenGroup (g, 2, 0, NULL);
30029   StaticPrompt (dlg->prot_grp, "Protein Name", 0, 0, systemFont, 'c');
30030   dlg->protein = DialogText (dlg->prot_grp, "", 10, NULL);
30031   StaticPrompt (dlg->prot_grp, "Gene Symbol", 0, 0, systemFont, 'c');
30032   dlg->gene = DialogText (dlg->prot_grp, "", 10, NULL);
30033 
30034   Hide (dlg->trna_grp);
30035   Hide (dlg->prot_grp);
30036 
30037   return (DialoG) p;
30038 }
30039 
30040 
30041 typedef struct igsfeatform {
30042   WIZARD_BLOCK
30043   DialoG gene_5;
30044   DialoG gene_3;
30045   GrouP partial_choice5;
30046   GrouP sub5;
30047   GrouP partial_choice3;
30048   GrouP sub3;
30049 } IGSFeatFormData, PNTR IGSFeatFormPtr;
30050 
30051 
CollectIGSFeat(Pointer data,WizardTrackerPtr wiz)30052 static void CollectIGSFeat (Pointer data, WizardTrackerPtr wiz)
30053 {
30054   IGSFeatFormPtr frm;
30055   CharPtr        name5, name3, gene5, gene3;
30056   CharPtr        fmt = "%s-%s intergenic spacer";
30057   Int4           len;
30058   Int2           part5, part3;
30059   CharPtr        contains = "contains ";
30060   CharPtr        may_also_contain = "; may also contain ";
30061   Boolean        any_contain = FALSE;
30062   Boolean        any_maybe = FALSE;
30063   Boolean        insufficient = FALSE;
30064 
30065   frm = (IGSFeatFormPtr) data;
30066   if (frm == NULL || wiz == NULL) {
30067     return;
30068   }
30069 
30070   wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
30071   wiz->partial5 = FALSE;
30072   wiz->partial3 = FALSE;
30073   gene5 = GeneSymbolFromIGSFlankDlg (frm->gene_5);
30074   gene3 = GeneSymbolFromIGSFlankDlg (frm->gene_3);
30075   name5 = NameFromIGSFlankDlg (frm->gene_5);
30076   name3 = NameFromIGSFlankDlg (frm->gene_3);
30077   /* note - have to subtract 1 from these choices because added prompt */
30078   part5 = GetValue (frm->partial_choice5) - 1;
30079   part3 = GetValue (frm->partial_choice3) - 1;
30080   if (StringHasNoText (gene5) || StringHasNoText (gene3) || part5 < 1 || part3 < 1) {
30081     /* do nothing, insufficient information */
30082   } else if (part5 == 3 && GetValue (frm->sub5) == 0) {
30083     /* do nothing, insufficient information */
30084   } else if (part3 == 3 && GetValue (frm->sub3) == 0) {
30085     /* do nothing, insufficient information */
30086   } else {
30087     len = StringLen (gene5) + StringLen (gene3) + StringLen (fmt);
30088     switch (part5) {
30089       case 1:
30090         if (StringHasNoText (name5)) {
30091           insufficient = TRUE;
30092         } else {
30093           len += StringLen (name5) + 7 + StringLen (contains);
30094           any_contain = TRUE;
30095           wiz->partial5 = TRUE;
30096         }
30097         break;
30098       case 2:
30099         if (StringHasNoText (name5)) {
30100           insufficient = TRUE;
30101         } else {
30102           len += StringLen (name5) + 7 + StringLen (may_also_contain);
30103           any_maybe = TRUE;
30104           wiz->partial5 = TRUE;
30105         }
30106         break;
30107       case 3:
30108         if (GetValue (frm->sub5) == 2) {
30109           wiz->partial5 = TRUE;
30110         }
30111         break;
30112     }
30113     switch (part3) {
30114       case 1:
30115         if (StringHasNoText (name3)) {
30116           insufficient = TRUE;
30117         } else {
30118           len += StringLen (name3) + 7 + StringLen (contains);
30119           any_contain = TRUE;
30120           wiz->partial3 = TRUE;
30121         }
30122         break;
30123       case 2:
30124         if (StringHasNoText (name3)) {
30125           insufficient = TRUE;
30126         } else {
30127           len += StringLen (name3) + 7 + StringLen (may_also_contain);
30128           any_maybe = TRUE;
30129           wiz->partial3 = TRUE;
30130         }
30131         break;
30132       case 3:
30133         if (GetValue (frm->sub3) == 2) {
30134           wiz->partial3 = TRUE;
30135         }
30136         break;
30137     }
30138 
30139     if (!insufficient) {
30140       wiz->misc_feat_comment = (CharPtr) MemNew (sizeof (Char) * len);
30141       wiz->misc_feat_comment[0] = 0;
30142       if (any_contain) {
30143         StringCat (wiz->misc_feat_comment, contains);
30144       }
30145       if (part5 == 1) {
30146         StringCat (wiz->misc_feat_comment, name5);
30147         if (part3 == 1) {
30148           StringCat (wiz->misc_feat_comment, ", ");
30149         } else {
30150           StringCat (wiz->misc_feat_comment, " and ");
30151         }
30152       }
30153       StringCat (wiz->misc_feat_comment, gene5);
30154       StringCat (wiz->misc_feat_comment, "-");
30155       StringCat (wiz->misc_feat_comment, gene3);
30156       StringCat (wiz->misc_feat_comment, " intergenic spacer");
30157 
30158       if (part3 == 1) {
30159         if (part5 == 1) {
30160           StringCat (wiz->misc_feat_comment, ",");
30161         }
30162         StringCat (wiz->misc_feat_comment, " and ");
30163         StringCat (wiz->misc_feat_comment, name3);
30164       }
30165 
30166       if (any_maybe) {
30167         StringCat (wiz->misc_feat_comment, may_also_contain);
30168       }
30169       if (part5 == 2) {
30170         StringCat (wiz->misc_feat_comment, name5);
30171         if (part3 == 2) {
30172           StringCat (wiz->misc_feat_comment, " and ");
30173         }
30174       }
30175       if (part3 == 2) {
30176         StringCat (wiz->misc_feat_comment, name3);
30177       }
30178     }
30179   }
30180   gene5 = MemFree (gene5);
30181   gene3 = MemFree (gene3);
30182   name5 = MemFree (name5);
30183   name3 = MemFree (name3);
30184 }
30185 
30186 
ChangePartial5(GrouP g)30187 static void ChangePartial5 (GrouP g)
30188 {
30189   IGSFeatFormPtr frm;
30190 
30191   frm = (IGSFeatFormPtr) GetObjectExtra (g);
30192   if (frm == NULL) {
30193     return;
30194   }
30195   if (GetValue (frm->partial_choice5) == 4) {
30196     Show (frm->sub5);
30197   } else {
30198     Hide (frm->sub5);
30199   }
30200 }
30201 
30202 
ChangePartial3(GrouP g)30203 static void ChangePartial3 (GrouP g)
30204 {
30205   IGSFeatFormPtr frm;
30206 
30207   frm = (IGSFeatFormPtr) GetObjectExtra (g);
30208   if (frm == NULL) {
30209     return;
30210   }
30211   if (GetValue (frm->partial_choice3) == 4) {
30212     Show (frm->sub3);
30213   } else {
30214     Hide (frm->sub3);
30215   }
30216 }
30217 
30218 
ClearIGSAnnotMult(ButtoN b)30219 static void ClearIGSAnnotMult (ButtoN b)
30220 {
30221   IGSFeatFormPtr frm;
30222 
30223   frm = (IGSFeatFormPtr) GetObjectExtra (b);
30224   if (frm == NULL) {
30225     return;
30226   }
30227 
30228   PointerToDialog (frm->gene_5, NULL);
30229   PointerToDialog (frm->gene_3, NULL);
30230   SetValue (frm->partial_choice5, 0);
30231   SetValue (frm->sub5, 0);
30232   SetValue (frm->sub3, 0);
30233   SetValue (frm->partial_choice3, 0);
30234   ChangePartial5 (frm->partial_choice5);
30235   ChangePartial3 (frm->partial_choice3);
30236 }
30237 
30238 
MultipleIGSFeatSpansUnknown(WizardTrackerPtr wiz)30239 static Boolean MultipleIGSFeatSpansUnknown (WizardTrackerPtr wiz)
30240 {
30241   IGSFeatFormPtr frm;
30242   WindoW w;
30243   GrouP  h;
30244   GrouP  g, g_inside, c;
30245   CharPtr dlg_title;
30246   ButtoN b;
30247 
30248   frm = (IGSFeatFormPtr) MemNew (sizeof (IGSFeatFormData));
30249   frm->wiz = wiz;
30250 
30251   dlg_title = "Intergenic Spacer Annotation";
30252   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
30253   SetObjectExtra (w, frm, CleanupWizardForm);
30254   frm->form = (ForM) w;
30255   frm->collect_func = CollectIGSFeat;
30256   frm->fwd_ok_func = HasIGSFeatInfoAndOkToContinueToSequin;
30257   frm->next_form = FinishWizardAndLaunchSequin;
30258 
30259   wiz->spans_unknown = TRUE;
30260 
30261   h = HiddenGroup (w, -1, -1, NULL);
30262   SetGroupSpacing (h, 10, 10);
30263 
30264   g = NormalGroup (h, -1, 0, "What features flank the intergenic spacer?", programFont, NULL);
30265   SetGroupSpacing (g, 10, 10);
30266   StaticPrompt (g, " ", 0, 0, programFont, 'c');
30267   g_inside = HiddenGroup (g, 2, 0, NULL);
30268   SetGroupSpacing (g_inside, 10, 10);
30269   frm->gene_5 = IGSFlankDialog(g_inside, "5' end");
30270   frm->gene_3 = IGSFlankDialog(g_inside, "3' end");
30271 
30272   frm->partial_choice5 = NormalGroup (g_inside, 1, 0, "", programFont, ChangePartial5);
30273   SetObjectExtra (frm->partial_choice5, frm, NULL);
30274   MultiLinePrompt (frm->partial_choice5, "Do your sequences contain part of the feature described above?", 30 * stdCharWidth, systemFont);
30275   RadioButton (frm->partial_choice5, "Yes");
30276   RadioButton (frm->partial_choice5, "Yes, but only in some of the sequences");
30277   RadioButton (frm->partial_choice5, "No, it is only the intergenic spacer at the 5' end");
30278 
30279   frm->partial_choice3 = NormalGroup (g_inside, 1, 0, "", programFont, ChangePartial3);
30280   SetObjectExtra (frm->partial_choice3, frm, NULL);
30281   MultiLinePrompt (frm->partial_choice3, "Do your sequences contain part of the feature described above?", 30 * stdCharWidth, systemFont);
30282   RadioButton (frm->partial_choice3, "Yes");
30283   RadioButton (frm->partial_choice3, "Yes, but only in some of the sequences");
30284   RadioButton (frm->partial_choice3, "No, it is only the intergenic spacer at the 3' end");
30285 
30286   frm->sub5 = NormalGroup (g_inside, 1, 0, "Is the intergenic spacer 5' complete?", programFont, NULL);
30287   RadioButton (frm->sub5, "Yes");
30288   RadioButton (frm->sub5, "No");
30289 
30290   frm->sub3 = NormalGroup (g_inside, 1, 0, "Is the intergenic spacer 3' complete?", programFont, NULL);
30291   RadioButton (frm->sub3, "Yes");
30292   RadioButton (frm->sub3, "No");
30293 
30294   Hide (frm->sub5);
30295   Hide (frm->sub3);
30296 
30297   b = PushButton (h, "Clear", ClearIGSAnnotMult);
30298   SetObjectExtra (b, frm, NULL);
30299 
30300   c = MakeWizardNav (h, frm);
30301 
30302 
30303   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) b, (HANDLE) c, NULL);
30304 
30305   Update();
30306   Show (w);
30307   SendHelpScrollMessage (helpForm, "IGS Wizard Annotation", "Intergenic spacer and other features (gene, tRNA) where spans are unknown");
30308   return TRUE;
30309 }
30310 
30311 
30312 typedef struct microsatelliteannotationtypeform {
30313   WIZARD_BLOCK
30314   GrouP apply_type;
30315   GrouP  extra_info;
30316   ButtoN no_additional;
30317   ButtoN rpt_unit_seq;
30318   ButtoN rpt_unit_range;
30319 
30320 } MicrosatelliteAnnotationTypeFormData, PNTR MicrosatelliteAnnotationTypeFormPtr;
30321 
30322 
HasMicrosatelliteAnnotationType(WizardTrackerPtr wiz)30323 static Boolean HasMicrosatelliteAnnotationType (WizardTrackerPtr wiz)
30324 {
30325   return TRUE;
30326 }
30327 
NeedsMicrosatelliteAnnotationType(WizardTrackerPtr wiz)30328 static Boolean NeedsMicrosatelliteAnnotationType (WizardTrackerPtr wiz)
30329 {
30330   Message (MSG_ERROR, "You must answer the questions.");
30331   return FALSE;
30332 }
30333 
30334 
ChangeMicrosatelliteAnnotationExtra(ButtoN b)30335 static void ChangeMicrosatelliteAnnotationExtra (ButtoN b)
30336 {
30337   MicrosatelliteAnnotationTypeFormPtr frm;
30338 
30339   frm = (MicrosatelliteAnnotationTypeFormPtr) GetObjectExtra (b);
30340   if (frm == NULL) {
30341     return;
30342   }
30343 
30344   if (GetStatus (frm->no_additional)) {
30345     Disable (frm->rpt_unit_range);
30346     Disable (frm->rpt_unit_seq);
30347   } else {
30348     Enable (frm->rpt_unit_range);
30349     Enable (frm->rpt_unit_seq);
30350     if (GetStatus (frm->rpt_unit_range) || GetStatus (frm->rpt_unit_seq)) {
30351       Disable (frm->no_additional);
30352     } else {
30353       Enable (frm->no_additional);
30354     }
30355   }
30356 }
30357 
30358 
ChangeMicrosatelliteAnnotationApplyType(GrouP g)30359 static void ChangeMicrosatelliteAnnotationApplyType (GrouP g)
30360 {
30361   MicrosatelliteAnnotationTypeFormPtr frm;
30362   Int2 val;
30363 
30364   frm = (MicrosatelliteAnnotationTypeFormPtr) GetObjectExtra (g);
30365   if (frm == NULL) {
30366     return;
30367   }
30368 
30369   val = GetValue (frm->apply_type);
30370   if (val == 1) {
30371     Enable (frm->extra_info);
30372     ChangeMicrosatelliteAnnotationExtra (frm->no_additional);
30373     frm->fwd_ok_func = HasMicrosatelliteAnnotationType;
30374   } else {
30375     Disable (frm->extra_info);
30376     if (val == 3) {
30377       frm->fwd_ok_func = HasMicrosatelliteAnnotationType;
30378     } else {
30379       frm->fwd_ok_func = NeedsMicrosatelliteAnnotationType;
30380     }
30381   }
30382 }
30383 
30384 
CollectMicrosatelliteAnnotationType(Pointer data,WizardTrackerPtr wiz)30385 static void CollectMicrosatelliteAnnotationType (Pointer data, WizardTrackerPtr wiz)
30386 {
30387   MicrosatelliteAnnotationTypeFormPtr frm;
30388   Int2 val;
30389   WizardFeatQualPtr q;
30390   IDAndTitleEditPtr iatep;
30391   WizardSrcQualPtr  sq;
30392 
30393   frm = (MicrosatelliteAnnotationTypeFormPtr) data;
30394   if (frm == NULL || wiz == NULL) {
30395     return;
30396   }
30397 
30398   wiz->show_feature_table_help = FALSE;
30399   wiz->feature_quals = ValNodeFreeData (wiz->feature_quals);
30400   wiz->annot_list = FreeAnnotList(wiz->annot_list);
30401   wiz->feat_qual_table = FreeTabTable (wiz->feat_qual_table);
30402   wiz->multiple_repeats = FALSE;
30403 
30404   val = GetValue (frm->apply_type);
30405   if (val == 3) {
30406     wiz->show_feature_table_help = TRUE;
30407     wiz->multiple_repeats = TRUE;
30408     frm->next_form = CreateWizardSrcQualsForm;
30409 
30410   } else if (val == 1) {
30411     iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
30412     if (DoAnySequencesHaveModifier(iatep, "clone")) {
30413       sq = MoveQualFromExtraToBase (&(wiz->base_src_quals), &(wiz->extra_src_quals), "clone");
30414       if (sq != NULL) {
30415         sq->required = TRUE;
30416       }
30417     } else {
30418       ValNodeAddPointer (&(wiz->feature_quals), 0,
30419                          WizardFeatQualNew ("Microsatellite Name", eWizardEditQual_CopyFromId, TRUE, TRUE,
30420                          ApplyMicrosatelliteName, GetMicrosatelliteName, CheckMicrosatelliteName, NULL, FALSE, "Ca-123"));
30421     }
30422     if (GetStatus (frm->rpt_unit_seq)) {
30423       ValNodeAddPointer (&(wiz->feature_quals), 0,
30424                          WizardFeatQualNew ("rpt_unit_seq", eWizardEditQual_None, TRUE, FALSE,
30425                          ApplyRptUnitSeq, GetRptUnitSeq, CheckRptUnitSeq, IsRptUnitSeqFormatValid, TRUE, "ag"));
30426     }
30427     if (GetStatus (frm->rpt_unit_range)) {
30428       q = WizardFeatQualNew ("rpt_unit_range", eWizardEditQual_Range, TRUE, FALSE,
30429                          ApplyRangeStart, GetRangeStart, CheckRangeStart, IsLocStartFormatValid, FALSE, "24");
30430       q->delete_if_invalid = TRUE;
30431       ValNodeAddPointer (&(wiz->feature_quals), 0, q);
30432       q = WizardFeatQualNew ("rpt_unit_range", eWizardEditQual_Range, TRUE, FALSE,
30433                          ApplyRangeStop, GetRangeStop, CheckRangeStop, IsLocStopFormatValid, FALSE, "25");
30434       q->delete_if_invalid = TRUE;
30435       ValNodeAddPointer (&(wiz->feature_quals), 0, q);
30436     }
30437     frm->next_form = CreateFeatureQualsForm;
30438     wiz->annot_list = FreeAnnotList(wiz->annot_list);
30439     PregenerateFeatures(wiz);
30440   }
30441 }
30442 
30443 
CreateMicrosatelliteAnnotationTypeForm(WizardTrackerPtr wiz)30444 static Boolean CreateMicrosatelliteAnnotationTypeForm (WizardTrackerPtr wiz)
30445 {
30446   MicrosatelliteAnnotationTypeFormPtr frm;
30447   WindoW w;
30448   GrouP  h;
30449   PrompT ppt;
30450   GrouP  c;
30451   CharPtr dlg_title;
30452 
30453   frm = (MicrosatelliteAnnotationTypeFormPtr) MemNew (sizeof (MicrosatelliteAnnotationTypeFormData));
30454   frm->wiz = wiz;
30455 
30456   dlg_title = GetWizardDlgTitle (wiz->wizard_type, eWizardDlgTitle_Annotation);
30457   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
30458   SetObjectExtra (w, frm, CleanupWizardForm);
30459   frm->form = (ForM) w;
30460   frm->collect_func = CollectMicrosatelliteAnnotationType;
30461   frm->fwd_ok_func = NeedsMicrosatelliteAnnotationType;
30462   frm->next_form = NULL;
30463 
30464   h = HiddenGroup (w, -1, -1, NULL);
30465   SetGroupSpacing (h, 10, 10);
30466 
30467   ppt = StaticPrompt (h, "What type of annotation do you want to apply to each sequence?", 0, 0, programFont, 'c');
30468 
30469   frm->apply_type = HiddenGroup (h, 0, 4, ChangeMicrosatelliteAnnotationApplyType);
30470   SetObjectExtra (frm->apply_type, frm, NULL);
30471   SetGroupSpacing (frm->apply_type, 10, 10);
30472   RadioButton (frm->apply_type, "Apply a microsatellite repeat region to each sequence (automatic)");
30473   frm->extra_info = NormalGroup (frm->apply_type, 0, 3, "Do you want to apply information about the sequence repeat?", systemFont, NULL);
30474   frm->no_additional = CheckBox (frm->extra_info, "No, I do not want to add more information", ChangeMicrosatelliteAnnotationExtra);
30475   SetObjectExtra (frm->no_additional, frm, NULL);
30476   frm->rpt_unit_seq = CheckBox (frm->extra_info, "Add rpt_unit_seq (sequence of 1 repeat)", ChangeMicrosatelliteAnnotationExtra);
30477   SetObjectExtra (frm->rpt_unit_seq, frm, NULL);
30478   frm->rpt_unit_range = CheckBox (frm->extra_info, "Add rpt_unit_range (nucleotide location of 1 repeat unit)", ChangeMicrosatelliteAnnotationExtra);
30479   SetObjectExtra (frm->rpt_unit_range, frm, NULL);
30480   RadioButton (frm->apply_type, "Apply multiple microsatellite repeat regions to each sequence.");
30481   StaticPrompt (frm->apply_type, "Annotate using a feature table or menu options in the record viewer", 0, 0, systemFont, 'l');
30482 
30483   c = MakeWizardNav (h, frm);
30484 
30485   AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) frm->apply_type, (HANDLE) c, NULL);
30486   ChangeMicrosatelliteAnnotationApplyType(frm->apply_type);
30487 
30488   Update();
30489   Show (w);
30490   return TRUE;
30491 }
30492 
30493 
SetDLoopDefaults(WizardTrackerPtr wiz)30494 static void SetDLoopDefaults (WizardTrackerPtr wiz)
30495 {
30496   wiz->genome = GENOME_mitochondrion;
30497   if (wiz->molinfo == NULL) {
30498     wiz->molinfo = MolInfoNew ();
30499   }
30500   wiz->molinfo->biomol = MOLECULE_TYPE_GENOMIC;
30501   wiz->mol_class = Seq_mol_dna;
30502   wiz->add_span_note = FALSE;
30503 }
30504 
30505 
AnySequencesLonger(SeqEntryPtr sep,Int4 max_length)30506 static Boolean AnySequencesLonger (SeqEntryPtr sep, Int4 max_length)
30507 {
30508   BioseqPtr bsp;
30509   BioseqSetPtr bssp;
30510 
30511   while (sep != NULL) {
30512     if (IS_Bioseq (sep) && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL && bsp->length > max_length) {
30513       return TRUE;
30514     } else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL && AnySequencesLonger (bssp->seq_set, max_length)) {
30515       return TRUE;
30516     }
30517     sep = sep->next;
30518   }
30519   return FALSE;
30520 }
30521 
30522 
CheckDLoopSequenceLengthAndOkToContinueToSequin(WizardTrackerPtr wiz)30523 static Boolean CheckDLoopSequenceLengthAndOkToContinueToSequin (WizardTrackerPtr wiz)
30524 {
30525   if (AnySequencesLonger(wiz->sequences, 1099)) {
30526     if (ANS_NO == Message (MSG_YN, "Your sequences are longer than expected, are you sure your sequences contain only control regions?")) {
30527       return FALSE;
30528     }
30529   }
30530   return OkToContinueToSequin (wiz);
30531 }
30532 
30533 
MakeControlRegionAndContinueToSequin(WizardTrackerPtr wiz)30534 static Boolean MakeControlRegionAndContinueToSequin (WizardTrackerPtr wiz)
30535 {
30536   wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
30537   wiz->misc_feat_comment = StringSave ("control region");
30538   wiz->partial5 = TRUE;
30539   wiz->partial3 = TRUE;
30540   SetDLoopDefaults(wiz);
30541   FinishWizardAndLaunchSequin (wiz);
30542   return TRUE;
30543 }
30544 
30545 
MakeDLoopAndContinueToSequin(WizardTrackerPtr wiz)30546 static Boolean MakeDLoopAndContinueToSequin (WizardTrackerPtr wiz)
30547 {
30548   wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
30549   wiz->misc_feat_comment = StringSave ("D-loop");
30550   wiz->partial5 = TRUE;
30551   wiz->partial3 = TRUE;
30552   SetDLoopDefaults(wiz);
30553   FinishWizardAndLaunchSequin (wiz);
30554   return TRUE;
30555 }
30556 
30557 
SetSpansKnownAndContinueToSequin(WizardTrackerPtr wiz)30558 static Boolean SetSpansKnownAndContinueToSequin (WizardTrackerPtr wiz)
30559 {
30560   wiz->spans_unknown = FALSE;
30561   wiz->add_span_note = TRUE;
30562   wiz->use_alternate_leaving_msg = TRUE;
30563   return ShowDLoopFeatureTableInstructionsAndContinueToSequin(wiz);
30564 }
30565 
30566 
30567 static Boolean CreateDloopFeaturesForm (WizardTrackerPtr wiz, Int4 num_features);
30568 
CreateDloopPlusOne(WizardTrackerPtr wiz)30569 static Boolean CreateDloopPlusOne (WizardTrackerPtr wiz)
30570 {
30571   return CreateDloopFeaturesForm(wiz, 2);
30572 }
30573 
30574 
CreateDloopPlusTwo(WizardTrackerPtr wiz)30575 static Boolean CreateDloopPlusTwo (WizardTrackerPtr wiz)
30576 {
30577   return CreateDloopFeaturesForm(wiz, 3);
30578 }
30579 
30580 
CreateDloopPlusThree(WizardTrackerPtr wiz)30581 static Boolean CreateDloopPlusThree (WizardTrackerPtr wiz)
30582 {
30583   return CreateDloopFeaturesForm(wiz, 4);
30584 }
30585 
30586 
30587 static WizardSubChoiceData dloop_annotation_choice_list[] = {
30588   { "Yes", NULL,
30589     { { NULL, NULL, SetSpansKnownAndContinueToSequin },
30590       { NULL, NULL, NULL },
30591       { NULL, NULL, NULL },
30592       { NULL, NULL, NULL },
30593       { NULL, NULL, NULL } } } ,
30594   { "No", "How many features are in your sequences?",
30595     { { "D-loop/Control Region and 1 other feature", NULL, CreateDloopPlusOne },
30596       { "D-loop/Control Region and 2 other features", NULL, CreateDloopPlusTwo },
30597       { "D-loop/Control Region and 3 other features", NULL, CreateDloopPlusThree },
30598       { NULL, NULL, NULL },
30599       { NULL, NULL, NULL } } } ,
30600   { NULL, NULL,
30601     { { NULL, NULL, NULL },
30602       { NULL, NULL, NULL },
30603       { NULL, NULL, NULL },
30604       { NULL, NULL, NULL },
30605       { NULL, NULL, NULL } } }
30606 };
30607 
30608 
CreateDLoopAnnotationChoiceForm(WizardTrackerPtr wiz)30609 static Boolean CreateDLoopAnnotationChoiceForm (WizardTrackerPtr wiz)
30610 {
30611   wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
30612   wiz->partial5 = FALSE;
30613   wiz->partial3 = FALSE;
30614   SetDLoopDefaults(wiz);
30615   return CreateWizardMultiChoiceForm (wiz, dloop_annotation_choice_list,
30616                                       "D-loop Wizard Features",
30617                                       "Do you know the nucleotide spans for each feature in your sequences?");
30618 }
30619 
30620 
30621 typedef struct dloopfeaturedialog {
30622   DIALOG_MESSAGE_BLOCK
30623 
30624   GrouP  feature_list;
30625   ButtoN control_region_btn;
30626   ButtoN d_loop_btn;
30627   PopuP  rna_type;
30628   PopuP  trna_type;
30629   TexT   free_text;
30630 
30631   Nlm_ChangeNotifyProc change_notify;
30632   Pointer change_userdata;
30633 } DLoopFeatureDialogData, PNTR DLoopFeatureDialogPtr;
30634 
30635 
30636 static CharPtr DloopRnaNames[] = {
30637   "12S ribosomal RNA",
30638   "16S ribosomal RNA",
30639   NULL
30640 };
30641 
30642 static CharPtr DlooptRNANames[] = {
30643   "Ala",
30644   "Asx",
30645   "Cys",
30646   "Asp",
30647   "Glu",
30648   "Phe",
30649   "Gly",
30650   "His",
30651   "Ile",
30652   "Lys",
30653   "Leu",
30654   "Met",
30655   "Asn",
30656   "Pro",
30657   "Gln",
30658   "Arg",
30659   "Ser",
30660   "Thr",
30661   "Val",
30662   "Trp",
30663   "Tyr",
30664   "Glx",
30665   "Sec",
30666   "Ter",
30667   "Pyl",
30668   "Xle",
30669   NULL
30670 };
30671 
30672 
DLoopFeatureFromDialog(DialoG d)30673 static Pointer DLoopFeatureFromDialog (DialoG d)
30674 {
30675   DLoopFeatureDialogPtr dlg;
30676   Int2 val;
30677   CharPtr rval = NULL;
30678   CharPtr fmt = "tRNA-%s";
30679 
30680   dlg = (DLoopFeatureDialogPtr) GetObjectExtra (d);
30681   if (dlg == NULL) {
30682     return NULL;
30683   }
30684 
30685   val = GetValue (dlg->feature_list);
30686   switch (val) {
30687     case 1:
30688       rval = StringSave ("control region");
30689       break;
30690     case 3:
30691       rval = StringSave ("D-loop");
30692       break;
30693     case 5:
30694       val = GetValue (dlg->trna_type);
30695       if (val > 1) {
30696         rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (DlooptRNANames[val - 1])));
30697         sprintf (rval, fmt, DlooptRNANames[val - 2]);
30698       }
30699       break;
30700     case 7:
30701       val = GetValue (dlg->rna_type);
30702       if (val > 1) {
30703         rval = StringSave (DloopRnaNames[val - 2]);
30704       }
30705       break;
30706     case 9:
30707       if (!TextHasNoText (dlg->free_text)) {
30708         rval = SaveStringFromText (dlg->free_text);
30709       }
30710       break;
30711   }
30712   return rval;
30713 }
30714 
30715 
ChangeDLoopFeatureChoice(GrouP g)30716 static void ChangeDLoopFeatureChoice (GrouP g)
30717 {
30718   DLoopFeatureDialogPtr dlg;
30719   Int2 val;
30720 
30721   dlg = (DLoopFeatureDialogPtr) GetObjectExtra (g);
30722   if (dlg == NULL) {
30723     return;
30724   }
30725 
30726   Disable (dlg->rna_type);
30727   Disable (dlg->trna_type);
30728   Disable (dlg->free_text);
30729   val = GetValue (dlg->feature_list);
30730   switch (val) {
30731     case 5:
30732       Enable (dlg->trna_type);
30733       break;
30734     case 7:
30735       Enable (dlg->rna_type);
30736       break;
30737     case 9:
30738       Enable (dlg->free_text);
30739       break;
30740   }
30741 
30742   if (dlg->change_notify != NULL) {
30743     (dlg->change_notify)(dlg->change_userdata);
30744   }
30745 }
30746 
30747 
ChangeDloopPopup(PopuP p)30748 static void ChangeDloopPopup (PopuP p)
30749 {
30750   DLoopFeatureDialogPtr dlg;
30751 
30752   dlg = (DLoopFeatureDialogPtr) GetObjectExtra (p);
30753   if (dlg == NULL) {
30754     return;
30755   }
30756   if (dlg->change_notify != NULL) {
30757     (dlg->change_notify)(dlg->change_userdata);
30758   }
30759 }
30760 
30761 
ChangeDloopFreeText(TexT t)30762 static void ChangeDloopFreeText (TexT t)
30763 {
30764   DLoopFeatureDialogPtr dlg;
30765 
30766   dlg = (DLoopFeatureDialogPtr) GetObjectExtra (t);
30767   if (dlg == NULL) {
30768     return;
30769   }
30770   if (dlg->change_notify != NULL) {
30771     (dlg->change_notify)(dlg->change_userdata);
30772   }
30773 }
30774 
30775 
DisableDloopAndControlRegion(DialoG d)30776 static void DisableDloopAndControlRegion (DialoG d)
30777 {
30778   DLoopFeatureDialogPtr dlg;
30779 
30780   dlg = (DLoopFeatureDialogPtr) GetObjectExtra (d);
30781   if (dlg == NULL) {
30782     return;
30783   }
30784 
30785   Disable (dlg->d_loop_btn);
30786   Disable (dlg->control_region_btn);
30787 }
30788 
30789 
EnableDloopAndControlRegion(DialoG d)30790 static void EnableDloopAndControlRegion (DialoG d)
30791 {
30792   DLoopFeatureDialogPtr dlg;
30793 
30794   dlg = (DLoopFeatureDialogPtr) GetObjectExtra (d);
30795   if (dlg == NULL) {
30796     return;
30797   }
30798 
30799   Enable (dlg->d_loop_btn);
30800   Enable (dlg->control_region_btn);
30801 }
30802 
30803 
ResetDloopFeatureDialog(DialoG d)30804 static void ResetDloopFeatureDialog (DialoG d)
30805 {
30806   DLoopFeatureDialogPtr dlg;
30807 
30808   dlg = (DLoopFeatureDialogPtr) GetObjectExtra (d);
30809   if (dlg == NULL) {
30810     return;
30811   }
30812 
30813   SetValue (dlg->feature_list, 0);
30814   SetValue (dlg->trna_type, 1);
30815   SetValue (dlg->rna_type, 1);
30816   SetTitle (dlg->free_text, "");
30817   ChangeDLoopFeatureChoice (dlg->feature_list);
30818 }
30819 
30820 
CreateDLoopFeatureDialog(GrouP parent,CharPtr prompt,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)30821 static DialoG CreateDLoopFeatureDialog (GrouP parent, CharPtr prompt, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
30822 {
30823   DLoopFeatureDialogPtr dlg;
30824   GrouP  h;
30825   Int4   i;
30826 
30827   dlg = (DLoopFeatureDialogPtr) MemNew (sizeof (DLoopFeatureDialogData));
30828   if (dlg == NULL)
30829   {
30830     return NULL;
30831   }
30832   dlg->change_notify = change_notify;
30833   dlg->change_userdata = change_userdata;
30834 
30835   h = NormalGroup (parent, 0, 3, prompt, programFont, NULL);
30836   SetGroupSpacing (h, 10, 10);
30837   SetObjectExtra (h, dlg, StdCleanupExtraProc);
30838   dlg->dialog = (DialoG) h;
30839   dlg->fromdialog = DLoopFeatureFromDialog;
30840 
30841   dlg->feature_list = HiddenGroup (h, 2, 0, ChangeDLoopFeatureChoice);
30842   SetObjectExtra (dlg->feature_list, dlg, NULL);
30843   SetGroupSpacing (dlg->feature_list, 10, 10);
30844   dlg->control_region_btn = RadioButton (dlg->feature_list, "Control Region");
30845   StaticPrompt (dlg->feature_list, "", 0, 0, programFont, 'c');
30846   dlg->d_loop_btn = RadioButton (dlg->feature_list, "D-loop");
30847   StaticPrompt (dlg->feature_list, "", 0, 0, programFont, 'c');
30848   RadioButton (dlg->feature_list, "tRNA");
30849   dlg->trna_type = PopupList (dlg->feature_list, TRUE, ChangeDloopPopup);
30850   PopupItem (dlg->trna_type, "Select tRNA:");
30851   for (i = 0; DlooptRNANames[i] != NULL; i++) {
30852     PopupItem (dlg->trna_type, DlooptRNANames[i]);
30853   }
30854   SetValue (dlg->trna_type, 1);
30855   Disable(dlg->trna_type);
30856   RadioButton (dlg->feature_list, "rRNA");
30857   dlg->rna_type = PopupList (dlg->feature_list, TRUE, ChangeDloopPopup);
30858   SetObjectExtra (dlg->rna_type, dlg, NULL);
30859   PopupItem (dlg->rna_type, "Select rRNA:");
30860   for (i = 0; DloopRnaNames[i] != NULL; i++) {
30861     PopupItem (dlg->rna_type, DloopRnaNames[i]);
30862   }
30863   SetValue (dlg->rna_type, 1);
30864   Disable (dlg->rna_type);
30865   RadioButton (dlg->feature_list, "Something else:");
30866   dlg->free_text = DialogText (dlg->feature_list, "", 10, ChangeDloopFreeText);
30867   SetObjectExtra (dlg->free_text, dlg, NULL);
30868   Disable (dlg->free_text);
30869 
30870   return (DialoG) h;
30871 }
30872 
30873 
30874 typedef struct dloopfeaturesform {
30875   WIZARD_BLOCK
30876 
30877   DialoG PNTR features;
30878 
30879   Int4 num_features;
30880 } DLoopFeaturesFormData, PNTR DLoopFeaturesFormPtr;
30881 
30882 
CleanupDloopFeaturesForm(GraphiC g,Pointer data)30883 static void CleanupDloopFeaturesForm (GraphiC g, Pointer data)
30884 {
30885   DLoopFeaturesFormPtr frm;
30886 
30887   if (data != NULL)
30888   {
30889     frm = (DLoopFeaturesFormPtr) data;
30890     frm->features = MemFree (frm->features);
30891   }
30892   CleanupWizardForm (g, data);
30893 }
30894 
30895 
ChangeDloopFeature(Pointer data)30896 static void ChangeDloopFeature (Pointer data)
30897 {
30898   DLoopFeaturesFormPtr frm;
30899   Int4                 i, j;
30900   CharPtr              feat;
30901   Boolean              any = FALSE;
30902 
30903   frm = (DLoopFeaturesFormPtr) data;
30904   if (frm == NULL) {
30905     return;
30906   }
30907 
30908   for (i = 0; i < frm->num_features; i++) {
30909     feat = DialogToPointer (frm->features[i]);
30910     if (StringICmp (feat, "D-loop") == 0 || StringICmp (feat, "control region") == 0) {
30911       for (j = 0; j < i; j++) {
30912         DisableDloopAndControlRegion (frm->features[j]);
30913       }
30914       for (j = i + 1; j < frm->num_features; j++) {
30915         DisableDloopAndControlRegion (frm->features[j]);
30916       }
30917       any = TRUE;
30918       break;
30919     }
30920     feat = MemFree (feat);
30921   }
30922   if (!any) {
30923     for (i = 0; i < frm->num_features; i++) {
30924       EnableDloopAndControlRegion (frm->features[i]);
30925     }
30926   }
30927 }
30928 
30929 
CollectDloopFeatures(Pointer data,WizardTrackerPtr wiz)30930 static void CollectDloopFeatures (Pointer data, WizardTrackerPtr wiz)
30931 {
30932   DLoopFeaturesFormPtr frm;
30933   Int4                 i, len = 0;
30934   Boolean              missing = FALSE;
30935   CharPtr              contains = "contains ";
30936   CharPtr              and = "and ";
30937   CharPtr              feat;
30938 
30939   frm = (DLoopFeaturesFormPtr) data;
30940   if (frm == NULL || wiz == NULL) {
30941     return;
30942   }
30943 
30944   wiz->misc_feat_comment = MemFree (wiz->misc_feat_comment);
30945   wiz->spans_unknown = TRUE;
30946   wiz->add_span_note = TRUE;
30947   wiz->partial5 = TRUE;
30948   wiz->partial3 = TRUE;
30949 
30950   for (i = 0; i < frm->num_features && !missing; i++) {
30951     feat = DialogToPointer (frm->features[i]);
30952     if (StringHasNoText (feat)) {
30953       missing = TRUE;
30954     } else {
30955       len += StringLen (feat);
30956     }
30957     feat = MemFree (feat);
30958   }
30959   if (!missing) {
30960     len += StringLen (contains) + StringLen (and) + 1;
30961     if (frm->num_features > 2) {
30962       len += (frm->num_features - 1) * 2;
30963     } else {
30964       len += 1;
30965     }
30966     wiz->misc_feat_comment = (CharPtr) MemNew (sizeof (Char) * len);
30967     StringCpy (wiz->misc_feat_comment, contains);
30968     for (i = 0; i < frm->num_features && !missing; i++) {
30969       feat = DialogToPointer (frm->features[i]);
30970       StringCat (wiz->misc_feat_comment, feat);
30971       feat = MemFree (feat);
30972       if (i < frm->num_features - 1) {
30973         if (frm->num_features > 2) {
30974           StringCat (wiz->misc_feat_comment, ", ");
30975         } else {
30976           StringCat (wiz->misc_feat_comment, " ");
30977         }
30978         if (i == frm->num_features - 2) {
30979           StringCat (wiz->misc_feat_comment, and);
30980         }
30981       }
30982     }
30983   }
30984 }
30985 
30986 
HasMiscFeatCommentAndOkToContinueToSequin(WizardTrackerPtr wiz)30987 static Boolean HasMiscFeatCommentAndOkToContinueToSequin (WizardTrackerPtr wiz)
30988 {
30989   Boolean rval = FALSE;
30990 
30991   if (StringHasNoText (wiz->misc_feat_comment)) {
30992     Message (MSG_ERROR, "You must provide information for each of the features!");
30993   } else if (StringISearch (wiz->misc_feat_comment, "D-loop") == NULL && StringISearch (wiz->misc_feat_comment, "control region") == NULL) {
30994     Message (MSG_ERROR, "One of the features must be a D-loop or a control region.");
30995   } else {
30996     rval = OkToContinueToSequin(wiz);
30997   }
30998   return rval;
30999 }
31000 
31001 
ClearDloopFeaturesForm(ButtoN b)31002 static void ClearDloopFeaturesForm (ButtoN b)
31003 {
31004   DLoopFeaturesFormPtr frm;
31005   Int4 i;
31006 
31007   frm = (DLoopFeaturesFormPtr) GetObjectExtra (b);
31008   if (frm == NULL) {
31009     return;
31010   }
31011   for (i = 0; i < frm->num_features; i++) {
31012     ResetDloopFeatureDialog(frm->features[i]);
31013   }
31014 }
31015 
31016 
CreateDloopFeaturesForm(WizardTrackerPtr wiz,Int4 num_features)31017 static Boolean CreateDloopFeaturesForm (WizardTrackerPtr wiz, Int4 num_features)
31018 {
31019   DLoopFeaturesFormPtr frm;
31020   WindoW w;
31021   GrouP  h;
31022   PrompT ppt;
31023   GrouP  g, c;
31024   ButtoN  b;
31025   CharPtr dlg_title;
31026   Char    buf[50];
31027   CharPtr fmt = "Feature %d";
31028   Int4    i;
31029 
31030   frm = (DLoopFeaturesFormPtr) MemNew (sizeof (DLoopFeaturesFormData));
31031   frm->wiz = wiz;
31032 
31033   dlg_title = "D-Loop Feature Annotation";
31034   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
31035   SetObjectExtra (w, frm, CleanupDloopFeaturesForm);
31036   frm->form = (ForM) w;
31037   frm->collect_func = CollectDloopFeatures;
31038   frm->fwd_ok_func = HasMiscFeatCommentAndOkToContinueToSequin;
31039   frm->next_form = FinishWizardAndLaunchSequin;
31040   frm->num_features = num_features;
31041 
31042   h = HiddenGroup (w, -1, -1, NULL);
31043   SetGroupSpacing (h, 10, 10);
31044 
31045   ppt = StaticPrompt (h, "Starting at the 5' end, please select the features in your sequences.",
31046                       0, 0, programFont, 'c');
31047 
31048   g = HiddenGroup (h, num_features, 0, NULL);
31049   frm->features = (DialoG PNTR) MemNew (sizeof (DialoG) * frm->num_features);
31050 
31051   StaticPrompt (g, "5' end", 0, 0, programFont, 'l');
31052   for (i = 1; i < frm->num_features - 1; i++) {
31053     StaticPrompt (g, "", 0, 0, programFont, 'c');
31054   }
31055   StaticPrompt (g, "3' end", 0, 0, programFont, 'r');
31056 
31057   for (i = 0; i < frm->num_features; i++) {
31058     sprintf (buf, fmt, i + 1);
31059     frm->features[i] = CreateDLoopFeatureDialog (g, buf, ChangeDloopFeature, frm);
31060   }
31061 
31062   b = PushButton (h, "Clear", ClearDloopFeaturesForm);
31063   SetObjectExtra (b, frm, NULL);
31064 
31065   c = MakeWizardNav (h, frm);
31066 
31067   AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) g, (HANDLE) b, (HANDLE) c, NULL);
31068 
31069   Update();
31070   Show (w);
31071   return TRUE;
31072 }
31073 
31074 
31075 typedef struct bioprojectbiosampleform {
31076   WIZARD_BLOCK
31077   TexT bioproject;
31078   TexT srr;
31079   TexT biosample;
31080 } BioProjectBioSampleFormData, PNTR BioProjectBioSampleFormPtr;
31081 
31082 
CollectBioProjectBioSample(Pointer data,WizardTrackerPtr wiz)31083 static void CollectBioProjectBioSample (Pointer data, WizardTrackerPtr wiz)
31084 {
31085   BioProjectBioSampleFormPtr frm;
31086 
31087   frm = (BioProjectBioSampleFormPtr) data;
31088   if (frm == NULL || wiz == NULL) {
31089     return;
31090   }
31091 
31092   wiz->bioproject = MemFree (wiz->bioproject);
31093   wiz->biosample  = MemFree (wiz->biosample);
31094   wiz->srr = MemFree (wiz->srr);
31095   wiz->bioproject = SaveStringFromText (frm->bioproject);
31096   if (frm->biosample != NULL) {
31097     wiz->biosample = SaveStringFromText (frm->biosample);
31098   }
31099   if (frm->srr != NULL) {
31100     wiz->srr = SaveStringFromText (frm->srr);
31101   }
31102 }
31103 
31104 
HasBioProject(WizardTrackerPtr wiz)31105 static Boolean HasBioProject (WizardTrackerPtr wiz)
31106 {
31107   Boolean rval;
31108 
31109   if (StringHasNoText (wiz->bioproject)) {
31110     rval = FALSE;
31111     Message (MSG_ERROR, "You must provide a BioProject!");
31112   } else {
31113     rval = TRUE;
31114   }
31115   return rval;
31116 }
31117 
31118 
RegisterBioProjectBtn(ButtoN b)31119 static void RegisterBioProjectBtn (ButtoN b)
31120 {
31121   LaunchWebBrowser("https://dsubmit.ncbi.nlm.nih.gov/subs/SUB002235/submitter");
31122 }
31123 
31124 
RegisterSRRBtn(ButtoN b)31125 static void RegisterSRRBtn (ButtoN b)
31126 {
31127   LaunchWebBrowser("http://trace.ncbi.nlm.nih.gov/Traces/sra/sra.cgi?view=announcement");
31128 }
31129 
RegisterBioSampleBtn(ButtoN b)31130 static void RegisterBioSampleBtn (ButtoN b)
31131 {
31132   LaunchWebBrowser("https://dsubmit.ncbi.nlm.nih.gov/subs/SUB002236/submitter");
31133 }
31134 
31135 
BioProjectBioSampleWindow(WizardTrackerPtr wiz)31136 static Boolean BioProjectBioSampleWindow(WizardTrackerPtr wiz)
31137 {
31138   BioProjectBioSampleFormPtr frm;
31139   WindoW w;
31140   GrouP  h;
31141   GrouP  g, c;
31142   CharPtr dlg_title;
31143 
31144   frm = (BioProjectBioSampleFormPtr) MemNew (sizeof (BioProjectBioSampleFormData));
31145   frm->wiz = wiz;
31146 
31147   dlg_title = FormatWizardTitle("%s BioProject and BioSample", wiz->wizard_type);
31148   w = FixedWindow (-50, -33, -10, -10, dlg_title, NULL);
31149   SetObjectExtra (w, frm, CleanupWizardForm);
31150   frm->form = (ForM) w;
31151   frm->collect_func = CollectBioProjectBioSample;
31152   frm->fwd_ok_func = HasBioProject;
31153   if (wiz->wizard_type == eWizardType_WGS) {
31154     frm->next_form = CreateWizardSingleSourceForm;
31155   } else {
31156     frm->next_form = CreateWizardSrcQualsForm;
31157   }
31158 
31159   h = HiddenGroup (w, -1, -1, NULL);
31160   SetGroupSpacing (h, 10, 10);
31161 
31162   g = HiddenGroup (h, 3, 0, NULL);
31163   StaticPrompt (g, "BioProject Accession (required)", 0, 0, programFont, 'c');
31164   frm->bioproject = DialogText (g, wiz->bioproject, 10, NULL);
31165   PushButton (g, "If you have not registered your project, please register at BioProject", RegisterBioProjectBtn);
31166   StaticPrompt (g, "", 0, 0, programFont, 'c');
31167   StaticPrompt (g, "", 0, 0, programFont, 'c');
31168   StaticPrompt (g, "", 0, 0, programFont, 'c');
31169   if (wiz->wizard_type != eWizardType_WGS) {
31170     StaticPrompt (g, "SRA Run accessions (SRR) (if applicable)", 0, 0, programFont, 'c');
31171     frm->srr = DialogText (g, wiz->srr, 10, NULL);
31172     PushButton (g, "Link to submit NextGen primary sequence data to SRA", RegisterSRRBtn);
31173     StaticPrompt (g, "", 0, 0, programFont, 'c');
31174     StaticPrompt (g, "", 0, 0, programFont, 'c');
31175     StaticPrompt (g, "", 0, 0, programFont, 'c');
31176   }
31177   StaticPrompt (g, "BioSample Accession (optional)", 0, 0, programFont, 'c');
31178   frm->biosample = DialogText (g, wiz->biosample, 10, NULL);
31179   PushButton (g, "Link to register for a BioSample accession", RegisterBioSampleBtn);
31180 
31181   c = MakeWizardNav (h, frm);
31182 
31183 
31184   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
31185 
31186   Update();
31187   Show (w);
31188   SendHelpScrollMessage (helpForm, dlg_title, "");
31189   dlg_title = MemFree (dlg_title);
31190   return TRUE;
31191 }
31192 
31193 
31194 typedef struct splitint {
31195   Int4 start;
31196   Int4 stop;
31197 } SplitIntData, PNTR SplitIntPtr;
31198 
31199 
SplitIntNew(Int4 start,Int4 stop)31200 static SplitIntPtr SplitIntNew (Int4 start, Int4 stop)
31201 {
31202   SplitIntPtr s;
31203 
31204   s = (SplitIntPtr) MemNew (sizeof (SplitIntData));
31205   s->start = start;
31206   s->stop = stop;
31207   return s;
31208 }
31209 
31210 
SplitIntListCopy(ValNodePtr orig)31211 static ValNodePtr SplitIntListCopy (ValNodePtr orig)
31212 {
31213   ValNodeBlock block;
31214   ValNodePtr vnp;
31215   SplitIntPtr s;
31216 
31217   InitValNodeBlock (&block, NULL);
31218 
31219   for (vnp = orig; vnp != NULL; vnp = vnp->next) {
31220     if ((s = (SplitIntPtr)vnp->data.ptrvalue) != NULL) {
31221       ValNodeAddPointerToEnd (&block, 0, SplitIntNew (s->start, s->stop));
31222     }
31223   }
31224   return block.head;
31225 }
31226 
31227 
31228 typedef struct ambiguousend {
31229   BioseqPtr bsp;
31230   Int4      trim5;
31231   Int4      trim3;
31232   Int4      longest_n_run;
31233   Int4      untrimmed_ns;
31234   Int4      num_n_not_in_run;
31235   Char      id[100];
31236   CharPtr   orig_id;
31237   Boolean   is_new;
31238   ValNodePtr split_locs;
31239 } AmbiguousEndData, PNTR AmbiguousEndPtr;
31240 
31241 
AmbiguousEndNew(BioseqPtr bsp,Int4 trim5,Int4 trim3)31242 static AmbiguousEndPtr AmbiguousEndNew (BioseqPtr bsp, Int4 trim5, Int4 trim3)
31243 {
31244   AmbiguousEndPtr a;
31245 
31246   a = (AmbiguousEndPtr) MemNew (sizeof (AmbiguousEndData));
31247   MemSet (a, 0, sizeof (AmbiguousEndData));
31248   a->bsp = bsp;
31249   a->trim5 = trim5;
31250   a->trim3 = trim3;
31251   a->longest_n_run = 0;
31252   a->untrimmed_ns = 0;
31253   a->is_new = FALSE;
31254   a->split_locs = NULL;
31255   a->orig_id = NULL;
31256   if (a->bsp != NULL) {
31257     SeqIdWrite (SeqIdFindBest (a->bsp->id, SEQID_GENBANK), a->id, PRINTID_REPORT, sizeof (a->id) - 1);
31258   }
31259   return a;
31260 }
31261 
31262 
AmbiguousEndCopy(AmbiguousEndPtr orig)31263 static AmbiguousEndPtr AmbiguousEndCopy (AmbiguousEndPtr orig)
31264 {
31265   AmbiguousEndPtr a;
31266 
31267   if (orig == NULL) {
31268     return NULL;
31269   }
31270   a = (AmbiguousEndPtr) MemNew (sizeof (AmbiguousEndData));
31271   MemSet (a, 0, sizeof (AmbiguousEndData));
31272   a->bsp = orig->bsp;
31273   a->trim5 = orig->trim5;
31274   a->trim3 = orig->trim3;
31275   a->longest_n_run = orig->longest_n_run;
31276   a->untrimmed_ns = orig->untrimmed_ns;
31277   a->is_new = orig->is_new;
31278   a->split_locs = SplitIntListCopy(orig->split_locs);
31279   if (orig->orig_id != NULL) {
31280     a->orig_id = StringSave (orig->orig_id);
31281   }
31282   StringCpy (a->id, orig->id);
31283   return a;
31284 }
31285 
31286 
AmbiguousEndFree(AmbiguousEndPtr a)31287 static AmbiguousEndPtr AmbiguousEndFree (AmbiguousEndPtr a)
31288 {
31289   if (a != NULL) {
31290     a->split_locs = ValNodeFreeData (a->split_locs);
31291     a->orig_id = MemFree (a->orig_id);
31292     a = MemFree (a);
31293   }
31294   return a;
31295 }
31296 
31297 
AmbiguousEndListFree(ValNodePtr list)31298 static ValNodePtr AmbiguousEndListFree (ValNodePtr list)
31299 {
31300   ValNodePtr vnp;
31301   for (vnp = list; vnp != NULL; vnp = vnp->next) {
31302     vnp->data.ptrvalue = AmbiguousEndFree (vnp->data.ptrvalue);
31303   }
31304   list = ValNodeFree (list);
31305   return list;
31306 }
31307 
31308 
31309 static void DoAmbiguous3EndTrim (AmbiguousEndPtr a, SeqEntryPtr top_sep);
31310 static void DoAmbiguous5EndTrim (AmbiguousEndPtr a, SeqEntryPtr top_sep);
31311 
31312 
SplitOneAtSplitLocations(AmbiguousEndPtr a,SeqEntryPtr top_sep,Int4 min_len)31313 static ValNodePtr SplitOneAtSplitLocations (AmbiguousEndPtr a, SeqEntryPtr top_sep, Int4 min_len)
31314 {
31315   ValNodePtr list = NULL, vnp;
31316   AmbiguousEndPtr a_new;
31317   BioseqPtr       bsp_new;
31318   SeqIdPtr        sip, sip_remove, sip_next;
31319   SplitIntPtr     s;
31320 
31321   if (a == NULL || a->split_locs == NULL) {
31322     return NULL;
31323   }
31324 
31325   for (vnp = a->split_locs; vnp != NULL; vnp = vnp->next) {
31326     s = (SplitIntPtr) vnp->data.ptrvalue;
31327     bsp_new = (BioseqPtr) AsnIoMemCopy (a->bsp, (AsnReadFunc) BioseqAsnRead, (AsnWriteFunc) BioseqAsnWrite);
31328     if (bsp_new == NULL) {
31329       Message (MSG_POSTERR, "Out of memory!");
31330       break;
31331     }
31332     sip = MakeNewProteinSeqId (NULL, bsp_new->id);
31333     sip_remove = bsp_new->id;
31334     bsp_new->id = sip;
31335     for (sip = sip_remove; sip != NULL; sip = sip_next) {
31336       sip_next = sip->next;
31337       sip->next = NULL;
31338       sip = SeqIdFree (sip);
31339     }
31340     SeqMgrAddToBioseqIndex (bsp_new);
31341     a_new = AmbiguousEndNew (bsp_new, s->stop, a->trim3);
31342     a_new->is_new = TRUE;
31343     if (a->orig_id == NULL) {
31344       a_new->orig_id = StringSave (a->id);
31345     } else {
31346       a_new->orig_id = StringSave (a->orig_id);
31347     }
31348     ValNodeAddPointer (&list, 0, a_new);
31349     a->trim3 = a->bsp->length - s->start;
31350     /* trim now, so not to log trim later */
31351     DoAmbiguous3EndTrim (a, top_sep);
31352     DoAmbiguous5EndTrim (a_new, top_sep);
31353     a = a_new;
31354   }
31355   a->split_locs = ValNodeFreeData (a->split_locs);
31356   return list;
31357 }
31358 
31359 
SplitAtSplitLocations(ValNodePtr list,SeqEntryPtr top_sep,Int4 min_len)31360 static void SplitAtSplitLocations (ValNodePtr list, SeqEntryPtr top_sep, Int4 min_len)
31361 {
31362   ValNodePtr      vnp, vnp_next, new_list;
31363 
31364   for (vnp = list; vnp != NULL; vnp = vnp_next) {
31365     vnp_next = vnp->next;
31366     new_list = SplitOneAtSplitLocations (vnp->data.ptrvalue, top_sep, min_len);
31367     if (new_list != NULL) {
31368       ValNodeLink (&new_list, vnp_next);
31369       vnp->next = new_list;
31370     }
31371   }
31372 }
31373 
31374 
AddSplitBioseqs(SeqEntryPtr sep,ValNodePtr list)31375 static void AddSplitBioseqs (SeqEntryPtr sep, ValNodePtr list)
31376 {
31377   BioseqSetPtr    bssp = NULL;
31378   AmbiguousEndPtr a;
31379   ValNodePtr      vnp;
31380   SeqEntryPtr     sep_last;
31381 
31382   if (sep == NULL || list == NULL) {
31383     return;
31384   }
31385   while (sep->next != NULL) {
31386     sep = sep->next;
31387   }
31388 
31389   if (IS_Bioseq (sep)) {
31390     sep_last = sep;
31391   } else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL) {
31392     sep_last = bssp->seq_set;
31393     if (sep_last != NULL) {
31394       while (sep_last->next != NULL) {
31395         sep_last = sep_last->next;
31396       }
31397     }
31398   } else {
31399     return;
31400   }
31401 
31402   for (vnp = list; vnp != NULL; vnp = vnp->next) {
31403     a = (AmbiguousEndPtr) vnp->data.ptrvalue;
31404     if (a->is_new) {
31405       sep = SeqEntryNew ();
31406       sep->choice = 1;
31407       sep->data.ptrvalue = a->bsp;
31408       SeqMgrSeqEntry(OBJ_BIOSEQ, sep->data.ptrvalue, sep);
31409       if (sep_last == NULL) {
31410         bssp->seq_set = sep;
31411       } else {
31412         sep_last->next = sep;
31413       }
31414       sep_last = sep;
31415       a->is_new = FALSE;
31416     }
31417   }
31418 }
31419 
31420 
ClearSplitLocs(ValNodePtr list)31421 static void ClearSplitLocs (ValNodePtr list)
31422 {
31423   AmbiguousEndPtr a;
31424 
31425   while (list != NULL) {
31426     if ((a = (AmbiguousEndPtr) list->data.ptrvalue) != NULL) {
31427       a->split_locs = ValNodeFreeData (a->split_locs);
31428     }
31429     list = list->next;
31430   }
31431 }
31432 
31433 
31434 typedef struct ambicount {
31435   Int4 big_end_size;
31436   FloatLo big_end_percent;
31437   Int4 small_end_size;
31438   FloatLo small_end_percent;
31439   Int4 num_other;
31440   Int4 last_n_pos;
31441   Int4 pos;
31442   Int4 trim;
31443   Boolean all_n;
31444 } AmbicountData, PNTR AmbicountPtr;
31445 
31446 
CountAmbiProc(CharPtr sequence,Pointer userdata)31447 static void LIBCALLBACK CountAmbiProc (CharPtr sequence, Pointer userdata)
31448 {
31449   AmbicountPtr a;
31450   CharPtr cp;
31451   FloatLo pct;
31452   Int4    normal = 0;
31453 
31454   if (sequence == NULL || userdata == NULL) return;
31455   a = (AmbicountPtr) userdata;
31456 
31457   for (cp = sequence; *cp != 0; cp++)
31458   {
31459     if (*cp == 'A' || *cp == 'T' || *cp == 'G' || *cp == 'C')
31460     {
31461       /* ignore */
31462       a->all_n = FALSE;
31463     }
31464     else
31465     {
31466       a->num_other++;
31467       a->last_n_pos = a->pos;
31468       if (a->all_n) {
31469         a->trim = a->last_n_pos + 1;
31470         a->num_other = 0;
31471       }
31472     }
31473     /* a->pos starts at 0, after incrementing, a->pos is count of nt examined already */
31474     a->pos++;
31475     if (a->pos - a->trim == a->big_end_size) {
31476       pct = ((FloatLo)a->num_other * 100) / (FloatLo) (a->pos - a->trim);
31477       if (pct > a->big_end_percent) {
31478         a->trim = a->last_n_pos + 1;
31479         a->num_other = 0;
31480         if (a->pos == a->last_n_pos + 1) {
31481           a->all_n = TRUE;
31482         }
31483       }
31484     }
31485     if (a->pos - a->trim == a->small_end_size) {
31486       pct = ((FloatLo)a->num_other * 100) / (FloatLo) (a->pos - a->trim);
31487       if (pct > a->small_end_percent) {
31488         a->trim = a->last_n_pos + 1;
31489         a->num_other = 0;
31490         if (a->pos == a->last_n_pos + 1) {
31491           a->all_n = TRUE;
31492         }
31493       }
31494     }
31495   }
31496 }
31497 
31498 
FindAmbiguousEndsForBioseq(BioseqPtr bsp,Int4 big_end,FloatLo big_end_percent,Int4 small_end,FloatLo small_end_percent)31499 static AmbiguousEndPtr FindAmbiguousEndsForBioseq (BioseqPtr bsp, Int4 big_end, FloatLo big_end_percent, Int4 small_end, FloatLo small_end_percent)
31500 {
31501   AmbicountData a;
31502   AmbiguousEndPtr ae;
31503 
31504   ae = AmbiguousEndNew (bsp, 0, 0);
31505   MemSet (&a, 0, sizeof (AmbicountData));
31506   a.big_end_size = big_end;
31507   a.big_end_percent = big_end_percent;
31508   a.small_end_size = small_end;
31509   a.small_end_percent = small_end_percent;
31510   SeqPortStreamInt (bsp, 0, bsp->length - 1, Seq_strand_plus, STREAM_EXPAND_GAPS, (Pointer) &a, CountAmbiProc);
31511   ae->trim5 = a.trim;
31512   a.last_n_pos = 0;
31513   a.pos = 0;
31514   a.num_other = 0;
31515   a.trim = 0;
31516 
31517   SeqPortStreamInt (bsp, 0, bsp->length - 1, Seq_strand_minus, STREAM_EXPAND_GAPS, (Pointer) &a, CountAmbiProc);
31518   ae->trim3 = a.trim;
31519   if (ae->trim5 == 0 && ae->trim3 == 0) {
31520     ae = AmbiguousEndFree (ae);
31521   }
31522   return ae;
31523 }
31524 
31525 
FindAmbiguousEnds(SeqEntryPtr sep,ValNodeBlockPtr block)31526 static void FindAmbiguousEnds (SeqEntryPtr sep, ValNodeBlockPtr block)
31527 {
31528   BioseqPtr bsp;
31529   BioseqSetPtr bssp;
31530   AmbiguousEndPtr a;
31531   Int4 big_end = 50;
31532   Int4 small_end = 10;
31533   FloatLo big_end_percent = 30.0;
31534   FloatLo small_end_percent = 50.0;
31535 
31536   while (sep != NULL) {
31537     if (IS_Bioseq (sep) && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL) {
31538       a = FindAmbiguousEndsForBioseq (bsp, big_end, big_end_percent, small_end, small_end_percent);
31539       if (a != NULL) {
31540         ValNodeAddPointerToEnd (block, 0, a);
31541       }
31542     } else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL) {
31543       FindAmbiguousEnds (bssp->seq_set, block);
31544     }
31545     sep = sep->next;
31546   }
31547 }
31548 
31549 
ShrinkTSATrimForLowQuality(AmbiguousEndPtr end,Int4 big_end,FloatLo big_end_percent,Int4 small_end,FloatLo small_end_percent)31550 static void ShrinkTSATrimForLowQuality (AmbiguousEndPtr end, Int4 big_end, FloatLo big_end_percent, Int4 small_end, FloatLo small_end_percent)
31551 {
31552   AmbicountData a;
31553   Int4 trim5, trim3;
31554 
31555   MemSet (&a, 0, sizeof (AmbicountData));
31556   a.big_end_size = big_end;
31557   a.big_end_percent = big_end_percent;
31558   a.small_end_size = small_end;
31559   a.small_end_percent = small_end_percent;
31560   SeqPortStreamInt (end->bsp, end->trim5, end->bsp->length - 1 - end->trim3, Seq_strand_plus, STREAM_EXPAND_GAPS, (Pointer) &a, CountAmbiProc);
31561   trim5 = a.trim;
31562   a.last_n_pos = 0;
31563   a.pos = 0;
31564   a.num_other = 0;
31565   a.trim = 0;
31566 
31567   SeqPortStreamInt (end->bsp, end->trim5, end->bsp->length - 1 - end->trim3, Seq_strand_minus, STREAM_EXPAND_GAPS, (Pointer) &a, CountAmbiProc);
31568   trim3 = a.trim;
31569   end->trim5 += trim5;
31570   end->trim3 += trim3;
31571 }
31572 
31573 
FindTSATrimEndsForBioseq(BioseqPtr bsp,FloatLo n_percent,Int4 run_length,Int4 min_length)31574 static AmbiguousEndPtr FindTSATrimEndsForBioseq (BioseqPtr bsp, FloatLo n_percent, Int4 run_length, Int4 min_length)
31575 {
31576   AmbiguousEndPtr a = NULL;
31577   Int4 trim5 = 0, trim3 = 0;
31578   Int4 big_end = 50;
31579   Int4 small_end = 10;
31580   FloatLo big_end_percent = 30.0;
31581   FloatLo small_end_percent = 50.0;
31582 
31583   TSATrimBioseq (bsp, n_percent, run_length, 200, &trim5, &trim3);
31584   if (trim5 > 0 || trim3 > 0) {
31585     a = AmbiguousEndNew (bsp, trim5, trim3);
31586     ShrinkTSATrimForLowQuality (a, big_end, big_end_percent, small_end, small_end_percent);
31587   } else {
31588     a = FindAmbiguousEndsForBioseq(bsp, big_end, big_end_percent, small_end, small_end_percent);
31589   }
31590 
31591   return a;
31592 }
31593 
31594 
FindTSATrimEnds(SeqEntryPtr sep,ValNodeBlockPtr block)31595 static void FindTSATrimEnds (SeqEntryPtr sep, ValNodeBlockPtr block)
31596 {
31597   BioseqPtr bsp;
31598   BioseqSetPtr bssp;
31599   AmbiguousEndPtr a;
31600   FloatLo n_percent = 0.10;
31601   Int4    run_length = 14;
31602 
31603   while (sep != NULL) {
31604     if (IS_Bioseq (sep) && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL) {
31605       a = FindTSATrimEndsForBioseq (bsp, n_percent, run_length, 200);
31606       if (a != NULL) {
31607         ValNodeAddPointerToEnd (block, 0, a);
31608       }
31609     } else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL) {
31610       FindTSATrimEnds (bssp->seq_set, block);
31611     }
31612     sep = sep->next;
31613   }
31614 }
31615 
31616 
DoAmbiguous5EndTrim(AmbiguousEndPtr a,SeqEntryPtr top_sep)31617 static void DoAmbiguous5EndTrim (AmbiguousEndPtr a, SeqEntryPtr top_sep)
31618 {
31619   SeqLocPtr  delete_loc;
31620   SeqIntPtr  sint;
31621   SeqEntryPtr sep, orig_scope;
31622 
31623   if (a == NULL || a->bsp == NULL) {
31624     return;
31625   }
31626   if (a->trim5 == 0) {
31627     return;
31628   }
31629 
31630   if (IS_Bioseq_set (top_sep)) {
31631     sep = top_sep;
31632   } else {
31633     sep = SeqMgrGetSeqEntryForData (a->bsp);
31634   }
31635   orig_scope = SeqEntrySetScope (sep);
31636 
31637   /* Trim Quality Scores */
31638   TrimQualityScores (a->bsp, a->trim5, TRUE);
31639   sint = SeqIntNew ();
31640   sint->id = SeqIdDup (a->bsp->id);
31641   sint->from = 0;
31642   sint->to = a->trim5 - 1;
31643   delete_loc = ValNodeNew (NULL);
31644   delete_loc->choice = SEQLOC_INT;
31645   delete_loc->data.ptrvalue = sint;
31646   /* delete from alignments */
31647   SeqEntryExplore (top_sep, (Pointer) delete_loc, SeqAlignDeleteByLocCallback);
31648   /* delete from sequence */
31649   SeqDeleteByLocEx (delete_loc, TRUE, FALSE, TRUE);
31650   delete_loc = SeqLocFree (delete_loc);
31651   SeqEntrySetScope (orig_scope);
31652   a->trim5 = 0;
31653 }
31654 
31655 
DoAmbiguous3EndTrim(AmbiguousEndPtr a,SeqEntryPtr top_sep)31656 static void DoAmbiguous3EndTrim (AmbiguousEndPtr a, SeqEntryPtr top_sep)
31657 {
31658   SeqLocPtr  delete_loc;
31659   SeqIntPtr  sint;
31660   SeqEntryPtr sep, orig_scope;
31661 
31662   if (a == NULL || a->bsp == NULL) {
31663     return;
31664   }
31665   if (a->trim3 == 0) {
31666     return;
31667   }
31668 
31669   if (IS_Bioseq_set (top_sep)) {
31670     sep = top_sep;
31671   } else {
31672     sep = SeqMgrGetSeqEntryForData (a->bsp);
31673   }
31674   orig_scope = SeqEntrySetScope (sep);
31675 
31676   /* Trim Quality Scores */
31677   TrimQualityScores (a->bsp, a->trim3, FALSE);
31678   sint = SeqIntNew ();
31679   sint->id = SeqIdDup (a->bsp->id);
31680   sint->from = a->bsp->length - a->trim3;
31681   sint->to = a->bsp->length - 1;
31682   delete_loc = ValNodeNew (NULL);
31683   delete_loc->choice = SEQLOC_INT;
31684   delete_loc->data.ptrvalue = sint;
31685   /* delete from alignments */
31686   SeqEntryExplore (top_sep, (Pointer) delete_loc, SeqAlignDeleteByLocCallback);
31687   /* delete from sequence */
31688   SeqDeleteByLocEx (delete_loc, TRUE, FALSE, TRUE);
31689   delete_loc = SeqLocFree (delete_loc);
31690   SeqEntrySetScope (orig_scope);
31691   a->trim3 = 0;
31692 }
31693 
31694 
TrimAmbiguousEnds(AmbiguousEndPtr a,SeqEntryPtr top_sep,Int4 min_len)31695 static void TrimAmbiguousEnds (AmbiguousEndPtr a, SeqEntryPtr top_sep, Int4 min_len)
31696 {
31697   SeqLocPtr  delete_loc;
31698   SeqIntPtr  sint;
31699   SeqEntryPtr sep, orig_scope;
31700 
31701   if (a == NULL || a->bsp == NULL) {
31702     return;
31703   }
31704   if (a->trim5 == 0 && a->trim3 == 0) {
31705     return;
31706   }
31707   if (a->bsp->length - a->trim5 - a->trim3 < min_len) {
31708     a->bsp->idx.deleteme = 1;
31709     return;
31710   }
31711 
31712   if (IS_Bioseq_set (top_sep)) {
31713     sep = top_sep;
31714   } else {
31715     sep = SeqMgrGetSeqEntryForData (a->bsp);
31716   }
31717   orig_scope = SeqEntrySetScope (sep);
31718 
31719   if (a->trim3 > 0) {
31720     /* Trim Quality Scores */
31721     TrimQualityScores (a->bsp, a->trim3, FALSE);
31722     sint = SeqIntNew ();
31723     sint->id = SeqIdDup (a->bsp->id);
31724     sint->from = a->bsp->length - a->trim3;
31725     sint->to = a->bsp->length - 1;
31726     delete_loc = ValNodeNew (NULL);
31727     delete_loc->choice = SEQLOC_INT;
31728     delete_loc->data.ptrvalue = sint;
31729     /* delete from alignments */
31730     SeqEntryExplore (top_sep, (Pointer) delete_loc, SeqAlignDeleteByLocCallback);
31731     /* delete from sequence */
31732     SeqDeleteByLocEx (delete_loc, TRUE, FALSE, TRUE);
31733     delete_loc = SeqLocFree (delete_loc);
31734   }
31735   if (a->trim5 > 0) {
31736     /* Trim Quality Scores */
31737     TrimQualityScores (a->bsp, a->trim5, TRUE);
31738     sint = SeqIntNew ();
31739     sint->id = SeqIdDup (a->bsp->id);
31740     sint->from = 0;
31741     sint->to = a->trim5 - 1;
31742     delete_loc = ValNodeNew (NULL);
31743     delete_loc->choice = SEQLOC_INT;
31744     delete_loc->data.ptrvalue = sint;
31745     /* delete from alignments */
31746     SeqEntryExplore (top_sep, (Pointer) delete_loc, SeqAlignDeleteByLocCallback);
31747     /* delete from sequence */
31748     SeqDeleteByLocEx (delete_loc, TRUE, FALSE, TRUE);
31749     delete_loc = SeqLocFree (delete_loc);
31750   }
31751   SeqEntrySetScope (orig_scope);
31752 }
31753 
31754 
OkToTrimAmbiguous(ValNodePtr list,Int4 min_length,CharPtr delete_warn_fmt,CharPtr extra_warning,CharPtr optional_title)31755 static Boolean OkToTrimAmbiguous (ValNodePtr list, Int4 min_length, CharPtr delete_warn_fmt, CharPtr extra_warning, CharPtr optional_title)
31756 {
31757   ModalAcceptCancelData acd;
31758   WindoW                w;
31759   GrouP                 h, c, prompt_group, boxes_group;
31760   ButtoN                b;
31761   Boolean               rval = FALSE;
31762   CharPtr               msg;
31763   DoC                   doc1 = NULL, doc2 = NULL;
31764   PrompT                p1, title = NULL, pr = NULL, pt = NULL;
31765   GrouP                 p2 = NULL;
31766   CharPtr               question;
31767   Int4 num_delete = 0, delete_msg_len = 1;
31768   Int4 num_trim = 0, trim_msg_len = 1;
31769   ValNodePtr vnp;
31770   AmbiguousEndPtr a;
31771   CharPtr      trim_warn_fmt = "The 5' and/or 3' ends of the %d sequences listed below include significant ambiguous bases, which may mean these regions are of low quality. We suggest that you trim them.";
31772   CharPtr      end5 = " %d from 5' end";
31773   CharPtr      end3 = " %d from 3' end";
31774   Int4         len;
31775   LogInfoPtr   lip;
31776 
31777   for (vnp = list; vnp != NULL; vnp = vnp->next) {
31778     a = (AmbiguousEndPtr) vnp->data.ptrvalue;
31779     if (a->bsp->length - a->trim5 - a->trim3 < min_length) {
31780       num_delete++;
31781       delete_msg_len += StringLen (a->id) + 1;
31782     } else {
31783       num_trim++;
31784       trim_msg_len += StringLen (a->id) + 2;
31785       if (a->trim5 > 0) {
31786         trim_msg_len += 15 + StringLen (end5);
31787         if (a->trim3) {
31788           trim_msg_len += 1;
31789         }
31790       }
31791       if (a->trim3 > 0) {
31792         trim_msg_len += 15 + StringLen (end3);
31793       }
31794     }
31795   }
31796 
31797   lip = OpenLog ("Sequence Changes");
31798   acd.accepted = FALSE;
31799   acd.cancelled = FALSE;
31800   acd.third_option = FALSE;
31801 
31802   w = ModalWindow(-20, -13, -10, -10, NULL);
31803   h = HiddenGroup (w, -1, 0, NULL);
31804   SetGroupSpacing (h, 10, 10);
31805 
31806   if (optional_title != NULL) {
31807     title = StaticPrompt (h, optional_title, 0, 0, programFont, 'c');
31808   }
31809 
31810   boxes_group = HiddenGroup (h, -1, 0, NULL);
31811   SetGroupSpacing (boxes_group, 10, 10);
31812   if (num_delete > 0) {
31813     pr = StaticPrompt (boxes_group, "Sequences to be removed:", 0, 0, programFont, 'c');
31814     doc1 = DocumentPanel (boxes_group, 800, 100);
31815     SetDocAutoAdjust (doc1, TRUE);
31816     msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (delete_warn_fmt) + 15));
31817     sprintf (msg, delete_warn_fmt, num_delete);
31818     AppendText (doc1, msg, NULL, NULL, programFont);
31819     msg = MemFree (msg);
31820     msg = (CharPtr) MemNew (sizeof (Char) * delete_msg_len);
31821     for (vnp = list; vnp != NULL; vnp = vnp->next) {
31822       a = (AmbiguousEndPtr) vnp->data.ptrvalue;
31823       if (a->bsp->length - a->trim5 - a->trim3 < min_length) {
31824         StringCat (msg, a->id);
31825         StringCat (msg, "\n");
31826       }
31827     }
31828     AppendText (doc1, msg, NULL, NULL, programFont);
31829     fprintf (lip->fp, "Sequences Removed:\n");
31830     fprintf (lip->fp, "%s\n", msg);
31831     lip->data_in_log = TRUE;
31832     msg = MemFree (msg);
31833   }
31834   if (num_trim > 0) {
31835     pt = StaticPrompt (boxes_group, "Sequences to be trimmed:", 0, 0, programFont, 'c');
31836     doc2 = DocumentPanel (boxes_group, 800, 100);
31837     SetDocAutoAdjust (doc2, TRUE);
31838     msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (trim_warn_fmt) + 15));
31839     sprintf (msg, trim_warn_fmt, num_trim);
31840     AppendText (doc2, msg, NULL, NULL, programFont);
31841     msg = MemFree (msg);
31842     msg = (CharPtr) MemNew (sizeof (Char) * trim_msg_len);
31843     for (vnp = list; vnp != NULL; vnp = vnp->next) {
31844       a = (AmbiguousEndPtr) vnp->data.ptrvalue;
31845       if (a->bsp->length - a->trim5 - a->trim3 < min_length) {
31846         /* already listed in delete section */
31847       } else {
31848         StringCat (msg, a->id);
31849         StringCat (msg, ":");
31850         len = StringLen (msg);
31851         if (a->trim5 > 0) {
31852           sprintf (msg + len, end5, a->trim5);
31853           if (a->trim3 > 0) {
31854             StringCat (msg, ",");
31855           }
31856           len = StringLen (msg);
31857         }
31858         if (a->trim3 > 0) {
31859           sprintf (msg + len, end3, a->trim3);
31860         }
31861         StringCat (msg, "\n");
31862       }
31863     }
31864     AppendText (doc2, msg, NULL, NULL, programFont);
31865     fprintf (lip->fp, "Sequences Trimmed:\n");
31866     fprintf (lip->fp, "%s", msg);
31867     lip->data_in_log = TRUE;
31868     msg = MemFree (msg);
31869     if (doc1 == NULL) {
31870       AlignObjects (ALIGN_CENTER, (HANDLE) pt, (HANDLE) doc2, NULL);
31871     } else {
31872       AlignObjects (ALIGN_CENTER, (HANDLE) pr, (HANDLE) doc1, (HANDLE) pt, (HANDLE) doc2, NULL);
31873     }
31874   }
31875 
31876   prompt_group = HiddenGroup (h, -1, 0, NULL);
31877   SetGroupSpacing (prompt_group, 10, 10);
31878 
31879   if (num_delete > 0 && num_trim > 0) {
31880     question = "Would you like to proceed with the actions listed above now?";
31881   } else if (num_delete > 0) {
31882     question = "Would you like to remove the sequences above now?";
31883   } else {
31884     question = "Would you like to trim the sequences above now?";
31885   }
31886 
31887   if (extra_warning != NULL) {
31888     msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (extra_warning) + StringLen (question) + 2));
31889     sprintf (msg, "%s\n%s", extra_warning, question);
31890     p2 = MultiLinePrompt (prompt_group, msg, 60 * stdCharWidth, programFont);
31891     msg = MemFree (msg);
31892   } else {
31893     p1 = StaticPrompt (prompt_group, question, 0, 0, programFont, 'c');
31894   }
31895 
31896   c = HiddenGroup (h, 3, 0, NULL);
31897   SetGroupSpacing (c, 10, 10);
31898   b = PushButton (c, "Yes", ModalAcceptButton);
31899   SetObjectExtra (b, &acd, NULL);
31900   b = PushButton (c, "No", ModalCancelButton);
31901   SetObjectExtra (b, &acd, NULL);
31902   AlignObjects (ALIGN_CENTER, (HANDLE) prompt_group, (HANDLE) c, (HANDLE) boxes_group, (HANDLE) title, NULL);
31903 
31904   Show(w);
31905   Select (w);
31906   while (!acd.accepted && ! acd.cancelled)
31907   {
31908     ProcessExternalEvent ();
31909     Update ();
31910   }
31911   ProcessAnEvent ();
31912   Remove (w);
31913   if (acd.accepted)
31914   {
31915     rval = TRUE;
31916     CloseLog (lip);
31917   }
31918   lip = FreeLog (lip);
31919   return rval;
31920 }
31921 
31922 
RemoveOneSequenceFromAlignmentsByIdx(SeqEntryPtr sequences,SeqIdPtr sip)31923 static void RemoveOneSequenceFromAlignmentsByIdx (SeqEntryPtr sequences, SeqIdPtr sip)
31924 {
31925   SeqEntryPtr sep;
31926   BioseqPtr bsp;
31927   BioseqSetPtr bssp;
31928   SeqAnnotPtr sap;
31929 
31930   for (sep = sequences; sep != NULL; sep = sep->next)
31931   {
31932     sap = NULL;
31933     if (IS_Bioseq (sep)
31934         && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL)
31935     {
31936       sap = bsp->annot;
31937     }
31938     else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL)
31939     {
31940       sap = bssp->annot;
31941     }
31942     while (sap != NULL) {
31943       if (sap->type == 2) {
31944         RemoveOneSequenceFromAlignment(sip, sap->data);
31945       }
31946       sap = sap->next;
31947     }
31948   }
31949 }
31950 
31951 
RemoveSequencesFromAlignmentByIdx(SeqEntryPtr sequences,SeqEntryPtr top_sep)31952 static void RemoveSequencesFromAlignmentByIdx (SeqEntryPtr sequences, SeqEntryPtr top_sep)
31953 {
31954   SeqEntryPtr sep;
31955   BioseqPtr bsp;
31956   BioseqSetPtr bssp;
31957 
31958   if (top_sep == NULL) {
31959     top_sep = sequences;
31960   }
31961 
31962   for (sep = sequences; sep != NULL; sep = sep->next)
31963   {
31964     if (IS_Bioseq (sep)
31965         && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL
31966         && bsp->idx.deleteme)
31967     {
31968       RemoveOneSequenceFromAlignmentsByIdx(top_sep, bsp->id);
31969     }
31970     else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL)
31971     {
31972       RemoveSequencesFromAlignmentByIdx (bssp->seq_set, top_sep);
31973     }
31974   }
31975 }
31976 
31977 
RemoveSequencesByIdxEx(SeqEntryPtr PNTR sequences)31978 static void RemoveSequencesByIdxEx (SeqEntryPtr PNTR sequences)
31979 {
31980   SeqEntryPtr sep, sep_prev = NULL, sep_next;
31981   BioseqPtr bsp;
31982   BioseqSetPtr bssp;
31983 
31984   if (sequences == NULL) {
31985     return;
31986   }
31987   for (sep = *sequences; sep != NULL; sep = sep_next)
31988   {
31989     sep_next = sep->next;
31990     if (IS_Bioseq (sep)
31991         && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL
31992         && bsp->idx.deleteme)
31993     {
31994       if (sep_prev == NULL)
31995       {
31996         *sequences = sep_next;
31997       }
31998       else
31999       {
32000         sep_prev->next = sep_next;
32001       }
32002       sep->next = NULL;
32003       sep = SeqEntryFree (sep);
32004     }
32005     else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL)
32006     {
32007       RemoveSequencesByIdxEx (&(bssp->seq_set));
32008       sep_prev = sep;
32009     }
32010     else
32011     {
32012       sep_prev = sep;
32013     }
32014   }
32015 }
32016 
32017 
RemoveSequencesByIdx(SeqEntryPtr PNTR sequences)32018 static void RemoveSequencesByIdx (SeqEntryPtr PNTR sequences)
32019 {
32020   if (sequences == NULL) {
32021     return;
32022   }
32023   RemoveSequencesFromAlignmentByIdx (*sequences, *sequences);
32024   RemoveSequencesByIdxEx (sequences);
32025 }
32026 
32027 
TrimAmbiguousBases(SeqEntryPtr PNTR sequences)32028 NLM_EXTERN void TrimAmbiguousBases (SeqEntryPtr PNTR sequences)
32029 {
32030   ValNodeBlock block;
32031   ValNodePtr   vnp;
32032   AmbiguousEndPtr a;
32033   SeqEntryPtr orig_scope;
32034   CharPtr     delete_warn_fmt = "The %d sequence(s) listed below have a high percentage of ambiguous bases, which may mean these regions are of low quality.  We suggest that you remove them from the submission.";
32035 
32036 
32037   if (sequences == NULL || *sequences == NULL) {
32038     return;
32039   }
32040   InitValNodeBlock (&block, NULL);
32041 
32042   FindAmbiguousEnds (*sequences, &block);
32043   if (block.head == NULL || !OkToTrimAmbiguous(block.head, 50, delete_warn_fmt, NULL, NULL)) {
32044     return;
32045   }
32046 
32047   orig_scope = SeqEntrySetScope (*sequences);
32048   for (vnp = block.head; vnp != NULL; vnp = vnp->next) {
32049     a = (AmbiguousEndPtr) vnp->data.ptrvalue;
32050     TrimAmbiguousEnds (a, *sequences, 50);
32051   }
32052   block.head = AmbiguousEndListFree (block.head);
32053   /* actually remove the sequences */
32054   RemoveSequencesByIdx (sequences);
32055   SeqEntrySetScope(orig_scope);
32056 }
32057 
32058 
TrimTSABases(SeqEntryPtr PNTR sequences)32059 static void TrimTSABases (SeqEntryPtr PNTR sequences)
32060 {
32061   ValNodeBlock block;
32062   ValNodePtr   vnp;
32063   AmbiguousEndPtr a;
32064   SeqEntryPtr orig_scope;
32065   CharPtr     delete_warn_fmt = "The %d sequence(s) listed below are less than 200 nucleotides or have a high percentage of amibiguous bases..  We suggest that you remove them from the submission.";
32066   CharPtr     extra_warning = "Some of your sequences do not meet the requirements for the TSA database. Note you will delay processing of your file if you do not remove or trim these sequences.";
32067   CharPtr     title = "The following sequences do not meet the requirements for the TSA database.";
32068 
32069   if (sequences == NULL || *sequences == NULL) {
32070     return;
32071   }
32072   InitValNodeBlock (&block, NULL);
32073 
32074   FindTSATrimEnds (*sequences, &block);
32075   if (block.head == NULL || !OkToTrimAmbiguous(block.head, 50, delete_warn_fmt, extra_warning, title)) {
32076     return;
32077   }
32078 
32079   orig_scope = SeqEntrySetScope (*sequences);
32080   for (vnp = block.head; vnp != NULL; vnp = vnp->next) {
32081     a = (AmbiguousEndPtr) vnp->data.ptrvalue;
32082     TrimAmbiguousEnds (a, *sequences, 50);
32083   }
32084   block.head = AmbiguousEndListFree (block.head);
32085   /* actually remove the sequences */
32086   RemoveSequencesByIdx (sequences);
32087   SeqEntrySetScope(orig_scope);
32088 }
32089 
32090 
TrimLowQualitySequences(SeqEntryPtr PNTR sequences,EWizardType wizard_type)32091 static void TrimLowQualitySequences (SeqEntryPtr PNTR sequences, EWizardType wizard_type)
32092 {
32093   TrimAmbiguousBases(sequences);
32094 }
32095 
32096 
CountShortSequences(SeqEntryPtr seq_list,Int4 less_than)32097 static Int4 CountShortSequences (SeqEntryPtr seq_list, Int4 less_than)
32098 {
32099   Int4 num_less_than = 0;
32100   BioseqPtr bsp;
32101   BioseqSetPtr bssp;
32102 
32103   while (seq_list != NULL) {
32104     if (IS_Bioseq (seq_list)) {
32105       bsp = (BioseqPtr) seq_list->data.ptrvalue;
32106       if (bsp != NULL && bsp->length < less_than) {
32107         num_less_than++;
32108       }
32109     } else if (IS_Bioseq_set (seq_list)) {
32110       bssp = (BioseqSetPtr) seq_list->data.ptrvalue;
32111       if (bssp != NULL) {
32112         num_less_than += CountShortSequences (bssp->seq_set, less_than);
32113       }
32114     }
32115     seq_list = seq_list->next;
32116   }
32117   return num_less_than;
32118 }
32119 
32120 
32121 typedef struct termncount {
32122   Int4 pos;
32123   Int4 trim;
32124   Boolean all_n;
32125   Int4 num_n;
32126   Int4 num_n_not_in_run;
32127   Int4 run_size;
32128   Int4 best_run_size;
32129 } TermNCountData, PNTR TermNCountPtr;
32130 
TermNProc(CharPtr sequence,Pointer userdata)32131 static void LIBCALLBACK TermNProc (CharPtr sequence, Pointer userdata)
32132 {
32133   TermNCountPtr tn;
32134   CharPtr cp;
32135 
32136   if (sequence == NULL || userdata == NULL) return;
32137   tn = (TermNCountPtr) userdata;
32138 
32139   for (cp = sequence; *cp != 0; cp++)
32140   {
32141     if (*cp == 'A' || *cp == 'T' || *cp == 'G' || *cp == 'C')
32142     {
32143       /* ignore */
32144       tn->all_n = FALSE;
32145       if (tn->run_size < 10) {
32146         tn->num_n_not_in_run += tn->run_size;
32147       }
32148       if (tn->run_size > tn->best_run_size) {
32149         tn->best_run_size = tn->run_size;
32150       }
32151       tn->run_size = 0;
32152     }
32153     else
32154     {
32155       tn->num_n++;
32156       if (tn->all_n) {
32157         tn->trim = tn->pos + 1;
32158         tn->num_n = 0;
32159       } else {
32160         tn->run_size ++;
32161       }
32162     }
32163     /* a->pos starts at 0, after incrementing, a->pos is count of nt examined already */
32164     tn->pos++;
32165   }
32166 }
32167 
32168 
ShrinkForTerminalNs(AmbiguousEndPtr a)32169 static void ShrinkForTerminalNs (AmbiguousEndPtr a)
32170 {
32171   TermNCountData tn;
32172 
32173   if (a == NULL || a->bsp == NULL || a->bsp->length < a->trim5 + a->trim3) {
32174     return;
32175   }
32176   MemSet (&tn, 0, sizeof (TermNCountData));
32177   tn.all_n = TRUE;
32178   SeqPortStreamInt (a->bsp, a->trim5, a->bsp->length - 1 - a->trim3, Seq_strand_plus, STREAM_EXPAND_GAPS, (Pointer) &tn, TermNProc);
32179   a->trim5 += tn.trim;
32180   MemSet (&tn, 0, sizeof (TermNCountData));
32181   tn.all_n = TRUE;
32182   SeqPortStreamInt (a->bsp, a->trim5, a->bsp->length - 1 - a->trim3, Seq_strand_minus, STREAM_EXPAND_GAPS, (Pointer) &tn, TermNProc);
32183   a->trim3 += tn.trim;
32184   a->untrimmed_ns = tn.num_n;
32185   a->num_n_not_in_run = tn.num_n_not_in_run;
32186   a->longest_n_run = tn.best_run_size;
32187 }
32188 
32189 
GetAmbiguousEndBlankList(SeqEntryPtr sep,ValNodeBlockPtr block)32190 static void GetAmbiguousEndBlankList (SeqEntryPtr sep, ValNodeBlockPtr block)
32191 {
32192   BioseqPtr    bsp;
32193   BioseqSetPtr bssp;
32194   while (sep != NULL) {
32195     if (IS_Bioseq (sep) && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL) {
32196       ValNodeAddPointerToEnd (block, 0, AmbiguousEndNew (bsp, 0, 0));
32197     } else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL) {
32198       GetAmbiguousEndBlankList (bssp->seq_set, block);
32199     }
32200     sep = sep->next;
32201   }
32202 }
32203 
32204 
CombineSplitsForAmbiguousEnd(AmbiguousEndPtr a,Int4 min_length)32205 static void CombineSplitsForAmbiguousEnd (AmbiguousEndPtr a, Int4 min_length)
32206 {
32207   SplitIntPtr      s, s_prev;
32208   ValNodePtr       vnp, vnp_prev, vnp_next;
32209 
32210   if (a == NULL || a->split_locs == NULL || a->split_locs->next == NULL) {
32211     return;
32212   }
32213 
32214   s_prev = a->split_locs->data.ptrvalue;
32215   vnp_prev = a->split_locs;
32216   for (vnp = vnp_prev->next; vnp != NULL; vnp = vnp_next) {
32217     vnp_next = vnp->next;
32218     s = (SplitIntPtr) vnp->data.ptrvalue;
32219     if (s->start - s_prev->stop - 1 < min_length)  {
32220       if (s->stop > s_prev->stop) {
32221         s_prev->stop = s->stop;
32222       }
32223       s = MemFree (s);
32224       vnp->next = NULL;
32225       vnp = ValNodeFree (vnp);
32226       vnp_prev->next = vnp_next;
32227     } else {
32228       vnp_prev = vnp;
32229     }
32230   }
32231 }
32232 
32233 
RecheckSplits(AmbiguousEndPtr a,Int4 max_dist)32234 static void RecheckSplits (AmbiguousEndPtr a, Int4 max_dist)
32235 {
32236   ValNodePtr vnp, vnp_next;
32237   SplitIntPtr s;
32238 
32239   if (a == NULL || a->split_locs == NULL) {
32240     return;
32241   }
32242   /* reverse distance, so can start from right side */
32243   ValNodeReverse (&(a->split_locs));
32244   for (vnp = a->split_locs; vnp != NULL; vnp = vnp_next) {
32245     vnp_next = vnp->next;
32246     s = (SplitIntPtr) vnp->data.ptrvalue;
32247     if (s->start < a->bsp->length - a->trim3 && a->bsp->length - s->stop < max_dist) {
32248       a->trim3 = a->bsp->length - s->start;
32249       vnp->next = NULL;
32250       vnp = ValNodeFreeData (vnp);
32251       a->split_locs = vnp_next;
32252     } else {
32253       break;
32254     }
32255   }
32256   /* put back in left to right order */
32257   ValNodeReverse (&(a->split_locs));
32258 }
32259 
32260 
GetVectorTrimAndSplit(AmbiguousEndPtr a,Int4 min_length,Int4 max_dist)32261 static void GetVectorTrimAndSplit (AmbiguousEndPtr a, Int4 min_length, Int4 max_dist)
32262 {
32263   SeqFeatPtr       sfp;
32264   Int4             left, right, tmp, left_dist, right_dist, left_remaining, right_remaining;
32265   SeqAnnotPtr      sap;
32266 
32267   if (a == NULL || a->bsp == NULL || a->bsp->length - a->trim5 - a->trim3 < min_length) return;
32268 
32269   for (sap = a->bsp->annot; sap != NULL; sap = sap->next) {
32270     if (IsVecScreenAnnot(sap)) {
32271       sfp = sap->data;
32272       while (sfp != NULL) {
32273         left = SeqLocStart (sfp->location);
32274         right = SeqLocStop (sfp->location);
32275         if (left > right) {
32276           tmp = left;
32277           left = right;
32278           right = tmp;
32279         }
32280         left_remaining = left - a->trim5;
32281         right_remaining = a->bsp->length - a->trim3 - right;
32282         left_dist = left - a->trim5;
32283         right_dist = a->bsp->length - a->trim3 - right;
32284         if (right > a->trim5 && right_remaining > left_remaining) {
32285           if (left_dist < max_dist) {
32286             a->trim5 = right;
32287           } else {
32288             ValNodeAddPointer (&(a->split_locs), 0, SplitIntNew (left, right));
32289           }
32290         }
32291         if (left < a->trim3 && left_remaining > right_remaining) {
32292           if (right_dist < max_dist) {
32293             a->trim3 = a->bsp->length - left;
32294           } else {
32295             ValNodeAddPointer (&(a->split_locs), 0, SplitIntNew (left, right));
32296           }
32297         }
32298         if (left_remaining > max_dist && right_remaining > max_dist) {
32299           ValNodeAddPointer (&(a->split_locs), 0, SplitIntNew (left, right));
32300         }
32301         sfp = sfp->next;
32302       }
32303     }
32304   }
32305 
32306   /* some splits may be so close together that they should be combined */
32307   CombineSplitsForAmbiguousEnd (a, min_length);
32308 
32309   /* after removing right-most vector, some earlier splits might be close enough for simple trimming */
32310   RecheckSplits (a, max_dist);
32311 }
32312 
32313 
32314 typedef struct splitncount {
32315   Int4 pos;
32316   Int4 run_size;
32317   Int4 min_gap_size;
32318   SplitIntPtr last_split;
32319   ValNodePtr splits;
32320 } SplitNCountData, PNTR SplitNCountPtr;
32321 
32322 
SplitNProc(CharPtr sequence,Pointer userdata)32323 static void LIBCALLBACK SplitNProc (CharPtr sequence, Pointer userdata)
32324 {
32325   SplitNCountPtr tn;
32326   CharPtr cp;
32327 
32328   if (sequence == NULL || userdata == NULL) return;
32329   tn = (SplitNCountPtr) userdata;
32330 
32331   for (cp = sequence; *cp != 0; cp++)
32332   {
32333     if (*cp == 'N')
32334     {
32335       tn->run_size ++;
32336       if (tn->run_size >= tn->min_gap_size) {
32337         if (tn->last_split == NULL) {
32338           tn->last_split = SplitIntNew (tn->pos - tn->run_size, tn->pos);
32339           ValNodeAddPointer (&(tn->splits), 0, tn->last_split);
32340         } else {
32341           tn->last_split->stop = tn->pos;
32342         }
32343       }
32344     }
32345     else
32346     {
32347       tn->run_size = 0;
32348       tn->last_split = NULL;
32349     }
32350     /* a->pos starts at 0, after incrementing, a->pos is count of nt examined already */
32351     tn->pos++;
32352   }
32353 }
32354 
32355 
SplitOneForNs(AmbiguousEndPtr a,Int4 min_gap_size,Int4 min_length)32356 static void SplitOneForNs (AmbiguousEndPtr a, Int4 min_gap_size, Int4 min_length)
32357 {
32358   SplitNCountData tn;
32359 
32360   if (a == NULL || a->bsp == NULL || a->bsp->length < a->trim5 + a->trim3) {
32361     return;
32362   }
32363   MemSet (&tn, 0, sizeof (SplitNCountData));
32364   tn.min_gap_size = min_gap_size;
32365   SeqPortStreamInt (a->bsp, a->trim5, a->bsp->length - 1 - a->trim3, Seq_strand_plus, STREAM_EXPAND_GAPS, (Pointer) &tn, SplitNProc);
32366 
32367   if (tn.splits != NULL) {
32368     ValNodeLink (&(a->split_locs), tn.splits);
32369     /* some splits may be so close together that they should be combined */
32370     CombineSplitsForAmbiguousEnd (a, min_length);
32371   }
32372 }
32373 
32374 
SplitForNs(ValNodePtr list,Int4 min_gap_size,Int4 min_length)32375 static void SplitForNs (ValNodePtr list, Int4 min_gap_size, Int4 min_length)
32376 {
32377   ValNodePtr vnp;
32378 
32379   for (vnp = list; vnp != NULL; vnp = vnp->next) {
32380     SplitOneForNs (vnp->data.ptrvalue, min_gap_size, min_length);
32381   }
32382 }
32383 
32384 
32385 static CharPtr s_SplitMsgFmt = "Split %s before %d and after %d (%s)\n";
32386 
AddToLogSplitMessages(AmbiguousEndPtr a,CharPtr reason,ValNodeBlockPtr msg_block)32387 static void AddToLogSplitMessages (AmbiguousEndPtr a, CharPtr reason, ValNodeBlockPtr msg_block)
32388 {
32389   ValNodePtr vnp;
32390   SplitIntPtr s;
32391   CharPtr     msg;
32392   Int4        len;
32393 
32394   if (a == NULL || a->split_locs == NULL || msg_block == NULL) {
32395     return;
32396   }
32397   for (vnp = a->split_locs; vnp != NULL; vnp = vnp->next) {
32398     s = (SplitIntPtr) vnp->data.ptrvalue;
32399     len = StringLen (s_SplitMsgFmt) + StringLen (a->id) + StringLen (reason) + 30;
32400     msg = (CharPtr) MemNew (sizeof (Char) * len);
32401     sprintf (msg, s_SplitMsgFmt, a->id, s->start, s->stop, reason == NULL ? "Unknown" : reason);
32402     ValNodeAddPointerToEnd (msg_block, 0, msg);
32403   }
32404 }
32405 
32406 
LogSplit(AmbiguousEndPtr a,CharPtr reason,LogInfoPtr lip)32407 static void LogSplit (AmbiguousEndPtr a, CharPtr reason, LogInfoPtr lip)
32408 {
32409   ValNodePtr vnp;
32410   SplitIntPtr s;
32411 
32412   if (a == NULL || a->split_locs == NULL || lip == NULL || lip->fp == NULL) {
32413     return;
32414   }
32415   for (vnp = a->split_locs; vnp != NULL; vnp = vnp->next) {
32416     s = (SplitIntPtr) vnp->data.ptrvalue;
32417     fprintf (lip->fp, s_SplitMsgFmt, a->id, s->start, s->stop, reason == NULL ? "Unknown" : reason);
32418     lip->data_in_log = TRUE;
32419   }
32420 }
32421 
32422 
AnySplits(ValNodePtr list)32423 static Boolean AnySplits (ValNodePtr list)
32424 {
32425   Boolean any = FALSE;
32426   AmbiguousEndPtr a;
32427 
32428   while (list != NULL && !any) {
32429     if ((a = (AmbiguousEndPtr) list->data.ptrvalue) != NULL && a->split_locs != NULL) {
32430       any = TRUE;
32431     }
32432     list = list->next;
32433   }
32434   return any;
32435 }
32436 
32437 
LogSplitIdChanges(ValNodePtr list,LogInfoPtr lip)32438 static void LogSplitIdChanges (ValNodePtr list, LogInfoPtr lip)
32439 {
32440   AmbiguousEndPtr a;
32441   Boolean any = FALSE;
32442 
32443   while (list != NULL) {
32444     if ((a = (AmbiguousEndPtr) list->data.ptrvalue) != NULL && a->orig_id != NULL) {
32445       if (!any) {
32446         fprintf (lip->fp, "New sequences:\n");
32447         lip->data_in_log = TRUE;
32448         any = TRUE;
32449       }
32450       fprintf (lip->fp, "%s (originally part of %s)\n", a->id, a->orig_id);
32451     }
32452     list = list->next;
32453   }
32454 }
32455 
32456 
DescribeTrimAction(AmbiguousEndPtr a,Int4 min_length)32457 static CharPtr DescribeTrimAction (AmbiguousEndPtr a, Int4 min_length)
32458 {
32459   CharPtr msg = NULL;
32460   Int4    len;
32461   CharPtr end5 = " %d from 5' end";
32462   CharPtr end3 = " %d from 3' end";
32463 
32464   if (a == NULL || (a->trim5 == 0 && a->trim3 == 0) || a->bsp->length - a->trim5 - a->trim3 < min_length) {
32465     return NULL;
32466   }
32467 
32468   len = StringLen (a->id) + 3;
32469   if (a->trim5 > 0) {
32470     len += StringLen (end5) + 15;
32471   }
32472   if (a->trim3 > 0) {
32473     len += StringLen (end3) + 15;
32474   }
32475 
32476   msg = (CharPtr) MemNew (sizeof (Char) * len);
32477   sprintf (msg, "%s:", a->id);
32478   len = StringLen (msg);
32479   if (a->trim5 > 0) {
32480     sprintf (msg + len, end5, a->trim5);
32481     if (a->trim3 > 0) {
32482       StringCat (msg, ",");
32483     }
32484     len = StringLen (msg);
32485   }
32486   if (a->trim3 > 0) {
32487     sprintf (msg + len, end3, a->trim3);
32488   }
32489   return msg;
32490 }
32491 
32492 
ShouldDelete(AmbiguousEndPtr a,Int4 min_length)32493 static Boolean ShouldDelete (AmbiguousEndPtr a, Int4 min_length)
32494 {
32495   if (a != NULL && a->bsp->length - a->trim5 - a->trim3 < min_length) {
32496     return TRUE;
32497   } else {
32498     return FALSE;
32499   }
32500 }
32501 
32502 
CountTrim(ValNodePtr list,Int4 min_length)32503 static Int4 CountTrim (ValNodePtr list, Int4 min_length)
32504 {
32505   AmbiguousEndPtr a;
32506   Int4 count = 0;
32507 
32508   while (list != 0) {
32509     if ((a = (AmbiguousEndPtr) list->data.ptrvalue) != NULL
32510         && (a->trim5 > 0 || a->trim3 > 0)
32511         && !ShouldDelete (a, min_length)) {
32512       count++;
32513     }
32514     list = list->next;
32515   }
32516   return count;
32517 }
32518 
32519 
CountDelete(ValNodePtr list,Int4 min_length)32520 static Int4 CountDelete (ValNodePtr list, Int4 min_length)
32521 {
32522   AmbiguousEndPtr a;
32523   Int4 count = 0;
32524 
32525   while (list != 0) {
32526     if ((a = (AmbiguousEndPtr) list->data.ptrvalue) != NULL && ShouldDelete (a, min_length)) {
32527       count++;
32528     }
32529     list = list->next;
32530   }
32531   return count;
32532 }
32533 
32534 
CheckForWGSSource(WizardTrackerPtr wiz)32535 static Boolean CheckForWGSSource (WizardTrackerPtr wiz)
32536 {
32537   IDAndTitleEditPtr iatep;
32538   ValNodePtr summaries, vnp_s, vnp_q;
32539   Boolean    rval = TRUE;
32540   UniversalSrcPtr u;
32541   WizardQualPtr   q;
32542   CharPtr         warn_fmt = "Your file contains multiple %s values, which is unexpected for a WGS submission.\
32543 If you think this is from a typo in one of the FASTA definition lines you may continue. \
32544 You will be prompted to provide the correct information later in the dialogs. \
32545 If these sequences are from multiple %s, please quit using the WGS wizard now.";
32546   CharPtr         warn_msg;
32547 
32548   if (wiz == NULL || wiz->sequences == NULL) {
32549     return FALSE;
32550   }
32551   iatep = SeqEntryListToIDAndTitleEditEx (wiz->sequences, TRUE);
32552 
32553   SetWizardTrackerBaseSrcQuals (wiz, iatep);
32554   wiz->extra_src_quals = ValNodeFreeData (wiz->extra_src_quals);
32555   SetWizardTrackerExtraSrcQuals (wiz, iatep);
32556 
32557   summaries = FindUniversalSourceInfo (iatep, wiz);
32558   for (vnp_s = summaries, vnp_q = wiz->base_src_quals;
32559        vnp_s != NULL && vnp_q != NULL && rval;
32560        vnp_s = vnp_s->next, vnp_q = vnp_q->next) {
32561     u = (UniversalSrcPtr) vnp_s->data.ptrvalue;
32562     q = (WizardQualPtr) vnp_q->data.ptrvalue;
32563     if (u != NULL && u->val_list->next != NULL) {
32564       warn_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (warn_fmt) + 2 * StringLen (q->name)));
32565       sprintf (warn_msg, warn_fmt, q->name, q->name);
32566       if (ThreeOptionsDlg ("Multiple values", warn_msg,
32567                            "Continue", "Quit", NULL) == 2) {
32568         rval = FALSE;
32569       }
32570       warn_msg = MemFree (warn_msg);
32571     }
32572   }
32573   for (vnp_q = wiz->extra_src_quals;
32574        vnp_s != NULL && vnp_q != NULL && rval;
32575        vnp_q = vnp_q->next) {
32576     u = (UniversalSrcPtr) vnp_s->data.ptrvalue;
32577     q = (WizardQualPtr) vnp_q->data.ptrvalue;
32578     if (q->show) {
32579       if (u != NULL && u->val_list->next != NULL) {
32580         warn_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (warn_fmt) + 2 * StringLen (q->name)));
32581         sprintf (warn_msg, warn_fmt, q->name, q->name);
32582         if (ThreeOptionsDlg ("Multiple values", warn_msg,
32583                              "Continue", "Quit", NULL) == 2) {
32584           rval = FALSE;
32585         }
32586         warn_msg = MemFree (warn_msg);
32587       }
32588       vnp_s = vnp_s->next;
32589     }
32590   }
32591 
32592   summaries = UniversalSrcListFree (summaries);
32593   wiz->base_src_quals = ValNodeFreeData (wiz->base_src_quals);
32594   wiz->extra_src_quals = ValNodeFreeData (wiz->extra_src_quals);
32595 
32596   iatep = IDAndTitleEditFree (iatep);
32597   return rval;
32598 }
32599 
32600 
32601 typedef struct norgapfrm {
32602   FORM_MESSAGE_BLOCK
32603   GrouP n_or_gap;
32604   TexT other_exp;
32605   TexT gap_size;
32606   PrompT gap_prompt;
32607 } NOrGapFrmData, PNTR NOrGapFrmPtr;
32608 
ChangeNOrGap(GrouP g)32609 static void ChangeNOrGap (GrouP g)
32610 {
32611   NOrGapFrmPtr frm;
32612   Int2 val;
32613 
32614   frm = (NOrGapFrmPtr) GetObjectExtra (g);
32615   if (frm == NULL) {
32616     return;
32617   }
32618   val = GetValue (frm->n_or_gap);
32619   if (val == 1 || val == 2) {
32620     Enable (frm->gap_prompt);
32621     Enable (frm->gap_size);
32622     Disable (frm->other_exp);
32623   } else if (val == 3) {
32624     Disable (frm->gap_prompt);
32625     Disable (frm->gap_size);
32626     Enable (frm->other_exp);
32627   } else {
32628     Disable (frm->gap_prompt);
32629     Disable (frm->gap_size);
32630     Disable (frm->other_exp);
32631   }
32632 }
32633 
32634 
SplitAtNs(ValNodePtr list,WizardTrackerPtr wiz,Int4 min_length)32635 static Boolean SplitAtNs (ValNodePtr list, WizardTrackerPtr wiz, Int4 min_length)
32636 {
32637   ModalAcceptCancelData acd;
32638   WindoW                w;
32639   GrouP                 h, c;
32640   PrompT                intro;
32641   ButtoN                b;
32642   Boolean               rval = FALSE;
32643   NOrGapFrmPtr          frm;
32644   Int2                  val;
32645   CharPtr               tmp;
32646   Int4                  gap;
32647   CharPtr               split_msg_fmt = "split at sequencing gaps of %d Ns";
32648   CharPtr               no_split_fmt = "Ns = %s";
32649 
32650   acd.accepted = FALSE;
32651   acd.cancelled = FALSE;
32652   acd.third_option = FALSE;
32653 
32654   w = ModalWindow(-20, -13, -10, -10, NULL);
32655   h = HiddenGroup (w, -1, 0, NULL);
32656   SetGroupSpacing (h, 10, 10);
32657 
32658   frm = (NOrGapFrmPtr) MemNew (sizeof (NOrGapFrmData));
32659   SetObjectExtra (w, frm, StdCleanupFormProc);
32660 
32661   intro = StaticPrompt (h, "Some of your sequences contain runs of ten or more consecutive Ns.", 0, 0, systemFont, 'c');
32662   frm->n_or_gap = NormalGroup (h, 0, 3, "What do the Ns represent?", systemFont, ChangeNOrGap);
32663   SetObjectExtra (frm->n_or_gap, frm, NULL);
32664   SetGroupSpacing (frm->n_or_gap, 10, 10);
32665   RadioButton (frm->n_or_gap, "Sequencing Gaps");
32666   RadioButton (frm->n_or_gap, "Sequencing gaps and sequence ambiguities");
32667   RadioButton (frm->n_or_gap, "Other");
32668   StaticPrompt (frm->n_or_gap, "", 0, 0, systemFont, 'c');
32669   StaticPrompt (frm->n_or_gap, "", 0, 0, systemFont, 'c');
32670   frm->other_exp = DialogText (frm->n_or_gap, "", 10, NULL);
32671 
32672   frm->gap_prompt = StaticPrompt (h, "What is the shortest run of Ns that represents a sequence gap?", 0, 0, systemFont, 'c');
32673   frm->gap_size = DialogText (h, "", 10, NULL);
32674 
32675   c = HiddenGroup (h, 3, 0, NULL);
32676   SetGroupSpacing (c, 10, 10);
32677   b = PushButton (c, "Accept", ModalAcceptButton);
32678   SetObjectExtra (b, &acd, NULL);
32679   AlignObjects (ALIGN_CENTER, (HANDLE) intro,
32680                               (HANDLE) frm->n_or_gap,
32681                               (HANDLE) frm->other_exp,
32682                               (HANDLE) frm->gap_prompt,
32683                               (HANDLE) frm->gap_size,
32684                               (HANDLE) c,
32685                               NULL);
32686   ChangeNOrGap(frm->n_or_gap);
32687   Show(w);
32688   Select (w);
32689   while (!acd.accepted && !acd.cancelled)
32690   {
32691     ProcessExternalEvent ();
32692     Update ();
32693     if (acd.accepted) {
32694       val = GetValue (frm->n_or_gap);
32695       if (val < 1 || val > 3) {
32696         Message (MSG_ERROR, "Must select meaning for runs of Ns");
32697         acd.accepted = FALSE;
32698       } else if (val == 1 || val == 2) {
32699         if (TextHasNoText (frm->gap_size)) {
32700           Message (MSG_ERROR, "Must select smallest run of Ns to convert to gap");
32701           acd.accepted = FALSE;
32702         } else {
32703           tmp = SaveStringFromText (frm->gap_size);
32704           if (!StringIsAllDigits (tmp)) {
32705             Message (MSG_ERROR, "Must specify a number!");
32706             acd.accepted = FALSE;
32707           }
32708           tmp = MemFree (tmp);
32709         }
32710       } else if (TextHasNoText (frm->other_exp)) {
32711         Message (MSG_ERROR, "Must explain runs of Ns");
32712         acd.accepted = FALSE;
32713       }
32714     }
32715   }
32716   ProcessAnEvent ();
32717   Remove (w);
32718   if (acd.accepted)
32719   {
32720     val = GetValue (frm->n_or_gap);
32721     if (val == 1 || val == 2) {
32722       tmp = SaveStringFromText (frm->gap_size);
32723       gap = atoi (tmp);
32724       tmp = MemFree (tmp);
32725       SplitForNs (list, gap, min_length);
32726       wiz->wgs_ns_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (split_msg_fmt) + 15));
32727       sprintf (wiz->wgs_ns_msg, split_msg_fmt, gap);
32728     } else {
32729       tmp = SaveStringFromText (frm->other_exp);
32730       wiz->wgs_ns_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (no_split_fmt) + StringLen(tmp)));
32731       sprintf (wiz->wgs_ns_msg, no_split_fmt, tmp);
32732       tmp = MemFree (tmp);
32733     }
32734     rval = TRUE;
32735   }
32736   return rval;
32737 }
32738 
32739 
WGSVectorScreen(WizardTrackerPtr wiz,ValNodeBlockPtr block,Int4 min_length,Int4 max_dist)32740 static void WGSVectorScreen (WizardTrackerPtr wiz, ValNodeBlockPtr block, Int4 min_length, Int4 max_dist)
32741 {
32742   ValNodeBlock vector_adjusted_list;
32743   ValNodeBlock vector_split_msgs;
32744   Int4        num_vector_trim = 0;
32745   Int4        num_vector_delete = 0;
32746   ValNodePtr  vnp;
32747   AmbiguousEndPtr a, a_vec;
32748   Boolean     any_internal_vector = FALSE;
32749   CharPtr     action;
32750   CharPtr     trim_action = "trim ends of sequence with vector";
32751   CharPtr     delete_action = "delete sequences that are mostly vector";
32752   ValNodePtr  internal_vector = NULL;
32753   CharPtr     reasons[] = {"Low Quality", "Vector Contamination", "Low Quality and Vector Contamination"};
32754   MsgAnswer   ans;
32755 
32756   VecScreenWizard (wiz->sequences);
32757 
32758   InitValNodeBlock (&vector_adjusted_list, NULL);
32759   InitValNodeBlock (&vector_split_msgs, NULL);
32760   /* now look for vector trimming in addition to quality */
32761   for (vnp = block->head; vnp != NULL; vnp = vnp->next) {
32762     a = (AmbiguousEndPtr) vnp->data.ptrvalue;
32763     a_vec = AmbiguousEndCopy (a);
32764     GetVectorTrimAndSplit (a_vec, min_length, max_dist);
32765     if (a_vec->split_locs != NULL) {
32766       any_internal_vector = TRUE;
32767     }
32768     if (a_vec->trim5 > a->trim5 || a_vec->trim3 > a->trim3) {
32769       if (ShouldDelete(a_vec, min_length)) {
32770         num_vector_delete++;
32771       } else {
32772         num_vector_trim++;
32773       }
32774     }
32775     ValNodeAddPointerToEnd (&vector_adjusted_list, 0, a_vec);
32776   }
32777 
32778   if (any_internal_vector || num_vector_trim > 0 || num_vector_delete > 0) {
32779     action = NULL;
32780     if (any_internal_vector) {
32781       action = StringSave ("split sequences at internal vector");
32782       for (vnp = vector_adjusted_list.head; vnp != NULL; vnp = vnp->next) {
32783         AddToLogSplitMessages (vnp->data.ptrvalue, "Vector match", &vector_split_msgs);
32784       }
32785     }
32786     if (num_vector_trim > 0) {
32787       if (StringHasNoText (action)) {
32788         action = StringSave (trim_action);
32789       } else if (num_vector_delete == 0) {
32790         SetStringValue (&action, "and", ExistingTextOption_append_space);
32791         SetStringValue (&action, trim_action, ExistingTextOption_append_space);
32792       } else {
32793         SetStringValue (&action, "trim ends of sequence with vector", ExistingTextOption_append_comma);
32794       }
32795     }
32796     if (num_vector_delete > 0) {
32797       if (StringHasNoText (action)) {
32798         action = StringSave (delete_action);
32799       } else if (internal_vector != NULL && num_vector_trim > 0) {
32800         SetStringValue (&action, "and", ExistingTextOption_append_comma);
32801         SetStringValue (&action, delete_action, ExistingTextOption_append_space);
32802       } else {
32803         SetStringValue (&action, "and", ExistingTextOption_append_space);
32804         SetStringValue (&action, trim_action, ExistingTextOption_append_space);
32805       }
32806     }
32807     if (wiz->has_agp) {
32808       ans = Message (MSG_YN, "Vector contamination was detected.  Do you want to %s to adjust your FASTA file, before regenerating your AGP file?  Failure to do so could cause a delay in processing.", action);
32809     } else {
32810       ans = Message (MSG_YN, "Vector contamination was detected.  Do you want to %s?  Failure to do so could cause a delay in processing.", action);
32811     }
32812     if (ans == ANS_YES) {
32813       block->head = AmbiguousEndListFree (block->head);
32814       block->head = vector_adjusted_list.head;
32815       block->tail = vector_adjusted_list.tail;
32816       vector_adjusted_list.head = NULL;
32817       SplitAtSplitLocations (block->head, wiz->sequences, min_length);
32818       AddSplitBioseqs (wiz->sequences, block->head);
32819       ClearSplitLocs (block->head);
32820     } else {
32821       vector_split_msgs.head = ValNodeFreeData (vector_split_msgs.head);
32822     }
32823   }
32824   vector_adjusted_list.head = AmbiguousEndListFree (vector_adjusted_list.head);
32825   WizardRemoveVecScreenAnnots (wiz->sequences);
32826 }
32827 
32828 
32829 /* returns TRUE if anything is changed */
WGSSequenceAdjustment(WizardTrackerPtr wiz)32830 static Boolean WGSSequenceAdjustment (WizardTrackerPtr wiz)
32831 {
32832   ValNodeBlock block;
32833   ValNodePtr   vnp;
32834   CharPtr      msg, action;
32835   AmbiguousEndPtr a;
32836   SeqEntryPtr orig_scope;
32837   LogInfoPtr  lip;
32838   Int4        min_length = 200;
32839   Int4        max_dist = 20;
32840   Int4        num_trim, num_delete;
32841   CharPtr     quit_problems = NULL;
32842   Boolean     rval = FALSE;
32843   Int4        keep_len;
32844   Boolean     has_n_runs = FALSE;
32845   Boolean     was_split = FALSE;
32846 
32847   if (wiz->sequences == NULL) {
32848     return FALSE;
32849   }
32850   wiz->wgs_ns_msg = MemFree (wiz->wgs_ns_msg);
32851 
32852   if (Message (MSG_YN, "Do you have an AGP file that accompanies this submission?") == ANS_YES) {
32853     wiz->has_agp = TRUE;
32854   } else {
32855     wiz->has_agp = FALSE;
32856   }
32857 
32858   InitValNodeBlock (&block, NULL);
32859 
32860   GetAmbiguousEndBlankList (wiz->sequences, &block);
32861   for (vnp = block.head; vnp != NULL; vnp = vnp->next) {
32862     ShrinkForTerminalNs (vnp->data.ptrvalue);
32863   }
32864 
32865   /* WGSVectorScreen () */
32866 
32867   for (vnp = block.head; vnp != NULL; vnp = vnp->next) {
32868     a = (AmbiguousEndPtr) vnp->data.ptrvalue;
32869     ShrinkForTerminalNs (a);
32870   }
32871   has_n_runs = FALSE;
32872   /* check for > 10% Ns */
32873   for (vnp = block.head; vnp != NULL; vnp = vnp->next) {
32874     a = (AmbiguousEndPtr) vnp->data.ptrvalue;
32875     keep_len = a->bsp->length - a->trim5 - a->trim3;
32876     if (keep_len >= min_length) {
32877       if ((100 * a->untrimmed_ns) / keep_len >= 10) {
32878         /* greater than 10% Ns */
32879         a->trim5 = a->bsp->length - 1;
32880       } else if (a->longest_n_run > 9) {
32881         has_n_runs = TRUE;
32882       }
32883     }
32884   }
32885 
32886   if (has_n_runs) {
32887     SplitAtNs (block.head, wiz, min_length);
32888     SplitAtSplitLocations (block.head, wiz->sequences, min_length);
32889     AddSplitBioseqs (wiz->sequences, block.head);
32890   }
32891 
32892   lip = OpenLog ("Sequence Adjustments");
32893   if (AnySplits(block.head)) {
32894     fprintf (lip->fp, "Sequences %ssplit:\n", wiz->has_agp ? "to be " : "");
32895     lip->data_in_log = TRUE;
32896     for (vnp = block.head; vnp != NULL; vnp = vnp->next) {
32897       LogSplit ((AmbiguousEndPtr) vnp->data.ptrvalue, "Split at sequence gap", lip);
32898     }
32899     was_split = TRUE;
32900     LogSplitIdChanges (block.head, lip);
32901     rval = TRUE;
32902   }
32903 
32904   num_trim = CountTrim (block.head, min_length);
32905   num_delete = CountDelete (block.head, min_length);
32906   if (num_delete > 0 || num_trim > 0) {
32907     orig_scope = SeqEntrySetScope (wiz->sequences);
32908     /* sequences to delete */
32909     if (num_delete > 0) {
32910       fprintf (lip->fp, "Sequences %sremoved:\n", wiz->has_agp ? "to be " : "");
32911       lip->data_in_log = TRUE;
32912       for (vnp = block.head; vnp != NULL; vnp = vnp->next) {
32913         a = (AmbiguousEndPtr) vnp->data.ptrvalue;
32914         if (ShouldDelete(a, min_length)) {
32915           if (a->bsp->length < min_length || (a->trim5 == 0 && a->trim3 == 0)) {
32916             fprintf (lip->fp, "%s (too short)\n", a->id, "Low Quality");
32917           } else {
32918             fprintf (lip->fp, "%s (%s)\n", a->id, "Low Quality");
32919           }
32920           a->bsp->idx.deleteme = 1;
32921         }
32922       }
32923     }
32924     /* sequences to trim */
32925     if (num_trim > 0) {
32926       fprintf (lip->fp, "Sequences %strimmed:\n", wiz->has_agp ? "to be " : "");
32927       lip->data_in_log = TRUE;
32928       for (vnp = block.head; vnp != NULL; vnp = vnp->next) {
32929         a = (AmbiguousEndPtr) vnp->data.ptrvalue;
32930         msg = DescribeTrimAction (a, min_length);
32931         if (msg != NULL) {
32932           fprintf (lip->fp, "%s (%s)\n", msg, "Low Quality");
32933           TrimAmbiguousEnds (a, wiz->sequences, min_length);
32934         }
32935       }
32936     }
32937     /* actually remove the sequences */
32938     RemoveSequencesByIdx (&(wiz->sequences));
32939     SeqEntrySetScope(orig_scope);
32940     rval = TRUE;
32941   }
32942   CloseLog (lip);
32943   lip = FreeLog (lip);
32944   if (wiz->has_agp && (was_split || num_delete > 0 || num_trim > 0)) {
32945     if (was_split && num_delete > 0 && num_trim > 0) {
32946       action = "split, trimmed, or deleted";
32947     } else if (num_delete > 0 && num_trim > 0) {
32948       action = "trimmed or deleted";
32949     } else if (was_split && num_delete > 0) {
32950       action = "split or deleted";
32951     } else if (was_split && num_trim > 0) {
32952       action = "split or trimmed";
32953     } else if (was_split) {
32954       action = "split";
32955     } else if (num_delete > 0) {
32956       action = "deleted";
32957     } else {
32958       action = "trimmed";
32959     }
32960     Message (MSG_ERROR, "The sequences listed need to be %s.  Please perform these actions and import a new sequence file.  Please don't forget to regenerate your AGP file.",
32961              action);
32962   }
32963 
32964   block.head = AmbiguousEndListFree (block.head);
32965   return rval;
32966 }
32967 
32968 
32969 typedef struct wizardfastaform {
32970   WIZARD_BLOCK
32971 
32972   DoC    fasta_doc;
32973   ButtoN fasta_import_btn;
32974   ButtoN fasta_clear_btn;
32975   DialoG tbs;
32976   DialoG sequencing_method;
32977   GrouP  pages[2];
32978   GrouP  fasta_vs_aln;
32979   ButtoN aln_btn;
32980   ButtoN vecscreen_btn;
32981   PrompT current_count;
32982 
32983   ParData parFmt;
32984   ColData colFmt;
32985   Int4    currentPage;
32986 } WizardFastaFormData, PNTR WizardFastaFormPtr;
32987 
32988 
CleanupWizardFastaForm(GraphiC g,Pointer data)32989 static void CleanupWizardFastaForm (GraphiC g, Pointer data)
32990 {
32991   WizardFastaFormPtr frm;
32992 
32993   if (data != NULL)
32994   {
32995     frm = (WizardFastaFormPtr) data;
32996     frm->wiz = WizardTrackerFree(frm->wiz);
32997   }
32998   StdCleanupFormProc (g, data);
32999 }
33000 
33001 
33002 static CharPtr s_UnculturedSamplesFastaExample[] = {
33003 "\
33004 FASTA Format Help\n\
33005 -----------------\n\
33006 -Sequences must be in a plain text file (.txt)\n\
33007 \n\
33008 -Each sequence must have a FASTA header line that begins with \">\" followed by a SeqID see\n\
33009 the example below).\n\
33010 \n\
33011 -The SeqIDs must be unique and may not contain spaces.\n\
33012 \n\
33013 ",
33014 "\
33015 -You may use the clone IDs as the seqIDs\n\
33016 \n\
33017 -The source information (organism names, clone names, etc.) can be included after the \n\
33018 SeqIDs. Including this information is optional, however it is recommended that you use this\n\
33019 format. If you do not include this information in your FASTA file, you will need to provide\n\
33020 it as you progress through the following steps of the  wizard.\n\
33021 \n\
33022 Example of the preferred FASTA file format:\n\
33023 -------------------------------------------\n\
33024 >SeqID1 [organism=uncultured Bacillus sp.][clone=ex1][isolation_source=soil][country=USA]\n\
33025 ",
33026 "\
33027 accggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33028 taccggatggcaccggatggcaccggatggcaccggatggcaccggatgg\n\
33029 ggaccggatggcaccggatggcaccggatggcaccggatggcaccggatg\n\
33030 accggatggcaccggatggcaccggatggc\n\
33031 >SeqID2 [organism=uncultured Bacillus sp.][clone=ex2][isolation_source=leaf][host=Cocos sp.]\n\
33032 accggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33033 aaccggatggcaccggatggcaccggatggcaccggatggcaccggatgt\n\
33034 ttaccggatggcaccggatggcaccggatggcaccggatggcaccggatg\n\
33035 accggatggcaccggatggcaccggatggc\n\
33036 \n\
33037 ", NULL};
33038 
33039 
33040 static CharPtr s_VirusFastaExample[] = {
33041 "\
33042 FASTA Format Help\n\
33043 -----------------\n\
33044 -Sequences must be in a plain text file (.txt)\n\
33045 \n\
33046 -Each sequence must have a FASTA header line that begins with \">\" followed by a SeqID see\n\
33047 the example below).\n\
33048 \n\
33049 -The SeqIDs must be unique and may not contain spaces.\n\
33050 \n\
33051 ",
33052 "\
33053 -You may use the strain or isolate IDs as the seqIDs\n\
33054 \n\
33055 -The source information (organism names, clone names, etc.) can be included after the \n\
33056 SeqIDs. Including this information is optional, however it is recommended that you use this\n\
33057 format. If you do not include this information in your FASTA file, you will need to provide\n\
33058 it as you progress through the following steps of the  wizard.\n\
33059 \n\
33060 Example of the preferred FASTA file format:\n\
33061 -------------------------------------------\n\
33062 >SeqID1 [organism=Tomato leaf curl virus][isolate=ex1][host=tomato][country=USA][collection_date=05-Aug-2005][genotype=EX1]\n\
33063 ",
33064 "\
33065 accggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33066 >SeqID2 [organism=Tomato leaf curl virus][isolate=ex2][host=tomato][country=Mexico][collection_date=10-Aug-2005][genotype=EX1]\n\
33067 accggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33068 ", NULL};
33069 
33070 
33071 static CharPtr s_CulturedSamplesFastaExample[] = {
33072 "\
33073 FASTA Format Help\n\
33074 -----------------\n\
33075 -Sequences must be in a plain text file (.txt)\n\
33076 \n\
33077 -Each sequence must have a FASTA header line that begins with \">\" followed by a SeqID see\n\
33078 the example below).\n\
33079 \n\
33080 -The SeqIDs must be unique and may not contain spaces.\n\
33081 \n\
33082 -You may use the strain IDs as the seqIDs.\n\
33083 \n\
33084 ",
33085 "\
33086 -The source information (organism names, strain names, etc.) can be included after the \n\
33087 SeqIDs. Including this information is optional, however it is recommended that you use this\n\
33088 format. If you do not include this information in your FASTA file, you will need to provide\n\
33089 it as you progress through the following steps of the wizard.\n\
33090 \n\
33091 ",
33092 "\
33093 Example of the preferred FASTA file format\n\
33094 In this example ex1 and ex2 are the seqIDs and strain names.\n\
33095 ------------------------------------------------------------\n\
33096 >ex1 [organism=Listeria monocytogenes][strain=ex1][isolation-source=cheese][collection_date=05-Aug-2005]\n\
33097 accggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33098 >ex2 [organism=Bacillus cereus][strain=ex2][host=rice][collection_date=10-Aug-2005]\n\
33099 accggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33100 ", NULL};
33101 
33102 
33103 static CharPtr s_TSAFastaExample[] = {
33104 "\
33105 FASTA Format Help\n\
33106 -----------------\n\
33107 -Sequences must be in a plain text file (.txt)\n\
33108 \n\
33109 -Each sequence must have a FASTA header line that begins with \">\" followed by a SeqID see\n\
33110 the example below).\n\
33111 \n\
33112 -The SeqIDs must be unique and may not contain spaces.\n\
33113 \n\
33114 -You may use the strain IDs as the seqIDs.\n\
33115 \n\
33116 ",
33117 "\
33118 -The source information (organism names, strain names, etc.) can be included after the \n\
33119 SeqIDs. Including this information is optional, however it is recommended that you use this\n\
33120 format. If you do not include this information in your FASTA file, you will need to provide\n\
33121 it as you progress through the following steps of the wizard.\n\
33122 \n\
33123 ",
33124 "\
33125 Example of the preferred FASTA file format\n\
33126 ------------------------------------------------------------\n\
33127 >lcl|contig30162\n\
33128 AGCCATTTTGGCTCAAGCGAGCCAGGCAGACAGCGCCGCCCGCAACCCTCGCGGCGGCCAGTCCCACTCC\n\
33129 CCTTCTCTCGGAGACCGTCGGCCCTTGGACAGACCGGACAGCCATGGCCGTCCCCGCATCCGTGGTCGCG\n\
33130 GCCGGCATTCCGGCCGGCACCCCGTCCACCGTGACGCTGCCGGAGGATGCCTGGGACATGCTCGGCCTGG\n\
33131 GCGTCTCTGACGCGATGAGCGAGAAGGCGCTGCAGATCAAGAACGGACAGGTCGGCCTGCTCACTGCTGC\n\
33132 GGACTACTTCGCGTCACGGCAGCAGTACGAGTTGGAGCAGCGGGAGAGCTACCGCCAGCAGTGGCAGTAC\n\
33133 GAGGCCGAGCAGCGCCTAGCACGCCTCGAGGCCAAGAAGAGCCCCCTGGAGAAGGCCGGCGAGGGCGGCA\n\
33134 \n\
33135 ",
33136 "\
33137 >lcl|contig32575\n\
33138 ACGAGACGCCGACGTAGCCGGTGGGAGCCCCCTGGTCGACCATCTCGGGCGTGAAGATCACGGGGTAGGC\n\
33139 GTGGTAGTCGATATGGGGGTTCAGAAGCCTCAGGTGGAGGTTGGGGGCGGCGCAGGCGTTGACGGCAAGG\n\
33140 AGGACGCACTTGACCATACCGTTGATGCCTGCGCAGATCTCCGTGTGACTCAGGTTGGACTTGTTACTCG\n\
33141 TCTTCACCAGGGGCTTCGTGCGGACCGTTCCTTGAATGGTCATCATGGTAGCGCGCAGCGCTCCCACCTC\n\
33142 GATAGGGTCGCCCAGCGCTGTGCCCGTGCCGTGCAGCTCCTGGATCTGAATGTCCAGCGGATGAATGCCG\n\
33143 GATTCTCGCATCGACATCCTGATACACTCCTGCTGTGAGGGCCCGTGGGGAGCTGTCAGGCTGGCGCTGC\n\
33144 \n\
33145 ", NULL};
33146 
33147 static CharPtr s_MicrosatelliteFastaExample[] = {
33148 "\
33149 FASTA Format Help\n\
33150 -----------------\n\
33151 -Sequences must be in a plain text file (.txt)\n\
33152 \n\
33153 -Each sequence must have a FASTA header line that begins with \">\" followed by a SeqID see\n\
33154 the example below).\n\
33155 \n\
33156 -The SeqIDs must be unique and may not contain spaces.\n\
33157 \n\
33158 ",
33159 "\
33160 -You may use the microsatellite names as the seqIDs\n\
33161 \n\
33162 -The source information (organism names, clone names, etc.) can be included after the \n\
33163 SeqIDs. Including this information is optional, however it is recommended that you use this\n\
33164 format. If you do not include this information in your FASTA file, you will need to provide\n\
33165 it as you progress through the following steps of the  wizard.\n\
33166 \n\
33167 Example of the preferred FASTA file format:\n\
33168 -------------------------------------------\n\
33169 >Ca-123 [organism=Coffea arabica][isolation_source=leaf][country=Colombia]\n\
33170 ",
33171 "\
33172 accggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33173 taccggatggcaccggatggcaccggatggcaccggatggcaccggatgg\n\
33174 ggaccggatggcaccggatggcaccggatggcaccggatggcaccggatg\n\
33175 accggatggcaccggatggcaccggatggc\n\
33176 >Ca-234 [organism=Coffea arabica][isolation_source=leaf][country=USA: Hawaii]\n\
33177 accggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33178 aaccggatggcaccggatggcaccggatggcaccggatggcaccggatgt\n\
33179 ttaccggatggcaccggatggcaccggatggcaccggatggcaccggatg\n\
33180 accggatggcaccggatggcaccggatggc\n\
33181 ", NULL};
33182 
33183 
33184 static CharPtr s_DLoopFastaExample[] = {
33185 "\
33186 FASTA Format Help\n\
33187 -----------------\n\
33188 -Sequences must be in a plain text file (.txt)\n\
33189 \n\
33190 -Each sequence must have a FASTA header line that begins with \">\" followed by\n\
33191 a SeqID see the example below).\n\
33192 \n\
33193 -The SeqIDs must be unique and may not contain spaces.\n\
33194 ",
33195 "\
33196 \n\
33197 -You may use the isolate codes as the seqIDs\n\
33198 \n\
33199 -The source information (organism names, clone names, etc.) can be included\n\
33200 after the SeqIDs. Including this information is optional, however it is \n\
33201 recommended that you use this format. If you do not include this information \n\
33202 in your FASTA file, you will need to provide it as you progress through the \n\
33203 following steps of the  wizard.\n\
33204 ",
33205 "\
33206 \n\
33207 Example of the preferred FASTA file format:\n\
33208 -------------------------------------------\n\
33209 >Ca-123 [organism=Coffea arabica][country=Colombia]\n\
33210 accggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33211 taccggatggcaccggatggcaccggatggcaccggatggcaccggatgg\n\
33212 ggaccggatggcaccggatggcaccggatggcaccggatggcaccggatg\n\
33213 accggatggcaccggatggcaccggatggc\n\
33214 >Ca-234 [organism=Coffea arabica][isolation_source=leaf][country=USA: Hawaii]\n\
33215 accggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33216 ",
33217 "\
33218 aaccggatggcaccggatggcaccggatggcaccggatggcaccggatgt\n\
33219 ttaccggatggcaccggatggcaccggatggcaccggatggcaccggatg\n\
33220 accggatggcaccggatggcaccggatggc\n\
33221 \n\
33222 ", NULL};
33223 
33224 
33225 static CharPtr s_IGSFastaExample[] = {
33226 "\
33227 FASTA Format Help\n\
33228 -----------------\n\
33229 -Sequences must be in a plain text file (.txt)\n\
33230 \n\
33231 -Each sequence must have a FASTA header line that begins with \">\" followed by a SeqID see\n\
33232 the example below).\n\
33233 \n\
33234 -The SeqIDs must be unique and may not contain spaces.\n\
33235 \n\
33236 ",
33237 "\
33238 -The source information (organism names, strain names, etc.) can be included after the \n\
33239 SeqIDs. Including this information is optional, however it is recommended that you use this\n\
33240 format. If you do not include this information in your FASTA file, you will need to provide\n\
33241 it as you progress through the following steps of the  wizard.\n\
33242 \n\
33243 Example of the preferred FASTA file format:\n\
33244 -------------------------------------------\n\
33245 >EX-A1 [organism=Morchella esculenta][strain=EX-A1][country=Germany]\n\
33246 accggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33247 taccggatggcaccggatggcaccggatggcaccggatggcaccggatgg\n\
33248 ",
33249 "\
33250 ggaccggatggcaccggatggcaccggatggcaccggatggcaccggatg\n\
33251 accggatggcaccggatggcaccggatggc\n\
33252 >EX-A2 [organism=Morchella esculenta][strain=EX-A2][country=Germany]\n\
33253 accggatggcaccggatggcaccggatggcaccggatggcaccggatggc\n\
33254 aaccggatggcaccggatggcaccggatggcaccggatggcaccggatgt\n\
33255 ttaccggatggcaccggatggcaccggatggcaccggatggcaccggatg\n\
33256 accggatggcaccggatggcaccggatggc\n\
33257 \n\
33258 ", NULL };
33259 
33260 static CharPtr s_VectorURL = "http://www.ncbi.nlm.nih.gov/Sequin/sequin.hlp.html#VectorScreen";
33261 static CharPtr s_WGSURL = "http://www.ncbi.nlm.nih.gov/genbank/wgs/";
33262 
33263 /* note - welcome text array follows same order as wizard text */
33264 static CharPtr s_WizardIntroText[] = {
33265   /* eWizardType_UnculturedSamples */
33266 "\
33267 Welcome to the Sequin Bulk DNA Sequence Submission Wizard!\n\
33268 \n\
33269 Use this tool if your sequences are from:\n\
33270 -uncultured samples\n\
33271 -the same gene region (for example: all 16S rRNA or all nifH)\n\
33272 \n\
33273 Requirements:\n\
33274 -FASTA formatted nucleotide sequence text file or alignment file\n\
33275 -Unique clone names\n\
33276 -Isolation source (for example, freshwater lake at 100m depth)\n\
33277  or hostname (for example, Cocos nucifera) \n\
33278 \n\
33279 Vector Contamination:\n\
33280 Vector contamination should be removed before submitting your sequences to GenBank.\n\
33281 Click the Vector Trim Tool button below if you have not yet screened your sequences for vector.\n\
33282 Please see: \n\
33283 ",
33284   /* eWizardType_Viruses */
33285 "\
33286 Welcome to the Virus Sequence Submission Wizard!\n\
33287 Use this tool if you are submitting:\n\
33288 -virus sequences\n\
33289 -viroid sequences\n\
33290 \n\
33291 Requirements\n\
33292 -FASTA formatted nucleotide sequence text file or alignment file\n\
33293 -Unique isolate/strain names\n\
33294 -Country, host, collection-date, segment, genotype,\n\
33295 and/or serotype may be required for certain viruses \n\
33296 and is requested for all virus submissions\n\
33297 \n\
33298 Feature Annotation:\n\
33299 Please use the assistance provided in the wizard to\n\
33300 annotate the features your submission or annotate your\n\
33301 submissions in the record viewer.\n\
33302 If you do not provide feature annotation, assigning of \n\
33303 Accession numbers will be delayed.\n\
33304 \n\
33305 Vector Contamination:\n\
33306 Vector contamination should be removed before submitting your sequences to GenBank.\n\
33307 Click the Vector Trim Tool button below if you have not yet screened your sequences for vector.\n\
33308 Please see: \n\
33309 ",
33310   /* eWizardType_CulturedSamples */
33311 "\
33312 Welcome to the Cultured rRNA-ITS-IGS Submission Wizard!\n\
33313 \n\
33314 Use this tool for rRNA, ITS, or IGS sequences from:\n\
33315 - Cultured, pure strains of Bacteria, Archaea, or Fungi\n\
33316 - Vouchered Fungi\n\
33317 - Plant, animal or other eukaryotic sequences\n\
33318 \n\
33319 This tool is NOT for uncultured samples. Use the uncultured sample wizard if you are submitting sequences from an uncultured source.\n\
33320 \n\
33321 Requirements:\n\
33322    - FASTA formatted nucleotide sequence text file or alignment file\n\
33323    - Organism names\n\
33324    - Strain names for bacteria, and archaea\n\
33325    - Strain or specimen-vouchers for fungi\n\
33326    - Specimen vouchers or isolate codes for plants and animals\n\
33327 \n\
33328 Feature Annotation:\n\
33329 Please use the wizard to annotate features in your sequences or annotate your submissions in the record viewer.\n\
33330 If you do not provide feature annotation, assigning of Accession numbers will be delayed.\n\
33331 \n\
33332 Vector Contamination:\n\
33333 Vector contamination should be removed before submitting your sequences to GenBank.\n\
33334 Click the Vector Trim Tool button below if you have not yet screened your sequences for vector.\n\
33335 Please see: \n\
33336 ",
33337   /* eWizardType_IGS */
33338 "\
33339 Welcome to the Intergenic Spacer Submission Wizard!\n\
33340 \n\
33341 Use this tool for submitting intergenic spacer sequences.\n\
33342 Do not use this tool for submitting complete genomes.\n\
33343 \n\
33344 Do not use this wizard if you are submitting rRNA-IGS sequences.\n\
33345 If you are submitting rRNA-IGS sequences go back and select the rRNA/ITS/IGS wizard.\n\
33346 \n\
33347 Requirements:\n\
33348 - FASTA formatted nucleotide sequence text file or alignment file\n\
33349 - Organism names\n\
33350 - Unique Source information\n\
33351 \n\
33352 Vector Contamination:\n\
33353 Vector contamination should be removed before submitting your sequences to GenBank.\n\
33354 Click the Vector Trim Tool button below if you have not yet screened your sequences for vector.\n\
33355 Please see: \n\
33356 ",
33357   /* eWizardType_Microsatellite */
33358 "\
33359 Welcome to the Microsatellite Wizard!\n\
33360 \n\
33361 Use this tool for submitting Microsatellite sequences.\n\
33362 \n\
33363 Requirements:\n\
33364 - FASTA formatted nucleotide sequence text file\n\
33365 - Organism names\n\
33366 - Unique microsatellite names or clone names\n\
33367 \n\
33368 Vector Contamination:\n\
33369 Vector contamination should be removed before submitting your sequences to GenBank.\n\
33370 Click the Vector Trim Tool button below if you have not yet screened your sequences for vector.\n\
33371 Please see: \n\
33372 ",
33373   /* eWizardType_DLoop */
33374 "\
33375 Welcome to the D-loop & Control Region Wizard!\n\
33376 \n\
33377 Use this tool for submitting D-loop or Control Region sequences.\n\
33378 \n\
33379 Requirements:\n\
33380 - FASTA formatted nucleotide sequence text file\n\
33381 - Organism names\n\
33382 - Unique source information (such as isolate, haplotype, or specimen- voucher)\n\
33383 \n\
33384 Vector Contamination:\n\
33385 Vector contamination should be removed before submitting your sequences to GenBank.\n\
33386 Click the Vector Trim Tool button below if you have not yet screened your sequences for vector.\n\
33387 Please see: \n\
33388 ",
33389 /* WGS */
33390 "\
33391 Welcome to the WGS wizard!\n\
33392 \n\
33393 Use this tool for submitting Whole Genome Shotgun Submissions to NCBI. \n\
33394 This tool is for microbial genomes without annotation. Your file should include sequences from one organism only.\n\
33395 \n\
33396 Prior to preparing your WGS submission, please make sure your sequences and file conform to the following standards:\n\
33397 -WGS contigs should not have any Ns representing gaps. If there are gaps in your sequence, you will need to split the sequences at the gaps. \n\
33398 -do not include terminal N's\n\
33399 -do not include any sequences shorter than 200 nt \n\
33400 -do not include sequences containing more than 10% N's or large regions of low quality sequence\n\
33401 -file should not contain more than 10,000 sequences\n\
33402 \n\
33403 For more information about WGS submissions, please see: \n\
33404 ",
33405 /* default */
33406 "\
33407 Vector Contamination:\n\
33408 Vector contamination should be removed before submitting your sequences to GenBank.\n\
33409 Click the Vector Trim Tool button below if you have not yet screened your sequences for vector.\n\
33410 Please see: \n\
33411 "
33412 };
33413 
33414 
33415 static CharPtr s_AlignmentInstructionsText = "\
33416 Click �Import Nucleotide Alignment� to load your nucleotide alignment file.\n\
33417 Click �Custom Alignment Settings� if there is trouble reading your alignment file.\n\
33418 ";
33419 
SetFastaText(WizardFastaFormPtr frm)33420 static void SetFastaText (WizardFastaFormPtr frm)
33421 {
33422   Char        txt[200];
33423   CharPtr     intro = NULL;
33424   CharPtr     url = NULL;
33425   IDAndTitleEditPtr iatep;
33426   Int4        i;
33427   CharPtr     line;
33428   CharPtr     line_fmt = "%s: %d nt\n";
33429 
33430   if (frm == NULL) {
33431     return;
33432   }
33433 
33434   Reset (frm->fasta_doc);
33435   if (frm->wiz->sequences == NULL) {
33436     AppendText (frm->fasta_doc, s_WizardIntroText[frm->wiz->wizard_type - 1], &(frm->parFmt), &(frm->colFmt), programFont);
33437     if (frm->wiz->wizard_type == eWizardType_WGS) {
33438       url = s_WGSURL;
33439     } else {
33440       url = s_VectorURL;
33441     }
33442 
33443     if (url != NULL) {
33444       AppendText (frm->fasta_doc, url, &(frm->parFmt), &(frm->colFmt), programFont);
33445     }
33446 
33447     if (!frm->wiz->is_fasta) {
33448       AppendText (frm->fasta_doc, s_AlignmentInstructionsText, &(frm->parFmt), &(frm->colFmt), programFont);
33449     }
33450 
33451     UpdateDocument (frm->fasta_doc, 0, 0);
33452 
33453     /* enable import button */
33454     Enable (frm->fasta_import_btn);
33455     /* enable FASTA vs. align group and options button */
33456     if (frm->fasta_vs_aln != NULL) {
33457       Enable (frm->fasta_vs_aln);
33458       if (GetValue (frm->fasta_vs_aln) == 2) {
33459         Enable (frm->aln_btn);
33460       } else {
33461         Disable (frm->aln_btn);
33462       }
33463     }
33464     /* disable clear button */
33465     Disable (frm->fasta_clear_btn);
33466     /* disable vecscreen btn */
33467     SafeDisable (frm->vecscreen_btn);
33468   } else {
33469     Reset (frm->fasta_doc);
33470     /* provide sequence summary */
33471     /* number of sequences, lengths? */
33472     iatep = SeqEntryListToIDAndTitleEditEx (frm->wiz->sequences, TRUE);
33473     sprintf (txt, "%d sequences\n", iatep->num_sequences);
33474     AppendText (frm->fasta_doc,
33475                 txt,
33476                 &(frm->parFmt), &(frm->colFmt), programFont);
33477 
33478     for (i = 0; i < iatep->num_sequences; i++) {
33479       line = (CharPtr) MemNew (sizeof (Char) * (StringLen (line_fmt) + StringLen (iatep->id_list[i]) + 15));
33480       sprintf (line, line_fmt, iatep->id_list[i], iatep->length_list[i]);
33481       AppendText (frm->fasta_doc,
33482                   line,
33483                   &(frm->parFmt), &(frm->colFmt), programFont);
33484       line = MemFree (line);
33485     }
33486     iatep = IDAndTitleEditFree (iatep);
33487 
33488     UpdateDocument (frm->fasta_doc, 0, 0);
33489 
33490     /* disable import button */
33491     Disable (frm->fasta_import_btn);
33492     /* disable sequence/alignment choice button and alignment options button*/
33493     if (frm->fasta_vs_aln != NULL) {
33494       Disable (frm->fasta_vs_aln);
33495       Disable (frm->aln_btn);
33496     }
33497     /* enable clear button */
33498     Enable (frm->fasta_clear_btn);
33499     /* enable vecscreen button */
33500     SafeEnable (frm->vecscreen_btn);
33501   }
33502 }
33503 
33504 
CountSequences(SeqEntryPtr seq_list)33505 static Int4 CountSequences (SeqEntryPtr seq_list)
33506 {
33507   Int4 num = 0;
33508   BioseqPtr bsp;
33509   BioseqSetPtr bssp;
33510 
33511   while (seq_list != NULL) {
33512     if (IS_Bioseq (seq_list)) {
33513       bsp = (BioseqPtr) seq_list->data.ptrvalue;
33514       if (bsp != NULL) {
33515         num++;
33516       }
33517     } else if (IS_Bioseq_set (seq_list)) {
33518       bssp = (BioseqSetPtr) seq_list->data.ptrvalue;
33519       if (bssp != NULL) {
33520         num += CountSequences (bssp->seq_set);
33521       }
33522     }
33523     seq_list = seq_list->next;
33524   }
33525   return num;
33526 }
33527 
33528 
BadSeqIdLengths(SeqEntryPtr sep)33529 NLM_EXTERN Boolean BadSeqIdLengths (SeqEntryPtr sep)
33530 {
33531   BioseqPtr bsp;
33532   BioseqSetPtr bssp;
33533   Boolean      rval = FALSE;
33534   SeqIdPtr     sip;
33535   ObjectIdPtr  oip;
33536   DbtagPtr     dbtag;
33537 
33538   while (sep != NULL && !rval) {
33539     if (IS_Bioseq (sep) && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL) {
33540       for (sip = bsp->id; sip != NULL && !rval; sip = sip->next) {
33541         if (sip->choice == SEQID_LOCAL
33542             && (oip = (ObjectIdPtr) sip->data.ptrvalue) != NULL
33543             && StringLen (oip->str) > 64) {
33544           Message (MSG_ERROR, "Please do not use sequence IDs longer than 64 characters (example: %s).", oip->str);
33545           rval = TRUE;
33546         } else if (sip->choice == SEQID_GENERAL
33547                    && (dbtag = (DbtagPtr) sip->data.ptrvalue) != NULL
33548                    && dbtag->tag != NULL
33549                    && StringLen (dbtag->tag->str) > 64) {
33550           Message (MSG_ERROR, "Please do not use sequence IDs longer than 64 characters (example: %s).", dbtag->tag->str);
33551           rval = TRUE;
33552         }
33553       }
33554     } else if (IS_Bioseq_set (sep) && (bssp = (BioseqSetPtr) sep->data.ptrvalue) != NULL) {
33555       rval = BadSeqIdLengths(bssp->seq_set);
33556     }
33557     sep = sep->next;
33558   }
33559   return rval;
33560 }
33561 
33562 
ImportSeqCallback(Int4 seq_count,Int4 nt_count,Pointer data)33563 static void ImportSeqCallback (Int4 seq_count, Int4 nt_count, Pointer data)
33564 {
33565   Char    buf[50];
33566   PrompT  ppt;
33567   Int4    x = 0;
33568 
33569   if (seq_count % 100 == 0) {
33570     x = 1;
33571   }
33572   if (seq_count % 10 == 0) {
33573     x = 2;
33574   }
33575 /*  if ((ppt = (PrompT) data) != NULL && count % 100 == 0) { */
33576   if ((ppt = (PrompT) data) != NULL) {
33577     sprintf (buf, "%d %d", seq_count, nt_count);
33578     SetTitle (ppt, buf);
33579     Show (ppt);
33580     Update();
33581   }
33582 }
33583 
33584 
ExportWizardFASTA(SeqEntryPtr sep)33585 static void ExportWizardFASTA (SeqEntryPtr sep)
33586 {
33587   CharPtr       extension;
33588   FILE          *f;
33589   Char          path [PATH_MAX];
33590   Boolean       rval = FALSE;
33591 
33592   path [0] = '\0';
33593 
33594   extension = NULL;
33595   extension = GetAppProperty ("FastaNucExtension");
33596 
33597   if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), extension)) {
33598     f = FileOpen (path, "w");
33599     if (f == NULL)
33600     {
33601       Message (MSG_ERROR, "Unable to open %s", path);
33602     }
33603     else
33604     {
33605       WatchCursor ();
33606       ExportFASTASeqEntryList (sep, f);
33607       FileClose (f);
33608 
33609       ArrowCursor ();
33610       Update ();
33611       rval = TRUE;
33612     }
33613   }
33614 }
33615 
33616 
ImportWizardFASTA(ButtoN b)33617 static void ImportWizardFASTA (ButtoN b)
33618 {
33619   WizardFastaFormPtr frm;
33620   Char        path [PATH_MAX];
33621   CharPtr     extension;
33622   SeqEntryPtr sep = NULL, next;
33623   FILE * fp;
33624   Boolean     changed = FALSE;
33625 
33626   frm = (WizardFastaFormPtr) GetObjectExtra (b);
33627   if (frm == NULL) {
33628     return;
33629   }
33630 
33631   /* read in FASTA */
33632   extension = GetAppProperty ("FastaNucExtension");
33633   if (! GetInputFileName (path, sizeof (path), extension, "TEXT")) {
33634     return;
33635   }
33636 
33637   if (frm->wiz->is_fasta) {
33638     sep = GetSequencesFromFileEx (path, NULL, ImportSeqCallback, frm->current_count);
33639     Hide (frm->current_count);
33640   } else {
33641     fp = FileOpen (path, "r");
33642     if (fp == NULL) {
33643       Message (MSG_ERROR, "Unable to open %s", path);
33644     } else {
33645       sep = SeqEntryFromAlignmentFile (fp, frm->wiz->aln_settings, Seq_mol_na, NULL);
33646       FileClose (fp);
33647     }
33648   }
33649   if (sep == NULL) {
33650     Message (MSG_ERROR, "Unable to read %s from %s", frm->wiz->is_fasta ? "sequences" : "alignment", path);
33651     return;
33652   } else if (BadSeqIdLengths (sep)) {
33653     while (sep != NULL) {
33654       next = sep->next;
33655       sep->next = NULL;
33656       SeqEntryFree (sep);
33657       sep = next;
33658     }
33659     frm->wiz->sequences = NULL;
33660     return;
33661   } else if (frm->wiz->wizard_type == eWizardType_WGS) {
33662     frm->wiz->sequences = sep;
33663     if (!CheckForWGSSource(frm->wiz)) {
33664       QuitFromWizard (frm->form);
33665       return;
33666     } else if (CountSequences (sep) > 10000) {
33667       Message (MSG_ERROR, "Your file should contain less than 10,000 sequences.  Please split your file.");
33668       while (sep != NULL) {
33669         next = sep->next;
33670         sep->next = NULL;
33671         SeqEntryFree (sep);
33672         sep = next;
33673       }
33674       frm->wiz->sequences = NULL;
33675       return;
33676     } else {
33677       if (WGSSequenceAdjustment (frm->wiz)) {
33678         if (frm->wiz->has_agp) {
33679           sep = frm->wiz->sequences;
33680           if (sep != NULL) {
33681             if (ANS_YES == Message (MSG_YN, "Would you like to save an adjusted sequence file to use when you regenerate your AGP file?")) {
33682               ExportWizardFASTA (sep);
33683             }
33684           }
33685           frm->wiz->sequences = NULL;
33686           while (sep != NULL) {
33687             next = sep->next;
33688             sep->next = NULL;
33689             SeqEntryFree (sep);
33690             sep = next;
33691           }
33692           return;
33693         } else {
33694           if (ANS_YES == Message (MSG_YN, "Would you like to save an adjusted sequence file?")) {
33695             ExportWizardFASTA (frm->wiz->sequences);
33696           }
33697         }
33698       }
33699     }
33700     sep = frm->wiz->sequences;
33701   } else {
33702     TrimLowQualitySequences (&sep, frm->wiz->wizard_type);
33703   }
33704 
33705   frm->wiz->sequences = sep;
33706   /* change instructions */
33707   SetFastaText (frm);
33708 }
33709 
33710 
ClearWizardFASTA(ButtoN b)33711 static void ClearWizardFASTA (ButtoN b)
33712 {
33713   WizardFastaFormPtr frm;
33714   SeqEntryPtr sep, next;
33715 
33716   frm = (WizardFastaFormPtr) GetObjectExtra (b);
33717   if (frm == NULL) {
33718     return;
33719   }
33720 
33721   if (ANS_CANCEL == Message (MSG_OKC, "Are you sure?  All source and annotation information will be lost.")) {
33722     return;
33723   }
33724   /* remove sequences */
33725   sep = frm->wiz->sequences;
33726   while (sep != NULL) {
33727     next = sep->next;
33728     sep->next = NULL;
33729     SeqEntryFree (sep);
33730     sep = next;
33731   }
33732   frm->wiz->sequences = NULL;
33733 
33734   /* change instructions */
33735   SetFastaText (frm);
33736 
33737   /* clean up some other items */
33738   frm->wiz->bioproject = MemFree (frm->wiz->bioproject);
33739   frm->wiz->biosample = MemFree (frm->wiz->biosample);
33740   frm->wiz->srr = MemFree (frm->wiz->srr);
33741 
33742 }
33743 
33744 
ChangeWizardFastaPage(VoidPtr data,Int2 newval,Int2 oldval)33745 static void ChangeWizardFastaPage (VoidPtr data, Int2 newval, Int2 oldval)
33746 
33747 {
33748   WizardFastaFormPtr  frm;
33749 
33750   frm = (WizardFastaFormPtr) data;
33751   if (frm == NULL) {
33752     return;
33753   }
33754   frm->currentPage = newval;
33755   SafeHide (frm->pages [oldval]);
33756   SafeShow (frm->pages [newval]);
33757 
33758   if (newval == 0) {
33759     SendHelpScrollMessage (helpForm, "Wizard Import Nucleotide Sequences", "");
33760   } else {
33761     SendHelpScrollMessage (helpForm, "Sequencing Method", "");
33762   }
33763 
33764 
33765   Update ();
33766 }
33767 
33768 
33769 static CharPtr s_ShorterThan50Msg = "\
33770 Sequences shorter than %d nucleotides were detected in your submission.\n\
33771 GenBank will not accept sequences with fewer than 50 nucleotides. Please \n\
33772 remove the short sequences from your file.\
33773 ";
33774 static CharPtr s_ShorterThan200Msg = "\
33775 Sequences shorter than %d nucleotides were detected in your submission.\n\
33776 GenBank does not accept sequences with fewer than 200 nucleotides. Please \n\
33777 remove the short sequences from your file or provide an explanation of \n\
33778 why you are submitting short sequences in your email when you submit.\
33779 ";
33780 
33781 
ShowPolicyBtn(ButtoN b)33782 static void ShowPolicyBtn (ButtoN b)
33783 {
33784   LaunchWebBrowser("http://www.ncbi.nlm.nih.gov/books/NBK53707/#gbankquickstart.what_kind_of_data_will_2");
33785 }
33786 
33787 
ShortSequencesOk(SeqEntryPtr seq,Int4 min,Int4 rec)33788 static Boolean ShortSequencesOk (SeqEntryPtr seq, Int4 min, Int4 rec)
33789 {
33790   ModalAcceptCancelData acd;
33791   WindoW                w;
33792   GrouP                 h, c;
33793   GrouP                 txt;
33794   ButtoN                b, policy_btn;
33795   Boolean               rval = FALSE;
33796   CharPtr               msg;
33797   Int4 num_short;
33798 
33799   if ((num_short = CountShortSequences(seq, min)) > 0) {
33800     Message (MSG_ERROR, s_ShorterThan50Msg, min);
33801     return FALSE;
33802   } else if (rec <= min) {
33803     return TRUE;
33804   } else if ((num_short = CountShortSequences (seq, rec)) == 0) {
33805     return TRUE;
33806   }
33807 
33808   acd.accepted = FALSE;
33809   acd.cancelled = FALSE;
33810   acd.third_option = FALSE;
33811 
33812   w = ModalWindow(-20, -13, -10, -10, NULL);
33813   h = HiddenGroup (w, -1, 0, NULL);
33814   SetGroupSpacing (h, 10, 10);
33815 
33816   msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (s_ShorterThan200Msg) + 15));
33817   sprintf (msg, s_ShorterThan200Msg, rec);
33818   txt = MultiLinePrompt (h, msg, 30 * stdCharWidth, systemFont);
33819   msg = MemFree (msg);
33820 
33821   policy_btn = PushButton (h, "See Submission Policy", ShowPolicyBtn);
33822 
33823   c = HiddenGroup (h, 3, 0, NULL);
33824   SetGroupSpacing (c, 10, 10);
33825   b = PushButton (c, "Continue - provide an explanation in email", ModalAcceptButton);
33826   SetObjectExtra (b, &acd, NULL);
33827   b = PushButton (c, "Go back and remove sequences", ModalCancelButton);
33828   SetObjectExtra (b, &acd, NULL);
33829   AlignObjects (ALIGN_CENTER, (HANDLE) txt, (HANDLE) policy_btn, (HANDLE) c, NULL);
33830 
33831   Show(w);
33832   Select (w);
33833   while (!acd.accepted && ! acd.cancelled)
33834   {
33835     ProcessExternalEvent ();
33836     Update ();
33837   }
33838   ProcessAnEvent ();
33839   Remove (w);
33840   if (acd.accepted)
33841   {
33842     rval = TRUE;
33843   }
33844   return rval;
33845 }
33846 
33847 
IsSequencingMethodOkForTSA(WizardTrackerPtr wiz)33848 static Boolean IsSequencingMethodOkForTSA (WizardTrackerPtr wiz)
33849 {
33850   CharPtr tech;
33851   ValNodePtr sc;
33852   ValNode vn;
33853 
33854   if (wiz == NULL) {
33855     return FALSE;
33856   }
33857   sc = GetStructuredCommentFromList (wiz->structured_comments,
33858                                      GetSequencingMethodPrefixForWizardType(wiz->wizard_type));
33859   if (sc == NULL) {
33860     return FALSE;
33861   }
33862   MemSet (&vn, 0, sizeof (ValNode));
33863   vn.choice = StructuredCommentField_named;
33864   vn.data.ptrvalue = "Sequencing Technology";
33865   tech = GetStructuredCommentFieldFromUserObject (sc->data.ptrvalue, &vn, NULL);
33866   if (StringICmp (tech, "Sanger dideoxy sequencing") == 0
33867       && wiz->assembled_choice != 2) {
33868     Message (MSG_ERROR, "This wizard should not be used with Sanger dideoxy sequencing results.");
33869     return FALSE;
33870   }
33871   return TRUE;
33872 }
33873 
33874 
AbandonSequences(WizardTrackerPtr wiz)33875 static void AbandonSequences (WizardTrackerPtr wiz)
33876 {
33877   SeqEntryPtr sep, next;
33878 
33879   if (wiz == NULL) {
33880     return;
33881   }
33882   sep = wiz->sequences;
33883   while (sep != NULL) {
33884     next = sep->next;
33885     sep->next = NULL;
33886     SeqEntryFree (sep);
33887     sep = next;
33888   }
33889   wiz->sequences = NULL;
33890 }
33891 
33892 
WizardFASTAFwd(ButtoN b)33893 static void WizardFASTAFwd (ButtoN b)
33894 {
33895   WizardFastaFormPtr frm;
33896   SequencingMethodInfoPtr info;
33897   CreateFormFunc next_form = NULL;
33898   Int4           ans;
33899   ValNodePtr     errs;
33900 
33901   if ((frm = (WizardFastaFormPtr) GetObjectExtra (b)) == NULL) {
33902     return;
33903   }
33904 
33905   if (frm->currentPage == 0) {
33906     ChangeWizardFastaPage (frm, 1, 0);
33907     SetValue (frm->tbs, 1);
33908     return;
33909   }
33910 
33911   if (frm->wiz->sequences == NULL) {
33912     Message (MSG_ERROR, "You must import FASTA before continuing");
33913     return;
33914   }
33915 
33916   switch (frm->wiz->wizard_type) {
33917     case eWizardType_DLoop:
33918       if (AnySequencesLonger(frm->wiz->sequences, 1099)) {
33919         ans = ThreeOptionsDlg ("Sequences are unexpectedly long",
33920                                "These sequences are longer than expected. Do not use this tool to submit partial mitochondrial genomes.",
33921                                "Abandon", "Continue", "Cancel");
33922         if (ans == 1) {
33923           Show (wizardChoiceForm);
33924           SendHelpScrollMessage (helpForm, "Preparing the Sequences", "");
33925           AbandonSequences(frm->wiz);
33926           Remove (frm->form);
33927           return;
33928         } else if (ans == 3) {
33929           return;
33930         }
33931       }
33932       break;
33933   }
33934 
33935   /* check for sequencing info */
33936   RemoveStructuredCommentFromList (&(frm->wiz->structured_comments),
33937                                    GetSequencingMethodPrefixForWizardType(frm->wiz->wizard_type));
33938   errs = TestDialog (frm->sequencing_method);
33939   if (errs != NULL) {
33940     Message (MSG_ERROR, "%s", errs->data.ptrvalue);
33941     errs = ValNodeFree (errs);
33942     return;
33943   }
33944   info = DialogToPointer (frm->sequencing_method);
33945   if (info != NULL) {
33946     ValNodeLink (&(frm->wiz->structured_comments), info->structured_comments);
33947     info->structured_comments = NULL;
33948     frm->wiz->assembled_choice = info->assembled_choice;
33949     frm->wiz->quit_now = info->quit_now;
33950   }
33951   info = SequencingMethodInfoFree (info);
33952 
33953   if (!IsSequencingMethodValid (frm->wiz)) {
33954     if (frm->wiz->quit_now) {
33955       QuitFromWizard (frm->form);
33956     }
33957     return;
33958   }
33959 
33960   if (!ShortSequencesOk(frm->wiz->sequences, frm->wiz->min_seq_length, frm->wiz->recommended_seq_length)) {
33961     if (RemoveSequencesFromWizardList (&(frm->wiz->sequences), frm->wiz->recommended_seq_length)) {
33962       /* redraw dialog */
33963       SetFastaText (frm);
33964     }
33965     return;
33966   }
33967 
33968   Hide (frm->form);
33969   if (frm->wiz->sequences->next != NULL || IS_Bioseq_set (frm->wiz->sequences)) {
33970     switch (frm->wiz->wizard_type) {
33971       case eWizardType_UnculturedSamples:
33972         globalFormatBlock.seqPackage = SEQ_PKG_GENBANK;
33973         if (IS_Bioseq_set (frm->wiz->sequences)) {
33974           frm->wiz->set_class = BioseqseqSet_class_eco_set;
33975           next_form = CreateWizardSrcQualsForm;
33976         } else {
33977           next_form = WizardSetTypeForm;
33978         }
33979         break;
33980       case eWizardType_Viruses:
33981       case eWizardType_CulturedSamples:
33982       case eWizardType_IGS:
33983       case eWizardType_DLoop:
33984         globalFormatBlock.seqPackage = SEQ_PKG_GENBANK;
33985         next_form = WizardSetTypeForm;
33986         break;
33987       case eWizardType_Microsatellite:
33988         globalFormatBlock.seqPackage = SEQ_PKG_GENBANK;
33989         next_form = CreateWizardMoleculeForm;
33990         break;
33991       case eWizardType_WGS:
33992         globalFormatBlock.seqPackage = SEQ_PKG_GENBANK;
33993         next_form = CreateWGSWizardSourceTypeForm;
33994         break;
33995       default:
33996         next_form = CreateWizardSrcQualsForm;
33997         break;
33998     }
33999   } else {
34000     if (frm->wiz->wizard_type == eWizardType_Microsatellite) {
34001       next_form = CreateMicrosatelliteAnnotationTypeForm;
34002     } else if (frm->wiz->wizard_type == eWizardType_Viruses
34003         || frm->wiz->wizard_type == eWizardType_CulturedSamples
34004         || frm->wiz->wizard_type == eWizardType_IGS) {
34005       next_form = WizardSourceTypeForm;
34006     } else if (frm->wiz->wizard_type == eWizardType_WGS) {
34007       next_form = CreateWGSWizardSourceTypeForm;
34008     } else {
34009       next_form = CreateWizardSrcQualsForm;
34010     }
34011 
34012   }
34013   AddToWizardBreadcrumbTrail (frm->wiz, next_form);
34014   next_form (frm->wiz);
34015   frm->wiz = NULL;
34016   Remove (frm->form);
34017 
34018 }
34019 
WizardFASTABack(ButtoN b)34020 static void WizardFASTABack (ButtoN b)
34021 {
34022   WizardFastaFormPtr frm;
34023   Int4 ans;
34024   CharPtr title = "Leaving Wizard";
34025   CharPtr question = "You are about to leave the wizard - do you want to abandon your data and start over, or copy it to the normal submission dialog?";
34026 
34027   frm = (WizardFastaFormPtr) GetObjectExtra (b);
34028   if (frm == NULL) {
34029     return;
34030   }
34031 
34032   if (frm->currentPage == 1) {
34033     ChangeWizardFastaPage (frm, 0, 1);
34034     SetValue (frm->tbs, 0);
34035     return;
34036   }
34037 
34038   switch (frm->wiz->wizard_type) {
34039     case eWizardType_UnculturedSamples:
34040       title = "Leaving Uncultured Samples Wizard";
34041       question = "You are about to leave the uncultured samples wizard - do you want to abandon your data and start over, or copy it to the normal submission dialog?";
34042       break;
34043     case eWizardType_Viruses:
34044       title = "Leaving Viruses Wizard";
34045       question = "You are about to leave the viruses wizard - do you want to abandon your data and start over, or copy it to the normal submission dialog?";
34046       break;
34047     case eWizardType_CulturedSamples:
34048       title = "Leaving rRNA-ITS-IGS Sequences Wizard";
34049       question = "You are about to leave the rRNA-ITS-IGS sequences wizard - do you want to abandon your data and start over, or copy it to the normal submission dialog?";
34050       break;
34051     case eWizardType_IGS:
34052       title = "Leaving Intergenic Spacer Wizard";
34053       question = "You are about to leave the intergenic spacer wizard - do you want to abandon your data and start over, or copy it to the normal submission dialog?";
34054       break;
34055     case eWizardType_Microsatellite:
34056       title = "Leaving Microsatellite Wizard";
34057       question = "You are about to leave the microsatellite wizard - do you want to abandon your data and start over, or copy it to the normal submission dialog?";
34058       break;
34059     case eWizardType_DLoop:
34060       title = "Leaving D-Loop Wizard";
34061       question = "You are about to leave the D-Loop wizard - do you want to abandon your data and start over, or copy it to the normal submission dialog?";
34062       break;
34063   }
34064 
34065   /* ask if they want to abandon the data completely, jump to normal dialog, or cancel */
34066   ans = ThreeOptionsDlg (title, question,
34067                          "Copy", "Abandon", "Cancel");
34068   if (ans == 1) {
34069     RejoinMainSubmissionForm (frm->wiz->sequences, 0, frm->wiz);
34070     frm->wiz->sequences = NULL;
34071     Remove (frm->form);
34072   } else if (ans == 2) {
34073     Show (wizardChoiceForm);
34074     SendHelpScrollMessage (helpForm, "Preparing the Sequences", "");
34075     AbandonSequences(frm->wiz);
34076     Remove (frm->form);
34077   }
34078 }
34079 
34080 
WizardFastaHelpBtn(ButtoN b)34081 static void WizardFastaHelpBtn (ButtoN b)
34082 {
34083   WizardTrackerPtr wiz;
34084 
34085   wiz = (WizardTrackerPtr) GetObjectExtra (b);
34086   if (wiz == NULL) {
34087     return;
34088   }
34089   switch (wiz->wizard_type) {
34090     case eWizardType_UnculturedSamples:
34091       ShowWizardHelpText ("FASTA Format Help", s_UnculturedSamplesFastaExample);
34092       break;
34093     case eWizardType_Viruses:
34094       ShowWizardHelpText ("FASTA Format Help", s_VirusFastaExample);
34095       break;
34096     case eWizardType_CulturedSamples:
34097       ShowWizardHelpText ("FASTA Format Help", s_CulturedSamplesFastaExample);
34098       break;
34099     case eWizardType_Microsatellite:
34100       ShowWizardHelpText ("FASTA Format Help", s_MicrosatelliteFastaExample);
34101       break;
34102     case eWizardType_DLoop:
34103       ShowWizardHelpText ("FASTA Format Help", s_DLoopFastaExample);
34104       break;
34105     case eWizardType_IGS:
34106       ShowWizardHelpText ("FASTA Format Help", s_IGSFastaExample);
34107       break;
34108   }
34109 }
34110 
34111 
QuitWizard(IteM i)34112 static void QuitWizard (IteM i)
34113 {
34114   WizardFastaFormPtr frm;
34115 
34116   frm = (WizardFastaFormPtr) GetObjectExtra (i);
34117   if (frm == NULL) {
34118     return;
34119   }
34120 
34121   Remove (frm->form);
34122   Hide (initSubmitForm);
34123   Update ();
34124   Show (startupForm);
34125   Select (startupForm);
34126   SendHelpScrollMessage (helpForm, "Introduction", NULL);
34127   Update ();
34128 }
34129 
34130 
ChangeFastaVsAln(GrouP g)34131 static void ChangeFastaVsAln (GrouP g)
34132 {
34133   WizardFastaFormPtr frm;
34134 
34135   frm = (WizardFastaFormPtr) GetObjectExtra (g);
34136   if (frm == NULL) {
34137     return;
34138   }
34139   if (GetValue (frm->fasta_vs_aln) == 1) {
34140     // will import FASTA
34141     Disable (frm->aln_btn);
34142     frm->wiz->is_fasta = TRUE;
34143     SetTitle (frm->fasta_import_btn, "Import Nucleotide FASTA");
34144     SetTitle (frm->fasta_clear_btn, "Clear Nucleotide FASTA");
34145   } else {
34146     // will import alignment
34147     Enable (frm->aln_btn);
34148     frm->wiz->is_fasta = FALSE;
34149     SetTitle (frm->fasta_import_btn, "Import Nucleotide Alignment");
34150     SetTitle (frm->fasta_clear_btn, "Clear Nucleotide Alignment");
34151   }
34152 }
34153 
34154 
GetWizardAlnSettings(ButtoN b)34155 static void GetWizardAlnSettings (ButtoN b)
34156 {
34157   WizardFastaFormPtr frm;
34158   TSequenceInfoPtr new_settings;
34159 
34160   frm = (WizardFastaFormPtr) GetObjectExtra (b);
34161   if (frm == NULL) {
34162     return;
34163   }
34164   new_settings = GetAlignmentOptions (NULL, frm->wiz->aln_settings);
34165   if (new_settings != NULL)
34166   {
34167     SequenceInfoFree (frm->wiz->aln_settings);
34168     frm->wiz->aln_settings = new_settings;
34169   }
34170 }
34171 
34172 
34173 static void RemoveSequencesFromWizard (IteM i);
34174 static void RemoveAllSequencesFromWizard (IteM i);
34175 
34176 
WizardVectorTrim(ButtoN b)34177 static void WizardVectorTrim (ButtoN b)
34178 {
34179   WizardFastaFormPtr frm;
34180 
34181   frm = (WizardFastaFormPtr) GetObjectExtra (b);
34182   if (frm == NULL || frm->wiz == NULL) {
34183     return;
34184   }
34185   WizardVectorTool(&(frm->wiz->sequences));
34186   SetFastaText (frm);
34187 }
34188 
34189 
34190 static CharPtr wizardFastaFormTabs [] = {
34191   "Sequences",  "Sequencing Method", NULL
34192 };
34193 
34194 
CreateWizardFastaForm(WizardTrackerPtr wiz)34195 static Boolean CreateWizardFastaForm(WizardTrackerPtr wiz)
34196 {
34197   WizardFastaFormPtr frm;
34198   WindoW w;
34199   GrouP  h;
34200   GrouP  k;
34201   GrouP  g;
34202   GrouP  table_btns, aln_btns = NULL;
34203   ButtoN b;
34204   RecT   r;
34205   MenU   m;
34206   IteM   i;
34207 #ifdef WIN_MAC
34208   Int2          wid = 30;
34209 #else
34210   Int2          wid = 40;
34211 #endif
34212 
34213 
34214   frm = (WizardFastaFormPtr) MemNew (sizeof (WizardFastaFormData));
34215   frm->wiz = wiz;
34216 
34217   w = FixedWindow (-50, -33, -10, -10, "Wizard Import Nucleotide Sequences", NULL);
34218   SetObjectExtra (w, frm, CleanupWizardFastaForm);
34219   frm->form = (ForM) w;
34220 
34221   m = PulldownMenu (w, "File/ F");
34222   AddAboutAndHelpMenuItems (m);
34223   i = CommandItem (m, "Quit", QuitWizard);
34224   SetObjectExtra (i, frm, NULL);
34225   m = PulldownMenu (w, "Edit/ E");
34226   i = CommandItem (m, "Sequence Deletion Tool", RemoveSequencesFromWizard);
34227   SetObjectExtra (i, frm, NULL);
34228   i = CommandItem (m, "Delete All Sequences", RemoveAllSequencesFromWizard);
34229   SetObjectExtra (i, frm, NULL);
34230 
34231   h = HiddenGroup (w, -1, 0, NULL);
34232   SetGroupSpacing (h, 10, 10);
34233 
34234   frm->tbs = CreateFolderTabs (h, wizardFastaFormTabs, 0,
34235                                     0, 0, SYSTEM_FOLDER_TAB,
34236                                     ChangeWizardFastaPage, (Pointer) frm);
34237 
34238   k = HiddenGroup (h, 0, 0, NULL);
34239   frm->pages[0] = HiddenGroup (k, -1, 0, NULL);
34240   SetGroupSpacing (frm->pages[0], 10, 10);
34241 
34242   frm->fasta_doc = DocumentPanel (frm->pages[0], stdCharWidth * wid, stdLineHeight * 26);
34243   SetDocProcs (frm->fasta_doc, ClickDocURL, NULL, NULL, NULL);
34244   SetDocAutoAdjust (frm->fasta_doc, FALSE);
34245   MemSet (&(frm->parFmt), 0, sizeof (ParData));
34246   MemSet (&(frm->colFmt), 0, sizeof (ColData));
34247   frm->colFmt.charWidth = 80;
34248   frm->colFmt.just = 'l';
34249   frm->colFmt.wrap = TRUE;
34250   frm->colFmt.last = TRUE;
34251   ObjectRect (frm->fasta_doc, &r);
34252   InsetRect (&r, 4, 4);
34253   frm->colFmt.pixWidth = r.right - r.left;
34254 
34255   if (wiz->wizard_type != eWizardType_Microsatellite
34256       && wiz->wizard_type != eWizardType_WGS) {
34257     aln_btns = HiddenGroup (frm->pages[0], 2, 0, NULL);
34258     SetGroupSpacing (aln_btns, 10, 10);
34259     frm->fasta_vs_aln = HiddenGroup (aln_btns, 2, 0, ChangeFastaVsAln);
34260     SetGroupSpacing (frm->fasta_vs_aln, 10, 10);
34261     SetObjectExtra (frm->fasta_vs_aln, frm, NULL);
34262     RadioButton (frm->fasta_vs_aln, "Just FASTA");
34263     RadioButton (frm->fasta_vs_aln, "Alignment");
34264     if (wiz->is_fasta) {
34265       SetValue (frm->fasta_vs_aln, 1);
34266     } else {
34267       SetValue (frm->fasta_vs_aln, 2);
34268     }
34269     frm->aln_btn = PushButton (aln_btns, "Optional Alignment Settings", GetWizardAlnSettings);
34270     SetObjectExtra (frm->aln_btn, frm, NULL);
34271     Disable (frm->aln_btn);
34272   }
34273   frm->current_count = StaticPrompt (frm->pages[0], "      sequences", 0, 0, systemFont, 'c');
34274   Hide (frm->current_count);
34275 
34276   table_btns = HiddenGroup (frm->pages[0], 6, 0, NULL);
34277   SetGroupSpacing (table_btns, 10, 10);
34278 
34279   frm->fasta_import_btn = PushButton (table_btns, "Import Nucleotide FASTA", ImportWizardFASTA);
34280   SetObjectExtra (frm->fasta_import_btn, frm, NULL);
34281   frm->fasta_clear_btn = PushButton (table_btns, "Clear Nucleotide FASTA", ClearWizardFASTA);
34282   SetObjectExtra (frm->fasta_clear_btn, frm, NULL);
34283   b = PushButton (table_btns, "FASTA Format Help", WizardFastaHelpBtn);
34284   SetObjectExtra (b, wiz, NULL);
34285   if (wiz->wizard_type != eWizardType_WGS) {
34286     frm->vecscreen_btn = PushButton (frm->pages[0], "Vector Trim Tool", WizardVectorTrim);
34287     SetObjectExtra (frm->vecscreen_btn, frm, NULL);
34288   }
34289 
34290   if (frm->vecscreen_btn == NULL) {
34291     AlignObjects (ALIGN_CENTER, (HANDLE) frm->fasta_doc, (HANDLE) table_btns, (HANDLE) frm->current_count, (HANDLE) aln_btns, NULL);
34292   } else {
34293     AlignObjects (ALIGN_CENTER, (HANDLE) frm->fasta_doc, (HANDLE) table_btns, (HANDLE) frm->current_count, (HANDLE) frm->vecscreen_btn, (HANDLE) aln_btns, NULL);
34294   }
34295 
34296   frm->pages[1] = HiddenGroup (k, -1, 0, NULL);
34297   SetGroupSpacing (frm->pages[1], 10, 10);
34298   frm->sequencing_method = SequencingMethodDialog (frm->pages[1], frm->wiz->wizard_type);
34299   AlignObjects (ALIGN_CENTER, (HANDLE) frm->pages[0], (HANDLE) frm->pages[1], NULL);
34300   Hide (frm->pages[1]);
34301 
34302   g = HiddenGroup (h, 2, 0, NULL);
34303   SetGroupSpacing (g, 10, 10);
34304   b = PushButton (g, "Back", WizardFASTABack);
34305   SetObjectExtra (b, frm, NULL);
34306   b = PushButton (g, "Next", WizardFASTAFwd);
34307   SetObjectExtra (b, frm, NULL);
34308 
34309   AlignObjects (ALIGN_CENTER, (HANDLE) frm->tbs, (HANDLE) k, (HANDLE) g, NULL);
34310 
34311   if (aln_btns != NULL) {
34312     ChangeFastaVsAln(frm->fasta_vs_aln);
34313   }
34314 
34315   SetFastaText (frm);
34316 
34317   Update();
34318   Show (w);
34319   SendHelpScrollMessage (helpForm, "Wizard Import Nucleotide Sequences", "");
34320 
34321   return TRUE;
34322 }
34323 
34324 
34325 typedef struct wizardchoiceform {
34326   FORM_MESSAGE_BLOCK
34327 
34328   GrouP wizard_choice;
34329 } WizardChoiceFormData, PNTR WizardChoiceFormPtr;
34330 
34331 
BackToSubmitterForm(ButtoN b)34332 static void BackToSubmitterForm (ButtoN b)
34333 {
34334   Hide (wizardChoiceForm);
34335   Update ();
34336   PointerToForm (initSubmitForm, globalsbp);
34337   globalsbp = SequinBlockFree (globalsbp);
34338   Show (initSubmitForm);
34339   Select (initSubmitForm);
34340   SendHelpScrollMessage (helpForm, "Submitting Authors Form", NULL);
34341   Update ();
34342   globalFormatBlock.seqPackage = SEQ_PKG_SINGLE;
34343   globalFormatBlock.seqFormat = SEQ_FMT_FASTA;
34344   globalFormatBlock.numSeqs = 0;
34345   globalFormatBlock.submType = SEQ_ORIG_SUBMISSION;
34346 }
34347 
34348 
NextToWizard(ButtoN b)34349 static void NextToWizard (ButtoN b)
34350 {
34351   WizardChoiceFormPtr frm;
34352   Int2 val;
34353   WizardTrackerPtr wiz;
34354 
34355   frm = (WizardChoiceFormPtr) GetObjectExtra (b);
34356   if (frm == NULL) {
34357     return;
34358   }
34359 
34360   val = GetValue (frm->wizard_choice);
34361   switch (val) {
34362     case 5:
34363       Hide (frm->form);
34364       wiz = WizardTrackerNew(eWizardType_Viruses, NULL);
34365       CreateWizardFastaForm (wiz);
34366       Update();
34367       break;
34368     case 6:
34369       Hide (frm->form);
34370       wiz = WizardTrackerNew(eWizardType_UnculturedSamples, NULL);
34371       CreateWizardFastaForm (wiz);
34372       Update();
34373       break;
34374     case 7:
34375       Hide (frm->form);
34376       wiz = WizardTrackerNew(eWizardType_CulturedSamples, NULL);
34377       CreateWizardFastaForm (wiz);
34378       Update();
34379       break;
34380     case 8:
34381       Hide (frm->form);
34382       wiz = WizardTrackerNew(eWizardType_IGS, NULL);
34383       CreateWizardFastaForm (wiz);
34384       Update();
34385       break;
34386     case 9:
34387       Hide (frm->form);
34388       wiz = WizardTrackerNew (eWizardType_Microsatellite, NULL);
34389       CreateWizardFastaForm (wiz);
34390       Update();
34391       break;
34392     case 10:
34393       Hide (frm->form);
34394       wiz = WizardTrackerNew (eWizardType_DLoop, NULL);
34395       CreateWizardFastaForm (wiz);
34396       Update();
34397       break;
34398     case 2:
34399       Hide (frm->form);
34400       Show (formatForm);
34401       Select (formatForm);
34402       SendHelpScrollMessage (helpForm, "Sequence Format Form", NULL);
34403       Update ();
34404       break;
34405     case 0:
34406     default:
34407       Message (MSG_ERROR, "You must select an option!");
34408       return;
34409       break;
34410   }
34411 
34412 }
34413 
34414 
CreateWizardChoiceForm(void)34415 static ForM CreateWizardChoiceForm (void)
34416 {
34417   WindoW w;
34418   WizardChoiceFormPtr frm;
34419   GrouP h, c;
34420   ButtoN b;
34421   CharPtr dlg_title = "Preparing the Sequences";
34422 
34423   SeqEntrySetScope (NULL);
34424 
34425   frm = (WizardChoiceFormPtr) MemNew (sizeof (WizardChoiceFormData));
34426   w = FixedWindow (-5, -67, -10, -10, dlg_title, NULL);
34427   SetObjectExtra (w, frm, StdCleanupFormProc);
34428   frm->form = (ForM) w;
34429 
34430   h = HiddenGroup (w, -1, 0, NULL);
34431   SetGroupSpacing (h, 10, 10);
34432 
34433   frm->wizard_choice = NormalGroup (h, 0, 15, "How do you want to prepare your submission?", systemFont, NULL);
34434   SetGroupSpacing (frm->wizard_choice, 10, 10);
34435 
34436   StaticPrompt (frm->wizard_choice, "", 0, 0, programFont, 'l');
34437   RadioButton (frm->wizard_choice, "Use the normal submission dialog");
34438   StaticPrompt (frm->wizard_choice, "---------------------------------", 0, 0, programFont, 'l');
34439   StaticPrompt (frm->wizard_choice, "Use a Submission Wizard:", 0, 0, systemFont, 'l');
34440   RadioButton (frm->wizard_choice, "Viruses");
34441   RadioButton (frm->wizard_choice, "Uncultured Samples");
34442   RadioButton (frm->wizard_choice, "rRNA-ITS-IGS sequences");
34443   RadioButton (frm->wizard_choice, "Intergenic Spacer (IGS) sequences");
34444   RadioButton (frm->wizard_choice, "Microsatellite sequences");
34445   RadioButton (frm->wizard_choice, "D-loops and control regions");
34446 
34447   SetValue (frm->wizard_choice, 1);
34448 
34449   c = HiddenGroup (h, 2, 0, NULL);
34450   SetGroupSpacing (c, 10, 10);
34451 
34452   b = PushButton (c, "Back", BackToSubmitterForm);
34453   SetObjectExtra (b, frm, NULL);
34454   b = PushButton (c, "Next", NextToWizard);
34455   SetObjectExtra (b, frm, NULL);
34456 
34457   AlignObjects (ALIGN_CENTER, (HANDLE) frm->wizard_choice, (HANDLE) c, NULL);
34458   RealizeWindow (w);
34459   return (ForM) w;
34460 }
34461 
34462 
RemoveSequencesFromWizard(IteM i)34463 static void RemoveSequencesFromWizard (IteM i)
34464 {
34465   WizardFastaFormPtr frm;
34466 
34467   frm = (WizardFastaFormPtr) GetObjectExtra (i);
34468   if (frm == NULL || frm->wiz == NULL || frm->wiz->sequences == NULL) {
34469     return;
34470   }
34471 
34472   if (RemoveSequencesFromWizardList (&(frm->wiz->sequences), frm->wiz->recommended_seq_length)) {
34473     /* redraw dialog */
34474     SetFastaText (frm);
34475   }
34476 
34477 }
34478 
34479 
RemoveAllSequencesFromWizard(IteM i)34480 static void RemoveAllSequencesFromWizard (IteM i)
34481 {
34482   WizardFastaFormPtr frm;
34483   SeqEntryPtr        sep, next;
34484 
34485   frm = (WizardFastaFormPtr) GetObjectExtra (i);
34486   if (frm == NULL || frm->wiz == NULL || frm->wiz->sequences == NULL) {
34487     return;
34488   }
34489   if (ANS_CANCEL == Message (MSG_OKC, "Are you sure?  All source and annotation information will be lost.")) {
34490     return;
34491   }
34492   /* remove sequences */
34493   sep = frm->wiz->sequences;
34494   while (sep != NULL) {
34495     next = sep->next;
34496     sep->next = NULL;
34497     SeqEntryFree (sep);
34498     sep = next;
34499   }
34500   frm->wiz->sequences = NULL;
34501 
34502   /* change instructions */
34503   SetFastaText (frm);
34504 }
34505 
34506 
34507 typedef struct wizardkeyword {
34508   CharPtr keyword;
34509   EWizardType wizard_type;
34510 } WizardKeywordData, PNTR WizardKeywordPtr;
34511 
34512 
34513 static WizardKeywordData wizard_keyword_list[] = {
34514   { "virus", eWizardType_Viruses} ,
34515   { "uncultured", eWizardType_UnculturedSamples},
34516   { "16S", eWizardType_CulturedSamples},
34517   { "ITS", eWizardType_CulturedSamples},
34518   { "rRNA", eWizardType_CulturedSamples},
34519   { "ribosomal RNA", eWizardType_CulturedSamples},
34520   { "internal transcribed spacer", eWizardType_CulturedSamples},
34521   { "microsatellite", eWizardType_Microsatellite},
34522   { "D-loop", eWizardType_DLoop},
34523   { "Control region", eWizardType_DLoop},
34524   { NULL, eWizardType_CulturedSamples}
34525 };
34526 
34527 
DetectWizardWordsInFastaDeflines(SeqEntryPtr sep)34528 static Int4 DetectWizardWordsInFastaDeflines (SeqEntryPtr sep)
34529 {
34530   Int4 rval = -1;
34531   BioseqPtr bsp;
34532   SeqDescrPtr sdp;
34533   Int4        j;
34534 
34535   while (sep != NULL && rval == -1) {
34536     if (IS_Bioseq (sep) && (bsp = (BioseqPtr) sep->data.ptrvalue) != NULL) {
34537       for (sdp = bsp->descr; sdp != NULL && rval == -1; sdp = sdp->next) {
34538         if (sdp->choice == Seq_descr_title) {
34539           for (j = 0; wizard_keyword_list[j].keyword != NULL; j++) {
34540             if (StringISearch ((CharPtr) sdp->data.ptrvalue, wizard_keyword_list[j].keyword) != NULL) {
34541               rval = wizard_keyword_list[j].wizard_type;
34542             }
34543           }
34544         }
34545       }
34546     }
34547     sep = sep->next;
34548   }
34549   return rval;
34550 }
34551 
34552 
GetRNAWizardType(void)34553 static Int4 GetRNAWizardType (void)
34554 {
34555   WindoW w;
34556   GrouP  h, sample_choice, c;
34557   ButtoN b;
34558   ModalAcceptCancelData acd;
34559   Int4 rval = -1;
34560 
34561   w = ModalWindow(-20, -13, -10, -10, NULL);
34562   h = HiddenGroup (w, -1, 0, NULL);
34563   SetGroupSpacing (h, 10, 10);
34564 
34565   sample_choice = NormalGroup (h, 1, 0, "Are all of your sequences from", systemFont, NULL);
34566   RadioButton (sample_choice, "Pure cultures");
34567   RadioButton (sample_choice, "Uncultured samples from bulk environmental DNA");
34568   RadioButton (sample_choice, "Plant or Animal");
34569   RadioButton (sample_choice, "None of the above - use regular dialogs");
34570   SetValue (sample_choice, 4);
34571 
34572   c = HiddenGroup (h, 3, 0, NULL);
34573   SetGroupSpacing (c, 10, 10);
34574   b = PushButton (c, "Ok", ModalAcceptButton);
34575   SetObjectExtra (b, &acd, NULL);
34576   b = PushButton (c, "Cancel (use regular dialogs)", ModalCancelButton);
34577   SetObjectExtra (b, &acd, NULL);
34578   AlignObjects (ALIGN_CENTER, (HANDLE) sample_choice, (HANDLE) c, NULL);
34579 
34580   acd.accepted = FALSE;
34581   acd.cancelled = FALSE;
34582   acd.third_option = FALSE;
34583 
34584   Show(w);
34585   Select (w);
34586   while (!acd.accepted && ! acd.cancelled && ! acd.third_option)
34587   {
34588     ProcessExternalEvent ();
34589     Update ();
34590   }
34591   ProcessAnEvent ();
34592   if (acd.accepted)
34593   {
34594     switch (GetValue (sample_choice)) {
34595       case 1:
34596       case 3:
34597         rval = eWizardType_CulturedSamples;
34598         break;
34599       case 2:
34600         rval = eWizardType_UnculturedSamples;
34601         break;
34602     }
34603   }
34604   Remove (w);
34605   return rval;
34606 }
34607 
34608 
34609 static CharPtr s_AskForWizard[] = {
34610   NULL,
34611 "\
34612 You may use the uncultured sample wizard if these sequences are all from an uncultured source.\n\
34613 Would you like to use the uncultured sample wizard to assist with your submission?",
34614 "\
34615 You may use the Submission Wizard for viruses if your file contains all virus sequences.\n\
34616 Would you like to use the virus wizard to assist with your submission?",
34617 "\
34618 It appears you may be submitting rRNA or ITS sequences.\n\
34619 Would you like to use a wizard to assist with your submission?",
34620   NULL,
34621 "\
34622 You may use the Submission Wizard for Intergenic spacer sequences if your file contains all sequences from the same Intergenic spacer.\n\
34623 Would you like to use the Intergenic spacer wizard to assist with your submission?",
34624 "\
34625 You may use the Submission Wizard for Microsatellites if your file contains all microsatellite sequences.\n\
34626 Would you like to use the Microsatellite wizard to assist with your submission?",
34627 "\
34628 You may use the Submission Wizard for D-loops and Control regions if your file contains all sequences from D-loops and control regions.\n\
34629 Would you like to use the D-loop/Control region wizard to assist with your submission?",
34630   NULL
34631 };
34632 
34633 
SuggestJumpingToWizard(SeqEntryPtr sep)34634 NLM_EXTERN Boolean SuggestJumpingToWizard (SeqEntryPtr sep)
34635 {
34636   Int4 wizard_type;
34637   Boolean rval = FALSE;
34638   WizardTrackerPtr wiz;
34639   CharPtr ask;
34640 
34641   if (ValNodeLen (sep) < 20) {
34642     return FALSE;
34643   }
34644   wizard_type = DetectWizardWordsInFastaDeflines (sep);
34645   if (wizard_type == -1) {
34646     return FALSE;
34647   }
34648   ask = s_AskForWizard[wizard_type];
34649   if (ask == NULL) {
34650     return FALSE;
34651   }
34652 
34653   switch (wizard_type) {
34654     case eWizardType_CulturedSamples:
34655       if (ANS_OK == Message (MSG_OKC, ask)) {
34656         wizard_type = GetRNAWizardType ();
34657         if (wizard_type != -1) {
34658           wiz = WizardTrackerNew(wizard_type, sep);
34659           CreateWizardFastaForm (wiz);
34660           rval = TRUE;
34661         }
34662       }
34663       break;
34664     default:
34665       if (ask != NULL && ANS_OK == Message (MSG_OKC, ask)) {
34666         wiz = WizardTrackerNew(wizard_type, sep);
34667         CreateWizardFastaForm (wiz);
34668         rval = TRUE;
34669       }
34670       break;
34671   }
34672   return rval;
34673 }
34674