1 /* sequin9.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: sequin9.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 4/20/99
31 *
32 * $Revision: 6.529 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44
45 #include <subutil.h>
46 #include <explore.h>
47 #include <alignmgr.h>
48 #include <urkptpf.h>
49 #include <entrez.h>
50 #include <accentr.h>
51 #include <urlquery.h>
52 #include <vecscrn.h>
53 #include <vecscnapi.h>
54 #include <qblastapi.h>
55 #include <edutil.h>
56 #include <actutils.h>
57 #include <findrepl.h>
58 #include <rpsutil.h>
59 #include "sequin.h"
60 #include <seqpanel.h>
61 #include <salpanel.h>
62 #include <assert.h>
63 #include <pmfapi.h>
64 #include <vsm.h>
65 #define NLM_GENERATED_CODE_PROTO
66 #include <objmacro.h>
67 #include <macrodlg.h>
68 #include <macroapi.h>
69
70 /*-------------------*/
71 /* Defined Constants */
72 /*-------------------*/
73
74 #define MAX_ID_LEN 84
75 #define FASTA_READ_OK 0
76 #define FASTA_READ_ERROR -1
77 #define FASTA_READ_DONE 1
78
79 #define CONVERTPUBS_NOT_SET 0
80 #define CONVERTPUBS_YES 1
81 #define CONVERTPUBS_NO 2
82
83 /* constants for update sequence */
84 #define UPDATE_CHOICE_NOT_SET 0
85 #define UPDATE_SEQUENCE_ONLY 1
86 #define UPDATE_FEATURES_ONLY 2
87 #define UPDATE_SEQUENCE_AND_FEATURES 3
88
89 #define UPDATE_REPLACE 1
90 #define UPDATE_EXTEND5 2
91 #define UPDATE_EXTEND3 3
92 #define UPDATE_PATCH 4
93
94 enum update_dup_feat_type
95 {
96 UPDATE_FEAT_DUP_NOT_SET = 0,
97 UPDATE_FEAT_DUP_USE_NEW,
98 UPDATE_FEAT_DUP_USE_OLD,
99 UPDATE_FEAT_DUP_USE_BOTH,
100 UPDATE_FEAT_DUP_MERGE,
101 UPDATE_FEAT_DUP_REPLACE
102 };
103
104
105 /*-----------------*/
106 /* Data Structures */
107 /*-----------------*/
108
109 typedef struct {
110 Char newId[MAX_ID_LEN];
111 BioseqPtr matchingBsp;
112 } UpdateData, PNTR UpdateDataPtr;
113
114 typedef struct upsdata {
115 FORM_MESSAGE_BLOCK
116 ButtoN accept;
117 ButtoN acceptAll;
118 CharPtr aln1;
119 CharPtr aln2;
120 Int4 aln_length;
121 Int2 charwidth;
122 Int2 convertPubs;
123 VieweR details;
124 Boolean diffOrgs;
125 SegmenT dtpict;
126 FILE *fp;
127 ValNodePtr indels;
128 Boolean isSet;
129 ButtoN keepProteinIDs;
130 PaneL letters;
131 Int2 lineheight;
132 Int4 log10_aln_length;
133 Int2 maxchars;
134 ValNodePtr mismatches;
135 Int4 new3;
136 Int4 new5;
137 Int4 newa;
138 BioseqPtr newbsp;
139 ButtoN replace_all;
140 GrouP nobm;
141 Int4 old3;
142 Int4 old5;
143 Int4 olda;
144 BioseqPtr oldbsp;
145 VieweR overview;
146 SegmenT ovpict;
147 Int4 recomb1;
148 Int4 recomb2;
149 Boolean revcomp;
150 GrouP rmc;
151 SeqAlignPtr salp;
152 Int4 scaleX;
153 CharPtr seq1;
154 CharPtr seq2;
155 GrouP sfb;
156 Int4 startmax;
157 Int4 stopmax;
158 Uint1 strandnew;
159 Uint1 strandold;
160 Boolean useGUI;
161 Boolean do_update;
162 ButtoN add_cit_subs;
163 ButtoN update_proteins;
164 Boolean suppress_continue_msg;
165 Boolean suppress_instant_refresh;
166 ButtoN update_quality_scores_btn;
167 FILE *log_fp;
168 Char log_path [PATH_MAX];
169 Boolean data_in_log;
170 ButtoN truncate_proteins_btn;
171 ButtoN extend_proteins5_btn;
172 ButtoN extend_proteins3_btn;
173 ButtoN correct_cds_genes_btn;
174 Boolean truncate_proteins;
175 Boolean extend_proteins5;
176 Boolean extend_proteins3;
177 Boolean correct_cds_genes;
178 ValNodePtr transl_except_list;
179 Int2 rmcval; /* This is the choice selected from the
180 * rmc radio button group.
181 * We store it so that we can use it in
182 * Accept All.
183 */
184
185 SeqEntryPtr seqsubsep; /* when we are updating from a Sequin record
186 * that contains a set, store the set here.
187 */
188 Int4 seqsubpos; /* when we are updating from a Sequin record
189 * that contains a set, store the number of
190 * Bioseqs already processed here.
191 */
192
193 Int2 no_aln_choice; /* what to do when updating a set and no
194 * alignment is found.
195 */
196
197 ValNodePtr affected_variation_features; /* list of variation features
198 * affected by this update.
199 * by "affected" we mean that
200 * an insertion, deletion,
201 * or replacement takes place
202 * either inside the variation
203 * location, or immediately
204 * to the left or right of the
205 * location.
206 */
207 } UpsData, PNTR UpsDataPtr;
208
209 /*---------------------*/
210 /* Function prototypes */
211 /*---------------------*/
212
213 static Int2 UpdateNextBioseqInFastaSet (UpsDataPtr udp);
214 static void FreeUdpFields (UpsDataPtr udp);
215 static void TruncateCDS (SeqFeatPtr sfp, Uint1 frame, BioseqPtr pbsp);
216
217 extern void SubmitToNCBI (IteM i);
218 extern void QuitProc (void);
219 extern void NewFeaturePropagate (IteM i);
220 extern void FuseSlpJoins (IteM i);
221
222 /*-----------*/
223 /* Functions */
224 /*-----------*/
225
226 /*
227 * This function is called by HandleOneNewAsnProc, CommonHandleMultBioseqs,
228 * and DoReadAnythingLoop in sequin1.c
229 */
HandleProjectAsn(ProjectPtr proj,Uint2 entityID)230 extern void HandleProjectAsn (ProjectPtr proj, Uint2 entityID)
231
232 {
233 Int2 db = -1;
234 EntrezGlobalsPtr egp;
235 Int4 i;
236 ValNodePtr list;
237 Int4 num;
238 ValNodePtr pip;
239 Int4Ptr uids;
240 ValNodePtr vnp;
241
242 if (proj == NULL) return;
243 if (! useEntrez) return;
244 egp = (EntrezGlobalsPtr) GetAppProperty ("EntrezGlobals");
245 if (egp == NULL) return;
246 pip = proj->data;
247 if (pip == NULL) return;
248 list = (ValNodePtr) pip->data.ptrvalue;
249 if (list == NULL) return;
250 if (pip->choice >= ProjectItem_protent && pip->choice <= ProjectItem_genomeent) {
251 if (egp->retrieveProjectProc == NULL) return;
252 /*
253 if (! EntrezIsInited ()) {
254 SequinEntrezInit ("Sequin", FALSE, NULL);
255 }
256 */
257 egp->retrieveProjectProc (NULL, (Pointer) proj);
258 Update ();
259 return;
260 }
261 if (egp->retrieveDocsProc == NULL) return;
262 switch (pip->choice) {
263 case ProjectItem_pmuid :
264 db = 0;
265 break;
266 case ProjectItem_protuid :
267 db = 1;
268 break;
269 case ProjectItem_nucuid :
270 db = 2;
271 break;
272 case ProjectItem_genomeuid :
273 db = 4;
274 break;
275 case ProjectItem_structuid :
276 db = 3;
277 break;
278 default :
279 break;
280 }
281 if (db == -1) return;
282 /*
283 if (! EntrezIsInited ()) {
284 SequinEntrezInit ("Sequin", FALSE, NULL);
285 }
286 */
287 num = ValNodeLen (list);
288 uids = MemNew ((size_t) (num * sizeof (Int4)));
289 if (uids == NULL) return;
290 for (i = 0, vnp = list; i < 32766 && vnp != NULL; i++, vnp = vnp->next) {
291 uids [i] = vnp->data.intvalue;
292 }
293 if (egp->retrieveDocsProc != NULL) {
294 egp->retrieveDocsProc (NULL, (Int2) num, 0, uids, db);
295 }
296 MemFree (uids);
297 Update ();
298 }
299
300 /* BioseqViewOrDocSumChoice allows a single callback for each analysis item */
BioseqViewOrDocSumChoice(NewObjectPtr nop)301 static Int2 BioseqViewOrDocSumChoice (NewObjectPtr nop)
302
303 {
304 Int2 which = 0; /* 1 = bioseq viewer, 2 = docsum window */
305
306 if (nop == NULL) return 0;
307 #ifdef WIN_MAC
308 if (bioseqViewUp) {
309 which = 1;
310 } else if (docSumUp) {
311 which = 2;
312 }
313 #else
314 if (nop->bspOK) {
315 which = 1;
316 } else if (nop->dsmOK) {
317 which = 2;
318 }
319 #endif
320 return which;
321 }
322
323 /*
324 #define TEST_APPLE_EVENT_MESSAGING
325 */
326
327 #ifndef TEST_APPLE_EVENT_MESSAGING
AddRestrictionSite(SeqAnnotPtr annot,PackSeqPntPtr pspp,CharPtr name)328 static void AddRestrictionSite (SeqAnnotPtr annot, PackSeqPntPtr pspp, CharPtr name)
329
330 {
331 DbtagPtr dbt;
332 ObjectIdPtr oip;
333 RsiteRefPtr rrp;
334 SeqFeatPtr sfp, lastsfp;
335 SeqLocPtr slp;
336
337 if (annot == NULL || pspp == NULL || name == NULL) return;
338 slp = ValNodeNew (NULL);
339 if (slp == NULL) return;
340 slp->choice = SEQLOC_PACKED_PNT;
341 slp->data.ptrvalue = (Pointer) pspp;
342 sfp = SeqFeatNew ();
343 if (sfp == NULL) return;
344
345 sfp->data.choice = SEQFEAT_RSITE;
346 sfp->location = slp;
347 dbt = DbtagNew ();
348 if (dbt != NULL) {
349 dbt->db = StringSave ("REBASE");
350 oip = ObjectIdNew ();
351 if (oip != NULL) {
352 oip->str = StringSave (name);
353 }
354 dbt->tag = oip;
355 }
356 rrp = ValNodeNew (NULL);
357 if (rrp != NULL) {
358 rrp->choice = 2;
359 rrp->data.ptrvalue = dbt;
360 }
361 sfp->data.value.ptrvalue = (Pointer) rrp;
362
363 if (annot->data == NULL) {
364 annot->data = (Pointer) sfp;
365 } else {
366 lastsfp = (SeqFeatPtr) annot->data;
367 while (lastsfp->next != NULL) {
368 lastsfp = lastsfp->next;
369 }
370 lastsfp->next = sfp;
371 }
372 }
373
RestrictionSearchProc(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)374 static void RestrictionSearchProc (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
375
376 {
377 SeqAnnotPtr annot;
378 BioseqPtr bsp;
379 ComPatPtr cpp, cpph;
380 ValNodePtr desc;
381 SeqAnnotPtr lastannot;
382 PackSeqPntPtr pspp;
383 Int4 pt;
384 SeqAlignPtr sap;
385 SeqLocPtr slp, slpn;
386
387 if (sep == NULL) return;
388 if (! IS_Bioseq (sep)) return;
389 bsp = (BioseqPtr) sep->data.ptrvalue;
390 if (bsp == NULL) return;
391 if (! ISA_na (bsp->mol)) return;
392
393 desc = SeqDescrNew (NULL);
394 desc->choice = Annot_descr_name;
395 desc->data.ptrvalue = StringSave ("cutsites");
396
397 annot = SeqAnnotNew ();
398 annot->type = 1;
399 annot->desc = desc;
400 annot->data = NULL;
401
402 cpph = (ComPatPtr) mydata;
403 cpp = cpph;
404 while (cpp != NULL) {
405 sap = PatternMatchBioseq (bsp, cpp, 0);
406 slp = MatchSa2Sl (&sap);
407 if (slp != NULL) {
408 pspp = PackSeqPntNew ();
409 pspp->id = SeqIdDup (SeqIdFindBest (bsp->id, 0));
410 while (slp != NULL) {
411 pt = SeqLocStart (slp);
412 PackSeqPntPut (pspp, pt);
413 slpn = slp->next;
414 SeqLocFree (slp);
415 slp = slpn;
416 }
417 AddRestrictionSite (annot, pspp, cpp->name);
418 }
419 cpp = cpp->nextpattern;
420 }
421
422 if (annot->data == NULL) {
423 SeqAnnotFree (annot);
424 return;
425 }
426 if (bsp->annot == NULL) {
427 bsp->annot = annot;
428 } else {
429 lastannot = bsp->annot;
430 while (lastannot->next != NULL) {
431 lastannot = lastannot->next;
432 }
433 lastannot->next = annot;
434 }
435 }
436 #endif
437
SimpleRsiteProc(IteM i)438 static void SimpleRsiteProc (IteM i)
439
440 {
441 BaseFormPtr bfp;
442 BioseqPtr bsp;
443 NewObjectPtr nop;
444 SeqEntryPtr sep = NULL;
445 Int2 which;
446 #ifdef TEST_APPLE_EVENT_MESSAGING
447 AsnIoPtr aip;
448 Char tmp [PATH_MAX];
449 #else
450 ComPatPtr cpph;
451 Char enzyme [64];
452 Int2 j;
453 Char temp [32];
454 ValNodePtr enzymes;
455 #endif
456
457 nop = (NewObjectPtr) GetObjectExtra (i);
458 if (nop == NULL) return;
459 #ifdef WIN_MAC
460 bfp = (BaseFormPtr) currentFormDataPtr;
461 #else
462 bfp = nop->bfp;
463 #endif
464 if (bfp == NULL) return;
465 which = BioseqViewOrDocSumChoice (nop);
466 if (which != 1) return;
467 bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
468 if (bsp != NULL) {
469 sep = SeqMgrGetSeqEntryForData (bsp);
470 } else {
471 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
472 }
473 if (sep == NULL) return;
474
475 #ifdef TEST_APPLE_EVENT_MESSAGING
476 TmpNam (tmp);
477 aip = AsnIoOpen (tmp, "w");
478 if (aip != NULL) {
479 SeqEntryAsnWrite (sep, aip, NULL);
480 AsnIoClose (aip);
481 /* Nlm_SendOpenDocAppleEventEx (tmp, "REST", NULL, TRUE); */
482 Nlm_SendOpenDocAppleEventEx (tmp, NULL, "RsiteFind", TRUE);
483 }
484 #else
485 enzymes = NULL;
486 j = 1;
487 sprintf (temp, "ENZ_%d", (int) j);
488 while (GetAppParam ("SEQNCGIS", "ENZYMES", temp, NULL, enzyme, sizeof (enzyme) - 1)) {
489 ValNodeCopyStr (&enzymes, 0, enzyme);
490 j++;
491 sprintf (temp, "ENZ_%d", (int) j);
492 }
493 if (enzymes == NULL) {
494 ValNodeCopyStr (&enzymes, 0, "BamHI");
495 ValNodeCopyStr (&enzymes, 0, "EcoRI");
496 ValNodeCopyStr (&enzymes, 0, "HindIII");
497 }
498 cpph = ReadRENPattern ("ncbiren.dat", FALSE, enzymes);
499 /* PalindromeCheck (cpph); */
500 SeqEntryExplore (sep, (Pointer) cpph, RestrictionSearchProc);
501 ComPatFree (cpph);
502 ValNodeFreeData (enzymes);
503
504 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
505 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
506 Update ();
507 #endif
508 }
509
510 static VQUEUE vsquerylist = NULL;
511
512 static Int2 vsquerynum = 0;
513
514 /*
515 static void LIBCALLBACK AnnounceCallback (CharPtr requestID, CharPtr seqID, Int2 estimatedSeconds)
516
517 {
518 if (StringHasNoText (requestID)) {
519 requestID = "?";
520 }
521 if (StringHasNoText (seqID)) {
522 seqID = "?";
523 }
524 Message (MSG_POST, "Queued rID %s, seqID %s, estimated seconds = %d",
525 requestID, seqID, (int) estimatedSeconds);
526
527 vsquerynum++;
528 }
529
530 static Boolean LIBCALLBACK VecScreenCallback (
531 CharPtr filename,
532 VoidPtr userdata,
533 CharPtr requestID,
534 CharPtr seqID,
535 Boolean success
536 )
537
538 {
539 if (StringHasNoText (requestID)) {
540 requestID = "?";
541 }
542 if (StringHasNoText (seqID)) {
543 seqID = "?";
544 }
545 if (success) {
546 if (! SequinHandleNetResults (filename)) {
547 }
548 } else {
549 Message (MSG_POST, "Failure of rID '%s', seqID %s", requestID, seqID);
550 }
551 return TRUE;
552 }
553
554 static void DoVecScreens (BioseqPtr bsp, Pointer userdata)
555
556 {
557 CharPtr service;
558
559 if (bsp == NULL || ISA_aa (bsp->mol)) return;
560 service = (CharPtr) userdata;
561 VecScreenAsynchronousRequest (service, bsp, &vsquerylist, VecScreenCallback, AnnounceCallback, NULL);
562 }
563
564 static void SimpleVecScreenCommon (IteM i, CharPtr service)
565
566 {
567 BaseFormPtr bfp;
568 BioseqPtr bsp;
569 NewObjectPtr nop;
570 SeqEntryPtr sep = NULL;
571 Int2 which;
572
573 nop = (NewObjectPtr) GetObjectExtra (i);
574 if (nop == NULL) return;
575 #ifdef WIN_MAC
576 bfp = (BaseFormPtr) currentFormDataPtr;
577 #else
578 bfp = nop->bfp;
579 #endif
580 if (bfp == NULL) return;
581 which = BioseqViewOrDocSumChoice (nop);
582 if (which != 1) return;
583 bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
584 if (bsp != NULL) {
585 sep = SeqMgrGetSeqEntryForData (bsp);
586 if (sep == NULL) return;
587 VecScreenAsynchronousRequest (service, bsp, &vsquerylist, VecScreenCallback, AnnounceCallback, NULL);
588 } else {
589 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
590 if (sep == NULL) return;
591 VisitBioseqsInSep (sep, (Pointer) service, DoVecScreens);
592 }
593 }
594 */
595
596 typedef struct vsdata {
597 CharPtr date;
598 CharPtr path;
599 CharPtr database;
600 Boolean changed;
601 Int4 count;
602 MonitorPtr mon;
603 } VsData, PNTR VsDataPtr;
604
605 static CharPtr vectorStrengths [6] = {
606 NULL,
607 "Strong match",
608 "Moderate match",
609 "Weak match",
610 "Suspect origin",
611 "Unknown vector match"
612 };
613
CountVecScreens(BioseqPtr bsp,Pointer userdata)614 static void CountVecScreens (BioseqPtr bsp, Pointer userdata)
615
616 {
617 Int4Ptr maxp;
618
619 if (bsp == NULL || ISA_aa (bsp->mol)) return;
620 maxp = (Int4Ptr) userdata;
621 (*maxp)++;
622 }
623
DoVecScreens(BioseqPtr bsp,Pointer userdata)624 static void DoVecScreens (BioseqPtr bsp, Pointer userdata)
625
626 {
627 AnnotDescrPtr desc;
628 GeneRefPtr grp;
629 Int2 hits;
630 ImpFeatPtr ifp;
631 ValNodePtr locs = NULL;
632 Char note [128];
633 SeqAnnotPtr prevsap;
634 SeqFeatPtr prevsfp;
635 SeqAnnotPtr sap = NULL;
636 SeqFeatPtr sfp = NULL;
637 SeqIdPtr sip;
638 SeqLocPtr slp;
639 Int4 start;
640 Int4 stop;
641 Uint1 strength;
642 SeqLocPtr tmp;
643 VsDataPtr vsp;
644 ValNodePtr vnp;
645 SeqFeatXrefPtr xref;
646
647 if (bsp == NULL || ISA_aa (bsp->mol)) return;
648 vsp = (VsDataPtr) userdata;
649 if (vsp == NULL) return;
650 sip = SeqIdFindBest (bsp->id, 0);
651 if (sip == NULL) return;
652
653 if (vsp->mon != NULL) {
654 MonitorIntValue (vsp->mon, vsp->count);
655 }
656 (vsp->count)++;
657
658 hits = VSScreenSequence (bsp, NULL, vsp->path, NULL, &locs, NULL, NULL);
659 for (vnp = locs; vnp != NULL; vnp = vnp->next) {
660 strength = vnp->choice;
661 if (strength < 1 || strength > 4) {
662 strength = 5;
663 }
664 slp = (SeqLocPtr) vnp->data.ptrvalue;
665 if (slp == NULL) continue;
666 if (slp->choice == SEQLOC_PACKED_INT) {
667 for (tmp = (SeqLocPtr) slp->data.ptrvalue; tmp != NULL; tmp = tmp->next) {
668 start = SeqLocStart (tmp);
669 stop = SeqLocStop (tmp);
670 if (start < 0 || stop < 0) continue;
671 vsp->changed = TRUE;
672
673 if (sap == NULL) {
674 sap = SeqAnnotNew ();
675 if (sap != NULL) {
676 sap->type = 1;
677 desc = AnnotDescrNew (NULL);
678 if (desc != NULL) {
679 desc->choice = Annot_descr_name;
680 desc->data.ptrvalue = StringSave ("VecScreen");
681 sap->desc = desc;
682 }
683 }
684 }
685
686 sfp = SeqFeatNew ();
687 if (sfp != NULL) {
688
689 /* make misc_feature for now */
690
691 sfp->data.choice = SEQFEAT_IMP;
692 ifp = ImpFeatNew ();
693 if (ifp != NULL) {
694 ifp->key = StringSave ("misc_feature");
695 }
696 AddQualifierToFeature (sfp, "standard_name", "Vector Contamination");
697 AddQualifierToFeature (sfp, "phenotype", vectorStrengths [(int) strength]);
698
699 sprintf (note, "Screened against %s using VecScreen on %s", vsp->database, vsp->date);
700 sfp->comment = StringSave (note);
701
702 /* suppress /gene */
703
704 grp = GeneRefNew ();
705 if (grp != NULL) {
706 xref = SeqFeatXrefNew ();
707 sfp->xref = xref;
708 if (xref != NULL) {
709 xref->data.choice = SEQFEAT_GENE;
710 xref->data.value.ptrvalue = (Pointer) grp;
711 }
712 }
713
714 sfp->data.value.ptrvalue = (Pointer) ifp;
715
716 if (sap != NULL) {
717 if (sap->data != NULL) {
718 prevsfp = sap->data;
719 while (prevsfp->next != NULL) {
720 prevsfp = prevsfp->next;
721 }
722 prevsfp->next = sfp;
723 } else {
724 sap->data = (Pointer) sfp;
725 }
726 }
727
728 sfp->location = AddIntervalToLocation (NULL, sip, (Int4) start, (Int4) stop, FALSE, FALSE);
729 }
730 }
731 }
732 SeqLocFree (slp);
733 }
734 locs = ValNodeFree (locs);
735
736 if (sap != NULL) {
737 if (bsp->annot != NULL) {
738 prevsap = bsp->annot;
739 while (prevsap->next != NULL) {
740 prevsap = prevsap->next;
741 }
742 prevsap->next = sap;
743 } else {
744 bsp->annot = sap;
745 }
746 }
747 }
748
749
VsDataFree(VsDataPtr vsp)750 static VsDataPtr VsDataFree (VsDataPtr vsp)
751 {
752 if (vsp != NULL) {
753 vsp->date = MemFree (vsp->date);
754 vsp->path = MemFree (vsp->path);
755 vsp = MemFree (vsp);
756 }
757 return vsp;
758 }
759
760
InitVecScreenData(CharPtr database)761 static VsDataPtr InitVecScreenData (CharPtr database)
762
763 {
764 VsDataPtr vsp;
765 Char path [PATH_MAX];
766 CharPtr pathplusone;
767 Char quote [4];
768 Char date [32];
769 DatePtr dp;
770 CharPtr check_existence;
771 CharPtr ptr;
772 Boolean no_ncbi_data = FALSE;
773 struct stat buffer;
774
775 vsp = (VsDataPtr) MemNew (sizeof (VsData));
776 MemSet (vsp, 0, sizeof (VsData));
777 path [0] = '"';
778 path [1] = '\0';
779 pathplusone = &(path [1]);
780 GetAppParam ("NCBI", "NCBI", "DATA", "", pathplusone, sizeof (path) - 1);
781 if (StringHasNoText (pathplusone)) {
782 no_ncbi_data = TRUE;
783 }
784
785 /*
786 if (StringChr (path, ' ') != NULL) {
787 Message (MSG_OK, "Unable to process because vector database file\npath must not have a space character. Path is:\n'%s'", path);
788 return;
789 }
790 */
791
792 FileBuildPath (pathplusone, NULL, database);
793
794 quote [0] = '"';
795 quote [1] = '\0';
796 StringCat (pathplusone, quote);
797
798 date [0] = '\0';
799 dp = DateCurr ();
800 DatePrint (dp, date);
801 DateFree (dp);
802
803 check_existence = (CharPtr) MemNew (sizeof (Char) * (StringLen (pathplusone) + 5));
804 StringNCpy (check_existence, pathplusone, StringLen (pathplusone) - 1);
805 StringCat (check_existence, ".nsq");
806
807 if (stat (check_existence, &buffer) != 0) {
808 if (no_ncbi_data) {
809 ProgramPath (path, sizeof (path));
810 ptr = StringRChr (path, DIRDELIMCHR);
811 if (ptr != NULL) {
812 ptr++;
813 *ptr = '\0';
814 }
815 Message (MSG_ERROR, "No database files at %s", path);
816 } else {
817 Message (MSG_ERROR, "No database files at %s", check_existence);
818 }
819 vsp = VsDataFree(vsp);
820 check_existence = MemFree (check_existence);
821 return vsp;
822 }
823 check_existence = MemFree (check_existence);
824
825 vsp->date = StringSave(date);
826 vsp->path = StringSave(path);
827 vsp->database = database;
828 vsp->changed = FALSE;
829 vsp->count = 0;
830 vsp->mon = NULL;
831 return vsp;
832 }
833
834
VecScreenAll(Uint2 entityID)835 NLM_EXTERN void VecScreenAll (Uint2 entityID)
836
837 {
838 SeqEntryPtr sep;
839 Int4 max;
840 VsDataPtr vsp;
841
842 vsp = InitVecScreenData("UniVec_Core");
843 if (vsp == NULL) {
844 return;
845 }
846 sep = GetTopSeqEntryForEntityID (entityID);
847 if (sep == NULL) return;
848 max = 0;
849 VisitBioseqsInSep (sep, (Pointer) &max, CountVecScreens);
850 if (max > 2) {
851 vsp->mon = MonitorIntNewEx ("VecScreen Progress", 0, max - 1, FALSE);
852 }
853 VisitBioseqsInSep (sep, (Pointer) vsp, DoVecScreens);
854 if (vsp->mon != NULL) {
855 vsp->mon = MonitorFree (vsp->mon);
856 Update ();
857 }
858 if (vsp->changed) {
859 ObjMgrSetDirtyFlag (entityID, TRUE);
860 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
861 Update ();
862 } else {
863 Message (MSG_POST, "No vector contamination found");
864 }
865 vsp = VsDataFree(vsp);
866 }
867
868
CountWizardVecScreen(SeqEntryPtr sep)869 static Int4 CountWizardVecScreen (SeqEntryPtr sep)
870 {
871 Int4 max = 0;
872 BioseqSetPtr bssp;
873
874 while (sep != NULL) {
875 if (IS_Bioseq (sep)) {
876 CountVecScreens(sep->data.ptrvalue, &max);
877 } else if (IS_Bioseq_set (sep)) {
878 bssp = (BioseqSetPtr) sep->data.ptrvalue;
879 max += CountWizardVecScreen (bssp->seq_set);
880 }
881 sep = sep->next;
882 }
883 return max;
884 }
885
886
WizardDoVecScreen(SeqEntryPtr sep,VsDataPtr vsp)887 static void WizardDoVecScreen (SeqEntryPtr sep, VsDataPtr vsp)
888 {
889 BioseqSetPtr bssp;
890
891 while (sep != NULL) {
892 if (IS_Bioseq (sep)) {
893 DoVecScreens(sep->data.ptrvalue, vsp);
894 } else if (IS_Bioseq_set (sep)) {
895 bssp = (BioseqSetPtr) sep->data.ptrvalue;
896 WizardDoVecScreen (bssp->seq_set, vsp);
897 }
898 sep = sep->next;
899 }
900 }
901
902
VecScreenWizard(SeqEntryPtr sep)903 NLM_EXTERN Boolean VecScreenWizard (SeqEntryPtr sep)
904 {
905 Int4 max;
906 VsDataPtr vsp;
907 Boolean rval = FALSE;
908
909 vsp = InitVecScreenData("UniVec");
910 if (vsp == NULL) {
911 return FALSE;
912 }
913 if (sep == NULL) {
914 vsp = VsDataFree(vsp);
915 return FALSE;
916 }
917 max = CountWizardVecScreen(sep);
918 if (max > 2) {
919 vsp->mon = MonitorIntNewEx ("VecScreen Progress", 0, max - 1, FALSE);
920 }
921 WizardDoVecScreen (sep, vsp);
922 if (vsp->mon != NULL) {
923 vsp->mon = MonitorFree (vsp->mon);
924 Update ();
925 }
926 rval = vsp->changed;
927 vsp = VsDataFree(vsp);
928 return rval;
929 }
930
931
SimpleVecScreenCommon(IteM i,CharPtr database)932 static void SimpleVecScreenCommon (IteM i, CharPtr database)
933
934 {
935 BaseFormPtr bfp;
936 BioseqPtr bsp;
937 Int4 max;
938 SeqEntryPtr sep;
939 VsDataPtr vsp;
940
941 #ifdef WIN_MAC
942 bfp = (BaseFormPtr) currentFormDataPtr;
943 #else
944 bfp = (BaseFormPtr) GetObjectExtra (i);
945 #endif
946 if (bfp == NULL) return;
947
948 vsp = InitVecScreenData(database);
949 if (vsp == NULL) {
950 return;
951 }
952 bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
953 if (bsp != NULL) {
954 DoVecScreens (bsp, (Pointer) vsp);
955 } else {
956 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
957 if (sep == NULL) return;
958 max = 0;
959 VisitBioseqsInSep (sep, (Pointer) &max, CountVecScreens);
960 if (max > 2) {
961 vsp->mon = MonitorIntNewEx ("VecScreen Progress", 0, max - 1, FALSE);
962 }
963 VisitBioseqsInSep (sep, (Pointer) vsp, DoVecScreens);
964 if (vsp->mon != NULL) {
965 vsp->mon = MonitorFree (vsp->mon);
966 Update ();
967 }
968 }
969
970 if (vsp->changed) {
971 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
972 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
973 Update ();
974 } else {
975 Message (MSG_POST, "No vector contamination found");
976 }
977 vsp = VsDataFree (vsp);
978 }
979
SimpleUniVecScreenProc(IteM i)980 extern void SimpleUniVecScreenProc (IteM i)
981
982 {
983 SimpleVecScreenCommon (i, "UniVec");
984 }
985
SimpleUniVecCoreScreenProc(IteM i)986 extern void SimpleUniVecCoreScreenProc (IteM i)
987
988 {
989 SimpleVecScreenCommon (i, "UniVec_Core");
990 }
991
992 static QBQUEUE qbquerylist = NULL;
993
QBAnnounceCallback(CharPtr requestID,CharPtr seqID,Int2 estimatedSeconds)994 static void LIBCALLBACK QBAnnounceCallback (CharPtr requestID, CharPtr seqID, Int2 estimatedSeconds)
995
996 {
997 if (StringHasNoText (requestID)) {
998 requestID = "?";
999 }
1000 if (StringHasNoText (seqID)) {
1001 seqID = "?";
1002 }
1003 Message (MSG_POST, "Queued rID %s, seqID %s, estimated seconds = %d",
1004 requestID, seqID, (int) estimatedSeconds);
1005 }
1006
QBCallback(CharPtr filename,VoidPtr userdata,CharPtr requestID,CharPtr seqID,Boolean success)1007 static Boolean LIBCALLBACK QBCallback (
1008 CharPtr filename,
1009 VoidPtr userdata,
1010 CharPtr requestID,
1011 CharPtr seqID,
1012 Boolean success
1013 )
1014
1015 {
1016 if (StringHasNoText (requestID)) {
1017 requestID = "?";
1018 }
1019 if (StringHasNoText (seqID)) {
1020 seqID = "?";
1021 }
1022 if (success) {
1023 if (! SequinHandleNetResults (filename)) {
1024 /* LaunchGeneralTextViewer (path, "QueueFastaQueryToURL failed"); */
1025 }
1026 } else {
1027 Message (MSG_POST, "Failure of rID '%s', seqID %s", requestID, seqID);
1028 }
1029 return TRUE;
1030 }
1031
SimpleQBlastProc(IteM i)1032 static void SimpleQBlastProc (IteM i)
1033
1034 {
1035 BaseFormPtr bfp;
1036 BioseqPtr bsp;
1037 NewObjectPtr nop;
1038 SeqEntryPtr sep = NULL;
1039 Int2 which;
1040
1041 nop = (NewObjectPtr) GetObjectExtra (i);
1042 if (nop == NULL) return;
1043 #ifdef WIN_MAC
1044 bfp = (BaseFormPtr) currentFormDataPtr;
1045 #else
1046 bfp = nop->bfp;
1047 #endif
1048 if (bfp == NULL) return;
1049 which = BioseqViewOrDocSumChoice (nop);
1050 if (which != 1) return;
1051 bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
1052 if (bsp != NULL) {
1053 sep = SeqMgrGetSeqEntryForData (bsp);
1054 } else {
1055 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1056 }
1057 if (sep == NULL) return;
1058
1059 QBlastAsynchronousRequest ("nr", "blastn", bsp, &qbquerylist, QBCallback, QBAnnounceCallback, NULL);
1060 }
1061
1062 /* Analysis menu can launch external programs or use Web services */
1063
1064 static QUEUE urlquerylist = NULL;
1065
1066 static Int4 pendingqueries = 0;
1067
SubmitToNCBIResultProc(CONN conn,VoidPtr userdata,EIO_Status status)1068 static Boolean LIBCALLBACK SubmitToNCBIResultProc (CONN conn, VoidPtr userdata, EIO_Status status)
1069
1070 {
1071 AsnIoPtr aop;
1072 FILE *fp;
1073 Char path [PATH_MAX];
1074 SeqEntryPtr sep;
1075
1076 TmpNam (path);
1077 fp = FileOpen (path, "wb");
1078 QUERY_CopyResultsToFile (conn, fp);
1079 FileClose (fp);
1080 aop = AsnIoOpen (path, "rb");
1081 sep = SeqEntryAsnRead (aop, NULL);
1082 AsnIoClose (aop);
1083 aop = AsnIoOpen (path, "w");
1084 SeqEntryAsnWrite (sep, aop, NULL);
1085 AsnIoFlush (aop);
1086 AsnIoClose (aop);
1087 LaunchGeneralTextViewer (path, "Echo binary transformation of Seq-entry");
1088 FileRemove (path);
1089 return TRUE;
1090 }
1091
SubmitToNCBI(IteM i)1092 extern void SubmitToNCBI (IteM i)
1093
1094 {
1095 AsnIoPtr aop;
1096 BaseFormPtr bfp;
1097 CONN conn;
1098 FILE *fp;
1099 Char path [PATH_MAX];
1100 Char progname [64];
1101 SeqEntryPtr sep;
1102
1103 #ifdef WIN_MAC
1104 bfp = currentFormDataPtr;
1105 #else
1106 bfp = GetObjectExtra (i);
1107 #endif
1108 if (bfp == NULL) return;
1109 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1110 if (sep == NULL) return;
1111
1112 sprintf (progname, "Sequin/%s", SEQUIN_APPLICATION);
1113
1114 TmpNam (path);
1115
1116 aop = AsnIoOpen (path, "wb");
1117 SeqEntryAsnWrite (sep, aop, NULL);
1118 AsnIoFlush (aop);
1119 AsnIoClose (aop);
1120
1121 conn = QUERY_OpenUrlQuery ("cruncher.nlm.nih.gov", 0,
1122 "/cgi-bin/Sequin/testcgi.cgi", "request=echo",
1123 progname, 30, eMIME_T_NcbiData, eMIME_AsnBinary,
1124 eENCOD_Url,
1125 fHCC_UrlDecodeInput | fHCC_UrlEncodeOutput);
1126
1127 fp = FileOpen (path, "rb");
1128 QUERY_CopyFileToQuery (conn, fp);
1129 FileClose (fp);
1130
1131 QUERY_SendQuery (conn);
1132
1133 QUERY_AddToQueue (&urlquerylist, conn, SubmitToNCBIResultProc, NULL, TRUE);
1134
1135 pendingqueries++;
1136
1137 FileRemove (path);
1138 }
1139
1140 static QUEUE cddquerylist = NULL;
1141
1142 static Int2 cddquerynum = 0;
1143
1144 #include <cddapi.h>
1145
1146 #define CDD_EXPECT_VALUE 0.01
1147
CddProc(CONN conn,VoidPtr userdata,EIO_Status status)1148 static Boolean LIBCALLBACK CddProc (
1149 CONN conn,
1150 VoidPtr userdata,
1151 EIO_Status status
1152 )
1153
1154 {
1155 BioseqPtr bsp;
1156 SeqAnnotPtr prev;
1157 SeqAnnotPtr sap;
1158
1159 if (conn == NULL || userdata == NULL) return TRUE;
1160 if (status != eIO_Success) return TRUE;
1161 sap = CddReadReply (conn, status);
1162 if (sap == NULL) return FALSE;
1163
1164 bsp = (BioseqPtr) userdata;
1165 CddCorrectIDs (bsp, sap);
1166
1167 prev = bsp->annot;
1168 if (prev == NULL) {
1169 bsp->annot = sap;
1170 } else {
1171 while (prev->next != NULL) {
1172 prev = prev->next;
1173 }
1174 prev->next = sap;
1175 }
1176
1177 ObjMgrSetDirtyFlag (bsp->idx.entityID, TRUE);
1178 ObjMgrSendMsg (OM_MSG_UPDATE, bsp->idx.entityID, 0, 0);
1179
1180 return TRUE;
1181 }
1182
SearchCDD(BioseqPtr bsp,Pointer userdata)1183 static void SearchCDD (BioseqPtr bsp, Pointer userdata)
1184
1185 {
1186 BoolPtr dofeats;
1187
1188 if (bsp == NULL) return;
1189 if (! ISA_aa (bsp->mol)) return;
1190
1191 dofeats = (BoolPtr) userdata;
1192 if (! CddAsynchronousQuery (bsp, CDD_EXPECT_VALUE, TRUE, TRUE, *dofeats, "cdd", FALSE, &cddquerylist, CddProc, (Pointer) bsp)) {
1193 ErrPostEx (SEV_ERROR, 0, 0, "Unable to run CDD search");
1194 } else {
1195 cddquerynum++;
1196 }
1197 }
1198
1199 /*
1200 static void SearchCDD (BioseqPtr bsp, Pointer userdata)
1201
1202 {
1203 BoolPtr dofeats;
1204 SeqAnnotPtr prev;
1205 SeqAnnotPtr sap;
1206
1207 if (bsp == NULL) return;
1208 if (! ISA_aa (bsp->mol)) return;
1209
1210 dofeats = (BoolPtr) userdata;
1211 sap = CddSynchronousQuery (bsp, CDD_EXPECT_VALUE, TRUE, TRUE, *dofeats, "cdd", FALSE);
1212 if (sap == NULL) return;
1213 CddCorrectIDs (bsp, sap);
1214
1215 prev = bsp->annot;
1216 if (prev == NULL) {
1217 bsp->annot = sap;
1218 } else {
1219 while (prev->next != NULL) {
1220 prev = prev->next;
1221 }
1222 prev->next = sap;
1223 }
1224 }
1225 */
1226
SimpleCDDSearchCommonProc(IteM i,Boolean makeFeats)1227 static void SimpleCDDSearchCommonProc (IteM i, Boolean makeFeats)
1228
1229 {
1230 BaseFormPtr bfp;
1231 Boolean dofeats;
1232 SeqEntryPtr sep;
1233
1234 #ifdef WIN_MAC
1235 bfp = currentFormDataPtr;
1236 #else
1237 bfp = GetObjectExtra (i);
1238 #endif
1239 if (bfp == NULL) return;
1240 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1241 if (sep == NULL) return;
1242
1243 WatchCursor ();
1244 Update ();
1245
1246 if (makeFeats) {
1247 FreeCDDRegions (sep);
1248 } else {
1249 FreeCDDAligns (sep);
1250 }
1251
1252 dofeats = makeFeats;
1253 VisitBioseqsInSep (sep, (Pointer) &dofeats, SearchCDD);
1254
1255 /*
1256 RemoveDuplicateCDDs (sep);
1257
1258 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1259 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1260 */
1261 ArrowCursor ();
1262 Update ();
1263 }
1264
SimpleCDDSearchFeatProc(IteM i)1265 void SimpleCDDSearchFeatProc (IteM i)
1266
1267 {
1268 SimpleCDDSearchCommonProc (i, TRUE);
1269 }
1270
SimpleCDDSearchAlignProc(IteM i)1271 void SimpleCDDSearchAlignProc (IteM i)
1272
1273 {
1274 SimpleCDDSearchCommonProc (i, FALSE);
1275 }
1276
SequinCheckSocketsProc(void)1277 extern void SequinCheckSocketsProc (void)
1278
1279 {
1280 Int4 remaining;
1281
1282 remaining = QUERY_CheckQueue (&urlquerylist);
1283 if (remaining < pendingqueries) {
1284 Beep ();
1285 pendingqueries--;
1286 }
1287 remaining = VecScreenCheckQueue (&vsquerylist);
1288 if (remaining < vsquerynum) {
1289 vsquerynum = remaining;
1290 Message (MSG_POST, "There are %d vector screens remaining", (int) vsquerynum);
1291 }
1292 remaining = QBlastCheckQueue (&qbquerylist);
1293 remaining = CddCheckQueue (&cddquerylist);
1294 if (remaining < cddquerynum) {
1295 cddquerynum = remaining;
1296 Message (MSG_POST, "There are %d cdd searches remaining", (int) cddquerynum);
1297 }
1298 }
1299
DemoModeResultProc(CONN conn,VoidPtr userdata,EIO_Status status)1300 static Boolean LIBCALLBACK DemoModeResultProc (CONN conn, VoidPtr userdata, EIO_Status status)
1301
1302 {
1303 FILE *fp;
1304 Char path [PATH_MAX];
1305
1306 TmpNam (path);
1307 fp = FileOpen (path, "w");
1308 QUERY_CopyResultsToFile (conn, fp);
1309 FileClose (fp);
1310 LaunchGeneralTextViewer (path, "QueueFastaQueryToURL results");
1311 FileRemove (path);
1312 return TRUE;
1313 }
1314
SequinHandleURLResults(CONN conn,VoidPtr userdata,EIO_Status status)1315 static Boolean LIBCALLBACK SequinHandleURLResults (CONN conn, VoidPtr userdata, EIO_Status status)
1316
1317 {
1318 FILE *fp;
1319 Char path [PATH_MAX];
1320
1321 TmpNam (path);
1322 fp = FileOpen (path, "w");
1323 QUERY_CopyResultsToFile (conn, fp);
1324 FileClose (fp);
1325 if (! SequinHandleNetResults (path)) {
1326 /* LaunchGeneralTextViewer (path, "QueueFastaQueryToURL failed"); */
1327 }
1328 FileRemove (path);
1329 return TRUE;
1330 }
1331
1332 #define DEBUG_SEQN_BUFLEN 4096
1333
FinishURLProc(NewObjectPtr nop,CharPtr arguments,CharPtr path)1334 static void FinishURLProc (NewObjectPtr nop, CharPtr arguments, CharPtr path)
1335
1336 {
1337 Char buf [DEBUG_SEQN_BUFLEN + 4];
1338 CONN conn;
1339 size_t ct;
1340 FILE *fp, *fpp;
1341 Char pth [PATH_MAX];
1342 Char progname [64];
1343 QueryResultProc resultproc;
1344 EMIME_SubType subtype;
1345
1346 sprintf (progname, "Sequin/%s", SEQUIN_APPLICATION);
1347
1348 if (nop->demomode) {
1349 resultproc = DemoModeResultProc;
1350 } else {
1351 resultproc = nop->resultproc;
1352 }
1353 if (nop->format == 1) {
1354 subtype = eMIME_Fasta;
1355 } else if (nop->format == 2) {
1356 subtype = eMIME_AsnText;
1357 } else {
1358 subtype = eMIME_Unknown;
1359 }
1360
1361 conn = QUERY_OpenUrlQuery (nop->host_machine, nop->host_port,
1362 nop->host_path, arguments,
1363 progname, nop->timeoutsec,
1364 eMIME_T_NcbiData, subtype, eENCOD_Url,
1365 fHCC_UrlDecodeInput | fHCC_UrlEncodeOutput);
1366 if (conn == NULL) return;
1367
1368 fp = FileOpen (path, "r");
1369 QUERY_CopyFileToQuery (conn, fp);
1370 FileClose (fp);
1371
1372 QUERY_SendQuery (conn);
1373
1374 QUERY_AddToQueue (&urlquerylist, conn, resultproc, NULL, TRUE);
1375
1376 pendingqueries++;
1377
1378 if (nop->demomode) {
1379 TmpNam (pth);
1380 fpp = FileOpen (pth, "w");
1381 fprintf (fpp, "%s\n", nop->host_machine);
1382 fprintf (fpp, "%s\n", nop->host_path);
1383 fprintf (fpp, "%s\n", arguments);
1384 fp = FileOpen (path, "r");
1385 if (fp != NULL) {
1386 while ((ct = FileRead (buf, 1, DEBUG_SEQN_BUFLEN, fp)) > 0) {
1387 FileWrite (buf, 1, ct, fpp);
1388 }
1389 fprintf (fpp, "\n");
1390 FileClose (fp);
1391 }
1392 FileClose (fpp);
1393 LaunchGeneralTextViewer (pth, "QueueFastaQueryToURL request");
1394 FileRemove (pth);
1395 }
1396 }
1397
DoAnalysisProc(NewObjectPtr nop,BaseFormPtr bfp,Int2 which,CharPtr arguments,ResultProc dotheanalysis)1398 static void DoAnalysisProc (NewObjectPtr nop, BaseFormPtr bfp, Int2 which, CharPtr arguments, ResultProc dotheanalysis)
1399
1400 {
1401 AsnIoPtr aop;
1402 BioseqPtr bsp;
1403 Char path1 [PATH_MAX];
1404 SeqEntryPtr sep;
1405
1406 if (nop == NULL || bfp == NULL) return;
1407 switch (which) {
1408 case 1 :
1409 if (BioseqViewCanSaveFasta (bfp->form, nop->fastaNucOK, nop->fastaProtOK, nop->onlyBspTarget)) {
1410 TmpNam (path1);
1411 switch (nop->format) {
1412 case 1 :
1413 ExportBioseqViewFasta (bfp->form, path1, nop->fastaNucOK, nop->fastaProtOK, nop->onlyBspTarget);
1414 break;
1415 case 2 :
1416 sep = NULL;
1417 if (nop->onlyBspTarget) {
1418 bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
1419 sep = SeqMgrGetSeqEntryForData (bsp);
1420 } else {
1421 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1422 }
1423 if (sep != NULL) {
1424 aop = AsnIoOpen (path1, "w");
1425 SeqEntryAsnWrite (sep, aop, NULL);
1426 AsnIoFlush (aop);
1427 AsnIoClose (aop);
1428 }
1429 break;
1430 default :
1431 break;
1432 }
1433 if (dotheanalysis != NULL) {
1434 dotheanalysis (path1);
1435 } else {
1436 FinishURLProc (nop, arguments, path1);
1437 }
1438 FileRemove (path1);
1439 } else {
1440 ErrPostEx (SEV_ERROR, 0, 0, "BioseqView cannot save fasta format");
1441 }
1442 break;
1443 case 2 :
1444 /*
1445 if (DocSumCanSaveFasta (bfp->form, nop->fastaNucOK, nop->fastaProtOK)) {
1446 TmpNam (path1);
1447 ExportDocSumFasta (bfp->form, path1, nop->fastaNucOK, nop->fastaProtOK);
1448 if (dotheanalysis != NULL) {
1449 dotheanalysis (path1);
1450 } else {
1451 FinishURLProc (nop, arguments, path1);
1452 }
1453 FileRemove (path1);
1454 } else {
1455 ErrPostEx (SEV_ERROR, 0, 0, "DocSum cannot save fasta format");
1456 }
1457 */
1458 ErrPostEx (SEV_ERROR, 0, 0, "DocSum cannot save fasta format");
1459 break;
1460 default :
1461 break;
1462 }
1463 }
1464
1465 /* encodes spaces as %20 in URLs */
StrSaveNoNullEncodeSpaces(CharPtr from)1466 static CharPtr StrSaveNoNullEncodeSpaces (CharPtr from)
1467
1468 {
1469 Char ch;
1470 size_t len = 0;
1471 CharPtr p;
1472 CharPtr q;
1473 CharPtr to;
1474
1475 if (StringHasNoText (from)) return NULL;
1476 p = from;
1477 ch = *p;
1478 while (ch != '\0') {
1479 if (ch == ' ') {
1480 len += 3;
1481 } else {
1482 len++;
1483 }
1484 p++;
1485 ch = *p;
1486 }
1487 to = MemNew (len + 1);
1488 if (to == NULL) return NULL;
1489
1490 q = to;
1491 p = from;
1492 ch = *p;
1493 while (ch != '\0') {
1494 if (ch == ' ') {
1495 *q = '%';
1496 q++;
1497 *q = '2';
1498 q++;
1499 *q = '0';
1500 q++;
1501 } else {
1502 *q = ch;
1503 q++;
1504 }
1505 p++;
1506 ch = *p;
1507 }
1508 *q = '\0';
1509 return to;
1510 }
1511
1512 typedef struct urlargform {
1513 FORM_MESSAGE_BLOCK
1514
1515 NewObjectPtr nop;
1516 BaseFormPtr bfp;
1517 ValNodePtr controls;
1518 ValNodePtr helps;
1519 Int2 which;
1520 } UrlArgForm, PNTR UrlArgFormPtr;
1521
AcceptArgumentFormProc(ButtoN b)1522 static void AcceptArgumentFormProc (ButtoN b)
1523
1524 {
1525 CharPtr args = NULL;
1526 CharPtr arguments = NULL;
1527 ButtoN btn;
1528 Char ch;
1529 Int2 choice;
1530 Char cpy [256];
1531 GrouP grp;
1532 ValNodePtr head = NULL;
1533 Int2 i;
1534 CharPtr itms;
1535 CharPtr last;
1536 size_t len;
1537 LisT lst;
1538 NewObjectPtr nop;
1539 Boolean notFirst = FALSE;
1540 PopuP pop;
1541 ValNodePtr ppt;
1542 CharPtr ptr;
1543 CharPtr str;
1544 Char tmp [256];
1545 TexT txt;
1546 UrlArgFormPtr ufp;
1547 UrlParamPtr upp;
1548 Int2 val;
1549 ValNodePtr vnp;
1550
1551 ufp = (UrlArgFormPtr) GetObjectExtra (b);
1552 if (ufp == NULL) return;
1553 Hide (ufp->form);
1554 Update ();
1555 nop = ufp->nop;
1556 if (nop != NULL) {
1557 if (! StringHasNoText (nop->prefix)) {
1558 ValNodeCopyStr (&head, 0, nop->prefix);
1559 }
1560 for (vnp = ufp->controls, ppt = nop->paramlist;
1561 vnp != NULL && ppt != NULL;
1562 vnp = vnp->next, ppt = ppt->next) {
1563 upp = (UrlParamPtr) ppt->data.ptrvalue;
1564 if (upp == NULL) continue;
1565 choice = vnp->choice;
1566 switch (upp->type) {
1567 case 1 :
1568 txt = (TexT) vnp->data.ptrvalue;
1569 str = SaveStringFromText (txt);
1570 if (str != NULL) {
1571 sprintf (tmp, "%s=%s", upp->param, str);
1572 ValNodeCopyStr (&head, ppt->choice, tmp);
1573 MemFree (str);
1574 }
1575 break;
1576 case 2 :
1577 btn = (ButtoN) vnp->data.ptrvalue;
1578 if (GetStatus (btn)) {
1579 sprintf (tmp, "%s=TRUE", upp->param);
1580 } else {
1581 sprintf (tmp, "%s=FALSE", upp->param);
1582 }
1583 ValNodeCopyStr (&head, ppt->choice, tmp);
1584 break;
1585 case 3 :
1586 pop = (PopuP) vnp->data.ptrvalue;
1587 val = GetValue (pop);
1588 if (val > 0) {
1589 i = 0;
1590 itms = upp->choices;
1591 StringNCpy_0 (tmp, itms, sizeof (tmp));
1592 last = tmp;
1593 ptr = last;
1594 ch = *ptr;
1595 while (ch != '\0') {
1596 if (ch == ',') {
1597 *ptr = '\0';
1598 i++;
1599 if (val == i) {
1600 sprintf (cpy, "%s=%s", upp->param, last);
1601 ValNodeCopyStr (&head, ppt->choice, cpy);
1602 }
1603 ptr++;
1604 last = ptr;
1605 ch = *ptr;
1606 } else {
1607 ptr++;
1608 ch = *ptr;
1609 }
1610 }
1611 if (! StringHasNoText (last)) {
1612 i++;
1613 if (val == i) {
1614 sprintf (cpy, "%s=%s", upp->param, last);
1615 ValNodeCopyStr (&head, ppt->choice, cpy);
1616 }
1617 }
1618 }
1619 break;
1620 case 4 :
1621 grp = (GrouP) vnp->data.ptrvalue;
1622 val = GetValue (grp);
1623 if (val > 0) {
1624 i = 0;
1625 itms = upp->choices;
1626 StringNCpy_0 (tmp, itms, sizeof (tmp));
1627 last = tmp;
1628 ptr = last;
1629 ch = *ptr;
1630 while (ch != '\0') {
1631 if (ch == ',') {
1632 *ptr = '\0';
1633 i++;
1634 if (val == i) {
1635 sprintf (cpy, "%s=%s", upp->param, last);
1636 ValNodeCopyStr (&head, ppt->choice, cpy);
1637 }
1638 ptr++;
1639 last = ptr;
1640 ch = *ptr;
1641 } else {
1642 ptr++;
1643 ch = *ptr;
1644 }
1645 }
1646 if (! StringHasNoText (last)) {
1647 i++;
1648 if (val == i) {
1649 sprintf (cpy, "%s=%s", upp->param, last);
1650 ValNodeCopyStr (&head, ppt->choice, cpy);
1651 }
1652 }
1653 }
1654 break;
1655 case 5 :
1656 lst = (LisT) vnp->data.ptrvalue;
1657 val = GetValue (lst);
1658 if (val > 0) {
1659 i = 0;
1660 itms = upp->choices;
1661 StringNCpy_0 (tmp, itms, sizeof (tmp));
1662 last = tmp;
1663 ptr = last;
1664 ch = *ptr;
1665 while (ch != '\0') {
1666 if (ch == ',') {
1667 *ptr = '\0';
1668 i++;
1669 if (val == i) {
1670 sprintf (cpy, "%s=%s", upp->param, last);
1671 ValNodeCopyStr (&head, ppt->choice, cpy);
1672 }
1673 ptr++;
1674 last = ptr;
1675 ch = *ptr;
1676 } else {
1677 ptr++;
1678 ch = *ptr;
1679 }
1680 }
1681 if (! StringHasNoText (last)) {
1682 i++;
1683 if (val == i) {
1684 sprintf (cpy, "%s=%s", upp->param, last);
1685 ValNodeCopyStr (&head, ppt->choice, cpy);
1686 }
1687 }
1688 }
1689 break;
1690 default :
1691 break;
1692 }
1693 }
1694 head = SortValNode (head, SortByVnpChoice);
1695 if (! StringHasNoText (nop->suffix)) {
1696 ValNodeCopyStr (&head, 0, nop->suffix);
1697 }
1698 for (len = 0, vnp = head; vnp != NULL; vnp = vnp->next) {
1699 len += StringLen ((CharPtr) vnp->data.ptrvalue) + 1;
1700 }
1701 if (len > 0) {
1702 arguments = MemNew (len + 5);
1703 if (arguments != NULL) {
1704 vnp = head;
1705 notFirst = FALSE;
1706 while (vnp != NULL) {
1707 if (notFirst) {
1708 StringCat (arguments, "&");
1709 }
1710 StringCat (arguments, (CharPtr) vnp->data.ptrvalue);
1711 notFirst = TRUE;
1712 vnp = vnp->next;
1713 }
1714 }
1715 }
1716 args = /* StrSaveNoNullEncodeSpaces */ StringSave (arguments);
1717 MemFree (arguments);
1718 DoAnalysisProc (nop, ufp->bfp, ufp->which, args, NULL);
1719 MemFree (args);
1720 }
1721 Remove (ufp->form);
1722 }
1723
ShowArgumentHelp(ButtoN b)1724 static void ShowArgumentHelp (ButtoN b)
1725
1726 {
1727 NewObjectPtr nop;
1728 ValNodePtr ppt;
1729 CharPtr str;
1730 UrlArgFormPtr ufp;
1731 UrlParamPtr upp;
1732 ValNodePtr vnp;
1733
1734 ufp = (UrlArgFormPtr) GetObjectExtra (b);
1735 if (ufp == NULL) return;
1736 nop = ufp->nop;
1737 if (nop == NULL) return;
1738 for (vnp = ufp->helps, ppt = nop->paramlist;
1739 vnp != NULL && ppt != NULL;
1740 vnp = vnp->next, ppt = ppt->next) {
1741 upp = (UrlParamPtr) ppt->data.ptrvalue;
1742 if (upp == NULL) continue;
1743 if ((Pointer) b == (Pointer) vnp->data.ptrvalue) {
1744 str = upp->help;
1745 Message (MSG_OK, "%s", str);
1746 return;
1747 }
1748 }
1749 Beep ();
1750 }
1751
ArgumentFormMessage(ForM f,Int2 mssg)1752 static void ArgumentFormMessage (ForM f, Int2 mssg)
1753
1754 {
1755 UrlArgFormPtr ufp;
1756
1757 ufp = (UrlArgFormPtr) GetObjectExtra (f);
1758 if (ufp != NULL) {
1759 switch (mssg) {
1760 case VIB_MSG_CLOSE :
1761 Remove (f);
1762 break;
1763 default :
1764 if (ufp->appmessage != NULL) {
1765 ufp->appmessage (f, mssg);
1766 }
1767 break;
1768 }
1769 }
1770 }
1771
CleanupArgumentForm(GraphiC g,VoidPtr data)1772 static void CleanupArgumentForm (GraphiC g, VoidPtr data)
1773
1774 {
1775 UrlArgFormPtr ufp;
1776
1777 ufp = (UrlArgFormPtr) data;
1778 if (ufp != NULL) {
1779 ValNodeFree (ufp->controls);
1780 ValNodeFree (ufp->helps);
1781 }
1782 StdCleanupFormProc (g, data);
1783 }
1784
RearrangeParamList(ValNodePtr paramlist)1785 static ValNodePtr RearrangeParamList (ValNodePtr paramlist)
1786
1787 {
1788 ValNodePtr curr;
1789 CharPtr group;
1790 ValNodePtr head = NULL;
1791 ValNodePtr list;
1792 ValNodePtr next;
1793 ValNodePtr PNTR prev;
1794 ValNodePtr ppt;
1795 UrlParamPtr upp;
1796
1797 ppt = paramlist;
1798 while (ppt != NULL) {
1799 list = ppt->next;
1800 ppt->next = NULL;
1801 ValNodeLink (&head, ppt);
1802 upp = (UrlParamPtr) ppt->data.ptrvalue;
1803 if (upp == NULL) {
1804 ppt = list;
1805 continue;
1806 }
1807 group = upp->group;
1808 curr = list;
1809 prev = &list;
1810 while (curr != NULL) {
1811 next = curr->next;
1812 upp = (UrlParamPtr) curr->data.ptrvalue;
1813 if (upp == NULL) {
1814 prev = &(curr->next);
1815 curr = next;
1816 continue;
1817 }
1818 if (StringICmp (upp->group, group) == 0) {
1819 *prev = next;
1820 curr->next = NULL;
1821 ValNodeLink (&head, curr);
1822 } else {
1823 prev = &(curr->next);
1824 }
1825 curr = next;
1826 }
1827 ppt = list;
1828 }
1829 return head;
1830 }
1831
BuildArgumentForm(NewObjectPtr nop,BaseFormPtr bfp,Int2 which)1832 static void BuildArgumentForm (NewObjectPtr nop, BaseFormPtr bfp, Int2 which)
1833
1834 {
1835 ButtoN b;
1836 ButtoN btn;
1837 GrouP c;
1838 Char ch;
1839 CharPtr def;
1840 Int2 delta;
1841 TexT first = NULL;
1842 GrouP g;
1843 GrouP grp;
1844 GrouP h;
1845 ValNodePtr hlp;
1846 Int2 i;
1847 CharPtr itms;
1848 CharPtr last;
1849 CharPtr lastGroup = " ";
1850 LisT lst;
1851 GrouP m;
1852 Int2 max;
1853 Int2 min;
1854 ValNodePtr moveMe = NULL;
1855 Nlm_Handle obj1, obj2;
1856 PopuP pop;
1857 PrompT prmpt;
1858 ValNodePtr ppt;
1859 CharPtr ptr;
1860 RecT r;
1861 StdEditorProcsPtr sepp;
1862 CharPtr str;
1863 Char tmp [128];
1864 TexT txt;
1865 UrlArgFormPtr ufp;
1866 UrlParamPtr upp;
1867 Int2 val;
1868 ValNodePtr vnp;
1869 WindoW w;
1870
1871 if (nop == NULL || bfp == NULL) return;
1872 ufp = (UrlArgFormPtr) MemNew (sizeof (UrlArgForm));
1873 if (ufp == NULL) return;
1874
1875 nop->paramlist = RearrangeParamList (nop->paramlist);
1876
1877 w = FixedWindow (-50, -33, -10, -10, "Arguments", NULL);
1878 SetObjectExtra (w, ufp, CleanupArgumentForm);
1879 ufp->form = (ForM) w;
1880 ufp->formmessage = ArgumentFormMessage;
1881
1882 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
1883 if (sepp != NULL) {
1884 SetActivate (w, sepp->activateForm);
1885 ufp->appmessage = sepp->handleMessages;
1886 }
1887
1888 ufp->bfp = bfp;
1889 ufp->nop = nop;
1890 ufp->which = which;
1891
1892 m = HiddenGroup (w, 1, 0, NULL);
1893
1894 g = NULL;
1895 for (ppt = nop->paramlist;
1896 ppt != NULL;
1897 ppt = ppt->next) {
1898 upp = (UrlParamPtr) ppt->data.ptrvalue;
1899 if (upp == NULL) continue;
1900 if (StringICmp (upp->group, lastGroup) != 0) {
1901 if (StringHasNoText (upp->group)) {
1902 if (StringHasNoText (lastGroup)) {
1903 g = HiddenGroup (m, 3, 0, NULL);
1904 } else {
1905 g = NormalGroup (m, 3, 0, "", programFont, NULL);
1906 }
1907 } else {
1908 g = NormalGroup (m, 3, 0, upp->group, programFont, NULL);
1909 }
1910 lastGroup = upp->group;
1911 }
1912 if (g == NULL) {
1913 g = HiddenGroup (m, 3, 0, NULL);
1914 }
1915 switch (upp->type) {
1916 case 1 :
1917 str = upp->prompt;
1918 StaticPrompt (g, str, 0, dialogTextHeight, programFont, 'l');
1919 def = upp->dfault;
1920 if (StringHasNoText (def)) {
1921 def = "";
1922 }
1923 txt = DialogText (g, def, 10, NULL);
1924 if (first == NULL) {
1925 first = txt;
1926 }
1927 ValNodeAddPointer (&(ufp->controls), 1, (Pointer) txt);
1928 ValNodeAddPointer (&moveMe, 0, (Pointer) txt);
1929 b = PushButton (g, "?", ShowArgumentHelp);
1930 SetObjectExtra (b, ufp, NULL);
1931 ValNodeAddPointer (&(ufp->helps), 0, (Pointer) b);
1932 break;
1933 case 2 :
1934 str = upp->prompt;
1935 btn = CheckBox (g, str, NULL);
1936 def = upp->dfault;
1937 if (StringICmp (def, "TRUE") == 0) {
1938 SetStatus (btn, TRUE);
1939 }
1940 prmpt = StaticPrompt (g, "", 0, 0, programFont, 'l');
1941 ValNodeAddPointer (&moveMe, 0, (Pointer) prmpt);
1942 ValNodeAddPointer (&(ufp->controls), 2, (Pointer) btn);
1943 b = PushButton (g, "?", ShowArgumentHelp);
1944 SetObjectExtra (b, ufp, NULL);
1945 ValNodeAddPointer (&(ufp->helps), 0, (Pointer) b);
1946 break;
1947 case 3 :
1948 str = upp->prompt;
1949 StaticPrompt (g, str, 0, dialogTextHeight, programFont, 'l');
1950 h = HiddenGroup (g, 1, 0, NULL);
1951 pop = PopupList (h, TRUE, NULL);
1952 def = upp->dfault;
1953 val = 0;
1954 i = 0;
1955 itms = upp->choices;
1956 StringNCpy_0 (tmp, itms, sizeof (tmp));
1957 last = tmp;
1958 ptr = last;
1959 ch = *ptr;
1960 while (ch != '\0') {
1961 if (ch == ',') {
1962 *ptr = '\0';
1963 PopupItem (pop, last);
1964 i++;
1965 if (StringICmp (def, last) == 0) {
1966 val = i;
1967 }
1968 ptr++;
1969 last = ptr;
1970 ch = *ptr;
1971 } else {
1972 ptr++;
1973 ch = *ptr;
1974 }
1975 }
1976 if (! StringHasNoText (last)) {
1977 PopupItem (pop, last);
1978 i++;
1979 if (StringICmp (def, last) == 0) {
1980 val = i;
1981 }
1982 }
1983 if (val > 0) {
1984 SetValue (pop, val);
1985 }
1986 ValNodeAddPointer (&(ufp->controls), 3, (Pointer) pop);
1987 ValNodeAddPointer (&moveMe, 0, (Pointer) pop);
1988 b = PushButton (g, "?", ShowArgumentHelp);
1989 SetObjectExtra (b, ufp, NULL);
1990 ValNodeAddPointer (&(ufp->helps), 0, (Pointer) b);
1991 break;
1992 case 4 :
1993 str = upp->prompt;
1994 StaticPrompt (g, str, 0, dialogTextHeight, programFont, 'l');
1995 h = HiddenGroup (g, 1, 0, NULL);
1996 grp = HiddenGroup (h, -5, 0, NULL);
1997 def = upp->dfault;
1998 val = 0;
1999 i = 0;
2000 itms = upp->choices;
2001 StringNCpy_0 (tmp, itms, sizeof (tmp));
2002 last = tmp;
2003 ptr = last;
2004 ch = *ptr;
2005 while (ch != '\0') {
2006 if (ch == ',') {
2007 *ptr = '\0';
2008 RadioButton (grp, last);
2009 i++;
2010 if (StringICmp (def, last) == 0) {
2011 val = i;
2012 }
2013 ptr++;
2014 last = ptr;
2015 ch = *ptr;
2016 } else {
2017 ptr++;
2018 ch = *ptr;
2019 }
2020 }
2021 if (! StringHasNoText (last)) {
2022 RadioButton (grp, last);
2023 i++;
2024 if (StringICmp (def, last) == 0) {
2025 val = i;
2026 }
2027 }
2028 if (val > 0) {
2029 SetValue (grp, val);
2030 }
2031 ValNodeAddPointer (&(ufp->controls), 4, (Pointer) grp);
2032 ValNodeAddPointer (&moveMe, 0, (Pointer) grp);
2033 b = PushButton (g, "?", ShowArgumentHelp);
2034 SetObjectExtra (b, ufp, NULL);
2035 ValNodeAddPointer (&(ufp->helps), 0, (Pointer) b);
2036 break;
2037 case 5 :
2038 str = upp->prompt;
2039 StaticPrompt (g, str, 0, dialogTextHeight, programFont, 'l');
2040 h = HiddenGroup (g, 1, 0, NULL);
2041 lst = SingleList (h, 10, 3, NULL);
2042 def = upp->dfault;
2043 val = 0;
2044 i = 0;
2045 itms = upp->choices;
2046 StringNCpy_0 (tmp, itms, sizeof (tmp));
2047 last = tmp;
2048 ptr = last;
2049 ch = *ptr;
2050 while (ch != '\0') {
2051 if (ch == ',') {
2052 *ptr = '\0';
2053 ListItem (lst, last);
2054 i++;
2055 if (StringICmp (def, last) == 0) {
2056 val = i;
2057 }
2058 ptr++;
2059 last = ptr;
2060 ch = *ptr;
2061 } else {
2062 ptr++;
2063 ch = *ptr;
2064 }
2065 }
2066 if (! StringHasNoText (last)) {
2067 ListItem (lst, last);
2068 i++;
2069 if (StringICmp (def, last) == 0) {
2070 val = i;
2071 }
2072 }
2073 if (val > 0) {
2074 SetValue (lst, val);
2075 }
2076 ValNodeAddPointer (&(ufp->controls), 5, (Pointer) lst);
2077 ValNodeAddPointer (&moveMe, 0, (Pointer) lst);
2078 b = PushButton (g, "?", ShowArgumentHelp);
2079 SetObjectExtra (b, ufp, NULL);
2080 ValNodeAddPointer (&(ufp->helps), 0, (Pointer) b);
2081 break;
2082 default :
2083 break;
2084 }
2085 }
2086
2087 min = 0;
2088 max = 0;
2089 for (vnp = moveMe; vnp != NULL; vnp = vnp->next) {
2090 obj1 = (Nlm_Handle) vnp->data.ptrvalue;
2091 GetPosition (obj1, &r);
2092 min = MAX (min, r.left);
2093 }
2094 for (vnp = moveMe; vnp != NULL; vnp = vnp->next) {
2095 obj1 = (Nlm_Handle) vnp->data.ptrvalue;
2096 GetPosition (obj1, &r);
2097 delta = min - r.left;
2098 OffsetRect (&r, delta, 0);
2099 SetPosition (obj1, &r);
2100 AdjustPrnt (obj1, &r, FALSE);
2101 max = MAX (max, r.right);
2102 }
2103 max += 3;
2104 for (vnp = moveMe, hlp = ufp->helps;
2105 vnp != NULL && hlp != NULL;
2106 vnp = vnp->next, hlp = hlp->next) {
2107 obj2 = (Nlm_Handle) hlp->data.ptrvalue;
2108 GetPosition (obj2, &r);
2109 delta = max - r.left;
2110 OffsetRect (&r, delta, 0);
2111 SetPosition (obj2, &r);
2112 AdjustPrnt (obj2, &r, TRUE);
2113 }
2114
2115 c = HiddenGroup (w, 2, 0, NULL);
2116 SetGroupSpacing (c, 10, 3);
2117 b = DefaultButton (c, "Accept", AcceptArgumentFormProc);
2118 SetObjectExtra (b, ufp, NULL);
2119 PushButton (c, "Cancel", StdCancelButtonProc);
2120
2121 AlignObjects (ALIGN_CENTER, (HANDLE) m, (HANDLE) c, NULL);
2122 RealizeWindow (w);
2123 Show (w);
2124 Select (w);
2125 if (first != NULL) {
2126 Select (first);
2127 }
2128 }
2129
DoURLProc(IteM i)2130 static void DoURLProc (IteM i)
2131
2132 {
2133 CharPtr args = NULL;
2134 BaseFormPtr bfp;
2135 size_t len;
2136 NewObjectPtr nop;
2137 Int2 which;
2138
2139 nop = (NewObjectPtr) GetObjectExtra (i);
2140 if (nop == NULL) return;
2141 #ifdef WIN_MAC
2142 bfp = (BaseFormPtr) currentFormDataPtr;
2143 #else
2144 bfp = nop->bfp;
2145 #endif
2146 if (bfp == NULL) return;
2147 which = BioseqViewOrDocSumChoice (nop);
2148 if (nop->paramlist == NULL) {
2149 len = StringLen (nop->prefix) + StringLen (nop->suffix);
2150 if (len > 0) {
2151 args = MemNew (sizeof (Char) * (len + 2));
2152 StringCpy (args, nop->prefix);
2153 if (! StringHasNoText (nop->suffix)) {
2154 StringCat (args, "&");
2155 StringCat (args, nop->suffix);
2156 }
2157 }
2158 DoAnalysisProc (nop, bfp, which, args, NULL);
2159 } else {
2160 BuildArgumentForm (nop, bfp, which);
2161 }
2162 }
2163
EnableAnalysisItems(BaseFormPtr bfp,Boolean isDocSum)2164 extern void EnableAnalysisItems (BaseFormPtr bfp, Boolean isDocSum)
2165
2166 {
2167 Boolean hasFastaNuc;
2168 Boolean hasFastaProt;
2169 NewObjectPtr nop;
2170
2171 if (bfp == NULL) return;
2172 #ifdef WIN_MAC
2173 nop = (NewObjectPtr) macUserDataPtr;
2174 #else
2175 nop = (NewObjectPtr) bfp->userDataPtr;
2176 #endif
2177 if (isDocSum) {
2178 } else {
2179 }
2180 while (nop != NULL) {
2181 if (nop->kind == 1) {
2182 /* annotate menu item, ignore it */
2183 } else if (isDocSum) {
2184 if (nop->dsmOK) {
2185 /*
2186 hasFastaNuc = DocSumCanSaveFasta (bfp->form, TRUE, FALSE);
2187 hasFastaProt = DocSumCanSaveFasta (bfp->form, FALSE, TRUE);
2188 if (nop->fastaNucOK && hasFastaNuc) {
2189 SafeEnable (nop->item);
2190 } else if (nop->fastaProtOK && hasFastaProt) {
2191 SafeEnable (nop->item);
2192 } else {
2193 SafeDisable (nop->item);
2194 }
2195 */
2196 SafeDisable (nop->item);
2197 } else {
2198 SafeDisable (nop->item);
2199 }
2200 } else {
2201 if (nop->bspOK) {
2202 hasFastaNuc = BioseqViewCanSaveFasta (bfp->form, TRUE, FALSE, nop->onlyBspTarget);
2203 hasFastaProt = BioseqViewCanSaveFasta (bfp->form, FALSE, TRUE, nop->onlyBspTarget);
2204 if (nop->fastaNucOK && hasFastaNuc) {
2205 SafeEnable (nop->item);
2206 } else if (nop->fastaProtOK && hasFastaProt) {
2207 SafeEnable (nop->item);
2208 } else {
2209 SafeDisable (nop->item);
2210 }
2211 } else {
2212 SafeDisable (nop->item);
2213 }
2214 }
2215 nop = nop->next;
2216 }
2217 }
2218
LinkNewObjectLists(NewObjectPtr list1,NewObjectPtr list2)2219 static VoidPtr LinkNewObjectLists (NewObjectPtr list1, NewObjectPtr list2)
2220
2221 {
2222 NewObjectPtr nop;
2223
2224 if (list1 == NULL) return list2;
2225 nop = list1;
2226 while (nop->next != NULL) {
2227 nop = nop->next;
2228 }
2229 nop->next = list2;
2230 return list1;
2231 }
2232
CleanupAnalysisExtraProc(GraphiC g,VoidPtr data)2233 static void CleanupAnalysisExtraProc (GraphiC g, VoidPtr data)
2234
2235 {
2236 NewObjectPtr nop;
2237 ValNodePtr ppt;
2238 UrlParamPtr upp;
2239
2240 nop = (NewObjectPtr) data;
2241 if (nop != NULL) {
2242 MemFree (nop->host_machine);
2243 MemFree (nop->host_path);
2244 for (ppt = nop->paramlist; ppt != NULL; ppt = ppt->next) {
2245 upp = (UrlParamPtr) ppt->data.ptrvalue;
2246 if (upp == NULL) continue;
2247 MemFree (upp->param);
2248 MemFree (upp->prompt);
2249 MemFree (upp->dfault);
2250 MemFree (upp->choices);
2251 MemFree (upp->group);
2252 MemFree (upp->help);
2253 }
2254 ValNodeFreeData (nop->paramlist);
2255 MemFree (nop->prefix);
2256 MemFree (nop->suffix);
2257 }
2258 MemFree (data);
2259 }
2260
2261 typedef struct sbstruc {
2262 CharPtr name;
2263 MenU menu;
2264 } Sbstruc, PNTR SbstrucPtr;
2265
2266 static ValNodePtr analysissubmenulist = NULL;
2267
AddAnalysisItem(MenU m,BaseFormPtr bfp,Boolean bspviewOK,Boolean docsumOK,Boolean nucOK,Boolean protOK,Boolean onlyBspTarget,CharPtr host_machine,Uint2 host_port,CharPtr host_path,CharPtr program,Uint2 timeoutsec,Int2 format,Boolean demomode,QueryResultProc resultproc,ValNodePtr paramlist,CharPtr prefix,CharPtr suffix,CharPtr title,CharPtr submenu,ItmActnProc actn,NewObjectPtr PNTR head)2268 static void AddAnalysisItem (MenU m, BaseFormPtr bfp,
2269 Boolean bspviewOK, Boolean docsumOK,
2270 Boolean nucOK, Boolean protOK, Boolean onlyBspTarget,
2271 CharPtr host_machine, Uint2 host_port,
2272 CharPtr host_path, CharPtr program,
2273 Uint2 timeoutsec, Int2 format, Boolean demomode,
2274 QueryResultProc resultproc, ValNodePtr paramlist,
2275 CharPtr prefix, CharPtr suffix,
2276 CharPtr title, CharPtr submenu,
2277 ItmActnProc actn, NewObjectPtr PNTR head)
2278
2279 {
2280 IteM i;
2281 NewObjectPtr last;
2282 size_t len;
2283 NewObjectPtr nop;
2284 SbstrucPtr sbp;
2285 CharPtr tmp;
2286 ValNodePtr vnp;
2287 MenU x;
2288
2289 if (m == NULL || actn == NULL) return;
2290 x = NULL;
2291 if (! StringHasNoText (submenu)) {
2292 vnp = analysissubmenulist;
2293 while (vnp != NULL && x == NULL) {
2294 sbp = (SbstrucPtr) vnp->data.ptrvalue;
2295 if (sbp != NULL && StringICmp (sbp->name, submenu) == 0) {
2296 x = sbp->menu;
2297 }
2298 vnp = vnp->next;
2299 }
2300 if (x == NULL) {
2301 sbp = (SbstrucPtr) MemNew (sizeof (Sbstruc));
2302 if (sbp != NULL) {
2303 sbp->name = StringSave (submenu);
2304 sbp->menu = SubMenu (m, sbp->name);
2305 x = sbp->menu;
2306 ValNodeAddPointer (&analysissubmenulist, 0, (VoidPtr) sbp);
2307 }
2308 }
2309 }
2310 if (x == NULL) {
2311 x = m;
2312 }
2313 i = CommandItem (x, title, actn);
2314 nop = (NewObjectPtr) MemNew (sizeof (NewObjectData));
2315 if (nop != NULL) {
2316 nop->kind = 2; /* analysis menu item */
2317 nop->bfp = bfp;
2318 nop->item = i;
2319 nop->bspOK = bspviewOK;
2320 nop->dsmOK = docsumOK;
2321 nop->fastaNucOK = nucOK;
2322 nop->fastaProtOK = protOK;
2323 nop->onlyBspTarget = onlyBspTarget;
2324 nop->host_machine = /* StrSaveNoNullEncodeSpaces */ StringSave (host_machine);
2325 nop->host_port = host_port;
2326 len = StringLen (host_path);
2327 tmp = MemNew (len + StringLen (program) + 5);
2328 if (tmp != NULL) {
2329 StringCpy (tmp, host_path);
2330 if (len > 1 && tmp [len - 1] != '/') {
2331 StringCat (tmp, "/");
2332 }
2333 StringCat (tmp, program);
2334 }
2335 nop->host_path = /* StrSaveNoNullEncodeSpaces */ StringSave (tmp);
2336 MemFree (tmp);
2337 nop->query = NULL;
2338 /*
2339 nop->host_path = StrSaveNoNullEncodeSpaces (host_path);
2340 nop->query = StrSaveNoNullEncodeSpaces (program);
2341 */
2342 nop->timeoutsec = timeoutsec;
2343 nop->format = format;
2344 nop->demomode = demomode;
2345 nop->resultproc = resultproc;
2346 nop->paramlist = paramlist;
2347 nop->prefix = StringSaveNoNull (prefix);
2348 nop->suffix = StringSaveNoNull (suffix);
2349 }
2350 SetObjectExtra (i, (Pointer) nop, CleanupAnalysisExtraProc);
2351 if (head == NULL) return;
2352 last = *head;
2353 if (last != NULL) {
2354 while (last->next != NULL) {
2355 last = last->next;
2356 }
2357 last->next = nop;
2358 } else {
2359 *head = nop;
2360 }
2361 }
2362
2363 /* Sample seqncgis.cnf/seqncgis.ini/.seqncgisrc/sequincgi.cfg config file.
2364 PATH can contain query (separated by ? symbol), or separate QUERY item can
2365 be used, or multiple QUERY and TITLE items can also be used.
2366
2367 [SERVICES]
2368 PATH=mydisk:Common Files:services:
2369
2370 [ORDER]
2371 ORDER_1=tRNAscan
2372 ORDER_2=Seg
2373
2374 [tRNAscan]
2375 PROGRAM=testcgi.cgi?request=trnascan
2376 HOST=www.myserver.myschool.edu
2377 PORT=80
2378 PATH=/MyServices/cgi-bin/testcgi.cgi
2379 SUBMENU=Search
2380 FORMATIN=FASTA
2381 FLAGS=SEQ,NUC,TRG
2382 TIMEOUT=30
2383
2384 [Seg]
2385 PROGRAM=segify
2386 HOST=www.myserver.myschool.edu
2387 PORT=80
2388 PATH=/MyServices/cgi-bin/testcgi.cgi
2389 FORMATIN=fasta
2390 FLAGS=SEQ,DOC,PRT,TRG
2391 SUBMENU=Secondary structure prediction
2392 PROMPT_1=Window Size
2393 PARAM_1=window
2394 DESCRIPTION_1=window size for determining low-complexity segments
2395 TYPE_1=text
2396 DEFAULT_1=12
2397 REQUIRED_1=FALSE
2398 IMPORTANCE_1=
2399 GROUP_1=Algorithm
2400 HELP_1=window size for determining low-complexity segments
2401 PROMPT_2=Trigger Complexity
2402 PARAM_2=trigger
2403 DESCRIPTION_2=trigger complexity for determining low-complexity segments
2404 TYPE_2=text
2405 DEFAULT_2=2.2
2406 REQUIRED_2=FALSE
2407 IMPORTANCE_2=
2408 GROUP_2=Algorithm
2409 HELP_2=trigger complexity for determining low-complexity segments
2410 ...
2411
2412 [ENZYMES]
2413 ENZ_1=BamHI
2414 ENZ_2=EcoRI
2415 ENZ_3=HindIII
2416
2417 */
2418
GetServiceParam(ValNodePtr head,CharPtr type,CharPtr buf,Int2 buflen)2419 static Int2 GetServiceParam (ValNodePtr head, CharPtr type, CharPtr buf, Int2 buflen)
2420
2421 {
2422 size_t len;
2423 Boolean seenBracket = FALSE;
2424 CharPtr str;
2425 ValNodePtr vnp;
2426
2427 if (buf == NULL || buflen <= 0) return 0;
2428 *buf = '\0';
2429 len = StringLen (type);
2430 for (vnp = head; vnp != NULL; vnp = vnp->next) {
2431 str = (CharPtr) vnp->data.ptrvalue;
2432 if (str != NULL) {
2433 if (str [0] == '[') {
2434 if (seenBracket) return 0;
2435 seenBracket = TRUE;
2436 } else if (StringNICmp (str, type, len) == 0) {
2437 str += len;
2438 StringNCpy_0 (buf, str, buflen);
2439 return (Int2) StringLen (buf);
2440 }
2441 }
2442 }
2443 return 0;
2444 }
2445
GetConfigParamAndPromptLists(CharPtr sect)2446 static ValNodePtr GetConfigParamAndPromptLists (CharPtr sect)
2447
2448 {
2449 Int2 i;
2450 ValNodePtr paramlist = NULL;
2451 Uint1 paramtype;
2452 Char title [512];
2453 Char tmp [32];
2454 UrlParamPtr upp;
2455
2456 if (sect == NULL) return NULL;
2457 i = 1;
2458 sprintf (tmp, "PARAM_%d", (int) i);
2459 while (GetAppParam ("SEQNCGIS", sect, tmp, NULL, title, sizeof (title) - 1)) {
2460 upp = (UrlParamPtr) MemNew (sizeof (UrlParamData));
2461 if (upp == NULL) continue;
2462 upp->param = StringSave (title);
2463 sprintf (tmp, "TYPE_%d", (int) i);
2464 paramtype = 1;
2465 if (GetAppParam ("SEQNCGIS", sect, tmp, NULL, title, sizeof (title) - 1)) {
2466 if (StringICmp (title, "text") == 0) {
2467 paramtype = 1;
2468 } else if (StringICmp (title, "checkbox") == 0) {
2469 paramtype = 2;
2470 } else if (StringICmp (title, "popup") == 0) {
2471 paramtype = 3;
2472 } else if (StringICmp (title, "radio") == 0) {
2473 paramtype = 4;
2474 } else if (StringICmp (title, "list") == 0) {
2475 paramtype = 5;
2476 }
2477 }
2478 upp->type = paramtype;
2479 sprintf (tmp, "PROMPT_%d", (int) i);
2480 if (GetAppParam ("SEQNCGIS", sect, tmp, NULL, title, sizeof (title) - 1)) {
2481 upp->prompt = StringSave (title);
2482 } else {
2483 upp->prompt = StringSave (upp->param);
2484 }
2485 sprintf (tmp, "DEFAULT_%d", (int) i);
2486 if (GetAppParam ("SEQNCGIS", sect, tmp, NULL, title, sizeof (title) - 1)) {
2487 upp->dfault = StringSave (title);
2488 } else {
2489 upp->dfault = StringSave (" ");
2490 }
2491 sprintf (tmp, "CHOICES_%d", (int) i);
2492 if (GetAppParam ("SEQNCGIS", sect, tmp, NULL, title, sizeof (title) - 1)) {
2493 upp->choices = StringSave (title);
2494 } else {
2495 upp->choices = StringSave (" ");
2496 }
2497 sprintf (tmp, "GROUP_%d", (int) i);
2498 if (GetAppParam ("SEQNCGIS", sect, tmp, NULL, title, sizeof (title) - 1)) {
2499 upp->group = StringSave (title);
2500 } else {
2501 upp->group = StringSave (" ");
2502 }
2503 sprintf (tmp, "HELP_%d", (int) i);
2504 if (GetAppParam ("SEQNCGIS", sect, tmp, NULL, title, sizeof (title) - 1)) {
2505 upp->help = StringSave (title);
2506 } else {
2507 upp->help = StringSave (" ");
2508 }
2509 ValNodeAddPointer (¶mlist, i, (Pointer) upp);
2510 i++;
2511 sprintf (tmp, "PARAM_%d", (int) i);
2512 }
2513 return paramlist;
2514 }
2515
GetServiceParamAndPromptLists(ValNodePtr list)2516 static ValNodePtr GetServiceParamAndPromptLists (ValNodePtr list)
2517
2518 {
2519 Int2 i;
2520 ValNodePtr paramlist = NULL;
2521 Uint1 paramtype;
2522 Char title [512];
2523 Char tmp [32];
2524 UrlParamPtr upp;
2525
2526 if (list == NULL) return NULL;
2527 i = 1;
2528 sprintf (tmp, "PARAM_%d=", (int) i);
2529 while (GetServiceParam (list, tmp, title, sizeof (title) - 1)) {
2530 upp = (UrlParamPtr) MemNew (sizeof (UrlParamData));
2531 if (upp == NULL) continue;
2532 upp->param = StringSave (title);
2533 sprintf (tmp, "TYPE_%d", (int) i);
2534 paramtype = 1;
2535 if (GetServiceParam (list, tmp, title, sizeof (title) - 1)) {
2536 if (StringICmp (title, "text") == 0) {
2537 paramtype = 1;
2538 } else if (StringICmp (title, "checkbox") == 0) {
2539 paramtype = 2;
2540 } else if (StringICmp (title, "popup") == 0) {
2541 paramtype = 3;
2542 } else if (StringICmp (title, "radio") == 0) {
2543 paramtype = 4;
2544 } else if (StringICmp (title, "list") == 0) {
2545 paramtype = 5;
2546 }
2547 }
2548 upp->type = paramtype;
2549 sprintf (tmp, "PROMPT_%d=", (int) i);
2550 if (GetServiceParam (list, tmp, title, sizeof (title) - 1)) {
2551 upp->prompt = StringSave (title);
2552 } else {
2553 upp->prompt = StringSave (upp->param);
2554 }
2555 sprintf (tmp, "DEFAULT_%d=", (int) i);
2556 if (GetServiceParam (list, tmp, title, sizeof (title) - 1)) {
2557 upp->dfault = StringSave (title);
2558 } else {
2559 upp->dfault = StringSave (" ");
2560 }
2561 sprintf (tmp, "CHOICES_%d=", (int) i);
2562 if (GetServiceParam (list, tmp, title, sizeof (title) - 1)) {
2563 upp->choices = StringSave (title);
2564 } else {
2565 upp->choices = StringSave (" ");
2566 }
2567 sprintf (tmp, "GROUP_%d=", (int) i);
2568 if (GetServiceParam (list, tmp, title, sizeof (title) - 1)) {
2569 upp->group = StringSave (title);
2570 } else {
2571 upp->group = StringSave (" ");
2572 }
2573 sprintf (tmp, "HELP_%d=", (int) i);
2574 if (GetServiceParam (list, tmp, title, sizeof (title) - 1)) {
2575 upp->help = StringSave (title);
2576 } else {
2577 upp->help = StringSave (" ");
2578 }
2579 ValNodeAddPointer (¶mlist, i, (Pointer) upp);
2580 i++;
2581 sprintf (tmp, "PARAM_%d=", (int) i);
2582 }
2583 return paramlist;
2584 }
2585
ReadAnalysisConfigFile(CharPtr sect,MenU m,BaseFormPtr bfp,Boolean bspviewOK,Boolean docsumOK,NewObjectPtr PNTR head)2586 static void ReadAnalysisConfigFile (CharPtr sect, MenU m, BaseFormPtr bfp,
2587 Boolean bspviewOK, Boolean docsumOK,
2588 NewObjectPtr PNTR head)
2589
2590 {
2591 Boolean demomode = FALSE;
2592 Int2 format = 1;
2593 Char host [128];
2594 Boolean nucOK = FALSE;
2595 Boolean onlyBspTarget = FALSE;
2596 ValNodePtr paramlist = NULL;
2597 Char program [128];
2598 Char path [256];
2599 Uint2 port = 80;
2600 Char prefix [128];
2601 Boolean protOK = FALSE;
2602 Char submenu [128];
2603 Char suffix [128];
2604 Uint2 timeoutsec = 30;
2605 Char title [128];
2606 Char tmp [32];
2607 unsigned int val;
2608
2609 if (! GetAppParam ("SEQNCGIS", sect, "TITLE", NULL, title, sizeof (title) - 1)) {
2610 StringNCpy_0 (title, sect, sizeof (title));
2611 }
2612 if (GetAppParam ("SEQNCGIS", sect, "HOST", NULL, host, sizeof (host) - 1)) {
2613 if (GetAppParam ("SEQNCGIS", sect, "FLAGS", NULL, tmp, sizeof (tmp) - 1)) {
2614 if (StringStr (tmp, "SEQ") == NULL) {
2615 bspviewOK = FALSE;
2616 }
2617 if (StringStr (tmp, "DOC") == NULL) {
2618 docsumOK = FALSE;
2619 }
2620 if (StringStr (tmp, "NUC") != NULL) {
2621 nucOK = TRUE;
2622 }
2623 if (StringStr (tmp, "PRT") != NULL) {
2624 protOK = TRUE;
2625 }
2626 if (StringStr (tmp, "TRG") != NULL) {
2627 onlyBspTarget = TRUE;
2628 }
2629 }
2630
2631 if ((! bspviewOK) && (! docsumOK)) return;
2632
2633 if (GetAppParam ("SEQNCGIS", sect, "PORT", NULL, tmp, sizeof (tmp) - 1) &&
2634 sscanf (tmp, "%u", &val) == 1) {
2635 port = (Uint2) val;
2636 } else {
2637 port = 80;
2638 }
2639 if (GetAppParam ("SEQNCGIS", sect, "FORMATIN", NULL, tmp, sizeof (tmp) - 1)) {
2640 if (StringICmp (tmp, "FASTA") == 0) {
2641 format = 1;
2642 } else if (StringICmp (tmp, "ASN.1") == 0) {
2643 format = 2;
2644 }
2645 }
2646 if (GetAppParam ("SEQNCGIS", sect, "TIMEOUT", NULL, tmp, sizeof (tmp) - 1) &&
2647 sscanf (tmp, "%u", &val) == 1) {
2648 timeoutsec = (Uint2) val;
2649 } else {
2650 timeoutsec = 30;
2651 }
2652 submenu [0] = '\0';
2653 GetAppParam ("SEQNCGIS", sect, "SUBMENU", NULL, submenu, sizeof (submenu) - 1);
2654 if (GetAppParam ("SEQNCGIS", sect, "DEMO", NULL, tmp, sizeof (tmp) - 1)) {
2655 if (StringICmp (tmp, "TRUE") == 0) {
2656 demomode = TRUE;
2657 }
2658 }
2659
2660 if (GetAppParam ("SEQNCGIS", sect, "PATH", NULL, path, sizeof (path) - 1)) {
2661 if (GetAppParam ("SEQNCGIS", sect, "PROGRAM", NULL, program, sizeof (program) - 1)) {
2662 paramlist = GetConfigParamAndPromptLists (sect);
2663 prefix [0] = '\0';
2664 GetAppParam ("SEQNCGIS", sect, "PREFIX", NULL, prefix, sizeof (prefix) - 1);
2665 suffix [0] = '\0';
2666 GetAppParam ("SEQNCGIS", sect, "SUFFIX", NULL, suffix, sizeof (suffix) - 1);
2667 AddAnalysisItem (m, bfp, bspviewOK, docsumOK,
2668 nucOK, protOK, onlyBspTarget,
2669 host, port, path, program, timeoutsec, format, demomode,
2670 SequinHandleURLResults, paramlist, prefix, suffix,
2671 title, submenu, DoURLProc, head);
2672 }
2673 }
2674 }
2675 }
2676
ReadServiceConfigFile(CharPtr pathbase,ValNodePtr config,MenU m,BaseFormPtr bfp,Boolean bspviewOK,Boolean docsumOK,NewObjectPtr PNTR head)2677 static void ReadServiceConfigFile (CharPtr pathbase, ValNodePtr config,
2678 MenU m, BaseFormPtr bfp,
2679 Boolean bspviewOK, Boolean docsumOK,
2680 NewObjectPtr PNTR head)
2681
2682 {
2683 Char ch;
2684 Boolean demomode = FALSE;
2685 Int2 format = 1;
2686 FILE *fp;
2687 Boolean goOn = TRUE;
2688 Char host [128];
2689 Boolean keepGoing;
2690 ValNodePtr list = NULL;
2691 Boolean nucOK = FALSE;
2692 Boolean onlyBspTarget = FALSE;
2693 ValNodePtr paramlist = NULL;
2694 Char program [128];
2695 Char path [PATH_MAX];
2696 Uint2 port = 0;
2697 Char prefix [128];
2698 Boolean protOK = FALSE;
2699 CharPtr ptr;
2700 Boolean seenBracket;
2701 Char str [256];
2702 Char submenu [128];
2703 Char suffix [128];
2704 Uint2 timeoutsec = 30;
2705 Char title [128];
2706 Char tmp [32];
2707 unsigned int val;
2708 ValNodePtr vnp;
2709
2710 if (path == NULL || config == NULL || config->data.ptrvalue == NULL) return;
2711 StringNCpy_0 (path, pathbase, sizeof (path));
2712 FileBuildPath (path, NULL, (CharPtr) config->data.ptrvalue);
2713 fp = FileOpen (path, "r");
2714 if (fp == NULL) return;
2715 while (FileGets (str, sizeof (str), fp) != NULL) {
2716 ptr = str;
2717 ch = *ptr;
2718 while (ch != '\0' && ch != '\n' && ch != '\r') {
2719 ptr++;
2720 ch = *ptr;
2721 }
2722 *ptr = '\0';
2723 ValNodeCopyStr (&list, 1, str);
2724 }
2725 FileClose (fp);
2726 while (goOn) {
2727 goOn = FALSE;
2728 title [0] = '\0';
2729 if (GetServiceParam (list, "TITLE=", tmp, sizeof (tmp) - 1)) {
2730 StringNCpy_0 (title, tmp, sizeof (title));
2731 }
2732 if (StringHasNoText (title)) {
2733 if (GetServiceParam (list, "[", title, sizeof (title) - 1)) {
2734 ptr = StringChr (title, ']');
2735 if (ptr != NULL) {
2736 *ptr = '\0';
2737 }
2738 }
2739 }
2740 if (title [0] != '\0' && GetServiceParam (list, "HOST=", host, sizeof (host) - 1)) {
2741 if (GetServiceParam (list, "FLAGS=", tmp, sizeof (tmp) - 1)) {
2742 if (StringStr (tmp, "SEQ") == NULL) {
2743 bspviewOK= FALSE;
2744 }
2745 if (StringStr (tmp, "DOC") == NULL) {
2746 docsumOK= FALSE;
2747 }
2748 if (StringStr (tmp, "NUC") != NULL) {
2749 nucOK= TRUE;
2750 }
2751 if (StringStr (tmp, "PRT") != NULL) {
2752 protOK= TRUE;
2753 }
2754 if (StringStr (tmp, "TRG") != NULL) {
2755 onlyBspTarget= TRUE;
2756 }
2757 }
2758
2759 if (bspviewOK || docsumOK) {
2760
2761 if (GetServiceParam (list, "PORT=", tmp, sizeof (tmp) - 1) &&
2762 sscanf (tmp, "%u", &val) == 1) {
2763 port = (Uint2) val;
2764 } else {
2765 port = 0;
2766 }
2767 if (GetServiceParam (list, "FORMATIN=", tmp, sizeof (tmp) - 1)) {
2768 if (StringICmp (tmp, "FASTA") == 0) {
2769 format = 1;
2770 } else if (StringICmp (tmp, "ASN.1") == 0) {
2771 format = 2;
2772 }
2773 }
2774 if (GetServiceParam (list, "TIMEOUT=", tmp, sizeof (tmp) - 1) &&
2775 sscanf (tmp, "%u", &val) == 1) {
2776 timeoutsec = (Uint2) val;
2777 } else {
2778 timeoutsec = 30;
2779 }
2780 submenu [0] = '\0';
2781 GetServiceParam (list, "SUBMENU=", submenu, sizeof (submenu) - 1);
2782 if (GetServiceParam (list, "DEMO=", tmp, sizeof (tmp) - 1)) {
2783 if (StringICmp (tmp, "TRUE") == 0) {
2784 demomode = TRUE;
2785 }
2786 }
2787
2788 if (GetServiceParam (list, "PATH=", path, sizeof (path) - 1)) {
2789 if (GetServiceParam (list, "PROGRAM=", program, sizeof (program) - 1)) {
2790 paramlist = GetServiceParamAndPromptLists (list);
2791 prefix [0] = '\0';
2792 GetServiceParam (list, "PREFIX=", prefix, sizeof (prefix) - 1);
2793 suffix [0] = '\0';
2794 GetServiceParam (list, "SUFFIX=", suffix, sizeof (suffix) - 1);
2795 AddAnalysisItem (m, bfp, bspviewOK, docsumOK,
2796 nucOK, protOK, onlyBspTarget,
2797 host, port, path, program, timeoutsec, format, demomode,
2798 SequinHandleURLResults, paramlist, prefix, suffix,
2799 title, submenu, DoURLProc, head);
2800 }
2801 }
2802
2803 }
2804 }
2805
2806 seenBracket = FALSE;
2807 keepGoing = TRUE;
2808 for (vnp = list; vnp != NULL && keepGoing; vnp = vnp->next) {
2809 ptr = (CharPtr) vnp->data.ptrvalue;
2810 if (ptr != NULL) {
2811 if (ptr [0] == '[') {
2812 if (seenBracket) {
2813 keepGoing = FALSE;
2814 } else {
2815 seenBracket = TRUE;
2816 }
2817 }
2818 if (keepGoing) {
2819 vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
2820 }
2821 }
2822 }
2823
2824 }
2825
2826 ValNodeFreeData (list);
2827 }
2828
CreateAnalysisMenu(WindoW w,BaseFormPtr bfp,Boolean bspviewOK,Boolean docsumOK)2829 extern MenU CreateAnalysisMenu (WindoW w, BaseFormPtr bfp, Boolean bspviewOK, Boolean docsumOK)
2830
2831 {
2832 NewObjectPtr first;
2833 ValNodePtr head1 = NULL, head2 = NULL;
2834 Int2 i;
2835 size_t len;
2836 MenU m;
2837 Char path1 [PATH_MAX];
2838 Char path2 [PATH_MAX];
2839 CharPtr ptr;
2840 SbstrucPtr sbp;
2841 Char sect [256];
2842 Char temp [32];
2843 ValNodePtr vnp;
2844
2845 ProgramPath (path1, sizeof (path1));
2846 ptr = StringRChr (path1, DIRDELIMCHR);
2847 if (ptr != NULL) {
2848 ptr++;
2849 *ptr = '\0';
2850 }
2851 FileBuildPath (path1, "services", NULL);
2852 head1 = DirCatalog (path1);
2853
2854 if (GetAppParam ("SEQNCGIS", "SERVICES", "PATH", NULL, path2, sizeof (path2) - 1)) {
2855 len = StringLen (path2);
2856 if (path2 [len - 1] != DIRDELIMCHR) {
2857 StringCat (path2, DIRDELIMSTR);
2858 }
2859 if (StringCmp (path1, path2) != 0) {
2860 head2 = DirCatalog (path2);
2861 }
2862 }
2863
2864 if ((! extraServices) && (! indexerVersion) && (! genomeCenter) &&
2865 head1 == NULL && head2 == NULL) {
2866 if (! GetAppParam ("SEQNCGIS", "ORDER", NULL, NULL, sect, sizeof (sect) - 1)) {
2867 return NULL;
2868 }
2869 }
2870 m = PulldownMenu (w, "Analysis");
2871 if (m == NULL) return NULL;
2872 analysissubmenulist = NULL;
2873 first = NULL;
2874 if (bspviewOK) {
2875 AddAnalysisItem (m, bfp, bspviewOK, FALSE, TRUE, FALSE, TRUE,
2876 NULL, 0, NULL, NULL, 0, 0, FALSE, NULL, NULL, NULL, NULL,
2877 "Restriction Search", "Search",
2878 SimpleRsiteProc, &first);
2879 if (indexerVersion) {
2880 AddAnalysisItem (m, bfp, bspviewOK, FALSE, TRUE, FALSE, TRUE,
2881 NULL, 0, NULL, NULL, 0, 0, FALSE, NULL, NULL, NULL, NULL,
2882 "QBlast Test", "Search",
2883 SimpleQBlastProc, &first);
2884 }
2885 }
2886 if (bspviewOK || docsumOK) {
2887 if (useEntrez) {
2888 i = 1;
2889 sprintf (temp, "ORDER_%d", (int) i);
2890 while (GetAppParam ("SEQNCGIS", "ORDER", temp, NULL, sect, sizeof (sect) - 1)) {
2891 ReadAnalysisConfigFile (sect, m, bfp, bspviewOK, docsumOK, &first);
2892 i++;
2893 sprintf (temp, "ORDER_%d", (int) i);
2894 }
2895 for (vnp = head1; vnp != NULL; vnp = vnp->next) {
2896 if (vnp->choice == 0) {
2897 ReadServiceConfigFile (path1, vnp, m, bfp, bspviewOK, docsumOK, &first);
2898 }
2899 }
2900 for (vnp = head2; vnp != NULL; vnp = vnp->next) {
2901 if (vnp->choice == 0) {
2902 ReadServiceConfigFile (path2, vnp, m, bfp, bspviewOK, docsumOK, &first);
2903 }
2904 }
2905 }
2906 }
2907 if (bspviewOK) {
2908 }
2909 if (docsumOK) {
2910 }
2911 #ifdef WIN_MAC
2912 macUserDataPtr = LinkNewObjectLists (macUserDataPtr, first);
2913 #else
2914 bfp->userDataPtr = LinkNewObjectLists (bfp->userDataPtr, first);
2915 #endif
2916 for (vnp = analysissubmenulist; vnp != NULL; vnp = vnp->next) {
2917 sbp = (SbstrucPtr) vnp->data.ptrvalue;
2918 if (sbp != NULL) {
2919 sbp->name = MemFree (sbp->name);
2920 }
2921 }
2922 analysissubmenulist = ValNodeFreeData (analysissubmenulist);
2923 ValNodeFreeData (head1);
2924 ValNodeFreeData (head2);
2925 return m;
2926 }
2927
2928 /* NEW UPDATE SEQUENCE SECTION */
2929
2930
2931 #define SQN_LEFT 1
2932 #define SQN_RIGHT 2
2933 #define SQN_MIDDLE 3
2934
ListPhrapGraphsCallback(SeqGraphPtr sgp,Pointer userdata)2935 static void ListPhrapGraphsCallback (SeqGraphPtr sgp, Pointer userdata)
2936 {
2937 ValNodePtr PNTR vnpp;
2938
2939 if (sgp == NULL || userdata == NULL) return;
2940 if (StringICmp (sgp->title, "Phrap Quality") == 0)
2941 {
2942 vnpp = (ValNodePtr PNTR) userdata;
2943 ValNodeAddPointer (vnpp, 0, sgp);
2944 }
2945 }
2946
2947 /* THOUGHTS:
2948 * Can we/must we update quality scores before/after the old Bioseq has been replaced?
2949 * If we replace quality scores after the bioseq has been replaced, the oldbsp->length
2950 * is the length of the buffer we need to hold the quality scores,
2951 * otherwise use the newbsp->length.
2952 * Useful functions:
2953 aln_len = AlnMgr2GetAlnLength(salp, FALSE);
2954
2955 NLM_EXTERN Int4 AlnMgr2GetNumAlnBlocks(SeqAlignPtr sap)
2956 NLM_EXTERN Boolean AlnMgr2GetNthBlockRange(SeqAlignPtr sap, Int4 n, Int4Ptr start, Int4Ptr stop)
2957
2958
2959 * Assumptions: data replacement has already taken place, oldbsp is in row 1 of salp,
2960 * newbsp is in row 2 of salp.
2961
2962 */
2963 static Boolean
ReplaceQualityScores(BioseqPtr oldbsp,BioseqPtr newbsp,FILE * log_fp,BoolPtr data_in_log)2964 ReplaceQualityScores
2965 (BioseqPtr oldbsp,
2966 BioseqPtr newbsp,
2967 FILE *log_fp,
2968 BoolPtr data_in_log)
2969 {
2970 ValNodePtr oldhead = NULL, newhead = NULL, vnp;
2971 SeqGraphPtr sgp, last_sgp = NULL, new_sgp;
2972 SeqAnnotPtr sap, last_sap;
2973 Char acc_str [256];
2974
2975 if (oldbsp == NULL || newbsp == NULL
2976 || !ISA_na (oldbsp->mol) || !ISA_na (newbsp->mol))
2977 {
2978 return FALSE;
2979 }
2980
2981 /* first, remove old scores */
2982 VisitGraphsOnBsp (oldbsp, &oldhead, ListPhrapGraphsCallback);
2983 for (vnp = oldhead; vnp != NULL; vnp = vnp->next)
2984 {
2985 sgp = vnp->data.ptrvalue;
2986 if (sgp != NULL)
2987 {
2988 sgp->idx.deleteme = TRUE;
2989 }
2990 }
2991 oldhead = ValNodeFree (oldhead);
2992 DeleteMarkedObjects (0, OBJ_BIOSEQ, (Pointer) oldbsp);
2993
2994 /* now copy new quality scores to old sequence */
2995 VisitGraphsOnBsp (newbsp, &newhead, ListPhrapGraphsCallback);
2996
2997 if (newhead == NULL)
2998 {
2999 if (log_fp != NULL && data_in_log != NULL)
3000 {
3001 SeqIdWrite (oldbsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
3002 fprintf (log_fp, "Quality scores cleared for %s\n", acc_str);
3003 *data_in_log = TRUE;
3004 }
3005 }
3006 else
3007 {
3008 /* now add in new phrap annotations */
3009 last_sap = NULL;
3010 last_sgp = NULL;
3011 for (sap = oldbsp->annot; sap != NULL && sap->type !=3; sap = sap->next)
3012 {
3013 last_sap = sap;
3014 }
3015
3016 if (sap == NULL)
3017 {
3018 sap = SeqAnnotNew ();
3019 sap->type = 3;
3020 sap->data = NULL;
3021 if (last_sap == NULL)
3022 {
3023 oldbsp->annot = sap;
3024 }
3025 else
3026 {
3027 last_sap->next = sap;
3028 }
3029 }
3030
3031
3032 for (sgp = (SeqGraphPtr) sap->data; sgp != NULL; sgp = sgp->next)
3033 {
3034 last_sgp = sgp;
3035 }
3036 for (vnp = newhead; vnp != NULL; vnp = vnp->next)
3037 {
3038 sgp = (SeqGraphPtr) vnp->data.ptrvalue;
3039 if (sgp != NULL)
3040 {
3041 new_sgp = (SeqGraphPtr) AsnIoMemCopy (sgp, (AsnReadFunc) SeqGraphAsnRead, (AsnWriteFunc) SeqGraphAsnWrite);
3042 if (new_sgp != NULL)
3043 {
3044 new_sgp->next = NULL;
3045 if (last_sgp == NULL)
3046 {
3047 sap->data = new_sgp;
3048 }
3049 else
3050 {
3051 last_sgp->next = new_sgp;
3052 }
3053 last_sgp = new_sgp;
3054 }
3055 }
3056 }
3057 SeqIdWrite (oldbsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
3058 fprintf (log_fp, "Replaced quality scores for %s\n", acc_str);
3059 *data_in_log = TRUE;
3060 }
3061
3062
3063 return TRUE;
3064 }
3065
3066
3067 #define SEQGRAPH_FloatHi 1
3068 #define SEQGRAPH_Int4 2
3069 #define SEQGRAPH_BS 3
3070
3071 /* remove compression from SeqGraph */
ExpandSeqGraph(SeqGraphPtr sgp)3072 static Boolean ExpandSeqGraph (SeqGraphPtr sgp)
3073 {
3074 Int4 oldpos = 0, newpos = 0, i;
3075 Pointer new_values = NULL;
3076 Int4 new_numval;
3077 Int2 cur_byte;
3078
3079 if (sgp == NULL || sgp->compr == 0 || sgp->compr == 1) {
3080 return TRUE;
3081 } else if (sgp->compr < 0) {
3082 return FALSE;
3083 }
3084
3085 new_numval = sgp->numval * sgp->compr;
3086
3087 /* allocate space for new values */
3088 switch (sgp->flags[2]) {
3089 case SEQGRAPH_FloatHi:
3090 new_values = MemNew (sizeof (FloatHi) * new_numval);
3091 break;
3092 case SEQGRAPH_Int4:
3093 new_values = MemNew (sizeof (Int4) * new_numval);
3094 break;
3095 case SEQGRAPH_BS:
3096 new_values = (Pointer) BSNew (new_numval);
3097 BSSeek ((ByteStorePtr)new_values, 0, SEEK_SET);
3098 BSSeek ((ByteStorePtr) sgp->values, 0, SEEK_SET);
3099 break;
3100 }
3101
3102 /* copy and expand */
3103 while (oldpos < sgp->numval) {
3104 cur_byte = 0;
3105 if (sgp->flags[2] == SEQGRAPH_BS) {
3106 cur_byte = BSGetByte ((ByteStorePtr) sgp->values);
3107 }
3108 for (i = 0; i < sgp->compr; i++) {
3109 switch (sgp->flags[2]) {
3110 case SEQGRAPH_FloatHi:
3111 ((FloatHiPtr)new_values)[newpos++] = ((FloatHiPtr)sgp->values)[oldpos];
3112 break;
3113 case SEQGRAPH_Int4:
3114 ((Int4Ptr)new_values)[newpos++] = ((Int4Ptr)sgp->values)[oldpos];
3115 break;
3116 case SEQGRAPH_BS:
3117 BSPutByte ((ByteStorePtr) new_values, cur_byte);
3118 break;
3119 }
3120 }
3121 oldpos++;
3122 }
3123
3124 /* free old values and replace with new */
3125 if (sgp->flags[2] == SEQGRAPH_BS) {
3126 sgp->values = BSFree ((ByteStorePtr) sgp->values);
3127 } else {
3128 sgp->values = MemFree (sgp->values);
3129 }
3130 sgp->values = new_values;
3131 sgp->numval = new_numval;
3132 sgp->compr = 0;
3133
3134 return TRUE;
3135 }
3136
TruncateSeqGraphValues(SeqGraphPtr sgp,Int4 len,Boolean onleft)3137 static Boolean TruncateSeqGraphValues (SeqGraphPtr sgp, Int4 len, Boolean onleft)
3138 {
3139 Int4 oldpos, newpos = 0;
3140 Pointer new_values = NULL;
3141 Int4 new_numval;
3142 Int2 cur_byte;
3143 Int4 imin = 0, imax = 0;
3144 FloatHi fmin, fmax;
3145
3146 if (sgp == NULL) return TRUE;
3147 if (!ExpandSeqGraph (sgp)) return FALSE;
3148
3149 new_numval = sgp->numval - len;
3150
3151 /* allocate space for new values */
3152 switch (sgp->flags[2]) {
3153 case SEQGRAPH_FloatHi:
3154 new_values = MemNew (sizeof (FloatHi) * new_numval);
3155 fmin = ((FloatHiPtr)sgp->values)[0];
3156 fmax = fmin;
3157 break;
3158 case SEQGRAPH_Int4:
3159 new_values = MemNew (sizeof (Int4) * new_numval);
3160 imin = ((Int4Ptr)sgp->values)[0];
3161 imax = imin;
3162 break;
3163 case SEQGRAPH_BS:
3164 new_values = (Pointer) BSNew (new_numval);
3165 BSSeek ((ByteStorePtr)new_values, 0, SEEK_SET);
3166 if (onleft) {
3167 BSSeek ((ByteStorePtr) sgp->values, len, SEEK_SET);
3168 } else {
3169 BSSeek ((ByteStorePtr) sgp->values, 0, SEEK_SET);
3170 }
3171 imin = BSGetByte ((ByteStorePtr) sgp->values);
3172 imax = imin;
3173 /* put pointer back */
3174 if (onleft) {
3175 BSSeek ((ByteStorePtr) sgp->values, len, SEEK_SET);
3176 } else {
3177 BSSeek ((ByteStorePtr) sgp->values, 0, SEEK_SET);
3178 }
3179 break;
3180 }
3181
3182 /* copy */
3183 if (onleft) {
3184 oldpos = len;
3185 } else {
3186 oldpos = 0;
3187 }
3188 while (oldpos < sgp->numval && newpos < new_numval) {
3189 switch (sgp->flags[2]) {
3190 case SEQGRAPH_FloatHi:
3191 ((FloatHiPtr)new_values)[newpos] = ((FloatHiPtr)sgp->values)[oldpos];
3192 if (((FloatHiPtr)new_values)[newpos] > fmax) {
3193 fmax = ((FloatHiPtr)new_values)[newpos];
3194 }
3195 if (((FloatHiPtr)new_values)[newpos] < fmin) {
3196 fmin = ((FloatHiPtr)new_values)[newpos];
3197 }
3198 break;
3199 case SEQGRAPH_Int4:
3200 ((Int4Ptr)new_values)[newpos] = ((Int4Ptr)sgp->values)[oldpos];
3201 if (((Int4Ptr)new_values)[newpos] > imax) {
3202 imax = ((Int4Ptr)new_values)[newpos];
3203 }
3204 if (((Int4Ptr)new_values)[newpos] < imin) {
3205 imin = ((Int4Ptr)new_values)[newpos];
3206 }
3207 break;
3208 case SEQGRAPH_BS:
3209 cur_byte = BSGetByte ((ByteStorePtr) sgp->values);
3210 BSPutByte ((ByteStorePtr) new_values, cur_byte);
3211 if (cur_byte > imax) {
3212 imax = cur_byte;
3213 }
3214 if (cur_byte < imin) {
3215 imin = cur_byte;
3216 }
3217 break;
3218 }
3219 oldpos++;
3220 newpos++;
3221 }
3222
3223 /* free old values and replace with new */
3224 if (sgp->flags[2] == SEQGRAPH_BS) {
3225 sgp->values = BSFree ((ByteStorePtr) sgp->values);
3226 } else {
3227 sgp->values = MemFree (sgp->values);
3228 }
3229 sgp->values = new_values;
3230 sgp->numval = new_numval;
3231
3232 /* replace mins and maxes */
3233 if (sgp->flags[2] == SEQGRAPH_FloatHi) {
3234 sgp->max.realvalue = fmax;
3235 sgp->min.realvalue = fmin;
3236 } else {
3237 sgp->max.intvalue = imax;
3238 sgp->min.intvalue = imin;
3239 }
3240 return TRUE;
3241 }
3242
3243
3244
3245 /* assume Bioseq has already been trimmed - length of old Bioseq was trim5 + bsp->length + trim3 */
3246 static Boolean
TrimQualityScoresForSequenceUpdate(BioseqPtr bsp,Int4 trim5,Int4 trim3,FILE * log_fp,BoolPtr data_in_log)3247 TrimQualityScoresForSequenceUpdate
3248 (BioseqPtr bsp,
3249 Int4 trim5,
3250 Int4 trim3,
3251 FILE *log_fp,
3252 BoolPtr data_in_log)
3253 {
3254 ValNodePtr score_list = NULL, vnp;
3255 SeqGraphPtr sgp;
3256 SeqIntPtr sip;
3257 Int4 left, right;
3258 Boolean rval = FALSE;
3259 Char acc_str [256];
3260
3261 if (bsp == NULL) return FALSE;
3262
3263 VisitGraphsOnBsp (bsp, &score_list, ListPhrapGraphsCallback);
3264 if (score_list == NULL) return FALSE;
3265
3266 for (vnp = score_list; vnp != NULL; vnp = vnp->next) {
3267 sgp = vnp->data.ptrvalue;
3268 if (sgp != NULL && sgp->loc != NULL && sgp->loc->choice == SEQLOC_INT) {
3269 sip = (SeqIntPtr) sgp->loc->data.ptrvalue;
3270 /* trim on right */
3271 if (sip->from > trim5 + bsp->length) {
3272 sgp->idx.deleteme = TRUE;
3273 rval = TRUE;
3274 } else if (sip->to > trim5 + bsp->length - 1) {
3275 right = sip->to - trim5 - bsp->length + 1;
3276 sip->to = trim5 + bsp->length - 1;
3277 TruncateSeqGraphValues (sgp, right, FALSE);
3278 rval = TRUE;
3279 }
3280
3281 sip->from -= trim5;
3282 sip->to -= trim5;
3283 if (sip->to < 0) {
3284 sgp->idx.deleteme = TRUE;
3285 rval = TRUE;
3286 } else if (sip->from < 0) {
3287 left = 0 - sip->from;
3288 sip->from = 0;
3289 TruncateSeqGraphValues (sgp, left, TRUE);
3290 rval = TRUE;
3291 }
3292 }
3293 }
3294
3295 if (rval && log_fp != NULL && data_in_log != NULL) {
3296 SeqIdWrite (bsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
3297 fprintf (log_fp, "Quality scores trimmed for %s\n", acc_str);
3298 *data_in_log = TRUE;
3299 }
3300 return rval;
3301 }
3302
3303
AdjustAlignment(UpsDataPtr udp,Int2 choice)3304 static Boolean AdjustAlignment (
3305 UpsDataPtr udp,
3306 Int2 choice
3307 )
3308
3309 {
3310 DenseSegPtr dsp;
3311 Int2 j;
3312 SeqAlignPtr sap;
3313
3314 if (udp == NULL) return FALSE;
3315
3316 sap = udp->salp;
3317 if (sap == NULL) return FALSE;
3318 AMFreeAllIndexes (sap);
3319
3320 if (sap->segtype == SAS_DENSEG) {
3321 dsp = (DenseSegPtr) sap->segs;
3322
3323 switch (choice) {
3324 case 2 :
3325 /* adjust alignment 5' */
3326 if (dsp != NULL && dsp->lens != NULL && dsp->numseg > 0) {
3327 dsp->lens [dsp->numseg - 1] += udp->old3;
3328 }
3329 break;
3330 case 3 :
3331 /* adjust alignment 3' */
3332 if (dsp != NULL && dsp->lens != NULL && dsp->starts != NULL && dsp->numseg > 0) {
3333 dsp->lens [0] += udp->old5;
3334 dsp->starts [0] = 0;
3335 dsp->starts [1] = 0;
3336 for (j = 1; j < dsp->numseg; j++) {
3337 if (dsp->starts [1 + j * 2] != -1) {
3338 dsp->starts [1 + j * 2] += udp->old5 - udp->new5;
3339 }
3340 }
3341 }
3342 break;
3343 case 4 :
3344 /* adjust alignment patch */
3345 if (dsp != NULL && dsp->lens != NULL && dsp->starts != NULL && dsp->numseg > 0) {
3346 dsp->lens [dsp->numseg - 1] += udp->old3;
3347 dsp->lens [0] += udp->old5;
3348 dsp->starts [0] = 0;
3349 dsp->starts [1] = 0;
3350 for (j = 1; j < dsp->numseg; j++) {
3351 if (dsp->starts [1 + j * 2] != -1) {
3352 dsp->starts [1 + j * 2] += udp->old5 - udp->new5;
3353 }
3354 }
3355 }
3356 break;
3357 default :
3358 break;
3359 }
3360 }
3361
3362 AlnMgr2IndexSingleChildSeqAlign (sap);
3363
3364 return TRUE;
3365 }
3366
OffsetLoc(SeqLocPtr slp,Int4 offset,SeqIdPtr sip)3367 static void OffsetLoc (SeqLocPtr slp, Int4 offset, SeqIdPtr sip)
3368
3369 {
3370 PackSeqPntPtr psp;
3371 SeqIntPtr sinp;
3372 SeqPntPtr spp;
3373 Uint1 used;
3374
3375 if (slp == NULL) return;
3376 switch (slp->choice) {
3377 case SEQLOC_INT :
3378 sinp = (SeqIntPtr) slp->data.ptrvalue;
3379 if (sinp != NULL) {
3380 sinp->from += offset;
3381 sinp->to += offset;
3382 if (sip != NULL) {
3383 sinp->id = SeqIdFree (sinp->id);
3384 sinp->id = SeqIdDup (sip);
3385 }
3386 }
3387 break;
3388 case SEQLOC_PNT :
3389 spp = (SeqPntPtr) slp->data.ptrvalue;
3390 if (spp != NULL) {
3391 spp->point += offset;
3392 if (sip != NULL) {
3393 spp->id = SeqIdFree (spp->id);
3394 spp->id = SeqIdDup (sip);
3395 }
3396 }
3397 break;
3398 case SEQLOC_PACKED_PNT :
3399 psp = (PackSeqPntPtr) slp->data.ptrvalue;
3400 if (psp != NULL) {
3401 for (used = 0; used < psp->used; used++) {
3402 psp->pnts [used] += offset;
3403 }
3404 if (sip != NULL) {
3405 psp->id = SeqIdFree (psp->id);
3406 psp->id = SeqIdDup (sip);
3407 }
3408 }
3409 break;
3410 default :
3411 break;
3412 }
3413 }
3414
OffsetLocation(SeqLocPtr loc,Int4 offset,SeqIdPtr sip)3415 extern void OffsetLocation (SeqLocPtr loc, Int4 offset, SeqIdPtr sip)
3416
3417 {
3418 SeqLocPtr slp;
3419
3420 slp = SeqLocFindNext (loc, NULL);
3421 while (slp != NULL) {
3422 OffsetLoc (slp, offset, sip);
3423 slp = SeqLocFindNext (loc, slp);
3424 }
3425 }
3426
PromoteSeqId(SeqIdPtr sip,Pointer userdata)3427 static void PromoteSeqId (SeqIdPtr sip, Pointer userdata)
3428
3429 {
3430 SeqIdPtr bestid, newid, oldid;
3431
3432 bestid = (SeqIdPtr) userdata;
3433
3434 newid = SeqIdDup (bestid);
3435 if (newid == NULL) return;
3436
3437 oldid = ValNodeNew (NULL);
3438 if (oldid == NULL) return;
3439
3440 MemCopy (oldid, sip, sizeof (ValNode));
3441 oldid->next = NULL;
3442
3443 sip->choice = newid->choice;
3444 sip->data.ptrvalue = newid->data.ptrvalue;
3445
3446 SeqIdFree (oldid);
3447 ValNodeFree (newid);
3448
3449 SeqIdStripLocus (sip);
3450 }
3451
CorrectFeatureSeqIds(SeqFeatPtr sfp,Pointer userdata)3452 static void CorrectFeatureSeqIds (
3453 SeqFeatPtr sfp,
3454 Pointer userdata
3455 )
3456
3457 {
3458 VisitSeqIdsInSeqLoc (sfp->location, userdata, PromoteSeqId);
3459 }
3460
DoFeaturePropWithOffset(UpsDataPtr udp,Int4 offset,SeqAnnotPtr PNTR sapp,Boolean patch)3461 static Boolean DoFeaturePropWithOffset (
3462 UpsDataPtr udp,
3463 Int4 offset,
3464 SeqAnnotPtr PNTR sapp,
3465 Boolean patch
3466 )
3467
3468 {
3469 BioseqPtr bsp, newbsp, oldbsp;
3470 CodeBreakPtr cbp;
3471 SeqMgrFeatContext context;
3472 CdRegionPtr crp;
3473 SeqFeatPtr dup, sfp, last = NULL;
3474 Uint2 entityID;
3475 Boolean keepProteinIDs;
3476 SeqEntryPtr newsep, prdsep, top;
3477 RnaRefPtr rrp;
3478 SeqAnnotPtr sap = NULL, saptmp;
3479 SeqDescrPtr sdp;
3480 SeqIdPtr sip;
3481 tRNAPtr trp;
3482
3483 if (udp == NULL) return FALSE;
3484
3485 SeqEntrySetScope (NULL);
3486
3487 sfp = SeqMgrGetNextFeature (udp->newbsp, NULL, 0, 0, &context);
3488 if (sfp == NULL) return FALSE;
3489
3490 if (udp->diffOrgs) {
3491 keepProteinIDs = FALSE;
3492 } else {
3493 keepProteinIDs = GetStatus (udp->keepProteinIDs);
3494 }
3495
3496 oldbsp = udp->oldbsp;
3497
3498 entityID = ObjMgrGetEntityIDForPointer (udp->oldbsp);
3499 top = GetBestTopParentForData (entityID, udp->oldbsp);
3500
3501 sdp = ExtractBioSourceAndPubs (top);
3502
3503 sip = SeqIdFindBest (oldbsp->id, 0);
3504
3505 while (sfp != NULL) {
3506
3507 if ((! patch) || (context.right >= udp->new5 && context.left <= udp->new5 + udp->newa)) {
3508
3509 dup = AsnIoMemCopy ((Pointer) sfp,
3510 (AsnReadFunc) SeqFeatAsnRead,
3511 (AsnWriteFunc) SeqFeatAsnWrite);
3512
3513 if (last == NULL) {
3514 sap = SeqAnnotNew ();
3515 if (oldbsp->annot == NULL) {
3516 oldbsp->annot = sap;
3517 } else {
3518 for (saptmp = oldbsp->annot; saptmp->next != NULL; saptmp = saptmp->next) continue;
3519 saptmp->next = sap;
3520 }
3521 sap->type = 1;
3522 sap->data = (Pointer) dup;
3523 } else {
3524 last->next = dup;
3525 }
3526 last = dup;
3527
3528 /*
3529 sep = SeqMgrGetSeqEntryForData (oldbsp);
3530 CreateNewFeature (sep, NULL, dup->data.choice, dup);
3531 */
3532
3533 OffsetLocation (dup->location, offset, sip);
3534 switch (dup->data.choice) {
3535 case SEQFEAT_CDREGION :
3536 crp = (CdRegionPtr) dup->data.value.ptrvalue;
3537 if (crp != NULL) {
3538 for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
3539 OffsetLocation (cbp->loc, offset, sip);
3540 }
3541 }
3542 break;
3543 case SEQFEAT_RNA :
3544 rrp = (RnaRefPtr) dup->data.value.ptrvalue;
3545 if (rrp != NULL && rrp->ext.choice == 2) {
3546 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
3547 if (trp != NULL && trp->anticodon != NULL) {
3548 OffsetLocation (trp->anticodon, offset, sip);
3549 }
3550 }
3551 break;
3552 default :
3553 break;
3554 }
3555 if (dup->product != NULL) {
3556 SeqEntrySetScope (NULL);
3557 bsp = BioseqFindFromSeqLoc (dup->product);
3558 if (bsp != NULL) {
3559 prdsep = SeqMgrGetSeqEntryForData (bsp);
3560 if (prdsep != NULL) {
3561 newsep = AsnIoMemCopy ((Pointer) prdsep,
3562 (AsnReadFunc) SeqEntryAsnRead,
3563 (AsnWriteFunc) SeqEntryAsnWrite);
3564 if (newsep != NULL) {
3565 if (IS_Bioseq (newsep)) {
3566 newbsp = (BioseqPtr) newsep->data.ptrvalue;
3567 if (newbsp != NULL) {
3568 if (! keepProteinIDs) {
3569 newbsp->id = SeqIdSetFree (newbsp->id);
3570 newbsp->id = MakeNewProteinSeqId (NULL, sip);
3571 newbsp->hist = SeqHistFree (newbsp->hist);
3572 VisitFeaturesOnBsp (newbsp, (Pointer) newbsp->id, CorrectFeatureSeqIds);
3573 SetSeqFeatProduct (dup, newbsp);
3574 /*
3575 dup->product = SeqLocFree (dup->product);
3576 dup->product = CreateWholeInterval (newsep);
3577 */
3578 }
3579 SeqMgrReplaceInBioseqIndex (newbsp);
3580 }
3581 }
3582 AddSeqEntryToSeqEntry (top, newsep, TRUE);
3583 }
3584 }
3585 }
3586 }
3587 }
3588
3589 sfp = SeqMgrGetNextFeature (udp->newbsp, sfp, 0, 0, &context);
3590 }
3591
3592 ReplaceBioSourceAndPubs (top, sdp);
3593
3594 if (sapp != NULL) {
3595 *sapp = sap;
3596 }
3597
3598 return TRUE;
3599 }
3600
LengthForNewSequence(UpsDataPtr udp)3601 static Int4 LengthForNewSequence (UpsDataPtr udp)
3602 {
3603 Int4 new_len = 0;
3604
3605 if (udp == NULL)
3606 {
3607 return 0;
3608 }
3609 else if (GetValue (udp->sfb) == UPDATE_FEATURES_ONLY)
3610 {
3611 new_len = udp->oldbsp->length;
3612 }
3613 else if (udp->rmcval == UPDATE_PATCH)
3614 {
3615 new_len = udp->old5 + udp->newa + udp->old3;
3616 }
3617 else if (udp->rmcval == UPDATE_REPLACE)
3618 {
3619 new_len = udp->new5 + udp->newa + udp->new3;
3620 }
3621 else if (udp->rmcval == UPDATE_EXTEND5)
3622 {
3623 new_len = udp->new5 + udp->olda + udp->old3;
3624 }
3625 else if (udp->rmcval == UPDATE_EXTEND3)
3626 {
3627 new_len = udp->old5 + udp->olda + udp->new3;
3628 }
3629 return new_len;
3630 }
3631
3632 static SeqLocPtr
GetPropagatedLocation(SeqLocPtr orig_loc,BioseqPtr newbsp,BioseqPtr oldbsp,Int4 new_len,SeqAlignPtr salp)3633 GetPropagatedLocation
3634 (SeqLocPtr orig_loc,
3635 BioseqPtr newbsp,
3636 BioseqPtr oldbsp,
3637 Int4 new_len,
3638 SeqAlignPtr salp)
3639 {
3640 SeqLocPtr tmp_loc, new_loc;
3641 Boolean split;
3642
3643 tmp_loc = SeqLocCopy (orig_loc);
3644 ReplaceComplexLocation (tmp_loc, salp, new_len, 2, 1);
3645
3646 new_loc = SeqLocCopyRegion (oldbsp->id, tmp_loc, newbsp, 0, oldbsp->length - 1, Seq_strand_plus, &split);
3647
3648 tmp_loc = SeqLocFree (tmp_loc);
3649
3650 return new_loc;
3651 }
3652
3653
DoFeaturePropThruAlign(UpsDataPtr udp,SeqAnnotPtr PNTR sapp)3654 static Boolean DoFeaturePropThruAlign (
3655 UpsDataPtr udp,
3656 SeqAnnotPtr PNTR sapp
3657 )
3658
3659 {
3660 BioseqPtr bsp, newbsp, oldbsp;
3661 CodeBreakPtr cbp, prevcbp, nextcbp;
3662 SeqMgrFeatContext context;
3663 CdRegionPtr crp;
3664 SeqFeatPtr dup, sfp, last = NULL;
3665 Uint2 entityID;
3666 Int4 from, to;
3667 Boolean keepProteinIDs;
3668 SeqLocPtr newloc;
3669 SeqEntryPtr newsep, prdsep, top;
3670 RnaRefPtr rrp;
3671 SeqAnnotPtr sap = NULL, saptmp;
3672 SeqDescrPtr sdp;
3673 SeqIdPtr sip;
3674 Boolean split;
3675 tRNAPtr trp;
3676 Boolean partial5, partial3;
3677
3678 if (udp == NULL) return FALSE;
3679
3680 SeqEntrySetScope (NULL);
3681
3682 sfp = SeqMgrGetNextFeature (udp->newbsp, NULL, 0, 0, &context);
3683 if (sfp == NULL) return FALSE;
3684
3685 keepProteinIDs = GetStatus (udp->keepProteinIDs);
3686
3687 oldbsp = udp->oldbsp;
3688
3689 entityID = ObjMgrGetEntityIDForPointer (oldbsp);
3690 top = GetBestTopParentForData (entityID, oldbsp);
3691
3692 sdp = ExtractBioSourceAndPubs (top);
3693
3694 sip = SeqIdFindBest (oldbsp->id, 0);
3695
3696 from = udp->new5;
3697 to = udp->new5 + udp->newa;
3698
3699 while (sfp != NULL) {
3700
3701 if (context.right >= from && context.left <= to) {
3702 split = FALSE;
3703 newloc = GetPropagatedLocation (sfp->location, udp->newbsp, udp->oldbsp,
3704 LengthForNewSequence (udp), udp->salp);
3705 if (newloc != NULL) {
3706 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
3707 SetSeqLocPartial (newloc, partial5, partial3);
3708 dup = AsnIoMemCopy ((Pointer) sfp,
3709 (AsnReadFunc) SeqFeatAsnRead,
3710 (AsnWriteFunc) SeqFeatAsnWrite);
3711
3712 SeqLocFree (dup->location);
3713 dup->location = newloc;
3714 if (split) {
3715 dup->partial = TRUE;
3716 }
3717 dup->partial |= partial5;
3718 dup->partial |= partial3;
3719
3720 if (last == NULL) {
3721 sap = SeqAnnotNew ();
3722 if (oldbsp->annot == NULL) {
3723 oldbsp->annot = sap;
3724 } else {
3725 for (saptmp = oldbsp->annot; saptmp->next != NULL; saptmp = saptmp->next) continue;
3726 saptmp->next = sap;
3727 }
3728 sap->type = 1;
3729 sap->data = (Pointer) dup;
3730 } else {
3731 last->next = dup;
3732 }
3733 last = dup;
3734
3735 switch (dup->data.choice) {
3736 case SEQFEAT_CDREGION :
3737 crp = (CdRegionPtr) dup->data.value.ptrvalue;
3738 if (crp != NULL) {
3739 prevcbp = NULL;
3740 for (cbp = crp->code_break; cbp != NULL; cbp = nextcbp) {
3741 nextcbp = cbp->next;
3742 newloc = GetPropagatedLocation (cbp->loc, udp->newbsp, udp->oldbsp,
3743 LengthForNewSequence (udp), udp->salp);
3744 SeqLocFree (cbp->loc);
3745 cbp->loc = newloc;
3746 if (cbp->loc == NULL) {
3747 if (prevcbp != NULL) {
3748 prevcbp->next = nextcbp;
3749 } else {
3750 crp->code_break = nextcbp;
3751 }
3752 cbp->next = NULL;
3753 CodeBreakFree (cbp);
3754 } else {
3755 prevcbp = cbp;
3756 }
3757 }
3758 }
3759 break;
3760 case SEQFEAT_RNA :
3761 rrp = (RnaRefPtr) dup->data.value.ptrvalue;
3762 if (rrp != NULL && rrp->ext.choice == 2) {
3763 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
3764 if (trp != NULL && trp->anticodon != NULL) {
3765 newloc = GetPropagatedLocation (trp->anticodon, udp->newbsp, udp->oldbsp,
3766 LengthForNewSequence (udp), udp->salp);
3767 SeqLocFree (trp->anticodon);
3768 trp->anticodon = newloc;
3769 }
3770 }
3771 break;
3772 default :
3773 break;
3774 }
3775 if (dup->product != NULL) {
3776 SeqEntrySetScope (NULL);
3777 bsp = BioseqFindFromSeqLoc (dup->product);
3778 if (bsp != NULL) {
3779 prdsep = SeqMgrGetSeqEntryForData (bsp);
3780 if (prdsep != NULL) {
3781 newsep = AsnIoMemCopy ((Pointer) prdsep,
3782 (AsnReadFunc) SeqEntryAsnRead,
3783 (AsnWriteFunc) SeqEntryAsnWrite);
3784 if (newsep != NULL) {
3785 if (IS_Bioseq (newsep)) {
3786 newbsp = (BioseqPtr) newsep->data.ptrvalue;
3787 if (newbsp != NULL) {
3788 if (! keepProteinIDs) {
3789 newbsp->id = SeqIdSetFree (newbsp->id);
3790 newbsp->id = MakeNewProteinSeqId (NULL, sip);
3791 VisitFeaturesOnBsp (newbsp, (Pointer) newbsp->id, CorrectFeatureSeqIds);
3792 SetSeqFeatProduct (dup, newbsp);
3793 /*
3794 dup->product = SeqLocFree (dup->product);
3795 dup->product = CreateWholeInterval (newsep);
3796 */
3797 }
3798 SeqMgrReplaceInBioseqIndex (newbsp);
3799 }
3800 }
3801 AddSeqEntryToSeqEntry (top, newsep, TRUE);
3802 }
3803 }
3804 }
3805 }
3806 }
3807 }
3808
3809 sfp = SeqMgrGetNextFeature (udp->newbsp, sfp, 0, 0, &context);
3810 }
3811
3812 ReplaceBioSourceAndPubs (top, sdp);
3813
3814 if (sapp != NULL) {
3815 *sapp = sap;
3816 }
3817
3818 return TRUE;
3819 }
3820
ReplaceSequence(UpsDataPtr udp)3821 static Boolean ReplaceSequence (UpsDataPtr udp)
3822
3823 {
3824 MsgAnswer ans;
3825
3826 if (udp == NULL)
3827 {
3828 return TRUE;
3829 }
3830
3831 if (FALSE == udp->isSet)
3832 {
3833 if ((udp->seq1 != NULL || udp->seq2 != NULL)
3834 && StringICmp (udp->seq1, udp->seq2) == 0
3835 && ! udp->revcomp)
3836 {
3837 ans = Message (MSG_OKC, "Replacement sequence is identical to"
3838 " original - possible error");
3839 if (ans == ANS_CANCEL) return FALSE;
3840 }
3841 }
3842
3843 ReplaceOneSequence (udp->salp, udp->oldbsp, udp->newbsp);
3844 return TRUE;
3845 }
3846
Merge5Prime(UpsDataPtr udp)3847 static Boolean Merge5Prime (UpsDataPtr udp)
3848
3849 {
3850 ByteStorePtr bs;
3851 Char ch;
3852 Int4 i, newlen;
3853 BioseqPtr newbsp;
3854 CharPtr ptr, str, tmp;
3855
3856 /* construct replacement sequence by recombining between old and overlap */
3857
3858 tmp = udp->seq2;
3859
3860 newlen = udp->new5 + udp->newa + udp->old3;
3861 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
3862 if (str == NULL)
3863 return FALSE;
3864 ptr = str;
3865
3866 for (i = 0; i < udp->new5 + udp->newa; i++) {
3867 ch = *tmp;
3868 *ptr = ch;
3869 tmp++;
3870 ptr++;
3871 }
3872
3873 tmp = udp->seq1 + udp->old5 + udp->olda;
3874 for (i = 0; i < udp->old3; i++) {
3875 ch = *tmp;
3876 *ptr = ch;
3877 tmp++;
3878 ptr++;
3879 }
3880
3881 *ptr = '\0';
3882 bs = BSNew (newlen);
3883 BSWrite (bs, (VoidPtr) str, newlen);
3884
3885 udp->seq2 = MemFree (udp->seq2);
3886 udp->seq2 = str;
3887
3888 if (bs != NULL && BSLen (bs) < 1) {
3889 bs = BSFree (bs);
3890 }
3891 if (bs == NULL) return FALSE;
3892
3893 /* overlap turned into replacement sequence */
3894
3895 newbsp = udp->newbsp;
3896 newbsp->seq_data = SeqDataFree (newbsp->seq_data, newbsp->seq_data_type);
3897 newbsp->seq_data = (SeqDataPtr) bs;
3898 newbsp->seq_data_type = Seq_code_iupacna;
3899 newbsp->length = newlen;
3900
3901 /* adjust alignment and reindex */
3902
3903 if (! AdjustAlignment (udp, 2)) return FALSE;
3904
3905 /* then finish by replacing with new sequence */
3906
3907 return ReplaceSequence (udp);
3908 }
3909
Merge3Prime(UpsDataPtr udp)3910 static Boolean Merge3Prime (UpsDataPtr udp)
3911
3912 {
3913 ByteStorePtr bs;
3914 Char ch;
3915 Int4 i, newlen;
3916 BioseqPtr newbsp;
3917 CharPtr ptr, str, tmp;
3918
3919 /* construct replacement sequence by recombining between old and overlap */
3920
3921 newlen = udp->old5 + udp->newa + udp->new3;
3922 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
3923 if (str == NULL)
3924 return FALSE;
3925 ptr = str;
3926
3927 tmp = udp->seq1;
3928 for (i = 0; i < udp->old5; i++) {
3929 ch = *tmp;
3930 *ptr = ch;
3931 tmp++;
3932 ptr++;
3933 }
3934
3935 tmp = udp->seq2 + udp->new5;
3936 for (i = 0; i < udp->newa + udp->new3; i++) {
3937 ch = *tmp;
3938 *ptr = ch;
3939 tmp++;
3940 ptr++;
3941 }
3942
3943 *ptr = '\0';
3944 bs = BSNew (newlen);
3945 BSWrite (bs, (VoidPtr) str, newlen);
3946
3947 udp->seq2 = MemFree (udp->seq2);
3948 udp->seq2 = str;
3949
3950 if (bs != NULL && BSLen (bs) < 1) {
3951 bs = BSFree (bs);
3952 }
3953 if (bs == NULL) return FALSE;
3954
3955 /* overlap turned into replacement sequence */
3956
3957 newbsp = udp->newbsp;
3958 newbsp->seq_data = SeqDataFree (newbsp->seq_data, newbsp->seq_data_type);
3959 newbsp->seq_data = (SeqDataPtr) bs;
3960 newbsp->seq_data_type = Seq_code_iupacna;
3961 newbsp->length = newlen;
3962
3963 /* adjust alignment and reindex */
3964
3965 if (! AdjustAlignment (udp, 3)) return FALSE;
3966
3967 /* then finish by replacing with new sequence */
3968
3969 return ReplaceSequence (udp);
3970 }
3971
3972 static Boolean ExtendFeatures (UpsDataPtr udp, Int4 offset);
3973
3974 /*------------------------------------------------------------------*/
3975 /* */
3976 /* Merge5PrimeNoOverlap () -- Merge a new sequence onto the 5' end */
3977 /* of an existing sequence. */
3978 /* */
3979 /* Performs a similar function to */
3980 /* Merge5Prime() except works when */
3981 /* there is no alignment between the */
3982 /* two sequences. */
3983 /* */
3984 /*------------------------------------------------------------------*/
3985
Merge5PrimeNoOverlap(UpsDataPtr udp)3986 static Boolean Merge5PrimeNoOverlap (UpsDataPtr udp)
3987
3988 {
3989 CharPtr origSeqStr;
3990 CharPtr newSeqStr;
3991 CharPtr mergedSeqStr;
3992 Int4 mergedLen;
3993 ByteStorePtr mergedBS;
3994
3995 /* Get original and new sequences */
3996
3997 origSeqStr = GetSequenceByBsp (udp->oldbsp);
3998 newSeqStr = GetSequenceByBsp (udp->newbsp);
3999
4000 /* Concatenate the new sequence onto the beginning */
4001 /* (i.e. the 5' end) of the original sequence. */
4002
4003 mergedLen = StringLen (newSeqStr) + StringLen (origSeqStr);
4004 mergedSeqStr = (CharPtr) MemNew (mergedLen + 1);
4005 sprintf (mergedSeqStr, "%s%s", newSeqStr, origSeqStr);
4006
4007 /* Convert the new sequence into a ByteStore */
4008
4009 mergedBS = BSNew (mergedLen);
4010 BSWrite (mergedBS, (VoidPtr) mergedSeqStr, mergedLen);
4011
4012 /* Replace the original sequence with the */
4013 /* new concatenated sequence. */
4014
4015 udp->newbsp->seq_data = SeqDataFree (udp->newbsp->seq_data, udp->newbsp->seq_data_type);
4016 udp->newbsp->seq_data = (SeqDataPtr) mergedBS;
4017 udp->newbsp->seq_data_type = Seq_code_iupacna;
4018 udp->newbsp->length = mergedLen;
4019
4020 /* Replace the merged sequence and return */
4021
4022 return ExtendFeatures (udp, StringLen (newSeqStr));
4023 }
4024
4025 /*------------------------------------------------------------------*/
4026 /* */
4027 /* Merge3PrimeNoOverlap () -- Merge a new sequence onto the 3' end */
4028 /* of an existing sequence. */
4029 /* */
4030 /* Performs a similar function to */
4031 /* Merge3Prime() except works when */
4032 /* there is no alignment between the */
4033 /* two sequences. */
4034 /* */
4035 /*------------------------------------------------------------------*/
4036
Merge3PrimeNoOverlap(UpsDataPtr udp)4037 static Boolean Merge3PrimeNoOverlap (UpsDataPtr udp)
4038
4039 {
4040 CharPtr origSeqStr;
4041 CharPtr newSeqStr;
4042 CharPtr mergedSeqStr;
4043 Int4 mergedLen;
4044 ByteStorePtr mergedBS;
4045
4046 /* Get original and new sequences */
4047
4048 origSeqStr = GetSequenceByBsp (udp->oldbsp);
4049 newSeqStr = GetSequenceByBsp (udp->newbsp);
4050
4051 /* Concatenate the new sequence onto the end */
4052 /* (i.e. the 3' end) of the original sequence. */
4053
4054 mergedLen = StringLen (newSeqStr) + StringLen (origSeqStr);
4055 mergedSeqStr = (CharPtr) MemNew (mergedLen + 1);
4056 sprintf (mergedSeqStr, "%s%s", origSeqStr, newSeqStr);
4057
4058 /* Convert the new sequence into a ByteStore */
4059
4060 mergedBS = BSNew (mergedLen);
4061 BSWrite (mergedBS, (VoidPtr) mergedSeqStr, mergedLen);
4062
4063 /* Replace the original sequence with the */
4064 /* new concatenated sequence. */
4065
4066 udp->newbsp->seq_data = SeqDataFree (udp->newbsp->seq_data, udp->newbsp->seq_data_type);
4067 udp->newbsp->seq_data = (SeqDataPtr) mergedBS;
4068 udp->newbsp->seq_data_type = Seq_code_iupacna;
4069 udp->newbsp->length = mergedLen;
4070
4071 /* Replace the merged sequence and return */
4072
4073 return ExtendFeatures (udp, 0);
4074 }
4075
OkToPatchDelta(UpsDataPtr udp)4076 static Boolean OkToPatchDelta (UpsDataPtr udp)
4077 {
4078 Boolean rval = TRUE;
4079
4080 if (udp == NULL || udp->oldbsp == NULL || udp->newbsp == NULL
4081 || udp->oldbsp->repr != Seq_repr_delta || udp->newbsp->repr != Seq_repr_delta
4082 || udp->oldbsp->seq_ext_type != 4 || udp->newbsp->seq_ext_type != 4)
4083 {
4084 rval = FALSE;
4085 }
4086
4087 return rval;
4088 }
4089
SplitDeltaSeq(DeltaSeqPtr dsp,Int4 offset)4090 static void SplitDeltaSeq (DeltaSeqPtr dsp, Int4 offset)
4091 {
4092 SeqLocPtr slp1, slp2;
4093 SeqLitPtr slip1, slip2;
4094 Int4 len;
4095 Boolean changed;
4096 DeltaSeqPtr dsp_new;
4097 ByteStorePtr bs_1, bs_2;
4098 Int2 residue;
4099 Int4 pos;
4100
4101 if (dsp == NULL || dsp->data.ptrvalue == NULL || offset == 0)
4102 {
4103 return;
4104 }
4105
4106 if (dsp->choice == 1)
4107 {
4108 slp1 = (SeqLocPtr)(dsp->data.ptrvalue);
4109 len = SeqLocLen (slp1);
4110 if (offset > len)
4111 {
4112 return;
4113 }
4114 slp2 = (SeqLocPtr) AsnIoMemCopy (slp1, (AsnReadFunc) SeqLocAsnRead,
4115 (AsnWriteFunc) SeqLocAsnWrite);
4116 slp1 = SeqLocDelete (slp1, SeqLocId (slp1),
4117 offset, len - 1, FALSE, &changed);
4118 slp2 = SeqLocDelete (slp2, SeqLocId (slp2),
4119 0, offset, FALSE, &changed);
4120 dsp_new = ValNodeNew (NULL);
4121 dsp_new->choice = 1;
4122 dsp_new->data.ptrvalue = slp2;
4123 dsp_new->next = dsp->next;
4124 dsp->next = dsp_new;
4125 }
4126 else if (dsp->choice == 2)
4127 {
4128 slip1 = (SeqLitPtr) dsp->data.ptrvalue;
4129 if (offset > slip1->length)
4130 {
4131 return;
4132 }
4133 if (IsDeltaSeqGap (dsp))
4134 {
4135 /* use AsnIoMemCopy, to automatically copy gap data if present */
4136 slip2 = (SeqLitPtr) AsnIoMemCopy (slip1, (AsnReadFunc) SeqLitAsnRead, (AsnWriteFunc) SeqLitAsnWrite);
4137 slip2->length = slip1->length - offset;
4138 slip1->length = offset;
4139 }
4140 else
4141 {
4142 slip2 = SeqLitNew ();
4143 if (slip1->seq_data_type == Seq_code_iupacna)
4144 {
4145 bs_1 = (ByteStorePtr) slip1->seq_data;
4146 }
4147 else
4148 {
4149 bs_1 = BSConvertSeq((ByteStorePtr) slip1->seq_data, Seq_code_iupacna,
4150 slip1->seq_data_type,
4151 slip1->length);
4152 slip1->seq_data_type = Seq_code_iupacna;
4153 slip1->seq_data = (SeqDataPtr) bs_1;
4154 }
4155 bs_2 = BSNew (slip1->length - offset);
4156 pos = offset;
4157 BSSeek(bs_1, pos, SEEK_SET);
4158 BSSeek (bs_2, 0L, SEEK_SET);
4159 while (pos < slip1->length)
4160 {
4161 residue = BSGetByte (bs_1);
4162 BSPutByte (bs_2, residue);
4163 pos++;
4164 }
4165 BSSeek(bs_1, offset, SEEK_SET);
4166 BSDelete(bs_1, slip1->length - offset);
4167
4168 slip2->seq_data = (SeqDataPtr) bs_2;
4169 slip2->seq_data_type = slip1->seq_data_type;
4170 slip2->length = slip1->length - offset;
4171 slip1->length = offset;
4172 }
4173 dsp_new = ValNodeNew (NULL);
4174 dsp_new->choice = 2;
4175 dsp_new->data.ptrvalue = slip2;
4176 dsp_new->next = dsp->next;
4177 dsp->next = dsp_new;
4178 }
4179 }
4180
4181 /* This function will patch a delta sequence with another delta sequence.
4182 * The pieces in the overlap from the old sequence will be replaced by pieces
4183 * in the overlap from the new sequence.
4184 */
PatchDeltaSequence(UpsDataPtr udp)4185 static Boolean PatchDeltaSequence (UpsDataPtr udp)
4186
4187 {
4188 Int4 currnew_pos = 0, currold_pos;
4189 SeqLitPtr slip, slip_new;
4190 DeltaSeqPtr dspold, dspnew;
4191 Int4 seqstart;
4192 DeltaSeqPtr new_list = NULL;
4193
4194 if (! OkToPatchDelta (udp))
4195 {
4196 return FALSE;
4197 }
4198
4199 /* keep old 5' end intact */
4200 currold_pos = 0;
4201 seqstart = 0;
4202 dspold = (DeltaSeqPtr) udp->oldbsp->seq_ext;
4203 while (dspold != NULL && currold_pos < udp->old5)
4204 {
4205 seqstart = currold_pos;
4206 if (dspold->data.ptrvalue == NULL || dspold->choice != 2)
4207 {
4208 return FALSE;
4209 }
4210 slip = (SeqLitPtr) (dspold->data.ptrvalue);
4211 currold_pos += slip->length;
4212 if (currold_pos > udp->old5)
4213 {
4214 SplitDeltaSeq (dspold, udp->old5 - seqstart);
4215 slip = (SeqLitPtr) (dspold->data.ptrvalue);
4216 currold_pos = udp->old5;
4217 }
4218 slip_new = (SeqLitPtr) AsnIoMemCopy (slip, (AsnReadFunc) SeqLitAsnRead,
4219 (AsnWriteFunc) SeqLitAsnWrite);
4220 ValNodeAddPointer (&new_list, 2, slip_new);
4221 dspold = dspold->next;
4222 }
4223
4224 /* skip over new 5' end */
4225 currnew_pos = 0;
4226 seqstart = 0;
4227 dspnew = (DeltaSeqPtr) udp->newbsp->seq_ext;
4228 while (dspnew != NULL && currnew_pos < udp->new5)
4229 {
4230 seqstart = currold_pos;
4231 if (dspnew->data.ptrvalue == NULL || dspnew->choice != 2)
4232 {
4233 return FALSE;
4234 }
4235 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
4236 currnew_pos += slip->length;
4237 if (currnew_pos > udp->new5)
4238 {
4239 SplitDeltaSeq (dspnew, udp->new5 - seqstart);
4240 currnew_pos = udp->new5;
4241 }
4242 dspnew = dspnew->next;
4243 }
4244
4245 /* copy in new overlap */
4246 while (dspnew != NULL && currnew_pos < udp->new5 + udp->newa)
4247 {
4248 seqstart = currold_pos;
4249 if (dspnew->data.ptrvalue == NULL || dspnew->choice != 2)
4250 {
4251 return FALSE;
4252 }
4253 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
4254 currnew_pos += slip->length;
4255 if (currnew_pos > udp->new5 + udp->newa)
4256 {
4257 SplitDeltaSeq (dspnew, udp->new5 + udp->newa - seqstart);
4258 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
4259 currnew_pos = udp->new5 + udp->newa;
4260 }
4261 slip_new = (SeqLitPtr) AsnIoMemCopy (slip, (AsnReadFunc) SeqLitAsnRead,
4262 (AsnWriteFunc) SeqLitAsnWrite);
4263 ValNodeAddPointer (&new_list, 2, slip_new);
4264 dspnew = dspnew->next;
4265 }
4266
4267 /* skip over old overlap */
4268
4269 while (dspold != NULL && currold_pos < udp->old5 + udp->olda)
4270 {
4271 seqstart = currold_pos;
4272 if (dspold->data.ptrvalue == NULL || dspold->choice != 2)
4273 {
4274 return FALSE;
4275 }
4276 slip = (SeqLitPtr) (dspold->data.ptrvalue);
4277 currold_pos += slip->length;
4278 if (currold_pos > udp->old5 + udp->olda)
4279 {
4280 SplitDeltaSeq (dspold, udp->new5 + udp->newa - seqstart);
4281 currold_pos = udp->old5 + udp->olda;
4282 }
4283 dspold = dspold->next;
4284 }
4285
4286 /* copy in old 3' */
4287
4288 while (dspold != NULL)
4289 {
4290 if (dspold->data.ptrvalue == NULL || dspold->choice != 2)
4291 {
4292 return FALSE;
4293 }
4294 slip = (SeqLitPtr) (dspold->data.ptrvalue);
4295 slip_new = (SeqLitPtr) AsnIoMemCopy (slip, (AsnReadFunc) SeqLitAsnRead,
4296 (AsnWriteFunc) SeqLitAsnWrite);
4297 ValNodeAddPointer (&new_list, 2, slip_new);
4298 dspold = dspold->next;
4299 }
4300
4301 /* free newbsp's old SeqLit List */
4302 for (dspnew = (DeltaSeqPtr) udp->newbsp->seq_ext;
4303 dspnew != NULL;
4304 dspnew = dspnew->next)
4305 {
4306 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
4307 SeqLitFree (slip);
4308 }
4309 udp->newbsp->seq_ext = ValNodeFree (udp->newbsp->seq_ext);
4310 udp->newbsp->seq_ext = new_list;
4311 udp->newbsp->length = udp->old5 + udp->newa + udp->old3;
4312 return TRUE;
4313 }
4314
OkToPatchRaw(UpsDataPtr udp)4315 static Boolean OkToPatchRaw (UpsDataPtr udp)
4316 {
4317 Boolean rval = TRUE;
4318
4319 if (udp == NULL || udp->oldbsp == NULL || udp->newbsp == NULL
4320 || udp->oldbsp->repr != Seq_repr_raw || udp->newbsp->repr != Seq_repr_raw)
4321 {
4322 rval = FALSE;
4323 }
4324
4325 return rval;
4326 }
4327
PatchRawSequence(UpsDataPtr udp)4328 static Boolean PatchRawSequence (UpsDataPtr udp)
4329
4330 {
4331 ByteStorePtr bs;
4332 Char ch;
4333 Int4 i, newlen;
4334 BioseqPtr newbsp;
4335 CharPtr ptr, str, tmp;
4336
4337 newlen = udp->old5 + udp->newa + udp->old3;
4338 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
4339 if (str == NULL) return FALSE;
4340
4341 /* construct replacement sequence by double recombination */
4342 ptr = str;
4343
4344 tmp = udp->seq1;
4345 for (i = 0; i < udp->old5; i++) {
4346 ch = *tmp;
4347 *ptr = ch;
4348 tmp++;
4349 ptr++;
4350 }
4351
4352 tmp = udp->seq2 + udp->new5;
4353 for (i = 0; i < udp->newa; i++) {
4354 ch = *tmp;
4355 *ptr = ch;
4356 tmp++;
4357 ptr++;
4358 }
4359
4360 tmp = udp->seq1 + udp->old5 + udp->olda;
4361 for (i = 0; i < udp->old3; i++) {
4362 ch = *tmp;
4363 *ptr = ch;
4364 tmp++;
4365 ptr++;
4366 }
4367
4368 *ptr = '\0';
4369 bs = BSNew (newlen);
4370 BSWrite (bs, (VoidPtr) str, newlen);
4371
4372 udp->seq2 = MemFree (udp->seq2);
4373 udp->seq2 = str;
4374
4375 if (bs != NULL && BSLen (bs) < 1) {
4376 bs = BSFree (bs);
4377 }
4378 if (bs == NULL) return FALSE;
4379
4380 /* overlap turned into replacement sequence */
4381
4382 newbsp = udp->newbsp;
4383 newbsp->seq_data = SeqDataFree (newbsp->seq_data, newbsp->seq_data_type);
4384 newbsp->seq_data = (SeqDataPtr) bs;
4385 newbsp->seq_data_type = Seq_code_iupacna;
4386 newbsp->length = newlen;
4387 return TRUE;
4388 }
4389
PatchSequence(UpsDataPtr udp)4390 static Boolean PatchSequence (UpsDataPtr udp)
4391
4392 {
4393 Boolean rval = FALSE;
4394
4395 if (OkToPatchRaw (udp))
4396 {
4397 rval = PatchRawSequence (udp);
4398 }
4399 else if (OkToPatchDelta (udp))
4400 {
4401 rval = PatchDeltaSequence (udp);
4402 }
4403
4404 if (!rval)
4405 {
4406 return rval;
4407 }
4408
4409 /* adjust alignment and reindex */
4410
4411 if (! AdjustAlignment (udp, 4)) return FALSE;
4412
4413 /* then finish by replacing with new sequence */
4414
4415 return ReplaceSequence (udp);
4416 }
4417
MarkProductForDeletion(SeqLocPtr product)4418 static void MarkProductForDeletion (
4419 SeqLocPtr product
4420 )
4421
4422 {
4423 BioseqPtr bsp;
4424 SeqIdPtr sip;
4425
4426 if (product == NULL) return;
4427 sip = SeqLocId (product);
4428 if (sip == NULL) return;
4429 bsp = BioseqFind (sip);
4430 if (bsp == NULL) return;
4431 bsp->idx.deleteme = TRUE;
4432 }
4433
CombineTexts(CharPtr PNTR txtptr,CharPtr PNTR oldtxtptr)4434 static void CombineTexts (
4435 CharPtr PNTR txtptr,
4436 CharPtr PNTR oldtxtptr
4437 )
4438
4439 {
4440 size_t len;
4441 CharPtr str;
4442
4443 if (txtptr == NULL || oldtxtptr == NULL) return;
4444
4445 if (*txtptr == NULL) {
4446
4447 *txtptr = *oldtxtptr;
4448 *oldtxtptr = NULL;
4449
4450 } else if (*oldtxtptr != NULL && StringICmp (*txtptr, *oldtxtptr) != 0) {
4451
4452 len = StringLen (*txtptr) + StringLen (*oldtxtptr) + 5;
4453 str = MemNew (sizeof (Char) * len);
4454 StringCpy (str, *txtptr);
4455 StringCat (str, "; ");
4456 StringCat (str, *oldtxtptr);
4457 *txtptr = MemFree (*txtptr);
4458 *txtptr = str;
4459 }
4460 }
4461
FuseCommonFeatureFields(SeqFeatPtr sfp,SeqFeatPtr oldsfp)4462 static void FuseCommonFeatureFields (
4463 SeqFeatPtr sfp,
4464 SeqFeatPtr oldsfp
4465 )
4466
4467 {
4468 GBQualPtr lastgbq;
4469 SeqFeatXrefPtr lastxref;
4470
4471 if (sfp == NULL || oldsfp == NULL) return;
4472
4473 CombineTexts (&(sfp->comment), &(oldsfp->comment));
4474 CombineTexts (&(sfp->title), &(oldsfp->title));
4475 CombineTexts (&(sfp->except_text), &(oldsfp->except_text));
4476
4477 if (sfp->qual == NULL) {
4478 sfp->qual = oldsfp->qual;
4479 oldsfp->qual = NULL;
4480 } else if (oldsfp->qual != NULL) {
4481 for (lastgbq = sfp->qual; lastgbq->next != NULL; lastgbq = lastgbq->next) continue;
4482 lastgbq->next = oldsfp->qual;
4483 oldsfp->qual = NULL;
4484 }
4485
4486 ValNodeLink (&(sfp->dbxref), oldsfp->dbxref);
4487 oldsfp->dbxref = NULL;
4488
4489 ValNodeLink (&(sfp->cit), oldsfp->cit);
4490 oldsfp->cit = NULL;
4491
4492 if (sfp->xref == NULL) {
4493 sfp->xref = oldsfp->xref;
4494 oldsfp->xref = NULL;
4495 } else if (oldsfp->xref != NULL) {
4496 for (lastxref = sfp->xref; lastxref->next != NULL; lastxref = lastxref->next) continue;
4497 lastxref->next = oldsfp->xref;
4498 oldsfp->xref = NULL;
4499 }
4500
4501 if (sfp->ext == NULL) {
4502 sfp->ext = oldsfp->ext;
4503 oldsfp->ext = NULL;
4504 } else if (oldsfp->ext != NULL) {
4505 sfp->ext = CombineUserObjects (sfp->ext, oldsfp->ext);
4506 oldsfp->ext = NULL;
4507 }
4508
4509 sfp->partial |= oldsfp->partial;
4510 sfp->excpt |= oldsfp->excpt;
4511 sfp->pseudo |= oldsfp->pseudo;
4512 }
4513
FuseFeatures(SeqFeatPtr sfp,SeqFeatPtr oldsfp)4514 static void FuseFeatures (
4515 SeqFeatPtr sfp,
4516 SeqFeatPtr oldsfp
4517 )
4518
4519 {
4520 GeneRefPtr grp, oldgrp;
4521 BioseqPtr prod, oldprod;
4522 SeqFeatPtr prot, oldprot;
4523 ProtRefPtr prp, oldprp;
4524 RnaRefPtr rrp, oldrrp;
4525 SeqIdPtr sip;
4526
4527 if (sfp == NULL || oldsfp == NULL) return;
4528
4529 /* merge common fields */
4530
4531 FuseCommonFeatureFields (sfp, oldsfp);
4532
4533 /* now deal with type-specific data */
4534
4535 switch (sfp->data.choice) {
4536 case SEQFEAT_GENE :
4537 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
4538 oldgrp = (GeneRefPtr) oldsfp->data.value.ptrvalue;
4539 if (grp == NULL || oldgrp == NULL) return;
4540 CombineTexts (&(grp->locus), &(oldgrp->locus));
4541 CombineTexts (&(grp->allele), &(oldgrp->allele));
4542 CombineTexts (&(grp->desc), &(oldgrp->desc));
4543 CombineTexts (&(grp->maploc), &(oldgrp->maploc));
4544 CombineTexts (&(grp->locus_tag), &(oldgrp->locus_tag));
4545 grp->pseudo |= oldgrp->pseudo;
4546 ValNodeLink (&(grp->db), oldgrp->db);
4547 oldgrp->db = NULL;
4548 ValNodeLink (&(grp->syn), oldgrp->syn);
4549 oldgrp->syn = NULL;
4550 break;
4551 case SEQFEAT_CDREGION :
4552 sip = SeqLocId (sfp->product);
4553 prod = BioseqFind (sip);
4554 sip = SeqLocId (oldsfp->product);
4555 oldprod = BioseqFind (sip);
4556 if (prod == NULL || oldprod == NULL) return;
4557 prot = SeqMgrGetBestProteinFeature (prod, NULL);
4558 oldprot = SeqMgrGetBestProteinFeature (oldprod, NULL);
4559 if (prot == NULL || oldprot == NULL) return;
4560 FuseCommonFeatureFields (prot, oldprot);
4561 prp = (ProtRefPtr) prot->data.value.ptrvalue;
4562 oldprp = (ProtRefPtr) oldprot->data.value.ptrvalue;
4563 if (prp == NULL || oldprp == NULL) return;
4564 ValNodeLink (&(prp->name), oldprp->name);
4565 oldprp->name = NULL;
4566 ValNodeLink (&(prp->ec), oldprp->ec);
4567 oldprp->ec = NULL;
4568 ValNodeLink (&(prp->activity), oldprp->activity);
4569 oldprp->activity = NULL;
4570 ValNodeLink (&(prp->db), oldprp->db);
4571 oldprp->db = NULL;
4572 CombineTexts (&(prp->desc), &(oldprp->desc));
4573 break;
4574 case SEQFEAT_RNA :
4575 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
4576 oldrrp = (RnaRefPtr) oldsfp->data.value.ptrvalue;
4577 if (rrp == NULL || oldrrp == NULL) return;
4578 if (rrp->ext.choice == 1 && oldrrp->ext.choice == 1) {
4579 CombineTexts ((CharPtr PNTR) &(rrp->ext.value.ptrvalue), (CharPtr PNTR) &(oldrrp->ext.value.ptrvalue));
4580 }
4581 break;
4582 case SEQFEAT_REGION :
4583 case SEQFEAT_COMMENT :
4584 if (sfp->data.value.ptrvalue == NULL || oldsfp->data.value.ptrvalue == NULL) return;
4585 CombineTexts ((CharPtr PNTR) &(sfp->data.value.ptrvalue), (CharPtr PNTR) &(oldsfp->data.value.ptrvalue));
4586 break;
4587 default :
4588 break;
4589 }
4590 }
4591
RemoveOldFeatsInRegion(UpsDataPtr udp,BioseqPtr bsp,SeqAnnotPtr sap)4592 static void RemoveOldFeatsInRegion (
4593 UpsDataPtr udp,
4594 BioseqPtr bsp,
4595 SeqAnnotPtr sap
4596 )
4597
4598 {
4599 SeqMgrFeatContext context;
4600 Int4 left, right;
4601 SeqFeatPtr sfp;
4602
4603 if (udp == NULL || bsp == NULL || sap == NULL) return;
4604 if (sap->type != 1) return;
4605
4606 left = INT4_MAX;
4607 right = INT4_MIN;
4608
4609 for (sfp = (SeqFeatPtr) sap->data; sfp != NULL; sfp = sfp->next) {
4610 if (sfp != SeqMgrGetDesiredFeature (0, bsp, 0, 0, sfp, &context)) continue;
4611 left = MIN (left, context.left);
4612 right = MAX (right, context.right);
4613 }
4614
4615 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
4616
4617 while (sfp != NULL) {
4618
4619 if (context.sap != sap && context.right >= left && context.left <= right) {
4620 sfp->idx.deleteme = TRUE;
4621 MarkProductForDeletion (sfp->product);
4622 }
4623
4624 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
4625 }
4626 }
4627
RemoveOldFeats(BioseqPtr bsp)4628 static Boolean RemoveOldFeats (BioseqPtr bsp)
4629
4630 {
4631 SeqMgrFeatContext context;
4632 SeqFeatPtr sfp;
4633 Boolean rval = FALSE;
4634
4635 if (bsp == NULL) return FALSE;
4636
4637 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
4638
4639 while (sfp != NULL)
4640 {
4641 sfp->idx.deleteme = TRUE;
4642 rval = TRUE;
4643 MarkProductForDeletion (sfp->product);
4644 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
4645 }
4646 return rval;
4647 }
4648
4649
ResolveDuplicateFeats(UpsDataPtr udp,BioseqPtr bsp,SeqAnnotPtr sap)4650 static void ResolveDuplicateFeats (
4651 UpsDataPtr udp,
4652 BioseqPtr bsp,
4653 SeqAnnotPtr sap
4654 )
4655
4656 {
4657 SeqMgrFeatContext context, lastcontext;
4658 Int2 i, j;
4659 Boolean ivalssame;
4660 SeqFeatPtr lastsfp = NULL, sfp;
4661 Int2 nobmval;
4662
4663 if (udp == NULL || bsp == NULL || sap == NULL) return;
4664
4665 nobmval = GetValue (udp->nobm);
4666 if (nobmval == UPDATE_FEAT_DUP_USE_BOTH) return; /* keep both */
4667
4668 SeqMgrIndexFeatures (0, (Pointer) bsp);
4669
4670 if (nobmval == UPDATE_FEAT_DUP_REPLACE) {
4671 RemoveOldFeatsInRegion (udp, bsp, sap);
4672 return;
4673 }
4674
4675 lastsfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
4676 if (lastsfp == NULL) return;
4677
4678 MemCopy ((Pointer) &lastcontext, (Pointer) &context, sizeof (SeqMgrFeatContext));
4679
4680 sfp = SeqMgrGetNextFeature (bsp, lastsfp, 0, 0, &context);
4681 if (sfp == NULL) return;
4682
4683 while (sfp != NULL) {
4684
4685 if (context.left == lastcontext.left &&
4686 context.right == lastcontext.right &&
4687 context.featdeftype == lastcontext.featdeftype) {
4688
4689 if (context.strand == lastcontext.strand ||
4690 lastcontext.strand == Seq_strand_unknown ||
4691 context.strand == Seq_strand_unknown) {
4692
4693 ivalssame = TRUE;
4694 if (context.numivals != lastcontext.numivals ||
4695 context.ivals == NULL ||
4696 lastcontext.ivals == NULL) {
4697
4698 ivalssame = FALSE;
4699
4700 } else {
4701
4702 for (i = 0, j = 0; i < lastcontext.numivals; i++, j += 2) {
4703 if (context.ivals [j] != lastcontext.ivals [j]) {
4704 ivalssame = FALSE;
4705 }
4706 if (context.ivals [j + 1] != lastcontext.ivals [j + 1]) {
4707 ivalssame = FALSE;
4708 }
4709 }
4710 }
4711
4712 if (ivalssame &&
4713 context.sap != lastcontext.sap &&
4714 (context.sap == sap || lastcontext.sap == sap)) {
4715
4716 if (nobmval == UPDATE_FEAT_DUP_USE_NEW) { /* keep new */
4717 if (context.sap == sap) {
4718 lastsfp->idx.deleteme = TRUE;
4719 MarkProductForDeletion (lastsfp->product);
4720 } else if (lastcontext.sap == sap) {
4721 sfp->idx.deleteme = TRUE;
4722 MarkProductForDeletion (sfp->product);
4723 }
4724
4725 } else if (nobmval == UPDATE_FEAT_DUP_USE_OLD) { /* keep old */
4726 if (context.sap == sap) {
4727 sfp->idx.deleteme = TRUE;
4728 MarkProductForDeletion (sfp->product);
4729 } else if (lastcontext.sap == sap) {
4730 lastsfp->idx.deleteme = TRUE;
4731 MarkProductForDeletion (lastsfp->product);
4732 }
4733
4734 } else if (nobmval == UPDATE_FEAT_DUP_MERGE) { /* merge */
4735 if (context.sap == sap) {
4736 FuseFeatures (sfp, lastsfp);
4737 lastsfp->idx.deleteme = TRUE;
4738 MarkProductForDeletion (lastsfp->product);
4739 } else if (lastcontext.sap == sap) {
4740 FuseFeatures (lastsfp, sfp);
4741 sfp->idx.deleteme = TRUE;
4742 MarkProductForDeletion (sfp->product);
4743 }
4744 }
4745 }
4746 }
4747 }
4748
4749 lastsfp = sfp;
4750 MemCopy ((Pointer) &lastcontext, (Pointer) &context, sizeof (SeqMgrFeatContext));
4751
4752 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
4753 }
4754 }
4755
ExtendFeatures(UpsDataPtr udp,Int4 offset)4756 static Boolean ExtendFeatures (UpsDataPtr udp, Int4 offset)
4757
4758 {
4759 MsgAnswer ans;
4760 CodeBreakPtr cbp;
4761 SeqMgrFeatContext context;
4762 CdRegionPtr crp;
4763 Int4 len;
4764 BioseqPtr newbsp;
4765 BioseqPtr oldbsp;
4766 RnaRefPtr rrp;
4767 Uint1 seq_data_type;
4768 SeqFeatPtr sfp;
4769 SeqIdPtr sip;
4770 tRNAPtr trp;
4771 SeqDataPtr sdp;
4772
4773 if (udp->salp != NULL)
4774 if (FALSE == udp->isSet)
4775 if (StringICmp (udp->seq1, udp->seq2) == 0) {
4776 ans = Message (MSG_OKC, "Replacement sequence is identical to"
4777 " original - possible error");
4778 if (ans == ANS_CANCEL) return FALSE;
4779 }
4780
4781 oldbsp = udp->oldbsp;
4782 newbsp = udp->newbsp;
4783
4784 sip = SeqIdFindBest (oldbsp->id, 0);
4785 if (sip == NULL) return FALSE;
4786
4787 if (offset > 0) {
4788 sfp = SeqMgrGetNextFeature (oldbsp, NULL, 0, 0, &context);
4789 while (sfp != NULL) {
4790 OffsetLocation (sfp->location, offset, sip);
4791 switch (sfp->data.choice) {
4792 case SEQFEAT_CDREGION :
4793 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
4794 if (crp != NULL) {
4795 for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
4796 OffsetLocation (cbp->loc, offset, sip);
4797 }
4798 }
4799 break;
4800 case SEQFEAT_RNA :
4801 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
4802 if (rrp != NULL && rrp->ext.choice == 2) {
4803 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
4804 if (trp != NULL && trp->anticodon != NULL) {
4805 OffsetLocation (trp->anticodon, offset, sip);
4806 }
4807 }
4808 break;
4809 default :
4810 break;
4811 }
4812 sfp = SeqMgrGetNextFeature (oldbsp, sfp, 0, 0, &context);
4813 }
4814 }
4815
4816 /* switch bioseqs to finish extension */
4817
4818 sdp = oldbsp->seq_data;
4819 oldbsp->seq_data = newbsp->seq_data;
4820 newbsp->seq_data = sdp;
4821 len = oldbsp->length;
4822 oldbsp->length = newbsp->length;
4823 newbsp->length = len;
4824 seq_data_type = oldbsp->seq_data_type;
4825 oldbsp->seq_data_type = newbsp->seq_data_type;
4826 newbsp->seq_data_type = seq_data_type;
4827
4828 return TRUE;
4829 }
4830
ExtendBothEnds(UpsDataPtr udp)4831 static Boolean ExtendBothEnds (UpsDataPtr udp)
4832
4833 {
4834 ByteStorePtr bs;
4835 Char ch;
4836 Int4 i, newlen;
4837 BioseqPtr newbsp;
4838 BioseqPtr oldbsp;
4839 CharPtr ptr, str, tmp;
4840
4841 /* construct replacement sequence by extending old sequence */
4842
4843 newlen = udp->new5 + udp->olda + udp->new3;
4844 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
4845 if (str == NULL)
4846 return FALSE;
4847 ptr = str;
4848
4849 tmp = udp->seq2;
4850 for (i = 0; i < udp->new5; i++) {
4851 ch = *tmp;
4852 *ptr = ch;
4853 tmp++;
4854 ptr++;
4855 }
4856
4857 tmp = udp->seq1 + udp->old5;
4858 for (i = 0; i < udp->olda; i++) {
4859 ch = *tmp;
4860 *ptr = ch;
4861 tmp++;
4862 ptr++;
4863 }
4864
4865 tmp = udp->seq2 + udp->new5 + udp->newa;
4866 for (i = 0; i < udp->new3; i++) {
4867 ch = *tmp;
4868 *ptr = ch;
4869 tmp++;
4870 ptr++;
4871 }
4872
4873 *ptr = '\0';
4874 bs = BSNew (newlen);
4875 BSWrite (bs, (VoidPtr) str, newlen);
4876
4877 udp->seq2 = MemFree (udp->seq2);
4878 udp->seq2 = str;
4879
4880 if (bs != NULL && BSLen (bs) < 1) {
4881 bs = BSFree (bs);
4882 }
4883 if (bs == NULL) return FALSE;
4884
4885 /* overlap turned into replacement sequence */
4886
4887 oldbsp = udp->oldbsp;
4888 newbsp = udp->newbsp;
4889 newbsp->seq_data = SeqDataFree (newbsp->seq_data, newbsp->seq_data_type);
4890 newbsp->seq_data = (SeqDataPtr) bs;
4891 newbsp->seq_data_type = Seq_code_iupacna;
4892 newbsp->length = newlen;
4893
4894 /* then finish by offsetting features */
4895
4896 return ExtendFeatures (udp, udp->new5);
4897 }
4898
Extend5Prime(UpsDataPtr udp)4899 static Boolean Extend5Prime (UpsDataPtr udp)
4900
4901 {
4902 ByteStorePtr bs;
4903 Char ch;
4904 Int4 i, newlen;
4905 BioseqPtr newbsp;
4906 BioseqPtr oldbsp;
4907 CharPtr ptr, str, tmp;
4908
4909 /* construct replacement sequence by extending old sequence */
4910
4911 newlen = udp->new5 + udp->olda + udp->old3;
4912 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
4913 if (str == NULL)
4914 return FALSE;
4915 ptr = str;
4916
4917 tmp = udp->seq2;
4918 for (i = 0; i < udp->new5; i++) {
4919 ch = *tmp;
4920 *ptr = ch;
4921 tmp++;
4922 ptr++;
4923 }
4924
4925 tmp = udp->seq1 + udp->old5;
4926 for (i = 0; i < udp->olda + udp->old3; i++) {
4927 ch = *tmp;
4928 *ptr = ch;
4929 tmp++;
4930 ptr++;
4931 }
4932
4933 *ptr = '\0';
4934 bs = BSNew (newlen);
4935 BSWrite (bs, (VoidPtr) str, newlen);
4936
4937 udp->seq2 = MemFree (udp->seq2);
4938 udp->seq2 = str;
4939
4940 if (bs != NULL && BSLen (bs) < 1) {
4941 bs = BSFree (bs);
4942 }
4943 if (bs == NULL) return FALSE;
4944
4945 /* overlap turned into replacement sequence */
4946
4947 oldbsp = udp->oldbsp;
4948 newbsp = udp->newbsp;
4949 newbsp->seq_data = SeqDataFree (newbsp->seq_data, newbsp->seq_data_type);
4950 newbsp->seq_data = (SeqDataPtr) bs;
4951 newbsp->seq_data_type = Seq_code_iupacna;
4952 newbsp->length = newlen;
4953
4954 /* then finish by offsetting features */
4955
4956 return ExtendFeatures (udp, udp->new5);
4957 }
4958
Extend3Prime(UpsDataPtr udp)4959 static Boolean Extend3Prime (UpsDataPtr udp)
4960
4961 {
4962 ByteStorePtr bs;
4963 Char ch;
4964 Int4 i, newlen;
4965 BioseqPtr newbsp;
4966 BioseqPtr oldbsp;
4967 CharPtr ptr, str, tmp;
4968
4969 /* construct replacement sequence by extending old sequence */
4970
4971 newlen = udp->old5 + udp->olda + udp->new3;
4972 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
4973 if (str == NULL)
4974 return FALSE;
4975 ptr = str;
4976
4977 tmp = udp->seq1;
4978 for (i = 0; i < udp->old5 + udp->olda; i++) {
4979 ch = *tmp;
4980 *ptr = ch;
4981 tmp++;
4982 ptr++;
4983 }
4984
4985 tmp = udp->seq2 + udp->new5 + udp->newa;
4986 for (i = 0; i < udp->new3; i++) {
4987 ch = *tmp;
4988 *ptr = ch;
4989 tmp++;
4990 ptr++;
4991 }
4992
4993 *ptr = '\0';
4994 bs = BSNew (newlen);
4995 BSWrite (bs, (VoidPtr) str, newlen);
4996
4997 udp->seq2 = MemFree (udp->seq2);
4998 udp->seq2 = str;
4999
5000 if (bs != NULL && BSLen (bs) < 1) {
5001 bs = BSFree (bs);
5002 }
5003 if (bs == NULL) return FALSE;
5004
5005 /* overlap turned into replacement sequence */
5006
5007 oldbsp = udp->oldbsp;
5008 newbsp = udp->newbsp;
5009 newbsp->seq_data = SeqDataFree (newbsp->seq_data, newbsp->seq_data_type);
5010 newbsp->seq_data = (SeqDataPtr) bs;
5011 newbsp->seq_data_type = Seq_code_iupacna;
5012 newbsp->length = newlen;
5013
5014 /* no offset, but ExtendFeatures finishes switch */
5015
5016 return ExtendFeatures (udp, 0);
5017 }
5018
ExtendOneSequence(UpsDataPtr udp)5019 static Boolean ExtendOneSequence (UpsDataPtr udp)
5020 {
5021 Boolean update = FALSE;
5022 MsgAnswer ans;
5023 Uint2 entityID;
5024 CharPtr errmsg = NULL;
5025
5026
5027 if (udp == NULL) return FALSE;
5028
5029 switch (udp->rmcval) {
5030 case UPDATE_REPLACE :
5031 if (udp->old5 > 0 && udp->old3 > 0) {
5032 errmsg = "Unaligned sequence at 5' and 3' ends. Do you wish to proceed?";
5033 } else if (udp->old5 > 0) {
5034 errmsg = "Unaligned sequence at 5' end. Do you wish to proceed?";
5035 } else if (udp->old3 > 0) {
5036 errmsg = "Unaligned sequence at 3' end. Do you wish to proceed?";
5037 }
5038 break;
5039 case UPDATE_EXTEND5 :
5040 if (udp->old5 > 0) {
5041 errmsg = "Unaligned sequence at 5' end. Do you wish to proceed?";
5042 }
5043 break;
5044 case UPDATE_EXTEND3 :
5045 if (udp->old3 > 0) {
5046 errmsg = "Unaligned sequence at 3' end. Do you wish to proceed?";
5047 }
5048 break;
5049 default :
5050 break;
5051 }
5052 if (errmsg != NULL) {
5053 ans = Message (MSG_YN, "%s", errmsg);
5054 if (ans == ANS_NO) {
5055 return FALSE;
5056 }
5057 }
5058
5059 switch (udp->rmcval) {
5060 case UPDATE_REPLACE :
5061 if (ExtendBothEnds (udp)) {
5062 update = TRUE;
5063 }
5064 break;
5065 case UPDATE_EXTEND5:
5066 if (udp->salp == NULL) {
5067 if (Merge5PrimeNoOverlap (udp)) {
5068 update = TRUE;
5069 }
5070 } else if (Extend5Prime (udp)) {
5071 update = TRUE;
5072 }
5073 break;
5074 case UPDATE_EXTEND3 :
5075 if (udp->salp == NULL) {
5076 if (Merge3PrimeNoOverlap (udp)) {
5077 update = TRUE;
5078 }
5079 } else if (Extend3Prime (udp)) {
5080 update = TRUE;
5081 }
5082 break;
5083 default :
5084 break;
5085 }
5086
5087 if (update) {
5088
5089 entityID = ObjMgrGetEntityIDForPointer (udp->oldbsp);
5090 if (GetStatus (udp->add_cit_subs))
5091 {
5092 AddCitSubToUpdatedSequence ( udp->oldbsp, entityID, kSubmitterUpdateText);
5093 }
5094 }
5095 return update;
5096 }
5097
OpenSequenceUpdateLog(UpsDataPtr udp)5098 static void OpenSequenceUpdateLog (UpsDataPtr udp)
5099 {
5100 if (udp == NULL || udp->log_fp != NULL)
5101 {
5102 return;
5103 }
5104 TmpNam (udp->log_path);
5105 udp->log_fp = FileOpen (udp->log_path, "wb");
5106 }
5107
CloseOutSequenceUpdateLog(UpsDataPtr udp)5108 static void CloseOutSequenceUpdateLog (UpsDataPtr udp)
5109 {
5110 if (udp == NULL || udp->log_fp == NULL)
5111 {
5112 return;
5113 }
5114 FileClose (udp->log_fp);
5115 udp->log_fp = NULL;
5116 if (udp->data_in_log) {
5117 LaunchGeneralTextViewer (udp->log_path, "Protein changes");
5118 udp->data_in_log = FALSE;
5119 }
5120 FileRemove (udp->log_path);
5121 }
5122
5123
5124 static Boolean PrepareToUpdateSequences (UpsDataPtr udp);
5125 static Boolean PrepareUpdatePtr (UpsDataPtr udp);
5126 static ForM UpdateSequenceForm (UpsDataPtr udp);
5127 static void UpdateOneSequence (
5128 UpsDataPtr udp,
5129 Int2 sfbval,
5130 Boolean add_cit_subs,
5131 Boolean update_proteins);
5132
5133
FindNewCDSStop(SeqLocPtr slp,BioseqPtr bsp,Int4 prot_len)5134 static Int4 FindNewCDSStop (SeqLocPtr slp, BioseqPtr bsp, Int4 prot_len)
5135 {
5136 Int4 loc_len, tot_len = 0;
5137 SeqLocPtr this_slp;
5138 Int4 curr_start;
5139
5140 for (this_slp = SeqLocFindNext (slp, NULL);
5141 this_slp != NULL;
5142 this_slp = SeqLocFindNext (slp, this_slp))
5143 {
5144 loc_len = SeqLocLen (this_slp);
5145 curr_start = GetOffsetInBioseq (this_slp, bsp, SEQLOC_START);
5146 if (loc_len + tot_len > prot_len)
5147 {
5148 curr_start = GetOffsetInBioseq (this_slp, bsp, SEQLOC_START);
5149 if (SeqLocStrand (this_slp) == Seq_strand_minus)
5150 {
5151 return curr_start - (prot_len - tot_len) + 1;
5152 }
5153 else
5154 {
5155 return curr_start + prot_len - tot_len - 1;
5156 }
5157 }
5158 tot_len += loc_len;
5159 }
5160 return tot_len;
5161 }
5162
5163
FixProteinString(SeqFeatPtr sfp,Uint1 strand,Boolean truncate_proteins,Boolean PNTR truncated,Boolean PNTR contains_start,Boolean PNTR contains_stop)5164 static CharPtr FixProteinString
5165 (SeqFeatPtr sfp,
5166 Uint1 strand,
5167 Boolean truncate_proteins,
5168 Boolean PNTR truncated,
5169 Boolean PNTR contains_start,
5170 Boolean PNTR contains_stop)
5171 {
5172 ByteStorePtr bs;
5173 BioseqPtr nucBsp;
5174 CharPtr newprot;
5175 CharPtr ptr;
5176 Char ch;
5177 Int4 start, stop, new_stop, prot_len;
5178 Boolean changed;
5179 CdRegionPtr crp;
5180
5181 if (sfp == NULL || truncated == NULL
5182 || contains_start == NULL
5183 || contains_stop == NULL) {
5184 return NULL;
5185 }
5186
5187 bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
5188 if (bs == NULL) return NULL;
5189 newprot = BSMerge (bs, NULL);
5190 bs = BSFree (bs);
5191 if (newprot == NULL) return NULL;
5192
5193 ptr = newprot;
5194 ch = *ptr;
5195 if (ch == 'M') {
5196 *contains_start = TRUE;
5197 } else {
5198 *contains_start = FALSE;
5199 }
5200 *contains_stop = FALSE;
5201 *truncated = FALSE;
5202 while (ch != '\0')
5203 {
5204 *ptr = TO_UPPER (ch);
5205 if (ch == '*') {
5206 *contains_stop = TRUE;
5207 if (*(ptr + 1) == 0 || truncate_proteins) {
5208 *ptr = 0;
5209 if (truncate_proteins && *(ptr + 1) != 0) {
5210 *truncated = TRUE;
5211 nucBsp = BioseqFindFromSeqLoc (sfp->location);
5212 if (nucBsp == NULL) return newprot;
5213 start = GetOffsetInBioseq (sfp->location, nucBsp, SEQLOC_START);
5214 stop = GetOffsetInBioseq (sfp->location, nucBsp, SEQLOC_STOP);
5215 prot_len = (1 + ptr - newprot) * 3;
5216 if (sfp->data.choice == SEQFEAT_CDREGION) {
5217 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
5218 if (crp != NULL) {
5219 if (crp->frame == 2) {
5220 prot_len += 1;
5221 } else if (crp->frame == 3) {
5222 prot_len += 2;
5223 }
5224 }
5225 }
5226 new_stop = FindNewCDSStop (sfp->location, nucBsp, prot_len);
5227 if (strand == Seq_strand_minus) {
5228 sfp->location = SeqLocDelete (sfp->location, SeqLocId (sfp->location),
5229 stop, new_stop - 1, FALSE, &changed);
5230 } else {
5231 sfp->location = SeqLocDelete (sfp->location, SeqLocId (sfp->location),
5232 new_stop + 1, stop, FALSE, &changed);
5233 }
5234 }
5235 return newprot;
5236 }
5237 }
5238 ptr++;
5239 ch = *ptr;
5240 }
5241 return newprot;
5242 }
5243
5244 /* This function will truncate base pairs to make the length of the CDS
5245 * a multiple of three. If truncation occurs, the function returns TRUE,
5246 * otherwise the function returns FALSE.
5247 */
ShiftStopForLengthChange(SeqLocPtr slp,BioseqPtr nucBsp,Int4 transl_except_len,Boolean PNTR changed)5248 static SeqLocPtr ShiftStopForLengthChange
5249 (SeqLocPtr slp,
5250 BioseqPtr nucBsp,
5251 Int4 transl_except_len,
5252 Boolean PNTR changed)
5253 {
5254 Int4 start, stop, new_stop;
5255 Uint1 strand;
5256 SeqIdPtr sip;
5257 Int4 len;
5258
5259 if (slp == NULL || nucBsp == NULL || changed == NULL) {
5260 return NULL;
5261 }
5262
5263 *changed = FALSE;
5264
5265 start = GetOffsetInBioseq (slp, nucBsp, SEQLOC_START);
5266 stop = GetOffsetInBioseq (slp, nucBsp, SEQLOC_STOP);
5267 new_stop = stop;
5268 strand = SeqLocStrand (slp);
5269 len = SeqLocLen (slp);
5270
5271 if (strand == Seq_strand_minus) {
5272 if (len % 3 != transl_except_len) {
5273 new_stop += len % 3 + transl_except_len;
5274 sip = SeqLocId (slp);
5275 slp = SeqLocDelete (slp, sip, stop, new_stop - 1, FALSE, changed);
5276 if (slp == NULL) {
5277 return NULL;
5278 }
5279 }
5280 } else {
5281 if (len % 3 != transl_except_len) {
5282 new_stop -= len % 3 - transl_except_len;
5283 sip = SeqLocId (slp);
5284 slp = SeqLocDelete (slp, sip, new_stop + 1, stop, FALSE, changed);
5285 if (slp == NULL) {
5286 return NULL;
5287 }
5288 }
5289 }
5290 return slp;
5291 }
5292
5293 extern SeqLocPtr
ExpandSeqLoc(Int4 start,Int4 stop,Uint1 strand,BioseqPtr bsp,SeqLocPtr slp)5294 ExpandSeqLoc
5295 (Int4 start,
5296 Int4 stop,
5297 Uint1 strand,
5298 BioseqPtr bsp,
5299 SeqLocPtr slp)
5300 {
5301 Int4 curr_start, curr_stop, tmp_start, tmp_stop;
5302 SeqLocPtr this_slp;
5303
5304 if (slp == NULL) return NULL;
5305
5306 if (slp->choice == SEQLOC_INT || slp->choice == SEQLOC_PNT) {
5307 slp = expand_seq_loc (start, stop, strand, slp);
5308 } else {
5309 curr_start = GetOffsetInBioseq (slp, bsp, SEQLOC_START);
5310 curr_stop = GetOffsetInBioseq (slp, bsp, SEQLOC_STOP);
5311 for (this_slp = SeqLocFindNext (slp, NULL);
5312 this_slp != NULL;
5313 this_slp = SeqLocFindNext (slp, this_slp))
5314 {
5315 tmp_start = GetOffsetInBioseq (this_slp, bsp, SEQLOC_START);
5316 tmp_stop = GetOffsetInBioseq (this_slp, bsp, SEQLOC_STOP);
5317 if (strand == Seq_strand_minus) {
5318 if (tmp_start == curr_start && tmp_start < stop) {
5319 this_slp = expand_seq_loc (tmp_stop, stop, strand, this_slp);
5320 tmp_start = stop;
5321 }
5322 if (tmp_stop == curr_stop && tmp_stop > start) {
5323 this_slp = expand_seq_loc (start, tmp_start, strand, this_slp);
5324 }
5325 } else {
5326 if (tmp_start == curr_start && tmp_start > start) {
5327 this_slp = expand_seq_loc (start, tmp_stop, strand, this_slp);
5328 tmp_start = start;
5329 }
5330 if (tmp_stop == curr_stop && tmp_stop < stop) {
5331 this_slp = expand_seq_loc (tmp_start, stop, strand, this_slp);
5332 }
5333 }
5334 }
5335 }
5336 return slp;
5337 }
5338
ShiftLocationForFrame(SeqLocPtr slp,Uint1 frame,BioseqPtr nucBsp)5339 static SeqLocPtr ShiftLocationForFrame
5340 (SeqLocPtr slp,
5341 Uint1 frame,
5342 BioseqPtr nucBsp)
5343 {
5344 Int4 max_stop, start, stop;
5345 Uint1 strand;
5346 SeqIdPtr sip;
5347 Int4 offset, new_start;
5348 Boolean changed;
5349
5350
5351 if (slp == NULL || nucBsp == NULL) return NULL;
5352 if (frame == 0 || frame == 1) return slp;
5353
5354 start = GetOffsetInBioseq (slp, nucBsp, SEQLOC_START);
5355 stop = GetOffsetInBioseq (slp, nucBsp, SEQLOC_STOP);
5356 strand = SeqLocStrand (slp);
5357 max_stop = nucBsp->length - 1;
5358 new_start = start;
5359
5360 offset = frame - 1;
5361 sip = SeqLocId (slp);
5362 if (strand == Seq_strand_minus) {
5363 stop -= offset;
5364 new_start = start - offset;
5365 if ((1 + new_start - stop ) % 3 != 0) {
5366 new_start -= (1 + new_start - stop) % 3;
5367 }
5368 if (stop < 0) stop = 0;
5369 slp = ExpandSeqLoc (stop, start, strand, nucBsp, slp);
5370 if (new_start < 0) new_start = 0;
5371 if (new_start < start) {
5372 slp = SeqLocDelete (slp, sip, new_start + 1, start, FALSE, &changed);
5373 }
5374 } else {
5375 stop += offset;
5376 new_start = start + offset;
5377 if ((1 + stop - new_start) % 3 != 0) {
5378 new_start += (1 + stop - new_start) % 3;
5379 }
5380 if (stop > max_stop) stop = max_stop;
5381 slp = ExpandSeqLoc (start, stop, strand, nucBsp, slp);
5382 if (start > max_stop) start = max_stop;
5383 if (new_start > start) {
5384 slp = SeqLocDelete (slp, sip, start, new_start - 1, FALSE, &changed);
5385 }
5386 }
5387 return slp;
5388 }
5389
GetTranslationTable(CdRegionPtr crp,Boolean PNTR table_is_local)5390 static TransTablePtr GetTranslationTable (CdRegionPtr crp, Boolean PNTR table_is_local)
5391 {
5392 TransTablePtr tbl = NULL;
5393 ValNodePtr vnp;
5394 Int2 genCode = 0;
5395 Char str [32];
5396
5397 if (crp == NULL || table_is_local == NULL) return NULL;
5398
5399 *table_is_local = FALSE;
5400 /* find genetic code */
5401
5402 if (crp->genetic_code != NULL) {
5403 vnp = (ValNodePtr) crp->genetic_code->data.ptrvalue;
5404 while (vnp != NULL) {
5405 if (vnp->choice == 2) {
5406 genCode = (Int2) vnp->data.intvalue;
5407 }
5408 vnp = vnp->next;
5409 }
5410 }
5411
5412 if (genCode == 7) {
5413 genCode = 4;
5414 } else if (genCode == 8) {
5415 genCode = 1;
5416 } else if (genCode == 0) {
5417 genCode = 1;
5418 }
5419
5420 /* set up translation table */
5421 /* set app property name for storing desired FSA */
5422
5423 sprintf (str, "TransTableFSAforGenCode%d", (int) genCode);
5424
5425 /* get FSA for desired genetic code if it already exists */
5426
5427 tbl = (TransTablePtr) GetAppProperty (str);
5428 if (tbl == NULL) {
5429 tbl = TransTableNew (genCode);
5430 *table_is_local = TRUE;
5431 }
5432 return tbl;
5433 }
5434
ExtendProtein5(SeqFeatPtr sfp,Uint2 input_entityID,Boolean force_partial)5435 static CharPtr ExtendProtein5
5436 (SeqFeatPtr sfp,
5437 Uint2 input_entityID,
5438 Boolean force_partial)
5439 {
5440 CdRegionPtr crp;
5441 TransTablePtr tbl = NULL;
5442 Boolean table_is_local = FALSE;
5443 SeqLocPtr test_slp;
5444 SeqIdPtr sip;
5445 BioseqPtr nucBsp;
5446 Int4 start, new_start;
5447 Int4 stop, new_stop;
5448 Int4 increment = 3000;
5449 Int4 offset;
5450 Uint1 strand;
5451 Boolean found_start = FALSE;
5452 Boolean found_stop = FALSE;
5453 Boolean stop_looking = FALSE;
5454 Int4 dna_len;
5455 CharPtr bases;
5456 Int4 total;
5457 Int2 state;
5458 CharPtr codon_start;
5459 Boolean partial3, partial5;
5460 Boolean contains_start, contains_stop;
5461 Boolean changed;
5462 CharPtr newprot;
5463 Boolean truncated;
5464
5465 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION
5466 || (crp = (CdRegionPtr)sfp->data.value.ptrvalue) == NULL) {
5467 return NULL;
5468 }
5469 nucBsp = GetBioseqGivenSeqLoc (sfp->location, input_entityID);
5470 if (nucBsp == NULL) return NULL;
5471
5472 tbl = GetTranslationTable (crp, &table_is_local);
5473 if (tbl == NULL) return NULL;
5474
5475 test_slp = SeqLocMerge (nucBsp, sfp->location, NULL, FALSE, FALSE, FALSE);
5476 strand = SeqLocStrand (sfp->location);
5477 sip = SeqLocId (sfp->location);
5478 offset = -1;
5479
5480 start = GetOffsetInBioseq (test_slp, nucBsp, SEQLOC_START);
5481 if (start == 0)
5482 {
5483 stop_looking = TRUE;
5484 }
5485
5486 while (((! found_start && ! found_stop) || force_partial) && ! stop_looking) {
5487 start = GetOffsetInBioseq (test_slp, nucBsp, SEQLOC_START);
5488 stop = GetOffsetInBioseq (test_slp, nucBsp, SEQLOC_STOP);
5489 if (strand == Seq_strand_minus) {
5490 new_start = start + increment;
5491 new_stop = start + 1;
5492 if (new_start > nucBsp->length - 1) {
5493 new_start = start + ((Int4)((nucBsp->length - 1 - start) / 3)) * 3;
5494 stop_looking = TRUE;
5495 }
5496 test_slp = ExpandSeqLoc (stop, new_start, strand, nucBsp, test_slp);
5497 test_slp = SeqLocDelete (test_slp, sip, stop, start, FALSE, &changed);
5498 } else {
5499 new_start = start - increment;
5500 new_stop = start - 1;
5501 if (new_start < 0) {
5502 new_start = start % 3;
5503 stop_looking = TRUE;
5504 }
5505 test_slp = ExpandSeqLoc (new_start, stop, strand, nucBsp, test_slp);
5506 test_slp = SeqLocDelete (test_slp, sip, start, stop, FALSE, &changed);
5507 }
5508 dna_len = SeqLocLen (test_slp);
5509 bases = ReadCodingRegionBases (test_slp, dna_len, crp->frame, &total);
5510 if (bases == NULL) {
5511 stop_looking = TRUE;
5512 } else {
5513 state = 0;
5514 codon_start = bases + StringLen (bases) - 3;
5515 while (codon_start >= bases && ! found_start && ! found_stop) {
5516 state = 0;
5517 state = NextCodonState (tbl, state, (Uint1)*codon_start);
5518 state = NextCodonState (tbl, state, (Uint1)*(codon_start + 1));
5519 state = NextCodonState (tbl, state, (Uint1)*(codon_start + 2));
5520 if (IsOrfStart (tbl, state, TTBL_TOP_STRAND)) {
5521 found_start = TRUE;
5522 if (strand == Seq_strand_minus) {
5523 offset = new_start - (codon_start - bases);
5524 } else {
5525 offset = new_start + codon_start - bases;
5526 }
5527 } else if (IsOrfStop (tbl, state, TTBL_TOP_STRAND)) {
5528 found_stop = TRUE;
5529 } else {
5530 codon_start -= 3;
5531 }
5532 }
5533 MemFree (bases);
5534 }
5535 }
5536
5537 SeqLocFree (test_slp);
5538 if (! found_stop) {
5539 start = GetOffsetInBioseq (sfp->location, nucBsp, SEQLOC_START);
5540 stop = GetOffsetInBioseq (sfp->location, nucBsp, SEQLOC_STOP);
5541 if (found_start) {
5542 if (strand == Seq_strand_minus) {
5543 sfp->location = ExpandSeqLoc (stop, offset, strand, nucBsp, sfp->location);
5544 } else {
5545 sfp->location = ExpandSeqLoc (offset, stop, strand, nucBsp, sfp->location);
5546 }
5547 } else {
5548 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
5549 SetSeqLocPartial (sfp->location, TRUE, partial3);
5550 sfp->partial = TRUE;
5551 if (crp->frame == 0)
5552 {
5553 crp->frame = 1;
5554 }
5555 if (strand == Seq_strand_minus) {
5556 sfp->location = ExpandSeqLoc (stop, nucBsp->length - 1, strand, nucBsp, sfp->location);
5557 crp->frame = (nucBsp->length - 1 - start + crp->frame - 1) % 3 + 1;
5558 } else {
5559 sfp->location = ExpandSeqLoc (0, stop, strand, nucBsp, sfp->location);
5560 crp->frame = (start + crp->frame - 1) % 3 + 1;
5561 }
5562 }
5563 }
5564 newprot = FixProteinString (sfp, strand, FALSE, &truncated,
5565 &contains_start, &contains_stop);
5566 if (table_is_local) {
5567 TransTableFree (tbl);
5568 }
5569
5570 return newprot;
5571 }
5572
5573
ExtendProtein3(SeqFeatPtr sfp,Uint2 input_entityID,Boolean force_partial)5574 extern CharPtr ExtendProtein3
5575 (SeqFeatPtr sfp,
5576 Uint2 input_entityID,
5577 Boolean force_partial)
5578 {
5579 BioseqPtr nucBsp;
5580 Int4 max_stop, min_start, start, stop;
5581 Uint1 strand;
5582 Boolean contains_start, contains_stop;
5583 Int4 increment = 3000;
5584 CharPtr newprot;
5585 Boolean partial5, partial3;
5586 Boolean truncated;
5587
5588 if (sfp == NULL) return NULL;
5589
5590 nucBsp = GetBioseqGivenSeqLoc (sfp->location, input_entityID);
5591 if (nucBsp == NULL) return NULL;
5592
5593 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
5594 start = GetOffsetInBioseq (sfp->location, nucBsp, SEQLOC_START);
5595 stop = GetOffsetInBioseq (sfp->location, nucBsp, SEQLOC_STOP);
5596 strand = SeqLocStrand (sfp->location);
5597 max_stop = nucBsp->length - 1;
5598 if (stop > start) {
5599 while (max_stop % 3 != stop % 3) {
5600 max_stop --;
5601 }
5602 min_start = start %3;
5603 } else {
5604 while (max_stop % 3 != start % 3) {
5605 max_stop --;
5606 }
5607 min_start = stop % 3;
5608 }
5609
5610 contains_stop = FALSE;
5611 contains_start = FALSE;
5612 newprot = NULL;
5613 /* need to initialize newprot in case we're already at the edge */
5614 if ((strand != Seq_strand_minus && stop == max_stop)
5615 || (strand == Seq_strand_minus && stop == min_start))
5616 {
5617 newprot = FixProteinString (sfp, strand, FALSE, &truncated,
5618 &contains_start, &contains_stop);
5619 }
5620 while ((! contains_stop || force_partial) &&
5621 ( (strand == Seq_strand_minus && stop > min_start)
5622 || (strand != Seq_strand_minus && stop < max_stop)))
5623 {
5624 if (newprot != NULL) {
5625 MemFree (newprot);
5626 newprot = NULL;
5627 }
5628 if (strand == Seq_strand_minus) {
5629 stop -= increment;
5630 if (stop < min_start) {
5631 stop = min_start;
5632 }
5633 sfp->location = ExpandSeqLoc (stop, start, strand, nucBsp, sfp->location);
5634 } else {
5635 stop += increment;
5636 if (stop > max_stop) {
5637 stop = max_stop;
5638 }
5639 sfp->location = ExpandSeqLoc (start, stop, strand, nucBsp, sfp->location);
5640 }
5641 newprot = FixProteinString (sfp, strand, TRUE, &truncated,
5642 &contains_start, &contains_stop);
5643 }
5644
5645 if (! contains_stop || force_partial) {
5646 start = GetOffsetInBioseq (sfp->location, nucBsp, SEQLOC_START);
5647 stop = GetOffsetInBioseq (sfp->location, nucBsp, SEQLOC_STOP);
5648 if (strand == Seq_strand_minus) {
5649 sfp->location = ExpandSeqLoc (0, start, strand, nucBsp, sfp->location);
5650 } else {
5651 sfp->location = ExpandSeqLoc (start, nucBsp->length - 1, strand, nucBsp, sfp->location);
5652 }
5653 partial3 = TRUE;
5654 SetSeqLocPartial (sfp->location, partial5, TRUE);
5655 }
5656 return newprot;
5657 }
5658
MergeOverlapsForThisFeature(SeqFeatPtr sfp)5659 static Boolean MergeOverlapsForThisFeature (SeqFeatPtr sfp)
5660 {
5661 if (sfp == NULL) return FALSE;
5662 return ! sfp->excpt;
5663 }
5664
5665 static Boolean
AdjustCDSForUpdate(SeqFeatPtr sfp,Uint2 input_entityID,Uint1 frame,Int4 transl_except_len,Boolean truncate_proteins,Boolean extend_proteins5,Boolean extend_proteins3,Boolean PNTR truncated,Boolean PNTR stop_shifted,Boolean PNTR extended5,Boolean PNTR extended3,BioseqPtr protBsp,BioseqPtr PNTR newbsp)5666 AdjustCDSForUpdate
5667 (SeqFeatPtr sfp,
5668 Uint2 input_entityID,
5669 Uint1 frame,
5670 Int4 transl_except_len,
5671 Boolean truncate_proteins,
5672 Boolean extend_proteins5,
5673 Boolean extend_proteins3,
5674 Boolean PNTR truncated,
5675 Boolean PNTR stop_shifted,
5676 Boolean PNTR extended5,
5677 Boolean PNTR extended3,
5678 BioseqPtr protBsp,
5679 BioseqPtr PNTR newbsp)
5680 {
5681 ByteStorePtr bs;
5682 CharPtr newprot, ptr;
5683 SeqEntryPtr nwsep;
5684 BioseqPtr newBsp;
5685 Boolean contains_start, contains_stop;
5686 Uint1 strand;
5687 SeqLocPtr newloc;
5688 BioseqPtr nucBsp;
5689 Boolean partial5, partial3;
5690 CharPtr seqnew = NULL, seqold = NULL;
5691 Boolean rval = FALSE;
5692
5693 if (sfp == NULL
5694 || sfp->idx.subtype != FEATDEF_CDS
5695 || sfp->product == NULL
5696 || protBsp == NULL
5697 || truncated == NULL || stop_shifted == NULL
5698 || extended5 == NULL || extended3 == NULL
5699 || newbsp == NULL)
5700 {
5701 return FALSE;
5702 }
5703
5704 CheckSeqLocForPartial (sfp->location, &partial3, &partial5);
5705
5706 nucBsp = GetBioseqGivenSeqLoc (sfp->location, input_entityID);
5707 if (nucBsp == NULL) return FALSE;
5708
5709 newloc = SeqLocMergeExEx (nucBsp, sfp->location, NULL, FALSE, FALSE,
5710 MergeOverlapsForThisFeature (sfp),
5711 FALSE, FALSE, FALSE, FALSE);
5712
5713 if (newloc == NULL) return FALSE;
5714 sfp->location = newloc;
5715 strand = SeqLocStrand (sfp->location);
5716 sfp->location = ShiftStopForLengthChange (sfp->location, nucBsp, transl_except_len, stop_shifted);
5717 if (sfp->location == NULL) {
5718 return FALSE;
5719 }
5720
5721 sfp->location = ShiftLocationForFrame (sfp->location, frame, nucBsp);
5722
5723 newprot = FixProteinString (sfp, strand, truncate_proteins, truncated,
5724 &contains_start, &contains_stop);
5725
5726 /* Must do 3' end first, otherwise may truncate at stops introduced by expanding 5' end for partiality */
5727 if ((! contains_stop && extend_proteins3 && transl_except_len == 0)
5728 || ((extend_proteins3 || partial3) && !truncate_proteins)) {
5729 MemFree (newprot);
5730 newprot = ExtendProtein3 (sfp, input_entityID, partial3 && !truncate_proteins);
5731 if (newprot == NULL) return FALSE;
5732 *extended3 = TRUE;
5733 } else {
5734 *extended3 = FALSE;
5735 }
5736 if (! contains_start && (extend_proteins5 || partial5)) {
5737 MemFree (newprot);
5738 newprot = ExtendProtein5 (sfp, input_entityID, partial5);
5739 if (newprot == NULL) return FALSE;
5740 *extended5 = TRUE;
5741 } else {
5742 *extended5 = FALSE;
5743 }
5744
5745 sfp->partial = CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
5746
5747 bs = BSNew (1000);
5748 if (bs != NULL)
5749 {
5750 ptr = newprot;
5751 BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
5752 }
5753 MemFree (newprot);
5754
5755 newBsp = BioseqNew ();
5756 if (newBsp == NULL) {
5757 return FALSE;
5758 }
5759
5760 newBsp->id = SeqIdParse ("lcl|ProtAlign");
5761 newBsp->repr = Seq_repr_raw;
5762 newBsp->mol = Seq_mol_aa;
5763 newBsp->seq_data_type = Seq_code_ncbieaa;
5764 newBsp->seq_data = (SeqDataPtr) bs;
5765 newBsp->length = BSLen (bs);
5766
5767 /* create SeqEntry for temporary protein bioseq to live in */
5768 nwsep = SeqEntryNew ();
5769 nwsep->choice = 1;
5770 nwsep->data.ptrvalue = newBsp;
5771 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) newBsp, nwsep);
5772
5773 seqold = GetSequenceByBsp (protBsp);
5774 seqnew = GetSequenceByBsp (newBsp);
5775
5776 if (StringCmp (seqold, seqnew) == 0
5777 || (contains_stop && ! *truncated
5778 && StringNCmp (seqold,
5779 seqnew,
5780 StringLen (seqold)) == 0))
5781 {
5782 SeqEntryFree (nwsep);
5783 rval = FALSE;
5784 }
5785 else
5786 {
5787 *newbsp = newBsp;
5788 rval = TRUE;
5789 }
5790
5791 return rval;
5792 }
5793
5794
WarnNoProteinUpdate(BioseqPtr bsp)5795 static void WarnNoProteinUpdate (BioseqPtr bsp)
5796 {
5797 Char acc_str [256];
5798 CharPtr warn_format = "Protein %s has not been updated - you must manually re-translate the coding regions and move any protein features";
5799 CharPtr warn_msg;
5800
5801 if (bsp == NULL || bsp->id == NULL) return;
5802 SeqIdWrite (bsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
5803 warn_msg = (CharPtr) MemNew (StringLen (warn_format) + StringLen (acc_str));
5804 if (warn_msg == NULL) return;
5805 sprintf (warn_msg, warn_format, acc_str);
5806 ErrPostEx (SEV_ERROR, 0, 0, warn_msg);
5807 MemFree (warn_msg);
5808 }
5809
5810
LogFrameChange(FILE * fp,BioseqPtr bsp,Uint1 frame)5811 static void LogFrameChange (FILE *fp, BioseqPtr bsp, Uint1 frame)
5812 {
5813 Char acc_str [256];
5814
5815 if (fp == NULL || bsp == NULL || bsp->id == NULL) return;
5816 SeqIdWrite (bsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
5817 fprintf (fp, "Changed frame for %s to %d\n", acc_str, frame);
5818 }
5819
5820
LogProteinTruncate(FILE * fp,BioseqPtr bsp)5821 static void LogProteinTruncate (FILE *fp, BioseqPtr bsp)
5822 {
5823 Char acc_str [256];
5824
5825 if (fp == NULL || bsp == NULL || bsp->id == NULL) return;
5826 SeqIdWrite (bsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
5827 fprintf (fp, "Truncated protein %s at stop\n", acc_str);
5828 }
5829
5830
LogProteinStopShift(FILE * fp,BioseqPtr bsp)5831 static void LogProteinStopShift (FILE *fp, BioseqPtr bsp)
5832 {
5833 Char acc_str [256];
5834
5835 if (fp == NULL || bsp == NULL || bsp->id == NULL) return;
5836 SeqIdWrite (bsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
5837 fprintf (fp, "Adjusted length of CDS for protein %s to be multiple of 3\n", acc_str);
5838 }
5839
5840
LogProteinExtend5(FILE * fp,BioseqPtr bsp)5841 static void LogProteinExtend5 (FILE *fp, BioseqPtr bsp)
5842 {
5843 Char acc_str [256];
5844
5845 if (fp == NULL || bsp == NULL || bsp->id == NULL) return;
5846 SeqIdWrite (bsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
5847 fprintf (fp, "Extended protein %s on 5' end\n", acc_str);
5848 }
5849
5850
LogProteinExtend3(FILE * fp,BioseqPtr bsp)5851 static void LogProteinExtend3 (FILE *fp, BioseqPtr bsp)
5852 {
5853 Char acc_str [256];
5854
5855 if (fp == NULL || bsp == NULL || bsp->id == NULL) return;
5856 SeqIdWrite (bsp->id, acc_str, PRINTID_REPORT, sizeof (acc_str));
5857 fprintf (fp, "Extended protein %s on 3' end\n", acc_str);
5858 }
5859
LogGeneCorrection(FILE * fp,SeqFeatPtr gene,SeqLocPtr oldloc)5860 static void LogGeneCorrection (FILE *fp, SeqFeatPtr gene, SeqLocPtr oldloc)
5861 {
5862 CharPtr loc1, loc2;
5863 SeqMgrFeatContext gcontext;
5864 SeqFeatPtr found_gene;
5865
5866 if (fp == NULL || gene == NULL || gene->location == NULL || oldloc == NULL) return;
5867 found_gene = SeqMgrGetDesiredFeature (gene->idx.entityID, NULL, 0, 0, gene, &gcontext);
5868 if (found_gene == NULL) return;
5869 loc1 = SeqLocPrint (gene->location);
5870 loc2 = SeqLocPrint (oldloc);
5871 if (loc1 != NULL && loc2 != NULL && StringCmp (loc1, loc2) != 0) {
5872 fprintf (fp, "Moved gene %s from %s to %s\n", gcontext.label, loc2, loc1);
5873 }
5874 MemFree (loc1);
5875 MemFree (loc2);
5876 }
5877
5878
LogGeneBadCorrection(FILE * fp,SeqFeatPtr gene)5879 static void LogGeneBadCorrection (FILE *fp, SeqFeatPtr gene)
5880 {
5881 SeqMgrFeatContext gcontext;
5882 SeqFeatPtr found_gene;
5883
5884 if (fp == NULL || gene == NULL || gene->location == NULL) return;
5885 found_gene = SeqMgrGetDesiredFeature (gene->idx.entityID, NULL, 0, 0, gene, &gcontext);
5886 if (found_gene == NULL) return;
5887 fprintf (fp, "Please examine gene %s, new gene may be too large\n", gcontext.label);
5888 }
5889
5890
CorrectCDSGene(SeqFeatPtr sfp,SeqFeatPtr gene_sfp,FILE * fp,Boolean PNTR data_in_log)5891 static void CorrectCDSGene
5892 (SeqFeatPtr sfp,
5893 SeqFeatPtr gene_sfp,
5894 FILE *fp,
5895 Boolean PNTR data_in_log)
5896 {
5897 BioseqPtr bsp;
5898 Boolean partial5, partial3;
5899 SeqLocPtr log_slp, new_slp;
5900 Int2 res;
5901
5902 if (sfp == NULL || gene_sfp == NULL || fp == NULL
5903 || data_in_log == NULL){
5904 return;
5905 }
5906 bsp = BioseqFindFromSeqLoc (sfp->location);
5907 if (bsp == NULL) return;
5908 new_slp = SeqLocMerge (bsp, sfp->location, NULL, TRUE, FALSE, FALSE);
5909 res = SeqLocCompare (gene_sfp->location, new_slp);
5910 if (res == SLC_A_EQ_B) {
5911 SeqLocFree (new_slp);
5912 return;
5913 }
5914 if (SeqLocLen (gene_sfp->location) > SeqLocLen (new_slp)) {
5915 SeqLocFree (new_slp);
5916 new_slp = SeqLocMerge (bsp, sfp->location, gene_sfp->location, TRUE, FALSE, FALSE);
5917 LogGeneBadCorrection (fp, gene_sfp);
5918 }
5919 log_slp = SeqLocMerge (bsp, sfp->location, NULL, FALSE, FALSE, FALSE);
5920
5921 *data_in_log = TRUE;
5922 SeqLocFree (gene_sfp->location);
5923 gene_sfp->location = new_slp;
5924 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
5925 SetSeqLocPartial (gene_sfp->location, partial5, partial3);
5926 gene_sfp->partial = sfp->partial;
5927 LogGeneCorrection (fp, gene_sfp, log_slp);
5928 SeqLocFree (log_slp);
5929 }
5930
FixProtRefPtrs(ValNodePtr feat_list)5931 static void FixProtRefPtrs (ValNodePtr feat_list)
5932 {
5933 ValNodePtr vnp;
5934 SeqFeatPtr sfp;
5935 Uint1 strand;
5936 BioseqPtr bsp;
5937
5938 if (feat_list == NULL) return;
5939 for (vnp = feat_list; vnp != NULL; vnp = vnp->next) {
5940 sfp = (SeqFeatPtr)vnp->data.ptrvalue;
5941 if (sfp == NULL) continue;
5942 bsp = BioseqFindFromSeqLoc (sfp->location);
5943 if (bsp == NULL) continue;
5944 strand = SeqLocStrand (sfp->location);
5945 if (strand == Seq_strand_minus) {
5946 sfp->location = ExpandSeqLoc (bsp->length - 1, 0, strand, bsp, sfp->location);
5947 } else {
5948 sfp->location = ExpandSeqLoc (0, bsp->length - 1, strand, bsp, sfp->location);
5949 }
5950 }
5951 }
5952
5953
Sqn_AlignForSequenceUpdate(BioseqPtr bsp1,BioseqPtr bsp2,BoolPtr revcomp)5954 static SeqAlignPtr Sqn_AlignForSequenceUpdate (BioseqPtr bsp1, BioseqPtr bsp2, BoolPtr revcomp)
5955 {
5956 return AlignForSequenceUpdate (bsp1, bsp2, revcomp, Sequin_GlobalAlign2Seq);
5957 }
5958
5959
PrepareUpdateAlignmentForProtein(SeqFeatPtr sfp,BioseqPtr protBsp,Uint2 input_entityID,FILE * fp,Boolean truncate_proteins,Boolean extend_proteins5,Boolean extend_proteins3,Boolean correct_cds_genes,Int4 transl_except_len,Boolean * data_in_log,SeqAlignPtr PNTR salpptr,BioseqPtr PNTR newbspptr)5960 static Boolean PrepareUpdateAlignmentForProtein
5961 (SeqFeatPtr sfp,
5962 BioseqPtr protBsp,
5963 Uint2 input_entityID,
5964 FILE * fp,
5965 Boolean truncate_proteins,
5966 Boolean extend_proteins5,
5967 Boolean extend_proteins3,
5968 Boolean correct_cds_genes,
5969 Int4 transl_except_len,
5970 Boolean *data_in_log,
5971 SeqAlignPtr PNTR salpptr,
5972 BioseqPtr PNTR newbspptr)
5973 {
5974 Boolean align_succeeded;
5975 Boolean changed_frame;
5976 Uint1 frame_attempts;
5977 ErrSev level;
5978 CdRegionPtr crp;
5979 SeqLocPtr orig_slp;
5980 Boolean orig_partial;
5981 SeqFeatPtr gene_sfp;
5982 SeqMgrFeatContext gcontext;
5983 Boolean truncated, stop_shifted;
5984 Boolean extended5, extended3;
5985 Uint1 old_frame;
5986 BioseqPtr newBsp = NULL;
5987 Boolean adjust_succeeded;
5988 SeqAlignPtr salp = NULL;
5989 Boolean revcomp;
5990
5991 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION
5992 || (crp = (CdRegionPtr)sfp->data.value.ptrvalue) == NULL
5993 || protBsp == NULL
5994 || data_in_log == NULL) {
5995 return FALSE;
5996 }
5997
5998 old_frame = crp->frame;
5999
6000 orig_slp = sfp->location;
6001 orig_partial = sfp->partial;
6002 if (correct_cds_genes) {
6003 gene_sfp = SeqMgrGetOverlappingGene (sfp->location, &gcontext);
6004 }
6005 align_succeeded = FALSE;
6006 changed_frame = FALSE;
6007
6008 level = ErrSetMessageLevel (SEV_MAX);
6009 for (frame_attempts = 1;
6010 frame_attempts < 4 && ! align_succeeded;
6011 frame_attempts ++) {
6012 if (sfp->location != orig_slp) {
6013 if (sfp->location->choice == 0) {
6014 SeqLocFree (sfp->location);
6015 }
6016 sfp->location = orig_slp;
6017 }
6018 sfp->partial = orig_partial;
6019 crp->frame = old_frame;
6020 if (newBsp != NULL) {
6021 newBsp = BioseqFree (newBsp);
6022 }
6023 truncated= FALSE;
6024 stop_shifted = FALSE;
6025 extended5 = FALSE;
6026 extended3 = FALSE;
6027 adjust_succeeded = AdjustCDSForUpdate (sfp,
6028 input_entityID,
6029 frame_attempts,
6030 transl_except_len,
6031 truncate_proteins,
6032 extend_proteins5,
6033 extend_proteins3,
6034 &truncated, &stop_shifted,
6035 &extended5, &extended3,
6036 protBsp, &newBsp);
6037 if (sfp->location == NULL || sfp->location->choice == 0)
6038 {
6039 sfp->location = orig_slp;
6040 }
6041 if (adjust_succeeded)
6042 {
6043 salp = Sqn_AlignForSequenceUpdate (protBsp, newBsp, &revcomp);
6044 }
6045 if (!adjust_succeeded || salp != NULL)
6046 {
6047 if (frame_attempts > 1) {
6048 changed_frame = TRUE;
6049 LogFrameChange (fp, protBsp, frame_attempts);
6050 *data_in_log = TRUE;
6051 }
6052 break;
6053 }
6054 }
6055 ErrSetMessageLevel (level);
6056 if (adjust_succeeded && salp == NULL)
6057 {
6058 /* put CD Region back to original state */
6059 crp->frame = old_frame;
6060 if (sfp->location != orig_slp) {
6061 SeqLocFree (sfp->location);
6062 sfp->location = orig_slp;
6063 }
6064 sfp->partial = orig_partial;
6065 WarnNoProteinUpdate (protBsp);
6066 newBsp = BioseqFree (newBsp);
6067 return FALSE;
6068 }
6069
6070 if (truncated) {
6071 LogProteinTruncate (fp, protBsp);
6072 *data_in_log = TRUE;
6073 }
6074 if (stop_shifted) {
6075 LogProteinStopShift (fp, protBsp);
6076 *data_in_log = TRUE;
6077 }
6078 if (extended5) {
6079 LogProteinExtend5 (fp, protBsp);
6080 *data_in_log = TRUE;
6081 }
6082 if (extended3) {
6083 LogProteinExtend3 (fp, protBsp);
6084 *data_in_log = TRUE;
6085 }
6086
6087 if (correct_cds_genes && gene_sfp != NULL) {
6088 CorrectCDSGene (sfp, gene_sfp, fp, data_in_log);
6089 }
6090 if (sfp->location != orig_slp) {
6091 SeqLocFree (orig_slp);
6092 }
6093
6094 *salpptr = salp;
6095 *newbspptr = newBsp;
6096 return TRUE;
6097 }
6098
6099
CheckForIDCollision(BioseqPtr oldbsp,BioseqPtr newbsp,BoolPtr islocal)6100 static Boolean CheckForIDCollision (
6101 BioseqPtr oldbsp,
6102 BioseqPtr newbsp,
6103 BoolPtr islocal
6104 )
6105
6106 {
6107 SeqIdPtr sip;
6108
6109 if (oldbsp == NULL || newbsp == NULL) return FALSE;
6110 for (sip = newbsp->id; sip != NULL; sip = sip->next) {
6111 if (SeqIdIn (sip, oldbsp->id)) {
6112 if (sip->choice == SEQID_LOCAL) {
6113 *islocal = TRUE;
6114 }
6115 return TRUE;
6116 }
6117 }
6118 return FALSE;
6119 }
6120
6121 static CharPtr convPubDescMssg =
6122 "Do you wish to convert publications to apply only to the appropriate ranges?";
6123
6124 #define UPDATE_SKIP_THIS 1
6125 #define UPDATE_SKIP_ALL 2
6126 #define UPDATE_REPLACE_THIS 3
6127 #define UPDATE_REPLACE_ALL 4
6128 #define UPDATE_CANCEL 5
6129
6130 typedef struct noalignmentchoice
6131 {
6132 Boolean done;
6133 Boolean cancelled;
6134 GrouP action_choice;
6135 Boolean skip_this;
6136 Boolean skip_all;
6137 Boolean replace_this;
6138 Boolean replace_all;
6139 } NoAlignmentChoiceData, PNTR NoAlignmentChoicePtr;
6140
NoAlignmentChoiceOk(ButtoN b)6141 static void NoAlignmentChoiceOk (ButtoN b)
6142 {
6143 NoAlignmentChoicePtr nacp;
6144
6145 nacp = (NoAlignmentChoicePtr) GetObjectExtra (b);
6146 if (nacp == NULL) return;
6147 nacp->cancelled = FALSE;
6148 nacp->done = TRUE;
6149 }
6150
NoAlignmentChoiceCancel(ButtoN b)6151 static void NoAlignmentChoiceCancel (ButtoN b)
6152 {
6153 NoAlignmentChoicePtr nacp;
6154
6155 nacp = (NoAlignmentChoicePtr) GetObjectExtra (b);
6156 if (nacp == NULL) return;
6157 nacp->cancelled = TRUE;
6158 nacp->done = TRUE;
6159 }
6160
GetNoAlignmentChoice(SeqIdPtr id,Int2 previous_choice)6161 static Int2 GetNoAlignmentChoice (SeqIdPtr id, Int2 previous_choice)
6162 {
6163 Char buf [64];
6164 WindoW w;
6165 GrouP h, g, c;
6166 ButtoN b;
6167 NoAlignmentChoiceData nacd;
6168 Char promptstr[115];
6169 Int2 no_aln_choice;
6170 SeqIdPtr sip, sip_next;
6171
6172 sip = SeqIdFindBest (id, 0);
6173 if (sip == NULL) return UPDATE_CANCEL;
6174 w = ModalWindow(-20, -13, -10, -10, NULL);
6175 if (w == NULL) return 0;
6176
6177 h = HiddenGroup (w, -1, 0, NULL);
6178 g = HiddenGroup(h, 0, 4, NULL);
6179 sip_next = sip->next;
6180 sip->next = NULL;
6181 SeqIdWrite (sip, buf, PRINTID_REPORT, sizeof (buf) - 1);
6182 sip->next = sip_next;
6183 sprintf (promptstr, "There is no alignment between the sequences for %s.", buf);
6184 StaticPrompt (g, promptstr, 0, popupMenuHeight, programFont, 'l');
6185 StaticPrompt (g, "You may choose to :", 0, popupMenuHeight, programFont, 'l');
6186 nacd.action_choice = HiddenGroup (g, 0, 4, NULL);
6187 RadioButton (nacd.action_choice, "Skip This Sequence");
6188 RadioButton (nacd.action_choice, "Skip All Sequences without Alignments");
6189 RadioButton (nacd.action_choice, "Replace This Sequence");
6190 RadioButton (nacd.action_choice, "Replace All Sequences without Alignments");
6191 if (previous_choice > 0 && previous_choice < UPDATE_CANCEL)
6192 {
6193 SetValue (nacd.action_choice, previous_choice);
6194 }
6195 else
6196 {
6197 SetValue (nacd.action_choice, 1);
6198 }
6199 c = HiddenGroup (h, 2, 0, NULL);
6200 b = PushButton (c, "Ok", NoAlignmentChoiceOk);
6201 SetObjectExtra (b, &nacd, NULL);
6202 b = PushButton (c, "Cancel", NoAlignmentChoiceCancel);
6203 SetObjectExtra (b, &nacd, NULL);
6204
6205 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
6206
6207 nacd.cancelled = FALSE;
6208 nacd.done = FALSE;
6209 Show(w);
6210 Select (w);
6211 while (!nacd.done)
6212 {
6213 ProcessExternalEvent ();
6214 Update ();
6215 }
6216 ProcessAnEvent ();
6217 no_aln_choice = GetValue (nacd.action_choice);
6218 Remove (w);
6219 if (nacd.cancelled)
6220 {
6221 return UPDATE_CANCEL;
6222 }
6223 else
6224 {
6225 return no_aln_choice;
6226 }
6227 }
6228
PrepareUpdatePtr(UpsDataPtr udp)6229 static Boolean PrepareUpdatePtr (UpsDataPtr udp)
6230 {
6231 Uint2 entityID;
6232 SeqEntryPtr oldsep, newsep;
6233 SeqIdPtr sip;
6234 Boolean islocal = FALSE;
6235 Char buf [64];
6236 SeqAlignPtr salp = NULL;
6237 Boolean revcomp = FALSE;
6238 Boolean asked_about_desc_prop = FALSE;
6239 Boolean propagate_descriptors = FALSE;
6240 SeqIdPtr id, id_next;
6241 MsgAnswer ans;
6242 Char collision_id [100];
6243
6244 if (udp->oldbsp == NULL || udp->newbsp == NULL) return FALSE;
6245 if (ISA_na (udp->oldbsp->mol) != ISA_na (udp->newbsp->mol)) {
6246 Message (MSG_OK, "Both sequences must be either nucleotides or proteins");
6247 return FALSE;
6248 }
6249
6250 entityID = ObjMgrGetEntityIDForPointer (udp->oldbsp);
6251 oldsep = GetBestTopParentForData (entityID, udp->oldbsp);
6252 entityID = ObjMgrGetEntityIDForPointer (udp->newbsp);
6253 newsep = GetBestTopParentForData (entityID, udp->newbsp);
6254 if (oldsep == NULL || newsep == NULL)
6255 return FALSE;
6256
6257 if (CONVERTPUBS_NOT_SET == udp->convertPubs)
6258 {
6259 if (Message (MSG_YN, convPubDescMssg) == ANS_YES) {
6260 ConvertPubSrcComDescsToFeats (oldsep, TRUE, FALSE, FALSE, FALSE, &asked_about_desc_prop, &propagate_descriptors, NULL);
6261 ConvertPubSrcComDescsToFeats (newsep, TRUE, FALSE, FALSE, FALSE, &asked_about_desc_prop, &propagate_descriptors, NULL);
6262 udp->convertPubs = CONVERTPUBS_YES;
6263 }
6264 else
6265 udp->convertPubs = CONVERTPUBS_NO;
6266 }
6267
6268 if (CheckForIDCollision (udp->oldbsp, udp->newbsp, &islocal)) {
6269 sprintf (collision_id, "lcl|SequinUpdateSequence%d", udp->seqsubpos);
6270 sip = SeqIdParse (collision_id);
6271 if (sip != NULL) {
6272 BioseqReplaceID (udp->newbsp, sip);
6273 sip = SeqIdFree (sip);
6274 }
6275 }
6276
6277 salp = Sqn_AlignForSequenceUpdate (udp->oldbsp, udp->newbsp, &revcomp);
6278
6279 if (salp == NULL) {
6280 if (udp->log_fp != NULL) {
6281 id = SeqIdFindBest (udp->oldbsp->id, 0);
6282 if (id != NULL)
6283 {
6284 id_next = id->next;
6285 id->next = NULL;
6286 SeqIdWrite (id, buf, PRINTID_REPORT, sizeof (buf) - 1);
6287 id->next = id_next;
6288 fprintf (udp->log_fp, "No sequence similarity for %s\n", buf);
6289 udp->data_in_log = TRUE;
6290 }
6291 }
6292 if (udp->suppress_continue_msg) {
6293 return FALSE;
6294 } else {
6295 if (udp->isSet && udp->do_update)
6296 {
6297 if (udp->no_aln_choice != UPDATE_SKIP_ALL && udp->no_aln_choice != UPDATE_REPLACE_ALL)
6298 {
6299 udp->no_aln_choice = GetNoAlignmentChoice (udp->oldbsp->id, udp->no_aln_choice);
6300 }
6301 if (udp->no_aln_choice == UPDATE_CANCEL)
6302 {
6303 return FALSE;
6304 }
6305 }
6306 else if (udp->do_update)
6307 {
6308 ans = Message (MSG_YN, "There is no alignment between the sequences. Do you wish to continue?");
6309 if (ans == ANS_YES)
6310 {
6311 udp->useGUI = TRUE;
6312 }
6313 else
6314 {
6315 return FALSE;
6316 }
6317 }
6318 }
6319 }
6320 udp->salp = salp;
6321 udp->revcomp = revcomp;
6322 udp->diffOrgs = FALSE;
6323 udp->recomb1 = -1;
6324 udp->recomb2 = -1;
6325
6326 return TRUE;
6327 }
6328
6329 static void UpdateProteinsOnNewBsp (SeqFeatPtr sfp, Pointer userdata);
6330
6331 static void
FindProtRefPtrsOnBsp(BioseqPtr bsp,ValNodePtr PNTR feat_list)6332 FindProtRefPtrsOnBsp
6333 (BioseqPtr bsp,
6334 ValNodePtr PNTR feat_list)
6335 {
6336 SeqMgrFeatContext context;
6337 SeqFeatPtr sfp;
6338 ValNodePtr vnp;
6339
6340 if (bsp == NULL || feat_list == NULL) return;
6341 sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_PROT, 0, &context);
6342 while (sfp != NULL) {
6343 if (context.left == 0 && context.right == bsp->length - 1) {
6344 vnp = ValNodeNew (*feat_list);
6345 if (vnp != NULL) {
6346 vnp->data.ptrvalue = sfp;
6347 }
6348 if (*feat_list == NULL) {
6349 *feat_list = vnp;
6350 }
6351 }
6352 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_PROT, 0, &context);
6353 }
6354 }
6355
FindProductProtRefs(BioseqPtr bsp)6356 static ValNodePtr FindProductProtRefs (BioseqPtr bsp)
6357 {
6358 SeqFeatPtr sfp;
6359 SeqMgrFeatContext context;
6360 ValNodePtr feat_list = NULL;
6361
6362 if (bsp == NULL) return NULL;
6363 sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &context);
6364 while (sfp != NULL) {
6365 FindProtRefPtrsOnBsp (BioseqFindFromSeqLoc (sfp->product), &feat_list);
6366 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &context);
6367 }
6368 return feat_list;
6369 }
6370
FindTranslExceptCDSs(BioseqPtr bsp)6371 static ValNodePtr FindTranslExceptCDSs (BioseqPtr bsp)
6372 {
6373 SeqFeatPtr sfp;
6374 SeqMgrFeatContext context;
6375 ValNodePtr feat_list = NULL;
6376 ValNodePtr vnp;
6377 Int4 cd_len;
6378
6379 if (bsp == NULL) return NULL;
6380 sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &context);
6381 while (sfp != NULL) {
6382 if (CodingRegionHasTranslExcept (sfp))
6383 {
6384 vnp = ValNodeNew(feat_list);
6385 if (feat_list == NULL)
6386 {
6387 feat_list = vnp;
6388 }
6389 if (vnp != NULL)
6390 {
6391 cd_len = SeqLocLen (sfp->location);
6392 vnp->choice = cd_len % 3;
6393 vnp->data.ptrvalue = sfp;
6394 }
6395 }
6396 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, 0, &context);
6397 }
6398 return feat_list;
6399 }
6400
GetOriginalTranslExceptLen(SeqFeatPtr sfp,ValNodePtr list)6401 static Int4 GetOriginalTranslExceptLen (SeqFeatPtr sfp, ValNodePtr list)
6402 {
6403 ValNodePtr vnp;
6404
6405 if (sfp == NULL || list == NULL) return 0;
6406 for (vnp = list; vnp != NULL; vnp = vnp->next)
6407 {
6408 if (vnp->data.ptrvalue == sfp)
6409 {
6410 return vnp->choice;
6411 }
6412 }
6413 if (CodingRegionHasTranslExcept (sfp))
6414 {
6415 return SeqLocLen (sfp->location) % 3;
6416 }
6417 return 0;
6418 }
6419
UpdateOneSequence(UpsDataPtr udp,Int2 sfbval,Boolean add_cit_subs,Boolean update_proteins)6420 static void UpdateOneSequence (
6421 UpsDataPtr udp,
6422 Int2 sfbval,
6423 Boolean add_cit_subs,
6424 Boolean update_proteins
6425 )
6426 {
6427 SeqAnnotPtr sap = NULL;
6428 Uint2 entityID;
6429 SeqEntryPtr sep;
6430 Boolean update = FALSE;
6431 Boolean feature_update = FALSE;
6432 ValNodePtr prot_feat_list = NULL;
6433
6434 if (udp != NULL)
6435 {
6436 if (GetStatus (udp->replace_all))
6437 {
6438 RemoveOldFeats (udp->oldbsp);
6439 }
6440 }
6441
6442 if (update_proteins && udp != NULL) {
6443 prot_feat_list = FindProductProtRefs (udp->oldbsp);
6444 if (udp->transl_except_list != NULL)
6445 {
6446 ValNodeFree (udp->transl_except_list);
6447 udp->transl_except_list = NULL;
6448 }
6449 udp->transl_except_list = FindTranslExceptCDSs (udp->oldbsp);
6450 }
6451
6452 if (udp != NULL && (sfbval == UPDATE_SEQUENCE_ONLY || sfbval == UPDATE_SEQUENCE_AND_FEATURES)) {
6453 switch (udp->rmcval) {
6454 case UPDATE_REPLACE :
6455 if (ReplaceSequence (udp)) {
6456 update = TRUE;
6457 }
6458 break;
6459 case UPDATE_EXTEND5 :
6460 if (NULL == udp->salp) {
6461 if (Merge5PrimeNoOverlap (udp))
6462 update = TRUE;
6463 }
6464 else
6465 {
6466 if (Merge5Prime (udp))
6467 update = TRUE;
6468 }
6469 break;
6470 case UPDATE_EXTEND3 :
6471 if (NULL == udp->salp) {
6472 if (Merge3PrimeNoOverlap (udp))
6473 update = TRUE;
6474 }
6475 else
6476 {
6477 if (Merge3Prime (udp))
6478 update = TRUE;
6479 }
6480 break;
6481 case UPDATE_PATCH :
6482 if (PatchSequence (udp)) {
6483 update = TRUE;
6484 }
6485 break;
6486 default :
6487 break;
6488 }
6489 if ( sfbval == UPDATE_SEQUENCE_AND_FEATURES) {
6490 switch (udp->rmcval) {
6491 case UPDATE_REPLACE :
6492 if (DoFeaturePropWithOffset (udp, 0, &sap, FALSE)) {
6493 update = TRUE;
6494 feature_update = TRUE;
6495 }
6496 break;
6497 case UPDATE_EXTEND5 :
6498 if (DoFeaturePropWithOffset (udp, 0, &sap, FALSE)) {
6499 update = TRUE;
6500 feature_update = TRUE;
6501 }
6502 break;
6503 case UPDATE_EXTEND3 :
6504 if (DoFeaturePropWithOffset (udp, udp->old5 - udp->new5, &sap, FALSE)) {
6505 update = TRUE;
6506 feature_update = TRUE;
6507 }
6508 break;
6509 case UPDATE_PATCH :
6510 if (DoFeaturePropWithOffset (udp, udp->old5 - udp->new5, &sap, TRUE)) {
6511 update = TRUE;
6512 feature_update = TRUE;
6513 }
6514 break;
6515 default :
6516 break;
6517 }
6518 }
6519 if (udp->rmcval == UPDATE_REPLACE && udp->revcomp && update)
6520 {
6521 ReverseComplementBioseqAndFeats (udp->oldbsp, udp->input_entityID);
6522 }
6523
6524 } else if (sfbval == UPDATE_FEATURES_ONLY && udp != NULL) {
6525 switch (udp->rmcval) {
6526 case UPDATE_REPLACE :
6527 if (DoFeaturePropThruAlign (udp, &sap)) {
6528 update = TRUE;
6529 feature_update = TRUE;
6530 }
6531 break;
6532 case UPDATE_EXTEND5 :
6533 if (DoFeaturePropThruAlign (udp, &sap)) {
6534 update = TRUE;
6535 feature_update = TRUE;
6536 }
6537 break;
6538 case UPDATE_EXTEND3 :
6539 if (DoFeaturePropThruAlign (udp, &sap)) {
6540 update = TRUE;
6541 feature_update = TRUE;
6542 }
6543 break;
6544 case UPDATE_PATCH :
6545 if (DoFeaturePropThruAlign (udp, &sap)) {
6546 update = TRUE;
6547 feature_update = TRUE;
6548 }
6549 break;
6550 default :
6551 break;
6552 }
6553 }
6554 if (update) {
6555 entityID = ObjMgrGetEntityIDForPointer (udp->oldbsp);
6556 if (add_cit_subs
6557 && (feature_update || StringCmp (udp->seq1, udp->seq2) != 0))
6558 {
6559 AddCitSubToUpdatedSequence ( udp->oldbsp, entityID, kSubmitterUpdateText);
6560 }
6561 if (update_proteins)
6562 {
6563 SeqMgrClearFeatureIndexes (entityID, udp->oldbsp);
6564 SeqMgrIndexFeatures (entityID, NULL);
6565 sep = GetBestTopParentForData (entityID, udp->oldbsp);
6566 udp->truncate_proteins = GetStatus (udp->truncate_proteins_btn);
6567 udp->extend_proteins5 = GetStatus (udp->extend_proteins5_btn);
6568 udp->extend_proteins3 = GetStatus (udp->extend_proteins3_btn);
6569 udp->correct_cds_genes = GetStatus (udp->correct_cds_genes_btn);
6570 VisitFeaturesInSep (sep, udp, UpdateProteinsOnNewBsp);
6571 FixProtRefPtrs (prot_feat_list);
6572 }
6573 if (! udp->suppress_instant_refresh) {
6574 ObjMgrSetDirtyFlag (entityID, TRUE);
6575 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
6576 }
6577 }
6578
6579 if (udp == NULL) return;
6580 if (GetStatus (udp->update_quality_scores_btn) && udp->rmcval == UPDATE_REPLACE
6581 && (sfbval == UPDATE_SEQUENCE_ONLY || sfbval == UPDATE_SEQUENCE_AND_FEATURES))
6582 {
6583 ReplaceQualityScores (udp->oldbsp, udp->newbsp, udp->log_fp, &(udp->data_in_log));
6584 }
6585 else if (sfbval != UPDATE_FEATURES_ONLY)
6586 {
6587 RemoveQualityScores (udp->oldbsp, udp->log_fp, &(udp->data_in_log));
6588 }
6589
6590 ValNodeFree (prot_feat_list);
6591 ValNodeFree (udp->transl_except_list);
6592 udp->transl_except_list = NULL;
6593 if (sfbval == UPDATE_FEATURES_ONLY || sfbval == UPDATE_SEQUENCE_AND_FEATURES) {
6594 if (update) {
6595 entityID = ObjMgrGetEntityIDForPointer (udp->oldbsp);
6596 sep = GetTopSeqEntryForEntityID (entityID);
6597 /* need to set scope to make sure we mark the right bioseq for deletion */
6598 SeqEntrySetScope (sep);
6599 /* resolve features unless the policy was to remove all the old ones */
6600 if (!GetStatus (udp->replace_all))
6601 {
6602 ResolveDuplicateFeats (udp, udp->oldbsp, sap);
6603 }
6604 SeqEntrySetScope (NULL);
6605 DeleteMarkedObjects (entityID, 0, NULL);
6606 SeqMgrClearFeatureIndexes (entityID, NULL);
6607 ObjMgrSetDirtyFlag (entityID, TRUE);
6608 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
6609 }
6610 }
6611 }
6612
UpdateProteinsOnNewBsp(SeqFeatPtr sfp,Pointer userdata)6613 static void UpdateProteinsOnNewBsp (SeqFeatPtr sfp, Pointer userdata)
6614 {
6615 UpsDataPtr udp_orig;
6616 SeqLocPtr new_product;
6617 Boolean data_in_log;
6618 Int4 transl_except_len = 0;
6619 Boolean fix_products = TRUE;
6620 BioseqPtr protBsp = NULL;
6621 SeqAlignPtr salp = NULL;
6622 BioseqPtr newbsp = NULL;
6623 Boolean rval;
6624
6625 if (sfp == NULL || sfp->idx.subtype != FEATDEF_CDS || userdata == NULL)
6626 {
6627 return;
6628 }
6629
6630 if (sfp->idx.deleteme)
6631 {
6632 return;
6633 }
6634
6635 protBsp = BioseqFindFromSeqLoc (sfp->product);
6636 if (protBsp == NULL)
6637 {
6638 return;
6639 }
6640 udp_orig = (UpsDataPtr) userdata;
6641
6642 data_in_log = FALSE;
6643 transl_except_len = GetOriginalTranslExceptLen (sfp, udp_orig->transl_except_list);
6644 rval = PrepareUpdateAlignmentForProtein (sfp,
6645 protBsp,
6646 udp_orig->input_entityID,
6647 udp_orig->log_fp,
6648 udp_orig->truncate_proteins,
6649 udp_orig->extend_proteins5,
6650 udp_orig->extend_proteins3,
6651 udp_orig->correct_cds_genes,
6652 transl_except_len,
6653 &data_in_log,
6654 &salp,
6655 &newbsp);
6656 if (data_in_log) {
6657 udp_orig->data_in_log = TRUE;
6658 }
6659 if (!rval) return;
6660
6661 if (protBsp->idx.deleteme)
6662 {
6663 fix_products = FALSE;
6664 }
6665
6666 ReplaceOneSequence (salp, protBsp, newbsp);
6667
6668 if (fix_products)
6669 {
6670 if (sfp->product->choice != SEQLOC_WHOLE) {
6671 new_product = SeqLocWholeNew (protBsp);
6672 if (new_product == NULL) return;
6673 SeqLocFree (sfp->product);
6674 sfp->product = new_product;
6675 }
6676 newbsp = BioseqFree (newbsp);
6677 }
6678 }
6679
6680
6681 /* This section of code is used to warn the user when an alignment update
6682 * will affect the area inside a variation or the area immediately to the
6683 * left or right of a variation.
6684 */
VariationAlignmentCallback(SeqFeatPtr sfp,Pointer userdata)6685 static void VariationAlignmentCallback (SeqFeatPtr sfp, Pointer userdata)
6686 {
6687 CharPtr buf, cp;
6688 UpsDataPtr udp;
6689 Boolean change_found = FALSE;
6690
6691 if (sfp == NULL || userdata == NULL || sfp->idx.subtype != FEATDEF_variation)
6692 {
6693 return;
6694 }
6695 udp = (UpsDataPtr) userdata;
6696 if (udp->salp == NULL)
6697 {
6698 return;
6699 }
6700
6701 buf = FeatureLocationAlignment (sfp, udp->salp, 1, 2);
6702 if (buf == NULL)
6703 {
6704 return;
6705 }
6706 cp = buf;
6707 /* skip over "Old :" */
6708 if (StringLen (cp) > 8)
6709 {
6710 cp += 8;
6711 }
6712 while (*cp != 0 && *cp != '\n' && !change_found)
6713 {
6714 if (*cp == '-')
6715 {
6716 change_found = TRUE;
6717 }
6718 cp++;
6719 }
6720 if (*cp == '\n')
6721 {
6722 cp++;
6723 }
6724 /* skip over "New :" */
6725 if (StringLen (cp) > 8)
6726 {
6727 cp += 8;
6728 }
6729 while (*cp != 0 && *cp != '\n' && !change_found)
6730 {
6731 if (*cp != '.')
6732 {
6733 change_found = TRUE;
6734 }
6735 cp++;
6736 }
6737 if (change_found)
6738 {
6739 ValNodeAddPointer (&udp->affected_variation_features, 0, sfp);
6740 }
6741 buf = MemFree (buf);
6742 }
6743
PrepareVariationFeatureLogEntry(SeqFeatPtr sfp,SeqAlignPtr salp)6744 static CharPtr PrepareVariationFeatureLogEntry (SeqFeatPtr sfp, SeqAlignPtr salp)
6745 {
6746 CharPtr loc_buf, feat_buf, total_buf;
6747 Int4 buf_len;
6748
6749 if (sfp == NULL || salp == NULL)
6750 {
6751 return NULL;
6752 }
6753
6754 loc_buf = SeqLocPrint (sfp->location);
6755 feat_buf = FeatureLocationAlignment (sfp, salp, 1, 2);
6756
6757 buf_len = StringLen (sfp->comment) + StringLen (loc_buf) + StringLen (feat_buf) + 3;
6758 total_buf = (CharPtr) MemNew (buf_len * sizeof (Char));
6759 if (total_buf != NULL)
6760 {
6761 total_buf [0] = 0;
6762 /* add feature name */
6763 if (!StringHasNoText (sfp->comment))
6764 {
6765 StringCpy (total_buf, sfp->comment);
6766 StringCat (total_buf, "\n");
6767 }
6768 /* add feature location */
6769 if (!StringHasNoText (loc_buf))
6770 {
6771 StringCat (total_buf, loc_buf);
6772 StringCat (total_buf, "\n");
6773 }
6774 /* add alignment picture */
6775 if (!StringHasNoText (feat_buf))
6776 {
6777 StringCat (total_buf, feat_buf);
6778 }
6779 loc_buf = MemFree (loc_buf);
6780 feat_buf = MemFree (feat_buf);
6781 }
6782 return total_buf;
6783 }
6784
6785 static Int4
VariationFeatureChangesOk(ValNodePtr variation_feature_list,SeqAlignPtr salp,Boolean allow_skip)6786 VariationFeatureChangesOk
6787 (ValNodePtr variation_feature_list,
6788 SeqAlignPtr salp,
6789 Boolean allow_skip)
6790 {
6791 WindoW w;
6792 GrouP h, c;
6793 ButtoN b;
6794 DoC doc;
6795 ValNodePtr vnp;
6796 SeqFeatPtr sfp;
6797 CharPtr total_buf;
6798 ModalAcceptCancelData acd;
6799 CharPtr str_format = "%d variation features are affected by this update.";
6800
6801 if (variation_feature_list == NULL || salp == NULL)
6802 {
6803 return TRUE;
6804 }
6805
6806 w = MovableModalWindow (-20, -13, -10, -10, "Affected Variation Sequences", NULL);
6807 h = HiddenGroup(w, -1, 0, NULL);
6808 SetGroupSpacing (h, 10, 10);
6809
6810 doc = DocumentPanel (h, stdCharWidth * 40, stdLineHeight * 12);
6811 SetDocAutoAdjust (doc, TRUE);
6812
6813 total_buf = MemNew (StringLen (str_format) + 15);
6814 if (total_buf != NULL)
6815 {
6816 sprintf (total_buf, str_format, ValNodeLen (variation_feature_list));
6817 AppendText (doc, total_buf, NULL, NULL, programFont);
6818 total_buf = MemFree (total_buf);
6819 }
6820
6821 for (vnp = variation_feature_list; vnp != NULL; vnp = vnp->next)
6822 {
6823 sfp = (SeqFeatPtr) vnp->data.ptrvalue;
6824 total_buf = PrepareVariationFeatureLogEntry (sfp, salp);
6825 if (!StringHasNoText (total_buf))
6826 {
6827 AppendText (doc, total_buf, NULL, NULL, programFont);
6828 }
6829 MemFree (total_buf);
6830 }
6831 UpdateDocument (doc, 0, 0);
6832
6833 c = HiddenGroup (h, 3, 0, NULL);
6834 b = PushButton (c, "Proceed", ModalAcceptButton);
6835 SetObjectExtra (b, &acd, NULL);
6836 if (allow_skip)
6837 {
6838 b = PushButton (c, "Skip Update", ModalThirdOptionButton);
6839 SetObjectExtra (b, &acd, NULL);
6840 }
6841
6842 b = PushButton (c, "Cancel Update", ModalCancelButton);
6843 SetObjectExtra (b, &acd, NULL);
6844
6845
6846 AlignObjects (ALIGN_CENTER, (HANDLE) doc,
6847 (HANDLE) c,
6848 NULL);
6849
6850 Show (w);
6851 Select (w);
6852
6853 acd.cancelled = FALSE;
6854 acd.third_option = FALSE;
6855 acd.accepted = FALSE;
6856 while (!acd.accepted && ! acd.cancelled && !acd.third_option)
6857 {
6858 ProcessExternalEvent ();
6859 Update ();
6860 }
6861 ProcessAnEvent ();
6862 Remove (w);
6863
6864 if (acd.accepted)
6865 {
6866 return 1;
6867 }
6868 else if (acd.cancelled)
6869 {
6870 return 2;
6871 }
6872 else
6873 {
6874 return 3;
6875 }
6876 }
6877
6878 static void
AddVariationFeaturesToLog(FILE * fp,BoolPtr data_in_log,ValNodePtr variation_feature_list,SeqAlignPtr salp)6879 AddVariationFeaturesToLog
6880 (FILE *fp,
6881 BoolPtr data_in_log,
6882 ValNodePtr variation_feature_list,
6883 SeqAlignPtr salp)
6884 {
6885 ValNodePtr vnp;
6886 CharPtr total_buf;
6887 SeqFeatPtr sfp;
6888
6889 if (fp == NULL || variation_feature_list == NULL)
6890 {
6891 return;
6892 }
6893
6894 for (vnp = variation_feature_list; vnp != NULL; vnp = vnp->next)
6895 {
6896 sfp = (SeqFeatPtr) vnp->data.ptrvalue;
6897 total_buf = PrepareVariationFeatureLogEntry (sfp, salp);
6898 if (!StringHasNoText (total_buf))
6899 {
6900 fprintf (fp, "%s", total_buf);
6901 if (data_in_log != NULL)
6902 {
6903 *data_in_log = TRUE;
6904 }
6905 }
6906 MemFree (total_buf);
6907 }
6908
6909 }
6910
AcceptRMCOrExtend(ButtoN b)6911 static void AcceptRMCOrExtend (ButtoN b)
6912 {
6913 UpsDataPtr udp;
6914 Int2 sfbval;
6915 Boolean log_is_local;
6916 Boolean update_proteins = FALSE;
6917 Uint2 entityID;
6918
6919 udp = (UpsDataPtr) GetObjectExtra (b);
6920 if (udp == NULL) return;
6921 SafeHide (udp->form);
6922
6923 sfbval = GetValue (udp->sfb);
6924 udp->rmcval = GetValue (udp->rmc);
6925
6926 if (udp->log_fp == NULL) {
6927 OpenSequenceUpdateLog (udp);
6928 if (udp->log_fp == NULL) return;
6929 log_is_local = TRUE;
6930 } else {
6931 log_is_local = FALSE;
6932 }
6933 WatchCursor ();
6934 Update ();
6935
6936 if (udp->do_update)
6937 {
6938 udp->affected_variation_features = ValNodeFree (udp->affected_variation_features);
6939 VisitFeaturesOnBsp (udp->oldbsp, udp, VariationAlignmentCallback);
6940 if (1 == VariationFeatureChangesOk (udp->affected_variation_features, udp->salp, FALSE))
6941 {
6942 if (udp->update_proteins != NULL
6943 && Enabled (udp->update_proteins)
6944 && GetStatus (udp->update_proteins))
6945 {
6946 update_proteins = TRUE;
6947 }
6948 AddVariationFeaturesToLog (udp->log_fp, &(udp->data_in_log),
6949 udp->affected_variation_features, udp->salp);
6950 UpdateOneSequence (udp, sfbval,
6951 GetStatus (udp->add_cit_subs),
6952 update_proteins);
6953 }
6954 udp->affected_variation_features = ValNodeFree (udp->affected_variation_features);
6955 }
6956 else
6957 {
6958 if (ExtendOneSequence (udp))
6959 {
6960 entityID = ObjMgrGetEntityIDForPointer (udp->oldbsp);
6961 ObjMgrSetDirtyFlag (entityID, TRUE);
6962 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
6963 }
6964 }
6965
6966 Remove (udp->form);
6967 if (log_is_local) {
6968 CloseOutSequenceUpdateLog (udp);
6969 }
6970 ArrowCursor ();
6971 Update();
6972 }
6973
DoAcceptRMCOrExtendSet(UpsDataPtr udp)6974 static void DoAcceptRMCOrExtendSet (UpsDataPtr udp)
6975 {
6976 Int2 sfbval = 0;
6977 Boolean log_is_local = FALSE;
6978 Boolean update_proteins = FALSE;
6979 Boolean do_update = TRUE;
6980 Boolean old_useGUI;
6981 Char acc_str [256];
6982 SeqIdPtr sip, sip_next;
6983 Int2 prior_rmcval;
6984 Int4 variation_action = 1;
6985
6986 if (udp == NULL) return;
6987
6988 SafeHide (udp->form);
6989 old_useGUI = udp->useGUI;
6990
6991 prior_rmcval = udp->rmcval;
6992 if (udp->do_update)
6993 {
6994 if (udp->salp == NULL
6995 && (udp->no_aln_choice == UPDATE_REPLACE_THIS
6996 || udp->no_aln_choice == UPDATE_REPLACE_ALL))
6997 {
6998 sfbval = UPDATE_SEQUENCE_ONLY;
6999 udp->rmcval = UPDATE_REPLACE;
7000 udp->useGUI = FALSE;
7001 }
7002 else if (udp->salp == NULL
7003 && (udp->no_aln_choice == UPDATE_SKIP_THIS
7004 || udp->no_aln_choice == UPDATE_SKIP_ALL))
7005 {
7006 do_update = FALSE;
7007 }
7008 else
7009 {
7010 sfbval = GetValue (udp->sfb);
7011 udp->rmcval = GetValue (udp->rmc);
7012 prior_rmcval = udp->rmcval;
7013 }
7014 }
7015 else
7016 {
7017 udp->rmcval = GetValue (udp->rmc);
7018 prior_rmcval = udp->rmcval;
7019 }
7020
7021 if (udp->log_fp == NULL)
7022 {
7023 OpenSequenceUpdateLog (udp);
7024 if (udp->log_fp == NULL) return;
7025 log_is_local = TRUE;
7026 }
7027 if (do_update && udp->do_update)
7028 {
7029 udp->affected_variation_features = ValNodeFree (udp->affected_variation_features);
7030 VisitFeaturesOnBsp (udp->oldbsp, udp, VariationAlignmentCallback);
7031 variation_action = VariationFeatureChangesOk (udp->affected_variation_features, udp->salp, TRUE);
7032 if (1 != variation_action)
7033 {
7034 do_update = FALSE;
7035 }
7036
7037
7038 }
7039
7040 if (do_update)
7041 {
7042 if (udp->do_update)
7043 {
7044 if (udp->update_proteins != NULL
7045 && Enabled (udp->update_proteins)
7046 && GetStatus (udp->update_proteins))
7047 {
7048 update_proteins = TRUE;
7049 }
7050
7051 AddVariationFeaturesToLog (udp->log_fp, &(udp->data_in_log),
7052 udp->affected_variation_features, udp->salp);
7053 UpdateOneSequence (udp, sfbval, GetStatus (udp->add_cit_subs),
7054 update_proteins);
7055 }
7056 else
7057 {
7058 ExtendOneSequence (udp);
7059 }
7060
7061 Remove (udp->form);
7062 }
7063 else
7064 {
7065 sip = SeqIdFindBest (udp->oldbsp->id, 0);
7066 if (sip != NULL)
7067 {
7068 sip_next = sip->next;
7069 SeqIdWrite (sip, acc_str, PRINTID_REPORT, sizeof (acc_str));
7070 fprintf (udp->log_fp, "Skipped update for %s\n", acc_str);
7071 udp->data_in_log = TRUE;
7072 sip->next = sip_next;
7073 }
7074 }
7075 udp->affected_variation_features = ValNodeFree (udp->affected_variation_features);
7076
7077 if (log_is_local)
7078 {
7079 CloseOutSequenceUpdateLog (udp);
7080 }
7081
7082 if (2 == variation_action)
7083 {
7084 FileClose (udp->fp);
7085 CloseOutSequenceUpdateLog (udp);
7086 }
7087
7088 udp->useGUI = old_useGUI;
7089 udp->rmcval = prior_rmcval;
7090 /* if we are updating a set from a SeqSub, we don't want to free the SeqSub yet */
7091 if (udp->seqsubsep != NULL)
7092 {
7093 udp->newbsp = NULL;
7094 }
7095 FreeUdpFields (udp);
7096 }
7097
7098 /*------------------------------------------------------------------*/
7099 /* */
7100 /* AcceptRMCAll () -- Breaks out of the GUI interface and updates */
7101 /* all remaining sequences in the file without */
7102 /* user intervention. */
7103 /* */
7104 /*------------------------------------------------------------------*/
7105
AcceptRMCOrExtendAll(ButtoN b)7106 static void AcceptRMCOrExtendAll (ButtoN b)
7107
7108 {
7109 UpsDataPtr udp;
7110 Int2 state;
7111 Int4 count;
7112 Char msgStr[256];
7113
7114 /* Get current data */
7115
7116 udp = (UpsDataPtr) GetObjectExtra (b);
7117 if (udp == NULL)
7118 return;
7119
7120 /* Process the current sequence */
7121
7122 WatchCursor ();
7123 udp->useGUI = FALSE;
7124
7125 if (udp->log_fp == NULL) {
7126 OpenSequenceUpdateLog (udp);
7127 if (udp->log_fp == NULL) return;
7128 }
7129
7130
7131 udp->rmcval = GetValue (udp->rmc);
7132
7133 DoAcceptRMCOrExtendSet (udp);
7134
7135 /* Loop through the file, processing all others */
7136
7137 state = FASTA_READ_OK;
7138 count = 0;
7139
7140 while (FASTA_READ_OK == state) {
7141 count++;
7142 WatchCursor ();
7143 state = UpdateNextBioseqInFastaSet (udp);
7144 if (udp->useGUI)
7145 return;
7146 }
7147
7148 CloseOutSequenceUpdateLog (udp);
7149 ArrowCursor ();
7150
7151 /* If there was an error, report it, otherwise */
7152 /* print a status message. */
7153
7154 if (FASTA_READ_ERROR == state) {
7155 sprintf (msgStr, "Encountered error while updating. Only %d sequences "
7156 "were updated.", count);
7157 Message (MSG_OK, msgStr);
7158 }
7159 else {
7160 sprintf (msgStr, "Successfully processed %d sequences from file (not"
7161 " counting any updated before hitting 'Accept All').", count);
7162 Message (MSG_OK, msgStr);
7163 }
7164 }
7165
7166
AcceptRMCOrExtendSet(ButtoN b)7167 static void AcceptRMCOrExtendSet (ButtoN b)
7168
7169 {
7170 UpsDataPtr udp;
7171
7172 udp = (UpsDataPtr) GetObjectExtra (b);
7173 if (udp == NULL)
7174 return;
7175
7176 if (udp->log_fp == NULL) {
7177 OpenSequenceUpdateLog (udp);
7178 if (udp->log_fp == NULL) return;
7179 }
7180
7181 udp->rmcval = GetValue (udp->rmc);
7182
7183 DoAcceptRMCOrExtendSet (udp);
7184
7185 UpdateNextBioseqInFastaSet (udp);
7186 }
7187
SetProteinOptionsEnable(UpsDataPtr udp)7188 static void SetProteinOptionsEnable (UpsDataPtr udp)
7189 {
7190 if (udp == NULL || udp->update_proteins == NULL) return;
7191
7192 if (Enabled (udp->update_proteins) && GetStatus (udp->update_proteins))
7193 {
7194 Enable (udp->truncate_proteins_btn);
7195 Enable (udp->extend_proteins3_btn);
7196 Enable (udp->extend_proteins5_btn);
7197 Enable (udp->correct_cds_genes_btn);
7198 }
7199 else
7200 {
7201 Disable (udp->truncate_proteins_btn);
7202 Disable (udp->extend_proteins3_btn);
7203 Disable (udp->extend_proteins5_btn);
7204 Disable (udp->correct_cds_genes_btn);
7205 }
7206 }
7207
SetStatusUpdateAcceptBtns(UpsDataPtr udp,Boolean status)7208 static void SetStatusUpdateAcceptBtns (UpsDataPtr udp, Boolean status)
7209 {
7210 if (udp == NULL) return;
7211
7212 if (status)
7213 {
7214 SafeEnable (udp->accept);
7215 SafeEnable (udp->acceptAll);
7216 }
7217 else
7218 {
7219 SafeDisable (udp->accept);
7220 SafeDisable (udp->acceptAll);
7221 }
7222 }
7223
UpdateAccept(GrouP g)7224 static void UpdateAccept (GrouP g)
7225
7226 {
7227 Int2 rmcval, sfbval;
7228 UpsDataPtr udp;
7229 Int2 nobmval = UPDATE_FEAT_DUP_NOT_SET;
7230
7231 udp = (UpsDataPtr) GetObjectExtra (g);
7232 if (udp == NULL) return;
7233
7234 rmcval = GetValue (udp->rmc);
7235 sfbval = GetValue (udp->sfb);
7236
7237 if (rmcval == UPDATE_REPLACE)
7238 {
7239 sfbval = GetValue (udp->sfb);
7240 if (sfbval == UPDATE_SEQUENCE_ONLY || sfbval == UPDATE_SEQUENCE_AND_FEATURES)
7241 {
7242 Enable (udp->update_quality_scores_btn);
7243 }
7244 else
7245 {
7246 Disable (udp->update_quality_scores_btn);
7247 }
7248 }
7249 else
7250 {
7251 Disable (udp->update_quality_scores_btn);
7252 }
7253
7254 if (sfbval == UPDATE_FEATURES_ONLY || sfbval == UPDATE_SEQUENCE_AND_FEATURES)
7255 {
7256 if (!GetStatus (udp->replace_all))
7257 {
7258 nobmval = GetValue (udp->nobm);
7259 }
7260 }
7261
7262 /* set enables for protein updates */
7263 if (sfbval == UPDATE_SEQUENCE_ONLY
7264 || (sfbval == UPDATE_SEQUENCE_AND_FEATURES
7265 && (nobmval == UPDATE_FEAT_DUP_USE_OLD || nobmval == UPDATE_FEAT_DUP_USE_BOTH)))
7266 {
7267 SafeEnable (udp->update_proteins);
7268 }
7269 else
7270 {
7271 SafeDisable (udp->update_proteins);
7272 }
7273 SetProteinOptionsEnable (udp);
7274
7275 if (rmcval == UPDATE_CHOICE_NOT_SET) {
7276 SetStatusUpdateAcceptBtns (udp, FALSE);
7277 return;
7278 }
7279 if (! udp->do_update) {
7280 SetStatusUpdateAcceptBtns (udp, TRUE);
7281 return;
7282 }
7283
7284 if (sfbval == UPDATE_CHOICE_NOT_SET || sfbval == UPDATE_SEQUENCE_ONLY || udp->diffOrgs) {
7285 SafeDisable (udp->keepProteinIDs);
7286 if (sfbval == UPDATE_CHOICE_NOT_SET || sfbval == UPDATE_SEQUENCE_ONLY) {
7287 SafeDisable (udp->nobm);
7288 SafeDisable (udp->replace_all);
7289 } else {
7290 SafeEnable (udp->replace_all);
7291 if (GetStatus (udp->replace_all))
7292 {
7293 SafeDisable (udp->nobm);
7294 }
7295 else
7296 {
7297 SafeEnable (udp->nobm);
7298 }
7299 }
7300 } else if (sfbval == UPDATE_FEATURES_ONLY || sfbval == UPDATE_SEQUENCE_AND_FEATURES) {
7301 SafeEnable (udp->keepProteinIDs);
7302 SafeEnable (udp->replace_all);
7303 if (GetStatus (udp->replace_all))
7304 {
7305 SafeDisable (udp->nobm);
7306 }
7307 else
7308 {
7309 SafeEnable (udp->nobm);
7310 }
7311 }
7312 if (sfbval == UPDATE_CHOICE_NOT_SET) {
7313 SetStatusUpdateAcceptBtns (udp, FALSE);
7314 return;
7315 }
7316 if (sfbval == UPDATE_FEATURES_ONLY || sfbval == UPDATE_SEQUENCE_AND_FEATURES) {
7317 if (!GetStatus (udp->replace_all) && nobmval == UPDATE_FEAT_DUP_NOT_SET)
7318 {
7319 SetStatusUpdateAcceptBtns (udp, FALSE);
7320 return;
7321 }
7322 }
7323
7324 SetStatusUpdateAcceptBtns (udp, TRUE);
7325 }
7326
UpdateButtons(GrouP g)7327 static void UpdateButtons (GrouP g)
7328 {
7329 UpsDataPtr udp;
7330 Int2 rmcval;
7331 Uint2 entityID;
7332 SeqFeatPtr sfp;
7333 SeqMgrFeatContext fcontext;
7334
7335 udp = (UpsDataPtr) GetObjectExtra (g);
7336 if (udp == NULL) return;
7337
7338 rmcval = GetValue (udp->rmc);
7339
7340 if (udp->new5 <= udp->old5 && udp->new3 <= udp->old3)
7341 {
7342 if (rmcval == UPDATE_PATCH)
7343 {
7344 /* If patch sequence matches, must be feature propagation only */
7345
7346 if (StringNICmp (udp->seq1 + udp->old5 - udp->new5,
7347 udp->seq2,
7348 StringLen (udp->seq2)) == 0) {
7349 SetValue (udp->sfb, UPDATE_FEATURES_ONLY);
7350 Disable (udp->sfb);
7351 }
7352 }
7353 else if (rmcval == UPDATE_REPLACE)
7354 {
7355 /* If no features, must be sequence update only */
7356
7357 entityID = ObjMgrGetEntityIDForPointer (udp->newbsp);
7358 if (! SeqMgrFeaturesAreIndexed (entityID))
7359 SeqMgrIndexFeatures (entityID, NULL);
7360
7361 sfp = SeqMgrGetNextFeature (udp->newbsp, NULL, 0, 0, &fcontext);
7362 if (sfp == NULL)
7363 {
7364 SetValue (udp->sfb, UPDATE_SEQUENCE_ONLY);
7365 Disable (udp->sfb);
7366 Disable (udp->replace_all);
7367 Disable (udp->nobm);
7368 }
7369 else if (!indexerVersion &&
7370 (udp->newbsp->repr != Seq_repr_raw || udp->oldbsp->repr != Seq_repr_raw))
7371 {
7372 SetValue (udp->sfb, UPDATE_FEATURES_ONLY);
7373 Disable (udp->sfb);
7374 }
7375 else
7376 {
7377 Enable (udp->sfb);
7378 }
7379 }
7380 }
7381 UpdateAccept (g);
7382 }
7383
DrawAlignBlock(SegmenT pict,Int4 top,Int4 bottom,Int4 labelpt,Int2 labelaln,Int4 len5,Int4 lena,Int4 len3,Int4 aln_length)7384 static void DrawAlignBlock (
7385 SegmenT pict,
7386 Int4 top,
7387 Int4 bottom,
7388 Int4 labelpt,
7389 Int2 labelaln,
7390 Int4 len5,
7391 Int4 lena,
7392 Int4 len3,
7393 Int4 aln_length
7394 )
7395
7396 {
7397 Char str [96];
7398
7399 if (len5 > 0) {
7400 AddRectangle (pict, -len5, top, 0, bottom, NO_ARROW, FALSE, 0);
7401 }
7402 sprintf (str, "%ld", (long) len5);
7403 AddLabel (pict, -len5, (top + bottom) / 2, str, SMALL_TEXT, 5, MIDDLE_LEFT, 0);
7404
7405 if (len3 > 0) {
7406 AddRectangle (pict, aln_length, top, aln_length + len3, bottom, NO_ARROW, FALSE, 0);
7407 }
7408 sprintf (str, "%ld", (long) len3);
7409 AddLabel (pict, aln_length + len3, (top + bottom) / 2, str, SMALL_TEXT, 5, MIDDLE_RIGHT, 0);
7410
7411 AddRectangle (pict, 0, top, aln_length, bottom, NO_ARROW, TRUE, 0);
7412 sprintf (str, "%ld", (long) lena);
7413 AddLabel (pict, aln_length / 2, labelpt, str, SMALL_TEXT, 5, labelaln, 0);
7414 }
7415
MakeAlignPicture(UpsDataPtr udp,CharPtr strid1,CharPtr strid2,SeqAlignPtr sap)7416 static SegmenT MakeAlignPicture (
7417 UpsDataPtr udp,
7418 CharPtr strid1,
7419 CharPtr strid2,
7420 SeqAlignPtr sap
7421 )
7422
7423 {
7424 SegmenT pict;
7425 Char str [96];
7426 Int4 top, bottom;
7427
7428 pict = CreatePicture ();
7429 if (sap == NULL) return pict;
7430
7431 top = 0;
7432 bottom = top - 10;
7433
7434 DrawAlignBlock (pict, top, bottom, bottom, LOWER_CENTER, udp->old5, udp->olda, udp->old3, udp->aln_length);
7435
7436 /*
7437 AddLabel (pict, (udp->stopmax - udp->startmax) / 2, bottom - 20, strid1, SMALL_TEXT, 5, LOWER_CENTER, 0);
7438 */
7439
7440
7441 sprintf (str, "%ld", (long) udp->aln_length);
7442 AddLabel (pict, udp->aln_length / 2, 10, str, SMALL_TEXT, 5, MIDDLE_CENTER, 0);
7443
7444
7445 top = 30;
7446 bottom = top - 10;
7447
7448 DrawAlignBlock (pict, top, bottom, top, UPPER_CENTER, udp->new5, udp->newa, udp->new3, udp->aln_length);
7449
7450 /*
7451 AddLabel (pict, (udp->stopmax - udp->startmax) / 2, top + 20, strid2, SMALL_TEXT, 5, UPPER_CENTER, 0);
7452 */
7453
7454 return pict;
7455 }
7456
DrawAlignDiffs(UpsDataPtr udp,SegmenT pict,Int4 top,Int4 bottom,SeqAlignPtr sap)7457 static void DrawAlignDiffs (
7458 UpsDataPtr udp,
7459 SegmenT pict,
7460 Int4 top,
7461 Int4 bottom,
7462 SeqAlignPtr sap
7463 )
7464
7465 {
7466 AlnMsg2Ptr amp1, amp2;
7467 SegmenT seg;
7468 Int4 len1, len2, i;
7469 Int4 seg_i, seg_n, seg_start, seg_stop;
7470
7471 if (udp->seq1 == NULL || udp->seq2 == NULL) return;
7472 len1 = StringLen (udp->seq1);
7473 len2 = StringLen (udp->seq2);
7474
7475 seg = CreateSegment (pict, 0, 0);
7476 AddAttribute (seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
7477
7478 seg_n = AlnMgr2GetNumSegs(sap);
7479 for (seg_i = 1; seg_i<=seg_n; seg_i++) {
7480 AlnMgr2GetNthSegmentRange(sap, seg_i, &seg_start, &seg_stop);
7481
7482 amp1 = AlnMsgNew2 ();
7483 amp2 = AlnMsgNew2 ();
7484 if (amp1 == NULL || amp2 == NULL) return;
7485
7486 amp1->from_aln = seg_start;
7487 amp1->to_aln = seg_stop;
7488 amp1->row_num = 1;
7489
7490 amp2->from_aln = seg_start;
7491 amp2->to_aln = seg_stop;
7492 amp2->row_num = 2;
7493
7494 AlnMgr2GetNextAlnBit (sap, amp1);
7495 AlnMgr2GetNextAlnBit (sap, amp2);
7496
7497 if (amp1->to_row - amp1->from_row == amp2->to_row - amp2->from_row &&
7498 amp1->type == AM_SEQ && amp2->type == AM_SEQ) {
7499 for (i=0; i<seg_stop-seg_start+1; i++) {
7500 if (udp->seq1[amp1->from_row+i] != udp->seq2[amp2->from_row+i]) {
7501
7502 /* record for accurate scrolling to text view */
7503 ValNodeAddInt (&(udp->mismatches), 0, i);
7504
7505 AddLine (seg, seg_start+i, top, seg_start+i, bottom, FALSE, 0);
7506 }
7507 }
7508 }
7509
7510 AlnMsgFree2 (amp1);
7511 AlnMsgFree2 (amp2);
7512 }
7513 }
7514
DrawAlignBits(UpsDataPtr udp,SegmenT pict,Int4 top,Int4 bottom,Int4 row,Int4 pos1,Int4 pos2,SeqAlignPtr sap)7515 static void DrawAlignBits (
7516 UpsDataPtr udp,
7517 SegmenT pict,
7518 Int4 top,
7519 Int4 bottom,
7520 Int4 row,
7521 Int4 pos1,
7522 Int4 pos2,
7523 SeqAlignPtr sap
7524 )
7525
7526 {
7527 AlnMsg2Ptr amp;
7528 Int4 len, start, stop, from, to;
7529 Char str [96];
7530 Boolean wasgap;
7531
7532 amp = AlnMsgNew2 ();
7533 if (amp == NULL) return;
7534
7535 amp->from_aln = 0;
7536 amp->to_aln = -1;
7537 amp->row_num = row;
7538
7539 start = 0;
7540 stop = 0;
7541 from = 0;
7542 to = 0;
7543 wasgap = FALSE;
7544
7545 while (AlnMgr2GetNextAlnBit (sap, amp)) {
7546 len = amp->to_row - amp->from_row + 1;
7547 stop = start + len;
7548 if (amp->type == AM_GAP) {
7549 if (wasgap) {
7550 to = stop;
7551 } else {
7552 AddRectangle (pict, from, top, to, bottom, NO_ARROW, FALSE, 0);
7553 wasgap = TRUE;
7554 from = start;
7555 to = stop;
7556 }
7557 } else {
7558 if (wasgap) {
7559
7560 /* record for accurate scrolling to text view */
7561 ValNodeAddInt (&(udp->indels), 0, from);
7562
7563 AddLine (pict, from, (top + bottom) / 2, to, (top + bottom) / 2, FALSE, 0);
7564 wasgap = FALSE;
7565 from = start;
7566 to = stop;
7567 } else {
7568 to = stop;
7569 }
7570 }
7571 start += len;
7572 }
7573
7574 if (to > from) {
7575 if (wasgap) {
7576
7577 /* record for accurate scrolling to text view */
7578 ValNodeAddInt (&(udp->indels), 0, from);
7579
7580 AddLine (pict, from, (top + bottom) / 2, to, (top + bottom) / 2, FALSE, 0);
7581 } else {
7582 AddRectangle (pict, from, top, to, bottom, NO_ARROW, FALSE, 0);
7583 }
7584 }
7585
7586 AlnMsgFree2 (amp);
7587
7588 sprintf (str, "%ld", (long) pos1);
7589 AddLabel (pict, 0, (top + bottom) / 2, str, SMALL_TEXT, 5, MIDDLE_LEFT, 0);
7590
7591 sprintf (str, "%ld", (long) pos2);
7592 AddLabel (pict, to, (top + bottom) / 2, str, SMALL_TEXT, 5, MIDDLE_RIGHT, 0);
7593 }
7594
MakeAlignDetails(UpsDataPtr udp,CharPtr strid1,CharPtr strid2,SeqAlignPtr sap)7595 static SegmenT MakeAlignDetails (
7596 UpsDataPtr udp,
7597 CharPtr strid1,
7598 CharPtr strid2,
7599 SeqAlignPtr sap
7600 )
7601
7602 {
7603 Int4 aln_length;
7604 SegmenT pict;
7605 Int4 top, bottom;
7606
7607 pict = CreatePicture ();
7608 if (sap == NULL) return pict;
7609
7610 aln_length = udp->aln_length;
7611
7612 top = 0;
7613 bottom = top - 10;
7614
7615 DrawAlignBits (udp, pict, top, bottom, 1, udp->old5 + 1, udp->old5 + udp->olda, sap);
7616
7617 /*
7618 AddLabel (pict, aln_length / 2, bottom, strid1, SMALL_TEXT, 5, LOWER_CENTER, 0);
7619 */
7620
7621 top = 30;
7622 bottom = top - 10;
7623
7624 if (udp->revcomp) {
7625 DrawAlignBits (udp, pict, top, bottom, 2, udp->new3 + udp->newa, udp->new3 + 1, sap);
7626 } else {
7627 DrawAlignBits (udp, pict, top, bottom, 2, udp->new5 + 1, udp->new5 + udp->newa, sap);
7628 }
7629
7630 /*
7631 AddLabel (pict, aln_length / 2, top, strid2, SMALL_TEXT, 5, UPPER_CENTER, 0);
7632 */
7633
7634 top = 15;
7635 bottom = top - 10;
7636
7637 DrawAlignDiffs (udp, pict, top, bottom, sap);
7638
7639 return pict;
7640 }
7641
MakeAlignSequence(UpsDataPtr udp,SeqAlignPtr sap,Int4 row,CharPtr seq)7642 static CharPtr MakeAlignSequence (
7643 UpsDataPtr udp,
7644 SeqAlignPtr sap,
7645 Int4 row,
7646 CharPtr seq
7647 )
7648
7649 {
7650 CharPtr aln;
7651 AlnMsg2Ptr amp;
7652 Int4 aln_length, len, lens, start, stop, from, to, i, j;
7653
7654 if (udp == NULL || sap == NULL || seq == NULL || udp->aln_length < 1) return NULL;
7655 lens = StringLen (seq);
7656
7657 aln = (CharPtr) MemNew (sizeof (Char) * (udp->aln_length + 2));
7658 if (aln == NULL) return NULL;
7659 aln_length = udp->aln_length;
7660 MemSet ((Pointer) aln, '-', aln_length);
7661
7662 amp = AlnMsgNew2 ();
7663 if (amp == NULL) return aln;
7664
7665 amp->from_aln = 0;
7666 amp->to_aln = -1;
7667 amp->row_num = row;
7668
7669 start = 0;
7670 stop = 0;
7671 from = 0;
7672 to = 0;
7673
7674 while (AlnMgr2GetNextAlnBit (sap, amp)) {
7675 len = amp->to_row - amp->from_row + 1;
7676 stop = start + len;
7677
7678 if (amp->type == AM_SEQ) {
7679 for (i = start, j = amp->from_row; i < stop && j < lens; i++, j++) {
7680 aln [i] = seq [j];
7681 }
7682 }
7683 start += len;
7684 }
7685
7686 AlnMsgFree2 (amp);
7687
7688 return aln;
7689 }
7690
PrintTAln(ButtoN b)7691 static void PrintTAln (ButtoN b)
7692
7693 {
7694 AsnIoPtr aip;
7695 Char path [PATH_MAX];
7696 UpsDataPtr udp;
7697
7698 udp = (UpsDataPtr) GetObjectExtra (b);
7699 if (udp == NULL) return;
7700 TmpNam (path);
7701 aip = AsnIoOpen (path, "w");
7702 if (aip != NULL) {
7703 SeqAlignAsnWrite (udp->salp, aip, NULL);
7704 AsnIoClose (aip);
7705 LaunchGeneralTextViewer (path, "Update Sequence Alignment");
7706 }
7707 FileRemove (path);
7708 }
7709
PrintGAln(ButtoN b)7710 static void PrintGAln (ButtoN b)
7711
7712 {
7713 UpsDataPtr udp;
7714
7715 udp = (UpsDataPtr) GetObjectExtra (b);
7716 if (udp == NULL) return;
7717 PrintViewer (udp->overview);
7718 PrintViewer (udp->details);
7719 }
7720
CalculateOverhangs(UpsDataPtr udp)7721 static void CalculateOverhangs (
7722 UpsDataPtr udp
7723 )
7724
7725 {
7726 Int4 aln_length;
7727 Uint2 entityID;
7728 SeqAlignPtr sap;
7729 SeqEntryPtr sep;
7730 Int4 stopold, startold, lenold, stopnew, startnew, lennew;
7731
7732 if (udp == NULL) return;
7733 sap = udp->salp;
7734 if (sap == NULL) return;
7735 aln_length = AlnMgr2GetAlnLength (sap, FALSE);
7736 AlnMgr2GetNthSeqRangeInSA (sap, 1, &startold, &stopold);
7737 AlnMgr2GetNthSeqRangeInSA (sap, 2, &startnew, &stopnew);
7738 lenold = udp->oldbsp->length;
7739 lennew = udp->newbsp->length;
7740
7741 udp->old5 = startold;
7742 udp->old3 = lenold - stopold - 1;
7743 udp->olda = stopold - startold + 1;
7744
7745 udp->new5 = startnew;
7746 udp->new3 = lennew - stopnew - 1;
7747 udp->newa = stopnew - startnew + 1;
7748
7749 udp->aln_length = aln_length;
7750 udp->startmax = MAX (startold, startnew);
7751 udp->stopmax = MAX (aln_length + lenold - stopold, aln_length + lennew - stopnew);
7752
7753 udp->strandold = AlnMgr2GetNthStrand (sap, 1);
7754 udp->strandnew = AlnMgr2GetNthStrand (sap, 2);
7755
7756 entityID = ObjMgrGetEntityIDForPointer (udp->oldbsp);
7757 sep = GetTopSeqEntryForEntityID (entityID);
7758 SeqEntrySetScope (sep);
7759 udp->seq1 = GetSequenceByBsp (udp->oldbsp);
7760 SeqEntrySetScope (NULL);
7761
7762 entityID = ObjMgrGetEntityIDForPointer (udp->oldbsp);
7763 sep = GetTopSeqEntryForEntityID (entityID);
7764 SeqEntrySetScope (sep);
7765 udp->seq2 = GetSequenceByBsp (udp->newbsp);
7766 SeqEntrySetScope (NULL);
7767
7768 udp->aln1 = MakeAlignSequence (udp, sap, 1, udp->seq1);
7769 udp->aln2 = MakeAlignSequence (udp, sap, 2, udp->seq2);
7770
7771 udp->log10_aln_length = 1;
7772 while (aln_length >= 10) {
7773 aln_length /= 10;
7774 (udp->log10_aln_length)++;
7775 }
7776 }
7777
CalculateBestScale(UpsDataPtr udp,VieweR vwr,SegmenT pict)7778 static Int4 CalculateBestScale (
7779 UpsDataPtr udp,
7780 VieweR vwr,
7781 SegmenT pict
7782 )
7783
7784 {
7785 BoxInfo box;
7786 Int2 i;
7787 Int4 max, worldwid, portwid;
7788 RecT r;
7789 Int4 scaleX, oldscaleX;
7790 Int4 wid;
7791
7792 ObjectRect (vwr, &r);
7793 InsetRect (&r, 4, 4);
7794 wid = (Int4) (r.right - r.left + 1);
7795
7796 SegmentBox (pict, &box);
7797 oldscaleX = (box.right - box.left + wid - 1) / wid;
7798 RecalculateSegment (pict, oldscaleX, 1);
7799 SegmentBox (pict, &box);
7800 portwid = wid * oldscaleX;
7801 worldwid = box.right - box.left + 20 * oldscaleX + 1;
7802 max = MAX (worldwid, portwid);
7803 scaleX = (max + wid - 1) / wid;
7804 i = 0;
7805 while (i < 10 && (scaleX > oldscaleX || portwid < worldwid)) {
7806 oldscaleX = scaleX;
7807 RecalculateSegment (pict, oldscaleX, 1);
7808 SegmentBox (pict, &box);
7809 portwid = wid * oldscaleX;
7810 worldwid = box.right - box.left + 20 * oldscaleX + 1;
7811 max = MAX (worldwid, portwid);
7812 scaleX = (max + wid - 1) / wid;
7813 i++;
7814 }
7815
7816 return scaleX;
7817 }
7818
7819 static Uint1 leftTriFillSym [] = {
7820 0x0C, 0x3C, 0xFC, 0x3C, 0x0C, 0x00, 0x00, 0x00
7821 };
7822 static Uint1 rightTriFillSym [] = {
7823 0xC0, 0xF0, 0xFC, 0xF0, 0xC0, 0x00, 0x00, 0x00
7824 };
7825
LetDraw(PaneL pnl)7826 static void LetDraw (
7827 PaneL pnl
7828 )
7829
7830 {
7831 Char ch1, ch2;
7832 Int2 i, k, q, left, top, bottom, arrowwidth;
7833 size_t len;
7834 Int4 offset, j, pos, realpos;
7835 RecT r, x;
7836 BaR sb;
7837 Char str [32];
7838 UpsDataPtr udp;
7839
7840 udp = (UpsDataPtr) GetObjectExtra (pnl);
7841 if (udp == NULL) return;
7842
7843 ObjectRect (pnl, &r);
7844 InsetRect (&r, 4, 4);
7845
7846 sb = GetSlateHScrollBar ((SlatE) pnl);
7847 offset = GetBarValue (sb);
7848
7849 SelectFont (SetSmallFont ());
7850
7851 /* draw top (new) letters */
7852
7853 if (udp->aln2 != NULL)
7854 {
7855 MoveTo (r.left, r.top + 8 + 3 * udp->lineheight);
7856 for (i = 0, j = offset; i < udp->maxchars && j < udp->aln_length; i++, j++) {
7857 PaintChar (udp->aln2 [j]);
7858 }
7859 }
7860
7861 /* draw bottom (old) letters */
7862
7863 if (udp->aln1 != NULL)
7864 {
7865 MoveTo (r.left, r.top + 8 + 5 * udp->lineheight);
7866 for (i = 0, j = offset; i < udp->maxchars && j < udp->aln_length; i++, j++) {
7867 PaintChar (udp->aln1 [j]);
7868 }
7869 }
7870
7871 /* draw recombination arrows */
7872
7873 arrowwidth = MIN (6, udp->charwidth);
7874 if (udp->recomb1 >= offset && udp->recomb1 <= offset + udp->maxchars) {
7875 left = r.left + udp->charwidth * (udp->recomb1 - offset);
7876 LoadRect (&x, left, r.top, left + arrowwidth, r.top + 6);
7877 CopyBits (&x, leftTriFillSym);
7878 }
7879
7880 if (udp->recomb2 >= offset && udp->recomb2 <= offset + udp->maxchars) {
7881 left = r.left + udp->charwidth * (udp->recomb2 - offset - 1);
7882 LoadRect (&x, left, r.top, left + arrowwidth, r.top + 6);
7883 CopyBits (&x, rightTriFillSym);
7884 }
7885
7886 if (udp->aln1 == NULL || udp->aln2 == NULL)
7887 {
7888 return;
7889 }
7890 /* draw red mismatch lines */
7891
7892 Red ();
7893 top = r.top + 8 + 4 * udp->lineheight - Ascent ();
7894 bottom = top + udp->lineheight - 2;
7895
7896 for (i = 0, j = offset; i < udp->maxchars && j < udp->aln_length; i++, j++) {
7897 ch1 = udp->aln1 [j];
7898 ch2 = udp->aln2 [j];
7899 if (ch1 == ch2) {
7900 } else if (ch1 == '-' || ch2 == '-') {
7901 } else {
7902 left = r.left + i * udp->charwidth + udp->charwidth / 2 - 1;
7903 MoveTo (left, top);
7904 LineTo (left, bottom);
7905 }
7906 }
7907 Black ();
7908
7909 /* draw top (new) tick marks and coordinates */
7910
7911 bottom = r.top + 8 + 3 * udp->lineheight - Ascent () - 2;
7912 top = bottom - 5;
7913 i = 0;
7914 j = offset;
7915 pos = AlnMgr2MapSeqAlignToBioseq (udp->salp, j, 2);
7916 while (pos < 1 && i < udp->maxchars && j < udp->aln_length) {
7917 i++;
7918 j++;
7919 pos = AlnMgr2MapSeqAlignToBioseq (udp->salp, j, 2);
7920 }
7921 for (; i < udp->maxchars + udp->log10_aln_length && j < udp->aln_length; i++, j++) {
7922 ch1 = udp->aln2 [j];
7923 if (ch1 != '-') {
7924 if (udp->revcomp) {
7925 realpos = (udp->newbsp->length - pos - 1);
7926 } else {
7927 realpos = pos;
7928 }
7929 if (((realpos + 1) % 10) == 0) {
7930 left = r.left + i * udp->charwidth + udp->charwidth / 2 - 1;
7931 if (i < udp->maxchars) {
7932 MoveTo (left, top);
7933 LineTo (left, bottom);
7934 }
7935 sprintf (str, "%ld", (long) (realpos + 1));
7936 len = StringLen (str);
7937 if (len <= j + 1) {
7938 k = i - len + 1;
7939 q = 0;
7940 if (k < 0) {
7941 q -= k;
7942 k = 0;
7943 }
7944 if (q < len) {
7945 left = r.left + k * udp->charwidth;
7946 MoveTo (left, r.top + 8 + udp->lineheight);
7947 while (k < udp->maxchars && q < len) {
7948 PaintChar (str [q]);
7949 k++;
7950 q++;
7951 }
7952 }
7953 }
7954 } else if (((realpos + 1) % 5) == 0) {
7955 left = r.left + i * udp->charwidth + udp->charwidth / 2 - 1;
7956 if (i < udp->maxchars) {
7957 MoveTo (left, top + 3);
7958 LineTo (left, bottom);
7959 }
7960 }
7961 pos++;
7962 }
7963 }
7964
7965 /* draw bottom (old) tick marks and coordinates */
7966
7967 top = r.top + 8 + 6 * udp->lineheight - Ascent () + 2;
7968 bottom = top + 5;
7969 i = 0;
7970 j = offset;
7971 pos = AlnMgr2MapSeqAlignToBioseq (udp->salp, j, 1);
7972 while (pos < 1 && i < udp->maxchars && j < udp->aln_length) {
7973 i++;
7974 j++;
7975 pos = AlnMgr2MapSeqAlignToBioseq (udp->salp, j, 1);
7976 }
7977 for (; i < udp->maxchars + udp->log10_aln_length && j < udp->aln_length; i++, j++) {
7978 ch1 = udp->aln1 [j];
7979 if (ch1 != '-') {
7980 if (((pos + 1) % 10) == 0) {
7981 left = r.left + i * udp->charwidth + udp->charwidth / 2 - 1;
7982 if (i < udp->maxchars) {
7983 MoveTo (left, top);
7984 LineTo (left, bottom);
7985 }
7986 sprintf (str, "%ld", (long) (pos + 1));
7987 len = StringLen (str);
7988 if (len <= j + 1) {
7989 k = i - len + 1;
7990 q = 0;
7991 if (k < 0) {
7992 q -= k;
7993 k = 0;
7994 }
7995 if (q < len) {
7996 left = r.left + k * udp->charwidth;
7997 MoveTo (left, r.top + 8 + 7 * udp->lineheight);
7998 while (k < udp->maxchars && q < len) {
7999 PaintChar (str [q]);
8000 k++;
8001 q++;
8002 }
8003 }
8004 }
8005 } else if (((pos + 1) % 5) == 0) {
8006 left = r.left + i * udp->charwidth + udp->charwidth / 2 - 1;
8007 if (i < udp->maxchars) {
8008 MoveTo (left, top);
8009 LineTo (left, bottom - 3);
8010 }
8011 }
8012 pos++;
8013 }
8014 }
8015 SelectFont (systemFont);
8016 }
8017
LetScrl(BaR sb,SlatE slt,Int4 newval,Int4 oldval)8018 static void LetScrl (
8019 BaR sb,
8020 SlatE slt,
8021 Int4 newval,
8022 Int4 oldval
8023 )
8024
8025 {
8026 RecT r;
8027 UpsDataPtr udp;
8028
8029 udp = (UpsDataPtr) GetObjectExtra (slt);
8030 if (udp == NULL) return;
8031
8032 ObjectRect (udp->letters, &r);
8033 InsetRect (&r, 4, 4);
8034 Select (udp->letters);
8035 if (ABS (oldval - newval) < udp->maxchars) {
8036 ScrollRect (&r, (oldval - newval) * udp->charwidth, 0);
8037 } else {
8038 InsetRect (&r, -2, -2);
8039 InvalRect (&r);
8040 }
8041 Update ();
8042 }
8043
DtlClck(VieweR vwr,SegmenT pict,PoinT pt)8044 static void DtlClck (
8045 VieweR vwr,
8046 SegmenT pict,
8047 PoinT pt
8048 )
8049
8050 {
8051 Int4 goHere;
8052 Int4 offset;
8053 Int4 maxover2;
8054 PntInfo pnt;
8055 BaR sb;
8056 UpsDataPtr udp;
8057 ValNodePtr vnp;
8058
8059 udp = (UpsDataPtr) GetViewerData (vwr);
8060 if (udp == NULL) return;
8061
8062 sb = GetSlateHScrollBar ((SlatE) udp->letters);
8063
8064 MapViewerToWorld (vwr, pt, &pnt);
8065 maxover2 = udp->maxchars / 2;
8066 if (pnt.x <= 0) {
8067 pnt.x = 0;
8068 } else if (pnt.x >= udp->aln_length) {
8069 pnt.x = udp->aln_length - udp->maxchars;
8070 } else if (pnt.x >= maxover2) {
8071
8072 offset = GetBarValue (sb);
8073
8074 /* look for clicks within 5 pixels of an indel start or a mismatch */
8075
8076 goHere = -1;
8077 for (vnp = udp->indels; vnp != NULL && goHere < 0; vnp = vnp->next) {
8078 if (ABS (pnt.x - vnp->data.intvalue) < udp->scaleX * 5) {
8079 goHere = vnp->data.intvalue;
8080 }
8081 }
8082 for (vnp = udp->mismatches; vnp != NULL && goHere < 0; vnp = vnp->next) {
8083 if (ABS (pnt.x - vnp->data.intvalue) < udp->scaleX * 5) {
8084 goHere = vnp->data.intvalue;
8085 }
8086 }
8087
8088 if (goHere >= 0) {
8089 pnt.x = goHere;
8090 } else {
8091 /* if already visible, no need to scroll */
8092 if (pnt.x - maxover2 > offset && pnt.x - maxover2 < offset + maxover2 - 5) return;
8093 if (pnt.x - maxover2 < offset && pnt.x - maxover2 > offset - maxover2 + 5) return;
8094 }
8095
8096 /* go left 1/2 screen so desired point is in the middle */
8097
8098 pnt.x -= maxover2;
8099 }
8100
8101 ResetClip ();
8102 SetBarValue (sb, pnt.x);
8103 Update ();
8104 }
8105
FrameVwr(VieweR vwr,SegmenT pict)8106 static void FrameVwr (
8107 VieweR vwr,
8108 SegmenT pict
8109 )
8110
8111 {
8112 RecT r;
8113
8114 ResetClip ();
8115 ObjectRect (vwr, &r);
8116 FrameRect (&r);
8117 }
8118
SortVnpByInt(VoidPtr ptr1,VoidPtr ptr2)8119 static int LIBCALLBACK SortVnpByInt (VoidPtr ptr1, VoidPtr ptr2)
8120
8121 {
8122 ValNodePtr vnp1;
8123 ValNodePtr vnp2;
8124
8125 if (ptr1 == NULL || ptr2 == NULL) return 0;
8126 vnp1 = *((ValNodePtr PNTR) ptr1);
8127 vnp2 = *((ValNodePtr PNTR) ptr2);
8128 if (vnp1 == NULL || vnp2 == NULL) return 0;
8129
8130 if (vnp1->data.intvalue > vnp2->data.intvalue) {
8131 return 1;
8132 } else if (vnp1->data.intvalue < vnp2->data.intvalue) {
8133 return -1;
8134 }
8135
8136 return 0;
8137 }
8138
8139
UpdateSequenceFormMessage(ForM f,Int2 mssg)8140 static void UpdateSequenceFormMessage (ForM f, Int2 mssg)
8141
8142 {
8143 BaseFormPtr bfp;
8144 StdEditorProcsPtr sepp;
8145
8146 bfp = (BaseFormPtr) GetObjectExtra (f);
8147 if (bfp == NULL) return;
8148 switch (mssg) {
8149 case VIB_MSG_CLOSE :
8150 Remove (f);
8151 break;
8152 case VIB_MSG_QUIT :
8153 QuitProc ();
8154 break;
8155 default :
8156 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
8157 if (sepp != NULL && sepp->handleMessages != NULL) {
8158 sepp->handleMessages (f, mssg);
8159 }
8160 break;
8161 }
8162 }
8163
FreeUdpFields(UpsDataPtr udp)8164 static void FreeUdpFields (UpsDataPtr udp)
8165 {
8166 Uint2 entityID;
8167
8168 udp->ovpict = DeletePicture (udp->ovpict);
8169 udp->dtpict = DeletePicture (udp->dtpict);
8170 udp->salp = SeqAlignFree (udp->salp);
8171 entityID = ObjMgrGetEntityIDForPointer (udp->newbsp);
8172 udp->newbsp = ObjMgrFreeByEntityID (entityID);
8173 udp->seq1 = MemFree (udp->seq1);
8174 udp->seq2 = MemFree (udp->seq2);
8175 udp->aln1 = MemFree (udp->aln1);
8176 udp->aln1 = NULL;
8177 udp->aln2 = MemFree (udp->aln2);
8178 udp->aln2 = NULL;
8179 udp->indels = ValNodeFree (udp->indels);
8180 udp->mismatches = ValNodeFree (udp->mismatches);
8181 udp->transl_except_list = ValNodeFree (udp->transl_except_list);
8182 udp->affected_variation_features = ValNodeFree (udp->affected_variation_features);
8183 }
8184
CleanupUpdateSequenceForm(GraphiC g,VoidPtr data)8185 static void CleanupUpdateSequenceForm (GraphiC g, VoidPtr data)
8186
8187 {
8188 UpsDataPtr udp;
8189
8190 udp = (UpsDataPtr) data;
8191 if (udp != NULL)
8192 FreeUdpFields (udp);
8193 StdCleanupFormProc (g, data);
8194 }
8195
8196 static CharPtr txt1 =
8197 "Sequence Relationship displays sequence lengths";
8198
8199 static CharPtr txt2 =
8200 "Alignment Details displays sequence positions";
8201
8202 static CharPtr txt3 =
8203 "Click above to scroll Alignment Text position";
8204
8205 /*------------------------------------------------------------------*/
8206 /* */
8207 /* DetermineButtonState () -- Enable/disable buttons based on the */
8208 /* nature of the alignment. */
8209 /* */
8210 /*------------------------------------------------------------------*/
8211
DetermineButtonState(UpsDataPtr udp,ButtoN PNTR replaceButtonPtr,ButtoN PNTR extend5ButtonPtr,ButtoN PNTR extend3ButtonPtr,ButtoN PNTR patchButtonPtr)8212 static void DetermineButtonState (UpsDataPtr udp,
8213 ButtoN PNTR replaceButtonPtr,
8214 ButtoN PNTR extend5ButtonPtr,
8215 ButtoN PNTR extend3ButtonPtr,
8216 ButtoN PNTR patchButtonPtr)
8217 {
8218 BioSourcePtr biop1;
8219 BioSourcePtr biop2;
8220 SeqMgrDescContext dcontext;
8221 Uint2 entityID;
8222 SeqMgrFeatContext fcontext;
8223 OrgRefPtr orp1;
8224 OrgRefPtr orp2;
8225 SeqDescrPtr sdp;
8226 SeqFeatPtr sfp;
8227
8228 /* If no alignment then disable the patch button */
8229
8230 if (udp->salp == NULL) {
8231 if (udp->do_update && patchButtonPtr != NULL && *patchButtonPtr != NULL) {
8232 Disable (*patchButtonPtr);
8233 }
8234 if (!udp->do_update)
8235 {
8236 Disable (*replaceButtonPtr);
8237 }
8238 }
8239
8240 /* Extend 5' */
8241
8242 else if (udp->new5 > udp->old5 && udp->new3 < udp->old3) {
8243 SetValue (udp->rmc, UPDATE_EXTEND5);
8244 Disable (*extend3ButtonPtr);
8245 udp->recomb2 = udp->aln_length;
8246 if (! udp->do_update) {
8247 Disable (*replaceButtonPtr);
8248 }
8249 }
8250
8251 /* Extend 3' */
8252
8253 else if (udp->new5 < udp->old5 && udp->new3 > udp->old3) {
8254 SetValue (udp->rmc, UPDATE_EXTEND3);
8255 Disable (*extend5ButtonPtr);
8256 udp->recomb1 = 0;
8257 if (! udp->do_update) {
8258 Disable (*replaceButtonPtr);
8259 }
8260 }
8261
8262 /* Replace */
8263
8264 else {
8265 SetValue (udp->rmc, UPDATE_REPLACE);
8266 Disable (*extend5ButtonPtr);
8267 Disable (*extend3ButtonPtr);
8268 udp->recomb1 = 0;
8269 udp->recomb2 = udp->aln_length;
8270 }
8271
8272 switch (udp->rmcval)
8273 {
8274 case UPDATE_REPLACE:
8275 if (Enabled (*replaceButtonPtr))
8276 {
8277 SetValue (udp->rmc, UPDATE_REPLACE);
8278 }
8279 break;
8280 case UPDATE_EXTEND5:
8281 if (Enabled (*extend5ButtonPtr))
8282 {
8283 SetValue (udp->rmc, UPDATE_EXTEND5);
8284 }
8285 break;
8286 case UPDATE_EXTEND3:
8287 if (Enabled (*extend3ButtonPtr))
8288 {
8289 SetValue (udp->rmc, UPDATE_EXTEND3);
8290 }
8291 break;
8292 case UPDATE_PATCH:
8293 if (patchButtonPtr != NULL && Enabled (*patchButtonPtr))
8294 {
8295 SetValue (udp->rmc, UPDATE_PATCH);
8296 }
8297 break;
8298 }
8299
8300 /* If no features, must be sequence update only */
8301
8302 entityID = ObjMgrGetEntityIDForPointer (udp->newbsp);
8303 if (! SeqMgrFeaturesAreIndexed (entityID))
8304 SeqMgrIndexFeatures (entityID, NULL);
8305
8306 sfp = SeqMgrGetNextFeature (udp->newbsp, NULL, 0, 0, &fcontext);
8307 if (sfp == NULL) {
8308 SetValue (udp->sfb, UPDATE_SEQUENCE_ONLY);
8309 Disable (udp->sfb);
8310 Disable (udp->replace_all);
8311 Disable (udp->nobm);
8312 }
8313
8314 /* If different organisms, must be feature propagation only */
8315
8316 orp1 = NULL;
8317 orp2 = NULL;
8318 sdp = SeqMgrGetNextDescriptor (udp->oldbsp, NULL, Seq_descr_source, &dcontext);
8319 if (sdp != NULL) {
8320 biop1 = (BioSourcePtr) sdp->data.ptrvalue;
8321 if (biop1 != NULL) {
8322 orp1 = biop1->org;
8323 }
8324 }
8325 sdp = SeqMgrGetNextDescriptor (udp->newbsp, NULL, Seq_descr_source, &dcontext);
8326 if (sdp != NULL) {
8327 biop2 = (BioSourcePtr) sdp->data.ptrvalue;
8328 if (biop2 != NULL) {
8329 orp2 = biop2->org;
8330 }
8331 }
8332 if (orp1 != NULL && orp2 != NULL) {
8333 if (StringICmp (orp1->taxname, orp2->taxname) != 0) {
8334 if (sfp != NULL) {
8335 SetValue (udp->sfb, UPDATE_FEATURES_ONLY);
8336 Disable (udp->sfb);
8337 udp->diffOrgs = TRUE;
8338 if (FALSE == udp->isSet)
8339 Message (MSG_OK, "Organisms are different, so features will"
8340 " be propagated, but sequence will not be changed");
8341 } else {
8342 /* no features, cannot do anything */
8343 SetValue (udp->sfb, UPDATE_CHOICE_NOT_SET);
8344 Disable (udp->sfb);
8345 Disable (udp->replace_all);
8346 Disable (udp->nobm);
8347 if (FALSE == udp->isSet)
8348 Message (MSG_OK, "Organisms are different, no features"
8349 " to propagate, so nothing to do");
8350 }
8351 Disable (udp->rmc);
8352 }
8353 }
8354
8355 /* If either sequence is not raw and not indexer version, only allow feature propagation */
8356 if (!indexerVersion &&
8357 (udp->oldbsp->repr != Seq_repr_raw || udp->newbsp->repr != Seq_repr_raw)) {
8358 SetValue (udp->sfb, UPDATE_FEATURES_ONLY);
8359 Disable (udp->sfb);
8360 }
8361
8362 /* Disable accept button unless rmc and sfb are both preset */
8363
8364 UpdateAccept (udp->rmc);
8365
8366 }
8367
ChangeUpdateReplaceAll(ButtoN b)8368 static void ChangeUpdateReplaceAll (ButtoN b)
8369 {
8370 UpsDataPtr udp;
8371
8372 if (b == NULL) return;
8373 udp = (UpsDataPtr) GetObjectExtra (b);
8374 if (udp == NULL) return;
8375
8376 if (GetStatus (b))
8377 {
8378 Disable (udp->nobm);
8379 }
8380 else
8381 {
8382 Enable (udp->nobm);
8383 }
8384 /* update accept button */
8385 UpdateAccept (udp->rmc);
8386 }
8387
CancelUpdate(ButtoN b)8388 static void CancelUpdate (ButtoN b)
8389 {
8390 UpsDataPtr udp;
8391
8392 if (b == NULL) return;
8393 udp = (UpsDataPtr) GetObjectExtra (b);
8394 if (udp == NULL) return;
8395 CloseOutSequenceUpdateLog (udp);
8396 StdCancelButtonProc (b);
8397 }
8398
CreateUpdateOperationsGroup(GrouP parent,UpsDataPtr udp)8399 static GrouP CreateUpdateOperationsGroup (GrouP parent, UpsDataPtr udp)
8400 {
8401 GrouP g;
8402 GrouP gp1, gp2, gp3;
8403 ButtoN b1 = NULL, b2 = NULL, b3 = NULL, b4 = NULL;
8404
8405 if (udp == NULL) return NULL;
8406
8407 g = HiddenGroup (parent, -1, 0, NULL);
8408 SetGroupSpacing (g, 5, 5);
8409
8410 gp1 = NormalGroup (g, 4, 0, "Alignment Relationship", programFont, NULL);
8411 udp->rmc = HiddenGroup (gp1, 4, 0, UpdateButtons);
8412 SetObjectExtra (udp->rmc, (Pointer) udp, NULL);
8413 SetGroupSpacing (udp->rmc, 10, 5);
8414 if (udp->do_update) {
8415 b1 = RadioButton (udp->rmc, "Replace");
8416 } else {
8417 b1= RadioButton (udp->rmc, "Extend Both Ends");
8418 }
8419 b2 = RadioButton (udp->rmc, "Extend 5'");
8420 b3 = RadioButton (udp->rmc, "Extend 3'");
8421 if (udp->do_update) {
8422 b4 = RadioButton (udp->rmc, "Patch");
8423 } else {
8424 b4 = NULL;
8425 }
8426
8427 if (udp->do_update) {
8428 gp2 = NormalGroup (g, 4, 0, "Update Operation", programFont, NULL);
8429 udp->sfb = HiddenGroup (gp2, 3, 0, UpdateAccept);
8430 SetObjectExtra (udp->sfb, (Pointer) udp, NULL);
8431 SetGroupSpacing (udp->sfb, 10, 5);
8432 RadioButton (udp->sfb, "Sequence");
8433 RadioButton (udp->sfb, "Features");
8434 RadioButton (udp->sfb, "Sequence + Features");
8435
8436 udp->keepProteinIDs = CheckBox (g, "Keep Protein IDs", NULL);
8437
8438 gp3 = NormalGroup (g, 1, 0, "Feature Policy", programFont, NULL);
8439 udp->replace_all = CheckBox (gp3, "Replace All Features", ChangeUpdateReplaceAll);
8440 SetObjectExtra (udp->replace_all, (Pointer) udp, NULL);
8441 SetValue (udp->replace_all, FALSE);
8442
8443 udp->nobm = NormalGroup (gp3, 5, 0, "Duplicate Features Only", programFont, UpdateAccept);
8444 SetObjectExtra (udp->nobm, (Pointer) udp, NULL);
8445 SetGroupSpacing (udp->nobm, 10, 5);
8446 RadioButton (udp->nobm, "New");
8447 RadioButton (udp->nobm, "Old");
8448 RadioButton (udp->nobm, "Both");
8449 RadioButton (udp->nobm, "Merge");
8450 RadioButton (udp->nobm, "Replace");
8451
8452 AlignObjects (ALIGN_CENTER, (HANDLE) gp1, (HANDLE) gp2,
8453 (HANDLE) udp->keepProteinIDs,
8454 (HANDLE) gp3, NULL);
8455 }
8456 /* Enable/disable buttons based on the nature of the alignment */
8457
8458 DetermineButtonState (udp, &b1, &b2, &b3, &b4);
8459 return g;
8460
8461 }
8462
8463
ChangeProteinUpdateStatus(ButtoN b)8464 static void ChangeProteinUpdateStatus (ButtoN b)
8465 {
8466 UpsDataPtr udp;
8467
8468 udp = (UpsDataPtr) GetObjectExtra (b);
8469 if (udp == NULL) return;
8470 SetProteinOptionsEnable (udp);
8471 }
8472
SkipUpdate(UpsDataPtr udp)8473 static void SkipUpdate (UpsDataPtr udp)
8474 {
8475 Char acc_str [256];
8476 SeqIdPtr sip, sip_next;
8477
8478 if (udp == NULL) return;
8479
8480 OpenSequenceUpdateLog (udp);
8481 if (udp->log_fp != NULL && udp->oldbsp != NULL && udp->oldbsp->id != NULL)
8482 {
8483 sip = SeqIdFindBest (udp->oldbsp->id, 0);
8484 if (sip != NULL)
8485 {
8486 sip_next = sip->next;
8487 sip->next = NULL;
8488 SeqIdWrite (sip, acc_str, PRINTID_REPORT, sizeof (acc_str));
8489 fprintf (udp->log_fp, "Skipped update for %s\n", acc_str);
8490 udp->data_in_log = TRUE;
8491 sip->next = sip_next;
8492 }
8493 }
8494
8495 /* if we are updating a set from a SeqSub, we don't want to free the SeqSub yet */
8496 if (udp->seqsubsep != NULL)
8497 {
8498 udp->newbsp = NULL;
8499 }
8500 FreeUdpFields (udp);
8501 UpdateNextBioseqInFastaSet (udp);
8502 }
8503
CreateExtraUpdateOptionsGroup(GrouP g,UpsDataPtr udp)8504 static GrouP CreateExtraUpdateOptionsGroup (GrouP g, UpsDataPtr udp)
8505 {
8506 GrouP y, protein_options = NULL;
8507
8508 if (udp == NULL || g == NULL) return NULL;
8509
8510 y = HiddenGroup (g, -1, 0, NULL);
8511
8512 udp->add_cit_subs = CheckBox (y, "Add Cit-subs for Updated Sequences", NULL);
8513 udp->update_quality_scores_btn = NULL;
8514 if (! ISA_aa (udp->oldbsp->mol) && udp->do_update)
8515 {
8516 udp->update_quality_scores_btn = CheckBox (y, "Replace Quality Scores", NULL);
8517 SetStatus (udp->update_quality_scores_btn, TRUE);
8518
8519 udp->update_proteins = CheckBox (y, "Update Proteins for Updated Sequences", ChangeProteinUpdateStatus);
8520 SetObjectExtra (udp->update_proteins, (Pointer) udp, NULL);
8521 SetStatus (udp->update_proteins, FALSE);
8522 protein_options = HiddenGroup (y, 1, 0, NULL);
8523 udp->truncate_proteins_btn = CheckBox (protein_options,
8524 "Truncate retranslated proteins at stops",
8525 NULL);
8526 SetStatus (udp->truncate_proteins_btn,
8527 udp->truncate_proteins);
8528 udp->extend_proteins3_btn = CheckBox (protein_options,
8529 "Extend retranslated proteins without stops",
8530 NULL);
8531 udp->extend_proteins5_btn = CheckBox (protein_options,
8532 "Extend retranslated proteins without starts",
8533 NULL);
8534 udp->correct_cds_genes_btn = CheckBox (protein_options, "Correct CDS genes", NULL);
8535
8536 SetStatus (udp->extend_proteins3_btn, udp->extend_proteins3);
8537 SetStatus (udp->extend_proteins5_btn, udp->extend_proteins5);
8538 SetStatus (udp->correct_cds_genes_btn, udp->correct_cds_genes);
8539 }
8540 AlignObjects (ALIGN_CENTER, (HANDLE) udp->add_cit_subs,
8541 (HANDLE) udp->update_quality_scores_btn,
8542 (HANDLE) udp->update_proteins,
8543 (HANDLE) protein_options,
8544 NULL);
8545 return y;
8546 }
8547
SkipUpdateBtn(ButtoN b)8548 static void SkipUpdateBtn (ButtoN b)
8549 {
8550 UpsDataPtr udp;
8551
8552 udp = (UpsDataPtr) GetObjectExtra (b);
8553 if (udp == NULL) return;
8554 SafeHide (udp->form);
8555 Remove (udp->form);
8556
8557 SkipUpdate (udp);
8558 }
8559
8560 /*------------------------------------------------------------------*/
8561 /* */
8562 /* UpdateSequenceForm () -- Compares two sequences and displays a */
8563 /* window giving the user options on how */
8564 /* to update one from the other. */
8565 /* */
8566 /*------------------------------------------------------------------*/
8567
UpdateSequenceForm(UpsDataPtr udp)8568 static ForM UpdateSequenceForm (UpsDataPtr udp)
8569 {
8570 ButtoN b;
8571 GrouP c, g, y, k, x, z = NULL;
8572 Uint2 hgt;
8573 GrouP ppt0, ppt1, ppt2, ppt3;
8574 RecT r;
8575 BaR sb;
8576 Int4 scaleX;
8577 SeqIdPtr sip;
8578 Char strid1 [MAX_ID_LEN], strid2 [MAX_ID_LEN], txt0 [256];
8579 CharPtr title;
8580 WindoW w;
8581 GrouP misc_options;
8582 Int4 prompt_width = 400;
8583 GrouP left_panel;
8584 GrouP right_panel;
8585
8586 /* Check parameters */
8587
8588 if ((udp->oldbsp == NULL) || (udp->newbsp == NULL))
8589 return NULL;
8590
8591 /* Create window */
8592
8593 if (udp->do_update) {
8594 title = "Update Sequence";
8595 } else {
8596 title = "Extend Sequence";
8597 }
8598 w = FixedWindow (-50, -33, -10, -10, title, NULL);
8599
8600 if (w == NULL)
8601 return NULL;
8602
8603 if (FALSE == udp->isSet)
8604 SetObjectExtra (w, (Pointer) udp, CleanupUpdateSequenceForm);
8605 udp->form = (ForM) w;
8606
8607 /* Get string IDs for the Bioseqs */
8608
8609 sip = SeqIdFindWorst (udp->oldbsp->id);
8610 SeqIdWrite (sip, strid1, PRINTID_REPORT, sizeof (strid1) - 1);
8611 sip = SeqIdFindWorst (udp->newbsp->id);
8612 SeqIdWrite (sip, strid2, PRINTID_REPORT, sizeof (strid2) - 1);
8613 if (StringNICmp (strid2, "SequinUpdateSequence", 20) == 0 &&
8614 udp->newbsp->id->next != NULL) {
8615 sip = SeqIdFindWorst (udp->newbsp->id->next);
8616 SeqIdWrite (sip, strid2, PRINTID_REPORT, sizeof (strid2) - 1);
8617 }
8618
8619 /* FIll in some of the data structure */
8620 /* for passing to the callbacks. */
8621
8622 udp->formmessage = UpdateSequenceFormMessage;
8623
8624 #ifdef WIN_MAC
8625 udp->activate = UpdateSequenceFormActivated;
8626 SetActivate (w, UpdateSequenceFormActivate);
8627 #endif
8628
8629 udp->diffOrgs = FALSE;
8630
8631 CalculateOverhangs (udp);
8632
8633 /* Display the sequences */
8634
8635 sprintf (txt0,
8636 "New sequence: %s - Length: %ld\nOld Sequence: %s - Length: %ld",
8637 strid2, (long) udp->newbsp->length, strid1,
8638 (long) udp->oldbsp->length);
8639 ppt0 = MultiLinePrompt (w, txt0, prompt_width, programFont);
8640
8641 x = HiddenGroup (w, 2, 0, NULL);
8642 left_panel = HiddenGroup (x, -1, 0, NULL);
8643 y = left_panel;
8644
8645 ppt1 = MultiLinePrompt (y, txt1, prompt_width, programFont);
8646 udp->overview = CreateViewer (y, prompt_width + Nlm_vScrollBarWidth, 100,
8647 FALSE, FALSE);
8648
8649 ppt2 = MultiLinePrompt (y, txt2, prompt_width, programFont);
8650 udp->details = CreateViewer (y, prompt_width + Nlm_vScrollBarWidth, 80,
8651 FALSE, FALSE);
8652
8653 ppt3 = MultiLinePrompt (y, txt3, prompt_width, programFont);
8654
8655 #ifdef WIN_MAC
8656 hgt = 90;
8657 #else
8658 hgt = 110;
8659 #endif
8660 udp->letters = AutonomousPanel4 (y, prompt_width + Nlm_vScrollBarWidth, hgt,
8661 LetDraw, NULL, LetScrl, 0, NULL, NULL);
8662 SetObjectExtra (udp->letters, (Pointer) udp, NULL);
8663
8664 if (indexerVersion && shftKey) {
8665 ButtoN b;
8666 z = HiddenGroup (y, 2, 0, NULL);
8667 SetGroupSpacing (z, 10, 3);
8668 b = PushButton (z, "Print Graphic", PrintGAln);
8669 SetObjectExtra (b, (Pointer) udp, NULL);
8670 b = PushButton (z, "Display Alignment", PrintTAln);
8671 SetObjectExtra (b, (Pointer) udp, NULL);
8672 }
8673
8674 udp->ovpict = NULL;
8675 udp->dtpict = NULL;
8676
8677 AlignObjects (ALIGN_CENTER, (HANDLE) udp->overview,
8678 (HANDLE) udp->details, (HANDLE) udp->letters,
8679 (HANDLE) ppt1, (HANDLE) ppt2,
8680 (HANDLE) ppt3, NULL);
8681
8682 right_panel = HiddenGroup (x, -1, 0, NULL);
8683 y = right_panel;
8684
8685 k = HiddenGroup (y, -1, 0, NULL);
8686 g = CreateUpdateOperationsGroup (k, udp);
8687 misc_options = CreateExtraUpdateOptionsGroup (k, udp);
8688 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) misc_options, NULL);
8689
8690 c = HiddenGroup (w, 5, 0, NULL);
8691 if (udp->isSet)
8692 {
8693 udp->accept = DefaultButton (c, "Accept", AcceptRMCOrExtendSet);
8694 SetObjectExtra (udp->accept, (Pointer) udp, NULL);
8695 udp->acceptAll = DefaultButton (c, "Accept All", AcceptRMCOrExtendAll);
8696 SetObjectExtra (udp->acceptAll, (Pointer) udp, NULL);
8697 b = PushButton (c, "Skip", SkipUpdateBtn);
8698 SetObjectExtra (b, (Pointer) udp, NULL);
8699 }
8700 else
8701 {
8702 udp->accept = DefaultButton (c, "Accept", AcceptRMCOrExtend);
8703 SetObjectExtra (udp->accept, (Pointer) udp, NULL);
8704 }
8705
8706 b = PushButton (c, "Cancel", CancelUpdate);
8707 SetObjectExtra (b, (Pointer) udp, NULL);
8708 UpdateButtons (udp->rmc);
8709
8710 AlignObjects (ALIGN_CENTER,
8711 (HANDLE) ppt0,
8712 (HANDLE) x,
8713 (HANDLE) c, (HANDLE) z, NULL);
8714 RealizeWindow (w);
8715
8716 udp->ovpict = MakeAlignPicture (udp, strid1, strid2, udp->salp);
8717 scaleX = CalculateBestScale (udp, udp->overview, udp->ovpict);
8718 AttachPicture (udp->overview, udp->ovpict, 0, 0, UPPER_LEFT,
8719 scaleX, 1, FrameVwr);
8720
8721 udp->dtpict = MakeAlignDetails (udp, strid1, strid2, udp->salp);
8722 scaleX = CalculateBestScale (udp, udp->details, udp->dtpict);
8723 udp->scaleX = scaleX;
8724 AttachPicture (udp->details, udp->dtpict, 0, 0, UPPER_LEFT,
8725 scaleX, 1, FrameVwr);
8726 SetViewerData (udp->details, (Pointer) udp, NULL);
8727 SetViewerProcs (udp->details, DtlClck, NULL, NULL, NULL);
8728
8729 udp->indels = ValNodeSort (udp->indels, SortVnpByInt);
8730 udp->mismatches = ValNodeSort (udp->mismatches, SortVnpByInt);
8731
8732 SelectFont (SetSmallFont ());
8733 ObjectRect (udp->letters, &r);
8734 InsetRect (&r, 4, 4);
8735 udp->lineheight = LineHeight ();
8736 udp->charwidth = MaxCharWidth ();
8737 udp->maxchars = (r.right-r.left-2+udp->charwidth - 1) / udp->charwidth;
8738 SelectFont (systemFont);
8739
8740 sb = GetSlateHScrollBar ((SlatE) udp->letters);
8741 SetBarMax (sb, udp->aln_length - (Int4) udp->maxchars);
8742 CorrectBarPage (sb, (Int4) udp->maxchars - 1, (Int4) udp->maxchars - 1);
8743
8744 udp->recomb1 = -1;
8745 udp->recomb2 = -1;
8746
8747 return (ForM) w;
8748 }
8749
8750
8751 /*=====================================================================*/
8752 /* */
8753 /* PrepareToUpdateSequences () */
8754 /* */
8755 /*=====================================================================*/
8756
PrepareToUpdateSequences(UpsDataPtr udp)8757 static Boolean PrepareToUpdateSequences (UpsDataPtr udp)
8758 {
8759 ForM f;
8760
8761 if ( ! PrepareUpdatePtr (udp))
8762 {
8763 CloseOutSequenceUpdateLog (udp);
8764 return FALSE;
8765 }
8766
8767 if (TRUE == udp->useGUI)
8768 {
8769 if (udp->salp == NULL && udp->do_update &&
8770 (udp->no_aln_choice == UPDATE_REPLACE_THIS
8771 || udp->no_aln_choice == UPDATE_SKIP_THIS
8772 || udp->no_aln_choice == UPDATE_REPLACE_ALL
8773 || udp->no_aln_choice == UPDATE_REPLACE_THIS))
8774 {
8775 CalculateOverhangs (udp);
8776 DoAcceptRMCOrExtendSet (udp);
8777 UpdateNextBioseqInFastaSet (udp);
8778 }
8779 else
8780 {
8781 f = UpdateSequenceForm (udp);
8782 if (f == NULL)
8783 {
8784 CloseOutSequenceUpdateLog (udp);
8785 return FALSE;
8786 }
8787 Show (f);
8788 Select (f);
8789 SendHelpScrollMessage (helpForm, "Edit Menu", "Update Sequence");
8790 }
8791 }
8792 else {
8793 CalculateOverhangs (udp);
8794 DoAcceptRMCOrExtendSet (udp);
8795 }
8796 return TRUE;
8797 }
8798
8799 /*=====================================================================*/
8800 /* */
8801 /* FindMatchingBioseq () -- Callback function for exploring Bioseqs. */
8802 /* Finds the bioseq that matches a given */
8803 /* string ID. */
8804 /* */
8805 /*=====================================================================*/
8806
FindMatchingBioseq(BioseqPtr bsp,SeqMgrBioseqContextPtr bContext)8807 static Boolean LIBCALLBACK FindMatchingBioseq (BioseqPtr bsp,
8808 SeqMgrBioseqContextPtr bContext)
8809 {
8810 Char currentId[MAX_ID_LEN];
8811 UpdateDataPtr pUpdateData;
8812 Int2 result;
8813 SeqIdPtr sip, sip_next;
8814
8815 pUpdateData = (UpdateDataPtr) bContext->userdata;
8816
8817 /* Get the string IDs for the current Bioseq */
8818
8819 for (sip = bsp->id; sip != NULL; sip = sip->next)
8820 {
8821 sip_next = sip->next;
8822 sip->next = NULL;
8823 SeqIdWrite (sip, currentId, PRINTID_TEXTID_ACC_ONLY,
8824 sizeof (currentId) - 1);
8825
8826 /* Compare it to the string ID of the new Bioseq */
8827
8828 result = StringICmp (pUpdateData->newId, currentId);
8829
8830 /* if TEXTID_ACC_ONLY doesn't match, try PRINTID_REPORT */
8831 if (result != 0)
8832 {
8833 SeqIdWrite (sip, currentId, PRINTID_REPORT,
8834 sizeof (currentId) - 1);
8835
8836 /* Compare it to the string ID of the new Bioseq */
8837
8838 result = StringICmp (pUpdateData->newId, currentId);
8839 }
8840
8841 sip->next = sip_next;
8842 /* If they match, save the Bioseq and quit searching */
8843
8844 if (0 == result) {
8845 pUpdateData->matchingBsp = bsp;
8846 return FALSE;
8847 }
8848 }
8849
8850 /* Else continue */
8851
8852 return TRUE;
8853 }
8854
SkipProteinInNucUpdate(SeqEntryPtr sep,UpsDataPtr udp)8855 static Boolean SkipProteinInNucUpdate (SeqEntryPtr sep, UpsDataPtr udp)
8856 {
8857 Char newId[MAX_ID_LEN];
8858 SeqIdPtr sip;
8859 BioseqPtr bsp;
8860 Boolean rval = FALSE;
8861 MsgAnswer ans;
8862
8863 if (sep == NULL || ! IS_Bioseq (sep) || sep->data.ptrvalue == NULL || udp == NULL)
8864 {
8865 return FALSE;
8866 }
8867
8868 bsp = (BioseqPtr) sep->data.ptrvalue;
8869 if (ISA_na (bsp->mol))
8870 {
8871 return FALSE;
8872 }
8873
8874 sip = SeqIdFindWorst (bsp->id);
8875 SeqIdWrite (sip, newId, PRINTID_REPORT, sizeof (newId) - 1);
8876 ans = Message (MSG_YN, "Found a protein (%s) in the update file, expecting "
8877 "only nucleotides. Do you want to skip this sequence and continue?", newId);
8878 if (ans == ANS_YES)
8879 {
8880 rval = TRUE;
8881 fprintf (udp->log_fp, "Skipped protein Bioseq (%s) in nucleotide update\n", newId);
8882 udp->data_in_log = TRUE;
8883 }
8884 return rval;
8885 }
8886
RemoveUpdateSet(UpsDataPtr udp)8887 static void RemoveUpdateSet (UpsDataPtr udp)
8888 {
8889 #if 0
8890 ObjMgrPtr omp;
8891 Int2 entityID;
8892
8893 if (udp == NULL || udp->seqsubsep == NULL)
8894 {
8895 return;
8896 }
8897 entityID = SeqMgrGetEntityIDForSeqEntry (udp->seqsubsep);
8898 udp->seqsubsep = SeqEntryFree (udp->seqsubsep);
8899 omp = ObjMgrGet ();
8900 ObjMgrReapOne (omp);
8901 ObjMgrFreeCache (0);
8902 ObjMgrSendMsg(OM_MSG_DEL, entityID, 0, 0);
8903 #endif
8904 }
8905
8906 /*=====================================================================*/
8907 /* */
8908 /* UpdateNextBioseqInFastaSet () - Reads in one Bioseq from a FASTA set*/
8909 /* file and updates the corresponding */
8910 /* Bioseq in memory. */
8911 /* */
8912 /*=====================================================================*/
8913
UpdateNextBioseqInFastaSet(UpsDataPtr udp)8914 static Int2 UpdateNextBioseqInFastaSet (UpsDataPtr udp)
8915 {
8916 BioseqPtr bsp;
8917 BioseqSetPtr bssp;
8918 Pointer dataptr;
8919 Uint2 datatype;
8920 Char errMsg[256];
8921 BioseqPtr nbsp;
8922 SeqEntryPtr nwsep = NULL;
8923 SeqEntryPtr sep = NULL;
8924 SeqIdPtr sip;
8925 SeqSubmitPtr ssp;
8926 UpdateData updateData;
8927 SeqEntryPtr nthBspSep;
8928 BioseqPtr nthBsp;
8929 Boolean skip_prot_in_nuc;
8930
8931 sep = GetTopSeqEntryForEntityID (udp->input_entityID);
8932 bsp = GetBioseqGivenIDs (udp->input_entityID,
8933 udp->input_itemID,
8934 udp->input_itemtype);
8935
8936 updateData.matchingBsp = NULL;
8937 /* keep reading file until we find a sequence that matches
8938 * one that we have.
8939 */
8940 while (updateData.matchingBsp == NULL)
8941 {
8942 skip_prot_in_nuc = FALSE;
8943 if (udp->seqsubsep == NULL)
8944 {
8945 /* Read in one sequence from the file */
8946 dataptr = ReadAsnFastaOrFlatFile (udp->fp, &datatype, NULL, FALSE, FALSE,
8947 TRUE, FALSE);
8948
8949 if (NULL == dataptr)
8950 {
8951 FileClose (udp->fp);
8952 CloseOutSequenceUpdateLog (udp);
8953 RemoveUpdateSet (udp);
8954 return FASTA_READ_DONE;
8955 }
8956
8957 /* Convert the file data to a SeqEntry */
8958
8959 if (datatype == OBJ_SEQENTRY)
8960 nwsep = (SeqEntryPtr) dataptr;
8961 else if (datatype == OBJ_BIOSEQ || datatype == OBJ_BIOSEQSET)
8962 nwsep = SeqMgrGetSeqEntryForData (dataptr);
8963 else if (datatype == OBJ_SEQSUB)
8964 {
8965 ssp = (SeqSubmitPtr) dataptr;
8966 if (ssp != NULL && ssp->datatype == 1)
8967 {
8968 nwsep = (SeqEntryPtr) ssp->data;
8969 udp->seqsubsep = nwsep;
8970 udp->seqsubpos = 1;
8971 }
8972 }
8973
8974 if (nwsep == NULL)
8975 {
8976 FileClose (udp->fp);
8977 ErrPostEx (SEV_ERROR, 0, 0, "Unable to convert file data into SeqEntry.");
8978 CloseOutSequenceUpdateLog (udp);
8979 return FASTA_READ_ERROR;
8980 }
8981
8982 /* Use the new SeqEntry to get a Bioseq */
8983
8984 if (ISA_na (bsp->mol))
8985 {
8986 nbsp = FindNucBioseq (nwsep);
8987 }
8988 else
8989 {
8990 nwsep = FindNthBioseq (nwsep, 1);
8991 if (nwsep == NULL || nwsep->choice != 1)
8992 {
8993 CloseOutSequenceUpdateLog (udp);
8994 return FASTA_READ_ERROR;
8995 }
8996 nbsp = (BioseqPtr) nwsep->data.ptrvalue;
8997 }
8998 if (nbsp == NULL)
8999 {
9000 if (ISA_na (bsp->mol))
9001 {
9002 skip_prot_in_nuc = SkipProteinInNucUpdate (nwsep, udp);
9003 }
9004 if (! skip_prot_in_nuc)
9005 {
9006 FileClose (udp->fp);
9007 ErrPostEx (SEV_ERROR, 0, 0, "Unable to convert file data into Bioseq.");
9008 CloseOutSequenceUpdateLog (udp);
9009 return FASTA_READ_ERROR;
9010 }
9011 }
9012 }
9013 else
9014 {
9015 /* get the next Bioseq from the record */
9016 udp->seqsubpos ++;
9017 nthBspSep = FindNthBioseq (udp->seqsubsep, udp->seqsubpos);
9018 nbsp = NULL;
9019 while (nthBspSep != NULL && nbsp == NULL)
9020 {
9021 if (!IS_Bioseq (nthBspSep))
9022 {
9023 udp->seqsubpos++;
9024 nthBspSep = FindNthBioseq (udp->seqsubsep, udp->seqsubpos);
9025 }
9026 else
9027 {
9028 nthBsp = nthBspSep->data.ptrvalue;
9029 if (ISA_na (bsp->mol) && ISA_na (nthBsp->mol))
9030 {
9031 nbsp = nthBsp;
9032 }
9033 else if (ISA_aa (bsp->mol) && ISA_aa (nthBsp->mol))
9034 {
9035 nbsp = nthBsp;
9036 }
9037 else
9038 {
9039 udp->seqsubpos++;
9040 nthBspSep = FindNthBioseq (udp->seqsubsep, udp->seqsubpos);
9041 }
9042 }
9043 }
9044 if (nthBspSep == NULL)
9045 {
9046 RemoveUpdateSet (udp);
9047 return FASTA_READ_DONE;
9048 }
9049 }
9050
9051 if (!skip_prot_in_nuc)
9052 {
9053 /* Get the string ID for the new Bioseq so that we */
9054 /* can find a matching ID among current Bioseqs. */
9055
9056 sip = SeqIdFindWorst (nbsp->id);
9057 SeqIdWrite (sip, updateData.newId, PRINTID_REPORT,
9058 sizeof (updateData.newId) - 1);
9059
9060 /* Find the matching bioseq in the current sequence set */
9061
9062 updateData.matchingBsp = NULL;
9063 if (2 == sep->choice )
9064 {
9065 bssp = (BioseqSetPtr) sep->data.ptrvalue;
9066 SeqMgrExploreBioseqs (0, (Pointer) bssp, &updateData, FindMatchingBioseq,
9067 TRUE, TRUE, TRUE);
9068 }
9069 else
9070 {
9071 bsp = (BioseqPtr) sep->data.ptrvalue;
9072 SeqMgrExploreBioseqs (0, (Pointer) bsp, &updateData, FindMatchingBioseq,
9073 TRUE, TRUE, TRUE);
9074 }
9075
9076
9077 if (updateData.matchingBsp == NULL)
9078 {
9079 OpenSequenceUpdateLog (udp);
9080 if (udp->log_fp != NULL)
9081 {
9082 fprintf (udp->log_fp, "No Bioseq found with ID matching that of the"
9083 " one in the file (%s)\n", updateData.newId);
9084 udp->data_in_log = TRUE;
9085 }
9086 sprintf (errMsg, "No Bioseq found with ID matching that of the"
9087 " one in the file (%s)", updateData.newId);
9088 ErrPostEx (SEV_ERROR, 0, 0, errMsg);
9089 }
9090 }
9091 }
9092
9093 /* Do the updating of the sequences */
9094
9095 udp->oldbsp = updateData.matchingBsp;
9096 udp->newbsp = nbsp;
9097
9098 if (! PrepareToUpdateSequences (udp))
9099 {
9100 return FASTA_READ_DONE;
9101 }
9102
9103 return FASTA_READ_OK;
9104 }
9105
9106 /*=====================================================================*/
9107 /* */
9108 /* UpdateFastaSet () - Updates a set of sequence from a FASTA file */
9109 /* containing a set of sequences. */
9110 /* */
9111 /*=====================================================================*/
9112
UpdateOrExtendFastaSet(IteM i,Boolean do_update)9113 static void UpdateOrExtendFastaSet (IteM i, Boolean do_update)
9114 {
9115 BaseFormPtr bfp;
9116 FILE *fp;
9117 Char path [PATH_MAX];
9118 UpsDataPtr udp;
9119
9120 /* Check parameters */
9121
9122 #ifdef WIN_MAC
9123 bfp = currentFormDataPtr;
9124 #else
9125 bfp = GetObjectExtra (i);
9126 #endif
9127
9128 if (bfp == NULL)
9129 return;
9130
9131 /* Read in the update data from a file */
9132
9133 if (! GetInputFileName (path, sizeof (path),"","TEXT"))
9134 return;
9135 fp = FileOpen (path, "r");
9136 if (fp == NULL)
9137 return;
9138
9139 /* Create data ptr */
9140
9141 udp = (UpsDataPtr) MemNew (sizeof (UpsData));
9142 if (udp == NULL)
9143 return;
9144
9145 udp->input_entityID = bfp->input_entityID;
9146 udp->input_itemID = bfp->input_itemID;
9147 udp->input_itemtype = bfp->input_itemtype;
9148 udp->fp = fp;
9149 udp->useGUI = TRUE;
9150 udp->isSet = TRUE;
9151 udp->convertPubs = CONVERTPUBS_NO; /* was CONVERTPUBS_NOT_SET */
9152 udp->do_update = do_update;
9153 udp->suppress_continue_msg = FALSE;
9154 udp->suppress_instant_refresh = FALSE;
9155 udp->log_fp = NULL;
9156 udp->data_in_log = FALSE;
9157 udp->transl_except_list = NULL;
9158 udp->aln1 = NULL;
9159 udp->aln2 = NULL;
9160
9161 /* Update one Bioseq from the file. Note that this chains */
9162 /* to the processing of the Bioseq after that, so that */
9163 /* actually all Bioseqs are processed by this call. */
9164
9165 UpdateNextBioseqInFastaSet (udp);
9166
9167 }
9168
UpdateFastaSet(IteM i)9169 extern void UpdateFastaSet (IteM i)
9170 {
9171 UpdateOrExtendFastaSet (i, TRUE);
9172 }
9173
9174 typedef struct extendsequences
9175 {
9176 FEATURE_FORM_BLOCK
9177
9178 BioseqPtr newbsp;
9179 Boolean add_cit_sub;
9180 Boolean extend5;
9181 FILE * log_fp;
9182 Char log_path [PATH_MAX];
9183 ValNodePtr sequence_list;
9184 Boolean data_in_log;
9185 LisT sequence_list_ctrl;
9186 ButtoN add_cit_sub_btn;
9187 GrouP extend_end;
9188
9189 } ExtendSequencesData, PNTR ExtendSequencesPtr;
9190
ExtendAllSequencesInSetCallback(BioseqPtr bsp,Pointer userdata)9191 static void ExtendAllSequencesInSetCallback (BioseqPtr bsp, Pointer userdata)
9192 {
9193 ExtendSequencesPtr esp;
9194 SeqIdPtr sip, id_next;
9195 Char acc_str [256];
9196 CharPtr origSeqStr;
9197 CharPtr newSeqStr;
9198 CharPtr mergedSeqStr;
9199 Int4 mergedLen;
9200 ByteStorePtr mergedBS;
9201 Int4 offset;
9202 SeqMgrFeatContext context;
9203 SeqFeatPtr sfp;
9204 CdRegionPtr crp;
9205 CodeBreakPtr cbp;
9206 RnaRefPtr rrp;
9207 tRNAPtr trp;
9208
9209 if (bsp == NULL || userdata == NULL) return;
9210 esp = (ExtendSequencesPtr) userdata;
9211
9212 if (bsp == esp->newbsp) return;
9213
9214 /* Get original and new sequences */
9215
9216 origSeqStr = GetSequenceByBsp (bsp);
9217 newSeqStr = GetSequenceByBsp (esp->newbsp);
9218
9219 /* create string to hold extended sequence */
9220 mergedLen = StringLen (newSeqStr) + StringLen (origSeqStr);
9221 mergedSeqStr = (CharPtr) MemNew (mergedLen + 1);
9222
9223 if (esp->extend5)
9224 {
9225 /* prepend the new sequence */
9226 sprintf (mergedSeqStr, "%s%s", newSeqStr, origSeqStr);
9227 }
9228 else
9229 {
9230 /* append the new sequence */
9231 sprintf (mergedSeqStr, "%s%s", origSeqStr, newSeqStr);
9232 }
9233
9234 /* Convert the new sequence into a ByteStore */
9235
9236 mergedBS = BSNew (mergedLen);
9237 BSWrite (mergedBS, (VoidPtr) mergedSeqStr, mergedLen);
9238
9239 /* Replace the original sequence with the */
9240 /* new concatenated sequence. */
9241
9242 bsp->seq_data = SeqDataFree (bsp->seq_data, bsp->seq_data_type);
9243 bsp->seq_data = (SeqDataPtr) mergedBS;
9244 bsp->seq_data_type = Seq_code_iupacna;
9245 bsp->length = mergedLen;
9246
9247 /* shift the features downstream for 5' extension */
9248 offset = StringLen (newSeqStr);
9249 sip = SeqIdFindBest (bsp->id, 0);
9250 if (sip == NULL) return;
9251 if (esp->extend5 && offset > 0)
9252 {
9253 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
9254 while (sfp != NULL) {
9255 OffsetLocation (sfp->location, offset, sip);
9256 switch (sfp->data.choice) {
9257 case SEQFEAT_CDREGION :
9258 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
9259 if (crp != NULL) {
9260 for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
9261 OffsetLocation (cbp->loc, offset, sip);
9262 }
9263 }
9264 break;
9265 case SEQFEAT_RNA :
9266 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
9267 if (rrp != NULL && rrp->ext.choice == 2) {
9268 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
9269 if (trp != NULL && trp->anticodon != NULL) {
9270 OffsetLocation (trp->anticodon, offset, sip);
9271 }
9272 }
9273 break;
9274 default :
9275 break;
9276 }
9277 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
9278 }
9279 }
9280
9281 if (esp->add_cit_sub)
9282 {
9283 AddCitSubToUpdatedSequence ( bsp, esp->input_entityID, kSubmitterUpdateText);
9284 }
9285
9286 if (esp->log_fp != NULL)
9287 {
9288 id_next = sip->next;
9289 sip->next = NULL;
9290 SeqIdWrite (sip, acc_str, PRINTID_REPORT, sizeof (acc_str) - 1);
9291 sip->next = id_next;
9292 if (esp->extend5)
9293 {
9294 fprintf (esp->log_fp, "Extended %s at 5' end\n", acc_str);
9295 }
9296 else
9297 {
9298 fprintf (esp->log_fp, "Extended %s at 3' end\n", acc_str);
9299 }
9300 esp->data_in_log = TRUE;
9301 }
9302 }
9303
DoExtendAllSequencesInSet(ButtoN b)9304 static void DoExtendAllSequencesInSet (ButtoN b)
9305 {
9306 ExtendSequencesPtr esp;
9307 SeqEntryPtr topsep;
9308 ValNodePtr sip_list, vnp;
9309 SeqIdPtr sip;
9310 BioseqPtr bsp;
9311
9312 esp = (ExtendSequencesPtr) GetObjectExtra (b);
9313 if (esp == NULL)
9314 {
9315 return;
9316 }
9317
9318 esp->add_cit_sub = GetStatus (esp->add_cit_sub_btn);
9319 if (GetValue (esp->extend_end) == 1)
9320 {
9321 esp->extend5 = TRUE;
9322 }
9323 else
9324 {
9325 esp->extend5 = FALSE;
9326 }
9327 sip_list = GetSelectedSequenceList (esp->sequence_list_ctrl);
9328
9329 /* create file for log */
9330 TmpNam (esp->log_path);
9331 esp->log_fp = FileOpen (esp->log_path, "wb");
9332
9333 topsep = GetTopSeqEntryForEntityID (esp->input_entityID);
9334 if (topsep == NULL)
9335 return;
9336
9337 for (vnp = sip_list; vnp != NULL; vnp = vnp->next)
9338 {
9339 sip = (SeqIdPtr) vnp->data.ptrvalue;
9340 bsp = BioseqFind (sip);
9341 if (bsp != NULL)
9342 {
9343 ExtendAllSequencesInSetCallback (bsp, esp);
9344 }
9345 }
9346
9347 if (esp->log_fp != NULL)
9348 {
9349 FileClose (esp->log_fp);
9350 esp->log_fp = NULL;
9351 if (esp->data_in_log)
9352 {
9353 LaunchGeneralTextViewer (esp->log_path, "Extended Sequences");
9354 esp->data_in_log = FALSE;
9355 }
9356 FileRemove (esp->log_path);
9357 }
9358 ObjMgrSetDirtyFlag (esp->input_entityID, TRUE);
9359 ObjMgrSendMsg (OM_MSG_UPDATE, esp->input_entityID, 0, 0);
9360 Remove (esp->form);
9361 Update ();
9362 }
9363
SelectAllSequencesForExtend(ButtoN b)9364 static void SelectAllSequencesForExtend (ButtoN b)
9365 {
9366 ExtendSequencesPtr esp;
9367
9368 esp = (ExtendSequencesPtr) GetObjectExtra (b);
9369 if (esp == NULL)
9370 {
9371 return;
9372 }
9373 SelectAllSequencesInListCtrl (esp->sequence_list_ctrl);
9374 }
9375
UnSelectAllSequencesForExtend(ButtoN b)9376 static void UnSelectAllSequencesForExtend (ButtoN b)
9377 {
9378 ExtendSequencesPtr esp;
9379
9380 esp = (ExtendSequencesPtr) GetObjectExtra (b);
9381 if (esp == NULL)
9382 {
9383 return;
9384 }
9385 UnSelectAllSequencesInListCtrl (esp->sequence_list_ctrl);
9386 }
9387
9388
ExtendAllSequencesInSet(IteM i)9389 extern void ExtendAllSequencesInSet (IteM i)
9390 {
9391 BaseFormPtr bfp;
9392 FILE *fp;
9393 Char path [PATH_MAX];
9394 Pointer dataptr;
9395 Uint2 datatype;
9396 SeqEntryPtr nwsep = NULL, topsep;
9397 SeqSubmitPtr ssp;
9398 BioseqPtr nbsp;
9399 BioseqPtr bsp;
9400 ExtendSequencesPtr esp;
9401 WindoW w;
9402 GrouP h, g, c;
9403 ButtoN b;
9404
9405 #ifdef WIN_MAC
9406 bfp = currentFormDataPtr;
9407 #else
9408 bfp = GetObjectExtra (i);
9409 #endif
9410
9411 if (bfp == NULL)
9412 return;
9413
9414 topsep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9415 if (topsep == NULL)
9416 return;
9417
9418 bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID,
9419 bfp->input_itemtype);
9420 if (bsp == NULL)
9421 {
9422 Message (MSG_ERROR, "You must select a bioseq");
9423 return;
9424 }
9425
9426 /* Read in the update data from a file */
9427
9428 if (! GetInputFileName (path, sizeof (path),"","TEXT"))
9429 return;
9430 fp = FileOpen (path, "r");
9431 if (fp == NULL)
9432 {
9433 Message (MSG_ERROR, "Unable to open %s", path);
9434 return;
9435 }
9436
9437 /* Create data ptr */
9438 dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, NULL, FALSE, FALSE,
9439 TRUE, FALSE);
9440
9441 FileClose (fp);
9442 if (NULL == dataptr)
9443 {
9444 Message (MSG_ERROR, "Unable to read sequence data from %s", path);
9445 return;
9446 }
9447
9448 /* Convert the file data to a SeqEntry */
9449
9450 if (datatype == OBJ_SEQENTRY)
9451 nwsep = (SeqEntryPtr) dataptr;
9452 else if (datatype == OBJ_BIOSEQ || datatype == OBJ_BIOSEQSET)
9453 nwsep = SeqMgrGetSeqEntryForData (dataptr);
9454 else if (datatype == OBJ_SEQSUB)
9455 {
9456 ssp = (SeqSubmitPtr) dataptr;
9457 if (ssp != NULL && ssp->datatype == 1)
9458 {
9459 nwsep = (SeqEntryPtr) ssp->data;
9460 }
9461 }
9462
9463 if (nwsep == NULL)
9464 {
9465 ErrPostEx (SEV_ERROR, 0, 0, "Unable to convert file data into SeqEntry.");
9466 return;
9467 }
9468
9469 /* Use the new SeqEntry to get a Bioseq */
9470
9471 if (ISA_na (bsp->mol))
9472 {
9473 nbsp = FindNucBioseq (nwsep);
9474 }
9475 else
9476 {
9477 nwsep = FindNthBioseq (nwsep, 1);
9478 if (nwsep == NULL || nwsep->choice != 1)
9479 {
9480 return;
9481 }
9482 nbsp = (BioseqPtr) nwsep->data.ptrvalue;
9483 }
9484
9485 if (nbsp == NULL)
9486 {
9487 ErrPostEx (SEV_ERROR, 0, 0, "Unable to convert file data into Bioseq.");
9488 return;
9489 }
9490
9491 esp = (ExtendSequencesPtr) MemNew (sizeof (ExtendSequencesData));
9492 if (esp == NULL) return;
9493 esp->newbsp = nbsp;
9494
9495 w = FixedWindow (-50, -33, -10, -10, "Extend Sequences", NULL);
9496
9497 SetObjectExtra (w, esp, StdCleanupFormProc);
9498 esp->form = (ForM) w;
9499 esp->input_entityID = bfp->input_entityID;
9500
9501 h = HiddenGroup (w, -1, 0, NULL);
9502 SetGroupSpacing (h, 10, 10);
9503
9504 esp->sequence_list_ctrl = MakeSequenceListControl (h, topsep, NULL, NULL, TRUE, TRUE);
9505 g = HiddenGroup (h, 2, 0, NULL);
9506 b = PushButton (g, "Select All", SelectAllSequencesForExtend);
9507 SetObjectExtra (b, esp, NULL);
9508 b = PushButton (g, "Unselect All", UnSelectAllSequencesForExtend);
9509 SetObjectExtra (b, esp, NULL);
9510
9511 esp->extend_end = HiddenGroup (h, 2, 0, NULL);
9512 RadioButton (esp->extend_end, "5' end");
9513 RadioButton (esp->extend_end, "3' end");
9514 SetValue (esp->extend_end, 1);
9515
9516 esp->add_cit_sub_btn = CheckBox (h, "Add Cit Subs to extended sequences", NULL);
9517
9518
9519 c = HiddenGroup (h, 4, 0, NULL);
9520 b = DefaultButton (c, "Accept", DoExtendAllSequencesInSet);
9521 SetObjectExtra (b, esp, NULL);
9522 PushButton (c, "Cancel", StdCancelButtonProc);
9523 AlignObjects (ALIGN_CENTER, (HANDLE) esp->sequence_list_ctrl,
9524 (HANDLE) esp->add_cit_sub_btn, (HANDLE) g,
9525 (HANDLE) esp->extend_end,
9526 (HANDLE) c, NULL);
9527 RealizeWindow (w);
9528 Show (w);
9529 Update ();
9530 }
9531
9532
9533
9534 /*=====================================================================*/
9535 /* */
9536 /* NewUpdateSequence () - Updates a sequence from a file. */
9537 /* */
9538 /*=====================================================================*/
9539
NewUpdateOrExtendSequence(IteM i,Boolean do_update)9540 static void NewUpdateOrExtendSequence (IteM i, Boolean do_update)
9541 {
9542 MsgAnswer ans;
9543 BaseFormPtr bfp;
9544 BioseqPtr bsp, nbsp;
9545 Pointer dataptr = NULL;
9546 Uint2 datatype;
9547 FILE *fp;
9548 Char path [PATH_MAX];
9549 SeqEntryPtr sep, nwsep = NULL;
9550 SeqSubmitPtr ssp;
9551 UpsDataPtr udp;
9552
9553 #ifdef WIN_MAC
9554 bfp = currentFormDataPtr;
9555 #else
9556 bfp = GetObjectExtra (i);
9557 #endif
9558
9559 /* Get the current Bioseq */
9560
9561 if (bfp == NULL)
9562 return;
9563
9564 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9565 if (sep == NULL)
9566 return;
9567 bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID,
9568 bfp->input_itemtype);
9569 if (bsp == NULL)
9570 return;
9571
9572 /* Read in the update data from a file */
9573
9574 if (! GetInputFileName (path, sizeof (path),"","TEXT"))
9575 return;
9576 fp = FileOpen (path, "r");
9577 if (fp == NULL)
9578 {
9579 Message (MSG_ERROR, "Unable to open %s", path);
9580 return;
9581 }
9582 if (bsp->repr == Seq_repr_delta)
9583 {
9584 nwsep = ImportOneGappedSequence (fp);
9585 if (nwsep != NULL && IS_Bioseq (nwsep))
9586 {
9587 nbsp = (BioseqPtr) nwsep->data.ptrvalue;
9588 if (nbsp->repr != Seq_repr_delta)
9589 {
9590 if (ANS_CANCEL == Message (MSG_OKC, "You are updating a delta sequence with a non-delta sequence. "
9591 "If you choose replace, your delta sequence will no longer be a delta sequence. "
9592 "Do you wish to continue?"))
9593 {
9594 SeqEntryFree (nwsep);
9595 return;
9596 }
9597 }
9598 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) nwsep->data.ptrvalue, nwsep);
9599 SeqMgrAddToBioseqIndex (nwsep->data.ptrvalue);
9600 dataptr = nwsep;
9601 datatype = OBJ_SEQENTRY;
9602 }
9603 }
9604 else
9605 {
9606 dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, NULL, FALSE, FALSE,
9607 TRUE, FALSE);
9608 }
9609 FileClose (fp);
9610 if (dataptr == NULL)
9611 return;
9612
9613 /* Get a pointer to the new SeqEntry */
9614
9615 if (datatype == OBJ_SEQENTRY)
9616 nwsep = (SeqEntryPtr) dataptr;
9617 else if (datatype == OBJ_BIOSEQ || datatype == OBJ_BIOSEQSET)
9618 nwsep = SeqMgrGetSeqEntryForData (dataptr);
9619 else if (datatype == OBJ_SEQSUB) {
9620 ssp = (SeqSubmitPtr) dataptr;
9621 if (ssp != NULL && ssp->datatype == 1)
9622 nwsep = (SeqEntryPtr) ssp->data;
9623 }
9624
9625 if (nwsep == NULL)
9626 return;
9627
9628 /* Use the new SeqEntry to get a Bioseq */
9629
9630 if (ISA_na (bsp->mol))
9631 nbsp = FindNucBioseq (nwsep);
9632 else {
9633 nwsep = FindNthBioseq (nwsep, 1);
9634 if (nwsep == NULL || nwsep->choice != 1) return;
9635 nbsp = (BioseqPtr) nwsep->data.ptrvalue;
9636 }
9637
9638 if (nbsp == NULL)
9639 return;
9640
9641 /* convert delta lit to raw so sequence can be updated */
9642 if (!indexerVersion)
9643 {
9644 /* If original sequence is a not a raw sequence then */
9645 /* ask user for advice on how to proceed. */
9646
9647 if (bsp->repr != Seq_repr_raw) {
9648 ans = Message (MSG_YN, "Only raw sequences can be updated."
9649 " Do you wish to proceed for copying features?");
9650 if (ans == ANS_NO)
9651 return;
9652 }
9653 }
9654
9655 /* Create data ptr */
9656
9657 udp = (UpsDataPtr) MemNew (sizeof (UpsData));
9658 if (udp == NULL)
9659 return;
9660
9661 udp->input_entityID = bfp->input_entityID;
9662 udp->input_itemID = bfp->input_itemID;
9663 udp->input_itemtype = bfp->input_itemtype;
9664 udp->oldbsp = bsp;
9665 udp->newbsp = nbsp;
9666 udp->fp = NULL;
9667 udp->isSet = FALSE;
9668 udp->useGUI = TRUE;
9669 udp->convertPubs = CONVERTPUBS_NO; /* was CONVERTPUBS_NOT_SET */
9670 udp->do_update = do_update;
9671 udp->suppress_continue_msg = FALSE;
9672 udp->suppress_instant_refresh = FALSE;
9673 udp->log_fp = NULL;
9674 udp->data_in_log = FALSE;
9675 udp->transl_except_list = NULL;
9676 udp->aln1 = NULL;
9677 udp->aln2 = NULL;
9678
9679 /* Do the updating of the sequences */
9680
9681 PrepareToUpdateSequences (udp);
9682 }
9683
NewUpdateSequence(IteM i)9684 extern void NewUpdateSequence (IteM i)
9685
9686 {
9687 NewUpdateOrExtendSequence (i, TRUE);
9688 }
9689
UpdateSeqAfterDownload(BaseFormPtr bfp,BioseqPtr oldbsp,BioseqPtr newbsp)9690 extern void UpdateSeqAfterDownload
9691 (BaseFormPtr bfp,
9692 BioseqPtr oldbsp,
9693 BioseqPtr newbsp)
9694 {
9695 MsgAnswer ans;
9696 UpsDataPtr udp;
9697
9698 /* convert delta lit to raw so sequence can be updated */
9699
9700 if (oldbsp->repr == Seq_repr_delta && DeltaLitOnly (oldbsp)) {
9701 if (indexerVersion) {
9702 SegOrDeltaBioseqToRaw (oldbsp);
9703 ObjMgrSetDirtyFlag (oldbsp->idx.entityID, TRUE);
9704 } else {
9705 ans = Message (MSG_YN, "Only raw sequences can be updated."
9706 " Do you wish to convert this delta sequence to raw?");
9707 if (ans == ANS_YES) {
9708 SegOrDeltaBioseqToRaw (oldbsp);
9709 ObjMgrSetDirtyFlag (oldbsp->idx.entityID, TRUE);
9710 }
9711 }
9712 }
9713
9714 if (newbsp->repr == Seq_repr_delta && DeltaLitOnly (newbsp)) {
9715 if (indexerVersion) {
9716 SegOrDeltaBioseqToRaw (newbsp);
9717 ObjMgrSetDirtyFlag (newbsp->idx.entityID, TRUE);
9718 } else {
9719 ans = Message (MSG_YN, "Only raw sequences can be updated."
9720 " Do you wish to convert this delta sequence to raw?");
9721 if (ans == ANS_YES) {
9722 SegOrDeltaBioseqToRaw (newbsp);
9723 ObjMgrSetDirtyFlag (newbsp->idx.entityID, TRUE);
9724 }
9725 }
9726 }
9727 /* Create data ptr */
9728
9729 udp = (UpsDataPtr) MemNew (sizeof (UpsData));
9730 if (udp == NULL)
9731 return;
9732
9733 udp->input_entityID = bfp->input_entityID;
9734 udp->input_itemID = bfp->input_itemID;
9735 udp->input_itemtype = bfp->input_itemtype;
9736 udp->oldbsp = oldbsp;
9737 udp->newbsp = newbsp;
9738 udp->fp = NULL;
9739 udp->isSet = FALSE;
9740 udp->useGUI = TRUE;
9741 udp->convertPubs = CONVERTPUBS_NO; /* was CONVERTPUBS_NOT_SET */
9742 udp->do_update = TRUE;
9743 udp->suppress_continue_msg = FALSE;
9744 udp->suppress_instant_refresh = FALSE;
9745 udp->log_fp = NULL;
9746 udp->data_in_log = FALSE;
9747 udp->transl_except_list = NULL;
9748 udp->aln1 = NULL;
9749 udp->aln2 = NULL;
9750
9751 /* Do the updating of the sequences */
9752
9753 PrepareToUpdateSequences (udp);
9754 }
9755
9756
ExtendSeqAfterDownload(BaseFormPtr bfp,BioseqPtr oldbsp,BioseqPtr newbsp)9757 extern void ExtendSeqAfterDownload
9758 (BaseFormPtr bfp,
9759 BioseqPtr oldbsp,
9760 BioseqPtr newbsp)
9761
9762 {
9763 MsgAnswer ans;
9764 UpsDataPtr udp;
9765
9766 /* convert delta lit to raw so sequence can be updated */
9767
9768 if (oldbsp->repr == Seq_repr_delta && DeltaLitOnly (oldbsp)) {
9769 if (indexerVersion) {
9770 SegOrDeltaBioseqToRaw (oldbsp);
9771 ObjMgrSetDirtyFlag (oldbsp->idx.entityID, TRUE);
9772 } else {
9773 ans = Message (MSG_YN, "Only raw sequences can be extended."
9774 " Do you wish to convert this delta sequence to raw?");
9775 if (ans == ANS_YES) {
9776 SegOrDeltaBioseqToRaw (oldbsp);
9777 ObjMgrSetDirtyFlag (oldbsp->idx.entityID, TRUE);
9778 }
9779 }
9780 }
9781
9782 if (newbsp->repr == Seq_repr_delta && DeltaLitOnly (newbsp)) {
9783 if (indexerVersion) {
9784 SegOrDeltaBioseqToRaw (newbsp);
9785 ObjMgrSetDirtyFlag (newbsp->idx.entityID, TRUE);
9786 } else {
9787 ans = Message (MSG_YN, "Only raw sequences can be extended."
9788 " Do you wish to convert this delta sequence to raw?");
9789 if (ans == ANS_YES) {
9790 SegOrDeltaBioseqToRaw (newbsp);
9791 ObjMgrSetDirtyFlag (newbsp->idx.entityID, TRUE);
9792 }
9793 }
9794 }
9795 /* Create data ptr */
9796
9797 udp = (UpsDataPtr) MemNew (sizeof (UpsData));
9798 if (udp == NULL)
9799 return;
9800
9801 udp->input_entityID = bfp->input_entityID;
9802 udp->input_itemID = bfp->input_itemID;
9803 udp->input_itemtype = bfp->input_itemtype;
9804 udp->oldbsp = oldbsp;
9805 udp->newbsp = newbsp;
9806 udp->fp = NULL;
9807 udp->isSet = FALSE;
9808 udp->useGUI = TRUE;
9809 udp->convertPubs = CONVERTPUBS_NO; /* was CONVERTPUBS_NOT_SET */
9810 udp->do_update = FALSE;
9811 udp->suppress_continue_msg = FALSE;
9812 udp->suppress_instant_refresh = FALSE;
9813 udp->log_fp = NULL;
9814 udp->data_in_log = FALSE;
9815 udp->transl_except_list = NULL;
9816 udp->aln1 = NULL;
9817 udp->aln2 = NULL;
9818
9819 /* Do the updating of the sequences */
9820
9821 PrepareToUpdateSequences (udp);
9822 }
9823
9824
9825
9826 /* NEW FEATURE PROPAGATION SECTION */
9827
9828
NewFeaturePropagate(IteM i)9829 extern void NewFeaturePropagate (
9830 IteM i
9831 )
9832
9833 {
9834 BaseFormPtr bfp;
9835 BioseqPtr bsp;
9836 ForM f;
9837 SeqMgrFeatContext fcontext;
9838 Uint4 itemID = 0;
9839 SeqAlignPtr salp;
9840 SeqFeatPtr sfp;
9841 SelStructPtr sel;
9842 SeqEntryPtr sep;
9843 BioseqPtr other_bsp = NULL;
9844
9845 #ifdef WIN_MAC
9846 bfp = currentFormDataPtr;
9847 #else
9848 bfp = GetObjectExtra (i);
9849 #endif
9850 if (bfp == NULL) return;
9851 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9852 if (sep == NULL) return;
9853 bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
9854 if (bsp == NULL) {
9855 Message (MSG_OK, "You must target a single sequence in order to propagate");
9856 return;
9857 }
9858 sfp = GetNextFeatureOnSegOrMaster (bsp, NULL, 0, 0, &fcontext);
9859 if (sfp == NULL)
9860 {
9861 Message (MSG_OK, "The sequence must have features in order to propagate");
9862 return;
9863 }
9864
9865 sel = ObjMgrGetSelected ();
9866 if (sel != NULL && sel->entityID == bfp->input_entityID &&
9867 sel->next == NULL && sel->itemtype == OBJ_SEQFEAT) {
9868 sfp = SeqMgrGetDesiredFeature (bfp->input_entityID, NULL, sel->itemID, 0, NULL, &fcontext);
9869 if (sfp != NULL) {
9870 if (fcontext.bsp == bsp) {
9871 itemID = sel->itemID;
9872 } else {
9873 other_bsp = fcontext.bsp;
9874 }
9875 }
9876 }
9877
9878
9879 salp = FindAlignmentsForBioseq (bsp);
9880
9881 if (salp == NULL) {
9882 salp = FindAlignmentsForBioseq (other_bsp);
9883 if (salp == NULL) {
9884 Message (MSG_ERROR, "The record must have an alignment in order to propagate");
9885 } else if (other_bsp != NULL) {
9886 if (ISA_aa (other_bsp->mol)) {
9887 Message (MSG_ERROR, "If you want to propagate protein features, you must view the protein sequence where the features are located, not the nucleotide sequence.");
9888 } else if (!ISA_aa (other_bsp->mol) && ISA_aa(bsp->mol)) {
9889 Message (MSG_ERROR, "If you want to propagate nucleotide features, you must view the nucleotide sequence where the features are located, not the protein sequence.");
9890 } else {
9891 Message (MSG_ERROR, "You must view the sequence where the selected feature is located in order to propagate.");
9892 }
9893 }
9894 return;
9895 }
9896
9897
9898 f = FeaturePropagateForm (bsp, salp, itemID);
9899 if (f == NULL) return;
9900 Show (f);
9901 Select (f);
9902 SendHelpScrollMessage (helpForm, "Edit Menu", "Feature Propagate");
9903 }
9904
9905
FuseFeatJoins(SeqFeatPtr sfp,Pointer userdata)9906 static void FuseFeatJoins (SeqFeatPtr sfp, Pointer userdata)
9907
9908 {
9909 BioseqPtr bsp;
9910 Boolean partial5;
9911 Boolean partial3;
9912 SeqLocPtr slp;
9913
9914 bsp = BioseqFindFromSeqLoc (sfp->location);
9915 if (bsp == NULL) return;
9916
9917 slp = SeqLocFindNext (sfp->location, NULL);
9918 if (slp == NULL) return;
9919 slp = SeqLocFindNext (sfp->location, slp);
9920 if (slp == NULL) return;
9921
9922 slp = SeqLocMerge (bsp, sfp->location, NULL, FALSE, TRUE, FALSE);
9923 if (slp == NULL) return;
9924 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
9925 sfp->location = SeqLocFree (sfp->location);
9926 sfp->location = slp;
9927 SetSeqLocPartial (sfp->location, partial5, partial3);
9928 }
9929
FuseSlpJoins(IteM i)9930 extern void FuseSlpJoins (IteM i)
9931
9932 {
9933 BaseFormPtr bfp;
9934 SeqEntryPtr sep;
9935
9936 #ifdef WIN_MAC
9937 bfp = currentFormDataPtr;
9938 #else
9939 bfp = GetObjectExtra (i);
9940 #endif
9941 if (bfp == NULL) return;
9942 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9943 if (sep == NULL) return;
9944
9945 VisitFeaturesInSep (sep, NULL, FuseFeatJoins);
9946
9947 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9948 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9949 }
9950
DoAuthorityPrefix(BioSourcePtr biop,Pointer userdata)9951 static void DoAuthorityPrefix (BioSourcePtr biop, Pointer userdata)
9952
9953 {
9954 size_t len;
9955 OrgModPtr omp;
9956 OrgNamePtr onp;
9957 OrgRefPtr orp;
9958 CharPtr str;
9959
9960 if (biop == NULL) return;
9961 orp = biop->org;
9962 if (orp == NULL) return;
9963 if (StringHasNoText (orp->taxname)) return;
9964 len = StringLen (orp->taxname);
9965 onp = orp->orgname;
9966 if (onp == NULL) return;
9967 for (omp = onp->mod; omp != NULL; omp = omp->next) {
9968 if (omp->subtype != ORGMOD_authority) continue;
9969 if (StringNCmp (omp->subname, orp->taxname, len) == 0) continue;
9970 str = MemNew (StringLen (omp->subname) + len + 3);
9971 if (str == NULL) continue;
9972 StringCpy (str, orp->taxname);
9973 StringCat (str, " ");
9974 StringCat (str, omp->subname);
9975 omp->subname = MemFree (omp->subname);
9976 omp->subname = str;
9977 }
9978 }
9979
PrefixAuthorityWithOrganism(IteM i)9980 extern void PrefixAuthorityWithOrganism (IteM i)
9981
9982 {
9983 BaseFormPtr bfp;
9984 SeqEntryPtr sep;
9985
9986 #ifdef WIN_MAC
9987 bfp = currentFormDataPtr;
9988 #else
9989 bfp = GetObjectExtra (i);
9990 #endif
9991 if (bfp == NULL) return;
9992 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
9993 if (sep == NULL) return;
9994 VisitBioSourcesInSep (sep, NULL, DoAuthorityPrefix);
9995 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
9996 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
9997 }
9998
9999 typedef struct addtranslexceptdata {
10000 FEATURE_FORM_BLOCK
10001
10002 TexT cds_comment;
10003 ButtoN strict_checking_btn;
10004 ButtoN extend_btn;
10005 ButtoN adjust_gene_btn;
10006 CharPtr cds_comment_txt;
10007 Boolean strict_checking;
10008 Boolean extend;
10009 Boolean adjust_gene;
10010 } AddTranslExceptData, PNTR AddTranslExceptPtr;
10011
10012
10013
SeqLocForTermination(SeqLocPtr slp,Int4 except_len)10014 static SeqLocPtr SeqLocForTermination (SeqLocPtr slp, Int4 except_len)
10015 {
10016 SeqLocPtr term_slp;
10017 BioseqPtr bsp;
10018 Uint1 strand;
10019 Int4 end;
10020
10021 if (slp == NULL || except_len < 1 || except_len > 2) return NULL;
10022 bsp = BioseqFindFromSeqLoc (slp);
10023 if (bsp == NULL) return NULL;
10024
10025 strand = SeqLocStrand (slp);
10026 if (strand == Seq_strand_minus) {
10027 end = SeqLocStart (slp);
10028 term_slp = SeqLocIntNew (end, end + except_len - 1, strand, SeqIdDup (SeqIdFindBest (bsp->id, 0)));
10029 } else {
10030 end = SeqLocStop (slp);
10031 term_slp = SeqLocIntNew (end - except_len + 1, end, strand, SeqIdDup (SeqIdFindBest (bsp->id, 0)));
10032 }
10033 return term_slp;
10034 }
10035
10036
DoesCodingRegionEndWithStopCodon(SeqFeatPtr sfp)10037 static Boolean DoesCodingRegionEndWithStopCodon (SeqFeatPtr sfp)
10038 {
10039 ByteStorePtr bs;
10040 CharPtr prot_str;
10041 Boolean rval = FALSE;
10042
10043 bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
10044 prot_str = BSMerge (bs, NULL);
10045 bs = BSFree (bs);
10046 if (prot_str != NULL && prot_str[StringLen (prot_str) - 1] == '*') {
10047 rval = TRUE;
10048 }
10049 prot_str = MemFree (prot_str);
10050 return rval;
10051 }
10052
10053
AddTerminalExceptionLen(SeqFeatPtr sfp)10054 static Int4 AddTerminalExceptionLen (SeqFeatPtr sfp)
10055 {
10056 BioseqPtr bsp;
10057 Uint1 strand;
10058 Int4 stop, len, except_len = 0, gene_stop;
10059 Char buf[4];
10060 Int4 rval = 0;
10061 SeqFeatPtr gene;
10062
10063 if (sfp == NULL || sfp->location == NULL) return FALSE;
10064
10065 bsp = BioseqFindFromSeqLoc (sfp->location);
10066 if (bsp == NULL) return 0;
10067 strand = SeqLocStrand (sfp->location);
10068 if (strand == Seq_strand_minus) {
10069 stop = SeqLocStart (sfp->location);
10070 len = MIN (stop, 3);
10071 if (len > 0) {
10072 SeqPortStreamInt (bsp, stop - len, stop - 1,
10073 Seq_strand_minus,STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL,
10074 buf, NULL);
10075 }
10076 } else {
10077 stop = SeqLocStop (sfp->location);
10078 len = MIN (bsp->length - stop - 1, 3);
10079 if (len > 0) {
10080 SeqPortStreamInt (bsp, stop + 1, stop + len,
10081 Seq_strand_plus,STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL,
10082 buf, NULL);
10083 }
10084 }
10085 if (len > 0) {
10086 if (buf[0] == 'T') {
10087 except_len++;
10088 if (buf[1] == 'A') {
10089 except_len++;
10090 if (buf[2] == 'A') {
10091 /* has real stop codon */
10092 except_len++;
10093 }
10094 }
10095 }
10096 if (except_len < 3 && except_len > 0) {
10097 gene = GetGeneForFeature (sfp);
10098 if (strand == Seq_strand_minus) {
10099 if (gene != NULL) {
10100 gene_stop = SeqLocStart (gene->location);
10101 if (gene_stop > stop - except_len) {
10102 ExtendSeqLocToPosition (gene->location, FALSE, stop - except_len);
10103 }
10104 }
10105 ExtendSeqLocToPosition (sfp->location, FALSE, stop - except_len);
10106 } else {
10107 if (gene != NULL) {
10108 gene_stop = SeqLocStop (gene->location);
10109 if (gene_stop < stop + except_len) {
10110 ExtendSeqLocToPosition (gene->location, FALSE, stop + except_len);
10111 }
10112 }
10113 ExtendSeqLocToPosition (sfp->location, FALSE, stop + except_len);
10114 }
10115 rval = except_len;
10116 }
10117 }
10118 return rval;
10119 }
10120
10121
AddTranslExcept(SeqFeatPtr sfp,CharPtr cds_comment,Boolean use_strict,Boolean extend,Boolean adjust_gene)10122 extern void AddTranslExcept (SeqFeatPtr sfp, CharPtr cds_comment, Boolean use_strict, Boolean extend, Boolean adjust_gene)
10123
10124 {
10125 CdRegionPtr crp;
10126 Boolean partial5, partial3;
10127 Int4 dna_len;
10128 CharPtr bases;
10129 Int4 except_len;
10130 Int4 total;
10131 TransTablePtr tbl = NULL;
10132 Int2 state;
10133 CharPtr codon_start;
10134 CodeBreakPtr new_cbp, last_cbp;
10135 Boolean table_is_local;
10136 CharPtr new_comment;
10137 Int4 comment_len;
10138 SeqFeatPtr gene = NULL;
10139 SeqMgrFeatContext fcontext;
10140
10141 if (sfp == NULL
10142 || sfp->idx.subtype != FEATDEF_CDS
10143 || (crp = (CdRegionPtr)sfp->data.value.ptrvalue)== NULL) {
10144 return;
10145 }
10146
10147 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
10148 if (partial3) return;
10149
10150 dna_len = SeqLocLen (sfp->location);
10151 if (partial5 && crp->frame > 1) {
10152 except_len = (dna_len - crp->frame + 1) % 3;
10153 } else {
10154 except_len = dna_len % 3;
10155 }
10156
10157 /* if adjusting gene, collect now before location changes */
10158 if (adjust_gene) {
10159 gene = SeqMgrGetOverlappingGene (sfp->location, &fcontext);
10160 }
10161
10162 if (except_len == 0 && extend && !DoesCodingRegionEndWithStopCodon(sfp)) {
10163 except_len = AddTerminalExceptionLen (sfp);
10164 dna_len = SeqLocLen (sfp->location);
10165 }
10166
10167 if (except_len == 0) return;
10168
10169 /* don't add code break if one already exists */
10170 last_cbp = crp->code_break;
10171 if (last_cbp != NULL && last_cbp->aa.choice == 1 && last_cbp->aa.value.intvalue == 42) {
10172 last_cbp->loc = SeqLocFree (last_cbp->loc);
10173 last_cbp->loc = SeqLocForTermination (sfp->location, except_len);
10174 return;
10175 }
10176 while (last_cbp != NULL && last_cbp->next != NULL) {
10177 if (last_cbp->aa.choice == 1 && last_cbp->aa.value.intvalue == 42) {
10178 last_cbp->loc = SeqLocFree (last_cbp->loc);
10179 last_cbp->loc = SeqLocForTermination (sfp->location, except_len);
10180 return;
10181 }
10182 last_cbp = last_cbp->next;
10183 }
10184
10185 bases = ReadCodingRegionBases (sfp->location, dna_len, crp->frame, &total);
10186 if (bases == NULL) return;
10187
10188 /* don't add transl_except if cds has valid stop codon */
10189 state = 0;
10190 codon_start = bases + StringLen (bases) - 6;
10191 if (codon_start < bases) {
10192 MemFree (bases);
10193 return;
10194 }
10195 tbl = GetTranslationTable (crp, &table_is_local);
10196 state = 0;
10197 state = NextCodonState (tbl, state, (Uint1)*codon_start);
10198 state = NextCodonState (tbl, state, (Uint1)*(codon_start + 1));
10199 state = NextCodonState (tbl, state, (Uint1)*(codon_start + 2));
10200 if (IsOrfStop (tbl, state, TTBL_TOP_STRAND)) {
10201 MemFree (bases);
10202 if (table_is_local) {
10203 TransTableFree (tbl);
10204 }
10205 return;
10206 }
10207 if (table_is_local) {
10208 TransTableFree (tbl);
10209 tbl = NULL;
10210 }
10211
10212 if (use_strict)
10213 {
10214 if (except_len == 2)
10215 {
10216 if (toupper (*(codon_start + 3)) != 'T' || toupper(*(codon_start + 4)) != 'A')
10217 {
10218 MemFree (bases);
10219 return;
10220 }
10221 }
10222 else
10223 {
10224 if (toupper (*(codon_start + 3)) != 'T')
10225 {
10226 MemFree (bases);
10227 return;
10228 }
10229 }
10230
10231 }
10232 else
10233 {
10234 /* don't add transl_except if exception location does not start with 'T' or 'N' */
10235 if (*(codon_start + 3) != 'T' && *(codon_start + 3) != 't'
10236 && *(codon_start + 3) != 'N' && *(codon_start + 3) != 'n') {
10237 MemFree (bases);
10238 return;
10239 }
10240 }
10241 MemFree (bases);
10242
10243 new_cbp = CodeBreakNew ();
10244 new_cbp->aa.choice = 1;
10245 new_cbp->aa.value.intvalue = 42;
10246 new_cbp->loc = SeqLocForTermination (sfp->location, except_len);
10247
10248 /* add code break to end of list */
10249 if (last_cbp == NULL) {
10250 crp->code_break = new_cbp;
10251 } else {
10252 last_cbp->next = new_cbp;
10253 }
10254
10255 /* add comment if there is one, unless it's already there */
10256 if (cds_comment != NULL && StringISearch (sfp->comment, cds_comment) == NULL)
10257 {
10258 if (StringHasNoText (sfp->comment))
10259 {
10260 sfp->comment = MemFree (sfp->comment);
10261 sfp->comment = StringSave (cds_comment);
10262 }
10263 else
10264 {
10265 comment_len = StringLen (sfp->comment) + StringLen (cds_comment) + 3;
10266 new_comment = (CharPtr) MemNew (sizeof (Char) * comment_len);
10267 if (new_comment != NULL)
10268 {
10269 StringCpy (new_comment, sfp->comment);
10270 StringCat (new_comment, "; ");
10271 StringCat (new_comment, cds_comment);
10272 sfp->comment = MemFree (sfp->comment);
10273 sfp->comment = new_comment;
10274 }
10275 }
10276 }
10277
10278 /* adjust gene if requested */
10279 if (gene != NULL)
10280 {
10281 if (SeqLocCompare (gene->location, sfp->location) != SLC_A_EQ_B)
10282 {
10283 gene->location = SeqLocFree (gene->location);
10284 gene->location = SeqLocCopy (sfp->location);
10285 }
10286 }
10287 }
10288
10289
AddTranslExceptCallback(SeqFeatPtr sfp,Pointer userdata)10290 static void AddTranslExceptCallback (SeqFeatPtr sfp, Pointer userdata)
10291
10292 {
10293 AddTranslExceptPtr ap;
10294 Boolean use_strict = FALSE;
10295 Boolean extend = FALSE;
10296 Boolean adjust_gene = FALSE;
10297 CharPtr cds_comment = NULL;
10298
10299 ap = (AddTranslExceptPtr) userdata;
10300 if (ap != NULL)
10301 {
10302 cds_comment = ap->cds_comment_txt;
10303 use_strict = ap->strict_checking;
10304 extend = ap->extend;
10305 adjust_gene = ap->adjust_gene;
10306 }
10307
10308 AddTranslExcept (sfp, cds_comment, use_strict, extend, adjust_gene);
10309 }
10310
10311
DoAddTranslExceptWithComment(ButtoN b)10312 static void DoAddTranslExceptWithComment (ButtoN b)
10313 {
10314 AddTranslExceptPtr ap;
10315 SeqEntryPtr sep, oldscope;
10316
10317 ap = (AddTranslExceptPtr) GetObjectExtra (b);
10318 if (ap == NULL) return;
10319 Hide (ap->form);
10320 sep = GetTopSeqEntryForEntityID (ap->input_entityID);
10321 if (sep == NULL) return;
10322 oldscope = SeqEntrySetScope (sep);
10323 ap->cds_comment_txt = SaveStringFromText (ap->cds_comment);
10324 ap->strict_checking = GetStatus (ap->strict_checking_btn);
10325 ap->extend = GetStatus (ap->extend_btn);
10326 ap->adjust_gene = GetStatus (ap->adjust_gene_btn);
10327 if (StringHasNoText (ap->cds_comment_txt))
10328 {
10329 ap->cds_comment_txt = MemFree (ap->cds_comment_txt);
10330 }
10331 VisitFeaturesInSep (sep, ap, AddTranslExceptCallback);
10332 ObjMgrSetDirtyFlag (ap->input_entityID, TRUE);
10333 ObjMgrSendMsg (OM_MSG_UPDATE, ap->input_entityID, 0, 0);
10334 ap->cds_comment_txt = MemFree (ap->cds_comment_txt);
10335 Remove (ap->form);
10336 SeqEntrySetScope (oldscope);
10337 }
10338
ClearComment(ButtoN b)10339 static void ClearComment(ButtoN b)
10340 {
10341 AddTranslExceptPtr ap;
10342
10343 ap = (AddTranslExceptPtr) GetObjectExtra (b);
10344 if (ap != NULL) {
10345 SetTitle (ap->cds_comment, "");
10346 }
10347 }
10348
AddTranslExceptWithCommentBaseForm(BaseFormPtr bfp)10349 extern void AddTranslExceptWithCommentBaseForm (BaseFormPtr bfp)
10350 {
10351 AddTranslExceptPtr ap;
10352 WindoW w;
10353 GrouP h, g, c;
10354 ButtoN b, clear_btn;
10355
10356 if (bfp == NULL) return;
10357
10358 ap = (AddTranslExceptPtr) MemNew (sizeof (AddTranslExceptData));
10359 w = FixedWindow (-50, -33, -10, -10, "Add Translation Exception", NULL);
10360
10361 SetObjectExtra (w, ap, StdCleanupFormProc);
10362 ap->form = (ForM) w;
10363 ap->input_entityID = bfp->input_entityID;
10364
10365 h = HiddenGroup (w, -1, 0, NULL);
10366 SetGroupSpacing (h, 10, 10);
10367
10368 g = HiddenGroup (h, 2, 0, NULL);
10369 StaticPrompt (g, "CDS comment", 0, 0, programFont, 'c');
10370 ap->cds_comment = DialogText (g, "TAA stop codon is completed by the addition of 3' A residues to the mRNA", 20, NULL);
10371 clear_btn = PushButton (h, "Clear Comment", ClearComment);
10372 SetObjectExtra (clear_btn, ap, NULL);
10373 ap->strict_checking_btn = CheckBox (h, "Overhang must be T or TA", NULL);
10374 SetStatus (ap->strict_checking_btn, TRUE);
10375 ap->extend_btn = CheckBox (h, "Extend for T/TA overhang", NULL);
10376 ap->adjust_gene_btn = CheckBox (h, "Adjust gene to match coding region location", NULL);
10377 SetStatus (ap->adjust_gene_btn, TRUE);
10378
10379 c = HiddenGroup (h, 4, 0, NULL);
10380 b = DefaultButton (c, "Accept", DoAddTranslExceptWithComment);
10381 SetObjectExtra (b, ap, NULL);
10382 PushButton (c, "Cancel", StdCancelButtonProc);
10383 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) clear_btn,
10384 (HANDLE) ap->strict_checking_btn,
10385 (HANDLE) ap->extend_btn,
10386 (HANDLE) ap->adjust_gene_btn,
10387 (HANDLE) c, NULL);
10388 RealizeWindow (w);
10389 Show (w);
10390 Update ();
10391 }
10392
10393
AddTranslExceptWithComment(IteM i)10394 extern void AddTranslExceptWithComment (IteM i)
10395 {
10396 BaseFormPtr bfp;
10397
10398 #ifdef WIN_MAC
10399 bfp = currentFormDataPtr;
10400 #else
10401 bfp = GetObjectExtra (i);
10402 #endif
10403 if (bfp == NULL) return;
10404
10405 AddTranslExceptWithCommentBaseForm (bfp);
10406 }
10407
10408
10409 typedef struct updatealignmentlengths
10410 {
10411 Int4 aln_length; /* length of alignment */
10412 Int4 old5; /* length of 5' end of original sequence that is not
10413 * included in the alignment.
10414 */
10415 Int4 old3; /* length of 3' end of original sequence that is not
10416 * included in the alignment.
10417 */
10418 Int4 olda; /* length of update sequence that is included in the alignment. */
10419 Int4 new5; /* length of 5' end of update sequence that is not
10420 * included in the alignment.
10421 */
10422 Int4 new3; /* length of 3' end of update sequence that is not
10423 * included in the alignment.
10424 */
10425 Int4 newa; /* length of update sequence that is included in the alignment. */
10426
10427 Int4 log10_aln_length;
10428
10429 Int4 recomb1;
10430 Int4 recomb2;
10431 } UpdateAlignmentLengthsData, PNTR UpdateAlignmentLengthsPtr;
10432
10433 /* holds information about an update pair */
10434 typedef struct updatepair
10435 {
10436 SeqAlignPtr salp;
10437 Boolean revcomp;
10438 BioseqPtr orig_bsp;
10439 BioseqPtr update_bsp;
10440 Boolean feature_update_successful;
10441 SeqAnnotPtr newfeat_sap;
10442 } UpdatePairData, PNTR UpdatePairPtr;
10443
10444 /* These structures hold information about how to perform the updates.
10445 * The dialogs for displaying and collecting these structures are farther
10446 * down in the code.
10447 */
10448 typedef enum {
10449 eSequenceUpdateNoChange = 1,
10450 eSequenceUpdateReplace,
10451 eSequenceUpdatePatch,
10452 eSequenceUpdateExtend5,
10453 eSequenceUpdateExtend3
10454 } ESequenceUpdateType;
10455
10456 typedef enum {
10457 eFeatureUpdateNoChange = 1,
10458 eFeatureUpdateAllExceptDups,
10459 eFeatureUpdateAllMergeDups,
10460 eFeatureUpdateAllReplaceDups,
10461 eFeatureUpdateAll
10462 } EFeatureUpdateType;
10463
10464 typedef enum {
10465 eFeatureRemoveNone = 1,
10466 eFeatureRemoveAligned,
10467 eFeatureRemoveNotAligned,
10468 eFeatureRemoveAll
10469 } EFeatureRemoveType;
10470
10471 typedef struct featureimportoptions
10472 {
10473 Uint1 feature_import_type;
10474 ValNodePtr feature_types;
10475 } FeatureImportOptionsData, PNTR FeatureImportOptionsPtr;
10476
10477
FeatureImportOptionsNew(void)10478 static FeatureImportOptionsPtr FeatureImportOptionsNew (void)
10479 {
10480 FeatureImportOptionsPtr f;
10481
10482 f = (FeatureImportOptionsPtr) MemNew (sizeof (FeatureImportOptionsData));
10483 f->feature_import_type = eFeatureUpdateNoChange;
10484 f->feature_types = NULL;
10485 return f;
10486 }
10487
10488
FeatureImportOptionsFree(FeatureImportOptionsPtr f)10489 static FeatureImportOptionsPtr FeatureImportOptionsFree (FeatureImportOptionsPtr f)
10490 {
10491 if (f != NULL) {
10492 f->feature_types = ValNodeFree (f->feature_types);
10493 f = MemFree (f);
10494 }
10495 return f;
10496 }
10497
10498
10499 typedef struct submitterupdateoptions
10500 {
10501 ESequenceUpdateType sequence_update_type;
10502 FeatureImportOptionsPtr feature_import_options;
10503 EFeatureRemoveType feature_remove_type;
10504 Boolean ignore_alignment;
10505 } SubmitterUpdateOptionsData, PNTR SubmitterUpdateOptionsPtr;
10506
10507
SubmitterUpdateOptionsFree(SubmitterUpdateOptionsPtr s)10508 static SubmitterUpdateOptionsPtr SubmitterUpdateOptionsFree (SubmitterUpdateOptionsPtr s)
10509 {
10510 if (s != NULL) {
10511 s->feature_import_options = FeatureImportOptionsFree(s->feature_import_options);
10512 s = MemFree (s);
10513 }
10514 return s;
10515 }
10516
10517
AreSubmitterOptsValid(SubmitterUpdateOptionsPtr opts)10518 static Boolean AreSubmitterOptsValid (SubmitterUpdateOptionsPtr opts)
10519 {
10520 if (opts == NULL
10521 || (opts->sequence_update_type == eSequenceUpdateNoChange
10522 && (opts->feature_import_options == NULL
10523 || opts->feature_import_options->feature_import_type == eFeatureUpdateNoChange
10524 || opts->feature_import_options->feature_import_type == eFeatureRemoveNone)))
10525 {
10526 return FALSE;
10527 } else {
10528 return TRUE;
10529 }
10530 }
10531
10532
10533 typedef struct indexer_options
10534 {
10535 Boolean keep_protein_ids;
10536 Boolean add_cit_subs;
10537 Boolean update_quality_scores;
10538 Boolean update_proteins;
10539 Boolean truncate_proteins;
10540 Boolean extend_proteins3;
10541 Boolean extend_proteins5;
10542 Boolean correct_cds_genes;
10543 } IndexerOptionsData, PNTR IndexerOptionsPtr;
10544
10545 typedef struct updateoptions
10546 {
10547 SubmitterUpdateOptionsPtr submitter_opts;
10548 IndexerOptionsPtr indexer_opts;
10549 } UpdateOptionsData, PNTR UpdateOptionsPtr;
10550
UpdateOptionsFree(UpdateOptionsPtr uop)10551 static UpdateOptionsPtr UpdateOptionsFree (UpdateOptionsPtr uop)
10552 {
10553 if (uop != NULL)
10554 {
10555 uop->submitter_opts = SubmitterUpdateOptionsFree (uop->submitter_opts);
10556 uop->indexer_opts = MemFree (uop->indexer_opts);
10557 uop = MemFree (uop);
10558 }
10559 return uop;
10560 }
10561
10562 /* These functions remove features from portions of the updated sequence:
10563 * RemoveFeatsInAlignedRegion
10564 * RemoveFeatsNotInAlignedRegion
10565 */
10566 static Boolean
RemoveFeatsInAlignedRegion(BioseqPtr orig_bsp,UpdateAlignmentLengthsPtr ualp)10567 RemoveFeatsInAlignedRegion
10568 (BioseqPtr orig_bsp,
10569 UpdateAlignmentLengthsPtr ualp)
10570
10571 {
10572 SeqMgrFeatContext context;
10573 Int4 left, right;
10574 SeqFeatPtr sfp;
10575 Boolean rval = FALSE;
10576
10577 if (orig_bsp == NULL || ualp == NULL) return FALSE;
10578
10579 left = ualp->old5;
10580 right = ualp->old5 + ualp->olda;
10581
10582 sfp = SeqMgrGetNextFeature (orig_bsp, NULL, 0, 0, &context);
10583
10584 while (sfp != NULL) {
10585
10586 if (context.right >= left && context.left <= right) {
10587 sfp->idx.deleteme = TRUE;
10588 rval = TRUE;
10589 MarkProductForDeletion (sfp->product);
10590 }
10591
10592 sfp = SeqMgrGetNextFeature (orig_bsp, sfp, 0, 0, &context);
10593 }
10594 return rval;
10595 }
10596
10597 static Boolean
RemoveFeatsNotInAlignedRegion(BioseqPtr orig_bsp,UpdateAlignmentLengthsPtr ualp)10598 RemoveFeatsNotInAlignedRegion
10599 (BioseqPtr orig_bsp,
10600 UpdateAlignmentLengthsPtr ualp)
10601
10602 {
10603 SeqMgrFeatContext context;
10604 Int4 left, right;
10605 SeqFeatPtr sfp;
10606 Boolean rval = FALSE;
10607
10608 if (orig_bsp == NULL || ualp == NULL) return FALSE;
10609
10610 left = ualp->old5;
10611 right = ualp->old5 + ualp->olda;
10612
10613 sfp = SeqMgrGetNextFeature (orig_bsp, NULL, 0, 0, &context);
10614
10615 while (sfp != NULL) {
10616
10617 if (context.right < left || context.left > right) {
10618 sfp->idx.deleteme = TRUE;
10619 rval = TRUE;
10620 MarkProductForDeletion (sfp->product);
10621 }
10622
10623 sfp = SeqMgrGetNextFeature (orig_bsp, sfp, 0, 0, &context);
10624 }
10625 return rval;
10626 }
10627
10628 /* This function adjusts an alignment based on updates to the sequence. */
ShiftAlignmentForUpdate(SeqAlignPtr sap,UpdateAlignmentLengthsPtr ualp,ESequenceUpdateType choice)10629 static Boolean ShiftAlignmentForUpdate
10630 (SeqAlignPtr sap,
10631 UpdateAlignmentLengthsPtr ualp,
10632 ESequenceUpdateType choice)
10633
10634 {
10635 DenseSegPtr dsp;
10636 Int2 j;
10637
10638 if (ualp == NULL || sap == NULL) return FALSE;
10639
10640 AMFreeAllIndexes (sap);
10641
10642 if (sap->segtype == SAS_DENSEG) {
10643 dsp = (DenseSegPtr) sap->segs;
10644
10645 switch (choice) {
10646 case eSequenceUpdateExtend5 :
10647 /* adjust alignment 5' */
10648 if (dsp != NULL && dsp->lens != NULL && dsp->numseg > 0) {
10649 dsp->lens [dsp->numseg - 1] += ualp->old3;
10650 }
10651 break;
10652 case eSequenceUpdateExtend3 :
10653 /* adjust alignment 3' */
10654 if (dsp != NULL && dsp->lens != NULL && dsp->starts != NULL && dsp->numseg > 0) {
10655 dsp->lens [0] += ualp->old5;
10656 dsp->starts [0] = 0;
10657 dsp->starts [1] = 0;
10658 for (j = 1; j < dsp->numseg; j++) {
10659 if (dsp->starts [1 + j * 2] != -1) {
10660 dsp->starts [1 + j * 2] += ualp->old5 - ualp->new5;
10661 }
10662 }
10663 }
10664 break;
10665 case eSequenceUpdatePatch :
10666 /* adjust alignment patch */
10667 if (dsp != NULL && dsp->lens != NULL && dsp->starts != NULL && dsp->numseg > 0) {
10668 dsp->lens [dsp->numseg - 1] += ualp->old3;
10669 dsp->lens [0] += ualp->old5;
10670 dsp->starts [0] = 0;
10671 dsp->starts [1] = 0;
10672 for (j = 1; j < dsp->numseg; j++) {
10673 if (dsp->starts [1 + j * 2] != -1) {
10674 dsp->starts [1 + j * 2] += ualp->old5 - ualp->new5;
10675 }
10676 }
10677 }
10678 break;
10679 default :
10680 break;
10681 }
10682 }
10683
10684 AlnMgr2IndexSingleChildSeqAlign (sap);
10685
10686 return TRUE;
10687 }
10688
10689 /* This function shifts the position of features on the updated sequence based on
10690 * the number of nucleotides added upstream.
10691 */
10692 static Boolean
ShiftFeaturesForUpdate(BioseqPtr orig_bsp,BioseqPtr update_bsp,Int4 offset)10693 ShiftFeaturesForUpdate
10694 (BioseqPtr orig_bsp,
10695 BioseqPtr update_bsp,
10696 Int4 offset)
10697
10698 {
10699 CodeBreakPtr cbp;
10700 SeqMgrFeatContext context;
10701 CdRegionPtr crp;
10702 Int4 len;
10703 RnaRefPtr rrp;
10704 Uint1 seq_data_type;
10705 SeqFeatPtr sfp;
10706 SeqIdPtr sip;
10707 tRNAPtr trp;
10708 SeqDataPtr sdp;
10709
10710 if (orig_bsp == NULL || update_bsp == NULL)
10711 {
10712 return FALSE;
10713 }
10714
10715 sip = SeqIdFindBest (orig_bsp->id, 0);
10716 if (sip == NULL) return FALSE;
10717
10718 if (offset > 0) {
10719 sfp = SeqMgrGetNextFeature (orig_bsp, NULL, 0, 0, &context);
10720 while (sfp != NULL) {
10721 OffsetLocation (sfp->location, offset, sip);
10722 switch (sfp->data.choice) {
10723 case SEQFEAT_CDREGION :
10724 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
10725 if (crp != NULL) {
10726 for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
10727 OffsetLocation (cbp->loc, offset, sip);
10728 }
10729 }
10730 break;
10731 case SEQFEAT_RNA :
10732 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
10733 if (rrp != NULL && rrp->ext.choice == 2) {
10734 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
10735 if (trp != NULL && trp->anticodon != NULL) {
10736 OffsetLocation (trp->anticodon, offset, sip);
10737 }
10738 }
10739 break;
10740 default :
10741 break;
10742 }
10743 sfp = SeqMgrGetNextFeature (orig_bsp, sfp, 0, 0, &context);
10744 }
10745 }
10746
10747 /* switch bioseqs to finish extension */
10748
10749 sdp = orig_bsp->seq_data;
10750 orig_bsp->seq_data = update_bsp->seq_data;
10751 update_bsp->seq_data = sdp;
10752 len = orig_bsp->length;
10753 orig_bsp->length = update_bsp->length;
10754 update_bsp->length = len;
10755 seq_data_type = orig_bsp->seq_data_type;
10756 orig_bsp->seq_data_type = update_bsp->seq_data_type;
10757 update_bsp->seq_data_type = seq_data_type;
10758
10759 return TRUE;
10760 }
10761
ReadLongDataToString(SeqPortPtr spp,Int4 how_much,CharPtr str)10762 static Int4 ReadLongDataToString (SeqPortPtr spp, Int4 how_much, CharPtr str)
10763 {
10764 Int4 ctr = 0, left_to_read, read_this;
10765
10766 if (spp == NULL || str == NULL)
10767 {
10768 return 0;
10769 }
10770 left_to_read = how_much;
10771 while (left_to_read > 0)
10772 {
10773 read_this = SeqPortRead (spp, (Uint1Ptr)(str + ctr), MIN (left_to_read, INT2_MAX));
10774 left_to_read -= read_this;
10775 ctr += read_this;
10776 }
10777 return ctr;
10778 }
10779
SeqLitFromBioseq(BioseqPtr bsp,Int4 start,Int4 stop)10780 static SeqLitPtr SeqLitFromBioseq (BioseqPtr bsp, Int4 start, Int4 stop)
10781 {
10782 CharPtr str;
10783 SeqLitPtr slip;
10784 Uint1 seqcode;
10785 SeqPortPtr spp;
10786 Int4 ctr;
10787
10788 if (bsp == NULL || bsp->length < 1 || start < 0 || stop >= bsp->length)
10789 {
10790 return NULL;
10791 }
10792
10793 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (stop - start + 5));
10794 if (str == NULL)
10795 return NULL;
10796
10797 if (ISA_na (bsp->mol))
10798 {
10799 seqcode = Seq_code_iupacna;
10800 }
10801 else
10802 {
10803 seqcode = Seq_code_iupacaa;
10804 }
10805
10806 slip = SeqLitNew ();
10807
10808 slip->seq_data_type = seqcode;
10809 slip->length = stop - start + 1;
10810 slip->seq_data = (SeqDataPtr) BSNew (slip->length);
10811
10812 /* copy in the data */
10813 spp = SeqPortNew(bsp, start, stop, Seq_strand_plus, seqcode);
10814 ctr = ReadLongDataToString (spp, stop - start + 1, str);
10815 spp = SeqPortFree (spp);
10816 str[ctr] = '\0';
10817
10818 BSWrite ((ByteStorePtr) slip->seq_data, (VoidPtr) str, stop - start + 1);
10819 return slip;
10820 }
10821
DeltaSeqListFree(DeltaSeqPtr list)10822 static DeltaSeqPtr DeltaSeqListFree (DeltaSeqPtr list)
10823 {
10824 DeltaSeqPtr dsp;
10825 SeqLitPtr slip;
10826
10827 dsp = list;
10828 while (dsp != NULL)
10829 {
10830 slip = (SeqLitPtr) (dsp->data.ptrvalue);
10831 SeqLitFree (slip);
10832 dsp = dsp->next;
10833 }
10834 ValNodeFree (list);
10835 return NULL;
10836 }
10837
10838 static Boolean
UpdateSequenceExtendDelta5Prime(UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp)10839 UpdateSequenceExtendDelta5Prime
10840 (UpdatePairPtr upp,
10841 UpdateAlignmentLengthsPtr ualp)
10842
10843 {
10844 Int4 currold_pos;
10845 SeqLitPtr slip, slip_new;
10846 DeltaSeqPtr dspold, dspnew, dspold_prev;
10847 Int4 seqstart;
10848 DeltaSeqPtr new_list = NULL;
10849
10850 if (upp == NULL
10851 || upp->orig_bsp == NULL
10852 || upp->update_bsp == NULL
10853 || (upp->orig_bsp->repr != Seq_repr_delta && upp->update_bsp->repr != Seq_repr_delta)
10854 || (upp->orig_bsp->repr == Seq_repr_delta && upp->orig_bsp->seq_ext_type != 4)
10855 || (upp->update_bsp->repr == Seq_repr_delta && upp->update_bsp->seq_ext_type != 4))
10856 {
10857 return FALSE;
10858 }
10859
10860 /* copy in entire new sequence */
10861 if (upp->update_bsp->repr == Seq_repr_delta)
10862 {
10863 dspnew = (DeltaSeqPtr) upp->update_bsp->seq_ext;
10864 while (dspnew != NULL)
10865 {
10866 if (dspnew->data.ptrvalue == NULL || dspnew->choice != 2)
10867 {
10868 return FALSE;
10869 }
10870 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
10871 slip_new = (SeqLitPtr) AsnIoMemCopy (slip, (AsnReadFunc) SeqLitAsnRead,
10872 (AsnWriteFunc) SeqLitAsnWrite);
10873
10874 ValNodeAddPointer (&new_list, 2, slip_new);
10875 dspnew = dspnew->next;
10876 }
10877 }
10878 else
10879 {
10880 slip = SeqLitFromBioseq (upp->update_bsp, 0, upp->update_bsp->length - 1);
10881 if (slip == NULL)
10882 {
10883 return FALSE;
10884 }
10885 ValNodeAddPointer (&new_list, 2, slip);
10886 }
10887
10888 /* now copy in old sequence, all if no alignment, after alignment if present */
10889 if (upp->orig_bsp->repr == Seq_repr_delta)
10890 {
10891 if (upp->salp == NULL)
10892 {
10893 ValNodeLink (&new_list, upp->orig_bsp->seq_ext);
10894 upp->orig_bsp->seq_ext = new_list;
10895 upp->orig_bsp->length += upp->update_bsp->length;
10896 }
10897 else
10898 {
10899 /* skip over old 5 and aligned area */
10900 dspold = (DeltaSeqPtr) upp->orig_bsp->seq_ext;
10901 currold_pos = 0;
10902 dspold_prev = NULL;
10903 while (dspold != NULL && currold_pos < ualp->old5 + ualp->olda)
10904 {
10905 seqstart = currold_pos;
10906 if (dspold->data.ptrvalue == NULL || dspold->choice != 2)
10907 {
10908 return FALSE;
10909 }
10910 slip = (SeqLitPtr) (dspold->data.ptrvalue);
10911 currold_pos += slip->length;
10912 if (currold_pos > ualp->old5 + ualp->olda)
10913 {
10914 SplitDeltaSeq (dspold, ualp->old5 + ualp->olda - seqstart);
10915 slip = (SeqLitPtr) (dspold->data.ptrvalue);
10916 currold_pos = ualp->old5 + ualp->olda;
10917 }
10918 dspold_prev = dspold;
10919 dspold = dspold->next;
10920 }
10921 if (dspold_prev == NULL)
10922 {
10923 ValNodeLink (&new_list, upp->orig_bsp->seq_ext);
10924 }
10925 else
10926 {
10927 /* attach remainder of list to new list */
10928 ValNodeLink (&new_list, dspold);
10929 dspold_prev->next = NULL;
10930
10931 /* free dsps in old sequence that are being replaced */
10932 upp->orig_bsp->seq_ext = DeltaSeqListFree (upp->orig_bsp->seq_ext);
10933
10934 /* put new list in place */
10935 upp->orig_bsp->seq_ext = new_list;
10936 }
10937 upp->orig_bsp->length = ualp->new5 + ualp->newa + ualp->old3;
10938 }
10939 }
10940 else
10941 {
10942 if (upp->salp == NULL)
10943 {
10944 slip = SeqLitFromBioseq (upp->orig_bsp, 0, upp->orig_bsp->length - 1);
10945 }
10946 else
10947 {
10948 slip = SeqLitFromBioseq (upp->orig_bsp, ualp->old5 + ualp->olda, upp->orig_bsp->length - 1);
10949 }
10950 if (slip == NULL)
10951 {
10952 return FALSE;
10953 }
10954 ValNodeAddPointer (&new_list, 2, slip);
10955 upp->orig_bsp->seq_data = SeqDataFree (upp->orig_bsp->seq_data, upp->orig_bsp->seq_data_type);
10956 upp->orig_bsp->seq_ext = new_list;
10957 upp->orig_bsp->repr = Seq_repr_delta;
10958
10959 upp->orig_bsp->length = ualp->new5 + ualp->newa + ualp->old3;
10960 }
10961
10962 return TRUE;
10963 }
10964
10965 static Boolean
UpdateSequenceExtend5Prime(UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp)10966 UpdateSequenceExtend5Prime
10967 (UpdatePairPtr upp,
10968 UpdateAlignmentLengthsPtr ualp)
10969
10970 {
10971 ByteStorePtr bs;
10972 Int4 newlen;
10973 CharPtr str;
10974 SeqPortPtr spp;
10975 Uint1 seqcode;
10976 Int4 ctr;
10977 Boolean rval;
10978 Int4 shift_len = 0;
10979
10980 if (upp == NULL || upp->orig_bsp == NULL || upp->update_bsp == NULL || ualp == NULL)
10981 {
10982 return FALSE;
10983 }
10984
10985 if (upp->orig_bsp->repr == Seq_repr_delta
10986 || upp->update_bsp->repr == Seq_repr_delta)
10987 {
10988 return UpdateSequenceExtendDelta5Prime (upp, ualp);
10989 }
10990
10991 if (upp->salp == NULL)
10992 {
10993 /* add to 5' end */
10994 newlen = upp->update_bsp->length + upp->orig_bsp->length;
10995 shift_len = upp->update_bsp->length;
10996 }
10997 else
10998 {
10999 /* construct replacement sequence by recombining between old and overlap */
11000 newlen = ualp->new5 + ualp->newa + ualp->old3;
11001 shift_len = ualp->new5;
11002 }
11003
11004 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
11005 if (str == NULL)
11006 return FALSE;
11007
11008 if (ISA_na (upp->orig_bsp->mol))
11009 {
11010 seqcode = Seq_code_iupacna;
11011 }
11012 else
11013 {
11014 seqcode = Seq_code_iupacaa;
11015 }
11016
11017 if (upp->salp == NULL)
11018 {
11019 /* add new sequence */
11020 spp = SeqPortNew(upp->update_bsp, 0, upp->update_bsp->length - 1, Seq_strand_plus, seqcode);
11021 ctr = ReadLongDataToString (spp, upp->update_bsp->length, str);
11022 spp = SeqPortFree (spp);
11023 /* add old sequence */
11024 spp = SeqPortNew(upp->orig_bsp, 0,upp-> orig_bsp->length - 1, Seq_strand_plus, seqcode);
11025 ctr += ReadLongDataToString(spp, upp->orig_bsp->length, str + ctr);
11026 spp = SeqPortFree (spp);
11027 }
11028 else
11029 {
11030 /* take new 5' and aligned middle */
11031 spp = SeqPortNew(upp->update_bsp, 0, ualp->new5 + ualp->newa - 1, Seq_strand_plus, seqcode);
11032 ctr = ReadLongDataToString (spp, ualp->new5 + ualp->newa, str);
11033 spp = SeqPortFree (spp);
11034 /* take old 3' end */
11035 if (ualp->old3 > 0)
11036 {
11037 spp = SeqPortNew(upp->orig_bsp, ualp->old5 + ualp->olda, upp->orig_bsp->length - 1, Seq_strand_plus, seqcode);
11038 ctr += ReadLongDataToString (spp, ualp->old3, str + ctr);
11039 spp = SeqPortFree (spp);
11040 }
11041 }
11042
11043 str[ctr] = '\0';
11044
11045 bs = BSNew (newlen);
11046 BSWrite (bs, (VoidPtr) str, newlen);
11047
11048 if (bs != NULL && BSLen (bs) < 1) {
11049 bs = BSFree (bs);
11050 }
11051 if (bs == NULL) return FALSE;
11052
11053 /* overlap turned into replacement sequence */
11054
11055 upp->update_bsp->seq_data = SeqDataFree (upp->update_bsp->seq_data, upp->update_bsp->seq_data_type);
11056 upp->update_bsp->seq_data = (SeqDataPtr) bs;
11057 upp->update_bsp->seq_data_type = seqcode;
11058 upp->update_bsp->length = newlen;
11059
11060
11061 if (upp->salp == NULL)
11062 {
11063 /* then finish by replacing with new sequence */
11064 rval = ShiftFeaturesForUpdate (upp->orig_bsp, upp->update_bsp, shift_len);
11065 }
11066 else
11067 {
11068 /* adjust alignment and reindex */
11069 rval = ShiftAlignmentForUpdate (upp->salp, ualp, eSequenceUpdateExtend5);
11070 if (rval)
11071 {
11072 /* then finish by replacing with new sequence */
11073 ReplaceOneSequence (upp->salp, upp->orig_bsp, upp->update_bsp);
11074 }
11075 }
11076
11077 return rval;
11078 }
11079
11080 static Boolean
UpdateSequenceExtendDelta3Prime(UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp)11081 UpdateSequenceExtendDelta3Prime
11082 (UpdatePairPtr upp,
11083 UpdateAlignmentLengthsPtr ualp)
11084
11085 {
11086 Int4 currnew_pos = 0, currold_pos;
11087 SeqLitPtr slip, slip_new;
11088 DeltaSeqPtr dspold, dspnew, dspold_prev;
11089 Int4 seqstart;
11090 DeltaSeqPtr new_list = NULL;
11091
11092 if (upp == NULL
11093 || upp->orig_bsp == NULL
11094 || upp->update_bsp == NULL
11095 || (upp->orig_bsp->repr != Seq_repr_delta && upp->update_bsp->repr != Seq_repr_delta)
11096 || (upp->orig_bsp->repr == Seq_repr_delta && upp->orig_bsp->seq_ext_type != 4)
11097 || (upp->update_bsp->repr == Seq_repr_delta && upp->update_bsp->seq_ext_type != 4))
11098 {
11099 return FALSE;
11100 }
11101
11102 /* retain 5' end of original sequence */
11103 if (upp->orig_bsp->repr == Seq_repr_delta)
11104 {
11105 if (upp->salp == NULL)
11106 {
11107 /* do nothing, keep the entire sequence */
11108 }
11109 else
11110 {
11111 /* discard the portion after the old 5' */
11112 dspold_prev = NULL;
11113 dspold = (DeltaSeqPtr) upp->orig_bsp->seq_ext;
11114 currold_pos = 0;
11115 while (dspold != NULL && currold_pos < ualp->old5)
11116 {
11117 seqstart = currold_pos;
11118 if (dspold->data.ptrvalue == NULL || dspold->choice != 2)
11119 {
11120 return FALSE;
11121 }
11122 slip = (SeqLitPtr) (dspold->data.ptrvalue);
11123 currold_pos += slip->length;
11124 if (currold_pos > ualp->old5)
11125 {
11126 SplitDeltaSeq (dspold, ualp->old5 - seqstart);
11127 slip = (SeqLitPtr) (dspold->data.ptrvalue);
11128 currold_pos = ualp->old5;
11129 }
11130 dspold_prev = dspold;
11131 dspold = dspold->next;
11132 }
11133
11134 if (dspold_prev == NULL)
11135 {
11136 /* discard the entire sequence */
11137 upp->orig_bsp->seq_ext = DeltaSeqListFree (upp->orig_bsp->seq_ext);
11138 }
11139 else
11140 {
11141 dspold_prev->next = DeltaSeqListFree (dspold_prev->next);
11142 }
11143 }
11144 }
11145 else
11146 {
11147 if (upp->salp == NULL)
11148 {
11149 slip = SeqLitFromBioseq (upp->orig_bsp, 0, upp->orig_bsp->length - 1);
11150 }
11151 else
11152 {
11153 slip = SeqLitFromBioseq (upp->orig_bsp, 0, ualp->old5);
11154 }
11155 upp->orig_bsp->seq_data = SeqDataFree (upp->orig_bsp->seq_data, upp->orig_bsp->seq_data_type);
11156 new_list = upp->orig_bsp->seq_ext;
11157 ValNodeAddPointer (&new_list, 2, slip);
11158 upp->orig_bsp->seq_ext = new_list;
11159 upp->orig_bsp->repr = Seq_repr_delta;
11160 }
11161
11162
11163 /* now add in new sequence */
11164 if (upp->update_bsp->repr == Seq_repr_delta)
11165 {
11166 /* skip over new5 */
11167 dspnew = (DeltaSeqPtr) upp->update_bsp->seq_ext;
11168 currnew_pos = 0;
11169 if (upp->salp != NULL)
11170 {
11171 while (dspnew != NULL && currnew_pos < ualp->new5)
11172 {
11173 seqstart = currnew_pos;
11174 if (dspnew->data.ptrvalue == NULL || dspnew->choice != 2)
11175 {
11176 return FALSE;
11177 }
11178 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
11179 currnew_pos += slip->length;
11180 if (currnew_pos > ualp->new5)
11181 {
11182 SplitDeltaSeq (dspnew, ualp->old5 - seqstart);
11183 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
11184 currnew_pos = ualp->new5;
11185 }
11186 dspnew = dspnew->next;
11187 }
11188 }
11189
11190 while (dspnew != NULL)
11191 {
11192 if (dspnew->data.ptrvalue == NULL || dspnew->choice != 2)
11193 {
11194 return FALSE;
11195 }
11196 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
11197 slip_new = (SeqLitPtr) AsnIoMemCopy (slip, (AsnReadFunc) SeqLitAsnRead,
11198 (AsnWriteFunc) SeqLitAsnWrite);
11199 new_list = upp->orig_bsp->seq_ext;
11200 ValNodeAddPointer (&new_list, 2, slip_new);
11201 upp->orig_bsp->seq_ext = new_list;
11202 dspnew = dspnew->next;
11203 }
11204 }
11205 else
11206 {
11207 if (upp->salp == NULL)
11208 {
11209 slip = SeqLitFromBioseq (upp->update_bsp, 0, upp->update_bsp->length - 1);
11210 }
11211 else
11212 {
11213 slip = SeqLitFromBioseq (upp->orig_bsp, ualp->new5, upp->update_bsp->length - 1);
11214 }
11215 new_list = upp->orig_bsp->seq_ext;
11216 ValNodeAddPointer (&new_list, 2, slip);
11217 upp->orig_bsp->seq_ext = new_list;
11218 }
11219
11220 if (upp->salp == NULL)
11221 {
11222 upp->orig_bsp->length = upp->orig_bsp->length + upp->update_bsp->length;
11223 }
11224 else
11225 {
11226 upp->orig_bsp->length = ualp->old5 + ualp->newa + ualp->new3;
11227 }
11228
11229 return TRUE;
11230 }
11231
11232 static Boolean
UpdateSequenceExtend3Prime(UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp)11233 UpdateSequenceExtend3Prime
11234 (UpdatePairPtr upp,
11235 UpdateAlignmentLengthsPtr ualp)
11236 {
11237 ByteStorePtr bs;
11238 Int4 newlen;
11239 CharPtr str;
11240 SeqPortPtr spp;
11241 Uint1 seqcode;
11242 Int4 ctr;
11243 Boolean rval;
11244
11245 if (upp == NULL || upp->orig_bsp == NULL || upp->update_bsp == NULL || ualp == NULL)
11246 {
11247 return FALSE;
11248 }
11249
11250 if (upp->orig_bsp->repr == Seq_repr_delta
11251 || upp->update_bsp->repr == Seq_repr_delta)
11252 {
11253 return UpdateSequenceExtendDelta3Prime (upp, ualp);
11254 }
11255
11256 /* construct replacement sequence by recombining between old and overlap */
11257 if (upp->salp == NULL)
11258 {
11259 newlen = upp->orig_bsp->length + upp->update_bsp->length;
11260 }
11261 else
11262 {
11263 newlen = ualp->old5 + ualp->newa + ualp->new3;
11264 }
11265
11266 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
11267 if (str == NULL)
11268 return FALSE;
11269
11270 if (ISA_na (upp->orig_bsp->mol))
11271 {
11272 seqcode = Seq_code_iupacna;
11273 }
11274 else
11275 {
11276 seqcode = Seq_code_iupacaa;
11277 }
11278
11279 if (upp->salp == NULL)
11280 {
11281 /* add old sequence */
11282 spp = SeqPortNew(upp->orig_bsp, 0, upp->orig_bsp->length - 1, Seq_strand_plus, seqcode);
11283 ctr = ReadLongDataToString (spp, upp->orig_bsp->length, str);
11284 spp = SeqPortFree (spp);
11285 /* add new sequence */
11286 spp = SeqPortNew(upp->update_bsp, 0, upp->update_bsp->length - 1, Seq_strand_plus, seqcode);
11287 ctr += ReadLongDataToString (spp, upp->update_bsp->length, str + ctr);
11288 spp = SeqPortFree (spp);
11289 }
11290 else
11291 {
11292 /* take old 5' */
11293 spp = SeqPortNew(upp->orig_bsp, 0, ualp->old5 - 1, Seq_strand_plus, seqcode);
11294 ctr = ReadLongDataToString(spp, ualp->old5, str);
11295 spp = SeqPortFree (spp);
11296 /* take aligned middle and new 3' end */
11297 spp = SeqPortNew(upp->update_bsp, ualp->new5, upp->update_bsp->length - 1, Seq_strand_plus, seqcode);
11298 ctr += ReadLongDataToString (spp, ualp->newa + ualp->new3, str + ctr);
11299 spp = SeqPortFree (spp);
11300 }
11301
11302 str[ctr] = '\0';
11303
11304 bs = BSNew (newlen);
11305 BSWrite (bs, (VoidPtr) str, newlen);
11306
11307 if (bs != NULL && BSLen (bs) < 1) {
11308 bs = BSFree (bs);
11309 }
11310 if (bs == NULL) return FALSE;
11311
11312 /* overlap turned into replacement sequence */
11313
11314 upp->update_bsp->seq_data = SeqDataFree (upp->update_bsp->seq_data, upp->update_bsp->seq_data_type);
11315 upp->update_bsp->seq_data = (SeqDataPtr) bs;
11316 upp->update_bsp->seq_data_type = Seq_code_iupacna;
11317 upp->update_bsp->length = newlen;
11318
11319 if (upp->salp == NULL)
11320 {
11321 /* then finish by replacing with new sequence */
11322 rval = ShiftFeaturesForUpdate (upp->orig_bsp, upp->update_bsp, 0);
11323 }
11324 else
11325 {
11326 /* adjust alignment and reindex */
11327 rval = ShiftAlignmentForUpdate (upp->salp, ualp, eSequenceUpdateExtend3);
11328 if (rval)
11329 {
11330 /* then finish by replacing with new sequence */
11331 ReplaceOneSequence (upp->salp, upp->orig_bsp, upp->update_bsp);
11332 }
11333 }
11334
11335 return rval;
11336 }
11337
RawSequencePatchOk(BioseqPtr orig_bsp,BioseqPtr update_bsp)11338 static Boolean RawSequencePatchOk (BioseqPtr orig_bsp, BioseqPtr update_bsp)
11339 {
11340 Boolean rval = TRUE;
11341
11342 if (orig_bsp == NULL || update_bsp == NULL
11343 || orig_bsp->repr != Seq_repr_raw
11344 || update_bsp->repr != Seq_repr_raw)
11345 {
11346 rval = FALSE;
11347 }
11348
11349 return rval;
11350 }
11351
11352 /* this replaces just the middle */
11353 static Boolean
UpdateSequencePatchRaw(UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp)11354 UpdateSequencePatchRaw
11355 (UpdatePairPtr upp,
11356 UpdateAlignmentLengthsPtr ualp)
11357
11358 {
11359 ByteStorePtr bs;
11360 Int4 newlen;
11361 CharPtr str;
11362 Uint1 seqcode;
11363 Int4 ctr = 0;
11364 StreamFlgType flags = STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL;
11365
11366 if (upp == NULL || upp->orig_bsp == NULL || upp->update_bsp == NULL
11367 || upp->salp == NULL || ualp == NULL)
11368 {
11369 return FALSE;
11370 }
11371
11372 newlen = ualp->old5 + ualp->newa + ualp->old3;
11373 str = (CharPtr) MemNew (sizeof (Char) * (size_t) (newlen + 5));
11374 if (str == NULL) return FALSE;
11375
11376 if (ISA_na (upp->orig_bsp->mol))
11377 {
11378 seqcode = Seq_code_iupacna;
11379 }
11380 else
11381 {
11382 seqcode = Seq_code_iupacaa;
11383 }
11384
11385 /* construct replacement sequence by double recombination */
11386
11387 /* take old 5' */
11388 if (ualp->old5 > 0) {
11389 ctr = SeqPortStreamInt (upp->orig_bsp, 0, ualp->old5 - 1, Seq_strand_plus,
11390 flags, (Pointer) str, NULL);
11391 }
11392
11393 /* take aligned middle */
11394 if (ualp->new5 + ualp->newa > 0) {
11395 ctr += SeqPortStreamInt (upp->update_bsp, ualp->new5, ualp->new5 + ualp->newa - 1, Seq_strand_plus,
11396 flags, (Pointer) (str + ctr), NULL);
11397 }
11398
11399 /* take old 3' (if any) */
11400 if (ualp->old5 + ualp->olda < upp->orig_bsp->length) {
11401 ctr += SeqPortStreamInt (upp->orig_bsp, ualp->old5 + ualp->olda, upp->orig_bsp->length - 1, Seq_strand_plus,
11402 flags, (Pointer) (str + ctr), NULL);
11403 }
11404
11405 str[ctr] = '\0';
11406
11407 bs = BSNew (newlen);
11408 BSWrite (bs, (VoidPtr) str, newlen);
11409
11410 if (bs != NULL && BSLen (bs) < 1) {
11411 bs = BSFree (bs);
11412 }
11413 if (bs == NULL) return FALSE;
11414
11415 /* overlap turned into replacement sequence */
11416
11417 upp->update_bsp->seq_data = SeqDataFree (upp->update_bsp->seq_data, upp->update_bsp->seq_data_type);
11418 upp->update_bsp->seq_data = (SeqDataPtr) bs;
11419 upp->update_bsp->seq_data_type = seqcode;
11420 upp->update_bsp->length = newlen;
11421 return TRUE;
11422 }
11423
DeltaSequencePatchOk(BioseqPtr orig_bsp,BioseqPtr update_bsp)11424 static Boolean DeltaSequencePatchOk (BioseqPtr orig_bsp, BioseqPtr update_bsp)
11425 {
11426 Boolean rval = TRUE;
11427
11428 if (orig_bsp == NULL || update_bsp == NULL
11429 || orig_bsp->repr != Seq_repr_delta || update_bsp->repr != Seq_repr_delta
11430 || orig_bsp->seq_ext_type != 4 || update_bsp->seq_ext_type != 4)
11431 {
11432 rval = FALSE;
11433 }
11434
11435 return rval;
11436 }
11437
11438 /* This function will patch a delta sequence with another delta sequence.
11439 * The pieces in the overlap from the old sequence will be replaced by pieces
11440 * in the overlap from the new sequence.
11441 */
UpdateSequencePatchDelta(UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp)11442 static Boolean UpdateSequencePatchDelta
11443 (UpdatePairPtr upp,
11444 UpdateAlignmentLengthsPtr ualp)
11445
11446 {
11447 Int4 currnew_pos = 0, currold_pos;
11448 SeqLitPtr slip, slip_new;
11449 DeltaSeqPtr dspold, dspnew;
11450 Int4 seqstart;
11451 DeltaSeqPtr new_list = NULL;
11452
11453 if (upp == NULL)
11454 {
11455 return FALSE;
11456 }
11457 if (! DeltaSequencePatchOk (upp->orig_bsp, upp->update_bsp)
11458 || upp->salp == NULL || ualp == NULL)
11459 {
11460 return FALSE;
11461 }
11462
11463 /* keep old 5' end intact */
11464 currold_pos = 0;
11465 seqstart = 0;
11466 dspold = (DeltaSeqPtr) upp->orig_bsp->seq_ext;
11467 while (dspold != NULL && currold_pos < ualp->old5)
11468 {
11469 seqstart = currold_pos;
11470 if (dspold->data.ptrvalue == NULL || dspold->choice != 2)
11471 {
11472 return FALSE;
11473 }
11474 slip = (SeqLitPtr) (dspold->data.ptrvalue);
11475 currold_pos += slip->length;
11476 if (currold_pos > ualp->old5)
11477 {
11478 SplitDeltaSeq (dspold, ualp->old5 - seqstart);
11479 slip = (SeqLitPtr) (dspold->data.ptrvalue);
11480 currold_pos = ualp->old5;
11481 }
11482 slip_new = (SeqLitPtr) AsnIoMemCopy (slip, (AsnReadFunc) SeqLitAsnRead,
11483 (AsnWriteFunc) SeqLitAsnWrite);
11484 ValNodeAddPointer (&new_list, 2, slip_new);
11485 dspold = dspold->next;
11486 }
11487
11488 /* skip over new 5' end */
11489 currnew_pos = 0;
11490 seqstart = 0;
11491 dspnew = (DeltaSeqPtr) upp->update_bsp->seq_ext;
11492 while (dspnew != NULL && currnew_pos < ualp->new5)
11493 {
11494 seqstart = currold_pos;
11495 if (dspnew->data.ptrvalue == NULL || dspnew->choice != 2)
11496 {
11497 return FALSE;
11498 }
11499 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
11500 currnew_pos += slip->length;
11501 if (currnew_pos > ualp->new5)
11502 {
11503 SplitDeltaSeq (dspnew, ualp->new5 - seqstart);
11504 currnew_pos = ualp->new5;
11505 }
11506 dspnew = dspnew->next;
11507 }
11508
11509 /* copy in new overlap */
11510 while (dspnew != NULL && currnew_pos < ualp->new5 + ualp->newa)
11511 {
11512 seqstart = currold_pos;
11513 if (dspnew->data.ptrvalue == NULL || dspnew->choice != 2)
11514 {
11515 return FALSE;
11516 }
11517 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
11518 currnew_pos += slip->length;
11519 if (currnew_pos > ualp->new5 + ualp->newa)
11520 {
11521 SplitDeltaSeq (dspnew, ualp->new5 + ualp->newa - seqstart);
11522 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
11523 currnew_pos = ualp->new5 + ualp->newa;
11524 }
11525 slip_new = (SeqLitPtr) AsnIoMemCopy (slip, (AsnReadFunc) SeqLitAsnRead,
11526 (AsnWriteFunc) SeqLitAsnWrite);
11527 ValNodeAddPointer (&new_list, 2, slip_new);
11528 dspnew = dspnew->next;
11529 }
11530
11531 /* skip over old overlap */
11532
11533 while (dspold != NULL && currold_pos < ualp->old5 + ualp->olda)
11534 {
11535 seqstart = currold_pos;
11536 if (dspold->data.ptrvalue == NULL || dspold->choice != 2)
11537 {
11538 return FALSE;
11539 }
11540 slip = (SeqLitPtr) (dspold->data.ptrvalue);
11541 currold_pos += slip->length;
11542 if (currold_pos > ualp->old5 + ualp->olda)
11543 {
11544 SplitDeltaSeq (dspold, ualp->new5 + ualp->newa - seqstart);
11545 currold_pos = ualp->old5 + ualp->olda;
11546 }
11547 dspold = dspold->next;
11548 }
11549
11550 /* copy in old 3' */
11551
11552 while (dspold != NULL)
11553 {
11554 if (dspold->data.ptrvalue == NULL || dspold->choice != 2)
11555 {
11556 return FALSE;
11557 }
11558 slip = (SeqLitPtr) (dspold->data.ptrvalue);
11559 slip_new = (SeqLitPtr) AsnIoMemCopy (slip, (AsnReadFunc) SeqLitAsnRead,
11560 (AsnWriteFunc) SeqLitAsnWrite);
11561 ValNodeAddPointer (&new_list, 2, slip_new);
11562 dspold = dspold->next;
11563 }
11564
11565 /* free newbsp's old SeqLit List */
11566 for (dspnew = (DeltaSeqPtr) upp->update_bsp->seq_ext;
11567 dspnew != NULL;
11568 dspnew = dspnew->next)
11569 {
11570 slip = (SeqLitPtr) (dspnew->data.ptrvalue);
11571 SeqLitFree (slip);
11572 }
11573 upp->update_bsp->seq_ext = ValNodeFree (upp->update_bsp->seq_ext);
11574 upp->update_bsp->seq_ext = new_list;
11575 upp->update_bsp->length = ualp->old5 + ualp->newa + ualp->old3;
11576 return TRUE;
11577 }
11578
UpdateSequencePatch(UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp)11579 static Boolean UpdateSequencePatch
11580 (UpdatePairPtr upp,
11581 UpdateAlignmentLengthsPtr ualp)
11582
11583 {
11584 Boolean rval = FALSE;
11585 if (upp == NULL || upp->orig_bsp == NULL || upp->update_bsp == NULL
11586 || upp->salp == NULL)
11587 {
11588 return FALSE;
11589 }
11590
11591 if (RawSequencePatchOk (upp->orig_bsp, upp->update_bsp))
11592 {
11593 rval = UpdateSequencePatchRaw (upp, ualp);
11594 }
11595 else if (DeltaSequencePatchOk (upp->orig_bsp, upp->update_bsp))
11596 {
11597 rval = UpdateSequencePatchDelta (upp, ualp);
11598 }
11599
11600 if (!rval)
11601 {
11602 return rval;
11603 }
11604
11605 /* adjust alignment and reindex */
11606 rval = ShiftAlignmentForUpdate (upp->salp, ualp, eSequenceUpdatePatch);
11607 if (rval)
11608 {
11609 /* then finish by replacing with new sequence */
11610 ReplaceOneSequence (upp->salp, upp->orig_bsp, upp->update_bsp);
11611 }
11612
11613 return rval;
11614 }
11615
DoSequencesHaveDifferentOrganisms(BioseqPtr bsp1,BioseqPtr bsp2)11616 static Boolean DoSequencesHaveDifferentOrganisms (BioseqPtr bsp1, BioseqPtr bsp2)
11617 {
11618 OrgRefPtr orp1 = NULL, orp2 = NULL;
11619 SeqDescrPtr sdp;
11620 SeqMgrDescContext dcontext;
11621 BioSourcePtr biop1, biop2;
11622 Boolean rval = FALSE;
11623
11624 sdp = SeqMgrGetNextDescriptor (bsp1, NULL, Seq_descr_source, &dcontext);
11625 if (sdp != NULL) {
11626 biop1 = (BioSourcePtr) sdp->data.ptrvalue;
11627 if (biop1 != NULL) {
11628 orp1 = biop1->org;
11629 }
11630 }
11631 sdp = SeqMgrGetNextDescriptor (bsp2, NULL, Seq_descr_source, &dcontext);
11632 if (sdp != NULL) {
11633 biop2 = (BioSourcePtr) sdp->data.ptrvalue;
11634 if (biop2 != NULL)
11635 {
11636 orp2 = biop2->org;
11637 }
11638 }
11639 if (orp1 != NULL && orp2 != NULL
11640 && StringICmp (orp1->taxname, orp2->taxname) != 0)
11641 {
11642 rval = TRUE;
11643 }
11644 return rval;
11645 }
11646
11647 /*This function removes RefTrackDescriptors from the specified Bioseq */
RemoveRefTrackDescriptors(BioseqPtr bsp)11648 static void RemoveRefTrackDescriptors (BioseqPtr bsp)
11649 {
11650 UserObjectPtr uop;
11651 ObjectIdPtr oip;
11652 SeqDescrPtr desc, prev_desc = NULL, next_desc;
11653
11654 for (desc=bsp->descr; desc != NULL; desc=next_desc)
11655 {
11656 next_desc = desc->next;
11657 if (desc->choice != Seq_descr_user || desc->data.ptrvalue == NULL)
11658 {
11659 prev_desc = desc;
11660 continue;
11661 }
11662 uop = desc->data.ptrvalue;
11663 if ((oip = uop->type) == NULL || StringCmp(oip->str, "RefGeneTracking") != 0)
11664 {
11665 prev_desc = desc;
11666 }
11667 else
11668 {
11669 if (prev_desc == NULL)
11670 {
11671 bsp->descr = desc->next;
11672 }
11673 else
11674 {
11675 prev_desc->next = desc->next;
11676 }
11677 desc->next = NULL;
11678 SeqDescrFree (desc);
11679 }
11680 }
11681 }
11682
RemoveCreateDateDescriptors(BioseqPtr bsp)11683 static void RemoveCreateDateDescriptors (BioseqPtr bsp)
11684 {
11685 ValNodePtr vnp;
11686
11687 vnp = ValNodeExtract (&(bsp->descr), Seq_descr_create_date);
11688 vnp = ValNodeFree (vnp);
11689 }
11690
11691 static void
ImportFeatureProduct(SeqFeatPtr dup,Boolean keepProteinIDs,SeqEntryPtr top,SeqIdPtr nuc_sip,Uint2 update_entityID)11692 ImportFeatureProduct
11693 (SeqFeatPtr dup,
11694 Boolean keepProteinIDs,
11695 SeqEntryPtr top,
11696 SeqIdPtr nuc_sip,
11697 Uint2 update_entityID)
11698 {
11699 BioseqPtr bsp, newbsp;
11700 SeqEntryPtr prdsep, newsep;
11701 SeqEntryPtr newscope, oldscope;
11702
11703 if (dup == NULL || dup->product == NULL || nuc_sip == NULL || top == NULL)
11704 {
11705 return;
11706 }
11707
11708 newscope = GetTopSeqEntryForEntityID (update_entityID);
11709 oldscope = SeqEntrySetScope (newscope);
11710 bsp = BioseqFindFromSeqLoc (dup->product);
11711 SeqEntrySetScope (oldscope);
11712 if (bsp != NULL) {
11713 prdsep = SeqMgrGetSeqEntryForData (bsp);
11714 if (prdsep != NULL) {
11715 newsep = AsnIoMemCopy ((Pointer) prdsep,
11716 (AsnReadFunc) SeqEntryAsnRead,
11717 (AsnWriteFunc) SeqEntryAsnWrite);
11718 if (newsep != NULL) {
11719 if (IS_Bioseq (newsep)) {
11720 newbsp = (BioseqPtr) newsep->data.ptrvalue;
11721 if (newbsp != NULL) {
11722 /* we do not want to import reftrack descriptors with the products */
11723 RemoveRefTrackDescriptors (newbsp);
11724 /* we do not want to import create-date descriptors with the products */
11725 RemoveCreateDateDescriptors (newbsp);
11726 if (! keepProteinIDs) {
11727 newbsp->id = SeqIdSetFree (newbsp->id);
11728 newbsp->id = MakeNewProteinSeqId (NULL, nuc_sip);
11729 newbsp->hist = SeqHistFree (newbsp->hist);
11730 VisitFeaturesOnBsp (newbsp, (Pointer) newbsp->id, CorrectFeatureSeqIds);
11731 SetSeqFeatProduct (dup, newbsp);
11732 }
11733 SeqMgrReplaceInBioseqIndex (newbsp);
11734 }
11735 }
11736 AddSeqEntryToSeqEntry (top, newsep, TRUE);
11737 }
11738 }
11739 }
11740 }
11741
11742
IsFeatureOkForFeatureTypes(SeqFeatPtr sfp,ValNodePtr list)11743 static Boolean IsFeatureOkForFeatureTypes (SeqFeatPtr sfp, ValNodePtr list)
11744 {
11745 Int4 ftype;
11746 Boolean rval = FALSE;
11747
11748 if (sfp == NULL) {
11749 rval = FALSE;
11750 } else if (list == NULL) {
11751 rval = TRUE;
11752 } else {
11753 ftype = GetFeatureTypeFromFeatdef (sfp->idx.subtype);
11754 while (list != NULL && !rval) {
11755 if (list->choice == ftype) {
11756 rval = TRUE;
11757 }
11758 list = list->next;
11759 }
11760 }
11761 return rval;
11762 }
11763
11764
11765 static Boolean
ImportFeaturesWithOffset(UpdatePairPtr upp,UpdateOptionsPtr uop,UpdateAlignmentLengthsPtr ualp,Int4 offset)11766 ImportFeaturesWithOffset
11767 (UpdatePairPtr upp,
11768 UpdateOptionsPtr uop,
11769 UpdateAlignmentLengthsPtr ualp,
11770 Int4 offset)
11771
11772 {
11773 CodeBreakPtr cbp;
11774 SeqMgrFeatContext context;
11775 CdRegionPtr crp;
11776 SeqFeatPtr dup, sfp, last = NULL;
11777 Uint2 entityID;
11778 Boolean keepProteinIDs = FALSE;
11779 SeqEntryPtr top;
11780 RnaRefPtr rrp;
11781 SeqAnnotPtr sap = NULL, saptmp;
11782 SeqDescrPtr sdp;
11783 SeqIdPtr sip;
11784 tRNAPtr trp;
11785
11786 if (upp == NULL || uop == NULL || ualp == NULL) return FALSE;
11787 upp->newfeat_sap = NULL;
11788 SeqEntrySetScope (NULL);
11789
11790 sfp = SeqMgrGetNextFeature (upp->update_bsp, NULL, 0, 0, &context);
11791
11792 if (sfp == NULL)
11793 {
11794 /* no features to update, done */
11795 return TRUE;
11796 }
11797
11798 if (uop->indexer_opts != NULL
11799 && uop->indexer_opts->keep_protein_ids
11800 && ! DoSequencesHaveDifferentOrganisms (upp->orig_bsp, upp->update_bsp))
11801 {
11802 keepProteinIDs = TRUE;
11803 }
11804
11805 entityID = ObjMgrGetEntityIDForPointer (upp->orig_bsp);
11806 top = GetBestTopParentForData (entityID, upp->orig_bsp);
11807
11808 sdp = ExtractBioSourceAndPubs (top);
11809
11810 sip = SeqIdFindBest (upp->orig_bsp->id, 0);
11811
11812 for (; sfp != NULL; sfp = SeqMgrGetNextFeature (upp->update_bsp, sfp, 0, 0, &context))
11813 {
11814 if (uop->submitter_opts->sequence_update_type == eSequenceUpdatePatch
11815 && (context.right < ualp->new5 || context.left > ualp->new5 + ualp->newa))
11816 {
11817 /* this was a patch operation, and feature is outside patch area */
11818 continue;
11819 }
11820 if (sfp->data.choice == SEQFEAT_USER)
11821 {
11822 /* this is where we will continue if this is a RefTrack object */
11823 }
11824
11825 /* skip if it's not in the list of feature types */
11826 if (uop->submitter_opts->feature_import_options != NULL
11827 && !IsFeatureOkForFeatureTypes(sfp, uop->submitter_opts->feature_import_options->feature_types))
11828 {
11829 continue;
11830 }
11831 dup = AsnIoMemCopy ((Pointer) sfp,
11832 (AsnReadFunc) SeqFeatAsnRead,
11833 (AsnWriteFunc) SeqFeatAsnWrite);
11834
11835 /* if this is the first feature we have imported, create an annotation to hold it.
11836 * we put the features on a separate annotation so that we will be able to resolve
11837 * duplicates later.
11838 */
11839 if (last == NULL)
11840 {
11841 sap = SeqAnnotNew ();
11842 if (upp->orig_bsp->annot == NULL)
11843 {
11844 upp->orig_bsp->annot = sap;
11845 }
11846 else
11847 {
11848 for (saptmp = upp->orig_bsp->annot; saptmp->next != NULL; saptmp = saptmp->next) continue;
11849 saptmp->next = sap;
11850 }
11851 sap->type = 1;
11852 sap->data = (Pointer) dup;
11853 } else {
11854 last->next = dup;
11855 }
11856 last = dup;
11857
11858 OffsetLocation (dup->location, offset, sip);
11859 switch (dup->data.choice) {
11860 case SEQFEAT_CDREGION :
11861 crp = (CdRegionPtr) dup->data.value.ptrvalue;
11862 if (crp != NULL) {
11863 for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
11864 OffsetLocation (cbp->loc, offset, sip);
11865 }
11866 }
11867 break;
11868 case SEQFEAT_RNA :
11869 rrp = (RnaRefPtr) dup->data.value.ptrvalue;
11870 if (rrp != NULL && rrp->ext.choice == 2) {
11871 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
11872 if (trp != NULL && trp->anticodon != NULL) {
11873 OffsetLocation (trp->anticodon, offset, sip);
11874 }
11875 }
11876 break;
11877 default :
11878 break;
11879 }
11880 ImportFeatureProduct (dup, keepProteinIDs, top, sip, sfp->idx.entityID);
11881 }
11882
11883 ReplaceBioSourceAndPubs (top, sdp);
11884
11885 upp->newfeat_sap = sap;
11886
11887 return TRUE;
11888 }
11889
GetMaxPositionForUpdate(BioseqPtr orig_bsp,UpdateOptionsPtr uop,UpdateAlignmentLengthsPtr ualp)11890 static Int4 GetMaxPositionForUpdate
11891 (BioseqPtr orig_bsp,
11892 UpdateOptionsPtr uop,
11893 UpdateAlignmentLengthsPtr ualp)
11894 {
11895 Int4 new_len = 0;
11896
11897 if (uop == NULL || uop->submitter_opts == NULL)
11898 {
11899 return 0;
11900 }
11901
11902 switch (uop->submitter_opts->sequence_update_type)
11903 {
11904 case eSequenceUpdateNoChange:
11905 if (orig_bsp != NULL)
11906 {
11907 new_len = orig_bsp->length;
11908 }
11909 break;
11910 case eSequenceUpdatePatch:
11911 if (ualp != NULL)
11912 {
11913 new_len = ualp->old5 + ualp->newa + ualp->old3;
11914 }
11915 break;
11916 case eSequenceUpdateReplace:
11917 if (ualp != NULL)
11918 {
11919 new_len = ualp->new5 + ualp->newa + ualp->new3;
11920 }
11921 break;
11922 case eSequenceUpdateExtend5:
11923 if (ualp != NULL)
11924 {
11925 new_len = ualp->new5 + ualp->newa + ualp->old3;
11926 }
11927 break;
11928 case eSequenceUpdateExtend3:
11929 if (ualp != NULL)
11930 {
11931 new_len = ualp->old5 + ualp->newa + ualp->new3;
11932 }
11933 break;
11934 }
11935 return new_len;
11936 }
11937
ImportFeaturesViaAlignment(UpdatePairPtr upp,UpdateOptionsPtr uop,UpdateAlignmentLengthsPtr ualp)11938 static Boolean ImportFeaturesViaAlignment
11939 (UpdatePairPtr upp,
11940 UpdateOptionsPtr uop,
11941 UpdateAlignmentLengthsPtr ualp)
11942
11943 {
11944 CodeBreakPtr cbp, prevcbp, nextcbp;
11945 SeqMgrFeatContext context;
11946 CdRegionPtr crp;
11947 SeqFeatPtr dup, sfp, last = NULL;
11948 Uint2 entityID;
11949 Int4 from, to, max_position;
11950 Boolean keepProteinIDs = FALSE;
11951 SeqLocPtr newloc;
11952 SeqEntryPtr top;
11953 RnaRefPtr rrp;
11954 SeqAnnotPtr sap = NULL, saptmp;
11955 SeqDescrPtr sdp;
11956 SeqIdPtr sip;
11957 Boolean split;
11958 tRNAPtr trp;
11959 Boolean partial5, partial3;
11960
11961 if (upp == NULL || uop == NULL || ualp == NULL) return FALSE;
11962 upp->newfeat_sap = NULL;
11963
11964 SeqEntrySetScope (NULL);
11965
11966 sfp = SeqMgrGetNextFeature (upp->update_bsp, NULL, 0, 0, &context);
11967 if (sfp == NULL) return FALSE;
11968
11969 if (uop->indexer_opts != NULL && uop->indexer_opts->keep_protein_ids)
11970 {
11971 keepProteinIDs = TRUE;
11972 }
11973
11974 entityID = ObjMgrGetEntityIDForPointer (upp->orig_bsp);
11975 top = GetBestTopParentForData (entityID, upp->orig_bsp);
11976
11977 sdp = ExtractBioSourceAndPubs (top);
11978
11979 sip = SeqIdFindBest (upp->orig_bsp->id, 0);
11980
11981 from = ualp->new5;
11982 to = ualp->new5 + ualp->newa;
11983
11984 max_position = GetMaxPositionForUpdate (upp->orig_bsp, uop, ualp);
11985
11986 while (sfp != NULL) {
11987
11988 if (uop->submitter_opts->feature_import_options != NULL
11989 && !IsFeatureOkForFeatureTypes(sfp, uop->submitter_opts->feature_import_options->feature_types))
11990 {
11991 /* skip if it's not in the list of feature types */
11992 } else if (context.right >= from && context.left <= to) {
11993 /* only use if in correct range */
11994 split = FALSE;
11995 newloc = GetPropagatedLocation (sfp->location, upp->update_bsp, upp->orig_bsp,
11996 max_position, upp->salp);
11997 if (newloc != NULL) {
11998 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
11999 SetSeqLocPartial (newloc, partial5, partial3);
12000 dup = AsnIoMemCopy ((Pointer) sfp,
12001 (AsnReadFunc) SeqFeatAsnRead,
12002 (AsnWriteFunc) SeqFeatAsnWrite);
12003
12004 SeqLocFree (dup->location);
12005 dup->location = newloc;
12006 if (split) {
12007 dup->partial = TRUE;
12008 }
12009 dup->partial |= partial5;
12010 dup->partial |= partial3;
12011
12012 if (last == NULL) {
12013 sap = SeqAnnotNew ();
12014 if (upp->orig_bsp->annot == NULL) {
12015 upp->orig_bsp->annot = sap;
12016 } else {
12017 for (saptmp = upp->orig_bsp->annot; saptmp->next != NULL; saptmp = saptmp->next) continue;
12018 saptmp->next = sap;
12019 }
12020 sap->type = 1;
12021 sap->data = (Pointer) dup;
12022 } else {
12023 last->next = dup;
12024 }
12025 last = dup;
12026
12027 switch (dup->data.choice) {
12028 case SEQFEAT_CDREGION :
12029 crp = (CdRegionPtr) dup->data.value.ptrvalue;
12030 if (crp != NULL) {
12031 prevcbp = NULL;
12032 for (cbp = crp->code_break; cbp != NULL; cbp = nextcbp) {
12033 nextcbp = cbp->next;
12034 newloc = GetPropagatedLocation (cbp->loc, upp->update_bsp, upp->orig_bsp,
12035 max_position, upp->salp);
12036 SeqLocFree (cbp->loc);
12037 cbp->loc = newloc;
12038 if (cbp->loc == NULL) {
12039 if (prevcbp != NULL) {
12040 prevcbp->next = nextcbp;
12041 } else {
12042 crp->code_break = nextcbp;
12043 }
12044 cbp->next = NULL;
12045 CodeBreakFree (cbp);
12046 } else {
12047 prevcbp = cbp;
12048 }
12049 }
12050 }
12051 break;
12052 case SEQFEAT_RNA :
12053 rrp = (RnaRefPtr) dup->data.value.ptrvalue;
12054 if (rrp != NULL && rrp->ext.choice == 2) {
12055 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
12056 if (trp != NULL && trp->anticodon != NULL) {
12057 newloc = GetPropagatedLocation (trp->anticodon, upp->update_bsp, upp->orig_bsp,
12058 max_position, upp->salp);
12059 SeqLocFree (trp->anticodon);
12060 trp->anticodon = newloc;
12061 }
12062 }
12063 break;
12064 default :
12065 break;
12066 }
12067 ImportFeatureProduct (dup, keepProteinIDs, top, sip, sfp->idx.entityID);
12068 }
12069 }
12070
12071 sfp = SeqMgrGetNextFeature (upp->update_bsp, sfp, 0, 0, &context);
12072 }
12073
12074 ReplaceBioSourceAndPubs (top, sdp);
12075
12076 upp->newfeat_sap = sap;
12077
12078 return TRUE;
12079 }
12080
12081 /* This function examines the contexts for two features.
12082 * If the featdeftypes are the same and the locations are identical,
12083 * the features are considered to be duplicates.
12084 */
12085 static Boolean
AreFeaturesDuplicates(SeqMgrFeatContextPtr context1,SeqMgrFeatContextPtr context2)12086 AreFeaturesDuplicates
12087 (SeqMgrFeatContextPtr context1,
12088 SeqMgrFeatContextPtr context2)
12089 {
12090 Boolean ivalssame = FALSE;
12091 Int4 i, j;
12092
12093 if (context1 == NULL || context2 == NULL)
12094 {
12095 return FALSE;
12096 }
12097
12098 if (context1->left == context2->left &&
12099 context1->right == context2->right &&
12100 context1->featdeftype == context2->featdeftype)
12101 {
12102 if (context1->strand == context2->strand ||
12103 context2->strand == Seq_strand_unknown ||
12104 context1->strand == Seq_strand_unknown)
12105 {
12106 ivalssame = TRUE;
12107 if (context1->numivals != context2->numivals ||
12108 context1->ivals == NULL ||
12109 context2->ivals == NULL)
12110 {
12111 ivalssame = FALSE;
12112 }
12113 else
12114 {
12115 for (i = 0, j = 0; i < context2->numivals; i++, j += 2)
12116 {
12117 if (context1->ivals [j] != context2->ivals [j])
12118 {
12119 ivalssame = FALSE;
12120 }
12121 if (context1->ivals [j + 1] != context2->ivals [j + 1])
12122 {
12123 ivalssame = FALSE;
12124 }
12125 }
12126 }
12127 }
12128 }
12129 return ivalssame;
12130 }
12131
12132
ResolveDuplicateUpdateFeats(BioseqPtr bsp,UpdateOptionsPtr uop,SeqAnnotPtr newfeat_sap)12133 static void ResolveDuplicateUpdateFeats
12134 (BioseqPtr bsp,
12135 UpdateOptionsPtr uop,
12136 SeqAnnotPtr newfeat_sap)
12137
12138 {
12139 SeqMgrFeatContext context, lastcontext;
12140 SeqFeatPtr lastsfp = NULL, sfp;
12141
12142 if (bsp == NULL
12143 || newfeat_sap == NULL
12144 || uop == NULL
12145 || uop->submitter_opts == NULL
12146 || uop->submitter_opts->feature_import_options == NULL
12147 || uop->submitter_opts->feature_import_options->feature_import_type == eFeatureUpdateAll)
12148 {
12149 return;
12150 }
12151 SeqMgrIndexFeatures (bsp->idx.entityID, NULL);
12152
12153 lastsfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
12154 if (lastsfp == NULL) return;
12155
12156 MemCopy ((Pointer) &lastcontext, (Pointer) &context, sizeof (SeqMgrFeatContext));
12157
12158 sfp = SeqMgrGetNextFeature (bsp, lastsfp, 0, 0, &context);
12159 if (sfp == NULL) return;
12160
12161 while (sfp != NULL)
12162 {
12163 if (context.sap != lastcontext.sap
12164 && (context.sap == newfeat_sap || lastcontext.sap == newfeat_sap)
12165 && AreFeaturesDuplicates (&context, &lastcontext))
12166 {
12167 if (uop->submitter_opts->feature_import_options->feature_import_type == eFeatureUpdateAllReplaceDups) { /* keep new */
12168 if (context.sap == newfeat_sap) {
12169 lastsfp->idx.deleteme = TRUE;
12170 MarkProductForDeletion (lastsfp->product);
12171 } else if (lastcontext.sap == newfeat_sap) {
12172 sfp->idx.deleteme = TRUE;
12173 MarkProductForDeletion (sfp->product);
12174 }
12175 } else if (uop->submitter_opts->feature_import_options->feature_import_type == eFeatureUpdateAllExceptDups) { /* keep old */
12176 if (context.sap == newfeat_sap) {
12177 sfp->idx.deleteme = TRUE;
12178 MarkProductForDeletion (sfp->product);
12179 } else if (lastcontext.sap == newfeat_sap) {
12180 lastsfp->idx.deleteme = TRUE;
12181 MarkProductForDeletion (lastsfp->product);
12182 }
12183
12184 } else if (uop->submitter_opts->feature_import_options->feature_import_type == eFeatureUpdateAllMergeDups) { /* merge */
12185 if (context.sap == newfeat_sap) {
12186 FuseFeatures (sfp, lastsfp);
12187 lastsfp->idx.deleteme = TRUE;
12188 MarkProductForDeletion (lastsfp->product);
12189 } else if (lastcontext.sap == newfeat_sap) {
12190 FuseFeatures (lastsfp, sfp);
12191 sfp->idx.deleteme = TRUE;
12192 MarkProductForDeletion (sfp->product);
12193 }
12194 }
12195 }
12196
12197 lastsfp = sfp;
12198 MemCopy ((Pointer) &lastcontext, (Pointer) &context, sizeof (SeqMgrFeatContext));
12199
12200 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
12201 }
12202 }
12203
12204
12205
12206 static void
UpdateProteinForOneUpdatedCodingRegion(SeqFeatPtr sfp,ValNodePtr transl_except_list,IndexerOptionsPtr iop,Uint2 entityID,FILE * log_fp,BoolPtr data_in_log)12207 UpdateProteinForOneUpdatedCodingRegion
12208 (SeqFeatPtr sfp,
12209 ValNodePtr transl_except_list,
12210 IndexerOptionsPtr iop,
12211 Uint2 entityID,
12212 FILE *log_fp,
12213 BoolPtr data_in_log)
12214 {
12215 SeqLocPtr new_product;
12216 Int4 transl_except_len = 0;
12217 Boolean fix_products = TRUE;
12218 BioseqPtr protBsp = NULL;
12219 SeqAlignPtr salp = NULL;
12220 BioseqPtr newbsp = NULL;
12221 Boolean rval;
12222
12223 if (sfp == NULL
12224 || sfp->idx.subtype != FEATDEF_CDS
12225 || sfp->idx.deleteme)
12226 {
12227 return;
12228 }
12229
12230 protBsp = BioseqFindFromSeqLoc (sfp->product);
12231 if (protBsp == NULL)
12232 {
12233 return;
12234 }
12235
12236 transl_except_len = GetOriginalTranslExceptLen (sfp, transl_except_list);
12237 rval = PrepareUpdateAlignmentForProtein (sfp,
12238 protBsp,
12239 entityID,
12240 log_fp,
12241 iop == NULL ? FALSE : iop->truncate_proteins,
12242 iop == NULL ? FALSE : iop->extend_proteins5,
12243 iop == NULL ? FALSE : iop->extend_proteins3,
12244 iop == NULL ? FALSE : iop->correct_cds_genes,
12245 transl_except_len,
12246 data_in_log,
12247 &salp,
12248 &newbsp);
12249 if (!rval) return;
12250
12251 if (protBsp->idx.deleteme)
12252 {
12253 fix_products = FALSE;
12254 }
12255
12256 ReplaceOneSequence (salp, protBsp, newbsp);
12257
12258 if (fix_products)
12259 {
12260 if (sfp->product->choice != SEQLOC_WHOLE) {
12261 new_product = SeqLocWholeNew (protBsp);
12262 if (new_product == NULL) return;
12263 SeqLocFree (sfp->product);
12264 sfp->product = new_product;
12265 }
12266 newbsp = BioseqFree (newbsp);
12267 }
12268 }
12269
12270 static void
UpdateProteinsForUpdatedCodingRegions(BioseqPtr orig_bsp,ValNodePtr transl_except_list,IndexerOptionsPtr iop,Uint2 entityID,FILE * log_fp,BoolPtr data_in_log)12271 UpdateProteinsForUpdatedCodingRegions
12272 (BioseqPtr orig_bsp,
12273 ValNodePtr transl_except_list,
12274 IndexerOptionsPtr iop,
12275 Uint2 entityID,
12276 FILE *log_fp,
12277 BoolPtr data_in_log)
12278 {
12279 SeqFeatPtr sfp;
12280 SeqMgrFeatContext context;
12281
12282 sfp = SeqMgrGetNextFeature (orig_bsp, NULL, SEQFEAT_CDREGION, 0, &context);
12283 while (sfp != NULL)
12284 {
12285 UpdateProteinForOneUpdatedCodingRegion (sfp, transl_except_list, iop,
12286 entityID, log_fp, data_in_log);
12287 sfp = SeqMgrGetNextFeature (orig_bsp, sfp, SEQFEAT_CDREGION, 0, &context);
12288 }
12289 }
12290
12291 static Boolean
IsSequenceUpdateChoiceAllowed(ESequenceUpdateType action,UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp,Boolean is_indexer,Boolean ignore_alignment)12292 IsSequenceUpdateChoiceAllowed
12293 (ESequenceUpdateType action,
12294 UpdatePairPtr upp,
12295 UpdateAlignmentLengthsPtr ualp,
12296 Boolean is_indexer,
12297 Boolean ignore_alignment)
12298 {
12299
12300 if (upp == NULL || upp->orig_bsp == NULL || upp->update_bsp == NULL)
12301 {
12302 return FALSE;
12303 }
12304 else if (action == eSequenceUpdateNoChange)
12305 {
12306 if (ignore_alignment)
12307 {
12308 return FALSE;
12309 }
12310 else
12311 {
12312 return TRUE;
12313 }
12314 }
12315 else if (action != eSequenceUpdateNoChange
12316 && !is_indexer
12317 && (upp->orig_bsp->repr != Seq_repr_raw || upp->update_bsp->repr != Seq_repr_raw))
12318 {
12319 /* If either sequence is not raw and not indexer version, do not allow sequence update */
12320 return FALSE;
12321 }
12322 else if (action == eSequenceUpdatePatch
12323 && (upp->salp == NULL || ignore_alignment
12324 || (! RawSequencePatchOk (upp->orig_bsp, upp->update_bsp)
12325 && !DeltaSequencePatchOk (upp->orig_bsp, upp->update_bsp))))
12326 {
12327 /* If no alignment or patch not available then disable the patch button */
12328 return FALSE;
12329 }
12330 else if (ignore_alignment
12331 && (action == eSequenceUpdateExtend3
12332 || action == eSequenceUpdateExtend5))
12333 {
12334 return TRUE;
12335 }
12336 else if (ualp == NULL)
12337 {
12338 return FALSE;
12339 }
12340 else if (action == eSequenceUpdateExtend3
12341 && (ualp->new3 < ualp->old3 || ualp->new3 == 0))
12342 {
12343 return FALSE;
12344 }
12345 else if (action == eSequenceUpdateExtend5
12346 && (ualp->new5 < ualp->old5 || ualp->new5 == 0))
12347 {
12348 return FALSE;
12349 }
12350 else
12351 {
12352 return TRUE;
12353 }
12354 }
12355
12356 static void
ReportBadUpdateType(ESequenceUpdateType action,UpdatePairPtr upp,FILE * log_fp,BoolPtr data_in_log)12357 ReportBadUpdateType
12358 (ESequenceUpdateType action,
12359 UpdatePairPtr upp,
12360 FILE *log_fp,
12361 BoolPtr data_in_log)
12362 {
12363 Char id_txt [MAX_ID_LEN];
12364
12365 if (upp == NULL
12366 || upp->orig_bsp == NULL
12367 || log_fp == NULL
12368 || data_in_log == NULL)
12369 {
12370 return;
12371 }
12372
12373 SeqIdWrite (SeqIdFindBest (upp->orig_bsp->id, SEQID_GENBANK), id_txt,
12374 PRINTID_REPORT, sizeof (id_txt) - 1);
12375
12376 switch (action)
12377 {
12378 case eSequenceUpdateNoChange:
12379 /* do nothing */
12380 break;
12381 case eSequenceUpdateReplace:
12382 fprintf (log_fp, "Unable to replace sequence for %s\n", id_txt);
12383 *data_in_log = TRUE;
12384 break;
12385 case eSequenceUpdatePatch:
12386 fprintf (log_fp, "Unable to patch sequence for %s\n", id_txt);
12387 *data_in_log = TRUE;
12388 break;
12389 case eSequenceUpdateExtend5:
12390 fprintf (log_fp, "Unable to extend sequence on 5' end for %s\n", id_txt);
12391 *data_in_log = TRUE;
12392 break;
12393 case eSequenceUpdateExtend3:
12394 fprintf (log_fp, "Unable to extend sequence on 3' end for %s\n", id_txt);
12395 *data_in_log = TRUE;
12396 break;
12397 default:
12398 fprintf (log_fp, "Unknown update operation for %s\n", id_txt);
12399 *data_in_log = TRUE;
12400 break;
12401 }
12402 }
12403
OkToTrimQualityScores(UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp)12404 static Boolean OkToTrimQualityScores (UpdatePairPtr upp, UpdateAlignmentLengthsPtr ualp)
12405 {
12406 CharPtr buf1, buf2;
12407 Boolean rval = FALSE;
12408
12409 if (upp == NULL || upp->orig_bsp == NULL || upp->update_bsp == NULL
12410 || upp->update_bsp->length > upp->orig_bsp->length
12411 || ualp == NULL || ualp->new5 > 0 || ualp->new3 > 0 || ualp->newa != ualp->olda || ualp->newa != upp->update_bsp->length) {
12412 return FALSE;
12413 }
12414 buf1 = (CharPtr) MemNew (sizeof (Char) * (ualp->newa + 1));
12415 MemSet (buf1, 0, sizeof (Char) * (ualp->newa + 1));
12416 buf2= (CharPtr) MemNew (sizeof (Char) * (ualp->newa + 1));
12417 MemSet (buf2, 0, sizeof (Char) * (ualp->newa + 1));
12418
12419 if (SeqPortStreamInt (upp->orig_bsp, ualp->old5, ualp->old5 + ualp->olda - 1, Seq_strand_plus, STREAM_EXPAND_GAPS, buf1, NULL) == upp->update_bsp->length
12420 && SeqPortStreamInt (upp->update_bsp, 0, upp->update_bsp->length - 1, Seq_strand_plus, STREAM_EXPAND_GAPS, buf2, NULL) == upp->update_bsp->length
12421 && StringCmp (buf1, buf2) == 0) {
12422 rval = TRUE;
12423 }
12424 buf1 = MemFree (buf1);
12425 buf2 = MemFree (buf2);
12426 return rval;
12427 }
12428
12429
12430 static Boolean
UpdateOrExtendOneSequenceEx(UpdatePairPtr upp,UpdateOptionsPtr uop,UpdateAlignmentLengthsPtr ualp,Uint2 entityID,FILE * log_fp,BoolPtr data_in_log,Boolean force_allow_replace_without_aln)12431 UpdateOrExtendOneSequenceEx
12432 (UpdatePairPtr upp,
12433 UpdateOptionsPtr uop,
12434 UpdateAlignmentLengthsPtr ualp,
12435 Uint2 entityID,
12436 FILE *log_fp,
12437 BoolPtr data_in_log,
12438 Boolean force_allow_replace_without_aln)
12439 {
12440 ValNodePtr prot_feat_list = NULL;
12441 ValNodePtr transl_except_list = NULL;
12442 Boolean sequence_update_successful = FALSE;
12443 Boolean rval = FALSE;
12444 Int4 feature_update_offset;
12445 Int4 orig_seq_len;
12446 Uint2 update_entityID;
12447 Char id_txt [128];
12448 Boolean deleted_features = FALSE;
12449 Boolean trim_quality_scores = FALSE;
12450 SeqFeatPtr sfp;
12451 SeqMgrFeatContext context;
12452 Boolean any_cds = FALSE;
12453
12454 if (upp == NULL || upp->orig_bsp == NULL || upp->update_bsp == NULL
12455 || uop == NULL || uop->submitter_opts == NULL)
12456 {
12457 return FALSE;
12458 }
12459 upp->feature_update_successful = FALSE;
12460
12461 update_entityID = upp->update_bsp->idx.entityID;
12462
12463 if (!IsSequenceUpdateChoiceAllowed (uop->submitter_opts->sequence_update_type,
12464 upp, ualp, indexerVersion,
12465 uop->submitter_opts->ignore_alignment))
12466 {
12467 ReportBadUpdateType (uop->submitter_opts->sequence_update_type,
12468 upp, log_fp, data_in_log);
12469 return FALSE;
12470 }
12471
12472 if (uop->submitter_opts->sequence_update_type == eSequenceUpdateReplace
12473 && upp->salp == NULL && !force_allow_replace_without_aln)
12474 {
12475 SeqIdWrite (SeqIdFindBest (upp->orig_bsp->id, SEQID_GENBANK), id_txt,
12476 PRINTID_REPORT, sizeof (id_txt) - 1);
12477
12478 if (ANS_NO == Message (MSG_YN,
12479 "There is no alignment for %s. Are you sure that you want to replace this sequence?",
12480 id_txt))
12481 {
12482 return FALSE;
12483 }
12484 }
12485
12486 if ((sfp = SeqMgrGetNextFeature (upp->orig_bsp, NULL, SEQFEAT_CDREGION, 0, &context)) != NULL)
12487 {
12488 any_cds = TRUE;
12489 }
12490 else if ((sfp = SeqMgrGetNextFeature (upp->update_bsp, NULL, SEQFEAT_CDREGION, 0, &context)) != NULL)
12491 {
12492 any_cds = TRUE;
12493 }
12494
12495 /* remove features */
12496 switch (uop->submitter_opts->feature_remove_type)
12497 {
12498 case eFeatureRemoveAll:
12499 deleted_features = RemoveOldFeats (upp->orig_bsp);
12500 break;
12501 case eFeatureRemoveAligned:
12502 deleted_features = RemoveFeatsInAlignedRegion (upp->orig_bsp, ualp);
12503 break;
12504 case eFeatureRemoveNotAligned:
12505 deleted_features = RemoveFeatsNotInAlignedRegion (upp->orig_bsp, ualp);
12506 break;
12507 default:
12508 break;
12509 }
12510 if (deleted_features) {
12511 DeleteMarkedObjects (upp->orig_bsp->idx.entityID, 0, NULL);
12512 SeqMgrClearFeatureIndexes (upp->orig_bsp->idx.entityID, upp->orig_bsp);
12513 SeqMgrIndexFeatures (upp->orig_bsp->idx.entityID, NULL);
12514 }
12515
12516 if (ISA_na (upp->orig_bsp->mol) && uop->indexer_opts != NULL && uop->indexer_opts->update_proteins)
12517 {
12518 prot_feat_list = FindProductProtRefs (upp->orig_bsp);
12519 transl_except_list = FindTranslExceptCDSs (upp->orig_bsp);
12520 }
12521
12522 /* get length of original sequence before updating */
12523 orig_seq_len = upp->orig_bsp->length;
12524
12525 /* update sequence */
12526 switch (uop->submitter_opts->sequence_update_type)
12527 {
12528 case eSequenceUpdateReplace:
12529 trim_quality_scores = OkToTrimQualityScores (upp, ualp);
12530 ReplaceOneSequence (upp->salp, upp->orig_bsp, upp->update_bsp);
12531 sequence_update_successful = TRUE;
12532 rval = sequence_update_successful;
12533 break;
12534 case eSequenceUpdatePatch:
12535 sequence_update_successful = UpdateSequencePatch (upp, ualp);
12536 rval = sequence_update_successful;
12537 break;
12538 case eSequenceUpdateExtend5:
12539 sequence_update_successful = UpdateSequenceExtend5Prime (upp, ualp);
12540 rval = sequence_update_successful;
12541 break;
12542 case eSequenceUpdateExtend3:
12543 sequence_update_successful = UpdateSequenceExtend3Prime (upp, ualp);
12544 rval = sequence_update_successful;
12545 break;
12546 case eSequenceUpdateNoChange:
12547 rval = TRUE;
12548 break;
12549 }
12550
12551 if (log_fp != NULL && data_in_log != NULL && upp->revcomp)
12552 {
12553 SeqIdWrite (SeqIdFindBest (upp->orig_bsp->id, SEQID_GENBANK), id_txt,
12554 PRINTID_REPORT, sizeof (id_txt) - 1);
12555 fprintf (log_fp, "Reverse complemented %s\n", id_txt);
12556 *data_in_log = TRUE;
12557 }
12558
12559 /* update features */
12560 if (uop->submitter_opts->feature_import_options != NULL
12561 && uop->submitter_opts->feature_import_options->feature_import_type != eFeatureUpdateNoChange)
12562 {
12563 if (! SeqMgrFeaturesAreIndexed (update_entityID))
12564 SeqMgrIndexFeatures (update_entityID, NULL);
12565
12566 if (sequence_update_successful)
12567 {
12568 feature_update_offset = 0;
12569 if (uop->submitter_opts->sequence_update_type == eSequenceUpdateExtend3
12570 || uop->submitter_opts->sequence_update_type == eSequenceUpdatePatch)
12571 {
12572 if (upp->salp == NULL)
12573 {
12574 feature_update_offset = orig_seq_len;
12575 }
12576 else
12577 {
12578 feature_update_offset = ualp->old5 - ualp->new5;
12579 }
12580 }
12581 upp->feature_update_successful = ImportFeaturesWithOffset (upp, uop, ualp,
12582 feature_update_offset);
12583 rval &= upp->feature_update_successful;
12584 }
12585 else
12586 {
12587 upp->feature_update_successful = ImportFeaturesViaAlignment (upp, uop, ualp);
12588 }
12589 }
12590
12591 if (uop->submitter_opts->sequence_update_type == eSequenceUpdateReplace
12592 && upp->revcomp
12593 && sequence_update_successful)
12594 {
12595 ReverseComplementBioseqAndFeats (upp->orig_bsp, entityID);
12596 }
12597
12598
12599 if (uop->indexer_opts != NULL && uop->indexer_opts->add_cit_subs
12600 && (upp->feature_update_successful
12601 || (sequence_update_successful
12602 && ! AreSequenceResiduesIdentical(upp->orig_bsp, upp->update_bsp))))
12603
12604 {
12605 AddCitSubToUpdatedSequence (upp->orig_bsp, entityID, kSubmitterUpdateText);
12606 }
12607
12608 /* update proteins for coding regions on the updated sequence */
12609 if (sequence_update_successful
12610 && uop->indexer_opts != NULL
12611 && uop->indexer_opts->update_proteins
12612 && any_cds)
12613 {
12614 SeqMgrClearFeatureIndexes (entityID, upp->orig_bsp);
12615 SeqMgrIndexFeatures (entityID, NULL);
12616 UpdateProteinsForUpdatedCodingRegions (upp->orig_bsp, transl_except_list,
12617 uop->indexer_opts, entityID,
12618 log_fp, data_in_log);
12619 FixProtRefPtrs (prot_feat_list);
12620 }
12621
12622 if (trim_quality_scores && (uop->indexer_opts == NULL || !uop->indexer_opts->update_quality_scores)) {
12623 TrimQualityScoresForSequenceUpdate (upp->orig_bsp, ualp->old5, ualp->old3, log_fp, data_in_log);
12624 } else if (uop->indexer_opts != NULL && uop->indexer_opts->update_quality_scores
12625 && uop->submitter_opts->sequence_update_type == eSequenceUpdateReplace)
12626 {
12627 ReplaceQualityScores (upp->orig_bsp, upp->update_bsp,
12628 log_fp, data_in_log);
12629 }
12630 else if (uop->submitter_opts->sequence_update_type != eSequenceUpdateNoChange)
12631 {
12632 RemoveQualityScores (upp->orig_bsp, log_fp, data_in_log);
12633 }
12634
12635 prot_feat_list = ValNodeFree (prot_feat_list);
12636 transl_except_list = ValNodeFree (transl_except_list);
12637
12638 /* Note - we do not remove the update sequence here - that will happen when
12639 * the UpdateSequence form is removed.
12640 */
12641 upp->update_bsp = NULL;
12642
12643 return rval;
12644 }
12645
12646
12647 static Boolean
UpdateOrExtendOneSequence(UpdatePairPtr upp,UpdateOptionsPtr uop,UpdateAlignmentLengthsPtr ualp,Uint2 entityID,FILE * log_fp,BoolPtr data_in_log)12648 UpdateOrExtendOneSequence
12649 (UpdatePairPtr upp,
12650 UpdateOptionsPtr uop,
12651 UpdateAlignmentLengthsPtr ualp,
12652 Uint2 entityID,
12653 FILE *log_fp,
12654 BoolPtr data_in_log)
12655 {
12656 Boolean rval;
12657 SeqEntryPtr sep;
12658
12659 rval = UpdateOrExtendOneSequenceEx (upp, uop, ualp, entityID, log_fp, data_in_log, FALSE);
12660
12661 if (upp->feature_update_successful
12662 && uop->submitter_opts->feature_import_options != NULL
12663 && uop->submitter_opts->feature_import_options->feature_import_type > eFeatureUpdateNoChange
12664 && uop->submitter_opts->feature_import_options->feature_import_type != eFeatureRemoveAll)
12665 {
12666 /* resolve features unless the policy was to remove all the old ones */
12667
12668 sep = GetTopSeqEntryForEntityID (entityID);
12669 /* need to set scope to make sure we mark the right bioseq for deletion */
12670 SeqEntrySetScope (sep);
12671 ResolveDuplicateUpdateFeats (upp->orig_bsp, uop, upp->newfeat_sap);
12672 SeqEntrySetScope (NULL);
12673 DeleteMarkedObjects (entityID, 0, NULL);
12674 SeqMgrClearFeatureIndexes (entityID, NULL);
12675 }
12676 return rval;
12677 }
12678
12679
12680 static void
CalculateUpdateAlignmentLengths(SeqAlignPtr salp,BioseqPtr orig_bsp,BioseqPtr update_bsp,UpdateAlignmentLengthsPtr ualp)12681 CalculateUpdateAlignmentLengths
12682 (SeqAlignPtr salp,
12683 BioseqPtr orig_bsp,
12684 BioseqPtr update_bsp,
12685 UpdateAlignmentLengthsPtr ualp)
12686 {
12687 Int4 stopold, startold, lenold, stopnew, startnew, lennew;
12688 Int4 aln_length;
12689
12690 if (ualp == NULL || update_bsp == NULL || orig_bsp == NULL) return;
12691
12692 MemSet (ualp, 0, sizeof (UpdateAlignmentLengthsData));
12693
12694 if (salp == NULL)
12695 {
12696 return;
12697 }
12698
12699 ualp->aln_length = AlnMgr2GetAlnLength (salp, FALSE);
12700 AlnMgr2GetNthSeqRangeInSA (salp, 1, &startold, &stopold);
12701 AlnMgr2GetNthSeqRangeInSA (salp, 2, &startnew, &stopnew);
12702 lenold = orig_bsp->length;
12703 lennew = update_bsp->length;
12704
12705 ualp->old5 = startold;
12706 ualp->old3 = lenold - stopold - 1;
12707 ualp->olda = stopold - startold + 1;
12708
12709 ualp->new5 = startnew;
12710 ualp->new3 = lennew - stopnew - 1;
12711 ualp->newa = stopnew - startnew + 1;
12712
12713 #if 0
12714 ualp->startmax = MAX (startold, startnew);
12715 ualp->stopmax = MAX (aln_length + lenold - stopold, aln_length + lennew - stopnew);
12716
12717 ualp->strandold = AlnMgr2GetNthStrand (sap, 1);
12718 ualp->strandnew = AlnMgr2GetNthStrand (sap, 2);
12719 #endif
12720
12721 /* calculate logarithmic scale for length */
12722 ualp->log10_aln_length = 1;
12723 aln_length = ualp->aln_length;
12724 while (aln_length >= 10) {
12725 aln_length /= 10;
12726 (ualp->log10_aln_length)++;
12727 }
12728
12729 /* calculate alignment recombination lengths */
12730 ualp->recomb1 = -1;
12731 ualp->recomb2 = -1;
12732 if (ualp->new5 > ualp->old5 && ualp->new3 < ualp->old3) {
12733 ualp->recomb2 = ualp->aln_length;
12734 }
12735
12736 /* Extend 3' */
12737
12738 else if (ualp->new5 < ualp->old5 && ualp->new3 > ualp->old3) {
12739 ualp->recomb1 = 0;
12740 }
12741
12742 /* Replace */
12743
12744 else {
12745 ualp->recomb1 = 0;
12746 ualp->recomb2 = ualp->aln_length;
12747 }
12748
12749
12750 }
12751
12752 /* The following group of functions is used to generate the pictures for the
12753 * alignment viewer for the update sequence dialog.
12754 */
12755
12756 /* This function draws one rectangle for the new sequence and one rectangle for
12757 * the old sequence. The aligned overlap is filled in with black, the unaligned
12758 * portions are drawn with outlines only.
12759 */
MakeAlignmentOverviewPicture(UpdateAlignmentLengthsPtr ualp)12760 static SegmenT MakeAlignmentOverviewPicture (UpdateAlignmentLengthsPtr ualp)
12761
12762 {
12763 SegmenT pict;
12764 Char str [96];
12765 Int4 top, bottom;
12766
12767 pict = CreatePicture ();
12768 if (ualp == NULL) return pict;
12769
12770 top = 0;
12771 bottom = top - 10;
12772
12773 DrawAlignBlock (pict, top, bottom, bottom, LOWER_CENTER, ualp->old5, ualp->olda, ualp->old3, ualp->aln_length);
12774
12775 sprintf (str, "%ld", (long) ualp->aln_length);
12776 AddLabel (pict, ualp->aln_length / 2, 10, str, SMALL_TEXT, 5, MIDDLE_CENTER, 0);
12777
12778
12779 top = 30;
12780 bottom = top - 10;
12781
12782 DrawAlignBlock (pict, top, bottom, top, UPPER_CENTER, ualp->new5, ualp->newa, ualp->new3, ualp->aln_length);
12783
12784 return pict;
12785 }
12786
12787 /* This function shows how the new sequence will be created when the sequence is
12788 * extended and the alignment is ignored.
12789 */
MakeExtensionPicture(Int4 len_old,Int4 len_new,Boolean extend5)12790 static SegmenT MakeExtensionPicture (Int4 len_old, Int4 len_new, Boolean extend5)
12791
12792 {
12793 SegmenT pict;
12794 Char str [96];
12795 Int4 top, bottom, label_loc;
12796
12797 pict = CreatePicture ();
12798
12799 top = 0;
12800 bottom = top - 10;
12801
12802 label_loc = -(top + bottom) / 2;
12803
12804 if (extend5)
12805 {
12806 sprintf (str, "New (%ld)", (long) len_new);
12807 AddLabel (pict, -len_new / 2, label_loc, str, SMALL_TEXT, 5, MIDDLE_LEFT, 0);
12808 AddRectangle (pict, -len_new, top, 0, bottom, NO_ARROW, FALSE, 0);
12809 sprintf (str, "Old (%ld)", (long) len_old);
12810 AddLabel (pict, len_old / 2, label_loc - 30, str, SMALL_TEXT, 5, MIDDLE_RIGHT, 0);
12811 AddRectangle (pict, 0, top, len_old, bottom, NO_ARROW, FALSE, 0);
12812 }
12813 else
12814 {
12815 sprintf (str, "Old (%ld)", (long) len_old);
12816 AddLabel (pict, -len_old / 2, label_loc - 30, str, SMALL_TEXT, 5, MIDDLE_LEFT, 0);
12817 AddRectangle (pict, -len_old, top, 0, bottom, NO_ARROW, FALSE, 0);
12818 sprintf (str, "New (%ld)", (long) len_new);
12819 AddLabel (pict, len_new / 2, label_loc, str, SMALL_TEXT, 5, MIDDLE_RIGHT, 0);
12820 AddRectangle (pict, 0, top, len_new, bottom, NO_ARROW, FALSE, 0);
12821 }
12822
12823 return pict;
12824 }
12825
DrawUpdateAlignmentBits(SegmenT pict,Int4 top,Int4 bottom,Int4 row,Int4 pos1,Int4 pos2,SeqAlignPtr sap,ValNodePtr PNTR indels)12826 static void DrawUpdateAlignmentBits (
12827 SegmenT pict,
12828 Int4 top,
12829 Int4 bottom,
12830 Int4 row,
12831 Int4 pos1,
12832 Int4 pos2,
12833 SeqAlignPtr sap,
12834 ValNodePtr PNTR indels /* pointer to ValNode list of integers which are the locations
12835 * of insertions and deletions.
12836 */
12837 )
12838
12839 {
12840 AlnMsg2Ptr amp;
12841 Int4 len, start, stop, from, to;
12842 Char str [96];
12843 Boolean wasgap;
12844
12845 amp = AlnMsgNew2 ();
12846 if (amp == NULL) return;
12847
12848 amp->from_aln = 0;
12849 amp->to_aln = -1;
12850 amp->row_num = row;
12851
12852 start = 0;
12853 stop = 0;
12854 from = 0;
12855 to = 0;
12856 wasgap = FALSE;
12857
12858 while (AlnMgr2GetNextAlnBit (sap, amp)) {
12859 len = amp->to_row - amp->from_row + 1;
12860 stop = start + len;
12861 if (amp->type == AM_GAP) {
12862 if (wasgap) {
12863 to = stop;
12864 } else {
12865 AddRectangle (pict, from, top, to, bottom, NO_ARROW, FALSE, 0);
12866 wasgap = TRUE;
12867 from = start;
12868 to = stop;
12869 }
12870 } else {
12871 if (wasgap) {
12872
12873 /* record for accurate scrolling to text view */
12874 ValNodeAddInt (indels, 0, from);
12875
12876 AddLine (pict, from, (top + bottom) / 2, to, (top + bottom) / 2, FALSE, 0);
12877 wasgap = FALSE;
12878 from = start;
12879 to = stop;
12880 } else {
12881 to = stop;
12882 }
12883 }
12884 start += len;
12885 }
12886
12887 if (to > from) {
12888 if (wasgap) {
12889
12890 /* record for accurate scrolling to text view */
12891 ValNodeAddInt (indels, 0, from);
12892
12893 AddLine (pict, from, (top + bottom) / 2, to, (top + bottom) / 2, FALSE, 0);
12894 } else {
12895 AddRectangle (pict, from, top, to, bottom, NO_ARROW, FALSE, 0);
12896 }
12897 }
12898
12899 AlnMsgFree2 (amp);
12900
12901 sprintf (str, "%ld", (long) pos1);
12902 AddLabel (pict, 0, (top + bottom) / 2, str, SMALL_TEXT, 5, MIDDLE_LEFT, 0);
12903
12904 sprintf (str, "%ld", (long) pos2);
12905 AddLabel (pict, to, (top + bottom) / 2, str, SMALL_TEXT, 5, MIDDLE_RIGHT, 0);
12906 }
12907
DrawUpdateAlignmentDiffs(SegmenT pict,Int4 top,Int4 bottom,SeqAlignPtr salp,BioseqPtr orig_bsp,BioseqPtr update_bsp,ValNodePtr PNTR mismatches)12908 static void DrawUpdateAlignmentDiffs
12909 (SegmenT pict,
12910 Int4 top,
12911 Int4 bottom,
12912 SeqAlignPtr salp,
12913 BioseqPtr orig_bsp,
12914 BioseqPtr update_bsp,
12915 ValNodePtr PNTR mismatches)
12916
12917 {
12918 AlnMsg2Ptr amp1, amp2;
12919 SegmenT seg;
12920 Int4 len1, len2, i;
12921 Int4 seg_i, seg_n, seg_start, seg_stop;
12922 CharPtr seq1, seq2;
12923 Uint2 entityID;
12924 SeqEntryPtr sep;
12925
12926 if (salp == NULL || orig_bsp == NULL || update_bsp == NULL
12927 || pict == NULL || mismatches == NULL)
12928 {
12929 return;
12930 }
12931
12932 entityID = ObjMgrGetEntityIDForPointer (orig_bsp);
12933 sep = GetTopSeqEntryForEntityID (entityID);
12934 SeqEntrySetScope (sep);
12935 seq1 = GetSequenceByBsp (orig_bsp);
12936 SeqEntrySetScope (NULL);
12937
12938 entityID = update_bsp->idx.entityID;
12939 sep = GetTopSeqEntryForEntityID (entityID);
12940 SeqEntrySetScope (sep);
12941 seq2 = GetSequenceByBsp (update_bsp);
12942 SeqEntrySetScope (NULL);
12943
12944 if (seq1 == NULL || seq2 == NULL)
12945 {
12946 seq1 = MemFree (seq1);
12947 seq2 = MemFree (seq2);
12948 return;
12949 }
12950 len1 = StringLen (seq1);
12951 len2 = StringLen (seq2);
12952
12953 seg = CreateSegment (pict, 0, 0);
12954 AddAttribute (seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
12955
12956 seg_n = AlnMgr2GetNumSegs(salp);
12957 for (seg_i = 1; seg_i<=seg_n; seg_i++) {
12958 AlnMgr2GetNthSegmentRange(salp, seg_i, &seg_start, &seg_stop);
12959
12960 amp1 = AlnMsgNew2 ();
12961 amp2 = AlnMsgNew2 ();
12962 if (amp1 == NULL || amp2 == NULL) return;
12963
12964 amp1->from_aln = seg_start;
12965 amp1->to_aln = seg_stop;
12966 amp1->row_num = 1;
12967
12968 amp2->from_aln = seg_start;
12969 amp2->to_aln = seg_stop;
12970 amp2->row_num = 2;
12971
12972 AlnMgr2GetNextAlnBit (salp, amp1);
12973 AlnMgr2GetNextAlnBit (salp, amp2);
12974
12975 if (amp1->to_row - amp1->from_row == amp2->to_row - amp2->from_row &&
12976 amp1->type == AM_SEQ && amp2->type == AM_SEQ) {
12977 for (i=0; i<seg_stop-seg_start+1; i++) {
12978 if (seq1[amp1->from_row+i] != seq2[amp2->from_row+i]) {
12979
12980 /* record for accurate scrolling to text view */
12981 ValNodeAddInt (mismatches, 0, i);
12982
12983 AddLine (seg, seg_start+i, top, seg_start+i, bottom, FALSE, 0);
12984 }
12985 }
12986 }
12987
12988 AlnMsgFree2 (amp1);
12989 AlnMsgFree2 (amp2);
12990 }
12991 }
12992
12993 /* This function draws just the aligned region.
12994 */
MakeAlignmentDetailsPicture(SeqAlignPtr salp,BioseqPtr orig_bsp,BioseqPtr update_bsp,ValNodePtr PNTR indels,ValNodePtr PNTR mismatches,UpdateAlignmentLengthsPtr ualp,Boolean revcomp)12995 static SegmenT MakeAlignmentDetailsPicture
12996 (SeqAlignPtr salp,
12997 BioseqPtr orig_bsp,
12998 BioseqPtr update_bsp,
12999 ValNodePtr PNTR indels,
13000 ValNodePtr PNTR mismatches,
13001 UpdateAlignmentLengthsPtr ualp,
13002 Boolean revcomp)
13003
13004 {
13005 Int4 aln_length;
13006 SegmenT pict;
13007 Int4 top, bottom;
13008
13009 pict = CreatePicture ();
13010 if (salp == NULL || ualp == NULL || indels == NULL) return pict;
13011
13012 aln_length = ualp->aln_length;
13013
13014 top = 0;
13015 bottom = top - 10;
13016
13017 DrawUpdateAlignmentBits (pict, top, bottom, 1, ualp->old5 + 1,
13018 ualp->old5 + ualp->olda, salp, indels);
13019
13020 top = 30;
13021 bottom = top - 10;
13022
13023 if (revcomp) {
13024 DrawUpdateAlignmentBits (pict, top, bottom, 2, ualp->new3 + ualp->newa,
13025 ualp->new3 + 1, salp, indels);
13026 } else {
13027 DrawUpdateAlignmentBits (pict, top, bottom, 2, ualp->new5 + 1,
13028 ualp->new5 + ualp->newa, salp, indels);
13029 }
13030
13031 top = 15;
13032 bottom = top - 10;
13033
13034 DrawUpdateAlignmentDiffs (pict, top, bottom, salp, orig_bsp, update_bsp, mismatches);
13035
13036 return pict;
13037 }
13038
13039
13040
CalculateBestUpdateAlignmentViewerScale(VieweR vwr,SegmenT pict)13041 static Int4 CalculateBestUpdateAlignmentViewerScale (VieweR vwr, SegmenT pict)
13042
13043 {
13044 BoxInfo box;
13045 Int2 i;
13046 Int4 max, worldwid, portwid;
13047 RecT r;
13048 Int4 scaleX, oldscaleX;
13049 Int4 wid;
13050
13051 ObjectRect (vwr, &r);
13052 InsetRect (&r, 4, 4);
13053 wid = (Int4) (r.right - r.left + 1);
13054
13055 SegmentBox (pict, &box);
13056 oldscaleX = (box.right - box.left + wid - 1) / wid;
13057 RecalculateSegment (pict, oldscaleX, 1);
13058 SegmentBox (pict, &box);
13059 portwid = wid * oldscaleX;
13060 worldwid = box.right - box.left + 20 * oldscaleX + 1;
13061 max = MAX (worldwid, portwid);
13062 scaleX = (max + wid - 1) / wid;
13063 i = 0;
13064 while (i < 10 && (scaleX > oldscaleX || portwid < worldwid)) {
13065 oldscaleX = scaleX;
13066 RecalculateSegment (pict, oldscaleX, 1);
13067 SegmentBox (pict, &box);
13068 portwid = wid * oldscaleX;
13069 worldwid = box.right - box.left + 20 * oldscaleX + 1;
13070 max = MAX (worldwid, portwid);
13071 scaleX = (max + wid - 1) / wid;
13072 i++;
13073 }
13074
13075 return scaleX;
13076 }
13077
MakeUpdateAlignmentSequenceString(SeqAlignPtr sap,Int4 aln_length,Int4 row,CharPtr seq)13078 static CharPtr MakeUpdateAlignmentSequenceString
13079 ( SeqAlignPtr sap,
13080 Int4 aln_length,
13081 Int4 row,
13082 CharPtr seq)
13083
13084 {
13085 CharPtr aln;
13086 AlnMsg2Ptr amp;
13087 Int4 len, lens, start, stop, from, to, i, j;
13088
13089 if (sap == NULL || seq == NULL || aln_length < 1) return NULL;
13090 lens = StringLen (seq);
13091
13092 aln = (CharPtr) MemNew (sizeof (Char) * (aln_length + 2));
13093 if (aln == NULL) return NULL;
13094 MemSet ((Pointer) aln, '-', aln_length);
13095
13096 amp = AlnMsgNew2 ();
13097 if (amp == NULL) return aln;
13098
13099 amp->from_aln = 0;
13100 amp->to_aln = -1;
13101 amp->row_num = row;
13102
13103 start = 0;
13104 stop = 0;
13105 from = 0;
13106 to = 0;
13107
13108 while (AlnMgr2GetNextAlnBit (sap, amp)) {
13109 len = amp->to_row - amp->from_row + 1;
13110 stop = start + len;
13111
13112 if (amp->type == AM_SEQ) {
13113 for (i = start, j = amp->from_row; i < stop && j < lens; i++, j++) {
13114 aln [i] = seq [j];
13115 }
13116 }
13117 start += len;
13118 }
13119
13120 AlnMsgFree2 (amp);
13121
13122 return aln;
13123 }
13124
13125 /* The alignment letters panel draws the individual letters of the sequence, showing
13126 * insertions, deletions, and mismatches.
13127 */
13128 typedef struct alignmentletterspanel
13129 {
13130 DIALOG_MESSAGE_BLOCK
13131 PaneL letters;
13132
13133 Int4 lineheight; /* height of lines in the letters panel */
13134 Int4 charwidth; /* width of characters in the letters panel */
13135 Int4 maxchars; /* maximum number of characters that can be
13136 * displayed in the letters panel.
13137 */
13138
13139 UpdateAlignmentLengthsData uald; /* structure that holds the length of the alignment,
13140 * the lengths of the 3' and 5' overlaps, etc.
13141 */
13142 CharPtr aln1; /* holds the string representation of the alignment
13143 * for the original sequence
13144 */
13145 CharPtr aln2; /* holds the string representation of the alignment
13146 * for the update sequence
13147 */
13148
13149 SeqAlignPtr salp; /* alignment used for update */
13150 /* This alignment should not be freed by this panel.
13151 */
13152 Boolean revcomp;
13153 } AlignmentLettersPanelData, PNTR AlignmentLettersPanelPtr;
13154
13155 static void
PaintAlignmentString(CharPtr aln_str,Int4 char_offset,Int4 char_width,Int4 left_pos,Int4 top_pos,Int4 right_pos,Int4 maxchars,Int4 aln_length)13156 PaintAlignmentString
13157 (CharPtr aln_str,
13158 Int4 char_offset,
13159 Int4 char_width,
13160 Int4 left_pos,
13161 Int4 top_pos,
13162 Int4 right_pos,
13163 Int4 maxchars,
13164 Int4 aln_length)
13165 {
13166 Int2 i;
13167 Int4 j;
13168 Int4 pos_offset;
13169
13170 if (aln_str != NULL)
13171 {
13172 MoveTo (left_pos, top_pos);
13173 pos_offset = left_pos;
13174 for (i = 0, j = char_offset, pos_offset = left_pos;
13175 i < maxchars && j < aln_length && pos_offset + char_width <= right_pos;
13176 i++, j++, pos_offset += char_width) {
13177 PaintChar (aln_str [j]);
13178 }
13179 }
13180
13181 }
13182
13183
UpdateAlignmentLettersPanelOnDraw(PaneL pnl)13184 static void UpdateAlignmentLettersPanelOnDraw (PaneL pnl)
13185
13186 {
13187 Char ch1, ch2;
13188 Int2 i, k, q, left, top, bottom, arrowwidth;
13189 size_t len;
13190 Int4 offset, j, pos, realpos;
13191 RecT r, x;
13192 BaR sb;
13193 Char str [32];
13194 AlignmentLettersPanelPtr dlg;
13195
13196 dlg = (AlignmentLettersPanelPtr) GetObjectExtra (pnl);
13197 if (dlg == NULL) return;
13198
13199 ObjectRect (pnl, &r);
13200 InsetRect (&r, 4, 4);
13201
13202 sb = GetSlateHScrollBar ((SlatE) pnl);
13203 offset = GetBarValue (sb);
13204
13205 SelectFont (SetSmallFont ());
13206
13207 /* draw top (new) letters */
13208
13209 PaintAlignmentString (dlg->aln2, offset, dlg->charwidth,
13210 r.left, r.top + 8 + 3 * dlg->lineheight,
13211 r.right,
13212 dlg->maxchars,
13213 dlg->uald.aln_length);
13214
13215 /* draw bottom (old) letters */
13216
13217 PaintAlignmentString (dlg->aln1, offset, dlg->charwidth,
13218 r.left, r.top + 8 + 5 * dlg->lineheight,
13219 r.right,
13220 dlg->maxchars,
13221 dlg->uald.aln_length);
13222
13223 /* draw recombination arrows */
13224
13225 arrowwidth = MIN (6, dlg->charwidth);
13226 if (dlg->uald.recomb1 >= offset && dlg->uald.recomb1 <= offset + dlg->maxchars) {
13227 left = r.left + dlg->charwidth * (dlg->uald.recomb1 - offset);
13228 LoadRect (&x, left, r.top, left + arrowwidth, r.top + 6);
13229 CopyBits (&x, leftTriFillSym);
13230 }
13231
13232 if (dlg->uald.recomb2 >= offset && dlg->uald.recomb2 <= offset + dlg->maxchars) {
13233 left = r.left + dlg->charwidth * (dlg->uald.recomb2 - offset - 1);
13234 LoadRect (&x, left, r.top, left + arrowwidth, r.top + 6);
13235 CopyBits (&x, rightTriFillSym);
13236 }
13237
13238 if (dlg->aln1 == NULL || dlg->aln2 == NULL)
13239 {
13240 return;
13241 }
13242 /* draw red mismatch lines */
13243
13244 Red ();
13245 top = r.top + 8 + 4 * dlg->lineheight - Ascent ();
13246 bottom = top + dlg->lineheight - 2;
13247
13248 for (i = 0, j = offset; i < dlg->maxchars && j < dlg->uald.aln_length; i++, j++) {
13249 ch1 = dlg->aln1 [j];
13250 ch2 = dlg->aln2 [j];
13251 if (ch1 == ch2) {
13252 } else if (ch1 == '-' || ch2 == '-') {
13253 } else {
13254 left = r.left + i * dlg->charwidth + dlg->charwidth / 2 - 1;
13255 MoveTo (left, top);
13256 LineTo (left, bottom);
13257 }
13258 }
13259 Black ();
13260
13261 /* draw top (new) tick marks and coordinates */
13262
13263 bottom = r.top + 8 + 3 * dlg->lineheight - Ascent () - 2;
13264 top = bottom - 5;
13265 i = 0;
13266 j = offset;
13267 pos = AlnMgr2MapSeqAlignToBioseq (dlg->salp, j, 2);
13268 while (pos < 1 && i < dlg->maxchars && j < dlg->uald.aln_length) {
13269 i++;
13270 j++;
13271 pos = AlnMgr2MapSeqAlignToBioseq (dlg->salp, j, 2);
13272 }
13273 for (; i < dlg->maxchars + dlg->uald.log10_aln_length && j < dlg->uald.aln_length; i++, j++) {
13274 ch1 = dlg->aln2 [j];
13275 if (ch1 != '-') {
13276 if (dlg->revcomp) {
13277 realpos = (dlg->uald.new5 + dlg->uald.newa + dlg->uald.new3 - pos - 1);
13278 } else {
13279 realpos = pos;
13280 }
13281 if (((realpos + 1) % 10) == 0) {
13282 left = r.left + i * dlg->charwidth + dlg->charwidth / 2 - 1;
13283 if (i < dlg->maxchars && left <= r.right - dlg->charwidth) {
13284 MoveTo (left, top);
13285 LineTo (left, bottom);
13286 }
13287 sprintf (str, "%ld", (long) (realpos + 1));
13288 len = StringLen (str);
13289 if (len <= j + 1) {
13290 k = i - len + 1;
13291 q = 0;
13292 if (k < 0) {
13293 q -= k;
13294 k = 0;
13295 }
13296 if (q < len) {
13297 left = r.left + k * dlg->charwidth;
13298 MoveTo (left, r.top + 8 + dlg->lineheight);
13299 while (k < dlg->maxchars && q < len && left <= r.right - dlg->charwidth) {
13300 PaintChar (str [q]);
13301 k++;
13302 q++;
13303 left += dlg->charwidth;
13304 }
13305 }
13306 }
13307 } else if (((realpos + 1) % 5) == 0) {
13308 left = r.left + i * dlg->charwidth + dlg->charwidth / 2 - 1;
13309 if (i < dlg->maxchars && left <= r.right - dlg->charwidth) {
13310 MoveTo (left, top + 3);
13311 LineTo (left, bottom);
13312 }
13313 }
13314 pos++;
13315 }
13316 }
13317
13318 /* draw bottom (old) tick marks and coordinates */
13319
13320 top = r.top + 8 + 6 * dlg->lineheight - Ascent () + 2;
13321 bottom = top + 5;
13322 i = 0;
13323 j = offset;
13324 pos = AlnMgr2MapSeqAlignToBioseq (dlg->salp, j, 1);
13325 while (pos < 1 && i < dlg->maxchars && j < dlg->uald.aln_length) {
13326 i++;
13327 j++;
13328 pos = AlnMgr2MapSeqAlignToBioseq (dlg->salp, j, 1);
13329 }
13330 for (; i < dlg->maxchars + dlg->uald.log10_aln_length && j < dlg->uald.aln_length; i++, j++) {
13331 ch1 = dlg->aln1 [j];
13332 if (ch1 != '-') {
13333 if (((pos + 1) % 10) == 0) {
13334 left = r.left + i * dlg->charwidth + dlg->charwidth / 2 - 1;
13335 if (i < dlg->maxchars && left <= r.right - dlg->charwidth) {
13336 MoveTo (left, top);
13337 LineTo (left, bottom);
13338 }
13339 sprintf (str, "%ld", (long) (pos + 1));
13340 len = StringLen (str);
13341 if (len <= j + 1) {
13342 k = i - len + 1;
13343 q = 0;
13344 if (k < 0) {
13345 q -= k;
13346 k = 0;
13347 }
13348 if (q < len) {
13349 left = r.left + k * dlg->charwidth;
13350 MoveTo (left, r.top + 8 + 7 * dlg->lineheight);
13351 while (k < dlg->maxchars && q < len && left <= r.right - dlg->charwidth) {
13352 PaintChar (str [q]);
13353 k++;
13354 q++;
13355 left += dlg->charwidth;
13356 }
13357 }
13358 }
13359 } else if (((pos + 1) % 5) == 0) {
13360 left = r.left + i * dlg->charwidth + dlg->charwidth / 2 - 1;
13361 if (i < dlg->maxchars && left <= r.right - dlg->charwidth) {
13362 MoveTo (left, top);
13363 LineTo (left, bottom - 3);
13364 }
13365 }
13366 pos++;
13367 }
13368 }
13369 SelectFont (systemFont);
13370 }
13371
UpdateAlignmentLettersPanelOnScroll(BaR sb,SlatE slt,Int4 newval,Int4 oldval)13372 static void UpdateAlignmentLettersPanelOnScroll (
13373 BaR sb,
13374 SlatE slt,
13375 Int4 newval,
13376 Int4 oldval
13377 )
13378
13379 {
13380 RecT r;
13381 AlignmentLettersPanelPtr dlg;
13382 Int4 scroll_distance;
13383
13384 dlg = (AlignmentLettersPanelPtr) GetObjectExtra (slt);
13385 if (dlg == NULL) return;
13386
13387 ObjectRect (dlg->letters, &r);
13388 InsetRect (&r, 4, 4);
13389 Select (dlg->letters);
13390 if (ABS (oldval - newval) < dlg->maxchars) {
13391 scroll_distance = (oldval - newval) * dlg->charwidth;
13392 ScrollRect (&r, scroll_distance, 0);
13393 if (scroll_distance > 0)
13394 {
13395 r.left += scroll_distance;
13396 r.right = r.left + dlg->charwidth;
13397 }
13398 else
13399 {
13400 r.right += scroll_distance;
13401 r.left = r.right - dlg->charwidth;
13402 }
13403 InvalRect (&r);
13404 } else {
13405 InsetRect (&r, -2, -2);
13406 InvalRect (&r);
13407 }
13408 Update ();
13409 }
13410
UpdatePairToAlignmentLettersPanel(DialoG d,Pointer data)13411 static void UpdatePairToAlignmentLettersPanel (DialoG d, Pointer data)
13412 {
13413 AlignmentLettersPanelPtr dlg;
13414 UpdatePairPtr upp;
13415 CharPtr seq_orig, seq_update;
13416 BaR sb;
13417 RecT r;
13418
13419 dlg = (AlignmentLettersPanelPtr) GetObjectExtra (d);
13420 if (dlg == NULL)
13421 {
13422 return;
13423 }
13424
13425 dlg->aln1 = MemFree (dlg->aln1);
13426 dlg->aln2 = MemFree (dlg->aln2);
13427 dlg->salp = NULL;
13428 dlg->revcomp = FALSE;
13429 dlg->salp = NULL;
13430 MemSet (&(dlg->uald), 0, sizeof (UpdateAlignmentLengthsData));
13431
13432 upp = (UpdatePairPtr) data;
13433 if (upp != NULL && upp->salp != NULL)
13434 {
13435 dlg->salp = upp->salp;
13436 dlg->revcomp = upp->revcomp;
13437
13438 CalculateUpdateAlignmentLengths (upp->salp, upp->orig_bsp, upp->update_bsp, &(dlg->uald));
13439
13440 /* create alignment string for original */
13441 seq_orig = GetSequenceByBsp (upp->orig_bsp);
13442 dlg->aln1 = MakeUpdateAlignmentSequenceString (upp->salp, dlg->uald.aln_length,
13443 1, seq_orig);
13444 seq_orig = MemFree (seq_orig);
13445
13446 /* create alignment string for update */
13447 seq_update = GetSequenceByBsp (upp->update_bsp);
13448 dlg->aln2 = MakeUpdateAlignmentSequenceString (upp->salp, dlg->uald.aln_length,
13449 2, seq_update);
13450 seq_update = MemFree (seq_update);
13451
13452 sb = GetSlateHScrollBar ((SlatE) dlg->letters);
13453 SetBarMax (sb, dlg->uald.aln_length - (Int4) dlg->maxchars);
13454 CorrectBarPage (sb, (Int4) dlg->maxchars - 1, (Int4) dlg->maxchars - 1);
13455 }
13456
13457 ObjectRect (dlg->letters, &r);
13458 InvalRect (&r);
13459
13460 }
13461
AlignmentLettersPanel(GrouP parent,Int4 prompt_width,Int4 hgt)13462 static DialoG AlignmentLettersPanel (GrouP parent, Int4 prompt_width, Int4 hgt)
13463 {
13464 AlignmentLettersPanelPtr dlg;
13465 GrouP p;
13466 RecT r;
13467
13468 dlg = (AlignmentLettersPanelPtr) MemNew (sizeof (AlignmentLettersPanelData));
13469 if (dlg == NULL)
13470 {
13471 return NULL;
13472 }
13473
13474 p = HiddenGroup (parent, 1, 0, NULL);
13475 SetObjectExtra (p, dlg, StdCleanupExtraProc);
13476 dlg->dialog = (DialoG) p;
13477 dlg->todialog = UpdatePairToAlignmentLettersPanel;
13478
13479 dlg->aln1 = NULL;
13480 dlg->aln2 = NULL;
13481 dlg->salp = NULL;
13482 dlg->revcomp = FALSE;
13483 MemSet (&(dlg->uald), 0, sizeof (UpdateAlignmentLengthsData));
13484
13485 dlg->letters = AutonomousPanel4 (p, prompt_width + Nlm_vScrollBarWidth, hgt,
13486 UpdateAlignmentLettersPanelOnDraw,
13487 NULL, UpdateAlignmentLettersPanelOnScroll, 0, NULL, NULL);
13488 SetObjectExtra (dlg->letters, (Pointer) dlg, NULL);
13489
13490 SelectFont (SetSmallFont ());
13491 ObjectRect (dlg->letters, &r);
13492 InsetRect (&r, 4, 4);
13493 dlg->lineheight = LineHeight ();
13494 dlg->charwidth = MaxCharWidth ();
13495 dlg->maxchars = (r.right-r.left-2+dlg->charwidth - 1) / dlg->charwidth;
13496 SelectFont (systemFont);
13497 return (DialoG) p;
13498 }
13499
GetAlignmentLettersPanelMaxchars(DialoG d)13500 static Int4 GetAlignmentLettersPanelMaxchars (DialoG d)
13501 {
13502 AlignmentLettersPanelPtr dlg;
13503
13504 dlg = (AlignmentLettersPanelPtr) GetObjectExtra (d);
13505 if (dlg == NULL)
13506 {
13507 return 0;
13508 }
13509 else
13510 {
13511 return dlg->maxchars;
13512 }
13513 }
13514
GetAlignmentLettersScrollPosition(DialoG d)13515 static Int4 GetAlignmentLettersScrollPosition (DialoG d)
13516 {
13517 AlignmentLettersPanelPtr dlg;
13518 BaR sb;
13519
13520 dlg = (AlignmentLettersPanelPtr) GetObjectExtra (d);
13521 if (dlg == NULL)
13522 {
13523 return 0;
13524 }
13525
13526 sb = GetSlateHScrollBar ((SlatE) dlg->letters);
13527
13528 return GetBarValue (sb);
13529 }
13530
ScrollAlignmentLettersPanel(DialoG d,Int4 pos)13531 static void ScrollAlignmentLettersPanel (DialoG d, Int4 pos)
13532 {
13533 AlignmentLettersPanelPtr dlg;
13534 BaR sb;
13535
13536 dlg = (AlignmentLettersPanelPtr) GetObjectExtra (d);
13537 if (dlg == NULL)
13538 {
13539 return;
13540 }
13541
13542 sb = GetSlateHScrollBar ((SlatE) dlg->letters);
13543
13544 SetBarValue (sb, pos);
13545 }
13546
13547 typedef struct updatetitlesdialog
13548 {
13549 DIALOG_MESSAGE_BLOCK
13550
13551 PrompT new_sequence_id_ppt; /* indicate which sequence is being used for the update */
13552 PrompT new_sequence_length_ppt;
13553 PrompT old_sequence_id_ppt; /* indicates which sequence is being updated */
13554 PrompT old_sequence_length_ppt;
13555
13556 BioseqPtr orig_bsp; /* original bioseq */
13557 BioseqPtr update_bsp; /* update bioseq */
13558 Uint2 entityID_orig;
13559 Uint2 entityID_update;
13560 Boolean is_indexer;
13561 Boolean is_update;
13562 } UpdateTitlesDialogData, PNTR UpdateTitlesDialogPtr;
13563
UpdatePairFromUpdateTitlesDialog(DialoG d)13564 static Pointer UpdatePairFromUpdateTitlesDialog (DialoG d)
13565 {
13566 UpdateTitlesDialogPtr dlg;
13567 UpdatePairPtr upp;
13568
13569 dlg = (UpdateTitlesDialogPtr) GetObjectExtra (d);
13570 if (dlg == NULL)
13571 {
13572 return NULL;
13573 }
13574
13575 upp = (UpdatePairPtr) MemNew (sizeof (UpdatePairData));
13576 if (upp != NULL)
13577 {
13578 upp->orig_bsp = dlg->orig_bsp;
13579 upp->update_bsp = dlg->update_bsp;
13580 upp->revcomp = FALSE;
13581 upp->salp = NULL;
13582 }
13583
13584 return upp;
13585 }
13586
UpdatePairToUpdateTitlesDialog(DialoG d,Pointer data)13587 static void UpdatePairToUpdateTitlesDialog (DialoG d, Pointer data)
13588 {
13589 UpdateTitlesDialogPtr dlg;
13590 UpdatePairPtr upp;
13591 Char ppt_txt [500];
13592 Char id_txt [MAX_ID_LEN];
13593
13594 dlg = (UpdateTitlesDialogPtr) GetObjectExtra (d);
13595 if (dlg == NULL)
13596 {
13597 return;
13598 }
13599
13600 dlg->orig_bsp = NULL;
13601 dlg->update_bsp = NULL;
13602
13603 upp = (UpdatePairPtr) data;
13604
13605 if (upp == NULL)
13606 {
13607 SafeHide (dlg->new_sequence_id_ppt);
13608 SafeHide (dlg->new_sequence_length_ppt);
13609 SafeHide (dlg->old_sequence_id_ppt);
13610 SafeHide (dlg->old_sequence_length_ppt);
13611 return;
13612 }
13613
13614 dlg->orig_bsp = upp->orig_bsp;
13615 dlg->update_bsp = upp->update_bsp;
13616
13617 if (upp->orig_bsp == NULL)
13618 {
13619 SafeHide (dlg->new_sequence_id_ppt);
13620 SafeHide (dlg->new_sequence_length_ppt);
13621 SafeHide (dlg->old_sequence_id_ppt);
13622 SafeHide (dlg->old_sequence_length_ppt);
13623 }
13624 /* show no update message */
13625 else if (upp->update_bsp == NULL)
13626 {
13627 SeqIdWrite (SeqIdFindBest (upp->orig_bsp->id, SEQID_GENBANK), id_txt,
13628 PRINTID_REPORT, sizeof (id_txt) - 50);
13629 if (dlg->is_indexer)
13630 {
13631 sprintf (ppt_txt, "No update sequence for %s", id_txt);
13632 SetTitle (dlg->new_sequence_id_ppt, ppt_txt);
13633 sprintf (ppt_txt, "Length %ld", (long) upp->orig_bsp->length);
13634 SetTitle (dlg->new_sequence_length_ppt, ppt_txt);
13635 }
13636 else
13637 {
13638 sprintf (ppt_txt, "No update sequence for %s (length %ld)",
13639 id_txt, (long) upp->orig_bsp->length);
13640 SetTitle (dlg->new_sequence_id_ppt, ppt_txt);
13641 }
13642 SafeHide (dlg->old_sequence_id_ppt);
13643 SafeHide (dlg->old_sequence_length_ppt);
13644 }
13645 /* show no alignment message */
13646 else if (upp->salp == NULL && dlg->is_update)
13647 {
13648 SeqIdWrite (SeqIdFindBest (upp->orig_bsp->id, SEQID_GENBANK), id_txt,
13649 PRINTID_REPORT, sizeof (id_txt));
13650 if (dlg->is_indexer)
13651 {
13652 sprintf (ppt_txt, "No alignment for %s", id_txt);
13653 SetTitle (dlg->new_sequence_id_ppt, ppt_txt);
13654 sprintf (ppt_txt, "Length: %ld", (long) dlg->orig_bsp->length);
13655 SetTitle (dlg->new_sequence_length_ppt, ppt_txt);
13656 }
13657 else
13658 {
13659 sprintf (ppt_txt, "No alignment for %s Length: %ld", id_txt, (long) dlg->orig_bsp->length);
13660 SetTitle (dlg->new_sequence_id_ppt, ppt_txt);
13661 }
13662 SafeHide (dlg->old_sequence_id_ppt);
13663 SafeHide (dlg->old_sequence_length_ppt);
13664 }
13665 else
13666 {
13667 /* update sequence title prompts */
13668 SeqIdWrite (SeqIdFindBest (dlg->update_bsp->id, SEQID_GENBANK), id_txt,
13669 PRINTID_REPORT, sizeof (id_txt));
13670 if (dlg->is_indexer)
13671 {
13672 sprintf (ppt_txt, "New sequence: %s", id_txt);
13673 SetTitle (dlg->new_sequence_id_ppt, ppt_txt);
13674 sprintf (ppt_txt, "Length: %ld", (long) dlg->update_bsp->length);
13675 SetTitle (dlg->new_sequence_length_ppt, ppt_txt);
13676 }
13677 else
13678 {
13679 sprintf (ppt_txt, "New sequence: %s Length: %ld", id_txt, (long) dlg->update_bsp->length);
13680 SetTitle (dlg->new_sequence_id_ppt, ppt_txt);
13681 }
13682
13683 SeqIdWrite (SeqIdFindBest (dlg->orig_bsp->id, SEQID_GENBANK), id_txt,
13684 PRINTID_REPORT, sizeof (id_txt));
13685 if (dlg->is_indexer)
13686 {
13687 sprintf (ppt_txt, "Old sequence: %s", id_txt);
13688 SetTitle (dlg->old_sequence_id_ppt, ppt_txt);
13689 sprintf (ppt_txt, "Length: %ld", (long) dlg->orig_bsp->length);
13690 SetTitle (dlg->old_sequence_length_ppt, ppt_txt);
13691 }
13692 else
13693 {
13694 sprintf (ppt_txt, "Old sequence: %s Length: %ld", id_txt, (long) dlg->orig_bsp->length);
13695 SetTitle (dlg->old_sequence_id_ppt, ppt_txt);
13696 }
13697
13698 SafeShow (dlg->new_sequence_id_ppt);
13699 SafeShow (dlg->new_sequence_length_ppt);
13700 SafeShow (dlg->old_sequence_id_ppt);
13701 SafeShow (dlg->old_sequence_length_ppt);
13702 }
13703 }
13704
UpdateTitlesDialog(GrouP parent,Boolean is_indexer,Boolean is_update)13705 static DialoG UpdateTitlesDialog (GrouP parent, Boolean is_indexer, Boolean is_update)
13706 {
13707 UpdateTitlesDialogPtr dlg;
13708 GrouP p;
13709 Int4 prompt_width = 450;
13710
13711 dlg = (UpdateTitlesDialogPtr) MemNew (sizeof (UpdateTitlesDialogData));
13712 if (dlg == NULL)
13713 {
13714 return NULL;
13715 }
13716
13717 p = HiddenGroup (parent, -1, 0, NULL);
13718 SetObjectExtra (p, dlg, StdCleanupExtraProc);
13719 SetGroupSpacing (p, 2, 2);
13720
13721 dlg->dialog = (DialoG) p;
13722
13723 dlg->todialog = UpdatePairToUpdateTitlesDialog;
13724 dlg->fromdialog = UpdatePairFromUpdateTitlesDialog;
13725
13726 dlg->is_indexer = is_indexer;
13727 dlg->is_update = is_update;
13728
13729 if (is_indexer)
13730 {
13731 prompt_width = 400;
13732 }
13733 else
13734 {
13735 prompt_width = 550;
13736 }
13737
13738 dlg->new_sequence_id_ppt = StaticPrompt (p, "", prompt_width,
13739 dialogTextHeight, programFont, 'l');
13740 if (is_indexer)
13741 {
13742 dlg->new_sequence_length_ppt = StaticPrompt (p, "", prompt_width,
13743 dialogTextHeight, programFont, 'l');
13744 }
13745 else
13746 {
13747 dlg->new_sequence_length_ppt = NULL;
13748 }
13749
13750 dlg->old_sequence_id_ppt = StaticPrompt (p, "", prompt_width, dialogTextHeight, programFont, 'l');
13751 if (is_indexer)
13752 {
13753 dlg->old_sequence_length_ppt = StaticPrompt (p, "", prompt_width,
13754 dialogTextHeight, programFont, 'l');
13755 }
13756
13757 return (DialoG) p;
13758 }
13759
13760 typedef struct updatepreviewdialog
13761 {
13762 DIALOG_MESSAGE_BLOCK
13763
13764 GrouP viewer_grp; /* group that contains viewers and prompts
13765 * this group is hidden when there is no alignment
13766 */
13767 VieweR overview; /* shows sequence lengths/overlap */
13768 GrouP details_grp;
13769 VieweR details; /* shows individual mismatches/deletions/insertions */
13770 GrouP letters_grp;
13771 DialoG letters_dlg; /* shows sequence and gap characters and coordinates */
13772
13773 SegmenT overview_picture; /* picture of sequence lengths/overlap */
13774 SegmenT details_picture; /* picture of mismatches/deletions/insertions */
13775 Int4 details_scaleX; /* scale at which the details picture is displayed */
13776
13777 UpdateAlignmentLengthsData uald; /* structure that holds the length of the alignment,
13778 * the lengths of the 3' and 5' overlaps, etc.
13779 */
13780 ValNodePtr indels; /* ValNode structure that holds the positions
13781 * of insertions and deletions (in alignment
13782 * coordinates)
13783 */
13784 ValNodePtr mismatches; /* ValNode structure that holds the positions
13785 * of mismatches (in alignment coordinates)
13786 */
13787
13788 SeqAlignPtr salp; /* alignment used for update */
13789 /* The UpdatePreviewDialog is responsible for freeing
13790 * the alignment passed to it.
13791 */
13792 BioseqPtr orig_bsp; /* original bioseq */
13793 BioseqPtr update_bsp; /* update bioseq */
13794 Uint2 entityID_orig;
13795 Uint2 entityID_update;
13796 Boolean revcomp;
13797
13798 Boolean ignore_alignment;
13799 Boolean extend5;
13800 } UpdatePreviewDialogData, PNTR UpdatePreviewDialogPtr;
13801
13802 /* if the user clicks on the details picture, scroll to the appropriate position
13803 * in the letters panel.
13804 */
UpdateAlignmentDetailsOnClick(VieweR vwr,SegmenT pict,PoinT pt)13805 static void UpdateAlignmentDetailsOnClick (VieweR vwr, SegmenT pict, PoinT pt)
13806
13807 {
13808 Int4 goHere;
13809 Int4 offset;
13810 Int4 maxchars;
13811 Int4 maxover2;
13812 PntInfo pnt;
13813 UpdatePreviewDialogPtr dlg;
13814 ValNodePtr vnp;
13815
13816 dlg = (UpdatePreviewDialogPtr) GetViewerData (vwr);
13817 if (dlg == NULL) return;
13818
13819 MapViewerToWorld (vwr, pt, &pnt);
13820 maxchars = GetAlignmentLettersPanelMaxchars (dlg->letters_dlg);
13821 maxover2 = maxchars / 2;
13822 if (pnt.x <= 0) {
13823 pnt.x = 0;
13824 } else if (pnt.x >= dlg->uald.aln_length) {
13825 pnt.x = dlg->uald.aln_length - maxchars;
13826 } else if (pnt.x >= maxover2) {
13827
13828 offset = GetAlignmentLettersScrollPosition (dlg->letters_dlg);
13829
13830 /* look for clicks within 5 pixels of an indel start or a mismatch */
13831
13832 goHere = -1;
13833 for (vnp = dlg->indels; vnp != NULL && goHere < 0; vnp = vnp->next) {
13834 if (ABS (pnt.x - vnp->data.intvalue) < dlg->details_scaleX * 5) {
13835 goHere = vnp->data.intvalue;
13836 }
13837 }
13838 for (vnp = dlg->mismatches; vnp != NULL && goHere < 0; vnp = vnp->next) {
13839 if (ABS (pnt.x - vnp->data.intvalue) < dlg->details_scaleX * 5) {
13840 goHere = vnp->data.intvalue;
13841 }
13842 }
13843
13844 if (goHere >= 0) {
13845 pnt.x = goHere;
13846 } else {
13847 /* if already visible, no need to scroll */
13848 if (pnt.x - maxover2 > offset && pnt.x - maxover2 < offset + maxover2 - 5) return;
13849 if (pnt.x - maxover2 < offset && pnt.x - maxover2 > offset - maxover2 + 5) return;
13850 }
13851
13852 /* go left 1/2 screen so desired point is in the middle */
13853
13854 pnt.x -= maxover2;
13855 }
13856
13857 ResetClip ();
13858 ScrollAlignmentLettersPanel (dlg->letters_dlg, pnt.x);
13859 Update ();
13860 }
13861
UpdatePairFromUpdatePreviewDialog(DialoG d)13862 static Pointer UpdatePairFromUpdatePreviewDialog (DialoG d)
13863 {
13864 UpdatePreviewDialogPtr dlg;
13865 UpdatePairPtr upp;
13866
13867 dlg = (UpdatePreviewDialogPtr) GetObjectExtra (d);
13868 if (dlg == NULL)
13869 {
13870 return NULL;
13871 }
13872
13873 upp = (UpdatePairPtr) MemNew (sizeof (UpdatePairData));
13874 if (upp != NULL)
13875 {
13876 upp->orig_bsp = dlg->orig_bsp;
13877 upp->update_bsp = dlg->update_bsp;
13878 upp->revcomp = dlg->revcomp;
13879 upp->salp = dlg->salp;
13880 }
13881
13882 return upp;
13883 }
13884
RedrawAlignmentPreview(DialoG d)13885 static void RedrawAlignmentPreview (DialoG d)
13886 {
13887 UpdatePreviewDialogPtr dlg;
13888 UpdatePairData upd;
13889 Int4 scaleX;
13890
13891 dlg = (UpdatePreviewDialogPtr) GetObjectExtra (d);
13892 if (dlg == NULL)
13893 {
13894 return;
13895 }
13896
13897 upd.orig_bsp = dlg->orig_bsp;
13898 upd.update_bsp = dlg->update_bsp;
13899 upd.salp = dlg->salp;
13900 upd.revcomp = dlg->revcomp;
13901
13902 /* reverse the sequence for drawing purposes */
13903 if (upd.revcomp)
13904 {
13905 BioseqRevComp (upd.update_bsp);
13906 ReverseBioseqFeatureStrands (upd.update_bsp);
13907 SeqMgrReplaceInBioseqIndex (upd.update_bsp);
13908 }
13909
13910 if (dlg->salp == NULL
13911 || dlg->orig_bsp == NULL
13912 || dlg->update_bsp == NULL)
13913 {
13914 dlg->overview_picture = CreatePicture ();
13915 AttachPicture (dlg->overview, dlg->overview_picture, 0, 0, UPPER_LEFT,
13916 1, 1, FrameVwr);
13917 dlg->details_picture = CreatePicture ();
13918 AttachPicture (dlg->details, dlg->details_picture, 0, 0, UPPER_LEFT,
13919 1, 1, FrameVwr);
13920 MemSet (&(dlg->uald), 0, sizeof (UpdateAlignmentLengthsData));
13921
13922 PointerToDialog (dlg->letters_dlg, NULL);
13923
13924 Hide (dlg->viewer_grp);
13925 /* reverse the sequence for drawing purposes */
13926 if (upd.revcomp)
13927 {
13928 BioseqRevComp (upd.update_bsp);
13929 ReverseBioseqFeatureStrands (upd.update_bsp);
13930 SeqMgrReplaceInBioseqIndex (upd.update_bsp);
13931 }
13932
13933 return;
13934 }
13935
13936 CalculateUpdateAlignmentLengths (dlg->salp, dlg->orig_bsp, dlg->update_bsp, &(dlg->uald));
13937
13938 if (dlg->ignore_alignment)
13939 {
13940 dlg->overview_picture = MakeExtensionPicture (dlg->orig_bsp->length, dlg->update_bsp->length, dlg->extend5);
13941 }
13942 else
13943 {
13944 dlg->overview_picture = MakeAlignmentOverviewPicture (&(dlg->uald));
13945 }
13946
13947 scaleX = CalculateBestUpdateAlignmentViewerScale (dlg->overview, dlg->overview_picture);
13948 AttachPicture (dlg->overview, dlg->overview_picture, 0, 0, UPPER_LEFT,
13949 scaleX, 1, FrameVwr);
13950
13951 dlg->indels = ValNodeFree (dlg->indels);
13952 dlg->details_picture = MakeAlignmentDetailsPicture (dlg->salp,
13953 dlg->orig_bsp,
13954 dlg->update_bsp,
13955 &(dlg->indels),
13956 &(dlg->mismatches),
13957 &(dlg->uald), dlg->revcomp);
13958 dlg->details_scaleX = CalculateBestUpdateAlignmentViewerScale (dlg->details, dlg->details_picture);
13959 AttachPicture (dlg->details, dlg->details_picture, 0, 0, UPPER_LEFT,
13960 dlg->details_scaleX, 1, FrameVwr);
13961 SetViewerData (dlg->details, (Pointer) dlg, NULL);
13962 SetViewerProcs (dlg->details, UpdateAlignmentDetailsOnClick, NULL, NULL, NULL);
13963
13964 /* sort the insertions and deletions so they will be in order */
13965 dlg->indels = ValNodeSort (dlg->indels, SortVnpByInt);
13966 /* sort the matches so that they will be in order */
13967 dlg->mismatches = ValNodeSort (dlg->mismatches, SortVnpByInt);
13968
13969 PointerToDialog (dlg->letters_dlg, &upd);
13970 Show (dlg->viewer_grp);
13971 if (dlg->ignore_alignment)
13972 {
13973 Hide (dlg->details_grp);
13974 Hide (dlg->letters_grp);
13975 }
13976 else
13977 {
13978 Show (dlg->details_grp);
13979 Show (dlg->letters_grp);
13980 }
13981
13982 /* unreverse the sequence if it was reversed */
13983 if (upd.revcomp)
13984 {
13985 BioseqRevComp (upd.update_bsp);
13986 ReverseBioseqFeatureStrands (upd.update_bsp);
13987 SeqMgrReplaceInBioseqIndex (upd.update_bsp);
13988 }
13989
13990 }
13991
AlignmentToUpdatePreviewDialog(DialoG d,Pointer data)13992 static void AlignmentToUpdatePreviewDialog (DialoG d, Pointer data)
13993 {
13994 UpdatePreviewDialogPtr dlg;
13995 UpdatePairPtr upp;
13996
13997 dlg = (UpdatePreviewDialogPtr) GetObjectExtra (d);
13998 if (dlg == NULL)
13999 {
14000 return;
14001 }
14002
14003 dlg->overview_picture = DeletePicture (dlg->overview_picture);
14004 dlg->details_picture = DeletePicture (dlg->details_picture);
14005 dlg->salp = NULL;
14006 dlg->orig_bsp = NULL;
14007 dlg->update_bsp = NULL;
14008 dlg->revcomp = FALSE;
14009 dlg->salp = SeqAlignFree (dlg->salp);
14010
14011 upp = (UpdatePairPtr) data;
14012
14013 if (upp != NULL)
14014 {
14015 dlg->salp = upp->salp;
14016 dlg->revcomp = upp->revcomp;
14017 dlg->orig_bsp = upp->orig_bsp;
14018 dlg->update_bsp = upp->update_bsp;
14019 if (dlg->update_bsp != NULL && BioseqFind (dlg->update_bsp->id) != dlg->update_bsp)
14020 {
14021 SeqMgrReplaceInBioseqIndex (dlg->update_bsp);
14022 }
14023 }
14024
14025 RedrawAlignmentPreview (d);
14026 }
14027
SetIgnoreAndExtendForPreviewPictures(DialoG d,Boolean ignore_alignment,Boolean extend5)14028 static void SetIgnoreAndExtendForPreviewPictures (DialoG d, Boolean ignore_alignment, Boolean extend5)
14029 {
14030 UpdatePreviewDialogPtr dlg;
14031
14032 dlg = (UpdatePreviewDialogPtr) GetObjectExtra (d);
14033 if (dlg == NULL)
14034 {
14035 return;
14036 }
14037 dlg->ignore_alignment = ignore_alignment;
14038 dlg->extend5 = extend5;
14039 RedrawAlignmentPreview (d);
14040 }
14041
CleanupPreviewDialog(GraphiC g,Pointer data)14042 static void CleanupPreviewDialog (GraphiC g, Pointer data)
14043 {
14044 UpdatePreviewDialogPtr dlg;
14045
14046 dlg = (UpdatePreviewDialogPtr) data;
14047 if (dlg != NULL)
14048 {
14049 dlg->indels = ValNodeFree (dlg->indels);
14050 dlg->mismatches = ValNodeFree (dlg->mismatches);
14051 dlg->salp = SeqAlignFree (dlg->salp);
14052 }
14053 StdCleanupExtraProc (g, data);
14054 }
14055
UpdatePreviewDialog(GrouP parent,Boolean is_indexer)14056 static DialoG UpdatePreviewDialog (GrouP parent, Boolean is_indexer)
14057 {
14058 UpdatePreviewDialogPtr dlg;
14059 GrouP p;
14060 Int4 prompt_width = 400, hgt;
14061 GrouP ppt1, ppt2, ppt3;
14062
14063 dlg = (UpdatePreviewDialogPtr) MemNew (sizeof (UpdatePreviewDialogData));
14064 if (dlg == NULL)
14065 {
14066 return NULL;
14067 }
14068
14069 p = HiddenGroup (parent, -1, 0, NULL);
14070 SetObjectExtra (p, dlg, CleanupPreviewDialog);
14071 SetGroupSpacing (p, 2, 2);
14072
14073 dlg->dialog = (DialoG) p;
14074
14075 dlg->todialog = AlignmentToUpdatePreviewDialog;
14076 dlg->fromdialog = UpdatePairFromUpdatePreviewDialog;
14077
14078 dlg->viewer_grp = HiddenGroup (p, -1, 0, NULL);
14079 SetGroupSpacing (dlg->viewer_grp, 2, 2);
14080 ppt1 = MultiLinePrompt (dlg->viewer_grp, txt1, prompt_width, programFont);
14081 dlg->overview = CreateViewer (dlg->viewer_grp, prompt_width + Nlm_vScrollBarWidth, 100,
14082 FALSE, FALSE);
14083
14084 dlg->details_grp = HiddenGroup (dlg->viewer_grp, -1, 0, NULL);
14085 SetGroupSpacing (dlg->details_grp, 2, 2);
14086 ppt2 = MultiLinePrompt (dlg->details_grp, txt2, prompt_width, programFont);
14087 dlg->details = CreateViewer (dlg->details_grp, prompt_width + Nlm_vScrollBarWidth, 80,
14088 FALSE, FALSE);
14089 AlignObjects (ALIGN_CENTER, (HANDLE) ppt2, (HANDLE) dlg->details, NULL);
14090
14091 dlg->letters_grp = HiddenGroup (dlg->viewer_grp, -1, 0, NULL);
14092 SetGroupSpacing (dlg->letters_grp, 2, 2);
14093 ppt3 = MultiLinePrompt (dlg->letters_grp, txt3, prompt_width, programFont);
14094
14095 #ifdef WIN_MAC
14096 hgt = 90;
14097 #else
14098 hgt = 110;
14099 #endif
14100
14101 dlg->letters_dlg = AlignmentLettersPanel (dlg->letters_grp, prompt_width, hgt);
14102 AlignObjects (ALIGN_CENTER, (HANDLE) ppt3, (HANDLE) dlg->letters_dlg, NULL);
14103
14104 dlg->overview_picture = NULL;
14105 dlg->details_picture = NULL;
14106 dlg->indels = NULL;
14107 dlg->mismatches = NULL;
14108 MemSet (&(dlg->uald), 0, sizeof (UpdateAlignmentLengthsData));
14109
14110
14111
14112 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->overview,
14113 (HANDLE) dlg->details_grp,
14114 (HANDLE) dlg->letters_grp,
14115 (HANDLE) ppt1,
14116 NULL);
14117
14118 return (DialoG) p;
14119 }
14120
14121
14122 typedef struct submitterfeatureimportoptionsdialog
14123 {
14124 DIALOG_MESSAGE_BLOCK
14125
14126 GrouP feature_update_type;
14127
14128 Nlm_ChangeNotifyProc change_notify;
14129 Pointer change_userdata;
14130 } SubmitterFeatureImportOptionsDlgData, PNTR SubmitterFeatureImportOptionsDlgPtr;
14131
14132
SubmitterFeatureImportOptionsToDialog(DialoG d,Pointer data)14133 static void SubmitterFeatureImportOptionsToDialog (DialoG d, Pointer data)
14134 {
14135 SubmitterFeatureImportOptionsDlgPtr dlg;
14136 FeatureImportOptionsPtr f;
14137
14138 dlg = (SubmitterFeatureImportOptionsDlgPtr) GetObjectExtra (d);
14139 if (dlg == NULL) {
14140 return;
14141 }
14142
14143 if ((f = (FeatureImportOptionsPtr) data) == NULL) {
14144 SetValue (dlg->feature_update_type, eFeatureUpdateNoChange);
14145 } else {
14146 SetValue (dlg->feature_update_type, f->feature_import_type);
14147 }
14148 }
14149
14150
SubmitterFeatureImportOptionsFromDialog(DialoG d)14151 static Pointer SubmitterFeatureImportOptionsFromDialog (DialoG d)
14152 {
14153 SubmitterFeatureImportOptionsDlgPtr dlg;
14154 FeatureImportOptionsPtr f;
14155
14156 dlg = (SubmitterFeatureImportOptionsDlgPtr) GetObjectExtra (d);
14157 if (dlg == NULL) {
14158 return NULL;
14159 }
14160
14161 f = FeatureImportOptionsNew ();
14162 f->feature_import_type = GetValue (dlg->feature_update_type);
14163 return f;
14164 }
14165
14166
ChangeSubmitterFeatureImportOptionsDialogGroup(GrouP g)14167 static void ChangeSubmitterFeatureImportOptionsDialogGroup (GrouP g)
14168 {
14169 SubmitterFeatureImportOptionsDlgPtr dlg;
14170
14171 dlg = (SubmitterFeatureImportOptionsDlgPtr) GetObjectExtra (g);
14172 if (dlg == NULL) {
14173 return;
14174 }
14175
14176 if (dlg->change_notify != NULL) {
14177 (dlg->change_notify)(dlg->change_userdata);
14178 }
14179 }
14180
14181
14182 static DialoG
SubmitterFeatureImportOptionsDialog(GrouP parent,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)14183 SubmitterFeatureImportOptionsDialog
14184 (GrouP parent,
14185 Nlm_ChangeNotifyProc change_notify,
14186 Pointer change_userdata)
14187 {
14188 SubmitterFeatureImportOptionsDlgPtr dlg;
14189 GrouP p;
14190
14191 dlg = (SubmitterFeatureImportOptionsDlgPtr) MemNew (sizeof (SubmitterFeatureImportOptionsDlgData));
14192 if (dlg == NULL)
14193 {
14194 return NULL;
14195 }
14196
14197 p = NormalGroup (parent, 1, 0, "Import Features", programFont, NULL);
14198 SetObjectExtra (p, dlg, StdCleanupExtraProc);
14199 SetGroupSpacing (p, 10, 10);
14200
14201 dlg->dialog = (DialoG) p;
14202 dlg->todialog = SubmitterFeatureImportOptionsToDialog;
14203 dlg->fromdialog = SubmitterFeatureImportOptionsFromDialog;
14204
14205 dlg->change_notify = change_notify;
14206 dlg->change_userdata = change_userdata;
14207
14208 dlg->feature_update_type = HiddenGroup (p, 0, 6, ChangeSubmitterFeatureImportOptionsDialogGroup);
14209 SetObjectExtra (dlg->feature_update_type, dlg, NULL);
14210 RadioButton (dlg->feature_update_type, "Do not import features");
14211 RadioButton (dlg->feature_update_type, "Import all except duplicates");
14212 RadioButton (dlg->feature_update_type, "Import all, merge duplicates");
14213 RadioButton (dlg->feature_update_type, "Import all, replace duplicates");
14214 RadioButton (dlg->feature_update_type, "Import all, including duplicates");
14215 SetValue (dlg->feature_update_type, eFeatureUpdateNoChange);
14216
14217 return (DialoG) p;
14218 }
14219
14220
14221 typedef struct indexerfeatureimportoptionsdialog
14222 {
14223 DIALOG_MESSAGE_BLOCK
14224
14225 ButtoN do_import_btn;
14226 DialoG feature_types;
14227 GrouP feature_update_type;
14228
14229 Nlm_ChangeNotifyProc change_notify;
14230 Pointer change_userdata;
14231 } IndexerFeatureImportOptionsDlgData, PNTR IndexerFeatureImportOptionsDlgPtr;
14232
14233
IndexerFeatureImportOptionsToDialog(DialoG d,Pointer data)14234 static void IndexerFeatureImportOptionsToDialog (DialoG d, Pointer data)
14235 {
14236 IndexerFeatureImportOptionsDlgPtr dlg;
14237 FeatureImportOptionsPtr f;
14238
14239 dlg = (IndexerFeatureImportOptionsDlgPtr) GetObjectExtra (d);
14240 if (dlg == NULL) {
14241 return;
14242 }
14243
14244 if ((f = (FeatureImportOptionsPtr) data) == NULL || f->feature_import_type == eFeatureUpdateNoChange) {
14245 SetStatus (dlg->do_import_btn, FALSE);
14246 Disable (dlg->feature_types);
14247 Disable (dlg->feature_update_type);
14248 } else {
14249 SetStatus (dlg->do_import_btn, TRUE);
14250 if (f->feature_types == NULL) {
14251 SendMessageToDialog (dlg->feature_types, NUM_VIB_MSG + 1);
14252 } else {
14253 PointerToDialog (dlg->feature_types, f->feature_types);
14254 }
14255 SetValue (dlg->feature_update_type, f->feature_import_type - 1);
14256 }
14257 }
14258
14259
IndexerFeatureImportOptionsFromDialog(DialoG d)14260 static Pointer IndexerFeatureImportOptionsFromDialog (DialoG d)
14261 {
14262 IndexerFeatureImportOptionsDlgPtr dlg;
14263 FeatureImportOptionsPtr f = NULL;
14264
14265 dlg = (IndexerFeatureImportOptionsDlgPtr) GetObjectExtra (d);
14266 if (dlg == NULL) {
14267 return NULL;
14268 }
14269
14270 if (GetStatus (dlg->do_import_btn)) {
14271 f = FeatureImportOptionsNew ();
14272 f->feature_import_type = GetValue (dlg->feature_update_type) + 1;
14273 f->feature_types = DialogToPointer (dlg->feature_types);
14274 if (f->feature_types != NULL && (f->feature_types->choice == FEATDEF_ANY || f->feature_types->choice == 0)) {
14275 f->feature_types = ValNodeFree (f->feature_types);
14276 }
14277 }
14278 return f;
14279 }
14280
14281
ChangeIndexerFeatureImportOptionsDialogGroup(GrouP g)14282 static void ChangeIndexerFeatureImportOptionsDialogGroup (GrouP g)
14283 {
14284 IndexerFeatureImportOptionsDlgPtr dlg;
14285
14286 dlg = (IndexerFeatureImportOptionsDlgPtr) GetObjectExtra (g);
14287 if (dlg == NULL) {
14288 return;
14289 }
14290
14291 if (dlg->change_notify != NULL) {
14292 (dlg->change_notify)(dlg->change_userdata);
14293 }
14294 }
14295
14296
ChangeIndexerFeatureImportOptionsDialogBtn(ButtoN b)14297 static void ChangeIndexerFeatureImportOptionsDialogBtn (ButtoN b)
14298 {
14299 IndexerFeatureImportOptionsDlgPtr dlg;
14300 ValNodePtr tmp;
14301
14302 dlg = (IndexerFeatureImportOptionsDlgPtr) GetObjectExtra (b);
14303 if (dlg == NULL) {
14304 return;
14305 }
14306 if (GetStatus (dlg->do_import_btn)) {
14307 Enable (dlg->feature_update_type);
14308 Enable (dlg->feature_types);
14309 tmp = DialogToPointer (dlg->feature_types);
14310 if (tmp == NULL) {
14311 SendMessageToDialog (dlg->feature_types, NUM_VIB_MSG + 1);
14312 } else {
14313 tmp = ValNodeFree (tmp);
14314 }
14315 } else {
14316 Disable (dlg->feature_update_type);
14317 Disable (dlg->feature_types);
14318 }
14319
14320 if (dlg->change_notify != NULL) {
14321 (dlg->change_notify)(dlg->change_userdata);
14322 }
14323 }
14324
14325
14326 static DialoG
IndexerFeatureImportOptionsDialog(GrouP parent,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)14327 IndexerFeatureImportOptionsDialog
14328 (GrouP parent,
14329 Nlm_ChangeNotifyProc change_notify,
14330 Pointer change_userdata)
14331 {
14332 IndexerFeatureImportOptionsDlgPtr dlg;
14333 GrouP p;
14334
14335 dlg = (IndexerFeatureImportOptionsDlgPtr) MemNew (sizeof (IndexerFeatureImportOptionsDlgData));
14336 if (dlg == NULL)
14337 {
14338 return NULL;
14339 }
14340
14341 p = NormalGroup (parent, 3, 0, "Import Features", programFont, NULL);
14342 SetObjectExtra (p, dlg, StdCleanupExtraProc);
14343 SetGroupSpacing (p, 10, 10);
14344
14345 dlg->dialog = (DialoG) p;
14346 dlg->todialog = IndexerFeatureImportOptionsToDialog;
14347 dlg->fromdialog = IndexerFeatureImportOptionsFromDialog;
14348
14349 dlg->change_notify = change_notify;
14350 dlg->change_userdata = change_userdata;
14351
14352 dlg->do_import_btn = CheckBox (p, "Import features", ChangeIndexerFeatureImportOptionsDialogBtn);
14353 SetObjectExtra (dlg->do_import_btn, dlg, NULL);
14354 dlg->feature_types = FeatureTypeDialogMulti (p, change_notify, change_userdata);
14355 SendMessageToDialog (dlg->feature_types, NUM_VIB_MSG + 1);
14356 dlg->feature_update_type = HiddenGroup (p, 0, 6, ChangeIndexerFeatureImportOptionsDialogGroup);
14357 SetObjectExtra (dlg->feature_update_type, dlg, NULL);
14358 RadioButton (dlg->feature_update_type, "Except duplicates");
14359 RadioButton (dlg->feature_update_type, "Merge duplicates");
14360 RadioButton (dlg->feature_update_type, "Replace duplicates");
14361 RadioButton (dlg->feature_update_type, "Including duplicates");
14362 SetValue (dlg->feature_update_type, 1);
14363
14364 return (DialoG) p;
14365 }
14366
14367
14368 typedef struct submitterupdateoptionsdialog
14369 {
14370 DIALOG_MESSAGE_BLOCK
14371 GrouP sequence_update_type;
14372 DialoG feature_update_options;
14373 GrouP feature_remove_type;
14374
14375 ButtoN sequence_update_btns [eSequenceUpdateExtend3];
14376
14377 ButtoN ignore_alignment;
14378
14379 Boolean do_update;
14380
14381 Nlm_ChangeNotifyProc change_notify;
14382 Pointer change_userdata;
14383
14384 } SubmitterUpdateOptionsDialogData, PNTR SubmitterUpdateOptionsDialogPtr;
14385
SubmitterUpdateOptionsToDialog(DialoG d,Pointer data)14386 static void SubmitterUpdateOptionsToDialog (DialoG d, Pointer data)
14387 {
14388 SubmitterUpdateOptionsDialogPtr dlg;
14389 SubmitterUpdateOptionsPtr suop;
14390
14391 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (d);
14392 if (dlg == NULL)
14393 {
14394 return;
14395 }
14396
14397 suop = (SubmitterUpdateOptionsPtr) data;
14398 if (dlg->do_update)
14399 {
14400 if (suop == NULL)
14401 {
14402 SetValue (dlg->sequence_update_type, eSequenceUpdateNoChange);
14403 PointerToDialog (dlg->feature_update_options, NULL);
14404 SetValue (dlg->feature_remove_type, eFeatureRemoveNone);
14405 SetStatus (dlg->ignore_alignment, FALSE);
14406 }
14407 else
14408 {
14409 SetValue (dlg->sequence_update_type, suop->sequence_update_type);
14410 PointerToDialog (dlg->feature_update_options, suop->feature_import_options);
14411 SetValue (dlg->feature_remove_type, suop->feature_remove_type);
14412 SetStatus (dlg->ignore_alignment, suop->ignore_alignment);
14413 }
14414 }
14415 else
14416 {
14417 if (suop == NULL)
14418 {
14419 SetValue (dlg->sequence_update_type, 1);
14420 PointerToDialog (dlg->feature_update_options, NULL);
14421 SetValue (dlg->feature_remove_type, eFeatureRemoveNone);
14422 }
14423 else
14424 {
14425 if (suop->sequence_update_type == eSequenceUpdateExtend3)
14426 {
14427 SetValue (dlg->sequence_update_type, 2);
14428 }
14429 else
14430 {
14431 SetValue (dlg->sequence_update_type, 1);
14432 }
14433
14434 PointerToDialog (dlg->feature_update_options, suop->feature_import_options);
14435 SetValue (dlg->feature_remove_type, suop->feature_remove_type);
14436 }
14437 }
14438
14439 if (dlg->change_notify != NULL)
14440 {
14441 (dlg->change_notify) (dlg->change_userdata);
14442 }
14443
14444 }
14445
SubmitterUpdateOptionsFromDialog(DialoG d)14446 static Pointer SubmitterUpdateOptionsFromDialog (DialoG d)
14447 {
14448 SubmitterUpdateOptionsDialogPtr dlg;
14449 SubmitterUpdateOptionsPtr suop;
14450
14451 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (d);
14452 if (dlg == NULL)
14453 {
14454 return NULL;
14455 }
14456
14457 suop = (SubmitterUpdateOptionsPtr) MemNew (sizeof (SubmitterUpdateOptionsData));
14458 if (suop != NULL)
14459 {
14460 if (dlg->do_update)
14461 {
14462 suop->sequence_update_type = (ESequenceUpdateType) GetValue (dlg->sequence_update_type);
14463 if (suop->sequence_update_type > eSequenceUpdateNoChange
14464 && ! Enabled (dlg->sequence_update_btns [suop->sequence_update_type - 1]))
14465 {
14466 suop->sequence_update_type = eSequenceUpdateNoChange;
14467 }
14468 }
14469 else
14470 {
14471 if (GetValue (dlg->sequence_update_type) == 2)
14472 {
14473 suop->sequence_update_type = eSequenceUpdateExtend3;
14474 }
14475 else
14476 {
14477 suop->sequence_update_type = eSequenceUpdateExtend5;
14478 }
14479 }
14480
14481 suop->feature_import_options = DialogToPointer (dlg->feature_update_options);
14482 suop->feature_remove_type = (EFeatureRemoveType) GetValue (dlg->feature_remove_type);
14483
14484 if (dlg->do_update)
14485 {
14486 if (Enabled (dlg->ignore_alignment)
14487 && (suop->sequence_update_type == eSequenceUpdateExtend5
14488 || suop->sequence_update_type == eSequenceUpdateExtend3
14489 || suop->sequence_update_type == eSequenceUpdateReplace))
14490 {
14491 suop->ignore_alignment = GetStatus (dlg->ignore_alignment);
14492 }
14493 else
14494 {
14495 suop->ignore_alignment = FALSE;
14496 }
14497 }
14498 else
14499 {
14500 suop->ignore_alignment = TRUE;
14501 }
14502 }
14503 return suop;
14504 }
14505
DisableSubmitterImportFeatureOptions(DialoG d)14506 static void DisableSubmitterImportFeatureOptions (DialoG d)
14507 {
14508 SubmitterUpdateOptionsDialogPtr dlg;
14509
14510 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (d);
14511 if (dlg == NULL)
14512 {
14513 return;
14514 }
14515
14516 Disable (dlg->feature_update_options);
14517 }
14518
EnableSubmitterImportFeatureOptions(DialoG d)14519 static void EnableSubmitterImportFeatureOptions (DialoG d)
14520 {
14521 SubmitterUpdateOptionsDialogPtr dlg;
14522
14523 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (d);
14524 if (dlg == NULL)
14525 {
14526 return;
14527 }
14528
14529 Enable (dlg->feature_update_options);
14530 }
14531
DisableSubmitterRemoveFeatureOptions(DialoG d)14532 static void DisableSubmitterRemoveFeatureOptions (DialoG d)
14533 {
14534 SubmitterUpdateOptionsDialogPtr dlg;
14535
14536 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (d);
14537 if (dlg == NULL)
14538 {
14539 return;
14540 }
14541
14542 Disable (dlg->feature_remove_type);
14543 }
14544
EnableSubmitterRemoveFeatureOptions(DialoG d)14545 static void EnableSubmitterRemoveFeatureOptions (DialoG d)
14546 {
14547 SubmitterUpdateOptionsDialogPtr dlg;
14548
14549 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (d);
14550 if (dlg == NULL)
14551 {
14552 return;
14553 }
14554
14555 Enable (dlg->feature_remove_type);
14556 }
14557
AdjustSequenceUpdateOptionsEnabled(DialoG d,UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp,Boolean is_indexer)14558 static void AdjustSequenceUpdateOptionsEnabled
14559 (DialoG d,
14560 UpdatePairPtr upp,
14561 UpdateAlignmentLengthsPtr ualp,
14562 Boolean is_indexer)
14563 {
14564 SubmitterUpdateOptionsDialogPtr dlg;
14565 ESequenceUpdateType action;
14566 Boolean ignore_alignment;
14567 SubmitterUpdateOptionsPtr suop;
14568
14569 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (d);
14570 if (dlg == NULL)
14571 {
14572 return;
14573 }
14574
14575 if (!dlg->do_update)
14576 {
14577 Enable (dlg->sequence_update_btns [0]);
14578 Enable (dlg->sequence_update_btns [1]);
14579 return;
14580 }
14581
14582 suop = DialogToPointer (d);
14583
14584 if (upp == NULL || upp->salp == NULL)
14585 {
14586 Disable (dlg->ignore_alignment);
14587 ignore_alignment = TRUE;
14588 }
14589 else if (suop != NULL
14590 && (suop->sequence_update_type == eSequenceUpdateNoChange
14591 || suop->sequence_update_type == eSequenceUpdatePatch))
14592 {
14593 Disable (dlg->ignore_alignment);
14594 ignore_alignment = FALSE;
14595 }
14596 else
14597 {
14598
14599 Enable (dlg->ignore_alignment);
14600 ignore_alignment = GetStatus (dlg->ignore_alignment);
14601 }
14602
14603 for (action = eSequenceUpdateNoChange;
14604 action <= eSequenceUpdateExtend3;
14605 action++)
14606 {
14607 if (IsSequenceUpdateChoiceAllowed (action, upp, ualp, is_indexer,
14608 ignore_alignment))
14609 {
14610 Enable (dlg->sequence_update_btns [action - 1]);
14611 }
14612 else
14613 {
14614 Disable (dlg->sequence_update_btns [action - 1]);
14615 }
14616 }
14617
14618 }
14619
IgnoreAlignmentBtn(ButtoN b)14620 static void IgnoreAlignmentBtn (ButtoN b)
14621 {
14622 SubmitterUpdateOptionsDialogPtr dlg;
14623
14624 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (b);
14625 if (dlg != NULL && dlg->change_notify != NULL)
14626 {
14627 (dlg->change_notify) (dlg->change_userdata);
14628 }
14629 }
14630
UpdateTypeGroup(GrouP g)14631 static void UpdateTypeGroup (GrouP g)
14632 {
14633 SubmitterUpdateOptionsDialogPtr dlg;
14634
14635 dlg = (SubmitterUpdateOptionsDialogPtr) GetObjectExtra (g);
14636 if (dlg != NULL && dlg->change_notify != NULL)
14637 {
14638 (dlg->change_notify) (dlg->change_userdata);
14639 }
14640 }
14641
14642 static DialoG
SubmitterUpdateOptionsDialog(GrouP parent,Boolean is_indexer,Boolean do_update,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)14643 SubmitterUpdateOptionsDialog
14644 (GrouP parent,
14645 Boolean is_indexer,
14646 Boolean do_update,
14647 Nlm_ChangeNotifyProc change_notify,
14648 Pointer change_userdata)
14649 {
14650 SubmitterUpdateOptionsDialogPtr dlg;
14651 GrouP p, j, k, g;
14652
14653 dlg = (SubmitterUpdateOptionsDialogPtr) MemNew (sizeof (SubmitterUpdateOptionsDialogData));
14654 if (dlg == NULL)
14655 {
14656 return NULL;
14657 }
14658
14659 if (is_indexer)
14660 {
14661 p = HiddenGroup (parent, -1, 0, NULL);
14662 }
14663 else
14664 {
14665 p = HiddenGroup (parent, 1, 0, NULL);
14666 }
14667 SetObjectExtra (p, dlg, StdCleanupExtraProc);
14668 SetGroupSpacing (p, 10, 10);
14669
14670 dlg->dialog = (DialoG) p;
14671 dlg->todialog = SubmitterUpdateOptionsToDialog;
14672 dlg->fromdialog = SubmitterUpdateOptionsFromDialog;
14673
14674 dlg->change_notify = change_notify;
14675 dlg->change_userdata = change_userdata;
14676
14677 dlg->do_update = do_update;
14678
14679 if (dlg->do_update)
14680 {
14681 j = NormalGroup (p, -1, 0, "Sequence Update", programFont, NULL);
14682 if (is_indexer)
14683 {
14684 dlg->sequence_update_type = HiddenGroup (j, 0, 1, UpdateTypeGroup);
14685 }
14686 else
14687 {
14688 SetGroupSpacing (j, 3, 10);
14689 dlg->sequence_update_type = HiddenGroup (j, 1, 0, UpdateTypeGroup);
14690 SetGroupSpacing (dlg->sequence_update_type, 3, 2);
14691 }
14692 SetObjectExtra (dlg->sequence_update_type, dlg, NULL);
14693 dlg->sequence_update_btns [0] = RadioButton (dlg->sequence_update_type, "No change");
14694 dlg->sequence_update_btns [1] = RadioButton (dlg->sequence_update_type, "Replace");
14695 dlg->sequence_update_btns [2] = RadioButton (dlg->sequence_update_type, "Patch");
14696 dlg->sequence_update_btns [3] = RadioButton (dlg->sequence_update_type, "Extend 5'");
14697 dlg->sequence_update_btns [4] = RadioButton (dlg->sequence_update_type, "Extend 3'");
14698 SetValue (dlg->sequence_update_type, eSequenceUpdateNoChange);
14699 dlg->ignore_alignment = CheckBox (j, "Ignore alignment", IgnoreAlignmentBtn);
14700 SetObjectExtra (dlg->ignore_alignment, dlg, NULL);
14701 if (is_indexer)
14702 {
14703 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->sequence_update_type,
14704 (HANDLE) dlg->ignore_alignment,
14705 NULL);
14706 }
14707 else
14708 {
14709 AlignObjects (ALIGN_LEFT, (HANDLE) dlg->sequence_update_type,
14710 (HANDLE) dlg->ignore_alignment,
14711 NULL);
14712 }
14713 }
14714 else
14715 {
14716 j = NormalGroup (p, -1, 0, "Extend Sequence", programFont, NULL);
14717 dlg->sequence_update_type = HiddenGroup (j, 0, 1, NULL);
14718 dlg->sequence_update_btns [0] = RadioButton (dlg->sequence_update_type, "Extend 5'");
14719 dlg->sequence_update_btns [1] = RadioButton (dlg->sequence_update_type, "Extend 3'");
14720 dlg->sequence_update_btns [2] = NULL;
14721 dlg->sequence_update_btns [3] = NULL;
14722 dlg->sequence_update_btns [4] = NULL;
14723
14724 SetValue (dlg->sequence_update_type, 1);
14725 dlg->ignore_alignment = NULL;
14726 }
14727
14728 if (is_indexer)
14729 {
14730 k = HiddenGroup (p, 2, 0, NULL);
14731 }
14732 else
14733 {
14734 k = p;
14735 }
14736
14737 g = NormalGroup (k, 1, 0, "Existing Features", programFont, NULL);
14738 dlg->feature_remove_type = HiddenGroup (g, 0, 6, NULL);
14739 RadioButton (dlg->feature_remove_type, "Do not remove");
14740 RadioButton (dlg->feature_remove_type, "Remove in aligned area");
14741 RadioButton (dlg->feature_remove_type, "Remove outside aligned area");
14742 RadioButton (dlg->feature_remove_type, "Remove all");
14743 SetValue (dlg->feature_remove_type, eFeatureRemoveNone);
14744
14745 if (is_indexer) {
14746 dlg->feature_update_options = IndexerFeatureImportOptionsDialog (k, NULL, NULL);
14747 } else {
14748 dlg->feature_update_options = SubmitterFeatureImportOptionsDialog (k, NULL, NULL);
14749 }
14750
14751 if (is_indexer)
14752 {
14753 AlignObjects (ALIGN_CENTER, (HANDLE) j,
14754 (HANDLE) k,
14755 NULL);
14756 }
14757
14758 return (DialoG) p;
14759 }
14760
14761 typedef struct indexeroptionsdialog
14762 {
14763 DIALOG_MESSAGE_BLOCK
14764 ButtoN keep_protein_ids;
14765 ButtoN add_cit_subs;
14766 ButtoN update_quality_scores;
14767 ButtoN update_proteins;
14768 GrouP protein_options;
14769 ButtoN truncate_proteins;
14770 ButtoN extend_proteins3;
14771 ButtoN extend_proteins5;
14772 ButtoN correct_cds_genes;
14773 } IndexerOptionsDialogData, PNTR IndexerOptionsDialogPtr;
14774
EnableIndexerOptions(ButtoN b)14775 static void EnableIndexerOptions (ButtoN b)
14776 {
14777 IndexerOptionsDialogPtr dlg;
14778
14779 dlg = (IndexerOptionsDialogPtr) GetObjectExtra (b);
14780 if (dlg == NULL)
14781 {
14782 return;
14783 }
14784
14785 if (GetStatus (dlg->update_proteins))
14786 {
14787 Enable (dlg->protein_options);
14788 }
14789 else
14790 {
14791 Disable (dlg->protein_options);
14792 }
14793 }
14794
IndexerOptionsToDialog(DialoG d,Pointer data)14795 static void IndexerOptionsToDialog (DialoG d, Pointer data)
14796 {
14797 IndexerOptionsDialogPtr dlg;
14798 IndexerOptionsPtr iop;
14799
14800 dlg = (IndexerOptionsDialogPtr) GetObjectExtra (d);
14801 if (dlg == NULL)
14802 {
14803 return;
14804 }
14805
14806 iop = (IndexerOptionsPtr) data;
14807
14808 if (iop == NULL)
14809 {
14810 SetStatus (dlg->add_cit_subs, FALSE);
14811 SetStatus (dlg->update_quality_scores, TRUE);
14812 SafeSetStatus (dlg->update_proteins, FALSE);
14813 SafeSetStatus (dlg->truncate_proteins, FALSE);
14814 SafeSetStatus (dlg->extend_proteins3, FALSE);
14815 SafeSetStatus (dlg->extend_proteins5, FALSE);
14816 SafeSetStatus (dlg->correct_cds_genes, FALSE);
14817 SafeSetStatus (dlg->keep_protein_ids, FALSE);
14818 }
14819 else
14820 {
14821 SetStatus (dlg->add_cit_subs, iop->add_cit_subs);
14822 SetStatus (dlg->update_quality_scores, iop->update_quality_scores);
14823 SafeSetStatus (dlg->update_proteins, iop->update_proteins);
14824 SafeSetStatus (dlg->keep_protein_ids, iop->keep_protein_ids);
14825 if (iop->update_proteins)
14826 {
14827 SafeSetStatus (dlg->truncate_proteins, iop->truncate_proteins);
14828 SafeSetStatus (dlg->extend_proteins3, iop->extend_proteins3);
14829 SafeSetStatus (dlg->extend_proteins5, iop->extend_proteins5);
14830 SafeSetStatus (dlg->correct_cds_genes, iop->correct_cds_genes);
14831 }
14832 else
14833 {
14834 SafeSetStatus (dlg->truncate_proteins, FALSE);
14835 SafeSetStatus (dlg->extend_proteins3, FALSE);
14836 SafeSetStatus (dlg->extend_proteins5, FALSE);
14837 SafeSetStatus (dlg->correct_cds_genes, FALSE);
14838 }
14839 }
14840
14841 EnableIndexerOptions (dlg->update_proteins);
14842 }
14843
IndexerOptionsFromDialog(DialoG d)14844 static Pointer IndexerOptionsFromDialog (DialoG d)
14845 {
14846 IndexerOptionsDialogPtr dlg;
14847 IndexerOptionsPtr iop;
14848
14849 dlg = (IndexerOptionsDialogPtr) GetObjectExtra (d);
14850 if (dlg == NULL)
14851 {
14852 return NULL;
14853 }
14854
14855 iop = (IndexerOptionsPtr) MemNew (sizeof (IndexerOptionsData));
14856
14857 if (iop == NULL)
14858 {
14859 return NULL;
14860 }
14861 iop->add_cit_subs = GetStatus (dlg->add_cit_subs);
14862 iop->update_quality_scores = GetStatus (dlg->update_quality_scores);
14863 iop->keep_protein_ids = GetStatus (dlg->keep_protein_ids);
14864 if (dlg->protein_options == NULL || GetStatus (dlg->update_proteins) == FALSE)
14865 {
14866 iop->update_proteins = FALSE;
14867 iop->truncate_proteins = FALSE;
14868 iop->extend_proteins3 = FALSE;
14869 iop->extend_proteins5 = FALSE;
14870 iop->correct_cds_genes = FALSE;
14871 }
14872 else
14873 {
14874 iop->update_proteins = TRUE;
14875 iop->truncate_proteins = GetStatus (dlg->truncate_proteins);
14876 iop->extend_proteins3 = GetStatus (dlg->extend_proteins3);
14877 iop->extend_proteins5 = GetStatus (dlg->extend_proteins5);
14878 iop->correct_cds_genes = GetStatus (dlg->correct_cds_genes);
14879 }
14880 return iop;
14881 }
14882
EnableIndexerImportFeatureOptions(DialoG d)14883 static void EnableIndexerImportFeatureOptions (DialoG d)
14884 {
14885 IndexerOptionsDialogPtr dlg;
14886
14887 dlg = (IndexerOptionsDialogPtr) GetObjectExtra (d);
14888 if (dlg == NULL)
14889 {
14890 return;
14891 }
14892
14893 SafeEnable (dlg->keep_protein_ids);
14894 Enable (dlg->update_proteins);
14895 EnableIndexerOptions (dlg->update_proteins);
14896 }
14897
IndexerUpdateOptionsDialog(GrouP parent,Boolean is_nuc)14898 static DialoG IndexerUpdateOptionsDialog (GrouP parent, Boolean is_nuc)
14899 {
14900 GrouP p;
14901 IndexerOptionsDialogPtr dlg;
14902
14903 dlg = (IndexerOptionsDialogPtr) MemNew (sizeof (IndexerOptionsDialogData));
14904 if (dlg == NULL)
14905 {
14906 return NULL;
14907 }
14908 p = HiddenGroup (parent, -1, 0, NULL);
14909 SetObjectExtra (p, dlg, StdCleanupExtraProc);
14910 SetGroupSpacing (p, 2, 2);
14911
14912 dlg->dialog = (DialoG) p;
14913 dlg->todialog = IndexerOptionsToDialog;
14914 dlg->fromdialog = IndexerOptionsFromDialog;
14915
14916 dlg->keep_protein_ids = CheckBox (p, "Keep protein IDs", NULL);
14917 dlg->add_cit_subs = CheckBox (p, "Add Cit-subs for Updated Sequences", NULL);
14918 dlg->update_quality_scores = CheckBox (p, "Replace Quality Scores", NULL);
14919 if (is_nuc)
14920 {
14921 dlg->update_proteins = CheckBox (p, "Update Proteins for Updated Sequences", EnableIndexerOptions);
14922 SetObjectExtra (dlg->update_proteins, dlg, NULL);
14923 dlg->protein_options = HiddenGroup (p, 1, 0, NULL);
14924 dlg->truncate_proteins = CheckBox (dlg->protein_options,
14925 "Truncate retranslated proteins at stops",
14926 NULL);
14927 dlg->extend_proteins3 = CheckBox (dlg->protein_options,
14928 "Extend retranslated proteins without stops",
14929 NULL);
14930 dlg->extend_proteins5 = CheckBox (dlg->protein_options,
14931 "Extend retranslated proteins without starts",
14932 NULL);
14933 dlg->correct_cds_genes = CheckBox (dlg->protein_options, "Correct CDS genes", NULL);
14934 }
14935 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->keep_protein_ids,
14936 (HANDLE) dlg->add_cit_subs,
14937 (HANDLE) dlg->update_quality_scores,
14938 (HANDLE) dlg->update_proteins,
14939 (HANDLE) dlg->protein_options,
14940 NULL);
14941 EnableIndexerOptions (dlg->update_proteins);
14942 return (DialoG) p;
14943 }
14944
14945 typedef struct updateoptionsdialog
14946 {
14947 DIALOG_MESSAGE_BLOCK
14948 DialoG submitter_opts;
14949 DialoG indexer_opts;
14950 } UpdateOptionsDialogData, PNTR UpdateOptionsDialogPtr;
14951
UpdateOptionsToDialog(DialoG d,Pointer data)14952 static void UpdateOptionsToDialog (DialoG d, Pointer data)
14953 {
14954 UpdateOptionsDialogPtr dlg;
14955 UpdateOptionsPtr uop;
14956
14957 dlg = (UpdateOptionsDialogPtr) GetObjectExtra (d);
14958 if (dlg == NULL)
14959 {
14960 return;
14961 }
14962 uop = (UpdateOptionsPtr) data;
14963 if (uop == NULL)
14964 {
14965 PointerToDialog (dlg->submitter_opts, NULL);
14966 PointerToDialog (dlg->indexer_opts, NULL);
14967 }
14968 else
14969 {
14970 PointerToDialog (dlg->submitter_opts, uop->submitter_opts);
14971 PointerToDialog (dlg->indexer_opts, uop->indexer_opts);
14972 }
14973 }
14974
UpdateOptionsFromDialog(DialoG d)14975 static Pointer UpdateOptionsFromDialog (DialoG d)
14976 {
14977 UpdateOptionsDialogPtr dlg;
14978 UpdateOptionsPtr uop;
14979
14980 dlg = (UpdateOptionsDialogPtr) GetObjectExtra (d);
14981 if (dlg == NULL)
14982 {
14983 return NULL;
14984 }
14985 uop = (UpdateOptionsPtr) MemNew (sizeof (UpdateOptionsData));
14986 if (uop != NULL)
14987 {
14988 uop->submitter_opts = DialogToPointer (dlg->submitter_opts);
14989 if (dlg->indexer_opts == NULL)
14990 {
14991 uop->indexer_opts = NULL;
14992 }
14993 else
14994 {
14995 uop->indexer_opts = DialogToPointer (dlg->indexer_opts);
14996 }
14997 }
14998 return uop;
14999 }
15000
DisableImportFeatureOptions(DialoG d)15001 static void DisableImportFeatureOptions (DialoG d)
15002 {
15003 UpdateOptionsDialogPtr dlg;
15004
15005 dlg = (UpdateOptionsDialogPtr) GetObjectExtra (d);
15006 if (dlg == NULL)
15007 {
15008 return;
15009 }
15010 DisableSubmitterImportFeatureOptions (dlg->submitter_opts);
15011 }
15012
EnableImportFeatureOptions(DialoG d)15013 static void EnableImportFeatureOptions (DialoG d)
15014 {
15015 UpdateOptionsDialogPtr dlg;
15016
15017 dlg = (UpdateOptionsDialogPtr) GetObjectExtra (d);
15018 if (dlg == NULL)
15019 {
15020 return;
15021 }
15022 EnableSubmitterImportFeatureOptions (dlg->submitter_opts);
15023 EnableIndexerImportFeatureOptions (dlg->indexer_opts);
15024 }
15025
DisableRemoveFeatureOptions(DialoG d)15026 static void DisableRemoveFeatureOptions (DialoG d)
15027 {
15028 UpdateOptionsDialogPtr dlg;
15029
15030 dlg = (UpdateOptionsDialogPtr) GetObjectExtra (d);
15031 if (dlg == NULL)
15032 {
15033 return;
15034 }
15035 DisableSubmitterRemoveFeatureOptions (dlg->submitter_opts);
15036 }
15037
EnableRemoveFeatureOptions(DialoG d)15038 static void EnableRemoveFeatureOptions (DialoG d)
15039 {
15040 UpdateOptionsDialogPtr dlg;
15041
15042 dlg = (UpdateOptionsDialogPtr) GetObjectExtra (d);
15043 if (dlg == NULL)
15044 {
15045 return;
15046 }
15047 EnableSubmitterRemoveFeatureOptions (dlg->submitter_opts);
15048 }
15049
15050 static void
AdjustUpdateOptionsEnabled(DialoG d,UpdatePairPtr upp,UpdateAlignmentLengthsPtr ualp,Boolean is_indexer)15051 AdjustUpdateOptionsEnabled
15052 (DialoG d,
15053 UpdatePairPtr upp,
15054 UpdateAlignmentLengthsPtr ualp,
15055 Boolean is_indexer)
15056 {
15057 UpdateOptionsDialogPtr dlg;
15058
15059 dlg = (UpdateOptionsDialogPtr) GetObjectExtra (d);
15060 if (dlg == NULL)
15061 {
15062 return;
15063 }
15064
15065 AdjustSequenceUpdateOptionsEnabled (dlg->submitter_opts, upp, ualp, is_indexer);
15066 }
15067
15068 static DialoG
UpdateOptionsDialog(GrouP parent,Boolean is_nuc,Boolean indexer,Boolean do_update,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)15069 UpdateOptionsDialog
15070 (GrouP parent,
15071 Boolean is_nuc,
15072 Boolean indexer,
15073 Boolean do_update,
15074 Nlm_ChangeNotifyProc change_notify,
15075 Pointer change_userdata)
15076 {
15077 UpdateOptionsDialogPtr dlg;
15078 GrouP p;
15079
15080 dlg = (UpdateOptionsDialogPtr) MemNew (sizeof (UpdateOptionsDialogData));
15081 if (dlg == NULL)
15082 {
15083 return NULL;
15084 }
15085
15086 p = HiddenGroup (parent, -1, 0, NULL);
15087 SetObjectExtra (p, dlg, StdCleanupExtraProc);
15088 SetGroupSpacing (p, 10, 10);
15089 dlg->dialog = (DialoG) p;
15090 dlg->todialog = UpdateOptionsToDialog;
15091 dlg->fromdialog = UpdateOptionsFromDialog;
15092
15093 dlg->submitter_opts = SubmitterUpdateOptionsDialog (p, indexer, do_update, change_notify, change_userdata);
15094 if (indexer)
15095 {
15096 dlg->indexer_opts = IndexerUpdateOptionsDialog (p, is_nuc);
15097 }
15098 else
15099 {
15100 dlg->indexer_opts = NULL;
15101 }
15102
15103 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->submitter_opts,
15104 (HANDLE) dlg->indexer_opts,
15105 NULL);
15106
15107 return (DialoG) p;
15108 }
15109
15110 typedef struct previewsequenceselectiondialog
15111 {
15112 DIALOG_MESSAGE_BLOCK
15113 DoC doc;
15114 Int4 sequence_row;
15115 Nlm_ChangeNotifyProc change_notify;
15116 Pointer change_userdata;
15117 ValNodePtr sequence_list;
15118 ParData ParFmt;
15119 ColData ColFmt;
15120
15121 } PreviewSequenceSelectionDialogData, PNTR PreviewSequenceSelectionDialogPtr;
15122
SelectionToPreviewSequenceSelectionDialog(DialoG d,Pointer userdata)15123 static void SelectionToPreviewSequenceSelectionDialog (DialoG d, Pointer userdata)
15124 {
15125 PreviewSequenceSelectionDialogPtr dlg;
15126 SeqIdPtr sip;
15127 Int4 seq_num, match_num;
15128 ValNodePtr vnp;
15129
15130 dlg = (PreviewSequenceSelectionDialogPtr) GetObjectExtra (d);
15131 if (dlg == NULL) return;
15132
15133 sip = (SeqIdPtr) userdata;
15134 if (sip == NULL)
15135 {
15136 dlg->sequence_row = -1;
15137 }
15138 else
15139 {
15140 match_num = -1;
15141 for (seq_num = 1, vnp = dlg->sequence_list;
15142 vnp != NULL && match_num < 0;
15143 seq_num++, vnp = vnp->next)
15144 {
15145 if (SeqIdComp (sip, vnp->data.ptrvalue))
15146 {
15147 match_num = seq_num;
15148 }
15149 }
15150 dlg->sequence_row = match_num;
15151 }
15152 InvalDocRows (dlg->doc, 0, 0, 0);
15153
15154 UpdateDocument(dlg->doc, 0, 0);
15155
15156 if (dlg->change_notify != NULL)
15157 {
15158 (dlg->change_notify) (dlg->change_userdata);
15159 }
15160 }
15161
SelectionFromPreviewSequenceSelectionDialog(DialoG d)15162 static Pointer SelectionFromPreviewSequenceSelectionDialog (DialoG d)
15163 {
15164 PreviewSequenceSelectionDialogPtr dlg;
15165 SeqIdPtr sip = NULL;
15166 ValNodePtr vnp;
15167
15168 dlg = (PreviewSequenceSelectionDialogPtr) GetObjectExtra (d);
15169 if (dlg != NULL && dlg->sequence_row > 0)
15170 {
15171 vnp = GetNthValNode (dlg->sequence_list, dlg->sequence_row);
15172 if (vnp != NULL)
15173 {
15174 sip = vnp->data.ptrvalue;
15175 }
15176 }
15177 return sip;
15178 }
15179
ResetSequenceList(DialoG d,ValNodePtr sequence_list)15180 static void ResetSequenceList (DialoG d, ValNodePtr sequence_list)
15181 {
15182 PreviewSequenceSelectionDialogPtr dlg;
15183 Char id_txt [MAX_ID_LEN];
15184 SeqIdPtr sip;
15185
15186 dlg = (PreviewSequenceSelectionDialogPtr) GetObjectExtra (d);
15187 if (dlg == NULL) return;
15188
15189 dlg->sequence_list = ValNodeFree (dlg->sequence_list);
15190 dlg->sequence_list = sequence_list;
15191 Reset (dlg->doc);
15192
15193 while (sequence_list != NULL)
15194 {
15195 sip = (SeqIdPtr) sequence_list->data.ptrvalue;
15196 if (sip != NULL)
15197 {
15198 /* add to sequence_selector doc */
15199 SeqIdWrite (SeqIdFindBest (sip, SEQID_GENBANK), id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
15200 AppendText (dlg->doc, id_txt, &(dlg->ParFmt), &(dlg->ColFmt), programFont);
15201 }
15202 sequence_list = sequence_list->next;
15203 }
15204 InvalDocRows (dlg->doc, 0, 0, 0);
15205 dlg->sequence_row = -1;
15206 }
15207
SelectPreviewSequence(DoC d,PoinT pt)15208 static void SelectPreviewSequence (DoC d, PoinT pt)
15209 {
15210 Int2 item, row, prevrow;
15211 PreviewSequenceSelectionDialogPtr dlg;
15212
15213 dlg = (PreviewSequenceSelectionDialogPtr) GetObjectExtra (d);
15214 if (dlg == NULL) return;
15215
15216 MapDocPoint (d, pt, &item, &row, NULL, NULL);
15217 if (item > 0 && row > 0) {
15218 prevrow = dlg->sequence_row;
15219 dlg->sequence_row = item;
15220 if (item != prevrow)
15221 {
15222 if (prevrow != -1)
15223 {
15224 InvalDocRows (d, prevrow, 1, 1);
15225 }
15226 InvalDocRows (d, item, 1, 1);
15227 if (dlg->change_notify != NULL)
15228 {
15229 (dlg->change_notify) (dlg->change_userdata);
15230 }
15231 }
15232 }
15233 }
15234
PreviewSequenceHighlight(DoC doc,Int2 item,Int2 row,Int2 col)15235 static Boolean PreviewSequenceHighlight (DoC doc, Int2 item, Int2 row, Int2 col)
15236 {
15237 PreviewSequenceSelectionDialogPtr dlg;
15238
15239 dlg = (PreviewSequenceSelectionDialogPtr) GetObjectExtra (doc);
15240 if (dlg == NULL) return FALSE;
15241
15242 if (item == dlg->sequence_row) return TRUE;
15243 return FALSE;
15244 }
15245
CleanupPreviewSequenceSelectionDialog(GraphiC g,Pointer data)15246 static void CleanupPreviewSequenceSelectionDialog (GraphiC g, Pointer data)
15247 {
15248 PreviewSequenceSelectionDialogPtr dlg;
15249
15250 dlg = (PreviewSequenceSelectionDialogPtr) data;
15251 if (dlg != NULL)
15252 {
15253 dlg->sequence_list = ValNodeFree (dlg->sequence_list);
15254 }
15255 StdCleanupExtraProc (g, data);
15256 }
15257
SetPreviewSequenceSelectionByPosition(DialoG d,Int4 seq_pos)15258 static void SetPreviewSequenceSelectionByPosition (DialoG d, Int4 seq_pos)
15259 {
15260 PreviewSequenceSelectionDialogPtr dlg;
15261 Int4 prevrow, curr_scroll, max_scroll;
15262 BaR sb;
15263
15264 dlg = (PreviewSequenceSelectionDialogPtr) GetObjectExtra (d);
15265 if (dlg == NULL || seq_pos < 0)
15266 {
15267 return;
15268 }
15269
15270 prevrow = dlg->sequence_row;
15271 dlg->sequence_row = seq_pos + 1;
15272 if (dlg->sequence_row != prevrow)
15273 {
15274 if (prevrow != -1)
15275 {
15276 InvalDocRows (dlg->doc, prevrow, 1, 1);
15277 }
15278 InvalDocRows (dlg->doc, seq_pos + 1, 1, 1);
15279 sb = GetSlateVScrollBar( (SlatE) dlg->doc);
15280 if (sb != NULL)
15281 {
15282 curr_scroll = GetBarValue (sb);
15283 max_scroll = GetBarMax (sb);
15284 if (max_scroll > seq_pos)
15285 {
15286 SetBarValue (sb, seq_pos);
15287 }
15288 else
15289 {
15290 SetBarValue (sb, max_scroll);
15291 }
15292 }
15293 if (dlg->change_notify != NULL)
15294 {
15295 (dlg->change_notify) (dlg->change_userdata);
15296 }
15297 }
15298 }
15299
15300 static DialoG
PreviewSequenceSelectionDialog(GrouP parent,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)15301 PreviewSequenceSelectionDialog
15302 (GrouP parent,
15303 Nlm_ChangeNotifyProc change_notify,
15304 Pointer change_userdata)
15305 {
15306 PreviewSequenceSelectionDialogPtr dlg;
15307 GrouP p;
15308 RecT r;
15309
15310 dlg = (PreviewSequenceSelectionDialogPtr) MemNew (sizeof (PreviewSequenceSelectionDialogData));
15311 if (dlg == NULL)
15312 {
15313 return NULL;
15314 }
15315
15316 p = HiddenGroup (parent, 1, 0, NULL);
15317 SetObjectExtra (p, dlg, CleanupPreviewSequenceSelectionDialog);
15318
15319 dlg->dialog = (DialoG) p;
15320 dlg->todialog = SelectionToPreviewSequenceSelectionDialog;
15321 dlg->fromdialog = SelectionFromPreviewSequenceSelectionDialog;
15322 dlg->change_notify = change_notify;
15323 dlg->change_userdata = change_userdata;
15324 dlg->sequence_list = NULL;
15325
15326 dlg->doc = DocumentPanel (p, stdCharWidth * 10, stdLineHeight * 5);
15327 SetObjectExtra (dlg->doc, dlg, NULL);
15328 SetDocProcs (dlg->doc, SelectPreviewSequence, NULL, NULL, NULL);
15329 SetDocShade (dlg->doc, NULL, NULL, PreviewSequenceHighlight, NULL);
15330
15331 /* initialize document paragraph format */
15332 dlg->ParFmt.openSpace = FALSE;
15333 dlg->ParFmt.keepWithNext = FALSE;
15334 dlg->ParFmt.keepTogether = FALSE;
15335 dlg->ParFmt.newPage = FALSE;
15336 dlg->ParFmt.tabStops = FALSE;
15337 dlg->ParFmt.minLines = 0;
15338 dlg->ParFmt.minHeight = 0;
15339
15340 /* initialize document column format */
15341 ObjectRect (dlg->doc, &r);
15342 InsetRect (&r, 4, 4);
15343 dlg->ColFmt.pixWidth = r.right - r.left;
15344 dlg->ColFmt.pixInset = 0;
15345 dlg->ColFmt.charWidth = 80;
15346 dlg->ColFmt.charInset = 0;
15347 dlg->ColFmt.font = NULL;
15348 dlg->ColFmt.just = 'l';
15349 dlg->ColFmt.wrap = TRUE;
15350 dlg->ColFmt.bar = FALSE;
15351 dlg->ColFmt.underline = FALSE;
15352 dlg->ColFmt.left = FALSE;
15353 dlg->ColFmt.last = TRUE;
15354
15355
15356 return (DialoG) p;
15357 }
15358
15359 typedef struct unmatchedsequencedialog
15360 {
15361 DIALOG_MESSAGE_BLOCK
15362 DoC doc;
15363 ParData ParFmt;
15364 ColData ColFmt;
15365 Int4 dlg_height;
15366 Int4 selected;
15367 } UnmatchedSequenceDialogData, PNTR UnmatchedSequenceDialogPtr;
15368
ListToUnmatchedSequenceDialog(DialoG d,Pointer userdata)15369 static void ListToUnmatchedSequenceDialog (DialoG d, Pointer userdata)
15370 {
15371 UnmatchedSequenceDialogPtr dlg;
15372 ValNodePtr bioseq_list;
15373 BioseqPtr bsp;
15374 Char id_txt [MAX_ID_LEN];
15375
15376 dlg = (UnmatchedSequenceDialogPtr) GetObjectExtra (d);
15377 if (dlg == NULL)
15378 {
15379 return;
15380 }
15381
15382 Reset (dlg->doc);
15383
15384 bioseq_list = (ValNodePtr) userdata;
15385 if (bioseq_list == NULL)
15386 {
15387 return;
15388 }
15389
15390 while (bioseq_list != NULL)
15391 {
15392 bsp = (BioseqPtr) bioseq_list->data.ptrvalue;
15393 if (bsp != NULL)
15394 {
15395 /* add to sequence_selector doc */
15396 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
15397 AppendText (dlg->doc, id_txt, &(dlg->ParFmt), &(dlg->ColFmt), programFont);
15398 }
15399 bioseq_list = bioseq_list->next;
15400 }
15401 InvalDocRows (dlg->doc, 0, 0, 0);
15402
15403 }
15404
15405
15406 /* clicking on a column in the title indicates that we should sort by this column. */
ClickUnmatchedSequence(DoC d,PoinT pt)15407 static void ClickUnmatchedSequence (DoC d, PoinT pt)
15408 {
15409 UnmatchedSequenceDialogPtr dlg;
15410 Int2 item;
15411 Int2 row;
15412 Int2 col;
15413 RecT r;
15414
15415 MapDocPoint (d, pt, &item, &row, &col, NULL);
15416 if (item < 1) {
15417 return;
15418 }
15419 dlg = (UnmatchedSequenceDialogPtr) GetObjectExtra (d);
15420 if (dlg == NULL) return;
15421 if (dlg->selected == item) {
15422 dlg->selected = 0;
15423 } else {
15424 dlg->selected = item;
15425 }
15426 /* inval to redraw */
15427 ObjectRect (dlg->doc, &r);
15428 InvalRect (&r);
15429 Update ();
15430 }
15431
15432
HighlightUnmatchedSequence(DoC d,Int2 item,Int2 row,Int2 col)15433 static Boolean HighlightUnmatchedSequence (DoC d, Int2 item, Int2 row, Int2 col)
15434
15435 {
15436 UnmatchedSequenceDialogPtr dlg;
15437
15438 dlg = (UnmatchedSequenceDialogPtr) GetObjectExtra (d);
15439 if (dlg == NULL) return FALSE;
15440
15441 if (item == dlg->selected) {
15442 return TRUE;
15443 } else {
15444 return FALSE;
15445 }
15446 }
15447
15448
15449 static DialoG
UnmatchedSequenceDialog(GrouP parent,Nlm_BtnActnProc map_btn_proc,Pointer change_userdata,Nlm_BtnActnProc connect_btn_proc)15450 UnmatchedSequenceDialog
15451 (GrouP parent,
15452 Nlm_BtnActnProc map_btn_proc,
15453 Pointer change_userdata,
15454 Nlm_BtnActnProc connect_btn_proc)
15455 {
15456 UnmatchedSequenceDialogPtr dlg;
15457 GrouP p, button_grp = NULL;
15458 RecT r;
15459 PrompT ppt = NULL;
15460 ButtoN b;
15461
15462 dlg = (UnmatchedSequenceDialogPtr) MemNew (sizeof (UnmatchedSequenceDialogData));
15463 if (dlg == NULL)
15464 {
15465 return NULL;
15466 }
15467
15468 p = HiddenGroup (parent, -1, 0, NULL);
15469 SetObjectExtra (p, dlg, StdCleanupExtraProc);
15470
15471 dlg->dialog = (DialoG) p;
15472 dlg->todialog = ListToUnmatchedSequenceDialog;
15473
15474 if (map_btn_proc == NULL)
15475 {
15476 ppt = StaticPrompt (p, "No Updates", 0, 0, programFont, 'l');
15477 }
15478 else
15479 {
15480 ppt = StaticPrompt (p, "Unmatched Sequences", 0, 0, programFont, 'l');
15481 }
15482 dlg->doc = DocumentPanel (p, stdCharWidth * 10, stdLineHeight * 5);
15483 SetObjectExtra (dlg->doc, dlg, NULL);
15484 SetDocProcs (dlg->doc, ClickUnmatchedSequence, NULL, NULL, NULL);
15485 SetDocShade (dlg->doc, NULL, NULL, HighlightUnmatchedSequence, NULL);
15486 dlg->selected = 0;
15487
15488 /* initialize document paragraph format */
15489 dlg->ParFmt.openSpace = FALSE;
15490 dlg->ParFmt.keepWithNext = FALSE;
15491 dlg->ParFmt.keepTogether = FALSE;
15492 dlg->ParFmt.newPage = FALSE;
15493 dlg->ParFmt.tabStops = FALSE;
15494 dlg->ParFmt.minLines = 0;
15495 dlg->ParFmt.minHeight = 0;
15496
15497 /* initialize document column format */
15498 ObjectRect (dlg->doc, &r);
15499 dlg->dlg_height = r.bottom - r.top;
15500 InsetRect (&r, 4, 4);
15501 dlg->ColFmt.pixWidth = r.right - r.left;
15502 dlg->ColFmt.pixInset = 0;
15503 dlg->ColFmt.charWidth = 80;
15504 dlg->ColFmt.charInset = 0;
15505 dlg->ColFmt.font = NULL;
15506 dlg->ColFmt.just = 'l';
15507 dlg->ColFmt.wrap = TRUE;
15508 dlg->ColFmt.bar = FALSE;
15509 dlg->ColFmt.underline = FALSE;
15510 dlg->ColFmt.left = FALSE;
15511 dlg->ColFmt.last = TRUE;
15512
15513
15514 if (map_btn_proc != NULL || connect_btn_proc != NULL)
15515 {
15516 button_grp = HiddenGroup (p, 2, 0, NULL);
15517 SetGroupSpacing (button_grp, 10, 10);
15518
15519 if (map_btn_proc != NULL)
15520 {
15521 /* add button for loading map */
15522 b = PushButton (button_grp, "Load Map", map_btn_proc);
15523 SetObjectExtra (b, change_userdata, NULL);
15524 }
15525 if (connect_btn_proc != NULL)
15526 {
15527 /* add button for loading map */
15528 b = PushButton (button_grp, "Map Selected", connect_btn_proc);
15529 SetObjectExtra (b, change_userdata, NULL);
15530 }
15531
15532 ObjectRect (b, &r);
15533 dlg->dlg_height += 10 + r.bottom - r.top;
15534 }
15535
15536 AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) dlg->doc, (HANDLE) button_grp, NULL);
15537
15538 return (DialoG) p;
15539 }
15540
15541
GetUnmatchedSequenceDialogSelection(DialoG d)15542 static Int4 GetUnmatchedSequenceDialogSelection (DialoG d)
15543 {
15544 UnmatchedSequenceDialogPtr dlg;
15545
15546 dlg = (UnmatchedSequenceDialogPtr) GetObjectExtra (d);
15547 if (dlg == NULL) return -1;
15548
15549 return dlg->selected - 1;
15550 }
15551
15552
15553 static void
ChangePreviewSequenceSelectionDialogHeights(DialoG orig_sel,DialoG unmatched,DialoG no_updates,ButtoN remove_identical_btn,Boolean has_identical,WindoW match_win,Boolean show_unmatched,Boolean show_no_updates)15554 ChangePreviewSequenceSelectionDialogHeights
15555 (DialoG orig_sel,
15556 DialoG unmatched,
15557 DialoG no_updates,
15558 ButtoN remove_identical_btn,
15559 Boolean has_identical,
15560 WindoW match_win,
15561 Boolean show_unmatched,
15562 Boolean show_no_updates)
15563 {
15564 PreviewSequenceSelectionDialogPtr orig_sel_dlg;
15565 UnmatchedSequenceDialogPtr unmatched_dlg, no_updates_dlg;
15566 RecT pictures_r, unmatched_r, list_r;
15567 RecT no_updates_r, rem_ident_r;
15568 Int4 no_updates_height;
15569 BaR sb;
15570 Int4 updates_list_bottom;
15571 Int4 spacing = 0, rem_ident_height = 0;
15572
15573 orig_sel_dlg = (PreviewSequenceSelectionDialogPtr) GetObjectExtra (orig_sel);
15574 unmatched_dlg = (UnmatchedSequenceDialogPtr) GetObjectExtra (unmatched);
15575 no_updates_dlg = (UnmatchedSequenceDialogPtr) GetObjectExtra (no_updates);
15576 if (orig_sel_dlg == NULL || unmatched_dlg == NULL
15577 || no_updates_dlg == NULL)
15578 {
15579 return;
15580 }
15581
15582 ObjectRect (orig_sel_dlg->doc, &list_r);
15583 ObjectRect (unmatched_dlg->doc, &unmatched_r);
15584 ObjectRect (no_updates_dlg->doc, &no_updates_r);
15585 if (match_win == NULL)
15586 {
15587 pictures_r.top = list_r.top;
15588 pictures_r.left = list_r.right;
15589 pictures_r.right = list_r.right;
15590 pictures_r.bottom = no_updates_r.bottom;
15591 }
15592 else
15593 {
15594 ObjectRect (match_win, &pictures_r);
15595 }
15596
15597 if (remove_identical_btn != NULL && has_identical)
15598 {
15599 ObjectRect (remove_identical_btn, &rem_ident_r);
15600 rem_ident_height = rem_ident_r.bottom - rem_ident_r.top;
15601 spacing = 5;
15602 }
15603
15604 /* updates list is on top,
15605 * followed by remove_identical_btn,
15606 * followed by unmatched list,
15607 * followed by no updates list */
15608 updates_list_bottom = pictures_r.bottom;
15609
15610 if (show_no_updates)
15611 {
15612 /* align no updates list with bottom of preview pictures */
15613 no_updates_height = no_updates_r.bottom - no_updates_r.top;
15614 no_updates_r.bottom = updates_list_bottom;
15615 no_updates_r.top = no_updates_r.bottom - no_updates_height;
15616 sb = GetSlateVScrollBar( (SlatE) no_updates_dlg->doc);
15617 if (sb != NULL)
15618 {
15619 /* because the doc has a vertical scroll bar and the set position subtracts the
15620 * width of the scroll bar before positioning the list, must add the width of
15621 * the scroll bar to the rightt.
15622 */
15623 no_updates_r.right += Nlm_vScrollBarWidth;
15624 }
15625 SetPosition (no_updates, &no_updates_r);
15626 updates_list_bottom -= (no_updates_dlg->dlg_height + 10);
15627 Show (no_updates);
15628 }
15629 else
15630 {
15631 Hide (no_updates);
15632 }
15633
15634 if (show_unmatched)
15635 {
15636 /* align unmatched list with bottom of updates list or preview pictures */
15637 unmatched_r.bottom = updates_list_bottom ;
15638 unmatched_r.top = unmatched_r.bottom - unmatched_dlg->dlg_height;
15639
15640 sb = GetSlateVScrollBar( (SlatE) unmatched_dlg->doc);
15641 if (sb != NULL)
15642 {
15643 /* because the doc has a vertical scroll bar and the set position subtracts the
15644 * width of the scroll bar before positioning the list, must add the width of
15645 * the scroll bar to the rightt.
15646 */
15647 unmatched_r.right += Nlm_vScrollBarWidth;
15648 }
15649 SetPosition (unmatched, &unmatched_r);
15650 updates_list_bottom -= (unmatched_dlg->dlg_height + 10);
15651 Show (unmatched);
15652 }
15653 else
15654 {
15655 Hide (unmatched);
15656 }
15657
15658 /* set position of sequence list - align top with pictures,
15659 * align bottom with top of unmatched (if shown) or
15660 * bottom of pictures
15661 */
15662 list_r.top = pictures_r.top;
15663 list_r.bottom = updates_list_bottom - spacing - rem_ident_height;
15664
15665 sb = GetSlateVScrollBar( (SlatE) orig_sel_dlg->doc);
15666 if (sb != NULL)
15667 {
15668 /* because the doc has a vertical scroll bar and the set position subtracts the
15669 * width of the scroll bar before positioning the list, must add the width of
15670 * the scroll bar to the rightt.
15671 */
15672 list_r.right += Nlm_vScrollBarWidth;
15673 }
15674 SetPosition (orig_sel_dlg->doc, &list_r);
15675
15676 if (remove_identical_btn != NULL)
15677 {
15678 if (has_identical)
15679 {
15680 /* set position of remove identical btn */
15681 rem_ident_r.top = updates_list_bottom - rem_ident_height;
15682 rem_ident_r.bottom = rem_ident_r.top + rem_ident_height;
15683 SetPosition (remove_identical_btn, &rem_ident_r);
15684 Show (remove_identical_btn);
15685 }
15686 else
15687 {
15688 /* hide button */
15689 SafeHide (remove_identical_btn);
15690 }
15691 }
15692 }
15693
15694 typedef struct multisequenceupdatepreviewdialog
15695 {
15696 DIALOG_MESSAGE_BLOCK
15697
15698 DialoG update_list_dlg;
15699 DialoG preview_dlg;
15700 DialoG unmatched_list_dlg;
15701 DialoG no_updates_list_dlg;
15702 DialoG extend_preview_dlg;
15703 ButtoN remove_identical_btn;
15704 WindoW match_win;
15705 ValNodePtr orig_bioseq_list;
15706 ValNodePtr update_bioseq_list;
15707 Boolean is_na;
15708 Nlm_ChangeNotifyProc change_notify;
15709 Pointer change_userdata;
15710
15711 } MultiSequenceUpdatePreviewDialogData, PNTR MultiSequenceUpdatePreviewDialogPtr;
15712
15713
15714 typedef struct multisequenceupdate
15715 {
15716 ValNodePtr orig_bioseq_list;
15717 ValNodePtr update_bioseq_list;
15718 ValNodePtr unmatched_updates_list;
15719 ValNodePtr no_updates_list;
15720 } MultiSequenceUpdateData, PNTR MultiSequenceUpdatePtr;
15721
SelectSequenceForUpdatePreview(Pointer userdata)15722 static void SelectSequenceForUpdatePreview (Pointer userdata)
15723 {
15724 MultiSequenceUpdatePreviewDialogPtr dlg;
15725 UpdatePairData upd;
15726 ValNodePtr update_vnp;
15727 SeqIdPtr sip;
15728 Int4 orig_pos = -1;
15729
15730 dlg = (MultiSequenceUpdatePreviewDialogPtr) userdata;
15731 if (dlg == NULL)
15732 {
15733 return;
15734 }
15735
15736 sip = (SeqIdPtr) DialogToPointer (dlg->dialog);
15737
15738 upd.orig_bsp = FindBioseqInList (dlg->orig_bioseq_list, sip, &orig_pos);
15739
15740 update_vnp = GetNthValNode (dlg->update_bioseq_list, orig_pos + 1);
15741 if (update_vnp != NULL)
15742 {
15743 upd.update_bsp = update_vnp->data.ptrvalue;
15744 }
15745 else
15746 {
15747 upd.update_bsp = NULL;
15748 }
15749
15750 SeqMgrReplaceInBioseqIndex (upd.orig_bsp);
15751
15752 upd.revcomp = FALSE;
15753 upd.salp = Sqn_AlignForSequenceUpdate (upd.orig_bsp, upd.update_bsp, &(upd.revcomp));
15754
15755 if (upd.revcomp)
15756 {
15757 BioseqRevComp (upd.update_bsp);
15758 ReverseBioseqFeatureStrands (upd.update_bsp);
15759 SeqMgrReplaceInBioseqIndex (upd.update_bsp);
15760 }
15761
15762 PointerToDialog (dlg->preview_dlg, &upd);
15763 PointerToDialog (dlg->extend_preview_dlg, &upd);
15764
15765 SeqMgrReplaceInBioseqIndex (upd.orig_bsp);
15766
15767 if (dlg->change_notify != NULL)
15768 {
15769 (dlg->change_notify) (dlg->change_userdata);
15770 }
15771 }
15772
SeqIdListFromBioseqList(ValNodePtr bioseq_list)15773 static ValNodePtr SeqIdListFromBioseqList (ValNodePtr bioseq_list)
15774 {
15775 ValNodePtr sip_list = NULL;
15776 Int4 seq_num = 0;
15777 BioseqPtr bsp;
15778
15779 while (bioseq_list != NULL)
15780 {
15781 if (bioseq_list->data.ptrvalue == NULL)
15782 {
15783 ValNodeAddPointer (&sip_list, seq_num, NULL);
15784 }
15785 else
15786 {
15787 bsp = (BioseqPtr) bioseq_list->data.ptrvalue;
15788 ValNodeAddPointer (&sip_list, seq_num, bsp->id);
15789 }
15790 seq_num++;
15791 bioseq_list = bioseq_list->next;
15792 }
15793 return sip_list;
15794 }
15795
HasIdenticalUpdates(ValNodePtr orig_list,ValNodePtr update_list)15796 static Boolean HasIdenticalUpdates
15797 (ValNodePtr orig_list,
15798 ValNodePtr update_list)
15799 {
15800 BioseqPtr orig_bsp, update_bsp;
15801
15802 while (orig_list != NULL && update_list != NULL)
15803 {
15804 orig_bsp = orig_list->data.ptrvalue;
15805 update_bsp = update_list->data.ptrvalue;
15806
15807 if (orig_bsp != NULL && update_bsp != NULL
15808 && AreSequenceResiduesIdentical (orig_bsp, update_bsp))
15809 {
15810 return TRUE;
15811 }
15812
15813 orig_list = orig_list->next;
15814 update_list = update_list->next;
15815 }
15816
15817 return FALSE;
15818 }
15819
DataToMultiSequenceUpdatePreview(DialoG d,Pointer data)15820 static void DataToMultiSequenceUpdatePreview (DialoG d, Pointer data)
15821 {
15822 MultiSequenceUpdatePreviewDialogPtr dlg;
15823 MultiSequenceUpdatePtr msup;
15824 BioseqPtr first_bsp;
15825 ValNodePtr unmatched_updates_list = NULL;
15826 ValNodePtr no_updates_list = NULL;
15827 Boolean has_identical = FALSE;
15828
15829 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (d);
15830 if (dlg == NULL)
15831 {
15832 return;
15833 }
15834
15835 msup = (MultiSequenceUpdatePtr) data;
15836 if (msup == NULL)
15837 {
15838 dlg->orig_bioseq_list = NULL;
15839 dlg->update_bioseq_list = NULL;
15840 }
15841 else
15842 {
15843 dlg->orig_bioseq_list = msup->orig_bioseq_list;
15844 dlg->update_bioseq_list = msup->update_bioseq_list;
15845 unmatched_updates_list = msup->unmatched_updates_list;
15846 no_updates_list = msup->no_updates_list;
15847 }
15848
15849 ResetSequenceList (dlg->update_list_dlg, SeqIdListFromBioseqList(dlg->orig_bioseq_list));
15850 PointerToDialog (dlg->unmatched_list_dlg, unmatched_updates_list);
15851 PointerToDialog (dlg->no_updates_list_dlg, no_updates_list);
15852
15853 if (dlg->remove_identical_btn != NULL)
15854 {
15855 has_identical = HasIdenticalUpdates (dlg->orig_bioseq_list, dlg->update_bioseq_list);
15856 }
15857
15858 ChangePreviewSequenceSelectionDialogHeights (dlg->update_list_dlg,
15859 dlg->unmatched_list_dlg,
15860 dlg->no_updates_list_dlg,
15861 dlg->remove_identical_btn,
15862 has_identical,
15863 dlg->match_win,
15864 (unmatched_updates_list != NULL),
15865 (no_updates_list != NULL));
15866
15867 /* select first sequence */
15868 if (dlg->orig_bioseq_list != NULL && dlg->orig_bioseq_list->data.ptrvalue != NULL)
15869 {
15870 first_bsp = (BioseqPtr) dlg->orig_bioseq_list->data.ptrvalue;
15871
15872 PointerToDialog (dlg->update_list_dlg, first_bsp->id);
15873 SelectSequenceForUpdatePreview (dlg);
15874 }
15875 else
15876 {
15877 if (dlg->change_notify != NULL)
15878 {
15879 (dlg->change_notify) (dlg->change_userdata);
15880 }
15881 }
15882 }
15883
15884 /* returns SeqID currently selected in preview list */
SelectionFromMultiSequenceUpdatePreview(DialoG d)15885 static Pointer SelectionFromMultiSequenceUpdatePreview (DialoG d)
15886 {
15887 MultiSequenceUpdatePreviewDialogPtr dlg;
15888 ValNodePtr orig_vnp, update_vnp;
15889 BioseqPtr orig_bsp;
15890 SeqIdPtr return_sip = NULL;
15891
15892 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (d);
15893 if (dlg == NULL)
15894 {
15895 return NULL;
15896 }
15897
15898 if (dlg->update_list_dlg == NULL)
15899 {
15900 for (orig_vnp = dlg->orig_bioseq_list, update_vnp = dlg->update_bioseq_list;
15901 orig_vnp != NULL && update_vnp != NULL && return_sip == NULL;
15902 orig_vnp = orig_vnp->next, update_vnp = update_vnp->next)
15903 {
15904 if (orig_vnp->data.ptrvalue == NULL || update_vnp->data.ptrvalue == NULL)
15905 {
15906 continue;
15907 }
15908 orig_bsp = (BioseqPtr) orig_vnp->data.ptrvalue;
15909 return_sip = SeqIdDup (orig_bsp->id);
15910 }
15911 }
15912 else
15913 {
15914 return_sip = DialogToPointer (dlg->update_list_dlg);
15915 }
15916 return return_sip;
15917 }
15918
SelectUpdatePreviewSequenceByPosition(DialoG d,Int4 seq_pos)15919 static void SelectUpdatePreviewSequenceByPosition (DialoG d, Int4 seq_pos)
15920 {
15921 MultiSequenceUpdatePreviewDialogPtr dlg;
15922
15923 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (d);
15924 if (dlg == NULL)
15925 {
15926 return;
15927 }
15928
15929 SetPreviewSequenceSelectionByPosition (dlg->update_list_dlg, seq_pos);
15930 }
15931
GetCurrentUpdatePair(DialoG d)15932 static UpdatePairPtr GetCurrentUpdatePair (DialoG d)
15933 {
15934 MultiSequenceUpdatePreviewDialogPtr dlg;
15935
15936 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (d);
15937 if (dlg == NULL)
15938 {
15939 return NULL;
15940 }
15941
15942 return (UpdatePairPtr) DialogToPointer (dlg->preview_dlg);
15943 }
15944
AddExtendDialogToMultiSequenceUpdatePreview(DialoG msup,DialoG ext)15945 static void AddExtendDialogToMultiSequenceUpdatePreview (DialoG msup, DialoG ext)
15946 {
15947 MultiSequenceUpdatePreviewDialogPtr dlg;
15948
15949 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (msup);
15950 if (dlg != NULL)
15951 {
15952 dlg->extend_preview_dlg = ext;
15953 }
15954 }
15955
15956 static void RemoveIdenticalUpdates (ButtoN b);
15957
SetMultiSequenceUpdatePreviewMatchWindow(DialoG d,WindoW w)15958 static void SetMultiSequenceUpdatePreviewMatchWindow (DialoG d, WindoW w)
15959 {
15960 MultiSequenceUpdatePreviewDialogPtr dlg;
15961
15962 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (d);
15963 if (dlg != NULL)
15964 {
15965 dlg->match_win = w;
15966 }
15967 }
15968
SetIgnoreAndExtendForMultiSequencePreview(DialoG d,Boolean ignore_alignment,Boolean extend5)15969 static void SetIgnoreAndExtendForMultiSequencePreview (DialoG d, Boolean ignore_alignment, Boolean extend5)
15970 {
15971 MultiSequenceUpdatePreviewDialogPtr dlg;
15972
15973 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (d);
15974 if (dlg != NULL)
15975 {
15976 SetIgnoreAndExtendForPreviewPictures (dlg->preview_dlg, ignore_alignment, extend5);
15977 }
15978 }
15979
15980 static DialoG
MultiSequenceUpdatePreview(GrouP parent,Boolean is_na,Boolean do_update,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata,Nlm_BtnActnProc map_btn_proc,Nlm_BtnActnProc connect_btn_proc,Boolean is_indexer)15981 MultiSequenceUpdatePreview
15982 (GrouP parent,
15983 Boolean is_na,
15984 Boolean do_update,
15985 Nlm_ChangeNotifyProc change_notify,
15986 Pointer change_userdata,
15987 Nlm_BtnActnProc map_btn_proc,
15988 Nlm_BtnActnProc connect_btn_proc,
15989 Boolean is_indexer)
15990 {
15991 MultiSequenceUpdatePreviewDialogPtr dlg;
15992 GrouP p, k;
15993
15994 dlg = (MultiSequenceUpdatePreviewDialogPtr) MemNew (sizeof (MultiSequenceUpdatePreviewDialogData));
15995 if (dlg == NULL)
15996 {
15997 return NULL;
15998 }
15999
16000 if (do_update)
16001 {
16002 p = HiddenGroup (parent, 0, 1, NULL);
16003 }
16004 else
16005 {
16006 p = HiddenGroup (parent, -1, 0, NULL);
16007 }
16008 SetObjectExtra (p, dlg, StdCleanupExtraProc);
16009 SetGroupSpacing (p, 10, 10);
16010
16011 dlg->dialog = (DialoG) p;
16012 dlg->todialog = DataToMultiSequenceUpdatePreview;
16013 dlg->fromdialog = SelectionFromMultiSequenceUpdatePreview;
16014
16015 dlg->is_na = is_na;
16016
16017 dlg->change_notify = change_notify;
16018 dlg->change_userdata = change_userdata;
16019
16020 if (is_indexer)
16021 {
16022 k = HiddenGroup (p, 0, 4, NULL);
16023 /* note - the ValNodeSelectionDialog will free the seq_id list when done */
16024 dlg->update_list_dlg = PreviewSequenceSelectionDialog (k, SelectSequenceForUpdatePreview,
16025 dlg);
16026 if (do_update && is_indexer)
16027 {
16028 dlg->remove_identical_btn = PushButton (k, "Remove Identical Updates", RemoveIdenticalUpdates);
16029 SetObjectExtra (dlg->remove_identical_btn, change_userdata, NULL);
16030 }
16031
16032 dlg->unmatched_list_dlg = UnmatchedSequenceDialog (k, map_btn_proc, change_userdata, connect_btn_proc);
16033
16034 dlg->no_updates_list_dlg = UnmatchedSequenceDialog (k, NULL, NULL, NULL);
16035 }
16036
16037 dlg->extend_preview_dlg = NULL;
16038 if (do_update)
16039 {
16040 dlg->preview_dlg = UpdatePreviewDialog (p, is_indexer);
16041 dlg->match_win = (WindoW) dlg->preview_dlg;
16042 }
16043 else
16044 {
16045 dlg->preview_dlg = NULL;
16046 dlg->match_win = NULL;
16047 }
16048
16049 return (DialoG) p;
16050 }
16051
16052
GetMultiSequenceUpdatePreviewUnmatchedSelection(DialoG d)16053 static Int4 GetMultiSequenceUpdatePreviewUnmatchedSelection (DialoG d)
16054 {
16055 MultiSequenceUpdatePreviewDialogPtr dlg;
16056
16057 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (d);
16058 if (dlg != NULL)
16059 {
16060 return GetUnmatchedSequenceDialogSelection (dlg->unmatched_list_dlg);
16061 } else {
16062 return -1;
16063 }
16064 }
16065
16066
GetMultiSequenceUpdatePreviewNoUpdateSelection(DialoG d)16067 static Int4 GetMultiSequenceUpdatePreviewNoUpdateSelection (DialoG d)
16068 {
16069 MultiSequenceUpdatePreviewDialogPtr dlg;
16070
16071 dlg = (MultiSequenceUpdatePreviewDialogPtr) GetObjectExtra (d);
16072 if (dlg != NULL)
16073 {
16074 return GetUnmatchedSequenceDialogSelection (dlg->no_updates_list_dlg);
16075 } else {
16076 return -1;
16077 }
16078 }
16079
16080
ExtractSequencesWithoutUpdates(ValNodePtr PNTR orig_bioseq_list,ValNodePtr PNTR update_bioseq_list)16081 static ValNodePtr ExtractSequencesWithoutUpdates (ValNodePtr PNTR orig_bioseq_list, ValNodePtr PNTR update_bioseq_list)
16082 {
16083 ValNodePtr orig_prev = NULL, update_prev = NULL;
16084 ValNodePtr orig_next = NULL, update_next = NULL;
16085 ValNodePtr orig_vnp, update_vnp;
16086 ValNodePtr no_update_list = NULL;
16087 Int4 seq_num;
16088
16089 if (orig_bioseq_list == NULL || update_bioseq_list == NULL
16090 || *orig_bioseq_list == NULL || *update_bioseq_list == NULL)
16091 {
16092 return NULL;
16093 }
16094
16095 orig_vnp = *orig_bioseq_list;
16096 update_vnp = *update_bioseq_list;
16097
16098 while (orig_vnp != NULL && update_vnp != NULL)
16099 {
16100 orig_next = orig_vnp->next;
16101 update_next = update_vnp->next;
16102 if (orig_vnp->data.ptrvalue == NULL || update_vnp->data.ptrvalue == NULL)
16103 {
16104 if (orig_prev == NULL || update_prev == NULL)
16105 {
16106 *orig_bioseq_list = orig_vnp->next;
16107 *update_bioseq_list = update_vnp->next;
16108 }
16109 else
16110 {
16111 orig_prev->next = orig_vnp->next;
16112 update_prev->next = update_vnp->next;
16113 }
16114 orig_vnp->next = NULL;
16115 update_vnp->next = NULL;
16116 if (orig_vnp->data.ptrvalue == NULL)
16117 {
16118 ValNodeFree (orig_vnp);
16119 }
16120 else
16121 {
16122 ValNodeLink (&no_update_list, orig_vnp);
16123 }
16124
16125 ValNodeFree (update_vnp);
16126 }
16127 else
16128 {
16129 orig_prev = orig_vnp;
16130 update_prev = update_vnp;
16131 }
16132
16133 orig_vnp = orig_next;
16134 update_vnp = update_next;
16135 }
16136
16137 for (orig_vnp = *orig_bioseq_list, update_vnp = *update_bioseq_list, seq_num = 0;
16138 orig_vnp != NULL && update_vnp != NULL;
16139 orig_vnp = orig_vnp->next, update_vnp = update_vnp->next, seq_num++)
16140 {
16141 orig_vnp->choice = seq_num;
16142 update_vnp->choice = seq_num;
16143 }
16144 return no_update_list;
16145 }
16146
ReadASNUpdateSequences(FILE * fp,BoolPtr chars_stripped)16147 static SeqEntryPtr ReadASNUpdateSequences (FILE *fp, BoolPtr chars_stripped)
16148 {
16149 Pointer dataptr;
16150 Uint2 datatype;
16151 SeqEntryPtr sep = NULL;
16152 SeqSubmitPtr ssp;
16153
16154 /* Read in one sequence from the file */
16155 dataptr = ReadAsnFastaOrFlatFileEx (fp, &datatype, NULL, FALSE, FALSE,
16156 TRUE, FALSE, chars_stripped);
16157
16158 if (NULL == dataptr)
16159 {
16160 return NULL;
16161 }
16162
16163 /* Convert the file data to a SeqEntry */
16164
16165 if (datatype == OBJ_SEQENTRY)
16166 sep = (SeqEntryPtr) dataptr;
16167 else if (datatype == OBJ_BIOSEQ || datatype == OBJ_BIOSEQSET)
16168 sep = SeqMgrGetSeqEntryForData (dataptr);
16169 else if (datatype == OBJ_SEQSUB)
16170 {
16171 ssp = (SeqSubmitPtr) dataptr;
16172 if (ssp != NULL && ssp->datatype == 1)
16173 {
16174 sep = (SeqEntryPtr) ssp->data;
16175 }
16176 }
16177 return sep;
16178 }
16179
16180
ListIds(SeqEntryPtr sep_list)16181 static ValNodePtr ListIds (SeqEntryPtr sep_list)
16182 {
16183 BioseqPtr bsp;
16184 BioseqSetPtr bssp;
16185 SeqEntryPtr s;
16186 SeqIdPtr sip;
16187 Char id_txt[PATH_MAX];
16188 ValNodePtr list = NULL;
16189
16190 while (sep_list != NULL) {
16191 if (IS_Bioseq(sep_list) && (bsp = (BioseqPtr) sep_list->data.ptrvalue) != NULL) {
16192 for (sip = bsp->id; sip != NULL; sip = sip->next) {
16193 SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
16194 ValNodeAddPointer (&list, 0, StringSave(id_txt));
16195 }
16196 } else if (IS_Bioseq_set(sep_list) || (bssp = (BioseqSetPtr) sep_list->data.ptrvalue) == NULL) {
16197 for (s = bssp->seq_set; s != NULL; s = s->next) {
16198 ValNodeLink (&list, ListIds(s));
16199 }
16200 }
16201 sep_list = sep_list->next;
16202 }
16203 return list;
16204 }
16205
16206
HasDuplicateIds(SeqEntryPtr sep_list)16207 static Boolean HasDuplicateIds (SeqEntryPtr sep_list)
16208 {
16209 ValNodePtr list;
16210 Int4 num_before, num_after;
16211
16212 list = ListIds(sep_list);
16213 num_before = ValNodeLen (list);
16214 list = ValNodeSort (list, SortVnpByString);
16215 ValNodeUnique(&list, SortVnpByString, ValNodeFreeData);
16216 num_after = ValNodeLen (list);
16217 list = ValNodeFreeData (list);
16218 if (num_after != num_before) {
16219 return TRUE;
16220 } else {
16221 return FALSE;
16222 }
16223 }
16224
16225
ReadUpdateSequences(Boolean is_na,Boolean from_clipboard)16226 static SeqEntryPtr ReadUpdateSequences (Boolean is_na, Boolean from_clipboard)
16227 {
16228 FILE *fp;
16229 Char path [PATH_MAX];
16230 SeqEntryPtr sep_list;
16231 ValNodePtr err_msg_list = NULL;
16232 BioseqSetPtr top_bssp;
16233 BioseqPtr bsp;
16234 Uint2 entityID;
16235 Boolean chars_stripped = FALSE;
16236 CharPtr str;
16237
16238 if (from_clipboard) {
16239 if (!Nlm_ClipboardHasString()) {
16240 Message (MSG_ERROR, "Clipboard is empty!");
16241 return NULL;
16242 }
16243 TmpNam (path);
16244 fp = FileOpen (path, "w");
16245 str = ClipboardToString();
16246 fprintf (fp, "%s", str);
16247 FileClose (fp);
16248 str = MemFree (str);
16249 } else if (! GetInputFileName (path, sizeof (path),"","TEXT")) {
16250 return NULL;
16251 }
16252 fp = FileOpen (path, "r");
16253 if (fp == NULL)
16254 {
16255 Message (MSG_ERROR, "Unable to open %s", path);
16256 return NULL;
16257 }
16258 sep_list = ImportSequencesFromFileEx (fp, NULL, is_na, TRUE, NULL, &err_msg_list, &chars_stripped, TRUE);
16259 ValNodeFreeData (err_msg_list);
16260 FileClose (fp);
16261 if (HasDuplicateIds(sep_list)) {
16262 Message (MSG_ERROR, "Non-unique sequence IDs in update sequences!");
16263 return NULL;
16264 }
16265
16266 AddUniqueUpdateSequenceIDs (sep_list);
16267
16268 if (sep_list == NULL)
16269 {
16270 fp = FileOpen (path, "r");
16271 sep_list = ReadASNUpdateSequences (fp, &chars_stripped);
16272 FileClose (fp);
16273 if (from_clipboard) {
16274 FileRemove (path);
16275 }
16276
16277 if (sep_list == NULL)
16278 {
16279 Message (MSG_ERROR, "Unable to read sequences from %s, please check formatting", path);
16280 return NULL;
16281 }
16282 else if (chars_stripped)
16283 {
16284 if (ANS_CANCEL == Message (MSG_OKC, "Illegal characters will be stripped from your sequence data. Do you want to continue?"))
16285 {
16286 sep_list = SeqEntryFree (sep_list);
16287 return NULL;
16288 }
16289 }
16290
16291 if (sep_list->choice == 1)
16292 {
16293 bsp = (BioseqPtr) sep_list->data.ptrvalue;
16294 entityID = ObjMgrGetEntityIDForPointer (bsp);
16295 }
16296 else
16297 {
16298 top_bssp = (BioseqSetPtr) sep_list->data.ptrvalue;
16299 entityID = ObjMgrGetEntityIDForPointer (top_bssp);
16300 }
16301 AddUniqueUpdateSequenceIDs (sep_list);
16302 }
16303 else if (sep_list != NULL)
16304 {
16305 if (from_clipboard) {
16306 FileRemove (path);
16307 }
16308 if (chars_stripped)
16309 {
16310 if (ANS_CANCEL == Message (MSG_OKC, "Illegal characters will be stripped from your sequence data. Do you want to continue?"))
16311 {
16312 sep_list = SeqEntryFree (sep_list);
16313 return NULL;
16314 }
16315 }
16316 top_bssp = BioseqSetNew ();
16317 top_bssp->_class = BioseqseqSet_class_genbank;
16318 top_bssp->seq_set = sep_list;
16319 sep_list = SeqEntryNew ();
16320 sep_list->choice = 2;
16321 sep_list->data.ptrvalue = top_bssp;
16322 entityID = ObjMgrGetEntityIDForPointer (top_bssp);
16323 }
16324
16325 AssignIDsInEntityEx (entityID, 0, NULL, NULL);
16326 SeqMgrIndexFeatures (entityID, NULL);
16327
16328 return sep_list;
16329 }
16330
16331 typedef struct updatemultisequenceform
16332 {
16333 FORM_MESSAGE_BLOCK
16334 DialoG update_preview;
16335 DialoG options_dialog;
16336 DialoG titles_dlg;
16337 ButtoN update_this;
16338 ButtoN skip_this;
16339 ValNodePtr orig_bioseq_list;
16340 ValNodePtr update_bioseq_list;
16341 ValNodePtr unmatched_updates_list;
16342 ValNodePtr no_updates_list;
16343 Boolean is_na;
16344 LogInfoPtr lip;
16345 Int4 num_successful;
16346 Int4 num_failed;
16347 Int4 num_skipped;
16348 Char undo_file [PATH_MAX];
16349 ValNodePtr update_entityID_list; /* This list is used to remove sequences and sets loaded for update */
16350 } UpdateMultiSequenceFormData, PNTR UpdateMultiSequenceFormPtr;
16351
16352
DoTestUpdateOneSequence(ButtoN b)16353 static void DoTestUpdateOneSequence (ButtoN b)
16354 {
16355 UpdateMultiSequenceFormPtr usfp;
16356 SeqIdPtr sip;
16357 Char id_txt [MAX_ID_LEN];
16358 Int4 orig_pos;
16359 ValNodePtr orig_vnp, update_vnp;
16360 MultiSequenceUpdateData msud;
16361 Boolean update_successful = FALSE;
16362 UpdateAlignmentLengthsData uald;
16363 UpdateOptionsPtr uop;
16364 UpdatePairData upd;
16365 Uint2 update_entityID = 0;
16366 BioseqPtr update_bsp = NULL;
16367
16368 usfp = (UpdateMultiSequenceFormPtr) GetObjectExtra (b);
16369 if (usfp == NULL)
16370 {
16371 return;
16372 }
16373
16374 sip = DialogToPointer (usfp->update_preview);
16375 if (sip == NULL)
16376 {
16377 Message (MSG_ERROR, "No sequence selected!");
16378 return;
16379 }
16380
16381 uop = DialogToPointer (usfp->options_dialog);
16382 if (uop == NULL || !AreSubmitterOptsValid(uop->submitter_opts))
16383 {
16384 Message (MSG_ERROR, "Invalid options selected!");
16385 uop = UpdateOptionsFree (uop);
16386 return;
16387 }
16388
16389
16390 WatchCursor ();
16391 Update ();
16392
16393 SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
16394
16395 upd.orig_bsp = FindBioseqInList (usfp->orig_bioseq_list, sip, &orig_pos);
16396 if (upd.orig_bsp != NULL)
16397 {
16398 upd.update_bsp = NULL;
16399 update_vnp = GetNthValNode (usfp->update_bioseq_list, orig_pos + 1);
16400 if (update_vnp != NULL)
16401 {
16402 upd.update_bsp = update_vnp->data.ptrvalue;
16403 update_entityID = upd.update_bsp->idx.entityID;
16404 update_bsp = upd.update_bsp;
16405 }
16406
16407 /* if we are going to ignore the alignment, don't calculate it */
16408 if (uop->submitter_opts->ignore_alignment)
16409 {
16410 upd.revcomp = FALSE;
16411 upd.salp = NULL;
16412 }
16413 else
16414 {
16415 upd.revcomp = FALSE;
16416 upd.salp = Sqn_AlignForSequenceUpdate (upd.orig_bsp, upd.update_bsp, &(upd.revcomp));
16417 }
16418
16419 CalculateUpdateAlignmentLengths (upd.salp, upd.orig_bsp, upd.update_bsp, &uald);
16420 update_successful = UpdateOrExtendOneSequence (&upd, uop, &uald,
16421 usfp->input_entityID,
16422 usfp->lip == NULL ? NULL : usfp->lip->fp,
16423 usfp->lip == NULL ? NULL : &(usfp->lip->data_in_log));
16424 upd.salp = SeqAlignFree (upd.salp);
16425 }
16426 uop = UpdateOptionsFree (uop);
16427
16428 if (update_successful)
16429 {
16430 /* remove sequence and its pair from list */
16431 orig_vnp = ExtractNthValNode (&(usfp->orig_bioseq_list), orig_pos);
16432 orig_vnp = ValNodeFree (orig_vnp);
16433 update_vnp = ExtractNthValNode (&(usfp->update_bioseq_list), orig_pos);
16434 update_vnp = ValNodeFree (update_vnp);
16435
16436 /* don't delete update sequence until update dialog closes */
16437
16438 /* renumber valnode lists */
16439 for (orig_vnp = usfp->orig_bioseq_list; orig_vnp != NULL; orig_vnp = orig_vnp->next)
16440 {
16441 if (orig_vnp->choice > orig_pos)
16442 {
16443 orig_vnp->choice --;
16444 }
16445 }
16446 for (update_vnp = usfp->update_bioseq_list; update_vnp != NULL; update_vnp = update_vnp->next)
16447 {
16448 if (update_vnp->choice > orig_pos)
16449 {
16450 update_vnp->choice --;
16451 }
16452 }
16453
16454 /* only update the preview if we have any sequences left to update
16455 * otherwise we get a flash of a strange result
16456 */
16457 if (usfp->orig_bioseq_list != NULL)
16458 {
16459 msud.orig_bioseq_list = usfp->orig_bioseq_list;
16460 msud.update_bioseq_list = usfp->update_bioseq_list;
16461 msud.unmatched_updates_list = usfp->unmatched_updates_list;
16462 msud.no_updates_list = usfp->no_updates_list;
16463 PointerToDialog (usfp->update_preview, &msud);
16464
16465 /* maintain list position */
16466 if (orig_pos >= ValNodeLen (msud.orig_bioseq_list))
16467 {
16468 orig_pos--;
16469 }
16470 SelectUpdatePreviewSequenceByPosition (usfp->update_preview, orig_pos);
16471 }
16472 usfp->num_successful ++;
16473 }
16474
16475 SeqMgrClearFeatureIndexes (usfp->input_entityID, NULL);
16476 ObjMgrSetDirtyFlag (usfp->input_entityID, TRUE);
16477 ObjMgrSendMsg (OM_MSG_UPDATE, usfp->input_entityID, 0, 0);
16478
16479 /* close window after updating the last sequence */
16480 if (usfp->orig_bioseq_list == NULL)
16481 {
16482 Remove (usfp->form);
16483 }
16484 ArrowCursor ();
16485 Update ();
16486 }
16487
DoNotTestUpdateOneSequence(ButtoN b)16488 static void DoNotTestUpdateOneSequence (ButtoN b)
16489 {
16490 UpdateMultiSequenceFormPtr usfp;
16491 SeqIdPtr sip;
16492 Char id_txt [MAX_ID_LEN];
16493 BioseqPtr bsp, update_bsp;
16494 Int4 orig_pos;
16495 ValNodePtr orig_vnp, update_vnp;
16496 MultiSequenceUpdateData msud;
16497 Uint2 update_entityID;
16498
16499 usfp = (UpdateMultiSequenceFormPtr) GetObjectExtra (b);
16500 if (usfp == NULL)
16501 {
16502 return;
16503 }
16504
16505 sip = DialogToPointer (usfp->update_preview);
16506 if (sip == NULL)
16507 {
16508 Message (MSG_ERROR, "No sequence selected!");
16509 return;
16510 }
16511
16512 SeqIdWrite (SeqIdFindBest (sip, 0), id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
16513 if (usfp->lip != NULL && usfp->lip->fp != NULL)
16514 {
16515 fprintf (usfp->lip->fp, "Skipped %s\n", id_txt);
16516 usfp->lip->data_in_log = TRUE;
16517 }
16518
16519 usfp->num_skipped++;
16520 bsp = FindBioseqInList (usfp->orig_bioseq_list, sip, &orig_pos);
16521 if (bsp != NULL)
16522 {
16523 /* remove sequence and its pair from list */
16524 orig_vnp = ExtractNthValNode (&(usfp->orig_bioseq_list), orig_pos);
16525 orig_vnp = ValNodeFree (orig_vnp);
16526 update_vnp = ExtractNthValNode (&(usfp->update_bioseq_list), orig_pos);
16527
16528 /* remove update sequence from Desktop */
16529 if (update_vnp != NULL && update_vnp->data.ptrvalue != NULL)
16530 {
16531 update_bsp = (BioseqPtr) update_vnp->data.ptrvalue;
16532 update_bsp->idx.deleteme = TRUE;
16533 update_entityID = update_bsp->idx.entityID;
16534 DeleteMarkedObjects (update_entityID, 0, NULL);
16535 }
16536
16537 update_vnp = ValNodeFree (update_vnp);
16538 /* renumber valnode lists */
16539 for (orig_vnp = usfp->orig_bioseq_list; orig_vnp != NULL; orig_vnp = orig_vnp->next)
16540 {
16541 if (orig_vnp->choice > orig_pos)
16542 {
16543 orig_vnp->choice --;
16544 }
16545 }
16546 for (update_vnp = usfp->update_bioseq_list; update_vnp != NULL; update_vnp = update_vnp->next)
16547 {
16548 if (update_vnp->choice > orig_pos)
16549 {
16550 update_vnp->choice --;
16551 }
16552 }
16553 msud.orig_bioseq_list = usfp->orig_bioseq_list;
16554 msud.update_bioseq_list = usfp->update_bioseq_list;
16555 msud.unmatched_updates_list = usfp->unmatched_updates_list;
16556 msud.no_updates_list = usfp->no_updates_list;
16557 PointerToDialog (usfp->update_preview, &msud);
16558 /* maintain list position */
16559 if (orig_pos >= ValNodeLen (msud.orig_bioseq_list))
16560 {
16561 orig_pos--;
16562 }
16563 SelectUpdatePreviewSequenceByPosition (usfp->update_preview, orig_pos);
16564
16565 }
16566 /* close window after skipping the last sequence */
16567 if (usfp->orig_bioseq_list == NULL)
16568 {
16569 Remove (usfp->form);
16570 }
16571 }
16572
16573
GetUpdatesWithoutAlignments(ValNodePtr orig_bioseq_list,ValNodePtr update_bioseq_list)16574 static ValNodePtr GetUpdatesWithoutAlignments (ValNodePtr orig_bioseq_list, ValNodePtr update_bioseq_list)
16575 {
16576 ValNodePtr orig_vnp, update_vnp;
16577 BioseqPtr orig_bsp, update_bsp;
16578 Boolean revcomp;
16579 SeqAlignPtr salp;
16580 ValNodePtr no_aln_list = NULL;
16581 Char id_txt [MAX_ID_LEN];
16582
16583 for (orig_vnp = orig_bioseq_list, update_vnp = update_bioseq_list;
16584 orig_vnp != NULL && update_vnp != NULL;
16585 orig_vnp = orig_vnp->next, update_vnp = update_vnp->next)
16586 {
16587 if (orig_vnp->data.ptrvalue == NULL
16588 || update_vnp->data.ptrvalue == NULL)
16589 {
16590 continue;
16591 }
16592 orig_bsp = (BioseqPtr)(orig_vnp->data.ptrvalue);
16593 update_bsp = (BioseqPtr) (update_vnp->data.ptrvalue);
16594 revcomp = FALSE;
16595 salp = Sqn_AlignForSequenceUpdate (orig_bsp, update_bsp, &revcomp);
16596 if (salp == NULL) {
16597 SeqIdWrite (SeqIdFindBest (orig_bsp->id, SEQID_GENBANK), id_txt,
16598 PRINTID_REPORT, sizeof (id_txt) - 1);
16599 ValNodeAddPointer (&no_aln_list, 0, StringSave (id_txt));
16600 }
16601 if (revcomp) {
16602 BioseqRevComp (update_bsp);
16603 ReverseBioseqFeatureStrands (update_bsp);
16604 SeqMgrReplaceInBioseqIndex (update_bsp);
16605 }
16606 salp = SeqAlignFree (salp);
16607 }
16608 return no_aln_list;
16609 }
16610
16611
16612 typedef struct featureupdateinfo {
16613 BioseqPtr orig_bsp;
16614 BioseqPtr update_bsp;
16615 } FeatureUpdateInfoData, PNTR FeatureUpdateInfoPtr;
16616
16617
FeatureUpdateNew(BioseqPtr orig_bsp,BioseqPtr update_bsp)16618 static FeatureUpdateInfoPtr FeatureUpdateNew (BioseqPtr orig_bsp, BioseqPtr update_bsp)
16619 {
16620 FeatureUpdateInfoPtr f;
16621
16622 f = (FeatureUpdateInfoPtr) MemNew (sizeof (FeatureUpdateInfoData));
16623 f->orig_bsp = orig_bsp;
16624 f->update_bsp = update_bsp;
16625 return f;
16626 }
16627
16628
16629 typedef struct resolveduplicatefeats {
16630 BioseqPtr orig_bsp;
16631 SeqAnnotPtr newfeat_sap;
16632 } ResolveDuplicateFeatsData, PNTR ResolveDuplicateFeatsPtr;
16633
16634
ResolveDuplicateFeatsNew(BioseqPtr bsp,SeqAnnotPtr sap)16635 static ResolveDuplicateFeatsPtr ResolveDuplicateFeatsNew (BioseqPtr bsp, SeqAnnotPtr sap)
16636 {
16637 ResolveDuplicateFeatsPtr r;
16638
16639 r = (ResolveDuplicateFeatsPtr) MemNew (sizeof (ResolveDuplicateFeatsData));
16640 r->orig_bsp = bsp;
16641 r->newfeat_sap = sap;
16642 return r;
16643 }
16644
16645
UpdateAllSequences(ButtoN b)16646 static void UpdateAllSequences (ButtoN b)
16647 {
16648 UpdateMultiSequenceFormPtr usfp;
16649 ValNodePtr orig_vnp, update_vnp;
16650 Char id_txt [MAX_ID_LEN];
16651 UpdatePairData upd;
16652 Boolean update_successful;
16653 UpdateOptionsPtr uop;
16654 UpdateAlignmentLengthsData uald;
16655 BioseqPtr update_bsp = NULL;
16656 Uint2 update_entityID = 0;
16657 ValNodePtr no_aln_list;
16658 CharPtr msg;
16659 ValNodeBlock dupfeats;
16660 ValNodePtr vnp;
16661 ResolveDuplicateFeatsPtr r;
16662 SeqEntryPtr sep;
16663
16664 usfp = (UpdateMultiSequenceFormPtr) GetObjectExtra (b);
16665 if (usfp == NULL)
16666 {
16667 return;
16668 }
16669
16670 WatchCursor ();
16671 Update ();
16672
16673 /* Get Update Options */
16674 uop = DialogToPointer (usfp->options_dialog);
16675
16676 /* check for update pairs without alignments */
16677 if (uop != NULL && uop->submitter_opts != NULL
16678 && !uop->submitter_opts->ignore_alignment
16679 && uop->submitter_opts->sequence_update_type == eSequenceUpdateReplace)
16680 {
16681 no_aln_list = GetUpdatesWithoutAlignments (usfp->orig_bioseq_list, usfp->update_bioseq_list);
16682 if (no_aln_list != NULL)
16683 {
16684 msg = CreateListMessage ("Sequence",
16685 no_aln_list->next == NULL
16686 ? " has no alignment with its update sequence. Are you sure you want to do the replacement?"
16687 : " have no alignments with their update sequences. Are you sure you want to do the replacements?",
16688 no_aln_list);
16689 no_aln_list = ValNodeFreeData (no_aln_list);
16690 if (ANS_NO == Message (MSG_YN, msg))
16691 {
16692 msg = MemFree (msg);
16693 ArrowCursor();
16694 Update();
16695 return;
16696 }
16697 }
16698 }
16699
16700 InitValNodeBlock (&dupfeats, NULL);
16701
16702 for (orig_vnp = usfp->orig_bioseq_list, update_vnp = usfp->update_bioseq_list;
16703 orig_vnp != NULL && update_vnp != NULL;
16704 orig_vnp = orig_vnp->next, update_vnp = update_vnp->next)
16705 {
16706 if (orig_vnp->data.ptrvalue == NULL
16707 || update_vnp->data.ptrvalue == NULL)
16708 {
16709 continue;
16710 }
16711 upd.orig_bsp = (BioseqPtr)(orig_vnp->data.ptrvalue);
16712 upd.update_bsp = (BioseqPtr) (update_vnp->data.ptrvalue);
16713
16714 /* if we are going to ignore the alignment, don't calculate it */
16715 if ( uop != NULL && uop->submitter_opts != NULL && uop->submitter_opts->ignore_alignment)
16716 {
16717 upd.revcomp = FALSE;
16718 upd.salp = NULL;
16719 }
16720 else
16721 {
16722 upd.revcomp = FALSE;
16723 upd.salp = Sqn_AlignForSequenceUpdate (upd.orig_bsp, upd.update_bsp, &(upd.revcomp));
16724 }
16725 CalculateUpdateAlignmentLengths (upd.salp, upd.orig_bsp, upd.update_bsp, &uald);
16726 update_successful = UpdateOrExtendOneSequenceEx (&upd, uop, &uald,
16727 usfp->input_entityID,
16728 usfp->lip == NULL ? NULL : usfp->lip->fp,
16729 usfp->lip == NULL ? NULL : &(usfp->lip->data_in_log),
16730 TRUE);
16731 if (upd.feature_update_successful) {
16732 ValNodeAddPointerToEnd (&dupfeats, 0, ResolveDuplicateFeatsNew ((BioseqPtr)(orig_vnp->data.ptrvalue), upd.newfeat_sap));
16733 }
16734 upd.salp = SeqAlignFree (upd.salp);
16735
16736 SeqIdWrite (upd.orig_bsp->id, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
16737 if (usfp->lip != NULL && usfp->lip->fp != NULL && ! update_successful)
16738 {
16739 fprintf (usfp->lip->fp, "Failed to update %s\n", id_txt);
16740 usfp->lip->data_in_log = TRUE;
16741 }
16742 if (update_successful)
16743 {
16744 usfp->num_successful++;
16745 /* remove update sequence from list */
16746 update_vnp->data.ptrvalue = NULL;
16747 }
16748 else
16749 {
16750 usfp->num_failed++;
16751 }
16752
16753 }
16754
16755 if (dupfeats.head != NULL && uop != NULL && uop->submitter_opts != NULL
16756 && uop->submitter_opts->feature_import_options != NULL
16757 && uop->submitter_opts->feature_import_options->feature_import_type > eFeatureUpdateNoChange
16758 && uop->submitter_opts->feature_import_options->feature_import_type != eFeatureRemoveAll)
16759 {
16760 /* resolve features unless the policy was to remove all the old ones */
16761
16762 sep = GetTopSeqEntryForEntityID (usfp->input_entityID);
16763 /* need to set scope to make sure we mark the right bioseq for deletion */
16764 SeqEntrySetScope (sep);
16765 for (vnp = dupfeats.head; vnp != NULL; vnp = vnp->next)
16766 {
16767 r = (ResolveDuplicateFeatsPtr) vnp->data.ptrvalue;
16768 ResolveDuplicateUpdateFeats (r->orig_bsp, uop, r->newfeat_sap);
16769 }
16770 SeqEntrySetScope (NULL);
16771 DeleteMarkedObjects (usfp->input_entityID, 0, NULL);
16772 }
16773
16774 uop = UpdateOptionsFree (uop);
16775
16776 SeqMgrClearFeatureIndexes (usfp->input_entityID, NULL);
16777 ObjMgrSetDirtyFlag (usfp->input_entityID, TRUE);
16778 ObjMgrSendMsg (OM_MSG_UPDATE, usfp->input_entityID, 0, 0);
16779
16780 /* close window */
16781 if (usfp->num_failed == 0)
16782 {
16783 /* launch log viewer */
16784 CloseLog (usfp->lip);
16785 Remove (usfp->form);
16786 }
16787 ArrowCursor ();
16788 Update ();
16789 }
16790
UpdateSequenceSelectionChange(Pointer userdata)16791 static void UpdateSequenceSelectionChange (Pointer userdata)
16792 {
16793 UpdateMultiSequenceFormPtr usfp;
16794 SeqIdPtr sip;
16795 BioseqPtr orig_bsp;
16796 Int4 orig_pos;
16797 ValNodePtr update_vnp;
16798 UpdatePairPtr upp;
16799 UpdateAlignmentLengthsData uald;
16800 Boolean is_indexer = indexerVersion;
16801 UpdateOptionsPtr uop;
16802
16803 usfp = (UpdateMultiSequenceFormPtr) userdata;
16804 if (usfp == NULL)
16805 {
16806 return;
16807 }
16808
16809 sip = (SeqIdPtr) DialogToPointer (usfp->update_preview);
16810 if (sip == NULL)
16811 {
16812 Disable (usfp->update_this);
16813 Disable (usfp->skip_this);
16814 upp = NULL;
16815 }
16816 else
16817 {
16818 orig_bsp = FindBioseqInList (usfp->orig_bioseq_list, sip, &orig_pos);
16819 if (orig_bsp == NULL)
16820 {
16821 Disable (usfp->update_this);
16822 Disable (usfp->skip_this);
16823 }
16824 else
16825 {
16826 update_vnp = GetNthValNode (usfp->update_bioseq_list, orig_pos + 1);
16827 if (update_vnp == NULL || update_vnp->data.ptrvalue == NULL)
16828 {
16829 Disable (usfp->update_this);
16830 Enable (usfp->skip_this);
16831 }
16832 else
16833 {
16834 Enable (usfp->update_this);
16835 Enable (usfp->skip_this);
16836 }
16837 }
16838 upp = GetCurrentUpdatePair (usfp->update_preview);
16839 }
16840
16841 if (upp != NULL)
16842 CalculateUpdateAlignmentLengths (upp->salp,
16843 upp->orig_bsp,
16844 upp->update_bsp,
16845 &uald);
16846 AdjustUpdateOptionsEnabled (usfp->options_dialog, upp, &uald, is_indexer);
16847
16848 PointerToDialog (usfp->titles_dlg, upp);
16849
16850 uop = (UpdateOptionsPtr) DialogToPointer (usfp->options_dialog);
16851 if (uop != NULL && uop->submitter_opts != NULL)
16852 {
16853 if (uop->submitter_opts->ignore_alignment)
16854 {
16855 if (uop->submitter_opts->sequence_update_type == eSequenceUpdateExtend5)
16856 {
16857 SetIgnoreAndExtendForMultiSequencePreview (usfp->update_preview, TRUE, TRUE);
16858 }
16859 else if (uop->submitter_opts->sequence_update_type == eSequenceUpdateExtend3)
16860 {
16861 SetIgnoreAndExtendForMultiSequencePreview (usfp->update_preview, TRUE, FALSE);
16862 }
16863 else
16864 {
16865 SetIgnoreAndExtendForMultiSequencePreview (usfp->update_preview, FALSE, FALSE);
16866 }
16867 }
16868 else
16869 {
16870 SetIgnoreAndExtendForMultiSequencePreview (usfp->update_preview, FALSE, FALSE);
16871 }
16872 }
16873 else
16874 {
16875 SetIgnoreAndExtendForMultiSequencePreview (usfp->update_preview, FALSE, FALSE);
16876 }
16877 uop = UpdateOptionsFree (uop);
16878 }
16879
BioseqHasFeatures(BioseqPtr bsp)16880 static Boolean BioseqHasFeatures (BioseqPtr bsp)
16881 {
16882 SeqFeatPtr sfp;
16883 SeqMgrFeatContext context;
16884 Uint2 entityID;
16885
16886 if (bsp == NULL)
16887 {
16888 return FALSE;
16889 }
16890
16891 entityID = bsp->idx.entityID;
16892 if (entityID == 0)
16893 {
16894 entityID = ObjMgrGetEntityIDForPointer (bsp);
16895 }
16896 if (! SeqMgrFeaturesAreIndexed (entityID))
16897 {
16898 SeqMgrIndexFeatures (entityID, NULL);
16899 }
16900
16901 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &context);
16902 if (sfp == NULL)
16903 {
16904 return FALSE;
16905 }
16906 else
16907 {
16908 return TRUE;
16909 }
16910 }
16911
BioseqListHasFeatures(ValNodePtr bioseq_list)16912 static Boolean BioseqListHasFeatures (ValNodePtr bioseq_list)
16913 {
16914 Boolean has_features = FALSE;
16915
16916 while (bioseq_list != NULL && !has_features)
16917 {
16918 has_features = BioseqHasFeatures (bioseq_list->data.ptrvalue);
16919 bioseq_list = bioseq_list->next;
16920 }
16921 return has_features;
16922 }
16923
16924
EntityIDAlreadyInList(Uint2 entityID,ValNodePtr entityIDList)16925 extern Boolean EntityIDAlreadyInList (Uint2 entityID, ValNodePtr entityIDList)
16926 {
16927 while (entityIDList != NULL) {
16928 if ((Uint2)(entityIDList->data.intvalue) == entityID) {
16929 return TRUE;
16930 }
16931 }
16932 return FALSE;
16933 }
16934
16935
DestroyByEntityID(Uint2 entityID)16936 static void DestroyByEntityID (Uint2 entityID)
16937 {
16938 SeqEntryPtr sep;
16939 BioseqPtr bsp;
16940 BioseqSetPtr bssp;
16941 SeqSubmitPtr ssp;
16942
16943 sep = GetTopSeqEntryForEntityID (entityID);
16944 if (sep == NULL || sep->data.ptrvalue == NULL) {
16945 return;
16946 }
16947 if (IS_Bioseq(sep)) {
16948 bsp = (BioseqPtr) sep->data.ptrvalue;
16949 if (bsp->idx.parentptr != NULL && bsp->idx.parenttype == OBJ_SEQSUB) {
16950 ssp = (SeqSubmitPtr) bsp->idx.parentptr;
16951 ssp->idx.deleteme = TRUE;
16952 } else {
16953 bsp->idx.deleteme = TRUE;
16954 }
16955 } else if (IS_Bioseq_set (sep)) {
16956 bssp = (BioseqSetPtr) sep->data.ptrvalue;
16957 if (bssp->idx.parentptr != NULL && bssp->idx.parenttype == OBJ_SEQSUB) {
16958 ssp = (SeqSubmitPtr) bssp->idx.parentptr;
16959 ssp->idx.deleteme = TRUE;
16960 } else {
16961 bssp->idx.deleteme = TRUE;
16962 }
16963 }
16964 AssignIDsInEntityEx (entityID, 0, NULL, NULL);
16965 DeleteMarkedObjects (entityID, 0, NULL);
16966 Update();
16967 }
16968
16969
16970
CleanupUpdateMultiSequence(GraphiC g,Pointer data)16971 static void CleanupUpdateMultiSequence (GraphiC g, Pointer data)
16972 {
16973 UpdateMultiSequenceFormPtr usfp;
16974 ValNodePtr vnp;
16975 Uint2 update_entityID;
16976 ValNodePtr entityIDList = NULL;
16977 Boolean reopen_desktop = FALSE;
16978
16979 usfp = (UpdateMultiSequenceFormPtr) data;
16980 if (usfp != NULL)
16981 {
16982 /* report successes, skips, and failures */
16983 if (usfp->num_successful > 0)
16984 {
16985 if (usfp->num_skipped > 0)
16986 {
16987 if (usfp->num_failed > 0)
16988 {
16989 Message (MSG_OK, "%d succeeded, %d failed, %d skipped",
16990 usfp->num_successful,
16991 usfp->num_failed,
16992 usfp->num_skipped);
16993 }
16994 else
16995 {
16996 Message (MSG_OK, "%d succeeded, %d skipped",
16997 usfp->num_successful,
16998 usfp->num_skipped);
16999 }
17000 }
17001 else if (usfp->num_failed > 0)
17002 {
17003 Message (MSG_OK, "%d succeeded, %d failed",
17004 usfp->num_successful,
17005 usfp->num_failed);
17006 }
17007 else
17008 {
17009 Message (MSG_OK, "%d succeeded",
17010 usfp->num_successful);
17011 }
17012 }
17013 else
17014 {
17015 if (usfp->num_skipped > 0)
17016 {
17017 if (usfp->num_failed > 0)
17018 {
17019 Message (MSG_OK, "%d failed, %d skipped",
17020 usfp->num_failed,
17021 usfp->num_skipped);
17022 }
17023 else
17024 {
17025 Message (MSG_OK, "%d skipped",
17026 usfp->num_skipped);
17027 }
17028 }
17029 else if (usfp->num_failed > 0)
17030 {
17031 Message (MSG_OK, "%d failed",
17032 usfp->num_failed);
17033 }
17034 }
17035
17036 /* we don't need to free the data for the original bioseq list */
17037 usfp->orig_bioseq_list = ValNodeFree (usfp->orig_bioseq_list);
17038
17039 if (usfp->update_entityID_list != NULL)
17040 {
17041 if (IsVSeqMgrOpen()) {
17042 VSeqMgrDelete();
17043 reopen_desktop = TRUE;
17044 }
17045 for (vnp = usfp->update_entityID_list; vnp != NULL; vnp = vnp->next)
17046 {
17047 update_entityID = (Uint2) vnp->data.intvalue;
17048 DestroyByEntityID (update_entityID);
17049 }
17050 if (reopen_desktop) {
17051 VSeqMgrShow();
17052 }
17053 }
17054 usfp->update_entityID_list = ValNodeFree (usfp->update_entityID_list);
17055
17056 CloseLog (usfp->lip);
17057 usfp->lip = FreeLog (usfp->lip);
17058
17059 FileRemove (usfp->undo_file);
17060
17061 }
17062
17063 StdCleanupExtraProc (g, data);
17064 }
17065
LoadUpdateSequenceMapFile(UpdateMultiSequenceFormPtr usfp)17066 static void LoadUpdateSequenceMapFile (UpdateMultiSequenceFormPtr usfp)
17067 {
17068 Char path [PATH_MAX];
17069 ReadBufferData rbd;
17070 CharPtr line, ptr;
17071 SeqIdPtr sip_1, sip_2, sip_orig, sip_update;
17072 BioseqPtr bsp_orig, bsp_update;
17073 Int4 orig_position, update_position;
17074 ValNodePtr update_vnp;
17075 MultiSequenceUpdateData msud;
17076
17077 if (usfp == NULL)
17078 {
17079 return;
17080 }
17081
17082 if (! GetInputFileName (path, sizeof (path),"","TEXT"))
17083 return;
17084
17085 rbd.fp = FileOpen (path, "r");
17086 if (rbd.fp == NULL)
17087 {
17088 Message (MSG_ERROR, "Unable to open %s", path);
17089 return;
17090 }
17091
17092 rbd.current_data = NULL;
17093 line = AbstractReadFunction (&rbd);
17094 while (line != NULL)
17095 {
17096 ptr = line;
17097 /* skip over initial white space if any*/
17098 ptr += StringSpn (ptr, " \t");
17099 /* skip over first sequence ID */
17100 ptr += StringCSpn (ptr, "\t ");
17101 if (*ptr != 0 && ptr != line)
17102 {
17103 /* truncate string after first ID */
17104 *ptr = '\0';
17105 ptr++;
17106 /* skip over any white space before second ID */
17107 ptr += StringSpn (ptr, "\t ");
17108 /* truncate trailing white space */
17109 while (*(ptr + StringLen (ptr) - 1) == ' ' || *(ptr + StringLen (ptr) - 1) == '\t')
17110 {
17111 *(ptr + StringLen (ptr) - 1) = 0;
17112 }
17113
17114 sip_1 = MakeSeqID (line);
17115 sip_2 = MakeSeqID (ptr);
17116
17117 /* try to determine which is original and which is update */
17118 bsp_orig = FindBioseqInList (usfp->no_updates_list, sip_1, &orig_position);
17119 bsp_update = FindBioseqInList (usfp->unmatched_updates_list, sip_2, &update_position);
17120 if (bsp_orig == NULL && bsp_update == NULL)
17121 {
17122 bsp_orig = FindBioseqInList (usfp->no_updates_list, sip_2, &orig_position);
17123 bsp_update = FindBioseqInList (usfp->unmatched_updates_list, sip_1, &update_position);
17124 sip_orig = sip_2;
17125 sip_update = sip_1;
17126 }
17127 else
17128 {
17129 sip_orig = sip_1;
17130 sip_update = sip_2;
17131 }
17132
17133 if (bsp_orig != NULL && bsp_update != NULL)
17134 {
17135 /* remove Bioseq from no update list and add to list of originals */
17136 update_vnp = ExtractNthValNode (&(usfp->no_updates_list), orig_position);
17137 ValNodeLink (&(usfp->orig_bioseq_list), update_vnp);
17138 /* remove Bioseq from unmatched list and add to list of updates */
17139 update_vnp = ExtractNthValNode (&(usfp->unmatched_updates_list), update_position);
17140 ValNodeLink (&(usfp->update_bioseq_list), update_vnp);
17141 }
17142 sip_orig = SeqIdFree (sip_orig);
17143 sip_update = SeqIdFree (sip_update);
17144 }
17145 line = MemFree (line);
17146 line = AbstractReadFunction (&rbd);
17147 }
17148 FileClose (rbd.fp);
17149
17150 msud.orig_bioseq_list = usfp->orig_bioseq_list;
17151 msud.update_bioseq_list = usfp->update_bioseq_list;
17152 msud.unmatched_updates_list = usfp->unmatched_updates_list;
17153 msud.no_updates_list = usfp->no_updates_list;
17154 PointerToDialog (usfp->update_preview, &msud);
17155 }
17156
17157 static void
ReportIdenticalUpdateSequences(ValNodePtr orig_list,ValNodePtr update_list)17158 ReportIdenticalUpdateSequences
17159 (ValNodePtr orig_list,
17160 ValNodePtr update_list)
17161 {
17162 Char id_str [128];
17163 BioseqPtr orig_bsp, update_bsp;
17164 LogInfoPtr lip;
17165 Int4 num_identical = 0, num_total = 0;
17166
17167 lip = OpenLog ("Sequences Identical to Updates");
17168 if (lip == NULL)
17169 {
17170 return;
17171 }
17172 WatchCursor ();
17173 Update ();
17174 while (orig_list != NULL && update_list != NULL)
17175 {
17176 orig_bsp = orig_list->data.ptrvalue;
17177 update_bsp = update_list->data.ptrvalue;
17178
17179 if (orig_bsp != NULL)
17180 {
17181 num_total++;
17182 }
17183
17184 if (orig_bsp != NULL && update_bsp != NULL
17185 && AreSequenceResiduesIdentical (orig_bsp, update_bsp))
17186 {
17187 SeqIdWrite (SeqIdFindBest (orig_bsp->id, SEQID_GENBANK), id_str, PRINTID_REPORT, sizeof (id_str) - 1);
17188 fprintf (lip->fp, "%s\n", id_str);
17189 lip->data_in_log = TRUE;
17190 num_identical++;
17191 }
17192
17193 orig_list = orig_list->next;
17194 update_list = update_list->next;
17195 }
17196
17197 if (num_identical == 1)
17198 {
17199 Message (MSG_OK, "One sequence out of %d is identical to its update sequence.", num_total);
17200 }
17201 else if (num_identical > 1)
17202 {
17203 Message (MSG_OK, "%d sequences out of %d are identical to their update sequences.", num_identical, num_total);
17204 }
17205 CloseLog (lip);
17206 lip = FreeLog (lip);
17207 ArrowCursor ();
17208 Update ();
17209 }
17210
RemoveIdenticalUpdates(ButtoN b)17211 static void RemoveIdenticalUpdates (ButtoN b)
17212 {
17213 UpdateMultiSequenceFormPtr usfp;
17214 SeqIdPtr sip;
17215 Int4 orig_pos = 0, rem_pos = 0;
17216 ValNodePtr orig_list, update_list;
17217 ValNodePtr prev_orig_list = NULL, prev_update_list = NULL;
17218 ValNodePtr next_orig_list = NULL, next_update_list = NULL;
17219 Uint2 update_entityID = 0;
17220 MultiSequenceUpdateData msud;
17221 BioseqPtr orig_bsp, update_bsp;
17222
17223 usfp = (UpdateMultiSequenceFormPtr) GetObjectExtra (b);
17224 if (usfp == NULL)
17225 {
17226 return;
17227 }
17228
17229 sip = (SeqIdPtr) DialogToPointer (usfp->update_preview);
17230
17231 FindBioseqInList (usfp->orig_bioseq_list, sip, &orig_pos);
17232
17233
17234 orig_list = usfp->orig_bioseq_list;
17235 update_list = usfp->update_bioseq_list;
17236
17237 while (orig_list != NULL && update_list != NULL)
17238 {
17239 next_orig_list = orig_list->next;
17240 next_update_list = update_list->next;
17241 orig_bsp = orig_list->data.ptrvalue;
17242 update_bsp = update_list->data.ptrvalue;
17243
17244 if (orig_bsp != NULL && update_bsp != NULL
17245 && AreSequenceResiduesIdentical (orig_bsp, update_bsp))
17246 {
17247 /* remove pair from list */
17248 if (prev_orig_list == NULL)
17249 {
17250 usfp->orig_bioseq_list = orig_list->next;
17251 }
17252 else
17253 {
17254 prev_orig_list->next = orig_list->next;
17255 }
17256 if (prev_update_list == NULL)
17257 {
17258 usfp->update_bioseq_list = update_list->next;
17259 }
17260 else
17261 {
17262 prev_update_list->next = update_list->next;
17263 }
17264
17265 orig_list->next = NULL;
17266 orig_list = ValNodeFree (orig_list);
17267 update_list->next = NULL;
17268 update_list = ValNodeFree (update_list);
17269 if (rem_pos < orig_pos)
17270 {
17271 orig_pos --;
17272 }
17273 }
17274 else
17275 {
17276 prev_orig_list = orig_list;
17277 prev_update_list = update_list;
17278 rem_pos++;
17279 }
17280
17281 orig_list = next_orig_list;
17282 update_list = next_update_list;
17283 }
17284
17285 msud.orig_bioseq_list = usfp->orig_bioseq_list;
17286 msud.update_bioseq_list = usfp->update_bioseq_list;
17287 msud.unmatched_updates_list = usfp->unmatched_updates_list;
17288 msud.no_updates_list = usfp->no_updates_list;
17289 PointerToDialog (usfp->update_preview, &msud);
17290
17291 /* maintain list position */
17292 if (orig_pos >= ValNodeLen (msud.orig_bioseq_list))
17293 {
17294 orig_pos--;
17295 }
17296 SelectUpdatePreviewSequenceByPosition (usfp->update_preview, orig_pos);
17297
17298 /* close window after skipping the last sequence */
17299 if (usfp->orig_bioseq_list == NULL)
17300 {
17301 Message (MSG_OK, "All sequences were identical!");
17302 Remove (usfp->form);
17303 }
17304
17305
17306 Update ();
17307 }
17308
LoadUpdateSequenceMapFileBtn(ButtoN b)17309 static void LoadUpdateSequenceMapFileBtn (ButtoN b)
17310 {
17311 UpdateMultiSequenceFormPtr usfp;
17312
17313 usfp = (UpdateMultiSequenceFormPtr) GetObjectExtra (b);
17314 if (usfp == NULL) {
17315 return;
17316 }
17317 LoadUpdateSequenceMapFile (usfp);
17318 ReportIdenticalUpdateSequences (usfp->orig_bioseq_list, usfp->update_bioseq_list);
17319 if (BioseqListHasFeatures (usfp->update_bioseq_list)) {
17320 EnableImportFeatureOptions(usfp->options_dialog);
17321 } else {
17322 DisableImportFeatureOptions (usfp->options_dialog);
17323 }
17324 if (BioseqListHasFeatures (usfp->orig_bioseq_list)) {
17325 EnableRemoveFeatureOptions (usfp->options_dialog);
17326 } else {
17327 DisableRemoveFeatureOptions (usfp->options_dialog);
17328 }
17329 }
17330
17331
ConnectSelectedUpdateSequencesBtn(ButtoN b)17332 static void ConnectSelectedUpdateSequencesBtn (ButtoN b)
17333 {
17334 UpdateMultiSequenceFormPtr usfp;
17335 Int4 pos1;
17336 Int4 pos2;
17337 ValNodePtr update_vnp;
17338 MultiSequenceUpdateData msud;
17339
17340 usfp = (UpdateMultiSequenceFormPtr) GetObjectExtra (b);
17341 if (usfp == NULL) {
17342 return;
17343 }
17344
17345 pos1 = GetMultiSequenceUpdatePreviewUnmatchedSelection (usfp->update_preview);
17346 pos2 = GetMultiSequenceUpdatePreviewNoUpdateSelection (usfp->update_preview);
17347
17348 if (pos1 < 0 || pos2 < 0) {
17349 return;
17350 }
17351
17352 /* remap */
17353 /* remove Bioseq from no update list and add to list of originals */
17354 update_vnp = ExtractNthValNode (&(usfp->no_updates_list), pos2);
17355 if (update_vnp == NULL) {
17356 return;
17357 }
17358 ValNodeLink (&(usfp->orig_bioseq_list), update_vnp);
17359 /* remove Bioseq from unmatched list and add to list of updates */
17360 update_vnp = ExtractNthValNode (&(usfp->unmatched_updates_list), pos1);
17361 ValNodeLink (&(usfp->update_bioseq_list), update_vnp);
17362 /* update preview */
17363 msud.orig_bioseq_list = usfp->orig_bioseq_list;
17364 msud.update_bioseq_list = usfp->update_bioseq_list;
17365 msud.unmatched_updates_list = usfp->unmatched_updates_list;
17366 msud.no_updates_list = usfp->no_updates_list;
17367 PointerToDialog (usfp->update_preview, &msud);
17368
17369 ReportIdenticalUpdateSequences (usfp->orig_bioseq_list, usfp->update_bioseq_list);
17370 if (BioseqListHasFeatures (usfp->update_bioseq_list)) {
17371 EnableImportFeatureOptions(usfp->options_dialog);
17372 } else {
17373 DisableImportFeatureOptions (usfp->options_dialog);
17374 }
17375 if (BioseqListHasFeatures (usfp->orig_bioseq_list)) {
17376 EnableRemoveFeatureOptions (usfp->options_dialog);
17377 } else {
17378 DisableRemoveFeatureOptions (usfp->options_dialog);
17379 }
17380 }
17381
17382
UndoUpdates(ButtoN b)17383 static void UndoUpdates (ButtoN b)
17384 {
17385 UpdateMultiSequenceFormPtr usfp;
17386 Uint2 new_entityID;
17387
17388 usfp = (UpdateMultiSequenceFormPtr) GetObjectExtra (b);
17389 if (usfp == NULL)
17390 {
17391 return;
17392 }
17393 WatchCursor ();
17394 Update ();
17395
17396 new_entityID = RestoreEntityIDFromFile (usfp->undo_file, usfp->input_entityID);
17397 if (new_entityID != 0) {
17398 usfp->input_entityID = new_entityID;
17399 ObjMgrSetDirtyFlag (usfp->input_entityID, TRUE);
17400 ObjMgrSendMsg (OM_MSG_UPDATE, usfp->input_entityID, 0, 0);
17401 }
17402
17403 usfp->num_successful = 0;
17404 usfp->num_failed = 0;
17405 usfp->num_skipped = 0;
17406 usfp->lip = FreeLog (usfp->lip);
17407
17408 Remove (usfp->form);
17409 ArrowCursor ();
17410 Update ();
17411 }
17412
ExportUnmatchedUpdates(IteM i)17413 static void ExportUnmatchedUpdates (IteM i)
17414 {
17415 UpdateMultiSequenceFormPtr usfp;
17416 FILE *fp;
17417 Char path[PATH_MAX];
17418 ValNodePtr vnp;
17419 Char id_txt[128];
17420 BioseqPtr bsp;
17421
17422 usfp = (UpdateMultiSequenceFormPtr) GetObjectExtra (i);
17423 if (usfp == NULL) {
17424 return;
17425 }
17426
17427 if (! GetOutputFileName (path, sizeof (path), "")) return;
17428 fp = FileOpen (path, "w");
17429 if (fp == NULL)
17430 {
17431 Message (MSG_ERROR, "Unable to open %s", path);
17432 return;
17433 }
17434 fprintf (fp, "Unmatched update sequences\n");
17435 for (vnp = usfp->unmatched_updates_list; vnp != NULL; vnp = vnp->next) {
17436 bsp = (BioseqPtr) vnp->data.ptrvalue;
17437 if (bsp != NULL) {
17438 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
17439 fprintf (fp, "%s\n", id_txt);
17440 }
17441 }
17442
17443 fprintf (fp, "Sequences in record with no updates\n");
17444 for (vnp = usfp->no_updates_list; vnp != NULL; vnp = vnp->next) {
17445 bsp = (BioseqPtr) vnp->data.ptrvalue;
17446 if (bsp != NULL) {
17447 SeqIdWrite (SeqIdFindBest (bsp->id, SEQID_GENBANK), id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
17448 fprintf (fp, "%s\n", id_txt);
17449 }
17450 }
17451 FileClose (fp);
17452
17453 }
17454
TestUpdateSequenceSetBaseForm(BaseFormPtr bfp,Boolean is_indexer,Boolean do_update,Boolean from_clipboard)17455 NLM_EXTERN void TestUpdateSequenceSetBaseForm (BaseFormPtr bfp, Boolean is_indexer, Boolean do_update, Boolean from_clipboard)
17456 {
17457 WindoW w;
17458 CharPtr title;
17459 GrouP h, k, ext_grp;
17460 BioseqPtr orig_bsp, update_bsp;
17461 SeqEntryPtr sep;
17462 SeqEntryPtr update_list;
17463 GrouP c;
17464 ButtoN b;
17465 Boolean is_na;
17466 Int4 num_orig = 0, num_update = 0;
17467 UpdateMultiSequenceFormPtr usfp;
17468 MultiSequenceUpdateData msud;
17469 UpdateOptionsPtr uop;
17470 DialoG ext_dlg;
17471 MenU file_menu;
17472 IteM localItem;
17473 ValNodePtr vnp;
17474 SeqEntryPtr orig_scope;
17475
17476 if (bfp == NULL) return;
17477
17478 /* for test purposes, need to load sequence and update sequence */
17479 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
17480 if (sep == NULL)
17481 return;
17482
17483 if (ShowDeltaReport (sep)) {
17484 if (Message (MSG_YN, "This set contains delta sequences. If you update a delta sequence with a raw sequence, the delta sequence will be converted to raw. Do you want to continue?")
17485 != ANS_YES) {
17486 return;
17487 }
17488 }
17489
17490
17491 orig_bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID,
17492 bfp->input_itemtype);
17493 if (orig_bsp == NULL)
17494 {
17495 is_na = TRUE;
17496 }
17497 else
17498 {
17499 is_na = ISA_na (orig_bsp->mol);
17500 }
17501
17502 /* Read in the update data from a file */
17503 /* for now, just handling FASTA */
17504 update_list = ReadUpdateSequences (is_na, from_clipboard);
17505 if (update_list == NULL)
17506 {
17507 return;
17508 }
17509
17510 usfp = (UpdateMultiSequenceFormPtr) MemNew (sizeof (UpdateMultiSequenceFormData));
17511 if (usfp == NULL)
17512 {
17513 return;
17514 }
17515 usfp->input_entityID = bfp->input_entityID;
17516 usfp->is_na = is_na;
17517 usfp->orig_bioseq_list = NULL;
17518 usfp->update_bioseq_list = NULL;
17519 usfp->update_entityID_list = NULL;
17520
17521
17522 usfp->num_successful = 0;
17523 usfp->num_failed = 0;
17524 usfp->num_skipped = 0;
17525
17526 usfp->lip = OpenLog ("Update Sequence Log");
17527
17528 /* save the current SeqEntry to a file, so we can restore it if we need to */
17529 TmpNam (usfp->undo_file);
17530 write_out_put(sep, usfp->undo_file, FALSE);
17531
17532 ListBioseqsInSeqEntry (sep, usfp->is_na, &num_orig, &usfp->orig_bioseq_list);
17533 ListBioseqsInSeqEntry (update_list, usfp->is_na, &num_update, &usfp->update_bioseq_list);
17534
17535 /* add update sequence entity IDs */
17536 for (vnp = usfp->update_bioseq_list; vnp != NULL; vnp = vnp->next)
17537 {
17538 if (vnp->data.ptrvalue != NULL)
17539 {
17540 update_bsp = (BioseqPtr) vnp->data.ptrvalue;
17541 if (!EntityIDAlreadyInList(update_bsp->idx.entityID, usfp->update_entityID_list)) {
17542 ValNodeAddInt (&(usfp->update_entityID_list), 0, update_bsp->idx.entityID);
17543 }
17544 }
17545 }
17546
17547 orig_scope = SeqEntrySetScope (sep);
17548 usfp->unmatched_updates_list = ShuffleUpdateBioseqListWithIndex (&usfp->update_bioseq_list,
17549 usfp->orig_bioseq_list);
17550 SeqEntrySetScope (orig_scope);
17551
17552 usfp->no_updates_list = ExtractSequencesWithoutUpdates (&usfp->orig_bioseq_list, &usfp->update_bioseq_list);
17553 if (!is_indexer)
17554 {
17555 if (usfp->unmatched_updates_list != NULL)
17556 {
17557 if (ANS_YES == Message (MSG_YN, "Some sequences in your update file are not present in the record to be updated. Would you like to load a tab-delimited file to map the update files to the record files?"))
17558 {
17559 LoadUpdateSequenceMapFile (usfp);
17560 }
17561 }
17562 RemoveSequencesWithoutUpdates (&usfp->orig_bioseq_list, &usfp->update_bioseq_list);
17563 usfp->no_updates_list = ValNodeFree (usfp->no_updates_list);
17564 }
17565
17566 ReplaceCollidingUpdateIDs (usfp->update_bioseq_list, usfp->orig_bioseq_list);
17567
17568 /* Create window */
17569
17570 if (do_update) {
17571 title = "Update Sequence";
17572 } else {
17573 title = "Extend Sequence";
17574 }
17575 w = MovableModalWindow (-50, -33, -10, -10, title, NULL);
17576
17577 if (w == NULL)
17578 return;
17579
17580 SetObjectExtra (w, usfp, CleanupUpdateMultiSequence);
17581 usfp->form = (ForM) w;
17582
17583 if (is_indexer) {
17584 file_menu = PulldownMenu (w, "File");
17585 localItem = CommandItem (file_menu, "Export Unmatched", ExportUnmatchedUpdates);
17586 SetObjectExtra (localItem, usfp, NULL);
17587 }
17588
17589 h = HiddenGroup (w, -1, 0, NULL);
17590 SetGroupSpacing (h, 10, 10);
17591
17592 usfp->titles_dlg = UpdateTitlesDialog (h, is_indexer, do_update);
17593
17594 k = HiddenGroup (h, 2, 0, NULL);
17595 SetGroupSpacing (k, 10, 10);
17596
17597 usfp->update_preview = MultiSequenceUpdatePreview (k, usfp->is_na, do_update,
17598 UpdateSequenceSelectionChange,
17599 usfp,
17600 LoadUpdateSequenceMapFileBtn,
17601 ConnectSelectedUpdateSequencesBtn,
17602 is_indexer);
17603
17604 if (! do_update)
17605 {
17606 ext_grp = HiddenGroup (k, -1, 0, NULL);
17607
17608 ext_dlg = UpdateTitlesDialog (ext_grp, is_indexer, FALSE);
17609 AddExtendDialogToMultiSequenceUpdatePreview (usfp->update_preview, ext_dlg);
17610 ;
17611
17612 usfp->options_dialog = UpdateOptionsDialog (ext_grp, usfp->is_na, is_indexer, do_update,
17613 UpdateSequenceSelectionChange, usfp);
17614 AlignObjects (ALIGN_CENTER, (HANDLE) ext_dlg, (HANDLE) usfp->options_dialog, NULL);
17615 SetMultiSequenceUpdatePreviewMatchWindow (usfp->update_preview, (WindoW) ext_grp);
17616 }
17617 else
17618 {
17619 usfp->options_dialog = UpdateOptionsDialog (k, usfp->is_na, is_indexer, do_update,
17620 UpdateSequenceSelectionChange, usfp);
17621 }
17622
17623
17624 c = HiddenGroup (h, 6, 0, NULL);
17625 SetGroupSpacing (c, 10, 10);
17626 usfp->update_this = PushButton (c, "Update This Sequence", DoTestUpdateOneSequence);
17627 SetObjectExtra (usfp->update_this, usfp, NULL);
17628 usfp->skip_this = PushButton (c, "Skip This Sequence", DoNotTestUpdateOneSequence);
17629 SetObjectExtra (usfp->skip_this, usfp, NULL);
17630 b = PushButton (c, "Update All Sequences", UpdateAllSequences);
17631 SetObjectExtra (b, usfp, NULL);
17632
17633 b = PushButton (c, "Stop Updating", StdCancelButtonProc);
17634
17635 b = PushButton (c, "Cancel", UndoUpdates);
17636 SetObjectExtra (b, usfp, NULL);
17637
17638 AlignObjects (ALIGN_CENTER, (HANDLE) usfp->titles_dlg, (HANDLE) k, (HANDLE) c, NULL);
17639
17640 msud.orig_bioseq_list = usfp->orig_bioseq_list;
17641 msud.update_bioseq_list = usfp->update_bioseq_list;
17642 msud.unmatched_updates_list = usfp->unmatched_updates_list;
17643 msud.no_updates_list = usfp->no_updates_list;
17644 PointerToDialog (usfp->update_preview, &msud);
17645
17646 if (!BioseqListHasFeatures (usfp->update_bioseq_list))
17647 {
17648 DisableImportFeatureOptions (usfp->options_dialog);
17649 }
17650
17651 if (BioseqListHasFeatures (usfp->orig_bioseq_list)) {
17652 EnableRemoveFeatureOptions (usfp->options_dialog);
17653 } else {
17654 DisableRemoveFeatureOptions (usfp->options_dialog);
17655 }
17656
17657 uop = DialogToPointer (usfp->options_dialog);
17658 uop->submitter_opts->sequence_update_type = eSequenceUpdateReplace;
17659 PointerToDialog (usfp->options_dialog, uop);
17660 uop = UpdateOptionsFree (uop);
17661
17662 Show (w);
17663 Update ();
17664 ReportIdenticalUpdateSequences (usfp->orig_bioseq_list, usfp->update_bioseq_list);
17665 }
17666
TestUpdateSequenceSet(IteM i,Boolean is_indexer,Boolean do_update,Boolean from_clipboard)17667 static void TestUpdateSequenceSet (IteM i, Boolean is_indexer, Boolean do_update, Boolean from_clipboard)
17668 {
17669 BaseFormPtr bfp;
17670
17671 #ifdef WIN_MAC
17672 bfp = currentFormDataPtr;
17673 #else
17674 bfp = GetObjectExtra (i);
17675 #endif
17676 TestUpdateSequenceSetBaseForm (bfp, is_indexer, do_update, from_clipboard);
17677 }
17678
TestUpdateSequenceSetSubmitter(IteM i)17679 extern void TestUpdateSequenceSetSubmitter (IteM i)
17680 {
17681 TestUpdateSequenceSet (i, FALSE, TRUE, FALSE);
17682 }
17683
TestExtendSequenceSetSubmitter(IteM i)17684 extern void TestExtendSequenceSetSubmitter (IteM i)
17685 {
17686 TestUpdateSequenceSet (i, FALSE, FALSE, FALSE);
17687 }
17688
TestUpdateSequenceSetIndexer(IteM i)17689 extern void TestUpdateSequenceSetIndexer (IteM i)
17690 {
17691 TestUpdateSequenceSet (i, TRUE, TRUE, FALSE);
17692 }
17693
TestUpdateSequenceSetClipboardIndexer(IteM i)17694 extern void TestUpdateSequenceSetClipboardIndexer (IteM i)
17695 {
17696 TestUpdateSequenceSet (i, TRUE, TRUE, TRUE);
17697 }
17698
TestExtendSequenceSetIndexer(IteM i)17699 extern void TestExtendSequenceSetIndexer (IteM i)
17700 {
17701 TestUpdateSequenceSet (i, TRUE, FALSE, FALSE);
17702 }
17703
17704 typedef struct singlesequenceupdateform
17705 {
17706 FORM_MESSAGE_BLOCK
17707 DialoG preview_dlg;
17708 DialoG options_dlg;
17709 DialoG titles_dlg;
17710 Boolean is_na;
17711 LogInfoPtr lip;
17712 UpdatePairData update_pair;
17713 SeqEntryPtr update_list;
17714 Uint2 update_entity_ID;
17715 } SingleSequenceUpdateFormData, PNTR SingleSequenceUpdateFormPtr;
17716
17717
CleanupSingleSequenceUpdateForm(GraphiC g,Pointer data)17718 static void CleanupSingleSequenceUpdateForm (GraphiC g, Pointer data)
17719 {
17720 SingleSequenceUpdateFormPtr ssufp;
17721 Boolean reopen_desktop = FALSE;
17722
17723 ssufp = (SingleSequenceUpdateFormPtr) data;
17724 if (ssufp != NULL)
17725 {
17726 CloseLog (ssufp->lip);
17727 ssufp->lip = FreeLog (ssufp->lip);
17728
17729 if (IsVSeqMgrOpen()) {
17730 VSeqMgrDelete();
17731 reopen_desktop = TRUE;
17732 }
17733 DestroyByEntityID (ssufp->update_entity_ID);
17734 if (reopen_desktop) {
17735 VSeqMgrShow();
17736 }
17737 }
17738 StdCleanupExtraProc (g, data);
17739 }
17740
17741
DoUpdateSingleSequence(ButtoN b)17742 static void DoUpdateSingleSequence (ButtoN b)
17743 {
17744 SingleSequenceUpdateFormPtr ssufp;
17745 Char id_txt [MAX_ID_LEN];
17746 UpdateAlignmentLengthsData uald;
17747 UpdateOptionsPtr uop;
17748 Boolean update_successful = FALSE;
17749
17750 ssufp = (SingleSequenceUpdateFormPtr) GetObjectExtra (b);
17751
17752 WatchCursor ();
17753 Update ();
17754
17755 if (ssufp == NULL || ssufp->update_pair.orig_bsp == NULL)
17756 {
17757 return;
17758 }
17759
17760 uop = DialogToPointer (ssufp->options_dlg);
17761 if (uop == NULL || !AreSubmitterOptsValid(uop->submitter_opts))
17762 {
17763 Message (MSG_ERROR, "Invalid options selected!");
17764 uop = UpdateOptionsFree (uop);
17765 return;
17766 }
17767
17768 /* if we are going to ignore the alignment, remove it */
17769 if (uop->submitter_opts->ignore_alignment)
17770 {
17771 ssufp->update_pair.salp = NULL;
17772 ssufp->update_pair.revcomp = FALSE;
17773 }
17774 else
17775 {
17776 /* reverse the sequence prior to the update if necessary */
17777 if (ssufp->update_pair.revcomp)
17778 {
17779 BioseqRevComp (ssufp->update_pair.update_bsp);
17780 ReverseBioseqFeatureStrands (ssufp->update_pair.update_bsp);
17781 SeqMgrReplaceInBioseqIndex (ssufp->update_pair.update_bsp);
17782 }
17783 }
17784
17785 CalculateUpdateAlignmentLengths (ssufp->update_pair.salp,
17786 ssufp->update_pair.orig_bsp,
17787 ssufp->update_pair.update_bsp,
17788 &uald);
17789
17790 update_successful = UpdateOrExtendOneSequence (&(ssufp->update_pair),
17791 uop,
17792 &uald,
17793 ssufp->input_entityID,
17794 ssufp->lip->fp, &(ssufp->lip->data_in_log));
17795
17796 if (!update_successful && ssufp->lip != NULL && ssufp->lip->fp != NULL)
17797 {
17798 SeqIdWrite (ssufp->update_pair.orig_bsp->id, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
17799 fprintf (ssufp->lip->fp, "Failed to update %s\n", id_txt);
17800 ssufp->lip->data_in_log = TRUE;
17801 }
17802 uop = UpdateOptionsFree (uop);
17803
17804
17805 SeqMgrClearFeatureIndexes (ssufp->input_entityID, NULL);
17806 ObjMgrSetDirtyFlag (ssufp->input_entityID, TRUE);
17807 ObjMgrSendMsg (OM_MSG_UPDATE, ssufp->input_entityID, 0, 0);
17808
17809 Remove (ssufp->form);
17810 ArrowCursor ();
17811 Update ();
17812 }
17813
UpdateSingleSequenceOptions(Pointer userdata)17814 static void UpdateSingleSequenceOptions (Pointer userdata)
17815 {
17816 SingleSequenceUpdateFormPtr ssufp;
17817 UpdateAlignmentLengthsData uald;
17818 Boolean is_indexer = indexerVersion;
17819 UpdateOptionsPtr uop;
17820
17821 ssufp = (SingleSequenceUpdateFormPtr) userdata;
17822 if (ssufp == NULL)
17823 {
17824 return;
17825 }
17826
17827 CalculateUpdateAlignmentLengths (ssufp->update_pair.salp,
17828 ssufp->update_pair.orig_bsp,
17829 ssufp->update_pair.update_bsp,
17830 &uald);
17831
17832 AdjustUpdateOptionsEnabled (ssufp->options_dlg, &(ssufp->update_pair), &uald, is_indexer);
17833 uop = (UpdateOptionsPtr) DialogToPointer (ssufp->options_dlg);
17834 if (uop != NULL && uop->submitter_opts != NULL)
17835 {
17836 if (uop->submitter_opts->ignore_alignment)
17837 {
17838 if (uop->submitter_opts->sequence_update_type == eSequenceUpdateExtend5)
17839 {
17840 SetIgnoreAndExtendForPreviewPictures (ssufp->preview_dlg, TRUE, TRUE);
17841 }
17842 else if (uop->submitter_opts->sequence_update_type == eSequenceUpdateExtend3)
17843 {
17844 SetIgnoreAndExtendForPreviewPictures (ssufp->preview_dlg, TRUE, FALSE);
17845 }
17846 else
17847 {
17848 SetIgnoreAndExtendForPreviewPictures (ssufp->preview_dlg, FALSE, FALSE);
17849 }
17850 }
17851 else
17852 {
17853 SetIgnoreAndExtendForPreviewPictures (ssufp->preview_dlg, FALSE, FALSE);
17854 }
17855 }
17856 else
17857 {
17858 SetIgnoreAndExtendForPreviewPictures (ssufp->preview_dlg, FALSE, FALSE);
17859 }
17860 uop = UpdateOptionsFree (uop);
17861 }
17862
17863
17864 static void
UpdateSingleSequence(BioseqPtr orig_bsp,SeqEntryPtr update_list,Boolean is_indexer,Boolean do_update,Boolean update_is_download,Uint2 entityID)17865 UpdateSingleSequence
17866 (BioseqPtr orig_bsp,
17867 SeqEntryPtr update_list,
17868 Boolean is_indexer,
17869 Boolean do_update,
17870 Boolean update_is_download,
17871 Uint2 entityID)
17872 {
17873 WindoW w;
17874 CharPtr title;
17875 GrouP h, k;
17876 GrouP c;
17877 ButtoN b;
17878 Boolean is_na;
17879 Int4 num_update = 0;
17880 SingleSequenceUpdateFormPtr ssufp;
17881 ValNodePtr orig_bioseq_list = NULL, update_bioseq_list = NULL;
17882 UpdateAlignmentLengthsData uald;
17883 UpdateOptionsPtr uop;
17884
17885 if (orig_bsp == NULL || update_list == NULL)
17886 {
17887 return;
17888 }
17889
17890 is_na = ISA_na (orig_bsp->mol);
17891
17892 ssufp = (SingleSequenceUpdateFormPtr) MemNew (sizeof (SingleSequenceUpdateFormData));
17893 if (ssufp == NULL)
17894 {
17895 return;
17896 }
17897 ssufp->is_na = is_na;
17898 ssufp->lip = OpenLog ("Update Sequence Log");
17899
17900 ssufp->update_pair.orig_bsp = orig_bsp;
17901
17902 ssufp->update_list = update_list;
17903
17904 ValNodeAddPointer (&orig_bioseq_list, 0, orig_bsp);
17905 ListBioseqsInSeqEntry (update_list, ssufp->is_na, &num_update, &update_bioseq_list);
17906
17907 ReplaceCollidingUpdateIDs (update_bioseq_list, orig_bioseq_list);
17908
17909 ssufp->update_pair.update_bsp = update_bioseq_list->data.ptrvalue;
17910 update_bioseq_list = ValNodeFree (update_bioseq_list);
17911
17912 if (ssufp->update_pair.update_bsp != NULL)
17913 {
17914 ssufp->update_entity_ID = ssufp->update_pair.update_bsp->idx.entityID;
17915 }
17916
17917 if (ssufp->update_pair.orig_bsp != NULL && ssufp->update_pair.orig_bsp->repr == Seq_repr_delta
17918 && ssufp->update_pair.update_bsp != NULL && ssufp->update_pair.update_bsp->repr != Seq_repr_delta) {
17919 if (Message (MSG_YN, "You are about to update a delta sequence with a raw sequence, which will convert the delta sequence to raw. Do you want to continue?")
17920 != ANS_YES) {
17921 ssufp = MemFree (ssufp);
17922 return;
17923 }
17924 }
17925
17926 if (AreSequenceResiduesIdentical (ssufp->update_pair.orig_bsp,
17927 ssufp->update_pair.update_bsp))
17928 {
17929 Message (MSG_OK, "Sequence is identical to update sequence!");
17930 }
17931
17932 /* Create window */
17933
17934 if (do_update) {
17935 title = "Update Sequence";
17936 } else {
17937 title = "Extend Sequence";
17938 }
17939 w = FixedWindow (-50, -33, -10, -10, title, NULL);
17940
17941 if (w == NULL)
17942 return;
17943
17944 SetObjectExtra (w, ssufp, CleanupSingleSequenceUpdateForm);
17945 ssufp->form = (ForM) w;
17946 ssufp->input_entityID = entityID;
17947
17948 h = HiddenGroup (w, -1, 0, NULL);
17949 SetGroupSpacing (h, 10, 10);
17950
17951 ssufp->titles_dlg = UpdateTitlesDialog (h, is_indexer, do_update);
17952
17953 k = HiddenGroup (h, 2, 0, NULL);
17954
17955 SetGroupSpacing (k, 10, 10);
17956 if (do_update)
17957 {
17958 ssufp->preview_dlg = UpdatePreviewDialog (k, is_indexer);
17959 }
17960
17961 ssufp->update_pair.revcomp = FALSE;
17962 ssufp->update_pair.salp = Sqn_AlignForSequenceUpdate (ssufp->update_pair.orig_bsp,
17963 ssufp->update_pair.update_bsp,
17964 &(ssufp->update_pair.revcomp));
17965
17966 if (ssufp->update_pair.revcomp)
17967 {
17968 BioseqRevComp (ssufp->update_pair.update_bsp);
17969 ReverseBioseqFeatureStrands (ssufp->update_pair.update_bsp);
17970 SeqMgrReplaceInBioseqIndex (ssufp->update_pair.update_bsp);
17971 }
17972
17973 ssufp->options_dlg = UpdateOptionsDialog (k, ssufp->is_na, is_indexer, do_update,
17974 UpdateSingleSequenceOptions, ssufp);
17975 PointerToDialog (ssufp->preview_dlg, &(ssufp->update_pair));
17976 PointerToDialog (ssufp->titles_dlg, &(ssufp->update_pair));
17977
17978 c = HiddenGroup (h, 4, 0, NULL);
17979 SetGroupSpacing (c, 10, 10);
17980 b = PushButton (c, "Update Sequence", DoUpdateSingleSequence);
17981 SetObjectExtra (b, ssufp, NULL);
17982 b = PushButton (c, "Cancel", StdCancelButtonProc);
17983
17984 AlignObjects (ALIGN_CENTER, (HANDLE) ssufp->titles_dlg, (HANDLE) k, (HANDLE) c, NULL);
17985
17986 if (BioseqHasFeatures (ssufp->update_pair.update_bsp)) {
17987 EnableImportFeatureOptions(ssufp->options_dlg);
17988 uop = DialogToPointer (ssufp->options_dlg);
17989 /* for public version only, if there are features, default to
17990 * import all except duplicates
17991 */
17992 if (!is_indexer) {
17993 if (uop->submitter_opts->feature_import_options == NULL) {
17994 uop->submitter_opts->feature_import_options = FeatureImportOptionsNew ();
17995 }
17996 uop->submitter_opts->feature_import_options->feature_import_type = eFeatureUpdateAllExceptDups;
17997 uop->submitter_opts->feature_import_options->feature_types = ValNodeFree (uop->submitter_opts->feature_import_options->feature_types);
17998 PointerToDialog (ssufp->options_dlg, uop);
17999 uop = UpdateOptionsFree (uop);
18000 }
18001 } else {
18002 DisableImportFeatureOptions (ssufp->options_dlg);
18003 }
18004
18005 if (BioseqHasFeatures (ssufp->update_pair.orig_bsp)) {
18006 EnableRemoveFeatureOptions (ssufp->options_dlg);
18007 } else {
18008 DisableRemoveFeatureOptions (ssufp->options_dlg);
18009 }
18010
18011 CalculateUpdateAlignmentLengths (ssufp->update_pair.salp,
18012 ssufp->update_pair.orig_bsp,
18013 ssufp->update_pair.update_bsp,
18014 &uald);
18015 AdjustUpdateOptionsEnabled (ssufp->options_dlg, &(ssufp->update_pair), &uald, is_indexer);
18016
18017 uop = DialogToPointer (ssufp->options_dlg);
18018 if (is_indexer)
18019 {
18020 if (update_is_download && ssufp->update_pair.salp != NULL)
18021 {
18022 uop->submitter_opts->sequence_update_type = eSequenceUpdateNoChange;
18023 }
18024 else
18025 {
18026 uop->submitter_opts->sequence_update_type = eSequenceUpdateReplace;
18027 }
18028 }
18029 else
18030 {
18031 if (ssufp->update_pair.salp == NULL)
18032 {
18033 /* no alignment - default is to replace */
18034 uop->submitter_opts->sequence_update_type = eSequenceUpdateReplace;
18035 }
18036 else if (uald.new5 > uald.old5 && uald.new3 < uald.old3)
18037 {
18038 /* new 5' end is bigger, new 3' end is smaller,
18039 * default is extend 5' */
18040 uop->submitter_opts->sequence_update_type = eSequenceUpdateExtend5;
18041 }
18042 else if (uald.new5 < uald.old5 && uald.new3 > uald.old3)
18043 {
18044 /* new 3' end is bigger, new 5' end is smaller,
18045 * default is extend 3' */
18046 uop->submitter_opts->sequence_update_type = eSequenceUpdateExtend3;
18047 }
18048 else
18049 {
18050 uop->submitter_opts->sequence_update_type = eSequenceUpdateReplace;
18051 }
18052 }
18053 PointerToDialog (ssufp->options_dlg, uop);
18054 uop = UpdateOptionsFree (uop);
18055
18056 Show (w);
18057 Update ();
18058 }
18059
TestUpdateSequenceBaseForm(BaseFormPtr bfp,Boolean is_indexer,Boolean do_update,Boolean from_clipboard)18060 NLM_EXTERN void TestUpdateSequenceBaseForm (BaseFormPtr bfp, Boolean is_indexer, Boolean do_update, Boolean from_clipboard)
18061 {
18062 BioseqPtr orig_bsp;
18063 SeqEntryPtr sep;
18064 SeqEntryPtr update_list;
18065 Boolean is_na;
18066
18067 if (bfp == NULL) return;
18068
18069 /* for test purposes, need to load sequence and update sequence */
18070 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
18071 if (sep == NULL)
18072 return;
18073 orig_bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID,
18074 bfp->input_itemtype);
18075 if (orig_bsp == NULL)
18076 return;
18077
18078 is_na = ISA_na (orig_bsp->mol);
18079
18080 /* Read in the update data from a file */
18081 update_list = ReadUpdateSequences (is_na, from_clipboard);
18082 if (update_list == NULL)
18083 {
18084 return;
18085 }
18086
18087 UpdateSingleSequence (orig_bsp, update_list, is_indexer, do_update, FALSE, bfp->input_entityID);
18088 }
18089
18090
TestUpdateSequence(IteM i,Boolean is_indexer,Boolean do_update,Boolean from_clipboard)18091 static void TestUpdateSequence (IteM i, Boolean is_indexer, Boolean do_update, Boolean from_clipboard)
18092 {
18093 BaseFormPtr bfp;
18094
18095 #ifdef WIN_MAC
18096 bfp = currentFormDataPtr;
18097 #else
18098 bfp = GetObjectExtra (i);
18099 #endif
18100 if (bfp == NULL) return;
18101 TestUpdateSequenceBaseForm (bfp, is_indexer, do_update, from_clipboard);
18102 }
18103
18104
TestUpdateSequenceIndexer(IteM i)18105 extern void TestUpdateSequenceIndexer (IteM i)
18106 {
18107 TestUpdateSequence (i, TRUE, TRUE, FALSE);
18108 }
18109
TestUpdateSequenceClipboardIndexer(IteM i)18110 extern void TestUpdateSequenceClipboardIndexer (IteM i)
18111 {
18112 TestUpdateSequence (i, TRUE, TRUE, TRUE);
18113 }
18114
18115
TestExtendSequenceIndexer(IteM i)18116 extern void TestExtendSequenceIndexer (IteM i)
18117 {
18118 TestUpdateSequence (i, TRUE, FALSE, FALSE);
18119 }
18120
TestUpdateSequenceSubmitter(IteM i)18121 extern void TestUpdateSequenceSubmitter (IteM i)
18122 {
18123 TestUpdateSequence (i, FALSE, TRUE, FALSE);
18124 }
18125
TestExtendSequenceSubmitter(IteM i)18126 extern void TestExtendSequenceSubmitter (IteM i)
18127 {
18128 TestUpdateSequence (i, FALSE, FALSE, FALSE);
18129 }
18130
18131 typedef struct seqentrydownload
18132 {
18133 FORM_MESSAGE_BLOCK
18134 GrouP accntype;
18135 TexT accession;
18136 ButtoN accept;
18137 } SeqEntryDownloadData, PNTR SeqEntryDownloadPtr;
18138
TypeAccessionProc(TexT t)18139 static void TypeAccessionProc (TexT t)
18140
18141 {
18142 Boolean alldigits;
18143 Char ch;
18144 SeqEntryDownloadPtr sedp;
18145 CharPtr ptr;
18146 Char str [32];
18147
18148 sedp = (SeqEntryDownloadPtr) GetObjectExtra (t);
18149 if (sedp == NULL) return;
18150 GetTitle (t, str, sizeof (str));
18151 if (StringHasNoText (str)) {
18152 SafeDisable (sedp->accept);
18153 } else {
18154 SafeEnable (sedp->accept);
18155 TrimSpacesAroundString (str);
18156 alldigits = TRUE;
18157 ptr = str;
18158 ch = *ptr;
18159 while (ch != '\0') {
18160 if (! IS_DIGIT (ch)) {
18161 alldigits = FALSE;
18162 }
18163 ptr++;
18164 ch = *ptr;
18165 }
18166 if (alldigits) {
18167 SafeSetValue (sedp->accntype, 2);
18168 } else {
18169 SafeSetValue (sedp->accntype, 1);
18170 }
18171 }
18172 }
18173
18174
SetContainsID(BioseqSetPtr bssp,SeqIdPtr sip)18175 static Boolean SetContainsID (BioseqSetPtr bssp, SeqIdPtr sip)
18176 {
18177 SeqEntryPtr sep;
18178 Boolean rval = FALSE;
18179 BioseqPtr bsp;
18180
18181 if (bssp == NULL) return FALSE;
18182
18183 for (sep = bssp->seq_set; sep != NULL && !rval; sep = sep->next) {
18184 if (IS_Bioseq (sep)) {
18185 bsp = (BioseqPtr) sep->data.ptrvalue;
18186 rval = SeqIdIn (sip, bsp->id);
18187 } else if (IS_Bioseq_set (sep)) {
18188 rval = SetContainsID ((BioseqSetPtr) sep->data.ptrvalue, sip);
18189 }
18190 }
18191 return rval;
18192 }
18193
DeleteAllButRequestedSequenceAndItsProteins(BioseqSetPtr bssp,SeqIdPtr sip)18194 static void DeleteAllButRequestedSequenceAndItsProteins (BioseqSetPtr bssp, SeqIdPtr sip)
18195 {
18196 SeqEntryPtr sep;
18197 BioseqPtr bsp;
18198
18199 if (bssp == NULL) return;
18200
18201 if (SetContainsID (bssp, sip)) {
18202 if (bssp->_class != BioseqseqSet_class_nuc_prot && bssp->_class != BioseqseqSet_class_segset) {
18203 /* delete all subsets that don't contain ID */
18204 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
18205 if (IS_Bioseq(sep)) {
18206 bsp = (BioseqPtr) sep->data.ptrvalue;
18207 if (bsp != NULL && !SeqIdIn (sip, bsp->id)) {
18208 bsp->idx.deleteme = TRUE;
18209 }
18210 } else if (IS_Bioseq_set (sep)) {
18211 DeleteAllButRequestedSequenceAndItsProteins ((BioseqSetPtr) sep->data.ptrvalue, sip);
18212 }
18213 }
18214 }
18215 } else {
18216 bssp->idx.deleteme = TRUE;
18217 }
18218 }
18219
DownloadUpdateSequence(void)18220 static SeqEntryPtr DownloadUpdateSequence (void)
18221 {
18222 GrouP c;
18223 SeqEntryDownloadData sedd;
18224 GrouP g;
18225 WindoW w;
18226 ModalAcceptCancelData acd;
18227 ButtoN b;
18228 SeqEntryPtr fetched_sep = NULL;
18229 Char str [32];
18230 SeqIdPtr sip;
18231 Uint2 entityID;
18232 BioseqPtr bsp;
18233 BioseqSetPtr bssp;
18234
18235 w = MovableModalWindow (-50, -33, -10, -10, "Download From Entrez", NULL);
18236 SetObjectExtra (w, &sedd, NULL);
18237 sedd.form = (ForM) w;
18238 SetGroupSpacing (w, 10, 10);
18239
18240 g = HiddenGroup (w, -3, 0, NULL);
18241 StaticPrompt (g, "Type", 0, stdLineHeight, programFont, 'l');
18242 sedd.accntype = HiddenGroup (g, 4, 0, NULL);
18243 RadioButton (sedd.accntype, "Accession");
18244 RadioButton (sedd.accntype, "GI");
18245 SetValue (sedd.accntype, 1);
18246 sedd.accession = DialogText (g, "", 6, TypeAccessionProc);
18247 SetObjectExtra (sedd.accession, &sedd, NULL);
18248
18249 c = HiddenGroup (w, 4, 0, NULL);
18250 SetGroupSpacing (c, 10, 2);
18251 sedd.accept = DefaultButton (c, "Retrieve", ModalAcceptButton);
18252 SetObjectExtra (sedd.accept, &acd, NULL);
18253 Disable (sedd.accept);
18254 b = PushButton (c, "Cancel", ModalCancelButton);
18255 SetObjectExtra (b, &acd, NULL);
18256
18257 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
18258 RealizeWindow (w);
18259
18260 Select (sedd.accession);
18261 Show (w);
18262 Select (w);
18263 Update ();
18264
18265 acd.accepted = FALSE;
18266 acd.cancelled = FALSE;
18267 while (!acd.accepted && ! acd.cancelled)
18268 {
18269 ProcessExternalEvent ();
18270 Update ();
18271 }
18272 ProcessAnEvent ();
18273
18274 if (acd.accepted)
18275 {
18276 Hide (w);
18277 WatchCursor ();
18278 Update ();
18279
18280 GetTitle (sedd.accession, str, sizeof (str));
18281 if (!StringHasNoText (str))
18282 {
18283 sip = SeqIdFromPubSeqString (str);
18284 fetched_sep = PubSeqSynchronousQueryId (sip, 0, /* -1 */ 0);
18285 ArrowCursor ();
18286 Update ();
18287 if (fetched_sep == NULL)
18288 {
18289 Message (MSG_OK, "Unable to find this record in the database.");
18290 }
18291 else
18292 {
18293 if (IS_Bioseq (fetched_sep))
18294 {
18295 bsp = (BioseqPtr) fetched_sep->data.ptrvalue;
18296 entityID = ObjMgrGetEntityIDForPointer (bsp);
18297 }
18298 else
18299 {
18300 bssp = (BioseqSetPtr) fetched_sep->data.ptrvalue;
18301 entityID = ObjMgrGetEntityIDForPointer (bssp);
18302 AssignIDsInEntityEx (entityID, 0, NULL, NULL);
18303 DeleteAllButRequestedSequenceAndItsProteins (bssp, sip);
18304 if (bssp->idx.deleteme) {
18305 fetched_sep = NULL;
18306 }
18307 DeleteMarkedObjects (0, OBJ_BIOSEQSET, bssp);
18308 }
18309 }
18310 sip = SeqIdFree (sip);
18311 }
18312 }
18313 Remove (w);
18314 return fetched_sep;
18315 }
18316
18317
UpdateSequenceViaDownload(IteM i,Boolean is_indexer)18318 static void UpdateSequenceViaDownload (IteM i, Boolean is_indexer)
18319 {
18320 BaseFormPtr bfp;
18321 SeqEntryPtr sep;
18322 BioseqPtr orig_bsp;
18323 Boolean is_na;
18324 SeqEntryPtr update_sep;
18325
18326 #ifdef WIN_MAC
18327 bfp = currentFormDataPtr;
18328 #else
18329 bfp = GetObjectExtra (i);
18330 #endif
18331 if (bfp == NULL) return;
18332
18333 /* for test purposes, need to load sequence and update sequence */
18334 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
18335 if (sep == NULL)
18336 return;
18337 orig_bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID,
18338 bfp->input_itemtype);
18339 if (orig_bsp == NULL)
18340 return;
18341
18342 is_na = ISA_na (orig_bsp->mol);
18343
18344 update_sep = DownloadUpdateSequence ();
18345 if (update_sep == NULL)
18346 {
18347 return;
18348 }
18349
18350 UpdateSingleSequence (orig_bsp, update_sep, is_indexer, TRUE, TRUE, bfp->input_entityID);
18351 }
18352
UpdateSequenceViaDownloadIndexer(IteM i)18353 extern void UpdateSequenceViaDownloadIndexer (IteM i)
18354 {
18355 UpdateSequenceViaDownload (i, TRUE);
18356 }
18357
UpdateSequenceViaDownloadSubmitter(IteM i)18358 extern void UpdateSequenceViaDownloadSubmitter (IteM i)
18359 {
18360 UpdateSequenceViaDownload (i, FALSE);
18361 }
18362
18363