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.607 $
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 #include <objvalid.h>
66 #include <valapi.h>
67 #include <seqsub.h>
68 #include <tax3api.h>
69 #include <valid.h>
70 #include <vsmutil.h>
71 
72 typedef struct deflineformdata {
73   FEATURE_FORM_BLOCK
74 
75   ModifierItemLocalPtr modList;
76   ButtoN PNTR modifier_btns;
77   DeflineFeatureRequestList feature_requests;
78   ButtoN    feature_btns[NumRemovableItems];
79   GrouP     sourceListGrp;
80   PopuP     customGrp;
81   ButtoN    use_labels;
82   ButtoN    keep_paren;
83   ButtoN    exclude_sp;
84   ButtoN    exclude_cf;
85   ButtoN    exclude_aff;
86   ButtoN    exclude_nr;
87   ButtoN    allow_mod_at_end_of_taxname;
88   ButtoN    include_country_extra;
89   ButtoN    allow_semicolon_in_modifier;
90   GrouP     clone_isolate_HIV_rule_num;
91   PopuP     modLimit;
92   PopuP     organelle_popup;
93   BioseqPtr target_bsp;
94   ButtoN    modify_only_target;
95   ButtoN    suppress_alt_splice_phrase;
96   ButtoN    remove_subfeatures;
97   PopuP     featurePopup;
98   GrouP     featureOptsGrp;
99   GrouP     optional_features_grp;
100   PopuP     misc_feat_parse_rule;
101   GrouP     promoter_type;
102   ButtoN    alternate_splice_flag;
103   ButtoN    use_ncrna_note;
104   ButtoN    suppress_locus_tags;
105   ButtoN    gene_cluster_opp_strand;
106   DialoG    suppressed_feature_list;
107   GrouP     suppressed_feature_grp;
108   Boolean   popset_only;
109 } DefLineFormData, PNTR DefLineFormPtr;
110 
DefLineFormMessageProc(ForM f,Int2 mssg)111 static void DefLineFormMessageProc (ForM f, Int2 mssg)
112 
113 {
114   DefLineFormPtr  dlfp;
115 
116   dlfp = (DefLineFormPtr) GetObjectExtra (f);
117   if (dlfp != NULL) {
118     if (dlfp->appmessage != NULL) {
119       dlfp->appmessage (f, mssg);
120     }
121   }
122 }
123 
CleanupDefLineForm(GraphiC g,VoidPtr data)124 static void CleanupDefLineForm (
125   GraphiC g,
126   VoidPtr data
127 )
128 
129 {
130   DefLineFormPtr  dlfp;
131   Int4            i;
132 
133   dlfp = (DefLineFormPtr) data;
134   if (dlfp != NULL) {
135     if (dlfp->modList != NULL)
136     {
137       for (i=0; i < NumDefLineModifiers (); i++)
138       {
139         ValNodeFree (dlfp->modList[i].values_seen);
140       }
141       MemFree (dlfp->modList);
142     }
143     dlfp->modifier_btns = MemFree (dlfp->modifier_btns);
144   }
145   StdCleanupFormProc (g, data);
146 }
147 
ChangeCustomPopup(PopuP p)148 static void ChangeCustomPopup (PopuP p)
149 
150 {
151   DefLineFormPtr  dlfp;
152 
153   dlfp = (DefLineFormPtr) GetObjectExtra (p);
154   if (dlfp == NULL) return;
155   if (GetValue (p) == 1) {
156     SafeDisable (dlfp->sourceListGrp);
157   } else {
158     SafeEnable (dlfp->sourceListGrp);
159   }
160 }
161 
ChangeFeaturePopup(PopuP p)162 static void ChangeFeaturePopup (PopuP p)
163 {
164   DefLineFormPtr  dlfp;
165 
166   dlfp = (DefLineFormPtr) GetObjectExtra (p);
167   if (dlfp == NULL) return;
168   if (GetValue (p) == 2 || GetValue (p) == 3)
169   {
170     SafeDisable (dlfp->featureOptsGrp);
171     SafeDisable (dlfp->suppressed_feature_grp);
172     SafeDisable (dlfp->optional_features_grp);
173     SafeDisable (dlfp->organelle_popup);
174     SafeDisable (dlfp->alternate_splice_flag);
175   }
176   else
177   {
178     SafeEnable (dlfp->featureOptsGrp);
179     SafeEnable (dlfp->suppressed_feature_grp);
180     SafeEnable (dlfp->optional_features_grp);
181     SafeEnable (dlfp->organelle_popup);
182     SafeEnable (dlfp->alternate_splice_flag);
183   }
184 }
185 
186 
DoAutoDefLine(ButtoN b)187 static void DoAutoDefLine (ButtoN b)
188 {
189   DefLineFormPtr dlfp;
190   SeqEntryPtr sep;
191   ValNodePtr modifier_indices = NULL;
192   Int2 feature_index;
193   OrganismDescriptionModifiers odmp;
194   Int2 product_flag, feature_list_type;
195   Int4 i;
196   Boolean alternate_splice_flag;
197   Boolean gene_cluster_opp_strand;
198   UserObjectPtr uop;
199 
200   dlfp = GetObjectExtra (b);
201   if (b == NULL) return;
202   Hide (dlfp->form);
203   WatchCursor ();
204   Update ();
205 
206   if (!dlfp->popset_only) {
207     InitOrganismDescriptionModifiers (&odmp, NULL);
208     odmp.use_labels = GetStatus (dlfp->use_labels);
209     odmp.keep_paren = GetStatus (dlfp->keep_paren);
210     odmp.exclude_sp = GetStatus (dlfp->exclude_sp);
211     odmp.exclude_cf = GetStatus (dlfp->exclude_cf);
212     odmp.exclude_aff = GetStatus (dlfp->exclude_aff);
213     odmp.exclude_nr = GetStatus (dlfp->exclude_nr);
214     odmp.include_country_extra = GetStatus (dlfp->include_country_extra);
215     odmp.use_modifiers = TRUE;
216     odmp.allow_semicolon_in_modifier = GetStatus (dlfp->allow_semicolon_in_modifier);
217     odmp.allow_mod_at_end_of_taxname = !GetStatus (dlfp->allow_mod_at_end_of_taxname);
218 
219     if (dlfp->clone_isolate_HIV_rule_num == NULL)
220     {
221       odmp.clone_isolate_HIV_rule_num = clone_isolate_HIV_rule_want_both;
222     }
223     else
224     {
225       odmp.clone_isolate_HIV_rule_num = GetValue (dlfp->clone_isolate_HIV_rule_num);
226     }
227 
228     odmp.max_mods = GetValue (dlfp->modLimit);
229     if (odmp.max_mods > 1)
230     {
231       odmp.max_mods = odmp.max_mods - 1;
232     }
233     else
234     {
235       odmp.max_mods = -99;
236     }
237 
238   }
239 
240   if (GetValue (dlfp->customGrp) == 1)
241   {
242     /* take all features */
243     for (feature_index = 0; feature_index < NumDefLineModifiers (); feature_index++)
244     {
245       if (dlfp->modList[feature_index].any_present)
246       {
247         ValNodeAddInt (&modifier_indices, 0, feature_index);
248       }
249     }
250   }
251   else
252   {
253     /* take selected features */
254     for (feature_index = 0; feature_index < NumDefLineModifiers (); feature_index++)
255     {
256       if (GetStatus (dlfp->modifier_btns[feature_index]))
257       {
258         ValNodeAddInt (&modifier_indices, 0, feature_index);
259       }
260     }
261   }
262 
263   feature_list_type = GetValue (dlfp->featurePopup);
264   switch (feature_list_type)
265   {
266     case DEFLINE_USE_FEATURES :
267       dlfp->feature_requests.feature_list_type = DEFLINE_USE_FEATURES;
268       break;
269     case DEFLINE_PARTIAL_SEQUENCE :
270       dlfp->feature_requests.feature_list_type = DEFLINE_PARTIAL_SEQUENCE;
271       break;
272     case DEFLINE_COMPLETE_SEQUENCE :
273       dlfp->feature_requests.feature_list_type = DEFLINE_COMPLETE_SEQUENCE;
274       break;
275     case DEFLINE_COMPLETE_GENOME :
276       dlfp->feature_requests.feature_list_type = DEFLINE_COMPLETE_GENOME;
277       break;
278     case DEFLINE_PARTIAL_GENOME :
279       dlfp->feature_requests.feature_list_type = DEFLINE_PARTIAL_GENOME;
280       break;
281     case DEFLINE_SEQUENCE :
282       dlfp->feature_requests.feature_list_type = DEFLINE_SEQUENCE;
283       break;
284     default:
285       dlfp->feature_requests.feature_list_type = DEFLINE_USE_FEATURES;
286       break;
287   }
288 
289   for (i=0; i< NumRemovableItems; i++)
290   {
291     dlfp->feature_requests.keep_items[i]
292               = GetStatus (dlfp->feature_btns[i]);
293   }
294   if (GetValue (dlfp->promoter_type) == 1)
295   {
296     dlfp->feature_requests.add_fake_promoters = TRUE;
297   }
298   else
299   {
300     dlfp->feature_requests.add_fake_promoters = FALSE;
301   }
302 
303   dlfp->feature_requests.suppress_alt_splice_phrase =
304                  GetStatus (dlfp->suppress_alt_splice_phrase);
305 
306   dlfp->feature_requests.use_ncrna_note =
307                  GetStatus (dlfp->use_ncrna_note);
308 
309   dlfp->feature_requests.remove_subfeatures =
310                  GetStatus (dlfp->remove_subfeatures);
311 
312   dlfp->feature_requests.suppress_locus_tags =
313                  GetStatus (dlfp->suppress_locus_tags);
314 
315   dlfp->feature_requests.misc_feat_parse_rule =
316                  GetValue (dlfp->misc_feat_parse_rule);
317 
318   dlfp->feature_requests.suppressed_feature_list = DialogToPointer (dlfp->suppressed_feature_list);
319 
320   product_flag = GetValue (dlfp->organelle_popup) - 1;
321   alternate_splice_flag = GetStatus (dlfp->alternate_splice_flag);
322   gene_cluster_opp_strand = GetStatus (dlfp->gene_cluster_opp_strand);
323 
324   if (dlfp->target_bsp != NULL && GetStatus (dlfp->modify_only_target))
325   {
326     sep = GetBestTopParentForData (dlfp->input_entityID, dlfp->target_bsp);
327   }
328   else
329   {
330     sep = GetTopSeqEntryForEntityID (dlfp->input_entityID);
331   }
332   if (sep == NULL) return;
333 
334   RemovePopsetTitles (sep);
335   if (dlfp->popset_only) {
336     AddPopsetTitles (sep, &dlfp->feature_requests, product_flag, alternate_splice_flag, gene_cluster_opp_strand);
337   } else {
338     AutoDefForSeqEntry (sep, dlfp->input_entityID, &odmp, dlfp->modList, modifier_indices,
339                         &dlfp->feature_requests, product_flag, alternate_splice_flag, gene_cluster_opp_strand);
340   }
341 
342   dlfp->feature_requests.suppressed_feature_list = ValNodeFree (dlfp->feature_requests.suppressed_feature_list);
343   modifier_indices = ValNodeFree (modifier_indices);
344 
345   ArrowCursor ();
346   Update ();
347   ObjMgrSetDirtyFlag (dlfp->input_entityID, TRUE);
348   ObjMgrSendMsg (OM_MSG_UPDATE, dlfp->input_entityID, 0, 0);
349   Remove (dlfp->form);
350   SeqEntrySetScope (NULL);
351 }
352 
IsTricky(BioSourcePtr biop,Pointer userdata)353 static void IsTricky (
354   BioSourcePtr biop,
355   Pointer userdata
356 )
357 {
358   Boolean PNTR pTricky;
359   static CharPtr long_name = "Human immunodeficiency virus";
360   static CharPtr short_name = "HIV-";
361   OrgModPtr     mod;
362   OrgNamePtr    onp;
363   SubSourcePtr  ssp;
364 
365   pTricky = (Boolean PNTR) userdata;
366   if (pTricky == NULL
367     || *pTricky
368     || biop == NULL
369     || biop->org == NULL
370     || biop->org->taxname == NULL
371     || biop->org->orgname == NULL
372     || biop->subtype == NULL)
373   {
374     return;
375   }
376   if (StringNICmp (biop->org->taxname, long_name, StringLen (long_name)) != 0
377     && StringNICmp (biop->org->taxname, short_name, StringLen (short_name)) != 0)
378   {
379     return;
380   }
381 
382   onp = biop->org->orgname;
383   if (onp == NULL) return;
384   mod = onp->mod;
385   while (mod != NULL
386     && mod->subtype != ORGMOD_isolate)
387   {
388     mod = mod->next;
389   }
390   if (mod == NULL || mod->subname == NULL)
391   {
392     return;
393   }
394 
395   ssp = biop->subtype;
396   while (ssp != NULL && ssp->subtype != SUBSRC_clone)
397   {
398     ssp = ssp->next;
399   }
400   if (ssp == NULL || ssp->name == NULL)
401   {
402     return;
403   }
404   *pTricky = TRUE;
405   return;
406 }
407 
HasTrickyHIVRecords(SeqEntryPtr sep)408 static Boolean HasTrickyHIVRecords (
409   SeqEntryPtr sep
410 )
411 {
412   Boolean     has_tricky;
413 
414   if (sep == NULL) return FALSE;
415 
416   has_tricky = FALSE;
417   VisitBioSourcesInSep (sep, &has_tricky, IsTricky);
418   return has_tricky;
419 }
420 
421 
CreateDefLineFormHIVRule(GrouP h)422 static GrouP CreateDefLineFormHIVRule (
423   GrouP h
424 )
425 {
426   GrouP hiv_rule;
427 
428   hiv_rule = NormalGroup (h, 3, 0, "HIV rule", programFont, NULL);
429   RadioButton (hiv_rule, "Prefer Clone");
430   RadioButton (hiv_rule, "Prefer Isolate");
431   RadioButton (hiv_rule, "Want Both Isolate and Clone");
432   SetValue (hiv_rule, clone_isolate_HIV_rule_want_both);
433   return hiv_rule;
434 }
435 
CreateDefLineFormModLimitPopup(GrouP q,Int2 count)436 static PopuP CreateDefLineFormModLimitPopup (
437   GrouP q,
438   Int2 count
439 )
440 {
441   PopuP limit;
442   Int2  i;
443   Char  str[10];
444 
445   StaticPrompt (q, "Max modifiers per line", 0, popupMenuHeight, programFont, 'l');
446   limit = PopupList (q, TRUE, NULL);
447   PopupItem (limit, "no limit");
448   for (i = 1; i <= count; i++) {
449     sprintf (str, "%d", (int) i);
450     PopupItem (limit, str);
451   }
452 
453   SetValue (limit, 1);
454 
455   return limit;
456 }
457 
CreateDefLineFormModifierListPopuP(GrouP q,DefLineFormPtr dlfp)458 static PopuP CreateDefLineFormModifierListPopuP (
459   GrouP          q,
460   DefLineFormPtr dlfp
461 )
462 {
463   PopuP popup;
464   StaticPrompt (q, "Modifier List", 0, popupMenuHeight, programFont, 'l');
465   popup = PopupList (q, TRUE, ChangeCustomPopup);
466   SetObjectExtra (popup, dlfp, NULL);
467   PopupItem (popup, "All");
468   PopupItem (popup, "Custom");
469   SetValue (popup, 2);
470 
471   return popup;
472 }
473 
SetHIVRuleEnable(Handle a)474 static void SetHIVRuleEnable (Handle a)
475 {
476   DefLineFormPtr dlfp;
477 
478   dlfp = GetObjectExtra (a);
479   if (dlfp == NULL) return;
480   if (dlfp->clone_isolate_HIV_rule_num == NULL) return;
481   if (dlfp->modList == NULL) return;
482   if ((dlfp->modifier_btns [DEFLINE_POS_Clone] != NULL
483        && GetStatus (dlfp->modifier_btns [DEFLINE_POS_Clone]))
484       || (dlfp->modifier_btns [DEFLINE_POS_Isolate] != NULL
485           && GetStatus (dlfp->modifier_btns [DEFLINE_POS_Isolate])))
486   {
487     Disable (dlfp->clone_isolate_HIV_rule_num);
488   }
489   else
490   {
491     Enable (dlfp->clone_isolate_HIV_rule_num);
492   }
493 }
494 
CreateDefLineFormSourceGroup(GrouP h,DefLineFormPtr dlfp,SeqEntryPtr sep)495 static GrouP CreateDefLineFormSourceGroup (
496   GrouP          h,
497   DefLineFormPtr dlfp,
498   SeqEntryPtr    sep
499 )
500 {
501   GrouP p, g, g1, r;
502   Int2    item_index, num_label_columns, num_item_rows;
503   Int2    num_item_columns, count = 0;
504   Char    ch;
505   Boolean has_tricky;
506 
507   p = NormalGroup (h, -1, 0, "SOURCE", programFont, NULL);
508   SetGroupSpacing (p, 10, 10);
509 
510   count = 0;
511   for (item_index=0; item_index < NumDefLineModifiers (); item_index++)
512   {
513     if (dlfp->modList[item_index].any_present)
514     {
515       count++;
516     }
517   }
518 
519   g = HiddenGroup (p, 4, 0, NULL);
520   SetGroupSpacing (g, 20, 10);
521   dlfp->customGrp = CreateDefLineFormModifierListPopuP (g, dlfp);
522   dlfp->modLimit = CreateDefLineFormModLimitPopup (g, count);
523   dlfp->use_labels = CheckBox (p, "Use labels", NULL);
524   SetStatus (dlfp->use_labels, TRUE);
525 
526   num_item_rows = 6;
527   if (count > 18)
528     num_item_rows = 8;
529   if (count > 24)
530     num_item_rows = 10;
531   if (count > 30)
532     num_item_rows = 12;
533 
534   num_item_columns = count / num_item_rows;
535   if (count % num_item_rows != 0) num_item_columns ++;
536 
537   num_label_columns = 3;
538   if (count > 6)
539     num_label_columns --;
540   if (count > 12)
541     num_label_columns --;
542 
543   dlfp->sourceListGrp = NormalGroup (p,
544                                      0,
545                                      4,
546                                      "Available Modifiers",
547                                      programFont, NULL);
548   SetGroupSpacing (dlfp->sourceListGrp, 10, 10);
549 
550   for (item_index=0; item_index < NumDefLineModifiers (); item_index++)
551   {
552     if (dlfp->modList[item_index].any_present)
553     {
554       g1 = HiddenGroup (dlfp->sourceListGrp, num_label_columns, 0, NULL);
555       SetGroupSpacing (g1, 10, 10);
556       dlfp->modifier_btns[item_index] = CheckBox (g1,
557                                              DefLineModifiers[item_index].name,
558                                              (BtnActnProc) SetHIVRuleEnable);
559       SetObjectExtra (dlfp->modifier_btns [item_index], dlfp, NULL);
560       SetStatus (dlfp->modifier_btns [item_index],
561                  dlfp->modList[item_index].required);
562 
563       if (num_label_columns > 1)
564       {
565         StaticPrompt (g1,
566                       dlfp->modList[item_index].status,
567                       0, popupMenuHeight, programFont, 'l');
568         if (num_label_columns > 2)
569         {
570 		  if (StringLen (dlfp->modList[item_index].first_value_seen) > 50)
571 		  {
572 		    ch = dlfp->modList[item_index].first_value_seen [50];
573             dlfp->modList[item_index].first_value_seen [50] = 0;
574 		  }
575 		  else
576 		  {
577 		    ch = 0;
578 		  }
579           StaticPrompt (g1,
580                         dlfp->modList[item_index].first_value_seen,
581                         0, popupMenuHeight, programFont, 'l');
582 	      if (ch != 0)
583 		  {
584 		    dlfp->modList[item_index].first_value_seen [50] = ch;
585 		  }
586         }
587       }
588     }
589     else
590     {
591       dlfp->modifier_btns[item_index] = NULL;
592       dlfp->modList[item_index].required = FALSE;
593     }
594   }
595 
596   Enable (dlfp->sourceListGrp);
597 
598 
599   has_tricky = HasTrickyHIVRecords (sep);
600   if (has_tricky)
601   {
602     dlfp->clone_isolate_HIV_rule_num = CreateDefLineFormHIVRule (p);
603     SetObjectExtra (dlfp->clone_isolate_HIV_rule_num, dlfp, NULL);
604     SetHIVRuleEnable (dlfp->clone_isolate_HIV_rule_num);
605   }
606   else
607   {
608     dlfp->clone_isolate_HIV_rule_num = NULL;
609   }
610   r = NormalGroup (p, 3, 0, "Other Options", programFont, NULL);
611   SetGroupSpacing (r, 10, 10);
612   dlfp->keep_paren = CheckBox (r, "Leave in parenthetical organism info", NULL);
613   SetStatus (dlfp->keep_paren, TRUE);
614   dlfp->include_country_extra = CheckBox (r, "Include text after colon in country", NULL);
615   SetStatus (dlfp->include_country_extra, FALSE);
616   dlfp->allow_semicolon_in_modifier = CheckBox (r, "Include text after semicolon in modifiers", NULL);
617   SetStatus (dlfp->allow_semicolon_in_modifier, FALSE);
618   dlfp->exclude_sp = CheckBox (r, "Do not apply modifier to 'sp.' organisms",
619          NULL);
620   SetStatus (dlfp->exclude_sp, ShouldExcludeSp (sep));
621   dlfp->exclude_cf = CheckBox (r, "Do not apply modifier to 'cf.' organisms",
622          NULL);
623   SetStatus (dlfp->exclude_cf, FALSE);
624 
625   dlfp->exclude_aff = CheckBox (r, "Do not apply modifier to 'aff.' organisms",
626          NULL);
627   SetStatus (dlfp->exclude_aff, FALSE);
628   dlfp->exclude_nr = CheckBox (r, "Do not apply modifier to 'nr.' organisms", NULL);
629   SetStatus (dlfp->exclude_nr, FALSE);
630 
631   dlfp->allow_mod_at_end_of_taxname = CheckBox (r, "Do not apply modifier to organisms with matching tax name value", NULL);
632   SetStatus (dlfp->allow_mod_at_end_of_taxname, TRUE);
633 
634   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) dlfp->use_labels,
635                               (HANDLE) dlfp->sourceListGrp,
636                               (HANDLE) r,
637                               (HANDLE) dlfp->clone_isolate_HIV_rule_num,
638                               NULL);
639   return p;
640 }
641 
CreateDefLineFormOrganellePopup(GrouP h)642 static PopuP CreateDefLineFormOrganellePopup (
643   GrouP h
644 )
645 {
646   PopuP o;
647 
648   o = PopupList (h, FALSE, NULL);
649   PopupItem (o, "No mitochondrial or chloroplast suffix");
650   PopupItem (o, "Nuclear gene(s) for mitochondrial product(s)");
651   PopupItem (o, "Nuclear gene(s) for chloroplast product(s)");
652   PopupItem (o, "Nuclear gene(s) for kinetoplast product(s)");
653   PopupItem (o, "Nuclear gene(s) for plastid product(s)");
654   PopupItem (o, "Nuclear gene(s) for chromoplast product(s)");
655   PopupItem (o, "Nuclear gene(s) for cyanelle product(s)");
656   PopupItem (o, "Nuclear gene(s) for apicoplast product(s)");
657   PopupItem (o, "Nuclear gene(s) for leucoplast product(s)");
658   PopupItem (o, "Nuclear gene(s) for proplastid product(s)");
659   PopupItem (o, "Nuclear genes based on CDS products");
660   PopupItem(o, "Nuclear copy of mitochondrial gene");
661   PopupItem(o, "Nuclear copy of chloroplast gene");
662   PopupItem(o, "Nuclear copy of kinetoplast gene");
663   PopupItem(o, "Nuclear copy of plastid gene");
664   PopupItem(o, "Nuclear copy of chromoplast gene");
665   PopupItem(o, "Nuclear copy of cyanelle gene");
666   PopupItem(o, "Nuclear copy of apicoplast gene");
667   PopupItem(o, "Nuclear copy of leucoplast gene");
668   PopupItem(o, "Nuclear copy of proplastid gene");
669   SetValue(o, DEFAULT_ORGANELLE_CLAUSE + 1);
670   return o;
671 }
672 
CreateDefLineFormFeatureListPopuP(GrouP g,DefLineFormPtr dlfp)673 static GrouP CreateDefLineFormFeatureListPopuP (
674   GrouP          g,
675   DefLineFormPtr dlfp
676 )
677 {
678   GrouP q;
679 
680   q = HiddenGroup (g, 2, 0, NULL);
681   StaticPrompt (q, "Features or Complete", 0, popupMenuHeight, programFont, 'l');
682   dlfp->featurePopup = PopupList (q, TRUE, ChangeFeaturePopup);
683   SetObjectExtra (dlfp->featurePopup, dlfp, NULL);
684   PopupItem (dlfp->featurePopup, "List Features");
685   PopupItem (dlfp->featurePopup, "Complete Sequence");
686   PopupItem (dlfp->featurePopup, "Partial Sequence");
687   PopupItem (dlfp->featurePopup, "Complete Genome");
688   PopupItem (dlfp->featurePopup, "Partial Genome");
689   PopupItem (dlfp->featurePopup, "Sequence");
690   SetValue (dlfp->featurePopup, 1);
691 
692   return q;
693 }
694 
SetMiscFeatRuleEnable(Handle a)695 static void SetMiscFeatRuleEnable (Handle a)
696 {
697   DefLineFormPtr dlfp;
698 
699   if (a == NULL || ( dlfp = (DefLineFormPtr) GetObjectExtra (a)) == NULL)
700   {
701     return;
702   }
703   if (GetStatus (dlfp->feature_btns[RemovableNoncodingProductFeat]))
704   {
705     Enable (dlfp->misc_feat_parse_rule);
706   }
707   else
708   {
709     Disable (dlfp->misc_feat_parse_rule);
710   }
711   if (GetStatus (dlfp->feature_btns[RemovablePromoter]))
712   {
713     Enable (dlfp->promoter_type);
714   }
715   else
716   {
717     Disable (dlfp->promoter_type);
718   }
719 }
720 
CreateDefLineFormFeatureOptionsGroup(GrouP h,DefLineFormPtr dlfp)721 static GrouP CreateDefLineFormFeatureOptionsGroup (
722   GrouP          h,
723   DefLineFormPtr dlfp
724 )
725 {
726   GrouP p, g1, s1, s2, k, k2;
727   Int4  i;
728   SeqEntryPtr sep;
729 
730   p = NormalGroup (h, -1, 0, "FEATURES", programFont, NULL);
731   SetGroupSpacing (p, 10, 10);
732 
733   g1 = HiddenGroup (p, 2, 0, NULL);
734   SetGroupSpacing (g1, 10, 10);
735   s1 = HiddenGroup (g1, -1, 0, NULL);
736   SetGroupSpacing (s1, 10, 10);
737   CreateDefLineFormFeatureListPopuP (s1, dlfp);
738   dlfp->organelle_popup = CreateDefLineFormOrganellePopup (s1);
739   dlfp->alternate_splice_flag = CheckBox (s1,
740 	                "Append 'alternatively spliced'", NULL);
741   dlfp->use_ncrna_note = CheckBox (s1, "Use ncRNA note if no class or product", NULL);
742   AlignObjects (ALIGN_CENTER, (HANDLE) dlfp->featurePopup,
743                               (HANDLE) dlfp->organelle_popup,
744                               (HANDLE) dlfp->use_ncrna_note,
745                               (HANDLE) dlfp->alternate_splice_flag, NULL);
746 
747   dlfp->optional_features_grp = NormalGroup (g1, 3, 0,
748                    "Optional Features", programFont, NULL);
749                    SetGroupSpacing (dlfp->optional_features_grp, 10, 10);
750   for (i=0; i < NumRemovableItems; i++)
751   {
752     if (i == 0 || i == 4 || i == 7)
753     {
754       k = HiddenGroup (dlfp->optional_features_grp, 0, 4, NULL);
755       SetGroupSpacing (k, 10, 10);
756     }
757     if (i != RemovableCDS)
758     {
759       dlfp->feature_btns[i] =
760                      CheckBox (k, GetRemovableItemName (i),
761                                (BtnActnProc) SetMiscFeatRuleEnable);
762       SetObjectExtra (dlfp->feature_btns[i], dlfp, NULL);
763       SetStatus (dlfp->feature_btns[i], FALSE);
764       if (i == RemovableNoncodingProductFeat) {
765         s2 = HiddenGroup (k, 2, 0, NULL);
766         StaticPrompt (s2, "        ", 8, popupMenuHeight, programFont, 'l');
767         dlfp->misc_feat_parse_rule = PopupList (s2, TRUE, NULL);
768         PopupItem (dlfp->misc_feat_parse_rule, "Use comment before first semicolon");
769         PopupItem (dlfp->misc_feat_parse_rule, "Look for Noncoding Products");
770         SetValue (dlfp->misc_feat_parse_rule, 2);
771         Disable (dlfp->misc_feat_parse_rule);
772       } else if (i == RemovablePromoter) {
773         k2 = HiddenGroup (k, 2, 0, NULL);
774         SetGroupSpacing (k2, 10, 10);
775         StaticPrompt (k2, "        ", 8, popupMenuHeight, programFont, 'l');
776         dlfp->promoter_type = HiddenGroup (k2, 0, 2, NULL);
777         RadioButton (dlfp->promoter_type, "All");
778         RadioButton (dlfp->promoter_type, "If present");
779         SetValue (dlfp->promoter_type, 1);
780         Disable (dlfp->promoter_type);
781         AlignObjects (ALIGN_CENTER, (HANDLE) dlfp->feature_btns[i],
782                                     (HANDLE) dlfp->promoter_type,
783                                     NULL);
784       }
785     }
786   }
787 
788   dlfp->suppressed_feature_grp = NormalGroup (g1, -1, 0,
789                     "Suppress Features", programFont, NULL);
790   sep = GetTopSeqEntryForEntityID(dlfp->input_entityID);
791   dlfp->suppressed_feature_list = FeatureSelectionDialogEx (dlfp->suppressed_feature_grp, TRUE, sep, NULL, NULL);
792 
793   dlfp->featureOptsGrp = NormalGroup (g1, 0, 4, "Suppress", programFont, NULL);
794   SetGroupSpacing (dlfp->featureOptsGrp, 10, 10);
795   dlfp->remove_subfeatures = CheckBox (dlfp->featureOptsGrp, "Mobile element subfeatures", NULL);
796   SetStatus (dlfp->remove_subfeatures, FALSE);
797 
798   dlfp->gene_cluster_opp_strand = CheckBox (dlfp->featureOptsGrp,
799              "Gene cluster/locus subfeatures (both strands)", NULL);
800   SetStatus (dlfp->gene_cluster_opp_strand, FALSE);
801 
802   dlfp->suppress_locus_tags = CheckBox (dlfp->featureOptsGrp, "Locus tags", NULL);
803   SetStatus (dlfp->suppress_locus_tags, FALSE);
804 
805   dlfp->suppress_alt_splice_phrase = CheckBox (dlfp->featureOptsGrp, "Alternative splice phrase", NULL);
806   SetStatus (dlfp->suppress_alt_splice_phrase, FALSE);
807 
808   return p;
809 }
810 
CreateDefLineForm(BaseFormPtr bfp,ModifierItemLocalPtr modList,DeflineFeatureRequestList * feature_requests,Boolean popset_only)811 static void CreateDefLineForm (
812   BaseFormPtr bfp,
813   ModifierItemLocalPtr modList,
814   DeflineFeatureRequestList *feature_requests,
815   Boolean popset_only
816 )
817 {
818   DefLineFormPtr dlfp;
819   WindoW         w;
820   GrouP          h, k, g1 = NULL, c, feat_opts;
821   ButtoN         b;
822   SeqEntryPtr    sep;
823 
824   dlfp = MemNew (sizeof (DefLineFormData));
825   if (dlfp == NULL) return;
826   dlfp->input_entityID = bfp->input_entityID;
827   dlfp->input_itemID = bfp->input_itemID;
828   dlfp->input_itemtype = bfp->input_itemtype;
829   dlfp->popset_only = popset_only;
830 
831   dlfp->modifier_btns = (ButtoN PNTR) MemNew (sizeof (ButtoN) * NumDefLineModifiers());
832 
833   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
834 
835   w = FixedWindow (-50, -33, -10, -10, "Automatic Definition Line",
836   StdCloseWindowProc);
837   SetObjectExtra (w, dlfp, CleanupDefLineForm);
838   dlfp->form = (ForM) w;
839   dlfp->formmessage = DefLineFormMessageProc;
840 
841   dlfp->modList = modList;
842   dlfp->feature_requests = *feature_requests;
843 
844   h = HiddenGroup (w, -1, 0, NULL);
845   SetGroupSpacing (h, 10, 10);
846 
847   k = HiddenGroup (h, -1, 0, NULL);
848   SetGroupSpacing (k, 10, 10);
849   if (!popset_only) {
850     g1 = CreateDefLineFormSourceGroup (k, dlfp, sep);
851   }
852 
853   feat_opts = CreateDefLineFormFeatureOptionsGroup (k, dlfp);
854   AlignObjects (ALIGN_CENTER, (HANDLE) feat_opts, (HANDLE) g1, NULL);
855 
856   c = HiddenGroup (h, 4, 0, NULL);
857   b = DefaultButton (c, "Accept", DoAutoDefLine);
858   SetObjectExtra (b, dlfp, NULL);
859   PushButton (c, "Cancel", StdCancelButtonProc);
860 
861   dlfp->target_bsp = GetBioseqGivenIDs (dlfp->input_entityID,
862           dlfp->input_itemID,
863           dlfp->input_itemtype);
864   dlfp->modify_only_target = CheckBox (c, "Only modify targeted record", NULL);
865   SetStatus (dlfp->modify_only_target, FALSE);
866   if (dlfp->target_bsp == NULL)
867   {
868     Disable (dlfp->modify_only_target);
869   }
870 
871   AlignObjects (ALIGN_CENTER, (HANDLE) k,
872                 (HANDLE) c, NULL);
873   RealizeWindow (w);
874   Show (w);
875   Update ();
876 }
877 
878 
879 /* The AddBestComboModifiersToModList function sets the modifiers
880  * selected by the FindBestCombo process as selected.
881  */
AddBestModifiersToModList(ValNodePtr modifier_indices,ModifierItemLocalPtr modList)882 static void AddBestModifiersToModList (
883   ValNodePtr modifier_indices,
884   ModifierItemLocalPtr modList
885 )
886 {
887   ValNodePtr vnp;
888 
889   for (vnp = modifier_indices; vnp != NULL; vnp = vnp->next)
890   {
891     modList[vnp->data.intvalue].required = TRUE;
892   }
893 }
894 
895 
AutoDefEntityIDNoOptions(Uint2 entityID,Boolean use_modifiers)896 extern void AutoDefEntityIDNoOptions (Uint2 entityID, Boolean use_modifiers)
897 {
898   SeqEntryPtr sep;
899   DeflineFeatureRequestList feature_requests;
900   ModifierItemLocalPtr modList;
901   ValNodePtr modifier_indices = NULL;
902   OrganismDescriptionModifiers odmp;
903   Int4 index;
904   ValNodePtr defline_clauses = NULL;
905   UserObjectPtr uop;
906 
907   sep = GetTopSeqEntryForEntityID (entityID);
908   if (sep == NULL) return;
909 
910   InitFeatureRequests (&feature_requests);
911 
912   modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
913   if (modList == NULL) return;
914   SetRequiredModifiers (modList);
915   CountModifiers (modList, sep);
916 
917   InitOrganismDescriptionModifiers (&odmp, sep);
918   odmp.use_modifiers = use_modifiers;
919 
920   RemoveNucProtSetTitles (sep);
921   SeqEntrySetScope (sep);
922 
923   BuildDefLineFeatClauseList (sep, entityID, &feature_requests,
924                               DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE,
925                               &defline_clauses);
926   if ( AreFeatureClausesUnique (defline_clauses))
927   {
928     modifier_indices = GetModifierIndicesFromModList (modList);
929   }
930   else
931   {
932     modifier_indices = FindBestModifiersForDeflineClauseList (defline_clauses, modList);
933   }
934 
935   BuildDefinitionLinesFromFeatureClauseLists (defline_clauses, modList,
936                                               modifier_indices, &odmp);
937 
938   uop = MakeAutoDefOptionsUserObject(&odmp, modList, modifier_indices,
939       &feature_requests, DEFAULT_ORGANELLE_CLAUSE,
940       FALSE, FALSE);
941   AddAutoDefUserObjectToSeqEntry(sep, uop);
942   uop = UserObjectFree(uop);
943 
944   DefLineFeatClauseListFree (defline_clauses);
945   if (modList != NULL)
946   {
947     for (index=0; index < NumDefLineModifiers (); index++)
948     {
949       ValNodeFree (modList[index].values_seen);
950     }
951     MemFree (modList);
952   }
953   modifier_indices = ValNodeFree (modifier_indices);
954 
955   ClearProteinTitlesInNucProts (entityID, NULL);
956   InstantiateProteinTitles (entityID, NULL);
957   RemovePopsetTitles (sep);
958   AddPopsetTitles (sep, &feature_requests, DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE);
959 }
960 
961 
AutoDefBaseFormCommon(BaseFormPtr bfp,Boolean use_form,Boolean use_modifiers,Boolean popset_only)962 extern void AutoDefBaseFormCommon (
963   BaseFormPtr bfp,
964   Boolean use_form,
965   Boolean use_modifiers,
966   Boolean popset_only
967 )
968 {
969   SeqEntryPtr sep;
970   DeflineFeatureRequestList feature_requests;
971   ModifierItemLocalPtr modList;
972   ValNodePtr modifier_indices = NULL;
973   OrganismDescriptionModifiers odmp;
974   Int4 index;
975   ValNodePtr defline_clauses = NULL;
976   UserObjectPtr uop;
977 
978   if (bfp == NULL) return;
979   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
980   if (sep == NULL) return;
981 
982   InitFeatureRequests (&feature_requests);
983 
984   modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
985   if (modList == NULL) return;
986   SetRequiredModifiers (modList);
987   CountModifiers (modList, sep);
988   if (use_form)
989   {
990     modifier_indices = FindBestModifiersEx (sep, modList, TRUE);
991     AddBestModifiersToModList ( modifier_indices, modList);
992     modifier_indices = ValNodeFree (modifier_indices);
993     CreateDefLineForm (bfp, modList, &feature_requests, popset_only);
994   }
995   else
996   {
997     WatchCursor ();
998     Update ();
999     InitOrganismDescriptionModifiers (&odmp, sep);
1000     odmp.use_modifiers = use_modifiers;
1001 
1002     RemoveNucProtSetTitles (sep);
1003     SeqEntrySetScope (sep);
1004 
1005     BuildDefLineFeatClauseList (sep, bfp->input_entityID, &feature_requests,
1006                                 DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE,
1007                                 &defline_clauses);
1008     if ( AreFeatureClausesUnique (defline_clauses))
1009     {
1010       modifier_indices = GetModifierIndicesFromModList (modList);
1011     }
1012     else
1013     {
1014       modifier_indices = FindBestModifiersForDeflineClauseList (defline_clauses, modList);
1015     }
1016 
1017     if (!popset_only) {
1018       BuildDefinitionLinesFromFeatureClauseLists (defline_clauses, modList,
1019                                                   modifier_indices, &odmp);
1020     }
1021     uop = MakeAutoDefOptionsUserObject(&odmp, modList, modifier_indices,
1022                               &feature_requests, DEFAULT_ORGANELLE_CLAUSE,
1023                               FALSE, FALSE);
1024     AddAutoDefUserObjectToSeqEntry(sep, uop);
1025     uop = UserObjectFree(uop);
1026 
1027     DefLineFeatClauseListFree (defline_clauses);
1028     if (modList != NULL)
1029     {
1030       for (index=0; index < NumDefLineModifiers (); index++)
1031       {
1032         ValNodeFree (modList[index].values_seen);
1033       }
1034       MemFree (modList);
1035     }
1036     modifier_indices = ValNodeFree (modifier_indices);
1037 
1038     if (!popset_only) {
1039       ClearProteinTitlesInNucProts (bfp->input_entityID, NULL);
1040       InstantiateProteinTitles (bfp->input_entityID, NULL);
1041     }
1042     RemovePopsetTitles (sep);
1043     AddPopsetTitles (sep, &feature_requests, DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE);
1044 
1045 
1046     ArrowCursor ();
1047     Update ();
1048     ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1049     ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1050     SeqEntrySetScope (NULL);
1051   }
1052 }
1053 
1054 
1055 static const Int4 s_auto_def_id_preferred_quals[] = {
1056   DEFLINE_POS_Strain,
1057   DEFLINE_POS_Clone,
1058   DEFLINE_POS_Isolate,
1059   DEFLINE_POS_Haplotype,
1060   DEFLINE_POS_Cultivar,
1061   DEFLINE_POS_Ecotype,
1062   DEFLINE_POS_Breed,
1063   DEFLINE_POS_Specimen_voucher,
1064   DEFLINE_POS_Culture_collection,
1065   DEFLINE_POS_Bio_material,
1066 };
1067 
1068 static const Int4 k_num_auto_def_id_preferred_quals = sizeof (s_auto_def_id_preferred_quals) / sizeof (Int4);
1069 
AutoDefIdEx(Uint2 entityID,DefLineType feature_list_type)1070 extern void AutoDefIdEx (Uint2 entityID, DefLineType feature_list_type)
1071 {
1072   SeqEntryPtr sep;
1073   DeflineFeatureRequestList feature_requests;
1074   ModifierItemLocalPtr modList;
1075   ValNodePtr modifier_indices = NULL;
1076   OrganismDescriptionModifiers odmp;
1077   Int4 index;
1078   Boolean added_required = FALSE;
1079   ValNodePtr defline_clauses = NULL;
1080   UserObjectPtr uop;
1081 
1082   sep = GetTopSeqEntryForEntityID (entityID);
1083   if (sep == NULL) return;
1084 
1085   InitFeatureRequests (&feature_requests);
1086   feature_requests.feature_list_type = feature_list_type;
1087 
1088   modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
1089   if (modList == NULL) return;
1090   SetRequiredModifiers (modList);
1091   CountModifiers (modList, sep);
1092   /* first look for first modifier in list that is present on all sources */
1093   for (index = 0; index < k_num_auto_def_id_preferred_quals && !added_required; index++) {
1094     if (modList[s_auto_def_id_preferred_quals[index]].all_present) {
1095       modList[s_auto_def_id_preferred_quals[index]].required = TRUE;
1096       added_required = TRUE;
1097     }
1098   }
1099   /* if not found, then look for first modifier in list that is present on any sources */
1100   for (index = 0; index < k_num_auto_def_id_preferred_quals && !added_required; index++) {
1101     if (modList[s_auto_def_id_preferred_quals[index]].any_present) {
1102       modList[s_auto_def_id_preferred_quals[index]].required = TRUE;
1103       added_required = TRUE;
1104     }
1105   }
1106 
1107   WatchCursor ();
1108   Update ();
1109   InitOrganismDescriptionModifiers (&odmp, sep);
1110   odmp.use_modifiers = TRUE;
1111 
1112   RemoveNucProtSetTitles (sep);
1113   SeqEntrySetScope (sep);
1114 
1115   BuildDefLineFeatClauseList (sep, entityID, &feature_requests,
1116                               DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE,
1117                               &defline_clauses);
1118   if ( AreFeatureClausesUnique (defline_clauses))
1119   {
1120     modifier_indices = GetModifierIndicesFromModList (modList);
1121   }
1122   else
1123   {
1124     modifier_indices = FindBestModifiersForDeflineClauseList (defline_clauses, modList);
1125   }
1126 
1127   BuildDefinitionLinesFromFeatureClauseLists (defline_clauses, modList,
1128                                               modifier_indices, &odmp);
1129 
1130   uop = MakeAutoDefOptionsUserObject(&odmp, modList, modifier_indices,
1131       &feature_requests, DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE);
1132   AddAutoDefUserObjectToSeqEntry(sep, uop);
1133   uop = UserObjectFree(uop);
1134 
1135   DefLineFeatClauseListFree (defline_clauses);
1136   if (modList != NULL)
1137   {
1138     for (index=0; index < NumDefLineModifiers (); index++)
1139     {
1140       ValNodeFree (modList[index].values_seen);
1141     }
1142     MemFree (modList);
1143   }
1144   modifier_indices = ValNodeFree (modifier_indices);
1145 
1146   ClearProteinTitlesInNucProts (entityID, NULL);
1147   InstantiateProteinTitles (entityID, NULL);
1148   RemovePopsetTitles (sep);
1149   AddPopsetTitles (sep, &feature_requests, DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE);
1150 
1151 
1152 
1153 }
1154 
1155 
AutoDefId(Uint2 entityID)1156 extern void AutoDefId (Uint2 entityID)
1157 {
1158   AutoDefIdEx (entityID, DEFLINE_USE_FEATURES);
1159 }
1160 
1161 
AutoDefStrain(BaseFormPtr bfp)1162 extern void AutoDefStrain (
1163   BaseFormPtr bfp
1164 )
1165 {
1166 
1167   if (bfp == NULL) return;
1168 
1169   WatchCursor ();
1170   Update ();
1171   AutoDefId (bfp->input_entityID);
1172 
1173   ArrowCursor ();
1174   Update ();
1175   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1176   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1177   SeqEntrySetScope (NULL);
1178 }
1179 
1180 
AutoDefMiscFeat(BaseFormPtr bfp)1181 extern void AutoDefMiscFeat (
1182   BaseFormPtr bfp
1183 )
1184 {
1185   SeqEntryPtr sep;
1186   DeflineFeatureRequestList feature_requests;
1187   ModifierItemLocalPtr modList;
1188   ValNodePtr modifier_indices = NULL;
1189   OrganismDescriptionModifiers odmp;
1190   Int4 index;
1191   ValNodePtr defline_clauses = NULL;
1192   UserObjectPtr uop;
1193 
1194   if (bfp == NULL) return;
1195   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1196   if (sep == NULL) return;
1197 
1198   InitFeatureRequests (&feature_requests);
1199   feature_requests.keep_items[RemovableNoncodingProductFeat] = TRUE;
1200 
1201   modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
1202   if (modList == NULL) return;
1203   SetRequiredModifiers (modList);
1204   CountModifiers (modList, sep);
1205 
1206   WatchCursor ();
1207   Update ();
1208   InitOrganismDescriptionModifiers (&odmp, sep);
1209   odmp.use_modifiers = TRUE;
1210 
1211   RemoveNucProtSetTitles (sep);
1212   SeqEntrySetScope (sep);
1213 
1214   BuildDefLineFeatClauseList (sep, bfp->input_entityID, &feature_requests,
1215                               DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE,
1216                               &defline_clauses);
1217   if ( AreFeatureClausesUnique (defline_clauses))
1218   {
1219     modifier_indices = GetModifierIndicesFromModList (modList);
1220   }
1221   else
1222   {
1223     modifier_indices = FindBestModifiersForDeflineClauseList (defline_clauses, modList);
1224   }
1225 
1226   BuildDefinitionLinesFromFeatureClauseLists (defline_clauses, modList,
1227                                               modifier_indices, &odmp);
1228 
1229   uop = MakeAutoDefOptionsUserObject(&odmp, modList, modifier_indices,
1230       &feature_requests, DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE);
1231   AddAutoDefUserObjectToSeqEntry(sep, uop);
1232   uop = UserObjectFree(uop);
1233 
1234   DefLineFeatClauseListFree (defline_clauses);
1235   if (modList != NULL)
1236   {
1237     for (index=0; index < NumDefLineModifiers (); index++)
1238     {
1239       ValNodeFree (modList[index].values_seen);
1240     }
1241     MemFree (modList);
1242   }
1243   modifier_indices = ValNodeFree (modifier_indices);
1244 
1245   ClearProteinTitlesInNucProts (bfp->input_entityID, NULL);
1246   InstantiateProteinTitles (bfp->input_entityID, NULL);
1247   RemovePopsetTitles (sep);
1248   AddPopsetTitles (sep, &feature_requests, DEFAULT_ORGANELLE_CLAUSE, FALSE, FALSE);
1249 
1250   ArrowCursor ();
1251   Update ();
1252   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1253   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1254   SeqEntrySetScope (NULL);
1255 }
1256 
1257 
AutoDefCommon(IteM i,Boolean use_form,Boolean use_modifiers)1258 static void AutoDefCommon (IteM i, Boolean use_form, Boolean use_modifiers)
1259 {
1260   BaseFormPtr  bfp;
1261 
1262 #ifdef WIN_MAC
1263   bfp = currentFormDataPtr;
1264 #else
1265   bfp = GetObjectExtra (i);
1266 #endif
1267   if (bfp == NULL || bfp->input_entityID == 0) return;
1268   AutoDefBaseFormCommon (bfp, use_form, use_modifiers, FALSE);
1269 }
1270 
AutoDef(IteM i)1271 extern void AutoDef (IteM i)
1272 {
1273   AutoDefCommon (i, FALSE, TRUE);
1274 }
1275 
AutoDefWithOptions(IteM i)1276 extern void AutoDefWithOptions (IteM i)
1277 {
1278   AutoDefCommon (i, TRUE, TRUE);
1279 }
1280 
1281 
AutoDefWithoutModifiers(IteM i)1282 extern void AutoDefWithoutModifiers (IteM i)
1283 {
1284   AutoDefCommon (i, FALSE, FALSE);
1285 }
1286 
AutoDefToolBtn(ButtoN b)1287 extern void AutoDefToolBtn (ButtoN b)
1288 {
1289   BaseFormPtr  bfp;
1290 
1291    bfp = (BaseFormPtr) GetObjectExtra (b);
1292   if (bfp == NULL) return;
1293   AutoDefBaseFormCommon (bfp, FALSE, TRUE, FALSE);
1294 }
1295 
AutoDefOptionsToolBtn(ButtoN b)1296 extern void AutoDefOptionsToolBtn (ButtoN b)
1297 {
1298   BaseFormPtr  bfp;
1299 
1300   bfp = (BaseFormPtr) GetObjectExtra (b);
1301   if (bfp == NULL) return;
1302   AutoDefBaseFormCommon (bfp, TRUE, TRUE, FALSE);
1303 }
1304 
1305 
AutoDefStrainToolBtn(ButtoN b)1306 extern void AutoDefStrainToolBtn (ButtoN b)
1307 {
1308   BaseFormPtr  bfp;
1309 
1310   bfp = (BaseFormPtr) GetObjectExtra (b);
1311   if (bfp == NULL) return;
1312   AutoDefStrain (bfp);
1313 }
1314 
1315 
AutoDefMiscFeatToolBtn(ButtoN b)1316 extern void AutoDefMiscFeatToolBtn (ButtoN b)
1317 {
1318   BaseFormPtr  bfp;
1319 
1320   bfp = (BaseFormPtr) GetObjectExtra (b);
1321   if (bfp == NULL) return;
1322   AutoDefMiscFeat (bfp);
1323 }
1324 
1325 
AddPopsetTitlesItem(IteM i)1326 extern void AddPopsetTitlesItem (IteM i)
1327 {
1328   BaseFormPtr  bfp;
1329 
1330   bfp = (BaseFormPtr) GetObjectExtra (i);
1331   if (bfp == NULL) return;
1332   AutoDefBaseFormCommon (bfp, TRUE, TRUE, TRUE);
1333 }
1334 
1335 
TrimQuotesAroundString(CharPtr str)1336 static void TrimQuotesAroundString (CharPtr str)
1337 {
1338   Int4 len;
1339   CharPtr src, dst;
1340 
1341   if (StringHasNoText (str) || *str != '"') return;
1342   len = StringLen (str);
1343   if (str[len - 1] != '"') return;
1344   src = str + 1;
1345   dst = str;
1346   while (*src != '"')
1347   {
1348     *dst = *src;
1349     dst++;
1350     src++;
1351   }
1352   *dst = 0;
1353 }
1354 
1355 
1356 typedef struct tablelinedata {
1357   Int4 num_parts;
1358   ValNodePtr parts;
1359 } TableLineData, PNTR TableLinePtr;
1360 
MakeTableData(CharPtr line,ValNodePtr PNTR special_list)1361 static TableLinePtr MakeTableData (CharPtr line, ValNodePtr PNTR special_list)
1362 {
1363   TableLinePtr tlp;
1364   CharPtr p_start, p_end;
1365   Int4    plen;
1366   Boolean found_end;
1367   CharPtr val;
1368   ValNodePtr vnp;
1369 
1370   if (line == NULL) return NULL;
1371   tlp = MemNew (sizeof (TableLineData));
1372   if (tlp == NULL) return NULL;
1373   p_start = line;
1374   found_end = FALSE;
1375   while (*p_start != 0 && !found_end)
1376   {
1377     plen = StringCSpn (p_start, "\t\n");
1378     if (plen == 0)
1379     {
1380       ValNodeAddStr (&tlp->parts, 0, StringSave (""));
1381       tlp->num_parts ++;
1382       p_start++;
1383       if (*p_start == 0) {
1384         if (tlp->num_parts > 0)
1385         {
1386           ValNodeAddStr (&tlp->parts, 0, StringSave (""));
1387           tlp->num_parts ++;
1388         }
1389       }
1390       continue;
1391     }
1392     if (plen == StringLen (p_start))
1393     {
1394       found_end = TRUE;
1395     }
1396     else
1397     {
1398       p_end = p_start + plen;
1399       *p_end = 0;
1400     }
1401     TrimSpacesAroundString (p_start);
1402     TrimQuotesAroundString (p_start);
1403     val = StringSave (p_start);
1404 
1405     vnp = ValNodeAddStr (&tlp->parts, 0, val);
1406     SpecialCharFindWithContext ((CharPtr PNTR)&(vnp->data.ptrvalue), special_list, NULL, NULL);
1407     tlp->num_parts ++;
1408     if (!found_end)
1409     {
1410       p_start = p_end + 1;
1411     }
1412   }
1413   if (tlp->num_parts == 0)
1414   {
1415     MemFree (tlp);
1416     return NULL;
1417   }
1418   return tlp;
1419 }
1420 
CleanUpTableData(ValNodePtr vnp)1421 static void CleanUpTableData (ValNodePtr vnp)
1422 {
1423   TableLinePtr tlp;
1424   ValNodePtr   vnp_next;
1425 
1426   while (vnp != NULL)
1427   {
1428     vnp_next = vnp->next;
1429     vnp->next = NULL;
1430     tlp = vnp->data.ptrvalue;
1431     if (tlp != NULL)
1432     {
1433       ValNodeFreeData (tlp->parts);
1434     }
1435     vnp = ValNodeFree (vnp);
1436     vnp = vnp_next;
1437   }
1438 }
1439 
FormatPopupWithTableDataColumns(PopuP p,ValNodePtr header_line)1440 static void FormatPopupWithTableDataColumns (PopuP p, ValNodePtr header_line)
1441 {
1442   TableLinePtr tlp;
1443   ValNodePtr   vnp;
1444   CharPtr      val_fmt = "Column %d (%s)";
1445   CharPtr      val;
1446   Int4         col = 1;
1447 
1448   if (p == NULL || header_line == NULL) return;
1449   tlp = (TableLinePtr) header_line->data.ptrvalue;
1450   while ((tlp == NULL || tlp->num_parts < 1) && header_line->next != NULL) {
1451     header_line = header_line->next;
1452     tlp = header_line->data.ptrvalue;
1453   }
1454   if (tlp == NULL || tlp->num_parts < 1) return;
1455   vnp = tlp->parts;
1456   while (vnp != NULL) {
1457     val = MemNew ((StringLen(val_fmt) + StringLen (vnp->data.ptrvalue) + 15) * sizeof (Char));
1458     sprintf (val, val_fmt, col, vnp->data.ptrvalue == NULL ? "" : vnp->data.ptrvalue);
1459     PopupItem (p, val);
1460     MemFree (val);
1461     vnp = vnp->next;
1462     col++;
1463   }
1464 }
1465 
1466 
1467 enum orgmodmatchtype
1468 {
1469   eMatchAccession = 1,
1470   eMatchLocalID,
1471   eMatchTaxName,
1472   eMatchTMSMART,
1473   eMatchBankIt,
1474   eMatchGeneral,
1475   eMatchNone
1476 };
1477 
1478 
1479 typedef struct orgmodtablecolumn {
1480   Int4       match_choice;
1481   ValNodePtr apply_choice;
1482 } OrgModTableColumnData, PNTR OrgModTableColumnPtr;
1483 
1484 
OrgModTableColumnFree(OrgModTableColumnPtr t)1485 static OrgModTableColumnPtr OrgModTableColumnFree (OrgModTableColumnPtr t)
1486 {
1487   if (t != NULL) {
1488     t->apply_choice = ValNodeFreeData (t->apply_choice);
1489     t = MemFree (t);
1490   }
1491   return t;
1492 }
1493 
1494 
OrgModTableColumnListFree(ValNodePtr vnp)1495 static ValNodePtr OrgModTableColumnListFree (ValNodePtr vnp)
1496 {
1497   ValNodePtr vnp_next;
1498 
1499   while (vnp != NULL)
1500   {
1501     vnp_next = vnp->next;
1502     vnp->next = NULL;
1503     vnp->data.ptrvalue = OrgModTableColumnFree (vnp->data.ptrvalue);
1504     vnp = ValNodeFree (vnp);
1505     vnp = vnp_next;
1506   }
1507   return vnp;
1508 }
1509 
1510 
1511 typedef struct orgmodtablecolumndlg {
1512   DIALOG_MESSAGE_BLOCK
1513 
1514   GrouP  action_choice;
1515   PopuP  match_choice;
1516   DialoG apply_choice;
1517 
1518   Nlm_ChangeNotifyProc change_notify;
1519   Pointer              change_userdata;
1520 } OrgModTableColumnDlgData, PNTR OrgModTableColumnDlgPtr;
1521 
OrgModTableColumnDialogToData(DialoG d)1522 static Pointer OrgModTableColumnDialogToData (DialoG d)
1523 {
1524   OrgModTableColumnPtr o;
1525   OrgModTableColumnDlgPtr dlg;
1526 
1527   dlg = (OrgModTableColumnDlgPtr) GetObjectExtra (d);
1528   if (dlg == NULL) return NULL;
1529 
1530   o = (OrgModTableColumnPtr) MemNew (sizeof (OrgModTableColumnData));
1531 
1532   if (GetValue (dlg->action_choice) == 1)
1533   {
1534     o->match_choice = GetValue (dlg->match_choice);
1535     o->apply_choice = NULL;
1536   }
1537   else
1538   {
1539     o->match_choice = 0;
1540     o->apply_choice = DialogToPointer (dlg->apply_choice);
1541   }
1542   return o;
1543 }
1544 
1545 
ChangeOrgModTableColumnMatchChoice(PopuP p)1546 static void ChangeOrgModTableColumnMatchChoice (PopuP p)
1547 {
1548   OrgModTableColumnDlgPtr dlg;
1549 
1550   dlg = (OrgModTableColumnDlgPtr) GetObjectExtra (p);
1551   if (dlg == NULL) return;
1552   if (dlg->change_notify != NULL)
1553   {
1554     (dlg->change_notify) (dlg->change_userdata);
1555   }
1556 }
1557 
1558 
ChangeOrgModTableColumnActionChoice(GrouP g)1559 static void ChangeOrgModTableColumnActionChoice (GrouP g)
1560 {
1561   OrgModTableColumnDlgPtr dlg;
1562 
1563   dlg = (OrgModTableColumnDlgPtr) GetObjectExtra (g);
1564   if (dlg == NULL) return;
1565 
1566   if (GetValue (dlg->action_choice) == 1)
1567   {
1568     Enable (dlg->match_choice);
1569     Disable (dlg->apply_choice);
1570   }
1571   else
1572   {
1573     Enable (dlg->apply_choice);
1574     Disable (dlg->match_choice);
1575   }
1576   if (dlg->change_notify != NULL)
1577   {
1578     (dlg->change_notify) (dlg->change_userdata);
1579   }
1580 }
1581 
1582 
OrgModTableColumnDataToDialog(DialoG d,Pointer data)1583 static void OrgModTableColumnDataToDialog (DialoG d, Pointer data)
1584 {
1585   OrgModTableColumnPtr o;
1586   OrgModTableColumnDlgPtr dlg;
1587 
1588   dlg = (OrgModTableColumnDlgPtr) GetObjectExtra (d);
1589   if (dlg == NULL) return;
1590 
1591   o = (OrgModTableColumnPtr) data;
1592 
1593   if (o == NULL)
1594   {
1595     SetValue (dlg->action_choice, 1);
1596     SetValue (dlg->match_choice, eMatchNone);
1597     PointerToDialog (dlg->apply_choice, NULL);
1598   }
1599   else
1600   {
1601     if (o->match_choice == 0)
1602     {
1603       SetValue (dlg->action_choice, 2);
1604       PointerToDialog (dlg->apply_choice, o->apply_choice);
1605     }
1606     else
1607     {
1608       SetValue (dlg->action_choice, 1);
1609       SetValue (dlg->match_choice, o->match_choice);
1610     }
1611   }
1612   ChangeOrgModTableColumnActionChoice (dlg->action_choice);
1613 }
1614 
1615 
1616 static DialoG
OrgModTableColumnDialog(GrouP h,CharPtr value_string,Int4 num_blank,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)1617 OrgModTableColumnDialog
1618 (GrouP                h,
1619  CharPtr              value_string,
1620  Int4                 num_blank,
1621  Nlm_ChangeNotifyProc change_notify,
1622  Pointer              change_userdata)
1623 {
1624   OrgModTableColumnDlgPtr dlg;
1625   GrouP            p, g;
1626   ValNodePtr       qual_selection_list;
1627   CharPtr real_title;
1628   CharPtr title_fmt = "%s (%d are blank)";
1629 
1630   dlg = (OrgModTableColumnDlgPtr) MemNew (sizeof (OrgModTableColumnDlgData));
1631 
1632   if (num_blank > 0) {
1633     real_title = (CharPtr) MemNew (sizeof (Char) * (StringLen (title_fmt) + StringLen (value_string) + 15));
1634     sprintf (real_title, title_fmt, value_string, num_blank);
1635   } else {
1636     real_title = value_string;
1637   }
1638 
1639   p = NormalGroup (h, 3, 0, real_title, programFont, NULL);
1640   SetObjectExtra (p, dlg, StdCleanupExtraProc);
1641 
1642   if (real_title != value_string) {
1643     real_title = MemFree (real_title);
1644   }
1645 
1646   dlg->dialog = (DialoG) p;
1647   dlg->fromdialog = OrgModTableColumnDialogToData;
1648   dlg->todialog = OrgModTableColumnDataToDialog;
1649   dlg->change_notify = change_notify;
1650   dlg->change_userdata = change_userdata;
1651 
1652   dlg->action_choice = HiddenGroup (p, 0, 2, ChangeOrgModTableColumnActionChoice);
1653   SetObjectExtra (dlg->action_choice, dlg, NULL);
1654   SetGroupSpacing (dlg->action_choice, 10, 10);
1655   RadioButton (dlg->action_choice, "Match to");
1656   RadioButton (dlg->action_choice, "Apply to");
1657   SetValue (dlg->action_choice, 1);
1658 
1659   g = HiddenGroup (p, 0, 3, NULL);
1660   /* list of matchable items */
1661   dlg->match_choice = PopupList (g, TRUE, ChangeOrgModTableColumnMatchChoice);
1662   SetObjectExtra (dlg->match_choice, dlg, NULL);
1663   PopupItem (dlg->match_choice, "Accession");
1664   PopupItem (dlg->match_choice, "Local ID");
1665   PopupItem (dlg->match_choice, "Organism Taxonomy Name");
1666   PopupItem (dlg->match_choice, "TMSMART ID");
1667   PopupItem (dlg->match_choice, "BankIt ID");
1668   PopupItem (dlg->match_choice, "General ID");
1669   PopupItem (dlg->match_choice, "None");
1670   SetValue (dlg->match_choice, eMatchNone);
1671 
1672 
1673   /* list of organism modifiers */
1674   qual_selection_list = GetSourceQualDescList (TRUE, TRUE, FALSE, FALSE);
1675 
1676   ValNodeAddPointer (&qual_selection_list, 1, StringSave ("Tax Name"));
1677 
1678     /* note - the ValNodeSelectionDialog will free the qual_selection_list when done */
1679   dlg->apply_choice = ValNodeSelectionDialog (g, qual_selection_list, 8, SourceQualValNodeName,
1680                                 ValNodeSimpleDataFree, SourceQualValNodeDataCopy,
1681                                 SourceQualValNodeMatch, "qual choice",
1682                                 change_notify, change_userdata, FALSE);
1683 
1684   ChangeOrgModTableColumnActionChoice(dlg->action_choice);
1685   return (DialoG) p;
1686 }
1687 
1688 
1689 typedef struct orgmodloadformdata {
1690   FEATURE_FORM_BLOCK
1691 
1692   ValNodePtr        line_list;
1693   BioSourcePtr PNTR biop_list;
1694   DialoG PNTR       columns;
1695   Int4              num_columns;
1696   Uint2             entityID;
1697   ButtoN            replace_with_blank_btn;
1698   ButtoN            accept_button;
1699   ButtoN            leave_dlg_up_btn;
1700   DialoG            taxname_options;
1701 
1702   /* These members are for importing modifiers in the
1703    * submission dialogs.
1704    */
1705   SeqEntryPtr       seq_list;
1706   Boolean           done;
1707   Boolean           mods_added;
1708 
1709 } OrgModLoadFormData, PNTR OrgModLoadFormPtr;
1710 
SetFormModsEnable(Pointer userdata)1711 static void SetFormModsEnable (Pointer userdata)
1712 {
1713   OrgModLoadFormPtr form_data;
1714   OrgModTableColumnPtr o;
1715   Boolean           have_apply = FALSE;
1716   Boolean           have_action = FALSE;
1717   Boolean           have_apply_taxname = FALSE;
1718   Int4              column_index;
1719 
1720   form_data = (OrgModLoadFormPtr) userdata;
1721   if (form_data == NULL) return;
1722 
1723   for (column_index = 0;
1724        column_index < form_data->num_columns;
1725        column_index ++)
1726   {
1727     o = (OrgModTableColumnPtr) DialogToPointer (form_data->columns[column_index]);
1728     if (o == NULL) continue;
1729     if (o->match_choice > 0 && o->match_choice != eMatchNone)
1730     {
1731       have_action = TRUE;
1732     }
1733     else if (o->apply_choice != NULL)
1734     {
1735       have_apply = TRUE;
1736       if (o->apply_choice->choice > 0 && StringCmp (o->apply_choice->data.ptrvalue, "Tax Name") == 0)
1737       {
1738         have_apply_taxname = TRUE;
1739       }
1740     }
1741     o = OrgModTableColumnFree (o);
1742   }
1743 
1744   if (have_apply_taxname)
1745   {
1746     Enable (form_data->taxname_options);
1747   }
1748   else
1749   {
1750     Disable (form_data->taxname_options);
1751   }
1752 
1753   /* must have an action selected if there is more than one line */
1754   if ( ! have_action
1755     && form_data->line_list != NULL
1756     && form_data->line_list->next != NULL)
1757   {
1758     Disable (form_data->accept_button);
1759     return;
1760   }
1761 
1762   if (have_apply)
1763   {
1764     Enable (form_data->accept_button);
1765   }
1766   else
1767   {
1768     Disable (form_data->accept_button);
1769   }
1770 }
1771 
CleanupOrgModLoadForm(GraphiC g,VoidPtr data)1772 static void CleanupOrgModLoadForm (
1773   GraphiC g,
1774   VoidPtr data
1775 )
1776 {
1777   OrgModLoadFormPtr form_data;
1778 
1779   form_data = (OrgModLoadFormPtr)data;
1780   if (form_data == NULL) return;
1781   form_data->columns = MemFree (form_data->columns);
1782   CleanUpTableData (form_data->line_list);
1783   StdCleanupFormProc (g, data);
1784 }
1785 
1786 static CharPtr genome_names[] =
1787 {
1788   "",
1789   "genomic",
1790   "chloroplast",
1791   "chromoplast",
1792   "kinteoplast",
1793   "mitochondrion",
1794   "plastid",
1795   "macronuclear",
1796   "extrachrom",
1797   "plasmid",
1798   "transposon",
1799   "insertion_seq",
1800   "cyanelle",
1801   "proviral",
1802   "virion",
1803   "nucleomorph",
1804   "apicoplast",
1805   "leucoplast",
1806   "proplastid",
1807   "endogenous_virus",
1808   "hydrogenosome",
1809   "chromosome",
1810   "chromatophore"
1811 };
1812 
GetGenomeValFromString(CharPtr value_string)1813 static Uint1 GetGenomeValFromString (CharPtr value_string)
1814 {
1815   Uint1 genome_val;
1816 
1817   if (StringHasNoText (value_string))
1818   {
1819     return 0;
1820   }
1821   for (genome_val = 1; genome_val < sizeof (genome_names); genome_val++)
1822   {
1823     if (StringICmp (value_string, genome_names[genome_val]) == 0)
1824     {
1825       return genome_val;
1826     }
1827   }
1828   return 0;
1829 }
1830 
1831 
AddOneQualToOrg(BioSourcePtr biop,CharPtr value_string,SourceQualDescPtr sqdp,ExistingTextPtr etp)1832 static void AddOneQualToOrg
1833 ( BioSourcePtr biop,
1834   CharPtr      value_string,
1835   SourceQualDescPtr sqdp,
1836   ExistingTextPtr etp)
1837 {
1838   OrgRefPtr     orp;
1839   OrgModPtr     mod, last_mod;
1840   OrgNamePtr    onp;
1841   SubSourcePtr  ssp, last_ssp;
1842 
1843   if (biop == NULL || value_string == NULL || sqdp == NULL) return;
1844 
1845   orp = biop->org;
1846   if (orp == NULL) return;
1847 
1848   if (sqdp->isOrgMod)
1849   {
1850     onp = orp->orgname;
1851     if (onp == NULL) {
1852       onp = OrgNameNew ();
1853       if (onp == NULL) return;
1854       orp->orgname = onp;
1855     }
1856     mod = onp->mod;
1857     last_mod = NULL;
1858     while (mod != NULL
1859       && mod->subtype != sqdp->subtype)
1860     {
1861       last_mod = mod;
1862       mod = mod->next;
1863     }
1864     if (mod != NULL)
1865     {
1866       if (StringHasNoText (value_string)) {
1867         if (last_mod == NULL) {
1868           onp->mod = mod->next;
1869         } else {
1870           last_mod->next = mod->next;
1871         }
1872         mod->next = NULL;
1873         mod = OrgModFree (mod);
1874       } else {
1875         mod->subname = HandleExistingText (mod->subname,
1876                                            StringSave (value_string),
1877                                            etp);
1878       }
1879     }
1880     else if (!StringHasNoText (value_string))
1881     {
1882       mod = OrgModNew ();
1883       mod->subtype = sqdp->subtype;
1884       mod->subname = StringSave (value_string);
1885       if (last_mod == NULL)
1886       {
1887         onp->mod = mod;
1888       }
1889       else
1890       {
1891         last_mod->next = mod;
1892       }
1893     }
1894   } else {
1895     ssp = biop->subtype;
1896     last_ssp = NULL;
1897     while (ssp != NULL && ssp->subtype != sqdp->subtype)
1898     {
1899       last_ssp = ssp;
1900       ssp = ssp->next;
1901     }
1902     if (ssp != NULL)
1903     {
1904       if (StringHasNoText (value_string)) {
1905         if (last_ssp == NULL) {
1906           biop->subtype = ssp->next;
1907         } else {
1908           last_ssp->next = ssp->next;
1909         }
1910         ssp->next = NULL;
1911         ssp = SubSourceFree (ssp);
1912       } else {
1913         ssp->name = HandleExistingText (ssp->name,
1914                                         StringSave (value_string),
1915                                         etp);
1916       }
1917     }
1918     else if (!StringHasNoText (value_string))
1919     {
1920       ssp = SubSourceNew ();
1921       ssp->subtype = sqdp->subtype;
1922       ssp->name = StringSave (value_string);
1923       if (last_ssp == NULL)
1924       {
1925         biop->subtype = ssp;
1926       }
1927       else
1928       {
1929         last_ssp->next = ssp;
1930       }
1931     }
1932   }
1933 }
1934 
ApplyTaxNameToOrg(BioSourcePtr biop,CharPtr value_string,ExistingTextPtr etp)1935 static void ApplyTaxNameToOrg (BioSourcePtr biop, CharPtr value_string, ExistingTextPtr etp)
1936 {
1937   if (biop == NULL) return;
1938   if (biop->org == NULL)
1939   {
1940   	biop->org = OrgRefNew ();
1941   }
1942   if (biop->org == NULL) return;
1943   biop->org->taxname = HandleExistingText (biop->org->taxname,
1944                                            StringSave (value_string),
1945                                            etp);
1946 }
1947 
ApplyLocationToOrg(BioSourcePtr biop,CharPtr value_string)1948 static void ApplyLocationToOrg (BioSourcePtr biop, CharPtr value_string)
1949 {
1950   if (biop != NULL)
1951   {
1952     biop->genome = GetGenomeValFromString (value_string);
1953   }
1954 }
1955 
1956 
HasExtraAccession(CharPtr acc_str,GBBlockPtr gbp)1957 static Boolean HasExtraAccession (
1958   CharPtr acc_str,
1959   GBBlockPtr gbp)
1960 {
1961   ValNodePtr vnp;
1962   if (acc_str == NULL || gbp == NULL) return FALSE;
1963   for (vnp = gbp->extra_accessions;
1964        vnp != NULL && StringCmp (acc_str, vnp->data.ptrvalue) != 0;
1965        vnp = vnp->next)
1966   {}
1967   if (vnp != NULL)
1968     return TRUE;
1969   else
1970     return FALSE;
1971 }
1972 
1973 static Boolean
IDIsInTextList(CharPtr id,CharPtr acc_str,Boolean look_for_tmsmart)1974 IDIsInTextList
1975 (CharPtr id,
1976  CharPtr acc_str,
1977  Boolean look_for_tmsmart)
1978 {
1979   CharPtr wanted, found;
1980   Int4    len;
1981 
1982   if (id == NULL || acc_str == NULL) return FALSE;
1983 
1984   if (StringNCmp (acc_str, "TMSMART:", 8) == 0) {
1985     if (look_for_tmsmart) {
1986       wanted = acc_str + 8;
1987     } else {
1988       return FALSE;
1989     }
1990   } else {
1991     if (look_for_tmsmart) {
1992       return FALSE;
1993     } else {
1994       wanted = acc_str;
1995     }
1996   }
1997   len = StringLen (wanted);
1998   found = StringStr (id, wanted);
1999   if (found == NULL) {
2000     return FALSE;
2001   } else if (*(found + len) != 0
2002              && *(found + len) != ','
2003              && ! isspace ((Int4)*(found + len))) {
2004     return FALSE;
2005   } else if (found != id
2006              && * (found - 1) != ','
2007              && ! isspace ((Int4)*(found - 1))) {
2008     return FALSE;
2009   } else {
2010     return TRUE;
2011   }
2012 }
2013 
IDListHasValue(CharPtr id,SeqIdPtr list,Boolean only_local,Boolean look_for_tmsmart,Boolean look_for_general)2014 static Boolean IDListHasValue (
2015   CharPtr id,
2016   SeqIdPtr list,
2017   Boolean only_local,
2018   Boolean look_for_tmsmart,
2019   Boolean look_for_general)
2020 {
2021   SeqIdPtr sip;
2022   Char     acc_str [256];
2023   Int4     match_len, match_len2, db_len;
2024   DbtagPtr gnl_tag;
2025 
2026   for (sip = list; sip != NULL; sip = sip->next)
2027   {
2028     if (sip->choice == SEQID_GENERAL
2029         && look_for_general
2030         && StringNICmp (id, "gnl|", 3) == 0
2031         && (db_len = StringCSpn (id + 4, "|")) > 0)
2032     {
2033       gnl_tag = (DbtagPtr) sip->data.ptrvalue;
2034       if (gnl_tag != NULL
2035           && StringNCmp (id + 4, gnl_tag->db, db_len) == 0
2036           && ((gnl_tag->tag->id > 0 && atoi (id + 5 + db_len) == gnl_tag->tag->id)
2037              || StringCmp (gnl_tag->tag->str, id + 5 + db_len) == 0))
2038       {
2039         return TRUE;
2040       }
2041     }
2042     if ((! only_local && sip->choice != SEQID_LOCAL)
2043       || (only_local && sip->choice == SEQID_LOCAL))
2044     {
2045       SeqIdWrite (sip, acc_str, PRINTID_REPORT, sizeof (acc_str));
2046       if (look_for_tmsmart)
2047       {
2048         if (StringNCmp (acc_str, "TMSMART:", 8) == 0
2049           && StringCmp (id, acc_str + 8) == 0)
2050         {
2051           return TRUE;
2052         } else if (IDIsInTextList (id, acc_str, TRUE)) {
2053           return TRUE;
2054         }
2055       } else {
2056         if (only_local)
2057         {
2058           if (StringCmp (id, acc_str) == 0)
2059           {
2060           	return TRUE;
2061           }
2062         }
2063         else
2064         {
2065           match_len = StringCSpn (acc_str, ".");
2066           match_len2 = StringCSpn (id, ".");
2067           if (match_len == match_len2
2068             && match_len > 0 && StringNCmp (id, acc_str, match_len) == 0)
2069           {
2070             return TRUE;
2071           }
2072         }
2073       }
2074     }
2075   }
2076   return FALSE;
2077 }
2078 
2079 
FindBankitNumberInTableString(CharPtr table_string)2080 static CharPtr FindBankitNumberInTableString (CharPtr table_string)
2081 {
2082   CharPtr bankit_start;
2083 
2084   if (StringHasNoText (table_string))
2085   {
2086     return table_string;
2087   }
2088   bankit_start = table_string + StringSpn (table_string, " ");
2089   if (StringNICmp (bankit_start, "bankit", 6) == 0)
2090   {
2091     bankit_start += 6;
2092     bankit_start += StringSpn (bankit_start, " ");
2093   }
2094   return bankit_start;
2095 }
2096 
2097 
2098 
2099 typedef struct applycolumn {
2100   ValNodePtr apply_choice;
2101   CharPtr    apply_value;
2102 } ApplyColumnData, PNTR ApplyColumnPtr;
2103 
2104 
ApplyColumnFree(ApplyColumnPtr p)2105 static ApplyColumnPtr ApplyColumnFree (ApplyColumnPtr p)
2106 {
2107   if (p != NULL) {
2108     p->apply_value = MemFree (p->apply_value);
2109     p->apply_choice = ValNodeFreeData (p->apply_choice);
2110     p = MemFree (p);
2111   }
2112   return p;
2113 }
2114 
2115 
ApplyColumnListFree(ValNodePtr vnp)2116 static ValNodePtr ApplyColumnListFree (ValNodePtr vnp)
2117 {
2118   ValNodePtr vnp_next;
2119 
2120   while (vnp != NULL) {
2121     vnp_next = vnp->next;
2122     vnp->next = NULL;
2123     vnp->data.ptrvalue = ApplyColumnFree (vnp->data.ptrvalue);
2124     vnp = ValNodeFree (vnp);
2125     vnp = vnp_next;
2126   }
2127   return vnp;
2128 }
2129 
2130 
2131 typedef struct tabletobiosource {
2132   ValNodePtr identifiers;
2133   ValNodePtr columns_to_apply;
2134   ValNodePtr biop_list;
2135 } TableToBioSourceData, PNTR TableToBioSourcePtr;
2136 
2137 
TableToBioSourceFree(TableToBioSourcePtr t)2138 static TableToBioSourcePtr TableToBioSourceFree (TableToBioSourcePtr t)
2139 {
2140   if (t != NULL) {
2141     t->identifiers = ValNodeFreeData (t->identifiers);
2142     t->columns_to_apply = ApplyColumnListFree (t->columns_to_apply);
2143     t->biop_list = ValNodeFree (t->biop_list);
2144     t = MemFree (t);
2145   }
2146   return t;
2147 }
2148 
2149 
TableToBioSourceListFree(ValNodePtr vnp)2150 static ValNodePtr TableToBioSourceListFree (ValNodePtr vnp)
2151 {
2152   ValNodePtr vnp_next;
2153 
2154   while (vnp != NULL)
2155   {
2156     vnp_next = vnp->next;
2157     vnp->next = NULL;
2158     vnp->data.ptrvalue = TableToBioSourceFree (vnp->data.ptrvalue);
2159     vnp = ValNodeFree (vnp);
2160     vnp = vnp_next;;
2161   }
2162   return vnp;
2163 }
2164 
2165 
TableToBioSourceFromTableLine(OrgModTableColumnPtr PNTR o_list,Int4 num_columns,TableLinePtr tlp)2166 static TableToBioSourcePtr TableToBioSourceFromTableLine (OrgModTableColumnPtr PNTR o_list, Int4 num_columns, TableLinePtr tlp)
2167 {
2168   Int4       column_index;
2169   ValNodePtr part;
2170   TableToBioSourcePtr t;
2171   ApplyColumnPtr      a;
2172 
2173   if (o_list == NULL || tlp == NULL || tlp->parts == NULL) return NULL;
2174 
2175   t = (TableToBioSourcePtr) MemNew (sizeof (TableToBioSourceData));
2176   for (column_index = 0, part = tlp->parts;
2177        column_index < num_columns;
2178        column_index ++)
2179   {
2180     if (o_list[column_index] == NULL) continue;
2181     if (o_list[column_index]->match_choice > 0
2182         && o_list[column_index]->match_choice != eMatchNone
2183         && part != NULL)
2184     {
2185       ValNodeAddPointer (&(t->identifiers), o_list[column_index]->match_choice, StringSave (part->data.ptrvalue));
2186     }
2187     else if (o_list[column_index]->apply_choice != NULL)
2188     {
2189       a = (ApplyColumnPtr) MemNew (sizeof (ApplyColumnData));
2190       a->apply_choice = SourceQualValNodeDataCopy (o_list[column_index]->apply_choice);
2191       if (part == NULL)
2192       {
2193         a->apply_value = StringSave ("");
2194       }
2195       else
2196       {
2197         a->apply_value = StringSave (part->data.ptrvalue);
2198       }
2199 
2200       ValNodeAddPointer (&(t->columns_to_apply), 0, a);
2201     }
2202 
2203     if (column_index < tlp->num_parts && part != NULL)
2204     {
2205       part = part->next;
2206     }
2207   }
2208   return t;
2209 }
2210 
2211 
OrgModLoadFormToApplyList(OrgModLoadFormPtr f)2212 static ValNodePtr OrgModLoadFormToApplyList (OrgModLoadFormPtr f)
2213 {
2214   ValNodePtr line;
2215   ValNodePtr apply_list = NULL;
2216   Int4       column_index;
2217   OrgModTableColumnPtr PNTR o_list;
2218 
2219   if (f == NULL) return NULL;
2220 
2221   o_list = (OrgModTableColumnPtr PNTR) MemNew (f->num_columns * sizeof (OrgModTableColumnPtr));
2222   for (column_index = 0; column_index < f->num_columns; column_index++)
2223   {
2224     o_list[column_index] = (OrgModTableColumnPtr) DialogToPointer (f->columns[column_index]);
2225   }
2226 
2227   for (line = f->line_list; line != NULL; line = line->next)
2228   {
2229     ValNodeAddPointer (&apply_list, 0, TableToBioSourceFromTableLine (o_list, f->num_columns, line->data.ptrvalue));
2230   }
2231 
2232   for (column_index = 0; column_index < f->num_columns; column_index++)
2233   {
2234     o_list[column_index] = OrgModTableColumnFree (o_list[column_index]);
2235   }
2236   o_list = MemFree (o_list);
2237   return apply_list;
2238 }
2239 
2240 
AddBioSourceToValNodeListIfNotAlreadyPresent(ValNodePtr PNTR list,BioSourcePtr biop)2241 static void AddBioSourceToValNodeListIfNotAlreadyPresent (ValNodePtr PNTR list, BioSourcePtr biop)
2242 {
2243   ValNodePtr vnp;
2244 
2245   if (list == NULL || biop == NULL) return;
2246 
2247   vnp = *list;
2248   if (vnp == NULL) {
2249     ValNodeAddPointer (list, 0, biop);
2250   } else {
2251     while (vnp->next != NULL) {
2252       if (biop == vnp->data.ptrvalue) {
2253         return;
2254       }
2255       vnp = vnp->next;
2256     }
2257     vnp->next = ValNodeNew(NULL);
2258     vnp->next->choice = 0;
2259     vnp->next->data.ptrvalue = biop;
2260   }
2261 }
2262 
2263 
FindOrganismsForTableToBioSourceByTaxName(BioSourcePtr biop,Pointer userdata)2264 static void FindOrganismsForTableToBioSourceByTaxName (BioSourcePtr biop, Pointer userdata)
2265 {
2266   ValNodePtr apply_list, vnp, vnp_id;
2267   TableToBioSourcePtr    t;
2268 
2269   if (biop == NULL || biop->org == NULL || userdata == NULL) return;
2270 
2271   apply_list = (ValNodePtr) userdata;
2272   for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2273   {
2274     t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2275     for (vnp_id = t->identifiers; vnp_id != NULL; vnp_id = vnp_id->next)
2276     {
2277       if (vnp_id->choice == eMatchTaxName && StringCmp (biop->org->taxname, vnp_id->data.ptrvalue) == 0) {
2278         AddBioSourceToValNodeListIfNotAlreadyPresent (&(t->biop_list), biop);
2279       }
2280     }
2281   }
2282 }
2283 
2284 
2285 /* look for matches based on accession numbers, local IDs, or bankit IDs */
FindOrganismsForTableToBioSourceByBioseq(BioseqPtr bsp,Pointer userdata)2286 static void FindOrganismsForTableToBioSourceByBioseq (BioseqPtr bsp, Pointer userdata)
2287 {
2288   ValNodePtr             apply_list, vnp, vnp_id;
2289   TableToBioSourcePtr    t;
2290   SeqDescrPtr            sdp;
2291   GBBlockPtr             gbp;
2292   BioSourcePtr           biop;
2293   Boolean                use_local_id, look_for_tmsmart, look_for_general;
2294   Char                   match_str [30];
2295   SeqIdPtr               sip;
2296   DbtagPtr               dp;
2297   ObjectIdPtr            oip;
2298 
2299   biop = GetBiopForBsp (bsp);
2300   if (biop == NULL || biop->org == NULL || userdata == NULL) return;
2301 
2302   apply_list = (ValNodePtr) userdata;
2303 
2304   /* Find GenBankBlockPtr for extra accessions */
2305   gbp = NULL;
2306   sdp = BioseqGetSeqDescr (bsp, Seq_descr_genbank, NULL);
2307   if (sdp != NULL)
2308   {
2309     gbp = sdp->data.ptrvalue;
2310   }
2311 
2312   /* Find Bankit ID */
2313   match_str [0] = 0;
2314   for(sip = bsp->id; sip != NULL; sip = sip->next) {
2315     if(sip->choice == SEQID_GENERAL) {
2316       dp = (DbtagPtr) sip->data.ptrvalue;
2317       if(StringICmp(dp->db, "BankIt") == 0) {
2318         oip = dp->tag;
2319         sprintf (match_str, "%d", oip->id);
2320         break;
2321       }
2322     }
2323   }
2324 
2325   for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2326   {
2327     t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2328     for (vnp_id = t->identifiers; vnp_id != NULL; vnp_id = vnp_id->next)
2329     {
2330       if (vnp_id->choice == eMatchAccession
2331           || vnp_id->choice == eMatchLocalID
2332           || vnp_id->choice == eMatchTMSMART
2333           || vnp_id->choice == eMatchGeneral)
2334       {
2335         if (vnp_id->choice == eMatchAccession
2336             || vnp_id->choice == eMatchTMSMART
2337             || vnp_id->choice == eMatchGeneral) {
2338           use_local_id = FALSE;
2339         } else {
2340           use_local_id = TRUE;
2341         }
2342         if (vnp_id->choice == eMatchTMSMART) {
2343           look_for_tmsmart = TRUE;
2344         } else {
2345           look_for_tmsmart = FALSE;
2346         }
2347 
2348         if (vnp_id->choice == eMatchGeneral)
2349         {
2350           look_for_general = TRUE;
2351         }
2352         else
2353         {
2354           look_for_general = FALSE;
2355         }
2356 
2357         if (IDListHasValue ( vnp_id->data.ptrvalue,
2358                             bsp->id, use_local_id, look_for_tmsmart, look_for_general)
2359               || (! use_local_id &&
2360                   HasExtraAccession ( vnp_id->data.ptrvalue, gbp)))
2361         {
2362           AddBioSourceToValNodeListIfNotAlreadyPresent (&(t->biop_list), biop);
2363         }
2364       }
2365       else if (vnp_id->choice == eMatchBankIt)
2366       {
2367         if (StringCmp (FindBankitNumberInTableString(vnp_id->data.ptrvalue),
2368                           match_str) == 0) {
2369           AddBioSourceToValNodeListIfNotAlreadyPresent (&(t->biop_list), biop);
2370         }
2371       }
2372     }
2373   }
2374 }
2375 
2376 
FindOrganismsForTableToBioSourceList(ValNodePtr apply_list,SeqEntryPtr sep)2377 static void FindOrganismsForTableToBioSourceList (ValNodePtr apply_list, SeqEntryPtr sep)
2378 {
2379   VisitBioSourcesInSep (sep, apply_list, FindOrganismsForTableToBioSourceByTaxName);
2380   VisitBioseqsInSep (sep, apply_list, FindOrganismsForTableToBioSourceByBioseq);
2381 
2382 }
2383 
2384 
ListOrganismsWithMultipleRows(ValNodePtr apply_list)2385 static Boolean ListOrganismsWithMultipleRows (ValNodePtr apply_list)
2386 {
2387   LogInfoPtr          lip;
2388   ValNodePtr          vnp, vnp_compare, vnp_biop, vnp_biop2;
2389   BioSourcePtr        biop;
2390   TableToBioSourcePtr t, t2;
2391   Int4                row1_num, row2_num;
2392   Boolean             rval;
2393 
2394   lip = OpenLog ("Organisms Affected by More Than One Row");
2395   for (vnp = apply_list, row1_num = 0; vnp != NULL; vnp = vnp->next, row1_num++)
2396   {
2397     t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2398     if (t == NULL || t->biop_list == NULL) continue;
2399     for (vnp_biop = t->biop_list; vnp_biop != NULL; vnp_biop = vnp_biop->next)
2400     {
2401       biop = vnp_biop->data.ptrvalue;
2402       if (biop == NULL) continue;
2403       for (vnp_compare = vnp->next, row2_num = row1_num + 1; vnp_compare != NULL; vnp_compare = vnp_compare->next, row2_num++)
2404       {
2405         t2 = (TableToBioSourcePtr) vnp_compare->data.ptrvalue;
2406         for (vnp_biop2 = t2->biop_list; vnp_biop2 != NULL; vnp_biop2 = vnp_biop2->next)
2407         {
2408           if (vnp_biop2->data.ptrvalue == biop)
2409           {
2410             fprintf (lip->fp, "Two rows (%d and %d) match the same organism", row1_num, row2_num);
2411             if (t->identifiers != NULL && t->identifiers->data.ptrvalue != NULL
2412                 && t2->identifiers != NULL && t2->identifiers->data.ptrvalue != NULL)
2413             {
2414               if (StringCmp (t->identifiers->data.ptrvalue, t2->identifiers->data.ptrvalue) == 0)
2415               {
2416                 fprintf (lip->fp, " (both are %s).\n", (CharPtr) t->identifiers->data.ptrvalue);
2417               }
2418               else
2419               {
2420                 fprintf (lip->fp, " (%s and %s).\n", (CharPtr) t->identifiers->data.ptrvalue, (CharPtr) t2->identifiers->data.ptrvalue);
2421               }
2422             }
2423             else if (t->identifiers != NULL && t->identifiers->data.ptrvalue != NULL)
2424             {
2425               fprintf (lip->fp, " (%s).\n", (CharPtr) t->identifiers->data.ptrvalue);
2426             }
2427             else if (t2->identifiers != NULL && t2->identifiers->data.ptrvalue != NULL)
2428             {
2429               fprintf (lip->fp, " (%s).\n", (CharPtr) t2->identifiers->data.ptrvalue);
2430             }
2431             else
2432             {
2433               fprintf (lip->fp, ".\n");
2434             }
2435 
2436             lip->data_in_log = TRUE;
2437           }
2438         }
2439       }
2440     }
2441   }
2442   rval = lip->data_in_log;
2443   CloseLog (lip);
2444   FreeLog (lip);
2445   return rval;
2446 }
2447 
2448 
ListRowsWithMultipleOrganisms(ValNodePtr apply_list)2449 static Boolean ListRowsWithMultipleOrganisms (ValNodePtr apply_list)
2450 {
2451   LogInfoPtr          lip;
2452   ValNodePtr          vnp, vnp_id;
2453   TableToBioSourcePtr t;
2454   Boolean             rval;
2455 
2456   lip = OpenLog ("Rows with Multiple Organisms");
2457   for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2458   {
2459     t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2460     if (t == NULL || t->biop_list == NULL || t->biop_list->next == NULL || t->identifiers == NULL) continue;
2461     fprintf (lip->fp, "Row with the following match columns applies to %d organisms\n", ValNodeLen (t->biop_list));
2462     for (vnp_id = t->identifiers; vnp_id != NULL; vnp_id = vnp_id->next)
2463     {
2464       fprintf (lip->fp, "\t%s\n", (CharPtr) vnp_id->data.ptrvalue);
2465     }
2466     lip->data_in_log = TRUE;
2467   }
2468 
2469   rval = lip->data_in_log;
2470   CloseLog (lip);
2471   FreeLog (lip);
2472   return rval;
2473 }
2474 
2475 
ListRowsWithoutOrganisms(ValNodePtr apply_list)2476 static void ListRowsWithoutOrganisms (ValNodePtr apply_list)
2477 {
2478   LogInfoPtr          lip;
2479   ValNodePtr          vnp, vnp_id;
2480   TableToBioSourcePtr t;
2481 
2482   lip = OpenLog ("Rows without Organisms");
2483   for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2484   {
2485     t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2486     if (t == NULL || t->biop_list != NULL || t->identifiers == NULL) continue;
2487     for (vnp_id = t->identifiers; vnp_id != NULL; vnp_id = vnp_id->next)
2488     {
2489       fprintf (lip->fp, "No match found for %s\n", (CharPtr) vnp_id->data.ptrvalue);
2490       lip->data_in_log = TRUE;
2491     }
2492   }
2493 
2494   CloseLog (lip);
2495   FreeLog (lip);
2496 }
2497 
2498 
2499 /* This code is used to detect existing modifiers before a change is made */
FindOneQualOnOrg(BioSourcePtr biop,SourceQualDescPtr sqdp,GetSamplePtr gsp)2500 static void FindOneQualOnOrg
2501 ( BioSourcePtr biop,
2502   SourceQualDescPtr sqdp,
2503   GetSamplePtr gsp)
2504 {
2505   OrgModPtr     mod;
2506   SubSourcePtr  ssp;
2507 
2508   if (biop == NULL || gsp == NULL || sqdp == NULL) return;
2509 
2510   if (sqdp->isOrgMod)
2511   {
2512     if (biop->org == NULL
2513         || biop->org->orgname == NULL)
2514     {
2515       return;
2516     }
2517 
2518     mod = biop->org->orgname->mod;
2519     while (mod != NULL
2520            && mod->subtype != sqdp->subtype)
2521     {
2522       mod = mod->next;
2523     }
2524     if (mod != NULL)
2525     {
2526       gsp->num_found ++;
2527       if (gsp->sample_text == NULL)
2528       {
2529         gsp->sample_text = StringSave (mod->subname);
2530       }
2531       else if (StringCmp (gsp->sample_text, mod->subname) != 0)
2532       {
2533         gsp->all_same = FALSE;
2534       }
2535     }
2536   }
2537   else
2538   {
2539     ssp = biop->subtype;
2540     while (ssp != NULL && ssp->subtype != sqdp->subtype)
2541     {
2542       ssp = ssp->next;
2543     }
2544     if (ssp != NULL)
2545     {
2546       gsp->num_found ++;
2547       if (gsp->sample_text == NULL)
2548       {
2549         gsp->sample_text = StringSave (ssp->name);
2550       }
2551       else if (StringCmp (gsp->sample_text, ssp->name) != 0)
2552       {
2553         gsp->all_same = FALSE;
2554       }
2555     }
2556   }
2557 }
2558 
2559 
DetectExistingModifiersForTableToBioSourceList(ValNodePtr apply_list,Boolean replace_with_blank)2560 static GetSamplePtr DetectExistingModifiersForTableToBioSourceList (ValNodePtr apply_list, Boolean replace_with_blank)
2561 {
2562   ValNodePtr vnp, vnp_col, vnp_biop;
2563   TableToBioSourcePtr    t;
2564   BioSourcePtr           biop;
2565   ApplyColumnPtr         a;
2566   GetSamplePtr           gsp;
2567 
2568   gsp = GetSampleNew ();
2569   for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2570   {
2571     t = (TableToBioSourcePtr) vnp->data.ptrvalue;
2572     for (vnp_biop = t->biop_list; vnp_biop != NULL; vnp_biop = vnp_biop->next)
2573     {
2574       biop = vnp_biop->data.ptrvalue;
2575       for (vnp_col = t->columns_to_apply; vnp_col != NULL; vnp_col = vnp_col->next)
2576       {
2577         a = (ApplyColumnPtr) vnp_col->data.ptrvalue;
2578 
2579         if (replace_with_blank || ! StringHasNoText (a->apply_value))
2580         {
2581           if (a->apply_choice->choice == 0 && a->apply_choice->data.ptrvalue != NULL)
2582           {
2583             FindOneQualOnOrg (biop, a->apply_choice->data.ptrvalue, gsp);
2584           }
2585           else if (a->apply_choice->choice > 0
2586                  && (StringICmp (a->apply_choice->data.ptrvalue, "Tax Name") == 0
2587                      || StringICmp (a->apply_choice->data.ptrvalue, "Organism") == 0))
2588 
2589           {
2590             if (biop->org != NULL && !StringHasNoText (biop->org->taxname))
2591             {
2592               gsp->num_found ++;
2593               if (gsp->sample_text == NULL)
2594               {
2595                 gsp->sample_text = StringSave (biop->org->taxname);
2596               }
2597               else if (StringCmp (gsp->sample_text, biop->org->taxname) != 0)
2598               {
2599                 gsp->all_same = FALSE;
2600               }
2601             }
2602           }
2603           else if (a->apply_choice->choice > 0 && StringICmp (a->apply_choice->data.ptrvalue, "Location") == 0)
2604           {
2605             if (biop->genome > 0)
2606             {
2607               gsp->num_found ++;
2608               if (gsp->sample_text == NULL)
2609               {
2610                 gsp->sample_text = StringSave (genome_names [biop->genome]);
2611               }
2612               else if (StringCmp (gsp->sample_text, genome_names [biop->genome]) != 0)
2613               {
2614                 gsp->all_same = FALSE;
2615               }
2616             }
2617           }
2618         }
2619       }
2620     }
2621   }
2622   return gsp;
2623 }
2624 
2625 
2626 static void
ApplyOneTableToBioSource(TableToBioSourcePtr t,Boolean replace_with_blank,ExistingTextPtr etp,TaxnameOptionsPtr taxname_options)2627 ApplyOneTableToBioSource
2628 (TableToBioSourcePtr t,
2629  Boolean             replace_with_blank,
2630  ExistingTextPtr     etp,
2631  TaxnameOptionsPtr   taxname_options)
2632 {
2633   ValNodePtr vnp_col, vnp_biop;
2634   BioSourcePtr biop;
2635   ApplyColumnPtr a;
2636 
2637   if (t == NULL || t->columns_to_apply == NULL || t->biop_list == NULL) return;
2638 
2639   for (vnp_biop = t->biop_list; vnp_biop != NULL; vnp_biop = vnp_biop->next)
2640   {
2641     biop = (BioSourcePtr) vnp_biop->data.ptrvalue;
2642     if (biop == NULL) continue;
2643     for (vnp_col = t->columns_to_apply; vnp_col != NULL; vnp_col = vnp_col->next)
2644     {
2645       a = (ApplyColumnPtr) vnp_col->data.ptrvalue;
2646       if (a == NULL
2647           || a->apply_choice == NULL
2648           || (!replace_with_blank && StringHasNoText (a->apply_value))) continue;
2649 
2650       if (a->apply_choice->choice == 0 && a->apply_choice->data.ptrvalue != NULL)
2651       {
2652         AddOneQualToOrg (biop, a->apply_value, a->apply_choice->data.ptrvalue,
2653                           etp);
2654       }
2655       else if (a->apply_choice->choice > 0
2656                 && (StringICmp (a->apply_choice->data.ptrvalue, "Tax Name") == 0
2657                     || StringICmp (a->apply_choice->data.ptrvalue, "Organism") == 0))
2658       {
2659         ApplyTaxNameToOrg (biop, a->apply_value, etp);
2660         ApplyTaxnameOptionsToBioSource (biop, taxname_options);
2661       }
2662       else if (a->apply_choice->choice > 0 && StringICmp (a->apply_choice->data.ptrvalue, "Location") == 0)
2663       {
2664         ApplyLocationToOrg (biop, a->apply_value);
2665       }
2666     }
2667   }
2668 }
2669 
2670 
2671 static void
ApplyTableToBioSourceList(ValNodePtr apply_list,Boolean replace_with_blank,ExistingTextPtr etp,TaxnameOptionsPtr taxname_options)2672 ApplyTableToBioSourceList
2673 (ValNodePtr        apply_list,
2674  Boolean           replace_with_blank,
2675  ExistingTextPtr   etp,
2676  TaxnameOptionsPtr taxname_options)
2677 {
2678   ValNodePtr vnp;
2679 
2680   for (vnp = apply_list; vnp != NULL; vnp = vnp->next)
2681   {
2682     ApplyOneTableToBioSource (vnp->data.ptrvalue, replace_with_blank, etp, taxname_options);
2683   }
2684 }
2685 
2686 
DoAcceptFormMods(ButtoN b)2687 static void DoAcceptFormMods (ButtoN b)
2688 {
2689   OrgModLoadFormPtr form_data;
2690   SeqEntryPtr   sep;
2691   GetSamplePtr gsp;
2692   ValNodePtr apply_list;
2693   Boolean    replace_with_blank;
2694   ExistingTextPtr etp;
2695   TaxnameOptionsPtr taxname_options;
2696 
2697   form_data = GetObjectExtra (b);
2698   if (form_data == NULL) return;
2699 
2700   sep = GetTopSeqEntryForEntityID (form_data->entityID);
2701   if (sep == NULL) return;
2702 
2703   replace_with_blank = GetStatus (form_data->replace_with_blank_btn);
2704   apply_list = OrgModLoadFormToApplyList (form_data);
2705   FindOrganismsForTableToBioSourceList (apply_list, sep);
2706   if (ListOrganismsWithMultipleRows (apply_list))
2707   {
2708     Message (MSG_ERROR, "Multiple rows in the table apply to the same organism!  Table cannot be imported.");
2709     apply_list = TableToBioSourceListFree (apply_list);
2710     return;
2711   }
2712   ListRowsWithoutOrganisms (apply_list);
2713   if (ListRowsWithMultipleOrganisms (apply_list)) {
2714     if (ANS_CANCEL == Message (MSG_OKC, "Some rows in the table apply to more than one organism - continue?"))
2715     {
2716       apply_list = TableToBioSourceListFree (apply_list);
2717       return;
2718     }
2719   }
2720   gsp = DetectExistingModifiersForTableToBioSourceList (apply_list, replace_with_blank);
2721   etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
2722   gsp = GetSampleFree (gsp);
2723   if (etp != NULL && etp->existing_text_choice == eExistingTextChoiceCancel)
2724   {
2725     etp = MemFree (etp);
2726     apply_list = TableToBioSourceListFree (apply_list);
2727     return;
2728   }
2729   taxname_options = DialogToPointer (form_data->taxname_options);
2730   ApplyTableToBioSourceList (apply_list, replace_with_blank, etp, taxname_options);
2731   taxname_options = MemFree (taxname_options);
2732   etp = MemFree (etp);
2733   apply_list = TableToBioSourceListFree (apply_list);
2734 
2735   Update ();
2736   ObjMgrSetDirtyFlag (form_data->entityID, TRUE);
2737   ObjMgrSendMsg (OM_MSG_UPDATE, form_data->entityID, 0, 0);
2738   if (!GetStatus (form_data->leave_dlg_up_btn))
2739   {
2740     Remove (form_data->form);
2741   }
2742 }
2743 
2744 
ReadTableData(void)2745 static ValNodePtr ReadTableData (void)
2746 {
2747   Char          path [PATH_MAX];
2748   Int4          max_columns;
2749   ValNodePtr    header_line;
2750   ValNodePtr    line_list;
2751   TableLinePtr  tlp;
2752   ValNodePtr    vnp;
2753   ReadBufferData rbd;
2754   CharPtr        line;
2755   ValNodePtr     special_list = NULL;
2756 
2757   path [0] = '\0';
2758   if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return NULL;
2759 
2760   rbd.fp = FileOpen (path, "r");
2761   if (rbd.fp == NULL) return NULL;
2762   rbd.current_data = NULL;
2763 
2764   line_list = NULL;
2765   max_columns = 0;
2766   header_line = NULL;
2767   line = AbstractReadFunction (&rbd);
2768   while (line != NULL)
2769   {
2770     tlp = MakeTableData (line, &special_list);
2771     if (tlp != NULL)
2772     {
2773       vnp = ValNodeNew (line_list);
2774       if (vnp == NULL) return NULL;
2775       if (line_list == NULL) line_list = vnp;
2776       vnp->data.ptrvalue = tlp;
2777       if (tlp->num_parts > max_columns)
2778       {
2779         max_columns = tlp->num_parts;
2780         header_line = vnp;
2781       }
2782     }
2783     line = MemFree (line);
2784     line = AbstractReadFunction (&rbd);
2785   }
2786   FileClose (rbd.fp);
2787   if (special_list != NULL && !FixSpecialCharactersForStringsInList (special_list, "The table contains special characters\nand cannot be used until they are replaced.", FALSE))
2788   {
2789     line_list = ValNodeFreeData (line_list);
2790     header_line = NULL;
2791   }
2792   /* throw out all lines before header line */
2793   else if (header_line != line_list)
2794   {
2795     vnp = line_list;
2796     while (vnp != NULL && vnp->next != header_line)
2797     {
2798       vnp = vnp->next;
2799     }
2800     if (vnp != NULL) {
2801       vnp->next = NULL;
2802     }
2803     ValNodeFreeData (line_list);
2804     line_list = NULL;
2805   }
2806   special_list = FreeContextList (special_list);
2807   return header_line;
2808 }
2809 
2810 
GetColumnBlankCounts(ValNodePtr header_line,Int4 num_columns)2811 static Int4Ptr GetColumnBlankCounts (ValNodePtr header_line, Int4 num_columns)
2812 {
2813   ValNodePtr   line_vnp, part_vnp;
2814   TableLinePtr tlp;
2815   Int4         i;
2816   Int4Ptr      blank_list;
2817 
2818   if (header_line == NULL || num_columns < 1) return NULL;
2819 
2820   blank_list = (Int4Ptr) MemNew (sizeof (Int4) * num_columns);
2821 
2822   for (line_vnp = header_line; line_vnp != NULL; line_vnp = line_vnp->next)
2823   {
2824     if (line_vnp->data.ptrvalue == NULL) continue;
2825     tlp = (TableLinePtr) line_vnp->data.ptrvalue;
2826     part_vnp = tlp->parts;
2827     for (i = 0; i < num_columns; i++)
2828     {
2829       if (part_vnp == NULL || StringHasNoText (part_vnp->data.ptrvalue))
2830       {
2831         blank_list[i]++;
2832       }
2833       if (part_vnp != NULL)
2834       {
2835         part_vnp = part_vnp->next;
2836       }
2837     }
2838   }
2839   return blank_list;
2840 }
2841 
2842 
LoadOrganismModifierTableBaseForm(BaseFormPtr bfp,Boolean IsTaxConsult)2843 NLM_EXTERN void LoadOrganismModifierTableBaseForm (BaseFormPtr bfp, Boolean IsTaxConsult)
2844 {
2845   ValNodePtr    header_line;
2846   ValNodePtr    vnp;
2847   TableLinePtr  tlp;
2848   WindoW        w;
2849   GrouP         h, g, k, c;
2850   OrgModLoadFormPtr form_data;
2851   Int4          index;
2852   Int4          max_columns;
2853   Int4Ptr       blank_list = NULL;
2854   OrgModTableColumnData o;
2855 
2856   if (bfp == NULL) return;
2857 
2858   header_line = ReadTableData ();
2859   if (header_line == NULL || header_line->data.ptrvalue == NULL) return;
2860   tlp = header_line->data.ptrvalue;
2861   max_columns = 0;
2862   for (vnp = tlp->parts; vnp != NULL; vnp = vnp->next)
2863   {
2864     max_columns ++;
2865   }
2866 
2867   form_data = MemNew (sizeof (OrgModLoadFormData));
2868   if (form_data == NULL) return;
2869   form_data->entityID = bfp->input_entityID;
2870   form_data->line_list = header_line;
2871 
2872   form_data->num_columns = max_columns;
2873   form_data->columns = (DialoG PNTR) MemNew (max_columns * sizeof (DialoG));
2874 
2875   /* now create a dialog to display values */
2876   w = FixedWindow (-50, -33, -10, -10, "Table Conversion", StdCloseWindowProc);
2877   SetObjectExtra (w, form_data, CleanupOrgModLoadForm);
2878   form_data->form = (ForM) w;
2879 
2880   h = HiddenGroup (w, -1, 0, NULL);
2881   SetGroupSpacing (h, 10, 10);
2882   g = HiddenGroup (h, 3, 0, NULL);
2883 
2884   /* pre-analyze table for blanks, so we can display the information in the column dialogs */
2885   blank_list = GetColumnBlankCounts (header_line, form_data->num_columns);
2886 
2887   tlp = header_line->data.ptrvalue;
2888   for (index = 0, vnp = tlp->parts; index < max_columns; index++)
2889   {
2890     form_data->columns[index] = OrgModTableColumnDialog (g, vnp == NULL ? NULL : vnp->data.ptrvalue,
2891                                                          blank_list == NULL ? 0 : blank_list[index],
2892                                                          SetFormModsEnable, form_data);
2893     if (vnp != NULL) vnp = vnp->next;
2894   }
2895   blank_list = MemFree (blank_list);
2896   if (max_columns > 1 && IsTaxConsult)
2897   {
2898     o.match_choice = eMatchAccession;
2899     o.apply_choice = NULL;
2900     PointerToDialog (form_data->columns[0], &o);
2901     o.match_choice = 0;
2902     ValNodeAddPointer (&o.apply_choice, 1, "Tax Name");
2903     PointerToDialog (form_data->columns[1], &o);
2904     o.apply_choice = ValNodeFree (o.apply_choice);
2905   }
2906 
2907   k = HiddenGroup (h, 1, 0, NULL);
2908   form_data->replace_with_blank_btn = CheckBox (k, "Erase current value when blank found in table", NULL);
2909 
2910   form_data->taxname_options = TaxnameOptionsDialog (h, NULL, NULL);
2911   Disable (form_data->taxname_options);
2912 
2913   c = HiddenGroup (h, 4, 0, NULL);
2914   form_data->accept_button = DefaultButton (c, "Accept", DoAcceptFormMods);
2915   SetObjectExtra (form_data->accept_button, form_data, NULL);
2916   PushButton (c, "Cancel", StdCancelButtonProc);
2917   form_data->leave_dlg_up_btn = CheckBox (c, "Leave Dialog Up", NULL);
2918 
2919   SetFormModsEnable(form_data);
2920 
2921   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) k, (HANDLE) form_data->taxname_options, (HANDLE) c, NULL);
2922 
2923   RealizeWindow (w);
2924   Show (w);
2925   Update ();
2926 }
2927 
LoadOrganismModifierTableEx(IteM i,Boolean IsTaxConsult)2928 static void LoadOrganismModifierTableEx (IteM i, Boolean IsTaxConsult)
2929 {
2930   BaseFormPtr   bfp;
2931 #ifdef WIN_MAC
2932   bfp = currentFormDataPtr;
2933 #else
2934   bfp = GetObjectExtra (i);
2935 #endif
2936 
2937   LoadOrganismModifierTableBaseForm (bfp, IsTaxConsult);
2938 }
2939 
LoadOrganismModifierTable(IteM i)2940 extern void LoadOrganismModifierTable (IteM i)
2941 {
2942   LoadOrganismModifierTableEx (i, FALSE);
2943 }
2944 
LoadTaxConsult(IteM i)2945 extern void LoadTaxConsult (IteM i)
2946 {
2947   LoadOrganismModifierTableEx (i, TRUE);
2948 }
2949 
2950 
LoadOrganismModifierTableButtonEx(ButtoN b,Boolean IsTaxConsult)2951 static void LoadOrganismModifierTableButtonEx (ButtoN b, Boolean IsTaxConsult)
2952 {
2953   BaseFormPtr   bfp;
2954 
2955   bfp = (BaseFormPtr) GetObjectExtra(b);
2956   if (b == NULL) {
2957     return;
2958   }
2959   LoadOrganismModifierTableBaseForm (bfp, IsTaxConsult);
2960 }
2961 
2962 
LoadTaxConsultBtn(ButtoN b)2963 extern void LoadTaxConsultBtn (ButtoN b)
2964 {
2965   LoadOrganismModifierTableButtonEx (b, TRUE);
2966 }
2967 
2968 
2969 
ReplaceImportModifierName(CharPtr PNTR orig_name,Int4 col_num,ValNodePtr preferred_list)2970 extern Boolean ReplaceImportModifierName (CharPtr PNTR orig_name, Int4 col_num, ValNodePtr preferred_list)
2971 {
2972   ModalAcceptCancelData acd;
2973   WindoW                w;
2974   Char                  title[128];
2975   GrouP                 g, k, c;
2976   ButtoN                b;
2977   DialoG                modifier_name_choice;
2978   ValNodePtr            mod_name_choice_list = NULL, default_vnp, choice_vnp;
2979 
2980   if (orig_name == NULL)
2981   {
2982     return FALSE;
2983   }
2984   acd.accepted = FALSE;
2985   acd.cancelled = FALSE;
2986 
2987   sprintf (title, "Choose import modifier for column %d", col_num);
2988   w = MovableModalWindow(-20, -13, -10, -10, title, NULL);
2989   g = HiddenGroup (w, -1, 0, NULL);
2990 
2991   k = NULL;
2992   if (!StringHasNoText (*orig_name))
2993   {
2994     k = HiddenGroup (g, 2, 0, NULL);
2995     StaticPrompt (k, "Unrecognized column name:", 0, popupMenuHeight, programFont, 'r');
2996     StaticPrompt (k, *orig_name, 0, popupMenuHeight, programFont, 'l');
2997   }
2998 
2999   ValNodeAddPointer (&mod_name_choice_list, 1, StringSave ("Ignore Column"));
3000   ValNodeLink (&mod_name_choice_list, ValNodeDupList(preferred_list, SourceQualValNodeCopy));
3001   ValNodeLink(&mod_name_choice_list, GetSourceQualDescList (TRUE, TRUE, FALSE, FALSE));
3002   ValNodeAddPointer (&mod_name_choice_list, 2, StringSave ("Organism"));
3003   ValNodeAddPointer (&mod_name_choice_list, 3, StringSave ("Location"));
3004 
3005   modifier_name_choice = ValNodeSelectionDialog (g, mod_name_choice_list, 6, SourceQualValNodeName,
3006                                 ValNodeSimpleDataFree, SourceQualValNodeDataCopy,
3007                                 SourceQualValNodeMatch, "feature list",
3008                                 NULL, NULL, FALSE);
3009   default_vnp = ValNodeNew (NULL);
3010   default_vnp->choice = 1;
3011   default_vnp->data.ptrvalue = StringSave ("Ignore Column");
3012   default_vnp->next = NULL;
3013   PointerToDialog (modifier_name_choice, default_vnp);
3014   default_vnp = ValNodeFreeData (default_vnp);
3015 
3016   c = HiddenGroup (g, 2, 0, NULL);
3017   b = PushButton (c, "Accept", ModalAcceptButton);
3018   SetObjectExtra (b, &acd, NULL);
3019   b = PushButton (c, "Cancel", ModalCancelButton);
3020   SetObjectExtra (b, &acd, NULL);
3021   if (k == NULL)
3022   {
3023     AlignObjects (ALIGN_CENTER, (HANDLE) modifier_name_choice, (HANDLE) c, NULL);
3024   }
3025   else
3026   {
3027     AlignObjects (ALIGN_CENTER, (HANDLE) k, (HANDLE) modifier_name_choice, (HANDLE) c, NULL);
3028   }
3029   Show (w);
3030   Select (w);
3031   acd.accepted = FALSE;
3032   acd.cancelled = FALSE;
3033   while (!acd.accepted && ! acd.cancelled)
3034   {
3035     ProcessExternalEvent ();
3036     Update ();
3037   }
3038   ProcessAnEvent ();
3039   choice_vnp = (ValNodePtr) DialogToPointer (modifier_name_choice);
3040 
3041   Remove (w);
3042   if (acd.cancelled)
3043   {
3044     return FALSE;
3045   }
3046   else
3047   {
3048     *orig_name = MemFree (*orig_name);
3049     if (choice_vnp != NULL && choice_vnp->choice != 1)
3050     {
3051       *orig_name = SourceQualValNodeName (choice_vnp);
3052     }
3053     return TRUE;
3054   }
3055 }
3056 
3057 
FreeTableData(ValNodePtr lines)3058 static ValNodePtr FreeTableData (ValNodePtr lines)
3059 {
3060   TableLinePtr tlp;
3061 
3062   if (lines == NULL)
3063   {
3064     return NULL;
3065   }
3066   lines->next = FreeTableData (lines->next);
3067   tlp = (lines->data.ptrvalue);
3068   if (tlp != NULL)
3069   {
3070     tlp->parts = ValNodeFreeData (tlp->parts);
3071     tlp = MemFree (tlp);
3072     lines->data.ptrvalue = NULL;
3073   }
3074   return ValNodeFree (lines);
3075 }
3076 
3077 
3078 typedef struct exportorgtable
3079 {
3080   ModifierItemLocalPtr modList;
3081   BioseqPtr            bsp;
3082   Boolean              list_tax_name;
3083   Boolean              list_accession;
3084   Boolean              list_local;
3085   Boolean              list_general;
3086   Boolean              launch_excel;
3087 
3088   ValNodePtr           organism_id_profile;
3089   FILE *fp;
3090 } ExportOrgTableData, PNTR ExportOrgTablePtr;
3091 
3092 #define ORGANISM_ID_PROFILE_HAS_ACCESSION 1
3093 #define ORGANISM_ID_PROFILE_HAS_LOCAL     2
3094 #define ORGANISM_ID_PROFILE_HAS_GENERAL   4
3095 #define ORGANISM_ID_PROFILE_HAS_TAX_NAME  8
3096 
ExportOneOrganism(BioSourcePtr biop,Pointer userdata)3097 static void ExportOneOrganism (BioSourcePtr biop, Pointer userdata)
3098 {
3099   ExportOrgTablePtr eotp;
3100   Char              acc_str [256];
3101   SeqIdPtr          sip;
3102   SeqIdPtr          acc_sip = NULL, local_sip = NULL, gen_sip = NULL;
3103   Int4              i;
3104   OrgModPtr         mod;
3105   SubSourcePtr      ssp;
3106   Boolean           need_tab = FALSE;
3107 
3108   if (biop == NULL || userdata == NULL) return;
3109   eotp = (ExportOrgTablePtr) userdata;
3110 
3111   if (eotp->bsp == NULL || eotp->modList == NULL || eotp->fp == NULL) return;
3112 
3113   for (sip = eotp->bsp->id;
3114        sip != NULL && (acc_sip == NULL || local_sip == NULL);
3115        sip = sip->next)
3116   {
3117     if (acc_sip == NULL && sip->choice == SEQID_GENBANK)
3118     {
3119       acc_sip = sip;
3120     }
3121     else if (local_sip == NULL && sip->choice == SEQID_LOCAL)
3122     {
3123       local_sip = sip;
3124     }
3125     else if (gen_sip == NULL && sip->choice == SEQID_GENERAL)
3126     {
3127       gen_sip = sip;
3128     }
3129   }
3130 
3131   if (eotp->list_accession)
3132   {
3133     /* get accession number and print to column */
3134     if (acc_sip == NULL)
3135     {
3136       fprintf (eotp->fp, " ");
3137     }
3138     else
3139     {
3140       sip = acc_sip->next;
3141       acc_sip->next = NULL;
3142       SeqIdWrite (acc_sip, acc_str, PRINTID_TEXTID_ACC_VER, sizeof (acc_str));
3143       acc_sip->next = sip;
3144       fprintf (eotp->fp, "%s", acc_str);
3145     }
3146     need_tab = TRUE;
3147   }
3148 
3149   if (eotp->list_local)
3150   {
3151     if (need_tab) {
3152       fprintf (eotp->fp, "\t");
3153     }
3154     /* get local ID and print to column */
3155     if (local_sip == NULL)
3156     {
3157       fprintf (eotp->fp, " ");
3158     }
3159     else
3160     {
3161       sip = local_sip->next;
3162       local_sip->next = NULL;
3163       SeqIdWrite (local_sip, acc_str, PRINTID_TEXTID_ACCESSION, sizeof (acc_str));
3164       local_sip->next = sip;
3165       fprintf (eotp->fp, "%s", acc_str);
3166     }
3167     need_tab = TRUE;
3168   }
3169 
3170   if (eotp->list_general)
3171   {
3172     if (need_tab) {
3173       fprintf (eotp->fp, "\t");
3174     }
3175     /* get general ID and print to column */
3176     if (gen_sip == NULL)
3177     {
3178       fprintf (eotp->fp, " ");
3179     }
3180     else
3181     {
3182       sip = gen_sip->next;
3183       gen_sip->next = NULL;
3184       SeqIdWrite (gen_sip, acc_str, PRINTID_FASTA_GENERAL, sizeof (acc_str));
3185       gen_sip->next = sip;
3186       fprintf (eotp->fp, "%s", acc_str);
3187     }
3188     need_tab = TRUE;
3189   }
3190 
3191   if (eotp->list_tax_name)
3192   {
3193     if (need_tab) {
3194       fprintf (eotp->fp, "\t");
3195     }
3196     /* get tax name and print to column */
3197     if (biop->org != NULL && ! StringHasNoText (biop->org->taxname))
3198     {
3199       fprintf (eotp->fp, "%s", biop->org->taxname);
3200     }
3201     else
3202     {
3203       fprintf (eotp->fp, " ");
3204     }
3205     need_tab = TRUE;
3206   }
3207 
3208   /* print modifiers for each available column */
3209   for (i= 0; i < NumDefLineModifiers (); i++)
3210   {
3211     if (eotp->modList[i].any_present)
3212     {
3213       mod = NULL;
3214       ssp = NULL;
3215       if (DefLineModifiers[i].isOrgMod)
3216       {
3217         if ( biop->org != NULL && biop->org->orgname != NULL)
3218         {
3219           mod = biop->org->orgname->mod;
3220           while (mod != NULL
3221                  && mod->subtype != DefLineModifiers[i].subtype)
3222           {
3223             mod = mod->next;
3224           }
3225         }
3226       }
3227       else
3228       {
3229         ssp = biop->subtype;
3230         while (ssp != NULL && ssp->subtype != DefLineModifiers[i].subtype)
3231         {
3232           ssp = ssp->next;
3233         }
3234       }
3235       if (need_tab) {
3236         fprintf (eotp->fp, "\t");
3237       }
3238 	  if (IsNonTextModifier (DefLineModifiers[i].name))
3239 	  {
3240 	    if (mod == NULL && ssp == NULL)
3241 	    {
3242 	      fprintf (eotp->fp, "FALSE");
3243 		}
3244 		else
3245 		{
3246 		  fprintf (eotp->fp, "TRUE");
3247 		}
3248 	  }
3249       else if (mod != NULL && !StringHasNoText (mod->subname))
3250       {
3251         fprintf (eotp->fp, "%s", mod->subname);
3252       }
3253       else if (ssp != NULL && !StringHasNoText (ssp->name))
3254       {
3255         fprintf (eotp->fp, "%s", ssp->name);
3256       }
3257       else
3258       {
3259         fprintf (eotp->fp, " ");
3260       }
3261       need_tab = TRUE;
3262     }
3263   }
3264   fprintf (eotp->fp, "\n");
3265 }
3266 
ExportOrganisms(SeqEntryPtr sep,ExportOrgTablePtr eotp)3267 static void ExportOrganisms (SeqEntryPtr sep, ExportOrgTablePtr eotp)
3268 {
3269   BioseqSetPtr bssp;
3270   SeqEntryPtr  nsep;
3271   BioseqPtr    bsp;
3272 
3273   if (sep == NULL || eotp == NULL || sep->data.ptrvalue == NULL) return;
3274 
3275   if (IS_Bioseq (sep))
3276   {
3277     bsp = (BioseqPtr) sep->data.ptrvalue;
3278     if (bsp != NULL && !ISA_aa (bsp->mol)) {
3279       eotp->bsp = bsp;
3280       VisitBioSourcesOnBsp (eotp->bsp, eotp, ExportOneOrganism);
3281     }
3282   }
3283   else if (IS_Bioseq_set (sep))
3284   {
3285     bssp = (BioseqSetPtr) sep->data.ptrvalue;
3286     if (bssp->_class == BioseqseqSet_class_nuc_prot)
3287     {
3288       nsep = FindNucSeqEntry (sep);
3289       if (nsep != NULL)
3290       {
3291         eotp->bsp = (BioseqPtr) nsep->data.ptrvalue;
3292         VisitBioSourcesOnSep (sep, eotp, ExportOneOrganism);
3293       }
3294     }
3295     else
3296     {
3297       for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
3298       {
3299         ExportOrganisms (sep, eotp);
3300       }
3301     }
3302   }
3303 }
3304 
GetOneOrganismIdProfile(BioSourcePtr biop,Pointer userdata)3305 static void GetOneOrganismIdProfile (BioSourcePtr biop, Pointer userdata)
3306 {
3307   ExportOrgTablePtr eotp;
3308   SeqIdPtr          sip;
3309   Int4              profile_value = 0;
3310 
3311   if (biop == NULL || userdata == NULL) return;
3312   eotp = (ExportOrgTablePtr) userdata;
3313 
3314   if (eotp->bsp == NULL) return;
3315 
3316   for (sip = eotp->bsp->id;
3317        sip != NULL;
3318        sip = sip->next)
3319   {
3320     if (sip->choice == SEQID_GENBANK)
3321     {
3322 	  profile_value |= ORGANISM_ID_PROFILE_HAS_ACCESSION;
3323     }
3324     else if (sip->choice == SEQID_LOCAL)
3325     {
3326       profile_value |= ORGANISM_ID_PROFILE_HAS_LOCAL;
3327     }
3328     else if (sip->choice == SEQID_GENERAL)
3329     {
3330       profile_value |= ORGANISM_ID_PROFILE_HAS_GENERAL;
3331     }
3332   }
3333 
3334   if (biop->org != NULL && ! StringHasNoText (biop->org->taxname))
3335   {
3336     profile_value |= ORGANISM_ID_PROFILE_HAS_TAX_NAME;
3337   }
3338 
3339   ValNodeAddInt (&(eotp->organism_id_profile), 0, profile_value);
3340 }
3341 
GetOrganismIDProfile(SeqEntryPtr sep,ExportOrgTablePtr eotp)3342 static void GetOrganismIDProfile (SeqEntryPtr sep, ExportOrgTablePtr eotp)
3343 {
3344   BioseqSetPtr bssp;
3345   SeqEntryPtr  nsep;
3346 
3347   if (sep == NULL || eotp == NULL || sep->data.ptrvalue == NULL) return;
3348 
3349   if (IS_Bioseq (sep))
3350   {
3351     eotp->bsp = (BioseqPtr) sep->data.ptrvalue;
3352     VisitBioSourcesOnBsp (eotp->bsp, eotp, GetOneOrganismIdProfile);
3353   }
3354   else if (IS_Bioseq_set (sep))
3355   {
3356     bssp = (BioseqSetPtr) sep->data.ptrvalue;
3357     if (bssp->_class == BioseqseqSet_class_nuc_prot)
3358     {
3359       nsep = FindNucSeqEntry (sep);
3360       if (nsep != NULL)
3361       {
3362         eotp->bsp = (BioseqPtr) nsep->data.ptrvalue;
3363         VisitBioSourcesOnSep (sep, eotp, GetOneOrganismIdProfile);
3364       }
3365     }
3366     else
3367     {
3368       for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
3369       {
3370         GetOrganismIDProfile (sep, eotp);
3371       }
3372     }
3373   }
3374 }
3375 
GetOrganismIDProfileSummary(ValNodePtr organism_id_profile,Int4Ptr available,Int4Ptr recommended)3376 static void GetOrganismIDProfileSummary (ValNodePtr organism_id_profile, Int4Ptr available, Int4Ptr recommended)
3377 {
3378   ValNodePtr vnp;
3379   Int4       has_vals = 0, recommended_vals = 0, missing_vals = 0;
3380 
3381   if (available != NULL)
3382   {
3383     *available = 0;
3384   }
3385   if (recommended != NULL)
3386   {
3387     *recommended = 0;
3388   }
3389 
3390   for (vnp = organism_id_profile;
3391 	   vnp != NULL;
3392 	   vnp = vnp->next)
3393   {
3394     has_vals |= vnp->data.intvalue;
3395 	missing_vals |= !(vnp->data.intvalue);
3396 	if (vnp->data.intvalue & ORGANISM_ID_PROFILE_HAS_ACCESSION)
3397 	{
3398 	  recommended_vals |= ORGANISM_ID_PROFILE_HAS_ACCESSION;
3399 	}
3400     else if (vnp->data.intvalue & ORGANISM_ID_PROFILE_HAS_LOCAL)
3401 	{
3402 	  recommended_vals |= ORGANISM_ID_PROFILE_HAS_LOCAL;
3403 	}
3404 	else if (vnp->data.intvalue & ORGANISM_ID_PROFILE_HAS_GENERAL)
3405 	{
3406 	  recommended_vals |= ORGANISM_ID_PROFILE_HAS_GENERAL;
3407 	}
3408 	else if (vnp->data.intvalue & ORGANISM_ID_PROFILE_HAS_TAX_NAME)
3409 	{
3410 	  recommended_vals |= ORGANISM_ID_PROFILE_HAS_TAX_NAME;
3411 	}
3412   }
3413 
3414   if (recommended_vals & ORGANISM_ID_PROFILE_HAS_TAX_NAME)
3415   {
3416     if (!(missing_vals & ORGANISM_ID_PROFILE_HAS_TAX_NAME))
3417 	{
3418 	  recommended_vals = ORGANISM_ID_PROFILE_HAS_TAX_NAME;
3419 	}
3420   }
3421   else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_GENERAL)
3422   {
3423     if (!(missing_vals & ORGANISM_ID_PROFILE_HAS_GENERAL))
3424 	{
3425 	  recommended_vals = ORGANISM_ID_PROFILE_HAS_GENERAL;
3426 	}
3427   }
3428   else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_LOCAL)
3429   {
3430     if (!(missing_vals & ORGANISM_ID_PROFILE_HAS_LOCAL))
3431 	{
3432 	  recommended_vals = ORGANISM_ID_PROFILE_HAS_LOCAL;
3433 	}
3434   }
3435 
3436   if (available != NULL)
3437   {
3438     *available = has_vals;
3439   }
3440 
3441   if (recommended != NULL)
3442   {
3443     *recommended = recommended_vals;
3444   }
3445 }
3446 
3447 typedef struct exportmodform
3448 {
3449   FEATURE_FORM_BLOCK
3450 
3451   DialoG selected_mods;
3452   ButtoN list_tax_name;
3453   ButtoN list_accession;
3454   ButtoN list_local;
3455   ButtoN list_general;
3456   ButtoN list_additional_mods;
3457   ButtoN launch_excel;
3458   ButtoN accept_btn;
3459 } ExportModFormData, PNTR ExportModFormPtr;
3460 
SetExportFormModsAccept(Pointer userdata)3461 static void SetExportFormModsAccept (Pointer userdata)
3462 {
3463   ExportModFormPtr form_data;
3464   ValNodePtr       selected_mods;
3465 
3466   form_data = (ExportModFormPtr) userdata;
3467   if (form_data == NULL) return;
3468 
3469   if (GetStatus (form_data->list_additional_mods))
3470   {
3471     Enable (form_data->selected_mods);
3472     selected_mods = (ValNodePtr) DialogToPointer (form_data->selected_mods);
3473     if (selected_mods == NULL)
3474     {
3475       Disable (form_data->accept_btn);
3476       return;
3477     }
3478     else
3479     {
3480 	    selected_mods = ValNodeFreeData (selected_mods);
3481     }
3482   }
3483   else
3484   {
3485     Disable (form_data->selected_mods);
3486   }
3487 
3488 	if (!GetStatus (form_data->list_tax_name) && ! GetStatus (form_data->list_accession)
3489 		&& !GetStatus (form_data->list_local) && ! GetStatus (form_data->list_general))
3490 	{
3491     Disable (form_data->accept_btn);
3492 	}
3493 	else
3494 	{
3495 	  Enable (form_data->accept_btn);
3496 	}
3497 }
3498 
SetExportFormModsAcceptBtn(ButtoN b)3499 static void SetExportFormModsAcceptBtn (ButtoN b)
3500 {
3501   SetExportFormModsAccept (GetObjectExtra (b));
3502 }
3503 
SelectModifiersForExport(ExportOrgTablePtr eotp)3504 static Boolean SelectModifiersForExport (ExportOrgTablePtr eotp)
3505 {
3506   Int4                  idx;
3507   ValNodePtr            available_mods_list = NULL, vnp;
3508   ModalAcceptCancelData acd;
3509   ExportModFormPtr      form_data;
3510   WindoW                w;
3511   GrouP                 h, g, c;
3512   ButtoN                b;
3513   ValNodePtr            selected_mods = NULL;
3514   Boolean               found_mod;
3515   Int4                  has_vals = 0, recommended_vals = 0;
3516 
3517   if (eotp == NULL)
3518   {
3519     return FALSE;
3520   }
3521 
3522   for (idx = 0; idx < NumDefLineModifiers (); idx++)
3523   {
3524     if (eotp->modList[idx].any_present)
3525     {
3526       ValNodeAddPointer (&available_mods_list, idx, StringSave (DefLineModifiers [idx].name));
3527     }
3528   }
3529 
3530   GetOrganismIDProfileSummary (eotp->organism_id_profile, &has_vals, &recommended_vals);
3531 
3532   form_data = (ExportModFormPtr) MemNew (sizeof (ExportModFormData));
3533 
3534   w = FixedWindow (-50, -33, -10, -10, "Choose Modifiers for Export", StdCloseWindowProc);
3535   SetObjectExtra (w, form_data, StdCleanupFormProc);
3536   form_data->form = (ForM) w;
3537 
3538   h = HiddenGroup (w, -1, 0, NULL);
3539   SetGroupSpacing (h, 10, 10);
3540 
3541   g = HiddenGroup (h, 0, 5, NULL);
3542   form_data->list_tax_name = CheckBox (g, "Tax Name", SetExportFormModsAcceptBtn);
3543   SetObjectExtra (form_data->list_tax_name, form_data, NULL);
3544   if (!(has_vals & ORGANISM_ID_PROFILE_HAS_TAX_NAME))
3545   {
3546     Disable (form_data->list_tax_name);
3547   }
3548   else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_TAX_NAME)
3549   {
3550     SetStatus (form_data->list_tax_name, TRUE);
3551   }
3552   form_data->list_accession = CheckBox (g, "Accession", SetExportFormModsAcceptBtn);
3553   SetObjectExtra (form_data->list_accession, form_data, NULL);
3554   if (!(has_vals & ORGANISM_ID_PROFILE_HAS_ACCESSION))
3555   {
3556     Disable (form_data->list_accession);
3557   }
3558   else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_ACCESSION)
3559   {
3560     SetStatus (form_data->list_accession, TRUE);
3561   }
3562   form_data->list_local = CheckBox (g, "Local ID", SetExportFormModsAcceptBtn);
3563   SetObjectExtra (form_data->list_local, form_data, NULL);
3564   if (!(has_vals & ORGANISM_ID_PROFILE_HAS_LOCAL))
3565   {
3566     Disable (form_data->list_local);
3567   }
3568   else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_LOCAL)
3569   {
3570     SetStatus (form_data->list_local, TRUE);
3571   }
3572   form_data->list_general = CheckBox (g, "General ID", SetExportFormModsAcceptBtn);
3573   SetObjectExtra (form_data->list_general, form_data, NULL);
3574   if (!(has_vals & ORGANISM_ID_PROFILE_HAS_GENERAL))
3575   {
3576     Disable (form_data->list_general);
3577   }
3578   else if (recommended_vals & ORGANISM_ID_PROFILE_HAS_GENERAL)
3579   {
3580     SetStatus (form_data->list_general, TRUE);
3581   }
3582 
3583   form_data->list_additional_mods = CheckBox (g, "Additional Modifiers", SetExportFormModsAcceptBtn);
3584   SetObjectExtra (form_data->list_additional_mods, form_data, NULL);
3585   SetStatus (form_data->list_additional_mods, TRUE);
3586 
3587   form_data->selected_mods = ValNodeSelectionDialog (h, available_mods_list, TALL_SELECTION_LIST,
3588                                 ValNodeStringName,
3589                                 ValNodeSimpleDataFree,
3590                                 ValNodeStringCopy,
3591                                 ValNodeStringMatch,
3592                                 "qualifiers",
3593                                 SetExportFormModsAccept, form_data,
3594                                 TRUE);
3595 
3596   /* initialize dialog to "All" */
3597   SendMessageToDialog (form_data->selected_mods, NUM_VIB_MSG + 1);
3598 
3599 #ifdef WIN_MSWIN
3600   form_data->launch_excel = CheckBox (h, "Launch Excel", NULL);
3601 #endif
3602 
3603   c = HiddenGroup (h, 2, 0, NULL);
3604   form_data->accept_btn = PushButton (c, "Accept", ModalAcceptButton);
3605   SetObjectExtra (form_data->accept_btn, &acd, NULL);
3606   b = PushButton (c, "Cancel", ModalCancelButton);
3607   SetObjectExtra (b, &acd, NULL);
3608   AlignObjects (ALIGN_CENTER, (HANDLE) form_data->selected_mods, (HANDLE) g, (HANDLE) c, NULL);
3609 
3610   SetExportFormModsAccept (form_data);
3611 
3612   Show (w);
3613   Select (w);
3614   acd.accepted = FALSE;
3615   acd.cancelled = FALSE;
3616   while (!acd.accepted && ! acd.cancelled)
3617   {
3618     ProcessExternalEvent ();
3619     Update ();
3620   }
3621   ProcessAnEvent ();
3622 
3623   Remove (w);
3624   if (acd.cancelled)
3625   {
3626     return FALSE;
3627   }
3628   else
3629   {
3630     if (GetStatus (form_data->list_additional_mods))
3631     {
3632       selected_mods = (ValNodePtr) DialogToPointer (form_data->selected_mods);
3633     }
3634     else
3635     {
3636       selected_mods = NULL;
3637     }
3638 
3639     for (idx = 0; idx < NumDefLineModifiers (); idx++)
3640     {
3641       if (eotp->modList[idx].any_present)
3642       {
3643         found_mod = FALSE;
3644    	    for (vnp = selected_mods; vnp != NULL && ! found_mod; vnp = vnp->next)
3645         {
3646           if (StringCmp (vnp->data.ptrvalue, DefLineModifiers [idx].name) == 0)
3647           {
3648             found_mod = TRUE;
3649           }
3650         }
3651         if (!found_mod)
3652         {
3653           eotp->modList[idx].any_present = FALSE;
3654         }
3655       }
3656     }
3657     selected_mods = ValNodeFreeData (selected_mods);
3658 
3659     eotp->list_tax_name = GetStatus (form_data->list_tax_name);
3660     eotp->list_accession = GetStatus (form_data->list_accession);
3661     eotp->list_local = GetStatus (form_data->list_local);
3662     eotp->list_general = GetStatus (form_data->list_general);
3663 #ifdef WIN_MSWIN
3664     eotp->launch_excel = GetStatus (form_data->launch_excel);
3665 #endif
3666 
3667     return TRUE;
3668   }
3669 }
3670 
ExportOrganismTable(IteM i)3671 extern void ExportOrganismTable (IteM i)
3672 {
3673   BaseFormPtr        bfp;
3674   SeqEntryPtr        sep;
3675   ExportOrgTableData eotd;
3676   Char               path [PATH_MAX];
3677   Int4               idx;
3678   Char               lead_str[2];
3679 
3680 #ifdef WIN_MAC
3681   bfp = currentFormDataPtr;
3682 #else
3683   bfp = GetObjectExtra (i);
3684 #endif
3685   if (bfp == NULL) return;
3686 
3687   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3688   if (sep == NULL) return;
3689 
3690   MemSet (&eotd, 0, sizeof (ExportOrgTableData));
3691   eotd.modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
3692   if (eotd.modList == NULL) return;
3693 
3694   CountModifiers (eotd.modList, sep);
3695 
3696   eotd.organism_id_profile = NULL;
3697   GetOrganismIDProfile (sep, &eotd);
3698 
3699   if (SelectModifiersForExport (&eotd))
3700   {
3701     if (GetOutputFileName (path, sizeof (path), NULL))
3702     {
3703       eotd.fp = FileOpen (path, "w");
3704       if (eotd.fp == NULL)
3705       {
3706         Message (MSG_ERROR, "Unable to open %s", path);
3707       }
3708 	    else
3709 	    {
3710 	      lead_str [0] = 0;
3711 		    lead_str [1] = 0;
3712         /* print a header line */
3713 	      if (eotd.list_accession)
3714 		    {
3715 		      fprintf (eotd.fp, "Accession Number");
3716 		      lead_str [0] = '\t';
3717 		    }
3718 		    if (eotd.list_local)
3719 		    {
3720   	          fprintf (eotd.fp, "%sLocal ID", lead_str);
3721 		      lead_str [0] = '\t';
3722 		    }
3723         if (eotd.list_general)
3724 		    {
3725 		      fprintf (eotd.fp, "%sGeneral ID", lead_str);
3726 		      lead_str [0] = '\t';
3727 		    }
3728 		    if (eotd.list_tax_name)
3729 		    {
3730 		      fprintf (eotd.fp, "%sTax Name", lead_str);
3731 		      lead_str [0] = '\t';
3732 		    }
3733 
3734         for (idx = 0; idx < NumDefLineModifiers (); idx++)
3735         {
3736           if (eotd.modList[idx].any_present)
3737           {
3738             fprintf (eotd.fp, "%s%s", lead_str, DefLineModifiers [idx].name);
3739             lead_str [0] = '\t';
3740           }
3741         }
3742         fprintf (eotd.fp, "\n");
3743 
3744         ExportOrganisms  (sep, &eotd);
3745         FileClose (eotd.fp);
3746 #ifdef WIN_MSWIN
3747         if (eotd.launch_excel) {
3748           Nlm_MSWin_OpenApplication ("excel.exe", path);
3749         }
3750 #endif
3751 	    }
3752 	  }
3753   }
3754   for (idx=0; idx < NumDefLineModifiers (); idx++)
3755   {
3756     ValNodeFree (eotd.modList[idx].values_seen);
3757   }
3758   eotd.modList = MemFree (eotd.modList);
3759   eotd.organism_id_profile = ValNodeFree (eotd.organism_id_profile);
3760 }
3761 
3762 
3763 typedef struct qualifierselect {
3764   LisT gene_quals;
3765   LisT cds_quals;
3766   LisT import_quals;
3767 } QualifierSelectData, PNTR QualifierSelectPtr;
3768 
3769 typedef struct featurequalloadformdata {
3770   FEATURE_FORM_BLOCK
3771 
3772   ValNodePtr             line_list;
3773   ValNodePtr             featlist;
3774   Int4                   num_feats;
3775   Uint2                  entityID;
3776   LisT                   feature_type;
3777   QualifierSelectData    match_qual;
3778   QualifierSelectData    apply_qual;
3779   PopuP                  sequence_id_type;
3780   PopuP                  sequence_column;
3781   PopuP                  feature_column;
3782   PopuP                  apply_column;
3783   GrouP                  seq_group;
3784   GrouP                  match_group;
3785   GrouP                  apply_group;
3786   Boolean                asked_about_replace;
3787   Boolean                do_replace;
3788   Boolean                use_semicolon;
3789   ButtoN                 replace_with_blank_btn;
3790   Boolean                replace_with_blank;
3791   ButtoN                 accept_button;
3792 } FeatureQualLoadFormData, PNTR FeatureQualLoadFormPtr;
3793 
CleanupFeatureQualLoadForm(GraphiC g,VoidPtr data)3794 static void CleanupFeatureQualLoadForm (
3795   GraphiC g,
3796   VoidPtr data
3797 )
3798 {
3799   FeatureQualLoadFormPtr form_data;
3800 
3801   form_data = (FeatureQualLoadFormPtr)data;
3802   if (form_data == NULL) return;
3803   CleanUpTableData (form_data->line_list);
3804   StdCleanupFormProc (g, data);
3805 }
3806 
3807 typedef struct qualifierlistdata {
3808   CharPtr item_name;
3809 } QualifierListData, PNTR QualifierListPtr;
3810 
GetSubtypeFromOffsetInFeatureList(Int4 list_offset,ValNodePtr list)3811 static Int4 GetSubtypeFromOffsetInFeatureList (Int4 list_offset,
3812                                                ValNodePtr list)
3813 {
3814   ValNodePtr vnp;
3815 
3816   if (list == NULL || list_offset < 1) return -1;
3817 
3818   vnp = list;
3819   while (vnp != NULL && list_offset > 1)
3820   {
3821     list_offset --;
3822     vnp = vnp->next;
3823   }
3824   if (list_offset > 1) return -1;
3825   if (vnp == NULL) return -1;
3826   return vnp->choice;
3827 }
3828 
ShowQualifierListBySubtype(QualifierSelectPtr qsp,Int4 feature_subtype)3829 static void ShowQualifierListBySubtype (QualifierSelectPtr qsp, Int4 feature_subtype)
3830 {
3831   if (feature_subtype == -1) {
3832     Hide (qsp->gene_quals);
3833     Hide (qsp->cds_quals);
3834     Hide (qsp->import_quals);
3835   } else if (feature_subtype == FEATDEF_GENE) {
3836     Show (qsp->gene_quals);
3837     Hide (qsp->cds_quals);
3838     Hide (qsp->import_quals);
3839   } else if (feature_subtype == FEATDEF_CDS) {
3840     Hide (qsp->gene_quals);
3841     Show (qsp->cds_quals);
3842     Hide (qsp->import_quals);
3843   } else {
3844     Hide (qsp->gene_quals);
3845     Hide (qsp->cds_quals);
3846     Show (qsp->import_quals);
3847   }
3848 }
3849 
ShowQualifierLists(FeatureQualLoadFormPtr form_data)3850 static void ShowQualifierLists (FeatureQualLoadFormPtr form_data)
3851 {
3852   Int4 feature_offset, feature_subtype;
3853 
3854   if (form_data == NULL) return;
3855 
3856   feature_offset = GetValue (form_data->feature_type);
3857   feature_subtype = GetSubtypeFromOffsetInFeatureList (feature_offset,
3858                                                        form_data->featlist);
3859   ShowQualifierListBySubtype (&(form_data->match_qual), feature_subtype);
3860   ShowQualifierListBySubtype (&(form_data->apply_qual), feature_subtype);
3861 }
3862 
3863 static QualifierListData GeneTableQualifiers [] = {
3864   { "allele"},
3865   { "locus" },
3866   { "locus_tag"},
3867   { "description"},
3868   { "product"}
3869 };
3870 
3871 #define NUM_GENE_TABLE_QUALIFIERS 5
3872 
3873 static QualifierListData ProtTableQualifiers [] = {
3874   { "product"},
3875   { "description"},
3876   { "comment"}
3877 };
3878 
3879 #define NUM_PROT_TABLE_QUALIFIERS 3
3880 
3881 /* check the appropriate list box for qualifier type,
3882  * keeping in mind that the first item is always "none"
3883  */
GetQualSelectBySubtype(QualifierSelectPtr qsp,Int4 feature_subtype)3884 static Int4 GetQualSelectBySubtype (QualifierSelectPtr qsp, Int4 feature_subtype)
3885 {
3886   Int4 qual_choice = -1;
3887 
3888   if (feature_subtype == -1) {
3889     qual_choice = -1;
3890   } else if (feature_subtype == FEATDEF_GENE) {
3891     qual_choice = GetValue (qsp->gene_quals);
3892     if (qual_choice < 2
3893       || qual_choice > NUM_GENE_TABLE_QUALIFIERS + 2) {
3894       qual_choice = -1;
3895     } else {
3896       qual_choice = qual_choice - 1;
3897     }
3898   } else if (feature_subtype == FEATDEF_CDS) {
3899     qual_choice = GetValue (qsp->cds_quals);
3900     if (qual_choice < 2
3901       || qual_choice > NUM_PROT_TABLE_QUALIFIERS + 2) {
3902       qual_choice = -1;
3903     } else {
3904       qual_choice = qual_choice - 1;
3905     }
3906   } else {
3907     qual_choice = GetValue (qsp->import_quals);
3908     if (qual_choice < 2
3909       || qual_choice > ParFlat_TOTAL_GBQUAL + 2) {
3910       qual_choice = -1;
3911     } else {
3912       qual_choice = qual_choice - 1;
3913     }
3914   }
3915   return qual_choice;
3916 
3917 }
3918 
SetFeatureQualAcceptButton(Handle a)3919 static void SetFeatureQualAcceptButton (Handle a)
3920 {
3921   FeatureQualLoadFormPtr form_data;
3922   Boolean                have_feature_select_column;
3923   Boolean                have_feature_qual_select_column;
3924   Int4                   feature_select_choice;
3925   Int4                   apply_qual_choice;
3926   Int4                   match_qual_choice;
3927   Int4                   feature_subtype;
3928   Boolean                seqid_select_ok;
3929   Int4                   seqid_select_type;
3930   Int4                   seqid_select_column;
3931 
3932   form_data = GetObjectExtra (a);
3933   if (form_data == NULL) return;
3934 
3935   ShowQualifierLists (form_data);
3936   have_feature_qual_select_column = FALSE;
3937   have_feature_select_column = FALSE;
3938   seqid_select_ok = FALSE;
3939 
3940   feature_select_choice = GetValue (form_data->feature_type);
3941   if ( feature_select_choice > 0 && feature_select_choice < form_data->num_feats)
3942   {
3943     have_feature_select_column = TRUE;
3944   }
3945 
3946   feature_subtype = GetSubtypeFromOffsetInFeatureList (feature_select_choice,
3947                                                        form_data->featlist);
3948 
3949   apply_qual_choice = GetQualSelectBySubtype (&(form_data->apply_qual),
3950                                               feature_subtype);
3951   if (apply_qual_choice != -1)
3952   {
3953     have_feature_qual_select_column = TRUE;
3954   }
3955 
3956   /* if a column is selected for a sequence identifier, must select type */
3957   /* if a column is not selected for a sequence identifier, must not select type */
3958   seqid_select_type = GetValue (form_data->sequence_id_type);
3959   seqid_select_column = GetValue (form_data->sequence_column);
3960   if (seqid_select_type == 1 || seqid_select_type == 2) {
3961     if (seqid_select_column > 0) {
3962       seqid_select_ok = TRUE;
3963     }
3964   } else {
3965     seqid_select_ok = TRUE;
3966   }
3967 
3968   /* if the feature column is not specified, must not have match qualifier */
3969   /* and must have sequence ID */
3970   /* if the feature column is specified, must have match qualifier */
3971   match_qual_choice = GetQualSelectBySubtype (&(form_data->match_qual),
3972                                               feature_subtype);
3973   if (GetValue (form_data->feature_column) < 1)
3974   {
3975     if (match_qual_choice != -1)
3976     {
3977       have_feature_select_column = FALSE;
3978     }
3979     else if (seqid_select_column < 1)
3980     {
3981       have_feature_select_column = FALSE;
3982     }
3983   } else {
3984     if (match_qual_choice == -1)
3985     {
3986       have_feature_select_column = FALSE;
3987     }
3988   }
3989 
3990   if (GetValue (form_data->apply_column) < 1) {
3991     have_feature_qual_select_column = FALSE;
3992   }
3993 
3994   if ( have_feature_select_column && have_feature_qual_select_column
3995     && seqid_select_ok)
3996   {
3997     Enable (form_data->accept_button);
3998   }
3999   else
4000   {
4001     Disable (form_data->accept_button);
4002   }
4003 }
4004 
ProductNameMatches(SeqLocPtr slp,BioseqPtr bsp,CharPtr pString)4005 static Boolean ProductNameMatches (
4006   SeqLocPtr slp,
4007   BioseqPtr  bsp,
4008   CharPtr   pString
4009 )
4010 {
4011   SeqFeatPtr        sfp;
4012   SeqMgrFeatContext fcontext;
4013 
4014   if (slp == NULL || bsp == NULL || pString == NULL) return FALSE;
4015 
4016   sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &fcontext);
4017   while (sfp != NULL)
4018   {
4019     if ( IsLocAInBonSameStrand (sfp->location, slp)
4020       && StringStr ( fcontext.label, pString) != NULL)
4021     {
4022       return TRUE;
4023     }
4024     sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &fcontext);
4025   }
4026   return FALSE;
4027 }
4028 
GeneHasThisQualifier(SeqFeatPtr sfp,Uint2 entityID,CharPtr pString,Int2 popup_offset)4029 static Boolean GeneHasThisQualifier (
4030   SeqFeatPtr sfp,
4031   Uint2      entityID,
4032   CharPtr    pString,
4033   Int2       popup_offset
4034 )
4035 {
4036   BioseqPtr  bsp;
4037   GeneRefPtr grp;
4038 
4039   if (sfp == NULL || pString == NULL) return FALSE;
4040   if (popup_offset < 1 || popup_offset > NUM_GENE_TABLE_QUALIFIERS) return FALSE;
4041 
4042   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
4043   if (grp == NULL) return FALSE;
4044 
4045   if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "allele") == 0) {
4046     if (StringCmp (pString, grp->allele) == 0) {
4047       return TRUE;
4048     } else {
4049       return FALSE;
4050     }
4051   } else if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "locus") == 0) {
4052     if (StringCmp (pString, grp->locus) == 0) {
4053       return TRUE;
4054     } else {
4055       return FALSE;
4056     }
4057   } else if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "locus_tag") == 0) {
4058     if (StringCmp (pString, grp->locus_tag) == 0) {
4059       return TRUE;
4060     } else {
4061       return FALSE;
4062     }
4063   } else if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "description") == 0) {
4064     if (StringCmp (pString, grp->desc) == 0) {
4065       return TRUE;
4066     } else {
4067       return FALSE;
4068     }
4069   } else if ( StringCmp (GeneTableQualifiers [popup_offset - 1].item_name, "product") == 0)
4070   {
4071     bsp = GetBioseqGivenSeqLoc (sfp->location, entityID);
4072     return ProductNameMatches (sfp->location, bsp, pString);
4073   }
4074   return FALSE;
4075 }
4076 
ProteinHasThisQualifier(SeqFeatPtr sfp,CharPtr pString,Int2 popup_offset)4077 static Boolean ProteinHasThisQualifier (
4078   SeqFeatPtr sfp,
4079   CharPtr    pString,
4080   Int2       popup_offset
4081 )
4082 {
4083   ProtRefPtr prp;
4084 
4085   if (sfp == NULL || sfp->data.choice != SEQFEAT_PROT || pString == NULL
4086     || popup_offset < 1 || popup_offset > NUM_PROT_TABLE_QUALIFIERS)
4087   {
4088     return FALSE;
4089   }
4090 
4091   prp = sfp->data.value.ptrvalue;
4092   if (prp == NULL) return FALSE;
4093 
4094   if (StringCmp (ProtTableQualifiers [ popup_offset - 1].item_name, "product") == 0)
4095   {
4096     if (prp->name != NULL
4097       && StringStr (prp->name->data.ptrvalue, pString) != NULL)
4098     {
4099       return TRUE;
4100     }
4101   } else if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "description") == 0) {
4102     if (StringStr (prp->desc, pString) != NULL)
4103     {
4104       return TRUE;
4105     }
4106   } else if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "comment") == 0) {
4107     if (StringStr (sfp->comment, pString) != NULL)
4108     {
4109       return TRUE;
4110     }
4111   }
4112   return FALSE;
4113 }
4114 
CDSHasThisQualifier(SeqFeatPtr sfp,Uint2 entityID,CharPtr pString,Int2 popup_offset)4115 static Boolean CDSHasThisQualifier (
4116   SeqFeatPtr sfp,
4117   Uint2      entityID,
4118   CharPtr    pString,
4119   Int2       popup_offset
4120 )
4121 {
4122   SeqFeatPtr protein;
4123 
4124   if (sfp == NULL || pString == NULL) return FALSE;
4125 
4126   if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "comment") == 0) {
4127     if (StringStr (sfp->comment, pString) != NULL)
4128     {
4129       return TRUE;
4130     }
4131   }
4132   else
4133   {
4134     protein = FindBestProtein (entityID, sfp->product);
4135     if (protein == NULL) return FALSE;
4136     return ProteinHasThisQualifier (protein, pString, popup_offset);
4137   }
4138   return FALSE;
4139 }
4140 
FeatureHasThisQualifier(SeqFeatPtr sfp,Uint2 entityID,CharPtr pString,Int2 popup_offset)4141 static Boolean FeatureHasThisQualifier (
4142   SeqFeatPtr sfp,
4143   Uint2      entityID,
4144   CharPtr    pString,
4145   Int2       popup_offset
4146 )
4147 {
4148   Int2      qualval;
4149   GBQualPtr gbqual;
4150 
4151   if (popup_offset < 1) return FALSE;
4152   if (sfp == NULL || pString == NULL) return FALSE;
4153 
4154   if (sfp->idx.subtype == FEATDEF_GENE)
4155   {
4156     return GeneHasThisQualifier (sfp, entityID, pString, popup_offset);
4157   }
4158   else if (sfp->idx.subtype == FEATDEF_CDS)
4159   {
4160     return CDSHasThisQualifier (sfp, entityID, pString, popup_offset);
4161   }
4162   else
4163   {
4164     for (gbqual = sfp->qual; gbqual != NULL; gbqual = gbqual->next)
4165     {
4166       qualval = GBQualNameValid (gbqual->qual);
4167       if (qualval > -1 && qualval == popup_offset -1)
4168       {
4169         return TRUE;
4170       }
4171     }
4172   }
4173   return FALSE;
4174 }
4175 
GetDataForColumnOffset(ValNodePtr column_data,Int4 offset)4176 static CharPtr GetDataForColumnOffset (ValNodePtr column_data, Int4 offset)
4177 {
4178   ValNodePtr vnp;
4179 
4180   for (vnp = column_data; vnp != NULL && offset > 1; vnp = vnp->next)
4181   {
4182     offset --;
4183   }
4184   if (offset > 1 || vnp == NULL) {
4185     return NULL;
4186   } else {
4187     return vnp->data.ptrvalue;
4188   }
4189 }
4190 
ApplyQualToThisFeature(SeqFeatPtr sfp,ValNodePtr parts,FeatureQualLoadFormPtr form_data)4191 static Boolean ApplyQualToThisFeature (
4192   SeqFeatPtr sfp,
4193   ValNodePtr parts,
4194   FeatureQualLoadFormPtr form_data
4195 )
4196 {
4197   Int4       column_index;
4198   CharPtr    val;
4199   Int4       subtype;
4200   Int4       popup_offset;
4201 
4202   if (sfp == NULL || parts == NULL || form_data == NULL) return FALSE;
4203 
4204   column_index = GetValue (form_data->feature_column);
4205   subtype = GetSubtypeFromOffsetInFeatureList (
4206                      GetValue (form_data->feature_type), form_data->featlist);
4207   val = GetDataForColumnOffset (parts, column_index);
4208 
4209   if (val != NULL && sfp->idx.subtype == subtype)
4210   {
4211     popup_offset = GetQualSelectBySubtype (&(form_data->match_qual),
4212                                               subtype);
4213     if (popup_offset < 1
4214       || FeatureHasThisQualifier (sfp, form_data->entityID, val, popup_offset))
4215     {
4216       return TRUE;
4217     }
4218   }
4219   return FALSE;
4220 }
4221 
4222 typedef struct featurequaltabledata {
4223   ValNodePtr parts;
4224   FeatureQualLoadFormPtr form_data;
4225 } FeatureQualTableData, PNTR FeatureQualTablePtr;
4226 
ApplyOneQualToProt(SeqFeatPtr sfp,Int2 popup_offset,CharPtr pString,Boolean PNTR asked_about_replace,Boolean PNTR do_replace,Boolean PNTR use_semicolon)4227 static void ApplyOneQualToProt (
4228   SeqFeatPtr sfp,
4229   Int2       popup_offset,
4230   CharPtr    pString,
4231   Boolean PNTR asked_about_replace,
4232   Boolean PNTR do_replace,
4233   Boolean PNTR use_semicolon)
4234 {
4235   ProtRefPtr prp;
4236   CharPtr    cp;
4237 
4238   if (sfp == NULL || sfp->data.choice != SEQFEAT_PROT || pString == NULL
4239     || popup_offset < 1 || popup_offset > NUM_PROT_TABLE_QUALIFIERS
4240     || asked_about_replace == NULL
4241     || do_replace == NULL
4242     || use_semicolon == NULL)
4243   {
4244     return;
4245   }
4246 
4247   prp = sfp->data.value.ptrvalue;
4248   if (prp == NULL) return;
4249 
4250   if (StringCmp (ProtTableQualifiers [ popup_offset - 1].item_name, "product") == 0)
4251   {
4252     if (prp->name == NULL)
4253     {
4254       ValNodeAddStr (&prp->name, 0, StringSave (pString));
4255     }
4256     else
4257     {
4258       cp = prp->name->data.ptrvalue;
4259       AppendOrReplaceString (&cp, pString,
4260                             asked_about_replace, do_replace, use_semicolon);
4261       prp->name->data.ptrvalue = cp;
4262     }
4263   } else if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "description") == 0) {
4264     AppendOrReplaceString (&(prp->desc), pString,
4265                             asked_about_replace, do_replace, use_semicolon);
4266   } else if (StringCmp (ProtTableQualifiers [popup_offset - 1].item_name, "comment") == 0) {
4267     AppendOrReplaceString (&(sfp->comment), pString,
4268                             asked_about_replace, do_replace, use_semicolon);
4269   }
4270 }
4271 
ApplyOneQualToCDS(SeqFeatPtr sfp,Uint2 entityID,Int2 feat_qual_choice,CharPtr pString,Boolean PNTR asked_about_replace,Boolean PNTR do_replace,Boolean PNTR use_semicolon)4272 static void ApplyOneQualToCDS (
4273   SeqFeatPtr sfp,
4274   Uint2      entityID,
4275   Int2       feat_qual_choice,
4276   CharPtr    pString,
4277   Boolean PNTR asked_about_replace,
4278   Boolean PNTR do_replace,
4279   Boolean PNTR use_semicolon)
4280 {
4281   SeqFeatPtr protein;
4282 
4283   if (sfp == NULL || pString == NULL
4284     || asked_about_replace == NULL
4285     || do_replace == NULL
4286     || use_semicolon == NULL)
4287   {
4288     return;
4289   }
4290 
4291   if (StringCmp (ProtTableQualifiers [feat_qual_choice - 1].item_name, "comment") == 0) {
4292     AppendOrReplaceString (&(sfp->comment), pString,
4293                             asked_about_replace, do_replace, use_semicolon);
4294   }
4295   else
4296   {
4297     protein = FindBestProtein (entityID, sfp->product);
4298     if (protein == NULL) return;
4299     ApplyOneQualToProt (protein, feat_qual_choice, pString,
4300                             asked_about_replace, do_replace, use_semicolon);
4301   }
4302 }
4303 
ApplyGeneProductName(SeqLocPtr slp,Uint2 entityID,CharPtr pString,Boolean PNTR asked_about_replace,Boolean PNTR do_replace,Boolean PNTR use_semicolon)4304 static void ApplyGeneProductName (
4305   SeqLocPtr slp,
4306   Uint2     entityID,
4307   CharPtr   pString,
4308   Boolean PNTR asked_about_replace,
4309   Boolean PNTR do_replace,
4310   Boolean PNTR use_semicolon)
4311 {
4312   SeqFeatPtr        sfp;
4313   SeqMgrFeatContext fcontext;
4314   Int4              prot_popup_offset;
4315   BioseqPtr         bsp;
4316 
4317   if (slp == NULL || pString == NULL
4318     || asked_about_replace == NULL
4319     || do_replace == NULL
4320     || use_semicolon == NULL)
4321   {
4322     return;
4323   }
4324 
4325   bsp = GetBioseqGivenSeqLoc (slp, entityID);
4326   if (bsp == NULL) return;
4327 
4328   for (prot_popup_offset = 0;
4329        prot_popup_offset < NUM_PROT_TABLE_QUALIFIERS
4330          && StringCmp (ProtTableQualifiers [prot_popup_offset].item_name, "product") != 0;
4331        prot_popup_offset ++)
4332   {}
4333   if (prot_popup_offset >= NUM_PROT_TABLE_QUALIFIERS) return;
4334 
4335   sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &fcontext);
4336   while (sfp != NULL)
4337   {
4338     if ( IsLocAInBonSameStrand (sfp->location, slp))
4339     {
4340       ApplyOneQualToCDS (sfp, entityID, prot_popup_offset + 1, pString,
4341                             asked_about_replace, do_replace, use_semicolon);
4342     }
4343     sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &fcontext);
4344   }
4345 }
4346 
ApplyOneQualToGene(SeqFeatPtr sfp,Uint2 entityID,Int2 feat_qual_choice,CharPtr pString,Boolean PNTR asked_about_replace,Boolean PNTR do_replace,Boolean PNTR use_semicolon)4347 static void ApplyOneQualToGene (
4348   SeqFeatPtr sfp,
4349   Uint2      entityID,
4350   Int2       feat_qual_choice,
4351   CharPtr    pString,
4352   Boolean PNTR asked_about_replace,
4353   Boolean PNTR do_replace,
4354   Boolean PNTR use_semicolon)
4355 {
4356   GeneRefPtr grp;
4357 
4358   if (sfp == NULL
4359     || sfp->idx.subtype != FEATDEF_GENE
4360     || feat_qual_choice < 1
4361     || feat_qual_choice > NUM_GENE_TABLE_QUALIFIERS
4362     || pString == NULL
4363     || asked_about_replace == NULL
4364     || do_replace == NULL
4365     || use_semicolon == NULL)
4366   {
4367     return;
4368   }
4369 
4370   grp = (GeneRefPtr) sfp->data.value.ptrvalue;
4371   if (grp == NULL) return;
4372 
4373   if (StringCmp ( GeneTableQualifiers [feat_qual_choice - 1].item_name,
4374                  "allele") == 0) {
4375     AppendOrReplaceString (&(grp->allele), pString,
4376                             asked_about_replace, do_replace, use_semicolon);
4377   } else if (StringCmp ( GeneTableQualifiers [feat_qual_choice - 1].item_name,
4378                         "locus") == 0) {
4379     AppendOrReplaceString (&(grp->locus), pString,
4380                             asked_about_replace, do_replace, use_semicolon);
4381   } else if (StringCmp ( GeneTableQualifiers [feat_qual_choice - 1].item_name,
4382                         "locus_tag") == 0) {
4383     AppendOrReplaceString (&(grp->locus_tag), pString,
4384                             asked_about_replace, do_replace, use_semicolon);
4385   } else if (StringCmp ( GeneTableQualifiers [feat_qual_choice - 1].item_name,
4386                         "description") == 0) {
4387     AppendOrReplaceString (&(grp->desc), pString,
4388                             asked_about_replace, do_replace, use_semicolon);
4389   } else if (StringCmp (GeneTableQualifiers [feat_qual_choice - 1].item_name,
4390                         "product") == 0) {
4391     ApplyGeneProductName (sfp->location, entityID, pString,
4392                             asked_about_replace, do_replace, use_semicolon);
4393   }
4394 }
4395 
ApplyOneQualToImportFeature(SeqFeatPtr sfp,Int2 feat_qual_choice,CharPtr pString,Boolean PNTR asked_about_replace,Boolean PNTR do_replace,Boolean PNTR use_semicolon)4396 static void ApplyOneQualToImportFeature (
4397   SeqFeatPtr sfp,
4398   Int2 feat_qual_choice,
4399   CharPtr pString,
4400   Boolean PNTR asked_about_replace,
4401   Boolean PNTR do_replace,
4402   Boolean PNTR use_semicolon)
4403 {
4404   GBQualPtr           gbqual;
4405 
4406   if (sfp == NULL
4407     || feat_qual_choice < 1
4408     || feat_qual_choice > ParFlat_TOTAL_GBQUAL
4409     || pString == NULL
4410     || asked_about_replace == NULL
4411     || do_replace == NULL
4412     || use_semicolon == NULL)
4413   {
4414     return;
4415   }
4416 
4417   gbqual = sfp->qual;
4418   while (gbqual != NULL
4419     && StringCmp (gbqual->qual,
4420                   ParFlat_GBQual_names [feat_qual_choice - 1].name) != 0)
4421   {
4422     gbqual = gbqual->next;
4423   }
4424 
4425   if (gbqual == NULL)
4426   {
4427     gbqual = GBQualNew ();
4428     if (gbqual == NULL) return;
4429     gbqual->qual = StringSave ( ParFlat_GBQual_names [feat_qual_choice - 1].name);
4430     gbqual->val = StringSave ( pString );
4431     gbqual->next = sfp->qual;
4432     sfp->qual = gbqual;
4433   }
4434   else
4435   {
4436     AppendOrReplaceString (&(gbqual->val), pString,
4437                             asked_about_replace, do_replace, use_semicolon);
4438   }
4439 }
4440 
ApplyOneQualToFeature(SeqFeatPtr sfp,Uint2 entityID,Int2 feat_qual_choice,CharPtr pString,Boolean PNTR asked_about_replace,Boolean PNTR do_replace,Boolean PNTR use_semicolon)4441 static void ApplyOneQualToFeature (
4442   SeqFeatPtr sfp,
4443   Uint2      entityID,
4444   Int2       feat_qual_choice,
4445   CharPtr    pString,
4446   Boolean PNTR asked_about_replace,
4447   Boolean PNTR do_replace,
4448   Boolean PNTR use_semicolon)
4449 {
4450   if (sfp == NULL || pString == NULL
4451     || asked_about_replace == NULL
4452     || do_replace == NULL
4453     || use_semicolon == NULL)
4454   {
4455     return;
4456   }
4457 
4458   switch (sfp->idx.subtype)
4459   {
4460     case FEATDEF_GENE :
4461       ApplyOneQualToGene (sfp, entityID, feat_qual_choice, pString,
4462                             asked_about_replace, do_replace, use_semicolon);
4463       break;
4464     case FEATDEF_CDS :
4465       ApplyOneQualToCDS (sfp, entityID, feat_qual_choice, pString,
4466                             asked_about_replace, do_replace, use_semicolon);
4467       break;
4468     default :
4469       ApplyOneQualToImportFeature (sfp, feat_qual_choice, pString,
4470                             asked_about_replace, do_replace, use_semicolon);
4471       break;
4472   }
4473 }
4474 
GetImpFeatKeyFromSubtype(Uint2 subtype)4475 static CharPtr GetImpFeatKeyFromSubtype (Uint2 subtype)
4476 {
4477   FeatDefPtr  curr;
4478   Uint1       key;
4479   CharPtr     label;
4480 
4481   curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
4482   while (curr != NULL) {
4483     if (key == subtype)
4484     {
4485       return curr->typelabel;
4486     }
4487     curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
4488   }
4489   return NULL;
4490 }
4491 
ApplyQualsToFeaturesOnBsp(BioseqPtr bsp,FeatureQualLoadFormPtr form_data,ValNodePtr parts)4492 static void ApplyQualsToFeaturesOnBsp (BioseqPtr bsp,
4493  FeatureQualLoadFormPtr form_data,
4494  ValNodePtr             parts)
4495 {
4496   SeqFeatPtr sfp;
4497   SeqMgrFeatContext fcontext;
4498   Boolean found_feature = FALSE;
4499   Int4                subtype;
4500   Int4                column_index;
4501   Int2                qualval;
4502   Int2                matchval;
4503   CharPtr             val;
4504   ImpFeatPtr          ifp;
4505 
4506   subtype = GetSubtypeFromOffsetInFeatureList (
4507                           GetValue (form_data->feature_type),
4508                           form_data->featlist);
4509   column_index = GetValue (form_data->apply_column);
4510   val = GetDataForColumnOffset (parts, column_index);
4511   /* if the value to be applied is blank and we're not replacing with blanks, skip */
4512   if (! form_data->replace_with_blank && StringHasNoText (val)) {
4513     return;
4514   }
4515   qualval = GetQualSelectBySubtype (&(form_data->apply_qual), subtype);
4516   if (subtype == -1 || val == NULL || column_index < 1 || qualval < 1) {
4517     /* do nothing */
4518   }
4519   else
4520   {
4521     sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
4522     while (sfp != NULL)
4523     {
4524       if ( ApplyQualToThisFeature (sfp, parts, form_data))
4525       {
4526         found_feature = TRUE;
4527         ApplyOneQualToFeature (sfp, form_data->entityID, qualval, val,
4528                                &(form_data->asked_about_replace),
4529                                &(form_data->do_replace),
4530                                &(form_data->use_semicolon));
4531       }
4532       sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &fcontext);
4533     }
4534 
4535     /* only want to create new features if no feature matching qualifier
4536      * was specified and no feature was found */
4537     matchval = GetQualSelectBySubtype (&(form_data->match_qual), subtype);
4538 
4539     if (! found_feature && matchval == -1)
4540     {
4541       if (subtype == FEATDEF_CDS)
4542       {
4543         sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_CDREGION, NULL);
4544         if (sfp == NULL) return;
4545         sfp->data.value.ptrvalue = CdRegionNew ();
4546       } else if (subtype == FEATDEF_GENE) {
4547         sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_GENE, NULL);
4548         if (sfp == NULL) return;
4549         sfp->data.value.ptrvalue = GeneRefNew ();
4550       } else {
4551         ifp = ImpFeatNew ();
4552         if (ifp == NULL) return;
4553         sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
4554         if (sfp == NULL) return;
4555         ifp->key = StringSave ( GetImpFeatKeyFromSubtype (subtype));
4556         sfp->data.value.ptrvalue = ifp;
4557       }
4558       SeqMgrIndexFeatures (0, (Pointer) bsp);
4559       ApplyOneQualToFeature (sfp, form_data->entityID, qualval, val,
4560                                &(form_data->asked_about_replace),
4561                                &(form_data->do_replace),
4562                                &(form_data->use_semicolon));
4563     }
4564   }
4565 }
4566 
ApplyTableQuals(BioseqPtr bsp,Pointer userdata)4567 static void ApplyTableQuals (BioseqPtr bsp, Pointer userdata)
4568 {
4569   FeatureQualLoadFormPtr form_data;
4570   SeqDescrPtr            sdp;
4571   GBBlockPtr             gbp;
4572   Int4                   column_index;
4573   ValNodePtr             line;
4574   TableLinePtr           tlp;
4575   Boolean                use_local_id = FALSE;
4576   FeatureQualTableData   fqtd;
4577   Int2                   seq_match_choice;
4578   CharPtr                idval;
4579 
4580   form_data = (FeatureQualLoadFormPtr) userdata;
4581   if (form_data == NULL || bsp == NULL) return;
4582 
4583   gbp = NULL;
4584   sdp = BioseqGetSeqDescr (bsp, Seq_descr_genbank, NULL);
4585   if (sdp != NULL)
4586   {
4587     gbp = sdp->data.ptrvalue;
4588   }
4589 
4590   seq_match_choice = GetValue (form_data->sequence_id_type);
4591   if (seq_match_choice == 1) {
4592     use_local_id = FALSE;
4593   }
4594 
4595   fqtd.form_data = form_data;
4596   if (seq_match_choice == 1 || seq_match_choice == 2)
4597   {
4598     column_index = GetValue (form_data->sequence_column);
4599 
4600     for (line = form_data->line_list; line != NULL; line = line->next)
4601     {
4602       tlp = line->data.ptrvalue;
4603       if (tlp == NULL) continue;
4604       idval = GetDataForColumnOffset (tlp->parts, column_index);
4605       if (idval != NULL
4606         && ( IDListHasValue ( idval,
4607                               bsp->id, use_local_id, FALSE, FALSE)
4608           || (! use_local_id &&
4609               HasExtraAccession ( idval, gbp))))
4610       {
4611         fqtd.parts = tlp->parts;
4612         ApplyQualsToFeaturesOnBsp (bsp, form_data, tlp->parts);
4613       }
4614     }
4615   } else {
4616     for (line = form_data->line_list; line != NULL; line = line->next)
4617     {
4618       tlp = line->data.ptrvalue;
4619       if (tlp == NULL) continue;
4620       fqtd.parts = tlp->parts;
4621       ApplyQualsToFeaturesOnBsp (bsp, form_data, tlp->parts);
4622     }
4623   }
4624 }
4625 
DoAcceptFeatureQuals(ButtoN b)4626 static void DoAcceptFeatureQuals (ButtoN b)
4627 {
4628   FeatureQualLoadFormPtr form_data;
4629   SeqEntryPtr   sep;
4630 
4631   form_data = GetObjectExtra (b);
4632   if (form_data == NULL) return;
4633 
4634   form_data->replace_with_blank = GetStatus (form_data->replace_with_blank_btn);
4635 
4636   sep = GetTopSeqEntryForEntityID (form_data->entityID);
4637   if (sep == NULL) return;
4638 
4639   VisitBioseqsInSep (sep, form_data, ApplyTableQuals);
4640   Update ();
4641   ObjMgrSetDirtyFlag (form_data->entityID, TRUE);
4642   ObjMgrSendMsg (OM_MSG_UPDATE, form_data->entityID, 0, 0);
4643   Remove (form_data->form);
4644 }
4645 
BuildColumnSelector(GrouP g,FeatureQualLoadFormPtr parent_form,ValNodePtr parts)4646 static PopuP BuildColumnSelector ( GrouP g,
4647                                   FeatureQualLoadFormPtr parent_form,
4648                                   ValNodePtr parts )
4649 {
4650   PopuP      p;
4651   ValNodePtr this_part;
4652 
4653   if (g == NULL || parts == NULL) return NULL;
4654 
4655   p = PopupList (g, TRUE, (PupActnProc) SetFeatureQualAcceptButton);
4656   for (this_part = parts; this_part != NULL; this_part = this_part->next)
4657   {
4658     if (this_part->data.ptrvalue != NULL)
4659     {
4660       PopupItem (p, this_part->data.ptrvalue);
4661     }
4662   }
4663   SetObjectExtra (p, parent_form, NULL);
4664   return p;
4665 }
4666 
BuildQualifierSelect(GrouP parent,FeatureQualLoadFormPtr parent_form,ValNodePtr parts,QualifierSelectPtr qsp)4667 static void BuildQualifierSelect ( GrouP parent,
4668                                   FeatureQualLoadFormPtr parent_form,
4669                                   ValNodePtr parts,
4670                                   QualifierSelectPtr qsp )
4671 {
4672   GrouP g;
4673   Int4  listheight = 4;
4674   Int4  listwidth  = 13;
4675   Int4  j;
4676 
4677   if (parent_form == NULL || parts == NULL || qsp == NULL)
4678   {
4679     return;
4680   }
4681 
4682   g = HiddenGroup (parent, 0, 0, NULL);
4683 
4684   qsp->gene_quals = SingleList (g, listwidth, listheight,
4685                                    (LstActnProc) SetFeatureQualAcceptButton);
4686   SetObjectExtra (qsp->gene_quals, parent_form, NULL);
4687   ListItem (qsp->gene_quals, "None");
4688   for (j=0; j < NUM_GENE_TABLE_QUALIFIERS; j++) {
4689     ListItem (qsp->gene_quals, GeneTableQualifiers [j].item_name);
4690   }
4691   SetValue (qsp->gene_quals, 1);
4692 
4693   qsp->cds_quals = SingleList (g, listwidth, listheight,
4694                                    (LstActnProc) SetFeatureQualAcceptButton);
4695   SetObjectExtra (qsp->cds_quals, parent_form, NULL);
4696   ListItem (qsp->cds_quals, "None");
4697   for (j=0; j < NUM_PROT_TABLE_QUALIFIERS; j++) {
4698     ListItem (qsp->cds_quals, ProtTableQualifiers [j].item_name);
4699   }
4700   SetValue (qsp->cds_quals, 1);
4701 
4702   qsp->import_quals = SingleList (g, listwidth, listheight,
4703                                    (LstActnProc) SetFeatureQualAcceptButton);
4704   SetObjectExtra (qsp->import_quals, parent_form, NULL);
4705   ListItem (qsp->import_quals, "None");
4706   for (j = 0; j < ParFlat_TOTAL_GBQUAL; j++) {
4707     ListItem (qsp->import_quals, ParFlat_GBQual_names [j].name);
4708   }
4709   SetValue (qsp->import_quals, 1);
4710 }
4711 
BuildSequenceSelect(GrouP parent,FeatureQualLoadFormPtr parent_form,ValNodePtr parts)4712 static void BuildSequenceSelect ( GrouP parent,
4713                                   FeatureQualLoadFormPtr parent_form,
4714                                   ValNodePtr parts )
4715 {
4716   if (parent == NULL || parent_form == NULL || parts == NULL) return;
4717 
4718   parent_form->seq_group = NormalGroup ( parent, 0, 2, "Sequence", programFont, NULL);
4719   StaticPrompt (parent_form->seq_group, "Identifier Type", 0, popupMenuHeight, programFont, 'l');
4720   parent_form->sequence_id_type = PopupList (parent_form->seq_group, TRUE, (PupActnProc) SetFeatureQualAcceptButton);
4721   PopupItem (parent_form->sequence_id_type, "Accession");
4722   PopupItem (parent_form->sequence_id_type, "Local ID");
4723   PopupItem (parent_form->sequence_id_type, "None");
4724   SetObjectExtra (parent_form->sequence_id_type, parent_form, NULL);
4725   SetValue (parent_form->sequence_id_type, 3);
4726 
4727   StaticPrompt (parent_form->seq_group, "Column", 0, popupMenuHeight, programFont, 'l');
4728   parent_form->sequence_column = BuildColumnSelector ( parent_form->seq_group, parent_form, parts);
4729 }
4730 
BuildFeatureSelect(GrouP parent,FeatureQualLoadFormPtr parent_form,ValNodePtr parts)4731 static void BuildFeatureSelect ( GrouP parent,
4732                                  FeatureQualLoadFormPtr parent_form,
4733                                  ValNodePtr parts )
4734 {
4735   Int4  listheight = 4;
4736   ValNodePtr vnp;
4737 
4738   if (parent == NULL || parent_form == NULL || parts == NULL) return;
4739 
4740   parent_form->match_group = NormalGroup ( parent, 0, 2,
4741                                     "Feature to Edit", programFont, NULL);
4742   StaticPrompt (parent_form->match_group, "Feature type", 0,
4743                                    popupMenuHeight, programFont, 'l');
4744   parent_form->feature_type = SingleList (parent_form->match_group,
4745                                    9, listheight,
4746                    (LstActnProc) SetFeatureQualAcceptButton);
4747   SetObjectExtra (parent_form->feature_type, parent_form, NULL);
4748   for (vnp = parent_form->featlist; vnp != NULL; vnp = vnp->next)
4749   {
4750     ListItem (parent_form->feature_type, (CharPtr) vnp->data.ptrvalue);
4751   }
4752 
4753   StaticPrompt (parent_form->match_group, "Qualifier to match", 0, popupMenuHeight, programFont, 'l');
4754   BuildQualifierSelect ( parent_form->match_group, parent_form, parts, &(parent_form->match_qual));
4755 
4756   StaticPrompt (parent_form->match_group, "Column", 0, popupMenuHeight, programFont, 'l');
4757   parent_form->feature_column = BuildColumnSelector ( parent_form->match_group, parent_form, parts);
4758 
4759 }
4760 
BuildFeatureApply(GrouP parent,FeatureQualLoadFormPtr parent_form,ValNodePtr parts)4761 static void BuildFeatureApply ( GrouP parent,
4762                                FeatureQualLoadFormPtr parent_form,
4763                                ValNodePtr parts )
4764 {
4765   if (parent == NULL || parent_form == NULL || parts == NULL) return;
4766 
4767   parent_form->apply_group = NormalGroup ( parent, 0, 2, "Qualifier to Edit", programFont, NULL);
4768 
4769   StaticPrompt (parent_form->apply_group, "Qualifier Name", 0, popupMenuHeight, programFont, 'l');
4770   BuildQualifierSelect ( parent_form->apply_group, parent_form, parts, &(parent_form->apply_qual));
4771 
4772   StaticPrompt (parent_form->apply_group, "Column", 0, popupMenuHeight, programFont, 'l');
4773   parent_form->apply_column = BuildColumnSelector ( parent_form->apply_group, parent_form, parts);
4774 
4775 }
4776 
LoadFeatureQualifierTable(IteM i)4777 extern void LoadFeatureQualifierTable (IteM i)
4778 {
4779   BaseFormPtr   bfp;
4780   ValNodePtr    header_line;
4781   ValNodePtr    vnp;
4782   TableLinePtr  tlp;
4783   WindoW        w;
4784   GrouP         h, g, c;
4785   FeatureQualLoadFormPtr form_data;
4786   Int4          max_columns;
4787 
4788 #ifdef WIN_MAC
4789   bfp = currentFormDataPtr;
4790 #else
4791   bfp = GetObjectExtra (i);
4792 #endif
4793   if (bfp == NULL) return;
4794 
4795   header_line = ReadTableData ();
4796   if (header_line == NULL || header_line->data.ptrvalue == NULL) return;
4797   tlp = header_line->data.ptrvalue;
4798   max_columns = 0;
4799   for (vnp = tlp->parts; vnp != NULL; vnp = vnp->next)
4800   {
4801     max_columns ++;
4802   }
4803 
4804   form_data = MemNew (sizeof (FeatureQualLoadFormData));
4805   if (form_data == NULL) return;
4806   form_data->asked_about_replace = FALSE;
4807   form_data->do_replace = FALSE;
4808   form_data->use_semicolon = FALSE;
4809   form_data->entityID = bfp->input_entityID;
4810   form_data->line_list = header_line;
4811   form_data->featlist = BuildFeatureValNodeList (TRUE, NULL, 0, TRUE, FALSE);
4812   form_data->num_feats = 0;
4813   for (vnp = form_data->featlist; vnp != NULL; vnp = vnp->next)
4814   {
4815     form_data->num_feats ++;
4816   }
4817 
4818   /* now create a dialog to display values */
4819   w = FixedWindow (-50, -33, -10, -10, "Table Conversion", StdCloseWindowProc);
4820   SetObjectExtra (w, form_data, CleanupFeatureQualLoadForm);
4821   form_data->form = (ForM) w;
4822 
4823   h = HiddenGroup (w, -1, 0, NULL);
4824   SetGroupSpacing (h, 10, 10);
4825 
4826   BuildSequenceSelect ( h, form_data, tlp->parts);
4827   BuildFeatureSelect (h, form_data, tlp->parts);
4828   BuildFeatureApply (h, form_data, tlp->parts);
4829   ShowQualifierLists (form_data);
4830 
4831   g = HiddenGroup (h, 1, 0, NULL);
4832   form_data->replace_with_blank_btn = CheckBox (g, "Erase current value when blank found in table", NULL);
4833   c = HiddenGroup (h, 4, 0, NULL);
4834   form_data->accept_button = DefaultButton (c, "Accept", DoAcceptFeatureQuals);
4835   SetObjectExtra (form_data->accept_button, form_data, NULL);
4836   Disable (form_data->accept_button);
4837   PushButton (c, "Cancel", StdCancelButtonProc);
4838 
4839   AlignObjects (ALIGN_CENTER,
4840                 (HANDLE) form_data->seq_group,
4841                 (HANDLE) form_data->match_group,
4842                 (HANDLE) form_data->apply_group,
4843                 (HANDLE) c, NULL);
4844 
4845   RealizeWindow (w);
4846   Show (w);
4847   Update ();
4848 }
4849 
4850 
4851 typedef struct qualloadformdata {
4852   FEATURE_FORM_BLOCK
4853   ValNodePtr             table;
4854   DialoG                 list_dlg;
4855   DialoG PNTR            column_list;
4856   Int4                   num_columns;
4857   ButtoN                 remove_quotes;
4858   ButtoN                 accept_button;
4859   ButtoN                 mail_button;
4860   ButtoN                 erase_all_when_blank;  /* J. Chen */
4861   PrompT                 err_msg;
4862   DialoG                 table_constraint;
4863 } QualLoadFormData, PNTR QualLoadFormPtr;
4864 
CleanupQualLoadForm(GraphiC g,VoidPtr data)4865 static void CleanupQualLoadForm (
4866   GraphiC g,
4867   VoidPtr data
4868 )
4869 {
4870   QualLoadFormPtr form_data;
4871 
4872   form_data = (QualLoadFormPtr)data;
4873   if (form_data == NULL) return;
4874   form_data->table = FreeTabTable (form_data->table);
4875   StdCleanupFormProc (g, data);
4876 }
4877 
4878 
ChangeTabColumnChoice(Pointer data)4879 static void ChangeTabColumnChoice (Pointer data)
4880 {
4881   QualLoadFormPtr form_data;
4882   Int4            i;
4883   Boolean         have_match = FALSE, have_apply = FALSE;
4884   TabColumnConfigPtr t;
4885   ValNodePtr         err_list = NULL;
4886 
4887   if (data == NULL) return;
4888 
4889   form_data = (QualLoadFormPtr) data;
4890   SetTitle (form_data->err_msg, "");
4891   /* must have one and only one match choice, must have at least one apply choice */
4892 
4893   if (form_data->list_dlg == NULL) {
4894     for (i = 0; i < form_data->num_columns; i++) {
4895       t = (TabColumnConfigPtr) DialogToPointer (form_data->column_list[i]);
4896       if (t != NULL) {
4897         if (t->match_type != NULL) {
4898           if (have_match) {
4899             Disable (form_data->accept_button);
4900             Disable (form_data->mail_button);
4901             return;
4902           } else {
4903             have_match = TRUE;
4904           }
4905         } else if (!IsFieldTypeEmpty(t->field)) {
4906           have_apply = TRUE;
4907         }
4908       }
4909       t = TabColumnConfigFree (t);
4910     }
4911     if (have_match && have_apply) {
4912       Enable (form_data->accept_button);
4913       Enable (form_data->mail_button);
4914     } else {
4915       Disable (form_data->accept_button);
4916       Disable (form_data->mail_button);
4917     }
4918   } else {
4919     err_list = TestDialog (form_data->list_dlg);
4920     if (err_list == NULL) {
4921       Enable (form_data->accept_button);
4922       Enable (form_data->mail_button);
4923     } else {
4924       Disable (form_data->accept_button);
4925       Disable (form_data->mail_button);
4926       SetTitle (form_data->err_msg, err_list->data.ptrvalue);
4927       err_list = ValNodeFree (err_list);
4928     }
4929   }
4930 }
4931 
4932 
OkCancelTellMeMore(CharPtr message,LogInfoPtr lip)4933 static Boolean OkCancelTellMeMore (CharPtr message, LogInfoPtr lip)
4934 {
4935   WindoW w;
4936   GrouP  h, prompts, c;
4937   PrompT p1;
4938   ButtoN b;
4939   ModalAcceptCancelData acd;
4940   Boolean rval = FALSE;
4941   CharPtr cp, cp_end;
4942 
4943   acd.accepted = FALSE;
4944   acd.cancelled = FALSE;
4945   acd.third_option = FALSE;
4946 
4947   w = ModalWindow(-20, -13, -10, -10, NULL);
4948   h = HiddenGroup (w, -1, 0, NULL);
4949   SetGroupSpacing (h, 10, 10);
4950 
4951   prompts = HiddenGroup (h, 1, 0, NULL);
4952   SetGroupSpacing (prompts, 10, 10);
4953   cp = message;
4954   while (cp != NULL) {
4955     cp_end = StringChr (cp, '\n');
4956     if (cp_end != NULL) {
4957       *cp_end = 0;
4958     }
4959     p1 = StaticPrompt (prompts, cp, 0, 0, programFont, 'l');
4960     if (cp_end == NULL) {
4961       cp = NULL;
4962     } else {
4963       cp = cp_end + 1;
4964     }
4965   }
4966 
4967   c = HiddenGroup (h, 3, 0, NULL);
4968   SetGroupSpacing (c, 10, 10);
4969   b = PushButton (c, "Ok", ModalAcceptButton);
4970   SetObjectExtra (b, &acd, NULL);
4971   b = PushButton (c, "Tell Me More", ModalThirdOptionButton);
4972   SetObjectExtra (b, &acd, NULL);
4973   b = PushButton (c, "Cancel", ModalCancelButton);
4974   SetObjectExtra (b, &acd, NULL);
4975   AlignObjects (ALIGN_CENTER, (HANDLE) prompts, (HANDLE) c, NULL);
4976 
4977   Show(w);
4978   Select (w);
4979   while (!acd.accepted && ! acd.cancelled)
4980   {
4981     ProcessExternalEvent ();
4982     Update ();
4983     if (acd.third_option) {
4984       ShowLog (lip);
4985       acd.third_option = FALSE;
4986     }
4987   }
4988   ProcessAnEvent ();
4989   Remove (w);
4990   if (acd.accepted)
4991   {
4992     rval = TRUE;
4993   }
4994   else
4995   {
4996     rval = FALSE;
4997   }
4998   return rval;
4999 }
5000 
5001 
GetArticleFromObject(Uint1 choice,Pointer data)5002 static CitArtPtr GetArticleFromObject (Uint1 choice, Pointer data)
5003 {
5004   SeqFeatPtr sfp;
5005   SeqDescPtr sdp;
5006   PubdescPtr pdp = NULL;
5007   CitArtPtr  cap = NULL;
5008   ValNodePtr pub;
5009 
5010   if (data == NULL) {
5011     return NULL;
5012   }
5013 
5014   if (choice == OBJ_SEQFEAT) {
5015     sfp = (SeqFeatPtr) data;
5016     if (sfp->data.choice == SEQFEAT_PUB) {
5017       pdp = sfp->data.value.ptrvalue;
5018     }
5019   } else if (choice == OBJ_SEQDESC) {
5020     sdp = (SeqDescPtr) data;
5021     if (sdp->choice == Seq_descr_pub) {
5022       pdp = sdp->data.ptrvalue;
5023     }
5024   }
5025   if (pdp == NULL) {
5026     return NULL;
5027   }
5028   for (pub = pdp->pub; pub != NULL && cap == NULL; pub = pub->next) {
5029     if (pub->choice == PUB_Article) {
5030       cap = pub->data.ptrvalue;
5031     }
5032   }
5033   return cap;
5034 }
5035 
5036 
LookupJournalTitleColumn(Int4 col,ValNodePtr table)5037 static ValNodePtr LookupJournalTitleColumn (Int4 col, ValNodePtr table)
5038 {
5039   ValNodePtr      vnp, vnp_r, obj_vnp, title;
5040   Int4            i, len;
5041   Char            str[256];
5042   ValNodePtr      allTitles = NULL;
5043   Int1            jtaType;
5044   Boolean         unable_to_match;
5045   ValNodeBlock    bad_list;
5046   CitArtPtr       cap;
5047   CitJourPtr      journal;
5048 
5049   InitValNodeBlock(&bad_list, NULL);
5050   for (vnp_r = table; vnp_r != NULL; vnp_r = vnp_r->next) {
5051     for (i = 0, vnp = vnp_r->data.ptrvalue; i < col && vnp != NULL; i++, vnp = vnp->next) {
5052     }
5053     if (vnp != NULL) {
5054       for (obj_vnp = vnp->data.ptrvalue; obj_vnp != NULL; obj_vnp = obj_vnp->next) {
5055         if ((cap = GetArticleFromObject(obj_vnp->choice, obj_vnp->data.ptrvalue)) != NULL
5056             && cap->from == 1 && (journal = (CitJourPtr)cap->fromptr) != NULL
5057             && journal->title != NULL) {
5058           for (title = journal->title; title != NULL; title = title->next) {
5059             if (title->choice == Cit_title_name) {
5060               unable_to_match = TRUE;
5061               if (StringLen(title->data.ptrvalue) < sizeof (str) / sizeof (Char)) {
5062                 StringCpy (str, title->data.ptrvalue);
5063                 if (LookupJournalEUtilsFunc (str, sizeof (str) - 1, &jtaType, &allTitles)) {
5064                   len = ValNodeLen (allTitles);
5065                   if (len == 1 && StringDoesHaveText (allTitles->data.ptrvalue) &&
5066                              allTitles->choice == Cit_title_iso_jta) {
5067                     title->data.ptrvalue = MemFree (title->data.ptrvalue);
5068                     title->data.ptrvalue = StringSave(allTitles->data.ptrvalue);
5069                     title->choice = Cit_title_iso_jta;
5070                     unable_to_match = FALSE;
5071                   }
5072                   allTitles = ValNodeFreeData (allTitles);
5073                 }
5074               }
5075               if (unable_to_match) {
5076                 ValNodeAddPointerToEnd(&bad_list, 0, StringSave (title->data.ptrvalue));
5077               }
5078             }
5079           }
5080         }
5081       }
5082     }
5083   }
5084   return bad_list.head;
5085 }
5086 
5087 
LookupJournalTitlesInObjectTable(ValNodePtr obj_table,ValNodePtr columns)5088 static ValNodePtr LookupJournalTitlesInObjectTable (ValNodePtr obj_table, ValNodePtr columns)
5089 {
5090   Int4 i;
5091   ValNodePtr vnp;
5092   TabColumnConfigPtr t;
5093   ValNodePtr bad_list = NULL;
5094   Boolean rval = TRUE;
5095 
5096   for (i = 0, vnp = columns; vnp != NULL; vnp = vnp->next) {
5097     t = (TabColumnConfigPtr) vnp->data.ptrvalue;
5098     if (t != NULL && t->field != NULL && t->field->choice == FieldType_pub
5099         && t->field->data.intvalue == Publication_field_journal) {
5100       ValNodeLink (&bad_list, LookupJournalTitleColumn(i, obj_table));
5101     }
5102     if (t != NULL && t->match_type == NULL) {
5103       i++;
5104     }
5105   }
5106   bad_list = ValNodeSort (bad_list, SortVnpByString);
5107   ValNodeUnique(&bad_list, SortVnpByString, ValNodeFreeData);
5108   if (bad_list != NULL) {
5109     vnp = ValNodeNew (NULL);
5110     vnp->data.ptrvalue = StringSave("Unable to look up journal titles");
5111     vnp->next = bad_list;
5112     bad_list = vnp;
5113   }
5114   return bad_list;
5115 }
5116 
5117 
ApplyTableValues(SeqEntryPtr sep,ValNodePtr table,ValNodePtr columns)5118 static Boolean ApplyTableValues (SeqEntryPtr sep, ValNodePtr table, ValNodePtr columns)
5119 {
5120   ValNodePtr err_list, vnp, obj_table, dup_dest_errs;
5121   LogInfoPtr lip;
5122   Int4       msg_len = 0;
5123   CharPtr    msg = NULL, msg_end;
5124   CharPtr    msg_end_more_click = "Continue with errors?  Hit cancel to scroll through details";
5125   CharPtr    msg_end_less_click = "Continue with errors?";
5126   Boolean    less_clicking;
5127 
5128   less_clicking = UseLessClickingOption();
5129   if (less_clicking) {
5130     msg_end = msg_end_less_click;
5131   } else {
5132     msg_end = msg_end_more_click;
5133   }
5134   lip = OpenLog ("Table Problems");
5135 
5136   err_list = ValidateTabTableValues (table, columns);
5137   for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
5138     fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
5139     lip->data_in_log = TRUE;
5140   }
5141   err_list = ValNodeFreeData (err_list);
5142 
5143   obj_table = GetObjectTableForTabTable (sep, table, columns, &err_list);
5144 
5145   dup_dest_errs = CheckObjTableForRowsThatApplyToTheSameDestination (obj_table);
5146   if (dup_dest_errs != NULL) {
5147     for (vnp = dup_dest_errs; vnp != NULL; vnp = vnp->next) {
5148       fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
5149       lip->data_in_log = TRUE;
5150     }
5151     CloseLog (lip);
5152     Message (MSG_ERROR, "For one or more columns, two or more rows in the table apply to the same object.  Cannot continue.");
5153     dup_dest_errs = ValNodeFreeData (dup_dest_errs);
5154     err_list = ValNodeFreeData (err_list);
5155     FreeLog (lip);
5156     obj_table = FreeObjectTableForTabTable (obj_table);
5157     DeleteMarkedObjects (SeqMgrGetEntityIDForSeqEntry (sep), 0, NULL);
5158     return FALSE;
5159   }
5160 
5161   ValNodeLink (&err_list, CheckObjTableForExistingText (sep, table, columns, obj_table));
5162 
5163   msg_len = StringLen (msg_end) + 1;
5164   /* cycle through errors twice - first time, just print the ones with choice 1 (and sum lengths) */
5165   for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
5166     if (vnp->choice == 1) {
5167       fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
5168       lip->data_in_log = TRUE;
5169       msg_len += StringLen (vnp->data.ptrvalue) + 2;
5170     }
5171   }
5172   /* then cycle again, printing 0s */
5173   for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
5174     if (vnp->choice == 0) {
5175       fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
5176       lip->data_in_log = TRUE;
5177     }
5178   }
5179 
5180   /* now produce error message */
5181   if (lip->data_in_log) {
5182     msg = (CharPtr) MemNew (sizeof (Char) * msg_len);
5183     for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
5184       if (vnp->choice == 1) {
5185         StringCat (msg, vnp->data.ptrvalue);
5186         StringCat (msg, "\n");
5187       }
5188     }
5189     StringCat (msg, msg_end);
5190   }
5191 
5192   err_list = ValNodeFreeData (err_list);
5193 
5194   if (UseLessClickingOption()) {
5195     if (!OkCancelTellMeMore(msg, lip)) {
5196       msg = MemFree (msg);
5197       FreeLog (lip);
5198       DeleteMarkedObjects (SeqMgrGetEntityIDForSeqEntry (sep), 0, NULL);
5199       return FALSE;
5200     }
5201   } else {
5202     CloseLog (lip);
5203     if (lip->data_in_log) {
5204       if (ANS_CANCEL == Message (MSG_OKC, msg)) {
5205         msg = MemFree (msg);
5206         FreeLog (lip);
5207         DeleteMarkedObjects (SeqMgrGetEntityIDForSeqEntry (sep), 0, NULL);
5208         return FALSE;
5209       }
5210     }
5211   }
5212   msg = MemFree (msg);
5213   FreeLog (lip);
5214 
5215   err_list =  ApplyTableValuesToObjectTable (sep, table, columns, obj_table);
5216 
5217   /* look up journal titles for pubs in obj_table if one of the columns was setting journal title */
5218   ValNodeLink(&err_list, LookupJournalTitlesInObjectTable(obj_table, columns));
5219 
5220   if (less_clicking) {
5221     for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
5222       Message (MSG_POSTERR, "%s", (CharPtr) vnp->data.ptrvalue);
5223     }
5224   } else {
5225     lip = OpenLog ("Table Problems");
5226     for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
5227       fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
5228       lip->data_in_log = TRUE;
5229     }
5230     CloseLog (lip);
5231     FreeLog (lip);
5232   }
5233   err_list = ValNodeFreeData (err_list);
5234   obj_table = FreeObjectTableForTabTable (obj_table);
5235   DeleteMarkedObjects (SeqMgrGetEntityIDForSeqEntry (sep), 0, NULL);
5236   return TRUE;
5237 }
5238 
5239 
HandleDuplicateColumns(QualLoadFormPtr form_data,ValNodePtr columns)5240 static Boolean HandleDuplicateColumns (QualLoadFormPtr form_data, ValNodePtr columns)
5241 {
5242   ValNodePtr      dup_col_list;
5243   Int4            i;
5244   ValNodePtr      vnp;
5245   Boolean         rval = TRUE;
5246 
5247   if (form_data == NULL || columns == NULL) {
5248     return FALSE;
5249   }
5250 
5251   dup_col_list = CheckForDuplicateColumns (columns);
5252   if (dup_col_list != NULL) {
5253     if (ANS_CANCEL == Message (MSG_OKC,
5254          "You have specified multiple columns for the same qualifier value.  This will probably not work as expected. "
5255          " Do you want to change the configuration to add them all as separate qualifiers?")) {
5256       rval = FALSE;
5257     } else {
5258       dup_col_list = ValNodeFreeData(dup_col_list);
5259       FixDuplicateColumns (columns);
5260       if (form_data->list_dlg == NULL) {
5261         for (i = 0, vnp = columns; i < form_data->num_columns && vnp != NULL; i++, vnp = vnp->next) {
5262           PointerToDialog (form_data->column_list[i], vnp->data.ptrvalue);
5263         }
5264       } else {
5265         PointerToDialog (form_data->list_dlg, columns);
5266       }
5267     }
5268   }
5269   dup_col_list = ValNodeFreeData(dup_col_list);
5270 
5271   return rval;
5272 }
5273 
5274 
AddGlobalConstraintToColumns(ValNodePtr columns,ValNodePtr constraint)5275 static void AddGlobalConstraintToColumns (ValNodePtr columns, ValNodePtr constraint)
5276 {
5277   ValNodePtr vnp;
5278   TabColumnConfigPtr t;
5279   if (columns == NULL || constraint == NULL) {
5280     return;
5281   }
5282   for (vnp = columns; vnp != NULL; vnp = vnp->next) {
5283     if ((t = (TabColumnConfigPtr) vnp->data.ptrvalue) != NULL
5284         && t->match_type == NULL
5285         && t->field != NULL) {
5286       ValNodeLink (&(t->constraint),
5287                    AsnIoMemCopy (constraint,
5288                                 (AsnReadFunc) ConstraintChoiceSetAsnRead,
5289                                 (AsnWriteFunc) ConstraintChoiceSetAsnWrite));
5290     }
5291   }
5292 }
5293 
5294 
DoAcceptQuals(ButtoN b)5295 static void DoAcceptQuals (ButtoN b)
5296 {
5297   QualLoadFormPtr form_data;
5298   ValNodePtr      columns = NULL;
5299   ValNodePtr      global_constraint;
5300   Int4            i;
5301   TabColumnConfigPtr t;
5302   SeqEntryPtr     sep;
5303 
5304   form_data = (QualLoadFormPtr) GetObjectExtra (b);
5305   if (form_data == NULL) return;
5306 
5307   if (form_data->list_dlg == NULL) {
5308     for (i = 0; i < form_data->num_columns; i++) {
5309       t = DialogToPointer (form_data->column_list[i]);
5310       ValNodeAddPointer (&columns, 0, t);
5311     }
5312   } else {
5313     columns = DialogToPointer (form_data->list_dlg);
5314   }
5315 
5316   if (!HandleDuplicateColumns(form_data, columns)) {
5317     columns = TabColumnConfigListFree (columns);
5318     return;
5319   }
5320   global_constraint = DialogToPointer (form_data->table_constraint);
5321   AddGlobalConstraintToColumns(columns, global_constraint);
5322   global_constraint = ConstraintChoiceSetFree(global_constraint);
5323 
5324   if (GetStatus (form_data->remove_quotes)) {
5325     RemoveQuotesFromTabTable (form_data->table);
5326   }
5327 
5328 
5329   sep = GetTopSeqEntryForEntityID (form_data->input_entityID);
5330   if (ApplyTableValues (sep, form_data->table, columns)) {
5331     ObjMgrSetDirtyFlag (form_data->input_entityID, TRUE);
5332     ObjMgrSendMsg (OM_MSG_UPDATE, form_data->input_entityID, 0, 0);
5333     if (GetStatus (form_data->leave_dlg_up)) {
5334     } else {
5335       Remove (form_data->form);
5336     }
5337     Update();
5338   }
5339   columns = TabColumnConfigListFree (columns);
5340 
5341 }
5342 
5343 
5344 typedef struct mailreport {
5345   BioseqPtr    bsp;
5346   BioSourcePtr biop;
5347   CharPtr      old_name;
5348 } MailReportData, PNTR MailReportPtr;
5349 
5350 
MailReportNew(BioseqPtr bsp,CharPtr old_name,BioSourcePtr biop)5351 static MailReportPtr MailReportNew (BioseqPtr bsp, CharPtr old_name, BioSourcePtr biop)
5352 {
5353   MailReportPtr m;
5354 
5355   m = (MailReportPtr) MemNew (sizeof (MailReportData));
5356   m->bsp = bsp;
5357   m->old_name = StringSave (old_name);
5358   m->biop = biop;
5359   return m;
5360 }
5361 
5362 
MailReportFree(MailReportPtr m)5363 static MailReportPtr MailReportFree (MailReportPtr m)
5364 {
5365   if (m != NULL) {
5366     m->old_name = MemFree (m->old_name);
5367     m = MemFree (m);
5368   }
5369   return m;
5370 }
5371 
5372 
MailReportListFree(ValNodePtr vnp)5373 static ValNodePtr MailReportListFree (ValNodePtr vnp)
5374 {
5375   ValNodePtr vnp_next;
5376 
5377   while (vnp != NULL) {
5378     vnp_next = vnp->next;
5379     vnp->next = NULL;
5380     vnp->data.ptrvalue = MailReportFree (vnp->data.ptrvalue);
5381     vnp = ValNodeFree (vnp);
5382     vnp = vnp_next;
5383   }
5384   return vnp;
5385 }
5386 
5387 
MailReportCallback(BioseqPtr bsp,Pointer data)5388 static void MailReportCallback (BioseqPtr bsp, Pointer data)
5389 {
5390   SeqDescrPtr       sdp;
5391   SeqMgrDescContext context;
5392   BioSourcePtr      biop;
5393 
5394   if (bsp == NULL || data == NULL || ISA_aa (bsp->mol)) {
5395     return;
5396   }
5397 
5398   for (sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &context);
5399        sdp != NULL;
5400        sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_source, &context)) {
5401     if ((biop = (BioSourcePtr) sdp->data.ptrvalue) != NULL
5402         && biop->org != NULL
5403         && !StringHasNoText (biop->org->taxname)) {
5404       ValNodeAddPointer ((ValNodePtr PNTR) data, 0, MailReportNew (bsp, biop->org->taxname, biop));
5405     }
5406   }
5407 }
5408 
5409 
ReportOneMailReport(MailReportPtr m,BioSourcePtr biop,LogInfoPtr lip)5410 static void ReportOneMailReport (MailReportPtr m, BioSourcePtr biop, LogInfoPtr lip)
5411 {
5412   Char              id_str[100];
5413 
5414   SeqIdWrite (SeqIdFindBest (m->bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, sizeof (id_str) - 1);
5415   fprintf (lip->fp, "%s\t%s\t%s\n", id_str, m->old_name == NULL ? "" : m->old_name,
5416                  biop->org == NULL || biop->org->taxname == NULL ? "" : biop->org->taxname);
5417   lip->data_in_log = TRUE;
5418 }
5419 
5420 
ReportOneMailReportNoTaxId(MailReportPtr m,LogInfoPtr lip)5421 static void ReportOneMailReportNoTaxId (MailReportPtr m, LogInfoPtr lip)
5422 {
5423   SeqDescrPtr       sdp;
5424   SeqMgrDescContext context;
5425   BioSourcePtr      biop;
5426 
5427   if (m == NULL || m->bsp == NULL) {
5428     return;
5429   }
5430 
5431   for (sdp = SeqMgrGetNextDescriptor (m->bsp, NULL, Seq_descr_source, &context);
5432        sdp != NULL;
5433        sdp = SeqMgrGetNextDescriptor (m->bsp, sdp, Seq_descr_source, &context)) {
5434     if ((biop = (BioSourcePtr) sdp->data.ptrvalue) != NULL
5435         && biop == m->biop
5436         &&!HasTaxonomyID(biop)) {
5437       ReportOneMailReport (m, biop, lip);
5438       lip->data_in_log = TRUE;
5439       break;
5440     }
5441   }
5442 }
5443 
5444 
ReportOneMailReportSpToNoSp(MailReportPtr m,LogInfoPtr lip)5445 static void ReportOneMailReportSpToNoSp (MailReportPtr m, LogInfoPtr lip)
5446 {
5447   SeqDescrPtr       sdp;
5448   SeqMgrDescContext context;
5449   BioSourcePtr      biop;
5450 
5451   if (m == NULL || m->bsp == NULL || StringStr (m->old_name, " sp.") == NULL) {
5452     return;
5453   }
5454 
5455   for (sdp = SeqMgrGetNextDescriptor (m->bsp, NULL, Seq_descr_source, &context);
5456        sdp != NULL;
5457        sdp = SeqMgrGetNextDescriptor (m->bsp, sdp, Seq_descr_source, &context)) {
5458     if ((biop = (BioSourcePtr) sdp->data.ptrvalue) != NULL
5459         && biop == m->biop
5460         && biop->org != NULL && biop->org->taxname != NULL
5461         && StringStr (biop->org->taxname, " sp.") == NULL) {
5462       ReportOneMailReport (m, biop, lip);
5463       lip->data_in_log = TRUE;
5464     }
5465   }
5466 }
5467 
5468 
ReportUnpublishedTaxnames(ValNodePtr list,LogInfoPtr lip)5469 static void ReportUnpublishedTaxnames (ValNodePtr list, LogInfoPtr lip)
5470 {
5471   ValNodePtr request_list = NULL, response_list;
5472   ValNodePtr vnp_m, vnp_r;
5473   MailReportPtr m;
5474 
5475   for (vnp_m = list; vnp_m != NULL; vnp_m = vnp_m->next) {
5476     m = (MailReportPtr) vnp_m->data.ptrvalue;
5477     ValNodeAddPointer (&request_list, 3, m->biop->org);
5478   }
5479   response_list = Taxon3GetOrgRefList (request_list);
5480   ValNodeFree (request_list);
5481 
5482   fprintf (lip->fp, "\n\nUnpublished Names\n");
5483   fprintf (lip->fp, "Accession\tOld Name\tNew Name\n");
5484   for (vnp_m = list, vnp_r = response_list;
5485        vnp_m != NULL && vnp_r != NULL;
5486        vnp_m = vnp_m->next, vnp_r = vnp_r->next) {
5487     if (vnp_r->choice & eReturnedOrgFlag_unpublished) {
5488       m = (MailReportPtr) vnp_m->data.ptrvalue;
5489       ReportOneMailReport (m, m->biop, lip);
5490     }
5491   }
5492 
5493   ValNodeFree (response_list);
5494 }
5495 
5496 
WantBarcodeAdjustmentCallback(BioseqPtr bsp,Pointer data)5497 static void WantBarcodeAdjustmentCallback (BioseqPtr bsp, Pointer data)
5498 {
5499   if (bsp != NULL && data != NULL && HasBARCODETech(bsp)) {
5500     *((BoolPtr)data) = TRUE;
5501   }
5502 }
5503 
5504 
WantBarcodeAdjustment(SeqEntryPtr sep)5505 static Boolean WantBarcodeAdjustment (SeqEntryPtr sep)
5506 {
5507   Boolean want_adjustment = FALSE;
5508   Char    path [PATH_MAX];
5509   FILE   *fp;
5510 
5511   if (!GetSequinAppParam ("BARCODE", "LIVELIST", NULL, path, sizeof (path))) {
5512     return FALSE;
5513   }
5514   if (StringHasNoText (path)) {
5515     return FALSE;
5516   }
5517 
5518   fp = FileOpen (path, "r");
5519   if (fp == NULL) {
5520     return FALSE;
5521   }
5522   FileClose (fp);
5523 
5524   VisitBioseqsInSep (sep, &want_adjustment, WantBarcodeAdjustmentCallback);
5525 
5526   return want_adjustment;
5527 }
5528 
5529 
5530 static TwoStringHashPtr sBarcodeLiveListAccBin = NULL;
5531 static TwoStringHashPtr sBarcodeLiveListAccId = NULL;
5532 static TwoStringHashPtr sBarcodeLiveListIdBin = NULL;
5533 static Boolean sAttemptedToReadBarcodeLiveList = FALSE;
5534 
FixBarcodeLiveListIds(ValNodePtr table)5535 static void FixBarcodeLiveListIds (ValNodePtr table)
5536 {
5537   ValNodePtr row, col;
5538   CharPtr    cp;
5539 
5540   for (row = table; row != NULL; row = row->next) {
5541     col = row->data.ptrvalue;
5542     if (col != NULL && col->next != NULL && (cp = StringChr (col->next->data.ptrvalue, '.')) != NULL) {
5543       *cp = 0;
5544     }
5545   }
5546 }
5547 
5548 
ReadBarcodeLiveList(void)5549 static Boolean ReadBarcodeLiveList (void)
5550 {
5551   ValNodePtr table, col, vnp;
5552   Char    path [PATH_MAX];
5553   FILE   *fp;
5554   Int4   len, i;
5555 
5556   if (sAttemptedToReadBarcodeLiveList) {
5557     if (sBarcodeLiveListAccBin == NULL) {
5558       return FALSE;
5559     } else {
5560       return TRUE;
5561     }
5562   }
5563   if (!GetSequinAppParam ("BARCODE", "LIVELIST", NULL, path, sizeof (path))) {
5564     return FALSE;
5565   }
5566   if (StringHasNoText (path)) {
5567     return FALSE;
5568   }
5569 
5570   fp = FileOpen (path, "r");
5571   if (fp == NULL) {
5572     return FALSE;
5573   }
5574   table = ReadTabTableFromFile (fp);
5575   FileClose (fp);
5576 
5577   if (table == NULL) {
5578     return FALSE;
5579   }
5580 
5581   /* process IDs in second column are actually just the part before the first period */
5582   FixBarcodeLiveListIds (table);
5583   table = SortTableRowByAnyColumn (table, 1);
5584   len = ValNodeLen (table);
5585   sBarcodeLiveListAccBin = (TwoStringHashPtr) MemNew (sizeof (TwoStringHashData));
5586   sBarcodeLiveListAccBin->table = (CharPtr PNTR) MemNew (sizeof (CharPtr) * len * 2);
5587   sBarcodeLiveListAccBin->num_lines = 0;
5588   sBarcodeLiveListAccId = (TwoStringHashPtr) MemNew (sizeof (TwoStringHashData));
5589   sBarcodeLiveListAccId->table = (CharPtr PNTR) MemNew (sizeof (CharPtr) * len * 2);
5590   sBarcodeLiveListAccId->num_lines = 0;
5591   for (vnp = table; vnp != NULL; vnp = vnp->next) {
5592     col = vnp->data.ptrvalue;
5593     if (col != NULL && !StringHasNoText (col->data.ptrvalue)) {
5594       if (col->next != NULL && !StringHasNoText (col->next->data.ptrvalue)) {
5595         i = sBarcodeLiveListAccId->num_lines;
5596         sBarcodeLiveListAccId->table[2 * i] = StringSave (col->data.ptrvalue);
5597         sBarcodeLiveListAccId->table[2 * i + 1] = StringSave (col->next->data.ptrvalue);
5598         sBarcodeLiveListAccId->num_lines++;
5599       }
5600       if (col->next != NULL && col->next->next != NULL && col->next->next->next != NULL && !StringHasNoText (col->next->next->next->data.ptrvalue)) {
5601         i = sBarcodeLiveListAccBin->num_lines;
5602         sBarcodeLiveListAccBin->table[2 * i] = StringSave (col->data.ptrvalue);
5603         sBarcodeLiveListAccBin->table[2 * i + 1] = StringSave (col->next->next->next->data.ptrvalue);
5604         sBarcodeLiveListAccBin->num_lines++;
5605       }
5606     }
5607   }
5608   table = SortTableRowByAnyColumn (table, 2);
5609   sBarcodeLiveListIdBin = (TwoStringHashPtr) MemNew (sizeof (TwoStringHashData));
5610   sBarcodeLiveListIdBin->table = (CharPtr PNTR) MemNew (sizeof (CharPtr) * len * 2);
5611   sBarcodeLiveListIdBin->num_lines = 0;
5612   for (vnp = table; vnp != NULL; vnp = vnp->next) {
5613     col = vnp->data.ptrvalue;
5614     if (col != NULL && col->next != NULL && !StringHasNoText (col->next->data.ptrvalue)
5615         && col->next->next != NULL && col->next->next->next != NULL && !StringHasNoText (col->next->next->next->data.ptrvalue)) {
5616       i = sBarcodeLiveListIdBin->num_lines;
5617       sBarcodeLiveListIdBin->table[2 * i] = StringSave (col->next->data.ptrvalue);
5618       sBarcodeLiveListIdBin->table[2 * i + 1] = StringSave (col->next->next->next->data.ptrvalue);
5619       sBarcodeLiveListIdBin->num_lines++;
5620     }
5621   }
5622 
5623   table = FreeTabTable (table);
5624 
5625   sAttemptedToReadBarcodeLiveList = TRUE;
5626   return TRUE;
5627 }
5628 
5629 
5630 static const CharPtr sBarcodeSpecialWords[] = {
5631   " sp.", " aff.", " cf.", " group", " complex", " nr.", " near", NULL };
5632 
5633 
IsJustOneWord(CharPtr organism)5634 static Boolean IsJustOneWord (CharPtr organism)
5635 {
5636   if (StringChr (organism, ' ') == NULL) {
5637     return TRUE;
5638   } else {
5639     return FALSE;
5640   }
5641 }
5642 
5643 
OrganismWantsBarcodeAdjustment(CharPtr organism)5644 static Boolean OrganismWantsBarcodeAdjustment (CharPtr organism)
5645 {
5646   Boolean rval = FALSE;
5647   Int4    i;
5648   /* TODO - only if contains one of the special words, or is just one word */
5649   if (IsJustOneWord (organism)) {
5650     rval = TRUE;
5651   } else {
5652     for (i = 0; sBarcodeSpecialWords[i] != NULL && !rval; i++) {
5653       if (StringSearch (organism, sBarcodeSpecialWords[i]) != NULL) {
5654         rval = TRUE;
5655       }
5656     }
5657   }
5658 
5659   return rval;
5660 }
5661 
5662 
FieldTypeIsTaxname(ValNodePtr field)5663 static Boolean FieldTypeIsTaxname (ValNodePtr field)
5664 {
5665   ValNodePtr srcq;
5666   if (field != NULL
5667       && field->choice == FieldType_source_qual
5668       && (srcq = field->data.ptrvalue) != NULL
5669       && srcq->choice == SourceQualChoice_textqual
5670       && srcq->data.intvalue == Source_qual_taxname) {
5671     return TRUE;
5672   } else {
5673     return FALSE;
5674   }
5675 }
5676 
5677 
AdjustTableForBarcodeLiveList(ValNodePtr table,QualLoadFormPtr form_data)5678 static ValNodePtr AdjustTableForBarcodeLiveList (ValNodePtr table, QualLoadFormPtr form_data)
5679 {
5680   ValNodePtr new_table;
5681   ValNodePtr         columns = NULL, vnp, org_vnp, acc_vnp;
5682   TabColumnConfigPtr t;
5683   Int4               accession_column = -1;
5684   Int4               organism_column = -1;
5685   Int4               i;
5686   CharPtr            uniquer, id, tmp_name;
5687 
5688   new_table = CopyTabTable (table);
5689 
5690   if (form_data->list_dlg == NULL) {
5691     for (i = 0; i < form_data->num_columns; i++) {
5692       t = DialogToPointer (form_data->column_list[i]);
5693       if (t != NULL && t->match_type != NULL && t->match_type->choice == eTableMatchNucID) {
5694         accession_column = i + 1;
5695       } else if (t != NULL && FieldTypeIsTaxname(t->field)) {
5696         organism_column = i + 1;
5697       }
5698       t = TabColumnConfigFree (t);
5699     }
5700   } else {
5701     columns = DialogToPointer (form_data->list_dlg);
5702     for (vnp = columns, i = 0; vnp != NULL; vnp = vnp->next, i++) {
5703       t = (TabColumnConfigPtr) vnp->data.ptrvalue;
5704       if (t != NULL && t->match_type != NULL && t->match_type->choice == eTableMatchNucID) {
5705         accession_column = i;
5706       } else if (t != NULL && FieldTypeIsTaxname(t->field)) {
5707         organism_column = i;
5708       }
5709     }
5710     columns = TabColumnConfigListFree (columns);
5711   }
5712 
5713   if (accession_column > -1 && organism_column > -1) {
5714     /* do replacements */
5715     for (vnp = new_table; vnp != NULL; vnp = vnp->next) {
5716       org_vnp = GetNthValNode(vnp->data.ptrvalue, organism_column);
5717       if (org_vnp != NULL && OrganismWantsBarcodeAdjustment (org_vnp->data.ptrvalue)) {
5718         acc_vnp = GetNthValNode(vnp->data.ptrvalue, accession_column);
5719         if (acc_vnp != NULL) {
5720           uniquer = GetValueFromTwoStringHash(acc_vnp->data.ptrvalue, sBarcodeLiveListAccBin);
5721           if (uniquer == NULL) {
5722             id = GetValueFromTwoStringHash(acc_vnp->data.ptrvalue, sBarcodeLiveListAccId);
5723             if (id != NULL) {
5724               uniquer = GetValueFromTwoStringHash(acc_vnp->data.ptrvalue, sBarcodeLiveListIdBin);
5725               if (uniquer == NULL) {
5726                 uniquer = id;
5727               }
5728             }
5729           }
5730           if (uniquer != NULL) {
5731             /* make sure it's not already in the organism name */
5732             tmp_name = org_vnp->data.ptrvalue;
5733             if (StringSearch (tmp_name, uniquer) == NULL) {
5734               if (IsJustOneWord(tmp_name)) {
5735                 SetStringValue (&tmp_name, "sp.", ExistingTextOption_append_space);
5736               }
5737               SetStringValue (&tmp_name, uniquer, ExistingTextOption_append_space);
5738               org_vnp->data.ptrvalue = tmp_name;
5739             }
5740           }
5741         }
5742       }
5743     }
5744   }
5745 
5746   return new_table;
5747 }
5748 
5749 
SpecialMailReport(ButtoN b)5750 static void SpecialMailReport (ButtoN b)
5751 {
5752   QualLoadFormPtr form_data;
5753   ValNodePtr      adjusted_table = NULL, tmp_table = NULL;
5754   ValNodePtr      list = NULL, vnp;
5755   SeqEntryPtr     sep;
5756   LogInfoPtr      lip;
5757   MailReportPtr   m;
5758 
5759   form_data = (QualLoadFormPtr) GetObjectExtra (b);
5760   if (form_data == NULL) return;
5761 
5762   /* first, get list of accessions and current names */
5763   sep = GetTopSeqEntryForEntityID (form_data->input_entityID);
5764   VisitBioseqsInSep (sep, &list, MailReportCallback);
5765 
5766   /* adjust table if necessary for barcode livelist */
5767   tmp_table = form_data->table;
5768   if (WantBarcodeAdjustment (sep) && ReadBarcodeLiveList()) {
5769     adjusted_table = AdjustTableForBarcodeLiveList (form_data->table, form_data);
5770     form_data->table = adjusted_table;
5771   }
5772 
5773   /* now apply table */
5774   DoAcceptQuals (b);
5775 
5776   /* put original table back */
5777   form_data->table = tmp_table;
5778   adjusted_table = FreeTabTable (adjusted_table);
5779 
5780   /* now do taxfix */
5781   Taxon3ReplaceOrgInSeqEntryEx (sep, FALSE, FALSE);
5782   ObjMgrSetDirtyFlag (form_data->input_entityID, TRUE);
5783   ObjMgrSendMsg (OM_MSG_UPDATE, form_data->input_entityID, 0, 0);
5784   Update();
5785 
5786   /* now create report for organisms without IDs */
5787   lip = OpenLog ("Organism Change Report");
5788   fprintf (lip->fp, "Failed Lookups\n");
5789   fprintf (lip->fp, "Accession\tOld Name\tNew Name\n");
5790   for (vnp = list; vnp != NULL; vnp = vnp->next) {
5791     m = (MailReportPtr) vnp->data.ptrvalue;
5792     ReportOneMailReportNoTaxId(m, lip);
5793   }
5794   fprintf (lip->fp, "\n\nSp. Replaced with Real\n");
5795 
5796   fprintf (lip->fp, "Accession\tOld Name\tNew Name\n");
5797   for (vnp = list; vnp != NULL; vnp = vnp->next) {
5798     m = (MailReportPtr) vnp->data.ptrvalue;
5799     ReportOneMailReportSpToNoSp(m, lip);
5800   }
5801 
5802   ReportUnpublishedTaxnames (list, lip);
5803 
5804   CloseLog (lip);
5805   lip = FreeLog (lip);
5806 
5807   MailReportListFree(list);
5808 
5809 }
5810 
5811 /* J. Chen */
ReMatchQuals(ButtoN b)5812 static void ReMatchQuals(ButtoN b)
5813 {
5814   QualLoadFormPtr form_data;
5815   ValNodePtr      val, vnp;
5816   ValNodePtr      columns = NULL;
5817   Int4            i;
5818   TabColumnConfigPtr t;
5819 
5820   form_data = (QualLoadFormPtr) GetObjectExtra (b);
5821   if (form_data == NULL) return;
5822 
5823   if (form_data->list_dlg == NULL) {
5824     for (i = 0; i < form_data->num_columns; i++) {
5825       t = DialogToPointer (form_data->column_list[i]);
5826       ValNodeAddPointer (&columns, 0, t);
5827     }
5828   } else {
5829     columns = DialogToPointer (form_data->list_dlg);
5830   }
5831 
5832   for (i = 0, val = form_data->table->data.ptrvalue, vnp = columns;
5833        val != NULL;
5834        val = val->next, vnp = vnp->next, i++) {
5835     if (vnp == NULL) {
5836       vnp = ValNodeNew (columns);
5837     }
5838     t = vnp->data.ptrvalue;
5839     if (t == NULL) {
5840       t = TabColumnConfigNew ();
5841       vnp->data.ptrvalue = t;
5842     }
5843     t->field = FieldTypeFromString (val->data.ptrvalue);
5844     if (t->field == NULL) {
5845 	if (!strcmp(val->data.ptrvalue, "Accession")) { /* new MatchTypeData */
5846 	    t->match_type = MatchTypeNew();   /* default: choice = eTableMatchNucID; */
5847 	}
5848 	else {
5849            t = TabColumnConfigFree (t);
5850            vnp->data.ptrvalue = NULL;
5851 	}
5852 
5853     }
5854     else  {  /* if match_type doesn't match the field, whatever, change "Match" to "Apply" */
5855 	t->match_type = MatchTypeFree(t->match_type);
5856     }
5857   }
5858 
5859   if (form_data->list_dlg == NULL) {
5860     for (i = 0, vnp = columns; i < form_data->num_columns && vnp != NULL; i++, vnp = vnp->next) {
5861       PointerToDialog (form_data->column_list[i], vnp->data.ptrvalue);
5862     }
5863   } else {
5864     PointerToDialog (form_data->list_dlg, columns);
5865   }
5866   columns = TabColumnConfigListFree (columns);
5867 }  /* ReMatchQuals */
5868 
5869 
5870 /* J. Chen */
EraseAllFieldsWhenBlank(ButtoN b)5871 static void EraseAllFieldsWhenBlank(ButtoN b)
5872 {
5873   QualLoadFormPtr form_data;
5874   ValNodePtr      columns = NULL;
5875   Int4            i;
5876   TabColumnConfigListDlgPtr dlg;
5877 
5878   form_data = (QualLoadFormPtr) GetObjectExtra (b);
5879   if (form_data == NULL) return;
5880 
5881 
5882   if (form_data->list_dlg != NULL) {
5883      dlg = (TabColumnConfigListDlgPtr) GetObjectExtra (form_data->list_dlg);
5884      for (i=0; i<  dlg->num_columns; i++) {
5885 	if ( dlg->column_list[i] != NULL) {
5886 	   if (dlg->blank_list[i] > 0) dlg->column_list[i]->skip_blank = FALSE;
5887 	   else dlg->column_list[i]->skip_blank = TRUE;
5888 	}
5889      }
5890      PopulateTabConfigListColumnListDoc(form_data->list_dlg);
5891   }
5892 
5893   return;
5894 
5895 }  /* EraseAllFieldsWhenBlank */
5896 
5897 
5898 
AutoMatchQuals(ButtoN b)5899 static void AutoMatchQuals (ButtoN b)
5900 {
5901   QualLoadFormPtr form_data;
5902   ValNodePtr      val, vnp;
5903   ValNodePtr      columns = NULL;
5904   Int4            i;
5905   TabColumnConfigPtr t;
5906 
5907   form_data = (QualLoadFormPtr) GetObjectExtra (b);
5908   if (form_data == NULL) return;
5909 
5910   if (form_data->list_dlg == NULL) {
5911     for (i = 0; i < form_data->num_columns; i++) {
5912       t = DialogToPointer (form_data->column_list[i]);
5913       ValNodeAddPointer (&columns, 0, t);
5914     }
5915   } else {
5916     columns = DialogToPointer (form_data->list_dlg);
5917   }
5918 
5919   for (val = form_data->table->data.ptrvalue, vnp = columns;
5920        val != NULL;
5921        val = val->next, vnp = vnp->next) {
5922     if (vnp == NULL) {
5923       vnp = ValNodeNew (columns);
5924     }
5925     t = vnp->data.ptrvalue;
5926     if (t == NULL) {
5927       t = TabColumnConfigNew ();
5928       vnp->data.ptrvalue = t;
5929     }
5930     if (t->match_type == NULL && t->field == NULL) {
5931       t->field = FieldTypeFromString (val->data.ptrvalue);
5932       if (t->field == NULL) {
5933         t = TabColumnConfigFree (t);
5934         vnp->data.ptrvalue = NULL;
5935       }
5936     }
5937   }
5938 
5939   if (form_data->list_dlg == NULL) {
5940     for (i = 0, vnp = columns; i < form_data->num_columns && vnp != NULL; i++, vnp = vnp->next) {
5941       PointerToDialog (form_data->column_list[i], vnp->data.ptrvalue);
5942     }
5943   } else {
5944     PointerToDialog (form_data->list_dlg, columns);
5945   }
5946   columns = TabColumnConfigListFree (columns);
5947 }
5948 
5949 
ResetColumns(ButtoN b)5950 static void ResetColumns (ButtoN b)
5951 {
5952   QualLoadFormPtr form_data;
5953   ValNodePtr      vnp;
5954   ValNodePtr      columns = NULL;
5955   Int4            i;
5956   TabColumnConfigPtr t;
5957 
5958   form_data = (QualLoadFormPtr) GetObjectExtra (b);
5959   if (form_data == NULL) return;
5960 
5961   if (form_data->list_dlg == NULL) {
5962     for (i = 0; i < form_data->num_columns; i++) {
5963       t = DialogToPointer (form_data->column_list[i]);
5964       TabColumnConfigReset(t);
5965       PointerToDialog (form_data->column_list[i], t);
5966       t = TabColumnConfigFree(t);
5967     }
5968   } else {
5969     columns = DialogToPointer (form_data->list_dlg);
5970     for (vnp = columns;
5971          vnp != NULL;
5972          vnp = vnp->next) {
5973       vnp->data.ptrvalue = TabColumnConfigFree (vnp->data.ptrvalue);
5974     }
5975     PointerToDialog (form_data->list_dlg, columns);
5976     columns = TabColumnConfigListFree (columns);
5977   }
5978 }
5979 
5980 
5981 static WindoW CreateTableReaderWindowWithTable (Uint2 entityID, ValNodePtr table, CharPtr title);
5982 
LoadNewTable(ButtoN b)5983 static void LoadNewTable (ButtoN b)
5984 {
5985   Char         path [PATH_MAX];
5986   FILE *fp;
5987   QualLoadFormPtr form_data, new_form_data;
5988   ValNodePtr      table, special_list, blank_list, columns = NULL, c_vnp;
5989   Int4            i;
5990   WindoW          w;
5991   TabColumnConfigPtr t;
5992 
5993   form_data = (QualLoadFormPtr) GetObjectExtra (b);
5994   if (form_data == NULL) return;
5995 
5996   path [0] = '\0';
5997   if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return;
5998 
5999   fp = FileOpen (path, "r");
6000 
6001   table = ReadTabTableFromFile (fp);
6002   FileClose (fp);
6003   if (table == NULL) return;
6004   special_list = ScanTabTableForSpecialCharacters (table);
6005   if (special_list != NULL
6006       && !FixSpecialCharactersForStringsInList (special_list,
6007                                                 "The table contains special characters\nand cannot be used until they are replaced.",
6008                                                 FALSE)) {
6009     special_list = FreeContextList (special_list);
6010     return;
6011   }
6012   special_list = FreeContextList (special_list);
6013   if (form_data->list_dlg != NULL) {
6014     form_data->table = table;
6015     /* it's ok, can just repopulate dialogs */
6016     blank_list = CountTabTableBlanks (table);
6017     ChangeDataForTabColumnConfigListDialog (form_data->list_dlg, form_data->table->data.ptrvalue, blank_list);
6018     blank_list = ValNodeFree (blank_list);
6019   } else {
6020     /* build a new window */
6021     w = CreateTableReaderWindowWithTable (form_data->input_entityID, table, "Apply Qualifiers");
6022     /* get old configurations */
6023     if (form_data->list_dlg == NULL) {
6024       for (i = 0; i < form_data->num_columns; i++) {
6025         t = DialogToPointer (form_data->column_list[i]);
6026         ValNodeAddPointer (&columns, 0, t);
6027       }
6028     } else {
6029       columns = DialogToPointer (form_data->list_dlg);
6030     }
6031 
6032     /* apply to new window */
6033     new_form_data = (QualLoadFormPtr) GetObjectExtra (w);
6034     if (new_form_data->list_dlg == NULL) {
6035       for (i = 0, c_vnp = columns; i < new_form_data->num_columns && c_vnp != NULL; i++, c_vnp = c_vnp->next) {
6036         PointerToDialog (new_form_data->column_list[i], c_vnp->data.ptrvalue);
6037       }
6038     } else {
6039       PointerToDialog (new_form_data->list_dlg, columns);
6040     }
6041     columns = ValNodeFree (columns);
6042     SetStatus (new_form_data->remove_quotes, GetStatus (form_data->remove_quotes));
6043     SetStatus (new_form_data->leave_dlg_up, GetStatus (form_data->leave_dlg_up));
6044 
6045     /* remove old window */
6046     Remove ((WindoW) form_data->form);
6047 
6048     RealizeWindow (w);
6049     Show (w);
6050     Update ();
6051   }
6052 
6053 
6054 }
6055 
6056 typedef void (*Nlm_ReparseTabTable) PROTO ((ValNodePtr));
6057 
6058 
ReDrawWindowAfterTableReload(QualLoadFormPtr form_data)6059 static void ReDrawWindowAfterTableReload(QualLoadFormPtr form_data)
6060 {
6061   QualLoadFormPtr new_form_data;
6062   ValNodePtr      blank_list, columns = NULL, c_vnp, table;
6063   Int4            i;
6064   WindoW          w;
6065   TabColumnConfigPtr t;
6066 
6067   if (form_data->list_dlg != NULL) {
6068     /* it's ok, can just repopulate dialogs */
6069     blank_list = CountTabTableBlanks (form_data->table);
6070     ChangeDataForTabColumnConfigListDialog (form_data->list_dlg, form_data->table->data.ptrvalue, blank_list);
6071     blank_list = ValNodeFree (blank_list);
6072   } else {
6073     /* build a new window */
6074     table = form_data->table;
6075     form_data->table = NULL;
6076 
6077     w = CreateTableReaderWindowWithTable (form_data->input_entityID, table, "Apply Qualifiers");
6078     /* get old configurations */
6079     if (form_data->list_dlg == NULL) {
6080       for (i = 0; i < form_data->num_columns; i++) {
6081         t = DialogToPointer (form_data->column_list[i]);
6082         ValNodeAddPointer (&columns, 0, t);
6083       }
6084     } else {
6085       columns = DialogToPointer (form_data->list_dlg);
6086     }
6087 
6088     /* apply to new window */
6089     new_form_data = (QualLoadFormPtr) GetObjectExtra (w);
6090     if (new_form_data->list_dlg == NULL) {
6091       for (i = 0, c_vnp = columns; i < new_form_data->num_columns && c_vnp != NULL; i++, c_vnp = c_vnp->next) {
6092         PointerToDialog (new_form_data->column_list[i], c_vnp->data.ptrvalue);
6093       }
6094     } else {
6095       PointerToDialog (new_form_data->list_dlg, columns);
6096     }
6097     columns = ValNodeFree (columns);
6098     SetStatus (new_form_data->remove_quotes, GetStatus (form_data->remove_quotes));
6099     SetStatus (new_form_data->leave_dlg_up, GetStatus (form_data->leave_dlg_up));
6100 
6101     /* remove old window */
6102     Remove ((WindoW) form_data->form);
6103 
6104     RealizeWindow (w);
6105     Show (w);
6106     Update ();
6107   }
6108 }
6109 
6110 
ReLoadTable(ButtoN b,Nlm_ReparseTabTable reparse_func)6111 static void ReLoadTable (ButtoN b, Nlm_ReparseTabTable reparse_func)
6112 {
6113   QualLoadFormPtr form_data;
6114 
6115   form_data = (QualLoadFormPtr) GetObjectExtra (b);
6116   if (form_data == NULL || reparse_func == NULL) return;
6117 
6118   reparse_func (form_data->table);
6119 
6120   ReDrawWindowAfterTableReload (form_data);
6121 }
6122 
6123 
ReloadFirstSpace(ButtoN b)6124 static void ReloadFirstSpace (ButtoN b)
6125 {
6126   ReLoadTable (b, ReparseTabTableConvertFirstSpaceToTab);
6127 }
6128 
6129 
ReloadMultiSpace(ButtoN b)6130 static void ReloadMultiSpace (ButtoN b)
6131 {
6132   ReLoadTable (b, ReparseTabTableConvertMultiSpaceToTab);
6133 }
6134 
6135 
ReparseForFileId(ValNodePtr table)6136 static void ReparseForFileId (ValNodePtr table)
6137 {
6138   ValNodePtr column_list = NULL;
6139   ValNodeAddInt (&column_list, 0, 0);
6140   ValNodeAddInt (&column_list, 0, 1);
6141   CombineTabTableColumns (table, column_list, "/");
6142 }
6143 
6144 
ReloadFileId(ButtoN b)6145 static void ReloadFileId (ButtoN b)
6146 {
6147   ReLoadTable (b, ReparseForFileId);
6148 }
6149 
6150 
SortVnpByInt(VoidPtr ptr1,VoidPtr ptr2)6151 static int LIBCALLBACK SortVnpByInt (VoidPtr ptr1, VoidPtr ptr2)
6152 
6153 {
6154   ValNodePtr  vnp1;
6155   ValNodePtr  vnp2;
6156 
6157   if (ptr1 == NULL || ptr2 == NULL) return 0;
6158   vnp1 = *((ValNodePtr PNTR) ptr1);
6159   vnp2 = *((ValNodePtr PNTR) ptr2);
6160   if (vnp1 == NULL || vnp2 == NULL) return 0;
6161 
6162   if (vnp1->data.intvalue > vnp2->data.intvalue) {
6163     return 1;
6164   } else if (vnp1->data.intvalue < vnp2->data.intvalue) {
6165     return -1;
6166   }
6167 
6168   return 0;
6169 }
6170 
6171 
CombineColumns(ButtoN b_in)6172 static void CombineColumns (ButtoN b_in)
6173 {
6174   WindoW w;
6175   GrouP  h, g, c;
6176   DialoG dlg;
6177   TexT   delimiter_txt;
6178   ValNodePtr options = NULL, vnp, combine_list = NULL;
6179   Int4       i;
6180   ButtoN b;
6181   ModalAcceptCancelData acd;
6182   QualLoadFormPtr form_data;
6183   CharPtr         label, delimiter;
6184 
6185   form_data = (QualLoadFormPtr) GetObjectExtra (b_in);
6186   if (form_data == NULL || form_data->table == NULL || form_data->table->data.ptrvalue == NULL) return;
6187 
6188   acd.accepted = FALSE;
6189   acd.cancelled = FALSE;
6190   acd.third_option = FALSE;
6191 
6192   w = ModalWindow(-20, -13, -10, -10, NULL);
6193   h = HiddenGroup (w, -1, 0, NULL);
6194   SetGroupSpacing (h, 10, 10);
6195 
6196   for (i = 0, vnp = form_data->table->data.ptrvalue;
6197        i < form_data->num_columns && vnp != NULL;
6198        i++, vnp = vnp->next)
6199   {
6200     label = (CharPtr) MemNew (sizeof (Char) * (StringLen (vnp->data.ptrvalue) + 15));
6201     sprintf (label, "%5d   %s", i + 1, (char *) vnp->data.ptrvalue);
6202     ValNodeAddPointer (&options, i, label);
6203   }
6204 
6205   dlg = ValNodeSelectionDialog (h, options, TALL_SELECTION_LIST, ValNodeStringName,
6206                                               ValNodeSimpleDataFree, ValNodeStringCopy,
6207                                               ValNodeStringMatch, "column",
6208                                               NULL, NULL, TRUE);
6209   g = HiddenGroup (h, 2, 0, NULL);
6210   SetGroupSpacing (g, 10, 10);
6211   StaticPrompt (g, "Delimiter", 0, popupMenuHeight, programFont, 'l');
6212   delimiter_txt = DialogText (g, ",", 5, NULL);
6213 
6214   c = HiddenGroup (h, 3, 0, NULL);
6215   SetGroupSpacing (c, 10, 10);
6216   b = PushButton (c, "Combine", ModalAcceptButton);
6217   SetObjectExtra (b, &acd, NULL);
6218   b = PushButton (c, "Cancel", ModalCancelButton);
6219   SetObjectExtra (b, &acd, NULL);
6220   AlignObjects (ALIGN_CENTER, (HANDLE) dlg, (HANDLE) g, (HANDLE) c, NULL);
6221 
6222   Show(w);
6223   Select (w);
6224   while (!acd.accepted && ! acd.cancelled)
6225   {
6226     ProcessExternalEvent ();
6227     Update ();
6228     ProcessAnEvent ();
6229     if (acd.accepted)
6230     {
6231       /* combine here */
6232       options = DialogToPointer (dlg);
6233       if (options == NULL || options->next == NULL) {
6234         Message (MSG_ERROR, "Must choose at least two columns!");
6235         acd.accepted = FALSE;
6236       } else {
6237         for (vnp = options; vnp != NULL; vnp = vnp->next) {
6238           ValNodeAddInt (&combine_list, 0, vnp->choice);
6239         }
6240         combine_list = ValNodeSort (combine_list, SortVnpByInt);
6241         delimiter = JustSaveStringFromText (delimiter_txt);
6242         CombineTabTableColumns (form_data->table, combine_list, delimiter);
6243         delimiter = MemFree (delimiter);
6244         combine_list = ValNodeFree (combine_list);
6245         ReDrawWindowAfterTableReload (form_data);
6246       }
6247       options = ValNodeFree (options);
6248     }
6249   }
6250   Remove (w);
6251 }
6252 
6253 
SeparateColumns(ButtoN b_in)6254 static void SeparateColumns (ButtoN b_in)
6255 {
6256   WindoW w;
6257   GrouP  h, g, c;
6258   DialoG dlg;
6259   TexT   delimiter_txt;
6260   ButtoN just_first_delimiter_btn;
6261   ValNodePtr options = NULL, vnp;
6262   Int4       i;
6263   ButtoN b;
6264   ModalAcceptCancelData acd;
6265   QualLoadFormPtr form_data;
6266   CharPtr         label, delimiter;
6267   Boolean         just_first_delimiter;
6268 
6269   form_data = (QualLoadFormPtr) GetObjectExtra (b_in);
6270   if (form_data == NULL || form_data->table == NULL || form_data->table->data.ptrvalue == NULL) return;
6271 
6272   acd.accepted = FALSE;
6273   acd.cancelled = FALSE;
6274   acd.third_option = FALSE;
6275 
6276   w = ModalWindow(-20, -13, -10, -10, NULL);
6277   h = HiddenGroup (w, -1, 0, NULL);
6278   SetGroupSpacing (h, 10, 10);
6279 
6280   for (i = 0, vnp = form_data->table->data.ptrvalue;
6281        i < form_data->num_columns && vnp != NULL;
6282        i++, vnp = vnp->next)
6283   {
6284     label = (CharPtr) MemNew (sizeof (Char) * (StringLen (vnp->data.ptrvalue) + 15));
6285     sprintf (label, "%5d   %s", i + 1, (char *) vnp->data.ptrvalue);
6286     ValNodeAddPointer (&options, i, label);
6287   }
6288 
6289   dlg = ValNodeSelectionDialog (h, options, TALL_SELECTION_LIST, ValNodeStringName,
6290                                               ValNodeSimpleDataFree, ValNodeStringCopy,
6291                                               ValNodeStringMatch, "column",
6292                                               NULL, NULL, TRUE);
6293   g = HiddenGroup (h, 2, 0, NULL);
6294   SetGroupSpacing (g, 10, 10);
6295   StaticPrompt (g, "Delimiter", 0, popupMenuHeight, programFont, 'l');
6296   delimiter_txt = DialogText (g, ",", 5, NULL);
6297 
6298   just_first_delimiter_btn = CheckBox (h, "Separate only at first delimiter", NULL);
6299 
6300   c = HiddenGroup (h, 3, 0, NULL);
6301   SetGroupSpacing (c, 10, 10);
6302   b = PushButton (c, "Separate", ModalAcceptButton);
6303   SetObjectExtra (b, &acd, NULL);
6304   b = PushButton (c, "Cancel", ModalCancelButton);
6305   SetObjectExtra (b, &acd, NULL);
6306   AlignObjects (ALIGN_CENTER, (HANDLE) dlg, (HANDLE) g, (HANDLE) c, NULL);
6307 
6308   Show(w);
6309   Select (w);
6310   while (!acd.accepted && ! acd.cancelled)
6311   {
6312     ProcessExternalEvent ();
6313     Update ();
6314     ProcessAnEvent ();
6315     if (acd.accepted)
6316     {
6317       /* combine here */
6318       options = DialogToPointer (dlg);
6319       if (options == NULL) {
6320         Message (MSG_ERROR, "Must choose at least one column!");
6321         acd.accepted = FALSE;
6322       } else {
6323         delimiter = JustSaveStringFromText (delimiter_txt);
6324         if (delimiter == NULL) {
6325           delimiter = StringSave (" ");
6326         }
6327         just_first_delimiter = GetStatus (just_first_delimiter_btn);
6328         for (vnp = options; vnp != NULL; vnp = vnp->next) {
6329           ReparseTabTableSeparateColumnAtDelimiter (form_data->table, *delimiter, vnp->choice, just_first_delimiter);
6330         }
6331         delimiter = MemFree (delimiter);
6332         ReDrawWindowAfterTableReload (form_data);
6333       }
6334       options = ValNodeFree (options);
6335     }
6336   }
6337   Remove (w);
6338 }
6339 
6340 
ShowTableReaderTable(ButtoN b)6341 static void ShowTableReaderTable (ButtoN b)
6342 {
6343   QualLoadFormPtr form_data;
6344   Char            path [PATH_MAX];
6345   FILE           *fp;
6346 
6347   form_data = (QualLoadFormPtr) GetObjectExtra (b);
6348   if (form_data == NULL || form_data->table == NULL) return;
6349 
6350   TmpNam (path);
6351   fp = FileOpen (path, "wb");
6352   if (fp == NULL) {
6353     Message (MSG_ERROR, "Unable to open temporary file %s", path);
6354     return;
6355   }
6356   WriteTabTableToFile (form_data->table, fp);
6357   FileClose (fp);
6358   LaunchGeneralTextViewer (path, "WARNING - Editing in this window will not be reflected in the table reader!");
6359   FileRemove (path);
6360 }
6361 
6362 
CreateTableReaderWindowWithTable(Uint2 entityID,ValNodePtr table,CharPtr window_title)6363 static WindoW CreateTableReaderWindowWithTable (Uint2 entityID, ValNodePtr table, CharPtr window_title)
6364 {
6365   ValNodePtr   blank_list;
6366   ValNodePtr   col_vnp, blank_vnp;
6367   Int4         index;
6368   WindoW        w;
6369   GrouP         h, g, g2, g3, g4, g5, g6, c;
6370   GrouP           btn_constraint_grp;
6371   GrouP           buttons_grp;
6372   QualLoadFormPtr form_data;
6373   CharPtr         title;
6374   Int4            col_for_list = 3;
6375   Char            buf[15];
6376   ButtoN          b;
6377 
6378   form_data = MemNew (sizeof (QualLoadFormData));
6379   if (form_data == NULL) return NULL;
6380   form_data->input_entityID = entityID;
6381   form_data->table = table;
6382   blank_list = CountTabTableBlanks (form_data->table);
6383   form_data->num_columns = ValNodeLen (blank_list);
6384   form_data->column_list = (DialoG PNTR) MemNew (sizeof (DialoG) * form_data->num_columns);
6385 
6386   /* now create a dialog to display values */
6387   w = FixedWindow (-50, -33, -10, -10, window_title, StdCloseWindowProc);
6388   SetObjectExtra (w, form_data, CleanupQualLoadForm);
6389   form_data->form = (ForM) w;
6390 
6391   h = HiddenGroup (w, -1, 0, NULL);
6392   SetGroupSpacing (h, 10, 10);
6393 
6394   if (GetSequinAppParam ("SETTINGS", "tablecolumns", NULL, buf, sizeof (buf))) {
6395     col_for_list = atoi (buf);
6396   }
6397 
6398   if (form_data->num_columns >= col_for_list) {
6399     form_data->list_dlg = TabColumnConfigListDialog (h, form_data->table->data.ptrvalue, blank_list, ChangeTabColumnChoice, form_data);
6400     g = (GrouP) form_data->list_dlg;
6401   } else {
6402     g = HiddenGroup (h, 3, 0, NULL);
6403     col_vnp = form_data->table->data.ptrvalue;
6404     blank_vnp = blank_list;
6405     for (index = 0; index < form_data->num_columns; index++) {
6406       if (col_vnp == NULL || StringHasNoText (col_vnp->data.ptrvalue)) {
6407         title = StringSave ("First row value is blank");
6408       } else {
6409         title = StringSave (col_vnp->data.ptrvalue);
6410         if (StringLen (title) > 104) {
6411           StringCpy (title + 100, "...");
6412           *(title + 103) = 0;
6413         }
6414       }
6415       form_data->column_list[index] = TabColumnConfigDialog (g, title, blank_vnp->data.intvalue, ChangeTabColumnChoice, form_data);
6416       title = MemFree (title);
6417       if (col_vnp != NULL) {
6418         col_vnp = col_vnp->next;
6419       }
6420       blank_vnp = blank_vnp->next;
6421     }
6422   }
6423 
6424   btn_constraint_grp = HiddenGroup (h, 2, 0, NULL);
6425   buttons_grp = HiddenGroup (btn_constraint_grp, -1, 0, NULL);
6426 
6427   g2 = HiddenGroup (buttons_grp, 3, 0, NULL);
6428   b = PushButton (g2, "Automatch Qualifiers", AutoMatchQuals);
6429   SetObjectExtra (b, form_data, NULL);
6430 
6431   /* J. Chen */
6432   b = PushButton (g2, "Rematch Qualifiers", ReMatchQuals);
6433   SetObjectExtra (b, form_data, NULL);
6434 
6435   b = PushButton (g2, "Reset Columns", ResetColumns);
6436   SetObjectExtra (b, form_data, NULL);
6437 
6438   g6 = HiddenGroup (buttons_grp, 2, 0, NULL);
6439   /* J. Chen */
6440   b = PushButton (g6, "Erase field when table cell is blank", EraseAllFieldsWhenBlank);
6441   SetObjectExtra(b, form_data, NULL);
6442 
6443   form_data->remove_quotes = CheckBox (g6, "Remove quotes around values", NULL);
6444   SetStatus (form_data->remove_quotes, TRUE); /* TRUE for checked, FALSE for unchecked, J.C. */
6445 
6446   g4 = HiddenGroup (buttons_grp, 8, 0, NULL);
6447   SetGroupSpacing (g4, 10, 10);
6448   b = PushButton (g4, "View Table (NO EDITING!)", ShowTableReaderTable);
6449   SetObjectExtra (b, form_data, NULL);
6450   g3 = HiddenGroup (buttons_grp, 3, 0, NULL);
6451   b = PushButton (g3, "Load New Table", LoadNewTable);
6452   SetObjectExtra (b, form_data, NULL);
6453   b = PushButton (g3, "Reload, 1st Space=Tab", ReloadFirstSpace);
6454   SetObjectExtra (b, form_data, NULL);
6455   b = PushButton (g3, "Reload, Mult Space=Tab", ReloadMultiSpace);
6456   SetObjectExtra (b, form_data, NULL);
6457   b = PushButton (g3, "Reload, Combine First Two for ID", ReloadFileId);
6458   SetObjectExtra (b, form_data, NULL);
6459   b = PushButton (g3, "Combine Columns", CombineColumns);
6460   SetObjectExtra (b, form_data, NULL);
6461   b = PushButton (g3, "Separate Columns", SeparateColumns);
6462   SetObjectExtra (b, form_data, NULL);
6463 
6464   AlignObjects (ALIGN_CENTER, (HANDLE) g2, (HANDLE) g6, (HANDLE) g4, (HANDLE) g3, NULL);
6465 
6466   g5 = NormalGroup(btn_constraint_grp, -1, 0, "Global Table Constraint", programFont, NULL);
6467   form_data->table_constraint = ConstraintSetDialog (g5, NULL, NULL);
6468   SetConstraintSetDefaultConstraintType(form_data->table_constraint, ConstraintChoice_pub);
6469 
6470   form_data->err_msg = StaticPrompt (h, "", 200, dialogTextHeight, systemFont, 'c');
6471   c = HiddenGroup (h, 7, 0, NULL);
6472   form_data->accept_button = DefaultButton (c, "Accept", DoAcceptQuals);
6473   SetObjectExtra (form_data->accept_button, form_data, NULL);
6474   Disable (form_data->accept_button);
6475   form_data->mail_button = DefaultButton (c, "Accept and Make Mail Report", SpecialMailReport);
6476   SetObjectExtra (form_data->mail_button, form_data, NULL);
6477   Disable (form_data->mail_button);
6478 
6479   PushButton (c, "Cancel", StdCancelButtonProc);
6480   form_data->leave_dlg_up = CheckBox (c, "Leave Dialog Up", NULL);
6481 
6482   AlignObjects (ALIGN_CENTER,
6483                 (HANDLE) g,
6484                 (HANDLE) btn_constraint_grp,
6485                 (HANDLE) form_data->err_msg,
6486                 (HANDLE) c, NULL);
6487 
6488   blank_list = ValNodeFree (blank_list);
6489   return w;
6490 }
6491 
6492 
CreateTableReaderWindowEx(Uint2 entityID,Boolean from_clipboard)6493 static WindoW CreateTableReaderWindowEx (Uint2 entityID, Boolean from_clipboard)
6494 {
6495   Char         path [PATH_MAX];
6496   FILE *fp;
6497 
6498   ValNodePtr   table;
6499   ValNodePtr   special_list;
6500   CharPtr      str;
6501 
6502   if (from_clipboard) {
6503     if (!Nlm_ClipboardHasString()) {
6504       Message (MSG_ERROR, "Clipboard is empty!");
6505       return NULL;
6506     }
6507     TmpNam (path);
6508     fp = FileOpen (path, "w");
6509     str = ClipboardToString();
6510     fprintf (fp, "%s", str);
6511     FileClose (fp);
6512     str = MemFree (str);
6513   } else if (! GetInputFileName (path, sizeof (path),"","TEXT")) {
6514     return NULL;
6515   }
6516   fp = FileOpen (path, "r");
6517   if (fp == NULL)
6518   {
6519     Message (MSG_ERROR, "Unable to open %s", path);
6520     if (from_clipboard) {
6521       FileRemove (path);
6522     }
6523     return NULL;
6524   }
6525 
6526   table = ReadTabTableFromFile (fp);
6527   FileClose (fp);
6528   if (from_clipboard) {
6529     FileRemove (path);
6530   }
6531   if (table == NULL) return NULL;
6532   special_list = ScanTabTableForSpecialCharacters (table);
6533   if (special_list != NULL
6534       && !FixSpecialCharactersForStringsInList (special_list,
6535                                                 "The table contains special characters\nand cannot be used until they are replaced.",
6536                                                 FALSE)) {
6537     special_list = FreeContextList (special_list);
6538     table = FreeTabTable (table);
6539     return NULL;
6540   }
6541   special_list = FreeContextList (special_list);
6542 
6543   return CreateTableReaderWindowWithTable (entityID, table, "Apply Qualifiers");
6544 }
6545 
6546 
CreateTableReaderWindow(Uint2 entityID)6547 static WindoW CreateTableReaderWindow (Uint2 entityID)
6548 {
6549   return CreateTableReaderWindowEx (entityID, FALSE);
6550 }
6551 
6552 
NewLoadFeatureQualifierTableEntityID(Uint2 entityID,Boolean from_clipboard)6553 static void NewLoadFeatureQualifierTableEntityID (Uint2 entityID, Boolean from_clipboard)
6554 {
6555   WindoW        w;
6556   QualLoadFormPtr form_data;
6557   TabColumnConfigPtr t;
6558   ValNodePtr         column_list = NULL;
6559 
6560 
6561   w = CreateTableReaderWindowEx (entityID, from_clipboard);
6562 
6563   if (w != NULL) {
6564     /* populate */
6565     form_data = (QualLoadFormPtr) GetObjectExtra (w);
6566     if (form_data != NULL) {
6567       t = TabColumnConfigNew ();
6568       t->match_type = MatchTypeNew ();
6569       t->match_type->match_location = eTableMatchNucID;
6570       if (form_data->list_dlg == NULL) {
6571         PointerToDialog (form_data->column_list[0], t);
6572       } else {
6573         ValNodeAddPointer (&column_list, 0, t);
6574         PointerToDialog (form_data->list_dlg, column_list);
6575         column_list = ValNodeFree (column_list);
6576       }
6577       t = TabColumnConfigFree (t);
6578     }
6579 
6580     RealizeWindow (w);
6581     Show (w);
6582     Update ();
6583   }
6584 }
6585 
6586 
NewLoadFeatureQualifierTable(IteM i)6587 extern void NewLoadFeatureQualifierTable (IteM i)
6588 {
6589   BaseFormPtr  bfp;
6590 
6591 #ifdef WIN_MAC
6592   bfp = currentFormDataPtr;
6593 #else
6594   bfp = GetObjectExtra (i);
6595 #endif
6596   if (bfp == NULL) return;
6597   NewLoadFeatureQualifierTableEntityID (bfp->input_entityID, FALSE);
6598 }
6599 
6600 
NewLoadFeatureQualifierTableFromClipboard(IteM i)6601 extern void NewLoadFeatureQualifierTableFromClipboard (IteM i)
6602 {
6603   BaseFormPtr  bfp;
6604 
6605 #ifdef WIN_MAC
6606   bfp = currentFormDataPtr;
6607 #else
6608   bfp = GetObjectExtra (i);
6609 #endif
6610   if (bfp == NULL) return;
6611   NewLoadFeatureQualifierTableEntityID (bfp->input_entityID, TRUE);
6612 }
6613 
6614 
NewLoadFeatureQualifierTableToolBtn(ButtoN b)6615 NLM_EXTERN void NewLoadFeatureQualifierTableToolBtn (ButtoN b)
6616 {
6617   BaseFormPtr  bfp;
6618 
6619   bfp = (BaseFormPtr) GetObjectExtra (b);
6620   if (bfp == NULL) return;
6621   NewLoadFeatureQualifierTableEntityID (bfp->input_entityID, FALSE);
6622 }
6623 
6624 
NewLoadFeatureQualifierTableClipToolBtn(ButtoN b)6625 NLM_EXTERN void NewLoadFeatureQualifierTableClipToolBtn (ButtoN b)
6626 {
6627   BaseFormPtr  bfp;
6628 
6629   bfp = (BaseFormPtr) GetObjectExtra (b);
6630   if (bfp == NULL) return;
6631   NewLoadFeatureQualifierTableEntityID (bfp->input_entityID, TRUE);
6632 }
6633 
6634 
CreateTableReaderWindowWithStructuredComments(IteM i)6635 NLM_EXTERN void CreateTableReaderWindowWithStructuredComments (IteM i)
6636 {
6637   BaseFormPtr  bfp;
6638   WindoW        w;
6639   QualLoadFormPtr form_data;
6640   TabColumnConfigPtr t;
6641   ValNodePtr         table, column_list = NULL;
6642 
6643 #ifdef WIN_MAC
6644   bfp = currentFormDataPtr;
6645 #else
6646   bfp = GetObjectExtra (i);
6647 #endif
6648   if (bfp == NULL) return;
6649 
6650   table = CreateStructuredCommentTableFromSeqEntry(GetTopSeqEntryForEntityID(bfp->input_entityID));
6651   if (table == NULL) {
6652     Message (MSG_ERROR, "Record contains no structured comments");
6653     return;
6654   }
6655   w = CreateTableReaderWindowWithTable (bfp->input_entityID, table, "Parse from Structured Comment");
6656 
6657   if (w != NULL) {
6658     /* populate */
6659     form_data = (QualLoadFormPtr) GetObjectExtra (w);
6660     if (form_data != NULL) {
6661       t = TabColumnConfigNew ();
6662       t->match_type = MatchTypeNew ();
6663       t->match_type->match_location = eTableMatchNucID;
6664       if (form_data->list_dlg == NULL) {
6665         PointerToDialog (form_data->column_list[0], t);
6666       } else {
6667         ValNodeAddPointer (&column_list, 0, t);
6668         PointerToDialog (form_data->list_dlg, column_list);
6669         column_list = ValNodeFree (column_list);
6670       }
6671       t = TabColumnConfigFree (t);
6672     }
6673 
6674     RealizeWindow (w);
6675     Show (w);
6676     Update ();
6677   }
6678 }
6679 
6680 
LoadTaxTableReaderBaseForm(BaseFormPtr bfp)6681 static void LoadTaxTableReaderBaseForm (BaseFormPtr bfp)
6682 {
6683   WindoW        w;
6684   QualLoadFormPtr form_data;
6685   TabColumnConfigPtr t;
6686   ValNodePtr         column_list = NULL, s;
6687 
6688   if (bfp == NULL) return;
6689 
6690   w = CreateTableReaderWindow (bfp->input_entityID);
6691 
6692   if (w != NULL) {
6693     /* populate */
6694     form_data = (QualLoadFormPtr) GetObjectExtra (w);
6695     if (form_data != NULL) {
6696       if (form_data->list_dlg == NULL) {
6697         if (form_data->num_columns > 1) {
6698           t = TabColumnConfigNew ();
6699           t->match_type = MatchTypeNew ();
6700           t->match_type->choice = eTableMatchBioSource;
6701           PointerToDialog (form_data->column_list[0], t);
6702           t->match_type = MatchTypeFree(t->match_type);
6703           t->field = ValNodeNew(NULL);
6704           t->field->choice = FieldType_source_qual;
6705           s = ValNodeNew (NULL);
6706           t->field->data.ptrvalue = s;
6707           s->choice = SourceQualChoice_textqual;
6708           s->data.intvalue = Source_qual_taxname;
6709           PointerToDialog (form_data->column_list[1], t);
6710           t = TabColumnConfigFree(t);
6711         }
6712       } else {
6713         t = TabColumnConfigNew ();
6714         t->match_type = MatchTypeNew ();
6715         t->match_type->choice = eTableMatchBioSource;
6716         PointerToDialog (form_data->column_list[0], t);
6717         ValNodeAddPointer (&column_list, 0, t);
6718         t = TabColumnConfigNew ();
6719         t->field = ValNodeNew(NULL);
6720         t->field->choice = FieldType_source_qual;
6721         s = ValNodeNew (NULL);
6722         t->field->data.ptrvalue = s;
6723         s->choice = SourceQualChoice_textqual;
6724         s->data.intvalue = Source_qual_taxname;
6725         ValNodeAddPointer (&column_list, 0, t);
6726         PointerToDialog (form_data->list_dlg, column_list);
6727         column_list = TabColumnConfigListFree (column_list);
6728       }
6729     }
6730 
6731     RealizeWindow (w);
6732     Show (w);
6733     Update ();
6734   }
6735 }
6736 
6737 
LoadTaxTableReader(IteM i)6738 extern void LoadTaxTableReader (IteM i)
6739 {
6740   ButtonOrMenuItemTemplate (i, LoadTaxTableReaderBaseForm);
6741 }
6742 
6743 
LoadTaxTableReaderBtn(ButtoN b)6744 extern void LoadTaxTableReaderBtn (ButtoN b)
6745 {
6746   ButtonOrMenuButtonTemplate (b, LoadTaxTableReaderBaseForm);
6747 }
6748 
6749 
NewLoadSourceQualifierTable(IteM i)6750 extern void NewLoadSourceQualifierTable (IteM i)
6751 {
6752   BaseFormPtr  bfp;
6753   WindoW        w;
6754   QualLoadFormPtr form_data;
6755   TabColumnConfigPtr t1, t2;
6756   ValNodePtr         column_list = NULL, vnp;
6757   Int4               n;
6758 
6759 #ifdef WIN_MAC
6760   bfp = currentFormDataPtr;
6761 #else
6762   bfp = GetObjectExtra (i);
6763 #endif
6764   if (bfp == NULL) return;
6765 
6766   w = CreateTableReaderWindow (bfp->input_entityID);
6767 
6768   if (w != NULL) {
6769     /* populate */
6770     form_data = (QualLoadFormPtr) GetObjectExtra (w);
6771     if (form_data != NULL) {
6772       t1 = TabColumnConfigNew ();
6773       t1->match_type = MatchTypeNew ();
6774       t1->match_type->match_location = eTableMatchNucID;
6775       t2 = TabColumnConfigNew ();
6776       vnp = ValNodeNew (NULL);
6777       vnp->choice = SourceQualChoice_textqual;
6778       vnp->data.intvalue = Source_qual_acronym;
6779       t2->field = ValNodeNew (NULL);
6780       t2->field->choice = FieldType_source_qual;
6781       t2->field->data.ptrvalue = vnp;
6782 
6783       if (form_data->list_dlg == NULL) {
6784         PointerToDialog (form_data->column_list[0], t1);
6785         PointerToDialog (form_data->column_list[1], t2);
6786       } else {
6787         ValNodeAddPointer (&column_list, 0, t1);
6788         for (n = 1; n < form_data->num_columns; n++) {
6789           ValNodeAddPointer (&column_list, 0, t2);
6790         }
6791         PointerToDialog (form_data->list_dlg, column_list);
6792         column_list = ValNodeFree (column_list);
6793       }
6794       t1 = TabColumnConfigFree (t1);
6795       t2 = TabColumnConfigFree (t2);
6796     }
6797 
6798     RealizeWindow (w);
6799     Show (w);
6800     Update ();
6801   }
6802 }
6803 
6804 
ExternalSourceQualifierTableReader(IteM i)6805 extern void ExternalSourceQualifierTableReader (IteM i)
6806 {
6807   Char         path [PATH_MAX];
6808   BaseFormPtr  bfp;
6809   ValNodePtr   table, columns = NULL, header_row, val;
6810   TabColumnConfigPtr t;
6811   LogInfoPtr         lip;
6812   Boolean            any_valid = FALSE;
6813   MsgAnswer          ans = ANS_OK;
6814   SeqEntryPtr        sep;
6815   FILE *fp;
6816 
6817 #ifdef WIN_MAC
6818   bfp = currentFormDataPtr;
6819 #else
6820   bfp = GetObjectExtra (i);
6821 #endif
6822   if (bfp == NULL || bfp->input_entityID == 0) return;
6823 
6824   path [0] = '\0';
6825   if (! GetInputFileName (path, sizeof (path), NULL, "TEXT")) return;
6826 
6827   fp = FileOpen (path, "r");
6828   if (fp == NULL) {
6829     Message (MSG_ERROR, "Unable to read from %s", path);
6830     return;
6831   }
6832 
6833   table = ReadTabTableFromFile (fp);
6834   FileClose (fp);
6835   if (table == NULL) {
6836     Message (MSG_ERROR, "Unable to read table from %s", path);
6837     return;
6838   }
6839 
6840   RemoveQuotesFromTabTable (table);
6841 
6842   /* first column is sequence ID */
6843   t = TabColumnConfigNew ();
6844   t->match_type = MatchTypeNew ();
6845   t->match_type->match_location = eTableMatchNucID;
6846   ValNodeAddPointer (&columns, 0, t);
6847 
6848   lip = OpenLog ("Table Problems");
6849   fprintf (lip->fp, "The following header values could not be matched to valid qualifier names.  They will be ignored.\n");
6850 
6851   /* automatch qualifiers */
6852   header_row = table->data.ptrvalue;
6853   if (header_row == NULL) {
6854     Message (MSG_ERROR, "First row of table must contain headers!");
6855   } else {
6856     for (val = header_row->next;
6857          val != NULL;
6858          val = val->next) {
6859       t = TabColumnConfigNew ();
6860       t->field = FieldTypeFromString (val->data.ptrvalue);
6861       if (t->field == NULL) {
6862         t = TabColumnConfigFree (t);
6863         fprintf (lip->fp, "%s\n", (CharPtr) val->data.ptrvalue);
6864         lip->data_in_log = TRUE;
6865       } else {
6866         any_valid = TRUE;
6867       }
6868       ValNodeAddPointer (&columns, 0, t);
6869     }
6870   }
6871 
6872   CloseLog (lip);
6873   if (lip->data_in_log) {
6874     ans = Message (MSG_OKC, "Some column headers were not recognized.  The values in this column will be ignored.  Continue anyway?");
6875   }
6876   lip = FreeLog (lip);
6877 
6878   if (ans == ANS_OK) {
6879     sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6880     if (ApplyTableValues (sep, table->next, columns)) {
6881       ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6882       ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
6883       Update();
6884     }
6885   }
6886   columns = TabColumnConfigListFree (columns);
6887   table = FreeTabTable (table);
6888 }
6889 
6890 
6891 typedef struct prefixformdata {
6892   FEATURE_FORM_BLOCK
6893 
6894   ModifierItemLocalPtr modList;
6895   PopuP PNTR           popup_list;
6896   ButtoN               add_org_name;
6897   ButtoN               use_labels;
6898 } PrefixFormData, PNTR PrefixFormPtr;
6899 
CleanupPrefixForm(GraphiC g,VoidPtr data)6900 static void CleanupPrefixForm (
6901   GraphiC g,
6902   VoidPtr data
6903 )
6904 
6905 {
6906   PrefixFormPtr  pfp;
6907   Int4           i;
6908 
6909   pfp = (PrefixFormPtr) data;
6910   if (pfp != NULL) {
6911     if (pfp->modList != NULL)
6912     {
6913       for (i=0; i < NumDefLineModifiers (); i++)
6914       {
6915         ValNodeFree (pfp->modList[i].values_seen);
6916       }
6917       MemFree (pfp->modList);
6918     }
6919     if (pfp->popup_list != NULL)
6920     {
6921       MemFree (pfp->popup_list);
6922     }
6923   }
6924   StdCleanupFormProc (g, data);
6925 }
6926 
GetDefLineModifierPopupIndex(Int4 popup_index,ModifierItemLocalPtr modList)6927 static Int4 GetDefLineModifierPopupIndex (
6928   Int4 popup_index,
6929   ModifierItemLocalPtr modList
6930 )
6931 {
6932   Int4 index;
6933   Int4 want_index;
6934 
6935   want_index = 0;
6936   for (index = 0;
6937        index < NumDefLineModifiers () && want_index < popup_index;
6938        index++)
6939   {
6940     if (modList [index].any_present)
6941     {
6942       want_index ++;
6943     }
6944   }
6945   if (index >= NumDefLineModifiers () || index == 0
6946     || want_index < popup_index)
6947   {
6948     return -1;
6949   }
6950   return index - 1;
6951 }
6952 
AddPrefixesToOneDefLine(PrefixFormPtr pfp,BioseqPtr bsp,SeqEntryPtr sep)6953 static void AddPrefixesToOneDefLine (
6954   PrefixFormPtr pfp,
6955   BioseqPtr bsp,
6956   SeqEntryPtr sep
6957 )
6958 {
6959   BioSourcePtr biop;
6960   SeqDescrPtr  sdp;
6961   ValNodePtr   strings;
6962   Int4         index;
6963   Int4         qual_index;
6964   Int4         popup_choice;
6965   CharPtr      new_defline;
6966   Char         taxName [196];
6967   Char         modifier_text [256];
6968   OrgRefPtr    orp;
6969   OrgNamePtr   onp;
6970   OrgModPtr    mod;
6971   SubSourcePtr ssp;
6972   CharPtr  org_desc;
6973   CharPtr  cp;
6974   SeqMgrDescContext  dcontext;
6975   Boolean      use_labels;
6976   Uint4        no_semicolon_len;
6977   Int4         prefix_len;
6978 
6979   if (bsp == NULL || pfp == NULL
6980     || pfp->popup_list == NULL
6981     || pfp->modList == NULL
6982     || (biop = GetBiopForBsp (bsp)) == NULL)
6983   {
6984     return;
6985   }
6986 
6987   if (biop->org == NULL) return;
6988   if (biop->org->taxname == NULL) return;
6989   StringNCpy (taxName, biop->org->taxname, sizeof (taxName) - 1);
6990   taxName [ sizeof (taxName) - 1] = 0;
6991 
6992   strings = NULL;
6993   CleanUpTaxName (taxName, TRUE);
6994   if (GetStatus (pfp->add_org_name))
6995   {
6996     ValNodeCopyStr( &strings, 0, taxName);
6997   }
6998 
6999   use_labels = GetStatus (pfp->use_labels);
7000 
7001   orp = biop->org;
7002   if (orp == NULL) return;
7003   onp = orp->orgname;
7004   if (onp == NULL) return;
7005   for (index = 0; index < NumDefLineModifiers (); index ++)
7006   {
7007     if (pfp->popup_list [ index] != NULL
7008       && (popup_choice = GetValue (pfp->popup_list [ index])) > 0)
7009     {
7010       qual_index = GetDefLineModifierPopupIndex (popup_choice, pfp->modList);
7011       if (qual_index < 0 || qual_index >= NumDefLineModifiers ()) continue;
7012       if (DefLineModifiers[qual_index].isOrgMod)
7013       {
7014         mod = onp->mod;
7015         while (mod != NULL
7016           && mod->subtype != DefLineModifiers[qual_index].subtype)
7017         {
7018           mod = mod->next;
7019         }
7020         if ( mod != NULL && UseOrgModifier (mod, taxName, FALSE))
7021         {
7022           no_semicolon_len = StringCSpn (mod->subname, ";");
7023           if (mod->subtype == ORGMOD_nat_host)
7024           {
7025             sprintf (modifier_text, "from ");
7026             if (no_semicolon_len > sizeof (modifier_text) - 6) {
7027               prefix_len = sizeof (modifier_text) - 1;
7028               no_semicolon_len = sizeof (modifier_text) - 6;
7029             } else {
7030 	            prefix_len = no_semicolon_len + 5;
7031             }
7032             StringNCpy (modifier_text + 5, mod->subname, no_semicolon_len);
7033             modifier_text[prefix_len] = 0;
7034           }
7035           else
7036           {
7037             AddModifierLabel (use_labels, TRUE, mod->subtype, modifier_text);
7038             if (modifier_text[0] != 0)
7039               StringCat (modifier_text, " ");
7040             if (no_semicolon_len > sizeof (modifier_text) - StringLen (modifier_text) - 1) {
7041               no_semicolon_len = sizeof (modifier_text) - StringLen (modifier_text) - 1;
7042 	            prefix_len = sizeof (modifier_text) - 1;
7043             } else {
7044 	            prefix_len = no_semicolon_len + StringLen (modifier_text);
7045             }
7046 
7047             StringNCat (modifier_text, mod->subname, no_semicolon_len);
7048             modifier_text[prefix_len] = 0;
7049           }
7050           ValNodeCopyStr( &strings, 0, modifier_text);
7051         }
7052       } else {
7053         ssp = biop->subtype;
7054         while (ssp != NULL
7055             && ssp->subtype != DefLineModifiers[qual_index].subtype)
7056         {
7057           ssp = ssp->next;
7058         }
7059         if (ssp != NULL && UseSubSrcModifier(ssp, taxName, FALSE))
7060         {
7061           no_semicolon_len = StringCSpn (ssp->name, ";");
7062           AddModifierLabel (use_labels, FALSE, ssp->subtype, modifier_text);
7063           if (ssp->subtype == SUBSRC_country)
7064           {
7065             sprintf (modifier_text, "from ");
7066             if (no_semicolon_len > sizeof (modifier_text) - 6) {
7067               no_semicolon_len = sizeof (modifier_text) - 6;
7068 			        prefix_len = sizeof(modifier_text);
7069 			      } else {
7070 			        prefix_len = StringLen (modifier_text) + no_semicolon_len;
7071 			      }
7072             StringNCpy (modifier_text + 5, ssp->name, no_semicolon_len);
7073             modifier_text[prefix_len] = 0;
7074             cp = StringChr (modifier_text, ':');
7075             if (cp != NULL) *cp = 0;
7076           }
7077           else if (ssp->name != NULL
7078             && (ssp->subtype != SUBSRC_plasmid_name
7079               || StringCmp (ssp->name, "unnamed") != 0))
7080           {
7081             if (modifier_text[0] != 0)
7082               StringCat (modifier_text, " ");
7083             if (no_semicolon_len > sizeof (modifier_text) - StringLen (modifier_text) - 1) {
7084               no_semicolon_len = sizeof (modifier_text) - StringLen (modifier_text) - 1;
7085 			  prefix_len = sizeof (modifier_text);
7086 			} else {
7087 			  prefix_len = StringLen (modifier_text) + no_semicolon_len;
7088 			}
7089 
7090             StringNCat (modifier_text, ssp->name, no_semicolon_len);
7091             modifier_text[prefix_len] = 0;
7092           }
7093           ValNodeCopyStr( &strings, 0, modifier_text);
7094         }
7095       }
7096     }
7097   }
7098   org_desc = MergeValNodeStrings (strings, FALSE);
7099   ValNodeFreeData (strings);
7100 
7101   sdp = SeqEntryGetSeqDescr (sep, Seq_descr_title, NULL);
7102   if (sdp == NULL) {
7103     sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_title, &dcontext);
7104     if (sdp == NULL) return;
7105     cp = (CharPtr) sdp->data.ptrvalue;
7106     if (cp == NULL) return;
7107     sdp = SeqDescrAdd (&(bsp->descr));
7108     if (sdp == NULL) return;
7109     sdp->choice = Seq_descr_title;
7110     sdp->data.ptrvalue = StringSave (cp);
7111   }
7112   if (sdp == NULL) return;
7113   if (StringHasNoText (sdp->data.ptrvalue)) return;
7114   new_defline = MemNew ((StringLen (org_desc)
7115                         + StringLen (sdp->data.ptrvalue) + 4) * sizeof (Char));
7116   if (new_defline == NULL) return;
7117   StringCpy (new_defline, org_desc);
7118   StringCat (new_defline, " ");
7119   StringCat (new_defline, sdp->data.ptrvalue);
7120   MemFree (sdp->data.ptrvalue);
7121   sdp->data.ptrvalue = new_defline;
7122   ObjMgrSetDirtyFlag (pfp->input_entityID, TRUE);
7123 }
7124 
AddPrefixesToDefLines(PrefixFormPtr pfp,SeqEntryPtr sep)7125 static void AddPrefixesToDefLines (PrefixFormPtr pfp, SeqEntryPtr sep)
7126 {
7127   BioseqSetPtr bssp;
7128   if (pfp == NULL || sep == NULL) return;
7129   if (IS_Bioseq_set (sep)) {
7130     bssp = (BioseqSetPtr) sep->data.ptrvalue;
7131     if (bssp != NULL) {
7132       for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
7133         AddPrefixesToDefLines (pfp, sep);
7134       }
7135       return;
7136     }
7137   }
7138   if (! IS_Bioseq (sep)) return;
7139   AddPrefixesToOneDefLine (pfp, sep->data.ptrvalue, sep);
7140 }
7141 
DoPrefixDefLines(ButtoN b)7142 static void DoPrefixDefLines (ButtoN b)
7143 {
7144   PrefixFormPtr pfp;
7145   SeqEntryPtr   sep;
7146 
7147   pfp = GetObjectExtra (b);
7148   if (pfp == NULL) return;
7149 
7150   Hide (pfp->form);
7151   WatchCursor ();
7152   Update ();
7153   sep = GetTopSeqEntryForEntityID (pfp->input_entityID);
7154   if (sep == NULL) return;
7155   AddPrefixesToDefLines (pfp, sep);
7156 
7157   ArrowCursor ();
7158   Update ();
7159   ObjMgrSetDirtyFlag (pfp->input_entityID, TRUE);
7160   ObjMgrSendMsg (OM_MSG_UPDATE, pfp->input_entityID, 0, 0);
7161 }
7162 
PrefixDefLines(IteM i)7163 extern void PrefixDefLines (IteM i)
7164 {
7165   BaseFormPtr  bfp;
7166   SeqEntryPtr  sep;
7167   ModifierItemLocalPtr modList;
7168   Int4         index;
7169   WindoW       w;
7170   GrouP        h, g, k;
7171   Int4         popup_index, item_index, listed_index;
7172   GrouP        c;
7173   ButtoN       b;
7174   PrefixFormPtr pfp;
7175   Char         label [256];
7176 
7177 #ifdef WIN_MAC
7178   bfp = currentFormDataPtr;
7179 #else
7180   bfp = GetObjectExtra (i);
7181 #endif
7182   if (bfp == NULL || bfp->input_entityID == 0) return;
7183 
7184   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
7185   if (sep == NULL) return;
7186 
7187   modList = MemNew (NumDefLineModifiers () * sizeof (ModifierItemLocalData));
7188   if (modList == NULL) return;
7189   CountModifiers (modList, sep);
7190 
7191   pfp = MemNew (sizeof (PrefixFormData));
7192   if (pfp == NULL) return;
7193   pfp->input_entityID = bfp->input_entityID;
7194   pfp->modList = modList;
7195   pfp->popup_list = MemNew (sizeof (PopuP) * NumDefLineModifiers ());
7196   if (pfp->popup_list == NULL) return;
7197 
7198   w = FixedWindow (-50, -33, -10, -10, "Definition Line Prefixes",
7199                    StdCloseWindowProc);
7200   SetObjectExtra (w, pfp, CleanupPrefixForm);
7201   pfp->form = (ForM) w;
7202 
7203   h = HiddenGroup (w, -1, 0, NULL);
7204   SetGroupSpacing (h, 10, 10);
7205   g = HiddenGroup (h, 4, 0, NULL);
7206   for (index = 0; index < NumDefLineModifiers (); index++)
7207   {
7208     pfp->popup_list [index] = NULL;
7209   }
7210   popup_index = 0;
7211   for (index = 0; index < NumDefLineModifiers (); index++)
7212   {
7213     if (modList [ index].any_present)
7214     {
7215       k = HiddenGroup (g, 2, 0, NULL);
7216       sprintf (label, "%d", popup_index + 1);
7217       StaticPrompt (k, label, 0, popupMenuHeight, programFont, 'l');
7218       pfp->popup_list[popup_index] = PopupList (k, TRUE, NULL);
7219       listed_index = 0;
7220       for (item_index = 0; item_index < NumDefLineModifiers (); item_index ++)
7221       {
7222         if (modList [item_index].any_present)
7223         {
7224           PopupItem (pfp->popup_list[popup_index],
7225                    DefLineModifiers[item_index].name);
7226           listed_index ++;
7227         }
7228       }
7229       PopupItem (pfp->popup_list[popup_index], "Ignore");
7230       listed_index++;
7231       SetValue (pfp->popup_list[popup_index], listed_index);
7232       popup_index ++;
7233     }
7234   }
7235 
7236   pfp->add_org_name = CheckBox (h, "Prefix with taxonomy name", NULL);
7237   SetStatus (pfp->add_org_name, TRUE);
7238   pfp->use_labels = CheckBox (h, "Use modifier labels", NULL);
7239   SetStatus (pfp->use_labels, TRUE);
7240 
7241   c = HiddenGroup (h, 4, 0, NULL);
7242   b = DefaultButton (c, "Accept", DoPrefixDefLines);
7243   SetObjectExtra (b, pfp, NULL);
7244   PushButton (c, "Cancel", StdCancelButtonProc);
7245 
7246   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) pfp->add_org_name,
7247                 (HANDLE) pfp->use_labels,
7248                 (HANDLE) c, NULL);
7249   RealizeWindow (w);
7250   Show (w);
7251   Update ();
7252 
7253 }
7254 
7255 #ifndef WIN16
7256 CharPtr objPrtMemStr = "PrintTemplateSet ::= {\n" \
7257 "{ name \"StdSeqDesc\" ,\n" \
7258 "format { asn1 \"Seqdesc\" , form block {\n" \
7259 "components {\n" \
7260 "{ asn1 \"Seqdesc.mol-type\" , label \"Molecule type\" , prefix \"\\n\" , form enum { } } ,\n" \
7261 "{ asn1 \"Seqdesc.modif\" , label \"Modifiers\" , prefix \"\\n\" , form block {\n" \
7262 "separator \", \" ,\n" \
7263 "components {\n" \
7264 "{ asn1 \"Seqdesc.modif.E\" , form enum { } } } } } ,\n" \
7265 "{ asn1 \"Seqdesc.method\" , label \"Method\" , prefix \"\\n\" , form enum { } } ,\n" \
7266 "{ asn1 \"Seqdesc.name\" , label \"Name\" , prefix \"\\n\" , form text { } } ,\n" \
7267 "{ asn1 \"Seqdesc.title\" , label \"Title\" , prefix \"\\n\" , form text { } } ,\n" \
7268 "{ asn1 \"Seqdesc.org\" , label \"Organism\" , prefix \"\\n\" , form use-template \"StdOrgRef\" } ,\n" \
7269 "{ asn1 \"Seqdesc.comment\" , label \"Comment\" , prefix \"\\n\" , form text { } } ,\n" \
7270 "{ asn1 \"Seqdesc.num\" , label \"Numbering\" , prefix \"\\n\" , form use-template \"StdNumbering\" } ,\n" \
7271 "{ asn1 \"Seqdesc.maploc\" , label \"Map location\" , prefix \"\\n\" , form use-template \"StdDbtag\" } ,\n" \
7272 "{ asn1 \"Seqdesc.pir\" , label \"PIR block\" , prefix \"\\n\" , form null NULL } ,\n" \
7273 "{ asn1 \"Seqdesc.genbank\" , label \"GenBank block\" , prefix \"\\n\" , form use-template \"StdGBBlock\" } ,\n" \
7274 "{ asn1 \"Seqdesc.pub\" , label \"Citation\" , prefix \"\\n\" , form use-template \"StdPubdesc\" } ,\n" \
7275 "{ asn1 \"Seqdesc.region\" , label \"Region\" , prefix \"\\n\" , form text { } } ,\n" \
7276 "{ asn1 \"Seqdesc.user\" , label \"User Type\" , prefix \"\\n\" , form use-template \"StdUserObj\" } ,\n" \
7277 "{ asn1 \"Seqdesc.sp\" , label \"SWISS-PROT block\" , prefix \"\\n\" , form null NULL } ,\n" \
7278 "{ asn1 \"Seqdesc.dbxref\" , label \"Cross reference\" , prefix \"\\n\" , form use-template \"StdDbtag\"  } ,\n" \
7279 "{ asn1 \"Seqdesc.embl\" , label \"EMBL block\" , prefix \"\\n\" , form null NULL } ,\n" \
7280 "{ asn1 \"Seqdesc.create-date\" , label \"Create date\" , prefix \"\\n\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
7281 "{ asn1 \"Seqdesc.update-date\" , label \"Update date\" , prefix \"\\n\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
7282 "{ asn1 \"Seqdesc.prf\" , label \"PRF block\" , prefix \"\\n\" , form null NULL } ,\n" \
7283 "{ asn1 \"Seqdesc.pdb\" , label \"PDB block\" , prefix \"\\n\" , form null NULL } ,\n" \
7284 "{ asn1 \"Seqdesc.het\" , label \"Heterogen\" , prefix \"\\n\" , form text { } } ,\n" \
7285 "{ asn1 \"Seqdesc.source\" , label \"Biological Source\" , prefix \"\\n\" , form use-template \"StdBioSource\" } ,\n" \
7286 "{ asn1 \"Seqdesc.molinfo\" , label \"Molecule Information\" , prefix \"\\n\" , form block {\n" \
7287 "separator \", \" ,\n" \
7288 "components {\n" \
7289 "{ asn1 \"MolInfo.biomol\" , form enum { } } ,\n" \
7290 "{ asn1 \"MolInfo.tech\" , form enum { } } ,\n" \
7291 "{ asn1 \"MolInfo.completeness\" , form enum { } } } } } } } } } ,\n" \
7292 "{ name \"StdSeqFeatLocation\" ,\n" \
7293 "format { asn1 \"Seq-feat.location\" , label \"Location\" , prefix \"\\t\" , form user { printfunc \"StdSeqLocPrint\" } } } ,\n" \
7294 "{ name \"StdSeqFeatProduct\" ,\n" \
7295 "format { asn1 \"Seq-feat.product\" , label \"Product\" , prefix \"\\t\" , form user { printfunc \"StdSeqLocPrint\" } } } ,\n" \
7296 "{ name \"EntrySeqFeatData\" ,\n" \
7297 "labelfrom \"Seq-feat.data\" ,\n" \
7298 "format { asn1 \"Seq-feat.data\" , prefix \"\\t\" , form use-template \"StdSeqFeatData\" } } ,\n" \
7299 "{ name \"StdSeqFeat\" ,\n" \
7300 "labelfrom \"Seq-feat.data\" ,\n" \
7301 "format { asn1 \"Seq-feat\" , prefix \"\\n\" , suffix \"\\n\" , form block {\n" \
7302 "separator \"\\n\" ,\n" \
7303 "components {\n" \
7304 "{ asn1 \"Seq-feat.data\" , form use-template \"StdSeqFeatData\" } ,\n" \
7305 "{ asn1 \"Seq-feat\" , form use-template \"StdSeqFeatCommon\" } ,\n" \
7306 "{ asn1 \"Seq-feat.product\" , label \"Product\" , prefix \" \" , form user { printfunc \"StdSeqLocPrint\" } } ,\n" \
7307 "{ asn1 \"Seq-feat.location\" , label \"Location\" , prefix \" \" , form user { printfunc \"StdSeqLocPrint\" } } ,\n" \
7308 "{ asn1 \"Seq-feat.cit\" , label \"Citations\" , prefix \"\\n\" , form block {\n" \
7309 "separator \"\\n\" ,\n" \
7310 "components {\n" \
7311 "{ asn1 \"Seq-feat.cit.pub.E\" , form use-template \"StdPub\" } } } } ,\n" \
7312 "{ asn1 \"Seq-feat.xref\" , label \"Cross-reference\" , prefix \"\\n\" , form block {\n" \
7313 "separator \"\\n\" ,\n" \
7314 "components {\n" \
7315 "{ asn1 \"Seq-feat.xref.E\" , form use-template \"StdSeqFeatXref\" } } } } } } } } ,\n" \
7316 "{ name \"StdSeqFeatData\" ,\n" \
7317 "format { asn1 \"SeqFeatData\" , form block {\n" \
7318 "components {\n" \
7319 "{ asn1 \"SeqFeatData.gene\" , label \"Gene\" , form use-template \"StdGeneRef\" } ,\n" \
7320 "{ asn1 \"SeqFeatData.org\" , label \"Organism\" , form use-template \"StdOrgRef\" } ,\n" \
7321 "{ asn1 \"SeqFeatData.cdregion\" , label \"Coding Region\" , form use-template \"StdCdRegion\" } ,\n" \
7322 "{ asn1 \"SeqFeatData.prot\" , label \"Protein\" , form use-template \"StdProtRef\" } ,\n" \
7323 "{ asn1 \"SeqFeatData.rna\" , label \"RNA\" , form use-template \"StdRNARef\" } ,\n" \
7324 "{ asn1 \"SeqFeatData.pub\" , label \"Citation\" , form use-template \"StdPubdesc\" } ,\n" \
7325 "{ asn1 \"SeqFeatData.seq\" , label \"Sequence\" , form user { printfunc \"StdSeqLocPrint\" } } ,\n" \
7326 "{ asn1 \"SeqFeatData.imp.key\" , label \"Import\" , form use-template \"StdImpFeat\" } ,\n" \
7327 "{ asn1 \"SeqFeatData.region\" , label \"Region\" , form text { } } ,\n" \
7328 "{ asn1 \"SeqFeatData.comment\" , label \"Comment\" , form null NULL } ,\n" \
7329 "{ asn1 \"SeqFeatData.bond\" , label \"Bond\" , form enum { } } ,\n" \
7330 "{ asn1 \"SeqFeatData.site\" , label \"Site\" , form enum { } } ,\n" \
7331 "{ asn1 \"SeqFeatData.rsite\" , label \"Rest. Site\" , form use-template \"StdRsiteRef\" } ,\n" \
7332 "{ asn1 \"SeqFeatData.user\" , label \"User Type\" , form use-template \"StdUserObj\" } ,\n" \
7333 "{ asn1 \"SeqFeatData.txinit\" , label \"TxInit\" , form use-template \"StdTxInit\" } ,\n" \
7334 "{ asn1 \"SeqFeatData.num\" , label \"Numbering\" , form use-template \"StdNumbering\" } ,\n" \
7335 "{ asn1 \"SeqFeatData.psec-str\" , label \"Sec. Struct\" , form enum { } } ,\n" \
7336 "{ asn1 \"SeqFeatData.non-std-residue\" , label \"NonStd Residue\" , form text { } } ,\n" \
7337 "{ asn1 \"SeqFeatData.het\" , label \"Heterogen\" , form text { } } ,\n" \
7338 "{ asn1 \"SeqFeatData.biosrc\" , label \"Biological Source\" , prefix \"\\n\" , form use-template \"StdBioSource\" } } } } } ,\n" \
7339 "{ name \"StdGeneRef\" ,\n" \
7340 "format { asn1 \"Gene-ref\" , form block {\n" \
7341 "separator \"\\n\" ,\n" \
7342 "components {\n" \
7343 "{ asn1 \"Gene-ref\" , form block {\n" \
7344 "components {\n" \
7345 "{ asn1 \"Gene-ref.locus\" , form text { } } ,\n" \
7346 "{ asn1 \"Gene-ref.allele\" , prefix \" \" , form text { } } } } } ,\n" \
7347 "{ asn1 \"Gene-ref.desc\" , prefix \"[\" , suffix \"]\" , form text { } } ,\n" \
7348 "{ asn1 \"Gene-ref.pseudo\" , form boolean {\n" \
7349 "true \"This is a pseudogene.\" } } ,\n" \
7350 "{ asn1 \"Gene-ref.syn\" , label \"Synonyms\" , prefix \" (\" , suffix \")\" , form block {\n" \
7351 "separator \", \" ,\n" \
7352 "components {\n" \
7353 "{ asn1 \"Gene-ref.syn.E\" , form text { } } } } } ,\n" \
7354 "{ asn1 \"Gene-ref.maploc\" , label \"Map Location\" , prefix \" \" , form text { } } ,\n" \
7355 "{ asn1 \"Gene-ref.db\" , label \"Cross Reference\" , prefix \" \" , form block {\n" \
7356 "separator \", \" ,\n" \
7357 "components {\n" \
7358 "{ asn1 \"Gene-ref.db.E\" , prefix \"(\" , suffix \")\" , form use-template \"StdDbtag\" } } } } } } } } ,\n" \
7359 "{ name \"StdUserObj\" ,\n" \
7360 "format { asn1 \"User-object\" , label \"User-object\" , prefix \"\\n\" , form block {\n" \
7361 "separator \": \" ,\n" \
7362 "components {\n" \
7363 "{ asn1 \"User-object.class\" , form text { } } ,\n" \
7364 "{ asn1 \"User-object.type\" , form use-template \"StdObjectId\" } } } } } ,\n" \
7365 "{ name \"StdPubOnFeat\" ,\n" \
7366 "format { asn1 \"Pub\" , label \"Citation\" , prefix \"\\n\" , form block {\n" \
7367 "separator \"\\n\" ,\n" \
7368 "components {\n" \
7369 "{ asn1 \"Pub\" , form use-template \"StdPub\" } } } } } ,\n" \
7370 "{ name \"StdPub\" ,\n" \
7371 "format { asn1 \"Pub\" , form block {\n" \
7372 "separator \"\\n\" ,\n" \
7373 "components {\n" \
7374 "{ asn1 \"Pub.gen\" , form use-template \"StdCitGen\" } ,\n" \
7375 "{ asn1 \"Pub.sub\" , form use-template \"StdCitSub\" } ,\n" \
7376 "{ asn1 \"Pub.medline\" , form use-template \"StdMedlineEntry\" } ,\n" \
7377 "{ asn1 \"Pub.muid\" , label \"MEDLINE uid: \" , form text { } } ,\n" \
7378 "{ asn1 \"Pub.pmid\" , label \"PubMed id: \" , form text { } } ,\n" \
7379 "{ asn1 \"Pub.article\" , form use-template \"StdCitArt\" } ,\n" \
7380 "{ asn1 \"Pub.journal\" , form use-template \"StdCitJour\" } ,\n" \
7381 "{ asn1 \"Pub.book\" , form use-template \"StdCitBook\" } ,\n" \
7382 "{ asn1 \"Pub.proc\" , form use-template \"StdCitProc\" } ,\n" \
7383 "{ asn1 \"Pub.patent\" , form use-template \"StdCitPat\" } ,\n" \
7384 "{ asn1 \"Pub.pat-id\" , form use-template \"StdIdPat\" } ,\n" \
7385 "{ asn1 \"Pub.man\" , form use-template \"StdCitLet\" } ,\n" \
7386 "{ asn1 \"Pub.equiv\" , form use-template \"StdPubEquiv\" } } } } } ,\n" \
7387 "{ name \"StdCitGen\" ,\n" \
7388 "format { asn1 \"Cit-gen\" , form block {\n" \
7389 "separator \"\\n\" ,\n" \
7390 "components {\n" \
7391 "{ asn1 \"Cit-gen.serial-number\" , prefix \"[\" , suffix \"]\" , form text { } } ,\n" \
7392 "{ asn1 \"Cit-gen.authors\" , form use-template \"StdAuthList\" } ,\n" \
7393 "{ asn1 \"Cit-gen.date\" , prefix \"(\" , suffix \")\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
7394 "{ asn1 \"Cit-gen.title\" , form text { } } ,\n" \
7395 "{ asn1 \"Cit-gen.cit\" , form text { } } ,\n" \
7396 "{ asn1 \"Cit-gen\" , form block {\n" \
7397 "separator \" \" ,\n" \
7398 "components {\n" \
7399 "{ asn1 \"Cit-gen.journal\" , suffix \":\" , form use-template \"StdTitle\" } ,\n" \
7400 "{ asn1 \"Cit-gen.issue\" , suffix \";\" , form text { } } ,\n" \
7401 "{ asn1 \"Cit-gen.pages\" , form text { } } } } } } } } } ,\n" \
7402 "{ name \"StdCitSub\" ,\n" \
7403 "format { asn1 \"Cit-sub\" , prefix \"Data Submission \" , form block {\n" \
7404 "components {\n" \
7405 "{ asn1 \"Cit-sub.medium\" , prefix \"on \" , suffix \" \" , form enum { } } ,\n" \
7406 "{ asn1 \"Cit-sub.imp.date\" , prefix \"(\" , suffix \")\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
7407 "{ asn1 \"Cit-sub.authors\" , prefix \"\\n\" , form use-template \"StdAuthList\" } } } } } ,\n" \
7408 "{ name \"StdMedlineEntry\" ,\n" \
7409 "format { asn1 \"Medline-entry\" , form block {\n" \
7410 "separator \"\\n\" ,\n" \
7411 "components {\n" \
7412 "{ asn1 \"Medline-entry\" , form block {\n" \
7413 "separator \"   \" ,\n" \
7414 "components {\n" \
7415 "{ asn1 \"Medline-entry.uid\" , label \"uid\" , prefix \": \" , form text { } } ,\n" \
7416 "{ asn1 \"Medline-entry.em\" , label \"entry month\" , prefix \": \" , form user { printfunc \"StdDatePrint\" } } } } } ,\n" \
7417 "{ asn1 \"Medline-entry.cit\" , form use-template \"StdCitArt\" } ,\n" \
7418 "{ asn1 \"Medline-entry.abstract\" , label \"abstract\" , prefix \": \" , form text { } } ,\n" \
7419 "{ asn1 \"Medline-entry.mesh\" , label \"Mesh Terms\" , prefix \"\\n\" , form block {\n" \
7420 "separator \"\\n\" ,\n" \
7421 "components {\n" \
7422 "{ asn1 \"Medline-entry.mesh.E\" , form block {\n" \
7423 "components {\n" \
7424 "{ asn1 \"Medline-mesh.term\" , form text { } } ,\n" \
7425 "{ asn1 \"Medline-mesh.mp\" , form boolean {\n" \
7426 "true \" (Main Point)\" } } ,\n" \
7427 "{ asn1 \"Medline-mesh.qual\" , form block {\n" \
7428 "separator \"\\n\" ,\n" \
7429 "components {\n" \
7430 "{ asn1 \"Medline-mesh.qual.E\" , form block {\n" \
7431 "components {\n" \
7432 "{ asn1 \"Medline-qual.subh\" , form text { } } ,\n" \
7433 "{ asn1 \"Medline-qual.mp\" , form boolean {\n" \
7434 "true \" (Main Point)\" } } } } } } } } } } } } } } ,\n" \
7435 "{ asn1 \"Medline-entry.substance\" , label \"Substance\" , prefix \"\\n\" , form block {\n" \
7436 "separator \"\\n\" ,\n" \
7437 "components {\n" \
7438 "{ asn1 \"Medline-entry.substance.E\" , form block {\n" \
7439 "components {\n" \
7440 "{ asn1 \"Medline-rn.name\" , form text { } } ,\n" \
7441 "{ asn1 \"Medline-rn.type\" , form enum {\n" \
7442 "values {\n" \
7443 "\"\" ,\n" \
7444 "\" CAS: \" ,\n" \
7445 "\"EC \" } } } ,\n" \
7446 "{ asn1 \"Medline-rn.cit\" , form text { } } } } } } } } ,\n" \
7447 "{ asn1 \"Medline-entry.xref\" , label \"Cross Reference\" , prefix \"\\n\" , form block {\n" \
7448 "separator \"\\n\" ,\n" \
7449 "components {\n" \
7450 "{ asn1 \"Medline-entry.xref.E\" , form block {\n" \
7451 "separator \": \" ,\n" \
7452 "components {\n" \
7453 "{ asn1 \"Medline-si.type\" , form enum { } } ,\n" \
7454 "{ asn1 \"Medline-si.cit\" , form text { } } } } } } } } ,\n" \
7455 "{ asn1 \"Medline-entry.gene\" , label \"Possible Gene Symbols\" , prefix \": \" , form block {\n" \
7456 "separator \", \" ,\n" \
7457 "components {\n" \
7458 "{ asn1 \"Medline-entry.gene.E\" , form text { } } } } } ,\n" \
7459 "{ asn1 \"Medline-entry.idnum\" , label \"Support\" , prefix \": \" , form block {\n" \
7460 "separator \", \" ,\n" \
7461 "components {\n" \
7462 "{ asn1 \"Medline-entry.idnum.E\" , form text { } } } } } } } } } ,\n" \
7463 "{ name \"StdCitArt\" ,\n" \
7464 "format { asn1 \"Cit-art\" , form block {\n" \
7465 "separator \"\\n\" ,\n" \
7466 "components {\n" \
7467 "{ asn1 \"Cit-art.title\" , form use-template \"StdTitle\" } ,\n" \
7468 "{ asn1 \"Cit-art.authors\" , form use-template \"StdAuthList\" } ,\n" \
7469 "{ asn1 \"Cit-art.from.journal\" , form use-template \"StdCitJour\" } ,\n" \
7470 "{ asn1 \"Cit-art.from.book\" , prefix \"(in) \" , form use-template \"StdCitBook\" } ,\n" \
7471 "{ asn1 \"Cit-art.from.proc\" , prefix \"(in) \" , form use-template \"StdCitProc\" } } } } } ,\n" \
7472 "{ name \"StdCitJour\" ,\n" \
7473 "format { asn1 \"Cit-jour\" , form block {\n" \
7474 "separator \" \" ,\n" \
7475 "components {\n" \
7476 "{ asn1 \"Cit-jour.title\" , form use-template \"StdTitle\" } ,\n" \
7477 "{ asn1 \"Cit-jour.imp\" , form use-template \"StdImprint\" } } } } } ,\n" \
7478 "{ name \"StdCitBook\" ,\n" \
7479 "format { asn1 \"Cit-book\" , form block {\n" \
7480 "separator \"\\n\" ,\n" \
7481 "components {\n" \
7482 "{ asn1 \"Cit-book.title\" , form use-template \"StdTitle\" } ,\n" \
7483 "{ asn1 \"Cit-book.coll\" , prefix \"Collection: \" , form use-template \"StdTitle\" } ,\n" \
7484 "{ asn1 \"Cit-book.authors\" , form use-template \"StdAuthList\" } ,\n" \
7485 "{ asn1 \"Cit-book.imp\" , form use-template \"StdImprint\" } } } } } ,\n" \
7486 "{ name \"StdCitProc\" ,\n" \
7487 "format { asn1 \"Cit-proc\" , form block {\n" \
7488 "separator \"\\n\" ,\n" \
7489 "components {\n" \
7490 "{ asn1 \"Cit-proc.book\" , form use-template \"StdCitBook\" } ,\n" \
7491 "{ asn1 \"Cit-proc.meet\" , label \"Meeting \" , form block {\n" \
7492 "separator \", \" ,\n" \
7493 "components {\n" \
7494 "{ asn1 \"Meeting.number\" , form text { } } ,\n" \
7495 "{ asn1 \"Meeting.date\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
7496 "{ asn1 \"Meeting.place\" , form use-template \"StdAffil\" } } } } } } } } ,\n" \
7497 "{ name \"StdCitPat\" ,\n" \
7498 "format { asn1 \"Cit-pat\" , form block {\n" \
7499 "separator \"\\n\" ,\n" \
7500 "components {\n" \
7501 "{ asn1 \"Cit-pat.title\" , form text { } } ,\n" \
7502 "{ asn1 \"Cit-pat.authors\" , form use-template \"StdAuthList\" } ,\n" \
7503 "{ asn1 \"Cit-pat\" , form block {\n" \
7504 "components {\n" \
7505 "{ asn1 \"Cit-pat.country\" , suffix \" \" , form text { } } ,\n" \
7506 "{ asn1 \"Cit-pat.doc-type\" , form text { } } ,\n" \
7507 "{ asn1 \"Cit-pat.number\" , form text { } } ,\n" \
7508 "{ asn1 \"Cit-pat.date-issue\" , prefix \" (\" , suffix \")\" , form user { printfunc \"StdDatePrint\" } } ,\n" \
7509 "{ asn1 \"Cit-pat.app-number\" , prefix \" Appl: \" , form text { } } ,\n" \
7510 "{ asn1 \"Cit-pat.app-date\" , prefix \" (\" , suffix \")\" , form user { printfunc \"StdDatePrint\" } } } } } } } } } ,\n" \
7511 "{ name \"StdIdPat\" ,\n" \
7512 "format { asn1 \"Id-pat\" , form block {\n" \
7513 "components {\n" \
7514 "{ asn1 \"Id-pat.country\" , suffix \" \" , form text { } } ,\n" \
7515 "{ asn1 \"Id-pat.id.number\" , form text { } } ,\n" \
7516 "{ asn1 \"Id-pat.id.app-number\" , prefix \"Appl: \" , form text { } } } } } } ,\n" \
7517 "{ name \"StdCitLet\" ,\n" \
7518 "format { asn1 \"Cit-let\" , form block {\n" \
7519 "separator \"\\n\" ,\n" \
7520 "components {\n" \
7521 "{ asn1 \"Cit-let.type\" , prefix \"[\" , suffix \"]\" , form enum { } } ,\n" \
7522 "{ asn1 \"Cit-let.man-id\" , form text { } } ,\n" \
7523 "{ asn1 \"Cit-let.cit\" , form use-template \"StdCitBook\" } } } } } ,\n" \
7524 "{ name \"StdPubEquiv\" ,\n" \
7525 "format { asn1 \"Pub-equiv\" , form block {\n" \
7526 "separator \"\\n\" ,\n" \
7527 "components {\n" \
7528 "{ asn1 \"Pub-equiv.E\" , form use-template \"StdPub\" } } } } } ,\n" \
7529 "{ name \"StdTitle\" ,\n" \
7530 "format { asn1 \"Title\" , form block {\n" \
7531 "separator \", \" ,\n" \
7532 "components {\n" \
7533 "{ asn1 \"Title.E.trans\" , prefix \"[\" , suffix \"]\" , form text { } } ,\n" \
7534 "{ asn1 \"Title.E.name\" , form text { } } ,\n" \
7535 "{ asn1 \"Title.E.tsub\" , form text { } } ,\n" \
7536 "{ asn1 \"Title.E.abr\" , form text { } } ,\n" \
7537 "{ asn1 \"Title.E.iso-jta\" , form text { } } ,\n" \
7538 "{ asn1 \"Title.E.ml-jta\" , label \"MEDLINE\" , prefix \": \" , form text { } } ,\n" \
7539 "{ asn1 \"Title.E.jta\" , label \"jta\" , prefix \": \" , form text { } } ,\n" \
7540 "{ asn1 \"Title.E.issn\" , label \"ISSN\" , prefix \": \" , form text { } } ,\n" \
7541 "{ asn1 \"Title.E.coden\" , label \"CODEN\" , prefix \": \" , form text { } } ,\n" \
7542 "{ asn1 \"Title.E.isbn\" , label \"ISBN\" , prefix \": \" , form text { } } } } } } ,\n" \
7543 "{ name \"StdAuthList\" ,\n" \
7544 "format { asn1 \"Auth-list\" , form block {\n" \
7545 "separator \"\\n\" ,\n" \
7546 "components {\n" \
7547 "{ asn1 \"Auth-list\" , form user { printfunc \"StdAuthListNamesPrint\" } } ,\n" \
7548 "{ asn1 \"Auth-list.affil\" , form use-template \"StdAffil\" } } } } } ,\n" \
7549 "{ name \"StdAffil\" ,\n" \
7550 "format { asn1 \"Affil\" , form block {\n" \
7551 "separator \"\\n\" ,\n" \
7552 "components {\n" \
7553 "{ asn1 \"Affil.str\" , form text { } } ,\n" \
7554 "{ asn1 \"Affil.std.affil\" , form text { } } ,\n" \
7555 "{ asn1 \"Affil.std.div\" , form text { } } ,\n" \
7556 "{ asn1 \"Affil.std.street\" , form text { } } ,\n" \
7557 "{ asn1 \"Affil.std\" , form block {\n" \
7558 "separator \" \" ,\n" \
7559 "components {\n" \
7560 "{ asn1 \"Affil.std.city\" , form text { } } ,\n" \
7561 "{ asn1 \"Affil.std.sub\" , form text { } } ,\n" \
7562 "{ asn1 \"Affil.std.country\" , form text { } } } } } } } } } ,\n" \
7563 "{ name \"StdImprint\" ,\n" \
7564 "format { asn1 \"Imprint\" , form block {\n" \
7565 "components {\n" \
7566 "{ asn1 \"Imprint.date\" , prefix \"(\" , suffix \") \" , form user { printfunc \"StdDatePrint\" } } ,\n" \
7567 "{ asn1 \"Imprint.volume\" , form text { } } ,\n" \
7568 "{ asn1 \"Imprint.issue\" , prefix \" (\" , suffix \")\" , form text { } } ,\n" \
7569 "{ asn1 \"Imprint.section\" , prefix \" (\" , suffix \")\" , form text { } } ,\n" \
7570 "{ asn1 \"Imprint.part-sup\" , prefix \" (\" , suffix \")\" , form text { } } ,\n" \
7571 "{ asn1 \"Imprint.pages\" , prefix \": \" , form text { } } ,\n" \
7572 "{ asn1 \"Imprint.prepub\" , prefix \" (\" , suffix \")\" , form enum { } } ,\n" \
7573 "{ asn1 \"Imprint.pub\" , label \"\nPublisher: \" , form use-template \"StdAffil\" } ,\n" \
7574 "{ asn1 \"Imprint.cprt\" , label \" Copyright: \" , form user { printfunc \"StdDatePrint\" } } } } } } ,\n" \
7575 "{ name \"StdSeqFeatXref\" ,\n" \
7576 "format { asn1 \"SeqFeatXref\" , form block {\n" \
7577 "separator \"\\n\" ,\n" \
7578 "components {\n" \
7579 "{ asn1 \"SeqFeatXref.id\" , label \"Id=\" , form use-template \"StdFeatId\" } ,\n" \
7580 "{ asn1 \"SeqFeatXref.data\" , form use-template \"StdSeqFeatData\" } } } } } ,\n" \
7581 "{ name \"StdOrgRef\" ,\n" \
7582 "format { asn1 \"Org-ref\" , label \"Org-ref\" , prefix \"\\n\" , form block {\n" \
7583 "separator \"\\n\" ,\n" \
7584 "components {\n" \
7585 "{ asn1 \"Org-ref\" , form block {\n" \
7586 "separator \" \" ,\n" \
7587 "components {\n" \
7588 "{ asn1 \"Org-ref.taxname\" , form text { } } ,\n" \
7589 "{ asn1 \"Org-ref.common\" , prefix \"(\" , suffix \")\" , form text { } } } } } ,\n" \
7590 "{ asn1 \"Org-ref.mod\" , label \"Modifiers\" , prefix \" (\" , suffix \")\" , form block {\n" \
7591 "separator \", \" ,\n" \
7592 "components {\n" \
7593 "{ asn1 \"Org-ref.mod.E\" , form text { } } } } } ,\n" \
7594 "{ asn1 \"Org-ref.db\" , label \"Cross Reference\" , prefix \" \" , form block {\n" \
7595 "separator \", \" ,\n" \
7596 "components {\n" \
7597 "{ asn1 \"Org-ref.db.E\" , prefix \"(\" , suffix \")\" , form use-template \"StdDbtag\" } } } } ,\n" \
7598 "{ asn1 \"Org-ref.syn\" , label \"Synonyms\" , prefix \" (\" , suffix \")\" , form block {\n" \
7599 "separator \", \" ,\n" \
7600 "components {\n" \
7601 "{ asn1 \"Org-ref.syn.E\" , form text { } } } } } } } } } ,\n" \
7602 "{ name \"StdBioSource\" ,\n" \
7603 "format { asn1 \"BioSource\" , label \"BioSource\" , form block {\n" \
7604 "separator \"\\n\" ,\n" \
7605 "components {\n" \
7606 "{ asn1 \"BioSource.genome\" , form enum { } } ,\n" \
7607 "{ asn1 \"BioSource.org\" , label \"Organism\" , form use-template \"StdOrgRef\" } } } } } ,\n" \
7608 "{ name \"StdCdRegion\" ,\n" \
7609 "format { asn1 \"Cdregion\" , label \"Cdregion\" , form block {\n" \
7610 "separator \"\\n\" ,\n" \
7611 "components {\n" \
7612 "{ asn1 \"Cdregion.orf\" , form boolean {\n" \
7613 "true \"Uncharacterized Open Reading Frame\" } } ,\n" \
7614 "{ asn1 \"Cdregion.frame\" , label \"Reading Frame = \" , form enum { } } ,\n" \
7615 "{ asn1 \"Cdregion.code\" , label \"Genetic Code: \" , suffix \";\" , form block {\n" \
7616 "separator \", \" ,\n" \
7617 "components {\n" \
7618 "{ asn1 \"Genetic-code.E.name\" , form text { } } ,\n" \
7619 "{ asn1 \"Genetic-code.E.id\" , label \"id= \" , form text { } } } } } ,\n" \
7620 "{ asn1 \"Cdregion.conflict\" , form boolean {\n" \
7621 "true \"Translation conflicts with protein sequence\" } } ,\n" \
7622 "{ asn1 \"Cdregion.stops\" , prefix \"Translation contains \" , suffix \" stop codons\" , form text { } } ,\n" \
7623 "{ asn1 \"Cdregion.gaps\" , prefix \"Translation contains \" , suffix \" gaps when aligned to protein\" , form text { } } ,\n" \
7624 "{ asn1 \"Cdregion.mismatch\" , prefix \"Translation contains \" , suffix \" mismatches when aligned to protein\" , form text { } } } } } } ,\n" \
7625 "{ name \"StdProtRef\" ,\n" \
7626 "format { asn1 \"Prot-ref\" , label \"Prot-ref\" , form block {\n" \
7627 "separator \"\\n\" ,\n" \
7628 "components {\n" \
7629 "{ asn1 \"Prot-ref.name\" , form block {\n" \
7630 "separator \", \" ,\n" \
7631 "components {\n" \
7632 "{ asn1 \"Prot-ref.name.E\" , form text { } } } } } ,\n" \
7633 "{ asn1 \"Prot-ref.desc\" , prefix \"[\" , suffix \"]\" , form text { } } ,\n" \
7634 "{ asn1 \"Prot-ref.processed\" , form enum { } } ,\n" \
7635 "{ asn1 \"Prot-ref.ec\" , label \"ec\" , prefix \": \" , form block {\n" \
7636 "separator \", \" ,\n" \
7637 "components {\n" \
7638 "{ asn1 \"Prot-ref.ec.E\" , form text { } } } } } ,\n" \
7639 "{ asn1 \"Prot-ref.activity\" , label \"activity\" , prefix \": \" , form block {\n" \
7640 "separator \", \" ,\n" \
7641 "components {\n" \
7642 "{ asn1 \"Prot-ref.activity.E\" , form text { } } } } } ,\n" \
7643 "{ asn1 \"Prot-ref.db\" , label \"Cross Reference\" , prefix \" \" , form block {\n" \
7644 "separator \", \" ,\n" \
7645 "components {\n" \
7646 "{ asn1 \"Prot-ref.db.E\" , prefix \"(\" , suffix \")\" , form use-template \"StdDbtag\" } } } } } } } } ,\n" \
7647 "{ name \"StdRNARef\" ,\n" \
7648 "format { asn1 \"RNA-ref\" , label \"RNA-ref\" , form block {\n" \
7649 "separator \"\\n\" ,\n" \
7650 "components {\n" \
7651 "{ asn1 \"RNA-ref.type\" , form enum { } } ,\n" \
7652 "{ asn1 \"RNA-ref.pseudo\" , form boolean {\n" \
7653 "true \"This is an RNA pseudogene.\" } } ,\n" \
7654 "{ asn1 \"RNA-ref.ext.name\" , form text { } } } } } } ,\n" \
7655 "{ name \"StdPubdesc\" ,\n" \
7656 "format { asn1 \"Pubdesc\" , label \"Pubdesc\" , form block {\n" \
7657 "separator \"\\n\" ,\n" \
7658 "components {\n" \
7659 "{ asn1 \"Pubdesc.pub\" , form use-template \"StdPubEquiv\" } ,\n" \
7660 "{ asn1 \"Pubdesc\" , prefix \"In this article:\n\" , form block {\n" \
7661 "separator \"\\n\" ,\n" \
7662 "components {\n" \
7663 "{ asn1 \"Pubdesc.name\" , label \"name=\" , form text { } } ,\n" \
7664 "{ asn1 \"Pubdesc.fig\" , label \"figure=\" , form text { } } ,\n" \
7665 "{ asn1 \"Pubdesc.poly-a\" , form boolean {\n" \
7666 "true \"poly(A) shown\" } } ,\n" \
7667 "{ asn1 \"Pubdesc.maploc\" , label \"map location=\" , form text { } } ,\n" \
7668 "{ asn1 \"Pubdesc.num\" , form use-template \"StdNumbering\" } ,\n" \
7669 "{ asn1 \"Pubdesc.numexc\" , form boolean {\n" \
7670 "true \"numbering inconsistent\" } } } } } ,\n" \
7671 "{ asn1 \"Pubdesc.comment\" , form text { } } } } } } ,\n" \
7672 "{ name \"StdImpFeat\" ,\n" \
7673 "format { asn1 \"Imp-feat.key\" , label \"Imp-feat\" , form text { } } } ,\n" \
7674 "{ name \"StdRsiteRef\" ,\n" \
7675 "format { asn1 \"Rsite-ref\" , label \"Rsite-ref\" , form block {\n" \
7676 "components {\n" \
7677 "{ asn1 \"Rsite-ref.str\" , form text { } } ,\n" \
7678 "{ asn1 \"Rsite-ref.std\" , form use-template \"StdDbtag\" } } } } } ,\n" \
7679 "{ name \"StdTxInit\" ,\n" \
7680 "format { asn1 \"Txinit\" , label \"TxInit\" , form block {\n" \
7681 "components {\n" \
7682 "{ asn1 \"Txinit.name\" , form text { } } } } } } ,\n" \
7683 "{ name \"StdNumbering\" ,\n" \
7684 "format { asn1 \"Numbering\" , label \"Numbering\" , form null NULL } } ,\n" \
7685 "{ name \"StdGBBlock\" ,\n" \
7686 "format { asn1 \"GB-block\" , label \"GenBank-block\" , form block {\n" \
7687 "separator \"\\n\" ,\n" \
7688 "components {\n" \
7689 "{ asn1 \"GB-block.extra-accessions\" , label \"Extra accessions\" , prefix \" (\" , suffix \")\" , form block {\n" \
7690 "separator \", \" ,\n" \
7691 "components {\n" \
7692 "{ asn1 \"GB-block.extra-accessions.E\" , form text { } } } } } ,\n" \
7693 "{ asn1 \"GB-block.keywords\" , label \"Keywords\" , prefix \" (\" , suffix \")\" , form block {\n" \
7694 "separator \", \" ,\n" \
7695 "components {\n" \
7696 "{ asn1 \"GB-block.keywords.E\" , form text { } } } } } ,\n" \
7697 "{ asn1 \"GB-block.source\" , label \"Source: \" , form text { } } ,\n" \
7698 "{ asn1 \"GB-block.origin\" , label \"Origin: \" , form text { } } ,\n" \
7699 "{ asn1 \"GB-block.div\" , label \"Division: \" , form text { } } ,\n" \
7700 "{ asn1 \"GB-block.taxonomy\" , label \"Taxonomy: \" , form text { } } ,\n" \
7701 "{ asn1 \"GB-block.date\" , label \"Date: \" , form text { } } ,\n" \
7702 "{ asn1 \"GB-block.entry-date\" , label \"Entry date: \" , form user { printfunc \"StdDatePrint\" } } } } } } ,\n" \
7703 "{ name \"StdFeatId\" ,\n" \
7704 "format { asn1 \"Feat-id\" , form block {\n" \
7705 "components {\n" \
7706 "{ asn1 \"Feat-id.gibb\" , label \"GenInfo Backbone: \" , form text { } } ,\n" \
7707 "{ asn1 \"Feat-id.giim.id\" , label \"GenInfo Import Id: \" , form text { } } ,\n" \
7708 "{ asn1 \"Feat-id.local\" , label \"Local: \" , form use-template \"StdObjectId\" } ,\n" \
7709 "{ asn1 \"Feat-id.general\" , form use-template \"StdDbtag\" } } } } } ,\n" \
7710 "{ name \"StdSeqFeatCommon\" ,\n" \
7711 "format { asn1 \"Seq-feat\" , form block {\n" \
7712 "separator \"\\n\" ,\n" \
7713 "components {\n" \
7714 "{ asn1 \"Seq-feat.id\" , label \"Id=\" , form use-template \"StdFeatId\" } ,\n" \
7715 "{ asn1 \"Seq-feat.title\" , form text { } } ,\n" \
7716 "{ asn1 \"Seq-feat\" , suffix \";\" , form block {\n" \
7717 "separator \", \" ,\n" \
7718 "components {\n" \
7719 "{ asn1 \"Seq-feat.partial\" , form boolean {\n" \
7720 "true \"Partial\" } } ,\n" \
7721 "{ asn1 \"Seq-feat.except\" , form boolean {\n" \
7722 "true \"Biological Exception\" } } ,\n" \
7723 "{ asn1 \"Seq-feat.exp-ev\" , label \"Evidence\" , prefix \" is \" , form enum { } } } } } ,\n" \
7724 "{ asn1 \"Seq-feat.comment\" , form text { } } ,\n" \
7725 "{ asn1 \"Seq-feat.ext\" , form use-template \"StdUserObj\" } ,\n" \
7726 "{ asn1 \"Seq-feat.qual\" , label \"Qualifiers\" , prefix \"\\n\" , form block {\n" \
7727 "separator \"\\n\" ,\n" \
7728 "components {\n" \
7729 "{ asn1 \"Seq-feat.qual.E\" , prefix \"/\" , form block {\n" \
7730 "separator \"= \" ,\n" \
7731 "components {\n" \
7732 "{ asn1 \"Gb-qual.qual\" , form text { } } ,\n" \
7733 "{ asn1 \"Gb-qual.val\" , form text { } } } } } } } } } } } } ,\n" \
7734 "{ name \"StdDbtag\" ,\n" \
7735 "format { asn1 \"Dbtag\" , form block {\n" \
7736 "components {\n" \
7737 "{ asn1 \"Dbtag.db\" , suffix \": \" , form text { } } ,\n" \
7738 "{ asn1 \"Dbtag.tag\" , form use-template \"StdObjectId\" } } } } } ,\n" \
7739 "{ name \"StdObjectId\" ,\n" \
7740 "format { asn1 \"Object-id\" , form block {\n" \
7741 "components {\n" \
7742 "{ asn1 \"Object-id.id\" , form text { } } ,\n" \
7743 "{ asn1 \"Object-id.str\" , form text { } } } } } } };\n";
7744 #else
7745 CharPtr objPrtMemStr = "";
7746 #endif
7747 
7748 typedef Boolean (*MatchBioseqToTableData) PROTO ((BioseqPtr, ValNodePtr, Int4));
7749 typedef Boolean (*BioseqAlreadyHasTableData) PROTO ((BioseqPtr, ValNodePtr, Int4));
7750 
GetMatchString(ValNodePtr columns,Int4 match_pos)7751 static CharPtr GetMatchString (ValNodePtr columns, Int4 match_pos)
7752 {
7753   ValNodePtr vnp;
7754 
7755   vnp = columns;
7756   while (match_pos > 0 && vnp != NULL) {
7757     vnp = vnp->next;
7758     match_pos--;
7759   }
7760   if (vnp == NULL) {
7761     return NULL;
7762   } else {
7763     return vnp->data.ptrvalue;
7764   }
7765 }
7766 
MatchBioseqToTableDataByID(BioseqPtr bsp,ValNodePtr columns,Int4 match_pos)7767 static Boolean MatchBioseqToTableDataByID (BioseqPtr bsp, ValNodePtr columns, Int4 match_pos)
7768 {
7769   Char       seqid[100];
7770   Int4       seqid_len;
7771   SeqIdPtr   sip;
7772   CharPtr    match_string;
7773   Boolean    rval = FALSE;
7774 
7775   if (bsp == NULL || columns == NULL || match_pos < 0) return rval;
7776 
7777   match_string = GetMatchString (columns, match_pos);
7778   if (match_string == NULL) return rval;
7779 
7780   sprintf (seqid, "gb|");
7781   seqid_len = StringLen (match_string);
7782   if (seqid_len > 96) {
7783     seqid_len = 96;
7784   }
7785   StringNCpy (seqid + 3, match_string, seqid_len);
7786   seqid [seqid_len + 3] = 0;
7787   sip = MakeSeqID (seqid);
7788   if (SeqIdIn (sip, bsp->id)) {
7789     rval = TRUE;
7790   }
7791   return rval;
7792 }
7793 
MatchBioseqToTableDataByOrgname(BioseqPtr bsp,ValNodePtr columns,Int4 match_pos)7794 static Boolean MatchBioseqToTableDataByOrgname (BioseqPtr bsp, ValNodePtr columns, Int4 match_pos)
7795 {
7796   CharPtr           match_string;
7797   Boolean           rval = FALSE;
7798   SeqDescrPtr       sdp;
7799   SeqMgrDescContext dcontext;
7800   BioSourcePtr      biop;
7801 
7802   if (bsp == NULL || columns == NULL || match_pos < 0) return rval;
7803 
7804   match_string = GetMatchString (columns, match_pos);
7805   if (match_string == NULL) return rval;
7806 
7807   sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
7808   while (sdp != NULL && !rval) {
7809     biop = (BioSourcePtr) sdp->data.ptrvalue;
7810     if (biop != NULL && biop->org != NULL && StringCmp (biop->org->taxname, match_string) == 0) {
7811       rval = TRUE;
7812     }
7813     sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_source, &dcontext);
7814   }
7815 
7816   return rval;
7817 }
7818 
7819 
7820 typedef struct bioseqtabledataassoc {
7821   BioseqPtr    bsp;
7822   TableLinePtr tlp;
7823 } BioseqTableDataAssocData, PNTR BioseqTableDataAssocPtr;
7824 
7825 typedef struct buildtabledataassoc {
7826   MatchBioseqToTableData match_func;
7827   Int4                   match_pos;
7828   ValNodePtr             table_data;
7829   ValNodePtr             assoc_list;
7830 } BuildBioseqTableDataAssocData, PNTR BuildBioseqTableDataAssocPtr;
7831 
BuildTableDataAssociationCallback(BioseqPtr bsp,Pointer userdata)7832 static void BuildTableDataAssociationCallback (BioseqPtr bsp, Pointer userdata)
7833 {
7834   BuildBioseqTableDataAssocPtr bp;
7835   ValNodePtr                   vnp;
7836   TableLinePtr                 tlp;
7837   BioseqTableDataAssocPtr      bap;
7838 
7839   bp = (BuildBioseqTableDataAssocPtr) userdata;
7840   if (bsp == NULL || bp == NULL || bp->match_func == NULL || bp->table_data == NULL) return;
7841   for (vnp = bp->table_data; vnp != NULL; vnp = vnp->next) {
7842     if (vnp->data.ptrvalue == NULL) continue;
7843     tlp = (TableLinePtr) vnp->data.ptrvalue;
7844     if (bp->match_func(bsp, tlp->parts, bp->match_pos)) {
7845       bap = (BioseqTableDataAssocPtr) MemNew (sizeof (BioseqTableDataAssocData));
7846       bap->bsp = bsp;
7847       bap->tlp = tlp;
7848       ValNodeAddPointer (&(bp->assoc_list), 0, bap);
7849     }
7850   }
7851 }
7852 
BuildTableDataAssociation(SeqEntryPtr sep,ValNodePtr table_data,MatchBioseqToTableData match_func,Int4 match_pos)7853 static ValNodePtr BuildTableDataAssociation (SeqEntryPtr sep, ValNodePtr table_data, MatchBioseqToTableData match_func, Int4 match_pos)
7854 {
7855   BuildBioseqTableDataAssocData bad;
7856 
7857   if (sep == NULL || table_data == NULL || match_func == NULL) return NULL;
7858   bad.assoc_list = NULL;
7859   bad.match_func = match_func;
7860   bad.match_pos = match_pos;
7861   bad.table_data = table_data;
7862 
7863   VisitBioseqsInSep (sep, &bad, BuildTableDataAssociationCallback);
7864   return bad.assoc_list;
7865 }
7866 
7867 static ValNodePtr
CheckTableDataAssociation(ValNodePtr assoc_list,BaseFormPtr bfp,ValNodePtr table_data,Int4 match_pos,BioseqAlreadyHasTableData already_func,CharPtr already_fmt,CharPtr more_than_one_fmt,BoolPtr data_needed,Int4 num_columns)7868 CheckTableDataAssociation
7869 (ValNodePtr assoc_list,
7870  BaseFormPtr bfp,
7871  ValNodePtr table_data,
7872  Int4 match_pos,
7873  BioseqAlreadyHasTableData already_func,
7874  CharPtr already_fmt,
7875  CharPtr more_than_one_fmt,
7876  BoolPtr data_needed,
7877  Int4    num_columns)
7878 {
7879   ValNodePtr vnp, vnp_match;
7880   BioseqTableDataAssocPtr bap1, bap2;
7881   ValNodePtr duplicated_bioseqs = NULL, already_has_list = NULL, err_list = NULL;
7882   ValNodePtr blanks = NULL;
7883   ClickableItemPtr cip;
7884   TableLinePtr     tlp;
7885   Boolean          found;
7886   CharPtr          no_match_fmt = "No match for %s";
7887   CharPtr          match_string;
7888   Int4             pos;
7889 
7890   if (assoc_list == NULL) {
7891     Message (MSG_ERROR, "No matches found!");
7892     return NULL;
7893   }
7894   for (vnp = assoc_list; vnp != NULL && vnp->next != NULL; vnp = vnp->next) {
7895     bap1 = (BioseqTableDataAssocPtr) vnp->data.ptrvalue;
7896     for (vnp_match = vnp->next; vnp_match != NULL; vnp_match = vnp_match->next) {
7897       bap2 = (BioseqTableDataAssocPtr) vnp_match->data.ptrvalue;
7898       if (bap1->bsp == bap2->bsp) {
7899         for (vnp_match = duplicated_bioseqs;
7900              vnp_match != NULL && bap1->bsp != vnp_match->data.ptrvalue;
7901              vnp_match = vnp_match->next) {}
7902         if (vnp_match == NULL) {
7903           ValNodeAddPointer (&(duplicated_bioseqs), OBJ_BIOSEQ, bap1->bsp);
7904         }
7905         break;
7906       }
7907     }
7908   }
7909   for (vnp = assoc_list; vnp != NULL; vnp = vnp->next) {
7910     bap1 = (BioseqTableDataAssocPtr) vnp->data.ptrvalue;
7911     if (already_func != NULL && already_func (bap1->bsp, NULL, 0)) {
7912       ValNodeAddPointer (&already_has_list, OBJ_BIOSEQ, bap1->bsp);
7913     }
7914     if (data_needed != NULL) {
7915       for (vnp_match = bap1->tlp->parts, pos = 0;
7916            vnp_match != NULL && pos < num_columns;
7917            vnp_match = vnp_match->next, pos++) {
7918         if (data_needed[pos] && StringHasNoText (vnp_match->data.ptrvalue)) {
7919           break;
7920         }
7921       }
7922       if (pos < num_columns) {
7923         ValNodeAddPointer (&blanks, OBJ_BIOSEQ, bap1->bsp);
7924       }
7925     }
7926   }
7927 
7928   if (duplicated_bioseqs != NULL) {
7929     if (more_than_one_fmt == NULL) {
7930       cip = NewClickableItem (TABLE_DATA_MULTIPLE_VALUES, "%d sequences will receive data from more than one line.", duplicated_bioseqs);
7931     } else {
7932       cip = NewClickableItem (TABLE_DATA_MULTIPLE_VALUES, more_than_one_fmt, duplicated_bioseqs);
7933     }
7934     ValNodeAddPointer (&err_list, 0, cip);
7935   }
7936 
7937   if (already_has_list != NULL) {
7938     if (already_fmt == NULL) {
7939       cip = NewClickableItem (TABLE_DATA_ALREADY_HAS, "%d sequences already have data", already_has_list);
7940     } else {
7941       cip = NewClickableItem (TABLE_DATA_ALREADY_HAS, already_fmt, already_has_list);
7942     }
7943     ValNodeAddPointer (&err_list, 0, cip);
7944   }
7945 
7946   if (blanks != NULL) {
7947     cip = NewClickableItem (TABLE_DATA_CELL_BLANK, "%d sequences have blank values in the table", blanks);
7948     ValNodeAddPointer (&err_list, 0, cip);
7949   }
7950 
7951   for (vnp = table_data; vnp != NULL; vnp = vnp->next) {
7952     tlp = vnp->data.ptrvalue;
7953     found = FALSE;
7954     for (vnp_match = assoc_list; vnp_match != NULL && !found; vnp_match = vnp_match->next) {
7955       bap1 = (BioseqTableDataAssocPtr) vnp_match->data.ptrvalue;
7956       if (bap1->tlp == tlp) {
7957         found = TRUE;
7958       }
7959     }
7960     if (!found) {
7961       match_string = GetMatchString (tlp->parts, match_pos);
7962       if (match_string != NULL) {
7963         cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
7964         MemSet (cip, 0, sizeof (ClickableItemData));
7965         cip->clickable_item_type = TABLE_DATA_NOT_FOUND;
7966         cip->description = MemNew ((StringLen (no_match_fmt) + StringLen (match_string)) * sizeof (Char));
7967         sprintf (cip->description, no_match_fmt, match_string);
7968         ValNodeAddPointer (&err_list, 0, cip);
7969       }
7970     }
7971   }
7972 
7973   return err_list;
7974 }
7975 
BioseqHasGenomeProjectID(BioseqPtr bsp,ValNodePtr columns,Int4 match_pos)7976 static Boolean BioseqHasGenomeProjectID (BioseqPtr bsp, ValNodePtr columns, Int4 match_pos)
7977 {
7978   Boolean     rval = FALSE;
7979   SeqDescrPtr sdp;
7980   SeqMgrDescContext context;
7981 
7982   if (bsp == NULL) return rval;
7983 
7984   sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &context);
7985   while (sdp != NULL && !rval) {
7986     rval = IsGenomeProjectIDDescriptor(sdp);
7987     sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &context);
7988   }
7989   return rval;
7990 }
7991 
ApplyGenomeProjectIDByTableDataAssociationList(ValNodePtr assoc_list,Int4 project_id_col,Boolean do_replace,Boolean blanks_erase,Uint2 entityID)7992 static void ApplyGenomeProjectIDByTableDataAssociationList (ValNodePtr assoc_list, Int4 project_id_col, Boolean do_replace, Boolean blanks_erase, Uint2 entityID)
7993 {
7994   BioseqTableDataAssocPtr bap;
7995   ValNodePtr              vnp;
7996   Int4                    projectID;
7997   SeqDescrPtr             sdp;
7998   UserObjectPtr           uop;
7999   ObjectIdPtr             oip;
8000   UserFieldPtr            ufp, ufp_last, ufp_next;
8001   CharPtr                 match_string;
8002   ObjValNodePtr           ovn;
8003 
8004   for (vnp = assoc_list; vnp != NULL; vnp = vnp->next) {
8005     bap = (BioseqTableDataAssocPtr) vnp->data.ptrvalue;
8006     sdp = NULL;
8007     if (BioseqHasGenomeProjectID (bap->bsp, NULL, 0)) {
8008       if (!do_replace) {
8009         continue;
8010       } else {
8011         sdp = GetGenomeProjectIDDescriptor(bap->bsp);
8012       }
8013     }
8014     match_string = GetMatchString (bap->tlp->parts, project_id_col);
8015     if (StringHasNoText (match_string)) {
8016       if (blanks_erase) {
8017         if (sdp != NULL && sdp->extended != 0) {
8018           ovn = (ObjValNodePtr) sdp;
8019           ovn->idx.deleteme = TRUE;
8020         }
8021       }
8022     } else {
8023       projectID = atoi (match_string);
8024       if (sdp == NULL) {
8025         sdp = SeqDescrNew (bap->bsp->descr);
8026         if (bap->bsp->descr == NULL) bap->bsp->descr = sdp;
8027         sdp->choice = Seq_descr_user;
8028         uop = CreateGenomeProjectsDBUserObject ();
8029         AddIDsToGenomeProjectsDBUserObject (uop, projectID, 0);
8030         sdp->data.ptrvalue = uop;
8031       } else {
8032         uop = sdp->data.ptrvalue;
8033         if (uop == NULL) {
8034           uop = CreateGenomeProjectsDBUserObject ();
8035           sdp->data.ptrvalue = uop;
8036         }
8037         ufp_last = NULL;
8038         ufp = uop->data;
8039         while (ufp != NULL) {
8040           oip = ufp->label;
8041           if (oip != NULL && StringCmp (oip->str, "ProjectID") == 0) {
8042             break;
8043           } else {
8044             ufp_last = ufp;
8045             ufp = ufp->next;
8046           }
8047         }
8048         if (ufp == NULL) {
8049           ufp_next = NULL;
8050         } else {
8051           ufp_next = ufp->next;
8052         }
8053 
8054         if (ufp != NULL && ufp->choice != 2) {
8055           ufp_next = ufp->next;
8056           ufp = UserFieldFree(ufp);
8057         }
8058         if (ufp == NULL) {
8059           ufp = UserFieldNew ();
8060           oip = ObjectIdNew ();
8061           oip->str = StringSave ("ProjectID");
8062           ufp->label = oip;
8063           ufp->choice = 2; /* integer */
8064           if (ufp_last == NULL) {
8065             uop->data = ufp;
8066           } else {
8067             ufp_last->next = ufp;
8068           }
8069         }
8070         ufp->data.intvalue = projectID;
8071         ufp->next = ufp_next;
8072       }
8073     }
8074   }
8075   DeleteMarkedObjects (entityID, 0, NULL);
8076 }
8077 
8078 typedef struct genomeprojectid {
8079   FORM_MESSAGE_BLOCK
8080   PopuP id_column;
8081   PopuP match_column;
8082   PopuP gpid_column;
8083 
8084   ValNodePtr table_data;
8085   BaseFormPtr bfp;
8086 } GenomeProjectIdData, PNTR GenomeProjectIdPtr;
8087 
CleanupGenomeProjectIDForm(GraphiC g,VoidPtr data)8088 static void CleanupGenomeProjectIDForm (GraphiC g, VoidPtr data)
8089 
8090 {
8091   GenomeProjectIdPtr gpip;
8092 
8093   gpip = (GenomeProjectIdPtr) data;
8094   if (gpip != NULL)
8095   {
8096     CleanUpTableData (gpip->table_data);
8097   }
8098   StdCleanupFormProc (g, data);
8099 }
8100 
ApplyGenomeProjectIDs(ButtoN b)8101 static void ApplyGenomeProjectIDs (ButtoN b)
8102 {
8103   GenomeProjectIdPtr gpip;
8104   ValNodePtr         assoc_list = NULL;
8105   SeqEntryPtr        sep;
8106   MatchBioseqToTableData match_func = NULL;
8107   Int4                   match_pos, project_id_col, col_num;
8108   Boolean                ok = FALSE;
8109   Boolean                skip_already_has = FALSE, blanks_erase = FALSE;
8110   ValNodePtr             err_list = NULL;
8111   SeqEntryPtr            oldscope;
8112   TableLinePtr           tlp;
8113   BoolPtr                data_needed = NULL;
8114   Int4                   num_parts = 0;
8115 
8116   gpip = (GenomeProjectIdPtr) GetObjectExtra (b);
8117   if (gpip == NULL) return;
8118 
8119   match_pos = GetValue (gpip->match_column);
8120   if (match_pos < 1) return;
8121   match_pos--;
8122   project_id_col = GetValue (gpip->gpid_column);
8123   if (project_id_col < 1) return;
8124   project_id_col--;
8125   if (GetValue (gpip->id_column) == 1) {
8126     match_func = MatchBioseqToTableDataByID;
8127   } else {
8128     match_func = MatchBioseqToTableDataByOrgname;
8129   }
8130 
8131   tlp = gpip->table_data->data.ptrvalue;
8132   if (tlp != NULL) {
8133     num_parts = tlp->num_parts;
8134     data_needed = (BoolPtr) MemNew (sizeof (Boolean) * tlp->num_parts);
8135     for (col_num = 0; col_num < tlp->num_parts; col_num++) {
8136       if (col_num == project_id_col) {
8137         data_needed[col_num] = TRUE;
8138       } else {
8139         data_needed[col_num] = FALSE;
8140       }
8141     }
8142   }
8143 
8144   sep = GetTopSeqEntryForEntityID (gpip->input_entityID);
8145   oldscope = SeqEntrySetScope (sep);
8146   assoc_list = BuildTableDataAssociation (sep, gpip->table_data, match_func, match_pos);
8147   err_list = CheckTableDataAssociation (assoc_list, gpip->bfp, gpip->table_data, match_pos,
8148                                  BioseqHasGenomeProjectID,
8149                                  "%d sequences already have a Genome Project ID.",
8150                                  "%d sequences will get more than one Genome Project ID from the table.",
8151                                  data_needed, num_parts);
8152 
8153 
8154 
8155   if (err_list == NULL || GetTableOptions (gpip->bfp, err_list, "Errors Matching Sequences from File", "", "",
8156                        "Skip sequences that already have Genome Project IDs",
8157                        "Erase Genome Project IDs when table cell is blank",
8158                        &skip_already_has, &blanks_erase)) {
8159     ApplyGenomeProjectIDByTableDataAssociationList (assoc_list, project_id_col, !skip_already_has, blanks_erase, gpip->input_entityID);
8160     ok = TRUE;
8161   }
8162   assoc_list = ValNodeFree (assoc_list);
8163   if (ok) {
8164     ObjMgrSetDirtyFlag (gpip->input_entityID, TRUE);
8165     ObjMgrSendMsg (OM_MSG_UPDATE, gpip->input_entityID, 0, 0);
8166     ArrowCursor ();
8167     Update ();
8168     Remove (gpip->form);
8169   }
8170   SeqEntrySetScope (oldscope);
8171 }
8172 
8173 
LoadGenomeProjectIDsFromFile(IteM i)8174 extern void LoadGenomeProjectIDsFromFile (IteM i)
8175 {
8176   BaseFormPtr   bfp;
8177   WindoW        w;
8178   GenomeProjectIdPtr gpip;
8179   GrouP              h, g, c;
8180   ButtoN             b;
8181 
8182 #ifdef WIN_MAC
8183   bfp = currentFormDataPtr;
8184 #else
8185   bfp = GetObjectExtra (i);
8186 #endif
8187   if (bfp == NULL) return;
8188 
8189   gpip = (GenomeProjectIdPtr) MemNew (sizeof(GenomeProjectIdData));
8190   gpip->table_data = ReadTableData ();
8191   if (gpip->table_data == NULL) {
8192     gpip = MemFree (gpip);
8193     return;
8194   }
8195   gpip->bfp = bfp;
8196 
8197   w = FixedWindow (-50, -33, -10, -10, "Add Genome Project IDs", StdCloseWindowProc);
8198   gpip->form = (ForM) w;
8199   SetObjectExtra (w, gpip, CleanupGenomeProjectIDForm);
8200   gpip->input_entityID = bfp->input_entityID;
8201 
8202   h = HiddenGroup (w, -1, 0, NULL);
8203 
8204   g = HiddenGroup (h, 6, 0, NULL);
8205   SetGroupSpacing (g, 10, 10);
8206   StaticPrompt (g, "Match", 0, dialogTextHeight, systemFont, 'c');
8207   gpip->match_column = PopupList (g, TRUE, NULL);
8208   FormatPopupWithTableDataColumns (gpip->match_column, gpip->table_data);
8209   SetValue (gpip->match_column, 1);
8210 
8211   StaticPrompt (g, "To", 0, dialogTextHeight, systemFont, 'c');
8212   gpip->id_column = PopupList (g, TRUE, NULL);
8213   PopupItem (gpip->id_column, "Accession");
8214   PopupItem (gpip->id_column, "Tax Name");
8215   SetValue (gpip->id_column, 1);
8216   StaticPrompt (g, "Use Project ID from", 0, dialogTextHeight, systemFont, 'c');
8217   gpip->gpid_column = PopupList (g, TRUE, NULL);
8218   FormatPopupWithTableDataColumns (gpip->gpid_column, gpip->table_data);
8219   SetValue (gpip->gpid_column, 1);
8220 
8221   c = HiddenGroup (h, 4, 0, NULL);
8222   b = DefaultButton (c, "Accept", ApplyGenomeProjectIDs);
8223   SetObjectExtra (b, gpip, NULL);
8224   b = PushButton (c, "Cancel", StdCancelButtonProc);
8225   SetObjectExtra (b, gpip, NULL);
8226   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
8227   RealizeWindow (w);
8228   Show (w);
8229   Update ();
8230 }
8231 
8232 
SuppressGenesOnFeaturesInsideMobileElementsCallback(BioseqPtr bsp,Pointer data)8233 static void SuppressGenesOnFeaturesInsideMobileElementsCallback (BioseqPtr bsp, Pointer data)
8234 {
8235   SeqFeatPtr        mobile_element, sfp, gene;
8236   SeqMgrFeatContext fcontext_m, fcontext_s, fcontext_g;
8237   GeneRefPtr        grp;
8238   SeqFeatXrefPtr    xref;
8239 
8240   if (bsp == NULL) return;
8241 
8242   for (mobile_element = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_IMP, FEATDEF_repeat_region, &fcontext_m);
8243        mobile_element != NULL;
8244        mobile_element = SeqMgrGetNextFeature (bsp, mobile_element, SEQFEAT_IMP, FEATDEF_repeat_region, &fcontext_m)) {
8245     if (!IsMobileElement (mobile_element)) continue;
8246     for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext_s);
8247          sfp != NULL && fcontext_s.left <= fcontext_m.right;
8248          sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &fcontext_s)) {
8249       if (SeqLocCompare (sfp->location, mobile_element->location) == SLC_A_IN_B
8250           && SeqMgrGetGeneXref (sfp) == NULL) {
8251         /* suppress gene if gene not contained in mobile_element */
8252         gene = SeqMgrGetOverlappingGene (sfp->location, &fcontext_g);
8253         if (gene != NULL && (fcontext_g.left <= fcontext_m.left || fcontext_g.right >= fcontext_m.right)) {
8254           grp = GeneRefNew ();
8255           if (grp != NULL) {
8256 	          xref = SeqFeatXrefNew ();
8257 	          xref->data.choice = SEQFEAT_GENE;
8258 	          xref->data.value.ptrvalue = grp;
8259 	          xref->next = sfp->xref;
8260 	          sfp->xref = xref;
8261           }
8262         }
8263       }
8264     }
8265   }
8266 }
8267 
8268 
SuppressGenesOnFeaturesInsideMobileElements(IteM i)8269 extern void SuppressGenesOnFeaturesInsideMobileElements (IteM i)
8270 {
8271   BaseFormPtr       bfp;
8272   SeqEntryPtr       sep;
8273 
8274 #ifdef WIN_MAC
8275   bfp = currentFormDataPtr;
8276 #else
8277   bfp = GetObjectExtra (i);
8278 #endif
8279   if (bfp == NULL || bfp->input_entityID == 0) return;
8280 
8281   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
8282 
8283   VisitBioseqsInSep (sep, NULL, SuppressGenesOnFeaturesInsideMobileElementsCallback);
8284 
8285   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
8286   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
8287   Update ();
8288 }
8289 
8290 
8291 /* Importing Protein ID Table */
8292 
8293 typedef struct featurefieldcolumnchoice {
8294   Int4            match_type;
8295   ValNodePtr      field_choice;
8296   Boolean         change_mrna;
8297   Boolean         erase_when_blank;
8298   ExistingTextPtr etp;
8299 } FeatureFieldColumnChoiceData, PNTR FeatureFieldColumnChoicePtr;
8300 
FeatureFieldColumnChoiceFree(FeatureFieldColumnChoicePtr f)8301 static FeatureFieldColumnChoicePtr FeatureFieldColumnChoiceFree (FeatureFieldColumnChoicePtr f)
8302 {
8303   if (f != NULL) {
8304     f->field_choice = ValNodeFree (f->field_choice);
8305     f->etp = MemFree (f->etp);
8306     f = MemFree (f);
8307   }
8308   return f;
8309 }
8310 
8311 
GetFeaturesForGene(SeqFeatPtr gene,Uint1 featdef)8312 static ValNodePtr GetFeaturesForGene (SeqFeatPtr gene, Uint1 featdef)
8313 {
8314   BioseqPtr bsp;
8315   SeqFeatPtr sfp;
8316   ValNodePtr feat_list = NULL;
8317   SeqMgrFeatContext fcontext;
8318   Int4              start, stop, swap;
8319 
8320   if (gene == NULL) return NULL;
8321 
8322   bsp = BioseqFindFromSeqLoc (gene->location);
8323   start = SeqLocStart (gene->location);
8324   stop = SeqLocStop (gene->location);
8325   if (stop < start)
8326   {
8327     swap = start;
8328     start = stop;
8329     stop = swap;
8330   }
8331   for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, featdef, &fcontext);
8332        sfp != NULL && fcontext.left < stop;
8333        sfp = SeqMgrGetNextFeature (bsp, sfp, 0, featdef, &fcontext))
8334   {
8335     if (fcontext.right >= start && gene == GetGeneForFeature (sfp))
8336     {
8337       ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
8338     }
8339   }
8340   return feat_list;
8341 }
8342 
GetFeatureListForProteinBioseq(Uint1 featdef,BioseqPtr bsp)8343 static ValNodePtr GetFeatureListForProteinBioseq (Uint1 featdef, BioseqPtr bsp)
8344 {
8345   ValNodePtr feat_list = NULL;
8346   SeqFeatPtr sfp, cds;
8347   SeqMgrFeatContext fcontext;
8348 
8349   if (bsp == NULL || !ISA_aa (bsp->mol))
8350   {
8351     return NULL;
8352   }
8353 
8354   if (featdef == FEATDEF_PROT || featdef == FEATDEF_mat_peptide_aa)
8355   {
8356     for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, featdef, &fcontext);
8357          sfp != NULL;
8358          sfp = SeqMgrGetNextFeature (bsp, sfp, 0, featdef, &fcontext))
8359     {
8360       ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
8361     }
8362   }
8363   else
8364   {
8365     cds = SeqMgrGetCDSgivenProduct (bsp, NULL);
8366     if (cds != NULL)
8367     {
8368       sfp = NULL;
8369       if (featdef == FEATDEF_CDS)
8370       {
8371         sfp = cds;
8372       }
8373       else if (featdef == FEATDEF_GENE)
8374       {
8375         sfp = GetGeneForFeature (cds);
8376       }
8377       else if (featdef == FEATDEF_mRNA)
8378       {
8379         sfp = SeqMgrGetOverlappingmRNA (cds->location, &fcontext);
8380       }
8381       if (sfp != NULL)
8382       {
8383         ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
8384       }
8385     }
8386   }
8387   return feat_list;
8388 }
8389 
8390 
GetFeatureListForGene(Uint1 featdef,SeqFeatPtr gene)8391 static ValNodePtr GetFeatureListForGene (Uint1 featdef, SeqFeatPtr gene)
8392 {
8393   ValNodePtr feat_list = NULL, cds_list, vnp;
8394   SeqFeatPtr sfp, cds;
8395   SeqMgrFeatContext fcontext;
8396   BioseqPtr         protbsp;
8397 
8398   if (gene == NULL)
8399   {
8400     return NULL;
8401   }
8402 
8403   if (featdef == FEATDEF_GENE)
8404   {
8405     ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, gene);
8406   }
8407   else if (featdef == FEATDEF_mRNA || featdef == FEATDEF_CDS)
8408   {
8409     feat_list = GetFeaturesForGene (gene, featdef);
8410   }
8411   else if (featdef == FEATDEF_PROT || featdef == FEATDEF_mat_peptide_aa)
8412   {
8413     cds_list = GetFeaturesForGene (gene, FEATDEF_CDS);
8414     for (vnp = cds_list; vnp != NULL; vnp = vnp->next)
8415     {
8416       cds = vnp->data.ptrvalue;
8417       if (cds != NULL)
8418       {
8419         protbsp = BioseqFindFromSeqLoc (cds->product);
8420         for (sfp = SeqMgrGetNextFeature (protbsp, NULL, 0, featdef, &fcontext);
8421              sfp != NULL;
8422              sfp = SeqMgrGetNextFeature (protbsp, sfp, 0, featdef, &fcontext))
8423         {
8424           ValNodeAddPointer (&feat_list, OBJ_SEQFEAT, sfp);
8425         }
8426       }
8427     }
8428     cds_list = ValNodeFree (cds_list);
8429   }
8430 
8431   return feat_list;
8432 }
8433 
8434 
GetFeatureForFieldByMatchList(ValNodePtr field,ValNodePtr match_list,ValNodePtr PNTR errors)8435 static SeqFeatPtr GetFeatureForFieldByMatchList (ValNodePtr field, ValNodePtr match_list, ValNodePtr PNTR errors)
8436 {
8437   Uint1 featdef;
8438   ValNodePtr vnp;
8439   ValNodePtr tmp;
8440   CharPtr    msg;
8441   CharPtr    no_match_fmt = "No feature found for %s";
8442   CharPtr    too_many_fmt = "%d features found for %s (only one allowed!)";
8443   CharPtr    bad_comb_fmt = "Multiple match columns specify different features (%s, %s)!";
8444   SeqFeatPtr sfp = NULL;
8445 
8446   if (field == NULL || match_list == NULL || errors == NULL) return NULL;
8447 
8448   featdef = (Uint1)FeatDefTypeFromFieldList (field);
8449   if (featdef == FEATDEF_BAD || featdef == FEATDEF_ANY)
8450   {
8451     return NULL;
8452   }
8453 
8454   for (vnp = match_list; vnp != NULL; vnp = vnp->next)
8455   {
8456     tmp = NULL;
8457     if (vnp->choice == OBJ_BIOSEQ)
8458     {
8459       tmp = GetFeatureListForProteinBioseq (featdef, vnp->data.ptrvalue);
8460     }
8461     else
8462     {
8463       tmp = GetFeatureListForGene (featdef, vnp->data.ptrvalue);
8464     }
8465     if (tmp == NULL)
8466     {
8467       msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (no_match_fmt) + StringLen (vnp->data.ptrvalue)));
8468       sprintf (msg, no_match_fmt, vnp->data.ptrvalue);
8469       ValNodeAddPointer (errors, 0, msg);
8470     }
8471     else if (tmp->next != NULL)
8472     {
8473       msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (too_many_fmt) + StringLen (vnp->data.ptrvalue) + 15));
8474       sprintf (msg, too_many_fmt, ValNodeLen (tmp), vnp->data.ptrvalue);
8475       ValNodeAddPointer (errors, 0, msg);
8476     }
8477     else if (sfp != NULL && sfp != tmp->data.ptrvalue)
8478     {
8479       msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (bad_comb_fmt) + StringLen (vnp->data.ptrvalue) + StringLen (match_list->data.ptrvalue)));
8480       sprintf (msg, too_many_fmt, match_list->data.ptrvalue, vnp->data.ptrvalue);
8481       ValNodeAddPointer (errors, 0, msg);
8482     }
8483     else
8484     {
8485       sfp = tmp->data.ptrvalue;
8486     }
8487     tmp = ValNodeFree (tmp);
8488   }
8489   return sfp;
8490 }
8491 
8492 
8493 static void
GetExistingValueCounts(TableLinePtr tlp,FeatureFieldColumnChoicePtr PNTR f_list,Int4 num_columns,ValNodePtr match_list,Int4Ptr existing_text,BoolPtr has_mrna,BoolPtr missing_mrna,ValNodePtr PNTR errors)8494 GetExistingValueCounts
8495 (TableLinePtr                     tlp,
8496  FeatureFieldColumnChoicePtr PNTR f_list,
8497  Int4                             num_columns,
8498  ValNodePtr                       match_list,
8499  Int4Ptr                          existing_text,
8500  BoolPtr                          has_mrna,
8501  BoolPtr                          missing_mrna,
8502  ValNodePtr PNTR                  errors)
8503 {
8504   Int4       i;
8505   ValNodePtr vnp;
8506   SeqFeatPtr sfp, mrna;
8507   CharPtr    val;
8508 
8509   if (tlp == NULL || f_list == NULL || existing_text == NULL) return;
8510 
8511   vnp = tlp->parts;
8512   for (i = 0; i < num_columns; i++)
8513   {
8514     if (f_list[i]->field_choice != NULL)
8515     {
8516       sfp = GetFeatureForFieldByMatchList (f_list[i]->field_choice, match_list, errors);
8517       if (sfp != NULL)
8518       {
8519         val = GetCDSGeneProtField (sfp, f_list[i]->field_choice, NULL);
8520         if (!StringHasNoText (val))
8521         {
8522           existing_text[i]++;
8523         }
8524         val = MemFree (val);
8525         if (IsCDSetProteinProductChoice (f_list[i]->field_choice) && f_list[i]->change_mrna)
8526         {
8527           mrna = GetmRNAForFeature (sfp);
8528           if (mrna == NULL)
8529           {
8530             *missing_mrna = TRUE;
8531           }
8532           else
8533           {
8534             *has_mrna = TRUE;
8535           }
8536         }
8537       }
8538     }
8539     if (vnp != NULL)
8540     {
8541       vnp = vnp->next;
8542     }
8543   }
8544 }
8545 
8546 
8547 static Int4
ApplyProteinIDTableLine(TableLinePtr tlp,FeatureFieldColumnChoicePtr PNTR f_list,Int4 num_columns,ValNodePtr match_list)8548 ApplyProteinIDTableLine
8549 (TableLinePtr                     tlp,
8550  FeatureFieldColumnChoicePtr PNTR f_list,
8551  Int4                             num_columns,
8552  ValNodePtr                       match_list)
8553 {
8554   Int4       index;
8555   ValNodePtr vnp;
8556   SeqFeatPtr sfp;
8557   ApplyValueData avd;
8558   ValNodePtr     errors = NULL;
8559   Int4           fields_affected = 0;
8560 
8561   if (tlp == NULL || f_list == NULL || match_list == NULL) return 0;
8562 
8563   index = 0;
8564   vnp = tlp->parts;
8565   while (index < num_columns)
8566   {
8567     if (f_list[index]->field_choice != NULL)
8568     {
8569       sfp = GetFeatureForFieldByMatchList (f_list[index]->field_choice, match_list, &errors);
8570       if (sfp != NULL)
8571       {
8572         if (vnp == NULL || StringHasNoText (vnp->data.ptrvalue))
8573         {
8574           if (f_list[index]->erase_when_blank)
8575           {
8576             RemoveCDSGeneProtField (sfp, f_list[index]->field_choice, NULL);
8577             fields_affected++;
8578           }
8579         }
8580         else
8581         {
8582           avd.etp = f_list[index]->etp;
8583           avd.field_list = f_list[index]->field_choice;
8584           avd.new_text = vnp->data.ptrvalue;
8585           avd.text_to_replace = NULL;
8586           avd.where_to_replace = EditApplyFindLocation_anywhere;
8587           SetCDSGeneProtField (sfp, f_list[index]->field_choice, &avd, NULL);
8588           fields_affected ++;
8589         }
8590         /* note - need special case to change mRNA product if CDS product changes */
8591         if (IsCDSetProteinProductChoice (f_list[index]->field_choice) && f_list[index]->change_mrna)
8592         {
8593           if (AdjustmRNAProductToMatchProteinProduct (sfp))
8594           {
8595             fields_affected++;
8596           }
8597         }
8598       }
8599     }
8600     index++;
8601     if (vnp != NULL)
8602     {
8603       vnp = vnp->next;
8604     }
8605   }
8606   errors = ValNodeFreeData (errors);
8607   return fields_affected;
8608 }
8609 
8610 
8611 typedef struct featurefieldcolumnchoicedlg {
8612   DIALOG_MESSAGE_BLOCK
8613   GrouP                    match_or_field;
8614   PopuP                    match_type;
8615   DialoG                   field_choice;
8616   ButtoN                   change_mrna;
8617   /* for existing text options */
8618   GrouP                    apply_options;
8619   ButtoN                   erase_when_blank;
8620   GrouP                    existing_text_action_grp;
8621   GrouP                    existing_text_delim_grp;
8622 
8623   Nlm_ChangeNotifyProc     change_notify;
8624   Pointer                  change_userdata;
8625 } FeatureFieldColumnChoiceDlgData, PNTR FeatureFieldColumnChoiceDlgPtr;
8626 
FeatureFieldColumnChoicePopupChange(PopuP p)8627 static void FeatureFieldColumnChoicePopupChange (PopuP p)
8628 {
8629   FeatureFieldColumnChoiceDlgPtr dlg;
8630 
8631   dlg = (FeatureFieldColumnChoiceDlgPtr) GetObjectExtra (p);
8632   if (dlg != NULL && dlg->change_notify != NULL) {
8633     (dlg->change_notify) (dlg->change_userdata);
8634   }
8635 }
8636 
8637 
FeatureFieldColumnChoiceFieldChange(Pointer data)8638 static void FeatureFieldColumnChoiceFieldChange (Pointer data)
8639 {
8640   FeatureFieldColumnChoiceDlgPtr dlg;
8641   ValNodePtr                     vnp;
8642 
8643   dlg = (FeatureFieldColumnChoiceDlgPtr) data;
8644   if (dlg != NULL) {
8645     vnp = DialogToPointer (dlg->field_choice);
8646     if (IsCDSetProteinProductChoice (vnp)) {
8647       Enable (dlg->change_mrna);
8648     } else {
8649       Disable (dlg->change_mrna);
8650     }
8651     vnp = ValNodeFree (vnp);
8652     if (dlg->change_notify != NULL) {
8653       (dlg->change_notify) (dlg->change_userdata);
8654     }
8655   }
8656 }
8657 
8658 
FeatureFieldColumnChoiceGroupChange(GrouP p)8659 static void FeatureFieldColumnChoiceGroupChange (GrouP p)
8660 {
8661   FeatureFieldColumnChoiceDlgPtr dlg;
8662 
8663   dlg = (FeatureFieldColumnChoiceDlgPtr) GetObjectExtra (p);
8664   if (dlg != NULL) {
8665     if (GetValue (dlg->match_or_field) == 1) {
8666       Enable (dlg->match_type);
8667       Disable (dlg->field_choice);
8668       Disable (dlg->apply_options);
8669       Disable (dlg->change_mrna);
8670     } else {
8671       Disable (dlg->match_type);
8672       Enable (dlg->field_choice);
8673       Enable (dlg->apply_options);
8674       FeatureFieldColumnChoiceFieldChange (dlg);
8675     }
8676     if (dlg->change_notify != NULL) {
8677       (dlg->change_notify) (dlg->change_userdata);
8678     }
8679   }
8680 }
8681 
8682 
FeatureFieldColumnDialogToChoice(DialoG d)8683 static Pointer FeatureFieldColumnDialogToChoice (DialoG d)
8684 {
8685   FeatureFieldColumnChoiceDlgPtr dlg;
8686   FeatureFieldColumnChoicePtr    f;
8687   Int4                           existing_text_action;
8688   Int4                           existing_text_delimiter;
8689 
8690   dlg = (FeatureFieldColumnChoiceDlgPtr) GetObjectExtra (d);
8691   if (dlg == NULL) return NULL;
8692 
8693   f = (FeatureFieldColumnChoicePtr) MemNew (sizeof (FeatureFieldColumnChoiceData));
8694   f->change_mrna = FALSE;
8695   if (GetValue (dlg->match_or_field) == 1) {
8696     f->match_type = GetValue (dlg->match_type);
8697     f->etp = NULL;
8698     f->erase_when_blank = FALSE;
8699   } else {
8700     f->field_choice = DialogToPointer (dlg->field_choice);
8701     if (dlg->erase_when_blank == NULL) {
8702       f->erase_when_blank = FALSE;
8703     } else {
8704       f->erase_when_blank = GetStatus (dlg->erase_when_blank);
8705     }
8706     if (IsCDSetProteinProductChoice (f->field_choice)) {
8707       f->change_mrna = GetStatus (dlg->change_mrna);
8708     }
8709     f->etp = (ExistingTextPtr) MemNew (sizeof (ExistingTextData));
8710     existing_text_action = GetValue (dlg->existing_text_action_grp);
8711     if (existing_text_action == 1) {
8712       f->etp->existing_text_choice = eExistingTextChoiceReplaceOld;
8713     } else if (existing_text_action == 4) {
8714       f->etp->existing_text_choice = eExistingTextChoiceLeaveOld;
8715     } else {
8716       existing_text_delimiter = GetValue (dlg->existing_text_delim_grp);
8717       if (existing_text_action == 2) {
8718         f->etp->existing_text_choice = eExistingTextChoiceAppendSemi + existing_text_delimiter - 1;
8719       } else if (existing_text_action == 3) {
8720         f->etp->existing_text_choice = eExistingTextChoicePrefixSemi + existing_text_delimiter - 1;
8721       } else {
8722         f->etp->existing_text_choice = eExistingTextChoiceCancel;
8723       }
8724     }
8725   }
8726   return f;
8727 
8728 }
8729 
8730 
ChangeExistingTextActionChoice(GrouP g)8731 static void ChangeExistingTextActionChoice (GrouP g)
8732 {
8733   FeatureFieldColumnChoiceDlgPtr dlg;
8734   Int4                           action_choice;
8735 
8736   dlg = (FeatureFieldColumnChoiceDlgPtr) GetObjectExtra (g);
8737   if (dlg == NULL) return;
8738 
8739   action_choice = GetValue (dlg->existing_text_action_grp);
8740   if (action_choice == 2 || action_choice == 3) {
8741     Enable (dlg->existing_text_delim_grp);
8742   } else {
8743     Disable (dlg->existing_text_delim_grp);
8744   }
8745 }
8746 
8747 
FeatureFieldColumnChoiceDialog(GrouP h,CharPtr title,Int4 num_blank,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)8748 static DialoG FeatureFieldColumnChoiceDialog
8749 (GrouP                    h,
8750  CharPtr                  title,
8751  Int4                     num_blank,
8752  Nlm_ChangeNotifyProc     change_notify,
8753  Pointer                  change_userdata)
8754 {
8755   FeatureFieldColumnChoiceDlgPtr dlg;
8756   GrouP p, g1, g;
8757   ButtoN b1, b2;
8758   PrompT ppt;
8759   CharPtr real_title;
8760   CharPtr title_fmt = "(%d are blank)%s";
8761 
8762   dlg = (FeatureFieldColumnChoiceDlgPtr) MemNew (sizeof (FeatureFieldColumnChoiceDlgData));
8763 
8764   if (num_blank > 0) {
8765     real_title = (CharPtr) MemNew (sizeof (Char) * (StringLen (title_fmt) + StringLen (title) + 15));
8766     sprintf (real_title, title_fmt, num_blank, title);
8767   } else {
8768     real_title = title;
8769   }
8770 
8771   p = NormalGroup (h, -1, 0, real_title, programFont, NULL);
8772   SetObjectExtra (p, dlg, StdCleanupExtraProc);
8773 
8774   if (real_title != title) {
8775     real_title = MemFree (real_title);
8776   }
8777   dlg->dialog = (DialoG) p;
8778   dlg->fromdialog = FeatureFieldColumnDialogToChoice;
8779   dlg->change_notify = change_notify;
8780   dlg->change_userdata = change_userdata;
8781 
8782   g1 = HiddenGroup (p, 2, 0, NULL);
8783   dlg->match_or_field = HiddenGroup (g1, 0, 2, FeatureFieldColumnChoiceGroupChange);
8784   SetObjectExtra (dlg->match_or_field, dlg, NULL);
8785   b1 = RadioButton (dlg->match_or_field, "Match to");
8786   b2 = RadioButton (dlg->match_or_field, "Apply to");
8787   SetValue (dlg->match_or_field, 1);
8788 
8789   g = HiddenGroup (g1, 0, 2, NULL);
8790   dlg->match_type = PopupList (g, TRUE, FeatureFieldColumnChoicePopupChange);
8791   SetObjectExtra (dlg->match_type, dlg, NULL);
8792   PopupItem (dlg->match_type, "None");
8793   PopupItem (dlg->match_type, "ID");
8794   PopupItem (dlg->match_type, "Gene locus tag");
8795   SetValue (dlg->match_type, 1);
8796 
8797   dlg->field_choice = CDSGeneProtFieldSelectionDialog (g, FALSE, FeatureFieldColumnChoiceFieldChange, dlg);
8798   Disable (dlg->field_choice);
8799   AlignObjects (ALIGN_MIDDLE, (HANDLE) b1, (HANDLE) dlg->match_type, NULL);
8800   AlignObjects (ALIGN_MIDDLE, (HANDLE) b2, (HANDLE) dlg->field_choice, NULL);
8801 
8802   dlg->change_mrna = CheckBox (p, "Also change mRNA product name", NULL);
8803   Disable (dlg->change_mrna);
8804 
8805   dlg->apply_options = HiddenGroup (p, -1, 0, NULL);
8806   if (num_blank > 0) {
8807     dlg->erase_when_blank = CheckBox (dlg->apply_options, "Erase field when table cell is blank", NULL);
8808   } else {
8809     dlg->erase_when_blank = NULL;
8810   }
8811   dlg->existing_text_action_grp = HiddenGroup (dlg->apply_options, 4, 0, ChangeExistingTextActionChoice);
8812   SetGroupSpacing (dlg->existing_text_action_grp, 10, 10);
8813   SetObjectExtra (dlg->existing_text_action_grp, dlg, NULL);
8814   RadioButton (dlg->existing_text_action_grp, "Overwrite existing text");
8815   RadioButton (dlg->existing_text_action_grp, "Append");
8816   RadioButton (dlg->existing_text_action_grp, "Prefix");
8817   RadioButton (dlg->existing_text_action_grp, "Ignore new text");
8818   SetValue (dlg->existing_text_action_grp, 1);
8819 
8820   ppt = StaticPrompt (dlg->apply_options, "Separate new text and old text with",
8821                       0, dialogTextHeight, programFont, 'c');
8822 
8823   dlg->existing_text_delim_grp = HiddenGroup (dlg->apply_options, 4, 0, NULL);
8824   SetGroupSpacing (dlg->existing_text_delim_grp, 10, 10);
8825   RadioButton (dlg->existing_text_delim_grp, "Semicolon");
8826   RadioButton (dlg->existing_text_delim_grp, "Space");
8827   RadioButton (dlg->existing_text_delim_grp, "Colon");
8828   RadioButton (dlg->existing_text_delim_grp, "Do not separate");
8829   SetValue (dlg->existing_text_delim_grp, 1);
8830   Disable (dlg->existing_text_delim_grp);
8831 
8832   Disable (dlg->apply_options);
8833 
8834   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->existing_text_action_grp,
8835                               (HANDLE) ppt,
8836                               (HANDLE) dlg->existing_text_delim_grp,
8837                               (HANDLE) dlg->erase_when_blank,
8838                               NULL);
8839 
8840   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) dlg->change_mrna, (HANDLE) dlg->apply_options, NULL);
8841 
8842   return (DialoG) p;
8843 }
8844 
8845 typedef struct featurefieldtable {
8846   FEATURE_FORM_BLOCK
8847   ValNodePtr header_line;
8848   Int4       num_columns;
8849   DialoG PNTR columns;
8850   ButtoN      accept_button;
8851 } FeatureFieldTableData, PNTR FeatureFieldTablePtr;
8852 
8853 
CleanupFeatureFieldTableForm(GraphiC g,VoidPtr data)8854 static void CleanupFeatureFieldTableForm (GraphiC g, VoidPtr data)
8855 {
8856   FeatureFieldTablePtr  form;
8857 
8858   form = (FeatureFieldTablePtr) data;
8859   if (form != NULL) {
8860     CleanUpTableData (form->header_line);
8861     form->columns = MemFree (form->columns);
8862   }
8863   StdCleanupFormProc (g, data);
8864 }
8865 
8866 
8867 typedef struct findgenelocustag {
8868   CharPtr locus_tag;
8869   ValNodePtr gene_list;
8870 } FindGeneLocusTagData, PNTR FindGeneLocusTagPtr;
8871 
FindGeneByLocusTagBioseqCallback(BioseqPtr bsp,Pointer userdata)8872 static void FindGeneByLocusTagBioseqCallback (BioseqPtr bsp, Pointer userdata)
8873 {
8874   FindGeneLocusTagPtr p;
8875   SeqFeatPtr          gene;
8876   SeqMgrFeatContext   fcontext;
8877 
8878   if (bsp == NULL || userdata == NULL || !ISA_na (bsp->mol)) {
8879     return;
8880   }
8881 
8882   p = (FindGeneLocusTagPtr) userdata;
8883 
8884   gene = SeqMgrGetGeneByLocusTag (bsp, p->locus_tag, &fcontext);
8885   if (gene != NULL) {
8886     ValNodeAddPointer (&p->gene_list, OBJ_SEQFEAT, gene);
8887   }
8888 }
8889 
8890 
8891 static ValNodePtr
FindMatchListForRow(FeatureFieldColumnChoicePtr PNTR f_list,Int4 num_columns,SeqEntryPtr sep,TableLinePtr tlp,ValNodePtr PNTR missing_ids,ValNodePtr PNTR missing_genes)8892 FindMatchListForRow
8893 (FeatureFieldColumnChoicePtr PNTR f_list,
8894  Int4                             num_columns,
8895  SeqEntryPtr                      sep,
8896  TableLinePtr                     tlp,
8897  ValNodePtr PNTR                  missing_ids,
8898  ValNodePtr PNTR                  missing_genes)
8899 {
8900   Int4       index;
8901   ValNodePtr match_list = NULL, vnp_match;
8902   SeqIdPtr   sip;
8903   BioseqPtr  bsp;
8904   FindGeneLocusTagData fd;
8905 
8906   if (f_list == NULL || tlp == NULL || tlp->parts == NULL || sep == NULL) return NULL;
8907   for (index = 0, vnp_match = tlp->parts;
8908        index < num_columns && vnp_match != NULL;
8909        index++, vnp_match = vnp_match->next)
8910   {
8911     if (f_list[index]->match_type == 2)
8912     {
8913       sip = CreateSeqIdFromText (vnp_match->data.ptrvalue, sep);
8914       bsp = BioseqFind (sip);
8915       sip = SeqIdFree (sip);
8916       if (bsp == NULL)
8917       {
8918         if (missing_ids != NULL)
8919         {
8920           ValNodeAddPointer (missing_ids, 0, StringSave (vnp_match->data.ptrvalue));
8921         }
8922       }
8923       else
8924       {
8925         ValNodeAddPointer (&match_list, OBJ_BIOSEQ, bsp);
8926       }
8927     }
8928     else if (f_list[index]->match_type == 3)
8929     {
8930       fd.locus_tag = vnp_match->data.ptrvalue;
8931       fd.gene_list = NULL;
8932       VisitBioseqsInSep (sep, &fd, FindGeneByLocusTagBioseqCallback);
8933       if (fd.gene_list == NULL)
8934       {
8935         if (missing_genes != NULL)
8936         {
8937           ValNodeAddPointer (missing_genes, 0, StringSave (vnp_match->data.ptrvalue));
8938         }
8939       }
8940       else
8941       {
8942         ValNodeLink (&match_list, fd.gene_list);
8943         fd.gene_list = NULL;
8944       }
8945     }
8946   }
8947   return match_list;
8948 }
8949 
8950 
DoLoadFeatureFieldTable(ButtoN b)8951 static void DoLoadFeatureFieldTable (ButtoN b)
8952 {
8953   FeatureFieldTablePtr  form;
8954   SeqEntryPtr           sep, oldscope;
8955   ValNodePtr            vnp;
8956   FeatureFieldColumnChoicePtr PNTR f_list;
8957   Int4                             index;
8958   Int4                             num_rows;
8959   ValNodePtr PNTR                  match_lists;
8960   ValNodePtr                       missing_ids = NULL, missing_genes = NULL;
8961   CharPtr                          msg;
8962   Int4Ptr                          existing_text;
8963   Boolean                          has_mrna = FALSE;
8964   Boolean                          missing_mrna = FALSE;
8965   ValNodePtr                       errors = NULL;
8966   LogInfoPtr                       lip;
8967   Int4                             fields_affected = 0;
8968   CharPtr                          label;
8969 
8970   form = (FeatureFieldTablePtr) GetObjectExtra (b);
8971   if (form == NULL) return;
8972 
8973   sep = GetTopSeqEntryForEntityID (form->input_entityID);
8974 
8975   f_list = (FeatureFieldColumnChoicePtr PNTR) MemNew (form->num_columns * sizeof (FeatureFieldColumnChoicePtr));
8976   for (index = 0; index < form->num_columns; index++) {
8977     f_list[index] = DialogToPointer (form->columns[index]);
8978   }
8979 
8980   /* find match items (either protein IDs or genes) for each row */
8981   /* make sure all IDs and gene locus_tags in table are in record */
8982   num_rows = ValNodeLen (form->header_line);
8983   match_lists = (ValNodePtr PNTR) MemNew (num_rows * sizeof (ValNodePtr));
8984   for (index = 0, vnp = form->header_line; index < num_rows && vnp != NULL; index++, vnp = vnp->next) {
8985     match_lists[index] = FindMatchListForRow (f_list, form->num_columns, sep, vnp->data.ptrvalue, &missing_ids, &missing_genes);
8986   }
8987 
8988   if (missing_ids != NULL) {
8989     msg = CreateListMessage ("ID",
8990   	                         missing_ids->next == NULL
8991   	                         ? " is not found in this record."
8992   	                         : " not found in this record.",
8993   	                         missing_ids);
8994     ValNodeAddPointer (&errors, 0, msg);
8995     missing_ids = ValNodeFreeData (missing_ids);
8996   }
8997   if (missing_genes != NULL) {
8998     msg = CreateListMessage ("Gene",
8999   	                         missing_genes->next == NULL
9000   	                         ? " is not found in this record."
9001   	                         : " not found in this record.",
9002   	                         missing_genes);
9003     ValNodeAddPointer (&errors, 0, msg);
9004     missing_genes = ValNodeFreeData (missing_genes);
9005   }
9006 
9007   existing_text = (Int4Ptr) MemNew (form->num_columns * sizeof (Int4));
9008 
9009   for (vnp = form->header_line, index = 0; vnp != NULL; vnp = vnp->next, index++) {
9010     if (vnp->data.ptrvalue == NULL) continue;
9011     GetExistingValueCounts (vnp->data.ptrvalue, f_list, form->num_columns, match_lists[index], existing_text, &has_mrna, &missing_mrna, &errors);
9012   }
9013 
9014   lip = OpenLog ("Table Problems");
9015   for (vnp = errors; vnp != NULL; vnp = vnp->next) {
9016     fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
9017     lip->data_in_log = TRUE;
9018   }
9019   errors = ValNodeFreeData (errors);
9020 
9021   if (has_mrna && missing_mrna) {
9022     fprintf (lip->fp, "Some coding regions for which product names will be set have overlapping mRNA features, but some do not!\n");
9023     lip->data_in_log = TRUE;
9024   }
9025   for (index = 0; index < form->num_columns; index++) {
9026     if (f_list[index]->field_choice != NULL) {
9027       if (existing_text[index] > 0) {
9028         label = GetCDSGeneProtFieldName (f_list[index]->field_choice);
9029         fprintf (lip->fp, "%d features affected by column %d contain existing text in field %s.\n", existing_text[index], index + 1, label);
9030         label = MemFree (label);
9031         lip->data_in_log = TRUE;
9032       }
9033     }
9034   }
9035   CloseLog (lip);
9036   if (lip->data_in_log) {
9037     if (ANS_CANCEL == Message (MSG_OKC, "Continue with errors?")) {
9038       existing_text = MemFree (existing_text);
9039       /* free match lists */
9040       for (index = 0; index < num_rows; index++) {
9041         match_lists[index] = ValNodeFree (match_lists[index]);
9042       }
9043       /* free choices */
9044       for (index = 0; index < form->num_columns; index++) {
9045         f_list[index] = FeatureFieldColumnChoiceFree (f_list[index]);
9046       }
9047       return;
9048     }
9049   }
9050 
9051   oldscope = SeqEntrySetScope (sep);
9052 
9053   for (vnp = form->header_line, index = 0; vnp != NULL; vnp = vnp->next, index++) {
9054     if (vnp->data.ptrvalue == NULL) continue;
9055     fields_affected += ApplyProteinIDTableLine (vnp->data.ptrvalue, f_list, form->num_columns, match_lists[index]);
9056   }
9057 
9058   SeqEntrySetScope (oldscope);
9059 
9060   /* free match lists */
9061   for (index = 0; index < num_rows; index++) {
9062     match_lists[index] = ValNodeFree (match_lists[index]);
9063   }
9064   /* free choices */
9065   for (index = 0; index < form->num_columns; index++) {
9066     f_list[index] = FeatureFieldColumnChoiceFree (f_list[index]);
9067   }
9068 
9069   ObjMgrSetDirtyFlag (form->input_entityID, TRUE);
9070   ObjMgrSendMsg (OM_MSG_UPDATE, form->input_entityID, 0, 0);
9071   Remove (form->form);
9072   Message (MSG_OK, "%d fields were affected", fields_affected);
9073 }
9074 
SetFeatureFieldTableAccept(Pointer data)9075 static void SetFeatureFieldTableAccept (Pointer data)
9076 {
9077   FeatureFieldTablePtr form;
9078   Int4                 index;
9079   FeatureFieldColumnChoicePtr f;
9080   Boolean                     have_match = FALSE, have_apply = FALSE;
9081 
9082   form = (FeatureFieldTablePtr) data;
9083   if (form == NULL) return;
9084 
9085   for (index = 0; index < form->num_columns && (!have_match || !have_apply); index++)
9086   {
9087     f = DialogToPointer (form->columns[index]);
9088     if (f != NULL)
9089     {
9090       if (f->match_type > 1)
9091       {
9092         have_match = TRUE;
9093       }
9094       else if (f->field_choice != NULL)
9095       {
9096         have_apply = TRUE;
9097       }
9098       f = FeatureFieldColumnChoiceFree (f);
9099     }
9100   }
9101   if (have_match && have_apply)
9102   {
9103     Enable (form->accept_button);
9104   }
9105   else
9106   {
9107     Disable (form->accept_button);
9108   }
9109 }
9110 
9111 
LoadFeatureFieldTable(IteM i)9112 extern void LoadFeatureFieldTable (IteM i)
9113 {
9114   BaseFormPtr          bfp;
9115   SeqEntryPtr          sep;
9116   ValNodePtr           header_line;
9117   Int4                 index;
9118   FeatureFieldTablePtr form;
9119   WindoW               w;
9120   GrouP                h, g, c;
9121   TableLinePtr         tlp;
9122   ValNodePtr           vnp;
9123   Int4Ptr              blank_list = NULL;
9124 
9125 #ifdef WIN_MAC
9126   bfp = currentFormDataPtr;
9127 #else
9128   bfp = GetObjectExtra (i);
9129 #endif
9130   if (bfp == NULL || bfp->input_entityID == 0) return;
9131 
9132   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9133 
9134 
9135   header_line = ReadTableData ();
9136   if (header_line == NULL || header_line->data.ptrvalue == NULL) {
9137     CleanUpTableData (header_line);
9138     return;
9139   }
9140 
9141   /* use form to pick columns for IDs, values */
9142 
9143   form = (FeatureFieldTablePtr) MemNew (sizeof (FeatureFieldTableData));
9144   if (form == NULL) return;
9145   form->input_entityID = bfp->input_entityID;
9146   form->header_line = header_line;
9147   tlp = (TableLinePtr) header_line->data.ptrvalue;
9148   form->num_columns = ValNodeLen (tlp->parts);
9149   form->columns = (DialoG PNTR) MemNew (form->num_columns * sizeof (DialoG));
9150 
9151   /* now create a dialog to display values */
9152   w = FixedWindow (-50, -33, -10, -10, "Feature Field Table", StdCloseWindowProc);
9153   SetObjectExtra (w, form, CleanupFeatureFieldTableForm);
9154   form->form = (ForM) w;
9155 
9156   h = HiddenGroup (w, -1, 0, NULL);
9157   SetGroupSpacing (h, 10, 10);
9158   g = HiddenGroup (h, 3, 0, NULL);
9159 
9160   /* pre-analyze table for blanks, so we can display the information in the column dialogs */
9161   blank_list = GetColumnBlankCounts (header_line, form->num_columns);
9162 
9163   for (vnp = tlp->parts, index = 0; vnp != NULL; vnp = vnp->next, index++)
9164   {
9165     form->columns[index] = FeatureFieldColumnChoiceDialog (g, vnp->data.ptrvalue,
9166                                                            blank_list == NULL ? 0 : blank_list[index],
9167                                                            SetFeatureFieldTableAccept, form);
9168   }
9169   blank_list = MemFree (blank_list);
9170 
9171   c = HiddenGroup (h, 4, 0, NULL);
9172   form->accept_button = DefaultButton (c, "Accept", DoLoadFeatureFieldTable);
9173   SetObjectExtra (form->accept_button, form, NULL);
9174   Disable (form->accept_button);
9175   PushButton (c, "Cancel", StdCancelButtonProc);
9176 
9177   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
9178   RealizeWindow (w);
9179   Show (w);
9180   Update ();
9181 }
9182 
GetRevSectionSequence(Uint1 data_choice,Pointer data,Pointer metadata)9183 static Pointer GetRevSectionSequence (Uint1 data_choice, Pointer data, Pointer metadata)
9184 {
9185   BioseqPtr bsp;
9186   Char        id_str[45];
9187 
9188   if (data == NULL)
9189   {
9190     return NULL;
9191   }
9192   else
9193   {
9194     bsp = (BioseqPtr) data;
9195     SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, 39);
9196     return StringSave (id_str);
9197   }
9198 }
9199 
9200 
GetRevSectionInterval(Uint1 data_choice,Pointer data,Pointer metadata)9201 static Pointer GetRevSectionInterval (Uint1 data_choice, Pointer data, Pointer metadata)
9202 {
9203   BioseqPtr bsp;
9204   DeltaSeqPtr dsp;
9205   Uint1       seg_num = 0;
9206   Int4        pos = 0;
9207   SeqLocPtr   loc;
9208   SeqLitPtr   slip;
9209   Char        buf[50];
9210 
9211   if ((bsp = (BioseqPtr)data) == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext == NULL)
9212   {
9213     return NULL;
9214   }
9215 
9216   for (dsp = (DeltaSeqPtr)(bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
9217     switch (dsp->choice)
9218     {
9219       case 1:      /* SeqLocPtr */
9220         if ((loc = (SeqLocPtr)dsp->data.ptrvalue) != NULL) {
9221           if (loc->choice != SEQLOC_NULL) {
9222             seg_num++;
9223             pos += SeqLocLen (loc);
9224           }
9225         }
9226         break;
9227       case 2:   /* SeqLitPtr */
9228         slip = (SeqLitPtr)(dsp->data.ptrvalue);
9229         if (slip != NULL) {
9230           if (slip->seq_data != NULL) {
9231             if (seg_num == data_choice) {
9232               sprintf (buf, "%d-%d", pos + 1, pos + 1 + slip->length);
9233               return StringSave (buf);
9234             } else {
9235               seg_num++;
9236             }
9237             pos += slip->length;
9238           }
9239         }
9240         break;
9241     }
9242   }
9243   return NULL;
9244 }
9245 
9246 
9247 /*
9248 static BulkEdFieldData revsection_fields[] = {
9249   { "Sequence", NULL, NULL, GetRevSectionSequence, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
9250   { "Interval", NULL, NULL, GetRevSectionInterval, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
9251   { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
9252 */
9253 
9254 
9255 typedef struct deltaseqint {
9256   BioseqPtr bsp;
9257   Int4      start;
9258   Int4      stop;
9259   SeqLitPtr slip;
9260 } DeltaSeqIntData, PNTR DeltaSeqIntPtr;
9261 
9262 
DeltaSeqIntNew(BioseqPtr bsp,Int4 start,Int4 stop,SeqLitPtr slip)9263 static DeltaSeqIntPtr DeltaSeqIntNew (BioseqPtr bsp, Int4 start, Int4 stop, SeqLitPtr slip)
9264 {
9265   DeltaSeqIntPtr dsip;
9266 
9267   dsip = (DeltaSeqIntPtr) MemNew (sizeof (DeltaSeqIntData));
9268   dsip->bsp = bsp;
9269   dsip->start = start;
9270   dsip->stop = stop;
9271   dsip->slip = slip;
9272   return dsip;
9273 }
9274 
9275 
ListDeltaSeqIntervalsCallback(BioseqPtr bsp,Pointer userdata)9276 static void ListDeltaSeqIntervalsCallback (BioseqPtr bsp, Pointer userdata)
9277 {
9278   ValNodePtr PNTR interval_list;
9279   DeltaSeqPtr dsp;
9280   Uint1       seg_num = 0;
9281   Int4        pos = 0;
9282   SeqLocPtr   loc;
9283   SeqLitPtr   slip;
9284   Char        id_str[45];
9285   ClickableItemPtr cip;
9286 
9287   if (bsp == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext == NULL || (interval_list = (ValNodePtr PNTR)userdata) == NULL) {
9288     return;
9289   }
9290 
9291   SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, sizeof (id_str) - 1);
9292 
9293   for (dsp = (DeltaSeqPtr)(bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
9294     switch (dsp->choice)
9295     {
9296       case 1:      /* SeqLocPtr */
9297         if ((loc = (SeqLocPtr)dsp->data.ptrvalue) != NULL) {
9298           if (loc->choice != SEQLOC_NULL) {
9299             seg_num++;
9300             pos += SeqLocLen (loc);
9301           }
9302         }
9303         break;
9304       case 2:   /* SeqLitPtr */
9305         slip = (SeqLitPtr)(dsp->data.ptrvalue);
9306         if (slip != NULL) {
9307           if (slip->seq_data != NULL) {
9308             cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
9309             cip->description = (CharPtr) MemNew (sizeof (Char) * (StringLen (id_str) + 65));
9310             sprintf (cip->description, "%s:%d-%d", id_str, pos + 1, pos + slip->length);
9311             cip->clickable_item_type = seg_num;
9312             ValNodeAddPointer (&cip->item_list, 0, DeltaSeqIntNew (bsp, pos, pos + slip->length - 1, slip));
9313             ValNodeAddPointer (interval_list, 0, cip);
9314             seg_num++;
9315           }
9316           pos += slip->length;
9317         }
9318         break;
9319     }
9320   }
9321 }
9322 
9323 
GetHighestInterval(ValNodePtr int_list)9324 static Int4 GetHighestInterval (ValNodePtr int_list)
9325 {
9326   Int4 max = 0;
9327   ClickableItemPtr cip;
9328 
9329   while (int_list != NULL) {
9330     cip = (ClickableItemPtr) int_list->data.ptrvalue;
9331     if (cip != NULL && cip->clickable_item_type > max) {
9332       max = cip->clickable_item_type;
9333     }
9334     int_list = int_list->next;
9335   }
9336   return max;
9337 }
9338 
9339 
9340 typedef struct revseqintform {
9341   FORM_MESSAGE_BLOCK
9342   DialoG          clickable_list;
9343   PopuP           interval_choice;
9344   ButtoN          also_reverse_feats;
9345   ValNodePtr      delta_list;
9346 } RevSeqIntFormData, PNTR RevSeqIntFormPtr;
9347 
CleanupRevSeqIntForm(GraphiC g,VoidPtr data)9348 static void CleanupRevSeqIntForm (GraphiC g, VoidPtr data)
9349 {
9350   RevSeqIntFormPtr f;
9351   ValNodePtr       vnp;
9352   ClickableItemPtr cip;
9353 
9354   f = (RevSeqIntFormPtr) data;
9355   if (f != NULL) {
9356     for (vnp = f->delta_list; vnp != NULL; vnp = vnp->next) {
9357       /* note - the rest of the ClickableItem will be freed by the clickableItemlist */
9358       cip = (ClickableItemPtr) vnp->data.ptrvalue;
9359       if (cip != NULL && cip->item_list != NULL) {
9360         cip->item_list->data.ptrvalue = MemFree (cip->item_list->data.ptrvalue);
9361       }
9362     }
9363   }
9364   StdCleanupFormProc (g, data);
9365 }
9366 
9367 
CheckIntervals(ButtoN b)9368 static void CheckIntervals (ButtoN b)
9369 {
9370   RevSeqIntFormPtr f;
9371   ValNodePtr       vnp;
9372   ClickableItemPtr cip;
9373   Int4             val;
9374 
9375   f = (RevSeqIntFormPtr) GetObjectExtra (b);
9376   if (f == NULL) return;
9377 
9378   val = GetValue (f->interval_choice);
9379   for (vnp = f->delta_list; vnp != NULL; vnp = vnp->next) {
9380     cip = (ClickableItemPtr) vnp->data.ptrvalue;
9381     if (cip != NULL && cip->clickable_item_type == val - 1) {
9382       cip->chosen = TRUE;
9383     }
9384   }
9385   PointerToDialog (f->clickable_list, f->delta_list);
9386 }
9387 
9388 
RevCompCoordInInterval(Int4 coord,Int4 start,Int4 stop)9389 static Int4 RevCompCoordInInterval (Int4 coord, Int4 start, Int4 stop)
9390 {
9391   Int4 offset;
9392 
9393   if (coord < start || coord > stop) return coord;
9394 
9395   offset = coord - start;
9396   coord = stop - offset;
9397   return coord;
9398 }
9399 
9400 
RevCompIntFuzz(IntFuzzPtr ifp,Int4 start,Int4 stop)9401 static void RevCompIntFuzz (IntFuzzPtr ifp, Int4 start, Int4 stop)
9402 {
9403   Int4 tmp;
9404 
9405   if (ifp == NULL) return;
9406 
9407 	switch (ifp->choice)
9408 	{
9409 		case 1:      /* plus/minus - no changes */
9410 		case 3:      /* percent - no changes */
9411 			break;
9412 		case 2:      /* range */
9413       tmp = RevCompCoordInInterval (ifp->a, start, stop);
9414       ifp->a = RevCompCoordInInterval (ifp->b, start, stop);
9415       ifp->b = tmp;
9416 			break;
9417 		case 4:     /* lim */
9418 			switch (ifp->a)
9419 			{
9420 				case 1:    /* greater than */
9421 					ifp->a = 2;
9422 					break;
9423 				case 2:    /* less than */
9424 					ifp->a = 1;
9425 					break;
9426 				case 3:    /* to right of residue */
9427 					ifp->a = 4;
9428 					break;
9429 				case 4:    /* to left of residue */
9430 					ifp->a = 3;
9431 					break;
9432 				default:
9433 					break;
9434 			}
9435 			break;
9436 	}
9437 }
9438 
RevStrand(Uint1 strand)9439 static Uint1 RevStrand (Uint1 strand)
9440 {
9441   if (strand == Seq_strand_minus) {
9442     strand = Seq_strand_plus;
9443   } else {
9444     strand = Seq_strand_minus;
9445   }
9446   return strand;
9447 }
9448 
9449 
RevCompSeqPntForFlippedInterval(SeqPntPtr spp,BioseqPtr bsp,Int4 start,Int4 stop)9450 static void RevCompSeqPntForFlippedInterval (SeqPntPtr spp, BioseqPtr bsp, Int4 start, Int4 stop)
9451 {
9452 
9453   if (spp == NULL || bsp == NULL) return;
9454   if (!SeqIdIn (spp->id, bsp->id)) return;
9455   if (spp->point < start || spp->point > stop) return;
9456 
9457   /* flip */
9458   spp->point = RevCompCoordInInterval (spp->point, start, stop);
9459   spp->strand = RevStrand (spp->strand);
9460   RevCompIntFuzz (spp->fuzz, start, stop);
9461 }
9462 
9463 
RevCompLocationForFlippedInterval(SeqLocPtr head,BioseqPtr bsp,Int4 start,Int4 stop)9464 static void RevCompLocationForFlippedInterval (SeqLocPtr head, BioseqPtr bsp, Int4 start, Int4 stop)
9465 {
9466 	SeqLocPtr slp;
9467 	SeqIntPtr sip;
9468 	SeqPntPtr spp;
9469 	PackSeqPntPtr pspp, pspp2;
9470 	SeqBondPtr sbp;
9471 	SeqIdPtr oldids;
9472 	Int4 numpnt, i, tpos, tmp;
9473 	Boolean do_rev;
9474 	IntFuzzPtr ifp;
9475 
9476 	if ((head == NULL) || (bsp == NULL)) return;
9477 
9478 	oldids = bsp->id;
9479 	switch (head->choice)
9480 	{
9481     case SEQLOC_BOND:   /* bond -- 2 seqs */
9482 			sbp = (SeqBondPtr)(head->data.ptrvalue);
9483       RevCompSeqPntForFlippedInterval (sbp->a, bsp, start, stop);
9484       RevCompSeqPntForFlippedInterval (sbp->b, bsp, start, stop);
9485 			break;
9486     case SEQLOC_FEAT:   /* feat -- can't track yet */
9487     case SEQLOC_NULL:    /* NULL */
9488     case SEQLOC_EMPTY:    /* empty */
9489 			break;
9490     case SEQLOC_WHOLE:    /* whole */
9491       /* nothing to reverse */
9492 			break;
9493     case SEQLOC_EQUIV:    /* does it stay equiv? */
9494     case SEQLOC_MIX:    /* mix -- more than one seq */
9495     case SEQLOC_PACKED_INT:    /* packed int */
9496 			for (slp = (SeqLocPtr)(head->data.ptrvalue); slp != NULL; slp = slp->next)
9497 			{
9498         RevCompLocationForFlippedInterval (slp, bsp, start, stop);
9499       }
9500       break;
9501     case SEQLOC_INT:    /* int */
9502 			sip = (SeqIntPtr)(head->data.ptrvalue);
9503 			if (SeqIdIn(sip->id, oldids))
9504 			{
9505         if (sip->from < start || sip->to > stop) {
9506           /* not contained in interval */
9507           break;
9508         }
9509         tmp = RevCompCoordInInterval (sip->from, start, stop);
9510         sip->from = RevCompCoordInInterval (sip->to, start, stop);
9511         sip->to = tmp;
9512         sip->strand = RevStrand (sip->strand);
9513         RevCompIntFuzz (sip->if_to, start, stop);
9514         RevCompIntFuzz (sip->if_from, start, stop);
9515         ifp = sip->if_to;
9516         sip->if_to = sip->if_from;
9517         sip->if_from = ifp;
9518       }
9519       break;
9520     case SEQLOC_PNT:    /* pnt */
9521 			spp = (SeqPntPtr)(head->data.ptrvalue);
9522       RevCompSeqPntForFlippedInterval (spp, bsp, start, stop);
9523       break;
9524     case SEQLOC_PACKED_PNT:    /* packed pnt */
9525 			pspp = (PackSeqPntPtr)(head->data.ptrvalue);
9526       do_rev = FALSE;
9527 			if (SeqIdIn(pspp->id, oldids))
9528 			{
9529         do_rev = TRUE;
9530 				numpnt = PackSeqPntNum(pspp);
9531         /* can only reverse set if all are in interval */
9532 				for (i = 0; i < numpnt && do_rev; i++)
9533 				{
9534 					tpos = PackSeqPntGet(pspp, i);
9535           if (tpos < start || tpos > stop) {
9536             do_rev = FALSE;
9537           }
9538         }
9539         if (do_rev) {
9540 				  pspp2 = PackSeqPntNew();
9541   				pspp2->id = pspp->id;
9542           pspp2->fuzz = pspp->fuzz;
9543           pspp->fuzz = NULL;
9544           RevCompIntFuzz (pspp2->fuzz, start, stop);
9545 				  for (i = 0; i < numpnt && do_rev; i++)
9546 				  {
9547 					  tpos = PackSeqPntGet(pspp, i);
9548             tpos = RevCompCoordInInterval (tpos, start, stop);
9549             PackSeqPntPut (pspp2, tpos);
9550           }
9551           pspp2->strand = RevStrand (pspp->strand);
9552           pspp = PackSeqPntFree (pspp);
9553           head->data.ptrvalue = pspp2;
9554 			  }
9555       }
9556       break;
9557     default:
9558       break;
9559 	}
9560 }
9561 
9562 
RevCompOneFeatForBioseqInterval(SeqFeatPtr sfp,BioseqPtr bsp,Int4 start,Int4 stop)9563 static void RevCompOneFeatForBioseqInterval (SeqFeatPtr sfp, BioseqPtr bsp, Int4 start, Int4 stop)
9564 {
9565   CodeBreakPtr cbp;
9566   CdRegionPtr  crp;
9567   RnaRefPtr    rrp;
9568   tRNAPtr      trp;
9569 
9570   if (sfp == NULL || bsp == NULL) return;
9571 
9572   RevCompLocationForFlippedInterval (sfp->location, bsp, start, stop);
9573   switch (sfp->data.choice) {
9574     case SEQFEAT_CDREGION :
9575       crp = (CdRegionPtr) sfp->data.value.ptrvalue;
9576       if (crp != NULL) {
9577         for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
9578           RevCompLocationForFlippedInterval (cbp->loc, bsp, start, stop);
9579         }
9580       }
9581       break;
9582     case SEQFEAT_RNA :
9583       rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
9584       if (rrp != NULL && rrp->ext.choice == 2) {
9585         trp = (tRNAPtr) rrp->ext.value.ptrvalue;
9586         if (trp != NULL && trp->anticodon != NULL) {
9587           RevCompLocationForFlippedInterval (trp->anticodon, bsp, start, stop);
9588         }
9589       }
9590       break;
9591     default :
9592       break;
9593   }
9594 }
9595 
9596 
FlipSelectedSequenceIntervals(ButtoN b)9597 static void FlipSelectedSequenceIntervals (ButtoN b)
9598 {
9599   RevSeqIntFormPtr f;
9600   ValNodePtr       vnp;
9601   ClickableItemPtr cip;
9602   Int4             num_disc;
9603   DeltaSeqIntPtr   dsip;
9604   Boolean          rev_feats;
9605   SeqFeatPtr        sfp;
9606   SeqMgrFeatContext fcontext;
9607 
9608   f = (RevSeqIntFormPtr) GetObjectExtra (b);
9609   if (f == NULL) return;
9610   num_disc = CountChosenDiscrepancies (f->delta_list, FALSE);
9611   if (num_disc == 0) {
9612     Message (MSG_ERROR, "No intervals selected");
9613     return;
9614   }
9615 
9616   rev_feats = GetStatus (f->also_reverse_feats);
9617 
9618   for (vnp = f->delta_list; vnp != NULL; vnp = vnp->next) {
9619     cip = (ClickableItemPtr) vnp->data.ptrvalue;
9620     if (cip != NULL && cip->chosen && cip->item_list != NULL) {
9621       dsip = (DeltaSeqIntPtr) cip->item_list->data.ptrvalue;
9622       if (dsip != NULL && dsip->slip != NULL) {
9623         ReverseSeqData (dsip->slip->seq_data_type, dsip->slip->length, dsip->slip->seq_data);
9624         ComplementSeqData (dsip->slip->seq_data_type, dsip->slip->length, dsip->slip->seq_data);
9625         if (rev_feats) {
9626           for (sfp = SeqMgrGetNextFeature (dsip->bsp, NULL, 0, 0, &fcontext);
9627                sfp != NULL && fcontext.left <= dsip->stop;
9628                sfp = SeqMgrGetNextFeature (dsip->bsp, sfp, 0, 0, &fcontext)) {
9629             if (fcontext.left >= dsip->start && fcontext.right <= dsip->stop) {
9630               RevCompOneFeatForBioseqInterval (sfp, dsip->bsp, dsip->start, dsip->stop);
9631             }
9632           }
9633         }
9634       }
9635     }
9636   }
9637   Update ();
9638   ObjMgrSetDirtyFlag (f->input_entityID, TRUE);
9639   ObjMgrSendMsg (OM_MSG_UPDATE, f->input_entityID, 0, 0);
9640   Remove (f->form);
9641 }
9642 
FlipSequenceIntervals(IteM i)9643 NLM_EXTERN void FlipSequenceIntervals (IteM i)
9644 {
9645   BaseFormPtr         bfp;
9646   RevSeqIntFormPtr    f;
9647   SeqEntryPtr         sep;
9648   WindoW              w;
9649   GrouP               h, g, c;
9650   ButtoN              b;
9651   ValNodePtr          delta_list = NULL;
9652   Int4                max, n;
9653   Char                buf[15];
9654 
9655 #ifdef WIN_MAC
9656   bfp = currentFormDataPtr;
9657 #else
9658   bfp = GetObjectExtra (i);
9659 #endif
9660   if (bfp == NULL || bfp->input_entityID == 0) return;
9661 
9662   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9663 
9664   VisitBioseqsInSep (sep, &delta_list, ListDeltaSeqIntervalsCallback);
9665 
9666   if (delta_list == NULL)
9667   {
9668     Message (MSG_OK, "No sequence intervals");
9669     return;
9670   }
9671 
9672 
9673   f = (RevSeqIntFormPtr) MemNew (sizeof (RevSeqIntFormData));
9674   if (f == NULL)
9675   {
9676     return;
9677   }
9678   f->delta_list = delta_list;
9679 
9680   f->input_entityID = bfp->input_entityID;
9681   w = FixedWindow (-50, -33, -10, -10, "Reverse Sequence Intervals", StdCloseWindowProc);
9682   SetObjectExtra (w, f, CleanupRevSeqIntForm);
9683   f->form = (ForM) w;
9684 
9685   h = HiddenGroup (w, -1, 0, NULL);
9686   SetGroupSpacing (h, 10, 10);
9687 
9688   f->clickable_list = CreateClickableListDialog (h, "Intervals", "",
9689                                                  NULL, NULL, NULL, NULL);
9690   PointerToDialog (f->clickable_list, f->delta_list);
9691 
9692   max = GetHighestInterval (f->delta_list);
9693 
9694   g = HiddenGroup (h, 4, 0, NULL);
9695   StaticPrompt (g, "Check Interval ", 0, popupMenuHeight, programFont, 'l');
9696   f->interval_choice = PopupList (g, TRUE, NULL);
9697   for (n = 0; n <= max; n++) {
9698     sprintf (buf, "%d", n + 1);
9699     PopupItem (f->interval_choice, buf);
9700   }
9701   SetValue (f->interval_choice, 1);
9702   StaticPrompt (g, " for every sequence", 0, popupMenuHeight, programFont, 'l');
9703   b = PushButton (g, "Check", CheckIntervals);
9704   SetObjectExtra (b, f, NULL);
9705 
9706   f->also_reverse_feats = CheckBox (h, "Also reverse features", NULL);
9707 
9708   c = HiddenGroup (h, 4, 0, NULL);
9709   SetGroupSpacing (c, 10, 10);
9710 
9711   b = PushButton (c, "Flip Checked Intervals", FlipSelectedSequenceIntervals);
9712   SetObjectExtra (b, f, NULL);
9713 
9714   PushButton (c, "Dismiss", StdCancelButtonProc);
9715 
9716   AlignObjects (ALIGN_CENTER, (HANDLE) f->clickable_list, (HANDLE) g, (HANDLE) f->also_reverse_feats, (HANDLE) c, NULL);
9717 
9718   RealizeWindow (w);
9719 
9720   Show (w);
9721 }
9722 
9723 
MacroAECRAction(IteM i,Boolean indexer_version,Uint1 action_type,Uint1 qual_type)9724 static void MacroAECRAction (IteM i, Boolean indexer_version, Uint1 action_type, Uint1 qual_type)
9725 {
9726   BaseFormPtr        bfp;
9727 
9728 #ifdef WIN_MAC
9729   bfp = currentFormDataPtr;
9730 #else
9731   bfp = GetObjectExtra (i);
9732 #endif
9733   if (bfp == NULL)
9734     return;
9735 
9736   SingleAECRMacroAction (bfp->input_entityID, indexer_version, action_type, qual_type);
9737 }
9738 
MacroApplyGBQual(IteM i)9739 extern void MacroApplyGBQual (IteM i)
9740 {
9741   MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_feature_field);
9742 }
9743 
9744 
MacroApplySourceQual(IteM i)9745 extern void MacroApplySourceQual (IteM i)
9746 {
9747   MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_source_qual);
9748 }
9749 
9750 
MacroApplyCDSGeneProt(IteM i)9751 extern void MacroApplyCDSGeneProt (IteM i)
9752 {
9753   MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_cds_gene_prot);
9754 }
9755 
PublicMacroApplyCDSGeneProt(IteM i)9756 extern void PublicMacroApplyCDSGeneProt (IteM i)
9757 {
9758   MacroAECRAction (i, FALSE, ActionChoice_apply, FieldType_cds_gene_prot);
9759 }
9760 
9761 
MacroApplyRNAQual(IteM i)9762 extern void MacroApplyRNAQual (IteM i)
9763 {
9764   MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_rna_field);
9765 }
9766 
9767 
MacroRemoveGBQual(IteM i)9768 extern void MacroRemoveGBQual (IteM i)
9769 {
9770   MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_feature_field);
9771 }
9772 
9773 
MacroRemoveSourceQual(IteM i)9774 extern void MacroRemoveSourceQual (IteM i)
9775 {
9776   MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_source_qual);
9777 }
9778 
9779 
MacroRemoveCDSGeneProt(IteM i)9780 extern void MacroRemoveCDSGeneProt (IteM i)
9781 {
9782   MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_cds_gene_prot);
9783 }
9784 
9785 
MacroRemoveRNAQual(IteM i)9786 extern void MacroRemoveRNAQual (IteM i)
9787 {
9788   MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_rna_field);
9789 }
9790 
9791 
MacroConvertGBQual(IteM i)9792 extern void MacroConvertGBQual (IteM i)
9793 {
9794   MacroAECRAction (i, TRUE, ActionChoice_convert, FieldType_feature_field);
9795 }
9796 
9797 
MacroConvertSourceQual(IteM i)9798 extern void MacroConvertSourceQual (IteM i)
9799 {
9800   MacroAECRAction (i, TRUE, ActionChoice_convert, FieldType_source_qual);
9801 }
9802 
9803 
MacroConvertCDSGeneProt(IteM i)9804 extern void MacroConvertCDSGeneProt (IteM i)
9805 {
9806   MacroAECRAction (i, TRUE, ActionChoice_convert, FieldType_cds_gene_prot);
9807 }
9808 
9809 
MacroConvertRNAQual(IteM i)9810 extern void MacroConvertRNAQual (IteM i)
9811 {
9812   MacroAECRAction (i, TRUE, ActionChoice_convert, FieldType_rna_field);
9813 }
9814 
9815 
MacroSwapGBQual(IteM i)9816 extern void MacroSwapGBQual (IteM i)
9817 {
9818   MacroAECRAction (i, TRUE, ActionChoice_swap, FieldType_feature_field);
9819 }
9820 
9821 
MacroSwapSourceQual(IteM i)9822 extern void MacroSwapSourceQual (IteM i)
9823 {
9824   MacroAECRAction (i, TRUE, ActionChoice_swap, FieldType_source_qual);
9825 }
9826 
9827 
MacroSwapCDSGeneProt(IteM i)9828 extern void MacroSwapCDSGeneProt (IteM i)
9829 {
9830   MacroAECRAction (i, TRUE, ActionChoice_swap, FieldType_cds_gene_prot);
9831 }
9832 
9833 
MacroSwapRNAQual(IteM i)9834 extern void MacroSwapRNAQual (IteM i)
9835 {
9836   MacroAECRAction (i, TRUE, ActionChoice_swap, FieldType_rna_field);
9837 }
9838 
9839 
MacroEditGBQual(IteM i)9840 extern void MacroEditGBQual (IteM i)
9841 {
9842   MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_feature_field);
9843 }
9844 
9845 
MacroEditSourceQual(IteM i)9846 extern void MacroEditSourceQual (IteM i)
9847 {
9848   MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_source_qual);
9849 }
9850 
9851 
MacroEditCDSGeneProt(IteM i)9852 extern void MacroEditCDSGeneProt (IteM i)
9853 {
9854   MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_cds_gene_prot);
9855 }
9856 
9857 
PublicMacroEditCDSGeneProt(IteM i)9858 extern void PublicMacroEditCDSGeneProt (IteM i)
9859 {
9860   MacroAECRAction (i, FALSE, ActionChoice_edit, FieldType_cds_gene_prot);
9861 }
9862 
9863 
MacroEditRNAQual(IteM i)9864 extern void MacroEditRNAQual (IteM i)
9865 {
9866   MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_rna_field);
9867 }
9868 
9869 
MacroApplyStructuredComment(IteM i)9870 extern void MacroApplyStructuredComment (IteM i)
9871 {
9872   MacroAECRAction (i, TRUE, ActionChoice_apply, FieldType_struc_comment_field);
9873 }
9874 
PublicMacroApplyStructuredComment(IteM i)9875 extern void PublicMacroApplyStructuredComment (IteM i)
9876 {
9877   MacroAECRAction (i, FALSE, ActionChoice_apply, FieldType_struc_comment_field);
9878 }
9879 
MacroEditStructuredComment(IteM i)9880 extern void MacroEditStructuredComment (IteM i)
9881 {
9882   MacroAECRAction (i, TRUE, ActionChoice_edit, FieldType_struc_comment_field);
9883 }
9884 
PublicMacroEditStructuredComment(IteM i)9885 extern void PublicMacroEditStructuredComment (IteM i)
9886 {
9887   MacroAECRAction (i, FALSE, ActionChoice_edit, FieldType_struc_comment_field);
9888 }
9889 
MacroRemoveStructuredComment(IteM i)9890 extern void MacroRemoveStructuredComment (IteM i)
9891 {
9892   MacroAECRAction (i, TRUE, ActionChoice_remove, FieldType_struc_comment_field);
9893 }
9894 
9895 
RemoveAllSourceNoteBaseForm(BaseFormPtr bfp)9896 NLM_EXTERN void RemoveAllSourceNoteBaseForm (BaseFormPtr bfp)
9897 {
9898   SeqEntryPtr sep;
9899   RemoveActionPtr remove;
9900   AECRActionPtr aecr;
9901   ValNodePtr    aecr_a;
9902   ValNodePtr    macro;
9903   ValNodePtr    src_field;
9904 
9905   if (bfp == NULL) {
9906     return;
9907   }
9908 
9909   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9910   if (sep == NULL) {
9911     return;
9912   }
9913 
9914   src_field = ValNodeNew (NULL);
9915   src_field->choice = SourceQualChoice_textqual;
9916   src_field->data.intvalue = Source_qual_all_notes;
9917   remove = RemoveActionNew ();
9918   remove->field = ValNodeNew (NULL);
9919   remove->field->choice = FieldType_source_qual;
9920   remove->field->data.ptrvalue = src_field;
9921   aecr_a = ValNodeNew (NULL);
9922   aecr_a->choice = ActionChoice_remove;
9923   aecr_a->data.ptrvalue = remove;
9924   aecr = AECRActionNew ();
9925   aecr->action = aecr_a;
9926   macro = ValNodeNew (NULL);
9927   macro->choice = MacroActionChoice_aecr;
9928   macro->data.ptrvalue = aecr;
9929 
9930   ApplyMacroToSeqEntryEx (sep, macro, NULL, Sequin_GlobalAlign2Seq);
9931 
9932   macro = MacroActionChoiceFree(macro);
9933 }
9934 
9935 
ApplyIsolationSourceBaseForm(BaseFormPtr bfp)9936 NLM_EXTERN void ApplyIsolationSourceBaseForm (BaseFormPtr bfp)
9937 {
9938   ForM           f;
9939   ValNodePtr     macro;
9940   ValNodePtr     src_field;
9941   ApplyActionPtr apply;
9942   AECRActionPtr  aecr;
9943   ValNodePtr     aecr_a;
9944 
9945   f = SingleMacroAction (bfp->input_entityID, TRUE);
9946 
9947   src_field = ValNodeNew (NULL);
9948   src_field->choice = SourceQualChoice_textqual;
9949   src_field->data.intvalue = Source_qual_isolation_source;
9950 
9951   apply = ApplyActionNew ();
9952   apply->field = ValNodeNew (NULL);
9953   apply->field->choice = FieldType_source_qual;
9954   apply->field->data.ptrvalue = src_field;
9955 
9956   aecr_a = ValNodeNew (NULL);
9957   aecr_a->choice = ActionChoice_apply;
9958   aecr_a->data.ptrvalue = apply;
9959   aecr = AECRActionNew ();
9960   aecr->action = aecr_a;
9961 
9962   macro = ValNodeNew (NULL);
9963   macro->choice = MacroActionChoice_aecr;
9964   macro->data.ptrvalue = aecr;
9965 
9966   PointerToForm (f, macro);
9967   macro = MacroActionChoiceFree (macro);
9968 
9969   Show (f);
9970   Select (f);
9971   SendMessageToForm (f, VIB_MSG_ENTER);
9972 }
9973 
9974 
9975 typedef struct convertboisourcedbxreftofeaturedbxref {
9976   FORM_MESSAGE_BLOCK
9977   DialoG feature_type;
9978 } ConvertBioSourceDbxrefToFeatureDbxrefData, PNTR ConvertBioSourceDbxrefToFeatureDbxrefPtr;
9979 
9980 
DbxrefListFree(ValNodePtr vnp)9981 static ValNodePtr DbxrefListFree (ValNodePtr vnp)
9982 
9983 {
9984   ValNodePtr  next;
9985 
9986   while (vnp != NULL) {
9987     next = vnp->next;
9988     DbtagFree ((DbtagPtr) vnp->data.ptrvalue);
9989     MemFree (vnp);
9990     vnp = next;
9991   }
9992   return NULL;
9993 }
9994 
9995 
DbxrefListCopy(ValNodePtr vnp)9996 static ValNodePtr DbxrefListCopy (ValNodePtr vnp)
9997 
9998 {
9999   ValNodePtr copy = NULL;
10000 
10001   while (vnp != NULL) {
10002     ValNodeAddPointer (&copy, 0, AsnIoMemCopy (vnp->data.ptrvalue, (AsnReadFunc) DbtagAsnRead, (AsnWriteFunc) DbtagAsnWrite));
10003     vnp = vnp->next;
10004   }
10005   return copy;
10006 }
10007 
10008 
ExtractNonTaxonDbxrefs(ValNodePtr PNTR list)10009 static ValNodePtr ExtractNonTaxonDbxrefs (ValNodePtr PNTR list)
10010 {
10011   ValNodePtr prev = NULL, extracted = NULL, vnp, vnp_next;
10012   DbtagPtr dbtag;
10013 
10014   if (list == NULL || *list == NULL) return NULL;
10015   vnp = *list;
10016   while (vnp != NULL) {
10017     vnp_next = vnp->next;
10018     dbtag = (DbtagPtr) vnp->data.ptrvalue;
10019     if (dbtag != NULL && StringCmp (dbtag->db, "taxon") != 0) {
10020       if (prev == NULL) {
10021         *list = vnp_next;
10022       } else {
10023         prev->next = vnp_next;
10024       }
10025       vnp->next = NULL;
10026       ValNodeLink (&extracted, vnp);
10027     } else {
10028       prev = vnp;
10029     }
10030     vnp = vnp_next;
10031   }
10032   return extracted;
10033 }
10034 
10035 
ConvertBioSourceDbxrefToFeatureDbxrefBioseqCallback(BioseqPtr bsp,Pointer userdata)10036 static void ConvertBioSourceDbxrefToFeatureDbxrefBioseqCallback (BioseqPtr bsp, Pointer userdata)
10037 {
10038   ValNodePtr        vnp;
10039   SeqFeatPtr        sfp;
10040   SeqMgrFeatContext fcontext;
10041   SeqDescrPtr       sdp;
10042   SeqMgrDescContext dcontext;
10043   BioSourcePtr      biop;
10044   ValNodePtr        dbxref_list = NULL;
10045   Int4              featdef;
10046   Boolean           any_feat = FALSE;
10047 
10048   if (bsp == NULL || userdata == NULL) {
10049     return;
10050   }
10051 
10052   vnp = (ValNodePtr) userdata;
10053   featdef = GetFeatdefFromFeatureType (vnp->choice);
10054 
10055   sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
10056   if (sdp == NULL || sdp->data.ptrvalue == NULL) return;
10057   biop = (BioSourcePtr) sdp->data.ptrvalue;
10058   if (biop->org == NULL || biop->org->db == NULL) return;
10059   dbxref_list = ExtractNonTaxonDbxrefs (&(biop->org->db));
10060   if (dbxref_list == NULL) return;
10061 
10062   for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, featdef, &fcontext);
10063        sfp != NULL;
10064        sfp = SeqMgrGetNextFeature (bsp, sfp, 0, featdef, &fcontext)) {
10065     ValNodeLink (&(sfp->dbxref), DbxrefListCopy(dbxref_list));
10066     any_feat = TRUE;
10067   }
10068   if (any_feat) {
10069     dbxref_list = DbxrefListFree(dbxref_list);
10070   } else {
10071     ValNodeLink (&(biop->org->db), dbxref_list);
10072   }
10073 }
10074 
10075 
AcceptConvertBioSourceDbxrefToFeatureDbxref(ButtoN b)10076 static void AcceptConvertBioSourceDbxrefToFeatureDbxref (ButtoN b)
10077 {
10078   ConvertBioSourceDbxrefToFeatureDbxrefPtr dlg;
10079   ValNodePtr vnp;
10080   SeqEntryPtr sep;
10081 
10082   dlg = (ConvertBioSourceDbxrefToFeatureDbxrefPtr) GetObjectExtra (b);
10083   if (dlg == NULL) return;
10084 
10085   vnp = DialogToPointer (dlg->feature_type);
10086   if (vnp == NULL) {
10087     Message (MSG_ERROR, "Please choose feature type");
10088     return;
10089   }
10090 
10091   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
10092 
10093   VisitBioseqsInSep (sep, vnp, ConvertBioSourceDbxrefToFeatureDbxrefBioseqCallback);
10094   vnp = ValNodeFree (vnp);
10095 
10096   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
10097   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
10098   Remove (dlg->form);
10099 }
10100 
10101 
ConvertBioSourceDbxrefToFeatureDbxref(IteM i)10102 extern void ConvertBioSourceDbxrefToFeatureDbxref (IteM i)
10103 {
10104   BaseFormPtr         bfp;
10105   ConvertBioSourceDbxrefToFeatureDbxrefPtr dlg;
10106   WindoW              w;
10107   GrouP               h, c;
10108   ButtoN              b;
10109   PrompT              ppt;
10110 
10111 #ifdef WIN_MAC
10112   bfp = currentFormDataPtr;
10113 #else
10114   bfp = GetObjectExtra (i);
10115 #endif
10116   if (bfp == NULL || bfp->input_entityID == 0) return;
10117 
10118   dlg = (ConvertBioSourceDbxrefToFeatureDbxrefPtr) MemNew (sizeof (ConvertBioSourceDbxrefToFeatureDbxrefData));
10119 
10120   w = FixedWindow (-50, -33, -10, -10, "Convert BioSource Dbxrefs to Feature Dbxrefs", StdCloseWindowProc);
10121   SetObjectExtra (w, dlg, StdCleanupExtraProc);
10122   dlg->form = (ForM) w;
10123   dlg->input_entityID = bfp->input_entityID;
10124 
10125   h = HiddenGroup (w, -1, 0, NULL);
10126   SetGroupSpacing (h, 10, 10);
10127 
10128   ppt = StaticPrompt (h, "Choose feature type to receive BioSource dbxrefs", 0, dialogTextHeight, programFont, 'l');
10129   dlg->feature_type = FeatureTypeDialog (h, NULL, NULL);
10130   c = HiddenGroup (h, 2, 0, NULL);
10131   b = PushButton (c, "Accept", AcceptConvertBioSourceDbxrefToFeatureDbxref);
10132   SetObjectExtra (b, dlg, NULL);
10133   PushButton (c, "Cancel", StdCancelButtonProc);
10134   AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) dlg->feature_type, (HANDLE) c, NULL);
10135   Show (w);
10136   Select (w);
10137 }
10138 
10139 
10140 typedef struct structuredcommentsform {
10141   FORM_MESSAGE_BLOCK
10142   GrouP table_type;
10143   GrouP match_info;
10144   PopuP match_column;
10145   DialoG match_type;
10146   DialoG database_name;
10147   DoC    row_suppression_doc;
10148 
10149   ValNodePtr table;
10150   Int4       num_columns;
10151 } StructuredCommentsFormData, PNTR StructuredCommentsFormPtr;
10152 
CleanupStructuredCommentsForm(GraphiC g,VoidPtr data)10153 static void CleanupStructuredCommentsForm (GraphiC g, VoidPtr data)
10154 
10155 {
10156   StructuredCommentsFormPtr  frm;
10157 
10158   frm = (StructuredCommentsFormPtr) data;
10159   if (frm != NULL) {
10160     frm->table = FreeTabTable(frm->table);
10161   }
10162   StdCleanupFormProc (g, data);
10163 }
10164 
10165 
10166 /* note - for the header, a non-zero choice indicates the column should be ignored */
UserObjectFromRow(ValNodePtr header,ValNodePtr line,Int4 col,CharPtr dbname,ValNodePtr PNTR err_list)10167 static UserObjectPtr UserObjectFromRow (ValNodePtr header, ValNodePtr line, Int4 col, CharPtr dbname, ValNodePtr PNTR err_list)
10168 {
10169   ValNodePtr vnp_h, vnp_l;
10170   CharPtr    id_str = NULL;
10171   Int4       num;
10172   CharPtr    extra_data_fmt = "Too many fields in line for %s";
10173   CharPtr    msg;
10174   UserObjectPtr uop;
10175   CharPtr       prefix = NULL, suffix = NULL;
10176   CharPtr       prefix_fmt = "##%s-START##";
10177   CharPtr       suffix_fmt = "##%s-END##";
10178   CharPtr       tmp_dbname = NULL;
10179   Boolean       prefix_from_row = FALSE;
10180 
10181   if (header == NULL || line == NULL) {
10182     return NULL;
10183   }
10184 
10185   /* find id_str */
10186   vnp_l = line->data.ptrvalue;
10187   if (vnp_l == NULL) {
10188     return NULL;
10189   }
10190   num = 0;
10191   while (vnp_l != NULL && num < col) {
10192     num++;
10193     vnp_l = vnp_l->next;
10194   }
10195   if (vnp_l == NULL || StringHasNoText (vnp_l->data.ptrvalue)) {
10196     return NULL;
10197   } else {
10198     id_str = vnp_l->data.ptrvalue;
10199   }
10200 
10201 
10202   /* look for dbname in table if not supplied */
10203   if (StringHasNoText (dbname)) {
10204     for (vnp_h = header, vnp_l = line->data.ptrvalue;
10205          vnp_h != NULL && vnp_l != NULL && StringHasNoText (dbname);
10206          vnp_h = vnp_h->next, vnp_l = vnp_l->next) {
10207       if (StringICmp (vnp_h->data.ptrvalue, "StructuredCommentPrefix") == 0
10208           || StringICmp (vnp_h->data.ptrvalue, "StructuredCommentSuffix") == 0) {
10209         tmp_dbname = StructuredCommentDbnameFromString(vnp_l->data.ptrvalue);
10210         dbname = tmp_dbname;
10211         prefix_from_row = TRUE;
10212       }
10213     }
10214   } else {
10215     /* fix supplied dbname if necessary */
10216     tmp_dbname = StructuredCommentDbnameFromString(dbname);
10217     if (tmp_dbname != NULL) {
10218       dbname = tmp_dbname;
10219     }
10220   }
10221 
10222   /* build user object */
10223   vnp_h = header;
10224   vnp_l = line->data.ptrvalue;
10225   num = 0;
10226 
10227   if (!StringHasNoText (dbname)) {
10228     prefix = (CharPtr) MemNew (sizeof (Char) * (StringLen (prefix_fmt) + StringLen (dbname)));
10229     sprintf (prefix, prefix_fmt, dbname);
10230     suffix = (CharPtr) MemNew (sizeof (Char) * (StringLen (suffix_fmt) + StringLen (dbname)));
10231     sprintf (suffix, suffix_fmt, dbname);
10232   }
10233 
10234   uop = CreateStructuredCommentUserObject (prefix, suffix);
10235 
10236   prefix = MemFree (prefix);
10237   suffix = MemFree (suffix);
10238 
10239   while (vnp_h != NULL && vnp_l != NULL) {
10240     if (num != col && !StringHasNoText (vnp_l->data.ptrvalue) && vnp_h->choice == 0) {
10241       if (!prefix_from_row
10242           || (StringCmp (vnp_h->data.ptrvalue, "StructuredCommentPrefix") != 0
10243               && StringCmp (vnp_h->data.ptrvalue, "StructuredCommentSuffix") != 0)) {
10244         AddItemStructuredCommentUserObject (uop, vnp_h->data.ptrvalue, vnp_l->data.ptrvalue);
10245       }
10246     }
10247     vnp_h = vnp_h->next;
10248     vnp_l = vnp_l->next;
10249     num++;
10250   }
10251   while (vnp_l != NULL && StringHasNoText (vnp_l->data.ptrvalue)) {
10252     vnp_l = vnp_l->next;
10253   }
10254   if (vnp_l != NULL) {
10255     msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (extra_data_fmt) + StringLen (id_str)));
10256     sprintf (msg, extra_data_fmt, id_str);
10257     ValNodeAddPointer (err_list, 0, msg);
10258   }
10259   tmp_dbname = MemFree (tmp_dbname);
10260   return uop;
10261 }
10262 
10263 
ChangeStructuredCommentTableType(GrouP g)10264 static void ChangeStructuredCommentTableType(GrouP g)
10265 {
10266   StructuredCommentsFormPtr frm;
10267 
10268   frm = (StructuredCommentsFormPtr)GetObjectExtra (g);
10269   if (frm == NULL) {
10270     return;
10271   }
10272 
10273   if (GetValue (frm->table_type) == 1) {
10274     Enable (frm->match_info);
10275   } else {
10276     Disable (frm->match_info);
10277   }
10278 }
10279 
10280 
DoParseStructuredComments(ButtoN b)10281 static void DoParseStructuredComments (ButtoN b)
10282 {
10283   StructuredCommentsFormPtr frm;
10284   Int4                      col;
10285   MatchTypePtr              match_type;
10286   ValNodePtr                sequence_lists;
10287   SeqEntryPtr               sep;
10288   ValNodePtr                err_list = NULL, vnp, header, line, s_row, vnp_s, tmp_table, vnp_h;
10289   LogInfoPtr                lip;
10290   BioseqPtr                 bsp;
10291   UserObjectPtr             uop, uop_cpy;
10292   SeqDescrPtr               sdp;
10293   CharPtr                   database_name = NULL, spec_db, file_db;
10294   Boolean                   found_prefix;
10295 
10296   frm = (StructuredCommentsFormPtr) GetObjectExtra (b);
10297   if (frm == NULL) {
10298     return;
10299   }
10300 
10301   sep = GetTopSeqEntryForEntityID (frm->input_entityID);
10302 
10303   database_name = DialogToPointer (frm->database_name);
10304 
10305   if (GetValue (frm->table_type) == 1) {
10306     col = GetValue (frm->match_column) - 1;
10307     match_type = DialogToPointer (frm->match_type);
10308     sequence_lists = GetSequenceListsForMatchTypeInTabTable (sep, frm->table->next, col, match_type, &err_list);
10309 
10310     if (err_list != NULL) {
10311       lip = OpenLog ("Table Problems");
10312       for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
10313         fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
10314       }
10315       lip->data_in_log = TRUE;
10316       CloseLog (lip);
10317       lip = FreeLog (lip);
10318       err_list = ValNodeFreeData (err_list);
10319       if (ANS_YES != Message (MSG_YN, "Continue with table problems")) {
10320         sequence_lists = FreeSequenceLists(sequence_lists);
10321         return;
10322       }
10323     }
10324 
10325     WatchCursor ();
10326     Update();
10327 
10328     header = frm->table->data.ptrvalue;
10329     line = frm->table->next;
10330     s_row = sequence_lists;
10331 
10332 
10333     while (line != NULL && s_row != NULL) {
10334       vnp_s = s_row->data.ptrvalue;
10335       if (vnp_s != NULL) {
10336         uop = UserObjectFromRow (header, line, col, database_name, &err_list);
10337         while (vnp_s != NULL) {
10338           bsp = vnp_s->data.ptrvalue;
10339           uop_cpy = (UserObjectPtr) AsnIoMemCopy (uop, (AsnReadFunc) UserObjectAsnRead, (AsnWriteFunc) UserObjectAsnWrite);
10340           sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_user);
10341           sdp->data.ptrvalue = uop_cpy;
10342           vnp_s = vnp_s->next;
10343         }
10344         uop = UserObjectFree (uop);
10345       }
10346       line = line->next;
10347       s_row = s_row->next;
10348     }
10349 
10350 
10351     sequence_lists = FreeSequenceLists(sequence_lists);
10352 
10353   } else {
10354     tmp_table = FlipTabTableAxes (frm->table);
10355     if (!StringHasNoText (database_name)) {
10356       found_prefix = FALSE;
10357       spec_db = StructuredCommentDbnameFromString(database_name);
10358       for (vnp_h = tmp_table->data.ptrvalue, vnp_s = tmp_table->next->data.ptrvalue;
10359            vnp_h != NULL && vnp_s != NULL;
10360            vnp_h = vnp_h->next, vnp_s = vnp_s->next) {
10361         if (StringICmp(vnp_h->data.ptrvalue, "StructuredCommentPrefix") == 0
10362             || StringICmp (vnp_h->data.ptrvalue, "StructuredCommentSuffix") == 0) {
10363           file_db = StructuredCommentDbnameFromString(vnp_s->data.ptrvalue);
10364           if (StringCmp (file_db, spec_db) != 0) {
10365             vnp_s->data.ptrvalue = MemFree (vnp_s->data.ptrvalue);
10366             vnp_s->data.ptrvalue = StringSave (spec_db);
10367           }
10368           file_db = MemFree (file_db);
10369           found_prefix = TRUE;
10370         }
10371       }
10372       if (!found_prefix) {
10373         vnp = ValNodeNew (NULL);
10374         vnp->data.ptrvalue = StringSave ("StructuredCommentPrefix");
10375         vnp->next = tmp_table->data.ptrvalue;
10376         tmp_table->data.ptrvalue = vnp;
10377 
10378         vnp = ValNodeNew (NULL);
10379         vnp->data.ptrvalue = StringSave (spec_db);
10380         vnp->next = tmp_table->next->data.ptrvalue;
10381         tmp_table->next->data.ptrvalue = vnp;
10382       }
10383       spec_db = MemFree (spec_db);
10384     }
10385 
10386     CreateStructuredCommentsForAllFromTable(sep, tmp_table->data.ptrvalue, tmp_table->next, &err_list);
10387     tmp_table = FreeTabTable(tmp_table);
10388   }
10389 
10390   /* show errors from creating structured comments */
10391   if (err_list != NULL) {
10392     lip = OpenLog ("Data Problems");
10393     for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
10394       fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
10395     }
10396     lip->data_in_log = TRUE;
10397     CloseLog (lip);
10398     lip = FreeLog (lip);
10399     err_list = ValNodeFreeData (err_list);
10400   }
10401 
10402   database_name = MemFree (database_name);
10403 
10404   ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
10405   ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
10406 
10407   Remove (frm->form);
10408   ArrowCursor ();
10409   Update ();
10410 
10411 }
10412 
10413 
ClickSuppressionRow(DoC d,PoinT pt)10414 static void ClickSuppressionRow (DoC d, PoinT pt)
10415 {
10416   Int2               item, row, col, i;
10417   RecT               rct;
10418   StructuredCommentsFormPtr frm;
10419   ValNodePtr vnp;
10420 
10421   frm = (StructuredCommentsFormPtr) GetObjectExtra (d);
10422   if (frm == NULL) return;
10423 
10424   MapDocPoint (d, pt, &item, &row, &col, &rct);
10425   if (item > 0) {
10426     for (i = 1, vnp = frm->table->data.ptrvalue; i < item && vnp != NULL; i++, vnp = vnp->next) {
10427     }
10428     if (vnp != NULL) {
10429       if (vnp->choice == 0) {
10430         vnp->choice = 1;
10431       } else {
10432         vnp->choice = 0;
10433       }
10434     }
10435     /* redraw */
10436     InvalDocument (frm->row_suppression_doc);
10437   }
10438 }
10439 
10440 
DrawSuppressionRow(DoC d,RectPtr r,Int2 item,Int2 firstLine)10441 static void DrawSuppressionRow (DoC d, RectPtr r, Int2 item, Int2 firstLine)
10442 
10443 {
10444   StructuredCommentsFormPtr frm;
10445   ValNodePtr                vnp;
10446   RecT                      rct;
10447   Int2                      i, lineHeight;
10448 
10449   frm = (StructuredCommentsFormPtr) GetObjectExtra (d);
10450   if (frm == NULL || r == NULL || item <= 0 || firstLine != 0) {
10451     return;
10452   }
10453 
10454   GetItemParams (d, item, NULL, NULL, NULL, &lineHeight, NULL);
10455   rct = *r;
10456   rct.right = rct.left + rct.bottom - rct.top;
10457 
10458   for (i = 1, vnp = frm->table->data.ptrvalue; i < item && vnp != NULL; i++, vnp = vnp->next) {
10459   }
10460   if (vnp != NULL) {
10461     /* draw box */
10462     MoveTo (rct.left, rct.top);
10463     LineTo (rct.right, rct.top);
10464     LineTo (rct.right, rct.bottom);
10465     LineTo (rct.left, rct.bottom);
10466     LineTo (rct.left, rct.top);
10467     if (vnp->choice > 0) {
10468       LineTo (rct.right, rct.bottom);
10469       MoveTo (rct.right, rct.top);
10470       LineTo (rct.left, rct.bottom);
10471     }
10472   }
10473 }
10474 
10475 
PopulateRowSuppressionDoc(DoC d)10476 NLM_EXTERN void PopulateRowSuppressionDoc (DoC d)
10477 {
10478   StructuredCommentsFormPtr frm;
10479   Int4 i, len;
10480   CharPtr str, tmp;
10481   CharPtr    row_fmt = "\t%d\t%s\n";
10482   RecT       r;
10483   ValNodePtr vnp;
10484   FonT       font = programFont;
10485   ParData    ParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
10486   ColData    ColFmt[] =
10487   {
10488     {15, 0, 10, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, FALSE}, /* check box */
10489     {0, 0, 4, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, FALSE}, /* column number */
10490     {0, 0, 80, 0, NULL, 'l', TRUE, FALSE, FALSE, FALSE, TRUE}   /* first value */
10491   };
10492   Int4 scroll_pos = 0;
10493   BaR  sb_vert;
10494 
10495 
10496   frm = (StructuredCommentsFormPtr) GetObjectExtra (d);
10497   if (frm == NULL) return;
10498 
10499   sb_vert = GetSlateVScrollBar ((SlatE) frm->row_suppression_doc);
10500   if (sb_vert) {
10501     scroll_pos = GetBarValue (sb_vert);
10502   }
10503 
10504   Reset (frm->row_suppression_doc);
10505 
10506   ObjectRect (frm->row_suppression_doc, &r);
10507   InsetRect (&r, 4, 4);
10508 
10509   if (frm->num_columns < 10) {
10510     ColFmt[1].pixWidth = stdCharWidth * 2;
10511   } else {
10512     ColFmt[1].pixWidth = stdCharWidth * 3;
10513   }
10514   ColFmt[2].pixWidth = r.right - r.left - ColFmt[1].pixWidth - ColFmt[0].pixWidth;
10515   for (i = 0, vnp = frm->table->data.ptrvalue; i < frm->num_columns && vnp != NULL; i++, vnp = vnp->next) {
10516     if (vnp->data.ptrvalue == NULL) {
10517       str = "blank";
10518     } else {
10519       str = vnp->data.ptrvalue;
10520     }
10521     len = StringLen (str) + 15 + StringLen (row_fmt);
10522     tmp = (CharPtr) MemNew (sizeof (Char) * len);
10523     sprintf (tmp, row_fmt, i + 1, str);
10524     AppendText (frm->row_suppression_doc, tmp, &ParFmt, ColFmt, font);
10525     tmp = MemFree (tmp);
10526   }
10527   UpdateDocument (frm->row_suppression_doc, 0, 0);
10528   if (scroll_pos > 0) {
10529     CorrectBarValue (sb_vert, scroll_pos);
10530   }
10531 }
10532 
10533 
CreateStructuredCommentsBaseForm(BaseFormPtr bfp)10534 NLM_EXTERN void CreateStructuredCommentsBaseForm (BaseFormPtr bfp)
10535 {
10536   SeqEntryPtr        sep;
10537   Char               path [PATH_MAX];
10538   ValNodePtr         vnp;
10539   FILE *fp;
10540   StructuredCommentsFormPtr frm;
10541   WindoW                    w;
10542   GrouP                     h, c;
10543   PrompT                    ppt1, ppt2, ppt3, ppt4;
10544   CharPtr                   choice_fmt = "Column %d (%s)";
10545   CharPtr                   choice_str, val;
10546   Int4                      col;
10547   ButtoN                    b;
10548 
10549   if (bfp == NULL)
10550     return;
10551 
10552   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
10553   if (sep == NULL)
10554     return;
10555 
10556   if (GetInputFileName (path, sizeof (path), "", "TEXT")) {
10557     fp = FileOpen (path, "r");
10558     if (fp == NULL) {
10559       Message (MSG_ERROR, "Unable to open %s");
10560     } else {
10561       frm = (StructuredCommentsFormPtr) MemNew (sizeof (StructuredCommentsFormData));
10562       if (frm == NULL) {
10563         FileClose (fp);
10564         return;
10565       }
10566       frm->table = ReadTabTableFromFile(fp);
10567       FileClose (fp);
10568       if (frm->table == NULL || frm->table->data.ptrvalue == NULL || frm->table->next == NULL) {
10569         Message (MSG_ERROR, "Unable to read table from file");
10570         frm = MemFree (frm);
10571         return;
10572       }
10573       frm->num_columns = ValNodeLen (frm->table->data.ptrvalue);
10574 
10575       w = FixedWindow (-50, -33, -10, -10, "Parse Structured Comment From File", StdCloseWindowProc);
10576       SetObjectExtra (w, frm, CleanupStructuredCommentsForm);
10577       frm->form = (ForM) w;
10578 
10579       frm->input_entityID = bfp->input_entityID;
10580 
10581       h = HiddenGroup (w, -1, 0, NULL);
10582 
10583       frm->table_type = HiddenGroup (h, 0, 2, ChangeStructuredCommentTableType);
10584       SetGroupSpacing (frm->table_type, 10, 10);
10585       SetObjectExtra (frm->table_type, frm, NULL);
10586       RadioButton (frm->table_type, "Table includes accessions for structured comments, one per line");
10587       RadioButton (frm->table_type, "Table is one structured comment, field names across the top");
10588       SetValue (frm->table_type, 1);
10589 
10590       frm->match_info = HiddenGroup (h, -1, 0, NULL);
10591       SetGroupSpacing (frm->match_info, 10, 10);
10592       ppt1 = StaticPrompt (frm->match_info, "Choose column that identifies sequence for structured comment", 0, dialogTextHeight,
10593 		                       programFont, 'l');
10594       frm->match_column = PopupList (frm->match_info, TRUE, NULL);
10595       vnp = frm->table->data.ptrvalue;
10596       col = 1;
10597       while (vnp != NULL) {
10598         if (vnp->data.ptrvalue == NULL) {
10599           val = "blank";
10600         } else {
10601           val = vnp->data.ptrvalue;
10602         }
10603         choice_str = (CharPtr) MemNew (sizeof (Char) * (StringLen (choice_fmt) + 15 + StringLen (val)));
10604         sprintf (choice_str, choice_fmt, col, val);
10605         PopupItem (frm->match_column, choice_str);
10606         choice_str = MemFree (choice_str);
10607         vnp = vnp->next;
10608         col++;
10609       }
10610       SetValue (frm->match_column, 1);
10611 
10612       ppt2 = StaticPrompt (frm->match_info, "Specify relationship of column to sequence", 0, dialogTextHeight,
10613 		                       programFont, 'l');
10614       frm->match_type = MatchTypeDialog (frm->match_info, NULL, NULL);
10615       AlignObjects (ALIGN_CENTER, (HANDLE) ppt1,
10616                                   (HANDLE) frm->match_column,
10617                                   (HANDLE) ppt2,
10618                                   (HANDLE) frm->match_type,
10619                                   NULL);
10620 
10621       ppt3 = StaticPrompt (h, "Choose database name", 0, dialogTextHeight,
10622 		                  programFont, 'l');
10623 
10624       frm->database_name = StructuredCommentDatabaseNameDialog (h, NULL, NULL);
10625 
10626       ppt4 = StaticPrompt (h, "Choose rows to ignore (optional", 0, dialogTextHeight, programFont, 'c');
10627       frm->row_suppression_doc = DocumentPanel (h, stdCharWidth * 50, stdLineHeight * 8);
10628       SetObjectExtra (frm->row_suppression_doc, frm, NULL);
10629       SetDocProcs (frm->row_suppression_doc, ClickSuppressionRow, NULL, NULL, NULL);
10630       SetDocShade (frm->row_suppression_doc, DrawSuppressionRow, NULL, NULL, NULL);
10631       PopulateRowSuppressionDoc (frm->row_suppression_doc);
10632 
10633       c = HiddenGroup (h, 2, 0, NULL);
10634       b = PushButton (c, "Accept", DoParseStructuredComments);
10635       SetObjectExtra (b, frm, NULL);
10636       PushButton (c, "Cancel", StdCancelButtonProc);
10637       AlignObjects (ALIGN_CENTER, (HANDLE) frm->table_type,
10638                                   (HANDLE) frm->match_info,
10639                                   (HANDLE) ppt3,
10640                                   (HANDLE) frm->database_name,
10641                                   (HANDLE) ppt4,
10642                                   (HANDLE) frm->row_suppression_doc,
10643                                   (HANDLE) c,
10644                                   NULL);
10645       RealizeWindow (w);
10646       Show (w);
10647       Update();
10648     }
10649   }
10650 }
10651 
10652 
CreateStructuredCommentsItem(IteM i)10653 NLM_EXTERN void CreateStructuredCommentsItem (IteM i)
10654 {
10655   BaseFormPtr        bfp;
10656 
10657 #ifdef WIN_MAC
10658   bfp = currentFormDataPtr;
10659 #else
10660   bfp = GetObjectExtra (i);
10661 #endif
10662   CreateStructuredCommentsBaseForm (bfp);
10663 }
10664 
10665 
AnySequencesInList(ValNodePtr list)10666 static Boolean AnySequencesInList (ValNodePtr list)
10667 {
10668   Boolean rval = FALSE;
10669 
10670   while (list != NULL && !rval) {
10671     if (list->data.ptrvalue != NULL) {
10672       rval = TRUE;
10673     }
10674     list = list->next;
10675   }
10676   return rval;
10677 }
10678 
10679 
HeaderHasAtLeastTwoColumns(ValNodePtr header)10680 static Boolean HeaderHasAtLeastTwoColumns (ValNodePtr header)
10681 {
10682   if (header == NULL || header->next == NULL) {
10683     return FALSE;
10684   } else {
10685     return TRUE;
10686   }
10687 }
10688 
10689 
HeaderLooksLikeSeqId(ValNodePtr header)10690 static Boolean HeaderLooksLikeSeqId (ValNodePtr header)
10691 {
10692   if (header == NULL) {
10693     return FALSE;
10694   } else if (StringICmp (header->data.ptrvalue, "accession") == 0
10695     || StringICmp (header->data.ptrvalue, "seqid") == 0) {
10696     return TRUE;
10697   } else {
10698     return FALSE;
10699   }
10700 }
10701 
10702 
SubmitterCreateStructuredComments(IteM i)10703 NLM_EXTERN void SubmitterCreateStructuredComments (IteM i)
10704 {
10705   BaseFormPtr               bfp;
10706   Char                      path [PATH_MAX];
10707   FILE *fp;
10708   Int4                      col;
10709   MatchTypeData             match_type;
10710   ValNodePtr                sequence_lists;
10711   SeqEntryPtr               sep;
10712   ValNodePtr                err_list = NULL, vnp, header, line, s_row, vnp_s, tmp;
10713   LogInfoPtr                lip;
10714   BioseqPtr                 bsp;
10715   UserObjectPtr             uop, uop_cpy;
10716   SeqDescrPtr               sdp;
10717   ValNodePtr                table;
10718 
10719 #ifdef WIN_MAC
10720   bfp = currentFormDataPtr;
10721 #else
10722   bfp = GetObjectExtra (i);
10723 #endif
10724   if (bfp == NULL)
10725     return;
10726 
10727   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
10728   if (sep == NULL)
10729     return;
10730 
10731   if (!GetInputFileName (path, sizeof (path), "", "TEXT")) {
10732     return;
10733   }
10734   fp = FileOpen (path, "r");
10735   if (fp == NULL) {
10736     Message (MSG_ERROR, "Unable to open %s");
10737     return;
10738   }
10739   table = ReadTabTableFromFile(fp);
10740   FileClose (fp);
10741   if (table == NULL || table->data.ptrvalue == NULL || table->next == NULL) {
10742     Message (MSG_ERROR, "Unable to read table from file");
10743     return;
10744   }
10745 
10746   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
10747   col = 0;
10748   match_type.choice = eTableMatchNucID;
10749   match_type.match_location = String_location_equals;
10750   match_type.data = NULL;
10751 
10752   sequence_lists = GetSequenceListsForMatchTypeInTabTable (sep, table->next, col, &match_type, &err_list);
10753 
10754   if (err_list != NULL && !AnySequencesInList(sequence_lists)
10755       && HeaderHasAtLeastTwoColumns(table->data.ptrvalue)
10756       && !HeaderLooksLikeSeqId(table->data.ptrvalue)) {
10757     err_list = ValNodeFreeData (err_list);
10758     tmp = FlipTabTableAxes (table);
10759     table = FreeTabTable (table);
10760     table = tmp;
10761     CreateStructuredCommentsForAllFromTable(sep, table->data.ptrvalue, table->next, &err_list);
10762   } else {
10763     if (err_list != NULL) {
10764       lip = OpenLog ("Table Problems");
10765       for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
10766         fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
10767       }
10768       lip->data_in_log = TRUE;
10769       CloseLog (lip);
10770       lip = FreeLog (lip);
10771       err_list = ValNodeFreeData (err_list);
10772       if (ANS_YES != Message (MSG_YN, "Continue with table problems")) {
10773         sequence_lists = FreeSequenceLists(sequence_lists);
10774         return;
10775       }
10776     }
10777 
10778     WatchCursor ();
10779     Update();
10780 
10781     header = table->data.ptrvalue;
10782     line = table->next;
10783     s_row = sequence_lists;
10784 
10785     while (line != NULL && s_row != NULL) {
10786       vnp_s = s_row->data.ptrvalue;
10787       if (vnp_s != NULL) {
10788         uop = UserObjectFromRow (header, line, col, NULL, &err_list);
10789         while (vnp_s != NULL) {
10790           bsp = vnp_s->data.ptrvalue;
10791           uop_cpy = (UserObjectPtr) AsnIoMemCopy (uop, (AsnReadFunc) UserObjectAsnRead, (AsnWriteFunc) UserObjectAsnWrite);
10792           sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_user);
10793           sdp->data.ptrvalue = uop_cpy;
10794           vnp_s = vnp_s->next;
10795         }
10796         uop = UserObjectFree (uop);
10797       }
10798       line = line->next;
10799       s_row = s_row->next;
10800     }
10801   }
10802 
10803   if (err_list != NULL) {
10804     lip = OpenLog ("Data Problems");
10805     for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
10806       fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
10807     }
10808     lip->data_in_log = TRUE;
10809     CloseLog (lip);
10810     lip = FreeLog (lip);
10811     err_list = ValNodeFreeData (err_list);
10812   }
10813 
10814   table = FreeTabTable (table);
10815   sequence_lists = FreeSequenceLists(sequence_lists);
10816   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
10817   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
10818 
10819   ArrowCursor ();
10820   Update ();
10821 
10822 }
10823 
10824 
10825 /*
10826  * Two BioSources are mergeable if the following conditions are met:
10827  * 1)	For the following items, either the value for one or both BioSources
10828  * is not set or the values are identical:
10829  *    BioSource.genome
10830  *    BioSource.origin
10831  *    BioSource.is-focus
10832  *    BioSource.org.taxname
10833  *    BioSource.org.common
10834  *    BioSource.org.orgname.name
10835  *    BioSource.org.orgname.attrib
10836  *    BioSource.org.orgname.lineage
10837  *    BioSource.org.orgname.gcode
10838  *    BioSource.org.orgname.mgcode
10839  *    BioSource.org.orgname.div
10840  * 2) For the following items, either one or both BioSources have empty lists
10841  * or the lists for the two BioSources are identical:
10842  *    BioSource.subtype
10843  *    BioSource.org.syn
10844  *    BioSource.org.orgname.mod
10845  *    BioSource.org.mod
10846  * 3)	No Dbtag in the BioSource.org.db list from one BioSource can have the same
10847  * db value as an item in the BioSource.org.db list from the other BioSource
10848  * unless the two Dbtags have identical tag values.
10849 */
10850 
10851 
OrgModListsMatch(OrgModPtr mod1,OrgModPtr mod2)10852 static ValNodePtr OrgModListsMatch (OrgModPtr mod1, OrgModPtr mod2)
10853 {
10854   ValNodePtr rval = NULL;
10855   OrgModPtr cmp1, cmp2;
10856   Boolean    found;
10857   CharPtr    str, qual, mismatch_fmt = "Mismatched values for %s";
10858 #if 0
10859   CharPtr    missing_fmt = "Only one has %s";
10860 #endif
10861 
10862   /* look for missing and mismatch */
10863   for (cmp1 = mod1; cmp1 != NULL; cmp1 = cmp1->next) {
10864     found = FALSE;
10865     for (cmp2 = mod2; cmp2 != NULL; cmp2 = cmp2->next) {
10866       if (cmp1->subtype == cmp2->subtype) {
10867         if (StringCmp (cmp1->subname, cmp2->subname) != 0) {
10868           qual = GetSourceQualName (GetSrcQualFromSubSrcOrOrgMod (cmp1->subtype, TRUE));
10869           str = (CharPtr) MemNew (sizeof (Char) * (StringLen (mismatch_fmt) + StringLen (qual)));
10870           sprintf (str, mismatch_fmt, qual);
10871           ValNodeAddPointer (&rval, 0, str);
10872         }
10873         found = TRUE;
10874       }
10875     }
10876 #if 0
10877     if (!found) {
10878       qual = GetSourceQualName (GetSrcQualFromSubSrcOrOrgMod (cmp1->subtype, TRUE));
10879       str = (CharPtr) MemNew (sizeof (Char) * (StringLen (missing_fmt) + StringLen (qual)));
10880       sprintf (str, missing_fmt, qual);
10881       ValNodeAddPointer (&rval, 0, str);
10882     }
10883 #endif
10884   }
10885 #if 0
10886   /* only look for missing this time */
10887   for (cmp2 = mod2; cmp2 != NULL; cmp2 = cmp2->next) {
10888     found = FALSE;
10889     for (cmp1 = mod1; cmp1 != NULL && !found; cmp1 = cmp1->next) {
10890       if (cmp1->subtype == cmp2->subtype) {
10891         found = TRUE;
10892       }
10893     }
10894     if (!found) {
10895       qual = GetSourceQualName (GetSrcQualFromSubSrcOrOrgMod (cmp2->subtype, TRUE));
10896       str = (CharPtr) MemNew (sizeof (Char) * (StringLen (missing_fmt) + StringLen (qual)));
10897       sprintf (str, missing_fmt, qual);
10898       ValNodeAddPointer (&rval, 0, str);
10899     }
10900   }
10901 #endif
10902 
10903   return rval;
10904 }
10905 
10906 
OkToMergeOrgNames(OrgNamePtr on1,OrgNamePtr on2)10907 static ValNodePtr OkToMergeOrgNames (OrgNamePtr on1, OrgNamePtr on2)
10908 {
10909   ValNodePtr rval = NULL;
10910 
10911   if (on1 == NULL || on2 == NULL) {
10912     return NULL;
10913   }
10914 
10915   /* attrib */
10916   if (!StringHasNoText (on1->attrib) && !StringHasNoText (on2->attrib)
10917       && StringCmp (on1->attrib, on2->attrib) != 0)
10918   {
10919     ValNodeAddPointer (&rval, 0, StringSave ("Orgname.attrib do not match"));
10920   }
10921   /* lineage */
10922   if (!StringHasNoText (on1->lineage) && !StringHasNoText (on2->lineage)
10923            && StringCmp (on1->lineage, on2->lineage) != 0)
10924   {
10925     ValNodeAddPointer (&rval, 0, StringSave ("Lineages do not match"));
10926   }
10927   /* div */
10928   if (!StringHasNoText (on1->div) && !StringHasNoText (on2->div)
10929            && StringCmp (on1->div, on2->div) != 0)
10930   {
10931     ValNodeAddPointer (&rval, 0, StringSave ("Divisions do not match"));
10932   }
10933   /* gcode */
10934   if (on1->gcode != 0 && on2->gcode != 0 && on1->gcode != on2->gcode)
10935   {
10936     ValNodeAddPointer (&rval, 0, StringSave ("Genetic codes do not match"));
10937   }
10938   /* mgcode */
10939   if (on1->mgcode != 0 && on2->mgcode != 0 && on1->mgcode != on2->mgcode)
10940   {
10941     ValNodeAddPointer (&rval, 0, StringSave ("Mitochondrial genetic codes do not match"));
10942   }
10943   /* OrgMods */
10944   if (on1->mod != NULL && on2->mod != NULL)
10945   {
10946     ValNodeLink (&rval, OrgModListsMatch (on1->mod, on2->mod));
10947   }
10948   /* name */
10949   if (on1->data != NULL && on2->data != NULL
10950            && on1->choice != on2->choice)
10951   {
10952     ValNodeAddPointer (&rval, 0, StringSave ("Orgname data differs"));
10953   }
10954 
10955   return rval;
10956 }
10957 
10958 
ValNodeStringsMatch(ValNodePtr vnp1,ValNodePtr vnp2)10959 static Boolean ValNodeStringsMatch (ValNodePtr vnp1, ValNodePtr vnp2)
10960 {
10961   Boolean rval = TRUE;
10962 
10963   while (rval && vnp1 != NULL && vnp2 != NULL) {
10964     if (StringCmp (vnp1->data.ptrvalue, vnp2->data.ptrvalue) != 0) {
10965       rval = FALSE;
10966     }
10967     vnp1 = vnp1->next;
10968     vnp2 = vnp2->next;
10969   }
10970   if (vnp1 != NULL || vnp2 != NULL) {
10971     rval = FALSE;
10972   }
10973   return rval;
10974 }
10975 
10976 
OkToMergeDbtagLists(ValNodePtr vnp1,ValNodePtr vnp2)10977 static Boolean OkToMergeDbtagLists (ValNodePtr vnp1, ValNodePtr vnp2)
10978 {
10979   Boolean rval = TRUE;
10980   DbtagPtr dbt1, dbt2;
10981   ValNodePtr vnp_x;
10982 
10983   while (rval && vnp1 != NULL) {
10984     dbt1 = (DbtagPtr) vnp1->data.ptrvalue;
10985     if (dbt1 != NULL) {
10986       vnp_x = vnp2;
10987       while (rval && vnp_x != NULL) {
10988         dbt2 = (DbtagPtr) vnp_x->data.ptrvalue;
10989         if (dbt2 != NULL && StringCmp (dbt1->db, dbt2->db) == 0
10990             && !DbtagMatch (dbt1, dbt2)) {
10991           rval = FALSE;
10992         }
10993         vnp_x = vnp_x->next;
10994       }
10995     }
10996     vnp1 = vnp1->next;
10997   }
10998   return rval;
10999 }
11000 
11001 
OkToMergeOrgRefs(OrgRefPtr org1,OrgRefPtr org2)11002 static ValNodePtr OkToMergeOrgRefs (OrgRefPtr org1, OrgRefPtr org2)
11003 {
11004   ValNodePtr rval = NULL;
11005 
11006   if (org1 == NULL || org2 == NULL) {
11007     return NULL;
11008   }
11009 
11010   /* taxname */
11011   if (!StringHasNoText (org1->taxname) && !StringHasNoText (org2->taxname)
11012       && StringCmp (org1->taxname, org2->taxname) != 0)
11013   {
11014     ValNodeAddPointer (&rval, 0, StringSave ("Taxnames do not match"));
11015   }
11016   /* common */
11017   if (!StringHasNoText (org1->common) && !StringHasNoText (org2->common)
11018            && StringCmp (org1->common, org2->common) != 0)
11019   {
11020     ValNodeAddPointer (&rval, 0, StringSave ("Common names do not match"));
11021   }
11022   /* synonyms */
11023   if (org1->syn != NULL && org2->syn != NULL
11024            && !ValNodeStringsMatch (org1->syn, org2->syn))
11025   {
11026     ValNodeAddPointer (&rval, 0, StringSave ("Synonyms do not match"));
11027   }
11028   /* mod */
11029   if (org1->mod != NULL && org2->mod != NULL
11030            && !ValNodeStringsMatch (org1->mod, org2->mod))
11031   {
11032     ValNodeAddPointer (&rval, 0, StringSave ("OrgRef Mods do not match"));
11033   }
11034   /* orgname */
11035   ValNodeLink (&rval, OkToMergeOrgNames (org1->orgname, org2->orgname));
11036   /* dbtags */
11037   if (!OkToMergeDbtagLists (org1->db, org2->db))
11038   {
11039     ValNodeAddPointer (&rval, 0, StringSave ("Dbxrefs do not match"));
11040   }
11041   return rval;
11042 }
11043 
11044 
SubtypeListsMatch(SubSourcePtr ssp1,SubSourcePtr ssp2)11045 static ValNodePtr SubtypeListsMatch (SubSourcePtr ssp1, SubSourcePtr ssp2)
11046 {
11047   ValNodePtr rval = NULL;
11048   SubSourcePtr cmp1, cmp2;
11049   Boolean    found;
11050   CharPtr    str, qual, mismatch_fmt = "Mismatched values for %s";
11051 #if 0
11052   CharPtr    missing_fmt = "Only one has %s";
11053 #endif
11054 
11055   /* look for missing and mismatch */
11056   for (cmp1 = ssp1; cmp1 != NULL; cmp1 = cmp1->next) {
11057     found = FALSE;
11058     for (cmp2 = ssp2; cmp2 != NULL; cmp2 = cmp2->next) {
11059       if (cmp1->subtype == cmp2->subtype) {
11060         if (StringCmp (cmp1->name, cmp2->name) != 0) {
11061           qual = GetSourceQualName (GetSrcQualFromSubSrcOrOrgMod (cmp1->subtype, FALSE));
11062           str = (CharPtr) MemNew (sizeof (Char) * (StringLen (mismatch_fmt) + StringLen (qual)));
11063           sprintf (str, mismatch_fmt, qual);
11064           ValNodeAddPointer (&rval, 0, str);
11065         }
11066         found = TRUE;
11067       }
11068     }
11069 #if 0
11070     if (!found) {
11071       qual = GetSourceQualName (GetSrcQualFromSubSrcOrOrgMod (cmp1->subtype, FALSE));
11072       str = (CharPtr) MemNew (sizeof (Char) * (StringLen (missing_fmt) + StringLen (qual)));
11073       sprintf (str, missing_fmt, qual);
11074       ValNodeAddPointer (&rval, 0, str);
11075     }
11076 #endif
11077   }
11078 #if 0
11079   /* only look for missing this time */
11080   for (cmp2 = ssp2; cmp2 != NULL; cmp2 = cmp2->next) {
11081     found = FALSE;
11082     for (cmp1 = ssp1; cmp1 != NULL && !found; cmp1 = cmp1->next) {
11083       if (cmp1->subtype == cmp2->subtype) {
11084         found = TRUE;
11085       }
11086     }
11087     if (!found) {
11088       qual = GetSourceQualName (GetSrcQualFromSubSrcOrOrgMod (cmp2->subtype, FALSE));
11089       str = (CharPtr) MemNew (sizeof (Char) * (StringLen (missing_fmt) + StringLen (qual)));
11090       sprintf (str, missing_fmt, qual);
11091       ValNodeAddPointer (&rval, 0, str);
11092     }
11093   }
11094 #endif
11095 
11096   return rval;
11097 }
11098 
11099 
OkToMergeBioSources(BioSourcePtr biop1,BioSourcePtr biop2)11100 static ValNodePtr OkToMergeBioSources (BioSourcePtr biop1, BioSourcePtr biop2)
11101 {
11102   ValNodePtr rval = NULL;
11103 
11104   if (biop1 == NULL || biop2 == NULL)
11105   {
11106     return NULL;
11107   }
11108 
11109   /* genome */
11110   if  (biop1->genome != GENOME_unknown && biop2->genome != GENOME_unknown
11111        && biop1->genome != biop2->genome)
11112   {
11113     ValNodeAddPointer (&rval, 0, StringSave ("Locations do not match"));
11114   }
11115   /* origin */
11116   if (biop1->origin != ORG_UNKNOWN && biop2->origin != ORG_UNKNOWN
11117              && biop1->origin != biop2->origin)
11118   {
11119     ValNodeAddPointer (&rval, 0, StringSave ("Origins do not match"));
11120   }
11121   /* is-focus */
11122   if ((biop1->is_focus && !biop2->is_focus) || (!biop1->is_focus && biop2->is_focus))
11123   {
11124     ValNodeAddPointer (&rval, 0, StringSave ("Focus does not match"));
11125   }
11126   /* subtype */
11127   if (biop1->subtype != NULL && biop2->subtype != NULL) {
11128     ValNodeLink (&rval, SubtypeListsMatch(biop1->subtype, biop2->subtype));
11129   }
11130   /* orgref */
11131   ValNodeLink (&rval, OkToMergeOrgRefs(biop1->org, biop2->org));
11132   return rval;
11133 }
11134 
11135 
OrgModListCopy(OrgModPtr orig)11136 static OrgModPtr OrgModListCopy (OrgModPtr orig)
11137 {
11138   OrgModPtr list = NULL, prev = NULL, mod;
11139 
11140   while (orig != NULL) {
11141     mod = AsnIoMemCopy (orig, (AsnReadFunc)OrgModAsnRead, (AsnWriteFunc)OrgModAsnWrite);
11142     if (prev == NULL) {
11143       list = mod;
11144     } else {
11145       prev->next = mod;
11146     }
11147     prev = mod;
11148     orig = orig->next;
11149   }
11150   return list;
11151 }
11152 
11153 
AddOrgNameToOrgName(OrgNamePtr on1,OrgNamePtr on2)11154 static void AddOrgNameToOrgName (OrgNamePtr on1, OrgNamePtr on2)
11155 {
11156   OrgModPtr cpy, mod;
11157 
11158   if (on1 == NULL || on2 == NULL) {
11159     return;
11160   }
11161   /* OrgMods */
11162   if (on2->mod != NULL) {
11163     cpy = OrgModListCopy (on2->mod);
11164     if (on1->mod == NULL) {
11165       on1->mod = cpy;
11166     } else {
11167       mod = on1->mod;
11168       while (mod->next != NULL) {
11169         mod = mod->next;
11170       }
11171       mod->next = cpy;
11172     }
11173   }
11174   /* attrib */
11175   if (StringHasNoText (on1->attrib) && !StringHasNoText (on2->attrib)) {
11176     on1->attrib = MemFree (on1->attrib);
11177     on1->attrib = StringSave (on2->attrib);
11178   }
11179   /* lineage */
11180   if (StringHasNoText (on1->lineage) && !StringHasNoText (on2->lineage)) {
11181     on1->lineage = MemFree (on1->lineage);
11182     on1->lineage = StringSave (on2->lineage);
11183   }
11184   /* div */
11185   if (StringHasNoText (on1->div) && !StringHasNoText (on2->div)) {
11186     on1->div = MemFree (on1->div);
11187     on1->div = StringSave (on2->div);
11188   }
11189   /* gcode */
11190   if (on1->gcode == 0) {
11191     on1->gcode = on2->gcode;
11192   }
11193   /* mgcode */
11194   if (on1->mgcode == 0) {
11195     on1->mgcode = on2->mgcode;
11196   }
11197 
11198 }
11199 
11200 
AddOrgRefToOrgRef(OrgRefPtr org1,OrgRefPtr org2)11201 static void AddOrgRefToOrgRef (OrgRefPtr org1, OrgRefPtr org2)
11202 {
11203   ValNodePtr vnp1, vnp2;
11204   DbtagPtr dbt1, dbt2;
11205 
11206   if (org1 == NULL || org2 == NULL) {
11207     return;
11208   }
11209 
11210   /* taxname */
11211   if (StringHasNoText (org1->taxname) && !StringHasNoText (org2->taxname)) {
11212     org1->taxname = MemFree (org1->taxname);
11213     org1->taxname = StringSave (org2->taxname);
11214   }
11215   /* common */
11216   if (StringHasNoText (org1->common) && !StringHasNoText (org2->common)) {
11217     org1->common = MemFree (org1->common);
11218     org1->common = StringSave (org1->common);
11219   }
11220   /* synonyms */
11221   if (org1->syn == NULL && org2->syn != NULL) {
11222     org1->syn = ValNodeDupStringList (org2->syn);
11223   }
11224   /* mod */
11225   if (org1->mod == NULL && org2->mod != NULL) {
11226     org1->mod = ValNodeDupStringList (org2->mod);
11227   }
11228   /* orgname */
11229   if (org2->orgname != NULL) {
11230     if (org1->orgname == NULL) {
11231       org1->orgname = AsnIoMemCopy (org2->orgname, (AsnReadFunc) OrgNameAsnRead,
11232                                                    (AsnWriteFunc) OrgNameAsnWrite);
11233     } else {
11234       AddOrgNameToOrgName (org1->orgname, org2->orgname);
11235     }
11236   }
11237   /* dbtags */
11238   if (org2->db != NULL) {
11239     vnp2 = org2->db;
11240     while (vnp2 != NULL) {
11241       dbt2 = vnp2->data.ptrvalue;
11242       if (dbt2 != NULL) {
11243         vnp1 = org1->db;
11244         while (vnp1 != NULL) {
11245           dbt1 = vnp1->data.ptrvalue;
11246           if (dbt1 != NULL && StringCmp (dbt1->db, dbt2->db) == 0) {
11247             break;
11248           }
11249           vnp1 = vnp1->next;
11250         }
11251         if (vnp1 == NULL) {
11252           ValNodeAddPointer (&(org1->db), 0, DbtagDup (dbt2));
11253         }
11254       }
11255       vnp2 = vnp2->next;
11256     }
11257   }
11258 }
11259 
11260 
SubSourceListCopy(SubSourcePtr orig)11261 static SubSourcePtr SubSourceListCopy (SubSourcePtr orig)
11262 {
11263   SubSourcePtr list = NULL, prev = NULL, mod;
11264 
11265   while (orig != NULL) {
11266     mod = AsnIoMemCopy (orig, (AsnReadFunc)SubSourceAsnRead, (AsnWriteFunc)SubSourceAsnWrite);
11267     if (prev == NULL) {
11268       list = mod;
11269     } else {
11270       prev->next = mod;
11271     }
11272     prev = mod;
11273     orig = orig->next;
11274   }
11275   return list;
11276 }
11277 
11278 
AddBioSourceToBioSource(BioSourcePtr biop1,BioSourcePtr biop2)11279 static void AddBioSourceToBioSource (BioSourcePtr biop1, BioSourcePtr biop2)
11280 {
11281   SubSourcePtr cpy, ssp;
11282 
11283   if (biop1 == NULL || biop2 == NULL) {
11284     return;
11285   }
11286 
11287   /* genome */
11288   if (biop1->genome == GENOME_unknown) {
11289     biop1->genome = biop2->genome;
11290   }
11291   /* origin */
11292   if (biop1->origin == ORG_UNKNOWN) {
11293     biop1->origin = biop2->origin;
11294   }
11295   /* subtype */
11296   if (biop2->subtype != NULL) {
11297     cpy = SubSourceListCopy (biop2->subtype);
11298     if (biop1->subtype == NULL) {
11299       biop1->subtype = cpy;
11300     } else {
11301       ssp = biop1->subtype;
11302       while (ssp->next != NULL) {
11303         ssp = ssp->next;
11304       }
11305       ssp->next = cpy;
11306     }
11307   }
11308 
11309   if (biop1->org == NULL) {
11310     biop1->org = AsnIoMemCopy (biop2->org, (AsnReadFunc) OrgRefAsnRead,
11311                                            (AsnWriteFunc) OrgRefAsnWrite);
11312   } else {
11313     AddOrgRefToOrgRef (biop1->org, biop2->org);
11314   }
11315 
11316 }
11317 
11318 
MergeBioSourcesInDescrs(SeqDescrPtr sdp,CharPtr id,LogInfoPtr lip)11319 static void MergeBioSourcesInDescrs (SeqDescrPtr sdp, CharPtr id, LogInfoPtr lip)
11320 {
11321   SeqDescrPtr sdp1, sdp2;
11322   ObjValNodePtr ovp;
11323   ValNodePtr errs, vnp;
11324 
11325   sdp1 = sdp;
11326   while (sdp1 != NULL && sdp1->choice != Seq_descr_source) {
11327     sdp1 = sdp1->next;
11328   }
11329   if (sdp1 != NULL) {
11330     sdp2 = sdp1->next;
11331     while (sdp2 != NULL) {
11332       if (sdp2->choice == Seq_descr_source && sdp2->extended == 1) {
11333         errs = OkToMergeBioSources (sdp1->data.ptrvalue, sdp2->data.ptrvalue);
11334         if (errs == NULL) {
11335           AddBioSourceToBioSource (sdp1->data.ptrvalue, sdp2->data.ptrvalue);
11336           ovp = (ObjValNodePtr) sdp2;
11337           ovp->idx.deleteme = TRUE;
11338           fprintf (lip->fp, "Successfully merged biosources on %s\n", id);
11339         } else {
11340           fprintf (lip->fp, "Unable to merge biosources on %s because:\n", id);
11341           for (vnp = errs; vnp != NULL; vnp = vnp->next) {
11342             fprintf (lip->fp, "\t%s\n", (CharPtr) vnp->data.ptrvalue);
11343           }
11344           errs = ValNodeFreeData (errs);
11345         }
11346         lip->data_in_log = TRUE;
11347       }
11348       sdp2 = sdp2->next;
11349     }
11350   }
11351 }
11352 
11353 
MergeBiosourcesCallback(BioseqPtr bsp,Pointer data)11354 static void MergeBiosourcesCallback (BioseqPtr bsp, Pointer data)
11355 {
11356   CharPtr label;
11357 
11358   if (bsp == NULL || bsp->descr == NULL) {
11359     return;
11360   }
11361 
11362   label = GetBioseqLabel (bsp);
11363   MergeBioSourcesInDescrs (bsp->descr, label, (LogInfoPtr) data);
11364   label = MemFree (label);
11365 }
11366 
11367 
MergeBioSourcesOnSetCallback(BioseqSetPtr bssp,Pointer data)11368 static void MergeBioSourcesOnSetCallback (BioseqSetPtr bssp, Pointer data)
11369 {
11370   CharPtr label;
11371 
11372   if (bssp == NULL || bssp->descr == NULL) {
11373     return;
11374   }
11375 
11376   label = GetBioseqSetLabel (bssp);
11377   MergeBioSourcesInDescrs (bssp->descr, label, (LogInfoPtr) data);
11378   label = MemFree (label);
11379 }
11380 
11381 
MergeBiosources(IteM i)11382 NLM_EXTERN void MergeBiosources (IteM i)
11383 {
11384   BaseFormPtr        bfp;
11385   SeqEntryPtr sep;
11386   LogInfoPtr lip;
11387 
11388 #ifdef WIN_MAC
11389   bfp = currentFormDataPtr;
11390 #else
11391   bfp = GetObjectExtra (i);
11392 #endif
11393   if (bfp == NULL) return;
11394 
11395   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
11396 
11397   lip = OpenLog ("BioSource Merge Report");
11398   VisitBioseqsInSep (sep, lip, MergeBiosourcesCallback);
11399   VisitSetsInSep (sep, lip, MergeBioSourcesOnSetCallback);
11400   CloseLog (lip);
11401   if (!lip->data_in_log) {
11402     Message (MSG_ERROR, "No Biosource found for merging");
11403   }
11404   lip = FreeLog (lip);
11405 
11406   DeleteMarkedObjects (bfp->input_entityID, 0, NULL);
11407   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
11408   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
11409 }
11410 
11411 
11412 typedef struct exportqualifiersform {
11413   FORM_MESSAGE_BLOCK
11414   ButtoN source_qualifiers;
11415   DialoG src_qual_selection;
11416   GrouP  qual_choice;
11417   ButtoN launch_excel;
11418 } ExportQualifiersFormData, PNTR ExportQualifiersFormPtr;
11419 
DoExportQualifiers(ButtoN b)11420 static void DoExportQualifiers (ButtoN b)
11421 {
11422   ExportQualifiersFormPtr frm;
11423   Char               path [PATH_MAX];
11424   Uint1              field_type = 0;
11425   Int2               val;
11426   FILE *fp;
11427   ValNodePtr         field_list = NULL;
11428 
11429   frm = (ExportQualifiersFormPtr) GetObjectExtra (b);
11430   if (frm == NULL) {
11431     return;
11432   }
11433 
11434   if (GetStatus (frm->source_qualifiers)) {
11435     field_list = DialogToPointer (frm->src_qual_selection);
11436   }
11437   val = GetValue (frm->qual_choice);
11438   if ((val < 2 || val > 7) && field_list == NULL) {
11439     Message (MSG_ERROR, "Must select qualifiers to export!");
11440     return;
11441   }
11442   switch (val) {
11443     case 1:
11444       field_type = 0;
11445       break;
11446     case 2:
11447       field_type = FieldType_feature_field;
11448       break;
11449     case 3:
11450       field_type = FieldType_cds_gene_prot;
11451       break;
11452     case 4:
11453       field_type = FieldType_rna_field;
11454       break;
11455     case 5:
11456       field_type = FieldType_misc;
11457       break;
11458     case 6:
11459       field_type = FieldType_pub;
11460       break;
11461     case 7:
11462       field_type = FieldType_dblink;
11463       break;
11464   }
11465 
11466   if (GetOutputFileName (path, sizeof (path), NULL)) {
11467     fp = FileOpen (path, "w");
11468     if (fp == NULL) {
11469       Message (MSG_ERROR, "Unable to open %s", path);
11470       return;
11471     }
11472     ExportFieldTable (field_type, field_list, GetTopSeqEntryForEntityID (frm->input_entityID), fp);
11473     FileClose (fp);
11474 #ifdef WIN_MSWIN
11475     if (GetStatus (frm->launch_excel)) {
11476       Nlm_MSWin_OpenApplication ("excel.exe", path);
11477     }
11478 #endif
11479 
11480   }
11481   field_list = FieldTypeListFree (field_list);
11482   Remove (frm->form);
11483 }
11484 
11485 
ChooseSourceQualifiers(ButtoN b)11486 static void ChooseSourceQualifiers (ButtoN b)
11487 {
11488   ExportQualifiersFormPtr frm;
11489 
11490   frm = (ExportQualifiersFormPtr) GetObjectExtra (b);
11491   if (frm == NULL) {
11492     return;
11493   }
11494   if (GetStatus (frm->source_qualifiers)) {
11495     Enable (frm->src_qual_selection);
11496   } else {
11497     Disable (frm->src_qual_selection);
11498   }
11499 }
11500 
11501 
FieldTypeDataFree(ValNodePtr vnp)11502 static void FieldTypeDataFree (ValNodePtr vnp)
11503 {
11504   if (vnp != NULL) {
11505     vnp->data.ptrvalue = SourceQualChoiceFree (vnp->data.ptrvalue);
11506   }
11507 }
11508 
11509 
FieldTypeMatch(ValNodePtr vnp1,ValNodePtr vnp2)11510 static Boolean FieldTypeMatch (ValNodePtr vnp1, ValNodePtr vnp2)
11511 {
11512   if (vnp1 == NULL || vnp2 == NULL)
11513   {
11514     return FALSE;
11515   }
11516   return AsnIoMemComp (vnp1, vnp2, (AsnWriteFunc) FieldTypeAsnWrite);
11517 }
11518 
11519 
ExportQualifiersBaseForm(BaseFormPtr bfp)11520 NLM_EXTERN void ExportQualifiersBaseForm (BaseFormPtr bfp)
11521 {
11522   ExportQualifiersFormPtr frm;
11523   WindoW         w;
11524   GrouP          h, c;
11525   ButtoN         b;
11526   SeqEntryPtr    sep;
11527   ValNodePtr     fields;
11528 
11529   if (bfp == NULL) return;
11530 
11531   frm = (ExportQualifiersFormPtr) MemNew (sizeof (ExportQualifiersFormData));
11532   if (frm == NULL) return;
11533   frm->input_entityID = bfp->input_entityID;
11534 
11535   w = FixedWindow (-50, -33, -10, -10, "Export Qualifiers", StdCloseWindowProc);
11536   SetObjectExtra (w, frm, StdCleanupExtraProc);
11537   frm->form = (ForM) w;
11538 
11539   h = HiddenGroup (w, -1, 0, NULL);
11540   SetGroupSpacing (h, 10, 10);
11541   frm->source_qualifiers = CheckBox (h, "Source Qualifiers", ChooseSourceQualifiers);
11542   SetObjectExtra (frm->source_qualifiers, frm, NULL);
11543   SetStatus (frm->source_qualifiers, TRUE);
11544 
11545   sep = GetTopSeqEntryForEntityID (frm->input_entityID);
11546 
11547   fields = GetFieldListForFieldType (FieldType_source_qual, sep);
11548 
11549   frm->src_qual_selection = ValNodeSelectionDialog (h, fields, TALL_SELECTION_LIST,
11550                                 SummarizeFieldType,
11551                                 FieldTypeDataFree,
11552                                 FieldTypeCopy,
11553                                 FieldTypeMatch,
11554                                 "qualifiers",
11555                                 NULL, NULL, TRUE);
11556   SendMessageToDialog (frm->src_qual_selection, NUM_VIB_MSG + 1);
11557 
11558   frm->qual_choice = NormalGroup (h, 0, 7, "Other Qualifiers", programFont, NULL);
11559   RadioButton (frm->qual_choice, "None");
11560   RadioButton (frm->qual_choice, "Feature Qualifiers");
11561   RadioButton (frm->qual_choice, "CDS-Gene-Prot Qualifiers");
11562   RadioButton (frm->qual_choice, "RNA Qualifiers");
11563   RadioButton (frm->qual_choice, "Definition Lines");
11564   RadioButton (frm->qual_choice, "Publication Titles");
11565   RadioButton (frm->qual_choice, "DBLink");
11566   SetValue (frm->qual_choice, 1);
11567 
11568 #ifdef WIN_MSWIN
11569   frm->launch_excel = CheckBox (h, "Launch Excel", NULL);
11570 #endif
11571 
11572   c = HiddenGroup (h, 2, 0, NULL);
11573   b = PushButton (c, "Accept", DoExportQualifiers);
11574   SetObjectExtra (b, frm, NULL);
11575   PushButton (c, "Cancel", StdCancelButtonProc);
11576 
11577   AlignObjects (ALIGN_CENTER, (HANDLE) frm->source_qualifiers,
11578                               (HANDLE) frm->src_qual_selection,
11579                               (HANDLE) frm->qual_choice,
11580 #ifdef WIN_MSWIN
11581                               (HANDLE) frm->launch_excel,
11582 #endif
11583                               (HANDLE) c,
11584                               NULL);
11585   Show (w);
11586 }
11587 
11588 
ExportQualifiers(IteM i)11589 NLM_EXTERN void ExportQualifiers (IteM i)
11590 {
11591   BaseFormPtr        bfp;
11592 
11593 #ifdef WIN_MAC
11594   bfp = currentFormDataPtr;
11595 #else
11596   bfp = GetObjectExtra (i);
11597 #endif
11598 
11599   ExportQualifiersBaseForm (bfp);
11600 }
11601 
11602 
ExportBankitComment(SeqDescrPtr sdp,Pointer data)11603 static void ExportBankitComment (SeqDescrPtr sdp, Pointer data)
11604 {
11605   UserObjectPtr      uop;
11606   ObjectIdPtr        oip;
11607   UserFieldPtr       ufp;
11608   CharPtr            comment, pound;
11609   BioseqPtr          bsp;
11610   Char               id_text[100];
11611   FILE               *fp;
11612   CharPtr            buf = NULL;
11613   Int4               buf_len = 0, line_len;
11614 
11615   if (sdp == NULL || sdp->choice != Seq_descr_user || data == NULL) {
11616     return;
11617   }
11618 
11619   fp = (FILE *) data;
11620 
11621   /* Bankit Comments */
11622   uop = (UserObjectPtr) sdp->data.ptrvalue;
11623   if (uop != NULL && StringCmp (uop->_class, "SMART_V1.0") != 0) {
11624     oip = uop->type;
11625     if (oip != NULL && StringCmp (oip->str, "Submission") == 0) {
11626       for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
11627         oip = ufp->label;
11628         if (oip != NULL && StringCmp (oip->str, "AdditionalComment") == 0) {
11629 
11630           /* print out ID */
11631           bsp = GetSequenceForObject (OBJ_SEQDESC, sdp);
11632           if (bsp != NULL) {
11633             SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_text, PRINTID_FASTA_SHORT, sizeof (id_text) - 1);
11634             fprintf (fp, ">%s\n", id_text);
11635           }
11636 
11637           comment = (CharPtr) ufp->data.ptrvalue;
11638           pound = StringSearch (comment, "##");
11639           while (pound != NULL) {
11640             line_len = pound - comment + 1;
11641             if (buf_len < line_len) {
11642               buf = MemFree (buf);
11643               buf_len = line_len;
11644               buf = (CharPtr) MemNew (sizeof (Char) * buf_len);
11645             }
11646             if (buf != NULL) {
11647               StringNCpy (buf, comment, line_len - 1);
11648               buf[line_len - 1] = 0;
11649               fprintf (fp, "%s\n", buf);
11650             }
11651             comment = pound + 2;
11652             pound = StringSearch (comment, "##");
11653           }
11654           fprintf (fp, "%s\n", comment);
11655           buf = MemFree (buf);
11656         }
11657       }
11658     }
11659   }
11660 }
11661 
11662 
11663 
ExportBankitComments(IteM i)11664 extern void ExportBankitComments (IteM i)
11665 {
11666   BaseFormPtr        bfp;
11667   SeqEntryPtr    sep;
11668   Char          path [PATH_MAX];
11669   FILE *fp;
11670 
11671 
11672 #ifdef WIN_MAC
11673   bfp = currentFormDataPtr;
11674 #else
11675   bfp = GetObjectExtra (i);
11676 #endif
11677   if (bfp == NULL) return;
11678 
11679   if (!GetOutputFileName (path, sizeof (path), NULL)
11680       || (fp = FileOpen (path, "w")) == NULL) {
11681     return;
11682   }
11683 
11684   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
11685 
11686   VisitDescriptorsInSep (sep, fp, ExportBankitComment);
11687   FileClose (fp);
11688 
11689 }
11690 
11691 
TrimPrimerSeqJunk(IteM i)11692 extern void TrimPrimerSeqJunk (IteM i)
11693 {
11694   BaseFormPtr    bfp;
11695   SeqEntryPtr    sep;
11696 
11697 
11698 #ifdef WIN_MAC
11699   bfp = currentFormDataPtr;
11700 #else
11701   bfp = GetObjectExtra (i);
11702 #endif
11703   if (bfp == NULL) return;
11704 
11705   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
11706 
11707   WatchCursor ();
11708   Update();
11709   TrimPrimerSeqJunkInSeqEntry (sep, NULL);
11710   ArrowCursor ();
11711   Update ();
11712   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
11713   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
11714 }
11715 
11716 
FixiPCRPrimerSeqsMenuItem(IteM i)11717 extern void FixiPCRPrimerSeqsMenuItem (IteM i)
11718 {
11719   BaseFormPtr    bfp;
11720   SeqEntryPtr    sep;
11721 
11722 
11723 #ifdef WIN_MAC
11724   bfp = currentFormDataPtr;
11725 #else
11726   bfp = GetObjectExtra (i);
11727 #endif
11728   if (bfp == NULL) return;
11729 
11730   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
11731 
11732   WatchCursor ();
11733   Update();
11734   VisitBioSourcesInSep (sep, NULL, FixiPCRPrimerSeqsCallback);
11735   ArrowCursor ();
11736   Update ();
11737   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
11738   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
11739 }
11740 
11741 
GetContigsInScaffoldsCallback(BioseqPtr bsp,Pointer data)11742 static void GetContigsInScaffoldsCallback (BioseqPtr bsp, Pointer data)
11743 {
11744   ValNodePtr PNTR contig_list;
11745   DeltaSeqPtr dsp;
11746   SeqLocPtr   loc;
11747   SeqIdPtr    sip;
11748 
11749   if (bsp == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext == NULL
11750       || (contig_list = (ValNodePtr PNTR) data) == NULL) {
11751     return;
11752   }
11753 
11754   for (dsp = (DeltaSeqPtr)(bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
11755     if (dsp->choice == 1) {
11756       loc = (SeqLocPtr)dsp->data.ptrvalue;
11757       sip = SeqLocId (loc);
11758       if (sip != NULL) {
11759         ValNodeAddPointer (contig_list, 0, SeqIdDup (sip));
11760       }
11761     }
11762   }
11763 }
11764 
11765 
AdjustFeaturesForSequenceCut(BioseqPtr bsp,Int4 cut_start,Int4 cut_len)11766 static void AdjustFeaturesForSequenceCut (BioseqPtr bsp, Int4 cut_start, Int4 cut_len)
11767 {
11768   SeqFeatPtr  sfp;
11769   SeqMgrFeatContext fcontext;
11770 
11771   for (sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
11772       sfp != NULL;
11773       sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &fcontext)) {
11774     if (sfp->idx.deleteme) {
11775       continue;
11776     }
11777     if (fcontext.right >= cut_start) {
11778       if (fcontext.left >= cut_start && fcontext.right < cut_start + cut_len) {
11779         /* feature is entirely in removal area */
11780         sfp->idx.deleteme = TRUE;
11781       } else {
11782         /* adjust positions of downstream features */
11783         SeqEdSeqFeatDelete (sfp, bsp, cut_start, cut_start + cut_len - 1, TRUE);
11784       }
11785     }
11786   }
11787 }
11788 
11789 /* need to:
11790  * remove loc from sequence
11791  * remove features that corresponded to that loc
11792  * adjust positions of downstream features
11793  */
RemoveContigFromScaffold(BioseqPtr bsp,SeqIdPtr remove_sip)11794 static void RemoveContigFromScaffold (BioseqPtr bsp, SeqIdPtr remove_sip)
11795 {
11796   DeltaSeqPtr dsp, dsp_prev = NULL, dsp_next;
11797   SeqLocPtr   loc;
11798   SeqLitPtr   slip;
11799   SeqIdPtr    sip;
11800   Int4        offset = 0, len, orig_offset = 0;
11801 
11802   if (bsp == NULL || remove_sip == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext == NULL) {
11803     return;
11804   }
11805 
11806   for (dsp = (DeltaSeqPtr)(bsp->seq_ext); dsp != NULL; dsp = dsp_next) {
11807     dsp_next = dsp->next;
11808     if (dsp->choice == 1) {
11809       loc = (SeqLocPtr)dsp->data.ptrvalue;
11810       sip = SeqLocId (loc);
11811       len = SeqLocLen (loc);
11812       if (SeqIdComp (sip, remove_sip) == SIC_YES) {
11813         AdjustFeaturesForSequenceCut (bsp, orig_offset, len);
11814 
11815         /* remove from sequence */
11816         bsp->length -= len;
11817         if (dsp_prev == NULL) {
11818           bsp->seq_ext = dsp->next;
11819         } else {
11820           dsp_prev->next = dsp->next;
11821         }
11822         dsp->next = NULL;
11823         dsp = DeltaSeqFree (dsp);
11824         orig_offset += len;
11825       } else {
11826         offset += len;
11827         orig_offset += len;
11828         dsp_prev = dsp;
11829       }
11830     } else if (dsp->choice == 2) {   /* SeqLitPtr */
11831       slip = (SeqLitPtr)(dsp->data.ptrvalue);
11832       if (slip != NULL) {
11833         offset += slip->length;
11834         orig_offset += slip->length;
11835       }
11836       dsp_prev = dsp;
11837     }
11838   }
11839 
11840   /* if last deltaseq is gap, remove */
11841   if (dsp_prev != NULL && dsp_prev->choice == 2 && (slip = dsp_prev->data.ptrvalue) != NULL
11842     && slip->seq_data == NULL && slip->fuzz == NULL) {
11843     if (slip->length == 0) {
11844       bsp->length -= 100;
11845       AdjustFeaturesForSequenceCut (bsp, orig_offset, 100);
11846     } else {
11847       bsp->length -= slip->length;
11848       AdjustFeaturesForSequenceCut (bsp, orig_offset, slip->length);
11849     }
11850     dsp = bsp->seq_ext;
11851     dsp_prev = NULL;
11852     while (dsp->next != NULL) {
11853       dsp_prev = dsp;
11854       dsp = dsp->next;
11855     }
11856     if (dsp_prev != NULL) {
11857       dsp_prev->next = NULL;
11858     }
11859     dsp = DeltaSeqFree (dsp);
11860   }
11861 
11862   /* if first delta seq is gap, remove */
11863   if ((dsp = (DeltaSeqPtr) bsp->seq_ext) != NULL && dsp->choice == 2
11864       && (slip = dsp->data.ptrvalue) != NULL
11865       && slip->seq_data == NULL && slip->fuzz == NULL) {
11866     if (slip->length == 0) {
11867       bsp->length -= 100;
11868       AdjustFeaturesForSequenceCut (bsp, 0, 100);
11869     } else {
11870       bsp->length -= slip->length;
11871       AdjustFeaturesForSequenceCut (bsp, 0, slip->length);
11872     }
11873     bsp->seq_ext = dsp->next;
11874     dsp->next = NULL;
11875     dsp = DeltaSeqFree (dsp);
11876   }
11877 
11878   CombineAdjacentGapsOnBioseq (bsp, NULL);
11879 }
11880 
11881 
RemoveContigFromScaffoldCallback(BioseqPtr bsp,Pointer data)11882 static void RemoveContigFromScaffoldCallback (BioseqPtr bsp, Pointer data)
11883 {
11884   RemoveContigFromScaffold (bsp, (SeqIdPtr)data);
11885 }
11886 
11887 
11888 typedef struct removecontigfromscaffoldform {
11889   FORM_MESSAGE_BLOCK
11890 
11891   DialoG list_dlg;
11892 
11893 } RemoveContigFromScaffoldFormData, PNTR RemoveContigFromScaffoldFormPtr;
11894 
11895 
DoRemoveContigsFromScaffolds(ButtoN b)11896 static void DoRemoveContigsFromScaffolds (ButtoN b)
11897 {
11898   ValNodePtr contig_list, vnp;
11899   RemoveContigFromScaffoldFormPtr frm;
11900   SeqEntryPtr sep;
11901 
11902   frm = (RemoveContigFromScaffoldFormPtr)GetObjectExtra (b);
11903   if (frm == NULL) {
11904     return;
11905   }
11906 
11907   contig_list = DialogToPointer (frm->list_dlg);
11908   if (contig_list == NULL) {
11909     Message (MSG_ERROR, "No sequences selected");
11910     return;
11911   }
11912 
11913   sep = GetTopSeqEntryForEntityID (frm->input_entityID);
11914 
11915   for (vnp = contig_list; vnp != NULL; vnp = vnp->next) {
11916     VisitBioseqsInSep (sep, vnp->data.ptrvalue, RemoveContigFromScaffoldCallback);
11917   }
11918 
11919   DeleteMarkedObjects (frm->input_entityID, 0, NULL);
11920   RenormalizeNucProtSets (sep, TRUE);
11921   ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
11922   ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
11923   Remove (frm->form);
11924   Update();
11925 }
11926 
RemoveContigFromScaffoldMenuItem(IteM i)11927 extern void RemoveContigFromScaffoldMenuItem (IteM i)
11928 {
11929   BaseFormPtr    bfp;
11930   SeqEntryPtr    sep;
11931   ValNodePtr     contig_list = NULL;
11932   RemoveContigFromScaffoldFormPtr frm;
11933   WindoW         w;
11934   GrouP          h, c;
11935   ButtoN         b;
11936   PrompT         p1;
11937 
11938 #ifdef WIN_MAC
11939   bfp = currentFormDataPtr;
11940 #else
11941   bfp = GetObjectExtra (i);
11942 #endif
11943   if (bfp == NULL) return;
11944 
11945   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
11946 
11947   /* first, need to get list of contigs in scaffolds */
11948   VisitBioseqsInSep (sep, &contig_list, GetContigsInScaffoldsCallback);
11949 
11950   if (contig_list == NULL) {
11951     Message (MSG_ERROR, "No scaffolds found");
11952     return;
11953   }
11954 
11955   /* get list of contigs to remove */
11956   frm = (RemoveContigFromScaffoldFormPtr) MemNew (sizeof (RemoveContigFromScaffoldFormData));
11957   w = FixedWindow (-50, -33, -10, -10, "Remove Contigs from Scaffolds", StdCloseWindowProc);
11958   SetObjectExtra (w, frm, StdCleanupFormProc);
11959   frm->form = (ForM) w;
11960   frm->input_entityID = bfp->input_entityID;
11961   h = HiddenGroup (w, -1, 0, NULL);
11962   SetGroupSpacing (h, 10, 10);
11963   p1 = StaticPrompt (h, "Choose contigs to remove", 0, dialogTextHeight, programFont, 'c');
11964   frm->list_dlg = ValNodeSelectionDialog (h, contig_list, TALL_SELECTION_LIST,
11965                                           ValNodeSeqIdName, ValNodeSeqIdFree,
11966                                           ValNodeSeqIdCopy, ValNodeSeqIdMatch,
11967                                           "seqid", NULL, NULL, TRUE);
11968   c = HiddenGroup (h, 4, 0, NULL);
11969   b = PushButton (c, "Accept", DoRemoveContigsFromScaffolds);
11970   SetObjectExtra (b, frm, NULL);
11971   PushButton (c, "Cancel", StdCancelButtonProc);
11972 
11973   AlignObjects (ALIGN_CENTER, (HANDLE) p1, (HANDLE) frm->list_dlg, (HANDLE) c, NULL);
11974   RealizeWindow (w);
11975   Show (w);
11976   Update ();
11977 }
11978 
11979 
ConvertRptUnitRangeToLocationCallback(SeqFeatPtr sfp,Pointer data)11980 static void ConvertRptUnitRangeToLocationCallback (SeqFeatPtr sfp, Pointer data)
11981 {
11982   SeqLocPtr new_slp;
11983   GBQualPtr gbqual, gbq_prev = NULL;
11984   LogInfoPtr lip;
11985   BioseqPtr bsp;
11986 
11987   if (sfp == NULL || sfp->idx.subtype != FEATDEF_repeat_region) {
11988     return;
11989   }
11990 
11991   bsp = BioseqFindFromSeqLoc (sfp->location);
11992 
11993   lip = (LogInfoPtr) data;
11994 
11995   for (gbqual = sfp->qual; gbqual != NULL; gbqual = gbqual->next) {
11996     if (StringICmp (gbqual->qual, "rpt_unit_range") == 0 && bsp != NULL) {
11997       new_slp = ParseSimpleSeqLoc (gbqual->val, bsp);
11998       if (new_slp == NULL) {
11999         if (lip != NULL) {
12000           fprintf (lip->fp, "Unable to parse location from '%s'\n", gbqual->val);
12001           lip->data_in_log = TRUE;
12002         }
12003         gbq_prev = gbqual;
12004       } else {
12005         sfp->location = SeqLocFree (sfp->location);
12006         sfp->location = new_slp;
12007         if (gbq_prev == NULL) {
12008           sfp->qual = gbqual->next;
12009         } else {
12010           gbq_prev->next = gbqual->next;
12011         }
12012         gbqual->next = NULL;
12013         gbqual = GBQualFree (gbqual);
12014         break;
12015       }
12016     } else {
12017       gbq_prev = gbqual;
12018     }
12019   }
12020 }
12021 
ConvertRptUnitRangeToLocation(IteM i)12022 extern void ConvertRptUnitRangeToLocation (IteM i)
12023 {
12024   BaseFormPtr    bfp;
12025   SeqEntryPtr    sep;
12026   LogInfoPtr     lip;
12027 
12028 #ifdef WIN_MAC
12029   bfp = currentFormDataPtr;
12030 #else
12031   bfp = GetObjectExtra (i);
12032 #endif
12033   if (bfp == NULL) return;
12034 
12035   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
12036 
12037   lip = OpenLog ("Conversions");
12038 
12039   VisitFeaturesInSep (sep, lip, ConvertRptUnitRangeToLocationCallback);
12040 
12041   CloseLog (lip);
12042   FreeLog (lip);
12043 
12044   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
12045   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
12046   Update ();
12047 }
12048 
12049 
FindGeneInSeqEntryByLocusTag(SeqEntryPtr sep,CharPtr locus_tag)12050 static SeqFeatPtr FindGeneInSeqEntryByLocusTag (SeqEntryPtr sep, CharPtr locus_tag)
12051 {
12052   SeqMgrFeatContext fcontext;
12053   BioseqSetPtr bssp;
12054   SeqFeatPtr   gene = NULL;
12055 
12056 
12057   if (sep == NULL || sep->data.ptrvalue == NULL || StringHasNoText (locus_tag)) {
12058     return NULL;
12059   }
12060 
12061   if (IS_Bioseq (sep)) {
12062     gene = SeqMgrGetGeneByLocusTag (sep->data.ptrvalue, locus_tag, &fcontext);
12063   } else if (IS_Bioseq_set (sep)) {
12064     bssp = (BioseqSetPtr) sep->data.ptrvalue;
12065     for (sep = bssp->seq_set; sep != NULL && gene == NULL; sep = sep->next) {
12066       gene = FindGeneInSeqEntryByLocusTag (sep, locus_tag);
12067     }
12068   }
12069   return gene;
12070 }
12071 
12072 
ClearCDDCallback(SeqFeatPtr sfp,Pointer data)12073 static void ClearCDDCallback (SeqFeatPtr sfp, Pointer data)
12074 {
12075   ObjectIdPtr    oip;
12076   UserObjectPtr  uop;
12077   ValNodePtr     vnp, vnp_n, vnp_p;
12078   DbtagPtr       dbtag;
12079   Int4           len;
12080 
12081   if (sfp == NULL) {
12082     return;
12083   }
12084   if ((uop = sfp->ext) != NULL && (oip = uop->type) != NULL
12085       && (len = StringLen (oip->str)) >= 12
12086       && StringNICmp (oip->str, "cdd", 3) == 0
12087       && StringICmp (oip->str + len - 9, "ScoreData") == 0) {
12088     sfp->idx.deleteme = TRUE;
12089   } else if (sfp->dbxref != NULL) {
12090     vnp_p = NULL;
12091     for (vnp = sfp->dbxref; vnp != NULL; vnp = vnp_n) {
12092       vnp_n = vnp->next;
12093       dbtag = (DbtagPtr) vnp->data.ptrvalue;
12094       if (dbtag != NULL && StringICmp (dbtag->db, "CDD") == 0) {
12095         if (vnp_p == NULL) {
12096           sfp->dbxref = vnp_n;
12097         } else {
12098           vnp_p->next = vnp_n;
12099         }
12100         vnp->next = NULL;
12101         vnp->data.ptrvalue = DbtagFree (vnp->data.ptrvalue);
12102         vnp = ValNodeFree (vnp);
12103       } else {
12104         vnp_p = vnp;
12105       }
12106     }
12107   }
12108 }
12109 
12110 
CleanupCDD(IteM i)12111 NLM_EXTERN void CleanupCDD (IteM i)
12112 {
12113   BaseFormPtr       bfp;
12114   SeqEntryPtr       sep;
12115 
12116 #ifdef WIN_MAC
12117   bfp = currentFormDataPtr;
12118 #else
12119   bfp = GetObjectExtra (i);
12120 #endif
12121   if (bfp == NULL || bfp->input_entityID == 0) return;
12122 
12123   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
12124 
12125   WatchCursor();
12126   Update();
12127   VisitFeaturesInSep (sep, NULL, ClearCDDCallback);
12128   DeleteMarkedObjects (0, OBJ_SEQENTRY, sep);
12129   ArrowCursor ();
12130   Update ();
12131   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
12132   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
12133 }
12134 
12135 
12136 typedef struct trimseqbyalignform {
12137   FORM_MESSAGE_BLOCK
12138 
12139   ButtoN trim_before_btn;
12140   TexT trim_before_coord_txt;
12141   ButtoN trim_after_btn;
12142   TexT trim_after_coord_txt;
12143   ButtoN accept_btn;
12144 
12145   SeqAlignPtr salp;
12146 } TrimSeqByAlignFormData, PNTR TrimSeqByAlignFormPtr;
12147 
12148 
CleanupTrimSeqByAlignForm(GraphiC g,VoidPtr data)12149 static void CleanupTrimSeqByAlignForm (GraphiC g, VoidPtr data)
12150 
12151 {
12152   TrimSeqByAlignFormPtr frm;
12153 
12154   frm = (TrimSeqByAlignFormPtr) data;
12155   if (frm != NULL) {
12156     frm->salp = SeqAlignFree (frm->salp);
12157   }
12158   StdCleanupFormProc (g, data);
12159 }
12160 
12161 
12162 
ChangeTrimSeqByAln(TrimSeqByAlignFormPtr frm)12163 static void ChangeTrimSeqByAln(TrimSeqByAlignFormPtr frm)
12164 {
12165   Boolean is_ok = FALSE;
12166   CharPtr str;
12167   Int4 val1 = 0, val2 = 0;
12168 
12169   if (frm == NULL) {
12170     return;
12171   }
12172 
12173   if (GetStatus (frm->trim_before_btn)) {
12174     Enable (frm->trim_before_coord_txt);
12175     str = SaveStringFromText (frm->trim_before_coord_txt);
12176     if (!StringHasNoText (str)) {
12177       val1 = atoi (str);
12178       if (val1 > 0) {
12179         is_ok = TRUE;
12180       }
12181     }
12182     str = MemFree (str);
12183   }
12184 
12185   if (GetStatus (frm->trim_after_btn)) {
12186     Enable (frm->trim_after_coord_txt);
12187     str = SaveStringFromText (frm->trim_after_coord_txt);
12188     if (!StringHasNoText (str)) {
12189       val2 = atoi (str);
12190       if (val2 > 0) {
12191         is_ok = TRUE;
12192       } else {
12193         is_ok = FALSE;
12194       }
12195     }
12196     str = MemFree (str);
12197   }
12198 
12199   if (val1 > 0 && val2 > 0 && val2 <= val1) {
12200     is_ok = FALSE;
12201   }
12202 
12203   if (is_ok) {
12204     Enable (frm->accept_btn);
12205   } else {
12206     Disable (frm->accept_btn);
12207   }
12208 
12209 }
12210 
12211 
ChangeTrimSeqByAlnBtn(ButtoN b)12212 static void ChangeTrimSeqByAlnBtn(ButtoN b)
12213 {
12214   TrimSeqByAlignFormPtr frm;
12215   frm = (TrimSeqByAlignFormPtr) GetObjectExtra (b);
12216   ChangeTrimSeqByAln (frm);
12217 }
12218 
12219 
ChangeTrimSeqByAlnTxt(TexT t)12220 static void ChangeTrimSeqByAlnTxt(TexT t)
12221 {
12222   TrimSeqByAlignFormPtr frm;
12223   frm = (TrimSeqByAlignFormPtr) GetObjectExtra (t);
12224   ChangeTrimSeqByAln (frm);
12225 }
12226 
12227 
AreAllSequencesInAlignmentAtPosition(SeqAlignPtr salp,Int4 pos)12228 static Boolean AreAllSequencesInAlignmentAtPosition (SeqAlignPtr salp, Int4 pos)
12229 {
12230   Int4 row, num_rows, val;
12231 
12232   if (salp == NULL || pos < 0) {
12233     return FALSE;
12234   }
12235   num_rows = AlnMgr2GetNumRows(salp);
12236   for (row = 1; row <= num_rows; row++) {
12237     val = AlnMgr2MapSeqAlignToBioseq (salp, pos, row);
12238     if (val == -2) {
12239       return FALSE;
12240     }
12241   }
12242   return TRUE;
12243 }
12244 
12245 
DoTrimSeqsByAln(ButtoN b)12246 static void DoTrimSeqsByAln (ButtoN b)
12247 {
12248   TrimSeqByAlignFormPtr frm;
12249   CharPtr str;
12250   Int4 val_start = -1, val_stop = -1, num_rows, row, pos, val;
12251   SeqIdPtr sip;
12252   BioseqPtr bsp;
12253   SeqLocPtr slp;
12254   SeqEntryPtr sep;
12255   SeqAnnotPtr sap;
12256   LogInfoPtr  lip;
12257 
12258   frm = (TrimSeqByAlignFormPtr) GetObjectExtra (b);
12259 
12260   if (GetStatus (frm->trim_before_btn)) {
12261     str = SaveStringFromText (frm->trim_before_coord_txt);
12262     val_start = atoi (str) - 1;
12263     str = MemFree (str);
12264     if (!AreAllSequencesInAlignmentAtPosition(frm->salp, val_start)) {
12265       if (Message(MSG_OKC, "Not all sequences are in the alignment at position %d - are you sure you want to continue?", val_start) == ANS_CANCEL) {
12266         return;
12267       }
12268     }
12269   }
12270   if (GetStatus (frm->trim_after_btn)) {
12271     str = SaveStringFromText (frm->trim_after_coord_txt);
12272     val_stop = atoi (str) - 1;
12273     str = MemFree (str);
12274     if (!AreAllSequencesInAlignmentAtPosition(frm->salp, val_stop)) {
12275       if (Message(MSG_OKC, "Not all sequences are in the alignment at position %d - are you sure you want to continue?", val_stop) == ANS_CANCEL) {
12276         return;
12277       }
12278     }
12279   }
12280   lip = OpenLog ("Trimmed Locations");
12281 
12282   num_rows = AlnMgr2GetNumRows(frm->salp);
12283 
12284   /* for each sequence in alignment*/
12285   for (row = 1; row <= num_rows; row++) {
12286     sip = AlnMgr2GetNthSeqIdPtr (frm->salp, row);
12287     bsp = BioseqLockById (sip);
12288     if (bsp != NULL) {
12289       if (AlnMgr2GetNthStrand(frm->salp, row) == Seq_strand_minus) {
12290         /* trim 3' ends first */
12291         if (val_start > -1) {
12292           /* get sequence position for alignment coordinate */
12293           pos = AlnMgr2MapSeqAlignToBioseq (frm->salp, val_start, row);
12294           if (pos < 0) {
12295             val = val_start + 1;
12296             while (pos < 0 && val > -1) {
12297               pos = AlnMgr2MapSeqAlignToBioseq (frm->salp, val, row);
12298               val ++;
12299             }
12300           }
12301 
12302           if (pos > -1 && pos < bsp->length - 1) {
12303             /* remove sequence after position */
12304             slp = SeqLocIntNew (pos + 1, bsp->length - 1, Seq_strand_plus, sip);
12305             SeqDeleteByLoc (slp, TRUE, FALSE);
12306             LogTrimmedLocation (lip, slp);
12307             TrimQualityScores (bsp, bsp->length - 1 - pos, FALSE);
12308           }
12309         }
12310         /* now trim 5' end */
12311         if (val_stop > -1) {
12312           /* get sequence position for alignment coordinate */
12313           pos = AlnMgr2MapSeqAlignToBioseq (frm->salp, val_stop, row);
12314           if (pos < 0) {
12315             val = val_stop - 1;
12316             while (pos < 0 && val > -1) {
12317               pos = AlnMgr2MapSeqAlignToBioseq (frm->salp, val, row);
12318               val --;
12319             }
12320           }
12321 
12322           if (pos > 0) {
12323             /* remove sequence before position */
12324             slp = SeqLocIntNew (0, pos - 1, Seq_strand_plus, sip);
12325             SeqDeleteByLoc (slp, TRUE, FALSE);
12326             LogTrimmedLocation (lip, slp);
12327             TrimQualityScores (bsp, pos, TRUE);
12328           }
12329         }
12330       } else {
12331         /* trim 3' ends first */
12332         if (val_stop > -1) {
12333           /* get sequence position for alignment coordinate */
12334           pos = AlnMgr2MapSeqAlignToBioseq (frm->salp, val_stop, row);
12335           if (pos < 0) {
12336             val = val_stop - 1;
12337             while (pos < 0 && val > -1) {
12338               pos = AlnMgr2MapSeqAlignToBioseq (frm->salp, val, row);
12339               val --;
12340             }
12341           }
12342 
12343           if (pos > -1 && pos < bsp->length - 1) {
12344             /* remove sequence after position */
12345             slp = SeqLocIntNew (pos + 1, bsp->length - 1, Seq_strand_plus, sip);
12346             SeqDeleteByLoc (slp, TRUE, FALSE);
12347             LogTrimmedLocation (lip, slp);
12348             TrimQualityScores (bsp, bsp->length - 1 - pos, FALSE);
12349           }
12350         }
12351         /* now trim 5' end */
12352         if (val_start > -1) {
12353           /* get sequence position for alignment coordinate */
12354           pos = AlnMgr2MapSeqAlignToBioseq (frm->salp, val_start, row);
12355           if (pos < 0) {
12356             val = val_start + 1;
12357             while (pos < 0 && val > -1) {
12358               pos = AlnMgr2MapSeqAlignToBioseq (frm->salp, val, row);
12359               val ++;
12360             }
12361           }
12362 
12363           if (pos > -1) {
12364             /* remove sequence before position */
12365             slp = SeqLocIntNew (0, pos - 1, Seq_strand_plus, sip);
12366             SeqDeleteByLoc (slp, TRUE, FALSE);
12367             LogTrimmedLocation (lip, slp);
12368             TrimQualityScores (bsp, pos, TRUE);
12369           }
12370         }
12371       }
12372       BioseqUnlock (bsp);
12373     }
12374   }
12375 
12376   sep = GetTopSeqEntryForEntityID (frm->input_entityID);
12377   sap = (SeqAnnotPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQANNOT);
12378   if (sap != NULL) {
12379     CloseAlignmentEditor (sap->idx.entityID, sap->idx.itemID);
12380 
12381     sap->idx.deleteme = TRUE;
12382     DeleteMarkedObjects (frm->input_entityID, 0, NULL);
12383     fprintf (lip->fp, "Removed Alignment\n");
12384     lip->data_in_log = TRUE;
12385   }
12386 
12387   CloseLog (lip);
12388   lip = FreeLog (lip);
12389 
12390   ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
12391   ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
12392   Remove (frm->form);
12393 }
12394 
12395 
TrimSequencesByAlignment(IteM i)12396 NLM_EXTERN void TrimSequencesByAlignment (IteM i)
12397 {
12398   BaseFormPtr       bfp;
12399   SeqEntryPtr       sep;
12400   TrimSeqByAlignFormPtr frm;
12401   WindoW                w;
12402   ButtoN                b;
12403   GrouP                 h, g, c;
12404   SeqAlignPtr           salp;
12405 
12406 #ifdef WIN_MAC
12407   bfp = currentFormDataPtr;
12408 #else
12409   bfp = GetObjectExtra (i);
12410 #endif
12411   if (bfp == NULL || bfp->input_entityID == 0) return;
12412 
12413   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
12414 
12415   salp  = (SeqAlignPtr)FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN);
12416   if (!salp) {
12417     Message (MSG_ERROR, "No alignments found!");
12418     return;
12419   }
12420 
12421   frm = (TrimSeqByAlignFormPtr) MemNew (sizeof (TrimSeqByAlignFormData));
12422   if (frm == NULL)
12423   {
12424     return;
12425   }
12426 
12427   frm->salp = SeqAlignDup (salp);
12428   AlnMgr2IndexSingleChildSeqAlign(frm->salp);
12429 
12430   frm->input_entityID = bfp->input_entityID;
12431   w = FixedWindow (-50, -33, -10, -10, "Trim Sequences by Alignment Coordinates", StdCloseWindowProc);
12432   SetObjectExtra (w, frm, CleanupTrimSeqByAlignForm);
12433   frm->form = (ForM) w;
12434 
12435   h = HiddenGroup (w, -1, 0, NULL);
12436   SetGroupSpacing (h, 10, 10);
12437 
12438   g = HiddenGroup (h, 2, 0, NULL);
12439   frm->trim_before_btn = CheckBox (g, "Trim before alignment coordinate", ChangeTrimSeqByAlnBtn);
12440   SetObjectExtra (frm->trim_before_btn, frm, NULL);
12441   SetStatus (frm->trim_before_btn, FALSE);
12442   frm->trim_before_coord_txt = DialogText (g, "", 10, ChangeTrimSeqByAlnTxt);
12443   SetObjectExtra (frm->trim_before_coord_txt, frm, NULL);
12444   Disable (frm->trim_before_coord_txt);
12445 
12446   frm->trim_after_btn = CheckBox (g, "Trim after alignment coordinate", ChangeTrimSeqByAlnBtn);
12447   SetObjectExtra (frm->trim_after_btn, frm, NULL);
12448   SetStatus (frm->trim_after_btn, FALSE);
12449   frm->trim_after_coord_txt = DialogText (g, "", 10, ChangeTrimSeqByAlnTxt);
12450   SetObjectExtra (frm->trim_after_coord_txt, frm, NULL);
12451   Disable (frm->trim_after_coord_txt);
12452 
12453   c = HiddenGroup (h, 4, 0, NULL);
12454   frm->accept_btn = PushButton (c, "Accept", DoTrimSeqsByAln);
12455   SetObjectExtra (frm->accept_btn, frm, NULL);
12456 
12457   b = PushButton (c, "Close", StdCancelButtonProc);
12458 
12459   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
12460 
12461   Show (w);
12462 }
12463 
12464 /* add a repeat-region with satellite-type of microsatellite and repeat-type of tandem.
12465 * Make the feature complete over the entire span of the sequence.
12466 */
MakeCommonFeatureMicrosatelliteCallback(BioseqPtr bsp,Pointer data)12467 static void MakeCommonFeatureMicrosatelliteCallback (BioseqPtr bsp, Pointer data)
12468 {
12469   SeqFeatPtr sfp;
12470   ImpFeatPtr ifp;
12471   GBQualPtr  gbq;
12472 
12473   if (bsp == NULL || ISA_aa (bsp->mol)) {
12474     return;
12475   }
12476 
12477   sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
12478   ifp = ImpFeatNew ();
12479   ifp->key = StringSave ("repeat_region");
12480   sfp->data.value.ptrvalue = ifp;
12481   gbq = GBQualNew ();
12482   gbq->qual = StringSave ("rpt_type");
12483   gbq->val = StringSave ("tandem");
12484   sfp->qual = gbq;
12485   gbq = GBQualNew ();
12486   gbq->qual = StringSave ("satellite");
12487   gbq->val = StringSave ("microsatellite");
12488   gbq->next = sfp->qual;
12489   sfp->qual = gbq;
12490 }
12491 
12492 
MakeCommonFeatureMicrosatellite(IteM i)12493 NLM_EXTERN void MakeCommonFeatureMicrosatellite (IteM i)
12494 {
12495   BaseFormPtr       bfp;
12496   SeqEntryPtr       sep;
12497 
12498 #ifdef WIN_MAC
12499   bfp = currentFormDataPtr;
12500 #else
12501   bfp = GetObjectExtra (i);
12502 #endif
12503   if (bfp == NULL || bfp->input_entityID == 0) return;
12504 
12505   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
12506   VisitBioseqsInSep (sep, NULL, MakeCommonFeatureMicrosatelliteCallback);
12507   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
12508   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
12509 }
12510 
12511 
MakeCommonFeatureControlRegionCallback(BioseqPtr bsp,Pointer data)12512 static void MakeCommonFeatureControlRegionCallback (BioseqPtr bsp, Pointer data)
12513 {
12514   SeqFeatPtr sfp;
12515   ImpFeatPtr ifp;
12516   SeqDescPtr sdp;
12517   SeqMgrDescContext context;
12518   MolInfoPtr mip;
12519   BioSourcePtr biop;
12520 
12521   if (bsp == NULL || ISA_aa (bsp->mol)) {
12522     return;
12523   }
12524 
12525   /* requests from JIRA:SQD-808 */
12526   bsp->mol = Seq_mol_dna;
12527   sdp = SeqMgrGetNextDescriptor(bsp, NULL, Seq_descr_molinfo, &context);
12528   if (sdp != NULL && (mip = (MolInfoPtr) sdp->data.ptrvalue) != NULL) {
12529     mip->biomol = MOLECULE_TYPE_GENOMIC;
12530     mip->completeness = 0;
12531   }
12532   sdp = SeqMgrGetNextDescriptor(bsp, NULL, Seq_descr_source, &context);
12533   if (sdp != NULL && (biop = (BioSourcePtr) sdp->data.ptrvalue) != NULL) {
12534     biop->genome = GENOME_mitochondrion;
12535   }
12536 
12537   sfp = CreateNewFeatureOnBioseq (bsp, SEQFEAT_IMP, NULL);
12538   ifp = ImpFeatNew ();
12539   ifp->key = StringSave ("misc_feature");
12540   sfp->data.value.ptrvalue = ifp;
12541   sfp->comment = StringSave ("control region");
12542   SetSeqLocPartial (sfp->location, TRUE, TRUE);
12543   sfp->partial = TRUE;
12544 }
12545 
12546 
MakeCommonFeatureControlRegion(IteM i)12547 NLM_EXTERN void MakeCommonFeatureControlRegion (IteM i)
12548 {
12549   BaseFormPtr       bfp;
12550   SeqEntryPtr       sep;
12551 
12552 #ifdef WIN_MAC
12553   bfp = currentFormDataPtr;
12554 #else
12555   bfp = GetObjectExtra (i);
12556 #endif
12557   if (bfp == NULL || bfp->input_entityID == 0) return;
12558 
12559   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
12560   VisitBioseqsInSep (sep, NULL, MakeCommonFeatureControlRegionCallback);
12561   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
12562   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
12563 }
12564 
12565 
RemoveNonNIslandsCallback(BioseqPtr bsp,Pointer data)12566 static void RemoveNonNIslandsCallback (BioseqPtr bsp, Pointer data)
12567 {
12568   CharPtr     bases, cp;
12569   Int4        pos = 0, island_start = 0, island_len = 0, i;
12570   SeqDataPtr  seq_data;
12571 
12572   if (bsp == NULL || ISA_aa (bsp->mol)) {
12573     return;
12574   }
12575 
12576   bases = GetSequenceByBsp (bsp);
12577   if (bases == NULL) return;
12578 
12579   for (cp = bases; *cp != 0; cp++) {
12580     if (*cp == 'N') {
12581       if (island_len < 3 && island_len > 0) {
12582         for (i = island_start; i < pos; i++) {
12583           *(bases + i) = 'N';
12584         }
12585       }
12586       island_len = 0;
12587     } else {
12588       if (island_len == 0) {
12589         island_start = pos;
12590       }
12591       island_len++;
12592     }
12593     pos++;
12594   }
12595   if (island_len < 3 && island_len > 0) {
12596     for (i = island_start; i < pos; i++) {
12597       *(bases + i) = 'N';
12598     }
12599   }
12600 
12601   seq_data = (SeqDataPtr) BSNew (bsp->length);
12602   AddBasesToByteStore ((ByteStorePtr) seq_data, bases);
12603   bsp->seq_data = SeqDataFree (bsp->seq_data, bsp->seq_data_type);
12604   bsp->seq_data_type = Seq_code_iupacna;
12605   bsp->seq_data = seq_data;
12606   bases = MemFree (bases);
12607   BioseqPack (bsp);
12608 }
12609 
RemoveNonNIslands(IteM i)12610 NLM_EXTERN void RemoveNonNIslands (IteM i)
12611 {
12612   BaseFormPtr       bfp;
12613   SeqEntryPtr       sep;
12614 
12615 #ifdef WIN_MAC
12616   bfp = currentFormDataPtr;
12617 #else
12618   bfp = GetObjectExtra (i);
12619 #endif
12620   if (bfp == NULL || bfp->input_entityID == 0) return;
12621 
12622   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
12623   VisitBioseqsInSep (sep, NULL, RemoveNonNIslandsCallback);
12624   DeleteMarkedObjects (bfp->input_entityID, 0, NULL);
12625   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
12626   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
12627 }
12628 
12629 
StrandOk(Uint1 strand1,Uint1 strand2)12630 static Boolean StrandOk (Uint1 strand1, Uint1 strand2)
12631 {
12632   if (strand1 == Seq_strand_minus && strand2 != Seq_strand_minus) {
12633     return FALSE;
12634   } else if (strand1 != Seq_strand_minus && strand2 == Seq_strand_minus) {
12635     return FALSE;
12636   } else {
12637     return TRUE;
12638   }
12639 }
12640 
12641 
RemoveUTRsFromCDSCallback(SeqFeatPtr sfp,Pointer data)12642 static void RemoveUTRsFromCDSCallback (SeqFeatPtr sfp, Pointer data)
12643 {
12644   BioseqPtr bsp;
12645   SeqFeatPtr utr;
12646   SeqMgrFeatContext fcontext;
12647   Int4              start, stop, right;
12648   Uint1             cds_strand;
12649   Boolean           changed, partial5, partial3, retranslate = FALSE;
12650   CdRegionPtr       crp;
12651 
12652   if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) {
12653     return;
12654   }
12655 
12656   bsp = BioseqFindFromSeqLoc (sfp->location);
12657   if (bsp == NULL) {
12658     return;
12659   }
12660 
12661   start = SeqLocStart (sfp->location);
12662   stop = SeqLocStop (sfp->location);
12663   if (start < stop) {
12664     right = stop;
12665   } else {
12666     right = start;
12667   }
12668   cds_strand = SeqLocStrand (sfp->location);
12669 
12670   for (utr = SeqMgrGetNextFeature (bsp, NULL, 0, FEATDEF_5UTR, &fcontext);
12671        utr != NULL;
12672        utr = SeqMgrGetNextFeature (bsp, NULL, 0, FEATDEF_5UTR, &fcontext)) {
12673     if (fcontext.left > right) {
12674       break;
12675     } else if (!StrandOk (cds_strand, SeqLocStrand (utr->location))) {
12676       continue;
12677     }
12678     if ((cds_strand == Seq_strand_minus && fcontext.right == start)
12679         || (cds_strand != Seq_strand_minus && fcontext.left == start)) {
12680       sfp->location = SeqLocDelete (sfp->location, SeqLocId (sfp->location), fcontext.left, fcontext.right, FALSE, &changed);
12681       crp = (CdRegionPtr) sfp->data.value.ptrvalue;
12682       if (crp != NULL) {
12683         crp->frame = 1;
12684       }
12685       CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
12686       SetSeqLocPartial (sfp->location, FALSE, partial3);
12687       retranslate = TRUE;
12688       break;
12689     }
12690   }
12691 
12692   for (utr = SeqMgrGetNextFeature (bsp, NULL, 0, FEATDEF_3UTR, &fcontext);
12693        utr != NULL;
12694        utr = SeqMgrGetNextFeature (bsp, NULL, 0, FEATDEF_3UTR, &fcontext)) {
12695     if (fcontext.left > right) {
12696       break;
12697     } else if (!StrandOk (cds_strand, SeqLocStrand (utr->location))) {
12698       continue;
12699     }
12700     if ((cds_strand == Seq_strand_minus && fcontext.left == stop)
12701         || (cds_strand != Seq_strand_minus && fcontext.right == stop)) {
12702       sfp->location = SeqLocDelete (sfp->location, SeqLocId (sfp->location), fcontext.left, fcontext.right, FALSE, &changed);
12703       CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
12704       SetSeqLocPartial (sfp->location, partial5, FALSE);
12705       retranslate = TRUE;
12706       break;
12707     }
12708   }
12709 
12710   if (retranslate) {
12711     RetranslateOneCDS (sfp, sfp->idx.entityID, FALSE, FALSE);
12712   }
12713 }
12714 
12715 
RemoveUTRsFromCDSs(IteM i)12716 NLM_EXTERN void RemoveUTRsFromCDSs (IteM i)
12717 {
12718   BaseFormPtr       bfp;
12719   SeqEntryPtr       sep;
12720 
12721 #ifdef WIN_MAC
12722   bfp = currentFormDataPtr;
12723 #else
12724   bfp = GetObjectExtra (i);
12725 #endif
12726   if (bfp == NULL || bfp->input_entityID == 0) return;
12727 
12728   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
12729   VisitFeaturesInSep (sep, NULL, RemoveUTRsFromCDSCallback);
12730   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
12731   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
12732 }
12733 
12734 
12735 typedef enum {
12736   eFeatureBetweenPolicy_NoFeatPartial = 1,
12737   eFeatureBetweenPolicy_NoFeatNoFeat,
12738   eFeatureBetweenPolicy_ExtendComplete,
12739   eFeatureBetweenPolicy_ExtendPartial
12740 } EFeatureBetweenPolicy;
12741 
12742 typedef struct featurebetweenendpolicy {
12743   Uint1 policy;
12744   ValNodePtr feat_type;
12745   ConstraintChoiceSetPtr constraint;
12746 } FeatureBetweenEndPolicyData, PNTR FeatureBetweenEndPolicyPtr;
12747 
12748 
FeatureBetweenEndPolicyNew(void)12749 static FeatureBetweenEndPolicyPtr FeatureBetweenEndPolicyNew (void)
12750 {
12751   FeatureBetweenEndPolicyPtr pol;
12752 
12753   pol = (FeatureBetweenEndPolicyPtr) MemNew (sizeof (FeatureBetweenEndPolicyData));
12754   pol->policy = eFeatureBetweenPolicy_ExtendPartial;
12755   return pol;
12756 }
12757 
12758 
FeatureBetweenEndPolicyFree(FeatureBetweenEndPolicyPtr pol)12759 static FeatureBetweenEndPolicyPtr FeatureBetweenEndPolicyFree (FeatureBetweenEndPolicyPtr pol)
12760 {
12761   if (pol != NULL) {
12762     pol->feat_type = ValNodeFree (pol->feat_type);
12763     pol = MemFree (pol);
12764   }
12765   return pol;
12766 }
12767 
12768 
12769 typedef struct addfeaturebetween {
12770   FeatureBetweenEndPolicyPtr left_policy;
12771   ValNodePtr feat_type_add;
12772   ApplyFeatureDetailsPtr details;
12773   FeatureBetweenEndPolicyPtr right_policy;
12774 } AddFeatureBetweenData, PNTR AddFeatureBetweenPtr;
12775 
AddFeatureBetweenNew(void)12776 static AddFeatureBetweenPtr AddFeatureBetweenNew (void)
12777 {
12778   AddFeatureBetweenPtr add;
12779 
12780   add = (AddFeatureBetweenPtr) MemNew (sizeof (AddFeatureBetweenData));
12781   return add;
12782 }
12783 
12784 
AddFeatureBetweenFree(AddFeatureBetweenPtr add)12785 static AddFeatureBetweenPtr AddFeatureBetweenFree (AddFeatureBetweenPtr add)
12786 {
12787   if (add != NULL) {
12788     add->left_policy = FeatureBetweenEndPolicyFree (add->left_policy);
12789     add->feat_type_add = ValNodeFree (add->feat_type_add);
12790     add->details = ApplyFeatureDetailsFree (add->details);
12791     add->right_policy = FeatureBetweenEndPolicyFree (add->right_policy);
12792     add = MemFree (add);
12793   }
12794   return add;
12795 }
12796 
12797 
12798 static void
AddOneFeatureBetween(BioseqPtr bsp,Int4 feat_left,Boolean partial_left,Int4 feat_right,Boolean partial_right,Uint1 strand,Uint1 featdef,ApplyFeatureDetailsPtr details)12799 AddOneFeatureBetween
12800 (BioseqPtr bsp,
12801  Int4 feat_left,
12802  Boolean partial_left,
12803  Int4 feat_right,
12804  Boolean partial_right,
12805  Uint1   strand,
12806  Uint1   featdef,
12807  ApplyFeatureDetailsPtr details)
12808 {
12809   Int4       seqfeattype;
12810   SeqLocPtr  slp;
12811   SeqPntPtr  spp;
12812 
12813   seqfeattype = FindFeatFromFeatDefType (featdef);
12814 
12815   if (feat_left >= feat_right) {
12816     slp = SeqLocPntNew (feat_right, strand, SeqIdFindWorst (bsp->id), FALSE);
12817     if (feat_right < feat_left) {
12818       spp = (SeqPntPtr) slp->data.ptrvalue;
12819       spp->fuzz = IntFuzzNew();
12820       spp->fuzz->choice = 4; /*lim */
12821       spp->fuzz->a = 3; /*tr */
12822     }
12823   } else {
12824     slp = SeqLocIntNew (feat_left, feat_right, strand, SeqIdFindWorst (bsp->id));
12825     SetSeqLocPartial (slp, partial_left, partial_right);
12826   }
12827 
12828   ApplyOneFeatureToBioseq (bsp, featdef, slp, details == NULL ? NULL : details->fields,
12829                            details == NULL ? NULL : details->src_fields, details == NULL ? FALSE : details->add_mrna);
12830 }
12831 
12832 
AddFeaturesBetweenCallback(BioseqPtr bsp,Pointer data)12833 static void AddFeaturesBetweenCallback (BioseqPtr bsp, Pointer data)
12834 {
12835   AddFeatureBetweenPtr add;
12836   SeqFeatPtr           feat_before, feat_after;
12837   SeqMgrFeatContext    context_before, context_after;
12838   Boolean              found = FALSE, partial_left = TRUE, partial_right = TRUE;
12839   Uint1                featdef_before = FEATDEF_BAD, featdef_after = FEATDEF_BAD, featdef_new;
12840   Int4                 seqfeattype;
12841   Int4                 feat_left, feat_right;
12842 
12843   if (bsp == NULL || (add = (AddFeatureBetweenPtr) data) == NULL || add->left_policy == NULL || add->right_policy == NULL) {
12844     return;
12845   }
12846   if (add->feat_type_add == NULL) {
12847     return;
12848   }
12849 
12850   featdef_new = GetFeatdefFromFeatureType (add->feat_type_add->choice);
12851   seqfeattype = FindFeatFromFeatDefType (featdef_new);
12852   if (seqfeattype == SEQFEAT_PROT) {
12853     if (!ISA_aa (bsp->mol)) {
12854       return;
12855     }
12856   } else {
12857     if (ISA_aa (bsp->mol)) {
12858       return;
12859     }
12860   }
12861 
12862   if ((add->left_policy->policy == eFeatureBetweenPolicy_NoFeatPartial
12863           || add->left_policy->policy == eFeatureBetweenPolicy_NoFeatNoFeat)
12864       && add->left_policy->feat_type != NULL) {
12865     featdef_before = GetFeatdefFromFeatureType (add->left_policy->feat_type->choice);
12866   }
12867   if ((add->right_policy->policy == eFeatureBetweenPolicy_NoFeatPartial
12868           || add->right_policy->policy == eFeatureBetweenPolicy_NoFeatNoFeat)
12869       && add->right_policy->feat_type != NULL) {
12870     featdef_after = GetFeatdefFromFeatureType (add->right_policy->feat_type->choice);
12871   }
12872 
12873   if (featdef_before != FEATDEF_BAD) {
12874     for (feat_before = SeqMgrGetNextFeature (bsp, NULL, 0, featdef_before, &context_before);
12875          feat_before != NULL;
12876          feat_before = SeqMgrGetNextFeature (bsp, feat_before, 0, featdef_before, &context_before)) {
12877       if (DoesObjectMatchConstraintChoiceSet (OBJ_SEQFEAT, feat_before, add->left_policy->constraint)) {
12878         /* add feature starting at context_before.right + 1, ending with first feature matching right constraint */
12879         feat_left = context_before.right + 1;
12880         partial_left = FALSE;
12881         feat_right = bsp->length - 1;
12882         if (featdef_after != FEATDEF_BAD) {
12883           for (feat_after = SeqMgrGetNextFeature (bsp, NULL, 0, featdef_after, &context_after);
12884                feat_after != NULL && feat_right == bsp->length - 1;
12885                feat_after = SeqMgrGetNextFeature (bsp, feat_after, 0, featdef_after, &context_after)) {
12886             if (context_after.left >= feat_left && DoesObjectMatchConstraintChoiceSet (OBJ_SEQFEAT, feat_after, add->right_policy->constraint)) {
12887               feat_right = context_after.left - 1;
12888               partial_right = FALSE;
12889             }
12890           }
12891         }
12892         if (feat_right > -1
12893             && feat_right >= feat_left - 1
12894             && (feat_right < bsp->length - 1
12895                 || add->right_policy->policy != eFeatureBetweenPolicy_NoFeatNoFeat)) {
12896           if (add->right_policy->policy == eFeatureBetweenPolicy_ExtendComplete) {
12897             partial_right = FALSE;
12898           }
12899           AddOneFeatureBetween (bsp, feat_left, partial_left, feat_right, partial_right, context_before.strand, featdef_new, add->details);
12900         }
12901         found = TRUE;
12902       }
12903     }
12904     if (!found && add->left_policy->policy == eFeatureBetweenPolicy_NoFeatPartial) {
12905       /* add feature starting at 0 and partial on this end, ending with first feature matching right constraint */
12906       feat_left = 0;
12907       feat_right = bsp->length - 1;
12908       if (featdef_after != FEATDEF_BAD) {
12909         for (feat_after = SeqMgrGetNextFeature (bsp, NULL, 0, featdef_after, &context_after);
12910               feat_after != NULL && feat_right == bsp->length - 1;
12911               feat_after = SeqMgrGetNextFeature (bsp, feat_after, 0, featdef_after, &context_after)) {
12912           if (context_after.left > feat_left && DoesObjectMatchConstraintChoiceSet (OBJ_SEQFEAT, feat_after, add->right_policy->constraint)) {
12913             feat_right = context_after.left - 1;
12914             partial_right = FALSE;
12915             AddOneFeatureBetween (bsp, feat_left, partial_left, feat_right, partial_right, context_after.strand, featdef_new, add->details);
12916             found = TRUE;
12917           }
12918         }
12919       }
12920       if (!found && add->right_policy->policy != eFeatureBetweenPolicy_NoFeatNoFeat) {
12921         if (add->right_policy->policy == eFeatureBetweenPolicy_ExtendComplete) {
12922           partial_right = FALSE;
12923         }
12924         if (feat_right > feat_left && feat_right > -1) {
12925           AddOneFeatureBetween (bsp, feat_left, partial_left, feat_right, partial_right, Seq_strand_plus, featdef_new, add->details);
12926         }
12927       }
12928     }
12929   } else if (featdef_after != FEATDEF_BAD) {
12930     feat_left = 0;
12931     if (add->left_policy->policy == eFeatureBetweenPolicy_ExtendComplete) {
12932       partial_left = FALSE;
12933     }
12934     for (feat_after = SeqMgrGetNextFeature (bsp, NULL, 0, featdef_after, &context_after);
12935          feat_after != NULL && !found;
12936          feat_after = SeqMgrGetNextFeature (bsp, feat_after, 0, featdef_after, &context_after)) {
12937       if (DoesObjectMatchConstraintChoiceSet (OBJ_SEQFEAT, feat_after, add->right_policy->constraint)) {
12938         /* add feature starting at 0 and partial on this end, ending with context_after.left - 1 */
12939         partial_right = FALSE;
12940         feat_right = context_after.left - 1;
12941         if (feat_right > feat_left && feat_right > -1) {
12942           AddOneFeatureBetween (bsp, feat_left, partial_left, feat_right, partial_right, context_after.strand, featdef_new, add->details);
12943         }
12944         found = TRUE;
12945       }
12946     }
12947     if (!found && add->right_policy->policy != eFeatureBetweenPolicy_NoFeatNoFeat) {
12948       AddOneFeatureBetween (bsp, feat_left, partial_left, bsp->length - 1, partial_right, Seq_strand_plus, featdef_new, add->details);
12949     }
12950   } else {
12951     feat_left = 0;
12952     feat_right = bsp->length - 1;
12953     if (add->left_policy->policy == eFeatureBetweenPolicy_ExtendComplete) {
12954       partial_left = FALSE;
12955     }
12956     if (add->right_policy->policy == eFeatureBetweenPolicy_ExtendComplete) {
12957       partial_right = FALSE;
12958     }
12959     if (feat_right > feat_left && feat_right > -1) {
12960       AddOneFeatureBetween (bsp, feat_left, partial_left, feat_right, partial_right, Seq_strand_plus, featdef_new, add->details);
12961     }
12962   }
12963 }
12964 
12965 typedef struct featurebetweenendpolicydlg {
12966   DIALOG_MESSAGE_BLOCK
12967 
12968   GrouP          missing_feat_policy;
12969   DialoG         feat_type_dlg;
12970   DialoG         constraint_dlg;
12971 
12972   Nlm_ChangeNotifyProc     change_notify;
12973   Pointer                  change_userdata;
12974 } FeatureBetweenEndPolicyDlgData, PNTR FeatureBetweenEndPolicyDlgPtr;
12975 
12976 
EnableDialogFeatureBetweenEndPolicy(FeatureBetweenEndPolicyDlgPtr dlg)12977 static void EnableDialogFeatureBetweenEndPolicy (FeatureBetweenEndPolicyDlgPtr dlg)
12978 {
12979   Int4 val;
12980 
12981   if (dlg != NULL) {
12982     val = GetValue (dlg->missing_feat_policy);
12983     if (val == eFeatureBetweenPolicy_NoFeatPartial || val == eFeatureBetweenPolicy_NoFeatNoFeat) {
12984       Enable (dlg->feat_type_dlg);
12985       Enable (dlg->constraint_dlg);
12986     } else {
12987       Disable (dlg->feat_type_dlg);
12988       Disable (dlg->constraint_dlg);
12989     }
12990   }
12991 }
12992 
12993 
FeatureBetweenEndPolicyToDialog(DialoG d,Pointer data)12994 static void FeatureBetweenEndPolicyToDialog (DialoG d, Pointer data)
12995 {
12996   FeatureBetweenEndPolicyDlgPtr dlg;
12997   FeatureBetweenEndPolicyPtr    pol;
12998   ValNode                       vn;
12999 
13000   dlg = (FeatureBetweenEndPolicyDlgPtr) GetObjectExtra (d);
13001   if (dlg == NULL) {
13002     return;
13003   }
13004   pol = (FeatureBetweenEndPolicyPtr) data;
13005   if (data == NULL) {
13006     SetValue (dlg->missing_feat_policy, eFeatureBetweenPolicy_NoFeatPartial);
13007     MemSet (&vn, 0, sizeof (ValNode));
13008     vn.choice = Macro_feature_type_cds;
13009     PointerToDialog (dlg->feat_type_dlg, &vn);
13010     PointerToDialog (dlg->constraint_dlg, NULL);
13011   } else {
13012     SetValue (dlg->missing_feat_policy, pol->policy);
13013     PointerToDialog (dlg->feat_type_dlg, pol->feat_type);
13014     PointerToDialog (dlg->constraint_dlg, pol->constraint);
13015   }
13016   EnableDialogFeatureBetweenEndPolicy (dlg);
13017 }
13018 
13019 
DialogToFeatureBetweenEndPolicy(DialoG d)13020 static Pointer DialogToFeatureBetweenEndPolicy (DialoG d)
13021 {
13022   FeatureBetweenEndPolicyDlgPtr dlg;
13023   FeatureBetweenEndPolicyPtr    pol;
13024 
13025   dlg = (FeatureBetweenEndPolicyDlgPtr) GetObjectExtra (d);
13026   if (dlg == NULL) {
13027     return NULL;
13028   }
13029 
13030   pol = FeatureBetweenEndPolicyNew();
13031   pol->policy = GetValue (dlg->missing_feat_policy);
13032   pol->feat_type = DialogToPointer (dlg->feat_type_dlg);
13033   pol->constraint = DialogToPointer (dlg->constraint_dlg);
13034 
13035   return pol;
13036 }
13037 
13038 
ChangeFeatureBetweenPolicy(GrouP g)13039 static void ChangeFeatureBetweenPolicy (GrouP g)
13040 {
13041   EnableDialogFeatureBetweenEndPolicy (GetObjectExtra (g));
13042 }
13043 
13044 
FeatureBetweenEndPolicyDialog(GrouP h,CharPtr label,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)13045 static DialoG FeatureBetweenEndPolicyDialog (GrouP h, CharPtr label, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
13046 {
13047   FeatureBetweenEndPolicyDlgPtr dlg;
13048   GrouP                    p;
13049   PrompT                   ppt;
13050 
13051   dlg = (FeatureBetweenEndPolicyDlgPtr) MemNew (sizeof (FeatureBetweenEndPolicyDlgData));
13052   p = HiddenGroup (h, -1, 0, NULL);
13053   SetGroupSpacing (p, 10, 10);
13054   SetObjectExtra (p, dlg, StdCleanupExtraProc);
13055 
13056   dlg->dialog = (DialoG) p;
13057   dlg->todialog = FeatureBetweenEndPolicyToDialog;
13058   dlg->fromdialog = DialogToFeatureBetweenEndPolicy;
13059   dlg->dialogmessage = NULL;
13060   dlg->change_notify = change_notify;
13061   dlg->change_userdata = change_userdata;
13062 
13063   ppt = StaticPrompt (p, label, 0, popupMenuHeight, programFont, 'l');
13064   dlg->missing_feat_policy = HiddenGroup (p, 0, 4, ChangeFeatureBetweenPolicy);
13065   SetObjectExtra (dlg->missing_feat_policy, dlg, NULL);
13066   RadioButton (dlg->missing_feat_policy, "If selected feature missing, extend to partial end");
13067   RadioButton (dlg->missing_feat_policy, "If selected feature missing, do not create feature");
13068   RadioButton (dlg->missing_feat_policy, "Extend to complete end");
13069   RadioButton (dlg->missing_feat_policy, "Extend to partial end");
13070 
13071   dlg->feat_type_dlg = FeatureTypeDialog (p, NULL, NULL);
13072   dlg->constraint_dlg = ConstraintSetDialog (p, NULL, NULL);
13073   AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) dlg->missing_feat_policy,
13074                               (HANDLE) dlg->feat_type_dlg, (HANDLE) dlg->constraint_dlg, NULL);
13075 
13076   return (DialoG) p;
13077 }
13078 
13079 
13080 typedef struct addfeaturebetweendlg {
13081   DIALOG_MESSAGE_BLOCK
13082 
13083   DialoG         left_policy_dlg;
13084 
13085   DialoG         feat_type_add_dlg;
13086   DialoG         details_dlg;
13087 
13088   DialoG         right_policy_dlg;
13089 
13090   Nlm_ChangeNotifyProc     change_notify;
13091   Pointer                  change_userdata;
13092 } AddFeatureBetweenDlgData, PNTR AddFeatureBetweenDlgPtr;
13093 
13094 
DialogToAddFeatureBetween(DialoG d)13095 static Pointer DialogToAddFeatureBetween (DialoG d)
13096 {
13097   AddFeatureBetweenDlgPtr dlg;
13098   AddFeatureBetweenPtr add;
13099 
13100   dlg = (AddFeatureBetweenDlgPtr) GetObjectExtra (d);
13101   if (dlg == NULL) {
13102     return NULL;
13103   }
13104   add = AddFeatureBetweenNew ();
13105   add->left_policy = DialogToPointer (dlg->left_policy_dlg);
13106   add->feat_type_add = DialogToPointer (dlg->feat_type_add_dlg);
13107   add->details = DialogToPointer (dlg->details_dlg);
13108   add->right_policy = DialogToPointer (dlg->right_policy_dlg);
13109 
13110   return add;
13111 }
13112 
13113 
AddFeatureBetweenToDialog(DialoG d,Pointer data)13114 static void AddFeatureBetweenToDialog (DialoG d, Pointer data)
13115 {
13116   AddFeatureBetweenDlgPtr dlg;
13117   AddFeatureBetweenPtr add;
13118   ValNode              vn;
13119 
13120   dlg = (AddFeatureBetweenDlgPtr) GetObjectExtra (d);
13121   if (dlg == NULL) {
13122     return;
13123   }
13124 
13125   add = (AddFeatureBetweenPtr) data;
13126   if (add == NULL) {
13127     PointerToDialog (dlg->left_policy_dlg, NULL);
13128     MemSet (&vn, 0, sizeof (ValNode));
13129     vn.choice = Macro_feature_type_misc_feature;
13130     PointerToDialog (dlg->feat_type_add_dlg, &vn);
13131     PointerToDialog (dlg->details_dlg, NULL);
13132     PointerToDialog (dlg->right_policy_dlg, NULL);
13133   } else {
13134     PointerToDialog (dlg->left_policy_dlg, add->left_policy);
13135     PointerToDialog (dlg->feat_type_add_dlg, add->feat_type_add);
13136     PointerToDialog (dlg->details_dlg, add->details);
13137     PointerToDialog (dlg->right_policy_dlg, add->right_policy);
13138   }
13139 
13140 }
13141 
13142 
AddFeatureBetweenDialog(GrouP h,Uint1 add_type,ApplyFeatureDetailsPtr details,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)13143 static DialoG AddFeatureBetweenDialog (GrouP h, Uint1 add_type, ApplyFeatureDetailsPtr details, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
13144 {
13145   AddFeatureBetweenDlgPtr dlg;
13146   GrouP                    p, k2;
13147   PrompT                   ppt;
13148 
13149   dlg = (AddFeatureBetweenDlgPtr) MemNew (sizeof (AddFeatureBetweenDlgData));
13150   p = HiddenGroup (h, 3, 0, NULL);
13151   SetGroupSpacing (p, 10, 10);
13152   SetObjectExtra (p, dlg, StdCleanupExtraProc);
13153 
13154   dlg->dialog = (DialoG) p;
13155   dlg->todialog = AddFeatureBetweenToDialog;
13156   dlg->fromdialog = DialogToAddFeatureBetween;
13157   dlg->dialogmessage = NULL;
13158   dlg->change_notify = change_notify;
13159   dlg->change_userdata = change_userdata;
13160 
13161   dlg->left_policy_dlg = FeatureBetweenEndPolicyDialog (p, "Left Feature", NULL, NULL);
13162 
13163   k2 = HiddenGroup (p, -1, 0, NULL);
13164   ppt = StaticPrompt (k2, "Feature to Add", 0, popupMenuHeight, programFont, 'l');
13165   dlg->feat_type_add_dlg = FeatureTypeDialog (k2, change_notify, change_userdata);
13166   dlg->details_dlg = ApplyFeatureDetailsDialog (k2, add_type, details, TRUE, NULL, NULL);
13167   AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) dlg->feat_type_add_dlg, (HANDLE) dlg->details_dlg, NULL);
13168 
13169   dlg->right_policy_dlg = FeatureBetweenEndPolicyDialog (p, "Right Feature", NULL, NULL);
13170 
13171   return (DialoG) p;
13172 }
13173 
13174 
13175 typedef struct addfeaturebetweenform {
13176   FORM_MESSAGE_BLOCK
13177 
13178   DialoG add_between_dlg;
13179   ButtoN leave_dlg_up;
13180 
13181   Boolean changing;
13182 } AddFeatureBetweenFormData, PNTR AddFeatureBetweenFormPtr;
13183 
13184 
13185 static void ChangeAddFeatureFunc (Pointer data);
13186 
DoAddFeatureBetween(ButtoN b)13187 static void DoAddFeatureBetween (ButtoN b)
13188 {
13189   AddFeatureBetweenFormPtr dlg;
13190   AddFeatureBetweenPtr     add;
13191   SeqEntryPtr              sep;
13192 
13193   dlg = (AddFeatureBetweenFormPtr) GetObjectExtra (b);
13194   if (dlg == NULL) {
13195     return;
13196   }
13197 
13198   WatchCursor();
13199   Update();
13200   add = DialogToPointer (dlg->add_between_dlg);
13201   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
13202 
13203   VisitBioseqsInSep (sep, add, AddFeaturesBetweenCallback);
13204 
13205   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
13206   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
13207 
13208   if (!GetStatus (dlg->leave_dlg_up)) {
13209     Remove (dlg->form);
13210   }
13211   ArrowCursor();
13212   Update();
13213 }
13214 
13215 
AddFeatureBetweenForm(Uint2 entityID,AddFeatureBetweenPtr add)13216 static WindoW AddFeatureBetweenForm (Uint2 entityID, AddFeatureBetweenPtr add)
13217 {
13218   WindoW            w;
13219   GrouP             h, c;
13220   ButtoN            b;
13221   AddFeatureBetweenFormPtr dlg;
13222 
13223   dlg = (AddFeatureBetweenFormPtr) MemNew (sizeof (AddFeatureBetweenFormData));
13224   if (dlg == NULL) return NULL;
13225 
13226   w = FixedWindow (-50, -33, -10, -10, "Add Feature Between", StdCloseWindowProc);
13227   SetObjectExtra (w, dlg, StdCleanupFormProc);
13228   dlg->form = (ForM) w;
13229   dlg->input_entityID = entityID;
13230   h = HiddenGroup (w, -1, 0, NULL);
13231   SetGroupSpacing (h, 10, 10);
13232 
13233   dlg->changing = TRUE;
13234   dlg->add_between_dlg = AddFeatureBetweenDialog (h, (add == NULL || add->feat_type_add == NULL) ? FEATDEF_misc_feature : GetFeatdefFromFeatureType (add->feat_type_add->choice),
13235                                                   add == NULL ? NULL : add->details,
13236                                                   ChangeAddFeatureFunc, dlg);
13237   PointerToDialog (dlg->add_between_dlg, add);
13238   dlg->changing = FALSE;
13239 
13240   c = HiddenGroup (h, 4, 0, NULL);
13241   b = DefaultButton (c, "Accept", DoAddFeatureBetween);
13242   SetObjectExtra (b, dlg, NULL);
13243   PushButton (c, "Cancel", StdCancelButtonProc);
13244   dlg->leave_dlg_up = CheckBox (c, "Leave dialog up", NULL);
13245 
13246   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->add_between_dlg, (HANDLE) c, NULL);
13247 
13248   return w;
13249 }
13250 
13251 
ChangeAddFeatureFunc(Pointer data)13252 static void ChangeAddFeatureFunc (Pointer data)
13253 {
13254   AddFeatureBetweenFormPtr dlg;
13255   AddFeatureBetweenPtr add;
13256   WindoW               w;
13257 
13258   dlg = (AddFeatureBetweenFormPtr) data;
13259   if (dlg == NULL || dlg->changing) {
13260     return;
13261   }
13262 
13263   add = DialogToPointer (dlg->add_between_dlg);
13264   Hide (dlg->form);
13265   /* build new form */
13266   w = AddFeatureBetweenForm (dlg->input_entityID, add);
13267   RealizeWindow (w);
13268   Show (w);
13269   Update ();
13270 
13271   /* remove old form */
13272   dlg->changing = TRUE;
13273   Remove (dlg->form);
13274 
13275   add = AddFeatureBetweenFree (add);
13276 
13277 }
13278 
13279 
AddFeatureBetween(IteM i)13280 NLM_EXTERN void AddFeatureBetween (IteM i)
13281 {
13282   BaseFormPtr       bfp;
13283   WindoW            w;
13284   AddFeatureBetweenFormPtr dlg;
13285 
13286 #ifdef WIN_MAC
13287   bfp = currentFormDataPtr;
13288 #else
13289   bfp = GetObjectExtra (i);
13290 #endif
13291   if (bfp == NULL || bfp->input_entityID == 0) return;
13292 
13293   dlg = (AddFeatureBetweenFormPtr) MemNew (sizeof (AddFeatureBetweenFormData));
13294   if (dlg == NULL) return;
13295 
13296   w = AddFeatureBetweenForm (bfp->input_entityID, NULL);
13297 
13298   RealizeWindow (w);
13299   Show (w);
13300   Update ();
13301 }
13302 
13303 
13304 typedef struct changequalcaseform {
13305   FORM_MESSAGE_BLOCK
13306 
13307   DialoG qual_dlg;
13308   DialoG cap_dlg;
13309   ButtoN leave_dlg_up;
13310 
13311 } ChangeQualCaseFormData, PNTR ChangeQualCaseFormPtr;
13312 
13313 
13314 typedef struct changecase {
13315   ValNodePtr dst_field;
13316   Int4       change_cap;
13317   ValNodePtr orgnames;
13318 } ChangeCaseData, PNTR ChangeCasePtr;
13319 
ChangeQualCaseCallbackDesc(SeqDescrPtr sdp,Pointer data)13320 static void ChangeQualCaseCallbackDesc (SeqDescrPtr sdp, Pointer data)
13321 {
13322   ChangeCasePtr ccp;
13323   ParseDstOrgPtr o;
13324   CharPtr        str;
13325 
13326   ccp = (ChangeCasePtr) data;
13327   if (sdp == NULL || ccp == NULL || ccp->dst_field == NULL || ccp->change_cap < 1) {
13328     return;
13329   }
13330 
13331   switch (ccp->dst_field->choice) {
13332     case ParseDest_defline:
13333       if (sdp->choice == Seq_descr_title) {
13334         FixCapitalizationInString ((CharPtr PNTR)&(sdp->data.ptrvalue), ccp->change_cap, ccp->orgnames);
13335       }
13336       break;
13337     case ParseDest_org:
13338       if ((o = (ParseDstOrgPtr) ccp->dst_field->data.ptrvalue) != NULL
13339           && o->type != Object_type_constraint_feature
13340           && sdp->choice == Seq_descr_source) {
13341         str = GetSourceQualFromBioSource (sdp->data.ptrvalue, o->field, NULL);
13342         FixCapitalizationInString(&str, ccp->change_cap, NULL);
13343         SetSourceQualInBioSource(sdp->data.ptrvalue, o->field, NULL, str, ExistingTextOption_replace_old);
13344         str = MemFree (str);
13345       }
13346       break;
13347     case ParseDest_comment_descriptor:
13348       if (sdp->choice == Seq_descr_comment) {
13349         FixCapitalizationInString ((CharPtr PNTR)&(sdp->data.ptrvalue), ccp->change_cap, ccp->orgnames);
13350       }
13351       break;
13352     case ParseDest_dbxref:
13353       if (sdp->choice == Seq_descr_source) {
13354         str = GetDBxrefFromBioSource (sdp->data.ptrvalue, ccp->dst_field->data.ptrvalue);
13355         if (str != NULL) {
13356           FixCapitalizationInString(&str, ccp->change_cap, ccp->orgnames);
13357           SetDBxrefForBioSource (sdp->data.ptrvalue, ccp->dst_field->data.ptrvalue, str, ExistingTextOption_replace_old);
13358           str = MemFree (str);
13359         }
13360       }
13361       break;
13362   }
13363 }
13364 
13365 
ChangeQualCaseCallbackFeat(SeqFeatPtr sfp,Pointer data)13366 static void ChangeQualCaseCallbackFeat (SeqFeatPtr sfp, Pointer data)
13367 {
13368   ChangeCasePtr ccp;
13369   ParseDstOrgPtr o;
13370   CharPtr        str;
13371   FeatureFieldLegalPtr fl;
13372   FeatureField f;
13373 
13374   ccp = (ChangeCasePtr) data;
13375   if (sfp == NULL || ccp == NULL || ccp->dst_field == NULL || ccp->change_cap < 1) {
13376     return;
13377   }
13378 
13379   switch (ccp->dst_field->choice) {
13380     case ParseDest_org:
13381       if ((o = (ParseDstOrgPtr) ccp->dst_field->data.ptrvalue) != NULL
13382           && o->type != Object_type_constraint_descriptor
13383           && sfp->data.choice == SEQFEAT_BIOSRC) {
13384         str = GetSourceQualFromBioSource (sfp->data.value.ptrvalue, o->field, NULL);
13385         FixCapitalizationInString(&str, ccp->change_cap, NULL);
13386         SetSourceQualInBioSource(sfp->data.value.ptrvalue, o->field, NULL, str, ExistingTextOption_replace_old);
13387         str = MemFree (str);
13388       }
13389       break;
13390     case ParseDest_featqual:
13391       fl = (FeatureFieldLegalPtr) ccp->dst_field->data.ptrvalue;
13392       if (fl != NULL) {
13393         f.type = fl->type;
13394         f.field = ValNodeNew(NULL);
13395         f.field->next = NULL;
13396         f.field->choice = FeatQualChoice_legal_qual;
13397         f.field->data.intvalue = fl->field;
13398         str = GetQualFromFeature (sfp, &f, NULL);
13399         if (str != NULL) {
13400           FixCapitalizationInString(&str, ccp->change_cap, ccp->orgnames);
13401           SetQualOnFeature (sfp, &f, NULL, str, ExistingTextOption_replace_old);
13402           f.field = ValNodeFree (f.field);
13403           str = MemFree (str);
13404         }
13405       }
13406       break;
13407     case ParseDest_dbxref:
13408       if (sfp->data.choice == SEQFEAT_BIOSRC) {
13409         str = GetDBxrefFromBioSource (sfp->data.value.ptrvalue, ccp->dst_field->data.ptrvalue);
13410         if (str != NULL) {
13411           FixCapitalizationInString(&str, ccp->change_cap, ccp->orgnames);
13412           SetDBxrefForBioSource (sfp->data.value.ptrvalue, ccp->dst_field->data.ptrvalue, str, ExistingTextOption_replace_old);
13413           str = MemFree (str);
13414         }
13415       }
13416       break;
13417   }
13418 }
13419 
13420 
DoChangeQualCase(ButtoN b)13421 static void DoChangeQualCase(ButtoN b)
13422 {
13423   ChangeQualCaseFormPtr dlg;
13424   ChangeCaseData        ccd;
13425   SeqEntryPtr           sep;
13426   ParseDstOrgPtr        o;
13427 
13428   dlg = (ChangeQualCaseFormPtr) GetObjectExtra (b);
13429   if (dlg == NULL) {
13430     return;
13431   }
13432 
13433   ccd.dst_field = DialogToPointer (dlg->qual_dlg);
13434   if (ccd.dst_field == NULL) {
13435     return;
13436   }
13437 
13438   ccd.change_cap = GetCapChangeDialogValue (dlg->cap_dlg);
13439 
13440   ccd.orgnames = NULL;
13441   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
13442   VisitBioSourcesInSep (sep, &ccd.orgnames, GetOrgNamesInRecordCallback);
13443 
13444 
13445   switch (ccd.dst_field->choice) {
13446     case ParseDest_defline :
13447       VisitDescriptorsInSep (sep, &ccd, ChangeQualCaseCallbackDesc);
13448       break;
13449     case ParseDest_org :
13450       o = (ParseDstOrgPtr) ccd.dst_field->data.ptrvalue;
13451       if (o->type == Object_type_constraint_any || o->type == Object_type_constraint_descriptor) {
13452         VisitDescriptorsInSep (sep, &ccd, ChangeQualCaseCallbackDesc);
13453       }
13454       if (o->type == Object_type_constraint_any || o->type == Object_type_constraint_feature) {
13455         VisitFeaturesInSep (sep, &ccd, ChangeQualCaseCallbackFeat);
13456       }
13457       break;
13458     case ParseDest_featqual :
13459       VisitFeaturesInSep (sep, &ccd, ChangeQualCaseCallbackFeat);
13460       break;
13461     case ParseDest_comment_descriptor :
13462       VisitDescriptorsInSep (sep, &ccd, ChangeQualCaseCallbackDesc);
13463       break;
13464     case ParseDest_dbxref :
13465       VisitDescriptorsInSep (sep, &ccd, ChangeQualCaseCallbackDesc);
13466       VisitFeaturesInSep (sep, &ccd, ChangeQualCaseCallbackFeat);
13467       break;
13468   }
13469 
13470   ccd.orgnames = ValNodeFree (ccd.orgnames);
13471   ccd.dst_field = ParseDestFree (ccd.dst_field);
13472 
13473   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
13474   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
13475 
13476   if (!GetStatus (dlg->leave_dlg_up)) {
13477     Remove (dlg->form);
13478   }
13479   ArrowCursor();
13480   Update();
13481 }
13482 
13483 
ChangeQualifierCaseBaseForm(BaseFormPtr bfp)13484 NLM_EXTERN void ChangeQualifierCaseBaseForm (BaseFormPtr bfp)
13485 {
13486   WindoW            w;
13487   GrouP             h, c;
13488   ButtoN            b;
13489   ChangeQualCaseFormPtr dlg;
13490   ValNode           vn;
13491 
13492   if (bfp == NULL || bfp->input_entityID == 0) return;
13493 
13494   dlg = (ChangeQualCaseFormPtr) MemNew (sizeof (ChangeQualCaseFormData));
13495   if (dlg == NULL) return;
13496 
13497   w = FixedWindow (-50, -33, -10, -10, "Lowercase Qualifiers", StdCloseWindowProc);
13498   SetObjectExtra (w, dlg, StdCleanupFormProc);
13499   dlg->form = (ForM) w;
13500   dlg->input_entityID = bfp->input_entityID;
13501   h = HiddenGroup (w, -1, 0, NULL);
13502   SetGroupSpacing (h, 10, 10);
13503 
13504   dlg->qual_dlg = ParseDstDialog (h, NULL, NULL);
13505   MemSet (&vn, 0, sizeof (ValNode));
13506   vn.choice = ParseDest_org;
13507   PointerToDialog (dlg->qual_dlg, &vn);
13508   dlg->cap_dlg = CapChangeDialogEx (h, NULL, NULL, FALSE);
13509   SetCapChangeDialogValue (dlg->cap_dlg, Cap_change_tolower);
13510 
13511   c = HiddenGroup (h, 4, 0, NULL);
13512   b = DefaultButton (c, "Accept", DoChangeQualCase);
13513   SetObjectExtra (b, dlg, NULL);
13514   PushButton (c, "Cancel", StdCancelButtonProc);
13515   dlg->leave_dlg_up = CheckBox (c, "Leave dialog up", NULL);
13516 
13517   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->qual_dlg, (HANDLE) dlg->cap_dlg, (HANDLE) c, NULL);
13518 
13519   RealizeWindow (w);
13520   Show (w);
13521   Update ();
13522 }
13523 
ChangeQualifierCase(IteM i)13524 NLM_EXTERN void ChangeQualifierCase (IteM i)
13525 {
13526   BaseFormPtr       bfp;
13527 
13528 #ifdef WIN_MAC
13529   bfp = currentFormDataPtr;
13530 #else
13531   bfp = GetObjectExtra (i);
13532 #endif
13533   if (bfp == NULL || bfp->input_entityID == 0) return;
13534 
13535   ChangeQualifierCaseBaseForm (bfp);
13536 }
13537 
13538 
13539 typedef struct applymoltypeform {
13540   FORM_MESSAGE_BLOCK
13541 
13542   DialoG mol_type_dlg;
13543 
13544   Uint1 mol_type;
13545   Uint1 mol_class;
13546 
13547 } ApplyMolTypeFormData, PNTR ApplyMolTypeFormPtr;
13548 
13549 
ApplyMoleculeTypeCallback(BioseqPtr bsp,Pointer data)13550 static void ApplyMoleculeTypeCallback (BioseqPtr bsp, Pointer data)
13551 {
13552   ApplyMolTypeFormPtr dlg;
13553   SeqDescrPtr         sdp;
13554   SeqMgrDescContext   context;
13555   MolInfoPtr          mip;
13556 
13557   if (bsp == NULL || ISA_aa(bsp->mol) || (dlg = (ApplyMolTypeFormPtr) data) == NULL) {
13558     return;
13559   }
13560 
13561   bsp->mol = dlg->mol_class;
13562   sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &context);
13563   if (sdp == NULL) {
13564     sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_molinfo);
13565   }
13566 
13567   mip = (MolInfoPtr) sdp->data.ptrvalue;
13568   if (mip == NULL) {
13569     mip = MolInfoNew ();
13570     sdp->data.ptrvalue = mip;
13571   }
13572   mip->biomol = dlg->mol_type;
13573 }
13574 
13575 
DoApplyMoleculeType(ButtoN b)13576 static void DoApplyMoleculeType(ButtoN b)
13577 {
13578   ApplyMolTypeFormPtr dlg;
13579   ValNodePtr          vnp;
13580   SeqEntryPtr         sep;
13581 
13582   dlg = (ApplyMolTypeFormPtr) GetObjectExtra (b);
13583   if (dlg == NULL) {
13584     return;
13585   }
13586 
13587   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
13588 
13589   vnp = DialogToPointer (dlg->mol_type_dlg);
13590   if (vnp == NULL) {
13591     return;
13592   }
13593 
13594   dlg->mol_type = BiomolFromMoleculeType (vnp->choice);
13595   if (StringSearch (vnp->data.ptrvalue, "RNA") == NULL) {
13596     dlg->mol_class = MOLECULE_CLASS_DNA;
13597   } else {
13598     dlg->mol_class = MOLECULE_CLASS_RNA;
13599   }
13600 
13601   VisitBioseqsInSep (sep, dlg, ApplyMoleculeTypeCallback);
13602 
13603   vnp = ValNodeFree (vnp);
13604   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
13605   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
13606   Remove (dlg->form);
13607   ArrowCursor();
13608   Update();
13609 }
13610 
13611 
ExternalApplyMoleculeType(IteM i)13612 NLM_EXTERN void ExternalApplyMoleculeType (IteM i)
13613 {
13614   BaseFormPtr       bfp;
13615   WindoW            w;
13616   GrouP             h, c;
13617   ButtoN            b;
13618   ApplyMolTypeFormPtr dlg;
13619   ValNodePtr          moltype_list, vnp, vnp_new;
13620 
13621 
13622 #ifdef WIN_MAC
13623   bfp = currentFormDataPtr;
13624 #else
13625   bfp = GetObjectExtra (i);
13626 #endif
13627   if (bfp == NULL || bfp->input_entityID == 0) return;
13628 
13629   dlg = (ApplyMolTypeFormPtr) MemNew (sizeof (ApplyMolTypeFormData));
13630   if (dlg == NULL) return;
13631 
13632   w = FixedWindow (-50, -33, -10, -10, "Apply Molecule Type", StdCloseWindowProc);
13633   SetObjectExtra (w, dlg, StdCleanupFormProc);
13634   dlg->form = (ForM) w;
13635   dlg->input_entityID = bfp->input_entityID;
13636   h = HiddenGroup (w, -1, 0, NULL);
13637   SetGroupSpacing (h, 10, 10);
13638 
13639   moltype_list = GetMoleculeTypeList ();
13640   /* edit list - split genomic into genomic DNA and genomic RNA */
13641   for (vnp = moltype_list; vnp != NULL; vnp = vnp->next) {
13642     if (vnp->choice == Molecule_type_unknown) {
13643       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
13644       vnp->data.ptrvalue = StringSave ("unknown");
13645     } else if (vnp->choice == Molecule_type_genomic) {
13646       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
13647       vnp->data.ptrvalue = StringSave ("genomic DNA");
13648       vnp_new = ValNodeNew (NULL);
13649       vnp_new->choice = Molecule_type_genomic;
13650       vnp_new->data.ptrvalue = StringSave ("genomic RNA");
13651       vnp_new->next = vnp->next;
13652       vnp->next = vnp_new;
13653       vnp = vnp_new;
13654     }
13655   }
13656 
13657   dlg->mol_type_dlg = ValNodeSelectionDialog (h, moltype_list, SHORT_SELECTION_LIST, ValNodeStringName,
13658                                               ValNodeSimpleDataFree, ValNodeStringCopy,
13659                                               ValNodeStringMatch, "molecule type",
13660                                               NULL, NULL, FALSE);
13661   vnp = ValNodeNew (NULL);
13662   vnp->choice = Molecule_type_unknown;
13663   vnp->data.ptrvalue = StringSave ("unknown");
13664   PointerToDialog (dlg->mol_type_dlg, vnp);
13665   vnp = ValNodeFree (vnp);
13666 
13667   c = HiddenGroup (h, 4, 0, NULL);
13668   b = DefaultButton (c, "Accept", DoApplyMoleculeType);
13669   SetObjectExtra (b, dlg, NULL);
13670   PushButton (c, "Cancel", StdCancelButtonProc);
13671 
13672   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->mol_type_dlg, (HANDLE) c, NULL);
13673 
13674   RealizeWindow (w);
13675   Show (w);
13676   Update ();
13677 }
13678 
13679 
13680 typedef struct applygcform {
13681   FORM_MESSAGE_BLOCK
13682 
13683   PopuP gc;
13684 
13685 } ApplyGCFormData, PNTR ApplyGCFormPtr;
13686 
13687 
ApplyGcCodeCallback(BioSourcePtr biop,Pointer data)13688 static void ApplyGcCodeCallback (BioSourcePtr biop, Pointer data)
13689 {
13690   ApplyGCFormPtr dlg;
13691   if (biop == NULL || (dlg = (ApplyGCFormPtr) data) == NULL) {
13692     return;
13693   }
13694   if (biop->org == NULL) {
13695     biop->org = OrgRefNew();
13696   }
13697   if (biop->org->orgname == NULL) {
13698     biop->org->orgname = OrgNameNew ();
13699   }
13700   switch (biop->genome) {
13701     case GENOME_mitochondrion:
13702     case GENOME_kinetoplast:
13703       biop->org->orgname->mgcode = gcIndexToId [GetValue (dlg->gc)];
13704       break;
13705     case GENOME_chloroplast:
13706     case GENOME_chromoplast:
13707     case GENOME_plastid:
13708     case GENOME_cyanelle:
13709     case GENOME_apicoplast:
13710     case GENOME_leucoplast:
13711     case GENOME_proplastid:
13712     case GENOME_chromatophore:
13713       biop->org->orgname->pgcode = gcIndexToId [GetValue (dlg->gc)];
13714       break;
13715     default:
13716       biop->org->orgname->gcode = gcIndexToId [GetValue (dlg->gc)];
13717       break;
13718   }
13719 }
13720 
13721 
DoApplyGcCode(ButtoN b)13722 static void DoApplyGcCode(ButtoN b)
13723 {
13724   ApplyGCFormPtr dlg;
13725   SeqEntryPtr sep;
13726 
13727   dlg = (ApplyGCFormPtr) GetObjectExtra (b);
13728   if (dlg == NULL) {
13729     return;
13730   }
13731   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
13732   VisitBioSourcesInSep (sep, dlg, ApplyGcCodeCallback);
13733 
13734   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
13735   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
13736   Remove (dlg->form);
13737   Update ();
13738 }
13739 
13740 
BatchApplyGeneticCode(IteM i)13741 NLM_EXTERN void BatchApplyGeneticCode (IteM i)
13742 {
13743   BaseFormPtr       bfp;
13744   WindoW            w;
13745   GrouP             h, c;
13746   ButtoN            b;
13747   ApplyGCFormPtr    dlg;
13748 
13749 
13750 #ifdef WIN_MAC
13751   bfp = currentFormDataPtr;
13752 #else
13753   bfp = GetObjectExtra (i);
13754 #endif
13755   if (bfp == NULL || bfp->input_entityID == 0) return;
13756 
13757   dlg = (ApplyGCFormPtr) MemNew (sizeof (ApplyGCFormData));
13758   if (dlg == NULL) return;
13759 
13760   w = FixedWindow (-50, -33, -10, -10, "Apply Genetic Code to Sources", StdCloseWindowProc);
13761   SetObjectExtra (w, dlg, StdCleanupFormProc);
13762   dlg->form = (ForM) w;
13763   dlg->input_entityID = bfp->input_entityID;
13764   h = HiddenGroup (w, -1, 0, NULL);
13765   SetGroupSpacing (h, 10, 10);
13766 
13767   dlg->gc = PopupList (h, TRUE, NULL);
13768   PopulateGeneticCodePopup (dlg->gc);
13769   SetValue (dlg->gc, 1);
13770 
13771 
13772   c = HiddenGroup (h, 4, 0, NULL);
13773   b = DefaultButton (c, "Accept", DoApplyGcCode);
13774   SetObjectExtra (b, dlg, NULL);
13775   PushButton (c, "Cancel", StdCancelButtonProc);
13776 
13777   AlignObjects (ALIGN_CENTER, (HANDLE) dlg->gc, (HANDLE) c, NULL);
13778 
13779   RealizeWindow (w);
13780   Show (w);
13781   Update ();
13782 }
13783 
13784 
13785 typedef struct formattedstruccomform {
13786   FORM_MESSAGE_BLOCK
13787 
13788   TexT * values;
13789   Int4   num_fields;
13790 
13791   CommentRulePtr    comment_rule;
13792 
13793 } FormattedStrucComFormData, PNTR FormattedStrucComFormPtr;
13794 
13795 
CleanupFormattedStrucComFormProc(GraphiC g,VoidPtr data)13796 static void CleanupFormattedStrucComFormProc (GraphiC g, VoidPtr data)
13797 
13798 {
13799   FormattedStrucComFormPtr  dlg;
13800 
13801   if (data) {
13802     dlg = (FormattedStrucComFormPtr) data;
13803     dlg->values = MemFree (dlg->values);
13804   }
13805   StdCleanupFormProc (g, data);
13806 }
13807 
13808 
DoApplyFormattedStructuredComment(ButtoN b)13809 static void DoApplyFormattedStructuredComment (ButtoN b)
13810 {
13811   FormattedStrucComFormPtr dlg;
13812   UserObjectPtr            uop;
13813   CharPtr                  suffix, value;
13814   Int4                     len;
13815   SeqDescrPtr              sdp;
13816   SeqEntryPtr              sep;
13817   FieldRulePtr             field;
13818   Int4                     n;
13819 
13820   dlg = (FormattedStrucComFormPtr) GetObjectExtra (b);
13821   if (dlg == NULL) {
13822     return;
13823   }
13824 
13825   uop = UserObjectNew ();
13826   uop->type = ObjectIdNew ();
13827   uop->type->str = StringSave ("StructuredComment");
13828 
13829   AddItemStructuredCommentUserObject (uop, "StructuredCommentPrefix", dlg->comment_rule->prefix);
13830 
13831   for (field = dlg->comment_rule->fields, n = 0; field != NULL; field = field->next, n++) {
13832     if (!TextHasNoText (dlg->values[n])) {
13833       value = SaveStringFromText (dlg->values[n]);
13834       AddItemStructuredCommentUserObject (uop, field->field_name, value);
13835       value = MemFree (value);
13836     }
13837   }
13838 
13839   if ((len = StringLen (dlg->comment_rule->prefix)) > 7
13840     && StringCmp (dlg->comment_rule->prefix + len - 7, "START##") == 0) {
13841     suffix = StringSave (dlg->comment_rule->prefix);
13842     sprintf (suffix + len - 7, "%s", "END##");
13843     AddItemStructuredCommentUserObject (uop, "StructuredCommentSuffix", suffix);
13844     suffix = MemFree (suffix);
13845   }
13846 
13847   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
13848   sdp = CreateNewDescriptor (sep, Seq_descr_user);
13849   sdp->data.ptrvalue = uop;
13850 
13851   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
13852   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
13853   Remove (dlg->form);
13854   Update ();
13855 }
13856 
ApplyFormattedStructuredCommentBaseForm(BaseFormPtr bfp,CharPtr prefix)13857 NLM_EXTERN void ApplyFormattedStructuredCommentBaseForm (BaseFormPtr bfp, CharPtr prefix)
13858 {
13859   CharPtr           prefix_fmt = "##%s-Data-START##";
13860   CharPtr           title_fmt = "Apply %s Structured Comment";
13861   CharPtr           tmp;
13862   WindoW            w;
13863   GrouP             h, g, c;
13864   ButtoN            b;
13865   CommentRulePtr    comment_rule;
13866   FieldRulePtr      field;
13867   Int4              n;
13868   FormattedStrucComFormPtr dlg;
13869 
13870   if (bfp == NULL || bfp->input_entityID == 0) return;
13871 
13872   tmp = (CharPtr) MemNew (sizeof (Char) * (StringLen (prefix) + StringLen (prefix_fmt)));
13873   sprintf (tmp, prefix_fmt, prefix);
13874 
13875   comment_rule = GetCommentRuleFromRuleSet (tmp);
13876   tmp = MemFree (tmp);
13877   if (comment_rule == NULL) {
13878     return;
13879   }
13880 
13881   dlg = (FormattedStrucComFormPtr) MemNew (sizeof (FormattedStrucComFormData));
13882   if (dlg == NULL) return;
13883 
13884   dlg->comment_rule = comment_rule;
13885   n = 0;
13886   for (field = comment_rule->fields; field != NULL; field = field->next) {
13887     n++;
13888   }
13889   dlg->num_fields = n;
13890   dlg->values = (TexT *) MemNew (sizeof (TexT) * dlg->num_fields);
13891 
13892   tmp = (CharPtr) MemNew (sizeof (Char) * (StringLen (title_fmt) + StringLen(prefix)));
13893   sprintf (tmp, title_fmt, prefix);
13894   w = FixedWindow (-50, -33, -10, -10, tmp, StdCloseWindowProc);
13895   tmp = MemFree (tmp);
13896   SetObjectExtra (w, dlg, CleanupFormattedStrucComFormProc);
13897   dlg->form = (ForM) w;
13898   dlg->input_entityID = bfp->input_entityID;
13899   h = HiddenGroup (w, -1, 0, NULL);
13900   SetGroupSpacing (h, 10, 10);
13901 
13902   g = HiddenGroup (h, 2, 0, NULL);
13903   for (field = dlg->comment_rule->fields, n = 0; field != NULL; field = field->next, n++) {
13904     StaticPrompt (g, field->field_name, 0, dialogTextHeight, programFont, 'l');
13905     dlg->values[n] = DialogText (g, "", 10, NULL);
13906   }
13907 
13908   c = HiddenGroup (h, 4, 0, NULL);
13909   b = DefaultButton (c, "Accept", DoApplyFormattedStructuredComment);
13910   SetObjectExtra (b, dlg, NULL);
13911   PushButton (c, "Cancel", StdCancelButtonProc);
13912 
13913   AlignObjects (ALIGN_CENTER, (HANDLE)g, (HANDLE) c, NULL);
13914 
13915   RealizeWindow (w);
13916   Show (w);
13917   Update ();
13918 }
13919 
13920 
ApplyFormattedStructuredComment(IteM i,CharPtr prefix)13921 static void ApplyFormattedStructuredComment (IteM i, CharPtr prefix)
13922 {
13923   BaseFormPtr       bfp;
13924 
13925 #ifdef WIN_MAC
13926   bfp = currentFormDataPtr;
13927 #else
13928   bfp = GetObjectExtra (i);
13929 #endif
13930 
13931   ApplyFormattedStructuredCommentBaseForm (bfp, prefix);
13932 }
13933 
13934 
ApplyGenomeAssemblyComment(IteM i)13935 NLM_EXTERN void ApplyGenomeAssemblyComment (IteM i)
13936 {
13937   ApplyFormattedStructuredComment (i, "Genome-Assembly");
13938 }
13939 
13940 
ApplyAssemblyComment(IteM i)13941 NLM_EXTERN void ApplyAssemblyComment (IteM i)
13942 {
13943   ApplyFormattedStructuredComment (i, "Assembly");
13944 }
13945 
13946 
13947 typedef struct releasedateform {
13948   FORM_MESSAGE_BLOCK
13949 
13950   DialoG dlg;
13951 } ReleaseDateFormData, PNTR ReleaseDateFormPtr;
13952 
13953 
DoApplyReleaseDate(ButtoN b)13954 static void DoApplyReleaseDate (ButtoN b)
13955 {
13956   ReleaseDateFormPtr dlg;
13957   SeqEntryPtr        sep;
13958   SeqSubmitPtr       ssp;
13959 
13960   dlg = (ReleaseDateFormPtr) GetObjectExtra (b);
13961   if (dlg == NULL) {
13962     return;
13963   }
13964 
13965   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
13966   if (sep == NULL) return;
13967 
13968   ssp = FindSeqSubmitForSeqEntry (sep);
13969   if (ssp == NULL) {
13970     return;
13971   }
13972 
13973   ssp->sub = SubmitBlockFree (ssp->sub);
13974   ssp->sub = DialogToPointer (dlg->dlg);
13975 
13976   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
13977   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
13978   Remove (dlg->form);
13979   Update ();
13980 }
13981 
13982 
SetReleaseDate(IteM i)13983 NLM_EXTERN void SetReleaseDate(IteM i)
13984 {
13985   BaseFormPtr  bfp;
13986   SeqEntryPtr  sep;
13987   SeqSubmitPtr ssp;
13988   ReleaseDateFormPtr dlg;
13989   WindoW             w;
13990   GrouP              h, c;
13991   ButtoN             b;
13992 
13993 #ifdef WIN_MAC
13994   bfp = currentFormDataPtr;
13995 #else
13996   bfp = GetObjectExtra (i);
13997 #endif
13998   if (bfp == NULL) return;
13999   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
14000   if (sep == NULL) return;
14001 
14002   ssp = FindSeqSubmitForSeqEntry (sep);
14003   if (ssp == NULL) {
14004     return;
14005   }
14006 
14007   dlg = (ReleaseDateFormPtr) MemNew (sizeof (ReleaseDateFormData));
14008   if (dlg == NULL) return;
14009 
14010   w = FixedWindow (-50, -33, -10, -10, "Set Release Date", StdCloseWindowProc);
14011   SetObjectExtra (w, dlg, StdCleanupFormProc);
14012   dlg->form = (ForM) w;
14013   dlg->input_entityID = bfp->input_entityID;
14014   h = HiddenGroup (w, -1, 0, NULL);
14015   SetGroupSpacing (h, 10, 10);
14016 
14017   dlg->dlg = CreateSubmitDataDialog (h, "", ssp->sub == NULL, ssp->sub == NULL || ssp->sub->hup);
14018   PointerToDialog (dlg->dlg, ssp->sub);
14019 
14020   c = HiddenGroup (h, 4, 0, NULL);
14021   b = DefaultButton (c, "Accept", DoApplyReleaseDate);
14022   SetObjectExtra (b, dlg, NULL);
14023   PushButton (c, "Cancel", StdCancelButtonProc);
14024 
14025   AlignObjects (ALIGN_CENTER, (HANDLE)dlg->dlg, (HANDLE) c, NULL);
14026 
14027   RealizeWindow (w);
14028   Show (w);
14029   Update ();
14030 }
14031 
14032 
14033 typedef struct removetextform {
14034   FORM_MESSAGE_BLOCK
14035   DialoG text_portion;
14036   GrouP  not_found;
14037   DialoG field;
14038   DialoG constraint;
14039   ButtoN leave_dlg_up;
14040   ButtoN accept_btn;
14041 
14042 } RemoveTextFormData, PNTR RemoveTextFormPtr;
14043 
14044 typedef struct removetext {
14045   TextPortionPtr text_portion;
14046   Boolean    remove_if_not_found;
14047   ValNodePtr field;
14048   ValNodePtr constraint;
14049 } RemoveTextData, PNTR RemoveTextPtr;
14050 
14051 
RemoveTextFree(RemoveTextPtr data)14052 static RemoveTextPtr RemoveTextFree (RemoveTextPtr data)
14053 {
14054   if (data != NULL) {
14055     data->text_portion = TextPortionFree (data->text_portion);
14056     data->field = ParseDestFree (data->field);
14057     data->constraint = ConstraintChoiceSetFree (data->constraint);
14058     data = MemFree (data);
14059   }
14060   return data;
14061 }
14062 
14063 
RemoveTextCallbackDesc(SeqDescPtr sdp,Pointer data)14064 static void RemoveTextCallbackDesc (SeqDescPtr sdp, Pointer data)
14065 {
14066   RemoveTextPtr     rt;
14067   ParseDstOrgPtr    o;
14068   CharPtr           str;
14069   ObjValNodePtr     ovn;
14070   StringConstraint  sc;
14071 
14072   if (sdp == NULL || (rt = (RemoveTextPtr) data) == NULL
14073       || !DoesObjectMatchConstraintChoiceSet(OBJ_SEQDESC, sdp, rt->constraint)) {
14074     return;
14075   }
14076   switch (rt->field->choice) {
14077     case ParseDest_defline:
14078       if (sdp->choice == Seq_descr_title) {
14079         if (!RemoveTextPortionFromString ((CharPtr)(sdp->data.ptrvalue), rt->text_portion)
14080             && rt->remove_if_not_found) {
14081           if (sdp->extended) {
14082             ovn = (ObjValNodePtr) sdp;
14083             ovn->idx.deleteme = TRUE;
14084           }
14085         }
14086       }
14087       break;
14088     case ParseDest_org:
14089       if ((o = (ParseDstOrgPtr) rt->field->data.ptrvalue) != NULL
14090           && o->type != Object_type_constraint_feature
14091           && sdp->choice == Seq_descr_source) {
14092         str = GetSourceQualFromBioSource (sdp->data.ptrvalue, o->field, NULL);
14093         if (RemoveTextPortionFromString(str, rt->text_portion)) {
14094           SetSourceQualInBioSource(sdp->data.ptrvalue, o->field, NULL, str, ExistingTextOption_replace_old);
14095         } else if (rt->remove_if_not_found) {
14096           MemSet (&sc, 0, sizeof (StringConstraint));
14097           sc.case_sensitive = TRUE;
14098           sc.match_location = String_location_equals;
14099           sc.match_text = str;
14100           RemoveSourceQualFromBioSource (sdp->data.ptrvalue, o->field, &sc);
14101         }
14102         str = MemFree (str);
14103       }
14104       break;
14105     case ParseDest_comment_descriptor:
14106       if (sdp->choice == Seq_descr_comment) {
14107         if (!RemoveTextPortionFromString ((CharPtr)(sdp->data.ptrvalue), rt->text_portion)
14108           && rt->remove_if_not_found) {
14109           if (sdp->extended) {
14110             ovn = (ObjValNodePtr) sdp;
14111             ovn->idx.deleteme = TRUE;
14112           }
14113         }
14114       }
14115       break;
14116     case ParseDest_dbxref:
14117       if (sdp->choice == Seq_descr_source) {
14118         str = GetDBxrefFromBioSource (sdp->data.ptrvalue, rt->field->data.ptrvalue);
14119         if (str != NULL) {
14120           if (RemoveTextPortionFromString(str, rt->text_portion)) {
14121             SetDBxrefForBioSource (sdp->data.ptrvalue, rt->field->data.ptrvalue, str, ExistingTextOption_replace_old);
14122           } else if (rt->remove_if_not_found) {
14123             MemSet (&sc, 0, sizeof (StringConstraint));
14124             sc.case_sensitive = TRUE;
14125             sc.match_location = String_location_equals;
14126             sc.match_text = str;
14127             RemoveDBxrefForBioSource (sdp->data.ptrvalue, rt->field->data.ptrvalue, &sc);
14128           }
14129           str = MemFree (str);
14130         }
14131       }
14132       break;
14133   }
14134 }
14135 
14136 
RemoveTextCallbackFeat(SeqFeatPtr sfp,Pointer data)14137 static void RemoveTextCallbackFeat (SeqFeatPtr sfp, Pointer data)
14138 {
14139   RemoveTextPtr     rt;
14140   ParseDstOrgPtr    o;
14141   CharPtr           str;
14142   StringConstraint  sc;
14143   FeatureFieldLegalPtr fl;
14144   FeatureField         f;
14145 
14146   if (sfp == NULL || (rt = (RemoveTextPtr) data) == NULL
14147       || !DoesObjectMatchConstraintChoiceSet(OBJ_SEQFEAT, sfp, rt->constraint)) {
14148     return;
14149   }
14150 
14151   switch (rt->field->choice) {
14152     case ParseDest_org:
14153       if ((o = (ParseDstOrgPtr) rt->field->data.ptrvalue) != NULL
14154           && o->type != Object_type_constraint_descriptor
14155           && sfp->data.choice == SEQFEAT_BIOSRC) {
14156         str = GetSourceQualFromBioSource (sfp->data.value.ptrvalue, o->field, NULL);
14157         if (RemoveTextPortionFromString(str, rt->text_portion)) {
14158           SetSourceQualInBioSource(sfp->data.value.ptrvalue, o->field, NULL, str, ExistingTextOption_replace_old);
14159         } else if (rt->remove_if_not_found) {
14160           MemSet (&sc, 0, sizeof (StringConstraint));
14161           sc.case_sensitive = TRUE;
14162           sc.match_location = String_location_equals;
14163           sc.match_text = str;
14164           RemoveSourceQualFromBioSource (sfp->data.value.ptrvalue, o->field, &sc);
14165         }
14166         str = MemFree (str);
14167       }
14168       break;
14169     case ParseDest_featqual:
14170       fl = (FeatureFieldLegalPtr) rt->field->data.ptrvalue;
14171       if (fl != NULL) {
14172         f.type = fl->type;
14173         f.field = ValNodeNew(NULL);
14174         f.field->next = NULL;
14175         f.field->choice = FeatQualChoice_legal_qual;
14176         f.field->data.intvalue = fl->field;
14177         str = GetQualFromFeature (sfp, &f, NULL);
14178         if (str != NULL) {
14179           if (RemoveTextPortionFromString(str, rt->text_portion)) {
14180             SetQualOnFeature (sfp, &f, NULL, str, ExistingTextOption_replace_old);
14181           } else if (rt->remove_if_not_found) {
14182             MemSet (&sc, 0, sizeof (StringConstraint));
14183             sc.case_sensitive = TRUE;
14184             sc.match_location = String_location_equals;
14185             sc.match_text = str;
14186             RemoveQualFromFeature (sfp, &f, &sc);
14187           }
14188           f.field = ValNodeFree (f.field);
14189           str = MemFree (str);
14190         }
14191       }
14192       break;
14193     case ParseDest_dbxref:
14194       if (sfp->data.choice == SEQFEAT_BIOSRC) {
14195         str = GetDBxrefFromBioSource (sfp->data.value.ptrvalue, rt->field->data.ptrvalue);
14196         if (str != NULL) {
14197           if (RemoveTextPortionFromString (str, rt->text_portion)) {
14198             SetDBxrefForBioSource (sfp->data.value.ptrvalue, rt->field->data.ptrvalue, str, ExistingTextOption_replace_old);
14199           } else if (rt->remove_if_not_found) {
14200             MemSet (&sc, 0, sizeof (StringConstraint));
14201             sc.case_sensitive = TRUE;
14202             sc.match_location = String_location_equals;
14203             sc.match_text = str;
14204             RemoveDBxrefForBioSource (sfp->data.value.ptrvalue, rt->field->data.ptrvalue, &sc);
14205           }
14206           str = MemFree (str);
14207         }
14208       }
14209       break;
14210   }
14211 
14212 }
14213 
14214 
DoRemoveText(ButtoN b)14215 static void DoRemoveText (ButtoN b)
14216 {
14217   RemoveTextFormPtr dlg;
14218   RemoveTextPtr     data;
14219   SeqEntryPtr       sep;
14220   ParseDstOrgPtr    o;
14221 
14222   dlg = (RemoveTextFormPtr) GetObjectExtra (b);
14223   if (dlg == NULL) {
14224     return;
14225   }
14226 
14227   data = (RemoveTextPtr) MemNew (sizeof (RemoveTextData));
14228 
14229   data->text_portion = DialogToPointer (dlg->text_portion);
14230   data->field = DialogToPointer (dlg->field);
14231   data->remove_if_not_found = (GetValue (dlg->not_found) == 2);
14232   data->constraint = DialogToPointer (dlg->constraint);
14233 
14234   sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
14235 
14236 
14237   switch (data->field->choice) {
14238     case ParseDest_defline :
14239       VisitDescriptorsInSep (sep, data, RemoveTextCallbackDesc);
14240       break;
14241     case ParseDest_org :
14242       o = (ParseDstOrgPtr) data->field->data.ptrvalue;
14243       if (o->type == Object_type_constraint_any || o->type == Object_type_constraint_descriptor) {
14244         VisitDescriptorsInSep (sep, data, RemoveTextCallbackDesc);
14245       }
14246       if (o->type == Object_type_constraint_any || o->type == Object_type_constraint_feature) {
14247         VisitFeaturesInSep (sep, data, RemoveTextCallbackFeat);
14248       }
14249       break;
14250     case ParseDest_featqual :
14251       VisitFeaturesInSep (sep, data, RemoveTextCallbackFeat);
14252       break;
14253     case ParseDest_comment_descriptor :
14254       VisitDescriptorsInSep (sep, data, RemoveTextCallbackDesc);
14255       break;
14256     case ParseDest_dbxref :
14257       VisitDescriptorsInSep (sep, data, RemoveTextCallbackDesc);
14258       VisitFeaturesInSep (sep, data, RemoveTextCallbackFeat);
14259       break;
14260   }
14261 
14262   data = RemoveTextFree (data);
14263 
14264   DeleteMarkedObjects (dlg->input_entityID, 0, NULL);
14265   ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
14266   ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
14267   if (GetStatus (dlg->leave_dlg_up)) {
14268   } else {
14269     Remove (dlg->form);
14270   }
14271   Update();
14272 }
14273 
14274 
EnableRemoveTextAccept(Pointer data)14275 static void EnableRemoveTextAccept (Pointer data)
14276 {
14277   RemoveTextFormPtr dlg;
14278   ValNodePtr        field;
14279 
14280   dlg = (RemoveTextFormPtr) data;
14281   if (dlg == NULL) {
14282     return;
14283   }
14284 
14285   field = DialogToPointer (dlg->field);
14286   if (field == NULL) {
14287     Disable (dlg->accept_btn);
14288   } else {
14289     Enable (dlg->accept_btn);
14290   }
14291   field = ParseDestFree (field);
14292 }
14293 
14294 
ClearRemoveText(ButtoN b)14295 static void ClearRemoveText(ButtoN b)
14296 {
14297   RemoveTextFormPtr dlg;
14298 
14299   dlg = (RemoveTextFormPtr) GetObjectExtra (b);
14300   if (dlg == NULL) {
14301     return;
14302   }
14303 
14304   PointerToDialog (dlg->text_portion, NULL);
14305   PointerToDialog (dlg->field, NULL);
14306   EnableRemoveTextAccept(dlg);
14307 }
14308 
14309 
RemoveTextBaseForm(BaseFormPtr bfp,Boolean inside)14310 static void RemoveTextBaseForm (BaseFormPtr bfp, Boolean inside)
14311 {
14312   RemoveTextFormPtr dlg;
14313   WindoW             w;
14314   GrouP              h, g1, c;
14315   PrompT             p1;
14316   ButtoN             clear_btn;
14317 
14318   if (bfp == NULL) return;
14319 
14320   dlg = (RemoveTextFormPtr) MemNew (sizeof (RemoveTextFormData));
14321   if (dlg == NULL) return;
14322 
14323   w = FixedWindow (-50, -33, -10, -10, inside ? "Remove Text Inside String" : "Remove Text Outside String", StdCloseWindowProc);
14324   SetObjectExtra (w, dlg, StdCleanupFormProc);
14325   dlg->form = (ForM) w;
14326   dlg->input_entityID = bfp->input_entityID;
14327   h = HiddenGroup (w, -1, 0, NULL);
14328   SetGroupSpacing (h, 10, 10);
14329 
14330   dlg->text_portion = TextPortionDialog (h, inside, NULL, NULL);
14331 
14332   g1 = HiddenGroup (h, 0, 2, NULL);
14333   StaticPrompt (g1, "If field doesn't contain searched for text:", 0, 0, programFont, 'l');
14334 
14335   dlg->not_found = HiddenGroup (g1, 0, 3, NULL);
14336 
14337   RadioButton (dlg->not_found, "     Do nothing to field");
14338   RadioButton (dlg->not_found, "     Remove entire field text");
14339   SetValue (dlg->not_found, 1);
14340 
14341   p1 = StaticPrompt (h, "Perform excision in", 0, popupMenuHeight, programFont, 'l');
14342 
14343   dlg->field = ParseDstDialog (h, EnableRemoveTextAccept, dlg);
14344 
14345   /* clear button */
14346   clear_btn = PushButton (h, "Clear", ClearRemoveText);
14347   SetObjectExtra (clear_btn, dlg, NULL);
14348 
14349   dlg->constraint = ConstraintSetDialog (h, NULL, NULL);
14350 
14351 
14352   c = HiddenGroup (h, 4, 0, NULL);
14353   dlg->accept_btn = DefaultButton (c, "Accept", DoRemoveText);
14354   SetObjectExtra (dlg->accept_btn, dlg, NULL);
14355   PushButton (c, "Cancel", StdCancelButtonProc);
14356   dlg->leave_dlg_up = CheckBox (c, "Leave Dialog Up", NULL);
14357 
14358   AlignObjects (ALIGN_CENTER, (HANDLE)dlg->text_portion,
14359                               (HANDLE) g1,
14360                               (HANDLE) p1,
14361                               (HANDLE) dlg->field,
14362                               (HANDLE) dlg->constraint,
14363                               (HANDLE) clear_btn,
14364                               (HANDLE) c, NULL);
14365   EnableRemoveTextAccept (dlg);
14366   RealizeWindow (w);
14367   Show (w);
14368   Update ();
14369 }
14370 
14371 
NewRemoveText(IteM i,Boolean inside)14372 static void NewRemoveText (IteM i, Boolean inside)
14373 {
14374   BaseFormPtr  bfp;
14375 
14376 #ifdef WIN_MAC
14377   bfp = currentFormDataPtr;
14378 #else
14379   bfp = GetObjectExtra (i);
14380 #endif
14381   if (bfp == NULL) return;
14382 
14383   RemoveTextBaseForm (bfp, inside);
14384 }
14385 
14386 
NewRemoveTextOutsideString(IteM i)14387 NLM_EXTERN void NewRemoveTextOutsideString (IteM i)
14388 {
14389   NewRemoveText (i, FALSE);
14390 }
14391 
14392 
RemoveTextOutsideStringBaseForm(BaseFormPtr bfp)14393 extern void RemoveTextOutsideStringBaseForm (BaseFormPtr bfp)
14394 {
14395   RemoveTextBaseForm (bfp, FALSE);
14396 }
14397 
14398 
PrintTPAHistErrors(LogInfoPtr lip,ValNodePtr errors)14399 static void PrintTPAHistErrors (LogInfoPtr lip, ValNodePtr errors)
14400 {
14401   ValNodePtr vnp;
14402 
14403   if (lip == NULL || lip->fp == NULL || errors == NULL) return;
14404 
14405   for (vnp = errors; vnp != NULL; vnp = vnp->next)
14406   {
14407     fprintf (lip->fp, "%s\n", (CharPtr) vnp->data.ptrvalue);
14408     lip->data_in_log = TRUE;
14409   }
14410   fprintf (lip->fp, "\n\n");
14411 }
14412 
14413 
AdjustForConsensusSplice(IteM i)14414 NLM_EXTERN void AdjustForConsensusSplice (IteM i)
14415 {
14416   BaseFormPtr  bfp;
14417   SeqEntryPtr  sep;
14418 
14419 #ifdef WIN_MAC
14420   bfp = currentFormDataPtr;
14421 #else
14422   bfp = GetObjectExtra (i);
14423 #endif
14424   if (bfp == NULL) return;
14425 
14426   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
14427   if (sep == NULL) {
14428     return;
14429   }
14430 
14431   AdjustSeqEntryForConsensusSplice (sep);
14432 
14433   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
14434   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
14435   Update ();
14436 }
14437 
14438 
AdjustForConsensusSpliceRelaxed(IteM i)14439 NLM_EXTERN void AdjustForConsensusSpliceRelaxed (IteM i)
14440 {
14441   BaseFormPtr  bfp;
14442   SeqEntryPtr  sep;
14443 
14444 #ifdef WIN_MAC
14445   bfp = currentFormDataPtr;
14446 #else
14447   bfp = GetObjectExtra (i);
14448 #endif
14449   if (bfp == NULL) return;
14450 
14451   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
14452   if (sep == NULL) {
14453     return;
14454   }
14455 
14456   AdjustSeqEntryForConsensusSpliceEx (sep, NULL, FALSE);
14457 
14458   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
14459   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
14460   Update ();
14461 }
14462 
14463 
BioseqListFromString(CharPtr str,SeqEntryPtr sep)14464 static ValNodePtr BioseqListFromString(CharPtr str, SeqEntryPtr sep)
14465 {
14466   ValNodePtr list = NULL;
14467   SeqIdPtr   sip;
14468   BioseqPtr  bsp;
14469   CharPtr    cp;
14470   Int4       len;
14471   Char       ch;
14472   ValNodePtr errors = NULL;
14473 
14474   if (str == NULL) {
14475     return NULL;
14476   }
14477   len = StringSpn (str, " \t\r\n,;");
14478   cp = str + len;
14479 
14480   while (*cp != 0) {
14481     len = StringCSpn (cp, " \t\r\n,;");
14482     ch = *(cp + len);
14483     *(cp + len) = 0;
14484     sip = CreateSeqIdFromText (cp, sep);
14485     if (sip == NULL) {
14486       ValNodeAddPointer (&errors, 0, StringSave (cp));
14487     } else {
14488       bsp = BioseqFind (sip);
14489       if (bsp == NULL) {
14490         ValNodeAddPointer (&errors, 0, StringSave (cp));
14491       } else {
14492         ValNodeAddPointer (&list, OBJ_BIOSEQ, bsp);
14493       }
14494       sip = SeqIdFree (sip);
14495     }
14496     *(cp + len) = ch;
14497     cp += len;
14498     len = StringSpn (cp, " \t\r\n,;");
14499     cp = cp + len;
14500   }
14501 
14502   if (errors != NULL) {
14503     cp = ValNodeMergeStrs (errors);
14504     Message (MSG_ERROR, "Unable to find Bioseqs for the following IDs: %s", cp);
14505     cp = MemFree (cp);
14506     list = ValNodeFree (list);
14507   } else if (list == NULL) {
14508     Message (MSG_ERROR, "No IDs listed!");
14509   }
14510   return list;
14511 }
14512 
14513 
14514 typedef struct withdrawsequencesfrm {
14515   FORM_MESSAGE_BLOCK
14516 
14517   TexT id_list;
14518   ButtoN leave_dlg_up;
14519 } WithdrawSequencesFrmData, PNTR WithdrawSequencesFrmPtr;
14520 
DoWithdrawSequences(ButtoN b)14521 static void DoWithdrawSequences (ButtoN b)
14522 {
14523   WithdrawSequencesFrmPtr frm;
14524   SeqEntryPtr             sep;
14525   ValNodePtr              list = NULL;
14526   CharPtr                 list_str;
14527   PopSetRetroStatData     stat;
14528 
14529   frm = (WithdrawSequencesFrmPtr) GetObjectExtra (b);
14530   if (frm == NULL) {
14531     return;
14532   }
14533 
14534   sep = GetTopSeqEntryForEntityID (frm->input_entityID);
14535 
14536   /* get id list from text */
14537   list_str = SaveStringFromText (frm->id_list);
14538   list = BioseqListFromString (list_str, sep);
14539   list_str = MemFree (list_str);
14540   if (list == NULL) {
14541     return;
14542   }
14543 
14544   /* move listed sequences to wrapper */
14545   MoveSequencesFromSetToWrapper (list, frm->input_entityID);
14546 
14547   /* taxfix/cleanup */
14548   ForceCleanupEntityID (frm->input_entityID);
14549 
14550   /* redo set title */
14551   MemSet ((Pointer) &stat, 0, sizeof (PopSetRetroStatData));
14552   RemovePopsetTitles (sep);
14553   PopSetAutoDefRetro (sep, &stat);
14554 
14555   /* validate */
14556   ValSeqEntryForm (frm->form);
14557 
14558   if (!GetStatus (frm->leave_dlg_up)) {
14559     Remove (frm->form);
14560   }
14561 
14562 }
14563 
14564 
WithdrawSequences(IteM i)14565 NLM_EXTERN void WithdrawSequences (IteM i)
14566 {
14567   BaseFormPtr  bfp;
14568   WithdrawSequencesFrmPtr frm;
14569   WindoW       w;
14570   GrouP        h, c;
14571   ButtoN       b;
14572   PrompT       ppt;
14573 
14574 #ifdef WIN_MAC
14575   bfp = currentFormDataPtr;
14576 #else
14577   bfp = GetObjectExtra (i);
14578 #endif
14579   if (bfp == NULL) return;
14580 
14581 
14582   frm = MemNew (sizeof (WithdrawSequencesFrmData));
14583   if (frm == NULL) return;
14584   frm->input_entityID = bfp->input_entityID;
14585 
14586   w = FixedWindow (-50, -33, -10, -10, "Withdraw Sequences", StdCloseWindowProc);
14587   SetObjectExtra (w, frm, StdCleanupFormProc);
14588   frm->form = (ForM) w;
14589 
14590   h = HiddenGroup (w, -1, 0, NULL);
14591   SetGroupSpacing (h, 10, 10);
14592 
14593   ppt = StaticPrompt (h, "List of Accessions", 0, popupMenuHeight, programFont, 'l');
14594 
14595   frm->id_list = ScrollText (h, 25, 10, programFont, TRUE, NULL);
14596 
14597   c = HiddenGroup (h, 4, 0, NULL);
14598   b = DefaultButton (c, "Accept", DoWithdrawSequences);
14599   SetObjectExtra (b, frm, NULL);
14600   PushButton (c, "Cancel", StdCancelButtonProc);
14601   frm->leave_dlg_up = CheckBox (c, "Leave dialog up", NULL);
14602 
14603   AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) frm->id_list,
14604                 (HANDLE) c, NULL);
14605   RealizeWindow (w);
14606   Show (w);
14607   Update ();
14608 }
14609 
14610 
ParseTaxnameToSourceQual(IteM i)14611 extern void ParseTaxnameToSourceQual (IteM i)
14612 {
14613   BaseFormPtr  bfp;
14614   ForM         f;
14615   ParseSrcOrgPtr org;
14616   ParseActionPtr parse;
14617 
14618 #ifdef WIN_MAC
14619   bfp = currentFormDataPtr;
14620 #else
14621   bfp = GetObjectExtra (i);
14622 #endif
14623   if (bfp == NULL) return;
14624 
14625   f = SingleParseAction (bfp->input_entityID);
14626   if (f != NULL) {
14627     /* create parse action with preselected fields */
14628     parse = ParseActionNew ();
14629     /* choose taxname after bionomial as source */
14630     org = ParseSrcOrgNew ();
14631     org->field = ValNodeNew (NULL);
14632     org->field->choice = ParseSrcOrgChoice_taxname_after_binomial;
14633     parse->src = ValNodeNew (NULL);
14634     parse->src->choice = ParseSrc_org;
14635     parse->src->data.ptrvalue = org;
14636     /* choose source qualifiers as dest */
14637     parse->dest = ValNodeNew (NULL);
14638     parse->dest->choice = ParseDest_org;
14639     PointerToForm (f, parse);
14640     parse = ParseActionFree (parse);
14641     Show (f);
14642   }
14643 }
14644 
14645 
ParseDefLineToSourceQual(IteM i)14646 extern void ParseDefLineToSourceQual (IteM i)
14647 {
14648   BaseFormPtr  bfp;
14649   ForM         f;
14650   ParseActionPtr parse;
14651 
14652 #ifdef WIN_MAC
14653   bfp = currentFormDataPtr;
14654 #else
14655   bfp = GetObjectExtra (i);
14656 #endif
14657   if (bfp == NULL) return;
14658 
14659   f = SingleParseAction (bfp->input_entityID);
14660   if (f != NULL) {
14661     /* create parse action with preselected fields */
14662     parse = ParseActionNew ();
14663     /* choose defline as source */
14664     parse->src = ValNodeNew (NULL);
14665     parse->src->choice = ParseSrc_defline;
14666     /* choose source qualifiers as dest */
14667     parse->dest = ValNodeNew (NULL);
14668     parse->dest->choice = ParseDest_org;
14669     PointerToForm (f, parse);
14670     parse = ParseActionFree (parse);
14671     Show (f);
14672   }
14673 }
14674 
ParseFlatfileToSourceQual(IteM i)14675 extern void ParseFlatfileToSourceQual (IteM i)
14676 {
14677   BaseFormPtr  bfp;
14678   ForM         f;
14679   ParseActionPtr parse;
14680 
14681 #ifdef WIN_MAC
14682   bfp = currentFormDataPtr;
14683 #else
14684   bfp = GetObjectExtra (i);
14685 #endif
14686   if (bfp == NULL) return;
14687 
14688   f = SingleParseAction (bfp->input_entityID);
14689   if (f != NULL) {
14690     /* create parse action with preselected fields */
14691     parse = ParseActionNew ();
14692     /* choose defline as source */
14693     parse->src = ValNodeNew (NULL);
14694     parse->src->choice = ParseSrc_flatfile;
14695     /* choose source qualifiers as dest */
14696     parse->dest = ValNodeNew (NULL);
14697     parse->dest->choice = ParseDest_org;
14698     PointerToForm (f, parse);
14699     parse = ParseActionFree (parse);
14700     Show (f);
14701   }
14702 }
14703 
14704 
ParseLocalIDToSourceQual(ButtoN b)14705 extern void ParseLocalIDToSourceQual (ButtoN b)
14706 {
14707   BaseFormPtr bfp;
14708   ForM         f;
14709   ParseActionPtr parse;
14710 
14711   bfp = (BaseFormPtr) GetObjectExtra (b);
14712   if (bfp == NULL) return;
14713 
14714   f = SingleParseAction (bfp->input_entityID);
14715   if (f != NULL) {
14716     /* create parse action with preselected fields */
14717     parse = ParseActionNew ();
14718     /* choose localID as source */
14719     parse->src = ValNodeNew (NULL);
14720     parse->src->choice = ParseSrc_local_id;
14721     /* choose source qualifiers as dest */
14722     parse->dest = ValNodeNew (NULL);
14723     parse->dest->choice = ParseDest_org;
14724     PointerToForm (f, parse);
14725     parse = ParseActionFree (parse);
14726     Show (f);
14727   }
14728 }
14729 
14730 
SegregateIdDialog(GrouP g)14731 NLM_EXTERN DialoG SegregateIdDialog (GrouP g)
14732 {
14733   DialoG dlg;
14734   StringConstraint   scd;
14735 
14736   dlg = StringConstraintDialog (g, "Mark sequences where sequence ID", TRUE, NULL, NULL);
14737   MemSet (&scd, 0, sizeof (StringConstraint));
14738   scd.match_location = eStringConstraintInList;
14739   PointerToDialog (dlg, &scd);
14740   return dlg;
14741 }
14742 
14743 
ChooseCategoriesByStringConstraint(ValNodePtr value_list,StringConstraintPtr scp,Boolean do_choose)14744 static void ChooseCategoriesByStringConstraint (ValNodePtr value_list, StringConstraintPtr scp, Boolean do_choose)
14745 {
14746   ClickableItemPtr cip;
14747 
14748   while (value_list != NULL) {
14749     cip = (ClickableItemPtr) value_list->data.ptrvalue;
14750       if (cip != NULL) {
14751       if (cip->item_list != NULL
14752           && cip->item_list->choice == OBJ_BIOSEQ
14753           && cip->item_list->data.ptrvalue != NULL
14754           && DoesSeqIDListMeetStringConstraint (((BioseqPtr) cip->item_list->data.ptrvalue)->id, scp)) {
14755         cip->chosen = do_choose;
14756       } else {
14757           ChooseCategoriesByStringConstraint (cip->subcategories, scp, do_choose);
14758       }
14759       }
14760       value_list = value_list->next;
14761   }
14762 }
14763 
14764 
ChooseCategoriesForSegregateIdDialog(DialoG d,ValNodePtr list)14765 NLM_EXTERN void ChooseCategoriesForSegregateIdDialog(DialoG d, ValNodePtr list)
14766 {
14767   StringConstraintPtr scp;
14768 
14769   scp = DialogToPointer (d);
14770   ChooseCategoriesByStringConstraint (list, scp, TRUE);
14771   scp = StringConstraintFree (scp);
14772 
14773 }
14774 
14775 
SegregateConstraintDialog(GrouP g)14776 NLM_EXTERN DialoG SegregateConstraintDialog (GrouP g)
14777 {
14778   DialoG dlg;
14779 
14780   dlg = ComplexConstraintDialog (g, NULL, NULL);
14781   ChangeComplexConstraintFieldType (dlg, FieldType_molinfo_field, NULL, Macro_feature_type_any);
14782   return dlg;
14783 }
14784 
14785 
ChooseCategoriesByConstraint(ValNodePtr value_list,ValNodePtr constraint,Boolean do_choose)14786 static void ChooseCategoriesByConstraint (ValNodePtr value_list, ValNodePtr constraint, Boolean do_choose)
14787 {
14788   ClickableItemPtr cip;
14789 
14790   while (value_list != NULL) {
14791     cip = (ClickableItemPtr) value_list->data.ptrvalue;
14792     if (cip != NULL) {
14793       if (cip->item_list != NULL
14794           && DoesObjectMatchConstraintChoiceSet (cip->item_list->choice, cip->item_list->data.ptrvalue, constraint)) {
14795         cip->chosen = do_choose;
14796       } else {
14797           ChooseCategoriesByConstraint (cip->subcategories, constraint, do_choose);
14798       }
14799     }
14800     value_list = value_list->next;
14801   }
14802 }
14803 
14804 
ChooseCategoriesForSegregateConstraintDialog(DialoG d,ValNodePtr list)14805 NLM_EXTERN void ChooseCategoriesForSegregateConstraintDialog(DialoG d, ValNodePtr list)
14806 {
14807   ValNodePtr constraint;
14808 
14809   constraint = DialogToPointer (d);
14810   ChooseCategoriesByConstraint (list, constraint, TRUE);
14811   constraint = ConstraintChoiceSetFree (constraint);
14812 }
14813 
14814 
UnchooseCategoriesForSegregateConstraintDialog(DialoG d,ValNodePtr list)14815 NLM_EXTERN void UnchooseCategoriesForSegregateConstraintDialog(DialoG d, ValNodePtr list)
14816 {
14817   ValNodePtr constraint;
14818 
14819   constraint = DialogToPointer (d);
14820   ChooseCategoriesByConstraint (list, constraint, FALSE);
14821   constraint = ConstraintChoiceSetFree (constraint);
14822 }
14823 
14824 
DomRNAAndProteinMatch(SeqFeatPtr mrna,ProtRefPtr prp)14825 static Boolean DomRNAAndProteinMatch (SeqFeatPtr mrna, ProtRefPtr prp)
14826 {
14827   CharPtr mrna_product;
14828   Boolean rval = FALSE;
14829 
14830   if (mrna == NULL || prp == NULL) {
14831     return FALSE;
14832   }
14833   mrna_product = GetRNARefProductString (mrna->data.value.ptrvalue, NULL);
14834   if (StringHasNoText (mrna_product)) {
14835     if (prp->name == NULL || StringHasNoText (prp->name->data.ptrvalue)) {
14836       rval = TRUE;
14837     }
14838   } else {
14839     if (prp->name != NULL && StringCmp (mrna_product, prp->name->data.ptrvalue) == 0) {
14840       rval = TRUE;
14841     }
14842   }
14843   mrna_product = MemFree (mrna_product);
14844   return rval;
14845 }
14846 
14847 
BulkCDSSetProtein(Pointer target,Pointer data)14848 NLM_EXTERN void BulkCDSSetProtein (Pointer target, Pointer data)
14849 {
14850   SeqFeatXrefPtr xref;
14851   ProtRefPtr     prp = NULL;
14852   BioseqPtr      prot_bsp;
14853   SeqFeatPtr     prot_feat;
14854   SeqMgrFeatContext fcontext;
14855   ValNodePtr        prot_name_list = NULL, vnp;
14856   SeqFeatPtr        sfp, mrna;
14857 
14858   if ((sfp = (SeqFeatPtr) target) == NULL) return;
14859 
14860   prot_name_list = (ValNodePtr) data;
14861 
14862   xref = sfp->xref;
14863   while (xref != NULL && xref->data.choice != SEQFEAT_PROT) {
14864     xref = xref->next;
14865   }
14866   if (xref != NULL) {
14867     prp = xref->data.value.ptrvalue;
14868   }
14869 
14870   if (prp == NULL) {
14871     if (sfp->data.choice == SEQFEAT_PROT) {
14872       prp = (ProtRefPtr) sfp->data.value.ptrvalue;
14873     } else if (sfp->data.choice == SEQFEAT_CDREGION) {
14874       prot_bsp = BioseqFindFromSeqLoc (sfp->product);
14875       prot_feat = SeqMgrGetNextFeature (prot_bsp, NULL, SEQFEAT_PROT, FEATDEF_PROT, &fcontext);
14876       if (prot_feat == NULL && prot_name_list != NULL) {
14877         prot_feat = CreateNewFeatureOnBioseq (prot_bsp, SEQFEAT_PROT, NULL);
14878         prp = ProtRefNew ();
14879         prot_feat->data.value.ptrvalue = prp;
14880           SeqMgrIndexFeatures (prot_bsp->idx.entityID, NULL);
14881       }
14882       if (prot_feat != NULL) {
14883         prp = (ProtRefPtr) prot_feat->data.value.ptrvalue;
14884       }
14885     }
14886   }
14887 
14888   if (prp == NULL && prot_name_list != NULL) {
14889     xref = SeqFeatXrefNew ();
14890     prp = ProtRefNew ();
14891     xref->data.choice = SEQFEAT_PROT;
14892     xref->data.value.ptrvalue = prp;
14893     xref->next = sfp->xref;
14894     sfp->xref = xref;
14895   }
14896 
14897   mrna = SeqMgrGetOverlappingmRNA (sfp->location, &fcontext);
14898   if (mrna != NULL) {
14899     if (!DomRNAAndProteinMatch(mrna, prp)) {
14900       mrna = NULL;
14901     }
14902   }
14903 
14904   if (prp != NULL) {
14905     prp->name = ValNodeFreeData (prp->name);
14906     for (vnp = prot_name_list; vnp != NULL; vnp = vnp->next) {
14907       ValNodeAddPointer (&prp->name, vnp->choice, StringSave (vnp->data.ptrvalue));
14908     }
14909     if (mrna != NULL && prot_name_list != NULL) {
14910       SetRNARefProductString (mrna->data.value.ptrvalue, NULL, prot_name_list->data.ptrvalue, ExistingTextOption_replace_old);
14911     }
14912   }
14913 
14914 }
14915 
14916 
14917 typedef struct stringobjectpair {
14918   CharPtr str;
14919   Uint1   choice;
14920   Pointer data;
14921 } StringObjectPairData, PNTR StringObjectPairPtr;
14922 
14923 
StringObjectPairNew(CharPtr str,Uint1 choice,Pointer data)14924 static StringObjectPairPtr StringObjectPairNew (CharPtr str, Uint1 choice, Pointer data)
14925 {
14926   StringObjectPairPtr sop = (StringObjectPairPtr) MemNew (sizeof (StringObjectPairData));
14927   sop->str = str;
14928   sop->choice = choice;
14929   sop->data = data;
14930   return sop;
14931 }
14932 
14933 
StringObjectPairFree(StringObjectPairPtr sop)14934 static StringObjectPairPtr StringObjectPairFree (StringObjectPairPtr sop)
14935 {
14936   if (sop != NULL) {
14937     sop->str = MemFree (sop->str);
14938     sop = MemFree (sop);
14939   }
14940   return sop;
14941 }
14942 
14943 
StringObjectPairListFree(ValNodePtr list)14944 static ValNodePtr StringObjectPairListFree (ValNodePtr list)
14945 {
14946   ValNodePtr vnp_next;
14947 
14948   while (list != NULL) {
14949     vnp_next = list->next;
14950     list->next = NULL;
14951     list->data.ptrvalue = StringObjectPairFree (list->data.ptrvalue);
14952     list = ValNodeFree (list);
14953     list = vnp_next;
14954   }
14955   return list;
14956 }
14957 
14958 
SortVnpByStringObjectPair(VoidPtr ptr1,VoidPtr ptr2)14959 static int LIBCALLBACK SortVnpByStringObjectPair (VoidPtr ptr1, VoidPtr ptr2)
14960 
14961 {
14962   StringObjectPairPtr     sop1;
14963   StringObjectPairPtr     sop2;
14964   ValNodePtr  vnp1;
14965   ValNodePtr  vnp2;
14966 
14967   if (ptr1 != NULL && ptr2 != NULL) {
14968     vnp1 = *((ValNodePtr PNTR) ptr1);
14969     vnp2 = *((ValNodePtr PNTR) ptr2);
14970     if (vnp1 != NULL && vnp2 != NULL) {
14971       sop1 = (StringObjectPairPtr) vnp1->data.ptrvalue;
14972       sop2 = (StringObjectPairPtr) vnp2->data.ptrvalue;
14973       if (sop1 != NULL && sop2 != NULL) {
14974         return StringCmp (sop1->str, sop2->str);
14975       }
14976     }
14977   }
14978   return 0;
14979 }
14980 
14981 
14982 typedef struct uniqstructuredcomment {
14983   StructuredCommentFieldPtr field;
14984   ValNodeBlock pair_list;
14985 } UniqStructuredCommentData, PNTR UniqStructuredCommentPtr;
14986 
14987 
GetUniqueValuesForStructuredCommentFieldCallback(SeqDescrPtr sdp,Pointer data)14988 static void GetUniqueValuesForStructuredCommentFieldCallback (SeqDescrPtr sdp, Pointer data)
14989 {
14990   UniqStructuredCommentPtr usc;
14991   UserObjectPtr uop;
14992   CharPtr str;
14993 
14994   if (sdp == NULL || sdp->choice != Seq_descr_user
14995       || (uop = (UserObjectPtr) sdp->data.ptrvalue) == NULL
14996       || uop->type == NULL
14997       || StringCmp (uop->type->str, "StructuredComment") != 0
14998       || (usc = (UniqStructuredCommentPtr)data) == NULL) {
14999     return;
15000   }
15001 
15002   str = GetStructuredCommentFieldFromUserObject (uop, usc->field, NULL);
15003   if (str != NULL) {
15004     ValNodeAddPointerToEnd (&(usc->pair_list), 0, StringObjectPairNew(str, OBJ_SEQDESC, sdp));
15005   }
15006 }
15007 
15008 
GetUniqueValuesForStructuredCommentField(SeqEntryPtr sep,CharPtr field_name)15009 NLM_EXTERN ValNodePtr GetUniqueValuesForStructuredCommentField (SeqEntryPtr sep, CharPtr field_name)
15010 {
15011   UniqStructuredCommentData usd;
15012   ValNodePtr list, vnp;
15013   ClickableItemPtr last_cip = NULL;
15014   StringObjectPairPtr sop;
15015   ValNodeBlock cip_list;
15016 
15017   usd.field = ValNodeNew (NULL);
15018   usd.field->choice = StructuredCommentField_named;
15019   usd.field->data.ptrvalue = field_name;
15020   InitValNodeBlock(&(usd.pair_list), NULL);
15021 
15022   VisitDescriptorsInSep (sep, &usd, GetUniqueValuesForStructuredCommentFieldCallback);
15023   usd.field = ValNodeFree (usd.field);
15024   list = usd.pair_list.head;
15025   list = ValNodeSort (list, SortVnpByStringObjectPair);
15026 
15027   InitValNodeBlock(&cip_list, NULL);
15028 
15029   for (vnp = list; vnp != NULL; vnp = vnp->next) {
15030     sop = (StringObjectPairPtr) vnp->data.ptrvalue;
15031     if (sop != NULL) {
15032       if (last_cip == NULL || StringCmp (last_cip->description, sop->str) != 0) {
15033         /* make new category */
15034         last_cip = (ClickableItemPtr) MemNew (sizeof (ClickableItemData));
15035         MemSet (last_cip, 0, sizeof (ClickableItemData));
15036         last_cip->description = sop->str;
15037         sop->str = NULL;
15038         ValNodeAddPointerToEnd (&(cip_list), 0, last_cip);
15039       }
15040       /* add to category */
15041       ValNodeAddPointer (&(last_cip->item_list), sop->choice, sop->data);
15042     }
15043   }
15044   list = StringObjectPairListFree(list);
15045 
15046   return cip_list.head;
15047 }
15048 
15049 
GetStructuredCommentFieldNamesCallback(SeqDescrPtr sdp,Pointer data)15050 static void GetStructuredCommentFieldNamesCallback (SeqDescrPtr sdp, Pointer data)
15051 {
15052   UserObjectPtr uop;
15053   UserFieldPtr  ufp;
15054 
15055   if (sdp != NULL && data != NULL && sdp->choice == Seq_descr_user
15056       && (uop = sdp->data.ptrvalue) != NULL
15057       && IsUserObjectStructuredComment (uop)) {
15058 
15059     ufp = uop->data;
15060     while (ufp != NULL) {
15061       if (ufp->label != NULL && ufp->label->str != NULL
15062           && StringCmp (ufp->label->str, "StructuredCommentPrefix") != 0
15063           && StringCmp (ufp->label->str, "StructuredCommentSuffix") != 0) {
15064         ValNodeAddPointer ((ValNodePtr PNTR) data, 0, StringSave (ufp->label->str));
15065       }
15066       ufp = ufp->next;
15067     }
15068   }
15069 }
15070 
15071 
GetStructuredCommentFieldNames(SeqEntryPtr sep)15072 NLM_EXTERN ValNodePtr GetStructuredCommentFieldNames (SeqEntryPtr sep)
15073 {
15074   ValNodePtr list = NULL;
15075 
15076   VisitDescriptorsInSep (sep, &list, GetStructuredCommentFieldNamesCallback);
15077   list = ValNodeSort (list, SortVnpByString);
15078   ValNodeUnique (&list, SortVnpByString, ValNodeFreeData);
15079   return list;
15080 }
15081 
15082 
15083 typedef struct badqual {
15084   Boolean wrong;
15085   Boolean illegal;
15086   Boolean move_to_note;
15087 } BadQualData, PNTR BadQualPtr;
15088 
RemoveBadQualsCommonCallback(SeqFeatPtr sfp,Pointer data)15089 static void RemoveBadQualsCommonCallback (SeqFeatPtr sfp, Pointer data)
15090 {
15091   BadQualPtr bq;
15092   GBQualPtr  gbqual, gbqual_prev = NULL, gbqual_next;
15093   Int2       index;
15094   Int2       val;
15095   CharPtr    key;
15096   Boolean    do_remove;
15097   CharPtr    note_txt;
15098   CharPtr    note_fmt = "[%s=%s]";
15099   Int4       qvalid;
15100 
15101   if (sfp == NULL || (bq = (BadQualPtr) data) == NULL) {
15102     return;
15103   }
15104   key = GetGBFeatKeyForFeature (sfp);
15105   index = GBFeatKeyNameValid (&key, FALSE);
15106   key = MemFree (key);
15107   if (index < 0) {
15108     return;
15109   }
15110 
15111   for (gbqual = sfp->qual; gbqual != NULL; gbqual = gbqual_next) {
15112     gbqual_next = gbqual->next;
15113     do_remove = FALSE;
15114     qvalid = IsQualValidForFeature(gbqual, sfp);
15115     if (qvalid == 1) {
15116       val = GBQualNameValid (gbqual->qual);
15117       if (bq->illegal && !ShouldBeAGBQual (sfp->idx.subtype, val, FALSE)) {
15118         if (val != GBQUAL_experiment && val != GBQUAL_inference && val != GBQUAL_pseudogene) {
15119           do_remove = TRUE;
15120         }
15121       }
15122     } else {
15123       if (bq->illegal && (val = GBQualNameValid (gbqual->qual)) == -1) {
15124         do_remove = TRUE;
15125       } else if (bq->wrong && (qvalid == 0 || qvalid > 1)) {
15126         do_remove = TRUE;
15127       }
15128     }
15129     if (do_remove) {
15130       if (bq->move_to_note) {
15131         note_txt = (CharPtr) MemNew (sizeof (Char) * (StringLen (note_fmt) + StringLen (gbqual->qual) + StringLen (gbqual->val)));
15132         sprintf (note_txt, note_fmt, gbqual->qual == NULL ? "" : gbqual->qual, gbqual->val == NULL ? "" : gbqual->val);
15133         SetStringValue (&(sfp->comment), note_txt, ExistingTextOption_append_semi);
15134         note_txt = MemFree (note_txt);
15135       }
15136       if (gbqual_prev == NULL) {
15137         sfp->qual = gbqual_next;
15138       } else {
15139         gbqual_prev->next = gbqual_next;
15140       }
15141       gbqual->next = NULL;
15142       gbqual = GBQualFree (gbqual);
15143     } else {
15144       gbqual_prev = gbqual;
15145     }
15146   }
15147 }
15148 
15149 
RemoveBadQualsCommon(Uint2 entityID,Boolean wrong,Boolean illegal,Boolean move_to_note)15150 NLM_EXTERN void RemoveBadQualsCommon (Uint2 entityID, Boolean wrong, Boolean illegal, Boolean move_to_note)
15151 {
15152   SeqEntryPtr  sep;
15153   BadQualData  bq;
15154 
15155 
15156   sep = GetTopSeqEntryForEntityID (entityID);
15157   if (sep == NULL) {
15158     return;
15159   }
15160 
15161   bq.wrong = wrong;
15162   bq.illegal = illegal;
15163   bq.move_to_note = move_to_note;
15164 
15165   VisitFeaturesInSep (sep, &bq, RemoveBadQualsCommonCallback);
15166 
15167   ObjMgrSetDirtyFlag (entityID, TRUE);
15168   ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
15169   Update();
15170 }
15171 
15172 
RemoveBadQualsCommonItem(IteM i,Boolean wrong,Boolean illegal,Boolean move_to_note)15173 static void RemoveBadQualsCommonItem (IteM i, Boolean wrong, Boolean illegal, Boolean move_to_note)
15174 {
15175   BaseFormPtr  bfp;
15176 #ifdef WIN_MAC
15177   bfp = currentFormDataPtr;
15178 #else
15179   bfp = GetObjectExtra (i);
15180 #endif
15181   if (bfp == NULL || bfp->input_entityID == 0) return;
15182 
15183   RemoveBadQualsCommon (bfp->input_entityID, wrong, illegal, move_to_note);
15184 }
15185 
15186 
RemoveIllegalQuals(IteM i)15187 NLM_EXTERN void RemoveIllegalQuals (IteM i)
15188 {
15189   RemoveBadQualsCommonItem (i, FALSE, TRUE, FALSE);
15190 }
15191 
15192 
RemoveWrongQuals(IteM i)15193 NLM_EXTERN void RemoveWrongQuals (IteM i)
15194 {
15195   RemoveBadQualsCommonItem (i, TRUE, FALSE, FALSE);
15196 }
15197 
15198 
MoveIllegalQuals(IteM i)15199 NLM_EXTERN void MoveIllegalQuals (IteM i)
15200 {
15201   RemoveBadQualsCommonItem (i, FALSE, TRUE, TRUE);
15202 }
15203 
15204 
MoveWrongQuals(IteM i)15205 NLM_EXTERN void MoveWrongQuals (IteM i)
15206 {
15207   RemoveBadQualsCommonItem (i, TRUE, FALSE, TRUE);
15208 }
15209 
15210 
GetProteinSeqIdFromBioseq(BioseqPtr bsp)15211 static SeqIdPtr GetProteinSeqIdFromBioseq (BioseqPtr bsp)
15212 {
15213   SeqIdPtr sip;
15214   DbtagPtr dbtag;
15215 
15216   if (bsp == NULL) {
15217     return NULL;
15218   }
15219   for (sip = bsp->id; sip != NULL; sip = sip->next) {
15220     if (sip->choice == SEQID_GENERAL
15221         && (dbtag = (DbtagPtr) sip->data.ptrvalue) != NULL
15222         && !IsSkippableDbtag(dbtag)) {
15223       return sip;
15224     }
15225   }
15226   return NULL;
15227 }
15228 
15229 
FindProteinIDDBCallback(BioseqPtr bsp,Pointer data)15230 static void FindProteinIDDBCallback (BioseqPtr bsp, Pointer data)
15231 {
15232   CharPtr PNTR pDb;
15233   SeqIdPtr sip;
15234   DbtagPtr dbtag;
15235 
15236   if (bsp == NULL || !ISA_aa(bsp->mol) || (pDb = (CharPtr PNTR)data) == NULL || *pDb != NULL) {
15237     return;
15238   }
15239 
15240   sip = GetProteinSeqIdFromBioseq (bsp);
15241   if (sip != NULL
15242       && (dbtag = (DbtagPtr) sip->data.ptrvalue) != NULL
15243       && !IsSkippableDbtag(dbtag)) {
15244     *pDb = StringSave (dbtag->db);
15245   }
15246 }
15247 
15248 
15249 
CreateOneProteinId(BioseqPtr bsp,CharPtr db,CharPtr locus_tag,LogInfoPtr lip)15250 static void CreateOneProteinId (BioseqPtr bsp, CharPtr db, CharPtr locus_tag, LogInfoPtr lip)
15251 {
15252   SeqIdPtr sip;
15253   DbtagPtr dbtag;
15254   SeqEntryPtr sep;
15255   SeqIdPtr sip_local = NULL, sip_last = NULL;
15256   Char     id1[255];
15257   Char     id2[255];
15258 
15259   for (sip = bsp->id; sip != NULL; sip = sip->next) {
15260     if (sip->choice == SEQID_GENERAL
15261         && (dbtag = (DbtagPtr) sip->data.ptrvalue) != NULL
15262         && !IsSkippableDbtag(dbtag)) {
15263       return;
15264     }
15265     if (sip->choice == SEQID_LOCAL) {
15266       sip_local = sip;
15267     }
15268     sip_last = sip;
15269   }
15270 
15271   sip = ValNodeNew(NULL);
15272   sip->choice = SEQID_GENERAL;
15273   dbtag = DbtagNew ();
15274   dbtag->db = StringSave (db);
15275   dbtag->tag = ObjectIdNew();
15276   dbtag->tag->str = StringSave (locus_tag);
15277   sip->data.ptrvalue = dbtag;
15278   SeqIdWrite (sip, id2, PRINTID_REPORT, sizeof (id2) - 1);
15279   if (sip_local == NULL) {
15280     SeqIdWrite (SeqIdFindWorst (bsp->id), id1, PRINTID_REPORT, sizeof (id1) - 1);
15281     if (sip_last == NULL) {
15282       bsp->id = sip;
15283     } else {
15284       sip_last->next = sip;
15285     }
15286     /* replace in bioseq index */
15287     SeqMgrReplaceInBioseqIndex (bsp);
15288     if (lip != NULL) {
15289       fprintf (lip->fp, "Added protein ID %s to Bioseq %s\n", id2, id1);
15290       lip->data_in_log = TRUE;
15291     }
15292   } else {
15293     SeqIdWrite (sip_local, id1, PRINTID_REPORT, sizeof (id1) - 1);
15294     sep = GetTopSeqEntryForEntityID (bsp->idx.entityID);
15295     ReplaceSeqIdWithSeqId (sip_local, sip, sep);
15296     sip = SeqIdFree (sip);
15297     if (lip != NULL) {
15298       fprintf (lip->fp, "Replaced protein ID %s with %s\n", id1, id2);
15299       lip->data_in_log = TRUE;
15300     }
15301   }
15302 }
15303 
15304 
CreateProteinIDsCallback(BioseqPtr bsp,Pointer data)15305 static void CreateProteinIDsCallback (BioseqPtr bsp, Pointer data)
15306 {
15307   CharPtr db;
15308   SeqIdPtr sip;
15309   DbtagPtr dbtag;
15310   SeqFeatPtr cds, gene = NULL;
15311   GeneRefPtr grp = NULL;
15312   SeqMgrFeatContext context;
15313 
15314   if (bsp == NULL || !ISA_aa(bsp->mol) || (db = (CharPtr)data) == NULL) {
15315     return;
15316   }
15317 
15318   for (sip = bsp->id; sip != NULL; sip = sip->next) {
15319     if (sip->choice == SEQID_GENERAL
15320         && (dbtag = (DbtagPtr) sip->data.ptrvalue) != NULL
15321         && !IsSkippableDbtag(dbtag)) {
15322       return;
15323     }
15324   }
15325 
15326   cds = SeqMgrGetCDSgivenProduct (bsp, &context);
15327   if (cds == NULL) {
15328     return;
15329   }
15330   GetGeneInfoForFeature (cds, &grp, &gene);
15331   if (grp != NULL && !StringHasNoText (grp->locus_tag)) {
15332     CreateOneProteinId (bsp, db, grp->locus_tag, NULL);
15333   }
15334 
15335 }
15336 
15337 
15338 typedef struct justtextform {
15339   FORM_MESSAGE_BLOCK
15340   TexT       db_txt;
15341 } JustTextFormData, PNTR JustTextFormPtr;
15342 
15343 
DoCreateProteinIDs(ButtoN b)15344 static void DoCreateProteinIDs (ButtoN b)
15345 {
15346   JustTextFormPtr frm;
15347   CharPtr db;
15348   SeqEntryPtr sep;
15349 
15350   frm = (JustTextFormPtr) GetObjectExtra (b);
15351   if (frm == NULL) {
15352     return;
15353   } else if (TextHasNoText (frm->db_txt)) {
15354     Message (MSG_ERROR, "Must provide database tag!");
15355     return;
15356   }
15357 
15358   sep = GetTopSeqEntryForEntityID (frm->input_entityID);
15359 
15360   WatchCursor();
15361   Update();
15362   db = SaveStringFromText (frm->db_txt);
15363   VisitBioseqsInSep (sep, db, CreateProteinIDsCallback);
15364   db = MemFree (db);
15365   ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
15366   ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
15367   Remove (frm->form);
15368   ArrowCursor();
15369   Update();
15370 }
15371 
15372 
CreateProteinIDs(IteM i)15373 NLM_EXTERN void CreateProteinIDs (IteM i)
15374 {
15375   BaseFormPtr  bfp;
15376   SeqEntryPtr  sep;
15377   JustTextFormPtr frm;
15378   WindoW       w;
15379   GrouP        h, g, c;
15380   ButtoN       b;
15381   CharPtr      db = NULL;
15382 
15383 #ifdef WIN_MAC
15384   bfp = currentFormDataPtr;
15385 #else
15386   bfp = GetObjectExtra (i);
15387 #endif
15388   if (bfp == NULL) return;
15389 
15390   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
15391   VisitBioseqsInSep (sep, &db, FindProteinIDDBCallback);
15392 
15393   frm = (JustTextFormPtr) MemNew (sizeof (JustTextFormData));
15394 
15395   w = FixedWindow (-50, -33, -10, -10, "Create Protein IDs", StdCloseWindowProc);
15396   SetObjectExtra (w, frm, StdCleanupExtraProc);
15397   h = HiddenGroup (w, -1, 0, NULL);
15398   SetGroupSpacing (h, 10, 10);
15399   frm->form = (ForM) w;
15400   frm->input_entityID = bfp->input_entityID;
15401 
15402   g = HiddenGroup (h, 2, 0, NULL);
15403   StaticPrompt (g, "Database", 0, dialogTextHeight, programFont, 'c');
15404   frm->db_txt = DialogText (g, db, 14, NULL);
15405   db = MemFree (db);
15406 
15407   c = HiddenGroup (h, 2, 0, NULL);
15408   b = DefaultButton (c, "Accept", DoCreateProteinIDs);
15409   SetObjectExtra (b, frm, NULL);
15410   PushButton (c, "Cancel", StdCancelButtonProc);
15411   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
15412 
15413   Show (w);
15414 
15415 }
15416 
15417 
15418 typedef struct existinglocustag {
15419   CharPtr prefix;
15420   Int4    num_digits;
15421   Int4    max;
15422   CharPtr id_db;
15423   LogInfoPtr lip;
15424 } ExistingLocusTagData, PNTR ExistingLocusTagPtr;
15425 
15426 
GetLocusTagPrefixLen(CharPtr str)15427 static Int4 GetLocusTagPrefixLen (CharPtr str)
15428 
15429 {
15430   Int4    len;
15431 
15432   if (StringHasNoText (str)) return 0;
15433 
15434   len = StringLen (str) - 1;
15435 
15436   while (len > 0 && isdigit (*(str + len))) {
15437     len--;
15438   }
15439   return len;
15440 }
15441 
15442 
PopulateExistingLocusTag(ExistingLocusTagPtr pLocusTag,CharPtr locus_tag)15443 static void PopulateExistingLocusTag (ExistingLocusTagPtr pLocusTag, CharPtr locus_tag)
15444 {
15445   Int4 prefix_len;
15446   Int4 val;
15447   Int4 num_digits;
15448 
15449   if (pLocusTag == NULL || StringHasNoText (locus_tag)
15450       || (prefix_len = GetLocusTagPrefixLen(locus_tag)) < 1) {
15451     return;
15452   }
15453 
15454   if (pLocusTag->prefix == NULL) {
15455     pLocusTag->prefix = (CharPtr) MemNew (sizeof (Char) * (prefix_len + 1));
15456     StringNCpy (pLocusTag->prefix, locus_tag, prefix_len);
15457     pLocusTag->prefix[prefix_len] = 0;
15458   }
15459   if (StringNCmp (locus_tag, pLocusTag->prefix, prefix_len) == 0) {
15460     num_digits = StringLen (locus_tag + prefix_len + 1);
15461     if (pLocusTag->num_digits < num_digits) {
15462       pLocusTag->num_digits = num_digits;
15463     }
15464     val = atol (locus_tag + prefix_len + 1);
15465     if (val > pLocusTag->max) {
15466       pLocusTag->max = val;
15467     }
15468   }
15469 }
15470 
15471 
FindGenePrefix(SeqFeatPtr sfp,Pointer data)15472 static void FindGenePrefix (SeqFeatPtr sfp, Pointer data)
15473 {
15474   ExistingLocusTagPtr pLocusTag;
15475   GeneRefPtr grp;
15476 
15477   if (sfp == NULL
15478       || sfp->data.choice != SEQFEAT_GENE
15479       || (pLocusTag = (ExistingLocusTagPtr)data) == NULL
15480       || (grp = (GeneRefPtr) sfp->data.value.ptrvalue) == NULL) {
15481     return;
15482   }
15483 
15484   PopulateExistingLocusTag (pLocusTag, grp->locus_tag);
15485 }
15486 
15487 
FindGeneLocusTagFromProteinID(BioseqPtr bsp,Pointer data)15488 static void FindGeneLocusTagFromProteinID (BioseqPtr bsp, Pointer data)
15489 {
15490   ExistingLocusTagPtr pLocusTag;
15491   SeqIdPtr sip;
15492   DbtagPtr dbtag;
15493 
15494   if (bsp == NULL || !ISA_aa (bsp->mol)
15495       || (pLocusTag = (ExistingLocusTagPtr)data) == NULL) {
15496     return;
15497   }
15498 
15499   sip = GetProteinSeqIdFromBioseq (bsp);
15500   if (sip != NULL
15501       && (dbtag = (DbtagPtr) sip->data.ptrvalue) != NULL
15502       && !IsSkippableDbtag(dbtag)) {
15503     PopulateExistingLocusTag (pLocusTag, dbtag->tag->str);
15504     if (pLocusTag->id_db == NULL) {
15505       pLocusTag->id_db = StringSave (dbtag->db);
15506     }
15507   }
15508 }
15509 
15510 
FeatureSubtypeWantsLocusTagGene(Int4 featdef)15511 static Boolean FeatureSubtypeWantsLocusTagGene (Int4 featdef)
15512 {
15513   if (featdef == FEATDEF_CDS
15514       || featdef == FEATDEF_tRNA
15515       || featdef == FEATDEF_rRNA
15516       || featdef == FEATDEF_tmRNA
15517       || featdef == FEATDEF_ncRNA) {
15518     return TRUE;
15519   } else {
15520     return FALSE;
15521   }
15522 }
15523 
15524 
CreateLocusTagGenesCallback(SeqFeatPtr sfp,Pointer data)15525 static void CreateLocusTagGenesCallback (SeqFeatPtr sfp, Pointer data)
15526 {
15527   ExistingLocusTagPtr locus_data;
15528   SeqFeatPtr gene = NULL, mrna;
15529   GeneRefPtr grp = NULL;
15530   Char buf[15];
15531   BioseqPtr bsp, pbsp = NULL;
15532   SeqLocPtr gene_loc;
15533   DbtagPtr  dbtag = NULL;
15534   SeqIdPtr  sip;
15535   Char      fmt_buf[30];
15536   ValNode   vn;
15537   CharPtr   txt;
15538   Boolean   created_gene = FALSE;
15539 
15540   /* create locus tag genes for features that don't have them */
15541   if (sfp == NULL || !FeatureSubtypeWantsLocusTagGene(sfp->idx.subtype) || (locus_data = (ExistingLocusTagPtr) data) == NULL) {
15542     return;
15543   }
15544 
15545   if (sfp->idx.subtype == FEATDEF_CDS) {
15546     pbsp = BioseqFindFromSeqLoc (sfp->product);
15547     sip = GetProteinSeqIdFromBioseq (pbsp);
15548     if (sip != NULL) {
15549       dbtag = (DbtagPtr) sip->data.ptrvalue;
15550     }
15551   }
15552 
15553   GetGeneInfoForFeature (sfp, &grp, &gene);
15554   if (grp == NULL) {
15555     bsp = BioseqFindFromSeqLoc (sfp->location);
15556     if (bsp != NULL) {
15557       mrna = GetmRNAforCDS(sfp);
15558       if (mrna == NULL) {
15559         gene_loc = SeqLocMerge (bsp, sfp->location, NULL, TRUE, FALSE, FALSE);
15560       } else {
15561         gene_loc = SeqLocMerge (bsp, mrna->location, NULL, TRUE, FALSE, FALSE);
15562       }
15563       if (gene_loc != NULL) {
15564         gene = CreateNewFeatureOnBioseq (bsp, SEQFEAT_GENE, gene_loc);
15565         gene_loc = SeqLocFree (gene_loc);
15566         grp = GeneRefNew ();
15567         gene->data.value.ptrvalue = grp;
15568         created_gene = TRUE;
15569       }
15570     }
15571   }
15572   if (grp != NULL && StringHasNoText (grp->locus_tag)) {
15573     grp->locus_tag = MemFree (grp->locus_tag);
15574 
15575     if (dbtag != NULL && dbtag->tag != NULL && !StringHasNoText (dbtag->tag->str))
15576     {
15577       grp->locus_tag = StringSave (dbtag->tag->str);
15578     } else {
15579       sprintf (fmt_buf, "%%0%dd", locus_data->num_digits);
15580       sprintf (buf, fmt_buf, locus_data->max + 5);
15581 
15582       grp->locus_tag = (CharPtr) MemNew (sizeof (Char) * (StringLen (locus_data->prefix) + StringLen (buf) + 2));
15583       sprintf (grp->locus_tag, "%s_%s", locus_data->prefix, buf);
15584       locus_data->max += 5;
15585     }
15586     if (locus_data->lip != NULL) {
15587       MemSet (&vn, 0, sizeof (ValNode));
15588       vn.choice = OBJ_SEQFEAT;
15589       vn.data.ptrvalue = sfp;
15590       txt = GetDiscrepancyItemText (&vn);
15591 
15592       if (locus_data->lip->fp != NULL) {
15593         fprintf (locus_data->lip->fp, "Added locus tag %s%s for %s\n",
15594                                       grp->locus_tag,
15595                                       created_gene ? " (and created gene)":"",
15596                                       txt);
15597       }
15598       locus_data->lip->data_in_log = TRUE;
15599       txt = MemFree (txt);
15600     }
15601 
15602     if (pbsp != NULL && !StringHasNoText (locus_data->id_db)) {
15603       CreateOneProteinId (pbsp, locus_data->id_db, grp->locus_tag, locus_data->lip);
15604     }
15605   }
15606 }
15607 
15608 
15609 typedef struct locustaggeneform {
15610   FORM_MESSAGE_BLOCK
15611   TexT       prefix_txt;
15612   ButtoN     also_protein_ids;
15613   TexT       db_txt;
15614 
15615   ExistingLocusTagData locus_data;
15616 } LocusTagGeneFormData, PNTR LocusTagGeneFormPtr;
15617 
15618 
CleanupLocusTagGeneForm(GraphiC g,VoidPtr data)15619 static void CleanupLocusTagGeneForm (
15620   GraphiC g,
15621   VoidPtr data
15622 )
15623 
15624 {
15625   LocusTagGeneFormPtr frm;
15626 
15627   frm = (LocusTagGeneFormPtr) data;
15628   if (frm != NULL) {
15629     frm->locus_data.prefix = MemFree (frm->locus_data.prefix);
15630     frm->locus_data.id_db = MemFree (frm->locus_data.id_db);
15631   }
15632   StdCleanupFormProc (g, data);
15633 }
15634 
15635 
DoCreateLocusTagGenes(ButtoN b)15636 static void DoCreateLocusTagGenes (ButtoN b)
15637 {
15638   LocusTagGeneFormPtr frm;
15639   SeqEntryPtr sep;
15640 
15641   frm = (LocusTagGeneFormPtr) GetObjectExtra (b);
15642   if (frm == NULL || TextHasNoText (frm->prefix_txt)) {
15643     return;
15644   }
15645   frm->locus_data.prefix = MemFree (frm->locus_data.prefix);
15646   frm->locus_data.prefix = SaveStringFromText (frm->prefix_txt);
15647   frm->locus_data.id_db = MemFree (frm->locus_data.id_db);
15648   if (GetStatus (frm->also_protein_ids)) {
15649     frm->locus_data.id_db = SaveStringFromText (frm->db_txt);
15650   }
15651 
15652   sep = GetTopSeqEntryForEntityID (frm->input_entityID);
15653   WatchCursor();
15654   Update();
15655   frm->locus_data.lip = OpenLog ("Locus Tags Created");
15656   VisitFeaturesInSep (sep, &(frm->locus_data), CreateLocusTagGenesCallback);
15657   CloseLog (frm->locus_data.lip);
15658   frm->locus_data.lip = FreeLog (frm->locus_data.lip);
15659   ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
15660   ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
15661   Remove (frm->form);
15662   ArrowCursor();
15663   Update();
15664 }
15665 
15666 
AlsoProteinIdsBtn(ButtoN b)15667 static void AlsoProteinIdsBtn (ButtoN b)
15668 {
15669   LocusTagGeneFormPtr frm;
15670 
15671   frm = (LocusTagGeneFormPtr) GetObjectExtra (b);
15672   if (frm == NULL) {
15673     return;
15674   }
15675 
15676   if (GetStatus (frm->also_protein_ids)) {
15677     Enable (frm->db_txt);
15678   } else {
15679     Disable (frm->db_txt);
15680   }
15681 }
15682 
15683 
AddLocusTagGenes(IteM i)15684 NLM_EXTERN void AddLocusTagGenes (IteM i)
15685 {
15686   BaseFormPtr         bfp;
15687   SeqEntryPtr         sep;
15688   LocusTagGeneFormPtr frm;
15689   WindoW              w;
15690   GrouP               h, g, g2, c;
15691   ButtoN              b;
15692 
15693 #ifdef WIN_MAC
15694   bfp = currentFormDataPtr;
15695 #else
15696   bfp = GetObjectExtra (i);
15697 #endif
15698   if (bfp == NULL) return;
15699 
15700   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
15701 
15702   frm = (LocusTagGeneFormPtr) MemNew (sizeof (LocusTagGeneFormData));
15703   frm->locus_data.prefix = NULL;
15704   frm->locus_data.max = 0;
15705   VisitFeaturesInSep (sep, &(frm->locus_data), FindGenePrefix);
15706   VisitBioseqsInSep (sep, &(frm->locus_data), FindGeneLocusTagFromProteinID);
15707   if (frm->locus_data.num_digits < 1) {
15708     frm->locus_data.num_digits = 4;
15709   }
15710 
15711   w = FixedWindow (-50, -33, -10, -10, "Create locus_tag genes", StdCloseWindowProc);
15712   SetObjectExtra (w, frm, CleanupLocusTagGeneForm);
15713 
15714   h = HiddenGroup (w, -1, 0, NULL);
15715   SetGroupSpacing (h, 10, 10);
15716   frm->form = (ForM) w;
15717   frm->input_entityID = bfp->input_entityID;
15718 
15719   g = HiddenGroup (h, 2, 0, NULL);
15720   StaticPrompt (g, "Prefix", 0, dialogTextHeight, programFont, 'c');
15721   frm->prefix_txt = DialogText (g, frm->locus_data.prefix, 14, NULL);
15722 
15723   g2 = HiddenGroup (h, 2, 0, NULL);
15724   frm->also_protein_ids = CheckBox (g2, "Also create protein IDs with database:", AlsoProteinIdsBtn);
15725   SetObjectExtra (frm->also_protein_ids, frm, NULL);
15726   frm->db_txt = DialogText (g2, frm->locus_data.id_db, 14, NULL);
15727   Disable (frm->db_txt);
15728 
15729   c = HiddenGroup (h, 2, 0, NULL);
15730   b = DefaultButton (c, "Accept", DoCreateLocusTagGenes);
15731   SetObjectExtra (b, frm, NULL);
15732   PushButton (c, "Cancel", StdCancelButtonProc);
15733   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
15734 
15735   Show (w);
15736 
15737 }
15738 
15739 
ExtendCodingRegionEnds(IteM i)15740 NLM_EXTERN void ExtendCodingRegionEnds (IteM i)
15741 {
15742   BaseFormPtr         bfp;
15743   SeqEntryPtr         sep;
15744   EditFeatureLocationActionPtr a1, a2;
15745   LocationConstraintPtr lcp;
15746   ValNodePtr          m_list = NULL;
15747 
15748 #ifdef WIN_MAC
15749   bfp = currentFormDataPtr;
15750 #else
15751   bfp = GetObjectExtra (i);
15752 #endif
15753   if (bfp == NULL) return;
15754 
15755   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
15756 
15757   a1 = EditFeatureLocationActionNew ();
15758   a1->type = Macro_feature_type_cds;
15759   a1->action = ValNodeNew (NULL);
15760   a1->action->choice = LocationEditType_extend_5;
15761   a1->retranslate_cds = TRUE;
15762   a1->also_edit_gene = TRUE;
15763   lcp = LocationConstraintNew ();
15764   lcp->end5 = ValNodeNew (NULL);
15765   lcp->end5->choice = LocationPosConstraint_max_dist_from_end;
15766   lcp->end5->data.intvalue = 4;
15767   lcp->partial5 = Partial_constraint_partial;
15768   a1->constraint = ValNodeNew (NULL);
15769   a1->constraint->choice = ConstraintChoice_location;
15770   a1->constraint->data.ptrvalue = lcp;
15771 
15772   ValNodeAddPointer (&m_list, MacroActionChoice_edit_location, a1);
15773 
15774   a2 = EditFeatureLocationActionNew ();
15775   a2->type = Macro_feature_type_cds;
15776   a2->action = ValNodeNew (NULL);
15777   a2->action->choice = LocationEditType_extend_3;
15778   a2->retranslate_cds = TRUE;
15779   a2->also_edit_gene = TRUE;
15780   lcp = LocationConstraintNew ();
15781   lcp->end3 = ValNodeNew (NULL);
15782   lcp->end3->choice = LocationPosConstraint_max_dist_from_end;
15783   lcp->end3->data.intvalue = 4;
15784   lcp->partial3 = Partial_constraint_partial;
15785   a2->constraint = ValNodeNew (NULL);
15786   a2->constraint->choice = ConstraintChoice_location;
15787   a2->constraint->data.ptrvalue = lcp;
15788 
15789   ValNodeAddPointer (&m_list, MacroActionChoice_edit_location, a2);
15790 
15791   ApplyMacroToSeqEntryEx(sep, m_list, NULL, Sequin_GlobalAlign2Seq);
15792   m_list = MacroActionListFree (m_list);
15793   Update();
15794 }
15795 
15796 
15797 typedef struct removeidform {
15798   FORM_MESSAGE_BLOCK
15799 
15800   DialoG db_constraint;
15801 } RemoveIdFormData, PNTR RemoveIdFormPtr;
15802 
15803 
15804 typedef struct removeid {
15805   ValNodePtr list;
15806   StringConstraintPtr scp;
15807 } RemoveIdData, PNTR RemoveIdPtr;
15808 
15809 
SeqIdMatchesGeneralConstraint(SeqIdPtr sip,StringConstraintPtr scp)15810 static Boolean SeqIdMatchesGeneralConstraint (SeqIdPtr sip, StringConstraintPtr scp)
15811 {
15812   DbtagPtr dbtag;
15813 
15814   if (sip == NULL) {
15815     return FALSE;
15816   } else if (sip->choice != SEQID_GENERAL || (dbtag = (DbtagPtr)sip->data.ptrvalue) == NULL) {
15817     return FALSE;
15818   } else if (DoesStringMatchConstraint (dbtag->db, scp)) {
15819     return TRUE;
15820   } else {
15821     return FALSE;
15822   }
15823 }
15824 
15825 
GetBioseqsForIdRemovalCallback(BioseqPtr bsp,Pointer data)15826 static void GetBioseqsForIdRemovalCallback (BioseqPtr bsp, Pointer data)
15827 {
15828   RemoveIdPtr r;
15829   SeqIdPtr sip;
15830 
15831   if (bsp == NULL || (r = (RemoveIdPtr)data) == NULL) {
15832     return;
15833   }
15834 
15835   for (sip = bsp->id; sip != NULL; sip = sip->next) {
15836     if (SeqIdMatchesGeneralConstraint(sip, r->scp)) {
15837       ValNodeAddPointer (&(r->list), OBJ_BIOSEQ, bsp);
15838       break;
15839     }
15840   }
15841 }
15842 
15843 
DoRemoveGeneralIds(ButtoN b)15844 static void DoRemoveGeneralIds (ButtoN b)
15845 {
15846   RemoveIdFormPtr frm;
15847   RemoveIdData    r;
15848   SeqEntryPtr     sep;
15849   Int4            num_unable = 0;
15850   ValNodePtr      vnp;
15851   BioseqPtr       bsp;
15852   SeqIdPtr        sip, sip_good, sip_bad = NULL;
15853   Boolean         found;
15854 
15855   frm = (RemoveIdFormPtr) GetObjectExtra (b);
15856   if (frm == NULL) {
15857     return;
15858   }
15859 
15860   sep = GetTopSeqEntryForEntityID (frm->input_entityID);
15861 
15862   r.list = NULL;
15863   r.scp = DialogToPointer (frm->db_constraint);
15864 
15865   VisitBioseqsInSep (sep, &r, GetBioseqsForIdRemovalCallback);
15866   if (r.list == NULL) {
15867     Message (MSG_ERROR, "No general sequence IDs match your constraint");
15868     r.scp = StringConstraintFree (r.scp);
15869     return;
15870   }
15871 
15872   for (vnp = r.list; vnp != NULL; vnp = vnp->next) {
15873     bsp = (BioseqPtr) vnp->data.ptrvalue;
15874     sip = SeqIdFindWorst (bsp->id);
15875     if (SeqIdMatchesGeneralConstraint(sip, r.scp)) {
15876       num_unable++;
15877     }
15878   }
15879   if (num_unable > 0) {
15880     if (Message (MSG_OKC, "%d bioseqs have no non-matching sequence IDs.  Remove sequence IDs from the rest?") == ANS_CANCEL) {
15881       r.scp = StringConstraintFree (r.scp);
15882       r.list = ValNodeFree (r.list);
15883       return;
15884     }
15885   }
15886 
15887   for (vnp = r.list; vnp != NULL; vnp = vnp->next) {
15888     bsp = (BioseqPtr) vnp->data.ptrvalue;
15889     sip_good = SeqIdFindWorst (bsp->id);
15890     if (SeqIdMatchesGeneralConstraint(sip_good, r.scp)) {
15891       /* skip it */
15892     } else {
15893       found = TRUE;
15894       while (found) {
15895         found = FALSE;
15896         for (sip = bsp->id; sip != NULL && !found; sip = sip->next) {
15897           if (SeqIdMatchesGeneralConstraint(sip, r.scp)) {
15898             sip_bad = SeqIdDup (sip);
15899             found = TRUE;
15900           }
15901         }
15902         if (found) {
15903           ReplaceSeqIdWithSeqId (sip_bad, sip_good, sep);
15904           sip_bad = SeqIdFree (sip_bad);
15905         }
15906       }
15907     }
15908   }
15909   ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
15910   ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
15911   Remove (frm->form);
15912 }
15913 
15914 
RemoveGeneralIds(IteM i)15915 NLM_EXTERN void RemoveGeneralIds (IteM i)
15916 {
15917   BaseFormPtr     bfp;
15918   RemoveIdFormPtr frm;
15919   WindoW          w;
15920   GrouP           h, c;
15921   ButtoN          b;
15922 
15923 #ifdef WIN_MAC
15924   bfp = currentFormDataPtr;
15925 #else
15926   bfp = GetObjectExtra (i);
15927 #endif
15928   if (bfp == NULL) return;
15929 
15930 
15931   frm = (RemoveIdFormPtr) MemNew (sizeof (RemoveIdFormData));
15932 
15933   w = FixedWindow (-50, -33, -10, -10, "Remove Sequence IDs", StdCloseWindowProc);
15934   SetObjectExtra (w, frm, StdCleanupFormProc);
15935 
15936   h = HiddenGroup (w, -1, 0, NULL);
15937   SetGroupSpacing (h, 10, 10);
15938   frm->form = (ForM) w;
15939   frm->input_entityID = bfp->input_entityID;
15940 
15941   frm->db_constraint = StringConstraintDialog (h, "Remove general sequence IDs where database", TRUE, NULL, NULL);
15942 
15943   c = HiddenGroup (h, 2, 0, NULL);
15944   b = DefaultButton (c, "Accept", DoRemoveGeneralIds);
15945   SetObjectExtra (b, frm, NULL);
15946   PushButton (c, "Cancel", StdCancelButtonProc);
15947   AlignObjects (ALIGN_CENTER, (HANDLE) frm->db_constraint, (HANDLE) c, NULL);
15948 
15949   Show (w);
15950 
15951 }
15952 
15953 
15954 typedef enum
15955 {
15956   eSeqIdEdit_local = 1,
15957   eSeqIdEdit_general_db,
15958   eSeqIdEdit_general_tag
15959 } ESeqIdEditType;
15960 
15961 typedef struct editseqid {
15962   Int4 id_type;
15963   CharPtr prefix;
15964   CharPtr suffix;
15965   TextPortionPtr text_portion;
15966   StringConstraintPtr db_constraint;
15967   SequenceConstraintPtr seq_constraint;
15968   SeqEntryPtr top_sep;
15969 } EditSeqIdData, PNTR EditSeqIdPtr;
15970 
15971 
ApplySeqIdEditToString(EditSeqIdPtr e,CharPtr PNTR str)15972 static Boolean ApplySeqIdEditToString (EditSeqIdPtr e, CharPtr PNTR str)
15973 {
15974   CharPtr tmp;
15975   Boolean rval = FALSE;
15976 
15977   if (e == NULL || str == NULL) {
15978     return FALSE;
15979   }
15980   if (e->text_portion != NULL) {
15981     tmp = GetTextPortionFromString (*str, e->text_portion);
15982     *str = MemFree (*str);
15983     *str = tmp;
15984     rval = TRUE;
15985   }
15986   if (!StringHasNoText (e->prefix)) {
15987     SetStringValue (str, e->prefix, ExistingTextOption_prefix_none);
15988     rval = TRUE;
15989   }
15990   if (!StringHasNoText (e->suffix)) {
15991     SetStringValue (str, e->suffix, ExistingTextOption_append_none);
15992     rval = TRUE;
15993   }
15994   return rval;
15995 }
15996 
15997 
ApplySeqIdEditToObjectId(EditSeqIdPtr e,ObjectIdPtr o)15998 static Boolean ApplySeqIdEditToObjectId (EditSeqIdPtr e, ObjectIdPtr o)
15999 {
16000   Char sbuf[20];
16001   CharPtr tmp;
16002   Boolean rval = FALSE;
16003 
16004   if (e == NULL || o == NULL) {
16005     return FALSE;
16006   }
16007 
16008   if (o->id > 0) {
16009     sprintf (sbuf, "%d", o->id);
16010     tmp = StringSave (sbuf);
16011   } else {
16012     tmp = StringSave (o->str);
16013   }
16014   ApplySeqIdEditToString (e, &tmp);
16015   if (!StringHasNoText (tmp)) {
16016     o->id = 0;
16017     o->str = NULL;
16018     if (StringIsAllDigits (tmp) && StringLen (tmp) < 12) {
16019       o->id = atoi (tmp);
16020     } else {
16021       o->str = tmp;
16022       tmp = NULL;
16023     }
16024     rval = TRUE;
16025   }
16026   tmp = MemFree (tmp);
16027   return rval;
16028 }
16029 
16030 
EditSeqIdBioseqCallback(BioseqPtr bsp,Pointer data)16031 static void EditSeqIdBioseqCallback (BioseqPtr bsp, Pointer data)
16032 {
16033   EditSeqIdPtr e;
16034   SeqIdPtr sip, new_sip;
16035   ObjectIdPtr cpy;
16036   DbtagPtr    dbtag;
16037   Boolean     found = FALSE;
16038 
16039   if (bsp == NULL || (e = (EditSeqIdPtr) data) == NULL
16040       || !DoesSequenceMatchSequenceConstraint(bsp, e->seq_constraint)) {
16041     return;
16042   }
16043 
16044   for (sip = bsp->id; sip != NULL && !found; sip = sip->next) {
16045     if (e->id_type == eSeqIdEdit_local && sip->choice == SEQID_LOCAL) {
16046       new_sip = SeqIdDup (sip);
16047       cpy = (ObjectIdPtr) new_sip->data.ptrvalue;
16048       if (ApplySeqIdEditToObjectId(e, cpy)) {
16049         sip = SeqIdDup (sip);
16050         ReplaceSeqIdWithSeqId (sip, new_sip, e->top_sep);
16051         sip = SeqIdFree (sip);
16052         found = TRUE;
16053       }
16054       new_sip = SeqIdFree (new_sip);
16055     } else if ((e->id_type == eSeqIdEdit_general_db || e->id_type == eSeqIdEdit_general_tag)
16056                && sip->choice == SEQID_GENERAL) {
16057       new_sip = SeqIdDup (sip);
16058       dbtag = (DbtagPtr) new_sip->data.ptrvalue;
16059       if (IsStringConstraintEmpty (e->db_constraint)
16060           || DoesStringMatchConstraint (dbtag->db, e->db_constraint)) {
16061         if (e->id_type == eSeqIdEdit_general_db) {
16062           if (ApplySeqIdEditToString (e, &(dbtag->db)) && !StringHasNoText (dbtag->db)) {
16063             sip = SeqIdDup (sip);
16064             ReplaceSeqIdWithSeqId (sip, new_sip, e->top_sep);
16065             sip = SeqIdFree (sip);
16066             found = TRUE;
16067           }
16068         } else if (e->id_type == eSeqIdEdit_general_tag) {
16069           if (ApplySeqIdEditToObjectId(e, dbtag->tag)) {
16070             sip = SeqIdDup (sip);
16071             ReplaceSeqIdWithSeqId (sip, new_sip, e->top_sep);
16072             sip = SeqIdFree (sip);
16073             found = TRUE;
16074           }
16075         }
16076       }
16077       new_sip = SeqIdFree (new_sip);
16078     }
16079     if (found) {
16080       break;
16081     }
16082   }
16083 
16084 }
16085 
16086 
16087 typedef struct editseqidfrm {
16088   FORM_MESSAGE_BLOCK
16089   GrouP id_type;
16090   TexT  prefix;
16091   TexT  suffix;
16092   DialoG text_portion;
16093   DialoG db_constraint;
16094   DialoG seq_constraint;
16095 } EditSeqIdFrmData, PNTR EditSeqIdFrmPtr;
16096 
16097 
DoEditSeqIds(ButtoN b)16098 static void DoEditSeqIds (ButtoN b)
16099 {
16100   EditSeqIdFrmPtr frm;
16101   EditSeqIdData data;
16102 
16103   frm = (EditSeqIdFrmPtr) GetObjectExtra (b);
16104   if (frm == NULL) {
16105     return;
16106   }
16107 
16108   MemSet (&data, 0, sizeof (EditSeqIdData));
16109   data.top_sep = GetTopSeqEntryForEntityID (frm->input_entityID);
16110   data.id_type = GetValue (frm->id_type);
16111   data.prefix = SaveStringFromText (frm->prefix);
16112   data.suffix = SaveStringFromText (frm->suffix);
16113   data.text_portion = DialogToPointer (frm->text_portion);
16114   if (data.id_type == eSeqIdEdit_general_db || data.id_type == eSeqIdEdit_general_tag) {
16115     data.db_constraint = DialogToPointer (frm->db_constraint);
16116   }
16117   data.seq_constraint = DialogToPointer (frm->seq_constraint);
16118 
16119   VisitBioseqsInSep (data.top_sep, &data, EditSeqIdBioseqCallback);
16120 
16121   data.prefix = MemFree (data.prefix);
16122   data.suffix = MemFree (data.suffix);
16123   data.text_portion = TextPortionFree (data.text_portion);
16124   data.db_constraint = StringConstraintFree (data.db_constraint);
16125   data.seq_constraint = SequenceConstraintFree (data.seq_constraint);
16126 
16127   Update ();
16128   ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
16129   ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
16130   Remove (frm->form);
16131 }
16132 
16133 
ChangeSeqIdType(GrouP g)16134 static void ChangeSeqIdType (GrouP g)
16135 {
16136   EditSeqIdFrmPtr frm;
16137 
16138   frm = (EditSeqIdFrmPtr) GetObjectExtra (g);
16139   if (frm == NULL) {
16140     return;
16141   }
16142   if (GetValue (frm->id_type) == 1) {
16143     Hide (frm->db_constraint);
16144   } else {
16145     Show (frm->db_constraint);
16146   }
16147 }
16148 
16149 
EditSeqIds(IteM i)16150 NLM_EXTERN void EditSeqIds (IteM i)
16151 {
16152   BaseFormPtr     bfp;
16153   EditSeqIdFrmPtr frm;
16154   WindoW          w;
16155   GrouP           h, g, c;
16156   ButtoN          b;
16157 
16158 #ifdef WIN_MAC
16159   bfp = currentFormDataPtr;
16160 #else
16161   bfp = GetObjectExtra (i);
16162 #endif
16163   if (bfp == NULL) return;
16164 
16165 
16166   frm = (EditSeqIdFrmPtr) MemNew (sizeof (EditSeqIdFrmData));
16167 
16168   w = FixedWindow (-50, -33, -10, -10, "Edit Sequence IDs", StdCloseWindowProc);
16169   SetObjectExtra (w, frm, StdCleanupFormProc);
16170 
16171   h = HiddenGroup (w, -1, 0, NULL);
16172   SetGroupSpacing (h, 10, 10);
16173   frm->form = (ForM) w;
16174   frm->input_entityID = bfp->input_entityID;
16175 
16176   frm->id_type = NormalGroup (h, 0, 4, "What part of the SeqId do you want to edit?", systemFont, ChangeSeqIdType);
16177   SetObjectExtra (frm->id_type, frm, NULL);
16178   SetGroupSpacing (frm->id_type, 10, 10);
16179   RadioButton (frm->id_type, "Local ID");
16180   RadioButton (frm->id_type, "General ID db");
16181   RadioButton (frm->id_type, "General ID tag");
16182   SetValue (frm->id_type, 1);
16183 
16184   frm->db_constraint = StringConstraintDialog (h, "Where General ID db", TRUE, NULL, NULL);
16185   Hide (frm->db_constraint);
16186 
16187   frm->seq_constraint = SequenceConstraintDialog (h, NULL, NULL);
16188 
16189   g = HiddenGroup (h, 2, 0, NULL);
16190   StaticPrompt (g, "Keep", 0, dialogTextHeight, programFont, 'c');
16191   frm->text_portion = TextPortionDialog (g, TRUE, NULL, NULL);
16192   StaticPrompt (g, "Add Prefix", 0, dialogTextHeight, programFont, 'c');
16193   frm->prefix = DialogText (g, "", 14, NULL);
16194   StaticPrompt (g, "Add Suffix", 0, dialogTextHeight, programFont, 'c');
16195   frm->suffix = DialogText (g, "", 14, NULL);
16196 
16197   c = HiddenGroup (h, 2, 0, NULL);
16198   b = DefaultButton (c, "Accept", DoEditSeqIds);
16199   SetObjectExtra (b, frm, NULL);
16200   PushButton (c, "Cancel", StdCancelButtonProc);
16201   AlignObjects (ALIGN_CENTER, (HANDLE) frm->id_type,
16202                               (HANDLE) frm->db_constraint,
16203                               (HANDLE) frm->seq_constraint,
16204                               (HANDLE) g, (HANDLE) c, NULL);
16205 
16206   Show (w);
16207 
16208 }
16209 
16210 
RemoveSeqAnnotDataIdsCallback(SeqAnnotPtr sap,Pointer data)16211 static void RemoveSeqAnnotDataIdsCallback(SeqAnnotPtr sap, Pointer data)
16212 {
16213   if (sap != NULL && sap->type == 4) {
16214     sap->idx.deleteme = TRUE;
16215   }
16216 }
16217 
16218 
RemoveSeqAnnotDataIds(IteM i)16219 NLM_EXTERN void RemoveSeqAnnotDataIds (IteM i)
16220 {
16221   BaseFormPtr     bfp;
16222   SeqEntryPtr     sep;
16223 
16224 #ifdef WIN_MAC
16225   bfp = currentFormDataPtr;
16226 #else
16227   bfp = GetObjectExtra (i);
16228 #endif
16229   if (bfp == NULL) return;
16230 
16231   sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
16232   VisitAnnotsInSep (sep, NULL, RemoveSeqAnnotDataIdsCallback);
16233   DeleteMarkedObjects (bfp->input_entityID, 0, NULL);
16234   ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
16235   ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
16236 }
16237