|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/sequin/sequin10.c |
source navigation diff markup identifier search freetext search file search |
1 /* sequin10.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: sequin10.c
27 *
28 * Author: Colleen Bollin
29 *
30 * Version Creation Date: 9/3/2003
31 *
32 * $Revision: 1.465 $
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 <sqnutils.h>
47 #include <subutil.h>
48 #include <explore.h>
49 #include <edutil.h>
50 #include <tofasta.h>
51 #include <gbftdef.h>
52 #include <gbfeat.h>
53 #include <biosrc.h>
54 #include <findrepl.h>
55 #include <asnenbin.h>
56 #include <cdrgn.h>
57 #define NLM_GENERATED_CODE_PROTO
58 #include <objmacro.h>
59 #include <macrodlg.h>
60 #include <macroapi.h>
61 #include <seqpanel.h>
62 #include <salpanel.h>
63 #include <alignmgr2.h>
64 #include <salpedit.h>
65
66 typedef struct deflineformdata {
67 FEATURE_FORM_BLOCK
68
69 ModifierItemLocalPtr modList;
70 ButtoN PNTR modifier_btns;
71 DeflineFeatureRequestList feature_requests;
72 ButtoN feature_btns[NumRemovableItems];
73 GrouP sourceListGrp;
74 PopuP customGrp;
75 ButtoN use_labels;
76 ButtoN keep_paren;
77 ButtoN exclude_sp;
78 ButtoN exclude_cf;
79 ButtoN exclude_aff;
80 ButtoN exclude_nr;
81 ButtoN allow_mod_at_end_of_taxname;
82 ButtoN include_country_extra;
83 ButtoN allow_semicolon_in_modifier;
84 GrouP clone_isolate_HIV_rule_num;
85 PopuP modLimit;
86 PopuP organelle_popup;
87 BioseqPtr target_bsp;
88 ButtoN modify_only_target;
89 ButtoN suppress_alt_splice_phrase;
90 ButtoN remove_subfeatures;
91 PopuP featurePopup;
92 GrouP featureOptsGrp;
93 GrouP optional_features_grp;
94 PopuP misc_feat_parse_rule;
95 GrouP promoter_type;
96 ButtoN alternate_splice_flag;
97 ButtoN use_ncrna_note;
98 ButtoN suppress_locus_tags;
99 ButtoN gene_cluster_opp_strand;
100 DialoG suppressed_feature_list;
101 GrouP suppressed_feature_grp;
102 } DefLineFormData, PNTR DefLineFormPtr;
103
104 static void DefLineFormMessageProc (ForM f, Int2 mssg)
105
106 {
107 DefLineFormPtr dlfp;
108
109 dlfp = (DefLineFormPtr) GetObjectExtra (f);
110 if (dlfp != NULL) {
111 if (dlfp->appmessage != NULL) {
112 dlfp->appmessage (f, mssg);
113 }
114 }
115 }
116
117 static void CleanupDefLineForm (
118 GraphiC g,
119 VoidPtr data
120 )
121
122 {
123 DefLineFormPtr dlfp;
124 Int4 i;
125
126 dlfp = (DefLineFormPtr) data;
127 if (dlfp != NULL) {
128 if (dlfp->modList != NULL)
129 {
130 for (i=0; i < NumDefLineModifiers (); i++)
131 {
132 ValNodeFree (dlfp->modList[i].values_seen);
133 }
134 MemFree (dlfp->modList);
135 }
136 dlfp->modifier_btns = MemFree (dlfp->modifier_btns);
137 }
138 StdCleanupFormProc (g, data);
139 }
140
141 static void ChangeCustomPopup (PopuP p)
142
143 {
144 DefLineFormPtr dlfp;
145
146 dlfp = (DefLineFormPtr) GetObjectExtra (p);
147 if (dlfp == NULL) return;
148 if (GetValue (p) == 1) {
149 SafeDisable (dlfp->sourceListGrp);
150 } else {
151 SafeEnable (dlfp->sourceListGrp);
152 }
153 }
154
155 static void ChangeFeaturePopup (PopuP p)
156 {
157 DefLineFormPtr dlfp;
158
159 dlfp = (DefLineFormPtr) GetObjectExtra (p);
160 if (dlfp == NULL) return;
161 if (GetValue (p) == 2 || GetValue (p) == 3)
162 {
163 SafeDisable (dlfp->featureOptsGrp);
164 SafeDisable (dlfp->suppressed_feature_grp);
165 SafeDisable (dlfp->optional_features_grp);
166 SafeDisable (dlfp->organelle_popup);
167 SafeDisable (dlfp->alternate_splice_flag);
168 }
169 else
170 {
171 SafeEnable (dlfp->featureOptsGrp);
172 SafeEnable (dlfp->suppressed_feature_grp);
173 SafeEnable (dlfp->optional_features_grp);
174 SafeEnable (dlfp->organelle_popup);
175 SafeEnable (dlfp->alternate_splice_flag);
176 }
177 }
178
179
180 static void DoAutoDefLine (ButtoN b)
181 {
182 DefLineFormPtr dlfp;
183 SeqEntryPtr sep;
184 ValNodePtr modifier_indices = NULL;
185 Int2 feature_index;
186 OrganismDescriptionModifiers odmp;
187 Int2 product_flag, feature_list_type;
188 Int4 i;
189 Boolean alternate_splice_flag;
190 Boolean gene_cluster_opp_strand;
191
192 dlfp = GetObjectExtra (b);
193 if (b == NULL) return;
194 Hide (dlfp->form);
195 WatchCursor ();
196 Update ();
197
198 InitOrganismDescriptionModifiers (&odmp, NULL);
199 odmp.use_labels = GetStatus (dlfp->use_labels);
200 odmp.keep_paren = GetStatus (dlfp->keep_paren);
201 odmp.exclude_sp = GetStatus (dlfp->exclude_sp);
202 odmp.exclude_cf = GetStatus (dlfp->exclude_cf);
203 odmp.exclude_aff = GetStatus (dlfp->exclude_aff);
204 odmp.exclude_nr = GetStatus (dlfp->exclude_nr);
205 odmp.include_country_extra = GetStatus (dlfp->include_country_extra);
206 odmp.use_modifiers = TRUE;
207 odmp.allow_semicolon_in_modifier = GetStatus (dlfp->allow_semicolon_in_modifier);
208 odmp.allow_mod_at_end_of_taxname = !GetStatus (dlfp->allow_mod_at_end_of_taxname);
209
210 if (dlfp->clone_isolate_HIV_rule_num == NULL)
211 {
212 odmp.clone_isolate_HIV_rule_num = clone_isolate_HIV_rule_want_both;
213 }
214 else
215 {
216 odmp.clone_isolate_HIV_rule_num = GetValue (dlfp->clone_isolate_HIV_rule_num);
217 }
218
219 if (GetValue (dlfp->customGrp) == 1)
220 {
221 /* take all features */
222 for (feature_index = 0; feature_index < NumDefLineModifiers (); feature_index++)
223 {
224 if (dlfp->modList[feature_index].any_present)
225 {
226 ValNodeAddInt (&modifier_indices, 0, feature_index);
227 }
228 }
229 }
230 else
231 {
232 /* take selected features */
233 for (feature_index = 0; feature_index < NumDefLineModifiers (); feature_index++)
234 {
235 if (GetStatus (dlfp->modifier_btns[feature_index]))
236 {
237 ValNodeAddInt (&modifier_indices, 0, feature_index);
238 }
239 }
240 }
241
242 feature_list_type = GetValue (dlfp->featurePopup);
243 switch (feature_list_type)
244 {
245 case DEFLINE_USE_FEATURES :
246 dlfp->feature_requests.feature_list_type = DEFLINE_USE_FEATURES;
247 break;
248 case DEFLINE_COMPLETE_SEQUENCE :
249 dlfp->feature_requests.feature_list_type = DEFLINE_COMPLETE_SEQUENCE;
250 break;
251 case DEFLINE_COMPLETE_GENOME :
252 dlfp->feature_requests.feature_list_type = DEFLINE_COMPLETE_GENOME;
253 break;
254 case DEFLINE_SEQUENCE :
255 dlfp->feature_requests.feature_list_type = DEFLINE_SEQUENCE;
256 break;
257 default:
258 dlfp->feature_requests.feature_list_type = DEFLINE_USE_FEATURES;
259 break;
260 }
261
262 for (i=0; i< NumRemovableItems; i++)
263 {
264 dlfp->feature_requests.keep_items[i]
265 = GetStatus (dlfp->feature_btns[i]);
266 }
267 if (GetValue (dlfp->promoter_type) == 1)
268 {
269 dlfp->feature_requests.add_fake_promoters = TRUE;
270 }
271 else
272 {
273 dlfp->feature_requests.add_fake_promoters = FALSE;
274 }
275
276 dlfp->feature_requests.suppress_alt_splice_phrase =
277 GetStatus (dlfp->suppress_alt_splice_phrase);
278
279 dlfp->feature_requests.use_ncrna_note =
280 GetStatus (dlfp->use_ncrna_note);
281
282 dlfp->feature_requests.remove_subfeatures =
283 GetStatus (dlfp->remove_subfeatures);
284
285 dlfp->feature_requests.suppress_locus_tags =
286 GetStatus (dlfp->suppress_locus_tags);
287
288 dlfp->feature_requests.misc_feat_parse_rule =
289 GetValue (dlfp->misc_feat_parse_rule);
290
291 dlfp->feature_requests.suppressed_feature_list = DialogToPointer (dlfp->suppressed_feature_list);
292
293 odmp.max_mods = GetValue (dlfp->modLimit);
294 if (odmp.max_mods > 1)
295 {
296 odmp.max_mods = odmp.max_mods - 1;
297 }
298 else
299 {
300 odmp.max_mods = -99;
301 }
302
303 product_flag = GetValue (dlfp->organelle_popup) - 1;
304 alternate_splice_flag = GetStatus (dlfp->alternate_splice_flag);
305 gene_cluster_opp_strand = GetStatus (dlfp->gene_cluster_opp_strand);
306
307 if (dlfp->target_bsp != NULL && GetStatus (dlfp->modify_only_target))
308 {
309 sep = GetBestTopParentForData (dlfp->input_entityID, dlfp->target_bsp);
310 }
311 else
312 {
313 sep = GetTopSeqEntryForEntityID (dlfp->input_entityID);
314 }
315 if (sep == NULL) return;
316
317 AutoDefForSeqEntry (sep, dlfp->input_entityID, &odmp, dlfp->modList, modifier_indices,
318 &dlfp->feature_requests, product_flag, alternate_splice_flag, gene_cluster_opp_strand);
319
320 dlfp->feature_requests.suppressed_feature_list = ValNodeFree (dlfp->feature_requests.suppressed_feature_list);
321 modifier_indices = ValNodeFree (modifier_indices);
322
323 ArrowCursor ();
324 Update ();
325 ObjMgrSetDirtyFlag (dlfp->input_entityID, TRUE);
326 ObjMgrSendMsg (OM_MSG_UPDATE, dlfp->input_entityID, 0, 0);
327 Remove (dlfp->form);
328 SeqEntrySetScope (NULL);
329 }
330
331 static void IsTricky (
332 BioSourcePtr biop,
333 Pointer userdata
334 )
335 {
336 Boolean PNTR pTricky;
337 static CharPtr long_name = "Human immunodeficiency virus";
338 static CharPtr short_name = "HIV-";
339 OrgModPtr mod;
340 OrgNamePtr onp;
341 SubSourcePtr ssp;
342
343 pTricky = (Boolean PNTR) userdata;
344 if (pTricky == NULL
345 || *pTricky
346 || biop == NULL
347 || biop->org == NULL
348 || biop->org->taxname == NULL
349 || biop->org->orgname == NULL
350 || biop->subtype == NULL)
351 {
352 return;
353 }
354 if (StringNICmp (biop->org->taxname, long_name, StringLen (long_name)) != 0
355 && StringNICmp (biop->org->taxname, short_name, StringLen (short_name)) != 0)
356 {
357 return;
358 }
359
360 onp = biop->org->orgname;
361 if (onp == NULL) return;
362 mod = onp->mod;
363 while (mod != NULL
364 && mod->subtype != ORGMOD_isolate)
365 {
366 mod = mod->next;
367 }
368 if (mod == NULL || mod->subname == NULL)
369 {
370 return;
371 }
372
373 ssp = biop->subtype;
374 while (ssp != NULL && ssp->subtype != SUBSRC_clone)
375 {
376 ssp = ssp->next;
377 }
378 if (ssp == NULL || ssp->name == NULL)
379 {
380 return;
381 }
382 *pTricky = TRUE;
383 return;
384 }
385
386 static Boolean HasTrickyHIVRecords (
387 SeqEntryPtr sep
388 )
389 {
390 Boolean has_tricky;
391
392 if (sep == NULL) return FALSE;
393
394 has_tricky = FALSE;
395 VisitBioSourcesInSep (sep, &has_tricky, IsTricky);
396 return has_tricky;
397 }
398
399
400 static GrouP CreateDefLineFormHIVRule (
401 GrouP h
402 )
403 {
404 GrouP hiv_rule;
405
406 hiv_rule = NormalGroup (h, 3, 0, "HIV rule", programFont, NULL);
407 RadioButton (hiv_rule, "Prefer Clone");
408 RadioButton (hiv_rule, "Prefer Isolate");
409 RadioButton (hiv_rule, "Want Both Isolate and Clone");
410 SetValue (hiv_rule, clone_isolate_HIV_rule_want_both);
411 return hiv_rule;
412 }
413
414 static PopuP CreateDefLineFormModLimitPopup (
415 GrouP q,
416 Int2 count
417 )
418 {
419 PopuP limit;
420 Int2 i;
421 Char str[10];
422
423 StaticPrompt (q, "Max modifiers per line", 0, popupMenuHeight, programFont, 'l');
424 limit = PopupList (q, TRUE, NULL);
425 PopupItem (limit, "no limit");
426 for (i = 1; i <= count; i++) {
427 sprintf (str, "%d", (int) i);
428 PopupItem (limit, str);
429 }
430
431 SetValue (limit, 1);
432
433 return limit;
434 }
435
436 static PopuP CreateDefLineFormModifierListPopuP (
437 GrouP q,
438 DefLineFormPtr dlfp
439 )
440 {
441 PopuP popup;
442 StaticPrompt (q, "Modifier List", 0, popupMenuHeight, programFont, 'l');
443 popup = PopupList (q, TRUE, ChangeCustomPopup);
444 SetObjectExtra (popup, dlfp, NULL);
445 PopupItem (popup, "All");
446 PopupItem (popup, "Custom");
447 SetValue (popup, 2);
448
449 return popup;
450 }
451
452 static void SetHIVRuleEnable (Handle a)
453 {
454 DefLineFormPtr dlfp;
455
456 dlfp = GetObjectExtra (a);
457 if (dlfp == NULL) return;
458 if (dlfp->clone_isolate_HIV_rule_num == NULL) return;
459 if (dlfp->modList == NULL) return;
460 if ((dlfp->modifier_btns [DEFLINE_POS_Clone] != NULL
461 && GetStatus (dlfp->modifier_btns [DEFLINE_POS_Clone]))
462 || (dlfp->modifier_btns [DEFLINE_POS_Isolate] != NULL
463 && GetStatus (dlfp->modifier_btns [DEFLINE_POS_Isolate])))
464 {
465 Disable (dlfp->clone_isolate_HIV_rule_num);
466 }
467 else
468 {
469 Enable (dlfp->clone_isolate_HIV_rule_num);
470 }
471 }
472
473 static GrouP CreateDefLineFormSourceGroup (
474 GrouP h,
475 DefLineFormPtr dlfp,
476 SeqEntryPtr sep
477 )
478 {
479 GrouP p, g, g1, r;
480 Int2 item_index, num_label_columns, num_item_rows;
481 Int2 num_item_columns, count = 0;
482 Char ch;
483 Boolean has_tricky;
484
485 p = NormalGroup (h, -1, 0, "SOURCE", programFont, NULL);
486 SetGroupSpacing (p, 10, 10);
487
488 count = 0;
489 for (item_index=0; item_index < NumDefLineModifiers (); item_index++)
490 {
491 if (dlfp->modList[item_index].any_present)
492 {
493 count++;
494 }
495 }
496
497 g = HiddenGroup (p, 4, 0, NULL);
498 SetGroupSpacing (g, 20, 10);
499 dlfp->customGrp = CreateDefLineFormModifierListPopuP (g, dlfp);
500 dlfp->modLimit = CreateDefLineFormModLimitPopup (g, count);
501 dlfp->use_labels = CheckBox (p, "Use labels", NULL);
502 SetStatus (dlfp->use_labels, TRUE);
503
504 num_item_rows = 6;
505 if (count > 18)
506 num_item_rows = 8;
507 if (count > 24)
508 num_item_rows = 10;
509 if (count > 30)
510 num_item_rows = 12;
511
512 num_item_columns = count / num_item_rows;
513 if (count % num_item_rows != 0) num_item_columns ++;
514
515 num_label_columns = 3;
516 if (count > 6)
517 num_label_columns --;
518 if (count > 12)
519 num_label_columns --;
520
521 dlfp->sourceListGrp = NormalGroup (p,
522 0,
523 4,
524 "Available Modifiers",
525 programFont, NULL);
526 SetGroupSpacing (dlfp->sourceListGrp, 10, 10);
527
528 for (item_index=0; item_index < NumDefLineModifiers (); item_index++)
529 {
530 if (dlfp->modList[item_index].any_present)
531 {
532 g1 = HiddenGroup (dlfp->sourceListGrp, num_label_columns, 0, NULL);
533 SetGroupSpacing (g1, 10, 10);
534 dlfp->modifier_btns[item_index] = CheckBox (g1,
535 DefLineModifiers[item_index].name,
536 (BtnActnProc) SetHIVRuleEnable);
537 SetObjectExtra (dlfp->modifier_btns [item_index], dlfp, NULL);
538 SetStatus (dlfp->modifier_btns [item_index],
539 dlfp->modList[item_index].required);
540
541 if (num_label_columns > 1)
542 {
543 StaticPrompt (g1,
544 dlfp->modList[item_index].status,
545 0, popupMenuHeight, programFont, 'l');
546 if (num_label_columns > 2)
547 {
548 if (StringLen (dlfp->modList[item_index].first_value_seen) > 50)
549 {
550 ch = dlfp->modList[item_index].first_value_seen [50];
551 dlfp->modList[item_index].first_value_seen [50] = 0;
552 }
553 else
554 {
555 ch = 0;
556 }
557 StaticPrompt (g1,
558 dlfp->modList[item_index].first_value_seen,
559 0, popupMenuHeight, programFont, 'l');
560 if (ch != 0)
561 {
562 dlfp->modList[item_index].first_value_seen [50] = ch;
563 }
564 }
565 }
566 }
567 else
568 {
569 dlfp->modifier_btns[item_index] = NULL;
570 dlfp->modList[item_index].required = FALSE;
571 }
572 }
573
574 Enable (dlfp->sourceListGrp);
575
576
577 has_tricky = HasTrickyHIVRecords (sep);
578 if (has_tricky)
579 {
580 dlfp->clone_isolate_HIV_rule_num = CreateDefLineFormHIVRule (p);
581 SetObjectExtra (dlfp->clone_isolate_HIV_rule_num, dlfp, NULL);
582 SetHIVRuleEnable (dlfp->clone_isolate_HIV_rule_num);
583 }
584 else
585 {
586 dlfp->clone_isolate_HIV_rule_num = NULL;
587 }
588 r = NormalGroup (p, 3, 0, "Other Options", programFont, NULL);
589 SetGroupSpacing (r, 10, 10);
590 dlfp->keep_paren = CheckBox (r, "Leave in parenthetical organism info", NULL);
591 SetStatus (dlfp->keep_paren, TRUE);
592 dlfp->include_country_extra = CheckBox (r, "Include text after colon in country", NULL);
593 SetStatus (dlfp->include_country_extra, FALSE);
594 dlfp->allow_semicolon_in_modifier = CheckBox (r, "Include text after semicolon in modifiers", NULL);
595 SetStatus (dlfp->allow_semicolon_in_modifier, FALSE);
596 dlfp->exclude_sp = CheckBox (r, "Do not apply modifier to 'sp.' organisms",
597 NULL);
598 SetStatus (dlfp->exclude_sp, ShouldExcludeSp (sep));
599 dlfp->exclude_cf = CheckBox (r, "Do not apply modifier to 'cf.' organisms",
600 NULL);
601 SetStatus (dlfp->exclude_cf, FALSE);
602
603 dlfp->exclude_aff = CheckBox (r, "Do not apply modifier to 'aff.' organisms",
604 NULL);
605 SetStatus (dlfp->exclude_aff, FALSE);
606 dlfp->exclude_nr = CheckBox (r, "Do not apply modifier to 'nr.' organisms", NULL);
607 SetStatus (dlfp->exclude_nr, FALSE);
608
609 dlfp->allow_mod_at_end_of_taxname = CheckBox (r, "Do not apply modifier to organisms with matching tax name value", NULL);
610 SetStatus (dlfp->allow_mod_at_end_of_taxname, TRUE);
611
612 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) dlfp->use_labels,
613 (HANDLE) dlfp->sourceListGrp,
614 (HANDLE) r,
615 (HANDLE) dlfp->clone_isolate_HIV_rule_num,
616 NULL);
617 return p;
618 }
619
620 static PopuP CreateDefLineFormOrganellePopup (
621 GrouP h
622 )
623 {
624 PopuP o;
625
626 o = PopupList (h, FALSE, NULL);
627 PopupItem (o, "No mitochondrial or chloroplast suffix");
628 PopupItem (o, "Nuclear gene(s) for mitochondrial product(s)");
629 PopupItem (o, "Nuclear gene(s) for chloroplast product(s)");
630 PopupItem (o, "Nuclear gene(s) for kinetoplast product(s)");
631 PopupItem (o, "Nuclear gene(s) for plastid product(s)");
632 PopupItem (o, "Nuclear gene(s) for chromoplast product(s)");
633 PopupItem (o, "Nuclear gene(s) for cyanelle product(s)");
634 PopupItem (o, "Nuclear gene(s) for apicoplast product(s)");
635 PopupItem (o, "Nuclear gene(s) for leucoplast product(s)");
636 PopupItem (o, "Nuclear gene(s) for proplastid product(s)");
637 PopupItem (o, "Nuclear genes based on CDS products");
638 SetValue (o, DEFAULT_ORGANELLE_CLAUSE + 1);
639 return o;
640 }
641
642 static GrouP CreateDefLineFormFeatureListPopuP (
643 GrouP g,
644 DefLineFormPtr dlfp
645 )
646 {
647 GrouP q;
648
649 q = HiddenGroup (g, 2, 0, NULL);
650 StaticPrompt (q, "Features or Complete", 0, popupMenuHeight, programFont, 'l');
651 dlfp->featurePopup = PopupList (q, TRUE, ChangeFeaturePopup);
652 SetObjectExtra (dlfp->featurePopup, dlfp, NULL);
653 PopupItem (dlfp->featurePopup, "List Features");
654 PopupItem (dlfp->featurePopup, "Complete Sequence");
655 PopupItem (dlfp->featurePopup, "Complete Genome");
656 PopupItem (dlfp->featurePopup, "Sequence");
657 SetValue (dlfp->featurePopup, 1);
658
659 return q;
660 }
661
662 static void SetMiscFeatRuleEnable (Handle a)
663 {
664 DefLineFormPtr dlfp;
665
666 if (a == NULL || ( dlfp = (DefLineFormPtr) GetObjectExtra (a)) == NULL)
667 {
668 return;
669 }
670 if (GetStatus (dlfp->feature_btns[RemovableNoncodingProductFeat]))
671 {
672 Enable (dlfp->misc_feat_parse_rule);
673 }
674 else
675 {
676 Disable (dlfp->misc_feat_parse_rule);
677 }
678 if (GetStatus (dlfp->feature_btns[RemovablePromoter]))
679 {
680 Enable (dlfp->promoter_type);
681 }
682 else
683 {
684 Disable (dlfp->promoter_type);
685 }
686 }
687
688 static GrouP CreateDefLineFormFeatureOptionsGroup (
689 GrouP h,
690 DefLineFormPtr dlfp
691 )
692 {
693 GrouP p, g1, s1, s2, k, k2;
694 Int4 i;
695 SeqEntryPtr sep;
696
697 p = NormalGroup (h, -1, 0, "FEATURES", programFont, NULL);
698 SetGroupSpacing (p, 10, 10);
699
700 g1 = HiddenGroup (p, 2, 0, NULL);
701 SetGroupSpacing (g1, 10, 10);
702 s1 = HiddenGroup (g1, -1, 0, NULL);
703 SetGroupSpacing (s1, 10, 10);
704 CreateDefLineFormFeatureListPopuP (s1, dlfp);
705 dlfp->organelle_popup = CreateDefLineFormOrganellePopup (s1);
706 dlfp->alternate_splice_flag = CheckBox (s1,
707 "Append 'alternatively spliced'", NULL);
708 dlfp->use_ncrna_note = CheckBox (s1, "Use ncRNA note if no class or product", NULL);
709 AlignObjects (ALIGN_CENTER, (HANDLE) dlfp->featurePopup,
710 (HANDLE) dlfp->organelle_popup,
711 (HANDLE) dlfp->use_ncrna_note,
712 (HANDLE) dlfp->alternate_splice_flag, NULL);
713
714 dlfp->optional_features_grp = NormalGroup (g1, 3, 0,
715 "Optional Features", programFont, NULL);
716 SetGroupSpacing (dlfp->optional_features_grp, 10, 10);
717 for (i=0; i < NumRemovableItems; i++)
718 {
719 if (i == 0 || i == 4 || i == 7)
720 {
721 k = HiddenGroup (dlfp->optional_features_grp, 0, 4, NULL);
722 SetGroupSpacing (k, 10, 10);
723 }
724 if (i != RemovableCDS)
725 {
726 dlfp->feature_btns[i] =
727 CheckBox (k, GetRemovableItemName (i),
728 (BtnActnProc) SetMiscFeatRuleEnable);
729 SetObjectExtra (dlfp->feature_btns[i], dlfp, NULL);
730 SetStatus (dlfp->feature_btns[i], FALSE);
731 if (i == RemovableNoncodingProductFeat) {
732 s2 = HiddenGroup (k, 2, 0, NULL);
733 StaticPrompt (s2, " ", 8, popupMenuHeight, programFont, 'l');
734 dlfp->misc_feat_parse_rule = PopupList (s2, TRUE, NULL);
735 PopupItem (dlfp->misc_feat_parse_rule, "Use comment before first semicolon");
736 PopupItem (dlfp->misc_feat_parse_rule, "Look for Noncoding Products");
737 SetValue (dlfp->misc_feat_parse_rule, 2);
738 Disable (dlfp->misc_feat_parse_rule);
739 } else if (i == RemovablePromoter) {
740 k2 = HiddenGroup (k, 2, 0, NULL);
741 SetGroupSpacing (k2, 10, 10);
742 StaticPrompt (k2, " ", 8, popupMenuHeight, programFont, 'l');
743 dlfp->promoter_type = HiddenGroup (k2, 0, 2, NULL);
744 RadioButton (dlfp->promoter_type, "All");
745 RadioButton (dlfp->promoter_type, "If present");
746 SetValue (dlfp->promoter_type, 1);
747 Disable (dlfp->promoter_type);
748 AlignObjects (ALIGN_CENTER, (HANDLE) dlfp->feature_btns[i],
749 (HANDLE) dlfp->promoter_type,
750 NULL);
751 }
752 }
753 }
754
755 dlfp->suppressed_feature_grp = NormalGroup (g1, -1, 0,
756 "Suppress Features", programFont, NULL);
757 sep = GetTopSeqEntryForEntityID(dlfp->input_entityID);
758 dlfp->suppressed_feature_list = FeatureSelectionDialogEx (dlfp->suppressed_feature_grp, TRUE, sep, NULL, NULL);
759
760 dlfp->featureOptsGrp = NormalGroup (g1, 0, 4, "Suppress", programFont, NULL);
761 SetGroupSpacing (dlfp->featureOptsGrp, 10, 10);
762 dlfp->remove_subfeatures = CheckBox (dlfp->featureOptsGrp, "Mobile element subfeatures", NULL);
763 SetStatus (dlfp->remove_subfeatures, FALSE);
764
765 dlfp->gene_cluster_opp_strand = CheckBox (dlfp->featureOptsGrp,
766 "Gene cluster/locus subfeatures (both strands)", NULL);
767 SetStatus (dlfp->gene_cluster_opp_strand, FALSE);
768
769 dlfp->suppress_locus_tags = CheckBox (dlfp->featureOptsGrp, "Locus tags", NULL);
770 SetStatus (dlfp->suppress_locus_tags, FALSE);
771
772 dlfp->suppress_alt_splice_phrase = CheckBox (dlfp->featureOptsGrp, "Alternative splice phrase", NULL);
773 SetStatus (dlfp->suppress_alt_splice_phrase, FALSE);
774
775 return p;
776 }
777
778 static void CreateDefLineForm (
779 BaseFormPtr bfp,
780 ModifierItemLocalPtr modList,
781 DeflineFeatureRequestList *feature_requests
782 )
783 {
784 DefLineFormPtr dlfp;
785 WindoW w;
786 GrouP h, k, g1, c, feat_opts;
787 ButtoN b;
788 SeqEntryPtr sep;
789
790 dlfp = MemNew (sizeof (DefLineFormData));
791 if (dlfp == NULL) return;
792 dlfp->input_entityID = bfp->input_entityID;
793 dlfp->input_itemID = bfp->input_itemID;
794 dlfp->input_itemtype = bfp->input_itemtype;
795
796 dlfp->modifier_btns = (ButtoN PNTR) MemNew (sizeof (ButtoN) * NumDefLineModifiers());
797
798 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
799
800 w = FixedWindow (-50, -33, -10, -10, "Automatic Definition Line",
801 StdCloseWindowProc);
802 SetObjectExtra (w, dlfp, CleanupDefLineForm);
803 dlfp->form = (ForM) w;
804 dlfp->formmessage = DefLineFormMessageProc;
805
806 dlfp->modList = modList;
807 dlfp->feature_requests = *feature_requests;
808
809 h = HiddenGroup (w, -1, 0, NULL);
810 SetGroupSpacing (h, 10, 10);
811
812 k = HiddenGroup (h, -1, 0, NULL);
813 SetGroupSpacing (k, 10, 10);
814 g1 = CreateDefLineFormSourceGroup (k, dlfp, sep);
815
816 feat_opts = CreateDefLineFormFeatureOptionsGroup (k, dlfp);
817 AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) feat_opts, NULL);
818
819 c = HiddenGroup (h, 4, 0, NULL);
820 b = DefaultButton (c, "Accept", DoAutoDefLine);
821 SetObjectExtra (b, dlfp, NULL);
822 PushButton (c, "Cancel", StdCancelButtonProc);
823
824 dlfp->target_bsp = GetBioseqGivenIDs (dlfp->input_entityID,
825 dlfp->input_itemID,
826 dlfp->input_itemtype);
827 dlfp->modify_only_target = CheckBox (c, "Only modify targeted record", NULL);
828 SetStatus (dlfp->modify_only_target, FALSE);
829 if (dlfp->target_bsp == NULL)
830 {
831 Disable (dlfp->modify_only_target);
832 }
833
834 AlignObjects (ALIGN_CENTER, (HANDLE) k,
835 (HANDLE) c, NULL);
836 RealizeWindow (w);
837 Show (w);
838 Update ();
839 }
840
841
842 /* The AddBestComboModifiersToModList function sets the modifiers
843 * selected by the FindBestCombo process as selected.
844 */
845 static void AddBestModifiersToModList (
846 ValNodePtr modifier_indices,
847 ModifierItemLocalPtr modList
848 )
849 {
850 ValNodePtr vnp;
851
852 for (vnp = modifier_indices; vnp != NULL; vnp = vnp->next)
853 {
854 modList[vnp->data.intvalue].required = TRUE;
855 }
856 }
857
858
859 extern void AutoDefEntityIDNoOptions (Uint2 entityID, Boolean use_modifiers)
860 {
861 SeqEntryPtr sep;
862 DeflineFeatureRequestList feature_requests;
863 ModifierItemLocalPtr modList;
864 ValNodePtr modifier_indices = NULL;
865 OrganismDescriptionModifiers odmp;
866 Int4 index;
867 ValNodePtr defline_clauses = NULL;
868
869 sep = GetTopSeqEntryForEntityID (entityID);
870 if (sep == NULL) return;
871
872 InitFeatureRequests (&feature_requests);
873
874 modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
875 if (modList == NULL) return;
876 SetRequiredModifiers (modList);
877 CountModifiers (modList, sep);
878
879 InitOrganismDescriptionModifiers (&odmp, sep);
880 odmp.use_modifiers = use_modifiers;
881
882 RemoveNucProtSetTitles (sep);
883 SeqEntrySetScope (sep);
884
885 BuildDefLineFeatClauseList (sep, entityID, &feature_requests,
886 DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE,
887 &defline_clauses);
888 if ( AreFeatureClausesUnique (defline_clauses))
889 {
890 modifier_indices = GetModifierIndicesFromModList (modList);
891 }
892 else
893 {
894 modifier_indices = FindBestModifiersForDeflineClauseList (defline_clauses, modList);
895 }
896
897 BuildDefinitionLinesFromFeatureClauseLists (defline_clauses, modList,
898 modifier_indices, &odmp);
899
900 DefLineFeatClauseListFree (defline_clauses);
901 if (modList != NULL)
902 {
903 for (index=0; index < NumDefLineModifiers (); index++)
904 {
905 ValNodeFree (modList[index].values_seen);
906 }
907 MemFree (modList);
908 }
909 modifier_indices = ValNodeFree (modifier_indices);
910
911 ClearProteinTitlesInNucProts (entityID, NULL);
912 InstantiateProteinTitles (entityID, NULL);
913 }
914
915
916 extern void AutoDefBaseFormCommon (
917 BaseFormPtr bfp,
918 Boolean use_form,
919 Boolean use_modifiers
920 )
921 {
922 SeqEntryPtr sep;
923 DeflineFeatureRequestList feature_requests;
924 ModifierItemLocalPtr modList;
925 ValNodePtr modifier_indices = NULL;
926 OrganismDescriptionModifiers odmp;
927 Int4 index;
928 ValNodePtr defline_clauses = NULL;
929
930 if (bfp == NULL) return;
931 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
932 if (sep == NULL) return;
933
934 InitFeatureRequests (&feature_requests);
935
936 modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
937 if (modList == NULL) return;
938 SetRequiredModifiers (modList);
939 CountModifiers (modList, sep);
940 if (use_form)
941 {
942 modifier_indices = FindBestModifiersEx (sep, modList, TRUE);
943 AddBestModifiersToModList ( modifier_indices, modList);
944 modifier_indices = ValNodeFree (modifier_indices);
945 CreateDefLineForm (bfp, modList, &feature_requests);
946 }
947 else
948 {
949 WatchCursor ();
950 Update ();
951 InitOrganismDescriptionModifiers (&odmp, sep);
952 odmp.use_modifiers = use_modifiers;
953
954 RemoveNucProtSetTitles (sep);
955 SeqEntrySetScope (sep);
956
957 BuildDefLineFeatClauseList (sep, bfp->input_entityID, &feature_requests,
958 DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE,
959 &defline_clauses);
960 if ( AreFeatureClausesUnique (defline_clauses))
961 {
962 modifier_indices = GetModifierIndicesFromModList (modList);
963 }
964 else
965 {
966 modifier_indices = FindBestModifiersForDeflineClauseList (defline_clauses, modList);
967 }
968
969 BuildDefinitionLinesFromFeatureClauseLists (defline_clauses, modList,
970 modifier_indices, &odmp);
971
972 DefLineFeatClauseListFree (defline_clauses);
973 if (modList != NULL)
974 {
975 for (index=0; index < NumDefLineModifiers (); index++)
976 {
977 ValNodeFree (modList[index].values_seen);
978 }
979 MemFree (modList);
980 }
981 modifier_indices = ValNodeFree (modifier_indices);
982
983 ClearProteinTitlesInNucProts (bfp->input_entityID, NULL);
984 InstantiateProteinTitles (bfp->input_entityID, NULL);
985
986 ArrowCursor ();
987 Update ();
988 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
989 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
990 SeqEntrySetScope (NULL);
991 }
992 }
993
994
995 static const Int4 s_auto_def_id_preferred_quals[] = {
996 DEFLINE_POS_Strain,
997 DEFLINE_POS_Clone,
998 DEFLINE_POS_Isolate,
999 DEFLINE_POS_Cultivar,
1000 DEFLINE_POS_Specimen_voucher,
1001 };
1002
1003 static const Int4 k_num_auto_def_id_preferred_quals = sizeof (s_auto_def_id_preferred_quals) / sizeof (Int4);
1004
1005 extern void AutoDefId (Uint2 entityID)
1006 {
1007 SeqEntryPtr sep;
1008 DeflineFeatureRequestList feature_requests;
1009 ModifierItemLocalPtr modList;
1010 ValNodePtr modifier_indices = NULL;
1011 OrganismDescriptionModifiers odmp;
1012 Int4 index;
1013 Boolean added_required = FALSE;
1014 ValNodePtr defline_clauses = NULL;
1015
1016 sep = GetTopSeqEntryForEntityID (entityID);
1017 if (sep == NULL) return;
1018
1019 InitFeatureRequests (&feature_requests);
1020
1021 modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
1022 if (modList == NULL) return;
1023 SetRequiredModifiers (modList);
1024 CountModifiers (modList, sep);
1025 /* first look for first modifier in list that is present on all sources */
1026 for (index = 0; index < k_num_auto_def_id_preferred_quals && !added_required; index++) {
1027 if (modList[s_auto_def_id_preferred_quals[index]].all_present) {
1028 modList[s_auto_def_id_preferred_quals[index]].required = TRUE;
1029 added_required = TRUE;
1030 }
1031 }
1032 /* if not found, then look for first modifier in list that is present on any sources */
1033 for (index = 0; index < k_num_auto_def_id_preferred_quals && !added_required; index++) {
1034 if (modList[s_auto_def_id_preferred_quals[index]].any_present) {
1035 modList[s_auto_def_id_preferred_quals[index]].required = TRUE;
1036 added_required = TRUE;
1037 }
1038 }
1039
1040 WatchCursor ();
1041 Update ();
1042 InitOrganismDescriptionModifiers (&odmp, sep);
1043 odmp.use_modifiers = TRUE;
1044
1045 RemoveNucProtSetTitles (sep);
1046 SeqEntrySetScope (sep);
1047
1048 BuildDefLineFeatClauseList (sep, entityID, &feature_requests,
1049 DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE,
1050 &defline_clauses);
1051 if ( AreFeatureClausesUnique (defline_clauses))
1052 {
1053 modifier_indices = GetModifierIndicesFromModList (modList);
1054 }
1055 else
1056 {
1057 modifier_indices = FindBestModifiersForDeflineClauseList (defline_clauses, modList);
1058 }
1059
1060 BuildDefinitionLinesFromFeatureClauseLists (defline_clauses, modList,
1061 modifier_indices, &odmp);
1062
1063 DefLineFeatClauseListFree (defline_clauses);
1064 if (modList != NULL)
1065 {
1066 for (index=0; index < NumDefLineModifiers (); index++)
1067 {
1068 ValNodeFree (modList[index].values_seen);
1069 }
1070 MemFree (modList);
1071 }
1072 modifier_indices = ValNodeFree (modifier_indices);
1073
1074 ClearProteinTitlesInNucProts (entityID, NULL);
1075 InstantiateProteinTitles (entityID, NULL);
1076
1077 }
1078
1079
1080 extern void AutoDefStrain (
1081 BaseFormPtr bfp
1082 )
1083 {
1084
1085 if (bfp == NULL) return;
1086
1087 WatchCursor ();
1088 Update ();
1089 AutoDefId (bfp->input_entityID);
1090
1091 ArrowCursor ();
1092 Update ();
1093 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1094 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1095 SeqEntrySetScope (NULL);
1096 }
1097
1098
1099 extern void AutoDefMiscFeat (
1100 BaseFormPtr bfp
1101 )
1102 {
1103 SeqEntryPtr sep;
1104 DeflineFeatureRequestList feature_requests;
1105 ModifierItemLocalPtr modList;
1106 ValNodePtr modifier_indices = NULL;
1107 OrganismDescriptionModifiers odmp;
1108 Int4 index;
1109 ValNodePtr defline_clauses = NULL;
1110
1111 if (bfp == NULL) return;
1112 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1113 if (sep == NULL) return;
1114
1115 InitFeatureRequests (&feature_requests);
1116 feature_requests.keep_items[RemovableNoncodingProductFeat] = TRUE;
1117
1118 modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
1119 if (modList == NULL) return;
1120 SetRequiredModifiers (modList);
1121 CountModifiers (modList, sep);
1122
1123 WatchCursor ();
1124 Update ();
1125 InitOrganismDescriptionModifiers (&odmp, sep);
1126 odmp.use_modifiers = TRUE;
1127
1128 RemoveNucProtSetTitles (sep);
1129 SeqEntrySetScope (sep);
1130
1131 BuildDefLineFeatClauseList (sep, bfp->input_entityID, &feature_requests,
1132 DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE,
1133 &defline_clauses);
1134 if ( AreFeatureClausesUnique (defline_clauses))
1135 {
1136 modifier_indices = GetModifierIndicesFromModList (modList);
1137 }
1138 else
1139 {
1140 modifier_indices = FindBestModifiersForDeflineClauseList (defline_clauses, modList);
1141 }
1142
1143 BuildDefinitionLinesFromFeatureClauseLists (defline_clauses, modList,
1144 modifier_indices, &odmp);
1145
1146 DefLineFeatClauseListFree (defline_clauses);
1147 if (modList != NULL)
1148 {
1149 for (index=0; index < NumDefLineModifiers (); index++)
1150 {
1151 ValNodeFree (modList[index].values_seen);
1152 }
1153 MemFree (modList);
1154 }
1155 modifier_indices = ValNodeFree (modifier_indices);
1156
1157 ClearProteinTitlesInNucProts (bfp->input_entityID, NULL);
1158 InstantiateProteinTitles (bfp->input_entityID, NULL);
1159
1160 ArrowCursor ();
1161 Update ();
1162 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1163 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1164 SeqEntrySetScope (NULL);
1165 }
1166
1167
1168 static void AutoDefCommon (IteM i, Boolean use_form, Boolean use_modifiers)
1169 {
1170 BaseFormPtr bfp;
1171
1172 #ifdef WIN_MAC
1173 bfp = currentFormDataPtr;
1174 #else
1175 bfp = GetObjectExtra (i);
1176 #endif
1177 if (bfp == NULL || bfp->input_entityID == 0) return;
1178 AutoDefBaseFormCommon (bfp, use_form, use_modifiers);
1179 }
1180
1181 extern void AutoDef (IteM i)
1182 {
1183 AutoDefCommon (i, FALSE, TRUE);
1184 }
1185
1186 extern void AutoDefWithOptions (IteM i)
1187 {
1188 AutoDefCommon (i, TRUE, TRUE);
1189 }
1190
1191
1192 extern void AutoDefWithoutModifiers (IteM i)
1193 {
1194 AutoDefCommon (i, FALSE, FALSE);
1195 }
1196
1197 extern void AutoDefToolBtn (ButtoN b)
1198 {
1199 BaseFormPtr bfp;
1200
1201 bfp = (BaseFormPtr) GetObjectExtra (b);
1202 if (bfp == NULL) return;
1203 AutoDefBaseFormCommon (bfp, FALSE, TRUE);
1204 }
1205
1206 extern void AutoDefOptionsToolBtn (ButtoN b)
1207 {
1208 BaseFormPtr bfp;
1209
1210 bfp = (BaseFormPtr) GetObjectExtra (b);
1211 if (bfp == NULL) return;
1212 AutoDefBaseFormCommon (bfp, TRUE, TRUE);
1213 }
1214
1215
1216 extern void AutoDefStrainToolBtn (ButtoN b)
1217 {
1218 BaseFormPtr bfp;
1219
1220 bfp = (BaseFormPtr) GetObjectExtra (b);
1221 if (bfp == NULL) return;
1222 AutoDefStrain (bfp);
1223 }
1224
1225
1226 extern void AutoDefMiscFeatToolBtn (ButtoN b)
1227 {
1228 BaseFormPtr bfp;
1229
1230 bfp = (BaseFormPtr) GetObjectExtra (b);
1231 if (bfp == NULL) return;
1232 AutoDefMiscFeat (bfp);
1233 }
1234
1235
1236 static void TrimQuotesAroundString (CharPtr str)
1237 {
1238 Int4 len;
1239 CharPtr src, dst;
1240
1241 if (StringHasNoText (str) || *str != '"') return;
1242 len = StringLen (str);
1243 if (str[len - 1] != '"') return;
1244 src = str + 1;
1245 dst = str;
1246 while (*src != '"')
1247 {
1248 *dst = *src;
1249 dst++;
1250 src++;
1251 }
1252 *dst = 0;
1253 }
1254
1255
1256 typedef struct tablelinedata {
1257 Int4 num_parts;
1258 ValNodePtr parts;
1259 } TableLineData, PNTR TableLinePtr;
1260
1261 static TableLinePtr MakeTableData (CharPtr line, ValNodePtr PNTR special_list)
1262 {
1263 TableLinePtr tlp;
1264 CharPtr p_start, p_end;
1265 Int4 plen;
1266 Boolean found_end;
1267 CharPtr val;
1268 ValNodePtr vnp;
1269
1270 if (line == NULL) return NULL;
1271 tlp = MemNew (sizeof (TableLineData));
1272 if (tlp == NULL) return NULL;
1273 p_start = line;
1274 found_end = FALSE;
1275 while (*p_start != 0 && !found_end)
1276 {
1277 plen = StringCSpn (p_start, "\t\n");
1278 if (plen == 0)
1279 {
1280 ValNodeAddStr (&tlp->parts, 0, StringSave (""));
1281 tlp->num_parts ++;
1282 p_start++;
1283 if (*p_start == 0) {
1284 if (tlp->num_parts > 0)
1285 {
1286 ValNodeAddStr (&tlp->parts, 0, StringSave (""));
1287 tlp->num_parts ++;
1288 }
1289 }
1290 continue;
1291 }
1292 if (plen == StringLen (p_start))
1293 {
1294 found_end = TRUE;
1295 }
1296 else
1297 {
1298 p_end = p_start + plen;
1299 *p_end = 0;
1300 }
1301 TrimSpacesAroundString (p_start);
1302 TrimQuotesAroundString (p_start);
1303 val = StringSave (p_start);
1304
1305 vnp = ValNodeAddStr (&tlp->parts, 0, val);
1306 SpecialCharFindWithContext ((CharPtr PNTR)&(vnp->data.ptrvalue), special_list, NULL, NULL);
1307 tlp->num_parts ++;
1308 if (!found_end)
1309 {
1310 p_start = p_end + 1;
1311 }
1312 }
1313 if (tlp->num_parts == 0)
1314 {
1315 MemFree (tlp);
1316 return NULL;
1317 }
1318 return tlp;
1319 }
1320
1321 static void CleanUpTableData (ValNodePtr vnp)
1322 {
1323 TableLinePtr tlp;
1324 ValNodePtr vnp_next;
1325
1326 while (vnp != NULL)
1327 {
1328 vnp_next = vnp->next;
1329 vnp->next = NULL;
1330 tlp = vnp->data.ptrvalue;
1331 if (tlp != NULL)
1332 {
1333 ValNodeFreeData (tlp->parts);
1334 }
1335 vnp = ValNodeFree (vnp);
1336 vnp = vnp_next;
1337 }
1338 }
1339
1340 static void FormatPopupWithTableDataColumns (PopuP p, ValNodePtr header_line)
1341 {
1342 TableLinePtr tlp;
1343 ValNodePtr vnp;
1344 CharPtr val_fmt = "Column %d (%s)";
1345 CharPtr val;
1346 Int4 col = 1;
1347
1348 if (p == NULL || header_line == NULL) return;
1349 tlp = (TableLinePtr) header_line->data.ptrvalue;
1350 while ((tlp == NULL || tlp->num_parts < 1) && header_line->next != NULL) {
1351 header_line = header_line->next;
1352 tlp = header_line->data.ptrvalue;
1353 }
1354 if (tlp == NULL || tlp->num_parts < 1) return;
1355 vnp = tlp->parts;
1356 while (vnp != NULL) {
1357 val = MemNew ((StringLen(val_fmt) + StringLen (vnp->data.ptrvalue) + 15) * sizeof (Char));
1358 sprintf (val, val_fmt, col, vnp->data.ptrvalue == NULL ? "" : vnp->data.ptrvalue);
1359 PopupItem (p, val);
1360 MemFree (val);
1361 vnp = vnp->next;
1362 col++;
1363 }
1364 }
1365
1366
1367 enum orgmodmatchtype
1368 {
1369 eMatchAccession = 1,
1370 eMatchLocalID,
1371 eMatchTaxName,
1372 eMatchTMSMART,
1373 eMatchBankIt,
1374 eMatchGeneral,
1375 eMatchNone
1376 };
1377
1378
1379 typedef struct orgmodtablecolumn {
1380 Int4 match_choice;
1381 ValNodePtr apply_choice;
1382 } OrgModTableColumnData, PNTR OrgModTableColumnPtr;
1383
1384
1385 static OrgModTableColumnPtr OrgModTableColumnFree (OrgModTableColumnPtr t)
1386 {
1387 if (t != NULL) {
1388 t->apply_choice = ValNodeFreeData (t->apply_choice);
1389 t = MemFree (t);
1390 }
1391 return t;
1392 }
1393
1394
1395 static ValNodePtr OrgModTableColumnListFree (ValNodePtr vnp)
1396 {
1397 ValNodePtr vnp_next;
1398
1399 while (vnp != NULL)
1400 {
1401 vnp_next = vnp->next;
1402 vnp->next = NULL;
1403 vnp->data.ptrvalue = OrgModTableColumnFree (vnp->data.ptrvalue);
1404 vnp = ValNodeFree (vnp);
1405 vnp = vnp_next;
1406 }
1407 return vnp;
1408 }
1409
1410
1411 typedef struct orgmodtablecolumndlg {
1412 DIALOG_MESSAGE_BLOCK
1413
1414 GrouP action_choice;
1415 PopuP match_choice;
1416 DialoG apply_choice;
1417
1418 Nlm_ChangeNotifyProc change_notify;
1419 Pointer change_userdata;
1420 } OrgModTableColumnDlgData, PNTR OrgModTableColumnDlgPtr;
1421
1422 static Pointer OrgModTableColumnDialogToData (DialoG d)
1423 {
1424 OrgModTableColumnPtr o;
1425 OrgModTableColumnDlgPtr dlg;
1426
1427 dlg = (OrgModTableColumnDlgPtr) GetObjectExtra (d);
1428 if (dlg == NULL) return NULL;
1429
1430 o = (OrgModTableColumnPtr) MemNew (sizeof (OrgModTableColumnData));
1431
1432 if (GetValue (dlg->action_choice) == 1)
1433 {
1434 o->match_choice = GetValue (dlg->match_choice);
1435 o->apply_choice = NULL;
1436 }
1437 else
1438 {
1439 o->match_choice = 0;
1440 o->apply_choice = DialogToPointer (dlg->apply_choice);
1441 }
1442 return o;
1443 }
1444
1445
1446 static void ChangeOrgModTableColumnMatchChoice (PopuP p)
1447 {
1448 OrgModTableColumnDlgPtr dlg;
1449
1450 dlg = (OrgModTableColumnDlgPtr) GetObjectExtra (p);
1451 if (dlg == NULL) return;
1452 if (dlg->change_notify != NULL)
1453 {
1454 (dlg->change_notify) (dlg->change_userdata);
1455 }
1456 }
1457
1458
1459 static void ChangeOrgModTableColumnActionChoice (GrouP g)
1460 {
1461 OrgModTableColumnDlgPtr dlg;
1462
1463 dlg = (OrgModTableColumnDlgPtr) GetObjectExtra (g);
1464 if (dlg == NULL) return;
1465
1466 if (GetValue (dlg->action_choice) == 1)
1467 {
1468 Enable (dlg->match_choice);
1469 Disable (dlg->apply_choice);
1470 }
1471 else
1472 {
1473 Enable (dlg->apply_choice);
1474 Disable (dlg->match_choice);
1475 }
1476 if (dlg->change_notify != NULL)
1477 {
1478 (dlg->change_notify) (dlg->change_userdata);
1479 }
1480 }
1481
1482
1483 static void OrgModTableColumnDataToDialog (DialoG d, Pointer data)
1484 {
1485 OrgModTableColumnPtr o;
1486 OrgModTableColumnDlgPtr dlg;
1487
1488 dlg = (OrgModTableColumnDlgPtr) GetObjectExtra (d);
1489 if (dlg == NULL) return;
1490
1491 o = (OrgModTableColumnPtr) data;
1492
1493 if (o == NULL)
1494 {
1495 SetValue (dlg->action_choice, 1);
1496 SetValue (dlg->match_choice, eMatchNone);
1497 PointerToDialog (dlg->apply_choice, NULL);
1498 }
1499 else
1500 {
1501 if (o->match_choice == 0)
1502 {
1503 SetValue (dlg->action_choice, 2);
1504 PointerToDialog (dlg->apply_choice, o->apply_choice);
1505 }
1506 else
1507 {
1508 SetValue (dlg->action_choice, 1);
1509 SetValue (dlg->match_choice, o->match_choice);
1510 }
1511 }
1512 ChangeOrgModTableColumnActionChoice (dlg->action_choice);
1513 }
1514
1515
1516 static DialoG
1517 OrgModTableColumnDialog
1518 (GrouP h,
1519 CharPtr value_string,
1520 Int4 num_blank,
1521 Nlm_ChangeNotifyProc change_notify,
1522 Pointer change_userdata)
1523 {
1524 OrgModTableColumnDlgPtr dlg;
1525 GrouP p, g;
1526 ValNodePtr qual_selection_list;
1527 CharPtr real_title;
1528 CharPtr title_fmt = "%s (%d are blank)";
1529
1530 dlg = (OrgModTableColumnDlgPtr) MemNew (sizeof (OrgModTableColumnDlgData));
1531
1532 if (num_blank > 0) {
1533 real_title = (CharPtr) MemNew (sizeof (Char) * (StringLen (title_fmt) + StringLen (value_string) + 15));
1534 sprintf (real_title, title_fmt, value_string, num_blank);
1535 } else {
1536 real_title = value_string;
1537 }
1538
1539 p = NormalGroup (h, 3, 0, real_title, programFont, NULL);
1540 SetObjectExtra (p, dlg, StdCleanupExtraProc);
1541
1542 if (real_title != value_string) {
1543 real_title = MemFree (real_title);
1544 }
1545
1546 dlg->dialog = (DialoG) p;
1547 dlg->fromdialog = OrgModTableColumnDialogToData;
1548 dlg->todialog = OrgModTableColumnDataToDialog;
1549 dlg->change_notify = change_notify;
1550 dlg->change_userdata = change_userdata;
1551
1552 dlg->action_choice = HiddenGroup (p, 0, 2, ChangeOrgModTableColumnActionChoice);
1553 SetObjectExtra (dlg->action_choice, dlg, NULL);
1554 SetGroupSpacing (dlg->action_choice, 10, 10);
1555 RadioButton (dlg->action_choice, "Match to");
1556 RadioButton (dlg->action_choice, "Apply to");
1557 SetValue (dlg->action_choice, 1);
1558
1559 g = HiddenGroup (p, 0, 3, NULL);
1560 /* list of matchable items */
1561 dlg->match_choice = PopupList (g, TRUE, ChangeOrgModTableColumnMatchChoice);
1562 SetObjectExtra (dlg->match_choice, dlg, NULL);
1563 PopupItem (dlg->match_choice, "Accession");
1564 PopupItem (dlg->match_choice, "Local ID");
1565 PopupItem (dlg->match_choice, "Organism Taxonomy Name");
1566 PopupItem (dlg->match_choice, "TMSMART ID");
1567 PopupItem (dlg->match_choice, "BankIt ID");
1568 PopupItem (dlg->match_choice, "General ID");
1569 PopupItem (dlg->match_choice, "None");
1570 SetValue (dlg->match_choice, eMatchNone);
1571
1572
1573 /* list of organism modifiers */
1574 qual_selection_list = GetSourceQualDescList (TRUE, TRUE, FALSE, FALSE);
1575
1576 ValNodeAddPointer (&qual_selection_list, 1, StringSave ("Tax Name"));
1577
1578 /* note - the ValNodeSelectionDialog will free the qual_selection_list when done */
1579 dlg->apply_choice = ValNodeSelectionDialog (g, qual_selection_list, 8, SourceQualValNodeName,
1580 ValNodeSimpleDataFree, SourceQualValNodeDataCopy,
1581 SourceQualValNodeMatch, "qual choice",
1582 change_notify, change_userdata, FALSE);
1583
1584 ChangeOrgModTableColumnActionChoice(dlg->action_choice);
1585 return (DialoG) p;
1586 }
1587
1588
1589 typedef struct orgmodloadformdata {
1590 FEATURE_FORM_BLOCK
1591
1592 ValNodePtr line_list;
1593 BioSourcePtr PNTR biop_list;
1594 DialoG PNTR columns;
1595 Int4 num_columns;
1596 Uint2 entityID;
1597 ButtoN replace_with_blank_btn;
1598 ButtoN accept_button;
1599 ButtoN leave_dlg_up_btn;
1600 DialoG taxname_options;
1601
1602 /* These members are for importing modifiers in the
1603 * submission dialogs.
1604 */
1605 SeqEntryPtr seq_list;
1606 Boolean done;
1607 Boolean mods_added;
1608
1609 } OrgModLoadFormData, PNTR OrgModLoadFormPtr;
1610
1611 static void SetFormModsEnable (Pointer userdata)
1612 {
1613 OrgModLoadFormPtr form_data;
1614 OrgModTableColumnPtr o;
1615 Boolean have_apply = FALSE;
1616 Boolean have_action = FALSE;
1617 Boolean have_apply_taxname = FALSE;
1618 Int4 column_index;
1619
1620 form_data = (OrgModLoadFormPtr) userdata;
1621 if (form_data == NULL) return;
1622
1623 for (column_index = 0;
1624 column_index < form_data->num_columns;
1625 column_index ++)
1626 {
1627 o = (OrgModTableColumnPtr) DialogToPointer (form_data->columns[column_index]);
1628 if (o == NULL) continue;
1629 if (o->match_choice > 0 && o->match_choice != eMatchNone)
1630 {
1631 have_action = TRUE;
1632 }
1633 else if (o->apply_choice != NULL)
1634 {
1635 have_apply = TRUE;
1636 if (o->apply_choice->choice > 0 && StringCmp (o->apply_choice->data.ptrvalue, "Tax Name") == 0)
1637 {
1638 have_apply_taxname = TRUE;
1639 }
1640 }
1641 o = OrgModTableColumnFree (o);
1642 }
1643
1644 if (have_apply_taxname)
1645 {
1646 Enable (form_data->taxname_options);
1647 }
1648 else
1649 {
1650 Disable (form_data->taxname_options);
1651 }
1652
1653 /* must have an action selected if there is more than one line */
1654 if ( ! have_action
1655 && form_data->line_list != NULL
1656 && form_data->line_list->next != NULL)
1657 {
1658 Disable (form_data->accept_button);
1659 return;
1660 }
1661
1662 if (have_apply)
1663 {
1664 Enable (form_data->accept_button);
1665 }
1666 else
1667 {
1668 Disable (form_data->accept_button);
1669 }
1670 }
1671
1672 static void CleanupOrgModLoadForm (
1673 GraphiC g,
1674 VoidPtr data
1675 )
1676 {
1677 OrgModLoadFormPtr form_data;
1678
1679 form_data = (OrgModLoadFormPtr)data;
1680 if (form_data == NULL) return;
1681 form_data->columns = MemFree (form_data->columns);
1682 CleanUpTableData (form_data->line_list);
1683 StdCleanupFormProc (g, data);
1684 }
1685
1686 static CharPtr genome_names[] =
1687 {
1688 "",
1689 "genomic",
1690 "chloroplast",
1691 "chromoplast",
1692 "kinteoplast",
1693 "mitochondrion",
1694 "plastid",
1695 "macronuclear",
1696 "extrachrom",
1697 "plasmid",
1698 "transposon",
1699 "insertion_seq",
1700 "cyanelle",
1701 "proviral",
1702 "virion",
1703 "nucleomorph",
1704 "apicoplast",
1705 "leucoplast",
1706 "proplastid",
1707 "endogenous_virus",
1708 "hydrogenosome",
1709 "chromosome",
1710 "chromatophore"
1711 };
1712
1713 static Uint1 GetGenomeValFromString (CharPtr value_string)
1714 {
1715 Uint1 genome_val;
1716
1717 if (StringHasNoText (value_string))
1718 {
1719 return 0;
1720 }
1721 for (genome_val = 1; genome_val < sizeof (genome_names); genome_val++)
1722 {
1723 if (StringICmp (value_string, genome_names[genome_val]) == 0)
1724 {
1725 return genome_val;
1726 }
1727 }
1728 return 0;
1729 }
1730
1731
1732 static void AddOneQualToOrg
1733 ( BioSourcePtr biop,
1734 CharPtr value_string,
1735 SourceQualDescPtr sqdp,
1736 ExistingTextPtr etp)
1737 {
1738 OrgRefPtr orp;
1739 OrgModPtr mod, last_mod;
1740 OrgNamePtr onp;
1741 SubSourcePtr ssp, last_ssp;
1742
1743 if (biop == NULL || value_string == NULL || sqdp == NULL) return;
1744
1745 orp = biop->org;
1746 if (orp == NULL) return;
1747
1748 if (sqdp->isOrgMod)
1749 {
1750 onp = orp->orgname;
1751 if (onp == NULL) {
1752 onp = OrgNameNew ();
1753 if (onp == NULL) return;
1754 orp->orgname = onp;
1755 }
1756 mod = onp->mod;
1757 last_mod = NULL;
1758 while (mod != NULL
1759 && mod->subtype != sqdp->subtype)
1760 {
1761 last_mod = mod;
1762 mod = mod->next;
1763 }
1764 if (mod != NULL)
1765 {
1766 if (StringHasNoText (value_string)) {
1767 if (last_mod == NULL) {
1768 onp->mod = mod->next;
1769 } else {
1770 last_mod->next = mod->next;
1771 }
1772 mod->next = NULL;
1773 mod = OrgModFree (mod);
1774 } else {
1775 mod->subname = HandleExistingText (mod->subname,
1776 StringSave (value_string),
1777 etp);
1778 }
1779 }
1780 else if (!StringHasNoText (value_string))
1781 {
1782 mod = OrgModNew ();
1783 mod->subtype = sqdp->subtype;
1784 mod->subname = StringSave (value_string);
1785 if (last_mod == NULL)
1786 {
1787 onp->mod = mod;
1788 }
1789 else
1790 {
1791 last_mod->next = mod;
1792 }
1793 }
1794 } else {
1795 ssp = biop->subtype;
1796 last_ssp = NULL;
1797 while (ssp != NULL && ssp->subtype != sqdp->subtype)
1798 {
1799 last_ssp = ssp;
1800 ssp = ssp->next;
1801 }
1802 if (ssp != NULL)
1803 {
1804 if (StringHasNoText (value_string)) {
1805 if (last_ssp == NULL) {
1806 biop->subtype = ssp->next;
1807 } else {
1808 last_ssp->next = ssp->next;
1809 }
1810 ssp->next = NULL;
1811 ssp = SubSourceFree (ssp);
1812 } else {
1813 ssp->name = HandleExistingText (ssp->name,
1814 StringSave (value_string),
1815 etp);
1816 }
1817 }
1818 else if (!StringHasNoText (value_string))
1819 {
1820 ssp = SubSourceNew ();
1821 ssp->subtype = sqdp->subtype;
1822 ssp->name = StringSave (value_string);
1823 if (last_ssp == NULL)
1824 {
1825 biop->subtype = ssp;
1826 }
1827 else
1828 {
1829 last_ssp->next = ssp;
1830 }
1831 }
1832 }
1833 }
1834
1835 static void ApplyTaxNameToOrg (BioSourcePtr biop, CharPtr value_string, ExistingTextPtr etp)
1836 {
1837 if (biop == NULL) return;
1838 if (biop->org == NULL)
1839 {
1840 biop->org = OrgRefNew ();
1841 }
1842 if (biop->org == NULL) return;
1843 biop->org->taxname = HandleExistingText (biop->org->taxname,
1844 StringSave (value_string),
1845 etp);
1846 }
1847
1848 static void ApplyLocationToOrg (BioSourcePtr biop, CharPtr value_string)
1849 {
1850 if (biop != NULL)
1851 {
1852 biop->genome = GetGenomeValFromString (value_string);
1853 }
1854 }
1855
1856
1857 static Boolean HasExtraAccession (
1858 CharPtr acc_str,
1859 GBBlockPtr gbp)
1860 {
1861 ValNodePtr vnp;
1862 if (acc_str == NULL || gbp == NULL) return FALSE;
1863 for (vnp = gbp->extra_accessions;
1864 vnp != NULL && StringCmp (acc_str, vnp->data.ptrvalue) != 0;
1865 vnp = vnp->next)
1866 {}
1867 if (vnp != NULL)
1868 return TRUE;
1869 else
1870 return FALSE;
1871 }
1872
1873 static Boolean
1874 IDIsInTextList
1875 (CharPtr id,
1876 CharPtr acc_str,
1877 Boolean look_for_tmsmart)
1878 {
1879 CharPtr wanted, found;
1880 Int4 len;
1881
1882 if (id == NULL || acc_str == NULL) return FALSE;
1883
1884 if (StringNCmp (acc_str, "TMSMART:", 8) == 0) {
1885 if (look_for_tmsmart) {
1886 wanted = acc_str + 8;
1887 } else {
1888 return FALSE;
1889 }
1890 } else {
1891 if (look_for_tmsmart) {
1892 return FALSE;
1893 } else {
1894 wanted = acc_str;
1895 }
1896 }
1897 len = StringLen (wanted);
1898 found = StringStr (id, wanted);
1899 if (found == NULL) {
1900 return FALSE;
1901 } else if (*(found + len) != 0
1902 && *(found + len) != ','
1903 && ! isspace ((Int4)*(found + len))) {
1904 return FALSE;
1905 } else if (found != id
1906 && * (found - 1) != ','
1907 && ! isspace ((Int4)*(found - 1))) {
1908 return FALSE;
1909 } else {
1910 return TRUE;
1911 }
1912 }
1913
1914 static Boolean IDListHasValue (
1915 CharPtr id,
1916 SeqIdPtr list,
1917 Boolean only_local,
1918 Boolean look_for_tmsmart,
1919 Boolean look_for_general)
1920 {
1921 SeqIdPtr sip;
1922 Char acc_str [256];
1923 Int4 match_len, match_len2, db_len;
1924 DbtagPtr gnl_tag;
1925
1926 for (sip = list; sip != NULL; sip = sip->next)
1927 {
1928 if (sip->choice == SEQID_GENERAL
1929 && look_for_general
1930 && StringNICmp (id, "gnl|", 3) == 0
1931 && (db_len = StringCSpn (id + 4, "|")) > 0)
1932 {
1933 gnl_tag = (DbtagPtr) sip->data.ptrvalue;
1934 if (gnl_tag != NULL
1935 && StringNCmp (id + 4, gnl_tag->db, db_len) == 0
1936 && ((gnl_tag->tag->id > 0 && atoi (id + 5 + db_len) == gnl_tag->tag->id)
1937 || StringCmp (gnl_tag->tag->str, id + 5 + db_len) == 0))
1938 {
1939 return TRUE;
1940 }
1941 }
1942 if ((! only_local && sip->choice != SEQID_LOCAL)
1943 || (only_local && sip->choice == SEQID_LOCAL))
1944 {
1945 SeqIdWrite (sip, acc_str, PRINTID_REPORT, sizeof (acc_str));
1946 if (look_for_tmsmart)
1947 {
1948 if (StringNCmp (acc_str, "TMSMART:", 8) == 0
1949 && StringCmp (id, acc_str + 8) == 0)
1950 {
1951 return TRUE;
1952 } else if (IDIsInTextList (id, acc_str, TRUE)) {
1953 return TRUE;
1954 }
1955 } else {
1956 if (only_local)
1957 {
1958 if (StringCmp (id, acc_str) == 0)
1959 {
1960 return TRUE;
1961 }
1962 }
1963 else
1964 {
1965 match_len = StringCSpn (acc_str, ".");
1966 match_len2 = StringCSpn (id, ".");
1967 if (match_len == match_len2
1968 && match_len > 0 && StringNCmp (id, acc_str, match_len) == 0)
1969 {
1970 return TRUE;
1971 }
1972 }
1973 }
1974 }
1975 }
1976 return FALSE;
1977 }
1978
1979
1980 static CharPtr FindBankitNumberInTableString (CharPtr table_string)
1981 {
1982 CharPtr bankit_start;
1983
1984 if (StringHasNoText (table_string))
1985 {
1986 return table_string;
1987 }
1988 bankit_start = table_string + StringSpn (table_string, " ");
1989 if (StringNICmp (bankit_start, "bankit", 6) == 0)
1990 {
1991 bankit_start += 6;
1992 bankit_start += StringSpn (bankit_start, " ");
1993 }
1994 return bankit_start;
1995 }
1996
1997
1998
1999 typedef struct applycolumn {
2000 ValNodePtr apply_choice;
2001 CharPtr apply_value;
2002 } ApplyColumnData, PNTR ApplyColumnPtr;
2003
2004
2005 static ApplyColumnPtr ApplyColumnFree (ApplyColumnPtr p)
2006 {
2007 if (p != NULL) {
2008 p->apply_value = MemFree (p->apply_value);
2009 p->apply_choice = ValNodeFreeData (p->apply_choice);
2010 p = MemFree (p);
2011 }
2012 return p;
2013 }
2014
2015
2016 static ValNodePtr ApplyColumnListFree (ValNodePtr vnp)
2017 {
2018 ValNodePtr vnp_next;
2019
2020 while (vnp != NULL) {
2021 vnp_next = vnp->next;
2022 vnp->next = NULL;
2023 vnp->data.ptrvalue = ApplyColumnFree (vnp->data.ptrvalue);
2024 vnp = ValNodeFree (vnp);
2025 vnp = vnp_next;
2026 }
2027 return vnp;
2028 }
2029
2030
2031 typedef struct tabletobiosource {
2032 ValNodePtr identifiers;
2033 ValNodePtr columns_to_apply;
2034 ValNodePtr biop_list;
2035 } TableToBioSourceData, PNTR TableToBioSourcePtr;
2036
2037
2038 static TableToBioSourcePtr TableToBioSourceFree (TableToBioSourcePtr t)
2039 {
2040 if (t != NULL) {
2041 t->identifiers = ValNodeFreeData (t->identifiers);
2042 t->columns_to_apply = ApplyColumnListFree (t->columns_to_apply);
2043 t->biop_list = ValNodeFree (t->biop_list);
2044 t = MemFree (t);
2045 }
2046 return t;
2047 }
2048
2049
2050 static ValNodePtr TableToBioSourceListFree (ValNodePtr vnp)
2051 {
2052 ValNodePtr vnp_next;
2053
2054 while (vnp != NULL)
2055 {
2056 vnp_next = vnp->next;
2057 vnp->next = NULL;
2058 vnp->data.ptrvalue = TableToBioSourceFree (vnp->data.ptrvalue);
2059 vnp = ValNodeFree (vnp);
2060 vnp = vnp_next;;
2061 }
2062 return vnp;
2063 }
2064
2065
2066 static TableToBioSourcePtr TableToBioSourceFromTableLine (OrgModTableColumnPtr PNTR o_list, Int4 num_columns, TableLinePtr tlp)
2067 {
2068 Int4 column_index;
2069 ValNodePtr part;
2070 TableToBioSourcePtr t;
2071 ApplyColumnPtr a;
2072
2073 if (o_list == NULL || tlp == NULL || tlp->parts == NULL) return NULL;
2074
2075 t = (TableToBioSourcePtr) MemNew (sizeof (TableToBioSourceData));
2076 for (column_index = 0, part = tlp->parts;
2077 column_index < num_columns;
2078 column_index ++)
2079 {
2080 if (o_list[column_index] == NULL) continue;
2081 if (o_list[column_index]->match_choice > 0
2082 && o_list[column_index]->match_choice != eMatchNone
2083 && part != NULL)
2084 {
2085 ValNodeAddPointer (&(t->identifiers), o_list[column_index]->match_choice, StringSave (part->data.ptrvalue));
2086 }
2087 else if (o_list[column_index]->apply_choice != NULL)
2088 {
2089 a = (ApplyColumnPtr) MemNew (sizeof (ApplyColumnData));
2090 a->apply_choice = SourceQualValNodeDataCopy (o_list[column_index]->apply_choice);
2091 if (part == NULL)
2092 {
2093 a->apply_value = StringSave ("");
2094 }
2095 else
2096 {
2097 a->apply_value = StringSave (part->data.ptrvalue);
2098 }
2099
2100 ValNodeAddPointer (&(t->columns_to_apply), 0, a);
2101 }
2102
2103 if (column_index < tlp->num_parts && part != NULL)
2104 {
2105 part = part->next;
2106 }
2107 }
2108 return t;
2109 }
2110
2111
2112 static ValNodePtr OrgModLoadFormToApplyList (OrgModLoadFormPtr f)
2113 {
2114 ValNodePtr line;
2115 ValNodePtr apply_list = NULL;
2116 Int4 column_index;
2117 OrgModTableColumnPtr PNTR o_list;
2118
2119 if (f == NULL) return NULL;
2120
2121 o_list = (OrgModTableColumnPtr PNTR) MemNew (f->num_columns * sizeof (OrgModTableColumnPtr));
2122 for (column_index = 0; column_index < f->num_columns; column_index++)
2123 {
2124 o_list[column_index] = (OrgModTableColumnPtr) DialogToPointer (f->columns[column_index]);
2125 }
2126
2127 for (line = f->line_list; line != NULL; line = line->next)
2128 {
2129 ValNodeAddPointer (&apply_list, 0, TableToBioSourceFromTableLine (o_list, f->num_columns, line->data.ptrvalue));
2130 }
2131
2132 for (column_index = 0; column_index < f->num_columns; column_index++)
2133 {
2134 o_list[column_index] = OrgModTableColumnFree (o_list[column_index]);
2135 }
2136 o_list = MemFree (o_list);
2137 return apply_list;
2138 }
2139
2140
2141 static void AddBioSourceToValNodeListIfNotAlreadyPresent (ValNodePtr PNTR list, BioSourcePtr biop)
2142 {
2143 ValNodePtr vnp;
2144
2145 if (list == NULL || biop == NULL) return;
2146
2147 vnp = *list;
2148 if (vnp == NULL) {
2149 ValNodeAddPointer (list, 0, biop);
2150 } else {
2151 while (vnp->next != NULL) {
2152 if (biop == vnp->data.ptrvalue) {
2153 return;
2154 }
2155 vnp = vnp->next;
2156 }
2157 vnp->next = ValNodeNew(NULL);
2158 vnp->next->choice = 0;
2159 vnp->next->data.ptrvalue = biop;
2160 }
2161 }
2162
2163
2164 static void FindOrganismsForTableToBioSourceByTaxName (BioSourcePtr biop, Pointer userdata)
2165 {
2166 ValNodePtr apply_list, vnp, vnp_id;
2167 TableToBioSourcePtr t;
2168
2169 if (biop == NULL || biop->org == NULL || userdata == NULL) return;
2170
2171 apply_list = (ValNodePtr) userdata;
2172 for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2173 {
2174 t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2175 for (vnp_id = t->identifiers; vnp_id != NULL; vnp_id = vnp_id->next)
2176 {
2177 if (vnp_id->choice == eMatchTaxName && StringCmp (biop->org->taxname, vnp_id->data.ptrvalue) == 0) {
2178 AddBioSourceToValNodeListIfNotAlreadyPresent (&(t->biop_list), biop);
2179 }
2180 }
2181 }
2182 }
2183
2184
2185 /* look for matches based on accession numbers, local IDs, or bankit IDs */
2186 static void FindOrganismsForTableToBioSourceByBioseq (BioseqPtr bsp, Pointer userdata)
2187 {
2188 ValNodePtr apply_list, vnp, vnp_id;
2189 TableToBioSourcePtr t;
2190 SeqDescrPtr sdp;
2191 GBBlockPtr gbp;
2192 BioSourcePtr biop;
2193 Boolean use_local_id, look_for_tmsmart, look_for_general;
2194 Char match_str [30];
2195 SeqIdPtr sip;
2196 DbtagPtr dp;
2197 ObjectIdPtr oip;
2198
2199 biop = GetBiopForBsp (bsp);
2200 if (biop == NULL || biop->org == NULL || userdata == NULL) return;
2201
2202 apply_list = (ValNodePtr) userdata;
2203
2204 /* Find GenBankBlockPtr for extra accessions */
2205 gbp = NULL;
2206 sdp = BioseqGetSeqDescr (bsp, Seq_descr_genbank, NULL);
2207 if (sdp != NULL)
2208 {
2209 gbp = sdp->data.ptrvalue;
2210 }
2211
2212 /* Find Bankit ID */
2213 match_str [0] = 0;
2214 for(sip = bsp->id; sip != NULL; sip = sip->next) {
2215 if(sip->choice == SEQID_GENERAL) {
2216 dp = (DbtagPtr) sip->data.ptrvalue;
2217 if(StringICmp(dp->db, "BankIt") == 0) {
2218 oip = dp->tag;
2219 sprintf (match_str, "%d", oip->id);
2220 break;
2221 }
2222 }
2223 }
2224
2225 for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2226 {
2227 t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2228 for (vnp_id = t->identifiers; vnp_id != NULL; vnp_id = vnp_id->next)
2229 {
2230 if (vnp_id->choice == eMatchAccession
2231 || vnp_id->choice == eMatchLocalID
2232 || vnp_id->choice == eMatchTMSMART
2233 || vnp_id->choice == eMatchGeneral)
2234 {
2235 if (vnp_id->choice == eMatchAccession
2236 || vnp_id->choice == eMatchTMSMART
2237 || vnp_id->choice == eMatchGeneral) {
2238 use_local_id = FALSE;
2239 } else {
2240 use_local_id = TRUE;
2241 }
2242 if (vnp_id->choice == eMatchTMSMART) {
2243 look_for_tmsmart = TRUE;
2244 } else {
2245 look_for_tmsmart = FALSE;
2246 }
2247
2248 if (vnp_id->choice == eMatchGeneral)
2249 {
2250 look_for_general = TRUE;
2251 }
2252 else
2253 {
2254 look_for_general = FALSE;
2255 }
2256
2257 if (IDListHasValue ( vnp_id->data.ptrvalue,
2258 bsp->id, use_local_id, look_for_tmsmart, look_for_general)
2259 || (! use_local_id &&
2260 HasExtraAccession ( vnp_id->data.ptrvalue, gbp)))
2261 {
2262 AddBioSourceToValNodeListIfNotAlreadyPresent (&(t->biop_list), biop);
2263 }
2264 }
2265 else if (vnp_id->choice == eMatchBankIt)
2266 {
2267 if (StringCmp (FindBankitNumberInTableString(vnp_id->data.ptrvalue),
2268 match_str) == 0) {
2269 AddBioSourceToValNodeListIfNotAlreadyPresent (&(t->biop_list), biop);
2270 }
2271 }
2272 }
2273 }
2274 }
2275
2276
2277 static void FindOrganismsForTableToBioSourceList (ValNodePtr apply_list, SeqEntryPtr sep)
2278 {
2279 VisitBioSourcesInSep (sep, apply_list, FindOrganismsForTableToBioSourceByTaxName);
2280 VisitBioseqsInSep (sep, apply_list, FindOrganismsForTableToBioSourceByBioseq);
2281
2282 }
2283
2284
2285 static Boolean ListOrganismsWithMultipleRows (ValNodePtr apply_list)
2286 {
2287 LogInfoPtr lip;
2288 ValNodePtr vnp, vnp_compare, vnp_biop, vnp_biop2;
2289 BioSourcePtr biop;
2290 TableToBioSourcePtr t, t2;
2291 Int4 row1_num, row2_num;
2292 Boolean rval;
2293
2294 lip = OpenLog ("Organisms Affected by More Than One Row");
2295 for (vnp = apply_list, row1_num = 0; vnp != NULL; vnp = vnp->next, row1_num++)
2296 {
2297 t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2298 if (t == NULL || t->biop_list == NULL) continue;
2299 for (vnp_biop = t->biop_list; vnp_biop != NULL; vnp_biop = vnp_biop->next)
2300 {
2301 biop = vnp_biop->data.ptrvalue;
2302 if (biop == NULL) continue;
2303 for (vnp_compare = vnp->next, row2_num = row1_num + 1; vnp_compare != NULL; vnp_compare = vnp_compare->next, row2_num++)
2304 {
2305 t2 = (TableToBioSourcePtr) vnp_compare->data.ptrvalue;
2306 for (vnp_biop2 = t2->biop_list; vnp_biop2 != NULL; vnp_biop2 = vnp_biop2->next)
2307 {
2308 if (vnp_biop2->data.ptrvalue == biop)
2309 {
2310 fprintf (lip->fp, "Two rows (%d and %d) match the same organism", row1_num, row2_num);
2311 if (t->identifiers != NULL && t->identifiers->data.ptrvalue != NULL
2312 && t2->identifiers != NULL && t2->identifiers->data.ptrvalue != NULL)
2313 {
2314 if (StringCmp (t->identifiers->data.ptrvalue, t2->identifiers->data.ptrvalue) == 0)
2315 {
2316 fprintf (lip->fp, " (both are %s).\n", t->identifiers->data.ptrvalue);
2317 }
2318 else
2319 {
2320 fprintf (lip->fp, " (%s and %s).\n", t->identifiers->data.ptrvalue, t2->identifiers->data.ptrvalue);
2321 }
2322 }
2323 else if (t->identifiers != NULL && t->identifiers->data.ptrvalue != NULL)
2324 {
2325 fprintf (lip->fp, " (%s).\n", t->identifiers->data.ptrvalue);
2326 }
2327 else if (t2->identifiers != NULL && t2->identifiers->data.ptrvalue != NULL)
2328 {
2329 fprintf (lip->fp, " (%s).\n", t2->identifiers->data.ptrvalue);
2330 }
2331 else
2332 {
2333 fprintf (lip->fp, ".\n");
2334 }
2335
2336 lip->data_in_log = TRUE;
2337 }
2338 }
2339 }
2340 }
2341 }
2342 rval = lip->data_in_log;
2343 CloseLog (lip);
2344 FreeLog (lip);
2345 return rval;
2346 }
2347
2348
2349 static Boolean ListRowsWithMultipleOrganisms (ValNodePtr apply_list)
2350 {
2351 LogInfoPtr lip;
2352 ValNodePtr vnp, vnp_id;
2353 TableToBioSourcePtr t;
2354 Boolean rval;
2355
2356 lip = OpenLog ("Rows with Multiple Organisms");
2357 for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2358 {
2359 t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2360 if (t == NULL || t->biop_list == NULL || t->biop_list->next == NULL || t->identifiers == NULL) continue;
2361 fprintf (lip->fp, "Row with the following match columns applies to %d organisms\n", ValNodeLen (t->biop_list));
2362 for (vnp_id = t->identifiers; vnp_id != NULL; vnp_id = vnp_id->next)
2363 {
2364 fprintf (lip->fp, "\t%s\n", vnp_id->data.ptrvalue);
2365 }
2366 lip->data_in_log = TRUE;
2367 }
2368
2369 rval = lip->data_in_log;
2370 CloseLog (lip);
2371 FreeLog (lip);
2372 return rval;
2373 }
2374
2375
2376 static void ListRowsWithoutOrganisms (ValNodePtr apply_list)
2377 {
2378 LogInfoPtr lip;
2379 ValNodePtr vnp, vnp_id;
2380 TableToBioSourcePtr t;
2381
2382 lip = OpenLog ("Rows without Organisms");
2383 for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2384 {
2385 t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2386 if (t == NULL || t->biop_list != NULL || t->identifiers == NULL) continue;
2387 for (vnp_id = t->identifiers; vnp_id != NULL; vnp_id = vnp_id->next)
2388 {
2389 fprintf (lip->fp, "No match found for %s\n", vnp_id->data.ptrvalue);
2390 lip->data_in_log = TRUE;
2391 }
2392 }
2393
2394 CloseLog (lip);
2395 FreeLog (lip);
2396 }
2397
2398
2399 /* This code is used to detect existing modifiers before a change is made */
2400 static void FindOneQualOnOrg
2401 ( BioSourcePtr biop,
2402 SourceQualDescPtr sqdp,
2403 GetSamplePtr gsp)
2404 {
2405 OrgModPtr mod;
2406 SubSourcePtr ssp;
2407
2408 if (biop == NULL || gsp == NULL || sqdp == NULL) return;
2409
2410 if (sqdp->isOrgMod)
2411 {
2412 if (biop->org == NULL
2413 || biop->org->orgname == NULL)
2414 {
2415 return;
2416 }
2417
2418 mod = biop->org->orgname->mod;
2419 while (mod != NULL
2420 && mod->subtype != sqdp->subtype)
2421 {
2422 mod = mod->next;
2423 }
2424 if (mod != NULL)
2425 {
2426 gsp->num_found ++;
2427 if (gsp->sample_text == NULL)
2428 {
2429 gsp->sample_text = StringSave (mod->subname);
2430 }
2431 else if (StringCmp (gsp->sample_text, mod->subname) != 0)
2432 {
2433 gsp->all_same = FALSE;
2434 }
2435 }
2436 }
2437 else
2438 {
2439 ssp = biop->subtype;
2440 while (ssp != NULL && ssp->subtype != sqdp->subtype)
2441 {
2442 ssp = ssp->next;
2443 }
2444 if (ssp != NULL)
2445 {
2446 gsp->num_found ++;
2447 if (gsp->sample_text == NULL)
2448 {
2449 gsp->sample_text = StringSave (ssp->name);
2450 }
2451 else if (StringCmp (gsp->sample_text, ssp->name) != 0)
2452 {
2453 gsp->all_same = FALSE;
2454 }
2455 }
2456 }
2457 }
2458
2459
2460 static GetSamplePtr DetectExistingModifiersForTableToBioSourceList (ValNodePtr apply_list, Boolean replace_with_blank)
2461 {
2462 ValNodePtr vnp, vnp_col, vnp_biop;
2463 TableToBioSourcePtr t;
2464 BioSourcePtr biop;
2465 ApplyColumnPtr a;
2466 GetSamplePtr gsp;
2467
2468 gsp = GetSampleNew ();
2469 for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2470 {
2471 t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2472 for (vnp_biop = t->biop_list; vnp_biop != NULL; vnp_biop = vnp_biop->next)
2473 {
2474 biop = vnp_biop->data.ptrvalue;
2475 for (vnp_col = t->columns_to_apply; vnp_col != NULL; vnp_col = vnp_col->next)
2476 {
2477 a = (ApplyColumnPtr) vnp_col->data.ptrvalue;
2478
2479 if (replace_with_blank || ! StringHasNoText (a->apply_value))
2480 {
2481 if (a->apply_choice->choice == 0 && a->apply_choice->data.ptrvalue != NULL)
2482 {
2483 FindOneQualOnOrg (biop, a->apply_choice->data.ptrvalue, gsp);
2484 }
2485 else if (a->apply_choice->choice > 0
2486 && (StringICmp (a->apply_choice->data.ptrvalue, "Tax Name") == 0
2487 || StringICmp (a->apply_choice->data.ptrvalue, "Organism") == 0))
2488
2489 {
2490 if (biop->org != NULL && !StringHasNoText (biop->org->taxname))
2491 {
2492 gsp->num_found ++;
2493 if (gsp->sample_text == NULL)
2494 {
2495 gsp->sample_text = StringSave (biop->org->taxname);
2496 }
2497 else if (StringCmp (gsp->sample_text, biop->org->taxname) != 0)
2498 {
2499 gsp->all_same = FALSE;
2500 }
2501 }
2502 }
2503 else if (a->apply_choice->choice > 0 && StringICmp (a->apply_choice->data.ptrvalue, "Location") == 0)
2504 {
2505 if (biop->genome > 0)
2506 {
2507 gsp->num_found ++;
2508 if (gsp->sample_text == NULL)
2509 {
2510 gsp->sample_text = StringSave (genome_names [biop->genome]);
2511 }
2512 else if (StringCmp (gsp->sample_text, genome_names [biop->genome]) != 0)
2513 {
2514 gsp->all_same = FALSE;
2515 }
2516 }
2517 }
2518 }
2519 }
2520 }
2521 }
2522 return gsp;
2523 }
2524
2525
2526 static void
2527 ApplyOneTableToBioSource
2528 (TableToBioSourcePtr t,
2529 Boolean replace_with_blank,
2530 ExistingTextPtr etp,
2531 TaxnameOptionsPtr taxname_options)
2532 {
2533 ValNodePtr vnp_col, vnp_biop;
2534 BioSourcePtr biop;
2535 ApplyColumnPtr a;
2536
2537 if (t == NULL || t->columns_to_apply == NULL || t->biop_list == NULL) return;
2538
2539 for (vnp_biop = t->biop_list; vnp_biop != NULL; vnp_biop = vnp_biop->next)
2540 {
2541 biop = (BioSourcePtr) vnp_biop->data.ptrvalue;
2542 if (biop == NULL) continue;
2543 for (vnp_col = t->columns_to_apply; vnp_col != NULL; vnp_col = vnp_col->next)
2544 {
2545 a = (ApplyColumnPtr) vnp_col->data.ptrvalue;
2546 if (a == NULL
2547 || a->apply_choice == NULL
2548 || (!replace_with_blank && StringHasNoText (a->apply_value))) continue;
2549
2550 if (a->apply_choice->choice == 0 && a->apply_choice->data.ptrvalue != NULL)
2551 {
2552 AddOneQualToOrg (biop, a->apply_value, a->apply_choice->data.ptrvalue,
2553 etp);
2554 }
2555 else if (a->apply_choice->choice > 0
2556 && (StringICmp (a->apply_choice->data.ptrvalue, "Tax Name") == 0
2557 || StringICmp (a->apply_choice->data.ptrvalue, "Organism") == 0))
2558 {
2559 ApplyTaxNameToOrg (biop, a->apply_value, etp);
2560 ApplyTaxnameOptionsToBioSource (biop, taxname_options);
2561 }
2562 else if (a->apply_choice->choice > 0 && StringICmp (a->apply_choice->data.ptrvalue, "Location") == 0)
2563 {
2564 ApplyLocationToOrg (biop, a->apply_value);
2565 }
2566 }
2567 }
2568 }
2569
2570
2571 static void
2572 ApplyTableToBioSourceList
2573 (ValNodePtr apply_list,
2574 Boolean replace_with_blank,
2575 ExistingTextPtr etp,
2576 TaxnameOptionsPtr taxname_options)
2577 {
2578 ValNodePtr vnp;
2579
2580 for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2581 {
2582 ApplyOneTableToBioSource (vnp->data.ptrvalue, replace_with_blank, etp, taxname_options);
2583 }
2584 }
2585
2586
2587 static void DoAcceptFormMods (ButtoN b)
2588 {
2589 OrgModLoadFormPtr form_data;
2590 SeqEntryPtr sep;
2591 GetSamplePtr gsp;
2592 ValNodePtr apply_list;
2593 Boolean replace_with_blank;
2594 ExistingTextPtr etp;
2595 TaxnameOptionsPtr taxname_options;
2596
2597 form_data = GetObjectExtra (b);
2598 if (form_data == NULL) return;
2599
2600 sep = GetTopSeqEntryForEntityID (form_data->entityID);
2601 if (sep == NULL) return;
2602
2603 replace_with_blank = GetStatus (form_data->replace_with_blank_btn);
2604 apply_list = OrgModLoadFormToApplyList (form_data);
2605 FindOrganismsForTableToBioSourceList (apply_list, sep);
2606 if (ListOrganismsWithMultipleRows (apply_list))
2607 {
2608 Message (MSG_ERROR, "Multiple rows in the table apply to the same organism! Table cannot be imported.");
2609 apply_list = TableToBioSourceListFree (apply_list);
2610 return;
2611 }
2612 ListRowsWithoutOrganisms (apply_list);
2613 if (ListRowsWithMultipleOrganisms (apply_list)) {
2614 if (ANS_CANCEL == Message (MSG_OKC, "Some rows in the table apply to more than one organism - continue?"))
2615 {
2616 apply_list = TableToBioSourceListFree (apply_list);
2617 return;
2618 }
2619 }
2620 gsp = DetectExistingModifiersForTableToBioSourceList (apply_list, replace_with_blank);
2621 etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
2622 gsp = GetSampleFree (gsp);
2623 if (etp != NULL && etp->existing_text_choice == eExistingTextChoiceCancel)
2624 {
2625 etp = MemFree (etp);
2626 apply_list = TableToBioSourceListFree (apply_list);
2627 return;
2628 }
2629 taxname_options = DialogToPointer (form_data->taxname_options);
2630 ApplyTableToBioSourceList (apply_list, replace_with_blank, etp, taxname_options);
2631 taxname_options = MemFree (taxname_options);
2632 etp = MemFree (etp);
2633 apply_list = TableToBioSourceListFree (apply_list);
2634
2635 Update ();
2636 ObjMgrSetDirtyFlag (form_data->entityID, TRUE);
2637 ObjMgrSendMsg (OM_MSG_UPDATE, form_data->entityID, 0, 0);
2638 if (!GetStatus (form_data->leave_dlg_up_btn))
2639 {
2640 Remove (form_data->form);
2641 }
2642 }
2643
2644
2645 static ValNodePtr ReadTableData (void)
2646 {
2647 Char path [PATH_MAX];
2648 Int4 max_columns;
2649 ValNodePtr header_line;
2650 ValNodePtr line_list;
2651 TableLinePtr tlp;
2652 ValNodePtr vnp;
2653 ReadBufferData rbd;
2654 CharPtr line;
2655 ValNodePtr special_list = NULL;
2656
2657 path [0] = '\0';
2658 if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return NULL;
2659
2660 rbd.fp = FileOpen (path, "r");
2661 if (rbd.fp == NULL) return NULL;
2662 rbd.current_data = NULL;
2663
2664 line_list = NULL;
2665 max_columns = 0;
2666 header_line = NULL;
2667 line = AbstractReadFunction (&rbd);
2668 while (line != NULL)
2669 {
2670 tlp = MakeTableData (line, &special_list);
2671 if (tlp != NULL)
2672 {
2673 vnp = ValNodeNew (line_list);
2674 if (vnp == NULL) return NULL;
2675 if (line_list == NULL) line_list = vnp;
2676 vnp->data.ptrvalue = tlp;
2677 if (tlp->num_parts > max_columns)
2678 {
2679 max_columns = tlp->num_parts;
2680 header_line = vnp;
2681 }
2682 }
2683 line = MemFree (line);
2684 line = AbstractReadFunction (&rbd);
2685 }
2686 FileClose (rbd.fp);
2687 if (special_list != NULL && !FixSpecialCharactersForStringsInList (special_list, "The table contains special characters\nand cannot be used until they are replaced.", FALSE))
2688 {
2689 line_list = ValNodeFreeData (line_list);
2690 header_line = NULL;
2691 }
2692 /* throw out all lines before header line */
2693 else if (header_line != line_list)
2694 {
2695 vnp = line_list;
2696 while (vnp != NULL && vnp->next != header_line)
2697 {
2698 vnp = vnp->next;
2699 }
2700 vnp->next = NULL;
2701 ValNodeFreeData (line_list);
2702 line_list = NULL;
2703 }
2704 special_list = FreeContextList (special_list);
2705 return header_line;
2706 }
2707
2708
2709 static Int4Ptr GetColumnBlankCounts (ValNodePtr header_line, Int4 num_columns)
2710 {
2711 ValNodePtr line_vnp, part_vnp;
2712 TableLinePtr tlp;
2713 Int4 i;
2714 Int4Ptr blank_list;
2715
2716 if (header_line == NULL || num_columns < 1) return NULL;
2717
2718 blank_list = (Int4Ptr) MemNew (sizeof (Int4) * num_columns);
2719
2720 for (line_vnp = header_line; line_vnp != NULL; line_vnp = line_vnp->next)
2721 {
2722 if (line_vnp->data.ptrvalue == NULL) continue;
2723 tlp = (TableLinePtr) line_vnp->data.ptrvalue;
2724 part_vnp = tlp->parts;
2725 for (i = 0; i < num_columns; i++)
2726 {
2727 if (part_vnp == NULL || StringHasNoText (part_vnp->data.ptrvalue))
2728 {
2729 blank_list[i]++;
2730 }
2731 if (part_vnp != NULL)
2732 {
2733 part_vnp = part_vnp->next;
2734 }
2735 }
2736 }
2737 return blank_list;
2738 }
2739
2740
2741 static void LoadOrganismModifierTableEx (IteM i, Boolean IsTaxConsult)
2742 {
2743 BaseFormPtr bfp;
2744 ValNodePtr header_line;
2745 ValNodePtr vnp;
2746 TableLinePtr tlp;
2747 WindoW w;
2748 GrouP h, g, k, c;
2749 OrgModLoadFormPtr form_data;
2750 Int4 index;
2751 Int4 max_columns;
2752 Int4Ptr blank_list = NULL;
2753 OrgModTableColumnData o;
2754
2755 #ifdef WIN_MAC
2756 bfp = currentFormDataPtr;
2757 #else
2758 bfp = GetObjectExtra (i);
2759 #endif
2760 if (bfp == NULL) return;
2761
2762 header_line = ReadTableData ();
2763 if (header_line == NULL || header_line->data.ptrvalue == NULL) return;
2764 tlp = header_line->data.ptrvalue;
2765 max_columns = 0;
2766 for (vnp = tlp->parts; vnp != NULL; vnp = vnp->next)
2767 {
2768 max_columns ++;
2769 }
2770
2771 form_data = MemNew (sizeof (OrgModLoadFormData));
2772 if (form_data == NULL) return;
2773 form_data->entityID = bfp->input_entityID;
2774 form_data->line_list = header_line;
2775
2776 form_data->num_columns = max_columns;
2777 form_data->columns = (DialoG PNTR) MemNew (max_columns * sizeof (DialoG));
2778
2779 /* now create a dialog to display values */
2780 w = FixedWindow (-50, -33, -10, -10, "Table Conversion", StdCloseWindowProc);
2781 SetObjectExtra (w, form_data, CleanupOrgModLoadForm);
2782 form_data->form = (ForM) w;
2783
2784 h = HiddenGroup (w, -1, 0, NULL);
2785 SetGroupSpacing (h, 10, 10);
2786 g = HiddenGroup (h, 3, 0, NULL);
2787
2788 /* pre-analyze table for blanks, so we can display the information in the column dialogs */
2789 blank_list = GetColumnBlankCounts (header_line, form_data->num_columns);
2790
2791 tlp = header_line->data.ptrvalue;
2792 for (index = 0, vnp = tlp->parts; index < max_columns; index++)
2793 {
2794 form_data->columns[index] = OrgModTableColumnDialog (g, vnp == NULL ? NULL : vnp->data.ptrvalue,
2795 blank_list == NULL ? 0 : blank_list[index],
2796 SetFormModsEnable, form_data);
2797 if (vnp != NULL) vnp = vnp->next;
2798 }
2799 blank_list = MemFree (blank_list);
2800 if (max_columns > 1 && IsTaxConsult)
2801 {
2802 o.match_choice = eMatchAccession;
2803 o.apply_choice = NULL;
2804 PointerToDialog (form_data->columns[0], &o);
2805 o.match_choice = 0;
2806 ValNodeAddPointer (&o.apply_choice, 1, "Tax Name");
2807 PointerToDialog (form_data->columns[1], &o);
2808 o.apply_choice = ValNodeFree (o.apply_choice);
2809 }
2810
2811 k = HiddenGroup (h, 1, 0, NULL);
2812 form_data->replace_with_blank_btn = CheckBox (k, "Erase current value when blank found in table", NULL);
2813
2814 form_data->taxname_options = TaxnameOptionsDialog (h, NULL, NULL);
2815 Disable (form_data->taxname_options);
2816
2817 c = HiddenGroup (h, 4, 0, NULL);
2818 form_data->accept_button = DefaultButton (c, "Accept", DoAcceptFormMods);
2819 SetObjectExtra (form_data->accept_button, form_data, NULL);
2820 PushButton (c, "Cancel", StdCancelButtonProc);
2821 form_data->leave_dlg_up_btn = CheckBox (c, "Leave Dialog Up", NULL);
2822
2823 SetFormModsEnable(form_data);
2824
2825 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) k, (HANDLE) form_data->taxname_options, (HANDLE) c, NULL);
2826
2827 RealizeWindow (w);
2828 Show (w);
2829 Update ();
2830 }
2831
2832 extern void LoadOrganismModifierTable (IteM i)
2833 {
2834 LoadOrganismModifierTableEx (i, FALSE);
2835 }
2836
2837 extern void LoadTaxConsult (IteM i)
2838 {
2839 LoadOrganismModifierTableEx (i, TRUE);
2840 }
2841
2842
2843 extern Boolean ReplaceImportModifierName (CharPtr PNTR orig_name, Int4 col_num)
2844 {
2845 ModalAcceptCancelData acd;
2846 WindoW w;
2847 Char title[128];
2848 GrouP g, k, c;
2849 ButtoN b;
2850 DialoG modifier_name_choice;
2851 ValNodePtr mod_name_choice_list = NULL, default_vnp, choice_vnp;
2852
2853 if (orig_name == NULL)
2854 {
2855 return FALSE;
2856 }
2857 acd.accepted = FALSE;
2858 acd.cancelled = FALSE;
2859
2860 sprintf (title, "Choose import modifier for column %d", col_num);
2861 w = MovableModalWindow(-20, -13, -10, -10, title, NULL);
2862 g = HiddenGroup (w, -1, 0, NULL);
2863
2864 k = NULL;
2865 if (!StringHasNoText (*orig_name))
2866 {
2867 k = HiddenGroup (g, 2, 0, NULL);
2868 StaticPrompt (k, "Unrecognized column name:", 0, popupMenuHeight, programFont, 'r');
2869 StaticPrompt (k, *orig_name, 0, popupMenuHeight, programFont, 'l');
2870 }
2871
2872 ValNodeAddPointer (&mod_name_choice_list, 1, StringSave ("Ignore Column"));
2873 mod_name_choice_list->next = GetSourceQualDescList (TRUE, TRUE, FALSE, FALSE);
2874 ValNodeAddPointer (&mod_name_choice_list, 2, StringSave ("Organism"));
2875 ValNodeAddPointer (&mod_name_choice_list, 3, StringSave ("Location"));
2876
2877 modifier_name_choice = ValNodeSelectionDialog (g, mod_name_choice_list, 6, SourceQualValNodeName,
2878 ValNodeSimpleDataFree, SourceQualValNodeDataCopy,
2879 SourceQualValNodeMatch, "feature list",
2880 NULL, NULL, FALSE);
2881 default_vnp = ValNodeNew (NULL);
2882 default_vnp->choice = 1;
2883 default_vnp->data.ptrvalue = StringSave ("Ignore Column");
2884 default_vnp->next = NULL;
2885 PointerToDialog (modifier_name_choice, default_vnp);
2886 default_vnp = ValNodeFreeData (default_vnp);
2887
2888 c = HiddenGroup (g, 2, 0, NULL);
2889 b = PushButton (c, "Accept", ModalAcceptButton);
2890 SetObjectExtra (b, &acd, NULL);
2891 b = PushButton (c, "Cancel", ModalCancelButton);
2892 SetObjectExtra (b, &acd, NULL);
2893 if (k == NULL)
2894 {
2895 AlignObjects (ALIGN_CENTER, (HANDLE) modifier_name_choice, (HANDLE) c, NULL);
2896 }
2897 else
2898 {
2899 AlignObjects (ALIGN_CENTER, (HANDLE) k, (HANDLE) modifier_name_choice, (HANDLE) c, NULL);
2900 }
2901 Show (w);
2902 Select (w);
2903 acd.accepted = FALSE;
2904 acd.cancelled = FALSE;
2905 while (!acd.accepted && ! acd.cancelled)
2906 {
2907 ProcessExternalEvent ();
2908 Update ();
2909 }
2910 ProcessAnEvent ();
2911 choice_vnp = (ValNodePtr) DialogToPointer (modifier_name_choice);
2912
2913 Remove (w);
2914 if (acd.cancelled)
2915 {
2916 return FALSE;
2917 }
2918 else
2919 {
2920 *orig_name = MemFree (*orig_name);
2921 if (choice_vnp != NULL && choice_vnp->choice != 1)
2922 {
2923 *orig_name = SourceQualValNodeName (choice_vnp);
2924 }
2925 return TRUE;
2926 }
2927 }
2928
2929
2930 static ValNodePtr FreeTableData (ValNodePtr lines)
2931 {
2932 TableLinePtr tlp;
2933
2934 if (lines == NULL)
2935 {
2936 return NULL;
2937 }
2938 lines->next = FreeTableData (lines->next);
2939 tlp = (lines->data.ptrvalue);
2940 if (tlp != NULL)
2941 {
2942 tlp->parts = ValNodeFreeData (tlp->parts);
2943 tlp = MemFree (tlp);
2944 lines->data.ptrvalue = NULL;
2945 }
2946 return ValNodeFree (lines);
2947 }
2948
2949
2950 typedef struct exportorgtable
2951 {
2952 ModifierItemLocalPtr modList;
2953 BioseqPtr bsp;
2954 Boolean list_tax_name;
2955 Boolean list_accession;
2956 Boolean list_local;
2957 Boolean list_general;
2958
2959 ValNodePtr organism_id_profile;
2960 FILE *fp;
2961 } ExportOrgTableData, PNTR ExportOrgTablePtr;
2962
2963 #define ORGANISM_ID_PROFILE_HAS_ACCESSION 1
2964 #define ORGANISM_ID_PROFILE_HAS_LOCAL 2
2965 #define ORGANISM_ID_PROFILE_HAS_GENERAL 4
2966 #define ORGANISM_ID_PROFILE_HAS_TAX_NAME 8
2967
2968 static void ExportOneOrganism (BioSourcePtr biop, Pointer userdata)
2969 {
2970 ExportOrgTablePtr eotp;
2971 Char acc_str [256];
2972 SeqIdPtr sip;
2973 SeqIdPtr acc_sip = NULL, local_sip = NULL, gen_sip = NULL;
2974 Int4 i;
2975 OrgModPtr mod;
2976 SubSourcePtr ssp;
2977 Boolean need_tab = FALSE;
2978
2979 if (biop == NULL || userdata == NULL) return;
2980 eotp = (ExportOrgTablePtr) userdata;
2981
2982 if (eotp->bsp == NULL || eotp->modList == NULL || eotp->fp == NULL) return;
2983
2984 for (sip = eotp->bsp->id;
2985 sip != NULL && (acc_sip == NULL || local_sip == NULL);
2986 sip = sip->next)
2987 {
2988 if (acc_sip == NULL && sip->choice == SEQID_GENBANK)
2989 {
2990 acc_sip = sip;
2991 }
2992 else if (local_sip == NULL && sip->choice == SEQID_LOCAL)
2993 {
2994 local_sip = sip;
2995 }
2996 else if (gen_sip == NULL && sip->choice == SEQID_GENERAL)
2997 {
2998 gen_sip = sip;
2999 }
3000 }
3001
3002 if (eotp->list_accession)
3003 {
3004 /* get accession number and print to column */
3005 if (acc_sip == NULL)
3006 {
3007 fprintf (eotp->fp, " ");
3008 }
3009 else
3010 {
3011 sip = acc_sip->next;
3012 acc_sip->next = NULL;
3013 SeqIdWrite (acc_sip, acc_str, PRINTID_TEXTID_ACC_VER, sizeof (acc_str));
3014 acc_sip->next = sip;
3015 fprintf (eotp->fp, "%s", acc_str);
3016 }
3017 need_tab = TRUE;
3018 }
3019
3020 if (eotp->list_local)
3021 {
3022 if (need_tab) {
3023 fprintf (eotp->fp, "\t");
3024 }
3025 /* get local ID and print to column */
3026 if (local_sip == NULL)
3027 {
3028 fprintf (eotp->fp, " ");
3029 }
3030 else
3031 {
3032 sip = local_sip->next;
3033 local_sip->next = NULL;
3034 SeqIdWrite (local_sip, acc_str, PRINTID_TEXTID_ACCESSION, sizeof (acc_str));
3035 local_sip->next = sip;
3036 fprintf (eotp->fp, "%s", acc_str);
3037 }
3038 need_tab = TRUE;
3039 }
3040
3041 if (eotp->list_general)
3042 {
3043 if (need_tab) {
3044 fprintf (eotp->fp, "\t");
3045 }
3046 /* get general ID and print to column */
3047 if (gen_sip == NULL)
3048 {
3049 fprintf (eotp->fp, " ");
3050 }
3051 else
3052 {
3053 sip = gen_sip->next;
3054 gen_sip->next = NULL;
3055 SeqIdWrite (gen_sip, acc_str, PRINTID_FASTA_GENERAL, sizeof (acc_str));
3056 gen_sip->next = sip;
3057 fprintf (eotp->fp, "%s", acc_str);
3058 }
3059 need_tab = TRUE;
3060 }
3061
3062 if (eotp->list_tax_name)
3063 {
3064 if (need_tab) {
3065 fprintf (eotp->fp, "\t");
3066 }
3067 /* get tax name and print to column */
3068 if (biop->org != NULL && ! StringHasNoText (biop->org->taxname))
3069 {
3070 fprintf (eotp->fp, "%s", biop->org->taxname);
3071 }
3072 else
3073 {
3074 fprintf (eotp->fp, " ");
3075 }
3076 need_tab = TRUE;
3077 }
3078
3079 /* print modifiers for each available column */
3080 for (i= 0; i < NumDefLineModifiers (); i++)
3081 {
3082 if (eotp->modList[i].any_present)
3083 {
3084 mod = NULL;
3085 ssp = NULL;
3086 if (DefLineModifiers[i].isOrgMod)
3087 {
3088 if ( biop->org != NULL && biop->org->orgname != NULL)
3089 {
3090 mod = biop->org->orgname->mod;
3091 while (mod != NULL
3092 && mod->subtype != DefLineModifiers[i].subtype)
3093 {
3094 mod = mod->next;
3095 }
3096 }
3097 }
3098 else
3099 {
3100 ssp = biop->subtype;
3101 while (ssp != NULL && ssp->subtype != DefLineModifiers[i].subtype)
3102 {
3103 ssp = ssp->next;
3104 }
3105 }
3106 if (need_tab) {
3107 fprintf (eotp->fp, "\t");
3108 }
3109 if (IsNonTextModifier (DefLineModifiers[i].name))
3110 {
3111 if (mod == NULL && ssp == NULL)
3112 {
3113 fprintf (eotp->fp, "FALSE");
3114 }
3115 else
3116 {
3117 fprintf (eotp->fp, "TRUE");
3118 }
3119 }
3120 else if (mod != NULL && !StringHasNoText (mod->subname))
3121 {
3122 fprintf (eotp->fp, "%s", mod->subname);
3123 }
3124 else if (ssp != NULL && !StringHasNoText (ssp->name))
3125 {
3126 fprintf (eotp->fp, "%s", ssp->name);
3127 }
3128 else
3129 {
3130 fprintf (eotp->fp, " ");
3131 }
3132 need_tab = TRUE;
3133 }
3134 }
3135 fprintf (eotp->fp, "\n");
3136 }
3137
3138 static void ExportOrganisms (SeqEntryPtr sep, ExportOrgTablePtr eotp)
3139 {
3140 BioseqSetPtr bssp;
3141 SeqEntryPtr nsep;
3142 BioseqPtr bsp;
3143
3144 if (sep == NULL || eotp == NULL || sep->data.ptrvalue == NULL) return;
3145
3146 if (IS_Bioseq (sep))
3147 {
3148 bsp = (BioseqPtr) sep->data.ptrvalue;
3149 if (bsp != NULL && !ISA_aa (bsp->mol)) {
3150 eotp->bsp = bsp;
3151 VisitBioSourcesOnBsp (eotp->bsp, eotp, ExportOneOrganism);
3152 }
3153 }
3154 else if (IS_Bioseq_set (sep))
3155 {
3156 bssp = (BioseqSetPtr) sep->data.ptrvalue;
3157 if (bssp->_class == BioseqseqSet_class_nuc_prot)
3158 {
3159 nsep = FindNucSeqEntry (sep);
3160 if (nsep != NULL)
3161 {
3162 eotp->bsp = (BioseqPtr) nsep->data.ptrvalue;
3163 VisitBioSourcesOnSep (sep, eotp, ExportOneOrganism);
3164 }
3165 }
3166 else
3167 {
3168 for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
3169 {
3170 ExportOrganisms (sep, eotp);
3171 }
3172 }
3173 }
3174 }
3175
3176 static void GetOneOrganismIdProfile (BioSourcePtr biop, Pointer userdata)
3177 {
3178 ExportOrgTablePtr eotp;
3179 SeqIdPtr sip;
3180 Int4 profile_value = 0;
3181
3182 if (biop == NULL || userdata == NULL) return;
3183 eotp = (ExportOrgTablePtr) userdata;
3184
3185 if (eotp->bsp == NULL) return;
3186
3187 for (sip = eotp->bsp->id;
3188 sip != NULL;
3189 sip = sip->next)
3190 {
3191 if (sip->choice == SEQID_GENBANK)
3192 {
3193 profile_value |= ORGANISM_ID_PROFILE_HAS_ACCESSION;
3194 }
3195 else if (sip->choice == SEQID_LOCAL)
3196 {
3197 profile_value |= ORGANISM_ID_PROFILE_HAS_LOCAL;
3198 }
3199 else if (sip->choice == SEQID_GENERAL)
3200 {
3201 profile_value |= ORGANISM_ID_PROFILE_HAS_GENERAL;
3202 }
3203 }
3204
3205 if (biop->org != NULL && ! StringHasNoText (biop->org->taxname))
3206 {
3207 profile_value |= ORGANISM_ID_PROFILE_HAS_TAX_NAME;
3208 }
3209
3210 ValNodeAddInt (&(eotp->organism_id_profile), 0, profile_value);
3211 }
3212
3213 static void GetOrganismIDProfile (SeqEntryPtr sep, ExportOrgTablePtr eotp)
3214 {
3215 BioseqSetPtr bssp;
3216 SeqEntryPtr nsep;
3217
3218 if (sep == NULL || eotp == NULL || sep->data.ptrvalue == NULL) return;
3219
3220 if (IS_Bioseq (sep))
3221 {
3222 eotp->bsp = (BioseqPtr) sep->data.ptrvalue;
3223 VisitBioSourcesOnBsp (eotp->bsp, eotp, GetOneOrganismIdProfile);
3224 }
3225 else if (IS_Bioseq_set (sep))
3226 {
3227 bssp = (BioseqSetPtr) sep->data.ptrvalue;
3228 if (bssp->_class == BioseqseqSet_class_nuc_prot)
3229 {
3230 nsep = FindNucSeqEntry (sep);
3231 if (nsep != NULL)
3232 {
3233 eotp->bsp = (BioseqPtr) nsep->data.ptrvalue;
3234 VisitBioSourcesOnSep (sep, eotp, GetOneOrganismIdProfile);
3235 }
3236 }
3237 else
3238 {
3239 for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
3240 {
3241 GetOrganismIDProfile (sep, eotp);
3242 }
3243 }
3244 }
3245 }
3246
3247 static void GetOrganismIDProfileSummary (ValNodePtr organism_id_profile, Int4Ptr available, Int4Ptr recommended)
3248 {
3249 ValNodePtr vnp;
3250 Int4 has_vals = 0, recommended_vals = 0, missing_vals = 0;
3251
3252 if (available != NULL)
3253 {
3254 *available = 0;
3255 }
3256 if (recommended != NULL)
3257 {
3258 *recommended = 0;
3259 }
3260
3261 for (vnp = organism_id_profile;
3262 vnp != NULL;
3263 vnp = vnp->next)
3264 {
3265 has_vals |= vnp->data.intvalue;
3266 missing_vals |= !(vnp->data.intvalue);
3267 if (vnp->data.intvalue & ORGANISM_ID_PROFILE_HAS_ACCESSION)
3268 {
3269 recommended_vals |= ORGANISM_ID_PROFILE_HAS_ACCESSION;
3270 }
3271 else if (vnp->data.intvalue & ORGANISM_ID_PROFILE_HAS_LOCAL)
3272 {
3273 recommended_vals |= ORGANISM_ID_PROFILE_HAS_LOCAL;
3274 }
3275 else if (vnp->data.intvalue & ORGANISM_ID_PROFILE_HAS_GENERAL)
3276 {
3277 recommended_vals |= ORGANISM_ID_PROFILE_HAS_GENERAL;
3278 }
3279 else if (vnp->data.intvalue & ORGANISM_ID_PROFILE_HAS_TAX_NAME)
3280 {
3281 recommended_vals |= ORGANISM_ID_PROFILE_HAS_TAX_NAME;
3282 }
3283 }
3284
3285 if (recommended_vals & ORGANISM_ID_PROFILE_HAS_TAX_NAME)
3286 {
3287 if (!(missing_vals & ORGANISM_ID_PROFILE_HAS_TAX_NAME))
3288 {
3289 recommended_vals = ORGANISM_ID_PROFILE_HAS_TAX_NAME;
3290 }
3291 }
3292 else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_GENERAL)
3293 {
3294 if (!(missing_vals & ORGANISM_ID_PROFILE_HAS_GENERAL))
3295 {
3296 recommended_vals = ORGANISM_ID_PROFILE_HAS_GENERAL;
3297 }
3298 }
3299 else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_LOCAL)
3300 {
3301 if (!(missing_vals & ORGANISM_ID_PROFILE_HAS_LOCAL))
3302 {
3303 recommended_vals = ORGANISM_ID_PROFILE_HAS_LOCAL;
3304 }
3305 }
3306
3307 if (available != NULL)
3308 {
3309 *available = has_vals;
3310 }
3311
3312 if (recommended != NULL)
3313 {
3314 *recommended = recommended_vals;
3315 }
3316 }
3317
3318 typedef struct exportmodform
3319 {
3320 FEATURE_FORM_BLOCK
3321
3322 DialoG selected_mods;
3323 ButtoN list_tax_name;
3324 ButtoN list_accession;
3325 ButtoN list_local;
3326 ButtoN list_general;
3327 ButtoN list_additional_mods;
3328 ButtoN accept_btn;
3329 } ExportModFormData, PNTR ExportModFormPtr;
3330
3331 static void SetExportFormModsAccept (Pointer userdata)
3332 {
3333 ExportModFormPtr form_data;
3334 ValNodePtr selected_mods;
3335
3336 form_data = (ExportModFormPtr) userdata;
3337 if (form_data == NULL) return;
3338
3339 if (GetStatus (form_data->list_additional_mods))
3340 {
3341 Enable (form_data->selected_mods);
3342 selected_mods = (ValNodePtr) DialogToPointer (form_data->selected_mods);
3343 if (selected_mods == NULL)
3344 {
3345 Disable (form_data->accept_btn);
3346 return;
3347 }
3348 else
3349 {
3350 selected_mods = ValNodeFreeData (selected_mods);
3351 }
3352 }
3353 else
3354 {
3355 Disable (form_data->selected_mods);
3356 }
3357
3358 if (!GetStatus (form_data->list_tax_name) && ! GetStatus (form_data->list_accession)
3359 && !GetStatus (form_data->list_local) && ! GetStatus (form_data->list_general))
3360 {
3361 Disable (form_data->accept_btn);
3362 }
3363 else
3364 {
3365 Enable (form_data->accept_btn);
3366 }
3367 }
3368
3369 static void SetExportFormModsAcceptBtn (ButtoN b)
3370 {
3371 SetExportFormModsAccept (GetObjectExtra (b));
3372 }
3373
3374 static Boolean SelectModifiersForExport (ExportOrgTablePtr eotp)
3375 {
3376 Int4 idx;
3377 ValNodePtr available_mods_list = NULL, vnp;
3378 ModalAcceptCancelData acd;
3379 ExportModFormPtr form_data;
3380 WindoW w;
3381 GrouP h, g, c;
3382 ButtoN b;
3383 ValNodePtr selected_mods = NULL;
3384 Boolean found_mod;
3385 Int4 has_vals = 0, recommended_vals = 0;
3386
3387 if (eotp == NULL)
3388 {
3389 return FALSE;
3390 }
3391
3392 for (idx = 0; idx < NumDefLineModifiers (); idx++)
3393 {
3394 if (eotp->modList[idx].any_present)
3395 {
3396 ValNodeAddPointer (&available_mods_list, idx, StringSave (DefLineModifiers [idx].name));
3397 }
3398 }
3399
3400 GetOrganismIDProfileSummary (eotp->organism_id_profile, &has_vals, &recommended_vals);
3401
3402 form_data = (ExportModFormPtr) MemNew (sizeof (ExportModFormData));
3403
3404 w = FixedWindow (-50, -33, -10, -10, "Choose Modifiers for Export", StdCloseWindowProc);
3405 SetObjectExtra (w, form_data, StdCleanupFormProc);
3406 form_data->form = (ForM) w;
3407
3408 h = HiddenGroup (w, -1, 0, NULL);
3409 SetGroupSpacing (h, 10, 10);
3410
3411 g = HiddenGroup (h, 0, 5, NULL);
3412 form_data->list_tax_name = CheckBox (g, "Tax Name", SetExportFormModsAcceptBtn);
3413 SetObjectExtra (form_data->list_tax_name, form_data, NULL);
3414 if (!(has_vals & ORGANISM_ID_PROFILE_HAS_TAX_NAME))
3415 {
3416 Disable (form_data->list_tax_name);
3417 }
3418 else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_TAX_NAME)
3419 {
3420 SetStatus (form_data->list_tax_name, TRUE);
3421 }
3422 form_data->list_accession = CheckBox (g, "Accession", SetExportFormModsAcceptBtn);
3423 SetObjectExtra (form_data->list_accession, form_data, NULL);
3424 if (!(has_vals & ORGANISM_ID_PROFILE_HAS_ACCESSION))
3425 {
3426 Disable (form_data->list_accession);
3427 }
3428 else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_ACCESSION)
3429 {
3430 SetStatus (form_data->list_accession, TRUE);
3431 }
3432 form_data->list_local = CheckBox (g, "Local ID", SetExportFormModsAcceptBtn);
3433 SetObjectExtra (form_data->list_local, form_data, NULL);
3434 if (!(has_vals & ORGANISM_ID_PROFILE_HAS_LOCAL))
3435 {
3436 Disable (form_data->list_local);
3437 }
3438 else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_LOCAL)
3439 {
3440 SetStatus (form_data->list_local, TRUE);
3441 }
3442 form_data->list_general = CheckBox (g, "General ID", SetExportFormModsAcceptBtn);
3443 SetObjectExtra (form_data->list_general, form_data, NULL);
3444 if (!(has_vals & ORGANISM_ID_PROFILE_HAS_GENERAL))
3445 {
3446 Disable (form_data->list_general);
3447 }
3448 else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_GENERAL)
3449 {
3450 SetStatus (form_data->list_general, TRUE);
3451 }
3452
3453 form_data->list_additional_mods = CheckBox (g, "Additional Modifiers", SetExportFormModsAcceptBtn);
3454 SetObjectExtra (form_data->list_additional_mods, form_data, NULL);
3455 SetStatus (form_data->list_additional_mods, TRUE);
3456
3457 form_data->selected_mods = ValNodeSelectionDialog (h, available_mods_list, TALL_SELECTION_LIST,
3458 ValNodeStringName,
3459 ValNodeSimpleDataFree,
3460 ValNodeStringCopy,
3461 ValNodeStringMatch,
3462 "qualifiers",
3463 SetExportFormModsAccept, form_data,
3464 TRUE);
3465
3466 /* initialize dialog to "All" */
3467 SendMessageToDialog (form_data->selected_mods, NUM_VIB_MSG + 1);
3468
3469 c = HiddenGroup (h, 2, 0, NULL);
3470 form_data->accept_btn = PushButton (c, "Accept", ModalAcceptButton);
3471 SetObjectExtra (form_data->accept_btn, &acd, NULL);
3472 b = PushButton (c, "Cancel", ModalCancelButton);
3473 SetObjectExtra (b, &acd, NULL);
3474 AlignObjects (ALIGN_CENTER, (HANDLE) form_data->selected_mods, (HANDLE) g, (HANDLE) c, NULL);
3475
3476 SetExportFormModsAccept (form_data);
3477
3478 Show (w);
3479 Select (w);
3480 acd.accepted = FALSE;
3481 acd.cancelled = FALSE;
3482 while (!acd.accepted && ! acd.cancelled)
3483 {
3484 ProcessExternalEvent ();
3485 Update ();
3486 }
3487 ProcessAnEvent ();
3488
3489 Remove (w);
3490 if (acd.cancelled)
3491 {
3492 return FALSE;
3493 }
3494 else
3495 {
3496 if (GetStatus (form_data->list_additional_mods))
3497 {
3498 selected_mods = (ValNodePtr) DialogToPointer (form_data->selected_mods);
3499 }
3500 else
3501 {
3502 selected_mods = NULL;
3503 }
3504
3505 for (idx = 0; idx < NumDefLineModifiers (); idx++)
3506 {
3507 if (eotp->modList[idx].any_present)
3508 {
3509 found_mod = FALSE;
3510 for (vnp = selected_mods; vnp != NULL && ! found_mod; vnp = vnp->next)
3511 {
3512 if (StringCmp (vnp->data.ptrvalue, DefLineModifiers [idx].name) == 0)
3513 {
3514 found_mod = TRUE;
3515 }
3516 }
3517 if (!found_mod)
3518 {
3519 eotp->modList[idx].any_present = FALSE;
3520 }
3521 }
3522 }
3523 selected_mods = ValNodeFreeData (selected_mods);
3524
3525 eotp->list_tax_name = GetStatus (form_data->list_tax_name);
3526 eotp->list_accession = GetStatus (form_data->list_accession);
3527 eotp->list_local = GetStatus (form_data->list_local);
3528 eotp->list_general = GetStatus (form_data->list_general);
3529
3530 return TRUE;
3531 }
3532 }
3533
3534 extern void ExportOrganismTable (IteM i)
3535 {
3536 BaseFormPtr bfp;
3537 SeqEntryPtr sep;
3538 ExportOrgTableData eotd;
3539 Char path [PATH_MAX];
3540 Int4 idx;
3541 Char lead_str[2];
3542
3543 #ifdef WIN_MAC
3544 bfp = currentFormDataPtr;
3545 #else
3546 bfp = GetObjectExtra (i);
3547 #endif
3548 if (bfp == NULL) return;
3549
3550 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3551 if (sep == NULL) return;
3552
3553 eotd.modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
3554 if (eotd.modList == NULL) return;
3555
3556 CountModifiers (eotd.modList, sep);
3557
3558 eotd.organism_id_profile = NULL;
3559 GetOrganismIDProfile (sep, &eotd);
3560
3561 if (SelectModifiersForExport (&eotd))
3562 {
3563 if (GetOutputFileName (path, sizeof (path), NULL))
3564 {
3565 eotd.fp = FileOpen (path, "w");
3566 if (eotd.fp == NULL)
3567 {
3568 Message (MSG_ERROR, "Unable to open %s", path);
3569 }
3570 else
3571 {
3572 lead_str [0] = 0;
3573 lead_str [1] = 0;
3574 /* print a header line */
3575 if (eotd.list_accession)
3576 {
3577 fprintf (eotd.fp, "Accession Number");
3578 lead_str [0] = '\t';
3579 }
3580 if (eotd.list_local)
3581 {
3582 fprintf (eotd.fp, "%sLocal ID", lead_str);
3583 lead_str [0] = '\t';
3584 }
3585 if (eotd.list_general)
3586 {
3587 fprintf (eotd.fp, "%sGeneral ID", lead_str);
3588 lead_str [0] = '\t';
3589 }
3590 if (eotd.list_tax_name)
3591 {
3592 fprintf (eotd.fp, "%sTax Name", lead_str);
3593 lead_str [0] = '\t';
3594 }
3595
3596 for (idx = 0; idx < NumDefLineModifiers (); idx++)
3597 {
3598 if (eotd.modList[idx].any_present)
3599 {
3600 fprintf (eotd.fp, "%s%s", lead_str, DefLineModifiers [idx].name);
3601 lead_str [0] = '\t';
3602 }
3603 }
3604 fprintf (eotd.fp, "\n");
3605
3606 ExportOrganisms (sep, &eotd);
3607 FileClose (eotd.fp);
3608 }
3609 }
3610 }
3611 for (idx=0; idx < NumDefLineModifiers (); idx++)
3612 {
3613 ValNodeFree (eotd.modList[idx].values_seen);
3614 }
3615 eotd.modList = MemFree (eotd.modList);
3616 eotd.organism_id_profile = ValNodeFree (eotd.organism_id_profile);
3617 }
3618
3619
3620 typedef struct qualifierselect {
3621 LisT gene_quals;
3622 LisT cds_quals;
3623 LisT import_quals;
3624 } QualifierSelectData, PNTR QualifierSelectPtr;
3625
3626 typedef struct featurequalloadformdata {
3627 FEATURE_FORM_BLOCK
3628
3629 ValNodePtr line_list;
3630 ValNodePtr featlist;
3631 Int4 num_feats;
3632 Uint2 entityID;
3633 LisT feature_type;
3634 QualifierSelectData match_qual;
3635 QualifierSelectData apply_qual;
3636 PopuP sequence_id_type;
3637 PopuP sequence_column;
3638 PopuP feature_column;
3639 PopuP apply_column;
3640 GrouP seq_group;
3641 GrouP match_group;
3642 GrouP apply_group;
3643 Boolean asked_about_replace;
3644 Boolean do_replace;
3645 Boolean use_semicolon;
3646 ButtoN replace_with_blank_btn;
3647 Boolean replace_with_blank;
3648 ButtoN accept_button;
3649 } FeatureQualLoadFormData, PNTR FeatureQualLoadFormPtr;
3650
3651 static void CleanupFeatureQualLoadForm (
3652 GraphiC g,
3653 VoidPtr data
3654 )
3655 {
3656 FeatureQualLoadFormPtr form_data;
3657
3658 form_data = (FeatureQualLoadFormPtr)data;
3659 if (form_data == NULL) return;
3660 CleanUpTableData (form_data->line_list);
3661 StdCleanupFormProc (g, data);
3662 }
3663
3664 typedef struct qualifierlistdata {
3665 CharPtr item_name;
3666 } QualifierListData, PNTR QualifierListPtr;
3667
3668 static Int4 GetSubtypeFromOffsetInFeatureList (Int4 list_offset,
3669 ValNodePtr list)
3670 {
3671 ValNodePtr vnp;
3672
3673 if (list == NULL || list_offset < 1) return -1;
3674
3675 vnp = list;
3676 while (vnp != NULL && list_offset > 1)
3677 {
3678 list_offset --;
3679 vnp = vnp->next;
3680 }
3681 if (list_offset > 1) return -1;
3682 return vnp->choice;
3683 }
3684
3685 static void ShowQualifierListBySubtype (QualifierSelectPtr qsp, Int4 feature_subtype)
3686 {
3687 if (feature_subtype == -1) {
3688 Hide (qsp->gene_quals);
3689 Hide (qsp->cds_quals);
3690 Hide (qsp->import_quals);
3691 } else if (feature_subtype == FEATDEF_GENE) {
3692 Show (qsp->gene_quals);
3693 Hide (qsp->cds_quals);
3694 Hide (qsp->import_quals);
3695 } else if (feature_subtype == FEATDEF_CDS) {
3696 Hide (qsp->gene_quals);
3697 Show (qsp->cds_quals);
3698 Hide (qsp->import_quals);
3699 } else {
3700 Hide (qsp->gene_quals);
3701 Hide (qsp->cds_quals);
3702 Show (qsp->import_quals);
3703 }
3704 }
3705
3706 static void ShowQualifierLists (FeatureQualLoadFormPtr form_data)
3707 {
3708 Int4 feature_offset, feature_subtype;
3709
3710 if (form_data == NULL) return;
3711
3712 feature_offset = GetValue (form_data->feature_type);
3713 feature_subtype = GetSubtypeFromOffsetInFeatureList (feature_offset,
3714 form_data->featlist);
3715 ShowQualifierListBySubtype (&(form_data->match_qual), feature_subtype);
3716 ShowQualifierListBySubtype (&(form_data->apply_qual), feature_subtype);
3717 }
3718
3719 static QualifierListData GeneTableQualifiers [] = {
3720 { "allele"},
3721 { "locus" },
3722 { "locus_tag"},
3723 { "description"},
3724 { "product"}
3725 };
3726
3727 #define NUM_GENE_TABLE_QUALIFIERS 5
3728
3729 static QualifierListData ProtTableQualifiers [] = {
3730 { "product"},
3731 { "description"},
3732 { "comment"}
3733 };
3734
3735 #define NUM_PROT_TABLE_QUALIFIERS 3
3736
3737 /* check the appropriate list box for qualifier type,
3738 * keeping in mind that the first item is always "none"
3739 */
3740 static Int4 GetQualSelectBySubtype (QualifierSelectPtr qsp, Int4 feature_subtype)
3741 {
3742 Int4 qual_choice = -1;
3743
3744 if (feature_subtype == -1) {
3745 qual_choice = -1;
3746 } else if (feature_subtype == FEATDEF_GENE) {
3747 qual_choice = GetValue (qsp->gene_quals);
3748 if (qual_choice < 2
3749 || qual_choice > NUM_GENE_TABLE_QUALIFIERS + 2) {
3750 qual_choice = -1;
3751 } else {
3752 qual_choice = qual_choice - 1;
3753 }
3754 } else if (feature_subtype == FEATDEF_CDS) {
3755 qual_choice = GetValue (qsp->cds_quals);
3756 if (qual_choice < 2
3757 || qual_choice > NUM_PROT_TABLE_QUALIFIERS + 2) {
3758 qual_choice = -1;
3759 } else {
3760 qual_choice = qual_choice - 1;
3761 }
3762 } else {
3763 qual_choice = GetValue (qsp->import_quals);
3764 if (qual_choice < 2
3765 || qual_choice > ParFlat_TOTAL_GBQUAL + 2) {
3766 qual_choice = -1;
3767 } else {
3768 qual_choice = qual_choice - 1;
3769 }
3770 }
3771 return qual_choice;
3772
3773 }
3774
3775 static void SetFeatureQualAcceptButton (Handle a)
3776 {
3777 FeatureQualLoadFormPtr form_data;
3778 Boolean have_feature_select_column;
3779 Boolean have_feature_qual_select_column;
3780 Int4 feature_select_choice;
3781 Int4 apply_qual_choice;
3782 Int4 match_qual_choice;
3783 Int4 feature_subtype;
3784 Boolean seqid_select_ok;
3785 Int4 seqid_select_type;
3786 Int4 seqid_select_column;
3787
3788 form_data = GetObjectExtra (a);
3789 if (form_data == NULL) return;
3790
3791 ShowQualifierLists (form_data);
3792 have_feature_qual_select_column = FALSE;
3793 have_feature_select_column = FALSE;
3794 seqid_select_ok = FALSE;
3795
3796 feature_select_choice = GetValue (form_data->feature_type);
3797 if ( feature_select_choice > 0 && feature_select_choice < form_data->num_feats)
3798 {
3799 have_feature_select_column = TRUE;
3800 }
3801
3802 feature_subtype = GetSubtypeFromOffsetInFeatureList (feature_select_choice,
3803 form_data->featlist);
3804
3805 apply_qual_choice = GetQualSelectBySubtype (&(form_data->apply_qual),
3806 feature_subtype);
3807 if (apply_qual_choice != -1)
3808 {
3809 have_feature_qual_select_column = TRUE;
3810 }
3811
3812 /* if a column is selected for a sequence identifier, must select type */
3813 /* if a column is not selected for a sequence identifier, must not select type */
3814 seqid_select_type = GetValue (form_data->sequence_id_type);
3815 seqid_select_column = GetValue (form_data->sequence_column);
3816 if (seqid_select_type == 1 || seqid_select_type == 2) {
3817 if (seqid_select_column > 0) {
3818 seqid_select_ok = TRUE;
3819 }
3820 } else {
3821 seqid_select_ok = TRUE;
3822 }
3823
3824 /* if the feature column is not specified, must not have match qualifier */
3825 /* and must have sequence ID */
3826 /* if the feature column is specified, must have match qualifier */
3827 match_qual_choice = GetQualSelectBySubtype (&(form_data->match_qual),
3828 feature_subtype);
3829 if (GetValue (form_data->feature_column) < 1)
3830 {
3831 if (match_qual_choice != -1)
3832 {
3833 have_feature_select_column = FALSE;
3834 }
3835 else if (seqid_select_column < 1)
3836 {
3837 have_feature_select_column = FALSE;
3838 }
3839 } else {
3840 if (match_qual_choice == -1)
3841 {
3842 have_feature_select_column = FALSE;
3843 }
3844 }
3845
3846 if (GetValue (form_data->apply_column) < 1) {
3847 have_feature_qual_select_column = FALSE;
3848 }
3849
3850 if ( have_feature_select_column && have_feature_qual_select_column
3851 && seqid_select_ok)
3852 {
3853 Enable (form_data->accept_button);
3854 }
3855 else
3856 {
3857 Disable (form_data->accept_button);
3858 }
3859 }
3860
3861 static Boolean ProductNameMatches (
3862 SeqLocPtr slp,
3863 BioseqPtr bsp,
3864 CharPtr pString
3865 )
3866 {
3867 SeqFeatPtr sfp;
3868 SeqMgrFeatContext fcontext;
3869
3870 if (slp == NULL || bsp == NULL || pString == NULL) return FALSE;
3871
3872 sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &fcontext);
3873 while (sfp != NULL)
3874 {
3875 if ( IsLocAInBonSameStrand (sfp->location, slp)
3876 && StringStr ( fcontext.label, pString) != NULL)
3877 {
3878 return TRUE;
3879 }
3880 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &fcontext);
3881 }
3882 return FALSE;
3883 }
3884
3885 static Boolean GeneHasThisQualifier (
3886 SeqFeatPtr sfp,
3887 Uint2 entityID,
3888 CharPtr pString,
3889 Int2 popup_offset
3890 )
3891 {
3892 BioseqPtr bsp;
3893 GeneRefPtr grp;
3894
3895 if (sfp == NULL || pString == NULL) return FALSE;
3896 if (popup_offset < 1 || popup_offset > NUM_GENE_TABLE_QUALIFIERS) return FALSE;
3897
3898 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
3899 if (grp == NULL) return FALSE;
3900
3901 if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "allele") == 0) {
3902 if (StringCmp (pString, grp->allele) == 0) {
3903 return TRUE;
3904 } else {
3905 return FALSE;
3906 }
3907 } else if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "locus") == 0) {
3908 if (StringCmp (pString, grp->locus) == 0) {
3909 return TRUE;
3910 } else {
3911 return FALSE;
3912 }
3913 } else if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "locus_tag") == 0) {
3914 if (StringCmp (pString, grp->locus_tag) == 0) {
3915 return TRUE;
3916 } else {
3917 return FALSE;
3918 }
3919 } else if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "description") == 0) {
3920 if (StringCmp (pString, grp->desc) == 0) {
3921 return TRUE;
3922 } else {
3923 return FALSE;
3924 }
3925 } else if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "product") == 0)
3926 {
3927 bsp = GetBioseqGivenSeqLoc (sfp->location, entityID);
3928 return ProductNameMatches (sfp->location, bsp, pString);
3929 }
3930 return FALSE;
3931 }
3932
3933 static Boolean ProteinHasThisQualifier (
3934 SeqFeatPtr sfp,
3935 CharPtr pString,
3936 Int2 popup_offset
3937 )
3938 {
3939 ProtRefPtr prp;
3940
3941 if (sfp == NULL || sfp->data.choice != SEQFEAT_PROT || pString == NULL
3942 || popup_offset < 1 || popup_offset > NUM_PROT_TABLE_QUALIFIERS)
3943 {
3944 return FALSE;
3945 }
3946
3947 prp = sfp->data.value.ptrvalue;
3948 if (prp == NULL) return FALSE;
3949
3950 if (StringCmp (ProtTableQualifiers [ popup_offset - 1].item_name, "product") == 0)
3951 {
3952 if (prp->name != NULL
3953 && StringStr (prp->name->data.ptrvalue, pString) != NULL)
3954 {
3955 return TRUE;
3956 }
3957 } else if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "description") == 0) {
3958 if (StringStr (prp->desc, pString) != NULL)
3959 {
3960 return TRUE;
3961 }
3962 } else if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "comment") == 0) {
3963 if (StringStr (sfp->comment, pString) != NULL)
3964 {
3965 return TRUE;
3966 }
3967 }
3968 return FALSE;
3969 }
3970
3971 static Boolean CDSHasThisQualifier (
3972 SeqFeatPtr sfp,
3973 Uint2 entityID,
3974 CharPtr pString,
3975 Int2 popup_offset
3976 )
3977 {
3978 SeqFeatPtr protein;
3979
3980 if (sfp == NULL || pString == NULL) return FALSE;
3981
3982 if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "comment") == 0) {
3983 if (StringStr (sfp->comment, pString) != NULL)
3984 {
3985 return TRUE;
3986 }
3987 }
3988 else
3989 {
3990 protein = FindBestProtein (entityID, sfp->product);
3991 if (protein == NULL) return FALSE;
3992 return ProteinHasThisQualifier (protein, pString, popup_offset);
3993 }
3994 return FALSE;
3995 }
3996
3997 static Boolean FeatureHasThisQualifier (
3998 SeqFeatPtr sfp,
3999 Uint2 entityID,
4000 CharPtr pString,
4001 Int2 popup_offset
4002 )
4003 {
4004 Int2 qualval;
4005 GBQualPtr gbqual;
4006
4007 if (popup_offset < 1) return FALSE;
4008 if (sfp == NULL || pString == NULL) return FALSE;
4009
4010 if (sfp->idx.subtype == FEATDEF_GENE)
4011 {
4012 return GeneHasThisQualifier (sfp, entityID, pString, popup_offset);
4013 }
4014 else if (sfp->idx.subtype == FEATDEF_CDS)
4015 {
4016 return CDSHasThisQualifier (sfp, entityID, pString, popup_offset);
4017 }
4018 else
4019 {
4020 for (gbqual = sfp->qual; gbqual != NULL; gbqual = gbqual->next)
4021 {
4022 qualval = GBQualNameValid (gbqual->qual);
4023 if (qualval > -1 && qualval == popup_offset -1)
4024 {
4025 return TRUE;
4026 }
4027 }
4028 }
4029 return FALSE;
4030 }
4031
4032 static CharPtr GetDataForColumnOffset (ValNodePtr column_data, Int4 offset)
4033 {
4034 ValNodePtr vnp;
4035
4036 for (vnp = column_data; vnp != NULL && offset > 1; vnp = vnp->next)
4037 {
4038 offset --;
4039 }
4040 if (offset > 1 || vnp == NULL) {
4041 return NULL;
4042 } else {
4043 return vnp->data.ptrvalue;
4044 }
4045 }
4046
4047 static Boolean ApplyQualToThisFeature (
4048 SeqFeatPtr sfp,
4049 ValNodePtr parts,
4050 FeatureQualLoadFormPtr form_data
4051 )
4052 {
4053 Int4 column_index;
4054 CharPtr val;
4055 Int4 subtype;
4056 Int4 popup_offset;
4057
4058 if (sfp == NULL || parts == NULL || form_data == NULL) return FALSE;
4059
4060 column_index = GetValue (form_data->feature_column);
4061 subtype = GetSubtypeFromOffsetInFeatureList (
4062 GetValue (form_data->feature_type), form_data->featlist);
4063 val = GetDataForColumnOffset (parts, column_index);
4064
4065 if (val != NULL && sfp->idx.subtype == subtype)
4066 {
4067 popup_offset = GetQualSelectBySubtype (&(form_data->match_qual),
4068 subtype);
4069 if (popup_offset < 1
4070 || FeatureHasThisQualifier (sfp, form_data->entityID, val, popup_offset))
4071 {
4072 return TRUE;
4073 }
4074 }
4075 return FALSE;
4076 }
4077
4078 typedef struct featurequaltabledata {
4079 ValNodePtr parts;
4080 FeatureQualLoadFormPtr form_data;
4081 } FeatureQualTableData, PNTR FeatureQualTablePtr;
4082
4083 static void ApplyOneQualToProt (
4084 SeqFeatPtr sfp,
4085 Int2 popup_offset,
4086 CharPtr pString,
4087 Boolean PNTR asked_about_replace,
4088 Boolean PNTR do_replace,
4089 Boolean PNTR use_semicolon)
4090 {
4091 ProtRefPtr prp;
4092 CharPtr cp;
4093
4094 if (sfp == NULL || sfp->data.choice != SEQFEAT_PROT || pString == NULL
4095 || popup_offset < 1 || popup_offset > NUM_PROT_TABLE_QUALIFIERS
4096 || asked_about_replace == NULL
4097 || do_replace == NULL
4098 || use_semicolon == NULL)
4099 {
4100 return;
4101 }
4102
4103 prp = sfp->data.value.ptrvalue;
4104 if (prp == NULL) return;
4105
4106 if (StringCmp (ProtTableQualifiers [ popup_offset - 1].item_name, "product") == 0)
4107 {
4108 if (prp->name == NULL)
4109 {
4110 ValNodeAddStr (&prp->name, 0, StringSave (pString));
4111 }
4112 else
4113 {
4114 cp = prp->name->data.ptrvalue;
4115 AppendOrReplaceString (&cp, pString,
4116 asked_about_replace, do_replace, use_semicolon);
4117 prp->name->data.ptrvalue = cp;
4118 }
4119 } else if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "description") == 0) {
4120 AppendOrReplaceString (&(prp->desc), pString,
4121 asked_about_replace, do_replace, use_semicolon);
4122 } else if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "comment") == 0) {
4123 AppendOrReplaceString (&(sfp->comment), pString,
4124 asked_about_replace, do_replace, use_semicolon);
4125 }
4126 }
4127
4128 static void ApplyOneQualToCDS (
4129 SeqFeatPtr sfp,
4130 Uint2 entityID,
4131 Int2 feat_qual_choice,
4132 CharPtr pString,
4133 Boolean PNTR asked_about_replace,
4134 Boolean PNTR do_replace,
4135 Boolean PNTR use_semicolon)
4136 {
4137 SeqFeatPtr protein;
4138
4139 if (sfp == NULL || pString == NULL
4140 || asked_about_replace == NULL
4141 || do_replace == NULL
4142 || use_semicolon == NULL)
4143 {
4144 return;
4145 }
4146
4147 if (StringCmp (ProtTableQualifiers [feat_qual_choice - 1].item_name, "comment") == 0) {
4148 AppendOrReplaceString (&(sfp->comment), pString,
4149 asked_about_replace, do_replace, use_semicolon);
4150 }
4151 else
4152 {
4153 protein = FindBestProtein (entityID, sfp->product);
4154 if (protein == NULL) return;
4155 ApplyOneQualToProt (protein, feat_qual_choice, pString,
4156 asked_about_replace, do_replace, use_semicolon);
4157 }
4158 }
4159
4160 static void ApplyGeneProductName (
4161 SeqLocPtr slp,
4162 Uint2 entityID,
4163 CharPtr pString,
4164 Boolean PNTR asked_about_replace,
4165 Boolean PNTR do_replace,
4166 Boolean PNTR use_semicolon)
4167 {
4168 SeqFeatPtr sfp;
4169 SeqMgrFeatContext fcontext;
4170 Int4 prot_popup_offset;
4171 BioseqPtr bsp;
4172
4173 if (slp == NULL || pString == NULL
4174 || asked_about_replace == NULL
4175 || do_replace == NULL
4176 || use_semicolon == NULL)
4177 {
4178 return;
4179 }
4180
4181 bsp = GetBioseqGivenSeqLoc (slp, entityID);
4182 if (bsp == NULL) return;
4183
4184 for (prot_popup_offset = 0;
4185 prot_popup_offset < NUM_PROT_TABLE_QUALIFIERS
4186 && StringCmp (ProtTableQualifiers [prot_popup_offset].item_name, "product") != 0;
4187 prot_popup_offset ++)
4188 {}
4189 if (prot_popup_offset >= NUM_PROT_TABLE_QUALIFIERS) return;
4190
4191 sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &fcontext);
4192 while (sfp != NULL)
4193 {
4194 if ( IsLocAInBonSameStrand (sfp->location, slp))
4195 {
4196 ApplyOneQualToCDS (sfp, entityID, prot_popup_offset + 1, pString,
4197 asked_about_replace, do_replace, use_semicolon);
4198 }
4199 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &fcontext);
4200 }
4201 }
4202
4203 static void ApplyOneQualToGene (
4204 SeqFeatPtr sfp,
4205 Uint2 entityID,
4206 Int2 feat_qual_choice,
4207 CharPtr pString,
4208 Boolean PNTR asked_about_replace,
4209 Boolean PNTR do_replace,
4210 Boolean PNTR use_semicolon)
4211 {
4212 GeneRefPtr grp;
4213
4214 if (sfp == NULL
4215 || sfp->idx.subtype != FEATDEF_GENE
4216 || feat_qual_choice < 1
4217 || feat_qual_choice > NUM_GENE_TABLE_QUALIFIERS
4218 || pString == NULL
4219 || asked_about_replace == NULL
4220 || do_replace == NULL
4221 || use_semicolon == NULL)
4222 {
4223 return;
4224 }
4225
4226 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
4227 if (grp == NULL) return;
4228
4229 if (StringCmp ( GeneTableQualifiers [feat_qual_choice - 1].item_name,
4230 "allele") == 0) {
4231 AppendOrReplaceString (&(grp->allele), pString,
4232 asked_about_replace, do_replace, use_semicolon);
4233 } else if (StringCmp ( GeneTableQualifiers [feat_qual_choice - 1].item_name,
4234 "locus") == 0) {
4235 AppendOrReplaceString (&(grp->locus), pString,
4236 asked_about_replace, do_replace, use_semicolon);
4237 } else if (StringCmp ( GeneTableQualifiers [feat_qual_choice - 1].item_name,
4238 "locus_tag") == 0) {
4239 AppendOrReplaceString (&(grp->locus_tag), pString,
4240 asked_about_replace, do_replace, use_semicolon);
4241 } else if (StringCmp ( GeneTableQualifiers [feat_qual_choice - 1].item_name,
4242 "description") == 0) {
4243 AppendOrReplaceString (&(grp->desc), pString,
4244 asked_about_replace, do_replace, use_semicolon);
4245 } else if (StringCmp (GeneTableQualifiers [feat_qual_choice - 1].item_name,
4246 "product") == 0) {
4247 ApplyGeneProductName (sfp->location, entityID, pString,
4248 asked_about_replace, do_replace, use_semicolon);
4249 }
4250 }
4251
4252 static void ApplyOneQualToImportFeature (
4253 SeqFeatPtr sfp,
4254 Int2 feat_qual_choice,
4255 CharPtr pString,
4256 Boolean PNTR asked_about_replace,
4257 Boolean PNTR do_replace,
4258 Boolean PNTR use_semicolon)
4259 {
4260 GBQualPtr gbqual;
4261
4262 if (sfp == NULL
4263 || feat_qual_choice < 1
4264 || feat_qual_choice > ParFlat_TOTAL_GBQUAL
4265 || pString == NULL
4266 || asked_about_replace == NULL
4267 || do_replace == NULL
4268 || use_semicolon == NULL)
4269 {
4270 return;
4271 }
4272
4273 gbqual = sfp->qual;
4274 while (gbqual != NULL
4275 && StringCmp (gbqual->qual,
4276 ParFlat_GBQual_names [feat_qual_choice - 1].name) != 0)
4277 {
4278 gbqual = gbqual->next;
4279 }
4280
4281 if (gbqual == NULL)
4282 {
4283 gbqual = GBQualNew ();
4284 if (gbqual == NULL) return;
4285 gbqual->qual = StringSave ( ParFlat_GBQual_names [feat_qual_choice - 1].name);
4286 gbqual->val = StringSave ( pString );
4287 gbqual->next = sfp->qual;
4288 sfp->qual = gbqual;
4289 }
4290 else
4291 {
4292 AppendOrReplaceString (&(gbqual->val), pString,
4293 asked_about_replace, do_replace, use_semicolon);
4294 }
4295 }
4296
4297 static void ApplyOneQualToFeature (
4298 SeqFeatPtr sfp,
4299 Uint2 entityID,
4300 Int2 feat_qual_choice,
4301 CharPtr pString,
4302 Boolean PNTR asked_about_replace,
4303 Boolean PNTR do_replace,
4304 Boolean PNTR use_semicolon)
4305 {
4306 if (sfp == NULL || pString == NULL
4307 || asked_about_replace == NULL
4308 || do_replace == NULL
4309 || use_semicolon == NULL)
4310 {
4311 return;
4312 }
4313
4314 switch (sfp->idx.subtype)
4315 {
4316 case FEATDEF_GENE :
4317 ApplyOneQualToGene (sfp, entityID, feat_qual_choice, pString,
4318 asked_about_replace, do_replace, use_semicolon);
4319 break;
4320 case FEATDEF_CDS :
4321 ApplyOneQualToCDS (sfp, entityID, feat_qual_choice, pString,
4322 asked_about_replace, do_replace, use_semicolon);
4323 break;
4324 default :
4325 ApplyOneQualToImportFeature (sfp, feat_qual_choice, pString,
4326 asked_about_replace, do_replace, use_semicolon);
4327 break;
4328 }
4329 }
4330
4331 static CharPtr GetImpFeatKeyFromSubtype (Uint2 subtype)
4332 {
4333 FeatDefPtr curr;
4334 Uint1 key;
4335 CharPtr label;
4336
4337 curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
4338 while (curr != NULL) {
4339 if (key == subtype)
4340 {
4341 return curr->typelabel;
4342 }
4343 curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
4344 }
4345 return NULL;
4346 }
4347
4348 static void ApplyQualsToFeaturesOnBsp (BioseqPtr bsp,
4349 FeatureQualLoadFormPtr form_data,
4350 ValNodePtr parts)
4351 {
4352 SeqFeatPtr sfp;
4353 SeqMgrFeatContext fcontext;
4354 Boolean found_feature = FALSE;
4355 Int4 subtype;
4356 Int4 column_index;
4357 Int2 qualval;
4358 Int2 matchval;
4359 CharPtr val;
4360 ImpFeatPtr ifp;
4361
4362 subtype = GetSubtypeFromOffsetInFeatureList (
4363 GetValue (form_data->feature_type),
4364 form_data->featlist);
4365 column_index = GetValue (form_data->apply_column);
4366 val = GetDataForColumnOffset (parts, column_index);
4367 /* if the value to be applied is blank and we're not replacing with blanks, skip */
4368 if (! form_data->replace_with_blank && StringHasNoText (val)) {
4369 return;
4370 }
4371 qualval = GetQualSelectBySubtype (&(form_data->apply_qual), subtype);
4372 if (subtype == -1 || val == NULL || column_index < 1 || qualval < 1) {
4373 /* do nothing */
4374 }
4375 else
4376 {
4377 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
4378 while (sfp != NULL)
4379 {
4380 if ( ApplyQualToThisFeature (sfp, parts, form_data))
4381 {
4382 found_feature = TRUE;
4383 ApplyOneQualToFeature (sfp, form_data->entityID, qualval, val,
4384 &(form_data->asked_about_replace),
4385 &(form_data->do_replace),
4386 &(form_data->use_semicolon));
4387 }
4388 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &fcontext);
4389 }
4390
4391 /* only want to create new features if no feature matching qualifier
4392 * was specified and no feature was found */
4393 matchval = GetQualSelectBySubtype (&(form_data->match_qual), subtype);
4394
4395 if (! found_feature && matchval == -1)
4396 {
4397 if (subtype == FEATDEF_CDS)
4398 {
4399 sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_CDREGION, NULL);
4400 if (sfp == NULL) return;
4401 sfp->data.value.ptrvalue = CdRegionNew ();
4402 } else if (subtype == FEATDEF_GENE) {
4403 sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_GENE, NULL);
4404 if (sfp == NULL) return;
4405 sfp->data.value.ptrvalue = GeneRefNew ();
4406 } else {
4407 ifp = ImpFeatNew ();
4408 if (ifp == NULL) return;
4409 sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
4410 if (sfp == NULL) return;
4411 ifp->key = StringSave ( GetImpFeatKeyFromSubtype (subtype));
4412 sfp->data.value.ptrvalue = ifp;
4413 }
4414 SeqMgrIndexFeatures (0, (Pointer) bsp);
4415 ApplyOneQualToFeature (sfp, form_data->entityID, qualval, val,
4416 &(form_data->asked_about_replace),
4417 &(form_data->do_replace),
4418 &(form_data->use_semicolon));
4419 }
4420 }
4421 }
4422
4423 static void ApplyTableQuals (BioseqPtr bsp, Pointer userdata)
4424 {
4425 FeatureQualLoadFormPtr form_data;
4426 SeqDescrPtr sdp;
4427 GBBlockPtr gbp;
4428 Int4 column_index;
4429 ValNodePtr line;
4430 TableLinePtr tlp;
4431 Boolean use_local_id = FALSE;
4432 FeatureQualTableData fqtd;
4433 Int2 seq_match_choice;
4434 CharPtr idval;
4435
4436 form_data = (FeatureQualLoadFormPtr) userdata;
4437 if (form_data == NULL || bsp == NULL) return;
4438
4439 gbp = NULL;
4440 sdp = BioseqGetSeqDescr (bsp, Seq_descr_genbank, NULL);
4441 if (sdp != NULL)
4442 {
4443 gbp = sdp->data.ptrvalue;
4444 }
4445
4446 seq_match_choice = GetValue (form_data->sequence_id_type);
4447 if (seq_match_choice == 1) {
4448 use_local_id = FALSE;
4449 }
4450
4451 fqtd.form_data = form_data;
4452 if (seq_match_choice == 1 || seq_match_choice == 2)
4453 {
4454 column_index = GetValue (form_data->sequence_column);
4455
4456 for (line = form_data->line_list; line != NULL; line = line->next)
4457 {
4458 tlp = line->data.ptrvalue;
4459 if (tlp == NULL) continue;
4460 idval = GetDataForColumnOffset (tlp->parts, column_index);
4461 if (idval != NULL
4462 && ( IDListHasValue ( idval,
4463 bsp->id, use_local_id, FALSE, FALSE)
4464 || (! use_local_id &&
4465 HasExtraAccession ( idval, gbp))))
4466 {
4467 fqtd.parts = tlp->parts;
4468 ApplyQualsToFeaturesOnBsp (bsp, form_data, tlp->parts);
4469 }
4470 }
4471 } else {
4472 for (line = form_data->line_list; line != NULL; line = line->next)
4473 {
4474 tlp = line->data.ptrvalue;
4475 if (tlp == NULL) continue;
4476 fqtd.parts = tlp->parts;
4477 ApplyQualsToFeaturesOnBsp (bsp, form_data, tlp->parts);
4478 }
4479 }
4480 }
4481
4482 static void DoAcceptFeatureQuals (ButtoN b)
4483 {
4484 FeatureQualLoadFormPtr form_data;
4485 SeqEntryPtr sep;
4486
4487 form_data = GetObjectExtra (b);
4488 if (form_data == NULL) return;
4489
4490 form_data->replace_with_blank = GetStatus (form_data->replace_with_blank_btn);
4491
4492 sep = GetTopSeqEntryForEntityID (form_data->entityID);
4493 if (sep == NULL) return;
4494
4495 VisitBioseqsInSep (sep, form_data, ApplyTableQuals);
4496 Update ();
4497 ObjMgrSetDirtyFlag (form_data->entityID, TRUE);
4498 ObjMgrSendMsg (OM_MSG_UPDATE, form_data->entityID, 0, 0);
4499 Remove (form_data->form);
4500 }
4501
4502 static PopuP BuildColumnSelector ( GrouP g,
4503 FeatureQualLoadFormPtr parent_form,
4504 ValNodePtr parts )
4505 {
4506 PopuP p;
4507 ValNodePtr this_part;
4508
4509 if (g == NULL || parts == NULL) return NULL;
4510
4511 p = PopupList (g, TRUE, (PupActnProc) SetFeatureQualAcceptButton);
4512 for (this_part = parts; this_part != NULL; this_part = this_part->next)
4513 {
4514 if (this_part->data.ptrvalue != NULL)
4515 {
4516 PopupItem (p, this_part->data.ptrvalue);
4517 }
4518 }
4519 SetObjectExtra (p, parent_form, NULL);
4520 return p;
4521 }
4522
4523 static void BuildQualifierSelect ( GrouP parent,
4524 FeatureQualLoadFormPtr parent_form,
4525 ValNodePtr parts,
4526 QualifierSelectPtr qsp )
4527 {
4528 GrouP g;
4529 Int4 listheight = 4;
4530 Int4 listwidth = 13;
4531 Int4 j;
4532
4533 if (parent_form == NULL || parts == NULL || qsp == NULL)
4534 {
4535 return;
4536 }
4537
4538 g = HiddenGroup (parent, 0, 0, NULL);
4539
4540 qsp->gene_quals = SingleList (g, listwidth, listheight,
4541 (LstActnProc) SetFeatureQualAcceptButton);
4542 SetObjectExtra (qsp->gene_quals, parent_form, NULL);
4543 ListItem (qsp->gene_quals, "None");
4544 for (j=0; j < NUM_GENE_TABLE_QUALIFIERS; j++) {
4545 ListItem (qsp->gene_quals, GeneTableQualifiers [j].item_name);
4546 }
4547 SetValue (qsp->gene_quals, 1);
4548
4549 qsp->cds_quals = SingleList (g, listwidth, listheight,
4550 (LstActnProc) SetFeatureQualAcceptButton);
4551 SetObjectExtra (qsp->cds_quals, parent_form, NULL);
4552 ListItem (qsp->cds_quals, "None");
4553 for (j=0; j < NUM_PROT_TABLE_QUALIFIERS; j++) {
4554 ListItem (qsp->cds_quals, ProtTableQualifiers [j].item_name);
4555 }
4556 SetValue (qsp->cds_quals, 1);
4557
4558 qsp->import_quals = SingleList (g, listwidth, listheight,
4559 (LstActnProc) SetFeatureQualAcceptButton);
4560 SetObjectExtra (qsp->import_quals, parent_form, NULL);
4561 ListItem (qsp->import_quals, "None");
4562 for (j = 0; j < ParFlat_TOTAL_GBQUAL; j++) {
4563 ListItem (qsp->import_quals, ParFlat_GBQual_names [j].name);
4564 }
4565 SetValue (qsp->import_quals, 1);
4566 }
4567
4568 static void BuildSequenceSelect ( GrouP parent,
4569 FeatureQualLoadFormPtr parent_form,
4570 ValNodePtr parts )
4571 {
4572 if (parent == NULL || parent_form == NULL || parts == NULL) return;
4573
4574 parent_form->seq_group = NormalGroup ( parent, 0, 2, "Sequence", programFont, NULL);
4575 StaticPrompt (parent_form->seq_group, "Identifier Type", 0, popupMenuHeight, programFont, 'l');
4576 parent_form->sequence_id_type = PopupList (parent_form->seq_group, TRUE, (PupActnProc) SetFeatureQualAcceptButton);
4577 PopupItem (parent_form->sequence_id_type, "Accession");
4578 PopupItem (parent_form->sequence_id_type, "Local ID");
4579 PopupItem (parent_form->sequence_id_type, "None");
4580 SetObjectExtra (parent_form->sequence_id_type, parent_form, NULL);
4581 SetValue (parent_form->sequence_id_type, 3);
4582
4583 StaticPrompt (parent_form->seq_group, "Column", 0, popupMenuHeight, programFont, 'l');
4584 parent_form->sequence_column = BuildColumnSelector ( parent_form->seq_group, parent_form, parts);
4585 }
4586
4587 static void BuildFeatureSelect ( GrouP parent,
4588 FeatureQualLoadFormPtr parent_form,
4589 ValNodePtr parts )
4590 {
4591 Int4 listheight = 4;
4592 ValNodePtr vnp;
4593
4594 if (parent == NULL || parent_form == NULL || parts == NULL) return;
4595
4596 parent_form->match_group = NormalGroup ( parent, 0, 2,
4597 "Feature to Edit", programFont, NULL);
4598 StaticPrompt (parent_form->match_group, "Feature type", 0,
4599 popupMenuHeight, programFont, 'l');
4600 parent_form->feature_type = SingleList (parent_form->match_group,
4601 9, listheight,
4602 (LstActnProc) SetFeatureQualAcceptButton);
4603 SetObjectExtra (parent_form->feature_type, parent_form, NULL);
4604 for (vnp = parent_form->featlist; vnp != NULL; vnp = vnp->next)
4605 {
4606 ListItem (parent_form->feature_type, (CharPtr) vnp->data.ptrvalue);
4607 }
4608
4609 StaticPrompt (parent_form->match_group, "Qualifier to match", 0, popupMenuHeight, programFont, 'l');
4610 BuildQualifierSelect ( parent_form->match_group, parent_form, parts, &(parent_form->match_qual));
4611
4612 StaticPrompt (parent_form->match_group, "Column", 0, popupMenuHeight, programFont, 'l');
4613 parent_form->feature_column = BuildColumnSelector ( parent_form->match_group, parent_form, parts);
4614
4615 }
4616
4617 static void BuildFeatureApply ( GrouP parent,
4618 FeatureQualLoadFormPtr parent_form,
4619 ValNodePtr parts )
4620 {
4621 if (parent == NULL || parent_form == NULL || parts == NULL) return;
4622
4623 parent_form->apply_group = NormalGroup ( parent, 0, 2, "Qualifier to Edit", programFont, NULL);
4624
4625 StaticPrompt (parent_form->apply_group, "Qualifier Name", 0, popupMenuHeight, programFont, 'l');
4626 BuildQualifierSelect ( parent_form->apply_group, parent_form, parts, &(parent_form->apply_qual));
4627
4628 StaticPrompt (parent_form->apply_group, "Column", 0, popupMenuHeight, programFont, 'l');
4629 parent_form->apply_column = BuildColumnSelector ( parent_form->apply_group, parent_form, parts);
4630
4631 }
4632
4633 extern void LoadFeatureQualifierTable (IteM i)
4634 {
4635 BaseFormPtr bfp;
4636 ValNodePtr header_line;
4637 ValNodePtr vnp;
4638 TableLinePtr tlp;
4639 WindoW w;
4640 GrouP h, g, c;
4641 FeatureQualLoadFormPtr form_data;
4642 Int4 max_columns;
4643
4644 #ifdef WIN_MAC
4645 bfp = currentFormDataPtr;
4646 #else
4647 bfp = GetObjectExtra (i);
4648 #endif
4649 if (bfp == NULL) return;
4650
4651 header_line = ReadTableData ();
4652 if (header_line == NULL || header_line->data.ptrvalue == NULL) return;
4653 tlp = header_line->data.ptrvalue;
4654 max_columns = 0;
4655 for (vnp = tlp->parts; vnp != NULL; vnp = vnp->next)
4656 {
4657 max_columns ++;
4658 }
4659
4660 form_data = MemNew (sizeof (FeatureQualLoadFormData));
4661 if (form_data == NULL) return;
4662 form_data->asked_about_replace = FALSE;
4663 form_data->do_replace = FALSE;
4664 form_data->use_semicolon = FALSE;
4665 form_data->entityID = bfp->input_entityID;
4666 form_data->line_list = header_line;
4667 form_data->featlist = BuildFeatureValNodeList (TRUE, NULL, 0, TRUE, FALSE);
4668 form_data->num_feats = 0;
4669 for (vnp = form_data->featlist; vnp != NULL; vnp = vnp->next)
4670 {
4671 form_data->num_feats ++;
4672 }
4673
4674 /* now create a dialog to display values */
4675 w = FixedWindow (-50, -33, -10, -10, "Table Conversion", StdCloseWindowProc);
4676 SetObjectExtra (w, form_data, CleanupFeatureQualLoadForm);
4677 form_data->form = (ForM) w;
4678
4679 h = HiddenGroup (w, -1, 0, NULL);
4680 SetGroupSpacing (h, 10, 10);
4681
4682 BuildSequenceSelect ( h, form_data, tlp->parts);
4683 BuildFeatureSelect (h, form_data, tlp->parts);
4684 BuildFeatureApply (h, form_data, tlp->parts);
4685 ShowQualifierLists (form_data);
4686
4687 g = HiddenGroup (h, 1, 0, NULL);
4688 form_data->replace_with_blank_btn = CheckBox (g, "Erase current value when blank found in table", NULL);
4689 c = HiddenGroup (h, 4, 0, NULL);
4690 form_data->accept_button = DefaultButton (c, "Accept", DoAcceptFeatureQuals);
4691 SetObjectExtra (form_data->accept_button, form_data, NULL);
4692 Disable (form_data->accept_button);
4693 PushButton (c, "Cancel", StdCancelButtonProc);
4694
4695 AlignObjects (ALIGN_CENTER,
4696 (HANDLE) form_data->seq_group,
4697 (HANDLE) form_data->match_group,
4698 (HANDLE) form_data->apply_group,
4699 (HANDLE) c, NULL);
4700
4701 RealizeWindow (w);
4702 Show (w);
4703 Update ();
4704 }
4705
4706
4707 typedef struct qualloadformdata {
4708 FEATURE_FORM_BLOCK
4709 ValNodePtr table;
4710 DialoG list_dlg;
4711 DialoG PNTR column_list;
4712 Int4 num_columns;
4713 ButtoN remove_quotes;
4714 ButtoN accept_button;
4715 } QualLoadFormData, PNTR QualLoadFormPtr;
4716
4717 static void CleanupQualLoadForm (
4718 GraphiC g,
4719 VoidPtr data
4720 )
4721 {
4722 QualLoadFormPtr form_data;
4723
4724 form_data = (QualLoadFormPtr)data;
4725 if (form_data == NULL) return;
4726 form_data->table = FreeTabTable (form_data->table);
4727 StdCleanupFormProc (g, data);
4728 }
4729
4730
4731 static void ChangeTabColumnChoice (Pointer data)
4732 {
4733 QualLoadFormPtr form_data;
4734 Int4 i;
4735 Boolean have_match = FALSE, have_apply = FALSE;
4736 TabColumnConfigPtr t;
4737 ValNodePtr err_list = NULL;
4738
4739 if (data == NULL) return;
4740
4741 form_data = (QualLoadFormPtr) data;
4742 /* must have one and only one match choice, must have at least one apply choice */
4743
4744 if (form_data->list_dlg == NULL) {
4745 for (i = 0; i < form_data->num_columns; i++) {
4746 t = (TabColumnConfigPtr) DialogToPointer (form_data->column_list[i]);
4747 if (t != NULL) {
4748 if (t->match_type != NULL) {
4749 if (have_match) {
4750 Disable (form_data->accept_button);
4751 return;
4752 } else {
4753 have_match = TRUE;
4754 }
4755 } else if (!IsFieldTypeEmpty(t->field)) {
4756 have_apply = TRUE;
4757 }
4758 }
4759 t = TabColumnConfigFree (t);
4760 }
4761 if (have_match && have_apply) {
4762 Enable (form_data->accept_button);
4763 } else {
4764 Disable (form_data->accept_button);
4765 }
4766 } else {
4767 err_list = TestDialog (form_data->list_dlg);
4768 if (err_list == NULL) {
4769 Enable (form_data->accept_button);
4770 } else {
4771 Disable (form_data->accept_button);
4772 err_list = ValNodeFree (err_list);
4773 }
4774 }
4775 }
4776
4777
4778 static Boolean ApplyTableValues (SeqEntryPtr sep, ValNodePtr table, ValNodePtr columns)
4779 {
4780 ValNodePtr err_list, vnp, obj_table, dup_dest_errs;
4781 LogInfoPtr lip;
4782 Int4 msg_len = 0;
4783 CharPtr msg = NULL, msg_end = "Continue with errors? Hit cancel to scroll through details";
4784
4785 lip = OpenLog ("Table Problems");
4786
4787 err_list = ValidateTabTableValues (table, columns);
4788 for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
4789 fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
4790 lip->data_in_log = TRUE;
4791 }
4792 err_list = ValNodeFreeData (err_list);
4793
4794 obj_table = GetObjectTableForTabTable (sep, table, columns, &err_list);
4795
4796 dup_dest_errs = CheckObjTableForRowsThatApplyToTheSameDestination (obj_table);
4797 if (dup_dest_errs != NULL) {
4798 for (vnp = dup_dest_errs; vnp != NULL; vnp = vnp->next) {
4799 fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
4800 lip->data_in_log = TRUE;
4801 }
4802 CloseLog (lip);
4803 Message (MSG_ERROR, "For one or more columns, two or more rows in the table apply to the same object. Cannot continue.");
4804 dup_dest_errs = ValNodeFreeData (dup_dest_errs);
4805 err_list = ValNodeFreeData (err_list);
4806 FreeLog (lip);
4807 obj_table = FreeObjectTableForTabTable (obj_table);
4808 DeleteMarkedObjects (SeqMgrGetEntityIDForSeqEntry (sep), 0, NULL);
4809 return FALSE;
4810 }
4811
4812 ValNodeLink (&err_list, CheckObjTableForExistingText (sep, table, columns, obj_table));
4813
4814 msg_len = StringLen (msg_end) + 1;
4815 /* cycle through errors twice - first time, just print the ones with choice 1 (and sum lengths) */
4816 for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
4817 if (vnp->choice == 1) {
4818 fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
4819 lip->data_in_log = TRUE;
4820 msg_len += StringLen (vnp->data.ptrvalue) + 2;
4821 }
4822 }
4823 /* then cycle again, printing 0s */
4824 for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
4825 if (vnp->choice == 0) {
4826 fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
4827 lip->data_in_log = TRUE;
4828 }
4829 }
4830
4831 /* now produce error message */
4832 if (lip->data_in_log) {
4833 msg = (CharPtr) MemNew (sizeof (Char) * msg_len);
4834 for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
4835 if (vnp->choice == 1) {
4836 StringCat (msg, vnp->data.ptrvalue);
4837 StringCat (msg, "\n");
4838 }
4839 }
4840 StringCat (msg, msg_end);
4841 }
4842
4843 err_list = ValNodeFreeData (err_list);
4844
4845 CloseLog (lip);
4846 if (lip->data_in_log) {
4847 if (ANS_CANCEL == Message (MSG_OKC, msg)) {
4848 msg = MemFree (msg);
4849 FreeLog (lip);
4850 DeleteMarkedObjects (SeqMgrGetEntityIDForSeqEntry (sep), 0, NULL);
4851 return FALSE;
4852 }
4853 }
4854 msg = MemFree (msg);
4855 FreeLog (lip);
4856
4857 err_list = ApplyTableValuesToObjectTable (sep, table, columns, obj_table);
4858
4859 lip = OpenLog ("Table Problems");
4860 for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
4861 fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
4862 lip->data_in_log = TRUE;
4863 }
4864 err_list = ValNodeFreeData (err_list);
4865 CloseLog (lip);
4866 FreeLog (lip);
4867 obj_table = FreeObjectTableForTabTable (obj_table);
4868 DeleteMarkedObjects (SeqMgrGetEntityIDForSeqEntry (sep), 0, NULL);
4869 return TRUE;
4870 }
4871
4872
4873 static void DoAcceptQuals (ButtoN b)
4874 {
4875 QualLoadFormPtr form_data;
4876 ValNodePtr columns = NULL;
4877 Int4 i;
4878 TabColumnConfigPtr t;
4879 SeqEntryPtr sep;
4880
4881 form_data = (QualLoadFormPtr) GetObjectExtra (b);
4882 if (form_data == NULL) return;
4883
4884 if (GetStatus (form_data->remove_quotes)) {
4885 RemoveQuotesFromTabTable (form_data->table);
4886 }
4887
4888 if (form_data->list_dlg == NULL) {
4889 for (i = 0; i < form_data->num_columns; i++) {
4890 t = DialogToPointer (form_data->column_list[i]);
4891 ValNodeAddPointer (&columns, 0, t);
4892 }
4893 } else {
4894 columns = DialogToPointer (form_data->list_dlg);
4895 }
4896
4897 sep = GetTopSeqEntryForEntityID (form_data->input_entityID);
4898 if (ApplyTableValues (sep, form_data->table, columns)) {
4899 ObjMgrSetDirtyFlag (form_data->input_entityID, TRUE);
4900 ObjMgrSendMsg (OM_MSG_UPDATE, form_data->input_entityID, 0, 0);
4901 if (GetStatus (form_data->leave_dlg_up)) {
4902 } else {
4903 Remove (form_data->form);
4904 }
4905 Update();
4906 }
4907 columns = TabColumnConfigListFree (columns);
4908
4909 }
4910
4911
4912 static void AutoMatchQuals (ButtoN b)
4913 {
4914 QualLoadFormPtr form_data;
4915 ValNodePtr val, vnp;
4916 ValNodePtr columns = NULL;
4917 Int4 i;
4918 TabColumnConfigPtr t;
4919
4920 form_data = (QualLoadFormPtr) GetObjectExtra (b);
4921 if (form_data == NULL) return;
4922
4923 if (form_data->list_dlg == NULL) {
4924 for (i = 0; i < form_data->num_columns; i++) {
4925 t = DialogToPointer (form_data->column_list[i]);
4926 ValNodeAddPointer (&columns, 0, t);
4927 }
4928 } else {
4929 columns = DialogToPointer (form_data->list_dlg);
4930 }
4931
4932 for (val = form_data->table->data.ptrvalue, vnp = columns;
4933 val != NULL;
4934 val = val->next, vnp = vnp->next) {
4935 if (vnp == NULL) {
4936 vnp = ValNodeNew (columns);
4937 }
4938 t = vnp->data.ptrvalue;
4939 if (t == NULL) {
4940 t = TabColumnConfigNew ();
4941 vnp->data.ptrvalue = t;
4942 }
4943 if (t->match_type == NULL && t->field == NULL) {
4944 t->field = FieldTypeFromString (val->data.ptrvalue);
4945 if (t->field == NULL) {
4946 t = TabColumnConfigFree (t);
4947 vnp->data.ptrvalue = NULL;
4948 }
4949 }
4950 }
4951
4952 if (form_data->list_dlg == NULL) {
4953 for (i = 0, vnp = columns; i < form_data->num_columns && vnp != NULL; i++, vnp = vnp->next) {
4954 PointerToDialog (form_data->column_list[i], vnp->data.ptrvalue);
4955 }
4956 } else {
4957 PointerToDialog (form_data->list_dlg, columns);
4958 }
4959 columns = TabColumnConfigListFree (columns);
4960 }
4961
4962
4963 static WindoW CreateTableReaderWindowWithTable (Uint2 entityID, ValNodePtr table);
4964
4965 static void LoadNewTable (ButtoN b)
4966 {
4967 Char path [PATH_MAX];
4968 FILE *fp;
4969 QualLoadFormPtr form_data, new_form_data;
4970 ValNodePtr table, special_list, blank_list, columns = NULL, c_vnp;
4971 Int4 i;
4972 WindoW w;
4973 TabColumnConfigPtr t;
4974
4975 form_data = (QualLoadFormPtr) GetObjectExtra (b);
4976 if (form_data == NULL) return;
4977
4978 path [0] = '\0';
4979 if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return;
4980
4981 fp = FileOpen (path, "r");
4982
4983 table = ReadTabTableFromFile (fp);
4984 FileClose (fp);
4985 if (table == NULL) return;
4986 special_list = ScanTabTableForSpecialCharacters (table);
4987 if (special_list != NULL
4988 && !FixSpecialCharactersForStringsInList (special_list,
4989 "The table contains special characters\nand cannot be used until they are replaced.",
4990 FALSE)) {
4991 special_list = FreeContextList (special_list);
4992 return;
4993 }
4994 special_list = FreeContextList (special_list);
4995 if (form_data->list_dlg != NULL) {
4996 form_data->table = table;
4997 /* it's ok, can just repopulate dialogs */
4998 blank_list = CountTabTableBlanks (table);
4999 ChangeDataForTabColumnConfigListDialog (form_data->list_dlg, form_data->table->data.ptrvalue, blank_list);
5000 blank_list = ValNodeFree (blank_list);
5001 } else {
5002 /* build a new window */
5003 w = CreateTableReaderWindowWithTable (form_data->input_entityID, table);
5004 /* get old configurations */
5005 if (form_data->list_dlg == NULL) {
5006 for (i = 0; i < form_data->num_columns; i++) {
5007 t = DialogToPointer (form_data->column_list[i]);
5008 ValNodeAddPointer (&columns, 0, t);
5009 }
5010 } else {
5011 columns = DialogToPointer (form_data->list_dlg);
5012 }
5013
5014 /* apply to new window */
5015 new_form_data = (QualLoadFormPtr) GetObjectExtra (w);
5016 if (new_form_data->list_dlg == NULL) {
5017 for (i = 0, c_vnp = columns; i < new_form_data->num_columns && c_vnp != NULL; i++, c_vnp = c_vnp->next) {
5018 PointerToDialog (new_form_data->column_list[i], c_vnp->data.ptrvalue);
5019 }
5020 } else {
5021 PointerToDialog (new_form_data->list_dlg, columns);
5022 }
5023 columns = ValNodeFree (columns);
5024 SetStatus (new_form_data->remove_quotes, GetStatus (form_data->remove_quotes));
5025 SetStatus (new_form_data->leave_dlg_up, GetStatus (form_data->leave_dlg_up));
5026
5027 /* remove old window */
5028 Remove ((WindoW) form_data->form);
5029
5030 RealizeWindow (w);
5031 Show (w);
5032 Update ();
5033 }
5034
5035
5036 }
5037
5038
5039 static WindoW CreateTableReaderWindowWithTable (Uint2 entityID, ValNodePtr table)
5040 {
5041 ValNodePtr blank_list;
5042 ValNodePtr col_vnp, blank_vnp;
5043 Int4 index;
5044 WindoW w;
5045 GrouP h, g, g2, c;
5046 QualLoadFormPtr form_data;
5047 CharPtr title;
5048 Int4 col_for_list = 3;
5049 Char buf[15];
5050 ButtoN b;
5051
5052 form_data = MemNew (sizeof (QualLoadFormData));
5053 if (form_data == NULL) return NULL;
5054 form_data->input_entityID = entityID;
5055 form_data->table = table;
5056 blank_list = CountTabTableBlanks (form_data->table);
5057 form_data->num_columns = ValNodeLen (blank_list);
5058 form_data->column_list = (DialoG PNTR) MemNew (sizeof (DialoG) * form_data->num_columns);
5059
5060 /* now create a dialog to display values */
5061 w = FixedWindow (-50, -33, -10, -10, "Apply Qualifiers", StdCloseWindowProc);
5062 SetObjectExtra (w, form_data, CleanupQualLoadForm);
5063 form_data->form = (ForM) w;
5064
5065 h = HiddenGroup (w, -1, 0, NULL);
5066 SetGroupSpacing (h, 10, 10);
5067
5068 if (GetSequinAppParam ("SETTINGS", "tablecolumns", NULL, buf, sizeof (buf))) {
5069 col_for_list = atoi (buf);
5070 }
5071
5072
5073 if (form_data->num_columns >= col_for_list) {
5074 form_data->list_dlg = TabColumnConfigListDialog (h, form_data->table->data.ptrvalue, blank_list, ChangeTabColumnChoice, form_data);
5075 g = (GrouP) form_data->list_dlg;
5076 } else {
5077 g = HiddenGroup (h, 3, 0, NULL);
5078 col_vnp = form_data->table->data.ptrvalue;
5079 blank_vnp = blank_list;
5080 for (index = 0; index < form_data->num_columns; index++) {
5081 if (col_vnp == NULL || StringHasNoText (col_vnp->data.ptrvalue)) {
5082 title = StringSave ("First row value is blank");
5083 } else {
5084 title = StringSave (col_vnp->data.ptrvalue);
5085 if (StringLen (title) > 104) {
5086 StringCpy (title + 100, "...");
5087 *(title + 103) = 0;
5088 }
5089 }
5090 form_data->column_list[index] = TabColumnConfigDialog (g, title, blank_vnp->data.intvalue, ChangeTabColumnChoice, form_data);
5091 title = MemFree (title);
5092 if (col_vnp != NULL) {
5093 col_vnp = col_vnp->next;
5094 }
5095 blank_vnp = blank_vnp->next;
5096 }
5097 }
5098
5099 g2 = HiddenGroup (h, 2, 0, NULL);
5100 b = PushButton (g2, "Automatch Qualifiers", AutoMatchQuals);
5101 SetObjectExtra (b, form_data, NULL);
5102 form_data->remove_quotes = CheckBox (g2, "Remove quotes around values", NULL);
5103 SetStatus (form_data->remove_quotes, TRUE);
5104
5105 c = HiddenGroup (h, 4, 0, NULL);
5106 form_data->accept_button = DefaultButton (c, "Accept", DoAcceptQuals);
5107 SetObjectExtra (form_data->accept_button, form_data, NULL);
5108 Disable (form_data->accept_button);
5109 b = PushButton (c, "Load New Table", LoadNewTable);
5110 SetObjectExtra (b, form_data, NULL);
5111 PushButton (c, "Cancel", StdCancelButtonProc);
5112 form_data->leave_dlg_up = CheckBox (c, "Leave Dialog Up", NULL);
5113
5114 AlignObjects (ALIGN_CENTER,
5115 (HANDLE) g,
5116 (HANDLE) g2,
5117 (HANDLE) c, NULL);
5118
5119 blank_list = ValNodeFree (blank_list);
5120 return w;
5121 }
5122
5123
5124 static WindoW CreateTableReaderWindow (Uint2 entityID)
5125 {
5126 Char path [PATH_MAX];
5127 FILE *fp;
5128
5129 ValNodePtr table;
5130 ValNodePtr special_list;
5131
5132 path [0] = '\0';
5133 if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return NULL;
5134
5135 fp = FileOpen (path, "r");
5136
5137 table = ReadTabTableFromFile (fp);
5138 FileClose (fp);
5139 if (table == NULL) return NULL;
5140 special_list = ScanTabTableForSpecialCharacters (table);
5141 if (special_list != NULL
5142 && !FixSpecialCharactersForStringsInList (special_list,
5143 "The table contains special characters\nand cannot be used until they are replaced.",
5144 FALSE)) {
5145 special_list = FreeContextList (special_list);
5146 return NULL;
5147 }
5148 special_list = FreeContextList (special_list);
5149
5150 return CreateTableReaderWindowWithTable (entityID, table);
5151 }
5152
5153
5154 extern void NewLoadFeatureQualifierTable (IteM i)
5155 {
5156 BaseFormPtr bfp;
5157 WindoW w;
5158 QualLoadFormPtr form_data;
5159 TabColumnConfigPtr t;
5160 ValNodePtr column_list = NULL;
5161
5162 #ifdef WIN_MAC
5163 bfp = currentFormDataPtr;
5164 #else
5165 bfp = GetObjectExtra (i);
5166 #endif
5167 if (bfp == NULL) return;
5168
5169 w = CreateTableReaderWindow (bfp->input_entityID);
5170
5171 if (w != NULL) {
5172 /* populate */
5173 form_data = (QualLoadFormPtr) GetObjectExtra (w);
5174 if (form_data != NULL) {
5175 t = TabColumnConfigNew ();
5176 t->match_type = MatchTypeNew ();
5177 t->match_type->match_location = eTableMatchNucID;
5178 if (form_data->list_dlg == NULL) {
5179 PointerToDialog (form_data->column_list[0], t);
5180 } else {
5181 ValNodeAddPointer (&column_list, 0, t);
5182 PointerToDialog (form_data->list_dlg, column_list);
5183 column_list = ValNodeFree (column_list);
5184 }
5185 t = TabColumnConfigFree (t);
5186 }
5187
5188 RealizeWindow (w);
5189 Show (w);
5190 Update ();
5191 }
5192 }
5193
5194
5195 extern void LoadTaxTableReader (IteM i)
5196 {
5197 BaseFormPtr bfp;
5198 WindoW w;
5199 QualLoadFormPtr form_data;
5200 TabColumnConfigPtr t;
5201 ValNodePtr column_list = NULL, s;
5202
5203 #ifdef WIN_MAC
5204 bfp = currentFormDataPtr;
5205 #else
5206 bfp = GetObjectExtra (i);
5207 #endif
5208 if (bfp == NULL) return;
5209
5210 w = CreateTableReaderWindow (bfp->input_entityID);
5211
5212 if (w != NULL) {
5213 /* populate */
5214 form_data = (QualLoadFormPtr) GetObjectExtra (w);
5215 if (form_data != NULL) {
5216 if (form_data->list_dlg == NULL) {
5217 if (form_data->num_columns > 1) {
5218 t = TabColumnConfigNew ();
5219 t->match_type = MatchTypeNew ();
5220 t->match_type->choice = eTableMatchBioSource;
5221 PointerToDialog (form_data->column_list[0], t);
5222 t->match_type = MatchTypeFree(t->match_type);
5223 t->field = ValNodeNew(NULL);
5224 t->field->choice = FieldType_source_qual;
5225 s = ValNodeNew (NULL);
5226 t->field->data.ptrvalue = s;
5227 s->choice = SourceQualChoice_textqual;
5228 s->data.intvalue = Source_qual_taxname;
5229 PointerToDialog (form_data->column_list[1], t);
5230 t = TabColumnConfigFree(t);
5231 }
5232 } else {
5233 t = TabColumnConfigNew ();
5234 t->match_type = MatchTypeNew ();
5235 t->match_type->choice = eTableMatchBioSource;
5236 PointerToDialog (form_data->column_list[0], t);
5237 ValNodeAddPointer (&column_list, 0, t);
5238 t = TabColumnConfigNew ();
5239 t->field = ValNodeNew(NULL);
5240 t->field->choice = FieldType_source_qual;
5241 s = ValNodeNew (NULL);
5242 t->field->data.ptrvalue = s;
5243 s->choice = SourceQualChoice_textqual;
5244 s->data.intvalue = Source_qual_taxname;
5245 ValNodeAddPointer (&column_list, 0, t);
5246 PointerToDialog (form_data->list_dlg, column_list);
5247 column_list = TabColumnConfigListFree (column_list);
5248 }
5249 }
5250
5251 RealizeWindow (w);
5252 Show (w);
5253 Update ();
5254 }
5255 }
5256
5257
5258 extern void NewLoadSourceQualifierTable (IteM i)
5259 {
5260 BaseFormPtr bfp;
5261 WindoW w;
5262 QualLoadFormPtr form_data;
5263 TabColumnConfigPtr t1, t2;
5264 ValNodePtr column_list = NULL, vnp;
5265 Int4 n;
5266
5267 #ifdef WIN_MAC
5268 bfp = currentFormDataPtr;
5269 #else
5270 bfp = GetObjectExtra (i);
5271 #endif
5272 if (bfp == NULL) return;
5273
5274 w = CreateTableReaderWindow (bfp->input_entityID);
5275
5276 if (w != NULL) {
5277 /* populate */
5278 form_data = (QualLoadFormPtr) GetObjectExtra (w);
5279 if (form_data != NULL) {
5280 t1 = TabColumnConfigNew ();
5281 t1->match_type = MatchTypeNew ();
5282 t1->match_type->match_location = eTableMatchNucID;
5283 t2 = TabColumnConfigNew ();
5284 vnp = ValNodeNew (NULL);
5285 vnp->choice = SourceQualChoice_textqual;
5286 vnp->data.intvalue = Source_qual_acronym;
5287 t2->field = ValNodeNew (NULL);
5288 t2->field->choice = FieldType_source_qual;
5289 t2->field->data.ptrvalue = vnp;
5290
5291 if (form_data->list_dlg == NULL) {
5292 PointerToDialog (form_data->column_list[0], t1);
5293 PointerToDialog (form_data->column_list[1], t2);
5294 } else {
5295 ValNodeAddPointer (&column_list, 0, t1);
5296 for (n = 1; n < form_data->num_columns; n++) {
5297 ValNodeAddPointer (&column_list, 0, t2);
5298 }
5299 PointerToDialog (form_data->list_dlg, column_list);
5300 column_list = ValNodeFree (column_list);
5301 }
5302 t1 = TabColumnConfigFree (t1);
5303 t2 = TabColumnConfigFree (t2);
5304 }
5305
5306 RealizeWindow (w);
5307 Show (w);
5308 Update ();
5309 }
5310 }
5311
5312
5313 extern void ExternalSourceQualifierTableReader (IteM i)
5314 {
5315 Char path [PATH_MAX];
5316 BaseFormPtr bfp;
5317 ValNodePtr table, columns = NULL, header_row, val;
5318 TabColumnConfigPtr t;
5319 LogInfoPtr lip;
5320 Boolean any_valid = FALSE;
5321 MsgAnswer ans = ANS_OK;
5322 SeqEntryPtr sep;
5323 FILE *fp;
5324
5325 #ifdef WIN_MAC
5326 bfp = currentFormDataPtr;
5327 #else
5328 bfp = GetObjectExtra (i);
5329 #endif
5330 if (bfp == NULL || bfp->input_entityID == 0) return;
5331
5332 path [0] = '\0';
5333 if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return;
5334
5335 fp = FileOpen (path, "r");
5336 if (fp == NULL) {
5337 Message (MSG_ERROR, "Unable to read from %s", path);
5338 return;
5339 }
5340
5341 table = ReadTabTableFromFile (fp);
5342 FileClose (fp);
5343 if (table == NULL) {
5344 Message (MSG_ERROR, "Unable to read table from %s", path);
5345 return;
5346 }
5347
5348 RemoveQuotesFromTabTable (table);
5349
5350 /* first column is sequence ID */
5351 t = TabColumnConfigNew ();
5352 t->match_type = MatchTypeNew ();
5353 t->match_type->match_location = eTableMatchNucID;
5354 ValNodeAddPointer (&columns, 0, t);
5355
5356 lip = OpenLog ("Table Problems");
5357 fprintf (lip->fp, "The following header values could not be matched to valid qualifier names. They will be ignored.\n");
5358
5359 /* automatch qualifiers */
5360 header_row = table->data.ptrvalue;
5361 if (header_row == NULL) {
5362 Message (MSG_ERROR, "First row of table must contain headers!");
5363 } else {
5364 for (val = header_row->next;
5365 val != NULL;
5366 val = val->next) {
5367 t = TabColumnConfigNew ();
5368 t->field = FieldTypeFromString (val->data.ptrvalue);
5369 if (t->field == NULL) {
5370 t = TabColumnConfigFree (t);
5371 fprintf (lip->fp, "%s\n", val->data.ptrvalue);
5372 lip->data_in_log = TRUE;
5373 } else {
5374 any_valid = TRUE;
5375 }
5376 ValNodeAddPointer (&columns, 0, t);
5377 }
5378 }
5379
5380 CloseLog (lip);
5381 if (lip->data_in_log) {
5382 ans = Message (MSG_OKC, "Some column headers were not recognized. The values in this column will be ignored. Continue anyway?");
5383 }
5384 lip = FreeLog (lip);
5385
5386 if (ans == ANS_OK) {
5387 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5388 if (ApplyTableValues (sep, table->next, columns)) {
5389 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
5390 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5391 Update();
5392 }
5393 }
5394 columns = TabColumnConfigListFree (columns);
5395 table = FreeTabTable (table);
5396 }
5397
5398
5399 typedef struct prefixformdata {
5400 FEATURE_FORM_BLOCK
5401
5402 ModifierItemLocalPtr modList;
5403 PopuP PNTR popup_list;
5404 ButtoN add_org_name;
5405 ButtoN use_labels;
5406 } PrefixFormData, PNTR PrefixFormPtr;
5407
5408 static void CleanupPrefixForm (
5409 GraphiC g,
5410 VoidPtr data
5411 )
5412
5413 {
5414 PrefixFormPtr pfp;
5415 Int4 i;
5416
5417 pfp = (PrefixFormPtr) data;
5418 if (pfp != NULL) {
5419 if (pfp->modList != NULL)
5420 {
5421 for (i=0; i < NumDefLineModifiers (); i++)
5422 {
5423 ValNodeFree (pfp->modList[i].values_seen);
5424 }
5425 MemFree (pfp->modList);
5426 }
5427 if (pfp->popup_list != NULL)
5428 {
5429 MemFree (pfp->popup_list);
5430 }
5431 }
5432 StdCleanupFormProc (g, data);
5433 }
5434
5435 static Int4 GetDefLineModifierPopupIndex (
5436 Int4 popup_index,
5437 ModifierItemLocalPtr modList
5438 )
5439 {
5440 Int4 index;
5441 Int4 want_index;
5442
5443 want_index = 0;
5444 for (index = 0;
5445 index < NumDefLineModifiers () && want_index < popup_index;
5446 index++)
5447 {
5448 if (modList [index].any_present)
5449 {
5450 want_index ++;
5451 }
5452 }
5453 if (index >= NumDefLineModifiers () || index == 0
5454 || want_index < popup_index)
5455 {
5456 return -1;
5457 }
5458 return index - 1;
5459 }
5460
5461 static void AddPrefixesToOneDefLine (
5462 PrefixFormPtr pfp,
5463 BioseqPtr bsp,
5464 SeqEntryPtr sep
5465 )
5466 {
5467 BioSourcePtr biop;
5468 SeqDescrPtr sdp;
5469 ValNodePtr strings;
5470 Int4 index;
5471 Int4 qual_index;
5472 Int4 popup_choice;
5473 CharPtr new_defline;
5474 Char taxName [196];
5475 Char modifier_text [256];
5476 OrgRefPtr orp;
5477 OrgNamePtr onp;
5478 OrgModPtr mod;
5479 SubSourcePtr ssp;
5480 CharPtr org_desc;
5481 CharPtr cp;
5482 SeqMgrDescContext dcontext;
5483 Boolean use_labels;
5484 Uint4 no_semicolon_len;
5485 Int4 prefix_len;
5486
5487 if (bsp == NULL || pfp == NULL
5488 || pfp->popup_list == NULL
5489 || pfp->modList == NULL
5490 || (biop = GetBiopForBsp (bsp)) == NULL)
5491 {
5492 return;
5493 }
5494
5495 if (biop->org == NULL) return;
5496 if (biop->org->taxname == NULL) return;
5497 StringNCpy (taxName, biop->org->taxname, sizeof (taxName) - 1);
5498 taxName [ sizeof (taxName) - 1] = 0;
5499
5500 strings = NULL;
5501 CleanUpTaxName (taxName, TRUE);
5502 if (GetStatus (pfp->add_org_name))
5503 {
5504 ValNodeCopyStr( &strings, 0, taxName);
5505 }
5506
5507 use_labels = GetStatus (pfp->use_labels);
5508
5509 orp = biop->org;
5510 if (orp == NULL) return;
5511 onp = orp->orgname;
5512 if (onp == NULL) return;
5513 for (index = 0; index < NumDefLineModifiers (); index ++)
5514 {
5515 if (pfp->popup_list [ index] != NULL
5516 && (popup_choice = GetValue (pfp->popup_list [ index])) > 0)
5517 {
5518 qual_index = GetDefLineModifierPopupIndex (popup_choice, pfp->modList);
5519 if (qual_index < 0 || qual_index >= NumDefLineModifiers ()) continue;
5520 if (DefLineModifiers[qual_index].isOrgMod)
5521 {
5522 mod = onp->mod;
5523 while (mod != NULL
5524 && mod->subtype != DefLineModifiers[qual_index].subtype)
5525 {
5526 mod = mod->next;
5527 }
5528 if ( UseOrgModifier (mod, taxName, FALSE))
5529 {
5530 no_semicolon_len = StringCSpn (mod->subname, ";");
5531 if (mod->subtype == ORGMOD_nat_host)
5532 {
5533 sprintf (modifier_text, "from ");
5534 if (no_semicolon_len > sizeof (modifier_text) - 6) {
5535 prefix_len = sizeof (modifier_text) - 1;
5536 no_semicolon_len = sizeof (modifier_text) - 6;
5537 } else {
5538 prefix_len = no_semicolon_len + 5;
5539 }
5540 StringNCpy (modifier_text + 5, mod->subname, no_semicolon_len);
5541 modifier_text[prefix_len] = 0;
5542 }
5543 else
5544 {
5545 AddModifierLabel (use_labels, TRUE, mod->subtype, modifier_text);
5546 if (modifier_text[0] != 0)
5547 StringCat (modifier_text, " ");
5548 if (no_semicolon_len > sizeof (modifier_text) - StringLen (modifier_text) - 1) {
5549 no_semicolon_len = sizeof (modifier_text) - StringLen (modifier_text) - 1;
5550 prefix_len = sizeof (modifier_text) - 1;
5551 } else {
5552 prefix_len = no_semicolon_len + StringLen (modifier_text);
5553 }
5554
5555 StringNCat (modifier_text, mod->subname, no_semicolon_len);
5556 modifier_text[prefix_len] = 0;
5557 }
5558 ValNodeCopyStr( &strings, 0, modifier_text);
5559 }
5560 } else {
5561 ssp = biop->subtype;
5562 while (ssp != NULL
5563 && ssp->subtype != DefLineModifiers[qual_index].subtype)
5564 {
5565 ssp = ssp->next;
5566 }
5567 if (ssp != NULL)
5568 {
5569 no_semicolon_len = StringCSpn (ssp->name, ";");
5570 AddModifierLabel (use_labels, FALSE, ssp->subtype, modifier_text);
5571 if (ssp->subtype == SUBSRC_country)
5572 {
5573 sprintf (modifier_text, "from ");
5574 if (no_semicolon_len > sizeof (modifier_text) - 6) {
5575 no_semicolon_len = sizeof (modifier_text) - 6;
5576 prefix_len = sizeof(modifier_text);
5577 } else {
5578 prefix_len = StringLen (modifier_text) + no_semicolon_len;
5579 }
5580 StringNCpy (modifier_text + 5, ssp->name, no_semicolon_len);
5581 modifier_text[prefix_len] = 0;
5582 cp = StringChr (modifier_text, ':');
5583 if (cp != NULL) *cp = 0;
5584 }
5585 else if (ssp->name != NULL
5586 && (ssp->subtype != SUBSRC_plasmid_name
5587 || StringCmp (ssp->name, "unnamed") != 0))
5588 {
5589 if (modifier_text[0] != 0)
5590 StringCat (modifier_text, " ");
5591 if (no_semicolon_len > sizeof (modifier_text) - StringLen (modifier_text) - 1) {
5592 no_semicolon_len = sizeof (modifier_text) - StringLen (modifier_text) - 1;
5593 prefix_len = sizeof (modifier_text);
5594 } else {
5595 prefix_len = StringLen (modifier_text) + no_semicolon_len;
5596 }
5597
5598 StringNCat (modifier_text, ssp->name, no_semicolon_len);
5599 modifier_text[prefix_len] = 0;
5600 }
5601 ValNodeCopyStr( &strings, 0, modifier_text);
5602 }
5603 }
5604 }
5605 }
5606 org_desc = MergeValNodeStrings (strings, FALSE);
5607 ValNodeFreeData (strings);
5608
5609 sdp = SeqEntryGetSeqDescr (sep, Seq_descr_title, NULL);
5610 if (sdp == NULL) {
5611 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_title, &dcontext);
5612 if (sdp == NULL) return;
5613 cp = (CharPtr) sdp->data.ptrvalue;
5614 if (cp == NULL) return;
5615 sdp = SeqDescrAdd (&(bsp->descr));
5616 if (sdp == NULL) return;
5617 sdp->choice = Seq_descr_title;
5618 sdp->data.ptrvalue = StringSave (cp);
5619 }
5620 if (sdp == NULL) return;
5621 if (StringHasNoText (sdp->data.ptrvalue)) return;
5622 new_defline = MemNew ((StringLen (org_desc)
5623 + StringLen (sdp->data.ptrvalue) + 4) * sizeof (Char));
5624 if (new_defline == NULL) return;
5625 StringCpy (new_defline, org_desc);
5626 StringCat (new_defline, " ");
5627 StringCat (new_defline, sdp->data.ptrvalue);
5628 MemFree (sdp->data.ptrvalue);
5629 sdp->data.ptrvalue = new_defline;
5630 ObjMgrSetDirtyFlag (pfp->input_entityID, TRUE);
5631 }
5632
5633 static void AddPrefixesToDefLines (PrefixFormPtr pfp, SeqEntryPtr sep)
5634 {
5635 BioseqSetPtr bssp;
5636 if (pfp == NULL || sep == NULL) return;
5637 if (IS_Bioseq_set (sep)) {
5638 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5639 if (bssp != NULL) {
5640 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
5641 AddPrefixesToDefLines (pfp, sep);
5642 }
5643 return;
5644 }
5645 }
5646 if (! IS_Bioseq (sep)) return;
5647 AddPrefixesToOneDefLine (pfp, sep->data.ptrvalue, sep);
5648 }
5649
5650 static void DoPrefixDefLines (ButtoN b)
5651 {
5652 PrefixFormPtr pfp;
5653 SeqEntryPtr sep;
5654
5655 pfp = GetObjectExtra (b);
5656 if (pfp == NULL) return;
5657
5658 Hide (pfp->form);
5659 WatchCursor ();
5660 Update ();
5661 sep = GetTopSeqEntryForEntityID (pfp->input_entityID);
5662 if (sep == NULL) return;
5663 AddPrefixesToDefLines (pfp, sep);
5664
5665 ArrowCursor ();
5666 Update ();
5667 ObjMgrSetDirtyFlag (pfp->input_entityID, TRUE);
5668 ObjMgrSendMsg (OM_MSG_UPDATE, pfp->input_entityID, 0, 0);
5669 }
5670
5671 extern void PrefixDefLines (IteM i)
5672 {
5673 BaseFormPtr bfp;
5674 SeqEntryPtr sep;
5675 ModifierItemLocalPtr modList;
5676 Int4 index;
5677 WindoW w;
5678 GrouP h, g, k;
5679 Int4 popup_index, item_index, listed_index;
5680 GrouP c;
5681 ButtoN b;
5682 PrefixFormPtr pfp;
5683 Char label [256];
5684
5685 #ifdef WIN_MAC
5686 bfp = currentFormDataPtr;
5687 #else
5688 bfp = GetObjectExtra (i);
5689 #endif
5690 if (bfp == NULL || bfp->input_entityID == 0) return;
5691
5692 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5693 if (sep == NULL) return;
5694
5695 modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
5696 if (modList == NULL) return;
5697 CountModifiers (modList, sep);
5698
5699 pfp = MemNew (sizeof (PrefixFormData));
5700 if (pfp == NULL) return;
5701 pfp->input_entityID = bfp->input_entityID;
5702 pfp->modList = modList;
5703 pfp->popup_list = MemNew (sizeof (PopuP) * NumDefLineModifiers ());
5704 if (pfp->popup_list == NULL) return;
5705
5706 w = FixedWindow (-50, -33, -10, -10, "Definition Line Prefixes",
5707 StdCloseWindowProc);
5708 SetObjectExtra (w, pfp, CleanupPrefixForm);
5709 pfp->form = (ForM) w;
5710
5711 h = HiddenGroup (w, -1, 0, NULL);
5712 SetGroupSpacing (h, 10, 10);
5713 g = HiddenGroup (h, 4, 0, NULL);
5714 for (index = 0; index < NumDefLineModifiers (); index++)
5715 {
5716 pfp->popup_list [index] = NULL;
5717 }
5718 popup_index = 0;
5719 for (index = 0; index < NumDefLineModifiers (); index++)
5720 {
5721 if (modList [ index].any_present)
5722 {
5723 k = HiddenGroup (g, 2, 0, NULL);
5724 sprintf (label, "%d", popup_index + 1);
5725 StaticPrompt (k, label, 0, popupMenuHeight, programFont, 'l');
5726 pfp->popup_list[popup_index] = PopupList (k, TRUE, NULL);
5727 listed_index = 0;
5728 for (item_index = 0; item_index < NumDefLineModifiers (); item_index ++)
5729 {
5730 if (modList [item_index].any_present)
5731 {
5732 PopupItem (pfp->popup_list[popup_index],
5733 DefLineModifiers[item_index].name);
5734 listed_index ++;
5735 }
5736 }
5737 PopupItem (pfp->popup_list[popup_index], "Ignore");
5738 listed_index++;
5739 SetValue (pfp->popup_list[popup_index], listed_index);
5740 popup_index ++;
5741 }
5742 }
5743
5744 pfp->add_org_name = CheckBox (h, "Prefix with taxonomy name", NULL);
5745 SetStatus (pfp->add_org_name, TRUE);
5746 pfp->use_labels = CheckBox (h, "Use modifier labels", NULL);
5747 SetStatus (pfp->use_labels, TRUE);
5748
5749 c = HiddenGroup (h, 4, 0, NULL);
5750 b = DefaultButton (c, "Accept", DoPrefixDefLines);
5751 SetObjectExtra (b, pfp, NULL);
5752 PushButton (c, "Cancel", StdCancelButtonProc);
5753
5754 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) pfp->add_org_name,
5755 (HANDLE) pfp->use_labels,
5756 (HANDLE) c, NULL);
5757 RealizeWindow (w);
5758 Show (w);
5759 Update ();
5760
5761 }
5762
5763 #ifndef WIN16
5764 CharPtr objPrtMemStr = "PrintTemplateSet ::= {\n" \
5765 "{ name \"StdSeqDesc\" ,\n" \
5766 "format { asn1 \"Seqdesc\" , form block {\n" \
5767 "components {\n" \
5768 "{ asn1 \"Seqdesc.mol-type\" , label \"Molecule type\" , prefix \"\\n\" , form enum { } } ,\n" \
5769 "{ asn1 \"Seqdesc.modif\" , label \"Modifiers\" , prefix \"\\n\" , form block {\n" \
5770 "separator \", \" ,\n" \
5771 "components {\n" \
5772 "{ asn1 \"Seqdesc.modif.E\" , form enum { } } } } } ,\n" \
5773 "{ asn1 \"Seqdesc.method\" , label \"Method\" , prefix \"\\n\" , form enum { } } ,\n" \
5774 "{ asn1 \"Seqdesc.name\" , label \"Name\" , prefix \"\\n\" , form text { } } ,\n" \
5775 "{ asn1 \"Seqdesc.title\" , label \"Title\" , prefix \"\\n\" , form text { } } ,\n" \
5776 "{ asn1 \"Seqdesc.org\" , label \"Organism\" , prefix \"\\n\" , form use-template \"StdOrgRef\" } ,\n" \
5777 "{ asn1 \"Seqdesc.comment\" , label \"Comment\" , prefix \"\\n\" , form text { } } ,\n" \
5778 "{ asn1 \"Seqdesc.num\" , label \"Numbering\" , prefix \"\\n\" , form use-template \"StdNumbering\" } ,\n" \
5779 "{ asn1 \"Seqdesc.maploc\" , label \"Map location\" , prefix \"\\n\" , form use-template \"StdDbtag\" } ,\n" \
5780 "{ asn1 \"Seqdesc.pir\" , label \"PIR block\" , prefix \"\\n\" , form null NULL } ,\n" \
5781 "{ asn1 \"Seqdesc.genbank\" , label \"GenBank block\" , prefix \"\\n\" , form use-template \"StdGBBlock\" } ,\n" \
5782 "{ asn1 \"Seqdesc.pub\" , label \"Citation\" , prefix \"\\n\" , form use-template \"StdPubdesc\" } ,\n" \
5783 "{ asn1 \"Seqdesc.region\" , label \"Region\" , prefix \"\\n\" , form text { } } ,\n" \
5784 "{ asn1 \"Seqdesc.user\" , label \"User Type\" , prefix \"\\n\" , form use-template \"StdUserObj\" } ,\n" \
5785 "{ asn1 \"Seqdesc.sp\" , label \"SWISS-PROT block\" , prefix \"\\n\" , form null NULL } ,\n" \
5786 "{ asn1 \"Seqdesc.dbxref\" , label \"Cross reference\" , prefix \"\\n\" , form use-template \"StdDbtag\" } ,\n" \
5787 "{ asn1 \"Seqdesc.embl\" , label \"EMBL block\" , prefix \"\\n\" , form null NULL } ,\n" \
5788 "{ asn1 \"Seqdesc.create-date\" , label \"Create date\" , prefix \"\\n\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
5789 "{ asn1 \"Seqdesc.update-date\" , label \"Update date\" , prefix \"\\n\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
5790 "{ asn1 \"Seqdesc.prf\" , label \"PRF block\" , prefix \"\\n\" , form null NULL } ,\n" \
5791 "{ asn1 \"Seqdesc.pdb\" , label \"PDB block\" , prefix \"\\n\" , form null NULL } ,\n" \
5792 "{ asn1 \"Seqdesc.het\" , label \"Heterogen\" , prefix \"\\n\" , form text { } } ,\n" \
5793 "{ asn1 \"Seqdesc.source\" , label \"Biological Source\" , prefix \"\\n\" , form use-template \"StdBioSource\" } ,\n" \
5794 "{ asn1 \"Seqdesc.molinfo\" , label \"Molecule Information\" , prefix \"\\n\" , form block {\n" \
5795 "separator \", \" ,\n" \
5796 "components {\n" \
5797 "{ asn1 \"MolInfo.biomol\" , form enum { } } ,\n" \
5798 "{ asn1 \"MolInfo.tech\" , form enum { } } ,\n" \
5799 "{ asn1 \"MolInfo.completeness\" , form enum { } } } } } } } } } ,\n" \
5800 "{ name \"StdSeqFeatLocation\" ,\n" \
5801 "format { asn1 \"Seq-feat.location\" , label \"Location\" , prefix \"\\t\" , form user { printfunc \"StdSeqLocPrint\" } } } ,\n" \
5802 "{ name \"StdSeqFeatProduct\" ,\n" \
5803 "format { asn1 \"Seq-feat.product\" , label \"Product\" , prefix \"\\t\" , form user { printfunc \"StdSeqLocPrint\" } } } ,\n" \
5804 "{ name \"EntrySeqFeatData\" ,\n" \
5805 "labelfrom \"Seq-feat.data\" ,\n" \
5806 "format { asn1 \"Seq-feat.data\" , prefix \"\\t\" , form use-template \"StdSeqFeatData\" } } ,\n" \
5807 "{ name \"StdSeqFeat\" ,\n" \
5808 "labelfrom \"Seq-feat.data\" ,\n" \
5809 "format { asn1 \"Seq-feat\" , prefix \"\\n\" , suffix \"\\n\" , form block {\n" \
5810 "separator \"\\n\" ,\n" \
5811 "components {\n" \
5812 "{ asn1 \"Seq-feat.data\" , form use-template \"StdSeqFeatData\" } ,\n" \
5813 "{ asn1 \"Seq-feat\" , form use-template \"StdSeqFeatCommon\" } ,\n" \
5814 "{ asn1 \"Seq-feat.product\" , label \"Product\" , prefix \" \" , form user { printfunc \"StdSeqLocPrint\" } } ,\n" \
5815 "{ asn1 \"Seq-feat.location\" , label \"Location\" , prefix \" \" , form user { printfunc \"StdSeqLocPrint\" } } ,\n" \
5816 "{ asn1 \"Seq-feat.cit\" , label \"Citations\" , prefix \"\\n\" , form block {\n" \
5817 "separator \"\\n\" ,\n" \
5818 "components {\n" \
5819 "{ asn1 \"Seq-feat.cit.pub.E\" , form use-template \"StdPub\" } } } } ,\n" \
5820 "{ asn1 \"Seq-feat.xref\" , label \"Cross-reference\" , prefix \"\\n\" , form block {\n" \
5821 "separator \"\\n\" ,\n" \
5822 "components {\n" \
5823 "{ asn1 \"Seq-feat.xref.E\" , form use-template \"StdSeqFeatXref\" } } } } } } } } ,\n" \
5824 "{ name \"StdSeqFeatData\" ,\n" \
5825 "format { asn1 \"SeqFeatData\" , form block {\n" \
5826 "components {\n" \
5827 "{ asn1 \"SeqFeatData.gene\" , label \"Gene\" , form use-template \"StdGeneRef\" } ,\n" \
5828 "{ asn1 \"SeqFeatData.org\" , label \"Organism\" , form use-template \"StdOrgRef\" } ,\n" \
5829 "{ asn1 \"SeqFeatData.cdregion\" , label \"Coding Region\" , form use-template \"StdCdRegion\" } ,\n" \
5830 "{ asn1 \"SeqFeatData.prot\" , label \"Protein\" , form use-template \"StdProtRef\" } ,\n" \
5831 "{ asn1 \"SeqFeatData.rna\" , label \"RNA\" , form use-template \"StdRNARef\" } ,\n" \
5832 "{ asn1 \"SeqFeatData.pub\" , label \"Citation\" , form use-template \"StdPubdesc\" } ,\n" \
5833 "{ asn1 \"SeqFeatData.seq\" , label \"Sequence\" , form user { printfunc \"StdSeqLocPrint\" } } ,\n" \
5834 "{ asn1 \"SeqFeatData.imp.key\" , label \"Import\" , form use-template \"StdImpFeat\" } ,\n" \
5835 "{ asn1 \"SeqFeatData.region\" , label \"Region\" , form text { } } ,\n" \
5836 "{ asn1 \"SeqFeatData.comment\" , label \"Comment\" , form null NULL } ,\n" \
5837 "{ asn1 \"SeqFeatData.bond\" , label \"Bond\" , form enum { } } ,\n" \
5838 "{ asn1 \"SeqFeatData.site\" , label \"Site\" , form enum { } } ,\n" \
5839 "{ asn1 \"SeqFeatData.rsite\" , label \"Rest. Site\" , form use-template \"StdRsiteRef\" } ,\n" \
5840 "{ asn1 \"SeqFeatData.user\" , label \"User Type\" , form use-template \"StdUserObj\" } ,\n" \
5841 "{ asn1 \"SeqFeatData.txinit\" , label \"TxInit\" , form use-template \"StdTxInit\" } ,\n" \
5842 "{ asn1 \"SeqFeatData.num\" , label \"Numbering\" , form use-template \"StdNumbering\" } ,\n" \
5843 "{ asn1 \"SeqFeatData.psec-str\" , label \"Sec. Struct\" , form enum { } } ,\n" \
5844 "{ asn1 \"SeqFeatData.non-std-residue\" , label \"NonStd Residue\" , form text { } } ,\n" \
5845 "{ asn1 \"SeqFeatData.het\" , label \"Heterogen\" , form text { } } ,\n" \
5846 "{ asn1 \"SeqFeatData.biosrc\" , label \"Biological Source\" , prefix \"\\n\" , form use-template \"StdBioSource\" } } } } } ,\n" \
5847 "{ name \"StdGeneRef\" ,\n" \
5848 "format { asn1 \"Gene-ref\" , form block {\n" \
5849 "separator \"\\n\" ,\n" \
5850 "components {\n" \
5851 "{ asn1 \"Gene-ref\" , form block {\n" \
5852 "components {\n" \
5853 "{ asn1 \"Gene-ref.locus\" , form text { } } ,\n" \
5854 "{ asn1 \"Gene-ref.allele\" , prefix \" \" , form text { } } } } } ,\n" \
5855 "{ asn1 \"Gene-ref.desc\" , prefix \"[\" , suffix \"]\" , form text { } } ,\n" \
5856 "{ asn1 \"Gene-ref.pseudo\" , form boolean {\n" \
5857 "true \"This is a pseudogene.\" } } ,\n" \
5858 "{ asn1 \"Gene-ref.syn\" , label \"Synonyms\" , prefix \" (\" , suffix \")\" , form block {\n" \
5859 "separator \", \" ,\n" \
5860 "components {\n" \
5861 "{ asn1 \"Gene-ref.syn.E\" , form text { } } } } } ,\n" \
5862 "{ asn1 \"Gene-ref.maploc\" , label \"Map Location\" , prefix \" \" , form text { } } ,\n" \
5863 "{ asn1 \"Gene-ref.db\" , label \"Cross Reference\" , prefix \" \" , form block {\n" \
5864 "separator \", \" ,\n" \
5865 "components {\n" \
5866 "{ asn1 \"Gene-ref.db.E\" , prefix \"(\" , suffix \")\" , form use-template \"StdDbtag\" } } } } } } } } ,\n" \
5867 "{ name \"StdUserObj\" ,\n" \
5868 "format { asn1 \"User-object\" , label \"User-object\" , prefix \"\\n\" , form block {\n" \
5869 "separator \": \" ,\n" \
5870 "components {\n" \
5871 "{ asn1 \"User-object.class\" , form text { } } ,\n" \
5872 "{ asn1 \"User-object.type\" , form use-template \"StdObjectId\" } } } } } ,\n" \
5873 "{ name \"StdPubOnFeat\" ,\n" \
5874 "format { asn1 \"Pub\" , label \"Citation\" , prefix \"\\n\" , form block {\n" \
5875 "separator \"\\n\" ,\n" \
5876 "components {\n" \
5877 "{ asn1 \"Pub\" , form use-template \"StdPub\" } } } } } ,\n" \
5878 "{ name \"StdPub\" ,\n" \
5879 "format { asn1 \"Pub\" , form block {\n" \
5880 "separator \"\\n\" ,\n" \
5881 "components {\n" \
5882 "{ asn1 \"Pub.gen\" , form use-template \"StdCitGen\" } ,\n" \
5883 "{ asn1 \"Pub.sub\" , form use-template \"StdCitSub\" } ,\n" \
5884 "{ asn1 \"Pub.medline\" , form use-template \"StdMedlineEntry\" } ,\n" \
5885 "{ asn1 \"Pub.muid\" , label \"MEDLINE uid: \" , form text { } } ,\n" \
5886 "{ asn1 \"Pub.pmid\" , label \"PubMed id: \" , form text { } } ,\n" \
5887 "{ asn1 \"Pub.article\" , form use-template \"StdCitArt\" } ,\n" \
5888 "{ asn1 \"Pub.journal\" , form use-template \"StdCitJour\" } ,\n" \
5889 "{ asn1 \"Pub.book\" , form use-template \"StdCitBook\" } ,\n" \
5890 "{ asn1 \"Pub.proc\" , form use-template \"StdCitProc\" } ,\n" \
5891 "{ asn1 \"Pub.patent\" , form use-template \"StdCitPat\" } ,\n" \
5892 "{ asn1 \"Pub.pat-id\" , form use-template \"StdIdPat\" } ,\n" \
5893 "{ asn1 \"Pub.man\" , form use-template \"StdCitLet\" } ,\n" \
5894 "{ asn1 \"Pub.equiv\" , form use-template \"StdPubEquiv\" } } } } } ,\n" \
5895 "{ name \"StdCitGen\" ,\n" \
5896 "format { asn1 \"Cit-gen\" , form block {\n" \
5897 "separator \"\\n\" ,\n" \
5898 "components {\n" \
5899 "{ asn1 \"Cit-gen.serial-number\" , prefix \"[\" , suffix \"]\" , form text { } } ,\n" \
5900 "{ asn1 \"Cit-gen.authors\" , form use-template \"StdAuthList\" } ,\n" \
5901 "{ asn1 \"Cit-gen.date\" , prefix \"(\" , suffix \")\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
5902 "{ asn1 \"Cit-gen.title\" , form text { } } ,\n" \
5903 "{ asn1 \"Cit-gen.cit\" , form text { } } ,\n" \
5904 "{ asn1 \"Cit-gen\" , form block {\n" \
5905 "separator \" \" ,\n" \
5906 "components {\n" \
5907 "{ asn1 \"Cit-gen.journal\" , suffix \":\" , form use-template \"StdTitle\" } ,\n" \
5908 "{ asn1 \"Cit-gen.issue\" , suffix \";\" , form text { } } ,\n" \
5909 "{ asn1 \"Cit-gen.pages\" , form text { } } } } } } } } } ,\n" \
5910 "{ name \"StdCitSub\" ,\n" \
5911 "format { asn1 \"Cit-sub\" , prefix \"Data Submission \" , form block {\n" \
5912 "components {\n" \
5913 "{ asn1 \"Cit-sub.medium\" , prefix \"on \" , suffix \" \" , form enum { } } ,\n" \
5914 "{ asn1 \"Cit-sub.imp.date\" , prefix \"(\" , suffix \")\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
5915 "{ asn1 \"Cit-sub.authors\" , prefix \"\\n\" , form use-template \"StdAuthList\" } } } } } ,\n" \
5916 "{ name \"StdMedlineEntry\" ,\n" \
5917 "format { asn1 \"Medline-entry\" , form block {\n" \
5918 "separator \"\\n\" ,\n" \
5919 "components {\n" \
5920 "{ asn1 \"Medline-entry\" , form block {\n" \
5921 "separator \" \" ,\n" \
5922 "components {\n" \
5923 "{ asn1 \"Medline-entry.uid\" , label \"uid\" , prefix \": \" , form text { } } ,\n" \
5924 "{ asn1 \"Medline-entry.em\" , label \"entry month\" , prefix \": \" , form user { printfunc \"StdDatePrint\" } } } } } ,\n" \
5925 "{ asn1 \"Medline-entry.cit\" , form use-template \"StdCitArt\" } ,\n" \
5926 "{ asn1 \"Medline-entry.abstract\" , label \"abstract\" , prefix \": \" , form text { } } ,\n" \
5927 "{ asn1 \"Medline-entry.mesh\" , label \"Mesh Terms\" , prefix \"\\n\" , form block {\n" \
5928 "separator \"\\n\" ,\n" \
5929 "components {\n" \
5930 "{ asn1 \"Medline-entry.mesh.E\" , form block {\n" \
5931 "components {\n" \
5932 "{ asn1 \"Medline-mesh.term\" , form text { } } ,\n" \
5933 "{ asn1 \"Medline-mesh.mp\" , form boolean {\n" \
5934 "true \" (Main Point)\" } } ,\n" \
5935 "{ asn1 \"Medline-mesh.qual\" , form block {\n" \
5936 "separator \"\\n\" ,\n" \
5937 "components {\n" \
5938 "{ asn1 \"Medline-mesh.qual.E\" , form block {\n" \
5939 "components {\n" \
5940 "{ asn1 \"Medline-qual.subh\" , form text { } } ,\n" \
5941 "{ asn1 \"Medline-qual.mp\" , form boolean {\n" \
5942 "true \" (Main Point)\" } } } } } } } } } } } } } } ,\n" \
5943 "{ asn1 \"Medline-entry.substance\" , label \"Substance\" , prefix \"\\n\" , form block {\n" \
5944 "separator \"\\n\" ,\n" \
5945 "components {\n" \
5946 "{ asn1 \"Medline-entry.substance.E\" , form block {\n" \
5947 "components {\n" \
5948 "{ asn1 \"Medline-rn.name\" , form text { } } ,\n" \
5949 "{ asn1 \"Medline-rn.type\" , form enum {\n" \
5950 "values {\n" \
5951 "\"\" ,\n" \
5952 "\" CAS: \" ,\n" \
5953 "\"EC \" } } } ,\n" \
5954 "{ asn1 \"Medline-rn.cit\" , form text { } } } } } } } } ,\n" \
5955 "{ asn1 \"Medline-entry.xref\" , label \"Cross Reference\" , prefix \"\\n\" , form block {\n" \
5956 "separator \"\\n\" ,\n" \
5957 "components {\n" \
5958 "{ asn1 \"Medline-entry.xref.E\" , form block {\n" \
5959 "separator \": \" ,\n" \
5960 "components {\n" \
5961 "{ asn1 \"Medline-si.type\" , form enum { } } ,\n" \
5962 "{ asn1 \"Medline-si.cit\" , form text { } } } } } } } } ,\n" \
5963 "{ asn1 \"Medline-entry.gene\" , label \"Possible Gene Symbols\" , prefix \": \" , form block {\n" \
5964 "separator \", \" ,\n" \
5965 "components {\n" \
5966 "{ asn1 \"Medline-entry.gene.E\" , form text { } } } } } ,\n" \
5967 "{ asn1 \"Medline-entry.idnum\" , label \"Support\" , prefix \": \" , form block {\n" \
5968 "separator \", \" ,\n" \
5969 "components {\n" \
5970 "{ asn1 \"Medline-entry.idnum.E\" , form text { } } } } } } } } } ,\n" \
5971 "{ name \"StdCitArt\" ,\n" \
5972 "format { asn1 \"Cit-art\" , form block {\n" \
5973 "separator \"\\n\" ,\n" \
5974 "components {\n" \
5975 "{ asn1 \"Cit-art.title\" , form use-template \"StdTitle\" } ,\n" \
5976 "{ asn1 \"Cit-art.authors\" , form use-template \"StdAuthList\" } ,\n" \
5977 "{ asn1 \"Cit-art.from.journal\" , form use-template \"StdCitJour\" } ,\n" \
5978 "{ asn1 \"Cit-art.from.book\" , prefix \"(in) \" , form use-template \"StdCitBook\" } ,\n" \
5979 "{ asn1 \"Cit-art.from.proc\" , prefix \"(in) \" , form use-template \"StdCitProc\" } } } } } ,\n" \
5980 "{ name \"StdCitJour\" ,\n" \
5981 "format { asn1 \"Cit-jour\" , form block {\n" \
5982 "separator \" \" ,\n" \
5983 "components {\n" \
5984 "{ asn1 \"Cit-jour.title\" , form use-template \"StdTitle\" } ,\n" \
5985 "{ asn1 \"Cit-jour.imp\" , form use-template \"StdImprint\" } } } } } ,\n" \
5986 "{ name \"StdCitBook\" ,\n" \
5987 "format { asn1 \"Cit-book\" , form block {\n" \
5988 "separator \"\\n\" ,\n" \
5989 "components {\n" \
5990 "{ asn1 \"Cit-book.title\" , form use-template \"StdTitle\" } ,\n" \
5991 "{ asn1 \"Cit-book.coll\" , prefix \"Collection: \" , form use-template \"StdTitle\" } ,\n" \
5992 "{ asn1 \"Cit-book.authors\" , form use-template \"StdAuthList\" } ,\n" \
5993 "{ asn1 \"Cit-book.imp\" , form use-template \"StdImprint\" } } } } } ,\n" \
5994 "{ name \"StdCitProc\" ,\n" \
5995 "format { asn1 \"Cit-proc\" , form block {\n" \
5996 "separator \"\\n\" ,\n" \
5997 "components {\n" \
5998 "{ asn1 \"Cit-proc.book\" , form use-template \"StdCitBook\" } ,\n" \
5999 "{ asn1 \"Cit-proc.meet\" , label \"Meeting \" , form block {\n" \
6000 "separator \", \" ,\n" \
6001 "components {\n" \
6002 "{ asn1 \"Meeting.number\" , form text { } } ,\n" \
6003 "{ asn1 \"Meeting.date\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
6004 "{ asn1 \"Meeting.place\" , form use-template \"StdAffil\" } } } } } } } } ,\n" \
6005 "{ name \"StdCitPat\" ,\n" \
6006 "format { asn1 \"Cit-pat\" , form block {\n" \
6007 "separator \"\\n\" ,\n" \
6008 "components {\n" \
6009 "{ asn1 \"Cit-pat.title\" , form text { } } ,\n" \
6010 "{ asn1 \"Cit-pat.authors\" , form use-template \"StdAuthList\" } ,\n" \
6011 "{ asn1 \"Cit-pat\" , form block {\n" \
6012 "components {\n" \
6013 "{ asn1 \"Cit-pat.country\" , suffix \" \" , form text { } } ,\n" \
6014 "{ asn1 \"Cit-pat.doc-type\" , form text { } } ,\n" \
6015 "{ asn1 \"Cit-pat.number\" , form text { } } ,\n" \
6016 "{ asn1 \"Cit-pat.date-issue\" , prefix \" (\" , suffix \")\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
6017 "{ asn1 \"Cit-pat.app-number\" , prefix \" Appl: \" , form text { } } ,\n" \
6018 "{ asn1 \"Cit-pat.app-date\" , prefix \" (\" , suffix \")\" , form user { printfunc \"StdDatePrint\" } } } } } } } } } ,\n" \
6019 "{ name \"StdIdPat\" ,\n" \
6020 "format { asn1 \"Id-pat\" , form block {\n" \
6021 "components {\n" \
6022 "{ asn1 \"Id-pat.country\" , suffix \" \" , form text { } } ,\n" \
6023 "{ asn1 \"Id-pat.id.number\" , form text { } } ,\n" \
6024 "{ asn1 \"Id-pat.id.app-number\" , prefix \"Appl: \" , form text { } } } } } } ,\n" \
6025 "{ name \"StdCitLet\" ,\n" \
6026 "format { asn1 \"Cit-let\" , form block {\n" \
6027 "separator \"\\n\" ,\n" \
6028 "components {\n" \
6029 "{ asn1 \"Cit-let.type\" , prefix \"[\" , suffix \"]\" , form enum { } } ,\n" \
6030 "{ asn1 \"Cit-let.man-id\" , form text { } } ,\n" \
6031 "{ asn1 \"Cit-let.cit\" , form use-template \"StdCitBook\" } } } } } ,\n" \
6032 "{ name \"StdPubEquiv\" ,\n" \
6033 "format { asn1 \"Pub-equiv\" , form block {\n" \
6034 "separator \"\\n\" ,\n" \
6035 "components {\n" \
6036 "{ asn1 \"Pub-equiv.E\" , form use-template \"StdPub\" } } } } } ,\n" \
6037 "{ name \"StdTitle\" ,\n" \
6038 "format { asn1 \"Title\" , form block {\n" \
6039 "separator \", \" ,\n" \
6040 "components {\n" \
6041 "{ asn1 \"Title.E.trans\" , prefix \"[\" , suffix \"]\" , form text { } } ,\n" \
6042 "{ asn1 \"Title.E.name\" , form text { } } ,\n" \
6043 "{ asn1 \"Title.E.tsub\" , form text { } } ,\n" \
6044 "{ asn1 \"Title.E.abr\" , form text { } } ,\n" \
6045 "{ asn1 \"Title.E.iso-jta\" , form text { } } ,\n" \
6046 "{ asn1 \"Title.E.ml-jta\" , label \"MEDLINE\" , prefix \": \" , form text { } } ,\n" \
6047 "{ asn1 \"Title.E.jta\" , label \"jta\" , prefix \": \" , form text { } } ,\n" \
6048 "{ asn1 \"Title.E.issn\" , label \"ISSN\" , prefix \": \" , form text { } } ,\n" \
6049 "{ asn1 \"Title.E.coden\" , label \"CODEN\" , prefix \": \" , form text { } } ,\n" \
6050 "{ asn1 \"Title.E.isbn\" , label \"ISBN\" , prefix \": \" , form text { } } } } } } ,\n" \
6051 "{ name \"StdAuthList\" ,\n" \
6052 "format { asn1 \"Auth-list\" , form block {\n" \
6053 "separator \"\\n\" ,\n" \
6054 "components {\n" \
6055 "{ asn1 \"Auth-list\" , form user { printfunc \"StdAuthListNamesPrint\" } } ,\n" \
6056 "{ asn1 \"Auth-list.affil\" , form use-template \"StdAffil\" } } } } } ,\n" \
6057 "{ name \"StdAffil\" ,\n" \
6058 "format { asn1 \"Affil\" , form block {\n" \
6059 "separator \"\\n\" ,\n" \
6060 "components {\n" \
6061 "{ asn1 \"Affil.str\" , form text { } } ,\n" \
6062 "{ asn1 \"Affil.std.affil\" , form text { } } ,\n" \
6063 "{ asn1 \"Affil.std.div\" , form text { } } ,\n" \
6064 "{ asn1 \"Affil.std.street\" , form text { } } ,\n" \
6065 "{ asn1 \"Affil.std\" , form block {\n" \
6066 "separator \" \" ,\n" \
6067 "components {\n" \
6068 "{ asn1 \"Affil.std.city\" , form text { } } ,\n" \
6069 "{ asn1 \"Affil.std.sub\" , form text { } } ,\n" \
6070 "{ asn1 \"Affil.std.country\" , form text { } } } } } } } } } ,\n" \
6071 "{ name \"StdImprint\" ,\n" \
6072 "format { asn1 \"Imprint\" , form block {\n" \
6073 "components {\n" \
6074 "{ asn1 \"Imprint.date\" , prefix \"(\" , suffix \") \" , form user { printfunc \"StdDatePrint\" } } ,\n" \
6075 "{ asn1 \"Imprint.volume\" , form text { } } ,\n" \
6076 "{ asn1 \"Imprint.issue\" , prefix \" (\" , suffix \")\" , form text { } } ,\n" \
6077 "{ asn1 \"Imprint.section\" , prefix \" (\" , suffix \")\" , form text { } } ,\n" \
6078 "{ asn1 \"Imprint.part-sup\" , prefix \" (\" , suffix \")\" , form text { } } ,\n" \
6079 "{ asn1 \"Imprint.pages\" , prefix \": \" , form text { } } ,\n" \
6080 "{ asn1 \"Imprint.prepub\" , prefix \" (\" , suffix \")\" , form enum { } } ,\n" \
6081 "{ asn1 \"Imprint.pub\" , label \"\nPublisher: \" , form use-template \"StdAffil\" } ,\n" \
6082 "{ asn1 \"Imprint.cprt\" , label \" Copyright: \" , form user { printfunc \"StdDatePrint\" } } } } } } ,\n" \
6083 "{ name \"StdSeqFeatXref\" ,\n" \
6084 "format { asn1 \"SeqFeatXref\" , form block {\n" \
6085 "separator \"\\n\" ,\n" \
6086 "components {\n" \
6087 "{ asn1 \"SeqFeatXref.id\" , label \"Id=\" , form use-template \"StdFeatId\" } ,\n" \
6088 "{ asn1 \"SeqFeatXref.data\" , form use-template \"StdSeqFeatData\" } } } } } ,\n" \
6089 "{ name \"StdOrgRef\" ,\n" \
6090 "format { asn1 \"Org-ref\" , label \"Org-ref\" , prefix \"\\n\" , form block {\n" \
6091 "separator \"\\n\" ,\n" \
6092 "components {\n" \
6093 "{ asn1 \"Org-ref\" , form block {\n" \
6094 "separator \" \" ,\n" \
6095 "components {\n" \
6096 "{ asn1 \"Org-ref.taxname\" , form text { } } ,\n" \
6097 "{ asn1 \"Org-ref.common\" , prefix \"(\" , suffix \")\" , form text { } } } } } ,\n" \
6098 "{ asn1 \"Org-ref.mod\" , label \"Modifiers\" , prefix \" (\" , suffix \")\" , form block {\n" \
6099 "separator \", \" ,\n" \
6100 "components {\n" \
6101 "{ asn1 \"Org-ref.mod.E\" , form text { } } } } } ,\n" \
6102 "{ asn1 \"Org-ref.db\" , label \"Cross Reference\" , prefix \" \" , form block {\n" \
6103 "separator \", \" ,\n" \
6104 "components {\n" \
6105 "{ asn1 \"Org-ref.db.E\" , prefix \"(\" , suffix \")\" , form use-template \"StdDbtag\" } } } } ,\n" \
6106 "{ asn1 \"Org-ref.syn\" , label \"Synonyms\" , prefix \" (\" , suffix \")\" , form block {\n" \
6107 "separator \", \" ,\n" \
6108 "components {\n" \
6109 "{ asn1 \"Org-ref.syn.E\" , form text { } } } } } } } } } ,\n" \
6110 "{ name \"StdBioSource\" ,\n" \
6111 "format { asn1 \"BioSource\" , label \"BioSource\" , form block {\n" \
6112 "separator \"\\n\" ,\n" \
6113 "components {\n" \
6114 "{ asn1 \"BioSource.genome\" , form enum { } } ,\n" \
6115 "{ asn1 \"BioSource.org\" , label \"Organism\" , form use-template \"StdOrgRef\" } } } } } ,\n" \
6116 "{ name \"StdCdRegion\" ,\n" \
6117 "format { asn1 \"Cdregion\" , label \"Cdregion\" , form block {\n" \
6118 "separator \"\\n\" ,\n" \
6119 "components {\n" \
6120 "{ asn1 \"Cdregion.orf\" , form boolean {\n" \
6121 "true \"Uncharacterized Open Reading Frame\" } } ,\n" \
6122 "{ asn1 \"Cdregion.frame\" , label \"Reading Frame = \" , form enum { } } ,\n" \
6123 "{ asn1 \"Cdregion.code\" , label \"Genetic Code: \" , suffix \";\" , form block {\n" \
6124 "separator \", \" ,\n" \
6125 "components {\n" \
6126 "{ asn1 \"Genetic-code.E.name\" , form text { } } ,\n" \
6127 "{ asn1 \"Genetic-code.E.id\" , label \"id= \" , form text { } } } } } ,\n" \
6128 "{ asn1 \"Cdregion.conflict\" , form boolean {\n" \
6129 "true \"Translation conflicts with protein sequence\" } } ,\n" \
6130 "{ asn1 \"Cdregion.stops\" , prefix \"Translation contains \" , suffix \" stop codons\" , form text { } } ,\n" \
6131 "{ asn1 \"Cdregion.gaps\" , prefix \"Translation contains \" , suffix \" gaps when aligned to protein\" , form text { } } ,\n" \
6132 "{ asn1 \"Cdregion.mismatch\" , prefix \"Translation contains \" , suffix \" mismatches when aligned to protein\" , form text { } } } } } } ,\n" \
6133 "{ name \"StdProtRef\" ,\n" \
6134 "format { asn1 \"Prot-ref\" , label \"Prot-ref\" , form block {\n" \
6135 "separator \"\\n\" ,\n" \
6136 "components {\n" \
6137 "{ asn1 \"Prot-ref.name\" , form block {\n" \
6138 "separator \", \" ,\n" \
6139 "components {\n" \
6140 "{ asn1 \"Prot-ref.name.E\" , form text { } } } } } ,\n" \
6141 "{ asn1 \"Prot-ref.desc\" , prefix \"[\" , suffix \"]\" , form text { } } ,\n" \
6142 "{ asn1 \"Prot-ref.processed\" , form enum { } } ,\n" \
6143 "{ asn1 \"Prot-ref.ec\" , label \"ec\" , prefix \": \" , form block {\n" \
6144 "separator \", \" ,\n" \
6145 "components {\n" \
6146 "{ asn1 \"Prot-ref.ec.E\" , form text { } } } } } ,\n" \
6147 "{ asn1 \"Prot-ref.activity\" , label \"activity\" , prefix \": \" , form block {\n" \
6148 "separator \", \" ,\n" \
6149 "components {\n" \
6150 "{ asn1 \"Prot-ref.activity.E\" , form text { } } } } } ,\n" \
6151 "{ asn1 \"Prot-ref.db\" , label \"Cross Reference\" , prefix \" \" , form block {\n" \
6152 "separator \", \" ,\n" \
6153 "components {\n" \
6154 "{ asn1 \"Prot-ref.db.E\" , prefix \"(\" , suffix \")\" , form use-template \"StdDbtag\" } } } } } } } } ,\n" \
6155 "{ name \"StdRNARef\" ,\n" \
6156 "format { asn1 \"RNA-ref\" , label \"RNA-ref\" , form block {\n" \
6157 "separator \"\\n\" ,\n" \
6158 "components {\n" \
6159 "{ asn1 \"RNA-ref.type\" , form enum { } } ,\n" \
6160 "{ asn1 \"RNA-ref.pseudo\" , form boolean {\n" \
6161 "true \"This is an RNA pseudogene.\" } } ,\n" \
6162 "{ asn1 \"RNA-ref.ext.name\" , form text { } } } } } } ,\n" \
6163 "{ name \"StdPubdesc\" ,\n" \
6164 "format { asn1 \"Pubdesc\" , label \"Pubdesc\" , form block {\n" \
6165 "separator \"\\n\" ,\n" \
6166 "components {\n" \
6167 "{ asn1 \"Pubdesc.pub\" , form use-template \"StdPubEquiv\" } ,\n" \
6168 "{ asn1 \"Pubdesc\" , prefix \"In this article:\n\" , form block {\n" \
6169 "separator \"\\n\" ,\n" \
6170 "components {\n" \
6171 "{ asn1 \"Pubdesc.name\" , label \"name=\" , form text { } } ,\n" \
6172 "{ asn1 \"Pubdesc.fig\" , label \"figure=\" , form text { } } ,\n" \
6173 "{ asn1 \"Pubdesc.poly-a\" , form boolean {\n" \
6174 "true \"poly(A) shown\" } } ,\n" \
6175 "{ asn1 \"Pubdesc.maploc\" , label \"map location=\" , form text { } } ,\n" \
6176 "{ asn1 \"Pubdesc.num\" , form use-template \"StdNumbering\" } ,\n" \
6177 "{ asn1 \"Pubdesc.numexc\" , form boolean {\n" \
6178 "true \"numbering inconsistent\" } } } } } ,\n" \
6179 "{ asn1 \"Pubdesc.comment\" , form text { } } } } } } ,\n" \
6180 "{ name \"StdImpFeat\" ,\n" \
6181 "format { asn1 \"Imp-feat.key\" , label \"Imp-feat\" , form text { } } } ,\n" \
6182 "{ name \"StdRsiteRef\" ,\n" \
6183 "format { asn1 \"Rsite-ref\" , label \"Rsite-ref\" , form block {\n" \
6184 "components {\n" \
6185 "{ asn1 \"Rsite-ref.str\" , form text { } } ,\n" \
6186 "{ asn1 \"Rsite-ref.std\" , form use-template \"StdDbtag\" } } } } } ,\n" \
6187 "{ name \"StdTxInit\" ,\n" \
6188 "format { asn1 \"Txinit\" , label \"TxInit\" , form block {\n" \
6189 "components {\n" \
6190 "{ asn1 \"Txinit.name\" , form text { } } } } } } ,\n" \
6191 "{ name \"StdNumbering\" ,\n" \
6192 "format { asn1 \"Numbering\" , label \"Numbering\" , form null NULL } } ,\n" \
6193 "{ name \"StdGBBlock\" ,\n" \
6194 "format { asn1 \"GB-block\" , label \"GenBank-block\" , form block {\n" \
6195 "separator \"\\n\" ,\n" \
6196 "components {\n" \
6197 "{ asn1 \"GB-block.extra-accessions\" , label \"Extra accessions\" , prefix \" (\" , suffix \")\" , form block {\n" \
6198 "separator \", \" ,\n" \
6199 "components {\n" \
6200 "{ asn1 \"GB-block.extra-accessions.E\" , form text { } } } } } ,\n" \
6201 "{ asn1 \"GB-block.keywords\" , label \"Keywords\" , prefix \" (\" , suffix \")\" , form block {\n" \
6202 "separator \", \" ,\n" \
6203 "components {\n" \
6204 "{ asn1 \"GB-block.keywords.E\" , form text { } } } } } ,\n" \
6205 "{ asn1 \"GB-block.source\" , label \"Source: \" , form text { } } ,\n" \
6206 "{ asn1 \"GB-block.origin\" , label \"Origin: \" , form text { } } ,\n" \
6207 "{ asn1 \"GB-block.div\" , label \"Division: \" , form text { } } ,\n" \
6208 "{ asn1 \"GB-block.taxonomy\" , label \"Taxonomy: \" , form text { } } ,\n" \
6209 "{ asn1 \"GB-block.date\" , label \"Date: \" , form text { } } ,\n" \
6210 "{ asn1 \"GB-block.entry-date\" , label \"Entry date: \" , form user { printfunc \"StdDatePrint\" } } } } } } ,\n" \
6211 "{ name \"StdFeatId\" ,\n" \
6212 "format { asn1 \"Feat-id\" , form block {\n" \
6213 "components {\n" \
6214 "{ asn1 \"Feat-id.gibb\" , label \"GenInfo Backbone: \" , form text { } } ,\n" \
6215 "{ asn1 \"Feat-id.giim.id\" , label \"GenInfo Import Id: \" , form text { } } ,\n" \
6216 "{ asn1 \"Feat-id.local\" , label \"Local: \" , form use-template \"StdObjectId\" } ,\n" \
6217 "{ asn1 \"Feat-id.general\" , form use-template \"StdDbtag\" } } } } } ,\n" \
6218 "{ name \"StdSeqFeatCommon\" ,\n" \
6219 "format { asn1 \"Seq-feat\" , form block {\n" \
6220 "separator \"\\n\" ,\n" \
6221 "components {\n" \
6222 "{ asn1 \"Seq-feat.id\" , label \"Id=\" , form use-template \"StdFeatId\" } ,\n" \
6223 "{ asn1 \"Seq-feat.title\" , form text { } } ,\n" \
6224 "{ asn1 \"Seq-feat\" , suffix \";\" , form block {\n" \
6225 "separator \", \" ,\n" \
6226 "components {\n" \
6227 "{ asn1 \"Seq-feat.partial\" , form boolean {\n" \
6228 "true \"Partial\" } } ,\n" \
6229 "{ asn1 \"Seq-feat.except\" , form boolean {\n" \
6230 "true \"Biological Exception\" } } ,\n" \
6231 "{ asn1 \"Seq-feat.exp-ev\" , label \"Evidence\" , prefix \" is \" , form enum { } } } } } ,\n" \
6232 "{ asn1 \"Seq-feat.comment\" , form text { } } ,\n" \
6233 "{ asn1 \"Seq-feat.ext\" , form use-template \"StdUserObj\" } ,\n" \
6234 "{ asn1 \"Seq-feat.qual\" , label \"Qualifiers\" , prefix \"\\n\" , form block {\n" \
6235 "separator \"\\n\" ,\n" \
6236 "components {\n" \
6237 "{ asn1 \"Seq-feat.qual.E\" , prefix \"/\" , form block {\n" \
6238 "separator \"= \" ,\n" \
6239 "components {\n" \
6240 "{ asn1 \"Gb-qual.qual\" , form text { } } ,\n" \
6241 "{ asn1 \"Gb-qual.val\" , form text { } } } } } } } } } } } } ,\n" \
6242 "{ name \"StdDbtag\" ,\n" \
6243 "format { asn1 \"Dbtag\" , form block {\n" \
6244 "components {\n" \
6245 "{ asn1 \"Dbtag.db\" , suffix \": \" , form text { } } ,\n" \
6246 "{ asn1 \"Dbtag.tag\" , form use-template \"StdObjectId\" } } } } } ,\n" \
6247 "{ name \"StdObjectId\" ,\n" \
6248 "format { asn1 \"Object-id\" , form block {\n" \
6249 "components {\n" \
6250 "{ asn1 \"Object-id.id\" , form text { } } ,\n" \
6251 "{ asn1 \"Object-id.str\" , form text { } } } } } } };\n";
6252 #else
6253 CharPtr objPrtMemStr = "";
6254 #endif
6255
6256 typedef Boolean (*MatchBioseqToTableData) PROTO ((BioseqPtr, ValNodePtr, Int4));
6257 typedef Boolean (*BioseqAlreadyHasTableData) PROTO ((BioseqPtr, ValNodePtr, Int4));
6258
6259 static CharPtr GetMatchString (ValNodePtr columns, Int4 match_pos)
6260 {
6261 ValNodePtr vnp;
6262
6263 vnp = columns;
6264 while (match_pos > 0 && vnp != NULL) {
6265 vnp = vnp->next;
6266 match_pos--;
6267 }
6268 if (vnp == NULL) {
6269 return NULL;
6270 } else {
6271 return vnp->data.ptrvalue;
6272 }
6273 }
6274
6275 static Boolean MatchBioseqToTableDataByID (BioseqPtr bsp, ValNodePtr columns, Int4 match_pos)
6276 {
6277 Char seqid[100];
6278 Int4 seqid_len;
6279 SeqIdPtr sip;
6280 CharPtr match_string;
6281 Boolean rval = FALSE;
6282
6283 if (bsp == NULL || columns == NULL || match_pos < 0) return rval;
6284
6285 match_string = GetMatchString (columns, match_pos);
6286 if (match_string == NULL) return rval;
6287
6288 sprintf (seqid, "gb|");
6289 seqid_len = StringLen (match_string);
6290 if (seqid_len > 96) {
6291 seqid_len = 96;
6292 }
6293 StringNCpy (seqid + 3, match_string, seqid_len);
6294 seqid [seqid_len + 3] = 0;
6295 sip = MakeSeqID (seqid);
6296 if (SeqIdIn (sip, bsp->id)) {
6297 rval = TRUE;
6298 }
6299 return rval;
6300 }
6301
6302 static Boolean MatchBioseqToTableDataByOrgname (BioseqPtr bsp, ValNodePtr columns, Int4 match_pos)
6303 {
6304 CharPtr match_string;
6305 Boolean rval = FALSE;
6306 SeqDescrPtr sdp;
6307 SeqMgrDescContext dcontext;
6308 BioSourcePtr biop;
6309
6310 if (bsp == NULL || columns == NULL || match_pos < 0) return rval;
6311
6312 match_string = GetMatchString (columns, match_pos);
6313 if (match_string == NULL) return rval;
6314
6315 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
6316 while (sdp != NULL && !rval) {
6317 biop = (BioSourcePtr) sdp->data.ptrvalue;
6318 if (biop != NULL && biop->org != NULL && StringCmp (biop->org->taxname, match_string) == 0) {
6319 rval = TRUE;
6320 }
6321 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_source, &dcontext);
6322 }
6323
6324 return rval;
6325 }
6326
6327
6328 typedef struct bioseqtabledataassoc {
6329 BioseqPtr bsp;
6330 TableLinePtr tlp;
6331 } BioseqTableDataAssocData, PNTR BioseqTableDataAssocPtr;
6332
6333 typedef struct buildtabledataassoc {
6334 MatchBioseqToTableData match_func;
6335 Int4 match_pos;
6336 ValNodePtr table_data;
6337 ValNodePtr assoc_list;
6338 } BuildBioseqTableDataAssocData, PNTR BuildBioseqTableDataAssocPtr;
6339
6340 static void BuildTableDataAssociationCallback (BioseqPtr bsp, Pointer userdata)
6341 {
6342 BuildBioseqTableDataAssocPtr bp;
6343 ValNodePtr vnp;
6344 TableLinePtr tlp;
6345 BioseqTableDataAssocPtr bap;
6346
6347 bp = (BuildBioseqTableDataAssocPtr) userdata;
6348 if (bsp == NULL || bp == NULL || bp->match_func == NULL || bp->table_data == NULL) return;
6349 for (vnp = bp->table_data; vnp != NULL; vnp = vnp->next) {
6350 if (vnp->data.ptrvalue == NULL) continue;
6351 tlp = (TableLinePtr) vnp->data.ptrvalue;
6352 if (bp->match_func(bsp, tlp->parts, bp->match_pos)) {
6353 bap = (BioseqTableDataAssocPtr) MemNew (sizeof (BioseqTableDataAssocData));
6354 bap->bsp = bsp;
6355 bap->tlp = tlp;
6356 ValNodeAddPointer (&(bp->assoc_list), 0, bap);
6357 }
6358 }
6359 }
6360
6361 static ValNodePtr BuildTableDataAssociation (SeqEntryPtr sep, ValNodePtr table_data, MatchBioseqToTableData match_func, Int4 match_pos)
6362 {
6363 BuildBioseqTableDataAssocData bad;
6364
6365 if (sep == NULL || table_data == NULL || match_func == NULL) return NULL;
6366 bad.assoc_list = NULL;
6367 bad.match_func = match_func;
6368 bad.match_pos = match_pos;
6369 bad.table_data = table_data;
6370
6371 VisitBioseqsInSep (sep, &bad, BuildTableDataAssociationCallback);
6372 return bad.assoc_list;
6373 }
6374
6375 static ValNodePtr
6376 CheckTableDataAssociation
6377 (ValNodePtr assoc_list,
6378 BaseFormPtr bfp,
6379 ValNodePtr table_data,
6380 Int4 match_pos,
6381 BioseqAlreadyHasTableData already_func,
6382 CharPtr already_fmt,
6383 CharPtr more_than_one_fmt,
6384 BoolPtr data_needed,
6385 Int4 num_columns)
6386 {
6387 ValNodePtr vnp, vnp_match;
6388 BioseqTableDataAssocPtr bap1, bap2;
6389 ValNodePtr duplicated_bioseqs = NULL, already_has_list = NULL, err_list = NULL;
6390 ValNodePtr blanks = NULL;
6391 ClickableItemPtr cip;
6392 TableLinePtr tlp;
6393 Boolean found;
6394 CharPtr no_match_fmt = "No match for %s";
6395 CharPtr match_string;
6396 Int4 pos;
6397
6398 if (assoc_list == NULL) {
6399 Message (MSG_ERROR, "No matches found!");
6400 return NULL;
6401 }
6402 for (vnp = assoc_list; vnp != NULL && vnp->next != NULL; vnp = vnp->next) {
6403 bap1 = (BioseqTableDataAssocPtr) vnp->data.ptrvalue;
6404 for (vnp_match = vnp->next; vnp_match != NULL; vnp_match = vnp_match->next) {
6405 bap2 = (BioseqTableDataAssocPtr) vnp_match->data.ptrvalue;
6406 if (bap1->bsp == bap2->bsp) {
6407 for (vnp_match = duplicated_bioseqs;
6408 vnp_match != NULL && bap1->bsp != vnp_match->data.ptrvalue;
6409 vnp_match = vnp_match->next) {}
6410 if (vnp_match == NULL) {
6411 ValNodeAddPointer (&(duplicated_bioseqs), OBJ_BIOSEQ, bap1->bsp);
6412 }
6413 break;
6414 }
6415 }
6416 }
6417 for (vnp = assoc_list; vnp != NULL; vnp = vnp->next) {
6418 bap1 = (BioseqTableDataAssocPtr) vnp->data.ptrvalue;
6419 if (already_func != NULL && already_func (bap1->bsp, NULL, 0)) {
6420 ValNodeAddPointer (&already_has_list, OBJ_BIOSEQ, bap1->bsp);
6421 }
6422 if (data_needed != NULL) {
6423 for (vnp_match = bap1->tlp->parts, pos = 0;
6424 vnp_match != NULL && pos < num_columns;
6425 vnp_match = vnp_match->next, pos++) {
6426 if (data_needed[pos] && StringHasNoText (vnp_match->data.ptrvalue)) {
6427 break;
6428 }
6429 }
6430 if (pos < num_columns) {
6431 ValNodeAddPointer (&blanks, OBJ_BIOSEQ, bap1->bsp);
6432 }
6433 }
6434 }
6435
6436 if (duplicated_bioseqs != NULL) {
6437 if (more_than_one_fmt == NULL) {
6438 cip = NewClickableItem (TABLE_DATA_MULTIPLE_VALUES, "%d sequences will receive data from more than one line.", duplicated_bioseqs);
6439 } else {
6440 cip = NewClickableItem (TABLE_DATA_MULTIPLE_VALUES, more_than_one_fmt, duplicated_bioseqs);
6441 }
6442 ValNodeAddPointer (&err_list, 0, cip);
6443 }
6444
6445 if (already_has_list != NULL) {
6446 if (already_fmt == NULL) {
6447 cip = NewClickableItem (TABLE_DATA_ALREADY_HAS, "%d sequences already have data", already_has_list);
6448 } else {
6449 cip = NewClickableItem (TABLE_DATA_ALREADY_HAS, already_fmt, already_has_list);
6450 }
6451 ValNodeAddPointer (&err_list, 0, cip);
6452 }
6453
6454 if (blanks != NULL) {
6455 cip = NewClickableItem (TABLE_DATA_CELL_BLANK, "%d sequences have blank values in the table", blanks);
6456 ValNodeAddPointer (&err_list, 0, cip);
6457 }
6458
6459 for (vnp = table_data; vnp != NULL; vnp = vnp->next) {
6460 tlp = vnp->data.ptrvalue;
6461 found = FALSE;
6462 for (vnp_match = assoc_list; vnp_match != NULL && !found; vnp_match = vnp_match->next) {
6463 bap1 = (BioseqTableDataAssocPtr) vnp_match->data.ptrvalue;
6464 if (bap1->tlp == tlp) {
6465 found = TRUE;
6466 }
6467 }
6468 if (!found) {
6469 match_string = GetMatchString (tlp->parts, match_pos);
6470 if (match_string != NULL) {
6471 cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
6472 MemSet (cip, 0, sizeof (ClickableItemData));
6473 cip->clickable_item_type = TABLE_DATA_NOT_FOUND;
6474 cip->description = MemNew ((StringLen (no_match_fmt) + StringLen (match_string)) * sizeof (Char));
6475 sprintf (cip->description, no_match_fmt, match_string);
6476 ValNodeAddPointer (&err_list, 0, cip);
6477 }
6478 }
6479 }
6480
6481 return err_list;
6482 }
6483
6484 static Boolean BioseqHasGenomeProjectID (BioseqPtr bsp, ValNodePtr columns, Int4 match_pos)
6485 {
6486 Boolean rval = FALSE;
6487 SeqDescrPtr sdp;
6488 SeqMgrDescContext context;
6489
6490 if (bsp == NULL) return rval;
6491
6492 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &context);
6493 while (sdp != NULL && !rval) {
6494 rval = IsGenomeProjectIDDescriptor(sdp);
6495 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &context);
6496 }
6497 return rval;
6498 }
6499
6500 static void ApplyGenomeProjectIDByTableDataAssociationList (ValNodePtr assoc_list, Int4 project_id_col, Boolean do_replace, Boolean blanks_erase, Uint2 entityID)
6501 {
6502 BioseqTableDataAssocPtr bap;
6503 ValNodePtr vnp;
6504 Int4 projectID;
6505 SeqDescrPtr sdp;
6506 UserObjectPtr uop;
6507 ObjectIdPtr oip;
6508 UserFieldPtr ufp, ufp_last, ufp_next;
6509 CharPtr match_string;
6510 ObjValNodePtr ovn;
6511
6512 for (vnp = assoc_list; vnp != NULL; vnp = vnp->next) {
6513 bap = (BioseqTableDataAssocPtr) vnp->data.ptrvalue;
6514 sdp = NULL;
6515 if (BioseqHasGenomeProjectID (bap->bsp, NULL, 0)) {
6516 if (!do_replace) {
6517 continue;
6518 } else {
6519 sdp = GetGenomeProjectIDDescriptor(bap->bsp);
6520 }
6521 }
6522 match_string = GetMatchString (bap->tlp->parts, project_id_col);
6523 if (StringHasNoText (match_string)) {
6524 if (blanks_erase) {
6525 if (sdp != NULL && sdp->extended != 0) {
6526 ovn = (ObjValNodePtr) sdp;
6527 ovn->idx.deleteme = TRUE;
6528 }
6529 }
6530 } else {
6531 projectID = atoi (match_string);
6532 if (sdp == NULL) {
6533 sdp = SeqDescrNew (bap->bsp->descr);
6534 if (bap->bsp->descr == NULL) bap->bsp->descr = sdp;
6535 sdp->choice = Seq_descr_user;
6536 uop = CreateGenomeProjectsDBUserObject ();
6537 AddIDsToGenomeProjectsDBUserObject (uop, projectID, 0);
6538 sdp->data.ptrvalue = uop;
6539 } else {
6540 uop = sdp->data.ptrvalue;
6541 if (uop == NULL) {
6542 uop = CreateGenomeProjectsDBUserObject ();
6543 sdp->data.ptrvalue = uop;
6544 }
6545 ufp_last = NULL;
6546 ufp = uop->data;
6547 while (ufp != NULL) {
6548 oip = ufp->label;
6549 if (oip != NULL && StringCmp (oip->str, "ProjectID") == 0) {
6550 break;
6551 } else {
6552 ufp_last = ufp;
6553 ufp = ufp->next;
6554 }
6555 }
6556 if (ufp == NULL) {
6557 ufp_next = NULL;
6558 } else {
6559 ufp_next = ufp->next;
6560 }
6561
6562 if (ufp->choice != 2) {
6563 ufp_next = ufp->next;
6564 ufp = UserFieldFree(ufp);
6565 }
6566 if (ufp == NULL) {
6567 ufp = UserFieldNew ();
6568 oip = ObjectIdNew ();
6569 oip->str = StringSave ("ProjectID");
6570 ufp->label = oip;
6571 ufp->choice = 2; /* integer */
6572 if (ufp_last == NULL) {
6573 uop->data = ufp;
6574 } else {
6575 ufp_last->next = ufp;
6576 }
6577 }
6578 ufp->data.intvalue = projectID;
6579 ufp->next = ufp_next;
6580 }
6581 }
6582 }
6583 DeleteMarkedObjects (entityID, 0, NULL);
6584 }
6585
6586 typedef struct genomeprojectid {
6587 FORM_MESSAGE_BLOCK
6588 PopuP id_column;
6589 PopuP match_column;
6590 PopuP gpid_column;
6591
6592 ValNodePtr table_data;
6593 BaseFormPtr bfp;
6594 } GenomeProjectIdData, PNTR GenomeProjectIdPtr;
6595
6596 static void CleanupGenomeProjectIDForm (GraphiC g, VoidPtr data)
6597
6598 {
6599 GenomeProjectIdPtr gpip;
6600
6601 gpip = (GenomeProjectIdPtr) data;
6602 if (gpip != NULL)
6603 {
6604 CleanUpTableData (gpip->table_data);
6605 }
6606 StdCleanupFormProc (g, data);
6607 }
6608
6609 static void ApplyGenomeProjectIDs (ButtoN b)
6610 {
6611 GenomeProjectIdPtr gpip;
6612 ValNodePtr assoc_list = NULL;
6613 SeqEntryPtr sep;
6614 MatchBioseqToTableData match_func = NULL;
6615 Int4 match_pos, project_id_col, col_num;
6616 Boolean ok = FALSE;
6617 Boolean skip_already_has = FALSE, blanks_erase = FALSE;
6618 ValNodePtr err_list = NULL;
6619 SeqEntryPtr oldscope;
6620 TableLinePtr tlp;
6621 BoolPtr data_needed = NULL;
6622
6623 gpip = (GenomeProjectIdPtr) GetObjectExtra (b);
6624 if (gpip == NULL) return;
6625
6626 match_pos = GetValue (gpip->match_column);
6627 if (match_pos < 1) return;
6628 match_pos--;
6629 project_id_col = GetValue (gpip->gpid_column);
6630 if (project_id_col < 1) return;
6631 project_id_col--;
6632 if (GetValue (gpip->id_column) == 1) {
6633 match_func = MatchBioseqToTableDataByID;
6634 } else {
6635 match_func = MatchBioseqToTableDataByOrgname;
6636 }
6637
6638 tlp = gpip->table_data->data.ptrvalue;
6639 if (tlp != NULL) {
6640 data_needed = (BoolPtr) MemNew (sizeof (Boolean) * tlp->num_parts);
6641 for (col_num = 0; col_num < tlp->num_parts; col_num++) {
6642 if (col_num == project_id_col) {
6643 data_needed[col_num] = TRUE;
6644 } else {
6645 data_needed[col_num] = FALSE;
6646 }
6647 }
6648 }
6649
6650 sep = GetTopSeqEntryForEntityID (gpip->input_entityID);
6651 oldscope = SeqEntrySetScope (sep);
6652 assoc_list = BuildTableDataAssociation (sep, gpip->table_data, match_func, match_pos);
6653 err_list = CheckTableDataAssociation (assoc_list, gpip->bfp, gpip->table_data, match_pos,
6654 BioseqHasGenomeProjectID,
6655 "%d sequences already have a Genome Project ID.",
6656 "%d sequences will get more than one Genome Project ID from the table.",
6657 data_needed, tlp->num_parts);
6658
6659
6660
6661 if (err_list == NULL || GetTableOptions (gpip->bfp, err_list, "Errors Matching Sequences from File", "", "",
6662 "Skip sequences that already have Genome Project IDs",
6663 "Erase Genome Project IDs when table cell is blank",
6664 &skip_already_has, &blanks_erase)) {
6665 ApplyGenomeProjectIDByTableDataAssociationList (assoc_list, project_id_col, !skip_already_has, blanks_erase, gpip->input_entityID);
6666 ok = TRUE;
6667 }
6668 assoc_list = ValNodeFree (assoc_list);
6669 if (ok) {
6670 ObjMgrSetDirtyFlag (gpip->input_entityID, TRUE);
6671 ObjMgrSendMsg (OM_MSG_UPDATE, gpip->input_entityID, 0, 0);
6672 ArrowCursor ();
6673 Update ();
6674 Remove (gpip->form);
6675 }
6676 SeqEntrySetScope (oldscope);
6677 }
6678
6679
6680 extern void LoadGenomeProjectIDsFromFile (IteM i)
6681 {
6682 BaseFormPtr bfp;
6683 WindoW w;
6684 GenomeProjectIdPtr gpip;
6685 GrouP h, g, c;
6686 ButtoN b;
6687
6688 #ifdef WIN_MAC
6689 bfp = currentFormDataPtr;
6690 #else
6691 bfp = GetObjectExtra (i);
6692 #endif
6693 if (bfp == NULL) return;
6694
6695 gpip = (GenomeProjectIdPtr) MemNew (sizeof(GenomeProjectIdData));
6696 gpip->table_data = ReadTableData ();
6697 if (gpip->table_data == NULL) {
6698 gpip = MemFree (gpip);
6699 return;
6700 }
6701 gpip->bfp = bfp;
6702
6703 w = FixedWindow (-50, -33, -10, -10, "Add Genome Project IDs", StdCloseWindowProc);
6704 gpip->form = (ForM) w;
6705 SetObjectExtra (w, gpip, CleanupGenomeProjectIDForm);
6706 gpip->input_entityID = bfp->input_entityID;
6707
6708 h = HiddenGroup (w, -1, 0, NULL);
6709
6710 g = HiddenGroup (h, 6, 0, NULL);
6711 SetGroupSpacing (g, 10, 10);
6712 StaticPrompt (g, "Match", 0, dialogTextHeight, systemFont, 'c');
6713 gpip->match_column = PopupList (g, TRUE, NULL);
6714 FormatPopupWithTableDataColumns (gpip->match_column, gpip->table_data);
6715 SetValue (gpip->match_column, 1);
6716
6717 StaticPrompt (g, "To", 0, dialogTextHeight, systemFont, 'c');
6718 gpip->id_column = PopupList (g, TRUE, NULL);
6719 PopupItem (gpip->id_column, "Accession");
6720 PopupItem (gpip->id_column, "Tax Name");
6721 SetValue (gpip->id_column, 1);
6722 StaticPrompt (g, "Use Project ID from", 0, dialogTextHeight, systemFont, 'c');
6723 gpip->gpid_column = PopupList (g, TRUE, NULL);
6724 FormatPopupWithTableDataColumns (gpip->gpid_column, gpip->table_data);
6725 SetValue (gpip->gpid_column, 1);
6726
6727 c = HiddenGroup (h, 4, 0, NULL);
6728 b = DefaultButton (c, "Accept", ApplyGenomeProjectIDs);
6729 SetObjectExtra (b, gpip, NULL);
6730 b = PushButton (c, "Cancel", StdCancelButtonProc);
6731 SetObjectExtra (b, gpip, NULL);
6732 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
6733 RealizeWindow (w);
6734 Show (w);
6735 Update ();
6736 }
6737
6738
6739 static void SuppressGenesOnFeaturesInsideMobileElementsCallback (BioseqPtr bsp, Pointer data)
6740 {
6741 SeqFeatPtr mobile_element, sfp, gene;
6742 SeqMgrFeatContext fcontext_m, fcontext_s, fcontext_g;
6743 GeneRefPtr grp;
6744 SeqFeatXrefPtr xref;
6745
6746 if (bsp == NULL) return;
6747
6748 for (mobile_element = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_IMP, FEATDEF_repeat_region, &fcontext_m);
6749 mobile_element != NULL;
6750 mobile_element = SeqMgrGetNextFeature (bsp, mobile_element, SEQFEAT_IMP, FEATDEF_repeat_region, &fcontext_m)) {
6751 if (!IsMobileElement (mobile_element)) continue;
6752 for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext_s);
6753 sfp != NULL && fcontext_s.left <= fcontext_m.right;
6754 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &fcontext_s)) {
6755 if (SeqLocCompare (sfp->location, mobile_element->location) == SLC_A_IN_B
6756 && SeqMgrGetGeneXref (sfp) == NULL) {
6757 /* suppress gene if gene not contained in mobile_element */
6758 gene = SeqMgrGetOverlappingGene (sfp->location, &fcontext_g);
6759 if (gene != NULL && (fcontext_g.left <= fcontext_m.left || fcontext_g.right >= fcontext_m.right)) {
6760 grp = GeneRefNew ();
6761 if (grp != NULL) {
6762 xref = SeqFeatXrefNew ();
6763 xref->data.choice = SEQFEAT_GENE;
6764 xref->data.value.ptrvalue = grp;
6765 xref->next = sfp->xref;
6766 sfp->xref = xref;
6767 }
6768 }
6769 }
6770 }
6771 }
6772 }
6773
6774
6775 extern void SuppressGenesOnFeaturesInsideMobileElements (IteM i)
6776 {
6777 BaseFormPtr bfp;
6778 SeqEntryPtr sep;
6779
6780 #ifdef WIN_MAC
6781 bfp = currentFormDataPtr;
6782 #else
6783 bfp = GetObjectExtra (i);
6784 #endif
6785 if (bfp == NULL || bfp->input_entityID == 0) return;
6786
6787 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6788
6789 VisitBioseqsInSep (sep, NULL, SuppressGenesOnFeaturesInsideMobileElementsCallback);
6790
6791 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6792 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
6793 Update ();
6794 }
6795
6796
6797 /* Importing Protein ID Table */
6798 static ValNodePtr GetNthValNode (ValNodePtr list, Int4 nth)
6799 {
6800 if (nth < 0)
6801 {
6802 return NULL;
6803 }
6804
6805 while (nth > 0 && list != NULL)
6806 {
6807 list = list->next;
6808 nth --;
6809 }
6810 return list;
6811 }
6812
6813
6814 typedef struct featurefieldcolumnchoice {
6815 Int4 match_type;
6816 ValNodePtr field_choice;
6817 Boolean change_mrna;
6818 Boolean erase_when_blank;
6819 ExistingTextPtr etp;
6820 } FeatureFieldColumnChoiceData, PNTR FeatureFieldColumnChoicePtr;
6821
6822 static FeatureFieldColumnChoicePtr FeatureFieldColumnChoiceFree (FeatureFieldColumnChoicePtr f)
6823 {
6824 if (f != NULL) {
6825 f->field_choice = ValNodeFree (f->field_choice);
6826 f->etp = MemFree (f->etp);
6827 f = MemFree (f);
6828 }
6829 return f;
6830 }
6831
6832
6833 static ValNodePtr GetFeaturesForGene (SeqFeatPtr gene, Uint1 featdef)
6834 {
6835 BioseqPtr bsp;
6836 SeqFeatPtr sfp;
6837 ValNodePtr feat_list = NULL;
6838 SeqMgrFeatContext fcontext;
6839 Int4 start, stop, swap;
6840
6841 if (gene == NULL) return NULL;
6842
6843 bsp = BioseqFindFromSeqLoc (gene->location);
6844 start = SeqLocStart (gene->location);
6845 stop = SeqLocStop (gene->location);
6846 if (stop < start)
6847 {
6848 swap = start;
6849 start = stop;
6850 stop = swap;
6851 }
6852 for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, featdef, &fcontext);
6853 sfp != NULL && fcontext.left < stop;
6854 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, featdef, &fcontext))
6855 {
6856 if (fcontext.right >= start && gene == GetGeneForFeature (sfp))
6857 {
6858 ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
6859 }
6860 }
6861 return feat_list;
6862 }
6863
6864 static ValNodePtr GetFeatureListForProteinBioseq (Uint1 featdef, BioseqPtr bsp)
6865 {
6866 ValNodePtr feat_list = NULL;
6867 SeqFeatPtr sfp, cds;
6868 SeqMgrFeatContext fcontext;
6869
6870 if (bsp == NULL || !ISA_aa (bsp->mol))
6871 {
6872 return NULL;
6873 }
6874
6875 if (featdef == FEATDEF_PROT || featdef == FEATDEF_mat_peptide_aa)
6876 {
6877 for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, featdef, &fcontext);
6878 sfp != NULL;
6879 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, featdef, &fcontext))
6880 {
6881 ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
6882 }
6883 }
6884 else
6885 {
6886 cds = SeqMgrGetCDSgivenProduct (bsp, NULL);
6887 if (cds != NULL)
6888 {
6889 sfp = NULL;
6890 if (featdef == FEATDEF_CDS)
6891 {
6892 sfp = cds;
6893 }
6894 else if (featdef == FEATDEF_GENE)
6895 {
6896 sfp = GetGeneForFeature (cds);
6897 }
6898 else if (featdef == FEATDEF_mRNA)
6899 {
6900 sfp = SeqMgrGetOverlappingmRNA (cds->location, &fcontext);
6901 }
6902 if (sfp != NULL)
6903 {
6904 ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
6905 }
6906 }
6907 }
6908 return feat_list;
6909 }
6910
6911
6912 static ValNodePtr GetFeatureListForGene (Uint1 featdef, SeqFeatPtr gene)
6913 {
6914 ValNodePtr feat_list = NULL, cds_list, vnp;
6915 SeqFeatPtr sfp, cds;
6916 SeqMgrFeatContext fcontext;
6917 BioseqPtr protbsp;
6918
6919 if (gene == NULL)
6920 {
6921 return NULL;
6922 }
6923
6924 if (featdef == FEATDEF_GENE)
6925 {
6926 ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, gene);
6927 }
6928 else if (featdef == FEATDEF_mRNA || featdef == FEATDEF_CDS)
6929 {
6930 feat_list = GetFeaturesForGene (gene, featdef);
6931 }
6932 else if (featdef == FEATDEF_PROT || featdef == FEATDEF_mat_peptide_aa)
6933 {
6934 cds_list = GetFeaturesForGene (gene, FEATDEF_CDS);
6935 for (vnp = cds_list; vnp != NULL; vnp = vnp->next)
6936 {
6937 cds = vnp->data.ptrvalue;
6938 if (cds != NULL)
6939 {
6940 protbsp = BioseqFindFromSeqLoc (cds->product);
6941 for (sfp = SeqMgrGetNextFeature (protbsp, NULL, 0, featdef, &fcontext);
6942 sfp != NULL;
6943 sfp = SeqMgrGetNextFeature (protbsp, sfp, 0, featdef, &fcontext))
6944 {
6945 ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
6946 }
6947 }
6948 }
6949 cds_list = ValNodeFree (cds_list);
6950 }
6951
6952 return feat_list;
6953 }
6954
6955
6956 static SeqFeatPtr GetFeatureForFieldByMatchList (ValNodePtr field, ValNodePtr match_list, ValNodePtr PNTR errors)
6957 {
6958 Uint1 featdef;
6959 ValNodePtr vnp;
6960 ValNodePtr tmp;
6961 CharPtr msg;
6962 CharPtr no_match_fmt = "No feature found for %s";
6963 CharPtr too_many_fmt = "%d features found for %s (only one allowed!)";
6964 CharPtr bad_comb_fmt = "Multiple match columns specify different features (%s, %s)!";
6965 SeqFeatPtr sfp = NULL;
6966
6967 if (field == NULL || match_list == NULL || errors == NULL) return NULL;
6968
6969 featdef = (Uint1)FeatDefTypeFromFieldList (field);
6970 if (featdef == FEATDEF_BAD || featdef == FEATDEF_ANY)
6971 {
6972 return NULL;
6973 }
6974
6975 for (vnp = match_list; vnp != NULL; vnp = vnp->next)
6976 {
6977 tmp = NULL;
6978 if (vnp->choice == OBJ_BIOSEQ)
6979 {
6980 tmp = GetFeatureListForProteinBioseq (featdef, vnp->data.ptrvalue);
6981 }
6982 else
6983 {
6984 tmp = GetFeatureListForGene (featdef, vnp->data.ptrvalue);
6985 }
6986 if (tmp == NULL)
6987 {
6988 msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (no_match_fmt) + StringLen (vnp->data.ptrvalue)));
6989 sprintf (msg, no_match_fmt, vnp->data.ptrvalue);
6990 ValNodeAddPointer (errors, 0, msg);
6991 }
6992 else if (tmp->next != NULL)
6993 {
6994 msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (too_many_fmt) + StringLen (vnp->data.ptrvalue) + 15));
6995 sprintf (msg, too_many_fmt, ValNodeLen (tmp), vnp->data.ptrvalue);
6996 ValNodeAddPointer (errors, 0, msg);
6997 }
6998 else if (sfp != NULL && sfp != tmp->data.ptrvalue)
6999 {
7000 msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (bad_comb_fmt) + StringLen (vnp->data.ptrvalue) + StringLen (match_list->data.ptrvalue)));
7001 sprintf (msg, too_many_fmt, match_list->data.ptrvalue, vnp->data.ptrvalue);
7002 ValNodeAddPointer (errors, 0, msg);
7003 }
7004 else
7005 {
7006 sfp = tmp->data.ptrvalue;
7007 }
7008 tmp = ValNodeFree (tmp);
7009 }
7010 return sfp;
7011 }
7012
7013
7014 static void
7015 GetExistingValueCounts
7016 (TableLinePtr tlp,
7017 FeatureFieldColumnChoicePtr PNTR f_list,
7018 Int4 num_columns,
7019 ValNodePtr match_list,
7020 Int4Ptr existing_text,
7021 BoolPtr has_mrna,
7022 BoolPtr missing_mrna,
7023 ValNodePtr PNTR errors)
7024 {
7025 Int4 i;
7026 ValNodePtr vnp;
7027 SeqFeatPtr sfp, mrna;
7028 CharPtr val;
7029
7030 if (tlp == NULL || f_list == NULL || existing_text == NULL) return;
7031
7032 vnp = tlp->parts;
7033 for (i = 0; i < num_columns; i++)
7034 {
7035 if (f_list[i]->field_choice != NULL)
7036 {
7037 sfp = GetFeatureForFieldByMatchList (f_list[i]->field_choice, match_list, errors);
7038 if (sfp != NULL)
7039 {
7040 val = GetCDSGeneProtField (sfp, f_list[i]->field_choice, NULL);
7041 if (!StringHasNoText (val))
7042 {
7043 existing_text[i]++;
7044 }
7045 val = MemFree (val);
7046 if (IsCDSetProteinProductChoice (f_list[i]->field_choice) && f_list[i]->change_mrna)
7047 {
7048 mrna = GetmRNAForFeature (sfp);
7049 if (mrna == NULL)
7050 {
7051 *missing_mrna = TRUE;
7052 }
7053 else
7054 {
7055 *has_mrna = TRUE;
7056 }
7057 }
7058 }
7059 }
7060 if (vnp != NULL)
7061 {
7062 vnp = vnp->next;
7063 }
7064 }
7065 }
7066
7067
7068 static Int4
7069 ApplyProteinIDTableLine
7070 (TableLinePtr tlp,
7071 FeatureFieldColumnChoicePtr PNTR f_list,
7072 Int4 num_columns,
7073 ValNodePtr match_list)
7074 {
7075 Int4 index;
7076 ValNodePtr vnp;
7077 SeqFeatPtr sfp;
7078 ApplyValueData avd;
7079 ValNodePtr errors = NULL;
7080 Int4 fields_affected = 0;
7081
7082 if (tlp == NULL || f_list == NULL || match_list == NULL) return 0;
7083
7084 index = 0;
7085 vnp = tlp->parts;
7086 while (index < num_columns)
7087 {
7088 if (f_list[index]->field_choice != NULL)
7089 {
7090 sfp = GetFeatureForFieldByMatchList (f_list[index]->field_choice, match_list, &errors);
7091 if (sfp != NULL)
7092 {
7093 if (vnp == NULL || StringHasNoText (vnp->data.ptrvalue))
7094 {
7095 if (f_list[index]->erase_when_blank)
7096 {
7097 RemoveCDSGeneProtField (sfp, f_list[index]->field_choice, NULL);
7098 fields_affected++;
7099 }
7100 }
7101 else
7102 {
7103 avd.etp = f_list[index]->etp;
7104 avd.field_list = f_list[index]->field_choice;
7105 avd.new_text = vnp->data.ptrvalue;
7106 avd.text_to_replace = NULL;
7107 avd.where_to_replace = EditApplyFindLocation_anywhere;
7108 SetCDSGeneProtField (sfp, f_list[index]->field_choice, &avd, NULL);
7109 fields_affected ++;
7110 }
7111 /* note - need special case to change mRNA product if CDS product changes */
7112 if (IsCDSetProteinProductChoice (f_list[index]->field_choice) && f_list[index]->change_mrna)
7113 {
7114 if (AdjustmRNAProductToMatchProteinProduct (sfp))
7115 {
7116 fields_affected++;
7117 }
7118 }
7119 }
7120 }
7121 index++;
7122 if (vnp != NULL)
7123 {
7124 vnp = vnp->next;
7125 }
7126 }
7127 errors = ValNodeFreeData (errors);
7128 return fields_affected;
7129 }
7130
7131
7132 typedef struct featurefieldcolumnchoicedlg {
7133 DIALOG_MESSAGE_BLOCK
7134 GrouP match_or_field;
7135 PopuP match_type;
7136 DialoG field_choice;
7137 ButtoN change_mrna;
7138 /* for existing text options */
7139 GrouP apply_options;
7140 ButtoN erase_when_blank;
7141 GrouP existing_text_action_grp;
7142 GrouP existing_text_delim_grp;
7143
7144 Nlm_ChangeNotifyProc change_notify;
7145 Pointer change_userdata;
7146 } FeatureFieldColumnChoiceDlgData, PNTR FeatureFieldColumnChoiceDlgPtr;
7147
7148 static void FeatureFieldColumnChoicePopupChange (PopuP p)
7149 {
7150 FeatureFieldColumnChoiceDlgPtr dlg;
7151
7152 dlg = (FeatureFieldColumnChoiceDlgPtr) GetObjectExtra (p);
7153 if (dlg != NULL && dlg->change_notify != NULL) {
7154 (dlg->change_notify) (dlg->change_userdata);
7155 }
7156 }
7157
7158
7159 static void FeatureFieldColumnChoiceFieldChange (Pointer data)
7160 {
7161 FeatureFieldColumnChoiceDlgPtr dlg;
7162 ValNodePtr vnp;
7163
7164 dlg = (FeatureFieldColumnChoiceDlgPtr) data;
7165 if (dlg != NULL) {
7166 vnp = DialogToPointer (dlg->field_choice);
7167 if (IsCDSetProteinProductChoice (vnp)) {
7168 Enable (dlg->change_mrna);
7169 } else {
7170 Disable (dlg->change_mrna);
7171 }
7172 vnp = ValNodeFree (vnp);
7173 if (dlg->change_notify != NULL) {
7174 (dlg->change_notify) (dlg->change_userdata);
7175 }
7176 }
7177 }
7178
7179
7180 static void FeatureFieldColumnChoiceGroupChange (GrouP p)
7181 {
7182 FeatureFieldColumnChoiceDlgPtr dlg;
7183
7184 dlg = (FeatureFieldColumnChoiceDlgPtr) GetObjectExtra (p);
7185 if (dlg != NULL) {
7186 if (GetValue (dlg->match_or_field) == 1) {
7187 Enable (dlg->match_type);
7188 Disable (dlg->field_choice);
7189 Disable (dlg->apply_options);
7190 Disable (dlg->change_mrna);
7191 } else {
7192 Disable (dlg->match_type);
7193 Enable (dlg->field_choice);
7194 Enable (dlg->apply_options);
7195 FeatureFieldColumnChoiceFieldChange (dlg);
7196 }
7197 if (dlg->change_notify != NULL) {
7198 (dlg->change_notify) (dlg->change_userdata);
7199 }
7200 }
7201 }
7202
7203
7204 static Pointer FeatureFieldColumnDialogToChoice (DialoG d)
7205 {
7206 FeatureFieldColumnChoiceDlgPtr dlg;
7207 FeatureFieldColumnChoicePtr f;
7208 Int4 existing_text_action;
7209 Int4 existing_text_delimiter;
7210
7211 dlg = (FeatureFieldColumnChoiceDlgPtr) GetObjectExtra (d);
7212 if (dlg == NULL) return NULL;
7213
7214 f = (FeatureFieldColumnChoicePtr) MemNew (sizeof (FeatureFieldColumnChoiceData));
7215 f->change_mrna = FALSE;
7216 if (GetValue (dlg->match_or_field) == 1) {
7217 f->match_type = GetValue (dlg->match_type);
7218 f->etp = NULL;
7219 f->erase_when_blank = FALSE;
7220 } else {
7221 f->field_choice = DialogToPointer (dlg->field_choice);
7222 if (dlg->erase_when_blank == NULL) {
7223 f->erase_when_blank = FALSE;
7224 } else {
7225 f->erase_when_blank = GetStatus (dlg->erase_when_blank);
7226 }
7227 if (IsCDSetProteinProductChoice (f->field_choice)) {
7228 f->change_mrna = GetStatus (dlg->change_mrna);
7229 }
7230 f->etp = (ExistingTextPtr) MemNew (sizeof (ExistingTextData));
7231 existing_text_action = GetValue (dlg->existing_text_action_grp);
7232 if (existing_text_action == 1) {
7233 f->etp->existing_text_choice = eExistingTextChoiceReplaceOld;
7234 } else if (existing_text_action == 4) {
7235 f->etp->existing_text_choice = eExistingTextChoiceLeaveOld;
7236 } else {
7237 existing_text_delimiter = GetValue (dlg->existing_text_delim_grp);
7238 if (existing_text_action == 2) {
7239 f->etp->existing_text_choice = eExistingTextChoiceAppendSemi + existing_text_delimiter - 1;
7240 } else if (existing_text_action == 3) {
7241 f->etp->existing_text_choice = eExistingTextChoicePrefixSemi + existing_text_delimiter - 1;
7242 } else {
7243 f->etp->existing_text_choice = eExistingTextChoiceCancel;
7244 }
7245 }
7246 }
7247 return f;
7248
7249 }
7250
7251
7252 static void ChangeExistingTextActionChoice (GrouP g)
7253 {
7254 FeatureFieldColumnChoiceDlgPtr dlg;
7255 Int4 action_choice;
7256
7257 dlg = (FeatureFieldColumnChoiceDlgPtr) GetObjectExtra (g);
7258 if (dlg == NULL) return;
7259
7260 action_choice = GetValue (dlg->existing_text_action_grp);
7261 if (action_choice == 2 || action_choice == 3) {
7262 Enable (dlg->existing_text_delim_grp);
7263 } else {
7264 Disable (dlg->existing_text_delim_grp);
7265 }
7266 }
7267
7268
7269 static DialoG FeatureFieldColumnChoiceDialog
7270 (GrouP h,
7271 CharPtr title,
7272 Int4 num_blank,
7273 Nlm_ChangeNotifyProc change_notify,
7274 Pointer change_userdata)
7275 {
7276 FeatureFieldColumnChoiceDlgPtr dlg;
7277 GrouP p, g1, g;
7278 ButtoN b1, b2;
7279 PrompT ppt;
7280 CharPtr real_title;
7281 CharPtr title_fmt = "(%d are blank)%s";
7282
7283 dlg = (FeatureFieldColumnChoiceDlgPtr) MemNew (sizeof (FeatureFieldColumnChoiceDlgData));
7284
7285 if (num_blank > 0) {
7286 real_title = (CharPtr) MemNew (sizeof (Char) * (StringLen (title_fmt) + StringLen (title) + 15));
7287 sprintf (real_title, title_fmt, num_blank, title);
7288 } else {
7289 real_title = title;
7290 }
7291
7292 p = NormalGroup (h, -1, 0, real_title, programFont, NULL);
7293 SetObjectExtra (p, dlg, StdCleanupExtraProc);
7294
7295 if (real_title != title) {
7296 real_title = MemFree (real_title);
7297 }
7298 dlg->dialog = (DialoG) p;
7299 dlg->fromdialog = FeatureFieldColumnDialogToChoice;
7300 dlg->change_notify = change_notify;
7301 dlg->change_userdata = change_userdata;
7302
7303 g1 = HiddenGroup (p, 2, 0, NULL);
7304 dlg->match_or_field = HiddenGroup (g1, 0, 2, FeatureFieldColumnChoiceGroupChange);
7305 SetObjectExtra (dlg->match_or_field, dlg, NULL);
7306 b1 = RadioButton (dlg->match_or_field, "Match to");
7307 b2 = RadioButton (dlg->match_or_field, "Apply to");
7308 SetValue (dlg->match_or_field, 1);
7309
7310 g = HiddenGroup (g1, 0, 2, NULL);
7311 dlg->match_type = PopupList (g, TRUE, FeatureFieldColumnChoicePopupChange);
7312 SetObjectExtra (dlg->match_type, dlg, NULL);
7313 PopupItem (dlg->match_type, "None");
7314 PopupItem (dlg->match_type, "ID");
7315 PopupItem (dlg->match_type, "Gene locus tag");
7316 SetValue (dlg->match_type, 1);
7317
7318 dlg->field_choice = CDSGeneProtFieldSelectionDialog (g, FALSE, FeatureFieldColumnChoiceFieldChange, dlg);
7319 Disable (dlg->field_choice);
7320 AlignObjects (ALIGN_MIDDLE, (HANDLE) b1, (HANDLE) dlg->match_type, NULL);
7321 AlignObjects (ALIGN_MIDDLE, (HANDLE) b2, (HANDLE) dlg->field_choice, NULL);
7322
7323 dlg->change_mrna = CheckBox (p, "Also change mRNA product name", NULL);
7324 Disable (dlg->change_mrna);
7325
7326 dlg->apply_options = HiddenGroup (p, -1, 0, NULL);
7327 if (num_blank > 0) {
7328 dlg->erase_when_blank = CheckBox (dlg->apply_options, "Erase field when table cell is blank", NULL);
7329 } else {
7330 dlg->erase_when_blank = NULL;
7331 }
7332 dlg->existing_text_action_grp = HiddenGroup (dlg->apply_options, 4, 0, ChangeExistingTextActionChoice);
7333 SetGroupSpacing (dlg->existing_text_action_grp, 10, 10);
7334 SetObjectExtra (dlg->existing_text_action_grp, dlg, NULL);
7335 RadioButton (dlg->existing_text_action_grp, "Overwrite existing text");
7336 RadioButton (dlg->existing_text_action_grp, "Append");
7337 RadioButton (dlg->existing_text_action_grp, "Prefix");
7338 RadioButton (dlg->existing_text_action_grp, "Ignore new text");
7339 SetValue (dlg->existing_text_action_grp, 1);
7340
7341 ppt = StaticPrompt (dlg->apply_options, "Separate new text and old text with",
7342 0, dialogTextHeight, programFont, 'c');
7343
7344 dlg->existing_text_delim_grp = HiddenGroup (dlg->apply_options, 4, 0, NULL);
7345 SetGroupSpacing (dlg->existing_text_delim_grp, 10, 10);
7346 RadioButton (dlg->existing_text_delim_grp, "Semicolon");
7347 RadioButton (dlg->existing_text_delim_grp, "Space");
7348 RadioButton (dlg->existing_text_delim_grp, "Colon");
7349 RadioButton (dlg->existing_text_delim_grp, "Do not separate");
7350 SetValue (dlg->existing_text_delim_grp, 1);
7351 Disable (dlg->existing_text_delim_grp);
7352
7353 Disable (dlg->apply_options);
7354
7355 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->existing_text_action_grp,
7356 (HANDLE) ppt,
7357 (HANDLE) dlg->existing_text_delim_grp,
7358 (HANDLE) dlg->erase_when_blank,
7359 NULL);
7360
7361 AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->change_mrna, (HANDLE) dlg->apply_options, NULL);
7362
7363 return (DialoG) p;
7364 }
7365
7366 typedef struct featurefieldtable {
7367 FEATURE_FORM_BLOCK
7368 ValNodePtr header_line;
7369 Int4 num_columns;
7370 DialoG PNTR columns;
7371 ButtoN accept_button;
7372 } FeatureFieldTableData, PNTR FeatureFieldTablePtr;
7373
7374
7375 static void CleanupFeatureFieldTableForm (GraphiC g, VoidPtr data)
7376 {
7377 FeatureFieldTablePtr form;
7378
7379 form = (FeatureFieldTablePtr) data;
7380 if (form != NULL) {
7381 CleanUpTableData (form->header_line);
7382 form->columns = MemFree (form->columns);
7383 }
7384 StdCleanupFormProc (g, data);
7385 }
7386
7387
7388 typedef struct findgenelocustag {
7389 CharPtr locus_tag;
7390 ValNodePtr gene_list;
7391 } FindGeneLocusTagData, PNTR FindGeneLocusTagPtr;
7392
7393 static void FindGeneByLocusTagBioseqCallback (BioseqPtr bsp, Pointer userdata)
7394 {
7395 FindGeneLocusTagPtr p;
7396 SeqFeatPtr gene;
7397 SeqMgrFeatContext fcontext;
7398
7399 if (bsp == NULL || userdata == NULL || !ISA_na (bsp->mol)) {
7400 return;
7401 }
7402
7403 p = (FindGeneLocusTagPtr) userdata;
7404
7405 gene = SeqMgrGetGeneByLocusTag (bsp, p->locus_tag, &fcontext);
7406 if (gene != NULL) {
7407 ValNodeAddPointer (&p->gene_list, OBJ_SEQFEAT, gene);
7408 }
7409 }
7410
7411
7412 static ValNodePtr
7413 FindMatchListForRow
7414 (FeatureFieldColumnChoicePtr PNTR f_list,
7415 Int4 num_columns,
7416 SeqEntryPtr sep,
7417 TableLinePtr tlp,
7418 ValNodePtr PNTR missing_ids,
7419 ValNodePtr PNTR missing_genes)
7420 {
7421 Int4 index;
7422 ValNodePtr match_list = NULL, vnp_match;
7423 SeqIdPtr sip;
7424 BioseqPtr bsp;
7425 FindGeneLocusTagData fd;
7426
7427 if (f_list == NULL || tlp == NULL || tlp->parts == NULL || sep == NULL) return NULL;
7428 for (index = 0, vnp_match = tlp->parts;
7429 index < num_columns && vnp_match != NULL;
7430 index++, vnp_match = vnp_match->next)
7431 {
7432 if (f_list[index]->match_type == 2)
7433 {
7434 sip = CreateSeqIdFromText (vnp_match->data.ptrvalue, sep);
7435 bsp = BioseqFind (sip);
7436 sip = SeqIdFree (sip);
7437 if (bsp == NULL)
7438 {
7439 if (missing_ids != NULL)
7440 {
7441 ValNodeAddPointer (missing_ids, 0, StringSave (vnp_match->data.ptrvalue));
7442 }
7443 }
7444 else
7445 {
7446 ValNodeAddPointer (&match_list, OBJ_BIOSEQ, bsp);
7447 }
7448 }
7449 else if (f_list[index]->match_type == 3)
7450 {
7451 fd.locus_tag = vnp_match->data.ptrvalue;
7452 fd.gene_list = NULL;
7453 VisitBioseqsInSep (sep, &fd, FindGeneByLocusTagBioseqCallback);
7454 if (fd.gene_list == NULL)
7455 {
7456 if (missing_genes != NULL)
7457 {
7458 ValNodeAddPointer (missing_genes, 0, StringSave (vnp_match->data.ptrvalue));
7459 }
7460 }
7461 else
7462 {
7463 ValNodeLink (&match_list, fd.gene_list);
7464 fd.gene_list = NULL;
7465 }
7466 }
7467 }
7468 return match_list;
7469 }
7470
7471
7472 static void DoLoadFeatureFieldTable (ButtoN b)
7473 {
7474 FeatureFieldTablePtr form;
7475 SeqEntryPtr sep, oldscope;
7476 ValNodePtr vnp;
7477 FeatureFieldColumnChoicePtr PNTR f_list;
7478 Int4 index;
7479 Int4 num_rows;
7480 ValNodePtr PNTR match_lists;
7481 ValNodePtr missing_ids = NULL, missing_genes = NULL;
7482 CharPtr msg;
7483 Int4Ptr existing_text;
7484 Boolean has_mrna = FALSE;
7485 Boolean missing_mrna = FALSE;
7486 ValNodePtr errors = NULL;
7487 LogInfoPtr lip;
7488 Int4 fields_affected = 0;
7489 CharPtr label;
7490
7491 form = (FeatureFieldTablePtr) GetObjectExtra (b);
7492 if (form == NULL) return;
7493
7494 sep = GetTopSeqEntryForEntityID (form->input_entityID);
7495
7496 f_list = (FeatureFieldColumnChoicePtr PNTR) MemNew (form->num_columns * sizeof (FeatureFieldColumnChoicePtr));
7497 for (index = 0; index < form->num_columns; index++) {
7498 f_list[index] = DialogToPointer (form->columns[index]);
7499 }
7500
7501 /* find match items (either protein IDs or genes) for each row */
7502 /* make sure all IDs and gene locus_tags in table are in record */
7503 num_rows = ValNodeLen (form->header_line);
7504 match_lists = (ValNodePtr PNTR) MemNew (num_rows * sizeof (ValNodePtr));
7505 for (index = 0, vnp = form->header_line; index < num_rows && vnp != NULL; index++, vnp = vnp->next) {
7506 match_lists[index] = FindMatchListForRow (f_list, form->num_columns, sep, vnp->data.ptrvalue, &missing_ids, &missing_genes);
7507 }
7508
7509 if (missing_ids != NULL) {
7510 msg = CreateListMessage ("ID",
7511 missing_ids->next == NULL
7512 ? " is not found in this record."
7513 : " not found in this record.",
7514 missing_ids);
7515 ValNodeAddPointer (&errors, 0, msg);
7516 missing_ids = ValNodeFreeData (missing_ids);
7517 }
7518 if (missing_genes != NULL) {
7519 msg = CreateListMessage ("Gene",
7520 missing_genes->next == NULL
7521 ? " is not found in this record."
7522 : " not found in this record.",
7523 missing_genes);
7524 ValNodeAddPointer (&errors, 0, msg);
7525 missing_genes = ValNodeFreeData (missing_genes);
7526 }
7527
7528 existing_text = (Int4Ptr) MemNew (form->num_columns * sizeof (Int4));
7529
7530 for (vnp = form->header_line, index = 0; vnp != NULL; vnp = vnp->next, index++) {
7531 if (vnp->data.ptrvalue == NULL) continue;
7532 GetExistingValueCounts (vnp->data.ptrvalue, f_list, form->num_columns, match_lists[index], existing_text, &has_mrna, &missing_mrna, &errors);
7533 }
7534
7535 lip = OpenLog ("Table Problems");
7536 for (vnp = errors; vnp != NULL; vnp = vnp->next) {
7537 fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
7538 lip->data_in_log = TRUE;
7539 }
7540 errors = ValNodeFreeData (errors);
7541
7542 if (has_mrna && missing_mrna) {
7543 fprintf (lip->fp, "Some coding regions for which product names will be set have overlapping mRNA features, but some do not!\n");
7544 lip->data_in_log = TRUE;
7545 }
7546 for (index = 0; index < form->num_columns; index++) {
7547 if (f_list[index]->field_choice != NULL) {
7548 if (existing_text[index] > 0) {
7549 label = GetCDSGeneProtFieldName (f_list[index]->field_choice);
7550 fprintf (lip->fp, "%d features affected by column %d contain existing text in field %s.\n", existing_text[index], index + 1, label);
7551 label = MemFree (label);
7552 lip->data_in_log = TRUE;
7553 }
7554 }
7555 }
7556 CloseLog (lip);
7557 if (lip->data_in_log) {
7558 if (ANS_CANCEL == Message (MSG_OKC, "Continue with errors?")) {
7559 existing_text = MemFree (existing_text);
7560 /* free match lists */
7561 for (index = 0; index < num_rows; index++) {
7562 match_lists[index] = ValNodeFree (match_lists[index]);
7563 }
7564 /* free choices */
7565 for (index = 0; index < form->num_columns; index++) {
7566 f_list[index] = FeatureFieldColumnChoiceFree (f_list[index]);
7567 }
7568 return;
7569 }
7570 }
7571
7572 oldscope = SeqEntrySetScope (sep);
7573
7574 for (vnp = form->header_line, index = 0; vnp != NULL; vnp = vnp->next, index++) {
7575 if (vnp->data.ptrvalue == NULL) continue;
7576 fields_affected += ApplyProteinIDTableLine (vnp->data.ptrvalue, f_list, form->num_columns, match_lists[index]);
7577 }
7578
7579 SeqEntrySetScope (oldscope);
7580
7581 /* free match lists */
7582 for (index = 0; index < num_rows; index++) {
7583 match_lists[index] = ValNodeFree (match_lists[index]);
7584 }
7585 /* free choices */
7586 for (index = 0; index < form->num_columns; index++) {
7587 f_list[index] = FeatureFieldColumnChoiceFree (f_list[index]);
7588 }
7589
7590 ObjMgrSetDirtyFlag (form->input_entityID, TRUE);
7591 ObjMgrSendMsg (OM_MSG_UPDATE, form->input_entityID, 0, 0);
7592 Remove (form->form);
7593 Message (MSG_OK, "%d fields were affected", fields_affected);
7594 }
7595
7596 static void SetFeatureFieldTableAccept (Pointer data)
7597 {
7598 FeatureFieldTablePtr form;
7599 Int4 index;
7600 FeatureFieldColumnChoicePtr f;
7601 Boolean have_match = FALSE, have_apply = FALSE;
7602
7603 form = (FeatureFieldTablePtr) data;
7604 if (form == NULL) return;
7605
7606 for (index = 0; index < form->num_columns && (!have_match || !have_apply); index++)
7607 {
7608 f = DialogToPointer (form->columns[index]);
7609 if (f != NULL)
7610 {
7611 if (f->match_type > 1)
7612 {
7613 have_match = TRUE;
7614 }
7615 else if (f->field_choice != NULL)
7616 {
7617 have_apply = TRUE;
7618 }
7619 f = FeatureFieldColumnChoiceFree (f);
7620 }
7621 }
7622 if (have_match && have_apply)
7623 {
7624 Enable (form->accept_button);
7625 }
7626 else
7627 {
7628 Disable (form->accept_button);
7629 }
7630 }
7631
7632
7633 extern void LoadFeatureFieldTable (IteM i)
7634 {
7635 BaseFormPtr bfp;
7636 SeqEntryPtr sep;
7637 ValNodePtr header_line;
7638 Int4 index;
7639 FeatureFieldTablePtr form;
7640 WindoW w;
7641 GrouP h, g, c;
7642 TableLinePtr tlp;
7643 ValNodePtr vnp;
7644 Int4Ptr blank_list = NULL;
7645
7646 #ifdef WIN_MAC
7647 bfp = currentFormDataPtr;
7648 #else
7649 bfp = GetObjectExtra (i);
7650 #endif
7651 if (bfp == NULL || bfp->input_entityID == 0) return;
7652
7653 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
7654
7655
7656 header_line = ReadTableData ();
7657 if (header_line == NULL || header_line->data.ptrvalue == NULL) {
7658 CleanUpTableData (header_line);
7659 return;
7660 }
7661
7662 /* use form to pick columns for IDs, values */
7663
7664 form = (FeatureFieldTablePtr) MemNew (sizeof (FeatureFieldTableData));
7665 if (form == NULL) return;
7666 form->input_entityID = bfp->input_entityID;
7667 form->header_line = header_line;
7668 tlp = (TableLinePtr) header_line->data.ptrvalue;
7669 form->num_columns = ValNodeLen (tlp->parts);
7670 form->columns = (DialoG PNTR) MemNew (form->num_columns * sizeof (DialoG));
7671
7672 /* now create a dialog to display values */
7673 w = FixedWindow (-50, -33, -10, -10, "Feature Field Table", StdCloseWindowProc);
7674 SetObjectExtra (w, form, CleanupFeatureFieldTableForm);
7675 form->form = (ForM) w;
7676
7677 h = HiddenGroup (w, -1, 0, NULL);
7678 SetGroupSpacing (h, 10, 10);
7679 g = HiddenGroup (h, 3, 0, NULL);
7680
7681 /* pre-analyze table for blanks, so we can display the information in the column dialogs */
7682 blank_list = GetColumnBlankCounts (header_line, form->num_columns);
7683
7684 for (vnp = tlp->parts, index = 0; vnp != NULL; vnp = vnp->next, index++)
7685 {
7686 form->columns[index] = FeatureFieldColumnChoiceDialog (g, vnp->data.ptrvalue,
7687 blank_list == NULL ? 0 : blank_list[index],
7688 SetFeatureFieldTableAccept, form);
7689 }
7690 blank_list = MemFree (blank_list);
7691
7692 c = HiddenGroup (h, 4, 0, NULL);
7693 form->accept_button = DefaultButton (c, "Accept", DoLoadFeatureFieldTable);
7694 SetObjectExtra (form->accept_button, form, NULL);
7695 Disable (form->accept_button);
7696 PushButton (c, "Cancel", StdCancelButtonProc);
7697
7698 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
7699 RealizeWindow (w);
7700 Show (w);
7701 Update ();
7702 }
7703
7704 static Pointer GetRevSectionSequence (Uint1 data_choice, Pointer data, Pointer metadata)
7705 {
7706 BioseqPtr bsp;
7707 Char id_str[45];
7708
7709 if (data == NULL)
7710 {
7711 return NULL;
7712 }
7713 else
7714 {
7715 bsp = (BioseqPtr) data;
7716 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, 39);
7717 return StringSave (id_str);
7718 }
7719 }
7720
7721
7722 static Pointer GetRevSectionInterval (Uint1 data_choice, Pointer data, Pointer metadata)
7723 {
7724 BioseqPtr bsp;
7725 DeltaSeqPtr dsp;
7726 Uint1 seg_num = 0;
7727 Int4 pos = 0;
7728 SeqLocPtr loc;
7729 SeqLitPtr slip;
7730 Char buf[50];
7731
7732 if ((bsp = (BioseqPtr)data) == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext == NULL)
7733 {
7734 return NULL;
7735 }
7736
7737 for (dsp = (DeltaSeqPtr)(bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
7738 switch (dsp->choice)
7739 {
7740 case 1: /* SeqLocPtr */
7741 if ((loc = (SeqLocPtr)dsp->data.ptrvalue) != NULL) {
7742 if (loc->choice != SEQLOC_NULL) {
7743 seg_num++;
7744 pos += SeqLocLen (loc);
7745 }
7746 }
7747 break;
7748 case 2: /* SeqLitPtr */
7749 slip = (SeqLitPtr)(dsp->data.ptrvalue);
7750 if (slip != NULL) {
7751 if (slip->seq_data != NULL) {
7752 if (seg_num == data_choice) {
7753 sprintf (buf, "%d-%d", pos + 1, pos + 1 + slip->length);
7754 return StringSave (buf);
7755 } else {
7756 seg_num++;
7757 }
7758 pos += slip->length;
7759 }
7760 }
7761 break;
7762 }
7763 }
7764 return NULL;
7765 }
7766
7767
7768 /*
7769 static BulkEdFieldData revsection_fields[] = {
7770 { "Sequence", NULL, NULL, GetRevSectionSequence, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
7771 { "Interval", NULL, NULL, GetRevSectionInterval, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
7772 { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
7773 */
7774
7775
7776 typedef struct deltaseqint {
7777 BioseqPtr bsp;
7778 Int4 start;
7779 Int4 stop;
7780 SeqLitPtr slip;
7781 } DeltaSeqIntData, PNTR DeltaSeqIntPtr;
7782
7783
7784 static DeltaSeqIntPtr DeltaSeqIntNew (BioseqPtr bsp, Int4 start, Int4 stop, SeqLitPtr slip)
7785 {
7786 DeltaSeqIntPtr dsip;
7787
7788 dsip = (DeltaSeqIntPtr) MemNew (sizeof (DeltaSeqIntData));
7789 dsip->bsp = bsp;
7790 dsip->start = start;
7791 dsip->stop = stop;
7792 dsip->slip = slip;
7793 return dsip;
7794 }
7795
7796
7797 static void ListDeltaSeqIntervalsCallback (BioseqPtr bsp, Pointer userdata)
7798 {
7799 ValNodePtr PNTR interval_list;
7800 DeltaSeqPtr dsp;
7801 Uint1 seg_num = 0;
7802 Int4 pos = 0;
7803 SeqLocPtr loc;
7804 SeqLitPtr slip;
7805 Char id_str[45];
7806 ClickableItemPtr cip;
7807
7808 if (bsp == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext == NULL || (interval_list = (ValNodePtr PNTR)userdata) == NULL) {
7809 return;
7810 }
7811
7812 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, sizeof (id_str) - 1);
7813
7814 for (dsp = (DeltaSeqPtr)(bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
7815 switch (dsp->choice)
7816 {
7817 case 1: /* SeqLocPtr */
7818 if ((loc = (SeqLocPtr)dsp->data.ptrvalue) != NULL) {
7819 if (loc->choice != SEQLOC_NULL) {
7820 seg_num++;
7821 pos += SeqLocLen (loc);
7822 }
7823 }
7824 break;
7825 case 2: /* SeqLitPtr */
7826 slip = (SeqLitPtr)(dsp->data.ptrvalue);
7827 if (slip != NULL) {
7828 if (slip->seq_data != NULL) {
7829 cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
7830 cip->description = (CharPtr) MemNew (sizeof (Char) * (StringLen (id_str) + 65));
7831 sprintf (cip->description, "%s:%d-%d", id_str, pos + 1, pos + slip->length);
7832 cip->clickable_item_type = seg_num;
7833 ValNodeAddPointer (&cip->item_list, 0, DeltaSeqIntNew (bsp, pos, pos + slip->length - 1, slip));
7834 ValNodeAddPointer (interval_list, 0, cip);
7835 seg_num++;
7836 }
7837 pos += slip->length;
7838 }
7839 break;
7840 }
7841 }
7842 }
7843
7844
7845 static Int4 GetHighestInterval (ValNodePtr int_list)
7846 {
7847 Int4 max = 0;
7848 ClickableItemPtr cip;
7849
7850 while (int_list != NULL) {
7851 cip = (ClickableItemPtr) int_list->data.ptrvalue;
7852 if (cip != NULL && cip->clickable_item_type > max) {
7853 max = cip->clickable_item_type;
7854 }
7855 int_list = int_list->next;
7856 }
7857 return max;
7858 }
7859
7860
7861 typedef struct revseqintform {
7862 FORM_MESSAGE_BLOCK
7863 DialoG clickable_list;
7864 PopuP interval_choice;
7865 ButtoN also_reverse_feats;
7866 ValNodePtr delta_list;
7867 } RevSeqIntFormData, PNTR RevSeqIntFormPtr;
7868
7869 static void CleanupRevSeqIntForm (GraphiC g, VoidPtr data)
7870 {
7871 RevSeqIntFormPtr f;
7872 ValNodePtr vnp;
7873 ClickableItemPtr cip;
7874
7875 f = (RevSeqIntFormPtr) data;
7876 if (f != NULL) {
7877 for (vnp = f->delta_list; vnp != NULL; vnp = vnp->next) {
7878 /* note - the rest of the ClickableItem will be freed by the clickableItemlist */
7879 cip = (ClickableItemPtr) vnp->data.ptrvalue;
7880 if (cip != NULL && cip->item_list != NULL) {
7881 cip->item_list->data.ptrvalue = MemFree (cip->item_list->data.ptrvalue);
7882 }
7883 }
7884 }
7885 StdCleanupFormProc (g, data);
7886 }
7887
7888
7889 static void CheckIntervals (ButtoN b)
7890 {
7891 RevSeqIntFormPtr f;
7892 ValNodePtr vnp;
7893 ClickableItemPtr cip;
7894 Int4 val;
7895
7896 f = (RevSeqIntFormPtr) GetObjectExtra (b);
7897 if (f == NULL) return;
7898
7899 val = GetValue (f->interval_choice);
7900 for (vnp = f->delta_list; vnp != NULL; vnp = vnp->next) {
7901 cip = (ClickableItemPtr) vnp->data.ptrvalue;
7902 if (cip != NULL && cip->clickable_item_type == val - 1) {
7903 cip->chosen = TRUE;
7904 }
7905 }
7906 PointerToDialog (f->clickable_list, f->delta_list);
7907 }
7908
7909
7910 static Int4 RevCompCoordInInterval (Int4 coord, Int4 start, Int4 stop)
7911 {
7912 Int4 offset;
7913
7914 if (coord < start || coord > stop) return coord;
7915
7916 offset = coord - start;
7917 coord = stop - offset;
7918 return coord;
7919 }
7920
7921
7922 static void RevCompIntFuzz (IntFuzzPtr ifp, Int4 start, Int4 stop)
7923 {
7924 Int4 tmp;
7925
7926 if (ifp == NULL) return;
7927
7928 switch (ifp->choice)
7929 {
7930 case 1: /* plus/minus - no changes */
7931 case 3: /* percent - no changes */
7932 break;
7933 case 2: /* range */
7934 tmp = RevCompCoordInInterval (ifp->a, start, stop);
7935 ifp->a = RevCompCoordInInterval (ifp->b, start, stop);
7936 ifp->b = tmp;
7937 break;
7938 case 4: /* lim */
7939 switch (ifp->a)
7940 {
7941 case 1: /* greater than */
7942 ifp->a = 2;
7943 break;
7944 case 2: /* less than */
7945 ifp->a = 1;
7946 break;
7947 case 3: /* to right of residue */
7948 ifp->a = 4;
7949 break;
7950 case 4: /* to left of residue */
7951 ifp->a = 3;
7952 break;
7953 default:
7954 break;
7955 }
7956 break;
7957 }
7958 }
7959
7960 static Uint1 RevStrand (Uint1 strand)
7961 {
7962 if (strand == Seq_strand_minus) {
7963 strand = Seq_strand_plus;
7964 } else {
7965 strand = Seq_strand_minus;
7966 }
7967 return strand;
7968 }
7969
7970
7971 static void RevCompSeqPntForFlippedInterval (SeqPntPtr spp, BioseqPtr bsp, Int4 start, Int4 stop)
7972 {
7973
7974 if (spp == NULL || bsp == NULL) return;
7975 if (!SeqIdIn (spp->id, bsp->id)) return;
7976 if (spp->point < start || spp->point > stop) return;
7977
7978 /* flip */
7979 spp->point = RevCompCoordInInterval (spp->point, start, stop);
7980 spp->strand = RevStrand (spp->strand);
7981 RevCompIntFuzz (spp->fuzz, start, stop);
7982 }
7983
7984
7985 static void RevCompLocationForFlippedInterval (SeqLocPtr head, BioseqPtr bsp, Int4 start, Int4 stop)
7986 {
7987 SeqLocPtr slp;
7988 SeqIntPtr sip;
7989 SeqPntPtr spp;
7990 PackSeqPntPtr pspp, pspp2;
7991 SeqBondPtr sbp;
7992 SeqIdPtr oldids;
7993 Int4 numpnt, i, tpos, tmp;
7994 Boolean do_rev;
7995 IntFuzzPtr ifp;
7996
7997 if ((head == NULL) || (bsp == NULL)) return;
7998
7999 oldids = bsp->id;
8000 switch (head->choice)
8001 {
8002 case SEQLOC_BOND: /* bond -- 2 seqs */
8003 sbp = (SeqBondPtr)(head->data.ptrvalue);
8004 RevCompSeqPntForFlippedInterval (sbp->a, bsp, start, stop);
8005 RevCompSeqPntForFlippedInterval (sbp->b, bsp, start, stop);
8006 break;
8007 case SEQLOC_FEAT: /* feat -- can't track yet */
8008 case SEQLOC_NULL: /* NULL */
8009 case SEQLOC_EMPTY: /* empty */
8010 break;
8011 case SEQLOC_WHOLE: /* whole */
8012 /* nothing to reverse */
8013 break;
8014 case SEQLOC_EQUIV: /* does it stay equiv? */
8015 case SEQLOC_MIX: /* mix -- more than one seq */
8016 case SEQLOC_PACKED_INT: /* packed int */
8017 for (slp = (SeqLocPtr)(head->data.ptrvalue); slp != NULL; slp = slp->next)
8018 {
8019 RevCompLocationForFlippedInterval (slp, bsp, start, stop);
8020 }
8021 break;
8022 case SEQLOC_INT: /* int */
8023 sip = (SeqIntPtr)(head->data.ptrvalue);
8024 if (SeqIdIn(sip->id, oldids))
8025 {
8026 if (sip->from < start || sip->to > stop) {
8027 /* not contained in interval */
8028 break;
8029 }
8030 tmp = RevCompCoordInInterval (sip->from, start, stop);
8031 sip->from = RevCompCoordInInterval (sip->to, start, stop);
8032 sip->to = tmp;
8033 sip->strand = RevStrand (sip->strand);
8034 RevCompIntFuzz (sip->if_to, start, stop);
8035 RevCompIntFuzz (sip->if_from, start, stop);
8036 ifp = sip->if_to;
8037 sip->if_to = sip->if_from;
8038 sip->if_from = ifp;
8039 }
8040 break;
8041 case SEQLOC_PNT: /* pnt */
8042 spp = (SeqPntPtr)(head->data.ptrvalue);
8043 RevCompSeqPntForFlippedInterval (spp, bsp, start, stop);
8044 break;
8045 case SEQLOC_PACKED_PNT: /* packed pnt */
8046 pspp = (PackSeqPntPtr)(head->data.ptrvalue);
8047 do_rev = FALSE;
8048 if (SeqIdIn(pspp->id, oldids))
8049 {
8050 do_rev = TRUE;
8051 numpnt = PackSeqPntNum(pspp);
8052 /* can only reverse set if all are in interval */
8053 for (i = 0; i < numpnt && do_rev; i++)
8054 {
8055 tpos = PackSeqPntGet(pspp, i);
8056 if (tpos < start || tpos > stop) {
8057 do_rev = FALSE;
8058 }
8059 }
8060 if (do_rev) {
8061 pspp2 = PackSeqPntNew();
8062 pspp2->id = pspp->id;
8063 pspp2->fuzz = pspp->fuzz;
8064 pspp->fuzz = NULL;
8065 RevCompIntFuzz (pspp2->fuzz, start, stop);
8066 for (i = 0; i < numpnt && do_rev; i++)
8067 {
8068 tpos = PackSeqPntGet(pspp, i);
8069 tpos = RevCompCoordInInterval (tpos, start, stop);
8070 PackSeqPntPut (pspp2, tpos);
8071 }
8072 pspp2->strand = RevStrand (pspp->strand);
8073 pspp = PackSeqPntFree (pspp);
8074 head->data.ptrvalue = pspp2;
8075 }
8076 }
8077 break;
8078 default:
8079 break;
8080 }
8081 }
8082
8083
8084 static void RevCompOneFeatForBioseqInterval (SeqFeatPtr sfp, BioseqPtr bsp, Int4 start, Int4 stop)
8085 {
8086 CodeBreakPtr cbp;
8087 CdRegionPtr crp;
8088 RnaRefPtr rrp;
8089 tRNAPtr trp;
8090
8091 if (sfp == NULL || bsp == NULL) return;
8092
8093 RevCompLocationForFlippedInterval (sfp->location, bsp, start, stop);
8094 switch (sfp->data.choice) {
8095 case SEQFEAT_CDREGION :
8096 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
8097 if (crp != NULL) {
8098 for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
8099 RevCompLocationForFlippedInterval (cbp->loc, bsp, start, stop);
8100 }
8101 }
8102 break;
8103 case SEQFEAT_RNA :
8104 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
8105 if (rrp != NULL && rrp->ext.choice == 2) {
8106 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
8107 if (trp != NULL && trp->anticodon != NULL) {
8108 RevCompLocationForFlippedInterval (trp->anticodon, bsp, start, stop);
8109 }
8110 }
8111 break;
8112 default :
8113 break;
8114 }
8115 }
8116
8117
8118 static void FlipSelectedSequenceIntervals (ButtoN b)
8119 {
8120 RevSeqIntFormPtr f;
8121 ValNodePtr vnp;
8122 ClickableItemPtr cip;
8123 Int4 num_disc;
8124 DeltaSeqIntPtr dsip;
8125 Boolean rev_feats;
8126 SeqFeatPtr sfp;
8127 SeqMgrFeatContext fcontext;
8128
8129 f = (RevSeqIntFormPtr) GetObjectExtra (b);
8130 if (f == NULL) return;
8131 num_disc = CountChosenDiscrepancies (f->delta_list, FALSE);
8132 if (num_disc == 0) {
8133 Message (MSG_ERROR, "No intervals selected");
8134 return;
8135 }
8136
8137 rev_feats = GetStatus (f->also_reverse_feats);
8138
8139 for (vnp = f->delta_list; vnp != NULL; vnp = vnp->next) {
8140 cip = (ClickableItemPtr) vnp->data.ptrvalue;
8141 if (cip != NULL && cip->chosen && cip->item_list != NULL) {
8142 dsip = (DeltaSeqIntPtr) cip->item_list->data.ptrvalue;
8143 if (dsip != NULL && dsip->slip != NULL) {
8144 ReverseSeqData (dsip->slip->seq_data_type, dsip->slip->length, dsip->slip->seq_data);
8145 ComplementSeqData (dsip->slip->seq_data_type, dsip->slip->length, dsip->slip->seq_data);
8146 if (rev_feats) {
8147 for (sfp = SeqMgrGetNextFeature (dsip->bsp, NULL, 0, 0, &fcontext);
8148 sfp != NULL && fcontext.left <= dsip->stop;
8149 sfp = SeqMgrGetNextFeature (dsip->bsp, sfp, 0, 0, &fcontext)) {
8150 if (fcontext.left >= dsip->start && fcontext.right <= dsip->stop) {
8151 RevCompOneFeatForBioseqInterval (sfp, dsip->bsp, dsip->start, dsip->stop);
8152 }
8153 }
8154 }
8155 }
8156 }
8157 }
8158 Update ();
8159 ObjMgrSetDirtyFlag (f->input_entityID, TRUE);
8160 ObjMgrSendMsg (OM_MSG_UPDATE, f->input_entityID, 0, 0);
8161 Remove (f->form);
8162 }
8163
8164 NLM_EXTERN void FlipSequenceIntervals (IteM i)
8165 {
8166 BaseFormPtr bfp;
8167 RevSeqIntFormPtr f;
8168 SeqEntryPtr sep;
8169 WindoW w;
8170 GrouP h, g, c;
8171 ButtoN b;
8172 ValNodePtr delta_list = NULL;
8173 Int4 max, n;
8174 Char buf[15];
8175
8176 #ifdef WIN_MAC
8177 bfp = currentFormDataPtr;
8178 #else
8179 bfp = GetObjectExtra (i);
8180 #endif
8181 if (bfp == NULL || bfp->input_entityID == 0) return;
8182
8183 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
8184
8185 VisitBioseqsInSep (sep, &delta_list, ListDeltaSeqIntervalsCallback);
8186
8187 if (delta_list == NULL)
8188 {
8189 Message (MSG_OK, "No sequence intervals");
8190 return;
8191 }
8192
8193
8194 f = (RevSeqIntFormPtr) MemNew (sizeof (RevSeqIntFormData));
8195 if (f == NULL)
8196 {
8197 return;
8198 }
8199 f->delta_list = delta_list;
8200
8201 f->input_entityID = bfp->input_entityID;
8202 w = FixedWindow (-50, -33, -10, -10, "Reverse Sequence Intervals", StdCloseWindowProc);
8203 SetObjectExtra (w, f, CleanupRevSeqIntForm);
8204 f->form = (ForM) w;
8205
8206 h = HiddenGroup (w, -1, 0, NULL);
8207 SetGroupSpacing (h, 10, 10);
8208
8209 f->clickable_list = CreateClickableListDialog (h, "Intervals", "",
8210 NULL, NULL, NULL, NULL);
8211 PointerToDialog (f->clickable_list, f->delta_list);
8212
8213 max = GetHighestInterval (f->delta_list);
8214
8215 g = HiddenGroup (h, 4, 0, NULL);
8216 StaticPrompt (g, "Check Interval ", 0, popupMenuHeight, programFont, 'l');
8217 f->interval_choice = PopupList (g, TRUE, NULL);
8218 for (n = 0; n <= max; n++) {
8219 sprintf (buf, "%d", n + 1);
8220 PopupItem (f->interval_choice, buf);
8221 }
8222 SetValue (f->interval_choice, 1);
8223 StaticPrompt (g, " for every sequence", 0, popupMenuHeight, programFont, 'l');
8224 b = PushButton (g, "Check", CheckIntervals);
8225 SetObjectExtra (b, f, NULL);
8226
8227 f->also_reverse_feats = CheckBox (h, "Also reverse features", NULL);
8228
8229 c = HiddenGroup (h, 4, 0, NULL);
8230 SetGroupSpacing (c, 10, 10);
8231
8232 b = PushButton (c, "Flip Checked Intervals", FlipSelectedSequenceIntervals);
8233 SetObjectExtra (b, f, NULL);
8234
8235 PushButton (c, "Dismiss", StdCancelButtonProc);
8236
8237 AlignObjects (ALIGN_CENTER, (HANDLE) f->clickable_list, (HANDLE) g, (HANDLE) f->also_reverse_feats, (HANDLE) c, NULL);
8238
8239 RealizeWindow (w);
8240
8241 Show (w);
8242 }
8243
8244
8245 #ifdef OS_MSWIN
8246 #include <undefwin.h>
8247 #include <windows.h>
8248
8249 NLM_EXTERN Int4 RunSilent(const char *cmdline) {
8250 int status = -1;
8251
8252 STARTUPINFO StartupInfo;
8253 PROCESS_INFORMATION ProcessInfo;
8254
8255 DWORD dwCreateFlags;
8256
8257 #ifndef COMP_METRO
8258 /* code warrior headers do not have this, so comment out to allow compilation */
8259 _flushall();
8260 #endif
8261
8262 /* Set startup info */
8263 memset(&StartupInfo, 0, sizeof(StartupInfo));
8264 StartupInfo.cb = sizeof(STARTUPINFO);
8265 StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
8266 StartupInfo.wShowWindow = SW_HIDE;
8267 dwCreateFlags = CREATE_NEW_CONSOLE;
8268
8269 /* Run program */
8270 if (CreateProcess(NULL, (LPSTR)cmdline, NULL, NULL, FALSE,
8271 dwCreateFlags, NULL, NULL, &StartupInfo, &ProcessInfo))
8272 {
8273 /* wait running process */
8274 DWORD exitcode = -1;
8275 WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
8276 GetExitCodeProcess(ProcessInfo.hProcess, &exitcode);
8277 status = exitcode;
8278 CloseHandle(ProcessInfo.hProcess);
8279 CloseHandle(ProcessInfo.hThread);
8280 }
8281 else
8282 {
8283 DWORD dw = GetLastError();
8284 /* check for common errors first */
8285 if(dw == ERROR_FILE_NOT_FOUND)
8286 Message(MSG_ERROR, "CreateProcess() failed: file not found.");
8287 else
8288 /* generic error message */
8289 Message(MSG_ERROR, "CreateProcess() failed, error code %d.",
8290 (int)dw);
8291 }
8292
8293 return status;
8294 }
8295 #endif
8296
8297 static void MacroAECRAction (IteM i, Boolean indexer_version, Uint1 action_type, Uint1 qual_type)
8298 {
8299 BaseFormPtr bfp;
8300
8301 #ifdef WIN_MAC
8302 bfp = currentFormDataPtr;
8303 #else
8304 bfp = GetObjectExtra (i);
8305 #endif
8306 if (bfp == NULL)
8307 return;
8308
8309 SingleAECRMacroAction (bfp->input_entityID, indexer_version, action_type, qual_type);
8310 }
8311
8312 extern void MacroApplyGBQual (IteM i)
8313 {
8314 MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_feature_field);
8315 }
8316
8317
8318 extern void MacroApplySourceQual (IteM i)
8319 {
8320 MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_source_qual);
8321 }
8322
8323
8324 extern void MacroApplyCDSGeneProt (IteM i)
8325 {
8326 MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_cds_gene_prot);
8327 }
8328
8329 extern void PublicMacroApplyCDSGeneProt (IteM i)
8330 {
8331 MacroAECRAction (i, FALSE, ActionChoice_apply, FieldType_cds_gene_prot);
8332 }
8333
8334
8335 extern void MacroApplyRNAQual (IteM i)
8336 {
8337 MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_rna_field);
8338 }
8339
8340
8341 extern void MacroRemoveGBQual (IteM i)
8342 {
8343 MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_feature_field);
8344 }
8345
8346
8347 extern void MacroRemoveSourceQual (IteM i)
8348 {
8349 MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_source_qual);
8350 }
8351
8352
8353 extern void MacroRemoveCDSGeneProt (IteM i)
8354 {
8355 MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_cds_gene_prot);
8356 }
8357
8358
8359 extern void MacroRemoveRNAQual (IteM i)
8360 {
8361 MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_rna_field);
8362 }
8363
8364
8365 extern void MacroConvertGBQual (IteM i)
8366 {
8367 MacroAECRAction (i, TRUE, ActionChoice_convert, FieldType_feature_field);
8368 }
8369
8370
8371 extern void MacroConvertSourceQual (IteM i)
8372 {
8373 MacroAECRAction (i, TRUE, ActionChoice_convert, FieldType_source_qual);
8374 }
8375
8376
8377 extern void MacroConvertCDSGeneProt (IteM i)
8378 {
8379 MacroAECRAction (i, TRUE, ActionChoice_convert, FieldType_cds_gene_prot);
8380 }
8381
8382
8383 extern void MacroConvertRNAQual (IteM i)
8384 {
8385 MacroAECRAction (i, TRUE, ActionChoice_convert, FieldType_rna_field);
8386 }
8387
8388
8389 extern void MacroSwapGBQual (IteM i)
8390 {
8391 MacroAECRAction (i, TRUE, ActionChoice_swap, FieldType_feature_field);
8392 }
8393
8394
8395 extern void MacroSwapSourceQual (IteM i)
8396 {
8397 MacroAECRAction (i, TRUE, ActionChoice_swap, FieldType_source_qual);
8398 }
8399
8400
8401 extern void MacroSwapCDSGeneProt (IteM i)
8402 {
8403 MacroAECRAction (i, TRUE, ActionChoice_swap, FieldType_cds_gene_prot);
8404 }
8405
8406
8407 extern void MacroSwapRNAQual (IteM i)
8408 {
8409 MacroAECRAction (i, TRUE, ActionChoice_swap, FieldType_rna_field);
8410 }
8411
8412
8413 extern void MacroEditGBQual (IteM i)
8414 {
8415 MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_feature_field);
8416 }
8417
8418
8419 extern void MacroEditSourceQual (IteM i)
8420 {
8421 MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_source_qual);
8422 }
8423
8424
8425 extern void MacroEditCDSGeneProt (IteM i)
8426 {
8427 MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_cds_gene_prot);
8428 }
8429
8430
8431 extern void PublicMacroEditCDSGeneProt (IteM i)
8432 {
8433 MacroAECRAction (i, FALSE, ActionChoice_edit, FieldType_cds_gene_prot);
8434 }
8435
8436
8437 extern void MacroEditRNAQual (IteM i)
8438 {
8439 MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_rna_field);
8440 }
8441
8442
8443 extern void MacroApplyStructuredComment (IteM i)
8444 {
8445 MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_struc_comment_field);
8446 }
8447
8448 extern void PublicMacroApplyStructuredComment (IteM i)
8449 {
8450 MacroAECRAction (i, FALSE, ActionChoice_apply, FieldType_struc_comment_field);
8451 }
8452
8453 extern void MacroEditStructuredComment (IteM i)
8454 {
8455 MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_struc_comment_field);
8456 }
8457
8458 extern void PublicMacroEditStructuredComment (IteM i)
8459 {
8460 MacroAECRAction (i, FALSE, ActionChoice_edit, FieldType_struc_comment_field);
8461 }
8462
8463 extern void MacroRemoveStructuredComment (IteM i)
8464 {
8465 MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_struc_comment_field);
8466 }
8467
8468
8469
8470 typedef struct convertboisourcedbxreftofeaturedbxref {
8471 FORM_MESSAGE_BLOCK
8472 DialoG feature_type;
8473 } ConvertBioSourceDbxrefToFeatureDbxrefData, PNTR ConvertBioSourceDbxrefToFeatureDbxrefPtr;
8474
8475
8476 static ValNodePtr DbxrefListFree (ValNodePtr vnp)
8477
8478 {
8479 ValNodePtr next;
8480
8481 while (vnp != NULL) {
8482 next = vnp->next;
8483 DbtagFree ((DbtagPtr) vnp->data.ptrvalue);
8484 MemFree (vnp);
8485 vnp = next;
8486 }
8487 return NULL;
8488 }
8489
8490
8491 static ValNodePtr DbxrefListCopy (ValNodePtr vnp)
8492
8493 {
8494 ValNodePtr copy = NULL;
8495
8496 while (vnp != NULL) {
8497 ValNodeAddPointer (©, 0, AsnIoMemCopy (vnp->data.ptrvalue, (AsnReadFunc) DbtagAsnRead, (AsnWriteFunc) DbtagAsnWrite));
8498 vnp = vnp->next;
8499 }
8500 return copy;
8501 }
8502
8503
8504 static ValNodePtr ExtractNonTaxonDbxrefs (ValNodePtr PNTR list)
8505 {
8506 ValNodePtr prev = NULL, extracted = NULL, vnp, vnp_next;
8507 DbtagPtr dbtag;
8508
8509 if (list == NULL || *list == NULL) return NULL;
8510 vnp = *list;
8511 while (vnp != NULL) {
8512 vnp_next = vnp->next;
8513 dbtag = (DbtagPtr) vnp->data.ptrvalue;
8514 if (dbtag != NULL && StringCmp (dbtag->db, "taxon") != 0) {
8515 if (prev == NULL) {
8516 *list = vnp_next;
8517 } else {
8518 prev->next = vnp_next;
8519 }
8520 vnp->next = NULL;
8521 ValNodeLink (&extracted, vnp);
8522 } else {
8523 prev = vnp;
8524 }
8525 vnp = vnp_next;
8526 }
8527 return extracted;
8528 }
8529
8530
8531 static void ConvertBioSourceDbxrefToFeatureDbxrefBioseqCallback (BioseqPtr bsp, Pointer userdata)
8532 {
8533 ValNodePtr vnp;
8534 SeqFeatPtr sfp;
8535 SeqMgrFeatContext fcontext;
8536 SeqDescrPtr sdp;
8537 SeqMgrDescContext dcontext;
8538 BioSourcePtr biop;
8539 ValNodePtr dbxref_list = NULL;
8540 Int4 featdef;
8541 Boolean any_feat = FALSE;
8542
8543 if (bsp == NULL || userdata == NULL) {
8544 return;
8545 }
8546
8547 vnp = (ValNodePtr) userdata;
8548 featdef = GetFeatdefFromFeatureType (vnp->choice);
8549
8550 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
8551 if (sdp == NULL || sdp->data.ptrvalue == NULL) return;
8552 biop = (BioSourcePtr) sdp->data.ptrvalue;
8553 if (biop->org == NULL || biop->org->db == NULL) return;
8554 dbxref_list = ExtractNonTaxonDbxrefs (&(biop->org->db));
8555 if (dbxref_list == NULL) return;
8556
8557 for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, featdef, &fcontext);
8558 sfp != NULL;
8559 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, featdef, &fcontext)) {
8560 ValNodeLink (&(sfp->dbxref), DbxrefListCopy(dbxref_list));
8561 any_feat = TRUE;
8562 }
8563 if (any_feat) {
8564 dbxref_list = DbxrefListFree(dbxref_list);
8565 } else {
8566 ValNodeLink (&(biop->org->db), dbxref_list);
8567 }
8568 }
8569
8570
8571 static void AcceptConvertBioSourceDbxrefToFeatureDbxref (ButtoN b)
8572 {
8573 ConvertBioSourceDbxrefToFeatureDbxrefPtr dlg;
8574 ValNodePtr vnp;
8575 SeqEntryPtr sep;
8576
8577 dlg = (ConvertBioSourceDbxrefToFeatureDbxrefPtr) GetObjectExtra (b);
8578 if (dlg == NULL) return;
8579
8580 vnp = DialogToPointer (dlg->feature_type);
8581 if (vnp == NULL) {
8582 Message (MSG_ERROR, "Please choose feature type");
8583 return;
8584 }
8585
8586 sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
8587
8588 VisitBioseqsInSep (sep, vnp, ConvertBioSourceDbxrefToFeatureDbxrefBioseqCallback);
8589 vnp = ValNodeFree (vnp);
8590
8591 ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
8592 ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
8593 Remove (dlg->form);
8594 }
8595
8596
8597 extern void ConvertBioSourceDbxrefToFeatureDbxref (IteM i)
8598 {
8599 BaseFormPtr bfp;
8600 ConvertBioSourceDbxrefToFeatureDbxrefPtr dlg;
8601 WindoW w;
8602 GrouP h, c;
8603 ButtoN b;
8604 PrompT ppt;
8605
8606 #ifdef WIN_MAC
8607 bfp = currentFormDataPtr;
8608 #else
8609 bfp = GetObjectExtra (i);
8610 #endif
8611 if (bfp == NULL || bfp->input_entityID == 0) return;
8612
8613 dlg = (ConvertBioSourceDbxrefToFeatureDbxrefPtr) MemNew (sizeof (ConvertBioSourceDbxrefToFeatureDbxrefData));
8614
8615 w = FixedWindow (-50, -33, -10, -10, "Convert BioSource Dbxrefs to Feature Dbxrefs", StdCloseWindowProc);
8616 SetObjectExtra (w, dlg, StdCleanupExtraProc);
8617 dlg->form = (ForM) w;
8618 dlg->input_entityID = bfp->input_entityID;
8619
8620 h = HiddenGroup (w, -1, 0, NULL);
8621 SetGroupSpacing (h, 10, 10);
8622
8623 ppt = StaticPrompt (h, "Choose feature type to receive BioSource dbxrefs", 0, dialogTextHeight, programFont, 'l');
8624 dlg->feature_type = FeatureTypeDialog (h, NULL, NULL);
8625 c = HiddenGroup (h, 2, 0, NULL);
8626 b = PushButton (c, "Accept", AcceptConvertBioSourceDbxrefToFeatureDbxref);
8627 SetObjectExtra (b, dlg, NULL);
8628 PushButton (c, "Cancel", StdCancelButtonProc);
8629 AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) dlg->feature_type, (HANDLE) c, NULL);
8630 Show (w);
8631 Select (w);
8632 }
8633
8634
8635 typedef struct structuredcommentsform {
8636 FORM_MESSAGE_BLOCK
8637 PopuP match_column;
8638 DialoG match_type;
8639 TexT database_name;
8640
8641 ValNodePtr table;
8642 } StructuredCommentsFormData, PNTR StructuredCommentsFormPtr;
8643
8644 static void CleanupStructuredCommentsForm (GraphiC g, VoidPtr data)
8645
8646 {
8647 StructuredCommentsFormPtr frm;
8648
8649 frm = (StructuredCommentsFormPtr) data;
8650 if (frm != NULL) {
8651 frm->table = FreeTabTable(frm->table);
8652 }
8653 StdCleanupFormProc (g, data);
8654 }
8655
8656
8657 static UserObjectPtr UserObjectFromRow (ValNodePtr header, ValNodePtr line, Int4 col, CharPtr dbname, ValNodePtr PNTR err_list)
8658 {
8659 ValNodePtr vnp_h, vnp_l;
8660 CharPtr id_str = NULL;
8661 Int4 num;
8662 CharPtr extra_data_fmt = "Too many fields in line for %s";
8663 CharPtr msg;
8664 UserObjectPtr uop;
8665 CharPtr prefix = NULL, suffix = NULL;
8666 CharPtr prefix_fmt = "##%sData-START##";
8667 CharPtr suffix_fmt = "##%sData-END##";
8668
8669 if (header == NULL || line == NULL) {
8670 return NULL;
8671 }
8672
8673 /* find id_str */
8674 vnp_l = line->data.ptrvalue;
8675 if (vnp_l == NULL) {
8676 return NULL;
8677 }
8678 num = 0;
8679 while (vnp_l != NULL && num < col) {
8680 num++;
8681 vnp_l = vnp_l->next;
8682 }
8683 if (vnp_l == NULL || StringHasNoText (vnp_l->data.ptrvalue)) {
8684 return NULL;
8685 } else {
8686 id_str = vnp_l->data.ptrvalue;
8687 }
8688
8689 /* build user object */
8690 vnp_h = header;
8691 vnp_l = line->data.ptrvalue;
8692 num = 0;
8693
8694 if (StringHasNoText (dbname)) {
8695 dbname = "Meta";
8696 }
8697
8698 prefix = (CharPtr) MemNew (sizeof (Char) * (StringLen (prefix_fmt) + StringLen (dbname)));
8699 sprintf (prefix, prefix_fmt, dbname);
8700 suffix = (CharPtr) MemNew (sizeof (Char) * (StringLen (suffix_fmt) + StringLen (dbname)));
8701 sprintf (suffix, suffix_fmt, dbname);
8702
8703 uop = CreateStructuredCommentUserObject (prefix, suffix);
8704
8705 prefix = MemFree (prefix);
8706 suffix = MemFree (suffix);
8707