|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/sequin/sequin7.c |
source navigation diff markup identifier search freetext search file search |
1 /* sequin7.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: sequin7.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 1/3/98
31 *
32 * $Revision: 6.368 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44
45 #ifndef CODECENTER
46 static char *date_of_compilation = __DATE__;
47 static char *time_of_compilation = __TIME__;
48 #else
49 static char *date_of_compilation = "today";
50 static char *time_of_compilation = "now";
51 #endif
52
53 #include "sequin.h"
54 #include <gather.h>
55 #include <edutil.h>
56 #include <cdrgn.h>
57 #include <subutil.h>
58 #include <tofasta.h>
59 #include <vsm.h>
60 #include <document.h>
61 #include <maputil.h>
62 #include <asn2gnbp.h>
63 #include <bspview.h>
64 #include <findrepl.h>
65 #include <toasn3.h>
66 #include <toporg.h>
67 #include <utilpub.h>
68 #include <salsap.h>
69 #include <salptool.h>
70 #include <salutil.h>
71 #include <saledit.h>
72 #include <explore.h>
73 #include <seqpanel.h>
74 #include <alignmgr2.h>
75 #include <actutils.h>
76 #include <tax3api.h>
77 #include <algo/blast/api/blast_options_api.h>
78 #include <algo/blast/api/blast_seqalign.h>
79 #include <algo/blast/api/blast_api.h>
80 #include <salstruc.h>
81 #include <valid.h> /* added for latloncountry conflict checking */
82
83 #define CONVERT_TO_JOIN 1
84 #define CONVERT_TO_ORDER 2
85 #define DO_NOT_CONVERT 3
86
87 NLM_EXTERN SeqEntryPtr FastaToSeqEntryInternal
88 (
89 VoidPtr input, /* input pointer (file or memory) */
90 Int4 type, /* type of inquiry FASTA_MEM_IO or FASTA_FILE_IO */
91 CharPtr PNTR last_char, /* returned pointer to next FASTA sequence */
92 Boolean is_na, /* type of sequence */
93 CharPtr PNTR errormsg, /* error messge for debugging */
94 Boolean parseSeqId, /* Parse SeqID from def line */
95 CharPtr special_symbol /* Returns special symbol if no SeqEntry */
96 );
97
98 NLM_EXTERN SeqEntryPtr SequinFastaToSeqEntryExEx
99 (
100 FILE *fp, /* file to get sequence from */
101 Boolean is_na, /* type of sequence */
102 CharPtr PNTR errormsg, /* error message for debugginq */
103 Boolean parseSeqId, /* Parse SeqID from def line */
104 CharPtr special_symbol, /* Returns special symbol if no SeqEntry */
105 BoolPtr chars_stripped /* set to TRUE if characters other than digits
106 * were stripped from the FASTA sequence data */
107 )
108 {
109 BioseqPtr bsp;
110 FileCache fc;
111 Boolean forceNuc = FALSE;
112 Boolean forceProt = FALSE;
113 Pointer dataptr;
114 Uint2 datatype;
115 Char line [128];
116 Int4 pos;
117 SeqEntryPtr sep = NULL;
118 CharPtr str;
119
120 if (errormsg != NULL) {
121 *errormsg = NULL;
122 }
123 if (special_symbol != NULL) {
124 *special_symbol = NULLB;
125 }
126 if (is_na) {
127 forceNuc = TRUE;
128 } else {
129 forceProt = TRUE;
130 }
131 dataptr = ReadAsnFastaOrFlatFileEx (fp, &datatype, NULL, forceNuc, forceProt, parseSeqId, FALSE, chars_stripped);
132 if (dataptr != NULL) {
133 if (datatype == OBJ_BIOSEQ) {
134 bsp = (BioseqPtr) dataptr;
135 sep = SeqMgrGetSeqEntryForData (bsp);
136 if (sep == NULL) {
137 sep = SeqEntryNew ();
138 if (sep != NULL) {
139 sep->choice = 1;
140 sep->data.ptrvalue = bsp;
141 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
142 }
143 }
144 }
145 } else if (special_symbol != NULL) {
146 /* look ahead to see what character caused inability to interpret line */
147 FileCacheSetup (&fc, fp);
148 /* pos = FileCacheTell (&fc); */
149 str = FileCacheReadLine (&fc, line, sizeof (line), NULL);
150 if (str != NULL && StringDoesHaveText (str)) {
151 TrimSpacesAroundString (str);
152 }
153 *special_symbol = line [0];
154 /* seek to start of next line after one that could not be interpreted */
155 pos = FileCacheTell (&fc);
156 FileCacheSetup (&fc, fp);
157 FileCacheSeek (&fc, pos);
158 fseek (fp, pos, SEEK_SET);
159 }
160 /* return FastaToSeqEntryInternal((void *)fp, 2, NULL,is_na, errormsg, parseSeqId, special_symbol); */
161 return sep;
162 }
163
164 NLM_EXTERN SeqEntryPtr SequinFastaToSeqEntryEx
165 (
166 FILE *fp, /* file to get sequence from */
167 Boolean is_na, /* type of sequence */
168 CharPtr PNTR errormsg, /* error message for debugginq */
169 Boolean parseSeqId, /* Parse SeqID from def line */
170 CharPtr special_symbol /* Returns special symbol if no SeqEntry */
171 )
172 {
173 return SequinFastaToSeqEntryExEx (fp, is_na, errormsg, parseSeqId, special_symbol, NULL);
174 }
175
176 static FonT titleFont = NULL;
177
178 #ifndef WIN_MAC
179 void CreateSqnInitialFormMenus (WindoW w)
180
181 {
182 BaseFormPtr bfp;
183 MenU m;
184
185 bfp = (BaseFormPtr) GetObjectExtra (w);
186 if (bfp != NULL) {
187 m = PulldownMenu (w, "File");
188 AddAboutAndHelpMenuItems (m);
189 if (bfp->importform != NULL || bfp->exportform != NULL) {
190 if (bfp->importform != NULL) {
191 FormCommandItem (m, "Import...", bfp, VIB_MSG_IMPORT);
192 }
193 if (bfp->exportform != NULL) {
194 FormCommandItem (m, "Export...", bfp, VIB_MSG_EXPORT);
195 }
196 SeparatorItem (m);
197 }
198 FormCommandItem (m, "Quit", bfp, VIB_MSG_QUIT);
199 m = PulldownMenu (w, "Edit");
200 FormCommandItem (m, CUT_MENU_ITEM, bfp, VIB_MSG_CUT);
201 FormCommandItem (m, COPY_MENU_ITEM, bfp, VIB_MSG_COPY);
202 FormCommandItem (m, PASTE_MENU_ITEM, bfp, VIB_MSG_PASTE);
203 FormCommandItem (m, CLEAR_MENU_ITEM, bfp, VIB_MSG_DELETE);
204 }
205 }
206 #endif
207
208 static void DefaultMessageProc (ForM f, Int2 mssg)
209
210 {
211 StdEditorProcsPtr sepp;
212
213 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
214 if (sepp != NULL) {
215 if (sepp->handleMessages != NULL) {
216 sepp->handleMessages (f, mssg);
217 }
218 }
219 }
220
221 typedef struct startupform {
222 FORM_MESSAGE_BLOCK
223 } StartupForm, PNTR StartupFormPtr;
224
225 static void ChangeDestination (GrouP g)
226
227 {
228 Char str [64];
229 Int2 val;
230
231 val = GetValue (g);
232 switch (val) {
233 case 1 :
234 RemoveAppProperty ("SequinUseEMBLStyle");
235 RemoveAppProperty ("SequinUseDDBJStyle");
236 if (GetAppParam ("SEQUIN", "PREFERENCES", "DATABASE", NULL, str, sizeof (str))) {
237 if (! StringHasNoText (str)) {
238 if (StringICmp (str, "GenBank") != 0) {
239 WriteSequinAppParam ("PREFERENCES", "DATABASE", "GenBank");
240 }
241 }
242 }
243 break;
244 case 2 :
245 SetAppProperty ("SequinUseEMBLStyle", (void *) 1024);
246 RemoveAppProperty ("SequinUseDDBJStyle");
247 WriteSequinAppParam ("PREFERENCES", "DATABASE", "EMBL");
248 break;
249 case 3 :
250 RemoveAppProperty ("SequinUseEMBLStyle");
251 SetAppProperty ("SequinUseDDBJStyle", (void *) 1024);
252 WriteSequinAppParam ("PREFERENCES", "DATABASE", "DDBJ");
253 break;
254 default :
255 break;
256 }
257 SetupBioseqPageList ();
258 }
259
260 static void CenterString (RectPtr rptr, CharPtr text, FonT fnt, Int2 inc)
261
262 {
263 if (fnt != NULL) {
264 SelectFont (fnt);
265 }
266 rptr->bottom = rptr->top + LineHeight ();
267 DrawString (rptr, text, 'c', FALSE);
268 rptr->top = rptr->bottom + inc;
269 }
270
271 extern void DrawAbout (PaneL p)
272
273 {
274 RecT r;
275
276
277 if (titleFont == NULL) {
278 #ifdef WIN_MAC
279 titleFont = GetFont ("Geneva", 18, TRUE, TRUE, FALSE, "");
280 #endif
281 #ifdef WIN_MSWIN
282 titleFont = GetFont ("Arial", 24, TRUE, TRUE, FALSE, "");
283 #endif
284 #ifdef WIN_MOTIF
285 titleFont = GetFont ("Courier", 24, TRUE, TRUE, FALSE, "");
286 #endif
287 }
288
289 ObjectRect (p, &r);
290 InsetRect (&r, 4, 4);
291 r.top += 5;
292 Blue ();
293 CenterString (&r, "Sequin", titleFont, 5);
294 CenterString (&r, SEQUIN_VERSION, programFont, 5);
295 CenterString (&r, SEQUIN_SERVICES, programFont, 10);
296 CenterString (&r, "National Center for Biotechnology Information", systemFont, 5);
297 CenterString (&r, "National Library of Medicine", systemFont, 5);
298 CenterString (&r, "National Institutes of Health", systemFont, 10);
299 CenterString (&r, "(301) 496-2475", systemFont, 5);
300 CenterString (&r, "info@ncbi.nlm.nih.gov", systemFont, 0);
301 }
302
303 extern Int2 AboutBoxWidth (void)
304
305 {
306 Int2 max;
307 CharPtr ptr;
308 Char sequinServices [60];
309 Char sequinVersion [60];
310 Int2 wid;
311
312
313 if (titleFont == NULL) {
314 #ifdef WIN_MAC
315 titleFont = GetFont ("Geneva", 18, TRUE, TRUE, FALSE, "");
316 #endif
317 #ifdef WIN_MSWIN
318 titleFont = GetFont ("Arial", 24, TRUE, TRUE, FALSE, "");
319 #endif
320 #ifdef WIN_MOTIF
321 titleFont = GetFont ("Courier", 24, TRUE, TRUE, FALSE, "");
322 #endif
323 }
324
325 sprintf (sequinVersion, "Sequin Application Version %s", SEQUIN_APPLICATION);
326 ptr = "Standard Release";
327 /*#ifdef USE_ENTREZ*/
328 if (useEntrez || useBlast) {
329 ptr = "Network Aware";
330 }
331 /*#endif*/
332 /*#ifdef INTERNAL_NCBI_SEQUIN*/
333 if (indexerVersion) {
334 ptr = "Indexer Services";
335 }
336 /*#endif*/
337 if (genomeCenter != NULL) {
338 ptr = "Genome Center";
339 }
340 sprintf (sequinServices, "%s [%s]", ptr, date_of_compilation);
341
342 SelectFont (titleFont);
343 max = StringWidth ("Sequin");
344 SelectFont (programFont);
345 wid = StringWidth (sequinVersion);
346 if (wid > max) {
347 max = wid;
348 }
349 wid = StringWidth (sequinServices);
350 if (wid > max) {
351 max = wid;
352 }
353 SelectFont (systemFont);
354 wid = StringWidth ("National Center for Biotechnology Information");
355 if (wid > max) {
356 max = wid;
357 }
358 max += 2 * stdCharWidth + 2;
359 return max;
360 }
361
362 extern Int2 AboutBoxHeight (void)
363
364 {
365 Int2 hgt;
366
367 if (titleFont == NULL) {
368 #ifdef WIN_MAC
369 titleFont = GetFont ("Geneva", 18, TRUE, TRUE, FALSE, "");
370 #endif
371 #ifdef WIN_MSWIN
372 titleFont = GetFont ("Arial", 24, TRUE, TRUE, FALSE, "");
373 #endif
374 #ifdef WIN_MOTIF
375 titleFont = GetFont ("Courier", 24, TRUE, TRUE, FALSE, "");
376 #endif
377 }
378
379 SelectFont (titleFont);
380 hgt = LineHeight () + 5;
381 SelectFont (programFont);
382 hgt += 2 * LineHeight () + 15;
383 SelectFont (systemFont);
384 hgt += 5 * LineHeight () + 25;
385 hgt += 18;
386 return hgt;
387 }
388
389 extern ForM CreateStartupForm (Int2 left, Int2 top, CharPtr title,
390 BtnActnProc startFa2htgs,
391 BtnActnProc startPhrap,
392 BtnActnProc buildContig,
393 BtnActnProc startNew,
394 BtnActnProc readExisting,
395 BtnActnProc fetchFromNet,
396 BtnActnProc showHelp,
397 BtnActnProc createSubmissionTemplate,
398 BtnActnProc quitProgram,
399 WndActnProc activateForm)
400
401 {
402 ButtoN b;
403 GrouP c;
404 GrouP d;
405 GrouP k;
406 PaneL p;
407 StartupFormPtr sfp;
408 Char str [32];
409 WindoW w;
410 #ifndef WIN_MAC
411 MenU m;
412 #endif
413
414 w = NULL;
415 sfp = MemNew (sizeof (StartupForm));
416 if (sfp != NULL) {
417 w = FixedWindow (left, top, -10, -10, title, NULL);
418 SetObjectExtra (w, sfp, StdCleanupFormProc);
419 sfp->form = (ForM) w;
420 sfp->formmessage = DefaultMessageProc;
421
422 #ifndef WIN_MAC
423 m = PulldownMenu (w, "Misc");
424 CommandItem (m, "Net Configure...", NetConfigureProc);
425 if (useEntrez) {
426 /*
427 SeparatorItem (m);
428 CommandItem (m, "Entrez Query...", EntrezQueryProc);
429 SeparatorItem (m);
430 CommandItem (m, "Entrez2 Query...", Entrez2QueryProc);
431 */
432 if (extraServices) {
433 SeparatorItem (m);
434 CommandItem (m, "Process FASTA Nucleotide Updates", ParseInNucUpdates);
435 }
436 }
437 if (useDesktop) {
438 SeparatorItem (m);
439 VSMAddToMenu (m, VSM_DESKTOP);
440 }
441 #endif
442
443 p = SimplePanel (w, AboutBoxWidth (), AboutBoxHeight (), DrawAbout);
444
445 k = HiddenGroup (w, 4, 0, NULL);
446 SetGroupSpacing (k, 3, 10);
447 StaticPrompt (k, "Database for submission", 0, stdLineHeight, programFont, 'l');
448 d = HiddenGroup (k, 4, 0, ChangeDestination);
449 RadioButton (d, "GenBank");
450 RadioButton (d, "EMBL");
451 RadioButton (d, "DDBJ");
452 if (GetAppParam ("SEQUIN", "PREFERENCES", "DATABASE", NULL, str, sizeof (str))) {
453 if (StringICmp (str, "GenBank") == 0) {
454 SetValue (d, 1);
455 } else if (StringICmp (str, "EMBL") == 0) {
456 SetValue (d, 2);
457 } else if (StringICmp (str, "DDBJ") == 0) {
458 SetValue (d, 3);
459 } else {
460 SetValue (d, 1);
461 }
462 } else {
463 SetValue (d, 1);
464 }
465 ChangeDestination (d);
466
467 c = HiddenGroup (w, 1, 0, NULL);
468 SetGroupSpacing (c, 10, 5);
469
470 if (startFa2htgs != NULL) {
471 b = PushButton (c, "New FA2HTGS Submission", startFa2htgs);
472 SetObjectExtra (b, sfp, NULL);
473 }
474 if (startPhrap != NULL) {
475 b = PushButton (c, "New PHRAP Submission", startPhrap);
476 SetObjectExtra (b, sfp, NULL);
477 }
478 if (buildContig != NULL) {
479 b = PushButton (c, "Read CONTIG Instructions", buildContig);
480 SetObjectExtra (b, sfp, NULL);
481 }
482 b = PushButton (c, "Start New Submission", startNew);
483 SetObjectExtra (b, sfp, NULL);
484 b = PushButton (c, "Read Existing Record", readExisting);
485 SetObjectExtra (b, sfp, NULL);
486 if (fetchFromNet != NULL) {
487 b = PushButton (c, "Download From Entrez", fetchFromNet);
488 SetObjectExtra (b, sfp, NULL);
489 }
490 b = PushButton (c, "Show Help", showHelp);
491 SetObjectExtra (b, sfp, NULL);
492 if (createSubmissionTemplate != NULL)
493 {
494 b = PushButton (c, "Submission Template", createSubmissionTemplate);
495 SetObjectExtra (b, sfp, NULL);
496 }
497 b = PushButton (c, "Quit Program", quitProgram);
498 SetObjectExtra (b, sfp, NULL);
499
500 AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) c, (HANDLE) k, NULL);
501
502 RealizeWindow (w);
503
504 if (activateForm != NULL) {
505 SetActivate (w, activateForm);
506 }
507 }
508 return (ForM) w;
509 }
510
511 typedef struct formatform {
512 FORM_MESSAGE_BLOCK
513
514 GrouP package;
515 GrouP format;
516 GrouP submType;
517 ButtoN alignmentButton;
518 ButtoN originalButton;
519 ButtoN tpaButton;
520 TexT numseqs;
521
522 Int2 restoreFormatTo;
523 } FormatForm, PNTR FormatFormPtr;
524
525 static Boolean allowGenomicPlusCDNA = FALSE;
526
527 static void FormatBlockPtrToFormatForm (ForM f, Pointer data)
528
529 {
530 FormatBlockPtr fbp;
531 FormatFormPtr ffp;
532 Char str [32];
533
534 ffp = (FormatFormPtr) GetObjectExtra (f);
535 fbp = (FormatBlockPtr) data;
536 if (ffp == NULL) return;
537 if (fbp != NULL) {
538 if (fbp->seqPackage > 0 && fbp->seqPackage <= NUM_SEQ_PKG) {
539 if ((! allowGenomicPlusCDNA) && fbp->seqPackage >= SEQ_PKG_GENOMICCDNA) {
540 SafeSetValue (ffp->package, fbp->seqPackage - 1);
541 } else {
542 SafeSetValue (ffp->package, fbp->seqPackage);
543 }
544 if (fbp->seqPackage <= SEQ_PKG_GENOMICCDNA || fbp->seqPackage == SEQ_PKG_GENBANK) {
545 SafeDisable (ffp->alignmentButton);
546 } else {
547 SafeEnable (ffp->alignmentButton);
548 }
549 } else {
550 SafeSetValue (ffp->package, SEQ_PKG_SINGLE);
551 SafeDisable (ffp->alignmentButton);
552 }
553 if (fbp->seqFormat > 0 && fbp->seqFormat <= NUM_SEQ_FMT) {
554 SafeSetValue (ffp->format, fbp->seqFormat);
555 } else {
556 SafeSetValue (ffp->format, SEQ_FMT_FASTA);
557 }
558 if (fbp->numSeqs > 0) {
559 IntToStr (fbp->numSeqs, str, 0, sizeof (str));
560 SafeSetTitle (ffp->numseqs, str);
561 } else {
562 SafeSetTitle (ffp->numseqs, "");
563 }
564 } else {
565 SafeSetValue (ffp->package, SEQ_PKG_SINGLE);
566 SafeDisable (ffp->alignmentButton);
567 SafeSetValue (ffp->format, SEQ_FMT_FASTA);
568 SafeSetTitle (ffp->numseqs, "");
569 ffp->restoreFormatTo = SEQ_FMT_FASTA;
570 }
571 }
572
573 static Pointer FormatFormToFormatBlockPtr (ForM f)
574
575 {
576 FormatBlockPtr fbp;
577 FormatFormPtr ffp;
578 Char str [32];
579 Int2 val;
580
581 fbp = NULL;
582 ffp = (FormatFormPtr) GetObjectExtra (f);
583 if (ffp == NULL) return NULL;
584 fbp = (FormatBlockPtr) MemNew (sizeof (FormatBlock));
585 if (fbp == NULL) return NULL;
586 fbp->seqPackage = GetValue (ffp->package);
587 if ((! allowGenomicPlusCDNA) && fbp->seqPackage >= SEQ_PKG_GENOMICCDNA) {
588 (fbp->seqPackage)++;
589 }
590 fbp->seqFormat = GetValue (ffp->format);
591 fbp->submType = GetValue (ffp->submType);
592 GetTitle (ffp->numseqs, str, sizeof (str));
593 if (StrToInt (str, &val) && val > 0) {
594 fbp->numSeqs = val;
595 } else {
596 fbp->numSeqs = 0;
597 }
598 return (Pointer) fbp;
599 }
600
601 static void EnableOrDisableFormats (GrouP g)
602
603 {
604 FormatFormPtr ffp;
605 Int2 val;
606
607 ffp = (FormatFormPtr) GetObjectExtra (g);
608 if (ffp == NULL) return;
609 val = GetValue (g);
610 if ((! allowGenomicPlusCDNA) && val >= SEQ_PKG_GENOMICCDNA) {
611 val++;
612 }
613 if (val <= SEQ_PKG_GENOMICCDNA || val == SEQ_PKG_GENBANK) {
614 if (Enabled (ffp->alignmentButton)) {
615 ffp->restoreFormatTo = GetValue (ffp->format);
616 }
617 SafeSetValue (ffp->format, SEQ_FMT_FASTA);
618 SafeDisable (ffp->alignmentButton);
619 } else {
620 if (! Enabled (ffp->alignmentButton)) {
621 SafeSetValue (ffp->format, ffp->restoreFormatTo);
622 }
623 SafeEnable (ffp->alignmentButton);
624 }
625 }
626
627 static Boolean ExportTemplateMenu (ForM f, CharPtr filename)
628 {
629 WindoW w;
630 GrouP h, g1, g2, c;
631 ButtoN b;
632 DialoG org_dlg;
633 TexT comment_txt;
634 ModalAcceptCancelData acd;
635 SeqEntryPtr sep;
636 BioseqSetPtr bssp;
637 BioSourcePtr biop;
638 SeqDescrPtr sdp;
639 CharPtr org_name;
640 Boolean done;
641
642 if (ANS_NO == Message (MSG_YN, "Do you want to add an organism name and comment before saving the template?"))
643 {
644 bssp = BioseqSetNew ();
645 bssp->_class = BioseqseqSet_class_not_set;
646 sep = SeqEntryNew ();
647 sep->choice = 2;
648 sep->data.ptrvalue = bssp;
649
650 done = ExportSubmitterBlockTemplate (sep, NULL);
651 if (!done)
652 {
653 /* if done were TRUE, sep would have been freed as part of the new SeqSubmit */
654 SeqEntryFree (sep);
655 }
656 return done;
657 }
658
659 w = MovableModalWindow (-20, -13, -10, -10, "Submission Template", NULL);
660 h = HiddenGroup(w, -1, 0, NULL);
661 SetGroupSpacing (h, 10, 10);
662
663 g1 = NormalGroup (h, 1, 0, "Organism Name", programFont, NULL);
664 org_dlg = OrganismSelectionDialog (g1, "");
665 g2 = NormalGroup (h, 2, 0, "Comment", programFont, NULL);
666 comment_txt = DialogText (g2, "", 30, NULL);
667
668 c = HiddenGroup (h, 2, 0, NULL);
669 b = PushButton (c, "Accept", ModalAcceptButton);
670 SetObjectExtra (b, &acd, NULL);
671 b = PushButton (c, "Cancel", ModalCancelButton);
672 SetObjectExtra (b, &acd, NULL);
673
674 AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2,
675 (HANDLE) c, (HANDLE) NULL);
676
677 Show (w);
678 Select (w);
679 done = FALSE;
680 while (!done)
681 {
682 acd.accepted = FALSE;
683 acd.cancelled = FALSE;
684 while (!acd.accepted && ! acd.cancelled)
685 {
686 ProcessExternalEvent ();
687 Update ();
688 }
689 ProcessAnEvent ();
690
691 if (acd.cancelled)
692 {
693 done = TRUE;
694 }
695 else
696 {
697 bssp = BioseqSetNew ();
698 sep = SeqEntryNew ();
699 sep->choice = 2;
700 sep->data.ptrvalue = bssp;
701 bssp->_class = BioseqseqSet_class_not_set;
702
703 org_name = DialogToPointer (org_dlg);
704 if (!StringHasNoText (org_name))
705 {
706 biop = BioSourceNew ();
707 biop->org = OrgRefNew ();
708 biop->org->taxname = org_name;
709 sdp = CreateNewDescriptor (sep, Seq_descr_source);
710 sdp->data.ptrvalue = biop;
711 }
712 else
713 {
714 org_name = MemFree (org_name);
715 }
716
717 sdp = NULL;
718 if (!TextHasNoText (comment_txt))
719 {
720 sdp = CreateNewDescriptor (sep, Seq_descr_comment);
721 sdp->data.ptrvalue = SaveStringFromText (comment_txt);
722 }
723
724 done = ExportSubmitterBlockTemplate (sep, sdp);
725 if (!done)
726 {
727 /* if done were TRUE, sep would have been freed as part of the new SeqSubmit */
728 SeqEntryFree (sep);
729 }
730 }
731 }
732 Remove (w);
733 return acd.accepted;
734 }
735
736 static void FormatFormMessage (ForM f, Int2 mssg)
737
738 {
739 switch (mssg) {
740 case VIB_MSG_EXPORT :
741 ExportTemplateMenu (NULL, NULL);
742 break;
743 case VIB_MSG_CUT :
744 StdCutTextProc (NULL);
745 break;
746 case VIB_MSG_COPY :
747 StdCopyTextProc (NULL);
748 break;
749 case VIB_MSG_PASTE :
750 StdPasteTextProc (NULL);
751 break;
752 case VIB_MSG_DELETE :
753 StdDeleteTextProc (NULL);
754 break;
755 default :
756 DefaultMessageProc (f, mssg);
757 break;
758 }
759 }
760
761 static void CreateFormatFormMenus (WindoW w)
762 {
763 #ifndef WIN_MAC
764 BaseFormPtr bfp;
765 MenU m;
766
767 bfp = (BaseFormPtr) GetObjectExtra (w);
768 if (bfp != NULL) {
769 m = PulldownMenu (w, "File");
770 FormCommandItem (m, "Export Template...", bfp, VIB_MSG_EXPORT);
771 }
772 #endif
773 }
774
775 static void InitFormatFormActivate (WindoW w)
776
777 {
778 IteM exportItm;
779 FormatFormPtr ffp;
780
781 ffp = (FormatFormPtr) GetObjectExtra (w);
782 if (ffp != NULL) {
783 if (ffp->activate != NULL) {
784 ffp->activate (w);
785 }
786 exportItm = FindFormMenuItem ((BaseFormPtr) ffp, VIB_MSG_EXPORT);
787 SafeSetTitle (exportItm, "Export Template...");
788 SafeEnable (exportItm);
789 }
790 }
791
792 extern ForM CreateFormatForm (Int2 left, Int2 top, CharPtr title,
793 BtnActnProc goToNext,
794 BtnActnProc goBack,
795 WndActnProc activateForm)
796
797 {
798 ButtoN b;
799 GrouP c;
800 FormatFormPtr ffp;
801 GrouP g1, g2, g3;
802 GrouP h;
803 PrompT ppt;
804 Char str [32];
805 WindoW w;
806
807 w = NULL;
808 ffp = MemNew (sizeof (FormatForm));
809 if (ffp != NULL) {
810 w = FixedWindow (left, top, -10, -10, title, NULL);
811 SetObjectExtra (w, ffp, StdCleanupFormProc);
812 ffp->form = (ForM) w;
813 ffp->toform = FormatBlockPtrToFormatForm;
814 ffp->fromform = FormatFormToFormatBlockPtr;
815 ffp->formmessage = FormatFormMessage;
816 ffp->exportform = ExportTemplateMenu;
817
818 SetGroupSpacing (w, 10, 10);
819
820 CreateFormatFormMenus (w);
821
822 h = HiddenGroup (w, -1, 0, NULL);
823 SetGroupSpacing (h, 3, 10);
824
825 g1 = HiddenGroup (h, 2, 0, NULL);
826
827 allowGenomicPlusCDNA = FALSE;
828 if (GetAppParam ("SEQUIN", "SETTINGS", "GENOMICPLUSTRANSCRIPTS", NULL, str, sizeof (str))) {
829 if (StringICmp (str, "TRUE") == 0) {
830 allowGenomicPlusCDNA = TRUE;
831 }
832 }
833
834 ppt = StaticPrompt (g1, "Submission type", 0, 0, programFont, 'l');
835 ffp->package = HiddenGroup (g1, 2, 0, EnableOrDisableFormats);
836 SetObjectExtra (ffp->package, ffp, NULL);
837 RadioButton (ffp->package, "Single Sequence");
838 RadioButton (ffp->package, "Segmented Sequence");
839 RadioButton (ffp->package, "Gapped Sequence");
840 if (allowGenomicPlusCDNA) {
841 RadioButton (ffp->package, "Genomic + Transcripts");
842 }
843 RadioButton (ffp->package, "Population Study");
844 RadioButton (ffp->package, "Phylogenetic Study");
845 RadioButton (ffp->package, "Mutation Study");
846 RadioButton (ffp->package, "Environmental Samples");
847 RadioButton (ffp->package, "Batch Submission");
848 SetValue (ffp->package, SEQ_PKG_SINGLE);
849 AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) ffp->package, NULL);
850
851 g2 = HiddenGroup (h, 2, 0, NULL);
852
853 ppt = StaticPrompt (g2, "Sequence data format", 0, 0, programFont, 'l');
854 ffp->format = HiddenGroup (g2, -1, 0, NULL);
855 SetObjectExtra (ffp->format, ffp, NULL);
856 RadioButton (ffp->format, "FASTA (no alignment)");
857 ffp->alignmentButton = RadioButton (ffp->format, "Alignment (FASTA+GAP, NEXUS, PHYLIP, etc.)");
858 Disable (ffp->alignmentButton);
859 SetValue (ffp->format, SEQ_FMT_FASTA);
860 ffp->restoreFormatTo = SEQ_FMT_FASTA;
861 AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) ffp->format, NULL);
862
863 g3 = HiddenGroup (h, 2, 0, NULL);
864
865 ppt = StaticPrompt (g3, "Submission category", 0, 0, programFont, 'l');
866 ffp->submType = HiddenGroup (g3, -1, 0, NULL);
867 SetObjectExtra (ffp->submType, ffp, NULL);
868 ffp->originalButton = RadioButton (ffp->submType, "Original Submission");
869 ffp->tpaButton = RadioButton (ffp->submType, "Third Party Annotation");
870 SetValue (ffp->submType, SEQ_ORIG_SUBMISSION);
871 AlignObjects (ALIGN_MIDDLE, (HANDLE) ppt, (HANDLE) ffp->submType, NULL);
872
873 c = HiddenGroup (w, 4, 0, NULL);
874 SetGroupSpacing (c, 10, 2);
875 b = PushButton (c, " << Prev Form ", goBack);
876 SetObjectExtra (b, ffp, NULL);
877 b = PushButton (c, " Next Form >> ", goToNext);
878 SetObjectExtra (b, ffp, NULL);
879
880 AlignObjects (ALIGN_LEFT, (HANDLE) g1, (HANDLE) g2, (HANDLE) g3, NULL);
881 AlignObjects (ALIGN_CENTER, (HANDLE) h, (HANDLE) c, NULL);
882
883 RealizeWindow (w);
884
885 ffp->activate = activateForm;
886 SetActivate (w, InitFormatFormActivate);
887 }
888 return (ForM) w;
889 }
890
891 extern SequinBlockPtr SequinBlockFree (SequinBlockPtr sbp)
892
893 {
894 if (sbp != NULL) {
895 AuthorFree (sbp->contactperson);
896 AuthListFree (sbp->citsubauthors);
897 AffilFree (sbp->citsubaffil);
898 MemFree (sbp->citsubtitle);
899 DateFree (sbp->releasedate);
900 }
901 return NULL;
902 }
903
904 extern void ExciseString (CharPtr str, CharPtr from, CharPtr to)
905
906 {
907 Char ch;
908 CharPtr ptrf;
909 CharPtr ptrt;
910
911 if (str == NULL || from == NULL || to == NULL) return;
912 ptrf = StringISearch (str, from);
913 if (ptrf == NULL) return;
914 ptrt = StringISearch (ptrf, to);
915 if (ptrt == NULL) return;
916 ptrt += StringLen (to);
917 ch = *ptrt;
918 while (ch != '\0') {
919 *ptrf = ch;
920 ptrf++;
921 ptrt++;
922 ch = *ptrt;
923 }
924 *ptrf = '\0';
925 }
926
927 typedef struct geneextendlist {
928 GeneRefPtr grp;
929 SeqLocPtr slp;
930 ObjMgrPtr omp;
931 Boolean rsult;
932 Char label [41];
933 } GeneExtendList, PNTR GeneExtendPtr;
934
935 static Boolean GeneExtendFunc (GatherContextPtr gcp)
936
937 {
938 BioseqPtr bsp;
939 GeneExtendPtr gep;
940 GeneRefPtr grp;
941 Boolean hasNulls;
942 ObjMgrTypePtr omtp;
943 SeqFeatPtr sfp;
944 SeqLocPtr slp;
945 Char thislabel [41];
946
947 if (gcp == NULL) return TRUE;
948
949 gep = (GeneExtendPtr) gcp->userdata;
950 if (gep == NULL ) return TRUE;
951
952 thislabel [0] = '\0';
953
954 if (gcp->thistype == OBJ_SEQFEAT) {
955 sfp = (SeqFeatPtr) gcp->thisitem;
956 if (sfp != NULL && sfp->data.choice == SEQFEAT_GENE && sfp->data.value.ptrvalue != NULL) {
957 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
958 omtp = ObjMgrTypeFind (gep->omp, gcp->thistype, NULL, NULL);
959 if (omtp == NULL) {
960 return TRUE;
961 }
962 if (omtp->labelfunc != NULL) {
963 (*(omtp->labelfunc)) (gcp->thisitem, thislabel, 40, OM_LABEL_CONTENT);
964 }
965 if (thislabel [0] != '\0') {
966 if (StringICmp (thislabel, gep->label) == 0) {
967 if (SeqLocCompare (gep->slp, sfp->location) != SLC_NO_MATCH) {
968 bsp = GetBioseqGivenSeqLoc (sfp->location, gcp->entityID);
969 if (bsp != NULL) {
970 slp = SeqLocMerge (bsp, sfp->location, gep->slp, TRUE, FALSE, FALSE);
971 if (slp != NULL) {
972 sfp->location = SeqLocFree (sfp->location);
973 sfp->location = slp;
974 if (bsp->repr == Seq_repr_seg) {
975 slp = SegLocToPartsEx (bsp, sfp->location, TRUE);
976 sfp->location = SeqLocFree (sfp->location);
977 sfp->location = slp;
978 hasNulls = LocationHasNullsBetween (sfp->location);
979 sfp->partial = (sfp->partial || hasNulls);
980 }
981 FreeAllFuzz (slp);
982 gep->rsult = TRUE;
983 }
984 }
985 }
986 return FALSE;
987 }
988 }
989 }
990 }
991 return TRUE;
992 }
993
994 extern Boolean ExtendGene (GeneRefPtr grp, SeqEntryPtr nsep, SeqLocPtr slp)
995
996 {
997 GeneExtendList gel;
998 GatherScope gs;
999 ObjMgrTypePtr omtp;
1000 SeqFeatPtr sfp;
1001
1002 if (grp == NULL || nsep == NULL || slp == NULL) return FALSE;
1003 gel.grp = grp;
1004 gel.slp = slp;
1005 gel.omp = ObjMgrGet ();
1006 gel.label [0] = '\0';
1007 gel.rsult = FALSE;
1008 omtp = ObjMgrTypeFind (gel.omp, OBJ_SEQFEAT, NULL, NULL);
1009 if (omtp != NULL && omtp->labelfunc != NULL) {
1010 sfp = SeqFeatNew ();
1011 if (sfp != NULL) {
1012 sfp->data.choice = SEQFEAT_GENE;
1013 sfp->data.value.ptrvalue = (Pointer) grp;
1014 (*(omtp->labelfunc)) ((Pointer) sfp, gel.label, 40, OM_LABEL_CONTENT);
1015 sfp->data.value.ptrvalue = NULL;
1016 SeqFeatFree (sfp);
1017 }
1018 }
1019 MemSet ((Pointer)(&gs), 0, sizeof (GatherScope));
1020 gs.seglevels = 1;
1021 gs.get_feats_location = TRUE;
1022 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
1023 gs.ignore[OBJ_BIOSEQ] = FALSE;
1024 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
1025 gs.ignore[OBJ_SEQFEAT] = FALSE;
1026 gs.ignore[OBJ_SEQANNOT] = FALSE;
1027 GatherSeqEntry (nsep, (Pointer) &gel, GeneExtendFunc, &gs);
1028 return gel.rsult;
1029 }
1030
1031 /*=====================================================================*/
1032 /* */
1033 /* CreateGeneAndProtFeats() - */
1034 /* */
1035 /*=====================================================================*/
1036
1037 static void CreateGeneAndProtFeats (SeqEntryPtr nsep, SeqEntryPtr psep,
1038 SeqLocPtr slp, CdRegionPtr crp, CharPtr title,
1039 CharPtr best, size_t maxsize, CharPtr PNTR ttl)
1040
1041 {
1042 BioseqPtr nbsp;
1043 BioseqPtr pbsp;
1044 SeqFeatPtr sfp;
1045 ProtRefPtr prp = NULL;
1046 Boolean partial5, partial3;
1047
1048 if (nsep != NULL && psep != NULL && slp != NULL && crp != NULL && title != NULL) {
1049 if (best != NULL) {
1050 best [0] = '\0';
1051 }
1052 if (IS_Bioseq (nsep) && IS_Bioseq (psep)) {
1053 nbsp = (BioseqPtr) nsep->data.ptrvalue;
1054 pbsp = (BioseqPtr) psep->data.ptrvalue;
1055 if (nbsp != NULL && pbsp != NULL) {
1056
1057 AddGeneFeatureFromTitle (nsep, title, slp);
1058
1059 sfp = AddProteinFeatureFromDefline (psep, title);
1060 if (sfp != NULL && sfp->data.choice == SEQFEAT_PROT) {
1061 prp = sfp->data.value.ptrvalue;
1062 CheckSeqLocForPartial (slp, &partial5, &partial3);
1063 SetSeqLocPartial (sfp->location, partial5, partial3);
1064 sfp->partial = partial5 | partial3;
1065 }
1066
1067 if (prp != NULL && best != NULL)
1068 {
1069 if (prp->name != NULL && !StringHasNoText (prp->name->data.ptrvalue))
1070 {
1071 StringNCpy_0 (best, prp->name->data.ptrvalue, maxsize);
1072 }
1073 else if (!StringHasNoText (prp->desc))
1074 {
1075 StringNCpy_0 (best, prp->desc, maxsize);
1076 }
1077 }
1078
1079 AddCodingRegionFieldsFromProteinTitle (crp, title, ttl);
1080 }
1081 }
1082 }
1083 }
1084
1085 static Boolean intBoxUp;
1086 static Boolean intBoxRsult;
1087
1088 static void AcceptAskProc (ButtoN b)
1089
1090 {
1091 intBoxRsult = TRUE;
1092 intBoxUp = FALSE;
1093 }
1094
1095 static void CancelAskProc (ButtoN b)
1096
1097 {
1098 intBoxRsult = FALSE;
1099 intBoxUp = FALSE;
1100 }
1101
1102 static SeqLocPtr AskForInterval (SeqEntryPtr sep, BioseqPtr nuc, BioseqPtr prot)
1103
1104 {
1105 GrouP c;
1106 DialoG d;
1107 GrouP g;
1108 GrouP m;
1109 SeqIdPtr sip;
1110 SeqLocPtr slp;
1111 Char str [128];
1112 ValNodePtr vnp;
1113 WindoW w;
1114
1115 slp = NULL;
1116 if (sep == NULL || nuc == NULL || prot == NULL) return NULL;
1117
1118 if (GetAppParam ("SEQUIN", "PREFERENCES", "ASKIFSUGGESTFAILED", NULL, str, sizeof (str))) {
1119 if (StringICmp (str, "FALSE") == 0) {
1120 sip = SeqIdFindWorst (prot->id);
1121 SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
1122 Message (MSG_POSTERR, "Suggest failure for %s", str);
1123 return NULL;
1124 }
1125 }
1126
1127 w = MovableModalWindow (-50, -33, -10, -10, "Enter coding region interval", NULL);
1128 g = HiddenGroup (w, -1, 0, NULL);
1129 m = NULL;
1130 SetGroupSpacing (g, 3, 10);
1131 if (prot->descr != NULL) {
1132 vnp = ValNodeFindNext (prot->descr, NULL, Seq_descr_title);
1133 if (vnp != NULL && vnp->data.ptrvalue != NULL) {
1134 m = MultiLinePrompt (g, (CharPtr) vnp->data.ptrvalue, stdCharWidth * 28, programFont);
1135 }
1136 }
1137 d = CreateIntervalEditorDialog (g, NULL, 4, 2, sep, TRUE, FALSE);
1138 c = HiddenGroup (g, 2, 0, NULL);
1139 SetGroupSpacing (c, 10, 2);
1140 DefaultButton (c, "Accept", AcceptAskProc);
1141 PushButton (c, "Cancel", CancelAskProc);
1142 AlignObjects (ALIGN_CENTER, (HANDLE) d, (HANDLE) c, (HANDLE) m, NULL);
1143 Show (w);
1144 Select (w);
1145 intBoxUp = TRUE;
1146 intBoxRsult = FALSE;
1147 while (intBoxUp) {
1148 ProcessEventOrIdle ();
1149 }
1150 ProcessAnEvent ();
1151 if (intBoxRsult) {
1152 slp = (SeqLocPtr) DialogToPointer (d);
1153 }
1154 Remove (w);
1155 return slp;
1156 }
1157
1158 extern Boolean AutomaticProteinProcess (SeqEntryPtr esep, SeqEntryPtr psep,
1159 Int2 code, Boolean makeMRNA, SeqLocPtr use_this)
1160
1161 {
1162 SeqFeatPtr cds;
1163 CdRegionPtr crp;
1164 Char mRnaName [128];
1165 BioseqPtr nbsp;
1166 SeqEntryPtr nsep;
1167 BioseqPtr pbsp;
1168 SeqFeatPtr rna;
1169 RnaRefPtr rrp;
1170 SeqLocPtr slp;
1171 CharPtr ttl;
1172 ValNodePtr vnp;
1173 CharPtr vnpstr;
1174 Boolean partial5, partial3;
1175
1176 if (esep == NULL || psep == NULL) return FALSE;
1177
1178 nsep = FindNucSeqEntry (esep);
1179 if (nsep == NULL || (! IS_Bioseq (nsep)) || (! IS_Bioseq (psep))) return FALSE;
1180
1181 nbsp = (BioseqPtr) nsep->data.ptrvalue;
1182 pbsp = (BioseqPtr) psep->data.ptrvalue;
1183 if (nbsp == NULL || pbsp == NULL) return FALSE;
1184
1185 cds = NULL;
1186 WatchCursor ();
1187 Update ();
1188 if (use_this == NULL) {
1189 slp = PredictCodingRegion (nbsp, pbsp, code);
1190 if (slp == NULL) {
1191 ArrowCursor ();
1192 Update ();
1193 slp = AskForInterval (nsep, nbsp, pbsp);
1194 }
1195 } else {
1196 slp = use_this;
1197 }
1198 if (slp == NULL) return FALSE;
1199
1200 mRnaName [0] = '\0';
1201 ttl = NULL;
1202 crp = CreateNewCdRgn (0, FALSE, code);
1203 if (crp != NULL) {
1204 if (pbsp->descr != NULL) {
1205 vnp = ValNodeFindNext (pbsp->descr, NULL, Seq_descr_title);
1206 if (vnp != NULL && vnp->data.ptrvalue != NULL) {
1207 vnpstr = (CharPtr) vnp->data.ptrvalue;
1208 CreateGeneAndProtFeats (nsep, psep, slp, crp, vnpstr, mRnaName, sizeof (mRnaName), &ttl);
1209 TrimSpacesAroundString (vnpstr);
1210 if (StringHasNoText (vnpstr)) {
1211 ValNodeExtract (&(pbsp->descr), Seq_descr_title);
1212 }
1213 }
1214 }
1215 if (makeMRNA) {
1216 rrp = RnaRefNew ();
1217 if (rrp != NULL) {
1218 rrp->type = 2;
1219 if (! StringHasNoText (mRnaName)) {
1220 rrp->ext.choice = 1;
1221 rrp->ext.value.ptrvalue = StringSave (mRnaName);
1222 }
1223 rna = CreateNewFeature (nsep, NULL, SEQFEAT_RNA, NULL);
1224 if (rna != NULL) {
1225 rna->data.value.ptrvalue = (Pointer) rrp;
1226 rna->location = SeqLocFree (rna->location);
1227 rna->location = AsnIoMemCopy ((Pointer) slp,
1228 (AsnReadFunc) SeqLocAsnRead,
1229 (AsnWriteFunc) SeqLocAsnWrite);
1230 }
1231 }
1232 }
1233 cds = CreateNewFeature (nsep, NULL, SEQFEAT_CDREGION, NULL);
1234 if (cds != NULL) {
1235 cds->data.value.ptrvalue = (Pointer) crp;
1236 cds->location = SeqLocFree (cds->location);
1237 cds->location = slp;
1238 slp = NULL;
1239 CheckSeqLocForPartial (cds->location, &partial5, &partial3);
1240 cds->partial |= partial5 | partial3;
1241 SetSeqFeatProduct (cds, pbsp);
1242 if (! StringHasNoText (ttl)) {
1243 cds->comment = ttl;
1244 }
1245 }
1246 }
1247
1248 SeqLocFree (slp);
1249 return TRUE;
1250 }
1251
1252 typedef struct fa2htgsform {
1253 FORM_MESSAGE_BLOCK
1254
1255 SeqSubmitPtr ssp;
1256 SeqEntryPtr sep;
1257
1258 GrouP templateblock;
1259 GrouP fastablock;
1260 GrouP orderblock;
1261 GrouP controlblock;
1262 GrouP contigtype;
1263
1264 DialoG contigorder;
1265 EnumFieldAssocPtr alists [1];
1266 GrouP htgsphase;
1267 ButtoN draft;
1268 ButtoN fulltop;
1269 ButtoN activefin;
1270 TexT orgname;
1271 TexT seqname;
1272 ButtoN update;
1273 TexT accession;
1274 TexT knownlength;
1275 TexT gaplength;
1276 TexT remark;
1277 TexT clone;
1278 TexT strain;
1279 TexT cultivar;
1280 TexT chromosome;
1281 TexT title;
1282 DialoG secondaries;
1283
1284 SeqEntryPtr seplist;
1285
1286 ButtoN okBtn;
1287 BtnActnProc finish;
1288 BtnActnProc cancel;
1289 Boolean readPhrap;
1290 Boolean buildContig;
1291
1292 } Fa2htgsForm, PNTR Fa2htgsFormPtr;
1293
1294 /*------------- MakeAc2GBSeqId() -----------------------*/
1295 /***************************************************************
1296 * MakeAc2GBSeqId:
1297 * -- return NULL if acnum == null
1298 * Hsiu-Chuan 4-18-97
1299 ****************************************************************/
1300 static SeqIdPtr SqnMakeAc2GBSeqId(CharPtr accession)
1301 {
1302 TextSeqIdPtr tsip;
1303 SeqIdPtr sip;
1304
1305 if (accession == NULL || *accession == '\0')
1306 return NULL;
1307
1308 sip = ValNodeNew(NULL);
1309 sip->choice = SEQID_GENBANK;
1310 tsip = TextSeqIdNew();
1311 sip->data.ptrvalue = tsip;
1312 tsip->accession = StringSave(accession);
1313
1314 return sip;
1315
1316 } /* MakeAc2GBSeqId */
1317
1318 /*----------- AddExtraAc2Entry() ----------------------------*/
1319 /***************************************************************
1320 * AddExtraAc2Entry:
1321 * Hsiu-Chuan 4-11-97, modified by JK
1322 ****************************************************************/
1323 static void SqnAddDraft2Entry (SeqEntryPtr entry, CharPtr keyword)
1324
1325 {
1326 BioseqPtr bsp;
1327 ValNodePtr vnp;
1328 GBBlockPtr gbp;
1329
1330 if (entry == NULL) return;
1331
1332 bsp = (BioseqPtr)(entry->data.ptrvalue);
1333
1334 for (gbp= NULL, vnp = bsp->descr; vnp != NULL; vnp = vnp->next)
1335 {
1336 if (vnp->choice == Seq_descr_genbank)
1337 {
1338 gbp = vnp->data.ptrvalue;
1339 break;
1340 }
1341 }
1342
1343 if (gbp == NULL)
1344 {
1345 vnp = (ValNodePtr) NewDescrOnSeqEntry (entry, Seq_descr_genbank);
1346 gbp = GBBlockNew();
1347 vnp->data.ptrvalue = (Pointer)gbp;
1348 }
1349
1350 if (gbp != NULL) {
1351 ValNodeCopyStr (&gbp->keywords, 0, keyword);
1352 }
1353 }
1354
1355 static Boolean SqnAddExtraAc2Entry (SeqEntryPtr entry , ValNodePtr extra_accs )
1356 {
1357 BioseqPtr bsp;
1358 ValNodePtr vnp;
1359 GBBlockPtr gbp;
1360 Char acnum[17];
1361 CharPtr p;
1362 Int4 i, j;
1363 SeqHistPtr shp;
1364 SeqIdPtr sip;
1365 ValNodePtr tmp;
1366
1367 if ((entry == NULL) || (extra_accs == NULL))
1368 return FALSE;
1369
1370 bsp = (BioseqPtr)(entry->data.ptrvalue);
1371
1372 for (gbp= NULL, vnp = bsp->descr; vnp != NULL; vnp = vnp->next)
1373 {
1374 if (vnp->choice == Seq_descr_genbank)
1375 {
1376 gbp = vnp->data.ptrvalue;
1377 break;
1378 }
1379 }
1380
1381 shp = bsp->hist;
1382
1383 if (gbp == NULL)
1384 {
1385 vnp = (ValNodePtr) NewDescrOnSeqEntry (entry, Seq_descr_genbank);
1386 gbp = GBBlockNew();
1387 vnp->data.ptrvalue = (Pointer)gbp;
1388 }
1389
1390 for (tmp = extra_accs; tmp != NULL; tmp = tmp->next)
1391 {
1392 p = (CharPtr) tmp->data.ptrvalue;
1393 if (p == NULL) continue;
1394 for (i = 0; isalnum((Int4)(*p)) && *p != '\0'; ++p, ++i)
1395 acnum[i] = *p;
1396 acnum[i] = '\0';
1397 /* check one_letter+5digits or two_letter+6digits */
1398 if (i == 6 || i == 8)
1399 {
1400 if (!isalpha((Int4)(acnum[0])) || (!(isdigit((Int4)(acnum[1])) && i == 6) &&
1401 !(isalpha((Int4)(acnum[1])) && i == 8)))
1402 {
1403 ErrPostEx(SEV_ERROR,0,0,
1404 "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
1405 acnum);
1406 return FALSE;
1407 }
1408
1409 for (j = 2; j < i; ++j)
1410 {
1411 if (!(isdigit((Int4)(acnum[j]))))
1412 {
1413 ErrPostEx(SEV_ERROR,0,0,
1414 "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
1415 acnum);
1416 return FALSE;
1417 }
1418 }
1419
1420 ValNodeCopyStr(&gbp->extra_accessions, 0, acnum);
1421 sip = SqnMakeAc2GBSeqId (acnum);
1422 if (shp == NULL)
1423 {
1424 shp = SeqHistNew();
1425 bsp->hist = shp;
1426 }
1427 ValNodeLink(&shp->replace_ids, sip);
1428 }
1429 else
1430 {
1431 ErrPostEx(SEV_ERROR,0,0,
1432 "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
1433 acnum);
1434 return FALSE;
1435 }
1436
1437 while (!isalnum((Int4)(*p)) && *p != '\0')
1438 ++p;
1439 }
1440
1441 return TRUE;
1442
1443 } /* AddExtraAc2Entry */
1444
1445 static void RescueSeqGraphs (BioseqPtr bsp, Int2 index, ValNodePtr PNTR vnpp)
1446
1447 {
1448 SeqAnnotPtr nextsap;
1449 SeqGraphPtr nextsgp;
1450 Pointer PNTR prevsap;
1451 Pointer PNTR prevsgp;
1452 SeqAnnotPtr sap;
1453 SeqGraphPtr sgp;
1454
1455 if (bsp == NULL || vnpp == NULL) return;
1456 sap = bsp->annot;
1457 prevsap = (Pointer PNTR) &(bsp->annot);
1458 while (sap != NULL) {
1459 nextsap = sap->next;
1460 if (sap->type == 3) {
1461 sgp = (SeqGraphPtr) sap->data;
1462 prevsgp = (Pointer PNTR) &(sap->data);
1463 while (sgp != NULL) {
1464 nextsgp = sgp->next;
1465 *(prevsgp) = sgp->next;
1466 sgp->next = NULL;
1467 ValNodeAddPointer (vnpp, index, (Pointer) sgp);
1468 sgp = nextsgp;
1469 }
1470 }
1471 if (sap->data == NULL) {
1472 *(prevsap) = sap->next;
1473 sap->next = NULL;
1474 SeqAnnotFree (sap);
1475 } else {
1476 prevsap = (Pointer PNTR) &(sap->next);
1477 }
1478 sap = nextsap;
1479 }
1480 }
1481
1482 static SeqAnnotPtr NewSeqAnnotType3 (CharPtr name, SeqGraphPtr sgp)
1483
1484 {
1485 SeqAnnotPtr sap = NULL;
1486
1487 if (sgp == NULL) return NULL;
1488 sap = SeqAnnotNew ();
1489 if (sap == NULL) return NULL;
1490
1491 if (! StringHasNoText (name)) {
1492 SeqDescrAddPointer (&(sap->desc), Annot_descr_name, StringSave (name));
1493 }
1494 sap->type = 3;
1495 sap->data = (Pointer) sgp;
1496
1497 return sap;
1498 }
1499
1500 static void OffsetAndLinkSeqGraph (BioseqPtr bsp, SeqGraphPtr sgp, Int2 index)
1501
1502 {
1503 DeltaSeqPtr dsp;
1504 SeqGraphPtr lastsgp;
1505 Int4 len;
1506 SeqLitPtr litp;
1507 SeqAnnotPtr sap;
1508 SeqIntPtr sintp;
1509 SeqLocPtr slp;
1510
1511 if (bsp == NULL || sgp == NULL || index < 1) return;
1512 len = 0;
1513 if (bsp->repr == Seq_repr_delta && bsp->seq_ext_type == 4) {
1514 for (dsp = (DeltaSeqPtr) (bsp->seq_ext);
1515 dsp != NULL && index > 1; dsp = dsp->next, index--) {
1516 if (dsp->choice == 1) {
1517 len += SeqLocLen ((SeqLocPtr) dsp->data.ptrvalue);
1518 } else if (dsp->choice == 2) {
1519 litp = (SeqLitPtr) dsp->data.ptrvalue;
1520 if (litp != NULL) {
1521 len += litp->length;
1522 }
1523 }
1524 }
1525 }
1526 slp = sgp->loc;
1527 if (slp != NULL && slp->choice == SEQLOC_INT) {
1528 sintp = (SeqIntPtr) slp->data.ptrvalue;
1529 if (sintp != NULL) {
1530 sintp->from += len;
1531 sintp->to += len;
1532 sintp->id = SeqIdFree (sintp->id);
1533 sintp->id = SeqIdDup (bsp->id);
1534 }
1535 }
1536 for (sap = bsp->annot; sap != NULL; sap = sap->next) {
1537 if (sap->type == 3) {
1538 for (lastsgp = sap->data; lastsgp->next != NULL; lastsgp = lastsgp->next) {
1539 continue;
1540 }
1541 lastsgp->next = sgp;
1542 break;
1543 }
1544 }
1545 if (sap == NULL) {
1546 if (bsp->annot != NULL) {
1547 for (sap = bsp->annot; sap->next != NULL; sap = sap->next) {
1548 continue;
1549 }
1550 sap->next = NewSeqAnnotType3 ("Graphs", sgp);
1551 } else {
1552 bsp->annot = NewSeqAnnotType3 ("Graphs", sgp);
1553 }
1554 }
1555 }
1556
1557 static CharPtr phrapBoilerPlate = "Sequence Quality Assessment:~ \
1558 This entry has been annotated with sequence quality~ \
1559 estimates computed by the Phrap assembly program.~ \
1560 All manually edited bases have been reduced to quality zero.~ \
1561 Quality levels above 40 are expected to have less than ~ \
1562 1 error in 10,000 bp.~ \
1563 Base-by-base quality values are not generally visible from the~ \
1564 GenBank flat file format but are available as part~ \
1565 of this entry's ASN.1 file.~----------------------~";
1566
1567 static void ProcessFa2htgs (Fa2htgsFormPtr ffp, SeqSubmitPtr ssp)
1568
1569 {
1570 SeqEntryPtr sep, oldsep, the_entry, nextsep;
1571 NCBISubPtr nsp;
1572 Int2 htgs_phase = -1;
1573 Uint1 tech;
1574 CharPtr seqname = NULL, accession = NULL, orgname = NULL;
1575 CharPtr clone = NULL, strain = NULL, cultivar = NULL, chromosome = NULL;
1576 CharPtr remark = NULL, title = NULL, seqbuf = NULL;
1577 Int4 length = 0, cumlength = 0, gaplen;
1578 BioseqPtr bsp;
1579 BioseqSetPtr bssp;
1580 SeqLitPtr slp;
1581 ValNodePtr vnp, PNTR prevpnt, next, extra_accs;
1582 Boolean lastwasraw, draft, fulltop, activefin, usedelta = FALSE;
1583 Char str [64];
1584 long int val;
1585 Int2 index = 0;
1586 ValNodePtr rescuedsgps = NULL;
1587 ValNodePtr seqlitlist = NULL;
1588 IntFuzzPtr ifp;
1589 ObjectIdPtr oip;
1590 UserFieldPtr ufp;
1591 UserObjectPtr uop;
1592 DatePtr dp;
1593
1594 if (ffp == NULL || ssp == NULL) return;
1595
1596 htgs_phase = GetValue (ffp->htgsphase) - 1;
1597 orgname = SaveStringFromText (ffp->orgname);
1598 seqname = SaveStringFromText (ffp->seqname);
1599 if (GetStatus (ffp->update)) {
1600 accession = SaveStringFromText (ffp->accession);
1601 }
1602 clone = SaveStringFromText (ffp->clone);
1603 strain = SaveStringFromText (ffp->strain);
1604 cultivar = SaveStringFromText (ffp->cultivar);
1605 chromosome = SaveStringFromText (ffp->chromosome);
1606 remark = SaveStringFromText (ffp->remark);
1607 title = SaveStringFromText (ffp->title);
1608 extra_accs = DialogToPointer (ffp->secondaries);
1609 draft = GetStatus (ffp->draft);
1610 fulltop = GetStatus (ffp->fulltop);
1611 activefin = GetStatus (ffp->activefin);
1612
1613 length = 0;
1614 /* may need to really calculate length */
1615 GetTitle (ffp->knownlength, str, sizeof (str));
1616 if (! StringHasNoText (str)) {
1617 if (sscanf (str, "%ld", &val) == 1 && val > 0) {
1618 length = (Int4) val;
1619 }
1620 }
1621
1622 gaplen = 0;
1623 /* now usually filling in with gaps of 100 bases */
1624 GetTitle (ffp->gaplength, str, sizeof (str));
1625 if (! StringHasNoText (str)) {
1626 if (sscanf (str, "%ld", &val) == 1 && val > 0) {
1627 gaplen = (Int4) val;
1628 }
1629 }
1630
1631 /* modified from fa2htgs */
1632 oldsep = (SeqEntryPtr)(ssp->data); /* clear out template */
1633 ssp->data = NULL;
1634 MemFree(ssp->sub->tool);
1635 sprintf (str, "Sequin %s", SEQUIN_APPLICATION);
1636 ssp->sub->tool = StringSave (str);
1637 nsp = MemNew(sizeof(NCBISub));
1638 nsp->ssp = ssp;
1639 nsp->submittor_key = StringSave (genomeCenter);
1640 /*
1641 MemFree(ssp->sub->cit->descr);
1642 ssp->sub->cit->descr = remark;
1643 */
1644
1645 cumlength = 0;
1646 index = 0;
1647
1648 sep = ffp->seplist;
1649 if (sep != NULL && sep->next != NULL) {
1650 usedelta = TRUE;
1651 }
1652
1653 if (ffp->buildContig) {
1654 ssp->data = (Pointer) ffp->seplist;
1655 the_entry = ffp->seplist;
1656 sep = the_entry;
1657
1658 oip = ObjectIdNew ();
1659 oip->str = StringSave ("info");
1660 uop = UserObjectNew ();
1661 uop->type = oip;
1662 uop->_class = StringSave ("Genomes");
1663
1664 oip = ObjectIdNew ();
1665 oip->id = 0;
1666 ufp = UserFieldNew ();
1667 ufp->choice = 2;
1668 ufp->data.intvalue = 0;
1669 ufp->label = oip;
1670
1671 uop->data = ufp;
1672
1673 if (IS_Bioseq (sep)) {
1674 bsp = (BioseqPtr) sep->data.ptrvalue;
1675 vnp = SeqDescrNew (NULL);
1676 vnp->choice = Seq_descr_user;
1677 vnp->data.ptrvalue = (Pointer) uop;
1678 vnp->next = bsp->descr;
1679 bsp->descr = vnp;
1680 cumlength = bsp->length;
1681 }
1682
1683 }
1684 else if (htgs_phase < 3 || usedelta)
1685 {
1686 the_entry = AddDeltaSeqOnlyToSubmission (
1687 nsp,
1688 seqname,
1689 NULL,
1690 accession,
1691 0,
1692 MOLECULE_CLASS_DNA,
1693 MOLECULE_TYPE_GENOMIC,
1694 length,
1695 TOPOLOGY_LINEAR,
1696 STRANDEDNESS_DOUBLE);
1697
1698 sep = ffp->seplist;
1699 lastwasraw = FALSE;
1700 while (sep != NULL)
1701 {
1702 nextsep = sep->next;
1703 sep->next = NULL;
1704 bsp = (BioseqPtr)(sep->data.ptrvalue);
1705 if (bsp->repr == Seq_repr_raw)
1706 {
1707 if (lastwasraw) {
1708 slp = AddFakeGapToDeltaSeq(nsp, the_entry, gaplen);
1709 ValNodeAddPointer (&seqlitlist, 0, (Pointer) slp);
1710 index++;
1711 cumlength += gaplen;
1712 }
1713 BioseqRawConvert(bsp, Seq_code_iupacna);
1714 seqbuf = BSMerge((ByteStorePtr)(bsp->seq_data), NULL);
1715 slp = AddLiteralToDeltaSeq(nsp, the_entry,
1716 bsp->length);
1717 AddBasesToLiteral(nsp, slp, seqbuf);
1718 MemFree(seqbuf);
1719 lastwasraw = TRUE;
1720 index++;
1721 }
1722 else
1723 {
1724 if (bsp->length < 0)
1725 bsp->length = 0; /* -1 may be set */
1726 AddGapToDeltaSeq(nsp, the_entry,
1727 bsp->length);
1728 lastwasraw = FALSE;
1729 index++;
1730 }
1731 cumlength += bsp->length;
1732 RescueSeqGraphs (bsp, index, &rescuedsgps);
1733 SeqEntryFree(sep);
1734 sep = nextsep;
1735 }
1736 }
1737 else
1738 {
1739 the_entry = AddSeqOnlyToSubmission (
1740 nsp,
1741 seqname,
1742 NULL,
1743 accession,
1744 0,
1745 MOLECULE_CLASS_DNA,
1746 MOLECULE_TYPE_GENOMIC,
1747 length,
1748 TOPOLOGY_LINEAR,
1749 STRANDEDNESS_DOUBLE);
1750
1751 sep = ffp->seplist;
1752 nextsep = sep->next;
1753 sep->next = NULL;
1754 bsp = (BioseqPtr)(sep->data.ptrvalue);
1755 if (bsp->repr == Seq_repr_raw)
1756 {
1757 BioseqRawConvert(bsp, Seq_code_iupacna);
1758 seqbuf = BSMerge((ByteStorePtr)(bsp->seq_data), NULL);
1759 AddBasesToBioseq(nsp, the_entry, seqbuf);
1760 MemFree(seqbuf);
1761 index++;
1762 }
1763 cumlength += bsp->length;
1764 RescueSeqGraphs (bsp, index, &rescuedsgps);
1765 SeqEntryFree(sep);
1766 if (nextsep != NULL) {
1767 ErrPostEx (SEV_ERROR ,0, 0, "Only the first contig was used for HTGS 3");
1768 }
1769 if (length > 0 && length != cumlength) {
1770 ErrPostEx (SEV_ERROR ,0, 0, "Length is exactly %ld, not %ld",
1771 (long) cumlength, (long) length);
1772 length = cumlength;
1773 }
1774 }
1775
1776 /* get data from template: pub, organism, and comment */
1777 if (IS_Bioseq(oldsep))
1778 {
1779 bsp = (BioseqPtr)(oldsep->data.ptrvalue);
1780 prevpnt = &(bsp->descr);
1781 }
1782 else
1783 {
1784 bssp = (BioseqSetPtr)(oldsep->data.ptrvalue);
1785 prevpnt = &(bssp->descr);
1786 }
1787
1788 bsp = (BioseqPtr)(the_entry->data.ptrvalue);
1789 if (bsp != NULL) {
1790 bsp->length = MAX (cumlength, length);
1791 }
1792
1793 for (vnp = *prevpnt; vnp != NULL; vnp = next)
1794 {
1795 next = vnp->next;
1796 if (vnp->choice == Seq_descr_pub)
1797 {
1798 *prevpnt = next;
1799 vnp->next = NULL;
1800 ValNodeLink(&(bsp->descr), vnp);
1801 }
1802 else
1803 prevpnt = &(vnp->next);
1804 }
1805 if (remark != NULL) {
1806 vnp = SeqDescrNew (NULL);
1807 if (vnp != NULL) {
1808 vnp->choice = Seq_descr_comment;
1809 vnp->data.ptrvalue = remark;
1810 ValNodeLink(&(bsp->descr), vnp);
1811 }
1812 }
1813
1814 SeqEntryFree(oldsep);
1815
1816 AddOrganismToEntryNew(nsp, the_entry, orgname, NULL, NULL, NULL,
1817 NULL, NULL, NULL, NULL);
1818
1819 AddGenomeToEntry(nsp, the_entry, 1);
1820 if (clone != NULL)
1821 AddSubSourceToEntry(nsp, the_entry, 3, clone);
1822 if (chromosome != NULL)
1823 AddSubSourceToEntry(nsp, the_entry, 1, chromosome);
1824 if (strain != NULL)
1825 AddOrgModToEntry(nsp, the_entry, 2, strain);
1826 if (cultivar != NULL)
1827 AddOrgModToEntry(nsp, the_entry, ORGMOD_cultivar, cultivar);
1828 if (title != NULL)
1829 AddTitleToEntry(nsp, the_entry, title);
1830 if (ffp->readPhrap) {
1831 AddCommentToEntry(nsp, the_entry, phrapBoilerPlate);
1832 }
1833
1834 if (extra_accs != NULL) {
1835 SqnAddExtraAc2Entry(the_entry, extra_accs);
1836 }
1837
1838 if (draft) {
1839 SqnAddDraft2Entry(the_entry, "HTGS_DRAFT");
1840 }
1841 if (fulltop) {
1842 SqnAddDraft2Entry(the_entry, "HTGS_FULLTOP");
1843 }
1844 if (activefin) {
1845 SqnAddDraft2Entry(the_entry, "HTGS_ACTIVEFIN");
1846 }
1847
1848 AddBiomolToEntry(nsp, the_entry, 1);
1849 if (ffp->buildContig) {
1850 } else {
1851 switch (htgs_phase) {
1852 case 0 :
1853 tech = MI_TECH_htgs_0;
1854 break;
1855 case 1 :
1856 tech = MI_TECH_htgs_1;
1857 break;
1858 case 2 :
1859 tech = MI_TECH_htgs_2;
1860 break;
1861 case 3 :
1862 tech = MI_TECH_htgs_3;
1863 break;
1864 default :
1865 tech = MI_TECH_htgs_3;
1866 break;
1867 }
1868 AddTechToEntry(nsp, the_entry, tech);
1869 }
1870 vnp = NewDescrOnSeqEntry (the_entry, Seq_descr_create_date);
1871 if (vnp != NULL) {
1872 dp = DateCurr ();
1873 vnp->data.ptrvalue = (Pointer) dp;
1874 }
1875
1876 if (bsp != NULL) {
1877 for (vnp = rescuedsgps; vnp != NULL; vnp = vnp->next) {
1878 OffsetAndLinkSeqGraph (bsp, (SeqGraphPtr) vnp->data.ptrvalue, (Int2) vnp->choice);
1879 vnp->data.ptrvalue = NULL;
1880 }
1881 }
1882 rescuedsgps = ValNodeFreeData (rescuedsgps);
1883
1884 for (vnp = seqlitlist; vnp != NULL; vnp = vnp->next) {
1885 slp = (SeqLitPtr) vnp->data.ptrvalue;
1886 if (slp != NULL) {
1887 ifp = IntFuzzNew();
1888 ifp->choice = 4; /* lim - unk*/
1889 slp->fuzz = ifp;
1890 }
1891 }
1892 seqlitlist = ValNodeFree (seqlitlist);
1893
1894 MemFree (nsp);
1895
1896 }
1897
1898 static Pointer Fa2htgsToSeqSubmitPtr (ForM f)
1899
1900 {
1901 Fa2htgsFormPtr ffp;
1902 SeqSubmitPtr ssp;
1903
1904 ffp = (Fa2htgsFormPtr) GetObjectExtra (f);
1905 if (ffp == NULL) return NULL;
1906 ProcessFa2htgs (ffp, ffp->ssp);
1907 ssp = ffp->ssp;
1908 ffp->ssp = NULL;
1909 ffp->sep = NULL;
1910 ffp->seplist = NULL;
1911 return (Pointer) ssp;
1912 }
1913
1914 static void Fa2htgsFormMessage (ForM f, Int2 mssg)
1915
1916 {
1917 Fa2htgsFormPtr ffp;
1918
1919 ffp = (Fa2htgsFormPtr) GetObjectExtra (f);
1920 if (ffp) {
1921 switch (mssg) {
1922 case VIB_MSG_CUT :
1923 StdCutTextProc (NULL);
1924 break;
1925 case VIB_MSG_COPY :
1926 StdCopyTextProc (NULL);
1927 break;
1928 case VIB_MSG_PASTE :
1929 StdPasteTextProc (NULL);
1930 break;
1931 case VIB_MSG_DELETE :
1932 StdDeleteTextProc (NULL);
1933 break;
1934 default :
1935 if (ffp->appmessage != NULL) {
1936 ffp->appmessage (f, mssg);
1937 }
1938 break;
1939 }
1940 }
1941 }
1942
1943 #ifndef WIN_MAC
1944 static void CreateFa2htgsFormMenus (WindoW w)
1945
1946 {
1947 BaseFormPtr bfp;
1948 MenU m;
1949
1950 bfp = (BaseFormPtr) GetObjectExtra (w);
1951 if (bfp != NULL) {
1952 m = PulldownMenu (w, "File");
1953 AddAboutAndHelpMenuItems (m);
1954 FormCommandItem (m, "Quit", bfp, VIB_MSG_QUIT);
1955 m = PulldownMenu (w, "Edit");
1956 FormCommandItem (m, CUT_MENU_ITEM, bfp, VIB_MSG_CUT);
1957 FormCommandItem (m, COPY_MENU_ITEM, bfp, VIB_MSG_COPY);
1958 FormCommandItem (m, PASTE_MENU_ITEM, bfp, VIB_MSG_PASTE);
1959 FormCommandItem (m, CLEAR_MENU_ITEM, bfp, VIB_MSG_DELETE);
1960 }
1961 }
1962 #endif
1963
1964 static void FillInFa2htgsFields (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
1965
1966 {
1967 BioseqPtr bsp;
1968 BioseqSetPtr bssp;
1969 Fa2htgsFormPtr ffp;
1970 ValNodePtr sdp = NULL;
1971
1972 if (sep == NULL || sep->data.ptrvalue == NULL) return;
1973 ffp = (Fa2htgsFormPtr) mydata;
1974 if (ffp == NULL) return;
1975 if (IS_Bioseq (sep)) {
1976 bsp = (BioseqPtr) sep->data.ptrvalue;
1977 sdp = bsp->descr;
1978 } else if (IS_Bioseq_set (sep)) {
1979 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1980 sdp = bssp->descr;
1981 } else return;
1982 while (sdp != NULL) {
1983 if (sdp->choice == Seq_descr_comment) {
1984 SetTitle (ffp->remark, (CharPtr) sdp->data.ptrvalue);
1985 }
1986 sdp = sdp->next;
1987 }
1988 }
1989
1990 static void ReadTemplate (ButtoN b)
1991
1992 {
1993 AsnIoPtr aip;
1994 Fa2htgsFormPtr ffp;
1995 Char path [PATH_MAX];
1996 SeqEntryPtr sep;
1997 SeqSubmitPtr ssp;
1998 Char str [128];
1999
2000 ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2001 if (ffp == NULL) return;
2002 if (GetInputFileName (path, sizeof (path), "", "TEXT")) {
2003 ffp->ssp = SeqSubmitFree (ffp->ssp);
2004 aip = AsnIoOpen (path, "r");
2005 if (aip != NULL) {
2006 ffp->ssp = SeqSubmitAsnRead (aip, NULL);
2007 }
2008 AsnIoClose (aip);
2009 }
2010 if (ffp->ssp != NULL) {
2011 SafeShow (ffp->fastablock);
2012 SafeDisable (b);
2013 ssp = ffp->ssp;
2014 if (ssp->datatype == 1) {
2015 sep = (SeqEntryPtr) ssp->data;
2016 if (sep != NULL) {
2017 SeqEntryToGeneticCode (sep, NULL, str, sizeof (str));
2018 SetTitle (ffp->orgname, str);
2019 SeqEntryExplore (sep, (Pointer) ffp, FillInFa2htgsFields);
2020 }
2021 }
2022 }
2023 }
2024
2025 static Boolean Fa2htgsFormOkay (Fa2htgsFormPtr ffp)
2026
2027 {
2028 if (ffp == NULL) return FALSE;
2029 if (ffp->ssp == NULL) return FALSE;
2030 if (ffp->seplist == NULL) return FALSE;
2031 if (GetValue (ffp->htgsphase) == 0 && (! ffp->buildContig)) return FALSE;
2032 if (TextHasNoText (ffp->orgname)) return FALSE;
2033 if (TextHasNoText (ffp->seqname)) return FALSE;
2034 return TRUE;
2035 }
2036
2037 static void ReadFastaHtgsFile (ButtoN b)
2038
2039 {
2040 Fa2htgsFormPtr ffp;
2041 FILE *fp;
2042 SeqEntryPtr head;
2043 Char path [PATH_MAX];
2044 SeqEntryPtr sep;
2045 CharPtr ttl;
2046
2047 ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2048 if (ffp == NULL) return;
2049 if (! GetInputFileName (path, sizeof (path), "", "TEXT")) return;
2050 if (! StringHasNoText (path)) {
2051 fp = FileOpen (path, "r");
2052 if (fp != NULL) {
2053 head = NULL;
2054 sep = FastaToSeqEntry (fp, TRUE);
2055 while (sep != NULL) {
2056 ValNodeLink (&head, sep);
2057 sep = FastaToSeqEntry (fp, TRUE);
2058 }
2059 if (head != NULL) {
2060 ttl = SeqEntryGetTitle (head);
2061 SetTitle (ffp->title, ttl);
2062 }
2063 ffp->seplist = head;
2064 }
2065 FileClose (fp);
2066 if (ffp->seplist != NULL) {
2067 SafeShow (ffp->controlblock);
2068 SafeDisable (b);
2069 if (TextHasNoText (ffp->orgname)) {
2070 Select (ffp->orgname);
2071 } else {
2072 Select (ffp->seqname);
2073 }
2074 if (Fa2htgsFormOkay (ffp)) {
2075 SafeEnable (ffp->okBtn);
2076 } else {
2077 SafeDisable (ffp->okBtn);
2078 }
2079 }
2080 }
2081 }
2082
2083 static EnumFieldAssocPtr MakePhrapAlists (SeqEntryPtr head)
2084
2085 {
2086 EnumFieldAssocPtr alist = NULL;
2087 BioseqPtr bsp;
2088 Int2 count;
2089 Int2 j;
2090 SeqEntryPtr sep;
2091 SeqIdPtr sip;
2092 Char str [128];
2093
2094 if (head == NULL) return NULL;
2095 count = ValNodeLen (head);
2096 alist = MemNew (sizeof (EnumFieldAssoc) * (size_t) (count + 4));
2097 if (alist == NULL) return NULL;
2098
2099 j = 0;
2100 alist [j].name = StringSave (" ");
2101 alist [j].value = (UIEnum) 0;
2102 for (j = 1, sep = head; j <= count && sep != NULL; j++, sep = sep->next) {
2103 if (sep != NULL && sep->choice == 1 && sep->data.ptrvalue != NULL) {
2104 bsp = (BioseqPtr) sep->data.ptrvalue;
2105 sip = SeqIdFindWorst (bsp->id);
2106 SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
2107 str [30] = '\0';
2108 alist [j].name = StringSave (str);
2109 alist [j].value = (UIEnum) j;
2110 }
2111 }
2112 j = count + 1;
2113 alist [j].name = NULL;
2114 alist [j].value = (UIEnum) 0;
2115
2116
2117 return alist;
2118 }
2119
2120 static void ReadAPhrapFile (ButtoN b)
2121
2122 {
2123 PopuP control;
2124 Int2 count;
2125 Fa2htgsFormPtr ffp;
2126 FILE *fp;
2127 SeqEntryPtr head;
2128 Int2 i;
2129 Char path [PATH_MAX];
2130 RecT r;
2131 TagListPtr tlp;
2132
2133 ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2134 if (ffp == NULL) return;
2135 if (! GetInputFileName (path, sizeof (path), "", "TEXT")) return;
2136 if (! StringHasNoText (path)) {
2137 WatchCursor ();
2138 fp = FileOpen (path, "r");
2139 if (fp != NULL) {
2140 head = ReadPhrapFile (fp);
2141 ffp->seplist = head;
2142 }
2143 FileClose (fp);
2144 tlp = (TagListPtr) GetObjectExtra (ffp->contigorder);
2145 if (tlp != NULL) {
2146 ffp->alists [0] = MakePhrapAlists (ffp->seplist);
2147 tlp->alists = ffp->alists;
2148 for (i = 0; i < tlp->rows; i++) {
2149 control = (PopuP) tlp->control [i * MAX_TAGLIST_COLS + 0];
2150 if (control != NULL) {
2151 GetPosition (control, &r);
2152 Reset (control);
2153 InitEnumPopup (control, ffp->alists [0], NULL);
2154 SetEnumPopup (control, ffp->alists [0], 0);
2155 SetPosition (control, &r);
2156 }
2157 }
2158 count = ValNodeLen (ffp->seplist);
2159 for (i = 0; i < count; i++) {
2160 ValNodeCopyStr (&(tlp->vnp), 0, "0");
2161 }
2162 tlp->max = MAX ((Int2) 0, (Int2) (count - tlp->rows));
2163 CorrectBarMax (tlp->bar, tlp->max);
2164 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
2165 }
2166 SafeShow (ffp->orderblock);
2167 SafeDisable (b);
2168 ArrowCursor ();
2169 }
2170 }
2171
2172 static void PhrapOrderChosen (ButtoN b)
2173
2174 {
2175 SeqEntryPtr PNTR collision;
2176 Int2 count;
2177 Fa2htgsFormPtr ffp;
2178 Int2 i;
2179 Int2 j;
2180 SeqEntryPtr lastsep;
2181 SeqEntryPtr nextsep;
2182 Boolean okay;
2183 SeqEntryPtr PNTR order;
2184 SeqEntryPtr sep;
2185 CharPtr str;
2186 TagListPtr tlp;
2187 int val;
2188 ValNodePtr vnp;
2189 /*
2190 Char contigs [256];
2191 Char tmp [256];
2192 BioseqPtr bsp;
2193 SeqIdPtr sip;
2194 Boolean notfirst;
2195 */
2196
2197 ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2198 if (ffp == NULL) return;
2199 tlp = (TagListPtr) GetObjectExtra (ffp->contigorder);
2200 if (tlp == NULL) return;
2201 count = ValNodeLen (tlp->vnp);
2202 order = MemNew (sizeof (SeqEntryPtr) * (count + 1));
2203 if (order == NULL) return;
2204 collision = MemNew (sizeof (SeqEntryPtr) * (count + 1));
2205 if (collision == NULL) return;
2206
2207 okay = TRUE;
2208 for (i = 0, vnp = tlp->vnp; i < count && vnp != NULL; i++, vnp = vnp->next) {
2209 str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
2210 if (str != NULL && sscanf (str, "%d", &val) == 1 && val > 0) {
2211 val--;
2212 for (j = 0, sep = ffp->seplist; j < (Int2) val && sep != NULL; j++, sep = sep->next) continue;
2213 if (sep != NULL) {
2214 if (collision [j] != NULL) {
2215 okay = FALSE;
2216 }
2217 collision [j] = sep;
2218 order [i] = sep;
2219 }
2220 }
2221 MemFree (str);
2222 }
2223 if (! okay) {
2224 Message (MSG_ERROR, "You must not select a contig more than once");
2225 MemFree (order);
2226 MemFree (collision);
2227 return;
2228 }
2229
2230 okay = FALSE;
2231 for (i = 0; i < count; i++) {
2232 if (order [i] != NULL) {
2233 okay = TRUE;
2234 }
2235 }
2236 /* if no contigs selected, use all in order */
2237 if (! okay) {
2238 for (j = 0, sep = ffp->seplist; j < count && sep != NULL; j++, sep = sep->next) {
2239 order [j] = sep;
2240 }
2241 okay = TRUE;
2242 }
2243 /*
2244 if (! okay) {
2245 Message (MSG_ERROR, "You must select at least one contig");
2246 MemFree (order);
2247 MemFree (collision);
2248 return;
2249 }
2250 */
2251
2252 /* use spreadsheet to reorder ffp->seplist, delete unwanted items */
2253
2254 /*
2255 contigs [0] = '\0';
2256 notfirst = FALSE;
2257 for (i = 0; i < count; i++) {
2258 if (order [i] != NULL) {
2259 sep = order [i];
2260 bsp = (BioseqPtr) sep->data.ptrvalue;
2261 sip = SeqIdFindWorst (bsp->id);
2262 SeqIdWrite (sip, tmp, PRINTID_REPORT, sizeof (tmp));
2263 if (notfirst) {
2264 StringCat (contigs, " ");
2265 }
2266 StringCat (contigs, tmp);
2267 notfirst = TRUE;
2268 }
2269 }
2270 ffp->seplist = SetPhrapContigOrder (ffp->seplist, contigs);
2271 */
2272
2273 for (i = 0; i < count; i++) {
2274 if (order [i] != NULL) {
2275 sep = ffp->seplist;
2276 lastsep = NULL;
2277 while (sep != NULL && sep != order [i]) {
2278 lastsep = sep;
2279 sep = sep->next;
2280 }
2281 if (sep != NULL) {
2282 if (lastsep != NULL) {
2283 lastsep->next = sep->next;
2284 sep->next = NULL;
2285 } else {
2286 ffp->seplist = sep->next;
2287 sep->next = NULL;
2288 }
2289 }
2290 }
2291 }
2292 sep = ffp->seplist;
2293 while (sep != NULL) {
2294 nextsep = sep->next;
2295 sep->next = NULL;
2296 SeqEntryFree (sep);
2297 sep = nextsep;
2298 }
2299 ffp->seplist = NULL;
2300
2301 for (i = 0; i < count; i++) {
2302 if (order [i] != NULL) {
2303 ValNodeLink (&(ffp->seplist), order [i]);
2304 }
2305 }
2306
2307 MemFree (order);
2308 MemFree (collision);
2309 SafeDisable (b);
2310 SafeHide (ffp->orderblock);
2311 SafeShow (ffp->controlblock);
2312 if (TextHasNoText (ffp->orgname)) {
2313 Select (ffp->orgname);
2314 } else {
2315 Select (ffp->seqname);
2316 }
2317 if (Fa2htgsFormOkay (ffp)) {
2318 SafeEnable (ffp->okBtn);
2319 } else {
2320 SafeDisable (ffp->okBtn);
2321 }
2322 }
2323
2324 static void ReadContigFile (ButtoN b)
2325
2326 {
2327 BioseqPtr bsp;
2328 Fa2htgsFormPtr ffp;
2329 FILE *fp;
2330 Boolean onMaster;
2331 Char path [PATH_MAX];
2332 SeqEntryPtr sep = NULL;
2333
2334 ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2335 if (ffp == NULL) return;
2336 if (! GetInputFileName (path, sizeof (path), "", "TEXT")) return;
2337 if (! StringHasNoText (path)) {
2338 WatchCursor ();
2339 fp = FileOpen (path, "r");
2340 if (fp != NULL) {
2341 onMaster = (Boolean) (GetValue (ffp->contigtype) == 2);
2342 sep = ReadContigList (fp, onMaster);
2343 if (sep != NULL && sep->choice == 1) {
2344 ffp->seplist = sep;
2345 bsp = (BioseqPtr) sep->data.ptrvalue;
2346 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
2347 }
2348 }
2349 FileClose (fp);
2350 ArrowCursor ();
2351 if (ffp->seplist != NULL) {
2352 SafeShow (ffp->controlblock);
2353 SafeDisable (b);
2354 SafeDisable (ffp->contigtype);
2355 if (TextHasNoText (ffp->orgname)) {
2356 Select (ffp->orgname);
2357 } else {
2358 Select (ffp->seqname);
2359 }
2360 if (Fa2htgsFormOkay (ffp)) {
2361 SafeEnable (ffp->okBtn);
2362 } else {
2363 SafeDisable (ffp->okBtn);
2364 }
2365 }
2366 }
2367 }
2368
2369 static void AcceptFa2htgs (ButtoN b)
2370
2371 {
2372 Fa2htgsFormPtr ffp;
2373
2374 ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2375 if (ffp == NULL) return;
2376 Hide (ffp->form);
2377 Update ();
2378 if (ffp->finish != NULL) {
2379 ffp->finish (b);
2380 }
2381 SeqSubmitFree (ffp->ssp);
2382 SeqEntryFree (ffp->sep);
2383 Remove (ffp->form);
2384 }
2385
2386 static void CancelFa2htgs (ButtoN b)
2387
2388 {
2389 Fa2htgsFormPtr ffp;
2390
2391 ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2392 if (ffp == NULL) return;
2393 Hide (ffp->form);
2394 Update ();
2395 if (ffp->cancel != NULL) {
2396 ffp->cancel (b);
2397 }
2398 SeqSubmitFree (ffp->ssp);
2399 SeqEntryFree (ffp->sep);
2400 Remove (ffp->form);
2401 }
2402
2403 static void SetFa2htgsAcceptBtn (Handle control)
2404
2405 {
2406 Fa2htgsFormPtr ffp;
2407
2408 ffp = (Fa2htgsFormPtr) GetObjectExtra (control);
2409 if (ffp == NULL) return;
2410 if (Fa2htgsFormOkay (ffp)) {
2411 SafeEnable (ffp->okBtn);
2412 } else {
2413 SafeDisable (ffp->okBtn);
2414 }
2415 }
2416
2417 static void SetFa2htgsUpdate (ButtoN b)
2418
2419 {
2420 Fa2htgsFormPtr ffp;
2421
2422 ffp = (Fa2htgsFormPtr) GetObjectExtra (b);
2423 if (ffp == NULL) return;
2424 if (GetStatus (b)) {
2425 SafeEnable (ffp->accession);
2426 } else {
2427 SafeDisable (ffp->accession);
2428 }
2429 SetFa2htgsAcceptBtn ((Handle) b);
2430 }
2431
2432 static void CleanupGenomeCenterForm (GraphiC g, VoidPtr data)
2433
2434 {
2435 Fa2htgsFormPtr ffp;
2436 SeqEntryPtr next;
2437 SeqEntryPtr sep;
2438
2439 ffp = (Fa2htgsFormPtr) data;
2440 if (ffp != NULL) {
2441 sep = ffp->seplist;
2442 while (sep != NULL) {
2443 next = sep->next;
2444 sep->next = NULL;
2445 SeqEntryFree (sep);
2446 sep = next;
2447 }
2448 if (ffp->alists [0] != NULL) {
2449 FreeEnumFieldAlist (ffp->alists [0]);
2450 }
2451 }
2452 StdCleanupFormProc (g, data);
2453 }
2454
2455 static CharPtr secaccstrings [] = {"Secondary", "Accessions", NULL};
2456
2457 static Uint2 contigorder_types [] = {
2458 TAGLIST_POPUP
2459 };
2460
2461 static ENUM_ALIST(contigdefault_alist)
2462 {" ", 0},
2463 END_ENUM_ALIST
2464
2465 static EnumFieldAssocPtr contigdefault_alists [] = {
2466 contigdefault_alist
2467 };
2468
2469 extern DialoG CreateTagListDialogEx (GrouP h, Uint2 rows, Uint2 cols,
2470 Int2 spacing, Uint2Ptr types,
2471 Uint2Ptr textWidths, EnumFieldAssocPtr PNTR alists,
2472 Boolean useBar, Boolean noExtend,
2473 ToDialogFunc tofunc, FromDialogFunc fromfunc);
2474
2475 extern ForM CreateGenomeCenterForm (Int2 left, Int2 top, CharPtr title,
2476 BtnActnProc finish,
2477 BtnActnProc cancel,
2478 Boolean readPhrap,
2479 Boolean buildContig,
2480 WndActnProc activateForm)
2481
2482 {
2483 ButtoN b;
2484 GrouP c;
2485 Fa2htgsFormPtr ffp;
2486 GrouP g;
2487 GrouP h;
2488 PrompT ppt;
2489 GrouP q;
2490 GrouP sa;
2491 StdEditorProcsPtr sepp;
2492 WindoW w;
2493 Int2 wid;
2494 GrouP x;
2495 GrouP y;
2496
2497 ffp = (Fa2htgsFormPtr) MemNew (sizeof (Fa2htgsForm));
2498 if (ffp == NULL) return NULL;
2499 ffp->finish = finish;
2500 ffp->cancel = cancel;
2501 ffp->readPhrap = readPhrap;
2502 ffp->buildContig = buildContig;
2503
2504 w = FixedWindow (left, top, -10, -10, title, NULL);
2505 if (w == NULL) return NULL;
2506 SetObjectExtra (w, ffp, CleanupGenomeCenterForm);
2507
2508 ffp->form = (ForM) w;
2509 ffp->toform = NULL;
2510 ffp->fromform = Fa2htgsToSeqSubmitPtr;
2511 ffp->formmessage = Fa2htgsFormMessage;
2512
2513 ffp->ssp = NULL;
2514 ffp->sep = NULL;
2515 ffp->seplist = NULL;
2516 ffp->alists [0] = NULL;
2517
2518 #ifndef WIN_MAC
2519 CreateFa2htgsFormMenus (w);
2520 #endif
2521
2522 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2523 if (sepp != NULL) {
2524 ffp->appmessage = sepp->handleMessages;
2525 }
2526
2527 SetGroupSpacing (w, 10, 10);
2528
2529 h = HiddenGroup (w, -1, 0, NULL);
2530 SetGroupSpacing (h, 10, 10);
2531
2532 ffp->templateblock = HiddenGroup (h, -1, 0, NULL);
2533 b = PushButton (ffp->templateblock, "Read Seq-submit Template", ReadTemplate);
2534 SetObjectExtra (b, ffp, NULL);
2535
2536 ffp->fastablock = HiddenGroup (h, -1, 0, NULL);
2537 if (readPhrap) {
2538 b = PushButton (ffp->fastablock, "Read PHRAP File", ReadAPhrapFile);
2539 } else if (buildContig) {
2540 SetGroupSpacing (ffp->fastablock, 10, 10);
2541 y = HiddenGroup (ffp->fastablock, 1, 0, NULL);
2542 StaticPrompt (y, "Coordinates are on", 0, stdLineHeight, programFont, 'c');
2543 ffp->contigtype = HiddenGroup (y, 3, 0, NULL);
2544 RadioButton (ffp->contigtype, "Individual Accessions");
2545 RadioButton (ffp->contigtype, "Master Sequence");
2546 SetValue (ffp->contigtype, 1);
2547 b = PushButton (ffp->fastablock, "Read CONTIG Instructions", ReadContigFile);
2548 AlignObjects (ALIGN_CENTER, (HANDLE) y, (HANDLE) b, NULL);
2549 } else {
2550 b = PushButton (ffp->fastablock, "Read FASTA File", ReadFastaHtgsFile);
2551 }
2552 SetObjectExtra (b, ffp, NULL);
2553 Hide (ffp->fastablock);
2554
2555 x = HiddenGroup (h, 0, 0, NULL);
2556
2557 ffp->orderblock = HiddenGroup (x, -1, 0, NULL);
2558 SetGroupSpacing (ffp->orderblock, 5, 5);
2559 ppt = StaticPrompt (ffp->orderblock, "Enter contigs in desired order", 0, 0, programFont, 'c');
2560 ffp->contigorder = CreateTagListDialogEx (ffp->orderblock, 8, 1, 2,
2561 contigorder_types, NULL,
2562 contigdefault_alists,
2563 TRUE, TRUE, NULL, NULL);
2564 b = PushButton (ffp->orderblock, "Proceed", PhrapOrderChosen);
2565 SetObjectExtra (b, ffp, NULL);
2566 AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) ffp->contigorder,
2567 (HANDLE) b, NULL);
2568 Hide (ffp->orderblock);
2569
2570 ffp->controlblock = HiddenGroup (x, -1, 0, NULL);
2571 g = HiddenGroup (ffp->controlblock, 2, 0, NULL);
2572
2573 ffp->htgsphase = NULL;
2574 if (! buildContig) {
2575 StaticPrompt (g, "Phase", 0, stdLineHeight, programFont, 'l');
2576 ffp->htgsphase = HiddenGroup (g, 4, 0, (GrpActnProc) SetFa2htgsAcceptBtn);
2577 SetObjectExtra (ffp->htgsphase, ffp, NULL);
2578 RadioButton (ffp->htgsphase, "HTGS-0");
2579 RadioButton (ffp->htgsphase, "HTGS-1");
2580 RadioButton (ffp->htgsphase, "HTGS-2");
2581 RadioButton (ffp->htgsphase, "HTGS-3");
2582 StaticPrompt (g, "HTGS_", 0, stdLineHeight, programFont, 'l');
2583 q = HiddenGroup (g, 3, 0, NULL);
2584 ffp->draft = CheckBox (q, "Draft", NULL);
2585 ffp->fulltop = CheckBox (q, "Fulltop", NULL);
2586 ffp->activefin = CheckBox (q, "Activefin", NULL);
2587 }
2588
2589 StaticPrompt (g, "Organism", 0, dialogTextHeight, programFont, 'l');
2590 ffp->orgname = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2591 SetObjectExtra (ffp->orgname, ffp, NULL);
2592
2593 StaticPrompt (g, "Sequence name", 0, dialogTextHeight, programFont, 'l');
2594 ffp->seqname = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2595 SetObjectExtra (ffp->seqname, ffp, NULL);
2596
2597 StaticPrompt (g, "Length", 0, dialogTextHeight, programFont, 'l');
2598 ffp->knownlength = DialogText (g, "", 10, NULL);
2599 SetObjectExtra (ffp->knownlength, ffp, NULL);
2600
2601 StaticPrompt (g, "Gap Length", 0, dialogTextHeight, programFont, 'l');
2602 ffp->gaplength = DialogText (g, "100", 10, NULL);
2603 SetObjectExtra (ffp->gaplength, ffp, NULL);
2604
2605 ffp->update = CheckBox (g, "Update", SetFa2htgsUpdate);
2606 SetObjectExtra (ffp->update, ffp, NULL);
2607 ffp->accession = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2608 SetObjectExtra (ffp->accession, ffp, NULL);
2609 Disable (ffp->accession);
2610
2611 StaticPrompt (g, "Chromosome", 0, dialogTextHeight, programFont, 'l');
2612 ffp->chromosome = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2613 SetObjectExtra (ffp->chromosome, ffp, NULL);
2614
2615 StaticPrompt (g, "Clone", 0, dialogTextHeight, programFont, 'l');
2616 ffp->clone = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2617 SetObjectExtra (ffp->clone, ffp, NULL);
2618
2619 StaticPrompt (g, "Strain", 0, dialogTextHeight, programFont, 'l');
2620 ffp->strain = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2621 SetObjectExtra (ffp->strain, ffp, NULL);
2622
2623 StaticPrompt (g, "Cultivar", 0, dialogTextHeight, programFont, 'l');
2624 ffp->cultivar = DialogText (g, "", 10, (TxtActnProc) SetFa2htgsAcceptBtn);
2625 SetObjectExtra (ffp->cultivar, ffp, NULL);
2626
2627 wid = MaxStringWidths (secaccstrings) + 2;
2628 sa = MultiLinePrompt (g, "Secondary Accessions", wid, programFont);
2629 ffp->secondaries = CreateVisibleStringDialog (g, 3, -1, 15);
2630 AlignObjects (ALIGN_MIDDLE, (HANDLE) sa, (HANDLE) ffp->secondaries, NULL);
2631
2632 q = HiddenGroup (ffp->controlblock, 1, 0, NULL);
2633
2634 StaticPrompt (q, "Title", 0, 0, programFont, 'c');
2635 ffp->title = ScrollText (q, 20, 4, programFont, TRUE, (TxtActnProc) SetFa2htgsAcceptBtn);
2636 SetObjectExtra (ffp->title, ffp, NULL);
2637
2638 StaticPrompt (q, "Remark", 0, 0, programFont, 'c');
2639 ffp->remark = ScrollText (q, 20, 4, programFont, TRUE, (TxtActnProc) SetFa2htgsAcceptBtn);
2640 SetObjectExtra (ffp->remark, ffp, NULL);
2641
2642 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) q, NULL);
2643 Hide (ffp->controlblock);
2644
2645 c = HiddenGroup (h, 2, 0, NULL);
2646 ffp->okBtn = DefaultButton (c, "Accept", AcceptFa2htgs);
2647 SetObjectExtra (ffp->okBtn, ffp, NULL);
2648 Disable (ffp->okBtn);
2649 b = PushButton (c, "Cancel", CancelFa2htgs);
2650 SetObjectExtra (b, ffp, NULL);
2651
2652 AlignObjects (ALIGN_CENTER, (HANDLE) ffp->templateblock, (HANDLE) ffp->fastablock,
2653 (HANDLE) ffp->orderblock, (HANDLE) ffp->controlblock, (HANDLE) c, NULL);
2654
2655 RealizeWindow (w);
2656
2657 if (activateForm != NULL) {
2658 SetActivate (w, activateForm);
2659 }
2660
2661 Show (w);
2662 Select (w);
2663 Select (ffp->orgname);
2664
2665 return (ForM) w;
2666 }
2667
2668 typedef struct convcdsdata {
2669 FEATURE_FORM_BLOCK
2670
2671 SeqEntryPtr sep;
2672 TexT geneName;
2673 TexT protName;
2674 TexT featcomment;
2675 ButtoN retain;
2676 Uint2 subtype;
2677 Int2 errcount;
2678 Char findThis [128];
2679 SeqLocPtr slp;
2680 SeqEntryPtr nsep;
2681 ObjMgrPtr omp;
2682 ObjMgrTypePtr omtp;
2683 } ConvCdsData, PNTR ConvCdsPtr;
2684
2685 static Boolean CollectCDSAncestorGatherFunc (GatherContextPtr gcp)
2686
2687 {
2688 BioseqPtr bsp;
2689 ConvCdsPtr ccp;
2690 Boolean noLeft;
2691 Boolean noRight;
2692 ObjMgrTypePtr omtp;
2693 SeqEntryPtr sep;
2694 SeqFeatPtr sfp;
2695 SeqLocPtr slp;
2696 Uint2 subtype;
2697
2698 if (gcp == NULL) return TRUE;
2699
2700 ccp = (ConvCdsPtr) gcp->userdata;
2701 if (ccp == NULL ) return TRUE;
2702
2703 if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
2704 omtp = ccp->omtp;
2705 if (omtp == NULL || omtp->subtypefunc == NULL) return TRUE;
2706
2707 sfp = (SeqFeatPtr) gcp->thisitem;
2708 subtype = (*(omtp->subtypefunc)) ((Pointer) sfp);
2709 if (subtype != ccp->subtype) return TRUE;
2710
2711 bsp = GetBioseqGivenSeqLoc (sfp->location, gcp->entityID);
2712 if (bsp == NULL) return TRUE;
2713 if (ISA_aa (bsp->mol)) return TRUE;
2714 if (bsp->repr != Seq_repr_seg) {
2715 sep = ccp->nsep;
2716 if (sep == NULL || sep->choice != 1) return TRUE;
2717 bsp = (BioseqPtr) sep->data.ptrvalue;
2718 if (bsp == NULL) return TRUE;
2719 }
2720 CheckSeqLocForPartial (sfp->location, &noLeft, &noRight);
2721 slp = SeqLocMerge (bsp, sfp->location, ccp->slp, FALSE, TRUE, FALSE);
2722 if (slp == NULL) return TRUE;
2723 SetSeqLocPartial (slp, noLeft, noRight);
2724
2725 ccp->slp = SeqLocFree (ccp->slp);
2726 ccp->slp = slp;
2727
2728 return TRUE;
2729 }
2730
2731 static void FinishConvertingToCDS (SeqEntryPtr sep, Uint2 entityID, ConvCdsPtr ccp)
2732
2733 {
2734 ByteStorePtr bs;
2735 BioseqPtr bsp;
2736 Char ch;
2737 CdRegionPtr crp;
2738 ValNodePtr descr;
2739 Uint1 frame;
2740 Int2 genCode;
2741 Int2 i;
2742 Int4 len;
2743 Int4 lens [4];
2744 Int4 max;
2745 Boolean noLeft;
2746 Boolean noRight;
2747 MolInfoPtr mip;
2748 SeqEntryPtr nsep;
2749 SeqEntryPtr old;
2750 CharPtr prot;
2751 ProtRefPtr prp;
2752 SeqEntryPtr psep;
2753 CharPtr ptr;
2754 SeqFeatPtr sfp;
2755 Char str [128];
2756 ValNodePtr vnp;
2757
2758 if (sep == NULL || ccp == NULL) return;
2759 genCode = SeqEntryToGeneticCode (sep, NULL, NULL, 0);
2760 crp = CreateNewCdRgn (1, FALSE, genCode);
2761 if (crp == NULL) return;
2762 sfp = CreateNewFeature (ccp->nsep, NULL, SEQFEAT_CDREGION, NULL);
2763 if (sfp == NULL) {
2764 CdRegionFree (crp);
2765 return;
2766 }
2767 sfp->data.value.ptrvalue = (Pointer) crp;
2768 sfp->location = SeqLocFree (sfp->location);
2769 sfp->location = AsnIoMemCopy ((Pointer) ccp->slp,
2770 (AsnReadFunc) SeqLocAsnRead,
2771 (AsnWriteFunc) SeqLocAsnWrite);
2772 CheckSeqLocForPartial (sfp->location, &noLeft, &noRight);
2773 sfp->partial = (sfp->partial || noLeft || noRight);
2774 if (! TextHasNoText (ccp->featcomment)) {
2775 sfp->comment = SaveStringFromTextAndStripNewlines (ccp->featcomment);
2776 }
2777 max = 0;
2778 frame = 0;
2779 for (i = 1; i <= 3; i++) {
2780 crp->frame = (Uint1) i;
2781 bs = ProteinFromCdRegionEx (sfp, FALSE, FALSE);
2782 len = BSLen (bs);
2783 BSFree (bs);
2784 lens [i] = len;
2785 if (len > max) {
2786 max = len;
2787 frame = (Uint1) i;
2788 }
2789 }
2790 for (i = 1; i <= 3; i++) {
2791 if (lens [i] == max && i != frame) {
2792 (ccp->errcount)++;
2793 }
2794 }
2795 crp->frame = frame;
2796 bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
2797 if (bs == NULL) return;
2798 prot = BSMerge (bs, NULL);
2799 bs = BSFree (bs);
2800 if (prot == NULL) return;
2801 ptr = prot;
2802 ch = *ptr;
2803 while (ch != '\0') {
2804 *ptr = TO_UPPER (ch);
2805 ptr++;
2806 ch = *ptr;
2807 }
2808 i = (Int2) StringLen (prot);
2809 if (i > 0 && prot [i - 1] == '*') {
2810 prot [i - 1] = '\0';
2811 }
2812 bs = BSNew (1000);
2813 if (bs != NULL) {
2814 ptr = prot;
2815 /*
2816 if (prot [0] == '-') {
2817 ptr++;
2818 }
2819 */
2820 BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
2821 }
2822 MemFree (prot);
2823 if (bs == NULL) return;
2824 bsp = BioseqNew ();
2825 if (bsp == NULL) return;
2826 bsp->repr = Seq_repr_raw;
2827 bsp->mol = Seq_mol_aa;
2828 bsp->seq_data_type = Seq_code_ncbieaa;
2829 bsp->seq_data = (SeqDataPtr) bs;
2830 bsp->length = BSLen (bs);
2831 bs = NULL;
2832 old = SeqEntrySetScope (sep);
2833 bsp->id = MakeNewProteinSeqId (sfp->location, NULL);
2834 SeqMgrAddToBioseqIndex (bsp);
2835 SeqEntrySetScope (old);
2836 psep = SeqEntryNew ();
2837 if (psep != NULL) {
2838 psep->choice = 1;
2839 psep->data.ptrvalue = (Pointer) bsp;
2840 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, psep);
2841 mip = MolInfoNew ();
2842 if (mip != NULL) {
2843 mip->biomol = 8;
2844 mip->tech = 8;
2845 if (noLeft && noRight) {
2846 mip->completeness = 5;
2847 } else if (noLeft) {
2848 mip->completeness = 3;
2849 } else if (noRight) {
2850 mip->completeness = 4;
2851 }
2852 vnp = CreateNewDescriptor (psep, Seq_descr_molinfo);
2853 if (vnp != NULL) {
2854 vnp->data.ptrvalue = (Pointer) mip;
2855 }
2856 }
2857 descr = ExtractBioSourceAndPubs (sep);
2858 /*
2859 AddSeqEntryToSeqEntry (sep, psep, FALSE);
2860 */
2861 AddSeqEntryToSeqEntry (sep, psep, TRUE);
2862 nsep = FindNucSeqEntry (sep);
2863 ReplaceBioSourceAndPubs (sep, descr);
2864 SetSeqFeatProduct (sfp, bsp);
2865 GetTitle (ccp->protName, str, sizeof (str));
2866 if (! StringHasNoText (str)) {
2867 prp = CreateNewProtRef (str, NULL, NULL, NULL);
2868 if (prp != NULL) {
2869 sfp = CreateNewFeature (psep, NULL, SEQFEAT_PROT, NULL);
2870 if (sfp != NULL) {
2871 sfp->data.value.ptrvalue = (Pointer) prp;
2872 SetSeqLocPartial (sfp->location, noLeft, noRight);
2873 sfp->partial = (sfp->partial || noLeft || noRight);
2874 }
2875 }
2876 }
2877 }
2878 }
2879
2880 static void RemoveCDSAncestorCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
2881
2882 {
2883 BioseqPtr bsp;
2884 BioseqSetPtr bssp;
2885 ConvCdsPtr ccp;
2886 SeqAnnotPtr nextsap;
2887 SeqFeatPtr nextsfp;
2888 ObjMgrTypePtr omtp;
2889 Pointer PNTR prevsap;
2890 Pointer PNTR prevsfp;
2891 SeqAnnotPtr sap;
2892 SeqFeatPtr sfp;
2893 Uint2 subtype;
2894
2895 if (sep == NULL || sep->data.ptrvalue == NULL) return;
2896 ccp = (ConvCdsPtr) mydata;
2897 if (ccp == NULL) return;
2898 omtp = ccp->omtp;
2899 if (omtp == NULL || omtp->subtypefunc == NULL) return;
2900 if (IS_Bioseq (sep)) {
2901 bsp = (BioseqPtr) sep->data.ptrvalue;
2902 sap = bsp->annot;
2903 prevsap = (Pointer PNTR) &(bsp->annot);
2904 } else if (IS_Bioseq_set (sep)) {
2905 bssp = (BioseqSetPtr) sep->data.ptrvalue;
2906 sap = bssp->annot;
2907 prevsap = (Pointer PNTR) &(bssp->annot);
2908 } else return;
2909 while (sap != NULL) {
2910 nextsap = sap->next;
2911 if (sap->type == 1) {
2912 sfp = (SeqFeatPtr) sap->data;
2913 prevsfp = (Pointer PNTR) &(sap->data);
2914 while (sfp != NULL) {
2915 nextsfp = sfp->next;
2916 subtype = (*(omtp->subtypefunc)) ((Pointer) sfp);
2917 if (subtype == ccp->subtype) {
2918 *(prevsfp) = sfp->next;
2919 sfp->next = NULL;
2920 SeqFeatFree (sfp);
2921 } else {
2922 prevsfp = (Pointer PNTR) &(sfp->next);
2923 }
2924 sfp = nextsfp;
2925 }
2926 }
2927 if (sap->data == NULL) {
2928 *(prevsap) = sap->next;
2929 sap->next = NULL;
2930 SeqAnnotFree (sap);
2931 } else {
2932 prevsap = (Pointer PNTR) &(sap->next);
2933 }
2934 sap = nextsap;
2935 }
2936 }
2937
2938 static void ConvertToCDSCallback (SeqEntryPtr sep, Uint2 entityID, ConvCdsPtr ccp)
2939
2940 {
2941 BioseqPtr bsp;
2942 BioseqSetPtr bssp;
2943 GeneRefPtr grp;
2944 GatherScope gs;
2945 SeqLocPtr gslp;
2946 Boolean hasNulls;
2947 Boolean noLeft;
2948 Boolean noRight;
2949 SeqEntryPtr nsep;
2950 SeqFeatPtr sfp;
2951 SeqIdPtr sip;
2952 SeqLocPtr slp;
2953 Char str [128];
2954
2955 if (sep == NULL || ccp == NULL) return;
2956 if (IS_Bioseq_set (sep)) {
2957 bssp = (BioseqSetPtr) sep->data.ptrvalue;
2958 if (bssp != NULL && (bssp->_class == 7 ||
2959 (IsPopPhyEtcSet (bssp->_class)))) {
2960 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
2961 ConvertToCDSCallback (sep, entityID, ccp);
2962 }
2963 return;
2964 }
2965 }
2966 ccp->nsep = FindNucSeqEntry (sep);
2967 if (ccp->nsep == NULL) return;
2968 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
2969 gs.seglevels = 1;
2970 gs.get_feats_location = FALSE;
2971 MemSet ((Pointer) (gs.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
2972 gs.ignore[OBJ_BIOSEQ] = FALSE;
2973 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
2974 gs.ignore[OBJ_SEQFEAT] = FALSE;
2975 gs.ignore[OBJ_SEQANNOT] = FALSE;
2976 gs.scope = sep;
2977 ccp->slp = NULL;
2978 GatherEntity (entityID, (Pointer) ccp, CollectCDSAncestorGatherFunc, &gs);
2979 if (ccp->slp != NULL) {
2980 CheckSeqLocForPartial (ccp->slp, &noLeft, &noRight);
2981 sip = SeqLocId (ccp->slp);
2982 if (sip != NULL) {
2983 bsp = BioseqFind (sip);
2984 if (bsp != NULL && ISA_na (bsp->mol)) {
2985 slp = SegLocToParts (bsp, ccp->slp);
2986 if (slp != NULL) {
2987 ccp->slp = SeqLocFree (ccp->slp);
2988 ccp->slp = slp;
2989 FreeAllFuzz (ccp->slp);
2990 SetSeqLocPartial (ccp->slp, noLeft, noRight);
2991 }
2992 }
2993 }
2994 FinishConvertingToCDS (sep, entityID, ccp);
2995 nsep = FindNucSeqEntry (sep);
2996 GetTitle (ccp->geneName, str, sizeof (str));
2997 if (! StringHasNoText (str)) {
2998 grp = CreateNewGeneRef (str, NULL, NULL, FALSE);
2999 if (grp != NULL) {
3000 if (ExtendGene (grp, nsep, ccp->slp)) {
3001 grp = GeneRefFree (grp);
3002 } else {
3003 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_GENE, NULL);
3004 if (sfp != NULL) {
3005 sfp->data.value.ptrvalue = (Pointer) grp;
3006 sfp->location = SeqLocFree (sfp->location);
3007 sfp->location = AsnIoMemCopy ((Pointer) ccp->slp,
3008 (AsnReadFunc) SeqLocAsnRead,
3009 (AsnWriteFunc) SeqLocAsnWrite);
3010 sip = SeqLocId (sfp->location);
3011 if (sip != NULL) {
3012 bsp = BioseqFind (sip);
3013 if (bsp != NULL) {
3014 gslp = SeqLocMerge (bsp, sfp->location, NULL, TRUE, FALSE, FALSE);
3015 if (gslp != NULL) {
3016 sfp->location = SeqLocFree (sfp->location);
3017 sfp->location = gslp;
3018 if (bsp->repr == Seq_repr_seg) {
3019 gslp = SegLocToPartsEx (bsp, sfp->location, TRUE);
3020 sfp->location = SeqLocFree (sfp->location);
3021 sfp->location = gslp;
3022 hasNulls = LocationHasNullsBetween (sfp->location);
3023 sfp->partial = (sfp->partial || hasNulls);
3024 }
3025 FreeAllFuzz (gslp);
3026 SetSeqLocPartial (sfp->location, noLeft, noRight);
3027 sfp->partial = (sfp->partial || noLeft || noRight);
3028 }
3029 }
3030 }
3031 }
3032 }
3033 }
3034 }
3035 }
3036 ccp->slp = SeqLocFree (ccp->slp);
3037 }
3038
3039 static void DoConvertToCDS (ButtoN b)
3040
3041 {
3042 ConvCdsPtr ccp;
3043 CharPtr plural;
3044 Char str [128];
3045
3046 ccp = GetObjectExtra (b);
3047 if (ccp == NULL) {
3048 Remove (ParentWindow (b));
3049 return;
3050 }
3051 GetTitle (ccp->protName, str, sizeof (str));
3052 if (StringHasNoText (str)) {
3053 Message (MSG_OK, "Protein name is required");
3054 return;
3055 }
3056 Hide (ccp->form);
3057 WatchCursor ();
3058
3059 ccp->omp = ObjMgrGet ();
3060 if (ccp->omp != NULL) {
3061 ccp->omtp = ObjMgrTypeFind (ccp->omp, OBJ_SEQFEAT, NULL, NULL);
3062 if (ccp->omtp != NULL && ccp->omtp->subtypefunc != NULL) {
3063 ConvertToCDSCallback (ccp->sep, ccp->input_entityID, ccp);
3064 if (! GetStatus (ccp->retain)) {
3065 SeqEntryExplore (ccp->sep, (Pointer) ccp, RemoveCDSAncestorCallback);
3066 }
3067 }
3068 }
3069
3070 ArrowCursor ();
3071 Update ();
3072
3073 if (ccp->errcount > 0) {
3074 if (ccp->errcount > 1) {
3075 plural = "records";
3076 } else {
3077 plural = "record";
3078 }
3079 Message (MSG_ERROR, "Possible ambiguous frames detected in %d %s",
3080 (int) ccp->errcount, plural);
3081 }
3082
3083 ObjMgrSetDirtyFlag (ccp->input_entityID, TRUE);
3084 ObjMgrSendMsg (OM_MSG_UPDATE, ccp->input_entityID, 0, 0);
3085 Remove (ccp->form);
3086 Update ();
3087 }
3088
3089 extern void PrepareToConvertToCDS (SeqEntryPtr sep, Uint2 entityID,
3090 Uint2 subtype, CharPtr findthis)
3091
3092 {
3093 ButtoN b;
3094 GrouP c;
3095 ConvCdsPtr ccp;
3096 GrouP g;
3097 GrouP h;
3098 StdEditorProcsPtr sepp;
3099 WindoW w;
3100
3101 if (sep == NULL || entityID == 0 || subtype == 0) return;
3102
3103 ccp = (ConvCdsPtr) MemNew (sizeof (ConvCdsData));
3104 if (ccp == NULL) return;
3105 w = FixedWindow (-50, -33, -10, -10, "Convert to CDS", StdCloseWindowProc);
3106 SetObjectExtra (w, ccp, StdCleanupFormProc);
3107 ccp->form = (ForM) w;
3108 ccp->formmessage = DefaultMessageProc;
3109
3110 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3111 if (sepp != NULL) {
3112 SetActivate (w, sepp->activateForm);
3113 ccp->appmessage = sepp->handleMessages;
3114 }
3115
3116 ccp->input_entityID = entityID;
3117
3118 h = HiddenGroup (w, -1, 0, NULL);
3119 SetGroupSpacing (h, 10, 10);
3120
3121 ccp->sep = sep;
3122 ccp->subtype = subtype;
3123 StringNCpy_0 (ccp->findThis, findthis, sizeof (ccp->findThis));
3124 ccp->errcount = 0;
3125
3126 g = HiddenGroup (h, 2, 0, NULL);
3127 StaticPrompt (g, "Gene Symbol", 0, dialogTextHeight, programFont, 'l');
3128 ccp->geneName = DialogText (g, "", 20, NULL);
3129 StaticPrompt (g, "Protein Name", 0, dialogTextHeight, programFont, 'l');
3130 ccp->protName = DialogText (g, "", 20, NULL);
3131 StaticPrompt (g, "Comment", 0, 4 * Nlm_stdLineHeight, programFont, 'l');
3132 ccp->featcomment = ScrollText (g, 20, 4, programFont, TRUE, NULL);
3133
3134 ccp->retain = CheckBox (h, "Retain original features", NULL);
3135
3136 c = HiddenGroup (h, 4, 0, NULL);
3137 b = DefaultButton (c, "Accept", DoConvertToCDS);
3138 SetObjectExtra (b, ccp, NULL);
3139 PushButton (c, "Cancel", StdCancelButtonProc);
3140
3141 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, (HANDLE) ccp->retain, NULL);
3142 RealizeWindow (w);
3143 Show (w);
3144 Select (ccp->geneName);
3145 Update ();
3146 }
3147
3148 typedef struct alignform {
3149 FORM_MESSAGE_BLOCK
3150 DoC doc;
3151 } AlignForm, PNTR AlignFormPtr;
3152
3153 static ParData bioseqParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
3154 static ColData bioseqColFmt [] = {
3155 {0, 5, 0, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, TRUE}
3156 };
3157
3158 static ParData annotParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
3159 static ColData annotColFmt [] = {
3160 {0, 10, 0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, TRUE}
3161 };
3162
3163 static ParData alignParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
3164 static ColData alignColFmt [] = {
3165 {0, 15, 0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
3166 {0, 5, 0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
3167 {0, 0, 0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, TRUE}
3168 };
3169
3170 static Boolean AlignFormPopulateProc (GatherContextPtr gcp)
3171
3172 {
3173 AlignFormPtr afp;
3174 SeqAlignPtr align;
3175 Char annotDB [32];
3176 Uint1 annot_type;
3177 BioseqContextPtr bcp;
3178 BioseqPtr bsp;
3179 DenseDiagPtr ddp;
3180 DenseSegPtr dsp;
3181 ProtRefPtr prp;
3182 CharPtr ptr;
3183 SeqAnnotPtr sap;
3184 SeqEntryPtr sep;
3185 SeqFeatPtr sfp;
3186 SeqIdPtr sip;
3187 StdSegPtr ssp;
3188 Char str [256];
3189 Char tmp [128];
3190
3191 if (gcp == NULL) return TRUE;
3192
3193 afp = (AlignFormPtr) gcp->userdata;
3194 if (afp == NULL ) return TRUE;
3195
3196 switch (gcp->thistype) {
3197 case OBJ_BIOSEQ :
3198 bsp = (BioseqPtr) gcp->thisitem;
3199 if (bsp != NULL) {
3200 SeqIdWrite (bsp->id, str, PRINTID_REPORT, sizeof (str));
3201 bcp = BioseqContextNew (bsp);
3202 sfp = BioseqContextGetSeqFeat (bcp, SEQFEAT_PROT, NULL, NULL, 0);
3203 BioseqContextFree (bcp);
3204 if (sfp != NULL) {
3205 prp = (ProtRefPtr) sfp->data.value.ptrvalue;
3206 if (prp != NULL) {
3207 if (prp->name != NULL && (! StringHasNoText (prp->name->data.ptrvalue))) {
3208 StringCat (str, " (");
3209 StringCat (str, (CharPtr) prp->name->data.ptrvalue);
3210 StringCat (str, ")");
3211 } else if (! StringHasNoText (prp->desc)) {
3212 StringCat (str, " (");
3213 StringCat (str, (CharPtr) prp->desc);
3214 StringCat (str, ")");
3215 }
3216 }
3217 }
3218 StringCat (str, ":\n");
3219 AppendText (afp->doc, str, &bioseqParFmt, bioseqColFmt, programFont);
3220 }
3221 break;
3222 case OBJ_SEQANNOT :
3223 sap = (SeqAnnotPtr) gcp->thisitem;
3224 if (sap != NULL && sap->type == 2) {
3225 get_align_annot_qual (sap, annotDB, sizeof (annotDB), &annot_type);
3226 if (annot_type == ANNOT_BLAST) {
3227 StringCpy (str, annotDB);
3228 StringCat (str, ":\n");
3229 AppendText (afp->doc, str, &annotParFmt, annotColFmt, programFont);
3230 }
3231 }
3232 break;
3233 case OBJ_SEQALIGN :
3234 case OBJ_SEQHIST_ALIGN :
3235 align = (SeqAlignPtr) gcp->thisitem;
3236 sip = NULL;
3237 if (align->segtype == 1) {
3238 ddp = (DenseDiagPtr) align->segs;
3239 if (ddp != NULL) {
3240 for (sip = ddp->id; sip != NULL && sip->next != NULL; sip = sip->next) {
3241 }
3242 }
3243 } else if (align->segtype == 2) {
3244 dsp = (DenseSegPtr) align->segs;
3245 if (dsp != NULL) {
3246 for (sip = dsp->ids; sip != NULL && sip->next != NULL; sip = sip->next) {
3247 }
3248 }
3249 } else if (align->segtype == 3) {
3250 ssp = (StdSegPtr) align->segs;
3251 if (ssp != NULL) {
3252 for (sip = ssp->ids; sip != NULL && sip->next != NULL; sip = sip->next) {
3253 }
3254 }
3255 }
3256 if (sip != NULL) {
3257 bsp = BioseqLockById (sip);
3258 if (bsp != NULL) {
3259 /* SeqIdWrite (bsp->id, str, PRINTID_FASTA_LONG, sizeof (str)); */
3260 SeqIdWrite (bsp->id, str, PRINTID_REPORT, sizeof (str));
3261 StringNCpy_0 (tmp, BioseqGetTitle (bsp), sizeof (tmp));
3262 StringCat (str, "\t");
3263 if (! StringHasNoText (tmp)) {
3264 StringCat (str, tmp);
3265 }
3266 tmp [0] = '\0';
3267 sep = SeqMgrGetSeqEntryForData (bsp);
3268 if (sep != NULL) {
3269 SeqEntryToBioSource (sep, NULL, tmp, sizeof (tmp), NULL);
3270 if (! StringHasNoText (tmp)) {
3271 ptr = StringStr (tmp, "(");
3272 if (ptr != NULL) {
3273 *ptr = '\0';
3274 }
3275 StringCat (str, " [");
3276 StringCat (str, tmp);
3277 StringCat (str, "]");
3278 }
3279 }
3280 StringCat (str, "\t");
3281 sprintf (tmp, "%d %d %d", (int) gcp->entityID,
3282 (int) gcp->itemID, (int) gcp->thistype);
3283 StringCat (str, tmp);
3284 StringCat (str, "\n");
3285 AppendText (afp->doc, str, &alignParFmt, alignColFmt, programFont);
3286 }
3287 BioseqUnlock (bsp);
3288 }
3289 return TRUE;
3290 default :
3291 break;
3292 }
3293 return TRUE;
3294 }
3295
3296 static void PopulateAlignForm (ForM f, SeqEntryPtr sep)
3297
3298 {
3299 AlignFormPtr afp;
3300 GatherScope gs;
3301 RecT r;
3302 Int2 width;
3303
3304 if (f == NULL || sep == NULL) return;
3305 afp = (AlignFormPtr) GetObjectExtra (f);
3306 if (afp == NULL) return;
3307 Reset (afp->doc);
3308 SetDocAutoAdjust (afp->doc, FALSE);
3309 ObjectRect (afp->doc, &r);
3310 InsetRect (&r, 4, 4);
3311 width = r.right - r.left;
3312 alignColFmt [0].pixWidth = width / 5;
3313 alignColFmt [1].pixWidth = width - alignColFmt [0].pixWidth;
3314 bioseqColFmt [0].pixWidth = width;
3315 annotColFmt [0].pixWidth = width;
3316 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
3317 gs.seglevels = 1;
3318 MemSet((Pointer) (gs.ignore), (int) (TRUE), (size_t) (OBJ_MAX * sizeof (Boolean)));
3319 gs.ignore[OBJ_BIOSEQ] = FALSE;
3320 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
3321 gs.ignore[OBJ_SEQALIGN] = FALSE;
3322 gs.ignore[OBJ_SEQANNOT] = FALSE;
3323 gs.ignore[OBJ_SEQHIST] = FALSE;
3324 gs.ignore[OBJ_SEQHIST_ALIGN] = FALSE;
3325 gs.scope = sep;
3326 GatherEntity (afp->input_entityID, (Pointer) afp, AlignFormPopulateProc, &gs);
3327 AdjustDocScroll (afp->doc);
3328 }
3329
3330 static void AlignMessageProc (ForM f, Int2 mssg)
3331
3332 {
3333 FILE *fp;
3334 AlignFormPtr afp;
3335 Char path [PATH_MAX];
3336
3337 afp = (AlignFormPtr) GetObjectExtra (f);
3338 if (afp != NULL) {
3339 switch (mssg) {
3340 case VIB_MSG_CLOSE :
3341 Remove (f);
3342 break;
3343 case VIB_MSG_PRINT :
3344 PrintDocument (afp->doc);
3345 break;
3346 case VIB_MSG_EXPORT :
3347 if (GetOutputFileName (path, sizeof (path), "align.txt")) {
3348 WatchCursor ();
3349 #ifdef WIN_MAC
3350 fp = FileOpen (path, "r");
3351 if (fp != NULL) {
3352 FileClose (fp);
3353 } else {
3354 FileCreate (path, "TEXT", "ttxt");
3355 }
3356 #endif
3357 fp = FileOpen (path, "w");
3358 if (fp != NULL) {
3359 SaveDocument (afp->doc, fp);
3360 FileClose (fp);
3361 }
3362 ArrowCursor ();
3363 }
3364 break;
3365 default :
3366 if (afp->appmessage != NULL) {
3367 afp->appmessage (f, mssg);
3368 }
3369 break;
3370 }
3371 }
3372 }
3373
3374 static void AlignFormActivate (WindoW w)
3375
3376 {
3377 AlignFormPtr afp;
3378 IteM exportItm;
3379 IteM printItm;
3380
3381 afp = (AlignFormPtr) GetObjectExtra (w);
3382 #ifdef WIN_MAC
3383 currentFormDataPtr = (VoidPtr) afp;
3384 #endif
3385 if (afp != NULL) {
3386 if (afp->activate != NULL) {
3387 afp->activate (w);
3388 }
3389 exportItm = FindFormMenuItem ((BaseFormPtr) afp, VIB_MSG_EXPORT);
3390 SafeSetTitle (exportItm, "Export Align Summary...");
3391 SafeEnable (exportItm);
3392 printItm = FindFormMenuItem ((BaseFormPtr) afp, VIB_MSG_PRINT);
3393 SafeEnable (printItm);
3394 }
3395 }
3396
3397 static void AlignNotifyProc (DoC d, Int2 item, Int2 row, Int2 col, Boolean dblClick)
3398
3399 {
3400 unsigned int entityID;
3401 unsigned int itemID;
3402 unsigned int itemtype;
3403 CharPtr txt;
3404
3405 if (d == NULL || item < 1 || row < 1 || col < 1) return;
3406 txt = GetDocText (d, item, row, 3);
3407 if (! StringHasNoText (txt)) {
3408 if (sscanf (txt, "%u %u %u", &entityID, &itemID, &itemtype) == 3) {
3409 if (shftKey) {
3410 ObjMgrAlsoSelect (entityID, itemID, itemtype, 0, NULL);
3411 } else {
3412 ObjMgrSelect (entityID, itemID, itemtype, 0, NULL);
3413 }
3414 }
3415 }
3416 MemFree (txt);
3417 }
3418
3419 static ForM CreateAlignForm (Uint2 entityID)
3420
3421 {
3422 AlignFormPtr afp;
3423 GrouP c;
3424 GrouP h;
3425 StdEditorProcsPtr sepp;
3426 WindoW w;
3427 #ifndef WIN_MAC
3428 MenU m;
3429 #endif
3430
3431 w = NULL;
3432 afp = MemNew (sizeof (AlignForm));
3433 if (afp != NULL) {
3434 w = FixedWindow (-50, -33, -10, -10, "Alignment Summary", StdCloseWindowProc);
3435 SetObjectExtra (w, afp, StdCleanupFormProc);
3436 afp->form = (ForM) w;
3437 afp->formmessage = AlignMessageProc;
3438 afp->input_entityID = entityID;
3439
3440 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3441 if (sepp != NULL) {
3442 afp->appmessage = sepp->handleMessages;
3443 }
3444
3445 #ifndef WIN_MAC
3446 m = PulldownMenu (w, "File");
3447 FormCommandItem (m, "Close", (BaseFormPtr) afp, VIB_MSG_CLOSE);
3448 SeparatorItem (m);
3449 FormCommandItem (m, "Export...", (BaseFormPtr) afp, VIB_MSG_EXPORT);
3450 SeparatorItem (m);
3451 FormCommandItem (m, "Print...", (BaseFormPtr) afp, VIB_MSG_PRINT);
3452 #endif
3453
3454 h = HiddenGroup (w, -1, 0, NULL);
3455 SetGroupSpacing (h, 10, 10);
3456
3457 afp->doc = DocumentPanel (h, 35 * stdCharWidth, 20 * stdLineHeight);
3458 SetObjectExtra (afp->doc, afp, NULL);
3459 SetDocNotify (afp->doc, AlignNotifyProc);
3460
3461 c = HiddenGroup (w, 4, 0, NULL);
3462 PushButton (c, "Cancel", StdCancelButtonProc);
3463
3464 AlignObjects (ALIGN_CENTER, (HANDLE) afp->doc, (HANDLE) c, NULL);
3465
3466 RealizeWindow (w);
3467 SetActivate (w, AlignFormActivate);
3468 }
3469 return (ForM) w;
3470 }
3471
3472 extern void ViewAlignmentSummary (IteM i)
3473
3474 {
3475 BaseFormPtr bfp;
3476 ForM f;
3477 SeqEntryPtr sep;
3478
3479 #ifdef WIN_MAC
3480 bfp = currentFormDataPtr;
3481 #else
3482 bfp = GetObjectExtra (i);
3483 #endif
3484 if (bfp == NULL || bfp->input_entityID == 0) return;
3485 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3486 if (sep == NULL) return;
3487
3488 WatchCursor ();
3489 Update ();
3490 f = CreateAlignForm (bfp->input_entityID);
3491 PopulateAlignForm (f, sep);
3492 ArrowCursor ();
3493 Update ();
3494 Show (f);
3495 Select (f);
3496 }
3497
3498 typedef struct geneprotfind {
3499 SeqFeatPtr cds;
3500 SeqFeatPtr gene;
3501 SeqFeatPtr prot;
3502 SeqLocPtr location;
3503 SeqLocPtr product;
3504 Int4 mingene;
3505 Int4 minprot;
3506 } GeneProtFind, PNTR GeneProtPtr;
3507
3508 static Boolean GeneProtFindFunc (GatherContextPtr gcp)
3509
3510 {
3511 Int4 diff;
3512 GeneProtPtr gpp;
3513 SeqFeatPtr sfp;
3514
3515 if (gcp == NULL) return TRUE;
3516 gpp = (GeneProtPtr) gcp->userdata;
3517 if (gpp == NULL) return TRUE;
3518 if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
3519 sfp = (SeqFeatPtr) gcp->thisitem;
3520 if (sfp == NULL || sfp->data.value.ptrvalue == NULL) return TRUE;
3521 if (sfp->data.choice == SEQFEAT_GENE && gpp->location != NULL) {
3522 diff = SeqLocAinB (gpp->location, sfp->location);
3523 if (diff >= 0) {
3524 if (diff < gpp->mingene) {
3525 gpp->gene = sfp;
3526 gpp->mingene = diff;
3527 }
3528 }
3529 } else if (sfp->data.choice == SEQFEAT_PROT && gpp->product != NULL) {
3530 diff = SeqLocAinB (gpp->product, sfp->location);
3531 if (diff >= 0) {
3532 if (diff < gpp->minprot) {
3533 gpp->prot = sfp;
3534 gpp->minprot = diff;
3535 }
3536 }
3537 }
3538 return TRUE;
3539 }
3540
3541 void FindGeneAndProtForCDS (Uint2 entityID, SeqFeatPtr cds,
3542 SeqFeatPtr PNTR gene, SeqFeatPtr PNTR prot)
3543
3544 {
3545 GeneProtFind gpf;
3546 GatherScope gs;
3547
3548 if (gene != NULL) {
3549 *gene = NULL;
3550 }
3551 if (prot != NULL) {
3552 *prot = NULL;
3553 }
3554 if (entityID == 0 || cds == NULL) return;
3555 MemSet ((Pointer) (&gpf), 0, sizeof (GeneProtFind));
3556 gpf.cds = cds;
3557 gpf.gene = NULL;
3558 gpf.prot = NULL;
3559 gpf.location = cds->location;
3560 gpf.product = cds->product;
3561 gpf.mingene = INT4_MAX;
3562 gpf.minprot = INT4_MAX;
3563 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
3564 gs.seglevels = 1;
3565 gs.get_feats_location = FALSE;
3566 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
3567 gs.ignore[OBJ_BIOSEQ] = FALSE;
3568 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
3569 gs.ignore[OBJ_SEQFEAT] = FALSE;
3570 gs.ignore[OBJ_SEQANNOT] = FALSE;
3571 GatherEntity (entityID, (Pointer) &gpf, GeneProtFindFunc, &gs);
3572 if (gene != NULL) {
3573 *gene = gpf.gene;
3574 }
3575 if (prot != NULL) {
3576 *prot = gpf.prot;
3577 }
3578 }
3579
3580
3581 #define FIND_ASN 1
3582 #define FIND_FLAT 2
3583 #define FIND_GENE 3
3584 #define FIND_PROT 4
3585 #define FIND_POS 5
3586
3587 typedef struct findform {
3588 FORM_MESSAGE_BLOCK
3589 TexT findTxt;
3590 TexT replaceTxt;
3591 ButtoN caseCounts;
3592 ButtoN wholeWord;
3593 ButtoN doSeqIdLocal;
3594 ButtoN findAllBtn;
3595 ButtoN replaceAllBtn;
3596 Int2 type;
3597 ButtoN findFirstBtn;
3598 ButtoN findNextBtn;
3599 Int4 last_paragraph_found;
3600 } FindForm, PNTR FindFormPtr;
3601
3602 extern CharPtr CompressSpaces (CharPtr str)
3603
3604 {
3605 Char ch;
3606 CharPtr dst;
3607 Char last;
3608 CharPtr ptr;
3609
3610 if (str != NULL && str [0] != '\0') {
3611 dst = str;
3612 ptr = str;
3613 ch = *ptr;
3614 while (ch != '\0' && ch <= ' ') {
3615 ptr++;
3616 ch = *ptr;
3617 }
3618 while (ch != '\0') {
3619 *dst = ch;
3620 dst++;
3621 ptr++;
3622 last = ch;
3623 ch = *ptr;
3624 if (ch != '\0' && ch < ' ') {
3625 *ptr = ' ';
3626 ch = *ptr;
3627 }
3628 while (ch != '\0' && last <= ' ' && ch <= ' ') {
3629 ptr++;
3630 ch = *ptr;
3631 }
3632 }
3633 *dst = '\0';
3634 dst = NULL;
3635 ptr = str;
3636 ch = *ptr;
3637 while (ch != '\0') {
3638 if (ch != ' ') {
3639 dst = NULL;
3640 } else if (dst == NULL) {
3641 dst = ptr;
3642 }
3643 ptr++;
3644 ch = *ptr;
3645 }
3646 if (dst != NULL) {
3647 *dst = '\0';
3648 }
3649 }
3650 return str;
3651 }
3652
3653 extern CharPtr SearchForString (CharPtr str, CharPtr sub, Boolean case_counts, Boolean whole_word)
3654
3655 {
3656 CharPtr ptr = NULL;
3657 CharPtr tmp;
3658
3659 if (case_counts) {
3660 ptr = StringSearch (str, sub);
3661 } else {
3662 ptr = StringISearch (str, sub);
3663 }
3664 if (ptr == NULL) return NULL;
3665 if (whole_word) {
3666 if (ptr > str) {
3667 tmp = ptr - 1;
3668 if (! IS_WHITESP (*tmp)) return NULL;
3669 }
3670 tmp = ptr + StringLen (sub);
3671 if (*tmp != '\0' && (! IS_WHITESP (*tmp))) return NULL;
3672 }
3673 return ptr;
3674 }
3675
3676
3677 static Int4
3678 FindInFlatFileNext
3679 (Asn2gbJobPtr ajp,
3680 CharPtr sub,
3681 Boolean case_counts,
3682 Boolean whole_word,
3683 Boolean stop_after_one_found,
3684 Int4 start_index)
3685 {
3686 Int4 index;
3687 CharPtr string;
3688 BaseBlockPtr bbp;
3689 SelStructPtr sel;
3690 unsigned int entID;
3691 unsigned int itmID;
3692 unsigned int itmtype;
3693 Boolean already = FALSE;
3694
3695 if (ajp == NULL) return -1;
3696
3697 for (index = start_index + 1; index < ajp->numParagraphs; index++) {
3698 string = asn2gnbk_format (ajp, (Int4) index);
3699 if (string != NULL && *string != '\0') {
3700 CompressSpaces (string);
3701 if (SearchForString (string, sub, case_counts, whole_word) != NULL) {
3702 bbp = ajp->paragraphArray [index];
3703 if (bbp != NULL) {
3704 entID = bbp->entityID;
3705 itmID = bbp->itemID;
3706 itmtype = bbp->itemtype;
3707 already = FALSE;
3708 for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
3709 if (sel->entityID == entID && sel->itemID == itmID && sel->itemtype == itmtype) {
3710 already = TRUE;
3711 }
3712 }
3713 if (! already) {
3714 ObjMgrAlsoSelect (entID, itmID, itmtype, 0, NULL);
3715 if (stop_after_one_found) return index;
3716 }
3717 }
3718 }
3719 }
3720 }
3721 return -1;
3722 }
3723
3724
3725 static Int4
3726 FindInFlatFile
3727 (Uint2 entityID,
3728 Uint4 itemID,
3729 Uint2 itemtype,
3730 Uint1 format,
3731 Uint1 mode,
3732 CharPtr sub,
3733 Boolean case_counts,
3734 Boolean whole_word,
3735 Boolean stop_after_one,
3736 Int4 start_index)
3737
3738 {
3739 Asn2gbJobPtr ajp = NULL;
3740 BioseqPtr bsp = NULL;
3741 BioseqSetPtr bssp;
3742 ErrSev level;
3743 SeqEntryPtr oldsep;
3744 SeqEntryPtr sep = NULL;
3745 SeqEntryPtr topsep;
3746 SeqEntryPtr usethetop = NULL;
3747 Int4 retval = -1;
3748 FlgType flags = SHOW_CONTIG_FEATURES | SHOW_CONTIG_SOURCES | SHOW_FAR_TRANSLATION;
3749
3750 if (itemID == 0) {
3751 sep = GetTopSeqEntryForEntityID (entityID);
3752 usethetop = sep;
3753 } else {
3754 bsp = GetBioseqGivenIDs (entityID, itemID, itemtype);
3755 if (bsp == NULL)
3756 return retval;
3757 sep = SeqMgrGetSeqEntryForData (bsp);
3758 if (bsp->repr == Seq_repr_seg) {
3759 sep = GetBestTopParentForData (entityID, bsp);
3760 }
3761 }
3762
3763 if (sep == NULL)
3764 return retval;
3765
3766 level = ErrSetMessageLevel (SEV_MAX);
3767 WatchCursor ();
3768 Update ();
3769
3770 topsep = GetTopSeqEntryForEntityID (entityID);
3771 oldsep = SeqEntrySetScope (topsep);
3772
3773 if (usethetop != NULL && IS_Bioseq_set (usethetop)) {
3774 bssp = (BioseqSetPtr) usethetop->data.ptrvalue;
3775 ajp = asn2gnbk_setup (NULL, bssp, NULL, (FmtType) format, (ModType) mode, NORMAL_STYLE, flags, (LckType) 0, (CstType) 0, NULL);
3776 } else if (bsp != NULL) {
3777 ajp = asn2gnbk_setup (bsp, NULL, NULL, (FmtType) format, (ModType) mode, NORMAL_STYLE, flags, (LckType) 0, (CstType) 0, NULL);
3778 }
3779 if (ajp != NULL) {
3780 retval = FindInFlatFileNext (ajp, sub, case_counts, whole_word, stop_after_one, start_index);
3781 asn2gnbk_cleanup (ajp);
3782 }
3783
3784 SeqEntrySetScope (oldsep);
3785
3786 ErrSetMessageLevel (level);
3787 ArrowCursor ();
3788 Update ();
3789 return retval;
3790 }
3791
3792 static void FindFlatProc (ButtoN b)
3793
3794 {
3795 Boolean caseCounts;
3796 FindFormPtr ffp;
3797 CharPtr findme;
3798 Boolean wholeWord;
3799
3800 ffp = (FindFormPtr) GetObjectExtra (b);
3801 if (ffp == NULL) return;
3802 findme = SaveStringFromText (ffp->findTxt);
3803 ObjMgrDeSelect (0, 0, 0, 0, NULL);
3804 caseCounts = GetStatus (ffp->caseCounts);
3805 wholeWord = GetStatus (ffp->wholeWord);
3806 CompressSpaces (findme);
3807 ffp->last_paragraph_found = FindInFlatFile (ffp->input_entityID, ffp->input_itemID,
3808 ffp->input_itemtype, GENBANK_FMT, SEQUIN_MODE,
3809 findme, caseCounts, wholeWord, FALSE, -1);
3810 MemFree (findme);
3811 }
3812
3813 static void FindFlatProcFirst (ButtoN b)
3814
3815 {
3816 Boolean caseCounts;
3817 FindFormPtr ffp;
3818 CharPtr findme;
3819 Boolean wholeWord;
3820
3821 ffp = (FindFormPtr) GetObjectExtra (b);
3822 if (ffp == NULL) return;
3823 findme = SaveStringFromText (ffp->findTxt);
3824 ObjMgrDeSelect (0, 0, 0, 0, NULL);
3825 caseCounts = GetStatus (ffp->caseCounts);
3826 wholeWord = GetStatus (ffp->wholeWord);
3827 CompressSpaces (findme);
3828 ffp->last_paragraph_found = FindInFlatFile (ffp->input_entityID, ffp->input_itemID,
3829 ffp->input_itemtype, GENBANK_FMT, SEQUIN_MODE,
3830 findme, caseCounts, wholeWord, TRUE, -1);
3831 MemFree (findme);
3832 }
3833
3834 static void FindFlatProcNext (ButtoN b)
3835
3836 {
3837 Boolean caseCounts;
3838 FindFormPtr ffp;
3839 CharPtr findme;
3840 Boolean wholeWord;
3841
3842 ffp = (FindFormPtr) GetObjectExtra (b);
3843 if (ffp == NULL) return;
3844 findme = SaveStringFromText (ffp->findTxt);
3845 ObjMgrDeSelect (0, 0, 0, 0, NULL);
3846 caseCounts = GetStatus (ffp->caseCounts);
3847 wholeWord = GetStatus (ffp->wholeWord);
3848 CompressSpaces (findme);
3849 ffp->last_paragraph_found = FindInFlatFile (ffp->input_entityID, ffp->input_itemID,
3850 ffp->input_itemtype, GENBANK_FMT, SEQUIN_MODE,
3851 findme, caseCounts, wholeWord, TRUE, ffp->last_paragraph_found);
3852 MemFree (findme);
3853 }
3854
3855 static void FindTextProc (TexT t)
3856
3857 {
3858 FindFormPtr ffp;
3859
3860 ffp = (FindFormPtr) GetObjectExtra (t);
3861 if (ffp != NULL) {
3862 if (TextLength (t) > 0) {
3863 SafeEnable (ffp->findAllBtn);
3864 SafeEnable (ffp->replaceAllBtn);
3865 if (ffp->type == FIND_FLAT) {
3866 SafeEnable (ffp->findFirstBtn);
3867 SafeEnable (ffp->findNextBtn);
3868 }
3869 if (ffp->type == FIND_GENE || ffp->type == FIND_PROT) {
3870 SafeEnable (ffp->findFirstBtn);
3871 }
3872 } else {
3873 SafeDisable (ffp->findAllBtn);
3874 SafeDisable (ffp->replaceAllBtn);
3875 if (ffp->type == FIND_FLAT) {
3876 SafeDisable (ffp->findFirstBtn);
3877 SafeDisable (ffp->findNextBtn);
3878 }
3879 if (ffp->type == FIND_GENE || ffp->type == FIND_PROT) {
3880 SafeDisable (ffp->findFirstBtn);
3881 }
3882 }
3883 }
3884 }
3885
3886 static void CommonFindReplaceProc (ButtoN b, Boolean replace, Boolean replaceAll)
3887
3888 {
3889 Boolean caseCounts;
3890 CharPtr changeme;
3891 Boolean doSeqIdLocal;
3892 FindFormPtr ffp;
3893 CharPtr findme;
3894 Boolean wholeWord;
3895
3896 ffp = (FindFormPtr) GetObjectExtra (b);
3897 if (ffp != NULL) {
3898 findme = JustSaveStringFromText (ffp->findTxt);
3899 ObjMgrDeSelect (0, 0, 0, 0, NULL);
3900 caseCounts = GetStatus (ffp->caseCounts);
3901 wholeWord = GetStatus (ffp->wholeWord);
3902 doSeqIdLocal = GetStatus (ffp->doSeqIdLocal);
3903 if (replace) {
3904 changeme = JustSaveStringFromText (ffp->replaceTxt);
3905 FindReplaceInEntity (ffp->input_entityID, findme, changeme, caseCounts, wholeWord, replaceAll,
3906 FALSE, UPDATE_ONCE, NULL, NULL, NULL, doSeqIdLocal, NULL, NULL);
3907 GetRidOfEmptyFeatsDescStrings (ffp->input_entityID, NULL);
3908 ObjMgrSetDirtyFlag (ffp->input_entityID, TRUE);
3909 ObjMgrSendMsg (OM_MSG_UPDATE, ffp->input_entityID, 0, 0);
3910 MemFree (changeme);
3911 } else {
3912 FindReplaceInEntity (ffp->input_entityID, findme, NULL, caseCounts, wholeWord, FALSE,
3913 TRUE, UPDATE_ONCE, NULL, NULL, NULL, doSeqIdLocal, NULL, NULL);
3914 }
3915 MemFree (findme);
3916 Update ();
3917 }
3918 }
3919
3920 static void FindAllProc (ButtoN b)
3921
3922 {
3923 CommonFindReplaceProc (b, FALSE, FALSE);
3924 }
3925
3926 static void ReplaceAllProc (ButtoN b)
3927
3928 {
3929 CommonFindReplaceProc (b, TRUE, TRUE);
3930 }
3931
3932 static SeqFeatPtr
3933 FindNthFeatureOnBspByLabel
3934 (BioseqPtr bsp,
3935 CharPtr label,
3936 Uint1 seqFeatChoice,
3937 Uint1 featDefChoice,
3938 Int4 n,
3939 Int4 PNTR last_found,
3940 SeqMgrFeatContext PNTR context)
3941 {
3942 SMFeatItemPtr PNTR array;
3943 BioseqExtraPtr bspextra;
3944 Uint2 entityID;
3945 SMFeatItemPtr feat;
3946 Int4 L;
3947 Int4 mid;
3948 Int4 num;
3949 ObjMgrDataPtr omdp;
3950 Int4 R;
3951 SeqFeatPtr sfp;
3952 Uint1 seqfeattype;
3953 Int4 index = 0;
3954
3955 if (context != NULL) {
3956 MemSet ((Pointer) context, 0, sizeof (SeqMgrFeatContext));
3957 }
3958 if (last_found != NULL) {
3959 *last_found = -1;
3960 }
3961
3962 if (bsp == NULL || StringHasNoText (label)) return NULL;
3963
3964 omdp = SeqMgrGetOmdpForBioseq (bsp);
3965 if (omdp == NULL || omdp->datatype != OBJ_BIOSEQ) return NULL;
3966
3967 bspextra = (BioseqExtraPtr) omdp->extradata;
3968 if (bspextra == NULL) return NULL;
3969 array = bspextra->featsByLabel;
3970 num = bspextra->numfeats;
3971
3972 if (array == NULL || num < 1) return NULL;
3973
3974 if (n < 0 || n > bspextra->numfeats) return NULL;
3975
3976 entityID = ObjMgrGetEntityIDForPointer (omdp->dataptr);
3977
3978 /* binary search to leftmost candidate within the featsByLabel array */
3979
3980 L = 0;
3981 R = num - 1;
3982 while (L < R) {
3983 mid = (L + R) / 2;
3984 feat = array [mid];
3985 if (feat != NULL && StringICmp (feat->label, label) < 0) {
3986 L = mid + 1;
3987 } else {
3988 R = mid;
3989 }
3990 }
3991
3992 feat = array [R];
3993
3994 /* linear scan to find desired label on desired feature type */
3995
3996 while (R < num && feat != NULL && StringICmp (feat->label, label) == 0) {
3997 sfp = feat->sfp;
3998 if (sfp != NULL) {
3999 seqfeattype = sfp->data.choice;
4000 if ((seqFeatChoice == 0 || seqfeattype == seqFeatChoice) &&
4001 (featDefChoice == 0 || feat->subtype == featDefChoice) &&
4002 (! feat->ignore)) {
4003 if (context != NULL) {
4004 context->entityID = entityID;
4005 context->itemID = feat->itemID;
4006 context->sfp = sfp;
4007 context->sap = feat->sap;
4008 context->bsp = feat->bsp;
4009 context->label = feat->label;
4010 context->left = feat->left;
4011 context->right = feat->right;
4012 context->dnaStop = feat->dnaStop;
4013 context->partialL = feat->partialL;
4014 context->partialR = feat->partialR;
4015 context->farloc = feat->farloc;
4016 context->strand = feat->strand;
4017 context->seqfeattype = seqfeattype;
4018 context->featdeftype = feat->subtype;
4019 context->numivals = feat->numivals;
4020 context->ivals = feat->ivals;
4021 context->userdata = NULL;
4022 context->omdp = (Pointer) omdp;
4023 context->index = R + 1;
4024 }
4025 if (index == n) {
4026 if (last_found != NULL) {
4027 *last_found = index;
4028 }
4029 return sfp;
4030 } else {
4031 if (last_found != NULL) {
4032 *last_found = index;
4033 }
4034 index++;
4035 }
4036 }
4037 }
4038
4039 R++;
4040 feat = array [R];
4041 }
4042
4043 return NULL;
4044 }
4045
4046 typedef struct findnthfeatdata {
4047 CharPtr findme;
4048 Uint1 seqFeatChoice;
4049 Uint1 featDefChoice;
4050 Int4 n;
4051 Int4 passed_so_far;
4052 SeqMgrFeatContext PNTR context;
4053 SeqFeatPtr sfp;
4054 } FindNthFeatData, PNTR FindNthFeatPtr;
4055
4056 static void FindNthFeatureByLabelInSeqEntryBspProc (BioseqPtr bsp, Pointer userdata)
4057 {
4058 FindNthFeatPtr fnfp;
4059 Int4 this_search_index;
4060 Int4 passed_this_bsp = 0;
4061
4062 if (bsp == NULL || (fnfp = (FindNthFeatPtr)userdata) == NULL
4063 || fnfp->sfp != NULL) {
4064 return;
4065 }
4066
4067 this_search_index = fnfp->n - fnfp->passed_so_far;
4068
4069 if (fnfp->seqFeatChoice == SEQFEAT_GENE || fnfp->featDefChoice == FEATDEF_GENE) {
4070 fnfp->sfp = FindNthGeneOnBspByLabelOrLocusTag (bsp,
4071 fnfp->findme,
4072 this_search_index,
4073 &passed_this_bsp,
4074 fnfp->context);
4075 } else {
4076 fnfp->sfp = FindNthFeatureOnBspByLabel (bsp,
4077 fnfp->findme,
4078 fnfp->seqFeatChoice,
4079 fnfp->featDefChoice,
4080 this_search_index,
4081 &passed_this_bsp,
4082 fnfp->context);
4083 }
4084 if (fnfp->sfp == NULL) {
4085 fnfp->passed_so_far += passed_this_bsp;
4086 }
4087 }
4088
4089 static SeqFeatPtr FindNthFeatureByLabelInSeqEntry
4090 (SeqEntryPtr sep,
4091 CharPtr findme,
4092 Uint1 seqFeatChoice,
4093 Uint1 featDefChoice,
4094 Int4 n,
4095 SeqMgrFeatContext PNTR context)
4096 {
4097 FindNthFeatData fnf;
4098
4099 fnf.findme = findme;
4100 fnf.seqFeatChoice = seqFeatChoice;
4101 fnf.featDefChoice = featDefChoice;
4102 fnf.n = n;
4103 fnf.context = context;
4104 fnf.passed_so_far = 0;
4105 fnf.sfp = NULL;
4106
4107 VisitBioseqsInSep (sep, &fnf, FindNthFeatureByLabelInSeqEntryBspProc);
4108
4109 return fnf.sfp;
4110 }
4111
4112 static void FindByLabelOrPosProc (ButtoN b)
4113
4114 {
4115 Boolean already;
4116 BioseqPtr bsp = NULL;
4117 SeqMgrFeatContext context;
4118 FindFormPtr ffp;
4119 CharPtr findme;
4120 SelStructPtr sel;
4121 SeqEntryPtr sep = NULL;
4122 SeqFeatPtr sfp = NULL;
4123 Int4 val;
4124
4125 ffp = (FindFormPtr) GetObjectExtra (b);
4126 if (ffp == NULL) return;
4127
4128 if (ffp->input_itemID == 0) {
4129 sep = GetTopSeqEntryForEntityID (ffp->input_entityID);
4130 } else {
4131 bsp = GetBioseqGivenIDs (ffp->input_entityID, ffp->input_itemID, ffp->input_itemtype);
4132 if (bsp == NULL) return;
4133 sep = SeqMgrGetSeqEntryForData (bsp);
4134 if (bsp->repr == Seq_repr_seg) {
4135 sep = GetBestTopParentForData (ffp->input_entityID, bsp);
4136 }
4137 }
4138 if (sep == NULL) return;
4139
4140 findme = SaveStringFromText (ffp->findTxt);
4141 ObjMgrDeSelect (0, 0, 0, 0, NULL);
4142 CompressSpaces (findme);
4143
4144 switch (ffp->type) {
4145 case FIND_GENE :
4146 sfp = FindNthFeatureByLabelInSeqEntry (sep, findme, SEQFEAT_GENE, 0,
4147 ffp->last_paragraph_found + 1,
4148 &context);
4149 if (sfp == NULL) {
4150 if (ffp->last_paragraph_found > -1) {
4151 Message (MSG_OK, "No more found");
4152 } else {
4153 Message (MSG_OK, "No matches found");
4154 }
4155 ffp->last_paragraph_found = -1;
4156 } else {
4157 ffp->last_paragraph_found ++;
4158 }
4159 break;
4160 case FIND_PROT :
4161 sfp = FindNthFeatureByLabelInSeqEntry (sep, findme, SEQFEAT_CDREGION, 0,
4162 ffp->last_paragraph_found + 1,
4163 &context);
4164 if (sfp == NULL) {
4165 ffp->last_paragraph_found = -1;
4166 } else {
4167 ffp->last_paragraph_found ++;
4168 }
4169 break;
4170 case FIND_POS :
4171 if (StrToLong (findme, &val)) {
4172 if (val > 0 && val <= bsp->length) {
4173 val--;
4174 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
4175 while (sfp != NULL) {
4176 if (context.left >= val) break;
4177 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
4178 }
4179 }
4180 }
4181 break;
4182 default :
4183 break;
4184 }
4185
4186 MemFree (findme);
4187
4188 if (sfp == NULL) return;
4189
4190 already = FALSE;
4191 for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
4192 if (sel->entityID == context.entityID &&
4193 sel->itemID == context.itemID &&
4194 sel->itemtype == OBJ_SEQFEAT) {
4195 already = TRUE;
4196 }
4197 }
4198 if (! already) {
4199 ObjMgrAlsoSelect (context.entityID, context.itemID, OBJ_SEQFEAT, 0, NULL);
4200 }
4201
4202 }
4203
4204 static void FindByLabelOrPosProcFindFirst (ButtoN b)
4205 {
4206 FindFormPtr ffp;
4207
4208 ffp = (FindFormPtr) GetObjectExtra (b);
4209 if (ffp == NULL) return;
4210 ffp->last_paragraph_found = -1;
4211 FindByLabelOrPosProc (b);
4212 }
4213
4214 static void ClearFindTextProc (ButtoN b)
4215
4216 {
4217 FindFormPtr ffp;
4218
4219 ffp = (FindFormPtr) GetObjectExtra (b);
4220 if (ffp == NULL) return;
4221 SafeSetTitle (ffp->findTxt, "");
4222 SafeSetTitle (ffp->replaceTxt, "");
4223 if (ffp->type == FIND_FLAT) {
4224 ObjMgrDeSelect (0, 0, 0, 0, NULL);
4225 ffp->last_paragraph_found = -1;
4226 }
4227 FindTextProc (ffp->findTxt);
4228 Select (ffp->findTxt);
4229 }
4230
4231 static void FindFormMessage (ForM f, Int2 mssg)
4232
4233 {
4234 FindFormPtr ffp;
4235
4236 ffp = (FindFormPtr) GetObjectExtra (f);
4237 if (ffp != NULL) {
4238 switch (mssg) {
4239 case VIB_MSG_CLOSE :
4240 Remove (f);
4241 break;
4242 case VIB_MSG_CUT :
4243 StdCutTextProc (NULL);
4244 break;
4245 case VIB_MSG_COPY :
4246 StdCopyTextProc (NULL);
4247 break;
4248 case VIB_MSG_PASTE :
4249 StdPasteTextProc (NULL);
4250 break;
4251 case VIB_MSG_DELETE :
4252 StdDeleteTextProc (NULL);
4253 break;
4254 default :
4255 if (ffp->appmessage != NULL) {
4256 ffp->appmessage (f, mssg);
4257 }
4258 break;
4259 }
4260 }
4261 }
4262
4263 static void CopyFindReplBtn (ButtoN b)
4264 {
4265 FindFormPtr ffp;
4266 CharPtr str;
4267
4268 ffp = (FindFormPtr) GetObjectExtra (b);
4269 if (ffp == NULL)
4270 {
4271 return;
4272 }
4273 str = JustSaveStringFromText (ffp->findTxt);
4274 SetTitle (ffp->replaceTxt, str);
4275 str = MemFree (str);
4276 }
4277
4278 static ForM CreateFindForm (Int2 left, Int2 top, CharPtr title,
4279 Uint2 entityID, Uint4 itemID, Uint2 itemtype,
4280 Int2 type)
4281
4282 {
4283 ButtoN b;
4284 GrouP c;
4285 GrouP g;
4286 FindFormPtr ffp;
4287 GrouP j;
4288 GrouP q = NULL;
4289 StdEditorProcsPtr sepp;
4290 WindoW w;
4291
4292 w = NULL;
4293 ffp = MemNew (sizeof (FindForm));
4294 if (ffp != NULL) {
4295 w = FixedWindow (left, top, -10, -10, title, StdCloseWindowProc);
4296 SetObjectExtra (w, ffp, StdCleanupFormProc);
4297 ffp->form = (ForM) w;
4298 ffp->formmessage = FindFormMessage;
4299 ffp->input_entityID = entityID;
4300 ffp->input_itemID = itemID;
4301 ffp->input_itemtype = itemtype;
4302 ffp->type = type;
4303 ffp->last_paragraph_found = -1;
4304
4305 #ifndef WIN_MAC
4306 CreateStdEditorFormMenus (w);
4307 #endif
4308
4309 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4310 if (sepp != NULL) {
4311 SetActivate (w, sepp->activateForm);
4312 ffp->appmessage = sepp->handleMessages;
4313 }
4314
4315 j = HiddenGroup (w, -1, 0, NULL);
4316 SetGroupSpacing (j, 10, 10);
4317
4318 g = HiddenGroup (j, 3, 0, NULL);
4319 StaticPrompt (g, "Find", 0, dialogTextHeight, programFont, 'l');
4320 ffp->findTxt = DialogText (g, "", 25, FindTextProc);
4321 SetObjectExtra (ffp->findTxt, ffp, NULL);
4322 StaticPrompt (g, "", 0, 0, programFont, 'l');
4323 if (type == FIND_ASN) {
4324 StaticPrompt (g, "Replace", 0, dialogTextHeight, programFont, 'l');
4325 ffp->replaceTxt = DialogText (g, "", 25, NULL);
4326 SetObjectExtra (ffp->replaceTxt, ffp, NULL);
4327 b = PushButton (g, "Copy", CopyFindReplBtn);
4328 SetObjectExtra (b, ffp, NULL);
4329 }
4330
4331 if (type == FIND_ASN || type == FIND_FLAT) {
4332 q = HiddenGroup (w, 3, 0, NULL);
4333 ffp->caseCounts = CheckBox (q, "Case Sensitive", NULL);
4334 ffp->wholeWord = CheckBox (q, "Entire Word", NULL);
4335 if (indexerVersion && type == FIND_ASN) {
4336 ffp->doSeqIdLocal = CheckBox (q, "SeqID LOCAL", NULL);
4337 }
4338 }
4339
4340 c = HiddenGroup (w, 5, 0, NULL);
4341 SetGroupSpacing (c, 10, 2);
4342 if (type == FIND_ASN) {
4343 ffp->findAllBtn = DefaultButton (c, "Find All", FindAllProc);
4344 SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4345 Disable (ffp->findAllBtn);
4346 ffp->replaceAllBtn = PushButton (c, "Replace All", ReplaceAllProc);
4347 SetObjectExtra (ffp->replaceAllBtn, ffp, NULL);
4348 Disable (ffp->replaceAllBtn);
4349 } else if (type == FIND_FLAT) {
4350 ffp->findFirstBtn = PushButton (c, "Find First", FindFlatProcFirst);
4351 SetObjectExtra (ffp->findFirstBtn, ffp, NULL);
4352 Disable (ffp->findFirstBtn);
4353 ffp->findNextBtn = PushButton (c, "Find Next", FindFlatProcNext);
4354 SetObjectExtra (ffp->findNextBtn, ffp, NULL);
4355 Disable (ffp->findNextBtn);
4356 ffp->findAllBtn = DefaultButton (c, "Find All", FindFlatProc);
4357 SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4358 Disable (ffp->findAllBtn);
4359 } else if (type == FIND_GENE) {
4360 ffp->findFirstBtn = DefaultButton (c, "Find First Gene", FindByLabelOrPosProcFindFirst);
4361 SetObjectExtra (ffp->findFirstBtn, ffp, NULL);
4362 Disable (ffp->findFirstBtn);
4363 ffp->findAllBtn = PushButton (c, "Find Next Gene", FindByLabelOrPosProc);
4364 SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4365 Disable (ffp->findAllBtn);
4366 } else if (type == FIND_PROT) {
4367 ffp->findFirstBtn = DefaultButton (c, "Find First Protein", FindByLabelOrPosProcFindFirst);
4368 SetObjectExtra (ffp->findFirstBtn, ffp, NULL);
4369 Disable (ffp->findFirstBtn);
4370 ffp->findAllBtn = PushButton (c, "Find Next Protein", FindByLabelOrPosProc);
4371 SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4372 Disable (ffp->findAllBtn);
4373 } else if (type == FIND_POS) {
4374 ffp->findAllBtn = DefaultButton (c, "Find by Position", FindByLabelOrPosProc);
4375 SetObjectExtra (ffp->findAllBtn, ffp, NULL);
4376 Disable (ffp->findAllBtn);
4377 }
4378 b = PushButton (c, "Clear", ClearFindTextProc);
4379 SetObjectExtra (b, ffp, NULL);
4380 PushButton (c, "Cancel", StdCancelButtonProc);
4381
4382 AlignObjects (ALIGN_CENTER, (HANDLE) j, (HANDLE) c, (HANDLE) q, NULL);
4383
4384 RealizeWindow (w);
4385 Select (ffp->findTxt);
4386 }
4387 return (ForM) w;
4388 }
4389
4390 extern void FindStringProc (IteM i)
4391
4392 {
4393 BaseFormPtr bfp;
4394 ForM w;
4395
4396 #ifdef WIN_MAC
4397 bfp = currentFormDataPtr;
4398 #else
4399 bfp = GetObjectExtra (i);
4400 #endif
4401 if (bfp != NULL) {
4402 w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4403 bfp->input_itemID, bfp->input_itemtype, FIND_ASN);
4404 Show (w);
4405 Select (w);
4406 }
4407 }
4408
4409 extern void FindStringProcToolBtn (ButtoN b)
4410
4411 {
4412 BaseFormPtr bfp;
4413 ForM w;
4414
4415 bfp = (BaseFormPtr) GetObjectExtra (b);
4416 if (bfp == NULL) return;
4417
4418 w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4419 bfp->input_itemID, bfp->input_itemtype, FIND_ASN);
4420 Show (w);
4421 Select (w);
4422
4423 }
4424
4425
4426 extern void FindFlatfileProcToolBtn (ButtoN b)
4427
4428 {
4429 BaseFormPtr bfp;
4430 ForM w;
4431
4432 bfp = (BaseFormPtr) GetObjectExtra (b);
4433 if (bfp == NULL) return;
4434
4435 w = CreateFindForm (-90, -66, "Flat File Find", bfp->input_entityID,
4436 bfp->input_itemID, bfp->input_itemtype, FIND_FLAT);
4437 Show (w);
4438 Select (w);
4439
4440 }
4441
4442
4443 extern void FindFlatfileProc (IteM i)
4444
4445 {
4446 BaseFormPtr bfp;
4447 ForM w;
4448
4449 #ifdef WIN_MAC
4450 bfp = currentFormDataPtr;
4451 #else
4452 bfp = GetObjectExtra (i);
4453 #endif
4454 if (bfp != NULL) {
4455 w = CreateFindForm (-90, -66, "Flat File Find", bfp->input_entityID,
4456 bfp->input_itemID, bfp->input_itemtype, FIND_FLAT);
4457 Show (w);
4458 Select (w);
4459 }
4460 }
4461
4462 extern void FindGeneProc (IteM i)
4463
4464 {
4465 BaseFormPtr bfp;
4466 ForM w;
4467
4468 #ifdef WIN_MAC
4469 bfp = currentFormDataPtr;
4470 #else
4471 bfp = GetObjectExtra (i);
4472 #endif
4473 if (bfp != NULL) {
4474 w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4475 bfp->input_itemID, bfp->input_itemtype, FIND_GENE);
4476 Show (w);
4477 Select (w);
4478 }
4479 }
4480
4481 extern void FindProtProc (IteM i)
4482
4483 {
4484 BaseFormPtr bfp;
4485 ForM w;
4486
4487 #ifdef WIN_MAC
4488 bfp = currentFormDataPtr;
4489 #else
4490 bfp = GetObjectExtra (i);
4491 #endif
4492 if (bfp != NULL) {
4493 w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4494 bfp->input_itemID, bfp->input_itemtype, FIND_PROT);
4495 Show (w);
4496 Select (w);
4497 }
4498 }
4499
4500 extern void FindPosProc (IteM i)
4501
4502 {
4503 BaseFormPtr bfp;
4504 ForM w;
4505
4506 #ifdef WIN_MAC
4507 bfp = currentFormDataPtr;
4508 #else
4509 bfp = GetObjectExtra (i);
4510 #endif
4511 if (bfp != NULL) {
4512 w = CreateFindForm (-90, -66, "Find", bfp->input_entityID,
4513 bfp->input_itemID, bfp->input_itemtype, FIND_POS);
4514 Show (w);
4515 Select (w);
4516 }
4517 }
4518
4519 static void RemoveRedundantSourceNote (CharPtr str, CharPtr keyword, CharPtr name)
4520
4521 {
4522 Char ch;
4523 Boolean extract;
4524 CharPtr tmp1, tmp2;
4525
4526 if (str == NULL || keyword == NULL || name == NULL) return;
4527 while (str != NULL && *str != '\0') {
4528 extract = TRUE;
4529 tmp1 = str;
4530 ch = *tmp1;
4531 while (ch == ' ' || ch == ';') {
4532 tmp1++;
4533 ch = *tmp1;
4534 }
4535 tmp2 = keyword;
4536 ch = TO_UPPER (*tmp1);
4537 while (ch != '\0' && ch == TO_UPPER (*tmp2)) {
4538 tmp1++;
4539 tmp2++;
4540 ch = TO_UPPER (*tmp1);
4541 }
4542 if (*tmp2 == '\0' && ch == ' ') {
4543 while (ch != '\0' && ch == ' ') {
4544 tmp1++;
4545 ch = *tmp1;
4546 }
4547 tmp2 = name;
4548 while (ch != '\0' && ch == *tmp2) {
4549 tmp1++;
4550 tmp2++;
4551 ch = *tmp1;
4552 }
4553 if (*tmp2 == '\0' && (ch == '\0' || ch == ' ' || ch == ';')) {
4554 while (ch != '\0' && ch == ' ') {
4555 tmp1++;
4556 ch = *tmp1;
4557 }
4558 /* now ready to extract */
4559 } else {
4560 extract = FALSE;
4561 }
4562 } else {
4563 extract = FALSE;
4564 }
4565 if (extract) {
4566 while (ch == ' ' || ch == ';') {
4567 tmp1++;
4568 ch = *tmp1;
4569 }
4570 tmp2 = str;
4571 while (ch != '\0') {
4572 *tmp2 = ch;
4573 tmp1++;
4574 tmp2++;
4575 ch = *tmp1;
4576 }
4577 *tmp2 = '\0';
4578 } else {
4579 ch = *tmp1;
4580 while (ch != '\0' && ch != ';') {
4581 tmp1++;
4582 ch = *tmp1;
4583 }
4584 if (ch == ';') {
4585 tmp1++;
4586 ch = *tmp1;
4587 }
4588 while (ch != '\0' && (ch == ' ' || ch == ';')) {
4589 tmp1++;
4590 ch = *tmp1;
4591 }
4592 str = tmp1;
4593 }
4594 }
4595 }
4596
4597 static CharPtr TrimSpacesAndSemicolonsAroundString (CharPtr str)
4598
4599 {
4600 Uchar ch; /* to use 8bit characters in multibyte languages */
4601 CharPtr dst;
4602 CharPtr ptr;
4603
4604 if (str != NULL && str [0] != '\0') {
4605 dst = str;
4606 ptr = str;
4607 ch = *ptr;
4608 while (ch != '\0' && (ch <= ' ' || ch == ';')) {
4609 ptr++;
4610 ch = *ptr;
4611 }
4612 while (ch != '\0') {
4613 *dst = ch;
4614 dst++;
4615 ptr++;
4616 ch = *ptr;
4617 }
4618 *dst = '\0';
4619 dst = NULL;
4620 ptr = str;
4621 ch = *ptr;
4622 while (ch != '\0') {
4623 if (ch != ' ' && ch != ';') {
4624 dst = NULL;
4625 } else if (dst == NULL) {
4626 dst = ptr;
4627 }
4628 ptr++;
4629 ch = *ptr;
4630 }
4631 if (dst != NULL) {
4632 *dst = '\0';
4633 }
4634 }
4635 return str;
4636 }
4637
4638 extern void GetRidOfRedundantSourceNotes (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent);
4639 extern void GetRidOfRedundantSourceNotes (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4640
4641 {
4642 BioSourcePtr biop;
4643 BioseqPtr bsp;
4644 BioseqSetPtr bssp;
4645 OrgModPtr mod;
4646 OrgNamePtr onp;
4647 OrgRefPtr orp;
4648 ValNodePtr sdp;
4649 SubSourcePtr ssp;
4650 CharPtr str1, str2;
4651
4652 if (sep == NULL || sep->data.ptrvalue == NULL) return;
4653 if (IS_Bioseq (sep)) {
4654 bsp = (BioseqPtr) sep->data.ptrvalue;
4655 sdp = bsp->descr;
4656 } else if (IS_Bioseq_set (sep)) {
4657 bssp = (BioseqSetPtr) sep->data.ptrvalue;
4658 sdp = bssp->descr;
4659 } else return;
4660 while (sdp != NULL) {
4661 if (sdp->choice == Seq_descr_source) {
4662 str1 = NULL;
4663 str2 = NULL;
4664 onp = NULL;
4665 biop = (BioSourcePtr) sdp->data.ptrvalue;
4666 if (biop != NULL) {
4667 orp = biop->org;
4668 if (orp != NULL) {
4669 onp = orp->orgname;
4670 if (onp != NULL) {
4671 mod = onp->mod;
4672 while (mod != NULL) {
4673 if (mod->subtype == 255) {
4674 str1 = mod->subname;
4675 }
4676 mod = mod->next;
4677 }
4678 }
4679 }
4680 ssp = biop->subtype;
4681 while (ssp != NULL) {
4682 if (ssp->subtype == 255) {
4683 str2 = ssp->name;
4684 }
4685 ssp = ssp->next;
4686 }
4687 if (str1 != NULL || str2 != NULL) {
4688 if (onp != NULL) {
4689 mod = onp->mod;
4690 while (mod != NULL) {
4691 if (mod->subtype != 255) {
4692 RemoveRedundantSourceNote (str1, GetOrgModQualName (mod->subtype), mod->subname);
4693 RemoveRedundantSourceNote (str2, GetOrgModQualName (mod->subtype), mod->subname);
4694 }
4695 mod = mod->next;
4696 }
4697 }
4698 ssp = biop->subtype;
4699 while (ssp != NULL) {
4700 if (ssp->subtype != 255) {
4701 RemoveRedundantSourceNote (str1, GetSubsourceQualName (ssp->subtype), ssp->name);
4702 RemoveRedundantSourceNote (str2, GetSubsourceQualName (ssp->subtype), ssp->name);
4703 }
4704 ssp = ssp->next;
4705 }
4706 }
4707 }
4708 TrimSpacesAndSemicolonsAroundString (str1);
4709 TrimSpacesAndSemicolonsAroundString (str2);
4710 }
4711 sdp = sdp->next;
4712 }
4713 }
4714
4715 typedef struct convaccdata {
4716 CharPtr currID;
4717 CharPtr newID;
4718 } ConvAccData, PNTR ConvAccPtr;
4719
4720 static void ChangeSeqIdListToAccLocalID (SeqIdPtr sip, CharPtr currID, CharPtr newID)
4721
4722 {
4723 ObjectIdPtr oip;
4724
4725 while (sip != NULL) {
4726 switch (sip->choice) {
4727 case SEQID_LOCAL :
4728 oip = (ObjectIdPtr) sip->data.ptrvalue;
4729 if (oip != NULL) {
4730 if (StringCmp (oip->str, currID) == 0) {
4731 MemFree (oip->str);
4732 oip->str = StringSave (newID);
4733 }
4734 }
4735 break;
4736 default :
4737 break;
4738 }
4739 sip = sip->next;
4740 }
4741 }
4742
4743 static void ChangeSeqLocListToAccLocalID (SeqLocPtr slp, CharPtr currID, CharPtr newID)
4744
4745 {
4746 SeqLocPtr loc;
4747 PackSeqPntPtr psp;
4748 SeqBondPtr sbp;
4749 SeqIntPtr sinp;
4750 SeqIdPtr sip;
4751 SeqPntPtr spp;
4752
4753 while (slp != NULL) {
4754 switch (slp->choice) {
4755 case SEQLOC_NULL :
4756 break;
4757 case SEQLOC_EMPTY :
4758 case SEQLOC_WHOLE :
4759 sip = (SeqIdPtr) slp->data.ptrvalue;
4760 ChangeSeqIdListToAccLocalID (sip, currID, newID);
4761 break;
4762 case SEQLOC_INT :
4763 sinp = (SeqIntPtr) slp->data.ptrvalue;
4764 if (sinp != NULL) {
4765 sip = sinp->id;
4766 ChangeSeqIdListToAccLocalID (sip, currID, newID);
4767 }
4768 break;
4769 case SEQLOC_PNT :
4770 spp = (SeqPntPtr) slp->data.ptrvalue;
4771 if (spp != NULL) {
4772 sip = spp->id;
4773 ChangeSeqIdListToAccLocalID (sip, currID, newID);
4774 }
4775 break;
4776 case SEQLOC_PACKED_PNT :
4777 psp = (PackSeqPntPtr) slp->data.ptrvalue;
4778 if (psp != NULL) {
4779 sip = psp->id;
4780 ChangeSeqIdListToAccLocalID (sip, currID, newID);
4781 }
4782 break;
4783 case SEQLOC_PACKED_INT :
4784 case SEQLOC_MIX :
4785 case SEQLOC_EQUIV :
4786 loc = (SeqLocPtr) slp->data.ptrvalue;
4787 while (loc != NULL) {
4788 ChangeSeqIdListToAccLocalID (loc, currID, newID);
4789 loc = loc->next;
4790 }
4791 break;
4792 case SEQLOC_BOND :
4793 sbp = (SeqBondPtr) slp->data.ptrvalue;
4794 if (sbp != NULL) {
4795 spp = (SeqPntPtr) sbp->a;
4796 if (spp != NULL) {
4797 sip = spp->id;
4798 ChangeSeqIdListToAccLocalID (sip, currID, newID);
4799 }
4800 spp = (SeqPntPtr) sbp->b;
4801 if (spp != NULL) {
4802 sip = spp->id;
4803 ChangeSeqIdListToAccLocalID (sip, currID, newID);
4804 }
4805 }
4806 break;
4807 case SEQLOC_FEAT :
4808 break;
4809 default :
4810 break;
4811 }
4812 slp = slp->next;
4813 }
4814 }
4815
4816 static void ChangeAlignListToAccLocalID (SeqAlignPtr align, CharPtr currID, CharPtr newID)
4817
4818 {
4819 DenseDiagPtr ddp;
4820 DenseSegPtr dsp;
4821 StdSegPtr ssp;
4822
4823 if (align == NULL) return;
4824 if (align->segtype == 1) {
4825 ddp = (DenseDiagPtr) align->segs;
4826 if (ddp != NULL) {
4827 ChangeSeqIdListToAccLocalID (ddp->id, currID, newID);
4828 }
4829 } else if (align->segtype == 2) {
4830 dsp = (DenseSegPtr) align->segs;
4831 if (dsp != NULL) {
4832 ChangeSeqIdListToAccLocalID (dsp->ids, currID, newID);
4833 }
4834 } else if (align->segtype == 3) {
4835 ssp = (StdSegPtr) align->segs;
4836 if (ssp != NULL) {
4837 ChangeSeqLocListToAccLocalID (ssp->loc, currID, newID);
4838 }
4839 }
4840 }
4841
4842 static void CopyAccToLocalCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4843
4844 {
4845 BioseqPtr bsp;
4846 BioseqSetPtr bssp;
4847 ConvAccPtr cap;
4848 SeqAlignPtr sal;
4849 SeqAnnotPtr sap;
4850 SeqFeatPtr sfp;
4851 SeqIdPtr sip;
4852 SeqLocPtr slp;
4853
4854 if (sep == NULL || sep->data.ptrvalue == NULL) return;
4855 cap = (ConvAccPtr) mydata;
4856 if (cap == NULL) return;
4857 if (IS_Bioseq (sep)) {
4858 bsp = (BioseqPtr) sep->data.ptrvalue;
4859 sip = bsp->id;
4860 ChangeSeqIdListToAccLocalID (sip, cap->currID, cap->newID);
4861 SeqMgrReplaceInBioseqIndex (bsp);
4862 sap = bsp->annot;
4863 } else if (IS_Bioseq_set (sep)) {
4864 bssp = (BioseqSetPtr) sep->data.ptrvalue;
4865 sap = bssp->annot;
4866 } else return;
4867 while (sap != NULL) {
4868 if (sap->type == 1) {
4869 sfp = (SeqFeatPtr) sap->data;
4870 while (sfp != NULL) {
4871 slp = sfp->location;
4872 ChangeSeqLocListToAccLocalID (slp, cap->currID, cap->newID);
4873 slp = sfp->product;
4874 ChangeSeqLocListToAccLocalID (slp, cap->currID, cap->newID);
4875 sfp = sfp->next;
4876 }
4877 } else if (sap->type == 2) {
4878 sal = (SeqAlignPtr) sap->data;
4879 while (sal != NULL) {
4880 ChangeAlignListToAccLocalID (sal, cap->currID, cap->newID);
4881 sal = sal->next;
4882 }
4883 }
4884 sap = sap->next;
4885 }
4886 }
4887
4888 static void RecordAccToConvert (ValNodePtr PNTR vnpp, BioseqPtr bsp, CharPtr newID)
4889
4890 {
4891 ConvAccPtr cap;
4892 ObjectIdPtr oip;
4893 SeqIdPtr sip;
4894
4895 if (vnpp == NULL || bsp == NULL || StringHasNoText (newID)) return;
4896 for (sip = bsp->id; sip != NULL; sip = sip->next) {
4897 if (sip->choice == SEQID_LOCAL) {
4898 oip = (ObjectIdPtr) sip->data.ptrvalue;
4899 if (oip != NULL) {
4900 if (! StringHasNoText (oip->str)) {
4901 cap = (ConvAccPtr) MemNew (sizeof (ConvAccData));
4902 if (cap == NULL) return;
4903 cap->currID = StringSave (oip->str);
4904 cap->newID = StringSave (newID);
4905 ValNodeAddPointer (vnpp, 0, (Pointer) cap);
4906 return;
4907 }
4908 }
4909 }
4910 }
4911 }
4912
4913 static Boolean IsLegalAccession (CharPtr acnum, Int2 i)
4914
4915 {
4916 Int2 j;
4917
4918 if (! isalpha ((Int4)(acnum [0]))) return FALSE;
4919 if (!(isdigit((Int4)(acnum[1])) && i == 6) && !(isalpha((Int4)(acnum[1])) && i == 8)) return FALSE;
4920 for (j = 2; j < i; j++) {
4921 if (!(isdigit((Int4)(acnum[j])))) return FALSE;
4922 }
4923 return TRUE;
4924 }
4925
4926 static void FindAccInDefCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
4927
4928 {
4929 Char acnum [17];
4930 BioseqPtr bsp;
4931 Int2 i;
4932 CharPtr p;
4933 Char str [128];
4934 ValNodePtr ttl;
4935 ValNodePtr PNTR vnpp;
4936
4937 if (sep == NULL || sep->data.ptrvalue == NULL) return;
4938 if (! IS_Bioseq (sep)) return;
4939 vnpp = (ValNodePtr PNTR) mydata;
4940 if (vnpp == NULL) return;
4941 ttl = SeqEntryGetSeqDescr (sep, Seq_descr_title, NULL);
4942 while (ttl != NULL) {
4943 StringNCpy_0 (str, (CharPtr) ttl->data.ptrvalue, sizeof (str));
4944 TrimSpacesAroundString (str);
4945 if (! StringHasNoText (str)) {
4946 if (str [0] == 'a' && str [1] == 'c' && str [2] == 'c') {
4947 p = str + 3;
4948 for (i = 0; isalnum ((Int4)(*p)) && *p != '\0'; p++, i++) {
4949 acnum [i] = *p;
4950 }
4951 acnum [i] = '\0';
4952 if (i == 6 || i == 8) {
4953 if (IsLegalAccession (acnum, i)) {
4954 bsp = (BioseqPtr) sep->data.ptrvalue;
4955 RecordAccToConvert (vnpp, bsp, str);
4956 }
4957 }
4958 }
4959 }
4960 ttl = SeqEntryGetSeqDescr (sep, Seq_descr_title, ttl);
4961 }
4962 }
4963
4964 static void ConvertAccInDefToLocalIdProc (SeqEntryPtr sep)
4965
4966 {
4967 ConvAccPtr cap;
4968 ValNodePtr head;
4969 ValNodePtr vnp;
4970
4971 if (sep == NULL) return;
4972 head = NULL;
4973 SeqEntryExplore (sep, (Pointer) &head, FindAccInDefCallback);
4974 if (head == NULL) return;
4975 if (Message (MSG_YN, "Convert accLNNNNN or accLLNNNNNN in title to local ID?") == ANS_NO) return;
4976 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4977 cap = (ConvAccPtr) vnp->data.ptrvalue;
4978 if (cap != NULL) {
4979 SeqEntryExplore (sep, (Pointer) cap, CopyAccToLocalCallback);
4980 }
4981 }
4982 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4983 cap = (ConvAccPtr) vnp->data.ptrvalue;
4984 if (cap != NULL) {
4985 MemFree (cap->currID);
4986 MemFree (cap->newID);
4987 vnp->data.ptrvalue = MemFree (cap);
4988 }
4989 }
4990 ValNodeFree (head);
4991 }
4992
4993 static Int2 taxonCount;
4994
4995 static Int4 DoSeqEntryToAsn3 (SeqEntryPtr sep, Boolean strip, Boolean correct,
4996 Boolean force, Boolean dotaxon, MonitorPtr mon)
4997
4998 {
4999 BioseqSetPtr bssp;
5000 SeqEntryPtr oldscope;
5001 Int4 rsult;
5002 Char str [32];
5003
5004 rsult = 0;
5005 if (IS_Bioseq_set (sep)) {
5006 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5007 if (bssp != NULL && (bssp->_class == 7 ||
5008 (IsPopPhyEtcSet (bssp->_class)))) {
5009 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
5010 rsult += DoSeqEntryToAsn3 (sep, strip, correct, force, dotaxon, mon);
5011 }
5012 return rsult;
5013 }
5014 }
5015 /*#ifdef USE_TAXON*/
5016 if (dotaxon && mon != NULL) {
5017 taxonCount++;
5018 sprintf (str, "Processing Component %d", (int) taxonCount);
5019 MonitorStrValue (mon, str);
5020 }
5021 /*#endif*/
5022 /*#ifdef INTERNAL_NCBI_SEQUIN*/
5023 if (indexerVersion) {
5024 if ((! force) && (! NoBiosourceOrTaxonId (sep))) return 0;
5025 } else {
5026 /*#else*/
5027 if ((! force) && SeqEntryGetSeqDescr (sep, Seq_descr_source, NULL) != NULL) return 0;
5028 }
5029 /*#endif*/
5030 oldscope = SeqEntrySetScope (sep);
5031 if (dotaxon) {
5032 rsult = SeqEntryToAsn3Ex (sep, strip, correct, TRUE, NULL, Tax3MergeSourceDescr, FALSE);
5033 DeleteMarkedObjects (0, OBJ_SEQENTRY, sep);
5034 } else {
5035 rsult = SeqEntryToAsn3Ex (sep, strip, correct, FALSE, NULL, NULL, FALSE);
5036 }
5037 SeqEntrySetScope (oldscope);
5038 return rsult;
5039 }
5040
5041 /* CheckSeqAlignCallback copied from salsa.c */
5042 static void CheckSeqAlignCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
5043 {
5044 BioseqPtr bsp;
5045 BioseqSetPtr bssp;
5046 SeqAnnotPtr sap,
5047 pre;
5048
5049 if (sep != NULL && sep->data.ptrvalue) {
5050 if (IS_Bioseq(sep)) {
5051 bsp = (BioseqPtr) sep->data.ptrvalue;
5052 if (bsp!=NULL) {
5053 pre=NULL;
5054 sap=bsp->annot;
5055 while (sap!= NULL)
5056 {
5057 if (sap->type == 2) {
5058 if (is_dim1seqalign ((SeqAlignPtr) sap->data)) {
5059 if (pre==NULL) {
5060 bsp->annot=sap->next;
5061 sap->next=NULL;
5062 SeqAnnotFree (sap);
5063 sap=bsp->annot;
5064 }
5065 else {
5066 pre->next=sap->next;
5067 pre=sap->next;
5068 sap->next=NULL;
5069 SeqAnnotFree (sap);
5070 sap=pre;
5071 }
5072 }
5073 else {
5074 pre=sap;
5075 sap=sap->next;
5076 }
5077 }
5078 else {
5079 pre=sap;
5080 sap=sap->next;
5081 }
5082 }
5083 }
5084 }
5085 else if(IS_Bioseq_set(sep)) {
5086 bssp = (BioseqSetPtr)sep->data.ptrvalue;
5087 if (bssp!=NULL) {
5088 pre=NULL;
5089 sap=bssp->annot;
5090 while (sap!= NULL)
5091 {
5092 if (sap->type == 2) {
5093 if (is_dim1seqalign ((SeqAlignPtr) sap->data)) {
5094 if (pre==NULL) {
5095 bssp->annot=sap->next;
5096 sap->next=NULL;
5097 SeqAnnotFree (sap);
5098 sap=bssp->annot;
5099 }
5100 else {
5101 pre=sap->next;
5102 sap->next=NULL;
5103 SeqAnnotFree (sap);
5104 sap=sap->next;
5105 }
5106 }
5107 else {
5108 pre=sap;
5109 sap=sap->next;
5110 }
5111 }
5112 else {
5113 pre=sap;
5114 sap=sap->next;
5115 }
5116 }
5117 }
5118 }
5119 }
5120 }
5121
5122 /* RemoveMultipleTitles currently removes FIRST title in chain */
5123
5124 static void RemoveMultipleTitles (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
5125
5126 {
5127 BioseqPtr bsp;
5128 BioseqSetPtr bssp;
5129 SeqDescrPtr descr = NULL;
5130 SeqDescrPtr lasttitle = NULL;
5131 ObjValNodePtr ovp;
5132 SeqDescrPtr sdp;
5133
5134 if (IS_Bioseq (sep)) {
5135 bsp = (BioseqPtr) sep->data.ptrvalue;
5136 if (bsp == NULL) return;
5137 descr = bsp->descr;
5138 } else if (IS_Bioseq_set (sep)) {
5139 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5140 if (bssp == NULL) return;
5141 descr = bssp->descr;
5142 } else return;
5143 for (sdp = descr; sdp != NULL; sdp = sdp->next) {
5144 if (sdp->choice != Seq_descr_title) continue;
5145 if (lasttitle != NULL) {
5146 if (lasttitle->extended != 0) {
5147 ovp = (ObjValNodePtr) lasttitle;
5148 ovp->idx.deleteme = TRUE;
5149 }
5150 lasttitle = sdp;
5151 } else {
5152 lasttitle = sdp;
5153 }
5154 }
5155 }
5156
5157 static void MakeSequinCleanupObject (SeqEntryPtr sep)
5158
5159 {
5160 DatePtr dp;
5161 ValNodePtr sdp;
5162 UserObjectPtr uop;
5163
5164 dp = DateCurr ();
5165 if (dp == NULL) return;
5166
5167 uop = CreateNcbiCleanupUserObject ();
5168 if (uop == NULL) return;
5169
5170 AddStringToNcbiCleanupUserObject (uop, "method", "SequinCleanup");
5171 AddIntegerToNcbiCleanupUserObject (uop, "version", NCBI_CLEANUP_VERSION);
5172
5173 AddIntegerToNcbiCleanupUserObject (uop, "month", dp->data [2]);
5174 AddIntegerToNcbiCleanupUserObject (uop, "day", dp->data [3]);
5175 AddIntegerToNcbiCleanupUserObject (uop, "year", dp->data [1] + 1900);
5176
5177 sdp = NewDescrOnSeqEntry (sep, Seq_descr_user);
5178 if (sdp == NULL) return;
5179 sdp->data.ptrvalue = uop;
5180 }
5181
5182 extern Int4 MySeqEntryToAsn3Ex (SeqEntryPtr sep, Boolean strip, Boolean correct, Boolean force, Boolean dotaxon);
5183 extern Int4 MySeqEntryToAsn3Ex (SeqEntryPtr sep, Boolean strip, Boolean correct, Boolean force, Boolean dotaxon)
5184
5185 {
5186 Uint2 entityID;
5187 MonitorPtr mon;
5188 Boolean needstaxfix;
5189 Int4 rsult;
5190 ErrSev sev;
5191
5192 rsult = 0;
5193 sev = ErrSetMessageLevel (SEV_FATAL);
5194
5195 RemoveAllNcbiCleanupUserObjects (sep);
5196
5197 BasicSeqEntryCleanup (sep);
5198 EntryChangeImpFeat(sep); /* change any CDS ImpFeat to real CdRegion */
5199 /* NormalizePeriodsOnInitials (sep); */ /* put periods on author initials */
5200 /* MoveRnaGBQualProductToName (sep); */ /* move rna gbqual product to rna-ref.ext.name */
5201 /* MoveProtGBQualProductToName (sep); */ /* move prot gbqual product to prot-ref.name */
5202 /* MoveCdsGBQualProductToName (sep); */ /* move cds gbqual product to prot-ref.name */
5203 /* MoveFeatGBQualsToFields (sep); */ /* move feature partial, exception to fields */
5204 if (indexerVersion) {
5205 /*
5206 StripTitleFromProtsInNucProts (sep);
5207 */
5208 MoveFeatsFromPartsSet (sep);
5209 move_cds (sep); /* move CDS features to nuc-prot set */
5210 }
5211 /* ExtendGeneFeatIfOnMRNA (0, sep); */ /* gene on mRNA is full length */
5212 entityID = ObjMgrGetEntityIDForChoice (sep);
5213 SeqMgrIndexFeatures (entityID, NULL);
5214 VisitBioseqsInSep (sep, NULL, ExtendSingleGeneOnMRNA);
5215 RemoveBioSourceOnPopSet (sep, NULL);
5216 /* SeqEntryExplore (sep, NULL, CleanupEmptyFeatCallback); */
5217 SeqEntryExplore (sep, NULL, DeleteMultipleTitles); /* do it old way in Sequin */
5218 /*
5219 SeqEntryExplore (sep, NULL, RemoveMultipleTitles);
5220 DeleteMarkedObjects (0, OBJ_SEQENTRY, (Pointer) sep);
5221 */
5222 SeqEntryPack (sep);
5223 if (indexerVersion) {
5224 ConvertAccInDefToLocalIdProc (sep); /* if title is accXNNNNN, convert to seqID */
5225 }
5226 if (useEntrez) {
5227 ValidateSeqAlignandACCInSeqEntry (sep, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE); /* remove components with seqID accXNNNNN */
5228 }
5229 SeqEntryExplore (sep, NULL, CheckSeqAlignCallback); /* remove alignments with single dimension */
5230 needstaxfix = FALSE;
5231 if (! force) {
5232 needstaxfix = NoBiosourceOrTaxonId (sep);
5233 }
5234 if ((! force) && (! needstaxfix)) {
5235 ConvertFullLenSourceFeatToDesc (sep);
5236 ConvertFullLenPubFeatToDesc (sep);
5237 /* EntryStripSerialNumber(sep); */ /* strip citation serial numbers */
5238 EntryChangeGBSource (sep); /* at least remove redundant information in GBBlocks */
5239 EntryCheckGBBlock (sep);
5240 /* SeqEntryMoveDbxrefs (sep); */ /* db_xref gbqual to sfp->dbxref */
5241 EntryMergeDupBioSources (sep);
5242 GetRidOfEmptyFeatsDescStrings (0, sep);
5243 GetRidOfLocusInSeqIds (0, sep);
5244 /* reindex, since CdEndCheck (from CdCheck) gets best overlapping gene */
5245 entityID = ObjMgrGetEntityIDForChoice (sep);
5246 SeqMgrIndexFeatures (entityID, NULL);
5247 MakeSequinCleanupObject (sep);
5248 NormalizeDescriptorOrder (sep);
5249 SeqMgrIndexFeatures (entityID, NULL);
5250 CdCheck (sep, NULL);
5251 BasicSeqEntryCleanup (sep);
5252 ErrSetMessageLevel (sev);
5253 return rsult;
5254 }
5255 if (force && useTaxon) {
5256 dotaxon = TRUE;
5257 }
5258 mon = NULL;
5259 taxonCount = 0;
5260 /*#ifdef USE_TAXON*/
5261 if (dotaxon) {
5262 WatchCursor ();
5263 mon = MonitorStrNewEx ("Taxonomy Lookup", 40, FALSE);
5264 MonitorStrValue (mon, "Processing Organism Info");
5265 Update ();
5266 }
5267 /*#endif*/
5268
5269 /* set dirty flag if no lineage or division in any biosource */
5270 if (dotaxon && needstaxfix) {
5271 entityID = ObjMgrGetEntityIDForChoice (sep);
5272 ObjMgrSetDirtyFlag (entityID, TRUE);
5273 }
5274
5275 EntryMergeDupBioSources (sep); /* do before and after SE2A3 */
5276 if (dotaxon) {
5277 Taxon3ReplaceOrgInSeqEntry (sep, FALSE);
5278 }
5279 rsult = DoSeqEntryToAsn3 (sep, strip, correct, force, FALSE, mon);
5280 /*#ifdef USE_TAXON*/
5281 if (dotaxon) {
5282 MonitorStrValue (mon, "Closing Taxon");
5283 Update ();
5284 MonitorFree (mon);
5285 ArrowCursor ();
5286 Update ();
5287 }
5288 /*#endif*/
5289 ConvertFullLenSourceFeatToDesc (sep);
5290 ConvertFullLenPubFeatToDesc (sep);
5291 /* EntryStripSerialNumber(sep); */ /* strip citation serial numbers */
5292 MovePopPhyMutPubs (sep);
5293 EntryChangeGBSource (sep); /* remove redundant information in GBBlocks again */
5294 EntryCheckGBBlock (sep);
5295 /* SeqEntryMoveDbxrefs (sep); */ /* db_xref gbqual to sfp->dbxref */
5296 EntryMergeDupBioSources (sep);
5297 GetRidOfEmptyFeatsDescStrings (0, sep);
5298 GetRidOfLocusInSeqIds (0, sep);
5299 /* reindex, since CdEndCheck (from CdCheck) gets best overlapping gene */
5300 entityID = ObjMgrGetEntityIDForChoice (sep);
5301 SeqMgrClearFeatureIndexes (entityID, NULL);
5302 MakeSequinCleanupObject (sep);
5303 NormalizeDescriptorOrder (sep);
5304 SeqMgrIndexFeatures (entityID, NULL);
5305 CdCheck (sep, NULL);
5306 BasicSeqEntryCleanup (sep);
5307 ErrSetMessageLevel (sev);
5308 ErrClear ();
5309 ErrShow ();
5310 return rsult;
5311 }
5312
5313 typedef struct partialformdata {
5314 FEATURE_FORM_BLOCK
5315
5316 ValNodePtr featlist;
5317 LisT feature;
5318 PopuP change5;
5319 PopuP change3;
5320 PopuP orderJoinState;
5321 GrouP nucprotchoice;
5322 TexT findThis;
5323 CharPtr findThisStr;
5324 Int2 subtype;
5325 Int2 leftpolicy;
5326 Int2 rightpolicy;
5327 Int2 nucprotpolicy;
5328 Int2 orderjoinpolicy;
5329 ObjMgrPtr omp;
5330 ObjMgrTypePtr omtp;
5331 ButtoN extend5_btn;
5332 ButtoN extend3_btn;
5333 Boolean extend5;
5334 Boolean extend3;
5335 ButtoN leaveDlgUp;
5336 Boolean case_insensitive;
5337 ButtoN case_insensitive_btn;
5338 Boolean when_string_not_present;
5339 ButtoN when_string_not_present_btn;
5340 } PartialFormData, PNTR PartialFormPtr;
5341
5342 static Boolean CDSMeetsStringConstraint (SeqFeatPtr sfp,
5343 CharPtr findThisStr,
5344 Boolean case_insensitive)
5345 {
5346 BioseqPtr protbsp;
5347 SeqFeatPtr protsfp;
5348 SeqMgrFeatContext context;
5349 ProtRefPtr prp;
5350
5351 if (sfp == NULL) return FALSE;
5352 protbsp = BioseqFindFromSeqLoc (sfp->product);
5353 if (protbsp == NULL) return FALSE;
5354 protsfp = SeqMgrGetBestProteinFeature (protbsp, &context);
5355 if ((case_insensitive && StringISearch (context.label, findThisStr) != NULL)
5356 || (!case_insensitive && StringSearch (context.label, findThisStr) != NULL))
5357 {
5358 return TRUE;
5359 }
5360 if (protsfp == NULL) return FALSE;
5361 prp = (ProtRefPtr) protsfp->data.value.ptrvalue;
5362 if (prp->name != NULL)
5363 {
5364 if ((case_insensitive && StringISearch (prp->name->data.ptrvalue, findThisStr) != NULL)
5365 || (!case_insensitive && StringSearch (prp->name->data.ptrvalue, findThisStr) != NULL))
5366 {
5367 return TRUE;
5368 }
5369 }
5370 if (prp->desc != NULL)
5371 {
5372 if ((case_insensitive && StringISearch (prp->desc, findThisStr) != NULL)
5373 || (!case_insensitive && StringSearch (prp->desc, findThisStr) != NULL))
5374 {
5375 return TRUE;
5376 }
5377 }
5378 return FALSE;
5379 }
5380
5381 extern Boolean MeetsStringConstraint (SeqFeatPtr sfp,
5382 CharPtr findThisStr,
5383 Boolean case_insensitive)
5384 {
5385 GBQualPtr gbqp;
5386 GeneRefPtr grp;
5387 RnaRefPtr rrp;
5388 SeqMgrFeatContext context;
5389 Boolean have_context = FALSE;
5390
5391 /* If no string constraint, then everyone matches */
5392
5393 if (NULL == findThisStr)
5394 return TRUE;
5395
5396 /* Search for the string constraint */
5397 /* in the feature title field */
5398 if (StringISearch (sfp->title, findThisStr))
5399 return TRUE;
5400
5401 /* Search for the string constraint */
5402 /* in the feature comment field. */
5403
5404 if (StringISearch (sfp->comment, findThisStr))
5405 return TRUE;
5406
5407 /* Search for the string constraint */
5408 /* in GB qualifiers. */
5409
5410 gbqp = sfp->qual;
5411 while (NULL != gbqp)
5412 {
5413 if ((NULL != gbqp->val) && StringISearch (gbqp->val, findThisStr))
5414 return TRUE;
5415 gbqp = gbqp->next;
5416 }
5417
5418 if (SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, 0, 0, sfp, &context) != NULL)
5419 {
5420 if (!case_insensitive && StringSearch (context.label, findThisStr) != NULL)
5421 {
5422 return TRUE;
5423 }
5424 else if (case_insensitive && StringISearch (context.label, findThisStr) != NULL)
5425 {
5426 return TRUE;
5427 }
5428 have_context = TRUE;
5429 }
5430
5431 if (sfp->data.choice == SEQFEAT_GENE)
5432 {
5433 grp = sfp->data.value.ptrvalue;
5434 if (!case_insensitive &&
5435 (StringSearch (grp->locus, findThisStr) != NULL
5436 || StringSearch (grp->desc, findThisStr) != NULL
5437 || StringSearch (grp->desc, findThisStr) != NULL
5438 || StringSearch (grp->locus_tag, findThisStr) != NULL))
5439 {
5440 return TRUE;
5441 }
5442 else if (case_insensitive &&
5443 (StringISearch (grp->locus, findThisStr) != NULL
5444 || StringISearch (grp->desc, findThisStr) != NULL
5445 || StringISearch (grp->desc, findThisStr) != NULL
5446 || StringISearch (grp->locus_tag, findThisStr) != NULL))
5447 {
5448 return TRUE;
5449 }
5450 }
5451 else if (sfp->data.choice == SEQFEAT_CDREGION)
5452 {
5453 if (CDSMeetsStringConstraint (sfp, findThisStr, case_insensitive))
5454 return TRUE;
5455 }
5456 else if (sfp->data.choice == SEQFEAT_RNA)
5457 {
5458 rrp = sfp->data.value.ptrvalue;
5459
5460 if (rrp->ext.choice == 1) {
5461 if ((!case_insensitive && StringSearch ((CharPtr) rrp->ext.value.ptrvalue, findThisStr) != NULL)
5462 || (case_insensitive && StringISearch ((CharPtr) rrp->ext.value.ptrvalue, findThisStr) != NULL))
5463 {
5464 return TRUE;
5465 }
5466 }
5467 else if (rrp->type == 3 && rrp->ext.choice == 2 && have_context)
5468 {
5469 /* look for the label as it appears to the user */
5470 if ((!case_insensitive && StringNCmp(findThisStr, "tRNA-", 5) == 0
5471 && StringSearch (context.label, findThisStr + 5))
5472 || (case_insensitive && StringNICmp (findThisStr, "tRNA-", 5) == 0
5473 && StringISearch (context.label, findThisStr + 5)))
5474 {
5475 return TRUE;
5476 }
5477 }
5478 }
5479
5480 /* If we got to here, then the string constraint was not found */
5481
5482 return FALSE;
5483 }
5484
5485
5486 extern Boolean SetBestFrameByLocation (SeqFeatPtr sfp)
5487 {
5488 CdRegionPtr crp;
5489 Uint1 new_frame = 0, i;
5490 ByteStorePtr bs;
5491 Int4 lens [3];
5492 Int4 max;
5493 Boolean retval = TRUE;
5494
5495 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return FALSE;
5496
5497 crp = sfp->data.value.ptrvalue;
5498 if (crp == NULL) return FALSE;
5499
5500 max = 0;
5501 for (i = 1; i <= 3; i++) {
5502 crp->frame = i;
5503 bs = ProteinFromCdRegionEx (sfp, FALSE, FALSE);
5504 lens[i - 1] = BSLen (bs);
5505 BSFree (bs);
5506 if (lens[i - 1] > max) {
5507 max = lens[i - 1];
5508 new_frame = i;
5509 }
5510 }
5511 for (i = 1; i <= 3; i++) {
5512 if (lens [i - 1] == max && i != new_frame) {
5513 retval = FALSE;
5514 }
5515 }
5516 crp->frame = new_frame;
5517 return retval;
5518 }
5519
5520
5521 extern void SetBestFrame (SeqFeatPtr sfp)
5522 {
5523 SeqAlignPtr salp;
5524 CdRegionPtr crp;
5525 BioseqPtr old_prot, new_prot;
5526 ByteStorePtr bs = NULL;
5527 Int4 original_frame, test_frame;
5528 Boolean revcomp;
5529 ErrSev level;
5530 CharPtr seq_str1, seq_str2;
5531 Int4 best_len = -1, new_aln_len;
5532 Int4 best_frame = -1;
5533
5534 if (sfp == NULL || sfp->idx.subtype != FEATDEF_CDS) return;
5535
5536 crp = sfp->data.value.ptrvalue;
5537 if (crp == NULL) return;
5538
5539 old_prot = BioseqFindFromSeqLoc (sfp->product);
5540 if (old_prot == NULL) return;
5541
5542 new_prot = BioseqNew ();
5543 new_prot->id = SeqIdParse ("lcl|CdRgnTransl");
5544 new_prot->repr = Seq_repr_raw;
5545 new_prot->mol = Seq_mol_aa;
5546 new_prot->seq_data_type = Seq_code_ncbieaa;
5547 bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
5548 new_prot->seq_data = (SeqDataPtr) bs;
5549 new_prot->length = BSLen (bs);
5550
5551 original_frame = crp->frame;
5552
5553 /* suppress BLAST error messages when no similarity is found */
5554 level = ErrSetMessageLevel (SEV_MAX);
5555 seq_str1 = BSMerge((ByteStorePtr)(old_prot->seq_data), NULL);
5556 seq_str2 = BSMerge((ByteStorePtr)(new_prot->seq_data), NULL);
5557
5558 for (test_frame = 1; test_frame <= 3; test_frame ++)
5559 {
5560 new_prot->seq_data = SeqDataFree (new_prot->seq_data, new_prot->seq_data_type);
5561 crp->frame = test_frame;
5562 new_prot->seq_data = (SeqDataPtr) ProteinFromCdRegionEx (sfp, TRUE, FALSE);
5563 salp = Sequin_GlobalAlign2Seq (old_prot, new_prot, &revcomp);
5564 if (salp != NULL)
5565 {
5566 new_aln_len = SeqAlignLength (salp);
5567 if (new_aln_len > best_len)
5568 {
5569 best_len = new_aln_len;
5570 best_frame = test_frame;
5571 }
5572 salp = SeqAlignFree (salp);
5573 }
5574 }
5575
5576 if (best_frame > -1)
5577 {
5578 crp->frame = best_frame;
5579 }
5580 else
5581 {
5582 crp->frame = original_frame;
5583 }
5584
5585 ErrSetMessageLevel (level);
5586 BioseqFree (new_prot);
5587 }
5588
5589
5590 /*
5591 static Boolean AddOrgToDefGatherFunc (GatherContextPtr gcp)
5592
5593 {
5594 CharPtr def;
5595 CharPtr ptr;
5596 ValNodePtr sdp;
5597 CharPtr str;
5598 CharPtr text;
5599
5600 if (gcp == NULL || gcp->thisitem == NULL) return TRUE;
5601 if (gcp->thistype != OBJ_SEQDESC) return TRUE;
5602 text = (CharPtr) gcp->userdata;
5603 if (text == NULL || StringHasNoText (text)) return TRUE;
5604 sdp = (ValNodePtr) gcp->thisitem;
5605 if (sdp->choice != Seq_descr_title) return TRUE;
5606 def = (CharPtr) sdp->data.ptrvalue;
5607 if (StringHasNoText (def)) return TRUE;
5608
5609 ptr = StringISearch (def, text);
5610 if (ptr != NULL && ptr == def) return TRUE;
5611 str = MemNew ((StringLen (text) + StringLen (def) + 4) * sizeof (Char));
5612 if (str != NULL) {
5613 StringCpy (str, text);
5614 StringCat (str, " ");
5615 StringCat (str, def);
5616 sdp->data.ptrvalue = MemFree (sdp->data.ptrvalue);
5617 sdp->data.ptrvalue = str;
5618 ObjMgrSetDirtyFlag (gcp->entityID, TRUE);
5619 }
5620 return TRUE;
5621 }
5622 */
5623
5624 static void AppendOrgToString (Uint2 entityID, SeqDescrPtr sdp, CharPtr text)
5625
5626 {
5627 CharPtr def;
5628 CharPtr ptr;
5629 CharPtr str;
5630
5631 def = (CharPtr) sdp->data.ptrvalue;
5632 if (StringHasNoText (def)) return;
5633
5634 ptr = StringISearch (def, text);
5635 if (ptr != NULL && ptr == def) return;
5636 str = MemNew ((StringLen (text) + StringLen (def) + 4) * sizeof (Char));
5637 if (str != NULL) {
5638 StringCpy (str, text);
5639 StringCat (str, " ");
5640 StringCat (str, def);
5641 sdp->data.ptrvalue = MemFree (sdp->data.ptrvalue);
5642 sdp->data.ptrvalue = str;
5643 ObjMgrSetDirtyFlag (entityID, TRUE);
5644 }
5645 }
5646
5647 static void AddOrgToDefElement (Uint2 entityID, SeqEntryPtr sep, Int2 orgmod, Int2 subsource)
5648
5649 {
5650 BioSourcePtr biop;
5651 BioseqPtr bsp;
5652 BioseqSetPtr bssp;
5653 Char ch;
5654 SeqMgrDescContext dcontext;
5655 OrgModPtr mod;
5656 OrgNamePtr onp;
5657 OrgRefPtr orp;
5658 CharPtr ptr;
5659 SeqDescrPtr sdp;
5660 SubSourcePtr ssp;
5661 Char str [96];
5662 Char text [64];
5663 CharPtr title;
5664
5665 if (sep == NULL) return;
5666 if (IS_Bioseq_set (sep)) {
5667 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5668 if (bssp != NULL && (bssp->_class == 1 || bssp->_class == 2 ||
5669 bssp->_class == 4)) {
5670 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
5671 AddOrgToDefElement (entityID, sep, orgmod, subsource);
5672 }
5673 return;
5674 }
5675 }
5676 if (! IS_Bioseq (sep)) return;
5677 bsp = (BioseqPtr) sep->data.ptrvalue;
5678 biop = NULL;
5679 text [0] = '\0';
5680 str [0] = '\0';
5681 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
5682 if (sdp != NULL) {
5683 biop = (BioSourcePtr) sdp->data.ptrvalue;
5684 }
5685 if (biop == NULL) return;
5686 /* SeqEntryToBioSource (sep, NULL, str, sizeof (str) - 1, &biop); */
5687 if (orgmod == 0 && subsource == 0) {
5688 orp = biop->org;
5689 if (orp == NULL) return;
5690 StringNCpy_0 (str, orp->taxname, sizeof (str));
5691 /*
5692 ptr = StringSearch (str, "(");
5693 if (ptr != NULL) {
5694 *ptr = '\0';
5695 }
5696 */
5697 TrimSpacesAroundString (str);
5698 if ((StringICmp (str, "Human immunodeficiency virus type 1") == 0) ||
5699 (StringICmp (str, "Human immunodeficiency virus 1") == 0)) {
5700 StringCpy (str, "HIV-1");
5701 } else if ((StringICmp (str,"Human immunodeficiency virus type 2")==0) ||
5702 (StringICmp (str,"Human immunodeficiency virus 2") == 0)) {
5703 StringCpy (str, "HIV-2");
5704 }
5705 str [0] = TO_UPPER (str [0]);
5706 } else if (biop != NULL && biop->org != NULL) {
5707 text [0] = '\0';
5708 str [0] = '\0';
5709 orp = biop->org;
5710 if (orgmod > 0) {
5711 onp = orp->orgname;
5712 if (onp != NULL) {
5713 mod = onp->mod;
5714 while (mod != NULL) {
5715 if (mod->subtype == orgmod) {
5716 StringNCpy_0 (text, mod->subname, sizeof (text));
5717 StringNCpy_0 (str, GetOrgModQualName (mod->subtype), sizeof (str));
5718 }
5719 mod = mod->next;
5720 }
5721 }
5722 } else if (subsource > 0) {
5723 ssp = biop->subtype;
5724 while (ssp != NULL) {
5725 if (ssp->subtype == subsource) {
5726 StringNCpy_0 (text, ssp->name, sizeof (text));
5727 StringNCpy_0 (str, GetSubsourceQualName (ssp->subtype), sizeof (str));
5728 }
5729 ssp = ssp->next;
5730 }
5731 }
5732 if (StringHasNoText (text)) {
5733 str [0] = '\0';
5734 text [0] = '\0';
5735 } else {
5736 StringCat (str, " ");
5737 ptr = str;
5738 while (*ptr != '\0') {
5739 ch = *ptr;
5740 *ptr = TO_LOWER (ch);
5741 ptr++;
5742 }
5743 StringCat (str, text);
5744 }
5745 }
5746 /*
5747 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
5748 gs.seglevels = 1;
5749 gs.get_feats_location = FALSE;
5750 MemSet ((Pointer) (gs.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
5751 gs.ignore[OBJ_BIOSEQ] = FALSE;
5752 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
5753 gs.ignore[OBJ_SEQANNOT] = FALSE;
5754 gs.ignore[OBJ_SEQDESC] = FALSE;
5755 gs.scope = sep;
5756 GatherSeqEntry (sep, (Pointer) str, AddOrgToDefGatherFunc, &gs);
5757 */
5758 sdp = SeqEntryGetSeqDescr (sep, Seq_descr_title, NULL);
5759 if (sdp == NULL) {
5760 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_title, &dcontext);
5761 if (sdp == NULL) return;
5762 title = (CharPtr) sdp->data.ptrvalue;
5763 if (title == NULL) return;
5764 sdp = SeqDescrAdd (&(bsp->descr));
5765 if (sdp == NULL) return;
5766 sdp->choice = Seq_descr_title;
5767 sdp->data.ptrvalue = StringSave (title);
5768 }
5769 if (sdp == NULL) return;
5770 AppendOrgToString (entityID, sdp, str);
5771 }
5772
5773 static void AddOrgToDef (Uint2 entityID, SeqEntryPtr sep, Int2 orgmod, Int2 subsource)
5774
5775 {
5776 BioseqSetPtr bssp;
5777
5778 if (sep == NULL) return;
5779 if (IS_Bioseq_set (sep)) {
5780 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5781 if (bssp != NULL && (bssp->_class == 7 ||
5782 (IsPopPhyEtcSet (bssp->_class)))) {
5783 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
5784 AddOrgToDef (entityID, sep, orgmod, subsource);
5785 }
5786 return;
5787 }
5788 }
5789 AddOrgToDefElement (entityID, sep, orgmod, subsource);
5790 }
5791
5792 extern void CommonAddOrgOrModsToDefLines (IteM i, Int2 orgmod, Int2 subsource, ButtoN b)
5793
5794 {
5795 BaseFormPtr bfp;
5796 SeqEntryPtr sep;
5797
5798 if (b != NULL) {
5799 bfp = GetObjectExtra (b);
5800 } else {
5801 #ifdef WIN_MAC
5802 bfp = currentFormDataPtr;
5803 #else
5804 bfp = GetObjectExtra (i);
5805 #endif
5806 }
5807 if (bfp == NULL) return;
5808 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5809 if (sep == NULL) return;
5810 WatchCursor ();
5811 Update ();
5812 AddOrgToDef (bfp->input_entityID, sep, orgmod, subsource);
5813 ArrowCursor ();
5814 Update ();
5815 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5816 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5817 }
5818
5819 static void RemoveAlignmentCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
5820
5821 {
5822 BioseqPtr bsp;
5823 BioseqSetPtr bssp;
5824 SeqAlignPtr nextsalp;
5825 SeqAnnotPtr nextsap;
5826 Pointer PNTR prevsalp;
5827 Pointer PNTR prevsap;
5828 SeqAlignPtr salp;
5829 SeqAnnotPtr sap;
5830
5831 if (sep == NULL || sep->data.ptrvalue == NULL) return;
5832 if (IS_Bioseq (sep)) {
5833 bsp = (BioseqPtr) sep->data.ptrvalue;
5834 sap = bsp->annot;
5835 prevsap = (Pointer PNTR) &(bsp->annot);
5836 } else if (IS_Bioseq_set (sep)) {
5837 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5838 sap = bssp->annot;
5839 prevsap = (Pointer PNTR) &(bssp->annot);
5840 } else return;
5841 while (sap != NULL) {
5842 nextsap = sap->next;
5843 if (sap->type == 2) {
5844 salp = (SeqAlignPtr) sap->data;
5845 prevsalp = (Pointer PNTR) &(sap->data);
5846 while (salp != NULL) {
5847 nextsalp = salp->next;
5848 *(prevsalp) = salp->next;
5849 salp->next = NULL;
5850 SeqAlignFree (salp);
5851 salp = nextsalp;
5852 }
5853 }
5854 if (sap->data == NULL) {
5855 *(prevsap) = sap->next;
5856 sap->next = NULL;
5857 SeqAnnotFree (sap);
5858 } else {
5859 prevsap = (Pointer PNTR) &(sap->next);
5860 }
5861 sap = nextsap;
5862 }
5863 }
5864
5865 extern void RemoveAlignment (IteM i)
5866
5867 {
5868 BaseFormPtr bfp;
5869 SeqEntryPtr sep;
5870
5871 #ifdef WIN_MAC
5872 bfp = currentFormDataPtr;
5873 #else
5874 bfp = GetObjectExtra (i);
5875 #endif
5876 if (bfp == NULL) return;
5877 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5878 if (sep == NULL) return;
5879 SeqEntryExplore (sep, NULL, RemoveAlignmentCallback);
5880 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5881 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5882 ObjMgrDeSelect (0, 0, 0, 0, NULL);
5883 Update ();
5884 }
5885
5886 static void RemoveGraphCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
5887
5888 {
5889 BioseqPtr bsp;
5890 BioseqSetPtr bssp;
5891 SeqAnnotPtr nextsap;
5892 SeqGraphPtr nextsgp;
5893 Pointer PNTR prevsap;
5894 Pointer PNTR prevsgp;
5895 SeqAnnotPtr sap;
5896 SeqGraphPtr sgp;
5897
5898 if (sep == NULL || sep->data.ptrvalue == NULL) return;
5899 if (IS_Bioseq (sep)) {
5900 bsp = (BioseqPtr) sep->data.ptrvalue;
5901 sap = bsp->annot;
5902 prevsap = (Pointer PNTR) &(bsp->annot);
5903 } else if (IS_Bioseq_set (sep)) {
5904 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5905 sap = bssp->annot;
5906 prevsap = (Pointer PNTR) &(bssp->annot);
5907 } else return;
5908 while (sap != NULL) {
5909 nextsap = sap->next;
5910 if (sap->type == 3) {
5911 sgp = (SeqGraphPtr) sap->data;
5912 prevsgp = (Pointer PNTR) &(sap->data);
5913 while (sgp != NULL) {
5914 nextsgp = sgp->next;
5915 if (sgp->flags [2] >= 1 && sgp->flags [2] <= 3) {
5916 *(prevsgp) = sgp->next;
5917 sgp->next = NULL;
5918 SeqGraphFree (sgp);
5919 } else {
5920 prevsgp = (Pointer PNTR) &(sgp->next);
5921 }
5922 sgp = nextsgp;
5923 }
5924 }
5925 if (sap->data == NULL) {
5926 *(prevsap) = sap->next;
5927 sap->next = NULL;
5928 SeqAnnotFree (sap);
5929 } else {
5930 prevsap = (Pointer PNTR) &(sap->next);
5931 }
5932 sap = nextsap;
5933 }
5934 }
5935
5936 extern void RemoveGraph (IteM i)
5937
5938 {
5939 BaseFormPtr bfp;
5940 SeqEntryPtr sep;
5941
5942 #ifdef WIN_MAC
5943 bfp = currentFormDataPtr;
5944 #else
5945 bfp = GetObjectExtra (i);
5946 #endif
5947 if (bfp == NULL) return;
5948 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5949 if (sep == NULL) return;
5950 SeqEntryExplore (sep, NULL, RemoveGraphCallback);
5951 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5952 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5953 ObjMgrDeSelect (0, 0, 0, 0, NULL);
5954 Update ();
5955 }
5956
5957 static void RemoveSeqAnnotIDsCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
5958
5959 {
5960 BioseqPtr bsp;
5961 BioseqSetPtr bssp;
5962 SeqAnnotPtr nextsap;
5963 Pointer PNTR prevsap;
5964 SeqAnnotPtr sap;
5965 SeqIdPtr sip;
5966
5967 if (sep == NULL || sep->data.ptrvalue == NULL) return;
5968 if (IS_Bioseq (sep)) {
5969 bsp = (BioseqPtr) sep->data.ptrvalue;
5970 sap = bsp->annot;
5971 prevsap = (Pointer PNTR) &(bsp->annot);
5972 } else if (IS_Bioseq_set (sep)) {
5973 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5974 sap = bssp->annot;
5975 prevsap = (Pointer PNTR) &(bssp->annot);
5976 } else return;
5977 while (sap != NULL) {
5978 nextsap = sap->next;
5979 if (sap->type == 4) {
5980 sip = (SeqIdPtr) sap->data;
5981 SeqIdSetFree (sip);
5982 sap->data = NULL;
5983 }
5984 if (sap->data == NULL) {
5985 *(prevsap) = sap->next;
5986 sap->next = NULL;
5987 SeqAnnotFree (sap);
5988 } else {
5989 prevsap = (Pointer PNTR) &(sap->next);
5990 }
5991 sap = nextsap;
5992 }
5993 }
5994
5995 extern void RemoveSeqAnnotIDs (IteM i)
5996
5997 {
5998 BaseFormPtr bfp;
5999 SeqEntryPtr sep;
6000
6001 #ifdef WIN_MAC
6002 bfp = currentFormDataPtr;
6003 #else
6004 bfp = GetObjectExtra (i);
6005 #endif
6006 if (bfp == NULL) return;
6007 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6008 if (sep == NULL) return;
6009 SeqEntryExplore (sep, NULL, RemoveSeqAnnotIDsCallback);
6010 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6011 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
6012 ObjMgrDeSelect (0, 0, 0, 0, NULL);
6013 Update ();
6014 }
6015
6016 static void RemoveSeqAnnotLOCsCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
6017
6018 {
6019 BioseqPtr bsp;
6020 BioseqSetPtr bssp;
6021 SeqAnnotPtr nextsap;
6022 Pointer PNTR prevsap;
6023 SeqAnnotPtr sap;
6024 SeqLocPtr slp;
6025
6026 if (sep == NULL || sep->data.ptrvalue == NULL) return;
6027 if (IS_Bioseq (sep)) {
6028 bsp = (BioseqPtr) sep->data.ptrvalue;
6029 sap = bsp->annot;
6030 prevsap = (Pointer PNTR) &(bsp->annot);
6031 } else if (IS_Bioseq_set (sep)) {
6032 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6033 sap = bssp->annot;
6034 prevsap = (Pointer PNTR) &(bssp->annot);
6035 } else return;
6036 while (sap != NULL) {
6037 nextsap = sap->next;
6038 if (sap->type == 4) {
6039 slp = (SeqLocPtr) sap->data;
6040 SeqLocSetFree (slp);
6041 sap->data = NULL;
6042 }
6043 if (sap->data == NULL) {
6044 *(prevsap) = sap->next;
6045 sap->next = NULL;
6046 SeqAnnotFree (sap);
6047 } else {
6048 prevsap = (Pointer PNTR) &(sap->next);
6049 }
6050 sap = nextsap;
6051 }
6052 }
6053
6054 extern void RemoveSeqAnnotLOCs (IteM i)
6055
6056 {
6057 BaseFormPtr bfp;
6058 SeqEntryPtr sep;
6059
6060 #ifdef WIN_MAC
6061 bfp = currentFormDataPtr;
6062 #else
6063 bfp = GetObjectExtra (i);
6064 #endif
6065 if (bfp == NULL) return;
6066 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6067 if (sep == NULL) return;
6068 SeqEntryExplore (sep, NULL, RemoveSeqAnnotLOCsCallback);
6069 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6070 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
6071 ObjMgrDeSelect (0, 0, 0, 0, NULL);
6072 Update ();
6073 }
6074
6075 static void MarkProteinCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
6076
6077 {
6078 BioseqPtr bsp;
6079 ValNodePtr PNTR vnpp;
6080
6081 if (mydata == NULL) return;
6082 if (sep == NULL || sep->data.ptrvalue == NULL) return;
6083 vnpp = (ValNodePtr PNTR) mydata;
6084 if (vnpp == NULL) return;
6085 if (IS_Bioseq (sep)) {
6086 bsp = (BioseqPtr) sep->data.ptrvalue;
6087 if (ISA_aa (bsp->mol)) {
6088 ValNodeAddPointer (vnpp, 0, (Pointer) bsp);
6089 }
6090 }
6091 }
6092
6093 static void RemoveProteinsAndOptionallyRenormalize (IteM i, Boolean renormalize)
6094
6095 {
6096 BaseFormPtr bfp;
6097 BioseqPtr bsp;
6098 Uint4 itemID;
6099 ObjMgrDataPtr omdptop;
6100 ObjMgrData omdata;
6101 OMProcControl ompc;
6102 Uint2 parenttype;
6103 Pointer parentptr;
6104 SeqEntryPtr sep;
6105 ValNodePtr tmp;
6106 ValNodePtr vnp;
6107
6108 #ifdef WIN_MAC
6109 bfp = currentFormDataPtr;
6110 #else
6111 bfp = GetObjectExtra (i);
6112 #endif
6113 if (bfp == NULL) return;
6114 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6115 if (sep == NULL) return;
6116 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
6117 GetSeqEntryParent (sep, &parentptr, &parenttype);
6118 vnp = NULL;
6119 SeqEntryExplore (sep, (Pointer) &vnp, MarkProteinCallback);
6120 for (tmp = vnp; tmp != NULL; tmp = tmp->next) {
6121 bsp = (BioseqPtr) tmp->data.ptrvalue;
6122 itemID = GetItemIDGivenPointer (bfp->input_entityID, OBJ_BIOSEQ, (Pointer) bsp);
6123 if (itemID > 0) {
6124 MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
6125 ompc.do_not_reload_from_cache = TRUE;
6126 ompc.input_entityID = bfp->input_entityID;
6127 ompc.input_itemID = itemID;
6128 ompc.input_itemtype = OBJ_BIOSEQ;
6129 if (! DetachDataForProc (&ompc, FALSE)) {
6130 Message (MSG_POSTERR, "DetachDataForProc failed");
6131 }
6132 }
6133 }
6134 ValNodeFree (vnp);
6135 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
6136 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
6137 if (renormalize)
6138 {
6139 RenormalizeNucProtSets (sep, TRUE);
6140 }
6141 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6142 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
6143 ObjMgrDeSelect (0, 0, 0, 0, NULL);
6144 Update ();
6145 }
6146
6147 extern void RemoveProteins (IteM i)
6148 {
6149 RemoveProteinsAndOptionallyRenormalize (i, FALSE);
6150 }
6151
6152 extern void RemoveProteinsAndRenormalize (IteM i)
6153 {
6154 RemoveProteinsAndOptionallyRenormalize (i, TRUE);
6155 }
6156
6157 #define EDIT_FIVE_PRIME 1
6158 #define EDIT_THREE_PRIME 2
6159
6160 #define ADD_TO_END 1
6161 #define TRIM_FROM_END 2
6162
6163 #define TRIM_BY_SEQUENCE 1
6164 #define TRIM_BY_COUNT 2
6165
6166 typedef struct edseqendsdata {
6167 FEATURE_FORM_BLOCK
6168
6169 TexT seq;
6170 TexT genename;
6171 GrouP whichend;
6172 GrouP addOrTrim;
6173 Int2 addOrTrimBool;
6174 GrouP trimBy;
6175 Int2 trimByBool;
6176 Int4 trimCount;
6177 TexT trimCountText;
6178 ButtoN extendfeat;
6179 LisT nuc_sequence_list_ctrl;
6180 ButtoN addCitSub;
6181 CharPtr seqstr;
6182 CharPtr genestr;
6183 Int2 endval;
6184 Int2 frameshift;
6185 Boolean adjustframe;
6186 Boolean extendflag;
6187 BioseqPtr extendedthis;
6188 SeqEntryPtr sep;
6189 Boolean rsult;
6190 } EditSeqEnds, PNTR EditSeqPtr;
6191
6192 static Boolean GeneFindByNameFunc (GatherContextPtr gcp)
6193
6194 {
6195 EditSeqPtr esp;
6196 GeneRefPtr grp;
6197 SeqFeatPtr sfp;
6198
6199 if (gcp == NULL) return TRUE;
6200 esp = (EditSeqPtr) gcp->userdata;
6201 if (esp == NULL) return TRUE;
6202 if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
6203 sfp = (SeqFeatPtr) gcp->thisitem;
6204 if (sfp == NULL) return TRUE;
6205 if (sfp->data.choice != SEQFEAT_GENE) return TRUE;
6206 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
6207 if (grp == NULL) return TRUE;
6208 if (StringICmp (grp->locus, esp->genestr) == 0) {
6209 esp->rsult = TRUE;
6210 }
6211 return TRUE;
6212 }
6213
6214 static Boolean EditSeqEntryHasGene (BioseqPtr bsp, SeqEntryPtr sep, EditSeqPtr esp)
6215
6216 {
6217 GatherScope gs;
6218
6219 if (esp->input_entityID == 0 || esp->sep == NULL) return FALSE;
6220 if (StringHasNoText (esp->genestr)) return TRUE;
6221 esp->rsult = FALSE;
6222 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
6223 gs.seglevels = 1;
6224 gs.get_feats_location = TRUE;
6225 gs.scope = sep;
6226 MemSet ((Pointer)(gs.ignore), (int) (TRUE), (size_t) (OBJ_MAX * sizeof (Boolean)));
6227 gs.ignore [OBJ_BIOSEQ] = FALSE;
6228 gs.ignore [OBJ_BIOSEQ_SEG] = FALSE;
6229 gs.ignore [OBJ_SEQFEAT] = FALSE;
6230 gs.ignore [OBJ_SEQANNOT] = FALSE;
6231 GatherEntity (esp->input_entityID, (Pointer) esp, GeneFindByNameFunc, &gs);
6232 gs.target = SeqLocFree (gs.target);
6233 return esp->rsult;
6234 }
6235
6236 static Boolean FixACDSFunc (GatherContextPtr gcp)
6237
6238 {
6239 SeqFeatPtr bestprot;
6240 ByteStorePtr bs;
6241 BioseqPtr bsp;
6242 Char ch;
6243 CdRegionPtr crp;
6244 EditSeqPtr esp;
6245 Int2 frame;
6246 Boolean partial5;
6247 Boolean partial3;
6248 CharPtr prot;
6249 CharPtr ptr;
6250 SeqEntryPtr sep;
6251 SeqFeatPtr sfp;
6252 SeqIdPtr sip;
6253 SeqLocPtr slp;
6254
6255 if (gcp == NULL) return TRUE;
6256 esp = (EditSeqPtr) gcp->userdata;
6257 if (esp == NULL) return TRUE;
6258 if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
6259 sfp = (SeqFeatPtr) gcp->thisitem;
6260 if (sfp == NULL) return TRUE;
6261 if (sfp->data.choice != SEQFEAT_CDREGION) return TRUE;
6262 slp = SeqLocFindNext (sfp->location, NULL);
6263 if (slp == NULL) return TRUE;
6264 CheckSeqLocForPartial (slp, &partial5, &partial3);
6265 sip = SeqLocId (slp);
6266 if (sip == NULL) return TRUE;
6267 bsp = BioseqFind (sip);
6268 if (bsp == NULL || bsp != esp->extendedthis) return TRUE;
6269 if (esp->adjustframe) {
6270 if (GetOffsetInBioseq (slp, bsp, SEQLOC_START) != 0) return TRUE;
6271 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
6272 if (crp == NULL) return TRUE;
6273 frame = crp->frame;
6274 if (frame == 0)
6275 frame = 1;
6276 if (esp->addOrTrimBool == ADD_TO_END)
6277 {
6278 frame--;
6279 frame += esp->frameshift;
6280 crp->frame = (frame % 3) + 1;
6281 }
6282 else if (esp->addOrTrimBool == TRIM_FROM_END)
6283 {
6284 frame = ABS(frame - esp->frameshift);
6285 crp->frame = 3 - (frame % 3);
6286 }
6287 } else {
6288 if (GetOffsetInBioseq (slp, bsp, SEQLOC_STOP) != bsp->length - 1)
6289 return TRUE;
6290 }
6291 sip = SeqLocId (sfp->product);
6292 if (sip == NULL) return TRUE;
6293 bsp = BioseqFind (sip);
6294 if (bsp == NULL) return TRUE;
6295 if (bsp->repr != Seq_repr_raw) return TRUE;
6296 if (bsp->mol != Seq_mol_aa) return TRUE;
6297 bestprot = FindBestProtein (esp->input_entityID, sfp->product);
6298 bs = ProteinFromCdRegionEx (sfp, FALSE, FALSE);
6299 if (bs == NULL) return TRUE;
6300 prot = BSMerge (bs, NULL);
6301 bs = BSFree (bs);
6302 if (prot == NULL) return TRUE;
6303 ptr = prot;
6304 ch = *ptr;
6305 while (ch != '\0') {
6306 *ptr = TO_UPPER (ch);
6307 ptr++;
6308 ch = *ptr;
6309 }
6310 bs = BSNew (1000);
6311 if (bs != NULL) {
6312 ptr = prot;
6313 /*
6314 if (prot [0] == '-') {
6315 ptr++;
6316 }
6317 */
6318 BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
6319 bsp->seq_data = SeqDataFree (bsp->seq_data, bsp->seq_data_type);
6320 bsp->seq_data = (SeqDataPtr) bs;
6321 bsp->length = BSLen (bs);
6322 bsp->seq_data_type = Seq_code_ncbieaa;
6323 }
6324 if (bestprot == NULL) return TRUE;
6325 sep = SeqMgrGetSeqEntryForData (bsp);
6326 bestprot->location = SeqLocFree (bestprot->location);
6327 bestprot->location = CreateWholeInterval (sep);
6328 SetSeqLocPartial (bestprot->location, partial5, partial3);
6329 return TRUE;
6330 }
6331
6332 static void FixAndRetranslateCDSs (BioseqPtr bsp, SeqEntryPtr sep,
6333 EditSeqPtr esp, Boolean adjustframe)
6334
6335 {
6336 GatherScope gs;
6337
6338 if (esp->input_entityID == 0 || esp->sep == NULL) return;
6339 esp->adjustframe = adjustframe;
6340 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
6341 gs.seglevels = 1;
6342 gs.get_feats_location = FALSE;
6343 gs.scope = sep;
6344 MemSet ((Pointer)(gs.ignore), (int) (TRUE), (size_t) (OBJ_MAX * sizeof (Boolean)));
6345 gs.ignore [OBJ_BIOSEQ] = FALSE;
6346 gs.ignore [OBJ_BIOSEQ_SEG] = FALSE;
6347 gs.ignore [OBJ_SEQFEAT] = FALSE;
6348 gs.ignore [OBJ_SEQANNOT] = FALSE;
6349 GatherEntity (esp->input_entityID, (Pointer) esp, FixACDSFunc, &gs);
6350 gs.target = SeqLocFree (gs.target);
6351 }
6352
6353 static ValNodePtr CollectAndExtendSingleBaseFeatures (BioseqPtr bsp, Int2 whichend, Int4 len)
6354
6355 {
6356 SeqMgrFeatContext context;
6357 ValNodePtr head = NULL;
6358 SeqFeatPtr sfp;
6359 SeqLocPtr slp;
6360 SeqPntPtr spp;
6361
6362 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
6363 while (sfp != NULL) {
6364 if (whichend == 1 && context.numivals == 1 && context.right == 0) {
6365 slp = sfp->location;
6366 if (slp != NULL && slp->choice == SEQLOC_PNT && slp->next == NULL) {
6367 spp = (SeqPntPtr) slp->data.ptrvalue;
6368 if (spp != NULL && spp->point == 0) {
6369 spp->point = 1;
6370 ValNodeAddPointer (&head, 1, (Pointer) sfp);
6371 }
6372 }
6373 } else if (whichend == 2 && context.numivals == 1 && context.left == bsp->length - 1) {
6374 slp = sfp->location;
6375 if (slp != NULL && slp->choice == SEQLOC_PNT && slp->next == NULL) {
6376 spp = (SeqPntPtr) slp->data.ptrvalue;
6377 if (spp != NULL && spp->point == bsp->length - 1) {
6378 spp->point = bsp->length - 2;
6379 ValNodeAddPointer (&head, 2, (Pointer) sfp);
6380 }
6381 }
6382 }
6383 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
6384 }
6385
6386 return head;
6387 }
6388
6389 static void ReadjustSingleBaseFeatures (ValNodePtr head, BioseqPtr bsp, Int2 whichend, Int4 len)
6390
6391 {
6392 SeqFeatPtr sfp;
6393 SeqIntPtr sintp;
6394 SeqLocPtr slp;
6395 SeqPntPtr spp;
6396 ValNodePtr vnp;
6397
6398 for (vnp = head; vnp != NULL; vnp = vnp->next) {
6399 sfp = (SeqFeatPtr) vnp->data.ptrvalue;
6400 if (sfp != NULL) {
6401 slp = sfp->location;
6402 if (slp != NULL && slp->choice == SEQLOC_PNT && slp->next == NULL) {
6403 spp = (SeqPntPtr) slp->data.ptrvalue;
6404 if (spp != NULL) {
6405 if (whichend == 1) {
6406 sintp = SeqIntNew ();
6407 if (sintp != NULL) {
6408 sintp->from = 0;
6409 sintp->to = spp->point - 1;
6410 sintp->strand = spp->strand;
6411 sintp->id = spp->id;
6412 spp->id = NULL;
6413 sintp->if_from = spp->fuzz;
6414 spp->fuzz = NULL;
6415 slp->choice = SEQLOC_INT;
6416 slp->data.ptrvalue = (Pointer) sintp;
6417 SeqPntFree (spp);
6418 }
6419 } else if (whichend == 2) {
6420 sintp = SeqIntNew ();
6421 if (sintp != NULL) {
6422 sintp->from = spp->point + 1;
6423 sintp->to = spp->point + 1 + len;
6424 sintp->strand = spp->strand;
6425 sintp->id = spp->id;
6426 spp->id = NULL;
6427 sintp->if_to = spp->fuzz;
6428 spp->fuzz = NULL;
6429 slp->choice = SEQLOC_INT;
6430 slp->data.ptrvalue = (Pointer) sintp;
6431 SeqPntFree (spp);
6432 }
6433 }
6434 }
6435 }
6436 }
6437 }
6438 }
6439
6440 static void TrimFromSequenceEnd (EditSeqPtr esp,
6441 SeqEntryPtr sep,
6442 BioseqPtr bsp)
6443 {
6444 CharPtr currSeqStr;
6445 Int2 length;
6446 Int4 pos;
6447 Int4 trim_length;
6448
6449 /* Get the current sequence string */
6450
6451 currSeqStr = GetSequenceByBsp (bsp);
6452
6453 /* Trim from either the 5' end (i.e., */
6454 /* the beginning of the string... */
6455
6456 if (esp->endval == EDIT_FIVE_PRIME)
6457 {
6458 /* Find end point */
6459
6460 if (esp->trimByBool == TRIM_BY_SEQUENCE)
6461 {
6462 length = StringLen (esp->seqstr);
6463 if (StringNICmp (esp->seqstr, currSeqStr, length) != 0)
6464 return;
6465 pos = length - 1;
6466 trim_length = length;
6467 }
6468 else if (esp->trimByBool == TRIM_BY_COUNT)
6469 {
6470 pos = esp->trimCount - 1;
6471 trim_length = esp->trimCount;
6472 }
6473 else
6474 return;
6475
6476 /* Trim from beginning of string to end point */
6477
6478 esp->frameshift = trim_length;
6479 BioseqDelete (bsp->id, 0, pos, TRUE, FALSE);
6480 esp->extendedthis = bsp;
6481 FixAndRetranslateCDSs (bsp, sep, esp, TRUE);
6482
6483 /* trim quality scores */
6484 TrimQualityScores (bsp, trim_length, TRUE);
6485 }
6486
6487 /* .. or the 3' end (i.e., the */
6488 /* end of the string. */
6489
6490 else if (esp->endval == EDIT_THREE_PRIME)
6491 {
6492 /* Find trim point */
6493
6494 if (esp->trimByBool == TRIM_BY_SEQUENCE)
6495 {
6496 length = StringLen (esp->seqstr);
6497 pos = bsp->length - length;
6498 if (StringICmp (esp->seqstr, &currSeqStr[pos]) != 0)
6499 return;
6500 trim_length = length;
6501 }
6502 else if (esp->trimByBool == TRIM_BY_COUNT)
6503 {
6504 pos = bsp->length - esp->trimCount;
6505 trim_length = esp->trimCount;
6506 }
6507 else
6508 return;
6509
6510 /* Trim from there to end of string */
6511
6512 BioseqDelete (bsp->id, pos, bsp->length - 1, TRUE, FALSE);
6513 esp->extendedthis = bsp;
6514 FixAndRetranslateCDSs (bsp, sep, esp, FALSE);
6515
6516 /* trim quality scores */
6517 TrimQualityScores (bsp, trim_length, FALSE);
6518 }
6519 }
6520
6521 static void
6522 AddToSequenceEnd
6523 (EditSeqPtr esp,
6524 SeqEntryPtr sep,
6525 BioseqPtr bsp,
6526 LogInfoPtr lip)
6527 {
6528 ValNodePtr head;
6529 Int4 len;
6530 Int4 pos;
6531 Uint1 residue;
6532 SeqPortPtr spp;
6533 CharPtr str;
6534 Char terminal [2];
6535
6536 pos = 0;
6537 if (esp->endval == 2) {
6538 pos = bsp->length;
6539 }
6540 if (esp->extendflag) {
6541 esp->frameshift = 0;
6542 terminal [0] = '\0';
6543 terminal [1] = '\0';
6544 residue = 0;
6545 if (esp->endval == 2) {
6546 spp = SeqPortNew (bsp, bsp->length - 1, -1, 0, Seq_code_iupacna);
6547 } else {
6548 spp = SeqPortNew (bsp, 0, -1, 0, Seq_code_iupacna);
6549 }
6550 if (spp != NULL) {
6551 residue = SeqPortGetResidue (spp);
6552 if (IS_residue (residue)) {
6553 terminal [0] = TO_LOWER ((Char) residue);
6554 }
6555 }
6556 SeqPortFree (spp);
6557 str = MemNew ((size_t) (StringLen (esp->seqstr) + 4));
6558 if (str != NULL) {
6559 head = NULL;
6560 if (esp->endval == 2) {
6561 esp->extendedthis = bsp;
6562 StringCpy (str, terminal);
6563 StringCat (str, esp->seqstr);
6564 len = StringLen (esp->seqstr);
6565 pos = bsp->length - 1;
6566 head = CollectAndExtendSingleBaseFeatures (bsp, 2, len);
6567 insertchar (str, pos, bsp->id, bsp->mol, FALSE);
6568 BioseqDelete (bsp->id, bsp->length - 1, bsp->length - 1,
6569 TRUE, FALSE);
6570 ReadjustSingleBaseFeatures (head, bsp, 2, len);
6571 FixAndRetranslateCDSs (bsp, sep, esp, FALSE);
6572 } else {
6573 esp->frameshift = (Int2) StringLen (esp->seqstr);
6574 esp->extendedthis = bsp;
6575 StringCpy (str, esp->seqstr);
6576 StringCat (str, terminal);
6577 len = StringLen (esp->seqstr);
6578 pos = 1;
6579 head = CollectAndExtendSingleBaseFeatures (bsp, 1, len);
6580 insertchar (str, pos, bsp->id, bsp->mol, FALSE);
6581 BioseqDelete (bsp->id, 0, 0, TRUE, FALSE);
6582 ReadjustSingleBaseFeatures (head, bsp, 1, len);
6583 FixAndRetranslateCDSs (bsp, sep, esp, TRUE);
6584 }
6585 ValNodeFree (head);
6586 if (lip != NULL) {
6587 RemoveQualityScores (bsp, lip->fp, &(lip->data_in_log));
6588 }
6589 }
6590 MemFree (str);
6591 } else {
6592 insertchar (esp->seqstr, pos, bsp->id, bsp->mol, FALSE);
6593 if (lip != NULL) {
6594 RemoveQualityScores (bsp, lip->fp, &(lip->data_in_log));
6595 }
6596 }
6597 }
6598
6599
6600 static void DoEditSeqEndsProc (ButtoN b)
6601
6602 {
6603 Char ch;
6604 EditSeqPtr esp;
6605 CharPtr p, q;
6606 CharPtr tempStr;
6607 ValNodePtr sip_list, vnp;
6608 SeqIdPtr sip;
6609 BioseqPtr bsp;
6610 SeqEntryPtr sep;
6611 Boolean add_cit_subs = FALSE;
6612 LogInfoPtr lip;
6613
6614 esp = (EditSeqPtr) GetObjectExtra (b);
6615 if (esp == NULL) {
6616 Remove (ParentWindow (b));
6617 return;
6618 }
6619 sip_list = GetSelectedSequenceList (esp->nuc_sequence_list_ctrl);
6620 if (sip_list == NULL)
6621 {
6622 Message (MSG_ERROR, "You have not specified any sequences to edit!");
6623 return;
6624 }
6625
6626 Hide (esp->form);
6627 Update ();
6628 esp->seqstr = SaveStringFromText (esp->seq);
6629 p = esp->seqstr;
6630 if (p != NULL) {
6631 /* remove any non-sequence characters */
6632 q = p;
6633 ch = *p;
6634 while (ch != '\0') {
6635 if (IS_ALPHA (ch)) {
6636 *q = ch;
6637 q++;
6638 }
6639 p++;
6640 ch = *p;
6641 }
6642 *q = '\0';
6643 }
6644 esp->genestr = SaveStringFromText (esp->genename);
6645 esp->endval = GetValue (esp->whichend);
6646 esp->extendflag = GetStatus (esp->extendfeat);
6647 esp->addOrTrimBool = GetValue (esp->addOrTrim);
6648 esp->trimByBool = GetValue (esp->trimBy);
6649 tempStr = SaveStringFromText (esp->trimCountText);
6650 if (tempStr != NULL)
6651 esp->trimCount = atoi (tempStr);
6652 else
6653 esp->trimCount = 0;
6654
6655 add_cit_subs = GetStatus (esp->addCitSub);
6656
6657 lip = OpenLog ("Quality Scores Affected");
6658 for (vnp = sip_list; vnp != NULL; vnp = vnp->next)
6659 {
6660 sip = (SeqIdPtr) vnp->data.ptrvalue;
6661 bsp = BioseqFind (sip);
6662 sep = SeqMgrGetSeqEntryForData (bsp);
6663 if (bsp != NULL && sep != NULL && EditSeqEntryHasGene (bsp, sep, esp))
6664 {
6665 if (esp->addOrTrimBool == 1)
6666 AddToSequenceEnd (esp, sep, bsp, lip);
6667 else
6668 TrimFromSequenceEnd (esp, sep, bsp);
6669 if (add_cit_subs)
6670 {
6671 AddCitSubToUpdatedSequence (bsp, esp->input_entityID, kSubmitterUpdateText);
6672 }
6673 }
6674 }
6675 CloseLog (lip);
6676 lip = FreeLog (lip);
6677
6678 MemFree (esp->seqstr);
6679 MemFree (esp->genestr);
6680 ObjMgrSetDirtyFlag (esp->input_entityID, TRUE);
6681 ObjMgrSendMsg (OM_MSG_UPDATE, esp->input_entityID, 0, 0);
6682 Remove (esp->form);
6683 }
6684
6685 static void EditSeqMessageProc (ForM f, Int2 mssg)
6686
6687 {
6688 EditSeqPtr esp;
6689
6690 esp = (EditSeqPtr) GetObjectExtra (f);
6691 if (esp != NULL) {
6692 if (esp->appmessage != NULL) {
6693 esp->appmessage (f, mssg);
6694 }
6695 }
6696 }
6697
6698 static void ChangeAddOrTrim_Callback (GrouP g)
6699
6700 {
6701 EditSeqPtr esp;
6702 Int2 val;
6703 Int2 trimByState;
6704
6705 val = GetValue (g);
6706 esp = GetObjectExtra (g);
6707
6708 switch (val) {
6709 case ADD_TO_END :
6710 SafeDisable (esp->trimBy);
6711 SafeEnable (esp->extendfeat);
6712 SafeDisable (esp->trimCountText);
6713 SafeEnable (esp->seq);
6714 break;
6715 case TRIM_FROM_END :
6716 SafeDisable (esp->extendfeat);
6717 SafeEnable (esp->trimBy);
6718 trimByState = GetValue (esp->trimBy);
6719 switch (trimByState) {
6720 case TRIM_BY_SEQUENCE :
6721 SafeDisable (esp->trimCountText);
6722 SafeEnable (esp->seq);
6723 break;
6724 case TRIM_BY_COUNT :
6725 SafeEnable (esp->trimCountText);
6726 SafeDisable (esp->seq);
6727 break;
6728 default :
6729 break;
6730 }
6731 break;
6732 default :
6733 break;
6734 }
6735 }
6736
6737 static void ChangeTrimBy_Callback (GrouP g)
6738
6739 {
6740 EditSeqPtr esp;
6741 Int2 val;
6742
6743 val = GetValue (g);
6744 esp = GetObjectExtra (g);
6745
6746 switch (val) {
6747 case TRIM_BY_SEQUENCE :
6748 SafeDisable (esp->trimCountText);
6749 SafeEnable (esp->seq);
6750 break;
6751 case TRIM_BY_COUNT :
6752 SafeEnable (esp->trimCountText);
6753 SafeDisable (esp->seq);
6754 break;
6755 default :
6756 break;
6757 }
6758 }
6759
6760 static void SelectAllSequencesForExtend (ButtoN b)
6761 {
6762 EditSeqPtr esp;
6763
6764 esp = (EditSeqPtr) GetObjectExtra (b);
6765 if (esp == NULL)
6766 {
6767 return;
6768 }
6769 SelectAllSequencesInListCtrl (esp->nuc_sequence_list_ctrl);
6770 }
6771
6772 static void UnSelectAllSequencesForExtend (ButtoN b)
6773 {
6774 EditSeqPtr esp;
6775
6776 esp = (EditSeqPtr) GetObjectExtra (b);
6777 if (esp == NULL)
6778 {
6779 return;
6780 }
6781 UnSelectAllSequencesInListCtrl (esp->nuc_sequence_list_ctrl);
6782 }
6783
6784 extern void EditSeqEndsProc (IteM i);
6785
6786 extern void EditSeqEndsProc (IteM i)
6787
6788 {
6789 ButtoN b;
6790 BaseFormPtr bfp;
6791 GrouP c;
6792 EditSeqPtr esp;
6793 GrouP g;
6794 GrouP h;
6795 GrouP k;
6796 GrouP p;
6797 GrouP q;
6798 GrouP r;
6799 GrouP s;
6800 SeqEntryPtr sep;
6801 StdEditorProcsPtr sepp;
6802 WindoW w;
6803
6804 #ifdef WIN_MAC
6805 bfp = currentFormDataPtr;
6806 #else
6807 bfp = GetObjectExtra (i);
6808 #endif
6809 if (bfp == NULL) return;
6810 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6811 if (sep == NULL) return;
6812 esp = (EditSeqPtr) MemNew (sizeof (EditSeqEnds));
6813 if (esp == NULL) return;
6814
6815 w = FixedWindow (-50, -33, -10, -10, "Edit Sequence Ends", StdCloseWindowProc);
6816 SetObjectExtra (w, esp, StdCleanupFormProc);
6817 esp->form = (ForM) w;
6818 esp->formmessage = EditSeqMessageProc;
6819
6820 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
6821 if (sepp != NULL) {
6822 SetActivate (w, sepp->activateForm);
6823 esp->appmessage = sepp->handleMessages;
6824 }
6825
6826 esp->input_entityID = bfp->input_entityID;
6827 esp->input_itemID = bfp->input_itemID;
6828 esp->input_itemtype = bfp->input_itemtype;
6829
6830 esp->sep = sep;
6831
6832 h = HiddenGroup (w, -1, 0, NULL);
6833 SetGroupSpacing (h, 10, 10);
6834
6835 g = HiddenGroup (h, 2, 0, NULL);
6836
6837 StaticPrompt (g, "End", 0, stdLineHeight, programFont, 'l');
6838 esp->whichend = HiddenGroup (g, 2, 0, NULL);
6839 RadioButton (esp->whichend, "5'");
6840 RadioButton (esp->whichend, "3'");
6841 SetValue (esp->whichend, 1);
6842
6843 esp->addOrTrim = HiddenGroup (h, 2, 0, ChangeAddOrTrim_Callback);
6844 SetObjectExtra (esp->addOrTrim, esp, NULL);
6845 RadioButton (esp->addOrTrim, "Add to end");
6846 RadioButton (esp->addOrTrim, "Trim from end");
6847 SetValue (esp->addOrTrim, 1);
6848
6849 k = HiddenGroup (h, 0, -2, NULL);
6850 StaticPrompt (k, "Sequence", 0, 0, programFont, 'l');
6851 esp->seq = ScrollText (k, 25, 5, programFont, TRUE, NULL);
6852
6853 q = HiddenGroup (h, 2, 0, NULL);
6854 StaticPrompt (q, "Optional gene constraint", 0, dialogTextHeight,
6855 programFont, 'l');
6856 esp->genename = DialogText (q, "", 14, NULL);
6857
6858 esp->extendfeat = CheckBox (h, "Extend features", NULL);
6859
6860 esp->trimBy = HiddenGroup (h, 2, 0, ChangeTrimBy_Callback);
6861 SetObjectExtra (esp->trimBy, esp, NULL);
6862 RadioButton (esp->trimBy, "Trim by sequence");
6863 RadioButton (esp->trimBy, "Trim by count");
6864 SetValue (esp->trimBy, 1);
6865 SafeDisable (esp->trimBy);
6866
6867 p = HiddenGroup (h, 2, 0, NULL);
6868 StaticPrompt (p, "Trim count", 0, dialogTextHeight, programFont, 'l');
6869 esp->trimCountText = DialogText (p, "", 5, NULL);
6870 SafeDisable (esp->trimCountText);
6871
6872 s = NormalGroup (h, -1, 0, "Choose Sequences To Edit", programFont, NULL);
6873 esp->nuc_sequence_list_ctrl = MakeSequenceListControl (s, sep, NULL, NULL, TRUE, FALSE);
6874
6875 r = HiddenGroup (s, 2, 0, NULL);
6876 b = PushButton (r, "Select All", SelectAllSequencesForExtend);
6877 SetObjectExtra (b, esp, NULL);
6878 b = PushButton (r, "Unselect All", UnSelectAllSequencesForExtend);
6879 SetObjectExtra (b, esp, NULL);
6880 AlignObjects (ALIGN_CENTER, (HANDLE) esp->nuc_sequence_list_ctrl,
6881 (HANDLE) r, NULL);
6882
6883 esp->addCitSub = CheckBox (h, "Add Cit Subs to edited sequences", NULL);
6884
6885 c = HiddenGroup (h, 4, 0, NULL);
6886 b = DefaultButton (c, "Accept", DoEditSeqEndsProc);
6887 SetObjectExtra (b, esp, NULL);
6888 PushButton (c, "Cancel", StdCancelButtonProc);
6889
6890 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) esp->extendfeat,
6891 (HANDLE) esp->addOrTrim, (HANDLE) esp->trimBy,
6892 (HANDLE) k, (HANDLE) q, (HANDLE) p,
6893 (HANDLE) s, (HANDLE) esp->addCitSub, (HANDLE) c, NULL);
6894 RealizeWindow (w);
6895 Show (w);
6896 Select (w);
6897 Select (esp->seq);
6898 Update ();
6899 }
6900
6901 static void SetAlignmentDim (SeqAlignPtr salp)
6902 {
6903 AMAlignIndex2Ptr amaip;
6904 DenseSegPtr dsp;
6905
6906 if (salp == NULL || salp->dim > 0 || salp->saip == NULL) return;
6907
6908 if (salp->saip->indextype == INDEX_PARENT)
6909 {
6910 amaip = (AMAlignIndex2Ptr)(salp->saip);
6911 salp->dim = amaip->sharedaln->dim;
6912 }
6913 else if (salp->saip->indextype == INDEX_CHILD)
6914 {
6915 dsp = (DenseSegPtr)(salp->segs);
6916 salp->dim = dsp->dim;
6917 }
6918 }
6919
6920 static void IndexAlignmentSet (SeqAlignPtr salp)
6921 {
6922 SeqAlignPtr tmp_salp, next_salp;
6923
6924 if (salp == NULL || salp->saip != NULL) return;
6925
6926 if (salp->next != NULL && salp->dim > 2)
6927 {
6928 for (tmp_salp = salp; tmp_salp != NULL; tmp_salp = tmp_salp->next)
6929 {
6930 next_salp = tmp_salp->next;
6931 tmp_salp->next = NULL;
6932 if (tmp_salp->segtype == SAS_DENSEG && tmp_salp->next == NULL) {
6933 AlnMgr2IndexSingleChildSeqAlign(tmp_salp);
6934 } else {
6935 AlnMgr2IndexSeqAlign(tmp_salp);
6936 }
6937 SetAlignmentDim (tmp_salp);
6938 tmp_salp->next = next_salp;
6939 }
6940 }
6941 else
6942 {
6943 if (salp->segtype == SAS_DENSEG && salp->next == NULL) {
6944 AlnMgr2IndexSingleChildSeqAlign(salp);
6945 } else {
6946 AlnMgr2IndexSeqAlign(salp);
6947 }
6948 SetAlignmentDim (salp);
6949 }
6950 }
6951
6952 static void WriteSeqEntryAlignmentToFile (SeqEntryPtr sep, FILE *fp, Boolean Interleave)
6953 {
6954 BioseqSetPtr bssp;
6955 SeqAnnotPtr sap;
6956 SeqAlignPtr salp = NULL;
6957
6958 if (sep == NULL || ! IS_Bioseq_set (sep)) return;
6959 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6960 if (bssp == NULL) return;
6961 for (sap = bssp->annot; sap != NULL; sap = sap->next) {
6962 if (sap->type == 2) {
6963 salp = SeqAlignListDup((SeqAlignPtr) sap->data);
6964 IndexAlignmentSet (salp);
6965
6966 if (Interleave) {
6967 if (salp->next != NULL)
6968 {
6969 Message (MSG_ERROR, "Unable to write segmented alignments as interleave");
6970 return;
6971 }
6972 WriteAlignmentInterleaveToFile (salp, fp, 40, FALSE);
6973 } else {
6974 WriteAlignmentContiguousToFile (salp, fp, 40, FALSE);
6975 }
6976 SeqAlignFree (salp);
6977 salp = NULL;
6978 }
6979 }
6980
6981 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
6982 WriteSeqEntryAlignmentToFile (sep, fp, Interleave);
6983 }
6984 }
6985
6986 static void ExportAlignment (IteM i, Boolean Interleave)
6987 {
6988 BaseFormPtr bfp;
6989 SeqEntryPtr sep;
6990 Char path [PATH_MAX];
6991 FILE * fp;
6992
6993 #ifdef WIN_MAC
6994 bfp = currentFormDataPtr;
6995 #else
6996 bfp = GetObjectExtra (i);
6997 #endif
6998 if (bfp == NULL) return;
6999 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
7000 if (sep == NULL) return;
7001
7002 if (! GetOutputFileName (path, sizeof (path), "")) return;
7003 if (! StringHasNoText (path)) {
7004 fp = FileOpen (path, "w");
7005 if (fp != NULL) {
7006 WatchCursor ();
7007 Update();
7008 WriteSeqEntryAlignmentToFile (sep, fp, Interleave);
7009 ArrowCursor ();
7010 Update();
7011 FileClose (fp);
7012 } else {
7013 Message (MSG_ERROR, "Unable to open file");
7014 }
7015 }
7016 }
7017
7018 extern void ExportAlignmentInterleave (IteM i)
7019 {
7020 ExportAlignment (i, TRUE);
7021 }
7022
7023 extern void ExportAlignmentContiguous (IteM i)
7024 {
7025 ExportAlignment (i, FALSE);
7026 }
7027
7028 static Int4 FindFeaturePos (SeqIdPtr sip, SeqAlignPtr salp, Int4 pos)
7029 {
7030 Int4 aln_row;
7031 Int4 new_pos;
7032
7033 if (sip == NULL || salp == NULL) return pos;
7034 aln_row = AlnMgr2GetFirstNForSip(salp, sip);
7035 if (aln_row > 0)
7036 {
7037 new_pos = AlnMgr2MapSeqAlignToBioseq (salp, pos, aln_row);
7038 if (new_pos < 0)
7039 {
7040 return pos;
7041 }
7042 else
7043 {
7044 return new_pos;
7045 }
7046 }
7047 return pos;
7048 }
7049
7050 static void FixFeatureIntervalSeqLoc (SeqLocPtr slp, SeqAlignPtr salp)
7051 {
7052 SeqIntPtr sintp;
7053 SeqBondPtr sbp;
7054 SeqPntPtr spp;
7055 SeqIdPtr tmpsip;
7056 SeqLocPtr this_slp;
7057
7058 if (slp == NULL || slp->data.ptrvalue == NULL || salp == NULL) return;
7059
7060 tmpsip = SeqIdPtrFromSeqAlign (salp);
7061
7062 switch (slp->choice)
7063 {
7064 case SEQLOC_INT:
7065 sintp = slp->data.ptrvalue;
7066 sintp->from = FindFeaturePos (sintp->id, salp, sintp->from);
7067 sintp->to = FindFeaturePos (sintp->id, salp, sintp->to);
7068 break;
7069 case SEQLOC_PNT:
7070 spp = slp->data.ptrvalue;
7071 spp->point = FindFeaturePos (spp->id, salp, spp->point);
7072 break;
7073 case SEQLOC_BOND: /* bond -- 2 seqs */
7074 sbp = (SeqBondPtr)(slp->data.ptrvalue);
7075 spp = sbp->a;
7076 spp->point = FindFeaturePos (spp->id, salp, spp->point);
7077 spp = sbp->b;
7078 spp->point = FindFeaturePos (spp->id, salp, spp->point);
7079 break;
7080 case SEQLOC_MIX: /* mix -- more than one seq */
7081 case SEQLOC_EQUIV: /* equiv -- ditto */
7082 case SEQLOC_PACKED_INT: /* packed int */
7083 for (this_slp = slp->data.ptrvalue; this_slp != NULL; this_slp = this_slp->next)
7084 {
7085 FixFeatureIntervalSeqLoc (this_slp, salp);
7086 }
7087 break;
7088 default:
7089 break;
7090 }
7091 }
7092
7093 typedef struct featurefixdata
7094 {
7095 Uint2 entityID;
7096 SeqAlignPtr salp;
7097 } FeatureFixData, PNTR FeatureFixPtr;
7098
7099 static void FixFeatureIntervalCallback (SeqFeatPtr sfp, Pointer userdata)
7100
7101 {
7102 BioseqPtr bsp;
7103 FeatureFixPtr ffp;
7104
7105 if (sfp == NULL || userdata == NULL) return;
7106
7107 ffp = (FeatureFixPtr) userdata;
7108
7109 FixFeatureIntervalSeqLoc (sfp->location, ffp->salp);
7110 if (sfp->idx.subtype == FEATDEF_CDS)
7111 {
7112 bsp = BioseqFindFromSeqLoc (sfp->location);
7113 SeqEdTranslateOneCDS (sfp, bsp, ffp->entityID, Sequin_GlobalAlign2Seq);
7114 }
7115 }
7116
7117 extern void FixFeatureIntervals (IteM i)
7118 {
7119 BaseFormPtr bfp;
7120 SeqEntryPtr sep;
7121 FeatureFixData ffd;
7122
7123 #ifdef WIN_MAC
7124 bfp = currentFormDataPtr;
7125 #else
7126 bfp = GetObjectExtra (i);
7127 #endif
7128 if (bfp == NULL) return;
7129 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
7130 if (sep == NULL) return;
7131
7132 ffd.entityID = bfp->input_entityID;
7133 ffd.salp = SeqAlignListDup((SeqAlignPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN));
7134 if (ffd.salp == NULL)
7135 {
7136 Message (MSG_ERROR, "No alignment present - cannot remap intervals");
7137 return;
7138 }
7139
7140 if (ffd.salp->segtype == SAS_DENSEG && ffd.salp->next == NULL)
7141 {
7142 AlnMgr2IndexSingleChildSeqAlign(ffd.salp);
7143 } else {
7144 AlnMgr2IndexSeqAlign(ffd.salp);
7145 }
7146
7147 VisitFeaturesInSep (sep, (Pointer) &ffd, FixFeatureIntervalCallback);
7148 SeqAlignFree (ffd.salp);
7149
7150 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
7151 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
7152 }
7153
7154 typedef struct objstringdata
7155 {
7156 StringConstraintXPtr scp;
7157 Boolean found;
7158 } ObjStringData, PNTR ObjStringPtr;
7159
7160 static void LIBCALLBACK AsnWriteStringConstraintCallBack (AsnExpOptStructPtr pAEOS)
7161
7162 {
7163 CharPtr pchSource;
7164 ObjStringPtr osp;
7165
7166 osp = (ObjStringPtr) pAEOS->data;
7167 if (ISA_STRINGTYPE (AsnFindBaseIsa (pAEOS->atp)))
7168 {
7169 pchSource = (CharPtr) pAEOS->dvp->ptrvalue;
7170 if (DoesStringMatchConstraintX (pchSource, osp->scp))
7171 {
7172 osp->found = TRUE;
7173 }
7174 }
7175 }
7176
7177 static Boolean DoesBioseqMatchStringConstraint (BioseqPtr bsp, StringConstraintXPtr scp)
7178
7179 {
7180 ObjMgrPtr omp;
7181 ObjMgrTypePtr omtp;
7182 AsnExpOptPtr aeop;
7183 AsnIoPtr aip;
7184 ObjStringData osd;
7185
7186 omp = ObjMgrGet ();
7187 if (omp == NULL) return FALSE;
7188 omtp = ObjMgrTypeFind (omp, OBJ_BIOSEQ, NULL, NULL);
7189 if (omtp == NULL) return FALSE;
7190
7191 aip = AsnIoNullOpen ();
7192 aeop = AsnExpOptNew (aip, NULL, NULL, AsnWriteStringConstraintCallBack);
7193 if (aeop != NULL) {
7194 aeop->user_data = (Pointer) &osd;
7195 }
7196 osd.scp = scp;
7197
7198 osd.found = FALSE;
7199 (omtp->asnwrite) (bsp, aip, NULL);
7200 AsnIoClose (aip);
7201
7202 if (scp != NULL && scp->not_present)
7203 {
7204 osd.found = ! osd.found;
7205 }
7206
7207 return osd.found;
7208 }
7209
7210
7211 extern Boolean DoBioseqFeaturesMatchSequenceConstraintX (BioseqPtr bsp, ValNodePtr feat_list, StringConstraintXPtr scp)
7212 {
7213 AsnExpOptPtr aeop;
7214 AsnIoPtr aip;
7215 ObjStringData osd;
7216 SeqFeatPtr sfp;
7217 ObjMgrPtr omp;
7218 ObjMgrTypePtr omtp;
7219 SeqMgrFeatContext fcontext;
7220 ValNodePtr vnp;
7221
7222 if (bsp == NULL) return FALSE;
7223 if (scp == NULL) return TRUE;
7224 omp = ObjMgrGet ();
7225 if (omp == NULL) return FALSE;
7226 omtp = ObjMgrTypeFind (omp, OBJ_SEQFEAT, NULL, NULL);
7227 if (omtp == NULL) return FALSE;
7228
7229 aip = AsnIoNullOpen ();
7230 osd.scp = scp;
7231
7232 aeop = AsnExpOptNew (aip, NULL, NULL, AsnWriteStringConstraintCallBack);
7233 if (aeop != NULL) {
7234 aeop->user_data = (Pointer) &osd;
7235 }
7236
7237 for (vnp = feat_list; vnp != NULL; vnp = vnp->next)
7238 {
7239 for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, vnp->choice, &fcontext);
7240 sfp != NULL;
7241 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, vnp->choice, &fcontext))
7242 {
7243 osd.found = FALSE;
7244 (omtp->asnwrite) (sfp, aip, NULL);
7245 if (osd.found)
7246 {
7247 if (scp->not_present)
7248 {
7249 AsnIoClose (aip);
7250 return FALSE;
7251 }
7252 else
7253 {
7254 AsnIoClose (aip);
7255 return TRUE;
7256 }
7257 }
7258 }
7259 }
7260 AsnIoClose (aip);
7261 if (scp->not_present)
7262 {
7263 return TRUE;
7264 }
7265 else
7266 {
7267 return FALSE;
7268 }
7269 }
7270
7271
7272 typedef struct keywordform
7273 {
7274 FORM_MESSAGE_BLOCK
7275 DialoG string_src_dlg;
7276 DialoG string_constraint_dlg;
7277 TexT keyword_txt;
7278
7279 ParseFieldPtr pfp;
7280 FilterSetPtr fsp;
7281 CharPtr keyword;
7282 } KeywordFormData, PNTR KeywordFormPtr;
7283
7284
7285 static void ApplyKeywordCallback (BioseqPtr bsp, Pointer userdata)
7286 {
7287 SeqEntryPtr sep;
7288 ValNodePtr vnp;
7289 KeywordFormPtr scfp;
7290 GBBlockPtr gbp;
7291 GetSamplePtr gsp;
7292 Boolean ok_to_add = TRUE;
7293
7294 sep = SeqMgrGetSeqEntryForData (bsp);
7295 if (sep == NULL)
7296 {
7297 return;
7298 }
7299
7300 scfp = (KeywordFormPtr) userdata;
7301
7302 if (scfp->pfp != NULL && scfp->fsp != NULL)
7303 {
7304 gsp = GetSampleForSeqEntry (sep, bsp->idx.entityID, scfp->pfp, scfp->fsp);
7305 if (gsp == NULL || gsp->num_found == 0)
7306 {
7307 ok_to_add = FALSE;
7308 }
7309 gsp = GetSampleFree (gsp);
7310 }
7311
7312 if (!ok_to_add)
7313 {
7314 return;
7315 }
7316
7317 vnp = GetDescrOnSeqEntry (sep, Seq_descr_genbank);
7318 if (vnp == NULL) {
7319 vnp = NewDescrOnSeqEntry (sep, Seq_descr_genbank);
7320 if (vnp != NULL) {
7321 vnp->data.ptrvalue = (Pointer) GBBlockNew ();
7322 }
7323 }
7324 if (vnp == NULL) return;
7325 gbp = (GBBlockPtr) vnp->data.ptrvalue;
7326 if (gbp == NULL)
7327 {
7328 gbp = GBBlockNew ();
7329 vnp->data.ptrvalue = gbp;
7330 }
7331 if (gbp == NULL) return;
7332
7333 for (vnp = gbp->keywords; vnp; vnp = vnp->next) {
7334 if (StringCmp((CharPtr)vnp->data.ptrvalue, scfp->keyword) == 0) {
7335 return;
7336 }
7337 }
7338 ValNodeAddPointer (&(gbp->keywords), 0, StringSave (scfp->keyword));
7339 }
7340
7341 static void RemoveKeywordCallback (BioseqPtr bsp, Pointer userdata)
7342 {
7343 SeqEntryPtr sep;
7344 ValNodePtr vnp, prev_keyword, next_keyword;
7345 KeywordFormPtr scfp;
7346 GBBlockPtr gbp;
7347 GetSamplePtr gsp;
7348 Boolean ok_to_remove = TRUE;
7349
7350 sep = SeqMgrGetSeqEntryForData (bsp);
7351 if (sep == NULL)
7352 {
7353 return;
7354 }
7355
7356 scfp = (KeywordFormPtr) userdata;
7357
7358 if (scfp->pfp != NULL && scfp->fsp != NULL)
7359 {
7360 gsp = GetSampleForSeqEntry (sep, bsp->idx.entityID, scfp->pfp, scfp->fsp);
7361 if (gsp == NULL || gsp->num_found == 0)
7362 {
7363 ok_to_remove = FALSE;
7364 }
7365 gsp = GetSampleFree (gsp);
7366 }
7367
7368 if (!ok_to_remove)
7369 {
7370 return;
7371 }
7372
7373 vnp = GetDescrOnSeqEntry (sep, Seq_descr_genbank);
7374 /* no GenBank descriptor, no keywords to remove */
7375 if (vnp == NULL) return;
7376
7377 gbp = (GBBlockPtr) vnp->data.ptrvalue;
7378 /* No GBBlock, no keywords to remove */
7379 if (gbp == NULL) return;
7380
7381 prev_keyword = NULL;
7382 for (vnp = gbp->keywords; vnp; vnp = next_keyword) {
7383 next_keyword = vnp->next;
7384 if (StringICmp((CharPtr)vnp->data.ptrvalue, scfp->keyword) == 0) {
7385 if (prev_keyword == NULL)
7386 {
7387 gbp->keywords = next_keyword;
7388 }
7389 else
7390 {
7391 prev_keyword->next = next_keyword;
7392 }
7393 vnp->next = NULL;
7394 ValNodeFreeData (vnp);
7395 }
7396 else
7397 {
7398 prev_keyword = vnp;
7399 }
7400 }
7401 }
7402
7403 static void ApplyKeyword (IteM i, CharPtr keyword)
7404 {
7405 BaseFormPtr bfp;
7406 SeqEntryPtr sep;
7407 KeywordFormData kfd;
7408
7409 #ifdef WIN_MAC
7410 bfp = currentFormDataPtr;
7411 #else
7412 bfp = GetObjectExtra (i);
7413 #endif
7414 if (bfp == NULL) return;
7415 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
7416 if (sep == NULL) return;
7417
7418 kfd.pfp = NULL;
7419 kfd.fsp = NULL;
7420 kfd.keyword = keyword;
7421
7422 VisitBioseqsInSep (sep, &kfd, ApplyKeywordCallback);
7423
7424 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
7425 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
7426 ArrowCursor ();
7427 Update ();
7428 }
7429
7430 extern void ApplyGDSKeyword (IteM i)
7431 {
7432 ApplyKeyword (i, "GDS");
7433 }
7434
7435 extern void ApplyTPAInferentialKeyword (IteM i)
7436 {
7437 ApplyKeyword (i, "TPA:inferential");
7438 }
7439
7440 extern void ApplyTPAExperimentalKeyword (IteM i)
7441 {
7442 ApplyKeyword (i, "TPA:experimental");
7443 }
7444
7445 extern void ApplyTPAReassemblyKeyword (IteM i)
7446 {
7447 ApplyKeyword (i, "TPA:reassembly");
7448 }
7449
7450 static void DoRemoveKeywords (ButtoN b)
7451 {
7452 KeywordFormPtr scfp;
7453 SeqEntryPtr sep;
7454
7455 scfp = (KeywordFormPtr) GetObjectExtra (b);
7456 if (scfp == NULL)
7457 {
7458 return;
7459 }
7460
7461 scfp->pfp = (ParseFieldPtr) DialogToPointer (scfp->string_src_dlg);
7462 scfp->fsp = FilterSetNew ();
7463 scfp->fsp->scp = (StringConstraintXPtr) DialogToPointer (scfp->string_constraint_dlg);
7464 scfp->keyword = SaveStringFromText (scfp->keyword_txt);
7465
7466 sep = GetTopSeqEntryForEntityID (scfp->input_entityID);
7467 if (sep == NULL) return;
7468
7469 VisitBioseqsInSep (sep, scfp, RemoveKeywordCallback);
7470
7471 scfp->fsp = FilterSetFree (scfp->fsp);
7472 scfp->pfp = ParseFieldFree (scfp->pfp);
7473
7474 ObjMgrSetDirtyFlag (scfp->input_entityID, TRUE);
7475 ObjMgrSendMsg (OM_MSG_UPDATE, scfp->input_entityID, 0, 0);
7476 ArrowCursor ();
7477 Update ();
7478 Remove (scfp->form);
7479 }
7480
7481 extern void RemoveKeywordWithStringConstraint (IteM i)
7482 {
7483 BaseFormPtr bfp;
7484 KeywordFormPtr scfp;
7485 WindoW w;
7486 PrompT ppt;
7487 GrouP h, g, c;
7488 ButtoN b;
7489
7490 #ifdef WIN_MAC
7491 bfp = currentFormDataPtr;
7492 #else
7493 bfp = GetObjectExtra (i);
7494 #endif
7495 if (bfp == NULL) return;
7496
7497 scfp = (KeywordFormPtr) MemNew (sizeof (KeywordFormData));
7498 if (scfp == NULL) return;
7499
7500 w = FixedWindow (-50, -33, -10, -10, "Remove Keywords", StdCloseWindowProc);
7501 SetObjectExtra (w, scfp, StdCleanupExtraProc);
7502 scfp->form = (ForM) w;
7503 scfp->input_entityID = bfp->input_entityID;
7504
7505 h = HiddenGroup (w, -1, 0, NULL);
7506 SetGroupSpacing (h, 10, 10);
7507
7508 g = HiddenGroup (h, 2, 0, NULL);
7509 SetGroupSpacing (g, 10, 10);
7510 StaticPrompt (g, "Remove Keyword", 0, 0, programFont, 'l');
7511 scfp->keyword_txt = DialogText (g, "", 30, NULL);
7512
7513 ppt = StaticPrompt (h, "Where", 0, 0, programFont, 'l');
7514 scfp->string_src_dlg = ParseFieldDestDialogEx (h, NULL, NULL, FALSE, TRUE);
7515
7516 scfp->string_constraint_dlg = StringConstraintDialogX (h, NULL, FALSE);
7517
7518 c = HiddenGroup (h, 2, 0, NULL);
7519 b = PushButton (c, "Accept", DoRemoveKeywords);
7520 SetObjectExtra (b, scfp, NULL);
7521 b = PushButton (c, "Cancel", StdCancelButtonProc);
7522
7523 AlignObjects (ALIGN_CENTER, (HANDLE) g,
7524 (HANDLE) ppt,
7525 (HANDLE) scfp->string_src_dlg,
7526 (HANDLE) scfp->string_constraint_dlg,
7527 (HANDLE) c,
7528 NULL);
7529 RealizeWindow (w);
7530 Show (w);
7531 Select (w);
7532 Update ();
7533 }
7534
7535
7536 static CharPtr RNAstrandcmd = NULL;
7537
7538 typedef struct rnastrand
7539 {
7540 FORM_MESSAGE_BLOCK
7541
7542 ParData rnaParFmt;
7543 ColData rnaColFmt[3];
7544
7545 DoC doc;
7546 ButtoN rev_feats;
7547 ButtoN use_smart_btn;
7548 SeqEntryPtr sep;
7549 ValNodePtr sequence_list;
7550 Int4 num_sequences;
7551 BoolPtr selected;
7552 Int2 lineheight;
7553 CharPtr database;
7554 Boolean use_smart;
7555 } RNAStrandData, PNTR RNAStrandPtr;
7556
7557 typedef enum
7558 {
7559 RNAstrand_PLUS = 1,
7560 RNAstrand_MINUS,
7561 RNAstrand_MIXED,
7562 RNAstrand_NO_HITS,
7563 RNAstrand_UNEXPECTED,
7564 RNAstrand_PARSE_ERROR,
7565 RNAstrand_IN_PROGRESS
7566 } ERNAstrand_return_val;
7567
7568 static CharPtr RNAstrand_strings[] =
7569 { "Plus", "Minus", "Mixed", "No Hits", "Unexpected", "Parse Error", "In Progress" };
7570
7571
7572 typedef enum
7573 {
7574 RNASTRANDGRP_ERROR = 0,
7575 RNASTRANDGRP_NO_HITS,
7576 RNASTRANDGRP_MIXED,
7577 RNASTRANDGRP_MINUS,
7578 RNASTRANDGRP_PLUS
7579 } ERNAstrand_group_num;
7580
7581 static ERNAstrand_group_num GetRNAStrandGroupNum (ValNodePtr vnp)
7582 {
7583 if (vnp == NULL) return RNASTRANDGRP_ERROR;
7584 else if (vnp->choice == RNAstrand_NO_HITS) return RNASTRANDGRP_NO_HITS;
7585 else if (vnp->choice == RNAstrand_MINUS) return RNASTRANDGRP_MINUS;
7586 else if (vnp->choice == RNAstrand_MIXED) return RNASTRANDGRP_MIXED;
7587 else if (vnp->choice == RNAstrand_PLUS) return RNASTRANDGRP_PLUS;
7588 else return RNASTRANDGRP_ERROR;
7589 }
7590
7591
7592 static void LimitAlignmentResults (SeqAlignPtr salp, Int4 num_results)
7593 {
7594 Int4 k = 0;
7595 SeqAlignPtr tmp_salp, last_salp = NULL;
7596
7597 while (salp != NULL && k < num_results)
7598 {
7599 last_salp = salp;
7600 salp = salp->next;
7601 k++;
7602 }
7603 if (last_salp != NULL)
7604 {
7605 last_salp->next = NULL;
7606 }
7607 while (salp != NULL)
7608 {
7609 tmp_salp = salp->next;
7610 salp->next = NULL;
7611 salp = SeqAlignFree (salp);
7612 salp = tmp_salp;
7613 }
7614 }
7615
7616
7617 static SBlastOptions*
7618 RNABlastOptionNew(void)
7619
7620 {
7621 SBlastOptions* options;
7622 Int2 rval;
7623 Blast_SummaryReturn *extra_returns;
7624
7625
7626 extra_returns = Blast_SummaryReturnNew();
7627 rval = SBlastOptionsNew("blastn", &options,
7628 extra_returns);
7629
7630 if (options == NULL)
7631 return NULL;
7632
7633 /* This replaces:
7634 * options->expect_value = 1;
7635 */
7636 SBlastOptionsSetEvalue(options, 1);
7637
7638 /* This replaces:
7639 * options->filter_string = StringSave("m L");
7640 */
7641 SBlastOptionsSetFilterString(options, "m L");
7642
7643 /* This replaces the following:
7644 * options->mb_template_length = 18;
7645 * options->mb_disc_type = MB_WORD_CODING;
7646 * options->is_megablast_search = TRUE;
7647 * options->discontinuous = TRUE;
7648 */
7649 SBlastOptionsSetDiscMbParams(options, 18, MB_WORD_CODING);
7650
7651 /* This replaces:
7652 * options->wordsize = 11; \
7653 */
7654 SBlastOptionsSetWordSize (options, 11);
7655
7656 /* This replaces:
7657 * options->hitlist_size = 20;
7658 */
7659 options->hit_options->hitlist_size = 20;
7660
7661 /* This replaces the following:
7662 * options->multiple_hits_only = TRUE;
7663 * options->window_size = 40;
7664 */
7665 options->word_options->window_size = 40;
7666
7667 /* This replaces the following:
7668 * options->reward = 1;
7669 * options->penalty = -3;
7670 * options->gap_open = 5;
7671 * options->gap_extend = 2;
7672 */
7673 SBlastOptionsSetRewardPenaltyAndGapCosts(options, 2, -3, 5, 2, FALSE);
7674
7675 extra_returns = Blast_SummaryReturnFree(extra_returns);
7676 return options;
7677 }
7678
7679 #if 0
7680 const CharPtr kRNAStrandDatabaseName = "rRNAstrand";
7681 #else
7682 const CharPtr kRNAStrandDatabaseName = "rRNA_blast";
7683 #endif
7684
7685 static Int4
7686 RNAScreenSequence(BioseqPtr bsp, CharPtr database, SeqAlignPtr PNTR seqalign_ptr)
7687
7688 {
7689 SBlastOptions *blast_options;
7690 Int2 retval=0;
7691 SeqAlignPtr seqalign = NULL;
7692 SeqLocPtr slp;
7693 SBlastSeqalignArray* seqalign_arr = NULL;
7694 Blast_SummaryReturn *extra_returns;
7695
7696 if (bsp == NULL)
7697 return -1;
7698
7699 if (seqalign_ptr)
7700 *seqalign_ptr = NULL;
7701
7702 blast_options = RNABlastOptionNew();
7703 if (blast_options == NULL)
7704 return -1;
7705
7706 slp = SeqLocWholeNew(bsp);
7707 if (database == NULL)
7708 database = kRNAStrandDatabaseName;
7709
7710 extra_returns = Blast_SummaryReturnNew();
7711
7712 retval = Blast_DatabaseSearch(slp, NULL, database, NULL, blast_options, NULL, &seqalign_arr, NULL, extra_returns);
7713 extra_returns = Blast_SummaryReturnFree(extra_returns);
7714 blast_options = SBlastOptionsFree(blast_options);
7715
7716 if (retval == 0 && seqalign_arr != NULL && seqalign_arr->num_queries >0)
7717 {
7718 seqalign = seqalign_arr->array[0];
7719 seqalign_arr->array[0] = NULL;
7720 }
7721
7722 seqalign_arr = SBlastSeqalignArrayFree(seqalign_arr);
7723
7724 /* limit results to first 20 alignments, as SMART does */
7725 LimitAlignmentResults (seqalign, 20);
7726
7727 if (seqalign)
7728 {
7729 if (seqalign_ptr)
7730 *seqalign_ptr = seqalign;
7731 }
7732
7733
7734 return retval;
7735 }
7736
7737
7738 typedef struct rnastrandcollection
7739 {
7740 ValNodePtr sequence_list;
7741 Char path [PATH_MAX];
7742 CharPtr database;
7743 Int4 count;
7744 Int4 total;
7745 MonitorPtr mon;
7746 } RNAStrandCollectionData, PNTR RNAStrandCollectionPtr;
7747
7748 static Uint1 GetStatusForAlignmentList (SeqAlignPtr salp)
7749 {
7750 Uint1 status = RNAstrand_NO_HITS;
7751 Uint1 strand;
7752
7753 while (salp != NULL)
7754 {
7755 AlnMgr2IndexSingleChildSeqAlign(salp);
7756 strand = AlnMgr2GetNthStrand(salp, 1);
7757 if (status == RNAstrand_NO_HITS)
7758 {
7759 if (strand == Seq_strand_plus)
7760 {
7761 status = RNAstrand_PLUS;
7762 }
7763 else if (strand == Seq_strand_minus)
7764 {
7765 status = RNAstrand_MINUS;
7766 }
7767 else
7768 {
7769 return RNAstrand_UNEXPECTED;
7770 }
7771 }
7772 else if (strand == Seq_strand_plus)
7773 {
7774 if (status != RNAstrand_PLUS)
7775 {
7776 return RNAstrand_MIXED;
7777 }
7778 }
7779 else if (strand == Seq_strand_minus)
7780 {
7781 if (status != RNAstrand_MINUS)
7782 {
7783 return RNAstrand_MIXED;
7784 }
7785 }
7786 else
7787 {
7788 return RNAstrand_UNEXPECTED;
7789 }
7790 salp = salp->next;
7791 }
7792 return status;
7793 }
7794
7795 static void GetOneRNAStrandednessInfo (BioseqPtr bsp, Pointer userdata)
7796 {
7797 RNAStrandCollectionPtr rscp;
7798 SeqAlignPtr salp = NULL;
7799
7800 if (bsp == NULL || !ISA_na (bsp->mol) || userdata == NULL)
7801 {
7802 return;
7803 }
7804
7805 rscp = (RNAStrandCollectionPtr) userdata;
7806
7807 if (rscp->mon != NULL) {
7808 MonitorIntValue (rscp->mon, rscp->count);
7809 }
7810 (rscp->count)++;
7811
7812 RNAScreenSequence(bsp, rscp->path, &salp);
7813
7814 ValNodeAddPointer (&(rscp->sequence_list),
7815 GetStatusForAlignmentList(salp),
7816 SeqIdFindBest (bsp->id, SEQID_GENBANK));
7817 salp = SeqAlignFree (salp);
7818 }
7819
7820 static void CountRNASequences (BioseqPtr bsp, Pointer userdata)
7821 {
7822 RNAStrandCollectionPtr rscp;
7823
7824 if (bsp == NULL || !ISA_na (bsp->mol) || userdata == NULL)
7825 {
7826 return;
7827 }
7828
7829 rscp = (RNAStrandCollectionPtr) userdata;
7830
7831 rscp->total++;
7832 }
7833
7834 static ValNodePtr GetRNAStrandednessFromLocalDatabase (SeqEntryPtr sep, CharPtr database)
7835 {
7836 RNAStrandCollectionData rscd;
7837
7838 if (sep == NULL) return NULL;
7839
7840 rscd.path [0] = '\0';
7841 GetAppParam ("NCBI", "NCBI", "DATA", "", rscd.path, sizeof (rscd.path));
7842 FileBuildPath (rscd.path, NULL, database);
7843
7844 rscd.database = database;
7845 rscd.sequence_list = NULL;
7846 rscd.total = 0;
7847 rscd.count = 0;
7848 rscd.mon = NULL;
7849
7850 VisitBioseqsInSep (sep, &rscd, CountRNASequences);
7851 if (rscd.total > 2)
7852 {
7853 rscd.mon = MonitorIntNewEx ("RNA Strand Progress", 0, rscd.total - 1, FALSE);
7854 }
7855
7856 VisitBioseqsInSep (sep, &rscd, GetOneRNAStrandednessInfo);
7857
7858 if (rscd.mon != NULL) {
7859 rscd.mon = MonitorFree (rscd.mon);
7860 Update ();
7861 }
7862
7863 return rscd.sequence_list;
7864 }
7865
7866 static void GetAccessionList (BioseqPtr bsp, Pointer userdata)
7867 {
7868 ValNodePtr PNTR sequence_list;
7869 SeqIdPtr sip;
7870
7871 if (bsp == NULL || userdata == NULL) return;
7872
7873 sequence_list = (ValNodePtr PNTR) userdata;
7874
7875 for (sip = bsp->id; sip != NULL; sip = sip->next)
7876 {
7877 if (sip->choice == SEQID_GENBANK)
7878 {
7879 ValNodeAddPointer (sequence_list, 0, sip);
7880 return;
7881 }
7882 }
7883 }
7884
7885
7886 /* Looks at a portion of the list of sequences for strand correction.
7887 * Returns the number of sequences examined.
7888 */
7889 static Int4
7890 GetSubListForRNAStrandCorrection
7891 (ValNodePtr start_list,
7892 Int4 num_seqs,
7893 CharPtr RNAstrandcmd)
7894 {
7895 Int4 seq_num, cmd_len = 0, k;
7896 ValNodePtr vnp;
7897 FILE * fp;
7898 CharPtr args = NULL, cp, cp2, cmmd;
7899 Char tmp_id [256];
7900 Char path [PATH_MAX];
7901 Char file_line [256];
7902 Boolean found_id;
7903 #ifdef OS_MAC
7904 CharPtr cmd_format = "%s -a \'%s\' > %s"; /* just to allow compilation */
7905 #endif
7906 #ifdef OS_UNIX
7907 CharPtr cmd_format = "%s -a \'%s\' > %s";
7908 #endif
7909 #ifdef OS_MSWIN
7910 CharPtr cmd_format = "%s -a \"%s\" > %s";
7911 #endif
7912
7913 if (start_list == NULL || num_seqs < 1 || StringHasNoText (RNAstrandcmd))
7914 {
7915 return 0;
7916 }
7917
7918 TmpNam (path);
7919
7920 /* calculate length of string needed for command */
7921 for (vnp = start_list, seq_num = 0;
7922 vnp != NULL && seq_num < num_seqs;
7923 vnp = vnp->next, seq_num++)
7924 {
7925 SeqIdWrite (vnp->data.ptrvalue, tmp_id, PRINTID_TEXTID_ACC_ONLY, sizeof (tmp_id) - 1);
7926 cmd_len += StringLen (tmp_id) + 3;
7927 }
7928
7929 args = (CharPtr) MemNew (cmd_len * sizeof (Char));
7930 if (args == NULL)
7931 {
7932 Message (MSG_ERROR, "Unable to allocate memory for strand script argument list");
7933 return 0;
7934 }
7935
7936 cp = args;
7937 for (vnp = start_list, seq_num = 0;
7938 vnp != NULL && seq_num < num_seqs;
7939 vnp = vnp->next, seq_num++)
7940 {
7941 SeqIdWrite (vnp->data.ptrvalue, cp, PRINTID_TEXTID_ACC_ONLY, cmd_len - (cp - args) - 1);
7942 cp += StringLen (cp);
7943 if (vnp->next != NULL && seq_num < num_seqs - 1)
7944 {
7945 #ifdef OS_UNIX
7946 StringCat (cp, ",");
7947 cp ++;
7948 #else
7949 StringCat (cp, ", ");
7950 cp += 2;
7951 #endif
7952 }
7953 }
7954
7955
7956 cmd_len += 3 + StringLen (cmd_format) + StringLen (RNAstrandcmd) + StringLen (path);
7957 cmmd = (CharPtr) MemNew (cmd_len * sizeof (Char));
7958 if (cmmd == NULL)
7959 {
7960 args = MemFree (args);
7961 Message (MSG_ERROR, "Unable to allocate memory for RNA strand script command");
7962 return 0;
7963 }
7964
7965 #ifdef OS_UNIX
7966 sprintf (cmmd, cmd_format, RNAstrandcmd, args, path);
7967 system (cmmd);
7968 #endif
7969 #ifdef OS_MSWIN
7970 sprintf (cmmd, cmd_format, RNAstrandcmd, args, path);
7971 RunSilent (cmmd);
7972 #endif
7973
7974 args = MemFree (args);
7975 cmmd = MemFree (cmmd);
7976
7977 fp = FileOpen (path, "r");
7978 if (fp == NULL) {
7979 FileRemove (path);
7980 return 0;
7981 }
7982
7983
7984 while (fgets (file_line, sizeof (file_line) - 1, fp) != NULL)
7985 {
7986 /* find SeqId that matches file line */
7987 cp = StringChr (file_line, '\t');
7988 if (cp == NULL)
7989 {
7990 continue;
7991 }
7992 *cp = 0;
7993 cp++;
7994 cp2 = StringChr (cp, '\n');
7995 if (cp2 != NULL)
7996 {
7997 *cp2 = 0;
7998 }
7999 found_id = FALSE;
8000 for (vnp = start_list, seq_num = 0;
8001 vnp != NULL && seq_num < num_seqs;
8002 vnp = vnp->next, seq_num++)
8003 {
8004 SeqIdWrite (vnp->data.ptrvalue, tmp_id, PRINTID_TEXTID_ACC_ONLY, sizeof (tmp_id) - 1);
8005 if (StringCmp (tmp_id, file_line) == 0)
8006 {
8007 for (k = 1; k <= RNAstrand_IN_PROGRESS; k++)
8008 {
8009 if (StringCmp (cp, RNAstrand_strings [k - 1]) == 0
8010 || (k == RNAstrand_MIXED
8011 && StringNCmp (cp, RNAstrand_strings [k - 1],
8012 StringLen (RNAstrand_strings[k - 1])) == 0))
8013 {
8014 vnp->choice = k;
8015 }
8016 }
8017 }
8018 }
8019 }
8020
8021 FileClose (fp);
8022
8023 FileRemove (path);
8024 return seq_num;
8025 }
8026
8027
8028 static ValNodePtr GetStrandednessFromSMART (SeqEntryPtr sep)
8029 {
8030 Char file_line [256];
8031 ValNodePtr sequence_list = NULL, vnp;
8032 Int4 num_sequences = 0, num_inspected;
8033
8034 if (sep == NULL) return NULL;
8035
8036 if (RNAstrandcmd == NULL) {
8037 if (GetAppParam ("SEQUIN", "RNACORRECT", "RNASTRAND", NULL, file_line, sizeof (file_line))) {
8038 RNAstrandcmd = StringSaveNoNull (file_line);
8039 }
8040 }
8041 if (RNAstrandcmd == NULL)
8042 {
8043 Message (MSG_ERROR, "RNASTRAND not set in config file!");
8044 return NULL;
8045 }
8046
8047
8048 VisitBioseqsInSep (sep, &sequence_list, GetAccessionList);
8049
8050 if (sequence_list == NULL)
8051 {
8052 Message (MSG_ERROR, "No sequences with accession numbers found!\n");
8053 return NULL;
8054 }
8055
8056 vnp = sequence_list;
8057 while ((num_inspected = GetSubListForRNAStrandCorrection (vnp, 25, RNAstrandcmd)) != 0)
8058 {
8059 num_sequences += num_inspected;
8060 while (num_inspected > 0 && vnp != NULL)
8061 {
8062 vnp = vnp->next;
8063 num_inspected --;
8064 }
8065 }
8066
8067 return sequence_list;
8068 }
8069
8070
8071 static void DoOneReverse (ValNodePtr vnp, Boolean rev_feats, FILE *fp)
8072 {
8073 BioseqPtr bsp;
8074 Char str [128];
8075 SeqEntryPtr sep;
8076
8077 if (vnp == NULL)
8078 {
8079 return;
8080 }
8081
8082 /* reverse sequence */
8083 bsp = BioseqFind (vnp->data.ptrvalue);
8084 BioseqRevComp (bsp);
8085 sep = GetTopSeqEntryForEntityID (bsp->idx.entityID);
8086 VisitAlignmentsInSep (sep, (Pointer) bsp, ReverseBioseqInAlignment);
8087
8088 if (fp != NULL && bsp != NULL && bsp->id != NULL) {
8089 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), str, PRINTID_REPORT, sizeof (str));
8090 fprintf (fp, "%s\n", str);
8091 }
8092
8093 if (rev_feats)
8094 {
8095 ReverseBioseqFeatureStrands (bsp);
8096 }
8097 }
8098
8099 static void RemoveAlignmentsWithSequenceCallback (SeqAnnotPtr sap, Pointer userdata)
8100 {
8101 SeqAlignPtr salp;
8102 SeqIdPtr sip;
8103
8104 if (sap == NULL || sap->type != 2 || userdata == NULL) return;
8105 salp = (SeqAlignPtr) sap->data;
8106 if (salp == NULL || salp->idx.deleteme) return;
8107 sip = (SeqIdPtr) userdata;
8108 while (sip != NULL && !sap->idx.deleteme) {
8109 if (FindSeqIdinSeqAlign (salp, sip)) {
8110 sap->idx.deleteme = TRUE;
8111 }
8112 sip = sip->next;
8113 }
8114 }
8115
8116 extern void RemoveAlignmentsWithSequence (BioseqPtr bsp, Uint2 input_entityID)
8117 {
8118 SeqEntryPtr topsep;
8119
8120 if (bsp == NULL) return;
8121 topsep = GetTopSeqEntryForEntityID (input_entityID);
8122
8123 VisitAnnotsInSep (topsep, bsp->id, RemoveAlignmentsWithSequenceCallback);
8124 }
8125
8126 extern void FlipEntireAlignmentIfAllSequencesFlipped (SeqAnnotPtr sap, Pointer userdata)
8127 {
8128 SeqAlignPtr salp;
8129 ValNodePtr vnp;
8130 BioseqPtr bsp;
8131 SeqIdPtr sip;
8132 Boolean found;
8133 Int4 row, num_rows;
8134
8135 if (sap == NULL || sap->type != 2 || userdata == NULL) return;
8136 salp = (SeqAlignPtr) sap->data;
8137 if (salp == NULL || salp->idx.deleteme) return;
8138
8139
8140 AlnMgr2IndexSingleChildSeqAlign(salp);
8141 num_rows = AlnMgr2GetNumRows(salp);
8142 for (row = 1; row <= num_rows; row++) {
8143 sip = AlnMgr2GetNthSeqIdPtr(salp, row);
8144 found = FALSE;
8145 vnp = (ValNodePtr)userdata;
8146 while (vnp != NULL && !found) {
8147 bsp = (BioseqPtr) vnp->data.ptrvalue;
8148 if (SeqIdOrderInBioseqIdList (sip, bsp->id) > 0) {
8149 found = TRUE;
8150 }
8151 vnp = vnp->next;
8152 }
8153 if (!found) return;
8154 }
8155
8156 FlipAlignment(salp);
8157 }
8158
8159
8160 static Boolean CheckForAlignmentsBeforeCorrection (RNAStrandPtr strand_info)
8161 {
8162 ValNodePtr vnp, seq_in_aln = NULL, aln_bsp = NULL;
8163 BioseqPtr bsp;
8164 Char id_str[255];
8165 CharPtr msg;
8166 MsgAnswer ans;
8167 Boolean retval = TRUE;
8168 Int4 strand_num = 0;
8169 Uint2 entityID = 0;
8170
8171
8172 if (strand_info == NULL || strand_info->sequence_list == NULL) return FALSE;
8173
8174 for (vnp = strand_info->sequence_list, strand_num = 0; vnp != NULL; vnp = vnp->next, strand_num++) {
8175 if (!strand_info->selected [strand_num]) continue;
8176 bsp = BioseqFind (vnp->data.ptrvalue);
8177 if (bsp != NULL && IsBioseqInAnyAlignment (bsp, bsp->idx.entityID)) {
8178 entityID = bsp->idx.entityID;
8179 SeqIdWrite (vnp->data.ptrvalue, id_str, PRINTID_REPORT, sizeof (id_str) - 1);
8180 ValNodeAddPointer (&seq_in_aln, 0, StringSave (id_str));
8181 ValNodeAddPointer (&aln_bsp, 0, bsp);
8182 }
8183 }
8184 if (seq_in_aln != NULL) {
8185 msg = CreateListMessage ("Sequence",
8186 seq_in_aln->next == NULL
8187 ? " is in an alignment, which will become invalid. Do you want to remove the alignment?"
8188 : " are in alignments, which will become invalid unless all of the sequences in these alignments are reversed. Do you want to remove the alignments?",
8189 seq_in_aln);
8190 seq_in_aln = ValNodeFreeData (seq_in_aln);
8191 ans = Message (MSG_YNC, msg);
8192 msg = MemFree (msg);
8193 if (ans == ANS_YES) {
8194 /* remove the alignments */
8195 for (vnp = aln_bsp; vnp != NULL; vnp = vnp->next) {
8196 bsp = vnp->data.ptrvalue;
8197 RemoveAlignmentsWithSequence (bsp, bsp->idx.entityID);
8198 DeleteMarkedObjects (bsp->idx.entityID, 0, NULL);
8199 }
8200 } else if (ans == ANS_CANCEL) {
8201 retval = FALSE;
8202 } else {
8203 VisitAnnotsInSep (GetTopSeqEntryForEntityID (entityID), aln_bsp, FlipEntireAlignmentIfAllSequencesFlipped);
8204 }
8205 aln_bsp = ValNodeFree (aln_bsp);
8206 }
8207 return retval;
8208 }
8209
8210 static void DoRNACorrection (ButtoN b)
8211 {
8212 RNAStrandPtr strand_info;
8213 Int4 strand_num = 0;
8214 ValNodePtr vnp;
8215 Boolean rev_feats;
8216 FILE *fp;
8217 Char path [PATH_MAX];
8218
8219 strand_info = (RNAStrandPtr) GetObjectExtra (b);
8220 if (strand_info == NULL)
8221 {
8222 return;
8223 }
8224
8225 rev_feats = GetStatus (strand_info->rev_feats);
8226
8227 /* check for alignments */
8228 if (!CheckForAlignmentsBeforeCorrection (strand_info)) {
8229 return;
8230 }
8231
8232 TmpNam (path);
8233 fp = FileOpen (path, "w");
8234 if (fp != NULL) {
8235 for (vnp = strand_info->sequence_list, strand_num = 0;
8236 vnp != NULL;
8237 vnp = vnp->next, strand_num++)
8238 {
8239 if (strand_info->selected [strand_num])
8240 {
8241 /* reverse sequence */
8242 DoOneReverse (vnp, rev_feats, fp);
8243 }
8244 }
8245
8246 FileClose (fp);
8247 LaunchGeneralTextViewer (path, "Flipped Sequences");
8248 FileRemove (path);
8249 } else {
8250 Message (MSG_ERROR, "Unable to open file for flip report");
8251 }
8252
8253 ObjMgrSetDirtyFlag (strand_info->input_entityID, TRUE);
8254 ObjMgrSendMsg (OM_MSG_UPDATE, strand_info->input_entityID, 0, 0);
8255 Remove (strand_info->form);
8256 Update ();
8257 }
8258
8259 static void CleanupRNAStrandFormProc (GraphiC g, Pointer data)
8260 {
8261 RNAStrandPtr strand_info;
8262
8263 if (data != NULL)
8264 {
8265 strand_info = (RNAStrandPtr) data;
8266 strand_info->sequence_list = ValNodeFree (strand_info->sequence_list);
8267 strand_info->selected = MemFree (strand_info->selected);
8268 strand_info = MemFree (strand_info);
8269 }
8270 }
8271
8272 static Int4 GetSeqNumFromListPos (Int4 list_pos, ValNodePtr sequence_list)
8273 {
8274 Int4 seq_num = 0, list_offset;
8275 ValNodePtr vnp;
8276 ERNAstrand_group_num group;
8277
8278 if (sequence_list == NULL)
8279 {
8280 return 0;
8281 }
8282
8283 list_offset = -1;
8284 for (group = RNASTRANDGRP_ERROR; group <= RNASTRANDGRP_PLUS && list_offset != list_pos; group++)
8285 {
8286 for (vnp = sequence_list, seq_num = -1;
8287 vnp != NULL && list_offset != list_pos;
8288 vnp = vnp->next, seq_num++)
8289 {
8290 if (GetRNAStrandGroupNum(vnp) == group)
8291 {
8292 list_offset ++;
8293 }
8294 }
8295 }
8296
8297 return seq_num;
8298 }
8299
8300 static void ReleaseRNAStrand (DoC d, PoinT pt)
8301
8302 {
8303 Int2 col;
8304 RNAStrandPtr strand_info;
8305 Int2 item;
8306 RecT rct;
8307 Int2 row;
8308 Int4 seq_num;
8309
8310 strand_info = (RNAStrandPtr) GetObjectExtra (d);
8311 if (strand_info != NULL && strand_info->selected != NULL) {
8312 MapDocPoint (d, pt, &item, &row, &col, &rct);
8313 rct.left += 1;
8314 rct.right = rct.left + strand_info->lineheight;
8315 rct.bottom = rct.top + (rct.right - rct.left);
8316 if (row == 1 && col == 3 && PtInRect (pt, &rct))
8317 {
8318 seq_num = GetSeqNumFromListPos (item - 1, strand_info->sequence_list);
8319 if (seq_num > -1 && seq_num < strand_info->num_sequences)
8320 {
8321 if (strand_info->selected [seq_num]) {
8322 strand_info->selected [seq_num] = FALSE;
8323 } else {
8324 strand_info->selected [seq_num] = TRUE;
8325 }
8326 InsetRect (&rct, -1, -1);
8327 InvalRect (&rct);
8328 Update ();
8329 }
8330 }
8331 }
8332 }
8333
8334 static void DrawRNAStrand (DoC d, RectPtr r, Int2 item, Int2 firstLine)
8335
8336 {
8337 RNAStrandPtr strand_info;
8338 RecT rct;
8339 RecT doc_rect;
8340 Int4 seq_num;
8341
8342 strand_info = (RNAStrandPtr) GetObjectExtra (d);
8343
8344 if (strand_info == NULL || r == NULL
8345 || item < 1 || item > strand_info->num_sequences
8346 || firstLine != 0)
8347 {
8348 return;
8349 }
8350
8351 rct = *r;
8352 rct.right --;
8353 rct.left = rct.right - strand_info->lineheight;
8354 rct.bottom = rct.top + (rct.right - rct.left);
8355
8356 /* make sure we don't draw a box where we aren't drawing text */
8357 ObjectRect (strand_info->doc, &doc_rect);
8358 InsetRect (&doc_rect, 4, 4);
8359 if (rct.bottom > doc_rect.bottom)
8360 {
8361 return;
8362 }
8363
8364 FrameRect (&rct);
8365
8366 seq_num = GetSeqNumFromListPos (item - 1, strand_info->sequence_list);
8367 if (seq_num > -1 && seq_num < strand_info->num_sequences) {
8368 if (strand_info->selected != NULL && strand_info->selected [seq_num]) {
8369 MoveTo (rct.left, rct.top);
8370 LineTo (rct.right - 1, rct.bottom - 1);
8371 MoveTo (rct.left, rct.bottom - 1);
8372 LineTo (rct.right - 1, rct.top);
8373 }
8374 }
8375 }
8376
8377 static void GetRNAStrandDesc (ValNodePtr vnp, CharPtr doc_line)
8378 {
8379 if (vnp == NULL || doc_line == NULL) return;
8380
8381 if (vnp->choice == RNAstrand_MINUS) {
8382 StringCat (doc_line, "\tMINUS\t\n");
8383 } else if (vnp->choice == RNAstrand_PLUS) {
8384 StringCat (doc_line, "\tPLUS\t\n");
8385 } else {
8386 StringCat (doc_line, "\t");
8387 if (vnp->choice == 0)
8388 {
8389 StringCat (doc_line, "Unknown error");
8390 }
8391 else
8392 {
8393 StringCat (doc_line, RNAstrand_strings [vnp->choice - 1]);
8394 }
8395 StringCat (doc_line, "\t\n");
8396 }
8397 }
8398
8399 static void RedrawRNAStrandDialog (RNAStrandPtr strand_info)
8400 {
8401 Int4 strand_num;
8402 Char doc_line [500];
8403 ValNodePtr vnp;
8404 ERNAstrand_group_num group_num;
8405
8406 if (strand_info == NULL)
8407 {
8408 return;
8409 }
8410
8411 Reset (strand_info->doc);
8412
8413 for (group_num = RNASTRANDGRP_ERROR;
8414 group_num <= RNASTRANDGRP_PLUS;
8415 group_num++)
8416 {
8417 for (vnp = strand_info->sequence_list, strand_num = 0;
8418 vnp != NULL;
8419 vnp = vnp->next, strand_num++)
8420 {
8421 if (GetRNAStrandGroupNum(vnp) != group_num) continue;
8422 SeqIdWrite (vnp->data.ptrvalue, doc_line, PRINTID_TEXTID_ACC_ONLY, 255);
8423 GetRNAStrandDesc (vnp, doc_line);
8424 AppendText (strand_info->doc, doc_line, &(strand_info->rnaParFmt), strand_info->rnaColFmt, programFont);
8425 if (group_num == RNASTRANDGRP_MINUS) strand_info->selected[strand_num] = TRUE;
8426 }
8427 }
8428
8429 UpdateDocument (strand_info->doc, 0, 0);
8430 }
8431
8432 static void RefreshRNAStrandDialog (ButtoN b)
8433 {
8434 RNAStrandPtr strand_info;
8435 ValNodePtr new_seq_list;
8436
8437 strand_info = (RNAStrandPtr) GetObjectExtra (b);
8438 if (strand_info == NULL)
8439 {
8440 return;
8441 }
8442
8443 if (strand_info->use_smart) {
8444 new_seq_list = GetStrandednessFromSMART (strand_info->sep);
8445 } else {
8446 new_seq_list = GetRNAStrandednessFromLocalDatabase (strand_info->sep, strand_info->database);
8447 }
8448
8449 if (new_seq_list == NULL)
8450 {
8451 Message (MSG_ERROR, "Unable to refresh sequence list.");
8452 return;
8453 }
8454 strand_info->sequence_list = ValNodeFree (strand_info->sequence_list);
8455 strand_info->sequence_list = new_seq_list;
8456
8457 RedrawRNAStrandDialog (strand_info);
8458 }
8459
8460
8461 static void ChangeStrandSmart (ButtoN b)
8462 {
8463 RNAStrandPtr strand_info;
8464
8465 strand_info = (RNAStrandPtr) GetObjectExtra (b);
8466 if (strand_info == NULL)
8467 {
8468 return;
8469 }
8470 strand_info->use_smart = GetStatus (strand_info->use_smart_btn);
8471 RefreshRNAStrandDialog (strand_info->use_smart_btn);
8472 }
8473
8474
8475 static Int2 CorrectRNAStrandednessForEntityID (Uint2 entityID, Boolean use_smart)
8476
8477 {
8478 SeqEntryPtr sep;
8479 ValNodePtr sequence_list = NULL;
8480 RNAStrandPtr strand_info;
8481 WindoW w;
8482 GrouP h, c;
8483 ButtoN b;
8484 RecT r;
8485 ButtoN refresh_btn;
8486
8487 sep = GetTopSeqEntryForEntityID (entityID);
8488 if (sep == NULL) return OM_MSG_RET_ERROR;
8489
8490 if (use_smart)
8491 {
8492 sequence_list = GetStrandednessFromSMART (sep);
8493 }
8494 else
8495 {
8496 sequence_list = GetRNAStrandednessFromLocalDatabase (sep, kRNAStrandDatabaseName);
8497 }
8498
8499 if (sequence_list == NULL)
8500 {
8501 return OM_MSG_RET_ERROR;
8502 }
8503
8504 strand_info = (RNAStrandPtr) MemNew (sizeof (RNAStrandData));
8505 if (strand_info == NULL)
8506 {
8507 return OM_MSG_RET_ERROR;
8508 }
8509
8510 strand_info->input_entityID = entityID;
8511 strand_info->sep = sep;
8512 strand_info->sequence_list = sequence_list;
8513 strand_info->num_sequences = ValNodeLen (sequence_list);
8514 strand_info->selected = (BoolPtr) MemNew (strand_info->num_sequences * sizeof (Boolean));
8515 strand_info->database = kRNAStrandDatabaseName;
8516 strand_info->use_smart = use_smart;
8517
8518 /* initialize document paragraph format */
8519 strand_info->rnaParFmt.openSpace = FALSE;
8520 strand_info->rnaParFmt.keepWithNext = FALSE;
8521 strand_info->rnaParFmt.keepTogether = FALSE;
8522 strand_info->rnaParFmt.newPage = FALSE;
8523 strand_info->rnaParFmt.tabStops = FALSE;
8524 strand_info->rnaParFmt.minLines = 0;
8525 strand_info->rnaParFmt.minHeight = 0;
8526
8527 /* initialize document column format */
8528 strand_info->rnaColFmt[0].pixWidth = 0;
8529 strand_info->rnaColFmt[0].pixInset = 0;
8530 strand_info->rnaColFmt[0].charWidth = 80;
8531 strand_info->rnaColFmt[0].charInset = 0;
8532 strand_info->rnaColFmt[0].font = NULL;
8533 strand_info->rnaColFmt[0].just = 'l';
8534 strand_info->rnaColFmt[0].wrap = TRUE;
8535 strand_info->rnaColFmt[0].bar = FALSE;
8536 strand_info->rnaColFmt[0].underline = FALSE;
8537 strand_info->rnaColFmt[0].left = FALSE;
8538 strand_info->rnaColFmt[0].last = FALSE;
8539 strand_info->rnaColFmt[1].pixWidth = 0;
8540 strand_info->rnaColFmt[1].pixInset = 0;
8541 strand_info->rnaColFmt[1].charWidth = 80;
8542 strand_info->rnaColFmt[1].charInset = 0;
8543 strand_info->rnaColFmt[1].font = NULL;
8544 strand_info->rnaColFmt[1].just = 'l';
8545 strand_info->rnaColFmt[1].wrap = TRUE;
8546 strand_info->rnaColFmt[1].bar = FALSE;
8547 strand_info->rnaColFmt[1].underline = FALSE;
8548 strand_info->rnaColFmt[1].left = FALSE;
8549 strand_info->rnaColFmt[1].last = FALSE;
8550 strand_info->rnaColFmt[2].pixWidth = 0;
8551 strand_info->rnaColFmt[2].pixInset = 0;
8552 strand_info->rnaColFmt[2].charWidth = 80;
8553 strand_info->rnaColFmt[2].charInset = 0;
8554 strand_info->rnaColFmt[2].font = NULL;
8555 strand_info->rnaColFmt[2].just = 'l';
8556 strand_info->rnaColFmt[2].wrap = TRUE;
8557 strand_info->rnaColFmt[2].bar = FALSE;
8558 strand_info->rnaColFmt[2].underline = FALSE;
8559 strand_info->rnaColFmt[2].left = FALSE;
8560 strand_info->rnaColFmt[2].last = TRUE;
8561
8562 w = FixedWindow (50, 33, -10, -10, "Correct RNA Strandedness", NULL);
8563 SetObjectExtra (w, strand_info, CleanupRNAStrandFormProc);
8564 strand_info->form = (ForM) w;
8565
8566 h = HiddenGroup (w, -1, 0, NULL);
8567 SetGroupSpacing (h, 10, 10);
8568
8569 strand_info->doc = DocumentPanel (h, stdCharWidth * 27, stdLineHeight * 8);
8570 SetObjectExtra (strand_info->doc, strand_info, NULL);
8571 SetDocAutoAdjust (strand_info->doc, TRUE);
8572 SetDocProcs (strand_info->doc, NULL, NULL, ReleaseRNAStrand, NULL);
8573 SetDocShade (strand_info->doc, DrawRNAStrand, NULL, NULL, NULL);
8574
8575 SelectFont (programFont);
8576 strand_info->lineheight = LineHeight ();
8577
8578 ObjectRect (strand_info->doc, &r);
8579 InsetRect (&r, 4, 4);
8580 strand_info->rnaColFmt[0].pixWidth = (r.right - r.left - strand_info->lineheight) / 2;
8581 strand_info->rnaColFmt[1].pixWidth = (r.right - r.left - strand_info->lineheight) / 2;
8582 strand_info->rnaColFmt[2].pixWidth = strand_info->lineheight;
8583
8584 refresh_btn = PushButton (h, "Refresh Strand Results", RefreshRNAStrandDialog);
8585 SetObjectExtra (refresh_btn, strand_info, NULL);
8586 strand_info->rev_feats = CheckBox (h, "Also reverse features", NULL);
8587 SetStatus (strand_info->rev_feats, FALSE);
8588 strand_info->use_smart_btn = CheckBox (h, "Use SMART for strand information", ChangeStrandSmart);
8589 SetObjectExtra (strand_info->use_smart_btn, strand_info, NULL);
8590 SetStatus (strand_info->use_smart_btn, strand_info->use_smart);
8591
8592 c = HiddenGroup (h, 2, 0, NULL);
8593 b = PushButton (c, "Autocorrect Minus Strands", DoRNACorrection);
8594 SetObjectExtra (b, strand_info, NULL);
8595 b = PushButton (c, "Cancel", StdCancelButtonProc);
8596
8597 AlignObjects (ALIGN_CENTER, (HANDLE) strand_info->doc,
8598 (HANDLE) refresh_btn,
8599 (HANDLE) strand_info->use_smart_btn,
8600 (HANDLE) strand_info->rev_feats,
8601 (HANDLE) c,
8602 NULL);
8603 RedrawRNAStrandDialog (strand_info);
8604 Show (w);
8605 return OM_MSG_RET_OK;
8606 }
8607
8608
8609 static Int2 LIBCALLBACK CorrectRNAStrandednessEx (Pointer data, Boolean use_smart)
8610 {
8611 OMProcControlPtr ompcp;
8612
8613 ompcp = (OMProcControlPtr) data;
8614 if (ompcp == NULL)
8615 {
8616 Message (MSG_ERROR, "You must select something!");
8617 return OM_MSG_RET_ERROR;
8618 }
8619
8620 return CorrectRNAStrandednessForEntityID (ompcp->input_entityID, use_smart);
8621 }
8622
8623
8624 extern Int2 LIBCALLBACK CorrectRNAStrandedness (Pointer data)
8625 {
8626 return CorrectRNAStrandednessEx (data, FALSE);
8627 }
8628 extern Int2 LIBCALLBACK CorrectRNAStrandednessUseSmart (Pointer data)
8629 {
8630 return CorrectRNAStrandednessEx (data, TRUE);
8631 }
8632
8633 extern void CorrectRNAStrandednessMenuItem (IteM i)
8634 {
8635 BaseFormPtr bfp;
8636
8637 #ifdef WIN_MAC
8638 bfp = currentFormDataPtr;
8639 #else
8640 bfp = GetObjectExtra (i);
8641 #endif
8642 if (bfp == NULL) return;
8643
8644 CorrectRNAStrandednessForEntityID (bfp->input_entityID, TRUE);
8645 }
8646
8647
8648 /* collection_date has a controlled format.
8649 * It is YYYY or Mmm-YYYY or DD-Mmm-YYYY where Mmm = Jan, Feb, Mar, Apr, May,
8650 * Jun, Jul, Aug, Sep, Oct,
8651 * Nov, Dec
8652 * This function will convert other formats to this format.
8653 * For instance, September 12, 2004 should be converted to 12-Sep-2004
8654 * 12/15/2003 should be converted to 15-Dec-2003.
8655 *
8656 * If the date supplied is ambiguous (01/03/05), can you allow the indexer to choose which field goes in Mmm and which in DD.
8657 */
8658
8659 typedef struct parsecollectiondate
8660 {
8661 Int4 num_successful;
8662 Int4 num_unsuccessful;
8663 Boolean month_first;
8664 } ParseCollectionDateData, PNTR ParseCollectionDatePtr;
8665
8666 static void ParseCollectionDateCallback (BioSourcePtr biop, Pointer userdata)
8667 {
8668 SubSourcePtr ssp;
8669 CharPtr reformatted_date = NULL;
8670 ParseCollectionDatePtr pcdp;
8671
8672 if (biop == NULL || biop->subtype == NULL || userdata == NULL)
8673 {
8674 return;
8675 }
8676
8677 pcdp = (ParseCollectionDatePtr) userdata;
8678
8679 ssp = biop->subtype;
8680 while (ssp != NULL)
8681 {
8682 if (ssp->subtype == SUBSRC_collection_date)
8683 {
8684 reformatted_date = ReformatDateStringEx (ssp->name, pcdp->month_first, NULL);
8685 if (reformatted_date == NULL)
8686 {
8687 pcdp->num_unsuccessful ++;
8688 }
8689 else
8690 {
8691 ssp->name = MemFree (ssp->name);
8692 ssp->name = reformatted_date;
8693 pcdp->num_successful ++;
8694 }
8695 }
8696 ssp = ssp->next;
8697 }
8698 }
8699
8700 static void CountParseCollectionDateCallback (BioSourcePtr biop, Pointer userdata)
8701 {
8702 SubSourcePtr ssp;
8703 CharPtr reformatted_date = NULL;
8704 ParseCollectionDatePtr pcdp;
8705
8706 if (biop == NULL || biop->subtype == NULL || userdata == NULL)
8707 {
8708 return;
8709 }
8710
8711 pcdp = (ParseCollectionDatePtr) userdata;
8712
8713 ssp = biop->subtype;
8714 while (ssp != NULL)
8715 {
8716 if (ssp->subtype == SUBSRC_collection_date)
8717 {
8718 reformatted_date = ReformatDateStringEx (ssp->name, pcdp->month_first, NULL);
8719 if (reformatted_date == NULL)
8720 {
8721 pcdp->num_unsuccessful++;
8722 }
8723 else
8724 {
8725 MemFree (reformatted_date);
8726 pcdp->num_successful ++;
8727 }
8728 }
8729 ssp = ssp->next;
8730 }
8731 }
8732
8733 static void ParseCollectionDate (IteM i, Boolean month_first)