~ubuntu-branches/ubuntu/precise/ncbi-tools6/precise

« back to all changes in this revision

Viewing changes to sequin/sequin4.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2005-03-27 12:00:15 UTC
  • mfrom: (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050327120015-embhesp32nj73p9r
Tags: 6.1.20041020-3
* Fix FTBFS under GCC 4.0 caused by inconsistent use of "static" on
  functions.  (Closes: #295110.)
* Add a watch file, now that we can.  (Upstream's layout needs version=3.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
*
30
30
* Version Creation Date:   6/28/96
31
31
*
32
 
* $Revision: 6.151 $
 
32
* $Revision: 6.247 $
33
33
*
34
34
* File Description: 
35
35
*
72
72
#include <alignmgr.h>
73
73
#include <alignmgr2.h>
74
74
#include <aliparse.h>
 
75
#include <spidey.h>
 
76
#include <ent2api.h>
 
77
#include <valid.h>
 
78
#include <sqnutils.h>
 
79
 
75
80
 
76
81
#define REGISTER_UPDATESEGSET ObjMgrProcLoadEx (OMPROC_FILTER,"Update Segmented Set","UpdateSegSet",0,0,0,0,NULL,UpdateSegSet,PROC_PRIORITY_DEFAULT, "Indexer")
77
82
 
87
92
 
88
93
#define REGISTER_POPSET_WITHIN_GENBANK ObjMgrProcLoadEx (OMPROC_FILTER,"Add Popset Within GenBank Set","AddPopSetWithinGenBankSet",0,0,0,0,NULL,PopWithinGenBankSet,PROC_PRIORITY_DEFAULT, "Indexer")
89
94
 
 
95
#define REGISTER_PHYSET_WITHIN_GENBANK ObjMgrProcLoadEx (OMPROC_FILTER,"Add Physet Within GenBank Set","AddPhySetWithinGenBankSet",0,0,0,0,NULL,PhyWithinGenBankSet,PROC_PRIORITY_DEFAULT, "Indexer")
 
96
 
90
97
#define REGISTER_REMOVE_MESSEDUP ObjMgrProcLoadEx (OMPROC_FILTER,"Repair Messed Up Sets","RepairMessedUpSets",0,0,0,0,NULL,RepairMessedUpRecord,PROC_PRIORITY_DEFAULT, "Indexer")
91
98
 
92
99
#define REGISTER_UPDATE_SEQALIGN ObjMgrProcLoadEx (OMPROC_FILTER, "Update SeqAlign","UpdateSeqAlign",OBJ_SEQALIGN,0,OBJ_SEQALIGN,0,NULL,NewUpdateSeqAlign,PROC_PRIORITY_DEFAULT, "Indexer")
93
100
 
 
101
#define REGISTER_DELETE_BY_TEXT ObjMgrProcLoadEx (OMPROC_FILTER, "Delete By Text","DeleteByText",0,0,0,0,NULL,CreateDeleteByTextWindow,PROC_PRIORITY_DEFAULT, "Indexer")
 
102
 
 
103
#define REGISTER_SEGREGATE_BY_TEXT ObjMgrProcLoadEx (OMPROC_FILTER, "Segregate By Text","SegregateByText",0,0,0,0,NULL,CreateSegregateByTextWindow,PROC_PRIORITY_DEFAULT, "Indexer")
 
104
 
 
105
#define REGISTER_SEGREGATE_BY_FEATURE ObjMgrProcLoadEx (OMPROC_FILTER, "Segregate By Feature","SegregateByFeature",0,0,0,0,NULL,CreateSegregateByFeatureWindow,PROC_PRIORITY_DEFAULT, "Indexer")
 
106
 
 
107
#define REGISTER_SEGREGATE_BY_DESCRIPTOR ObjMgrProcLoadEx (OMPROC_FILTER, "Segregate By Descriptor","SegregateByDescriptor",0,0,0,0,NULL,CreateSegregateByDescriptorWindow,PROC_PRIORITY_DEFAULT, "Indexer")
 
108
 
 
109
#define REGISTER_SEGREGATE_BY_MOLECULE_TYPE ObjMgrProcLoadEx (OMPROC_FILTER, "Segregate By Molecule Type","SegregateByMoleculeType",0,0,0,0,NULL,CreateSegregateByMoleculeTypeWindow,PROC_PRIORITY_DEFAULT, "Indexer")
 
110
 
94
111
#define REGISTER_CONVERTSEQALIGN ObjMgrProcLoadEx (OMPROC_FILTER,"Convert SeqAlign","ConvertSeqAlign",0,0,0,0,NULL,ConvertToTrueMultipleAlignment,PROC_PRIORITY_DEFAULT, "Alignment")
95
112
 
96
113
#define REGISTER_MAKESEQALIGN ObjMgrProcLoadEx (OMPROC_FILTER,"Make SeqAlign","CreateSeqAlign",0,0,0,0,NULL,GenerateSeqAlignFromSeqEntry,PROC_PRIORITY_DEFAULT, "Alignment")
97
114
 
98
115
#define REGISTER_MAKESEQALIGNP ObjMgrProcLoadEx (OMPROC_FILTER,"Make Protein SeqAlign","CreateSeqAlignProt",0,0,0,0,NULL,GenerateSeqAlignFromSeqEntryProt,PROC_PRIORITY_DEFAULT, "Alignment")
99
116
 
 
117
#define REGISTER_MAKESEQALIGND ObjMgrProcLoadEx (OMPROC_FILTER,"Make Discontinuous SeqAlign","CreateSeqAlignDisc",0,0,0,0,NULL,GenerateSeqAlignDiscFromSeqEntry,PROC_PRIORITY_DEFAULT, "Alignment")
 
118
 
100
119
#define REGISTER_NORMSEQALIGN ObjMgrProcLoadEx (OMPROC_FILTER,"Validate SeqAlign","ValidateSeqAlign",0,0,0,0,NULL,ValidateSeqAlignFromData,PROC_PRIORITY_DEFAULT, "Alignment")
101
120
 
 
121
#define REGISTER_NOMORESEGGAP ObjMgrProcLoadEx (OMPROC_FILTER,"Get Rid of Seg Gap","GetRidOfSegGap",0,0,0,0,NULL,NoMoreSegGap,PROC_PRIORITY_DEFAULT, "Alignment")
 
122
 
102
123
#define REGISTER_PARTSEQALIGNTOPARENT ObjMgrProcLoadEx (OMPROC_FILTER,"Part SeqAlign to Parent","PartSeqAlignToParent",0,0,0,0,NULL,PartSeqAlignToParent,PROC_PRIORITY_DEFAULT, "Alignment")
103
124
 
104
125
#define REGISTER_GROUP_EXPLODE ObjMgrProcLoadEx (OMPROC_FILTER, "Explode a group", "GroupExplode", OBJ_SEQFEAT, 0, OBJ_SEQFEAT, 0, NULL, GroupExplodeFunc, PROC_PRIORITY_DEFAULT, "Indexer")
105
126
 
106
127
#define REGISTER_INTERVAL_COMBINE ObjMgrProcLoadEx (OMPROC_FILTER, "Combine feature intervals", "IntervalCombine", OBJ_SEQFEAT, 0, OBJ_SEQFEAT, 0, NULL, IntervalCombineFunc, PROC_PRIORITY_DEFAULT, "Indexer")
107
128
 
 
129
#define REGISTER_INTERVAL_COMBINE_AND_FUSE ObjMgrProcLoadEx (OMPROC_FILTER, "Combine and fuse feature intervals", "IntervalCombineAndFuse", OBJ_SEQFEAT, 0, OBJ_SEQFEAT, 0, NULL, IntervalCombineAndFuseFunc, PROC_PRIORITY_DEFAULT, "Indexer")
 
130
 
108
131
#define REGISTER_MRNA_FROM_CDS ObjMgrProcLoadEx (OMPROC_FILTER, "mRNA from CDS", "mRNAfromCDS", OBJ_SEQFEAT, FEATDEF_CDS, OBJ_SEQFEAT, FEATDEF_CDS, NULL, MRnaFromCdsFunc, PROC_PRIORITY_DEFAULT, "Utilities")
109
132
 
110
133
#define REGISTER_SPLIT_BIOSEQ ObjMgrProcLoadEx (OMPROC_FILTER,"Split Bioseq Into Segments","SplitBioseqIntoSegments",0,0,0,0,NULL,SplitIntoSegmentedBioseq,PROC_PRIORITY_DEFAULT, "Indexer")
126
149
 
127
150
#define REGISTER_BSP_INDEX ObjMgrProcLoadEx (OMPROC_FILTER,"Bioseq Index","MakeBioseqIndex",0,0,0,0,NULL,DoBioseqIndexing,PROC_PRIORITY_DEFAULT, "Indexer")
128
151
 
 
152
#define REGISTER_FIND_NON_ACGT ObjMgrProcLoadEx (OMPROC_FILTER,"Find Non ACGT","FindNonACGT",0,0,0,0,NULL,FindNonACGT,PROC_PRIORITY_DEFAULT, "Indexer")
 
153
 
129
154
#define REGISTER_TRIM_GENES ObjMgrProcLoadEx (OMPROC_FILTER,"Trim Genes","TrimGenes",0,0,0,0,NULL,TrimGenes,PROC_PRIORITY_DEFAULT, "Indexer")
130
155
 
131
156
#define REGISTER_OPENALED ObjMgrProcLoadEx (OMPROC_FILTER,"Open Align Editor 1","Open Contiguous Protein Alignment", 0,0,0,0,NULL,LaunchAlignEditorFromDesktop, PROC_PRIORITY_DEFAULT, "Alignment")
142
167
 
143
168
#define REGISTER_DESKTOP_REPORT ObjMgrProcLoadEx (OMPROC_FILTER, "Desktop Report", "DesktopReport", 0, 0, 0, 0, NULL, DesktopReportFunc, PROC_PRIORITY_DEFAULT, "Indexer")
144
169
 
145
 
#define REGISTER_DESCRIPTOR_PROPAGATE ObjMgrProcLoadEx (OMPROC_FILTER, "Descriptor Propagate", "DescriptorPropagate", 0, 0, 0, 0, NULL, DoDescriptorPropagate, PROC_PRIORITY_DEFAULT, "Indexer")
 
170
#define REGISTER_DESCRIPTOR_PROPAGATE ObjMgrProcLoadEx (OMPROC_FILTER, "Descriptor Propagate", "DescriptorPropagate", 0, 0, 0, 0, NULL, DescriptorPropagate, PROC_PRIORITY_DEFAULT, "Indexer")
146
171
 
147
172
#define REGISTER_CLEAR_SEQENTRYSCOPE ObjMgrProcLoadEx (OMPROC_FILTER, "Clear SeqEntry Scope", "ClearSeqEntryScope", 0, 0, 0, 0, NULL, DoClearSeqEntryScope, PROC_PRIORITY_DEFAULT, "Indexer")
148
173
 
161
186
#define REGISTER_SEQUIN_GI_TO_ACCN ObjMgrProcLoadEx (OMPROC_FILTER,"Convert Align GI to Accession","ConvertAlignGisToAccn",0,0,0,0,NULL,AlignGiToAccnProc,PROC_PRIORITY_DEFAULT, "Misc")
162
187
static Int2 LIBCALLBACK AlignGiToAccnProc (Pointer data);
163
188
 
 
189
#define REGISTER_SEQUIN_ACCN_TO_GI ObjMgrProcLoadEx (OMPROC_FILTER,"Convert Align Accession To Gi","ConvertAlignAccnsToGi",0,0,0,0,NULL,AlignAccnToGiProc,PROC_PRIORITY_DEFAULT, "Misc")
 
190
static Int2 LIBCALLBACK AlignAccnToGiProc (Pointer data);
 
191
 
164
192
#define REGISTER_SEQUIN_CACHE_ACCN ObjMgrProcLoadEx (OMPROC_FILTER,"Cache Accessions to Disk","CacheAccnsToDisk",0,0,0,0,NULL,CacheAccnsToDisk,PROC_PRIORITY_DEFAULT, "Misc")
165
193
static Int2 LIBCALLBACK CacheAccnsToDisk (Pointer data);
166
194
 
 
195
#define REGISTER_SEPARATE_MRNA_ALIGNS ObjMgrProcLoadEx (OMPROC_FILTER,"Separate mRNA Alignments from NR","SeparateMrnaAlignsFromNR",0,0,0,0,NULL,SeparateMrnaFromNrProc,PROC_PRIORITY_DEFAULT, "Misc")
 
196
static Int2 LIBCALLBACK SeparateMrnaFromNrProc (Pointer data);
 
197
 
167
198
#define REGISTER_REFGENEUSER_DESC_EDIT ObjMgrProcLoad(OMPROC_EDIT,"Edit RefGene UserTrack Desc","RefGene Tracking",OBJ_SEQDESC,Seq_descr_user,OBJ_SEQDESC,Seq_descr_user,NULL,RefGeneUserGenFunc,PROC_PRIORITY_DEFAULT)
168
199
extern Int2 LIBCALLBACK RefGeneUserGenFunc (Pointer data);
169
200
 
170
201
#define REGISTER_TPAASSEMBLYUSER_DESC_EDIT ObjMgrProcLoad(OMPROC_EDIT,"Edit Assembly User Desc","TPA Assembly",OBJ_SEQDESC,Seq_descr_user,OBJ_SEQDESC,Seq_descr_user,NULL,AssemblyUserGenFunc,PROC_PRIORITY_DEFAULT)
 
202
 
 
203
typedef struct {
 
204
  CharPtr  oldStr;
 
205
  SeqIdPtr newSip;
 
206
} ReplaceIDStruct, PNTR ReplaceIDStructPtr;
 
207
 
 
208
typedef struct _explodeStruct {
 
209
  SeqEntryPtr topSep;
 
210
  SeqFeatPtr  seqFeatPtr;
 
211
  struct _explodeStruct PNTR next;
 
212
} ExplodeStruct, PNTR ExplodeStructPtr;
 
213
 
 
214
typedef struct {
 
215
  DESCRIPTOR_FORM_BLOCK
 
216
  PopuP        fromPopup;
 
217
  PopuP        toPopup;
 
218
  Int2         fromStrand;
 
219
  Int2         toStrand;
 
220
  ValNodePtr   featlist;
 
221
  LisT         feature;
 
222
  Int2         featSubType;
 
223
  CharPtr      findThisStr;
 
224
  TexT         findThis;
 
225
  Boolean      case_insensitive;
 
226
  ButtoN       case_insensitive_btn;
 
227
  Boolean      when_string_not_present;
 
228
  ButtoN       when_string_not_present_btn;
 
229
} EditStrand, PNTR EditStrandPtr;
 
230
 
171
231
extern Int2 LIBCALLBACK AssemblyUserGenFunc (Pointer data);
172
232
 
173
233
static void AddBspToSegSet (BioseqPtr segseq, BioseqPtr bsp)
418
478
  if (IS_Bioseq_set (sep)) {
419
479
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
420
480
    if (bssp != NULL && (bssp->_class == 7 ||
421
 
                         (bssp->_class >= 13 && bssp->_class <= 16))) {
 
481
                         (IsPopPhyEtcSet (bssp->_class)))) {
422
482
      choice = 0;
423
483
      for (tmp = bssp->seq_set; tmp != NULL; tmp = tmp->next) {
424
484
        if (choice == 0) {
562
622
  return OM_MSG_RET_DONE;
563
623
}
564
624
 
 
625
#if 0
 
626
static SeqLocPtr FixLonelySeqLocIntervals (SeqLocPtr slp)
 
627
{
 
628
  SeqLocPtr loc;
 
629
 
 
630
  if (slp == NULL || (slp->choice != SEQLOC_MIX && slp->choice != SEQLOC_PACKED_INT)) {
 
631
    return slp;
 
632
  }
 
633
 
 
634
  loc = SeqLocFindNext (slp, NULL);
 
635
  if (loc == NULL) {
 
636
    SeqLocFree (slp);
 
637
    return NULL;
 
638
  } else if (loc->next == NULL) {
 
639
    slp->data.ptrvalue = NULL;
 
640
    SeqLocFree (slp);
 
641
    return loc;
 
642
  } else {
 
643
    return slp;
 
644
  }
 
645
}
 
646
#endif
 
647
 
 
648
static SeqLocPtr ReduceLocationToSingleBioseq (SeqLocPtr slp, BioseqPtr bsp)
 
649
{
 
650
  SeqLocPtr this_slp, tmp_slp;
 
651
  BioseqPtr this_bsp;
 
652
 
 
653
  if (slp == NULL || bsp == NULL) return NULL;
 
654
 
 
655
  this_slp = SeqLocFindNext (slp, NULL);
 
656
 
 
657
  while (slp != NULL && this_slp != NULL) {
 
658
    this_bsp = BioseqFindFromSeqLoc (this_slp);
 
659
    if (this_bsp != bsp) {
 
660
      tmp_slp = SeqLocMerge (this_bsp, this_slp, NULL, TRUE, FALSE, FALSE);
 
661
      slp = SeqLocSubtract (slp, tmp_slp);
 
662
      SeqLocFree (tmp_slp);
 
663
      this_slp = SeqLocFindNext (slp, NULL);
 
664
    } else {
 
665
      this_slp = SeqLocFindNext (slp, this_slp);
 
666
    }
 
667
  }
 
668
  return slp;
 
669
}
 
670
 
 
671
static SeqLocPtr RemoveBioseqFromLocation (SeqLocPtr slp, BioseqPtr bsp)
 
672
{
 
673
  SeqLocPtr this_slp, tmp_slp;
 
674
  BioseqPtr this_bsp;
 
675
 
 
676
  if (slp == NULL || bsp == NULL) return slp;
 
677
 
 
678
  this_slp = SeqLocFindNext (slp, NULL);
 
679
  while (slp != NULL && this_slp != NULL) {
 
680
    this_bsp = BioseqFindFromSeqLoc (this_slp);
 
681
    if (this_bsp == bsp) {
 
682
      tmp_slp = SeqLocMerge (bsp, this_slp, NULL, TRUE, FALSE, FALSE);
 
683
      slp = SeqLocSubtract (slp, tmp_slp);
 
684
      SeqLocFree (tmp_slp);
 
685
      this_slp = SeqLocFindNext (slp, NULL);
 
686
    } else {
 
687
      this_slp = SeqLocFindNext (slp, this_slp);
 
688
    }
 
689
  }
 
690
  return slp;
 
691
}
 
692
 
 
693
static void PushFeaturesDownToBioseq (SeqAnnotPtr annot, SeqEntryPtr sep)
 
694
{
 
695
  BioseqSetPtr bssp;
 
696
  BioseqPtr    bsp, this_bsp;
 
697
  SeqFeatPtr   sfp, prev_sfp, last_sfp, next_sfp;
 
698
 
 
699
  if (annot == NULL || annot->type != 1 || sep == NULL) return;
 
700
 
 
701
  if (IS_Bioseq_set (sep)) {
 
702
    bssp = sep->data.ptrvalue;
 
703
    for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
 
704
      PushFeaturesDownToBioseq (annot, sep);
 
705
    }
 
706
    return;
 
707
  }
 
708
 
 
709
  if (! IS_Bioseq (sep)) return;
 
710
 
 
711
  bsp = sep->data.ptrvalue;
 
712
  sfp = annot->data;
 
713
  prev_sfp = NULL;
 
714
  while (sfp != NULL) {
 
715
    next_sfp = sfp->next;
 
716
    while (sfp != NULL && (this_bsp = BioseqFindFromSeqLoc (sfp->location)) != bsp) {
 
717
      prev_sfp = sfp;
 
718
      sfp = sfp->next;
 
719
      if (sfp != NULL) {
 
720
        next_sfp = sfp->next;
 
721
      }
 
722
    }
 
723
    if (sfp != NULL) {  
 
724
      if (bsp->annot == NULL) {
 
725
        bsp->annot = SeqAnnotNew ();
 
726
        bsp->annot->type = 1;
 
727
        bsp->annot->data = sfp;
 
728
      } else {
 
729
        if (bsp->annot->data == NULL) {
 
730
          bsp->annot->data = sfp;
 
731
        } else {
 
732
          last_sfp = bsp->annot->data;
 
733
          while (last_sfp->next != NULL) {
 
734
            last_sfp = last_sfp->next;
 
735
          }
 
736
          last_sfp->next = sfp;
 
737
        }
 
738
      }
 
739
      if (prev_sfp == NULL) {
 
740
        annot->data = sfp->next;
 
741
      } else {
 
742
        prev_sfp->next = sfp->next;
 
743
      }
 
744
      sfp->next = NULL;
 
745
      sfp = next_sfp;
 
746
    }
 
747
  }
 
748
}
 
749
 
 
750
static void SplitSegmentedFeatsOnOneSet (BioseqSetPtr set)
 
751
{
 
752
  SeqAnnotPtr annot, prev_annot, next_annot;
 
753
  SeqFeatPtr  sfp, new_sfp, prev_sfp, next_sfp;
 
754
  SeqEntryPtr sep;
 
755
  BioseqPtr   bsp, last_bsp;
 
756
  SeqLocPtr   loc, slp;
 
757
 
 
758
  if (set == NULL || set->annot == NULL) return;
 
759
  prev_annot = NULL;
 
760
  annot = set->annot;
 
761
  next_annot = annot->next;
 
762
  while (annot != NULL) {
 
763
    next_annot = annot->next;
 
764
    if (annot->type != 1) {
 
765
      prev_annot = annot;
 
766
      annot = next_annot;
 
767
      continue;
 
768
    }
 
769
    sfp = annot->data;
 
770
    while (sfp != NULL) {
 
771
      next_sfp = sfp->next;
 
772
      prev_sfp = sfp;
 
773
      loc = SeqLocFindNext (sfp->location, NULL);
 
774
      last_bsp = BioseqFindFromSeqLoc (loc);
 
775
      slp = SeqLocFindNext (sfp->location, loc);
 
776
      while (slp != NULL) {
 
777
        bsp = BioseqFindFromSeqLoc (slp);
 
778
        if (bsp != last_bsp && bsp != NULL) {
 
779
          new_sfp = SeqFeatCopy (sfp);
 
780
          new_sfp->location = ReduceLocationToSingleBioseq (new_sfp->location, bsp);
 
781
          sfp->location = RemoveBioseqFromLocation (sfp->location, bsp);
 
782
          prev_sfp->next = new_sfp;
 
783
          new_sfp->next = next_sfp;
 
784
          prev_sfp = new_sfp;
 
785
          slp = SeqLocFindNext (sfp->location, NULL);
 
786
        } else {
 
787
          slp = SeqLocFindNext (sfp->location, slp);
 
788
        }
 
789
      }
 
790
      sfp = next_sfp;
 
791
    }
 
792
 
 
793
    /* push features to appropriate bioseqs */
 
794
    for (sep = set->seq_set; sep != NULL; sep = sep->next) {
 
795
      PushFeaturesDownToBioseq (annot, sep);
 
796
    }
 
797
    if (prev_annot == NULL) {
 
798
      set->annot = annot->next;
 
799
    } else {
 
800
      prev_annot->next = annot->next;
 
801
    }
 
802
    annot->next = NULL;
 
803
    SeqAnnotFree (annot);
 
804
    annot = next_annot;      
 
805
  }
 
806
}
 
807
 
 
808
static void SplitSegmentedFeats (SeqEntryPtr sep)
 
809
{
 
810
  BioseqSetPtr bssp;
 
811
 
 
812
  if (IS_Bioseq_set (sep)) {
 
813
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
 
814
    SplitSegmentedFeatsOnOneSet (bssp);
 
815
    for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
 
816
      SplitSegmentedFeats (sep);
 
817
    }
 
818
  }
 
819
}
 
820
 
 
821
extern void SplitSegmentedFeatsMenuItem (IteM i)
 
822
{
 
823
  BaseFormPtr   bfp;
 
824
  SeqEntryPtr   sep;
 
825
 
 
826
#ifdef WIN_MAC
 
827
  bfp = currentFormDataPtr;
 
828
#else
 
829
  bfp = GetObjectExtra (i);
 
830
#endif
 
831
  if (bfp == NULL) return;
 
832
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
 
833
  if (sep == NULL) return;
 
834
  SplitSegmentedFeats (sep);
 
835
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
836
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
837
 
 
838
}
 
839
 
565
840
static void DoSegSetUndo (BioseqPtr segseq, BioseqSetPtr parts, BioseqSetPtr segset)
566
841
 
567
842
{
607
882
  if (IS_Bioseq_set (sep)) {
608
883
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
609
884
    if (bssp != NULL && (bssp->_class == 7 ||
610
 
                         (bssp->_class >= 13 && bssp->_class <= 16))) {
 
885
                         (IsPopPhyEtcSet (bssp->_class)))) {
611
886
      for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
612
887
        count += DoOneSegUndo (sep);
613
888
      }
614
889
      return count;
615
890
    }
616
891
  }
 
892
 
617
893
  uss.segseq = NULL;
618
894
  uss.parts = NULL;
619
895
  uss.segset = NULL;
679
955
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
680
956
    if (bssp == NULL) return;
681
957
    if (bssp->_class == 7 ||
682
 
        (bssp->_class >= 13 && bssp->_class <= 16)) {
 
958
        (IsPopPhyEtcSet (bssp->_class))) {
683
959
      for (tmp = bssp->seq_set; tmp != NULL; tmp = tmp->next) {
684
960
        DoRepairPartsSet (tmp);
685
961
      }
766
1042
  annot = tmpbssp->annot;
767
1043
  tmpbssp->annot = NULL;
768
1044
  if (bssp->annot == NULL) {
769
 
    tmpbssp->annot = annot;
 
1045
    bssp->annot = annot;
770
1046
    annot = NULL;
771
1047
  } else {
772
1048
    sap = bssp->annot;
817
1093
  RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
818
1094
  if (count > 0) {
819
1095
    PropagateFromGenBankBioseqSet (sep, FALSE);
 
1096
    SeqMgrClearFeatureIndexes (ompcp->input_entityID, NULL);
 
1097
    SeqMgrIndexFeatures (ompcp->input_entityID, NULL);
 
1098
    SplitSegmentedFeats (sep);
820
1099
    ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
821
1100
    ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
822
1101
  }
948
1227
     }
949
1228
     salp = salp->next;
950
1229
  }
951
 
  if (! AlnMgrIndexSeqAlign (sap)) return OM_MSG_RET_ERROR;
 
1230
  AlnMgr2IndexSeqAlign (sap);
952
1231
 
953
 
  salp = AlnMgrGetSubAlign (sap, NULL, 0, -1);
 
1232
  salp = AlnMgr2GetSubAlign (sap, 0, -1, 0, FALSE);
954
1233
  if (salp == NULL) return OM_MSG_RET_ERROR;
955
1234
 
956
1235
  if (sap->idx.prevlink != NULL) {
970
1249
  return OM_MSG_RET_DONE;
971
1250
}
972
1251
 
 
1252
static void SqnCleanUpSegGap (SeqAlignPtr sap)
 
1253
{
 
1254
   DenseSegPtr  dsp;
 
1255
   DenseSegPtr  dsp_new;
 
1256
   Boolean      found;
 
1257
   Int4         i;
 
1258
   Int4         j;
 
1259
   Int4         k;
 
1260
   Int4         numgap;
 
1261
 
 
1262
   if (sap == NULL || sap->segtype != SAS_DENSEG)
 
1263
      return;
 
1264
   dsp = (DenseSegPtr)(sap->segs);
 
1265
   numgap = 0;
 
1266
   for (i=0; i<dsp->numseg; i++)
 
1267
   {
 
1268
      found = FALSE;
 
1269
      for (j=0; !found && j<dsp->dim; j++)
 
1270
      {
 
1271
         if (dsp->starts[i*dsp->dim+j] != -1)
 
1272
            found = TRUE;
 
1273
      }
 
1274
      if (!found)
 
1275
         numgap++;
 
1276
   }
 
1277
   if (numgap == 0)
 
1278
      return;
 
1279
   dsp_new = DenseSegNew();
 
1280
   dsp_new->dim = dsp->dim;
 
1281
   dsp_new->ids = dsp->ids;
 
1282
   dsp->ids = NULL;
 
1283
   dsp_new->numseg = dsp->numseg - numgap;
 
1284
   dsp_new->starts = (Int4Ptr)MemNew(dsp_new->numseg*dsp_new->dim*sizeof(Int4));
 
1285
   dsp_new->strands = (Uint1Ptr)MemNew(dsp_new->numseg*dsp_new->dim*sizeof(Uint1));
 
1286
   dsp_new->lens = (Int4Ptr)MemNew(dsp_new->numseg*sizeof(Int4));
 
1287
   k = 0;
 
1288
   for (i=0; i<dsp->numseg; i++)
 
1289
   {
 
1290
      found = FALSE;
 
1291
      for (j=0; !found && j<dsp->dim; j++)
 
1292
      {
 
1293
         if (dsp->starts[i*dsp->dim+j] != -1)
 
1294
            found = TRUE;
 
1295
      }
 
1296
      if (found)
 
1297
      {
 
1298
         for (j=0; j<dsp_new->dim; j++)
 
1299
         {
 
1300
            dsp_new->starts[k*dsp_new->dim+j] = dsp->starts[i*dsp->dim+j];
 
1301
            dsp_new->strands[k*dsp_new->dim+j] = dsp->strands[i*dsp->dim+j];
 
1302
         }
 
1303
         dsp_new->lens[k] = dsp->lens[i];
 
1304
         k++;
 
1305
      }
 
1306
   }
 
1307
   DenseSegFree(dsp);
 
1308
   sap->segs = (Pointer)(dsp_new);
 
1309
   return;
 
1310
}
 
1311
 
 
1312
static void NoMoreSegGapForOneAlignment (SeqAlignPtr sap, Pointer userdata)
 
1313
{
 
1314
  SeqAlignPtr       salp;
 
1315
 
 
1316
  salp = sap;
 
1317
  while (salp != NULL)
 
1318
  {
 
1319
    if (salp->saip != NULL)
 
1320
    {
 
1321
       SeqAlignIndexFree(salp->saip);
 
1322
       salp->saip = NULL;
 
1323
    } else {
 
1324
       AlnMgr2IndexSingleChildSeqAlign(salp); /* make sure it's dense-seg */
 
1325
       SeqAlignIndexFree(salp->saip);
 
1326
       salp->saip = NULL;
 
1327
    }
 
1328
    SqnCleanUpSegGap(salp);
 
1329
    AlnMgr2IndexSingleChildSeqAlign(salp);
 
1330
    salp = salp->next;
 
1331
  }
 
1332
}
 
1333
 
 
1334
 
 
1335
static Int2 LIBCALLBACK NoMoreSegGap (Pointer data)
 
1336
{
 
1337
  OMProcControlPtr  ompcp;
 
1338
  SeqAlignPtr       sap;
 
1339
  SeqAnnotPtr       sanp;
 
1340
 
 
1341
  ompcp = (OMProcControlPtr) data;
 
1342
  if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
 
1343
  switch (ompcp->input_itemtype) {
 
1344
    case OBJ_SEQALIGN :
 
1345
      sap = (SeqAlignPtr) ompcp->input_data;
 
1346
      if (sap == NULL)
 
1347
      {
 
1348
        return OM_MSG_RET_ERROR;
 
1349
      }
 
1350
      else
 
1351
      {
 
1352
        NoMoreSegGapForOneAlignment (sap, NULL);
 
1353
      }
 
1354
      break;
 
1355
    case OBJ_SEQANNOT :
 
1356
      sanp = (SeqAnnotPtr) ompcp->input_data;
 
1357
      if (sanp->type != 2)
 
1358
      {
 
1359
        return OM_MSG_RET_ERROR;
 
1360
      }
 
1361
      else if ((sap = (SeqAlignPtr)(sanp->data)) == NULL)
 
1362
      {
 
1363
        return OM_MSG_RET_ERROR;
 
1364
      }
 
1365
      else
 
1366
      {
 
1367
        NoMoreSegGapForOneAlignment (sap, NULL);
 
1368
      }
 
1369
      break;
 
1370
    case OBJ_BIOSEQ :
 
1371
      VisitAlignmentsOnBsp (ompcp->input_data, NULL, NoMoreSegGapForOneAlignment);
 
1372
      break;
 
1373
    case OBJ_BIOSEQSET :
 
1374
      VisitAlignmentsInSet (ompcp->input_data, NULL, NoMoreSegGapForOneAlignment);
 
1375
      break;
 
1376
    case 0 :
 
1377
      return OM_MSG_RET_ERROR;
 
1378
      break;
 
1379
    default :
 
1380
      return OM_MSG_RET_ERROR;
 
1381
      break;
 
1382
  }
 
1383
  ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
 
1384
  ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
 
1385
  return OM_MSG_RET_DONE;
 
1386
}
 
1387
 
973
1388
static void SqnSeqAlignDeleteInSeqEntryCallBack (SeqEntryPtr sep, Pointer mydata,
974
1389
                                          Int4 index, Int2 indent)
975
1390
{
1044
1459
  }
1045
1460
}
1046
1461
 
 
1462
typedef struct alignmentoptionsform
 
1463
{
 
1464
  Boolean accepted;
 
1465
  Boolean done; 
 
1466
} AlignmentOptionsFormData, PNTR AlignmentOptionsFormPtr;
 
1467
 
 
1468
static void AcceptAlignmentOptions (ButtoN b)
 
1469
{
 
1470
  AlignmentOptionsFormPtr aofp;
 
1471
  
 
1472
  aofp = (AlignmentOptionsFormPtr) GetObjectExtra (b);
 
1473
  if (aofp == NULL) return;
 
1474
  aofp->accepted = TRUE;
 
1475
  aofp->done = TRUE;
 
1476
}
 
1477
 
 
1478
static void CancelAlignmentOptions (ButtoN b)
 
1479
{
 
1480
  AlignmentOptionsFormPtr aofp;
 
1481
  
 
1482
  aofp = (AlignmentOptionsFormPtr) GetObjectExtra (b);
 
1483
  if (aofp == NULL) return;
 
1484
  aofp->accepted = FALSE;
 
1485
  aofp->done = TRUE;
 
1486
}
 
1487
 
 
1488
static TSequenceInfoPtr GetAlignmentOptions (Uint1Ptr moltype)
 
1489
{
 
1490
  ButtoN                   b;
 
1491
  GrouP                    c, h, g;
 
1492
  WindoW                   w;
 
1493
  AlignmentOptionsFormData aofd;
 
1494
  TexT                     missing, match, beginning_gap, middle_gap, end_gap;
 
1495
  PopuP                    sequence_type;
 
1496
  TSequenceInfoPtr         sequence_info;
 
1497
  Char                     missing_txt [15], match_txt [15], beginning_gap_txt [15],
 
1498
                           middle_gap_txt [15], end_gap_txt [15];
 
1499
  Char                     nucleotide_alphabet[] = "ABCDGHKMRSTUVWYabcdghkmrstuvwy";
 
1500
  Char                     protein_alphabet[] = "ABCDEFGHIKLMPQRSTUVWXYZabcdefghiklmpqrstuvwxyz";
 
1501
 
 
1502
  aofd.accepted = FALSE;
 
1503
  aofd.done = FALSE;
 
1504
  w = ModalWindow (-50, -33, -10, -10, NULL);
 
1505
 
 
1506
  h = HiddenGroup (w, -1, 0, NULL);
 
1507
  SetGroupSpacing (h, 10, 10);
 
1508
  
 
1509
  g = HiddenGroup (h, 2, 4, NULL);
 
1510
  StaticPrompt (g, "Ambiguous/Unknown", 0, dialogTextHeight, programFont, 'c');
 
1511
  missing = DialogText (g, "?Nn", 5, NULL);
 
1512
  StaticPrompt (g, "Match", 0, dialogTextHeight, programFont, 'c');
 
1513
  match = DialogText (g, ".", 5, NULL);
 
1514
  StaticPrompt (g, "Beginning Gap", 0, dialogTextHeight, programFont, 'c');
 
1515
  beginning_gap = DialogText (g, "-.?nN", 5, NULL);
 
1516
  StaticPrompt (g, "Middle Gap", 0, dialogTextHeight, programFont, 'c');
 
1517
  middle_gap = DialogText (g, "-", 5, NULL);
 
1518
  StaticPrompt (g, "End Gap", 0, dialogTextHeight, programFont, 'c');
 
1519
  end_gap = DialogText (g, "-.?nN", 5, NULL);
 
1520
  StaticPrompt (g, "Sequence Type", 0, dialogTextHeight, programFont, 'c');
 
1521
  sequence_type = PopupList (g, TRUE, NULL);
 
1522
  PopupItem (sequence_type, "Nucleotide");
 
1523
  PopupItem (sequence_type, "Protein");
 
1524
  SetValue (sequence_type, 1);
 
1525
 
 
1526
  c = HiddenGroup (h, 4, 0, NULL);
 
1527
  b = DefaultButton (c, "Accept", AcceptAlignmentOptions);
 
1528
  SetObjectExtra (b, &aofd, NULL);
 
1529
  PushButton (c, "Cancel", CancelAlignmentOptions);
 
1530
 
 
1531
  AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
 
1532
  RealizeWindow (w);
 
1533
  Show (w);
 
1534
  Update ();
 
1535
  
 
1536
  while (!aofd.done)
 
1537
  {
 
1538
    ProcessExternalEvent ();
 
1539
    Update ();
 
1540
  }
 
1541
  ProcessAnEvent ();
 
1542
  if (!aofd.accepted)
 
1543
  {
 
1544
    Remove (w);
 
1545
        return NULL;
 
1546
  }
 
1547
  
 
1548
  sequence_info = SequenceInfoNew ();
 
1549
  if (sequence_info == NULL) return NULL;
 
1550
 
 
1551
  GetTitle (missing, missing_txt, sizeof (missing_txt) -1);
 
1552
  GetTitle (beginning_gap, beginning_gap_txt, sizeof (beginning_gap_txt) - 1);
 
1553
  GetTitle (middle_gap, middle_gap_txt, sizeof (middle_gap_txt) - 1);
 
1554
  GetTitle (end_gap, end_gap_txt, sizeof (end_gap_txt) - 1);
 
1555
  GetTitle (match, match_txt, sizeof (match_txt) - 1);
 
1556
  if (GetValue (sequence_type) == 1) 
 
1557
  {
 
1558
    sequence_info->alphabet = StringSave (nucleotide_alphabet);
 
1559
    if (moltype != NULL)
 
1560
    {
 
1561
      *moltype = Seq_mol_na;
 
1562
    }
 
1563
  } else {
 
1564
    sequence_info->alphabet = StringSave (protein_alphabet);
 
1565
    if (moltype != NULL)
 
1566
    {
 
1567
      *moltype = Seq_mol_aa;
 
1568
    }
 
1569
  }
 
1570
 
 
1571
  MemFree (sequence_info->missing);
 
1572
  sequence_info->missing = StringSave (missing_txt);
 
1573
  MemFree (sequence_info->beginning_gap);
 
1574
  sequence_info->beginning_gap = StringSave (beginning_gap_txt);
 
1575
  MemFree (sequence_info->middle_gap);
 
1576
  sequence_info->middle_gap = StringSave (middle_gap_txt);
 
1577
  MemFree (sequence_info->end_gap);
 
1578
  sequence_info->end_gap = StringSave (end_gap_txt);
 
1579
  MemFree (sequence_info->match);
 
1580
  sequence_info->match = StringSave (match_txt);
 
1581
  Remove (w);
 
1582
  return sequence_info;
 
1583
}
 
1584
 
1047
1585
static Int2 LIBCALLBACK NewUpdateSeqAlign (Pointer data)
1048
1586
 
1049
1587
{
1050
 
  AlignFileDataPtr  afdp;
1051
1588
  Char              path [PATH_MAX];
1052
1589
  FILE              *fp;
1053
1590
  OMProcControlPtr  ompcp;
1063
1600
  SeqSubmitPtr      ssp;
1064
1601
  Boolean           ok = TRUE, 
1065
1602
                    dirty = FALSE;
1066
 
  ErrInfoPtr        eip;
1067
 
  CharPtr           msg;
1068
 
  Char              str [256];
1069
 
  FILE              *tmpFp;
1070
 
  Char              tmpPath [PATH_MAX];
 
1603
  TSequenceInfoPtr  sequence_info;
 
1604
  ReadBufferData    rbd;
 
1605
  TErrorInfoPtr     error_list;
 
1606
  TAlignmentFilePtr afp;
 
1607
  Uint1             moltype;
 
1608
  ErrSev            sev;
1071
1609
   
1072
1610
  ompcp = (OMProcControlPtr) data;
1073
1611
  if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
1100
1638
  entityID = ObjMgrGetEntityIDForChoice (sep);
1101
1639
  if (entityID < 1)
1102
1640
     return OM_MSG_RET_ERROR;
1103
 
 
1104
 
  if (newAlignReader) {
1105
 
    if (GetInputFileName (path, sizeof (path), NULL, "TEXT")) {
1106
 
      fp = FileOpen (path, "r");
1107
 
      if (fp != NULL) {
1108
 
        afdp = Ali_Read (fp);
1109
 
        FileClose (fp);
1110
 
        if (afdp != NULL) {
1111
 
          if (afdp->errors != NULL) {
1112
 
            TmpNam (tmpPath);
1113
 
            tmpFp = FileOpen (tmpPath, "w");
1114
 
            
1115
 
            for (eip = afdp->errors; eip != NULL; eip = eip->next) {
1116
 
              size_t   len;
1117
 
              if (eip->info == NULL) {
1118
 
                fprintf (tmpFp, "ERROR: eip->info is NULL\n");
1119
 
                continue;
1120
 
              }
1121
 
 
1122
 
              /* Ignore "No source info" errors for updates */
1123
 
 
1124
 
              if ((eip->errNum == ERR_DEFLINE_NODEFS) ||
1125
 
                  (eip->errNum == ERR_GLOBAL_DEFLINE_NODEFS) ||
1126
 
                  (eip->errNum == ERR_MULTI_DEFLINE_NODEFS))
1127
 
                continue;
1128
 
 
1129
 
              len = StringLen (eip->info) + 60;
1130
 
              msg = MemNew (len);
1131
 
              if (msg == NULL) continue;
1132
 
              if (eip->level == LEVEL_MULTI) {
1133
 
                StringCpy (msg, "MULTIPLE ERRORS:");
1134
 
              } else if (eip->level == LEVEL_ERROR) {
1135
 
                StringCpy (msg, "ERROR:");
1136
 
              } else if (eip->level == LEVEL_WARNING) {
1137
 
                StringCpy (msg, "WARNING:");
1138
 
              } else if (eip->level == LEVEL_INFO) {
1139
 
                  StringCpy (msg, "INFO:");
1140
 
              }
1141
 
              if (eip->rowNum != 0) {
1142
 
                sprintf (str, " [Line %ld]", (long) eip->rowNum);
1143
 
                StringCat (msg, str);
1144
 
              }
1145
 
              if (eip->info != NULL) {
1146
 
                  StringCat (msg, " ");
1147
 
                  StringCat (msg, eip->info);
1148
 
              }
1149
 
              fprintf (tmpFp, "%s\n\n", msg);
1150
 
              MemFree (msg);
1151
 
              }
1152
 
            FileClose (tmpFp);
1153
 
            LaunchGeneralTextViewer (tmpPath, "Sequence Alignment Update Errors");
1154
 
            FileRemove (tmpPath);
1155
 
          }
1156
 
          sepnew = ALI_ConvertToNCBIData (afdp);
1157
 
          Ali_Free (afdp);
1158
 
          afdp = NULL;
1159
 
        }
 
1641
  
 
1642
  if (GetInputFileName (path, sizeof (path), NULL, "TEXT")) {
 
1643
    fp = FileOpen (path, "r");
 
1644
    if (fp != NULL) {
 
1645
      sequence_info = GetAlignmentOptions (&moltype);
 
1646
      if (sequence_info == NULL) return OM_MSG_RET_ERROR;
 
1647
      error_list = NULL;
 
1648
 
 
1649
      rbd.fp = fp;
 
1650
      rbd.current_data = NULL;
 
1651
      afp = ReadAlignmentFile ( AbstractReadFunction,
 
1652
                                (Pointer) &rbd,
 
1653
                                AbstractReportError,
 
1654
                                (Pointer) &error_list,
 
1655
                                sequence_info);
 
1656
      if (afp != NULL) 
 
1657
      {
 
1658
        sepnew = MakeSequinDataFromAlignmentEx (afp, moltype, TRUE); 
1160
1659
      }
 
1660
      ProduceAlignmentNotes (afp, error_list);
 
1661
      ErrorInfoFree (error_list);
 
1662
      SequenceInfoFree (sequence_info);
 
1663
      AlignmentFileFree (afp);
 
1664
      Update ();
1161
1665
    }
1162
 
  } else {
1163
 
    sepnew = ReadAnyAlignment (FALSE, NULL);
1164
1666
  }
1165
 
  if (sepnew) {
1166
 
     salpnew = (SeqAlignPtr) FindSeqAlignInSeqEntry (sepnew, OBJ_SEQALIGN);
1167
 
     if (salpnew) {
1168
 
        ok = ValidateSeqAlignandACCInSeqEntry (sepnew, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE);
1169
 
        if (ok) {
1170
 
           salp = (SeqAlignPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN);
1171
 
           if (salp) {
1172
 
              ans = Message (MSG_OKC, "Do you wish to replace (OK) or add (Cancel) the alignment in your SeqEntry?");
1173
 
              if (ans == ANS_OK)
1174
 
              {
1175
 
                 SeqEntryExplore (sep, &dirty, SqnSeqAlignDeleteInSeqEntryCallBack);
1176
 
              }
1177
 
           }
1178
 
           sap=SeqAnnotForSeqAlign(salpnew);
1179
 
           sapcopy = (SeqAnnotPtr) AsnIoMemCopy (sap, (AsnReadFunc) SeqAnnotAsnRead, (AsnWriteFunc) SeqAnnotAsnWrite);
1180
 
           SeqAlignAddInSeqEntry (sep, sapcopy);
1181
 
           sap->data=NULL;
1182
 
           MemFree(sap);
1183
 
           ObjMgrSetDirtyFlag (entityID, TRUE);
1184
 
           itemID = GetItemIDGivenPointer (entityID, OBJ_SEQENTRY, (Pointer) sep);
1185
 
           ObjMgrSendMsg (OM_MSG_UPDATE, entityID, itemID, OBJ_SEQENTRY);
 
1667
  if (sepnew) 
 
1668
  {
 
1669
    salpnew = (SeqAlignPtr) FindSeqAlignInSeqEntry (sepnew, OBJ_SEQALIGN);
 
1670
    if (salpnew) {
 
1671
      sev = ErrSetMessageLevel (SEV_FATAL);
 
1672
   
 
1673
      /* adjust the start positions for the sequences read in from the alignments. */
 
1674
      CalculateAlignmentOffsets (sepnew, sep);
 
1675
      /* ValidateSeqAlignandACCInSeqEntry will readjust the start positions for
 
1676
       * the alignments for far pointer sequences.
 
1677
       */
 
1678
      ok = ValidateSeqAlignandACCInSeqEntry (sepnew, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE);
 
1679
 
 
1680
      ErrSetMessageLevel (sev);
 
1681
      if (ok) {
 
1682
        salp = (SeqAlignPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN);
 
1683
        if (salp) 
 
1684
        {
 
1685
          ans = Message (MSG_OKC, "Do you wish to replace (OK) or add (Cancel) the alignment in your SeqEntry?");
 
1686
          if (ans == ANS_OK)
 
1687
          {
 
1688
            SeqEntryExplore (sep, &dirty, SqnSeqAlignDeleteInSeqEntryCallBack);
 
1689
          }
1186
1690
        }
1187
 
     }
1188
 
     ObjMgrFree (OBJ_SEQENTRY, (Pointer)sepnew);
1189
 
     sepnew=NULL;
 
1691
           
 
1692
        sap=SeqAnnotForSeqAlign(salpnew);
 
1693
        sapcopy = (SeqAnnotPtr) AsnIoMemCopy (sap, (AsnReadFunc) SeqAnnotAsnRead, (AsnWriteFunc) SeqAnnotAsnWrite);
 
1694
           
 
1695
        SeqAlignAddInSeqEntry (sep, sapcopy);
 
1696
        sap->data=NULL;
 
1697
        MemFree(sap); 
 
1698
        ObjMgrSetDirtyFlag (entityID, TRUE);
 
1699
        itemID = GetItemIDGivenPointer (entityID, OBJ_SEQENTRY, (Pointer) sep);
 
1700
        ObjMgrSendMsg (OM_MSG_UPDATE, entityID, itemID, OBJ_SEQENTRY);
 
1701
      }
 
1702
    }
 
1703
    ObjMgrFree (OBJ_SEQENTRY, (Pointer)sepnew);
 
1704
    sepnew=NULL;
1190
1705
  }
1191
1706
  return OM_MSG_RET_OK;
1192
1707
}
1207
1722
   {
1208
1723
      if (sbp->bsp == NULL)
1209
1724
         sbp->bsp = (BioseqPtr)(sep->data.ptrvalue);
1210
 
      else
 
1725
      else if (ISA_na(sbp->bsp->mol))
1211
1726
      {
1212
1727
         while (sbp->next != NULL)
1213
1728
         {
1245
1760
   }
1246
1761
}
1247
1762
 
1248
 
static Int2 LIBCALLBACK GenerateSeqAlignFromSeqEntry (Pointer data)
1249
 
 
1250
 
{
 
1763
typedef struct masterseqform 
 
1764
{
 
1765
  Boolean listBoxAccept;
 
1766
  Boolean listBoxUp;
 
1767
  PopuP   seqPopup;
 
1768
  GrouP   flipFeatGrp;
 
1769
} MasterSeqFormData, PNTR MasterSeqFormPtr;
 
1770
 
 
1771
static void AcceptMasterSeqMessage (ButtoN b)
 
1772
 
 
1773
{
 
1774
  MasterSeqFormPtr mp;
 
1775
  
 
1776
  mp = (MasterSeqFormPtr) GetObjectExtra (b);
 
1777
  if (mp == NULL) return;
 
1778
  mp->listBoxAccept = TRUE;
 
1779
  mp->listBoxUp = FALSE;
 
1780
}
 
1781
 
 
1782
static void CancelMasterSeqMessage (ButtoN b)
 
1783
 
 
1784
{
 
1785
  MasterSeqFormPtr mp;
 
1786
  
 
1787
  mp = (MasterSeqFormPtr) GetObjectExtra (b);
 
1788
  if (mp == NULL) return;
 
1789
  mp->listBoxAccept = FALSE;
 
1790
  mp->listBoxUp = FALSE;
 
1791
}
 
1792
 
 
1793
static void EnableMasterSeqChoice (GrouP g)
 
1794
{
 
1795
  MasterSeqFormPtr mp;
 
1796
  
 
1797
  mp = (MasterSeqFormPtr) GetObjectExtra (g);
 
1798
  if (mp == NULL) return;
 
1799
  if (GetValue (g) == 1)
 
1800
  {
 
1801
        Enable (mp->seqPopup);
 
1802
        Enable (mp->flipFeatGrp);
 
1803
  }
 
1804
  else
 
1805
  {
 
1806
        Disable (mp->seqPopup);
 
1807
        Disable (mp->flipFeatGrp);
 
1808
  }
 
1809
}
 
1810
 
 
1811
static Boolean GetMasterSeq 
 
1812
(ValNodePtr good_list, BioseqPtr PNTR master_bsp, BoolPtr flip_for_aln, BoolPtr flip_feat)
 
1813
 
 
1814
{
 
1815
  GrouP             c;
 
1816
  GrouP             g;
 
1817
  PrompT            ppt1, ppt2, ppt3, ppt4;
 
1818
  WindoW            w;
 
1819
  MasterSeqFormData md;
 
1820
  Int4              i;
 
1821
  Char              buf [41];
 
1822
  ButtoN            b;
 
1823
  Int4              val;
 
1824
  GrouP             flipGrp;
 
1825
  SeqIdPtr          sip;
 
1826
  ValNodePtr        vnp;
 
1827
 
 
1828
  if (good_list == NULL || master_bsp == NULL || flip_for_aln == NULL || flip_feat == NULL)
 
1829
  {
 
1830
        return FALSE;
 
1831
  }
 
1832
  md.listBoxUp = TRUE;
 
1833
  md.listBoxAccept = FALSE;
 
1834
  w = ModalWindow (-50, -20, -20, -20, NULL);
 
1835
  if (w != NULL) {
 
1836
    g = HiddenGroup (w, -1, 0, NULL);
 
1837
    SetGroupSpacing (g, 10, 10);
 
1838
    ppt1 = StaticPrompt (g, "The alignment you are attempting to create contains mixed strands.",
 
1839
                         0, 0, programFont, 'c');
 
1840
    ppt2 = StaticPrompt (g, "Do you wish to reverse complement the sequences to form the alignment?",
 
1841
                         0, 0, programFont, 'c');
 
1842
    flipGrp = HiddenGroup (g, 2, 0, EnableMasterSeqChoice);
 
1843
    SetObjectExtra (flipGrp, &md, NULL);
 
1844
    RadioButton (flipGrp, "Yes");
 
1845
    RadioButton (flipGrp, "No");
 
1846
    SetValue (flipGrp, 2);
 
1847
    
 
1848
    ppt3 = StaticPrompt (g, "Reverse the strands for the features as well?", 0, 0, programFont, 'c');
 
1849
    md.flipFeatGrp = HiddenGroup (g, 2, 0, NULL);
 
1850
    RadioButton (md.flipFeatGrp, "Yes");
 
1851
    RadioButton (md.flipFeatGrp, "No");
 
1852
    SetValue (md.flipFeatGrp, 1);
 
1853
    Disable (md.flipFeatGrp);
 
1854
    
 
1855
    ppt4 = StaticPrompt (g, "Choose a sequence with the correct strand", 0, 0, programFont, 'c');
 
1856
    md.seqPopup = PopupList (g, TRUE, NULL);
 
1857
    for (i = 0, vnp = good_list; vnp != NULL; vnp = vnp->next, i++)
 
1858
    {
 
1859
      sip = (SeqIdPtr) vnp->data.ptrvalue;
 
1860
      SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
 
1861
      PopupItem (md.seqPopup, buf);
 
1862
    }
 
1863
    SetValue (md.seqPopup, 1);
 
1864
    Disable (md.seqPopup);
 
1865
    c = HiddenGroup (g, 2, 0, NULL);
 
1866
    b = DefaultButton (c, "Accept", AcceptMasterSeqMessage);
 
1867
    SetObjectExtra (b, &md, NULL);
 
1868
    b = PushButton (c, "Cancel", CancelMasterSeqMessage);
 
1869
    SetObjectExtra (b, &md, NULL);
 
1870
    AlignObjects (ALIGN_CENTER, (HANDLE) ppt1, (HANDLE) ppt2, (HANDLE) flipGrp,
 
1871
                  (HANDLE) ppt3, (HANDLE) md.flipFeatGrp,
 
1872
                  (HANDLE) ppt4, (HANDLE) md.seqPopup,
 
1873
                  (HANDLE) c, NULL);
 
1874
    RealizeWindow (w);
 
1875
    Show (w);
 
1876
    Select (w);
 
1877
    while (md.listBoxUp) {
 
1878
      ProcessExternalEvent ();
 
1879
      Update ();
 
1880
    }
 
1881
    ProcessAnEvent ();
 
1882
   
 
1883
    if (GetValue (flipGrp) == 1)
 
1884
    {
 
1885
      *flip_for_aln = TRUE;
 
1886
      val = GetValue (md.seqPopup);
 
1887
      for (i = 1, vnp = good_list; i != val && vnp != NULL; vnp = vnp->next, i++)
 
1888
      {
 
1889
      }
 
1890
      if (i != val || vnp == NULL) 
 
1891
      {
 
1892
        md.listBoxAccept = FALSE;
 
1893
      }
 
1894
      else
 
1895
      {
 
1896
        *master_bsp = BioseqFind ((SeqIdPtr)vnp->data.ptrvalue);
 
1897
      }         
 
1898
      if (GetValue (md.flipFeatGrp) == 1)
 
1899
      {
 
1900
        *flip_feat = TRUE;
 
1901
      }
 
1902
      else
 
1903
      {
 
1904
        *flip_feat = FALSE;
 
1905
      }
 
1906
    }
 
1907
    else
 
1908
    {
 
1909
      *flip_for_aln = FALSE;
 
1910
    }
 
1911
    Remove (w);
 
1912
  }
 
1913
  return md.listBoxAccept;
 
1914
 
1915
 
 
1916
static Boolean DoesAlignmentMixStrands (SQNBspPtr sbp)
 
1917
{
 
1918
  Boolean           revcomp = FALSE;
 
1919
  SQNBspPtr         sbp_idx;
 
1920
  SeqAlignPtr       salp;
 
1921
  Boolean           some_reversed = FALSE;
 
1922
  
 
1923
  if (sbp == NULL) return FALSE;
 
1924
  
 
1925
  for (sbp_idx = sbp->next; sbp_idx != NULL; sbp_idx = sbp_idx->next)
 
1926
  {
 
1927
    salp = Sqn_GlobalAlign2Seq(sbp->bsp, sbp_idx->bsp, &revcomp);
 
1928
    SeqAlignFree (salp);        
 
1929
    if (revcomp)
 
1930
    {
 
1931
      BioseqRevComp (sbp_idx->bsp);
 
1932
      ReverseBioseqFeatureStrands (sbp_idx->bsp);
 
1933
      some_reversed = TRUE;
 
1934
    }
 
1935
  }
 
1936
  return some_reversed;
 
1937
}
 
1938
 
 
1939
static ValNodePtr FreeSequenceIDValNodeList (ValNodePtr seqlist)
 
1940
{
 
1941
  ValNodePtr vnp;
 
1942
  SeqIdPtr   sip;
 
1943
  
 
1944
  if (seqlist == NULL) return NULL;
 
1945
  for (vnp = seqlist; vnp != NULL; vnp = vnp->next)
 
1946
  {
 
1947
    sip = (SeqIdPtr) vnp->data.ptrvalue;
 
1948
    SeqIdFree (sip);
 
1949
  }
 
1950
  ValNodeFree (seqlist);
 
1951
  return NULL;
 
1952
}
 
1953
 
 
1954
static void GetBadSequencesAndReversals 
 
1955
(SQNBspPtr       sbp, 
 
1956
 Uint2           entityID,
 
1957
 BoolPtr         some_reversed,
 
1958
 Int4Ptr         num_seqs,
 
1959
 ValNodePtr PNTR good_list_ptr,
 
1960
 ValNodePtr PNTR bad_list_ptr)
 
1961
{
 
1962
  Boolean           revcomp = FALSE;
 
1963
  SQNBspPtr         sbp_idx;
 
1964
  SeqAlignPtr       salp;
 
1965
  ValNodePtr        bad_list = NULL, vnp;
 
1966
  SeqIdPtr          tmp_id;
 
1967
  Boolean           dirty;
 
1968
  ValNodePtr        good_list = NULL;
 
1969
  
 
1970
  if (sbp == NULL) return;
 
1971
  if (some_reversed != NULL)
 
1972
  {
 
1973
    *some_reversed = FALSE;
 
1974
  }
 
1975
  
 
1976
  if (num_seqs != NULL)
 
1977
  {
 
1978
    *num_seqs = 1;
 
1979
  }
 
1980
  for (sbp_idx = sbp->next; sbp_idx != NULL; sbp_idx = sbp_idx->next)
 
1981
  {
 
1982
    if (num_seqs != NULL)
 
1983
    {
 
1984
      (*num_seqs) ++;
 
1985
    }
 
1986
    revcomp = FALSE;
 
1987
    salp = Sqn_GlobalAlign2Seq(sbp->bsp, sbp_idx->bsp, &revcomp);
 
1988
    if (salp == NULL || ! ValidateSeqAlign (salp, entityID, FALSE, FALSE, TRUE, FALSE, FALSE, &dirty))
 
1989
    {
 
1990
      tmp_id = SeqIdDup (SeqIdFindBest (sbp_idx->bsp->id, 0));
 
1991
      if (tmp_id != NULL)
 
1992
      {
 
1993
        vnp = ValNodeNew (bad_list);
 
1994
        if (vnp != NULL)
 
1995
        {
 
1996
          vnp->data.ptrvalue = tmp_id;
 
1997
        }
 
1998
        if (bad_list == NULL)
 
1999
        {
 
2000
          bad_list = vnp;
 
2001
        }
 
2002
      }
 
2003
    }
 
2004
    else
 
2005
    {
 
2006
      tmp_id = SeqIdDup (SeqIdFindBest (sbp_idx->bsp->id, 0));
 
2007
      if (tmp_id != NULL)
 
2008
      {
 
2009
        vnp = ValNodeNew (good_list);
 
2010
        if (vnp != NULL)
 
2011
        {
 
2012
          vnp->data.ptrvalue = tmp_id;
 
2013
        }
 
2014
        if (good_list == NULL)
 
2015
        {
 
2016
          good_list = vnp;
 
2017
        }
 
2018
      }
 
2019
      if (revcomp)
 
2020
      {
 
2021
        if (some_reversed != NULL)
 
2022
        {
 
2023
          *some_reversed = TRUE;
 
2024
        }
 
2025
      }
 
2026
    }
 
2027
    SeqAlignFree (salp);        
 
2028
    if (revcomp)
 
2029
    {
 
2030
      BioseqRevComp (sbp_idx->bsp);
 
2031
      ReverseBioseqFeatureStrands (sbp_idx->bsp);
 
2032
    }
 
2033
  }
 
2034
  if (good_list_ptr != NULL)
 
2035
  {
 
2036
    *good_list_ptr = good_list;
 
2037
  }
 
2038
  else
 
2039
  {
 
2040
    FreeSequenceIDValNodeList (good_list);
 
2041
  }
 
2042
  if (bad_list_ptr != NULL)
 
2043
  {
 
2044
    *bad_list_ptr = bad_list;
 
2045
  } 
 
2046
  else
 
2047
  {
 
2048
    FreeSequenceIDValNodeList (bad_list);
 
2049
  }
 
2050
}
 
2051
 
 
2052
static MsgAnswer ContinueWithBadSequences (ValNodePtr bad_list, Int4 num_seqs)
 
2053
{
 
2054
  Int4       num_bad_seq;
 
2055
  Char       buf [41];
 
2056
  CharPtr    msg_start = "BLAST is unable to create valid pairwise "
 
2057
           "alignments for the following sequences:\n"; 
 
2058
  CharPtr    msg_end = "Do you want to create this alignment without "
 
2059
           "these sequences?";
 
2060
  CharPtr    msg;
 
2061
  Int4       msg_len;
 
2062
  ValNodePtr vnp;
 
2063
  SeqIdPtr   tmp_id;
 
2064
  MsgAnswer  ans = ANS_YES;
 
2065
 
 
2066
  if (bad_list == NULL) return ANS_YES;
 
2067
  num_bad_seq = ValNodeLen (bad_list);
 
2068
  if (num_bad_seq == 0) return ANS_YES;
 
2069
  if (num_bad_seq == num_seqs)
 
2070
  {
 
2071
    Message (MSG_ERROR, "BLAST is unable to create valid pairwise alignments "
 
2072
             "for any of the sequences.  No alignment will be created.");
 
2073
    return ANS_NO;
 
2074
  }
 
2075
  msg_len = StringLen (msg_start) + StringLen (msg_end)
 
2076
            + num_bad_seq * (sizeof (buf) + 2) + 3;
 
2077
  
 
2078
  msg = (CharPtr) MemNew (msg_len * sizeof (Char));
 
2079
  if (msg != NULL)
 
2080
  {
 
2081
    StringCat (msg, msg_start);
 
2082
    for (vnp = bad_list; vnp != NULL; vnp = vnp->next)
 
2083
    {
 
2084
      tmp_id = (SeqIdPtr) vnp->data.ptrvalue;
 
2085
      SeqIdWrite (tmp_id, buf, PRINTID_REPORT, sizeof (buf) - 1);
 
2086
      StringCat (msg, buf);
 
2087
      if (vnp->next != NULL)
 
2088
      {
 
2089
        StringCat (msg, ", ");
 
2090
      }
 
2091
    }
 
2092
    StringCat (msg, msg_end);
 
2093
    ans = Message (MSG_YN, msg);
 
2094
    MemFree (msg);
 
2095
  }
 
2096
  return ans;
 
2097
}
 
2098
 
 
2099
/* In order to create alignments for segmented sets, first need to change
 
2100
 * method of collecting bioseqs to collect one set per segment, then
 
2101
 * need to to process each set individually.
 
2102
 */
 
2103
static void FindSegSetsCallback (BioseqSetPtr bssp, Pointer userdata)
 
2104
{
 
2105
  SeqEntryPtr     sep;
 
2106
  BioseqSetPtr    segment_set = NULL;
 
2107
  ValNodePtr      vnp;
 
2108
  ValNodePtr PNTR seg_list;
 
2109
  SQNBspPtr       sbp;
 
2110
  
 
2111
  if (bssp == NULL || bssp->_class != BioseqseqSet_class_segset 
 
2112
      || userdata == NULL) return;
 
2113
  
 
2114
  for (sep = bssp->seq_set; sep != NULL && segment_set == NULL; sep = sep->next)
 
2115
  {
 
2116
    if (IS_Bioseq_set (sep))
 
2117
    {
 
2118
      segment_set = sep->data.ptrvalue;
 
2119
      if (segment_set != NULL && segment_set->_class != BioseqseqSet_class_parts)
 
2120
      {
 
2121
        segment_set = NULL;
 
2122
      }
 
2123
    }
 
2124
  }
 
2125
  if (segment_set != NULL)
 
2126
  {
 
2127
    seg_list = (ValNodePtr PNTR) userdata;
 
2128
    vnp = *seg_list;
 
2129
    for (sep = segment_set->seq_set; sep != NULL; sep = sep->next)
 
2130
    {
 
2131
      if (!IS_Bioseq (sep)) continue;
 
2132
      if (vnp == NULL)
 
2133
      {
 
2134
        vnp = ValNodeNew (*seg_list);
 
2135
        if (*seg_list == NULL)
 
2136
        {
 
2137
          *seg_list = vnp;
 
2138
        }
 
2139
        sbp = MemNew (sizeof (SQNBsp));
 
2140
        sbp->bsp = (BioseqPtr)sep->data.ptrvalue;
 
2141
        sbp->next = NULL;
 
2142
        vnp->data.ptrvalue = sbp;
 
2143
      }
 
2144
      else
 
2145
      {
 
2146
        sbp = (SQNBspPtr) vnp->data.ptrvalue;
 
2147
        if (sbp == NULL)
 
2148
        {
 
2149
          sbp = MemNew (sizeof (SQNBsp));
 
2150
          sbp->bsp = (BioseqPtr)sep->data.ptrvalue;
 
2151
          sbp->next = NULL;
 
2152
          vnp->data.ptrvalue = sbp;
 
2153
        }
 
2154
        else
 
2155
        {
 
2156
          while (sbp->next != NULL)
 
2157
          {
 
2158
            sbp = sbp->next;
 
2159
          }
 
2160
          sbp->next = (SQNBspPtr)MemNew(sizeof(SQNBsp));
 
2161
          sbp->next->bsp = (BioseqPtr)(sep->data.ptrvalue);
 
2162
        }
 
2163
      }
 
2164
      vnp = vnp->next;
 
2165
    }
 
2166
  }  
 
2167
}
 
2168
 
 
2169
static void FindNucBioseqsCallback (BioseqPtr bsp, Pointer userdata)
 
2170
{
 
2171
  ValNodePtr PNTR seg_list;
 
2172
  ValNodePtr      vnp;
 
2173
  SQNBspPtr       sbp;
 
2174
 
 
2175
  if (bsp == NULL || ! ISA_na(bsp->mol) || userdata == NULL)
 
2176
    return;
 
2177
  
 
2178
  seg_list = (ValNodePtr PNTR) userdata;
 
2179
  if (*seg_list == NULL)
 
2180
  {
 
2181
    vnp = ValNodeNew (*seg_list);
 
2182
    if (vnp == NULL) return;
 
2183
    *seg_list = vnp;
 
2184
  }
 
2185
  else
 
2186
  {
 
2187
    vnp = *seg_list;
 
2188
  }
 
2189
  sbp = (SQNBspPtr)vnp->data.ptrvalue;
 
2190
  if (sbp == NULL)
 
2191
  {
 
2192
    sbp = MemNew (sizeof (SQNBsp));
 
2193
    if (sbp == NULL) return;
 
2194
    sbp->bsp = bsp;
 
2195
    sbp->next = NULL;
 
2196
    vnp->data.ptrvalue = sbp;
 
2197
  }
 
2198
  else
 
2199
  {
 
2200
    while (sbp->next != NULL)
 
2201
    {
 
2202
      sbp = sbp->next;
 
2203
    }
 
2204
    sbp->next = (SQNBspPtr)MemNew(sizeof(SQNBsp));
 
2205
    sbp->next->bsp = bsp;
 
2206
  }
 
2207
}
 
2208
 
 
2209
static ValNodePtr GetAlignmentSegmentsList (SeqEntryPtr sep)
 
2210
{
 
2211
  ValNodePtr seg_list = NULL;
 
2212
  if (sep == NULL) return NULL;
 
2213
  
 
2214
  VisitSetsInSep (sep, &seg_list, FindSegSetsCallback);
 
2215
  if (seg_list == NULL)
 
2216
  {
 
2217
    VisitBioseqsInSep (sep, &seg_list, FindNucBioseqsCallback);
 
2218
  }
 
2219
  return seg_list;
 
2220
}
 
2221
 
 
2222
static Int2 CreateOneAlignment 
 
2223
(SQNBspPtr sbp, 
 
2224
 Uint2     entityID,
 
2225
 FILE      *fp,
 
2226
 BoolPtr   errors_in_log)
 
2227
{
 
2228
  BioseqPtr         master_bsp;
 
2229
  Boolean           some_reversed;
 
2230
  ValNodePtr        bad_list, good_list;
 
2231
  MsgAnswer         continue_with_bad;
 
2232
  Int4              num_seqs = 0;
 
2233
  Boolean           flip_for_aln = FALSE;
 
2234
  Boolean           flip_feat = FALSE;
 
2235
  SeqAlignPtr       salp, salp_head, salp_prev, salp_tmp, salp_mult;
 
2236
  Boolean           revcomp = FALSE;
 
2237
  SeqIdPtr          sip, sip1, sip2;
 
2238
  Char              buf [41];
1251
2239
  BioseqPtr         bsp;
 
2240
  SQNBspPtr         sbp_prev;
 
2241
  Boolean           dirty;
 
2242
  DenseSegPtr       dsp;
 
2243
  SeqAnnotPtr       sap;
 
2244
  ObjectIdPtr       oip;
 
2245
  UserObjectPtr     uop;
 
2246
  UserFieldPtr      ufp;
 
2247
  SeqEntryPtr       sep;
 
2248
  SeqAnnotPtr PNTR  sapp;
1252
2249
  BioseqSetPtr      bssp;
1253
 
  Int4              chlen;
1254
2250
  SeqAnnotPtr       curr;
1255
 
  Int4              endsfixed;
1256
 
  ObjectIdPtr       oip;
1257
 
  OMProcControlPtr  ompcp;
1258
 
  SeqAlignPtr       salp;
1259
 
  SeqAlignPtr       salp_head;
1260
 
  SeqAlignPtr       salp_mult;
1261
 
  SeqAlignPtr       salp_prev;
1262
 
  SeqAlignPtr       salp_tmp;
1263
 
  SeqAnnotPtr       sap;
1264
 
  SeqAnnotPtr PNTR  sapp;
1265
 
  SQNBspPtr         sbp;
1266
 
  SQNBspPtr         sbp_prev;
1267
 
  SeqEntryPtr       sep;
1268
 
  UserFieldPtr      ufp;
1269
 
  UserObjectPtr     uop;
1270
 
 
1271
 
  ompcp = (OMProcControlPtr) data;
1272
 
  if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
1273
 
  switch (ompcp->input_itemtype) {
1274
 
    case OBJ_BIOSEQ :
1275
 
      break;
1276
 
    case OBJ_BIOSEQSET :
1277
 
      break;
1278
 
    case 0 :
1279
 
      return OM_MSG_RET_ERROR;
1280
 
    default :
1281
 
      return OM_MSG_RET_ERROR;
1282
 
  }
1283
 
  if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
1284
 
  sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
1285
 
  if (sep == NULL) return OM_MSG_RET_ERROR;
1286
 
  sbp = (SQNBspPtr)MemNew(sizeof(SQNBsp));
1287
 
  SeqEntryExplore(sep, sbp, SQNGetBioseqs);
 
2251
  ValNodePtr        vnp;
 
2252
  Int4              num_reversed = 0;
 
2253
  
 
2254
  if (sbp == NULL || errors_in_log == NULL) return;
 
2255
 
 
2256
  master_bsp = sbp->bsp;
 
2257
  GetBadSequencesAndReversals (sbp, entityID, &some_reversed, &num_seqs, &good_list, &bad_list);
 
2258
  continue_with_bad = ContinueWithBadSequences(bad_list, num_seqs);
 
2259
  if (continue_with_bad != ANS_YES)
 
2260
  {
 
2261
    bad_list = FreeSequenceIDValNodeList (bad_list);
 
2262
    return OM_MSG_RET_DONE;
 
2263
  }
 
2264
  if (some_reversed)
 
2265
  {
 
2266
    if (! GetMasterSeq (good_list, &master_bsp, &flip_for_aln, &flip_feat))
 
2267
    {
 
2268
      bad_list = FreeSequenceIDValNodeList (bad_list);
 
2269
      return OM_MSG_RET_ERROR;
 
2270
    }   
 
2271
  }
 
2272
  
 
2273
  if (bad_list != NULL)
 
2274
  {
 
2275
    fprintf (fp, "The following sequences were omitted from the alignment:\n");
 
2276
    for (vnp = bad_list; vnp != NULL; vnp = vnp->next)
 
2277
    {
 
2278
      sip = (SeqIdPtr) vnp->data.ptrvalue;
 
2279
      SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
 
2280
      fprintf (fp, "%s\n", buf);
 
2281
    }    
 
2282
    bad_list = FreeSequenceIDValNodeList (bad_list);
 
2283
    *errors_in_log = TRUE;
 
2284
  }
 
2285
 
 
2286
  if (flip_for_aln && master_bsp != sbp->bsp)
 
2287
  {  
 
2288
    /* we align the master with the top of the list - this will reverse the strandedness
 
2289
     * of the top of the list if necessary.
 
2290
     */
 
2291
    revcomp = FALSE;
 
2292
    salp = Sqn_GlobalAlign2Seq(master_bsp, sbp->bsp, &revcomp);
 
2293
    SeqAlignFree (salp); 
 
2294
    if (revcomp)
 
2295
    {
 
2296
      if (!flip_feat)
 
2297
      {
 
2298
        ReverseBioseqFeatureStrands (sbp->bsp);         
 
2299
      }
 
2300
      fprintf (fp, "The following sequences were reversed in order to "
 
2301
                              "construct the alignment:\n");
 
2302
      sip = SeqIdFindBest(sbp->bsp->id, 0);
 
2303
      SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
 
2304
      fprintf (fp, "%s\n", buf);
 
2305
      num_reversed ++;          
 
2306
    }
 
2307
  }
 
2308
  
1288
2309
  bsp = sbp->bsp;
1289
2310
  sbp_prev = sbp;
1290
2311
  sbp = sbp->next;
1291
2312
  MemFree(sbp_prev);
1292
2313
  salp_head = salp_prev = NULL;
1293
 
  endsfixed = 0;
 
2314
  
 
2315
 
 
2316
  num_seqs = 1;
1294
2317
  while (sbp != NULL)
1295
2318
  {
1296
 
    salp = Sequin_GlobalAlignTwoSeq(bsp, sbp->bsp, &chlen);
1297
 
    if (chlen > endsfixed)
1298
 
       endsfixed = chlen;
1299
 
    if (salp != NULL && salp_head != NULL)
 
2319
    if (ISA_na(sbp->bsp->mol))
1300
2320
    {
1301
 
       salp_prev->next = salp;
1302
 
       salp_prev = salp;
1303
 
    } else if (salp != NULL)
1304
 
       salp_head = salp_prev = salp;
 
2321
       sip1 = SeqIdDup(bsp->id);
 
2322
       sip2 = SeqIdDup(sbp->bsp->id);
 
2323
       revcomp = FALSE;
 
2324
#if 0
 
2325
       SqnNewAlign (bsp, sbp->bsp, &salp);
 
2326
#else
 
2327
       salp = Sqn_GlobalAlign2Seq(bsp, sbp->bsp, &revcomp);
 
2328
#endif
 
2329
       if (revcomp) {
 
2330
         if (flip_for_aln)
 
2331
         {
 
2332
           if (!flip_feat)
 
2333
           {
 
2334
             ReverseBioseqFeatureStrands (sbp->bsp);            
 
2335
           }
 
2336
           if (num_reversed == 0)
 
2337
           {
 
2338
                 fprintf (fp, "The following sequences were reversed in order to "
 
2339
                              "construct the alignment:\n");
 
2340
           }
 
2341
           sip = SeqIdFindBest(sbp->bsp->id, 0);
 
2342
           SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
 
2343
           fprintf (fp, "%s\n", buf);
 
2344
           num_reversed ++;     
 
2345
         }
 
2346
         else
 
2347
         {
 
2348
           BioseqRevComp (sbp->bsp);
 
2349
           ReverseBioseqFeatureStrands (sbp->bsp);
 
2350
         }
 
2351
         revcomp = FALSE;
 
2352
       }
 
2353
       num_seqs ++;
 
2354
       if (!ValidateSeqAlign (salp, entityID, FALSE, FALSE, TRUE, FALSE, FALSE, &dirty))
 
2355
       {
 
2356
         salp = SeqAlignFree (salp);
 
2357
       }
 
2358
       if (salp != NULL)
 
2359
       {
 
2360
         dsp = (DenseSegPtr)(salp->segs);
 
2361
         SeqIdSetFree(dsp->ids);
 
2362
         dsp->ids = sip1;
 
2363
         dsp->ids->next = sip2;
 
2364
         if (salp != NULL && salp_head != NULL) {
 
2365
            salp_prev->next = salp;
 
2366
            salp_prev = salp;
 
2367
         } else if (salp != NULL) {
 
2368
          salp_head = salp_prev = salp;
 
2369
         }
 
2370
       }
 
2371
    }
1305
2372
    sbp_prev = sbp;
1306
2373
    sbp = sbp->next;
1307
2374
    MemFree(sbp_prev);
1308
2375
  }
1309
 
  if (endsfixed > 0)
1310
 
  {
1311
 
    Message(MSG_OK, "The first sequence does not extend to both ends, so as much as %d nt%s on the ends %s not been algorithmically aligned.\nIf the ends do not look correctly aligned, and a good alignment is needed in those areas,\nchoose a sequence that extends to the desired end and put that first, then realign.", endsfixed, endsfixed > 1?"s":"", endsfixed > 1?"have":"has");
1312
 
  }
1313
2376
  if (salp_head != NULL)
1314
2377
  {
1315
2378
    salp_tmp = salp_head;
1322
2385
       }
1323
2386
       salp_tmp = salp_tmp->next;
1324
2387
    }
1325
 
    AlnMgr2IndexSeqAlign(salp_head);
1326
 
    salp_mult = AlnMgr2GetSubAlign(salp_head, 0, -1, 0);
 
2388
    AlnMgr2IndexSeqAlignEx(salp_head, FALSE);
 
2389
    salp_mult = AlnMgr2GetSubAlign(salp_head, 0, -1, 0, TRUE);
1327
2390
    salp_mult->dim = AlnMgr2GetNumRows(salp_head);
1328
2391
    salp_mult->type = SAT_PARTIAL;
 
2392
    ValidateSeqAlign (salp_mult, entityID, TRUE, FALSE, TRUE, FALSE, FALSE, &dirty);
1329
2393
    SeqAlignSetFree(salp_head);
1330
2394
    sap = SeqAnnotForSeqAlign(salp_mult);
1331
2395
  } else
1345
2409
    ufp->label = oip;
1346
2410
 
1347
2411
    uop->data = ufp;
1348
 
        ValNodeAddPointer (&(sap->desc), Annot_descr_user, (Pointer) uop);
 
2412
          ValNodeAddPointer (&(sap->desc), Annot_descr_user, (Pointer) uop);
1349
2413
 
1350
 
    sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
 
2414
    sep = GetTopSeqEntryForEntityID (entityID);
1351
2415
    if (sep != NULL && sep->data.ptrvalue != NULL) {
1352
2416
      sapp = NULL;
1353
2417
      if (IS_Bioseq (sep)) {
1368
2432
          *sapp = sap;
1369
2433
        }
1370
2434
      }
1371
 
      ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
1372
 
      ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
 
2435
      ObjMgrSetDirtyFlag (entityID, TRUE);
 
2436
      ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
1373
2437
    }
1374
2438
  }
 
2439
  if (num_reversed > 0)
 
2440
  {
 
2441
    fprintf (fp, "%d out of %d sequences were reversed.\n", num_reversed, num_seqs);    
 
2442
    *errors_in_log = TRUE;
 
2443
  }
 
2444
}
 
2445
 
 
2446
static Int2 LIBCALLBACK GenerateSeqAlignFromSeqEntry (Pointer data) 
 
2447
 
 
2448
{
 
2449
  OMProcControlPtr  ompcp;
 
2450
  SQNBspPtr         sbp;
 
2451
  SeqEntryPtr       sep;
 
2452
  Char              path [PATH_MAX]; /* path for log of sequences reversed during alignment */
 
2453
  FILE             *fp;              /* file pointer for sequence reverse log */
 
2454
  Boolean           errors_in_log = FALSE;
 
2455
  ValNodePtr        seg_aln_list, vnp;
 
2456
  
 
2457
 
 
2458
  ompcp = (OMProcControlPtr) data;
 
2459
  if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
 
2460
  switch (ompcp->input_itemtype) {
 
2461
    case OBJ_BIOSEQ :
 
2462
      break;
 
2463
    case OBJ_BIOSEQSET :
 
2464
      break;
 
2465
    case 0 :
 
2466
      return OM_MSG_RET_ERROR;
 
2467
    default :
 
2468
      return OM_MSG_RET_ERROR;
 
2469
  }
 
2470
  if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
 
2471
  sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
 
2472
  if (sep == NULL) return OM_MSG_RET_ERROR;
 
2473
  
 
2474
  TmpNam (path);
 
2475
  fp = FileOpen (path, "wb");
 
2476
  if (fp == NULL) return OM_MSG_RET_ERROR;
 
2477
  
 
2478
  seg_aln_list = GetAlignmentSegmentsList (sep);
 
2479
  for (vnp = seg_aln_list; vnp != NULL; vnp = vnp->next)
 
2480
  {
 
2481
    sbp = vnp->data.ptrvalue;
 
2482
    if (sbp == NULL) continue;
 
2483
    CreateOneAlignment (sbp, ompcp->input_entityID, fp, &errors_in_log);
 
2484
  }
 
2485
  
 
2486
  FileClose (fp);
 
2487
  if (errors_in_log > 0) {
 
2488
    LaunchGeneralTextViewer (path, "Alignment Notes");
 
2489
  }
 
2490
  FileRemove (path);
 
2491
 
1375
2492
  return OM_MSG_RET_DONE;
1376
2493
}
1377
2494
 
 
2495
 
1378
2496
static Int2 LIBCALLBACK GenerateSeqAlignFromSeqEntryProt (Pointer data)
1379
2497
 
1380
2498
{
1381
2499
  BioseqPtr         bsp;
1382
2500
  BioseqSetPtr      bssp;
1383
 
  Int4              chlen;
1384
2501
  SeqAnnotPtr       curr;
1385
 
  Int4              endsfixed;
1386
2502
  ObjectIdPtr       oip;
1387
2503
  OMProcControlPtr  ompcp;
1388
2504
  SeqAlignPtr       salp;
1420
2536
  sbp = sbp->next;
1421
2537
  MemFree(sbp_prev);
1422
2538
  salp_head = salp_prev = NULL;
1423
 
  endsfixed = 0;
1424
2539
  while (sbp != NULL)
1425
2540
  {
1426
 
    salp = Sequin_GlobalAlignTwoSeq(bsp, sbp->bsp, &chlen);
1427
 
    if (chlen > endsfixed)
1428
 
       endsfixed = chlen;
 
2541
    salp = Sqn_GlobalAlign2Seq(bsp, sbp->bsp, FALSE);
1429
2542
    if (salp_head != NULL && salp != NULL)
1430
2543
    {
1431
2544
       salp_prev->next = salp;
1436
2549
    sbp = sbp->next;
1437
2550
    MemFree(sbp_prev);
1438
2551
  }
1439
 
  if (endsfixed > 1)
1440
 
    Message(MSG_OK, "The first sequence does not extend to both ends, so as much as %d nt%s on the ends %s not been algorithmically aligned.\nIf the ends do not look correctly aligned, and a good alignment is needed in those areas,\nchoose a sequence that extends to the desired end and put that first, then realign.", endsfixed, endsfixed > 1?"s":"", endsfixed > 1?"have":"has");
1441
2552
  if (salp_head != NULL)
1442
2553
  {
1443
2554
    salp_tmp = salp_head;
1451
2562
       salp_tmp = salp_tmp->next;
1452
2563
    }
1453
2564
    AlnMgr2IndexSeqAlign(salp_head);
1454
 
    salp_mult = AlnMgr2GetSubAlign(salp_head, 0, -1, 0);
 
2565
    salp_mult = AlnMgr2GetSubAlign(salp_head, 0, -1, 0, TRUE);
1455
2566
    salp_mult->dim = AlnMgr2GetNumRows(salp_head);
1456
2567
    salp_mult->type = SAT_PARTIAL;
1457
2568
    SeqAlignSetFree(salp_head);
1503
2614
  return OM_MSG_RET_DONE;
1504
2615
}
1505
2616
 
 
2617
static Int2 LIBCALLBACK GenerateSeqAlignDiscFromSeqEntry (Pointer data)
 
2618
 
 
2619
{
 
2620
  BioseqPtr            bsp;
 
2621
  BioseqSetPtr         bssp;
 
2622
  SeqAnnotPtr          curr;
 
2623
  ObjectIdPtr          oip;
 
2624
  OMProcControlPtr     ompcp;
 
2625
  BLAST_OptionsBlkPtr  options;
 
2626
  CharPtr              program;
 
2627
  SeqAlignPtr          salp;
 
2628
  SeqAlignPtr          salp_head;
 
2629
  SeqAlignPtr          salp_mult;
 
2630
  SeqAlignPtr          salp_prev;
 
2631
  SeqAlignPtr          salp_tmp;
 
2632
  SeqAnnotPtr          sap;
 
2633
  SeqAnnotPtr          PNTR sapp;
 
2634
  SQNBspPtr            sbp;
 
2635
  SQNBspPtr            sbp_prev;
 
2636
  SeqEntryPtr          sep;
 
2637
  UserFieldPtr         ufp;
 
2638
  UserObjectPtr        uop;
 
2639
 
 
2640
  ompcp = (OMProcControlPtr) data;
 
2641
  if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
 
2642
  switch (ompcp->input_itemtype) {
 
2643
    case OBJ_BIOSEQ :
 
2644
      break;
 
2645
    case OBJ_BIOSEQSET :
 
2646
      break;
 
2647
    case 0 :
 
2648
      return OM_MSG_RET_ERROR;
 
2649
    default :
 
2650
      return OM_MSG_RET_ERROR;
 
2651
  }
 
2652
  if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
 
2653
  sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
 
2654
  if (sep == NULL) return OM_MSG_RET_ERROR;
 
2655
  sbp = (SQNBspPtr)MemNew(sizeof(SQNBsp));
 
2656
  SeqEntryExplore(sep, sbp, SQNGetBioseqs);
 
2657
  bsp = sbp->bsp;
 
2658
  sbp_prev = sbp;
 
2659
  sbp = sbp->next;
 
2660
  MemFree(sbp_prev);
 
2661
  salp_head = salp_prev = NULL;
 
2662
  if (ISA_na(bsp->mol))
 
2663
     program = StringSave("blastn");
 
2664
  else
 
2665
     program = StringSave("blastp");
 
2666
  while (sbp != NULL)
 
2667
  {
 
2668
    options = BLASTOptionNew(program, TRUE);
 
2669
    options->filter_string = StringSave("m L;R");
 
2670
    salp = BlastTwoSequences(bsp, sbp->bsp, program, options);
 
2671
    BLASTOptionDelete(options);
 
2672
    if (salp != NULL)
 
2673
    {
 
2674
       AlnMgr2IndexLite(salp);
 
2675
       SPI_RemoveInconsistentAlnsFromSet(salp, 0, 1, SPI_LEFT);
 
2676
       salp_tmp = (SeqAlignPtr)(salp->segs);
 
2677
       salp->segs = NULL;
 
2678
       SeqAlignFree(salp);
 
2679
       salp = salp_tmp;
 
2680
    }
 
2681
    if (salp != NULL && salp_head != NULL)
 
2682
    {
 
2683
       salp_prev->next = salp;
 
2684
       salp_prev = salp;
 
2685
    } else if (salp != NULL)
 
2686
       salp_head = salp_prev = salp;
 
2687
    while (salp_prev != NULL && salp_prev->next != NULL)
 
2688
    {
 
2689
       salp_prev = salp_prev->next;
 
2690
    }
 
2691
    sbp_prev = sbp;
 
2692
    sbp = sbp->next;
 
2693
    MemFree(sbp_prev);
 
2694
  }
 
2695
  if (salp_head != NULL)
 
2696
  {
 
2697
    salp_tmp = salp_head;
 
2698
    while (salp_tmp != NULL)
 
2699
    {
 
2700
       if (salp_tmp->saip != NULL)
 
2701
       {
 
2702
          SeqAlignIndexFree(salp_tmp->saip);
 
2703
          salp_tmp->saip = NULL;
 
2704
       }
 
2705
       salp_tmp = salp_tmp->next;
 
2706
    }
 
2707
    AlnMgr2IndexSeqAlign(salp_head);
 
2708
    salp_mult = AlnMgr2GetSubAlign(salp_head, 0, -1, 0, FALSE);
 
2709
    SeqAlignSetFree(salp_head);
 
2710
    sap = SeqAnnotForSeqAlign(salp_mult);
 
2711
  } else
 
2712
    sap = NULL;
 
2713
  if (sap != NULL) {
 
2714
 
 
2715
    oip = ObjectIdNew ();
 
2716
    oip->str = StringSave ("Hist Seqalign");
 
2717
    uop = UserObjectNew ();
 
2718
    uop->type = oip;
 
2719
 
 
2720
    oip = ObjectIdNew();
 
2721
    oip->str = StringSave ("Hist Seqalign");
 
2722
    ufp = UserFieldNew ();
 
2723
    ufp->choice = 4;
 
2724
    ufp->data.boolvalue = TRUE;
 
2725
    ufp->label = oip;
 
2726
 
 
2727
    uop->data = ufp;
 
2728
        ValNodeAddPointer (&(sap->desc), Annot_descr_user, (Pointer) uop);
 
2729
 
 
2730
    sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
 
2731
    if (sep != NULL && sep->data.ptrvalue != NULL) {
 
2732
      sapp = NULL;
 
2733
      if (IS_Bioseq (sep)) {
 
2734
        bsp = (BioseqPtr) sep->data.ptrvalue;
 
2735
        sapp = &(bsp->annot);
 
2736
      } else if (IS_Bioseq_set (sep)) {
 
2737
        bssp = (BioseqSetPtr) sep->data.ptrvalue;
 
2738
        sapp = &(bssp->annot);
 
2739
      }
 
2740
      if (sapp != NULL) {
 
2741
        if (*sapp != NULL) {
 
2742
          curr = *sapp;
 
2743
          while (curr->next != NULL) {
 
2744
            curr = curr->next;
 
2745
          }
 
2746
          curr->next = sap;
 
2747
        } else {
 
2748
          *sapp = sap;
 
2749
        }
 
2750
      }
 
2751
      ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
 
2752
      ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
 
2753
    }
 
2754
  }
 
2755
  return OM_MSG_RET_DONE;
 
2756
}
 
2757
 
1506
2758
static Boolean RawSeqLaunchFunc (GatherContextPtr gcp)
1507
2759
 
1508
2760
{
1583
2835
  return slpnew;
1584
2836
}
1585
2837
 
1586
 
static SeqFeatPtr SeqFeatCopy (SeqFeatPtr sfp)
 
2838
extern SeqFeatPtr SeqFeatCopy (SeqFeatPtr sfp)
1587
2839
{
1588
2840
  SeqFeatPtr  sfpnew;
1589
2841
 
1673
2925
 
1674
2926
{
1675
2927
  OMProcControlPtr  ompcp;
1676
 
  SeqFeatPtr        sfp;
1677
 
  SeqEntryPtr       sep;
 
2928
  SelStructPtr      ssp;
 
2929
  Boolean           isDirty = FALSE;
 
2930
  Boolean           isFirstSsp;
 
2931
  ExplodeStructPtr  esp;
 
2932
  ExplodeStructPtr  firstEsp = NULL;
 
2933
  ExplodeStructPtr  lastEsp;
 
2934
  Boolean           isFirstEsp;
 
2935
 
 
2936
  /* Check the parameter */
1678
2937
 
1679
2938
  ompcp = (OMProcControlPtr) data;
1680
2939
  if (ompcp == NULL || ompcp->input_itemtype == 0)
1681
2940
    return OM_MSG_RET_ERROR;
1682
2941
 
1683
 
  switch (ompcp->input_itemtype)
1684
 
  {
1685
 
    case OBJ_SEQFEAT:
1686
 
      sfp = (SeqFeatPtr) ompcp->input_data;
1687
 
      break;
1688
 
    default:
1689
 
      return OM_MSG_RET_ERROR;
1690
 
  }
1691
 
 
1692
 
  sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
1693
 
 
1694
 
  if (ExplodeGroup (sep, sfp))
1695
 
  {
1696
 
    ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
1697
 
    ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, ompcp->input_itemID,
1698
 
                   ompcp->input_itemtype);
1699
 
    return OM_MSG_RET_DONE;
1700
 
  }
 
2942
  /* Get the linked of list of selected items */
 
2943
 
 
2944
  ssp  = ObjMgrGetSelected();
 
2945
 
 
2946
  /* Go through the list and save pointers */
 
2947
  /* to the items themselves.              */
 
2948
 
 
2949
  isFirstEsp = TRUE;
 
2950
  isFirstSsp = TRUE;
 
2951
 
 
2952
  while (NULL != ssp) {
 
2953
 
 
2954
    if (!isFirstSsp) {
 
2955
      ompcp->input_entityID = ssp->entityID;
 
2956
      ompcp->input_itemID   = ssp->itemID;
 
2957
      ompcp->input_itemtype = ssp->itemtype;
 
2958
      
 
2959
      GatherDataForProc (ompcp, FALSE);
 
2960
    }
 
2961
 
 
2962
    switch (ssp->itemtype)
 
2963
      {
 
2964
      case OBJ_SEQFEAT:
 
2965
 
 
2966
        esp = (ExplodeStructPtr) MemNew (sizeof (ExplodeStruct));
 
2967
        esp->seqFeatPtr = (SeqFeatPtr) ompcp->input_data;
 
2968
        esp->topSep     = GetTopSeqEntryForEntityID (ssp->entityID);
 
2969
        
 
2970
        if (isFirstEsp) {
 
2971
          firstEsp = esp;
 
2972
          isFirstEsp = FALSE;
 
2973
        }
 
2974
        else
 
2975
          lastEsp->next = esp;
 
2976
 
 
2977
        lastEsp = esp;
 
2978
        lastEsp->next = NULL;
 
2979
        break;
 
2980
      default:
 
2981
        break;
 
2982
      }
 
2983
 
 
2984
    isFirstSsp = FALSE;
 
2985
    ssp = ssp->next;
 
2986
  }  
 
2987
 
 
2988
  /* Loop through all the selected items */
 
2989
  /* and explode each one.               */
 
2990
 
 
2991
  esp = firstEsp;
 
2992
  while (NULL != esp) {
 
2993
    if (ExplodeGroup (esp->topSep, esp->seqFeatPtr))
 
2994
      isDirty = TRUE;
 
2995
    esp = esp->next;
 
2996
  }
 
2997
 
 
2998
  /* If any actual exploding was done then */
 
2999
  /* force an update to be done.           */
 
3000
 
 
3001
  if (isDirty)
 
3002
    {
 
3003
      ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
 
3004
      ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID,
 
3005
                     ompcp->input_itemID, ompcp->input_itemtype);
 
3006
      return OM_MSG_RET_DONE;
 
3007
    }
1701
3008
  else
1702
3009
    return OM_MSG_RET_ERROR;
1703
3010
}
1704
3011
 
 
3012
extern void GroupExplodeToolBtn (ButtoN b)
 
3013
{
 
3014
  BaseFormPtr       bfp;
 
3015
  SelStructPtr      ssp;
 
3016
  Boolean           isDirty = FALSE;
 
3017
  SeqEntryPtr       sep;
 
3018
  SeqFeatPtr        sfp;
 
3019
  SeqMgrFeatContext context;
 
3020
 
 
3021
  bfp = (BaseFormPtr) GetObjectExtra (b);
 
3022
  if (bfp == NULL) return;
 
3023
 
 
3024
  ssp  = ObjMgrGetSelected();
 
3025
  while (NULL != ssp) {
 
3026
    if (ssp->itemtype == OBJ_SEQFEAT)
 
3027
    {
 
3028
      sep = GetTopSeqEntryForEntityID (ssp->entityID);
 
3029
    
 
3030
      sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &context);
 
3031
      if (sfp != NULL && ExplodeGroup (sep, sfp))
 
3032
      {
 
3033
        isDirty = TRUE;
 
3034
      }
 
3035
    }
 
3036
    ssp = ssp->next;
 
3037
  }
 
3038
 
 
3039
  /* If any actual exploding was done then */
 
3040
  /* force an update to be done.           */
 
3041
 
 
3042
  if (isDirty)
 
3043
  {
 
3044
    ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
3045
    ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID,
 
3046
                     bfp->input_itemID, bfp->input_itemtype);
 
3047
  }
 
3048
}
 
3049
 
1705
3050
static Boolean MakeExonsAndIntronsFromFeature (SeqEntryPtr sep, BioseqPtr bsp,
1706
 
                                               SeqLocPtr location, SeqFeatPtr putafterhere)
 
3051
                                               SeqLocPtr location,
 
3052
                                               SeqFeatPtr putafterhere,
 
3053
                                               Boolean MakeIntrons,
 
3054
                                               Int4 first_exon_number)
1707
3055
 
1708
3056
{
1709
3057
  SeqFeatPtr  curr;
1720
3068
  Int4        stop;
1721
3069
  Uint1       strand;
1722
3070
  Int4        tmp;
 
3071
  Boolean     partial5, partial3;
 
3072
  GBQualPtr   gbqual;
 
3073
  Int4        part_number;
 
3074
  Char        number_text [256];
 
3075
  ValNodePtr  merge_to_parts_list = NULL;
 
3076
  ValNodePtr  vnp;
1723
3077
 
1724
3078
  if (sep == NULL || bsp == NULL || location == NULL || putafterhere == NULL) return FALSE;
1725
3079
  putbeforehere = putafterhere->next;
1728
3082
  if (slp == NULL) return FALSE;
1729
3083
  first = TRUE;
1730
3084
  last = 0;
 
3085
  part_number = first_exon_number;
1731
3086
  while (slp != NULL) {
 
3087
    CheckSeqLocForPartial (slp, &partial5, &partial3);
1732
3088
    next = SeqLocFindNext (location, slp);
1733
3089
    if (slp->choice != SEQLOC_NULL) {
1734
3090
      start = GetOffsetInBioseq (slp, bsp, SEQLOC_START);
1744
3100
        start = stop;
1745
3101
        stop = tmp;
1746
3102
      }
1747
 
      if (! first) {
 
3103
      if (! first && MakeIntrons) {
1748
3104
        sfp = SeqFeatNew ();
1749
3105
        if (sfp != NULL) {
1750
3106
          sfp->data.choice = SEQFEAT_IMP;
1760
3116
            sfp->data.value.ptrvalue = (Pointer) ifp;
1761
3117
            ifp->key = StringSave ("intron");
1762
3118
          }
 
3119
          gbqual = GBQualNew ();
 
3120
          if (gbqual != NULL)
 
3121
          {
 
3122
            sprintf (number_text, "%d", part_number - 1);
 
3123
            gbqual->qual = StringSave ("number");
 
3124
            gbqual->val = StringSave (number_text);
 
3125
            gbqual->next = sfp->qual;
 
3126
            sfp->qual = gbqual;
 
3127
          }
 
3128
          if (bsp->repr == Seq_repr_seg)
 
3129
          {
 
3130
            ValNodeAddPointer (&merge_to_parts_list, 0, sfp);
 
3131
          }
1763
3132
          curr->next = sfp;
1764
3133
          curr = sfp;
1765
3134
        }
1780
3149
          sfp->data.value.ptrvalue = (Pointer) ifp;
1781
3150
          ifp->key = StringSave ("exon");
1782
3151
        }
 
3152
        SetSeqLocPartial (sfp->location, partial5, partial3);
 
3153
        gbqual = GBQualNew ();
 
3154
        if (gbqual != NULL)
 
3155
        {
 
3156
          sprintf (number_text, "%d", part_number);
 
3157
          gbqual->qual = StringSave ("number");
 
3158
          gbqual->val = StringSave (number_text);
 
3159
          gbqual->next = sfp->qual;
 
3160
          sfp->qual = gbqual;
 
3161
        }
 
3162
        part_number ++;
 
3163
        if (bsp->repr == Seq_repr_seg)
 
3164
        {
 
3165
          ValNodeAddPointer (&merge_to_parts_list, 0, sfp);
 
3166
        }
1783
3167
        curr->next = sfp;
1784
3168
        curr = sfp;
1785
3169
      }
1787
3171
    slp = next;
1788
3172
  }
1789
3173
  curr->next = putbeforehere;
 
3174
  
 
3175
  for (vnp = merge_to_parts_list; vnp != NULL; vnp = vnp->next)
 
3176
  {
 
3177
    sfp = vnp->data.ptrvalue;
 
3178
    MergeFeatureIntervalsToParts (sfp);
 
3179
  }
 
3180
  ValNodeFree (merge_to_parts_list);
 
3181
  
1790
3182
  return TRUE;
1791
3183
}
1792
3184
 
 
3185
typedef struct makeexondata {
 
3186
  FEATURE_FORM_BLOCK
 
3187
 
 
3188
  ButtoN      make_introns_button;
 
3189
  TexT        exon_number_field;
 
3190
  ButtoN      accept;
 
3191
 
 
3192
  SeqEntryPtr sep;
 
3193
  Boolean     make_introns;
 
3194
  Int4        first_exon_number;
 
3195
  Uint1       feature_type;
 
3196
} MakeExonData, PNTR MakeExonPtr;
 
3197
 
 
3198
static void MakeExonsFromFeatureIntervalsVisitFunc (SeqFeatPtr sfp, Pointer userdata)
 
3199
{
 
3200
  MakeExonPtr mep;
 
3201
  BioseqPtr   bsp;
 
3202
 
 
3203
  if (sfp == NULL || (mep = (MakeExonPtr) userdata) == NULL || sfp->idx.subtype != mep->feature_type)
 
3204
  {
 
3205
    return;
 
3206
  }
 
3207
 
 
3208
  mep = (MakeExonPtr) userdata;
 
3209
  bsp = BioseqFindFromSeqLoc (sfp->location);
 
3210
 
 
3211
  MakeExonsAndIntronsFromFeature (mep->sep, bsp, sfp->location, sfp,
 
3212
      mep->make_introns, mep->first_exon_number);
 
3213
  
 
3214
}
 
3215
 
 
3216
static void DoMakeExonsFromFeatureIntervals (ButtoN b)
 
3217
{
 
3218
  MakeExonPtr mep;
 
3219
  Char        exon_number_str [256];
 
3220
 
 
3221
  if (b == NULL || (mep = (MakeExonPtr) GetObjectExtra (b)) == NULL) return;
 
3222
 
 
3223
  Hide (mep->form);
 
3224
 
 
3225
  WatchCursor ();
 
3226
  Update ();
 
3227
 
 
3228
  mep->sep = GetTopSeqEntryForEntityID (mep->input_entityID);
 
3229
  mep->make_introns = GetStatus (mep->make_introns_button);
 
3230
  GetTitle (mep->exon_number_field,
 
3231
            exon_number_str,
 
3232
            sizeof (exon_number_str) - 1 );
 
3233
  mep->first_exon_number = atoi (exon_number_str);
 
3234
  VisitFeaturesInSep (mep->sep, mep, 
 
3235
                      MakeExonsFromFeatureIntervalsVisitFunc);
 
3236
  ObjMgrSetDirtyFlag (mep->input_entityID, TRUE);
 
3237
  ObjMgrSendMsg (OM_MSG_UPDATE, mep->input_entityID, 0, 0);
 
3238
  ArrowCursor ();
 
3239
  Update ();
 
3240
}
 
3241
 
 
3242
static void CheckExonNumberText (TexT number_field)
 
3243
{
 
3244
  MakeExonPtr mep;
 
3245
  Char        exon_number_str [256];
 
3246
  CharPtr     cp;
 
3247
 
 
3248
  if (number_field == NULL || (mep = (MakeExonPtr)GetObjectExtra (number_field)) == NULL) return;
 
3249
 
 
3250
  GetTitle (mep->exon_number_field,
 
3251
            exon_number_str,
 
3252
            sizeof (exon_number_str) - 1 );
 
3253
  if (exon_number_str [0] == 0) 
 
3254
  {
 
3255
    Disable (mep->accept);
 
3256
    return;
 
3257
  }
 
3258
 
 
3259
  for (cp = exon_number_str; cp != NULL && *cp != 0; cp++)
 
3260
  {
 
3261
    if (*cp != '0' && *cp != '1' && *cp != '2' && *cp != '3'
 
3262
      && *cp != '4' && *cp != '5' && *cp != '6' && *cp != '7'
 
3263
      && *cp != '8' && *cp != '9')
 
3264
    {
 
3265
      Disable (mep->accept);
 
3266
      return;
 
3267
    }
 
3268
  }
 
3269
  Enable (mep->accept);
 
3270
  return;
 
3271
}
 
3272
 
 
3273
static void CommonMakeExonsFromFeatureIntervals (
 
3274
  IteM i,
 
3275
  Boolean make_introns,
 
3276
  Uint1 feature_type
 
3277
)
 
3278
{
 
3279
  BaseFormPtr  bfp;
 
3280
  MakeExonPtr  mep;
 
3281
  WindoW       w;
 
3282
  GrouP        h, p, c;
 
3283
 
 
3284
#ifdef WIN_MAC
 
3285
  bfp = currentFormDataPtr;
 
3286
#else
 
3287
  bfp = GetObjectExtra (i);
 
3288
#endif
 
3289
 
 
3290
  if (bfp == NULL) return;
 
3291
 
 
3292
  mep = MemNew (sizeof (MakeExonData));
 
3293
  if (mep == NULL) return;
 
3294
  mep->input_entityID = bfp->input_entityID;
 
3295
  mep->feature_type = feature_type;
 
3296
 
 
3297
  if (feature_type == FEATDEF_CDS)
 
3298
  {
 
3299
    w = FixedWindow (-50, -33, -10, -10, "Make Exons from CDS", NULL);
 
3300
  }
 
3301
  else if (feature_type == FEATDEF_mRNA)
 
3302
  {
 
3303
    w = FixedWindow (-50, -33, -10, -10, "Make Exons from mRNA", NULL);
 
3304
  }
 
3305
  else
 
3306
  {
 
3307
    w = FixedWindow (-50, -33, -10, -10, "Make Exons from Feature", NULL);
 
3308
  }
 
3309
 
 
3310
  SetObjectExtra (w, mep, StdCleanupFormProc);
 
3311
  mep->form = (ForM) w;
 
3312
 
 
3313
  h = HiddenGroup (w, -1, 0, NULL);
 
3314
  SetGroupSpacing (h, 10, 10);
 
3315
 
 
3316
  p = HiddenGroup (h, 2, 0, NULL);
 
3317
  StaticPrompt (p, "First Exon Number", 0, 0, programFont, 'c');
 
3318
  mep->exon_number_field = DialogText (p, "1", 3, CheckExonNumberText);
 
3319
  SetObjectExtra (mep->exon_number_field, mep, NULL);
 
3320
  mep->make_introns_button = CheckBox (p, "Make Introns", NULL);
 
3321
 
 
3322
  c = HiddenGroup (h, 4, 0, NULL);
 
3323
  mep->accept = DefaultButton (c, "Accept", DoMakeExonsFromFeatureIntervals);
 
3324
  SetObjectExtra (mep->accept, mep, NULL);
 
3325
  PushButton (c, "Cancel", StdCancelButtonProc);
 
3326
  AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) c, NULL);
 
3327
  RealizeWindow (w);
 
3328
  Show (w);
 
3329
  Update ();
 
3330
}
 
3331
 
 
3332
extern void MakeExonsFromCDSIntervals (IteM i)
 
3333
{
 
3334
  CommonMakeExonsFromFeatureIntervals (i, FALSE, FEATDEF_CDS);
 
3335
}
 
3336
 
 
3337
extern void MakeExonsFromMRNAIntervals (IteM i)
 
3338
{
 
3339
  CommonMakeExonsFromFeatureIntervals (i, TRUE, FEATDEF_mRNA);
 
3340
}
 
3341
 
1793
3342
static Int2 LIBCALLBACK MakeExonIntron (Pointer data)
1794
3343
 
1795
3344
{
1823
3372
  nbsp = (BioseqPtr) nsep->data.ptrvalue;
1824
3373
  if (nbsp == NULL) return OM_MSG_RET_ERROR;
1825
3374
 
1826
 
  if (MakeExonsAndIntronsFromFeature (sep, nbsp, sfp->location, sfp))
 
3375
  if (MakeExonsAndIntronsFromFeature (sep, nbsp, sfp->location, sfp, TRUE, 1))
1827
3376
  {
1828
3377
    ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
1829
3378
    ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, ompcp->input_itemID,
2306
3855
        Update();
2307
3856
}
2308
3857
 
2309
 
static void myrelease(IcoN ic, PoinT pt)
 
3858
static void LaunchOrfFindCDSEditor (OrfViewFormPtr ovp)
 
3859
{
 
3860
        OMProcControl  ompc;
 
3861
        ObjMgrProcPtr  ompp;
 
3862
        ObjMgrPtr      omp;
 
3863
    Int2           retval;
 
3864
        
 
3865
    if (ovp == NULL)
 
3866
    {
 
3867
        return;
 
3868
    }
 
3869
    omp = ObjMgrGet ();
 
3870
    if (omp == NULL) 
 
3871
    {
 
3872
        return;
 
3873
    }
 
3874
    ompp = NULL;
 
3875
    while ((ompp = ObjMgrProcFindNext (omp, OMPROC_EDIT,
 
3876
                                          OBJ_SEQFEAT, 0, ompp)) != NULL)
 
3877
                            
 
3878
        { 
 
3879
        if (ompp->subinputtype == FEATDEF_CDS) 
 
3880
        {
 
3881
                break;
 
3882
        }
 
3883
        }
 
3884
        if (ompp == NULL) return;
 
3885
        MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
 
3886
    ompc.input_entityID = ovp->bsp_entityID;
 
3887
    ompc.input_itemID = ovp->bsp_itemID;
 
3888
    ompc.input_itemtype = OBJ_BIOSEQ;
 
3889
    GatherDataForProc (&ompc, FALSE);
 
3890
    ompc.proc = ompp;
 
3891
    retval = (*(ompp->func)) (&ompc);
 
3892
    if (retval == OM_MSG_RET_ERROR) 
 
3893
    {
 
3894
        ErrShow ();
 
3895
    }
 
3896
}
 
3897
 
 
3898
static void myprocessmousepos (IcoN ic, PoinT pt, Boolean edit_on_dblclick)
2310
3899
{
2311
3900
        RecT r;
2312
3901
        Int2 ir;
2322
3911
        Int2 startsAt;
2323
3912
        DoC doc;
2324
3913
        
 
3914
        if (edit_on_dblclick && ! Nlm_dblClick)
 
3915
        {
 
3916
          return;
 
3917
        }
 
3918
        
2325
3919
        ovp = GetObjectExtra((IcoN) ic);
2326
3920
        ObjectRect(ic, &r);
2327
3921
        if (!PtInRect(pt, &(ovp->mi))) {
2344
3938
                pos = (pt.x - r.left)/ovp->dx - ir;
2345
3939
                for (vnp=ovp->orfs, item=1; vnp; vnp=vnp->next, item++) {
2346
3940
                        slp = vnp->data.ptrvalue;
 
3941
                        if (slp == NULL) continue;
2347
3942
                        sip = slp->data.ptrvalue;
 
3943
                        if (sip == NULL) continue;
2348
3944
                        if (vnp->choice != ir || sip->strand != Seq_strand_plus) {
2349
3945
                                continue;
2350
3946
                        }
2356
3952
                        Beep();
2357
3953
                        return;
2358
3954
                }
 
3955
                if (slp == NULL) return;
 
3956
                if (sip == NULL) return;
2359
3957
                ovp->frame = ir;
2360
3958
                ovp->strand = sip->strand;
2361
3959
                ovp->from = sip->from;
2378
3976
                        if (ovp->select_orf != NULL) {
2379
3977
                                ObjMgrSelect (ovp->bsp_entityID, ovp->bsp_itemID, OBJ_BIOSEQ, 
2380
3978
                                        OM_REGION_SEQLOC, ovp->select_orf);
 
3979
                                if (edit_on_dblclick)
 
3980
                        {
 
3981
                            /* launch CDS Editor */
 
3982
                    LaunchOrfFindCDSEditor (ovp);
 
3983
                        }
2381
3984
                        }
2382
3985
                }
2383
3986
                Update();
2395
3998
                pos = (pt.x - r.left)/ovp->dx - ir;
2396
3999
                for (vnp=ovp->orfs, item=1; vnp; vnp=vnp->next, item++) {
2397
4000
                        slp = vnp->data.ptrvalue;
 
4001
                        if (slp == NULL) continue;
2398
4002
                        sip = slp->data.ptrvalue;
 
4003
                        if (sip == NULL) continue;
2399
4004
                        if (vnp->choice != ir  || sip->strand != Seq_strand_minus) {
2400
4005
                                continue;
2401
4006
                        }
2407
4012
                        Beep();
2408
4013
                        return;
2409
4014
                }
 
4015
                if (slp == NULL) return;
 
4016
                if (sip == NULL) return;
2410
4017
                ovp->frame = ir;
2411
4018
                ovp->strand = sip->strand;
2412
4019
                ovp->from = sip->from;
2429
4036
                if (ovp->select_orf != NULL) {
2430
4037
                        ObjMgrSelect (ovp->bsp_entityID, ovp->bsp_itemID, OBJ_BIOSEQ, 
2431
4038
                                OM_REGION_SEQLOC, ovp->select_orf);
 
4039
                        if (edit_on_dblclick)
 
4040
                    {
 
4041
                        /* launch CDS Editor */
 
4042
                LaunchOrfFindCDSEditor (ovp);
 
4043
                    }
2432
4044
                }
2433
4045
        }
 
4046
        
2434
4047
        Update();
2435
4048
        return;
2436
4049
}
2437
4050
 
 
4051
static void myrelease(IcoN ic, PoinT pt)
 
4052
{
 
4053
    myprocessmousepos (ic, pt, FALSE);
 
4054
}
 
4055
 
 
4056
static void myclick(IcoN ic, PoinT pt)
 
4057
{
 
4058
    myprocessmousepos (ic, pt, TRUE);
 
4059
}
 
4060
 
 
4061
 
2438
4062
/* show all ORF from List without starts and stops */
2439
4063
static void ORFProc(ButtoN b)
2440
4064
{
2652
4276
        
2653
4277
    g = HiddenGroup (w, 2, 0, NULL);
2654
4278
        ic = IconButton(g, 500, 240, 
2655
 
                DrawIcon, NULL, NULL, NULL, NULL, myrelease);
 
4279
                DrawIcon, NULL, myclick, NULL, NULL, myrelease);
2656
4280
        if (ovp->select_orf != NULL) {
2657
4281
        }
2658
4282
        ovp->icon = ic;
2750
4374
 
2751
4375
typedef struct mergedata {
2752
4376
  SeqLocPtr     slp;
 
4377
  Boolean       fuse;
2753
4378
} MergeData, PNTR MergeDataPtr;
2754
4379
 
2755
4380
static Boolean AddToSeqLoc (GatherContextPtr gcp)
2767
4392
  if (sfp == NULL || sfp->location == NULL) return TRUE;
2768
4393
  bsp = GetBioseqGivenSeqLoc (sfp->location, gcp->entityID);
2769
4394
  if (bsp == NULL) return TRUE;
2770
 
  slp = SeqLocMerge (bsp, sfp->location, mdp->slp, FALSE, TRUE, FALSE);
 
4395
  slp = SeqLocMerge (bsp, sfp->location, mdp->slp, FALSE, mdp->fuse, FALSE);
2771
4396
  mdp->slp = SeqLocFree (mdp->slp);
2772
4397
  mdp->slp = slp;
2773
4398
  return TRUE;
2774
4399
}
2775
4400
 
2776
 
static SeqLocPtr MergeSelectedFeatureIntervals (void)
 
4401
static SeqLocPtr MergeSelectedFeatureIntervals (Boolean fuse)
2777
4402
 
2778
4403
{
2779
4404
  MergeData     md;
2780
4405
  SelStructPtr  sel;
2781
4406
 
2782
4407
  md.slp = NULL;
 
4408
  md.fuse = fuse;
2783
4409
  for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
2784
4410
    GatherItem (sel->entityID, sel->itemID, sel->itemtype,
2785
4411
                (Pointer) &md, AddToSeqLoc);
2795
4421
 
2796
4422
  ompcp = (OMProcControlPtr) data;
2797
4423
  if (ompcp == NULL) return OM_MSG_RET_ERROR;
2798
 
  slp = MergeSelectedFeatureIntervals ();
 
4424
  slp = MergeSelectedFeatureIntervals (FALSE);
 
4425
  if (slp == NULL) return OM_MSG_RET_ERROR;
 
4426
  ObjMgrRegister (OBJ_SEQLOC, (Pointer) slp);
 
4427
  return OM_MSG_RET_DONE;
 
4428
}
 
4429
 
 
4430
static Int2 LIBCALLBACK IntervalCombineAndFuseFunc (Pointer data)
 
4431
 
 
4432
{
 
4433
  OMProcControlPtr  ompcp;
 
4434
  SeqLocPtr         slp;
 
4435
 
 
4436
  ompcp = (OMProcControlPtr) data;
 
4437
  if (ompcp == NULL) return OM_MSG_RET_ERROR;
 
4438
  slp = MergeSelectedFeatureIntervals (TRUE);
2799
4439
  if (slp == NULL) return OM_MSG_RET_ERROR;
2800
4440
  ObjMgrRegister (OBJ_SEQLOC, (Pointer) slp);
2801
4441
  return OM_MSG_RET_DONE;
3033
4673
  MsgAnswer         ans;
3034
4674
  GatherScope       gs;
3035
4675
  OMProcControlPtr  ompcp;
 
4676
  SeqEntryPtr       sep;
3036
4677
 
3037
4678
  ompcp = (OMProcControlPtr) data;
3038
4679
  if (ompcp == NULL) return OM_MSG_RET_ERROR;
3039
4680
  ans = Message (MSG_OKC, "Are you sure you want to convert alignment GIs to accessions?");
3040
4681
  if (ans == ANS_CANCEL) return OM_MSG_RET_DONE;
 
4682
  sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
 
4683
  LookupFarSeqIDs (sep, FALSE, FALSE, FALSE, TRUE, FALSE);
3041
4684
  MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
3042
4685
  gs.seglevels = 1;
3043
4686
  gs.get_feats_location = FALSE;
3051
4694
  return OM_MSG_RET_DONE;
3052
4695
}
3053
4696
 
 
4697
static void ConvertAccnToGi (SeqIdPtr sip)
 
4698
 
 
4699
{
 
4700
  Int4      gi;
 
4701
  SeqIdPtr  newsip;
 
4702
  Char      str [42];
 
4703
 
 
4704
  if (sip == NULL) return;
 
4705
  if (sip->choice == SEQID_GI) return;
 
4706
  gi = GetGIForSeqId (sip);
 
4707
  if (gi < 1) return;
 
4708
  sprintf (str, "gi|%ld", (long) gi);
 
4709
  newsip = SeqIdParse (str);
 
4710
  if (newsip == NULL) return;
 
4711
  sip->choice = newsip->choice;
 
4712
  sip->data.ptrvalue = newsip->data.ptrvalue;
 
4713
  newsip->choice = SEQID_NOT_SET;
 
4714
  newsip->data.ptrvalue = NULL;
 
4715
  SeqIdFree (newsip);
 
4716
}
 
4717
 
 
4718
static Boolean AccnToGiAlignCallback (GatherContextPtr gcp)
 
4719
 
 
4720
{
 
4721
  SeqAlignPtr   align;
 
4722
  DenseDiagPtr  ddp;
 
4723
  DenseSegPtr   dsp;
 
4724
  SeqIdPtr      sip;
 
4725
  StdSegPtr     ssp;
 
4726
  SeqLocPtr     tloc;
 
4727
 
 
4728
  if (gcp == NULL) return TRUE;
 
4729
  switch (gcp->thistype) {
 
4730
    case OBJ_SEQALIGN :
 
4731
    case OBJ_SEQHIST_ALIGN :
 
4732
      align = (SeqAlignPtr) gcp->thisitem;
 
4733
      sip = NULL;
 
4734
      if (align->segtype == 1) {
 
4735
        ddp = (DenseDiagPtr) align->segs;
 
4736
        if (ddp != NULL) {
 
4737
          for (sip = ddp->id; sip != NULL; sip = sip->next) {
 
4738
            ConvertAccnToGi (sip);
 
4739
          }
 
4740
        }
 
4741
      } else if (align->segtype == 2) {
 
4742
        dsp = (DenseSegPtr) align->segs;
 
4743
        if (dsp != NULL) {
 
4744
          for (sip = dsp->ids; sip != NULL; sip = sip->next) {
 
4745
            ConvertAccnToGi (sip);
 
4746
          }
 
4747
        }
 
4748
      } else if (align->segtype == 3) {
 
4749
        ssp = (StdSegPtr) align->segs;
 
4750
        if (ssp != NULL) {
 
4751
          for (tloc = ssp->loc; tloc != NULL; tloc = tloc->next) {
 
4752
            sip = SeqLocId (tloc);
 
4753
            ConvertAccnToGi (sip);
 
4754
          }
 
4755
        }
 
4756
      }
 
4757
      break;
 
4758
    default :
 
4759
      break;
 
4760
  }
 
4761
  return TRUE;
 
4762
}
 
4763
 
 
4764
static Int2 LIBCALLBACK AlignAccnToGiProc (Pointer data)
 
4765
 
 
4766
{
 
4767
  MsgAnswer         ans;
 
4768
  GatherScope       gs;
 
4769
  OMProcControlPtr  ompcp;
 
4770
  SeqEntryPtr       sep;
 
4771
 
 
4772
  ompcp = (OMProcControlPtr) data;
 
4773
  if (ompcp == NULL) return OM_MSG_RET_ERROR;
 
4774
  ans = Message (MSG_OKC, "Are you sure you want to convert alignment accessions to GIs?");
 
4775
  if (ans == ANS_CANCEL) return OM_MSG_RET_DONE;
 
4776
  sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
 
4777
  LookupFarSeqIDs (sep, FALSE, FALSE, FALSE, TRUE, FALSE);
 
4778
  MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
 
4779
  gs.seglevels = 1;
 
4780
  gs.get_feats_location = FALSE;
 
4781
  MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
 
4782
  gs.ignore[OBJ_BIOSEQ] = FALSE;
 
4783
  gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
 
4784
  gs.ignore[OBJ_SEQALIGN] = FALSE;
 
4785
  gs.ignore[OBJ_SEQHIST_ALIGN] = FALSE;
 
4786
  gs.ignore[OBJ_SEQANNOT] = FALSE;
 
4787
  GatherEntity (ompcp->input_entityID, NULL, AccnToGiAlignCallback, &gs);
 
4788
  return OM_MSG_RET_DONE;
 
4789
}
 
4790
 
 
4791
static Boolean IsSipMrna (SeqIdPtr sip)
 
4792
 
 
4793
{
 
4794
  Char                    buf [45];
 
4795
  BioseqPtr               bsp;
 
4796
  Int4                    count;
 
4797
  Entrez2BooleanReplyPtr  e2br;
 
4798
  Entrez2RequestPtr       e2rq;
 
4799
  Entrez2ReplyPtr         e2ry;
 
4800
  Int4                    gi;
 
4801
  Char                    query [128];
 
4802
  E2ReplyPtr              reply;
 
4803
 
 
4804
  if (sip == NULL) return FALSE;
 
4805
  bsp = BioseqFind (sip);
 
4806
  if (bsp != NULL) return FALSE;
 
4807
  if (sip->choice == SEQID_GI) {
 
4808
    gi = sip->data.intvalue;
 
4809
    sip = GetSeqIdForGI (gi);
 
4810
  }
 
4811
  if (sip == NULL) return FALSE;
 
4812
  SeqIdWrite (sip, buf, PRINTID_TEXTID_ACCESSION, 41);
 
4813
  sprintf (query, "biomol_mrna [PROP] AND %s [ACCN]", buf);
 
4814
  e2rq = EntrezCreateBooleanRequest (FALSE, FALSE, "nucleotide", query, 0, 0, NULL, 0, 0);
 
4815
  e2ry = EntrezSynchronousQuery (e2rq);
 
4816
  e2rq = Entrez2RequestFree (e2rq);
 
4817
  if (e2ry == NULL) return FALSE;
 
4818
  reply = e2ry->reply;
 
4819
  if (reply == NULL || reply->choice != E2Reply_eval_boolean) return FALSE;
 
4820
  e2br = EntrezExtractBooleanReply (e2ry);
 
4821
  if (e2br == NULL) return FALSE;
 
4822
  count = e2br->count;
 
4823
  Entrez2BooleanReplyFree (e2br);
 
4824
  if (count > 0) return TRUE;
 
4825
  return FALSE;
 
4826
}
 
4827
 
 
4828
static Boolean IsMrnaAlignment (SeqAlignPtr align)
 
4829
 
 
4830
{
 
4831
  DenseDiagPtr  ddp;
 
4832
  DenseSegPtr   dsp;
 
4833
  SeqIdPtr      sip;
 
4834
  StdSegPtr     ssp;
 
4835
  SeqLocPtr     tloc;
 
4836
 
 
4837
  if (align == NULL) return FALSE;
 
4838
  sip = NULL;
 
4839
  if (align->segtype == 1) {
 
4840
    ddp = (DenseDiagPtr) align->segs;
 
4841
    if (ddp != NULL) {
 
4842
      for (sip = ddp->id; sip != NULL; sip = sip->next) {
 
4843
        if (IsSipMrna (sip)) return TRUE;
 
4844
      }
 
4845
    }
 
4846
  } else if (align->segtype == 2) {
 
4847
    dsp = (DenseSegPtr) align->segs;
 
4848
    if (dsp != NULL) {
 
4849
      for (sip = dsp->ids; sip != NULL; sip = sip->next) {
 
4850
        if (IsSipMrna (sip)) return TRUE;
 
4851
      }
 
4852
    }
 
4853
  } else if (align->segtype == 3) {
 
4854
    ssp = (StdSegPtr) align->segs;
 
4855
    if (ssp != NULL) {
 
4856
      for (tloc = ssp->loc; tloc != NULL; tloc = tloc->next) {
 
4857
        sip = SeqLocId (tloc);
 
4858
        if (IsSipMrna (sip)) return TRUE;
 
4859
      }
 
4860
    }
 
4861
  }
 
4862
  return FALSE;
 
4863
}
 
4864
 
 
4865
static SeqAnnotPtr ExtractBlastMrna (SeqAlignPtr sap, Pointer PNTR prevlink)
 
4866
 
 
4867
{
 
4868
  AnnotDescrPtr  adp;
 
4869
  SeqAnnotPtr    annot = NULL;
 
4870
  SeqAlignPtr    next;
 
4871
  ObjectIdPtr    oip;
 
4872
  UserFieldPtr   ufp;
 
4873
  UserObjectPtr  uop;
 
4874
 
 
4875
  while (sap != NULL) {
 
4876
    next = sap->next;
 
4877
 
 
4878
    if (IsMrnaAlignment (sap)) {
 
4879
      *prevlink = sap->next;
 
4880
      sap->next = NULL;
 
4881
 
 
4882
      if (annot == NULL) {
 
4883
        annot = SeqAnnotNew ();
 
4884
        if (annot != NULL) {
 
4885
          annot->type = 2;
 
4886
          adp = ValNodeNew (NULL);
 
4887
          adp->choice = Annot_descr_user;
 
4888
          annot->desc = adp;
 
4889
          uop = UserObjectNew ();
 
4890
          adp->data.ptrvalue = uop;
 
4891
          oip = ObjectIdNew ();
 
4892
          oip->str = StringSave ("Blast Type");
 
4893
          ufp = UserFieldNew ();
 
4894
          uop->type = oip;
 
4895
          uop->data = ufp;
 
4896
          oip = ObjectIdNew ();
 
4897
          oip->str = StringSave ("BLASTN - mrna");
 
4898
          ufp->label = oip;
 
4899
          ufp->choice = 2;
 
4900
          ufp->data.intvalue = 1;
 
4901
        }
 
4902
      }
 
4903
      if (annot != NULL) {
 
4904
        sap->next = annot->data;
 
4905
        annot->data = sap;
 
4906
      }
 
4907
 
 
4908
    } else {
 
4909
      sap->idx.prevlink = prevlink;
 
4910
      prevlink = (Pointer PNTR) &(sap->next);
 
4911
    }
 
4912
 
 
4913
    sap = next;
 
4914
  }
 
4915
 
 
4916
  return annot;
 
4917
}
 
4918
 
 
4919
static void FindBlastNR (SeqAnnotPtr sap, Pointer userdata)
 
4920
 
 
4921
{
 
4922
  AnnotDescrPtr  adp;
 
4923
  SeqAnnotPtr    annot;
 
4924
  ObjectIdPtr    oip;
 
4925
  UserFieldPtr   ufp;
 
4926
  UserObjectPtr  uop;
 
4927
 
 
4928
  if (sap == NULL || sap->type != 2) return;
 
4929
  for (adp = sap->desc; adp != NULL; adp = adp->next) {
 
4930
    if (adp->choice != Annot_descr_user) continue;
 
4931
    for (uop = adp->data.ptrvalue; uop != NULL; uop = uop->next) {
 
4932
      oip = uop->type;
 
4933
      if (oip == NULL) continue;
 
4934
      if (StringCmp (oip->str, "Blast Type") == 0) {
 
4935
        ufp = uop->data;
 
4936
        if (ufp == NULL) continue;
 
4937
        oip = ufp->label;
 
4938
        if (oip == NULL) continue;
 
4939
        if (StringCmp (oip->str, "BLASTN - nr") == 0) {
 
4940
          annot = ExtractBlastMrna ((SeqAlignPtr) sap->data, (Pointer PNTR) &(sap->data));
 
4941
          if (annot != NULL) {
 
4942
            annot->next = sap->next;
 
4943
            sap->next = annot;
 
4944
          }
 
4945
        }
 
4946
      }
 
4947
    }
 
4948
  }
 
4949
}
 
4950
 
 
4951
static Int2 LIBCALLBACK SeparateMrnaFromNrProc (Pointer data)
 
4952
 
 
4953
{
 
4954
  OMProcControlPtr  ompcp;
 
4955
  SeqEntryPtr       sep;
 
4956
 
 
4957
  ompcp = (OMProcControlPtr) data;
 
4958
  if (ompcp == NULL) return OM_MSG_RET_ERROR;
 
4959
  sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
 
4960
  LookupFarSeqIDs (sep, FALSE, FALSE, FALSE, TRUE, FALSE);
 
4961
  VisitAnnotsInSep (sep, NULL, FindBlastNR);
 
4962
  DeleteMarkedObjects (ompcp->input_entityID, 0, NULL);
 
4963
  ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
 
4964
  ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
 
4965
  return OM_MSG_RET_DONE;
 
4966
}
 
4967
 
3054
4968
static void CacheByAccn (SeqIdPtr sip, CharPtr directory)
3055
4969
 
3056
4970
{
3271
5185
  return pfl.prp;
3272
5186
}
3273
5187
 
3274
 
extern void MRnaFromCdsProc (Uint2 entityID)
3275
 
 
3276
 
{
3277
 
  BioseqPtr     bsp;
3278
 
  SeqFeatPtr    cds;
3279
 
  ValNodePtr    head;
 
5188
/* if gene location matches mRNA exactly, make it partial on both ends */
 
5189
static void MakeMRNAGenesPartial (SeqFeatPtr sfp, Pointer userdata)
 
5190
{
 
5191
  SeqFeatPtr mrna;
 
5192
 
 
5193
  if (sfp == NULL || userdata == NULL) return;
 
5194
  if (sfp->data.choice != SEQFEAT_GENE) return;
 
5195
 
 
5196
  mrna = (SeqFeatPtr) userdata;
 
5197
 
 
5198
  if (SeqLocAinB (mrna->location, sfp->location) != 0) return;
 
5199
 
 
5200
  SetSeqLocPartial (sfp->location, TRUE, TRUE);
 
5201
}
 
5202
 
 
5203
static void MRnaFromCdsCallback (SeqFeatPtr sfp, Pointer userdata)
 
5204
{
 
5205
  Boolean       process_this_one = FALSE;
 
5206
  SelStructPtr  sel;
 
5207
  RnaRefPtr     rrp;
3280
5208
  Char          mRnaName [128];
 
5209
  ProtRefPtr    prp;
 
5210
  Uint2Ptr      entityIDptr;
 
5211
  Uint2         entityID;
3281
5212
  ValNodePtr    name;
3282
 
  /*
3283
 
  Boolean       noLeft;
3284
 
  Boolean       noRight;
3285
 
  */
3286
 
  ProtRefPtr    prp;
3287
5213
  SeqFeatPtr    rna;
3288
 
  RnaRefPtr     rrp;
3289
 
  SelStructPtr  sel;
3290
 
  SeqEntryPtr   sep;
3291
 
  ValNodePtr    vnp;
 
5214
  BioseqPtr     bsp;
 
5215
  SeqEntryPtr   sep;
 
5216
  
 
5217
  if (sfp == NULL || sfp->idx.subtype != FEATDEF_CDS || userdata == NULL) return;
 
5218
  entityIDptr = (Uint2Ptr) userdata;
 
5219
  entityID = *entityIDptr;
 
5220
  
 
5221
  sel = ObjMgrGetSelected ();
 
5222
  if (sel == NULL)
 
5223
  {
 
5224
        process_this_one = TRUE;
 
5225
  }
 
5226
  else
 
5227
  {
 
5228
    while (sel != NULL && sel->itemID != sfp->idx.itemID)
 
5229
    {
 
5230
      sel = sel->next;
 
5231
    }
 
5232
    if (sel != NULL)
 
5233
    {
 
5234
      process_this_one = TRUE;
 
5235
    }
 
5236
  }
 
5237
  if (process_this_one)
 
5238
  {
 
5239
    rrp = RnaRefNew ();
 
5240
    if (rrp != NULL) {
 
5241
      rrp->type = 2;
 
5242
      mRnaName [0] = '\0';
 
5243
      prp = FindBestProtRef (entityID, sfp);
 
5244
      if (prp != NULL) {
 
5245
        name = prp->name;
 
5246
        if (name != NULL) {
 
5247
          StringNCpy_0 (mRnaName, (CharPtr) name->data.ptrvalue, sizeof (mRnaName));
 
5248
        }
 
5249
        if (StringHasNoText (mRnaName)) {
 
5250
          StringNCpy_0 (mRnaName, prp->desc, sizeof (mRnaName));
 
5251
        }
 
5252
      }
 
5253
      if (! StringHasNoText (mRnaName)) {
 
5254
        rrp->ext.choice = 1;
 
5255
        rrp->ext.value.ptrvalue = StringSave (mRnaName);
 
5256
      }
 
5257
      rna = SeqFeatNew ();
 
5258
      if (rna != NULL) {
 
5259
        rna->data.choice = SEQFEAT_RNA;
 
5260
        rna->data.value.ptrvalue = (Pointer) rrp;
 
5261
        rna->location = AsnIoMemCopy ((Pointer) sfp->location,
 
5262
                                      (AsnReadFunc) SeqLocAsnRead,
 
5263
                                      (AsnWriteFunc) SeqLocAsnWrite);
 
5264
        /* CheckSeqLocForPartial (rna->location, &noLeft, &noRight); */
 
5265
        SetSeqLocPartial (rna->location, TRUE, TRUE); /* now always set */
 
5266
        /* rna->partial = (rna->partial || noLeft || noRight); */
 
5267
        rna->partial = TRUE;
 
5268
        bsp = GetBioseqGivenSeqLoc (rna->location, entityID);
 
5269
        if (bsp != NULL) {
 
5270
          sep = SeqMgrGetSeqEntryForData (bsp);
 
5271
          if (sep != NULL) {
 
5272
            CreateNewFeature (sep, NULL, SEQFEAT_RNA, rna);
 
5273
          } else {
 
5274
            rna->next = sfp->next;
 
5275
            sfp->next = rna;
 
5276
          }
 
5277
          VisitFeaturesOnBsp (bsp, (Pointer) rna, MakeMRNAGenesPartial);
 
5278
        } else {
 
5279
          rna->next = sfp->next;
 
5280
          sfp->next = rna;
 
5281
        }
 
5282
      }
 
5283
    }
 
5284
  }
 
5285
}
 
5286
 
 
5287
extern void MRnaFromCdsProc (Uint2 entityID)
 
5288
 
 
5289
{
 
5290
  SeqEntryPtr   sep;
3292
5291
 
3293
5292
  if (entityID == 0) return;
3294
 
  head = NULL;
3295
 
  for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
3296
 
    GatherItem (sel->entityID, sel->itemID, sel->itemtype,
3297
 
                (Pointer) &head, AddFeatToVnp);
3298
 
  }
3299
 
  for (vnp = head; vnp != NULL; vnp = vnp->next) {
3300
 
    cds = (SeqFeatPtr) vnp->data.ptrvalue;
3301
 
    if (cds != NULL) {
3302
 
      rrp = RnaRefNew ();
3303
 
      if (rrp != NULL) {
3304
 
        rrp->type = 2;
3305
 
        mRnaName [0] = '\0';
3306
 
        prp = FindBestProtRef (entityID, cds);
3307
 
        if (prp != NULL) {
3308
 
          name = prp->name;
3309
 
          if (name != NULL) {
3310
 
            StringNCpy_0 (mRnaName, (CharPtr) name->data.ptrvalue, sizeof (mRnaName));
3311
 
          }
3312
 
          if (StringHasNoText (mRnaName)) {
3313
 
            StringNCpy_0 (mRnaName, prp->desc, sizeof (mRnaName));
3314
 
          }
3315
 
        }
3316
 
        if (! StringHasNoText (mRnaName)) {
3317
 
          rrp->ext.choice = 1;
3318
 
          rrp->ext.value.ptrvalue = StringSave (mRnaName);
3319
 
        }
3320
 
        rna = SeqFeatNew ();
3321
 
        if (rna != NULL) {
3322
 
          rna->data.choice = SEQFEAT_RNA;
3323
 
          rna->data.value.ptrvalue = (Pointer) rrp;
3324
 
          rna->location = AsnIoMemCopy ((Pointer) cds->location,
3325
 
                                        (AsnReadFunc) SeqLocAsnRead,
3326
 
                                        (AsnWriteFunc) SeqLocAsnWrite);
3327
 
          /* CheckSeqLocForPartial (rna->location, &noLeft, &noRight); */
3328
 
          SetSeqLocPartial (rna->location, TRUE, TRUE); /* now always set */
3329
 
          /* rna->partial = (rna->partial || noLeft || noRight); */
3330
 
          rna->partial = TRUE;
3331
 
          bsp = GetBioseqGivenSeqLoc (rna->location, entityID);
3332
 
          if (bsp != NULL) {
3333
 
            sep = SeqMgrGetSeqEntryForData (bsp);
3334
 
            if (sep != NULL) {
3335
 
              CreateNewFeature (sep, NULL, SEQFEAT_RNA, rna);
3336
 
            } else {
3337
 
              rna->next = cds->next;
3338
 
              cds->next = rna;
3339
 
            }
3340
 
          } else {
3341
 
            rna->next = cds->next;
3342
 
            cds->next = rna;
3343
 
          }
3344
 
        }
3345
 
      }
3346
 
    }
3347
 
  }
3348
 
  ValNodeFree (head);
 
5293
 
 
5294
  sep = GetTopSeqEntryForEntityID (entityID);
 
5295
  VisitFeaturesInSep (sep, (Pointer) &entityID, MRnaFromCdsCallback);
3349
5296
  ObjMgrSetDirtyFlag (entityID, TRUE);
3350
5297
  ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
3351
5298
}
3509
5456
{
3510
5457
  BioseqPtr     bsp;
3511
5458
  BioseqSetPtr  bssp;
 
5459
  CodeBreakPtr  cbp;
 
5460
  CdRegionPtr   crp;
 
5461
  RnaRefPtr     rrp;
3512
5462
  SeqAnnotPtr   sap;
3513
5463
  SeqFeatPtr    sfp;
3514
5464
  SeqIdPtr      sip;
3515
5465
  SeqLocPtr     slp;
 
5466
  Boolean       split;
 
5467
  tRNAPtr       trp;
3516
5468
 
3517
5469
  if (mydata == NULL) return;
3518
5470
  if (sep == NULL || sep->data.ptrvalue == NULL) return;
3534
5486
        if (sip != NULL) {
3535
5487
          if (SeqIdIn (sip, bsp->id)) {
3536
5488
            slp = SeqLocCopyRegion (sip, sfp->location, bsp, 0,
3537
 
                                    bsp->length - 1, Seq_strand_minus, FALSE);
 
5489
                                    bsp->length - 1, Seq_strand_minus, &split);
3538
5490
            sfp->location = SeqLocFree (sfp->location);
3539
5491
            sfp->location = slp;
 
5492
            switch (sfp->data.choice) {
 
5493
              case SEQFEAT_CDREGION :
 
5494
                crp = (CdRegionPtr) sfp->data.value.ptrvalue;
 
5495
                if (crp != NULL) {
 
5496
                  for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
 
5497
                    sip = SeqLocId (cbp->loc);
 
5498
                    slp = SeqLocCopyRegion (sip, cbp->loc, bsp, 0,
 
5499
                                            bsp->length - 1, Seq_strand_minus, &split);
 
5500
                    cbp->loc = SeqLocFree (cbp->loc);
 
5501
                    cbp->loc = slp;
 
5502
                  }
 
5503
                }
 
5504
                break;
 
5505
              case SEQFEAT_RNA :
 
5506
                rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
 
5507
                if (rrp != NULL && rrp->ext.choice == 2) {
 
5508
                  trp = (tRNAPtr) rrp->ext.value.ptrvalue;
 
5509
                  if (trp != NULL && trp->anticodon != NULL) {
 
5510
                    sip = SeqLocId (trp->anticodon);
 
5511
                    slp = SeqLocCopyRegion (sip, trp->anticodon, bsp, 0,
 
5512
                                            bsp->length - 1, Seq_strand_minus, &split);
 
5513
                    trp->anticodon = SeqLocFree (trp->anticodon);
 
5514
                    trp->anticodon = slp;
 
5515
                  }
 
5516
                }
 
5517
                break;
 
5518
              default :
 
5519
                break;
 
5520
            }
3540
5521
          }
3541
5522
        }
3542
5523
        sfp = sfp->next;
3811
5792
  }
3812
5793
}
3813
5794
 
3814
 
static void RemoveProteinBioseq (SeqEntryPtr sep, BioseqPtr bsp)
3815
 
 
3816
 
{
3817
 
  BioseqSetPtr      bssp;
3818
 
  SeqEntryPtr       next;
3819
 
  ObjMgrDataPtr     omdptop;
3820
 
  ObjMgrData        omdata;
3821
 
  Uint2             parenttype;
3822
 
  Pointer           parentptr;
3823
 
  SeqEntryPtr PNTR  prev;
3824
 
  SeqEntryPtr       top;
3825
 
 
3826
 
  if (sep == NULL) return;
3827
 
  if (IS_Bioseq_set (sep)) {
3828
 
    top = sep;
3829
 
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
3830
 
    if (bssp != NULL) {
3831
 
      prev = &(bssp->seq_set);
3832
 
      sep = bssp->seq_set;
3833
 
      while (sep != NULL) {
3834
 
        next = sep->next;
3835
 
        if (IS_Bioseq_set (sep)) {
3836
 
          RemoveProteinBioseq (sep, bsp);
3837
 
          sep = next;
3838
 
        } else if (IS_Bioseq (sep) && sep->data.ptrvalue == (Pointer) bsp) {
3839
 
          *(prev) = next;
3840
 
          sep->next = NULL;
3841
 
          SaveSeqEntryObjMgrData (top, &omdptop, &omdata);
3842
 
          GetSeqEntryParent (top, &parentptr, &parenttype);
3843
 
          SeqEntryFree (sep);
3844
 
          SeqMgrLinkSeqEntry (top, parenttype, parentptr);
3845
 
          RestoreSeqEntryObjMgrData (top, omdptop, &omdata);
3846
 
          sep = next;
3847
 
        } else {
3848
 
          prev = &(sep->next);
3849
 
          sep = next;
3850
 
        }
3851
 
      }
3852
 
    }
3853
 
  }
3854
 
}
3855
 
 
3856
 
static void RemoveOrphanProteins (Uint2 entityID, SeqEntryPtr sep)
 
5795
extern void RemoveOrphanProteins (Uint2 entityID, SeqEntryPtr sep)
3857
5796
 
3858
5797
{
3859
5798
  Int2        doit;
3861
5800
  ValNodePtr  vnp;
3862
5801
  ValNodePtr  vnp1;
3863
5802
  ValNodePtr  vnp2;
 
5803
  BioseqPtr   protein_bsp;
3864
5804
 
3865
5805
  if (sep == NULL || entityID == 0) return;
3866
5806
  od.bspfromcds = NULL;
3867
5807
  od.bspinentry = NULL;
 
5808
  /* This function collects a list of all proteins in the entry
 
5809
   * and a list of all proteins that are products of a CDS
 
5810
   */
3868
5811
  SeqEntryExplore (sep, (Pointer) &od, GetCdsProducts);
3869
 
  if (od.bspinentry != NULL && od.bspfromcds != NULL) {
 
5812
 
 
5813
  /* If there are no proteins in the entry at all, we're done */
 
5814
  if (od.bspinentry == NULL)
 
5815
  {
 
5816
    ValNodeFree (od.bspinentry);
 
5817
    return;
 
5818
  }
 
5819
 
 
5820
  /* If we found any CDS product proteins, we need to sort the two
 
5821
   * lists and mark the ones in both lists as "keep".
 
5822
   * If there are no CDS product proteins, then all of the proteins
 
5823
   * in the entry should be removed.
 
5824
   */
 
5825
  if (od.bspfromcds != NULL) {
3870
5826
    od.bspinentry = SortValNode (od.bspinentry, SortByVnpDataPtrvalue);
3871
5827
    od.bspfromcds = SortValNode (od.bspfromcds, SortByVnpDataPtrvalue);
3872
5828
    vnp1 = od.bspfromcds;
3882
5838
        vnp2 = vnp2->next;
3883
5839
      }
3884
5840
    }
3885
 
    doit = 0;
3886
 
    for (vnp = od.bspinentry; vnp != NULL; vnp = vnp->next) {
3887
 
      if (vnp->data.ptrvalue != NULL) {
3888
 
        doit++;
3889
 
      }
 
5841
  }
 
5842
 
 
5843
  /* Now we count how many proteins are in the entry but not a 
 
5844
   * product of a CDS
 
5845
   */
 
5846
  doit = 0;
 
5847
  for (vnp = od.bspinentry; vnp != NULL; vnp = vnp->next) {
 
5848
    if (vnp->data.ptrvalue != NULL) {
 
5849
      doit++;
3890
5850
    }
3891
 
    if (doit > 0) {
3892
 
      if (Message (MSG_YN, "Do you want to remove %d orphaned proteins?", (int) doit) == ANS_YES) {
3893
 
        vnp = od.bspinentry;
3894
 
        while (vnp != NULL) {
3895
 
          if (vnp->data.ptrvalue != NULL) {
3896
 
            RemoveProteinBioseq (sep, (BioseqPtr) vnp->data.ptrvalue);
3897
 
          }
3898
 
          vnp = vnp->next;
 
5851
  }
 
5852
  if (doit > 0) {
 
5853
    if (Message (MSG_YN, "Do you want to remove %d orphaned proteins?", (int) doit) == ANS_YES) {
 
5854
      vnp = od.bspinentry;
 
5855
      while (vnp != NULL) {
 
5856
        if (vnp->data.ptrvalue != NULL) {
 
5857
          protein_bsp = vnp->data.ptrvalue;
 
5858
          protein_bsp->idx.deleteme = TRUE;
3899
5859
        }
 
5860
        vnp = vnp->next;
3900
5861
      }
 
5862
      DeleteMarkedObjects (entityID, 0, NULL);
 
5863
      ObjMgrSetDirtyFlag (entityID, TRUE);
 
5864
      ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
3901
5865
    }
3902
5866
  }
 
5867
  
3903
5868
  ValNodeFree (od.bspinentry);
3904
5869
  ValNodeFree (od.bspfromcds);
3905
5870
}
4005
5970
  return popphymut;
4006
5971
}
4007
5972
 
4008
 
static Int2 LIBCALLBACK PopWithinGenBankSet (Pointer data)
 
5973
static Int2 LIBCALLBACK SetWithinGenBankSet (Pointer data, Uint1 _class)
4009
5974
 
4010
5975
{
4011
5976
  BioseqSetPtr      bssp;
4038
6003
  if (IS_Bioseq_set (sep)) {
4039
6004
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
4040
6005
    if (bssp != NULL) {
4041
 
      newbssp = InsetNewSet (bssp, BioseqseqSet_class_pop_set);
 
6006
      newbssp = InsetNewSet (bssp, _class);
4042
6007
      if (newbssp != NULL) {
4043
6008
        newbssp->descr = bssp->descr;
4044
6009
        bssp->descr = NULL;
4054
6019
  return OM_MSG_RET_DONE;
4055
6020
}
4056
6021
 
4057
 
static Int2 LIBCALLBACK RemoveExtraneousSets (Pointer data)
 
6022
static Int2 LIBCALLBACK PopWithinGenBankSet (Pointer data)
 
6023
 
 
6024
{
 
6025
  return SetWithinGenBankSet (data, BioseqseqSet_class_pop_set);
 
6026
}
 
6027
 
 
6028
static Int2 LIBCALLBACK PhyWithinGenBankSet (Pointer data)
 
6029
 
 
6030
{
 
6031
  return SetWithinGenBankSet (data, BioseqseqSet_class_phy_set);
 
6032
}
 
6033
 
 
6034
extern Int2 LIBCALLBACK RemoveExtraneousSets (Pointer data)
4058
6035
 
4059
6036
{
4060
6037
  BioseqPtr         bsp;
4129
6106
 
4130
6107
{
4131
6108
  BioseqSetPtr      bssp;
4132
 
  ValNodePtr        descr1 = NULL;
4133
 
  ValNodePtr        descr2 = NULL;
4134
 
  BioseqSetPtr      first = NULL;
4135
6109
  SeqEntryPtr       last;
4136
6110
  SeqEntryPtr       next;
4137
6111
  ObjMgrDataPtr     omdptop;
4475
6449
  if (IS_Bioseq_set (sep)) {
4476
6450
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
4477
6451
    if (bssp != NULL && (bssp->_class == 7 ||
4478
 
                         (bssp->_class >= 13 && bssp->_class <= 16))) {
 
6452
                         (IsPopPhyEtcSet (bssp->_class)))) {
4479
6453
      for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
4480
6454
        FixupRBSGenes (entityID, sep);
4481
6455
      }
4786
6760
  return OM_MSG_RET_DONE;
4787
6761
}
4788
6762
 
 
6763
static Int2 LIBCALLBACK FindNonACGT (Pointer data)
 
6764
 
 
6765
{
 
6766
  Byte              bases [400];
 
6767
  BioseqPtr         bsp = NULL;
 
6768
  Uint1             code = Seq_code_iupacna;
 
6769
  Int2              ctr;
 
6770
  FILE              *fp;
 
6771
  Int2              i;
 
6772
  Boolean           is_bad = FALSE;
 
6773
  Int4              len;
 
6774
  OMProcControlPtr  ompcp;
 
6775
  Char              path [PATH_MAX];
 
6776
  Uint1             residue;
 
6777
  SeqPortPtr        spp = NULL;
 
6778
  Int4              total = 0;
 
6779
 
 
6780
  ompcp = (OMProcControlPtr) data;
 
6781
  if (ompcp == NULL || ompcp->input_entityID == 0) {
 
6782
    Message (MSG_ERROR, "Please select a Bioseq");
 
6783
    return OM_MSG_RET_ERROR;
 
6784
  }
 
6785
  switch (ompcp->input_itemtype) {
 
6786
    case OBJ_BIOSEQ :
 
6787
      bsp = (BioseqPtr) ompcp->input_data;
 
6788
      break;
 
6789
    default :
 
6790
      break;
 
6791
  }
 
6792
  if (bsp == NULL) {
 
6793
    Message (MSG_ERROR, "Please select a Bioseq");
 
6794
    return OM_MSG_RET_ERROR;
 
6795
  }
 
6796
  if (ISA_aa (bsp->mol)) {
 
6797
    code = Seq_code_ncbieaa;
 
6798
  }
 
6799
 
 
6800
  spp = SeqPortNew (bsp, 0, -1, 0, code);
 
6801
  len = bsp->length;
 
6802
 
 
6803
  if (spp == NULL) return OM_MSG_RET_ERROR;
 
6804
 
 
6805
  TmpNam (path);
 
6806
  fp = FileOpen (path, "w");
 
6807
 
 
6808
  /* use SeqPortRead rather than SeqPortGetResidue for faster performance */
 
6809
 
 
6810
  ctr = SeqPortRead (spp, bases, sizeof (bases));
 
6811
  i = 0;
 
6812
  residue = (Uint1) bases [i];
 
6813
  while (residue != SEQPORT_EOF) {
 
6814
    if (IS_residue (residue)) {
 
6815
      total++;
 
6816
      switch (residue) {
 
6817
        case 'A' :
 
6818
        case 'C' :
 
6819
        case 'G' :
 
6820
        case 'T' :
 
6821
          break;
 
6822
        default :
 
6823
          fprintf (fp, "Bad residue '%c' at position %ld\n", (char) residue, (long) total);
 
6824
          is_bad = TRUE;
 
6825
          break;
 
6826
      }
 
6827
    }
 
6828
    i++;
 
6829
    if (i >= ctr) {
 
6830
      i = 0;
 
6831
      ctr = SeqPortRead (spp, bases, sizeof (bases));
 
6832
      if (ctr < 0) {
 
6833
        bases [0] = -ctr;
 
6834
      } else if (ctr < 1) {
 
6835
        bases [0] = SEQPORT_EOF;
 
6836
      }
 
6837
    }
 
6838
    residue = (Uint1) bases [i];
 
6839
  }
 
6840
 
 
6841
  SeqPortFree (spp);
 
6842
 
 
6843
  if (! is_bad) {
 
6844
    fprintf (fp, "No ambiguous residues found");
 
6845
  }
 
6846
 
 
6847
  FileClose (fp);
 
6848
  LaunchGeneralTextViewer (path, "Bioseq Index Report");
 
6849
  FileRemove (path);
 
6850
  return OM_MSG_RET_DONE;
 
6851
}
 
6852
 
4789
6853
static void NEAR RevStringUpper (CharPtr str)
4790
6854
{
4791
6855
        CharPtr nd;
4943
7007
  if (IS_Bioseq_set (sep)) {
4944
7008
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
4945
7009
    if (bssp != NULL && (bssp->_class == 7 ||
4946
 
                         (bssp->_class >= 13 && bssp->_class <= 16))) {
 
7010
                         (IsPopPhyEtcSet (bssp->_class)))) {
4947
7011
      for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
4948
7012
        DoTrimGenesGenes (entityID, sep);
4949
7013
      }
5138
7202
  return OM_MSG_RET_DONE;
5139
7203
}
5140
7204
 
5141
 
static Int2 LIBCALLBACK DoDescriptorPropagate (Pointer data)
5142
 
 
5143
 
{
5144
 
  BioseqPtr         bsp;
5145
 
  BioseqSetPtr      bssp = NULL;
5146
 
  OMProcControlPtr  ompcp;
5147
 
  SeqEntryPtr       seqentry;
5148
 
  ValNodePtr        sourcedescr;
5149
 
 
5150
 
  ompcp = (OMProcControlPtr) data;
5151
 
  if (ompcp == NULL || ompcp->input_entityID == 0) {
5152
 
    Message (MSG_ERROR, "Please select a BioseqSet");
5153
 
    return OM_MSG_RET_ERROR;
5154
 
  }
5155
 
  switch (ompcp->input_itemtype) {
5156
 
    case OBJ_BIOSEQSET :
5157
 
      bssp = (BioseqSetPtr) ompcp->input_data;
5158
 
      break;
5159
 
    case 0 :
5160
 
      Message (MSG_ERROR, "Please select a BioseqSet");
5161
 
      return OM_MSG_RET_ERROR;
5162
 
    default :
5163
 
      Message (MSG_ERROR, "Please select a BioseqSet");
5164
 
      return OM_MSG_RET_ERROR;
5165
 
  }
5166
 
 
5167
 
  if (bssp != NULL) {
5168
 
    sourcedescr = bssp->descr;
5169
 
    if (sourcedescr != NULL) {
5170
 
      bssp->descr = NULL;
5171
 
      seqentry = bssp->seq_set;
5172
 
      while (seqentry != NULL) {
5173
 
        if (seqentry->data.ptrvalue != NULL) {
5174
 
          if (seqentry->choice == 1) {
5175
 
            bsp = (BioseqPtr) seqentry->data.ptrvalue;
5176
 
            ValNodeLink (&(bsp->descr),
5177
 
                         AsnIoMemCopy ((Pointer) sourcedescr,
5178
 
                                       (AsnReadFunc) SeqDescrAsnRead,
5179
 
                                       (AsnWriteFunc) SeqDescrAsnWrite));
5180
 
          } else if (seqentry->choice == 2) {
5181
 
            bssp = (BioseqSetPtr) seqentry->data.ptrvalue;
5182
 
            ValNodeLink (&(bssp->descr),
5183
 
                         AsnIoMemCopy ((Pointer) sourcedescr,
5184
 
                                       (AsnReadFunc) SeqDescrAsnRead,
5185
 
                                       (AsnWriteFunc) SeqDescrAsnWrite));
5186
 
          }
5187
 
        }
5188
 
        seqentry = seqentry->next;
5189
 
      }
5190
 
      SeqDescrFree (sourcedescr);
5191
 
    }
5192
 
  }
5193
 
 
5194
 
  ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
5195
 
  ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
5196
 
  return OM_MSG_RET_DONE;
5197
 
}
5198
7205
 
5199
7206
static void ReindexBioseqs (BioseqPtr bsp, Pointer userdata)
5200
7207
 
5220
7227
  return OM_MSG_RET_DONE;
5221
7228
}
5222
7229
 
 
7230
static Int2 LIBCALLBACK FilterMolWtFunc (Pointer data)
 
7231
 
 
7232
{
 
7233
  BioseqPtr         bsp = NULL;
 
7234
  Char              buf [32];
 
7235
  FloatHi           molwt;
 
7236
  OMProcControlPtr  ompcp;
 
7237
  SeqEntryPtr       sep;
 
7238
  SeqLocPtr         slp;
 
7239
 
 
7240
  ompcp = (OMProcControlPtr) data;
 
7241
  if (ompcp == NULL || ompcp->input_itemtype == 0) return OM_MSG_RET_ERROR;
 
7242
 
 
7243
  switch (ompcp->input_itemtype)
 
7244
  {
 
7245
    case OBJ_BIOSEQ:
 
7246
      bsp = (BioseqPtr) ompcp->input_data;
 
7247
      break;
 
7248
    default:
 
7249
      return OM_MSG_RET_ERROR;
 
7250
  }
 
7251
 
 
7252
  if (bsp == NULL) return OM_MSG_RET_ERROR;
 
7253
  if (! (ISA_aa (bsp->mol))) return OM_MSG_RET_ERROR;
 
7254
 
 
7255
  sep = bsp->seqentry;
 
7256
  if (sep == NULL) return OM_MSG_RET_ERROR;
 
7257
 
 
7258
  slp = CreateWholeInterval (sep);
 
7259
  if (slp == NULL) return OM_MSG_RET_ERROR;
 
7260
 
 
7261
  molwt = MolWtForLoc (slp);
 
7262
  sprintf (buf, "%15.3lf", (double) molwt);
 
7263
  TrimSpacesAroundString (buf);
 
7264
  Message (MSG_OK, "Protein molecular weight is %s", buf);
 
7265
 
 
7266
  SeqLocFree (slp);
 
7267
 
 
7268
  return OM_MSG_RET_DONE;
 
7269
}
 
7270
 
 
7271
#define REGISTER_GROUP_MOLWT ObjMgrProcLoadEx (OMPROC_FILTER, \
 
7272
        "MOLWT", "MolWt", \
 
7273
        OBJ_BIOSEQ, 0, OBJ_BIOSEQ, 0, \
 
7274
        NULL, FilterMolWtFunc, PROC_PRIORITY_DEFAULT, "Analysis")
 
7275
 
5223
7276
extern void SetupSequinFilters (void)
5224
7277
 
5225
7278
{
5239
7292
  if (indexerVersion) {
5240
7293
    REGISTER_CLEAR_SEQENTRYSCOPE;
5241
7294
    REGISTER_SEQUIN_CACHE_ACCN;
 
7295
    REGISTER_SEPARATE_MRNA_ALIGNS;
 
7296
    REGISTER_SEQUIN_ACCN_TO_GI;
5242
7297
    REGISTER_SEQUIN_GI_TO_ACCN;
5243
 
    REGISTER_TPAASSEMBLYUSER_DESC_EDIT;
5244
7298
    REGISTER_REFGENEUSER_DESC_EDIT;
5245
7299
    REGISTER_PROT_IDS_TO_GENE_SYN;
5246
7300
    REGISTER_DESCRIPTOR_PROPAGATE;
5247
7301
  }
5248
7302
 
5249
 
  if (indexerVersion) {
5250
 
    if (GetAppParam ("SEQUIN", "SETTINGS", "ALLOWAUTOINTRONEXON", NULL, str, sizeof (str))) {
5251
 
      if (StringICmp (str, "TRUE") == 0) {
5252
 
        REGISTER_MAKEEXONINTRON;
5253
 
      }
5254
 
    }
 
7303
  if (indexerVersion
 
7304
    || (GetAppParam ("SEQUIN", "SETTINGS", "ALLOWAUTOINTRONEXON",
 
7305
                     NULL, str, sizeof (str))
 
7306
      && StringICmp (str, "TRUE") == 0))
 
7307
  {
 
7308
    REGISTER_MAKEEXONINTRON;
5255
7309
  }
5256
7310
 
 
7311
  REGISTER_TPAASSEMBLYUSER_DESC_EDIT;
 
7312
 
5257
7313
  REGISTER_BIOSEQ_COMPLEMENT;
5258
7314
  REGISTER_BIOSEQ_REVERSE;
5259
7315
  REGISTER_BIOSEQ_REVCOMP_WITHFEAT;
5271
7327
  REGISTER_MAKESEQALIGN;
5272
7328
  REGISTER_MAKESEQALIGNP;
5273
7329
  REGISTER_NORMSEQALIGN;
 
7330
  REGISTER_NOMORESEGGAP;
5274
7331
  REGISTER_OPENALED;
5275
7332
  REGISTER_OPENALED2;
5276
7333
  REGISTER_OPENALED3;
5279
7336
  if (extraServices) {
5280
7337
    REGISTER_TRIM_GENES;
5281
7338
    REGISTER_FIXUP_RBS;
 
7339
    REGISTER_INTERVAL_COMBINE_AND_FUSE;
5282
7340
    REGISTER_INTERVAL_COMBINE;
5283
7341
    REGISTER_REPACKAGE_PARTS;
5284
7342
    REGISTER_UNDOSEGSET;
5287
7345
  }
5288
7346
 
5289
7347
  if (indexerVersion) {
 
7348
    REGISTER_DELETE_BY_TEXT;
 
7349
    REGISTER_SEGREGATE_BY_MOLECULE_TYPE;
 
7350
    REGISTER_SEGREGATE_BY_FEATURE;
 
7351
    REGISTER_SEGREGATE_BY_DESCRIPTOR;
 
7352
    REGISTER_SEGREGATE_BY_TEXT;
 
7353
    REGISTER_FIND_NON_ACGT;
5290
7354
    REGISTER_BSP_INDEX;
5291
7355
    REGISTER_POPSET_WITHIN_GENBANK;
 
7356
    REGISTER_PHYSET_WITHIN_GENBANK;
5292
7357
    REGISTER_NORMALIZE_NUCPROT;
5293
7358
    REGISTER_REMOVE_EXTRANEOUS;
5294
7359
    REGISTER_REMOVE_MESSEDUP;
5303
7368
  REGISTER_GROUP_HOPP;
5304
7369
  REGISTER_GROUP_KYTE;
5305
7370
  REGISTER_GROUP_MATRIX;
 
7371
  REGISTER_GROUP_MOLWT;
5306
7372
}
5307
7373
 
5308
7374
extern CharPtr MergeValNodeStrings (ValNodePtr list, Boolean useReturn)
5436
7502
  {"Lab-host",              116},
5437
7503
  {"Lineage",               203},
5438
7504
  {"Map",                   102},
5439
 
  {"Natural-host",           21},
5440
7505
  {"Old Lineage",            53},
5441
7506
  {"Old Name",               54},
5442
7507
  {"OrgMod Note",            55},
5451
7516
  {"Serotype",                7},
5452
7517
  {"Serovar",                 9},
5453
7518
  {"Sex",                   107},
 
7519
  {"Specific-host",          21},
5454
7520
  {"Specimen-voucher",       23},
5455
7521
  {"Strain",                  2},
5456
7522
  {"Sub-species",            22},
5756
7822
*
5757
7823
**********************************************************************/
5758
7824
 
5759
 
static SeqLocPtr SeqLocReplaceLocalID (SeqLocPtr slp,
 
7825
extern SeqLocPtr SeqLocReplaceLocalID (SeqLocPtr slp,
5760
7826
                                       SeqIdPtr  new_sip)
5761
7827
{
5762
7828
  SeqLocPtr        curr;
5821
7887
    SeqLocReplaceLocalID (sfp->location, sip);
5822
7888
}
5823
7889
 
5824
 
static void ReplaceLocalIdOnProduct_callback (SeqFeatPtr sfp, Pointer userdata)
5825
 
{
5826
 
  SeqIdPtr sip;
5827
 
 
5828
 
  sip = (SeqIdPtr) userdata;
5829
 
  if (sfp->location != NULL) 
5830
 
    SeqLocReplaceLocalID (sfp->product, sip);
5831
 
}
5832
 
 
5833
 
static void ReplaceLocalID (BioseqPtr bsp, SeqIdPtr sip, CharPtr key, Int2 count)
5834
 
 
5835
 
{
5836
 
  ObjectIdPtr   oip;
5837
 
  Char          str [64];
5838
 
  Char          tmp [70];
5839
 
  BioseqSetPtr  bssp;
 
7890
static void CheckFeatForNuclID_callback (SeqFeatPtr sfp, Pointer userdata)
 
7891
{
 
7892
  SeqIdPtr            featSip = NULL;
 
7893
  ReplaceIDStructPtr  idsPtr;
 
7894
  ObjectIdPtr         oip;
 
7895
  Char                tmpIdStr [128];
 
7896
 
 
7897
  if (NULL == sfp)
 
7898
    return;
 
7899
 
 
7900
  if ((sfp->data.choice == SEQFEAT_CDREGION) &&
 
7901
      (sfp->location != NULL)) {
 
7902
 
 
7903
    /* Get the old Seq Id and the new */
 
7904
    /* one that it was changed to.    */
 
7905
    
 
7906
    idsPtr = (ReplaceIDStructPtr) userdata;
 
7907
    if ((NULL == idsPtr)         ||
 
7908
        (NULL == idsPtr->oldStr) ||
 
7909
        (NULL == idsPtr->newSip))
 
7910
      return;
 
7911
 
 
7912
    /* Get the location Seq ID for this CDS feature */
 
7913
    
 
7914
    featSip = SeqLocId (sfp->location);
 
7915
    if (featSip == NULL) return;
 
7916
    oip     = (ObjectIdPtr) featSip->data.ptrvalue;
 
7917
    
 
7918
    /* If the location Seq ID matches the old Seq Id */
 
7919
    /* then change the location to point to the new. */
 
7920
    
 
7921
    if (NULL == oip->str) {
 
7922
      sprintf (tmpIdStr, "%d", oip->id);
 
7923
      if (StringCmp (tmpIdStr, idsPtr->oldStr) == 0)
 
7924
        SeqLocReplaceLocalID (sfp->location, idsPtr->newSip);
 
7925
    }
 
7926
    else if (StringCmp (oip->str, idsPtr->oldStr) == 0)
 
7927
      SeqLocReplaceLocalID (sfp->location, idsPtr->newSip);
 
7928
  }
 
7929
}
 
7930
 
 
7931
static void CheckFeatForProductID_callback (SeqFeatPtr sfp, Pointer userdata)
 
7932
{
 
7933
  SeqIdPtr            featSip = NULL;
 
7934
  ReplaceIDStructPtr  idsPtr;
 
7935
  ObjectIdPtr         oip;
 
7936
  Char                tmpIdStr [128];
 
7937
 
 
7938
  if (NULL == sfp)
 
7939
    return;
 
7940
 
 
7941
  if ((sfp->data.choice == SEQFEAT_CDREGION) &&
 
7942
      (sfp->product != NULL)) {
 
7943
 
 
7944
    /* Get the old Seq Id and the new */
 
7945
    /* one that it was changed to.    */
 
7946
    
 
7947
    idsPtr = (ReplaceIDStructPtr) userdata;
 
7948
    if ((NULL == idsPtr)         ||
 
7949
        (NULL == idsPtr->oldStr) ||
 
7950
        (NULL == idsPtr->newSip))
 
7951
      return;
 
7952
 
 
7953
    /* Get the product Seq ID for this CDS feature */
 
7954
    
 
7955
    featSip = SeqLocId (sfp->product);
 
7956
    oip     = (ObjectIdPtr) featSip->data.ptrvalue;
 
7957
    
 
7958
    /* If the product Seq ID matches the old Seq Id */
 
7959
    /* then change the product to point to the new. */
 
7960
    
 
7961
    if (NULL == oip->str) {
 
7962
      sprintf (tmpIdStr, "%d", oip->id);
 
7963
      if (StringCmp (tmpIdStr, idsPtr->oldStr) == 0)
 
7964
        SeqLocReplaceLocalID (sfp->product, idsPtr->newSip);
 
7965
    }
 
7966
    if (StringCmp (oip->str, idsPtr->oldStr) == 0)
 
7967
      SeqLocReplaceLocalID (sfp->product, idsPtr->newSip);
 
7968
    
 
7969
  }
 
7970
}
 
7971
 
 
7972
static void ReplaceLocalID (BioseqPtr bsp,
 
7973
                            SeqIdPtr sip,
 
7974
                            CharPtr key,
 
7975
                            Int2 count)
 
7976
 
 
7977
{
 
7978
  ObjectIdPtr      oip;
 
7979
  Char             str [64];
 
7980
  Char             tmp [70];
 
7981
  BioseqSetPtr     bssp;
 
7982
  ReplaceIDStruct  ids;
 
7983
  BioseqPtr        siblingBsp;
 
7984
  SeqEntryPtr      sep;
 
7985
  Int2             parentType;
5840
7986
 
5841
7987
  if (bsp == NULL || sip == NULL || StringHasNoText (key)) return;
5842
7988
  oip = (ObjectIdPtr) sip->data.ptrvalue;
5843
7989
  if (oip == NULL) return;
 
7990
 
 
7991
  /* Create the new ID string */
 
7992
 
5844
7993
  StringNCpy_0 (str, key, sizeof (str));
5845
7994
  sprintf (tmp, "%s__%d", str, (int) count);
5846
 
  oip->str = MemFree (oip->str);
 
7995
 
 
7996
  /* Save the original SeqId for later passing */
 
7997
  /* to CheckSetForNuclID_callback () and      */
 
7998
  /* CheckSetForProductId_callback ().         */
 
7999
 
 
8000
  if (NULL != oip->str)
 
8001
    ids.oldStr = StringSave (oip->str);
 
8002
  else {
 
8003
    ids.oldStr = (CharPtr) MemNew (32);
 
8004
    sprintf (ids.oldStr, "%d", oip->id);
 
8005
  }
 
8006
    
 
8007
 
 
8008
  /* Update the Seq ID with the new string */
 
8009
 
5847
8010
  oip->str = StringSave (tmp);
 
8011
  ids.newSip = sip;
5848
8012
  SeqMgrReplaceInBioseqIndex (bsp);
5849
8013
 
5850
8014
  /* Replace the local ID on all the features of the bioseq */
5851
8015
 
5852
8016
  VisitFeaturesOnBsp (bsp, (Pointer) sip, ReplaceLocalIdOnLoc_callback);
5853
8017
 
5854
 
  if (bsp->idx.parenttype == OBJ_BIOSEQSET)
5855
 
    {
5856
 
      bssp = (BioseqSetPtr) bsp->idx.parentptr;
5857
 
      if ((bssp != NULL) && (bssp->_class == 1))
5858
 
        {
5859
 
          if (ISA_na(bsp->mol))
5860
 
            VisitFeaturesOnSet (bssp, (Pointer) sip,
5861
 
                                ReplaceLocalIdOnLoc_callback);
5862
 
          else if (ISA_aa(bsp->mol))
5863
 
            VisitFeaturesOnSet (bssp, (Pointer) sip,
5864
 
                                ReplaceLocalIdOnProduct_callback);
5865
 
        }
 
8018
  /* Check the parent (and grandparent, etc.) BioseqSet */
 
8019
  /* for features that use the changed ID.              */
 
8020
 
 
8021
  parentType = bsp->idx.parenttype;
 
8022
  if (parentType == OBJ_BIOSEQSET) 
 
8023
    bssp = (BioseqSetPtr) bsp->idx.parentptr;
 
8024
 
 
8025
  while (parentType == OBJ_BIOSEQSET) {
 
8026
 
 
8027
    if ((bssp != NULL) && (bssp->_class == 1)) {
 
8028
      
 
8029
      /* Check features that are attached to */
 
8030
      /* the parent set itself.              */
 
8031
      
 
8032
      if (ISA_na(bsp->mol))
 
8033
        VisitFeaturesOnSet (bssp, (Pointer) &ids,
 
8034
                            CheckFeatForNuclID_callback);
 
8035
      else if (ISA_aa(bsp->mol))
 
8036
        VisitFeaturesOnSet (bssp, (Pointer) &ids,
 
8037
                            CheckFeatForProductID_callback);
 
8038
      
 
8039
      /* Check features that are attached to */
 
8040
      /* other Bioseqs in the set.           */
 
8041
      
 
8042
      sep = bssp->seqentry;
 
8043
      while (NULL != sep) {
 
8044
        if (sep->choice == 1) { /* bioseq */
 
8045
          siblingBsp = (BioseqPtr) sep->data.ptrvalue;
 
8046
          if (ISA_na(bsp->mol))
 
8047
            VisitFeaturesOnBsp (siblingBsp, (Pointer) sip,
 
8048
                                CheckFeatForNuclID_callback);
 
8049
          else if (ISA_aa(bsp->mol))
 
8050
            VisitFeaturesOnBsp (siblingBsp, (Pointer) sip,
 
8051
                                CheckFeatForProductID_callback);
 
8052
        }
 
8053
        sep = sep->next;
 
8054
      }
 
8055
      
 
8056
      sep = bssp->seq_set;
 
8057
      while (NULL != sep) {
 
8058
        if (sep->choice == 1) { /* bioseq */
 
8059
          siblingBsp = (BioseqPtr) sep->data.ptrvalue;
 
8060
          if (ISA_na(bsp->mol))
 
8061
            VisitFeaturesOnBsp (siblingBsp, (Pointer) sip,
 
8062
                                CheckFeatForNuclID_callback);
 
8063
          else if (ISA_aa(bsp->mol))
 
8064
            VisitFeaturesOnBsp (siblingBsp, (Pointer) sip,
 
8065
                                CheckFeatForProductID_callback);
 
8066
        }
 
8067
        sep = sep->next;
 
8068
      }
5866
8069
    }
 
8070
    parentType = bssp->idx.parenttype;
 
8071
    bssp = (BioseqSetPtr) bssp->idx.parentptr;
 
8072
  }
 
8073
 
 
8074
  /* Clean up before exiting */
 
8075
 
 
8076
  MemFree (ids.oldStr);
5867
8077
 
5868
8078
}
5869
8079
 
5943
8153
 
5944
8154
extern Int2 DoOneSegFixup (SeqEntryPtr sep, Boolean ask);
5945
8155
 
5946
 
extern void ResolveExistingLocalIDs (IteM i);
5947
 
extern void ResolveExistingLocalIDs (IteM i)
5948
 
 
5949
 
{
5950
 
  MsgAnswer     ans;
5951
 
  BaseFormPtr   bfp;
 
8156
typedef struct reconstructsegsetans 
 
8157
{
 
8158
  WindoW  w;
 
8159
  Boolean ans;
 
8160
  Boolean done;
 
8161
} ReconstructSegSetAnsData, PNTR ReconstructSegSetAnsPtr;
 
8162
 
 
8163
static void ReconstructSegSetYes (ButtoN b)
 
8164
{
 
8165
  ReconstructSegSetAnsPtr rp;
 
8166
  
 
8167
  rp = (ReconstructSegSetAnsPtr) GetObjectExtra (b);
 
8168
  if (rp == NULL) return;
 
8169
  rp->ans = TRUE;
 
8170
  
 
8171
  Remove (rp->w);
 
8172
  rp->done = TRUE;
 
8173
}
 
8174
 
 
8175
static void ReconstructSegSetNo (ButtoN b)
 
8176
{
 
8177
  ReconstructSegSetAnsPtr rp;
 
8178
  
 
8179
  rp = (ReconstructSegSetAnsPtr) GetObjectExtra (b);
 
8180
  if (rp == NULL) return;
 
8181
  rp->ans = FALSE;
 
8182
  
 
8183
  Remove (rp->w);
 
8184
  rp->done = TRUE;
 
8185
}
 
8186
 
 
8187
static Boolean GetReconstructSegSetAnswer (void)
 
8188
{
 
8189
  ReconstructSegSetAnsData rd;
 
8190
  GrouP                    g, h, c;
 
8191
  ButtoN                   b;
 
8192
  
 
8193
  rd.w = ModalWindow(-20, -13, -10, -10, NULL);
 
8194
  h = HiddenGroup(rd.w, -1, 0, NULL);
 
8195
  SetGroupSpacing (h, 10, 10);
 
8196
  rd.done = FALSE;
 
8197
  g= HiddenGroup (h, 1, 0, NULL);
 
8198
  StaticPrompt (g, "Do you wish to also reconstruct segmented bioseqs?", 0, popupMenuHeight, programFont, 'l');
 
8199
  c = HiddenGroup (h, 2, 0, NULL);
 
8200
  b = PushButton(c, "Yes", ReconstructSegSetYes);
 
8201
  SetObjectExtra (b, &rd, NULL);
 
8202
  b = DefaultButton(c, "No", ReconstructSegSetNo);
 
8203
  SetObjectExtra (b, &rd, NULL);
 
8204
  AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
 
8205
  
 
8206
  Show(rd.w); 
 
8207
  Select (rd.w);
 
8208
  rd.done = FALSE;
 
8209
  while (!rd.done)
 
8210
  {
 
8211
    ProcessExternalEvent ();
 
8212
    Update ();
 
8213
  }
 
8214
  ProcessAnEvent ();
 
8215
  return rd.ans;
 
8216
}
 
8217
 
 
8218
 
 
8219
static void ResolveExistingLocalIDsBaseForm (BaseFormPtr bfp)
 
8220
 
 
8221
{
5952
8222
  Boolean       doParts = FALSE;
5953
8223
  LclIdListPtr  head = NULL;
5954
8224
  SeqEntryPtr   sep;
5955
8225
 
5956
 
#ifdef WIN_MAC
5957
 
  bfp = currentFormDataPtr;
5958
 
#else
5959
 
  bfp = GetObjectExtra (i);
5960
 
#endif
5961
8226
  if (bfp == NULL) return;
5962
8227
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
5963
8228
  if (sep == NULL) return;
5964
 
  ans = Message (MSG_YN, "Do you wish to also reconstruct segmented bioseqs?");
5965
 
  doParts = (Boolean) (ans == ANS_YES);
 
8229
  doParts = GetReconstructSegSetAnswer();
5966
8230
  SeqEntryExplore (sep, (Pointer) &head, ResolveExistingIDsCallback);
5967
8231
  FreeLclTree (&head);
5968
8232
  if (doParts) {
5972
8236
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
5973
8237
}
5974
8238
 
 
8239
extern void ResolveExistingLocalIDs (IteM i);
 
8240
extern void ResolveExistingLocalIDs (IteM i)
 
8241
{
 
8242
  BaseFormPtr   bfp;
 
8243
 
 
8244
#ifdef WIN_MAC
 
8245
  bfp = currentFormDataPtr;
 
8246
#else
 
8247
  bfp = GetObjectExtra (i);
 
8248
#endif
 
8249
 
 
8250
  if (bfp == NULL) return;
 
8251
  ResolveExistingLocalIDsBaseForm (bfp);
 
8252
}
 
8253
 
 
8254
extern void ResolveExistingLocalIDsToolBtn (ButtoN b)
 
8255
{
 
8256
  BaseFormPtr   bfp;
 
8257
 
 
8258
  bfp = (BaseFormPtr) GetObjectExtra (b);
 
8259
  if (bfp == NULL) return;
 
8260
  ResolveExistingLocalIDsBaseForm (bfp);
 
8261
}
 
8262
 
5975
8263
extern void SetSourceFocus (IteM i);
5976
8264
extern void ClearSourceFocus (IteM i);
5977
8265
 
5978
 
static void TouchFocus (SeqDescrPtr sdp, Pointer userdata)
5979
 
 
 
8266
static Boolean LIBCALLBACK SetDescriptorFocus (BioseqPtr bsp,
 
8267
                                        SeqMgrBioseqContextPtr bContext)
5980
8268
{
5981
 
  BioSourcePtr  biop;
5982
 
  BoolPtr       bptr;
5983
 
  Boolean       is_focus;
5984
 
 
5985
 
  if (sdp->choice != Seq_descr_source) return;
5986
 
  bptr = (BoolPtr) userdata;
5987
 
  is_focus = *bptr;
5988
 
  biop = (BioSourcePtr) sdp->data.ptrvalue;
5989
 
  if (biop == NULL) return;
5990
 
  biop->is_focus = is_focus;
 
8269
  SeqMgrFeatContext fContext;
 
8270
  SeqMgrDescContext dContext;
 
8271
  BioSourcePtr      biop;
 
8272
  Boolean           is_focus;
 
8273
  SeqDescrPtr       sdp;
 
8274
 
 
8275
  /* Only set the focus when the Bioseq has */
 
8276
  /* a source feature in addition to the    */
 
8277
  /* source descriptor.                     */
 
8278
 
 
8279
  is_focus = (Boolean) * ((BoolPtr) bContext->userdata);
 
8280
 
 
8281
  /* don't need feature to clear existing focus on descriptor */
 
8282
 
 
8283
  if (is_focus && NULL == SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_BIOSRC, 0,
 
8284
                                    &fContext))
 
8285
    return TRUE;
 
8286
 
 
8287
  /* Set the focus on all of the Bioseq's */
 
8288
  /* source descriptors.                  */
 
8289
 
 
8290
  sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dContext);
 
8291
  while (NULL != sdp) {
 
8292
    biop = (BioSourcePtr) sdp->data.ptrvalue;
 
8293
    if (biop == NULL)
 
8294
      return TRUE;
 
8295
    biop->is_focus = is_focus;
 
8296
    sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_source, &dContext);
 
8297
  }
 
8298
 
 
8299
  /* Return true to continue on to next Bioseq */
 
8300
    
 
8301
  return TRUE;
5991
8302
}
5992
8303
 
5993
8304
static void CommonSourceFocus (IteM i, Boolean setfocus)
6006
8317
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6007
8318
  if (sep == NULL) return;
6008
8319
  flag = setfocus;
6009
 
  VisitDescriptorsInSep (sep, (Pointer) &flag, TouchFocus);
 
8320
  SeqMgrExploreBioseqs (0, sep->data.ptrvalue, (Pointer) &flag,
 
8321
                        SetDescriptorFocus, TRUE, TRUE, TRUE);
6010
8322
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6011
8323
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
6012
8324
}
6168
8480
  ahp->which = DialogText (g, "", 5, NULL);
6169
8481
 
6170
8482
  c = HiddenGroup (h, 2, 0, NULL);
6171
 
  b = PushButton (c, "Accept", DoProcessExtraAccToHis);
 
8483
  b = DefaultButton (c, "Accept", DoProcessExtraAccToHis);
6172
8484
  SetObjectExtra (b, ahp, NULL);
6173
8485
  PushButton (c, "Cancel", StdCancelButtonProc);
6174
8486
  AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
6177
8489
  Update ();
6178
8490
}
6179
8491
 
6180
 
 
6181
 
static void FixLocStrands (SeqLocPtr slp)
6182
 
 
 
8492
static void ConvertLocationStrand (SeqLocPtr     slp,
 
8493
                                   EditStrandPtr esp)
6183
8494
{
6184
8495
  SeqLocPtr      loc;
6185
8496
  PackSeqPntPtr  psp;
6197
8508
      case SEQLOC_INT :
6198
8509
        sinp = (SeqIntPtr) slp->data.ptrvalue;
6199
8510
        if (sinp != NULL) {
6200
 
          if (sinp->strand == Seq_strand_unknown) {
6201
 
            sinp->strand = Seq_strand_plus;
 
8511
          if (sinp->strand == esp->fromStrand) {
 
8512
            sinp->strand = esp->toStrand;
6202
8513
          }
6203
8514
        }
6204
8515
        break;
6205
8516
      case SEQLOC_PNT :
6206
8517
        spp = (SeqPntPtr) slp->data.ptrvalue;
6207
8518
        if (spp != NULL) {
6208
 
          if (spp->strand == Seq_strand_unknown) {
6209
 
            spp->strand = Seq_strand_plus;
 
8519
          if (spp->strand == esp->fromStrand) {
 
8520
            spp->strand = esp->toStrand;
6210
8521
          }
6211
8522
        }
6212
8523
        break;
6213
8524
      case SEQLOC_PACKED_PNT :
6214
8525
        psp = (PackSeqPntPtr) slp->data.ptrvalue;
6215
8526
        if (psp != NULL) {
6216
 
          if (psp->strand == Seq_strand_unknown) {
6217
 
            psp->strand = Seq_strand_plus;
 
8527
          if (psp->strand == esp->fromStrand) {
 
8528
            psp->strand = esp->toStrand;
6218
8529
          }
6219
8530
        }
6220
8531
        break;
6223
8534
      case SEQLOC_EQUIV :
6224
8535
        loc = (SeqLocPtr) slp->data.ptrvalue;
6225
8536
        while (loc != NULL) {
6226
 
          FixLocStrands (loc);
 
8537
          ConvertLocationStrand (loc, esp);
6227
8538
          loc = loc->next;
6228
8539
        }
6229
8540
        break;
6232
8543
        if (sbp != NULL) {
6233
8544
          spp = (SeqPntPtr) sbp->a;
6234
8545
          if (spp != NULL) {
6235
 
            if (spp->strand == Seq_strand_unknown) {
6236
 
              spp->strand = Seq_strand_plus;
 
8546
            if (spp->strand == esp->fromStrand) {
 
8547
              spp->strand = esp->toStrand;
6237
8548
            }
6238
8549
          }
6239
8550
          spp = (SeqPntPtr) sbp->b;
6240
8551
          if (spp != NULL) {
6241
 
            if (spp->strand == Seq_strand_unknown) {
6242
 
              spp->strand = Seq_strand_plus;
 
8552
            if (spp->strand == esp->fromStrand) {
 
8553
              spp->strand = esp->toStrand;
6243
8554
            }
6244
8555
          }
6245
8556
        }
6253
8564
  }
6254
8565
}
6255
8566
 
6256
 
static void FixFeatStrands (SeqFeatPtr sfp, Pointer userdata)
6257
 
 
6258
 
{
6259
 
  FixLocStrands (sfp->location);
6260
 
}
6261
 
 
6262
 
extern void StrandUnknownToStrandPlus (IteM i);
6263
 
extern void StrandUnknownToStrandPlus (IteM i)
6264
 
 
6265
 
{
6266
 
  BaseFormPtr  bfp;
6267
 
  SeqEntryPtr  sep;
 
8567
static Boolean LIBCALLBACK DoEditStrand_FeatureCallback (SeqFeatPtr sfp,
 
8568
                                SeqMgrFeatContextPtr fcontext)
 
8569
{
 
8570
  EditStrandPtr  esp;
 
8571
  SeqLocPtr      slp;
 
8572
 
 
8573
  slp = sfp->location;
 
8574
  esp = (EditStrandPtr) fcontext->userdata;
 
8575
 
 
8576
  if ((!esp->when_string_not_present && MeetsStringConstraint (sfp, esp->findThisStr, esp->case_insensitive))
 
8577
    || (esp->when_string_not_present && !MeetsStringConstraint (sfp, esp->findThisStr, esp->case_insensitive)))
 
8578
  {
 
8579
    ConvertLocationStrand (slp, esp);
 
8580
  }
 
8581
 
 
8582
  return TRUE;
 
8583
}
 
8584
 
 
8585
static Boolean LIBCALLBACK DoEditStrand_BioseqCallback (BioseqPtr bsp,
 
8586
                                         SeqMgrBioseqContextPtr bcontext)
 
8587
{
 
8588
  Boolean        featureFilterArray [FEATDEF_MAX];
 
8589
  EditStrandPtr  esp;
 
8590
 
 
8591
  /* Get the attached data */
 
8592
 
 
8593
  esp = (EditStrandPtr) bcontext->userdata;
 
8594
 
 
8595
  /* Filter for the requested feature type, then */
 
8596
  /* explore the Bioseq's features, converting   */
 
8597
  /* the strands as requested.                   */
 
8598
 
 
8599
  if (esp->featSubType == 0)
 
8600
    SeqMgrExploreFeatures (bsp, (Pointer) esp, DoEditStrand_FeatureCallback,
 
8601
                           NULL, NULL, NULL);
 
8602
  else {
 
8603
    MemSet ((Pointer) (featureFilterArray), (int) FALSE, FEATDEF_MAX);
 
8604
    featureFilterArray[esp->featSubType] = TRUE;
 
8605
    SeqMgrExploreFeatures (bsp, (Pointer) esp, DoEditStrand_FeatureCallback,
 
8606
                           NULL, NULL, featureFilterArray);
 
8607
  }
 
8608
 
 
8609
  /* Return TRUE to continue on to the next Bioseq */
 
8610
 
 
8611
  return TRUE;
 
8612
}
 
8613
 
 
8614
static void DoEditFeatureStrand (ButtoN b)
 
8615
 
 
8616
{
 
8617
  EditStrandPtr   esp;
 
8618
  SeqEntryPtr     sep;
 
8619
  Int2            val;
 
8620
  ValNodePtr      vnp;
 
8621
 
 
8622
  /* Get the associated data */
 
8623
 
 
8624
  esp = (EditStrandPtr) GetObjectExtra (b);
 
8625
  if (esp == NULL)
 
8626
    return;
 
8627
 
 
8628
  /* Get the top-level seqentry */
 
8629
 
 
8630
  sep = GetTopSeqEntryForEntityID (esp->input_entityID);
 
8631
  if (sep == NULL)
 
8632
    return;
 
8633
 
 
8634
  /* Hide the screen and show 'working' cursor */
 
8635
 
 
8636
  Hide (esp->form);
 
8637
  WatchCursor ();
 
8638
  Update ();
 
8639
 
 
8640
  /* Get the selected values from the lists */
 
8641
 
 
8642
  esp->fromStrand = GetValue (esp->fromPopup);
 
8643
  esp->fromStrand--;
 
8644
  esp->toStrand = GetValue (esp->toPopup);
 
8645
  esp->toStrand--;
 
8646
 
 
8647
  val = GetValue (esp->feature);
 
8648
  vnp = NULL;
 
8649
  if (val > 0) {
 
8650
    vnp = esp->featlist;
 
8651
    while (vnp != NULL && val > 1) {
 
8652
      val--;
 
8653
      vnp = vnp->next;
 
8654
    }
 
8655
  }
 
8656
 
 
8657
  if (vnp != NULL)
 
8658
    esp->featSubType = vnp->choice;
 
8659
  else
 
8660
    esp->featSubType = 0;
 
8661
 
 
8662
  esp->findThisStr = JustSaveStringFromText (esp->findThis);
 
8663
  
 
8664
  esp->case_insensitive = GetStatus (esp->case_insensitive_btn);
 
8665
  esp->when_string_not_present = GetStatus (esp->when_string_not_present_btn);
 
8666
  
 
8667
  /* Explore each Bioseq */
 
8668
 
 
8669
  SeqMgrExploreBioseqs (esp->input_entityID, NULL, (Pointer) esp,
 
8670
                        DoEditStrand_BioseqCallback, TRUE, FALSE, TRUE);
 
8671
 
 
8672
  /* Flag as changed, cleanup, and exit */
 
8673
  MemFree (esp->findThisStr);
 
8674
 
 
8675
  ArrowCursor ();
 
8676
  Update ();
 
8677
  ObjMgrSetDirtyFlag (esp->input_entityID, TRUE);
 
8678
  ObjMgrSendMsg (OM_MSG_UPDATE, esp->input_entityID, 0, 0);
 
8679
  Remove (esp->form);
 
8680
}
 
8681
 
 
8682
static void CleanupEditStrandForm_Callback (GraphiC g, VoidPtr data)
 
8683
 
 
8684
{
 
8685
  EditStrandPtr  esp;
 
8686
 
 
8687
  esp = (EditStrandPtr) data;
 
8688
 
 
8689
  if (esp != NULL) 
 
8690
    ValNodeFree (esp->featlist);
 
8691
 
 
8692
  StdCleanupFormProc (g, data);
 
8693
}
 
8694
 
 
8695
extern void EditFeatureStrand (IteM i)
 
8696
{
 
8697
  ButtoN         b;
 
8698
  BaseFormPtr    bfp;
 
8699
  GrouP          c;
 
8700
  EditStrandPtr  esp;
 
8701
  GrouP          g;
 
8702
  GrouP          h;
 
8703
  ValNodePtr     head;
 
8704
  GrouP          k;
 
8705
  Int2           listHeight;
 
8706
  ValNodePtr     vnp;
 
8707
  WindoW         w;
 
8708
  GrouP          y;
 
8709
  GrouP          z;
6268
8710
 
6269
8711
#ifdef WIN_MAC
6270
8712
  bfp = currentFormDataPtr;
6271
8713
#else
6272
8714
  bfp = GetObjectExtra (i);
6273
8715
#endif
6274
 
  if (bfp == NULL) return;
6275
 
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
6276
 
  if (sep == NULL) return;
6277
 
  VisitFeaturesInSep (sep, NULL, FixFeatStrands);
6278
 
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
6279
 
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
8716
  if (bfp == NULL)
 
8717
    return;
 
8718
 
 
8719
  /* Create the edit feature window */
 
8720
 
 
8721
  w = FixedWindow (-50, -33, -10, -10, "Feature Strand Editor",
 
8722
                   StdCloseWindowProc);
 
8723
  /* Create a form for passing data to the callbacks */
 
8724
 
 
8725
  esp = (EditStrandPtr) MemNew (sizeof (EditStrand));
 
8726
  esp->form = (ForM) w;
 
8727
  esp->formmessage = NULL;
 
8728
  esp->input_entityID = bfp->input_entityID;
 
8729
 
 
8730
  SetObjectExtra (w, esp, CleanupEditStrandForm_Callback);
 
8731
 
 
8732
  /* Main overall group */
 
8733
 
 
8734
  h = HiddenGroup (w, -1, 0, NULL);
 
8735
  SetGroupSpacing (h, 10, 10);
 
8736
 
 
8737
  /* Create list box for feature types */
 
8738
 
 
8739
  k = HiddenGroup (h, 0, 2, NULL);
 
8740
  StaticPrompt (k, "Feature", 0, 0, programFont, 'c');
 
8741
  if (indexerVersion) {
 
8742
    listHeight = 16;
 
8743
  } else {
 
8744
    listHeight = 8;
 
8745
  }
 
8746
  esp->feature = SingleList (k, 16, listHeight, NULL);
 
8747
 
 
8748
  /* Create a val node list of all feature types */
 
8749
 
 
8750
  head = BuildFeatureValNodeList (TRUE, "[ALL FEATURES]", 0, FALSE, TRUE);
 
8751
 
 
8752
  /* Use the val node list to populate the feature list box */
 
8753
 
 
8754
  if (head != NULL) {
 
8755
    for (vnp = head; vnp != NULL; vnp = vnp->next)
 
8756
      ListItem (esp->feature, (CharPtr) vnp->data.ptrvalue);
 
8757
  }
 
8758
  esp->featlist = head;
 
8759
 
 
8760
  /* Create popups for source and destination strand type */
 
8761
 
 
8762
  g = HiddenGroup (h, 5, 0, NULL);
 
8763
 
 
8764
  StaticPrompt (g, "Convert From", 0, stdLineHeight, programFont, 'l');
 
8765
  esp->fromPopup = PopupList (g, TRUE, NULL);
 
8766
  PopupItem (esp->fromPopup, "Unknown");
 
8767
  PopupItem (esp->fromPopup, "Plus");
 
8768
  PopupItem (esp->fromPopup, "Minus");
 
8769
  PopupItem (esp->fromPopup, "Both");
 
8770
  PopupItem (esp->fromPopup, "Reverse");
 
8771
  SetValue (esp->fromPopup, 2);
 
8772
 
 
8773
  StaticPrompt (g, "To", 0, stdLineHeight, programFont, 'l');
 
8774
  esp->toPopup = PopupList (g, TRUE, NULL);
 
8775
  PopupItem (esp->toPopup, "Unknown");
 
8776
  PopupItem (esp->toPopup, "Plus");
 
8777
  PopupItem (esp->toPopup, "Minus");
 
8778
  PopupItem (esp->toPopup, "Both");
 
8779
  PopupItem (esp->toPopup, "Reverse");
 
8780
  SetValue (esp->toPopup, 3);
 
8781
 
 
8782
  y = HiddenGroup (h, 2, 0, NULL);
 
8783
  StaticPrompt (y, "Optional string constraint", 0,
 
8784
                dialogTextHeight, programFont, 'c');
 
8785
  esp->findThis = DialogText (y, "", 14, NULL);
 
8786
  z = HiddenGroup (h, 2, 0, NULL);
 
8787
  esp->case_insensitive_btn = CheckBox (z, "Case Insensitive", NULL);
 
8788
  esp->when_string_not_present_btn = CheckBox (z, "When String is Not Present", NULL);
 
8789
 
 
8790
  /* Create accept and cancel buttons */
 
8791
 
 
8792
  c = HiddenGroup (h, 2, 0, NULL);
 
8793
  b = DefaultButton (c, "Accept", DoEditFeatureStrand);
 
8794
  SetObjectExtra (b, esp, NULL);
 
8795
  PushButton (c, "Cancel", StdCancelButtonProc);
 
8796
 
 
8797
  /* Layout the objects and display the window */
 
8798
 
 
8799
  AlignObjects (ALIGN_CENTER, (HANDLE) k, (HANDLE) g, (HANDLE) y, (HANDLE) z, (HANDLE) c, NULL);
 
8800
  RealizeWindow (w);
 
8801
  Show (w);
 
8802
  Update ();
6280
8803
}
6281
8804
 
6282
8805
extern void ClearCdsProducts (IteM i);
6325
8848
  ClearFeatProducts (i, FEATDEF_mRNA);
6326
8849
}
6327
8850
 
 
8851
static void ConsolidateOneLikeSubSourceModifier (
 
8852
  SubSourcePtr match_to,
 
8853
  Boolean use_semicolon
 
8854
)
 
8855
{
 
8856
  SubSourcePtr prev, index;
 
8857
  Int4         len, num_matches;
 
8858
  CharPtr      new_value;
 
8859
 
 
8860
  if (match_to == NULL) return;
 
8861
  len = StringLen (match_to->name) + 1;
 
8862
  num_matches = 0;
 
8863
  prev = match_to;
 
8864
  index = match_to->next;
 
8865
  while (index != NULL)
 
8866
  {
 
8867
    if (index->subtype == match_to->subtype && index->name != NULL)
 
8868
    {
 
8869
      len += StringLen (index->name) + 2;
 
8870
      num_matches++;
 
8871
    }
 
8872
    index = index->next;
 
8873
  }
 
8874
  if (num_matches == 0) return;
 
8875
 
 
8876
  new_value = MemNew (len * sizeof (char));
 
8877
  if (new_value == NULL) return;
 
8878
 
 
8879
  StringCpy (new_value, match_to->name);
 
8880
  index = match_to->next;
 
8881
  while (index != NULL)
 
8882
  {
 
8883
    if (index->subtype == match_to->subtype && index->name != NULL)
 
8884
    {
 
8885
      if (use_semicolon)
 
8886
      {
 
8887
        StringCat (new_value, "; ");
 
8888
      }
 
8889
      else
 
8890
      {
 
8891
        StringCat (new_value, " ");
 
8892
      }
 
8893
      StringCat (new_value, index->name);
 
8894
      prev->next = index->next;
 
8895
      index->next = NULL;
 
8896
      SubSourceFree (index);
 
8897
      index = prev;
 
8898
    }
 
8899
    prev = index;
 
8900
    index = index->next;
 
8901
  }
 
8902
  MemFree (match_to->name);
 
8903
  match_to->name = new_value; 
 
8904
}
 
8905
  
 
8906
static void ConsolidateOneLikeOrganismModifier (
 
8907
  OrgModPtr match_to,
 
8908
  Boolean use_semicolon
 
8909
)
 
8910
{
 
8911
  OrgModPtr prev, index;
 
8912
  Int4      len, num_matches;
 
8913
  CharPtr   new_value;
 
8914
 
 
8915
  if (match_to == NULL) return;
 
8916
  len = StringLen (match_to->subname) + 1;
 
8917
  num_matches = 0;
 
8918
  prev = match_to;
 
8919
  index = match_to->next;
 
8920
  while (index != NULL)
 
8921
  {
 
8922
    if (index->subtype == match_to->subtype && index->subname != NULL)
 
8923
    {
 
8924
      len += StringLen (index->subname) + 2;
 
8925
      num_matches++;
 
8926
    }
 
8927
    index = index->next;
 
8928
  }
 
8929
  if (num_matches == 0) return;
 
8930
 
 
8931
  new_value = MemNew (len * sizeof (char));
 
8932
  if (new_value == NULL) return;
 
8933
 
 
8934
  StringCpy (new_value, match_to->subname);
 
8935
  index = match_to->next;
 
8936
  while (index != NULL)
 
8937
  {
 
8938
    if (index->subtype == match_to->subtype && index->subname != NULL)
 
8939
    {
 
8940
      if (use_semicolon)
 
8941
      {
 
8942
        StringCat (new_value, "; ");
 
8943
      }
 
8944
      else
 
8945
      {
 
8946
        StringCat (new_value, " ");
 
8947
      }
 
8948
      StringCat (new_value, index->subname);
 
8949
      prev->next = index->next;
 
8950
      index->next = NULL;
 
8951
      OrgModFree (index);
 
8952
      index = prev;
 
8953
    }
 
8954
    prev = index;
 
8955
    index = index->next;
 
8956
  }
 
8957
  MemFree (match_to->subname);
 
8958
  match_to->subname = new_value; 
 
8959
}
 
8960
  
 
8961
static void ConsolidateLikeModifiersProc (BioSourcePtr biop, Pointer userdata)
 
8962
{
 
8963
  SubSourcePtr ssp;
 
8964
  OrgModPtr    mod;
 
8965
  Boolean      use_semicolon;
 
8966
 
 
8967
  if (biop == NULL || userdata == NULL) return;
 
8968
 
 
8969
  use_semicolon = *((Boolean PNTR) userdata);
 
8970
 
 
8971
  for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next)
 
8972
  {
 
8973
    if (ssp->name != NULL)
 
8974
    {
 
8975
      ConsolidateOneLikeSubSourceModifier (ssp, use_semicolon);
 
8976
    }
 
8977
  }
 
8978
    
 
8979
  if (biop->org == NULL || biop->org->orgname == NULL) return;
 
8980
  for (mod = biop->org->orgname->mod; mod != NULL; mod = mod->next)
 
8981
  {
 
8982
    if (mod->subname != NULL)
 
8983
    {
 
8984
      ConsolidateOneLikeOrganismModifier (mod, use_semicolon);
 
8985
    }
 
8986
  }
 
8987
}
 
8988
 
 
8989
static void ConsolidateLikeModifiers (IteM i, Boolean use_semicolon)
 
8990
{
 
8991
  BaseFormPtr  bfp;
 
8992
  SeqEntryPtr  sep;
 
8993
 
 
8994
#ifdef WIN_MAC
 
8995
  bfp = currentFormDataPtr;
 
8996
#else
 
8997
  bfp = GetObjectExtra (i);
 
8998
#endif
 
8999
  if (bfp == NULL) return;
 
9000
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
 
9001
  if (sep == NULL) return;
 
9002
  VisitBioSourcesInSep (sep, &use_semicolon, ConsolidateLikeModifiersProc);
 
9003
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
9004
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
9005
}
 
9006
 
 
9007
extern void ConsolidateLikeModifiersWithSemicolons (IteM i)
 
9008
{
 
9009
  ConsolidateLikeModifiers (i, TRUE);
 
9010
}
 
9011
 
 
9012
extern void ConsolidateLikeModifiersWithoutSemicolons (IteM i)
 
9013
{
 
9014
  ConsolidateLikeModifiers (i, FALSE);
 
9015
}
 
9016
 
 
9017
static void ConsolidateOrganismNotesProc (BioSourcePtr biop, Pointer userdata)
 
9018
{
 
9019
  SubSourcePtr ssp, note_ssp;
 
9020
  OrgModPtr    mod, note_mod;
 
9021
 
 
9022
  if (biop == NULL) return;
 
9023
 
 
9024
  for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next)
 
9025
  {
 
9026
    if (ssp->subtype == 255 && ssp->name != NULL)
 
9027
    {
 
9028
      ConsolidateOneLikeSubSourceModifier (ssp, TRUE);
 
9029
      note_ssp = ssp;
 
9030
    }
 
9031
  }
 
9032
    
 
9033
  if (biop->org == NULL || biop->org->orgname == NULL) return;
 
9034
  for (mod = biop->org->orgname->mod; mod != NULL; mod = mod->next)
 
9035
  {
 
9036
    if (mod->subtype == 255 && mod->subname != NULL)
 
9037
    {
 
9038
      ConsolidateOneLikeOrganismModifier (mod, TRUE);
 
9039
      note_mod = mod;
 
9040
    }
 
9041
  }
 
9042
}
 
9043
 
 
9044
extern void ConsolidateOrganismNotes (IteM i)
 
9045
{
 
9046
  BaseFormPtr  bfp;
 
9047
  SeqEntryPtr  sep;
 
9048
 
 
9049
#ifdef WIN_MAC
 
9050
  bfp = currentFormDataPtr;
 
9051
#else
 
9052
  bfp = GetObjectExtra (i);
 
9053
#endif
 
9054
  if (bfp == NULL) return;
 
9055
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
 
9056
  if (sep == NULL) return;
 
9057
  VisitBioSourcesInSep (sep, NULL, ConsolidateOrganismNotesProc);
 
9058
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
9059
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
9060
}
 
9061
 
 
9062
static void CountryLookupProc (BioSourcePtr biop, Pointer userdata)
 
9063
{
 
9064
  CharPtr PNTR  list;
 
9065
  CharPtr PNTR  ptr;
 
9066
  SubSourcePtr  ssp;
 
9067
  CharPtr       cp, before, newname;
 
9068
  Int4          len_cntry, len_qual, len_name;
 
9069
 
 
9070
  if (biop == NULL || (list = (CharPtr PNTR)userdata) == NULL)
 
9071
  {
 
9072
        return;
 
9073
  }
 
9074
 
 
9075
  for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next) 
 
9076
  {
 
9077
        if (ssp->subtype != SUBSRC_country || ssp->name == NULL) continue;
 
9078
    for (ptr = list; ptr != NULL && *ptr != NULL; ptr++)
 
9079
    {
 
9080
      len_cntry = StringLen (*ptr);
 
9081
      cp = StringStr (ssp->name, *ptr);
 
9082
      if (cp != NULL && !isalpha (cp [len_cntry])) 
 
9083
      {
 
9084
        len_qual = StringLen (ssp->name);
 
9085
        if (cp == ssp->name)
 
9086
        {
 
9087
          if (len_cntry == len_qual || ssp->name [len_cntry] == ':')
 
9088
          {
 
9089
            /* exact match, don't need to do anything */
 
9090
            return;
 
9091
          }
 
9092
          ssp->name [len_cntry] = ':';
 
9093
          return;
 
9094
        }
 
9095
        else
 
9096
        {
 
9097
          if (isalpha (*(cp - 1)))
 
9098
          {
 
9099
            /* not really a match, part of another word */
 
9100
                continue;
 
9101
          }
 
9102
          else
 
9103
          {
 
9104
            newname = (CharPtr) MemNew (len_qual + 3);
 
9105
                *(cp - 1) = 0;
 
9106
                before = StringSave (ssp->name);
 
9107
                StringNCpy (newname, *ptr, len_cntry);
 
9108
                newname [len_cntry] = ':';
 
9109
                newname [len_cntry + 1] = ' ';
 
9110
                StringNCpy (newname + len_cntry + 2, before, StringLen (before));
 
9111
                StringCpy (newname + len_cntry + 2 + StringLen (before), cp + len_cntry);
 
9112
                len_name = StringLen (newname);
 
9113
                while (isspace (newname[len_name - 1]) || ispunct (newname [len_name - 1])) 
 
9114
                {
 
9115
                  newname [len_name - 1] = 0;
 
9116
                  len_name --;
 
9117
                }
 
9118
                before = MemFree (before);
 
9119
                MemFree (ssp->name);
 
9120
                ssp->name = newname;
 
9121
          }
 
9122
        }
 
9123
      }
 
9124
        }
 
9125
  }  
 
9126
}
 
9127
 
 
9128
extern void CountryLookup (IteM i)
 
9129
{
 
9130
  BaseFormPtr  bfp;
 
9131
  SeqEntryPtr  sep;
 
9132
  CharPtr PNTR list;
 
9133
 
 
9134
 
 
9135
#ifdef WIN_MAC
 
9136
  bfp = currentFormDataPtr;
 
9137
#else
 
9138
  bfp = GetObjectExtra (i);
 
9139
#endif
 
9140
  if (bfp == NULL) return;
 
9141
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
 
9142
  if (sep == NULL) return;
 
9143
  
 
9144
  list = GetValidCountryList ();
 
9145
  if (list == NULL) return;
 
9146
  VisitBioSourcesInSep (sep, list, CountryLookupProc);
 
9147
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
9148
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
9149
}
 
9150
 
 
9151
static Int4 ExtractNumber (CharPtr str)
 
9152
{
 
9153
  Int4    j;
 
9154
  CharPtr cp;
 
9155
  Char    num_str [15];
 
9156
  
 
9157
  if (str == NULL) return 0;
 
9158
  j = 0;
 
9159
  for (cp = str; *cp != 0 && ! ispunct (*cp) && j < 14; cp++)
 
9160
  {
 
9161
        if (isdigit (*cp))
 
9162
        {
 
9163
          num_str [j++] = *cp;
 
9164
        }
 
9165
  }
 
9166
  num_str [j] = 0;
 
9167
  return atoi (num_str);
 
9168
}
 
9169
 
 
9170
static Int4 GetProteinCoordinate (SeqFeatPtr cds, Int4 loc, BoolPtr warn)
 
9171
{
 
9172
  BioseqPtr         bsp;
 
9173
  SeqMgrFeatContext context;
 
9174
  Int4              j, len;
 
9175
  
 
9176
  if (cds == NULL) return 0;
 
9177
  
 
9178
  bsp = BioseqFindFromSeqLoc (cds->location);
 
9179
  if (bsp == NULL) return 0;
 
9180
  
 
9181
  cds = SeqMgrGetDesiredFeature (cds->idx.entityID, bsp, cds->idx.itemID, 0, cds, &context);
 
9182
  if (cds == NULL) return;
 
9183
  
 
9184
  len = 0;
 
9185
  for (j = 0; j < context.numivals; j++)
 
9186
  {
 
9187
        if (context.strand == Seq_strand_minus)
 
9188
        {
 
9189
          if (context.ivals [j] >= loc)
 
9190
          {
 
9191
                if (context.ivals [j + 1] > loc)
 
9192
                {
 
9193
                  len += context.ivals [j] - context.ivals [j + 1] + 1;
 
9194
                }
 
9195
                else
 
9196
                {
 
9197
                  len += context.ivals [j] - loc + 1;
 
9198
                }
 
9199
          }
 
9200
        }
 
9201
        else
 
9202
        {
 
9203
          if (context.ivals [j] <= loc)
 
9204
          {
 
9205
                if (context.ivals [j + 1] < loc)
 
9206
                {
 
9207
                  len += context.ivals [j + 1] - context.ivals [j] + 1;
 
9208
                }
 
9209
                else
 
9210
                {
 
9211
                  len += loc - context.ivals [j] + 1;
 
9212
                }
 
9213
          }
 
9214
        }
 
9215
  }
 
9216
  len--;
 
9217
  if (warn != NULL && len % 3 != 2)
 
9218
  {
 
9219
    *warn = TRUE;
 
9220
  }
 
9221
  return (len / 3);
 
9222
}
 
9223
 
 
9224
typedef struct logfiledata
 
9225
{
 
9226
  FILE *fp;
 
9227
  Boolean data_in_log;
 
9228
} LogFileData, PNTR LogFilePtr;
 
9229
 
 
9230
static void ExtractProteinFeaturesFromNoteCallback (SeqFeatPtr sfp, Pointer userdata)
 
9231
{
 
9232
  CharPtr     site_string, loc_string, stop_string;
 
9233
  CharPtr     format_str = "predicted by PSort:";
 
9234
  SeqFeatPtr  site_feat;
 
9235
  Int4        from, to, swp;
 
9236
  CharPtr     cp;
 
9237
  Int4        site_num = 0;
 
9238
  SeqIdPtr    sip;
 
9239
  SeqLocPtr   slp;
 
9240
  BioseqPtr   bsp;
 
9241
  Uint1       feat_type;
 
9242
  Char        ch;
 
9243
  ProtRefPtr  prp;
 
9244
  Boolean     warn;
 
9245
  LogFilePtr  lfp;
 
9246
  
 
9247
  if (sfp == NULL || sfp->idx.subtype != FEATDEF_CDS) return;
 
9248
  lfp = (LogFilePtr)userdata;
 
9249
  
 
9250
  sip = SeqLocId (sfp->product);
 
9251
  if (sip == NULL) return;
 
9252
  
 
9253
  bsp = BioseqFind (sip);
 
9254
  if (bsp == NULL) return;
 
9255
  
 
9256
  site_string = StringISearch (sfp->comment, format_str);
 
9257
  if (site_string == NULL) return;
 
9258
  site_string += StringLen (format_str);
 
9259
  /* need to parse semicolon-delimited list of site features */
 
9260
  while (site_string != NULL)
 
9261
  { 
 
9262
    stop_string = StringChr (site_string, ';');         
 
9263
    loc_string = StringChr (site_string, ':');
 
9264
    if (loc_string == NULL || (stop_string != NULL && loc_string > stop_string))
 
9265
    {
 
9266
      site_string = stop_string + 1;
 
9267
      continue;
 
9268
    }
 
9269
    loc_string ++;
 
9270
  
 
9271
    /* need to parse location */
 
9272
    from = ExtractNumber (loc_string);
 
9273
    cp = StringChr (loc_string, '-');
 
9274
    if (cp == NULL || (stop_string != NULL && cp > stop_string))
 
9275
    {
 
9276
      site_string = stop_string + 1;
 
9277
      continue;
 
9278
    }
 
9279
    to = ExtractNumber (cp + 1);  
 
9280
  
 
9281
    /* coordinates in comment start at 1, in SeqLoc start at 0 */
 
9282
    if (from > to)
 
9283
    {
 
9284
      swp = from;
 
9285
      from = to;
 
9286
      to = swp;
 
9287
    }
 
9288
 
 
9289
    warn = FALSE;
 
9290
    from = GetProteinCoordinate (sfp, from - 1, &warn);
 
9291
    /* Psort right end is off by one */
 
9292
    to = GetProteinCoordinate (sfp, to - 1, &warn);
 
9293
    if (warn && lfp != NULL)
 
9294
    {
 
9295
      if (stop_string != NULL)
 
9296
      {
 
9297
        ch = *stop_string;
 
9298
        *stop_string = 0;
 
9299
      }
 
9300
      fprintf (lfp->fp, "Cannot convert nucleotide coordinates to protein coordinates: %s\n",
 
9301
               site_string);
 
9302
      lfp->data_in_log = TRUE;
 
9303
      if (stop_string != NULL)
 
9304
      {
 
9305
        *stop_string = ch;
 
9306
      }
 
9307
    }
 
9308
 
 
9309
    /* parse feature type */
 
9310
    ch = *loc_string;
 
9311
    *loc_string = 0;
 
9312
    if (StringISearch (site_string, "transmembrane")!= NULL)
 
9313
    {
 
9314
      feat_type = SEQFEAT_REGION;
 
9315
    }
 
9316
    else if (StringISearch (site_string, "signal") != NULL)
 
9317
    {
 
9318
          feat_type = SEQFEAT_PROT;
 
9319
    }
 
9320
    else
 
9321
    {
 
9322
      feat_type = SEQFEAT_COMMENT;
 
9323
    }
 
9324
  
 
9325
    slp = SeqLocIntNew(from, to, SeqLocStrand (sfp->location), 
 
9326
                       SeqIdFindBest(sip, SEQID_GI)); 
 
9327
    if (slp == NULL) return;
 
9328
  
 
9329
    site_feat = CreateNewFeatureOnBioseq (bsp, feat_type, slp);
 
9330
    if (site_feat == NULL) return;
 
9331
    switch (feat_type)
 
9332
    {
 
9333
      case SEQFEAT_REGION:
 
9334
        site_feat->data.value.ptrvalue = StringSave ("Transmembrane domain");
 
9335
        break;
 
9336
      case SEQFEAT_PROT:
 
9337
        prp = ProtRefNew ();
 
9338
        site_feat->data.value.ptrvalue = prp;
 
9339
        if (prp != NULL)
 
9340
        {
 
9341
          prp->processed = 3;
 
9342
        }
 
9343
        break;
 
9344
      case SEQFEAT_COMMENT:
 
9345
        site_feat->data.choice = SEQFEAT_REGION;
 
9346
        site_feat->data.value.ptrvalue = StringSave (site_string);
 
9347
        break;
 
9348
    }
 
9349
    *loc_string = ch;
 
9350
        
 
9351
    /* move to next feature */
 
9352
    site_string = stop_string;
 
9353
    if (site_string != NULL)
 
9354
    {
 
9355
      site_string ++;
 
9356
      if (*site_string == 0)
 
9357
      {
 
9358
        site_string = NULL;
 
9359
      }
 
9360
    }
 
9361
  }
 
9362
}
 
9363
 
 
9364
extern void ExtractProteinFeaturesFromNote (IteM i)
 
9365
{
 
9366
  BaseFormPtr  bfp;
 
9367
  SeqEntryPtr  sep;
 
9368
  LogFileData  lfd;
 
9369
  Char         path [PATH_MAX];
 
9370
 
 
9371
#ifdef WIN_MAC
 
9372
  bfp = currentFormDataPtr;
 
9373
#else
 
9374
  bfp = GetObjectExtra (i);
 
9375
#endif
 
9376
  if (bfp == NULL) return;
 
9377
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
 
9378
  if (sep == NULL) return;
 
9379
  
 
9380
  TmpNam (path);
 
9381
  lfd.fp = FileOpen (path, "w");
 
9382
  lfd.data_in_log = FALSE;
 
9383
 
 
9384
  VisitFeaturesInSep (sep, (Pointer) &lfd, ExtractProteinFeaturesFromNoteCallback);
 
9385
  
 
9386
  FileClose (lfd.fp);
 
9387
  if (lfd.data_in_log)
 
9388
  {
 
9389
    LaunchGeneralTextViewer (path, "Protein Feature Location Errors");
 
9390
  }
 
9391
  FileRemove (path);
 
9392
  
 
9393
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
9394
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
9395
  Update ();
 
9396
}
 
9397
 
 
9398
extern void ConvertPseudoCDSToMiscFeat (IteM i)
 
9399
{
 
9400
  BaseFormPtr  bfp;
 
9401
 
 
9402
#ifdef WIN_MAC
 
9403
  bfp = currentFormDataPtr;
 
9404
#else
 
9405
  bfp = GetObjectExtra (i);
 
9406
#endif
 
9407
  if (bfp == NULL) return;
 
9408
  ConvertPseudoCDSToMiscFeatsForEntityID (bfp->input_entityID);
 
9409
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
9410
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
9411
  Update ();    
 
9412
}
 
9413
 
 
9414
extern void ProcessPseudoMiscFeat (IteM i)
 
9415
{
 
9416
  BaseFormPtr  bfp;
 
9417
 
 
9418
#ifdef WIN_MAC
 
9419
  bfp = currentFormDataPtr;
 
9420
#else
 
9421
  bfp = GetObjectExtra (i);
 
9422
#endif
 
9423
  if (bfp == NULL) return;
 
9424
  ProcessPseudoMiscFeatsForEntityID (bfp->input_entityID);
 
9425
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
9426
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
9427
  Update ();    
 
9428
}
 
9429
 
 
9430
static void ConvertGeneLocusTagToOldLocusTagCallback 
 
9431
(SeqFeatPtr sfp, Pointer userdata)
 
9432
{
 
9433
  SeqFeatPtr gene;
 
9434
  GeneRefPtr grp;
 
9435
  CharPtr    locus_tag;
 
9436
  GBQualPtr  new_qual, prev_qual;
 
9437
  SeqMgrFeatContext context;
 
9438
  
 
9439
  if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return;
 
9440
  
 
9441
  gene = SeqMgrGetOverlappingGene (sfp->location, &context);
 
9442
  if (gene == NULL) return;
 
9443
  
 
9444
  grp = (GeneRefPtr) gene->data.value.ptrvalue;
 
9445
  if (grp == NULL || StringHasNoText (grp->locus_tag))
 
9446
  {
 
9447
        return;
 
9448
  }
 
9449
  locus_tag = grp->locus_tag;
 
9450
  grp->locus_tag = NULL;
 
9451
  
 
9452
  new_qual = GBQualNew ();
 
9453
  if (new_qual == NULL) return;
 
9454
  new_qual->qual = StringSave ("old_locus_tag");
 
9455
  new_qual->val = locus_tag;
 
9456
  new_qual->next = NULL;
 
9457
  
 
9458
  if (gene->qual == NULL)
 
9459
  {
 
9460
        gene->qual = new_qual;
 
9461
  }
 
9462
  else
 
9463
  {
 
9464
        for (prev_qual = gene->qual; prev_qual->next != NULL; prev_qual = prev_qual->next)
 
9465
        {
 
9466
        }
 
9467
        prev_qual->next = new_qual;
 
9468
  }
 
9469
}
 
9470
 
 
9471
extern void ConvertGeneLocusTagToOldLocusTag (IteM i)
 
9472
{
 
9473
  BaseFormPtr  bfp;
 
9474
  SeqEntryPtr  sep;
 
9475
 
 
9476
#ifdef WIN_MAC
 
9477
  bfp = currentFormDataPtr;
 
9478
#else
 
9479
  bfp = GetObjectExtra (i);
 
9480
#endif
 
9481
  if (bfp == NULL) return;
 
9482
 
 
9483
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
 
9484
  if (sep == NULL) return;
 
9485
  VisitFeaturesInSep (sep, NULL, ConvertGeneLocusTagToOldLocusTagCallback);
 
9486
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
9487
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
9488
  Update ();            
 
9489
}
 
9490
 
 
9491
static void ParseInfluenzaAVirusNamesCallback (BioSourcePtr biop, Pointer userdata)
 
9492
{
 
9493
  CharPtr desired_name = "Influenza A virus";
 
9494
  Int4    desired_len = StringLen (desired_name);
 
9495
  CharPtr first_paren = NULL, second_paren = NULL;
 
9496
  CharPtr first_paren_close = NULL, second_paren_close = NULL;
 
9497
  CharPtr cp;
 
9498
  Int4    strain_len, serotype_len;
 
9499
  CharPtr strain, serotype;
 
9500
  OrgModPtr strain_omp, serotype_omp, last_omp, omp;
 
9501
  Boolean   added_strain = FALSE, added_serotype = FALSE;
 
9502
  
 
9503
  if (biop == NULL || biop->org == NULL || biop->org->taxname == NULL) return;
 
9504
  
 
9505
  if (StringNCmp (biop->org->taxname, desired_name, desired_len) != 0)
 
9506
  {
 
9507
    return;
 
9508
  }
 
9509
  
 
9510
  first_paren = StringChr (biop->org->taxname + desired_len, '(');
 
9511
  if (first_paren == NULL) return;
 
9512
  cp = first_paren + 1;
 
9513
  while (*cp != ')' && *cp != '(' && *cp != 0)
 
9514
  {
 
9515
    *cp++;
 
9516
  }
 
9517
  if (*cp != '(')
 
9518
  {
 
9519
    return;
 
9520
  }
 
9521
  second_paren = cp;
 
9522
  cp++;
 
9523
  while (*cp != ')' && *cp != '(' && *cp != 0)
 
9524
  {
 
9525
    *cp++;
 
9526
  }
 
9527
  if (*cp != ')')
 
9528
  {
 
9529
    return;
 
9530
  }
 
9531
  second_paren_close = cp;
 
9532
  cp++;
 
9533
  while (*cp != ')' && *cp != '(' && *cp != 0)
 
9534
  {
 
9535
    *cp++;
 
9536
  }
 
9537
  if (*cp != ')')
 
9538
  {
 
9539
    return;
 
9540
  }
 
9541
  first_paren_close = cp;
 
9542
 
 
9543
  if (biop->org->orgname == NULL)
 
9544
  {
 
9545
    biop->org->orgname = OrgNameNew ();
 
9546
    if (biop->org->orgname == NULL)
 
9547
    {
 
9548
      return;
 
9549
    }
 
9550
  }
 
9551
 
 
9552
  strain_len = second_paren - first_paren + first_paren_close - second_paren_close;
 
9553
  serotype_len = second_paren_close - second_paren;
 
9554
  strain = (CharPtr) MemNew (strain_len * sizeof (Char));
 
9555
  serotype = (CharPtr) MemNew (serotype_len * sizeof (Char));
 
9556
  if (strain == NULL || serotype == NULL)
 
9557
  {
 
9558
    strain = MemFree (strain);
 
9559
    serotype = MemFree (serotype);
 
9560
    return;
 
9561
  }
 
9562
  StringNCpy (strain, first_paren + 1, second_paren - first_paren - 1);
 
9563
  if (first_paren_close - second_paren_close > 1)
 
9564
  {
 
9565
    StringCat (strain, " ");
 
9566
    StringNCat (strain, second_paren_close + 1, first_paren_close - second_paren_close - 1);
 
9567
  }
 
9568
  StringNCpy (serotype, second_paren + 1, second_paren_close - second_paren - 1);
 
9569
 
 
9570
  last_omp = NULL;
 
9571
  for (omp = biop->org->orgname->mod;
 
9572
       omp != NULL && (!added_strain || ! added_serotype); 
 
9573
       omp = omp->next)
 
9574
  {
 
9575
    if (omp->subtype == ORGMOD_strain)
 
9576
    {
 
9577
      omp->subname = MemFree (omp->subname);
 
9578
      omp->subname = strain;
 
9579
      added_strain = TRUE;
 
9580
    }
 
9581
    else if (omp->subtype == ORGMOD_serotype)
 
9582
    {
 
9583
      omp->subname = MemFree (omp->subname);
 
9584
      omp->subname = serotype;
 
9585
      added_serotype = TRUE;      
 
9586
    }
 
9587
    last_omp = omp;
 
9588
  }
 
9589
  if (! added_strain)
 
9590
  {
 
9591
    strain_omp = OrgModNew ();
 
9592
    if (strain_omp != NULL)
 
9593
    {
 
9594
      strain_omp->subtype = ORGMOD_strain;
 
9595
      strain_omp->subname = strain;
 
9596
      if (last_omp == NULL)
 
9597
      {
 
9598
        biop->org->orgname->mod = strain_omp;
 
9599
      }
 
9600
      else
 
9601
      {
 
9602
        last_omp->next = strain_omp;
 
9603
      }
 
9604
      last_omp = strain_omp;
 
9605
    }
 
9606
  }
 
9607
  if (!added_serotype)
 
9608
  {
 
9609
    serotype_omp = OrgModNew ();
 
9610
    if (serotype_omp != NULL)
 
9611
    {
 
9612
      serotype_omp->subtype = ORGMOD_serotype;
 
9613
      serotype_omp->subname = serotype;
 
9614
      if (last_omp == NULL)
 
9615
      {
 
9616
        biop->org->orgname->mod = serotype_omp;
 
9617
      }
 
9618
      else
 
9619
      {
 
9620
        last_omp->next = serotype_omp;
 
9621
      }
 
9622
    }
 
9623
  }
 
9624
  
 
9625
}
 
9626
 
 
9627
extern void ParseInfluenzaAVirusNames (IteM i)
 
9628
{
 
9629
  BaseFormPtr  bfp;
 
9630
  SeqEntryPtr  sep;
 
9631
 
 
9632
#ifdef WIN_MAC
 
9633
  bfp = currentFormDataPtr;
 
9634
#else
 
9635
  bfp = GetObjectExtra (i);
 
9636
#endif
 
9637
  if (bfp == NULL) return;
 
9638
 
 
9639
  sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
 
9640
  if (sep == NULL) return;
 
9641
  VisitBioSourcesInSep (sep, NULL, ParseInfluenzaAVirusNamesCallback);
 
9642
  ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
 
9643
  ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
 
9644
  Update ();              
 
9645
}
 
9646
 
 
9647
/* The following code is used for global publication editing. */
 
9648
 
 
9649
enum pub_field_nums 
 
9650
{
 
9651
  PUB_FIELD_ANY = 0,
 
9652
  PUB_FIELD_TITLE,
 
9653
  PUB_FIELD_FIRST_NAME,
 
9654
  PUB_FIELD_MIDDLE_INITIAL,
 
9655
  PUB_FIELD_LAST_NAME,
 
9656
  PUB_FIELD_SUFFIX,
 
9657
  PUB_FIELD_CONSORTIUM,
 
9658
  PUB_FIELD_INSTITUTION,
 
9659
  PUB_FIELD_DEPARTMENT,
 
9660
  PUB_FIELD_ADDRESS,
 
9661
  PUB_FIELD_CITY,
 
9662
  PUB_FIELD_STATE,
 
9663
  PUB_FIELD_COUNTRY,
 
9664
  PUB_FIELD_ZIP,
 
9665
  PUB_FIELD_EMAIL,
 
9666
  PUB_FIELD_PHONE,
 
9667
  PUB_FIELD_FAX
 
9668
};
 
9669
 
 
9670
static ENUM_ALIST(pub_field_alist)
 
9671
  {"Any Pub Field",           PUB_FIELD_ANY},
 
9672
  {"Title",                   PUB_FIELD_TITLE},
 
9673
  {"Author First Name",       PUB_FIELD_FIRST_NAME},
 
9674
  {"Author Middle Initial",   PUB_FIELD_MIDDLE_INITIAL},
 
9675
  {"Author Last Name",        PUB_FIELD_LAST_NAME},
 
9676
  {"Author Suffix",           PUB_FIELD_SUFFIX},
 
9677
  {"Author Consortium",       PUB_FIELD_CONSORTIUM},
 
9678
  {"Affiliation Institution", PUB_FIELD_INSTITUTION},
 
9679
  {"Affiliation Department",  PUB_FIELD_DEPARTMENT},
 
9680
  {"Affiliation Address",     PUB_FIELD_ADDRESS},
 
9681
  {"Affiliation City",        PUB_FIELD_CITY},
 
9682
  {"Affiliation State",       PUB_FIELD_STATE},
 
9683
  {"Affiliation Country",     PUB_FIELD_COUNTRY},
 
9684
  {"Affiliation Zip Code",    PUB_FIELD_ZIP}, 
 
9685
  {"Affiliation Email",       PUB_FIELD_EMAIL}, 
 
9686
  {"Affiliation Phone",       PUB_FIELD_PHONE}, 
 
9687
  {"Affiliation Fax",         PUB_FIELD_FAX}, 
 
9688
END_ENUM_ALIST
 
9689
 
 
9690
static ENUM_ALIST(pub_field_no_any_alist)
 
9691
  {"Title",                   PUB_FIELD_TITLE},
 
9692
  {"Author First Name",       PUB_FIELD_FIRST_NAME},
 
9693
  {"Author Middle Initial",   PUB_FIELD_MIDDLE_INITIAL},
 
9694
  {"Author Last Name",        PUB_FIELD_LAST_NAME},
 
9695
  {"Author Suffix",           PUB_FIELD_SUFFIX},
 
9696
  {"Author Consortium",       PUB_FIELD_CONSORTIUM},
 
9697
  {"Affiliation Institution", PUB_FIELD_INSTITUTION},
 
9698
  {"Affiliation Department",  PUB_FIELD_DEPARTMENT},
 
9699
  {"Affiliation Address",     PUB_FIELD_ADDRESS},
 
9700
  {"Affiliation City",        PUB_FIELD_CITY},
 
9701
  {"Affiliation State",       PUB_FIELD_STATE},
 
9702
  {"Affiliation Country",     PUB_FIELD_COUNTRY},
 
9703
  {"Affiliation Zip Code",    PUB_FIELD_ZIP}, 
 
9704
  {"Affiliation Email",       PUB_FIELD_EMAIL}, 
 
9705
  {"Affiliation Phone",       PUB_FIELD_PHONE}, 
 
9706
  {"Affiliation Fax",         PUB_FIELD_FAX}, 
 
9707
END_ENUM_ALIST
 
9708
 
 
9709
 
 
9710
enum pub_status
 
9711
{
 
9712
  PUB_STAT_ANY = 0,
 
9713
  PUB_STAT_PUBLISHED,
 
9714
  PUB_STAT_UNPUBLISHED,
 
9715
  PUB_STAT_INPRESS,
 
9716
  PUB_STAT_PUBLISHED_SUBMISSION
 
9717
};
 
9718
 
 
9719
static ENUM_ALIST(pub_stat_alist)
 
9720
  {"Any",                     PUB_STAT_ANY},
 
9721
  {"Published",               PUB_STAT_PUBLISHED},
 
9722
  {"Unpublished",             PUB_STAT_UNPUBLISHED},
 
9723
  {"In Press",                PUB_STAT_INPRESS},
 
9724
  {"Submitter Block",         PUB_STAT_PUBLISHED_SUBMISSION},
 
9725
END_ENUM_ALIST
 
9726
 
 
9727
/* The following functions are used for getting and setting various types of data
 
9728
 * in publications.
 
9729
 */
 
9730
static CharPtr GetPubTitleSample (PubPtr the_pub)
 
9731
{
 
9732
  CitGenPtr    cgp;
 
9733
  CitArtPtr    cap;
 
9734
  CitBookPtr   cbp;
 
9735
  CitPatPtr    cpp;
 
9736
  CharPtr      retp = NULL;
 
9737
 
 
9738
  if (the_pub == NULL || the_pub->data.ptrvalue == NULL) return NULL;
 
9739
  
 
9740
  switch (the_pub->choice) {
 
9741
    case PUB_Gen :
 
9742
      cgp = (CitGenPtr) the_pub->data.ptrvalue;
 
9743
      retp = cgp->title;
 
9744
      break;
 
9745
    case PUB_Sub :
 
9746
      break;
 
9747
    case PUB_Article :
 
9748
      cap = (CitArtPtr) the_pub->data.ptrvalue;
 
9749
      if(cap->title != NULL) 
 
9750
      {
 
9751
        retp = cap->title->data.ptrvalue;
 
9752
      }
 
9753
      break;
 
9754
    case PUB_Book :
 
9755
    case PUB_Man :
 
9756
      cbp = (CitBookPtr) the_pub->data.ptrvalue;
 
9757
      if(cbp->title != NULL) 
 
9758
      {
 
9759
        retp = cbp->title->data.ptrvalue;
 
9760
      }
 
9761
      break;
 
9762
    case PUB_Patent :
 
9763
      cpp = (CitPatPtr) the_pub->data.ptrvalue;
 
9764
      retp = cpp->title;
 
9765
      break;
 
9766
    default :
 
9767
      break;
 
9768
  }
 
9769
  return retp;
 
9770
}
 
9771
 
 
9772
static void SetPubTitle (PubPtr the_pub, CharPtr new_title)
 
9773
{
 
9774
  CitGenPtr    cgp;
 
9775
  CitArtPtr    cap;
 
9776
  CitBookPtr   cbp;
 
9777
  CitPatPtr    cpp;
 
9778
 
 
9779
  if (the_pub == NULL || new_title == NULL) return;
 
9780
  
 
9781
  switch (the_pub->choice) {
 
9782
    case PUB_Gen :
 
9783
      cgp = (CitGenPtr) the_pub->data.ptrvalue;
 
9784
      cgp->title = MemFree (cgp->title);
 
9785
      cgp->title = StringSave (new_title);
 
9786
      break;
 
9787
    case PUB_Sub :
 
9788
      break;
 
9789
    case PUB_Article :
 
9790
      cap = (CitArtPtr) the_pub->data.ptrvalue;
 
9791
      if (cap->title == NULL)
 
9792
      {
 
9793
        cap->title = ValNodeNew (cap->title);
 
9794
        cap->title->choice = 1;
 
9795
      }
 
9796
      if(cap->title != NULL) 
 
9797
      {
 
9798
        cap->title->data.ptrvalue = MemFree (cap->title->data.ptrvalue);
 
9799
        cap->title->data.ptrvalue = StringSave (new_title);
 
9800
      }
 
9801
      break;
 
9802
    case PUB_Book :
 
9803
    case PUB_Man :
 
9804
      cbp = (CitBookPtr) the_pub->data.ptrvalue;
 
9805
      if (cbp->title == NULL)
 
9806
      {
 
9807
        cbp->title = ValNodeNew (cbp->title);
 
9808
        cbp->title->choice = 1;
 
9809
      }
 
9810
      if(cbp->title != NULL) 
 
9811
      {
 
9812
        cbp->title->data.ptrvalue = MemFree (cbp->title->data.ptrvalue);
 
9813
        cbp->title->data.ptrvalue = StringSave (new_title);
 
9814
      }
 
9815
      break;
 
9816
    case PUB_Patent :
 
9817
      cpp = (CitPatPtr) the_pub->data.ptrvalue;
 
9818
      cpp->title = MemFree (cpp->title);
 
9819
      cpp->title = StringSave (new_title);
 
9820
      break;
 
9821
    default :
 
9822
      break;
 
9823
  }   
 
9824
}
 
9825
 
 
9826
 
 
9827
static AuthListPtr GetAuthorListForPub (PubPtr the_pub)
 
9828
{
 
9829
  CitGenPtr  cgp;
 
9830
  CitSubPtr  csp;
 
9831
  CitArtPtr  cap;
 
9832
  CitBookPtr cbp;
 
9833
  CitPatPtr  cpp;
 
9834
  AuthListPtr alp = NULL;
 
9835
 
 
9836
  if (the_pub == NULL) return NULL;
 
9837
  
 
9838
  switch (the_pub->choice) {
 
9839
    case PUB_Gen :
 
9840
      cgp = (CitGenPtr) the_pub->data.ptrvalue;
 
9841
      alp = cgp->authors;
 
9842
      break;
 
9843
    case PUB_Sub :
 
9844
      csp = (CitSubPtr) the_pub->data.ptrvalue;
 
9845
      alp = csp->authors;
 
9846
      break;
 
9847
    case PUB_Article :
 
9848
      cap = (CitArtPtr) the_pub->data.ptrvalue;
 
9849
      alp = cap->authors;
 
9850
      break;
 
9851
    case PUB_Book :
 
9852
    case PUB_Man :
 
9853
      cbp = (CitBookPtr) the_pub->data.ptrvalue;
 
9854
      alp = cbp->authors;
 
9855
      break;
 
9856
    case PUB_Patent :
 
9857
      cpp = (CitPatPtr) the_pub->data.ptrvalue;
 
9858
      alp = cpp->authors;
 
9859
      break;
 
9860
    default :
 
9861
      break;
 
9862
  }
 
9863
  return alp;
 
9864
}
 
9865
 
 
9866
static Boolean SetPubAuthorList (PubPtr the_pub, AuthListPtr alp)
 
9867
{
 
9868
  CitGenPtr  cgp;
 
9869
  CitSubPtr  csp;
 
9870
  CitArtPtr  cap;
 
9871
  CitBookPtr cbp;
 
9872
  CitPatPtr  cpp;
 
9873
  Boolean    rval = FALSE;
 
9874
 
 
9875
  if (the_pub == NULL || the_pub->data.ptrvalue == NULL || alp == NULL) 
 
9876
    return FALSE;
 
9877
  
 
9878
  switch (the_pub->choice) {
 
9879
    case PUB_Gen :
 
9880
      cgp = (CitGenPtr) the_pub->data.ptrvalue;
 
9881
      cgp->authors = AuthListFree (cgp->authors);
 
9882
      cgp->authors = alp;
 
9883
      rval = TRUE;
 
9884
      break;
 
9885
    case PUB_Sub :
 
9886
      csp = (CitSubPtr) the_pub->data.ptrvalue;
 
9887
      csp->authors = AuthListFree (csp->authors);
 
9888
      csp->authors = alp;
 
9889
      rval = TRUE;
 
9890
      break;
 
9891
    case PUB_Article :
 
9892
      cap = (CitArtPtr) the_pub->data.ptrvalue;
 
9893
      cap->authors = AuthListFree (cap->authors);
 
9894
      cap->authors = alp;
 
9895
      rval = TRUE;
 
9896
      break;
 
9897
    case PUB_Book :
 
9898
    case PUB_Man :
 
9899
      cbp = (CitBookPtr) the_pub->data.ptrvalue;
 
9900
      cbp->authors = AuthListFree (cbp->authors);
 
9901
      cbp->authors = alp;
 
9902
      rval = TRUE;
 
9903
      break;
 
9904
    case PUB_Patent :
 
9905
      cpp = (CitPatPtr) the_pub->data.ptrvalue;
 
9906
      cpp->authors = AuthListFree (cpp->authors);
 
9907
      cpp->authors = alp;
 
9908
      rval = TRUE;
 
9909
      break;
 
9910
    default :
 
9911
      break;
 
9912
  }
 
9913
  return rval;
 
9914
}
 
9915
 
 
9916
 
 
9917
static CharPtr GetAuthorField (AuthorPtr ap, Int4 field_for_find)
 
9918
{
 
9919
  CharPtr      retp = NULL;
 
9920
  NameStdPtr   pNameStandard;
 
9921
  
 
9922
  if (ap == NULL || field_for_find == PUB_FIELD_ANY) return NULL;
 
9923
  
 
9924
  if (ap->name->choice == 2)
 
9925
  {
 
9926
    pNameStandard = (NameStdPtr) ap->name->data;
 
9927
    if (pNameStandard != NULL)
 
9928
    {
 
9929
      switch (field_for_find)
 
9930
      {
 
9931
        case PUB_FIELD_FIRST_NAME:
 
9932
          retp = pNameStandard->names [1];
 
9933
          break;
 
9934
        case PUB_FIELD_MIDDLE_INITIAL:
 
9935
          retp = pNameStandard->names [2];
 
9936
          break;
 
9937
        case PUB_FIELD_LAST_NAME:
 
9938
          retp = pNameStandard->names [0];
 
9939
          break;
 
9940
        case PUB_FIELD_SUFFIX:
 
9941
          retp = pNameStandard->names [5];
 
9942
          break;
 
9943
      }
 
9944
    }
 
9945
  }
 
9946
  else if (ap->name->choice == 5 && field_for_find == PUB_FIELD_CONSORTIUM)
 
9947
  {
 
9948
    retp = ap->name->data;
 
9949
  }
 
9950
  return retp;
 
9951
}
 
9952
 
 
9953
static CharPtr GetAuthorListFieldSample (PubPtr pub, Int4 field_for_find)
 
9954
{
 
9955
  CharPtr      retp = NULL;
 
9956
  AuthListPtr  alp;
 
9957
  ValNodePtr   names;
 
9958
  AuthorPtr    ap;
 
9959
  
 
9960
  if (pub == NULL || field_for_find == PUB_FIELD_ANY)
 
9961
  {
 
9962
    return NULL;
 
9963
  }
 
9964
  alp = GetAuthorListForPub (pub);
 
9965
  if (alp == NULL) return;
 
9966
  
 
9967
  for (names = alp->names; names != NULL && retp == NULL; names = names->next) 
 
9968
  { 
 
9969
    ap = names->data.ptrvalue;
 
9970
    retp = GetAuthorField (ap, field_for_find);
 
9971
    if (StringHasNoText (retp))
 
9972
    {
 
9973
      retp = NULL;
 
9974
    }
 
9975
  }
 
9976
  return retp;
 
9977
}
 
9978
 
 
9979
 
 
9980
static void MakeNewInitials (NameStdPtr name_std)
 
9981
{
 
9982
  Char       frstinits [64];
 
9983
  Int4       init_len;
 
9984
  
 
9985
  if (name_std == NULL) return;
 
9986
  FirstNameToInitials (name_std->names [1], frstinits, sizeof (frstinits) - 1);
 
9987
  init_len = StringLen (name_std->names [1]) + StringLen (name_std->names [2]) + 1;
 
9988
  name_std->names [4] = MemFree (name_std->names [4]);
 
9989
  name_std->names [4] = (CharPtr) MemNew (sizeof (Char) * init_len);
 
9990
  if (name_std->names [4] != NULL)
 
9991
  {
 
9992
    StringCpy (name_std->names [4], frstinits);
 
9993
    StringCat (name_std->names [4], name_std->names [2]);
 
9994
  }
 
9995
}
 
9996
 
 
9997
 
 
9998
static void SetAuthorString (AuthorPtr ap, Int4 field_to_set, CharPtr str)
 
9999
{
 
10000
  NameStdPtr name_std;
 
10001
  
 
10002
  if (field_to_set == PUB_FIELD_FIRST_NAME
 
10003
      || field_to_set == PUB_FIELD_LAST_NAME
 
10004
      || field_to_set == PUB_FIELD_MIDDLE_INITIAL
 
10005
      || field_to_set == PUB_FIELD_SUFFIX)
 
10006
  {
 
10007
    if (ap->name->choice != 2)
 
10008
    {
 
10009
      name_std = NameStdNew ();
 
10010
      if (name_std != NULL)
 
10011
      {
 
10012
        ap->name->data = MemFree (ap->name->data);
 
10013
        ap->name->data = name_std;
 
10014
        ap->name->choice = 2;        
 
10015
      }
 
10016
    }
 
10017
    if (ap->name->choice == 2)
 
10018
    {
 
10019
      name_std = (NameStdPtr) ap->name->data;
 
10020
      if (field_to_set == PUB_FIELD_FIRST_NAME)
 
10021
      {
 
10022
        name_std->names[1] = MemFree (name_std->names[1]);
 
10023
        name_std->names[1] = StringSave (str);
 
10024
        MakeNewInitials (name_std);
 
10025
      }
 
10026
      else if (field_to_set == PUB_FIELD_LAST_NAME)
 
10027
      {
 
10028
        name_std->names[0] = MemFree (name_std->names[0]);
 
10029
        name_std->names[0] = StringSave (str);
 
10030
      }
 
10031
      else if (field_to_set == PUB_FIELD_MIDDLE_INITIAL)
 
10032
      {
 
10033
        name_std->names[2] = MemFree (name_std->names[2]);
 
10034
        name_std->names[2] = StringSave (str);
 
10035
        MakeNewInitials (name_std);
 
10036
      }  
 
10037
      else if (field_to_set == PUB_FIELD_SUFFIX)
 
10038
      {
 
10039
        name_std->names[5] = MemFree (name_std->names[5]);
 
10040
        name_std->names[5] = StringSave (str);
 
10041
      }
 
10042
    }
 
10043
  }
 
10044
  else if (field_to_set == PUB_FIELD_CONSORTIUM)
 
10045
  {
 
10046
    if (ap->name->choice != 5)
 
10047
    {
 
10048
      if (ap->name->choice == 2)
 
10049
      {
 
10050
        ap->name->data = NameStdFree (ap->name->data);
 
10051
      }
 
10052
      else
 
10053
      {
 
10054
        ap->name->data = MemFree (ap->name->data);
 
10055
      }
 
10056
      ap->name->choice = 5;
 
10057
    }
 
10058
    if (ap->name->choice == 5)
 
10059
    {
 
10060
      ap->name->data = MemFree (ap->name->data);
 
10061
      ap->name->data = StringSave (str);      
 
10062
    }
 
10063
  }
 
10064
}
 
10065
 
 
10066
 
 
10067
static CharPtr GetAffiliationFieldSample (PubPtr pub, Int4 field_for_find)
 
10068
{
 
10069
  CharPtr      retp = NULL;
 
10070
  AuthListPtr  alp;
 
10071
  AffilPtr     affil;
 
10072
  
 
10073
  if (pub == NULL || field_for_find == PUB_FIELD_ANY)
 
10074
  {
 
10075
    return NULL;
 
10076
  }
 
10077
  alp = GetAuthorListForPub (pub);
 
10078
  if (alp == NULL) return;
 
10079
  
 
10080
  affil = alp->affil;
 
10081
  
 
10082
  if (affil == NULL) return;
 
10083
 
 
10084
  switch (field_for_find)
 
10085
  {
 
10086
    case PUB_FIELD_INSTITUTION:
 
10087
      retp = affil->affil;
 
10088
      break;
 
10089
    case PUB_FIELD_DEPARTMENT:
 
10090
      retp = affil->div;
 
10091
      break;
 
10092
    case PUB_FIELD_ADDRESS:
 
10093
      retp = affil->street;
 
10094
      break;
 
10095
    case PUB_FIELD_CITY:
 
10096
      retp = affil->city;
 
10097
      break;
 
10098
    case PUB_FIELD_STATE:
 
10099
      retp = affil->sub;
 
10100
      break;
 
10101
    case PUB_FIELD_COUNTRY:
 
10102
      retp = affil->country;
 
10103
      break;
 
10104
    case PUB_FIELD_ZIP:
 
10105
      retp = affil->postal_code;
 
10106
      break;
 
10107
    case PUB_FIELD_EMAIL:
 
10108
      retp = affil->email;
 
10109
      break;
 
10110
    case PUB_FIELD_PHONE:
 
10111
      retp = affil->phone;
 
10112
      break;
 
10113
    case PUB_FIELD_FAX:
 
10114
      retp = affil->fax;
 
10115
      break;
 
10116
  }
 
10117
  return retp;
 
10118
}
 
10119
 
 
10120
 
 
10121
static AffilPtr SetAffilString (AffilPtr affil, Int4 field_to_set, CharPtr str)
 
10122
{
 
10123
  if (affil == NULL)
 
10124
  {
 
10125
    affil = AffilNew ();
 
10126
    if (affil == NULL) return NULL;
 
10127
    affil->choice = 2;
 
10128
  }
 
10129
  else if (affil->choice != 2)
 
10130
  {
 
10131
    affil->choice = 2;
 
10132
  }    
 
10133
  if (field_to_set == PUB_FIELD_INSTITUTION)
 
10134
  {
 
10135
    affil->affil = MemFree (affil->affil);
 
10136
    affil->affil = StringSave (str);
 
10137
  }  
 
10138
  else if (field_to_set == PUB_FIELD_DEPARTMENT)
 
10139
  {
 
10140
    affil->div = MemFree (affil->div);
 
10141
    affil->div = StringSave (str);   
 
10142
  }
 
10143
  else if (field_to_set == PUB_FIELD_ADDRESS)
 
10144
  {
 
10145
    affil->street = MemFree (affil->street);
 
10146
    affil->street = StringSave (str);       
 
10147
  }
 
10148
  else if (field_to_set == PUB_FIELD_CITY)
 
10149
  {
 
10150
    affil->city = MemFree (affil->city);
 
10151
    affil->city = StringSave (str);       
 
10152
  }
 
10153
  else if (field_to_set == PUB_FIELD_STATE)
 
10154
  {
 
10155
    affil->sub = MemFree (affil->sub);
 
10156
    affil->sub = StringSave (str);       
 
10157
  }
 
10158
  else if (field_to_set == PUB_FIELD_COUNTRY)
 
10159
  {
 
10160
    affil->country = MemFree (affil->country);
 
10161
    affil->country = StringSave (str);       
 
10162
  }
 
10163
  else if (field_to_set == PUB_FIELD_ZIP)
 
10164
  {
 
10165
    affil->postal_code = MemFree (affil->postal_code);
 
10166
    affil->postal_code = StringSave (str);       
 
10167
  }
 
10168
  else if (field_to_set == PUB_FIELD_EMAIL)
 
10169
  {
 
10170
    affil->email = MemFree (affil->email);
 
10171
    affil->email = StringSave (str);       
 
10172
  }
 
10173
  else if (field_to_set == PUB_FIELD_PHONE)
 
10174
  {
 
10175
    affil->phone = MemFree (affil->phone);
 
10176
    affil->phone = StringSave (str);       
 
10177
  }
 
10178
  else if (field_to_set == PUB_FIELD_FAX)
 
10179
  {
 
10180
    affil->fax = MemFree (affil->fax);
 
10181
    affil->fax = StringSave (str);       
 
10182
  }
 
10183
  return affil;
 
10184
}
 
10185
 
 
10186
 
 
10187
static CharPtr GetSampleStringFromPub (PubdescPtr pdp, Int4 field_num)
 
10188
{
 
10189
  PubPtr       pub;
 
10190
  CharPtr      retp = NULL;
 
10191
  
 
10192
  if (pdp == NULL || pdp->pub == NULL || field_num == PUB_FIELD_ANY)
 
10193
  {
 
10194
    return NULL;
 
10195
  }
 
10196
  
 
10197
  for (pub = pdp->pub; pub != NULL && retp == NULL; pub = pub->next)
 
10198
  {
 
10199
    switch (field_num)
 
10200
    {
 
10201
      case PUB_FIELD_TITLE:
 
10202
        retp = GetPubTitleSample (pub);
 
10203
        break;
 
10204
      case PUB_FIELD_FIRST_NAME:
 
10205
      case PUB_FIELD_MIDDLE_INITIAL:
 
10206
      case PUB_FIELD_LAST_NAME:
 
10207
      case PUB_FIELD_SUFFIX:
 
10208
      case PUB_FIELD_CONSORTIUM:
 
10209
        retp = GetAuthorListFieldSample (pub, field_num);
 
10210
        break;
 
10211
      case PUB_FIELD_INSTITUTION:
 
10212
      case PUB_FIELD_DEPARTMENT:
 
10213
      case PUB_FIELD_ADDRESS:
 
10214
      case PUB_FIELD_CITY:
 
10215
      case PUB_FIELD_STATE:
 
10216
      case PUB_FIELD_COUNTRY:
 
10217
      case PUB_FIELD_ZIP:
 
10218
      case PUB_FIELD_EMAIL:
 
10219
      case PUB_FIELD_PHONE:
 
10220
      case PUB_FIELD_FAX:
 
10221
        retp = GetAffiliationFieldSample (pub, field_num);
 
10222
        break;
 
10223
    }
 
10224
    if (StringHasNoText (retp))
 
10225
    {
 
10226
      retp = NULL;
 
10227
    } 
 
10228
  }
 
10229
  return retp;
 
10230
}
 
10231
 
 
10232
 
 
10233
static Int4 GetPubStatus (PubPtr the_pub)
 
10234
{
 
10235
  CitGenPtr  cgp;
 
10236
  CitSubPtr  csp;
 
10237
  CitArtPtr  cap;
 
10238
  CitBookPtr cbp;
 
10239
  CitJourPtr cjp;
 
10240
  ImprintPtr imp = NULL;
 
10241
  Int4       status = PUB_STAT_ANY;
 
10242
  
 
10243
  if (the_pub == NULL || the_pub->data.ptrvalue == NULL)
 
10244
  {
 
10245
    return PUB_STAT_ANY;
 
10246
  }
 
10247
  
 
10248
  switch (the_pub->choice)
 
10249
  {
 
10250
    case PUB_Gen :
 
10251
      cgp = (CitGenPtr) the_pub->data.ptrvalue;
 
10252
      if (cgp->cit != NULL && StringICmp (cgp->cit, "unpublished") == 0)
 
10253
      {
 
10254
        status = PUB_STAT_UNPUBLISHED;
 
10255
      }
 
10256
      else
 
10257
      {
 
10258
        status = PUB_STAT_PUBLISHED;
 
10259
      }
 
10260
      break;
 
10261
    case PUB_Sub :
 
10262
      csp = (CitSubPtr) the_pub->data.ptrvalue;
 
10263
      status = PUB_STAT_PUBLISHED_SUBMISSION;
 
10264
      break;
 
10265
    case PUB_Article :
 
10266
      cap = (CitArtPtr) the_pub->data.ptrvalue;
 
10267
      if (cap->from == 1)
 
10268
      {
 
10269
        cjp = (CitJourPtr) cap->fromptr;
 
10270
        if (cjp != NULL)
 
10271
        {
 
10272
          imp = cjp->imp;
 
10273
        }
 
10274
      }
 
10275
      else if (cap->from == 2 || cap->from == 3)
 
10276
      {
 
10277
        cbp = (CitBookPtr) the_pub->data.ptrvalue;
 
10278
        if (cbp != NULL)
 
10279
        {
 
10280
          imp = cbp->imp;
 
10281
        }
 
10282
      }
 
10283
      break;
 
10284
    case PUB_Journal :
 
10285
      cjp = (CitJourPtr) the_pub->data.ptrvalue;
 
10286
      imp = cjp->imp;
 
10287
    case PUB_Book :
 
10288
    case PUB_Man :
 
10289
      cbp = (CitBookPtr) the_pub->data.ptrvalue;
 
10290
      imp = cbp->imp;
 
10291
      break;
 
10292
    case PUB_Patent :
 
10293
      status = PUB_STAT_PUBLISHED;
 
10294
      break;
 
10295
    default :
 
10296
      break;
 
10297
    
 
10298
  }
 
10299
  if (imp != NULL)
 
10300
  {
 
10301
    if (imp->prepub == 0)
 
10302
    {
 
10303
      status = PUB_STAT_PUBLISHED;
 
10304
    }
 
10305
    else if (imp->prepub == 2)
 
10306
    {
 
10307
      status = PUB_STAT_INPRESS;
 
10308
    }
 
10309
    else if (imp->prepub == 1 && the_pub->choice == PUB_Sub)
 
10310
    {
 
10311
      status = PUB_STAT_PUBLISHED_SUBMISSION;
 
10312
    }
 
10313
    else
 
10314
    {
 
10315
      status = PUB_STAT_UNPUBLISHED;
 
10316
    }
 
10317
    
 
10318
  }
 
10319
  return status;
 
10320
}
 
10321
 
 
10322
 
 
10323
/* The PubConstraintData structure is used by all of the global publication editing
 
10324
 * code to determine which publications to apply the requested changes to.
 
10325
 */
 
10326
typedef struct pubconstraint
 
10327
{
 
10328
  CharPtr find_str;
 
10329
  Int4    field_for_find;
 
10330
  Boolean insensitive_to_case;
 
10331
  Int4    pub_status;
 
10332
  TexT    find_str_txt;
 
10333
  ButtoN  insensitive_to_case_btn;
 
10334
  PopuP   field_for_find_popup;
 
10335
  PopuP   pub_status_popup;
 
10336
} PubConstraintData, PNTR PubConstraintPtr;
 
10337
 
 
10338
static PubConstraintPtr PubConstraintNew (void)
 
10339
{
 
10340
  PubConstraintPtr p;
 
10341
  
 
10342
  p = (PubConstraintPtr) MemNew (sizeof (PubConstraintData));
 
10343
  if (p != NULL)
 
10344
  {
 
10345
    p->find_str = NULL;
 
10346
    p->field_for_find = 0;
 
10347
    p->insensitive_to_case = FALSE;
 
10348
    p->pub_status = 0;
 
10349
    p->find_str_txt = NULL;
 
10350
    p->insensitive_to_case_btn = NULL;
 
10351
    p->field_for_find_popup = NULL;
 
10352
    p->pub_status_popup = NULL;
 
10353
  }
 
10354
  return p;
 
10355
}
 
10356
 
 
10357
static PubConstraintPtr PubConstraintFree (PubConstraintPtr p)
 
10358
{
 
10359
  if (p != NULL)
 
10360
  {
 
10361
    p->find_str = MemFree (p->find_str);
 
10362
    p = MemFree (p);
 
10363
  }
 
10364
  return p;
 
10365
}
 
10366
 
 
10367
static void LoadConstraintFromSelectedPub (ButtoN b)
 
10368
{
 
10369
  PubConstraintPtr  p;
 
10370
  SelStructPtr      ssp;
 
10371
  SeqMgrFeatContext fcontext;
 
10372
  SeqMgrDescContext dcontext;
 
10373
  PubdescPtr        pdp = NULL;
 
10374
  SeqFeatPtr        sfp;
 
10375
  SeqDescPtr        sdp;
 
10376
  CharPtr           field_val = NULL;
 
10377
  UIEnum            val;
 
10378
  Int4              field_num = PUB_FIELD_ANY;
 
10379
  
 
10380
  p = (PubConstraintPtr) GetObjectExtra (b);
 
10381
  if (p == NULL) return;
 
10382
  
 
10383
  if (GetEnumPopup (p->field_for_find_popup, pub_field_alist, &val)) 
 
10384
  {
 
10385
    field_num = val;
 
10386
  }
 
10387
 
 
10388
  if (field_num == PUB_FIELD_ANY) return;
 
10389
 
 
10390
  ssp  = ObjMgrGetSelected();
 
10391
 
 
10392
  while (NULL != ssp && field_val == NULL) 
 
10393
  {
 
10394
    if (ssp->itemtype == OBJ_SEQFEAT)
 
10395
    {
 
10396
      sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &fcontext);
 
10397
      if (sfp != NULL && sfp->data.choice == SEQFEAT_PUB)
 
10398
      {
 
10399
        pdp = sfp->data.value.ptrvalue;
 
10400
        field_val = GetSampleStringFromPub (pdp, field_num);
 
10401
      }
 
10402
    }
 
10403
    else if (ssp->itemtype == OBJ_SEQDESC)
 
10404
    {
 
10405
      sdp = SeqMgrGetDesiredDescriptor (ssp->entityID, NULL, ssp->itemID, 0, NULL, &dcontext);
 
10406
      if (sdp != NULL && sdp->choice == Seq_descr_pub)
 
10407
      {
 
10408
        pdp = sdp->data.ptrvalue;
 
10409
        field_val = GetSampleStringFromPub (pdp, field_num);
 
10410
      }
 
10411
    }
 
10412
    ssp = ssp->next;
 
10413
  }
 
10414
  
 
10415
  SetTitle (p->find_str_txt, field_val);
 
10416
}
 
10417
 
 
10418
/* This function creates the controls used for gathering the information 
 
10419
 * from the user for the PubConstraint.
 
10420
 */
 
10421
static void CreatePubConstraintControls (GrouP h, PubConstraintPtr p)
 
10422
{
 
10423
  GrouP  g, k1, k2, k3;
 
10424
  ButtoN b;
 
10425
  
 
10426
  if (h == NULL || p == NULL) return;
 
10427
  
 
10428
  g = HiddenGroup (h, -1, 0, NULL);
 
10429
  k1 = HiddenGroup (g, 5, 0, NULL);
 
10430
  StaticPrompt (k1, "Where", 0, dialogTextHeight, programFont, 'c');
 
10431
  p->find_str_txt = DialogText (k1, "", 15, NULL);
 
10432
  StaticPrompt (k1, "occurs in", 0, dialogTextHeight, programFont, 'c');
 
10433
  p->field_for_find_popup = PopupList (k1, TRUE, NULL);
 
10434
  InitEnumPopup (p->field_for_find_popup, pub_field_alist, NULL);
 
10435
  SetEnumPopup (p->field_for_find_popup, pub_field_alist, PUB_FIELD_ANY);
 
10436
  k2 = HiddenGroup (g, 2, 0, NULL);
 
10437
  p->insensitive_to_case_btn = CheckBox (k2, "Ignore case", NULL);
 
10438
  b = PushButton (k2, "Load Constraint Value From Selected Publication", LoadConstraintFromSelectedPub);
 
10439
  SetObjectExtra (b, p, NULL);
 
10440
  k3 = HiddenGroup (g, 2, 0, NULL);
 
10441
  StaticPrompt (k3, "Publication Status", 0, dialogTextHeight, programFont, 'c');
 
10442
  p->pub_status_popup = PopupList (k3, TRUE, NULL);
 
10443
  InitEnumPopup (p->pub_status_popup, pub_stat_alist, NULL);
 
10444
  SetEnumPopup (p->pub_status_popup, pub_stat_alist, 0);
 
10445
 
 
10446
  AlignObjects (ALIGN_CENTER, (HANDLE) k1, (HANDLE) k2, (HANDLE) k3, NULL);   
 
10447
}
 
10448
 
 
10449
/* This function reads values from the PubConstraint controls. */
 
10450
static void PopulatePubConstraint (PubConstraintPtr p)
 
10451
{
 
10452
  UIEnum         val;
 
10453
 
 
10454
  if (p == NULL) return;
 
10455
  
 
10456
  p->find_str = MemFree (p->find_str);
 
10457
  p->find_str = SaveStringFromText (p->find_str_txt);
 
10458
  if (StringHasNoText (p->find_str))
 
10459
  {
 
10460
    p->find_str = MemFree (p->find_str);
 
10461
  }
 
10462
  if (GetEnumPopup (p->field_for_find_popup, pub_field_alist, &val)) 
 
10463
  {
 
10464
    p->field_for_find = val;
 
10465
  }
 
10466
  p->insensitive_to_case = GetStatus (p->insensitive_to_case_btn);
 
10467
  if (GetEnumPopup (p->pub_status_popup, pub_field_alist, &val)) 
 
10468
  {
 
10469
    p->pub_status = val;
 
10470
  }
 
10471
}
 
10472
 
 
10473
/* The following functions are used to determine whether a particular section of a
 
10474
 * publication matches the value specified in the PubConstraint.
 
10475
 */
 
10476
static Boolean DoesPubTitleMatchConstraint (PubPtr the_pub, PubConstraintPtr p)
 
10477
{
 
10478
  CitGenPtr  cgp;
 
10479
  CitArtPtr  cap;
 
10480
  CitBookPtr cbp;
 
10481
  CitPatPtr  cpp;
 
10482
  Boolean    rval = FALSE;
 
10483
  CharPtr    title;
 
10484
  
 
10485
  if (the_pub == NULL || p == NULL || the_pub->data.ptrvalue == NULL)
 
10486
  {
 
10487
    return FALSE;    
 
10488
  }
 
10489
  if (p->find_str == NULL) return TRUE;
 
10490
  
 
10491
  switch (the_pub->choice) {
 
10492
    case PUB_Gen :
 
10493
      cgp = (CitGenPtr) the_pub->data.ptrvalue;
 
10494
      if ((p->insensitive_to_case 
 
10495
           && StringISearch (cgp->title, p->find_str) != NULL)
 
10496
          || StringSearch (cgp->title, p->find_str) != NULL)
 
10497
      {
 
10498
        rval = TRUE;
 
10499
      }
 
10500
      break;
 
10501
    case PUB_Sub :
 
10502
      break;
 
10503
    case PUB_Article :
 
10504
      cap = (CitArtPtr) the_pub->data.ptrvalue;
 
10505
      if(cap->title != NULL) 
 
10506
      {
 
10507
        title = (CharPtr) (cap->title->data.ptrvalue);
 
10508
        if ((p->insensitive_to_case 
 
10509
             && StringISearch (title, p->find_str) != NULL)
 
10510
            || StringSearch (title, p->find_str) != NULL)
 
10511
        {
 
10512
          rval = TRUE;
 
10513
        }
 
10514
      }
 
10515
      break;
 
10516
    case PUB_Book :
 
10517
    case PUB_Man :
 
10518
      cbp = (CitBookPtr) the_pub->data.ptrvalue;
 
10519
      if(cbp->title != NULL) {
 
10520
        title = (CharPtr) (cbp->title->data.ptrvalue);
 
10521
        if ((p->insensitive_to_case 
 
10522
             && StringISearch (title, p->find_str) != NULL)
 
10523
            || StringSearch (title, p->find_str) != NULL)
 
10524
        {
 
10525
          rval = TRUE;
 
10526
        }
 
10527
      }
 
10528
      break;
 
10529
    case PUB_Patent :
 
10530
      cpp = (CitPatPtr) the_pub->data.ptrvalue;
 
10531
      if ((p->insensitive_to_case 
 
10532
           && StringISearch (cpp->title, p->find_str) != NULL)
 
10533
          || StringSearch (cpp->title, p->find_str) != NULL)
 
10534
      {
 
10535
        rval = TRUE;
 
10536
      }
 
10537
      break;
 
10538
    default :
 
10539
      break;
 
10540
  }
 
10541
  
 
10542
  return rval;
 
10543
}
 
10544
 
 
10545
static Boolean DoesAffiliationMatchString (AffilPtr ap, PubConstraintPtr p)
 
10546
 
10547
  Boolean rval = FALSE;
 
10548
  
 
10549
  if (ap == NULL || p == NULL) return FALSE;
 
10550
  
 
10551
  if (p->find_str == NULL) return TRUE;
 
10552
  
 
10553
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_INSTITUTION)
 
10554
      && ((p->insensitive_to_case && StringISearch (ap->affil, p->find_str) != NULL)
 
10555
        || StringSearch (ap->affil, p->find_str) != NULL))
 
10556
  {
 
10557
    rval = TRUE;
 
10558
  }
 
10559
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_DEPARTMENT)
 
10560
      && ((p->insensitive_to_case && StringISearch (ap->div, p->find_str) != NULL)
 
10561
        || StringSearch (ap->div, p->find_str) != NULL))
 
10562
  {
 
10563
    rval = TRUE;
 
10564
  }
 
10565
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_ADDRESS)
 
10566
      && ((p->insensitive_to_case && StringISearch (ap->street, p->find_str) != NULL)
 
10567
        || StringSearch (ap->street, p->find_str) != NULL))
 
10568
  {
 
10569
    rval = TRUE;
 
10570
  }
 
10571
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_CITY)
 
10572
      && ((p->insensitive_to_case && StringISearch (ap->city, p->find_str) != NULL)
 
10573
        || StringSearch (ap->city, p->find_str) != NULL))
 
10574
  {
 
10575
    rval = TRUE;
 
10576
  }
 
10577
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_STATE)
 
10578
      && ((p->insensitive_to_case && StringISearch (ap->sub, p->find_str) != NULL)
 
10579
        || StringSearch (ap->sub, p->find_str) != NULL))
 
10580
  {
 
10581
    rval = TRUE;
 
10582
  }
 
10583
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_COUNTRY)
 
10584
      && ((p->insensitive_to_case && StringISearch (ap->country, p->find_str) != NULL)
 
10585
        || StringSearch (ap->country, p->find_str) != NULL))
 
10586
  {
 
10587
    rval = TRUE;
 
10588
  }
 
10589
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_EMAIL)
 
10590
      && ((p->insensitive_to_case && StringISearch (ap->email, p->find_str) != NULL)
 
10591
        || StringSearch (ap->email, p->find_str) != NULL))
 
10592
  {
 
10593
    rval = TRUE;
 
10594
  }
 
10595
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_ZIP)
 
10596
      && ((p->insensitive_to_case && StringISearch (ap->postal_code, p->find_str) != NULL)
 
10597
        || StringSearch (ap->postal_code, p->find_str) != NULL))
 
10598
  {
 
10599
    rval = TRUE;
 
10600
  }
 
10601
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_PHONE)
 
10602
      && ((p->insensitive_to_case && StringISearch (ap->phone, p->find_str) != NULL)
 
10603
        || StringSearch (ap->phone, p->find_str) != NULL))
 
10604
  {
 
10605
    rval = TRUE;
 
10606
  }
 
10607
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_FAX)
 
10608
      && ((p->insensitive_to_case && StringISearch (ap->fax, p->find_str) != NULL)
 
10609
        || StringSearch (ap->fax, p->find_str) != NULL))
 
10610
  {
 
10611
    rval = TRUE;
 
10612
  }
 
10613
  return rval;  
 
10614
}
 
10615
 
 
10616
 
 
10617
static Boolean DoesOneAuthorMatchString (AuthorPtr ap, PubConstraintPtr p)
 
10618
{
 
10619
  Boolean rval = FALSE;
 
10620
  NameStdPtr pNameStandard = NULL;
 
10621
  
 
10622
  if (ap == NULL || p == NULL) return FALSE;
 
10623
  if (p->find_str == NULL) return TRUE;
 
10624
  
 
10625
  if (ap->name->choice == 2)
 
10626
  {
 
10627
    pNameStandard = (NameStdPtr) ap->name->data;
 
10628
    if (((p->field_for_find == PUB_FIELD_ANY
 
10629
         || p->field_for_find == PUB_FIELD_FIRST_NAME))
 
10630
        && ((p->insensitive_to_case && StringISearch (pNameStandard->names[1], p->find_str) != NULL)
 
10631
          || StringSearch (pNameStandard->names[1], p->find_str) != NULL))
 
10632
    {
 
10633
      rval = TRUE;
 
10634
    }
 
10635
    if (((p->field_for_find == PUB_FIELD_ANY
 
10636
       || p->field_for_find == PUB_FIELD_LAST_NAME))
 
10637
        && ((p->insensitive_to_case && StringISearch (pNameStandard->names[0], p->find_str) != NULL)
 
10638
          || StringSearch (pNameStandard->names[0], p->find_str) != NULL))
 
10639
    {
 
10640
      rval = TRUE;
 
10641
    }
 
10642
    if (((p->field_for_find == PUB_FIELD_ANY
 
10643
        || p->field_for_find == PUB_FIELD_MIDDLE_INITIAL))
 
10644
         && ((p->insensitive_to_case && StringISearch (pNameStandard->names[2], p->find_str) != NULL)
 
10645
          || StringSearch (pNameStandard->names[2], p->find_str) != NULL))
 
10646
    {
 
10647
      rval = TRUE;
 
10648
    }
 
10649
    if (((p->field_for_find == PUB_FIELD_ANY
 
10650
        || p->field_for_find == PUB_FIELD_SUFFIX))
 
10651
         && ((p->insensitive_to_case && StringICmp (pNameStandard->names[5], p->find_str) == 0)
 
10652
          || StringCmp (pNameStandard->names[5], p->find_str) == 0))
 
10653
    {
 
10654
      rval = TRUE;
 
10655
    }
 
10656
  }
 
10657
  if (ap->name->choice == 5
 
10658
      && (p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_CONSORTIUM)
 
10659
      && ((p->insensitive_to_case && StringISearch (ap->name->data, p->find_str) != NULL)
 
10660
        || StringSearch (ap->name->data, p->find_str) != NULL))
 
10661
  {
 
10662
    rval = TRUE;
 
10663
  }
 
10664
  
 
10665
  return rval;
 
10666
}
 
10667
 
 
10668
 
 
10669
static Boolean DoesAuthorListMatchConstraint (AuthListPtr alp, PubConstraintPtr p)
 
10670
{  
 
10671
  Boolean    rval = FALSE;
 
10672
  ValNodePtr    names;
 
10673
  AuthorPtr   ap;
 
10674
  
 
10675
  if (alp == NULL || p == NULL)
 
10676
  {
 
10677
    return FALSE;    
 
10678
  }
 
10679
  if (p->find_str == NULL) return TRUE;
 
10680
  
 
10681
  for (names = alp->names; names != NULL && !rval; names = names->next) 
 
10682
  { 
 
10683
    ap = names->data.ptrvalue;
 
10684
    rval = DoesOneAuthorMatchString (ap, p);  
 
10685
  }
 
10686
  
 
10687
  return rval;
 
10688
}
 
10689
 
 
10690
 
 
10691
static Boolean DoesPubMatchConstraint (PubPtr the_pub, PubConstraintPtr p)
 
10692
{
 
10693
  Boolean     rval = FALSE;
 
10694
  AuthListPtr alp;
 
10695
  
 
10696
  if (the_pub == NULL || p == NULL) return FALSE;
 
10697
 
 
10698
  if (p->pub_status != PUB_STAT_ANY && p->pub_status != GetPubStatus (the_pub))
 
10699
  {
 
10700
    return FALSE;
 
10701
  }
 
10702
  if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_TITLE)
 
10703
      && DoesPubTitleMatchConstraint (the_pub, p))
 
10704
  {
 
10705
    rval = TRUE; 
 
10706
  }
 
10707
  if (!rval)
 
10708
  {
 
10709
    alp = GetAuthorListForPub (the_pub);
 
10710
    if (alp != NULL)
 
10711
    {
 
10712
      rval = DoesAuthorListMatchConstraint (alp, p);
 
10713
      if (!rval && DoesAffiliationMatchString (alp->affil, p))
 
10714
      {
 
10715
        rval = TRUE;
 
10716
      }
 
10717
    }
 
10718
  }
 
10719
  return rval;
 
10720
}
 
10721
 
 
10722
 
 
10723
/* This structure is used for the Edit Publications dialog.
 
10724
 * It contains a PubConstraint plus the necessary controls
 
10725
 * to collect user input for editing a single field,
 
10726
 * replacing a publication section, or merging author lists.
 
10727
 */
 
10728
typedef struct EditPubform
 
10729
{
 
10730
  FORM_MESSAGE_BLOCK
 
10731
  
 
10732
  PubConstraintData pcd;
 
10733
  ButtoN            leaveDlgUp;
 
10734
  
 
10735
  /* used for single field replace */
 
10736
  TexT              repl_string_txt;
 
10737
  PopuP             field_to_set_popup;
 
10738
  CharPtr           repl_string;
 
10739
  Int4              field_to_set;
 
10740
  
 
10741
  /* used for replacing publication section */
 
10742
  ButtoN            replace_author_list;
 
10743
  ButtoN            replace_title;
 
10744
  ButtoN            replace_affiliation; 
 
10745
  PubdescPtr        pdp;
 
10746
  AuthListPtr       alp;
 
10747
  CharPtr           title_str;
 
10748
  AffilPtr          affil;
 
10749
 
 
10750
  /* used for author list merge */
 
10751
  ValNodePtr        names_list;  
 
10752
  
 
10753
  GrouP             edit_type_group;
 
10754
  Int4              edit_type;
 
10755
  GrouP             single_field_group;
 
10756
  GrouP             replace_sect_group;
 
10757
  GrouP             merge_auth_list_group;
 
10758
  ButtoN            specify_author_order;
 
10759
 
 
10760
} EditPubFormData, PNTR EditPubFormPtr;
 
10761
 
 
10762
 
 
10763
typedef void (LIBCALLBACK *operateOnPubFunction) (
 
10764
  PubPtr pub,
 
10765
  EditPubFormPtr epfp
 
10766
);
 
10767
 
 
10768
typedef struct operatepub
 
10769
{
 
10770
  operateOnPubFunction op_pub;
 
10771
  EditPubFormPtr       epfp;
 
10772
} OperatePubData, PNTR OperatePubPtr;
 
10773
 
 
10774
static void OperateOnPubFeatureCallback (SeqFeatPtr sfp, Pointer userdata)
 
10775
{
 
10776
  OperatePubPtr       opp;
 
10777
  PubPtr              pub;
 
10778
  PubdescPtr          pdp;
 
10779
  
 
10780
  if (sfp == NULL || sfp->data.choice != SEQFEAT_PUB || userdata == NULL)
 
10781
  {
 
10782
    return;
 
10783
  }
 
10784
  opp = (OperatePubPtr) userdata;
 
10785
  if (opp->op_pub == NULL || opp->epfp == NULL) return;
 
10786
  pdp = (PubdescPtr) sfp->data.value.ptrvalue;
 
10787
  if (pdp == NULL) return;
 
10788
  for (pub = pdp->pub; pub != NULL; pub = pub->next)
 
10789
  {
 
10790
    opp->op_pub (pub, opp->epfp);
 
10791
  }
 
10792
}
 
10793
 
 
10794
static void OperateOnPubDescriptorCallback (SeqDescPtr sdp, Pointer userdata)
 
10795
{
 
10796
  OperatePubPtr       opp;
 
10797
  PubPtr              pub;
 
10798
  PubdescPtr          pdp;
 
10799
  
 
10800
  if (sdp == NULL || sdp->choice != Seq_descr_pub || userdata == NULL)
 
10801
  {
 
10802
    return;
 
10803
  }
 
10804
  opp = (OperatePubPtr) userdata;
 
10805
  if (opp->op_pub == NULL || opp->epfp == NULL) return;
 
10806
  pdp = (PubdescPtr) sdp->data.ptrvalue;
 
10807
  if (pdp == NULL) return;
 
10808
  for (pub = pdp->pub; pub != NULL; pub = pub->next)
 
10809
  {
 
10810
    opp->op_pub (pub, opp->epfp);
 
10811
  }
 
10812
}
 
10813
 
 
10814
 
 
10815
static void OperateOnPubByConstraint (SeqEntryPtr sep, EditPubFormPtr epfp, operateOnPubFunction op_pub)
 
10816
{
 
10817
  OperatePubData opd;
 
10818
  
 
10819
  if (sep == NULL || epfp == NULL || op_pub == NULL) return;
 
10820
  opd.epfp = epfp;
 
10821
  opd.op_pub = op_pub;
 
10822
  
 
10823
  VisitFeaturesInSep (sep, &opd, OperateOnPubFeatureCallback);
 
10824
  VisitDescriptorsInSep (sep, &opd, OperateOnPubDescriptorCallback);
 
10825
  
 
10826
}
 
10827
 
 
10828
/* The following code is used for setting the value of a single field
 
10829
 * in a publication.
 
10830
 */
 
10831
static void SetFieldByConstraint 
 
10832
(PubPtr pdp,
 
10833
 PubConstraintPtr p,
 
10834
 Int4 field_to_set,
 
10835
 CharPtr str)
 
10836
{
 
10837
  ValNodePtr  names;
 
10838
  AuthListPtr alp;
 
10839
  
 
10840
  if (pdp == NULL || p == NULL || 
 
10841
      (p->pub_status != PUB_STAT_ANY && p->pub_status != GetPubStatus (pdp)))
 
10842
  {
 
10843
    return;
 
10844
  }
 
10845
 
 
10846
  if (field_to_set == PUB_FIELD_TITLE)
 
10847
  {
 
10848
    if (DoesPubMatchConstraint (pdp, p))
 
10849
    {
 
10850
      SetPubTitle (pdp, str);
 
10851
    }
 
10852
  }
 
10853
  else if (field_to_set >= PUB_FIELD_FIRST_NAME
 
10854
           && field_to_set <= PUB_FIELD_CONSORTIUM)
 
10855
  {
 
10856
    alp = GetAuthorListForPub (pdp);
 
10857
    if (alp == NULL)
 
10858
    {
 
10859
      alp = AuthListNew ();
 
10860
      if (! SetPubAuthorList (pdp, alp))
 
10861
      {
 
10862
        MemFree (alp);
 
10863
        return;
 
10864
      }
 
10865
    }
 
10866
    if ((p->field_for_find == PUB_FIELD_TITLE && DoesPubTitleMatchConstraint (pdp, p))
 
10867
      || (p->field_for_find >= PUB_FIELD_INSTITUTION && p->field_for_find <= PUB_FIELD_FAX
 
10868
          && DoesAffiliationMatchString (alp->affil, p)))
 
10869
    {
 
10870
      for (names = alp->names; names != NULL; names = names->next) 
 
10871
      { 
 
10872
        SetAuthorString (names->data.ptrvalue, field_to_set, str);
 
10873
      }
 
10874
    }
 
10875
    else if (p->field_for_find >= PUB_FIELD_FIRST_NAME
 
10876
             && p->field_for_find <= PUB_FIELD_CONSORTIUM)
 
10877
    {
 
10878
      for (names = alp->names; names != NULL; names = names->next) 
 
10879
      { 
 
10880
        if (DoesOneAuthorMatchString (names->data.ptrvalue, p))
 
10881
        {
 
10882
          SetAuthorString (names->data.ptrvalue, field_to_set, str);            
 
10883
        }
 
10884
      }
 
10885
    }
 
10886
  }
 
10887
  else if (field_to_set >= PUB_FIELD_INSTITUTION
 
10888
           && field_to_set <= PUB_FIELD_FAX
 
10889
           )
 
10890
  {
 
10891
    alp = GetAuthorListForPub (pdp);
 
10892
    if (alp == NULL)
 
10893
    {
 
10894
      alp = AuthListNew ();
 
10895
      if (! SetPubAuthorList (pdp, alp))
 
10896
      {
 
10897
        MemFree (alp);
 
10898
        return;
 
10899
      }
 
10900
    }
 
10901
    if (DoesPubMatchConstraint (pdp, p))
 
10902
    {
 
10903
      alp->affil = SetAffilString (alp->affil, field_to_set, str);
 
10904
    }
 
10905
  }
 
10906
}
 
10907
 
 
10908
static void LIBCALLBACK EditPubSingleField (PubPtr pub, EditPubFormPtr epfp)
 
10909
{
 
10910
  if (pub == NULL || epfp == NULL) return;
 
10911
 
 
10912
  SetFieldByConstraint (pub, &(epfp->pcd), epfp->field_to_set, epfp->repl_string);
 
10913
}
 
10914
 
 
10915
 
 
10916
/* this code is used for replacing pub sections */
 
10917
static void LIBCALLBACK ReplacePubSectByConstraint (PubPtr pub, EditPubFormPtr epfp)
 
10918
{
 
10919
  AuthListPtr alp;
 
10920
  
 
10921
  if (pub == NULL || epfp == NULL)
 
10922
  {
 
10923
    return;
 
10924
  }
 
10925
  if (DoesPubMatchConstraint (pub, &(epfp->pcd)))
 
10926
  {
 
10927
    if (epfp->alp != NULL)
 
10928
    {
 
10929
      alp = AsnIoMemCopy ((Pointer) epfp->alp,
 
10930
                    (AsnReadFunc) AuthListAsnRead,
 
10931
                    (AsnWriteFunc) AuthListAsnWrite);
 
10932
      if (alp != NULL)
 
10933
      {
 
10934
        SetPubAuthorList (pub, alp);      
 
10935
      }
 
10936
    }
 
10937
    if (epfp->title_str != NULL)
 
10938
    {
 
10939
      SetPubTitle (pub, epfp->title_str);
 
10940
    }
 
10941
    if (epfp->affil != NULL)
 
10942
    {
 
10943
      alp = GetAuthorListForPub (pub);
 
10944
      if (alp != NULL)
 
10945
      {
 
10946
        alp->affil = AffilFree (alp->affil);
 
10947
        alp->affil = AsnIoMemCopy ((Pointer) epfp->affil,
 
10948
                         (AsnReadFunc) AffilAsnRead,
 
10949
                         (AsnWriteFunc) AffilAsnWrite);
 
10950
      }
 
10951
    }
 
10952
  }
 
10953
}
 
10954
 
 
10955
 
 
10956
/* this code is used for merging author lists */
 
10957
static Boolean AreAuthorNamesIdentical (AuthorPtr ap1, AuthorPtr ap2)
 
10958
{
 
10959
  NameStdPtr   pNameStandard1, pNameStandard2;
 
10960
  CharPtr      n1, n2;
 
10961
  Boolean      rval = FALSE;
 
10962
  Int4         idx;
 
10963
  
 
10964
  if (ap1 == NULL || ap2 == NULL) return FALSE;
 
10965
 
 
10966
  if (ap1->name->choice != ap2->name->choice)
 
10967
  {
 
10968
    rval = FALSE;
 
10969
  }
 
10970
  else
 
10971
  {
 
10972
    switch (ap1->name->choice)
 
10973
    {
 
10974
      case 2:
 
10975
        pNameStandard1 = (NameStdPtr) ap1->name->data;
 
10976
        pNameStandard2 = (NameStdPtr) ap2->name->data;
 
10977
        rval = TRUE;
 
10978
        for (idx = 0; idx < 7 && rval; idx++)
 
10979
        {
 
10980
          if (StringHasNoText (pNameStandard1->names[idx]))
 
10981
          {
 
10982
            if (!StringHasNoText (pNameStandard2->names[idx]))
 
10983
            {
 
10984
              rval = FALSE;
 
10985
            }
 
10986
          }
 
10987
          else if (StringHasNoText (pNameStandard2->names[idx]))
 
10988
          {
 
10989
            rval = FALSE;
 
10990
          }
 
10991
          else if (StringCmp (pNameStandard1->names[idx], pNameStandard2->names[idx]) != 0)
 
10992
          {
 
10993
            rval = FALSE;
 
10994
          }
 
10995
        }
 
10996
        break;
 
10997
      case 4:
 
10998
      case 5:
 
10999
        n1 = (CharPtr) ap1->name->data;
 
11000
        n2 = (CharPtr) ap2->name->data;
 
11001
        if (StringCmp (n1, n2) == 0)
 
11002
        {
 
11003
          rval = TRUE;
 
11004
        }
 
11005
        break;
 
11006
    }
 
11007
  }
 
11008
 
 
11009
  return rval;
 
11010
}
 
11011
 
 
11012
static void LIBCALLBACK GetMergedAuthorListByConstraint (PubPtr pub, EditPubFormPtr epfp)
 
11013
{
 
11014
  AuthListPtr alp;
 
11015
  ValNodePtr  name_in_this, name_in_list;
 
11016
  AuthorPtr   ap1, ap2;
 
11017
  Boolean     found_match;
 
11018
  
 
11019
  if (pub == NULL || epfp == NULL)
 
11020
  {
 
11021
    return;
 
11022
  }
 
11023
  if (DoesPubMatchConstraint (pub, &(epfp->pcd)))
 
11024
  {
 
11025
    alp = GetAuthorListForPub (pub);
 
11026
    if (alp != NULL)
 
11027
    {
 
11028
      for (name_in_this = alp->names; name_in_this != NULL; name_in_this = name_in_this->next) 
 
11029
      { 
 
11030
        ap1 = name_in_this->data.ptrvalue;
 
11031
        found_match = FALSE;
 
11032
        for (name_in_list = epfp->names_list; 
 
11033
             name_in_list != NULL && !found_match;
 
11034
             name_in_list = name_in_list->next)
 
11035
        {
 
11036
          ap2 = name_in_list->data.ptrvalue;
 
11037
          if (AreAuthorNamesIdentical (ap1, ap2))
 
11038
          {
 
11039
            found_match = TRUE;
 
11040
          }
 
11041
        }
 
11042
        if (!found_match)
 
11043
        {
 
11044
          ap2 = AsnIoMemCopy ((Pointer) ap1,
 
11045
                    (AsnReadFunc) AuthorAsnRead,
 
11046
                    (AsnWriteFunc) AuthorAsnWrite);
 
11047
          if (ap2 != NULL)
 
11048
          {
 
11049
            ValNodeAddPointer (&(epfp->names_list), name_in_this->choice, ap2);
 
11050
          }
 
11051
        }
 
11052
      }
 
11053
    }
 
11054
  }
 
11055
}
 
11056
 
 
11057
static ValNodePtr FreeAuthorNameList (ValNodePtr names_list)
 
11058
{
 
11059
  ValNodePtr vnp;
 
11060
  
 
11061
  for (vnp = names_list; vnp != NULL; vnp = vnp->next)
 
11062
  {
 
11063
    vnp->data.ptrvalue = AuthorFree (vnp->data.ptrvalue);
 
11064
  }
 
11065
  names_list = ValNodeFree (names_list);
 
11066
  return names_list;
 
11067
}
 
11068
 
 
11069
static void ReplaceNameList (AuthListPtr alp, ValNodePtr new_name_list)
 
11070
{
 
11071
  ValNodePtr  new_name;
 
11072
  AuthorPtr   new_ap;
 
11073
  
 
11074
  if (alp == NULL) return;
 
11075
 
 
11076
  alp->names = FreeAuthorNameList (alp->names);
 
11077
  
 
11078
  for (new_name = new_name_list; new_name != NULL; new_name = new_name->next)
 
11079
  {
 
11080
    new_ap = AsnIoMemCopy (new_name->data.ptrvalue,
 
11081
                    (AsnReadFunc) AuthorAsnRead,
 
11082
                    (AsnWriteFunc) AuthorAsnWrite);
 
11083
    if (new_ap != NULL)
 
11084
    {
 
11085
      ValNodeAddPointer (&(alp->names), new_name->choice, new_ap);
 
11086
    }
 
11087
  }
 
11088
}
 
11089
 
 
11090
static void LIBCALLBACK SetMergedAuthorListByConstraint (PubPtr pub, EditPubFormPtr epfp)
 
11091
{
 
11092
  AuthListPtr alp;
 
11093
  
 
11094
  if (pub == NULL || epfp == NULL)
 
11095
  {
 
11096
    return;
 
11097
  }
 
11098
  if (DoesPubMatchConstraint (pub, &(epfp->pcd)))
 
11099
  {
 
11100
    alp = GetAuthorListForPub (pub);
 
11101
    ReplaceNameList (alp, epfp->names_list);
 
11102
  }
 
11103
}
 
11104
 
 
11105
 
 
11106
static PubdescPtr FindFirstSelectedPub (void)
 
11107
{
 
11108
  SelStructPtr          ssp;
 
11109
  SeqFeatPtr            sfp;
 
11110
  SeqDescrPtr           sdp;
 
11111
  PubdescPtr            pdp = NULL;
 
11112
  SeqMgrFeatContext     fcontext;
 
11113
  SeqMgrDescContext     dcontext;
 
11114
  
 
11115
  
 
11116
  /* find the selected pub */
 
11117
  ssp  = ObjMgrGetSelected();
 
11118
 
 
11119
  while (NULL != ssp && pdp == NULL) 
 
11120
  {
 
11121
    if (ssp->itemtype == OBJ_SEQFEAT)
 
11122
    {
 
11123
      sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &fcontext);
 
11124
      if (sfp != NULL && sfp->data.choice == SEQFEAT_PUB)
 
11125
      {
 
11126
        pdp = sfp->data.value.ptrvalue;
 
11127
      }
 
11128
    }
 
11129
    else if (ssp->itemtype == OBJ_SEQDESC)
 
11130
    {
 
11131
      sdp = SeqMgrGetDesiredDescriptor (ssp->entityID, NULL, ssp->itemID, 0, NULL, &dcontext);
 
11132
      if (sdp != NULL && sdp->choice == Seq_descr_pub)
 
11133
      {
 
11134
        pdp = sdp->data.ptrvalue;
 
11135
      }
 
11136
    }
 
11137
    ssp = ssp->next;
 
11138
  }
 
11139
  return pdp;
 
11140
}
 
11141
 
 
11142
typedef Int4 (LIBCALLBACK *GetItemTextLength) (Pointer userdata);
 
11143
 
 
11144
typedef void (LIBCALLBACK *PrintItemToBuffer) (CharPtr cp, Pointer userdata);
 
11145
 
 
11146
typedef struct doublelist
 
11147
{
 
11148
  WindoW             w;
 
11149
  DoC                list1_ctrl;
 
11150
  DoC                list2_ctrl;
 
11151
  ButtoN             to_button;
 
11152
  ButtoN             from_button;
 
11153
  ButtoN             accept_button;
 
11154
  Boolean            change;
 
11155
  Boolean            done;
 
11156
  Boolean            accepted;  
 
11157
  ValNodePtr         list1;
 
11158
  ValNodePtr         list2;
 
11159
  BoolPtr            list1_clicked;
 
11160
  BoolPtr            list2_clicked;
 
11161
  Int4               num_total;
 
11162
  GetItemTextLength  getlenproc;
 
11163
  PrintItemToBuffer  printitemproc;
 
11164
  Boolean            none_in_1_ok;
 
11165
  Boolean            none_in_2_ok;
 
11166
} DoubleListData, PNTR DoubleListPtr;
 
11167
 
 
11168
static ColData doubleListCol [] = {
 
11169
  {0, 0, 80, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
 
11170
  {0, 0,  0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
 
11171
  {0, 0,  0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
 
11172
  {0, 0,  0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
 
11173
  {0, 0,  0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
 
11174
  {0, 0,  0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
 
11175
  {0, 0,  0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE},
 
11176
  {0, 0,  0, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, TRUE}};
 
11177
 
 
11178
static ParData doubleListPar = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
 
11179
 
 
11180
static CharPtr AllLinePrtProc (DoC d, Int2 item, Pointer ptr)
 
11181
 
 
11182
{
 
11183
  CharPtr  tmp;
 
11184
 
 
11185
  if (ptr != NULL) {
 
11186
    tmp = (CharPtr) ptr;
 
11187
    return StringSave (tmp);
 
11188
  } else {
 
11189
    return NULL;
 
11190
  }
 
11191
}
 
11192
 
 
11193
static CharPtr GetDoubleListTextList (ValNodePtr item_list, DoubleListPtr dlp)
 
11194
{
 
11195
  Int4       text_len = 0;
 
11196
  ValNodePtr vnp;
 
11197
  CharPtr    text_list, cp;
 
11198
  
 
11199
  if (dlp == NULL || dlp->getlenproc == NULL || dlp->printitemproc == NULL)
 
11200
  {
 
11201
    return NULL;
 
11202
  }
 
11203
  for (vnp = item_list; vnp != NULL; vnp = vnp->next)
 
11204
  {
 
11205
    text_len += dlp->getlenproc (vnp->data.ptrvalue);
 
11206
  }
 
11207
  if (text_len == 0) return NULL;
 
11208
  text_list = (CharPtr) MemNew (text_len * sizeof (Char));
 
11209
  if (text_list == NULL) return NULL;
 
11210
  cp = text_list;
 
11211
  for (vnp = item_list; vnp != NULL; vnp = vnp->next)
 
11212
  {
 
11213
    dlp->printitemproc (cp, vnp->data.ptrvalue);
 
11214
    cp += StringLen (cp);
 
11215
  }
 
11216
  return text_list;
 
11217
}
 
11218
 
 
11219
static void ClickList1 (DoC d, PoinT pt)
 
11220
 
 
11221
{
 
11222
  DoubleListPtr  dlp;
 
11223
  Int2           item;
 
11224
  Int2           row;
 
11225
 
 
11226
  dlp = (DoubleListPtr) GetObjectExtra (d);
 
11227
  if (dlp != NULL) {
 
11228
    MapDocPoint (d, pt, &item, &row, NULL, NULL);
 
11229
    if (item > 0 && row > 0) {
 
11230
      dlp->list1_clicked [row - 1] = ! dlp->list1_clicked [row - 1];
 
11231
      InvalDocRows (d, 1, row, row);
 
11232
    }
 
11233
  }
 
11234
}
 
11235
 
 
11236
static void ClickList2 (DoC d, PoinT pt)
 
11237
 
 
11238
{
 
11239
  DoubleListPtr  dlp;
 
11240
  Int2           item;
 
11241
  Int2           row;
 
11242
 
 
11243
  dlp = (DoubleListPtr) GetObjectExtra (d);
 
11244
  if (dlp != NULL) {
 
11245
    MapDocPoint (d, pt, &item, &row, NULL, NULL);
 
11246
    if (item > 0 && row > 0) {
 
11247
      dlp->list2_clicked [row - 1] = ! dlp->list2_clicked [row - 1];
 
11248
      InvalDocRows (d, 1, row, row);
 
11249
    }
 
11250
  }
 
11251
}
 
11252
 
 
11253
 
 
11254
static void ReleaseDoubleListItem (DoC d, PoinT pt)
 
11255
 
 
11256
{
 
11257
  DoubleListPtr  dlp;
 
11258
  Int2           item;
 
11259
  Int2           row;
 
11260
 
 
11261
  dlp = (DoubleListPtr) GetObjectExtra (d);
 
11262
  if (dlp != NULL) {
 
11263
    MapDocPoint (d, pt, &item, &row, NULL, NULL);
 
11264
    if (item > 0 && row > 0) {
 
11265
      ResetClip ();
 
11266
    }
 
11267
  }
 
11268
}
 
11269
 
 
11270
static Boolean HighlightList1 (DoC d, Int2 item, Int2 row, Int2 col)
 
11271
 
 
11272
{
 
11273
  DoubleListPtr  dlp;
 
11274
 
 
11275
  dlp = (DoubleListPtr) GetObjectExtra (d);
 
11276
  if (dlp != NULL) {
 
11277
    return dlp->list1_clicked [row - 1];
 
11278
  } else {
 
11279
    return FALSE;
 
11280
  }
 
11281
}
 
11282
 
 
11283
static Boolean HighlightList2 (DoC d, Int2 item, Int2 row, Int2 col)
 
11284
 
 
11285
{
 
11286
  DoubleListPtr  dlp;
 
11287
 
 
11288
  dlp = (DoubleListPtr) GetObjectExtra (d);
 
11289
  if (dlp != NULL) {
 
11290
    return dlp->list2_clicked [row - 1];
 
11291
  } else {
 
11292
    return FALSE;
 
11293
  }
 
11294
}
 
11295
 
 
11296
static void PopulateDoubleListPanels (DoubleListPtr dlp)
 
11297
{
 
11298
  CharPtr new_text;
 
11299
  Int4    idx;
 
11300
  
 
11301
  if (dlp == NULL) return;
 
11302
 
 
11303
        Reset(dlp->list1_ctrl);
 
11304
  SetDocAutoAdjust (dlp->list1_ctrl, FALSE);
 
11305
  new_text = GetDoubleListTextList (dlp->list1, dlp);
 
11306
  AppendItem (dlp->list1_ctrl, AllLinePrtProc, new_text, FALSE, ValNodeLen (dlp->list1),
 
11307
                &doubleListPar, doubleListCol, programFont);
 
11308
  SetDocAutoAdjust (dlp->list1_ctrl, TRUE);
 
11309
  SetDocProcs (dlp->list1_ctrl, ClickList1, NULL, ReleaseDoubleListItem, NULL);
 
11310
  SetDocShade (dlp->list1_ctrl, NULL, NULL, HighlightList1, NULL);
 
11311
  InvalDocRows (dlp->list1_ctrl, 1, 1, ValNodeLen (dlp->list1));
 
11312
 
 
11313
        Reset(dlp->list2_ctrl);
 
11314
  SetDocAutoAdjust (dlp->list2_ctrl, FALSE);
 
11315
  new_text = GetDoubleListTextList (dlp->list2, dlp);
 
11316
  AppendItem (dlp->list2_ctrl, AllLinePrtProc, new_text, FALSE, ValNodeLen (dlp->list2),
 
11317
                &doubleListPar, doubleListCol, programFont);
 
11318
  SetDocAutoAdjust (dlp->list2_ctrl, TRUE);
 
11319
  SetDocProcs (dlp->list2_ctrl, ClickList2, NULL, ReleaseDoubleListItem, NULL);
 
11320
  SetDocShade (dlp->list2_ctrl, NULL, NULL, HighlightList2, NULL);
 
11321
  InvalDocRows (dlp->list2_ctrl, 1, 1, ValNodeLen (dlp->list2));
 
11322
 
 
11323
  /* clear selections for both lists */
 
11324
  for (idx = 0; idx < dlp->num_total; idx++)
 
11325
  {
 
11326
    dlp->list1_clicked [idx] = FALSE;
 
11327
    dlp->list2_clicked [idx] = FALSE;
 
11328
  }
 
11329
  
 
11330
  if (! dlp->none_in_1_ok && dlp->list1 == NULL)
 
11331
  {
 
11332
    Disable (dlp->accept_button);
 
11333
  }
 
11334
  else if (! dlp->none_in_2_ok && dlp->list2 == NULL)
 
11335
  {
 
11336
    Disable (dlp->accept_button);
 
11337
  }
 
11338
  else
 
11339
  {
 
11340
    Enable (dlp->accept_button);
 
11341
  }
 
11342
  
 
11343
}
 
11344
 
 
11345
static void MoveToList2 (ButtoN b)
 
11346
{
 
11347
  DoubleListPtr  dlp;
 
11348
  ValNodePtr     vnp, prev = NULL, vnp_next;
 
11349
  Int4           idx;
 
11350
 
 
11351
  dlp = (DoubleListPtr) GetObjectExtra (b);
 
11352
  if (dlp != NULL) 
 
11353
  {
 
11354
    for (vnp = dlp->list1, idx = 0;
 
11355
         vnp != NULL && idx < dlp->num_total;
 
11356
         vnp = vnp_next, idx++)
 
11357
    {
 
11358
      vnp_next = vnp->next;
 
11359
      if (dlp->list1_clicked [idx])
 
11360
      {
 
11361
        /* add item to list2 */
 
11362
        ValNodeAddPointer (&dlp->list2, vnp->choice, vnp->data.ptrvalue);
 
11363
        
 
11364
        /* remove item from list1 */
 
11365
        vnp->data.ptrvalue = NULL;
 
11366
        if (prev == NULL)
 
11367
        {
 
11368
          dlp->list1 = vnp->next;
 
11369
        }
 
11370
        else
 
11371
        {
 
11372
          prev->next = vnp->next;
 
11373
        }
 
11374
        vnp->next = NULL;
 
11375
        ValNodeFree (vnp);
 
11376
        
 
11377
      }
 
11378
      else
 
11379
      {
 
11380
        prev = vnp;
 
11381
      }
 
11382
    }
 
11383
  }
 
11384
  /* redraw contents of docpanels */
 
11385
  PopulateDoubleListPanels (dlp);        
 
11386
}
 
11387
 
 
11388
static void MoveToList1 (ButtoN b)
 
11389
{
 
11390
  DoubleListPtr  dlp;
 
11391
  ValNodePtr     vnp, prev = NULL, vnp_next;
 
11392
  Int4           idx;
 
11393
 
 
11394
  dlp = (DoubleListPtr) GetObjectExtra (b);
 
11395
  if (dlp != NULL) 
 
11396
  {
 
11397
    for (vnp = dlp->list2, idx = 0;
 
11398
         vnp != NULL && idx < dlp->num_total;
 
11399
         vnp = vnp_next, idx++)
 
11400
    {
 
11401
      vnp_next = vnp->next;
 
11402
      if (dlp->list2_clicked [idx])
 
11403
      {
 
11404
        /* add item to list2 */
 
11405
        ValNodeAddPointer (&dlp->list1, vnp->choice, vnp->data.ptrvalue);
 
11406
        
 
11407
        /* remove item from list1 */
 
11408
        vnp->data.ptrvalue = NULL;
 
11409
        if (prev == NULL)
 
11410
        {
 
11411
          dlp->list2 = vnp->next;
 
11412
        }
 
11413
        else
 
11414
        {
 
11415
          prev->next = vnp->next;
 
11416
        }
 
11417
        vnp->next = NULL;
 
11418
        ValNodeFree (vnp);
 
11419
        
 
11420
      }
 
11421
      else
 
11422
      {
 
11423
        prev = vnp;
 
11424
      }
 
11425
    }
 
11426
  }
 
11427
  /* redraw contents of docpanels */
 
11428
  PopulateDoubleListPanels (dlp);        
 
11429
 
 
11430
}
 
11431
 
 
11432
static void AcceptDoubleList (ButtoN b)
 
11433
{
 
11434
  DoubleListPtr dlp;
 
11435
 
 
11436
  dlp = (DoubleListPtr) GetObjectExtra (b);
 
11437
  if (dlp == NULL) return;
 
11438
 
 
11439
  dlp->accepted = TRUE;
 
11440
  dlp->done = TRUE;
 
11441
  
 
11442
}
 
11443
 
 
11444
static void CancelDoubleList (ButtoN b)
 
11445
{
 
11446
  DoubleListPtr dlp;
 
11447
 
 
11448
  dlp = (DoubleListPtr) GetObjectExtra (b);
 
11449
  if (dlp == NULL) return;
 
11450
 
 
11451
  dlp->accepted = FALSE;
 
11452
  dlp->done = TRUE;
 
11453
}
 
11454
 
 
11455
static void DrawDoubleListWindow (DoubleListPtr dlp, CharPtr list1_name, CharPtr list2_name)
 
11456
{
 
11457
  GrouP           h, g, k, c;
 
11458
  ButtoN          b;
 
11459
  Int2            height = LineHeight ();
 
11460
    
 
11461
  
 
11462
  if (dlp == NULL) return;
 
11463
  
 
11464
  dlp->w = ModalWindow (-50, -33, -10, -10, NULL);
 
11465
  doubleListCol [0].pixWidth = screenRect.right - screenRect.left;
 
11466
 
 
11467
  h = HiddenGroup (dlp->w, -1, 0, NULL);
 
11468
  SetGroupSpacing (h, 10, 10);
 
11469
  
 
11470
  g = HiddenGroup (h, 3, 0, NULL);
 
11471
  /* top row - labels */
 
11472
  StaticPrompt (g, list1_name, 0, dialogTextHeight, programFont, 'c');
 
11473
  StaticPrompt (g, "", 0, dialogTextHeight, programFont, 'c');
 
11474
  StaticPrompt (g, list2_name, 0, dialogTextHeight, programFont, 'c');
 
11475
  /* panel 1 */
 
11476
  dlp->list1_ctrl = DocumentPanel (g, stdCharWidth * 25, height * 6);
 
11477
  SetObjectExtra (dlp->list1_ctrl, dlp, NULL);
 
11478
  /* movement buttons */
 
11479
  k = HiddenGroup (g, 0, 2, NULL);
 
11480
  dlp->to_button = PushButton (k, "->", MoveToList2);
 
11481
  SetObjectExtra (dlp->to_button, dlp, NULL);
 
11482
  dlp->from_button = PushButton (k, "<-", MoveToList1);
 
11483
  SetObjectExtra (dlp->from_button, dlp, NULL);
 
11484
  /* panel 2 */
 
11485
  dlp->list2_ctrl = DocumentPanel (g, stdCharWidth * 25, height * 6);
 
11486
  SetObjectExtra (dlp->list2_ctrl, dlp, NULL);
 
11487
  
 
11488
  c = HiddenGroup (h, 4, 0, NULL);
 
11489
  dlp->accept_button = PushButton (c, "Accept", AcceptDoubleList);
 
11490
  SetObjectExtra (dlp->accept_button, dlp, NULL);
 
11491
  b = PushButton (c, "Cancel", CancelDoubleList);
 
11492
  SetObjectExtra (b, dlp, NULL);
 
11493
  
 
11494
  PopulateDoubleListPanels (dlp);
 
11495
  
 
11496
  AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
 
11497
  
 
11498
}
 
11499
 
 
11500
static Int4 LIBCALLBACK GetAuthorPrintLen (Pointer userdata)
 
11501
{
 
11502
  Int4       text_len = 0;
 
11503
  NameStdPtr pName;
 
11504
  AuthorPtr  ap;
 
11505
  
 
11506
  ap = (AuthorPtr) userdata;
 
11507
  if (ap == NULL || ap->name == NULL || ap->name->data == NULL) return 0;
 
11508
  
 
11509
  if (ap->name->choice == 2)
 
11510
  {
 
11511
    pName = (NameStdPtr) ap->name->data;
 
11512
    if (!StringHasNoText (pName->names[0]))
 
11513
    {
 
11514
      text_len += StringLen (pName->names [0]) + 3;
 
11515
    }
 
11516
    if (!StringHasNoText (pName->names[4]))
 
11517
    {
 
11518
      text_len += StringLen (pName->names[4]) + 2;
 
11519
    }
 
11520
  }
 
11521
  else if (ap->name->choice == 4 || ap->name->choice == 5)
 
11522
  {
 
11523
    text_len = StringLen (ap->name->data) + 2;
 
11524
  }
 
11525
  return text_len;
 
11526
}
 
11527
 
 
11528
static void LIBCALLBACK PrintAuthor (CharPtr cp, Pointer userdata)
 
11529
{
 
11530
  NameStdPtr pName;
 
11531
  AuthorPtr  ap;
 
11532
  
 
11533
  ap = (AuthorPtr) userdata;
 
11534
  if (ap == NULL || ap->name == NULL || ap->name->data == NULL || cp == NULL) return;
 
11535
  
 
11536
  if (ap->name->choice == 2)
 
11537
  {
 
11538
    pName = (NameStdPtr) ap->name->data;
 
11539
    if (!StringHasNoText (pName->names[0]))
 
11540
    {
 
11541
      StringCat (cp, pName->names[0]);
 
11542
      if (!StringHasNoText (pName->names[4]))
 
11543
      {
 
11544
        StringCat (cp, ", ");
 
11545
      }
 
11546
    }
 
11547
    if (!StringHasNoText (pName->names[4]))
 
11548
    {
 
11549
      StringCat (cp, pName->names[4]);
 
11550
    }
 
11551
  }
 
11552
  else if (ap->name->choice == 4 || ap->name->choice == 5)
 
11553
  {
 
11554
    StringCat (cp, ap->name->data);
 
11555
  }
 
11556
  StringCat (cp, "\n");
 
11557
}
 
11558
 
 
11559
static Boolean ChangeAuthorOrder (EditPubFormPtr epfp)
 
11560
{
 
11561
  DoubleListData dld;
 
11562
  ValNodePtr     tmp_list = NULL, vnp;
 
11563
  AuthorPtr      ap;
 
11564
  
 
11565
  if (epfp == NULL || epfp->edit_type != 3)
 
11566
  {
 
11567
    return FALSE;
 
11568
  }
 
11569
   
 
11570
  if (epfp->names_list == NULL || epfp->names_list->next == NULL)
 
11571
  {
 
11572
    return TRUE;
 
11573
  }
 
11574
  
 
11575
  /* create temporary copy of list */
 
11576
  for (vnp = epfp->names_list; vnp != NULL; vnp = vnp->next)
 
11577
  {
 
11578
    ap = AsnIoMemCopy (vnp->data.ptrvalue,
 
11579
                    (AsnReadFunc) AuthorAsnRead,
 
11580
                    (AsnWriteFunc) AuthorAsnWrite);
 
11581
    if (ap != NULL)
 
11582
    {
 
11583
      ValNodeAddPointer (&(tmp_list), vnp->choice, ap);
 
11584
    }
 
11585
  }
 
11586
  
 
11587
  dld.list1 = tmp_list;
 
11588
  dld.list2 = NULL;
 
11589
  dld.num_total = ValNodeLen (dld.list1);
 
11590
  dld.list1_clicked = (BoolPtr) MemNew (dld.num_total * sizeof (Boolean));
 
11591
  dld.list2_clicked = (BoolPtr) MemNew (dld.num_total * sizeof (Boolean));
 
11592
  dld.done = FALSE;
 
11593
  dld.getlenproc = GetAuthorPrintLen;
 
11594
  dld.printitemproc = PrintAuthor;
 
11595
  dld.none_in_1_ok = TRUE;
 
11596
  dld.none_in_2_ok = FALSE;
 
11597
  
 
11598
  DrawDoubleListWindow (&dld, "Available Authors", "Final List");
 
11599
 
 
11600
  RealizeWindow (dld.w);
 
11601
  Show (dld.w);
 
11602
  Update ();
 
11603
  
 
11604
  while (!dld.done)
 
11605
  {
 
11606
    ProcessExternalEvent ();
 
11607
    Update ();
 
11608
  }
 
11609
  ProcessAnEvent ();
 
11610
  if (dld.accepted)
 
11611
  { 
 
11612
    /* now change author order */ 
 
11613
    tmp_list = epfp->names_list;
 
11614
    epfp->names_list = dld.list2;
 
11615
    dld.list2 = tmp_list;
 
11616
  }
 
11617
  
 
11618
  /* free lists */
 
11619
  for (vnp = dld.list1; vnp != NULL; vnp = vnp->next)
 
11620
  {
 
11621
    vnp->data.ptrvalue = AuthorFree (vnp->data.ptrvalue);
 
11622
  }
 
11623
  dld.list1 = ValNodeFree (dld.list1);
 
11624
  for (vnp = dld.list2; vnp != NULL; vnp = vnp->next)
 
11625
  {
 
11626
    vnp->data.ptrvalue = AuthorFree (vnp->data.ptrvalue);
 
11627
  }
 
11628
  dld.list2 = ValNodeFree (dld.list2);
 
11629
  
 
11630
  Remove (dld.w);
 
11631
  return dld.accepted;
 
11632
}
 
11633
 
 
11634
static void DoEditPubs (ButtoN b)
 
11635
{
 
11636
  SeqEntryPtr        sep;
 
11637
  EditPubFormPtr     epfp;
 
11638
  UIEnum             val;
 
11639
  PubPtr             pub;
 
11640
  AuthListPtr        alp;
 
11641
  
 
11642
  epfp = (EditPubFormPtr) GetObjectExtra (b);
 
11643
  if (epfp == NULL) return;
 
11644
  
 
11645
  sep = GetTopSeqEntryForEntityID (epfp->input_entityID);
 
11646
  if (sep == NULL) return;
 
11647
 
 
11648
  PopulatePubConstraint (&(epfp->pcd));
 
11649
 
 
11650
  switch (epfp->edit_type)
 
11651
  {
 
11652
    case 1:
 
11653
      if (GetEnumPopup (epfp->field_to_set_popup, pub_field_no_any_alist, &val)) 
 
11654
      {
 
11655
        epfp->field_to_set = val;
 
11656
      }
 
11657
      else
 
11658
      {
 
11659
        return;
 
11660
      }
 
11661
  
 
11662
      epfp->repl_string = SaveStringFromText (epfp->repl_string_txt);
 
11663
      OperateOnPubByConstraint (sep, epfp, EditPubSingleField);
 
11664
      break;
 
11665
 
 
11666
    case 2:
 
11667
      epfp->pdp = FindFirstSelectedPub ();
 
11668
      if (epfp->pdp == NULL)
 
11669
      {
 
11670
        Message (MSG_ERROR, "No selected pub!");
 
11671
        return;
 
11672
      }
 
11673
 
 
11674
      epfp->alp = AuthListFree (epfp->alp);
 
11675
      if (GetStatus (epfp->replace_author_list))
 
11676
      {
 
11677
        pub = epfp->pdp->pub;
 
11678
        while (epfp->alp == NULL && pub != NULL)
 
11679
        {
 
11680
          epfp->alp = GetAuthorListForPub (pub);
 
11681
          pub = pub->next;
 
11682
        }
 
11683
        /* make a copy, so that if the selected pub matches the contraint, we won't wipe out
 
11684
         * the contents of the master when we free the AuthListPtr for the selected pub
 
11685
         * when we replace it with itself.
 
11686
         */
 
11687
        if (epfp->alp != NULL)
 
11688
        {
 
11689
          epfp->alp = AsnIoMemCopy ((Pointer) epfp->alp,
 
11690
                    (AsnReadFunc) AuthListAsnRead,
 
11691
                    (AsnWriteFunc) AuthListAsnWrite);
 
11692
        }
 
11693
      }
 
11694
 
 
11695
      epfp->title_str = MemFree (epfp->title_str);
 
11696
      if (GetStatus (epfp->replace_title))
 
11697
      {
 
11698
        pub = epfp->pdp->pub;
 
11699
        while (epfp->title_str == NULL && pub != NULL)
 
11700
        {
 
11701
          epfp->title_str = GetPubTitleSample (pub);
 
11702
          pub = pub->next;
 
11703
        }
 
11704
        epfp->title_str = StringSave (epfp->title_str);
 
11705
      }
 
11706
  
 
11707
      epfp->affil = AffilFree (epfp->affil);
 
11708
      if (GetStatus (epfp->replace_affiliation))
 
11709
      {
 
11710
        pub = epfp->pdp->pub;
 
11711
        while (epfp->affil == NULL && pub != NULL)
 
11712
        {
 
11713
          alp = GetAuthorListForPub (pub);
 
11714
          if (alp != NULL && alp->affil != NULL)
 
11715
          {
 
11716
            epfp->affil = AsnIoMemCopy ((Pointer) alp->affil,
 
11717
                        (AsnReadFunc) AffilAsnRead,
 
11718
                        (AsnWriteFunc) AffilAsnWrite);
 
11719
          }
 
11720
          pub = pub->next;
 
11721
        }    
 
11722
      }
 
11723
      OperateOnPubByConstraint (sep, epfp, ReplacePubSectByConstraint);
 
11724
 
 
11725
      break;
 
11726
    
 
11727
    case 3:
 
11728
      /* clear out any old list */
 
11729
      epfp->names_list = FreeAuthorNameList (epfp->names_list);
 
11730
      
 
11731
      /* get the merged list */
 
11732
      OperateOnPubByConstraint (sep, epfp, GetMergedAuthorListByConstraint);
 
11733
 
 
11734
      if (GetStatus (epfp->specify_author_order))
 
11735
      {
 
11736
        if (!ChangeAuthorOrder (epfp))
 
11737
        {
 
11738
          /* cancelled - go back to dialog */
 
11739
          return;
 
11740
        }
 
11741
      }
 
11742
      
 
11743
      /* now set the merged list */
 
11744
      OperateOnPubByConstraint (sep, epfp, SetMergedAuthorListByConstraint);
 
11745
    break;
 
11746
  }
 
11747
  
 
11748
  ObjMgrSetDirtyFlag (epfp->input_entityID, TRUE);
 
11749
  ObjMgrSendMsg (OM_MSG_UPDATE, epfp->input_entityID, 0, 0);
 
11750
  Update ();              
 
11751
    
 
11752
  if (! GetStatus (epfp->leaveDlgUp))
 
11753
  {
 
11754
    Remove (epfp->form);
 
11755
  }
 
11756
  
 
11757
}
 
11758
 
 
11759
static void ChangePubEditType (GrouP g)
 
11760
{
 
11761
  EditPubFormPtr epfp;
 
11762
  
 
11763
  epfp = (EditPubFormPtr) GetObjectExtra (g);
 
11764
  if (epfp == NULL) return;
 
11765
  
 
11766
  epfp->edit_type = GetValue (epfp->edit_type_group);
 
11767
  switch (epfp->edit_type)
 
11768
  {
 
11769
    case 1:
 
11770
      Show (epfp->single_field_group);
 
11771
      Hide (epfp->replace_sect_group);
 
11772
      Hide (epfp->merge_auth_list_group);
 
11773
      break;
 
11774
    case 2:
 
11775
      Hide (epfp->single_field_group);
 
11776
      Show (epfp->replace_sect_group);
 
11777
      Hide (epfp->merge_auth_list_group);
 
11778
      break;
 
11779
    default:
 
11780
      Hide (epfp->single_field_group);
 
11781
      Hide (epfp->replace_sect_group);
 
11782
      Show (epfp->merge_auth_list_group);
 
11783
      epfp->edit_type = 3;
 
11784
      SetValue (g, 3);
 
11785
      break;
 
11786
  }
 
11787
}
 
11788
 
 
11789
static void LoadValueFromSelectedPub (ButtoN b)
 
11790
{
 
11791
  EditPubFormPtr    epfp;
 
11792
  SelStructPtr      ssp;
 
11793
  SeqMgrFeatContext fcontext;
 
11794
  SeqMgrDescContext dcontext;
 
11795
  PubdescPtr        pdp = NULL;
 
11796
  SeqFeatPtr        sfp;
 
11797
  SeqDescPtr        sdp;
 
11798
  CharPtr           field_val = NULL;
 
11799
  UIEnum            val;
 
11800
  Int4              field_to_set = PUB_FIELD_ANY;
 
11801
  
 
11802
  epfp = (EditPubFormPtr) GetObjectExtra (b);
 
11803
  if (epfp == NULL) return;
 
11804
  
 
11805
  if (GetEnumPopup (epfp->field_to_set_popup, pub_field_no_any_alist, &val)) 
 
11806
  {
 
11807
    field_to_set = val;
 
11808
  }
 
11809
 
 
11810
  if (field_to_set == PUB_FIELD_ANY) return;
 
11811
 
 
11812
  ssp  = ObjMgrGetSelected();
 
11813
 
 
11814
  while (NULL != ssp && field_val == NULL) 
 
11815
  {
 
11816
    if (ssp->itemtype == OBJ_SEQFEAT)
 
11817
    {
 
11818
      sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &fcontext);
 
11819
      if (sfp != NULL && sfp->data.choice == SEQFEAT_PUB)
 
11820
      {
 
11821
        pdp = sfp->data.value.ptrvalue;
 
11822
        field_val = GetSampleStringFromPub (pdp, field_to_set);
 
11823
      }
 
11824
    }
 
11825
    else if (ssp->itemtype == OBJ_SEQDESC)
 
11826
    {
 
11827
      sdp = SeqMgrGetDesiredDescriptor (ssp->entityID, NULL, ssp->itemID, 0, NULL, &dcontext);
 
11828
      if (sdp != NULL && sdp->choice == Seq_descr_pub)
 
11829
      {
 
11830
        pdp = sdp->data.ptrvalue;
 
11831
        field_val = GetSampleStringFromPub (pdp, field_to_set);
 
11832
      }
 
11833
    }
 
11834
    ssp = ssp->next;
 
11835
  }
 
11836
  
 
11837
  SetTitle (epfp->repl_string_txt, field_val);
 
11838
}
 
11839
 
 
11840
static void CleanupEditPub (GraphiC g, VoidPtr data)
 
11841
{
 
11842
  EditPubFormPtr      epfp;
 
11843
 
 
11844
  epfp = (EditPubFormPtr) data;
 
11845
  if (epfp != NULL) 
 
11846
  {
 
11847
    /* cleanup for single field replace */
 
11848
    epfp->repl_string = MemFree (epfp->repl_string);
 
11849
 
 
11850
    /* cleanup for replace section */    
 
11851
    epfp->alp = AuthListFree (epfp->alp);
 
11852
    epfp->title_str = MemFree (epfp->title_str);
 
11853
    epfp->affil = AffilFree (epfp->affil);
 
11854
    
 
11855
    /* cleanup for author list merge */
 
11856
    epfp->names_list = FreeAuthorNameList (epfp->names_list);
 
11857
    
 
11858
    /* cleanup constraint */
 
11859
    epfp->pcd.find_str = MemFree (epfp->pcd.find_str);
 
11860
  }
 
11861
  StdCleanupFormProc (g, data);
 
11862
}
 
11863
 
 
11864
extern void EditPubs (IteM i)
 
11865
{
 
11866
  BaseFormPtr           bfp;
 
11867
  GrouP                 h, k, g, n, m, c;
 
11868
  EditPubFormPtr        epfp;
 
11869
  WindoW                w;
 
11870
  ButtoN                b;
 
11871
  PrompT                p;
 
11872
 
 
11873
#ifdef WIN_MAC
 
11874
  bfp = currentFormDataPtr;
 
11875
#else
 
11876
  bfp = GetObjectExtra (i);
 
11877
#endif
 
11878
  if (bfp == NULL) return;
 
11879
 
 
11880
  epfp = (EditPubFormPtr) MemNew (sizeof (EditPubFormData));
 
11881
  if (epfp == NULL) return;
 
11882
  epfp->input_entityID = bfp->input_entityID;
 
11883
  epfp->input_itemID = bfp->input_itemID;
 
11884
  epfp->input_itemtype = bfp->input_itemtype;
 
11885
  
 
11886
  w = FixedWindow (-50, -33, -10, -10, "Edit Publications", StdCloseWindowProc);
 
11887
  SetObjectExtra (w, epfp, CleanupEditPub);
 
11888
  epfp->form = (ForM) w;
 
11889
 
 
11890
  h = HiddenGroup (w, -1, 0, NULL);
 
11891
  SetGroupSpacing (h, 10, 10);
 
11892
  
 
11893
  epfp->edit_type_group = NormalGroup (h, 3, 0, "Type of Edit", systemFont, ChangePubEditType);
 
11894
  SetObjectExtra (epfp->edit_type_group, epfp, NULL);
 
11895
  RadioButton (epfp->edit_type_group, "Replace Single Field");
 
11896
  RadioButton (epfp->edit_type_group, "Replace Section");
 
11897
  RadioButton (epfp->edit_type_group, "Merge author lists");
 
11898
  SetValue (epfp->edit_type_group, 1);
 
11899
  
 
11900
  m = HiddenGroup (h, 0, 0, NULL);
 
11901
  
 
11902
  epfp->single_field_group = HiddenGroup (m, -1, 0, NULL);
 
11903
  g = HiddenGroup (epfp->single_field_group, 2, 0, NULL);
 
11904
  StaticPrompt (g, "Set text in", 0, dialogTextHeight, programFont, 'c');
 
11905
  epfp->field_to_set_popup = PopupList (g, TRUE, NULL);
 
11906
  InitEnumPopup (epfp->field_to_set_popup, pub_field_no_any_alist, NULL);
 
11907
  SetEnumPopup (epfp->field_to_set_popup, pub_field_no_any_alist, PUB_FIELD_TITLE);
 
11908
  StaticPrompt (g, "To new value", 0, dialogTextHeight, programFont, 'c');
 
11909
  epfp->repl_string_txt = DialogText (g, "", 15, NULL);  
 
11910
  n = HiddenGroup (epfp->single_field_group, 1, 0, NULL);
 
11911
  b = PushButton (n, "Load New Value from Selected Publication", LoadValueFromSelectedPub);
 
11912
  SetObjectExtra (b, epfp, NULL);
 
11913
  AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) n, NULL);
 
11914
 
 
11915
  epfp->replace_sect_group = HiddenGroup (m, 1, 0, NULL);
 
11916
  epfp->replace_author_list = CheckBox (epfp->replace_sect_group, "Replace Author List with Selected Author List", NULL);
 
11917
  epfp->replace_title = CheckBox (epfp->replace_sect_group, "Replace Title with Selected Title", NULL);
 
11918
  epfp->replace_affiliation = CheckBox (epfp->replace_sect_group, "Replace Affiliation with Selected Affiliation", NULL);
 
11919
 
 
11920
  epfp->merge_auth_list_group = HiddenGroup (m, -1, 0, NULL);
 
11921
  p = StaticPrompt (epfp->merge_auth_list_group, "Merge publication author lists", 0, dialogTextHeight, programFont, 'c');
 
11922
  epfp->specify_author_order = CheckBox (epfp->merge_auth_list_group, "Specify Author Order", NULL);
 
11923
  AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) epfp->specify_author_order, NULL);
 
11924
  ChangePubEditType (epfp->edit_type_group);
 
11925
 
 
11926
  k = HiddenGroup (h, -1, 0, NULL);
 
11927
  SetGroupSpacing (k, 10, 10);
 
11928
  CreatePubConstraintControls (k, &(epfp->pcd));
 
11929
  
 
11930
  c = HiddenGroup (h, 4, 0, NULL);
 
11931
  b = DefaultButton (c, "Accept", DoEditPubs);
 
11932
  SetObjectExtra (b, epfp, NULL);
 
11933
  PushButton (c, "Cancel", StdCancelButtonProc);
 
11934
  epfp->leaveDlgUp = CheckBox (c, "Leave Dialog Up", NULL);
 
11935
  
 
11936
  AlignObjects (ALIGN_CENTER, (HANDLE) epfp->edit_type_group, (HANDLE) m, (HANDLE) k, (HANDLE) c, NULL);   
 
11937
 
 
11938
  RealizeWindow (w);
 
11939
  Show (w);
 
11940
  Update ();    
 
11941
  
 
11942
}
 
11943