1 /* sequin4.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: sequin4.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 6/28/96
31 *
32 * $Revision: 6.510 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44
45 #include "sequin.h"
46 #include <ncbilang.h>
47 #include <seqport.h>
48 #include <gather.h>
49 #include <objall.h>
50 #include <objcode.h>
51 #include <utilpub.h>
52 #include <vibrant.h>
53 #include <document.h>
54 #include <toasn3.h>
55 #include <asn2ffp.h>
56 #include <salfiles.h>
57 #include <salsap.h>
58 #include <saledit.h>
59 #include <salign.h>
60 #include <salptool.h>
61 #include <subutil.h>
62 #include <pobutil.h>
63 #include <tfuns.h>
64 #include <edutil.h>
65 #include <biosrc.h>
66 #include <seqgrphx.h>
67 #include <seqmtrx.h>
68 #include <bspview.h>
69 #include <vsmpriv.h>
70 #include <explore.h>
71 #include <alignval.h>
72 #include <alignmgr.h>
73 #include <alignmgr2.h>
74 #include <aliparse.h>
75 #include <spidey.h>
76 #include <ent2api.h>
77 #include <valid.h>
78 #include <sqnutils.h>
79 #include <seqpanel.h>
80 #include <salpanel.h>
81 #include <findrepl.h>
82 #include <macrodlg.h>
83 #include <macroapi.h>
84
85 static Int2 LIBCALLBACK CreateSegSet (Pointer data);
86 static Int2 LIBCALLBACK FeatToDeltaSeq (Pointer data);
87 static Int2 LIBCALLBACK CopyMasterSourceToSegments (Pointer data);
88 static Int2 LIBCALLBACK OrfFindFunc (Pointer data);
89
90 #define REGISTER_APPLY_SET_TYPE ObjMgrProcLoadEx (OMPROC_FILTER,"Convert Set Type","ConvertSetType",0,0,0,0,NULL,ApplySetTypeDesktop,PROC_PRIORITY_DEFAULT, "Indexer")
91
92 #define REGISTER_REMOVESET ObjMgrProcLoadEx (OMPROC_FILTER,"Remove Set","RemoveSet",0,0,0,0,NULL,RemoveSet,PROC_PRIORITY_DEFAULT, "Indexer")
93
94 #define REGISTER_REMOVESETSINSET ObjMgrProcLoadEx (OMPROC_FILTER,"Remove Sets in Selected Set","RemoveSetsInSelectedSet",0,0,0,0,NULL,RemoveSetsInSelectedSet,PROC_PRIORITY_DEFAULT, "Indexer")
95
96 #define REGISTER_REPACKAGE_PARTS ObjMgrProcLoadEx (OMPROC_FILTER,"Repackage Segmented Parts","RepackageParts",0,0,0,0,NULL,PackagePartsInPartsSet,PROC_PRIORITY_DEFAULT, "Indexer")
97
98 #define REGISTER_NORMALIZE_NUCPROT ObjMgrProcLoadEx (OMPROC_FILTER,"Normalize Nuc-Prot","NormalizeNucProts",0,0,0,0,NULL,NormalizeNucProts,PROC_PRIORITY_DEFAULT, "Indexer")
99
100 #define REGISTER_REMOVE_EXTRANEOUS ObjMgrProcLoadEx (OMPROC_FILTER,"Remove Extraneous Sets","RemoveExtraneousSets",0,0,0,0,NULL,RemoveExtraneousSets,PROC_PRIORITY_DEFAULT, "Indexer")
101
102 #define REGISTER_POPSET_WITHIN_GENBANK ObjMgrProcLoadEx (OMPROC_FILTER,"Add Popset Within GenBank Set","AddPopSetWithinGenBankSet",0,0,0,0,NULL,PopWithinGenBankSet,PROC_PRIORITY_DEFAULT, "Indexer")
103
104 #define REGISTER_PHYSET_WITHIN_GENBANK ObjMgrProcLoadEx (OMPROC_FILTER,"Add Physet Within GenBank Set","AddPhySetWithinGenBankSet",0,0,0,0,NULL,PhyWithinGenBankSet,PROC_PRIORITY_DEFAULT, "Indexer")
105
106 #define REGISTER_REMOVE_MESSEDUP ObjMgrProcLoadEx (OMPROC_FILTER,"Repair Messed Up Sets","RepairMessedUpSets",0,0,0,0,NULL,RepairMessedUpRecord,PROC_PRIORITY_DEFAULT, "Indexer")
107
108 #define REGISTER_UPDATE_SEQALIGN ObjMgrProcLoadEx (OMPROC_FILTER, "Update SeqAlign","UpdateSeqAlign",OBJ_SEQALIGN,0,OBJ_SEQALIGN,0,NULL,NewUpdateSeqAlign,PROC_PRIORITY_DEFAULT, "Alignment")
109
110 #define REGISTER_FIX_ALIGNMENT_OVER_GAPS ObjMgrProcLoadEx (OMPROC_FILTER, "Fix Alignment Over Gaps", "FixAlignmentOverGaps", 0,0,0,0,NULL,FixAlignmentOverGaps,PROC_PRIORITY_DEFAULT, "Alignment")
111
112 #define REGISTER_FIX_ALIGNMENT_GAP_GAPS ObjMgrProcLoadEx (OMPROC_FILTER, "Fix Alignment Gaps Containing Known Gaps", "FixKnownGapAlignmentGaps", 0,0,0,0,NULL,ConsolidateGapGaps, PROC_PRIORITY_DEFAULT, "Alignment")
113
114 #define REGISTER_REORDER_BY_ID ObjMgrProcLoadEx (OMPROC_FILTER, "Reorder by ID","ReorderByID",0,0,0,0,NULL,ReorderSetByAccession,PROC_PRIORITY_DEFAULT, "Indexer")
115
116 #define REGISTER_MAKESEQALIGNNEWBLAST ObjMgrProcLoadEx (OMPROC_FILTER,"Make SeqAlign","CreateSeqAlign",0,0,0,0,NULL,GenerateSeqAlignFromSeqEntryUseNewBlast,PROC_PRIORITY_DEFAULT, "Alignment")
117
118 #define REGISTER_MAKESEQALIGNMASTERNEWBLAST ObjMgrProcLoadEx (OMPROC_FILTER,"Make SeqAlign Choose Master","CreateSeqAlignChooseMaster",0,0,0,0,NULL,GenerateSeqAlignFromSeqEntryChooseMasterUseNewBlast,PROC_PRIORITY_DEFAULT, "Alignment")
119
120 #define REGISTER_MAKESEQALIGNPNEWBLAST ObjMgrProcLoadEx (OMPROC_FILTER,"Make Protein SeqAlign","CreateSeqAlignProt",0,0,0,0,NULL,GenerateSeqAlignFromSeqEntryProtUseNewBlast,PROC_PRIORITY_DEFAULT, "Alignment")
121
122 #define REGISTER_NORMSEQALIGN ObjMgrProcLoadEx (OMPROC_FILTER,"Validate SeqAlign","ValidateSeqAlign",0,0,0,0,NULL,ValidateSeqAlignFromData,PROC_PRIORITY_DEFAULT, "Alignment")
123
124 #define REGISTER_NOMORESEGGAP ObjMgrProcLoadEx (OMPROC_FILTER,"Get Rid of Seg Gap","GetRidOfSegGap",0,0,0,0,NULL,NoMoreSegGap,PROC_PRIORITY_DEFAULT, "Alignment")
125
126 #define REGISTER_GROUP_EXPLODE ObjMgrProcLoadEx (OMPROC_FILTER, "Explode a group", "GroupExplode", OBJ_SEQFEAT, 0, OBJ_SEQFEAT, 0, NULL, GroupExplodeFunc, PROC_PRIORITY_DEFAULT, "Indexer")
127
128 #define REGISTER_INTERVAL_COMBINE ObjMgrProcLoadEx (OMPROC_FILTER, "Combine feature intervals", "IntervalCombine", OBJ_SEQFEAT, 0, OBJ_SEQFEAT, 0, NULL, IntervalCombineFunc, PROC_PRIORITY_DEFAULT, "Indexer")
129
130 #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")
131
132 #define REGISTER_BIOSEQ_REVCOMP_WITHFEAT ObjMgrProcLoadEx (OMPROC_FILTER, "Bioseq and Features RevComp", "BioseqFeatsRevComp", OBJ_BIOSEQ, 0, OBJ_BIOSEQ, 0, NULL, RevCompFuncFeat, PROC_PRIORITY_DEFAULT, "Utilities")
133 #define REGISTER_BIOSEQ_REVCOMP_NOTFEAT ObjMgrProcLoadEx (OMPROC_FILTER, "Bioseq only RevComp", "BioseqOnlyRevComp", OBJ_BIOSEQ, 0, OBJ_BIOSEQ, 0, NULL, RevCompFunc, PROC_PRIORITY_DEFAULT, "Utilities")
134 #define REGISTER_BIOSEQ_REVERSE ObjMgrProcLoadEx (OMPROC_FILTER, "Bioseq Reverse", "BioseqReverse", OBJ_BIOSEQ, 0, OBJ_BIOSEQ, 0, NULL, RevFunc, PROC_PRIORITY_DEFAULT, "Utilities")
135 #define REGISTER_BIOSEQ_COMPLEMENT ObjMgrProcLoadEx (OMPROC_FILTER, "Bioseq Complement", "BioseqComplement", OBJ_BIOSEQ, 0, OBJ_BIOSEQ, 0, NULL, CompFunc, PROC_PRIORITY_DEFAULT, "Utilities")
136 #define REGISTER_BIOSEQ_REVCOMP_BYID ObjMgrProcLoadEx (OMPROC_FILTER, "Bioseq and Features RevComp By ID", "RevCompByID", OBJ_BIOSEQ, 0, OBJ_BIOSEQ, 0, NULL, BioseqRevCompByID, PROC_PRIORITY_DEFAULT, "Utilities")
137 #define REGISTER_BIOSEQ_ORF ObjMgrProcLoadEx (OMPROC_FILTER, "ORF Finder", "OrfFinder", OBJ_BIOSEQ, 0, OBJ_BIOSEQ, 0, NULL, OrfFindFunc, PROC_PRIORITY_DEFAULT, "Utilities")
138
139 #define REGISTER_BSP_INDEX ObjMgrProcLoadEx (OMPROC_FILTER,"Bioseq Index","MakeBioseqIndex",0,0,0,0,NULL,DoBioseqIndexing,PROC_PRIORITY_DEFAULT, "Indexer")
140
141 #define REGISTER_FIND_NON_ACGT ObjMgrProcLoadEx (OMPROC_FILTER,"Find Non ACGT","FindNonACGT",0,0,0,0,NULL,FindNonACGT,PROC_PRIORITY_DEFAULT, "Indexer")
142
143 #define REGISTER_OPENALED ObjMgrProcLoadEx (OMPROC_FILTER,"Open Align Editor 1","Open Contiguous Protein Alignment", 0,0,0,0,NULL,LaunchAlignEditorFromDesktop, PROC_PRIORITY_DEFAULT, "Alignment")
144
145 #define REGISTER_OPENALED2 ObjMgrProcLoadEx (OMPROC_FILTER,"Open Align Editor 2","Open Interleave Protein Alignment", 0,0,0,0,NULL,LaunchAlignEditorFromDesktop2, PROC_PRIORITY_DEFAULT, "Alignment")
146
147 #define REGISTER_DETACH ObjMgrProcLoadEx (OMPROC_FILTER,"Detach After Bioseq","DetachBioseq",OBJ_SEQFEAT,0,OBJ_SEQFEAT,0,NULL,DetachBioseq,PROC_PRIORITY_DEFAULT, "Misc")
148
149 #define REGISTER_DESKTOP_REPORT ObjMgrProcLoadEx (OMPROC_FILTER, "Desktop Report", "DesktopReport", 0, 0, 0, 0, NULL, DesktopReportFunc, PROC_PRIORITY_DEFAULT, "Indexer")
150
151 #define REGISTER_DESCRIPTOR_PROPAGATE ObjMgrProcLoadEx (OMPROC_FILTER, "Descriptor Propagate", "DescriptorPropagate", 0, 0, 0, 0, NULL, DescriptorPropagate, PROC_PRIORITY_DEFAULT, "Indexer")
152
153 #define REGISTER_COPY_MASTER_SOURCE_TO_SEGMENTS ObjMgrProcLoadEx (OMPROC_FILTER, "Copy Master Source To Segments", "CopyMasterSourceToSegments", 0, 0, 0, 0, NULL, CopyMasterSourceToSegments, PROC_PRIORITY_DEFAULT, "Indexer")
154
155 #define REGISTER_CLEAR_SEQENTRYSCOPE ObjMgrProcLoadEx (OMPROC_FILTER, "Clear SeqEntry Scope", "ClearSeqEntryScope", 0, 0, 0, 0, NULL, DoClearSeqEntryScope, PROC_PRIORITY_DEFAULT, "Indexer")
156
157 #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)
158 extern Int2 LIBCALLBACK RefGeneUserGenFunc (Pointer data);
159
160 #define REGISTER_GENOMEPROJSDBUSER_DESC_EDIT ObjMgrProcLoad(OMPROC_EDIT,"Edit GenomeProjectsDB User Desc","GenomeProjectsDB",OBJ_SEQDESC,Seq_descr_user,OBJ_SEQDESC,Seq_descr_user,NULL,GenomeProjectsDBUserGenFunc,PROC_PRIORITY_DEFAULT)
161 extern Int2 LIBCALLBACK GenomeProjectsDBUserGenFunc (Pointer data);
162
163 #define REGISTER_DBLINKUSER_DESC_EDIT ObjMgrProcLoad(OMPROC_EDIT,"Edit DBLink User Desc","DBLink",OBJ_SEQDESC,Seq_descr_user,OBJ_SEQDESC,Seq_descr_user,NULL,DBlinkUserGenFunc,PROC_PRIORITY_DEFAULT)
164 extern Int2 LIBCALLBACK DBlinkUserGenFunc (Pointer data);
165
166 #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)
167 extern Int2 LIBCALLBACK AssemblyUserGenFunc (Pointer data);
168
169 #define REGISTER_STRUCTUREDCOMMENTUSER_DESC_EDIT ObjMgrProcLoad(OMPROC_EDIT,"Edit StructuredComment User Desc","Structured Comment",OBJ_SEQDESC,Seq_descr_user,OBJ_SEQDESC,Seq_descr_user,NULL,StruCommUserGenFunc,PROC_PRIORITY_DEFAULT)
170 extern Int2 LIBCALLBACK StruCommUserGenFunc (Pointer data);
171
172 #define REGISTER_UNVERIFIED_DESC_EDIT ObjMgrProcLoad(OMPROC_EDIT,"Edit Unverified User Desc","Unverified",OBJ_SEQDESC,Seq_descr_user,OBJ_SEQDESC,Seq_descr_user,NULL,UnverifiedUserGenFunc,PROC_PRIORITY_DEFAULT)
173 extern Int2 LIBCALLBACK UnverifiedUserGenFunc (Pointer data);
174
175 #define REGISTER_AUTHORIZEDACCESSUSER_DESC_EDIT ObjMgrProcLoad(OMPROC_EDIT,"Edit AuthorizedAccess User Desc","AuthorizedAccess",OBJ_SEQDESC,Seq_descr_user,OBJ_SEQDESC,Seq_descr_user,NULL,AuthorizedAccessUserGenFunc,PROC_PRIORITY_DEFAULT)
176 extern Int2 LIBCALLBACK AuthorizedAccessUserGenFunc (Pointer data);
177
178 #define REGISTER_FEAT_INTERVALS_TO_DELTA ObjMgrProcLoadEx (OMPROC_FILTER, "Feature Intervals to Delta Sequence", "FeatToDelta", 0,0,0,0,NULL, FeatToDeltaSeq, PROC_PRIORITY_DEFAULT, "Indexer")
179
180 #if defined(OS_UNIX) || defined(OS_MSWIN)
181 #define REGISTER_CORRECTRNASTRANDSMART ObjMgrProcLoadEx (OMPROC_FILTER, "Correct RNA Strand Use SMART BLAST Results","CorrectRNAStrandSMART",0,0,0,0,NULL,CorrectRNAStrandednessUseSmart,PROC_PRIORITY_DEFAULT, "Indexer")
182 #define REGISTER_CORRECTRNASTRAND ObjMgrProcLoadEx (OMPROC_FILTER, "Correct RNA Strand Use Local Database Search","CorrectRNAStrandLocalDatabase",0,0,0,0,NULL,CorrectRNAStrandedness,PROC_PRIORITY_DEFAULT, "Indexer")
183 #endif
184
185
186 /* commands for Desktop Segregate menu */
187 #define REGISTER_SEGREGATE_BY_FIELD ObjMgrProcLoadEx (OMPROC_FILTER, "Segregate By Options","Segregate",0,0,0,0,NULL,SegregateSetsByField,PROC_PRIORITY_DEFAULT, "Segregate")
188
189 #define REGISTER_SEQUESTER_SETS ObjMgrProcLoadEx (OMPROC_FILTER, "Sequester", "Sequester",0,0,0,0,NULL,SequesterSequences, PROC_PRIORITY_DEFAULT, "Sequester")
190 /* commands for Desktop SegmentedSets menu */
191 #define REGISTER_CREATESEGSET ObjMgrProcLoadEx (OMPROC_FILTER,"Create Segmented Set", "CreateSegSet", 0,0,0,0,NULL,CreateSegSet, PROC_PRIORITY_DEFAULT, "SegmentedSets")
192 #define REGISTER_UPDATESEGSET ObjMgrProcLoadEx (OMPROC_FILTER,"Update Segmented Set","UpdateSegSet",0,0,0,0,NULL,UpdateSegSet,PROC_PRIORITY_DEFAULT, "SegmentedSets")
193 #define REGISTER_NEWUPDATESEGSET ObjMgrProcLoadEx (OMPROC_FILTER,"New Update Segmented Set","NewUpdateSegSet",0,0,0,0,NULL,NewUpdateSegSet,PROC_PRIORITY_DEFAULT, "SegmentedSets")
194 #define REGISTER_ADJUSTMULTISEGSEQ ObjMgrProcLoadEx (OMPROC_FILTER,"Adjust SegSeq Length","AdjustSegLength",0,0,0,0,NULL,AdjustSegSeqLength,PROC_PRIORITY_DEFAULT, "SegmentedSets")
195 #define REGISTER_UNDOSEGSET ObjMgrProcLoadEx (OMPROC_FILTER,"Undo Segmented Set","UndoSegSet",0,0,0,0,NULL,UndoSegSet,PROC_PRIORITY_DEFAULT, "SegmentedSets")
196 #define REGISTER_SEGSETREMOVESETSINSET ObjMgrProcLoadEx (OMPROC_FILTER,"Remove Sets in Selected Set (Like Undo SegSet)","RemoveSetsInSelectedSet",0,0,0,0,NULL,RemoveSetsInSelectedSet,PROC_PRIORITY_DEFAULT, "SegmentedSets")
197
198
199 typedef struct _explodeStruct {
200 SeqEntryPtr topSep;
201 SeqFeatPtr seqFeatPtr;
202 struct _explodeStruct PNTR next;
203 } ExplodeStruct, PNTR ExplodeStructPtr;
204
205 typedef struct {
206 DESCRIPTOR_FORM_BLOCK
207 PopuP fromPopup;
208 PopuP toPopup;
209 Int2 fromStrand;
210 Int2 toStrand;
211 ValNodePtr featlist;
212 LisT feature;
213 Int2 featSubType;
214 CharPtr findThisStr;
215 TexT findThis;
216 Boolean case_insensitive;
217 ButtoN case_insensitive_btn;
218 Boolean when_string_not_present;
219 ButtoN when_string_not_present_btn;
220 } EditStrand, PNTR EditStrandPtr;
221
AddBspToSegSet(BioseqPtr segseq,BioseqPtr bsp)222 static void AddBspToSegSet (BioseqPtr segseq, BioseqPtr bsp)
223
224 {
225 SeqIdPtr sip;
226 SeqLocPtr slp;
227
228 if (segseq == NULL) return;
229 slp = ValNodeNew ((ValNodePtr) segseq->seq_ext);
230 if (slp == NULL) return;
231 if (segseq->seq_ext == NULL) {
232 segseq->seq_ext = (Pointer) slp;
233 }
234 if (bsp != NULL && bsp->length > 0) {
235 segseq->length += bsp->length;
236 slp->choice = SEQLOC_WHOLE;
237 sip = SeqIdFindBest (bsp->id, 0);
238 slp->data.ptrvalue = (Pointer) SeqIdStripLocus (SeqIdDup (sip));
239 } else {
240 slp->choice = SEQLOC_NULL;
241 }
242 }
243
RemoveMolInfoDescriptors(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)244 static void RemoveMolInfoDescriptors (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
245
246 {
247 BioseqPtr bsp;
248 BioseqSetPtr bssp;
249 ValNodePtr nextsdp;
250 Pointer PNTR prevsdp;
251 ValNodePtr sdp;
252
253 if (IS_Bioseq (sep)) {
254 bsp = (BioseqPtr) sep->data.ptrvalue;
255 sdp = bsp->descr;
256 prevsdp = (Pointer PNTR) &(bsp->descr);
257 } else if (IS_Bioseq_set (sep)) {
258 bssp = (BioseqSetPtr) sep->data.ptrvalue;
259 sdp = bssp->descr;
260 prevsdp = (Pointer PNTR) &(bssp->descr);
261 } else return;
262 while (sdp != NULL) {
263 nextsdp = sdp->next;
264 if (sdp->choice == Seq_descr_molinfo) {
265 *(prevsdp) = sdp->next;
266 sdp->next = NULL;
267 SeqDescFree (sdp);
268 } else {
269 prevsdp = (Pointer PNTR) &(sdp->next);
270 }
271 sdp = nextsdp;
272 }
273 }
274
MoveSegSetMolInfo(BioseqPtr segseq,BioseqSetPtr parts,BioseqSetPtr segset)275 static void MoveSegSetMolInfo (BioseqPtr segseq, BioseqSetPtr parts, BioseqSetPtr segset)
276
277 {
278 MolInfoPtr first;
279 MolInfoPtr mip;
280 SeqEntryPtr partssep;
281 ValNodePtr sdp;
282 SeqEntryPtr sep;
283 SeqEntryPtr tmp;
284
285 if (segseq == NULL || parts == NULL || parts->seq_set == NULL || segset == NULL) return;
286 sep = SeqMgrGetSeqEntryForData (segset);
287 if (sep == NULL) return;
288 sdp = SeqEntryGetSeqDescr (sep, Seq_descr_molinfo, NULL);
289 if (sdp != NULL) return;
290 first = NULL;
291 partssep = SeqMgrGetSeqEntryForData (parts);
292 if (partssep != NULL) {
293 sdp = SeqEntryGetSeqDescr (partssep, Seq_descr_molinfo, NULL);
294 if (sdp != NULL) {
295 first = (MolInfoPtr) sdp->data.ptrvalue;
296 }
297 }
298 for (tmp = parts->seq_set; tmp != NULL; tmp = tmp->next) {
299 sdp = SeqEntryGetSeqDescr (tmp, Seq_descr_molinfo, NULL);
300 if (sdp != NULL) {
301 if (first == NULL) {
302 first = (MolInfoPtr) sdp->data.ptrvalue;
303 } else {
304 mip = (MolInfoPtr) sdp->data.ptrvalue;
305 if (first != NULL && mip != NULL) {
306 if (mip->biomol != first->biomol) return;
307 }
308 }
309 }
310 }
311 if (first == NULL) return;
312 mip = MolInfoNew ();
313 if (mip == NULL) return;
314 sdp = CreateNewDescriptor (sep, Seq_descr_molinfo);
315 if (sdp == NULL) return;
316 sdp->data.ptrvalue = (Pointer) mip;
317 mip->biomol = first->biomol;
318 mip->tech = first->tech;
319 mip->completeness = first->completeness;
320 mip->techexp = StringSaveNoNull (first->techexp);
321 if (partssep != NULL) {
322 SeqEntryExplore (partssep, NULL, RemoveMolInfoDescriptors);
323 }
324 for (tmp = parts->seq_set; tmp != NULL; tmp = tmp->next) {
325 SeqEntryExplore (tmp, NULL, RemoveMolInfoDescriptors);
326 }
327 }
328
329
DoDescriptorsMatch(SeqDescrPtr sdp1,SeqDescrPtr sdp2)330 static Boolean DoDescriptorsMatch (SeqDescrPtr sdp1, SeqDescrPtr sdp2)
331 {
332 if (sdp1 == NULL || sdp2 == NULL || sdp1->choice != sdp2->choice)
333 {
334 return FALSE;
335 }
336
337 /* compare publications */
338 if (sdp1->choice == Seq_descr_pub
339 && PubdescContentMatch (sdp1->data.ptrvalue, sdp2->data.ptrvalue))
340 {
341 return TRUE;
342 }
343 /* compare sources */
344 else if (sdp1->choice == Seq_descr_source
345 && BioSourceMatch (sdp1->data.ptrvalue, sdp2->data.ptrvalue))
346 {
347 return TRUE;
348 }
349 /* compare update dates */
350 else if (sdp1->choice == Seq_descr_update_date
351 && DateMatch (sdp1->data.ptrvalue, sdp2->data.ptrvalue, TRUE))
352 {
353 return TRUE;
354 }
355 else
356 {
357 return FALSE;
358 }
359 }
360
FindIdenticalDescriptorInEachBioseqInList(SeqDescrPtr sdp,SeqEntryPtr sep)361 static Boolean FindIdenticalDescriptorInEachBioseqInList (SeqDescrPtr sdp, SeqEntryPtr sep)
362 {
363 SeqDescrPtr check_sdp;
364 Boolean found_match = FALSE;
365 BioseqPtr bsp;
366
367 if (sdp == NULL)
368 {
369 return FALSE;
370 }
371 if (sep == NULL)
372 {
373 return TRUE;
374 }
375
376 if (!IS_Bioseq(sep) || sep->data.ptrvalue == NULL)
377 {
378 return FALSE;
379 }
380
381 bsp = (BioseqPtr) sep->data.ptrvalue;
382 check_sdp = bsp->descr;
383 while (check_sdp != NULL && !found_match)
384 {
385 found_match = DoDescriptorsMatch (check_sdp, sdp);
386 check_sdp = check_sdp->next;
387 }
388
389 if (found_match)
390 {
391 found_match = FindIdenticalDescriptorInEachBioseqInList (sdp, sep->next);
392 }
393
394 return found_match;
395 }
396
397
RemoveIdenticalDescriptorInEachBioseqInList(SeqDescrPtr sdp,SeqEntryPtr sep)398 static void RemoveIdenticalDescriptorInEachBioseqInList (SeqDescrPtr sdp, SeqEntryPtr sep)
399 {
400 SeqDescrPtr check_sdp, prev = NULL;
401 BioseqPtr bsp;
402
403 if (sdp == NULL || sep == NULL || !IS_Bioseq(sep) || sep->data.ptrvalue == NULL)
404 {
405 return;
406 }
407
408 bsp = (BioseqPtr) sep->data.ptrvalue;
409 check_sdp = bsp->descr;
410 while (check_sdp != NULL)
411 {
412 if (DoDescriptorsMatch (check_sdp, sdp))
413 {
414 if (prev == NULL)
415 {
416 bsp->descr = check_sdp->next;
417 }
418 else
419 {
420 prev->next = check_sdp->next;
421 }
422 check_sdp->next = NULL;
423 check_sdp = SeqDescrFree (check_sdp);
424 }
425 else
426 {
427 prev = check_sdp;
428 check_sdp = check_sdp->next;
429 }
430 }
431
432 RemoveIdenticalDescriptorInEachBioseqInList (sdp, sep->next);
433 }
434
435
436 static void
MoveUpIdenticalSegSetDescriptors(BioseqPtr segseq,BioseqSetPtr parts,BioseqSetPtr segset,Int2 descriptor_choice)437 MoveUpIdenticalSegSetDescriptors
438 (BioseqPtr segseq,
439 BioseqSetPtr parts,
440 BioseqSetPtr segset,
441 Int2 descriptor_choice)
442 {
443 SeqEntryPtr sep;
444 BioseqPtr bsp;
445 BioseqSetPtr bssp;
446 SeqDescrPtr sdp, sdp_next, prev = NULL;
447 SeqDescrPtr moved_list = NULL;
448
449 if (segseq == NULL || parts == NULL || parts->seq_set == NULL || segset == NULL
450 || ! IS_Bioseq (parts->seq_set) || parts->seq_set->data.ptrvalue == NULL)
451 {
452 return;
453 }
454
455 sep = GetBestTopParentForData (segseq->idx.entityID, segseq);
456 if (sep == NULL)
457 {
458 sep = SeqMgrGetSeqEntryForData (segset);
459 }
460
461 bsp = (BioseqPtr) parts->seq_set->data.ptrvalue;
462
463 sdp = bsp->descr;
464 while (sdp != NULL)
465 {
466 sdp_next = sdp->next;
467 if (sdp->choice == descriptor_choice
468 && FindIdenticalDescriptorInEachBioseqInList (sdp, parts->seq_set->next))
469 {
470 RemoveIdenticalDescriptorInEachBioseqInList (sdp, parts->seq_set->next);
471 if (prev == NULL)
472 {
473 bsp->descr = sdp->next;
474 }
475 else
476 {
477 prev->next = sdp->next;
478 }
479 sdp->next = NULL;
480 ValNodeLink (&moved_list, sdp);
481 }
482 else
483 {
484 prev = sdp;
485 }
486 sdp = sdp_next;
487 }
488
489 if (IS_Bioseq_set (sep))
490 {
491 bssp = (BioseqSetPtr) sep->data.ptrvalue;
492 ValNodeLink (&(bssp->descr), moved_list);
493 }
494 else if (IS_Bioseq (sep))
495 {
496 bsp = (BioseqPtr) sep->data.ptrvalue;
497 ValNodeLink (&(bsp->descr), moved_list);
498 }
499 }
500
501
DoUpdateSegSet(BioseqPtr segseq,BioseqSetPtr parts,Boolean ask,Boolean force_intersperse)502 static void DoUpdateSegSet (BioseqPtr segseq, BioseqSetPtr parts, Boolean ask, Boolean force_intersperse)
503
504 {
505 MsgAnswer ans;
506 BioseqPtr bsp;
507 Boolean notFirst;
508 Boolean nullsBetween;
509 SeqFeatPtr sfp;
510 SeqFeatPtr sfpnext;
511 SeqLocPtr slp;
512 SeqEntryPtr tmp;
513
514 if (segseq == NULL || parts == NULL || parts->seq_set == NULL) return;
515 tmp = parts->seq_set;
516 notFirst = FALSE;
517 nullsBetween = FALSE;
518 segseq->length = 0;
519 switch (segseq->seq_ext_type) {
520 case 1: /* seg-ext */
521 slp = (ValNodePtr) segseq->seq_ext;
522 while (slp != NULL) {
523 if (slp->choice == SEQLOC_NULL) {
524 nullsBetween = TRUE;
525 }
526 slp = slp->next;
527 }
528 SeqLocSetFree ((ValNodePtr) segseq->seq_ext);
529 break;
530 case 2: /* reference */
531 SeqLocFree ((ValNodePtr) segseq->seq_ext);
532 break;
533 case 3: /* map */
534 sfp = (SeqFeatPtr) segseq->seq_ext;
535 while (sfp != NULL) {
536 sfpnext = sfp->next;
537 SeqFeatFree (sfp);
538 sfp = sfpnext;
539 }
540 break;
541 default:
542 break;
543 }
544 segseq->seq_ext = NULL;
545 if (ask) {
546 if (nullsBetween) {
547 ans = Message (MSG_YN, "Intersperse intervals with gaps (currently has gaps)?");
548 } else {
549 ans = Message (MSG_YN, "Intersperse intervals with gaps (currently no gaps)?");
550 }
551 nullsBetween = (Boolean) (ans == ANS_YES);
552 }
553 else
554 {
555 nullsBetween |= force_intersperse;
556 }
557 while (tmp != NULL) {
558 if (nullsBetween && notFirst) {
559 AddBspToSegSet (segseq, NULL);
560 }
561 bsp = (BioseqPtr) tmp->data.ptrvalue;
562 if (bsp != NULL) {
563 AddBspToSegSet (segseq, bsp);
564 }
565 notFirst = TRUE;
566 tmp = tmp->next;
567 }
568 }
569
570 typedef struct updatesegstruc {
571 BioseqSetPtr parts;
572 BioseqPtr segseq;
573 BioseqSetPtr segset;
574 } UpdateSegStruc, PNTR UpdateSegStrucPtr;
575
FindSegSetComponentsCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)576 static void FindSegSetComponentsCallback (SeqEntryPtr sep, Pointer mydata,
577 Int4 index, Int2 indent)
578
579 {
580 BioseqPtr bsp;
581 BioseqSetPtr bssp;
582 UpdateSegStrucPtr ussp;
583
584 if (sep != NULL && sep->data.ptrvalue && mydata != NULL) {
585 ussp = (UpdateSegStrucPtr) mydata;
586 if (sep->choice == 1) {
587 bsp = (BioseqPtr) sep->data.ptrvalue;
588 if (bsp->repr == Seq_repr_seg) {
589 ussp->segseq = bsp;
590 }
591 } else if (sep->choice == 2) {
592 bssp = (BioseqSetPtr) sep->data.ptrvalue;
593 if (bssp->_class == 2) {
594 ussp->segset = bssp;
595 } else if (bssp->_class == 4) {
596 ussp->parts = bssp;
597 }
598 }
599 }
600 }
601
UpdateSegList(SeqEntryPtr sep,Pointer mydata,SeqEntryFunc mycallback,Int4 index,Int2 indent)602 static Int4 UpdateSegList (SeqEntryPtr sep, Pointer mydata,
603 SeqEntryFunc mycallback,
604 Int4 index, Int2 indent)
605
606 {
607 BioseqSetPtr bssp;
608
609 if (sep == NULL) return index;
610 if (mycallback != NULL)
611 (*mycallback) (sep, mydata, index, indent);
612 index++;
613 if (IS_Bioseq (sep)) return index;
614 if (Bioseq_set_class (sep) == 4) return index;
615 bssp = (BioseqSetPtr) sep->data.ptrvalue;
616 sep = bssp->seq_set;
617 indent++;
618 while (sep != NULL) {
619 index = UpdateSegList (sep, mydata, mycallback, index, indent);
620 sep = sep->next;
621 }
622 return index;
623 }
624
625 #define UpdateSegExplore(a,b,c) UpdateSegList(a, b, c, 0L, 0);
626
627 extern Int2 DoOneSegFixup (SeqEntryPtr sep, Boolean ask);
DoOneSegFixup(SeqEntryPtr sep,Boolean ask)628 extern Int2 DoOneSegFixup (SeqEntryPtr sep, Boolean ask)
629
630 {
631 BioseqSetPtr bssp;
632 Uint1 choice;
633 Int2 count;
634 SeqEntryPtr insert;
635 SeqEntryPtr next;
636 ObjMgrDataPtr omdptop;
637 ObjMgrData omdata;
638 Uint2 parenttype;
639 Pointer parentptr;
640 UpdateSegStruc uss;
641 SeqEntryPtr tmp;
642
643 if (sep == NULL) return 0;
644 if (IS_Bioseq_set (sep)) {
645 bssp = (BioseqSetPtr) sep->data.ptrvalue;
646 if (bssp != NULL && (bssp->_class == BioseqseqSet_class_genbank
647 || IsPopPhyEtcSet (bssp->_class))) {
648 choice = 0;
649 for (tmp = bssp->seq_set; tmp != NULL; tmp = tmp->next) {
650 if (choice == 0) {
651 choice = tmp->choice;
652 } else if (choice != tmp->choice) {
653 return 0;
654 }
655 }
656 count = 0;
657 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
658 count += DoOneSegFixup (sep, ask);
659 }
660 return count;
661 }
662 }
663 if (IS_Bioseq (sep) && sep->next != NULL) {
664 count = 0;
665 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
666 GetSeqEntryParent (sep, &parentptr, &parenttype);
667 insert = sep->next;
668 sep->next = NULL;
669 while (insert != NULL) {
670 next = insert->next;
671 insert->next = NULL;
672 AddSeqEntryToSeqEntry (sep, insert, FALSE);
673 count++;
674 insert = next;
675 }
676 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
677 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
678 uss.segseq = NULL;
679 uss.parts = NULL;
680 uss.segset = NULL;
681 UpdateSegExplore (sep, (Pointer) &uss, FindSegSetComponentsCallback);
682 if (uss.segseq != NULL && uss.parts != NULL && uss.segset != NULL) {
683 DoUpdateSegSet (uss.segseq, uss.parts, ask, FALSE);
684 MoveSegSetMolInfo (uss.segseq, uss.parts, uss.segset);
685
686 MoveUpIdenticalSegSetDescriptors (uss.segseq, uss.parts, uss.segset, Seq_descr_pub);
687 MoveUpIdenticalSegSetDescriptors (uss.segseq, uss.parts, uss.segset, Seq_descr_update_date);
688 MoveUpIdenticalSegSetDescriptors (uss.segseq, uss.parts, uss.segset, Seq_descr_source);
689 }
690 return count;
691 }
692 uss.segseq = NULL;
693 uss.parts = NULL;
694 uss.segset = NULL;
695 UpdateSegExplore (sep, (Pointer) &uss, FindSegSetComponentsCallback);
696 if (uss.segseq != NULL && uss.parts != NULL && uss.segset != NULL) {
697 DoUpdateSegSet (uss.segseq, uss.parts, ask, FALSE);
698 MoveSegSetMolInfo (uss.segseq, uss.parts, uss.segset);
699
700 MoveUpIdenticalSegSetDescriptors (uss.segseq, uss.parts, uss.segset, Seq_descr_pub);
701 MoveUpIdenticalSegSetDescriptors (uss.segseq, uss.parts, uss.segset, Seq_descr_update_date);
702 MoveUpIdenticalSegSetDescriptors (uss.segseq, uss.parts, uss.segset, Seq_descr_source);
703 return 1;
704 }
705 return 0;
706 }
707
708 static void
MoveNucProtSetFeaturesAndDescriptorsToNucSeg(BioseqSetPtr bssp,BioseqPtr bsp)709 MoveNucProtSetFeaturesAndDescriptorsToNucSeg
710 (BioseqSetPtr bssp, BioseqPtr bsp)
711 {
712 SeqAnnotPtr last_sap;
713 SeqDescrPtr last_sdp;
714 if (bssp == NULL || bsp == NULL)
715 {
716 return;
717 }
718 last_sap = bsp->annot;
719 while (last_sap != NULL && last_sap->next != NULL)
720 {
721 last_sap = last_sap->next;
722 }
723 if (last_sap == NULL)
724 {
725 bsp->annot = bssp->annot;
726 }
727 else
728 {
729 last_sap->next = bssp->annot;
730 }
731 bssp->annot = NULL;
732
733 last_sdp = bsp->descr;
734 while (last_sdp != NULL && last_sdp->next != NULL)
735 {
736 last_sdp = last_sdp->next;
737 }
738 if (last_sdp == NULL)
739 {
740 bsp->descr = bssp->descr;
741 }
742 else
743 {
744 last_sdp->next = bssp->descr;
745 }
746 bssp->descr = NULL;
747 }
748
UpdateOneSegSet(BioseqSetPtr seg_bssp,Boolean intersperse_nulls)749 static void UpdateOneSegSet (BioseqSetPtr seg_bssp, Boolean intersperse_nulls)
750 {
751 BioseqPtr seg = NULL;
752 BioseqSetPtr parts = NULL;
753 SeqEntryPtr sep;
754 BioseqPtr bsp;
755 BioseqSetPtr bssp;
756
757 if (seg_bssp == NULL || seg_bssp->_class != BioseqseqSet_class_segset)
758 {
759 return;
760 }
761
762 for (sep = seg_bssp->seq_set; sep != NULL; sep = sep->next)
763 {
764 if (IS_Bioseq (sep))
765 {
766 bsp = (BioseqPtr) sep->data.ptrvalue;
767 if (bsp != NULL
768 && ISA_na (bsp->mol)
769 && bsp->repr == Seq_repr_seg)
770 {
771 seg = bsp;
772 }
773 } else if (IS_Bioseq_set (sep)) {
774 bssp = (BioseqSetPtr) sep->data.ptrvalue;
775 if (bssp != NULL
776 && bssp->_class == BioseqseqSet_class_parts)
777 {
778 parts = bssp;
779 }
780 }
781 }
782 DoUpdateSegSet (seg, parts, FALSE, intersperse_nulls);
783 MoveSegSetMolInfo (seg, parts, seg_bssp);
784 MoveUpIdenticalSegSetDescriptors (seg, parts, seg_bssp, Seq_descr_pub);
785 MoveUpIdenticalSegSetDescriptors (seg, parts, seg_bssp, Seq_descr_update_date);
786 MoveUpIdenticalSegSetDescriptors (seg, parts, seg_bssp, Seq_descr_source);
787 }
788
ConvertOneSetToSegSet(SeqEntryPtr sep,Boolean intersperse_nulls)789 static void ConvertOneSetToSegSet (SeqEntryPtr sep, Boolean intersperse_nulls)
790 {
791 BioseqSetPtr bssp, this_bssp;
792 BioseqPtr seg;
793 SeqEntryPtr this_sep, next_sep;
794 SeqEntryPtr segment_list;
795 SeqEntryPtr nuc_list = NULL, last_nuc = NULL;
796 SeqEntryPtr prot_list = NULL, last_prot = NULL;
797 SeqEntryPtr nps_next, nuc_seg;
798 SeqEntryPtr nuc_sep, parts_sep, seg_sep;
799 BioseqSetPtr seg_bssp, parts;
800 BioseqPtr bsp;
801 SeqLocPtr slp;
802 ObjMgrDataPtr omdptop;
803 ObjMgrData omdata;
804 Uint2 parenttype;
805 Pointer parentptr;
806 BioseqSetPtr wrapper_bssp;
807 SeqEntryPtr tmp_sep;
808
809 if (sep == NULL || ! IS_Bioseq_set (sep))
810 {
811 return;
812 }
813 bssp = (BioseqSetPtr) sep->data.ptrvalue;
814 if (bssp == NULL
815 || bssp->_class == BioseqseqSet_class_nuc_prot
816 || bssp->_class == BioseqseqSet_class_segset)
817 {
818 return;
819 }
820
821 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
822 GetSeqEntryParent (sep, &parentptr, &parenttype);
823
824
825 segment_list = bssp->seq_set;
826 bssp->seq_set = NULL;
827
828 for (this_sep = segment_list;
829 this_sep != NULL;
830 this_sep = next_sep)
831 {
832 next_sep = this_sep->next;
833 this_sep->next = NULL;
834 if (IS_Bioseq (this_sep))
835 {
836 if (nuc_list == NULL)
837 {
838 nuc_list = this_sep;
839 }
840 else
841 {
842 if (last_nuc == NULL)
843 {
844 last_nuc = nuc_list;
845 }
846 while (last_nuc->next != NULL)
847 {
848 last_nuc = last_nuc->next;
849 }
850 last_nuc->next = this_sep;
851 }
852 }
853 else if (IS_Bioseq_set (this_sep))
854 {
855 this_bssp = (BioseqSetPtr) this_sep->data.ptrvalue;
856 if (this_bssp != NULL
857 && this_bssp->_class == BioseqseqSet_class_nuc_prot
858 && this_bssp->seq_set != NULL)
859 {
860 nuc_seg = this_bssp->seq_set;
861 this_bssp->seq_set = NULL;
862 nps_next = nuc_seg->next;
863 nuc_seg->next = NULL;
864 /* move set features to segment */
865 bsp = (BioseqPtr) nuc_seg->data.ptrvalue;
866 MoveNucProtSetFeaturesAndDescriptorsToNucSeg (this_bssp, bsp);
867
868 /* add nuc_seg to nuc_list */
869 if (nuc_list == NULL)
870 {
871 nuc_list = nuc_seg;
872 }
873 else
874 {
875 if (last_nuc == NULL)
876 {
877 last_nuc = nuc_list;
878 }
879 while (last_nuc->next != NULL)
880 {
881 last_nuc = last_nuc->next;
882 }
883 last_nuc->next = nuc_seg;
884 }
885
886 /* add proteins to prot_list */
887 if (prot_list == NULL)
888 {
889 prot_list = nps_next;
890 }
891 else
892 {
893 /* add proteins to protein list */
894 if (last_prot == NULL)
895 {
896 last_prot = prot_list;
897 }
898 while (last_prot->next != NULL)
899 {
900 last_prot = last_prot->next;
901 }
902 last_prot->next = nps_next;
903 }
904 }
905
906 /* remove nuc-prot set */
907 SeqEntryFree (this_sep);
908 }
909 }
910
911 if (nuc_list == NULL)
912 {
913 return;
914 }
915
916 /* create segment and parts from nuc_list */
917 bsp = nuc_list->data.ptrvalue;
918 seg = BioseqNew ();
919 if (seg == NULL) return;
920 seg->mol = bsp->mol;
921 seg->repr = Seq_repr_seg;
922 seg->seq_ext_type = 1;
923 seg->length = 0;
924 seg->id = MakeUniqueSeqID ("segseq_");
925 SeqMgrAddToBioseqIndex (seg);
926
927 nuc_sep = SeqEntryNew ();
928 if (nuc_sep == NULL) return;
929 nuc_sep->choice = 1;
930 nuc_sep->data.ptrvalue = (Pointer) seg;
931
932 parts = BioseqSetNew ();
933 if (parts == NULL) return;
934 parts->_class = 4;
935
936 parts_sep = SeqEntryNew ();
937 if (parts_sep == NULL) return;
938 parts_sep->choice = 2;
939 parts_sep->data.ptrvalue = (Pointer) parts;
940 nuc_sep->next = parts_sep;
941
942 parts->seq_set = nuc_list;
943 for (this_sep = nuc_list; this_sep != NULL; this_sep = this_sep->next)
944 {
945 bsp = (BioseqPtr) this_sep->data.ptrvalue;
946 if (bsp == NULL)
947 {
948 continue;
949 }
950 slp = ValNodeNew ((ValNodePtr) seg->seq_ext);
951 if (slp == NULL)
952 {
953 continue;
954 }
955
956 if (seg->seq_ext == NULL)
957 {
958 seg->seq_ext = (Pointer) slp;
959 }
960 if (bsp->length >= 0)
961 {
962 seg->length += bsp->length;
963 slp->choice = SEQLOC_WHOLE;
964 slp->data.ptrvalue = (Pointer) SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0)));
965 } else {
966 slp->choice = SEQLOC_NULL;
967 }
968 }
969
970 if (prot_list == NULL)
971 {
972 /* we just have nucleotides, so change the BioseqSet class to segset */
973 bssp->_class = BioseqseqSet_class_segset;
974 bssp->seq_set = nuc_sep;
975 seg_bssp = bssp;
976 }
977 else
978 {
979 /* change the BioseqSet class to nucprot, create the segmented
980 * set and put it in the nucleotide slot, and then add the proteins
981 */
982 bssp->_class = BioseqseqSet_class_nuc_prot;
983 seg_sep = SeqEntryNew ();
984 seg_bssp = BioseqSetNew ();
985 seg_sep->choice = 2;
986 seg_sep->data.ptrvalue = (Pointer) seg_bssp;
987 seg_bssp->_class = BioseqseqSet_class_segset;
988 seg_bssp->seq_set = nuc_sep;
989
990 bssp->seq_set = seg_sep;
991 seg_sep->next = prot_list;
992 }
993
994 /* if the set we have converted to a segset used to be our genbank wrapper,
995 * create a new genbank wrapper
996 */
997 if (parentptr == NULL)
998 {
999 tmp_sep = SeqEntryNew ();
1000 tmp_sep->choice = sep->choice;
1001 tmp_sep->data.ptrvalue = sep->data.ptrvalue;
1002 wrapper_bssp = BioseqSetNew ();
1003 wrapper_bssp->_class = BioseqseqSet_class_genbank;
1004 wrapper_bssp->seq_set = tmp_sep;
1005 sep->choice = 2;
1006 sep->data.ptrvalue = wrapper_bssp;
1007 }
1008
1009 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
1010 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
1011
1012 UpdateOneSegSet (seg_bssp, intersperse_nulls);
1013 }
1014
IsFlatNucProtSet(BioseqSetPtr bssp)1015 static Boolean IsFlatNucProtSet (BioseqSetPtr bssp)
1016 {
1017 SeqEntryPtr this_sep;
1018
1019 if (bssp == NULL || bssp->seq_set == NULL
1020 || bssp->_class != BioseqseqSet_class_nuc_prot)
1021 {
1022 return FALSE;
1023 }
1024
1025 for (this_sep = bssp->seq_set; this_sep != NULL; this_sep = this_sep->next)
1026 {
1027 if (!IS_Bioseq (this_sep))
1028 {
1029 return FALSE;
1030 }
1031 }
1032 return TRUE;
1033 }
1034
NewSegFixup(SeqEntryPtr sep,Boolean intersperse_nulls)1035 static void NewSegFixup (SeqEntryPtr sep, Boolean intersperse_nulls)
1036 {
1037 BioseqSetPtr bssp, this_bssp;
1038 SeqEntryPtr this_sep;
1039 Boolean can_convert = TRUE;
1040
1041 if (sep == NULL || IS_Bioseq (sep))
1042 {
1043 return;
1044 }
1045
1046 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1047 if (bssp == NULL)
1048 {
1049 return;
1050 }
1051 else if (bssp->_class == BioseqseqSet_class_segset)
1052 {
1053 UpdateOneSegSet (bssp, intersperse_nulls);
1054 return;
1055 }
1056
1057 /* if all of the entries in bssp->seq_set are bioseqs or nuc_prot
1058 sets, then we can convert this to a segset */
1059 for (this_sep = bssp->seq_set;
1060 this_sep != NULL && can_convert;
1061 this_sep = this_sep->next)
1062 {
1063 if (IS_Bioseq_set (this_sep))
1064 {
1065 this_bssp = (BioseqSetPtr) this_sep->data.ptrvalue;
1066 if (!IsFlatNucProtSet (this_bssp))
1067 {
1068 can_convert = FALSE;
1069 }
1070 }
1071 else if (!IS_Bioseq (this_sep))
1072 {
1073 can_convert = FALSE;
1074 }
1075 }
1076
1077 if (can_convert)
1078 {
1079 ConvertOneSetToSegSet (sep, intersperse_nulls);
1080 }
1081 else
1082 {
1083 for (this_sep = bssp->seq_set;
1084 this_sep != NULL;
1085 this_sep = this_sep->next)
1086 {
1087 NewSegFixup (this_sep, intersperse_nulls);
1088 }
1089 }
1090 }
1091
1092 extern void DoFixupLocus (SeqEntryPtr sep);
1093 extern void DoFixupSegSet (SeqEntryPtr sep);
1094
NewUpdateSegSet(Pointer data)1095 static Int2 LIBCALLBACK NewUpdateSegSet (Pointer data)
1096
1097 {
1098 OMProcControlPtr ompcp;
1099 SeqEntryPtr sep;
1100 ErrSev sev;
1101 ModalAcceptCancelData acd;
1102 WindoW w;
1103 GrouP h, g, c;
1104 ButtoN intersperse_nulls_btn;
1105 ButtoN fix_locus_btn;
1106 ButtoN tax_fix_cleanup_btn;
1107 ButtoN b;
1108
1109 ompcp = (OMProcControlPtr) data;
1110 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
1111 switch (ompcp->input_itemtype) {
1112 case OBJ_BIOSEQ :
1113 break;
1114 case OBJ_BIOSEQSET :
1115 break;
1116 case 0 :
1117 return OM_MSG_RET_ERROR;
1118 default :
1119 return OM_MSG_RET_ERROR;
1120 }
1121 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
1122 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
1123 if (sep == NULL) return OM_MSG_RET_ERROR;
1124
1125 w = MovableModalWindow (-50, -33, -10, -10, "SegSet Conversion Options", NULL);
1126 h = HiddenGroup (w, -1, 0, NULL);
1127 SetGroupSpacing (h, 10, 10);
1128
1129 g = HiddenGroup (h, 0, 4, NULL);
1130 intersperse_nulls_btn = CheckBox (g, "Intersperse NULLS", NULL);
1131 SetStatus (intersperse_nulls_btn, TRUE);
1132 fix_locus_btn = CheckBox (g, "Force Locus Fixup", NULL);
1133 SetStatus (fix_locus_btn, TRUE);
1134 tax_fix_cleanup_btn = CheckBox (g, "Do Tax_Fix/Cleanup", NULL);
1135 SetStatus (tax_fix_cleanup_btn, TRUE);
1136
1137 acd.accepted = FALSE;
1138 acd.cancelled = FALSE;
1139 c = HiddenGroup (h, 4, 0, NULL);
1140 b = DefaultButton (c, "Accept", ModalAcceptButton);
1141 SetObjectExtra (b, &acd, NULL);
1142 b = PushButton (c, "Cancel", ModalCancelButton);
1143 SetObjectExtra (b, &acd, NULL);
1144
1145 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
1146 RealizeWindow (w);
1147 Show (w);
1148 Update ();
1149
1150 while (!acd.accepted && !acd.cancelled)
1151 {
1152 ProcessExternalEvent ();
1153 Update ();
1154 }
1155 ProcessAnEvent ();
1156 Hide (w);
1157 if (acd.cancelled)
1158 {
1159 Remove (w);
1160 return OM_MSG_RET_DONE;
1161 }
1162
1163 NewSegFixup (sep, GetStatus (intersperse_nulls_btn));
1164
1165 if (GetStatus (fix_locus_btn))
1166 {
1167 sev = ErrSetMessageLevel (SEV_FATAL);
1168 DoFixupLocus (sep);
1169 DoFixupSegSet (sep);
1170 ErrSetMessageLevel (sev);
1171 }
1172
1173 if (GetStatus (tax_fix_cleanup_btn))
1174 {
1175 ForceCleanupEntityID (ompcp->input_entityID);
1176 }
1177 Remove (w);
1178
1179 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
1180 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
1181 Update ();
1182 return OM_MSG_RET_DONE;
1183 }
1184
UpdateSegSet(Pointer data)1185 static Int2 LIBCALLBACK UpdateSegSet (Pointer data)
1186
1187 {
1188 OMProcControlPtr ompcp;
1189 SeqEntryPtr sep;
1190 ErrSev sev;
1191
1192 ompcp = (OMProcControlPtr) data;
1193 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
1194 switch (ompcp->input_itemtype) {
1195 case OBJ_BIOSEQ :
1196 break;
1197 case OBJ_BIOSEQSET :
1198 break;
1199 case 0 :
1200 return OM_MSG_RET_ERROR;
1201 default :
1202 return OM_MSG_RET_ERROR;
1203 }
1204 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
1205 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
1206 if (sep == NULL) return OM_MSG_RET_ERROR;
1207
1208 DoOneSegFixup (sep, TRUE);
1209 if (Message (MSG_YN, "Do you want to Force Locus Fixup?") == ANS_YES) {
1210 sev = ErrSetMessageLevel (SEV_FATAL);
1211 DoFixupLocus (sep);
1212 DoFixupSegSet (sep);
1213 ErrSetMessageLevel (sev);
1214 }
1215
1216 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
1217 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
1218 Update ();
1219 return OM_MSG_RET_DONE;
1220 }
1221
DoAdjustSegSeqLength(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)1222 static void DoAdjustSegSeqLength (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
1223
1224 {
1225 BioseqPtr bsp;
1226 ValNode head;
1227 Int4 len;
1228 Int4 len2;
1229 ValNodePtr vnp;
1230
1231 if (! IS_Bioseq (sep)) return;
1232 bsp = (BioseqPtr) sep->data.ptrvalue;
1233 if (bsp == NULL || bsp->repr != Seq_repr_seg) return;
1234 head.choice = SEQLOC_MIX;
1235 head.data.ptrvalue = bsp->seq_ext;
1236 head.next = NULL;
1237 vnp = NULL;
1238 len = 0;
1239 while ((vnp = SeqLocFindNext (&head, vnp)) != NULL) {
1240 len2 = SeqLocLen (vnp);
1241 if (len2 > 0) {
1242 len += len2;
1243 }
1244 }
1245 bsp->length = len;
1246 }
1247
AdjustSegSeqLength(Pointer data)1248 static Int2 LIBCALLBACK AdjustSegSeqLength (Pointer data)
1249
1250 {
1251 OMProcControlPtr ompcp;
1252 SeqEntryPtr sep;
1253
1254 ompcp = (OMProcControlPtr) data;
1255 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
1256 switch (ompcp->input_itemtype) {
1257 case OBJ_BIOSEQ :
1258 break;
1259 case OBJ_BIOSEQSET :
1260 break;
1261 case 0 :
1262 return OM_MSG_RET_ERROR;
1263 default :
1264 return OM_MSG_RET_ERROR;
1265 }
1266 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
1267 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
1268 if (sep == NULL) return OM_MSG_RET_ERROR;
1269 SeqEntryExplore (sep, NULL, DoAdjustSegSeqLength);
1270 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
1271 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
1272 return OM_MSG_RET_DONE;
1273 }
1274
1275
ReduceLocationToSingleBioseq(SeqLocPtr slp,BioseqPtr bsp)1276 static SeqLocPtr ReduceLocationToSingleBioseq (SeqLocPtr slp, BioseqPtr bsp)
1277 {
1278 SeqLocPtr this_slp, prev_slp, next_slp;
1279 BioseqPtr this_bsp;
1280 SeqIntPtr sint;
1281 ValNodePtr this_vnp, prev_vnp, next_vnp;
1282
1283 if (slp == NULL || bsp == NULL) return NULL;
1284
1285 if (slp->choice == SEQLOC_MIX)
1286 {
1287 this_slp = slp->data.ptrvalue;
1288 prev_slp = NULL;
1289 while (this_slp != NULL)
1290 {
1291 next_slp = this_slp->next;
1292 this_bsp = BioseqFind (SeqLocId (this_slp));
1293 if (this_bsp != bsp)
1294 {
1295 if (prev_slp == NULL)
1296 {
1297 slp->data.ptrvalue = next_slp;
1298 }
1299 else
1300 {
1301 prev_slp->next = next_slp;
1302 }
1303 this_slp->next = NULL;
1304 SeqLocFree (this_slp);
1305 }
1306 else
1307 {
1308 prev_slp = this_slp;
1309 }
1310 this_slp = next_slp;
1311 }
1312 if (slp->data.ptrvalue == NULL)
1313 {
1314 slp = SeqLocFree (slp);
1315 }
1316 else
1317 {
1318 this_slp = slp->data.ptrvalue;
1319 if (this_slp->next == NULL)
1320 {
1321 slp->data.ptrvalue = NULL;
1322 slp = SeqLocFree (slp);
1323 slp = this_slp;
1324 }
1325 }
1326 }
1327 else if (slp->choice == SEQLOC_PACKED_INT)
1328 {
1329 prev_vnp = NULL;
1330 this_vnp = slp->data.ptrvalue;
1331 while (this_vnp != NULL)
1332 {
1333 next_vnp = this_vnp->next;
1334 sint = this_vnp->data.ptrvalue;
1335 this_bsp = BioseqFind (sint->id);
1336 if (this_bsp != bsp)
1337 {
1338 if (prev_vnp == NULL) {
1339 slp->data.ptrvalue = next_vnp;
1340 } else {
1341 prev_vnp->next = next_vnp;
1342 }
1343 this_vnp->next = NULL;
1344 sint = SeqIntFree (sint);
1345 this_vnp = ValNodeFree (this_vnp);
1346 } else {
1347 prev_vnp = this_vnp;
1348 }
1349 this_vnp = next_vnp;
1350 }
1351 if (slp->data.ptrvalue == NULL)
1352 {
1353 slp = SeqLocFree (slp);
1354 }
1355 }
1356 else
1357 {
1358 this_bsp = BioseqFind (SeqLocId (slp));
1359 if (this_bsp != bsp)
1360 {
1361 slp = SeqLocFree (slp);
1362 }
1363 }
1364 return slp;
1365 }
1366
RemoveBioseqFromLocation(SeqLocPtr slp,BioseqPtr bsp)1367 static SeqLocPtr RemoveBioseqFromLocation (SeqLocPtr slp, BioseqPtr bsp)
1368 {
1369 SeqLocPtr this_slp, prev_slp, next_slp;
1370 BioseqPtr this_bsp;
1371 SeqIntPtr sint;
1372 ValNodePtr this_vnp, prev_vnp, next_vnp;
1373
1374 if (slp == NULL || bsp == NULL) return NULL;
1375
1376 if (slp->choice == SEQLOC_MIX)
1377 {
1378 this_slp = slp->data.ptrvalue;
1379 prev_slp = NULL;
1380 while (this_slp != NULL)
1381 {
1382 next_slp = this_slp->next;
1383 this_bsp = BioseqFind (SeqLocId (this_slp));
1384 if (this_bsp == bsp)
1385 {
1386 if (prev_slp == NULL)
1387 {
1388 slp->data.ptrvalue = next_slp;
1389 }
1390 else
1391 {
1392 prev_slp->next = next_slp;
1393 }
1394 this_slp->next = NULL;
1395 SeqLocFree (this_slp);
1396 }
1397 else
1398 {
1399 prev_slp = this_slp;
1400 }
1401 this_slp = next_slp;
1402 }
1403 if (slp->data.ptrvalue == NULL)
1404 {
1405 slp = SeqLocFree (slp);
1406 }
1407 else
1408 {
1409 this_slp = slp->data.ptrvalue;
1410 if (this_slp->next == NULL)
1411 {
1412 slp->data.ptrvalue = NULL;
1413 slp = SeqLocFree (slp);
1414 slp = this_slp;
1415 }
1416 }
1417 }
1418 else if (slp->choice == SEQLOC_PACKED_INT)
1419 {
1420 prev_vnp = NULL;
1421 this_vnp = slp->data.ptrvalue;
1422 while (this_vnp != NULL)
1423 {
1424 next_vnp = this_vnp->next;
1425 sint = this_vnp->data.ptrvalue;
1426 this_bsp = BioseqFind (sint->id);
1427 if (this_bsp == bsp)
1428 {
1429 if (prev_vnp == NULL) {
1430 slp->data.ptrvalue = next_vnp;
1431 } else {
1432 prev_vnp->next = next_vnp;
1433 }
1434 this_vnp->next = NULL;
1435 sint = SeqIntFree (sint);
1436 this_vnp = ValNodeFree (this_vnp);
1437 } else {
1438 prev_vnp = this_vnp;
1439 }
1440 this_vnp = next_vnp;
1441 }
1442 if (slp->data.ptrvalue == NULL)
1443 {
1444 slp = SeqLocFree (slp);
1445 }
1446 }
1447 else
1448 {
1449 this_bsp = BioseqFind (SeqLocId (slp));
1450 if (this_bsp == bsp)
1451 {
1452 slp = SeqLocFree (slp);
1453 }
1454 }
1455 return slp;
1456 }
1457
PushFeaturesDownToBioseq(SeqAnnotPtr annot,SeqEntryPtr sep)1458 static void PushFeaturesDownToBioseq (SeqAnnotPtr annot, SeqEntryPtr sep)
1459 {
1460 BioseqSetPtr bssp;
1461 BioseqPtr bsp;
1462 SeqFeatPtr sfp, prev_sfp, last_sfp, next_sfp;
1463
1464 if (annot == NULL || annot->type != 1 || sep == NULL) return;
1465
1466 if (IS_Bioseq_set (sep)) {
1467 bssp = sep->data.ptrvalue;
1468 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
1469 PushFeaturesDownToBioseq (annot, sep);
1470 }
1471 return;
1472 }
1473
1474 if (! IS_Bioseq (sep)) return;
1475
1476 bsp = sep->data.ptrvalue;
1477
1478 sfp = annot->data;
1479 prev_sfp = NULL;
1480 while (sfp != NULL) {
1481 next_sfp = sfp->next;
1482 while (sfp != NULL && ! SeqIdIn (SeqLocId (sfp->location), bsp->id)) {
1483 prev_sfp = sfp;
1484 sfp = sfp->next;
1485 if (sfp != NULL) {
1486 next_sfp = sfp->next;
1487 }
1488 }
1489 if (sfp != NULL) {
1490 if (bsp->annot == NULL) {
1491 bsp->annot = SeqAnnotNew ();
1492 bsp->annot->type = 1;
1493 bsp->annot->data = sfp;
1494 } else {
1495 if (bsp->annot->data == NULL) {
1496 bsp->annot->data = sfp;
1497 } else {
1498 last_sfp = bsp->annot->data;
1499 while (last_sfp->next != NULL) {
1500 last_sfp = last_sfp->next;
1501 }
1502 last_sfp->next = sfp;
1503 }
1504 }
1505 if (prev_sfp == NULL) {
1506 annot->data = sfp->next;
1507 } else {
1508 prev_sfp->next = sfp->next;
1509 }
1510 sfp->next = NULL;
1511 sfp = next_sfp;
1512 }
1513 }
1514 }
1515
1516 static void
SplitSegmentedProduct(BioseqPtr old_protein,BioseqPtr new_protein,Int4 protein_offset)1517 SplitSegmentedProduct
1518 (BioseqPtr old_protein,
1519 BioseqPtr new_protein,
1520 Int4 protein_offset)
1521 {
1522 SeqFeatPtr sfp, copy_sfp, new_sfp;
1523 SeqMgrFeatContext fcontext;
1524 Int4 right_end;
1525 SeqLoc subtract_loc;
1526 SeqInt sint;
1527 Boolean partial3;
1528 Boolean partial5;
1529
1530 if (new_protein == NULL)
1531 {
1532 return;
1533 }
1534
1535 /* delete full length feature on new protein */
1536 sfp = SeqMgrGetNextFeature (new_protein, NULL, 0, 0, &fcontext);
1537 if (sfp != NULL)
1538 {
1539 sfp->idx.deleteme = TRUE;
1540 }
1541
1542 right_end = protein_offset + new_protein->length - 1;
1543
1544 /* if there are features on the original protein product
1545 * other than the full-length feature, we need to find the offsets
1546 * so that we can determine whether they belong in this product.
1547 */
1548 sfp = SeqMgrGetNextFeature (old_protein, NULL, 0, 0, &fcontext);
1549 while (sfp != NULL)
1550 {
1551 new_sfp = NULL;
1552 if ((fcontext.left == 0 && fcontext.right == old_protein->length - 1)
1553 || (fcontext.left <= protein_offset && fcontext.right >= right_end))
1554 {
1555 copy_sfp = SeqFeatCopy (sfp);
1556 new_sfp = CreateNewFeatureOnBioseq (new_protein, copy_sfp->data.choice, NULL);
1557 new_sfp->data.value.ptrvalue = copy_sfp->data.value.ptrvalue;
1558 copy_sfp->data.value.ptrvalue = NULL;
1559 copy_sfp = SeqFeatFree (copy_sfp);
1560 }
1561 else if ((fcontext.left <= protein_offset && fcontext.right >= protein_offset)
1562 || (fcontext.left <= right_end && fcontext.right >= right_end)
1563 || (fcontext.left >= protein_offset && fcontext.right <= protein_offset))
1564 {
1565 copy_sfp = SeqFeatCopy (sfp);
1566 new_sfp = CreateNewFeatureOnBioseq (new_protein, copy_sfp->data.choice, NULL);
1567 new_sfp->data.value.ptrvalue = copy_sfp->data.value.ptrvalue;
1568 copy_sfp->data.value.ptrvalue = NULL;
1569 copy_sfp = SeqFeatFree (copy_sfp);
1570 subtract_loc.next = NULL;
1571 subtract_loc.choice = SEQLOC_INT;
1572 subtract_loc.data.ptrvalue = &sint;
1573 sint.id = new_protein->id;
1574 sint.strand = Seq_strand_plus;
1575 sint.if_from = NULL;
1576 sint.if_to = NULL;
1577
1578 /* chop off left end if needed */
1579 if (fcontext.left > protein_offset)
1580 {
1581 sint.from = 0;
1582 sint.to = fcontext.left - protein_offset - 1;
1583 new_sfp->location = SeqLocSubtract (new_sfp->location, &subtract_loc);
1584 }
1585 /* chop off right end if needed */
1586 if (fcontext.right < right_end)
1587 {
1588 sint.from = fcontext.right - protein_offset + 1;
1589 sint.to = new_protein->length - 1;
1590 new_sfp->location = SeqLocSubtract (new_sfp->location, &subtract_loc);
1591 }
1592 }
1593 if (new_sfp != NULL)
1594 {
1595 partial3 = FALSE;
1596 partial5 = FALSE;
1597 if (fcontext.left < protein_offset)
1598 {
1599 partial5 = TRUE;
1600 }
1601 if (fcontext.right > right_end)
1602 {
1603 partial3 = TRUE;
1604 }
1605
1606 if (partial3 || partial5)
1607 {
1608 SetSeqLocPartial (new_sfp->location, partial5, partial3);
1609 new_sfp->partial = TRUE;
1610 }
1611
1612 }
1613 sfp = SeqMgrGetNextFeature (old_protein, sfp, 0, 0, &fcontext);
1614 }
1615 }
1616
SplitSegmentedFeatsOnOneSet(BioseqSetPtr set)1617 static void SplitSegmentedFeatsOnOneSet (BioseqSetPtr set)
1618 {
1619 SeqAnnotPtr annot, prev_annot, next_annot;
1620 SeqFeatPtr sfp, new_sfp, prev_sfp, next_sfp;
1621 SeqEntryPtr sep, set_sep;
1622 BioseqPtr bsp, last_bsp;
1623 SeqLocPtr loc, slp;
1624 Int4 product_offset, protein_offset;
1625 Boolean is_first = TRUE;
1626 SeqIdPtr sip;
1627 CdRegionPtr crp;
1628 Boolean partial3, partial5;
1629 Int4 len_modulo, new_frame;
1630
1631 if (set == NULL || set->annot == NULL) return;
1632
1633 set_sep = SeqMgrGetSeqEntryForData (set);
1634
1635 prev_annot = NULL;
1636 annot = set->annot;
1637 next_annot = annot->next;
1638 while (annot != NULL) {
1639 next_annot = annot->next;
1640 if (annot->type != 1) {
1641 prev_annot = annot;
1642 annot = next_annot;
1643 continue;
1644 }
1645 sfp = annot->data;
1646 while (sfp != NULL) {
1647 next_sfp = sfp->next;
1648 prev_sfp = sfp;
1649 loc = SeqLocFindNext (sfp->location, NULL);
1650 sip = SeqLocId (loc);
1651 last_bsp = BioseqFind (sip);
1652
1653 product_offset = 0;
1654 slp = SeqLocFindNext (sfp->location, loc);
1655 while (slp != NULL) {
1656 bsp = BioseqFind (SeqLocId (slp));
1657 if (bsp != last_bsp && last_bsp != NULL) {
1658 new_sfp = SeqFeatCopy (sfp);
1659 new_sfp->location = ReduceLocationToSingleBioseq (new_sfp->location, last_bsp);
1660 sfp->location = RemoveBioseqFromLocation (sfp->location, last_bsp);
1661 if (is_first)
1662 {
1663 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
1664 SetSeqLocPartial (sfp->location, TRUE, partial3);
1665 is_first = FALSE;
1666 sfp->partial = TRUE;
1667 SetSeqLocPartial (new_sfp->location, partial5, TRUE);
1668 new_sfp->partial = TRUE;
1669 }
1670 else
1671 {
1672 SetSeqLocPartial (new_sfp->location, TRUE, TRUE);
1673 new_sfp->partial = TRUE;
1674 }
1675
1676 if (sfp->data.choice == SEQFEAT_CDREGION && sfp->product != NULL)
1677 {
1678 /* now figure out protein offset, to use for copying protein features */
1679 if (SeqLocStrand (new_sfp->location) == Seq_strand_minus)
1680 {
1681 /* if on minus strand, offset is length of remaining location */
1682 protein_offset = SeqLocLen (sfp->location) / 3;
1683 len_modulo = SeqLocLen (sfp->location) % 3;
1684 }
1685 else
1686 {
1687 /* if on plus strand, offset is locations already removed */
1688 protein_offset = product_offset / 3;
1689 len_modulo = (product_offset + SeqLocLen (new_sfp->location)) % 3;
1690 }
1691 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
1692 if (crp != NULL && (crp->frame == 2 || crp->frame == 3))
1693 {
1694 protein_offset --;
1695 }
1696
1697 /* correct frame */
1698 if (crp != NULL) {
1699 new_frame = 0;
1700 if (len_modulo == 0)
1701 {
1702 new_frame = crp->frame;
1703 }
1704 else if (crp->frame == 0 || crp->frame == 1)
1705 {
1706 if (len_modulo == 1)
1707 {
1708 new_frame = 2;
1709 }
1710 else
1711 {
1712 /* len_modulo == 2 */
1713 new_frame = 3;
1714 }
1715 }
1716 else if (len_modulo == 1)
1717 {
1718 if (crp->frame == 2)
1719 {
1720 new_frame = 1;
1721 }
1722 else
1723 {
1724 /* crp->frame == 3 */
1725 new_frame = 2;
1726 }
1727
1728 }
1729 else if (len_modulo == 2)
1730 {
1731 if (crp->frame == 2)
1732 {
1733 new_frame = 3;
1734 }
1735 else
1736 {
1737 /* crp->frame == 3 */
1738 new_frame = 1;
1739 }
1740 }
1741 crp->frame = new_frame;
1742 }
1743
1744 new_sfp->product = SeqLocFree (new_sfp->product);
1745 SeqEdTranslateOneCDS (new_sfp, last_bsp, sfp->idx.entityID, Sequin_GlobalAlign2Seq);
1746
1747 SplitSegmentedProduct (BioseqFindFromSeqLoc (sfp->product),
1748 BioseqFindFromSeqLoc (new_sfp->product),
1749 protein_offset);
1750 ResynchCDSPartials (new_sfp, NULL);
1751 }
1752
1753 prev_sfp->next = new_sfp;
1754 new_sfp->next = next_sfp;
1755 prev_sfp = new_sfp;
1756 product_offset += SeqLocLen (slp);
1757 slp = SeqLocFindNext (sfp->location, NULL);
1758 last_bsp = bsp;
1759 } else {
1760 product_offset += SeqLocLen (slp);
1761 slp = SeqLocFindNext (sfp->location, slp);
1762 }
1763 }
1764 if (sfp->location == NULL)
1765 {
1766 sfp->idx.deleteme = TRUE;
1767 }
1768 else if (!is_first)
1769 {
1770 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
1771 SetSeqLocPartial (sfp->location, TRUE, partial3);
1772 sfp->partial = TRUE;
1773 if (sfp->data.choice == SEQFEAT_CDREGION && sfp->product != NULL)
1774 {
1775 SeqEdTranslateOneCDS (sfp, last_bsp, sfp->idx.entityID, Sequin_GlobalAlign2Seq);
1776
1777 ResynchCDSPartials (sfp, NULL);
1778 }
1779 }
1780 sfp = next_sfp;
1781 }
1782
1783 /* push features to appropriate bioseqs */
1784 for (sep = set->seq_set; sep != NULL; sep = sep->next) {
1785 PushFeaturesDownToBioseq (annot, sep);
1786 }
1787 if (prev_annot == NULL) {
1788 set->annot = annot->next;
1789 } else {
1790 prev_annot->next = annot->next;
1791 }
1792 annot->next = NULL;
1793 SeqAnnotFree (annot);
1794 annot = next_annot;
1795 }
1796 }
1797
SplitSegmentedFeats(SeqEntryPtr sep,Uint2 entityID)1798 static void SplitSegmentedFeats (SeqEntryPtr sep, Uint2 entityID)
1799 {
1800 BioseqSetPtr bssp;
1801
1802 if (IS_Bioseq_set (sep)) {
1803 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1804 SplitSegmentedFeatsOnOneSet (bssp);
1805 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
1806 SplitSegmentedFeats (sep, entityID);
1807 }
1808 }
1809 DeleteMarkedObjects (entityID, 0, NULL);
1810 }
1811
SplitSegmentedFeatsMenuItem(IteM i)1812 extern void SplitSegmentedFeatsMenuItem (IteM i)
1813 {
1814 BaseFormPtr bfp;
1815 SeqEntryPtr sep;
1816
1817 #ifdef WIN_MAC
1818 bfp = currentFormDataPtr;
1819 #else
1820 bfp = GetObjectExtra (i);
1821 #endif
1822 if (bfp == NULL) return;
1823 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1824 if (sep == NULL) return;
1825 SplitSegmentedFeats (sep, bfp->input_entityID);
1826 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1827 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1828
1829 }
1830
DoSegSetUndo(BioseqPtr segseq,BioseqSetPtr parts,BioseqSetPtr segset,Uint2 entityID)1831 static void DoSegSetUndo (BioseqPtr segseq, BioseqSetPtr parts, BioseqSetPtr segset, Uint2 entityID)
1832
1833 {
1834 SeqAnnotPtr annot;
1835 ValNodePtr descr;
1836 SeqAnnotPtr sap;
1837 SeqEntryPtr tmp;
1838 SeqEntryPtr split_sep;
1839 Uint2 parenttype;
1840 Pointer parentptr;
1841 BioseqSetPtr parent_bssp = NULL;
1842
1843 if (segseq == NULL || parts == NULL || parts->seq_set == NULL || segset == NULL) return;
1844
1845 /* split segmented features before undoing segset */
1846 split_sep = SeqMgrGetSeqEntryForData (segset);
1847 GetSeqEntryParent (split_sep, &parentptr, &parenttype);
1848 if (parenttype == OBJ_BIOSEQSET && parentptr != NULL)
1849 {
1850 parent_bssp = (BioseqSetPtr) parentptr;
1851 if (parent_bssp->_class == BioseqseqSet_class_nuc_prot)
1852 {
1853 split_sep = SeqMgrGetSeqEntryForData (parent_bssp);
1854 }
1855 }
1856 SplitSegmentedFeats (split_sep, entityID);
1857
1858 segset->_class = 7;
1859 parts->_class = 14;
1860 annot = segseq->annot;
1861 segseq->annot = NULL;
1862 if (segset->annot == NULL) {
1863 segset->annot = annot;
1864 annot = NULL;
1865 } else {
1866 sap = segset->annot;
1867 while (sap->next != NULL) {
1868 sap = sap->next;
1869 }
1870 sap->next = annot;
1871 }
1872 descr = segseq->descr;
1873 segseq->descr = NULL;
1874 ValNodeLink (&(segset->descr), descr);
1875 tmp = segset->seq_set;
1876 if (tmp != NULL && IS_Bioseq (tmp)) {
1877 segset->seq_set = tmp->next;
1878 tmp->next = NULL;
1879 SeqEntryFree (tmp);
1880 }
1881
1882 /* propagate the descriptors on the segset to the parts in the set */
1883 SetDescriptorPropagate (segset);
1884 SetDescriptorPropagate (parts);
1885
1886 }
1887
DoOneSegUndo(SeqEntryPtr sep,Uint2 entityID)1888 static Int2 DoOneSegUndo (SeqEntryPtr sep, Uint2 entityID)
1889
1890 {
1891 BioseqSetPtr bssp;
1892 Int2 count = 0;
1893 UpdateSegStruc uss;
1894
1895 if (sep == NULL) return 0;
1896 if (IS_Bioseq_set (sep)) {
1897 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1898 if (bssp != NULL && (bssp->_class == 7 ||
1899 (IsPopPhyEtcSet (bssp->_class)))) {
1900 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
1901 count += DoOneSegUndo (sep, entityID);
1902 }
1903 return count;
1904 }
1905 }
1906
1907 uss.segseq = NULL;
1908 uss.parts = NULL;
1909 uss.segset = NULL;
1910 UpdateSegExplore (sep, (Pointer) &uss, FindSegSetComponentsCallback);
1911 if (uss.segseq != NULL && uss.parts != NULL && uss.segset != NULL) {
1912 DoSegSetUndo (uss.segseq, uss.parts, uss.segset, entityID);
1913 return 1;
1914 }
1915 return 0;
1916 }
1917
BioseqExtract(SeqEntryPtr top,BioseqPtr bsp)1918 static SeqEntryPtr BioseqExtract (SeqEntryPtr top, BioseqPtr bsp)
1919
1920 {
1921 BioseqSetPtr bssp;
1922 SeqEntryPtr next;
1923 SeqEntryPtr PNTR prev;
1924 SeqEntryPtr rsult = NULL;
1925 SeqEntryPtr sep;
1926
1927 if (top == NULL || bsp == NULL) return NULL;
1928 if (! IS_Bioseq_set (top)) return NULL;
1929 bssp = (BioseqSetPtr) top->data.ptrvalue;
1930 if (bssp == NULL) return NULL;
1931 prev = &(bssp->seq_set);
1932 sep = bssp->seq_set;
1933 while (sep != NULL) {
1934 next = sep->next;
1935 if (IS_Bioseq_set (sep)) {
1936 rsult = BioseqExtract (sep, bsp);
1937 if (rsult != NULL) {
1938 return rsult;
1939 }
1940 prev = &(sep->next);
1941 sep = next;
1942 } else if (IS_Bioseq (sep) && sep->data.ptrvalue == (Pointer) bsp) {
1943 *(prev) = next;
1944 sep->next = NULL;
1945 return sep;
1946 } else {
1947 prev = &(sep->next);
1948 sep = next;
1949 }
1950 }
1951 return NULL;
1952 }
1953
DoRepairPartsSet(SeqEntryPtr sep)1954 static void DoRepairPartsSet (SeqEntryPtr sep)
1955
1956 {
1957 BioseqPtr bsp;
1958 BioseqSetPtr bssp;
1959 ValNode head;
1960 BioseqSetPtr parts;
1961 BioseqPtr segseq;
1962 SeqLocPtr slp;
1963 SeqEntryPtr tmp;
1964 UpdateSegStruc uss;
1965
1966 if (sep == NULL) return;
1967 if (IS_Bioseq (sep)) return;
1968 if (IS_Bioseq_set (sep)) {
1969 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1970 if (bssp == NULL) return;
1971 if (bssp->_class == 7 ||
1972 (IsPopPhyEtcSet (bssp->_class))) {
1973 for (tmp = bssp->seq_set; tmp != NULL; tmp = tmp->next) {
1974 DoRepairPartsSet (tmp);
1975 }
1976 return;
1977 }
1978 }
1979 uss.segseq = NULL;
1980 uss.parts = NULL;
1981 uss.segset = NULL;
1982 UpdateSegExplore (sep, (Pointer) &uss, FindSegSetComponentsCallback);
1983 if (uss.segseq == NULL || uss.parts == NULL || uss.segset == NULL) return;
1984 segseq = uss.segseq;
1985 parts = uss.parts;
1986 if (segseq->repr != Seq_repr_seg ||
1987 segseq->seq_ext_type != 1 ||
1988 segseq->seq_ext == NULL) return;
1989 head.choice = SEQLOC_MIX;
1990 head.data.ptrvalue = segseq->seq_ext;
1991 head.next = NULL;
1992 slp = NULL;
1993 while ((slp = SeqLocFindNext (&head, slp)) != NULL) {
1994 bsp = BioseqFind (SeqLocId (slp));
1995 if (bsp != NULL) {
1996 tmp = BioseqExtract (sep, bsp);
1997 if (tmp != NULL) {
1998 ValNodeLink (&parts->seq_set, tmp);
1999 }
2000 }
2001 }
2002 }
2003
2004
RepackageParksInPartsSetForEntityID(Uint2 entityID)2005 static void RepackageParksInPartsSetForEntityID (Uint2 entityID)
2006 {
2007 ObjMgrDataPtr omdptop;
2008 ObjMgrData omdata;
2009 Uint2 parenttype;
2010 Pointer parentptr;
2011 SeqEntryPtr sep;
2012
2013 sep = GetTopSeqEntryForEntityID (entityID);
2014 if (sep == NULL) return;
2015 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
2016 GetSeqEntryParent (sep, &parentptr, &parenttype);
2017 DoRepairPartsSet (sep);
2018 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
2019 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
2020 ObjMgrSetDirtyFlag (entityID, TRUE);
2021 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
2022 }
2023
2024
PackagePartsInPartsSet(Pointer data)2025 static Int2 LIBCALLBACK PackagePartsInPartsSet (Pointer data)
2026
2027 {
2028 OMProcControlPtr ompcp;
2029
2030 ompcp = (OMProcControlPtr) data;
2031 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
2032 switch (ompcp->input_itemtype) {
2033 case OBJ_BIOSEQ :
2034 break;
2035 case OBJ_BIOSEQSET :
2036 break;
2037 case 0 :
2038 return OM_MSG_RET_ERROR;
2039 default :
2040 return OM_MSG_RET_ERROR;
2041 }
2042 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
2043 RepackageParksInPartsSetForEntityID (ompcp->input_entityID);
2044 return OM_MSG_RET_DONE;
2045 }
2046
2047
RepackagePartsMenuItem(IteM i)2048 NLM_EXTERN void RepackagePartsMenuItem (IteM i)
2049 {
2050 BaseFormPtr bfp;
2051
2052 #ifdef WIN_MAC
2053 bfp = currentFormDataPtr;
2054 #else
2055 bfp = GetObjectExtra (i);
2056 #endif
2057 if (bfp == NULL) return;
2058 RepackageParksInPartsSetForEntityID (bfp->input_entityID);
2059 }
2060
2061
RemoveDupGenBankSets(SeqEntryPtr sep)2062 NLM_EXTERN void RemoveDupGenBankSets (SeqEntryPtr sep)
2063
2064 {
2065 SeqAnnotPtr annot;
2066 BioseqSetPtr bssp;
2067 ValNodePtr descr;
2068 SeqAnnotPtr sap;
2069 SeqEntryPtr tmp;
2070 BioseqSetPtr tmpbssp;
2071
2072 if (sep == NULL || ! IS_Bioseq_set (sep)) return;
2073 bssp = (BioseqSetPtr) sep->data.ptrvalue;
2074 if (bssp == NULL || bssp->_class != 7) return;
2075 tmp = bssp->seq_set;
2076 if (tmp == NULL || ! IS_Bioseq_set (tmp) || tmp->next != NULL) return;
2077 tmpbssp = (BioseqSetPtr) tmp->data.ptrvalue;
2078 if (tmpbssp == NULL || tmpbssp->_class != 7 || tmpbssp->seq_set == NULL) return;
2079 annot = tmpbssp->annot;
2080 tmpbssp->annot = NULL;
2081 if (bssp->annot == NULL) {
2082 bssp->annot = annot;
2083 annot = NULL;
2084 } else {
2085 sap = bssp->annot;
2086 while (sap->next != NULL) {
2087 sap = sap->next;
2088 }
2089 sap->next = annot;
2090 }
2091 descr = tmpbssp->descr;
2092 tmpbssp->descr = NULL;
2093 ValNodeLink (&(bssp->descr), descr);
2094 bssp->seq_set = tmpbssp->seq_set;
2095 tmpbssp->seq_set = NULL;
2096 SeqEntryFree (tmp);
2097 }
2098
UndoSegSet(Pointer data)2099 static Int2 LIBCALLBACK UndoSegSet (Pointer data)
2100
2101 {
2102 Int2 count;
2103 ObjMgrDataPtr omdptop;
2104 ObjMgrData omdata;
2105 OMProcControlPtr ompcp;
2106 Uint2 parenttype;
2107 Pointer parentptr;
2108 SeqEntryPtr sep;
2109
2110 ompcp = (OMProcControlPtr) data;
2111 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
2112 switch (ompcp->input_itemtype) {
2113 case OBJ_BIOSEQ :
2114 break;
2115 case OBJ_BIOSEQSET :
2116 break;
2117 case 0 :
2118 return OM_MSG_RET_ERROR;
2119 default :
2120 break;
2121 }
2122 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
2123 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
2124 if (sep == NULL) return OM_MSG_RET_ERROR;
2125 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
2126 GetSeqEntryParent (sep, &parentptr, &parenttype);
2127 count = DoOneSegUndo (sep, ompcp->input_entityID);
2128 RemoveDupGenBankSets (sep);
2129 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
2130 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
2131 if (count > 0) {
2132 PropagateFromGenBankBioseqSet (sep, FALSE);
2133 SeqMgrClearFeatureIndexes (ompcp->input_entityID, NULL);
2134 SeqMgrIndexFeatures (ompcp->input_entityID, NULL);
2135 SplitSegmentedFeats (sep, ompcp->input_entityID);
2136 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
2137 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
2138 }
2139 return OM_MSG_RET_DONE;
2140 }
2141
2142 static Boolean
ProteinUsedForThisSegmentInThisAnnotList(SeqEntryPtr seg_sep,SeqEntryPtr prot_sep,SeqAnnotPtr sap)2143 ProteinUsedForThisSegmentInThisAnnotList
2144 (SeqEntryPtr seg_sep,
2145 SeqEntryPtr prot_sep,
2146 SeqAnnotPtr sap)
2147 {
2148 SeqFeatPtr sfp;
2149 BioseqPtr seg_bsp, prot_bsp;
2150 SeqIdPtr loc_id, prot_id;
2151
2152 if (seg_sep == NULL || ! IS_Bioseq (seg_sep) || seg_sep->data.ptrvalue == NULL
2153 || prot_sep == NULL || ! IS_Bioseq (prot_sep) || prot_sep->data.ptrvalue == NULL
2154 || sap == NULL)
2155 {
2156 return FALSE;
2157 }
2158
2159 seg_bsp = seg_sep->data.ptrvalue;
2160 prot_bsp = prot_sep->data.ptrvalue;
2161
2162 if (sap->type == 1)
2163 {
2164 sfp = sap->data;
2165 while (sfp != NULL)
2166 {
2167 loc_id = SeqLocId (sfp->location);
2168 prot_id = SeqLocId (sfp->product);
2169 if (SeqIdIn (loc_id, seg_bsp->id) && SeqIdIn (prot_id, prot_bsp->id))
2170 {
2171 return TRUE;
2172 }
2173 sfp = sfp->next;
2174 }
2175 }
2176 return ProteinUsedForThisSegmentInThisAnnotList (seg_sep, prot_sep, sap->next);
2177 }
2178
RemoveIntermediateGenBankWrapper(BioseqSetPtr bssp)2179 static void RemoveIntermediateGenBankWrapper (BioseqSetPtr bssp)
2180 {
2181 SeqEntryPtr this_sep, next_sep, prev_sep, last_mem_sep;
2182 Uint2 parenttype;
2183 Pointer parentptr;
2184 BioseqSetPtr parent_bssp;
2185
2186 if (bssp == NULL || bssp->_class != BioseqseqSet_class_genbank)
2187 {
2188 return;
2189 }
2190 this_sep = SeqMgrGetSeqEntryForData (bssp);
2191 GetSeqEntryParent (this_sep, &parentptr, &parenttype);
2192 if (parenttype != OBJ_BIOSEQSET || parentptr == NULL)
2193 {
2194 return;
2195 }
2196 parent_bssp = (BioseqSetPtr) parentptr;
2197
2198 if (parent_bssp->_class != BioseqseqSet_class_genbank)
2199 {
2200 return;
2201 }
2202
2203 /* propagate descriptors on our original set to its members */
2204 SetDescriptorPropagate (bssp);
2205
2206 /* put the set members in the parent list where the set was */
2207 last_mem_sep = bssp->seq_set;
2208 while (last_mem_sep != NULL && last_mem_sep->next != NULL)
2209 {
2210 last_mem_sep = last_mem_sep->next;
2211 }
2212
2213 next_sep = this_sep->next;
2214 this_sep->next = NULL;
2215
2216 if (parent_bssp->seq_set == this_sep)
2217 {
2218 if (last_mem_sep == NULL)
2219 {
2220 parent_bssp->seq_set = next_sep;
2221 }
2222 else
2223 {
2224 parent_bssp->seq_set = bssp->seq_set;
2225 last_mem_sep->next = next_sep;
2226 }
2227 }
2228 else
2229 {
2230 prev_sep = parent_bssp->seq_set;
2231 while (prev_sep->next != this_sep)
2232 {
2233 prev_sep = prev_sep->next;
2234 }
2235 if (last_mem_sep == NULL)
2236 {
2237 prev_sep->next = next_sep;
2238 }
2239 else
2240 {
2241 prev_sep->next = bssp->seq_set;
2242 last_mem_sep->next = next_sep;
2243 }
2244 }
2245
2246 bssp->seq_set = NULL;
2247 SeqEntryFree (this_sep);
2248 }
2249
SetContainsProteins(BioseqSetPtr bssp)2250 static Boolean SetContainsProteins (BioseqSetPtr bssp)
2251 {
2252 BioseqPtr bsp;
2253 SeqEntryPtr sep;
2254 Boolean has_proteins = FALSE;
2255
2256 if (bssp == NULL || bssp->seq_set == NULL)
2257 {
2258 return FALSE;
2259 }
2260
2261 for (sep = bssp->seq_set; sep != NULL && !has_proteins; sep = sep->next)
2262 {
2263 if (sep->data.ptrvalue == NULL)
2264 {
2265 continue;
2266 }
2267 if (IS_Bioseq (sep))
2268 {
2269 bsp = (BioseqPtr) sep->data.ptrvalue;
2270 if (ISA_aa (bsp->mol))
2271 {
2272 has_proteins = TRUE;
2273 }
2274 }
2275 else if (IS_Bioseq_set (sep))
2276 {
2277 has_proteins |= SetContainsProteins (sep->data.ptrvalue);
2278 }
2279 }
2280 return has_proteins;
2281 }
2282
2283 static void
RemoveOneSegSet(SeqEntryPtr this_sep,BioseqSetPtr parent_bssp,BioseqSetPtr target_bssp,Uint2 entityID)2284 RemoveOneSegSet
2285 (SeqEntryPtr this_sep,
2286 BioseqSetPtr parent_bssp,
2287 BioseqSetPtr target_bssp,
2288 Uint2 entityID)
2289 {
2290 SeqEntryPtr protein_list = NULL;
2291 SeqEntryPtr seg_list, seg_sep, prot_sep;
2292 SeqEntryPtr prev_prot_sep, next_prot_sep;
2293 BioseqPtr seg_bsp;
2294 SeqEntryPtr this_prot_list, last_this;
2295 BioseqSetPtr seg_nuc_prot, seg_bssp;
2296 SeqEntryPtr next_seg;
2297
2298 if (this_sep == NULL)
2299 {
2300 return;
2301 }
2302
2303 DoOneSegUndo (this_sep, entityID);
2304 if (this_sep->choice != 2 || this_sep->data.ptrvalue == NULL)
2305 {
2306 return;
2307 }
2308
2309 target_bssp = (BioseqSetPtr) this_sep->data.ptrvalue;
2310
2311 if (parent_bssp != NULL
2312 && parent_bssp->_class == BioseqseqSet_class_nuc_prot
2313 && !SetContainsProteins (target_bssp))
2314 {
2315 seg_list = target_bssp->seq_set;
2316 target_bssp->seq_set = NULL;
2317
2318 protein_list = parent_bssp->seq_set->next;
2319 parent_bssp->seq_set->next = NULL;
2320
2321 /* parent_bssp->seq_set is this_sep */
2322 /* we've already moved everything out of this_sep, so we can free it now */
2323 parent_bssp->seq_set = SeqEntryFree (parent_bssp->seq_set);
2324 this_sep = NULL;
2325 target_bssp = NULL;
2326
2327 if (IS_Bioseq_set (seg_list))
2328 {
2329 this_sep = seg_list;
2330 target_bssp = seg_list->data.ptrvalue;
2331 seg_list = target_bssp->seq_set;
2332 target_bssp->seq_set = NULL;
2333 this_sep = SeqEntryFree (this_sep);
2334 target_bssp = NULL;
2335 }
2336
2337 for (seg_sep = seg_list; seg_sep != NULL; seg_sep = next_seg)
2338 {
2339 next_seg = seg_sep->next;
2340 if (!IS_Bioseq (seg_sep) || seg_sep->data.ptrvalue == NULL)
2341 {
2342 seg_bssp = (BioseqSetPtr) seg_sep->data.ptrvalue;
2343 continue;
2344 }
2345 seg_bsp = (BioseqPtr) seg_sep->data.ptrvalue;
2346 /* get the proteins from the parent set that go with this segment */
2347 this_prot_list = NULL;
2348 last_this = NULL;
2349 prot_sep = protein_list;
2350 prev_prot_sep = NULL;
2351 while (prot_sep != NULL)
2352 {
2353 next_prot_sep = prot_sep->next;
2354 if (ProteinUsedForThisSegmentInThisAnnotList (seg_sep, prot_sep, parent_bssp->annot)
2355 || ProteinUsedForThisSegmentInThisAnnotList (seg_sep, prot_sep, seg_bsp->annot))
2356 {
2357 /* remove from total list */
2358 if (prev_prot_sep == NULL)
2359 {
2360 protein_list = prot_sep->next;
2361 }
2362 else
2363 {
2364 prev_prot_sep->next = prot_sep->next;
2365 }
2366 prot_sep->next = NULL;
2367
2368 /* add to list for this nuc-prot set */
2369 if (last_this == NULL)
2370 {
2371 this_prot_list = prot_sep;
2372 }
2373 else
2374 {
2375 last_this->next = prot_sep;
2376 }
2377 last_this = prot_sep;
2378 }
2379 else
2380 {
2381 prev_prot_sep = prot_sep;
2382 }
2383 prot_sep = next_prot_sep;
2384 }
2385
2386 if (this_prot_list != NULL)
2387 {
2388 seg_nuc_prot = BioseqSetNew ();
2389 seg_nuc_prot->_class = BioseqseqSet_class_nuc_prot;
2390 seg_nuc_prot->seq_set = SeqEntryNew ();
2391 seg_nuc_prot->seq_set->choice = 1;
2392 seg_nuc_prot->seq_set->data.ptrvalue = seg_bsp;
2393 seg_nuc_prot->seq_set->next = this_prot_list;
2394 seg_sep->choice = 2;
2395 seg_sep->data.ptrvalue = seg_nuc_prot;
2396 }
2397 }
2398 parent_bssp->_class = BioseqseqSet_class_genbank;
2399 parent_bssp->seq_set = seg_list;
2400 }
2401
2402 if (protein_list != NULL && parent_bssp != NULL)
2403 {
2404 seg_sep = parent_bssp->seq_set;
2405 while (seg_sep != NULL && seg_sep->next != NULL)
2406 {
2407 seg_sep = seg_sep->next;
2408 }
2409 if (seg_sep == NULL)
2410 {
2411 parent_bssp->seq_set = protein_list;
2412 }
2413 else
2414 {
2415 seg_sep->next = protein_list;
2416 }
2417 }
2418
2419 /* if we have just put a genbank set inside another genbank set, move the nuc-prot sets
2420 * up. */
2421 RemoveIntermediateGenBankWrapper (parent_bssp);
2422 }
2423
2424 static void
RemoveOneUnsegmentedSet(SeqEntryPtr this_sep,BioseqSetPtr target_bssp,BioseqSetPtr parent_bssp)2425 RemoveOneUnsegmentedSet
2426 (SeqEntryPtr this_sep,
2427 BioseqSetPtr target_bssp,
2428 BioseqSetPtr parent_bssp)
2429 {
2430 SeqEntryPtr last_sep, prev_sep, target_sep;
2431
2432 if (this_sep == NULL || target_bssp == NULL || parent_bssp == NULL)
2433 {
2434 return;
2435 }
2436
2437 /* find last seqentry in target */
2438 last_sep = target_bssp->seq_set;
2439 while (last_sep != NULL && last_sep->next != NULL)
2440 {
2441 last_sep = last_sep->next;
2442 }
2443
2444 /* find target in parent set, put seqentries in its place */
2445 prev_sep = NULL;
2446 target_sep = parent_bssp->seq_set;
2447 while (target_sep != this_sep)
2448 {
2449 prev_sep = target_sep;
2450 target_sep = target_sep->next;
2451 }
2452 if (last_sep != NULL)
2453 {
2454 if (prev_sep == NULL)
2455 {
2456 parent_bssp->seq_set = target_bssp->seq_set;
2457 }
2458 else
2459 {
2460 prev_sep->next = target_bssp->seq_set;
2461 }
2462 last_sep->next = this_sep->next;
2463 }
2464 this_sep->next = NULL;
2465 target_bssp->seq_set = NULL;
2466 SeqEntryFree (this_sep);
2467 }
2468
2469 /* This function will remove a set and move the sequences in the set
2470 * to the parent set.
2471 */
RemoveSet(Pointer data)2472 static Int2 LIBCALLBACK RemoveSet (Pointer data)
2473
2474 {
2475 ObjMgrDataPtr omdptop;
2476 ObjMgrData omdata;
2477 OMProcControlPtr ompcp;
2478 Uint2 parenttype, top_parenttype;
2479 Pointer parentptr, top_parentptr;
2480 SeqEntryPtr top_sep, this_sep;
2481 BioseqSetPtr target_bssp, parent_bssp;
2482 ValNodePtr titles;
2483
2484 ompcp = (OMProcControlPtr) data;
2485 if (ompcp == NULL
2486 || ompcp->input_itemtype != OBJ_BIOSEQSET
2487 || ompcp->input_data == NULL)
2488 {
2489 return OM_MSG_RET_ERROR;
2490 }
2491
2492 top_sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
2493 if (top_sep == NULL) return OM_MSG_RET_ERROR;
2494 this_sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
2495 GetSeqEntryParent (this_sep, &parentptr, &parenttype);
2496
2497 if (parenttype != OBJ_BIOSEQSET || parentptr == NULL)
2498 {
2499 Message (MSG_ERROR, "Can't remove top set!");
2500 return OM_MSG_RET_ERROR;
2501 }
2502
2503 SaveSeqEntryObjMgrData (top_sep, &omdptop, &omdata);
2504 GetSeqEntryParent (top_sep, &top_parentptr, &top_parenttype);
2505
2506 target_bssp = (BioseqSetPtr) ompcp->input_data;
2507 parent_bssp = (BioseqSetPtr) parentptr;
2508
2509 if (parent_bssp->_class == BioseqseqSet_class_not_set
2510 || parent_bssp->_class == BioseqseqSet_class_segset
2511 || parent_bssp->_class == BioseqseqSet_class_parts)
2512 {
2513 Message (MSG_ERROR, "Can't move sequences up into parent");
2514 return OM_MSG_RET_ERROR;
2515 }
2516
2517 if (target_bssp->_class == BioseqseqSet_class_not_set
2518 || target_bssp->_class == BioseqseqSet_class_nuc_prot
2519 || target_bssp->_class == BioseqseqSet_class_parts)
2520 {
2521 Message (MSG_ERROR, "Can't disassemble this set");
2522 return OM_MSG_RET_ERROR;
2523 }
2524
2525 if (target_bssp->_class == BioseqseqSet_class_segset)
2526 {
2527 RemoveOneSegSet (this_sep, parent_bssp, target_bssp, ompcp->input_entityID);
2528 /* propagate the descriptors on the set to the sequences in the set */
2529 SetDescriptorPropagate (parent_bssp);
2530 DoFixupLocus (top_sep);
2531 DoFixupSegSet (top_sep);
2532 }
2533 else if (parent_bssp->_class == BioseqseqSet_class_nuc_prot
2534 && ! SetContainsProteins (target_bssp))
2535 {
2536 Message (MSG_ERROR, "Can't move sequences up into parent");
2537 return OM_MSG_RET_ERROR;
2538 }
2539 else
2540 {
2541 /* first, remove set title if any */
2542 titles = ValNodeExtractList (&(target_bssp->descr), Seq_descr_title);
2543 titles = SeqDescrFree (titles);
2544 /* propagate the descriptors on the set to the sequences in the set */
2545 SetDescriptorPropagate (target_bssp);
2546
2547 RemoveOneUnsegmentedSet (this_sep, target_bssp, parent_bssp);
2548 }
2549
2550 SeqMgrLinkSeqEntry (top_sep, top_parenttype, top_parentptr);
2551
2552 SeqMgrClearFeatureIndexes (ompcp->input_entityID, NULL);
2553 SeqMgrIndexFeatures (ompcp->input_entityID, NULL);
2554
2555 RestoreSeqEntryObjMgrData (top_sep, omdptop, &omdata);
2556
2557 SeqMgrClearFeatureIndexes (ompcp->input_entityID, NULL);
2558 SeqMgrIndexFeatures (ompcp->input_entityID, NULL);
2559
2560 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
2561 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
2562
2563 ForceCleanupEntityID (ompcp->input_entityID);
2564
2565 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
2566 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
2567
2568 return OM_MSG_RET_DONE;
2569 }
2570
2571 static Boolean
RemoveSetsInNucProtSet(BioseqSetPtr parent_bssp,Uint2 entityID)2572 RemoveSetsInNucProtSet
2573 (BioseqSetPtr parent_bssp,
2574 Uint2 entityID)
2575 {
2576 Boolean rval = FALSE;
2577 SeqEntryPtr this_sep;
2578 BioseqSetPtr target_bssp;
2579
2580 if (parent_bssp == NULL || parent_bssp->_class != BioseqseqSet_class_nuc_prot)
2581 {
2582 return FALSE;
2583 }
2584
2585 this_sep = parent_bssp->seq_set;
2586 if (this_sep != NULL
2587 && IS_Bioseq_set (this_sep)
2588 && this_sep->data.ptrvalue != NULL)
2589 {
2590 target_bssp = (BioseqSetPtr) this_sep->data.ptrvalue;
2591 if (target_bssp->_class == BioseqseqSet_class_segset)
2592 {
2593 RemoveOneSegSet (this_sep, parent_bssp, target_bssp, entityID);
2594 /* propagate the descriptors on the set to the sequences in the set */
2595 SetDescriptorPropagate (parent_bssp);
2596 rval = TRUE;
2597 }
2598 }
2599 return rval;
2600 }
2601
2602
RemoveSetsInBioseqSet(BioseqSetPtr parent_bssp,Uint2 entityID)2603 static Int2 LIBCALLBACK RemoveSetsInBioseqSet (BioseqSetPtr parent_bssp, Uint2 entityID)
2604 {
2605 ObjMgrDataPtr omdptop;
2606 ObjMgrData omdata;
2607 Uint2 top_parenttype;
2608 Pointer top_parentptr;
2609 SeqEntryPtr top_sep, this_sep, next_sep;
2610 BioseqSetPtr target_bssp;
2611 Boolean need_locus_fixup = FALSE;
2612 SeqDescrPtr titles;
2613
2614 if (parent_bssp == NULL) {
2615 return OM_MSG_RET_ERROR;
2616 }
2617
2618 top_sep = GetTopSeqEntryForEntityID (entityID);
2619 if (top_sep == NULL) return OM_MSG_RET_ERROR;
2620 SaveSeqEntryObjMgrData (top_sep, &omdptop, &omdata);
2621 GetSeqEntryParent (top_sep, &top_parentptr, &top_parenttype);
2622
2623 if (parent_bssp->_class == BioseqseqSet_class_not_set
2624 || parent_bssp->_class == BioseqseqSet_class_segset
2625 || parent_bssp->_class == BioseqseqSet_class_parts)
2626 {
2627 Message (MSG_ERROR, "Can't move sequences up into parent");
2628 return OM_MSG_RET_ERROR;
2629 }
2630 else if (parent_bssp->_class == BioseqseqSet_class_nuc_prot)
2631 {
2632 if (! RemoveSetsInNucProtSet (parent_bssp, entityID))
2633 {
2634 Message (MSG_ERROR, "Can't move sequences up into parent");
2635 return OM_MSG_RET_ERROR;
2636 }
2637 else
2638 {
2639 need_locus_fixup = TRUE;
2640 }
2641 }
2642 else
2643 {
2644 for (this_sep = parent_bssp->seq_set; this_sep != NULL; this_sep = next_sep)
2645 {
2646 next_sep = this_sep->next;
2647 if (!IS_Bioseq_set (this_sep) || this_sep->data.ptrvalue == NULL)
2648 {
2649 continue;
2650 }
2651 target_bssp = (BioseqSetPtr) this_sep->data.ptrvalue;
2652 if (target_bssp->_class == BioseqseqSet_class_nuc_prot)
2653 {
2654 need_locus_fixup |= RemoveSetsInNucProtSet (target_bssp, entityID);
2655 }
2656 else if (target_bssp->_class == BioseqseqSet_class_segset)
2657 {
2658 RemoveOneSegSet (this_sep, parent_bssp, target_bssp, entityID);
2659 }
2660 else if (target_bssp->_class != BioseqseqSet_class_not_set
2661 && target_bssp->_class != BioseqseqSet_class_parts)
2662 {
2663 /* first, remove set title if any */
2664 titles = ValNodeExtractList (&(target_bssp->descr), Seq_descr_title);
2665 titles = SeqDescrFree (titles);
2666
2667 /* propagate the descriptors on the set to the sequences in the set */
2668 SetDescriptorPropagate (target_bssp);
2669
2670 RemoveOneUnsegmentedSet (this_sep, target_bssp, parent_bssp);
2671 }
2672 }
2673 }
2674
2675 if (need_locus_fixup)
2676 {
2677 DoFixupLocus (top_sep);
2678 DoFixupSegSet (top_sep);
2679 }
2680
2681 SeqMgrLinkSeqEntry (top_sep, top_parenttype, top_parentptr);
2682
2683 SeqMgrClearFeatureIndexes (entityID, NULL);
2684 SeqMgrIndexFeatures (entityID, NULL);
2685
2686 RestoreSeqEntryObjMgrData (top_sep, omdptop, &omdata);
2687
2688 SeqMgrClearFeatureIndexes (entityID, NULL);
2689 SeqMgrIndexFeatures (entityID, NULL);
2690
2691 ObjMgrSetDirtyFlag (entityID, TRUE);
2692 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
2693
2694 ForceCleanupEntityID (entityID);
2695
2696 ObjMgrSetDirtyFlag (entityID, TRUE);
2697 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
2698
2699 return OM_MSG_RET_DONE;
2700 }
2701
RemoveSetsInSelectedSet(Pointer data)2702 static Int2 LIBCALLBACK RemoveSetsInSelectedSet (Pointer data)
2703 {
2704 OMProcControlPtr ompcp;
2705
2706 ompcp = (OMProcControlPtr) data;
2707 if (ompcp == NULL
2708 || ompcp->input_itemtype != OBJ_BIOSEQSET
2709 || ompcp->input_data == NULL)
2710 {
2711 return OM_MSG_RET_ERROR;
2712 }
2713
2714 return RemoveSetsInBioseqSet((BioseqSetPtr) ompcp->input_data, ompcp->input_entityID);
2715
2716 }
2717
2718
RemoveSetsInSetMenuItem(IteM i)2719 extern void RemoveSetsInSetMenuItem (IteM i)
2720 {
2721 BaseFormPtr bfp;
2722 BioseqSetPtr bssp;
2723 SeqEntryPtr sep;
2724
2725 #ifdef WIN_MAC
2726 bfp = currentFormDataPtr;
2727 #else
2728 bfp = GetObjectExtra (i);
2729 #endif
2730 if (bfp == NULL) return;
2731
2732 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
2733 if (sep == NULL || !IS_Bioseq_set (sep)) {
2734 Message (MSG_ERROR, "This record does not have a top-levelset!");
2735 } else {
2736 bssp = FindTopLevelSetForDesktopFunction((BioseqSetPtr) sep->data.ptrvalue);
2737 RemoveSetsInBioseqSet(bssp, bfp->input_entityID);
2738 }
2739 }
2740
2741
ApplySetTypeToSeqEntry(SeqEntryPtr sep,Uint1 new_class,Boolean is_top)2742 NLM_EXTERN void ApplySetTypeToSeqEntry (SeqEntryPtr sep, Uint1 new_class, Boolean is_top)
2743 {
2744 BioseqSetPtr bssp;
2745
2746 if (sep == NULL || !IS_Bioseq_set (sep)
2747 || (bssp = (BioseqSetPtr) sep->data.ptrvalue) == NULL
2748 || bssp->_class == BioseqseqSet_class_nuc_prot
2749 || bssp->_class == BioseqseqSet_class_segset) {
2750 return;
2751 }
2752
2753 if (is_top) {
2754 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
2755 ApplySetTypeToSeqEntry (sep, new_class, FALSE);
2756 }
2757 } else {
2758 bssp->_class = new_class;
2759 }
2760 }
2761
2762
ApplySetTypeDesktop(Pointer data)2763 static Int2 LIBCALLBACK ApplySetTypeDesktop (Pointer data)
2764 {
2765 OMProcControlPtr ompcp;
2766
2767 ompcp = (OMProcControlPtr) data;
2768 if (ompcp == NULL
2769 || ompcp->input_itemtype != OBJ_BIOSEQSET
2770 || ompcp->input_data == NULL)
2771 {
2772 return OM_MSG_RET_ERROR;
2773 }
2774 ApplySetTypeToInnerSets (ompcp->input_data, ompcp->input_entityID);
2775 return OM_MSG_RET_DONE;
2776 }
2777
2778
NoMoreSegGapForOneAlignment(SeqAlignPtr sap,Pointer userdata)2779 static void NoMoreSegGapForOneAlignment (SeqAlignPtr sap, Pointer userdata)
2780 {
2781 SeqAlignPtr salp;
2782
2783 salp = sap;
2784 while (salp != NULL)
2785 {
2786 if (salp->saip != NULL)
2787 {
2788 SeqAlignIndexFree(salp->saip);
2789 salp->saip = NULL;
2790 } else {
2791 AlnMgr2IndexSingleChildSeqAlign(salp); /* make sure it's dense-seg */
2792 SeqAlignIndexFree(salp->saip);
2793 salp->saip = NULL;
2794 }
2795 CleanUpSegGap(salp);
2796 AlnMgr2IndexSingleChildSeqAlign(salp);
2797 salp = salp->next;
2798 }
2799 }
2800
2801
NoMoreSegGap(Pointer data)2802 static Int2 LIBCALLBACK NoMoreSegGap (Pointer data)
2803 {
2804 OMProcControlPtr ompcp;
2805 SeqAlignPtr sap;
2806 SeqAnnotPtr sanp;
2807
2808 ompcp = (OMProcControlPtr) data;
2809 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
2810 switch (ompcp->input_itemtype) {
2811 case OBJ_SEQALIGN :
2812 sap = (SeqAlignPtr) ompcp->input_data;
2813 if (sap == NULL)
2814 {
2815 return OM_MSG_RET_ERROR;
2816 }
2817 else
2818 {
2819 NoMoreSegGapForOneAlignment (sap, NULL);
2820 }
2821 break;
2822 case OBJ_SEQANNOT :
2823 sanp = (SeqAnnotPtr) ompcp->input_data;
2824 if (sanp->type != 2)
2825 {
2826 return OM_MSG_RET_ERROR;
2827 }
2828 else if ((sap = (SeqAlignPtr)(sanp->data)) == NULL)
2829 {
2830 return OM_MSG_RET_ERROR;
2831 }
2832 else
2833 {
2834 NoMoreSegGapForOneAlignment (sap, NULL);
2835 }
2836 break;
2837 case OBJ_BIOSEQ :
2838 VisitAlignmentsOnBsp (ompcp->input_data, NULL, NoMoreSegGapForOneAlignment);
2839 break;
2840 case OBJ_BIOSEQSET :
2841 VisitAlignmentsInSet (ompcp->input_data, NULL, NoMoreSegGapForOneAlignment);
2842 break;
2843 case 0 :
2844 return OM_MSG_RET_ERROR;
2845 break;
2846 default :
2847 return OM_MSG_RET_ERROR;
2848 break;
2849 }
2850 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
2851 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
2852 return OM_MSG_RET_DONE;
2853 }
2854
2855
GetRidOfSegGapMenuItem(IteM i)2856 extern void GetRidOfSegGapMenuItem (IteM i)
2857 {
2858 BaseFormPtr bfp;
2859 SeqEntryPtr sep;
2860
2861 #ifdef WIN_MAC
2862 bfp = currentFormDataPtr;
2863 #else
2864 bfp = GetObjectExtra (i);
2865 #endif
2866 if (bfp == NULL) return;
2867
2868 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
2869 VisitAlignmentsInSep (sep, NULL, NoMoreSegGapForOneAlignment);
2870 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
2871 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
2872 }
2873
2874
SqnSeqAlignDeleteInSeqEntryCallBack(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)2875 static void SqnSeqAlignDeleteInSeqEntryCallBack (SeqEntryPtr sep, Pointer mydata,
2876 Int4 index, Int2 indent)
2877 {
2878 BioseqPtr bsp;
2879 BioseqSetPtr bssp;
2880 SeqAnnotPtr sap,
2881 pre;
2882 BoolPtr dirtyp;
2883
2884 if (sep != NULL && sep->data.ptrvalue && mydata != NULL) {
2885 dirtyp = (BoolPtr)mydata;
2886 if (IS_Bioseq(sep)) {
2887 bsp = (BioseqPtr) sep->data.ptrvalue;
2888 if (bsp!=NULL) {
2889 sap=bsp->annot;
2890 pre=NULL;
2891 while (sap) {
2892 if (sap->type == 2) {
2893 if (pre==NULL) {
2894 bsp->annot = sap->next;
2895 sap->next=NULL;
2896 sap = SeqAnnotFree (sap);
2897 if (bsp->annot)
2898 sap=bsp->annot->next;
2899 }
2900 else {
2901 pre=sap->next;
2902 sap->next=NULL;
2903 sap = SeqAnnotFree (sap);
2904 if (pre)
2905 sap=pre->next;
2906 }
2907 *dirtyp=TRUE;
2908 }
2909 else {
2910 pre=sap;
2911 sap=sap->next;
2912 }
2913 }
2914 }
2915 }
2916 else if(IS_Bioseq_set(sep)) {
2917 bssp = (BioseqSetPtr)sep->data.ptrvalue;
2918 if (bssp!=NULL) {
2919 sap=bssp->annot;
2920 pre=NULL;
2921 while (sap) {
2922 if (sap->type == 2) {
2923 if (pre==NULL) {
2924 bssp->annot = sap->next;
2925 sap->next=NULL;
2926 sap = SeqAnnotFree (sap);
2927 if (bssp->annot)
2928 sap=bssp->annot->next;
2929 }
2930 else {
2931 pre=sap->next;
2932 sap->next=NULL;
2933 sap = SeqAnnotFree (sap);
2934 if (pre)
2935 sap=pre->next;
2936 }
2937 *dirtyp=TRUE;
2938 }
2939 else {
2940 pre=sap;
2941 sap=sap->next;
2942 }
2943 }
2944 }
2945 }
2946 }
2947 }
2948
2949 /* This function creates one SeqAnnot for each alignment in a chain of
2950 * alignments, breaking the chain for each alignment.
2951 * This is used to create the separate alignment annotations for a
2952 * discontiguous set of alignments, especially one created for a set
2953 * that contains delta sequences.
2954 */
2955 static void
CreateSeqAnnotsForDiscontiguousAlignments(SeqAlignPtr salp_mult,Uint2 entityID,BioseqSetPtr set_for_alignment)2956 CreateSeqAnnotsForDiscontiguousAlignments
2957 (SeqAlignPtr salp_mult,
2958 Uint2 entityID,
2959 BioseqSetPtr set_for_alignment)
2960 {
2961 SeqAlignPtr salp, salp_next;
2962 SeqAnnotPtr sap;
2963 SeqEntryPtr sep;
2964 SeqAnnotPtr PNTR sapp = NULL;
2965 BioseqSetPtr bssp;
2966 BioseqPtr bsp;
2967 SeqAnnotPtr curr;
2968
2969 if (salp_mult == NULL)
2970 {
2971 return;
2972 }
2973 for (salp = salp_mult; salp != NULL; salp = salp_next)
2974 {
2975 salp_next = salp->next;
2976 salp->next = NULL;
2977 sap = SeqAnnotForSeqAlign(salp);
2978
2979 if (sap != NULL) {
2980 if (set_for_alignment == NULL)
2981 {
2982 sep = GetTopSeqEntryForEntityID (entityID);
2983 if (sep != NULL && sep->data.ptrvalue != NULL) {
2984 sapp = NULL;
2985 if (IS_Bioseq (sep)) {
2986 bsp = (BioseqPtr) sep->data.ptrvalue;
2987 sapp = &(bsp->annot);
2988 } else if (IS_Bioseq_set (sep)) {
2989 bssp = (BioseqSetPtr) sep->data.ptrvalue;
2990 sapp = &(bssp->annot);
2991 }
2992 }
2993 }
2994 else
2995 {
2996 sapp = &(set_for_alignment->annot);
2997 }
2998
2999 if (sapp != NULL) {
3000 if (*sapp != NULL) {
3001 curr = *sapp;
3002 while (curr->next != NULL) {
3003 curr = curr->next;
3004 }
3005 curr->next = sap;
3006 } else {
3007 *sapp = sap;
3008 }
3009 }
3010 }
3011 }
3012 }
3013
3014
UpdateSeqAlignForSeqEntry(SeqEntryPtr sep)3015 static Int2 LIBCALLBACK UpdateSeqAlignForSeqEntry (SeqEntryPtr sep)
3016
3017 {
3018 Char path [PATH_MAX];
3019 FILE *fp;
3020 SeqAlignPtr salp=NULL,
3021 salpnew;
3022 SeqEntryPtr sepnew=NULL;
3023 Uint2 entityID,
3024 itemID;
3025 MsgAnswer ans;
3026 Boolean ok = TRUE,
3027 dirty = FALSE;
3028 TSequenceInfoPtr sequence_info;
3029 ReadBufferData rbd;
3030 TErrorInfoPtr error_list;
3031 TAlignmentFilePtr afp;
3032 Uint1 moltype;
3033 ErrSev sev;
3034 SeqEntryPtr scope;
3035 SeqAlignPtr salp_copy;
3036 BioseqSetPtr bssp = NULL;
3037
3038 if (sep==NULL)
3039 return OM_MSG_RET_ERROR;
3040 entityID = ObjMgrGetEntityIDForChoice (sep);
3041 if (entityID < 1)
3042 return OM_MSG_RET_ERROR;
3043
3044 if (IS_Bioseq_set (sep)) {
3045 bssp = sep->data.ptrvalue;
3046 }
3047
3048 if (GetInputFileName (path, sizeof (path), NULL, "TEXT")) {
3049 fp = FileOpen (path, "r");
3050 if (fp != NULL) {
3051 sequence_info = GetAlignmentOptions (&moltype, NULL);
3052 if (sequence_info == NULL) return OM_MSG_RET_ERROR;
3053 error_list = NULL;
3054
3055 rbd.fp = fp;
3056 rbd.current_data = NULL;
3057 afp = ReadAlignmentFile ( AbstractReadFunction,
3058 (Pointer) &rbd,
3059 AbstractReportError,
3060 (Pointer) &error_list,
3061 sequence_info);
3062 if (afp != NULL)
3063 {
3064 SeqEntrySetScope (sep);
3065 if (CorrectAlignmentIDs (afp, moltype))
3066 {
3067 sepnew = MakeSequinDataFromAlignmentEx (afp, moltype, TRUE);
3068 }
3069 }
3070 ProduceAlignmentNotes (afp, error_list);
3071 ErrorInfoFree (error_list);
3072 SequenceInfoFree (sequence_info);
3073 AlignmentFileFree (afp);
3074 Update ();
3075 }
3076 }
3077 if (sepnew)
3078 {
3079 salpnew = (SeqAlignPtr) FindSeqAlignInSeqEntry (sepnew, OBJ_SEQALIGN);
3080 if (salpnew) {
3081 sev = ErrSetMessageLevel (SEV_FATAL);
3082
3083 scope = SeqEntrySetScope (NULL);
3084 /* adjust the start positions for the sequences read in from the alignments. */
3085 CalculateAlignmentOffsets (sepnew, sep);
3086 /* ValidateSeqAlignandACCInSeqEntry will readjust the start positions for
3087 * the alignments for far pointer sequences.
3088 */
3089 SeqEntrySetScope (scope);
3090 ok = ValidateSeqAlignandACCInSeqEntry (sepnew, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE);
3091
3092 ErrSetMessageLevel (sev);
3093
3094 if (ok) {
3095 AlnMgr2IndexSeqAlignEx(salpnew, FALSE);
3096 ok = CheckAlignmentSequenceLengths (salpnew);
3097 }
3098
3099 if (ok) {
3100 /* if there is already an alignment, ask if the user wants to remove the old
3101 * one before adding the new alignment.
3102 */
3103 salp = (SeqAlignPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN);
3104 if (salp)
3105 {
3106 ans = Message (MSG_OKC, "Do you wish to replace (OK) or add (Cancel) the alignment in your SeqEntry?");
3107 if (ans == ANS_OK)
3108 {
3109 SeqEntryExplore (sep, &dirty, SqnSeqAlignDeleteInSeqEntryCallBack);
3110 }
3111 }
3112
3113 /* make a copy of the alignment in sepnew - the alignment in sepnew will
3114 * be freed when sepnew is freed.
3115 */
3116 salp_copy = (SeqAlignPtr) AsnIoMemCopy (salpnew, (AsnReadFunc) SeqAlignAsnRead,
3117 (AsnWriteFunc) SeqAlignAsnWrite);
3118 /* the copy function doesn't copy the index, so the alignment must be
3119 * indexed now.
3120 */
3121 AlnMgr2IndexSeqAlignEx(salp_copy, FALSE);
3122 /* break the alignment at gaps, if the set contains any delta sequences */
3123 salp_copy = MakeDiscontiguousAlignments (salp_copy);
3124
3125 /* break the chain of alignments and create separate SeqAnnots for each one */
3126 CreateSeqAnnotsForDiscontiguousAlignments (salp_copy, entityID, bssp);
3127 ObjMgrSetDirtyFlag (entityID, TRUE);
3128 itemID = GetItemIDGivenPointer (entityID, OBJ_SEQENTRY, (Pointer) sep);
3129 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, itemID, OBJ_SEQENTRY);
3130 }
3131 }
3132 ObjMgrFree (OBJ_SEQENTRY, (Pointer)sepnew);
3133 sepnew=NULL;
3134 }
3135 return OM_MSG_RET_OK;
3136 }
3137
NewUpdateSeqAlign(Pointer data)3138 static Int2 LIBCALLBACK NewUpdateSeqAlign (Pointer data)
3139 {
3140 OMProcControlPtr ompcp;
3141 SeqEntryPtr sep = NULL;
3142 BioseqSetPtr bssp;
3143 SeqSubmitPtr ssp;
3144
3145 ompcp = (OMProcControlPtr) data;
3146 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
3147
3148 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
3149
3150 switch(ompcp->input_itemtype)
3151 {
3152 case OBJ_BIOSEQ :
3153 sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
3154 break;
3155 case OBJ_BIOSEQSET :
3156 sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
3157 bssp = (BioseqSetPtr) ompcp->input_data;
3158 break;
3159 case OBJ_SEQENTRY :
3160 sep = ompcp->input_data;
3161 break;
3162 case OBJ_SEQSUB :
3163 ssp = ompcp->input_data;
3164 if(ssp->datatype==1)
3165 sep = (SeqEntryPtr)ssp->data;
3166 break;
3167 case 0 :
3168 return OM_MSG_RET_ERROR;
3169 default :
3170 return OM_MSG_RET_ERROR;
3171 }
3172 if (sep==NULL)
3173 return OM_MSG_RET_ERROR;
3174
3175 return UpdateSeqAlignForSeqEntry (sep);
3176
3177 }
3178
UpdateSeqAlignMenuItem(IteM i)3179 extern void UpdateSeqAlignMenuItem (IteM i)
3180 {
3181 BaseFormPtr bfp;
3182 BioseqSetPtr bssp;
3183 SeqEntryPtr sep;
3184
3185 #ifdef WIN_MAC
3186 bfp = currentFormDataPtr;
3187 #else
3188 bfp = GetObjectExtra (i);
3189 #endif
3190 if (bfp == NULL) return;
3191
3192 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3193 if (sep == NULL || !IS_Bioseq_set (sep)) {
3194 Message (MSG_ERROR, "This record does not have a top-levelset!");
3195 } else {
3196 bssp = FindTopLevelSetForDesktopFunction((BioseqSetPtr) sep->data.ptrvalue);
3197 sep = SeqMgrGetSeqEntryForData (bssp);
3198 UpdateSeqAlignForSeqEntry (sep);
3199 }
3200 }
3201
3202
DenseSegSwitchSeqPos(DenseSegPtr dsp)3203 static void DenseSegSwitchSeqPos (DenseSegPtr dsp)
3204 {
3205 SeqIdPtr sip, sip_next;
3206 Int4 tmp_start, i;
3207 Uint1 tmp_strand;
3208
3209 if (dsp == NULL || dsp->dim != 2) {
3210 return;
3211 }
3212
3213 /* switch the IDs */
3214 sip = dsp->ids;
3215 sip_next = dsp->ids->next;
3216 sip_next->next = sip;
3217 sip->next = NULL;
3218 dsp->ids = sip_next;
3219
3220 /* switch the starts and strands*/
3221 for (i = 0; i < dsp->numseg; i++) {
3222 tmp_start = dsp->starts[(i * dsp->dim)];
3223 dsp->starts[(i * dsp->dim)] = dsp->starts[(i * dsp->dim) + 1];
3224 dsp->starts[(i * dsp->dim) + 1] = tmp_start;
3225 }
3226
3227 if (dsp->strands != NULL) {
3228 for (i = 0; i < dsp->numseg; i++) {
3229 tmp_strand = dsp->strands[(i * dsp->dim)];
3230 dsp->strands[(i * dsp->dim)] = dsp->strands[(i * dsp->dim) + 1];
3231 dsp->strands[(i * dsp->dim) + 1] = tmp_strand;
3232 }
3233 }
3234 }
3235
3236
FindBioseqForSeqHist(SeqAlignPtr salp)3237 static BioseqPtr FindBioseqForSeqHist (SeqAlignPtr salp)
3238 {
3239 SeqIdPtr sip;
3240 BioseqPtr bsp;
3241 DenseSegPtr dsp;
3242
3243 if (salp == NULL || salp->dim != 2 || salp->segtype != SAS_DENSEG) {
3244 return NULL;
3245 }
3246
3247 dsp = (DenseSegPtr) salp->segs;
3248
3249 sip = dsp->ids->next;
3250
3251 bsp = BioseqFind (sip);
3252 if (bsp == NULL) {
3253 /* if we find the bioseq here, need to switch the positions */
3254 sip = dsp->ids;
3255 bsp = BioseqFind (sip);
3256 if (bsp != NULL) {
3257 DenseSegSwitchSeqPos (dsp);
3258 }
3259 }
3260 return bsp;
3261 }
3262
3263
CorrectIDsForSeqHistAlign(TAlignmentFilePtr afp,SeqEntryPtr sep)3264 static SeqIdPtr CorrectIDsForSeqHistAlign (TAlignmentFilePtr afp, SeqEntryPtr sep)
3265 {
3266 SeqIdPtr sip;
3267 Boolean need_switch = FALSE;
3268 char *tmp;
3269
3270 if (afp == NULL || afp->num_sequences != 2) {
3271 return NULL;
3272 }
3273 if (StringNICmp (afp->ids[1], "acc", 3) == 0) {
3274 /* already have far pointer in place */
3275 sip = CreateSeqIdFromText (afp->ids[0], sep);
3276 } else if (StringNICmp (afp->ids[0], "acc", 3) == 0) {
3277 need_switch = TRUE;
3278 sip = CreateSeqIdFromText (afp->ids[1], sep);
3279 } else {
3280 /* first position should be primary */
3281 sip = CreateSeqIdFromText (afp->ids[0], sep);
3282 if (sip == NULL) {
3283 sip = CreateSeqIdFromText (afp->ids[1], sep);
3284 if (sip == NULL) {
3285 /* can't find match in record */
3286 } else {
3287 /* second position is primary, put acc on first position */
3288 need_switch = TRUE;
3289 tmp = malloc (StringLen (afp->ids[0]) + 4);
3290 sprintf (tmp, "acc%s", afp->ids[0]);
3291 free (afp->ids[0]);
3292 afp->ids[0] = tmp;
3293 }
3294 } else {
3295 tmp = malloc (StringLen (afp->ids[1]) + 4);
3296 sprintf (tmp, "acc%s", afp->ids[1]);
3297 free (afp->ids[1]);
3298 afp->ids[1] = tmp;
3299 }
3300 }
3301
3302 if (sip != NULL) {
3303 if (need_switch) {
3304 /* note - not bothering to switch deflines and organism names because
3305 * we don't need them for the seq-hist assembly
3306 */
3307 tmp = afp->ids[0];
3308 afp->ids[0] = afp->ids[1];
3309 afp->ids[1] = tmp;
3310
3311 tmp = afp->sequences[0];
3312 afp->sequences[0] = afp->sequences[1];
3313 afp->sequences[1] = tmp;
3314 }
3315 }
3316 return sip;
3317 }
3318
3319
IsIntervalGap(BioseqPtr bsp,Int4 start,Int4 stop)3320 static Boolean IsIntervalGap (BioseqPtr bsp, Int4 start, Int4 stop)
3321 {
3322 DeltaSeqPtr dsp;
3323 SeqLitPtr litp;
3324 SeqLocPtr loc;
3325 Int4 seq_offset = 0, len;
3326 Boolean this_is_gap;
3327
3328 if (bsp == NULL
3329 || bsp->repr != Seq_repr_delta
3330 || bsp->seq_ext_type != 4
3331 || start < 0
3332 || stop >= bsp->length)
3333 {
3334 return FALSE;
3335 }
3336
3337 for (dsp = (DeltaSeqPtr) bsp->seq_ext;
3338 dsp != NULL && dsp->next != NULL && seq_offset < stop;
3339 dsp = dsp->next)
3340 {
3341 len = 0;
3342 this_is_gap = FALSE;
3343 if (dsp->choice == 1)
3344 {
3345 loc = (SeqLocPtr) dsp->data.ptrvalue;
3346 len = SeqLocLen (loc);
3347 }
3348 else if (dsp->choice == 2)
3349 {
3350 litp = (SeqLitPtr) dsp->data.ptrvalue;
3351 if (litp != NULL)
3352 {
3353 len = litp->length;
3354 if (IsDeltaSeqGap (dsp))
3355 {
3356 this_is_gap = TRUE;
3357 }
3358 }
3359 }
3360
3361 if (seq_offset <= start && seq_offset + len >= stop)
3362 {
3363 return this_is_gap;
3364 }
3365 else if ((seq_offset <= start && seq_offset + len > start)
3366 || (seq_offset < stop && seq_offset + len > stop)
3367 || (seq_offset >= start && seq_offset + len <= stop))
3368 {
3369 if (!this_is_gap)
3370 {
3371 return FALSE;
3372 }
3373 }
3374 seq_offset += len;
3375 }
3376 return TRUE;
3377 }
3378
3379 static Boolean
CollapseTwoGapSegments(DenseSegPtr dsp,Int4 seg_num_first,BioseqPtr PNTR bsparray)3380 CollapseTwoGapSegments
3381 (DenseSegPtr dsp,
3382 Int4 seg_num_first,
3383 BioseqPtr PNTR bsparray)
3384 {
3385 Int4Ptr newstarts;
3386 Int4Ptr newlens;
3387 Uint1Ptr newstrands = NULL;
3388 Int4 row_num, seg_num;
3389
3390 if (dsp == NULL || seg_num_first > dsp->numseg - 2)
3391 {
3392 return FALSE;
3393 }
3394
3395 if (dsp->lens [seg_num_first] != dsp->lens [seg_num_first + 1])
3396 {
3397 return FALSE;
3398 }
3399
3400 for (row_num = 0; row_num < dsp->dim; row_num++)
3401 {
3402 if (dsp->starts [seg_num_first * dsp->dim + row_num] != -1
3403 && dsp->starts [(seg_num_first + 1) * dsp->dim + row_num] != -1)
3404 {
3405 return FALSE;
3406 }
3407
3408 /* segment must be over a gap for all rows not in gap */
3409 /* for the first segment */
3410 if (dsp->starts [seg_num_first * dsp->dim + row_num] != -1
3411 && ! IsIntervalGap (bsparray[row_num],
3412 dsp->starts [seg_num_first * dsp->dim + row_num],
3413 dsp->starts [seg_num_first * dsp->dim + row_num] + dsp->lens[seg_num_first]))
3414
3415 {
3416 return FALSE;
3417 }
3418 /* and for the second segment */
3419 if (dsp->starts [(seg_num_first + 1) * dsp->dim + row_num] != -1
3420 && ! IsIntervalGap (bsparray[row_num],
3421 dsp->starts [(seg_num_first + 1) * dsp->dim + row_num],
3422 dsp->starts [(seg_num_first + 1) * dsp->dim + row_num] + dsp->lens[seg_num_first + 1]))
3423
3424 {
3425 return FALSE;
3426 }
3427 }
3428
3429 newstarts = (Int4Ptr) MemNew (sizeof (Int4) * dsp->dim * (dsp->numseg - 1));
3430 newlens = (Int4Ptr) MemNew (sizeof (Int4) * (dsp->numseg - 1));
3431 if (dsp->strands != NULL)
3432 {
3433 newstrands = (Uint1Ptr) MemNew (sizeof (Uint1) * dsp->dim * (dsp->numseg - 1));
3434 }
3435
3436 /* copy the portion of the alignment before the segments to be collapsed */
3437 for (seg_num = 0; seg_num < seg_num_first; seg_num++)
3438 {
3439 for (row_num = 0; row_num < dsp->dim; row_num++)
3440 {
3441 newstarts [seg_num * dsp->dim + row_num] = dsp->starts [seg_num * dsp->dim + row_num];
3442 if (dsp->strands != NULL)
3443 {
3444 newstrands [seg_num * dsp->dim + row_num] = dsp->strands[seg_num * dsp->dim + row_num];
3445 }
3446 }
3447 newlens[seg_num] = dsp->lens[seg_num];
3448 }
3449
3450 /* collapse the two segments */
3451 for (row_num = 0; row_num < dsp->dim; row_num++)
3452 {
3453 if (dsp->starts [seg_num * dsp->dim + row_num] == -1)
3454 {
3455 newstarts [seg_num * dsp->dim + row_num] = dsp->starts [(seg_num + 1) * dsp->dim + row_num];
3456 if (dsp->strands != NULL)
3457 {
3458 newstrands [seg_num * dsp->dim + row_num] = dsp->strands [(seg_num + 1) * dsp->dim + row_num];
3459 }
3460 }
3461 else
3462 {
3463 newstarts [seg_num * dsp->dim + row_num] = dsp->starts [seg_num * dsp->dim + row_num];
3464 if (dsp->strands != NULL)
3465 {
3466 newstrands [seg_num * dsp->dim + row_num] = dsp->strands [seg_num * dsp->dim + row_num];
3467 }
3468 }
3469 }
3470 newlens [seg_num] = dsp->lens [seg_num];
3471 seg_num++;
3472
3473 /* copy the remaining segments after the collapsed pair */
3474 while (seg_num < dsp->numseg - 1)
3475 {
3476 for (row_num = 0; row_num < dsp->dim; row_num++)
3477 {
3478 newstarts [seg_num * dsp->dim + row_num] = dsp->starts [(seg_num + 1) * dsp->dim + row_num];
3479 if (dsp->strands != NULL)
3480 {
3481 newstrands [seg_num * dsp->dim + row_num] = dsp->strands[(seg_num + 1) * dsp->dim + row_num];
3482 }
3483 }
3484 newlens[seg_num] = dsp->lens[(seg_num + 1)];
3485 seg_num++;
3486 }
3487
3488 /* replace the starts, strands, lens, and numseg in dsp */
3489 dsp->starts = MemFree (dsp->starts);
3490 dsp->starts = newstarts;
3491 dsp->strands = MemFree (dsp->strands);
3492 dsp->strands = newstrands;
3493 dsp->lens = MemFree (dsp->lens);
3494 dsp->lens = newlens;
3495 dsp->numseg--;
3496 return TRUE;
3497 }
3498
ConsolidateSegmentsOverKnownLengthGaps(SeqAlignPtr salp)3499 extern void ConsolidateSegmentsOverKnownLengthGaps (SeqAlignPtr salp)
3500 {
3501 DenseSegPtr dsp;
3502 SeqIdPtr sip;
3503 BioseqPtr PNTR bsparray;
3504 Int4 row_num, seg_num;
3505
3506 if (salp == NULL || salp->segtype != SAS_DENSEG || salp->segs == NULL)
3507 {
3508 return;
3509 }
3510
3511 if (salp->saip != NULL)
3512 {
3513 SeqAlignIndexFree(salp->saip);
3514 salp->saip = NULL;
3515 }
3516
3517 dsp = (DenseSegPtr) salp->segs;
3518
3519 bsparray = (BioseqPtr PNTR) MemNew (sizeof (BioseqPtr) * dsp->dim);
3520
3521
3522 for (sip = dsp->ids, row_num = 0;
3523 sip != NULL && row_num < dsp->dim;
3524 sip = sip->next, row_num++)
3525 {
3526 bsparray [row_num] = BioseqFind (sip);
3527 }
3528
3529 seg_num = 0;
3530 while (seg_num < dsp->numseg - 1)
3531 {
3532 if (!CollapseTwoGapSegments (dsp, seg_num, bsparray))
3533 {
3534 seg_num++;
3535 }
3536 }
3537
3538 AlnMgr2IndexSeqAlignEx(salp, FALSE);
3539 bsparray = MemFree (bsparray);
3540 }
3541
ConsolidateGapGaps(Pointer data)3542 static Int2 LIBCALLBACK ConsolidateGapGaps (Pointer data)
3543
3544 {
3545 OMProcControlPtr ompcp;
3546 SeqAlignPtr salp=NULL;
3547 Uint2 entityID;
3548 SeqAnnotPtr sanp_old;
3549
3550 ompcp = (OMProcControlPtr) data;
3551 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
3552
3553 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
3554
3555 switch(ompcp->input_itemtype)
3556 {
3557 case OBJ_SEQALIGN :
3558 salp = (SeqAlignPtr) ompcp->input_data;
3559 break;
3560 case OBJ_SEQANNOT:
3561 sanp_old = (SeqAnnotPtr) ompcp->input_data;
3562 if (sanp_old->type == 2)
3563 {
3564 salp = sanp_old->data;
3565 }
3566 break;
3567 default :
3568 return OM_MSG_RET_ERROR;
3569 }
3570 if (salp==NULL)
3571 return OM_MSG_RET_ERROR;
3572 entityID = ompcp->input_entityID;
3573 if (entityID < 1)
3574 return OM_MSG_RET_ERROR;
3575
3576 ConsolidateSegmentsOverKnownLengthGaps (salp);
3577
3578 ObjMgrSetDirtyFlag (entityID, TRUE);
3579
3580 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
3581
3582 return OM_MSG_RET_OK;
3583 }
3584
3585
3586 /* NOTE - need to call DeleteMarkedObjects after calling this function */
FixOneAlignmentOverGaps(SeqAlignPtr salp,Uint2 entityID)3587 extern void FixOneAlignmentOverGaps (SeqAlignPtr salp, Uint2 entityID)
3588 {
3589 SeqAnnotPtr sanp_old, sanp_new;
3590 SeqAlignPtr salp_copy, salp_tmp;
3591 BioseqSetPtr bssp = NULL;
3592
3593 sanp_old = GetSeqAnnotForAlignment (salp);
3594 if (sanp_old == NULL)
3595 {
3596 return;
3597 }
3598
3599 if (sanp_old->idx.parenttype == OBJ_BIOSEQSET)
3600 {
3601 bssp = (BioseqSetPtr) sanp_old->idx.parentptr;
3602 }
3603
3604 /* make a copy of the alignment */
3605 salp_copy = (SeqAlignPtr) AsnIoMemCopy (salp, (AsnReadFunc) SeqAlignAsnRead,
3606 (AsnWriteFunc) SeqAlignAsnWrite);
3607 /* the copy function doesn't copy the index, so the alignment must be
3608 * indexed now.
3609 */
3610 AlnMgr2IndexSeqAlignEx(salp_copy, FALSE);
3611 /* break the alignment at gaps, if the set contains any delta sequences */
3612 salp_copy = MakeDiscontiguousAlignments (salp_copy);
3613
3614 for (salp_tmp = salp_copy; salp_tmp != NULL; salp_tmp = salp_tmp->next)
3615 {
3616 NoMoreSegGapForOneAlignment (salp_tmp, NULL);
3617 }
3618
3619 /* break the chain of alignments and create separate SeqAnnots for each one */
3620 CreateSeqAnnotsForDiscontiguousAlignments (salp_copy, entityID, bssp);
3621
3622 /* need to index the alignments before we can find the new alignment and remove the old */
3623 ObjMgrSetDirtyFlag (entityID, TRUE);
3624 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
3625
3626 sanp_new = GetSeqAnnotForAlignment (salp_copy);
3627
3628 if (sanp_new != NULL)
3629 {
3630 salp->idx.deleteme = TRUE;
3631 }
3632 }
3633
FixAlignmentOverGaps(Pointer data)3634 static Int2 LIBCALLBACK FixAlignmentOverGaps (Pointer data)
3635
3636 {
3637 OMProcControlPtr ompcp;
3638 SeqAlignPtr salp=NULL;
3639 Uint2 entityID;
3640 SeqAnnotPtr sanp_old;
3641
3642 ompcp = (OMProcControlPtr) data;
3643 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
3644
3645 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
3646
3647 switch(ompcp->input_itemtype)
3648 {
3649 case OBJ_SEQALIGN :
3650 salp = (SeqAlignPtr) ompcp->input_data;
3651 break;
3652 case OBJ_SEQANNOT:
3653 sanp_old = (SeqAnnotPtr) ompcp->input_data;
3654 if (sanp_old->type == 2)
3655 {
3656 salp = sanp_old->data;
3657 }
3658 break;
3659 default :
3660 return OM_MSG_RET_ERROR;
3661 }
3662 if (salp==NULL)
3663 return OM_MSG_RET_ERROR;
3664 entityID = ompcp->input_entityID;
3665 if (entityID < 1)
3666 return OM_MSG_RET_ERROR;
3667
3668 FixOneAlignmentOverGaps (salp, entityID);
3669 DeleteMarkedObjects (entityID, 0, NULL);
3670
3671 ObjMgrSetDirtyFlag (entityID, TRUE);
3672
3673 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
3674
3675 return OM_MSG_RET_OK;
3676 }
3677
3678
3679 typedef struct sqn_bsp {
3680 BioseqPtr bsp;
3681 struct sqn_bsp PNTR next;
3682 } SQNBsp, PNTR SQNBspPtr;
3683
SQNGetBioseqsProt(SeqEntryPtr sep,Pointer userdata,Int4 index,Int2 indent)3684 static void SQNGetBioseqsProt(SeqEntryPtr sep, Pointer userdata, Int4 index, Int2 indent)
3685 {
3686 BioseqPtr bsp = NULL;
3687 SQNBspPtr sbp;
3688
3689 if (sep == NULL || sep->data.ptrvalue == NULL || userdata == NULL)
3690 return;
3691 sbp = (SQNBspPtr)userdata;
3692 if (IS_Bioseq(sep))
3693 bsp = (BioseqPtr)(sep->data.ptrvalue);
3694 if (IS_Bioseq(sep) && ISA_aa(bsp->mol))
3695 {
3696 if (sbp->bsp == NULL)
3697 sbp->bsp = (BioseqPtr)(sep->data.ptrvalue);
3698 else
3699 {
3700 while (sbp->next != NULL)
3701 {
3702 sbp = sbp->next;
3703 }
3704 sbp->next = (SQNBspPtr)MemNew(sizeof(SQNBsp));
3705 sbp->next->bsp = (BioseqPtr)(sep->data.ptrvalue);
3706 }
3707 }
3708 }
3709
3710 typedef struct masterseqform
3711 {
3712 Boolean listBoxAccept;
3713 Boolean listBoxUp;
3714 DialoG seq_dlg;
3715 GrouP flipFeatGrp;
3716 } MasterSeqFormData, PNTR MasterSeqFormPtr;
3717
AcceptMasterSeqMessage(ButtoN b)3718 static void AcceptMasterSeqMessage (ButtoN b)
3719
3720 {
3721 MasterSeqFormPtr mp;
3722
3723 mp = (MasterSeqFormPtr) GetObjectExtra (b);
3724 if (mp == NULL) return;
3725 mp->listBoxAccept = TRUE;
3726 mp->listBoxUp = FALSE;
3727 }
3728
CancelMasterSeqMessage(ButtoN b)3729 static void CancelMasterSeqMessage (ButtoN b)
3730
3731 {
3732 MasterSeqFormPtr mp;
3733
3734 mp = (MasterSeqFormPtr) GetObjectExtra (b);
3735 if (mp == NULL) return;
3736 mp->listBoxAccept = FALSE;
3737 mp->listBoxUp = FALSE;
3738 }
3739
EnableMasterSeqChoice(GrouP g)3740 static void EnableMasterSeqChoice (GrouP g)
3741 {
3742 MasterSeqFormPtr mp;
3743
3744 mp = (MasterSeqFormPtr) GetObjectExtra (g);
3745 if (mp == NULL) return;
3746 if (GetValue (g) == 1)
3747 {
3748 Enable (mp->seq_dlg);
3749 Enable (mp->flipFeatGrp);
3750 }
3751 else
3752 {
3753 Disable (mp->seq_dlg);
3754 Disable (mp->flipFeatGrp);
3755 }
3756 }
3757
SeqNameFromValNodeProc(ValNodePtr vnp)3758 static CharPtr SeqNameFromValNodeProc (ValNodePtr vnp)
3759 {
3760 CharPtr str;
3761 Int4 buf_size = 41;
3762 SeqIdPtr sip;
3763
3764 if (vnp == NULL || vnp->data.ptrvalue == NULL)
3765 {
3766 return NULL;
3767 }
3768
3769 str = (CharPtr) MemNew (buf_size * sizeof (Char));
3770 if (str != NULL)
3771 {
3772 sip = (SeqIdPtr) vnp->data.ptrvalue;
3773 SeqIdWrite (sip, str, PRINTID_REPORT, buf_size - 1);
3774 }
3775 return str;
3776 }
3777
FreeSeqIdValNode(ValNodePtr vnp)3778 static void FreeSeqIdValNode (ValNodePtr vnp)
3779 {
3780 SeqIdPtr sip;
3781 if (vnp != NULL)
3782 {
3783 sip = (SeqIdPtr) vnp->data.ptrvalue;
3784 SeqIdFree (sip);
3785 vnp->data.ptrvalue = NULL;
3786 }
3787 }
3788
3789
CopySeqIDValNode(ValNodePtr vnp)3790 static ValNodePtr CopySeqIDValNode (ValNodePtr vnp)
3791 {
3792 ValNodePtr vnp_new;
3793
3794 vnp_new = ValNodeNew (NULL);
3795 if (vnp_new != NULL)
3796 {
3797 vnp_new->choice = vnp->choice;
3798 vnp_new->data.ptrvalue = SeqIdDup ((SeqIdPtr)vnp->data.ptrvalue);
3799 }
3800 return vnp_new;
3801 }
3802
MatchSeqIDValNode(ValNodePtr vnp1,ValNodePtr vnp2)3803 static Boolean MatchSeqIDValNode (ValNodePtr vnp1, ValNodePtr vnp2)
3804 {
3805 if (vnp1 == NULL && vnp2 == NULL)
3806 {
3807 return TRUE;
3808 }
3809 else if (vnp1 == NULL || vnp2 == NULL)
3810 {
3811 return FALSE;
3812 }
3813 else if (SeqIdComp ((SeqIdPtr) vnp1->data.ptrvalue,
3814 (SeqIdPtr) vnp1->data.ptrvalue) == SIC_YES)
3815 {
3816 return TRUE;
3817 }
3818 else
3819 {
3820 return FALSE;
3821 }
3822
3823 }
3824
3825
GetMasterStrandSeq(ValNodePtr good_list,BioseqPtr PNTR master_bsp,BoolPtr flip_for_aln,BoolPtr flip_feat)3826 static Boolean GetMasterStrandSeq
3827 (ValNodePtr good_list, BioseqPtr PNTR master_bsp, BoolPtr flip_for_aln, BoolPtr flip_feat)
3828
3829 {
3830 GrouP c;
3831 GrouP g;
3832 PrompT ppt1, ppt2, ppt3, ppt4;
3833 WindoW w;
3834 MasterSeqFormData md;
3835 ButtoN b;
3836 GrouP flipGrp;
3837 ValNodePtr vnp;
3838
3839 if (good_list == NULL || master_bsp == NULL || flip_for_aln == NULL || flip_feat == NULL)
3840 {
3841 return FALSE;
3842 }
3843 md.listBoxUp = TRUE;
3844 md.listBoxAccept = FALSE;
3845 w = ModalWindow (-50, -20, -20, -20, NULL);
3846 if (w != NULL) {
3847 g = HiddenGroup (w, -1, 0, NULL);
3848 SetGroupSpacing (g, 10, 10);
3849 ppt1 = StaticPrompt (g, "The alignment you are attempting to create contains mixed strands.",
3850 0, 0, programFont, 'c');
3851 ppt2 = StaticPrompt (g, "Do you wish to reverse complement the sequences to form the alignment?",
3852 0, 0, programFont, 'c');
3853 flipGrp = HiddenGroup (g, 2, 0, EnableMasterSeqChoice);
3854 SetObjectExtra (flipGrp, &md, NULL);
3855 RadioButton (flipGrp, "Yes");
3856 RadioButton (flipGrp, "No");
3857 SetValue (flipGrp, 2);
3858
3859 ppt3 = StaticPrompt (g, "Reverse the strands for the features as well?", 0, 0, programFont, 'c');
3860 md.flipFeatGrp = HiddenGroup (g, 2, 0, NULL);
3861 RadioButton (md.flipFeatGrp, "Yes");
3862 RadioButton (md.flipFeatGrp, "No");
3863 SetValue (md.flipFeatGrp, 1);
3864 Disable (md.flipFeatGrp);
3865
3866 ppt4 = StaticPrompt (g, "Choose a sequence with the correct strand", 0, 0, programFont, 'c');
3867 md.seq_dlg = ValNodeSelectionDialog (g, good_list, 8,
3868 SeqNameFromValNodeProc,
3869 FreeSeqIdValNode,
3870 CopySeqIDValNode,
3871 MatchSeqIDValNode,
3872 "sequence",
3873 NULL, NULL, FALSE);
3874 Disable (md.seq_dlg);
3875 c = HiddenGroup (g, 2, 0, NULL);
3876 b = DefaultButton (c, "Accept", AcceptMasterSeqMessage);
3877 SetObjectExtra (b, &md, NULL);
3878 b = PushButton (c, "Cancel", CancelMasterSeqMessage);
3879 SetObjectExtra (b, &md, NULL);
3880 AlignObjects (ALIGN_CENTER, (HANDLE) ppt1, (HANDLE) ppt2, (HANDLE) flipGrp,
3881 (HANDLE) ppt3, (HANDLE) md.flipFeatGrp,
3882 (HANDLE) ppt4, (HANDLE) md.seq_dlg,
3883 (HANDLE) c, NULL);
3884 RealizeWindow (w);
3885 Show (w);
3886 Select (w);
3887 while (md.listBoxUp) {
3888 ProcessExternalEvent ();
3889 Update ();
3890 }
3891 ProcessAnEvent ();
3892
3893 if (GetValue (flipGrp) == 1)
3894 {
3895 *flip_for_aln = TRUE;
3896 vnp = DialogToPointer (md.seq_dlg);
3897 if (vnp == NULL)
3898 {
3899 md.listBoxAccept = FALSE;
3900 }
3901 else
3902 {
3903 *master_bsp = BioseqFind ((SeqIdPtr)vnp->data.ptrvalue);
3904 }
3905 if (GetValue (md.flipFeatGrp) == 1)
3906 {
3907 *flip_feat = TRUE;
3908 }
3909 else
3910 {
3911 *flip_feat = FALSE;
3912 }
3913 }
3914 else
3915 {
3916 *flip_for_aln = FALSE;
3917 }
3918 Remove (w);
3919 }
3920 return md.listBoxAccept;
3921 }
3922
FreeSequenceIDValNodeList(ValNodePtr seqlist)3923 static ValNodePtr FreeSequenceIDValNodeList (ValNodePtr seqlist)
3924 {
3925 ValNodePtr vnp;
3926 SeqIdPtr sip;
3927
3928 if (seqlist == NULL) return NULL;
3929 for (vnp = seqlist; vnp != NULL; vnp = vnp->next)
3930 {
3931 sip = (SeqIdPtr) vnp->data.ptrvalue;
3932 SeqIdFree (sip);
3933 }
3934 ValNodeFree (seqlist);
3935 return NULL;
3936 }
3937
GetBadSequencesAndReversals(SQNBspPtr sbp,Uint2 entityID,Boolean use_new_blast,BoolPtr some_reversed,Int4Ptr num_seqs,ValNodePtr PNTR good_list_ptr,ValNodePtr PNTR bad_list_ptr)3938 static void GetBadSequencesAndReversals
3939 (SQNBspPtr sbp,
3940 Uint2 entityID,
3941 Boolean use_new_blast,
3942 BoolPtr some_reversed,
3943 Int4Ptr num_seqs,
3944 ValNodePtr PNTR good_list_ptr,
3945 ValNodePtr PNTR bad_list_ptr)
3946 {
3947 Boolean revcomp = FALSE;
3948 SQNBspPtr sbp_idx;
3949 SeqAlignPtr salp;
3950 ValNodePtr bad_list = NULL, vnp;
3951 SeqIdPtr tmp_id;
3952 Boolean dirty;
3953 ValNodePtr good_list = NULL;
3954
3955 if (sbp == NULL) return;
3956 if (some_reversed != NULL)
3957 {
3958 *some_reversed = FALSE;
3959 }
3960
3961 if (num_seqs != NULL)
3962 {
3963 *num_seqs = 1;
3964 }
3965 for (sbp_idx = sbp->next; sbp_idx != NULL; sbp_idx = sbp_idx->next)
3966 {
3967 if (num_seqs != NULL)
3968 {
3969 (*num_seqs) ++;
3970 }
3971 revcomp = FALSE;
3972 if (use_new_blast)
3973 {
3974 salp = Sequin_GlobalAlign2Seq(sbp->bsp, sbp_idx->bsp, &revcomp);
3975 }
3976 else
3977 {
3978 salp = Sqn_GlobalAlign2Seq(sbp->bsp, sbp_idx->bsp, &revcomp);
3979 }
3980 if (salp == NULL || ! ValidateSeqAlign (salp, entityID, FALSE, FALSE, TRUE, FALSE, FALSE, &dirty))
3981 {
3982 tmp_id = SeqIdDup (SeqIdFindBest (sbp_idx->bsp->id, 0));
3983 if (tmp_id != NULL)
3984 {
3985 vnp = ValNodeNew (bad_list);
3986 if (vnp != NULL)
3987 {
3988 vnp->data.ptrvalue = tmp_id;
3989 }
3990 if (bad_list == NULL)
3991 {
3992 bad_list = vnp;
3993 }
3994 }
3995 }
3996 else
3997 {
3998 if (good_list == NULL)
3999 {
4000 /* add master sequence to good list */
4001 tmp_id = SeqIdDup (SeqIdFindBest (sbp->bsp->id, 0));
4002 ValNodeAddPointer (&good_list, 0, tmp_id);
4003 }
4004 tmp_id = SeqIdDup (SeqIdFindBest (sbp_idx->bsp->id, 0));
4005 if (tmp_id != NULL)
4006 {
4007 vnp = ValNodeNew (good_list);
4008 if (vnp != NULL)
4009 {
4010 vnp->data.ptrvalue = tmp_id;
4011 }
4012 if (good_list == NULL)
4013 {
4014 good_list = vnp;
4015 }
4016 }
4017 if (revcomp)
4018 {
4019 if (some_reversed != NULL)
4020 {
4021 *some_reversed = TRUE;
4022 }
4023 }
4024 }
4025 SeqAlignFree (salp);
4026 if (revcomp)
4027 {
4028 BioseqRevComp (sbp_idx->bsp);
4029 ReverseBioseqFeatureStrands (sbp_idx->bsp);
4030 }
4031 }
4032 if (good_list_ptr != NULL)
4033 {
4034 *good_list_ptr = good_list;
4035 }
4036 else
4037 {
4038 FreeSequenceIDValNodeList (good_list);
4039 }
4040 if (bad_list_ptr != NULL)
4041 {
4042 *bad_list_ptr = bad_list;
4043 }
4044 else
4045 {
4046 FreeSequenceIDValNodeList (bad_list);
4047 }
4048 }
4049
ContinueWithBadSequences(ValNodePtr bad_list,Int4 num_seqs)4050 static MsgAnswer ContinueWithBadSequences (ValNodePtr bad_list, Int4 num_seqs)
4051 {
4052 Int4 num_bad_seq;
4053 Char buf [41];
4054 CharPtr msg_start = "BLAST is unable to create valid pairwise "
4055 "alignments for the following sequences:\n";
4056 CharPtr msg_end = "Do you want to create this alignment without "
4057 "these sequences?";
4058 CharPtr msg;
4059 Int4 msg_len;
4060 ValNodePtr vnp;
4061 SeqIdPtr tmp_id;
4062 MsgAnswer ans = ANS_YES;
4063
4064 if (bad_list == NULL) return ANS_YES;
4065 num_bad_seq = ValNodeLen (bad_list);
4066 if (num_bad_seq == 0) return ANS_YES;
4067 if (num_bad_seq == num_seqs)
4068 {
4069 Message (MSG_ERROR, "BLAST is unable to create valid pairwise alignments "
4070 "for any of the sequences. No alignment will be created.");
4071 return ANS_NO;
4072 }
4073 msg_len = StringLen (msg_start) + StringLen (msg_end)
4074 + num_bad_seq * (sizeof (buf) + 2) + 3;
4075
4076 msg = (CharPtr) MemNew (msg_len * sizeof (Char));
4077 if (msg != NULL)
4078 {
4079 StringCat (msg, msg_start);
4080 for (vnp = bad_list; vnp != NULL; vnp = vnp->next)
4081 {
4082 tmp_id = (SeqIdPtr) vnp->data.ptrvalue;
4083 SeqIdWrite (tmp_id, buf, PRINTID_REPORT, sizeof (buf) - 1);
4084 StringCat (msg, buf);
4085 if (vnp->next != NULL)
4086 {
4087 StringCat (msg, ", ");
4088 }
4089 }
4090 StringCat (msg, msg_end);
4091 ans = Message (MSG_YN, msg);
4092 MemFree (msg);
4093 }
4094 return ans;
4095 }
4096
4097 /* In order to create alignments for segmented sets, first need to change
4098 * method of collecting bioseqs to collect one set per segment, then
4099 * need to to process each set individually.
4100 */
FindSegSetsCallback(BioseqSetPtr bssp,Pointer userdata)4101 static void FindSegSetsCallback (BioseqSetPtr bssp, Pointer userdata)
4102 {
4103 SeqEntryPtr sep;
4104 BioseqSetPtr segment_set = NULL;
4105 ValNodePtr vnp;
4106 ValNodePtr PNTR seg_list;
4107 SQNBspPtr sbp;
4108
4109 if (bssp == NULL || bssp->_class != BioseqseqSet_class_segset
4110 || userdata == NULL) return;
4111
4112 for (sep = bssp->seq_set; sep != NULL && segment_set == NULL; sep = sep->next)
4113 {
4114 if (IS_Bioseq_set (sep))
4115 {
4116 segment_set = sep->data.ptrvalue;
4117 if (segment_set != NULL && segment_set->_class != BioseqseqSet_class_parts)
4118 {
4119 segment_set = NULL;
4120 }
4121 }
4122 }
4123 if (segment_set != NULL)
4124 {
4125 seg_list = (ValNodePtr PNTR) userdata;
4126 vnp = *seg_list;
4127 for (sep = segment_set->seq_set; sep != NULL; sep = sep->next)
4128 {
4129 if (!IS_Bioseq (sep)) continue;
4130 if (vnp == NULL)
4131 {
4132 vnp = ValNodeNew (*seg_list);
4133 if (*seg_list == NULL)
4134 {
4135 *seg_list = vnp;
4136 }
4137 sbp = MemNew (sizeof (SQNBsp));
4138 sbp->bsp = (BioseqPtr)sep->data.ptrvalue;
4139 sbp->next = NULL;
4140 vnp->data.ptrvalue = sbp;
4141 }
4142 else
4143 {
4144 sbp = (SQNBspPtr) vnp->data.ptrvalue;
4145 if (sbp == NULL)
4146 {
4147 sbp = MemNew (sizeof (SQNBsp));
4148 sbp->bsp = (BioseqPtr)sep->data.ptrvalue;
4149 sbp->next = NULL;
4150 vnp->data.ptrvalue = sbp;
4151 }
4152 else
4153 {
4154 while (sbp->next != NULL)
4155 {
4156 sbp = sbp->next;
4157 }
4158 sbp->next = (SQNBspPtr)MemNew(sizeof(SQNBsp));
4159 sbp->next->bsp = (BioseqPtr)(sep->data.ptrvalue);
4160 }
4161 }
4162 vnp = vnp->next;
4163 }
4164 }
4165 }
4166
FindNucBioseqsCallback(BioseqPtr bsp,Pointer userdata)4167 static void FindNucBioseqsCallback (BioseqPtr bsp, Pointer userdata)
4168 {
4169 ValNodePtr PNTR seg_list;
4170 ValNodePtr vnp;
4171 SQNBspPtr sbp;
4172
4173 if (bsp == NULL || ! ISA_na(bsp->mol) || userdata == NULL)
4174 return;
4175
4176 seg_list = (ValNodePtr PNTR) userdata;
4177 if (*seg_list == NULL)
4178 {
4179 vnp = ValNodeNew (*seg_list);
4180 if (vnp == NULL) return;
4181 *seg_list = vnp;
4182 }
4183 else
4184 {
4185 vnp = *seg_list;
4186 }
4187 sbp = (SQNBspPtr)vnp->data.ptrvalue;
4188 if (sbp == NULL)
4189 {
4190 sbp = MemNew (sizeof (SQNBsp));
4191 if (sbp == NULL) return;
4192 sbp->bsp = bsp;
4193 sbp->next = NULL;
4194 vnp->data.ptrvalue = sbp;
4195 }
4196 else
4197 {
4198 while (sbp->next != NULL)
4199 {
4200 sbp = sbp->next;
4201 }
4202 sbp->next = (SQNBspPtr)MemNew(sizeof(SQNBsp));
4203 sbp->next->bsp = bsp;
4204 }
4205 }
4206
GetAlignmentSegmentsList(SeqEntryPtr sep)4207 static ValNodePtr GetAlignmentSegmentsList (SeqEntryPtr sep)
4208 {
4209 ValNodePtr seg_list = NULL;
4210 if (sep == NULL) return NULL;
4211
4212 VisitSetsInSep (sep, &seg_list, FindSegSetsCallback);
4213 if (seg_list == NULL)
4214 {
4215 VisitBioseqsInSep (sep, &seg_list, FindNucBioseqsCallback);
4216 }
4217 return seg_list;
4218 }
4219
4220 /* This function finds the zero-based index of the single sequence in an alignment
4221 * that extends past the left side of an alignment (like a sore thumb).
4222 */
FindAlignmentLeftThumb(SeqAlignPtr salp)4223 static Int4 FindAlignmentLeftThumb (SeqAlignPtr salp)
4224 {
4225 DenseSegPtr dsp;
4226 Int4 k;
4227 Int4 sore_thumb = -1; /* because the sequence in question sticks out... */
4228 BioseqPtr bsp;
4229 SeqIdPtr sip;
4230
4231 if (salp == NULL || salp->segtype != SAS_DENSEG || salp->segs == NULL)
4232 {
4233 return -1;
4234 }
4235
4236 /* we need to examine the alignment, to see if there is a single sequence
4237 * that extends before the beginning of the alignment or past the end of
4238 * the alignment, so that we can insert additional segments with gaps for
4239 * all other sequences.
4240 */
4241
4242 dsp = (DenseSegPtr) salp->segs;
4243
4244 /* check left end of alignment */
4245 for (k = 0, sip = dsp->ids; k < dsp->dim; k++, sip = sip->next)
4246 {
4247 if (dsp->strands [k] == Seq_strand_minus)
4248 {
4249 bsp = BioseqFind (sip);
4250 if (bsp != NULL
4251 && dsp->starts [k] + dsp->lens [0] < bsp->length
4252 && dsp->starts [k] > -1)
4253 {
4254 if (sore_thumb != -1)
4255 {
4256 /* can only do this when only one sequence extends past the end */
4257 return -1;
4258 }
4259 else
4260 {
4261 sore_thumb = k;
4262 }
4263 }
4264 }
4265 else if (dsp->starts [k] > 0)
4266 {
4267 if (sore_thumb != -1)
4268 {
4269 /* can only do this when only one sequence extends past the end */
4270 return -1;
4271 }
4272 else
4273 {
4274 sore_thumb = k;
4275 }
4276 }
4277 }
4278
4279 return sore_thumb;
4280 }
4281
4282 /* This function finds the zero-based index of the single sequence in an alignment
4283 * that extends past the right side of an alignment (like a sore thumb).
4284 */
FindAlignmentRightThumb(SeqAlignPtr salp)4285 static Int4 FindAlignmentRightThumb (SeqAlignPtr salp)
4286 {
4287 DenseSegPtr dsp;
4288 Int4 k, start_index;
4289 Int4 sore_thumb = -1; /* because the sequence in question sticks out... */
4290 BioseqPtr bsp;
4291 SeqIdPtr sip;
4292
4293 if (salp == NULL || salp->segtype != SAS_DENSEG || salp->segs == NULL)
4294 {
4295 return -1;
4296 }
4297
4298 /* we need to examine the alignment, to see if there is a single sequence
4299 * that extends before the beginning of the alignment or past the end of
4300 * the alignment, so that we can insert additional segments with gaps for
4301 * all other sequences.
4302 */
4303
4304 dsp = (DenseSegPtr) salp->segs;
4305
4306 /* check right end of alignment */
4307 for (k = 0, sip = dsp->ids; k < dsp->dim; k++, sip = sip->next)
4308 {
4309 start_index = (dsp->dim * (dsp->numseg - 1)) + k ;
4310 if (dsp->strands [start_index] == Seq_strand_minus)
4311 {
4312 if (dsp->starts [start_index] > 0)
4313 {
4314 if (sore_thumb != -1)
4315 {
4316 /* can only do this when only one sequence extends past the end */
4317 return -1;
4318 }
4319 else
4320 {
4321 sore_thumb = k;
4322 }
4323 }
4324 }
4325 else
4326 {
4327 bsp = BioseqFind (sip);
4328 if (bsp != NULL
4329 && dsp->starts [start_index] > -1
4330 && dsp->starts [start_index] + dsp->lens [dsp->numseg - 1] < bsp->length)
4331 {
4332 if (sore_thumb != -1)
4333 {
4334 /* can only do this when only one sequence extends past the end */
4335 return -1;
4336 }
4337 else
4338 {
4339 sore_thumb = k;
4340 }
4341 }
4342 }
4343 }
4344
4345 return sore_thumb;
4346 }
4347
4348 /* This function looks for a single sequence extending past the left side of the
4349 * alignment and/or a single sequence extending past the right side of the alignment
4350 * and extends the alignment to cover these sequences, with gaps in the alignment for
4351 * all of the other sequences.
4352 * The function is unable to extend the alignment if more than one sequence extends
4353 * past the end of the alignment on that side.
4354 */
FixAlignmentEndStubs(SeqAlignPtr salp)4355 static void FixAlignmentEndStubs (SeqAlignPtr salp)
4356 {
4357 DenseSegPtr dsp, dsp_new;
4358 Int4 k;
4359 Int4 left_thumb, right_thumb; /* because the sequence in question sticks out... */
4360 BioseqPtr bsp;
4361 Int4 extra_segs = 0, seg_offset = 0;
4362 SeqIdPtr sip;
4363 Int4 new_index, old_index;
4364 Int4 thumb_len;
4365
4366 if (salp == NULL || salp->segtype != SAS_DENSEG || salp->segs == NULL)
4367 {
4368 return;
4369 }
4370
4371 /* we need to examine the alignment, to see if there is a single sequence
4372 * that extends before the beginning of the alignment or past the end of
4373 * the alignment, so that we can insert additional segments with gaps for
4374 * all other sequences.
4375 */
4376
4377 dsp = (DenseSegPtr) salp->segs;
4378
4379 left_thumb = FindAlignmentLeftThumb (salp);
4380 right_thumb = FindAlignmentRightThumb (salp);
4381
4382 if (left_thumb == -1 && right_thumb == 1)
4383 {
4384 return;
4385 }
4386
4387 if (left_thumb != -1)
4388 {
4389 extra_segs ++;
4390 }
4391 if (right_thumb != -1)
4392 {
4393 extra_segs ++;
4394 }
4395
4396 /* insert sequence for the thumb and gap for all of the other sequences at the
4397 * beginning of the alignment or end of the alignment.
4398 */
4399
4400 dsp_new = DenseSegNew();
4401 dsp_new->dim = dsp->dim;
4402 dsp_new->numseg = dsp->numseg + extra_segs;
4403 dsp_new->starts = (Int4Ptr) MemNew(dsp_new->dim * dsp_new->numseg * sizeof(Int4));
4404 dsp_new->lens = (Int4Ptr) MemNew(dsp_new->numseg * sizeof(Int4));
4405 dsp_new->strands = (Uint1Ptr) MemNew (dsp_new->dim * dsp_new->numseg * sizeof(Int4));
4406 dsp_new->ids = dsp->ids;
4407 dsp->ids = NULL;
4408
4409 if (left_thumb != -1)
4410 {
4411 for (k = 0, sip = dsp_new->ids; k < dsp_new->dim; k++, sip = sip->next)
4412 {
4413 if (k == left_thumb)
4414 {
4415 if (dsp->strands [k] == Seq_strand_minus)
4416 {
4417 bsp = BioseqFind (sip);
4418 if (bsp == NULL)
4419 {
4420 dsp->ids = dsp_new->ids;
4421 dsp_new->ids = NULL;
4422 DenseSegFree (dsp_new);
4423 return;
4424 }
4425 thumb_len = bsp->length - dsp->starts [k] - dsp->lens [0];
4426 dsp_new->starts [k] = bsp->length - thumb_len;
4427 dsp_new->lens [0] = thumb_len;
4428 dsp_new->strands [k] = Seq_strand_minus;
4429 }
4430 else
4431 {
4432 dsp_new->starts [k] = 0;
4433 dsp_new->lens [0] = dsp->starts [k];
4434 dsp_new->strands [k] = Seq_strand_plus;
4435 }
4436 }
4437 else
4438 {
4439 dsp_new->starts [k] = -1;
4440 /* keep strand consistent with first segment */
4441 dsp_new->strands [k] = dsp->strands [k];
4442 }
4443 }
4444 seg_offset ++;
4445 }
4446
4447 /* copy middle alignment starts and strands */
4448 for (k = 0; k < dsp->dim * dsp->numseg; k++)
4449 {
4450 dsp_new->starts [k + (dsp->dim * seg_offset)] = dsp->starts [k];
4451 dsp_new->strands [k + (dsp->dim * seg_offset)] = dsp->strands [k];
4452 }
4453 /* copy middle alignment lens */
4454 for (k = 0; k < dsp->numseg; k++)
4455 {
4456 dsp_new->lens [k + seg_offset] = dsp->lens [k];
4457 }
4458
4459 /* add final segment */
4460 if (right_thumb != -1)
4461 {
4462 for (k = 0, sip = dsp_new->ids; k < dsp->dim; k++, sip = sip->next)
4463 {
4464 new_index = dsp_new->dim * (dsp_new->numseg - 1) + k;
4465 old_index = dsp->dim * (dsp->numseg - 1) + k;
4466
4467 if (k == right_thumb)
4468 {
4469 if (dsp->strands [old_index] == Seq_strand_minus)
4470 {
4471 dsp_new->starts [new_index] = 0;
4472 dsp_new->strands [new_index] = Seq_strand_minus;
4473 dsp_new->lens [dsp_new->numseg - 1] = dsp->starts [old_index];
4474 }
4475 else
4476 {
4477 bsp = BioseqFind (sip);
4478 thumb_len = bsp->length - dsp->starts [old_index] - dsp->lens [dsp->numseg - 1];
4479 dsp_new->starts [new_index] = bsp->length - thumb_len;
4480 dsp_new->lens [dsp_new->numseg - 1] = thumb_len;
4481 dsp_new->strands [new_index] = Seq_strand_plus;
4482 }
4483 }
4484 else
4485 {
4486 dsp_new->starts [new_index] = -1;
4487 /* keep strands consistent */
4488 dsp_new->strands [new_index] = dsp->strands [old_index];
4489 }
4490 }
4491 }
4492
4493 /* free the old alignment */
4494 dsp = DenseSegFree(dsp);
4495
4496 /* replace it with the new alignment */
4497 salp->segs = (Pointer)(dsp_new);
4498
4499 /* reindex the alignment */
4500 SAIndex2Free2(salp->saip);
4501 salp->saip = NULL;
4502 AlnMgr2IndexSingleChildSeqAlign(salp);
4503 }
4504
CreateOneAlignment(SQNBspPtr sbp,Uint2 entityID,BioseqSetPtr bssp,Boolean use_new_blast,FILE * fp,BoolPtr errors_in_log)4505 static Int2 CreateOneAlignment
4506 (SQNBspPtr sbp,
4507 Uint2 entityID,
4508 BioseqSetPtr bssp,
4509 Boolean use_new_blast,
4510 FILE *fp,
4511 BoolPtr errors_in_log)
4512 {
4513 BioseqPtr master_bsp;
4514 Boolean some_reversed;
4515 ValNodePtr bad_list, good_list;
4516 MsgAnswer continue_with_bad;
4517 Int4 num_seqs = 0;
4518 Boolean flip_for_aln = FALSE;
4519 Boolean flip_feat = FALSE;
4520 SeqAlignPtr salp, salp_head, salp_prev, salp_tmp, salp_mult;
4521 Boolean revcomp = FALSE;
4522 SeqIdPtr sip, sip1, sip2;
4523 Char buf [41];
4524 BioseqPtr bsp;
4525 SQNBspPtr sbp_prev;
4526 Boolean dirty;
4527 DenseSegPtr dsp;
4528 ValNodePtr vnp;
4529 Int4 num_reversed = 0;
4530
4531 if (sbp == NULL || errors_in_log == NULL) return OM_MSG_RET_ERROR;
4532
4533 master_bsp = sbp->bsp;
4534 GetBadSequencesAndReversals (sbp, entityID, use_new_blast, &some_reversed, &num_seqs, &good_list, &bad_list);
4535 continue_with_bad = ContinueWithBadSequences(bad_list, num_seqs);
4536 if (continue_with_bad != ANS_YES)
4537 {
4538 bad_list = FreeSequenceIDValNodeList (bad_list);
4539 return OM_MSG_RET_DONE;
4540 }
4541 if (some_reversed)
4542 {
4543 if (! GetMasterStrandSeq (good_list, &master_bsp, &flip_for_aln, &flip_feat))
4544 {
4545 bad_list = FreeSequenceIDValNodeList (bad_list);
4546 return OM_MSG_RET_ERROR;
4547 }
4548 }
4549
4550 if (bad_list != NULL)
4551 {
4552 fprintf (fp, "The following sequences were omitted from the alignment:\n");
4553 for (vnp = bad_list; vnp != NULL; vnp = vnp->next)
4554 {
4555 sip = (SeqIdPtr) vnp->data.ptrvalue;
4556 SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
4557 fprintf (fp, "%s\n", buf);
4558 }
4559 bad_list = FreeSequenceIDValNodeList (bad_list);
4560 *errors_in_log = TRUE;
4561 }
4562
4563 if (flip_for_aln && master_bsp != sbp->bsp)
4564 {
4565 /* we align the master with the top of the list - this will reverse the strandedness
4566 * of the top of the list if necessary.
4567 */
4568 revcomp = FALSE;
4569 if (use_new_blast)
4570 {
4571 salp = Sequin_GlobalAlign2Seq(master_bsp, sbp->bsp, &revcomp);
4572 }
4573 else
4574 {
4575 salp = Sqn_GlobalAlign2Seq(master_bsp, sbp->bsp, &revcomp);
4576 }
4577 SeqAlignFree (salp);
4578 if (revcomp)
4579 {
4580 if (!flip_feat)
4581 {
4582 ReverseBioseqFeatureStrands (sbp->bsp);
4583 }
4584 fprintf (fp, "The following sequences were reversed in order to "
4585 "construct the alignment:\n");
4586 sip = SeqIdFindBest(sbp->bsp->id, 0);
4587 SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
4588 fprintf (fp, "%s\n", buf);
4589 num_reversed ++;
4590 }
4591 }
4592
4593 bsp = sbp->bsp;
4594 sbp_prev = sbp;
4595 sbp = sbp->next;
4596 MemFree(sbp_prev);
4597 salp_head = salp_prev = NULL;
4598
4599
4600 num_seqs = 1;
4601 while (sbp != NULL)
4602 {
4603 if (ISA_na(sbp->bsp->mol))
4604 {
4605 sip1 = SeqIdDup(bsp->id);
4606 sip2 = SeqIdDup(sbp->bsp->id);
4607 revcomp = FALSE;
4608 if (use_new_blast)
4609 {
4610 salp = Sequin_GlobalAlign2Seq(bsp, sbp->bsp, &revcomp);
4611 }
4612 else
4613 {
4614 salp = Sqn_GlobalAlign2Seq(bsp, sbp->bsp, &revcomp);
4615 }
4616
4617 /* count the number of sequences we are trying to align */
4618 num_seqs ++;
4619
4620 if (salp != NULL
4621 && ! ValidateSeqAlign (salp, entityID, FALSE, FALSE, TRUE, FALSE, FALSE, &dirty))
4622 {
4623 /* if an alignment was created and the sequence was reversed to create the alignment,
4624 * but the new alignment wasn't valid, un-reverse the sequence and don't add the
4625 * sequence to the list of sequences reversed.
4626 */
4627 salp = SeqAlignFree (salp);
4628 if (revcomp)
4629 {
4630 BioseqRevComp (sbp->bsp);
4631 ReverseBioseqFeatureStrands (sbp->bsp);
4632 revcomp = FALSE;
4633 }
4634 }
4635
4636 if (salp != NULL)
4637 {
4638 if (revcomp) {
4639 if (flip_for_aln)
4640 {
4641 if (!flip_feat)
4642 {
4643 ReverseBioseqFeatureStrands (sbp->bsp);
4644 }
4645 if (num_reversed == 0)
4646 {
4647 fprintf (fp, "The following sequences were reversed in order to "
4648 "construct the alignment:\n");
4649 }
4650 sip = SeqIdFindBest(sbp->bsp->id, 0);
4651 SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
4652 fprintf (fp, "%s\n", buf);
4653 num_reversed ++;
4654 }
4655 else
4656 {
4657 /* un-reverse the sequence */
4658 BioseqRevComp (sbp->bsp);
4659 ReverseBioseqFeatureStrands (sbp->bsp);
4660 /* change the alignment to show the reversed strand */
4661 ReverseAlignmentStrand (salp, 2);
4662 }
4663 revcomp = FALSE;
4664 }
4665
4666 dsp = (DenseSegPtr)(salp->segs);
4667 SeqIdSetFree(dsp->ids);
4668 dsp->ids = sip1;
4669 dsp->ids->next = sip2;
4670 if (salp != NULL && salp_head != NULL) {
4671 salp_prev->next = salp;
4672 salp_prev = salp;
4673 } else if (salp != NULL) {
4674 salp_head = salp_prev = salp;
4675 }
4676 }
4677 }
4678 sbp_prev = sbp;
4679 sbp = sbp->next;
4680 MemFree(sbp_prev);
4681 }
4682 if (salp_head != NULL)
4683 {
4684 salp_tmp = salp_head;
4685 while (salp_tmp != NULL)
4686 {
4687 if (salp_tmp->saip != NULL)
4688 {
4689 SeqAlignIndexFree(salp_tmp->saip);
4690 salp_tmp->saip = NULL;
4691 }
4692 salp_tmp = salp_tmp->next;
4693 }
4694 AlnMgr2IndexSeqAlignEx(salp_head, FALSE);
4695 salp_mult = AlnMgr2GetSubAlign(salp_head, 0, -1, 0, TRUE);
4696 salp_mult->dim = AlnMgr2GetNumRows(salp_head);
4697 salp_mult->type = SAT_PARTIAL;
4698
4699 FixAlignmentEndStubs (salp_mult);
4700
4701 ValidateSeqAlign (salp_mult, entityID, TRUE, FALSE, TRUE, FALSE, FALSE, &dirty);
4702 SeqAlignSetFree(salp_head);
4703
4704 /* index multiple alignment */
4705 AlnMgr2IndexSeqAlignEx(salp_mult, FALSE);
4706
4707 /* break up alignment if it covers gaps of unknown length */
4708 salp_mult = MakeDiscontiguousAlignments (salp_mult);
4709
4710 } else
4711 salp_mult = NULL;
4712
4713 if (salp_mult != NULL)
4714 {
4715 /* create separate SeqAnnots for each alignment in the chain */
4716 CreateSeqAnnotsForDiscontiguousAlignments (salp_mult, entityID, bssp);
4717 ObjMgrSetDirtyFlag (entityID, TRUE);
4718 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
4719 }
4720 if (num_reversed > 0)
4721 {
4722 fprintf (fp, "%d out of %d sequences were reversed.\n", num_reversed, num_seqs);
4723 *errors_in_log = TRUE;
4724 }
4725 return OM_MSG_RET_DONE;
4726 }
4727
ReOrderOneListForMaster(ValNodePtr one_list,Int4 master_pos)4728 static void ReOrderOneListForMaster (ValNodePtr one_list, Int4 master_pos)
4729 {
4730 SQNBspPtr sbp, sbp_prev;
4731 Int4 seg_pos;
4732
4733 if (one_list == NULL || one_list->data.ptrvalue == NULL || master_pos < 2)
4734 {
4735 return;
4736 }
4737
4738 sbp = (SQNBspPtr) one_list->data.ptrvalue;
4739
4740 sbp_prev = sbp;
4741 sbp = sbp->next;
4742 seg_pos = 2;
4743 while (sbp != NULL && seg_pos != master_pos)
4744 {
4745 sbp_prev = sbp;
4746 sbp = sbp->next;
4747 seg_pos++;
4748 }
4749
4750 if (sbp != NULL)
4751 {
4752 sbp_prev->next = sbp->next;
4753 sbp->next = (SQNBspPtr) one_list->data.ptrvalue;
4754 one_list->data.ptrvalue = sbp;
4755 }
4756 }
4757
GetMasterSeq(ValNodePtr seg_aln_list)4758 static Boolean GetMasterSeq (ValNodePtr seg_aln_list)
4759
4760 {
4761 GrouP c;
4762 GrouP g;
4763 PrompT ppt1;
4764 WindoW w;
4765 MasterSeqFormData md;
4766 ButtoN b;
4767 ValNodePtr choice_name_list = NULL, vnp;
4768 SQNBspPtr sbp, seg_list;
4769 Char buf [41];
4770 Int4 master_pos;
4771 SeqIdPtr sip;
4772
4773 if (seg_aln_list == NULL || seg_aln_list->data.ptrvalue == NULL)
4774 {
4775 return FALSE;
4776 }
4777 md.listBoxUp = TRUE;
4778 md.listBoxAccept = FALSE;
4779 w = ModalWindow (-50, -20, -20, -20, NULL);
4780 if (w == NULL)
4781 {
4782 return FALSE;
4783 }
4784
4785 g = HiddenGroup (w, -1, 0, NULL);
4786 SetGroupSpacing (g, 10, 10);
4787 ppt1 = StaticPrompt (g, "Select the master sequence for this alignment.",
4788 0, 0, programFont, 'c');
4789
4790 seg_list = (SQNBspPtr) seg_aln_list->data.ptrvalue;
4791 for (sbp = seg_list; sbp != NULL; sbp = sbp->next)
4792 {
4793 sip = SeqIdFindBest (sbp->bsp->id, 0);
4794 SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
4795 ValNodeAddPointer (&choice_name_list, 0, StringSave (buf));
4796 }
4797 md.seq_dlg = SelectionDialog (g, NULL, NULL, FALSE, "sequence", choice_name_list, 8);
4798 choice_name_list = ValNodeFreeData (choice_name_list);
4799
4800 c = HiddenGroup (g, 2, 0, NULL);
4801 b = DefaultButton (c, "Accept", AcceptMasterSeqMessage);
4802 SetObjectExtra (b, &md, NULL);
4803 b = PushButton (c, "Cancel", CancelMasterSeqMessage);
4804 SetObjectExtra (b, &md, NULL);
4805 AlignObjects (ALIGN_CENTER, (HANDLE) ppt1, (HANDLE) md.seq_dlg,
4806 (HANDLE) c, NULL);
4807 RealizeWindow (w);
4808 Show (w);
4809 Select (w);
4810 while (md.listBoxUp) {
4811 ProcessExternalEvent ();
4812 Update ();
4813 }
4814 ProcessAnEvent ();
4815
4816 vnp = DialogToPointer (md.seq_dlg);
4817 if (vnp == NULL || vnp->data.intvalue == 0)
4818 {
4819 md.listBoxAccept = FALSE;
4820 }
4821 else
4822 {
4823 master_pos = vnp->data.intvalue;
4824 for (vnp = seg_aln_list; vnp != NULL; vnp = vnp->next)
4825 {
4826 ReOrderOneListForMaster (vnp, master_pos);
4827 }
4828 }
4829 Remove (w);
4830 return md.listBoxAccept;
4831 }
4832
4833
AddSeqAlignForSeqEntry(SeqEntryPtr sep,Uint2 entityID,Boolean choose_master,Boolean use_new_blast)4834 extern Int2 AddSeqAlignForSeqEntry (SeqEntryPtr sep, Uint2 entityID, Boolean choose_master, Boolean use_new_blast)
4835 {
4836 SQNBspPtr sbp;
4837 Char path [PATH_MAX]; /* path for log of sequences reversed during alignment */
4838 FILE *fp; /* file pointer for sequence reverse log */
4839 Boolean errors_in_log = FALSE;
4840 ValNodePtr seg_aln_list, vnp;
4841 BioseqSetPtr bssp = NULL;
4842
4843 if (sep == NULL || sep->data.ptrvalue == NULL || !IS_Bioseq_set (sep)) return OM_MSG_RET_ERROR;
4844
4845 bssp = (BioseqSetPtr) sep->data.ptrvalue;
4846 seg_aln_list = GetAlignmentSegmentsList (sep);
4847
4848 if (choose_master)
4849 {
4850 if (!GetMasterSeq (seg_aln_list))
4851 {
4852 return OM_MSG_RET_ERROR;
4853 }
4854 }
4855
4856 TmpNam (path);
4857 fp = FileOpen (path, "wb");
4858 if (fp == NULL) return OM_MSG_RET_ERROR;
4859
4860 for (vnp = seg_aln_list; vnp != NULL; vnp = vnp->next)
4861 {
4862 sbp = vnp->data.ptrvalue;
4863 if (sbp == NULL) continue;
4864 CreateOneAlignment (sbp, entityID, bssp, use_new_blast, fp, &errors_in_log);
4865 }
4866
4867 FileClose (fp);
4868 if (errors_in_log > 0) {
4869 LaunchGeneralTextViewer (path, "Alignment Notes");
4870 }
4871 FileRemove (path);
4872 return OM_MSG_RET_DONE;
4873 }
4874
4875
GenerateSeqAlignMenuItem(IteM i)4876 extern void GenerateSeqAlignMenuItem (IteM i)
4877 {
4878 BaseFormPtr bfp;
4879 SeqEntryPtr sep;
4880
4881 #ifdef WIN_MAC
4882 bfp = currentFormDataPtr;
4883 #else
4884 bfp = GetObjectExtra (i);
4885 #endif
4886 if (bfp == NULL) return;
4887
4888 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
4889 if (sep == NULL || !IS_Bioseq_set (sep)) {
4890 Message (MSG_ERROR, "This record does not have a top-levelset!");
4891 } else {
4892 AddSeqAlignForSeqEntry (sep, bfp->input_entityID, FALSE, TRUE);
4893 }
4894 }
4895
4896 static Int2 LIBCALLBACK
GenerateSeqAlignFromSeqEntryMasterOption(Pointer data,Boolean choose_master,Boolean use_new_blast)4897 GenerateSeqAlignFromSeqEntryMasterOption
4898 (Pointer data,
4899 Boolean choose_master,
4900 Boolean use_new_blast)
4901
4902 {
4903 OMProcControlPtr ompcp;
4904 SeqEntryPtr sep;
4905 BioseqSetPtr bssp = NULL;
4906
4907 ompcp = (OMProcControlPtr) data;
4908 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
4909 switch (ompcp->input_itemtype) {
4910 case OBJ_BIOSEQ :
4911 Message (MSG_ERROR, "Must select BioseqSet to create alignment");
4912 return OM_MSG_RET_ERROR;
4913 break;
4914 case OBJ_BIOSEQSET :
4915 bssp = (BioseqSetPtr) ompcp->input_data;
4916 if (bssp == NULL) {
4917 Message (MSG_ERROR, "Must select BioseqSet to create alignment");
4918 return OM_MSG_RET_ERROR;
4919 }
4920 break;
4921 case 0 :
4922 return OM_MSG_RET_ERROR;
4923 default :
4924 return OM_MSG_RET_ERROR;
4925 }
4926 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
4927 sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
4928 if (sep == NULL) return OM_MSG_RET_ERROR;
4929
4930 return AddSeqAlignForSeqEntry (sep, ompcp->input_entityID, choose_master, use_new_blast);
4931 }
4932
GenerateSeqAlignFromSeqEntryUseNewBlast(Pointer data)4933 static Int2 LIBCALLBACK GenerateSeqAlignFromSeqEntryUseNewBlast (Pointer data)
4934
4935 {
4936 return GenerateSeqAlignFromSeqEntryMasterOption (data, FALSE, TRUE);
4937 }
4938
GenerateSeqAlignFromSeqEntryChooseMasterUseNewBlast(Pointer data)4939 static Int2 LIBCALLBACK GenerateSeqAlignFromSeqEntryChooseMasterUseNewBlast (Pointer data)
4940
4941 {
4942 return GenerateSeqAlignFromSeqEntryMasterOption (data, TRUE, TRUE);
4943 }
4944
GenerateSeqAlignFromSeqEntryProtEx(Pointer data,Boolean use_new_blast)4945 static Int2 LIBCALLBACK GenerateSeqAlignFromSeqEntryProtEx (Pointer data, Boolean use_new_blast)
4946
4947 {
4948 BioseqPtr bsp;
4949 BioseqSetPtr bssp;
4950 SeqAnnotPtr curr;
4951 OMProcControlPtr ompcp;
4952 SeqAlignPtr salp;
4953 SeqAlignPtr salp_head;
4954 SeqAlignPtr salp_mult;
4955 SeqAlignPtr salp_prev;
4956 SeqAlignPtr salp_tmp;
4957 SeqAnnotPtr sap;
4958 SeqAnnotPtr PNTR sapp;
4959 SQNBspPtr sbp;
4960 SQNBspPtr sbp_prev;
4961 SeqEntryPtr sep;
4962
4963 ompcp = (OMProcControlPtr) data;
4964 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
4965 switch (ompcp->input_itemtype) {
4966 case OBJ_BIOSEQ :
4967 break;
4968 case OBJ_BIOSEQSET :
4969 break;
4970 case 0 :
4971 return OM_MSG_RET_ERROR;
4972 default :
4973 return OM_MSG_RET_ERROR;
4974 }
4975 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
4976 sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
4977 if (sep == NULL) return OM_MSG_RET_ERROR;
4978 sbp = (SQNBspPtr)MemNew(sizeof(SQNBsp));
4979 SeqEntryExplore(sep, sbp, SQNGetBioseqsProt);
4980 bsp = sbp->bsp;
4981 sbp_prev = sbp;
4982 sbp = sbp->next;
4983 MemFree(sbp_prev);
4984 salp_head = salp_prev = NULL;
4985 while (sbp != NULL)
4986 {
4987 if (use_new_blast)
4988 {
4989 salp = Sequin_GlobalAlign2Seq(bsp, sbp->bsp, FALSE);
4990 }
4991 else
4992 {
4993 salp = Sqn_GlobalAlign2Seq(bsp, sbp->bsp, FALSE);
4994 }
4995 if (salp_head != NULL && salp != NULL)
4996 {
4997 salp_prev->next = salp;
4998 salp_prev = salp;
4999 } else if (salp != NULL)
5000 salp_head = salp_prev = salp;
5001 sbp_prev = sbp;
5002 sbp = sbp->next;
5003 MemFree(sbp_prev);
5004 }
5005 if (salp_head != NULL)
5006 {
5007 salp_tmp = salp_head;
5008 while (salp_tmp != NULL)
5009 {
5010 if (salp_tmp->saip != NULL)
5011 {
5012 SeqAlignIndexFree(salp_tmp->saip);
5013 salp_tmp->saip = NULL;
5014 }
5015 salp_tmp = salp_tmp->next;
5016 }
5017 AlnMgr2IndexSeqAlign(salp_head);
5018 salp_mult = AlnMgr2GetSubAlign(salp_head, 0, -1, 0, TRUE);
5019 salp_mult->dim = AlnMgr2GetNumRows(salp_head);
5020 salp_mult->type = SAT_PARTIAL;
5021 FixAlignmentEndStubs (salp_mult);
5022 SeqAlignSetFree(salp_head);
5023 sap = SeqAnnotForSeqAlign(salp_mult);
5024 } else
5025 sap = NULL;
5026 if (sap != NULL) {
5027
5028 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
5029 if (sep != NULL && sep->data.ptrvalue != NULL) {
5030 sapp = NULL;
5031 if (IS_Bioseq (sep)) {
5032 bsp = (BioseqPtr) sep->data.ptrvalue;
5033 sapp = &(bsp->annot);
5034 } else if (IS_Bioseq_set (sep)) {
5035 bssp = (BioseqSetPtr) sep->data.ptrvalue;
5036 sapp = &(bssp->annot);
5037 }
5038 if (sapp != NULL) {
5039 if (*sapp != NULL) {
5040 curr = *sapp;
5041 while (curr->next != NULL) {
5042 curr = curr->next;
5043 }
5044 curr->next = sap;
5045 } else {
5046 *sapp = sap;
5047 }
5048 }
5049 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
5050 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
5051 }
5052 }
5053 return OM_MSG_RET_DONE;
5054 }
5055
5056
GenerateSeqAlignFromSeqEntryProtUseNewBlast(Pointer data)5057 static Int2 LIBCALLBACK GenerateSeqAlignFromSeqEntryProtUseNewBlast (Pointer data)
5058 {
5059 return GenerateSeqAlignFromSeqEntryProtEx (data, TRUE);
5060 }
5061
RawSeqLaunchFunc(GatherContextPtr gcp)5062 static Boolean RawSeqLaunchFunc (GatherContextPtr gcp)
5063
5064 {
5065 BioseqPtr bsp;
5066 Int2 handled;
5067
5068 if (gcp == NULL) return TRUE;
5069 bsp = (BioseqPtr) gcp->userdata;
5070 if (bsp == NULL) return TRUE;
5071 if (gcp->thistype == OBJ_BIOSEQ) {
5072 if (bsp == (BioseqPtr) gcp->thisitem) {
5073 WatchCursor ();
5074 handled = GatherProcLaunch (OMPROC_EDIT, FALSE, gcp->entityID, gcp->itemID,
5075 OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
5076 ArrowCursor ();
5077 if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
5078 /*
5079 Message (MSG_ERROR, "Unable to launch editor on sequence.");
5080 */
5081 }
5082 return FALSE;
5083 }
5084 }
5085 return TRUE;
5086 }
5087
BioseqSegEditFunc(Pointer data)5088 extern Int2 LIBCALLBACK BioseqSegEditFunc (Pointer data)
5089
5090 {
5091 BioseqPtr bsp;
5092 GatherScope gs;
5093 SeqIdPtr sip;
5094 SeqLocPtr slp = NULL;
5095 OMProcControlPtr ompcp;
5096
5097 ompcp = (OMProcControlPtr) data;
5098 slp = NULL;
5099 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
5100 switch (ompcp->input_itemtype) {
5101 case OBJ_BIOSEQ_SEG :
5102 slp = (SeqLocPtr) ompcp->input_data;
5103 break;
5104 case 0 :
5105 return OM_MSG_RET_ERROR;
5106 default :
5107 return OM_MSG_RET_ERROR;
5108 }
5109 if (slp == NULL) return OM_MSG_RET_ERROR;
5110 sip = SeqLocId (slp);
5111 if (sip == NULL) return OM_MSG_RET_ERROR;
5112 bsp = BioseqFind (sip);
5113 if (bsp == NULL) return OM_MSG_RET_ERROR;
5114 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
5115 gs.seglevels = 1;
5116 gs.get_feats_location = TRUE;
5117 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
5118 gs.ignore[OBJ_BIOSEQ] = FALSE;
5119 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
5120 GatherEntity (ompcp->input_entityID, (Pointer) bsp, RawSeqLaunchFunc, &gs);
5121
5122 return OM_MSG_RET_DONE;
5123 }
5124
SeqLocCopyOne(SeqLocPtr slp)5125 static SeqLocPtr SeqLocCopyOne (SeqLocPtr slp)
5126 {
5127 SeqLocPtr slpnew, slptemp;
5128
5129 slptemp = slp->next;
5130 slp->next = NULL;
5131 slpnew = AsnIoMemCopy ((Pointer) slp, (AsnReadFunc) SeqLocAsnRead,
5132 (AsnWriteFunc) SeqLocAsnWrite);
5133 slp->next = slptemp;
5134 return slpnew;
5135 }
5136
SeqFeatCopy(SeqFeatPtr sfp)5137 extern SeqFeatPtr SeqFeatCopy (SeqFeatPtr sfp)
5138 {
5139 SeqFeatPtr sfpnew;
5140
5141 sfpnew = AsnIoMemCopy ((Pointer) sfp, (AsnReadFunc) SeqFeatAsnRead,
5142 (AsnWriteFunc) SeqFeatAsnWrite);
5143 return sfpnew;
5144 }
5145
5146 static void
SetExplodedProtein(BioseqPtr orig_prot,BioseqSetPtr nucprot_bssp,BioseqPtr nucbsp,SeqFeatPtr sfp,CharPtr prot_id_str,Int4 cum_offset)5147 SetExplodedProtein
5148 (BioseqPtr orig_prot,
5149 BioseqSetPtr nucprot_bssp,
5150 BioseqPtr nucbsp,
5151 SeqFeatPtr sfp,
5152 CharPtr prot_id_str,
5153 Int4 cum_offset)
5154 {
5155 SeqIdPtr prot_sip;
5156 BioseqPtr new_prot;
5157 SeqEntryPtr prot_sep, sep_last;
5158 Int4 frame_shift, prot_start, prot_stop;
5159 Int4 loc_len, adjusted_len = 0, prot_len;
5160 CdRegionPtr crp;
5161 ValNodePtr vnp;
5162 MolInfoPtr mip;
5163 Boolean partial5, partial3;
5164
5165 if (orig_prot == NULL || nucprot_bssp == NULL
5166 || sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION
5167 || StringHasNoText (prot_id_str))
5168 {
5169 return;
5170 }
5171
5172 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
5173 if (crp == NULL)
5174 {
5175 return;
5176 }
5177
5178 prot_sip = MakeUniqueSeqID (prot_id_str);
5179 frame_shift = cum_offset % 3;
5180 if (frame_shift == 0
5181 || (crp->frame == 3 && frame_shift == 1)
5182 || (crp->frame == 2 && frame_shift == 2))
5183 {
5184 prot_start = cum_offset / 3;
5185 }
5186 else
5187 {
5188 prot_start = cum_offset / 3 + 1;
5189 }
5190 loc_len = SeqLocLen (sfp->location);
5191 if (crp->frame == 1 || crp->frame == 0)
5192 {
5193 adjusted_len = loc_len - frame_shift;
5194 }
5195 else if (crp->frame == 2)
5196 {
5197 adjusted_len = loc_len - frame_shift - 1;
5198 }
5199 else if (crp->frame == 3)
5200 {
5201 adjusted_len = loc_len - frame_shift - 2;
5202 }
5203 prot_len = adjusted_len / 3;
5204 if (adjusted_len % 3 == 2)
5205 {
5206 prot_len ++;
5207 }
5208 prot_stop = prot_start + prot_len - 1;
5209 if (prot_stop > orig_prot->length - 1)
5210 {
5211 prot_stop = orig_prot->length - 1;
5212 }
5213 new_prot = BioseqCopyEx (prot_sip, orig_prot,
5214 prot_start,
5215 prot_stop,
5216 Seq_strand_plus, TRUE);
5217 /* add to nuc-prot set */
5218 prot_sep = SeqEntryNew ();
5219 prot_sep->choice = 1;
5220 prot_sep->data.ptrvalue = new_prot;
5221 sep_last = nucprot_bssp->seq_set;
5222 while (sep_last != NULL && sep_last->next != NULL)
5223 {
5224 sep_last = sep_last->next;
5225 }
5226 if (sep_last == NULL)
5227 {
5228 nucprot_bssp->seq_set = prot_sep;
5229 }
5230 else
5231 {
5232 sep_last->next = prot_sep;
5233 }
5234
5235 SeqMgrAddToBioseqIndex (new_prot);
5236
5237 /* set partials */
5238 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
5239 if (cum_offset > 0)
5240 {
5241 partial5 = TRUE;
5242 }
5243 if (prot_stop < orig_prot->length - 1)
5244 {
5245 partial3 = TRUE;
5246 }
5247 SetSeqLocPartial (sfp->location, partial5, partial3);
5248 sfp->partial = partial5 || partial3;
5249
5250 /* add MolInfo descriptor */
5251 vnp = SeqEntryGetSeqDescr (prot_sep, Seq_descr_molinfo, NULL);
5252 if (vnp == NULL) {
5253 vnp = CreateNewDescriptor (prot_sep, Seq_descr_molinfo);
5254 }
5255 if (vnp != NULL)
5256 {
5257 mip = (MolInfoPtr) vnp->data.ptrvalue;
5258 if (mip == NULL)
5259 {
5260 mip = MolInfoNew ();
5261 vnp->data.ptrvalue = (Pointer) mip;
5262 }
5263 if (mip != NULL) {
5264 mip->biomol = 8;
5265 mip->tech = 13;
5266 if (partial5 && partial3) {
5267 mip->completeness = 5;
5268 } else if (partial5) {
5269 mip->completeness = 3;
5270 } else if (partial3) {
5271 mip->completeness = 4;
5272 } else {
5273 mip->completeness = 0;
5274 }
5275 }
5276 }
5277
5278 /* make feature product point to new Bioseq */
5279 sfp->product = ValNodeNew (NULL);
5280 sfp->product->choice = SEQLOC_WHOLE;
5281 sfp->product->data.ptrvalue = prot_sip;
5282
5283 /* adjust frame */
5284 if (frame_shift != 0)
5285 {
5286 switch (crp->frame)
5287 {
5288 case 0:
5289 case 1:
5290 if (frame_shift == 1)
5291 {
5292 crp->frame = 3;
5293 }
5294 else if (frame_shift == 2)
5295 {
5296 crp->frame = 2;
5297 }
5298 break;
5299 case 2:
5300 if (frame_shift == 1)
5301 {
5302 crp->frame = 1;
5303 }
5304 else if (frame_shift == 2)
5305 {
5306 crp->frame = 3;
5307 }
5308 break;
5309 case 3:
5310 if (frame_shift == 1)
5311 {
5312 crp->frame = 2;
5313 }
5314 else if (frame_shift == 2)
5315 {
5316 crp->frame = 1;
5317 }
5318 break;
5319 }
5320 }
5321
5322 /* retranslate coding region */
5323 SeqEdTranslateOneCDS (sfp, nucbsp, nucbsp->idx.entityID, Sequin_GlobalAlign2Seq);
5324 }
5325
ObjectIdFromString(CharPtr str)5326 static ObjectIdPtr ObjectIdFromString (CharPtr str)
5327 {
5328 CharPtr cp;
5329 ObjectIdPtr oip;
5330
5331 oip = ObjectIdNew ();
5332
5333 if (!StringHasNoText (str)) {
5334 cp = str;
5335 while (*cp != 0 && isdigit (*cp)) {
5336 cp++;
5337 }
5338 if (*cp == 0) {
5339 oip->id = atoi (str);
5340 } else {
5341 oip->str = StringSave (str);
5342 }
5343 }
5344 return oip;
5345 }
5346
5347
IncrementObjectId(ObjectIdPtr oip)5348 static void IncrementObjectId (ObjectIdPtr oip)
5349 {
5350 Int4 len;
5351
5352 if (oip == NULL) {
5353 return;
5354 }
5355
5356 if (!StringHasNoText (oip->str)) {
5357 len = StringLen (oip->str);
5358 *(oip->str + len - 1) = *(oip->str + len - 1) + 1;
5359 } else {
5360 oip->id++;
5361 }
5362
5363 }
5364
5365
DecrementObjectId(ObjectIdPtr oip)5366 static void DecrementObjectId (ObjectIdPtr oip)
5367 {
5368 Int4 len;
5369
5370 if (oip == NULL) {
5371 return;
5372 }
5373
5374 if (!StringHasNoText (oip->str)) {
5375 len = StringLen (oip->str);
5376 *(oip->str + len - 1) = *(oip->str + len - 1) - 1;
5377 } else {
5378 oip->id--;
5379 }
5380
5381 }
5382
5383
ObjectIdLabel(ObjectIdPtr oip)5384 static CharPtr ObjectIdLabel (ObjectIdPtr oip)
5385 {
5386 Char buf[15];
5387
5388 if (oip == NULL) {
5389 return NULL;
5390 }
5391 if (!StringHasNoText (oip->str)) {
5392 return StringSave (oip->str);
5393 } else {
5394 sprintf (buf, "%d", oip->id);
5395 return StringSave (buf);
5396 }
5397 }
5398
5399
ExplodeGroup(SeqEntryPtr sep,SeqFeatPtr sfp)5400 static Boolean ExplodeGroup (SeqEntryPtr sep, SeqFeatPtr sfp)
5401
5402 {
5403 SeqFeatPtr sfpnew, sfpold, sfplast;
5404 ImpFeatPtr ifp;
5405 SeqLocPtr slphead, slp;
5406 GBQualPtr gbq;
5407 ObjectIdPtr exon_count = NULL;
5408 BioseqPtr orig_prot = NULL, nucbsp;
5409 Int4 cum_offset = 0;
5410 Char prot_id_str [128];
5411 Char prot_id_str_prefix [255];
5412 SeqEntryPtr nucprot_sep = NULL;
5413 BioseqSetPtr nucprot_bssp = NULL;
5414 ObjMgrDataPtr omdptop;
5415 ObjMgrData omdata;
5416 Uint2 parenttype;
5417 Pointer parentptr;
5418 Int4 feat_num = 1;
5419
5420 if (sfp == NULL || sfp->location == NULL) return FALSE;
5421
5422 /* save the seqloc (chain) */
5423 slphead = sfp->location;
5424 slp = SeqLocFindNext (slphead, NULL);
5425 if (slp == NULL) return FALSE;
5426
5427 /* trash the loc info in the impfeat */
5428 if (sfp->data.choice == SEQFEAT_IMP) {
5429 ifp = (ImpFeatPtr) sfp->data.value.ptrvalue;
5430 if (ifp != NULL) {
5431 ifp->loc = MemFree (ifp->loc);
5432 }
5433 }
5434
5435 /* if coding region, get copy of original protein, to use when
5436 * retranslating coding regions
5437 */
5438 if (sfp->data.choice == SEQFEAT_CDREGION && sfp->product != NULL)
5439 {
5440 orig_prot = BioseqFindFromSeqLoc (sfp->product);
5441 if (orig_prot != NULL)
5442 {
5443 nucbsp = BioseqFindFromSeqLoc (sfp->location);
5444 if (nucbsp != NULL)
5445 {
5446 nucprot_sep = GetBestTopParentForData (nucbsp->idx.entityID, nucbsp);
5447 if (nucprot_sep != NULL && IS_Bioseq_set (nucprot_sep))
5448 {
5449 nucprot_bssp = (BioseqSetPtr) nucprot_sep->data.ptrvalue;
5450 if (nucprot_bssp != NULL
5451 && nucprot_bssp->_class == BioseqseqSet_class_nuc_prot)
5452 {
5453 sfp->product = NULL;
5454 SeqIdWrite (SeqIdFindBest (orig_prot->id, SEQID_LOCAL), prot_id_str,
5455 PRINTID_REPORT, sizeof (prot_id_str) - 1);
5456 }
5457 }
5458 }
5459 if (nucprot_bssp == NULL)
5460 {
5461 orig_prot = NULL;
5462 }
5463 else
5464 {
5465 SaveSeqEntryObjMgrData (nucprot_sep, &omdptop, &omdata);
5466 GetSeqEntryParent (nucprot_sep, &parentptr, &parenttype);
5467 }
5468 }
5469 }
5470
5471
5472 /* orig sfp is copied then orig sfp data is replaced */
5473 sfplast = sfp->next;
5474 sfpnew = SeqFeatCopy (sfp);
5475
5476 /* if exon, increment /number qualifier */
5477 gbq = NULL;
5478 if (sfpnew != NULL && sfpnew->data.choice == SEQFEAT_IMP) {
5479 ifp = (ImpFeatPtr) sfpnew->data.value.ptrvalue;
5480 if (ifp != NULL) {
5481 if (StringICmp (ifp->key, "exon") == 0) {
5482 gbq = sfpnew->qual;
5483 while (gbq != NULL && StringICmp (gbq->qual, "number") != 0) {
5484 gbq = gbq->next;
5485 }
5486 if (gbq != NULL) {
5487 exon_count = ObjectIdFromString (gbq->val);
5488 }
5489 }
5490 }
5491 }
5492
5493 sfp->location = SeqLocCopyOne (slp);
5494 if (sfp->data.choice == SEQFEAT_CDREGION && orig_prot != NULL)
5495 {
5496 sprintf (prot_id_str_prefix, "%s%d", prot_id_str, feat_num);
5497 SetExplodedProtein (orig_prot, nucprot_bssp, nucbsp, sfp, prot_id_str_prefix, cum_offset);
5498 /* adjust cum_offset */
5499 cum_offset += SeqLocLen (sfp->location);
5500 feat_num++;
5501 }
5502 sfpold = sfp;
5503 slp = SeqLocFindNext (slphead, slp);
5504
5505 /* clone as many more as required */
5506 while (slp != NULL) {
5507 if (slp->choice != SEQLOC_NULL) {
5508 if (gbq != NULL) {
5509 gbq->val = MemFree (gbq->val);
5510 IncrementObjectId (exon_count);
5511 gbq->val = ObjectIdLabel (exon_count);
5512 }
5513 sfp = SeqFeatCopy (sfpnew);
5514 sfp->location = SeqLocFree (sfp->location);
5515 sfp->location = SeqLocCopyOne (slp);
5516 sfp->partial = CheckSeqLocForPartial (sfp->location, NULL, NULL);
5517
5518 if (sfp->data.choice == SEQFEAT_CDREGION && orig_prot != NULL)
5519 {
5520 sprintf (prot_id_str_prefix, "%s%d", prot_id_str, feat_num);
5521 SetExplodedProtein (orig_prot, nucprot_bssp, nucbsp, sfp, prot_id_str_prefix, cum_offset);
5522 /* adjust cum_offset */
5523 cum_offset += SeqLocLen (sfp->location);
5524 feat_num++;
5525 }
5526
5527 sfpold->next = sfp;
5528 sfpold = sfp;
5529 }
5530 slp = SeqLocFindNext (slphead, slp);
5531 }
5532 sfpold->next = sfplast;
5533 sfpnew = SeqFeatFree (sfpnew);
5534 slphead = SeqLocFree (slphead);
5535
5536 if (orig_prot != NULL)
5537 {
5538 /* mark orig_prot for deletion */
5539 orig_prot->idx.deleteme = TRUE;
5540
5541 /* relink nucprot set parent */
5542 SeqMgrLinkSeqEntry (nucprot_sep, parenttype, parentptr);
5543 RestoreSeqEntryObjMgrData (nucprot_sep, omdptop, &omdata);
5544 }
5545
5546 return TRUE;
5547 }
5548
GroupExplodeFunc(Pointer data)5549 static Int2 LIBCALLBACK GroupExplodeFunc (Pointer data)
5550
5551 {
5552 OMProcControlPtr ompcp;
5553 SelStructPtr ssp;
5554 Boolean isDirty = FALSE;
5555 Boolean isFirstSsp;
5556 ExplodeStructPtr esp;
5557 ExplodeStructPtr firstEsp = NULL;
5558 ExplodeStructPtr lastEsp;
5559 Boolean isFirstEsp;
5560
5561 /* Check the parameter */
5562
5563 ompcp = (OMProcControlPtr) data;
5564 if (ompcp == NULL || ompcp->input_itemtype == 0)
5565 return OM_MSG_RET_ERROR;
5566
5567 /* Get the linked of list of selected items */
5568
5569 ssp = ObjMgrGetSelected();
5570
5571 /* Go through the list and save pointers */
5572 /* to the items themselves. */
5573
5574 isFirstEsp = TRUE;
5575 isFirstSsp = TRUE;
5576
5577 while (NULL != ssp) {
5578
5579 if (!isFirstSsp) {
5580 ompcp->input_entityID = ssp->entityID;
5581 ompcp->input_itemID = ssp->itemID;
5582 ompcp->input_itemtype = ssp->itemtype;
5583
5584 GatherDataForProc (ompcp, FALSE);
5585 }
5586
5587 switch (ssp->itemtype)
5588 {
5589 case OBJ_SEQFEAT:
5590
5591 esp = (ExplodeStructPtr) MemNew (sizeof (ExplodeStruct));
5592 esp->seqFeatPtr = (SeqFeatPtr) ompcp->input_data;
5593 esp->topSep = GetTopSeqEntryForEntityID (ssp->entityID);
5594
5595 if (isFirstEsp) {
5596 firstEsp = esp;
5597 isFirstEsp = FALSE;
5598 }
5599 else
5600 lastEsp->next = esp;
5601
5602 lastEsp = esp;
5603 lastEsp->next = NULL;
5604 break;
5605 default:
5606 break;
5607 }
5608
5609 isFirstSsp = FALSE;
5610 ssp = ssp->next;
5611 }
5612
5613 /* Loop through all the selected items */
5614 /* and explode each one. */
5615
5616 esp = firstEsp;
5617 while (NULL != esp) {
5618 if (ExplodeGroup (esp->topSep, esp->seqFeatPtr))
5619 isDirty = TRUE;
5620 esp = esp->next;
5621 }
5622
5623 /* If any actual exploding was done then */
5624 /* force an update to be done. */
5625
5626 if (isDirty)
5627 {
5628 /* remove any protein sequences that were marked for deletion */
5629 DeleteMarkedObjects (ompcp->input_entityID, 0, NULL);
5630
5631 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
5632 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID,
5633 ompcp->input_itemID, ompcp->input_itemtype);
5634 return OM_MSG_RET_DONE;
5635 }
5636 else
5637 return OM_MSG_RET_ERROR;
5638 }
5639
5640
SortVnpByInt(VoidPtr ptr1,VoidPtr ptr2)5641 static int LIBCALLBACK SortVnpByInt (VoidPtr ptr1, VoidPtr ptr2)
5642
5643 {
5644 ValNodePtr vnp1;
5645 ValNodePtr vnp2;
5646
5647 if (ptr1 == NULL || ptr2 == NULL) return 0;
5648 vnp1 = *((ValNodePtr PNTR) ptr1);
5649 vnp2 = *((ValNodePtr PNTR) ptr2);
5650 if (vnp1 == NULL || vnp2 == NULL) return 0;
5651
5652 if (vnp1->data.intvalue > vnp2->data.intvalue) {
5653 return 1;
5654 } else if (vnp1->data.intvalue < vnp2->data.intvalue) {
5655 return -1;
5656 }
5657
5658 return 0;
5659 }
5660
GroupExplode()5661 static void GroupExplode()
5662 {
5663 ValNodePtr entityIDList = NULL, vnp;
5664 SelStructPtr ssp;
5665 Boolean isDirty = FALSE;
5666 SeqEntryPtr sep;
5667 SeqFeatPtr sfp;
5668 SeqMgrFeatContext context;
5669
5670 ssp = ObjMgrGetSelected();
5671 if (ssp == NULL) {
5672 Message (MSG_ERROR, "Nothing selected!");
5673 return;
5674 }
5675 while (NULL != ssp) {
5676 if (ssp->itemtype == OBJ_SEQFEAT)
5677 {
5678 sep = GetTopSeqEntryForEntityID (ssp->entityID);
5679
5680 sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &context);
5681 if (sfp != NULL && ExplodeGroup (sep, sfp))
5682 {
5683 isDirty = TRUE;
5684 ValNodeAddInt (&entityIDList, 0, ssp->entityID);
5685 }
5686 }
5687 ssp = ssp->next;
5688 }
5689
5690 /* If any actual exploding was done then */
5691 /* force an update to be done. */
5692
5693 if (isDirty)
5694 {
5695 entityIDList = ValNodeSort (entityIDList, SortVnpByInt);
5696 ValNodeUnique (&entityIDList, SortVnpByInt, ValNodeFree);
5697 for (vnp = entityIDList; vnp != NULL; vnp = vnp->next) {
5698 /* remove any protein sequences that were marked for deletion */
5699 DeleteMarkedObjects (vnp->data.intvalue, 0, NULL);
5700 ObjMgrSetDirtyFlag (vnp->data.intvalue, TRUE);
5701 ObjMgrSendMsg (OM_MSG_UPDATE, vnp->data.intvalue, 0, 0);
5702 }
5703 entityIDList = ValNodeFree (entityIDList);
5704 }
5705 }
5706
5707
GroupExplodeMenuItem(IteM i)5708 extern void GroupExplodeMenuItem (IteM i)
5709 {
5710 GroupExplode();
5711 }
5712
5713
GroupExplodeToolBtn(ButtoN b)5714 extern void GroupExplodeToolBtn (ButtoN b)
5715 {
5716 GroupExplode();
5717 }
5718
5719
5720 static SeqFeatPtr
AddIntronForInterval(Int4 start,Int4 stop,Int4 last,Uint1 strand,BioseqPtr bsp,Int2 fuzz_from,Int2 fuzz_to,ObjectIdPtr part_number)5721 AddIntronForInterval
5722 (Int4 start,
5723 Int4 stop,
5724 Int4 last,
5725 Uint1 strand,
5726 BioseqPtr bsp,
5727 Int2 fuzz_from,
5728 Int2 fuzz_to,
5729 ObjectIdPtr part_number)
5730 {
5731 SeqFeatPtr sfp;
5732 ImpFeatPtr ifp;
5733 GBQualPtr gbqual;
5734 Int4 int_from, int_to;
5735
5736 if (strand == Seq_strand_minus) {
5737 int_from = stop + 1;
5738 int_to = last - 1;
5739 } else {
5740 int_from = last + 1;
5741 int_to = start - 1;
5742 }
5743 if (int_from > int_to) {
5744 return NULL;
5745 }
5746 if (int_from == 0) {
5747 fuzz_from = 2;
5748 }
5749 if (int_to == bsp->length - 1) {
5750 fuzz_to = 1;
5751 }
5752
5753 sfp = SeqFeatNew ();
5754 if (sfp == NULL) {
5755 return NULL;
5756 }
5757
5758 sfp->data.choice = SEQFEAT_IMP;
5759 AddIntToSeqFeat (sfp, int_from, int_to, bsp,
5760 fuzz_from, fuzz_to, strand);
5761
5762 ifp = ImpFeatNew ();
5763 if (ifp != NULL) {
5764 sfp->data.value.ptrvalue = (Pointer) ifp;
5765 ifp->key = StringSave ("intron");
5766 }
5767 gbqual = GBQualNew ();
5768 if (gbqual != NULL)
5769 {
5770 /* need to use the previous value */
5771 DecrementObjectId (part_number);
5772 gbqual->qual = StringSave ("number");
5773 gbqual->val = ObjectIdLabel (part_number);
5774 /* put back to original value */
5775 IncrementObjectId (part_number);
5776 gbqual->next = sfp->qual;
5777 sfp->qual = gbqual;
5778 }
5779 return sfp;
5780 }
5781
MakeExonsAndIntronsFromFeature(SeqEntryPtr sep,BioseqPtr bsp,SeqLocPtr location,SeqFeatPtr putafterhere,Boolean MakeIntrons,ObjectIdPtr first_exon_number)5782 static Boolean MakeExonsAndIntronsFromFeature (SeqEntryPtr sep, BioseqPtr bsp,
5783 SeqLocPtr location,
5784 SeqFeatPtr putafterhere,
5785 Boolean MakeIntrons,
5786 ObjectIdPtr first_exon_number)
5787
5788 {
5789 SeqFeatPtr curr;
5790 Boolean first;
5791 Int2 fuzz_from;
5792 Int2 fuzz_to;
5793 ImpFeatPtr ifp;
5794 Int4 last;
5795 SeqLocPtr next;
5796 SeqFeatPtr putbeforehere;
5797 SeqFeatPtr sfp, intron;
5798 SeqLocPtr slp;
5799 Int4 start;
5800 Int4 stop;
5801 Uint1 strand;
5802 Int4 tmp;
5803 Boolean partial5, partial3, first_partial, last_partial;
5804 GBQualPtr gbqual;
5805 ObjectIdPtr part_number;
5806 ValNodePtr merge_to_parts_list = NULL;
5807 ValNodePtr vnp;
5808
5809 if (sep == NULL || bsp == NULL || location == NULL || putafterhere == NULL) return FALSE;
5810 putbeforehere = putafterhere->next;
5811 curr = putafterhere;
5812 slp = SeqLocFindNext (location, NULL);
5813 if (slp == NULL) return FALSE;
5814 first = TRUE;
5815 last = 0;
5816 part_number = ObjectIdDup (first_exon_number);
5817 CheckSeqLocForPartial (location, &first_partial, &last_partial);
5818 while (slp != NULL) {
5819 CheckSeqLocForPartial (slp, &partial5, &partial3);
5820 next = SeqLocFindNext (location, slp);
5821 if (slp->choice != SEQLOC_NULL) {
5822 start = GetOffsetInBioseq (slp, bsp, SEQLOC_START);
5823 stop = GetOffsetInBioseq (slp, bsp, SEQLOC_STOP);
5824 strand = SeqLocStrand (slp);
5825 if (strand > Seq_strand_both_rev && strand != Seq_strand_other) {
5826 strand = Seq_strand_unknown;
5827 }
5828 fuzz_from = -1;
5829 fuzz_to = -1;
5830 if (start > stop) {
5831 tmp = start;
5832 start = stop;
5833 stop = tmp;
5834 }
5835 if (start != 0) {
5836 if (strand == Seq_strand_minus) {
5837 partial3 = FALSE;
5838 } else {
5839 partial5 = FALSE;
5840 }
5841 }
5842 if (stop != bsp->length - 1) {
5843 if (strand == Seq_strand_minus) {
5844 partial5 = FALSE;
5845 } else {
5846 partial3 = FALSE;
5847 }
5848 }
5849 if (MakeIntrons) {
5850 intron = NULL;
5851 if (!first) {
5852 intron = AddIntronForInterval (start, stop, last, strand, bsp, fuzz_from, fuzz_to, part_number);
5853 } else if (first_partial) {
5854 if (strand == Seq_strand_minus) {
5855 intron = AddIntronForInterval (start, stop, bsp->length, strand, bsp, fuzz_from, fuzz_to, part_number);
5856 } else {
5857 intron = AddIntronForInterval (start, stop, -1, strand, bsp, fuzz_from, fuzz_to, part_number);
5858 }
5859 }
5860 if (intron != NULL) {
5861 if (bsp->repr == Seq_repr_seg)
5862 {
5863 ValNodeAddPointer (&merge_to_parts_list, 0, intron);
5864 }
5865 curr->next = intron;
5866 curr = intron;
5867 }
5868 }
5869 first = FALSE;
5870 if (strand == Seq_strand_minus) {
5871 last = start;
5872 } else {
5873 last = stop;
5874 }
5875 sfp = SeqFeatNew ();
5876 if (sfp != NULL) {
5877 sfp->data.choice = SEQFEAT_IMP;
5878 AddIntToSeqFeat (sfp, start, stop, bsp,
5879 fuzz_from, fuzz_to, strand);
5880 ifp = ImpFeatNew ();
5881 if (ifp != NULL) {
5882 sfp->data.value.ptrvalue = (Pointer) ifp;
5883 ifp->key = StringSave ("exon");
5884 }
5885 SetSeqLocPartial (sfp->location, partial5, partial3);
5886 gbqual = GBQualNew ();
5887 if (gbqual != NULL)
5888 {
5889 gbqual->qual = StringSave ("number");
5890 gbqual->val = ObjectIdLabel (part_number);
5891 gbqual->next = sfp->qual;
5892 sfp->qual = gbqual;
5893 }
5894 IncrementObjectId (part_number);
5895 if (bsp->repr == Seq_repr_seg)
5896 {
5897 ValNodeAddPointer (&merge_to_parts_list, 0, sfp);
5898 }
5899 curr->next = sfp;
5900 curr = sfp;
5901 }
5902 }
5903 slp = next;
5904 }
5905 if (MakeIntrons && last_partial) {
5906 intron = NULL;
5907 if (strand == Seq_strand_minus) {
5908 intron = AddIntronForInterval (start, -1, last, strand, bsp, fuzz_from, fuzz_to, part_number);
5909 } else {
5910 intron = AddIntronForInterval (bsp->length, stop, last, strand, bsp, fuzz_from, fuzz_to, part_number);
5911 }
5912 if (intron != NULL) {
5913 if (bsp->repr == Seq_repr_seg)
5914 {
5915 ValNodeAddPointer (&merge_to_parts_list, 0, intron);
5916 }
5917 curr->next = intron;
5918 curr = intron;
5919 }
5920 }
5921
5922 curr->next = putbeforehere;
5923
5924 for (vnp = merge_to_parts_list; vnp != NULL; vnp = vnp->next)
5925 {
5926 sfp = vnp->data.ptrvalue;
5927 MergeFeatureIntervalsToParts (sfp, FALSE);
5928 }
5929 ValNodeFree (merge_to_parts_list);
5930
5931 part_number = ObjectIdFree (part_number);
5932
5933 return TRUE;
5934 }
5935
5936
5937 typedef struct makeexondata {
5938 FEATURE_FORM_BLOCK
5939
5940 ButtoN make_introns_button;
5941 TexT exon_number_field;
5942 DialoG constraint_dlg;
5943 ButtoN accept;
5944
5945 SeqEntryPtr sep;
5946 Boolean make_introns;
5947 ObjectIdPtr first_exon_number;
5948 Uint1 feature_type;
5949 ConstraintChoiceSetPtr constraint;
5950 } MakeExonData, PNTR MakeExonPtr;
5951
MakeExonsFromFeatureIntervalsVisitFunc(SeqFeatPtr sfp,Pointer userdata)5952 static void MakeExonsFromFeatureIntervalsVisitFunc (SeqFeatPtr sfp, Pointer userdata)
5953 {
5954 MakeExonPtr mep;
5955 BioseqPtr bsp;
5956
5957 if (sfp == NULL || (mep = (MakeExonPtr) userdata) == NULL
5958 || sfp->idx.subtype != mep->feature_type
5959 || !DoesObjectMatchConstraintChoiceSet(OBJ_SEQFEAT, sfp, mep->constraint))
5960 {
5961 return;
5962 }
5963
5964 mep = (MakeExonPtr) userdata;
5965 bsp = BioseqFindFromSeqLoc (sfp->location);
5966
5967 MakeExonsAndIntronsFromFeature (mep->sep, bsp, sfp->location, sfp,
5968 mep->make_introns, mep->first_exon_number);
5969
5970 }
5971
5972
DoMakeExonsFromFeatureIntervals(ButtoN b)5973 static void DoMakeExonsFromFeatureIntervals (ButtoN b)
5974 {
5975 MakeExonPtr mep;
5976 Char exon_number_str [256];
5977
5978 if (b == NULL || (mep = (MakeExonPtr) GetObjectExtra (b)) == NULL) return;
5979
5980 Hide (mep->form);
5981
5982 WatchCursor ();
5983 Update ();
5984
5985 mep->sep = GetTopSeqEntryForEntityID (mep->input_entityID);
5986 mep->make_introns = GetStatus (mep->make_introns_button);
5987 GetTitle (mep->exon_number_field,
5988 exon_number_str,
5989 sizeof (exon_number_str) - 1 );
5990
5991 mep->first_exon_number = ObjectIdFromString (exon_number_str);
5992 mep->constraint = DialogToPointer (mep->constraint_dlg);
5993
5994 VisitFeaturesInSep (mep->sep, mep,
5995 MakeExonsFromFeatureIntervalsVisitFunc);
5996 mep->first_exon_number = ObjectIdFree (mep->first_exon_number);
5997 mep->constraint = ConstraintChoiceSetFree (mep->constraint);
5998 ObjMgrSetDirtyFlag (mep->input_entityID, TRUE);
5999 ObjMgrSendMsg (OM_MSG_UPDATE, mep->input_entityID, 0, 0);
6000 ArrowCursor ();
6001 Update ();
6002 }
6003
CheckExonNumberText(TexT number_field)6004 static void CheckExonNumberText (TexT number_field)
6005 {
6006 MakeExonPtr mep;
6007
6008 if (number_field == NULL || (mep = (MakeExonPtr)GetObjectExtra (number_field)) == NULL) return;
6009 if (TextHasNoText (number_field)) {
6010 Disable (mep->accept);
6011 } else {
6012 Enable (mep->accept);
6013 }
6014 }
6015
CommonMakeExonsFromFeatureIntervals(IteM i,Boolean make_introns,Uint1 feature_type)6016 static void CommonMakeExonsFromFeatureIntervals (
6017 IteM i,
6018 Boolean make_introns,
6019 Uint1 feature_type
6020 )
6021 {
6022 BaseFormPtr bfp;
6023 MakeExonPtr mep;
6024 WindoW w;
6025 GrouP h, p, c;
6026
6027 #ifdef WIN_MAC
6028 bfp = currentFormDataPtr;
6029 #else
6030 bfp = GetObjectExtra (i);
6031 #endif
6032
6033 if (bfp == NULL) return;
6034
6035 mep = MemNew (sizeof (MakeExonData));
6036 if (mep == NULL) return;
6037 mep->input_entityID = bfp->input_entityID;
6038 mep->feature_type = feature_type;
6039
6040 if (feature_type == FEATDEF_CDS)
6041 {
6042 w = FixedWindow (-50, -33, -10, -10, "Make Exons from CDS", NULL);
6043 }
6044 else if (feature_type == FEATDEF_mRNA)
6045 {
6046 w = FixedWindow (-50, -33, -10, -10, "Make Exons from mRNA", NULL);
6047 }
6048 else
6049 {
6050 w = FixedWindow (-50, -33, -10, -10, "Make Exons from Feature", NULL);
6051 }
6052
6053 SetObjectExtra (w, mep, StdCleanupFormProc);
6054 mep->form = (ForM) w;
6055
6056 h = HiddenGroup (w, -1, 0, NULL);
6057 SetGroupSpacing (h, 10, 10);
6058
6059 p = HiddenGroup (h, 2, 0, NULL);
6060 StaticPrompt (p, "First Exon Number", 0, 0, programFont, 'c');
6061 mep->exon_number_field = DialogText (p, "1", 3, CheckExonNumberText);
6062 SetObjectExtra (mep->exon_number_field, mep, NULL);
6063 mep->make_introns_button = CheckBox (p, "Make Introns", NULL);
6064 mep->constraint_dlg = ComplexConstraintDialog(h, NULL, NULL);
6065 ChangeComplexConstraintFieldType(mep->constraint_dlg, FieldType_cds_gene_prot, NULL, Macro_feature_type_any);
6066
6067 c = HiddenGroup (h, 4, 0, NULL);
6068 mep->accept = DefaultButton (c, "Accept", DoMakeExonsFromFeatureIntervals);
6069 SetObjectExtra (mep->accept, mep, NULL);
6070 PushButton (c, "Cancel", StdCancelButtonProc);
6071 AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) mep->constraint_dlg, (HANDLE) c, NULL);
6072 RealizeWindow (w);
6073 Show (w);
6074 Update ();
6075 }
6076
MakeExonsFromCDSIntervals(IteM i)6077 extern void MakeExonsFromCDSIntervals (IteM i)
6078 {
6079 CommonMakeExonsFromFeatureIntervals (i, FALSE, FEATDEF_CDS);
6080 }
6081
MakeExonsFromMRNAIntervals(IteM i)6082 extern void MakeExonsFromMRNAIntervals (IteM i)
6083 {
6084 CommonMakeExonsFromFeatureIntervals (i, TRUE, FEATDEF_mRNA);
6085 }
6086
6087
DetachBioseq(Pointer data)6088 static Int2 LIBCALLBACK DetachBioseq (Pointer data)
6089
6090 {
6091 BioseqPtr bsp;
6092 BioseqSetPtr bssp;
6093 OMProcControlPtr ompcp;
6094 SeqEntryPtr sep;
6095
6096 ompcp = (OMProcControlPtr) data;
6097 if (ompcp == NULL || ompcp->input_itemtype == 0 || ompcp->input_data == NULL)
6098 return OM_MSG_RET_ERROR;
6099
6100 switch (ompcp->input_itemtype)
6101 {
6102 case OBJ_BIOSEQ:
6103 bsp = (BioseqPtr) ompcp->input_data;
6104 if (bsp != NULL) {
6105 sep = bsp->seqentry;
6106 if (sep != NULL) {
6107 sep->next = NULL;
6108 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
6109 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, ompcp->input_itemID, ompcp->input_itemtype);
6110 return OM_MSG_RET_DONE;
6111 }
6112 }
6113 break;
6114 case OBJ_BIOSEQSET:
6115 bssp = (BioseqSetPtr) ompcp->input_data;
6116 if (bssp != NULL) {
6117 sep = bssp->seqentry;
6118 if (sep != NULL) {
6119 sep->next = NULL;
6120 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
6121 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, ompcp->input_itemID, ompcp->input_itemtype);
6122 return OM_MSG_RET_DONE;
6123 }
6124 }
6125 break;
6126 default:
6127 return OM_MSG_RET_ERROR;
6128 }
6129
6130 return OM_MSG_RET_ERROR;
6131 }
6132
6133
6134 #define BLACK 0
6135 #define RED 4
6136 #define GREEN 2
6137 #define BLUE 1
6138 #define CYAN 3
6139 #define MAGENTA 5
6140 #define YELLOW 6
6141 #define WHITE 15
6142 #define GRAY 8
6143 #define LTGRAY 7
6144
6145 #define DKCYAN 21
6146 #define DKGREEN 22
6147 #define DKBLUE 23
6148
6149 #define ORF_LENGTH 10
6150
6151
6152 typedef struct orfviewform
6153 {
6154 FORM_MESSAGE_BLOCK
6155 IcoN icon;
6156 WindoW w;
6157 DoC doc; /* orf list doc */
6158 BioseqPtr bsp;
6159 Int2 gcode;
6160 ValNodePtr orfs;
6161 Int2 frame, strand;
6162 Int4 from, to;
6163 double dx, dy;
6164 RecT mi;
6165 Boolean orf_only;
6166 SeqLocPtr select_orf;
6167 Uint2 bsp_entityID;
6168 Uint4 bsp_itemID;
6169 Uint2 len; /* minimum length of the ORF shown */
6170 Boolean standAlone;
6171 Boolean alt_start;
6172 ParData par; /* pardata for orf list doc */
6173 GrouP orf_order;
6174 GrouP start_choice;
6175 ButtoN show_partial_btn;
6176 Boolean allow_partial;
6177 } OrfViewForm, PNTR OrfViewFormPtr;
6178
6179 static RecT mi0 = { 24, 56, 460, 200 };
6180
6181 Uint1 AAForCodon (Uint1Ptr codon, CharPtr codes); /* in seqport.c */
6182
dkCyan(void)6183 static void dkCyan (void)
6184 {
6185 SelectColor(0, 203, 196);
6186 }
6187
dkBlue(void)6188 static void dkBlue (void)
6189 {
6190 SelectColor(0, 0, 196);
6191 }
6192
dkGreen(void)6193 static void dkGreen (void)
6194 {
6195 SelectColor(0, 203, 0);
6196 }
6197
SetIntColor(int color)6198 static void SetIntColor (int color)
6199 {
6200 switch (color) {
6201 case BLACK: Black(); break;
6202 case RED: Red(); break;
6203 case GREEN: Green(); break;
6204 case BLUE: Blue(); break;
6205 case CYAN: Cyan(); break;
6206 case MAGENTA: Magenta(); break;
6207 case YELLOW: Yellow(); break;
6208 case WHITE: White(); break;
6209 case GRAY: Gray(); break;
6210 case LTGRAY: LtGray(); break;
6211 case DKCYAN: dkCyan(); break;
6212 case DKBLUE: dkBlue(); break;
6213 case DKGREEN: dkGreen(); break;
6214 }
6215 }
6216
Frame2Rect(RecT PNTR a,int color1,int color2)6217 static void Frame2Rect (RecT PNTR a, int color1, int color2)
6218 {
6219 MoveTo(a->left, a->top);
6220 SetIntColor(color1);
6221 LineTo(a->right, a->top);
6222 LineTo(a->right, a->bottom);
6223 SetIntColor(color2);
6224 LineTo(a->left, a->bottom);
6225 LineTo(a->left, a->top);
6226 }
6227
Frame3d(RecT PNTR a)6228 static void Frame3d (RecT PNTR a)
6229 {
6230 int i, in = 3;
6231
6232 SetIntColor(LTGRAY);
6233 PaintRect(a);
6234 for (i=0; i < in; i++) {
6235 if (i > 0) {
6236 InsetRect(a, 1, 1);
6237 }
6238 Frame2Rect(a, WHITE, GRAY);
6239 }
6240 for (i=0; i < in; i++) {
6241 InsetRect(a, 1, 1);
6242 }
6243 for (i=0; i < in; i++) {
6244 InsetRect(a, 1, 1);
6245 Frame2Rect(a, GRAY, WHITE);
6246 }
6247 SelectColor(0, 203, 196);
6248 PaintRect(a);
6249 }
6250
DrawColorLine(int x0,int y0,int x1,int y1,int color)6251 static void DrawColorLine (int x0, int y0, int x1, int y1, int color)
6252 {
6253 SetIntColor(color);
6254 MoveTo(x0, y0);
6255 LineTo(x1, y1);
6256 }
6257
Rect3d(RecT PNTR a,int color)6258 static void Rect3d (RecT PNTR a, int color)
6259 {
6260 Frame2Rect(a, GRAY, WHITE);
6261 InsetRect(a, 1, 1);
6262 Frame2Rect(a, GRAY, WHITE);
6263 InsetRect(a, 1, 1);
6264 if (color != -1) {
6265 SetIntColor(color);
6266 PaintRect(a);
6267 }
6268 }
6269
6270
6271
OrfQuitProc(ButtoN b)6272 static void OrfQuitProc (ButtoN b)
6273
6274 {
6275 QuitProgram ();
6276 }
6277
CloseProc(ButtoN b)6278 static void CloseProc (ButtoN b)
6279 {
6280 WindoW w;
6281
6282 w = ParentWindow (b);
6283 Remove (w);
6284 }
6285
draw_rect(SeqPortPtr spp,Int2 ir,RecT PNTR frect,CharPtr vals,CharPtr codes,Boolean paint,OrfViewFormPtr ovp,Int2 strand)6286 static void draw_rect(SeqPortPtr spp, Int2 ir, RecT PNTR frect, CharPtr vals, CharPtr codes, Boolean paint, OrfViewFormPtr ovp, Int2 strand)
6287 {
6288 Int4 pos;
6289 Uint1 codon[3], aa;
6290 Int4 len;
6291 double x;
6292 RecT r;
6293
6294 SeqPortSeek(spp, ir, SEEK_SET);
6295 frect->bottom = frect->top + 15;
6296 len = spp->totlen;
6297 if (paint) {
6298 dkGreen();
6299 } else {
6300 dkCyan();
6301 }
6302 dkCyan();
6303 PaintRect(frect);
6304 Black();
6305 FrameRect(frect);
6306 for (pos=0; pos < len-2; pos += 3) {
6307 codon[0] = SeqPortGetResidue(spp);
6308 codon[1] = SeqPortGetResidue(spp);
6309 codon[2] = SeqPortGetResidue(spp);
6310 aa = AAForCodon(codon, codes);
6311 if (aa == '*') {
6312 if (strand == Seq_strand_plus) {
6313 x = frect->left + (pos+ir)*ovp->dx;
6314 } else {
6315 x = frect->left + (len+2-(pos+ir))*ovp->dx;
6316 }
6317 DrawColorLine(x, frect->top+1, x, frect->bottom-1, RED);
6318 DrawColorLine(x+1, frect->top+1, x+1, frect->bottom-1, RED);
6319 }
6320 if (ovp->alt_start == TRUE) {
6321 aa = AAForCodon(codon, vals);
6322 }
6323 if (aa == 'M') {
6324 if (strand == Seq_strand_plus) {
6325 x = frect->left + (pos+ir)*ovp->dx;
6326 } else {
6327 x = frect->left + (len+2-(pos+ir))*ovp->dx;
6328 }
6329 DrawColorLine(x, frect->top+1, x, frect->bottom-1, WHITE);
6330 DrawColorLine(x+1, frect->top+1, x+1, frect->bottom-1, WHITE);
6331 }
6332 }
6333 if (paint) {
6334 r.top = frect->top + 1;
6335 r.bottom = frect->bottom - 1;
6336 r.left = frect->left + ovp->from*ovp->dx + 2;
6337 r.right = frect->left + ovp->to*ovp->dx - 2;
6338 Magenta();
6339 PaintRect(&r);
6340 }
6341 frect->top = frect->bottom + 4;
6342 }
6343
draw_frame(Int2 ir,RecT PNTR frect,Boolean paint,OrfViewFormPtr ovp,Int2 strand)6344 static void draw_frame(Int2 ir, RecT PNTR frect, Boolean paint, OrfViewFormPtr ovp, Int2 strand)
6345 {
6346 RecT r; /* for ORF */
6347 ValNodePtr vnp;
6348 SeqLocPtr slp;
6349 SeqIntPtr sip;
6350
6351 frect->bottom = frect->top + 15;
6352 LtGray();
6353 PaintRect(frect);
6354 Black();
6355 FrameRect(frect);
6356 for (vnp = ovp->orfs; vnp; vnp=vnp->next) {
6357 if (vnp->choice == ir) {
6358 slp = vnp->data.ptrvalue;
6359 if (slp == NULL) {
6360 continue;
6361 }
6362 sip = slp->data.ptrvalue;
6363 if (sip == NULL) {
6364 continue;
6365 }
6366 if (sip->strand == strand) {
6367 r.top = frect->top + 1;
6368 r.bottom = frect->bottom - 1;
6369 r.left = frect->left + sip->from*ovp->dx;
6370 r.right = frect->left + sip->to*ovp->dx;
6371 dkCyan();
6372 PaintRect(&r);
6373 Black();
6374 r.top = frect->top;
6375 r.bottom = frect->bottom;
6376 FrameRect(&r);
6377 }
6378 if (paint) {
6379 r.top = frect->top + 1;
6380 r.bottom = frect->bottom - 1;
6381 r.left = frect->left + ovp->from*ovp->dx + 2;
6382 r.right = frect->left + ovp->to*ovp->dx - 2;
6383 Magenta();
6384 PaintRect(&r);
6385 }
6386 }
6387 }
6388 frect->top = frect->bottom + 4;
6389 return;
6390 }
6391
draw_strands(OrfViewFormPtr ovp)6392 static void draw_strands(OrfViewFormPtr ovp)
6393 {
6394 Int2 ir, gcode;
6395 RecT frect;
6396 SeqPortPtr spp;
6397 GeneticCodePtr gcp;
6398 CharPtr vals, codes;
6399 ValNodePtr vnp;
6400 Boolean paint;
6401 RecT PNTR r;
6402
6403 r = &(ovp->mi);
6404 gcode = ovp->gcode;
6405 gcp = GeneticCodeFind(gcode, NULL); /* use universal */
6406 vals = NULL;
6407 codes = NULL;
6408 for (vnp = (ValNodePtr)gcp->data.ptrvalue; vnp != NULL; vnp = vnp->next)
6409 {
6410 if (vnp->choice == 6) /* sncbieaa */
6411 vals = (CharPtr)vnp->data.ptrvalue;
6412 else if (vnp->choice == 3) /* ncbieaa */
6413 codes = (CharPtr)vnp->data.ptrvalue;
6414 }
6415 if (vals == NULL) {
6416 vals = codes;
6417 }
6418 frect.left = r->left + 11;
6419 frect.right = r->right - 11;
6420 frect.top = r->top + 4;
6421 ovp->dx = (frect.right - frect.left - 1.) / (ovp->bsp)->length;
6422 ovp->dy = (r->bottom - r->top - 1.) / 6.;
6423 spp = SeqPortNew(ovp->bsp, 0, -1, Seq_strand_plus, Seq_code_ncbi4na);
6424 for (ir=0; ir < 3; ir++) {
6425 if (ovp->from == 0 && ovp->to == 0) {
6426 paint = FALSE;
6427 } else if (ovp->strand == Seq_strand_plus && ovp->frame == ir) {
6428 paint = TRUE;
6429 } else {
6430 paint = FALSE;
6431 }
6432 if (ovp->orf_only) {
6433 draw_frame(ir, &frect, paint, ovp, Seq_strand_plus);
6434 } else {
6435 draw_rect(spp, ir, &frect, vals, codes, paint, ovp, Seq_strand_plus);
6436 }
6437 }
6438 SeqPortFree(spp);
6439 spp = SeqPortNew(ovp->bsp, 0, -1, Seq_strand_minus, Seq_code_ncbi4na);
6440 frect.top += 7;
6441 for (ir=0; ir < 3; ir++) {
6442 if (ovp->from == 0 && ovp->to == 0) {
6443 paint = FALSE;
6444 } else if (ovp->strand == Seq_strand_minus && ovp->frame == ir) {
6445 paint = TRUE;
6446 } else {
6447 paint = FALSE;
6448 }
6449 if (ovp->orf_only) {
6450 draw_frame(ir, &frect, paint, ovp, Seq_strand_minus);
6451 } else {
6452 draw_rect(spp, ir, &frect, vals, codes, paint, ovp, Seq_strand_minus);
6453 }
6454 }
6455
6456 SeqPortFree(spp);
6457 }
6458
DrawIcon(IcoN ic0)6459 static void DrawIcon(IcoN ic0)
6460 {
6461 RecT r;
6462 OrfViewFormPtr ovp;
6463
6464 ovp = (OrfViewFormPtr) GetObjectExtra (ic0);
6465 ObjectRect(ovp->icon, &r);
6466 ovp->mi.left = mi0.left + r.left;
6467 ovp->mi.right = mi0.right + r.left;
6468 ovp->mi.top = mi0.top + r.top;
6469 ovp->mi.bottom = mi0.bottom + r.top;
6470 Frame3d(&r);
6471 Rect3d(&(ovp->mi), LTGRAY);
6472 draw_strands(ovp);
6473 }
6474
notify(DoC d,Int2 item,Int2 raw,Int2 col,Boolean event)6475 static void notify( DoC d, Int2 item, Int2 raw, Int2 col, Boolean event)
6476 {
6477 ValNodePtr vnp;
6478 SeqLocPtr slp, slptmp;
6479 SeqIntPtr sip;
6480 Int2 i;
6481 Int2 itemOld1;
6482 Int2 itemOld2;
6483 Boolean status;
6484 OrfViewFormPtr ovp;
6485 Int2 top, bottom;
6486 BaR sb;
6487 Int2 startsAt;
6488
6489 if( item == 0) {
6490 return;
6491 }
6492 ovp = (OrfViewFormPtr) GetObjectExtra (d);
6493 for (vnp = ovp->orfs, i = 1; i < item && vnp; i++, vnp=vnp->next) continue;
6494 if (vnp == NULL) {
6495 return;
6496 }
6497 if (ItemIsVisible (d, item, &top, &bottom, NULL) == FALSE) {
6498 GetItemParams (d, item, &startsAt, NULL, NULL, NULL, NULL);
6499 sb = GetSlateVScrollBar ((SlatE) d);
6500 CorrectBarValue (sb, startsAt);
6501 }
6502 GetDocHighlight(d, &itemOld1, &itemOld2);
6503 SetDocHighlight(d, item, item);
6504 UpdateDocument(d, itemOld1, itemOld2);
6505 UpdateDocument(d, item, item);
6506
6507 ovp->frame = vnp->choice;
6508 slp = vnp->data.ptrvalue;
6509 sip = slp->data.ptrvalue;
6510 ovp->strand = sip->strand;
6511 ovp->from = sip->from;
6512 ovp->to = sip->to;
6513 DrawIcon(ovp->icon);
6514 status = GetStatus(ovp->icon);
6515 SetStatus(ovp->icon, !status);
6516
6517 if (! ovp->standAlone) {
6518 slptmp = AsnIoMemCopy(slp, (AsnReadFunc) SeqLocAsnRead,
6519 (AsnWriteFunc) SeqLocAsnWrite);
6520 ovp->select_orf = slptmp;
6521 ObjMgrSelect (ovp->bsp_entityID, ovp->bsp_itemID, OBJ_BIOSEQ,
6522 OM_REGION_SEQLOC, slptmp);
6523 }
6524
6525 Update();
6526 }
6527
LaunchOrfFindCDSEditor(OrfViewFormPtr ovp)6528 static void LaunchOrfFindCDSEditor (OrfViewFormPtr ovp)
6529 {
6530 OMProcControl ompc;
6531 ObjMgrProcPtr ompp;
6532 ObjMgrPtr omp;
6533 Int2 retval;
6534
6535 if (ovp == NULL)
6536 {
6537 return;
6538 }
6539 omp = ObjMgrGet ();
6540 if (omp == NULL)
6541 {
6542 return;
6543 }
6544 ompp = NULL;
6545 while ((ompp = ObjMgrProcFindNext (omp, OMPROC_EDIT,
6546 OBJ_SEQFEAT, 0, ompp)) != NULL)
6547
6548 {
6549 if (ompp->subinputtype == FEATDEF_CDS)
6550 {
6551 break;
6552 }
6553 }
6554 if (ompp == NULL) return;
6555 MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
6556 ompc.input_entityID = ovp->bsp_entityID;
6557 ompc.input_itemID = ovp->bsp_itemID;
6558 ompc.input_itemtype = OBJ_BIOSEQ;
6559 GatherDataForProc (&ompc, FALSE);
6560 ompc.proc = ompp;
6561 retval = (*(ompp->func)) (&ompc);
6562 if (retval == OM_MSG_RET_ERROR)
6563 {
6564 ErrShow ();
6565 }
6566 }
6567
myprocessmousepos(IcoN ic,PoinT pt,Boolean edit_on_dblclick)6568 static void myprocessmousepos (IcoN ic, PoinT pt, Boolean edit_on_dblclick)
6569 {
6570 RecT r;
6571 Int2 ir;
6572 Int4 pos;
6573 ValNodePtr vnp;
6574 SeqLocPtr slp;
6575 SeqIntPtr sip;
6576 Boolean status;
6577 OrfViewFormPtr ovp;
6578 Int2 item;
6579 Int2 top, bottom;
6580 BaR sb;
6581 Int2 startsAt;
6582 DoC doc;
6583
6584 if (edit_on_dblclick && ! Nlm_dblClick)
6585 {
6586 return;
6587 }
6588
6589 ovp = GetObjectExtra((IcoN) ic);
6590 ObjectRect(ic, &r);
6591 if (!PtInRect(pt, &(ovp->mi))) {
6592 return;
6593 }
6594 doc = ovp->doc;
6595 r.left = ovp->mi.left + 11;
6596 r.right = ovp->mi.right - 11;
6597 r.top = ovp->mi.top + 4;
6598 ovp->dx = (r.right - r.left - 1.) / (ovp->bsp)->length;
6599 ovp->dy = (ovp->mi.bottom - ovp->mi.top - 1.) / 6.;
6600 for (ir=0; ir < 3; ir++) {
6601 r.bottom = r.top + 15;
6602 if (pt.y < r.bottom && pt.y > r.top) {
6603 break;
6604 }
6605 r.top = r.bottom + 4;
6606 }
6607 if (ir < 3) {
6608 pos = (pt.x - r.left)/ovp->dx - ir;
6609 for (vnp=ovp->orfs, item=1; vnp; vnp=vnp->next, item++) {
6610 slp = vnp->data.ptrvalue;
6611 if (slp == NULL) continue;
6612 sip = slp->data.ptrvalue;
6613 if (sip == NULL) continue;
6614 if (vnp->choice != ir || sip->strand != Seq_strand_plus) {
6615 continue;
6616 }
6617 if (pos < sip->to && pos > sip->from) {
6618 break;
6619 }
6620 }
6621 if (vnp == NULL) {
6622 Beep();
6623 return;
6624 }
6625 if (slp == NULL) return;
6626 if (sip == NULL) return;
6627 ovp->frame = ir;
6628 ovp->strand = sip->strand;
6629 ovp->from = sip->from;
6630 ovp->to = sip->to;
6631 ovp->select_orf = AsnIoMemCopy(slp, (AsnReadFunc) SeqLocAsnRead,
6632 (AsnWriteFunc) SeqLocAsnWrite);
6633 status = GetStatus(ic);
6634 SetStatus(ic, !status);
6635 Update();
6636 Select(doc);
6637 SetDocHighlight(doc, item, item);
6638 if (ItemIsVisible (doc, item, &top, &bottom, NULL) == FALSE) {
6639 GetItemParams (doc, item, &startsAt, NULL, NULL, NULL, NULL);
6640 sb = GetSlateVScrollBar ((SlatE) doc);
6641 CorrectBarValue (sb, startsAt);
6642 }
6643 UpdateDocument(doc, 0, 0);
6644
6645 if (! ovp->standAlone) {
6646 if (ovp->select_orf != NULL) {
6647 ObjMgrSelect (ovp->bsp_entityID, ovp->bsp_itemID, OBJ_BIOSEQ,
6648 OM_REGION_SEQLOC, ovp->select_orf);
6649 if (edit_on_dblclick)
6650 {
6651 /* launch CDS Editor */
6652 LaunchOrfFindCDSEditor (ovp);
6653 }
6654 }
6655 }
6656 Update();
6657 return;
6658 }
6659 r.top += 7;
6660 for (ir=0; ir < 3; ir++) {
6661 r.bottom = r.top + 15;
6662 if (pt.y < r.bottom && pt.y > r.top) {
6663 break;
6664 }
6665 r.top = r.bottom + 4;
6666 }
6667 if (ir < 3) {
6668 pos = (pt.x - r.left)/ovp->dx - ir;
6669 for (vnp=ovp->orfs, item=1; vnp; vnp=vnp->next, item++) {
6670 slp = vnp->data.ptrvalue;
6671 if (slp == NULL) continue;
6672 sip = slp->data.ptrvalue;
6673 if (sip == NULL) continue;
6674 if (vnp->choice != ir || sip->strand != Seq_strand_minus) {
6675 continue;
6676 }
6677 if (pos < sip->to && pos > sip->from) {
6678 break;
6679 }
6680 }
6681 if (vnp == NULL) {
6682 Beep();
6683 return;
6684 }
6685 if (slp == NULL) return;
6686 if (sip == NULL) return;
6687 ovp->frame = ir;
6688 ovp->strand = sip->strand;
6689 ovp->from = sip->from;
6690 ovp->to = sip->to;
6691 ovp->select_orf = AsnIoMemCopy(slp, (AsnReadFunc) SeqLocAsnRead,
6692 (AsnWriteFunc) SeqLocAsnWrite);
6693 status = GetStatus(ic);
6694 SetStatus(ic, !status);
6695 Update();
6696 Select(doc);
6697 SetDocHighlight(doc, item, item);
6698 if (ItemIsVisible (doc, item, &top, &bottom, NULL) == FALSE) {
6699 GetItemParams (doc, item, &startsAt, NULL, NULL, NULL, NULL);
6700 sb = GetSlateVScrollBar ((SlatE) doc);
6701 CorrectBarValue (sb, startsAt);
6702 }
6703 UpdateDocument(doc, 0, 0);
6704 }
6705 if (! ovp->standAlone) {
6706 if (ovp->select_orf != NULL) {
6707 ObjMgrSelect (ovp->bsp_entityID, ovp->bsp_itemID, OBJ_BIOSEQ,
6708 OM_REGION_SEQLOC, ovp->select_orf);
6709 if (edit_on_dblclick)
6710 {
6711 /* launch CDS Editor */
6712 LaunchOrfFindCDSEditor (ovp);
6713 }
6714 }
6715 }
6716
6717 Update();
6718 return;
6719 }
6720
myrelease(IcoN ic,PoinT pt)6721 static void myrelease(IcoN ic, PoinT pt)
6722 {
6723 myprocessmousepos (ic, pt, FALSE);
6724 }
6725
myclick(IcoN ic,PoinT pt)6726 static void myclick(IcoN ic, PoinT pt)
6727 {
6728 myprocessmousepos (ic, pt, TRUE);
6729 }
6730
6731
6732 /* show all ORF from List without starts and stops */
ORFProc(ButtoN b)6733 static void ORFProc(ButtoN b)
6734 {
6735 OrfViewFormPtr ovp;
6736 Boolean status;
6737
6738 if ((ovp = (OrfViewFormPtr) GetObjectExtra (b)) == NULL) {
6739 return;
6740 }
6741 ovp->orf_only = !ovp->orf_only;
6742 draw_strands(ovp);
6743 status = GetStatus(ovp->icon);
6744 SetStatus(ovp->icon, !status);
6745 Update();
6746 }
AddOrfListToDoc(DoC doc,ValNodePtr list)6747 static void AddOrfListToDoc(DoC doc, ValNodePtr list)
6748 {
6749 ParPtr par;
6750 ValNodePtr vnp;
6751 SeqLocPtr slp, tmp;
6752 SeqIntPtr sip;
6753 Boolean minus;
6754 Int2 l, i;
6755 CharPtr buf, str;
6756 OrfViewFormPtr ovp;
6757
6758 Reset(doc);
6759 ovp = (OrfViewFormPtr) GetObjectExtra(doc);
6760 par = (ParPtr) MemNew(sizeof (ParData));
6761 par->openSpace = FALSE;
6762 par->keepWithNext = 1;
6763 par->keepTogether = 1;
6764 par->newPage = 1;
6765 par->tabStops = 1;
6766 for (vnp = list, i=0; vnp; vnp=vnp->next, i++) {
6767 minus = FALSE;
6768 tmp = (SeqLocPtr) vnp->data.ptrvalue;
6769 slp = AsnIoMemCopy ((Pointer) tmp, (AsnReadFunc) SeqLocAsnRead,
6770 (AsnWriteFunc) SeqLocAsnWrite);
6771 if (slp == NULL) {
6772 continue;
6773 }
6774 slp->next = NULL;
6775 sip = (SeqIntPtr) slp->data.ptrvalue;
6776 if (sip->strand == Seq_strand_minus) {
6777 sip->strand = Seq_strand_plus;
6778 minus = TRUE;
6779 }
6780 str = FlatLoc(ovp->bsp, slp);
6781 MemFree(slp);
6782 l = StringLen(str);
6783 if (minus == TRUE) {
6784 buf = MemNew(l+4);
6785 sprintf(buf, "c(%s)", str);
6786 AppendText(doc, buf, par, NULL, NULL);
6787 MemFree(buf);
6788 sip->strand = Seq_strand_minus;
6789 } else {
6790 AppendText(doc, str, par, NULL, NULL);
6791 }
6792 }
6793 UpdateDocument(doc, 0, 0);
6794 }
6795
ValNodeSeqLocListFree(ValNodePtr vnp)6796 static ValNodePtr ValNodeSeqLocListFree (ValNodePtr vnp)
6797 {
6798 if (vnp != NULL) {
6799 vnp->next = ValNodeSeqLocListFree(vnp->next);
6800 vnp->data.ptrvalue = SeqLocFree (vnp->data.ptrvalue);
6801 vnp = ValNodeFree (vnp);
6802 }
6803 return vnp;
6804 }
6805
6806 static void PopulateOrfList (OrfViewFormPtr ovp);
6807 static ValNodePtr ListOrfs (BioseqPtr bsp, Boolean altstart, Int4 min_len, Boolean allow_partial);
6808 static void SortOrfs (OrfViewFormPtr ovp);
6809
AltProc(GrouP g)6810 static void AltProc(GrouP g)
6811 {
6812 OrfViewFormPtr ovp;
6813 Boolean status;
6814
6815 if ((ovp = (OrfViewFormPtr) GetObjectExtra (g)) == NULL) {
6816 return;
6817 }
6818
6819 ovp->orfs = ValNodeSeqLocListFree(ovp->orfs);
6820 if (GetValue (ovp->start_choice) == 1) {
6821 ovp->alt_start = FALSE;
6822 } else {
6823 ovp->alt_start = TRUE;
6824 }
6825 ovp->orfs = ListOrfs(ovp->bsp, ovp->alt_start, ovp->len, ovp->allow_partial);
6826 SortOrfs(ovp);
6827 PopulateOrfList (ovp);
6828 /* AddOrfListToDoc(ovp->doc, ovp->orfs); */
6829 ovp->from = 0;
6830 ovp->to = 0;
6831 draw_strands(ovp);
6832 status = GetStatus(ovp->icon);
6833 SetStatus(ovp->icon, !status);
6834 Update();
6835 }
6836
ChangeAAcutoff(PopuP p)6837 static void ChangeAAcutoff(PopuP p)
6838 {
6839 OrfViewFormPtr ovp;
6840 Int2 i;
6841 Boolean status;
6842
6843 ovp = (OrfViewFormPtr) GetObjectExtra(p);
6844 i = GetValue((PopuP) p);
6845 switch (i) {
6846 case 1:
6847 ovp->len = 10;
6848 break;
6849 case 2:
6850 ovp->len = 50;
6851 break;
6852 case 3:
6853 ovp->len = 100;
6854 break;
6855 default:
6856 ovp->len = 3;
6857 break;
6858 }
6859 ovp->orfs = ValNodeSeqLocListFree(ovp->orfs);
6860 ovp->orfs = ListOrfs(ovp->bsp, ovp->alt_start, ovp->len, ovp->allow_partial);
6861 SortOrfs(ovp);
6862 PopulateOrfList (ovp);
6863
6864 draw_strands(ovp);
6865 status = GetStatus(ovp->icon);
6866 SetStatus(ovp->icon, !status);
6867 Update();
6868 }
6869
ShowPartialOrfs(ButtoN b)6870 static void ShowPartialOrfs (ButtoN b)
6871 {
6872 OrfViewFormPtr ovp;
6873
6874 ovp = (OrfViewFormPtr) GetObjectExtra(b);
6875
6876 if (ovp == NULL)
6877 {
6878 return;
6879 }
6880
6881 ovp->allow_partial = GetStatus (ovp->show_partial_btn);
6882
6883 ovp->orfs = ValNodeSeqLocListFree(ovp->orfs);
6884 ovp->orfs = ListOrfs(ovp->bsp, ovp->alt_start, ovp->len, ovp->allow_partial);
6885 SortOrfs(ovp);
6886 PopulateOrfList (ovp);
6887
6888 draw_strands(ovp);
6889
6890 Update();
6891 }
6892
6893
OrfViewerMsgFunc(OMMsgStructPtr ommsp)6894 static Int2 LIBCALLBACK OrfViewerMsgFunc (OMMsgStructPtr ommsp)
6895
6896 {
6897 ObjMgrDataPtr omdp;
6898 OMUserDataPtr omudp;
6899 OrfViewFormPtr ovp;
6900
6901 omudp = (OMUserDataPtr)(ommsp->omuserdata);
6902 if (omudp == NULL) return OM_MSG_RET_ERROR;
6903 ovp = (OrfViewFormPtr) omudp->userdata.ptrvalue;
6904 if (ovp == NULL) return OM_MSG_RET_ERROR;
6905 switch (ommsp->message) {
6906 case OM_MSG_DEL:
6907 omdp = ObjMgrGetData (ommsp->entityID);
6908 if (omdp != NULL) {
6909 if (ObjMgrWholeEntity (omdp, ommsp->itemID, ommsp->itemtype)) {
6910 if (ovp != NULL) {
6911 Remove (ovp->form);
6912 }
6913 return OM_MSG_RET_OK;
6914 }
6915 }
6916 break;
6917 default :
6918 break;
6919 }
6920 return OM_MSG_RET_OK;
6921 }
6922
CleanupOrfViewer(GraphiC g,VoidPtr data)6923 static void CleanupOrfViewer (GraphiC g, VoidPtr data)
6924
6925 {
6926 OrfViewFormPtr ovp;
6927
6928 ovp = (OrfViewFormPtr) data;
6929 if (ovp != NULL && ovp->input_entityID > 0 && ovp->procid > 0) {
6930 ObjMgrFreeUserData (ovp->input_entityID, ovp->procid, ovp->proctype, ovp->userkey);
6931 }
6932 StdCleanupFormProc (g, data);
6933 }
6934
PopulateOrfList(OrfViewFormPtr ovp)6935 static void PopulateOrfList (OrfViewFormPtr ovp)
6936 {
6937 ValNodePtr vnp;
6938 Int4 i, l, select_pos = 0;
6939 Boolean minus;
6940 SeqLocPtr tmp, slp;
6941 SeqIntPtr sip;
6942 CharPtr str, buf;
6943
6944 if (ovp == NULL) {
6945 return;
6946 }
6947
6948 Reset (ovp->doc);
6949 for (vnp = ovp->orfs, i=0; vnp; vnp=vnp->next, i++) {
6950 minus = FALSE;
6951 tmp = (SeqLocPtr) vnp->data.ptrvalue;
6952 if (ovp->select_orf != NULL && SeqLocCompare (ovp->select_orf, tmp) == SLC_A_EQ_B) {
6953 select_pos = i + 1;
6954 }
6955 slp = AsnIoMemCopy ((Pointer) tmp, (AsnReadFunc) SeqLocAsnRead,
6956 (AsnWriteFunc) SeqLocAsnWrite);
6957 if (slp == NULL) {
6958 continue;
6959 }
6960 slp->next = NULL;
6961 sip = (SeqIntPtr) slp->data.ptrvalue;
6962 if (sip->strand == Seq_strand_minus) {
6963 sip->strand = Seq_strand_plus;
6964 minus = TRUE;
6965 }
6966 str = FlatLoc(ovp->bsp, slp);
6967 MemFree(slp);
6968 l = StringLen(str);
6969 if (minus == TRUE) {
6970 buf = MemNew(l+4);
6971 sprintf(buf, "c(%s)", str);
6972 AppendText(ovp->doc, buf, &(ovp->par), NULL, NULL);
6973 MemFree(buf);
6974 sip->strand = Seq_strand_minus;
6975 } else {
6976 AppendText(ovp->doc, str, &(ovp->par), NULL, NULL);
6977 }
6978 }
6979 notify (ovp->doc, select_pos, 0, 0, FALSE);
6980 UpdateDocument (ovp->doc, 0, 0);
6981 }
6982
SortOrfsByStart(VoidPtr vp1,VoidPtr vp2)6983 static int LIBCALLBACK SortOrfsByStart (VoidPtr vp1, VoidPtr vp2)
6984 {
6985 ValNodePtr vnp1, vnp2;
6986 ValNodePtr PNTR vnpp1;
6987 ValNodePtr PNTR vnpp2;
6988 Int4 l1, l2;
6989
6990 vnpp1 = (ValNodePtr PNTR) vp1;
6991 vnpp2 = (ValNodePtr PNTR) vp2;
6992 vnp1 = *vnpp1;
6993 vnp2 = *vnpp2;
6994
6995 if (vnp1->data.ptrvalue == NULL) {
6996 l1 = 2;
6997 } else if (vnp2->data.ptrvalue == NULL) {
6998 l2 = 2;
6999 }
7000 l1 = SeqLocStart((SeqLocPtr) vnp1->data.ptrvalue);
7001 l2 = SeqLocStart((SeqLocPtr) vnp2->data.ptrvalue);
7002
7003 if (l1 < l2)
7004 return -1;
7005 else if (l1 > l2)
7006 return 1;
7007 else
7008 return 0;
7009 }
7010
SortOrfsByLength(VoidPtr vp1,VoidPtr vp2)7011 static int LIBCALLBACK SortOrfsByLength (VoidPtr vp1, VoidPtr vp2)
7012 {
7013 ValNodePtr vnp1, vnp2;
7014 ValNodePtr PNTR vnpp1;
7015 ValNodePtr PNTR vnpp2;
7016 Int4 l1, l2;
7017
7018 vnpp1 = (ValNodePtr PNTR) vp1;
7019 vnpp2 = (ValNodePtr PNTR) vp2;
7020 vnp1 = *vnpp1;
7021 vnp2 = *vnpp2;
7022 l1 = SeqLocLen((SeqLocPtr) vnp1->data.ptrvalue);
7023 l2 = SeqLocLen((SeqLocPtr) vnp2->data.ptrvalue);
7024
7025 if (l1 > l2)
7026 return -1;
7027 else if (l1 < l2)
7028 return 1;
7029 else
7030 return 0;
7031 }
7032
7033
SortOrfs(OrfViewFormPtr ovp)7034 static void SortOrfs (OrfViewFormPtr ovp)
7035 {
7036 Int4 sort_choice;
7037
7038 if (ovp == NULL) return;
7039
7040 sort_choice = GetValue (ovp->orf_order);
7041 if (sort_choice == 1) {
7042 VnpHeapSort(&(ovp->orfs), SortOrfsByLength);
7043 } else {
7044 VnpHeapSort(&(ovp->orfs), SortOrfsByStart);
7045 }
7046 }
7047
ReorderOrfs(GrouP g)7048 static void ReorderOrfs (GrouP g)
7049 {
7050 OrfViewFormPtr ovp;
7051
7052 ovp = (OrfViewFormPtr) GetObjectExtra (g);
7053 if (ovp == NULL) return;
7054 SortOrfs (ovp);
7055 PopulateOrfList (ovp);
7056 }
7057
7058 typedef struct orfdata {
7059 Int4 curlen [6], currstart [6], sublen [6];
7060 ValNodePtr lastvnp[6];
7061 Boolean inorf [6], altstart;
7062 Int4 min_len;
7063 Int4 bioseq_len;
7064 ValNodePtr orf_list;
7065 SeqIdPtr sip;
7066 Boolean allow_partial_orf;
7067 Boolean partial_other_end[6];
7068 } OrfData, PNTR OrfDataPtr;
7069
7070
TreatLikeStop(Int2 frame,Int4 pos,Uint1 strand,Int4 len)7071 static Boolean TreatLikeStop (Int2 frame, Int4 pos, Uint1 strand, Int4 len)
7072 {
7073 Int4 remainder = len % 3;
7074 Boolean like_stop = FALSE;
7075
7076 if (strand == Seq_strand_minus) {
7077 if (pos < 3) {
7078 like_stop = TRUE;
7079 }
7080 } else {
7081 if (pos >= len - remainder - 3) {
7082 like_stop = TRUE;
7083 }
7084 }
7085 return like_stop;
7086 }
7087
7088
LookForOrfs(Int4 position,Char residue,Boolean atgStart,Boolean altStart,Boolean orfStop,Int2 frame,Uint1 strand,Pointer userdata)7089 static void LIBCALLBACK LookForOrfs (
7090 Int4 position,
7091 Char residue,
7092 Boolean atgStart,
7093 Boolean altStart,
7094 Boolean orfStop,
7095 Int2 frame,
7096 Uint1 strand,
7097 Pointer userdata
7098 )
7099
7100 {
7101 Int2 idx;
7102 OrfDataPtr odp;
7103 SeqLocPtr slp, tmp;
7104 Boolean start_of_seq = FALSE;
7105 Boolean partial_this_end = FALSE;
7106
7107 odp = (OrfDataPtr) userdata;
7108
7109 if (strand == Seq_strand_plus) {
7110
7111 /* top strand */
7112
7113 idx = frame;
7114 if (position == 0 && (atgStart || (altStart && odp->altstart)))
7115 {
7116 /* not partial at 5' end */
7117 odp->partial_other_end[idx] = FALSE;
7118 }
7119
7120 if (odp->inorf [idx]) {
7121 if (!orfStop) {
7122 /* treat the end of the sequence like a stop codon */
7123 if (odp->allow_partial_orf && TreatLikeStop(frame, position, strand, odp->bioseq_len)) {
7124 position += 3;
7125 (odp->curlen[idx])++;
7126 orfStop = TRUE;
7127 partial_this_end = TRUE;
7128 }
7129 }
7130 if (orfStop) {
7131 odp->inorf [idx] = FALSE;
7132 if (odp->curlen[idx] >= odp->min_len) {
7133 slp = SeqLocIntNew (odp->currstart [idx] + idx,
7134 MIN (position + 2, (Int4) odp->bioseq_len - 1),
7135 strand, odp->sip);
7136 SetSeqLocPartial (slp, odp->partial_other_end[idx], partial_this_end);
7137 ValNodeAddPointer (&(odp->orf_list), frame, slp);
7138 }
7139 } else {
7140 (odp->curlen [idx])++;
7141 }
7142 } else if (atgStart || (altStart && odp->altstart)) {
7143 odp->inorf [idx] = TRUE;
7144 odp->curlen [idx] = 1;
7145 odp->currstart [idx] = position - frame;
7146 odp->partial_other_end [idx] = FALSE;
7147 }
7148 } else {
7149
7150 /* bottom strand */
7151
7152 idx = frame + 3;
7153
7154 if (!orfStop && odp->allow_partial_orf) {
7155 start_of_seq = TreatLikeStop (frame, position, strand, odp->bioseq_len);
7156 }
7157 if (orfStop) {
7158 odp->curlen [idx] = 0;
7159 odp->sublen [idx] = 0;
7160 odp->currstart [idx] = position - frame;
7161 odp->partial_other_end[idx] = FALSE;
7162 } else if (start_of_seq) {
7163 odp->curlen [idx] = 1;
7164 odp->sublen [idx] = 1;
7165 odp->currstart [idx] = position - frame - 3;
7166 } else if (atgStart || (altStart && odp->altstart) || (odp->allow_partial_orf && position >= odp->bioseq_len - 5)) {
7167 (odp->sublen [idx])++;
7168 odp->curlen [idx] = odp->sublen [idx];
7169 if (odp->allow_partial_orf && position >= odp->bioseq_len - 5)
7170 {
7171 /* also include partial codon at partial end */
7172 (odp->curlen[idx]) ++;
7173 if (!atgStart && (!altStart || !odp->altstart))
7174 {
7175 partial_this_end = TRUE;
7176 }
7177 }
7178 if (odp->curlen[idx] >= odp->min_len) {
7179 slp = SeqLocIntNew (MAX ((Int4) odp->currstart [idx] + idx - 3, (Int4) 0),
7180 MIN (odp->currstart [idx] + idx - 3 + (odp->curlen [idx]) * 3 + 2, odp->bioseq_len - 1),
7181 Seq_strand_minus, odp->sip);
7182 SetSeqLocPartial (slp, partial_this_end, odp->partial_other_end[idx]);
7183 if (odp->lastvnp[idx] != NULL) {
7184 tmp = (SeqLocPtr) odp->lastvnp[idx]->data.ptrvalue;
7185 if (SeqLocStart (tmp) == SeqLocStart (slp)) {
7186 tmp = SeqLocFree (tmp);
7187 odp->lastvnp[idx]->data.ptrvalue = slp;
7188 } else {
7189 odp->lastvnp[idx] = ValNodeAddPointer (&(odp->orf_list), frame, slp);
7190 }
7191 } else {
7192 odp->lastvnp[idx] = ValNodeAddPointer (&(odp->orf_list), frame, slp);
7193 }
7194 }
7195 } else {
7196 (odp->sublen [idx])++;
7197 }
7198 }
7199 }
7200
ListOrfs(BioseqPtr bsp,Boolean altstart,Int4 min_len,Boolean allow_partial)7201 static ValNodePtr ListOrfs (
7202 BioseqPtr bsp,
7203 Boolean altstart,
7204 Int4 min_len,
7205 Boolean allow_partial
7206 )
7207
7208 {
7209 Int2 i;
7210 OrfData od;
7211 TransTablePtr tbl;
7212 Int2 genCode;
7213
7214 if (bsp == NULL) return NULL;
7215
7216 od.sip = SeqIdFindBest (bsp->id, 0);
7217 genCode = GetGcodeFromBioseq(bsp);
7218
7219
7220 for (i = 0; i < 6; i++) {
7221 od.curlen [i] = INT4_MIN;
7222 od.currstart [i] = 0;
7223 od.sublen [i] = INT4_MIN;
7224 od.inorf [i] = FALSE;
7225 od.lastvnp [i] = NULL;
7226 od.partial_other_end [i] = allow_partial;
7227 }
7228
7229 if (allow_partial) {
7230 /* allow 5' partial ORFs */
7231 for (i = 0; i < 3; i++) {
7232 od.inorf[i] = TRUE;
7233 od.curlen [i] = 1;
7234 od.currstart [i] = 0 - i;
7235 }
7236 }
7237
7238 od.altstart = altstart;
7239 od.orf_list = NULL;
7240 od.min_len = min_len;
7241 od.bioseq_len = bsp->length;
7242 od.allow_partial_orf = allow_partial;
7243
7244 /* use simultaneous 6-frame translation finite state machine */
7245
7246 tbl = PersistentTransTableByGenCode (genCode);
7247 if (tbl != NULL) {
7248 TransTableProcessBioseq (tbl, LookForOrfs, (Pointer) &od, bsp);
7249 }
7250
7251 return od.orf_list;
7252 }
7253
LaunchOrfViewer(BioseqPtr bsp,Uint2 entityID,Uint4 itemID,Boolean standAlone)7254 extern void LaunchOrfViewer (BioseqPtr bsp, Uint2 entityID, Uint4 itemID, Boolean standAlone)
7255 {
7256 ButtoN qu, b1;
7257 GrouP g, k;
7258 OrfViewFormPtr ovp;
7259 WindoW w;
7260 IcoN ic;
7261 PopuP pu;
7262 ObjMgrPtr omp;
7263 ObjMgrProcPtr ompp;
7264 OMUserDataPtr omudp;
7265
7266 WatchCursor ();
7267 Update ();
7268 ovp = (OrfViewFormPtr) MemNew (sizeof (OrfViewForm));
7269 ovp->bsp = bsp;
7270 ovp->select_orf = NULL;
7271 ovp->input_entityID = entityID;
7272 ovp->bsp_entityID = entityID;
7273 ovp->bsp_itemID = itemID;
7274 ovp->len = 10;
7275 ovp->alt_start = FALSE;
7276 ovp->allow_partial = TRUE;
7277 #if 1
7278 ovp->orfs = ListOrfs (bsp, ovp->alt_start, ovp->len, ovp->allow_partial);
7279 #else
7280 ovp->orfs = GetOrfList(bsp, ORF_LENGTH);
7281 #endif
7282 ovp->orf_only = TRUE;
7283 ovp->gcode = 1;
7284 ovp->standAlone = standAlone;
7285 w = FixedWindow(-50, -33, -10, -10, "Orf Finder", NULL);
7286 SetObjectExtra (w, ovp, CleanupOrfViewer);
7287 ovp->form = (ForM) w;
7288 g = HiddenGroup (w, 6, 0, NULL);
7289 SetGroupSpacing (g, 6, 0);
7290 if (ovp->standAlone) {
7291 qu = PushButton(g, "Quit", OrfQuitProc);
7292 } else {
7293 qu = PushButton(g, "Close", CloseProc);
7294 }
7295 b1 = PushButton(g, "ORF", ORFProc);
7296 SetObjectExtra (b1, ovp, NULL);
7297 ovp->start_choice = NormalGroup (g, 2, 0, "Initiation Codon", programFont, AltProc);
7298 SetObjectExtra (ovp->start_choice, ovp, NULL);
7299 RadioButton (ovp->start_choice, "Standard");
7300 RadioButton (ovp->start_choice, "Alternative");
7301 SetValue (ovp->start_choice, 1);
7302 StaticPrompt(g, "ORF length", 0, 16, systemFont, '1');
7303 pu = PopupList(g, TRUE, ChangeAAcutoff );
7304 PopupItem(pu, "10");
7305 PopupItem(pu, "50");
7306 PopupItem(pu, "100");
7307 SetValue(pu, 1);
7308 SetObjectExtra (pu, ovp, NULL);
7309
7310 ovp->show_partial_btn = CheckBox (g, "Show Partial ORFs", ShowPartialOrfs);
7311 SetObjectExtra (ovp->show_partial_btn, ovp, NULL);
7312 SetStatus (ovp->show_partial_btn, TRUE);
7313
7314 g = HiddenGroup (w, 2, 0, NULL);
7315 ic = IconButton(g, 500, 240,
7316 DrawIcon, NULL, myclick, NULL, NULL, myrelease);
7317 if (ovp->select_orf != NULL) {
7318 }
7319 ovp->icon = ic;
7320 SetObjectExtra (ic, ovp, NULL);
7321 k = HiddenGroup (g, 0, 2, NULL);
7322 ovp->orf_order = HiddenGroup (k, 2, 0, ReorderOrfs);
7323 RadioButton (ovp->orf_order, "Order by Length");
7324 RadioButton (ovp->orf_order, "Order by Start");
7325 SetValue (ovp->orf_order, 1);
7326 SortOrfs (ovp);
7327 SetObjectExtra (ovp->orf_order, ovp, NULL);
7328 ovp->doc = DocumentPanel(k, 10 * stdCharWidth, 240);
7329 SetObjectExtra (ovp->doc, ovp, NULL);
7330 /****/
7331 ovp->par.openSpace = FALSE;
7332 ovp->par.keepWithNext = 1;
7333 ovp->par.keepTogether = 1;
7334 ovp->par.newPage = 1;
7335 ovp->par.tabStops = 1;
7336
7337 PopulateOrfList (ovp);
7338 /****/
7339 SetDocNotify(ovp->doc, notify);
7340 /*ovp = (OrfViewFormPtr) GetObjectExtra(ic);*/
7341 omp = ObjMgrGet ();
7342 if (omp != NULL) {
7343 ompp = ObjMgrProcFind (omp, 0, "ORF Finder", OMPROC_FILTER);
7344 if (ompp != NULL) {
7345 ovp->procid = ompp->procid;
7346 ovp->proctype = OMPROC_FILTER;
7347 ovp->userkey = OMGetNextUserKey ();
7348 omudp = ObjMgrAddUserData (ovp->input_entityID, ompp->procid,
7349 OMPROC_FILTER, ovp->userkey);
7350 if (omudp != NULL) {
7351 omudp->userdata.ptrvalue = (Pointer) ovp;
7352 omudp->messagefunc = OrfViewerMsgFunc;
7353 }
7354 }
7355 }
7356 RealizeWindow (w);
7357 Show(w);
7358 ArrowCursor ();
7359 Update ();
7360 if (ovp->standAlone) {
7361 ProcessEvents();
7362 } else {
7363 return;
7364 }
7365 }
7366
7367 typedef struct mergedata {
7368 SeqLocPtr slp;
7369 Boolean fuse;
7370 } MergeData, PNTR MergeDataPtr;
7371
AddToSeqLoc(GatherContextPtr gcp)7372 static Boolean AddToSeqLoc (GatherContextPtr gcp)
7373
7374 {
7375 BioseqPtr bsp;
7376 MergeDataPtr mdp;
7377 SeqFeatPtr sfp;
7378 SeqLocPtr slp;
7379
7380 mdp = (MergeDataPtr) gcp->userdata;
7381 if (mdp == NULL) return TRUE;
7382 if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
7383 sfp = (SeqFeatPtr) gcp->thisitem;
7384 if (sfp == NULL || sfp->location == NULL) return TRUE;
7385 bsp = GetBioseqGivenSeqLoc (sfp->location, gcp->entityID);
7386 if (bsp == NULL) return TRUE;
7387 slp = SeqLocMerge (bsp, sfp->location, mdp->slp, FALSE, mdp->fuse, FALSE);
7388 mdp->slp = SeqLocFree (mdp->slp);
7389 mdp->slp = slp;
7390 return TRUE;
7391 }
7392
OrfFindFunc(Pointer data)7393 static Int2 LIBCALLBACK OrfFindFunc (Pointer data)
7394
7395 {
7396 BioseqPtr bsp;
7397 OMProcControlPtr ompcp;
7398
7399
7400 ompcp = (OMProcControlPtr) data; /* always do this cast */
7401
7402 if (ompcp == NULL || ompcp->input_itemtype == 0)
7403 return OM_MSG_RET_ERROR;
7404
7405 switch (ompcp->input_itemtype)
7406 {
7407 case OBJ_BIOSEQ:
7408 bsp = (BioseqPtr) ompcp->input_data;
7409 break;
7410 default:
7411 return OM_MSG_RET_ERROR;
7412 }
7413
7414 LaunchOrfViewer (bsp, ompcp->input_entityID, ompcp->input_itemID, FALSE);
7415 return OM_MSG_RET_DONE;
7416 }
7417
MergeSelectedFeatureIntervals(Boolean fuse)7418 static SeqLocPtr MergeSelectedFeatureIntervals (Boolean fuse)
7419
7420 {
7421 MergeData md;
7422 SelStructPtr sel;
7423
7424 md.slp = NULL;
7425 md.fuse = fuse;
7426 for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
7427 GatherItem (sel->entityID, sel->itemID, sel->itemtype,
7428 (Pointer) &md, AddToSeqLoc);
7429 }
7430 return md.slp;
7431 }
7432
IntervalCombineFunc(Pointer data)7433 static Int2 LIBCALLBACK IntervalCombineFunc (Pointer data)
7434
7435 {
7436 OMProcControlPtr ompcp;
7437 SeqLocPtr slp;
7438
7439 ompcp = (OMProcControlPtr) data;
7440 if (ompcp == NULL) return OM_MSG_RET_ERROR;
7441 slp = MergeSelectedFeatureIntervals (FALSE);
7442 if (slp == NULL) return OM_MSG_RET_ERROR;
7443 ObjMgrRegister (OBJ_SEQLOC, (Pointer) slp);
7444 return OM_MSG_RET_DONE;
7445 }
7446
IntervalCombineAndFuseFunc(Pointer data)7447 static Int2 LIBCALLBACK IntervalCombineAndFuseFunc (Pointer data)
7448
7449 {
7450 OMProcControlPtr ompcp;
7451 SeqLocPtr slp;
7452
7453 ompcp = (OMProcControlPtr) data;
7454 if (ompcp == NULL) return OM_MSG_RET_ERROR;
7455 slp = MergeSelectedFeatureIntervals (TRUE);
7456 if (slp == NULL) return OM_MSG_RET_ERROR;
7457 ObjMgrRegister (OBJ_SEQLOC, (Pointer) slp);
7458 return OM_MSG_RET_DONE;
7459 }
7460
7461 static CharPtr objmgrtypestrs [] = {
7462 "OBJ_ALL", "OBJ_SEQENTRY", "OBJ_BIOSEQ", "OBJ_BIOSEQSET", "OBJ_SEQDESC",
7463 "OBJ_SEQANNOT", "OBJ_ANNOTDESC", "OBJ_SEQFEAT", "OBJ_SEQALIGN", "OBJ_SEQGRAPH",
7464 "OBJ_SEQSUB", "OBJ_SUBMIT_BLOCK", "OBJ_SEQSUB_CONTACT", "13", "OBJ_BIOSEQ_MAPFEAT",
7465 "OBJ_BIOSEQ_SEG", "OBJ_SEQHIST", "OBJ_SEQHIST_ALIGN", "OBJ_BIOSEQ_DELTA", "19",
7466 "OBJ_PUB", "OBJ_SEQFEAT_CIT", "OBJ_SEQSUB_CIT", "OBJ_MEDLINE_ENTRY", "OBJ_PUB_SET",
7467 "OBJ_SEQLOC", "OBJ_SEQID", "OBJ_SEQCODE", "OBJ_SEQCODE_SET", "OBJ_GENETIC_CODE",
7468 "OBJ_GENETIC_CODE_SET", "OBJ_TEXT_REPORT", "OBJ_FASTA", "OBJ_VIBRANT_PICTURE", "OBJ_PROJECT"
7469 };
7470
7471 static CharPtr temploadstrs [] = {
7472 "TL_NOT_TEMP", "TL_LOADED", "TL_CACHED"
7473 };
7474
7475 static CharPtr proctypestrs [] = {
7476 "0", "OMPROC_OPEN", "OMPROC_DELETE", "OMPROC_VIEW", "OMPROC_EDIT",
7477 "OMPROC_SAVE", "OMPROC_CUT", "OMPROC_COPY", "OMPROC_PASTE", "OMPROC_ANALYZE",
7478 "OMPROC_FIND", "OMPROC_REPLACE", "OMPROC_FILTER", "OMPROC_FETCH",
7479 };
7480
PrintABool(FILE * fp,CharPtr str,Boolean val)7481 static void PrintABool (FILE *fp, CharPtr str, Boolean val)
7482
7483 {
7484 if (val) {
7485 fprintf (fp, "%s TRUE\n", str);
7486 } else {
7487 fprintf (fp, "%s FALSE\n", str);
7488 }
7489 }
7490
7491 Int2 LIBCALLBACK VSMPictMsgFunc PROTO((OMMsgStructPtr ommsp));
7492
ReportOnEntity(ObjMgrDataPtr omdp,ObjMgrPtr omp,Boolean selected,Uint4 itemID,Uint2 itemtype,Int2 index,FILE * fp)7493 static void ReportOnEntity (ObjMgrDataPtr omdp, ObjMgrPtr omp, Boolean selected, Uint4 itemID,
7494 Uint2 itemtype, Int2 index, FILE *fp)
7495
7496 {
7497 BioseqPtr bsp;
7498 BioseqSetPtr bssp;
7499 Char buf [50];
7500 OMUserDataPtr omudp;
7501 VSMPictPtr vsmpp;
7502
7503 if (omdp == NULL || fp == NULL) return;
7504 if (selected) {
7505 fprintf (fp, "Data Element\n\n");
7506 fprintf (fp, " EntityID %d selected\n", (int) omdp->EntityID);
7507 fprintf (fp, " ItemID %d, Itemtype %d\n", (int) itemID, (int) itemtype);
7508 } else if (omdp->parentptr == NULL) {
7509 fprintf (fp, "Top Data Element %d\n\n", (int) index);
7510 fprintf (fp, " EntityID %d\n", (int) omdp->EntityID);
7511 } else {
7512 fprintf (fp, "Inner Data Element %d\n\n", (int) index);
7513 fprintf (fp, " EntityID %d\n", (int) omdp->EntityID);
7514 }
7515 if (omdp->datatype < OBJ_MAX) {
7516 fprintf (fp, " Datatype %s", objmgrtypestrs [omdp->datatype]);
7517 if (omdp->datatype == OBJ_BIOSEQ) {
7518 bsp = (BioseqPtr) omdp->dataptr;
7519 if (bsp != NULL) {
7520 SeqIdWrite (bsp->id, buf, PRINTID_FASTA_LONG, sizeof (buf) - 1);
7521 fprintf (fp, " %s, length %ld", buf, (long) bsp->length);
7522 }
7523 } else if (omdp->datatype == OBJ_BIOSEQSET) {
7524 bssp = (BioseqSetPtr) omdp->dataptr;
7525 if (bssp != NULL) {
7526 fprintf (fp, " class %d", (int) bssp->_class);
7527 }
7528 }
7529 fprintf (fp, "\n");
7530 } else {
7531 fprintf (fp, " Unregistered datatype %d\n", (int) omdp->datatype);
7532 }
7533 fprintf (fp, " Lockcnt %d\n", (int) omdp->lockcnt);
7534 if (omdp->tempload < 3) {
7535 fprintf (fp, " Tempload %s\n", temploadstrs [omdp->tempload]);
7536 } else {
7537 fprintf (fp, " Unrecognized tempload %d\n", (int) omdp->tempload);
7538 }
7539 PrintABool (fp, " Clipboard", omdp->clipboard);
7540 PrintABool (fp, " Dirty", omdp->dirty);
7541 PrintABool (fp, " Being_freed", omdp->being_freed);
7542 PrintABool (fp, " Free", omdp->free);
7543 fprintf (fp, "\n");
7544 for (omudp = omdp->userdata; omudp != NULL; omudp = omudp->next) {
7545 if (omudp->proctype <= OMPROC_MAX) {
7546 fprintf (fp, " Proctype %s\n", proctypestrs [omudp->proctype]);
7547 } else {
7548 fprintf (fp, " Unrecognized proctype %d\n", (int) omudp->proctype);
7549 }
7550 fprintf (fp, " Procid %d\n", (int) omudp->procid);
7551 fprintf (fp, " Userkey %d\n", (int) omudp->userkey);
7552 if (omudp->messagefunc == VSMPictMsgFunc) {
7553 vsmpp = (VSMPictPtr) omudp->userdata.ptrvalue;
7554 if (vsmpp != NULL) {
7555 if (vsmpp->s != NULL) {
7556 fprintf (fp, " VSMPictPtr segment not NULL\n");
7557 } else {
7558 fprintf (fp, " VSMPictPtr segment is NULL\n");
7559 }
7560 }
7561 }
7562 fprintf (fp, "\n");
7563 }
7564 }
7565
DesktopReportFunc(Pointer data)7566 static Int2 LIBCALLBACK DesktopReportFunc (Pointer data)
7567
7568 {
7569 FILE *fp;
7570 Uint4 j;
7571 Uint4 num;
7572 ObjMgrPtr omp;
7573 ObjMgrDataPtr omdp;
7574 ObjMgrDataPtr PNTR omdpp;
7575 Char path [PATH_MAX];
7576 SelStructPtr sel;
7577
7578 omp = ObjMgrGet ();
7579 if (omp == NULL) return OM_MSG_RET_DONE;
7580 TmpNam (path);
7581 fp = FileOpen (path, "w");
7582 fprintf (fp, "Object Manager\n\n");
7583 fprintf (fp, " HighestEntityID %d\n", (int) omp->HighestEntityID);
7584 fprintf (fp, " Totobj %d\n", (int) omp->totobj);
7585 fprintf (fp, " Currobj %d\n", (int) omp->currobj);
7586 fprintf (fp, " Maxtemp %d\n", (int) omp->maxtemp);
7587 fprintf (fp, " Tempcnt %d\n", (int) omp->tempcnt);
7588 fprintf (fp, " Hold %d\n", (int) omp->hold);
7589 PrintABool (fp, " Reaping", omp->reaping);
7590 PrintABool (fp, " Is_write_locked", omp->is_write_locked);
7591 fprintf (fp, "\n");
7592 sel = ObjMgrGetSelected ();
7593 if (sel != NULL) {
7594 omdp = ObjMgrGetData (sel->entityID);
7595 ReportOnEntity (omdp, omp, TRUE, sel->itemID, sel->itemtype, 0, fp);
7596 } else {
7597 num = omp->currobj;
7598 for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL; j++, omdpp++) {
7599 omdp = *omdpp;
7600 if (omdp->parentptr == NULL) {
7601 ReportOnEntity (omdp, omp, FALSE, 0, 0, j + 1, fp);
7602 }
7603 }
7604 for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL; j++, omdpp++) {
7605 omdp = *omdpp;
7606 if (omdp->parentptr != NULL) {
7607 ReportOnEntity (omdp, omp, FALSE, 0, 0, j + 1, fp);
7608 }
7609 }
7610 }
7611 FileClose (fp);
7612 LaunchGeneralTextViewer (path, "Object Manager Report");
7613 FileRemove (path);
7614 return OM_MSG_RET_DONE;
7615 }
7616
7617
MRnaFromCdsCallback(SeqFeatPtr sfp,Pointer userdata)7618 static void MRnaFromCdsCallback (SeqFeatPtr sfp, Pointer userdata)
7619 {
7620 Boolean process_this_one = FALSE;
7621 Boolean any_feat_selected = FALSE;
7622 SelStructPtr sel;
7623 Uint2Ptr entityIDptr;
7624 Uint2 entityID;
7625 SeqFeatPtr mrna;
7626 SeqMgrFeatContext context;
7627 ValNode field;
7628 FeatureFieldPtr ff;
7629 CharPtr feat_product, mrna_product;
7630
7631 if (sfp == NULL || sfp->idx.subtype != FEATDEF_CDS || userdata == NULL) return;
7632 if (IsMrnaSequence(BioseqFindFromSeqLoc(sfp->location))) {
7633 return;
7634 }
7635 entityIDptr = (Uint2Ptr) userdata;
7636 entityID = *entityIDptr;
7637
7638 sel = ObjMgrGetSelected ();
7639 if (sel == NULL)
7640 {
7641 process_this_one = TRUE;
7642 }
7643 else
7644 {
7645 while (sel != NULL && sel->itemID != sfp->idx.itemID)
7646 {
7647 if (sel->itemtype == OBJ_SEQFEAT) {
7648 any_feat_selected = TRUE;
7649 }
7650 sel = sel->next;
7651 }
7652 if (sel != NULL || !any_feat_selected)
7653 {
7654 process_this_one = TRUE;
7655 }
7656 }
7657 if (process_this_one)
7658 {
7659 mrna = SeqMgrGetLocationSupersetmRNA (sfp->location, &context);
7660 if (mrna == NULL) {
7661 mrna = SeqMgrGetOverlappingmRNA (sfp->location, &context);
7662 }
7663
7664 if (mrna != NULL) {
7665 ff = FeatureFieldNew ();
7666 ff->type = Macro_feature_type_any;
7667 ValNodeAddInt (&(ff->field), FeatQualChoice_legal_qual, Feat_qual_legal_product);
7668 field.choice = FieldType_feature_field;
7669 field.data.ptrvalue = ff;
7670 field.next = NULL;
7671 feat_product = GetFieldValueForObject (OBJ_SEQFEAT, sfp, &field, NULL);
7672 mrna_product = GetFieldValueForObject (OBJ_SEQFEAT, mrna, &field, NULL);
7673 if (StringCmp (feat_product, mrna_product) == 0 || ProductsMatchForRefSeq(feat_product, mrna_product)) {
7674 process_this_one = FALSE;
7675 }
7676 feat_product = MemFree (feat_product);
7677 mrna_product = MemFree (mrna_product);
7678 ff = FeatureFieldFree (ff);
7679 }
7680 }
7681
7682 if (process_this_one)
7683 {
7684 AddmRNAForCDS (sfp);
7685 }
7686 }
7687
MRnaFromCdsProc(Uint2 entityID)7688 extern void MRnaFromCdsProc (Uint2 entityID)
7689
7690 {
7691 SeqEntryPtr sep;
7692
7693 if (entityID == 0) return;
7694
7695 sep = GetTopSeqEntryForEntityID (entityID);
7696 VisitFeaturesInSep (sep, (Pointer) &entityID, MRnaFromCdsCallback);
7697 ObjMgrSetDirtyFlag (entityID, TRUE);
7698 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
7699 }
7700
7701
AddBspToVnpCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)7702 static void AddBspToVnpCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
7703
7704 {
7705 BioseqPtr bsp;
7706 ValNodePtr PNTR vnpp;
7707
7708 vnpp = (ValNodePtr PNTR) mydata;
7709 if (IS_Bioseq (sep)) {
7710 bsp = (BioseqPtr) sep->data.ptrvalue;
7711 if (bsp != NULL && ISA_na (bsp->mol)) {
7712 ValNodeAddPointer (vnpp, 0, (Pointer) bsp);
7713 }
7714 }
7715 }
7716
AddBspToVnp(GatherContextPtr gcp)7717 static Boolean AddBspToVnp (GatherContextPtr gcp)
7718
7719 {
7720 BioseqPtr bsp;
7721 BioseqSetPtr bssp;
7722 SeqEntryPtr sep;
7723 ValNodePtr PNTR vnpp;
7724
7725 vnpp = (ValNodePtr PNTR) gcp->userdata;
7726 if (vnpp == NULL) return TRUE;
7727 bsp = NULL;
7728 if (gcp->thistype == OBJ_BIOSEQ) {
7729 bsp = (BioseqPtr) gcp->thisitem;
7730 } else if (gcp->thistype == OBJ_BIOSEQSET) {
7731 bssp = (BioseqSetPtr) gcp->thisitem;
7732 if (bssp != NULL) {
7733 sep = SeqMgrGetSeqEntryForData (bssp);
7734 if (sep != NULL) {
7735 SeqEntryExplore (sep, (Pointer) vnpp, AddBspToVnpCallback);
7736 }
7737 }
7738 return TRUE;
7739 } else return TRUE;
7740 if (bsp == NULL) return TRUE;
7741 ValNodeAddPointer (vnpp, 0, (Pointer) bsp);
7742 return TRUE;
7743 }
7744
7745
RevCompBioseqListInteractive(ValNodePtr bsp_list,Uint2 entityID,BioseqFunc func,Boolean revCompFeats,Boolean check_for_aln)7746 static void RevCompBioseqListInteractive (ValNodePtr bsp_list, Uint2 entityID, BioseqFunc func,
7747 Boolean revCompFeats, Boolean check_for_aln)
7748 {
7749 ValNodePtr aln_bsp = NULL, vnp;
7750 ValNodeBlock msg_block;
7751 BioseqPtr bsp;
7752 Char id_str[255];
7753 CharPtr msg;
7754 MsgAnswer ans;
7755
7756 if (bsp_list == NULL) return;
7757
7758 if (func != NULL && check_for_aln) {
7759 aln_bsp = ListSequencesWithAlignments (bsp_list);
7760 if (aln_bsp != NULL) {
7761 InitValNodeBlock (&msg_block, NULL);
7762 for (vnp = aln_bsp; vnp != NULL; vnp = vnp->next) {
7763 bsp = (BioseqPtr) vnp->data.ptrvalue;
7764 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, sizeof (id_str) - 1);
7765 ValNodeAddPointerToEnd (&msg_block, 0, StringSave (id_str));
7766 }
7767 msg = CreateListMessage ("Sequence",
7768 msg_block.head->next == NULL
7769 ? " is in an alignment, which will become invalid. Do you want to remove the alignment?"
7770 : " are in alignments, which will become invalid unless all of the sequences in these alignments are reversed. Do you want to remove the alignments?",
7771 msg_block.head);
7772 msg_block.head = ValNodeFreeData (msg_block.head);
7773 ans = Message (MSG_YNC, msg);
7774 msg = MemFree (msg);
7775 if (ans == ANS_YES) {
7776 /* remove the alignments */
7777 for (vnp = aln_bsp; vnp != NULL; vnp = vnp->next) {
7778 bsp = vnp->data.ptrvalue;
7779 RemoveAlignmentsWithSequence (bsp, bsp->idx.entityID);
7780 }
7781 DeleteMarkedObjects (entityID, 0, NULL);
7782 } else if (ans == ANS_CANCEL) {
7783 aln_bsp = ValNodeFree (aln_bsp);
7784 return;
7785 }
7786 }
7787 }
7788
7789 RevCompBioseqList (bsp_list, entityID, func, revCompFeats, check_for_aln);
7790
7791 /* now also reverse quality scores - SQD-1271 */
7792 for (vnp = bsp_list; vnp != NULL; vnp = vnp->next) {
7793 ReverseQualityScores ((BioseqPtr) vnp->data.ptrvalue);
7794 }
7795
7796 /* flip alignments if all sequences in alignment were flipped */
7797 if (aln_bsp != NULL) {
7798 VisitAnnotsInSep (GetTopSeqEntryForEntityID (entityID), aln_bsp, FlipEntireAlignmentIfAllSequencesFlipped);
7799 aln_bsp = ValNodeFree (aln_bsp);
7800 }
7801
7802 ObjMgrSetDirtyFlag (entityID, TRUE);
7803 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
7804 }
7805
7806
ProcessMultipleBioseqFunctions(OMProcControlPtr ompcp,BioseqFunc func,Boolean revCompFeats,Boolean check_for_aln)7807 static void ProcessMultipleBioseqFunctions (OMProcControlPtr ompcp, BioseqFunc func,
7808 Boolean revCompFeats, Boolean check_for_aln)
7809
7810 {
7811 ValNodePtr head;
7812 SelStructPtr sel;
7813
7814 if (ompcp == NULL || ompcp->input_entityID == 0 || func == NULL) return;
7815 head = NULL;
7816 for (sel = ObjMgrGetSelected (); sel != NULL; sel = sel->next) {
7817 GatherItem (sel->entityID, sel->itemID, sel->itemtype,
7818 (Pointer) &head, AddBspToVnp);
7819 }
7820 if (head == NULL) return;
7821
7822 RevCompBioseqListInteractive (head, ompcp->input_entityID, func, revCompFeats, check_for_aln);
7823 head = ValNodeFree (head);
7824 }
7825
7826
7827 typedef struct revcompbyidfrm {
7828 FORM_MESSAGE_BLOCK
7829 DialoG constraint;
7830 ButtoN revcomp_seq;
7831 ButtoN reverse_feats;
7832 ButtoN accept;
7833 } RevCompByIdFrmData, PNTR RevCompByIdFrmPtr;
7834
7835
ChangeRevComp(ButtoN b)7836 static void ChangeRevComp (ButtoN b)
7837 {
7838 RevCompByIdFrmPtr f;
7839
7840 f = (RevCompByIdFrmPtr) GetObjectExtra (b);
7841 if (f == NULL) return;
7842
7843 if (!GetStatus (f->revcomp_seq) && !GetStatus (f->reverse_feats))
7844 {
7845 Disable (f->accept);
7846 }
7847 else
7848 {
7849 Enable (f->accept);
7850 }
7851 }
7852
7853
DoRevComp(ButtoN b)7854 static void DoRevComp (ButtoN b)
7855 {
7856 RevCompByIdFrmPtr f;
7857 ConstraintChoiceSetPtr constraint;
7858 ValNodePtr bsp_list;
7859 SeqEntryPtr sep;
7860
7861 f = (RevCompByIdFrmPtr) GetObjectExtra (b);
7862 if (f == NULL) return;
7863
7864 sep = GetTopSeqEntryForEntityID (f->input_entityID);
7865 constraint = DialogToPointer (f->constraint);
7866 bsp_list = GetSequenceListForConstraint (sep, constraint);
7867 constraint = ConstraintChoiceSetFree (constraint);
7868
7869 if (bsp_list == NULL)
7870 {
7871 Message (MSG_ERROR, "No sequences match constraint!");
7872 }
7873 else
7874 {
7875 RevCompBioseqListInteractive (bsp_list, f->input_entityID,
7876 GetStatus (f->revcomp_seq) ? BioseqRevComp : NULL,
7877 GetStatus (f->reverse_feats), GetStatus (f->revcomp_seq));
7878 Remove (f->form);
7879 }
7880 bsp_list = ValNodeFree (bsp_list);
7881 }
7882
BioseqRevCompByIDForEntityID(Uint2 entityID)7883 static Int2 LIBCALLBACK BioseqRevCompByIDForEntityID (Uint2 entityID)
7884
7885 {
7886 GrouP c;
7887 GrouP h;
7888 RevCompByIdFrmPtr f;
7889 WindoW w;
7890
7891 f = (RevCompByIdFrmPtr) MemNew (sizeof (RevCompByIdFrmData));
7892 if (f == NULL) return OM_MSG_RET_ERROR;
7893 w = FixedWindow (-50, -33, -10, -10, "Reverse Complement", StdCloseWindowProc);
7894 SetObjectExtra (w, f, StdCleanupFormProc);
7895 f->form = (ForM) w;
7896 f->formmessage = NULL;
7897
7898 f->input_entityID = entityID;
7899
7900 h = HiddenGroup (w, -1, 0, NULL);
7901 f->revcomp_seq = CheckBox (h, "Reverse complement sequence", ChangeRevComp);
7902 SetStatus (f->revcomp_seq, TRUE);
7903 f->reverse_feats = CheckBox (h, "Reverse features", ChangeRevComp);
7904 SetStatus (f->reverse_feats, TRUE);
7905
7906 f->constraint = ComplexConstraintDialog (h, NULL, NULL);
7907 ChangeComplexConstraintFieldType (f->constraint, FieldType_molinfo_field, NULL, Macro_feature_type_any);
7908
7909 c = HiddenGroup (h, 2, 0, NULL);
7910 f->accept = DefaultButton (c, "Accept", DoRevComp);
7911 SetObjectExtra (f->accept, f, NULL);
7912 PushButton (c, "Cancel", StdCancelButtonProc);
7913 AlignObjects (ALIGN_CENTER, (HANDLE) f->constraint,
7914 (HANDLE) f->revcomp_seq,
7915 (HANDLE) f->reverse_feats,
7916 (HANDLE) c, NULL);
7917 RealizeWindow (w);
7918 Show (w);
7919 Update ();
7920 return OM_MSG_RET_DONE;
7921 }
7922
7923
BioseqRevCompByID(Pointer data)7924 static Int2 LIBCALLBACK BioseqRevCompByID (Pointer data)
7925
7926 {
7927 OMProcControlPtr ompcp;
7928
7929 ompcp = (OMProcControlPtr) data;
7930 if (ompcp == NULL) return OM_MSG_RET_ERROR;
7931
7932 return BioseqRevCompByIDForEntityID (ompcp->input_entityID);
7933 }
7934
7935
BioseqRevCompByIDMenuItem(IteM i)7936 extern void BioseqRevCompByIDMenuItem (IteM i)
7937 {
7938 BaseFormPtr bfp;
7939
7940 #ifdef WIN_MAC
7941 bfp = currentFormDataPtr;
7942 #else
7943 bfp = GetObjectExtra (i);
7944 #endif
7945 if (bfp == NULL) return;
7946
7947 BioseqRevCompByIDForEntityID (bfp->input_entityID);
7948 }
7949
7950
DoRevQualScores(ButtoN b)7951 static void DoRevQualScores (ButtoN b)
7952 {
7953 RevCompByIdFrmPtr f;
7954 ConstraintChoiceSetPtr scp;
7955 ValNodePtr bsp_list, vnp;
7956 SeqEntryPtr sep;
7957
7958 f = (RevCompByIdFrmPtr) GetObjectExtra (b);
7959 if (f == NULL) return;
7960
7961 sep = GetTopSeqEntryForEntityID (f->input_entityID);
7962 scp = DialogToPointer (f->constraint);
7963 bsp_list = GetSequenceListForConstraint (sep, scp);
7964 scp = ConstraintChoiceSetFree (scp);
7965
7966 if (bsp_list == NULL)
7967 {
7968 Message (MSG_ERROR, "No sequences match constraint!");
7969 }
7970 else
7971 {
7972 for (vnp = bsp_list; vnp != NULL; vnp = vnp->next)
7973 {
7974 ReverseQualityScores ((BioseqPtr) vnp->data.ptrvalue);
7975 }
7976 ObjMgrSetDirtyFlag (f->input_entityID, TRUE);
7977 ObjMgrSendMsg (OM_MSG_UPDATE, f->input_entityID, 0, 0);
7978 Remove (f->form);
7979 Update();
7980 }
7981 bsp_list = ValNodeFree (bsp_list);
7982 }
7983
BioseqRevQualScoresForEntityID(Uint2 entityID)7984 static Int2 LIBCALLBACK BioseqRevQualScoresForEntityID (Uint2 entityID)
7985
7986 {
7987 GrouP c;
7988 GrouP h;
7989 RevCompByIdFrmPtr f;
7990 WindoW w;
7991
7992 f = (RevCompByIdFrmPtr) MemNew (sizeof (RevCompByIdFrmData));
7993 if (f == NULL) return OM_MSG_RET_ERROR;
7994 w = FixedWindow (-50, -33, -10, -10, "Reverse Quality Scores", StdCloseWindowProc);
7995 SetObjectExtra (w, f, StdCleanupFormProc);
7996 f->form = (ForM) w;
7997 f->formmessage = NULL;
7998
7999 f->input_entityID = entityID;
8000
8001 h = HiddenGroup (w, -1, 0, NULL);
8002
8003 f->constraint = ComplexConstraintDialog (h, NULL, NULL);
8004 ChangeComplexConstraintFieldType (f->constraint, FieldType_molinfo_field, NULL, Macro_feature_type_any);
8005
8006 c = HiddenGroup (h, 2, 0, NULL);
8007 f->accept = DefaultButton (c, "Accept", DoRevQualScores);
8008 SetObjectExtra (f->accept, f, NULL);
8009 PushButton (c, "Cancel", StdCancelButtonProc);
8010 AlignObjects (ALIGN_CENTER, (HANDLE) f->constraint,
8011 (HANDLE) c, NULL);
8012 RealizeWindow (w);
8013 Show (w);
8014 Update ();
8015 return OM_MSG_RET_DONE;
8016 }
8017
8018
BioseqRevQualScoresMenuItem(IteM i)8019 extern void BioseqRevQualScoresMenuItem (IteM i)
8020 {
8021 BaseFormPtr bfp;
8022
8023 #ifdef WIN_MAC
8024 bfp = currentFormDataPtr;
8025 #else
8026 bfp = GetObjectExtra (i);
8027 #endif
8028 if (bfp == NULL) return;
8029
8030 BioseqRevQualScoresForEntityID (bfp->input_entityID);
8031 }
8032
8033
ReverseComplementBioseqAndFeats(BioseqPtr bsp,Uint2 entityID)8034 extern void ReverseComplementBioseqAndFeats (BioseqPtr bsp, Uint2 entityID)
8035 {
8036 SeqEntryPtr sep;
8037
8038 if (bsp == NULL) return;
8039 sep = GetTopSeqEntryForEntityID (entityID);
8040 if (sep != NULL) {
8041 BioseqRevComp (bsp);
8042 SeqEntryExplore (sep, (Pointer) bsp, RevCompFeats);
8043 }
8044 }
8045
RevCompFuncFeat(Pointer data)8046 static Int2 LIBCALLBACK RevCompFuncFeat (Pointer data)
8047
8048 {
8049 ProcessMultipleBioseqFunctions ((OMProcControlPtr) data, BioseqRevComp, TRUE, TRUE);
8050 return OM_MSG_RET_DONE;
8051 }
8052
RevCompFunc(Pointer data)8053 static Int2 LIBCALLBACK RevCompFunc (Pointer data)
8054
8055 {
8056 ProcessMultipleBioseqFunctions ((OMProcControlPtr) data, BioseqRevComp, FALSE, TRUE);
8057 return OM_MSG_RET_DONE;
8058 }
8059
RevFunc(Pointer data)8060 static Int2 LIBCALLBACK RevFunc (Pointer data)
8061
8062 {
8063 ProcessMultipleBioseqFunctions ((OMProcControlPtr) data, BioseqReverse, FALSE, TRUE);
8064 return OM_MSG_RET_DONE;
8065 }
8066
CompFunc(Pointer data)8067 static Int2 LIBCALLBACK CompFunc (Pointer data)
8068
8069 {
8070 ProcessMultipleBioseqFunctions ((OMProcControlPtr) data, BioseqComplement, FALSE, FALSE);
8071 return OM_MSG_RET_DONE;
8072 }
8073
8074 typedef struct orphandata {
8075 ValNodePtr bspfromcds;
8076 ValNodePtr bspinentry;
8077 } OrphanData, PNTR OrphanDataPtr;
8078
GetCdsProducts(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)8079 static void GetCdsProducts (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
8080
8081 {
8082 BioseqPtr bsp;
8083 BioseqSetPtr bssp;
8084 OrphanDataPtr odp;
8085 SeqAnnotPtr sap;
8086 SeqFeatPtr sfp;
8087 SeqIdPtr sip;
8088
8089 if (mydata == NULL) return;
8090 if (sep == NULL || sep->data.ptrvalue == NULL) return;
8091 odp = (OrphanDataPtr) mydata;
8092 if (IS_Bioseq (sep)) {
8093 bsp = (BioseqPtr) sep->data.ptrvalue;
8094 sap = bsp->annot;
8095 if (ISA_aa (bsp->mol)) {
8096 ValNodeAddPointer (&(odp->bspinentry), 0, (Pointer) bsp);
8097 }
8098 } else if (IS_Bioseq_set (sep)) {
8099 bssp = (BioseqSetPtr) sep->data.ptrvalue;
8100 sap = bssp->annot;
8101 } else return;
8102 while (sap != NULL) {
8103 if (sap->type == 1) {
8104 sfp = (SeqFeatPtr) sap->data;
8105 while (sfp != NULL) {
8106 if (sfp->data.choice == SEQFEAT_CDREGION) {
8107 if (sfp->product != NULL) {
8108 sip = SeqLocId (sfp->product);
8109 if (sip != NULL) {
8110 bsp = BioseqFind (sip);
8111 if (bsp != NULL) {
8112 ValNodeAddPointer (&(odp->bspfromcds), 0, (Pointer) bsp);
8113 }
8114 }
8115 }
8116 }
8117 sfp = sfp->next;
8118 }
8119 }
8120 sap = sap->next;
8121 }
8122 }
8123
SortByVnpDataPtrvalue(VoidPtr ptr1,VoidPtr ptr2)8124 static int LIBCALLBACK SortByVnpDataPtrvalue (VoidPtr ptr1, VoidPtr ptr2)
8125
8126 {
8127 ValNodePtr vnp1;
8128 ValNodePtr vnp2;
8129
8130 if (ptr1 != NULL && ptr2 != NULL) {
8131 vnp1 = *((ValNodePtr PNTR) ptr1);
8132 vnp2 = *((ValNodePtr PNTR) ptr2);
8133 if (vnp1 != NULL && vnp2 != NULL) {
8134 if (vnp1->data.ptrvalue > vnp2->data.ptrvalue) {
8135 return 1;
8136 } else if (vnp1->data.ptrvalue < vnp2->data.ptrvalue) {
8137 return -1;
8138 } else {
8139 return 0;
8140 }
8141 } else {
8142 return 0;
8143 }
8144 } else {
8145 return 0;
8146 }
8147 }
8148
RemoveOrphanProteins(Uint2 entityID,SeqEntryPtr sep)8149 extern void RemoveOrphanProteins (Uint2 entityID, SeqEntryPtr sep)
8150
8151 {
8152 Int2 doit;
8153 OrphanData od;
8154 ValNodePtr vnp;
8155 ValNodePtr vnp1;
8156 ValNodePtr vnp2;
8157 BioseqPtr protein_bsp;
8158
8159 if (sep == NULL || entityID == 0) return;
8160 od.bspfromcds = NULL;
8161 od.bspinentry = NULL;
8162 /* This function collects a list of all proteins in the entry
8163 * and a list of all proteins that are products of a CDS
8164 */
8165 SeqEntryExplore (sep, (Pointer) &od, GetCdsProducts);
8166
8167 /* If there are no proteins in the entry at all, we're done */
8168 if (od.bspinentry == NULL)
8169 {
8170 ValNodeFree (od.bspinentry);
8171 return;
8172 }
8173
8174 /* If we found any CDS product proteins, we need to sort the two
8175 * lists and mark the ones in both lists as "keep".
8176 * If there are no CDS product proteins, then all of the proteins
8177 * in the entry should be removed.
8178 */
8179 if (od.bspfromcds != NULL) {
8180 od.bspinentry = SortValNode (od.bspinentry, SortByVnpDataPtrvalue);
8181 od.bspfromcds = SortValNode (od.bspfromcds, SortByVnpDataPtrvalue);
8182 vnp1 = od.bspfromcds;
8183 vnp2 = od.bspinentry;
8184 while (vnp1 != NULL && vnp2 != NULL) {
8185 if (vnp1->data.ptrvalue < vnp2->data.ptrvalue) {
8186 vnp1 = vnp1->next;
8187 } else if (vnp2->data.ptrvalue < vnp1->data.ptrvalue) {
8188 vnp2 = vnp2->next;
8189 } else {
8190 vnp2->data.ptrvalue = NULL;
8191 vnp1 = vnp1->next;
8192 vnp2 = vnp2->next;
8193 }
8194 }
8195 }
8196
8197 /* Now we count how many proteins are in the entry but not a
8198 * product of a CDS
8199 */
8200 doit = 0;
8201 for (vnp = od.bspinentry; vnp != NULL; vnp = vnp->next) {
8202 if (vnp->data.ptrvalue != NULL) {
8203 doit++;
8204 }
8205 }
8206 if (doit > 0) {
8207 if (Message (MSG_YN, "Do you want to remove %d orphaned proteins?", (int) doit) == ANS_YES) {
8208 vnp = od.bspinentry;
8209 while (vnp != NULL) {
8210 if (vnp->data.ptrvalue != NULL) {
8211 protein_bsp = vnp->data.ptrvalue;
8212 protein_bsp->idx.deleteme = TRUE;
8213 }
8214 vnp = vnp->next;
8215 }
8216 DeleteMarkedObjects (entityID, 0, NULL);
8217 ObjMgrSetDirtyFlag (entityID, TRUE);
8218 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
8219 }
8220 }
8221
8222 ValNodeFree (od.bspinentry);
8223 ValNodeFree (od.bspfromcds);
8224 }
8225
NormalizeNucProts(Pointer data)8226 static Int2 LIBCALLBACK NormalizeNucProts (Pointer data)
8227
8228 {
8229 OMProcControlPtr ompcp;
8230 SeqEntryPtr sep;
8231
8232 ompcp = (OMProcControlPtr) data;
8233 if (ompcp == NULL) return OM_MSG_RET_ERROR;
8234 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
8235 RemoveOrphanProteins (ompcp->input_entityID, sep);
8236 RenormalizeNucProtSets (sep, TRUE);
8237 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
8238 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
8239 return OM_MSG_RET_DONE;
8240 }
8241
RemovePopPhyMutSet(SeqEntryPtr sep,Boolean forceGBClass,Boolean forceAll)8242 static void RemovePopPhyMutSet (SeqEntryPtr sep, Boolean forceGBClass, Boolean forceAll)
8243
8244 {
8245 SeqAnnotPtr annot;
8246 BioseqPtr bsp;
8247 BioseqSetPtr bssp;
8248 ValNodePtr descr;
8249 SeqAnnotPtr sap;
8250 SeqEntryPtr seqentry;
8251
8252 if (sep == NULL || IS_Bioseq (sep)) return;
8253 bssp = (BioseqSetPtr) sep->data.ptrvalue;
8254 if (bssp == NULL) return;
8255 if (forceAll) {
8256 } else if (forceGBClass) {
8257 if ((bssp->_class < 13 || bssp->_class > 15) && bssp->_class != 7) return;
8258 } else {
8259 if (bssp->_class < 13 || bssp->_class > 15) return;
8260 }
8261 seqentry = bssp->seq_set;
8262 if (seqentry == NULL) return;
8263 if (! forceAll) {
8264 if (! forceGBClass) {
8265 if (seqentry->next != NULL) return;
8266 }
8267 }
8268 descr = bssp->descr;
8269 bssp->descr = NULL;
8270 annot = bssp->annot;
8271 bssp->annot = NULL;
8272 sep->choice = seqentry->choice;
8273 sep->data.ptrvalue = seqentry->data.ptrvalue;
8274 sep->next = seqentry->next;
8275 seqentry->data.ptrvalue = NULL;
8276 seqentry->next = NULL;
8277 bssp->seq_set = NULL;
8278 SeqEntryFree (seqentry);
8279 BioseqSetFree (bssp);
8280 sap = NULL;
8281 if (IS_Bioseq (sep)) {
8282 bsp = (BioseqPtr) sep->data.ptrvalue;
8283 ValNodeLink (&(bsp->descr), descr);
8284 if (bsp->annot == NULL) {
8285 bsp->annot = annot;
8286 annot = NULL;
8287 } else {
8288 sap = bsp->annot;
8289 }
8290 } else if (IS_Bioseq_set (sep)) {
8291 bssp = (BioseqSetPtr) sep->data.ptrvalue;
8292 ValNodeLink (&(bssp->descr), descr);
8293 if (bssp->annot == NULL) {
8294 bssp->annot = annot;
8295 annot = NULL;
8296 } else {
8297 sap = bssp->annot;
8298 }
8299 }
8300 if (sap != NULL) {
8301 while (sap->next != NULL) {
8302 sap = sap->next;
8303 }
8304 sap->next = annot;
8305 }
8306 }
8307
InsetNewSet(BioseqSetPtr bssp,Uint1 _class)8308 NLM_EXTERN BioseqSetPtr InsetNewSet (BioseqSetPtr bssp, Uint1 _class)
8309
8310 {
8311 BioseqSetPtr popphymut;
8312 SeqEntryPtr tmp;
8313
8314 if (bssp == NULL) return NULL;
8315 popphymut = BioseqSetNew ();
8316 if (popphymut == NULL) return NULL;
8317 popphymut->_class = _class;
8318 popphymut->seq_set = bssp->seq_set;
8319 tmp = SeqEntryNew ();
8320 if (tmp == NULL) return NULL;
8321 tmp->choice = 2;
8322 tmp->data.ptrvalue = (Pointer) popphymut;
8323 bssp->seq_set = tmp;
8324 return popphymut;
8325 }
8326
SetWithinGenBankSet(Pointer data,Uint1 _class)8327 static Int2 LIBCALLBACK SetWithinGenBankSet (Pointer data, Uint1 _class)
8328
8329 {
8330 BioseqSetPtr bssp;
8331 BioseqSetPtr newbssp;
8332 ObjMgrDataPtr omdptop;
8333 ObjMgrData omdata;
8334 OMProcControlPtr ompcp;
8335 Uint2 parenttype;
8336 Pointer parentptr;
8337 SeqEntryPtr sep;
8338
8339 ompcp = (OMProcControlPtr) data;
8340 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
8341 switch (ompcp->input_itemtype) {
8342 case OBJ_BIOSEQ :
8343 break;
8344 case OBJ_BIOSEQSET :
8345 break;
8346 case 0 :
8347 return OM_MSG_RET_ERROR;
8348 default :
8349 break;
8350 }
8351 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
8352 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
8353 if (sep == NULL) return OM_MSG_RET_ERROR;
8354 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
8355 GetSeqEntryParent (sep, &parentptr, &parenttype);
8356 RemoveDupGenBankSets (sep);
8357 if (IS_Bioseq_set (sep)) {
8358 bssp = (BioseqSetPtr) sep->data.ptrvalue;
8359 if (bssp != NULL) {
8360 newbssp = InsetNewSet (bssp, _class);
8361 if (newbssp != NULL) {
8362 newbssp->descr = bssp->descr;
8363 bssp->descr = NULL;
8364 newbssp->annot = bssp->annot;
8365 bssp->annot = NULL;
8366 }
8367 }
8368 }
8369 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
8370 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
8371 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
8372 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
8373 return OM_MSG_RET_DONE;
8374 }
8375
PopWithinGenBankSet(Pointer data)8376 static Int2 LIBCALLBACK PopWithinGenBankSet (Pointer data)
8377
8378 {
8379 return SetWithinGenBankSet (data, BioseqseqSet_class_pop_set);
8380 }
8381
PhyWithinGenBankSet(Pointer data)8382 static Int2 LIBCALLBACK PhyWithinGenBankSet (Pointer data)
8383
8384 {
8385 return SetWithinGenBankSet (data, BioseqseqSet_class_phy_set);
8386 }
8387
RemoveExtraneousSets(Pointer data)8388 extern Int2 LIBCALLBACK RemoveExtraneousSets (Pointer data)
8389
8390 {
8391 BioseqPtr bsp;
8392 BioseqSetPtr bssp;
8393 Uint1 _class;
8394 ValNodePtr descr1 = NULL;
8395 ValNodePtr descr2 = NULL;
8396 BioseqSetPtr first = NULL;
8397 ObjMgrDataPtr omdptop;
8398 ObjMgrData omdata;
8399 OMProcControlPtr ompcp;
8400 Uint2 parenttype;
8401 Pointer parentptr;
8402 SeqEntryPtr sep;
8403 SeqEntryPtr tmp;
8404
8405 ompcp = (OMProcControlPtr) data;
8406 if (ompcp == NULL) return OM_MSG_RET_ERROR;
8407 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
8408 if (sep != NULL && IS_Bioseq_set (sep)) {
8409 bssp = (BioseqSetPtr) sep->data.ptrvalue;
8410 if (bssp != NULL && bssp->_class == 7) {
8411 descr1 = bssp->descr;
8412 bssp->descr = NULL;
8413 _class = 0;
8414 for (tmp = bssp->seq_set; tmp != NULL; tmp = tmp->next) {
8415 if (IS_Bioseq (tmp)) return OM_MSG_RET_DONE;
8416 if (_class == 0 && IS_Bioseq_set (tmp)) {
8417 first = (BioseqSetPtr) tmp->data.ptrvalue;
8418 if (first != NULL) {
8419 _class = first->_class;
8420 }
8421 }
8422 }
8423 if (first != NULL && bssp->seq_set != NULL && bssp->seq_set->next == NULL) {
8424 descr2 = first->descr;
8425 first->descr = NULL;
8426 }
8427 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
8428 GetSeqEntryParent (sep, &parentptr, &parenttype);
8429 if (_class >= 13 && _class <= 15) {
8430 for (tmp = bssp->seq_set; tmp != NULL; tmp = tmp->next) {
8431 RemovePopPhyMutSet (tmp, FALSE, FALSE);
8432 }
8433 InsetNewSet (bssp, _class);
8434 }
8435 if (_class == 7) {
8436 tmp = bssp->seq_set;
8437 if (tmp != NULL && IS_Bioseq_set (tmp)) {
8438 RemovePopPhyMutSet (tmp, TRUE, FALSE);
8439 }
8440 }
8441 if (IS_Bioseq (sep)) {
8442 bsp = (BioseqPtr) sep->data.ptrvalue;
8443 ValNodeLink (&(bsp->descr), descr1);
8444 ValNodeLink (&(bsp->descr), descr2);
8445 } else if (IS_Bioseq_set (sep)) {
8446 bssp = (BioseqSetPtr) sep->data.ptrvalue;
8447 ValNodeLink (&(bssp->descr), descr1);
8448 ValNodeLink (&(bssp->descr), descr2);
8449 }
8450 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
8451 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
8452 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
8453 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
8454 }
8455 }
8456 return OM_MSG_RET_DONE;
8457 }
8458
RepairMessedUpRecord(Pointer data)8459 static Int2 LIBCALLBACK RepairMessedUpRecord (Pointer data)
8460
8461 {
8462 BioseqSetPtr bssp;
8463 SeqEntryPtr last;
8464 SeqEntryPtr next;
8465 ObjMgrDataPtr omdptop;
8466 ObjMgrData omdata;
8467 OMProcControlPtr ompcp;
8468 Uint2 parenttype;
8469 Pointer parentptr;
8470 SeqEntryPtr sep;
8471 SeqEntryPtr tmp;
8472
8473 ompcp = (OMProcControlPtr) data;
8474 if (ompcp == NULL) return OM_MSG_RET_ERROR;
8475 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
8476 if (sep == NULL) return OM_MSG_RET_ERROR;
8477 if (! IS_Bioseq_set (sep)) return OM_MSG_RET_ERROR;
8478 bssp = (BioseqSetPtr) sep->data.ptrvalue;
8479 if (bssp == NULL || bssp->_class != 7) return OM_MSG_RET_ERROR;
8480 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
8481 GetSeqEntryParent (sep, &parentptr, &parenttype);
8482 tmp = bssp->seq_set;
8483 while (tmp != NULL) {
8484 next = tmp->next;
8485 tmp->next = NULL;
8486 if (IS_Bioseq_set (tmp)) {
8487 RemovePopPhyMutSet (tmp, FALSE, TRUE);
8488 }
8489 last = bssp->seq_set;
8490 while (last->next != NULL) {
8491 last = last->next;
8492 }
8493 last->next = next;
8494 tmp = next;
8495 }
8496 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
8497 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
8498 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
8499 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
8500 return OM_MSG_RET_DONE;
8501 }
8502
8503
MakeGeneXref(SeqFeatPtr sfpr,SeqFeatPtr sfpg)8504 static void MakeGeneXref (SeqFeatPtr sfpr, SeqFeatPtr sfpg)
8505
8506 {
8507 SeqFeatXrefPtr curr;
8508 GeneRefPtr grp;
8509 SeqFeatXrefPtr PNTR last;
8510 CharPtr locus;
8511 SeqFeatXrefPtr next;
8512 SeqFeatXrefPtr xref;
8513
8514 if (sfpr == NULL || sfpg == NULL || sfpg->data.choice != SEQFEAT_GENE) return;
8515 grp = (GeneRefPtr) sfpg->data.value.ptrvalue;
8516 if (grp == NULL) return;
8517 locus = grp->locus;
8518 if (StringHasNoText (locus)) return;
8519 last = (SeqFeatXrefPtr PNTR) &(sfpr->xref);
8520 curr = sfpr->xref;
8521 while (curr != NULL) {
8522 next = curr->next;
8523 if (curr->data.choice == SEQFEAT_GENE) {
8524 *last = next;
8525 curr->next = NULL;
8526 SeqFeatXrefFree (curr);
8527 } else {
8528 last = &(curr->next);
8529 }
8530 curr = next;
8531 }
8532 grp = GeneRefNew ();
8533 if (grp == NULL) return;
8534 grp->locus = StringSave (locus);
8535 TrimSpacesAroundString (grp->locus);
8536 xref = SeqFeatXrefNew ();
8537 sfpr->xref = xref;
8538 if (xref != NULL) {
8539 xref->data.choice = SEQFEAT_GENE;
8540 xref->data.value.ptrvalue = (Pointer) grp;
8541 }
8542 }
8543
GetSeqs(BioseqPtr bsp,SeqMgrBioseqContextPtr context)8544 static Boolean LIBCALLBACK GetSeqs (BioseqPtr bsp, SeqMgrBioseqContextPtr context)
8545
8546 {
8547 FILE *fp;
8548 Char str [256];
8549
8550 fp = (FILE *) context->userdata;
8551 if (BioseqLabel (bsp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8552 fprintf (fp, " Bioseq item %d %s\n", (int) context->itemID, str);
8553 }
8554 return TRUE;
8555 }
8556
GetSegs(SeqLocPtr slp,SeqMgrSegmentContextPtr context)8557 static Boolean LIBCALLBACK GetSegs (SeqLocPtr slp, SeqMgrSegmentContextPtr context)
8558
8559 {
8560 FILE *fp;
8561 Char str [256];
8562
8563 fp = (FILE *) context->userdata;
8564 if (SeqLocLabel (slp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8565 fprintf (fp, " SeqLoc item %d %s cumulative %ld\n", (int) context->itemID,
8566 str, (long) context->cumOffset);
8567 }
8568 return TRUE;
8569 }
8570
GetDescs(ValNodePtr sdp,SeqMgrDescContextPtr context)8571 static Boolean LIBCALLBACK GetDescs (ValNodePtr sdp, SeqMgrDescContextPtr context)
8572
8573 {
8574 FILE *fp;
8575 Char str [256];
8576
8577 fp = (FILE *) context->userdata;
8578 if (SeqDescLabel (sdp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8579 fprintf (fp, " Descriptor item %d index %d %s\n",
8580 (int) context->itemID, (int) context->index, str);
8581 }
8582 return TRUE;
8583 }
8584
GetFeats(SeqFeatPtr sfp,SeqMgrFeatContextPtr context)8585 static Boolean LIBCALLBACK GetFeats (SeqFeatPtr sfp, SeqMgrFeatContextPtr context)
8586
8587 {
8588 FILE *fp;
8589 Char str [256];
8590
8591 fp = (FILE *) context->userdata;
8592 if (FeatDefLabel (sfp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8593 fprintf (fp, " Feature item %d index %d %s\n",
8594 (int) context->itemID, (int) context->index, str);
8595 }
8596 return TRUE;
8597 }
8598
DoBioseqReport(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)8599 static void DoBioseqReport (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
8600
8601 {
8602 BioseqPtr bsp;
8603 SeqMgrDescContext desccontext;
8604 SeqMgrFeatContext featcontext;
8605 FILE *fp;
8606 SeqFeatPtr gene;
8607 Int2 i;
8608 Int4Ptr ivals;
8609 Int2 numivals;
8610 ValNodePtr sdp;
8611 SeqFeatPtr sfp;
8612 Char str [256];
8613
8614 if (sep == NULL) return;
8615 if (! IS_Bioseq (sep)) return;
8616 bsp = (BioseqPtr) sep->data.ptrvalue;
8617 if (bsp == NULL) return;
8618
8619 fp = (FILE*) mydata;
8620 if (fp == NULL) return;
8621
8622 if (BioseqLabel (bsp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8623 fprintf (fp, "Bioseq %s\n\n", str);
8624 }
8625
8626 if (bsp->repr == Seq_repr_seg) {
8627 fprintf (fp, " Exploring segments\n\n");
8628 SeqMgrExploreSegments (bsp, (Pointer) fp, GetSegs);
8629 fprintf (fp, "\n");
8630 }
8631
8632 if (ISA_aa (bsp->mol)) {
8633 sfp = SeqMgrGetBestProteinFeature (bsp, NULL);
8634 if (FeatDefLabel (sfp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8635 fprintf (fp, " Best protein %s", str);
8636 }
8637 sfp = SeqMgrGetCDSgivenProduct (bsp, NULL);
8638 if (FeatDefLabel (sfp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8639 fprintf (fp, ", best cds %s", str);
8640 }
8641 fprintf (fp, "\n\n");
8642 }
8643
8644
8645 fprintf (fp, " Exploring descriptors\n\n");
8646 SeqMgrExploreDescriptors (bsp, (Pointer) fp, GetDescs, NULL);
8647 fprintf (fp, "\n");
8648
8649 fprintf (fp, " Exploring features\n\n");
8650 SeqMgrExploreFeatures (bsp, (Pointer) fp, GetFeats, NULL, NULL, NULL);
8651 fprintf (fp, "\n");
8652
8653
8654 fprintf (fp, " Collecting descriptors\n\n");
8655 sdp = SeqMgrGetNextDescriptor (bsp, NULL, 0, &desccontext);
8656 while (sdp != NULL) {
8657 if (SeqDescLabel (sdp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8658 fprintf (fp, " Descriptor item %d index %d %s\n",
8659 (int) desccontext.itemID, (int) desccontext.index, str);
8660 }
8661 sdp = SeqMgrGetNextDescriptor (bsp, sdp, 0, &desccontext);
8662 }
8663 fprintf (fp, "\n");
8664
8665 fprintf (fp, " Collecting features\n\n");
8666 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &featcontext);
8667 while (sfp != NULL) {
8668 if (FeatDefLabel (sfp, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8669 fprintf (fp, " Feature item %d index %d %s",
8670 (int) featcontext.itemID, (int) featcontext.index, str);
8671 }
8672 if (featcontext.seqfeattype != SEQFEAT_GENE) {
8673 gene = SeqMgrGetOverlappingGene (sfp->location, NULL);
8674 if (gene != NULL) {
8675 if (FeatDefLabel (gene, str, sizeof (str) - 1, OM_LABEL_BOTH)) {
8676 fprintf (fp, ", gene %s", str);
8677 }
8678 }
8679 }
8680 fprintf (fp, "\n");
8681 ivals = featcontext.ivals;
8682 numivals = featcontext.numivals * 2;
8683 if (ivals != NULL && numivals > 0) {
8684 fprintf (fp, " (");
8685 for (i = 0; i < numivals; i += 2) {
8686 if (i > 0) {
8687 fprintf (fp, ", ");
8688 }
8689 fprintf (fp, "%ld-%ld", (long) ivals [i], (long) ivals [i + 1]);
8690 }
8691 fprintf (fp, ")\n");
8692 }
8693 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &featcontext);
8694 }
8695 fprintf (fp, "\n");
8696 }
8697
DoBioseqIndexing(Pointer data)8698 static Int2 LIBCALLBACK DoBioseqIndexing (Pointer data)
8699
8700 {
8701 BioseqPtr bsp = NULL;
8702 Uint2 entityID;
8703 FILE *fp;
8704 OMProcControlPtr ompcp;
8705 Char path [PATH_MAX];
8706 SeqEntryPtr sep;
8707 SeqFeatPtr sfp = NULL;
8708
8709 ompcp = (OMProcControlPtr) data;
8710 if (ompcp == NULL || ompcp->input_entityID == 0) {
8711 Message (MSG_ERROR, "Please select a Bioseq");
8712 return OM_MSG_RET_ERROR;
8713 }
8714 switch (ompcp->input_itemtype) {
8715 case OBJ_BIOSEQ :
8716 bsp = (BioseqPtr) ompcp->input_data;
8717 break;
8718 case OBJ_SEQFEAT:
8719 sfp = (SeqFeatPtr) ompcp->input_data;
8720 break;
8721 case 0 :
8722 return OM_MSG_RET_ERROR;
8723 default :
8724 return OM_MSG_RET_ERROR;
8725 }
8726 if (sfp != NULL) {
8727 bsp = BioseqFindFromSeqLoc (sfp->location);
8728 }
8729 if (bsp == NULL) {
8730 Message (MSG_ERROR, "Please select a Bioseq");
8731 return OM_MSG_RET_ERROR;
8732 }
8733 entityID = SeqMgrIndexFeatures (ompcp->input_entityID, NULL);
8734 if (entityID == 0) {
8735 Message (MSG_ERROR, "SeqMgrReindexBioseqExtraData failed");
8736 return OM_MSG_RET_ERROR;
8737 }
8738 sep = GetTopSeqEntryForEntityID (entityID);
8739 if (sep == NULL) return OM_MSG_RET_DONE;
8740 TmpNam (path);
8741 fp = FileOpen (path, "w");
8742
8743 if (sfp != NULL) {
8744
8745 fprintf (fp, " Exploring features filtered by location\n\n");
8746 SeqMgrExploreFeatures (bsp, (Pointer) fp, GetFeats, sfp->location, NULL, NULL);
8747 fprintf (fp, "\n");
8748
8749 } else {
8750
8751 fprintf (fp, "Exploring bioseqs\n\n");
8752 SeqMgrExploreBioseqs (entityID, 0, (Pointer) fp, GetSeqs, TRUE, TRUE, TRUE);
8753 fprintf (fp, "\n");
8754
8755 SeqEntryExplore (sep, (Pointer) fp, DoBioseqReport);
8756 }
8757 FileClose (fp);
8758 LaunchGeneralTextViewer (path, "Bioseq Index Report");
8759 FileRemove (path);
8760 return OM_MSG_RET_DONE;
8761 }
8762
FindNonACGT(Pointer data)8763 static Int2 LIBCALLBACK FindNonACGT (Pointer data)
8764
8765 {
8766 Byte bases [400];
8767 BioseqPtr bsp = NULL;
8768 Uint1 code = Seq_code_iupacna;
8769 Int2 ctr;
8770 FILE *fp;
8771 Int2 i;
8772 Boolean is_bad = FALSE;
8773 Int4 len;
8774 OMProcControlPtr ompcp;
8775 Char path [PATH_MAX];
8776 Uint1 residue;
8777 SeqPortPtr spp = NULL;
8778 Int4 total = 0;
8779
8780 ompcp = (OMProcControlPtr) data;
8781 if (ompcp == NULL || ompcp->input_entityID == 0) {
8782 Message (MSG_ERROR, "Please select a Bioseq");
8783 return OM_MSG_RET_ERROR;
8784 }
8785 switch (ompcp->input_itemtype) {
8786 case OBJ_BIOSEQ :
8787 bsp = (BioseqPtr) ompcp->input_data;
8788 break;
8789 default :
8790 break;
8791 }
8792 if (bsp == NULL) {
8793 Message (MSG_ERROR, "Please select a Bioseq");
8794 return OM_MSG_RET_ERROR;
8795 }
8796 if (ISA_aa (bsp->mol)) {
8797 code = Seq_code_ncbieaa;
8798 }
8799
8800 spp = SeqPortNew (bsp, 0, -1, 0, code);
8801 len = bsp->length;
8802
8803 if (spp == NULL) return OM_MSG_RET_ERROR;
8804
8805 TmpNam (path);
8806 fp = FileOpen (path, "w");
8807
8808 /* use SeqPortRead rather than SeqPortGetResidue for faster performance */
8809
8810 ctr = SeqPortRead (spp, bases, sizeof (bases));
8811 i = 0;
8812 residue = (Uint1) bases [i];
8813 while (residue != SEQPORT_EOF) {
8814 if (IS_residue (residue)) {
8815 total++;
8816 switch (residue) {
8817 case 'A' :
8818 case 'C' :
8819 case 'G' :
8820 case 'T' :
8821 break;
8822 default :
8823 fprintf (fp, "Bad residue '%c' at position %ld\n", (char) residue, (long) total);
8824 is_bad = TRUE;
8825 break;
8826 }
8827 }
8828 i++;
8829 if (i >= ctr) {
8830 i = 0;
8831 ctr = SeqPortRead (spp, bases, sizeof (bases));
8832 if (ctr < 0) {
8833 bases [0] = -ctr;
8834 } else if (ctr < 1) {
8835 bases [0] = SEQPORT_EOF;
8836 }
8837 }
8838 residue = (Uint1) bases [i];
8839 }
8840
8841 SeqPortFree (spp);
8842
8843 if (! is_bad) {
8844 fprintf (fp, "No ambiguous residues found");
8845 }
8846
8847 FileClose (fp);
8848 LaunchGeneralTextViewer (path, "Bioseq Index Report");
8849 FileRemove (path);
8850 return OM_MSG_RET_DONE;
8851 }
8852
RevStringUpper(CharPtr str)8853 static void NEAR RevStringUpper (CharPtr str)
8854 {
8855 CharPtr nd;
8856 Char tmp;
8857
8858 if (str == NULL)
8859 return;
8860 nd = str;
8861 while (*nd != '\0')
8862 nd++;
8863 nd--;
8864
8865 while (nd > str)
8866 {
8867 tmp = TO_UPPER(*nd);
8868 *nd = TO_UPPER(*str);
8869 *str = tmp;
8870 nd--; str++;
8871 }
8872
8873 if (nd == str)
8874 *nd = TO_UPPER(*nd);
8875 return;
8876 }
8877
8878
ReindexBioseqs(BioseqPtr bsp,Pointer userdata)8879 static void ReindexBioseqs (BioseqPtr bsp, Pointer userdata)
8880
8881 {
8882 SeqMgrReplaceInBioseqIndex (bsp);
8883 }
8884
DoClearSeqEntryScope(Pointer data)8885 static Int2 LIBCALLBACK DoClearSeqEntryScope (Pointer data)
8886
8887 {
8888 OMProcControlPtr ompcp;
8889 SeqEntryPtr sep;
8890
8891 SeqEntrySetScope (NULL);
8892 ompcp = (OMProcControlPtr) data;
8893 if (ompcp != NULL) {
8894 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
8895 if (sep != NULL) {
8896 VisitBioseqsInSep (sep, NULL, ReindexBioseqs);
8897 }
8898 }
8899 SeqEntrySetScope (NULL);
8900 return OM_MSG_RET_DONE;
8901 }
8902
SetupSequinFilters(void)8903 extern void SetupSequinFilters (void)
8904
8905 {
8906 Char str [32];
8907
8908 if (indexerVersion) {
8909 REGISTER_CLEAR_SEQENTRYSCOPE;
8910 REGISTER_AUTHORIZEDACCESSUSER_DESC_EDIT;
8911 REGISTER_GENOMEPROJSDBUSER_DESC_EDIT;
8912 REGISTER_UNVERIFIED_DESC_EDIT;
8913 REGISTER_DBLINKUSER_DESC_EDIT;
8914 REGISTER_REFGENEUSER_DESC_EDIT;
8915 REGISTER_COPY_MASTER_SOURCE_TO_SEGMENTS;
8916 REGISTER_DESCRIPTOR_PROPAGATE;
8917 }
8918
8919 if (GetAppParam ("SEQUIN", "SETTINGS", "ALLOWDETACH",
8920 NULL, str, sizeof (str)) &&
8921 StringICmp (str, "TRUE") == 0) {
8922 REGISTER_DETACH;
8923 }
8924
8925 REGISTER_STRUCTUREDCOMMENTUSER_DESC_EDIT;
8926 REGISTER_TPAASSEMBLYUSER_DESC_EDIT;
8927
8928 REGISTER_BIOSEQ_COMPLEMENT;
8929 REGISTER_BIOSEQ_REVERSE;
8930 REGISTER_BIOSEQ_REVCOMP_WITHFEAT;
8931 REGISTER_BIOSEQ_REVCOMP_NOTFEAT;
8932 REGISTER_BIOSEQ_REVCOMP_BYID;
8933
8934 #if defined(OS_UNIX) || defined(OS_MSWIN)
8935 if (indexerVersion) {
8936 REGISTER_CORRECTRNASTRAND;
8937 REGISTER_CORRECTRNASTRANDSMART;
8938 }
8939 #endif
8940
8941 REGISTER_BIOSEQ_ORF;
8942
8943 REGISTER_FIX_ALIGNMENT_GAP_GAPS;
8944 REGISTER_FIX_ALIGNMENT_OVER_GAPS;
8945 REGISTER_UPDATE_SEQALIGN;
8946 REGISTER_MAKESEQALIGNMASTERNEWBLAST;
8947 REGISTER_MAKESEQALIGNNEWBLAST;
8948 REGISTER_MAKESEQALIGNPNEWBLAST;
8949 REGISTER_NORMSEQALIGN;
8950 REGISTER_NOMORESEGGAP;
8951 REGISTER_OPENALED;
8952 REGISTER_OPENALED2;
8953
8954 if (extraServices) {
8955 REGISTER_INTERVAL_COMBINE_AND_FUSE;
8956 REGISTER_INTERVAL_COMBINE;
8957 REGISTER_REPACKAGE_PARTS;
8958 REGISTER_APPLY_SET_TYPE;
8959 REGISTER_REMOVESET;
8960 REGISTER_REMOVESETSINSET;
8961 REGISTER_UNDOSEGSET;
8962 REGISTER_SEGSETREMOVESETSINSET;
8963 REGISTER_ADJUSTMULTISEGSEQ;
8964 REGISTER_UPDATESEGSET;
8965 REGISTER_NEWUPDATESEGSET;
8966 REGISTER_CREATESEGSET;
8967 }
8968
8969 if (indexerVersion) {
8970 /*
8971 REGISTER_FEAT_INTERVALS_TO_DELTA;
8972 */
8973 REGISTER_REORDER_BY_ID;
8974 REGISTER_SEQUESTER_SETS;
8975 REGISTER_SEGREGATE_BY_FIELD;
8976 REGISTER_FIND_NON_ACGT;
8977 REGISTER_BSP_INDEX;
8978 REGISTER_POPSET_WITHIN_GENBANK;
8979 REGISTER_PHYSET_WITHIN_GENBANK;
8980 REGISTER_NORMALIZE_NUCPROT;
8981 REGISTER_REMOVE_EXTRANEOUS;
8982 REGISTER_REMOVE_MESSEDUP;
8983 REGISTER_GROUP_EXPLODE;
8984 REGISTER_DESKTOP_REPORT;
8985 }
8986
8987 }
8988
8989
8990 /* resolve existing colliding ids section */
8991
8992
8993 extern Int2 DoOneSegFixup (SeqEntryPtr sep, Boolean ask);
8994
8995 typedef struct reconstructsegsetans
8996 {
8997 WindoW w;
8998 Boolean ans;
8999 Boolean done;
9000 } ReconstructSegSetAnsData, PNTR ReconstructSegSetAnsPtr;
9001
ReconstructSegSetYes(ButtoN b)9002 static void ReconstructSegSetYes (ButtoN b)
9003 {
9004 ReconstructSegSetAnsPtr rp;
9005
9006 rp = (ReconstructSegSetAnsPtr) GetObjectExtra (b);
9007 if (rp == NULL) return;
9008 rp->ans = TRUE;
9009
9010 Remove (rp->w);
9011 rp->done = TRUE;
9012 }
9013
ReconstructSegSetNo(ButtoN b)9014 static void ReconstructSegSetNo (ButtoN b)
9015 {
9016 ReconstructSegSetAnsPtr rp;
9017
9018 rp = (ReconstructSegSetAnsPtr) GetObjectExtra (b);
9019 if (rp == NULL) return;
9020 rp->ans = FALSE;
9021
9022 Remove (rp->w);
9023 rp->done = TRUE;
9024 }
9025
GetReconstructSegSetAnswer(void)9026 static Boolean GetReconstructSegSetAnswer (void)
9027 {
9028 ReconstructSegSetAnsData rd;
9029 GrouP g, h, c;
9030 ButtoN b;
9031
9032 rd.w = ModalWindow(-20, -13, -10, -10, NULL);
9033 h = HiddenGroup(rd.w, -1, 0, NULL);
9034 SetGroupSpacing (h, 10, 10);
9035 rd.done = FALSE;
9036 g= HiddenGroup (h, 1, 0, NULL);
9037 StaticPrompt (g, "Do you wish to also reconstruct segmented bioseqs?", 0, popupMenuHeight, programFont, 'l');
9038 c = HiddenGroup (h, 2, 0, NULL);
9039 b = PushButton(c, "Yes", ReconstructSegSetYes);
9040 SetObjectExtra (b, &rd, NULL);
9041 b = DefaultButton(c, "No", ReconstructSegSetNo);
9042 SetObjectExtra (b, &rd, NULL);
9043 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
9044
9045 Show(rd.w);
9046 Select (rd.w);
9047 rd.done = FALSE;
9048 while (!rd.done)
9049 {
9050 ProcessExternalEvent ();
9051 Update ();
9052 }
9053 ProcessAnEvent ();
9054 return rd.ans;
9055 }
9056
9057
SeqEntryHasSegSets(SeqEntryPtr sep)9058 static Boolean SeqEntryHasSegSets (SeqEntryPtr sep)
9059 {
9060 BioseqSetPtr bssp;
9061 SeqEntryPtr seq_set;
9062
9063 if (sep == NULL || !IS_Bioseq_set (sep) || sep->data.ptrvalue == NULL)
9064 {
9065 return FALSE;
9066 }
9067
9068 bssp = (BioseqSetPtr) sep->data.ptrvalue;
9069
9070 if (bssp->_class == BioseqseqSet_class_segset)
9071 {
9072 return TRUE;
9073 }
9074 for (seq_set = bssp->seq_set; seq_set != NULL; seq_set = seq_set->next)
9075 {
9076 if (SeqEntryHasSegSets (seq_set))
9077 {
9078 return TRUE;
9079 }
9080 }
9081 return FALSE;
9082 }
9083
ResolveExistingLocalIDsBaseForm(BaseFormPtr bfp)9084 static void ResolveExistingLocalIDsBaseForm (BaseFormPtr bfp)
9085
9086 {
9087 Boolean doParts = FALSE, has_segsets = FALSE;
9088 LclIdListPtr head = NULL;
9089 SeqEntryPtr sep, oldscope;
9090
9091 if (bfp == NULL) return;
9092 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9093 if (sep == NULL) return;
9094
9095 /* first, promote local IDs in alignments (if possible) */
9096 oldscope = SeqEntrySetScope (sep);
9097 VisitAnnotsInSep (sep, NULL, PromoteAlignIDsProc);
9098 SeqEntrySetScope (oldscope);
9099
9100 if (HasAlignmentsWithLocalIDs (sep))
9101 {
9102 if (ANS_CANCEL == Message (MSG_OKC, "This record has alignments with local IDs. You will need to repair the alignments manually if you resolve colliding IDs. Do you want to continue?"))
9103 {
9104 return;
9105 }
9106 }
9107 has_segsets = SeqEntryHasSegSets (sep);
9108 if (has_segsets)
9109 {
9110 doParts = GetReconstructSegSetAnswer();
9111 }
9112 SeqEntryExplore (sep, (Pointer) &head, ResolveExistingIDsCallback);
9113 FreeLclTree (&head);
9114 if (doParts) {
9115 DoOneSegFixup (sep, FALSE);
9116 }
9117 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9118 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9119 }
9120
9121 extern void ResolveExistingLocalIDs (IteM i);
ResolveExistingLocalIDs(IteM i)9122 extern void ResolveExistingLocalIDs (IteM i)
9123 {
9124 BaseFormPtr bfp;
9125
9126 #ifdef WIN_MAC
9127 bfp = currentFormDataPtr;
9128 #else
9129 bfp = GetObjectExtra (i);
9130 #endif
9131
9132 if (bfp == NULL) return;
9133 ResolveExistingLocalIDsBaseForm (bfp);
9134 }
9135
ResolveExistingLocalIDsToolBtn(ButtoN b)9136 extern void ResolveExistingLocalIDsToolBtn (ButtoN b)
9137 {
9138 BaseFormPtr bfp;
9139
9140 bfp = (BaseFormPtr) GetObjectExtra (b);
9141 if (bfp == NULL) return;
9142 ResolveExistingLocalIDsBaseForm (bfp);
9143 }
9144
9145 extern void SetSourceFocus (IteM i);
9146 extern void ClearSourceFocus (IteM i);
9147
SetDescriptorFocus(BioseqPtr bsp,SeqMgrBioseqContextPtr bContext)9148 static Boolean LIBCALLBACK SetDescriptorFocus (BioseqPtr bsp,
9149 SeqMgrBioseqContextPtr bContext)
9150 {
9151 SeqMgrFeatContext fContext;
9152 SeqMgrDescContext dContext;
9153 BioSourcePtr biop;
9154 Boolean is_focus;
9155 SeqDescrPtr sdp;
9156
9157 /* Only set the focus when the Bioseq has */
9158 /* a source feature in addition to the */
9159 /* source descriptor. */
9160
9161 is_focus = (Boolean) * ((BoolPtr) bContext->userdata);
9162
9163 /* don't need feature to clear existing focus on descriptor */
9164
9165 if (is_focus && NULL == SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_BIOSRC, 0,
9166 &fContext))
9167 return TRUE;
9168
9169 /* Set the focus on all of the Bioseq's */
9170 /* source descriptors. */
9171
9172 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dContext);
9173 while (NULL != sdp) {
9174 biop = (BioSourcePtr) sdp->data.ptrvalue;
9175 if (biop == NULL)
9176 return TRUE;
9177 biop->is_focus = is_focus;
9178 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_source, &dContext);
9179 }
9180
9181 /* Return true to continue on to next Bioseq */
9182
9183 return TRUE;
9184 }
9185
CommonSourceFocus(IteM i,Boolean setfocus)9186 static void CommonSourceFocus (IteM i, Boolean setfocus)
9187
9188 {
9189 BaseFormPtr bfp;
9190 Boolean flag;
9191 SeqEntryPtr sep;
9192
9193 #ifdef WIN_MAC
9194 bfp = currentFormDataPtr;
9195 #else
9196 bfp = GetObjectExtra (i);
9197 #endif
9198 if (bfp == NULL) return;
9199 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9200 if (sep == NULL) return;
9201 flag = setfocus;
9202 SeqMgrExploreBioseqs (0, sep->data.ptrvalue, (Pointer) &flag,
9203 SetDescriptorFocus, TRUE, TRUE, TRUE);
9204 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9205 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9206 }
9207
SetSourceFocus(IteM i)9208 extern void SetSourceFocus (IteM i)
9209
9210 {
9211 CommonSourceFocus (i, TRUE);
9212 }
9213
ClearSourceFocus(IteM i)9214 extern void ClearSourceFocus (IteM i)
9215
9216 {
9217 CommonSourceFocus (i, FALSE);
9218 }
9219
9220
ConsolidateLikeModifiersProc(BioSourcePtr biop,Pointer userdata)9221 static void ConsolidateLikeModifiersProc (BioSourcePtr biop, Pointer userdata)
9222 {
9223 SubSourcePtr ssp;
9224 OrgModPtr mod;
9225 Boolean use_semicolon;
9226
9227 if (biop == NULL || userdata == NULL) return;
9228
9229 use_semicolon = *((Boolean PNTR) userdata);
9230
9231 for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next)
9232 {
9233 if (ssp->name != NULL)
9234 {
9235 ConsolidateOneLikeSubSourceModifier (ssp, use_semicolon);
9236 }
9237 }
9238
9239 if (biop->org == NULL || biop->org->orgname == NULL) return;
9240 for (mod = biop->org->orgname->mod; mod != NULL; mod = mod->next)
9241 {
9242 if (mod->subname != NULL)
9243 {
9244 ConsolidateOneLikeOrganismModifier (mod, use_semicolon);
9245 }
9246 }
9247 }
9248
ConsolidateLikeModifiers(IteM i,Boolean use_semicolon)9249 static void ConsolidateLikeModifiers (IteM i, Boolean use_semicolon)
9250 {
9251 BaseFormPtr bfp;
9252 SeqEntryPtr sep;
9253
9254 #ifdef WIN_MAC
9255 bfp = currentFormDataPtr;
9256 #else
9257 bfp = GetObjectExtra (i);
9258 #endif
9259 if (bfp == NULL) return;
9260 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9261 if (sep == NULL) return;
9262 VisitBioSourcesInSep (sep, &use_semicolon, ConsolidateLikeModifiersProc);
9263 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9264 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9265 }
9266
ConsolidateLikeModifiersWithSemicolons(IteM i)9267 extern void ConsolidateLikeModifiersWithSemicolons (IteM i)
9268 {
9269 ConsolidateLikeModifiers (i, TRUE);
9270 }
9271
ConsolidateLikeModifiersWithoutSemicolons(IteM i)9272 extern void ConsolidateLikeModifiersWithoutSemicolons (IteM i)
9273 {
9274 ConsolidateLikeModifiers (i, FALSE);
9275 }
9276
GetCountry(Uint1 data_choice,Pointer data,Pointer metadata)9277 static Pointer GetCountry (Uint1 data_choice, Pointer data, Pointer metadata)
9278 {
9279 ValNode vn;
9280
9281 vn.choice = SourceQualChoice_textqual;
9282 vn.data.intvalue = Source_qual_country;
9283 vn.next = NULL;
9284 return GetSourceQualFromBioSource (GetBioSourceFromObject (data_choice, data), &vn, NULL);
9285 }
9286
9287
GetAccession(Uint1 data_choice,Pointer data,Pointer metadata)9288 static Pointer GetAccession (Uint1 data_choice, Pointer data, Pointer metadata)
9289 {
9290 ValNode vn;
9291
9292 vn.choice = data_choice;
9293 vn.data.ptrvalue = data;
9294 vn.next = NULL;
9295 return GetParentLabelForDiscrepancyItem (&vn);
9296 }
9297
BulkSetCountry(Pointer target,Pointer data)9298 static void BulkSetCountry (Pointer target, Pointer data)
9299 {
9300 ValNode vn;
9301 SeqDescrPtr sdp = (SeqDescrPtr) target;
9302
9303 if (sdp == NULL || sdp->choice != Seq_descr_source) return;
9304
9305 vn.choice = SourceQualChoice_textqual;
9306 vn.data.intvalue = Source_qual_country;
9307 vn.next = NULL;
9308
9309 SetSourceQualInBioSource (sdp->data.ptrvalue, &vn, NULL, (CharPtr) data, ExistingTextOption_replace_old);
9310 }
9311
9312
9313 static BulkEdFieldData country_fields[] = {
9314 { "Country", BulkSetCountry, BulkSetSimpleTextString, GetCountry, BulkDisplaySimpleText, BulkFreeSimpleText, BulkSimpleTextDialog, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
9315 { "Accession", NULL, NULL, GetAccession, BulkDisplaySimpleText, BulkFreeSimpleText, NULL, BulkFormatSimpleText, NULL, NULL, BulkSimpleTextCopy },
9316 { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
9317
9318
CountryLookup(IteM i,Boolean with_cap_fix)9319 static void CountryLookup (IteM i, Boolean with_cap_fix)
9320 {
9321 BaseFormPtr bfp;
9322 SeqEntryPtr sep;
9323 ValNodePtr unfixable = NULL;
9324
9325
9326 #ifdef WIN_MAC
9327 bfp = currentFormDataPtr;
9328 #else
9329 bfp = GetObjectExtra (i);
9330 #endif
9331 if (bfp == NULL) return;
9332 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9333 if (sep == NULL) return;
9334
9335 unfixable = FixupCountryQuals (sep, with_cap_fix);
9336
9337 if (unfixable != NULL) {
9338 BulkEditorObjectList (bfp->input_entityID, "Country Modifiers That Could Not Be Autocorrected", unfixable, country_fields);
9339 }
9340
9341 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9342 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9343 }
9344
9345
CountryLookupWithoutCapFix(IteM i)9346 extern void CountryLookupWithoutCapFix (IteM i)
9347 {
9348 CountryLookup (i, FALSE);
9349 }
9350
9351
CountryLookupWithCapFix(IteM i)9352 extern void CountryLookupWithCapFix (IteM i)
9353 {
9354 CountryLookup (i, TRUE);
9355 }
9356
9357
FixMouseStrains(IteM i)9358 NLM_EXTERN void FixMouseStrains (IteM i)
9359 {
9360 BaseFormPtr bfp;
9361 SeqEntryPtr sep;
9362
9363 #ifdef WIN_MAC
9364 bfp = currentFormDataPtr;
9365 #else
9366 bfp = GetObjectExtra (i);
9367 #endif
9368 if (bfp == NULL) return;
9369 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9370 if (sep == NULL) return;
9371 if (FixupMouseStrains(sep, NULL)) {
9372 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9373 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9374 }
9375 }
9376
9377
ConvertPseudoCDSToMiscFeat(IteM i)9378 extern void ConvertPseudoCDSToMiscFeat (IteM i)
9379 {
9380 BaseFormPtr bfp;
9381
9382 #ifdef WIN_MAC
9383 bfp = currentFormDataPtr;
9384 #else
9385 bfp = GetObjectExtra (i);
9386 #endif
9387 if (bfp == NULL) return;
9388 ConvertPseudoCDSToMiscFeatsForEntityID (bfp->input_entityID);
9389 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9390 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9391 Update ();
9392 }
9393
9394 static Boolean
IsParseableInfluenzaAVirusBioSource(BioSourcePtr biop,CharPtr PNTR strain,CharPtr PNTR serotype)9395 IsParseableInfluenzaAVirusBioSource
9396 (BioSourcePtr biop,
9397 CharPtr PNTR strain,
9398 CharPtr PNTR serotype)
9399 {
9400 CharPtr desired_name = "Influenza A virus";
9401 Int4 desired_len = StringLen (desired_name);
9402 CharPtr first_paren = NULL, second_paren = NULL;
9403 CharPtr first_paren_close = NULL, second_paren_close = NULL;
9404 CharPtr cp;
9405 Int4 strain_len, serotype_len;
9406
9407 if (biop == NULL || biop->org == NULL || biop->org->taxname == NULL
9408 || strain == NULL
9409 || serotype == NULL)
9410 {
9411 return FALSE;
9412 }
9413
9414 if (StringNICmp (biop->org->taxname, desired_name, desired_len) != 0)
9415 {
9416 return FALSE;
9417 }
9418
9419 first_paren = StringChr (biop->org->taxname + desired_len, '(');
9420 if (first_paren == NULL) return FALSE;
9421 cp = first_paren + 1;
9422 while (*cp != ')' && *cp != '(' && *cp != 0)
9423 {
9424 cp++;
9425 }
9426 if (*cp != '(')
9427 {
9428 return FALSE;
9429 }
9430 second_paren = cp;
9431 cp++;
9432 while (*cp != ')' && *cp != '(' && *cp != 0)
9433 {
9434 cp++;
9435 }
9436 if (*cp != ')')
9437 {
9438 return FALSE;
9439 }
9440 second_paren_close = cp;
9441 cp++;
9442 while (*cp != ')' && *cp != '(' && *cp != 0)
9443 {
9444 cp++;
9445 }
9446 if (*cp != ')')
9447 {
9448 return FALSE;
9449 }
9450 first_paren_close = cp;
9451
9452 strain_len = second_paren - first_paren + first_paren_close - second_paren_close;
9453 serotype_len = second_paren_close - second_paren;
9454 *strain = (CharPtr) MemNew (strain_len * sizeof (Char));
9455 *serotype = (CharPtr) MemNew (serotype_len * sizeof (Char));
9456 if (*strain == NULL || *serotype == NULL)
9457 {
9458 *strain = MemFree (*strain);
9459 *serotype = MemFree (*serotype);
9460 return FALSE;
9461 }
9462 StringNCpy (*strain, first_paren + 1, second_paren - first_paren - 1);
9463 if (first_paren_close - second_paren_close > 1)
9464 {
9465 StringCat (*strain, " ");
9466 StringNCat (*strain, second_paren_close + 1, first_paren_close - second_paren_close - 1);
9467 }
9468 StringNCpy (*serotype, second_paren + 1, second_paren_close - second_paren - 1);
9469
9470 return TRUE;
9471 }
9472
ParseInfluenzaAVirusNamesCallback(BioSourcePtr biop,Pointer userdata)9473 static void ParseInfluenzaAVirusNamesCallback (BioSourcePtr biop, Pointer userdata)
9474 {
9475 CharPtr strain = NULL, serotype = NULL;
9476 OrgModPtr strain_omp, serotype_omp, last_omp, omp;
9477 Boolean added_strain = FALSE, added_serotype = FALSE;
9478 ExistingTextPtr etp;
9479
9480 etp = (ExistingTextPtr) userdata;
9481
9482 if (!IsParseableInfluenzaAVirusBioSource (biop, &strain, &serotype))
9483 {
9484 return;
9485 }
9486
9487 if (biop->org->orgname == NULL)
9488 {
9489 biop->org->orgname = OrgNameNew ();
9490 if (biop->org->orgname == NULL)
9491 {
9492 return;
9493 }
9494 }
9495
9496 last_omp = NULL;
9497 for (omp = biop->org->orgname->mod;
9498 omp != NULL && (!added_strain || ! added_serotype);
9499 omp = omp->next)
9500 {
9501 if (omp->subtype == ORGMOD_strain)
9502 {
9503 omp->subname = HandleExistingText (omp->subname, strain, etp);
9504 added_strain = TRUE;
9505 }
9506 else if (omp->subtype == ORGMOD_serotype)
9507 {
9508 omp->subname = HandleExistingText (omp->subname, serotype, etp);
9509 added_serotype = TRUE;
9510 }
9511 last_omp = omp;
9512 }
9513 if (! added_strain)
9514 {
9515 strain_omp = OrgModNew ();
9516 if (strain_omp != NULL)
9517 {
9518 strain_omp->subtype = ORGMOD_strain;
9519 strain_omp->subname = strain;
9520 if (last_omp == NULL)
9521 {
9522 biop->org->orgname->mod = strain_omp;
9523 }
9524 else
9525 {
9526 last_omp->next = strain_omp;
9527 }
9528 last_omp = strain_omp;
9529 }
9530 }
9531 if (!added_serotype)
9532 {
9533 serotype_omp = OrgModNew ();
9534 if (serotype_omp != NULL)
9535 {
9536 serotype_omp->subtype = ORGMOD_serotype;
9537 serotype_omp->subname = serotype;
9538 if (last_omp == NULL)
9539 {
9540 biop->org->orgname->mod = serotype_omp;
9541 }
9542 else
9543 {
9544 last_omp->next = serotype_omp;
9545 }
9546 }
9547 }
9548 }
9549
ParseInfluenzaAVirusNamesSample(BioSourcePtr biop,Pointer userdata)9550 static void ParseInfluenzaAVirusNamesSample (BioSourcePtr biop, Pointer userdata)
9551 {
9552 CharPtr strain = NULL, serotype = NULL;
9553 GetSamplePtr gsp;
9554 OrgModPtr omp;
9555 Boolean found_strain = FALSE, found_serotype = FALSE;
9556 CharPtr overwrite_val;
9557
9558 if (biop == NULL || biop->org == NULL || biop->org->orgname == NULL || userdata == NULL)
9559 {
9560 return;
9561 }
9562
9563 gsp = (GetSamplePtr) userdata;
9564
9565 if (!IsParseableInfluenzaAVirusBioSource (biop, &strain, &serotype))
9566 {
9567 return;
9568 }
9569
9570 for (omp = biop->org->orgname->mod;
9571 omp != NULL && (!found_strain || !found_serotype);
9572 omp = omp->next)
9573 {
9574 overwrite_val = NULL;
9575 if (omp->subtype == ORGMOD_strain)
9576 {
9577 found_strain = TRUE;
9578 overwrite_val = omp->subname;
9579 }
9580 else if (omp->subtype == ORGMOD_serotype)
9581 {
9582 found_serotype = TRUE;
9583 overwrite_val = omp->subname;
9584 }
9585 if (!StringHasNoText (overwrite_val))
9586 {
9587 gsp->num_found ++;
9588 if (gsp->sample_text == NULL)
9589 {
9590 gsp->sample_text = StringSave (overwrite_val);
9591 }
9592 else if (StringCmp (gsp->sample_text, overwrite_val) != 0)
9593 {
9594 gsp->all_same = FALSE;
9595 }
9596 }
9597 }
9598
9599 strain = MemFree (strain);
9600 serotype = MemFree (serotype);
9601 }
9602
ParseInfluenzaAVirusNames(IteM i)9603 extern void ParseInfluenzaAVirusNames (IteM i)
9604 {
9605 BaseFormPtr bfp;
9606 SeqEntryPtr sep;
9607 GetSamplePtr gsp;
9608 ExistingTextPtr etp;
9609
9610 #ifdef WIN_MAC
9611 bfp = currentFormDataPtr;
9612 #else
9613 bfp = GetObjectExtra (i);
9614 #endif
9615 if (bfp == NULL) return;
9616
9617 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9618 if (sep == NULL) return;
9619
9620 gsp = GetSampleNew ();
9621 VisitBioSourcesInSep (sep, gsp, ParseInfluenzaAVirusNamesSample);
9622 etp = GetExistingTextHandlerInfo (gsp == NULL ? 0 : gsp->num_found, FALSE);
9623 gsp = GetSampleFree (gsp);
9624 if (etp == NULL || etp->existing_text_choice != eExistingTextChoiceCancel)
9625 {
9626 VisitBioSourcesInSep (sep, etp, ParseInfluenzaAVirusNamesCallback);
9627 }
9628 etp = MemFree (etp);
9629 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9630 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9631 Update ();
9632 }
9633
9634 static void
AddStrainAndSerotypeToInfluenzaAVirusNamesCallback(BioSourcePtr biop,Pointer userdata)9635 AddStrainAndSerotypeToInfluenzaAVirusNamesCallback
9636 (BioSourcePtr biop,
9637 Pointer userdata)
9638 {
9639 CharPtr strain_str = NULL;
9640 CharPtr serotype_str = NULL;
9641 OrgModPtr omp;
9642 CharPtr strain_serotype_str;
9643 Int4 len;
9644 CharPtr desired_name = "Influenza A virus";
9645 Int4 desired_len = StringLen (desired_name);
9646
9647
9648 if (biop == NULL || biop->org == NULL || biop->org->orgname == NULL
9649 || StringNICmp (biop->org->taxname, desired_name, desired_len) != 0)
9650 {
9651 return;
9652 }
9653
9654 for (omp = biop->org->orgname->mod;
9655 omp != NULL && (strain_str == NULL || serotype_str == NULL);
9656 omp = omp->next)
9657 {
9658 if (omp->subtype == ORGMOD_strain)
9659 {
9660 strain_str = omp->subname;
9661 }
9662 else if (omp->subtype == ORGMOD_serotype)
9663 {
9664 serotype_str = omp->subname;
9665 }
9666 }
9667
9668 if (strain_str == NULL || serotype_str == NULL) return;
9669
9670 len = StringLen (strain_str) + StringLen (serotype_str) + 6 + StringLen (biop->org->taxname);
9671 strain_serotype_str = (CharPtr) MemNew (len * sizeof (Char));
9672 if (strain_serotype_str == NULL) return;
9673 sprintf (strain_serotype_str, "(%s(%s))", strain_str, serotype_str);
9674 if (StringStr (biop->org->taxname, strain_serotype_str))
9675 {
9676 MemFree (strain_serotype_str);
9677 return;
9678 }
9679 sprintf (strain_serotype_str, "%s (%s(%s))", biop->org->taxname,
9680 strain_str, serotype_str);
9681 SetTaxNameAndRemoveTaxRef (biop->org, strain_serotype_str);
9682 RemoveOldName(biop->org);
9683 }
9684
AddStrainAndSerotypeToInfluenzaAVirusNames(IteM i)9685 extern void AddStrainAndSerotypeToInfluenzaAVirusNames (IteM i)
9686 {
9687 BaseFormPtr bfp;
9688 SeqEntryPtr sep;
9689
9690 #ifdef WIN_MAC
9691 bfp = currentFormDataPtr;
9692 #else
9693 bfp = GetObjectExtra (i);
9694 #endif
9695 if (bfp == NULL) return;
9696
9697 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9698 if (sep == NULL) return;
9699 VisitBioSourcesInSep (sep, NULL, AddStrainAndSerotypeToInfluenzaAVirusNamesCallback);
9700 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9701 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9702 Update ();
9703 }
9704
9705
FixInfluenzaVirusName(CharPtr orig_name)9706 extern CharPtr FixInfluenzaVirusName (CharPtr orig_name)
9707 {
9708 CharPtr desired_name = "Influenza A virus";
9709 Int4 desired_len = StringLen (desired_name);
9710 CharPtr new_name = NULL, cp, src_cp, dst_cp;
9711
9712 if (StringHasNoText(orig_name)
9713 || StringNICmp (orig_name, desired_name, desired_len) != 0)
9714 {
9715 return NULL;
9716 }
9717
9718 cp = orig_name + desired_len;
9719 if (*cp == 0)
9720 {
9721 return NULL;
9722 }
9723
9724 /* allow one space and only one space between virus and the strain/serotype */
9725
9726 if (*cp == '(')
9727 {
9728 new_name = (CharPtr) MemNew (sizeof (Char) * (StringLen (orig_name) + 2));
9729 sprintf (new_name, "%s %s", desired_name, cp);
9730 }
9731 else
9732 {
9733 new_name = StringSave (orig_name);
9734 }
9735
9736 dst_cp = new_name + desired_len;
9737
9738 if (*dst_cp != ' ')
9739 {
9740 new_name = MemFree (new_name);
9741 return NULL;
9742 }
9743
9744 dst_cp++;
9745
9746 src_cp = dst_cp;
9747 /* skip over spaces */
9748 while (isspace (*src_cp))
9749 {
9750 src_cp++;
9751 }
9752 if (*src_cp != '(')
9753 {
9754 new_name = MemFree (new_name);
9755 return NULL;
9756 }
9757 /* copy first open paren */
9758 *dst_cp = *src_cp;
9759 dst_cp++;
9760 src_cp++;
9761
9762 /* skip over spaces */
9763 while (*src_cp == ' ' || *src_cp == '\t')
9764 {
9765 src_cp++;
9766 }
9767 /* copy to next open paren */
9768 while (*src_cp != '(' && *src_cp != 0)
9769 {
9770 *dst_cp = *src_cp;
9771 dst_cp++;
9772 src_cp++;
9773 }
9774 if (*src_cp == 0)
9775 {
9776 new_name = MemFree (new_name);
9777 return NULL;
9778 }
9779 /* skip back past spaces */
9780 while (*(dst_cp - 1) == ' ' || *(dst_cp - 1) == '\t')
9781 {
9782 dst_cp --;
9783 }
9784 /* copy to first close paren */
9785 while (*src_cp != ')' && *src_cp != 0)
9786 {
9787 *dst_cp = *src_cp;
9788 dst_cp++;
9789 src_cp++;
9790 }
9791 if (*src_cp == 0)
9792 {
9793 new_name = MemFree (new_name);
9794 return NULL;
9795 }
9796 /* skip back past spaces */
9797 while (*(dst_cp - 1) == ' ' || *(dst_cp - 1) == '\t')
9798 {
9799 dst_cp --;
9800 }
9801 /* copy first close paren */
9802 *dst_cp = *src_cp;
9803 dst_cp++;
9804 src_cp++;
9805 /* skip over spaces */
9806 while (*src_cp == ' ' || *src_cp == '\t')
9807 {
9808 src_cp++;
9809 }
9810 /* copy to second close paren */
9811 while (*src_cp != ')' && *src_cp != 0)
9812 {
9813 *dst_cp = *src_cp;
9814 dst_cp++;
9815 src_cp++;
9816 }
9817 if (*src_cp == 0)
9818 {
9819 new_name = MemFree (new_name);
9820 return NULL;
9821 }
9822 /* skip back past spaces */
9823 while (*(dst_cp - 1) == ' ' || *(dst_cp - 1) == '\t')
9824 {
9825 dst_cp --;
9826 }
9827 /* copy second close paren */
9828 *dst_cp = *src_cp;
9829 dst_cp++;
9830 src_cp++;
9831 while (*src_cp == ' ' || *src_cp == '\t')
9832 {
9833 src_cp++;
9834 }
9835 if (*src_cp != 0)
9836 {
9837 new_name = MemFree (new_name);
9838 return NULL;
9839 }
9840 *dst_cp = 0;
9841 return new_name;
9842 }
9843
9844 static void
FixupInfluenzaAVirusNamesCallback(BioSourcePtr biop,Pointer userdata)9845 FixupInfluenzaAVirusNamesCallback
9846 (BioSourcePtr biop,
9847 Pointer userdata)
9848 {
9849 CharPtr new_name;
9850
9851 if (biop == NULL || biop->org == NULL)
9852 {
9853 return;
9854 }
9855
9856 new_name = FixInfluenzaVirusName (biop->org->taxname);
9857
9858 if (new_name != NULL)
9859 {
9860 SetTaxNameAndRemoveTaxRef (biop->org, new_name);
9861 RemoveOldName(biop->org);
9862 }
9863 }
9864
9865
FixupInfluenzaAVirusNames(IteM i)9866 extern void FixupInfluenzaAVirusNames(IteM i)
9867 {
9868 BaseFormPtr bfp;
9869 SeqEntryPtr sep;
9870
9871 #ifdef WIN_MAC
9872 bfp = currentFormDataPtr;
9873 #else
9874 bfp = GetObjectExtra (i);
9875 #endif
9876 if (bfp == NULL) return;
9877
9878 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9879 if (sep == NULL) return;
9880 VisitBioSourcesInSep (sep, NULL, FixupInfluenzaAVirusNamesCallback);
9881 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9882 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9883 Update ();
9884 }
9885
9886 /* The following code is used for global publication editing. */
9887 /* This section of code is used to create a Publication Constraint */
9888
PubConstraintClearText(PubConstraintPtr pcp)9889 static void PubConstraintClearText (PubConstraintPtr pcp)
9890 {
9891 if (pcp != NULL)
9892 {
9893 pcp->find_str = MemFree (pcp->find_str);
9894 }
9895 }
9896
PubConstraintFree(PubConstraintPtr pcp)9897 extern PubConstraintPtr PubConstraintFree (PubConstraintPtr pcp)
9898 {
9899 if (pcp != NULL)
9900 {
9901 pcp->find_str = MemFree (pcp->find_str);
9902 pcp = MemFree (pcp);
9903 }
9904 return pcp;
9905 }
9906
9907 typedef struct pubfieldchoicedialog
9908 {
9909 DIALOG_MESSAGE_BLOCK
9910 PopuP main_list;
9911 PopuP author_list;
9912 PopuP affiliation_list;
9913 Boolean allow_any;
9914 } PubFieldChoiceDialogData, PNTR PubFieldChoiceDialogPtr;
9915
9916 enum pubfield_main_choice
9917 {
9918 PUB_MAIN_ANY = 1,
9919 PUB_MAIN_TITLE,
9920 PUB_MAIN_AUTHOR,
9921 PUB_MAIN_AFFILIATION
9922 };
9923
ENUM_ALIST(edit_pub_author_field_alist)9924 static ENUM_ALIST (edit_pub_author_field_alist)
9925 {"Last Name", PUB_FIELD_LAST_NAME},
9926 {"First Name", PUB_FIELD_FIRST_NAME},
9927 {"Consortium", PUB_FIELD_CONSORTIUM},
9928 {"Middle Initial", PUB_FIELD_MIDDLE_INITIAL},
9929 {"Suffix", PUB_FIELD_SUFFIX},
9930 END_ENUM_ALIST
9931
9932 static ENUM_ALIST (edit_pub_affiliation_field_alist)
9933 {"Department", PUB_FIELD_DEPARTMENT},
9934 {"Institution", PUB_FIELD_INSTITUTION},
9935 {"Address", PUB_FIELD_ADDRESS},
9936 {"City", PUB_FIELD_CITY},
9937 {"State", PUB_FIELD_STATE},
9938 {"Country", PUB_FIELD_COUNTRY},
9939 {"Zip Code", PUB_FIELD_ZIP},
9940 END_ENUM_ALIST
9941
9942 static void ChangePubFieldMainChoice (PopuP p)
9943 {
9944 PubFieldChoiceDialogPtr dlg;
9945 Int4 main_choice;
9946
9947 dlg = (PubFieldChoiceDialogPtr) GetObjectExtra (p);
9948 if (dlg != NULL)
9949 {
9950 Hide (dlg->author_list);
9951 Hide (dlg->affiliation_list);
9952 main_choice = GetValue (dlg->main_list);
9953 if (! dlg->allow_any)
9954 {
9955 main_choice ++;
9956 }
9957 if (main_choice == PUB_MAIN_AUTHOR)
9958 {
9959 Show (dlg->author_list);
9960 }
9961 else if (main_choice == PUB_MAIN_AFFILIATION)
9962 {
9963 Show (dlg->affiliation_list);
9964 }
9965 }
9966 }
9967
ResetPubFieldChoiceDialog(PubFieldChoiceDialogPtr dlg)9968 static void ResetPubFieldChoiceDialog (PubFieldChoiceDialogPtr dlg)
9969 {
9970 if (dlg != NULL)
9971 {
9972 /* if allow_any, 1 is any, otherwise 1 is title */
9973 SetValue (dlg->main_list, 1);
9974 ChangePubFieldMainChoice (dlg->main_list);
9975 }
9976 }
9977
PubFieldChoiceToDialog(DialoG d,Pointer userdata)9978 static void PubFieldChoiceToDialog (DialoG d, Pointer userdata)
9979 {
9980 PubFieldChoiceDialogPtr dlg;
9981 Int4Ptr pFieldChoice;
9982 Int4 field_choice;
9983
9984 dlg = (PubFieldChoiceDialogPtr) GetObjectExtra (d);
9985 if (dlg == NULL)
9986 {
9987 return;
9988 }
9989
9990 ResetPubFieldChoiceDialog (dlg);
9991
9992 if (userdata == NULL)
9993 {
9994 return;
9995 }
9996
9997 pFieldChoice = (Int4Ptr) userdata;
9998 field_choice = *pFieldChoice;
9999 if (field_choice == PUB_FIELD_ANY && ! dlg->allow_any)
10000 {
10001 field_choice = PUB_FIELD_TITLE;
10002 }
10003
10004 if (field_choice == PUB_FIELD_ANY)
10005 {
10006 SetValue (dlg->main_list, PUB_MAIN_ANY);
10007 }
10008 else if (field_choice == PUB_FIELD_TITLE)
10009 {
10010 if (dlg->allow_any)
10011 {
10012 SetValue (dlg->main_list, PUB_MAIN_TITLE);
10013 }
10014 else
10015 {
10016 SetValue (dlg->main_list, PUB_MAIN_TITLE - 1);
10017 }
10018 }
10019 else if (field_choice >= PUB_FIELD_FIRST_NAME
10020 && field_choice <= PUB_FIELD_CONSORTIUM)
10021 {
10022 if (dlg->allow_any)
10023 {
10024 SetValue (dlg->main_list, PUB_MAIN_AUTHOR);
10025 }
10026 else
10027 {
10028 SetValue (dlg->main_list, PUB_MAIN_AUTHOR - 1);
10029 }
10030 SetEnumPopup (dlg->author_list, edit_pub_author_field_alist, field_choice);
10031 }
10032 else if (field_choice >= PUB_FIELD_INSTITUTION)
10033 {
10034 if (dlg->allow_any)
10035 {
10036 SetValue (dlg->main_list, PUB_MAIN_AFFILIATION);
10037 }
10038 else
10039 {
10040 SetValue (dlg->main_list, PUB_MAIN_AFFILIATION - 1);
10041 }
10042 SetEnumPopup (dlg->affiliation_list, edit_pub_affiliation_field_alist, field_choice);
10043 }
10044
10045 ChangePubFieldMainChoice (dlg->main_list);
10046 }
10047
DialogToPubFieldChoice(DialoG d)10048 static Pointer DialogToPubFieldChoice (DialoG d)
10049 {
10050 PubFieldChoiceDialogPtr dlg;
10051 Int4 main_field_choice;
10052 UIEnum val;
10053 Int4Ptr retval;
10054
10055 dlg = (PubFieldChoiceDialogPtr) GetObjectExtra (d);
10056 retval = (Int4Ptr) MemNew (sizeof (Int4));
10057 if (retval == NULL)
10058 {
10059 return NULL;
10060 }
10061 *retval = PUB_FIELD_ANY;
10062 if (dlg == NULL)
10063 {
10064 return retval;
10065 }
10066
10067 main_field_choice = GetValue (dlg->main_list);
10068 if (!dlg->allow_any)
10069 {
10070 main_field_choice ++;
10071 }
10072
10073 if (main_field_choice == PUB_MAIN_ANY)
10074 {
10075 *retval = PUB_FIELD_ANY;
10076 }
10077 else if (main_field_choice == PUB_MAIN_TITLE)
10078 {
10079 *retval = PUB_FIELD_TITLE;
10080 }
10081 else if (main_field_choice == PUB_MAIN_AUTHOR)
10082 {
10083 if (GetEnumPopup (dlg->author_list, edit_pub_author_field_alist, &val))
10084 {
10085 *retval = val;
10086 }
10087 }
10088 else if (main_field_choice == PUB_MAIN_AFFILIATION)
10089 {
10090 if (GetEnumPopup (dlg->affiliation_list, edit_pub_affiliation_field_alist, &val))
10091 {
10092 *retval = val;
10093 }
10094 }
10095 return retval;
10096 }
10097
PubFieldChoiceDialog(GrouP h,Boolean allow_any)10098 static DialoG PubFieldChoiceDialog (GrouP h, Boolean allow_any)
10099
10100 {
10101 PubFieldChoiceDialogPtr dlg;
10102 GrouP p, k1;
10103
10104 dlg = (PubFieldChoiceDialogPtr) MemNew (sizeof (PubFieldChoiceDialogData));
10105 if (dlg == NULL)
10106 {
10107 return NULL;
10108 }
10109
10110 p = HiddenGroup (h, 2, 0, NULL);
10111 SetObjectExtra (p, dlg, StdCleanupExtraProc);
10112
10113 dlg->dialog = (DialoG) p;
10114 dlg->todialog = PubFieldChoiceToDialog;
10115 dlg->fromdialog = DialogToPubFieldChoice;
10116 dlg->dialogmessage = NULL;
10117 dlg->testdialog = NULL;
10118
10119 dlg->allow_any = allow_any;
10120
10121 dlg->main_list = PopupList (p, TRUE, ChangePubFieldMainChoice);
10122 SetObjectExtra (dlg->main_list, dlg, NULL);
10123 if (allow_any)
10124 {
10125 PopupItem (dlg->main_list, "Any Pub Field");
10126 }
10127 PopupItem (dlg->main_list, "Title");
10128 PopupItem (dlg->main_list, "Author");
10129 PopupItem (dlg->main_list, "Affiliation");
10130
10131 k1 = HiddenGroup (p, 0, 0, NULL);
10132 dlg->author_list = PopupList (k1, TRUE, NULL);
10133 InitEnumPopup (dlg->author_list, edit_pub_author_field_alist, NULL);
10134 SetEnumPopup (dlg->author_list, edit_pub_author_field_alist, PUB_FIELD_LAST_NAME);
10135 dlg->affiliation_list = PopupList (k1, TRUE, NULL);
10136 InitEnumPopup (dlg->affiliation_list, edit_pub_affiliation_field_alist, NULL);
10137 SetEnumPopup (dlg->affiliation_list, edit_pub_affiliation_field_alist, PUB_FIELD_DEPARTMENT);
10138
10139 ChangePubFieldMainChoice (dlg->main_list);
10140 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->author_list,
10141 (HANDLE) dlg->affiliation_list,
10142 NULL);
10143 return (DialoG) p;
10144 }
10145
10146
ENUM_ALIST(pub_stat_alist)10147 static ENUM_ALIST(pub_stat_alist)
10148 {"Any", PUB_STAT_ANY},
10149 {"Published", PUB_STAT_PUBLISHED},
10150 {"Unpublished", PUB_STAT_UNPUBLISHED},
10151 {"In Press", PUB_STAT_INPRESS},
10152 {"Submitter Block", PUB_STAT_PUBLISHED_SUBMISSION},
10153 END_ENUM_ALIST
10154
10155 typedef struct pubconstraintdialog
10156 {
10157 DIALOG_MESSAGE_BLOCK
10158 TexT find_str;
10159 ButtoN insensitive_to_case;
10160 DialoG field_for_find;
10161 PopuP pub_status;
10162 } PubConstraintDialogData, PNTR PubConstraintDialogPtr;
10163
ResetPubConstraintDialog(PubConstraintDialogPtr pcp)10164 static void ResetPubConstraintDialog (PubConstraintDialogPtr pcp)
10165 {
10166 Int4 field_choice = PUB_FIELD_ANY;
10167
10168 if (pcp == NULL) return;
10169 SetTitle (pcp->find_str, "");
10170 SetStatus (pcp->insensitive_to_case, FALSE);
10171 PointerToDialog (pcp->field_for_find, &field_choice);
10172 SetEnumPopup (pcp->pub_status, pub_stat_alist, PUB_STAT_ANY);
10173 }
10174
PubConstraintToDialog(DialoG d,Pointer data)10175 static void PubConstraintToDialog (DialoG d, Pointer data)
10176
10177 {
10178 PubConstraintDialogPtr dlg;
10179 PubConstraintPtr pcp;
10180
10181 dlg = (PubConstraintDialogPtr) GetObjectExtra (d);
10182 if (dlg == NULL)
10183 {
10184 return;
10185 }
10186 pcp = (PubConstraintPtr) data;
10187
10188 ResetPubConstraintDialog (dlg);
10189 if (pcp != NULL)
10190 {
10191 SetTitle (dlg->find_str, pcp->find_str);
10192 SetStatus (dlg->insensitive_to_case, pcp->insensitive_to_case);
10193 PointerToDialog (dlg->field_for_find, &(pcp->field_for_find));
10194 SetEnumPopup (dlg->pub_status, pub_stat_alist, pcp->pub_status);
10195 }
10196 }
10197
DialogToPubConstraint(DialoG d)10198 static Pointer DialogToPubConstraint (DialoG d)
10199
10200 {
10201 PubConstraintDialogPtr dlg;
10202 PubConstraintPtr pcp;
10203 UIEnum val;
10204 Int4Ptr retval;
10205
10206 dlg = (PubConstraintDialogPtr) GetObjectExtra (d);
10207 if (dlg == NULL)
10208 {
10209 return NULL;
10210 }
10211 pcp = (PubConstraintPtr) MemNew (sizeof (PubConstraintData));
10212 if (pcp != NULL)
10213 {
10214 pcp->find_str = JustSaveStringFromText (dlg->find_str);
10215 pcp->insensitive_to_case = GetStatus (dlg->insensitive_to_case);
10216 retval = DialogToPointer (dlg->field_for_find);
10217 if (retval == NULL)
10218 {
10219 pcp->field_for_find = PUB_FIELD_ANY;
10220 }
10221 else
10222 {
10223 pcp->field_for_find = *retval;
10224 retval = MemFree (retval);
10225 }
10226 if (GetEnumPopup (dlg->pub_status, pub_stat_alist, &val))
10227 {
10228 pcp->pub_status = val;
10229 }
10230 }
10231 return pcp;
10232 }
10233
ClearPubConstraint(ButtoN b)10234 static void ClearPubConstraint (ButtoN b)
10235 {
10236 PubConstraintDialogPtr dlg;
10237
10238 dlg = (PubConstraintDialogPtr) GetObjectExtra (b);
10239 ResetPubConstraintDialog (dlg);
10240 }
10241
PubConstraintDialog(GrouP h)10242 extern DialoG PubConstraintDialog (GrouP h)
10243
10244 {
10245 PubConstraintDialogPtr dlg;
10246 GrouP p, k1, k3;
10247 ButtoN b;
10248 PrompT ppt;
10249
10250 dlg = (PubConstraintDialogPtr) MemNew (sizeof (PubConstraintDialogData));
10251 if (dlg == NULL)
10252 {
10253 return NULL;
10254 }
10255
10256 p = NormalGroup (h, -1, 0, "Optional Constraints", programFont, NULL);
10257 SetObjectExtra (p, dlg, StdCleanupExtraProc);
10258
10259 dlg->dialog = (DialoG) p;
10260 dlg->todialog = PubConstraintToDialog;
10261 dlg->fromdialog = DialogToPubConstraint;
10262 dlg->dialogmessage = NULL;
10263 dlg->testdialog = NULL;
10264
10265 ppt = StaticPrompt (p, "Change only publications meeting these criteria:", 0,
10266 dialogTextHeight, programFont, 'c');
10267 k1 = HiddenGroup (p, 5, 0, NULL);
10268 StaticPrompt (k1, "Where", 0, dialogTextHeight, programFont, 'c');
10269 dlg->find_str = DialogText (k1, "", 15, NULL);
10270 StaticPrompt (k1, "occurs in", 0, dialogTextHeight, programFont, 'c');
10271 dlg->field_for_find = PubFieldChoiceDialog (k1, TRUE);
10272 dlg->insensitive_to_case = CheckBox (p, "Ignore case", NULL);
10273 k3 = HiddenGroup (p, 2, 0, NULL);
10274 StaticPrompt (k3, "Publication Status", 0, dialogTextHeight, programFont, 'c');
10275 dlg->pub_status = PopupList (k3, TRUE, NULL);
10276 InitEnumPopup (dlg->pub_status, pub_stat_alist, NULL);
10277 SetEnumPopup (dlg->pub_status, pub_stat_alist, 0);
10278
10279 b = PushButton (p, "Clear Publication Constraint", ClearPubConstraint);
10280 SetObjectExtra (b, dlg, NULL);
10281
10282 AlignObjects (ALIGN_CENTER, (HANDLE) ppt,
10283 (HANDLE) k1,
10284 (HANDLE) dlg->insensitive_to_case,
10285 (HANDLE) k3,
10286 (HANDLE) b,
10287 NULL);
10288 return (DialoG) p;
10289 }
10290
10291 /* The following functions are used for getting and setting various types of data
10292 * in publications.
10293 */
GetPubTitleSample(PubPtr the_pub)10294 static CharPtr GetPubTitleSample (PubPtr the_pub)
10295 {
10296 CitGenPtr cgp;
10297 CitArtPtr cap;
10298 CitBookPtr cbp;
10299 CitPatPtr cpp;
10300 CharPtr retp = NULL;
10301
10302 if (the_pub == NULL || the_pub->data.ptrvalue == NULL) return NULL;
10303
10304 switch (the_pub->choice) {
10305 case PUB_Gen :
10306 cgp = (CitGenPtr) the_pub->data.ptrvalue;
10307 retp = cgp->title;
10308 break;
10309 case PUB_Sub :
10310 break;
10311 case PUB_Article :
10312 cap = (CitArtPtr) the_pub->data.ptrvalue;
10313 if(cap->title != NULL)
10314 {
10315 retp = cap->title->data.ptrvalue;
10316 }
10317 break;
10318 case PUB_Book :
10319 case PUB_Man :
10320 cbp = (CitBookPtr) the_pub->data.ptrvalue;
10321 if(cbp->title != NULL)
10322 {
10323 retp = cbp->title->data.ptrvalue;
10324 }
10325 break;
10326 case PUB_Patent :
10327 cpp = (CitPatPtr) the_pub->data.ptrvalue;
10328 retp = cpp->title;
10329 break;
10330 default :
10331 break;
10332 }
10333 return retp;
10334 }
10335
SetPubTitle(PubPtr the_pub,CharPtr new_title)10336 static void SetPubTitle (PubPtr the_pub, CharPtr new_title)
10337 {
10338 CitGenPtr cgp;
10339 CitArtPtr cap;
10340 CitBookPtr cbp;
10341 CitPatPtr cpp;
10342
10343 if (the_pub == NULL || new_title == NULL) return;
10344
10345 switch (the_pub->choice) {
10346 case PUB_Gen :
10347 cgp = (CitGenPtr) the_pub->data.ptrvalue;
10348 cgp->title = MemFree (cgp->title);
10349 cgp->title = StringSave (new_title);
10350 break;
10351 case PUB_Sub :
10352 break;
10353 case PUB_Article :
10354 cap = (CitArtPtr) the_pub->data.ptrvalue;
10355 if (cap->title == NULL)
10356 {
10357 cap->title = ValNodeNew (cap->title);
10358 cap->title->choice = 1;
10359 }
10360 if(cap->title != NULL)
10361 {
10362 cap->title->data.ptrvalue = MemFree (cap->title->data.ptrvalue);
10363 cap->title->data.ptrvalue = StringSave (new_title);
10364 }
10365 break;
10366 case PUB_Book :
10367 case PUB_Man :
10368 cbp = (CitBookPtr) the_pub->data.ptrvalue;
10369 if (cbp->title == NULL)
10370 {
10371 cbp->title = ValNodeNew (cbp->title);
10372 cbp->title->choice = 1;
10373 }
10374 if(cbp->title != NULL)
10375 {
10376 cbp->title->data.ptrvalue = MemFree (cbp->title->data.ptrvalue);
10377 cbp->title->data.ptrvalue = StringSave (new_title);
10378 }
10379 break;
10380 case PUB_Patent :
10381 cpp = (CitPatPtr) the_pub->data.ptrvalue;
10382 cpp->title = MemFree (cpp->title);
10383 cpp->title = StringSave (new_title);
10384 break;
10385 default :
10386 break;
10387 }
10388 }
10389
10390
SetPubAuthorList(PubPtr the_pub,AuthListPtr alp)10391 static Boolean SetPubAuthorList (PubPtr the_pub, AuthListPtr alp)
10392 {
10393 AffilPtr old_affil = NULL;
10394 AuthListPtr PNTR old_auth;
10395
10396 if (the_pub == NULL || the_pub->data.ptrvalue == NULL || alp == NULL)
10397 return FALSE;
10398
10399 old_auth = GetAuthListForPub (the_pub);
10400 if (old_auth == NULL)
10401 {
10402 return FALSE;
10403 }
10404 if (*old_auth != NULL)
10405 {
10406 old_affil = (*old_auth)->affil;
10407 (*old_auth)->affil = NULL;
10408 (*old_auth) = AuthListFree (*old_auth);
10409 }
10410
10411 alp->affil = AffilFree (alp->affil);
10412 alp->affil = old_affil;
10413 *old_auth = alp;
10414
10415 return TRUE;
10416 }
10417
10418
GetAuthorField(AuthorPtr ap,Int4 field_for_find)10419 static CharPtr GetAuthorField (AuthorPtr ap, Int4 field_for_find)
10420 {
10421 CharPtr retp = NULL;
10422 NameStdPtr pNameStandard;
10423
10424 if (ap == NULL || field_for_find == PUB_FIELD_ANY) return NULL;
10425
10426 if (ap->name->choice == 2)
10427 {
10428 pNameStandard = (NameStdPtr) ap->name->data;
10429 if (pNameStandard != NULL)
10430 {
10431 switch (field_for_find)
10432 {
10433 case PUB_FIELD_FIRST_NAME:
10434 retp = pNameStandard->names [1];
10435 break;
10436 case PUB_FIELD_MIDDLE_INITIAL:
10437 retp = pNameStandard->names [4];
10438 if (retp != NULL)
10439 {
10440 retp = StringChr (retp, '.');
10441 if (retp != NULL)
10442 {
10443 retp++;
10444 }
10445 }
10446 break;
10447 case PUB_FIELD_LAST_NAME:
10448 retp = pNameStandard->names [0];
10449 break;
10450 case PUB_FIELD_SUFFIX:
10451 retp = pNameStandard->names [5];
10452 break;
10453 }
10454 }
10455 }
10456 else if (ap->name->choice == 5 && field_for_find == PUB_FIELD_CONSORTIUM)
10457 {
10458 retp = ap->name->data;
10459 }
10460 return retp;
10461 }
10462
GetAuthorListFieldSample(PubPtr pub,Int4 field_for_find)10463 static CharPtr GetAuthorListFieldSample (PubPtr pub, Int4 field_for_find)
10464 {
10465 CharPtr retp = NULL;
10466 AuthListPtr alp;
10467 ValNodePtr names;
10468 AuthorPtr ap;
10469
10470 if (pub == NULL || field_for_find == PUB_FIELD_ANY)
10471 {
10472 return NULL;
10473 }
10474 alp = GetAuthorListForPub (pub);
10475 if (alp == NULL) return NULL;
10476
10477 for (names = alp->names; names != NULL && retp == NULL; names = names->next)
10478 {
10479 ap = names->data.ptrvalue;
10480 retp = GetAuthorField (ap, field_for_find);
10481 if (StringHasNoText (retp))
10482 {
10483 retp = NULL;
10484 }
10485 }
10486 return retp;
10487 }
10488
10489
MakeNewInitials(NameStdPtr name_std)10490 static void MakeNewInitials (NameStdPtr name_std)
10491 {
10492 Char frstinits [64];
10493 Int4 init_len;
10494 CharPtr cp, middle_inits = NULL;
10495
10496 if (name_std == NULL) return;
10497 FirstNameToInitials (name_std->names [1], frstinits, sizeof (frstinits) - 1);
10498 init_len = StringLen (name_std->names [1]) + StringLen (name_std->names [4]) + 1;
10499 if (name_std->names [4] != NULL)
10500 {
10501 cp = StringRChr (name_std->names [4], '.');
10502 if (cp != NULL)
10503 {
10504 cp ++;
10505 if (*cp != 0)
10506 {
10507 middle_inits = StringSave (cp);
10508 }
10509
10510 }
10511 }
10512
10513 name_std->names [4] = MemFree (name_std->names [4]);
10514 name_std->names [4] = (CharPtr) MemNew (sizeof (Char) * init_len);
10515 if (name_std->names [4] != NULL)
10516 {
10517 StringCpy (name_std->names [4], frstinits);
10518 if (middle_inits != NULL)
10519 {
10520 StringCat (name_std->names [4], middle_inits);
10521 }
10522 }
10523 }
10524
SetMiddleInitial(NameStdPtr name_std,CharPtr init)10525 static void SetMiddleInitial (NameStdPtr name_std, CharPtr init)
10526 {
10527 CharPtr new_inits = NULL;
10528 Int4 first_init_len;
10529 Int4 len;
10530
10531 if (name_std == NULL)
10532 {
10533 return;
10534 }
10535
10536 first_init_len = StringLen (name_std->names[1]);
10537 len = first_init_len + StringLen (init) + 3;
10538 new_inits = (CharPtr) MemNew (len * sizeof (Char));
10539 if (new_inits != NULL)
10540 {
10541 FirstNameToInitials (name_std->names [1], new_inits,
10542 first_init_len);
10543 StringCat (new_inits, ".");
10544 if (!StringHasNoText (init))
10545 {
10546 StringCat (new_inits, init);
10547 StringCat (new_inits, ".");
10548 }
10549
10550 name_std->names[4] = MemFree (name_std->names[4]);
10551 name_std->names[4] = new_inits;
10552 }
10553
10554 }
10555
10556
SetAuthorString(AuthorPtr ap,Int4 field_to_set,CharPtr str)10557 static void SetAuthorString (AuthorPtr ap, Int4 field_to_set, CharPtr str)
10558 {
10559 NameStdPtr name_std;
10560
10561 if (field_to_set != PUB_FIELD_LAST_NAME &&
10562 (field_to_set == PUB_FIELD_LAST_NAME
10563 || field_to_set == PUB_FIELD_MIDDLE_INITIAL
10564 || field_to_set == PUB_FIELD_SUFFIX))
10565 {
10566 return;
10567 }
10568
10569 if (field_to_set == PUB_FIELD_FIRST_NAME
10570 || field_to_set == PUB_FIELD_LAST_NAME
10571 || field_to_set == PUB_FIELD_MIDDLE_INITIAL
10572 || field_to_set == PUB_FIELD_SUFFIX)
10573 {
10574 if (ap->name->choice != 2)
10575 {
10576 name_std = NameStdNew ();
10577 if (name_std != NULL)
10578 {
10579 ap->name->data = MemFree (ap->name->data);
10580 ap->name->data = name_std;
10581 ap->name->choice = 2;
10582 }
10583 }
10584 if (ap->name->choice == 2)
10585 {
10586 name_std = (NameStdPtr) ap->name->data;
10587 if (field_to_set == PUB_FIELD_FIRST_NAME)
10588 {
10589 name_std->names[1] = MemFree (name_std->names[1]);
10590 name_std->names[1] = StringSave (str);
10591 MakeNewInitials (name_std);
10592 }
10593 else if (field_to_set == PUB_FIELD_LAST_NAME)
10594 {
10595 name_std->names[0] = MemFree (name_std->names[0]);
10596 name_std->names[0] = StringSave (str);
10597 }
10598 else if (field_to_set == PUB_FIELD_MIDDLE_INITIAL)
10599 {
10600 SetMiddleInitial (name_std, str);
10601 }
10602 else if (field_to_set == PUB_FIELD_SUFFIX)
10603 {
10604 name_std->names[5] = MemFree (name_std->names[5]);
10605 name_std->names[5] = StringSave (str);
10606 }
10607 }
10608 }
10609 else if (field_to_set == PUB_FIELD_CONSORTIUM)
10610 {
10611 if (ap->name->choice != 5)
10612 {
10613 if (ap->name->choice == 2)
10614 {
10615 ap->name->data = NameStdFree (ap->name->data);
10616 }
10617 else
10618 {
10619 ap->name->data = MemFree (ap->name->data);
10620 }
10621 ap->name->choice = 5;
10622 }
10623 if (ap->name->choice == 5)
10624 {
10625 ap->name->data = MemFree (ap->name->data);
10626 ap->name->data = StringSave (str);
10627 }
10628 }
10629 }
10630
10631
GetAffiliationFieldSample(PubPtr pub,Int4 field_for_find)10632 static CharPtr GetAffiliationFieldSample (PubPtr pub, Int4 field_for_find)
10633 {
10634 CharPtr retp = NULL;
10635 AuthListPtr alp;
10636 AffilPtr affil;
10637
10638 if (pub == NULL || field_for_find == PUB_FIELD_ANY)
10639 {
10640 return NULL;
10641 }
10642 alp = GetAuthorListForPub (pub);
10643 if (alp == NULL) return NULL;
10644
10645 affil = alp->affil;
10646
10647 if (affil == NULL) return NULL;
10648
10649 switch (field_for_find)
10650 {
10651 case PUB_FIELD_INSTITUTION:
10652 retp = affil->affil;
10653 break;
10654 case PUB_FIELD_DEPARTMENT:
10655 retp = affil->div;
10656 break;
10657 case PUB_FIELD_ADDRESS:
10658 retp = affil->street;
10659 break;
10660 case PUB_FIELD_CITY:
10661 retp = affil->city;
10662 break;
10663 case PUB_FIELD_STATE:
10664 retp = affil->sub;
10665 break;
10666 case PUB_FIELD_COUNTRY:
10667 retp = affil->country;
10668 break;
10669 case PUB_FIELD_ZIP:
10670 retp = affil->postal_code;
10671 break;
10672 case PUB_FIELD_EMAIL:
10673 retp = affil->email;
10674 break;
10675 case PUB_FIELD_PHONE:
10676 retp = affil->phone;
10677 break;
10678 case PUB_FIELD_FAX:
10679 retp = affil->fax;
10680 break;
10681 }
10682 return retp;
10683 }
10684
10685
SetAffilString(AffilPtr affil,Int4 field_to_set,CharPtr str)10686 static AffilPtr SetAffilString (AffilPtr affil, Int4 field_to_set, CharPtr str)
10687 {
10688 if (affil == NULL)
10689 {
10690 affil = AffilNew ();
10691 if (affil == NULL) return NULL;
10692 affil->choice = 2;
10693 }
10694 else if (affil->choice != 2)
10695 {
10696 affil->choice = 2;
10697 }
10698 if (field_to_set == PUB_FIELD_INSTITUTION)
10699 {
10700 affil->affil = MemFree (affil->affil);
10701 affil->affil = StringSave (str);
10702 }
10703 else if (field_to_set == PUB_FIELD_DEPARTMENT)
10704 {
10705 affil->div = MemFree (affil->div);
10706 affil->div = StringSave (str);
10707 }
10708 else if (field_to_set == PUB_FIELD_ADDRESS)
10709 {
10710 affil->street = MemFree (affil->street);
10711 affil->street = StringSave (str);
10712 }
10713 else if (field_to_set == PUB_FIELD_CITY)
10714 {
10715 affil->city = MemFree (affil->city);
10716 affil->city = StringSave (str);
10717 }
10718 else if (field_to_set == PUB_FIELD_STATE)
10719 {
10720 affil->sub = MemFree (affil->sub);
10721 affil->sub = StringSave (str);
10722 }
10723 else if (field_to_set == PUB_FIELD_COUNTRY)
10724 {
10725 affil->country = MemFree (affil->country);
10726 affil->country = StringSave (str);
10727 }
10728 else if (field_to_set == PUB_FIELD_ZIP)
10729 {
10730 affil->postal_code = MemFree (affil->postal_code);
10731 affil->postal_code = StringSave (str);
10732 }
10733 else if (field_to_set == PUB_FIELD_EMAIL)
10734 {
10735 affil->email = MemFree (affil->email);
10736 affil->email = StringSave (str);
10737 }
10738 else if (field_to_set == PUB_FIELD_PHONE)
10739 {
10740 affil->phone = MemFree (affil->phone);
10741 affil->phone = StringSave (str);
10742 }
10743 else if (field_to_set == PUB_FIELD_FAX)
10744 {
10745 affil->fax = MemFree (affil->fax);
10746 affil->fax = StringSave (str);
10747 }
10748 return affil;
10749 }
10750
10751
GetSampleStringFromPub(PubdescPtr pdp,Int4 field_num)10752 static CharPtr GetSampleStringFromPub (PubdescPtr pdp, Int4 field_num)
10753 {
10754 PubPtr pub;
10755 CharPtr retp = NULL;
10756
10757 if (pdp == NULL || pdp->pub == NULL || field_num == PUB_FIELD_ANY)
10758 {
10759 return NULL;
10760 }
10761
10762 for (pub = pdp->pub; pub != NULL && retp == NULL; pub = pub->next)
10763 {
10764 switch (field_num)
10765 {
10766 case PUB_FIELD_TITLE:
10767 retp = GetPubTitleSample (pub);
10768 break;
10769 case PUB_FIELD_FIRST_NAME:
10770 case PUB_FIELD_MIDDLE_INITIAL:
10771 case PUB_FIELD_LAST_NAME:
10772 case PUB_FIELD_SUFFIX:
10773 case PUB_FIELD_CONSORTIUM:
10774 retp = GetAuthorListFieldSample (pub, field_num);
10775 break;
10776 case PUB_FIELD_INSTITUTION:
10777 case PUB_FIELD_DEPARTMENT:
10778 case PUB_FIELD_ADDRESS:
10779 case PUB_FIELD_CITY:
10780 case PUB_FIELD_STATE:
10781 case PUB_FIELD_COUNTRY:
10782 case PUB_FIELD_ZIP:
10783 case PUB_FIELD_EMAIL:
10784 case PUB_FIELD_PHONE:
10785 case PUB_FIELD_FAX:
10786 retp = GetAffiliationFieldSample (pub, field_num);
10787 break;
10788 }
10789 if (StringHasNoText (retp))
10790 {
10791 retp = NULL;
10792 }
10793 }
10794 return retp;
10795 }
10796
10797
GetPubStatus(PubPtr the_pub)10798 static Int4 GetPubStatus (PubPtr the_pub)
10799 {
10800 CitGenPtr cgp;
10801 CitSubPtr csp;
10802 CitArtPtr cap;
10803 CitBookPtr cbp;
10804 CitJourPtr cjp;
10805 ImprintPtr imp = NULL;
10806 Int4 status = PUB_STAT_ANY;
10807
10808 while (the_pub != NULL && status == PUB_STAT_ANY)
10809 {
10810 if (the_pub->data.ptrvalue != NULL)
10811 {
10812 switch (the_pub->choice)
10813 {
10814 case PUB_Gen :
10815 cgp = (CitGenPtr) the_pub->data.ptrvalue;
10816 if (cgp->cit != NULL && StringICmp (cgp->cit, "unpublished") == 0)
10817 {
10818 status = PUB_STAT_UNPUBLISHED;
10819 }
10820 else
10821 {
10822 status = PUB_STAT_PUBLISHED;
10823 }
10824 break;
10825 case PUB_Sub :
10826 csp = (CitSubPtr) the_pub->data.ptrvalue;
10827 status = PUB_STAT_PUBLISHED_SUBMISSION;
10828 break;
10829 case PUB_Article :
10830 cap = (CitArtPtr) the_pub->data.ptrvalue;
10831 if (cap->from == 1)
10832 {
10833 cjp = (CitJourPtr) cap->fromptr;
10834 if (cjp != NULL)
10835 {
10836 imp = cjp->imp;
10837 }
10838 }
10839 else if (cap->from == 2 || cap->from == 3)
10840 {
10841 cbp = (CitBookPtr) cap->fromptr;
10842 if (cbp != NULL) {
10843 imp = cbp->imp;
10844 }
10845 }
10846 break;
10847 case PUB_Journal :
10848 cjp = (CitJourPtr) the_pub->data.ptrvalue;
10849 imp = cjp->imp;
10850 case PUB_Book :
10851 case PUB_Man :
10852 cbp = (CitBookPtr) the_pub->data.ptrvalue;
10853 imp = cbp->imp;
10854 break;
10855 case PUB_Patent :
10856 status = PUB_STAT_PUBLISHED;
10857 break;
10858 default :
10859 break;
10860
10861 }
10862 if (imp != NULL)
10863 {
10864 if (imp->prepub == 0)
10865 {
10866 status = PUB_STAT_PUBLISHED;
10867 }
10868 else if (imp->prepub == 2)
10869 {
10870 status = PUB_STAT_INPRESS;
10871 }
10872 else if (imp->prepub == 1 && the_pub->choice == PUB_Sub)
10873 {
10874 status = PUB_STAT_PUBLISHED_SUBMISSION;
10875 }
10876 else
10877 {
10878 status = PUB_STAT_UNPUBLISHED;
10879 }
10880 }
10881 }
10882 the_pub = the_pub->next;
10883 }
10884 return status;
10885 }
10886
10887 /* The following functions are used to determine whether a particular section of a
10888 * publication matches the value specified in the PubConstraint.
10889 */
DoesPubTitleMatchConstraint(PubPtr the_pub,PubConstraintPtr p)10890 static Boolean DoesPubTitleMatchConstraint (PubPtr the_pub, PubConstraintPtr p)
10891 {
10892 CitGenPtr cgp;
10893 CitArtPtr cap;
10894 CitBookPtr cbp;
10895 CitPatPtr cpp;
10896 Boolean rval = FALSE;
10897 CharPtr title;
10898
10899 if (the_pub == NULL || p == NULL || the_pub->data.ptrvalue == NULL)
10900 {
10901 return FALSE;
10902 }
10903 if (p->find_str == NULL) return TRUE;
10904
10905 switch (the_pub->choice) {
10906 case PUB_Gen :
10907 cgp = (CitGenPtr) the_pub->data.ptrvalue;
10908 if ((p->insensitive_to_case
10909 && StringISearch (cgp->title, p->find_str) != NULL)
10910 || StringSearch (cgp->title, p->find_str) != NULL)
10911 {
10912 rval = TRUE;
10913 }
10914 break;
10915 case PUB_Sub :
10916 break;
10917 case PUB_Article :
10918 cap = (CitArtPtr) the_pub->data.ptrvalue;
10919 if(cap->title != NULL)
10920 {
10921 title = (CharPtr) (cap->title->data.ptrvalue);
10922 if ((p->insensitive_to_case
10923 && StringISearch (title, p->find_str) != NULL)
10924 || StringSearch (title, p->find_str) != NULL)
10925 {
10926 rval = TRUE;
10927 }
10928 }
10929 break;
10930 case PUB_Book :
10931 case PUB_Man :
10932 cbp = (CitBookPtr) the_pub->data.ptrvalue;
10933 if(cbp->title != NULL) {
10934 title = (CharPtr) (cbp->title->data.ptrvalue);
10935 if ((p->insensitive_to_case
10936 && StringISearch (title, p->find_str) != NULL)
10937 || StringSearch (title, p->find_str) != NULL)
10938 {
10939 rval = TRUE;
10940 }
10941 }
10942 break;
10943 case PUB_Patent :
10944 cpp = (CitPatPtr) the_pub->data.ptrvalue;
10945 if ((p->insensitive_to_case
10946 && StringISearch (cpp->title, p->find_str) != NULL)
10947 || StringSearch (cpp->title, p->find_str) != NULL)
10948 {
10949 rval = TRUE;
10950 }
10951 break;
10952 default :
10953 break;
10954 }
10955
10956 return rval;
10957 }
10958
DoesAffiliationMatchString(AffilPtr ap,PubConstraintPtr p)10959 static Boolean DoesAffiliationMatchString (AffilPtr ap, PubConstraintPtr p)
10960 {
10961 Boolean rval = FALSE;
10962
10963 if (ap == NULL || p == NULL) return FALSE;
10964
10965 if (p->find_str == NULL) return TRUE;
10966
10967 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_INSTITUTION)
10968 && ((p->insensitive_to_case && StringISearch (ap->affil, p->find_str) != NULL)
10969 || StringSearch (ap->affil, p->find_str) != NULL))
10970 {
10971 rval = TRUE;
10972 }
10973 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_DEPARTMENT)
10974 && ((p->insensitive_to_case && StringISearch (ap->div, p->find_str) != NULL)
10975 || StringSearch (ap->div, p->find_str) != NULL))
10976 {
10977 rval = TRUE;
10978 }
10979 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_ADDRESS)
10980 && ((p->insensitive_to_case && StringISearch (ap->street, p->find_str) != NULL)
10981 || StringSearch (ap->street, p->find_str) != NULL))
10982 {
10983 rval = TRUE;
10984 }
10985 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_CITY)
10986 && ((p->insensitive_to_case && StringISearch (ap->city, p->find_str) != NULL)
10987 || StringSearch (ap->city, p->find_str) != NULL))
10988 {
10989 rval = TRUE;
10990 }
10991 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_STATE)
10992 && ((p->insensitive_to_case && StringISearch (ap->sub, p->find_str) != NULL)
10993 || StringSearch (ap->sub, p->find_str) != NULL))
10994 {
10995 rval = TRUE;
10996 }
10997 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_COUNTRY)
10998 && ((p->insensitive_to_case && StringISearch (ap->country, p->find_str) != NULL)
10999 || StringSearch (ap->country, p->find_str) != NULL))
11000 {
11001 rval = TRUE;
11002 }
11003 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_EMAIL)
11004 && ((p->insensitive_to_case && StringISearch (ap->email, p->find_str) != NULL)
11005 || StringSearch (ap->email, p->find_str) != NULL))
11006 {
11007 rval = TRUE;
11008 }
11009 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_ZIP)
11010 && ((p->insensitive_to_case && StringISearch (ap->postal_code, p->find_str) != NULL)
11011 || StringSearch (ap->postal_code, p->find_str) != NULL))
11012 {
11013 rval = TRUE;
11014 }
11015 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_PHONE)
11016 && ((p->insensitive_to_case && StringISearch (ap->phone, p->find_str) != NULL)
11017 || StringSearch (ap->phone, p->find_str) != NULL))
11018 {
11019 rval = TRUE;
11020 }
11021 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_FAX)
11022 && ((p->insensitive_to_case && StringISearch (ap->fax, p->find_str) != NULL)
11023 || StringSearch (ap->fax, p->find_str) != NULL))
11024 {
11025 rval = TRUE;
11026 }
11027 return rval;
11028 }
11029
11030
DoesOneAuthorMatchString(AuthorPtr ap,PubConstraintPtr p)11031 static Boolean DoesOneAuthorMatchString (AuthorPtr ap, PubConstraintPtr p)
11032 {
11033 Boolean rval = FALSE;
11034 NameStdPtr pNameStandard = NULL;
11035
11036 if (ap == NULL || p == NULL) return FALSE;
11037 if (p->find_str == NULL) return TRUE;
11038
11039 if (ap->name->choice == 2)
11040 {
11041 pNameStandard = (NameStdPtr) ap->name->data;
11042 if (((p->field_for_find == PUB_FIELD_ANY
11043 || p->field_for_find == PUB_FIELD_FIRST_NAME))
11044 && ((p->insensitive_to_case && StringISearch (pNameStandard->names[1], p->find_str) != NULL)
11045 || StringSearch (pNameStandard->names[1], p->find_str) != NULL))
11046 {
11047 rval = TRUE;
11048 }
11049 if (((p->field_for_find == PUB_FIELD_ANY
11050 || p->field_for_find == PUB_FIELD_LAST_NAME))
11051 && ((p->insensitive_to_case && StringISearch (pNameStandard->names[0], p->find_str) != NULL)
11052 || StringSearch (pNameStandard->names[0], p->find_str) != NULL))
11053 {
11054 rval = TRUE;
11055 }
11056 if (((p->field_for_find == PUB_FIELD_ANY
11057 || p->field_for_find == PUB_FIELD_MIDDLE_INITIAL))
11058 && ((p->insensitive_to_case && StringISearch (pNameStandard->names[2], p->find_str) != NULL)
11059 || StringSearch (pNameStandard->names[2], p->find_str) != NULL))
11060 {
11061 rval = TRUE;
11062 }
11063 if (((p->field_for_find == PUB_FIELD_ANY
11064 || p->field_for_find == PUB_FIELD_SUFFIX))
11065 && ((p->insensitive_to_case && StringICmp (pNameStandard->names[5], p->find_str) == 0)
11066 || StringCmp (pNameStandard->names[5], p->find_str) == 0))
11067 {
11068 rval = TRUE;
11069 }
11070 }
11071 if (ap->name->choice == 5
11072 && (p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_CONSORTIUM)
11073 && ((p->insensitive_to_case && StringISearch (ap->name->data, p->find_str) != NULL)
11074 || StringSearch (ap->name->data, p->find_str) != NULL))
11075 {
11076 rval = TRUE;
11077 }
11078
11079 return rval;
11080 }
11081
11082
DoesAuthorListMatchConstraint(AuthListPtr alp,PubConstraintPtr p)11083 static Boolean DoesAuthorListMatchConstraint (AuthListPtr alp, PubConstraintPtr p)
11084 {
11085 Boolean rval = FALSE;
11086 ValNodePtr names;
11087 AuthorPtr ap;
11088
11089 if (alp == NULL || p == NULL)
11090 {
11091 return FALSE;
11092 }
11093 if (p->find_str == NULL) return TRUE;
11094
11095 for (names = alp->names; names != NULL && !rval; names = names->next)
11096 {
11097 ap = names->data.ptrvalue;
11098 rval = DoesOneAuthorMatchString (ap, p);
11099 }
11100
11101 return rval;
11102 }
11103
11104
DoesPubMatchConstraint(PubPtr the_pub,PubConstraintPtr p)11105 static Boolean DoesPubMatchConstraint (PubPtr the_pub, PubConstraintPtr p)
11106 {
11107 Boolean rval = FALSE;
11108 AuthListPtr alp;
11109
11110 if (the_pub == NULL || p == NULL) return FALSE;
11111
11112 if (p->pub_status != PUB_STAT_ANY && p->pub_status != GetPubStatus (the_pub))
11113 {
11114 return FALSE;
11115 }
11116 if ((p->field_for_find == PUB_FIELD_ANY || p->field_for_find == PUB_FIELD_TITLE)
11117 && DoesPubTitleMatchConstraint (the_pub, p))
11118 {
11119 rval = TRUE;
11120 }
11121 if (!rval)
11122 {
11123 alp = GetAuthorListForPub (the_pub);
11124 if (alp != NULL)
11125 {
11126 rval = DoesAuthorListMatchConstraint (alp, p);
11127 if (!rval && DoesAffiliationMatchString (alp->affil, p))
11128 {
11129 rval = TRUE;
11130 }
11131 }
11132 }
11133 return rval;
11134 }
11135
11136
11137 /* This structure is used for the Edit Publications dialog.
11138 * It contains a PubConstraint plus the necessary controls
11139 * to collect user input for editing a single field,
11140 * replacing a publication section, or merging author lists.
11141 */
11142 typedef struct EditPubform
11143 {
11144 FORM_MESSAGE_BLOCK
11145
11146 DialoG pub_constraint_dlg;
11147 ButtoN leaveDlgUp;
11148
11149 PubConstraintPtr pcp;
11150
11151 /* used for single field replace */
11152 TexT repl_string_txt;
11153 DialoG field_to_set_dlg;
11154 CharPtr repl_string;
11155 Int4 field_to_set;
11156
11157 /* used for replacing publication section */
11158 ButtoN replace_author_list;
11159 ButtoN replace_title;
11160 ButtoN replace_affiliation;
11161 PubdescPtr pdp;
11162 AuthListPtr alp;
11163 CharPtr title_str;
11164 AffilPtr affil;
11165
11166 /* used for author list merge */
11167 ValNodePtr names_list;
11168
11169 GrouP edit_type_group;
11170 Int4 edit_type;
11171 GrouP single_field_group;
11172 GrouP replace_sect_group;
11173 GrouP merge_auth_list_group;
11174 GrouP specify_author_order;
11175 GrouP replace_pub_group;
11176
11177 /* used for publication replace */
11178 Boolean found_conflict;
11179 Boolean found_one_pub;
11180 Boolean found_any_pubs;
11181 PubdescPtr replacement_pdp;
11182
11183 /* used for updating feature citations */
11184 ValNodePtr affected_pubs;
11185 } EditPubFormData, PNTR EditPubFormPtr;
11186
11187 typedef struct affectedpubpair
11188 {
11189 PubdescPtr orig; /* this is a copy and should be freed */
11190 PubdescPtr curr; /* this is not a copy and should not be freed */
11191 } AffectedPubPairData, PNTR AffectedPubPairPtr;
11192
AffectedPubPairListFree(ValNodePtr pair_list)11193 static ValNodePtr AffectedPubPairListFree (ValNodePtr pair_list)
11194 {
11195 AffectedPubPairPtr appp;
11196
11197 if (pair_list == NULL)
11198 {
11199 return NULL;
11200 }
11201 pair_list->next = AffectedPubPairListFree (pair_list->next);
11202 appp = (AffectedPubPairPtr) pair_list->data.ptrvalue;
11203 if (appp != NULL)
11204 {
11205 appp->orig = PubdescFree (appp->orig);
11206 }
11207 pair_list = ValNodeFreeData (pair_list);
11208 return pair_list;
11209 }
11210
11211 typedef Boolean (LIBCALLBACK *operateOnPubFunction) (
11212 PubPtr pub,
11213 EditPubFormPtr epfp
11214 );
11215
11216 typedef struct operatepub
11217 {
11218 operateOnPubFunction op_pub;
11219 EditPubFormPtr epfp;
11220 } OperatePubData, PNTR OperatePubPtr;
11221
OperateOnPubFeatureCallback(SeqFeatPtr sfp,Pointer userdata)11222 static void OperateOnPubFeatureCallback (SeqFeatPtr sfp, Pointer userdata)
11223 {
11224 OperatePubPtr opp;
11225 PubPtr pub;
11226 PubdescPtr pdp, pdp_copy;
11227 Boolean changed = FALSE;
11228 AffectedPubPairPtr appp;
11229
11230 if (sfp == NULL || sfp->data.choice != SEQFEAT_PUB || userdata == NULL)
11231 {
11232 return;
11233 }
11234 opp = (OperatePubPtr) userdata;
11235 if (opp->op_pub == NULL || opp->epfp == NULL) return;
11236 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
11237 if (pdp == NULL) return;
11238 pdp_copy = (PubdescPtr) AsnIoMemCopy (pdp, (AsnReadFunc) PubdescAsnRead,
11239 (AsnWriteFunc) PubdescAsnWrite);
11240 for (pub = pdp->pub; pub != NULL; pub = pub->next)
11241 {
11242 changed |= opp->op_pub (pub, opp->epfp);
11243 }
11244
11245 if (changed)
11246 {
11247 appp = (AffectedPubPairPtr) MemNew (sizeof (AffectedPubPairData));
11248 if (appp != NULL)
11249 {
11250 appp->orig = pdp_copy;
11251 appp->curr = pdp;
11252 ValNodeAddPointer (&(opp->epfp->affected_pubs), 0, appp);
11253 pdp_copy = NULL;
11254 }
11255 }
11256 pdp_copy = PubdescFree (pdp_copy);
11257 }
11258
OperateOnPubDescriptorCallback(SeqDescPtr sdp,Pointer userdata)11259 static void OperateOnPubDescriptorCallback (SeqDescPtr sdp, Pointer userdata)
11260 {
11261 OperatePubPtr opp;
11262 PubPtr pub;
11263 PubdescPtr pdp, pdp_copy;
11264 Boolean changed = FALSE;
11265 AffectedPubPairPtr appp;
11266
11267 if (sdp == NULL || sdp->choice != Seq_descr_pub || userdata == NULL)
11268 {
11269 return;
11270 }
11271 opp = (OperatePubPtr) userdata;
11272 if (opp->op_pub == NULL || opp->epfp == NULL) return;
11273 pdp = (PubdescPtr) sdp->data.ptrvalue;
11274 if (pdp == NULL) return;
11275 pdp_copy = (PubdescPtr) AsnIoMemCopy (pdp, (AsnReadFunc) PubdescAsnRead,
11276 (AsnWriteFunc) PubdescAsnWrite);
11277 for (pub = pdp->pub; pub != NULL; pub = pub->next)
11278 {
11279 changed |= opp->op_pub (pub, opp->epfp);
11280 }
11281 if (changed)
11282 {
11283 appp = (AffectedPubPairPtr) MemNew (sizeof (AffectedPubPairData));
11284 if (appp != NULL)
11285 {
11286 appp->orig = pdp_copy;
11287 appp->curr = pdp;
11288 ValNodeAddPointer (&(opp->epfp->affected_pubs), 0, appp);
11289 pdp_copy = NULL;
11290 }
11291 }
11292 pdp_copy = PubdescFree (pdp_copy);
11293 }
11294
11295
OperateOnPubByConstraint(SeqEntryPtr sep,EditPubFormPtr epfp,operateOnPubFunction op_pub)11296 static void OperateOnPubByConstraint (SeqEntryPtr sep, EditPubFormPtr epfp, operateOnPubFunction op_pub)
11297 {
11298 OperatePubData opd;
11299
11300 if (sep == NULL || epfp == NULL || op_pub == NULL) return;
11301 opd.epfp = epfp;
11302 opd.op_pub = op_pub;
11303
11304 VisitFeaturesInSep (sep, &opd, OperateOnPubFeatureCallback);
11305 VisitDescriptorsInSep (sep, &opd, OperateOnPubDescriptorCallback);
11306
11307 }
11308
11309 /* The following code is used for setting the value of a single field
11310 * in a publication.
11311 */
SetFieldByConstraint(PubPtr pdp,PubConstraintPtr p,Int4 field_to_set,CharPtr str,ValNodePtr PNTR affected_pubs)11312 static Boolean SetFieldByConstraint
11313 (PubPtr pdp,
11314 PubConstraintPtr p,
11315 Int4 field_to_set,
11316 CharPtr str,
11317 ValNodePtr PNTR affected_pubs)
11318 {
11319 ValNodePtr names;
11320 AuthListPtr alp;
11321 AuthorPtr ap;
11322 Boolean changed = FALSE;
11323
11324 if (pdp == NULL || p == NULL ||
11325 (p->pub_status != PUB_STAT_ANY && p->pub_status != GetPubStatus (pdp)))
11326 {
11327 return FALSE;
11328 }
11329
11330 if (field_to_set == PUB_FIELD_TITLE)
11331 {
11332 if (DoesPubMatchConstraint (pdp, p))
11333 {
11334 SetPubTitle (pdp, str);
11335 changed = TRUE;
11336 }
11337 }
11338 else if (field_to_set >= PUB_FIELD_FIRST_NAME
11339 && field_to_set <= PUB_FIELD_CONSORTIUM)
11340 {
11341 alp = GetAuthorListForPub (pdp);
11342 if (alp == NULL)
11343 {
11344 alp = AuthListNew ();
11345 if (! SetPubAuthorList (pdp, alp))
11346 {
11347 MemFree (alp);
11348 return FALSE;
11349 }
11350 }
11351 if ((p->field_for_find == PUB_FIELD_TITLE && DoesPubTitleMatchConstraint (pdp, p))
11352 || (p->field_for_find >= PUB_FIELD_INSTITUTION && p->field_for_find <= PUB_FIELD_FAX
11353 && DoesAffiliationMatchString (alp->affil, p)))
11354 {
11355 for (names = alp->names; names != NULL; names = names->next)
11356 {
11357 SetAuthorString (names->data.ptrvalue, field_to_set, str);
11358 }
11359 changed = TRUE;
11360 }
11361 else if (p->field_for_find >= PUB_FIELD_FIRST_NAME
11362 && p->field_for_find <= PUB_FIELD_CONSORTIUM)
11363 {
11364 if (field_to_set == PUB_FIELD_CONSORTIUM)
11365 {
11366 for (names = alp->names; names != NULL; names = names->next)
11367 {
11368 ap = (AuthorPtr) names->data.ptrvalue;
11369 if (ap != NULL && ap->name->choice == 5 && DoesOneAuthorMatchString (ap, p))
11370 {
11371 SetAuthorString (ap, field_to_set, str);
11372 changed = TRUE;
11373 }
11374 }
11375 }
11376 else
11377 {
11378 for (names = alp->names; names != NULL; names = names->next)
11379 {
11380 if (DoesOneAuthorMatchString (names->data.ptrvalue, p))
11381 {
11382 SetAuthorString (names->data.ptrvalue, field_to_set, str);
11383 changed = TRUE;
11384 }
11385 }
11386 }
11387 }
11388 else if (p->field_for_find == PUB_FIELD_ANY)
11389 {
11390 if (field_to_set == PUB_FIELD_CONSORTIUM)
11391 {
11392 for (names = alp->names; names != NULL; names = names->next)
11393 {
11394 ap = (AuthorPtr) names->data.ptrvalue;
11395 if (ap != NULL && ap->name->choice == 5)
11396 {
11397 SetAuthorString (ap, field_to_set, str);
11398 changed = TRUE;
11399 }
11400 }
11401 }
11402 else
11403 {
11404 for (names = alp->names; names != NULL; names = names->next)
11405 {
11406 SetAuthorString (names->data.ptrvalue, field_to_set, str);
11407 changed = TRUE;
11408 }
11409 }
11410 }
11411 }
11412 else if (field_to_set >= PUB_FIELD_INSTITUTION
11413 && field_to_set <= PUB_FIELD_FAX
11414 )
11415 {
11416 alp = GetAuthorListForPub (pdp);
11417 if (alp == NULL)
11418 {
11419 alp = AuthListNew ();
11420 if (! SetPubAuthorList (pdp, alp))
11421 {
11422 MemFree (alp);
11423 return FALSE;
11424 }
11425 }
11426 if (DoesPubMatchConstraint (pdp, p))
11427 {
11428 alp->affil = SetAffilString (alp->affil, field_to_set, str);
11429 changed = TRUE;
11430 }
11431 }
11432 return changed;
11433 }
11434
EditPubSingleField(PubPtr pub,EditPubFormPtr epfp)11435 static Boolean LIBCALLBACK EditPubSingleField (PubPtr pub, EditPubFormPtr epfp)
11436 {
11437 if (pub == NULL || epfp == NULL) return FALSE;
11438
11439 return SetFieldByConstraint (pub, epfp->pcp, epfp->field_to_set, epfp->repl_string,
11440 &(epfp->affected_pubs));
11441 }
11442
11443
11444 /* this code is used for replacing pub sections */
ReplacePubSectByConstraint(PubPtr pub,EditPubFormPtr epfp)11445 static Boolean LIBCALLBACK ReplacePubSectByConstraint (PubPtr pub, EditPubFormPtr epfp)
11446 {
11447 AuthListPtr alp;
11448 Boolean changed = FALSE;
11449
11450 if (pub == NULL || epfp == NULL)
11451 {
11452 return FALSE;
11453 }
11454 if (DoesPubMatchConstraint (pub, epfp->pcp))
11455 {
11456 if (epfp->alp != NULL)
11457 {
11458 alp = AsnIoMemCopy ((Pointer) epfp->alp,
11459 (AsnReadFunc) AuthListAsnRead,
11460 (AsnWriteFunc) AuthListAsnWrite);
11461 if (alp != NULL)
11462 {
11463 SetPubAuthorList (pub, alp);
11464 }
11465 }
11466 if (epfp->title_str != NULL)
11467 {
11468 SetPubTitle (pub, epfp->title_str);
11469 }
11470 if (epfp->affil != NULL)
11471 {
11472 alp = GetAuthorListForPub (pub);
11473 if (alp != NULL)
11474 {
11475 alp->affil = AffilFree (alp->affil);
11476 alp->affil = AsnIoMemCopy ((Pointer) epfp->affil,
11477 (AsnReadFunc) AffilAsnRead,
11478 (AsnWriteFunc) AffilAsnWrite);
11479 }
11480 }
11481 changed = TRUE;
11482 }
11483 return changed;
11484 }
11485
11486
11487 /* this code is used for merging author lists */
AreAuthorNamesIdentical(AuthorPtr ap1,AuthorPtr ap2)11488 static Boolean AreAuthorNamesIdentical (AuthorPtr ap1, AuthorPtr ap2)
11489 {
11490 NameStdPtr pNameStandard1, pNameStandard2;
11491 CharPtr n1, n2;
11492 Boolean rval = FALSE;
11493 Int4 idx;
11494
11495 if (ap1 == NULL || ap2 == NULL) return FALSE;
11496
11497 if (ap1->name->choice != ap2->name->choice)
11498 {
11499 rval = FALSE;
11500 }
11501 else
11502 {
11503 switch (ap1->name->choice)
11504 {
11505 case 2:
11506 pNameStandard1 = (NameStdPtr) ap1->name->data;
11507 pNameStandard2 = (NameStdPtr) ap2->name->data;
11508 rval = TRUE;
11509 for (idx = 0; idx < 7 && rval; idx++)
11510 {
11511 if (StringHasNoText (pNameStandard1->names[idx]))
11512 {
11513 if (!StringHasNoText (pNameStandard2->names[idx]))
11514 {
11515 rval = FALSE;
11516 }
11517 }
11518 else if (StringHasNoText (pNameStandard2->names[idx]))
11519 {
11520 rval = FALSE;
11521 }
11522 else if (StringCmp (pNameStandard1->names[idx], pNameStandard2->names[idx]) != 0)
11523 {
11524 rval = FALSE;
11525 }
11526 }
11527 break;
11528 case 4:
11529 case 5:
11530 n1 = (CharPtr) ap1->name->data;
11531 n2 = (CharPtr) ap2->name->data;
11532 if (StringCmp (n1, n2) == 0)
11533 {
11534 rval = TRUE;
11535 }
11536 break;
11537 }
11538 }
11539
11540 return rval;
11541 }
11542
GetMergedAuthorListByConstraint(PubPtr pub,EditPubFormPtr epfp)11543 static Boolean LIBCALLBACK GetMergedAuthorListByConstraint (PubPtr pub, EditPubFormPtr epfp)
11544 {
11545 AuthListPtr alp;
11546 ValNodePtr name_in_this, name_in_list;
11547 AuthorPtr ap1, ap2;
11548 Boolean found_match;
11549 Boolean changed = FALSE;
11550
11551 if (pub == NULL || epfp == NULL)
11552 {
11553 return FALSE;
11554 }
11555 if (DoesPubMatchConstraint (pub, epfp->pcp))
11556 {
11557 alp = GetAuthorListForPub (pub);
11558 if (alp != NULL)
11559 {
11560 for (name_in_this = alp->names; name_in_this != NULL; name_in_this = name_in_this->next)
11561 {
11562 ap1 = name_in_this->data.ptrvalue;
11563 found_match = FALSE;
11564 for (name_in_list = epfp->names_list;
11565 name_in_list != NULL && !found_match;
11566 name_in_list = name_in_list->next)
11567 {
11568 ap2 = name_in_list->data.ptrvalue;
11569 if (AreAuthorNamesIdentical (ap1, ap2))
11570 {
11571 found_match = TRUE;
11572 }
11573 }
11574 if (!found_match)
11575 {
11576 ap2 = AsnIoMemCopy ((Pointer) ap1,
11577 (AsnReadFunc) AuthorAsnRead,
11578 (AsnWriteFunc) AuthorAsnWrite);
11579 if (ap2 != NULL)
11580 {
11581 ValNodeAddPointer (&(epfp->names_list), name_in_this->choice, ap2);
11582 }
11583 }
11584 }
11585 }
11586 changed = TRUE;
11587 }
11588 return changed;
11589 }
11590
FreeAuthorNameList(ValNodePtr names_list)11591 static ValNodePtr FreeAuthorNameList (ValNodePtr names_list)
11592 {
11593 ValNodePtr vnp;
11594
11595 for (vnp = names_list; vnp != NULL; vnp = vnp->next)
11596 {
11597 vnp->data.ptrvalue = AuthorFree (vnp->data.ptrvalue);
11598 }
11599 names_list = ValNodeFree (names_list);
11600 return names_list;
11601 }
11602
ReplaceNameList(AuthListPtr alp,ValNodePtr new_name_list)11603 static void ReplaceNameList (AuthListPtr alp, ValNodePtr new_name_list)
11604 {
11605 ValNodePtr new_name;
11606 AuthorPtr new_ap;
11607
11608 if (alp == NULL) return;
11609
11610 alp->names = FreeAuthorNameList (alp->names);
11611
11612 for (new_name = new_name_list; new_name != NULL; new_name = new_name->next)
11613 {
11614 new_ap = AsnIoMemCopy (new_name->data.ptrvalue,
11615 (AsnReadFunc) AuthorAsnRead,
11616 (AsnWriteFunc) AuthorAsnWrite);
11617 if (new_ap != NULL)
11618 {
11619 ValNodeAddPointer (&(alp->names), new_name->choice, new_ap);
11620 }
11621 }
11622 }
11623
SetMergedAuthorListByConstraint(PubPtr pub,EditPubFormPtr epfp)11624 static Boolean LIBCALLBACK SetMergedAuthorListByConstraint (PubPtr pub, EditPubFormPtr epfp)
11625 {
11626 AuthListPtr alp;
11627 Boolean changed = FALSE;
11628
11629 if (pub == NULL || epfp == NULL)
11630 {
11631 return FALSE;
11632 }
11633 if (DoesPubMatchConstraint (pub, epfp->pcp))
11634 {
11635 alp = GetAuthorListForPub (pub);
11636 ReplaceNameList (alp, epfp->names_list);
11637 changed = TRUE;
11638 }
11639 return changed;
11640 }
11641
11642
FindFirstSelectedPub(void)11643 static PubdescPtr FindFirstSelectedPub (void)
11644 {
11645 SelStructPtr ssp;
11646 SeqFeatPtr sfp;
11647 SeqDescrPtr sdp;
11648 PubdescPtr pdp = NULL;
11649 SeqMgrFeatContext fcontext;
11650 SeqMgrDescContext dcontext;
11651
11652
11653 /* find the selected pub */
11654 ssp = ObjMgrGetSelected();
11655
11656 while (NULL != ssp && pdp == NULL)
11657 {
11658 if (ssp->itemtype == OBJ_SEQFEAT)
11659 {
11660 sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &fcontext);
11661 if (sfp != NULL && sfp->data.choice == SEQFEAT_PUB)
11662 {
11663 pdp = sfp->data.value.ptrvalue;
11664 }
11665 }
11666 else if (ssp->itemtype == OBJ_SEQDESC)
11667 {
11668 sdp = SeqMgrGetDesiredDescriptor (ssp->entityID, NULL, ssp->itemID, 0, NULL, &dcontext);
11669 if (sdp != NULL && sdp->choice == Seq_descr_pub)
11670 {
11671 pdp = sdp->data.ptrvalue;
11672 }
11673 }
11674 ssp = ssp->next;
11675 }
11676 return pdp;
11677 }
11678
PubdescIsSubmitterBlock(PubdescPtr pdp)11679 static Boolean PubdescIsSubmitterBlock (PubdescPtr pdp)
11680 {
11681 Boolean is_submitter_block = FALSE;
11682 PubPtr pub;
11683
11684 if (pdp == NULL) return FALSE;
11685 for (pub = pdp->pub; pub != NULL && ! is_submitter_block; pub = pub->next)
11686 {
11687 if (pub->choice == PUB_Sub)
11688 {
11689 is_submitter_block = TRUE;
11690 }
11691 }
11692 return is_submitter_block;
11693 }
11694
FindPubReplaceConflictsInDescr(SeqDescrPtr sdp,EditPubFormPtr epfp)11695 static void FindPubReplaceConflictsInDescr (SeqDescrPtr sdp, EditPubFormPtr epfp)
11696 {
11697 Boolean this_pub_matches;
11698 PubPtr pub;
11699 PubdescPtr pdp;
11700 Boolean repl_is_submitter_block;
11701 Boolean this_is_submitter_block;
11702
11703 if (sdp == NULL || epfp == NULL) return;
11704
11705 repl_is_submitter_block = PubdescIsSubmitterBlock (epfp->replacement_pdp);
11706
11707 while (sdp != NULL && ! epfp->found_conflict)
11708 {
11709 this_pub_matches = FALSE;
11710 if (sdp->choice == Seq_descr_pub && sdp->data.ptrvalue != NULL)
11711 {
11712 pdp = (PubdescPtr) sdp->data.ptrvalue;
11713 for (pub = pdp->pub; pub != NULL && ! this_pub_matches; pub = pub->next)
11714 {
11715 this_pub_matches = DoesPubMatchConstraint (pub, epfp->pcp);
11716 }
11717 this_is_submitter_block = PubdescIsSubmitterBlock (pdp);
11718 if ((this_is_submitter_block && ! repl_is_submitter_block)
11719 || (! this_is_submitter_block && repl_is_submitter_block))
11720 {
11721 this_pub_matches = FALSE;
11722 }
11723
11724 if (this_pub_matches)
11725 {
11726 if (epfp->found_one_pub)
11727 {
11728 epfp->found_conflict = TRUE;
11729 }
11730 else
11731 {
11732 epfp->found_one_pub = TRUE;
11733 epfp->found_any_pubs = TRUE;
11734 }
11735 }
11736 }
11737 sdp = sdp->next;
11738 }
11739 }
11740
FindPubReplaceConflictsInAnnot(SeqAnnotPtr annot,EditPubFormPtr epfp)11741 static void FindPubReplaceConflictsInAnnot (SeqAnnotPtr annot, EditPubFormPtr epfp)
11742 {
11743 SeqFeatPtr sfp;
11744 Boolean this_pub_matches;
11745 PubPtr pub;
11746 PubdescPtr pdp;
11747
11748 if (annot == NULL || epfp == NULL) return;
11749
11750 while (annot != NULL && ! epfp->found_conflict)
11751 {
11752 if (annot->type == 1)
11753 {
11754 for (sfp = annot->data; sfp != NULL && ! epfp->found_conflict; sfp = sfp->next)
11755 {
11756 if (sfp->data.choice == SEQFEAT_PUB && sfp->data.value.ptrvalue != NULL)
11757 {
11758 this_pub_matches = FALSE;
11759 pdp = sfp->data.value.ptrvalue;
11760 for (pub = pdp->pub; pub != NULL && ! this_pub_matches; pub = pub->next)
11761 {
11762 this_pub_matches = DoesPubMatchConstraint (pub, epfp->pcp);
11763 }
11764 if (this_pub_matches)
11765 {
11766 if (epfp->found_one_pub)
11767 {
11768 epfp->found_conflict = TRUE;
11769 }
11770 else
11771 {
11772 epfp->found_one_pub = TRUE;
11773 epfp->found_any_pubs = TRUE;
11774 }
11775 }
11776 }
11777 }
11778 }
11779 annot = annot->next;
11780 }
11781 }
11782
11783
FindPubReplaceConflictsOnBioseq(BioseqPtr bsp,EditPubFormPtr epfp)11784 static void FindPubReplaceConflictsOnBioseq (BioseqPtr bsp, EditPubFormPtr epfp)
11785 {
11786 if (bsp == NULL || epfp == NULL) return;
11787
11788 /* don't need to check if we've found a conflict somewhere else */
11789 if (epfp->found_conflict) return;
11790
11791 FindPubReplaceConflictsInDescr (bsp->descr, epfp);
11792 FindPubReplaceConflictsInAnnot (bsp->annot, epfp);
11793 }
11794
11795 static void FindPubReplaceConflictsInSeqEntry (SeqEntryPtr sep, EditPubFormPtr epfp);
11796
FindPubReplaceConflictsOnBioseqSet(BioseqSetPtr bssp,EditPubFormPtr epfp)11797 static void FindPubReplaceConflictsOnBioseqSet (BioseqSetPtr bssp, EditPubFormPtr epfp)
11798 {
11799 if (bssp == NULL || epfp == NULL) return;
11800
11801 /* don't need to check if we've found a conflict somewhere else */
11802 if (epfp->found_conflict) return;
11803
11804 FindPubReplaceConflictsInDescr (bssp->descr, epfp);
11805 FindPubReplaceConflictsInAnnot (bssp->annot, epfp);
11806
11807 if (!epfp->found_conflict)
11808 {
11809 FindPubReplaceConflictsInSeqEntry (bssp->seq_set, epfp);
11810 }
11811 }
11812
FindPubReplaceConflictsInSeqEntry(SeqEntryPtr sep,EditPubFormPtr epfp)11813 static void FindPubReplaceConflictsInSeqEntry (SeqEntryPtr sep, EditPubFormPtr epfp)
11814 {
11815 Boolean found_above;
11816
11817 if (sep == NULL || epfp == NULL) return;
11818
11819 found_above = epfp->found_one_pub;
11820
11821 while (sep != NULL)
11822 {
11823 if (IS_Bioseq (sep))
11824 {
11825 FindPubReplaceConflictsOnBioseq ((BioseqPtr) sep->data.ptrvalue, epfp);
11826 }
11827 else if (IS_Bioseq_set (sep))
11828 {
11829 FindPubReplaceConflictsOnBioseqSet ((BioseqSetPtr) sep->data.ptrvalue, epfp);
11830 }
11831 sep = sep->next;
11832 epfp->found_one_pub = found_above;
11833 }
11834
11835 }
11836
MakeNewSubmitterBlock(PubdescPtr old_pdp,PubdescPtr repl_pdp)11837 static PubdescPtr MakeNewSubmitterBlock (PubdescPtr old_pdp, PubdescPtr repl_pdp)
11838 {
11839 PubPtr pub;
11840 CitSubPtr csp = NULL;
11841 DatePtr sub_date;
11842 PubdescPtr new_pdp;
11843
11844 if (old_pdp == NULL || repl_pdp == NULL || !PubdescIsSubmitterBlock (repl_pdp))
11845 {
11846 return NULL;
11847 }
11848 for (pub = old_pdp->pub; pub != NULL && csp == NULL; pub = pub->next)
11849 {
11850 if (pub->choice == PUB_Sub)
11851 {
11852 csp = (CitSubPtr) pub->data.ptrvalue;
11853 }
11854 }
11855 if (csp == NULL) return NULL;
11856 sub_date = csp->date;
11857
11858 new_pdp = AsnIoMemCopy ((Pointer) repl_pdp,
11859 (AsnReadFunc) PubdescAsnRead,
11860 (AsnWriteFunc) PubdescAsnWrite);
11861
11862 for (pub = new_pdp->pub; pub != NULL; pub = pub->next)
11863 {
11864 if (pub->choice == PUB_Sub)
11865 {
11866 csp = (CitSubPtr) pub->data.ptrvalue;
11867 csp->date = DateFree (csp->date);
11868 csp->date = AsnIoMemCopy ((Pointer)sub_date,
11869 (AsnReadFunc) DateAsnRead,
11870 (AsnWriteFunc) DateAsnWrite);
11871 }
11872 }
11873 return new_pdp;
11874 }
11875
ReplacePubFeature(SeqFeatPtr sfp,Pointer userdata)11876 static void ReplacePubFeature (SeqFeatPtr sfp, Pointer userdata)
11877 {
11878 EditPubFormPtr epfp;
11879 PubPtr pub;
11880 PubdescPtr pdp, new_pdp;
11881 Boolean this_pub_matches = FALSE;
11882 Boolean this_pub_is_submitter_block = FALSE;
11883 Boolean replace_pub_is_submitter_block = FALSE;
11884
11885
11886 if (sfp == NULL || sfp->data.choice != SEQFEAT_PUB || userdata == NULL)
11887 {
11888 return;
11889 }
11890 epfp = (EditPubFormPtr) userdata;
11891
11892 pdp = sfp->data.value.ptrvalue;
11893
11894 this_pub_is_submitter_block = PubdescIsSubmitterBlock (pdp);
11895 replace_pub_is_submitter_block = PubdescIsSubmitterBlock (epfp->replacement_pdp);
11896 if ((this_pub_is_submitter_block && ! replace_pub_is_submitter_block)
11897 || (!this_pub_is_submitter_block && replace_pub_is_submitter_block))
11898 {
11899 return;
11900 }
11901
11902 for (pub = pdp->pub; pub != NULL && ! this_pub_matches; pub = pub->next)
11903 {
11904 this_pub_matches = DoesPubMatchConstraint (pub, epfp->pcp);
11905 }
11906
11907 if (this_pub_matches)
11908 {
11909 if (this_pub_is_submitter_block)
11910 {
11911 new_pdp = MakeNewSubmitterBlock (pdp, epfp->replacement_pdp);
11912 }
11913 else
11914 {
11915 new_pdp = AsnIoMemCopy ((Pointer) epfp->replacement_pdp,
11916 (AsnReadFunc) PubdescAsnRead,
11917 (AsnWriteFunc) PubdescAsnWrite);
11918 }
11919
11920 pdp = PubdescFree (pdp);
11921 sfp->data.value.ptrvalue = new_pdp;
11922 }
11923 }
11924
ReplacePubDescriptor(SeqDescrPtr sdp,Pointer userdata)11925 static void ReplacePubDescriptor (SeqDescrPtr sdp, Pointer userdata)
11926 {
11927 EditPubFormPtr epfp;
11928 PubPtr pub;
11929 PubdescPtr pdp, new_pdp;
11930 Boolean this_pub_matches = FALSE;
11931 Boolean this_pub_is_submitter_block = FALSE;
11932 Boolean replace_pub_is_submitter_block = FALSE;
11933
11934 if (sdp == NULL || userdata == NULL || sdp->choice != Seq_descr_pub)
11935 {
11936 return;
11937 }
11938 epfp = (EditPubFormPtr) userdata;
11939
11940 pdp = sdp->data.ptrvalue;
11941
11942 this_pub_is_submitter_block = PubdescIsSubmitterBlock (pdp);
11943 replace_pub_is_submitter_block = PubdescIsSubmitterBlock (epfp->replacement_pdp);
11944 if ((this_pub_is_submitter_block && ! replace_pub_is_submitter_block)
11945 || (!this_pub_is_submitter_block && replace_pub_is_submitter_block))
11946 {
11947 return;
11948 }
11949
11950 for (pub = pdp->pub; pub != NULL && ! this_pub_matches; pub = pub->next)
11951 {
11952 this_pub_matches = DoesPubMatchConstraint (pub, epfp->pcp);
11953 }
11954
11955 if (this_pub_matches)
11956 {
11957 if (this_pub_is_submitter_block)
11958 {
11959 new_pdp = MakeNewSubmitterBlock (pdp, epfp->replacement_pdp);
11960 }
11961 else
11962 {
11963 new_pdp = AsnIoMemCopy ((Pointer) epfp->replacement_pdp,
11964 (AsnReadFunc) PubdescAsnRead,
11965 (AsnWriteFunc) PubdescAsnWrite);
11966 }
11967
11968 pdp = PubdescFree (pdp);
11969 sdp->data.ptrvalue = new_pdp;
11970 }
11971 }
11972
ReplacePubsWithSelectedPubsByConstraint(SeqEntryPtr sep,EditPubFormPtr epfp)11973 static Boolean ReplacePubsWithSelectedPubsByConstraint (SeqEntryPtr sep, EditPubFormPtr epfp)
11974 {
11975 MsgAnswer ans = ANS_YES;
11976 Boolean rval = FALSE;
11977 PubdescPtr pdp;
11978
11979 if (sep == NULL || epfp == NULL) return FALSE;
11980
11981 pdp = FindFirstSelectedPub ();
11982 if (pdp == NULL)
11983 {
11984 Message (MSG_ERROR, "No publication selected!");
11985 return FALSE;
11986 }
11987 epfp->replacement_pdp = AsnIoMemCopy ((Pointer) pdp,
11988 (AsnReadFunc) PubdescAsnRead,
11989 (AsnWriteFunc) PubdescAsnWrite);
11990
11991 epfp->found_one_pub = FALSE;
11992 epfp->found_conflict = FALSE;
11993 FindPubReplaceConflictsInSeqEntry (sep, epfp);
11994 if (epfp->found_conflict)
11995 {
11996 ans = Message (MSG_YN, "You will be replacing more than one publication "
11997 "per sequence - is this OK? (Select No to go back and edit constraints)");
11998 }
11999 else if (!epfp->found_any_pubs)
12000 {
12001 Message (MSG_ERROR, "There are no publications matching your constraint.");
12002 ans = ANS_NO;
12003 }
12004 if (ans == ANS_YES)
12005 {
12006 rval = TRUE;
12007 VisitFeaturesInSep (sep, epfp, ReplacePubFeature);
12008 VisitDescriptorsInSep (sep, epfp, ReplacePubDescriptor);
12009 }
12010
12011 epfp->replacement_pdp = PubdescFree (epfp->replacement_pdp);
12012 return rval;
12013 }
12014
12015
12016 typedef Int4 (LIBCALLBACK *GetItemTextLength) (Pointer userdata);
12017
12018 typedef void (LIBCALLBACK *PrintItemToBuffer) (CharPtr cp, Pointer userdata);
12019
12020 typedef struct doublelist
12021 {
12022 DIALOG_MESSAGE_BLOCK
12023 DoC list1_ctrl;
12024 DoC list2_ctrl;
12025 ButtoN to_button;
12026 ButtoN from_button;
12027 ButtoN to_all_button;
12028 ButtoN from_all_button;
12029 ValNodePtr list1;
12030 ValNodePtr list2;
12031 BoolPtr list1_clicked;
12032 BoolPtr list2_clicked;
12033 Int4 num_total;
12034 GetItemTextLength getlenproc;
12035 PrintItemToBuffer printitemproc;
12036 ColData col;
12037 ParData par;
12038 Nlm_ChangeNotifyProc change_notify;
12039 Pointer change_userdata;
12040 } DoubleListData, PNTR DoubleListPtr;
12041
AllLinePrtProc(DoC d,Int2 item,Pointer ptr)12042 static CharPtr AllLinePrtProc (DoC d, Int2 item, Pointer ptr)
12043
12044 {
12045 CharPtr tmp;
12046
12047 if (ptr != NULL) {
12048 tmp = (CharPtr) ptr;
12049 return StringSave (tmp);
12050 } else {
12051 return NULL;
12052 }
12053 }
12054
GetDoubleListTextList(ValNodePtr item_list,DoubleListPtr dlp)12055 static CharPtr GetDoubleListTextList (ValNodePtr item_list, DoubleListPtr dlp)
12056 {
12057 Int4 text_len = 0;
12058 ValNodePtr vnp;
12059 CharPtr text_list, cp;
12060
12061 if (dlp == NULL || dlp->getlenproc == NULL || dlp->printitemproc == NULL)
12062 {
12063 return NULL;
12064 }
12065 for (vnp = item_list; vnp != NULL; vnp = vnp->next)
12066 {
12067 text_len += dlp->getlenproc (vnp->data.ptrvalue);
12068 }
12069 if (text_len == 0) return NULL;
12070 text_list = (CharPtr) MemNew (text_len * sizeof (Char));
12071 if (text_list == NULL) return NULL;
12072 cp = text_list;
12073 for (vnp = item_list; vnp != NULL; vnp = vnp->next)
12074 {
12075 dlp->printitemproc (cp, vnp->data.ptrvalue);
12076 cp += StringLen (cp);
12077 }
12078 return text_list;
12079 }
12080
ClickList1(DoC d,PoinT pt)12081 static void ClickList1 (DoC d, PoinT pt)
12082
12083 {
12084 DoubleListPtr dlp;
12085 Int2 item;
12086 Int2 row;
12087
12088 dlp = (DoubleListPtr) GetObjectExtra (d);
12089 if (dlp != NULL) {
12090 MapDocPoint (d, pt, &item, &row, NULL, NULL);
12091 if (item > 0 && row > 0) {
12092 dlp->list1_clicked [row - 1] = ! dlp->list1_clicked [row - 1];
12093 InvalDocRows (d, 1, row, row);
12094 }
12095 }
12096 }
12097
ClickList2(DoC d,PoinT pt)12098 static void ClickList2 (DoC d, PoinT pt)
12099
12100 {
12101 DoubleListPtr dlp;
12102 Int2 item;
12103 Int2 row;
12104
12105 dlp = (DoubleListPtr) GetObjectExtra (d);
12106 if (dlp != NULL) {
12107 MapDocPoint (d, pt, &item, &row, NULL, NULL);
12108 if (item > 0 && row > 0) {
12109 dlp->list2_clicked [row - 1] = ! dlp->list2_clicked [row - 1];
12110 InvalDocRows (d, 1, row, row);
12111 }
12112 }
12113 }
12114
12115
ReleaseDoubleListItem(DoC d,PoinT pt)12116 static void ReleaseDoubleListItem (DoC d, PoinT pt)
12117
12118 {
12119 DoubleListPtr dlp;
12120 Int2 item;
12121 Int2 row;
12122
12123 dlp = (DoubleListPtr) GetObjectExtra (d);
12124 if (dlp != NULL) {
12125 MapDocPoint (d, pt, &item, &row, NULL, NULL);
12126 if (item > 0 && row > 0) {
12127 ResetClip ();
12128 }
12129 }
12130 }
12131
HighlightList1(DoC d,Int2 item,Int2 row,Int2 col)12132 static Boolean HighlightList1 (DoC d, Int2 item, Int2 row, Int2 col)
12133
12134 {
12135 DoubleListPtr dlp;
12136
12137 dlp = (DoubleListPtr) GetObjectExtra (d);
12138 if (dlp != NULL) {
12139 return dlp->list1_clicked [row - 1];
12140 } else {
12141 return FALSE;
12142 }
12143 }
12144
HighlightList2(DoC d,Int2 item,Int2 row,Int2 col)12145 static Boolean HighlightList2 (DoC d, Int2 item, Int2 row, Int2 col)
12146
12147 {
12148 DoubleListPtr dlp;
12149
12150 dlp = (DoubleListPtr) GetObjectExtra (d);
12151 if (dlp != NULL) {
12152 return dlp->list2_clicked [row - 1];
12153 } else {
12154 return FALSE;
12155 }
12156 }
12157
RedrawDoubleListDialog(DoubleListPtr dlp)12158 static void RedrawDoubleListDialog (DoubleListPtr dlp)
12159 {
12160 CharPtr new_text;
12161 Int4 idx;
12162 RecT r;
12163 BaR sb;
12164 Int4 orig_pos, barmax;
12165
12166 if (dlp == NULL) return;
12167
12168 sb = GetSlateVScrollBar ((SlatE) dlp->list1_ctrl);
12169 orig_pos = GetBarValue (sb);
12170
12171 Reset(dlp->list1_ctrl);
12172 SetDocAutoAdjust (dlp->list1_ctrl, FALSE);
12173 new_text = GetDoubleListTextList (dlp->list1, dlp);
12174 AppendItem (dlp->list1_ctrl, AllLinePrtProc, new_text, FALSE, ValNodeLen (dlp->list1),
12175 &(dlp->par), &(dlp->col), programFont);
12176 SetDocAutoAdjust (dlp->list1_ctrl, TRUE);
12177 SetDocProcs (dlp->list1_ctrl, ClickList1, NULL, ReleaseDoubleListItem, NULL);
12178 SetDocShade (dlp->list1_ctrl, NULL, NULL, HighlightList1, NULL);
12179 AdjustDocScroll (dlp->list1_ctrl);
12180
12181 barmax = GetBarMax (sb);
12182 if (barmax < orig_pos)
12183 {
12184 orig_pos = barmax;
12185 }
12186 SetBarValue (sb, orig_pos);
12187
12188 sb = GetSlateVScrollBar ((SlatE) dlp->list2_ctrl);
12189 orig_pos = GetBarValue (sb);
12190 Reset(dlp->list2_ctrl);
12191 SetDocAutoAdjust (dlp->list2_ctrl, FALSE);
12192 new_text = GetDoubleListTextList (dlp->list2, dlp);
12193 AppendItem (dlp->list2_ctrl, AllLinePrtProc, new_text, FALSE, ValNodeLen (dlp->list2),
12194 &(dlp->par), &(dlp->col), programFont);
12195 SetDocAutoAdjust (dlp->list2_ctrl, TRUE);
12196 SetDocProcs (dlp->list2_ctrl, ClickList2, NULL, ReleaseDoubleListItem, NULL);
12197 SetDocShade (dlp->list2_ctrl, NULL, NULL, HighlightList2, NULL);
12198
12199 AdjustDocScroll (dlp->list2_ctrl);
12200 barmax = GetBarMax (sb);
12201 if (barmax < orig_pos)
12202 {
12203 orig_pos = barmax;
12204 }
12205 SetBarValue (sb, orig_pos);
12206
12207 ObjectRect (dlp->list1_ctrl, &r);
12208 InsetRect (&r, -1, -1);
12209 InvalRect (&r);
12210 ObjectRect (dlp->list2_ctrl, &r);
12211 InsetRect (&r, -1, -1);
12212 InvalRect (&r);
12213
12214
12215 /* clear selections for both lists */
12216 for (idx = 0; idx < dlp->num_total; idx++)
12217 {
12218 dlp->list1_clicked [idx] = FALSE;
12219 dlp->list2_clicked [idx] = FALSE;
12220 }
12221 }
12222
MoveToList2(ButtoN b)12223 static void MoveToList2 (ButtoN b)
12224 {
12225 DoubleListPtr dlp;
12226 ValNodePtr vnp, prev = NULL, vnp_next;
12227 Int4 idx;
12228
12229 dlp = (DoubleListPtr) GetObjectExtra (b);
12230 if (dlp != NULL)
12231 {
12232 for (vnp = dlp->list1, idx = 0;
12233 vnp != NULL && idx < dlp->num_total;
12234 vnp = vnp_next, idx++)
12235 {
12236 vnp_next = vnp->next;
12237 if (dlp->list1_clicked [idx])
12238 {
12239 /* add item to list2 */
12240 ValNodeAddPointer (&dlp->list2, vnp->choice, vnp->data.ptrvalue);
12241
12242 /* remove item from list1 */
12243 vnp->data.ptrvalue = NULL;
12244 if (prev == NULL)
12245 {
12246 dlp->list1 = vnp->next;
12247 }
12248 else
12249 {
12250 prev->next = vnp->next;
12251 }
12252 vnp->next = NULL;
12253 ValNodeFree (vnp);
12254
12255 }
12256 else
12257 {
12258 prev = vnp;
12259 }
12260 }
12261 /* redraw contents of docpanels */
12262 RedrawDoubleListDialog (dlp);
12263 if (dlp->change_notify != NULL)
12264 {
12265 (dlp->change_notify) (dlp->change_userdata);
12266 }
12267 }
12268 }
12269
MoveToList1(ButtoN b)12270 static void MoveToList1 (ButtoN b)
12271 {
12272 DoubleListPtr dlp;
12273 ValNodePtr vnp, prev = NULL, vnp_next;
12274 Int4 idx;
12275
12276 dlp = (DoubleListPtr) GetObjectExtra (b);
12277 if (dlp != NULL)
12278 {
12279 for (vnp = dlp->list2, idx = 0;
12280 vnp != NULL && idx < dlp->num_total;
12281 vnp = vnp_next, idx++)
12282 {
12283 vnp_next = vnp->next;
12284 if (dlp->list2_clicked [idx])
12285 {
12286 /* add item to list2 */
12287 ValNodeAddPointer (&dlp->list1, vnp->choice, vnp->data.ptrvalue);
12288
12289 /* remove item from list1 */
12290 vnp->data.ptrvalue = NULL;
12291 if (prev == NULL)
12292 {
12293 dlp->list2 = vnp->next;
12294 }
12295 else
12296 {
12297 prev->next = vnp->next;
12298 }
12299 vnp->next = NULL;
12300 ValNodeFree (vnp);
12301
12302 }
12303 else
12304 {
12305 prev = vnp;
12306 }
12307 }
12308 /* redraw contents of docpanels */
12309 RedrawDoubleListDialog (dlp);
12310
12311 if (dlp->change_notify != NULL)
12312 {
12313 (dlp->change_notify) (dlp->change_userdata);
12314 }
12315 }
12316 }
12317
MoveAllToList2(ButtoN b)12318 static void MoveAllToList2 (ButtoN b)
12319 {
12320 DoubleListPtr dlp;
12321
12322 dlp = (DoubleListPtr) GetObjectExtra (b);
12323 if (dlp == NULL)
12324 {
12325 return;
12326 }
12327
12328 ValNodeLink (&(dlp->list2), dlp->list1);
12329 dlp->list1 = NULL;
12330
12331 /* redraw contents of docpanels */
12332 RedrawDoubleListDialog (dlp);
12333 if (dlp->change_notify != NULL)
12334 {
12335 (dlp->change_notify) (dlp->change_userdata);
12336 }
12337 }
12338
MoveAllToList1(ButtoN b)12339 static void MoveAllToList1 (ButtoN b)
12340 {
12341 DoubleListPtr dlp;
12342
12343 dlp = (DoubleListPtr) GetObjectExtra (b);
12344 if (dlp == NULL)
12345 {
12346 return;
12347 }
12348
12349 ValNodeLink (&(dlp->list1), dlp->list2);
12350 dlp->list2 = NULL;
12351
12352 /* redraw contents of docpanels */
12353 RedrawDoubleListDialog (dlp);
12354 if (dlp->change_notify != NULL)
12355 {
12356 (dlp->change_notify) (dlp->change_userdata);
12357 }
12358 }
12359
ListPairToDoubleListDialog(DialoG d,Pointer data)12360 static void ListPairToDoubleListDialog (DialoG d, Pointer data)
12361 {
12362 DoubleListPtr dlp;
12363 ValNodePtr list_pair;
12364
12365
12366 dlp = (DoubleListPtr) GetObjectExtra (d);
12367 if (dlp == NULL)
12368 {
12369 return;
12370 }
12371 Reset(dlp->list1_ctrl);
12372 Reset(dlp->list2_ctrl);
12373 dlp->list1 = NULL;
12374 dlp->list2 = NULL;
12375
12376 list_pair = (ValNodePtr) data;
12377 if (list_pair != NULL)
12378 {
12379 dlp->list1 = list_pair->data.ptrvalue;
12380 if (list_pair->next != NULL)
12381 {
12382 dlp->list2 = list_pair->next->data.ptrvalue;
12383 }
12384 }
12385
12386 /* set up clicked lists */
12387 dlp->list1_clicked = MemFree (dlp->list1_clicked);
12388 dlp->list2_clicked = MemFree (dlp->list2_clicked);
12389 dlp->num_total = ValNodeLen (dlp->list1) + ValNodeLen (dlp->list2);
12390 dlp->list1_clicked = (BoolPtr) MemNew (dlp->num_total * sizeof (Boolean));
12391 dlp->list2_clicked = (BoolPtr) MemNew (dlp->num_total * sizeof (Boolean));
12392
12393
12394
12395 RedrawDoubleListDialog (dlp);
12396 if (dlp->change_notify != NULL)
12397 {
12398 (dlp->change_notify) (dlp->change_userdata);
12399 }
12400 }
12401
DoubleListDialogToListPair(DialoG d)12402 static Pointer DoubleListDialogToListPair (DialoG d)
12403 {
12404 DoubleListPtr dlp;
12405 ValNodePtr list_pair = NULL;
12406 ValNodePtr vnp, list_tmp = NULL;
12407
12408 dlp = (DoubleListPtr) GetObjectExtra (d);
12409 if (dlp == NULL)
12410 {
12411 return NULL;
12412 }
12413
12414 list_tmp = NULL;
12415 for (vnp = dlp->list1; vnp != NULL; vnp = vnp->next) {
12416 ValNodeAddPointer (&list_tmp, vnp->choice, vnp->data.ptrvalue);
12417 }
12418 ValNodeAddPointer (&list_pair, 0, list_tmp);
12419
12420 list_tmp = NULL;
12421 for (vnp = dlp->list2; vnp != NULL; vnp = vnp->next) {
12422 ValNodeAddPointer (&list_tmp, vnp->choice, vnp->data.ptrvalue);
12423 }
12424 ValNodeAddPointer (&list_pair, 0, list_tmp);
12425 return list_pair;
12426 }
12427
CleanupDoubleListDialog(GraphiC g,VoidPtr data)12428 static void CleanupDoubleListDialog (GraphiC g, VoidPtr data)
12429 {
12430 DoubleListPtr dlp;
12431
12432 dlp = (DoubleListPtr) data;
12433 if (dlp != NULL)
12434 {
12435 dlp->list1 = ValNodeFree (dlp->list1);
12436 dlp->list2 = ValNodeFree (dlp->list2);
12437 }
12438 StdCleanupExtraProc (g, data);
12439 }
12440
12441
12442 static DialoG
DoubleListDialog(GrouP parent,CharPtr list1_title,CharPtr list2_title,GetItemTextLength getlenproc,PrintItemToBuffer printitemproc,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)12443 DoubleListDialog
12444 (GrouP parent,
12445 CharPtr list1_title,
12446 CharPtr list2_title,
12447 GetItemTextLength getlenproc,
12448 PrintItemToBuffer printitemproc,
12449 Nlm_ChangeNotifyProc change_notify,
12450 Pointer change_userdata)
12451 {
12452 DoubleListPtr dlp;
12453 GrouP p, k;
12454 RecT r;
12455 Int2 height = LineHeight ();
12456
12457 dlp = (DoubleListPtr) MemNew (sizeof (DoubleListData));
12458 if (dlp == NULL)
12459 {
12460 return NULL;
12461 }
12462
12463 dlp->getlenproc = getlenproc;
12464 dlp->printitemproc = printitemproc;
12465 dlp->change_notify = change_notify;
12466 dlp->change_userdata = change_userdata;
12467
12468 p = HiddenGroup (parent, 3, 0, NULL);
12469 SetGroupSpacing (p, 10, 10);
12470 SetObjectExtra (p, dlp, CleanupDoubleListDialog);
12471
12472 dlp->dialog = (DialoG) p;
12473 dlp->todialog = ListPairToDoubleListDialog;
12474 dlp->fromdialog = DoubleListDialogToListPair;
12475
12476 /* top row - labels */
12477 StaticPrompt (p, list1_title, 0, dialogTextHeight, programFont, 'c');
12478 StaticPrompt (p, "", 0, dialogTextHeight, programFont, 'c');
12479 StaticPrompt (p, list2_title, 0, dialogTextHeight, programFont, 'c');
12480 /* panel 1 */
12481 dlp->list1_ctrl = DocumentPanel (p, stdCharWidth * 25, height * 7);
12482 SetObjectExtra (dlp->list1_ctrl, dlp, NULL);
12483 /* movement buttons */
12484 k = HiddenGroup (p, 0, 4, NULL);
12485 dlp->to_button = PushButton (k, "->", MoveToList2);
12486 SetObjectExtra (dlp->to_button, dlp, NULL);
12487 dlp->to_all_button = PushButton (k, "All->", MoveAllToList2);
12488 SetObjectExtra (dlp->to_all_button, dlp, NULL);
12489
12490 dlp->from_button = PushButton (k, "<-", MoveToList1);
12491 SetObjectExtra (dlp->from_button, dlp, NULL);
12492 dlp->from_all_button = PushButton (k, "<-All", MoveAllToList1);
12493 SetObjectExtra (dlp->from_all_button, dlp, NULL);
12494 /* panel 2 */
12495 dlp->list2_ctrl = DocumentPanel (p, stdCharWidth * 25, height * 7);
12496 SetObjectExtra (dlp->list2_ctrl, dlp, NULL);
12497
12498 ObjectRect (dlp->list1_ctrl, &r);
12499 dlp->col.pixWidth = r.right - r.left;
12500 dlp->col.pixInset = 0;
12501 dlp->col.charWidth = 80;
12502 dlp->col.charInset = 0;
12503 dlp->col.font = NULL;
12504 dlp->col.just = 'l';
12505 dlp->col.wrap = FALSE;
12506 dlp->col.bar = FALSE;
12507 dlp->col.underline = FALSE;
12508 dlp->col.left = FALSE;
12509 dlp->col.last = TRUE;
12510
12511 dlp->par.openSpace = FALSE;
12512 dlp->par.keepWithNext = FALSE;
12513 dlp->par.keepTogether = FALSE;
12514 dlp->par.newPage = FALSE;
12515 dlp->par.tabStops = FALSE;
12516 dlp->par.minLines = 0;
12517 dlp->par.minHeight = 0;
12518
12519 return (DialoG) p;
12520 }
12521
12522 typedef struct adjustlistpair
12523 {
12524 DialoG list_pair_dlg;
12525 ButtoN accept_btn;
12526 Boolean none_in_1_ok;
12527 Boolean none_in_2_ok;
12528 } AdjustListPairData, PNTR AdjustListPairPtr;
12529
EnableAdjustListPairAccept(Pointer data)12530 static void EnableAdjustListPairAccept (Pointer data)
12531 {
12532 AdjustListPairPtr alpp;
12533 ValNodePtr list_pair, vnp;
12534
12535 alpp = (AdjustListPairPtr) data;
12536 if (alpp == NULL)
12537 {
12538 return;
12539 }
12540 if (alpp->none_in_1_ok && alpp->none_in_2_ok)
12541 {
12542 Enable (alpp->accept_btn);
12543 return;
12544 }
12545
12546 list_pair = DialogToPointer (alpp->list_pair_dlg);
12547 if (list_pair == NULL
12548 || (!alpp->none_in_1_ok && list_pair->data.ptrvalue == NULL)
12549 || (!alpp->none_in_2_ok
12550 && (list_pair->next == NULL
12551 || list_pair->next->data.ptrvalue == NULL)))
12552 {
12553 Disable (alpp->accept_btn);
12554 }
12555 else
12556 {
12557 Enable (alpp->accept_btn);
12558 }
12559 for (vnp = list_pair; vnp != NULL; vnp = vnp->next) {
12560 vnp->data.ptrvalue = ValNodeFree (vnp->data.ptrvalue);
12561 }
12562 list_pair = ValNodeFree (list_pair);
12563 }
12564
12565 static Boolean
AdjustListPair(ValNodePtr PNTR list1,ValNodePtr PNTR list2,CharPtr list1_title,CharPtr list2_title,GetItemTextLength getlenproc,PrintItemToBuffer printitemproc,Boolean none_in_1_ok,Boolean none_in_2_ok)12566 AdjustListPair
12567 (ValNodePtr PNTR list1,
12568 ValNodePtr PNTR list2,
12569 CharPtr list1_title,
12570 CharPtr list2_title,
12571 GetItemTextLength getlenproc,
12572 PrintItemToBuffer printitemproc,
12573 Boolean none_in_1_ok,
12574 Boolean none_in_2_ok)
12575 {
12576 WindoW w;
12577 GrouP h, c;
12578 ButtoN b;
12579 ModalAcceptCancelData acd;
12580 AdjustListPairData alpd;
12581 ValNodePtr list_pair = NULL;
12582 Boolean rval = FALSE;
12583
12584 if (list1 == NULL || list2 == NULL) return FALSE;
12585
12586 w = ModalWindow (-50, -33, -10, -10, NULL);
12587 h = HiddenGroup (w, -1, 0, NULL);
12588 SetGroupSpacing (h, 10, 10);
12589
12590 alpd.none_in_1_ok = none_in_1_ok;
12591 alpd.none_in_2_ok = none_in_2_ok;
12592
12593 alpd.list_pair_dlg = DoubleListDialog (h, list1_title, list2_title,
12594 getlenproc, printitemproc,
12595 EnableAdjustListPairAccept,
12596 &alpd);
12597
12598 c = HiddenGroup (h, 4, 0, NULL);
12599 alpd.accept_btn = PushButton (c, "Accept", ModalAcceptButton);
12600 SetObjectExtra (alpd.accept_btn, &acd, NULL);
12601 b = PushButton (c, "Cancel", ModalCancelButton);
12602 SetObjectExtra (b, &acd, NULL);
12603
12604 AlignObjects (ALIGN_CENTER, (HANDLE) alpd.list_pair_dlg, (HANDLE) c, NULL);
12605
12606 acd.accepted = FALSE;
12607 acd.cancelled = FALSE;
12608
12609 ValNodeAddPointer (&list_pair, 0, *list1);
12610 ValNodeAddPointer (&list_pair, 0, *list2);
12611 *list1 = NULL;
12612 *list2 = NULL;
12613 PointerToDialog (alpd.list_pair_dlg, list_pair);
12614 list_pair = ValNodeFree (list_pair);
12615
12616 RealizeWindow (w);
12617 Show (w);
12618 Update ();
12619
12620 while (!acd.accepted && ! acd.cancelled)
12621 {
12622 ProcessExternalEvent ();
12623 Update ();
12624 }
12625 ProcessAnEvent ();
12626 if (acd.accepted)
12627 {
12628 list_pair = DialogToPointer (alpd.list_pair_dlg);
12629 if (list_pair != NULL && list_pair->next != NULL)
12630 {
12631 *list1 = list_pair->data.ptrvalue;
12632 *list2 = list_pair->next->data.ptrvalue;
12633 rval = TRUE;
12634 }
12635 list_pair = ValNodeFree (list_pair);
12636 }
12637 Remove (w);
12638 return rval;
12639 }
12640
GetAuthorPrintLen(Pointer userdata)12641 static Int4 LIBCALLBACK GetAuthorPrintLen (Pointer userdata)
12642 {
12643 Int4 text_len = 0;
12644 NameStdPtr pName;
12645 AuthorPtr ap;
12646
12647 ap = (AuthorPtr) userdata;
12648 if (ap == NULL || ap->name == NULL || ap->name->data == NULL) return 0;
12649
12650 if (ap->name->choice == 2)
12651 {
12652 pName = (NameStdPtr) ap->name->data;
12653 if (!StringHasNoText (pName->names[0]))
12654 {
12655 text_len += StringLen (pName->names [0]) + 3;
12656 }
12657 if (!StringHasNoText (pName->names[4]))
12658 {
12659 text_len += StringLen (pName->names[4]) + 2;
12660 }
12661 }
12662 else if (ap->name->choice == 4 || ap->name->choice == 5)
12663 {
12664 text_len = StringLen (ap->name->data) + 2;
12665 }
12666 return text_len;
12667 }
12668
PrintAuthor(CharPtr cp,Pointer userdata)12669 static void LIBCALLBACK PrintAuthor (CharPtr cp, Pointer userdata)
12670 {
12671 NameStdPtr pName;
12672 AuthorPtr ap;
12673
12674 ap = (AuthorPtr) userdata;
12675 if (ap == NULL || ap->name == NULL || ap->name->data == NULL || cp == NULL) return;
12676
12677 if (ap->name->choice == 2)
12678 {
12679 pName = (NameStdPtr) ap->name->data;
12680 if (!StringHasNoText (pName->names[0]))
12681 {
12682 StringCat (cp, pName->names[0]);
12683 if (!StringHasNoText (pName->names[4]))
12684 {
12685 StringCat (cp, ", ");
12686 }
12687 }
12688 if (!StringHasNoText (pName->names[4]))
12689 {
12690 StringCat (cp, pName->names[4]);
12691 }
12692 }
12693 else if (ap->name->choice == 4 || ap->name->choice == 5)
12694 {
12695 StringCat (cp, ap->name->data);
12696 }
12697 StringCat (cp, "\n");
12698 }
12699
12700 #define PUB_EDIT_TYPE_REPLACE_SECTION 1
12701 #define PUB_EDIT_TYPE_REPLACE_PUB 2
12702 #define PUB_EDIT_TYPE_REPLACE_SINGLE_FIELD 3
12703 #define PUB_EDIT_TYPE_MERGE_AUTHOR_LISTS 4
12704 #define MAX_PUB_EDIT_TYPE 4
12705
ChangeAuthorOrder(EditPubFormPtr epfp)12706 static Boolean ChangeAuthorOrder (EditPubFormPtr epfp)
12707 {
12708 ValNodePtr list1 = NULL, list2 = NULL, tmp_list = NULL, vnp;
12709 AuthorPtr ap;
12710 Boolean rval;
12711
12712 if (epfp == NULL || epfp->edit_type != PUB_EDIT_TYPE_MERGE_AUTHOR_LISTS)
12713 {
12714 return FALSE;
12715 }
12716
12717 if (epfp->names_list == NULL || epfp->names_list->next == NULL)
12718 {
12719 return TRUE;
12720 }
12721
12722 /* create temporary copy of list */
12723 for (vnp = epfp->names_list; vnp != NULL; vnp = vnp->next)
12724 {
12725 ap = AsnIoMemCopy (vnp->data.ptrvalue,
12726 (AsnReadFunc) AuthorAsnRead,
12727 (AsnWriteFunc) AuthorAsnWrite);
12728 if (ap != NULL)
12729 {
12730 ValNodeAddPointer (&(list1), vnp->choice, ap);
12731 }
12732 }
12733
12734 rval = AdjustListPair (&list1, &list2, "Available Authors", "Final List",
12735 GetAuthorPrintLen, PrintAuthor, TRUE, FALSE);
12736 if (rval)
12737 {
12738 /* now change author order */
12739 tmp_list = epfp->names_list;
12740 epfp->names_list = list2;
12741 list2 = tmp_list;
12742 }
12743
12744 /* free lists */
12745 for (vnp = list1; vnp != NULL; vnp = vnp->next)
12746 {
12747 vnp->data.ptrvalue = AuthorFree (vnp->data.ptrvalue);
12748 }
12749 list1 = ValNodeFree (list1);
12750 for (vnp = list2; vnp != NULL; vnp = vnp->next)
12751 {
12752 vnp->data.ptrvalue = AuthorFree (vnp->data.ptrvalue);
12753 }
12754 list2 = ValNodeFree (list2);
12755
12756 return rval;
12757 }
12758
UpdateFeatureCitations(SeqFeatPtr sfp,Pointer userdata)12759 static void UpdateFeatureCitations (SeqFeatPtr sfp, Pointer userdata)
12760 {
12761 AffectedPubPairPtr appp;
12762 ValNodePtr cit_vnp, prev_cit, next_cit, pub_vnp, pub_list;
12763 ValNodePtr new_cit;
12764 ValNodePtr pubset;
12765 Boolean found_match;
12766 ValNode vn;
12767
12768 if (sfp == NULL || sfp->cit == NULL
12769 || sfp->cit->choice != 1 || sfp->cit->data.ptrvalue == NULL
12770 || userdata == NULL)
12771 {
12772 return;
12773 }
12774
12775 pubset = sfp->cit;
12776 if (pubset == NULL || pubset->choice != 1)
12777 {
12778 return;
12779 }
12780
12781 pub_list = (ValNodePtr) userdata;
12782
12783 prev_cit = NULL;
12784 vn.next = NULL;
12785 for (cit_vnp = pubset->data.ptrvalue; cit_vnp != NULL; cit_vnp = next_cit)
12786 {
12787 next_cit = cit_vnp->next;
12788 found_match = FALSE;
12789 for (pub_vnp = pub_list;
12790 pub_vnp != NULL && !found_match;
12791 pub_vnp = pub_vnp->next)
12792 {
12793 appp = (AffectedPubPairPtr) pub_vnp->data.ptrvalue;
12794 if (appp == NULL || appp->orig == NULL)
12795 {
12796 continue;
12797 }
12798 vn.choice = PUB_Equiv;
12799 vn.data.ptrvalue = appp->orig->pub;
12800 if (PubLabelMatch (cit_vnp, &vn) == 0)
12801 {
12802 found_match = TRUE;
12803 }
12804 }
12805 if (appp != NULL && found_match)
12806 {
12807 /* create a temporary PUB_Equiv to use for minimizing */
12808 vn.choice = PUB_Equiv;
12809 vn.data.ptrvalue = appp->curr->pub;
12810 new_cit = MinimizePub (&vn);
12811
12812 /* insert new_cit into list */
12813 new_cit->next = cit_vnp->next;
12814 cit_vnp->next = NULL;
12815 cit_vnp = PubFree (cit_vnp);
12816
12817 if (prev_cit == NULL)
12818 {
12819 sfp->cit->data.ptrvalue = new_cit;
12820 }
12821 else
12822 {
12823 prev_cit->next = new_cit;
12824 }
12825 cit_vnp = new_cit;
12826 }
12827 prev_cit = cit_vnp;
12828 }
12829 }
12830
DoEditPubs(ButtoN b)12831 static void DoEditPubs (ButtoN b)
12832 {
12833 SeqEntryPtr sep;
12834 EditPubFormPtr epfp;
12835 PubPtr pub;
12836 AuthListPtr alp;
12837 Int4Ptr retval;
12838
12839 epfp = (EditPubFormPtr) GetObjectExtra (b);
12840 if (epfp == NULL) return;
12841
12842 sep = GetTopSeqEntryForEntityID (epfp->input_entityID);
12843 if (sep == NULL) return;
12844
12845 epfp->pcp = DialogToPointer (epfp->pub_constraint_dlg);
12846
12847 switch (epfp->edit_type)
12848 {
12849 case PUB_EDIT_TYPE_REPLACE_SINGLE_FIELD:
12850 retval = DialogToPointer (epfp->field_to_set_dlg);
12851 if (retval == NULL)
12852 {
12853 return;
12854 }
12855 else
12856 {
12857 epfp->field_to_set = *retval;
12858 retval = MemFree (retval);
12859 }
12860
12861 epfp->repl_string = SaveStringFromText (epfp->repl_string_txt);
12862 OperateOnPubByConstraint (sep, epfp, EditPubSingleField);
12863 break;
12864
12865 case PUB_EDIT_TYPE_REPLACE_SECTION:
12866 epfp->pdp = FindFirstSelectedPub ();
12867 if (epfp->pdp == NULL)
12868 {
12869 Message (MSG_ERROR, "No selected pub!");
12870 epfp->pcp = PubConstraintFree (epfp->pcp);
12871 return;
12872 }
12873
12874 epfp->alp = AuthListFree (epfp->alp);
12875 if (GetStatus (epfp->replace_author_list))
12876 {
12877 pub = epfp->pdp->pub;
12878 while (epfp->alp == NULL && pub != NULL)
12879 {
12880 epfp->alp = GetAuthorListForPub (pub);
12881 pub = pub->next;
12882 }
12883 /* make a copy, so that if the selected pub matches the contraint, we won't wipe out
12884 * the contents of the master when we free the AuthListPtr for the selected pub
12885 * when we replace it with itself.
12886 */
12887 if (epfp->alp != NULL)
12888 {
12889 epfp->alp = AsnIoMemCopy ((Pointer) epfp->alp,
12890 (AsnReadFunc) AuthListAsnRead,
12891 (AsnWriteFunc) AuthListAsnWrite);
12892 }
12893 }
12894
12895 epfp->title_str = MemFree (epfp->title_str);
12896 if (GetStatus (epfp->replace_title))
12897 {
12898 pub = epfp->pdp->pub;
12899 while (epfp->title_str == NULL && pub != NULL)
12900 {
12901 epfp->title_str = GetPubTitleSample (pub);
12902 pub = pub->next;
12903 }
12904 epfp->title_str = StringSave (epfp->title_str);
12905 }
12906
12907 epfp->affil = AffilFree (epfp->affil);
12908 if (GetStatus (epfp->replace_affiliation))
12909 {
12910 pub = epfp->pdp->pub;
12911 while (epfp->affil == NULL && pub != NULL)
12912 {
12913 alp = GetAuthorListForPub (pub);
12914 if (alp != NULL && alp->affil != NULL)
12915 {
12916 epfp->affil = AsnIoMemCopy ((Pointer) alp->affil,
12917 (AsnReadFunc) AffilAsnRead,
12918 (AsnWriteFunc) AffilAsnWrite);
12919 }
12920 pub = pub->next;
12921 }
12922 }
12923 OperateOnPubByConstraint (sep, epfp, ReplacePubSectByConstraint);
12924
12925 break;
12926
12927 case PUB_EDIT_TYPE_MERGE_AUTHOR_LISTS:
12928 /* clear out any old list */
12929 epfp->names_list = FreeAuthorNameList (epfp->names_list);
12930
12931 /* get the merged list */
12932 OperateOnPubByConstraint (sep, epfp, GetMergedAuthorListByConstraint);
12933
12934 if (GetValue (epfp->specify_author_order) == 2)
12935 {
12936 if (!ChangeAuthorOrder (epfp))
12937 {
12938 /* cancelled - go back to dialog */
12939 epfp->pcp = PubConstraintFree (epfp->pcp);
12940 return;
12941 }
12942 }
12943
12944 /* now set the merged list */
12945 OperateOnPubByConstraint (sep, epfp, SetMergedAuthorListByConstraint);
12946 break;
12947 case PUB_EDIT_TYPE_REPLACE_PUB:
12948 /* replace entire citations */
12949 /* get list of currently selected publications */
12950 /* find publications that meet the constraint and replace them with the selected pubs */
12951 if (! ReplacePubsWithSelectedPubsByConstraint (sep, epfp))
12952 {
12953 epfp->pcp = PubConstraintFree (epfp->pcp);
12954 return;
12955 }
12956 break;
12957 }
12958 epfp->pcp = PubConstraintFree (epfp->pcp);
12959
12960 VisitFeaturesInSep (sep, (epfp->affected_pubs), UpdateFeatureCitations);
12961 epfp->affected_pubs = AffectedPubPairListFree (epfp->affected_pubs);
12962
12963 ObjMgrSetDirtyFlag (epfp->input_entityID, TRUE);
12964 ObjMgrSendMsg (OM_MSG_UPDATE, epfp->input_entityID, 0, 0);
12965 Update ();
12966
12967 if (! GetStatus (epfp->leaveDlgUp))
12968 {
12969 Remove (epfp->form);
12970 }
12971
12972 }
12973
ChangePubEditType(GrouP g)12974 static void ChangePubEditType (GrouP g)
12975 {
12976 EditPubFormPtr epfp;
12977
12978 epfp = (EditPubFormPtr) GetObjectExtra (g);
12979 if (epfp == NULL) return;
12980
12981 epfp->edit_type = GetValue (epfp->edit_type_group);
12982 switch (epfp->edit_type)
12983 {
12984 case PUB_EDIT_TYPE_REPLACE_SINGLE_FIELD:
12985 Show (epfp->single_field_group);
12986 Hide (epfp->replace_sect_group);
12987 Hide (epfp->merge_auth_list_group);
12988 Hide (epfp->replace_pub_group);
12989 break;
12990 case PUB_EDIT_TYPE_REPLACE_SECTION:
12991 Hide (epfp->single_field_group);
12992 Show (epfp->replace_sect_group);
12993 Hide (epfp->merge_auth_list_group);
12994 Hide (epfp->replace_pub_group);
12995 break;
12996 case PUB_EDIT_TYPE_MERGE_AUTHOR_LISTS:
12997 Hide (epfp->single_field_group);
12998 Hide (epfp->replace_sect_group);
12999 Show (epfp->merge_auth_list_group);
13000 Hide (epfp->replace_pub_group);
13001 break;
13002 case PUB_EDIT_TYPE_REPLACE_PUB:
13003 default:
13004 Hide (epfp->single_field_group);
13005 Hide (epfp->replace_sect_group);
13006 Hide (epfp->merge_auth_list_group);
13007 Show (epfp->replace_pub_group);
13008 epfp->edit_type = PUB_EDIT_TYPE_REPLACE_PUB;
13009 SetValue (g, PUB_EDIT_TYPE_REPLACE_PUB);
13010 break;
13011 }
13012 }
13013
LoadValueFromSelectedPub(ButtoN b)13014 static void LoadValueFromSelectedPub (ButtoN b)
13015 {
13016 EditPubFormPtr epfp;
13017 SelStructPtr ssp;
13018 SeqMgrFeatContext fcontext;
13019 SeqMgrDescContext dcontext;
13020 PubdescPtr pdp = NULL;
13021 SeqFeatPtr sfp;
13022 SeqDescPtr sdp;
13023 CharPtr field_val = NULL;
13024 Int4 field_to_set = PUB_FIELD_ANY;
13025 Boolean selected_pub_found = FALSE;
13026 CharPtr cp = NULL;
13027 Int4Ptr retval;
13028
13029 epfp = (EditPubFormPtr) GetObjectExtra (b);
13030 if (epfp == NULL) return;
13031
13032 retval = DialogToPointer (epfp->field_to_set_dlg);
13033 if (retval == NULL)
13034 {
13035 return;
13036 }
13037 field_to_set = *retval;
13038 retval = MemFree (retval);
13039 if (field_to_set == PUB_FIELD_ANY) return;
13040
13041 ssp = ObjMgrGetSelected();
13042
13043 while (NULL != ssp && field_val == NULL)
13044 {
13045 if (ssp->itemtype == OBJ_SEQFEAT)
13046 {
13047 sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &fcontext);
13048 if (sfp != NULL && sfp->data.choice == SEQFEAT_PUB)
13049 {
13050 pdp = sfp->data.value.ptrvalue;
13051 field_val = GetSampleStringFromPub (pdp, field_to_set);
13052 selected_pub_found = TRUE;
13053 }
13054 }
13055 else if (ssp->itemtype == OBJ_SEQDESC)
13056 {
13057 sdp = SeqMgrGetDesiredDescriptor (ssp->entityID, NULL, ssp->itemID, 0, NULL, &dcontext);
13058 if (sdp != NULL && sdp->choice == Seq_descr_pub)
13059 {
13060 pdp = sdp->data.ptrvalue;
13061 field_val = GetSampleStringFromPub (pdp, field_to_set);
13062 selected_pub_found = TRUE;
13063 }
13064 }
13065 ssp = ssp->next;
13066 }
13067
13068 if (!selected_pub_found)
13069 {
13070 Message (MSG_ERROR, "No publication selected - no value loaded!");
13071 }
13072 else
13073 {
13074 if (field_to_set == PUB_FIELD_MIDDLE_INITIAL
13075 && !StringHasNoText (field_val)
13076 && field_val [StringLen (field_val) - 1] == '.')
13077 {
13078 cp = field_val + StringLen (field_val) - 1;
13079 *cp = 0;
13080 }
13081 SetTitle (epfp->repl_string_txt, field_val);
13082 if (cp != NULL)
13083 {
13084 *cp = '.';
13085 }
13086 }
13087 }
13088
CleanupEditPub(GraphiC g,VoidPtr data)13089 static void CleanupEditPub (GraphiC g, VoidPtr data)
13090 {
13091 EditPubFormPtr epfp;
13092
13093 epfp = (EditPubFormPtr) data;
13094 if (epfp != NULL)
13095 {
13096 /* cleanup for single field replace */
13097 epfp->repl_string = MemFree (epfp->repl_string);
13098
13099 /* cleanup for replace section */
13100 epfp->alp = AuthListFree (epfp->alp);
13101 epfp->title_str = MemFree (epfp->title_str);
13102 epfp->affil = AffilFree (epfp->affil);
13103
13104 /* cleanup for author list merge */
13105 epfp->names_list = FreeAuthorNameList (epfp->names_list);
13106
13107 /* cleanup constraint */
13108 epfp->pcp = PubConstraintFree (epfp->pcp);
13109 }
13110 StdCleanupFormProc (g, data);
13111 }
13112
EditPubsEx(BaseFormPtr bfp)13113 extern void EditPubsEx (BaseFormPtr bfp)
13114 {
13115 GrouP h, g, n, m, c;
13116 EditPubFormPtr epfp;
13117 WindoW w;
13118 ButtoN b;
13119 PrompT p2;
13120
13121 if (bfp == NULL) return;
13122
13123 epfp = (EditPubFormPtr) MemNew (sizeof (EditPubFormData));
13124 if (epfp == NULL) return;
13125 epfp->input_entityID = bfp->input_entityID;
13126 epfp->input_itemID = bfp->input_itemID;
13127 epfp->input_itemtype = bfp->input_itemtype;
13128
13129 w = FixedWindow (-50, -33, -10, -10, "Edit Publications", StdCloseWindowProc);
13130 SetObjectExtra (w, epfp, CleanupEditPub);
13131 epfp->form = (ForM) w;
13132
13133 h = HiddenGroup (w, -1, 0, NULL);
13134 SetGroupSpacing (h, 10, 10);
13135
13136 epfp->edit_type_group = NormalGroup (h, 4, 0, "Type of Edit", systemFont, ChangePubEditType);
13137 SetObjectExtra (epfp->edit_type_group, epfp, NULL);
13138 RadioButton (epfp->edit_type_group, "Replace Section");
13139 RadioButton (epfp->edit_type_group, "Replace entire publication");
13140 RadioButton (epfp->edit_type_group, "Replace Single Field");
13141 RadioButton (epfp->edit_type_group, "Merge author lists");
13142 SetValue (epfp->edit_type_group, PUB_EDIT_TYPE_REPLACE_SECTION);
13143
13144 m = HiddenGroup (h, 0, 0, NULL);
13145
13146 epfp->single_field_group = HiddenGroup (m, -1, 0, NULL);
13147 g = HiddenGroup (epfp->single_field_group, 2, 0, NULL);
13148 StaticPrompt (g, "Set text in", 0, dialogTextHeight, programFont, 'c');
13149 epfp->field_to_set_dlg = PubFieldChoiceDialog (g, FALSE);
13150 StaticPrompt (g, "To new value", 0, dialogTextHeight, programFont, 'c');
13151 epfp->repl_string_txt = DialogText (g, "", 15, NULL);
13152 n = HiddenGroup (epfp->single_field_group, 1, 0, NULL);
13153 b = PushButton (n, "Load New Value from Selected Publication", LoadValueFromSelectedPub);
13154 SetObjectExtra (b, epfp, NULL);
13155 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) n, NULL);
13156
13157 epfp->replace_sect_group = HiddenGroup (m, 1, 0, NULL);
13158 epfp->replace_author_list = CheckBox (epfp->replace_sect_group, "Replace Author List with Selected Author List", NULL);
13159 epfp->replace_title = CheckBox (epfp->replace_sect_group, "Replace Title with Selected Title", NULL);
13160 epfp->replace_affiliation = CheckBox (epfp->replace_sect_group, "Replace Affiliation with Selected Affiliation", NULL);
13161
13162 epfp->merge_auth_list_group = HiddenGroup (m, -1, 0, NULL);
13163 epfp->specify_author_order = HiddenGroup (epfp->merge_auth_list_group, 0, 2, NULL);
13164 RadioButton (epfp->specify_author_order, "Automatically set author order");
13165 RadioButton (epfp->specify_author_order, "Manually set author order");
13166 SetValue (epfp->specify_author_order, 1);
13167 p2 = StaticPrompt (epfp->merge_auth_list_group,
13168 "Authors will be selected from publications that match the constraints.",
13169 0, dialogTextHeight, programFont, 'c');
13170 AlignObjects (ALIGN_CENTER, (HANDLE) epfp->specify_author_order,
13171 (HANDLE) p2,
13172 NULL);
13173
13174 epfp->replace_pub_group = HiddenGroup (m, -1, 0, NULL);
13175 StaticPrompt (epfp->replace_pub_group, "Replace with selected publication or submitter block", 0, dialogTextHeight, programFont, 'c');
13176 ChangePubEditType (epfp->edit_type_group);
13177
13178 AlignObjects (ALIGN_CENTER, (HANDLE) epfp->single_field_group,
13179 (HANDLE) epfp->replace_sect_group,
13180 (HANDLE) epfp->merge_auth_list_group,
13181 (HANDLE) epfp->replace_pub_group,
13182 NULL);
13183
13184 epfp->pub_constraint_dlg = PubConstraintDialog (h);
13185
13186 c = HiddenGroup (h, 4, 0, NULL);
13187 b = DefaultButton (c, "Accept", DoEditPubs);
13188 SetObjectExtra (b, epfp, NULL);
13189 PushButton (c, "Cancel", StdCancelButtonProc);
13190 epfp->leaveDlgUp = CheckBox (c, "Leave Dialog Up", NULL);
13191
13192 AlignObjects (ALIGN_CENTER, (HANDLE) epfp->edit_type_group,
13193 (HANDLE) m,
13194 (HANDLE) epfp->pub_constraint_dlg,
13195 (HANDLE) c,
13196 NULL);
13197
13198 RealizeWindow (w);
13199 Show (w);
13200 Update ();
13201
13202 }
13203
EditPubs(IteM i)13204 extern void EditPubs (IteM i)
13205 {
13206 BaseFormPtr bfp;
13207
13208 #ifdef WIN_MAC
13209 bfp = currentFormDataPtr;
13210 #else
13211 bfp = GetObjectExtra (i);
13212 #endif
13213
13214 EditPubsEx (bfp);
13215 }
13216
RemovePubConsortiumFromSeqFeat(SeqFeatPtr sfp,Pointer userdata)13217 static void RemovePubConsortiumFromSeqFeat (SeqFeatPtr sfp, Pointer userdata)
13218 {
13219 PubdescPtr pdp;
13220 PubPtr pub;
13221
13222 if (sfp == NULL || sfp->data.choice != SEQFEAT_PUB)
13223 {
13224 return;
13225 }
13226 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
13227 if (pdp == NULL) return;
13228 for (pub = pdp->pub; pub != NULL; pub = pub->next)
13229 {
13230 RemoveConsortiumFromPub (pub);
13231 }
13232 }
13233
RemovePubConsortiumFromDescr(SeqDescrPtr sdp,Pointer userdata)13234 static void RemovePubConsortiumFromDescr (SeqDescrPtr sdp, Pointer userdata)
13235 {
13236 PubdescPtr pdp;
13237 PubPtr pub;
13238
13239 if (sdp == NULL || sdp->choice != Seq_descr_pub)
13240 {
13241 return;
13242 }
13243 pdp = (PubdescPtr) sdp->data.ptrvalue;
13244 if (pdp == NULL) return;
13245 for (pub = pdp->pub; pub != NULL; pub = pub->next)
13246 {
13247 RemoveConsortiumFromPub (pub);
13248 }
13249 }
13250
13251
RemovePubConsortiumsBaseForm(BaseFormPtr bfp)13252 static void RemovePubConsortiumsBaseForm (BaseFormPtr bfp)
13253 {
13254 SeqEntryPtr sep;
13255
13256 if (bfp == NULL) return;
13257
13258 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
13259 if (sep == NULL) return;
13260
13261 VisitFeaturesInSep (sep, NULL, RemovePubConsortiumFromSeqFeat);
13262 VisitDescriptorsInSep (sep, NULL, RemovePubConsortiumFromDescr);
13263
13264 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
13265 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
13266 }
13267
13268
RemovePubConsortiums(IteM i)13269 extern void RemovePubConsortiums (IteM i)
13270 {
13271 ButtonOrMenuItemTemplate(i, RemovePubConsortiumsBaseForm);
13272 }
13273
13274
RemovePubConsortiumsBtn(ButtoN b)13275 extern void RemovePubConsortiumsBtn (ButtoN b)
13276 {
13277 ButtonOrMenuButtonTemplate(b, RemovePubConsortiumsBaseForm);
13278 }
13279
13280
13281 #define MAX_ID_LEN 84
13282
GetSeqIdPrintLen(Pointer userdata)13283 static Int4 LIBCALLBACK GetSeqIdPrintLen (Pointer userdata)
13284 {
13285 return MAX_ID_LEN + 2;
13286 }
13287
PrintSeqId(CharPtr cp,Pointer userdata)13288 static void LIBCALLBACK PrintSeqId (CharPtr cp, Pointer userdata)
13289 {
13290 BioseqPtr bsp;
13291
13292 bsp = (BioseqPtr) userdata;
13293 if (bsp == NULL) return;
13294
13295 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), cp, PRINTID_REPORT, MAX_ID_LEN);
13296 StringCat (cp, "\n");
13297 }
13298
AddNucleotideToList(BioseqPtr seg_bsp,SeqEntryPtr PNTR nuc_list)13299 static void AddNucleotideToList (BioseqPtr seg_bsp, SeqEntryPtr PNTR nuc_list)
13300 {
13301 SeqEntryPtr seg_sep, set_sep, prev_sep = NULL;
13302 BioseqSetPtr parent_bssp;
13303
13304
13305 if (seg_bsp == NULL || nuc_list == NULL)
13306 {
13307 return;
13308 }
13309
13310 seg_sep = SeqMgrGetSeqEntryForData (seg_bsp);
13311 if (seg_bsp->idx.parenttype == OBJ_BIOSEQSET && seg_bsp->idx.parentptr != NULL)
13312 {
13313 parent_bssp = (BioseqSetPtr) seg_bsp->idx.parentptr;
13314 set_sep = parent_bssp->seq_set;
13315 prev_sep = NULL;
13316 while (set_sep != seg_sep)
13317 {
13318 prev_sep = set_sep;
13319 set_sep = set_sep->next;
13320 }
13321 if (set_sep == seg_sep)
13322 {
13323 if (prev_sep == NULL)
13324 {
13325 parent_bssp->seq_set = set_sep->next;
13326 }
13327 else
13328 {
13329 prev_sep->next = set_sep->next;
13330 }
13331 set_sep->next = NULL;
13332 ValNodeLink (nuc_list, set_sep);
13333 }
13334 }
13335 }
13336
AddNucProtSetToList(BioseqSetPtr bssp,SeqEntryPtr PNTR set_list)13337 static void AddNucProtSetToList (BioseqSetPtr bssp, SeqEntryPtr PNTR set_list)
13338 {
13339 SeqEntryPtr seg_sep, set_sep, prev_sep = NULL;
13340 BioseqSetPtr parent_bssp;
13341
13342
13343 if (bssp == NULL || set_list == NULL)
13344 {
13345 return;
13346 }
13347
13348 seg_sep = SeqMgrGetSeqEntryForData (bssp);
13349 if (bssp->idx.parenttype == OBJ_BIOSEQSET && bssp->idx.parentptr != NULL)
13350 {
13351 parent_bssp = (BioseqSetPtr) bssp->idx.parentptr;
13352 set_sep = parent_bssp->seq_set;
13353 prev_sep = NULL;
13354 while (set_sep != seg_sep)
13355 {
13356 prev_sep = set_sep;
13357 set_sep = set_sep->next;
13358 }
13359 if (set_sep == seg_sep)
13360 {
13361 if (prev_sep == NULL)
13362 {
13363 parent_bssp->seq_set = set_sep->next;
13364 }
13365 else
13366 {
13367 prev_sep->next = set_sep->next;
13368 }
13369 set_sep->next = NULL;
13370 ValNodeLink (set_list, set_sep);
13371 }
13372 }
13373 }
13374
AddNucOrNucProtSetToList(BioseqPtr seg_bsp,SeqEntryPtr PNTR set_list)13375 static void AddNucOrNucProtSetToList (BioseqPtr seg_bsp, SeqEntryPtr PNTR set_list)
13376 {
13377 SeqEntryPtr top_sep;
13378 BioseqSetPtr bssp;
13379 Boolean moved_set = FALSE;
13380
13381 if (seg_bsp == NULL || set_list == NULL)
13382 {
13383 return;
13384 }
13385
13386 top_sep = GetBestTopParentForData (seg_bsp->idx.entityID, seg_bsp);
13387 if (top_sep != NULL && top_sep->choice == 2 && top_sep->data.ptrvalue != NULL)
13388 {
13389 bssp = (BioseqSetPtr) top_sep->data.ptrvalue;
13390 if (bssp->_class == BioseqseqSet_class_nuc_prot)
13391 {
13392 AddNucProtSetToList (bssp, set_list);
13393 moved_set = TRUE;
13394 }
13395 }
13396 if (!moved_set)
13397 {
13398 AddNucleotideToList (seg_bsp, set_list);
13399 }
13400 }
13401
IsBioseqMasterOrSegment(BioseqPtr bsp)13402 static Boolean IsBioseqMasterOrSegment (BioseqPtr bsp)
13403 {
13404 BioseqSetPtr bssp;
13405
13406 if (bsp == NULL
13407 || bsp->idx.parenttype != OBJ_BIOSEQSET
13408 || bsp->idx.parentptr == NULL)
13409 {
13410 return FALSE;
13411 }
13412
13413 bssp = (BioseqSetPtr) bsp->idx.parentptr;
13414 if (bssp->_class == BioseqseqSet_class_segset
13415 || bssp->_class == BioseqseqSet_class_parts)
13416 {
13417 return TRUE;
13418 }
13419 else
13420 {
13421 return FALSE;
13422 }
13423 }
13424
RemoveMasterAndSegmentSequences(ValNodePtr PNTR bioseq_list)13425 static void RemoveMasterAndSegmentSequences (ValNodePtr PNTR bioseq_list)
13426 {
13427 ValNodePtr prev_vnp = NULL, next_vnp, this_vnp;
13428 BioseqPtr bsp;
13429
13430 if (bioseq_list == NULL)
13431 {
13432 return;
13433 }
13434
13435 this_vnp = *bioseq_list;
13436 while (this_vnp != NULL)
13437 {
13438 next_vnp = this_vnp->next;
13439 bsp = (BioseqPtr) this_vnp->data.ptrvalue;
13440 if (IsBioseqMasterOrSegment (bsp))
13441 {
13442 if (prev_vnp == NULL)
13443 {
13444 *bioseq_list = this_vnp->next;
13445 }
13446 else
13447 {
13448 prev_vnp->next = this_vnp->next;
13449 }
13450 this_vnp->next = NULL;
13451 ValNodeFree (this_vnp);
13452 }
13453 else
13454 {
13455 prev_vnp = this_vnp;
13456 }
13457
13458 this_vnp = next_vnp;
13459 }
13460
13461 }
13462
13463 /* This function allows the user to exclude sequences from the list of nucleotide sequences
13464 * to be used in the new segset.
13465 * It is similar to NewUpdateSegSet, except that it uses the selected sequences to create
13466 * a new set to be converted to the segset, instead of converting the selected set directly.
13467 */
CreateSegSet(Pointer data)13468 static Int2 LIBCALLBACK CreateSegSet (Pointer data)
13469
13470 {
13471 OMProcControlPtr ompcp;
13472 SeqEntryPtr sep;
13473 ErrSev sev;
13474 WindoW w;
13475 GrouP h, g, c;
13476 ButtoN intersperse_nulls_btn;
13477 ButtoN fix_locus_btn;
13478 ButtoN tax_fix_cleanup_btn;
13479 ButtoN b;
13480 AdjustListPairData alpd;
13481 ValNodePtr bioseq_list = NULL;
13482 Int4 seq_num = 0;
13483 ValNodePtr list_pair = NULL;
13484 BioseqSetPtr target_set = NULL;
13485 ModalAcceptCancelData acd;
13486 BioseqSetPtr new_segset;
13487 SeqEntryPtr new_segset_sep, dest_sep;
13488 ValNodePtr seg_vnp, vnp;
13489 BioseqPtr seg_bsp;
13490 SeqEntryPtr prot_list = NULL;
13491
13492 ompcp = (OMProcControlPtr) data;
13493 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
13494 switch (ompcp->input_itemtype) {
13495 case OBJ_BIOSEQSET :
13496 break;
13497 case 0 :
13498 return OM_MSG_RET_ERROR;
13499 default :
13500 return OM_MSG_RET_ERROR;
13501 }
13502 if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
13503 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
13504 if (sep == NULL) return OM_MSG_RET_ERROR;
13505
13506 /* TODO: We will want to choose as our target set the set above this one if
13507 * this set is a nuc-prot set.
13508 */
13509 target_set = (BioseqSetPtr)ompcp->input_data;
13510 if (target_set == NULL) return OM_MSG_RET_ERROR;
13511 dest_sep = SeqMgrGetSeqEntryForData (target_set);
13512 if (dest_sep == NULL) return OM_MSG_RET_ERROR;
13513
13514 w = MovableModalWindow (-50, -33, -10, -10, "SegSet Creation Options", NULL);
13515 h = HiddenGroup (w, -1, 0, NULL);
13516 SetGroupSpacing (h, 10, 10);
13517
13518 alpd.list_pair_dlg = DoubleListDialog (h, "Sequences for SegSet", "Sequences to Exclude",
13519 GetSeqIdPrintLen, PrintSeqId,
13520 EnableAdjustListPairAccept,
13521 &alpd);
13522 alpd.none_in_1_ok = FALSE;
13523 alpd.none_in_2_ok = TRUE;
13524
13525 g = HiddenGroup (h, 0, 4, NULL);
13526 intersperse_nulls_btn = CheckBox (g, "Intersperse NULLS", NULL);
13527 SetStatus (intersperse_nulls_btn, TRUE);
13528 fix_locus_btn = CheckBox (g, "Force Locus Fixup", NULL);
13529 SetStatus (fix_locus_btn, TRUE);
13530 tax_fix_cleanup_btn = CheckBox (g, "Do Tax_Fix/Cleanup", NULL);
13531 SetStatus (tax_fix_cleanup_btn, TRUE);
13532
13533 acd.accepted = FALSE;
13534 acd.cancelled = FALSE;
13535 c = HiddenGroup (h, 4, 0, NULL);
13536 alpd.accept_btn = DefaultButton (c, "Accept", ModalAcceptButton);
13537 SetObjectExtra (alpd.accept_btn, &acd, NULL);
13538 b = PushButton (c, "Cancel", ModalCancelButton);
13539 SetObjectExtra (b, &acd, NULL);
13540
13541 ListBioseqsInSeqEntry (sep, TRUE, &seq_num, &bioseq_list);
13542 RemoveMasterAndSegmentSequences (&bioseq_list);
13543 ValNodeAddPointer (&list_pair, 0, bioseq_list);
13544 ValNodeAddPointer (&list_pair, 0, NULL);
13545 PointerToDialog (alpd.list_pair_dlg, list_pair);
13546 list_pair = ValNodeFree (list_pair);
13547
13548 AlignObjects (ALIGN_CENTER, (HANDLE) alpd.list_pair_dlg,
13549 (HANDLE) g,
13550 (HANDLE) c,
13551 NULL);
13552 RealizeWindow (w);
13553 Show (w);
13554 Update ();
13555
13556 while (!acd.cancelled && ! acd.accepted)
13557 {
13558 ProcessExternalEvent ();
13559 Update ();
13560 }
13561 ProcessAnEvent ();
13562 Hide (w);
13563 if (acd.cancelled)
13564 {
13565 Remove (w);
13566 return OM_MSG_RET_DONE;
13567 }
13568
13569 list_pair = DialogToPointer (alpd.list_pair_dlg);
13570 if (list_pair == NULL)
13571 {
13572 return OM_MSG_RET_DONE;
13573 }
13574
13575 new_segset = BioseqSetNew ();
13576 new_segset->_class = BioseqseqSet_class_pop_set;
13577 new_segset_sep = SeqEntryNew ();
13578 new_segset_sep->choice = 2;
13579 new_segset_sep->data.ptrvalue = new_segset;
13580
13581 for (seg_vnp = list_pair->data.ptrvalue; seg_vnp != NULL; seg_vnp = seg_vnp->next)
13582 {
13583 seg_bsp = (BioseqPtr) seg_vnp->data.ptrvalue;
13584 if (seg_bsp == NULL)
13585 {
13586 continue;
13587 }
13588
13589 AddNucOrNucProtSetToList (seg_bsp, &(new_segset->seq_set));
13590
13591 }
13592
13593 /* clean up list pair returned by dialog */
13594 for (vnp = list_pair; vnp != NULL; vnp = vnp->next) {
13595 vnp->data.ptrvalue = ValNodeFree (vnp->data.ptrvalue);
13596 }
13597 list_pair = ValNodeFree (list_pair);
13598
13599 AddSeqEntryToSeqEntry (dest_sep, new_segset_sep, TRUE);
13600
13601 NewSegFixup (new_segset_sep, GetStatus (intersperse_nulls_btn));
13602
13603 AddSeqEntryToSeqEntry (new_segset_sep, prot_list, TRUE);
13604
13605 DeleteMarkedObjects (ompcp->input_entityID, 0, NULL);
13606
13607 if (GetStatus (fix_locus_btn))
13608 {
13609 sev = ErrSetMessageLevel (SEV_FATAL);
13610 DoFixupLocus (new_segset_sep);
13611 DoFixupSegSet (new_segset_sep);
13612 ErrSetMessageLevel (sev);
13613 }
13614
13615 if (GetStatus (tax_fix_cleanup_btn))
13616 {
13617 ForceCleanupEntityID (ompcp->input_entityID);
13618 }
13619
13620
13621 Remove (w);
13622
13623 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
13624 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
13625 Update ();
13626 return OM_MSG_RET_DONE;
13627 }
13628
13629
ListBioseqSetRawSequences(BioseqSetPtr bssp,ValNodePtr PNTR vnpp)13630 static void ListBioseqSetRawSequences (BioseqSetPtr bssp, ValNodePtr PNTR vnpp)
13631 {
13632 SeqEntryPtr sep;
13633 BioseqPtr bsp;
13634 Char id_str [128];
13635
13636 if (bssp == NULL || bssp->_class == BioseqseqSet_class_parts || vnpp == NULL)
13637 {
13638 return;
13639 }
13640
13641 for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
13642 {
13643 if (IS_Bioseq_set (sep))
13644 {
13645 ListBioseqSetRawSequences (sep->data.ptrvalue, vnpp);
13646 }
13647 else if (IS_Bioseq (sep))
13648 {
13649 bsp = (BioseqPtr) (sep->data.ptrvalue);
13650 if (bsp != NULL)
13651 {
13652 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, sizeof (id_str) - 1);
13653 ValNodeAddPointer (vnpp, 0, StringSave (id_str));
13654 }
13655 }
13656 }
13657 }
13658
ListRawSequencesInAlignments(GatherContextPtr gcp)13659 static Boolean ListRawSequencesInAlignments (GatherContextPtr gcp)
13660
13661 {
13662 BioseqPtr bsp;
13663 BioseqSetPtr bssp;
13664 ValNodePtr PNTR vnpp;
13665 Char id_str [128];
13666
13667 if (gcp == NULL || gcp->thisitem == NULL || gcp->userdata == NULL)
13668 {
13669 return TRUE;
13670 }
13671
13672 /* don't process parts of a segmented set */
13673 if (gcp->parenttype == OBJ_BIOSEQSET
13674 && (bssp = (BioseqSetPtr) gcp->parentitem) != NULL
13675 && bssp->_class == BioseqseqSet_class_parts)
13676 {
13677 return TRUE;
13678 }
13679
13680 vnpp = (ValNodePtr PNTR) gcp->userdata;
13681 if (vnpp == NULL) return TRUE;
13682 bsp = NULL;
13683 if (gcp->thistype == OBJ_BIOSEQ) {
13684 bsp = (BioseqPtr) gcp->thisitem;
13685 if (bsp->repr == Seq_repr_raw && IsBioseqInAnyAlignment (bsp, gcp->entityID))
13686 {
13687 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, sizeof (id_str) - 1);
13688 ValNodeAddPointer (vnpp, 0, StringSave (id_str));
13689 }
13690 } else if (gcp->thistype == OBJ_BIOSEQSET) {
13691 bssp = (BioseqSetPtr) gcp->thisitem;
13692 ListBioseqSetRawSequences (bssp, vnpp);
13693 } else return TRUE;
13694
13695 return TRUE;
13696 }
13697
13698
FeatToDeltaSeq(Pointer data)13699 static Int2 LIBCALLBACK FeatToDeltaSeq (Pointer data)
13700
13701 {
13702 BioseqPtr bsp;
13703 SeqMgrFeatContext context;
13704 Int4 diff;
13705 FILE *fp;
13706 Int2 i;
13707 Int4Ptr ivals;
13708 Int4 last;
13709 OMProcControlPtr ompcp;
13710 Char path [PATH_MAX];
13711 SeqFeatPtr sfp;
13712 SeqInt sint;
13713 SeqIdPtr sip;
13714 Int4 start;
13715 Int4 stop;
13716 ValNode vn;
13717
13718 ompcp = (OMProcControlPtr) data;
13719 if (ompcp == NULL) return OM_MSG_RET_ERROR;
13720
13721 switch (ompcp->input_itemtype) {
13722 case OBJ_SEQFEAT:
13723 sfp = (SeqFeatPtr) ompcp->input_data;
13724 break;
13725 default:
13726 return OM_MSG_RET_ERROR;
13727 }
13728
13729 if (SeqMgrGetDesiredFeature (ompcp->input_entityID, NULL, 0, 0, sfp, &context) != sfp) return OM_MSG_RET_ERROR;
13730 bsp = BioseqFindFromSeqLoc (sfp->location);
13731 if (bsp == NULL) return OM_MSG_RET_ERROR;
13732 sip = SeqIdFindBest (bsp->id, 0);
13733 if (sip == NULL) return OM_MSG_RET_ERROR;
13734
13735 if (! GetOutputFileName (path, sizeof (path), NULL)) return OM_MSG_RET_ERROR;
13736 fp = FileOpen (path, "w");
13737 if (fp == NULL) return OM_MSG_RET_ERROR;
13738
13739 MemSet ((Pointer) &sint, 0, sizeof (SeqInt));
13740 MemSet ((Pointer) &vn, 0, sizeof (ValNode));
13741
13742 fprintf (fp, ">\n");
13743 ivals = context.ivals;
13744 start = *ivals;
13745 ivals++;
13746 stop = *ivals;
13747 ivals++;
13748 sint.from = MIN (start, stop);
13749 sint.to = MAX (start, stop);
13750 sint.strand = context.strand;
13751 sint.id = sip;
13752 vn.choice = SEQLOC_INT;
13753 vn.data.ptrvalue = (Pointer) &sint;
13754 SeqLocFastaStream (&vn, fp, 0, 60, 0, 0);
13755 last = stop;
13756 for (i = 1; i < context.numivals; i++) {
13757 start = *ivals;
13758 ivals++;
13759 stop = *ivals;
13760 ivals++;
13761 diff = start - last;
13762 if (diff < 0) {
13763 diff = -diff;
13764 }
13765 if (diff > 1) {
13766 fprintf (fp, ">?%ld\n", (long) diff - 1);
13767 }
13768 sint.from = MIN (start, stop);
13769 sint.to = MAX (start, stop);
13770 sint.strand = context.strand;
13771 sint.id = sip;
13772 vn.choice = SEQLOC_INT;
13773 vn.data.ptrvalue = (Pointer) &sint;
13774 SeqLocFastaStream (&vn, fp, 0, 60, 0, 0);
13775 last = stop;
13776 }
13777
13778 FileClose (fp);
13779 return OM_MSG_RET_ERROR;
13780 }
13781
13782
RemoveUnpublishedPubFeatCallback(SeqFeatPtr sfp,Pointer userdata)13783 static void RemoveUnpublishedPubFeatCallback (SeqFeatPtr sfp, Pointer userdata)
13784 {
13785 PubdescPtr pdp;
13786
13787 if (sfp == NULL || sfp->data.choice != SEQFEAT_PUB || sfp->data.value.ptrvalue == NULL)
13788 {
13789 return;
13790 }
13791 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
13792 if (GetPubStatus (pdp->pub) == PUB_STAT_UNPUBLISHED)
13793 {
13794 sfp->idx.deleteme = TRUE;
13795 }
13796 }
13797
RemoveUnpublishedPubDescCallback(SeqDescPtr sdp,Pointer userdata)13798 static void RemoveUnpublishedPubDescCallback (SeqDescPtr sdp, Pointer userdata)
13799 {
13800 PubdescPtr pdp;
13801 ObjValNodePtr ovp;
13802
13803 if (sdp == NULL || sdp->choice != Seq_descr_pub || sdp->data.ptrvalue == NULL)
13804 {
13805 return;
13806 }
13807
13808 pdp = (PubdescPtr) sdp->data.ptrvalue;
13809 if (GetPubStatus (pdp->pub) == PUB_STAT_UNPUBLISHED)
13810 {
13811 ovp = (ObjValNodePtr) sdp;
13812 ovp->idx.deleteme = TRUE;
13813 }
13814 }
13815
13816
RemoveUnpublishedPublicationsBaseForm(BaseFormPtr bfp)13817 NLM_EXTERN void RemoveUnpublishedPublicationsBaseForm (BaseFormPtr bfp)
13818 {
13819 SeqEntryPtr sep;
13820 if (bfp == NULL) return;
13821
13822 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
13823
13824 WatchCursor ();
13825 Update ();
13826
13827 VisitDescriptorsInSep (sep, NULL, RemoveUnpublishedPubDescCallback);
13828 VisitFeaturesInSep (sep, NULL, RemoveUnpublishedPubFeatCallback);
13829
13830 DeleteMarkedObjects (bfp->input_entityID, 0, NULL);
13831 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
13832 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
13833 ArrowCursor ();
13834 Update ();
13835 }
13836
13837
RemoveUnpublishedPublications(IteM i)13838 extern void RemoveUnpublishedPublications (IteM i)
13839 {
13840 BaseFormPtr bfp;
13841
13842 #ifdef WIN_MAC
13843 bfp = currentFormDataPtr;
13844 #else
13845 bfp = GetObjectExtra (i);
13846 #endif
13847 RemoveUnpublishedPublicationsBaseForm(bfp);
13848 }
13849
13850
RemovePublishedPubFeatCallback(SeqFeatPtr sfp,Pointer userdata)13851 static void RemovePublishedPubFeatCallback (SeqFeatPtr sfp, Pointer userdata)
13852 {
13853 PubdescPtr pdp;
13854
13855 if (sfp == NULL || sfp->data.choice != SEQFEAT_PUB || sfp->data.value.ptrvalue == NULL)
13856 {
13857 return;
13858 }
13859 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
13860 if (GetPubStatus (pdp->pub) == PUB_STAT_PUBLISHED)
13861 {
13862 sfp->idx.deleteme = TRUE;
13863 }
13864 }
13865
RemovePublishedPubDescCallback(SeqDescPtr sdp,Pointer userdata)13866 static void RemovePublishedPubDescCallback (SeqDescPtr sdp, Pointer userdata)
13867 {
13868 PubdescPtr pdp;
13869 ObjValNodePtr ovp;
13870
13871 if (sdp == NULL || sdp->choice != Seq_descr_pub || sdp->data.ptrvalue == NULL)
13872 {
13873 return;
13874 }
13875
13876 pdp = (PubdescPtr) sdp->data.ptrvalue;
13877 if (GetPubStatus (pdp->pub) == PUB_STAT_PUBLISHED)
13878 {
13879 ovp = (ObjValNodePtr) sdp;
13880 ovp->idx.deleteme = TRUE;
13881 }
13882 }
13883
RemovePublishedPublications(IteM i)13884 extern void RemovePublishedPublications (IteM i)
13885 {
13886 BaseFormPtr bfp;
13887 SeqEntryPtr sep;
13888
13889 #ifdef WIN_MAC
13890 bfp = currentFormDataPtr;
13891 #else
13892 bfp = GetObjectExtra (i);
13893 #endif
13894 if (bfp == NULL) return;
13895
13896 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
13897
13898 WatchCursor ();
13899 Update ();
13900
13901 VisitDescriptorsInSep (sep, NULL, RemovePublishedPubDescCallback);
13902 VisitFeaturesInSep (sep, NULL, RemovePublishedPubFeatCallback);
13903
13904 DeleteMarkedObjects (bfp->input_entityID, 0, NULL);
13905 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
13906 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
13907 ArrowCursor ();
13908 Update ();
13909 }
13910
13911
PropagateMasterSourceToSegments(BioseqSetPtr bssp)13912 static void PropagateMasterSourceToSegments (BioseqSetPtr bssp)
13913 {
13914 SeqEntryPtr sep, seg_entry;
13915 SeqDescrPtr sdp, copy_sdp, sdp_next;
13916 SeqMgrDescContext dcontext;
13917 BioseqSetPtr parts_set;
13918 BioseqPtr bsp, part_bsp;
13919 ObjValNodePtr ovp;
13920
13921 if (bssp == NULL)
13922 {
13923 return;
13924 }
13925
13926 if (bssp->_class == BioseqseqSet_class_segset)
13927 {
13928 sep = bssp->seq_set;
13929 /* find master segment */
13930 while (sep != NULL && (!IS_Bioseq (sep) || sep->data.ptrvalue == NULL))
13931 {
13932 sep = sep->next;
13933 }
13934 if (sep != NULL)
13935 {
13936 bsp = (BioseqPtr) sep->data.ptrvalue;
13937 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
13938 if (sdp != NULL)
13939 {
13940 /* don't want to copy descriptors after Bioseq */
13941 sdp_next = sdp->next;
13942 sdp->next = NULL;
13943
13944 /* find parts set */
13945 sep = bssp->seq_set;
13946 parts_set = NULL;
13947 while (sep != NULL && parts_set == NULL)
13948 {
13949 if (IS_Bioseq_set (sep) && sep->data.ptrvalue != NULL)
13950 {
13951 parts_set = (BioseqSetPtr) sep->data.ptrvalue;
13952 if (parts_set->_class != BioseqseqSet_class_parts)
13953 {
13954 parts_set = NULL;
13955 }
13956 }
13957 sep = sep->next;
13958 }
13959 if (parts_set != NULL)
13960 {
13961 /* add a copy of the master source to each segment */
13962 for (seg_entry = parts_set->seq_set;
13963 seg_entry != NULL;
13964 seg_entry = seg_entry->next)
13965 {
13966 if (!IS_Bioseq (seg_entry) || seg_entry->data.ptrvalue == NULL)
13967 {
13968 continue;
13969 }
13970 part_bsp = (BioseqPtr) seg_entry->data.ptrvalue;
13971 copy_sdp = (SeqDescrPtr) AsnIoMemCopy (sdp,
13972 (AsnReadFunc) SeqDescrAsnRead,
13973 (AsnWriteFunc) SeqDescrAsnWrite);
13974 ValNodeLink (&(part_bsp->descr),copy_sdp);
13975 }
13976 }
13977 sdp->next = sdp_next;
13978 /* we want to remove the source descriptor from the master */
13979 if (sdp->extended != 0) {
13980 ovp = (ObjValNodePtr) sdp;
13981 ovp->idx.deleteme = TRUE;
13982 }
13983 }
13984 }
13985 }
13986 else
13987 {
13988 for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
13989 {
13990 if (IS_Bioseq_set (sep))
13991 {
13992 PropagateMasterSourceToSegments (sep->data.ptrvalue);
13993 }
13994 }
13995 }
13996 }
13997
13998
CopyMasterSourceToSegments(Pointer data)13999 static Int2 LIBCALLBACK CopyMasterSourceToSegments (Pointer data)
14000
14001 {
14002 OMProcControlPtr ompcp;
14003 SeqEntryPtr sep = NULL;
14004
14005 ompcp = (OMProcControlPtr) data;
14006 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
14007 switch (ompcp->input_itemtype) {
14008 case OBJ_BIOSEQ :
14009 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
14010 break;
14011 case OBJ_BIOSEQSET :
14012 sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
14013 break;
14014 case 0 :
14015 return OM_MSG_RET_ERROR;
14016 default :
14017 return OM_MSG_RET_ERROR;
14018 }
14019 if (sep == NULL || !IS_Bioseq_set (sep) || sep->data.ptrvalue == NULL) return OM_MSG_RET_ERROR;
14020
14021 PropagateMasterSourceToSegments(sep->data.ptrvalue);
14022
14023 DeleteMarkedObjects (ompcp->input_entityID, 0, NULL);
14024 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
14025 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
14026 return OM_MSG_RET_DONE;
14027 }
14028
14029
GetNonPartialProteinsCallback(BioseqPtr bsp,Pointer userdata)14030 static void GetNonPartialProteinsCallback (BioseqPtr bsp, Pointer userdata)
14031 {
14032 SeqDescPtr sdp;
14033 SeqMgrDescContext context;
14034 MolInfoPtr mip;
14035
14036 if (bsp != NULL && ISA_aa(bsp->mol) && userdata != NULL) {
14037 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &context);
14038 /* we don't want to consider the ones that are 3' partial */
14039 if (sdp != NULL && (mip = (MolInfoPtr) sdp->data.ptrvalue) != NULL
14040 && mip->completeness != 4 /* no right */
14041 && mip->completeness != 5 /* no ends */) {
14042 ValNodeAddPointer ((ValNodePtr PNTR) userdata, OBJ_BIOSEQ, bsp);
14043 }
14044 }
14045 }
14046
14047
GetNonPartialProtAlign(SeqEntryPtr sep)14048 static SeqAlignPtr GetNonPartialProtAlign (SeqEntryPtr sep)
14049 {
14050 ValNodePtr protein_list = NULL;
14051 ValNodePtr vnp;
14052 SeqAlignPtr salp_head = NULL, salp_prev = NULL, salp, salp_tmp, salp_mult = NULL;
14053 BioseqPtr master_bsp;
14054
14055 if (sep == NULL)
14056 {
14057 return NULL;
14058 }
14059
14060 /* get list of protein sequences */
14061 VisitBioseqsInSep (sep, &protein_list, GetNonPartialProteinsCallback);
14062 if (protein_list == NULL || protein_list->next == NULL)
14063 {
14064 protein_list = ValNodeFree (protein_list);
14065 return NULL;
14066 }
14067
14068 /* now get protein alignment */
14069 master_bsp = protein_list->data.ptrvalue;
14070 for (vnp = protein_list->next; vnp != NULL; vnp = vnp->next)
14071 {
14072 salp = Sequin_GlobalAlign2Seq(master_bsp, vnp->data.ptrvalue, FALSE);
14073 if (salp_head != NULL && salp != NULL)
14074 {
14075 salp_prev->next = salp;
14076 salp_prev = salp;
14077 }
14078 else if (salp != NULL)
14079 {
14080 salp_head = salp_prev = salp;
14081 }
14082 }
14083 /* clean up protein list now that we are done with it */
14084 protein_list = ValNodeFree (protein_list);
14085
14086 if (salp_head != NULL)
14087 {
14088 salp_tmp = salp_head;
14089 while (salp_tmp != NULL)
14090 {
14091 if (salp_tmp->saip != NULL)
14092 {
14093 SeqAlignIndexFree(salp_tmp->saip);
14094 salp_tmp->saip = NULL;
14095 }
14096 salp_tmp = salp_tmp->next;
14097 }
14098 AlnMgr2IndexSeqAlign(salp_head);
14099 salp_mult = AlnMgr2GetSubAlign(salp_head, 0, -1, 0, TRUE);
14100 salp_mult->dim = AlnMgr2GetNumRows(salp_head);
14101 salp_mult->type = SAT_PARTIAL;
14102 FixAlignmentEndStubs (salp_mult);
14103 }
14104
14105 return salp_mult;
14106 }
14107
14108
14109 /* returns list of SeqIds that must be freed */
GetAccessionListForTruncateFromAlign(SeqAlignPtr salp,Int4 num_missing)14110 static ValNodePtr GetAccessionListForTruncateFromAlign (SeqAlignPtr salp, Int4 num_missing)
14111 {
14112 ValNodePtr trunc_list = NULL;
14113 Int4 aln_len, i, start_seq, stop_seq, aln_pos;
14114 SeqIdPtr sip;
14115 BioseqPtr bsp;
14116 MolInfoPtr mip;
14117 SeqDescPtr sdp;
14118 SeqMgrDescContext context;
14119
14120 if (salp == NULL || num_missing < 1) {
14121 return NULL;
14122 }
14123 AlnMgr2IndexSeqAlign(salp);
14124 aln_len = AlnMgr2GetAlnLength (salp, TRUE);
14125 for (i = 0; i < salp->dim; i++) {
14126 sip = AlnMgr2GetNthSeqIdPtr (salp, i + 1);
14127 bsp = BioseqFind (sip);
14128 if (bsp) {
14129 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &context);
14130 /* we don't want to consider the ones that are 3' partial */
14131 if (sdp != NULL && (mip = (MolInfoPtr) sdp->data.ptrvalue) != NULL
14132 && mip->completeness != 4 /* no right */
14133 && mip->completeness != 5 /* no ends */) {
14134 AlnMgr2GetNthSeqRangeInSA(salp, i + 1, &start_seq, &stop_seq);
14135 aln_pos = AlnMgr2MapBioseqToSeqAlign(salp, stop_seq, i + 1);
14136 if (aln_len - aln_pos >= num_missing) {
14137 ValNodeAddPointer (&trunc_list, 0, sip);
14138 sip = NULL;
14139 }
14140 }
14141 }
14142 sip = SeqIdFree (sip);
14143 }
14144 return trunc_list;
14145 }
14146
14147
14148 typedef struct truncatebyprotalign {
14149 FORM_MESSAGE_BLOCK
14150
14151 TexT num_missing;
14152
14153 SeqAlignPtr salp;
14154 } TruncateByProtAlignData, PNTR TruncateByProtAlignPtr;
14155
14156
CleanupTruncateByProtAlignForm(GraphiC g,VoidPtr data)14157 static void CleanupTruncateByProtAlignForm (GraphiC g, VoidPtr data)
14158 {
14159 TruncateByProtAlignPtr dlg;
14160
14161 dlg = (TruncateByProtAlignPtr) data;
14162 if (dlg != NULL) {
14163 dlg->salp = SeqAlignFree (dlg->salp);
14164 }
14165 StdCleanupFormProc (g, data);
14166 }
14167
14168
14169
ShowTruncateList(ButtoN b)14170 static void ShowTruncateList (ButtoN b)
14171 {
14172 TruncateByProtAlignPtr dlg;
14173 SeqEntryPtr sep;
14174 SeqAlignPtr salp;
14175 ValNodePtr trunc_list, vnp;
14176 CharPtr val;
14177 Int4 num_missing;
14178 LogInfoPtr lip;
14179 Char id_str[200];
14180
14181 dlg = (TruncateByProtAlignPtr) GetObjectExtra (b);
14182 if (dlg == NULL) {
14183 return;
14184 }
14185
14186 val = SaveStringFromText (dlg->num_missing);
14187 if (StringHasNoText (val)) {
14188 val = MemFree (val);
14189 return;
14190 }
14191 num_missing = atoi (val);
14192 val = MemFree (val);
14193
14194 sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
14195 if (dlg->salp == NULL) {
14196 salp = GetNonPartialProtAlign (sep);
14197 } else {
14198 salp = dlg->salp;
14199 }
14200 trunc_list = GetAccessionListForTruncateFromAlign(salp, num_missing);
14201 if (dlg->salp == NULL) {
14202 salp = SeqAlignFree (salp);
14203 }
14204
14205 lip = OpenLog ("Accessions");
14206 for (vnp = trunc_list; vnp != NULL; vnp = vnp->next) {
14207 SeqIdWrite (vnp->data.ptrvalue, id_str, PRINTID_FASTA_LONG, sizeof (id_str) - 1);
14208 fprintf (lip->fp, "%s\n", id_str);
14209 lip->data_in_log = TRUE;
14210 }
14211 if (!lip->data_in_log) {
14212 fprintf (lip->fp, "No accessions found\n");
14213 lip->data_in_log = TRUE;
14214 }
14215 CloseLog (lip);
14216 lip = FreeLog (lip);
14217
14218 for (vnp = trunc_list; vnp != NULL; vnp = vnp->next) {
14219 vnp->data.ptrvalue = SeqIdFree (vnp->data.ptrvalue);
14220 }
14221 trunc_list = ValNodeFree (trunc_list);
14222 }
14223
14224
MarkTruncateList(ButtoN b)14225 static void MarkTruncateList (ButtoN b)
14226 {
14227 TruncateByProtAlignPtr dlg;
14228 SeqEntryPtr sep;
14229 SeqAlignPtr salp;
14230 ValNodePtr trunc_list, vnp;
14231 CharPtr val;
14232 Int4 num_missing;
14233 BioseqPtr prot_bsp;
14234 SeqFeatPtr sfp, cds, mrna;
14235 SeqMgrFeatContext context;
14236 ProtRefPtr prp;
14237 CharPtr orig_val, new_val;
14238 RnaRefPtr rrp;
14239
14240 dlg = (TruncateByProtAlignPtr) GetObjectExtra (b);
14241 if (dlg == NULL) {
14242 return;
14243 }
14244
14245 val = SaveStringFromText (dlg->num_missing);
14246 if (StringHasNoText (val)) {
14247 val = MemFree (val);
14248 return;
14249 }
14250 num_missing = atoi (val);
14251 val = MemFree (val);
14252
14253 sep = GetTopSeqEntryForEntityID (dlg->input_entityID);
14254 if (dlg->salp == NULL) {
14255 salp = GetNonPartialProtAlign (sep);
14256 } else {
14257 salp = dlg->salp;
14258 }
14259 trunc_list = GetAccessionListForTruncateFromAlign(salp, num_missing);
14260 if (dlg->salp == NULL) {
14261 salp = SeqAlignFree (salp);
14262 }
14263
14264 for (vnp = trunc_list; vnp != NULL; vnp = vnp->next) {
14265 prot_bsp = BioseqFind (vnp->data.ptrvalue);
14266 sfp = SeqMgrGetNextFeature (prot_bsp, NULL, 0, FEATDEF_PROT, &context);
14267 if (sfp != NULL && (prp = (ProtRefPtr) sfp->data.value.ptrvalue) != NULL) {
14268 if (prp->name == NULL) {
14269 ValNodeAddPointer (&(prp->name), 0, StringSave ("truncated"));
14270 } else {
14271 orig_val = prp->name->data.ptrvalue;
14272 if (StringNCmp (orig_val, "truncated ", 10) != 0) {
14273 new_val = (CharPtr) MemNew (sizeof (Char) * (StringLen (orig_val) + 11));
14274 sprintf (new_val, "truncated %s", orig_val);
14275 orig_val = MemFree (orig_val);
14276 prp->name->data.ptrvalue = new_val;
14277 cds = SeqMgrGetCDSgivenProduct (prot_bsp, NULL);
14278 if (cds != NULL) {
14279 mrna = SeqMgrGetOverlappingmRNA (cds->location, &context);
14280 if (mrna != NULL) {
14281 rrp = (RnaRefPtr) mrna->data.value.ptrvalue;
14282 if (rrp->ext.choice == 1) {
14283 rrp->ext.value.ptrvalue = MemFree (rrp->ext.value.ptrvalue);
14284 rrp->ext.value.ptrvalue = StringSave (new_val);
14285 }
14286 }
14287 }
14288 }
14289 }
14290 }
14291 }
14292
14293 for (vnp = trunc_list; vnp != NULL; vnp = vnp->next) {
14294 vnp->data.ptrvalue = SeqIdFree (vnp->data.ptrvalue);
14295 }
14296 trunc_list = ValNodeFree (trunc_list);
14297
14298 ObjMgrSetDirtyFlag (dlg->input_entityID, TRUE);
14299 ObjMgrSendMsg (OM_MSG_UPDATE, dlg->input_entityID, 0, 0);
14300 Update ();
14301 }
14302
14303
TruncateByProtAlign(IteM i)14304 NLM_EXTERN void TruncateByProtAlign (IteM i)
14305 {
14306 BaseFormPtr bfp;
14307 TruncateByProtAlignPtr dlg;
14308 WindoW w;
14309 GrouP h, g, c;
14310 ButtoN b;
14311 SeqEntryPtr sep;
14312 SeqAlignPtr salp;
14313
14314 #ifdef WIN_MAC
14315 bfp = currentFormDataPtr;
14316 #else
14317 bfp = GetObjectExtra (i);
14318 #endif
14319 if (bfp == NULL) return;
14320
14321 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
14322 if (sep == NULL) return;
14323 salp = ReadAlignmentForSeqEntry (sep, FALSE, TRUE, FALSE);
14324 if (salp == NULL) {
14325 return;
14326 }
14327
14328 dlg = (TruncateByProtAlignPtr) MemNew (sizeof (TruncateByProtAlignData));
14329 dlg->input_entityID = bfp->input_entityID;
14330
14331 dlg->salp = salp;
14332
14333 w = FixedWindow (-50, -33, -10, -10, "Mark Truncated Products by Protein Alignment", StdCloseWindowProc);
14334 SetObjectExtra (w, dlg, StdCleanupExtraProc);
14335 dlg->form = (ForM) w;
14336
14337 h = HiddenGroup (w, -1, 0, NULL);
14338 SetGroupSpacing (h, 10, 10);
14339
14340 g = HiddenGroup (h, 2, 0, NULL);
14341 StaticPrompt (g, "Missing amino acids for truncation:", 0, dialogTextHeight, programFont, 'r');
14342 dlg->num_missing = DialogText (g, "10", 0, NULL);
14343 c = HiddenGroup (h, 4, 0, NULL);
14344 SetGroupSpacing (c, 10, 10);
14345
14346 b = PushButton (c, "Make List", ShowTruncateList);
14347 SetObjectExtra (b, dlg, NULL);
14348 b = PushButton (c, "Mark List", MarkTruncateList);
14349 SetObjectExtra (b, dlg, NULL);
14350
14351 b = PushButton (c, "Dismiss", StdCancelButtonProc);
14352
14353 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
14354 RealizeWindow (w);
14355 Show (w);
14356 Update ();
14357 }
14358
14359
14360
14361 typedef struct frameshiftdlg {
14362 FORM_MESSAGE_BLOCK
14363
14364 WindoW aln_window;
14365 DoC doc;
14366
14367 SeqAlignPtr salp;
14368 SeqAnnotPtr sanp;
14369 ValNodePtr report_list;
14370 Boolean any_exons;
14371
14372 FonT title_font;
14373 } FrameShiftDlgData, PNTR FrameShiftDlgPtr;
14374
14375
CleanupFrameShiftDlg(GraphiC g,VoidPtr data)14376 static void CleanupFrameShiftDlg (GraphiC g, VoidPtr data)
14377
14378 {
14379 FrameShiftDlgPtr dlg;
14380
14381 dlg = (FrameShiftDlgPtr) data;
14382 if (dlg != NULL)
14383 {
14384 if (dlg->aln_window != NULL) {
14385 RemoveSeqEdCloseFunc (dlg->aln_window);
14386 Remove (dlg->aln_window);
14387 }
14388 dlg->sanp = SeqAnnotFree (dlg->sanp);
14389 dlg->report_list = FrameShiftReportListFree (dlg->report_list);
14390 }
14391 StdCleanupFormProc (g, data);
14392 }
14393
14394
ResetFrameshiftWindow(Pointer data)14395 static void ResetFrameshiftWindow (Pointer data)
14396 {
14397 FrameShiftDlgPtr dlg;
14398
14399 if ((dlg = (FrameShiftDlgPtr) data) != NULL) {
14400 dlg->aln_window = NULL;
14401 }
14402 }
14403
14404
ClickFrameShiftList(DoC d,PoinT pt)14405 static void ClickFrameShiftList (DoC d, PoinT pt)
14406
14407 {
14408 Int2 item;
14409 Int2 row, i;
14410 FrameShiftDlgPtr dlg;
14411 ValNodePtr vnp;
14412 FrameShiftReportPtr fr;
14413 Uint1 last_choice = eFrameShiftReport_NoReport;
14414
14415 /* TODO - skip headers after headers are added */
14416
14417 dlg = GetObjectExtra (d);
14418 if (dlg != NULL) {
14419 MapDocPoint (d, pt, &item, &row, NULL, NULL);
14420 if (item > 0 && row > 0) {
14421 if (item == 1 || item == 2) {
14422 vnp = dlg->report_list;
14423 } else {
14424 i = 1;
14425 vnp = dlg->report_list;
14426 while (i < item && vnp != NULL) {
14427 i++;
14428 vnp = vnp->next;
14429 if (vnp->choice != last_choice) {
14430 i++;
14431 last_choice = vnp->choice;
14432 }
14433 }
14434 }
14435 if (vnp != NULL && (fr = (FrameShiftReportPtr) vnp->data.ptrvalue) != NULL) {
14436 /* navigage alignment window to coordinate */
14437 if (dlg->aln_window == NULL) {
14438 dlg->aln_window = (WindoW) CreateAlnEditorWindowEx (33, 50, "Frameshift Alignment", dlg->salp, dlg->input_entityID, ResetFrameshiftWindow, dlg);
14439 Show (dlg->aln_window);
14440 }
14441 SeqAlnWindowScrollToAlnPos (dlg->aln_window, fr->aln_pos - 1, fr->first_related_seq);
14442 }
14443 }
14444 }
14445 }
14446
14447
14448 static Nlm_ParData frameshiftParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
14449 static Nlm_ColData frameshiftColFmt = {500, 0, 0, 0, NULL, 'l', 0,0,0,0, TRUE};
14450
PopulateFrameShiftList(FrameShiftDlgPtr dlg,ValNodePtr list)14451 static void PopulateFrameShiftList (FrameShiftDlgPtr dlg, ValNodePtr list)
14452 {
14453 FrameShiftReportPtr fr;
14454 Int2 numItems;
14455 RecT r;
14456 Uint1 last_choice = eFrameShiftReport_NoReport;
14457
14458 if (dlg == NULL || dlg->doc == NULL)
14459 {
14460 return;
14461 }
14462
14463 Reset (dlg->doc);
14464
14465 ObjectRect (dlg->doc, &r);
14466 InsetRect (&r, 4, 4);
14467 frameshiftColFmt.pixWidth = r.right - r.left;
14468
14469 while (list != NULL)
14470 {
14471 if (list->choice != last_choice) {
14472 if (list->choice == eFrameShiftReport_Exon) {
14473 AppendText (dlg->doc, "FRAMESHIFTS IN EXONS", &frameshiftParFmt, &frameshiftColFmt, dlg->title_font);
14474 } else if (list->choice == eFrameShiftReport_Intron) {
14475 if (dlg->any_exons) {
14476 AppendText (dlg->doc, "FRAMESHIFTS IN INTRONS", &frameshiftParFmt, &frameshiftColFmt, dlg->title_font);
14477 } else {
14478 AppendText (dlg->doc, "FRAMESHIFTS", &frameshiftParFmt, &frameshiftColFmt, dlg->title_font);
14479 }
14480 } else if (list->choice == eFrameShiftReport_ExonMult3) {
14481 AppendText (dlg->doc, "MULTIPLES OF THREE ARE IGNORED", &frameshiftParFmt, &frameshiftColFmt, dlg->title_font);
14482 }
14483 last_choice = list->choice;
14484 }
14485 fr = (FrameShiftReportPtr) list->data.ptrvalue;
14486 AppendText (dlg->doc, fr->msg, &frameshiftParFmt, &frameshiftColFmt, programFont);
14487 list = list->next;
14488 }
14489 GetDocParams (dlg->doc, &numItems, NULL);
14490 UpdateDocument (dlg->doc, 0, numItems);
14491
14492 }
14493
14494
MakeFrameShiftReport(ButtoN b)14495 static void MakeFrameShiftReport (ButtoN b)
14496 {
14497 FrameShiftDlgPtr dlg;
14498 LogInfoPtr lip;
14499
14500 dlg = (FrameShiftDlgPtr) GetObjectExtra (b);
14501 if (dlg == NULL) {
14502 return;
14503 }
14504
14505 lip = OpenLog ("Frame Shift Report");
14506 PrintFrameShiftReportList (dlg->report_list, dlg->any_exons, FALSE, lip);
14507 CloseLog (lip);
14508 lip = FreeLog (lip);
14509 }
14510
14511
14512
FrameShiftFinderEntityID(Uint2 entityID,Boolean from_clipboard)14513 NLM_EXTERN void FrameShiftFinderEntityID (Uint2 entityID, Boolean from_clipboard)
14514 {
14515 SeqEntryPtr sep;
14516 SeqAlignPtr salp=NULL;
14517 SeqAnnotPtr sanp;
14518 ValNodePtr report_list;
14519 Boolean has_exons = FALSE;
14520 FrameShiftDlgPtr dlg;
14521 WindoW w;
14522 GrouP h, c;
14523 ButtoN b;
14524
14525 sep = GetTopSeqEntryForEntityID (entityID);
14526 if (sep == NULL) return;
14527
14528 salp = ReadAlignmentForSeqEntry (sep, TRUE, FALSE, from_clipboard);
14529 if (salp == NULL) {
14530 return;
14531 }
14532 sanp = SeqAnnotNew ();
14533 sanp->type = 2;
14534 sanp->data = salp;
14535 salp->idx.parentptr = sanp;
14536 salp->idx.parenttype = OBJ_SEQANNOT;
14537
14538 /* now look for frame shifts */
14539 report_list = FindFrameShiftsInAlignment (salp, &has_exons);
14540
14541 dlg = (FrameShiftDlgPtr) MemNew (sizeof (FrameShiftDlgData));
14542
14543 w = FixedWindow (-50, -33, -10, -10, "FrameShift Finder", StdCloseWindowProc);
14544 dlg->form = (ForM) w;
14545 SetObjectExtra (w, dlg, CleanupFrameShiftDlg);
14546 dlg->input_entityID = entityID;
14547 dlg->salp = salp;
14548 dlg->report_list = report_list;
14549 dlg->any_exons = has_exons;
14550 dlg->aln_window = NULL;
14551
14552 dlg->title_font = GetFont ("Arial", 12, TRUE, FALSE, FALSE, "");
14553
14554 h = HiddenGroup (w, -1, 0, NULL);
14555 dlg->doc = DocumentPanel (h, 900, stdLineHeight * 20);
14556 SetObjectExtra (dlg->doc, dlg, NULL);
14557 SetDocAutoAdjust (dlg->doc, FALSE);
14558 SetDocProcs (dlg->doc, ClickFrameShiftList, NULL, NULL, NULL);
14559 PopulateFrameShiftList (dlg, dlg->report_list);
14560
14561 c = HiddenGroup (h, 4, 0, NULL);
14562 b = PushButton (c, "Make Report", MakeFrameShiftReport);
14563 SetObjectExtra (b, dlg, NULL);
14564 PushButton (c, "Cancel", StdCancelButtonProc);
14565
14566 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->doc, (HANDLE) c, NULL);
14567 RealizeWindow (w);
14568 Show (w);
14569 Update ();
14570
14571 }
14572
14573
FrameShiftFinderEx(IteM i,Boolean from_clipboard)14574 static void FrameShiftFinderEx (IteM i, Boolean from_clipboard)
14575 {
14576 BaseFormPtr bfp;
14577
14578 #ifdef WIN_MAC
14579 bfp = currentFormDataPtr;
14580 #else
14581 bfp = GetObjectExtra (i);
14582 #endif
14583 if (bfp == NULL) return;
14584
14585 FrameShiftFinderEntityID (bfp->input_entityID, from_clipboard);
14586 }
14587
14588
FrameShiftFinder(IteM i)14589 NLM_EXTERN void FrameShiftFinder (IteM i)
14590 {
14591 FrameShiftFinderEx (i, FALSE);
14592 }
14593
14594
FrameShiftFinderClipboard(IteM i)14595 NLM_EXTERN void FrameShiftFinderClipboard (IteM i)
14596 {
14597 FrameShiftFinderEx (i, TRUE);
14598 }
14599