|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/sequin/sequin6.c |
source navigation diff markup identifier search freetext search file search |
1 /* sequin6.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: sequin6.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 11/12/97
31 *
32 * $Revision: 6.347 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44
45 #include "sequin.h"
46 #include <ncbilang.h>
47 #include <gather.h>
48 #include <asn2gnbp.h>
49 #include <bspview.h>
50 #include <import.h>
51 #include <objsub.h>
52 #include <explore.h>
53 #include <subutil.h>
54 #include <gbftdef.h>
55 #include <edutil.h>
56 #include <salpanel.h>
57 #include <seqpanel.h>
58 #include <biosrc.h>
59 #include <vsm.h>
60 #include <actutils.h>
61 #include <findrepl.h>
62 #define NLM_GENERATED_CODE_PROTO
63 #include <objmacro.h>
64 #include <macrodlg.h>
65 #include <macroapi.h>
66
67 #define NUMBER_OF_SUFFIXES 7
68
69 static ENUM_ALIST(name_suffix_alist)
70 {" ", 0},
71 {"Jr.", 1},
72 {"Sr.", 2},
73 {"II", 4},
74 {"III", 5},
75 {"IV", 6},
76 {"V", 7},
77 {"VI", 8},
78 END_ENUM_ALIST
79
80
81 #define PUBLICATION_PUBLISHED_FIELD 1
82 #define PUBLICATION_INPRESS_FIELD 2
83 #define PUBLICATION_UNPUB_FIELD 3
84
85 static ENUM_ALIST (publication_field_alist)
86 {" ", 0},
87 {"Published", PUBLICATION_PUBLISHED_FIELD},
88 {"In Press", PUBLICATION_INPRESS_FIELD},
89 {"Unpublished", PUBLICATION_UNPUB_FIELD},
90 END_ENUM_ALIST
91
92
93 #define GENE_LOCUS_FIELD 1
94 #define GENE_DESCRIPTION_FIELD 2
95 #define GENE_ALLELE_FIELD 3
96 #define GENE_MAPLOC_FIELD 4
97 #define GENE_LOCUS_TAG_FIELD 5
98 #define GENE_SYNONYM_FIELD 6
99 #define GENE_COMMENT_FIELD 7
100
101 static ENUM_ALIST(gene_field_alist)
102 {" ", 0},
103 {"Gene locus", GENE_LOCUS_FIELD},
104 {"Gene description", GENE_DESCRIPTION_FIELD},
105 {"Gene allele", GENE_ALLELE_FIELD},
106 {"Gene maploc", GENE_MAPLOC_FIELD},
107 {"Locus_tag", GENE_LOCUS_TAG_FIELD},
108 {"Gene synonym", GENE_SYNONYM_FIELD},
109 {"Gene comment", GENE_COMMENT_FIELD},
110 END_ENUM_ALIST
111
112 #define CDS_COMMENT 1
113 #define CDS_GENE_XREF 2
114 #define CDS_DB_XREF 3
115
116 static ENUM_ALIST(cds_field_alist)
117 {" ", 0},
118 {"CDS comment", CDS_COMMENT},
119 {"gene xref", CDS_GENE_XREF},
120 {"db_xref", CDS_DB_XREF},
121 END_ENUM_ALIST
122
123 static ENUM_ALIST(cds_short_field_alist)
124 {" ", 0},
125 {"CDS comment", CDS_COMMENT},
126 END_ENUM_ALIST
127
128 #define PROT_NAME_FIELD 1
129 #define PROT_DESCRIPTION_FIELD 2
130 #define PROT_ECNUM_FIELD 3
131 #define PROT_ACTIVITY_FIELD 4
132 #define PROT_COMMENT_FIELD 5
133
134 static ENUM_ALIST(prot_field_alist)
135 {" ", 0},
136 {"Protein name", PROT_NAME_FIELD},
137 {"Protein description", PROT_DESCRIPTION_FIELD},
138 {"Protein E.C. number", PROT_ECNUM_FIELD},
139 {"Protein activity", PROT_ACTIVITY_FIELD},
140 {"Protein comment", PROT_COMMENT_FIELD},
141 END_ENUM_ALIST
142
143 #define RNA_NAME_FIELD 1
144 #define RNA_COMMENT_FIELD 2
145 #define RNA_GENE_XREF_FIELD 3
146
147 static ENUM_ALIST(rnax_field_alist)
148 {" ", 0},
149 {"RNA Name", RNA_NAME_FIELD},
150 {"RNA Comment", RNA_COMMENT_FIELD},
151 {"gene xref", RNA_GENE_XREF_FIELD},
152 END_ENUM_ALIST
153
154 static ENUM_ALIST(rnax_short_field_alist)
155 {" ", 0},
156 {"RNA Name", RNA_NAME_FIELD},
157 {"RNA Comment", RNA_COMMENT_FIELD},
158 {"gene xref", RNA_GENE_XREF_FIELD},
159 END_ENUM_ALIST
160
161 #define ORGREF_SCI_NAME_FIELD 1
162 #define ORGREF_COMMON_NAME_FIELD 2
163 #define ORGREF_LINEAGE_FIELD 3
164 #define ORGREF_DIVISION_FIELD 4
165
166 static ENUM_ALIST(orgref_field_alist)
167 {" ", 0},
168 {"Scientific Name", ORGREF_SCI_NAME_FIELD},
169 {"Common Name", ORGREF_COMMON_NAME_FIELD},
170 {"Lineage", ORGREF_LINEAGE_FIELD},
171 {"Division", ORGREF_DIVISION_FIELD},
172 END_ENUM_ALIST
173
174 #define IMPORT_GBQUAL_FIELD 1
175 #define IMPORT_COMMENT_FIELD 2
176
177 static ENUM_ALIST(impfeat_field_alist)
178 {" ", 0},
179 {"GBQual", IMPORT_GBQUAL_FIELD},
180 {"Comment", IMPORT_COMMENT_FIELD},
181 END_ENUM_ALIST
182
183
184 #define NUM_SUBTARGET_POPUPS 12
185
186 static GbFeatName ParseQualifierList[] = {
187 {"allele", Class_text}, {"anticodon", Class_pos_aa},
188 {"bound_moiety", Class_text},
189 {"chromosome", Class_text},
190 {"citation", Class_bracket_int},
191 {"codon", Class_seq_aa},
192 {"codon_start", Class_int_or}, {"cons_splice", Class_site},
193 {"db_xref", Class_text},
194 {"direction", Class_L_R_B}, {"EC_number", Class_ecnum},
195 {"evidence", Class_exper}, {"exception", Class_text},
196 {"frequency", Class_text}, {"function", Class_text},
197 {"gene", Class_text}, {"gdb_xref", Class_text},
198 {"insertion_seq", Class_text},
199 {"label", Class_token},
200 {"map", Class_text},
201 {"mod_base", Class_token}, {"note", Class_note},
202 {"number", Class_number}, {"organism", Class_text},
203 {"partial", Class_none}, {"PCR_conditions", Class_text},
204 {"phenotype", Class_text},
205 {"plasmid", Class_text}, {"product", Class_text},
206 {"pseudo", Class_none},
207 {"rearranged", Class_none}, { "replace", Class_text},
208 {"rpt_family", Class_text}, {"rpt_type", Class_rpt},
209 {"rpt_unit", Class_token},
210 {"sequenced_mol", Class_text},
211 {"standard_name", Class_text},
212 {"translation", Class_text}, {"transl_except", Class_pos_aa},
213 {"transl_table", Class_int}, {"transposon", Class_text},
214 {"usedin", Class_token},
215 {"focus", Class_none},
216 {"protein_id", Class_text},
217 {"organelle", Class_text}, {"transcript_id", Class_text},
218 {"transgenic", Class_none}, {"environmental_sample", Class_none},
219 {"locus_tag", Class_text}, {"mol_type", Class_text},
220 };
221
222 const Int4 NumParseQualifiers = sizeof (ParseQualifierList) / sizeof (GbFeatName);
223
224
225 static void PopulateParseQualPopup (PopuP p)
226 {
227 Int4 i;
228 for (i = 0; i < NumParseQualifiers; i++) {
229 PopupItem (p, ParseQualifierList[i].name);
230 }
231 }
232
233
234 static DialoG ImpFeatSelectDialog (GrouP g, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
235 {
236 EnumFieldAssocPtr list, ap;
237 ValNodePtr choice_list = NULL;
238
239 list = import_featdef_alist (FALSE, FALSE, FALSE);
240 SortEnumFieldAssocPtrArray (list, CompareImpFeatEnumFieldAssoc);
241 for (ap = list; ap->name != NULL; ap++) {
242 if (ap == list) {
243 ValNodeAddPointer (&choice_list, 0, StringSave ("All import features"));
244 } else {
245 ValNodeAddPointer (&choice_list, 0, StringSave (ap->name));
246 }
247 }
248 return ValNodeSelectionDialog (g, choice_list, TALL_SELECTION_LIST,
249 ValNodeStringName,
250 ValNodeSimpleDataFree, ValNodeStringCopy,
251 ValNodeChoiceMatch, "Import Feature Type",
252 change_notify, change_userdata, FALSE);
253 }
254
255 typedef enum {
256 eFieldTypeGene = 0,
257 eFieldTypeCDS,
258 eFieldTypeProtein,
259 eFieldTypeRNA,
260 eFieldTypeBioSource,
261 eFieldTypeOrgModSubSource,
262 eFieldTypeImport,
263 eFieldTypeDefline,
264 eFieldTypeCommentDescriptor,
265 eFieldTypeFeatureNote,
266 eFieldTypePublication,
267 eFieldType_Max
268 } SegregateFieldType;
269
270 static CharPtr field_type_names[] = {
271 "Gene",
272 "CDS",
273 "Protein",
274 "RNA",
275 "BioSource",
276 "OrgMod and SubSource",
277 "Import Feature",
278 "DefLine",
279 "Comment Descriptor",
280 "Feature Note",
281 "Publication" };
282
283
284 typedef struct fieldsubfield {
285 Int4 field;
286 Int4 subfield;
287 CharPtr impfeat_key;
288 ValNodePtr subfield_list;
289 } FieldSubfieldData, PNTR FieldSubfieldPtr;
290
291
292 static FieldSubfieldPtr FieldSubfieldFree (FieldSubfieldPtr f)
293 {
294 if (f != NULL) {
295 f->subfield_list = ValNodeFree (f->subfield_list);
296 f->impfeat_key = MemFree (f->impfeat_key);
297 f = MemFree (f);
298 }
299 return f;
300 }
301
302
303 typedef struct fieldsubfielddlg {
304 DIALOG_MESSAGE_BLOCK
305 PopuP field_list;
306 DialoG subfield_dlg[eFieldType_Max];
307 DialoG impfeat_type;
308 Boolean allowed_fields[eFieldType_Max];
309 Nlm_ChangeNotifyProc change_notify;
310 Pointer change_userdata;
311 } FieldSubfieldDlgData, PNTR FieldSubfieldDlgPtr;
312
313
314 static Int4 FieldNumFromListVal (Int4 list_val, BoolPtr allowed_fields)
315 {
316 Int4 i;
317 Int4 field_num = -1;
318
319 if (list_val < 1) return -1;
320
321 for (i = 0; i < eFieldType_Max && field_num < 0; i++) {
322 if (allowed_fields[i]) {
323 if (list_val - 1 == i) {
324 field_num = i;
325 }
326 } else {
327 list_val++;
328 }
329 }
330 return field_num;
331 }
332
333
334 static Int4 ListValFromFieldNum (Int4 field_num, BoolPtr allowed_fields)
335 {
336 Int4 list_val = 0, i = 0;
337
338 if (field_num < 0) return 0;
339
340 while (i <= field_num) {
341 if (allowed_fields[i]) {
342 list_val++;
343 }
344 i++;
345 }
346 return list_val;
347 }
348
349
350 static void ChangeFieldType (PopuP p)
351 {
352 FieldSubfieldDlgPtr dlg;
353 Int4 list_val, field_num, i;
354
355 dlg = (FieldSubfieldDlgPtr) GetObjectExtra (p);
356 if (dlg == NULL) return;
357
358 list_val = GetValue (dlg->field_list);
359 field_num = FieldNumFromListVal (list_val, dlg->allowed_fields);
360
361 for (i = 0; i < eFieldType_Max; i++) {
362 if (dlg->subfield_dlg[i] == NULL) continue;
363 if (i == field_num) {
364 Show (dlg->subfield_dlg[i]);
365 } else {
366 Hide (dlg->subfield_dlg[i]);
367 }
368 }
369 if (field_num == eFieldTypeImport) {
370 Show (dlg->impfeat_type);
371 } else {
372 Hide (dlg->impfeat_type);
373 }
374 if (dlg->change_notify != NULL) {
375 (dlg->change_notify) (dlg->change_userdata);
376 }
377 }
378
379
380 static void FieldSubfieldToDialog (DialoG d, Pointer data)
381 {
382 FieldSubfieldDlgPtr dlg;
383 FieldSubfieldPtr f;
384 Int4 list_val;
385 ValNode vn;
386
387 dlg = (FieldSubfieldDlgPtr) GetObjectExtra (d);
388 if (dlg == NULL) return;
389
390 f = (FieldSubfieldPtr) data;
391 if (f == NULL || f->field < 0) {
392 SetValue (dlg->field_list, 0);
393 } else {
394 list_val = ListValFromFieldNum (f->field, dlg->allowed_fields);
395 SetValue (dlg->field_list, list_val);
396 if (dlg->subfield_dlg[f->field] != NULL) {
397 if (list_val == eFieldTypeFeatureNote) {
398 PointerToDialog (dlg->subfield_dlg[eFieldTypeFeatureNote], f->subfield_list);
399 } else {
400 vn.choice = f->subfield;
401 vn.data.ptrvalue = NULL;
402 vn.next = NULL;
403 PointerToDialog (dlg->subfield_dlg[f->field], &vn);
404 if (f->field == eFieldTypeImport) {
405 vn.choice = 0;
406 vn.data.ptrvalue = f->impfeat_key;
407 PointerToDialog (dlg->impfeat_type, &vn);
408 }
409 }
410 }
411 }
412 ChangeFieldType (dlg->field_list);
413 }
414
415
416 static Pointer DialogToFieldSubfield (DialoG d)
417 {
418 FieldSubfieldDlgPtr dlg;
419 FieldSubfieldPtr f;
420 Int4 val;
421 ValNodePtr vnp;
422 SourceQualDescPtr sqdp;
423
424 dlg = (FieldSubfieldDlgPtr) GetObjectExtra (d);
425 if (dlg == NULL) return NULL;
426
427 f = (FieldSubfieldPtr) MemNew (sizeof (FieldSubfieldData));
428 f->field = -1;
429 f->subfield = -1;
430 f->subfield_list = NULL;
431 f->impfeat_key = NULL;
432
433 val = GetValue (dlg->field_list);
434 if (val > 0) {
435 f->field = FieldNumFromListVal (val, dlg->allowed_fields);
436 if (dlg->subfield_dlg[f->field] == NULL) {
437 f->subfield = 0;
438 } else {
439 if (f->field == eFieldTypeFeatureNote) {
440 f->subfield_list = DialogToPointer (dlg->subfield_dlg[f->field]);
441 } else {
442 vnp = DialogToPointer (dlg->subfield_dlg[f->field]);
443 if (vnp != NULL) {
444 if (f->field == eFieldTypeOrgModSubSource) {
445 sqdp = (SourceQualDescPtr) vnp->data.ptrvalue;
446 if (sqdp != NULL) {
447 f->subfield = sqdp->subtype;
448 if (!sqdp->isOrgMod) {
449 f->subfield += 1000;
450 }
451 }
452 } else {
453 f->subfield = vnp->choice;
454 vnp = ValNodeFree (vnp);
455 }
456 }
457 if (f->field == eFieldTypeImport) {
458 vnp = DialogToPointer (dlg->impfeat_type);
459 if (vnp != NULL) {
460 f->impfeat_key = StringSave (vnp->data.ptrvalue);
461 vnp = ValNodeFree (vnp);
462 }
463 }
464 }
465 }
466 }
467
468 return f;
469 }
470
471
472 static ValNodePtr TestFieldSubfieldDialog (DialoG d)
473 {
474 ValNodePtr err_list = NULL;
475 FieldSubfieldPtr f;
476
477 f = DialogToPointer (d);
478 if (f == NULL || f->field < 0
479 || (f->subfield < 0 && f->subfield_list == NULL)
480 || (f->field == eFieldTypeImport && f->impfeat_key == NULL)) {
481 ValNodeAddPointer (&err_list, 0, "Must choose field");
482 }
483 f = FieldSubfieldFree (f);
484 return err_list;
485 }
486
487
488 static DialoG
489 CreateFieldSubfieldDlg
490 (GrouP h,
491 BoolPtr allowed_fields,
492 Nlm_ChangeNotifyProc change_notify,
493 Pointer change_userdata)
494 {
495 FieldSubfieldDlgPtr dlg;
496 GrouP p, g, g2;
497 Int4 i;
498 ValNode vn;
499
500 dlg = (FieldSubfieldDlgPtr) MemNew (sizeof (FieldSubfieldDlgData));
501 if (dlg == NULL)
502 {
503 return NULL;
504 }
505
506 p = HiddenGroup (h, 2, 0, NULL);
507 SetObjectExtra (p, dlg, StdCleanupExtraProc);
508
509 dlg->dialog = (DialoG) p;
510 dlg->todialog = FieldSubfieldToDialog;
511 dlg->fromdialog = DialogToFieldSubfield;
512 dlg->testdialog = TestFieldSubfieldDialog;
513 dlg->change_notify = change_notify;
514 dlg->change_userdata = change_userdata;
515
516 if (allowed_fields == NULL) {
517 MemSet (dlg->allowed_fields, TRUE, sizeof (dlg->allowed_fields));
518 } else {
519 for (i = 0; i < eFieldType_Max; i++) {
520 dlg->allowed_fields[i] = allowed_fields[i];
521 }
522 }
523
524 dlg->field_list = PopupList (p, TRUE, ChangeFieldType);
525 SetObjectExtra (dlg->field_list, dlg, NULL);
526 for (i = 0; i < eFieldType_Max; i++) {
527 if (dlg->allowed_fields[i]) {
528 PopupItem (dlg->field_list, field_type_names[i]);
529 }
530 }
531
532 g = HiddenGroup (p, 0, 0, NULL);
533 dlg->subfield_dlg[eFieldTypeGene] = EnumAssocSelectionDialog (g, gene_field_alist,
534 NULL, FALSE,
535 dlg->change_notify,
536 dlg->change_userdata);
537 dlg->subfield_dlg[eFieldTypeCDS] = EnumAssocSelectionDialog (g, cds_field_alist,
538 NULL, FALSE,
539 dlg->change_notify,
540 dlg->change_userdata);
541 dlg->subfield_dlg[eFieldTypeProtein] = EnumAssocSelectionDialog (g, prot_field_alist,
542 NULL, FALSE,
543 dlg->change_notify,
544 dlg->change_userdata);
545 dlg->subfield_dlg[eFieldTypeRNA] = EnumAssocSelectionDialog (g, rnax_field_alist,
546 NULL, FALSE,
547 dlg->change_notify,
548 dlg->change_userdata);
549 dlg->subfield_dlg[eFieldTypeBioSource] = EnumAssocSelectionDialog (g, orgref_field_alist,
550 NULL, FALSE,
551 dlg->change_notify,
552 dlg->change_userdata);
553 /* Set default BioSource field to scientific name */
554 vn.choice = ORGREF_SCI_NAME_FIELD;
555 vn.next = NULL;
556 vn.data.ptrvalue = NULL;
557 PointerToDialog (dlg->subfield_dlg[eFieldTypeBioSource], &vn);
558
559 dlg->subfield_dlg[eFieldTypeOrgModSubSource] = SourceQualTypeSelectionDialog (g, FALSE,
560 dlg->change_notify,
561 dlg->change_userdata);
562
563 if (dlg->allowed_fields[eFieldTypeImport]) {
564 g2 = HiddenGroup (g, 2, 0, NULL);
565 dlg->impfeat_type = ImpFeatSelectDialog (g2, change_notify, change_userdata);
566 Hide (dlg->impfeat_type);
567
568 dlg->subfield_dlg[eFieldTypeImport] = EnumAssocSelectionDialog (g2, impfeat_field_alist,
569 NULL, FALSE,
570 dlg->change_notify,
571 dlg->change_userdata);
572 }
573 dlg->subfield_dlg[eFieldTypeFeatureNote] = FeatureSelectionDialog (g, TRUE, dlg->change_notify, dlg->change_userdata);
574
575 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->subfield_dlg[eFieldTypeGene],
576 (HANDLE) dlg->subfield_dlg[eFieldTypeCDS],
577 (HANDLE) dlg->subfield_dlg[eFieldTypeProtein],
578 (HANDLE) dlg->subfield_dlg[eFieldTypeRNA],
579 (HANDLE) dlg->subfield_dlg[eFieldTypeBioSource],
580 (HANDLE) dlg->subfield_dlg[eFieldTypeOrgModSubSource],
581 (HANDLE) dlg->subfield_dlg[eFieldTypeFeatureNote],
582 (HANDLE) g2,
583 NULL);
584
585 for (i = 0; i < eFieldType_Max; i++) {
586 Hide (dlg->subfield_dlg[i]);
587 }
588 return (DialoG) p;
589 }
590
591
592 typedef struct convertformdata {
593 FEATURE_FORM_BLOCK
594
595 TexT deleteText;
596 CharPtr deleteStr;
597 GrouP deleteLevel;
598 Int2 deleteLevelInt;
599 DialoG target_dlg;
600 Int2 impfeat_type;
601 ButtoN accept;
602 ButtoN leaveDlgUp;
603 Int2 type;
604 Int2 subtype;
605
606 DialoG textportion_dlg;
607 TextPortionXPtr textportion;
608 Boolean remove_inside;
609
610 CharPtr foundstr;
611 GrouP repeat_remove_grp;
612
613 Boolean isDirty;
614 Boolean repeat_remove;
615 GrouP ifNotFoundGroup;
616 Int2 ifNotFound;
617 BioseqSetPtr target_set;
618 Nlm_ChangeNotifyProc set_accept_proc;
619 ValNodePtr id_list;
620
621 } ConvertFormData, PNTR ConvertFormPtr;
622
623 static ConvertFormPtr ConvertFormNew (void)
624 {
625 ConvertFormPtr cfp;
626
627 cfp = (ConvertFormPtr) MemNew (sizeof (ConvertFormData));
628 if (cfp == NULL) return NULL;
629 MemSet (cfp, 0, sizeof (ConvertFormData));
630 return cfp;
631 }
632
633
634 /* Values for ifNotFound field */
635
636 #define DO_NOTHING 2
637 #define REMOVE_ALL_TEXT 3
638
639 /* End values for string trimming */
640
641 #define TRIM_LEFT_END 1
642 #define TRIM_RIGHT_END 2
643
644 /*-------------------------------------------------------------------------*/
645 /* */
646 /* TrimOffEndQuotes () -- Trim double-quotes off the ends of a string. */
647 /* */
648 /*-------------------------------------------------------------------------*/
649
650 static Boolean TrimOffEndQuotes (CharPtr trimString,
651 Int2 whichEnd)
652 {
653 Int4 strLen;
654 Int4 i;
655
656 strLen = StringLen(trimString);
657 if (strLen == 0)
658 return FALSE;
659
660 /* If there is a quote at the end, remove it */
661
662 if (TRIM_RIGHT_END == whichEnd) {
663 if (trimString[strLen-1] == '"') {
664 strLen--;
665 trimString [strLen] = '\0';
666 return TRUE;
667 }
668 }
669
670 /* If there is a quote at the beginning, remove it */
671
672 else {
673 if (trimString[0] == '"') {
674 for (i = 0; trimString[i] != '\0'; i++)
675 trimString[i] = trimString [i+1];
676 return TRUE;
677 }
678 }
679
680 return FALSE;
681 }
682
683 /*-------------------------------------------------------------------------*/
684 /* */
685 /* SaveStringFromTextNoStripSpaces () - */
686 /* */
687 /*-------------------------------------------------------------------------*/
688
689 static CharPtr SaveStringFromTextNoStripSpaces (TexT t)
690
691 {
692 size_t len;
693 CharPtr str;
694
695 len = TextLength (t);
696 if (len > 0) {
697 str = (CharPtr) MemNew(len + 1);
698 if (str != NULL) {
699 GetTitle (t, str, len + 1);
700 return str;
701 } else {
702 return NULL;
703 }
704 } else {
705 return NULL;
706 }
707 }
708
709 static void ConvertFormTextCallback (TexT t)
710 {
711 ConvertFormPtr cfp;
712
713 cfp = (ConvertFormPtr) GetObjectExtra (t);
714 if (cfp != NULL && cfp->set_accept_proc != NULL) {
715 (cfp->set_accept_proc) (cfp);
716 }
717 }
718
719
720 /*-------------------------------------------------------------------------*/
721 /* */
722 /* SetDeleteAcceptButton () -- Enable/Disable the Accept button depending */
723 /* on the condition of other window objects. */
724 /* */
725 /*-------------------------------------------------------------------------*/
726
727 static void SetDeleteAcceptButton (Pointer data)
728
729 {
730 ConvertFormPtr cfp;
731 ValNodePtr vnp;
732
733 cfp = (ConvertFormPtr) data;
734 if (cfp == NULL)
735 return;
736
737 /* Disable if a target or subtarget has not been selected */
738 vnp = TestDialog (cfp->target_dlg);
739 if (vnp != NULL) {
740 vnp = ValNodeFree (vnp);
741 SafeDisable (cfp->accept);
742 } else if (TextHasNoText (cfp->deleteText)) {
743 /* Disable if there is no delete string */
744 SafeDisable (cfp->accept);
745 } else {
746 SafeEnable (cfp->accept);
747 }
748 }
749
750
751 static void ChangeTargetFields (Pointer data)
752
753 {
754 ConvertFormPtr cfp;
755
756 cfp = (ConvertFormPtr) data;
757 if (cfp == NULL) return;
758
759 if (cfp->set_accept_proc != NULL) {
760 cfp->set_accept_proc (cfp);
761 }
762 }
763
764
765 /*=========================================================================*/
766 /* */
767 /* CheckForString () -- Searches for a given string with another string. */
768 /* */
769 /*=========================================================================*/
770
771 static Boolean CheckForString (CharPtr searchStr,
772 CharPtr sourceStr)
773 {
774 if (NULL == SearchForString (sourceStr, searchStr, FALSE, FALSE))
775 return FALSE;
776 else
777 return TRUE;
778 }
779
780 /*=========================================================================*/
781 /* */
782 /* GeneRefPtr () -- Search a GeneRef feature for a given string. */
783 /* */
784 /*=========================================================================*/
785
786 static Boolean SearchGeneRef (GeneRefPtr grp,
787 SeqFeatPtr sfp,
788 ConvertFormPtr cfp)
789 {
790 ValNodePtr vnp;
791
792 /* Check parameters */
793
794 if ((NULL == grp) || (NULL == sfp))
795 return FALSE;
796
797 /* Check each text field for the given string */
798
799 switch (cfp->subtype) {
800 case 1 :
801 return CheckForString (cfp->deleteStr, grp->locus);
802 break;
803 case 2 :
804 return CheckForString (cfp->deleteStr, grp->desc);
805 break;
806 case 3 :
807 return CheckForString (cfp->deleteStr, grp->allele);
808 break;
809 case 4 :
810 return CheckForString (cfp->deleteStr, grp->maploc);
811 break;
812 case 5 :
813 return CheckForString (cfp->deleteStr, grp->locus_tag);
814 break;
815 case 6 :
816 for (vnp = grp->syn; vnp != NULL; vnp = vnp->next) {
817 if (TRUE == CheckForString (cfp->deleteStr,
818 vnp->data.ptrvalue))
819 return TRUE;
820 }
821 return FALSE;
822 break;
823 case 7 :
824 return CheckForString (cfp->deleteStr, sfp->comment);
825 break;
826 default :
827 break;
828 }
829
830 return FALSE;
831 }
832
833 /*=========================================================================*/
834 /* */
835 /* SearchCDSFeat () -- Search a CDS feature for a given string. */
836 /* */
837 /*=========================================================================*/
838
839 static Boolean SearchCDSFeat (SeqFeatPtr sfp,
840 ConvertFormPtr cfp)
841 {
842
843 /* Check parameters */
844
845 if (NULL == sfp)
846 return FALSE;
847
848 /* Check each text field for the given string */
849
850 switch (cfp->subtype) {
851 case 1 :
852 return CheckForString (cfp->deleteStr, sfp->comment);
853 break;
854 case 2 :
855 default :
856 break;
857 }
858
859 /* If no match found, return FALSE */
860
861 return FALSE;
862 }
863
864 /*=========================================================================*/
865 /* */
866 /* SearchRnaRef () -- Search an RnaRef feature for a given string. */
867 /* */
868 /*=========================================================================*/
869
870 static Boolean SearchRnaRef (RnaRefPtr rrp,
871 SeqFeatPtr sfp,
872 ConvertFormPtr cfp)
873 {
874 /* Check parameters */
875
876 if ((NULL == rrp) || (NULL == sfp))
877 return FALSE;
878
879 /* Check each text field for the given string */
880
881 switch (cfp->subtype) {
882 case 1 :
883 if ((0 == rrp->ext.choice) || (1 == rrp->ext.choice)) {
884 return CheckForString (cfp->deleteStr, rrp->ext.value.ptrvalue);
885 }
886 break;
887 case 2 :
888 return CheckForString (cfp->deleteStr, sfp->comment);
889 break;
890 case 3 :
891 default :
892 break;
893 }
894
895 /* If no match found, return FALSE */
896
897 return FALSE;
898 }
899
900 /*=========================================================================*/
901 /* */
902 /* SearchProtRef () -- Search a ProtRef feature for a given string. */
903 /* */
904 /*=========================================================================*/
905
906 static Boolean SearchProtRef (ProtRefPtr prp,
907 SeqFeatPtr sfp,
908 ConvertFormPtr cfp)
909 {
910 ValNodePtr vnp;
911
912 /* Check parameters */
913
914 if (NULL == prp)
915 return FALSE;
916
917 /* Check each text field for the given string */
918
919 switch (cfp->subtype) {
920
921 /* Search the name field */
922
923 case 1 :
924 for (vnp = prp->name; vnp != NULL; vnp = vnp->next) {
925 if (TRUE == CheckForString (cfp->deleteStr,
926 (CharPtr) vnp->data.ptrvalue))
927 return TRUE;
928 }
929 break;
930
931 /* Search the desc field */
932
933 case 2 :
934 return CheckForString (cfp->deleteStr, prp->desc);
935 break;
936
937 /* Search the ec field */
938
939 case 3 :
940 for (vnp = prp->ec; vnp != NULL; vnp = vnp->next) {
941 if (TRUE == CheckForString (cfp->deleteStr, vnp->data.ptrvalue))
942 return TRUE;
943 }
944 break;
945
946 /* Search the activity field */
947
948 case 4 :
949 for (vnp = prp->activity; vnp != NULL; vnp = vnp->next) {
950 if (TRUE == CheckForString (cfp->deleteStr, vnp->data.ptrvalue))
951 return TRUE;
952 }
953 break;
954
955 /* Search the comment field */
956
957 case 5 :
958 return CheckForString (cfp->deleteStr, sfp->comment);
959 break;
960
961 /* Default check */
962
963 default :
964 break;
965 }
966
967 /* If we made it this far no match was found */
968
969 return FALSE;
970 }
971
972 /*=========================================================================*/
973 /* */
974 /* SearchImpFeat () -- Search an ImpFeat feature for a given string. */
975 /* */
976 /*=========================================================================*/
977
978 static Boolean SearchImpFeat (SeqFeatPtr sfp,
979 ConvertFormPtr cfp)
980 {
981 GBQualPtr gbqp;
982
983 /* Check parameters */
984
985 if (NULL == sfp)
986 return FALSE;
987
988 switch (cfp->subtype) {
989
990 /* Search the GB Quals */
991
992 case IMPORT_GBQUAL_FIELD :
993 gbqp = sfp->qual;
994 while (NULL != gbqp) {
995 if (NULL != gbqp->val)
996 if (TRUE == CheckForString (cfp->deleteStr, gbqp->val))
997 return TRUE;
998 gbqp = gbqp->next;
999 }
1000 return FALSE;
1001 break;
1002
1003 /* Search the comment field */
1004
1005 case IMPORT_COMMENT_FIELD :
1006 return CheckForString (cfp->deleteStr, sfp->comment);
1007 break;
1008 default :
1009 break;
1010 }
1011
1012 return FALSE;
1013 }
1014
1015 /*=========================================================================*/
1016 /* */
1017 /* MarkObjectsByText_Callback () - Called for each object in a SeqEntry */
1018 /* this will mark the item for deletion */
1019 /* if it matches the given criteria. */
1020 /* */
1021 /*=========================================================================*/
1022
1023 static void DeleteFeaturesByText_Callback (SeqEntryPtr sep,
1024 Pointer mydata,
1025 Int4 index,
1026 Int2 indent)
1027 {
1028 ConvertFormPtr cfp;
1029 BioseqPtr bsp = NULL;
1030 BioseqSetPtr bssp = NULL;
1031 SeqAnnotPtr sap;
1032 SeqFeatPtr sfp;
1033 GeneRefPtr grp;
1034 ProtRefPtr prp;
1035 RnaRefPtr rrp;
1036 Boolean found = FALSE;
1037
1038 /* Check parameters */
1039
1040 if ((NULL == sep) || (NULL == sep->data.ptrvalue))
1041 return;
1042
1043 cfp = (ConvertFormPtr) mydata;
1044 if (NULL == cfp)
1045 return;
1046
1047 /* Get the list of annotations */
1048
1049 if (IS_Bioseq (sep)) {
1050 bsp = (BioseqPtr) sep->data.ptrvalue;
1051 sap = bsp->annot;
1052 }
1053 else if (IS_Bioseq_set (sep)) {
1054 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1055 sap = bssp->annot;
1056 }
1057 else
1058 return;
1059
1060 /* Search the requested item for the given string */
1061
1062 while (sap != NULL) {
1063 if (sap->type == 1) {
1064 sfp = (SeqFeatPtr) sap->data;
1065 while (sfp != NULL) {
1066 if (sfp->data.choice == SEQFEAT_GENE && cfp->type == eFieldTypeGene) {
1067 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
1068 found = SearchGeneRef (grp, sfp, cfp);
1069 }
1070 else if (sfp->data.choice == SEQFEAT_CDREGION &&
1071 cfp->type == eFieldTypeCDS) {
1072 found = SearchCDSFeat (sfp, cfp);
1073 }
1074 else if (sfp->data.choice == SEQFEAT_PROT &&
1075 cfp->type == eFieldTypeProtein) {
1076 prp = (ProtRefPtr) sfp->data.value.ptrvalue;
1077 found = SearchProtRef (prp, sfp, cfp);
1078 }
1079 else if (sfp->data.choice == SEQFEAT_RNA && cfp->type == eFieldTypeRNA) {
1080 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
1081 found = SearchRnaRef (rrp, sfp, cfp);
1082 }
1083 else if (sfp->data.choice == SEQFEAT_IMP &&
1084 cfp->type == eFieldTypeImport) {
1085 found = SearchImpFeat (sfp, cfp);
1086 }
1087 if (TRUE == found)
1088 break;
1089 else
1090 sfp = sfp->next;
1091 }
1092 }
1093 if (TRUE == found)
1094 break;
1095 else
1096 sap = sap->next;
1097 }
1098
1099 /* If we found the string, do the deletion */
1100
1101 if (TRUE == found) {
1102 cfp->isDirty = TRUE;
1103 switch (cfp->deleteLevelInt) {
1104 case 1 :
1105 sfp->idx.deleteme = TRUE;
1106 break;
1107 case 2 :
1108 if (bsp != NULL)
1109 bsp->idx.deleteme = TRUE;
1110 break;
1111 case 3 :
1112 if (bssp != NULL)
1113 bssp->idx.deleteme = TRUE;
1114 else if (bsp != NULL) {
1115 if (bsp->idx.parenttype == OBJ_BIOSEQSET) {
1116 bssp = (BioseqSetPtr) bsp->idx.parentptr;
1117 bssp->idx.deleteme = TRUE;
1118 }
1119 }
1120 break;
1121 default:
1122 break;
1123 }
1124 }
1125
1126 /* Return successfully */
1127
1128 return;
1129 }
1130
1131 static Boolean DoesBioSourceContainText
1132 (BioSourcePtr biop,
1133 ConvertFormPtr cfp)
1134 {
1135 OrgRefPtr orp;
1136 Boolean found;
1137 OrgNamePtr onp;
1138
1139 if (biop == NULL || cfp == NULL) return FALSE;
1140
1141 found = FALSE;
1142
1143 orp = biop->org;
1144 if (orp == NULL) return FALSE;
1145 switch (cfp->subtype) {
1146 case ORGREF_SCI_NAME_FIELD :
1147 found = CheckForString (cfp->deleteStr, orp->taxname);
1148 break;
1149 case ORGREF_COMMON_NAME_FIELD :
1150 found = CheckForString (cfp->deleteStr, orp->common);
1151 break;
1152 case ORGREF_LINEAGE_FIELD :
1153 onp = orp->orgname;
1154 if (onp == NULL) {
1155 onp = OrgNameNew ();
1156 orp->orgname = onp;
1157 }
1158 if (onp != NULL)
1159 found = CheckForString (cfp->deleteStr, onp->lineage);
1160 else
1161 found = FALSE;
1162 break;
1163 case ORGREF_DIVISION_FIELD :
1164 onp = orp->orgname;
1165 if (onp == NULL) {
1166 onp = OrgNameNew ();
1167 orp->orgname = onp;
1168 }
1169 if (onp != NULL)
1170 found = CheckForString (cfp->deleteStr, onp->div);
1171 else
1172 found = FALSE;
1173 break;
1174 default :
1175 break;
1176 }
1177 return found;
1178 }
1179
1180 static Boolean DoSubSourcesContainText
1181 (BioSourcePtr biop,
1182 ConvertFormPtr cfp)
1183 {
1184 OrgRefPtr orp;
1185 OrgModPtr mod;
1186 SubSourcePtr ssp;
1187 OrgNamePtr onp;
1188 Boolean found = FALSE;
1189
1190 if (biop == NULL || cfp == NULL) return FALSE;
1191 if (cfp->subtype < 1000) {
1192 orp = biop->org;
1193 if (orp == NULL) {
1194 orp = OrgRefNew ();
1195 biop->org = orp;
1196 }
1197 if (orp != NULL) {
1198 onp = orp->orgname;
1199 if (onp == NULL) {
1200 onp = OrgNameNew ();
1201 orp->orgname = onp;
1202 }
1203 if (onp != NULL) {
1204 mod = onp->mod;
1205 while (mod != NULL && mod->subtype != cfp->subtype) {
1206 mod = mod->next;
1207 }
1208 if (mod != NULL)
1209 found = CheckForString (cfp->deleteStr, mod->subname);
1210 else
1211 found = FALSE;
1212 }
1213 else
1214 found = FALSE;
1215 }
1216 } else {
1217 ssp = biop->subtype;
1218 while (ssp != NULL && ssp->subtype != (cfp->subtype - 1000)) {
1219 ssp = ssp->next;
1220 }
1221 while (ssp != NULL) {
1222 if (ssp->subtype == (cfp->subtype - 1000)) {
1223 found = CheckForString (cfp->deleteStr, ssp->name);
1224 if (found)
1225 break;
1226 }
1227 ssp = ssp->next;
1228 }
1229 if (NULL == ssp)
1230 found = FALSE;
1231 }
1232 return found;
1233 }
1234
1235 /*=========================================================================*/
1236 /* */
1237 /* DeleteSourceByText () - Given a text string, delete all items of a */
1238 /* given type that contain that string. */
1239 /* */
1240 /*=========================================================================*/
1241
1242 static void DeleteSourceByText (SeqDescrPtr sdp,
1243 SeqEntryPtr sep,
1244 BioseqPtr bsp,
1245 ConvertFormPtr cfp)
1246
1247 {
1248 Boolean found = FALSE;
1249 BioseqSetPtr bssp;
1250 BioSourcePtr biop;
1251
1252 /* Check parameters */
1253
1254 if (sdp == NULL || cfp == NULL)
1255 return;
1256
1257 if (Seq_descr_source != sdp->choice)
1258 return;
1259
1260 biop = sdp->data.ptrvalue;
1261 if (NULL == biop)
1262 return;
1263
1264 /* Search the source for the given string */
1265
1266 switch (cfp->type) {
1267 case eFieldTypeBioSource :
1268 found = DoesBioSourceContainText (biop, cfp);
1269 break;
1270 case eFieldTypeOrgModSubSource :
1271 found = DoSubSourcesContainText (biop, cfp);
1272 default:
1273 break;
1274 }
1275
1276 /* If we found anything to delete then */
1277 /* delete it and set the dirty flag. */
1278
1279 if (TRUE == found) {
1280 cfp->isDirty = TRUE;
1281 switch (cfp->deleteLevelInt) {
1282 case 1 :
1283 break;
1284 case 2 :
1285 if (IS_Bioseq (sep))
1286 bsp->idx.deleteme = TRUE;
1287 break;
1288 case 3 :
1289 if (IS_Bioseq_set (sep)) {
1290 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1291 bssp->idx.deleteme = TRUE;
1292 } else {
1293 if (bsp->idx.parenttype == OBJ_BIOSEQSET) {
1294 bssp = (BioseqSetPtr) bsp->idx.parentptr;
1295 bssp->idx.deleteme = TRUE;
1296 }
1297 }
1298 break;
1299 default:
1300 break;
1301 }
1302 }
1303
1304 /* Return successfully */
1305
1306 return;
1307
1308 }
1309
1310
1311 static void DeleteSimpleDescriptorsByString (BioseqPtr bsp, CharPtr deleteStr, Uint1 desc_choice, BoolPtr isDirty)
1312 {
1313 SeqMgrDescContext dcontext;
1314 SeqDescrPtr sdp;
1315
1316 for (sdp = SeqMgrGetNextDescriptor (bsp, NULL, desc_choice, &dcontext);
1317 sdp != NULL;
1318 sdp = SeqMgrGetNextDescriptor (bsp, sdp, desc_choice, &dcontext))
1319 {
1320 if (CheckForString (deleteStr, sdp->data.ptrvalue)) {
1321 if (sdp->extended != 0) {
1322 ((ObjValNodePtr)sdp)->idx.deleteme = TRUE;
1323 if (isDirty != NULL) {
1324 *isDirty = TRUE;
1325 }
1326 }
1327 }
1328 }
1329 }
1330
1331
1332 /*=========================================================================*/
1333 /* */
1334 /* DeleteItemsByText () - Given a text string, delete all items of a given */
1335 /* type that contain that string. */
1336 /* */
1337 /*=========================================================================*/
1338
1339 static void DeleteItemsByText (SeqEntryPtr sep,
1340 ConvertFormPtr cfp)
1341 {
1342 BioseqSetPtr bssp;
1343 BioseqPtr bsp;
1344 SeqMgrDescContext descContext;
1345 /*
1346 Uint2 parenttype;
1347 Pointer parentptr;
1348 SeqEntryPtr parentSep;
1349 */
1350 SeqDescrPtr sdp;
1351
1352 /* If we have a Bioseq Set, then recurse until */
1353 /* we get down to an actual Bioseq. */
1354
1355 if (IS_Bioseq_set (sep)) {
1356
1357 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1358 if (NULL == bssp)
1359 return;
1360
1361 for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
1362 DeleteItemsByText (sep, cfp);
1363
1364 return;
1365 }
1366
1367 /* If we made it this far, then we have a Bioseq */
1368
1369 bsp = (BioseqPtr) sep->data.ptrvalue;
1370
1371 switch (cfp->type) {
1372 case eFieldTypeGene :
1373 case eFieldTypeCDS :
1374 case eFieldTypeProtein :
1375 case eFieldTypeRNA :
1376 case eFieldTypeImport :
1377 SeqEntryExplore (sep, (Pointer) cfp, DeleteFeaturesByText_Callback);
1378 break;
1379 case eFieldTypeBioSource :
1380 case eFieldTypeOrgModSubSource :
1381 sdp = SeqMgrGetNextDescriptor (bsp, NULL, 0, &descContext);
1382 while (NULL != sdp) {
1383 sdp = SeqMgrGetNextDescriptor (bsp, sdp, 0, &descContext);
1384 DeleteSourceByText (sdp, sep, bsp, cfp);
1385 }
1386 /*
1387 SeqEntryToBioSource (sep, NULL, NULL, 0, &biop);
1388 if (NULL == biop) {
1389 GetSeqEntryParent (sep, &parentptr, &parenttype);
1390 SeqEntryToBioSource (parentSep, NULL, NULL, 0, &biop);
1391 }
1392 DeleteSourceByText (sep, bsp, biop, cfp);
1393 */
1394 break;
1395 case eFieldTypeDefline :
1396 DeleteSimpleDescriptorsByString (bsp, cfp->deleteStr, Seq_descr_title, &(cfp->isDirty));
1397 break;
1398 case eFieldTypeCommentDescriptor :
1399 DeleteSimpleDescriptorsByString (bsp, cfp->deleteStr, Seq_descr_comment, &(cfp->isDirty));
1400 break;
1401 default:
1402 break;
1403 }
1404
1405 /* Return succesfully */
1406
1407 return;
1408 }
1409
1410 /*=========================================================================*/
1411 /* */
1412 /* DeleteByText_Callback () - Finds and deletes all items of a selected */
1413 /* type that contain a given text phrase. */
1414 /* */
1415 /*=========================================================================*/
1416
1417 static void DeleteByText_Callback (ButtoN b)
1418 {
1419 ConvertFormPtr cfp;
1420 SeqEntryPtr sep;
1421 FieldSubfieldPtr f;
1422
1423 /* Check the initial conditions and get the sequence */
1424
1425 cfp = (ConvertFormPtr) GetObjectExtra (b);
1426 if (cfp == NULL || cfp->input_entityID == 0) {
1427 Remove (cfp->form);
1428 return;
1429 }
1430
1431 sep = GetTopSeqEntryForEntityID (cfp->input_entityID);
1432 if (sep == NULL) {
1433 Remove (cfp->form);
1434 return;
1435 }
1436
1437 /* Get the string to search for */
1438
1439 cfp->deleteStr = SaveStringFromTextNoStripSpaces (cfp->deleteText);
1440 if (StringHasNoText (cfp->deleteStr)){
1441 Remove (cfp->form);
1442 return;
1443 }
1444
1445 /* Get the type of items to search */
1446 f = DialogToPointer (cfp->target_dlg);
1447 if (f == NULL || f->field < 0 || (f->subfield < 0 && f->subfield_list == NULL)) {
1448 Remove (cfp->form);
1449 f = FieldSubfieldFree (f);
1450 return;
1451 } else {
1452 cfp->type = f->field + 1;
1453 cfp->subtype = f->subfield;
1454 }
1455
1456 /* Get the delete level */
1457
1458 cfp->deleteLevelInt = GetValue (cfp->deleteLevel);
1459
1460 /* Display the 'working' cursor */
1461
1462 WatchCursor ();
1463 Update ();
1464
1465 /* Do the search and mark and found objects for deletion */
1466
1467 cfp->isDirty = FALSE;
1468 DeleteItemsByText (sep, cfp);
1469
1470 /* Remove the window and update things */
1471
1472 if (cfp->isDirty) {
1473 DeleteMarkedObjects (cfp->input_entityID, 0, NULL);
1474 ObjMgrSetDirtyFlag (cfp->input_entityID, TRUE);
1475 ObjMgrSendMsg (OM_MSG_UPDATE, cfp->input_entityID, 0, 0);
1476 }
1477
1478 ArrowCursor ();
1479 Update ();
1480 Remove (cfp->form);
1481
1482 /* Return successfully */
1483
1484 return;
1485 }
1486
1487 static void CleanupDeleteByTextConvertForm (GraphiC g, VoidPtr data)
1488 {
1489 ConvertFormPtr cfp;
1490
1491 cfp = (ConvertFormPtr) data;
1492 StdCleanupFormProc (g, data);
1493 }
1494
1495 /*=========================================================================*/
1496 /* */
1497 /* CreateDeleteByTextWindow () - Creates and then display the window for */
1498 /* getting delete by text info from the user.*/
1499 /* */
1500 /*=========================================================================*/
1501
1502 extern Int2 LIBCALLBACK CreateDeleteByTextWindow (Pointer data)
1503 {
1504 GrouP c;
1505 ConvertFormPtr cfp;
1506 GrouP g;
1507 GrouP h;
1508 GrouP k;
1509 OMProcControlPtr ompcp;
1510 GrouP p;
1511 StdEditorProcsPtr sepp;
1512 WindoW w;
1513 Boolean allowed[eFieldType_Max];
1514
1515 /* Check parameters and get a pointer to the current data */
1516
1517 ompcp = (OMProcControlPtr) data;
1518 if (ompcp == NULL)
1519 return OM_MSG_RET_ERROR;
1520
1521 /* Create a new window, and a struct */
1522 /* to pass around the data in. */
1523
1524 cfp = ConvertFormNew ();
1525 if (cfp == NULL)
1526 return OM_MSG_RET_ERROR;
1527 cfp->set_accept_proc = SetDeleteAcceptButton;
1528
1529 w = FixedWindow (-50, -33, -10, -10, "Delete By Text String",
1530 StdCloseWindowProc);
1531 SetObjectExtra (w, cfp, CleanupDeleteByTextConvertForm);
1532 cfp->form = (ForM) w;
1533
1534 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
1535 if (sepp != NULL) {
1536 SetActivate (w, sepp->activateForm);
1537 cfp->appmessage = sepp->handleMessages;
1538 }
1539
1540 cfp->input_entityID = ompcp->input_entityID;
1541 cfp->input_itemID = ompcp->input_itemID;
1542 cfp->input_itemtype = ompcp->input_itemtype;
1543
1544 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
1545 if (sepp != NULL) {
1546 SetActivate (w, sepp->activateForm);
1547 cfp->appmessage = sepp->handleMessages;
1548 }
1549
1550 /* Add the popup lists */
1551
1552 h = HiddenGroup (w, -1, 0, NULL);
1553 SetGroupSpacing (h, 10, 10);
1554
1555 k = HiddenGroup (h, 3, 0, NULL);
1556
1557 StaticPrompt (k, "Delete at the level of", 0, dialogTextHeight,
1558 programFont, 'l');
1559 cfp->deleteLevel = HiddenGroup (k, 2, 0, NULL);
1560 RadioButton (cfp->deleteLevel, "Feature");
1561 RadioButton (cfp->deleteLevel, "Bioseq");
1562 RadioButton (cfp->deleteLevel, "Bioseq Set");
1563 SetValue (cfp->deleteLevel, 1);
1564
1565 g = HiddenGroup (h, 3, 0, NULL);
1566
1567 StaticPrompt (g, "Delete objects with the string", 0, dialogTextHeight,
1568 programFont, 'l');
1569 cfp->deleteText = DialogText (g, "", 10, ConvertFormTextCallback);
1570 SetObjectExtra (cfp->deleteText, cfp, NULL);
1571
1572 p = HiddenGroup (h, 6, 0, NULL);
1573 StaticPrompt (p, "Find string in", 0, popupMenuHeight, programFont, 'l');
1574 MemSet (allowed, TRUE, sizeof (Boolean) * eFieldType_Max);
1575 allowed[eFieldTypeCommentDescriptor] = FALSE;
1576 allowed[eFieldTypeFeatureNote] = FALSE;
1577 allowed[eFieldTypePublication] = FALSE;
1578
1579 cfp->target_dlg = CreateFieldSubfieldDlg (p, allowed, ChangeTargetFields, cfp);
1580
1581 /* Add Accept and Cancel buttons */
1582
1583 c = HiddenGroup (h, 4, 0, NULL);
1584 cfp->accept = DefaultButton (c, "Accept", DeleteByText_Callback);
1585 SetObjectExtra (cfp->accept, cfp, NULL);
1586 Disable (cfp->accept);
1587 PushButton (c, "Cancel", StdCancelButtonProc);
1588
1589 /* Line things up nicely */
1590
1591 AlignObjects (ALIGN_LEFT, (HANDLE) p, (HANDLE) c, (HANDLE) h,
1592 (HANDLE) k, NULL);
1593
1594 /* Display the window now */
1595
1596 RealizeWindow (w);
1597 Show (w);
1598 Select (w);
1599 Select (cfp->accept);
1600 Update ();
1601 return OM_MSG_RET_OK;
1602 }
1603
1604 typedef Boolean (LIBCALLBACK *wantSegregateNucProtSetFunction)
1605 ( BioseqSetPtr bssp,
1606 Pointer userdata);
1607
1608 typedef Boolean (LIBCALLBACK *wantSegregateSequenceFunction)
1609 ( BioseqPtr bsp,
1610 Pointer userdata);
1611
1612 /*=========================================================================*/
1613 /* */
1614 /* SegregateItemsRecursor () - Given a functions for determining which bioseqs */
1615 /* meet conditions, segregate bioseqs into separate */
1616 /* sets. */
1617 /* */
1618 /*=========================================================================*/
1619
1620 static void SegregateItemsRecursor
1621 (SeqEntryPtr seqlist,
1622 BioseqSetPtr set1,
1623 BioseqSetPtr set2,
1624 wantSegregateNucProtSetFunction do_np,
1625 wantSegregateSequenceFunction do_seq,
1626 Pointer userdata
1627 )
1628 {
1629
1630 BioseqPtr bsp;
1631 BioseqSetPtr this_bssp;
1632 SeqEntryPtr this_list;
1633 SeqEntryPtr sep, next_sep;
1634 SeqEntryPtr set1last, set2last;
1635
1636
1637 if (set1 == NULL || set2 == NULL || seqlist == NULL)
1638 return;
1639
1640 set1last = set1->seq_set;
1641 while (set1last != NULL && set1last->next != NULL) {
1642 set1last = set1last->next;
1643 }
1644 set2last = set2->seq_set;
1645 while (set2last != NULL && set2last->next != NULL) {
1646 set2last = set2last->next;
1647 }
1648
1649 sep = seqlist;
1650 while (sep != NULL) {
1651 next_sep = sep->next;
1652 if (IS_Bioseq_set (sep)) {
1653 this_bssp = (BioseqSetPtr) sep->data.ptrvalue;
1654 if (this_bssp->_class == BioseqseqSet_class_nuc_prot) {
1655 if (do_np != NULL && do_np (this_bssp, userdata)) {
1656 if (set2last == NULL) {
1657 set2->seq_set = sep;
1658 } else {
1659 set2last->next = sep;
1660 }
1661 set2last = sep;
1662 } else {
1663 if (set1last == NULL) {
1664 set1->seq_set = sep;
1665 } else {
1666 set1last->next = sep;
1667 }
1668 set1last = sep;
1669 }
1670 sep->next = NULL;
1671 } else {
1672 /* copy class types from this set if class types are not set */
1673 if (set1->_class == BioseqseqSet_class_genbank
1674 && set2->_class == BioseqseqSet_class_genbank) {
1675 set1->_class = this_bssp->_class;
1676 set2->_class = this_bssp->_class;
1677 }
1678 /* copy descriptors from this set */
1679 if (this_bssp != set1) {
1680 ValNodeLink (&(set1->descr),
1681 AsnIoMemCopy ((Pointer) this_bssp->descr,
1682 (AsnReadFunc) SeqDescrAsnRead,
1683 (AsnWriteFunc) SeqDescrAsnWrite));
1684 }
1685 if (this_bssp != set2) {
1686 ValNodeLink (&(set2->descr),
1687 AsnIoMemCopy ((Pointer) this_bssp->descr,
1688 (AsnReadFunc) SeqDescrAsnRead,
1689 (AsnWriteFunc) SeqDescrAsnWrite));
1690 }
1691 if (this_bssp != set1 && this_bssp != set2) {
1692 this_bssp->descr = SeqDescrFree (this_bssp->descr);
1693 }
1694
1695 this_list = this_bssp->seq_set;
1696 this_bssp->seq_set = NULL;
1697 SegregateItemsRecursor (this_list, set1, set2, do_np, do_seq, userdata);
1698 }
1699 } else if (IS_Bioseq (sep)) {
1700 bsp = (BioseqPtr) sep->data.ptrvalue;
1701 if (do_seq != NULL && do_seq (bsp, userdata)) {
1702 if (set2last == NULL) {
1703 set2->seq_set = sep;
1704 } else {
1705 set2last->next = sep;
1706 }
1707 set2last = sep;
1708 } else {
1709 if (set1last == NULL) {
1710 set1->seq_set = sep;
1711 } else {
1712 set1last->next = sep;
1713 }
1714 set1last = sep;
1715 }
1716 sep->next = NULL;
1717 }
1718 sep = next_sep;
1719 }
1720 }
1721
1722
1723 static Boolean DoFeaturesInAnnotContainText (SeqAnnotPtr sap, ConvertFormPtr cfp)
1724 {
1725 SeqFeatPtr sfp;
1726 GeneRefPtr grp;
1727 ProtRefPtr prp;
1728 RnaRefPtr rrp;
1729 Boolean found = FALSE;
1730 ValNodePtr vnp;
1731 FieldSubfieldPtr f;
1732
1733 if (sap == NULL || cfp == NULL) return FALSE;
1734
1735 /* Search the requested item for the given string */
1736
1737 while (sap != NULL && !found) {
1738 if (sap->type == 1) {
1739 sfp = (SeqFeatPtr) sap->data;
1740 while (sfp != NULL && !found) {
1741 if (sfp->data.choice == SEQFEAT_GENE && cfp->type == eFieldTypeGene) {
1742 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
1743 found = SearchGeneRef (grp, sfp, cfp);
1744 } else if (sfp->data.choice == SEQFEAT_CDREGION && cfp->type == eFieldTypeCDS) {
1745 found = SearchCDSFeat (sfp, cfp);
1746 } else if (sfp->data.choice == SEQFEAT_PROT && cfp->type == eFieldTypeProtein) {
1747 prp = (ProtRefPtr) sfp->data.value.ptrvalue;
1748 found = SearchProtRef (prp, sfp, cfp);
1749 } else if (sfp->data.choice == SEQFEAT_RNA && cfp->type == eFieldTypeRNA) {
1750 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
1751 found = SearchRnaRef (rrp, sfp, cfp);
1752 } else if (sfp->data.choice == SEQFEAT_IMP &&
1753 cfp->type == eFieldTypeImport) {
1754 found = SearchImpFeat (sfp, cfp);
1755 } else if (cfp->type == eFieldTypeFeatureNote) {
1756 f = DialogToPointer (cfp->target_dlg);
1757 if (f != NULL) {
1758 for (vnp = f->subfield_list; vnp != NULL; vnp = vnp->next) {
1759 if (vnp->choice == sfp->idx.subtype
1760 && CheckForString (cfp->deleteStr, sfp->comment)) {
1761 found = TRUE;
1762 }
1763 }
1764 f = FieldSubfieldFree (f);
1765 }
1766 }
1767 sfp = sfp->next;
1768 }
1769 }
1770 sap = sap->next;
1771 }
1772 return found;
1773 }
1774
1775 static Boolean DoFeaturesContainText_Callback
1776 (BioseqPtr bsp,
1777 ConvertFormPtr cfp)
1778 {
1779
1780 SeqAnnotPtr sap;
1781
1782 /* Check parameters */
1783
1784 if (bsp == NULL || cfp == NULL)
1785 return FALSE;
1786
1787 /* Get the list of annotations */
1788
1789 sap = bsp->annot;
1790
1791 /* Search the requested item for the given string */
1792
1793 return DoFeaturesInAnnotContainText (sap, cfp);
1794 }
1795
1796 typedef struct objstringdata
1797 {
1798 CharPtr match;
1799 Boolean found;
1800 } ObjStringData, PNTR ObjStringPtr;
1801
1802 static void LIBCALLBACK AsnWriteRemoveForDCallBack (AsnExpOptStructPtr pAEOS)
1803
1804 {
1805 CharPtr pchFind;
1806 CharPtr pchSource;
1807 ObjStringPtr osp;
1808
1809 osp = (ObjStringPtr) pAEOS->data;
1810 if (ISA_STRINGTYPE (AsnFindBaseIsa (pAEOS->atp))) {
1811 pchSource = (CharPtr) pAEOS->dvp->ptrvalue;
1812 pchFind = osp->match;
1813 if (StringSearch (pchSource, pchFind) != NULL) {
1814 osp->found = TRUE;
1815 }
1816 }
1817 }
1818
1819 static Boolean ObjectHasSubstring (ObjMgrTypePtr omtp, AsnIoPtr aip, Pointer ptr, ObjStringPtr osp)
1820
1821 {
1822 osp->found = FALSE;
1823 (omtp->asnwrite) (ptr, aip, NULL);
1824 return osp->found;
1825 }
1826
1827 static Uint1 GetPubStatus (PubdescPtr pdp)
1828 {
1829 ValNodePtr vnp;
1830 CitGenPtr cgp;
1831 CitArtPtr cap;
1832 CitJourPtr cjp;
1833 CitBookPtr cbp;
1834 CitSubPtr csp;
1835 MedlineEntryPtr mlp;
1836 ImprintPtr ip = NULL;
1837 Uint1 status = 255; /* 255 is currently not a valid status */
1838
1839 if (pdp == NULL) return status;
1840
1841 for (vnp = pdp->pub; vnp != NULL && ip == NULL; vnp = vnp->next)
1842 {
1843 switch (vnp->choice)
1844 {
1845 case PUB_Gen:
1846 cgp = (CitGenPtr) vnp->data.ptrvalue;
1847 if (cgp != NULL && StringICmp (cgp->cit, "Unpublished"))
1848 {
1849 return PUB_STATUS_UNPUBLISHED;
1850 }
1851 break;
1852 case PUB_Article:
1853 case PUB_Medline:
1854 if (vnp->choice == PUB_Article)
1855 {
1856 cap = (CitArtPtr) vnp->data.ptrvalue;
1857 }
1858 else
1859 {
1860 cap = NULL;
1861 mlp = (MedlineEntryPtr) vnp->data.ptrvalue;
1862 if (mlp != NULL)
1863 {
1864 cap = mlp->cit;
1865 }
1866 }
1867 if (cap != NULL && cap->from == 1)
1868 {
1869 cjp = (CitJourPtr) cap->fromptr;
1870 if (cjp != NULL)
1871 {
1872 ip = cjp->imp;
1873 }
1874 }
1875 break;
1876 case PUB_Man:
1877 case PUB_Book:
1878 cbp = (CitBookPtr) vnp->data.ptrvalue;
1879 if (cbp != NULL)
1880 {
1881 ip = cbp->imp;
1882 }
1883 break;
1884 case PUB_Sub:
1885 csp = (CitSubPtr) vnp->data.ptrvalue;
1886 if (csp != NULL)
1887 {
1888 ip = csp->imp;
1889 }
1890 break;
1891 }
1892 }
1893 if (ip != NULL)
1894 {
1895 status = ip->prepub;
1896 }
1897 return status;
1898 }
1899
1900 static Boolean DoesPubStatusMatch (PubdescPtr pdp, ConvertFormPtr cfp)
1901 {
1902 Uint1 pub_status;
1903
1904 if (pdp == NULL || cfp == NULL) return FALSE;
1905 if (cfp->subtype == 0) return TRUE;
1906
1907 pub_status = GetPubStatus (pdp);
1908
1909 if (cfp->subtype == PUBLICATION_PUBLISHED_FIELD
1910 && pub_status == PUB_STATUS_PUBLISHED)
1911 {
1912 return TRUE;
1913 }
1914 else if (cfp->subtype == PUBLICATION_INPRESS_FIELD
1915 && pub_status == PUB_STATUS_IN_PRESS)
1916 {
1917 return TRUE;
1918 }
1919 else if (cfp->subtype == PUBLICATION_UNPUB_FIELD
1920 && pub_status == PUB_STATUS_UNPUBLISHED)
1921 {
1922 return TRUE;
1923 }
1924 else
1925 {
1926 return FALSE;
1927 }
1928 }
1929
1930 static Boolean DoesSequenceHavePubWithText (BioseqPtr bsp, ConvertFormPtr cfp)
1931 {
1932 AsnExpOptPtr aeop;
1933 AsnIoPtr aip;
1934 ObjStringData osd;
1935 SeqMgrDescContext dcontext;
1936 SeqDescrPtr sdp;
1937 SeqMgrFeatContext fcontext;
1938 SeqFeatPtr sfp;
1939 Boolean rval = FALSE;
1940 ObjMgrPtr omp;
1941 ObjMgrTypePtr omtp;
1942 PubdescPtr pdp;
1943
1944 if (bsp == NULL || cfp == NULL) return FALSE;
1945 omp = ObjMgrGet ();
1946 if (omp == NULL) return FALSE;
1947 omtp = ObjMgrTypeFind (omp, OBJ_SEQDESC, NULL, NULL);
1948 if (omtp == NULL) return FALSE;
1949
1950 aip = AsnIoNullOpen ();
1951 aeop = AsnExpOptNew (aip, NULL, NULL, AsnWriteRemoveForDCallBack);
1952 if (aeop != NULL) {
1953 aeop->user_data = (Pointer) &osd;
1954 }
1955 osd.match = cfp->deleteStr;
1956
1957 /* look for publication descriptors */
1958 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_pub, &dcontext);
1959 while (sdp != NULL && !rval) {
1960 if (ObjectHasSubstring (omtp, aip, (Pointer) sdp, &osd)) {
1961 pdp = (PubdescPtr) sdp->data.ptrvalue;
1962 if (DoesPubStatusMatch (pdp, cfp))
1963 {
1964 rval = TRUE;
1965 }
1966 }
1967 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_pub, &dcontext);
1968 }
1969
1970 if (!rval)
1971 {
1972 omtp = ObjMgrTypeFind (omp, OBJ_SEQFEAT, NULL, NULL);
1973 if (omtp != NULL)
1974 {
1975 /* look for publication features */
1976 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, FEATDEF_PUB, &fcontext);
1977 while (sfp != NULL && !rval)
1978 {
1979 if (ObjectHasSubstring (omtp, aip, (Pointer) sfp, &osd))
1980 {
1981 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
1982 if (DoesPubStatusMatch (pdp, cfp))
1983 {
1984 rval = TRUE;
1985 }
1986 }
1987 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, FEATDEF_PUB, &fcontext);
1988 }
1989 }
1990 }
1991
1992 AsnIoClose (aip);
1993 return rval;
1994 }
1995
1996 static Boolean DoesNucProtSetHavePubWithText (BioseqSetPtr bssp, ConvertFormPtr cfp)
1997 {
1998 AsnExpOptPtr aeop;
1999 AsnIoPtr aip;
2000 ObjStringData osd;
2001 SeqDescrPtr sdp;
2002 Boolean rval = FALSE;
2003 ObjMgrPtr omp;
2004 ObjMgrTypePtr omtp;
2005 PubdescPtr pdp;
2006
2007 if (bssp == NULL || cfp == NULL) return FALSE;
2008 omp = ObjMgrGet ();
2009 if (omp == NULL) return FALSE;
2010 omtp = ObjMgrTypeFind (omp, OBJ_SEQDESC, NULL, NULL);
2011 if (omtp == NULL) return FALSE;
2012
2013 aip = AsnIoNullOpen ();
2014 aeop = AsnExpOptNew (aip, NULL, NULL, AsnWriteRemoveForDCallBack);
2015 if (aeop != NULL) {
2016 aeop->user_data = (Pointer) &osd;
2017 }
2018 osd.match = cfp->deleteStr;
2019
2020 /* look for publication descriptors */
2021 sdp = bssp->descr;
2022 while (sdp != NULL && !rval) {
2023 if (sdp->choice == Seq_descr_pub && ObjectHasSubstring (omtp, aip, (Pointer) sdp, &osd)) {
2024 pdp = (PubdescPtr) sdp->data.ptrvalue;
2025 if (DoesPubStatusMatch (pdp, cfp))
2026 {
2027 rval = TRUE;
2028 }
2029 }
2030 sdp = sdp->next;
2031 }
2032
2033 AsnIoClose (aip);
2034 return rval;
2035 }
2036
2037 static Boolean DoesSimpleDescriptorForSequenceContainText (BioseqPtr bsp, CharPtr checkStr, Uint1 desc_choice)
2038 {
2039 SeqMgrDescContext dcontext;
2040 SeqDescrPtr sdp;
2041 Boolean found = FALSE;
2042
2043 for (sdp = SeqMgrGetNextDescriptor (bsp, NULL, desc_choice, &dcontext);
2044 sdp != NULL && !found;
2045 sdp = SeqMgrGetNextDescriptor (bsp, sdp, desc_choice, &dcontext))
2046 {
2047 found = CheckForString (checkStr, sdp->data.ptrvalue);
2048 }
2049 return found;
2050 }
2051
2052
2053 static Boolean LIBCALLBACK DoesSequenceContainText (BioseqPtr bsp, Pointer userdata)
2054 {
2055 BioSourcePtr biop;
2056 ConvertFormPtr cfp;
2057 Boolean found = FALSE;
2058 SeqDescrPtr sdp;
2059 SeqMgrDescContext descContext;
2060
2061 cfp = (ConvertFormPtr) userdata;
2062 if (bsp == NULL || cfp == NULL) return FALSE;
2063
2064 switch (cfp->type) {
2065 case eFieldTypeGene :
2066 case eFieldTypeCDS :
2067 case eFieldTypeProtein :
2068 case eFieldTypeRNA :
2069 case eFieldTypeImport :
2070 case eFieldTypeFeatureNote :
2071 found = DoFeaturesContainText_Callback (bsp, cfp);
2072 break;
2073 case eFieldTypeBioSource :
2074 case eFieldTypeOrgModSubSource :
2075 sdp = SeqMgrGetNextDescriptor (bsp, NULL, 0, &descContext);
2076 while (NULL != sdp && ! found) {
2077 if (Seq_descr_source == sdp->choice
2078 && (biop = sdp->data.ptrvalue) != NULL) {
2079 if (cfp->type == eFieldTypeBioSource) {
2080 found = DoesBioSourceContainText (biop, cfp);
2081 } else if (cfp->type == eFieldTypeOrgModSubSource) {
2082 found = DoSubSourcesContainText (biop, cfp);
2083 }
2084 }
2085 sdp = SeqMgrGetNextDescriptor (bsp, sdp, 0, &descContext);
2086 }
2087 break;
2088 case eFieldTypeDefline :
2089 found = DoesSimpleDescriptorForSequenceContainText (bsp, cfp->deleteStr, Seq_descr_title);
2090 break;
2091 case eFieldTypeCommentDescriptor:
2092 found = DoesSimpleDescriptorForSequenceContainText (bsp, cfp->deleteStr, Seq_descr_comment);
2093 break;
2094 case eFieldTypePublication :
2095 found = DoesSequenceHavePubWithText (bsp, cfp);
2096 break;
2097 default:
2098 break;
2099 }
2100 return found;
2101 }
2102
2103 static Boolean LIBCALLBACK DoesNucProtSetContainText (BioseqSetPtr bssp, Pointer userdata)
2104 {
2105 SeqEntryPtr sep;
2106 BioseqPtr bsp;
2107 ConvertFormPtr cfp;
2108
2109 if (bssp == NULL) return FALSE;
2110 cfp = (ConvertFormPtr) userdata;
2111 if (cfp == NULL) return FALSE;
2112 if (cfp->type == eFieldTypePublication && DoesNucProtSetHavePubWithText (bssp, cfp))
2113 {
2114 return TRUE;
2115 }
2116 if (DoFeaturesInAnnotContainText (bssp->annot, cfp))
2117 {
2118 return TRUE;
2119 }
2120
2121 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
2122 if (IS_Bioseq (sep)) {
2123 bsp = (BioseqPtr) sep->data.ptrvalue;
2124 if (DoesSequenceContainText (bsp, (Pointer)cfp)) {
2125 return TRUE;
2126 }
2127 }
2128 }
2129 return FALSE;
2130 }
2131
2132 static void SegregateItemsByText
2133 (SeqEntryPtr seqlist,
2134 ConvertFormPtr cfp,
2135 BioseqSetPtr set1,
2136 BioseqSetPtr set2)
2137 {
2138 SegregateItemsRecursor (seqlist, set1, set2,
2139 DoesNucProtSetContainText,
2140 DoesSequenceContainText, (Pointer)cfp);
2141 }
2142
2143 typedef void (LIBCALLBACK *segregateFunction) (
2144 SeqEntryPtr seqlist,
2145 Pointer userdata,
2146 BioseqSetPtr set1,
2147 BioseqSetPtr set2
2148 );
2149
2150
2151 static void CreateSetsForSegregate (BioseqSetPtr bssp, BioseqSetPtr PNTR pNewSet1, BioseqSetPtr PNTR pNewSet2)
2152 {
2153 BioseqSetPtr parent_set;
2154 SeqEntryPtr tmp1, tmp2, last_sep;
2155 BioseqSetPtr newset1, newset2;
2156
2157 if (bssp == NULL || pNewSet1 == NULL || pNewSet2 == NULL) return;
2158
2159 parent_set = (BioseqSetPtr)(bssp->idx.parentptr);
2160
2161 if (parent_set == NULL || parent_set->seq_set == NULL) {
2162 /* this set has no parent, so make it the parent set, class GenBank,
2163 * and create two new sets using the original set class as members of this set
2164 */
2165 newset1 = BioseqSetNew ();
2166 if (newset1 == NULL) return;
2167 newset2 = BioseqSetNew ();
2168 if (newset2 == NULL) return;
2169 newset1->_class = bssp->_class;
2170 newset2->_class = bssp->_class;
2171 tmp1 = SeqEntryNew ();
2172 if (tmp1 == NULL) return;
2173 tmp1->choice = 2;
2174 tmp1->data.ptrvalue = (Pointer) newset1;
2175 tmp2 = SeqEntryNew ();
2176 if (tmp2 == NULL) return;
2177 tmp2->choice = 2;
2178 tmp2->data.ptrvalue = (Pointer) newset2;
2179 bssp->seq_set = tmp1;
2180 tmp1->next = tmp2;
2181 bssp->_class = BioseqseqSet_class_genbank;
2182 /* Propagate descriptors down */
2183 ValNodeLink (&(newset1->descr),
2184 AsnIoMemCopy ((Pointer) bssp->descr,
2185 (AsnReadFunc) SeqDescrAsnRead,
2186 (AsnWriteFunc) SeqDescrAsnWrite));
2187 ValNodeLink (&(newset2->descr),
2188 AsnIoMemCopy ((Pointer) bssp->descr,
2189 (AsnReadFunc) SeqDescrAsnRead,
2190 (AsnWriteFunc) SeqDescrAsnWrite));
2191 bssp->descr = SeqDescrFree (bssp->descr);
2192 } else {
2193 last_sep = parent_set->seq_set;
2194 newset1 = bssp;
2195 newset2 = BioseqSetNew ();
2196 if (newset2 == NULL) return;
2197 newset2->_class = newset1->_class;
2198 tmp1 = SeqEntryNew ();
2199 if (tmp1 == NULL) return;
2200 tmp1->choice = 2;
2201 tmp1->data.ptrvalue = (Pointer) newset2;
2202 while (last_sep != NULL && last_sep->next != NULL) {
2203 last_sep = last_sep->next;
2204 }
2205 if (last_sep == NULL) return;
2206 last_sep->next = tmp1;
2207 /* copy descriptors horizontally */
2208 ValNodeLink (&(newset2->descr),
2209 AsnIoMemCopy ((Pointer) bssp->descr,
2210 (AsnReadFunc) SeqDescrAsnRead,
2211 (AsnWriteFunc) SeqDescrAsnWrite));
2212 }
2213 *pNewSet1 = newset1;
2214 *pNewSet2 = newset2;
2215 }
2216
2217
2218 static void SegregateItemsGenericCallback
2219 (SeqEntryPtr sep,
2220 BioseqSetPtr bssp,
2221 Uint2 entityID,
2222 Pointer userdata,
2223 segregateFunction seg_func)
2224 {
2225 ObjMgrDataPtr omdptop;
2226 ObjMgrData omdata;
2227 BioseqSetPtr newset1;
2228 BioseqSetPtr newset2;
2229 Uint2 parenttype;
2230 Pointer parentptr;
2231 SeqEntryPtr seqlist;
2232
2233 if (sep == NULL || seg_func == NULL) return;
2234 /* Display the 'working' cursor */
2235
2236 WatchCursor ();
2237 Update ();
2238
2239
2240 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
2241 GetSeqEntryParent (sep, &parentptr, &parenttype);
2242
2243 seqlist = bssp->seq_set;
2244 bssp->seq_set = NULL;
2245
2246 CreateSetsForSegregate (bssp, &newset1, &newset2);
2247
2248 /* Do the search and move sequences */
2249 (*seg_func)(seqlist, userdata, newset1, newset2);
2250
2251 /* Remove the window and update things */
2252 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
2253 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
2254 ObjMgrSetDirtyFlag (entityID, TRUE);
2255 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
2256
2257 ArrowCursor ();
2258 Update ();
2259
2260 /* Return successfully */
2261 return;
2262
2263 }
2264
2265
2266 static Boolean OkToSegregate (OMProcControlPtr ompcp)
2267 {
2268 if (ompcp == NULL
2269 || ompcp->input_itemtype != OBJ_BIOSEQSET
2270 || ompcp->input_data == NULL) {
2271 Message (MSG_ERROR, "You must select a set to segregate!");
2272 return FALSE;
2273 } else {
2274 return TRUE;
2275 }
2276 }
2277
2278
2279 /*=========================================================================*/
2280 /* */
2281 /* SegregateByText_Callback () - Finds and deletes all items of a selected */
2282 /* type that contain a given text phrase. */
2283 /* */
2284 /*=========================================================================*/
2285
2286 static void SegregateByText_Callback (ButtoN b)
2287 {
2288 ConvertFormPtr cfp;
2289 SeqEntryPtr sep;
2290 BioseqSetPtr bssp;
2291 SeqEntryPtr seqlist;
2292 BioseqSetPtr newset1, newset2;
2293 ObjMgrDataPtr omdptop;
2294 ObjMgrData omdata;
2295 Uint2 parenttype;
2296 Pointer parentptr;
2297 Boolean leaveDlgUp = FALSE;
2298 FieldSubfieldPtr f;
2299
2300 /* Check the initial conditions and get the sequence */
2301 cfp = (ConvertFormPtr) GetObjectExtra (b);
2302 if (cfp == NULL || cfp->input_entityID == 0 || cfp->target_set == NULL) {
2303 Remove (cfp->form);
2304 return;
2305 }
2306
2307 sep = GetTopSeqEntryForEntityID (cfp->input_entityID);
2308 if (sep == NULL) {
2309 Remove (cfp->form);
2310 return;
2311 }
2312
2313 if (GetStatus (cfp->leaveDlgUp))
2314 {
2315 leaveDlgUp = TRUE;
2316 }
2317
2318 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
2319 GetSeqEntryParent (sep, &parentptr, &parenttype);
2320
2321 bssp = cfp->target_set;
2322 seqlist = bssp->seq_set;
2323 bssp->seq_set = NULL;
2324
2325 CreateSetsForSegregate (bssp, &newset1, &newset2);
2326
2327 /* Get the string to search for */
2328
2329 cfp->deleteStr = SaveStringFromTextNoStripSpaces (cfp->deleteText);
2330 if (StringHasNoText (cfp->deleteStr)){
2331 if (!leaveDlgUp)
2332 {
2333 Remove (cfp->form);
2334 }
2335 return;
2336 }
2337
2338 /* Get the type of items to search */
2339 f = DialogToPointer (cfp->target_dlg);
2340 if (f == NULL || f->field < 0 || (f->subfield < 0 && f->subfield_list == NULL)) {
2341 f = FieldSubfieldFree (f);
2342 if (!leaveDlgUp)
2343 {
2344 Remove (cfp->form);
2345 }
2346 return;
2347 }
2348
2349 cfp->type = f->field;
2350 cfp->subtype = f->subfield;
2351 f = FieldSubfieldFree (f);
2352
2353 /* Display the 'working' cursor */
2354
2355 WatchCursor ();
2356 Update ();
2357
2358 /* Do the search and move sequences */
2359 SegregateItemsByText (seqlist, cfp, newset1, newset2);
2360
2361 /* Remove the window and update things */
2362 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
2363 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
2364 ObjMgrSetDirtyFlag (cfp->input_entityID, TRUE);
2365 ObjMgrSendMsg (OM_MSG_UPDATE, cfp->input_entityID, 0, 0);
2366
2367 ArrowCursor ();
2368 Update ();
2369 if (!leaveDlgUp)
2370 {
2371 Remove (cfp->form);
2372 }
2373
2374 /* Return successfully */
2375 return;
2376 }
2377
2378
2379
2380
2381 /*-------------------------------------------------------------------------*/
2382 /* */
2383 /* SetSegregateAcceptButton () -- Enable/Disable the Accept button depending */
2384 /* on the condition of other window objects. */
2385 /* */
2386 /*-------------------------------------------------------------------------*/
2387
2388 static void SetSegregateAcceptButton (Pointer data)
2389
2390 {
2391 ConvertFormPtr cfp;
2392 FieldSubfieldPtr f;
2393
2394 cfp = (ConvertFormPtr) data;
2395 if (cfp == NULL)
2396 return;
2397
2398 /* Disable if a target has not been selected */
2399 f = DialogToPointer (cfp->target_dlg);
2400 if (f == NULL || f->field < 0 || (f->subfield < 0 && f->subfield_list == NULL)) {
2401 SafeDisable (cfp->accept);
2402 f = FieldSubfieldFree (f);
2403 return;
2404 }
2405 f = FieldSubfieldFree (f);
2406
2407 if (cfp->deleteText != NULL) {
2408 /* Disable if there is no delete string */
2409 if (TextHasNoText (cfp->deleteText)) {
2410 SafeDisable (cfp->accept);
2411 return;
2412 }
2413 }
2414
2415 /* If we made it to here, then we passed all */
2416 /* test and can enable the accept button. */
2417
2418 SafeEnable (cfp->accept);
2419 }
2420
2421 static void CleanupSegregatePage (GraphiC g, VoidPtr data)
2422
2423 {
2424 ConvertFormPtr cfp;
2425
2426 cfp = (ConvertFormPtr) data;
2427 if (cfp != NULL) {
2428 }
2429 StdCleanupFormProc (g, data);
2430 }
2431
2432 /*=========================================================================*/
2433 /* */
2434 /* CreateSegregateByTextWindow () - Creates and then displays the window */
2435 /* for getting segregate by text info from the user.*/
2436 /* */
2437 /*=========================================================================*/
2438
2439 extern Int2 LIBCALLBACK CreateSegregateByTextWindow (Pointer data)
2440 {
2441 Boolean allowed[eFieldType_Max];
2442 GrouP c;
2443 ConvertFormPtr cfp;
2444 GrouP g;
2445 GrouP h;
2446 OMProcControlPtr ompcp;
2447 GrouP p;
2448 StdEditorProcsPtr sepp;
2449 WindoW w;
2450
2451 /* Check parameters and get a pointer to the current data */
2452
2453 ompcp = (OMProcControlPtr) data;
2454 if (!OkToSegregate(ompcp)) {
2455 return OM_MSG_RET_ERROR;
2456 }
2457
2458 /* Create a new window, and a struct */
2459 /* to pass around the data in. */
2460
2461 cfp = ConvertFormNew ();
2462 if (cfp == NULL)
2463 return OM_MSG_RET_ERROR;
2464 cfp->target_set = (BioseqSetPtr)ompcp->input_data;
2465 cfp->set_accept_proc = SetSegregateAcceptButton;
2466
2467 w = FixedWindow (-50, -33, -10, -10, "Segregate By Text String",
2468 StdCloseWindowProc);
2469 SetObjectExtra (w, cfp, CleanupSegregatePage);
2470 cfp->form = (ForM) w;
2471
2472 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2473 if (sepp != NULL) {
2474 SetActivate (w, sepp->activateForm);
2475 cfp->appmessage = sepp->handleMessages;
2476 }
2477
2478 cfp->input_entityID = ompcp->input_entityID;
2479 cfp->input_itemID = ompcp->input_itemID;
2480 cfp->input_itemtype = ompcp->input_itemtype;
2481
2482 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2483 if (sepp != NULL) {
2484 SetActivate (w, sepp->activateForm);
2485 cfp->appmessage = sepp->handleMessages;
2486 }
2487
2488 /* Add the popup lists */
2489
2490 h = HiddenGroup (w, -1, 0, NULL);
2491 SetGroupSpacing (h, 10, 10);
2492
2493 g = HiddenGroup (h, 3, 0, NULL);
2494
2495 StaticPrompt (g, "Segregate sequences with the string", 0, dialogTextHeight,
2496 programFont, 'l');
2497 cfp->deleteText = DialogText (g, "", 10, ConvertFormTextCallback);
2498 SetObjectExtra (cfp->deleteText, cfp, NULL);
2499
2500 p = HiddenGroup (h, 6, 0, NULL);
2501 StaticPrompt (p, "Find string in", 0, popupMenuHeight, programFont, 'l');
2502 MemSet (allowed, TRUE, sizeof (Boolean) * eFieldType_Max);
2503 allowed[eFieldTypeCommentDescriptor] = TRUE;
2504
2505 cfp->target_dlg = CreateFieldSubfieldDlg (p, allowed, ChangeTargetFields, cfp);
2506
2507 /* Add Accept and Cancel buttons */
2508
2509 c = HiddenGroup (h, 4, 0, NULL);
2510 cfp->accept = DefaultButton (c, "Accept", SegregateByText_Callback);
2511 SetObjectExtra (cfp->accept, cfp, NULL);
2512 Disable (cfp->accept);
2513 PushButton (c, "Cancel", StdCancelButtonProc);
2514 cfp->leaveDlgUp = CheckBox (c, "Leave Dialog Up", NULL);
2515
2516 /* Line things up nicely */
2517
2518 AlignObjects (ALIGN_LEFT, (HANDLE) p, (HANDLE) c, (HANDLE) h, NULL);
2519
2520 /* Display the window now */
2521
2522 RealizeWindow (w);
2523 Show (w);
2524 Select (w);
2525 Select (cfp->accept);
2526 Update ();
2527 return OM_MSG_RET_OK;
2528 }
2529
2530
2531 typedef struct segregatefeatdata {
2532 FEATURE_FORM_BLOCK
2533
2534 PopuP type_popup;
2535 ValNodePtr type_list;
2536 ButtoN accept;
2537
2538 BioseqSetPtr target_set;
2539 Uint2 segregate_type;
2540 Boolean is_feat;
2541 } SegregateFeatData, PNTR SegregateFeatPtr;
2542
2543 static Boolean LIBCALLBACK DoesSequenceContainFeatureType (BioseqPtr bsp, Pointer userdata)
2544 {
2545 SeqMgrFeatContext context;
2546 SeqFeatPtr feat;
2547 SegregateFeatPtr sfp;
2548
2549 sfp = (SegregateFeatPtr) userdata;
2550 if (sfp == NULL || bsp == NULL) return FALSE;
2551
2552 feat = NULL;
2553 while ((feat = SeqMgrGetNextFeature (bsp, feat, 0, 0, &context)) != NULL)
2554 {
2555 if (feat->idx.subtype == sfp->segregate_type)
2556 {
2557 return TRUE;
2558 }
2559 }
2560 return FALSE;
2561 }
2562
2563 static Boolean LIBCALLBACK DoesNucProtSetContainFeatureType (BioseqSetPtr bssp, Pointer userdata)
2564 {
2565 SeqEntryPtr sep;
2566 BioseqPtr bsp;
2567 SegregateFeatPtr sfp;
2568
2569 sfp = (SegregateFeatPtr) userdata;
2570 if (sfp == NULL || bssp == NULL) return FALSE;
2571
2572 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
2573 if (IS_Bioseq (sep)) {
2574 bsp = (BioseqPtr) sep->data.ptrvalue;
2575 if (DoesSequenceContainFeatureType (bsp, sfp)) {
2576 return TRUE;
2577 }
2578 }
2579 }
2580 return FALSE;
2581 }
2582
2583 static Boolean LIBCALLBACK DoesSequenceContainDescriptorType (BioseqPtr bsp, Pointer userdata)
2584 {
2585 SeqMgrDescContext context;
2586 SeqDescPtr desc;
2587 SegregateFeatPtr sfp;
2588
2589 sfp = (SegregateFeatPtr) userdata;
2590 if (sfp == NULL || bsp == NULL) return FALSE;
2591
2592 if((desc = SeqMgrGetNextDescriptor (bsp, NULL, sfp->segregate_type, &context)) != NULL)
2593 {
2594 return TRUE;
2595 }
2596 return FALSE;
2597 }
2598
2599 typedef struct checkdescdata {
2600 Uint2 segregate_type;
2601 Boolean found;
2602 } CheckDescData, PNTR CheckDescPtr;
2603
2604 static void DoesSetContainDescriptorType_Callback (SeqDescPtr sdp, Pointer userdata)
2605 {
2606 CheckDescPtr p;
2607
2608 if (sdp == NULL || userdata == NULL) return;
2609 p = (CheckDescPtr) userdata;
2610 if (p->found) return;
2611 if (sdp->choice == p->segregate_type) p->found = TRUE;
2612 }
2613
2614 static Boolean LIBCALLBACK DoesNucProtSetContainDescriptorType (BioseqSetPtr bssp, Pointer userdata)
2615 {
2616 CheckDescData d;
2617 SegregateFeatPtr sfp;
2618
2619 sfp = (SegregateFeatPtr) userdata;
2620 if (sfp == NULL || bssp == NULL) return FALSE;
2621
2622 d.found = FALSE;
2623 d.segregate_type = sfp->segregate_type;
2624 VisitDescriptorsInSet (bssp, &d, DoesSetContainDescriptorType_Callback);
2625 return d.found;
2626 }
2627
2628 /*=========================================================================*/
2629 /* */
2630 /* SegregateItemsByFeature () - Given a feature type, move bioseqs */
2631 /* containing those features to a new popset. */
2632 /* */
2633 /*=========================================================================*/
2634
2635 static void SegregateItemsByFeatureOrDescriptor
2636 (SeqEntryPtr seqlist,
2637 SegregateFeatPtr sfp,
2638 BioseqSetPtr set1,
2639 BioseqSetPtr set2)
2640 {
2641
2642
2643 if (sfp == NULL || set1 == NULL || set2 == NULL || seqlist == NULL)
2644 return;
2645
2646 if (sfp->is_feat)
2647 {
2648 SegregateItemsRecursor (seqlist, set1, set2,
2649 DoesNucProtSetContainFeatureType,
2650 DoesSequenceContainFeatureType,
2651 (Pointer) sfp);
2652 }
2653 else
2654 {
2655 SegregateItemsRecursor (seqlist, set1, set2,
2656 DoesNucProtSetContainDescriptorType,
2657 DoesSequenceContainDescriptorType,
2658 (Pointer) sfp);
2659 }
2660
2661 }
2662
2663
2664 /*=========================================================================*/
2665 /* */
2666 /* SegregateByFeatureOrDescriptor_Callback () - Segregates sequences that */
2667 /* contain a selected feature. */
2668 /* */
2669 /*=========================================================================*/
2670
2671 static void SegregateByFeatureOrDescriptor_Callback (ButtoN b)
2672 {
2673 SegregateFeatPtr sfp;
2674 SeqEntryPtr sep;
2675 UIEnum val;
2676 BioseqSetPtr bssp;
2677 SeqEntryPtr seqlist;
2678 BioseqSetPtr newset1, newset2;
2679 ObjMgrDataPtr omdptop;
2680 ObjMgrData omdata;
2681 Uint2 parenttype;
2682 Pointer parentptr;
2683 ValNodePtr vnp;
2684
2685 /* Check the initial conditions and get the sequence */
2686 sfp = (SegregateFeatPtr) GetObjectExtra (b);
2687 if (sfp == NULL || sfp->input_entityID == 0 || sfp->target_set == NULL) {
2688 Remove (sfp->form);
2689 return;
2690 }
2691
2692 sep = GetTopSeqEntryForEntityID (sfp->input_entityID);
2693 if (sep == NULL) {
2694 Remove (sfp->form);
2695 return;
2696 }
2697
2698 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
2699 GetSeqEntryParent (sep, &parentptr, &parenttype);
2700
2701 bssp = sfp->target_set;
2702 seqlist = bssp->seq_set;
2703 bssp->seq_set = NULL;
2704
2705 CreateSetsForSegregate (bssp, &newset1, &newset2);
2706
2707 /* Get the feature to look for */
2708 val = GetValue (sfp->type_popup);
2709 for (vnp = sfp->type_list; vnp != NULL && val > 1; vnp = vnp->next, val--)
2710 {
2711 }
2712 if (vnp == NULL || val != 1)
2713 {
2714 Remove (sfp->form);
2715 return;
2716 }
2717 sfp->segregate_type = vnp->choice;
2718
2719 /* Display the 'working' cursor */
2720
2721 WatchCursor ();
2722 Update ();
2723
2724 /* Do the search and move sequences */
2725 SegregateItemsByFeatureOrDescriptor (seqlist, sfp, newset1, newset2);
2726
2727 /* Remove the window and update things */
2728 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
2729 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
2730 ObjMgrSetDirtyFlag (sfp->input_entityID, TRUE);
2731 ObjMgrSendMsg (OM_MSG_UPDATE, sfp->input_entityID, 0, 0);
2732
2733 ArrowCursor ();
2734 Update ();
2735 Remove (sfp->form);
2736
2737 /* Return successfully */
2738 return;
2739 }
2740
2741
2742 /*=========================================================================*/
2743 /* */
2744 /* CreateSegregateByFeatureWindow () - Creates and then displays the window*/
2745 /* for getting segregate by text info from the user.*/
2746 /* */
2747 /*=========================================================================*/
2748
2749 static Int2 LIBCALLBACK CreateSegregateByFeatureOrDescriptorWindow (Pointer data, Boolean is_feat)
2750 {
2751 GrouP c;
2752 SegregateFeatPtr sfp;
2753 GrouP g;
2754 GrouP h;
2755 OMProcControlPtr ompcp;
2756 StdEditorProcsPtr sepp;
2757 WindoW w;
2758 ValNodePtr vnp;
2759
2760 /* Check parameters and get a pointer to the current data */
2761
2762 ompcp = (OMProcControlPtr) data;
2763 if (!OkToSegregate(ompcp)) {
2764 return OM_MSG_RET_ERROR;
2765 }
2766
2767 /* Create a new window, and a struct */
2768 /* to pass around the data in. */
2769
2770 sfp = (SegregateFeatPtr) MemNew (sizeof (SegregateFeatData));
2771 if (sfp == NULL)
2772 return OM_MSG_RET_ERROR;
2773 sfp->is_feat = is_feat;
2774
2775 if (sfp->is_feat)
2776 {
2777 w = FixedWindow (-50, -33, -10, -10, "Segregate By Feature",
2778 StdCloseWindowProc);
2779 }
2780 else
2781 {
2782 w = FixedWindow (-50, -33, -10, -10, "Segregate By Descriptor",
2783 StdCloseWindowProc);
2784 }
2785
2786 SetObjectExtra (w, sfp, StdCleanupFormProc);
2787 sfp->form = (ForM) w;
2788
2789 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2790 if (sepp != NULL) {
2791 SetActivate (w, sepp->activateForm);
2792 sfp->appmessage = sepp->handleMessages;
2793 }
2794
2795 sfp->input_entityID = ompcp->input_entityID;
2796 sfp->input_itemID = ompcp->input_itemID;
2797 sfp->input_itemtype = ompcp->input_itemtype;
2798 sfp->target_set = (BioseqSetPtr)ompcp->input_data;
2799
2800 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2801 if (sepp != NULL) {
2802 SetActivate (w, sepp->activateForm);
2803 sfp->appmessage = sepp->handleMessages;
2804 }
2805
2806 /* Add the popup lists */
2807
2808 h = HiddenGroup (w, -1, 0, NULL);
2809 SetGroupSpacing (h, 10, 10);
2810
2811 g = HiddenGroup (h, 3, 0, NULL);
2812
2813 if (sfp->is_feat)
2814 {
2815 StaticPrompt (g, "Segregate sequences with the feature", 0, dialogTextHeight,
2816 programFont, 'l');
2817 sfp->type_list = BuildFeatureValNodeList (TRUE, NULL, 0, TRUE, FALSE);
2818 }
2819 else
2820 {
2821 StaticPrompt (g, "Segregate sequences with the descriptor", 0, dialogTextHeight,
2822 programFont, 'l');
2823 sfp->type_list = BuildDescriptorValNodeList ();
2824 }
2825
2826 sfp->type_popup = PopupList (g, TRUE, NULL);
2827 SetObjectExtra (sfp->type_popup, sfp, NULL);
2828 for (vnp = sfp->type_list; vnp != NULL; vnp = vnp->next)
2829 {
2830 PopupItem (sfp->type_popup, (CharPtr) vnp->data.ptrvalue);
2831 }
2832 SetValue (sfp->type_popup, 1);
2833
2834 /* Add Accept and Cancel buttons */
2835
2836 c = HiddenGroup (h, 4, 0, NULL);
2837 sfp->accept = DefaultButton (c, "Accept", SegregateByFeatureOrDescriptor_Callback);
2838 SetObjectExtra (sfp->accept, sfp, NULL);
2839 PushButton (c, "Cancel", StdCancelButtonProc);
2840
2841 /* Line things up nicely */
2842
2843 AlignObjects (ALIGN_LEFT, (HANDLE) g, (HANDLE) c, (HANDLE) h, NULL);
2844
2845 /* Display the window now */
2846
2847 RealizeWindow (w);
2848 Show (w);
2849 Select (w);
2850 Select (sfp->accept);
2851 Update ();
2852 return OM_MSG_RET_OK;
2853 }
2854
2855 extern Int2 LIBCALLBACK CreateSegregateByFeatureWindow (Pointer data)
2856 {
2857 return CreateSegregateByFeatureOrDescriptorWindow (data, TRUE);
2858 }
2859
2860 extern Int2 LIBCALLBACK CreateSegregateByDescriptorWindow (Pointer data)
2861 {
2862 return CreateSegregateByFeatureOrDescriptorWindow (data, FALSE);
2863 }
2864
2865 typedef struct segregatemoltypedata
2866 {
2867 FEATURE_FORM_BLOCK
2868
2869 PopuP type_popup;
2870 ButtoN use_mol_type;
2871 PopuP class_popup;
2872 ButtoN use_mol_class;
2873 ButtoN accept;
2874 Uint1 moltype;
2875 Uint1 molclass;
2876 BioseqSetPtr target_set;
2877 } SegregateMolTypeData, PNTR SegregateMolTypePtr;
2878
2879 static ENUM_ALIST(molinfo_biomol_alist)
2880 {"Genomic DNA or RNA", 1},
2881 {"Precursor RNA", 2},
2882 {"mRNA [cDNA]", 3},
2883 {"Ribosomal RNA", 4},
2884 {"Transfer RNA", 5},
2885 {"Peptide", 8},
2886 {"Other-Genetic", 9},
2887 {"Genomic-mRNA", 10},
2888 {"cRNA", 11},
2889 {"Transcribed RNA", 13},
2890 {"Other", 255},
2891 END_ENUM_ALIST
2892
2893 static ENUM_ALIST(mol_class_alist)
2894 {"DNA", Seq_mol_dna},
2895 {"RNA", Seq_mol_rna},
2896 {"Protein", Seq_mol_aa},
2897 {"Nucleotide", Seq_mol_na},
2898 {"Other", Seq_mol_other},
2899 END_ENUM_ALIST
2900
2901 static Boolean LIBCALLBACK DoesSequenceHaveMoleculeType (BioseqPtr bsp, Pointer userdata)
2902 {
2903 SegregateMolTypePtr smp;
2904 ValNodePtr sdp;
2905 MolInfoPtr mip;
2906
2907 smp = (SegregateMolTypePtr) userdata;
2908 if (bsp == NULL || smp == NULL) return FALSE;
2909
2910 if (GetStatus (smp->use_mol_class) && bsp->mol != smp->molclass)
2911 {
2912 return FALSE;
2913 }
2914
2915 if (GetStatus (smp->use_mol_type))
2916 {
2917 sdp = bsp->descr;
2918 while (sdp != NULL)
2919 {
2920 if (sdp->choice == Seq_descr_molinfo && sdp->data.ptrvalue != NULL)
2921 {
2922 mip = (MolInfoPtr) sdp->data.ptrvalue;
2923 if (mip->biomol == smp->moltype)
2924 {
2925 return TRUE;
2926 }
2927 }
2928 sdp = sdp->next;
2929 }
2930 return FALSE;
2931 }
2932 return TRUE;
2933 }
2934
2935 typedef struct lookformoltype
2936 {
2937 Boolean found;
2938 Uint1 moltype;
2939 Uint1 molclass;
2940 } LookForMolTypeData, PNTR LookForMolTypePtr;
2941
2942 static void DoesNucProtSetHaveMoleculeTypeCallback (SeqDescPtr sdp, Pointer userdata)
2943 {
2944 LookForMolTypePtr l;
2945 MolInfoPtr mip;
2946
2947 if (sdp == NULL || userdata == NULL) return;
2948 l = (LookForMolTypePtr) userdata;
2949
2950 if (sdp->choice == Seq_descr_molinfo && sdp->data.ptrvalue != NULL)
2951 {
2952 mip = (MolInfoPtr) sdp->data.ptrvalue;
2953 if (mip->biomol == l->moltype)
2954 {
2955 l->found = TRUE;
2956 }
2957 }
2958 }
2959
2960 typedef struct lookformolclass
2961 {
2962 Boolean found;
2963 Uint1 molclass;
2964 } LookForMolClassData, PNTR LookForMolClassPtr;
2965
2966 static void FindMolClassCallback (BioseqPtr bsp, Pointer userdata)
2967 {
2968 LookForMolClassPtr lcp;
2969
2970 if (bsp == NULL || userdata == NULL) return;
2971 lcp = (LookForMolClassPtr) userdata;
2972
2973 if (bsp->mol == lcp->molclass)
2974 {
2975 lcp->found = TRUE;
2976 }
2977 }
2978
2979 static Boolean LIBCALLBACK DoesNucProtSetHaveMoleculeType (BioseqSetPtr bssp, Pointer userdata)
2980 {
2981 LookForMolTypeData lm;
2982 LookForMolClassData lc;
2983 SegregateMolTypePtr smp;
2984
2985 if (bssp == NULL || userdata == NULL) return FALSE;
2986 smp = (SegregateMolTypePtr) userdata;
2987
2988 if (GetStatus (smp->use_mol_class))
2989 {
2990 lc.found = FALSE;
2991 lc.molclass = smp->molclass;
2992 VisitBioseqsInSet (bssp, &lc, FindMolClassCallback);
2993 if (!lc.found) return FALSE;
2994 }
2995
2996 if (GetStatus (smp->use_mol_type))
2997 {
2998 lm.moltype = smp->moltype;
2999 lm.found = FALSE;
3000 VisitDescriptorsInSet (bssp, &lm, DoesNucProtSetHaveMoleculeTypeCallback);
3001 if (!lm.found) return FALSE;
3002 }
3003 return TRUE;
3004 }
3005
3006 static void LIBCALLBACK SegregateByMoleculeType
3007 (SeqEntryPtr seqlist,
3008 Pointer userdata,
3009 BioseqSetPtr set1,
3010 BioseqSetPtr set2)
3011 {
3012 SegregateItemsRecursor (seqlist, set1, set2,
3013 DoesNucProtSetHaveMoleculeType,
3014 DoesSequenceHaveMoleculeType, userdata);
3015 }
3016
3017
3018 /*=========================================================================*/
3019 /* */
3020 /* SegregateByMoleculeType_Callback () - Segregates sequences that */
3021 /* have a selected molecule type. */
3022 /* */
3023 /*=========================================================================*/
3024
3025 static void SegregateByMoleculeType_Callback (ButtoN b)
3026 {
3027 SegregateMolTypePtr smp;
3028 SeqEntryPtr sep;
3029 UIEnum val;
3030
3031 /* Check the initial conditions and get the sequence */
3032 smp = (SegregateMolTypePtr) GetObjectExtra (b);
3033 if (smp == NULL || smp->input_entityID == 0 || smp->target_set == NULL) {
3034 Remove (smp->form);
3035 return;
3036 }
3037
3038 sep = GetTopSeqEntryForEntityID (smp->input_entityID);
3039 if (sep == NULL) {
3040 Remove (smp->form);
3041 return;
3042 }
3043
3044 if (!GetEnumPopup (smp->type_popup, molinfo_biomol_alist, &val))
3045 {
3046 return;
3047 }
3048 smp->moltype = val;
3049 if (!GetEnumPopup (smp->class_popup, mol_class_alist, &val))
3050 {
3051 return;
3052 }
3053 smp->molclass = val;
3054
3055 SegregateItemsGenericCallback (sep, smp->target_set, smp->input_entityID,
3056 (Pointer) smp, SegregateByMoleculeType);
3057
3058 Remove (smp->form);
3059
3060 /* Return successfully */
3061 return;
3062 }
3063
3064 static void EnableMolInfoPopups (ButtoN b)
3065 {
3066 SegregateMolTypePtr smp;
3067 Boolean ok_to_accept = FALSE;
3068
3069 smp = (SegregateMolTypePtr) GetObjectExtra (b);
3070 if (smp == NULL) return;
3071
3072 if (GetStatus (smp->use_mol_type))
3073 {
3074 Enable (smp->type_popup);
3075 ok_to_accept = TRUE;
3076 }
3077 else
3078 {
3079 Disable (smp->type_popup);
3080 }
3081 if (GetStatus (smp->use_mol_class))
3082 {
3083 Enable (smp->class_popup);
3084 ok_to_accept = TRUE;
3085 }
3086 else
3087 {
3088 Disable (smp->class_popup);
3089 }
3090 if (ok_to_accept)
3091 {
3092 Enable (smp->accept);
3093 }
3094 else
3095 {
3096 Disable (smp->accept);
3097 }
3098 }
3099
3100 /*=========================================================================*/
3101 /* */
3102 /* CreateSegregateByFeatureWindow () - Creates and then displays the window*/
3103 /* for getting segregate by text info from the user.*/
3104 /* */
3105 /*=========================================================================*/
3106
3107 extern Int2 LIBCALLBACK CreateSegregateByMoleculeTypeWindow (Pointer data)
3108 {
3109 GrouP c;
3110 SegregateMolTypePtr smp;
3111 GrouP g, k;
3112 GrouP h;
3113 OMProcControlPtr ompcp;
3114 StdEditorProcsPtr sepp;
3115 WindoW w;
3116
3117 /* Check parameters and get a pointer to the current data */
3118
3119 ompcp = (OMProcControlPtr) data;
3120 if (!OkToSegregate(ompcp)) {
3121 return OM_MSG_RET_ERROR;
3122 }
3123
3124 /* Create a new window, and a struct */
3125 /* to pass around the data in. */
3126
3127 smp = (SegregateMolTypePtr) MemNew (sizeof (SegregateMolTypeData));
3128 if (smp == NULL)
3129 return OM_MSG_RET_ERROR;
3130
3131 w = FixedWindow (-50, -33, -10, -10, "Segregate By Molecule Type",
3132 StdCloseWindowProc);
3133
3134 SetObjectExtra (w, smp, StdCleanupFormProc);
3135 smp->form = (ForM) w;
3136
3137 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3138 if (sepp != NULL) {
3139 SetActivate (w, sepp->activateForm);
3140 smp->appmessage = sepp->handleMessages;
3141 }
3142
3143 smp->input_entityID = ompcp->input_entityID;
3144 smp->input_itemID = ompcp->input_itemID;
3145 smp->input_itemtype = ompcp->input_itemtype;
3146 smp->target_set = (BioseqSetPtr)ompcp->input_data;
3147
3148 /* Add the popup lists */
3149
3150 h = HiddenGroup (w, -1, 0, NULL);
3151 SetGroupSpacing (h, 10, 10);
3152
3153 g = HiddenGroup (h, 1, 0, NULL);
3154
3155 StaticPrompt (g, "Segregate sequences with:", 0, dialogTextHeight,
3156 programFont, 'l');
3157 k = HiddenGroup (g, 2, 0, NULL);
3158 smp->use_mol_type = CheckBox (k, "Molecule Type", EnableMolInfoPopups);
3159 SetObjectExtra (smp->use_mol_type, smp, NULL);
3160 smp->type_popup = PopupList (k, TRUE, NULL);
3161 InitEnumPopup (smp->type_popup, molinfo_biomol_alist, NULL);
3162 SetValue (smp->type_popup, 1);
3163 SetStatus (smp->use_mol_type, FALSE);
3164 Disable (smp->type_popup);
3165 k = HiddenGroup (g, 2, 0, NULL);
3166 smp->use_mol_class = CheckBox (k, "Molecule Class", EnableMolInfoPopups);
3167 SetObjectExtra (smp->use_mol_class, smp, NULL);
3168 smp->class_popup = PopupList (k, TRUE, NULL);
3169 InitEnumPopup (smp->class_popup, mol_class_alist, NULL);
3170 SetValue (smp->class_popup, 1);
3171 SetStatus (smp->use_mol_class, FALSE);
3172 Disable (smp->class_popup);
3173
3174 /* Add Accept and Cancel buttons */
3175
3176 c = HiddenGroup (h, 4, 0, NULL);
3177 smp->accept = DefaultButton (c, "Accept", SegregateByMoleculeType_Callback);
3178 SetObjectExtra (smp->accept, smp, NULL);
3179 Disable (smp->accept);
3180 PushButton (c, "Cancel", StdCancelButtonProc);
3181
3182 /* Line things up nicely */
3183
3184 AlignObjects (ALIGN_LEFT, (HANDLE) g, (HANDLE) c, (HANDLE) h, NULL);
3185
3186 /* Display the window now */
3187
3188 RealizeWindow (w);
3189 Show (w);
3190 Select (w);
3191 Select (smp->accept);
3192 Update ();
3193 return OM_MSG_RET_OK;
3194 }
3195
3196 static Boolean LIBCALLBACK DoesSequenceHaveID (BioseqPtr bsp, Pointer userdata)
3197 {
3198 ConvertFormPtr cfp;
3199 Boolean found = FALSE;
3200 ValNodePtr vnp;
3201
3202 cfp = (ConvertFormPtr) userdata;
3203 if (bsp == NULL || cfp == NULL) return FALSE;
3204
3205 for (vnp = cfp->id_list; vnp != NULL && !found; vnp = vnp->next) {
3206 if (SeqIdIn (vnp->data.ptrvalue, bsp->id)) {
3207 found = TRUE;
3208 }
3209 }
3210 return found;
3211 }
3212
3213 static Boolean LIBCALLBACK DoesNucProtSetContainID (BioseqSetPtr bssp, Pointer userdata)
3214 {
3215 SeqEntryPtr sep;
3216 BioseqPtr bsp;
3217 ConvertFormPtr cfp;
3218
3219 if (bssp == NULL) return FALSE;
3220 cfp = (ConvertFormPtr) userdata;
3221 if (cfp == NULL) return FALSE;
3222
3223 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
3224 if (IS_Bioseq (sep)) {
3225 bsp = (BioseqPtr) sep->data.ptrvalue;
3226 if (DoesSequenceHaveID (bsp, (Pointer)cfp)) {
3227 return TRUE;
3228 }
3229 }
3230 }
3231 return FALSE;
3232 }
3233
3234 static void SegregateItemsById
3235 (SeqEntryPtr seqlist,
3236 ConvertFormPtr cfp,
3237 BioseqSetPtr set1,
3238 BioseqSetPtr set2)
3239 {
3240 SegregateItemsRecursor (seqlist, set1, set2,
3241 DoesNucProtSetContainID,
3242 DoesSequenceHaveID, (Pointer)cfp);
3243 }
3244
3245 static void SetSegregateByIDAcceptButton (Pointer data)
3246
3247 {
3248 ConvertFormPtr cfp;
3249 CharPtr id_str;
3250
3251 cfp = (ConvertFormPtr) data;
3252 if (cfp == NULL)
3253 return;
3254
3255 id_str = SaveStringFromText (cfp->deleteText);
3256 if (StringHasNoText (id_str)) {
3257 SafeDisable (cfp->accept);
3258 } else {
3259 SafeEnable (cfp->accept);
3260 }
3261 }
3262
3263 /*=========================================================================*/
3264 /* */
3265 /* SegregateByID_Callback () - Finds and deletes all items of a selected */
3266 /* type that contain a given text phrase. */
3267 /* */
3268 /*=========================================================================*/
3269
3270 static void SegregateById_Callback (ButtoN b)
3271 {
3272 ConvertFormPtr cfp;
3273 SeqEntryPtr sep;
3274 BioseqSetPtr bssp;
3275 SeqEntryPtr seqlist;
3276 BioseqSetPtr newset1, newset2;
3277 ObjMgrDataPtr omdptop;
3278 ObjMgrData omdata;
3279 Uint2 parenttype;
3280 Pointer parentptr;
3281 Boolean leaveDlgUp = FALSE;
3282 CharPtr id_str;
3283
3284 /* Check the initial conditions and get the sequence */
3285 cfp = (ConvertFormPtr) GetObjectExtra (b);
3286 if (cfp == NULL || cfp->input_entityID == 0 || cfp->target_set == NULL) {
3287 Remove (cfp->form);
3288 return;
3289 }
3290
3291 sep = GetTopSeqEntryForEntityID (cfp->input_entityID);
3292 if (sep == NULL) {
3293 Remove (cfp->form);
3294 return;
3295 }
3296
3297 if (GetStatus (cfp->leaveDlgUp))
3298 {
3299 leaveDlgUp = TRUE;
3300 }
3301
3302 /* Get the string to search for */
3303 id_str = SaveStringFromText(cfp->deleteText);
3304 if (StringHasNoText (id_str)){
3305 if (!leaveDlgUp)
3306 {
3307 Remove (cfp->form);
3308 }
3309 id_str = MemFree (id_str);
3310 return;
3311 }
3312
3313 cfp->id_list = ParseAccessionNumberListFromString (id_str, SeqMgrGetSeqEntryForData (cfp->target_set));
3314 id_str = MemFree (id_str);
3315 if (cfp->id_list == NULL) {
3316 Message (MSG_ERROR, "No IDs specified!");
3317 return;
3318 }
3319
3320 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
3321 GetSeqEntryParent (sep, &parentptr, &parenttype);
3322
3323 bssp = cfp->target_set;
3324 seqlist = bssp->seq_set;
3325 bssp->seq_set = NULL;
3326
3327 CreateSetsForSegregate (bssp, &newset1, &newset2);
3328
3329 /* Display the 'working' cursor */
3330
3331 WatchCursor ();
3332 Update ();
3333
3334 /* Do the search and move sequences */
3335 SegregateItemsById (seqlist, cfp, newset1, newset2);
3336
3337 cfp->id_list = FreeSeqIdList (cfp->id_list);
3338 /* Remove the window and update things */
3339 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
3340 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
3341 ObjMgrSetDirtyFlag (cfp->input_entityID, TRUE);
3342 ObjMgrSendMsg (OM_MSG_UPDATE, cfp->input_entityID, 0, 0);
3343
3344 ArrowCursor ();
3345 Update ();
3346 if (!leaveDlgUp)
3347 {
3348 Remove (cfp->form);
3349 }
3350
3351 /* Return successfully */
3352 return;
3353 }
3354
3355 /*=========================================================================*/
3356 /* */
3357 /* CreateSegregateByIdWindow () - Creates and then displays the window */
3358 /* for getting segregate by ID info from the user.*/
3359 /* */
3360 /*=========================================================================*/
3361
3362 extern Int2 LIBCALLBACK CreateSegregateByIdWindow (Pointer data)
3363 {
3364 GrouP c;
3365 ConvertFormPtr cfp;
3366 GrouP g;
3367 GrouP h;
3368 OMProcControlPtr ompcp;
3369 StdEditorProcsPtr sepp;
3370 WindoW w;
3371
3372 /* Check parameters and get a pointer to the current data */
3373
3374 ompcp = (OMProcControlPtr) data;
3375 if (!OkToSegregate(ompcp)) {
3376 return OM_MSG_RET_ERROR;
3377 }
3378
3379 /* Create a new window, and a struct */
3380 /* to pass around the data in. */
3381
3382 cfp = ConvertFormNew ();
3383 if (cfp == NULL)
3384 return OM_MSG_RET_ERROR;
3385 cfp->target_set = (BioseqSetPtr)ompcp->input_data;
3386 cfp->set_accept_proc = SetSegregateByIDAcceptButton;
3387
3388 w = FixedWindow (-50, -33, -10, -10, "Segregate By ID",
3389 StdCloseWindowProc);
3390 SetObjectExtra (w, cfp, CleanupSegregatePage);
3391 cfp->form = (ForM) w;
3392
3393 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3394 if (sepp != NULL) {
3395 SetActivate (w, sepp->activateForm);
3396 cfp->appmessage = sepp->handleMessages;
3397 }
3398
3399 cfp->input_entityID = ompcp->input_entityID;
3400 cfp->input_itemID = ompcp->input_itemID;
3401 cfp->input_itemtype = ompcp->input_itemtype;
3402
3403 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3404 if (sepp != NULL) {
3405 SetActivate (w, sepp->activateForm);
3406 cfp->appmessage = sepp->handleMessages;
3407 }
3408
3409 /* Add the popup lists */
3410
3411 h = HiddenGroup (w, -1, 0, NULL);
3412 SetGroupSpacing (h, 10, 10);
3413
3414 g = HiddenGroup (h, 3, 0, NULL);
3415
3416 StaticPrompt (g, "Segregate sequences with the following IDs", 0, dialogTextHeight,
3417 programFont, 'l');
3418 cfp->deleteText = DialogText (g, "", 10, ConvertFormTextCallback);
3419 SetObjectExtra (cfp->deleteText, cfp, NULL);
3420
3421 /* Add Accept and Cancel buttons */
3422
3423 c = HiddenGroup (h, 4, 0, NULL);
3424 cfp->accept = DefaultButton (c, "Accept", SegregateById_Callback);
3425 SetObjectExtra (cfp->accept, cfp, NULL);
3426 Disable (cfp->accept);
3427 PushButton (c, "Cancel", StdCancelButtonProc);
3428 cfp->leaveDlgUp = CheckBox (c, "Leave Dialog Up", NULL);
3429
3430 /* Line things up nicely */
3431
3432 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
3433
3434 /* Display the window now */
3435
3436 RealizeWindow (w);
3437 Show (w);
3438 Select (w);
3439 Select (cfp->accept);
3440 Update ();
3441 return OM_MSG_RET_OK;
3442 }
3443
3444
3445 static void SearchAndExciseTextInside (CharPtr PNTR strptr, ConvertFormPtr cfp)
3446
3447 {
3448 CharPtr lft = NULL;
3449 CharPtr rgt = NULL;
3450 CharPtr string;
3451 CharPtr next_delete = NULL;
3452 Int4 strLen;
3453
3454 if (strptr == NULL || cfp == NULL || cfp->textportion == NULL) return;
3455 string = *strptr;
3456 if (string == NULL) return;
3457
3458 FindTextPortionXInString (string, cfp->textportion, &lft, &strLen);
3459 if (lft == NULL) return;
3460 rgt = lft + strLen;
3461 next_delete = lft;
3462 if (lft < rgt) { /* No text to delete */
3463 while (*rgt != 0) {
3464 *lft = *rgt;
3465 lft++;
3466 rgt++;
3467 }
3468 *lft = '\0';
3469 }
3470 if (cfp->repeat_remove && next_delete != NULL && *next_delete != 0) {
3471 SearchAndExciseTextInside (&next_delete, cfp);
3472 }
3473 }
3474
3475
3476 /*---------------------------------------------------------------------*/
3477 /* */
3478 /* RemOutTxt_SearchAndExcise () -- Removes all text from a string that */
3479 /* does not match a specified substring*/
3480 /* */
3481 /*---------------------------------------------------------------------*/
3482
3483 static void SearchAndExciseTextOutside (CharPtr sourceStr, ConvertFormPtr cfp)
3484 {
3485 CharPtr leftEnd = NULL;
3486 CharPtr rightEnd = NULL;
3487 Int4 strLen;
3488 Int4 i;
3489
3490 /* Check parameters */
3491
3492 if (cfp == NULL || cfp->textportion == NULL || sourceStr == NULL)
3493 {
3494 return;
3495 }
3496
3497 FindTextPortionXInString (sourceStr, cfp->textportion, &leftEnd, &strLen);
3498
3499 if (leftEnd != NULL)
3500 {
3501 rightEnd = leftEnd + strLen;
3502 }
3503
3504 if (NULL == leftEnd) /* String not found */
3505 {
3506 if (DO_NOTHING == cfp->ifNotFound)
3507 {
3508 return;
3509 }
3510 else
3511 {
3512 sourceStr [0] = '\0';
3513 return;
3514 }
3515 }
3516 else
3517 {
3518 /* End the original string at rightEnd and */
3519 /* then move everything starting at leftEnd */
3520 /* to the beginning of the original. */
3521
3522 rightEnd[0] = '\0';
3523 if (leftEnd == sourceStr)
3524 return;
3525
3526 strLen = StringLen (leftEnd);
3527
3528 for (i = 0; i <= strLen; i++)
3529 sourceStr[i] = leftEnd[i];
3530
3531 sourceStr[i] = '\0';
3532 }
3533 }
3534
3535
3536 static void SearchAndExciseText (CharPtr str, ConvertFormPtr cfp)
3537 {
3538 if (str == NULL || cfp == NULL) return;
3539 if (cfp->remove_inside)
3540 {
3541 SearchAndExciseTextInside (&str, cfp);
3542 }
3543 else
3544 {
3545 SearchAndExciseTextOutside (str, cfp);
3546 }
3547 }
3548
3549
3550 static void RemoveAFeatureText (SeqFeatPtr sfp, Pointer mydata)
3551 {
3552 ConvertFormPtr cfp;
3553 GBQualPtr gbqp;
3554 GeneRefPtr grp;
3555 ProtRefPtr prp;
3556 RnaRefPtr rrp;
3557 CharPtr str;
3558 ValNodePtr vnp;
3559
3560 if (sfp == NULL) return;
3561 cfp = (ConvertFormPtr) mydata;
3562 if (cfp == NULL) return;
3563
3564 if (sfp->data.choice == SEQFEAT_GENE && cfp->type == eFieldTypeGene) {
3565 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
3566 if (grp != NULL) {
3567 switch (cfp->subtype) {
3568 case 1 :
3569 SearchAndExciseText (grp->locus, cfp);
3570 break;
3571 case 2 :
3572 SearchAndExciseText (grp->desc, cfp);
3573 break;
3574 case 3 :
3575 SearchAndExciseText (grp->allele, cfp);
3576 break;
3577 case 4 :
3578 SearchAndExciseText (grp->maploc, cfp);
3579 break;
3580 case 5 :
3581 SearchAndExciseText (grp->locus_tag, cfp);
3582 break;
3583 case 6 :
3584 for (vnp = grp->syn; vnp != NULL; vnp = vnp->next) {
3585 str = (CharPtr) vnp->data.ptrvalue;
3586 SearchAndExciseText (str, cfp);
3587 }
3588 break;
3589 case 7 :
3590 SearchAndExciseText (sfp->comment, cfp);
3591 break;
3592 default :
3593 break;
3594 }
3595 }
3596 } else if (sfp->data.choice == SEQFEAT_CDREGION && cfp->type == eFieldTypeCDS) {
3597 switch (cfp->subtype) {
3598 case CDS_COMMENT :
3599 SearchAndExciseText (sfp->comment, cfp);
3600 break;
3601 case CDS_GENE_XREF :
3602 break;
3603 default :
3604 break;
3605 }
3606 } else if (sfp->data.choice == SEQFEAT_PROT && cfp->type == eFieldTypeProtein) {
3607 prp = (ProtRefPtr) sfp->data.value.ptrvalue;
3608 if (prp != NULL) {
3609 switch (cfp->subtype) {
3610 case 1 :
3611 for (vnp = prp->name; vnp != NULL; vnp = vnp->next) {
3612 str = (CharPtr) vnp->data.ptrvalue;
3613 SearchAndExciseText (str, cfp);
3614 }
3615 break;
3616 case 2 :
3617 SearchAndExciseText (prp->desc, cfp);
3618 break;
3619 case 3 :
3620 for (vnp = prp->ec; vnp != NULL; vnp = vnp->next) {
3621 str = (CharPtr) vnp->data.ptrvalue;
3622 SearchAndExciseText (str, cfp);
3623 }
3624 break;
3625 case 4 :
3626 for (vnp = prp->activity; vnp != NULL; vnp = vnp->next) {
3627 str = (CharPtr) vnp->data.ptrvalue;
3628 SearchAndExciseText (str, cfp);
3629 }
3630 break;
3631 case 5 :
3632 SearchAndExciseText (sfp->comment, cfp);
3633 break;
3634 default :
3635 break;
3636 }
3637 }
3638 } else if (sfp->data.choice == SEQFEAT_RNA && cfp->type == eFieldTypeRNA) {
3639 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
3640 if (rrp != NULL) {
3641 switch (cfp->subtype) {
3642 case 1 :
3643 if (rrp->ext.choice == 0 || rrp->ext.choice == 1) {
3644 rrp->ext.choice = 1;
3645 str = (CharPtr) rrp->ext.value.ptrvalue;
3646 SearchAndExciseText (str, cfp);
3647 }
3648 break;
3649 case 2 :
3650 SearchAndExciseText (sfp->comment, cfp);
3651 break;
3652 case 3 :
3653 default :
3654 break;
3655 }
3656 }
3657 } else if (sfp->data.choice == SEQFEAT_IMP && cfp->type == eFieldTypeImport) {
3658 switch (cfp->subtype) {
3659 case IMPORT_GBQUAL_FIELD :
3660 gbqp = sfp->qual;
3661 while (NULL != gbqp)
3662 {
3663 if (NULL != gbqp->val)
3664 SearchAndExciseText (gbqp->val, cfp);
3665 gbqp = gbqp->next;
3666 }
3667 break;
3668 case IMPORT_COMMENT_FIELD :
3669 SearchAndExciseText (sfp->comment, cfp);
3670 break;
3671 default :
3672 break;
3673 }
3674 }
3675 }
3676
3677
3678 static void RemoveOrgModText (BioSourcePtr biop, ConvertFormPtr cfp)
3679 {
3680 OrgModPtr mod, prev_mod = NULL, next_mod;
3681
3682 if (biop == NULL || biop->org == NULL || biop->org->orgname == NULL || cfp == NULL) return;
3683
3684 mod = biop->org->orgname->mod;
3685 while (mod != NULL) {
3686 next_mod = mod->next;
3687 if (mod->subtype == cfp->subtype) {
3688 SearchAndExciseText (mod->subname, cfp);
3689 if (StringHasNoText (mod->subname) && !IsNonTextModifier (GetOrgModQualName (mod->subtype))) {
3690 if (prev_mod == NULL) {
3691 biop->org->orgname->mod = mod->next;
3692 } else {
3693 prev_mod->next = mod->next;
3694 }
3695 mod->next = NULL;
3696 mod = OrgModFree (mod);
3697 } else {
3698 prev_mod = mod;
3699 }
3700 } else {
3701 prev_mod = mod;
3702 }
3703 mod = mod->next;
3704 }
3705 }
3706
3707
3708 static void RemoveSubSourceText (BioSourcePtr biop, ConvertFormPtr cfp)
3709 {
3710 SubSourcePtr ssp, next_ssp, prev_ssp = NULL;
3711
3712 if (biop == NULL || cfp == NULL) return;
3713
3714 ssp = biop->subtype;
3715 while (ssp != NULL) {
3716 next_ssp = ssp->next;
3717 if (ssp->subtype == (cfp->subtype - 1000)) {
3718 SearchAndExciseText (ssp->name, cfp);
3719 if (StringHasNoText (ssp->name) && !IsNonTextModifier (GetSubsourceQualName (ssp->subtype))) {
3720 if (prev_ssp == NULL) {
3721 biop->subtype = ssp->next;
3722 } else {
3723 prev_ssp->next = ssp->next;
3724 }
3725 ssp->next = NULL;
3726 ssp = SubSourceFree (ssp);
3727 } else {
3728 prev_ssp = ssp;
3729 }
3730 } else {
3731 prev_ssp = ssp;
3732 }
3733 ssp = next_ssp;
3734 }
3735 }
3736
3737 static void RemoveASourceText (BioSourcePtr biop, Pointer data)
3738 {
3739 ConvertFormPtr cfp;
3740 OrgRefPtr orp;
3741 CharPtr tmp_str;
3742
3743 cfp = (ConvertFormPtr) data;
3744 if (biop == NULL || cfp == NULL) return;
3745 switch (cfp->type) {
3746 case eFieldTypeBioSource :
3747 orp = biop->org;
3748 if (orp == NULL) return;
3749 switch (cfp->subtype) {
3750 case ORGREF_SCI_NAME_FIELD :
3751 tmp_str = StringSave (orp->taxname);
3752 SearchAndExciseText (tmp_str, cfp);
3753 if (StringCmp (tmp_str, orp->taxname) == 0) {
3754 /* no change, no need to remove taxref */
3755 tmp_str = MemFree (tmp_str);
3756 } else {
3757 SetTaxNameAndRemoveTaxRef (orp, tmp_str);
3758 }
3759 break;
3760 case ORGREF_COMMON_NAME_FIELD :
3761 SearchAndExciseText (orp->common, cfp);
3762 break;
3763 case ORGREF_LINEAGE_FIELD :
3764 if (orp->orgname != NULL) {
3765 SearchAndExciseText (orp->orgname->lineage, cfp);
3766 }
3767 break;
3768 case ORGREF_DIVISION_FIELD :
3769 if (orp->orgname != NULL) {
3770 SearchAndExciseText (orp->orgname->div, cfp);
3771 }
3772 break;
3773 default:
3774 break;
3775 }
3776 break;
3777 case eFieldTypeOrgModSubSource :
3778 if (cfp->subtype < 1000) { /* Orgmod Note */
3779 RemoveOrgModText (biop, cfp);
3780 } else { /* subsource note */
3781 RemoveSubSourceText (biop, cfp);
3782 }
3783 break;
3784 default:
3785 break;
3786 }
3787 }
3788
3789
3790 static void RemoveDescriptorTextCallback (SeqDescrPtr sdp, Pointer userdata)
3791 {
3792 ConvertFormPtr cfp;
3793 CharPtr title;
3794 ObjValNodePtr ovp;
3795
3796 cfp = (ConvertFormPtr) userdata;
3797
3798 if (sdp == NULL || cfp == NULL) return;
3799
3800 if (cfp->type == eFieldTypeDefline) {
3801 if (sdp->choice != Seq_descr_title) {
3802 return;
3803 }
3804 } else if (cfp->type == eFieldTypeCommentDescriptor) {
3805 if (sdp->choice != Seq_descr_comment) {
3806 return;
3807 }
3808 } else {
3809 return;
3810 }
3811
3812 title = (CharPtr) sdp->data.ptrvalue;
3813 SearchAndExciseText (title, cfp);
3814
3815 if (StringHasNoText (title) && (sdp->extended > 0)) {
3816 ovp = (ObjValNodePtr) sdp;
3817 ovp->idx.deleteme = TRUE;
3818 cfp->isDirty = TRUE;
3819 }
3820 }
3821
3822
3823 static void DoRemoveText (ConvertFormPtr cfp)
3824
3825 {
3826 SeqEntryPtr sep;
3827 FieldSubfieldPtr f;
3828
3829 /* Get the current sequence and associated data */
3830
3831 if (cfp == NULL || cfp->input_entityID == 0)
3832 return;
3833
3834 sep = GetTopSeqEntryForEntityID (cfp->input_entityID);
3835 if (sep == NULL)
3836 return;
3837
3838 /* Get the feature and subfeature types */
3839 f = DialogToPointer (cfp->target_dlg);
3840 if (f == NULL || f->field < 0 || (f->subfield < 0 && f->subfield_list == NULL)) {
3841 f = FieldSubfieldFree (f);
3842 return;
3843 }
3844
3845 cfp->type = f->field;
3846 cfp->subtype = f->subfield;
3847
3848 f = FieldSubfieldFree (f);
3849
3850 /* Hide the window and set the 'working' cursor */
3851
3852 Hide (cfp->form);
3853 WatchCursor ();
3854 Update ();
3855
3856
3857 /* get information about text to remove */
3858 cfp->textportion = (TextPortionXPtr) DialogToPointer (cfp->textportion_dlg);
3859
3860 if (GetValue (cfp->repeat_remove_grp) == 2) {
3861 cfp->repeat_remove = TRUE;
3862 } else {
3863 cfp->repeat_remove = FALSE;
3864 }
3865
3866 /* Do actual work of removing text */
3867 cfp->isDirty = FALSE;
3868 if (cfp->type == eFieldTypeDefline || cfp->type == eFieldTypeCommentDescriptor) {
3869 VisitDescriptorsInSep (sep, cfp, RemoveDescriptorTextCallback);
3870 }
3871 else if (cfp->type == eFieldTypeBioSource || cfp->type == eFieldTypeOrgModSubSource) {
3872 VisitBioSourcesInSep (sep, cfp, RemoveASourceText);
3873 }
3874 else {
3875 VisitFeaturesInSep (sep, cfp, RemoveAFeatureText);
3876 }
3877
3878 /* Clean up and exit */
3879
3880 cfp->textportion = TextPortionXFree (cfp->textportion);
3881
3882 if (cfp->isDirty) {
3883 DeleteMarkedObjects (cfp->input_entityID, 0, NULL);
3884 }
3885
3886 ObjMgrSetDirtyFlag (cfp->input_entityID, TRUE);
3887 ObjMgrSendMsg (OM_MSG_UPDATE, cfp->input_entityID, 0, 0);
3888 if (GetStatus (cfp->leaveDlgUp))
3889 {
3890 Show (cfp->form);
3891 }
3892 else
3893 {
3894 Remove (cfp->form);
3895 }
3896 ArrowCursor ();
3897 Update ();
3898 }
3899
3900 static void ConvertMessageProc (ForM f, Int2 mssg)
3901
3902 {
3903 StdEditorProcsPtr sepp;
3904
3905 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3906 if (sepp != NULL) {
3907 if (sepp->handleMessages != NULL) {
3908 sepp->handleMessages (f, mssg);
3909 }
3910 }
3911 }
3912
3913
3914 /* gather information specific ro remove inside text, then call common removetext function */
3915 static void DoRemoveInsideText (ButtoN b)
3916 {
3917 ConvertFormPtr cfp;
3918
3919 cfp = (ConvertFormPtr) GetObjectExtra (b);
3920 if (cfp == NULL) return;
3921
3922 if (GetValue (cfp->repeat_remove_grp) == 2) {
3923 cfp->repeat_remove = TRUE;
3924 } else {
3925 cfp->repeat_remove = FALSE;
3926 }
3927
3928 DoRemoveText (cfp);
3929 }
3930
3931
3932 /* gather information specific ro remove inside text, then call common removetext function */
3933 static void DoRemoveOutsideText (ButtoN b)
3934 {
3935 ConvertFormPtr cfp;
3936
3937 cfp = (ConvertFormPtr) GetObjectExtra (b);
3938 if (cfp == NULL) return;
3939
3940 if (GetValue (cfp->ifNotFoundGroup) == DO_NOTHING)
3941 cfp->ifNotFound = DO_NOTHING;
3942 else
3943 cfp->ifNotFound = REMOVE_ALL_TEXT;
3944
3945
3946 DoRemoveText (cfp);
3947 }
3948
3949
3950 /*-------------------------------------------------------------------------*/
3951 /* */
3952 /* SetRemoveTextAcceptButton () -- Enable/Disable the Accept button depending */
3953 /* on the condition of other window objects. */
3954 /* */
3955 /*-------------------------------------------------------------------------*/
3956
3957 static void SetRemoveTextAcceptButton (Pointer data)
3958
3959 {
3960 ConvertFormPtr cfp;
3961 FieldSubfieldPtr f;
3962 Boolean ok_to_accept = FALSE;
3963 TextPortionXPtr tp;
3964
3965 cfp = (ConvertFormPtr) data;
3966 if (cfp == NULL) return;
3967
3968 f = DialogToPointer (cfp->target_dlg);
3969 if (f != NULL && f->field >= 0 && (f->subfield >= 0 || f->subfield_list != NULL)) {
3970 if (f->field == eFieldTypeFeatureNote) {
3971 if (f->subfield_list != NULL) {
3972 ok_to_accept = TRUE;
3973 }
3974 } else {
3975 ok_to_accept = TRUE;
3976 }
3977 }
3978 f = FieldSubfieldFree (f);
3979 if (ok_to_accept) {
3980 tp = (TextPortionXPtr) DialogToPointer (cfp->textportion_dlg);
3981 if (tp == NULL || (StringHasNoText (tp->start_text) && StringHasNoText (tp->end_text))) {
3982 ok_to_accept = FALSE;
3983 }
3984 tp = TextPortionXFree (tp);
3985 }
3986 if (ok_to_accept) {
3987 SafeEnable (cfp->accept);
3988 } else {
3989 SafeDisable (cfp->accept);
3990 }
3991 f = FieldSubfieldFree (f);
3992 }
3993
3994
3995 static void ClearRemoveOutsideText (ButtoN b)
3996 {
3997 ConvertFormPtr cfp;
3998
3999 cfp = (ConvertFormPtr) GetObjectExtra (b);
4000 if (cfp == NULL) return;
4001
4002 PointerToDialog (cfp->target_dlg, NULL);
4003 PointerToDialog (cfp->textportion_dlg, NULL);
4004
4005 SetRemoveTextAcceptButton (cfp);
4006 }
4007
4008
4009 /*---------------------------------------------------------------------*/
4010 /* */
4011 /* RemoveTextOutsideString () */
4012 /* */
4013 /*---------------------------------------------------------------------*/
4014
4015 extern void RemoveTextOutsideString (IteM i)
4016 {
4017 Boolean allowed[eFieldType_Max];
4018 BaseFormPtr bfp;
4019 GrouP buttonGroup;
4020 ConvertFormPtr cfp;
4021 GrouP mainGroup;
4022 SeqEntryPtr sep;
4023 StdEditorProcsPtr sepp;
4024 WindoW w;
4025 PrompT p, p2;
4026 ButtoN b;
4027
4028 /* Get current sequence */
4029
4030 #ifdef WIN_MAC
4031 bfp = currentFormDataPtr;
4032 #else
4033 bfp = GetObjectExtra (i);
4034 #endif
4035 if (bfp == NULL)
4036 return;
4037
4038 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
4039 if (sep == NULL)
4040 return;
4041
4042 /* Create a form for passing user data on to callbacks */
4043
4044 cfp = ConvertFormNew ();
4045 if (cfp == NULL)
4046 return;
4047
4048 /* Create a window for getting user input */
4049
4050 w = FixedWindow (-50, -33, -10, -10, "Remove Text Outside String",
4051 StdCloseWindowProc);
4052 SetObjectExtra (w, cfp, StdCleanupFormProc);
4053 cfp->form = (ForM) w;
4054 cfp->formmessage = ConvertMessageProc;
4055
4056 /* Attach some basic data and callbacks to the data form */
4057
4058 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4059 if (sepp != NULL) {
4060 SetActivate (w, sepp->activateForm);
4061 cfp->appmessage = sepp->handleMessages;
4062 }
4063
4064 cfp->input_entityID = bfp->input_entityID;
4065 cfp->input_itemID = bfp->input_itemID;
4066 cfp->input_itemtype = bfp->input_itemtype;
4067
4068 cfp->set_accept_proc = SetRemoveTextAcceptButton ;
4069 cfp->remove_inside = FALSE;
4070
4071 /* Main object group for holding all the others */
4072
4073 mainGroup = HiddenGroup (w, -1, 0, NULL);
4074 SetGroupSpacing (mainGroup, 10, 10);
4075
4076 /* Set up Text group and headers */
4077
4078 p = StaticPrompt (mainGroup, "Remove Text", 0, 0, programFont, 'l');
4079
4080 cfp->textportion_dlg = TextPortionXDialogEx (mainGroup, FALSE, SetRemoveTextAcceptButton, cfp);
4081
4082 /* The "If not found" group */
4083
4084 cfp->ifNotFoundGroup = HiddenGroup (mainGroup, 0, 3, NULL);
4085 StaticPrompt (cfp->ifNotFoundGroup, "If field doesn't contain searched"
4086 " for text:", 0, 0, programFont, 'l');
4087
4088 RadioButton (cfp->ifNotFoundGroup, " Do nothing to field");
4089 RadioButton (cfp->ifNotFoundGroup, " Remove entire field text");
4090 SetValue (cfp->ifNotFoundGroup, DO_NOTHING);
4091
4092 p2 = StaticPrompt (mainGroup, "Perform excision in", 0, popupMenuHeight, programFont, 'l');
4093
4094 /* selecting the target field */
4095 MemSet (allowed, TRUE, sizeof (Boolean) * eFieldType_Max);
4096 allowed[eFieldTypeFeatureNote] = FALSE;
4097 allowed[eFieldTypePublication] = FALSE;
4098 cfp->target_dlg = CreateFieldSubfieldDlg (mainGroup, allowed, ChangeTargetFields, cfp);
4099
4100 /* clear button */
4101 b = PushButton (mainGroup, "Clear", ClearRemoveOutsideText);
4102 SetObjectExtra (b, cfp, NULL);
4103
4104 /* Accept and Cancel buttons */
4105
4106 buttonGroup = HiddenGroup (mainGroup, 4, 0, NULL);
4107 cfp->accept = DefaultButton (buttonGroup, "Accept", DoRemoveOutsideText);
4108 SetObjectExtra (cfp->accept, cfp, NULL);
4109 Disable (cfp->accept);
4110 PushButton (buttonGroup, "Cancel", StdCancelButtonProc);
4111 cfp->leaveDlgUp = CheckBox (buttonGroup, "Leave Dialog Up", NULL);
4112
4113 /* Line things up and display the window */
4114
4115 AlignObjects (ALIGN_CENTER,
4116 (HANDLE) p,
4117 (HANDLE) cfp->textportion_dlg,
4118 (HANDLE) cfp->ifNotFoundGroup,
4119 (HANDLE) p2,
4120 (HANDLE) cfp->target_dlg,
4121 (HANDLE) b,
4122 (HANDLE) buttonGroup,
4123 NULL);
4124
4125 RealizeWindow (w);
4126 Show (w);
4127 Select (w);
4128 Update ();
4129 }
4130
4131 extern void RemoveTextInsideString (IteM i)
4132 {
4133 BaseFormPtr bfp;
4134 GrouP c;
4135 ConvertFormPtr cfp;
4136 GrouP h;
4137 PrompT ppt, ppt2;
4138 SeqEntryPtr sep;
4139 StdEditorProcsPtr sepp;
4140 WindoW w;
4141 Boolean allowed[eFieldType_Max];
4142
4143 #ifdef WIN_MAC
4144 bfp = currentFormDataPtr;
4145 #else
4146 bfp = GetObjectExtra (i);
4147 #endif
4148 if (bfp == NULL) return;
4149 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
4150 if (sep == NULL) return;
4151 cfp = ConvertFormNew ();
4152 if (cfp == NULL) return;
4153
4154 cfp->set_accept_proc = SetRemoveTextAcceptButton;
4155 cfp->remove_inside = TRUE;
4156
4157 w = FixedWindow (-50, -33, -10, -10, "Remove Text Inside String", StdCloseWindowProc);
4158 SetObjectExtra (w, cfp, StdCleanupFormProc);
4159 cfp->form = (ForM) w;
4160 cfp->formmessage = ConvertMessageProc;
4161
4162 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4163 if (sepp != NULL) {
4164 SetActivate (w, sepp->activateForm);
4165 cfp->appmessage = sepp->handleMessages;
4166 }
4167
4168 cfp->input_entityID = bfp->input_entityID;
4169 cfp->input_itemID = bfp->input_itemID;
4170 cfp->input_itemtype = bfp->input_itemtype;
4171
4172 h = HiddenGroup (w, -1, 0, NULL);
4173 SetGroupSpacing (h, 10, 10);
4174
4175 ppt = StaticPrompt (h, "Remove Text", 0, popupMenuHeight, programFont, 'c');
4176 cfp->textportion_dlg = TextPortionXDialogEx (h, TRUE, SetRemoveTextAcceptButton, cfp);
4177
4178 cfp->repeat_remove_grp = HiddenGroup (h, 2, 0, NULL);
4179 RadioButton (cfp->repeat_remove_grp, "Remove first instance in each string");
4180 RadioButton (cfp->repeat_remove_grp, "Remove all instances");
4181 SetValue (cfp->repeat_remove_grp, 1);
4182
4183 ppt2 = StaticPrompt (h, "Perform excision in", 0, popupMenuHeight, programFont, 'c');
4184
4185 MemSet (allowed, TRUE, sizeof (Boolean) * eFieldType_Max);
4186 allowed[eFieldTypeCommentDescriptor] = TRUE;
4187 allowed[eFieldTypeFeatureNote] = FALSE;
4188 allowed[eFieldTypePublication] = FALSE;
4189 cfp->target_dlg = CreateFieldSubfieldDlg (h, allowed, ChangeTargetFields, cfp);
4190
4191 c = HiddenGroup (h, 4, 0, NULL);
4192 cfp->accept = DefaultButton (c, "Accept", DoRemoveInsideText);
4193 SetObjectExtra (cfp->accept, cfp, NULL);
4194 Disable (cfp->accept);
4195 PushButton (c, "Cancel", StdCancelButtonProc);
4196 cfp->leaveDlgUp = CheckBox (c, "Leave Dialog Up", NULL);
4197
4198
4199 AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) cfp->textportion_dlg, (HANDLE) cfp->repeat_remove_grp, (HANDLE) ppt2, (HANDLE) cfp->target_dlg, (HANDLE) c, NULL);
4200 RealizeWindow (w);
4201 Show (w);
4202 Select (w);
4203 Select (cfp->textportion_dlg);
4204 Update ();
4205 }
4206
4207 /* AAForCodon is extern in seqport.c */
4208 /* NLM_EXTERN Uint1 AAForCodon (Uint1Ptr codon, CharPtr codes); */
4209
4210 /*
4211 static Boolean CorrectStartCodonCallback (GatherContextPtr gcp)
4212
4213 {
4214 Uint1 aa;
4215 Boolean bad_base;
4216 CodeBreakPtr cbp;
4217 Uint1 codon [3];
4218 CharPtr codes;
4219 CdRegionPtr crp;
4220 GeneticCodePtr gc;
4221 Int2 i;
4222 Uint1 residue;
4223 SeqEntryPtr sep;
4224 SeqFeatPtr sfp;
4225 SeqLocPtr slp;
4226 SeqPntPtr spntp;
4227 SeqPortPtr spp;
4228 ValNodePtr vnp;
4229
4230 if (gcp == NULL) return TRUE;
4231 sep = (SeqEntryPtr) gcp->userdata;
4232 if (sep == NULL ) return TRUE;
4233 if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
4234 sfp = (SeqFeatPtr) gcp->thisitem;
4235 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return TRUE;
4236 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
4237 if (crp == NULL) return TRUE;
4238
4239 if (crp->code_break != NULL) return TRUE;
4240
4241 gc = NULL;
4242 if (crp->genetic_code != NULL)
4243 {
4244 vnp = (ValNodePtr)(crp->genetic_code->data.ptrvalue);
4245 while ((vnp != NULL) && (gcp == NULL))
4246 {
4247 switch (vnp->choice)
4248 {
4249 case 1:
4250 gc = GeneticCodeFind(0, (CharPtr)vnp->data.ptrvalue);
4251 break;
4252 case 2:
4253 gc = GeneticCodeFind(vnp->data.intvalue, NULL);
4254 break;
4255 case 3:
4256 case 6:
4257 case 4:
4258 case 5:
4259 case 7:
4260 case 8:
4261 default:
4262 break;
4263 }
4264 vnp = vnp->next;
4265 }
4266 }
4267 if (gc == NULL)
4268 gc = GeneticCodeFind(1, NULL);
4269 if (gc == NULL) return TRUE;
4270
4271 codes = NULL;
4272 for (vnp = (ValNodePtr)gc->data.ptrvalue; vnp != NULL; vnp = vnp->next)
4273 {
4274 if (vnp->choice == 3)
4275 codes = (CharPtr)vnp->data.ptrvalue;
4276 }
4277 if (codes == NULL) return TRUE;
4278
4279 if (crp->frame == 2 || crp->frame == 3) return TRUE;
4280
4281 spp = SeqPortNewByLoc (sfp->location, Seq_code_ncbi4na);
4282 if (spp == NULL) return TRUE;
4283 bad_base = FALSE;
4284 for (i = 0; i < 3; i++) {
4285 residue = SeqPortGetResidue (spp);
4286 if (residue == SEQPORT_EOF)
4287 break;
4288 if (residue == INVALID_RESIDUE)
4289 bad_base = TRUE;
4290 codon[i] = residue;
4291 }
4292 SeqPortFree (spp);
4293 if (i != 3 || bad_base) return TRUE;
4294 aa = AAForCodon (codon, codes);
4295
4296 spp = SeqPortNewByLoc (sfp->product, Seq_code_ncbieaa);
4297 if (spp == NULL) return TRUE;
4298 residue = SeqPortGetResidue (spp);
4299 SeqPortFree (spp);
4300 if (residue == SEQPORT_EOF || residue == INVALID_RESIDUE) return TRUE;
4301
4302 if (residue != aa) {
4303 cbp = CodeBreakNew ();
4304 if (cbp != NULL) {
4305 spntp = SeqPntNew ();
4306 slp = ValNodeNew (NULL);
4307 slp->choice = SEQLOC_PNT;
4308 slp->data.ptrvalue = (Pointer) spntp;
4309 spntp->point = (Int4) 0;
4310 spntp->id = SeqIdStripLocus (SeqIdDup (SeqLocId (sfp->product)));
4311 cbp->loc = slp;
4312 slp = aaLoc_to_dnaLoc (sfp, cbp->loc);
4313 cbp->loc = SeqLocFree (cbp->loc);
4314 cbp->loc = slp;
4315 cbp->aa.value.intvalue = aa;
4316 cbp->aa.choice = 1;
4317 cbp->next = crp->code_break;
4318 crp->code_break = cbp;
4319 }
4320 }
4321
4322 return TRUE;
4323 }
4324
4325 static void CorrectStartCodon (SeqEntryPtr sep, Uint2 entityID)
4326
4327 {
4328 BioseqSetPtr bssp;
4329 GatherScope gs;
4330
4331 if (sep == NULL) return;
4332 if (IS_Bioseq_set (sep)) {
4333 bssp = (BioseqSetPtr) sep->data.ptrvalue;
4334 if (bssp != NULL && (bssp->_class == 7 || bssp->_class == 13 ||
4335 bssp->_class == 14 || bssp->_class == 15)) {
4336 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
4337 CorrectStartCodon (sep, entityID);
4338 }
4339 return;
4340 }
4341 }
4342 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
4343 gs.seglevels = 1;
4344 gs.get_feats_location = FALSE;
4345 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
4346 gs.ignore[OBJ_BIOSEQ] = FALSE;
4347 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
4348 gs.ignore[OBJ_SEQFEAT] = FALSE;
4349 gs.ignore[OBJ_SEQANNOT] = FALSE;
4350 gs.scope = sep;
4351 GatherEntity (entityID, (Pointer) sep, CorrectStartCodonCallback, &gs);
4352 }
4353
4354 extern void CorrectCDSStartCodon (IteM i);
4355 extern void CorrectCDSStartCodon (IteM i)
4356
4357 {
4358 BaseFormPtr bfp;
4359 SeqEntryPtr sep;
4360
4361 #ifdef WIN_MAC
4362 bfp = currentFormDataPtr;
4363 #else
4364 bfp = GetObjectExtra (i);
4365 #endif
4366 if (bfp == NULL) return;
4367 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
4368 if (sep == NULL) return;
4369 CorrectStartCodon (sep, bfp->input_entityID);
4370 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
4371 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
4372 }
4373 */
4374
4375
4376 typedef struct applyformdata {
4377 FEATURE_FORM_BLOCK
4378
4379 Int2 type;
4380 Int2 errcount;
4381 ValNodePtr ambigList;
4382 Boolean noLeft;
4383 Boolean noRight;
4384 ButtoN applyToParts;
4385 ButtoN partial5;
4386 ButtoN partial3;
4387 TexT onlyThisPart;
4388 GrouP all_or_some_grp;
4389 TexT accession_list_txt;
4390
4391 DialoG feature_details_dlg;
4392
4393 BatchApplyFeatureDetailsPtr feature_details_data;
4394
4395 GrouP strand_group;
4396 GrouP use_whole_interval;
4397 TexT left_end;
4398 TexT right_end;
4399 ButtoN add_to_seq_with_like_feature;
4400 ButtoN also_add_mRNA_btn;
4401 ButtoN accept;
4402 ButtoN leaveDlgUp;
4403
4404 GetSamplePtr gsp;
4405 ExistingTextPtr etp;
4406 } ApplyFormData, PNTR ApplyFormPtr;
4407
4408 typedef struct alreadyhas {
4409 Boolean rsult;
4410 Uint1 featchoice;
4411 Uint1 descchoice;
4412 Uint1 rnatype;
4413 } AlreadyHas, PNTR AlreadyHasPtr;
4414
4415 static Boolean SeeIfAlreadyHasGatherFunc (GatherContextPtr gcp)
4416
4417 {
4418 AlreadyHasPtr ahp;
4419 RnaRefPtr rrp;
4420 ValNodePtr sdp;
4421 SeqFeatPtr sfp;
4422
4423 if (gcp == NULL) return TRUE;
4424
4425 ahp = (AlreadyHasPtr) gcp->userdata;
4426 if (ahp == NULL ) return TRUE;
4427
4428 if (gcp->thistype == OBJ_SEQFEAT && ahp->featchoice != 0) {
4429 sfp = (SeqFeatPtr) gcp->thisitem;
4430 if (sfp != NULL && sfp->data.choice == ahp->featchoice && sfp->data.value.ptrvalue != NULL) {
4431 if (sfp->data.choice == SEQFEAT_RNA) {
4432 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
4433 if (rrp->type != ahp->rnatype) return TRUE;
4434 }
4435 ahp->rsult = TRUE;
4436 return FALSE;
4437 }
4438 } else if (gcp->thistype == OBJ_SEQDESC && ahp->descchoice != 0) {
4439 sdp = (ValNodePtr) gcp->thisitem;
4440 if (sdp != NULL && sdp->choice == ahp->descchoice && sdp->data.ptrvalue != NULL) {
4441 ahp->rsult = TRUE;
4442 return FALSE;
4443 }
4444 }
4445 return TRUE;
4446 }
4447
4448 static Boolean AlreadyHasFeatOrDesc (SeqEntryPtr sep, Uint1 featchoice, Uint1 descchoice, Uint1 rnatype)
4449
4450 {
4451 AlreadyHas ah;
4452 BioseqPtr bsp;
4453 GatherScope gs;
4454 SeqEntryPtr nsep;
4455 SeqIdPtr sip;
4456 SeqLocPtr slp;
4457
4458 ah.rsult = FALSE;
4459 ah.featchoice = featchoice;
4460 ah.descchoice = descchoice;
4461 ah.rnatype = rnatype;
4462 if (sep == NULL) return FALSE;
4463 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
4464 gs.seglevels = 1;
4465 gs.get_feats_location = TRUE;
4466 MemSet ((Pointer) (gs.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
4467 gs.ignore[OBJ_BIOSEQ] = FALSE;
4468 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
4469 gs.ignore[OBJ_SEQFEAT] = FALSE;
4470 gs.ignore[OBJ_SEQDESC] = FALSE;
4471 gs.ignore[OBJ_SEQANNOT] = FALSE;
4472 gs.scope = sep;
4473 if (descchoice != 0) {
4474 nsep = FindNucSeqEntry (sep);
4475 if (nsep != NULL && IS_Bioseq (nsep)) {
4476 bsp = (BioseqPtr) nsep->data.ptrvalue;
4477 if (bsp != NULL) {
4478 slp = ValNodeNew (NULL);
4479 slp->choice = SEQLOC_WHOLE;
4480 sip = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0)));
4481 slp->data.ptrvalue = sip;
4482 gs.target = slp;
4483 }
4484 }
4485 }
4486 GatherSeqEntry (sep, (Pointer) (&ah), SeeIfAlreadyHasGatherFunc, &gs);
4487 gs.target = SeqLocFree (gs.target);
4488 return ah.rsult;
4489 }
4490
4491 static void setSeqFeatStrand(SeqFeatPtr sfp, Uint1 strand)
4492 {
4493 SeqIntPtr sqip;
4494
4495 if (sfp == NULL) return;
4496 if (sfp->location == NULL) return;
4497 if (sfp->location->choice != SEQLOC_INT) return;
4498 sqip = (SeqIntPtr) sfp->location->data.ptrvalue;
4499 if (sqip != NULL)
4500 {
4501 sqip->strand = Seq_strand_minus;
4502 }
4503 }
4504
4505 /* must be called after partials and strand are set*/
4506 static void AdjustSeqLocForApply (SeqFeatPtr sfp, ApplyFormPtr afp)
4507 {
4508 BioseqPtr bsp;
4509 SeqLocPtr slp;
4510 SeqIntPtr sip;
4511 CharPtr num_str;
4512 Int4 from;
4513 Int4 to;
4514 Int4 tmp;
4515 Boolean partial3, partial5;
4516 Boolean is_caret = FALSE;
4517 Uint1 strand;
4518
4519 if (sfp == NULL || afp == NULL) return;
4520
4521 bsp = BioseqFindFromSeqLoc (sfp->location);
4522 if (bsp == NULL) return;
4523
4524 num_str = SaveStringFromText (afp->left_end);
4525 if (num_str == NULL) return;
4526 from = atoi (num_str);
4527 tmp = StringLen (num_str);
4528 if (tmp > 1 && num_str[tmp - 1] == '^')
4529 {
4530 is_caret = TRUE;
4531 }
4532 num_str = MemFree (num_str);
4533 num_str = SaveStringFromText (afp->right_end);
4534 if (num_str == NULL) return;
4535 to = atoi (num_str);
4536 num_str = MemFree (num_str);
4537 if (from > to)
4538 {
4539 tmp = from;
4540 from = to;
4541 to = tmp;
4542 }
4543 if (from < 1)
4544 {
4545 from = 1;
4546 }
4547 if (to < 1)
4548 {
4549 if (to == 0 && is_caret) {
4550 to = from + 1;
4551 } else {
4552 to = 1;
4553 }
4554 }
4555 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
4556 strand = SeqLocStrand (sfp->location);
4557 if (to > bsp->length)
4558 {
4559 to = bsp->length;
4560 partial3 = TRUE;
4561 }
4562
4563 if (is_caret && to != from + 1) {
4564 is_caret = FALSE;
4565 }
4566
4567 slp = NULL;
4568 if (is_caret) {
4569 AddSeqLocPoint (&slp, SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0))),
4570 from, FALSE, TRUE, strand);
4571 } else {
4572 slp = ValNodeNew (NULL);
4573 if (slp != NULL) {
4574 sip = SeqIntNew ();
4575 if (sip != NULL) {
4576 sip->from = from - 1;
4577 sip->to = to - 1;
4578 sip->strand = strand;
4579 sip->id = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0)));
4580 slp->choice = SEQLOC_INT;
4581 slp->data.ptrvalue = (Pointer) sip;
4582 SetSeqLocPartial (slp, partial5, partial3);
4583 }
4584 }
4585 }
4586
4587 sfp->location = SeqLocFree (sfp->location);
4588 sfp->location = slp;
4589
4590 if (partial5 || partial3)
4591 {
4592 sfp->partial = TRUE;
4593 }
4594
4595 }
4596
4597 static void SetApplyFeatureLocation (SeqFeatPtr sfp, ApplyFormPtr afp)
4598 {
4599 if (sfp == NULL || afp == NULL)
4600 {
4601 return;
4602 }
4603
4604 if (GetValue (afp->strand_group) == 2)
4605 {
4606 /* reverse strand direction - strand direction is plus by default */
4607 setSeqFeatStrand (sfp, Seq_strand_minus);
4608 }
4609
4610 SetSeqLocPartial (sfp->location, afp->noLeft, afp->noRight);
4611
4612 if (afp->use_whole_interval != NULL
4613 && GetValue (afp->use_whole_interval) != 1)
4614 {
4615 /* adjust location to match coordinates from user */
4616 AdjustSeqLocForApply (sfp, afp);
4617 }
4618
4619 sfp->partial = (afp->noLeft || afp->noRight);
4620 }
4621
4622 static void AddGeneXrefToFeat (SeqFeatPtr sfp, CharPtr str)
4623 {
4624 SeqFeatXrefPtr xref;
4625 GeneRefPtr grp;
4626
4627 if (sfp == NULL || StringHasNoText (str)) return;
4628
4629 /* add gene xref to feature */
4630 xref = SeqFeatXrefNew ();
4631 if (xref != NULL)
4632 {
4633 grp = CreateNewGeneRef (str, NULL, NULL, FALSE);
4634 if (grp != NULL)
4635 {
4636 xref->data.choice = SEQFEAT_GENE;
4637 xref->data.value.ptrvalue = grp;
4638 xref->next = sfp->xref;
4639 sfp->xref = xref;
4640 }
4641 }
4642 }
4643
4644 static SeqFeatPtr ApplyGene (CharPtr str, ApplyFormPtr afp, SeqEntryPtr gene_sep, SeqFeatPtr sfp)
4645 {
4646 GeneRefPtr grp;
4647 SeqFeatPtr gene_sfp;
4648 SeqFeatXrefPtr xref;
4649 SeqMgrFeatContext fcontext;
4650 BioseqPtr bsp = NULL;
4651 SeqFeatPtr other_feat;
4652 SeqFeatPtr overlap_gene;
4653 Boolean added_xrefs = FALSE;
4654 SeqFeatPtr misc_feat = NULL;
4655 SeqLocPtr overlap_loc;
4656 CharPtr gene_desc = NULL;
4657
4658 if (afp == NULL || gene_sep == NULL
4659 || (StringHasNoText (str)
4660 && (afp->feature_details_data == NULL
4661 || StringHasNoText (afp->feature_details_data->geneDesc))))
4662 {
4663 return NULL;
4664 }
4665
4666 if (afp != NULL && afp->feature_details_data != NULL)
4667 {
4668 gene_desc = afp->feature_details_data->geneDesc;
4669 }
4670
4671 /* we need a location to use when we're checking for feature-stealing genes */
4672 if (sfp != NULL)
4673 {
4674 overlap_loc = sfp->location;
4675 }
4676 else
4677 {
4678 misc_feat = CreateNewFeature (gene_sep, NULL, SEQFEAT_COMMENT, NULL);
4679 if (NULL == misc_feat)
4680 return NULL;
4681
4682 SetApplyFeatureLocation (misc_feat, afp);
4683
4684 overlap_loc = misc_feat->location;
4685 }
4686
4687 /* first, add gene xrefs to all features on bioseq that are contained in the location */
4688 /* maintain list of features that had xrefs before, should not remove them later */
4689 if (IS_Bioseq (gene_sep))
4690 {
4691 bsp = (BioseqPtr) gene_sep->data.ptrvalue;
4692 }
4693 else if (sfp != NULL)
4694 {
4695 bsp = BioseqFindFromSeqLoc (sfp->location);
4696 }
4697 if (bsp != NULL)
4698 {
4699 other_feat = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
4700 while (other_feat != NULL)
4701 {
4702 if (other_feat != sfp && other_feat->data.choice != SEQFEAT_GENE)
4703 {
4704 for (xref = other_feat->xref;
4705 xref != NULL && xref->data.choice != SEQFEAT_GENE;
4706 xref = xref->next)
4707 {}
4708 if (xref == NULL
4709 && SeqLocCompare (other_feat->location, overlap_loc) == SLC_A_EQ_B)
4710 {
4711 overlap_gene = SeqMgrGetOverlappingGene (other_feat->location, &fcontext);
4712 if (overlap_gene != NULL)
4713 {
4714 AddGeneXrefToFeat (other_feat, fcontext.label);
4715 added_xrefs = TRUE;
4716 }
4717 }
4718 }
4719 other_feat = SeqMgrGetNextFeature (bsp, other_feat, 0, 0, &fcontext);
4720 }
4721 }
4722
4723 if (misc_feat != NULL)
4724 {
4725 misc_feat->idx.deleteme = TRUE;
4726 DeleteMarkedObjects (0, OBJ_SEQENTRY, gene_sep);
4727 }
4728
4729 grp = CreateNewGeneRef (str, NULL, gene_desc, FALSE);
4730 if (NULL == grp)
4731 return NULL;
4732
4733 gene_sfp = CreateNewFeature (gene_sep, NULL, SEQFEAT_GENE, NULL);
4734 if (NULL == gene_sfp)
4735 return NULL;
4736
4737 gene_sfp->data.value.ptrvalue = (Pointer) grp;
4738
4739 SetApplyFeatureLocation (gene_sfp, afp);
4740
4741 if (added_xrefs && sfp != NULL)
4742 {
4743 /* add gene xref to feature */
4744 AddGeneXrefToFeat (sfp, str);
4745 }
4746
4747 return gene_sfp;
4748 }
4749
4750
4751 typedef struct adjustfeatforgapdialog {
4752 DIALOG_MESSAGE_BLOCK
4753 DialoG feature_select;
4754 ButtoN unknown_gaps;
4755 ButtoN known_gaps;
4756 GrouP partial_grp;
4757 ButtoN trim_ends;
4758 ButtoN split_internal;
4759
4760 Nlm_ChangeNotifyProc change_notify;
4761 Pointer change_userdata;
4762 } AdjustFeatForGapDialogData, PNTR AdjustFeatForGapDialogPtr;
4763
4764
4765 static void AdjustFeaturesForGapToDialog (DialoG d, Pointer udata)
4766 {
4767 AdjustFeatForGapDialogPtr dlg;
4768 AdjustFeatForGapPtr data;
4769
4770 dlg = (AdjustFeatForGapDialogPtr) GetObjectExtra (d);
4771 data = (AdjustFeatForGapPtr) udata;
4772
4773 if (dlg == NULL) return;
4774
4775 if (data == NULL) {
4776 PointerToDialog (dlg->feature_select, NULL);
4777 SetStatus (dlg->unknown_gaps, FALSE);
4778 SetStatus (dlg->known_gaps, FALSE);
4779 SetStatus (dlg->trim_ends, FALSE);
4780 SetStatus (dlg->split_internal, FALSE);
4781 SetValue (dlg->partial_grp, 2);
4782 } else {
4783 PointerToDialog (dlg->feature_select, data->feature_list);
4784 SetStatus (dlg->unknown_gaps, data->unknown_gaps);
4785 SetStatus (dlg->known_gaps, data->known_gaps);
4786 SetStatus (dlg->split_internal, data->split_internal);
4787 SetStatus (dlg->trim_ends, data->trim_ends);
4788
4789 if (data->make_partial && data->partial_for_pseudo) {
4790 SetValue (dlg->partial_grp, 1);
4791 } else if (data->make_partial && !data->partial_for_pseudo) {
4792 SetValue (dlg->partial_grp, 2);
4793 } else {
4794 SetValue (dlg->partial_grp, 3);
4795 }
4796 }
4797 }
4798
4799
4800 static Pointer AdjustFeaturesForGapToPointer (DialoG d)
4801 {
4802 AdjustFeatForGapDialogPtr dlg;
4803 AdjustFeatForGapPtr data;
4804 Int4 grp_val;
4805
4806 dlg = (AdjustFeatForGapDialogPtr) GetObjectExtra (d);
4807
4808 if (dlg == NULL) return NULL;
4809
4810 data = (AdjustFeatForGapPtr) MemNew (sizeof (AdjustFeatForGapData));
4811
4812 /* get list of feature types to ask on */
4813 data->feature_list = (ValNodePtr) DialogToPointer (dlg->feature_select);
4814 data->features_in_gap = NULL;
4815
4816 data->unknown_gaps = GetStatus (dlg->unknown_gaps);
4817 data->known_gaps = GetStatus (dlg->known_gaps);
4818
4819 grp_val = GetValue (dlg->partial_grp);
4820 switch (grp_val) {
4821 case 1:
4822 data->make_partial = TRUE;
4823 data->partial_for_pseudo = TRUE;
4824 break;
4825 case 2:
4826 data->make_partial = TRUE;
4827 data->partial_for_pseudo = FALSE;
4828 break;
4829 case 3:
4830 data->make_partial = FALSE;
4831 data->partial_for_pseudo = FALSE;
4832 break;
4833 }
4834
4835 data->split_internal = GetStatus (dlg->split_internal);
4836 data->trim_ends = GetStatus (dlg->trim_ends);
4837
4838 return (Pointer) data;
4839 }
4840
4841
4842 static ValNodePtr TestAdjustForGapsDialog (DialoG d)
4843 {
4844 AdjustFeatForGapDialogPtr dlg;
4845 AdjustFeatForGapPtr data;
4846 ValNodePtr err_list = NULL;
4847
4848 dlg = (AdjustFeatForGapDialogPtr) GetObjectExtra (d);
4849 if (dlg == NULL)
4850 {
4851 ValNodeAddPointer (&err_list, 0, "No dialog");
4852 return err_list;
4853 }
4854
4855 data = (AdjustFeatForGapPtr) DialogToPointer (d);
4856 if (data == NULL)
4857 {
4858 ValNodeAddPointer (&err_list, 0, "No data");
4859 return err_list;
4860 }
4861
4862 if (data->feature_list == NULL)
4863 {
4864 ValNodeAddPointer (&err_list, 0, "No features");
4865 }
4866
4867 if (!data->unknown_gaps && !data->known_gaps)
4868 {
4869 ValNodeAddPointer (&err_list, 0, "No gaps");
4870 }
4871
4872 if (!data->split_internal && !data->trim_ends)
4873 {
4874 ValNodeAddPointer (&err_list, 0, "No action");
4875 }
4876
4877 data = AdjustFeatForGapFree (data);
4878
4879 return err_list;
4880 }
4881
4882
4883 static void AdjustFeaturesForGapsChangeNotifyButton (ButtoN b)
4884 {
4885 AdjustFeatForGapDialogPtr dlg;
4886
4887 dlg = (AdjustFeatForGapDialogPtr) GetObjectExtra (b);
4888 if (dlg != NULL && dlg->change_notify != NULL) {
4889 (dlg->change_notify) (dlg->change_userdata);
4890 }
4891 }
4892
4893
4894 static void AdjustFeaturesForGapsChangeNotifyGroup (GrouP g)
4895 {
4896 AdjustFeatForGapDialogPtr dlg;
4897
4898 dlg = (AdjustFeatForGapDialogPtr) GetObjectExtra (g);
4899 if (dlg != NULL && dlg->change_notify != NULL) {
4900 (dlg->change_notify) (dlg->change_userdata);
4901 }
4902 }
4903
4904
4905 static DialoG AdjustFeaturesForGapDialog (GrouP h, Uint2 entityID, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
4906 {
4907 AdjustFeatForGapDialogPtr dlg;
4908 GrouP p, g, g2;
4909 SeqEntryPtr sep;
4910
4911 dlg = (AdjustFeatForGapDialogPtr) MemNew (sizeof (AdjustFeatForGapDialogData));
4912 if (dlg == NULL) return NULL;
4913
4914 p = HiddenGroup (h, -1, 0, NULL);
4915 SetObjectExtra (p, dlg, StdCleanupExtraProc);
4916 SetGroupSpacing (p, 10, 10);
4917
4918 dlg->dialog = (DialoG) p;
4919 dlg->todialog = AdjustFeaturesForGapToDialog;
4920 dlg->fromdialog = AdjustFeaturesForGapToPointer;
4921 dlg->dialogmessage = NULL;
4922 dlg->testdialog = TestAdjustForGapsDialog;
4923 dlg->change_notify = change_notify;
4924 dlg->change_userdata = change_userdata;
4925
4926 sep = GetTopSeqEntryForEntityID (entityID);
4927 dlg->feature_select = FeatureSelectionDialogEx (p, TRUE, sep,
4928 change_notify,
4929 change_userdata);
4930
4931 g = HiddenGroup (p, 2, 0, NULL);
4932 dlg->unknown_gaps = CheckBox (g, "Unknown length gaps", AdjustFeaturesForGapsChangeNotifyButton);
4933 SetObjectExtra (dlg->unknown_gaps, dlg, NULL);
4934 dlg->known_gaps = CheckBox (g, "Known length gaps", AdjustFeaturesForGapsChangeNotifyButton);
4935 SetObjectExtra (dlg->known_gaps, dlg, NULL);
4936
4937 dlg->partial_grp = NormalGroup (p, 3, 0, "Make truncated ends partial", programFont, AdjustFeaturesForGapsChangeNotifyGroup);
4938 SetObjectExtra (dlg->partial_grp, dlg, NULL);
4939 RadioButton (dlg->partial_grp, "Always");
4940 RadioButton (dlg->partial_grp, "Unless pseudo");
4941 RadioButton (dlg->partial_grp, "Never");
4942 SetValue (dlg->partial_grp, 2);
4943
4944 g2 = HiddenGroup (p, 2, 0, NULL);
4945 dlg->trim_ends = CheckBox (g2, "Trim ends in gaps", AdjustFeaturesForGapsChangeNotifyButton);
4946 SetObjectExtra (dlg->trim_ends, dlg, NULL);
4947 dlg->split_internal = CheckBox (g2, "Split for internal gaps", AdjustFeaturesForGapsChangeNotifyButton);
4948 SetObjectExtra (dlg->split_internal, dlg, NULL);
4949
4950 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->feature_select, (HANDLE) g, (HANDLE) dlg->partial_grp, (HANDLE) g2, NULL);
4951 return (DialoG) p;
4952 }
4953
4954 typedef struct adjustfeatforgapform {
4955 FORM_MESSAGE_BLOCK
4956
4957 DialoG dlg;
4958 DialoG clickable_list;
4959 ButtoN accept_btn;
4960
4961 ValNodePtr feat_list;
4962 } AdjustFeatforGapFormData, PNTR AdjustFeatForGapFormPtr;
4963
4964
4965 typedef struct featforadjust {
4966 AdjustFeatForGapPtr afgp;
4967 ValNodePtr features_to_adjust;
4968 ValNodePtr features_contain_gap;
4969 ValNodePtr features_in_gap;
4970 } FeatForAdjustData, PNTR FeatForAdjustPtr;
4971
4972
4973 static void FindFeaturesToBeAdjustedForGapsCallback (SeqFeatPtr sfp, Pointer data)
4974 {
4975 FeatForAdjustPtr faap;
4976 BioseqPtr gapped_bioseq;
4977 Boolean terminal_gaps = FALSE;
4978 Boolean entirely_in_gap = FALSE;
4979 Boolean internal_gaps = FALSE;
4980
4981 if (sfp == NULL || data == NULL) return;
4982
4983 faap = (FeatForAdjustPtr) data;
4984 if (faap->afgp == NULL) return;
4985
4986 if (!FeatureOkForFeatureList(sfp, faap->afgp->feature_list)) return;
4987
4988 gapped_bioseq = BioseqFind (SeqLocId (sfp->location));
4989
4990 LocationContainsGaps (sfp->location, gapped_bioseq, faap->afgp->unknown_gaps, faap->afgp->known_gaps, &terminal_gaps, &internal_gaps, &entirely_in_gap);
4991 if (entirely_in_gap)
4992 {
4993 ValNodeAddPointer (&(faap->features_in_gap), OBJ_SEQFEAT, sfp);
4994 }
4995
4996 if (internal_gaps)
4997 {
4998 ValNodeAddPointer (&(faap->features_contain_gap), OBJ_SEQFEAT, sfp);
4999 }
5000
5001 if ((faap->afgp->split_internal && internal_gaps)
5002 || (faap->afgp->trim_ends && terminal_gaps))
5003 {
5004 ValNodeAddPointer (&(faap->features_to_adjust), OBJ_SEQFEAT, sfp);
5005 }
5006 }
5007
5008
5009 static void AdjustFeaturesForGapsChangeNotify (Pointer data)
5010 {
5011 AdjustFeatForGapFormPtr dlg;
5012 FeatForAdjustData ffad;
5013 ValNodePtr err_list;
5014 SeqEntryPtr sep;
5015 ClickableItemPtr cip;
5016
5017 dlg = (AdjustFeatForGapFormPtr) data;
5018
5019 if (dlg == NULL) return;
5020
5021 err_list = TestDialog (dlg->dlg);
5022 if (err_list == NULL)
5023 {
5024 Enable (dlg->accept_btn);
5025 }
5026 else
5027 {
5028 err_list = ValNodeFree (err_list);
5029 Disable (dlg->accept_btn);
5030 }
5031
5032 /* clear clickable list display */
5033 PointerToDialog (dlg->clickable_list, NULL);
5034 /* re-create list of features */
5035 dlg->feat_list = FreeClickableList (dlg->feat_list);
5036
5037 ffad.afgp = DialogToPointer (dlg->dlg);
5038 ffad.features_contain_gap = NULL;
5039 ffad.features_in_gap = NULL;
5040 ffad.features_to_adjust = NULL;
5041
5042 if (ffad.afgp->feature_list != NULL)
5043 {
5044 sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
5045 VisitFeaturesInSep (sep, &(ffad), FindFeaturesToBeAdjustedForGapsCallback);
5046 }
5047
5048 if (ffad.features_to_adjust != NULL) {
5049 cip = NewClickableItem (0, "%d features will be adjusted", ffad.features_to_adjust);
5050 ValNodeAddPointer (&(dlg->feat_list), 0, cip);
5051 }
5052 if (ffad.features_in_gap != NULL) {
5053 cip = NewClickableItem (0, "%d features are completely contained in gaps and will be deleted", ffad.features_in_gap);
5054 ValNodeAddPointer (&(dlg->feat_list), 0, cip);
5055 }
5056 if (ffad.features_contain_gap != NULL) {
5057 cip = NewClickableItem (0, "%d features contain internal gaps", ffad.features_contain_gap);
5058 ValNodeAddPointer (&(dlg->feat_list), 0, cip);
5059 }
5060
5061 /* pass list of features to clickable list display */
5062 PointerToDialog (dlg->clickable_list, dlg->feat_list);
5063
5064 }
5065
5066
5067 static void DoAdjustFeaturesForGaps (ButtoN b)
5068 {
5069 AdjustFeatForGapFormPtr dlg;
5070 AdjustFeatForGapPtr data;
5071 SeqEntryPtr sep;
5072
5073 dlg = (AdjustFeatForGapFormPtr) GetObjectExtra (b);
5074
5075 if (dlg == NULL) return;
5076
5077 data = (AdjustFeatForGapPtr) DialogToPointer (dlg->dlg);
5078
5079 sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
5080 VisitFeaturesInSep (sep, data, AdjustFeatureForGapsCallback);
5081
5082 /* remove features entirely in the gap */
5083 MarkFeaturesInGapsForDeletion (data);
5084 DeleteMarkedObjects (dlg->input_entityID, 0, NULL);
5085 RenormalizeNucProtSets (sep, TRUE);
5086
5087 ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
5088 ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
5089
5090 data = AdjustFeatForGapFree(data);
5091
5092 Remove (dlg->form);
5093 }
5094
5095
5096 static void MakeGapFeatureReport (ButtoN b)
5097 {
5098 FILE *fp;
5099 Char path [PATH_MAX];
5100 AdjustFeatForGapFormPtr dlg;
5101 Int4 num_disc = 0;
5102 Boolean show_all = FALSE;
5103
5104
5105 dlg = (AdjustFeatForGapFormPtr) GetObjectExtra (b);
5106
5107 if (dlg == NULL) return;
5108
5109 num_disc = CountChosenDiscrepancies (dlg->feat_list, FALSE);
5110
5111 if (num_disc == 0)
5112 {
5113 if (ANS_CANCEL == Message (MSG_OKC, "No items selected! Export all?"))
5114 {
5115 return;
5116 }
5117 else
5118 {
5119 show_all = TRUE;
5120 }
5121 }
5122
5123 path [0] = '\0';
5124 if (GetOutputFileName (path, sizeof (path), NULL)) {
5125 #ifdef WIN_MAC
5126 fp = FileOpen (path, "r");
5127 if (fp != NULL) {
5128 FileClose (fp);
5129 } else {
5130 FileCreate (path, "TEXT", "ttxt");
5131 }
5132 #endif
5133 fp = FileOpen (path, "w");
5134 if (fp != NULL) {
5135 WriteClickableListReport (fp, dlg->feat_list, show_all, FALSE);
5136 FileClose (fp);
5137 return;
5138 }
5139 }
5140 }
5141
5142
5143 extern void AdjustFeaturesForGaps (IteM i)
5144 {
5145 BaseFormPtr bfp;
5146 AdjustFeatForGapFormPtr dlg;
5147 WindoW w;
5148 GrouP h, c;
5149 ButtoN b;
5150
5151 #ifdef WIN_MAC
5152 bfp = currentFormDataPtr;
5153 #else
5154 bfp = GetObjectExtra (i);
5155 #endif
5156 if (bfp == NULL) return;
5157
5158 dlg = (AdjustFeatForGapFormPtr) MemNew (sizeof (AdjustFeatforGapFormData));
5159 if (dlg == NULL) return;
5160
5161 w = FixedWindow (-50, -33, -10, -10, "Adjust Features for Gaps", StdCloseWindowProc);
5162 SetObjectExtra (w, dlg, StdCleanupFormProc);
5163 dlg->form = (ForM) w;
5164 dlg->input_entityID = bfp->input_entityID;
5165 h = HiddenGroup (w, -1, 0, NULL);
5166 SetGroupSpacing (h, 10, 10);
5167
5168 dlg->clickable_list = CreateClickableListDialogEx (h, "", "Features", NULL, NULL,
5169 ScrollToDiscrepancyItem, EditDiscrepancyItem, NULL,
5170 GetDiscrepancyItemText,
5171 stdCharWidth * 15,
5172 stdCharWidth * 30,
5173 TRUE, TRUE);
5174
5175 dlg->dlg = AdjustFeaturesForGapDialog (h, bfp->input_entityID, AdjustFeaturesForGapsChangeNotify, dlg);
5176
5177 c = HiddenGroup (h, 3, 0, NULL);
5178 SetGroupSpacing (c, 10, 10);
5179 dlg->accept_btn = PushButton (c, "Accept", DoAdjustFeaturesForGaps);
5180 SetObjectExtra (dlg->accept_btn, dlg, NULL);
5181 PushButton (c, "Cancel", StdCancelButtonProc);
5182 b = PushButton (c, "Make Report", MakeGapFeatureReport);
5183 SetObjectExtra (b, dlg, NULL);
5184 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->clickable_list,
5185 (HANDLE) dlg->dlg,
5186 (HANDLE) c,
5187 NULL);
5188 RealizeWindow (w);
5189 AdjustFeaturesForGapsChangeNotify (dlg);
5190 Show (w);
5191 Select (w);
5192 }
5193
5194
5195 static ValNodePtr GapLocationsFromNs (BioseqPtr bsp, Int4Ptr gap_sizes)
5196
5197 {
5198 CharPtr bases, txt;
5199 Char ch;
5200 Int4 len;
5201 ValNodePtr seq_ext;
5202 Boolean unknown_greater_than_or_equal = FALSE;
5203 Boolean known_greater_than_or_equal = FALSE;
5204 Int4 unknown_gap_size = 0;
5205 Int4 known_gap_size = 0;
5206 Int4 gap_len;
5207 Boolean make_unknown_size;
5208 GapLocInfoPtr glip;
5209 ValNodePtr result_list = NULL;
5210 Int4 start_pos = 0;
5211
5212
5213 if (bsp == NULL || bsp->repr != Seq_repr_raw || ISA_aa (bsp->mol))
5214 {
5215 return NULL;
5216 }
5217
5218 if (gap_sizes == NULL)
5219 {
5220 known_greater_than_or_equal = TRUE;
5221 }
5222 else
5223 {
5224 unknown_gap_size = gap_sizes[0];
5225 known_gap_size = gap_sizes[1];
5226 if (unknown_gap_size < 0)
5227 {
5228 unknown_greater_than_or_equal = TRUE;
5229 unknown_gap_size = 0 - unknown_gap_size;
5230 }
5231 if (known_gap_size < 0)
5232 {
5233 known_greater_than_or_equal = TRUE;
5234 known_gap_size = 0 - known_gap_size;
5235 }
5236 }
5237
5238 bases = GetSequenceByBsp (bsp);
5239 if (bases == NULL) return NULL;
5240
5241 for (txt = bases, ch = *txt; ch != '\0'; txt++, ch = *txt) {
5242 if (ch == 'N') break;
5243 }
5244 if (ch != 'N') {
5245 MemFree (bases);
5246 return NULL;
5247 }
5248
5249 seq_ext = NULL;
5250 len = 0;
5251
5252 txt = bases;
5253 ch = *txt;
5254
5255 gap_len = 0;
5256 while (ch != '\0') {
5257
5258 if (ch == 'N') {
5259 gap_len = StringSpn (txt, "N");
5260 if (gap_len == unknown_gap_size
5261 || (gap_len > unknown_gap_size && unknown_greater_than_or_equal)
5262 || gap_len == known_gap_size
5263 || (gap_len > known_gap_size && known_greater_than_or_equal))
5264 {
5265 make_unknown_size = FALSE;
5266 if (gap_len == 0)
5267 {
5268 make_unknown_size = FALSE;
5269 }
5270 else if (gap_len == unknown_gap_size)
5271 {
5272 make_unknown_size = TRUE;
5273 }
5274 else if (gap_len == known_gap_size)
5275 {
5276 make_unknown_size = FALSE;
5277 }
5278 else if (gap_len > unknown_gap_size && unknown_greater_than_or_equal)
5279 {
5280 if (!known_greater_than_or_equal)
5281 {
5282 make_unknown_size = TRUE;
5283 }
5284 else if (unknown_gap_size > known_gap_size)
5285 {
5286 make_unknown_size = TRUE;
5287 }
5288 else if (gap_len < known_gap_size)
5289 {
5290 make_unknown_size = TRUE;
5291 }
5292 }
5293
5294 /* Add Location to List */
5295 glip = (GapLocInfoPtr) MemNew (sizeof (GapLocInfoData));
5296 if (glip != NULL)
5297 {
5298 glip->start_pos = start_pos;
5299 glip->is_known = ! make_unknown_size;
5300 glip->length = gap_len;
5301 glip->replace = TRUE;
5302 ValNodeAddPointer (&result_list, 0, glip);
5303 }
5304 }
5305 txt += gap_len;
5306 start_pos += gap_len;
5307 ch = *txt;
5308 gap_len = 0;
5309 } else {
5310 gap_len = StringCSpn (txt, "N");
5311 txt+=gap_len;
5312 start_pos += gap_len;
5313 ch = *txt;
5314 gap_len = 0;
5315 }
5316 }
5317
5318 MemFree (bases);
5319 return result_list;
5320 }
5321
5322 static SeqLocPtr
5323 RemoveGapLocationsFromSeqLoc
5324 (SeqLocPtr slp,
5325 ValNodePtr gap_locs,
5326 BioseqPtr bsp,
5327 BoolPtr loc_changed)
5328 {
5329 ValNodePtr gap_vnp;
5330 GapLocInfoPtr glip;
5331 SeqLocPtr loc_list = NULL, prev_loc = NULL;
5332 SeqIdPtr sip, before_sip, after_sip;
5333 Boolean changed, partial5, partial3;
5334 SeqLocPtr before = NULL, after = NULL;
5335
5336 if (loc_changed != NULL)
5337 {
5338 *loc_changed = FALSE;
5339 }
5340
5341 if (slp == NULL || gap_locs == NULL || bsp == NULL)
5342 {
5343 return slp;
5344 }
5345
5346 sip = SeqLocId (slp);
5347 if (sip == NULL)
5348 {
5349 return slp;
5350 }
5351
5352 CheckSeqLocForPartial (slp, &partial5, &partial3);
5353
5354 before = SeqLocCopy (slp);
5355 loc_list = before;
5356
5357 for (gap_vnp = gap_locs;
5358 gap_vnp != NULL;
5359 gap_vnp = gap_vnp->next)
5360 {
5361 glip = (GapLocInfoPtr) gap_vnp->data.ptrvalue;
5362 if (glip == NULL || glip->is_known)
5363 {
5364 continue;
5365 }
5366 if (GapInLocation (glip->start_pos, glip->length, before))
5367 {
5368 if (loc_changed != NULL)
5369 {
5370 *loc_changed = TRUE;
5371 }
5372 /* we make a copy of the original location */
5373 after = SeqLocCopy (before);
5374
5375 /* note - we need to use duplicates of the SeqID returned by
5376 * SeqLocId, just in case the first location in a mixed location
5377 * is deleted, which would free the result from SeqLocId
5378 */
5379 after_sip = SeqIdDup (SeqLocId (after));
5380 before_sip = SeqIdDup (SeqLocId (before));
5381 /* in the "after" location, we free everything before the
5382 * end of the gap.
5383 */
5384 after = SeqLocDeleteEx (after, after_sip,
5385 0, glip->start_pos + glip->length - 1,
5386 FALSE, &changed, &partial5, &partial3);
5387
5388 /* in the "before" location, we free everything after the
5389 * beginning of the gap.
5390 */
5391 before = SeqLocDeleteEx (before, before_sip,
5392 glip->start_pos, bsp->length,
5393 FALSE, &changed, &partial5, &partial3);
5394
5395 /* we're done with these IDs now */
5396 after_sip = SeqIdFree (after_sip);
5397 before_sip = SeqIdFree (before_sip);
5398
5399 if (before == NULL)
5400 {
5401 if (prev_loc == NULL)
5402 {
5403 loc_list = after;
5404 }
5405 else
5406 {
5407 prev_loc->next = after;
5408 }
5409 }
5410 else
5411 {
5412 before->next = after;
5413 prev_loc = before;
5414 }
5415 before = after;
5416 }
5417 }
5418
5419 slp = SeqLocFree (slp);
5420 return loc_list;
5421 }
5422
5423
5424 static void AdjustCodingRegionLocationsForGapLocations (BioseqPtr bsp, ValNodePtr gap_list)
5425 {
5426 SeqFeatPtr sfp;
5427 SeqMgrFeatContext fcontext;
5428 BioseqPtr protbsp = NULL, new_protbsp = NULL;
5429 SeqFeatPtr new_sfp;
5430 CdRegionPtr crp;
5431 Boolean partial5, partial3;
5432 Uint2 entityID;
5433 Boolean loc_changed;
5434
5435 if (bsp == NULL || gap_list == NULL)
5436 {
5437 return;
5438 }
5439
5440 entityID = bsp->idx.entityID;
5441
5442 for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &fcontext);
5443 sfp != NULL;
5444 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &fcontext))
5445 {
5446 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
5447 loc_changed = FALSE;
5448 sfp->location = RemoveGapLocationsFromSeqLoc (sfp->location, gap_list, bsp, &loc_changed);
5449 if (!loc_changed) {
5450 continue;
5451 }
5452 if (loc_changed)
5453 {
5454 AddCDSGapComment (sfp);
5455 }
5456
5457 while (sfp->location->next != NULL)
5458 {
5459 new_sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_CDREGION, NULL);
5460 if (new_sfp != NULL)
5461 {
5462 /* create copy of coding region data */
5463 crp = (CdRegionPtr) AsnIoMemCopy ((CdRegionPtr) sfp->data.value.ptrvalue,
5464 (AsnReadFunc) CdRegionAsnRead,
5465 (AsnWriteFunc) CdRegionAsnWrite);
5466 new_sfp->data.value.ptrvalue = crp;
5467 new_sfp->location = sfp->location->next;
5468 new_sfp->comment = StringSave (sfp->comment);
5469
5470 protbsp = BioseqFindFromSeqLoc (sfp->product);
5471 if (protbsp != NULL)
5472 {
5473 new_protbsp = AddProteinSequenceCopy (protbsp, bsp, new_sfp, entityID);
5474 }
5475
5476 /* still to do:
5477 * adjust frame to match prior protein
5478 */
5479
5480 sfp->location->next = NULL;
5481
5482 /* fix partials */
5483 SetSeqLocPartial (sfp->location, partial5, TRUE);
5484 sfp->partial = TRUE;
5485
5486 /* adjust frame */
5487 AdjustFrame (sfp, protbsp);
5488
5489 /* retranslate coding region */
5490 SeqEdTranslateOneCDS (sfp, bsp, entityID, Sequin_GlobalAlign2Seq);
5491
5492 /* set partials on product */
5493 if (protbsp == NULL)
5494 {
5495 protbsp = BioseqFindFromSeqLoc (sfp->product);
5496 }
5497 SetProductSequencePartials (protbsp, partial5, partial3);
5498
5499 partial5 = TRUE;
5500 sfp = new_sfp;
5501 protbsp = new_protbsp;
5502 }
5503 else
5504 {
5505 return; /* bail */
5506 }
5507 }
5508 /* fix partials for last feature */
5509 SetSeqLocPartial (sfp->location, partial5, partial3);
5510 sfp->partial = partial5 || partial3;
5511
5512 /* adjust frame */
5513 AdjustFrame (sfp, protbsp);
5514
5515 /* retranslate coding region */
5516 SeqEdTranslateOneCDS (sfp, bsp, entityID, Sequin_GlobalAlign2Seq);
5517 /* set partials on product */
5518 if (protbsp == NULL)
5519 {
5520 protbsp = BioseqFindFromSeqLoc (sfp->product);
5521 }
5522 SetProductSequencePartials (protbsp, partial5, partial3);
5523 }
5524 }
5525
5526 extern void
5527 PrepareCodingRegionLocationsForDeltaConversionCallback
5528 (BioseqPtr bsp, Pointer userdata)
5529 {
5530 Int4Ptr gap_sizes;
5531 ValNodePtr gap_locations;
5532
5533 if (bsp == NULL)
5534 {
5535 return;
5536 }
5537
5538 gap_sizes = (Int4Ptr) userdata;
5539
5540 gap_locations = GapLocationsFromNs (bsp, gap_sizes);
5541
5542 AdjustCodingRegionLocationsForGapLocations (bsp, gap_locations);
5543
5544 gap_locations = ValNodeFreeData (gap_locations);
5545 }
5546
5547 static Int4
5548 CalculateGapCoverage
5549 (BioseqPtr bsp,
5550 SeqLocPtr slp,
5551 SeqMgrFeatContext context,
5552 Boolean include_terminal_gaps)
5553 {
5554 DeltaSeqPtr dsp;
5555 SeqLocPtr loc;
5556 SeqLitPtr slip;
5557 Int4 seq_offset = 0;
5558 Int4 covered = 0;
5559 Int4 k, start, stop;
5560
5561 if (slp == NULL
5562 || bsp == NULL || !ISA_na (bsp->mol)
5563 || bsp->repr != Seq_repr_delta || bsp->seq_ext_type != 4)
5564 {
5565 return 0;
5566 }
5567
5568 dsp = (DeltaSeqPtr) bsp->seq_ext;
5569 while (dsp != NULL && seq_offset < context.right)
5570 {
5571 if (dsp->choice == 1)
5572 {
5573 loc = (SeqLocPtr) dsp->data.ptrvalue;
5574 if (loc != NULL)
5575 {
5576 seq_offset += SeqLocLen (loc);
5577 }
5578 }
5579 else if (dsp->choice == 2)
5580 {
5581 slip = (SeqLitPtr) dsp->data.ptrvalue;
5582 if (slip != NULL)
5583 {
5584 if (IsDeltaSeqKnownGap (dsp) && !DoesDeltaSeqHaveGapTypeOrLinkage(dsp))
5585 {
5586 if (seq_offset <= context.left && seq_offset + slip->length >= context.right)
5587 {
5588 /* gap covers entire location */
5589 return SeqLocLen (slp);
5590 }
5591 else if (include_terminal_gaps ||
5592 (seq_offset > context.left
5593 && seq_offset + slip->length < context.right))
5594 {
5595 /* we only count internal gaps */
5596 for (k = 0; k < context.numivals; k += 2)
5597 {
5598 start = context.ivals [k];
5599 stop = context.ivals [k + 1];
5600 if (seq_offset <= start && seq_offset + slip->length > stop)
5601 {
5602 /* gap covers entire interval */
5603 covered += stop - start;
5604 }
5605 else if (seq_offset > start && seq_offset + slip->length < stop)
5606 {
5607 /* interval covers entire gap */
5608 covered += slip->length;
5609 }
5610 else if (seq_offset < start && seq_offset + slip->length < stop)
5611 {
5612 /* gap covers left end of interval */
5613 covered += seq_offset + slip->length - start;
5614 }
5615 else if (seq_offset > start && seq_offset + slip->length > stop)
5616 {
5617 /* gap covers right end of interval */
5618 covered += stop - seq_offset;
5619 }
5620 }
5621 }
5622 }
5623 seq_offset += slip->length;
5624 }
5625 }
5626 dsp = dsp->next;
5627 }
5628
5629 return covered;
5630
5631 }
5632
5633 static SeqLocPtr
5634 RemoveTerminalGapsFromLocation
5635 (BioseqPtr bsp,
5636 SeqLocPtr slp,
5637 SeqMgrFeatContext context)
5638 {
5639 DeltaSeqPtr dsp;
5640 SeqLocPtr loc, slp_copy;
5641 SeqLitPtr slip;
5642 Int4 seq_offset = 0;
5643 SeqIdPtr sip;
5644 Boolean changed = FALSE, partial5, partial3;
5645
5646 if (slp == NULL)
5647 {
5648 return NULL;
5649 }
5650
5651 CheckSeqLocForPartial (slp, &partial5, &partial3);
5652
5653 slp_copy = (SeqLocPtr) AsnIoMemCopy (slp,
5654 (AsnReadFunc) SeqLocAsnRead,
5655 (AsnWriteFunc) SeqLocAsnWrite);
5656 if (bsp == NULL || !ISA_na (bsp->mol)
5657 || bsp->repr != Seq_repr_delta || bsp->seq_ext_type != 4)
5658 {
5659 return slp_copy;
5660 }
5661
5662 dsp = (DeltaSeqPtr) bsp->seq_ext;
5663 while (dsp != NULL && seq_offset < context.right && slp_copy != NULL)
5664 {
5665 if (dsp->choice == 1)
5666 {
5667 loc = (SeqLocPtr) dsp->data.ptrvalue;
5668 if (loc != NULL)
5669 {
5670 seq_offset += SeqLocLen (loc);
5671 }
5672 }
5673 else if (dsp->choice == 2)
5674 {
5675 slip = (SeqLitPtr) dsp->data.ptrvalue;
5676 if (slip != NULL)
5677 {
5678 if (IsDeltaSeqKnownGap (dsp) && !DoesDeltaSeqHaveGapTypeOrLinkage(dsp))
5679 {
5680 if (seq_offset <= context.left && seq_offset + slip->length >= context.right)
5681 {
5682 slp_copy = SeqLocFree (slp_copy);
5683 }
5684 else if (seq_offset <= context.left && seq_offset + slip->length >= context.left)
5685 {
5686 sip = SeqIdDup (SeqLocId (slp_copy));
5687 slp_copy = SeqLocDeleteEx (slp_copy, sip,
5688 context.left, seq_offset + slip->length - 1,
5689 FALSE, &changed, &partial5, &partial3);
5690 sip = SeqIdFree (sip);
5691
5692 }
5693
5694 if (seq_offset <= context.right && seq_offset + slip->length >= context.right)
5695 {
5696 sip = SeqIdDup (SeqLocId (slp_copy));
5697 slp_copy = SeqLocDeleteEx (slp_copy, sip,
5698 seq_offset, context.right,
5699 FALSE, &changed, &partial5, &partial3);
5700 sip = SeqIdFree (sip);
5701 }
5702 }
5703 seq_offset += slip->length;
5704 }
5705 }
5706 dsp = dsp->next;
5707 }
5708
5709 if (slp_copy != NULL)
5710 {
5711 SetSeqLocPartial (slp_copy, partial5, partial3);
5712 }
5713
5714 return slp_copy;
5715 }
5716
5717 static void
5718 AdjustOneCodingRegionWithTerminalGapsOnBioseq
5719 (BioseqPtr bsp,
5720 SeqFeatPtr sfp,
5721 SeqMgrFeatContext context)
5722 {
5723 SeqLocPtr adjusted_loc;
5724 Int4 loc_len, adjusted_len;
5725 Boolean partial5, partial3;
5726 BioseqPtr protbsp;
5727 SeqFeatPtr gene_sfp;
5728 SeqMgrFeatContext gene_context;
5729
5730 if (bsp == NULL || !ISA_na (bsp->mol)
5731 || bsp->repr != Seq_repr_delta || bsp->seq_ext_type != 4
5732 || sfp == NULL
5733 || (sfp->data.choice != SEQFEAT_CDREGION && sfp->idx.subtype != FEATDEF_mRNA))
5734 {
5735 return;
5736 }
5737
5738 loc_len = SeqLocLen (sfp->location);
5739
5740 adjusted_loc = RemoveTerminalGapsFromLocation (bsp, sfp->location, context);
5741 adjusted_len = SeqLocLen (adjusted_loc);
5742 if (adjusted_loc != NULL && adjusted_len < loc_len)
5743 {
5744 gene_sfp = SeqMgrGetOverlappingGene (sfp->location, &gene_context);
5745 if (gene_sfp != NULL
5746 && SeqLocCompare (gene_sfp->location, sfp->location) == SLC_A_EQ_B)
5747 {
5748 gene_sfp->location = SeqLocFree (gene_sfp->location);
5749 gene_sfp->location = (SeqLocPtr) AsnIoMemCopy (adjusted_loc,
5750 (AsnReadFunc) SeqLocAsnRead,
5751 (AsnWriteFunc) SeqLocAsnWrite);
5752 }
5753
5754 sfp->location = SeqLocFree (sfp->location);
5755 sfp->location = adjusted_loc;
5756 adjusted_loc = NULL;
5757 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
5758 sfp->partial = partial5 || partial3;
5759
5760 protbsp = BioseqFindFromSeqLoc (sfp->product);
5761
5762 if (sfp->data.choice == SEQFEAT_CDREGION)
5763 {
5764 /* adjust frame */
5765 AdjustFrame (sfp, protbsp);
5766
5767 /* retranslate coding region */
5768 SeqEdTranslateOneCDS (sfp, bsp, sfp->idx.entityID, Sequin_GlobalAlign2Seq);
5769
5770 /* set partials on product */
5771 SetProductSequencePartials (protbsp, partial5, partial3);
5772 }
5773 }
5774
5775 adjusted_loc = SeqLocFree (adjusted_loc);
5776
5777 }
5778
5779 static void AdjustCodingRegionsEndingInGapOnBioseq (BioseqPtr bsp, Pointer userdata)
5780 {
5781 SeqMgrFeatContext context;
5782 SeqFeatPtr sfp;
5783
5784 if (bsp == NULL || !ISA_na (bsp->mol)
5785 || bsp->repr != Seq_repr_delta || bsp->seq_ext_type != 4)
5786 {
5787 return;
5788 }
5789
5790 for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &context);
5791 sfp != NULL;
5792 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &context))
5793 {
5794 AdjustOneCodingRegionWithTerminalGapsOnBioseq (bsp, sfp, context);
5795 }
5796 for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_RNA, FEATDEF_mRNA, &context);
5797 sfp != NULL;
5798 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_RNA, FEATDEF_mRNA, &context))
5799 {
5800 AdjustOneCodingRegionWithTerminalGapsOnBioseq (bsp, sfp, context);
5801 }
5802 }
5803
5804 extern void AdjustCodingRegionsEndingInGap (IteM i)
5805 {
5806 BaseFormPtr bfp;
5807 SeqEntryPtr sep;
5808
5809 #ifdef WIN_MAC
5810 bfp = currentFormDataPtr;
5811 #else
5812 bfp = GetObjectExtra (i);
5813 #endif
5814 if (bfp == NULL) return;
5815 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5816 if (sep == NULL) return;
5817
5818 VisitBioseqsInSep (sep, NULL, AdjustCodingRegionsEndingInGapOnBioseq);
5819 DeleteMarkedObjects (bfp->input_entityID, 0, NULL);
5820 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5821 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5822 }
5823
5824 typedef struct cdstomiscfeatform
5825 {
5826 FEATURE_FORM_BLOCK
5827
5828 GrouP all_or_percent_grp;
5829 DialoG string_constraint_dlg;
5830
5831 Boolean convert_all;
5832 FilterSetPtr fsp;
5833 StringConstraintXPtr scp;
5834 BioseqPtr bsp;
5835 } CDSToMiscFeatFormData, PNTR CDSToMiscFeatFormPtr;
5836
5837 static void ConvertCDSToMiscFeatFeatureCallback (SeqFeatPtr sfp, Pointer userdata, FilterSetPtr fsp)
5838 {
5839 CDSToMiscFeatFormPtr cmffp;
5840 Int4 orig_len, covered_len;
5841 SeqMgrFeatContext context;
5842 SeqEntryPtr oldscope;
5843 CDStoMiscFeatData cmfd;
5844
5845 cmffp = (CDSToMiscFeatFormPtr) userdata;
5846
5847 if (sfp == NULL || cmffp == NULL || cmffp->bsp == NULL)
5848 {
5849 return;
5850 }
5851
5852 sfp = SeqMgrGetDesiredFeature (sfp->idx.entityID, cmffp->bsp, sfp->idx.itemID, 0, sfp, &context);
5853 if (sfp == NULL)
5854 {
5855 return;
5856 }
5857
5858 oldscope = SeqEntrySetScope (NULL);
5859
5860 orig_len = SeqLocLen (sfp->location);
5861 covered_len = CalculateGapCoverage (cmffp->bsp, sfp->location, context, cmffp->convert_all);
5862 if (covered_len >= orig_len / 2 || (cmffp->convert_all && covered_len > 0))
5863 {
5864 cmfd.must_have_stops = FALSE;
5865 cmfd.viral = FALSE;
5866 cmfd.opts = NULL;
5867 ConvertCDSToMiscFeat (sfp, &cmfd);
5868 }
5869
5870 SeqEntrySetScope (oldscope);
5871 }
5872
5873 static void ConvertGappedCodingRegionsToMiscFeatBioseqCallback (BioseqPtr bsp, Pointer userdata)
5874 {
5875 CDSToMiscFeatFormPtr cmffp;
5876 SeqEntryPtr sep;
5877
5878 if (bsp == NULL || !ISA_na (bsp->mol)
5879 || bsp->repr != Seq_repr_delta || bsp->seq_ext_type != 4
5880 || userdata == NULL)
5881 {
5882 return;
5883 }
5884
5885 sep = SeqMgrGetSeqEntryForData (bsp);
5886
5887 cmffp = (CDSToMiscFeatFormPtr) userdata;
5888 cmffp->bsp = bsp;
5889
5890 OperateOnSeqEntryConstrainedObjects (sep, cmffp->fsp,
5891 ConvertCDSToMiscFeatFeatureCallback,
5892 NULL, SEQFEAT_CDREGION, FEATDEF_CDS, 0, cmffp);
5893
5894 }
5895
5896 static void AcceptCDSToMiscFeat (ButtoN b)
5897 {
5898 CDSToMiscFeatFormPtr cmffp;
5899 SeqEntryPtr sep;
5900
5901 cmffp = (CDSToMiscFeatFormPtr) GetObjectExtra (b);
5902 if (cmffp == NULL)
5903 {
5904 return;
5905 }
5906
5907 if (GetValue (cmffp->all_or_percent_grp) == 2)
5908 {
5909 cmffp->convert_all = TRUE;
5910 }
5911 else
5912 {
5913 cmffp->convert_all = FALSE;
5914 }
5915
5916 cmffp->fsp = FilterSetNew();
5917 cmffp->fsp->scp = DialogToPointer (cmffp->string_constraint_dlg);
5918
5919 sep = GetTopSeqEntryForEntityID (cmffp->input_entityID);
5920 if (sep == NULL) return;
5921
5922 VisitBioseqsInSep (sep, cmffp, ConvertGappedCodingRegionsToMiscFeatBioseqCallback);
5923 DeleteMarkedObjects (cmffp->input_entityID, 0, NULL);
5924 RenormalizeNucProtSets (sep, TRUE);
5925 ObjMgrSetDirtyFlag (cmffp->input_entityID, TRUE);
5926 ObjMgrSendMsg (OM_MSG_UPDATE, cmffp->input_entityID, 0, 0);
5927 Remove (cmffp->form);
5928 }
5929
5930 extern void ConvertCodingRegionsWithInternalKnownGapToMiscFeat (IteM i)
5931 {
5932 BaseFormPtr bfp;
5933 CDSToMiscFeatFormPtr cmffp;
5934 WindoW w;
5935 GrouP h, c;
5936 ButtoN b;
5937
5938 #ifdef WIN_MAC
5939 bfp = currentFormDataPtr;
5940 #else
5941 bfp = GetObjectExtra (i);
5942 #endif
5943 if (bfp == NULL) return;
5944
5945 cmffp = (CDSToMiscFeatFormPtr) MemNew (sizeof (CDSToMiscFeatFormData));
5946 if (cmffp == NULL) return;
5947
5948 w = FixedWindow (-50, -33, -10, -10, "Convert Coding Regions With Gaps to Misc_Feat", StdCloseWindowProc);
5949 SetObjectExtra (w, cmffp, StdCleanupFormProc);
5950 cmffp->form = (ForM) w;
5951 cmffp->input_entityID = bfp->input_entityID;
5952 h = HiddenGroup (w, -1, 0, NULL);
5953 SetGroupSpacing (h, 10, 10);
5954
5955 cmffp->all_or_percent_grp = HiddenGroup (h, 0, 2, NULL);
5956 SetGroupSpacing (cmffp->all_or_percent_grp, 10, 10);
5957 RadioButton (cmffp->all_or_percent_grp, "Convert only when internal gap covers 50% or more of the coding region");
5958 RadioButton (cmffp->all_or_percent_grp, "Convert all coding regions with gaps (both terminal and internal)");
5959 SetValue (cmffp->all_or_percent_grp, 1);
5960
5961 cmffp->string_constraint_dlg = StringConstraintDialogX (h, "Where feature text", FALSE);
5962
5963 c = HiddenGroup (h, 2, 0, NULL);
5964 SetGroupSpacing (c, 10, 10);
5965 b = PushButton (c, "Accept", AcceptCDSToMiscFeat);
5966 SetObjectExtra (b, cmffp, NULL);
5967 PushButton (c, "Cancel", StdCancelButtonProc);
5968 AlignObjects (ALIGN_CENTER, (HANDLE) cmffp->all_or_percent_grp,
5969 (HANDLE) cmffp->string_constraint_dlg,
5970 (HANDLE) c,
5971 NULL);
5972 RealizeWindow (w);
5973 Show (w);
5974 Select (w);
5975 }
5976
5977
5978 /*---------------------------------------------------------------------*/
5979 /* */
5980 /* Apply_AddCDS () -- */
5981 /* */
5982 /*---------------------------------------------------------------------*/
5983
5984 static void Apply_AddCDS (Uint2 entityID,
5985 SeqEntryPtr sep,
5986 SeqEntryPtr nsep,
5987 ApplyFormPtr afp,
5988 Boolean suppressDups)
5989 {
5990 ByteStorePtr bs;
5991 BioseqPtr bsp;
5992 Char ch;
5993 CdRegionPtr crp;
5994 RnaRefPtr rrp;
5995 ValNodePtr descr;
5996 Int2 genCode;
5997 Int2 i;
5998 MolInfoPtr mip;
5999 SeqEntryPtr old;
6000 CharPtr prot;
6001 ProtRefPtr prp;
6002 SeqEntryPtr psep;
6003 CharPtr ptr;
6004 SeqFeatPtr sfp;
6005 SeqIdPtr sip;
6006 Char str [128];
6007 ValNodePtr vnp;
6008 SeqEntryPtr parent_sep;
6009 SeqEntryPtr gene_sep;
6010 SeqFeatPtr prot_sfp, mRNA_sfp;
6011
6012 /* If necessary then check for duplication before adding */
6013
6014 if (suppressDups &&
6015 entityID > 0 &&
6016 AlreadyHasFeatOrDesc (sep, SEQFEAT_CDREGION, 0, 0))
6017 return;
6018
6019 /* determine the parent of this sequence (for use when segmented) */
6020 parent_sep = NULL;
6021 if (IS_Bioseq (sep))
6022 {
6023 parent_sep = GetBestTopParentForData (entityID, sep->data.ptrvalue);
6024 }
6025 if (parent_sep == NULL)
6026 {
6027 parent_sep = sep;
6028 }
6029
6030 /*Create a new CDS feature */
6031
6032 genCode = SeqEntryToGeneticCode (parent_sep, NULL, NULL, 0);
6033 crp = CreateNewCdRgn (1, FALSE, genCode);
6034 if (NULL == crp)
6035 return;
6036
6037 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_CDREGION, NULL);
6038
6039 if (NULL == sfp)
6040 return;
6041
6042 sfp->data.value.ptrvalue = (Pointer) crp;
6043
6044 /* set the comment */
6045 if (afp->feature_details_data->featcomment != NULL) {
6046 sfp->comment = StringSave (afp->feature_details_data->featcomment);
6047 }
6048
6049 /* adjust the location of the new feature */
6050 SetApplyFeatureLocation (sfp, afp);
6051
6052 /* Fill in the fields of the new CDS feature */
6053 if (afp->feature_details_data->reading_frame < 1
6054 || afp->feature_details_data->reading_frame > 3)
6055 {
6056 if (!SetBestFrameByLocation (sfp)) {
6057 str [0] = '\0';
6058 if (IS_Bioseq (nsep)) {
6059 bsp = (BioseqPtr) nsep->data.ptrvalue;
6060 if (bsp != NULL) {
6061 sip = SeqIdFindBest (bsp->id, 0);
6062 SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str) - 1);
6063 }
6064 }
6065 (afp->errcount)++;
6066 ValNodeCopyStr (&(afp->ambigList), 0, str);
6067 }
6068 }
6069 else
6070 {
6071 crp->frame = afp->feature_details_data->reading_frame;
6072 }
6073
6074 /* Create corresponding protein sequence data for the CDS */
6075
6076 bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
6077 if (NULL == bs)
6078 return;
6079
6080 prot = BSMerge (bs, NULL);
6081 bs = BSFree (bs);
6082 if (NULL == prot)
6083 return;
6084
6085 ptr = prot;
6086 ch = *ptr;
6087 while (ch != '\0') {
6088 *ptr = TO_UPPER (ch);
6089 ptr++;
6090 ch = *ptr;
6091 }
6092 i = (Int2) StringLen (prot);
6093 if (i > 0 && prot [i - 1] == '*') {
6094 prot [i - 1] = '\0';
6095 }
6096 bs = BSNew (1000);
6097 if (bs != NULL) {
6098 ptr = prot;
6099 BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
6100 }
6101
6102 /* Create the product protein Bioseq */
6103
6104 bsp = BioseqNew ();
6105 if (NULL == bsp)
6106 return;
6107
6108 bsp->repr = Seq_repr_raw;
6109 bsp->mol = Seq_mol_aa;
6110 bsp->seq_data_type = Seq_code_ncbieaa;
6111 bsp->seq_data = (SeqDataPtr) bs;
6112 bsp->length = BSLen (bs);
6113 bs = NULL;
6114 old = SeqEntrySetScope (sep);
6115 bsp->id = MakeNewProteinSeqId (sfp->location, NULL);
6116 SeqMgrAddToBioseqIndex (bsp);
6117 SeqEntrySetScope (old);
6118
6119 /* Create a new SeqEntry for the Prot Bioseq */
6120
6121 psep = SeqEntryNew ();
6122 if (NULL == psep)
6123 return;
6124
6125 psep->choice = 1;
6126 psep->data.ptrvalue = (Pointer) bsp;
6127 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, psep);
6128
6129 /* Add a descriptor to the protein Bioseq */
6130
6131 mip = MolInfoNew ();
6132 if (NULL == mip)
6133 return;
6134
6135 mip->biomol = 8;
6136 mip->tech = 8;
6137 if (afp->noLeft && afp->noRight) {
6138 mip->completeness = 5;
6139 } else if (afp->noLeft) {
6140 mip->completeness = 3;
6141 } else if (afp->noRight) {
6142 mip->completeness = 4;
6143 }
6144 vnp = CreateNewDescriptor (psep, Seq_descr_molinfo);
6145 if (NULL == vnp)
6146 return;
6147
6148 vnp->data.ptrvalue = (Pointer) mip;
6149
6150 /**/
6151
6152 descr = ExtractBioSourceAndPubs (parent_sep);
6153
6154 AddSeqEntryToSeqEntry (parent_sep, psep, TRUE);
6155 nsep = FindNucSeqEntry (parent_sep);
6156 ReplaceBioSourceAndPubs (parent_sep, descr);
6157 SetSeqFeatProduct (sfp, bsp);
6158
6159 /* create a full-length protein feature for the new protein sequence */
6160 if (! StringHasNoText (afp->feature_details_data->protName)
6161 && ! StringHasNoText (afp->feature_details_data->protDesc))
6162 {
6163 prp = CreateNewProtRef (afp->feature_details_data->protName,
6164 afp->feature_details_data->protDesc,
6165 NULL, NULL);
6166 }
6167 else if (!StringHasNoText (afp->feature_details_data->protName))
6168 {
6169 prp = CreateNewProtRef (afp->feature_details_data->protName, NULL, NULL, NULL);
6170 }
6171 else if (!StringHasNoText (afp->feature_details_data->protDesc))
6172 {
6173 prp = CreateNewProtRef (NULL, afp->feature_details_data->protDesc, NULL, NULL);
6174 }
6175 else
6176 {
6177 prp = ProtRefNew ();
6178 }
6179
6180 if (prp != NULL) {
6181 prot_sfp = CreateNewFeature (psep, NULL, SEQFEAT_PROT, NULL);
6182 if (prot_sfp != NULL) {
6183 prot_sfp->data.value.ptrvalue = (Pointer) prp;
6184 SetSeqLocPartial (prot_sfp->location, afp->noLeft, afp->noRight);
6185 prot_sfp->partial = (afp->noLeft || afp->noRight);
6186 }
6187 }
6188
6189 /* after the feature has been created, then adjust it for gaps */
6190 /* Note - this step may result in multiple coding regions being created. */
6191 AdjustCDSLocationsForUnknownGapsCallback (sfp, NULL);
6192
6193 /* if requested, also add mRNA feature */
6194 if (afp->also_add_mRNA_btn != NULL && GetStatus(afp->also_add_mRNA_btn)) {
6195 mRNA_sfp = CreateNewFeature (nsep, NULL, SEQFEAT_RNA, NULL);
6196 rrp = RnaRefNew ();
6197 if (rrp != NULL) {
6198 rrp->type = 2;
6199 if (!StringHasNoText(afp->feature_details_data->protName)) {
6200 rrp->ext.choice = 1;
6201 rrp->ext.value.ptrvalue = StringSave (afp->feature_details_data->protName);
6202 }
6203 }
6204 mRNA_sfp->data.value.ptrvalue = rrp;
6205 SetApplyFeatureLocation (mRNA_sfp, afp);
6206 AdjustCDSLocationsForUnknownGapsCallback (mRNA_sfp, NULL);
6207 }
6208
6209 /* Create a Gene ref feature on the nuc seq or segment */
6210 /* we can only create a feature where the sep->choice is 1 */
6211 if (sep->choice == 1)
6212 {
6213 gene_sep = sep;
6214 }
6215 else
6216 {
6217 gene_sep = nsep;
6218 }
6219
6220 if (! StringHasNoText (afp->feature_details_data->geneName)) {
6221 if (entityID > 0
6222 && suppressDups
6223 && AlreadyHasFeatOrDesc (gene_sep, SEQFEAT_GENE, 0, 0))
6224 {
6225 return;
6226 }
6227
6228 ApplyGene (afp->feature_details_data->geneName, afp, gene_sep, sfp);
6229 }
6230 }
6231
6232 static void CheckTitle (SeqEntryPtr sep, GetSamplePtr gsp)
6233 {
6234 BioseqPtr bsp;
6235 BioseqSetPtr bssp = NULL, part_set;
6236 SeqDescrPtr sdp;
6237
6238 if (sep == NULL || sep->data.ptrvalue == NULL
6239 || gsp == NULL)
6240 {
6241 return;
6242 }
6243
6244 if (IS_Bioseq_set (sep)) {
6245 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6246 if (bssp != NULL
6247 && bssp->_class == BioseqseqSet_class_nuc_prot
6248 && bssp->seq_set != NULL)
6249 {
6250 sep = bssp->seq_set;
6251 }
6252 }
6253
6254 if (IS_Bioseq_set (sep))
6255 {
6256 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6257 if (bssp != NULL
6258 && bssp->_class == BioseqseqSet_class_segset
6259 && bssp->seq_set != NULL)
6260 {
6261 /* first do parts */
6262 if (bssp->seq_set->next != NULL
6263 && IS_Bioseq_set (bssp->seq_set->next)
6264 && bssp->seq_set->next->data.ptrvalue != NULL)
6265 {
6266 part_set = (BioseqSetPtr) bssp->seq_set->next->data.ptrvalue;
6267 if (part_set->_class == BioseqseqSet_class_parts)
6268 {
6269 for (sep = part_set->seq_set; sep != NULL; sep = sep->next)
6270 {
6271 CheckTitle (sep, gsp);
6272 }
6273 }
6274 }
6275
6276 /* now do master */
6277 sep = bssp->seq_set;
6278 }
6279 }
6280
6281 if (!IS_Bioseq (sep))
6282 {
6283 return;
6284 }
6285
6286 bsp = (BioseqPtr) sep->data.ptrvalue;
6287 sdp = bsp->descr;
6288 while (sdp != NULL && sdp->choice != Seq_descr_title)
6289 {
6290 sdp = sdp->next;
6291 }
6292 if (sdp != NULL)
6293 {
6294 gsp->num_found ++;
6295 if (gsp->sample_text == NULL)
6296 {
6297 gsp->sample_text = StringSave (sdp->data.ptrvalue);
6298 }
6299 else if (StringCmp (gsp->sample_text, sdp->data.ptrvalue) != 0)
6300 {
6301 gsp->all_same = FALSE;
6302 }
6303 }
6304
6305
6306 }
6307
6308 static void ApplyOneTitle (SeqEntryPtr sep, ExistingTextPtr etp, CharPtr defline)
6309 {
6310 BioseqPtr bsp;
6311 BioseqSetPtr bssp, part_set;
6312 SeqDescrPtr sdp;
6313
6314 if (sep == NULL || sep->data.ptrvalue == NULL
6315 || StringHasNoText (defline))
6316 {
6317 return;
6318 }
6319
6320 if (IS_Bioseq_set (sep)) {
6321 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6322 if (bssp != NULL
6323 && bssp->_class == BioseqseqSet_class_nuc_prot
6324 && bssp->seq_set != NULL)
6325 {
6326 sep = bssp->seq_set;
6327 }
6328 }
6329
6330 if (IS_Bioseq_set (sep))
6331 {
6332 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6333 if (bssp != NULL
6334 && bssp->_class == BioseqseqSet_class_segset
6335 && bssp->seq_set != NULL)
6336 {
6337 /* first do parts */
6338 if (bssp->seq_set->next != NULL
6339 && IS_Bioseq_set (bssp->seq_set->next)
6340 && bssp->seq_set->next->data.ptrvalue != NULL)
6341 {
6342 part_set = (BioseqSetPtr) bssp->seq_set->next->data.ptrvalue;
6343 if (part_set->_class == BioseqseqSet_class_parts)
6344 {
6345 for (sep = part_set->seq_set; sep != NULL; sep = sep->next)
6346 {
6347 ApplyOneTitle (sep, etp, defline);
6348 }
6349 }
6350 }
6351
6352 /* now do master */
6353 sep = bssp->seq_set;
6354 }
6355 }
6356
6357 if (!IS_Bioseq (sep))
6358 {
6359 return;
6360 }
6361
6362 bsp = (BioseqPtr) sep->data.ptrvalue;
6363 sdp = bsp->descr;
6364 while (sdp != NULL && sdp->choice != Seq_descr_title)
6365 {
6366 sdp = sdp->next;
6367 }
6368
6369 if (sdp == NULL)
6370 {
6371 sdp = CreateNewDescriptor (sep, Seq_descr_title);
6372 }
6373
6374 if (sdp != NULL) {
6375 sdp->data.ptrvalue = HandleExistingText (sdp->data.ptrvalue,
6376 StringSave (defline), etp);
6377 }
6378
6379 }
6380
6381 /*---------------------------------------------------------------------*/
6382 /* */
6383 /* RealApplyBioFeatToAll () -- */
6384 /* */
6385 /*---------------------------------------------------------------------*/
6386
6387 static void RealApplyBioFeatToAll (Uint2 entityID,
6388 SeqEntryPtr sep,
6389 SeqEntryPtr nsep,
6390 ApplyFormPtr afp,
6391 Boolean suppressDups)
6392
6393 {
6394 ImpFeatPtr ifp;
6395 SeqFeatPtr sfp = NULL;
6396 SeqFeatPtr gene_sfp;
6397 Boolean put_comment_on_gene = FALSE;
6398
6399 /* Check parameters */
6400
6401 if (sep == NULL || nsep == NULL || afp == NULL)
6402 return;
6403
6404 /* Add a title feature */
6405
6406 if (afp->type == CHECK_TITLE)
6407 {
6408 CheckTitle (sep, afp->gsp);
6409 return;
6410 }
6411 else if (afp->type == ADD_TITLE)
6412 {
6413 if (entityID == 0 && SeqEntryGetTitle (sep) != NULL)
6414 {
6415 return;
6416 }
6417 ApplyOneTitle (sep, afp->etp, afp->feature_details_data->defline);
6418 return;
6419 }
6420
6421 /* Add a CDS feature */
6422
6423 else if (afp->type == ADD_CDS)
6424 Apply_AddCDS (entityID, sep, nsep, afp, suppressDups);
6425
6426 /* Add an rRNA feature */
6427
6428 else if (afp->type == ADD_RRNA) {
6429 if (suppressDups && entityID > 0
6430 && AlreadyHasRNA (sep, afp->feature_details_data->rnaType)) {
6431 return;
6432 }
6433
6434 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_RNA, NULL);
6435 ApplyRnaTypeToSeqFeat (sfp, afp->feature_details_data->rnaType);
6436 if (! StringHasNoText (afp->feature_details_data->rnaName)) {
6437 ApplyProductToRNA (sfp, afp->feature_details_data->rnaName);
6438 }
6439
6440 SetApplyFeatureLocation (sfp, afp);
6441 AddToComment (sfp, afp->feature_details_data->featcomment);
6442
6443 if (! StringHasNoText (afp->feature_details_data->geneName)) {
6444 if (entityID > 0
6445 && suppressDups
6446 && AlreadyHasFeatOrDesc (sep, SEQFEAT_GENE, 0, 0))
6447 {
6448 return;
6449 }
6450 ApplyGene (afp->feature_details_data->geneName, afp, nsep, sfp);
6451
6452 }
6453 }
6454
6455 /* Add an Import feature */
6456
6457 else if (afp->type == ADD_IMP) {
6458 if (afp->feature_details_data->featdef_choice == FEATDEF_GENE)
6459 {
6460 put_comment_on_gene = TRUE;
6461 }
6462 else
6463 {
6464 ifp = ImpFeatNew ();
6465 if (ifp != NULL) {
6466 ifp->key = StringSave (afp->feature_details_data->featdef_name);
6467 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_IMP, NULL);
6468 if (sfp != NULL) {
6469 sfp->data.value.ptrvalue = (Pointer) ifp;
6470 SetApplyFeatureLocation (sfp, afp);
6471 if (! StringHasNoText (afp->feature_details_data->featcomment))
6472 {
6473 sfp->comment = StringSave (afp->feature_details_data->featcomment);
6474 }
6475 sfp->qual = DialogToPointer (afp->gbquals);
6476 }
6477 }
6478 }
6479 if (! StringHasNoText (afp->feature_details_data->geneName)
6480 || ! StringHasNoText (afp->feature_details_data->geneDesc))
6481 {
6482 if (entityID > 0
6483 && suppressDups
6484 && AlreadyHasFeatOrDesc (sep, SEQFEAT_GENE, 0, 0))
6485 {
6486 return;
6487 }
6488 gene_sfp = ApplyGene (afp->feature_details_data->geneName, afp, nsep, sfp);
6489
6490 if (gene_sfp != NULL && ! StringHasNoText (afp->feature_details_data->featcomment) && put_comment_on_gene)
6491 {
6492 gene_sfp->comment = StringSave (afp->feature_details_data->featcomment);
6493 }
6494 }
6495 }
6496 }
6497
6498 /*---------------------------------------------------------------------*/
6499 /* */
6500 /* ApplyBioFeatToRaw () -- */
6501 /* */
6502 /*---------------------------------------------------------------------*/
6503
6504 static void ApplyBioFeatToRaw (Uint2 entityID,
6505 SeqEntryPtr parentSep,
6506 SeqEntryPtr sep,
6507 ApplyFormPtr afp,
6508 Int2 onlythis)
6509
6510 {
6511 BioseqPtr bsp;
6512 BioseqSetPtr bssp;
6513 Int2 count;
6514 SeqEntryPtr nucSep;
6515
6516 /* Check parameters */
6517
6518 if (sep == NULL || afp == NULL)
6519 return;
6520
6521 /* If it is a set then recurse until we get to the raw Bioseq */
6522
6523 if (IS_Bioseq_set (sep)) {
6524 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6525 if (bssp != NULL) {
6526 if (onlythis != 0 && bssp->_class == BioseqseqSet_class_parts) {
6527 for (sep = bssp->seq_set, count = 1;
6528 sep != NULL && count != onlythis;
6529 sep = sep->next, count++)
6530 continue;
6531 if (sep != NULL) {
6532 ApplyBioFeatToRaw (entityID, parentSep, sep, afp, onlythis);
6533 }
6534 } else {
6535 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
6536 ApplyBioFeatToRaw (entityID, parentSep, sep, afp, onlythis);
6537 }
6538 }
6539 return;
6540 }
6541 }
6542
6543 /* Get the nucleotide Bioseq */
6544
6545 nucSep = FindNucSeqEntry (sep);
6546 if (nucSep == NULL)
6547 return;
6548
6549 bsp = (BioseqPtr) nucSep->data.ptrvalue;
6550 if (bsp == NULL)
6551 return;
6552
6553 /* If we've got a raw Bioseq then do the apply */
6554
6555 if (bsp->repr == Seq_repr_raw) {
6556 RealApplyBioFeatToAll (entityID, nucSep, nucSep, afp, FALSE);
6557 /*
6558 RealApplyBioFeatToAll (entityID, parentSep, nucSep, afp, FALSE);
6559 */
6560 }
6561 }
6562
6563 /*---------------------------------------------------------------------*/
6564 /* */
6565 /* ApplyBioFeatToAll () -- */
6566 /* */
6567 /*---------------------------------------------------------------------*/
6568
6569 static void ApplyBioFeatToAll (Uint2 entityID,
6570 SeqEntryPtr sep,
6571 ApplyFormPtr afp)
6572
6573 {
6574 BioseqSetPtr bssp;
6575 SeqEntryPtr nsep;
6576 Int2 onlythis;
6577 Char str [32];
6578 Boolean suppressDups = FALSE;
6579
6580 /* Check parameters */
6581
6582 if (sep == NULL || afp == NULL)
6583 return;
6584
6585 if (afp->add_to_seq_with_like_feature != NULL)
6586 {
6587 suppressDups = ! GetStatus (afp->add_to_seq_with_like_feature);
6588 }
6589
6590 /* If it is a set then recurse until we get to a Bioseq */
6591
6592 if (IS_Bioseq_set (sep)) {
6593 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6594 if (bssp != NULL) {
6595 if (bssp->_class == BioseqseqSet_class_genbank || IsPopPhyEtcSet (bssp->_class)) {
6596 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
6597 ApplyBioFeatToAll (entityID, sep, afp);
6598 }
6599 return;
6600 } else if (bssp->_class == BioseqseqSet_class_gen_prod_set) {
6601 /* just the first item */
6602 ApplyBioFeatToAll (entityID, bssp->seq_set, afp);
6603 return;
6604 }
6605 }
6606 }
6607
6608 /* Get the nucleotide Bioseq */
6609
6610 nsep = FindNucSeqEntry (sep);
6611 if (nsep == NULL)
6612 return;
6613
6614 /* Apply the feature */
6615
6616 if (afp->applyToParts != NULL && GetStatus (afp->applyToParts)) {
6617 GetTitle (afp->onlyThisPart, str, sizeof (str));
6618 if (! StrToInt (str, &onlythis)) {
6619 onlythis = 0;
6620 }
6621 ApplyBioFeatToRaw (entityID, sep, sep, afp, onlythis);
6622 } else {
6623 RealApplyBioFeatToAll (entityID, sep, nsep, afp, suppressDups);
6624 }
6625 }
6626
6627 /*---------------------------------------------------------------------*/
6628 /* */
6629 /* ApplyBioFeatToAll () -- */
6630 /* */
6631 /*---------------------------------------------------------------------*/
6632
6633 static void ApplyBioFeatToList (Uint2 entityID,
6634 SeqEntryPtr sep,
6635 ApplyFormPtr afp,
6636 ValNodePtr id_list)
6637
6638 {
6639 BioseqPtr bsp;
6640 SeqEntryPtr nsep, oldscope;
6641 Int2 onlythis;
6642 Char str [32];
6643 Boolean suppressDups = FALSE;
6644 ValNodePtr vnp;
6645
6646 /* Check parameters */
6647
6648 if (sep == NULL || afp == NULL || id_list == NULL)
6649 return;
6650
6651 if (afp->add_to_seq_with_like_feature != NULL)
6652 {
6653 suppressDups = ! GetStatus (afp->add_to_seq_with_like_feature);
6654 }
6655
6656 oldscope = SeqEntrySetScope (sep);
6657 for (vnp = id_list; vnp != NULL; vnp = vnp->next) {
6658 bsp = BioseqFind (vnp->data.ptrvalue);
6659 if (bsp != NULL) {
6660 sep = SeqMgrGetSeqEntryForData (bsp);
6661
6662 /* Get the nucleotide Bioseq */
6663 nsep = FindNucSeqEntry (sep);
6664 if (nsep == NULL)
6665 continue;
6666
6667 /* Apply the feature */
6668
6669 if (afp->applyToParts != NULL && GetStatus (afp->applyToParts)) {
6670 GetTitle (afp->onlyThisPart, str, sizeof (str));
6671 if (! StrToInt (str, &onlythis)) {
6672 onlythis = 0;
6673 }
6674 ApplyBioFeatToRaw (entityID, sep, sep, afp, onlythis);
6675 } else {
6676 RealApplyBioFeatToAll (entityID, sep, nsep, afp, suppressDups);
6677 }
6678 }
6679 }
6680 }
6681
6682
6683 Int2 ApplyAnnotationToAll (Int2 type, SeqEntryPtr sep,
6684 ButtoN partialLft, ButtoN partialRgt,
6685 TexT geneName, TexT protName,
6686 TexT protDesc, TexT rnaName,
6687 TexT featcomment, TexT defline)
6688
6689 {
6690 ApplyFormData afd;
6691 RnaTypeData rtd;
6692
6693 MemSet ((Pointer) (&afd), 0, sizeof (ApplyFormData));
6694 afd.type = type;
6695 afd.errcount = 0;
6696 afd.ambigList = NULL;
6697 afd.partial5 = partialLft;
6698 afd.partial3 = partialRgt;
6699 afd.noLeft = GetStatus (afd.partial5);
6700 afd.noRight = GetStatus (afd.partial3);
6701 afd.feature_details_data = BatchApplyFeatureDetailsNew ();
6702 if (afd.feature_details_data == NULL)
6703 {
6704 return 1;
6705 }
6706
6707 if (ADD_RRNA == type)
6708 {
6709 rtd.ncrna_class = NULL;
6710 rtd.rna_featdef = FEATDEF_rRNA;
6711 afd.feature_details_data->rnaType = &rtd;
6712 }
6713
6714 if (geneName != NULL && ! TextHasNoText (geneName))
6715 afd.feature_details_data->geneName = SaveStringFromText (geneName);
6716 if (protName != NULL && ! TextHasNoText (protName))
6717 afd.feature_details_data->protName = SaveStringFromText (protName);
6718 if (protDesc != NULL && ! TextHasNoText (protDesc))
6719 afd.feature_details_data->protDesc = SaveStringFromText (protDesc);
6720 if (rnaName != NULL && ! TextHasNoText (rnaName))
6721 afd.feature_details_data->rnaName = SaveStringFromText (rnaName);
6722 if (featcomment != NULL && ! TextHasNoText (featcomment))
6723 afd.feature_details_data->featcomment = SaveStringFromText (featcomment);
6724 if (defline != NULL && ! TextHasNoText (defline))
6725 afd.feature_details_data->defline = SaveStringFromText (defline);
6726 ApplyBioFeatToAll (0, sep, &afd);
6727 if (afd.type == ADD_CDS) {
6728 return afd.errcount;
6729 }
6730 return 0;
6731 }
6732
6733 static void CommonApplyToAllProcBfpInfo (Uint2 entityID,
6734 Uint4 itemID,
6735 Uint2 itemtype,
6736 Int2 type);
6737
6738 static void NowReadyToApplyToAll (ApplyFormPtr afp, DialoG gbquals)
6739
6740 {
6741 Uint2 parenttype;
6742 Pointer parentptr;
6743 CharPtr plural;
6744 SeqEntryPtr sep;
6745 CharPtr tmp;
6746 SeqEntryPtr top;
6747 ValNodePtr vnp;
6748 Char path [PATH_MAX];
6749 FILE *fp;
6750 ValNodePtr id_list = NULL;
6751
6752 if (afp == NULL) return;
6753 afp->gbquals = gbquals;
6754 sep = GetTopSeqEntryForEntityID (afp->input_entityID);
6755 if (sep == NULL) return;
6756 Hide (afp->form);
6757 WatchCursor ();
6758 Update ();
6759 afp->noLeft = GetStatus (afp->partial5);
6760 afp->noRight = GetStatus (afp->partial3);
6761 top = sep;
6762 if (afp->type == ADD_CDS) {
6763 GetSeqEntryParent (top, &parentptr, &parenttype);
6764 }
6765
6766 if (afp->all_or_some_grp != NULL && GetValue (afp->all_or_some_grp) == 2) {
6767 tmp = SaveStringFromText (afp->accession_list_txt);
6768 id_list = ParseAccessionNumberListFromString(tmp, sep);
6769 tmp = MemFree (tmp);
6770 if (id_list == NULL) {
6771 ArrowCursor();
6772 Update();
6773 Show (afp->form);
6774 return;
6775 }
6776 ApplyBioFeatToList (afp->input_entityID, sep, afp, id_list);
6777 id_list = FreeSeqIdList (id_list);
6778 tmp = MemFree (tmp);
6779 } else {
6780 ApplyBioFeatToAll (afp->input_entityID, sep, afp);
6781 }
6782 ArrowCursor ();
6783 Update ();
6784 if (afp->errcount > 0 && afp->type == ADD_CDS) {
6785 TmpNam (path);
6786 fp = FileOpen (path, "w");
6787 if (fp != NULL) {
6788 if (afp->errcount > 1) {
6789 plural = "records";
6790 } else {
6791 plural = "record";
6792 }
6793 fprintf (fp, "Possible ambiguous frames detected in %d %s\n",
6794 (int) afp->errcount, plural);
6795 for (vnp = afp->ambigList; vnp != NULL; vnp = vnp->next) {
6796 tmp = (CharPtr) vnp->data.ptrvalue;
6797 fprintf (fp, "%s\n", tmp);
6798 }
6799 FileClose (fp);
6800 LaunchGeneralTextViewer (path, "Ambiguous Frames");
6801 FileRemove (path);
6802 }
6803 }
6804 ObjMgrSetDirtyFlag (afp->input_entityID, TRUE);
6805 ObjMgrSendMsg (OM_MSG_UPDATE, afp->input_entityID, 0, 0);
6806 if (GetStatus (afp->leaveDlgUp))
6807 {
6808 afp->ambigList = ValNodeFreeData (afp->ambigList);
6809 Show (afp->form);
6810 }
6811 else
6812 {
6813 Remove (afp->form);
6814 }
6815 }
6816
6817 typedef struct qualsform {
6818 FEATURE_FORM_BLOCK
6819
6820 ApplyFormPtr afp;
6821 } QualsForm, PNTR QualsFormPtr;
6822
6823 static void CallNowReady (ButtoN b)
6824
6825 {
6826 QualsFormPtr qfp;
6827
6828 qfp = (QualsFormPtr) GetObjectExtra (b);
6829 if (qfp == NULL) return;
6830 Hide (qfp->form);
6831 NowReadyToApplyToAll (qfp->afp, qfp->gbquals);
6832 Remove (qfp->form);
6833 }
6834
6835
6836 static void DoTheApplyToAllProc (ButtoN b)
6837
6838 {
6839 ApplyFormPtr afp;
6840 CharPtr name;
6841 QualsFormPtr qfp;
6842 WindoW w;
6843
6844 afp = GetObjectExtra (b);
6845 if (afp == NULL) {
6846 Remove (ParentWindow (b));
6847 return;
6848 }
6849
6850 afp->feature_details_data = DialogToPointer (afp->feature_details_dlg);
6851
6852 if (afp->type == ADD_IMP) {
6853 /* if gene, do not collect quals */
6854 if (afp->feature_details_data->featdef_choice != FEATDEF_GENE)
6855 {
6856 qfp = (QualsFormPtr) MemNew (sizeof (QualsForm));
6857 if (qfp != NULL) {
6858 Hide (afp->form);
6859 Update ();
6860 name = afp->feature_details_data->featdef_name;
6861 qfp->afp = afp;
6862 w = FixedWindow (-50, -33, -10, -10, "Qualifiers", StdCloseWindowProc);
6863 SetObjectExtra (w, qfp, StdCleanupFormProc);
6864 qfp->form = (ForM) w;
6865 CreateStandardEditMenu (w);
6866 qfp->gbquals = NewCreateImportFields (w, name, NULL, FALSE);
6867 b = PushButton (w, "Okay", CallNowReady);
6868 SetObjectExtra (b, qfp, NULL);
6869 AlignObjects (ALIGN_CENTER, (HANDLE) qfp->gbquals, (HANDLE) b, NULL);
6870 RealizeWindow (w);
6871 Show (w);
6872 Select (w);
6873 }
6874 } else {
6875 NowReadyToApplyToAll (afp, NULL);
6876 }
6877 }
6878 else if (afp->type == ADD_TITLE)
6879 {
6880 afp->gsp = GetSampleNew ();
6881 afp->type = CHECK_TITLE;
6882 NowReadyToApplyToAll (afp, NULL);
6883 afp->etp = GetExistingTextHandlerInfo (afp->gsp == NULL ? 0 : afp->gsp->num_found, FALSE);
6884 afp->gsp = GetSampleFree (afp->gsp);
6885 afp->type = ADD_TITLE;
6886 if (afp->etp == NULL
6887 || afp->etp->existing_text_choice != eExistingTextChoiceCancel)
6888 {
6889 NowReadyToApplyToAll (afp, NULL);
6890 }
6891 afp->etp = MemFree (afp->etp);
6892 } else {
6893 NowReadyToApplyToAll (afp, NULL);
6894 }
6895 }
6896
6897 static void ApplyToPartsProc (ButtoN b)
6898
6899 {
6900 ApplyFormPtr afp;
6901
6902 afp = (ApplyFormPtr) GetObjectExtra (b);
6903 if (afp == NULL) return;
6904 if (GetStatus (b)) {
6905 SafeEnable (afp->onlyThisPart);
6906 } else {
6907 SafeDisable (afp->onlyThisPart);
6908 }
6909 }
6910
6911 static void LookForParts (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
6912
6913 {
6914 BioseqSetPtr bssp;
6915 BoolPtr rsult;
6916
6917 if (IS_Bioseq_set (sep)) {
6918 bssp = (BioseqSetPtr) sep->data.ptrvalue;
6919 if (bssp != NULL && bssp->_class == BioseqseqSet_class_parts) {
6920 rsult = (BoolPtr) mydata;
6921 if (rsult != NULL) {
6922 *rsult = TRUE;
6923 }
6924 }
6925 }
6926 }
6927
6928 extern Boolean HasPartsSet (SeqEntryPtr sep);
6929 extern Boolean HasPartsSet (SeqEntryPtr sep)
6930
6931 {
6932 Boolean rsult = FALSE;
6933
6934 SeqEntryExplore (sep, (Pointer) (&rsult), LookForParts);
6935 return rsult;
6936 }
6937
6938 static void EnableApplyCdsCoords (GrouP g)
6939 {
6940 ApplyFormPtr afp;
6941
6942 afp = (ApplyFormPtr) GetObjectExtra (g);
6943 if (afp == NULL) return;
6944 if (GetValue (g) == 1)
6945 {
6946 Disable (afp->left_end);
6947 Disable (afp->right_end);
6948 }
6949 else
6950 {
6951 Enable (afp->left_end);
6952 Enable (afp->right_end);
6953 }
6954 }
6955
6956 static void ApplyMessageProc (ForM f, Int2 mssg)
6957
6958 {
6959 ApplyFormPtr afp;
6960
6961 afp = (ApplyFormPtr) GetObjectExtra (f);
6962 if (afp != NULL) {
6963 if (afp->appmessage != NULL) {
6964 afp->appmessage (f, mssg);
6965 }
6966 }
6967 }
6968
6969 static void CleanupApplyToAllForm (GraphiC g, VoidPtr data)
6970
6971 {
6972 ApplyFormPtr afp;
6973
6974 afp = (ApplyFormPtr) data;
6975 if (afp != NULL) {
6976 afp->feature_details_data = BatchApplyFeatureDetailsFree (afp->feature_details_data);
6977 ValNodeFreeData (afp->ambigList);
6978 }
6979 StdCleanupFormProc (g, data);
6980 }
6981
6982 static void ChangeAllOrSome (GrouP g)
6983 {
6984 ApplyFormPtr afp;
6985
6986 afp = (ApplyFormPtr) GetObjectExtra (g);
6987 if (afp != NULL) {
6988 if (GetValue(g) == 1) {
6989 Disable (afp->accession_list_txt);
6990 } else {
6991 Enable (afp->accession_list_txt);
6992 }
6993 }
6994 }
6995
6996
6997 static void EnableApplyFeatureAccept (Pointer data)
6998 {
6999 ApplyFormPtr afp;
7000
7001 afp = (ApplyFormPtr) data;
7002 if (afp == NULL) return;
7003
7004 if (OkToAcceptBatchApplyFeatureDetails (afp->feature_details_dlg))
7005 {
7006 Enable (afp->accept);
7007 }
7008 else
7009 {
7010 Disable (afp->accept);
7011 }
7012 }
7013
7014
7015 static void CommonApplyToAllProcBfpInfo (Uint2 entityID,
7016 Uint4 itemID,
7017 Uint2 itemtype,
7018 Int2 type)
7019 {
7020 ApplyFormPtr afp;
7021 GrouP c;
7022 GrouP g = NULL;
7023 GrouP h;
7024 GrouP r2, r3, r4;
7025 SeqEntryPtr sep;
7026 StdEditorProcsPtr sepp;
7027 WindoW w;
7028 GrouP x;
7029 GrouP parts_group = NULL;
7030 GrouP feature_details = NULL;
7031 GrouP indexer_only_group = NULL;
7032
7033 sep = GetTopSeqEntryForEntityID (entityID);
7034 if (sep == NULL) return;
7035 afp = (ApplyFormPtr) MemNew (sizeof (ApplyFormData));
7036 if (afp == NULL) return;
7037 w = FixedWindow (-50, -33, -10, -10, "Automatic Processing", StdCloseWindowProc);
7038 SetObjectExtra (w, afp, CleanupApplyToAllForm);
7039 afp->form = (ForM) w;
7040 afp->formmessage = ApplyMessageProc;
7041
7042 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
7043 if (sepp != NULL) {
7044 SetActivate (w, sepp->activateForm);
7045 afp->appmessage = sepp->handleMessages;
7046 }
7047
7048 afp->input_entityID = entityID;
7049 afp->input_itemID = itemID;
7050 afp->input_itemtype = itemtype;
7051
7052 h = HiddenGroup (w, -1, 0, NULL);
7053 SetGroupSpacing (h, 10, 10);
7054
7055 afp->type = type;
7056 afp->errcount = 0;
7057
7058 if (HasPartsSet (sep)) {
7059 parts_group = HiddenGroup (h, 1, 0, NULL);
7060 afp->applyToParts = CheckBox (parts_group, "Apply to segmented parts, not segmented sequence", ApplyToPartsProc);
7061 SetObjectExtra (afp->applyToParts, afp, NULL);
7062 x = HiddenGroup (parts_group, 2, 0, NULL);
7063 StaticPrompt (x, "Apply only to particular numbered segment", 0, dialogTextHeight, programFont, 'l');
7064 afp->onlyThisPart = DialogText (x, "", 4, NULL);
7065 Disable (afp->onlyThisPart);
7066 }
7067
7068 afp->strand_group = NULL;
7069 afp->add_to_seq_with_like_feature = NULL;
7070 afp->also_add_mRNA_btn = NULL;
7071
7072 if (type == ADD_CDS || type == ADD_RRNA || type == ADD_IMP) {
7073 /* create group to hold feature details */
7074 feature_details = HiddenGroup (h, -1, 0, NULL);
7075
7076 /* group for feature completeness */
7077 g = HiddenGroup (feature_details, 2, 0, NULL);
7078 afp->partial5 = CheckBox (g, "Incomplete at 5' end", NULL);
7079 afp->partial3 = CheckBox (g, "Incomplete at 3' end", NULL);
7080
7081 /* group for strand */
7082 afp->strand_group = HiddenGroup (feature_details, 2, 0, NULL);
7083 SetObjectExtra (afp->strand_group, afp, NULL);
7084 RadioButton (afp->strand_group, "Plus Strand");
7085 RadioButton (afp->strand_group, "Minus Strand");
7086 SetValue (afp->strand_group, 1);
7087
7088 /* coordinates */
7089 if (indexerVersion)
7090 {
7091 indexer_only_group = HiddenGroup (feature_details, -1, 0, NULL);
7092 r2 = HiddenGroup (indexer_only_group, 5, 0, NULL);
7093 afp->use_whole_interval = HiddenGroup (r2, 0, 2, EnableApplyCdsCoords);
7094 SetObjectExtra (afp->use_whole_interval, afp, NULL);
7095 RadioButton (afp->use_whole_interval, "Use Whole Sequence Interval");
7096 RadioButton (afp->use_whole_interval, "Use these coordinates:");
7097 r3 = HiddenGroup (r2, 0, 2, NULL);
7098 StaticPrompt (r3, "", 0, dialogTextHeight, programFont, 'l');
7099 r4 = HiddenGroup (r3, 4, 0, NULL);
7100 StaticPrompt (r4, "From", 0, dialogTextHeight, programFont, 'l');
7101 afp->left_end = DialogText (r4, "1", 5, NULL);
7102 StaticPrompt (r4, "To", 0, dialogTextHeight, programFont, 'l');
7103 afp->right_end = DialogText (r4, "1", 5, NULL);
7104 SetValue (afp->use_whole_interval, 1);
7105 Disable (afp->left_end);
7106 Disable (afp->right_end);
7107
7108 /* apply to some sequences or all sequences */
7109 afp->all_or_some_grp = HiddenGroup (indexer_only_group, 1, 0, ChangeAllOrSome);
7110 SetObjectExtra (afp->all_or_some_grp, afp, NULL);
7111 RadioButton (afp->all_or_some_grp, "Apply to all sequences");
7112 RadioButton (afp->all_or_some_grp, "Apply to sequences in this list");
7113 afp->accession_list_txt = DialogText (afp->all_or_some_grp, "", 25, NULL);
7114 SetValue (afp->all_or_some_grp, 1);
7115 ChangeAllOrSome(afp->all_or_some_grp);
7116
7117 /* add to features that already have same */
7118 if (type == ADD_CDS)
7119 {
7120 afp->add_to_seq_with_like_feature = CheckBox (indexer_only_group, "Also add to sequences that already have a CDS", NULL);
7121 afp->also_add_mRNA_btn = CheckBox (indexer_only_group, "Also add mRNA", NULL);
7122 SetStatus (afp->also_add_mRNA_btn, FALSE);
7123 }
7124 else if (type == ADD_RRNA)
7125 {
7126 afp->add_to_seq_with_like_feature = CheckBox (indexer_only_group, "Also add to sequences that already have an rRNA", NULL);
7127 }
7128 else if (type == ADD_IMP)
7129 {
7130 afp->add_to_seq_with_like_feature = CheckBox (indexer_only_group, "Also add to sequences that already have this feature", NULL);
7131 }
7132 SafeSetStatus (afp->add_to_seq_with_like_feature, TRUE);
7133 AlignObjects (ALIGN_CENTER, (HANDLE) r2,
7134 (HANDLE) afp->add_to_seq_with_like_feature,
7135 (HANDLE) afp->also_add_mRNA_btn,
7136 NULL);
7137 }
7138 else
7139 {
7140 afp->use_whole_interval = NULL;
7141 afp->all_or_some_grp = NULL;
7142 afp->accession_list_txt = NULL;
7143 }
7144
7145 AlignObjects (ALIGN_CENTER, (HANDLE) g,
7146 (HANDLE) afp->strand_group,
7147 (HANDLE) indexer_only_group,
7148 NULL);
7149 }
7150 afp->feature_details_dlg = BatchApplyFeatureDetailsDialog (h, type, EnableApplyFeatureAccept, afp);
7151
7152
7153 afp->gbquals = NULL;
7154
7155 c = HiddenGroup (h, 4, 0, NULL);
7156 afp->accept = DefaultButton (c, "Accept", DoTheApplyToAllProc);
7157 SetObjectExtra (afp->accept, afp, NULL);
7158 PushButton (c, "Cancel", StdCancelButtonProc);
7159 afp->leaveDlgUp = CheckBox (c, "Leave Dialog Up", NULL);
7160
7161 if (parts_group == NULL)
7162 {
7163 AlignObjects (ALIGN_CENTER, (HANDLE) c,
7164 (HANDLE) afp->feature_details_dlg,
7165 (HANDLE) feature_details,
7166 NULL);
7167 }
7168 else
7169 {
7170 AlignObjects (ALIGN_CENTER, (HANDLE) parts_group,
7171 (HANDLE) c,
7172 (HANDLE) afp->feature_details_dlg,
7173 (HANDLE) feature_details,
7174 NULL);
7175 }
7176
7177 EnableApplyFeatureAccept (afp);
7178 RealizeWindow (w);
7179 Show (w);
7180 SendMessageToDialog (afp->feature_details_dlg, VIB_MSG_ENTER);
7181 Update ();
7182 }
7183
7184 extern void CommonApplyToAllProc (BaseFormPtr bfp, Int2 type)
7185 {
7186 if (bfp == NULL) return;
7187 CommonApplyToAllProcBfpInfo (bfp->input_entityID,
7188 bfp->input_itemID,
7189 bfp->input_itemtype, type);
7190 }
7191
7192 static void CommonApplyToAllProcMenuItem (IteM i, Int2 type)
7193 {
7194 BaseFormPtr bfp;
7195
7196 #ifdef WIN_MAC
7197 bfp = currentFormDataPtr;
7198 #else
7199 bfp = GetObjectExtra (i);
7200 #endif
7201 if (bfp == NULL) return;
7202
7203 CommonApplyToAllProc (bfp, type);
7204 }
7205
7206 extern void ApplyTitle (IteM i)
7207
7208 {
7209 CommonApplyToAllProcMenuItem (i, ADD_TITLE);
7210 }
7211
7212 extern void ApplyCDS (IteM i)
7213
7214 {
7215 CommonApplyToAllProcMenuItem (i, ADD_CDS);
7216 }
7217
7218 extern void ApplyRRNA (IteM i)
7219
7220 {
7221 CommonApplyToAllProcMenuItem (i, ADD_RRNA);
7222 }
7223
7224 extern void ApplyImpFeat (IteM i)
7225
7226 {
7227 CommonApplyToAllProcMenuItem (i, ADD_IMP);
7228 }
7229
7230 #define SUBMISSION_PAGE 0
7231 #define CONTACT_PAGE 1
7232 #define AUTHOR_PAGE 2
7233 #define AFFILIATION_PAGE 3
7234
7235 typedef struct submitform {
7236 FORM_MESSAGE_BLOCK
7237 GrouP pages [4];
7238 Int2 currentPage;
7239 DialoG tbs;
7240
7241 GrouP hup;
7242 GrouP dateGrp;
7243
7244 TexT title;
7245 DialoG reldate;
7246 TexT firstname;
7247 TexT middleinit;
7248 TexT lastname;
7249 PopuP suffix;
7250 DialoG phonefaxemail;
7251 DialoG authors;
7252 TexT consortium;
7253 DialoG affil;
7254
7255 Boolean visitedContact;
7256 Boolean visitedAuthor;
7257
7258 ButtoN nextBtn;
7259 ButtoN prevBtn;
7260 BtnActnProc goToNext;
7261 BtnActnProc goToPrev;
7262 } SubmitForm, PNTR SubmitFormPtr;
7263
7264 static AuthListPtr AddConsortiumToAuthList (AuthListPtr alp, TexT consortium)
7265
7266 {
7267 AuthorPtr ap;
7268 ValNodePtr names;
7269 PersonIdPtr pid;
7270
7271 if (TextHasNoText (consortium)) return alp;
7272 if (alp == NULL) {
7273 alp = AuthListNew ();
7274 alp->choice = 1;
7275 }
7276 pid = PersonIdNew ();
7277 if (pid == NULL) return NULL;
7278 pid->choice = 5;
7279 pid->data = SaveStringFromText (consortium);
7280 ap = AuthorNew ();
7281 if (ap == NULL) return NULL;
7282 ap->name = pid;
7283 names = ValNodeAdd (&(alp->names));
7284 names->choice = 1;
7285 names->data.ptrvalue = ap;
7286 return alp;
7287 }
7288
7289 static void AuthListToConsortium (AuthListPtr alp, TexT consortium)
7290
7291 {
7292 AuthorPtr ap;
7293 ValNodePtr names;
7294 PersonIdPtr pid;
7295 CharPtr str;
7296
7297 if (alp == NULL || consortium == NULL) return;
7298 if (alp->choice != 1) return;
7299 for (names = alp->names; names != NULL; names = names->next) {
7300 ap = names->data.ptrvalue;
7301 if (ap == NULL) continue;
7302 pid = ap->name;
7303 if (pid == NULL || pid->choice != 5) continue;
7304 str = (CharPtr) pid->data;
7305 SafeSetTitle (consortium, str);
7306 }
7307 }
7308
7309 static void SequinBlockPtrToSubmitForm (ForM f, Pointer data)
7310
7311 {
7312 AuthorPtr ap;
7313 DatePtr dp;
7314 NameStdPtr nsp;
7315 PersonIdPtr pid;
7316 SubmitFormPtr sbfp;
7317 SequinBlockPtr sbp;
7318 CharPtr str;
7319 CharPtr txt;
7320
7321 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7322 sbp = (SequinBlockPtr) data;
7323 if (sbfp != NULL) {
7324 if (sbp != NULL) {
7325 SafeSetTitle (sbfp->title, sbp->citsubtitle);
7326 PointerToDialog (sbfp->reldate, (Pointer) sbp->releasedate);
7327 ap = sbp->contactperson;
7328 if (ap != NULL) {
7329 pid = ap->name;
7330 if (pid != NULL && pid->choice == 2) {
7331 nsp = pid->data;
7332 if (nsp != NULL) {
7333 str = NameStdPtrToAuthorSpreadsheetString (nsp);
7334 if (str != NULL) {
7335 txt = ExtractTagListColumn (str, 0);
7336 SafeSetTitle (sbfp->firstname, txt);
7337 MemFree (txt);
7338 txt = ExtractTagListColumn (str, 1);
7339 SafeSetTitle (sbfp->middleinit, txt);
7340 MemFree (txt);
7341 txt = ExtractTagListColumn (str, 2);
7342 SafeSetTitle (sbfp->lastname, txt);
7343 MemFree (txt);
7344 txt = ExtractTagListColumn (str, 3);
7345 if (! StringHasNoText (txt)) {
7346 SetEnumPopupByName (sbfp->suffix, name_suffix_alist, txt);
7347 }
7348 /*
7349 SafeSetTitle (sbfp->suffix, txt);
7350 */
7351 MemFree (txt);
7352 MemFree (str);
7353 }
7354 }
7355 }
7356 PointerToDialog (sbfp->phonefaxemail, (Pointer) ap->affil);
7357 }
7358 PointerToDialog (sbfp->authors, (Pointer) sbp->citsubauthors);
7359 AuthListToConsortium (sbp->citsubauthors, sbfp->consortium);
7360 PointerToDialog (sbfp->affil, (Pointer) sbp->citsubaffil);
7361 if (sbp->holduntilpublished) {
7362 SafeSetValue (sbfp->hup, 2);
7363 SafeShow (sbfp->dateGrp);
7364 } else {
7365 SafeSetValue (sbfp->hup, 1);
7366 SafeHide (sbfp->dateGrp);
7367 }
7368 sbfp->visitedAuthor = TRUE;
7369 SetValue (sbfp->tbs, 0);
7370 } else {
7371 SafeSetTitle (sbfp->title, NULL);
7372 dp = DateCurr ();
7373 if (dp != NULL) {
7374 dp->data [3] = 0; /* force to end of month */
7375 dp = DateAdvance (dp, 12);
7376 /*
7377 (dp->data [1])++;
7378 if (dp->data [2] == 2 && dp->data [3] > 28) {
7379 dp->data [3] = 28;
7380 }
7381 */
7382 PointerToDialog (sbfp->reldate, (Pointer) dp);
7383 } else {
7384 PointerToDialog (sbfp->reldate, NULL);
7385 }
7386 DateFree (dp);
7387 SafeSetTitle (sbfp->firstname, "");
7388 SafeSetTitle (sbfp->middleinit, "");
7389 SafeSetTitle (sbfp->lastname, "");
7390 PointerToDialog (sbfp->phonefaxemail, NULL);
7391 PointerToDialog (sbfp->authors, NULL);
7392 SafeSetTitle (sbfp->consortium, "");
7393 PointerToDialog (sbfp->affil, NULL);
7394 SafeSetValue (sbfp->hup, 1);
7395 SafeHide (sbfp->dateGrp);
7396 SetValue (sbfp->tbs, 0);
7397 }
7398 }
7399 }
7400
7401 static Pointer SubmitFormToSequinBlockPtr (ForM f)
7402
7403 {
7404 AffilPtr affil;
7405 AuthorPtr ap;
7406 NameStdPtr nsp;
7407 PersonIdPtr pid;
7408 SubmitFormPtr sbfp;
7409 SequinBlockPtr sbp;
7410 Char sfx [32];
7411 Char str [128];
7412 Uint2 suffixVal;
7413 CharPtr txt;
7414
7415 sbp = NULL;
7416 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7417 if (sbfp != NULL) {
7418 sbp = (SequinBlockPtr) MemNew (sizeof (SequinBlock));
7419 if (sbp != NULL) {
7420 sbp->citsubtitle = SaveStringFromTextAndStripNewlines (sbfp->title);
7421 ap = AuthorNew ();
7422 if (ap != NULL) {
7423 pid = PersonIdNew ();
7424 ap->name = pid;
7425 if (pid != NULL) {
7426 pid->choice = 2;
7427 str [0] = '\0';
7428 txt = SaveStringFromText (sbfp->firstname);
7429 StringCat (str, txt);
7430 StringCat (str, "\t");
7431 MemFree (txt);
7432 txt = SaveStringFromText (sbfp->middleinit);
7433 StringCat (str, txt);
7434 StringCat (str, "\t");
7435 MemFree (txt);
7436 txt = SaveStringFromText (sbfp->lastname);
7437 StringCat (str, txt);
7438 StringCat (str, "\t");
7439 MemFree (txt);
7440 suffixVal = GetValue (sbfp->suffix);
7441 sprintf (sfx, "%d", (int) (suffixVal - 1));
7442 StringCat (str, sfx);
7443 StringCat (str, "\n");
7444 txt = StringSave (str);
7445 nsp = AuthorSpreadsheetStringToNameStdPtr (txt);
7446 MemFree (txt);
7447 pid->data = nsp;
7448 if (nsp != NULL) {
7449 if (StringHasNoText (nsp->names [0])) {
7450 ap = AuthorFree (ap);
7451 }
7452 }
7453 }
7454 affil = (AffilPtr) DialogToPointer (sbfp->phonefaxemail);
7455 if (affil != NULL) {
7456 if (affil->choice == 2) {
7457 affil->affil = MemFree (affil->affil);
7458 affil->div = MemFree (affil->div);
7459 affil->city = MemFree (affil->city);
7460 affil->sub = MemFree (affil->sub);
7461 affil->country = MemFree (affil->country);
7462 affil->street = MemFree (affil->street);
7463 affil->postal_code = MemFree (affil->postal_code);
7464 if (affil->phone == NULL && affil->fax == NULL &&
7465 affil->email == NULL) {
7466 affil = AffilFree (affil);
7467 }
7468 } else {
7469 affil = AffilFree (affil);
7470 }
7471 }
7472 if (affil != NULL) {
7473 if (ap == NULL) {
7474 ap = AuthorNew();
7475 }
7476 ap->affil = affil;
7477 }
7478 }
7479 sbp->contactperson = ap;
7480 sbp->citsubauthors = (AuthListPtr) DialogToPointer (sbfp->authors);
7481 sbp->citsubauthors = AddConsortiumToAuthList (sbp->citsubauthors, sbfp->consortium);
7482 sbp->citsubaffil = (AffilPtr) DialogToPointer (sbfp->affil);
7483 if (GetValue (sbfp->hup) == 2) {
7484 sbp->holduntilpublished = TRUE;
7485 sbp->releasedate = (DatePtr) DialogToPointer (sbfp->reldate);
7486 }
7487 if (sbp->contactperson == NULL &&
7488 sbp->citsubauthors == NULL &&
7489 sbp->citsubaffil == NULL) {
7490 sbp = SequinBlockFree (sbp);
7491 }
7492 }
7493 }
7494 return (Pointer) sbp;
7495 }
7496
7497 static void SubmitBlockPtrToSubmitForm (ForM f, Pointer data)
7498
7499 {
7500 AuthorPtr ap;
7501 AuthListPtr authors;
7502 ContactInfoPtr cip;
7503 CitSubPtr csp;
7504 DatePtr dp;
7505 NameStdPtr nsp;
7506 PersonIdPtr pid;
7507 SubmitFormPtr sbfp;
7508 SubmitBlockPtr sbp;
7509 CharPtr str;
7510 CharPtr txt;
7511
7512 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7513 sbp = (SubmitBlockPtr) data;
7514 if (sbfp != NULL) {
7515 if (sbp != NULL) {
7516 PointerToDialog (sbfp->reldate, (Pointer) sbp->reldate);
7517 cip = sbp->contact;
7518 if (cip != NULL) {
7519 ap = cip->contact;
7520 if (ap != NULL) {
7521 pid = ap->name;
7522 if (pid != NULL && pid->choice == 2) {
7523 nsp = pid->data;
7524 if (nsp != NULL) {
7525 str = NameStdPtrToAuthorSpreadsheetString (nsp);
7526 if (str != NULL) {
7527 txt = ExtractTagListColumn (str, 0);
7528 SafeSetTitle (sbfp->firstname, txt);
7529 MemFree (txt);
7530 txt = ExtractTagListColumn (str, 1);
7531 SafeSetTitle (sbfp->middleinit, txt);
7532 MemFree (txt);
7533 txt = ExtractTagListColumn (str, 2);
7534 SafeSetTitle (sbfp->lastname, txt);
7535 MemFree (txt);
7536 txt = ExtractTagListColumn (str, 3);
7537 if (! StringHasNoText (txt)) {
7538 SetEnumPopupByName (sbfp->suffix, name_suffix_alist, txt);
7539 }
7540 /*
7541 SafeSetTitle (sbfp->suffix, txt);
7542 */
7543 MemFree (txt);
7544 MemFree (str);
7545 }
7546 }
7547 }
7548 PointerToDialog (sbfp->phonefaxemail, (Pointer) ap->affil);
7549 }
7550 }
7551 csp = sbp->cit;
7552 if (csp != NULL) {
7553 authors = csp->authors;
7554 if (authors != NULL) {
7555 PointerToDialog (sbfp->authors, (Pointer) authors);
7556 AuthListToConsortium (authors, sbfp->consortium);
7557 PointerToDialog (sbfp->affil, (Pointer) authors->affil);
7558 }
7559 }
7560 if (sbp->hup) {
7561 SafeSetValue (sbfp->hup, 2);
7562 SafeShow (sbfp->dateGrp);
7563 } else {
7564 SafeSetValue (sbfp->hup, 1);
7565 SafeHide (sbfp->dateGrp);
7566 }
7567 sbfp->visitedAuthor = TRUE;
7568 SetValue (sbfp->tbs, 0);
7569 } else {
7570 SafeSetTitle (sbfp->title, NULL);
7571 dp = DateCurr ();
7572 if (dp != NULL) {
7573 dp->data [3] = 0; /* force to end of month */
7574 dp = DateAdvance (dp, 12);
7575 PointerToDialog (sbfp->reldate, (Pointer) dp);
7576 } else {
7577 PointerToDialog (sbfp->reldate, NULL);
7578 }
7579 DateFree (dp);
7580 SafeSetTitle (sbfp->firstname, "");
7581 SafeSetTitle (sbfp->middleinit, "");
7582 SafeSetTitle (sbfp->lastname, "");
7583 SafeSetValue (sbfp->suffix, 0);
7584 PointerToDialog (sbfp->phonefaxemail, NULL);
7585 PointerToDialog (sbfp->authors, NULL);
7586 SafeSetTitle (sbfp->consortium, "");
7587 PointerToDialog (sbfp->affil, NULL);
7588 SafeSetValue (sbfp->hup, 1);
7589 SafeHide (sbfp->dateGrp);
7590 SetValue (sbfp->tbs, 0);
7591 }
7592 }
7593 }
7594
7595 static void TitleToSubmitBlockForm(ForM f, Pointer data)
7596
7597 {
7598 CharPtr man_title;
7599 SubmitFormPtr sbfp;
7600
7601 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7602 man_title = (CharPtr) data;
7603 if (sbfp != NULL)
7604 {
7605 if (man_title == NULL) {
7606 SetTitle (sbfp->title, "");
7607 } else {
7608 SetTitle (sbfp->title, man_title);
7609 }
7610 }
7611 }
7612
7613 static ValNodePtr TestSubmitForm (ForM f)
7614
7615 {
7616 AffilPtr affil;
7617 AuthListPtr authors;
7618 DatePtr dp;
7619 ValNodePtr head;
7620 SubmitFormPtr sbfp;
7621
7622 head = NULL;
7623
7624 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7625 if (sbfp != NULL) {
7626
7627 if (TextHasNoText (sbfp->firstname)) {
7628 head = AddStringToValNodeChain (head, "first name", 1);
7629 }
7630 if (TextHasNoText (sbfp->lastname)) {
7631 head = AddStringToValNodeChain (head, "last name", 1);
7632 }
7633 affil = DialogToPointer (sbfp->phonefaxemail);
7634 if (affil != NULL) {
7635 if (StringHasNoText (affil->phone)) {
7636 head = AddStringToValNodeChain (head, "telephone number", 0);
7637 }
7638 if (StringHasNoText (affil->fax)) {
7639 head = AddStringToValNodeChain (head, "fax number", 0);
7640 }
7641 if (StringHasNoText (affil->email)) {
7642 head = AddStringToValNodeChain (head, "e-mail address", 0);
7643 }
7644 } else {
7645 head = AddStringToValNodeChain (head, "telephone number", 0);
7646 head = AddStringToValNodeChain (head, "fax number", 0);
7647 head = AddStringToValNodeChain (head, "e-mail address", 0);
7648 }
7649 affil = AffilFree (affil);
7650
7651 if (GetValue (sbfp->hup) == 2) {
7652 dp = DialogToPointer (sbfp->reldate);
7653 if (dp == NULL) {
7654 head = AddStringToValNodeChain (head, "release date", 1);
7655 }
7656 dp = DateFree (dp);
7657 }
7658 if (TextHasNoText (sbfp->title)) {
7659 head = AddStringToValNodeChain (head, "manuscript title", 1);
7660 }
7661
7662 authors = DialogToPointer (sbfp->authors);
7663 authors = AddConsortiumToAuthList (authors, sbfp->consortium);
7664 if (authors == NULL) {
7665 head = AddStringToValNodeChain (head, "author names", 1);
7666 }
7667 authors = AuthListFree (authors);
7668 affil = DialogToPointer (sbfp->affil);
7669 if (affil == NULL) {
7670 head = AddStringToValNodeChain (head, "affiliation", 1);
7671 }
7672 affil = AffilFree (affil);
7673
7674 }
7675
7676 return head;
7677 }
7678
7679 /*
7680 static Boolean ReadSubmitBlock (ForM f, CharPtr filename)
7681
7682 {
7683 AsnIoPtr aip;
7684 Char path [PATH_MAX];
7685 SubmitFormPtr sbfp;
7686 SubmitBlockPtr sbp;
7687
7688 path [0] = '\0';
7689 StringNCpy_0 (path, filename, sizeof (path));
7690 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7691 if (sbfp != NULL) {
7692 if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
7693 aip = AsnIoOpen (path, "r");
7694 if (aip != NULL) {
7695 sbp = SubmitBlockAsnRead (aip, NULL);
7696 AsnIoClose (aip);
7697 if (sbp != NULL) {
7698 SubmitBlockPtrToSubmitForm (f, (Pointer) sbp);
7699 sbp = SubmitBlockFree (sbp);
7700 Update ();
7701 return TRUE;
7702 }
7703 }
7704 }
7705 }
7706 return FALSE;
7707 }
7708 */
7709
7710
7711 static Pointer ReadNextASNObject (FILE *fp, Uint2Ptr datatypeptr, Uint2Ptr entityIDptr)
7712 {
7713 AsnIoPtr aip;
7714 Pointer dataptr = NULL;
7715 Int4 pos;
7716 ObjMgrPtr omp;
7717 ObjMgrTypePtr omtp = NULL;
7718 FileCache fc;
7719 CharPtr str, tag, pEnd;
7720 Char line [4096];
7721
7722 if (fp == NULL) {
7723 return NULL;
7724 }
7725
7726 FileCacheSetup (&fc, fp);
7727
7728 pos = FileCacheTell (&fc);
7729
7730 str = FileCacheReadLine (&fc, line, sizeof (line), NULL);
7731 while (str != NULL && StringHasNoText (str)) {
7732 str = FileCacheReadLine (&fc, line, sizeof (line), NULL);
7733 }
7734
7735 if (str == NULL) return NULL; /* already at end of file */
7736
7737 if (StringStr (str, "::=") == NULL) return NULL;
7738
7739 /* first skip past empty space at start of line */
7740 tag = str;
7741 while (*tag != '\0' && IS_WHITESP (*tag)) {
7742 tag++;
7743 }
7744 pEnd = tag;
7745 while (*pEnd != '\0' && !IS_WHITESP (*pEnd)) {
7746 pEnd++;
7747 }
7748 *pEnd = 0;
7749
7750 omp = ObjMgrReadLock ();
7751 omtp = ObjMgrTypeFind (omp, 0, tag, NULL);
7752 ObjMgrUnlock ();
7753
7754 if (omtp == NULL) {
7755 return NULL;
7756 }
7757 FileCacheFree (&fc, FALSE);
7758 fseek (fp, pos, SEEK_SET);
7759
7760 aip = AsnIoNew (ASNIO_TEXT_IN, fp, NULL, NULL, NULL);
7761 aip->scan_for_start = TRUE;
7762 dataptr = (*(omtp->asnread)) (aip, NULL);
7763 pos = AsnIoTell (aip);
7764 AsnIoFree (aip, FALSE);
7765 fseek (fp, pos, SEEK_SET);
7766
7767 if (dataptr == NULL) {
7768 ErrPostEx (SEV_ERROR, 0, 0, "Couldn't read type [%s]", omtp->asnname);
7769 } else {
7770 if (datatypeptr != NULL) {
7771 *datatypeptr = omtp->datatype;
7772 }
7773 if (entityIDptr != NULL) {
7774 *entityIDptr = ObjMgrRegister (omtp->datatype, dataptr);
7775 }
7776 }
7777 return dataptr;
7778 }
7779
7780
7781 static Boolean ReadSubmitBlock (ForM f, CharPtr filename)
7782
7783 {
7784 Pointer dataptr;
7785 Uint2 datatype;
7786 Uint2 entityID;
7787 SubmitFormPtr sbfp;
7788 SubmitBlockPtr sbp;
7789 SeqSubmitPtr ssp;
7790 Char path [PATH_MAX];
7791 CharPtr man_title;
7792 CitGenPtr cgp;
7793 FILE * fp;
7794 PubdescPtr pdp;
7795 ValNodePtr sdp;
7796
7797
7798 path [0] = '\0';
7799 StringNCpy_0 (path, filename, sizeof (path));
7800 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7801 if (sbfp != NULL) {
7802 if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
7803 fp = FileOpen(path, "r");
7804 dataptr = ReadNextASNObject (fp, &datatype, &entityID);
7805 sbp = NULL;
7806 man_title = NULL;
7807 while (dataptr != NULL) {
7808 if (entityID > 0) {
7809 switch (datatype) {
7810 case OBJ_SUBMIT_BLOCK :
7811 if (sbp == NULL) {
7812 sbp = (SubmitBlockPtr) AsnIoMemCopy (dataptr,
7813 (AsnReadFunc) SubmitBlockAsnRead,
7814 (AsnWriteFunc) SubmitBlockAsnWrite);
7815 }
7816 break;
7817 case OBJ_SEQSUB :
7818 if (sbp == NULL) {
7819 ssp = (SeqSubmitPtr) dataptr;
7820 if (ssp != NULL) {
7821 sbp = (SubmitBlockPtr) AsnIoMemCopy (ssp->sub,
7822 (AsnReadFunc) SubmitBlockAsnRead,
7823 (AsnWriteFunc) SubmitBlockAsnWrite);
7824 }
7825 }
7826 break;
7827 case OBJ_SEQDESC:
7828 sdp = (ValNodePtr) dataptr;
7829 if (sdp->choice == Seq_descr_pub && sdp->data.ptrvalue != NULL && man_title == NULL) {
7830 pdp = (PubdescPtr) sdp->data.ptrvalue;
7831 sdp = pdp->pub;
7832 while (sdp != NULL && sdp->choice != PUB_Gen) {
7833 sdp = sdp->next;
7834 }
7835 if (sdp != NULL && sdp->data.ptrvalue != NULL) {
7836 cgp = (CitGenPtr) sdp->data.ptrvalue;
7837 if (StringICmp (cgp->cit, "unpublished") == 0
7838 && !StringHasNoText (cgp->title)) {
7839 man_title = StringSave (cgp->title);
7840 }
7841 }
7842 }
7843 break;
7844 default :
7845 break;
7846 }
7847 }
7848 ObjMgrDelete (datatype, dataptr);
7849 dataptr = ReadNextASNObject (fp, &datatype, &entityID);
7850 }
7851 FileClose (fp);
7852 if (sbp != NULL || man_title != NULL) {
7853 if (sbp != NULL) {
7854 SubmitBlockPtrToSubmitForm (f, sbp);
7855 sbp = SubmitBlockFree (sbp);
7856 }
7857 if (man_title != NULL) {
7858 TitleToSubmitBlockForm (f, man_title);
7859 man_title = MemFree (man_title);
7860 }
7861 Update ();
7862 return TRUE;
7863 }
7864 }
7865 }
7866 return FALSE;
7867 }
7868
7869 static SeqDescrPtr MakeUnpubPub (CharPtr title, AuthListPtr alp, AffilPtr affil)
7870
7871 {
7872 CitGenPtr cgp;
7873 PubdescPtr pdp;
7874 ValNodePtr pep;
7875 SeqDescrPtr vnp;
7876
7877 if (StringHasNoText (title) || alp == NULL) return NULL;
7878 pdp = PubdescNew ();
7879 if (pdp == NULL) return NULL;
7880 vnp = SeqDescrNew (NULL);
7881 if (vnp == NULL) return NULL;
7882 vnp->choice = Seq_descr_pub;
7883 vnp->data.ptrvalue = (Pointer) pdp;
7884 pdp->reftype = 0;
7885 pep = ValNodeNew (NULL);
7886 pdp->pub = pep;
7887 if (pep != NULL) {
7888 cgp = CitGenNew ();
7889 if (cgp != NULL) {
7890 pep->choice = PUB_Gen;
7891 pep->data.ptrvalue = cgp;
7892 cgp->cit = StringSave ("unpublished");
7893 cgp->authors = alp;
7894 if (alp != NULL) {
7895 alp->affil = affil;
7896 if (affil != NULL) {
7897 affil->phone = MemFree (affil->phone);
7898 affil->fax = MemFree (affil->fax);
7899 affil->email = MemFree (affil->email);
7900 }
7901 }
7902 cgp->title = StringSave (title);
7903 }
7904 }
7905 return vnp;
7906 }
7907
7908 extern SubmitBlockPtr ConvertSequinBlockToSubmitBlock (SequinBlockPtr sqp);
7909
7910 NLM_EXTERN void AsnPrintNewLine PROTO((AsnIoPtr aip));
7911
7912 static Boolean WriteSubmitBlock (ForM f, CharPtr filename)
7913
7914 {
7915 AffilPtr affil;
7916 AsnIoPtr aip;
7917 AuthListPtr alp;
7918 Char path [PATH_MAX];
7919 SubmitFormPtr sbfp;
7920 SubmitBlockPtr sbp;
7921 SeqDescrPtr sdp;
7922 SequinBlockPtr sqp;
7923 CharPtr title;
7924 #ifdef WIN_MAC
7925 FILE *fp;
7926 #endif
7927
7928 path [0] = '\0';
7929 StringNCpy_0 (path, filename, sizeof (path));
7930 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7931 if (sbfp != NULL) {
7932 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
7933 #ifdef WIN_MAC
7934 fp = FileOpen (path, "r");
7935 if (fp != NULL) {
7936 FileClose (fp);
7937 } else {
7938 FileCreate (path, "TEXT", "ttxt");
7939 }
7940 #endif
7941 sqp = (SequinBlockPtr) SubmitFormToSequinBlockPtr (f);
7942 if (sqp != NULL) {
7943 title = StringSaveNoNull (sqp->citsubtitle);
7944 alp = AsnIoMemCopy ((Pointer) sqp->citsubauthors,
7945 (AsnReadFunc) AuthListAsnRead,
7946 (AsnWriteFunc) AuthListAsnWrite);
7947 affil = AsnIoMemCopy ((Pointer) sqp->citsubaffil,
7948 (AsnReadFunc) AffilAsnRead,
7949 (AsnWriteFunc) AffilAsnWrite);
7950 sbp = ConvertSequinBlockToSubmitBlock (sqp);
7951 if (sbp != NULL) {
7952 aip = AsnIoOpen (path, "w");
7953 if (aip != NULL) {
7954 sbp->tool = MemFree (sbp->tool);
7955 SubmitBlockAsnWrite (sbp, aip, NULL);
7956 AsnPrintNewLine (aip);
7957 sdp = MakeUnpubPub (title, alp, affil);
7958 if (sdp != NULL) {
7959 AsnIoReset (aip);
7960 SeqDescAsnWrite (sdp, aip, NULL);
7961 AsnPrintNewLine (aip);
7962 SeqDescFree (sdp);
7963 }
7964 AsnIoClose (aip);
7965 sbp = SubmitBlockFree (sbp);
7966 return TRUE;
7967 }
7968 }
7969 }
7970 }
7971 }
7972 return FALSE;
7973 }
7974
7975 static Boolean ReadContactPage (ForM f, CharPtr filename)
7976
7977 {
7978 AsnIoPtr aip;
7979 AuthorPtr ap;
7980 ContactInfoPtr cip;
7981 NameStdPtr nsp;
7982 Char path [PATH_MAX];
7983 PersonIdPtr pid;
7984 SubmitFormPtr sbfp;
7985 CharPtr str;
7986 CharPtr txt;
7987
7988 path [0] = '\0';
7989 StringNCpy_0 (path, filename, sizeof (path));
7990 sbfp = (SubmitFormPtr) GetObjectExtra (f);
7991 if (sbfp != NULL) {
7992 if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
7993 aip = AsnIoOpen (path, "r");
7994 if (aip != NULL) {
7995 cip = ContactInfoAsnRead (aip, NULL);
7996 AsnIoClose (aip);
7997 if (cip != NULL) {
7998 ap = cip->contact;
7999 if (ap != NULL) {
8000 pid = ap->name;
8001 if (pid != NULL && pid->choice == 2) {
8002 nsp = pid->data;
8003 if (nsp != NULL) {
8004 str = NameStdPtrToAuthorSpreadsheetString (nsp);
8005 if (str != NULL) {
8006 txt = ExtractTagListColumn (str, 0);
8007 SafeSetTitle (sbfp->firstname, txt);
8008 MemFree (txt);
8009 txt = ExtractTagListColumn (str, 1);
8010 SafeSetTitle (sbfp->middleinit, txt);
8011 MemFree (txt);
8012 txt = ExtractTagListColumn (str, 2);
8013 SafeSetTitle (sbfp->lastname, txt);
8014 MemFree (txt);
8015 txt = ExtractTagListColumn (str, 3);
8016 if (! StringHasNoText (txt)) {
8017 SetEnumPopupByName (sbfp->suffix, name_suffix_alist, txt);
8018 }
8019 MemFree (txt);
8020 MemFree (str);
8021 }
8022 }
8023 }
8024 PointerToDialog (sbfp->phonefaxemail, (Pointer) ap->affil);
8025 }
8026 cip = ContactInfoFree (cip);
8027 Update ();
8028 return TRUE;
8029 }
8030 }
8031 }
8032 }
8033 return FALSE;
8034 }
8035
8036 static Boolean WriteContactPage (ForM f, CharPtr filename)
8037
8038 {
8039 AffilPtr affil;
8040 AsnIoPtr aip;
8041 AuthorPtr ap;
8042 ContactInfoPtr cip;
8043 NameStdPtr nsp;
8044 Char path [PATH_MAX];
8045 PersonIdPtr pid;
8046 SubmitFormPtr sbfp;
8047 Char sfx [32];
8048 Char str [128];
8049 Uint2 suffixVal;
8050 CharPtr txt;
8051 #ifdef WIN_MAC
8052 FILE *fp;
8053 #endif
8054
8055 path [0] = '\0';
8056 StringNCpy_0 (path, filename, sizeof (path));
8057 sbfp = (SubmitFormPtr) GetObjectExtra (f);
8058 if (sbfp != NULL) {
8059 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
8060 #ifdef WIN_MAC
8061 fp = FileOpen (path, "r");
8062 if (fp != NULL) {
8063 FileClose (fp);
8064 } else {
8065 FileCreate (path, "TEXT", "ttxt");
8066 }
8067 #endif
8068 aip = AsnIoOpen (path, "w");
8069 if (aip != NULL) {
8070 cip = ContactInfoNew ();
8071 if (cip != NULL) {
8072 ap = AuthorNew ();
8073 if (ap != NULL) {
8074 pid = PersonIdNew ();
8075 ap->name = pid;
8076 if (pid != NULL) {
8077 pid->choice = 2;
8078 str [0] = '\0';
8079 txt = SaveStringFromText (sbfp->firstname);
8080 StringCat (str, txt);
8081 StringCat (str, "\t");
8082 MemFree (txt);
8083 txt = SaveStringFromText (sbfp->middleinit);
8084 StringCat (str, txt);
8085 StringCat (str, "\t");
8086 MemFree (txt);
8087 txt = SaveStringFromText (sbfp->lastname);
8088 StringCat (str, txt);
8089 StringCat (str, "\t");
8090 MemFree (txt);
8091 suffixVal = GetValue (sbfp->suffix);
8092 sprintf (sfx, "%d", (int) (suffixVal - 1));
8093 StringCat (str, sfx);
8094 StringCat (str, "\n");
8095 txt = StringSave (str);
8096 nsp = AuthorSpreadsheetStringToNameStdPtr (txt);
8097 MemFree (txt);
8098 pid->data = nsp;
8099 if (nsp != NULL) {
8100 if (StringHasNoText (nsp->names [0])) {
8101 ap = AuthorFree (ap);
8102 }
8103 }
8104 }
8105 affil = (AffilPtr) DialogToPointer (sbfp->phonefaxemail);
8106 if (affil != NULL) {
8107 if (affil->choice == 2) {
8108 affil->affil = MemFree (affil->affil);
8109 affil->div = MemFree (affil->div);
8110 affil->city = MemFree (affil->city);
8111 affil->sub = MemFree (affil->sub);
8112 affil->country = MemFree (affil->country);
8113 affil->street = MemFree (affil->street);
8114 affil->postal_code = MemFree (affil->postal_code);
8115 if (affil->phone == NULL && affil->fax == NULL &&
8116 affil->email == NULL) {
8117 affil = AffilFree (affil);
8118 }
8119 } else {
8120 affil = AffilFree (affil);
8121 }
8122 }
8123 ap->affil = affil;
8124 }
8125 cip->contact = ap;
8126 ContactInfoAsnWrite (cip, aip, NULL);
8127 AsnIoClose (aip);
8128 cip = ContactInfoFree (cip);
8129 return TRUE;
8130 }
8131 }
8132 }
8133 }
8134 return FALSE;
8135 }
8136
8137 static Boolean ReadAuthListPage (ForM f, CharPtr filename)
8138
8139 {
8140 AsnIoPtr aip;
8141 AuthListPtr alp;
8142 Char path [PATH_MAX];
8143 SubmitFormPtr sbfp;
8144
8145 path [0] = '\0';
8146 StringNCpy_0 (path, filename, sizeof (path));
8147 sbfp = (SubmitFormPtr) GetObjectExtra (f);
8148 if (sbfp != NULL) {
8149 if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
8150 aip = AsnIoOpen (path, "r");
8151 if (aip != NULL) {
8152 alp = AuthListAsnRead (aip, NULL);
8153 AsnIoClose (aip);
8154 if (alp != NULL) {
8155 PointerToDialog (sbfp->authors, alp);
8156 AuthListToConsortium (alp, sbfp->consortium);
8157 alp = AuthListFree (alp);
8158 Update ();
8159 return TRUE;
8160 }
8161 }
8162 }
8163 }
8164 return FALSE;
8165 }
8166
8167 static Boolean WriteAuthListPage (ForM f, CharPtr filename)
8168
8169 {
8170 AsnIoPtr aip;
8171 AuthListPtr alp;
8172 Char path [PATH_MAX];
8173 SubmitFormPtr sbfp;
8174 #ifdef WIN_MAC
8175 FILE *fp;
8176 #endif
8177
8178 path [0] = '\0';
8179 StringNCpy_0 (path, filename, sizeof (path));
8180 sbfp = (SubmitFormPtr) GetObjectExtra (f);
8181 if (sbfp != NULL) {
8182 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
8183 #ifdef WIN_MAC
8184 fp = FileOpen (path, "r");
8185 if (fp != NULL) {
8186 FileClose (fp);
8187 } else {
8188 FileCreate (path, "TEXT", "ttxt");
8189 }
8190 #endif
8191 aip = AsnIoOpen (path, "w");
8192 if (aip != NULL) {
8193 alp = DialogToPointer (sbfp->authors);
8194 alp = AddConsortiumToAuthList (alp, sbfp->consortium);
8195 AuthListAsnWrite (alp, aip, NULL);
8196 AsnIoClose (aip);
8197 alp = AuthListFree (alp);
8198 return TRUE;
8199 }
8200 }
8201 }
8202 return FALSE;
8203 }
8204
8205 static Boolean ReadAffilPage (ForM f, CharPtr filename)
8206
8207 {
8208 AffilPtr affil;
8209 AsnIoPtr aip;
8210 Char path [PATH_MAX];
8211 SubmitFormPtr sbfp;
8212
8213 path [0] = '\0';
8214 StringNCpy_0 (path, filename, sizeof (path));
8215 sbfp = (SubmitFormPtr) GetObjectExtra (f);
8216 if (sbfp != NULL) {
8217 if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
8218 aip = AsnIoOpen (path, "r");
8219 if (aip != NULL) {
8220 affil = AffilAsnRead (aip, NULL);
8221 AsnIoClose (aip);
8222 if (affil != NULL) {
8223 affil->phone = MemFree (affil->phone);
8224 affil->fax = MemFree (affil->fax);
8225 affil->email = MemFree (affil->email);
8226 PointerToDialog (sbfp->affil, affil);
8227 affil = AffilFree (affil);
8228 Update ();
8229 return TRUE;
8230 }
8231 }
8232 }
8233 }
8234 return FALSE;
8235 }
8236
8237 static Boolean WriteAffilPage (ForM f, CharPtr filename)
8238
8239 {
8240 AffilPtr affil;
8241 AsnIoPtr aip;
8242 Char path [PATH_MAX];
8243 SubmitFormPtr sbfp;
8244 #ifdef WIN_MAC
8245 FILE *fp;
8246 #endif
8247
8248 path [0] = '\0';
8249 StringNCpy_0 (path, filename, sizeof (path));
8250 sbfp = (SubmitFormPtr) GetObjectExtra (f);
8251 if (sbfp != NULL) {
8252 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
8253 #ifdef WIN_MAC
8254 fp = FileOpen (path, "r");
8255 if (fp != NULL) {
8256 FileClose (fp);
8257 } else {
8258 FileCreate (path, "TEXT", "ttxt");
8259 }
8260 #endif
8261 aip = AsnIoOpen (path, "w");
8262 if (aip != NULL) {
8263 affil = DialogToPointer (sbfp->affil);
8264 affil->phone = MemFree (affil->phone);
8265 affil->fax = MemFree (affil->fax);
8266 affil->email = MemFree (affil->email);
8267 AffilAsnWrite (affil, aip, NULL);
8268 AsnIoClose (aip);
8269 affil = AffilFree (affil);
8270 return TRUE;
8271 }
8272 }
8273 }
8274 return FALSE;
8275 }
8276
8277 static Boolean ImportSubmitForm (ForM f, CharPtr filename)
8278
8279 {
8280 SubmitFormPtr sbfp;
8281
8282 sbfp = (SubmitFormPtr) GetObjectExtra (f);
8283 if (sbfp != NULL) {
8284 switch (sbfp->currentPage) {
8285 case SUBMISSION_PAGE :
8286 return ReadSubmitBlock (f, filename);
8287 case CONTACT_PAGE :
8288 return ReadContactPage (f, filename);
8289 case AUTHOR_PAGE :
8290 return ReadAuthListPage (f, filename);
8291 case AFFILIATION_PAGE :
8292 return ReadAffilPage (f, filename);
8293 default :
8294 break;
8295 }
8296 }
8297 return FALSE;
8298 }
8299
8300 static Boolean ExportSubmitForm (ForM f, CharPtr filename)
8301
8302 {
8303 SubmitFormPtr sbfp;
8304
8305 sbfp = (SubmitFormPtr) GetObjectExtra (f);
8306 if (sbfp != NULL) {
8307 switch (sbfp->currentPage) {
8308 case SUBMISSION_PAGE :
8309 return WriteSubmitBlock (f, filename);
8310 case CONTACT_PAGE :
8311 return WriteContactPage (f, filename);
8312 case AUTHOR_PAGE :
8313 return WriteAuthListPage (f, filename);
8314 case AFFILIATION_PAGE :
8315 return WriteAffilPage (f, filename);
8316 default :
8317 break;
8318 }
8319 }
8320 return FALSE;
8321 }
8322
8323 static void CopyContactToAuthors (SubmitFormPtr sbfp)
8324
8325 {
8326 AuthListPtr alp;
8327 AuthorPtr ap;
8328 ValNodePtr names;
8329 NameStdPtr nsp;
8330 PersonIdPtr pid;
8331 Char sfx [32];
8332 Char str [128];
8333 Uint2 suffixVal;
8334 CharPtr txt;
8335
8336 if (sbfp == NULL) return;
8337 ap = NULL;
8338 alp = AuthListNew ();
8339 if (alp != NULL) {
8340 alp->choice = 1;
8341 names = ValNodeNew (NULL);
8342 alp->choice = 1;
8343 alp->names = names;
8344 if (names != NULL) {
8345 ap = AuthorNew ();
8346 if (ap != NULL) {
8347 pid = PersonIdNew ();
8348 ap->name = pid;
8349 if (pid != NULL) {
8350 pid->choice = 2;
8351 str [0] = '\0';
8352 txt = SaveStringFromText (sbfp->firstname);
8353 StringCat (str, txt);
8354 StringCat (str, "\t");
8355 MemFree (txt);
8356 txt = SaveStringFromText (sbfp->middleinit);
8357 StringCat (str, txt);
8358 StringCat (str, "\t");
8359 MemFree (txt);
8360 txt = SaveStringFromText (sbfp->lastname);
8361 StringCat (str, txt);
8362 StringCat (str, "\t");
8363 MemFree (txt);
8364 suffixVal = GetValue (sbfp->suffix);
8365 sprintf (sfx, "%d", (int) (suffixVal - 1));
8366 /*
8367 txt = SaveStringFromText (sbfp->suffix);
8368 MemFree (txt);
8369 */
8370 StringCat (str, sfx);
8371 StringCat (str, "\n");
8372 txt = StringSave (str);
8373 nsp = AuthorSpreadsheetStringToNameStdPtr (txt);
8374 MemFree (txt);
8375 pid->data = nsp;
8376 if (nsp != NULL) {
8377 if (StringHasNoText (nsp->names [0])) {
8378 ap = AuthorFree (ap);
8379 }
8380 }
8381 }
8382 }
8383 names->choice = 1;
8384 names->data.ptrvalue = ap;
8385 }
8386 if (ap == NULL) {
8387 alp = AuthListFree (alp);
8388 }
8389 if (alp != NULL) {
8390 PointerToDialog (sbfp->authors, (Pointer) alp);
8391 AuthListToConsortium (alp, sbfp->consortium);
8392 }
8393 }
8394 alp = AuthListFree (alp);
8395 }
8396
8397 static void SetSubmitterImportExportItems (SubmitFormPtr sbfp)
8398
8399 {
8400 IteM exportItm;
8401 IteM importItm;
8402
8403 if (sbfp != NULL) {
8404 importItm = FindFormMenuItem ((BaseFormPtr) sbfp, VIB_MSG_IMPORT);
8405 exportItm = FindFormMenuItem ((BaseFormPtr) sbfp, VIB_MSG_EXPORT);
8406 switch (sbfp->currentPage) {
8407 case SUBMISSION_PAGE :
8408 SafeSetTitle (importItm, "Import Submitter Info...");
8409 SafeSetTitle (exportItm, "Export Submitter Info...");
8410 SafeEnable (importItm);
8411 SafeEnable (exportItm);
8412 break;
8413 case CONTACT_PAGE :
8414 SafeSetTitle (importItm, "Import Contact...");
8415 SafeSetTitle (exportItm, "Export Contact...");
8416 SafeEnable (importItm);
8417 SafeEnable (exportItm);
8418 break;
8419 case AUTHOR_PAGE :
8420 SafeSetTitle (importItm, "Import Authors...");
8421 SafeSetTitle (exportItm, "Export Authors...");
8422 SafeEnable (importItm);
8423 SafeEnable (exportItm);
8424 break;
8425 case AFFILIATION_PAGE :
8426 SafeSetTitle (importItm, "Import Affiliation...");
8427 SafeSetTitle (exportItm, "Export Affiliation...");
8428 SafeEnable (importItm);
8429 SafeEnable (exportItm);
8430 break;
8431 default :
8432 break;
8433 }
8434 }
8435 }
8436
8437 static void EnterSubmitPage (SubmitFormPtr sbfp, Int2 page)
8438
8439 {
8440 AuthListPtr alp;
8441
8442 if (sbfp != NULL) {
8443 switch (page) {
8444 case SUBMISSION_PAGE :
8445 Select (sbfp->title);
8446 SafeSetTitle (sbfp->prevBtn, "<< Prev Form");
8447 SafeSetTitle (sbfp->nextBtn, "Next Page >>");
8448 break;
8449 case CONTACT_PAGE :
8450 Select (sbfp->firstname);
8451 sbfp->visitedContact = TRUE;
8452 SafeSetTitle (sbfp->prevBtn, "<< Prev Page");
8453 SafeSetTitle (sbfp->nextBtn, "Next Page >>");
8454 break;
8455 case AUTHOR_PAGE :
8456 alp = (AuthListPtr) DialogToPointer (sbfp->authors);
8457 alp = AddConsortiumToAuthList (alp, sbfp->consortium);
8458 if (sbfp->visitedContact && alp == NULL) {
8459 CopyContactToAuthors (sbfp);
8460 }
8461 AuthListFree (alp);
8462 /*
8463 if (sbfp->visitedContact && (! sbfp->visitedAuthor)) {
8464 CopyContactToAuthors (sbfp);
8465 }
8466 */
8467 SendMessageToDialog (sbfp->authors, VIB_MSG_ENTER);
8468 sbfp->visitedAuthor = TRUE;
8469 SafeSetTitle (sbfp->prevBtn, "<< Prev Page");
8470 SafeSetTitle (sbfp->nextBtn, "Next Page >>");
8471 break;
8472 case AFFILIATION_PAGE :
8473 SendMessageToDialog (sbfp->affil, VIB_MSG_ENTER);
8474 SafeSetTitle (sbfp->prevBtn, "<< Prev Page");
8475 SafeSetTitle (sbfp->nextBtn, "Next Form >>");
8476 break;
8477 default :
8478 break;
8479 }
8480 }
8481 }
8482
8483 static void ChangeSubmitFormPage (VoidPtr data, Int2 newval, Int2 oldval)
8484
8485 {
8486 SubmitFormPtr sbfp;
8487
8488 sbfp = (SubmitFormPtr) data;
8489 if (sbfp != NULL) {
8490 sbfp->currentPage = newval;
8491 SafeHide (sbfp->pages [oldval]);
8492 Update ();
8493 #ifdef WIN_MAC
8494 EnterSubmitPage (sbfp, newval);
8495 #endif
8496 SetSubmitterImportExportItems (sbfp);
8497 SafeShow (sbfp->pages [newval]);
8498 #ifndef WIN_MAC
8499 EnterSubmitPage (sbfp, newval);
8500 #endif
8501 Update ();
8502 switch (newval) {
8503 case SUBMISSION_PAGE :
8504 SendHelpScrollMessage (helpForm, "Submitting Authors Form", "Submission Page");
8505 break;
8506 case CONTACT_PAGE :
8507 SendHelpScrollMessage (helpForm, "Submitting Authors Form", "Contact Page");
8508 break;
8509 case AUTHOR_PAGE :
8510 SendHelpScrollMessage (helpForm, "Submitting Authors Form", "Authors Page");
8511 break;
8512 case AFFILIATION_PAGE :
8513 SendHelpScrollMessage (helpForm, "Submitting Authors Form", "Affiliation Page");
8514 break;
8515 default :
8516 break;
8517 }
8518 }
8519 }
8520
8521 static void NextSubmitFormBtn (ButtoN b)
8522
8523 {
8524 SubmitFormPtr sbfp;
8525 CharPtr txt;
8526 Boolean ok = TRUE;
8527
8528 sbfp = (SubmitFormPtr) GetObjectExtra (b);
8529 if (sbfp != NULL) {
8530 if (sbfp->currentPage == 0)
8531 {
8532 txt = SaveStringFromText (sbfp->title);
8533 if (StringHasNoText (txt))
8534 {
8535 Message (MSG_ERROR, "You must supply a tentative title for your manuscript.");
8536 MemFree (txt);
8537 return;
8538 }
8539 MemFree (txt);
8540 }
8541 else if (sbfp->currentPage == 1)
8542 {
8543 txt = SaveStringFromText (sbfp->firstname);
8544 if (StringHasNoText (txt))
8545 {
8546 ok = FALSE;
8547 }
8548 MemFree (txt);
8549 txt = SaveStringFromText (sbfp->lastname);
8550 if (StringHasNoText (txt))
8551 {
8552 ok = FALSE;
8553 }
8554 MemFree (txt);
8555 if (!ok)
8556 {
8557 Message (MSG_ERROR, "You must supply a first and last name for the contact.");
8558 return;
8559 }
8560 }
8561 if (sbfp->currentPage < 3) {
8562 SetValue (sbfp->tbs, sbfp->currentPage + 1);
8563 } else if (sbfp->goToNext != NULL) {
8564 (sbfp->goToNext) (b);
8565 }
8566 }
8567 }
8568
8569 static void PrevSubmitFormBtn (ButtoN b)
8570
8571 {
8572 SubmitFormPtr sbfp;
8573
8574 sbfp = (SubmitFormPtr) GetObjectExtra (b);
8575 if (sbfp != NULL) {
8576 if (sbfp->currentPage > 0) {
8577 SetValue (sbfp->tbs, sbfp->currentPage - 1);
8578 } else if (sbfp->goToPrev != NULL) {
8579 (sbfp->goToPrev) (b);
8580 }
8581 }
8582 }
8583
8584 static void ChangeHup (GrouP g)
8585
8586 {
8587 Boolean hup;
8588 SubmitFormPtr sbfp;
8589
8590 sbfp = (SubmitFormPtr) GetObjectExtra (g);
8591 if (sbfp != NULL) {
8592 hup = (Boolean) (GetValue (sbfp->hup) == 2);
8593 if (hup) {
8594 SafeShow (sbfp->dateGrp);
8595 } else {
8596 SafeHide (sbfp->dateGrp);
8597 }
8598 }
8599 }
8600
8601 static CharPtr submitFormTabs [] = {
8602 "Submission", "Contact", "Authors", "Affiliation", NULL
8603 };
8604
8605 static void SubmitFormMessage (ForM f, Int2 mssg)
8606
8607 {
8608 SubmitFormPtr sbfp;
8609
8610 sbfp = (SubmitFormPtr) GetObjectExtra (f);
8611 if (sbfp != NULL) {
8612 switch (mssg) {
8613 case VIB_MSG_IMPORT :
8614 ImportSubmitForm (f, NULL);
8615 break;
8616 case VIB_MSG_EXPORT :
8617 ExportSubmitForm (f, NULL);
8618 break;
8619 case VIB_MSG_CUT :
8620 StdCutTextProc (NULL);
8621 break;
8622 case VIB_MSG_COPY :
8623 StdCopyTextProc (NULL);
8624 break;
8625 case VIB_MSG_PASTE :
8626 StdPasteTextProc (NULL);
8627 break;
8628 case VIB_MSG_DELETE :
8629 StdDeleteTextProc (NULL);
8630 break;
8631 default :
8632 if (sbfp->appmessage != NULL) {
8633 sbfp->appmessage (f, mssg);
8634 }
8635 break;
8636 }
8637 }
8638 }
8639
8640 static void InitSubmitterFormActivate (WindoW w)
8641
8642 {
8643 SubmitFormPtr sbfp;
8644
8645 sbfp = (SubmitFormPtr) GetObjectExtra (w);
8646 if (sbfp != NULL) {
8647 if (sbfp->activate != NULL) {
8648 sbfp->activate (w);
8649 }
8650 SetSubmitterImportExportItems (sbfp);
8651 }
8652 }
8653
8654 extern ForM CreateInitSubmitterForm (Int2 left, Int2 top, CharPtr title,
8655 BtnActnProc goToNext,
8656 BtnActnProc goBack,
8657 WndActnProc activateForm)
8658
8659 {
8660 GrouP c;
8661 GrouP g;
8662 GrouP h;
8663 GrouP j;
8664 GrouP m;
8665 GrouP n;
8666 GrouP q;
8667 SubmitFormPtr sbfp;
8668 StdEditorProcsPtr sepp;
8669 GrouP t;
8670 WindoW w;
8671 GrouP x;
8672 GrouP z;
8673 GrouP g1, g2;
8674 GrouP p;
8675 DatePtr dp;
8676
8677 w = NULL;
8678 sbfp = MemNew (sizeof (SubmitForm));
8679 if (sbfp != NULL) {
8680 w = FixedWindow (left, top, -10, -10, title, NULL);
8681 SetObjectExtra (w, sbfp, StdCleanupFormProc);
8682 sbfp->form = (ForM) w;
8683 sbfp->toform = SequinBlockPtrToSubmitForm;
8684 sbfp->fromform = SubmitFormToSequinBlockPtr;
8685 sbfp->testform = TestSubmitForm;
8686 sbfp->importform = ImportSubmitForm;
8687 sbfp->exportform = ExportSubmitForm;
8688 sbfp->formmessage = SubmitFormMessage;
8689
8690 #ifndef WIN_MAC
8691 CreateSqnInitialFormMenus (w);
8692 #endif
8693
8694 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
8695 if (sepp != NULL) {
8696 sbfp->appmessage = sepp->handleMessages;
8697 }
8698
8699 SetGroupSpacing (w, 10, 10);
8700
8701 j = HiddenGroup (w, -1, 0, NULL);
8702 SetGroupSpacing (j, 10, 10);
8703
8704 sbfp->tbs = CreateFolderTabs (j, submitFormTabs, 0, 0, 0,
8705 SYSTEM_FOLDER_TAB,
8706 ChangeSubmitFormPage, (Pointer) sbfp);
8707 sbfp->currentPage = SUBMISSION_PAGE;
8708
8709 sbfp->visitedContact = FALSE;
8710 sbfp->visitedAuthor = FALSE;
8711
8712 h = HiddenGroup (w, 0, 0, NULL);
8713
8714 q = HiddenGroup (h, -1, 0, NULL);
8715 SetGroupSpacing (q, 10, 20);
8716 m = HiddenGroup (q, -1, 0, NULL);
8717 g = HiddenGroup (m, 0, -4, NULL);
8718 SetGroupSpacing (g, 3, 10);
8719 StaticPrompt (g, "When may we release your sequence record?",
8720 0, stdLineHeight, programFont, 'l');
8721 sbfp->hup = HiddenGroup (g, 0, -2, ChangeHup);
8722 SetObjectExtra (sbfp->hup, sbfp, NULL);
8723 RadioButton (sbfp->hup, "Immediately After Processing");
8724 RadioButton (sbfp->hup, "Release Date:");
8725 SetValue (sbfp->hup, 1);
8726 sbfp->dateGrp = HiddenGroup (m, -1, 0, NULL);
8727 /* StaticPrompt (sbfp->dateGrp, "Release Date: ", 0, popupMenuHeight, programFont, 'l'); */
8728
8729 dp = DateCurr ();
8730 if (dp != NULL && dp->data[0] == 1) {
8731 sbfp->reldate = CreateDateDialogEx (sbfp->dateGrp, NULL, dp->data[1] + 1900, 10);
8732 } else {
8733 sbfp->reldate = CreateDateDialog (sbfp->dateGrp, NULL);
8734 }
8735 p = MultiLinePrompt (sbfp->dateGrp,
8736 "NOTE: Sequences must be released when the accession number or any portion of the sequence is published.",
8737 25 * stdCharWidth, programFont);
8738 AlignObjects (ALIGN_CENTER, (HANDLE) sbfp->reldate, (HANDLE) p, NULL);
8739 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) sbfp->dateGrp, NULL);
8740 Hide (sbfp->dateGrp);
8741 t = HiddenGroup (q, 1, 0, NULL);
8742 StaticPrompt (t, "Tentative title for manuscript (required)", 0, 0, programFont, 'c');
8743 sbfp->title = ScrollText (t, 25, 4, programFont, TRUE, NULL);
8744 AlignObjects (ALIGN_CENTER, (HANDLE) sbfp->reldate,
8745 (HANDLE) sbfp->title, (HANDLE) t, NULL);
8746 sbfp->pages [SUBMISSION_PAGE] = q;
8747 Hide (sbfp->pages [SUBMISSION_PAGE]);
8748
8749 q = HiddenGroup (h, -1, 0, NULL);
8750 SetGroupSpacing (q, 10, 20);
8751 n = HiddenGroup (q, 4, 0, NULL);
8752 SetGroupSpacing (n, -1, 2);
8753 StaticPrompt (n, "First Name", 0, 0, programFont, 'c');
8754 StaticPrompt (n, "M.I.", 0, 0, programFont, 'c');
8755 StaticPrompt (n, "Last Name", 0, 0, programFont, 'c');
8756 StaticPrompt (n, "Sfx", 0, 0, programFont, 'c');
8757 sbfp->firstname = DialogText (n, "", 8, NULL);
8758 sbfp->middleinit = DialogText (n, "", 4, NULL);
8759 sbfp->lastname = DialogText (n, "", 9, NULL);
8760 /*
8761 sbfp->suffix = DialogText (n, "", 3, NULL);
8762 sbfp->suffix = PopupList (n, TRUE, SuffixPopup_Callback);
8763 */
8764 sbfp->suffix = PopupList (n, TRUE, NULL);
8765 SetObjectExtra (sbfp->suffix, sbfp, NULL);
8766 InitEnumPopup (sbfp->suffix, name_suffix_alist, NULL);
8767 SetEnumPopup (sbfp->suffix, name_suffix_alist, 0);
8768
8769 sbfp->phonefaxemail = CreateExtAffilDialog (q, NULL, NULL, &x);
8770 Show (x);
8771 Show (sbfp->phonefaxemail);
8772 AlignObjects (ALIGN_CENTER, (HANDLE) n, (HANDLE) sbfp->phonefaxemail, NULL);
8773 sbfp->pages [CONTACT_PAGE] = q;
8774 Hide (sbfp->pages [CONTACT_PAGE]);
8775
8776 q = HiddenGroup (h, -1, 0, NULL);
8777 SetGroupSpacing (q, 10, 20);
8778 sbfp->authors = CreateAuthorDialog (q, 3, -1);
8779 z = HiddenGroup (q, 0, 2, NULL);
8780 g1 = HiddenGroup (z, 2, 0, NULL);
8781 StaticPrompt (g1, "Consortium", 0, stdLineHeight, programFont, 'l');
8782 sbfp->consortium = DialogText (g1, "", 16, NULL);
8783 g2 = HiddenGroup (z, 1, 0, NULL);
8784 MultiLinePrompt (g2, "The consortium field should be used when a "
8785 "consortium is responsible for the sequencing or "
8786 "publication of the data. Individual authors may "
8787 "be listed along with a consortium name.",
8788 25 * stdCharWidth, programFont);
8789 AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2, NULL);
8790 AlignObjects (ALIGN_CENTER, (HANDLE) sbfp->authors, (HANDLE) z, NULL);
8791 sbfp->pages [AUTHOR_PAGE] = q;
8792 Hide (sbfp->pages [AUTHOR_PAGE]);
8793
8794 q = HiddenGroup (h, -1, 0, NULL);
8795 SetGroupSpacing (q, 10, 20);
8796 sbfp->affil = CreateExtAffilDialog (q, NULL, &g, NULL);
8797 Show (g);
8798 Show (sbfp->affil);
8799 sbfp->pages [AFFILIATION_PAGE] = q;
8800 Hide (sbfp->pages [AFFILIATION_PAGE]);
8801
8802 c = HiddenGroup (w, 4, 0, NULL);
8803 SetGroupSpacing (c, 10, 2);
8804 sbfp->goToPrev = goBack;
8805 sbfp->prevBtn = PushButton (c, " << Prev Form ", PrevSubmitFormBtn);
8806 SetObjectExtra (sbfp->prevBtn, sbfp, NULL);
8807 sbfp->goToNext = goToNext;
8808 sbfp->nextBtn = PushButton (c, " Next Page >> ", NextSubmitFormBtn);
8809 SetObjectExtra (sbfp->nextBtn, sbfp, NULL);
8810
8811 AlignObjects (ALIGN_CENTER,
8812 (HANDLE) sbfp->pages [SUBMISSION_PAGE],
8813 (HANDLE) sbfp->pages [CONTACT_PAGE],
8814 (HANDLE) sbfp->pages [AUTHOR_PAGE],
8815 (HANDLE) sbfp->pages [AFFILIATION_PAGE],
8816 (HANDLE) sbfp->tbs, (HANDLE) c, NULL);
8817
8818 RealizeWindow (w);
8819
8820 SafeSetTitle (sbfp->prevBtn, "<< Prev Form");
8821 SafeSetTitle (sbfp->nextBtn, "Next Page >>");
8822
8823 sbfp->activate = activateForm;
8824 SetActivate (w, InitSubmitterFormActivate);
8825
8826 Show (sbfp->pages [sbfp->currentPage]);
8827 EnterSubmitPage (sbfp, sbfp->currentPage);
8828 }
8829 return (ForM) w;
8830 }
8831
8832 extern void AddCodonListTotRNA (tRNAPtr trna, ValNodePtr codons)
8833 {
8834 ValNodePtr vnp;
8835 Int2 j, k, q;
8836 Char str [8];
8837 Char ch;
8838 Uint1 codon [4];
8839 Uint1 code;
8840
8841 if (trna == NULL) return;
8842
8843 for (j = 0; j < 6; j++) {
8844 trna->codon [j] = 255;
8845 }
8846
8847 if (codons == NULL)
8848 {
8849 return;
8850 }
8851
8852 for (vnp = codons, j = 0; vnp != NULL && j < 6; vnp = vnp->next) {
8853 str [0] = '\0';
8854 StringNCpy_0 (str, (CharPtr) vnp->data.ptrvalue, sizeof (str));
8855 if (str [0] != '\0') {
8856 k = 0;
8857 q = 0;
8858 ch = str [k];
8859 while (ch != '\0' && q < 3) {
8860 ch = TO_UPPER (ch);
8861 if (StringChr ("ACGTU", ch) != NULL) {
8862 if (ch == 'U') {
8863 ch = 'T';
8864 }
8865 codon [q] = (Uint1) ch;
8866 q++;
8867 }
8868 k++;
8869 ch = str [k];
8870 }
8871 codon [q] = 0;
8872 if (q == 3) {
8873 code = IndexForCodon (codon, Seq_code_iupacna);
8874 if (code != INVALID_R