1 /* ===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *            National Center for Biotechnology Information (NCBI)
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government do not place any restriction on its use or reproduction.
12 *  We would, however, appreciate having the NCBI and the author cited in
13 *  any work or product based on this material
14 *
15 *  Although all reasonable efforts have been taken to ensure the accuracy
16 *  and reliability of the software and data, the NLM and the U.S.
17 *  Government do not and cannot warrant the performance or results that
18 *  may be obtained by using this software or data. The NLM and the U.S.
19 *  Government disclaim all warranties, express or implied, including
20 *  warranties of performance, merchantability or fitness for any particular
21 *  purpose.
22 *
23 * ===========================================================================
24 *
25 * File Name:  salsa.c
26 *
27 * Author:  Colombe Chappey
28 *
29 * Version Creation Date:   1/27/96
30 *
31 * $Revision: 6.190 $
32 *
33 * File Description:
34 *
35 * Modifications:
36 * --------------------------------------------------------------------------
37 * Date     Name        Description of modification
38 * -------  ----------  -----------------------------------------------------
39 *
40 *
41 * ==========================================================================
42 */
43 #include <salsa.h>
44 #include <saledit.h>
45 #include <salutil.h>
46 #include <salsap.h>
47 #include <salstruc.h>
48 #include <salpanel.h>
49 #include <saled.h>
50 #include <salparam.h>
51 #include <salfiles.h>
52 #include <salprop.h>
53 #include <salmedia.h>
54 #include <dlogutil.h>
55 #include <sqnutils.h>
56 #include <seqmgr.h>
57 #include <fstyle.h>
58 #include <satutil.h>
59 #include <picture.h>
60 #include <viewer.h>
61 #include <drawseq.h>
62 #include <vsm.h>
63 #include <bspview.h>
64 #include <alignval.h>
65 #include <salpacc.h>
66 #include <salpedit.h>
67 #include <salptool.h>
68 #include <alignmgr.h>
69 #include <alignmgr2.h>
70 #include <seqpanel.h>
71 #include <blastpri.h>
72 #include <spidey.h>
73 
74 /******/
75 #include <pgppop.h>
76 /****/
77 
78 #define OBJ_VIRT 254
79 #define MARGINLEFT15 16
80 #define MARGINLEFT25 22
81 
82 static SelEdStructPtr seq_info=NULL;
83 
84 static EditAlignDataPtr SeqAlignToEditAlignData (EditAlignDataPtr adp, SeqAlignPtr salp, Int4 start, SeqIdPtr mastersip, Uint1 showfeature);
85 static void CleanupAlignDataPanel (GraphiC g, VoidPtr data);
86 static void CloseWindowProc (PaneL pnl);
87 static void InsertSequenceDlg (ButtoN b);
88 static void CancelButton (ButtoN b);
89 static void InsertSequenceButton (ButtoN b);
90 static void InsertSeqProc (IteM i);
91 
92 
AmIConfiguredForTheNetwork(void)93 static Boolean AmIConfiguredForTheNetwork (void)
94 
95 {
96   SeqEditViewProcsPtr  svpp;
97 
98   svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
99   if (svpp != NULL)
100      if(svpp->download != NULL) return TRUE;
101   return FALSE;
102 }
103 
seqentry_write(SeqEntryPtr sep,CharPtr path)104 static Boolean seqentry_write (SeqEntryPtr sep, CharPtr path)
105 {
106   Char         name[PATH_MAX];
107   AsnIoPtr     aip;
108   AsnTypePtr   atp;
109   AsnModulePtr amp;
110 
111   if ( sep == NULL ) {
112     return 0;
113   }
114   if (path == NULL )
115   {
116      if (! GetInputFileName (name, PATH_MAX,"","TEXT"))  {
117         return 0;
118      }
119      path = name;
120   }
121   amp = AsnAllModPtr ();
122   atp = AsnTypeFind (amp,"SeqEntry");
123   if ((aip = AsnIoOpen (path,"w")) == NULL) {
124     return 0;
125   }
126   SeqEntryAsnWrite ( sep, aip, atp ) ;
127   aip = AsnIoClose (aip);
128   return 1;
129 }
130 
get_client_rect(PaneL p,RectPtr prc)131 static void get_client_rect (PaneL p, RectPtr prc)
132 {
133   ObjectRect (p, prc);
134   InsetRect (prc, HRZ_BORDER_WIDTH, VER_BORDER_WIDTH);
135 }
136 
getsize_seqids(ValNodePtr sloc,Uint1 printid)137 static Int2 getsize_seqids (ValNodePtr sloc, Uint1 printid)
138 {
139   ValNodePtr  vnp;
140   SeqLocPtr   slp;
141   SeqIdPtr    sip;
142   Char        str [52];
143   Int4        lens,
144               max = 15;
145 
146   if (printid < 1)
147      return 15;
148 
149   for (vnp=sloc; vnp!=NULL; vnp=vnp->next)
150   {
151      slp = (SeqLocPtr) vnp->data.ptrvalue;
152      if (slp!=NULL) {
153         sip = SeqLocId (slp);
154         if (sip!=NULL) {
155            SeqIdWrite (sip, str, printid, 50);
156            lens = (Int4)StringLen (str);
157            if (lens > max)
158               max = lens;
159         }
160      }
161   }
162   return max;
163 }
164 
165 /**************************************************
166 *** update_sequenceeditormenu
167 ***************************************************/
seqeditor2aligneditor(SeqEditViewFormPtr wdp)168 static void seqeditor2aligneditor (SeqEditViewFormPtr wdp)
169 {
170    Enable (wdp->delitem);
171    Enable (wdp->conscolor);
172    Disable (wdp->importalg);
173    Enable (wdp->expfsagitem);
174    Enable (wdp->expalgitem);
175    Enable (wdp->expasnitem);
176 
177    Enable (wdp->menu_align);
178    Enable (wdp->selmaster);
179    Enable (wdp->selall);
180    Enable (wdp->selsubs);
181    Enable (wdp->showdifitem);
182    Enable (wdp->showallitem);
183    Enable (wdp->dotmat);
184    Enable (wdp->alreport);
185    Disable (wdp->tmpcdspitem);
186    Disable (wdp->tmpcdsnitem);
187 }
188 
aligneditor2seqeditor(SeqEditViewFormPtr wdp)189 static void aligneditor2seqeditor (SeqEditViewFormPtr wdp)
190 {
191    Disable (wdp->delitem);
192    Disable (wdp->conscolor);
193    Enable (wdp->importalg);
194    Disable (wdp->expfsagitem);
195    Disable (wdp->expalgitem);
196    Disable (wdp->expasnitem);
197 
198    Disable (wdp->menu_align);
199    Disable (wdp->selmaster);
200    Disable (wdp->selall);
201    Disable (wdp->selsubs);
202    Disable (wdp->showdifitem);
203    Disable (wdp->showallitem);
204    Disable (wdp->dotmat);
205    Disable (wdp->alreport);
206    Enable (wdp->tmpcdspitem);
207    Enable (wdp->tmpcdsnitem);
208 }
209 
editor2viewer(SeqEditViewFormPtr wdp)210 static void editor2viewer (SeqEditViewFormPtr wdp)
211 {
212   Disable (wdp->undoitem);
213   Disable (wdp->pasteitem);
214   Disable (wdp->cutitem);
215   Disable (wdp->copyitem);
216   Disable (wdp->viewmodeitem);
217   Enable  (wdp->editmodeitem);
218   Disable (wdp->insitem);
219 }
220 
viewer2editor(SeqEditViewFormPtr wdp)221 static void viewer2editor (SeqEditViewFormPtr wdp)
222 {
223   Int2 k;
224 
225   Enable (wdp->undoitem);
226   Enable (wdp->pasteitem);
227   Enable (wdp->viewmodeitem);
228   Enable (wdp->insitem);
229 
230   Disable(wdp->editmodeitem);
231 
232   k = checkOMss_for_itemtype (OBJ_BIOSEQ);
233   if (k > 0) {
234      Enable (wdp->cutitem);
235      Enable (wdp->copyitem);
236   }
237   else {
238      Disable (wdp->cutitem);
239      Disable (wdp->copyitem);
240   }
241 
242 }
243 
update_sequenceeditormenu(SeqEditViewFormPtr wdp,EditAlignDataPtr adp)244 static void update_sequenceeditormenu (SeqEditViewFormPtr wdp, EditAlignDataPtr adp)
245 {
246   ResetClip ();
247   if (adp->seqnumber == 1)
248      aligneditor2seqeditor (wdp);
249   else
250   {
251      seqeditor2aligneditor (wdp);
252      if (adp->charmode)
253         Disable (wdp->showdifitem);
254      else
255         Disable (wdp->showallitem);
256   }
257 
258   if (adp->edit_mode == SEQ_EDIT)
259      viewer2editor (wdp);
260   else
261      editor2viewer (wdp);
262 
263   if (ISA_na (adp->mol_type))
264   {
265      Enable (wdp->showfeatbt);
266      Enable (wdp->translatebt);
267      Disable (wdp->savefeatbt);
268      Enable (wdp->closebt);
269      Enable (wdp->svclosebt);
270   }
271 /***** TEMPO **/
272   Disable (wdp->conscolor);
273   if (ISA_aa (adp->mol_type))
274   {
275      Disable (wdp->alreport);
276      if (adp->edit_mode==SEQ_VIEW) {
277         Disable (wdp->viewmodeitem);
278         Disable (wdp->editmodeitem);
279      }
280   }
281  /*****************/
282 }
283 
284 /**************************************************
285 ***  AlignDataInit
286 ***************************************************/
AdpOptionsInit(EditAlignDataPtr adp,Int2 marginleft,Uint1 columnpcell,FonT font,Uint1 display_panel)287 static EditAlignDataPtr AdpOptionsInit (EditAlignDataPtr adp, Int2 marginleft, Uint1 columnpcell, FonT font, Uint1 display_panel)
288 {
289   Uint2  j;
290   Uint4  carColor;
291 
292   adp->marginleft = marginleft;
293   adp->intersalpwidth = 15;
294   adp->interline = 0;
295 
296   if (font == NULL) {
297 #ifdef WIN_MAC
298   font = ParseFont ("Monaco, 9");
299 #endif
300 #ifdef WIN_MSWIN
301   font = ParseFont ("Courier, 9");
302 #endif
303 #ifdef WIN_MOTIF
304   font = ParseFont ("fixed, 12");
305 #endif
306   }
307   adp->font = (Handle)(font);
308   SelectFont (font);
309   adp->charw   = CharWidth ('0');
310   adp->ascent  = Ascent ();
311   adp->leading = Leading ();
312   adp->lineheight   = LineHeight () + adp->interline + 1;
313   adp->scaleheight  = 2 * adp->lineheight;
314   adp->margin.left  = adp->marginleft * adp->charw;
315   adp->margin.right = EDIT_MARGIN_RIGHT;
316   adp->margin.bottom= EDIT_MARGIN_BOT;
317   SelectFont (systemFont);
318 
319   carColor = GetColorRGB(255, 255, 255);
320   for (j=0; j<256; j++) adp->colorRefs[j] = carColor;
321   adp->colorRefs[COLOR_SCALE] = GetColorRGB(255,0,255);
322   adp->colorRefs[COLOR_ID] = carColor;
323   adp->colorRefs[COLOR_ID_MASTER] = GetColorRGB(255, 128, 0);
324   adp->colorRefs[COLOR_CDS] = GetColorRGB(0, 255, 0);
325   adp->colorRefs[COLOR_SELECT] = GetColorRGB(0, 0, 0);
326   adp->colorRefs[COLOR_GAP] = GetColorRGB(0, 0, 0);
327   adp->colorRefs[COLOR_STAR] = GetColorRGB (255, 0, 0);
328 /*
329   adp->colorRefs[(Uint1) ('M' - '*')] = GetColorRGB (255, 128, 0);
330 */
331   adp->popcolor[0] = adp->popcolor[1] = adp->popcolor[2] = adp->popcolor[3] = 1;
332   adp->popcolor[4] = adp->popcolor[5] = 6;
333   adp->popcolor[6] = adp->popcolor[7] = 4;
334   adp->popcolor[8] = adp->popcolor[9] = 3;
335 
336   adp->marginwithindex = FALSE;
337   adp->marginwithpos = TRUE;
338   adp->marginwithIds = FALSE;
339   adp->marginwithfeatid = TRUE;
340   adp->marginwithgroup = FALSE;
341 
342   adp->styleNum = GetMuskCurrentSt();
343   adp->newstyle = NULL;
344   adp->showfeat = FALSE;
345   adp->drawrfp = adp->drawrfm = adp->drawcomplt = FALSE;
346 
347   adp->draw_scale = FALSE;
348   adp->draw_bars = FALSE;
349   adp->nscaleline = 0;
350   if ( adp->draw_scale ) adp->nscaleline ++;
351   if ( adp->draw_bars )  adp->nscaleline ++;
352   adp->columnpcell = columnpcell;
353   adp->rowpcell = 0;
354   adp->displaytype = TRUE;
355   adp->charmode = FALSE;
356   adp->edit_pos = -1;
357   adp->feat_pos = -1;
358   adp->click_feat = 0;
359   adp->clickwhat = 0;
360   adp->mouse_mode = 0;
361 
362   adp->align_format = SALSA_FASTA;
363 
364   adp->printid = 0;
365   adp->prot_mode = ALLPROTAA;
366   adp->stoptransl = 0;
367   adp->spliteditmode = FALSE;
368   adp->gap_choice = IGNORE_GAP_CHOICE;
369 
370   adp->edit_mode = SEQ_EDIT;
371   adp->display_panel = display_panel;
372   adp->all_sequences = FALSE;
373   adp->draw_emptyline = TRUE;
374   adp->tmpfile [0] = '\0';
375 
376   return adp;
377 }
378 
AdpFieldsInit(EditAlignDataPtr adp,Int2 width,Int2 height)379 static EditAlignDataPtr AdpFieldsInit (EditAlignDataPtr adp, Int2 width, Int2 height)
380 {
381   Int2         x, y;
382 
383   adp->seqnumber = 0;
384   adp->length = 0;
385   adp->seg_bioseq = FALSE;
386   adp->master.entityID = 0;
387   adp->master.itemID = 0;
388   adp->master.itemtype = 0;
389   adp->master.region = NULL;
390   adp->master.regiontype = 0;
391 
392   adp->seq_info = NULL;
393   adp->sqloc_list = NULL;
394   adp->bsqloc_list = NULL;
395   adp->size_labels = 15;
396 
397   adp->sap_align = NULL;
398   adp->sap_original = NULL;
399   adp->sap1_original= NULL;
400   adp->blocks = NULL;
401 
402   adp->dirty = FALSE;
403 
404   adp->anp_list = NULL;
405   adp->anp_graph = NULL;
406   MemSet((Pointer)(adp->featOrder), 0, (size_t)(FEATDEF_ANY*sizeof(Uint1)));
407   MemSet((Pointer)(adp->groupOrder),0, (size_t)(FEATDEF_ANY*sizeof(Uint1)));
408 
409   adp->voffset = 0;
410   adp->hoffset = 0;
411 
412   adp->pnlLine = height - adp->margin.bottom/adp->lineheight;
413   adp->pnlWidth= width - adp->margin.right/adp->charw;
414 
415   y = 0; x = 0;
416   if (adp->columnpcell > 0) {
417      y = (Int2) (adp->pnlWidth -adp->marginleft) / (Int2) adp->columnpcell;
418      x = (Int2) (adp->pnlWidth -adp->marginleft -y) % (Int2)(adp->columnpcell);
419      if (x == 9)
420         x = -1;
421   }
422   adp->visibleWidth  = (Int2) (adp->pnlWidth -adp->marginleft -y -x);
423 
424   adp->vscrollbar_mode = TRUE;
425   adp->vPage = adp->pnlLine - 1;
426   adp->hPage = adp->visibleWidth - 1;
427   adp->curalignline = 0;
428   adp->nlines = 0;
429   adp->numberalignline = 0;
430   adp->item_id = NULL;
431   adp->seqEntity_id = NULL;
432   adp->alignline = NULL;
433   adp->itemtype =NULL;
434   adp->itemsubtype =NULL;
435 
436   adp->gr.left = 0;
437   adp->gr.right = 0;
438 
439   adp->edit_item.entityID = 0;
440   adp->edit_item.itemID = 0;
441   adp->edit_item.itemtype = 0;
442   adp->firstssp = NULL;
443   adp->buffer = NULL;
444   adp->linebuff = NULL;
445   adp->buffertail = NULL;
446   adp->bufferlength= 0;
447   adp->minbufferlength= 0;
448   adp->bufferstart = 0;
449   adp->editbuffer  = TMP_EDITBUFFER;
450   adp->colonne = NULL;
451   adp->select_block = NULL;
452 
453   adp->caret.entityID= adp->master.entityID;
454   adp->caret.itemID = adp->master.itemID;
455   adp->caret.itemtype= adp->master.itemtype;
456   adp->caret.regiontype = 0;
457   adp->caret.region = NULL;
458   adp->caret_line= 0;
459   adp->feat_line= 0;
460   adp->caret_orig= 0;
461 
462   adp->params = NULL;
463 
464   adp->feat= NULL;
465   adp->seqfeat= NULL;
466   adp->nfeat= 0;
467 
468   adp->mol_type = Seq_mol_na;
469 
470   adp->current_pattern = NULL;
471   adp->match_pat = NULL;
472   adp->cur_pat = NULL;
473   adp->ngroup = 0;
474   adp->extra_data = NULL;
475   return adp;
476 }
477 
478 
EditAlignDataInit(SelStructPtr master,Int2 width,Int2 height,Int2 marginleft,Uint1 columnpcell,Handle font,Boolean size_pixel,Uint1 display_panel)479 static EditAlignDataPtr EditAlignDataInit (SelStructPtr master, Int2 width, Int2 height, Int2 marginleft, Uint1 columnpcell, Handle font, Boolean size_pixel, Uint1 display_panel)
480 {
481   EditAlignDataPtr adp;
482 
483   adp = (EditAlignDataPtr) MemNew (sizeof(EditAlignData));
484   AdpOptionsInit (adp, marginleft, columnpcell, (FonT)font, display_panel);
485   if (size_pixel)
486      adp =AdpFieldsInit(adp, width/adp->charw, height/adp->lineheight);
487   else
488      adp =AdpFieldsInit(adp, width, height);
489   return adp;
490 }
491 
492 /******************************
493 ***  Proc FreeEditAlignData
494 *******************************/
AdpFieldsFree(EditAlignDataPtr adp)495 static EditAlignDataPtr AdpFieldsFree (EditAlignDataPtr adp)
496 {
497   ValNodePtr       vnp;
498   SeqParamPtr      prm;
499 
500   FreeAlignNode (adp->anp_list);
501   adp->anp_list = NULL;
502   if (adp->anp_graph!=NULL)
503      FreeAlignNode (adp->anp_graph);
504   adp->anp_graph = NULL;
505 
506   adp->seq_info = SelEdStructListDel (adp->seq_info);
507   adp->sqloc_list = ValNodeFreeType (&(adp->sqloc_list), TypeSeqLoc);
508   adp->bsqloc_list = ValNodeFreeType (&(adp->bsqloc_list), TypeSeqLoc);
509 
510   adp->size_labels = 15;
511 
512   if (adp->master.region != NULL)
513         adp->master.region = SeqLocFree ((SeqLocPtr) adp->master.region);
514 
515   adp->sap_align = CompSeqAnnotFree (adp->sap_align);
516   adp->sap_original = NULL;
517   adp->sap1_original= NULL;
518   adp->blocks = NULL;
519 
520   adp->firstssp = NULL;
521   adp->lastses  = NULL;
522 
523   MemFree (adp->item_id);
524   MemFree (adp->seqEntity_id);
525   MemFree (adp->itemtype);
526   MemFree (adp->itemsubtype);
527   MemFree (adp->alignline);
528   adp->item_id=NULL;
529   adp->seqEntity_id=NULL;
530   adp->itemtype=NULL;
531   adp->itemsubtype=NULL;
532   adp->alignline=NULL;
533 
534   adp->buffer = BufferFree (adp->buffer);
535   adp->buffertail = NULL;
536 
537   adp->linebuff = FreeTextAlignList(adp->linebuff);
538   MemFree (adp->colonne);
539   adp->colonne = NULL;
540   adp->newstyle = NULL;
541 
542   adp->select_block = NULL;
543   if (adp->caret.region != NULL)
544         adp->caret.region = SeqLocFree ((SeqLocPtr) adp->caret.region);
545 
546   adp->feat = NULL;
547   adp->seqfeat = NULL;
548 
549   for (vnp = adp->params; vnp != NULL; vnp = vnp->next) {
550         prm = (SeqParamPtr) vnp->data.ptrvalue;
551         if (prm != NULL) MemFree (prm);
552         vnp->data.ptrvalue = NULL;
553   }
554   adp->params = ValNodeFree (adp->params);
555 
556   if (adp->current_pattern != NULL)
557      MemFree (adp->current_pattern);
558   adp->current_pattern = NULL;
559   if (adp->match_pat != NULL)
560      SelStructDelList (adp->match_pat);
561   adp->match_pat = NULL;
562   adp->cur_pat = NULL;
563 
564   adp->extra_data = NULL;
565   return adp;
566 }
567 
EditAlignDataFree(EditAlignDataPtr adp)568 static EditAlignDataPtr EditAlignDataFree (EditAlignDataPtr adp)
569 {
570   if (adp!=NULL) {
571      adp = AdpFieldsFree (adp);
572      MemFree (adp);
573      adp=NULL;
574   }
575   return NULL;
576 }
577 
578 /*********************************************************
579 ***
580 ***  ResizeAlignDataWindow:
581 ***            CallBack for DocumentWindow
582 **********************************************************/
ResizeAlignDataWindow(WindoW w)583 static void ResizeAlignDataWindow (WindoW w)
584 {
585   SeqEditViewFormPtr wdp;
586   EditAlignDataPtr   adp;
587   WindoW             temport;
588 
589   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
590   if (wdp == NULL) return;
591   temport = SavePort(w);
592   Select (wdp->pnl);
593   GetPanelExtra (wdp->pnl, &adp);
594   if ( adp == NULL ) return;
595   do_resize_window (wdp->pnl, adp, FALSE);
596   inval_panel (wdp->pnl, -1, -1);
597   RestorePort (temport);
598   Update ();
599   return;
600 }
601 
602 /*********************************************************
603 ***
604 ***   RESET FUNCTIONS
605 ***    update sequence length
606 ***
607 **********************************************************/
608 typedef struct updatesegstruc {
609   BioseqSetPtr      parts;
610   BioseqPtr         segseq;
611   BioseqSetPtr      segset;
612 } UpdateSegStruc, PNTR UpdateSegStrucPtr;
613 
AddBspToSegSet(BioseqPtr segseq,BioseqPtr bsp)614 static void AddBspToSegSet (BioseqPtr segseq, BioseqPtr bsp)
615 
616 {
617   SeqIdPtr   sip;
618   SeqLocPtr  slp;
619 
620   if (segseq == NULL) return;
621   slp = ValNodeNew ((ValNodePtr) segseq->seq_ext);
622   if (slp == NULL) return;
623   if (segseq->seq_ext == NULL) {
624     segseq->seq_ext = (Pointer) slp;
625   }
626   if (bsp != NULL && bsp->length > 0) {
627     segseq->length += bsp->length;
628     slp->choice = SEQLOC_WHOLE;
629     sip = SeqIdFindBest (bsp->id, 0);
630     slp->data.ptrvalue = (Pointer) SeqIdDup (sip);
631   } else {
632     slp->choice = SEQLOC_NULL;
633   }
634 }
635 
636 
DoUpdateSegSet(BioseqPtr segseq,BioseqSetPtr parts)637 static void DoUpdateSegSet (BioseqPtr segseq, BioseqSetPtr parts)
638 
639 {
640   BioseqPtr    bsp;
641   Boolean      notFirst;
642   Boolean      nullsBetween;
643   SeqFeatPtr   sfp;
644   SeqFeatPtr   sfpnext;
645   SeqLocPtr    slp;
646   SeqEntryPtr  tmp;
647 
648   if (segseq == NULL || parts == NULL || parts->seq_set == NULL) return;
649   tmp = parts->seq_set;
650   notFirst = FALSE;
651   nullsBetween = FALSE;
652   segseq->length = 0;
653   switch (segseq->seq_ext_type) {
654     case 1:    /* seg-ext */
655       slp = (ValNodePtr) segseq->seq_ext;
656       while (slp != NULL) {
657         if (slp->choice == SEQLOC_NULL) {
658           nullsBetween = TRUE;
659         }
660         slp = slp->next;
661       }
662       SeqLocSetFree ((ValNodePtr) segseq->seq_ext);
663       break;
664     case 2:   /* reference */
665       SeqLocFree ((ValNodePtr) segseq->seq_ext);
666       break;
667     case 3:   /* map */
668       sfp = (SeqFeatPtr) segseq->seq_ext;
669       while (sfp != NULL) {
670         sfpnext = sfp->next;
671         SeqFeatFree (sfp);
672         sfp = sfpnext;
673       }
674       break;
675     default:
676       break;
677   }
678   segseq->seq_ext = NULL;
679   while (tmp != NULL) {
680     if (nullsBetween && notFirst) {
681       AddBspToSegSet (segseq, NULL);
682     }
683     bsp = (BioseqPtr) tmp->data.ptrvalue;
684     if (bsp != NULL) {
685       AddBspToSegSet (segseq, bsp);
686     }
687     notFirst = TRUE;
688     tmp = tmp->next;
689   }
690 }
691 
692 
FindSegSetComponentsCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)693 static void FindSegSetComponentsCallback (SeqEntryPtr sep, Pointer mydata,
694                                           Int4 index, Int2 indent)
695 
696 {
697   BioseqPtr          bsp;
698   BioseqSetPtr       bssp;
699   UpdateSegStrucPtr  ussp;
700 
701   if (sep != NULL && sep->data.ptrvalue && mydata != NULL) {
702     ussp = (UpdateSegStrucPtr) mydata;
703     if (IS_Bioseq(sep)) {
704       bsp = (BioseqPtr) sep->data.ptrvalue;
705       if (ISA_na (bsp->mol)) {
706         ussp->segseq = bsp;
707       }
708     } else if (IS_Bioseq_set(sep)) {
709       bssp = (BioseqSetPtr) sep->data.ptrvalue;
710       if (bssp->_class == 2) {
711         ussp->segset = bssp;
712       } else if (bssp->_class == 4) {
713         ussp->parts = bssp;
714       }
715     }
716   }
717 }
718 
UpdateSegList(SeqEntryPtr sep,Pointer mydata,SeqEntryFunc mycallback,Int4 index,Int2 indent)719 static Int4 UpdateSegList (SeqEntryPtr sep, Pointer mydata,
720                            SeqEntryFunc mycallback,
721                            Int4 index, Int2 indent)
722 
723 {
724   BioseqSetPtr  bssp;
725 
726   if (sep == NULL) return index;
727   if (mycallback != NULL)
728     (*mycallback) (sep, mydata, index, indent);
729   index++;
730   if (IS_Bioseq (sep)) return index;
731   if (Bioseq_set_class (sep) == 4) return index;
732   bssp = (BioseqSetPtr) sep->data.ptrvalue;
733   sep = bssp->seq_set;
734   indent++;
735   while (sep != NULL) {
736     index = UpdateSegList (sep, mydata, mycallback, index, indent);
737     sep = sep->next;
738   }
739   return index;
740 }
741 
742 #define UpdateSegExplore(a,b,c) UpdateSegList(a, b, c, 0L, 0);
743 
EditAlignDataChangeLength(EditAlignDataPtr adp,Int4 cutlength,SelStructPtr ssp)744 static EditAlignDataPtr EditAlignDataChangeLength (EditAlignDataPtr adp, Int4 cutlength, SelStructPtr ssp)
745 {
746   SeqLocPtr    slp_master;
747   SeqIntPtr    sit_master;
748   DenseSegPtr  dsp;
749   SeqAnnotPtr  sap;
750   SeqAlignPtr  salp;
751   SeqEntryPtr  sep;
752   UpdateSegStruc  uss;
753   Int4         start;
754 
755   adp->length -= cutlength;
756 
757   sap = SeqAnnotBoolSegToDenseSeg (adp->sap_align);
758   salp = (SeqAlignPtr) sap->data;
759   dsp = (DenseSegPtr) salp->segs;
760   *(dsp->lens) -= cutlength;
761   CompSeqAnnotFree (adp->sap_align);
762   adp->sap_align = SeqAnnotDenseSegToBoolSeg (sap);
763 
764   adp->sqloc_list = ValNodeFreeType (&(adp->sqloc_list), TypeSeqLoc);
765   adp->bsqloc_list= ValNodeFreeType (&(adp->bsqloc_list), TypeSeqLoc);
766   adp->sqloc_list = SeqLocListFromSeqAlign (salp);
767   adp->bsqloc_list = SeqLocListOfBioseqsFromSeqAlign (salp);
768 
769   slp_master = (SeqLocPtr) adp->master.region;
770   sit_master = (SeqIntPtr) slp_master->data.ptrvalue;
771   sit_master->to -= cutlength;
772 
773   FreeAlignNode(adp->anp_list);
774   if (adp->display_panel==0 || adp->display_panel==1 || adp->display_panel==2)
775   {
776      adp->anp_list = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr) adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MD, FALSE, FALSE, FALSE);
777   }
778   else if (adp->display_panel == 3) {
779      adp->anp_list = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr) adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MP, TRUE, FALSE, FALSE);
780   }
781   if (adp->display_panel==2) {
782      adp->anp_graph = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr)adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MP, TRUE, FALSE, FALSE);
783   }
784   sap = SeqAnnotFree (sap);
785   clean_annot_for_anp(&(adp->anp_list));
786   OrderFeatProc (adp->anp_list);
787 
788   start = SeqLocStart((SeqLocPtr)ssp->region);
789   setposition_tossp (&(adp->caret), start, start);
790   adp->caret_orig = start;
791   adp->feat = update_featpept (adp, adp->feat, NULL, ssp, (-cutlength), 255);
792   adp->seqfeat=update_featpept (adp, adp->seqfeat,NULL,ssp,(-cutlength), 255);
793 
794   adp->bufferlength = MIN((Int4)(adp->length),(Int4) adp->minbufferlength);
795   if (abs((adp->bufferstart +adp->bufferlength)-adp->length) < 100)
796                adp->bufferlength = adp->length - adp->bufferstart;
797 
798   if ( adp->seg_bioseq ) {
799      sep = GetBestTopParentForItemID (adp->master.entityID, adp->master.itemID, adp->master.itemtype);
800      uss.segseq = NULL;
801      uss.parts = NULL;
802      uss.segset = NULL;
803      UpdateSegExplore (sep, (Pointer) &uss, FindSegSetComponentsCallback);
804      if (uss.segseq != NULL && uss.parts != NULL && uss.segset != NULL) {
805         DoUpdateSegSet (uss.segseq, uss.parts);
806      }
807   }
808   if (adp->current_pattern != NULL)
809      MemFree (adp->current_pattern);
810   adp->current_pattern = NULL;
811   return adp;
812 }
813 
reset_features(PaneL pnl,EditAlignDataPtr adp)814 static void reset_features (PaneL pnl, EditAlignDataPtr adp)
815 {
816  if (adp->showfeat) {
817     Select (pnl);
818     HideFeatureFunc (adp);
819     adp->showfeat = FALSE;
820     ShowFeatureProc (pnl, TRUE);
821  }
822 }
823 
reset_features_afterlengthchange(PaneL pnl,EditAlignDataPtr adp)824 static void reset_features_afterlengthchange(PaneL pnl, EditAlignDataPtr adp) {
825   reset_features (pnl, adp);
826 }
827 
update_select_region(SelStructPtr ommsp,PaneL pnl,EditAlignDataPtr adp,Boolean update_caret)828 static void update_select_region (SelStructPtr ommsp, PaneL pnl, EditAlignDataPtr adp, Boolean update_caret)
829 {
830   SeqAlignPtr salp;
831   SeqIdPtr    sip;
832   SeqLocPtr   slp;
833   RecT        rp;
834   Int4        from, to;
835   Int4        froms, tos;
836   Int4        minp, maxp;
837   Int2        chklocp, chklocp2;
838   float hratio;
839 
840   get_client_rect (pnl, &rp);
841   salp = (SeqAlignPtr) adp->sap_align->data;
842   slp = (SeqLocPtr) ommsp->region;
843   sip = SeqLocId (slp);
844   chklocp = chkloc (sip, SeqLocStart (slp), adp->sqloc_list, &froms);
845   from = SeqCoordToAlignCoord (froms, sip, salp, 0, chklocp);
846   chklocp2 = chkloc (sip, SeqLocStop (slp), adp->sqloc_list, &tos);
847   to = SeqCoordToAlignCoord (tos, sip, salp, 0, chklocp2);
848 
849   if(chklocp>-1 && chklocp2>-1) {
850      if (to < adp->hoffset || from > adp->hoffset+ adp->visibleLength)
851      {
852         adp->voffset = hoffset2voffset(adp, adp->anp_list, adp->visibleWidth, 0, adp->length-1, from);
853         ResetClip ();
854         data_collect_arrange (adp, TRUE);
855         hratio = (float)MAX((Int4)(from-50), (Int4)0) / (float)adp->length;
856         SeqEdSetCorrectBarMax (pnl, adp, hratio);
857      }
858   }
859   if (update_caret && (from != SeqLocStart((SeqLocPtr)adp->caret.region))) {
860      locate_region (&(adp->caret), from, to, sip, Seq_strand_plus, FALSE);
861   }
862   if (!adp->display_panel) {
863      if (update_caret) {
864         if (chklocp2==APPEND_RESIDUE)
865            slp = SeqLocIntNew (froms, tos-1, 0, sip);
866         else
867            slp = SeqLocIntNew (froms, tos, 0, sip);
868 /************* BEFORE = REPLACE to do*****/
869         ommsp->region = slp;
870         to_update_prompt (pnl, ommsp, NULL, NULL, TRUE, adp->printid);
871      }
872      else {
873         to_update_prompt (pnl, &(adp->caret), NULL, NULL, TRUE, adp->printid);
874      }
875      update_edititem (pnl);
876   }
877   minp = MIN (from, to)-2;
878   maxp = MAX (from, to)+2;
879   inval_selstructloc (adp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, 255, &rp, minp, maxp);
880   return;
881 }
882 
883 
update_length(PaneL pnl,EditAlignDataPtr adp,Int4 cutlength)884 static EditAlignDataPtr update_length (PaneL pnl, EditAlignDataPtr adp, Int4 cutlength)
885 {
886   SelStructPtr     ssp;
887   RecT             rp;
888   SeqLocPtr        slp;
889   ValNodePtr       vnp;
890   AlignNodePtr     anp;
891   SeqAlignPtr      salp;
892   Int4             from,
893                    to,
894                    select_length;
895   Boolean          localssp=FALSE;
896   float hratio;
897 
898   if (adp!=NULL && cutlength != 0)
899   {
900      get_client_rect (pnl, &rp);
901      slp = (SeqLocPtr)(adp->caret.region);
902      ssp = getOMselect_for_itemtype (OBJ_BIOSEQ);
903      if (ssp == NULL) {
904         localssp = TRUE;
905         from = adp->caret_orig - cutlength;
906         to = adp->caret_orig;
907         for (vnp = adp->anp_list; vnp != NULL; vnp = vnp->next) {
908            anp = (AlignNodePtr) vnp->data.ptrvalue;
909            if (SeqIdForSameBioseq(anp->sip, SeqLocId(slp)))
910                break;
911         }
912         ssp = SelStructNew (anp->seq_entityID, anp->bsp_itemID, OBJ_BIOSEQ, from, to, anp->sip, Seq_strand_plus, FALSE);
913      }
914      else {
915         select_length = SeqLocStop((SeqLocPtr)ssp->region) - SeqLocStart((SeqLocPtr)ssp->region) +1;
916         if (select_length != cutlength) {
917            ErrPostEx (SEV_ERROR, 0, 0, "Selected region differs from deleted sequence's length");
918            return adp;
919         }
920      }
921      adp = EditAlignDataChangeLength (adp, cutlength, ssp);
922      if (localssp)
923         SelStructDel (ssp);
924      salp = (SeqAlignPtr) adp->sap_align->data;
925      if (!adp->display_panel)
926         to_update_prompt (pnl, &(adp->caret), salp, adp->sqloc_list, FALSE, adp->printid);
927      data_collect_arrange (adp, TRUE);
928      hratio = (float)adp->hoffset / (float)adp->length;
929      SeqEdSetCorrectBarMax (pnl, adp, hratio);
930   }
931   return adp;
932 }
933 
934 
create_list_alignedsegs(SeqAlignPtr salp)935 static SeqAlignPtr create_list_alignedsegs (SeqAlignPtr salp)
936 {
937   SeqAlignPtr   salp2 = NULL;
938   DenseDiagPtr  ddp ,
939                 ddphead=NULL;
940   SeqIdPtr      sip = NULL,
941                 siphead = NULL;
942   BioseqPtr     bsp;
943   Int2Ptr       tab;
944   Int4Ptr       startp;
945   Int4          start,
946                 from = -1,
947                 lens,
948                 lensmax;
949   Int4          k;
950   Int2          dim = 0;
951 
952   if (salp!=NULL)
953   {
954      if (salp->segtype == 1)
955      {
956         ddp = (DenseDiagPtr) salp->segs;
957         if (ddp!=NULL)
958            sip = ddp->id;
959      }
960   }
961   if (sip != NULL) {
962      bsp = BioseqLockById (sip);
963      if (bsp!=NULL) {
964         lensmax = bsp->length;
965         BioseqUnlock (bsp);
966         tab =  (Int2Ptr)MemNew ((size_t)((lensmax +4)*sizeof(Int2)));
967         for (k=0; k<lensmax; k++)
968            tab[k]=1;
969         siphead = AddSeqId (&siphead, sip);
970         dim = 1;
971         for (salp2=salp; salp2!=NULL; salp2=salp2->next)
972         {
973          if (salp2->type > 0)
974          {
975            ddp = (DenseDiagPtr) salp2->segs;
976            for (; ddp!=NULL; ddp=ddp->next)
977            {
978               startp = ddp->starts;
979               lens=(Int4)ddp->len;
980               for (k=*startp; k<*startp+lens && k<lensmax; k++)
981               {
982                  tab[k]++;
983               }
984               if (from<0)
985                  from = *startp;
986               siphead = AddSeqId (&siphead, ddp->id->next);
987            }
988            dim++;
989          }
990         }
991         k=0;
992         while (k<lensmax)
993         {
994            if (tab[k] == dim)
995            {
996               start = k;
997               k++;
998               while (k<lensmax && tab[k] == dim)
999                  k++;
1000               lens = k-start;
1001               ddp = DenseDiagCreate (dim, siphead, &start, lens, NULL, NULL);
1002               DenseDiagLink (&ddphead, ddp);
1003            }
1004            k++;
1005         }
1006         MemFree (tab);
1007      }
1008   }
1009   salp2 = NULL;
1010   if (ddphead != NULL)
1011   {
1012      salp2 = SeqAlignNew ();
1013      salp2->type = 3;
1014      salp2->segtype = 1; /*COMPSEG;*/
1015      salp2->dim = 2;
1016      salp2->segs = (Pointer) ddphead;
1017   }
1018   return salp2;
1019 }
1020 /*********************************************************
1021 ***
1022 ***   RESET FUNCTIONS
1023 ***     Reset data structure
1024 ***
1025 **********************************************************/
EditAlignDataReset(EditAlignDataPtr adp,Int2 width,Int2 height,SeqAlignPtr salp)1026 static EditAlignDataPtr EditAlignDataReset (EditAlignDataPtr adp, Int2 width, Int2 height, SeqAlignPtr salp)
1027 {
1028   SeqAlignPtr  newsalp;
1029   SeqIdPtr     mastersip;
1030   SeqAlignPtr  blocks = NULL;
1031   SeqAnnotPtr  sap = NULL;
1032 
1033   if (salp != NULL) {
1034      newsalp = salp;
1035   } else {
1036      newsalp = SeqAlignBoolSegToDenseSeg ((SeqAlignPtr)adp->sap_align->data);
1037   }
1038   if (newsalp == NULL)
1039      return adp;
1040 
1041   mastersip =SeqIdDup (SeqIdFindBest(SeqLocId((SeqLocPtr)adp->master.region), 0));
1042 /*if (adp->blocks!=NULL) {  */  /* yanli comment out, 7/19/1999 */
1043   if (adp->blocks!=NULL || adp->blocks == NULL) {
1044          /* no matter blocks exists or not previously, yanli, 7/19/1999 */
1045 /**
1046      SeqAlignSetFree (adp->blocks);
1047 **/
1048      adp->blocks=NULL;
1049      if (adp->sap1_original)
1050         blocks=create_list_alignedsegs ((SeqAlignPtr)adp->sap1_original->data);
1051 
1052   }
1053   if (adp->sap1_original)
1054   {
1055      sap = adp->sap1_original;
1056      adp->sap1_original=NULL;
1057   }
1058   adp = AdpFieldsFree (adp);
1059   adp = AdpFieldsInit (adp, width, height);
1060   adp = SeqAlignToEditAlignData (adp, newsalp, adp->hoffset, mastersip, (Uint1)(adp->showfeat));
1061   if (adp && blocks) {
1062 /*   adp->sap1_original=sap;  */
1063                     /* yanli comment out, 7/19/1999 */
1064      adp->blocks = blocks;
1065   }
1066   if(adp && sap) adp->sap1_original=sap;  /* yanli added, 7/19/1999 */
1067 
1068   return adp;
1069 }
1070 
1071 /******************************************
1072 ***
1073 ***  MESSAGE FUNCTIONS
1074 ***
1075 ***  SalsaFormMessage
1076 ***       sends update message when the windows is closed
1077 ***
1078 ***  BioseqEditMsgFunc
1079 ***       picks up update messages
1080 ***       if itemtype is OBJ_SEQFEAT: recollect data structure
1081 ***
1082 *******************************************/
SalsaFormMessage(ForM f,Int2 mssg)1083 static void SalsaFormMessage (ForM f, Int2 mssg)
1084 {
1085   SeqEditViewFormPtr  wdp;
1086 
1087   wdp = (SeqEditViewFormPtr) GetObjectExtra (f);
1088   if (wdp != NULL) {
1089     switch (mssg) {
1090       case VIB_MSG_CLOSE :
1091         Beep ();
1092         break;
1093       default :
1094         if (wdp->appmessage != NULL) {
1095           wdp->appmessage (f, mssg);
1096         }
1097         break;
1098     }
1099   }
1100 }
1101 
1102 /*************************************************************
1103 **************************************************************/
BioseqEditMsgFunc(OMMsgStructPtr ommsp)1104 static Int2 LIBCALLBACK BioseqEditMsgFunc (OMMsgStructPtr ommsp)
1105 {
1106   WindoW             currentport,
1107                      temport;
1108   OMUserDataPtr      omudp;
1109   SeqEditViewFormPtr wdp = NULL;
1110   EditAlignDataPtr   adp;
1111   SeqAlignPtr        salp,
1112                      newsalp = NULL;
1113   SeqAnnotPtr        sap = NULL;
1114   SelStructPtr       ssptmp;
1115   ValNodePtr         vnp;
1116   SeqLocPtr          slp;
1117   BioseqPtr          bsp;
1118   SeqIdPtr           sip;
1119   Int4               cutlength,
1120                      from=0,
1121                      to = 0;
1122   Int2               width;
1123   Int2               chklocp;
1124   RecT               rp;
1125   Boolean            ok;
1126   float hratio;
1127 
1128   SeqEditViewProcsPtr svpp;
1129 
1130   omudp = (OMUserDataPtr)(ommsp->omuserdata);
1131   if (omudp == NULL) return OM_MSG_RET_ERROR;
1132   wdp = (SeqEditViewFormPtr) omudp->userdata.ptrvalue;
1133   if (wdp == NULL) return OM_MSG_RET_ERROR;
1134   if ( ( adp = GetAlignDataPanel (wdp->pnl) ) == NULL )
1135          return OM_MSG_RET_ERROR;
1136   if ( adp->seqnumber == 0 )
1137          return OM_MSG_RET_ERROR;
1138 
1139   currentport = ParentWindow (wdp->pnl);
1140   temport = SavePort (currentport);
1141   UseWindow (currentport);
1142   Select (wdp->pnl);
1143   get_client_rect (wdp->pnl, &rp);
1144   width = adp->visibleWidth;
1145   if (adp->columnpcell > 0)
1146      width += (Int2) adp->visibleWidth / (Int2) adp->columnpcell;
1147   salp = (SeqAlignPtr) adp->sap_align->data;
1148   switch (ommsp->message)
1149   {
1150       case OM_MSG_UPDATE:
1151           if (! Visible (ParentWindow (wdp->pnl))) return OM_MSG_RET_OK;
1152           cutlength = 0;
1153           for (vnp=adp->bsqloc_list; vnp!=NULL; vnp=vnp->next)
1154           {
1155              slp = (SeqLocPtr) vnp->data.ptrvalue;
1156              bsp = BioseqLockById (SeqLocId(slp));
1157              if (bsp != NULL) {
1158                 cutlength = (Int4) SeqLocLen (slp) - bsp->length;
1159                 BioseqUnlock (bsp);
1160                 if (cutlength !=  0) break;
1161              }
1162           }
1163           if (cutlength != 0 && adp->input_format == OBJ_BIOSEQ)
1164           {
1165              update_length (wdp->pnl, adp, cutlength);
1166           }
1167           if (cutlength != 0 && adp->input_format == OBJ_SEQALIGN)
1168           {
1169              adp = EditAlignDataReset (adp, (rp.right-rp.left), (rp.bottom-rp.top), NULL);
1170              if (adp == NULL) {
1171                 return  OM_MSG_RET_ERROR;
1172              }
1173              do_resize_window (wdp->pnl, adp, TRUE);
1174           }
1175           if (cutlength!=0 && (adp->input_format==OBJ_BIOSEQ || adp->input_format==OBJ_SEQALIGN))
1176           {
1177              Select (wdp->pnl);
1178              reset_features_afterlengthchange (wdp->pnl, adp);
1179              if (cutlength < 0)
1180                 inval_selstructpos_tobottom(adp, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype, &rp, adp->edit_pos);
1181              else if (cutlength > 0 && adp->caret.region!=NULL) {
1182                 inval_selstructpos_tobottom(adp, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype, &rp, SeqLocStart((SeqLocPtr)adp->caret.region));
1183              }
1184              else
1185                 inval_panel (wdp->pnl, -1, -1);
1186              adp->edit_pos = SeqLocStart((SeqLocPtr)adp->caret.region);
1187           }
1188           if (cutlength == 0 && ommsp->itemtype == OBJ_BIOSEQ)
1189           {
1190              if (adp->input_format == OBJ_BIOSEQ)
1191              {
1192                 if (ommsp->regiontype == OM_REGION_SEQLOC)
1193                 {
1194                    sip = SeqLocId ((SeqLocPtr) ommsp->region);
1195                    from = SeqLocStart ((SeqLocPtr) ommsp->region);
1196                    from = SeqCoordToAlignCoord(from, sip, salp, 0, 0);
1197                    to = SeqLocStop ((SeqLocPtr) ommsp->region);
1198                    chklocp =chkloc(sip, to, adp->sqloc_list, &to);
1199                    to = SeqCoordToAlignCoord(to, sip, salp, 0, chklocp);
1200                    inval_selstructloc (adp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, 255, &rp, from, to);
1201                 }
1202                 else {
1203                     if (adp->curfeat != NULL) {
1204                        adp->feat = del_ssp_fromid (adp->feat, (Uint2) SEQFEAT_CDREGION, adp->curfeat);
1205                        adp->curfeat = NULL;
1206                     }
1207                     reset_features (wdp->pnl, adp);
1208                 }
1209              }
1210              else if (adp->input_format == OBJ_SEQALIGN) {
1211                 repopulate_panel (currentport, adp, (SeqAlignPtr)adp->sap_original->data);
1212              }
1213           }
1214           else if (cutlength == 0 && ommsp->itemtype == OBJ_VIRT)
1215           {
1216              data_collect_arrange (adp, TRUE);
1217              hratio = (float)adp->hoffset / (float)adp->length;
1218              SeqEdSetCorrectBarMax (wdp->pnl, adp, hratio);
1219              reset_features (wdp->pnl, adp);
1220              inval_panel (wdp->pnl, -1, -1);
1221           }
1222           else if (cutlength == 0)
1223           {
1224 /********
1225 Sequin send ommsp->itemtype==0 when update features
1226 *********/
1227              reset_features (wdp->pnl, adp);
1228              inval_panel (wdp->pnl, -1, -1);
1229           }
1230           break;
1231       case OM_MSG_SETCOLOR:
1232           if (ommsp->itemtype == OBJ_BIOSEQ)
1233           {
1234              svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
1235              if (svpp)
1236                 adp->colorRefs[COLOR_SELECT] = GetColorRGB(svpp->colorR_HL,svpp->colorG_HL,svpp->colorB_HL);
1237 
1238              inval_panel (wdp->pnl, -1, -1);
1239           }
1240           break;
1241       case OM_MSG_DESELECT:
1242           if (ommsp->itemtype == OBJ_BIOSEQ)
1243           {
1244              if (ommsp->regiontype == OM_REGION_SEQLOC) {
1245                 if (is_seqvisible(ommsp->entityID, ommsp->itemID, adp->seq_info))
1246                 {
1247                    slp = (SeqLocPtr)ommsp->region;
1248                    ssptmp = SelStructNew (ommsp->entityID, ommsp->itemID, ommsp->itemtype, SeqLocStart (slp)+1, SeqLocStop (slp), SeqLocId (slp), SeqLocStrand(slp), FALSE);
1249                    update_select_region (ssptmp, wdp->pnl, adp, FALSE);
1250                    SelStructDel (ssptmp);
1251 /************
1252                    sip = SeqLocId ((SeqLocPtr) ommsp->region);
1253                    from = SeqLocStart ((SeqLocPtr) ommsp->region);
1254                    from = SeqCoordToAlignCoord(from, sip, salp, 0, 0);
1255                    to = SeqLocStop ((SeqLocPtr) ommsp->region);
1256                    chklocp =chkloc(sip, to, adp->sqloc_list, &to);
1257                    to = SeqCoordToAlignCoord(to, sip, salp, 0, chklocp);
1258                    inval_selstructloc (adp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, 255, &rp, from, to);
1259                    if ( adp->caret.regiontype == OM_REGION_SEQLOC ) {
1260                       from = SeqLocStart ((SeqLocPtr)adp->caret.region);
1261                       if (from != SeqLocStop((SeqLocPtr)adp->caret.region)) {
1262                          setposition_tossp (&(adp->caret), from, from);
1263                       }
1264                    }
1265 ***************/
1266                    if (!adp->display_panel)
1267                       to_update_prompt (wdp->pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
1268                    if (adp->caret.entityID!=ommsp->entityID && adp->caret.itemID!=ommsp->itemID) {
1269                       inval_selstructpos(adp,adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype, &rp, from);
1270                    }
1271                 }
1272              }
1273           }
1274           else if (ommsp->itemtype == OBJ_SEQFEAT)
1275           {
1276              if (ommsp->regiontype == OM_REGION_SEQLOC) {
1277                 sip = SeqLocId ((SeqLocPtr) ommsp->region);
1278                 from = SeqLocStart ((SeqLocPtr) ommsp->region);
1279                 from = SeqCoordToAlignCoord(from, sip, salp, 0, 0);
1280                 to = SeqLocStop ((SeqLocPtr) ommsp->region);
1281                 chklocp =chkloc(sip, to, adp->sqloc_list, &to);
1282                 to = SeqCoordToAlignCoord(to, sip, salp, 0, chklocp);
1283                 inval_selstructloc_forfeat (adp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, 255, &rp, from, to);
1284              }
1285           }
1286           break;
1287 
1288       case OM_MSG_SELECT:
1289           if (ommsp->itemtype == OBJ_BIOSEQ)
1290           {
1291              if (ommsp->regiontype == OM_REGION_SEQLOC) {
1292                 if(is_seqvisible(ommsp->entityID, ommsp->itemID, adp->seq_info))
1293                 {
1294                    slp = (SeqLocPtr)ommsp->region;
1295                    ssptmp = SelStructNew (ommsp->entityID, ommsp->itemID, ommsp->itemtype, SeqLocStart (slp), SeqLocStop (slp), SeqLocId (slp), SeqLocStrand(slp), FALSE);
1296                    update_select_region (ssptmp, wdp->pnl, adp, FALSE);
1297                    SelStructDel (ssptmp);
1298                 }
1299              }
1300              else  {
1301                 ssptmp=is_selectedbyID (ommsp->entityID, ommsp->itemID, ommsp->itemtype);
1302                 if ( ssptmp != NULL )
1303                 {
1304                    if (is_seqvisible(ommsp->entityID, ommsp->itemID, adp->seq_info))
1305                    {
1306                       slp = (SeqLocPtr)ssptmp->region;
1307                       update_select_region (ssptmp, wdp->pnl, adp, FALSE);
1308                    }
1309                    else
1310                       inval_selstruct (adp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, 255, &rp, adp->margin.left,(Int2)(width *adp->charw));
1311                 }
1312              }
1313           }
1314           if (ommsp->itemtype == OBJ_SEQFEAT)
1315           {
1316            if ( adp->showfeat && adp->seqfeat!=NULL )
1317            {
1318              if (ommsp->region == NULL) {
1319                 ommsp->region = checkseqlocfeature_for_editor (ommsp->entityID, ommsp->itemID, adp->seqfeat);
1320                 if (ommsp->region != NULL) {
1321                    ommsp->regiontype = OM_REGION_SEQLOC;
1322                    checkselectsequinfeature_for_editor (adp->seqfeat);
1323                 }
1324              }
1325              if (ommsp->regiontype == OM_REGION_SEQLOC)
1326              {
1327                 sip = SeqLocId ((SeqLocPtr) ommsp->region);
1328                 from = SeqLocStart ((SeqLocPtr) ommsp->region);
1329                 from = SeqCoordToAlignCoord(from, sip, salp, 0, 0);
1330                 to = SeqLocStop ((SeqLocPtr) ommsp->region);
1331                 chklocp =chkloc(sip, to, adp->sqloc_list, &to);
1332                 to = SeqCoordToAlignCoord(to, sip, salp, 0, chklocp);
1333 /*
1334                 if(to < adp->hoffset || from > adp->hoffset+ adp->visibleLength)
1335                 {
1336                    adp->voffset = (Int2)(from/(adp->visibleWidth));
1337                    ResetClip ();
1338                    data_collect_arrange (adp, TRUE);
1339                    hratio = (float)adp->hoffset / (float)adp->length;
1340                    SeqEdSetCorrectBarMax (wdp->pnl, adp, hratio);
1341                 }
1342 */
1343                 inval_selstructloc_forfeat (adp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, 255, &rp, from, to);
1344              } else {
1345                 inval_selstruct (adp, ommsp->entityID, ommsp->itemID, ommsp->itemtype, 255, &rp, adp->margin.left,(Int2)(width *adp->charw));
1346              }
1347            }
1348            else {
1349              inval_panel (wdp->pnl, -1, -1);
1350            }
1351           }
1352           break;
1353       case OM_MSG_DEL:
1354           break;
1355       case OM_MSG_HIDE:
1356           bsp = GetBioseqGivenIDs (ommsp->entityID, ommsp->itemID, ommsp->itemtype);
1357           if (bsp)
1358           {
1359              sap = adp->sap_original;
1360              if (sap)
1361              {
1362                 newsalp = (SeqAlignPtr)sap->data;
1363                 ok = SeqAlignIDCache (newsalp, SeqIdFindBest (bsp->id, 0));
1364                 if (ok)
1365                 {
1366                    if (adp->sap1_original)
1367                       SeqAlignIDCache ((SeqAlignPtr)adp->sap1_original->data, SeqIdFindBest (bsp->id, 0));
1368                    set_seqnot_visible (ommsp->entityID, ommsp->itemID, adp->seq_info);
1369                    repopulate_panel (currentport, adp, newsalp);
1370                 }
1371              }
1372           }
1373           break;
1374       case OM_MSG_SHOW:
1375           bsp = GetBioseqGivenIDs (ommsp->entityID, ommsp->itemID, ommsp->itemtype);
1376           if (bsp)
1377           {
1378              sap = adp->sap_original;
1379              if (sap)
1380              {
1381                 newsalp = (SeqAlignPtr)sap->data;
1382                 newsalp=SeqAlignIDUncache (newsalp, SeqIdFindBest (bsp->id, 0));
1383                 if (newsalp)
1384                 {
1385                    if (adp->sap1_original)
1386                       SeqAlignIDUncache ((SeqAlignPtr)adp->sap1_original->data, SeqIdFindBest (bsp->id, 0));
1387                    set_seqvisible (ommsp->entityID, ommsp->itemID, adp->seq_info);
1388                    repopulate_panel (currentport, adp, newsalp);
1389                 }
1390              }
1391           }
1392           break;
1393       case OM_MSG_FLUSH:
1394           CloseWindowProc (wdp->pnl);
1395           break;
1396       default:
1397           break;
1398   }
1399   RestorePort (temport);
1400   UseWindow (temport);
1401   return OM_MSG_RET_OK;
1402 }
1403 
checkEntityIDForMsg(SeqEditViewFormPtr wdp)1404 static void checkEntityIDForMsg (SeqEditViewFormPtr wdp)
1405 {
1406   EditAlignDataPtr adp;
1407   AlignNodePtr    anp;
1408   ValNodePtr      vnp;
1409   OMUserDataPtr   omudp;
1410   Uint2           eID;
1411   SeqEntryPtr     sep;
1412 
1413   if ( ( adp = GetAlignDataPanel (wdp->pnl) ) == NULL )
1414          return;
1415   if ( adp->seqnumber == 0 )
1416          return;
1417   for (vnp=adp->anp_list; vnp!=NULL; vnp=vnp->next) {
1418    anp = (AlignNodePtr) vnp->data.ptrvalue;
1419    if (anp!=NULL) {
1420       sep = GetTopSeqEntryForEntityID (anp->seq_entityID);
1421       if (sep!=NULL) {
1422          eID = SeqMgrGetEntityIDForSeqEntry(sep);
1423          omudp = ObjMgrGetUserData (eID, wdp->procid, OMPROC_EDIT, wdp->userkey);
1424          if (omudp == NULL) {
1425             omudp = ObjMgrAddUserData (eID, wdp->procid, OMPROC_EDIT, wdp->userkey);
1426             if (omudp != NULL) {
1427                omudp->userdata.ptrvalue = (Pointer) wdp;
1428                omudp->messagefunc = BioseqEditMsgFunc;
1429             }
1430          }
1431       }
1432    }
1433   }
1434 }
1435 
1436 
1437 
1438 /******************************************
1439 ***
1440 ***  Repopulate functions
1441 ***
1442 *******************************************/
1443 
repopulate_panel(WindoW w,EditAlignDataPtr adp,SeqAlignPtr salp)1444 extern void repopulate_panel (WindoW w, EditAlignDataPtr adp, SeqAlignPtr salp)
1445 {
1446   WindoW temport;
1447   SeqEditViewFormPtr wdp;
1448 
1449   if (salp==NULL || adp==NULL)
1450      return;
1451   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
1452 /*** TEMPO ***/
1453   seq_info = adp->seq_info;
1454   adp->seq_info = NULL;
1455 /*** TEMPO ***/
1456   EditAlignDataRepopulateFromSeqAlign (wdp->pnl, adp, salp);
1457   temport = SavePort(w);
1458   Select (wdp->pnl);
1459   inval_panel (wdp->pnl, -1 ,-1);
1460   RestorePort (temport);
1461   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
1462   if (wdp) {
1463      update_sequenceeditormenu (wdp, adp);
1464      checkEntityIDForMsg (wdp);
1465   }
1466   seq_info = NULL;
1467 }
1468 
is_sip_inseqinfo(SeqIdPtr sip,SelEdStructPtr seq_info)1469 static SelEdStructPtr is_sip_inseqinfo (SeqIdPtr sip, SelEdStructPtr seq_info)
1470 {
1471   SelEdStructPtr tmp;
1472   SeqLocPtr      slp;
1473 
1474   for (tmp=seq_info; tmp!=NULL; tmp=tmp->next)
1475   {
1476      slp=(SeqLocPtr)tmp->region;
1477      if (SeqIdForSameBioseq (sip, SeqLocId(slp)))
1478      {
1479         return tmp;
1480      }
1481   }
1482   return NULL;
1483 }
1484 
1485 
ImportFromFileFunc(WindoW w,Int2 method)1486 static void ImportFromFileFunc (WindoW w, Int2 method)
1487 {
1488   EditAlignDataPtr adp;
1489   SeqAlignPtr      salp;
1490 
1491   if (w==NULL)
1492      return;
1493   if ( ( adp = GetAlignEditData (w) ) == NULL )
1494      return;
1495   adp->align_format = (Uint1) method;
1496   salp = ImportFromFile (adp);
1497   if (salp!=NULL)
1498      repopulate_panel (w, adp, salp);
1499 }
1500 
ImportFromFile1Proc(IteM i)1501 static void ImportFromFile1Proc (IteM i)
1502 {
1503   ImportFromFileFunc ((WindoW)ParentWindow(i), (Int2)PRGALIGNDEFAULT);
1504 }
1505 
ImportFromFile2Proc(IteM i)1506 static void ImportFromFile2Proc (IteM i)
1507 {
1508   ImportFromFileFunc ((WindoW)ParentWindow(i), (Int2)PRGALIGNBANDBL);
1509 }
1510 /**
1511 static void ImportFromFile3Proc (IteM i)
1512 {
1513   ImportFromFileFunc ((WindoW)ParentWindow(i), (Int2)PRG_FASTA_IMPORT);
1514 }
1515 **/
ImportFromFile4Proc(IteM i)1516 static void ImportFromFile4Proc (IteM i)
1517 {
1518   ImportFromFileFunc ((WindoW)ParentWindow(i), (Int2)PRG_BLAST);
1519 }
1520 
ImportAlignmentProc(IteM i)1521 static void ImportAlignmentProc (IteM i)
1522 {
1523   WindoW           w;
1524   EditAlignDataPtr adp;
1525   SeqEntryPtr      sep;
1526   SeqIdPtr         sip,
1527                    import_sip;
1528   Char             str[52],
1529                    import_str[52];
1530   SeqAlignPtr      salp;
1531   BioseqPtr        bsp;
1532 
1533   w = (WindoW)ParentWindow(i);
1534   if ( ( adp = GetAlignEditData (w) ) == NULL )
1535      return;
1536 
1537   sep = ReadAnyAlignment (ISA_aa(adp->mol_type), NULL);
1538   salp = (SeqAlignPtr) FindSeqAlignInSeqEntry (sep, (Uint1)OBJ_SEQALIGN);
1539   import_sip = SeqAlignId (salp, 0);
1540   if (import_sip!=NULL)
1541   {
1542      SeqIdWrite (import_sip, import_str, PRINTID_TEXTID_LOCUS, 50);
1543      sip = SeqLocId((SeqLocPtr)adp->master.region);
1544      bsp = BioseqLockById (sip);
1545      if (bsp) {
1546         SeqIdWrite (bsp->id, str, PRINTID_FASTA_LONG, 50);
1547         BioseqUnlock (bsp);
1548      }
1549      else
1550         SeqIdWrite (sip, str, PRINTID_FASTA_LONG, 50);
1551      if ((StringStr(str, import_str))!=NULL)
1552      {
1553         sip = SeqLocId((SeqLocPtr)adp->master.region);
1554         SeqAlignIdReplace (salp, 0, sip);
1555         repopulate_panel (w, adp, salp);
1556         return;
1557      }
1558   }
1559   SeqEntryFree (sep);
1560 }
1561 
CCFetchFromNetFunc(WindoW w,Int2 method)1562 static void CCFetchFromNetFunc (WindoW w, Int2 method)
1563 {
1564   WindoW           temport;
1565   PaneL            pnl;
1566   EditAlignDataPtr adp;
1567   Boolean          net_configuation;
1568 
1569   if (w==NULL)
1570      return;
1571   net_configuation = AmIConfiguredForTheNetwork();
1572   if (!net_configuation) {
1573      Message (MSG_OK, "No network configuration");
1574      return;
1575   }
1576   if ( ( pnl= GetPanelFromWindow (w) ) == NULL)
1577      return;
1578   temport = SavePort (pnl);
1579   Select (pnl);
1580   if ( ( adp = GetAlignEditData (w) ) == NULL )
1581      return;
1582   adp->align_format = (Uint1) method;
1583   CCFetchFromNet (adp, w);
1584   RestorePort (temport);
1585 }
1586 
CCFetchFromNet1Proc(IteM i)1587 static void CCFetchFromNet1Proc (IteM i)
1588 {
1589   CCFetchFromNetFunc ((WindoW)ParentWindow(i), (Int2)PRGALIGNDEFAULT);
1590 }
1591 
CCFetchFromNet2Proc(IteM i)1592 static void CCFetchFromNet2Proc (IteM i)
1593 {
1594   CCFetchFromNetFunc ((WindoW)ParentWindow(i), (Int2)PRGALIGNBANDBL);
1595 }
1596 /**
1597 static void CCFetchFromNet3Proc (IteM i)
1598 {
1599   CCFetchFromNetFunc ((WindoW)ParentWindow(i), (Int2)PRG_FASTA_IMPORT);
1600 }
1601 **/
CCFetchFromNet4Proc(IteM i)1602 static void CCFetchFromNet4Proc (IteM i)
1603 {
1604   CCFetchFromNetFunc ((WindoW)ParentWindow(i), (Int2)PRG_BLAST);
1605 }
1606 
1607 /***********************************************/
ExportTextProc(IteM i)1608 static void ExportTextProc (IteM i)
1609 {
1610   EditAlignDataPtr adp;
1611 
1612   if ( ( adp = GetAlignEditData ((WindoW)ParentWindow (i)) ) == NULL ) return;
1613   adp->align_format = SALSA_SHWTXT;
1614   SalsaExportDialog (i);
1615 }
1616 
ExportFastaProc(IteM i)1617 static void ExportFastaProc (IteM i)
1618 {
1619   EditAlignDataPtr adp;
1620   if ( ( adp = GetAlignEditData ((WindoW)ParentWindow (i)) ) == NULL ) return;
1621   adp->align_format = SALSA_FASTA;
1622   SalsaExportDialog (i);
1623 }
ExportFastaGapProc(IteM i)1624 static void ExportFastaGapProc (IteM i)
1625 {
1626   EditAlignDataPtr adp;
1627   if ( ( adp = GetAlignEditData ((WindoW)ParentWindow (i)) ) == NULL ) return;
1628   adp->align_format = SALSA_FASTGAP;
1629   SalsaExportDialog (i);
1630 }
ExportPhyProc(IteM i)1631 static void ExportPhyProc (IteM i)
1632 {
1633   EditAlignDataPtr adp;
1634   if ( ( adp = GetAlignEditData ((WindoW)ParentWindow (i)) ) == NULL ) return;
1635   adp->align_format = SALSA_PHYLIP;
1636   SalsaExportDialog (i);
1637 }
ExportSeqAnnotProc(IteM i)1638 static void ExportSeqAnnotProc (IteM i)
1639 {
1640   EditAlignDataPtr adp;
1641   if ( ( adp = GetAlignEditData ((WindoW)ParentWindow (i)) ) == NULL ) return;
1642   adp->align_format = SALSA_ASN1;
1643   SalsaExportDialog (i);
1644 }
1645 
1646 /***********************************************************
1647 ***
1648 *** CloseWindow
1649 ***     reads the temporary file
1650 ***     sends a message to ObjMgr (ObjMgrSendMessage(MSG_UPDATE))
1651 ***     frees the data structure
1652 ***     deletes the temporary file
1653 ***
1654 ************************************************************/
CloseWindowProc(PaneL pnl)1655 static void CloseWindowProc (PaneL pnl)
1656 {
1657   WindoW             w;
1658   EditAlignDataPtr   adp;
1659   SeqEntryPtr        prevsep;
1660   SeqEntryPtr        currentsep;
1661 
1662   w = (WindoW)ParentWindow (pnl);
1663   adp = GetAlignEditData (w);
1664   if (adp != NULL && adp->dirty) {
1665      if (adp->input_format == OBJ_BIOSEQ)
1666      {
1667         Hide (w);
1668         Update ();
1669         prevsep = seqentry_read (adp->tmpfile);
1670         currentsep = GetTopSeqEntryForEntityID (adp->master.entityID);
1671         ReplaceSeqEntryWithSeqEntry (currentsep, prevsep, TRUE);
1672         ObjMgrSendMsg (OM_MSG_UPDATE, adp->master.entityID, adp->master.itemID, adp->master.itemtype);
1673         Remove (w);
1674      }
1675      else if (adp->input_format == OBJ_SEQALIGN && adp->dirty)
1676      {
1677 /******
1678         SaveAlignDlg (w);
1679 ******/
1680         Hide (w);
1681         Update ();
1682         Remove (w);
1683      }
1684   }
1685   else {
1686      Hide (w);
1687      Update ();
1688      Remove (w);
1689   }
1690 }
1691 
CloseWindowItemProc(IteM i)1692 static void CloseWindowItemProc (IteM i)
1693 {
1694   PaneL            pnl;
1695   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
1696   CloseWindowProc (pnl);
1697 }
1698 
CloseWindowButton(ButtoN b)1699 static void CloseWindowButton (ButtoN b)
1700 {
1701   PaneL            pnl;
1702   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (b)) ) == NULL) return;
1703   CloseWindowProc (pnl);
1704 }
1705 
AcceptCloseFunc(WindoW w,EditAlignDataPtr adp)1706 static void AcceptCloseFunc (WindoW w, EditAlignDataPtr adp)
1707 {
1708   PaneL              pnl;
1709 
1710   if ( ( pnl= GetPanelFromWindow (w) ) == NULL) return;
1711   Hide (w);
1712   Update ();
1713   if (adp->dirty) {
1714      if (adp->input_format == OBJ_BIOSEQ) {
1715         SaveAllFeatProc (pnl);
1716         ObjMgrSendMsg (OM_MSG_UPDATE, adp->master.entityID, adp->master.itemID, adp->master.itemtype);
1717      }
1718   }
1719   Remove (w);
1720 }
1721 
AcceptCloseWithoutSaveCDSProc(ButtoN b)1722 static void AcceptCloseWithoutSaveCDSProc (ButtoN b)
1723 {
1724   WindoW           wdialog;
1725   DialogBoxDataPtr dbdp;
1726   EditAlignDataPtr adp;
1727 
1728   wdialog = ParentWindow (b);
1729   Hide (wdialog);
1730   Update ();
1731   dbdp = (DialogBoxDataPtr) GetObjectExtra (wdialog);
1732   if ( ( adp = GetAlignEditData (dbdp->w) ) != NULL ) {
1733      adp->feat = SeqfeatlistFree (adp->feat);
1734      AcceptCloseFunc (dbdp->w, adp);
1735   }
1736   Remove (wdialog);
1737 }
1738 
SaveCDSConfirmDlg(WindoW w)1739 static void SaveCDSConfirmDlg (WindoW w)
1740 {
1741   WindoW           wdialog;
1742   DialogBoxDataPtr dbdp;
1743   GrouP            g, c;
1744 
1745   wdialog = FixedWindow (-50, -33, -10, -10, "Save CDS", StdCloseWindowProc);
1746   dbdp = (DialogBoxDataPtr) MemNew (sizeof (DialogBoxData));
1747   SetObjectExtra (wdialog, (Pointer) dbdp, StdCleanupExtraProc);
1748   dbdp->w = w;
1749   g = HiddenGroup (wdialog, 1, 0, NULL);
1750   StaticPrompt (g, "Closing the window will lose unsaved features.", 0, dialogTextHeight,systemFont, 'l');
1751   c = HiddenGroup (wdialog, 2, 0, NULL);
1752   PushButton (c, "OK", AcceptCloseWithoutSaveCDSProc);
1753   PushButton (c, "Cancel", StdCancelButtonProc);
1754   AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
1755   RealizeWindow (wdialog);
1756   Show (wdialog);
1757   return;
1758 }
1759 
AcceptCloseWindowButton(ButtoN b)1760 static void AcceptCloseWindowButton (ButtoN b)
1761 {
1762   WindoW             w;
1763   EditAlignDataPtr   adp;
1764 
1765   w = (WindoW)ParentWindow (b);
1766   if ((adp = GetAlignEditData (w)) == NULL ) return;
1767   ObjMgrSetDirtyFlag (adp->input_entityID, TRUE);
1768   if (adp->feat != NULL) {
1769      SaveCDSConfirmDlg (w);
1770   }
1771   else AcceptCloseFunc (w, adp);
1772 }
1773 
AcceptCloseWindowItemProc(IteM i)1774 static void AcceptCloseWindowItemProc (IteM i)
1775 {
1776   WindoW             w;
1777   EditAlignDataPtr   adp;
1778 
1779   w = (WindoW)ParentWindow (i);
1780   if ((adp = GetAlignEditData (w)) == NULL ) return;
1781   ObjMgrSetDirtyFlag (adp->input_entityID, TRUE);
1782   if (adp->feat != NULL) {
1783      SaveCDSConfirmDlg (w);
1784   }
1785   else AcceptCloseFunc (w, adp);
1786 }
1787 
1788 /*********************************************************
1789 ***
1790 ***
1791 *********************************************************/
UndoProc(IteM i)1792 static void UndoProc (IteM i)
1793 {
1794   PaneL              pnl;
1795   EditAlignDataPtr   adp;
1796   SeqEntryPtr        prevsep, currentsep;
1797   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
1798   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL) return;
1799   if (adp->tmpfile != NULL && adp->tmpfile[0] != '\0')
1800   {
1801      if (adp->master.entityID > 0) {
1802         Update ();
1803         prevsep = seqentry_read (adp->tmpfile);
1804         currentsep = GetTopSeqEntryForEntityID (adp->master.entityID);
1805         ReplaceSeqEntryWithSeqEntry (currentsep, prevsep, TRUE);
1806         ObjMgrSendMsg (OM_MSG_UPDATE, adp->master.entityID, adp->master.itemID, adp->master.itemtype);
1807      }
1808   }
1809   return;
1810 }
1811 
1812 /*********************************************************
1813 ***  CutProc
1814 ***    get the selected segment, call do_cut
1815 ***    Deselect the segment
1816 **********************************************************/
CutProc(IteM i)1817 static void CutProc (IteM i)
1818 {
1819   PaneL              pnl;
1820   EditAlignDataPtr   adp;
1821   SelStructPtr       ssp = NULL;
1822 
1823   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
1824   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL) return;
1825   if (adp->input_format == OBJ_BIOSEQ)
1826   {
1827      if ( checkOMss_for_itemtype (OBJ_BIOSEQ) == 0 ) return;
1828      ssp = ObjMgrGetSelected ();
1829      for (; ssp != NULL; ssp = ssp->next)
1830         if ( ssp->itemtype == OBJ_BIOSEQ && checkssp_for_editor (ssp) )
1831            break;
1832      if (ssp != NULL) {
1833         do_cut (pnl, adp, ssp, TRUE);
1834      }
1835   }
1836   else if (adp->input_format == OBJ_SEQALIGN) {
1837      Beep ();
1838   }
1839   return;
1840 }
1841 
1842 /******************************
1843 ***  PasteProc
1844 ***
1845 *******************************/
PasteProc(IteM i)1846 static void PasteProc (IteM i)
1847 {
1848   PaneL              pnl;
1849   EditAlignDataPtr   adp;
1850   SelStructPtr       ssp = NULL;
1851   BioseqPtr          bsp = NULL;
1852   ObjMgrDataPtr      omdp = NULL;
1853 
1854   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL)
1855      return;
1856   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL )
1857      return;
1858   if (adp->input_format != OBJ_BIOSEQ)
1859      return;
1860   if (ClipboardHasString ())
1861   {
1862      CharPtr     str = ClipboardToString ();
1863      CharPtr     strtmp;
1864      size_t      len = StringLen (str);
1865 
1866      strtmp = char_to_insert (str, len, adp->mol_type);
1867      if (insertchar_atcaret (strtmp, adp)) {
1868         adp->dirty = TRUE;
1869         ObjMgrSetDirtyFlag (adp->caret.entityID, TRUE);
1870         ObjMgrSendMsg (OM_MSG_UPDATE, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype);
1871      }
1872      MemFree (strtmp);
1873      return;
1874   }
1875   if ( adp->caret.regiontype == 0 ) {
1876         ErrPostEx (SEV_ERROR, 0, 0, "Click before paste");
1877         return;
1878   }
1879   omdp = ObjMgrGetClipBoard ();
1880   if (omdp == NULL) {
1881         ErrPostEx (SEV_ERROR, 0, 0, "ClipBoard empty");
1882         return;
1883   }
1884   if (omdp->datatype != OBJ_BIOSEQ || omdp->dataptr == NULL) {
1885         ErrPostEx (SEV_ERROR, 0, 0, "Error: ClipBoard is not BIOSEQ");
1886         return;
1887   }
1888   bsp = (BioseqPtr) omdp->dataptr;
1889   if (bsp!=NULL && bsp->length > 0) {
1890      if (ISA_na (bsp->mol) != ISA_na (adp->mol_type)) {
1891         ErrPostEx (SEV_ERROR, 0, 0, "Error: Pasting uncorrect molecule type [%d / %d]", bsp->mol, adp->mol_type);
1892      }
1893      else {
1894         ssp = ObjMgrGetSelected ();
1895         if (ssp!=NULL) {
1896            if (checkssp_for_editor(ssp) && ssp->itemtype==OBJ_BIOSEQ) {
1897               if (SeqIdForSameBioseq (SeqLocId((SeqLocPtr)(adp->caret.region)), SeqLocId((SeqLocPtr)(ssp->region))) )
1898                  if (do_cut (pnl, adp, ssp, FALSE))
1899                     adp->dirty = TRUE;
1900            }
1901         }
1902         else ssp = NULL;
1903         if (do_paste (pnl, adp, bsp->id) ) {
1904            adp->dirty = TRUE;
1905            ObjMgrSetDirtyFlag (adp->caret.entityID, TRUE);
1906            ObjMgrSendMsg (OM_MSG_UPDATE, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype);
1907         }
1908      }
1909   }
1910   return;
1911 }
1912 
1913 /******************************
1914 *******************************/
DeleteProc(IteM i)1915 static void DeleteProc (IteM i)
1916 {
1917   WindoW             w;
1918   SeqEditViewFormPtr wdp;
1919   EditAlignDataPtr   adp;
1920   SelStructPtr       ssp = NULL;
1921   SeqAnnotPtr        sap;
1922   SeqAlignPtr        newsalp;
1923   SeqLocPtr          slp;
1924   Int2               j;
1925   Boolean            ok,
1926                      deletion = FALSE;
1927 
1928   w = (WindoW)ParentWindow (i);
1929   if (w==NULL)
1930      return;
1931   wdp = (SeqEditViewFormPtr) GetObjectExtra ((WindoW)ParentWindow (i));
1932   if (wdp==NULL)
1933      return;
1934   if ((adp = GetAlignDataPanel(wdp->pnl))!= NULL) {
1935      if ((j = GetNumberObjMgrSelect()) < 1) {
1936         ErrPostEx (SEV_ERROR, 0, 0, "No selection");
1937         return;
1938      }
1939      if (j >= adp->seqnumber) {
1940         ErrPostEx (SEV_ERROR, 0, 0, "You will delete all the sequences except the last one");
1941         return;
1942      }
1943      if (adp->sap_original)
1944         sap = adp->sap_original;
1945      newsalp = (SeqAlignPtr)sap->data;
1946      ssp = ObjMgrGetSelected();
1947      for (; ssp != NULL; ssp = ssp->next)
1948      {
1949         if (checkssp_for_editor (ssp) && ssp->itemtype == OBJ_BIOSEQ)
1950         {
1951            ok = FALSE;
1952            slp=(SeqLocPtr)ssp->region;
1953            if (slp)
1954            {
1955               if ((adp->sap1_original && (FindSeqIdinSeqAlign ((SeqAlignPtr)adp->sap1_original->data, SeqLocId(slp))) > 0) || (FindSeqIdinSeqAlign ((SeqAlignPtr)sap->data, SeqLocId(slp))) > 0)
1956               {
1957 /**
1958                  ObjMgrSendMsg(OM_MSG_HIDE,ssp->entityID, ssp->itemID, ssp->itemtype);
1959 **/
1960                  ok = SeqAlignIDCache (newsalp, SeqLocId((SeqLocPtr)ssp->region));
1961                  if (ok)
1962                     deletion=TRUE;
1963               }
1964               else
1965                  Message (MSG_OK, "Can not delete a sequence from the original input");
1966            }
1967         }
1968         else if ( ssp->itemtype == OBJ_VIRT ) {
1969             adp->feat = del_ssp_fromid (adp->feat, 255, ss_to_ses(ssp));
1970             adp->dirty = TRUE;
1971             ObjMgrSendMsg (OM_MSG_UPDATE, ssp->entityID, ssp->itemID, ssp->itemtype);
1972             ObjMgrDeSelect (ssp->entityID, ssp->itemID, ssp->itemtype, ssp->regiontype, ssp->region);
1973             return;
1974         }
1975         else if (ssp->itemtype == OBJ_SEQFEAT ) {
1976             ErrPostEx (SEV_ERROR, 0, 0, "Can't delete a feature");
1977             return;
1978         }
1979      }
1980      if (deletion)
1981      {
1982         repopulate_panel (w, adp, newsalp);
1983         ObjMgrDeSelectAll ();
1984      }
1985   }
1986   return;
1987 }
1988 
1989 /**********************************************************
1990 ***
1991 ***  ChangeCharModeProc:
1992 ***     adp->charmode shows all char
1993 ***     otherwise dots replacing chars identical to master's
1994 ***
1995 **********************************************************/
ChangeCharModeProc(IteM i)1996 static void ChangeCharModeProc (IteM i)
1997 {
1998   PaneL            pnl;
1999   WindoW           w,
2000                    temport;
2001   SeqEditViewFormPtr wdp;
2002   EditAlignDataPtr adp;
2003 
2004   w = (WindoW)ParentWindow (i);
2005   if (w==NULL)
2006      return;
2007   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
2008   if (wdp==NULL)
2009      return;
2010   if ( ( pnl= GetPanelFromWindow (w) ) == NULL)
2011      return;
2012   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL )
2013      return;
2014   adp->charmode = ! adp->charmode;
2015   ResetClip ();
2016   if ( !adp->charmode) {
2017      Enable(wdp->showdifitem);
2018      Disable (wdp->showallitem);
2019   } else {
2020      Disable(wdp->showdifitem);
2021      Enable (wdp->showallitem);
2022   }
2023   temport = SavePort(w);
2024   Select (pnl);
2025   inval_panel (pnl, -1, -1);
2026   RestorePort (temport);
2027   return;
2028 }
2029 
2030 /*********************************************************
2031 ***
2032 ***  SelectAllProc:
2033 ***    SelectAllSeqEntry + highlight all the sequence Ids
2034 ***
2035 **********************************************************/
SelectAllProc(IteM i)2036 static void SelectAllProc (IteM i)
2037 {
2038   WindoW           temport;
2039   PaneL            pnl;
2040   EditAlignDataPtr adp;
2041   ValNodePtr       vnp;
2042   SeqLocPtr        slp;
2043   AlignNodePtr     anp;
2044   Uint2            ei;
2045   Uint4            ii;
2046   Boolean          first = TRUE;
2047 
2048   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2049   temport = SavePort((WindoW)ParentWindow (i));
2050   Select (pnl);
2051   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2052   if ( adp->seqnumber == 0 || adp->anp_list == NULL) return;
2053   for (vnp =adp->anp_list; vnp !=NULL; vnp =vnp->next)
2054   {
2055      anp = (AlignNodePtr) vnp->data.ptrvalue;
2056      if (anp != NULL)
2057      {
2058            ei = anp->seq_entityID;
2059            ii = anp->bsp_itemID;
2060            slp = CollectSeqLocFromAlignNode (anp);
2061            if (slp != NULL) {
2062               if (first) {
2063                  ObjMgrSelect (ei, ii, OBJ_BIOSEQ, OM_REGION_SEQLOC, slp);
2064                  first = FALSE;
2065               }
2066               else {
2067                  ObjMgrAlsoSelect (ei, ii, OBJ_BIOSEQ, OM_REGION_SEQLOC, slp);
2068               }
2069            }
2070      }
2071   }
2072   RestorePort (temport);
2073   return;
2074 }
2075 
2076 /*********************************************************
2077 ***
2078 ***  SelectMasterProc
2079 ***
2080 **********************************************************/
SelectMasterProc(IteM i)2081 static void SelectMasterProc (IteM i)
2082 {
2083   WindoW           temport;
2084   PaneL            pnl;
2085   EditAlignDataPtr adp;
2086   SelStructPtr     ssp;
2087   SeqLocPtr        slp, slptmp;
2088   RecT             rp;
2089 
2090   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2091   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2092   if ( adp->seqnumber == 0 ) return;
2093   temport = SavePort((WindoW)ParentWindow (i));
2094   Select (pnl);
2095   ssp = ObjMgrGetSelected();
2096   if ( !checkssp_for_editor (ssp) ) return;
2097   if ( ssp->itemtype == OBJ_BIOSEQ && (adp->master.itemID != ssp->itemID
2098      || adp->master.entityID != ssp->entityID ))
2099   {
2100          adp->master.entityID = ssp->entityID;
2101          adp->master.itemID = ssp->itemID;
2102          SeqLocFree ((SeqLocPtr) adp->master.region);
2103          slp = (SeqLocPtr) ssp->region;
2104          slptmp = SeqLocIntNew (SeqLocStart(slp), SeqLocStop(slp), SeqLocStrand(slp), SeqLocId(slp));
2105          adp->master.region = (Pointer) slptmp;
2106          if (adp->charmode) {
2107             inval_panel (pnl, -1, -1);
2108          }
2109          else {
2110             get_client_rect (pnl, &rp);
2111             inval_rect (rp.left, rp.top, (Int2)(rp.left+adp->margin.left-1), rp.bottom);
2112          }
2113   }
2114   RestorePort (temport);
2115 }
2116 
SelectSubsProc(IteM i)2117 static void SelectSubsProc (IteM i)
2118 {
2119   WindoW           temport;
2120   PaneL            pnl;
2121   EditAlignDataPtr adp;
2122   SeqAlignPtr      salp;
2123   ValNodePtr       vnp = NULL;
2124   SeqIdPtr         sip;
2125   CharPtr PNTR     bufstr;
2126   SeqLocPtr        slp;
2127   Int4             from,
2128                    to,
2129                    masterlength,
2130                    k, k2;
2131   Int2             seqnumber,
2132                    nalgline,
2133                    j;
2134   Uint2            eID;
2135   Uint4            iID;
2136   Boolean          goOn= FALSE,
2137                    sel = FALSE,
2138                    first=TRUE;
2139   BoolPtr          select;
2140   SeqEditViewProcsPtr svpp=NULL;
2141 
2142   svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
2143   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL)
2144      return;
2145   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2146   if ( adp->seqnumber == 0 ) return;
2147   temport = SavePort((WindoW)ParentWindow (i));
2148   Select (pnl);
2149 
2150   masterlength = SeqLocLen((SeqLocPtr)adp->master.region);
2151   select=(BoolPtr)MemNew((size_t) ((masterlength+5) * sizeof(Boolean)));
2152   MemSet ((Pointer)select, 0, (size_t)((masterlength+5)*sizeof(Boolean)));
2153   salp = (SeqAlignPtr)adp->sap_align->data;
2154   from = 0;
2155   to = adp->length-1;
2156   seqnumber = adp->seqnumber;
2157   goOn = read_buffer_fromalignnode (adp, &vnp, from, to, &nalgline);
2158 
2159   if (goOn)
2160   {
2161      sip = SeqAlignId (salp, 0);
2162      bufstr=buf2array (vnp, 0, seqnumber-1);
2163      for (j=1; j<seqnumber; j++)
2164      {
2165 		for (k=0; k<to+1; k++)
2166         {
2167 		   if (bufstr[j][k] !='-' && bufstr[0][k]!='-' && bufstr[j][k] != bufstr[0][k])
2168            {
2169               k2 = AlignCoordToSeqCoord(k, sip, salp, adp->sqloc_list,0);
2170               select[k2]=TRUE;
2171            }
2172         }
2173      }
2174      eID=adp->master.entityID;
2175      iID=adp->master.itemID;
2176      k2=-1;
2177      k=0;
2178      sel=select[k];
2179      if (sel)
2180         k2=k;
2181      k++;
2182      for (; k<masterlength; k++)
2183      {
2184         if(select[k] && !sel) {
2185            k2=k;
2186            sel=TRUE;
2187         }
2188         else if (!select[k] && sel) {
2189            if (k2>-1) {
2190               slp=SeqLocIntNew (k2, k-1, Seq_strand_plus, sip);
2191               if (first) {
2192                  ObjMgrSelect(eID, iID, OBJ_BIOSEQ, OM_REGION_SEQLOC,(Pointer)slp);
2193                  first=FALSE;
2194               } else
2195                  ObjMgrAlsoSelect(eID, iID, OBJ_BIOSEQ, OM_REGION_SEQLOC,(Pointer)slp);
2196            }
2197            sel=FALSE;
2198            k2=-1;
2199         }
2200      }
2201      if (k2>-1) {
2202         slp=SeqLocIntNew (k2, k-1, Seq_strand_plus, sip);
2203         if (first) {
2204            ObjMgrSelect (eID, iID, OBJ_BIOSEQ, OM_REGION_SEQLOC,(Pointer)slp);
2205            first=FALSE;
2206         } else
2207            ObjMgrAlsoSelect(eID, iID, OBJ_BIOSEQ, OM_REGION_SEQLOC,(Pointer)slp);
2208      }
2209   }
2210   RestorePort (temport);
2211   MemFree(select);/*don't forget, dear Colombe, to free your memory !*/
2212 }
2213 
2214 /**********************************************************
2215 ***
2216 *** RefreshAlignData: refreches the window
2217 ***
2218 ***********************************************************/
RefreshAlignDataProc(PaneL pnl)2219 static void RefreshAlignDataProc (PaneL pnl)
2220 {
2221   WindoW           temport;
2222   EditAlignDataPtr adp;
2223 
2224   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2225   if ( adp->seqnumber == 0 ) return;
2226   data_collect_arrange (adp, TRUE);
2227   temport = SavePort (pnl);
2228   Select (pnl);
2229   inval_panel (pnl, -1, -1);
2230   RestorePort (temport);
2231   return;
2232 }
2233 
RefreshAlignDataItem(IteM i)2234 static void RefreshAlignDataItem (IteM i)
2235 {
2236   PaneL            pnl;
2237   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2238   RefreshAlignDataProc (pnl);
2239   CaptureSlateFocus ((SlatE) pnl);
2240 }
2241 
RefreshAlignDataButton(ButtoN b)2242 static void RefreshAlignDataButton (ButtoN b)
2243 {
2244   PaneL            pnl;
2245   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (b)) ) == NULL) return;
2246   RefreshAlignDataProc (pnl);
2247   CaptureSlateFocus ((SlatE) pnl);
2248 }
2249 
2250 /**********************************************************
2251 ***
2252 ***  Complement
2253 ***
2254 ***  SetRf, SetRfFunc:
2255 ***
2256 ***********************************************************/
ComplementProc(EditAlignDataPtr adp)2257 static void ComplementProc (EditAlignDataPtr adp)
2258 {
2259   SelStructPtr     ssp;
2260   ValNodePtr       vnp;
2261   SeqParamPtr      prm;
2262 
2263   if ( checkOMss_for_itemtype (OBJ_BIOSEQ) == 0 ) {
2264      ssp = &(adp->master);
2265   }
2266   else ssp = ObjMgrGetSelected();
2267   for (; ssp != NULL; ssp = ssp->next) {
2268      if (checkssp_for_editor (ssp) && ssp->itemtype == OBJ_BIOSEQ)
2269      {
2270         for (vnp = adp->params; vnp != NULL; vnp = vnp->next) {
2271            prm = (SeqParamPtr) vnp->data.ptrvalue;
2272            if ( prm->entityID == ssp->entityID )
2273               prm->complement = !(prm->complement);
2274         }
2275      }
2276   }
2277   return;
2278 }
2279 
ComplementItemProc(IteM i)2280 static void ComplementItemProc (IteM i)
2281 {
2282   WindoW           temport;
2283   PaneL            pnl;
2284   EditAlignDataPtr adp;
2285   float hratio;
2286 
2287   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2288   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2289   if (adp->seqnumber == 0 || ISA_aa(adp->mol_type))
2290     return;
2291   adp->drawcomplt = GetStatus (i);
2292   temport = SavePort((WindoW)ParentWindow (i));
2293   Select (pnl);
2294   inval_panel (pnl, -1, -1);
2295   ComplementProc (adp);
2296   data_collect_arrange (adp, TRUE);
2297   hratio = (float)adp->hoffset / (float)adp->length;
2298   SeqEdSetCorrectBarMax (pnl, adp, hratio);
2299   RestorePort (temport);
2300 }
2301 
2302 
changeseqid(PaneL pnl,Uint1 choice)2303 static void changeseqid (PaneL pnl, Uint1 choice)
2304 {
2305   WindoW           temport;
2306   EditAlignDataPtr adp;
2307 
2308   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL )
2309      return;
2310   if (adp->seqnumber == 0)
2311     return;
2312   if (choice < 6) {
2313      adp->printid = choice;
2314      adp->size_labels = getsize_seqids (adp->sqloc_list, choice);
2315      adp->marginwithIds = TRUE;
2316   }
2317   else if (choice == PRINTID_GIcc) {
2318      adp->printid = choice;
2319      adp->size_labels = 10;
2320      adp->marginwithIds = TRUE;
2321   }
2322   else if (choice == 6) {
2323      adp->printid = 0;
2324      adp->size_labels = 15;
2325      adp->marginwithIds = FALSE;
2326   }
2327   temport = SavePort(pnl);
2328   Select (pnl);
2329   inval_panel (pnl, -1, -1);
2330   RestorePort (temport);
2331 }
changeseqid1(IteM i)2332 static void changeseqid1 (IteM i) {
2333   changeseqid ((PaneL)GetPanelFromWindow((WindoW)ParentWindow (i)), (Uint2)PRINTID_GIcc);
2334 }
changeseqid2(IteM i)2335 static void changeseqid2 (IteM i) {
2336   changeseqid ((PaneL)GetPanelFromWindow((WindoW)ParentWindow (i)), (Uint2)PRINTID_FASTA_LONG);
2337 }
changeseqid3(IteM i)2338 static void changeseqid3 (IteM i) {
2339   changeseqid ((PaneL)GetPanelFromWindow((WindoW)ParentWindow (i)), (Uint2)PRINTID_TEXTID_LOCUS);
2340 }
changeseqid4(IteM i)2341 static void changeseqid4 (IteM i) {
2342   changeseqid ((PaneL)GetPanelFromWindow((WindoW)ParentWindow (i)), (Uint2)PRINTID_TEXTID_ACCESSION);
2343 }
changeseqid6(IteM i)2344 static void changeseqid6 (IteM i) {
2345   changeseqid ((PaneL)GetPanelFromWindow((WindoW)ParentWindow (i)), (Uint2)6);
2346 }
2347 
2348 /******************************************************************
2349 ***
2350 ***  MakemRNArProc
2351 ***  MakeCdRgnProc , MakeCdRgnrProc
2352 ***  SaveFeatureButton
2353 ***
2354 *******************************************************************/
2355 
MakeCdRgnProc(IteM i)2356 static void MakeCdRgnProc (IteM i) {
2357   MakeFeatProc((PaneL)GetPanelFromWindow((WindoW)ParentWindow (i)), SEQFEAT_CDREGION, Seq_strand_plus);
2358 }
2359 
MakeCdRgnrProc(IteM i)2360 static void MakeCdRgnrProc (IteM i) {
2361   MakeFeatProc((PaneL)GetPanelFromWindow((WindoW)ParentWindow (i)), SEQFEAT_CDREGION, Seq_strand_minus);
2362 }
2363 
SaveFeatureButton(ButtoN b)2364 static void SaveFeatureButton (ButtoN b)
2365 {
2366   PaneL              pnl;
2367   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (b)) ) == NULL) return;
2368   SaveFeatProc (pnl);
2369   CaptureSlateFocus ((SlatE) pnl);
2370 }
2371 
2372 /******************************************************************
2373 ***
2374 ***  TranslateProc , TranslateButton
2375 ***
2376 *******************************************************************/
2377 
TranslateButton(ButtoN b)2378 static void TranslateButton (ButtoN b)
2379 {
2380   PaneL            pnl;
2381   EditAlignDataPtr adp;
2382 
2383   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (b)) ) == NULL) return;
2384   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2385   if ( adp->seqnumber == 0 ) return;
2386   if (GetNumberObjMgrSelect() == 0)
2387      TranslateAllBioseq (pnl, adp);
2388   if ( checkOMss_for_itemtype (OBJ_VIRT) != 0
2389      || checkOMss_for_itemtype (OBJ_SEQFEAT) != 0 ) {
2390      CdRgnToProtProc (pnl, adp);
2391      if (!adp->display_panel) {
2392         update_translateitem (pnl, adp->seqfeat, adp->feat);
2393         update_codonstartbt (pnl, adp->seqfeat, adp->feat);
2394      }
2395   }
2396   CaptureSlateFocus ((SlatE) pnl);
2397 }
2398 
2399 /***********************************************************
2400 ***  FeatEditModeProc
2401 ************************************************************/
SelectFeatEditMode(PopuP p)2402 static void SelectFeatEditMode (PopuP p)
2403 {
2404   SeqEditViewFormPtr wdp;
2405   EditAlignDataPtr   adp;
2406   Int2               val;
2407 
2408   wdp = (SeqEditViewFormPtr) GetObjectExtra ((WindoW)ParentWindow (p));
2409   if ( ( adp = GetAlignDataPanel (wdp->pnl) ) == NULL ) return;
2410   val = GetValue(p);
2411   if (val==1)
2412      adp->spliteditmode = FALSE;
2413   else if (val==2)
2414      adp->spliteditmode = TRUE;
2415   CaptureSlateFocus ((SlatE) wdp->pnl);
2416 }
2417 
EditModeProc(IteM i)2418 static void EditModeProc (IteM i)
2419 {
2420   SeqEditViewFormPtr wdp;
2421   EditAlignDataPtr   adp;
2422 
2423   wdp = (SeqEditViewFormPtr) GetObjectExtra ((WindoW)ParentWindow (i));
2424   if ( ( adp = GetAlignDataPanel (wdp->pnl) ) != NULL )
2425   {
2426      if (adp->edit_mode == SEQ_EDIT || adp->edit_mode == ALIGN_EDIT)
2427      {
2428         adp->edit_mode = SEQ_VIEW;
2429         editor2viewer (wdp);
2430      }
2431      else {
2432         if (adp->seqnumber > 1)
2433            adp->edit_mode = ALIGN_EDIT;
2434         else
2435            adp->edit_mode = SEQ_EDIT;
2436         viewer2editor (wdp);
2437      }
2438   }
2439 }
2440 
2441 /***********************************************************
2442 ***  ShowFeatureItemProc
2443 ***  ShowFeatureButtonProc
2444 ************************************************************/
ShowFeatureItemProc(IteM i)2445 static void ShowFeatureItemProc (IteM i)
2446 {
2447   PaneL              pnl;
2448   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2449   ShowFeatureProc (pnl, TRUE);
2450 }
2451 
ShowFeatureButtonProc(ButtoN b)2452 static void ShowFeatureButtonProc (ButtoN b)
2453 {
2454   PaneL              pnl;
2455   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (b)) ) == NULL) return;
2456   ShowFeatureProc (pnl, TRUE);
2457   CaptureSlateFocus ((SlatE) pnl);
2458 }
2459 
2460 /***********************************************************
2461 ***  ChangeProtModeProc
2462 ************************************************************/
ChangeProtModeProc(IteM i)2463 static void ChangeProtModeProc (IteM i)
2464 {
2465   WindoW           temport;
2466   PaneL            pnl;
2467   EditAlignDataPtr adp;
2468 
2469   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2470   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2471   if ( adp->seqnumber == 0 ) return;
2472   adp->prot_mode = ALLPROTAA;
2473   adp->firstssp = NULL;
2474   data_collect_arrange (adp, FALSE);
2475   temport = SavePort((WindoW)ParentWindow (i));
2476   Select (pnl);
2477   inval_panel (pnl, -1, -1);
2478   RestorePort (temport);
2479 }
2480 
ChangeProtModeProc2(IteM i)2481 static void ChangeProtModeProc2 (IteM i)
2482 {
2483   WindoW           temport;
2484   PaneL            pnl;
2485   EditAlignDataPtr adp;
2486 
2487   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2488   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2489   if ( adp->seqnumber == 0 ) return;
2490   adp->prot_mode = MPROTAA;
2491   temport = SavePort((WindoW)ParentWindow (i));
2492   Select (pnl);
2493   inval_panel (pnl, -1, -1);
2494   RestorePort (temport);
2495 }
2496 
ChangeProtModeProc3(IteM i)2497 static void ChangeProtModeProc3 (IteM i)
2498 {
2499   WindoW           temport;
2500   PaneL            pnl;
2501   EditAlignDataPtr adp;
2502 
2503   if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2504   if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
2505   if ( adp->seqnumber == 0 ) return;
2506   adp->prot_mode = PUTPROT;
2507   adp->firstssp = NULL;
2508   data_collect_arrange (adp, FALSE);
2509   temport = SavePort((WindoW)ParentWindow (i));
2510   Select (pnl);
2511   inval_panel (pnl, -1, -1);
2512   RestorePort (temport);
2513 }
2514 
2515 /*****************************************************************
2516 ***    SetupMenus
2517 ***
2518   CommandItem (m, "Open Sequences", OpenSequenceProc);
2519   CommandItem (m, "Open SeqAnnot",  OpenSeqAnnotProc);
2520   CommandItem (m, "Open Alignment", OpenAlignmentProc);
2521   CommandItem (m, "Add Alignment", OpenAlignmentProc);
2522 
2523 *******************************************************************/
EditorEditMenu(MenU m,SeqEditViewFormPtr wdp)2524 static void EditorEditMenu (MenU m, SeqEditViewFormPtr wdp)
2525 {
2526   wdp->undoitem = CommandItem (m, "Undo", UndoProc);
2527   SeparatorItem (m);
2528   wdp->cutitem   = CommandItem (m, "Cut", CutProc);
2529   Disable (wdp->cutitem);
2530   wdp->pasteitem = CommandItem (m, "Paste", PasteProc);
2531   wdp->copyitem  = CommandItem (m, "Copy", do_copy);
2532   Disable (wdp->copyitem);
2533   CommandItem (m, "Refresh", RefreshAlignDataItem);
2534   SeparatorItem (m);
2535   wdp->insitem   = CommandItem (m, "Insert Sequence", InsertSeqProc);
2536   SeparatorItem (m);
2537   wdp->delitem   = CommandItem (m, "Delete Seq", DeleteProc);
2538   Disable (wdp->delitem);
2539 /****
2540   SeparatorItem (m);
2541   CommandItem (m, "Select Region", SelectRegionDialog);
2542 ****/
2543 }
2544 
CommonViewMenu(MenU m,SeqEditViewFormPtr wdp,Boolean isa_aa)2545 static void CommonViewMenu (MenU m, SeqEditViewFormPtr wdp, Boolean isa_aa)
2546 {
2547   IteM  localItem;
2548   MenU  sub;
2549 
2550   wdp->viewmodeitem = CommandItem (m, "View mode", EditModeProc);
2551   wdp->editmodeitem = CommandItem (m, "Edit mode", EditModeProc);
2552   SeparatorItem (m);
2553   sub = SubMenu (m, "Label");
2554     CommandItem (sub, "Accession", changeseqid4);
2555     CommandItem (sub, "Gi", changeseqid1);
2556     CommandItem (sub, "Locus", changeseqid3);
2557     CommandItem (sub, "Complete", changeseqid2);
2558     CommandItem (sub, "None", changeseqid6);
2559   CommandItem (m, "Font", SeqFontProc);
2560   wdp->prefitem=CommandItem (m, "Preferences", DefinePanelDialog);
2561 
2562   if (!isa_aa) {
2563      SeparatorItem (m);
2564      localItem = StatusItem (m, "Complement", ComplementItemProc);
2565      SetStatus ( localItem, FALSE);
2566      sub = SubMenu (m, "Reading frames");
2567     wdp->rfitem[0] = StatusItem (sub, "1", rf1ItemProc);
2568     SetStatus ( wdp->rfitem [0], FALSE);
2569     wdp->rfitem[1] = StatusItem (sub, "2", rf2ItemProc);
2570     SetStatus ( wdp->rfitem [1], FALSE);
2571     wdp->rfitem[2] = StatusItem (sub, "3", rf3ItemProc);
2572     SetStatus ( wdp->rfitem [2], FALSE);
2573     wdp->rfitem[6] = StatusItem (sub, "all+", rf7ItemProc);
2574     SetStatus ( wdp->rfitem [6], FALSE);
2575     SeparatorItem (sub);
2576     wdp->rfitem[3] = StatusItem (sub, "4", rf4ItemProc);
2577     SetStatus ( wdp->rfitem [3], FALSE);
2578     wdp->rfitem[4] = StatusItem (sub, "5", rf5ItemProc);
2579     SetStatus ( wdp->rfitem [4], FALSE);
2580     wdp->rfitem[5] = StatusItem (sub, "6", rf6ItemProc);
2581     SetStatus ( wdp->rfitem [5], FALSE);
2582     wdp->rfitem[7] = StatusItem (sub, "all-", rf8ItemProc);
2583     SetStatus ( wdp->rfitem [7], FALSE);
2584     SeparatorItem (sub);
2585     wdp->rfitem[8] = StatusItem (sub, "all", rf9ItemProc);
2586     SetStatus ( wdp->rfitem [8], FALSE);
2587     wdp->rfitem[9] = StatusItem (sub, "none", rf10ItemProc);
2588     SetStatus ( wdp->rfitem [0], FALSE);
2589      sub = SubMenu (m, "Translation style");
2590      CommandItem (sub, "all", ChangeProtModeProc);
2591      CommandItem (sub, "M*", ChangeProtModeProc2);
2592      CommandItem (sub, "orf", ChangeProtModeProc3);
2593   }
2594 #ifdef SALSA_DEBUG
2595   SeparatorItem (m);
2596   VSMAddToMenu (m, VSM_DESKTOP);
2597 #endif
2598 }
2599 
2600 typedef struct newfeaturedata {
2601   ObjMgrProcPtr  ompp;
2602   IteM           item;
2603   Uint1          molgroup;
2604   struct newfeaturedata PNTR next;
2605 } NewFeatureData, PNTR NewFeaturePtr;
2606 
2607 static CharPtr  editOldSrcDescMsg = "\
2608 You may really want to edit an existing BioSource descriptor instead.\n\
2609 Proceed anyway?";
2610 
SalsaNewFeatureMenuProc(IteM i)2611 static void SalsaNewFeatureMenuProc (IteM i)
2612 
2613 {
2614   EditAlignDataPtr  adp;
2615   MsgAnswer         ans;
2616   NewFeaturePtr     nfp;
2617   OMProcControl     ompc;
2618   ObjMgrProcPtr     ompp;
2619   PaneL             pnl;
2620   Int2              retval;
2621 
2622   pnl = (PaneL) GetPanelFromWindow ((WindoW) ParentWindow (i));
2623   if (pnl == NULL) return;
2624   adp = GetAlignDataPanel (pnl);
2625   if (adp == NULL) return;
2626   nfp = (NewFeaturePtr) GetObjectExtra (i);
2627   if (nfp == NULL) return;
2628   ompp = nfp->ompp;
2629   if (ompp == NULL || ompp->func == NULL) return;
2630   if (ompp->subinputtype == FEATDEF_BIOSRC) {
2631     ans = Message (MSG_YN, editOldSrcDescMsg);
2632     if (ans == ANS_NO) return;
2633   }
2634   MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
2635   ompc.input_entityID = adp->master.entityID;
2636   ompc.input_itemID = adp->master.itemID;
2637   ompc.input_itemtype = adp->master.itemtype;
2638   GatherDataForProc (&ompc, FALSE);
2639   ompc.proc = ompp;
2640   retval = (*(ompp->func)) (&ompc);
2641   if (retval == OM_MSG_RET_ERROR) {
2642     ErrShow ();
2643   }
2644 }
2645 
SalsaNewFeaturesMenu(MenU m,Boolean is_na)2646 static void SalsaNewFeaturesMenu (MenU m, Boolean is_na)
2647 
2648 {
2649   FeatDispGroupPtr  fdgp;
2650   FeatDefPtr        fdp;
2651   NewFeaturePtr     first;
2652   IteM              i;
2653   Uint1             key;
2654   CharPtr           label;
2655   NewFeaturePtr     last;
2656   NewFeaturePtr     nfp;
2657   ObjMgrPtr         omp;
2658   ObjMgrProcPtr     ompp;
2659   ObjMgrTypePtr     omtp;
2660   MenU              sub;
2661   Uint2             subtype;
2662 
2663   if (m == NULL) return;
2664   omp = ObjMgrGet ();
2665   if (omp == NULL) return;
2666   ompp = ObjMgrProcFindNext (omp, OMPROC_EDIT, 0, 0, NULL);
2667   if (ompp == NULL) return;
2668   omtp = NULL;
2669   first = NULL;
2670   last = NULL;
2671   while ((omtp = ObjMgrTypeFindNext (omp, omtp)) != NULL) {
2672     ompp = ObjMgrProcFindNext (omp, OMPROC_EDIT, omtp->datatype, 0, NULL);
2673     if (ompp != NULL) {
2674       switch (omtp->datatype) {
2675         case OBJ_SEQFEAT :
2676           fdgp = NULL;
2677           while ((fdgp = DispGroupFindNext (fdgp, &key, &label)) != NULL) {
2678             if (fdgp->groupkey != 0) {
2679               sub = SubMenu (m, fdgp->groupname);
2680               fdp = NULL;
2681               label = NULL;
2682               while ((fdp = FeatDefFindNext (fdp, &key, &label,
2683                      fdgp->groupkey, FALSE)) != NULL) {
2684                 if (key != FEATDEF_BAD) {
2685                   ompp = NULL;
2686                   while ((ompp = ObjMgrProcFindNext (omp, OMPROC_EDIT,
2687 				          omtp->datatype, 0, ompp)) != NULL) {
2688                     if (ompp->subinputtype == fdp->featdef_key &&
2689                         ompp->subinputtype != FEATDEF_PUB) {
2690                       i = CommandItem (sub, ompp->proclabel, SalsaNewFeatureMenuProc);
2691                       nfp = (NewFeaturePtr) MemNew (sizeof (NewFeatureData));
2692                       if (nfp != NULL) {
2693                         nfp->ompp = ompp;
2694                         nfp->item = i;
2695                         nfp->molgroup = fdp->molgroup;
2696                       }
2697                       if (first == NULL) {
2698                         first = nfp;
2699                       }
2700                       if (last != NULL) {
2701                         last->next = nfp;
2702                       }
2703                       last = nfp;
2704                       SetObjectExtra (i, (Pointer) nfp, StdCleanupExtraProc);
2705                       if ((is_na && (fdp->molgroup == 2 || fdp->molgroup == 3)) ||
2706                           ((! is_na) && (fdp->molgroup == 1 || fdp->molgroup == 3))) {
2707                       } else {
2708                         Disable (i);
2709                       }
2710                     }
2711                   }
2712                 }
2713               }
2714             }
2715           }
2716           sub = SubMenu (m, "Remaining Features");
2717           fdp = NULL;
2718           label = NULL;
2719           while ((fdp = FeatDefFindNext (fdp, &key, &label, 0, FALSE)) != NULL) {
2720             if (key != FEATDEF_BAD) {
2721               ompp = NULL;
2722               while ((ompp = ObjMgrProcFindNext (omp, OMPROC_EDIT,
2723                       omtp->datatype, 0, ompp)) != NULL) {
2724                 subtype = ompp->subinputtype;
2725                 if (subtype == fdp->featdef_key && OkToListFeatDefInRemainingFeatures (subtype)) {
2726                   i = CommandItem (sub, ompp->proclabel, SalsaNewFeatureMenuProc);
2727                   nfp = (NewFeaturePtr) MemNew (sizeof (NewFeatureData));
2728                   if (nfp != NULL) {
2729                     nfp->ompp = ompp;
2730                     nfp->item = i;
2731                     nfp->molgroup = fdp->molgroup;
2732                   }
2733                   if (first == NULL) {
2734                     first = nfp;
2735                   }
2736                   if (last != NULL) {
2737                     last->next = nfp;
2738                   }
2739                   last = nfp;
2740                   SetObjectExtra (i, (Pointer) nfp, StdCleanupExtraProc);
2741                   if ((is_na && (fdp->molgroup == 2 || fdp->molgroup == 3)) ||
2742                       ((! is_na) && (fdp->molgroup == 1 || fdp->molgroup == 3))) {
2743                   } else {
2744                     Disable (i);
2745                   }
2746                 }
2747               }
2748             }
2749           }
2750           break;
2751         default :
2752           break;
2753       }
2754     }
2755   }
2756 }
2757 
2758 /**************************************************************
2759 *** Menu item not used :
2760 ***   wdp->translateitem
2761 ***   wdp->codonstitem
2762 ***   wdp->savefeatitem
2763 *** items not tested
2764      CommandItem (m1, "Select", SelectSeqDialog);
2765 ***************************************************************/
SetupMenus(WindoW w,Boolean is_alignment,Boolean isa_aa,Boolean editor_mode,Boolean ext_dist_menu,Boolean ext_align_menu,Boolean ext_tree_menu)2766 static void SetupMenus (WindoW w, Boolean is_alignment,
2767             Boolean isa_aa, Boolean editor_mode,
2768             Boolean ext_dist_menu, Boolean ext_align_menu, Boolean ext_tree_menu)
2769 {
2770   SeqEditViewFormPtr wdp;
2771   MenU               mf, m1, m2, m3, m4;
2772   MenU               sub;
2773 
2774   SeqEditViewProcsPtr svpp=NULL;
2775 
2776   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
2777   if (wdp == NULL)
2778      return;
2779 
2780   mf = PulldownMenu (w, "File");
2781   sub = SubMenu (mf, "Read Sequence File");
2782   wdp->importseq=CommandItem (sub, "BLAST", ImportFromFile4Proc);
2783   wdp->importseq=CommandItem (sub, "BLAST with extensions", ImportFromFile1Proc);
2784   wdp->importalg=CommandItem (sub, "Global Alignment", ImportFromFile2Proc);
2785 /********TEMPO
2786   wdp->importnet=CommandItem (sub,"Manual Alignment", ImportFromFile3Proc);
2787 ****/
2788   sub = SubMenu (mf,"Download From Entrez");
2789   CommandItem (sub, "BLAST", CCFetchFromNet4Proc);
2790   CommandItem (sub, "BLAST with extensions", CCFetchFromNet1Proc);
2791   CommandItem (sub, "Global Alignment", CCFetchFromNet2Proc);
2792 /*****TEMPO
2793   CommandItem (sub,"Manual Alignment", CCFetchFromNet3Proc);
2794 ***/
2795   wdp->importalg=CommandItem(mf, "Import Alignment", ImportAlignmentProc);
2796 
2797   sub = SubMenu (mf, "Export");
2798   CommandItem (sub, "Text", ExportTextProc);
2799   CommandItem (sub, "Fasta", ExportFastaProc);
2800   wdp->expfsagitem=CommandItem (sub, "Fasta+gaps", ExportFastaGapProc);
2801   wdp->expalgitem=CommandItem (sub, "Phylip Format", ExportPhyProc);
2802   wdp->expasnitem=CommandItem (sub, "Asn1 SeqAlign", ExportSeqAnnotProc);
2803 
2804   SeparatorItem (mf);
2805   if (is_alignment) {
2806      CommandItem (mf, "Dismiss", CloseWindowItemProc);
2807   }
2808   else {
2809      if (editor_mode)
2810         CommandItem (mf, "Accept Changes", AcceptCloseWindowItemProc);
2811      CommandItem (mf, "Cancel", CloseWindowItemProc);
2812   }
2813   m1 = PulldownMenu (w, "Edit");
2814   EditorEditMenu (m1, wdp);
2815 
2816   m2 = PulldownMenu (w, "View");
2817   CommonViewMenu (m2, wdp, isa_aa);
2818   SeparatorItem (m2);
2819   CommandItem (m2, "Find/F", FindPatternDialog);
2820 
2821   wdp->showfeatitem = NULL;
2822   wdp->hidefeatitem = NULL;
2823   wdp->propaitem = NULL;
2824   wdp->tmpcdspitem=NULL;
2825 
2826   if (editor_mode)
2827   {
2828      m3= PulldownMenu (w, "Features");
2829      if (!is_alignment) {
2830         SalsaNewFeaturesMenu (m3, (! isa_aa));
2831      }
2832      else
2833      {
2834         wdp->propaitem = CommandItem (m3, "Propagate", PropagateFeatDialog);
2835      }
2836 /****
2837      if (!isa_aa && !is_alignment)
2838      {
2839         SeparatorItem (m3);
2840         wdp->tmpcdspitem=CommandItem(m3, "Temporary CDS +", MakeCdRgnProc);
2841         wdp->tmpcdsnitem=CommandItem(m3, "Temporary CDS -", MakeCdRgnrProc);
2842      }
2843 *****/
2844   }
2845   else {
2846      svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
2847      if (svpp) {
2848         if (svpp->Cn3D_On) {
2849            if(!is_alignment) {
2850               m3= PulldownMenu (w, "Features");
2851               wdp->showfeatitem = CommandItem (m3, "Show Features", ShowFeatureItemProc);
2852               wdp->hidefeatitem = CommandItem (m3, "Hide Features", ShowFeatureItemProc);
2853               Disable (wdp->hidefeatitem);
2854            }
2855         }
2856         else {
2857            m3= PulldownMenu (w, "Features");
2858            wdp->showfeatitem = CommandItem (m3, "Show Features", ShowFeatureItemProc);
2859            wdp->hidefeatitem = CommandItem (m3, "Hide Features", ShowFeatureItemProc);
2860            Disable (wdp->hidefeatitem);
2861         }
2862      }
2863      else {
2864         m3= PulldownMenu (w, "Features");
2865         wdp->showfeatitem = CommandItem (m3, "Show Features", ShowFeatureItemProc);
2866         wdp->hidefeatitem = CommandItem (m3, "Hide Features", ShowFeatureItemProc);
2867         Disable (wdp->hidefeatitem);
2868      }
2869   }
2870 
2871   m4 = PulldownMenu (w, "Alignment");
2872   wdp->selmaster = CommandItem (m4, "Select Reference", SelectMasterProc);
2873   wdp->selall = CommandItem (m4, "Select All", SelectAllProc);
2874   SeparatorItem (m4);
2875   wdp->showdifitem=CommandItem (m4, "Show Substitutions", ChangeCharModeProc);
2876   wdp->showallitem=CommandItem (m4, "Show All", ChangeCharModeProc);
2877   SeparatorItem (m4);
2878   wdp->selsubs= CommandItem (m4, "Select Variations", SelectSubsProc);
2879 /*if (!isa_aa)
2880      wdp->conscolor=CommandItem (m4, "Conservation", ColorIdentityDialogItem); */
2881 /* yanli started */
2882   wdp->conscolor=CommandItem (m4, "Conservation", ColorIdentityDialogItem);
2883   svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
2884   if (svpp)
2885      svpp->conscolor = wdp->conscolor;
2886 /* yanli ended */
2887 
2888 
2889   svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
2890   if (svpp) {
2891      if (!svpp->Cn3D_On) {
2892         SeparatorItem (m4);
2893         wdp->dotmat = CommandItem (m4, "Dot Matrix (BLAST)", DotPlotItem);
2894 /**
2895         wdp->alreport = CommandItem (m4, "Align Report", AlignReportItem);
2896 **/
2897      }
2898   }
2899   wdp->menu_align = m4;
2900 /*****
2901   if (is_alignment && ext_dist_menu)
2902   {
2903      SeparatorItem (m4);
2904      CommandItem (m4, "debug", NULL);
2905      CommandItem (m4, "Formula", FormulaDialog);
2906      CommandItem (m4, "Pw distance", PwDistanceItem);
2907      CommandItem (m4, "Pw dist per pos", DistPosItem);
2908      CommandItem (m4, "Gp distance", GpDistanceItem);
2909      CommandItem (m4, "Sort simil", SortbySimItem);
2910      CommandItem (m4, "Sort lenght", SortbyLenItem);
2911      CommandItem (m4, "Quorum", QuorumItem);
2912      CommandItem (m4, "Ks Ka gp", NonsyToSynItem1);
2913      CommandItem (m4, "Ks Ka gp wd", NonsyToSynItem2);
2914      CommandItem (m4, "Ks Ka ref", NonsyToSynItem3);
2915      CommandItem (m4, "Ks Ka ref wd", NonsyToSynItem4);
2916      CommandItem (m4, "Ks Ka btw gps", NonsyToSynItem5);
2917      CommandItem (m4, "Ks Ka btw gps wd", NonsyToSynItem6);
2918   }
2919 #ifdef SALSA_DEBUG
2920   if (is_alignment && ext_tree_menu)
2921   {
2922      SeparatorItem (m4);
2923      CommandItem (m4, "debug", NULL);
2924      CommandItem (m4, "Show tree", TreeViewItem);
2925   }
2926 #endif
2927 *****/
2928 }
2929 
2930 /***************************************************************
2931 ***    CleanupSequenceEditorForm
2932 ***
2933 ***      sends a message calling ObjMgrFreeUserData
2934 ***      StdCleanupFormProc
2935 ******************************************************************/
CleanupSequenceEditorForm(GraphiC g,VoidPtr data)2936 static void CleanupSequenceEditorForm (GraphiC g, VoidPtr data)
2937 
2938 {
2939   StdCleanupFormProc (g, data);
2940 }
2941 
2942 /**********************************************************
2943 ***
2944 ***  CleanupAlignDataPanel: Callback to free any instance
2945 ***     specific memory that may be pointed to in the extra.
2946 ***
2947 ***********************************************************/
CleanupAlignDataPanel(GraphiC g,VoidPtr data)2948 static void CleanupAlignDataPanel (GraphiC g, VoidPtr data)
2949 
2950 {
2951   EditAlignDataPtr   adp;
2952   SeqEditViewFormPtr wdp;
2953   Int4               strlens;
2954   SeqEntryPtr sep;
2955   Uint2       eID;
2956   OMUserDataPtr omudp;
2957   SelEdStructPtr sesp;
2958 
2959   adp = (EditAlignDataPtr) data;
2960   if (adp != NULL)
2961   {
2962      wdp = (SeqEditViewFormPtr) adp->wdp;
2963      if (wdp != NULL) {
2964       if (wdp->input_entityID > 0)
2965       {
2966         ObjMgrFreeUserData (wdp->input_entityID, wdp->procid, wdp->proctype, wdp->userkey);
2967         for (sesp=adp->seq_info; sesp!=NULL; sesp=sesp->next)
2968         {
2969               sep = GetTopSeqEntryForEntityID (sesp->entityID);
2970               if (sep!=NULL) {
2971                  eID = SeqMgrGetEntityIDForSeqEntry(sep);
2972                  omudp = ObjMgrGetUserData (eID, wdp->procid, OMPROC_EDIT, wdp->userkey);
2973                  if (omudp != NULL)
2974                     ObjMgrFreeUserData (eID, wdp->procid, wdp->proctype, wdp->userkey);
2975               }
2976         }
2977       }
2978      }
2979      strlens = StringLen(adp->tmpfile);
2980      if (strlens > 0)
2981         FileRemove (adp->tmpfile);
2982      adp = EditAlignDataFree (adp);
2983   }
2984 }
2985 
2986 /*****************************************************************
2987 ***
2988 *** SalsaPanelHasResized
2989 *** FindIdsInSalsaPanel
2990 *** SaveSalsaPanel
2991 *** ResetSalsaTextPanel
2992 *** SalsaTextPanel
2993 *** PopulateSalsaPanel
2994 ***
2995 ***/
2996 #define SIDLAND          1
2997 #define SEQLAND          2
2998 #define BADLAND          3
2999 #define HOLDDNLAND       4
3000 #define HOLDUPLAND       5
3001 /*****************************************************************/
3002 
ViewForGraph(VieweR view,Uint2 entityID,EditAlignDataPtr adp,Int2 width,ValNodePtr anp_graph)3003 static void ViewForGraph (VieweR view, Uint2 entityID, EditAlignDataPtr adp, Int2 width, ValNodePtr anp_graph)
3004 {
3005   SegmenT   pic;
3006   SeqLocPtr slpmaster;
3007   ValNode   vn;
3008   Int4      y_pos = 0;
3009   Int4      scale;
3010   Int4      max_width;
3011   Uint1     style = MSM_MPAIR;
3012 
3013   pic = CreatePicture();
3014   slpmaster = (SeqLocPtr) adp->master.region;
3015   vn.data.ptrvalue = slpmaster;
3016   vn.next = NULL;
3017   max_width = CountMaxSeqLabel(&vn);
3018   scale = FigureMaxScale (&vn, (Int2)width, max_width);
3019   if (scale<=0)
3020      scale = 1;
3021   max_width += 2;
3022   max_width *= scale;
3023   DrawMPAlignment (anp_graph, 0, adp->length-1, slpmaster, entityID, scale, &y_pos, (Uint1)style, FALSE, pic);
3024   AttachPicture (view, pic, -max_width, INT4_MAX, UPPER_LEFT, scale, 1, NULL);
3025 }
3026 
anp_has_feature(AlignNodePtr anp)3027 static Boolean anp_has_feature (AlignNodePtr anp)
3028 {
3029   AlignSegPtr asp;
3030 
3031   if(anp != NULL)
3032   {
3033      for(asp = anp->segs; asp != NULL; asp = asp->next) {
3034         if(asp->cnp != NULL)
3035            return TRUE;
3036      }
3037   }
3038   return FALSE;
3039 }
3040 
getmoltype(SeqIdPtr sip)3041 static Uint1 getmoltype (SeqIdPtr sip)
3042 {
3043   BioseqPtr bsp;
3044   Uint1     moltype;
3045 
3046   if (sip != NULL) {
3047      bsp = BioseqLockById (sip);
3048      if (bsp != NULL) {
3049         moltype = bsp->mol;
3050         BioseqUnlock (bsp);
3051         return moltype;
3052      }
3053   }
3054   return Seq_mol_na;
3055 }
3056 
is_segbioseq(BioseqPtr bsp)3057 static Boolean is_segbioseq (BioseqPtr bsp)
3058 {
3059   BioseqPtr   bigbsp;
3060   SeqEntryPtr sep;
3061 
3062   sep = SeqEntryFind (bsp->id);
3063   if (sep != NULL) {
3064      bigbsp = find_big_bioseq (sep);
3065      if (bigbsp != NULL)
3066      {
3067         if (bigbsp->repr == Seq_repr_seg && bigbsp->length > bsp->length)
3068            return TRUE;
3069      }
3070   }
3071   return FALSE;
3072 }
3073 
getcurrentfeatstyle(EditAlignDataPtr adp)3074 static void getcurrentfeatstyle (EditAlignDataPtr adp)
3075 {
3076   Int2             oldstyle;
3077   Uint1            groupNum;
3078   Int2             j;
3079 
3080   oldstyle = GetMuskCurrentSt ();
3081   SetMuskCurrentSt (GetMuskStyleName (adp->styleNum));
3082   for(j =0; j<FEATDEF_ANY; j++)
3083   {
3084      adp->featOrder[j] = (Uint1)GetMuskCParam(j, MSM_FORDER, MSM_NUM);
3085      groupNum = (Uint1)GetMuskCParam(j, MSM_FGROUP, MSM_NUM);
3086      adp->groupOrder[j] = (Uint1)GetMuskCParam(MSM_GROUPS, (Int2)groupNum, MSM_NUM);
3087   }
3088   SetMuskCurrentSt (GetMuskStyleName (oldstyle));
3089 }
3090 
SetupOptions(Int2 seqnumber)3091 static ValNodePtr SetupOptions (Int2 seqnumber)
3092 {
3093   ValNodePtr  params = NULL;
3094   SeqParamPtr prm;
3095   Int2        j, k;
3096 
3097   if (seqnumber > 0) {
3098    for (j = 0; j < seqnumber; j++) {
3099      prm = (SeqParamPtr) MemNew (sizeof(SeqParam));
3100      prm->entityID = 0;
3101      prm->itemID = 0;
3102      prm->complement = FALSE;
3103      for (k=0; k<6; k++) prm->rf[k] = FALSE;
3104      prm->group = 0;
3105      prm->sip_cons = NULL;
3106      ValNodeAddPointer (&(params), 0, (Pointer) prm);
3107    }
3108   }
3109   return params;
3110 }
3111 
CheckSeqAlignCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)3112 static void CheckSeqAlignCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
3113 {
3114   BioseqPtr          bsp;
3115   BioseqSetPtr       bssp;
3116   SeqAnnotPtr        sap,
3117                      pre;
3118 
3119   if (sep != NULL && sep->data.ptrvalue) {
3120      if (IS_Bioseq(sep)) {
3121         bsp = (BioseqPtr) sep->data.ptrvalue;
3122         if (bsp!=NULL) {
3123            pre=NULL;
3124            sap=bsp->annot;
3125            while (sap!= NULL)
3126            {
3127               if (sap->type == 2) {
3128                  if (is_dim1seqalign ((SeqAlignPtr) sap->data)) {
3129                     if (pre==NULL) {
3130                        bsp->annot=sap->next;
3131                        sap->next=NULL;
3132                        sap = SeqAnnotFree (sap);
3133                        sap=bsp->annot;
3134                     }
3135                     else {
3136                        pre->next=sap->next;
3137                        pre=sap->next;
3138                        sap->next=NULL;
3139                        sap = SeqAnnotFree (sap);
3140                        sap=pre;
3141                     }
3142                  }
3143                  else {
3144                     pre=sap;
3145                     sap=sap->next;
3146                  }
3147               }
3148               else {
3149                  pre=sap;
3150                  sap=sap->next;
3151               }
3152            }
3153         }
3154      }
3155      else if(IS_Bioseq_set(sep)) {
3156         bssp = (BioseqSetPtr)sep->data.ptrvalue;
3157         if (bssp!=NULL) {
3158            pre=NULL;
3159            sap=bssp->annot;
3160            while (sap!= NULL)
3161            {
3162               if (sap->type == 2) {
3163                  if (is_dim1seqalign ((SeqAlignPtr) sap->data)) {
3164                     if (pre==NULL) {
3165                        bssp->annot=sap->next;
3166                        sap->next=NULL;
3167                        sap = SeqAnnotFree (sap);
3168                        sap=bssp->annot;
3169                     }
3170                     else {
3171                        pre=sap->next;
3172                        sap->next=NULL;
3173                        sap = SeqAnnotFree (sap);
3174                        sap=sap->next;
3175                     }
3176                  }
3177                  else {
3178                     pre=sap;
3179                     sap=sap->next;
3180                  }
3181               }
3182               else {
3183                  pre=sap;
3184                  sap=sap->next;
3185               }
3186            }
3187         }
3188      }
3189   }
3190 }
3191 
SetSeqInfo(SeqAlignPtr salp,SelEdStructPtr seq_info)3192 static SelEdStructPtr SetSeqInfo (SeqAlignPtr salp, SelEdStructPtr seq_info)
3193 {
3194   SeqAlignPtr   salptmp;
3195   ValNodePtr    vnp = NULL;
3196   SeqLocPtr     slp;
3197   SeqIdPtr      sip;
3198   Int4          start,
3199                 stop;
3200   Uint1         strand;
3201   Int2          offset;
3202   SelEdStructPtr sesp,
3203                 tmp;
3204 
3205   if (salp==NULL)
3206      return NULL;
3207   for (salptmp=salp; salptmp!=NULL; salptmp=salptmp->next)
3208   {
3209      sip = SeqAlignId(salptmp, 0);
3210      if (sip != NULL)
3211      {
3212         offset = 0;
3213         for (; sip != NULL; sip = sip->next)
3214         {
3215          if ((tmp=is_sip_inseqinfo(sip, seq_info)) == NULL)
3216          {
3217            start = SeqAlignStart (salptmp, offset);
3218            stop = SeqAlignStop (salptmp, offset);
3219            strand = SeqAlignStrand (salptmp, offset);
3220            slp = SeqLocIntNew (start, stop, strand, sip);
3221            if (slp!=NULL) {
3222               sesp=new_seledstruct_fromseqloc(0,0,0,0,0,slp,NULL,NULL,0,0);
3223               seq_info=SelEdStructAdd(seq_info, sesp);
3224            }
3225          }
3226 /***** ???????????????
3227          else if (offset>0) {
3228            tmp->offset++;
3229          }
3230 ***************/
3231          offset++;
3232         }
3233      }
3234   }
3235   return seq_info;
3236 }
3237 
3238 
CheckSeqAlignInSeqEntry(BioseqPtr bsp)3239 static void CheckSeqAlignInSeqEntry (BioseqPtr bsp)
3240 {
3241   SeqEntryPtr      sep,
3242                    sep_head;
3243   Uint2            entityID;
3244 
3245   sep = SeqMgrGetSeqEntryForData (bsp);
3246   entityID = ObjMgrGetEntityIDForChoice (sep);
3247   sep_head = GetTopSeqEntryForEntityID (entityID);
3248   SeqEntryExplore (sep_head, NULL, CheckSeqAlignCallback);
3249   return;
3250 }
3251 
3252 
BioseqToEditAlignData(EditAlignDataPtr adp,BioseqPtr bsp,Uint1 showfeature)3253 static EditAlignDataPtr BioseqToEditAlignData (EditAlignDataPtr adp, BioseqPtr bsp, Uint1 showfeature)
3254 {
3255   SeqEntryPtr      sep;
3256   ValNodePtr       vnp;
3257   SeqLocPtr        slp;
3258   SeqAlignPtr      salp;
3259   SeqAnnotPtr      sap;
3260   AlignNodePtr     anp;
3261 
3262   if (adp == NULL)
3263       return NULL;
3264   if (showfeature)  {
3265      adp->showfeat = TRUE;
3266      getcurrentfeatstyle (adp);
3267   }
3268   adp->input_format = OBJ_BIOSEQ;
3269   sep = SeqEntryNew ();
3270   if ( sep == NULL )  {
3271      MemFree (adp);
3272      return NULL;
3273   }
3274   sep->choice = 1;
3275   sep->data.ptrvalue = (Pointer) bsp;
3276   vnp = SeqEntryToSeqLoc (sep, &(adp->seqnumber), bsp->mol);
3277   if (vnp == NULL) {
3278      MemFree (adp);
3279      return NULL;
3280   }
3281   adp->sqloc_list = vnp;
3282   adp->bsqloc_list = SeqEntryToSeqLoc (sep, &(adp->seqnumber), bsp->mol);
3283   adp->size_labels = getsize_seqids (adp->sqloc_list, adp->printid);
3284   adp->params = SetupOptions  (adp->seqnumber);
3285   adp->length = MaxLengthSeqLoc (adp->sqloc_list);
3286   salp = SeqLocToFastaSeqAlign (adp->sqloc_list);
3287   sap = SeqAnnotForSeqAlign (salp);
3288   slp = (SeqLocPtr) vnp->data.ptrvalue;
3289   adp->master.region = (Pointer) SeqLocFromSeqAlign (salp, NULL);
3290   if ( adp->master.region == NULL ) {
3291      MemFree (adp);
3292      return NULL;
3293   }
3294   adp->master.regiontype = 1;
3295   adp->caret.regiontype = 1;
3296   adp->caret.region = SeqLocIntNew (0, 0, Seq_strand_plus, SeqLocId ((SeqLocPtr)adp->master.region));
3297 
3298   adp->mol_type = bsp->mol;
3299   if (ISA_aa(adp->mol_type)) {
3300      adp->colorRefs[COLOR_SELECT] = GetColorRGB(255, 255, 0);
3301   }
3302   else {
3303      adp->colorRefs[COLOR_SELECT] = GetColorRGB(0, 0, 0);
3304   }
3305   if (adp->display_panel==0 || adp->display_panel==1 || adp->display_panel==2)
3306   {
3307      adp->anp_list = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr) adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MD, FALSE, FALSE, FALSE);
3308   }
3309   else if (adp->display_panel == 3) {
3310      adp->anp_list = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr) adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MP, TRUE, FALSE, FALSE);
3311   }
3312   if (adp->display_panel==2) {
3313      adp->anp_graph = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr)adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MP, TRUE, FALSE, FALSE);
3314   }
3315   clean_annot_for_anp (&(adp->anp_list));
3316   if ( adp->anp_list ==NULL ) {
3317      MemFree (adp);
3318      return NULL;
3319   }
3320   if (showfeature) {
3321      adp->seqfeat = SeqfeatlistFree (adp->seqfeat);
3322      for (vnp = adp->anp_list; vnp != NULL; vnp = vnp->next) {
3323         anp = (AlignNodePtr)vnp->data.ptrvalue;
3324         if (anp!=NULL && anp_has_feature(anp)) {
3325            slp = CollectSeqLocFromAlignNode (anp);
3326            adp->seqfeat=CollectFeatureForEditor (slp, adp->seqfeat, anp->seq_entityID, anp->bsp_itemID, adp->featOrder, FALSE);
3327         }
3328      }
3329   }
3330   adp->gr.left = 0;
3331   adp->gr.right = adp->length;
3332   adp->sap_align = SeqAnnotDenseSegToBoolSeg (sap);
3333   adp->sap_original = sap;
3334   sep->data.ptrvalue = NULL;
3335   SeqEntryFree (sep);
3336   adp = SetupDataBuffer (adp);
3337   adp = SetupDataPanel  (adp);
3338   if (adp!=NULL)
3339   {
3340      adp->seg_bioseq = is_segbioseq (bsp);
3341      CheckSeqAlignInSeqEntry (bsp);
3342      adp->seq_info = SetSeqInfo ((SeqAlignPtr)adp->sap_align->data, seq_info);
3343   }
3344   return adp;
3345 }
3346 
3347 /***************************************************************
3348 *** SeqAlignToEditAlignData
3349 *** SetupAlignDataSap
3350 ******************************************************************/
3351 
SeqAlignList2PosStrand(SeqAlignPtr salp)3352 static SeqAlignPtr SeqAlignList2PosStrand (SeqAlignPtr salp)
3353 {
3354   SeqAlignPtr salptmp;
3355   Int4Ptr     lenp;
3356   Int4Ptr     startp;
3357   Uint1Ptr    strandp;
3358   Int4        numseg;
3359   Int2        dim;
3360   Int4        j, k, n, tmp;
3361 
3362 
3363 for (salptmp=salp; salptmp!=NULL; salptmp=salptmp->next)
3364 {
3365   if ((SeqAlignStrand(salptmp,0) == Seq_strand_minus)
3366    && (SeqAlignStrand(salptmp,1) != Seq_strand_minus))
3367   {
3368      if (salptmp->segtype == 2)
3369      {
3370          DenseSegPtr dsp;
3371         dsp = (DenseSegPtr) salptmp->segs;
3372         strandp = dsp->strands;
3373         numseg = dsp->numseg;
3374         dim = dsp->dim;
3375         lenp = dsp->lens;
3376         startp = dsp->starts;
3377         for (j=0; j < numseg*dim && strandp!=NULL; j++, strandp++)
3378             {
3379                 if (*strandp == Seq_strand_minus)
3380                     *strandp = Seq_strand_plus;
3381                 else if (*strandp != Seq_strand_minus)
3382                     *strandp = Seq_strand_minus;
3383             }
3384         for (j=0, k=numseg-1; j<numseg/2; j++, k--) {
3385             tmp=lenp[j];
3386             lenp[j]=lenp[k];
3387             lenp[k]=tmp;
3388         }
3389         for (j=0, k=(dim*numseg-dim); j<(dim*numseg-1)/2; j+=dim, k-=dim) {
3390             for (n=0; n<dim; n++) {
3391                 tmp=startp[j+n];
3392                 startp[j+n]=startp[k+n];
3393                 startp[k+n]=tmp;
3394             }
3395         }
3396      }
3397   }
3398 }
3399 return salp;
3400 }
3401 
SetupAlignDataSap(EditAlignDataPtr adp,SeqAlignPtr salp_original,SeqIdPtr mastersip)3402 static Boolean SetupAlignDataSap (EditAlignDataPtr adp, SeqAlignPtr salp_original, SeqIdPtr mastersip)
3403 {
3404   SeqAnnotPtr  sap,
3405                saptmp;
3406   SeqAlignPtr  newsalp,
3407                salp,
3408                salp1;
3409 
3410   Uint2        entityID_sap;
3411 
3412   if (adp == NULL || salp_original == NULL)
3413      return FALSE;
3414 
3415   /*************************************/
3416   /** check if all ->type are NOT 0
3417   *** if all 0 -> all cached from CN3D viewer
3418   **************/
3419   for (newsalp = salp_original; newsalp!=NULL; newsalp=newsalp->next)
3420      if (newsalp->type > 0)
3421         break;
3422   if (newsalp== NULL)
3423      return FALSE;
3424   /**************************************/
3425   if (salp_original->segtype == SAS_DISC)
3426   {
3427   	salp_original = (SeqAlignPtr) salp_original->segs;
3428   }
3429 
3430 
3431   if ( salp_original->segtype == 1 )
3432   {
3433      adp->blocks = create_list_alignedsegs (salp_original);
3434      salp = DenseDiagToDenseSeg (salp_original, TRUE);
3435      adp->sap1_original = SeqAnnotForSeqAlign (salp_original);
3436   }
3437   else
3438      salp = salp_original;
3439 
3440   if ( salp->segtype == 2 )
3441   {
3442 /*************/
3443          adp->sap_original = SeqAnnotForSeqAlign (salp);
3444 /************/
3445          saptmp = SeqAnnotForSeqAlign (salp);
3446          sap = (SeqAnnotPtr) AsnIoMemCopy (saptmp, (AsnReadFunc) SeqAnnotAsnRead, (AsnWriteFunc) SeqAnnotAsnWrite);
3447          saptmp->data=NULL;
3448          saptmp = SeqAnnotFree(saptmp);
3449          if (sap == NULL)
3450          {
3451             return FALSE;
3452          }
3453          salp = (SeqAlignPtr)sap->data;
3454 
3455 
3456 /*       if (is_dim2seqalign(salp)) || (salp->dim==2 && adp->display_panel==1))
3457 */
3458 {{
3459 salp = SeqAlignList2PosStrand(salp);
3460 }}
3461          if (is_dim2seqalign (salp))
3462          {
3463             salp1 = (SeqAlignPtr) sap->data;
3464             sap->data=NULL;
3465             sap = SeqAnnotFree(sap);
3466 /*
3467             salp1 = SortSeqAlign (&salp1);
3468 */
3469             sap = multseqalign_from_pairseqalign (salp1);
3470             SeqAlignSetFree (salp1);
3471             if (sap == NULL)
3472             {
3473                return FALSE;
3474             }
3475          }
3476          newsalp = (SeqAlignPtr) sap->data;
3477          adp->seqnumber = newsalp->dim;
3478          adp->sqloc_list = SeqLocListFromSeqAlign (newsalp);
3479          adp->bsqloc_list = SeqLocListOfBioseqsFromSeqAlign (newsalp);
3480          adp->printid = PRINTID_TEXTID_ACCESSION;
3481          adp->size_labels = getsize_seqids (adp->sqloc_list, adp->printid);
3482          adp->params = SetupOptions  (adp->seqnumber);
3483 
3484          entityID_sap=ObjMgrRegister (OBJ_SEQANNOT, (Pointer)sap);
3485 
3486          adp->master.region=(Pointer)SeqLocFromSeqAlign(newsalp, mastersip);
3487          if (adp->master.region == NULL ) {
3488             adp->master.region=(Pointer)SeqLocFromSeqAlign(newsalp,NULL);
3489          }
3490          adp->master.regiontype = 1;
3491          if (adp->display_panel==0 || adp->display_panel==1 || adp->display_panel==2)
3492          {
3493             adp->anp_list = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr) adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MD, FALSE, FALSE, FALSE);  }
3494          else if (adp->display_panel == 3)
3495          {
3496             adp->anp_list = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr) adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MP, TRUE, FALSE, FALSE);
3497          }
3498          if (adp->display_panel==2) {
3499             adp->anp_graph = (ValNodePtr) CollAlignFromSeqAnnot (sap, (SeqLocPtr)adp->master.region, adp->featOrder, adp->groupOrder, COLLECT_MP, TRUE, FALSE, FALSE);
3500          }
3501          clean_annot_for_anp(&(adp->anp_list));
3502          if ( adp->anp_list == NULL ) {
3503             adp->seqnumber = 0;
3504             return FALSE;
3505          }
3506          adp->length = GetAlignLengthFromAlignNode ((AlignNodePtr) adp->anp_list->data.ptrvalue);
3507          adp->gr.left = 0;
3508          adp->gr.right = adp->length;
3509          salp1 = SeqAlignDenseSegToBoolSeg (newsalp);
3510 
3511          adp->sap_align = SeqAnnotForSeqAlign (salp1);
3512          adp->mol_type = getmoltype (SeqLocId((SeqLocPtr)adp->master.region));
3513          if (ISA_aa(adp->mol_type))
3514          {
3515             adp->colorRefs[COLOR_SELECT] = GetColorRGB(255, 255, 0);
3516          }
3517          else {
3518             adp->colorRefs[COLOR_SELECT] = GetColorRGB(0, 0, 0);
3519          }
3520          sap = SeqAnnotFree (sap);
3521          ObjMgrDelete (OBJ_SEQANNOT, (Pointer)sap);
3522   }
3523   return TRUE;
3524 }
3525 
SeqAlignBioseqRegister(SeqAlignPtr salp,Uint2 * entityID,Uint4 * itemID)3526 static void SeqAlignBioseqRegister (SeqAlignPtr salp, Uint2 *entityID, Uint4 *itemID)
3527 {
3528   SeqAlignPtr tmp;
3529   SeqIdPtr    sip;
3530   Int2        j;
3531   Uint2       eID=0;
3532   Uint4       iID=0;
3533   Boolean     first=TRUE;
3534 
3535   for (tmp=salp; tmp!=NULL; tmp=tmp->next)
3536   {
3537      for (j=0; j<tmp->dim; j++)
3538      {
3539         sip=SeqAlignId (tmp, j);
3540         eID = BioseqFindEntity (sip, &iID);
3541         if (first) {
3542            *entityID = eID;
3543            *itemID = iID;
3544            first = FALSE;
3545         }
3546      }
3547   }
3548 }
3549 
SeqAlignToEditAlignData(EditAlignDataPtr adp,SeqAlignPtr salp,Int4 start,SeqIdPtr mastersip,Uint1 showfeature)3550 static EditAlignDataPtr SeqAlignToEditAlignData (EditAlignDataPtr adp, SeqAlignPtr salp, Int4 start, SeqIdPtr mastersip, Uint1 showfeature)
3551 {
3552   AlignNodePtr     anp;
3553   SeqLocPtr        slp;
3554   SeqIdPtr         sip;
3555   ValNodePtr       vnp;
3556   BioseqPtr        bsp;
3557   Boolean          ok=FALSE;
3558 
3559   if (adp == NULL || salp == NULL)
3560      return NULL;
3561   if (SeqAlignMolType (salp) == 0)
3562      return NULL;
3563   if (salp!=NULL)
3564   {
3565      SeqAlignBioseqRegister (salp, &(adp->master.entityID), &(adp->master.itemID));
3566      adp->master.itemtype = OBJ_BIOSEQ;
3567      if (showfeature)
3568      {
3569         adp->showfeat = TRUE;
3570         getcurrentfeatstyle (adp);
3571      }
3572      adp->input_format = OBJ_SEQALIGN;
3573      ok = SetupAlignDataSap (adp, salp, mastersip);
3574   }
3575   if (!ok) {
3576      adp->input_format = OBJ_BIOSEQ;
3577      bsp = BioseqLockById (mastersip);
3578      if (bsp) {
3579         adp = BioseqToEditAlignData (adp, bsp, showfeature);
3580         ok = (Boolean) (adp!=NULL);
3581         if (adp!=NULL)
3582            adp->sap_original = SeqAnnotForSeqAlign (salp);
3583         BioseqUnlock (bsp);
3584      }
3585   }
3586   if (ok)
3587   {
3588         if (showfeature == SEQ_FEAT1 && mastersip != NULL) {
3589            adp->seqfeat = SeqfeatlistFree (adp->seqfeat);
3590            for (vnp = adp->anp_list; vnp != NULL; vnp = vnp->next) {
3591               anp = (AlignNodePtr)vnp->data.ptrvalue;
3592               if (anp!=NULL) {
3593                  for (sip=mastersip; sip!=NULL; sip=sip->next) {
3594                     if (SeqIdForSameBioseq(anp->sip, sip)) {
3595                        if(anp_has_feature(anp)) {
3596                           slp = CollectSeqLocFromAlignNode (anp);
3597                           adp->seqfeat=CollectFeatureForEditor (slp, adp->seqfeat, anp->seq_entityID, anp->bsp_itemID, adp->featOrder, FALSE);
3598                           break;
3599                        }
3600                     }
3601                  }
3602               }
3603            }
3604         }
3605         else if (showfeature) {
3606            adp->seqfeat = SeqfeatlistFree (adp->seqfeat);
3607            for (vnp = adp->anp_list; vnp != NULL; vnp = vnp->next) {
3608               anp = (AlignNodePtr)vnp->data.ptrvalue;
3609               if (anp!=NULL) {
3610                  if (anp_has_feature(anp)) {
3611                     slp = CollectSeqLocFromAlignNode (anp);
3612                     adp->seqfeat=CollectFeatureForEditor (slp, adp->seqfeat, anp->seq_entityID, anp->bsp_itemID, adp->featOrder, FALSE);
3613                  }
3614               }
3615            }
3616         }
3617         adp->caret.regiontype = 1;
3618         adp->caret.region = SeqLocIntNew (start, start, Seq_strand_plus, SeqLocId((SeqLocPtr)adp->master.region));
3619         adp = SetupDataBuffer (adp);
3620         adp = SetupDataPanel  (adp);
3621         if (adp!=NULL && adp->seqnumber > 1) {
3622            adp->draw_scale = TRUE;
3623            adp->draw_bars = TRUE;
3624            adp->marginwithindex = FALSE;
3625            adp->marginwithIds = TRUE;
3626            adp->marginwithgroup = FALSE;
3627         }
3628         if (adp!=NULL) {
3629            adp->seq_info = SetSeqInfo (salp, seq_info);
3630            return adp;
3631         }
3632   }
3633   adp = EditAlignDataFree (adp);
3634   return NULL;
3635 }
3636 
SalsaPanelHasResized(PaneL pnl)3637 extern void SalsaPanelHasResized (PaneL pnl)
3638 {
3639   EditAlignDataPtr adp;
3640   RecT             rp;
3641 
3642   GetPanelExtra (pnl, &adp);
3643   if (adp != NULL) {
3644      get_client_rect (pnl, &rp);
3645      do_resize_panel (pnl, adp, (Int2)(rp.right - rp.left), (Int2)(rp.bottom - rp.top), TRUE);
3646   }
3647   SetPanelExtra (pnl, &adp);
3648 }
3649 
FindIdsInSalsaPanel(PaneL pnl,PoinT pt,Uint2 * entityID,Uint4 * itemID,Uint2 * itemtype)3650 extern Boolean FindIdsInSalsaPanel (PaneL pnl, PoinT pt, Uint2 *entityID, Uint4 *itemID, Uint2 *itemtype)
3651 {
3652   EditAlignDataPtr adp;
3653   RecT             rp;
3654   Int4             pos;
3655   Int2             line;
3656   Uint4            iID;
3657   Uint2            eID, itype, isubtype;
3658   Uint1            what;
3659   SeqAlignPtr      salp;
3660 
3661   *entityID = 0;
3662   *itemID = 0;
3663   *itemtype = 0;
3664   GetPanelExtra (pnl, &adp);
3665   if (adp != NULL) {
3666      get_client_rect (pnl, &rp);
3667      what = locate_point (pt, rp, &iID, &eID, &itype, &isubtype, &pos, &line, adp);
3668      if (what == SIDLAND || (what == SEQLAND && adp->seqnumber == 1)) {
3669         if (eID) {
3670            *entityID = eID;
3671            *itemID = iID;
3672            *itemtype = itype;
3673            return TRUE;
3674         }
3675      }
3676      if (what == SEQLAND) {
3677         salp = SeqAlignBoolSegToDenseSeg((SeqAlignPtr)adp->sap_align->data);
3678         *entityID = ObjMgrRegister (OBJ_SEQALIGN, (Pointer) salp);
3679         *itemID = 1;
3680         *itemtype = OBJ_SEQALIGN;
3681         return TRUE;
3682      }
3683   }
3684   return FALSE;
3685 }
3686 
SaveSalsaPanel(PaneL pnl)3687 extern void SaveSalsaPanel (PaneL pnl)
3688 {
3689   Char             namep [PATH_MAX];
3690   EditAlignDataPtr adp;
3691   Int4             start, stop;
3692   FILE             *fout;
3693 
3694   if (!GetOutputFileName (namep, PATH_MAX, NULL))
3695      return;
3696   GetPanelExtra (pnl, &adp);
3697   if (adp != NULL) {
3698      fout = FileOpen (namep, "w");
3699      if (fout != NULL) {
3700         WatchCursor ();
3701         start = 0;
3702         stop = adp->length -1;
3703         ShowAlignmentText (fout, adp, NULL, adp->marginleft, start, stop, FALSE);
3704         ArrowCursor ();
3705         FileClose (fout);
3706      }
3707   }
3708 }
3709 
ResetSalsaTextPanel(PaneL pnl)3710 static void ResetSalsaTextPanel (PaneL pnl)
3711 {
3712   EditAlignDataPtr adp;
3713 
3714   GetPanelExtra (pnl, &adp);
3715   if (adp != NULL) {
3716     adp = EditAlignDataFree (adp);
3717   }
3718   SetPanelExtra (pnl, &adp);
3719 }
3720 
SalsaTextPanel(GrouP g,Int2 wid,Int2 hgt)3721 extern PaneL SalsaTextPanel (GrouP g, Int2 wid, Int2 hgt)
3722 {
3723   PaneL pnl;
3724   pnl = AutonomousPanel4 (g, wid, hgt, on_draw, VscrlProc, NULL,
3725                          sizeof (EditAlignDataPtr), ResetSalsaTextPanel, NULL);
3726   return pnl;
3727 }
3728 
PopulateSalsaPanel(PaneL pnl,SeqEntryPtr sep,Boolean all_seq,Uint1 sequence_shown,Uint1 show_feat,Uint1 numbering,FonT font)3729 extern void PopulateSalsaPanel (PaneL pnl, SeqEntryPtr sep, Boolean all_seq, Uint1 sequence_shown, Uint1 show_feat, Uint1 numbering, FonT font)
3730 {
3731   EditAlignDataPtr adp = NULL;
3732   BioseqPtr        bsp = NULL;
3733   SeqAlignPtr      salp = NULL;
3734   RecT             rp;
3735   Int2             height, width;
3736   Uint2            entityID;
3737   Uint4            itemID;
3738   SeqEditViewProcsPtr  svpp;
3739 
3740   if (sep == NULL)
3741      return;
3742   get_client_rect (pnl, &rp);
3743   width = (rp.right -rp.left);
3744   height = (rp.bottom -rp.top);
3745 
3746   if (all_seq || sequence_shown != SEQ_SHOW1)
3747      salp = (SeqAlignPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN);
3748 
3749   if (salp==NULL && IS_Bioseq(sep)) {
3750      bsp = (BioseqPtr) sep->data.ptrvalue;
3751      if (bsp != NULL) {
3752         adp = EditAlignDataInit(NULL,width,height,MARGINLEFT15,10,font, TRUE, 1);
3753         adp->Cn3D_On = FALSE;
3754         svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
3755         if (svpp)
3756            adp->Cn3D_On =svpp->Cn3D_On;
3757 
3758         adp = BioseqToEditAlignData (adp, bsp, show_feat);
3759      }
3760   }
3761   if (salp!=NULL) {
3762      get_client_rect (pnl, &rp);
3763      adp =EditAlignDataInit(NULL,width,height, MARGINLEFT15, 10, font, TRUE, 1);
3764      adp->Cn3D_On = FALSE;
3765      svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
3766      if (svpp)
3767         adp->Cn3D_On =svpp->Cn3D_On;
3768 
3769      if (IS_Bioseq(sep)) {
3770         bsp = (BioseqPtr) sep->data.ptrvalue;
3771         adp = SeqAlignToEditAlignData (adp, salp, 0, bsp->id, show_feat);
3772      }
3773      else {
3774         adp = SeqAlignToEditAlignData (adp, salp, 0, NULL, show_feat);
3775      }
3776   }
3777   if (adp != NULL)
3778   {
3779      adp->font = (Handle)(font);
3780      adp->draw_emptyline = FALSE;
3781      SetPanelExtra (pnl, &adp);
3782      adp->marginwithindex = FALSE;
3783      adp->marginwithfeatid = TRUE;
3784      adp->all_sequences = all_seq;
3785      if (!all_seq) {
3786         adp->charmode = TRUE;
3787         if (sequence_shown>SEQ_NUM1 && IS_Bioseq(sep)) {
3788            entityID = ObjMgrGetEntityIDForChoice (sep);
3789            bsp = (BioseqPtr) sep->data.ptrvalue;
3790            BioseqFindEntity (bsp->id, &itemID);
3791            adp->master.entityID = entityID;
3792            adp->master.itemID = itemID;
3793         }
3794      }
3795      if (numbering == SEQ_NUM1) {
3796         adp->draw_scale = FALSE;
3797         adp->draw_bars = FALSE;
3798         adp->marginwithpos = TRUE;
3799         adp->marginwithgroup = FALSE;
3800      }
3801      else if (numbering == SEQ_NUM2) {
3802         adp->draw_scale = TRUE;
3803         adp->draw_bars = TRUE;
3804         adp->marginwithpos = TRUE;
3805         adp->marginwithgroup = FALSE;
3806      }
3807      else {
3808         adp->draw_scale = FALSE;
3809         adp->draw_bars = FALSE;
3810         adp->marginwithpos = FALSE;
3811         adp->marginwithgroup = FALSE;
3812      }
3813      do_resize_panel(pnl,adp, width, height, TRUE);
3814      checkselectsequinfeature_for_editor (adp->seqfeat);
3815   }
3816 }
3817 
3818 
EditAlignDataRepopulateFromSeqAlign(PaneL pnl,EditAlignDataPtr adp,SeqAlignPtr salp)3819 extern EditAlignDataPtr EditAlignDataRepopulateFromSeqAlign (PaneL pnl, EditAlignDataPtr adp, SeqAlignPtr salp)
3820 {
3821   EditAlignDataPtr adpnew;
3822   RecT rp;
3823   float hratio;
3824 
3825   get_client_rect (pnl, &rp);
3826   adpnew = EditAlignDataReset (adp, (rp.right-rp.left), (rp.bottom-rp.top), salp);
3827   if (adpnew == NULL) {
3828      return adp;
3829   }
3830   adp = adpnew;
3831   do_resize_window  (pnl, adp, TRUE);
3832   reset_features (pnl, adp);
3833   hratio = (float)adp->hoffset / (float)adp->length;
3834   SeqEdSetCorrectBarMax (pnl, adp, hratio);
3835   adp->dirty = TRUE;
3836   return adp;
3837 }
3838 
SeqEditViewFormNew(void)3839 static SeqEditViewFormPtr SeqEditViewFormNew (void)
3840 {
3841   SeqEditViewFormPtr wdp;
3842 
3843   wdp = (SeqEditViewFormPtr) MemNew (sizeof (SeqEditViewForm));
3844   wdp->pnl = NULL;
3845   wdp->data = NULL;
3846   wdp->graph = NULL;
3847 
3848   wdp->pos = NULL;
3849   wdp->gototxt = NULL;
3850   wdp->lookattxt = NULL;
3851   wdp->gotobt = NULL;
3852   wdp->lookatbt = NULL;
3853 
3854   wdp->rfitem[0] = NULL;  wdp->rfitem[1] = NULL; wdp->rfitem[2] = NULL;
3855   wdp->rfitem[3] = NULL;  wdp->rfitem[4] = NULL; wdp->rfitem[5] = NULL;
3856   wdp->rfitem[6] = NULL;  wdp->rfitem[7] = NULL; wdp->rfitem[8] = NULL;
3857   wdp->rfitem[9] = NULL;
3858   wdp->btngp = NULL;
3859   wdp->editmodeitem = NULL;
3860   wdp->viewmodeitem=NULL;
3861   wdp->showfeatbt = NULL;
3862   wdp->showfeatitem = NULL;
3863   wdp->hidefeatitem = NULL;
3864   wdp->translatebt = NULL;
3865   wdp->translateitem = NULL;
3866   wdp->codonstitem = NULL;
3867   wdp->savefeatbt = NULL;
3868   wdp->savefeatitem = NULL;
3869   wdp->refreshbt = NULL;
3870   wdp->closebt = NULL;
3871   wdp->svclosebt = NULL;
3872   wdp->cutitem = NULL;
3873   wdp->insitem = NULL;
3874   wdp->delitem = NULL;
3875   wdp->copyitem = NULL;
3876   wdp->pasteitem = NULL;
3877   wdp->selmaster = NULL;
3878   wdp->showdifitem = NULL;
3879   wdp->showallitem = NULL;
3880 
3881   wdp->extended_align_menu = FALSE;
3882   wdp->extended_dist_menu = FALSE;
3883   wdp->extended_tree_menu = FALSE;
3884 
3885   return wdp;
3886 }
3887 
3888 
3889 /********************************************
3890 ***
3891 ***    Create new Window from SeqAlign
3892 ***
3893 ***********************************************/
CreateSeqAlignEditForm(Int2 left,Int2 top,CharPtr windowname,SeqAlignPtr salp,Pointer dummy)3894 static ForM CreateSeqAlignEditForm (Int2 left, Int2 top, CharPtr windowname, SeqAlignPtr salp, Pointer dummy)
3895 {
3896   SeqEditViewProcsPtr  svpp;
3897   WindoW             w;
3898   SeqEditViewFormPtr wdp;
3899   EditAlignDataPtr   adp;
3900   PaneL              pnl;
3901   GrouP              g;
3902   RecT               rw,    /* window rect */
3903                      rp,    /* panel rect  */
3904                      rb;    /* button rect */
3905   PopuP              pop;
3906   SeqEntryPtr        sep = NULL;
3907   SelStructPtr       ssp = NULL;
3908   Char               str [16];
3909   Int4               start = 0;
3910   Int2               window_width = 650,
3911                      wid,
3912                      window_hgt = 300,
3913                      hgt,
3914                      charwidth, lineheight;
3915   Uint1              display_panel = 0;
3916   Uint1              showfeat = 0;
3917   Uint1              moltype = 0;
3918   FonT               font;
3919   Boolean            is_prot = FALSE,
3920                      ble;
3921 
3922   if (salp==NULL)
3923      return NULL;
3924 
3925   moltype = SeqAlignMolType(salp);
3926   if (moltype == 0)
3927      return NULL;
3928   is_prot = (Boolean)(ISA_aa(moltype));
3929   wdp = SeqEditViewFormNew ();
3930   if (wdp==NULL)
3931      return NULL;
3932 
3933 #ifdef WIN_MAC
3934   font = ParseFont ("Monaco, 9");
3935 #endif
3936 #ifdef WIN_MSWIN
3937   font = ParseFont ("Courier, 9");
3938 #endif
3939 #ifdef WIN_MOTIF
3940   font = ParseFont ("fixed, 12");
3941 #endif
3942   SelectFont (font);
3943   charwidth  = CharWidth ('0');
3944   lineheight = LineHeight ();
3945 
3946   w = DocumentWindow (left, top, (Int2)(-10), (Int2)(-10),  windowname, NULL, ResizeAlignDataWindow);
3947   SetObjectExtra (w, (Pointer) wdp, CleanupSequenceEditorForm);
3948   wdp->form = (ForM) w;
3949   wdp->formmessage = SalsaFormMessage;
3950   svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
3951   if (svpp != NULL) {
3952       SetActivate (w, svpp->activateForm);
3953       wdp->appmessage = svpp->handleMessages;
3954       wdp->extended_align_menu = svpp->extended_align_menu;
3955       wdp->extended_dist_menu = svpp->extended_dist_menu;
3956       wdp->extended_tree_menu = svpp->extended_tree_menu;
3957       showfeat = svpp->showfeat;
3958 
3959 /*** BECAUSE it crashes if tries to load the features  **/
3960 /*** before getting the entityIDs of the sequences     **/
3961       showfeat = FALSE;
3962       if (svpp->minPixelWidth > 0) {
3963          window_width = svpp->minPixelWidth;
3964          if (window_width > 800)
3965             window_width = 800;
3966       }
3967       if (svpp->minPixelHeight > 0) {
3968          window_hgt = svpp->minPixelHeight;
3969          if (window_hgt > 300)
3970             window_hgt = 300;
3971       }
3972   }
3973   wid = (Int2)(window_width/charwidth);
3974   hgt = (Int2)(window_hgt / lineheight);
3975 
3976   if (dummy != NULL) {
3977      ssp = (SelStructPtr) dummy;
3978      if (ssp->regiontype>0)
3979         display_panel = ssp->regiontype;
3980   }
3981   adp = EditAlignDataInit (NULL, wid, hgt, MARGINLEFT25, 10, font, FALSE, display_panel);
3982   adp->Cn3D_On = FALSE;
3983   if (svpp)
3984      adp->Cn3D_On =svpp->Cn3D_On;
3985   if (dummy != NULL) {
3986      ssp = (SelStructPtr) dummy;
3987      adp->input_entityID = ssp->entityID;
3988      adp->input_itemID = ssp->itemID;
3989      adp->input_itemtype = ssp->itemtype;
3990      if (ssp->region!=NULL)
3991         start = (Int4)SeqLocStart((SeqLocPtr)ssp->region);
3992   }
3993   else {
3994      adp->input_entityID = 0;
3995      adp->input_itemID = 0;
3996      adp->input_itemtype = 0;
3997   }
3998   adp = SeqAlignToEditAlignData (adp, salp, start, NULL, showfeat);
3999   if (adp == NULL)
4000      return NULL;
4001   adp->wdp = (Pointer) wdp;
4002   if (svpp == NULL)
4003   {
4004      adp->edit_mode = ALIGN_EDIT;
4005      SetupMenus (w, TRUE, is_prot, FALSE, FALSE, FALSE, FALSE);
4006   }
4007   else
4008   {
4009      if (svpp->viewer_mode)
4010         adp->edit_mode = SEQ_VIEW;
4011      else
4012         adp->edit_mode = ALIGN_EDIT;
4013      ble = (Boolean)(!svpp->viewer_mode);
4014      SetupMenus (w, TRUE, is_prot, ble, svpp->extended_dist_menu, svpp->extended_align_menu, svpp->extended_tree_menu);
4015   }
4016   if (!is_prot)
4017   {
4018      g = HiddenGroup (w, 5, 0, NULL);
4019      sprintf (str, "%ld", (long) adp->caret_orig);
4020      wdp->gotobt = PushButton (g, "Go to:", GoToButton);
4021      wdp->gototxt = DialogText (g, str, (Int2)6, NULL);
4022      wdp->lookatbt = PushButton (g, "Look at:", LookAtButton);
4023      wdp->lookattxt = DialogText (g, str, (Int2)6, NULL);
4024      pop = PopupList (g, TRUE, SelectFeatEditMode);
4025      PopupItem (pop, "Merge feature mode");
4026      PopupItem (pop, "Split feature mode");
4027      SetValue (pop, 1);
4028   }
4029   else {
4030      g = HiddenGroup (w, 4, 0, NULL);
4031      sprintf (str, "%ld", (long) adp->caret_orig);
4032      wdp->gotobt = PushButton (g, "Go to:", GoToButton);
4033      wdp->gototxt = DialogText (g, str, (Int2)6, NULL);
4034      wdp->lookatbt = PushButton (g, "Look at:", LookAtButton);
4035      wdp->lookattxt = DialogText (g, str, (Int2)6, NULL);
4036   }
4037 
4038   g = HiddenGroup (w, 1, 0, NULL);
4039   wdp->pos = StaticPrompt (g, "", window_width, dialogTextHeight, programFont, 'l');
4040 
4041   g = HiddenGroup (w, 1, 0, NULL);
4042 /************************* HORIZONTAL SCROLLBAR>>*****************
4043   if (is_prot)
4044   {
4045      pnl = AutonomousPanel4 (g, window_width, window_hgt, on_draw, NULL,
4046                             HscrlProc, sizeof (EditAlignDataPtr), NULL, NULL);
4047      adp->vscrollbar_mode = FALSE;
4048   }
4049   else
4050 ****************************************************************/
4051      pnl = AutonomousPanel4 (g, window_width, window_hgt, on_draw, VscrlProc,
4052                             NULL, sizeof (EditAlignDataPtr), NULL, NULL);
4053   SetPanelExtra (pnl, &adp);
4054   SetObjectExtra (pnl, (Pointer) adp, CleanupAlignDataPanel);
4055   wdp->pnl = pnl;
4056 
4057   if (!is_prot) {
4058      wdp->btngp = HiddenGroup (w, 5, 0, NULL);
4059      wdp->showfeatbt= PushButton (wdp->btngp, "Show feat.", ShowFeatureButtonProc);
4060      wdp->translatebt = PushButton (wdp->btngp, "Translate", TranslateButton);
4061      wdp->savefeatbt = PushButton (wdp->btngp, "Save CDS", SaveFeatureButton);
4062      wdp->refreshbt = PushButton (wdp->btngp, "Refresh", RefreshAlignDataButton);
4063      wdp->closebt = PushButton (wdp->btngp, "Dismiss", CloseWindowButton);
4064   }
4065   update_sequenceeditormenu (wdp, adp);
4066 
4067   RealizeWindow (w);
4068 
4069   ObjectRect (w, &rw);
4070   GetPosition (pnl, &rp);
4071   adp->xoff = rp.left;
4072   adp->yoff = rp.top;
4073   adp->x = (rw.right -rw.left+1) - (rp.right -rp.left+1) - rp.left;
4074   adp->y = (rw.bottom-rw.top +1) - (rp.bottom-rp.top +1) - rp.top;
4075 
4076   if (!is_prot) {
4077      GetPosition (wdp->closebt, &rb);
4078      adp->ybutt = (rw.bottom-rw.top +1) - (rb.bottom-rb.top +1) - rb.top;
4079   }
4080 
4081   if (dummy != NULL) {
4082      adp->voffset = hoffset2voffset(adp, adp->anp_list, adp->visibleWidth, 0, adp->length-1, start);
4083   }
4084   SetPanelClick(pnl, on_click, on_drag, on_hold, on_release);
4085   SetSlateChar ((SlatE) pnl, on_key);
4086   SetWindowTimer (w, on_time);
4087   do_resize_window (pnl, adp, TRUE);
4088   if (dummy != NULL) {
4089      SeqEdCorrectBarValue (pnl, (Int2) adp->voffset);
4090   }
4091 
4092   if (adp->showfeat) {
4093      adp->showfeat = FALSE;
4094      if (wdp->showfeatbt!=NULL)
4095         ShowFeatureButtonProc (wdp->showfeatbt);
4096      if (wdp->showfeatitem!=NULL)
4097         ShowFeatureItemProc (wdp->showfeatitem);
4098   }
4099   if (!adp->display_panel)
4100      to_update_prompt (pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
4101 
4102   if (adp->master.entityID > 0) {
4103      sep = GetTopSeqEntryForEntityID (adp->master.entityID);
4104      TmpNam (adp->tmpfile);
4105      seqentry_write (sep, adp->tmpfile);
4106   }
4107   return (ForM) w;
4108 }
4109 
4110 
4111 /********************************************
4112 ***
4113 ***    Create new Window from SeqAlign
4114 ***
4115 ***********************************************/
4116 
DoReplaceBtn(ButtoN b)4117 static void DoReplaceBtn (ButtoN b)
4118 {
4119   WindoW             w;
4120   SeqEditViewFormPtr wdp;
4121   EditAlignDataPtr   adp;
4122   SeqAnnotPtr        sap_copy;
4123   SeqAlignPtr        salp,
4124                      salp2;
4125   SeqIdPtr           target_id,
4126                      source_id;
4127   CompSegPtr         csp;
4128   PropaStructPtr     psp;
4129   BioseqPtr          target_bsp,
4130                      source_bsp;
4131   ValNodePtr         targetfeats = NULL;
4132   Uint2              master_entityID,
4133                      master_itemID,
4134                      master_itemtype;
4135 
4136   w = (WindoW)ParentWindow (b);
4137   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
4138   adp = (EditAlignDataPtr) wdp->data;
4139   if (adp != NULL) {
4140      adp->stoptransl = 0;
4141      salp = (SeqAlignPtr) adp->sap_align->data;
4142      if (salp->segtype == COMPSEG) {
4143         csp = (CompSegPtr) salp->segs;
4144         if (csp->ids != NULL && csp->ids->next!=NULL) {
4145            target_id = SeqIdDup(csp->ids);
4146            source_id = SeqIdDup(csp->ids->next);
4147            master_entityID = adp->master.entityID;
4148            master_itemID = adp->master.itemID;
4149            master_itemtype = adp->master.itemtype;
4150            sap_copy = (SeqAnnotPtr) AsnIoMemCopy ((Pointer) adp->sap_original, (AsnReadFunc) SeqAnnotAsnRead, (AsnWriteFunc) SeqAnnotAsnWrite);
4151            salp2 = SeqAlignBoolSegToDenseSeg (salp);
4152            psp = CreatePropaStruc (target_id, source_id, salp2);
4153 
4154            if (psp) {
4155               psp->gap_choice = IGNORE_GAP_CHOICE;
4156               psp->stoptransl = adp->stoptransl;
4157               psp->keep_protID = FALSE;
4158 
4159               Hide (w);
4160               Update ();
4161               Remove (w);
4162               Nlm_RemoveDyingWindows ();
4163 
4164               target_bsp = BioseqLockById (target_id);
4165               if (target_bsp) {
4166 SeqLocPtr target_slp;
4167                  target_slp = SeqLocIntNew (0, target_bsp->length-1, Seq_strand_plus, target_id);
4168                  targetfeats = CollectFeatureForEditor (target_slp, targetfeats, psp->target_entityID, psp->target_bsp_itemID, NULL, TRUE);
4169                  PropagateFeatureBySeqLock (psp->sap, psp->target_bsp_itemID, psp->source_entityID, psp->source_sep, targetfeats, psp->gap_choice);
4170                  BioseqUnlock (target_bsp);
4171 /**** TODO:
4172 free targetfeats **********************/
4173               }
4174               PropagateFeatureByApply (psp);
4175               psp->sap->data = NULL;
4176               psp->sap = SeqAnnotFree (psp->sap);
4177               psp->target_sep = NULL;
4178               psp->source_seqfeat = NULL;
4179               psp->target_seqfeat = NULL;
4180               MemFree(psp);
4181 
4182               target_bsp = BioseqLockById (target_id);
4183               source_bsp = BioseqLockById (source_id);
4184               if (target_bsp && source_bsp &&
4185                   target_bsp->seq_data_type != Seq_code_gap &&
4186                   source_bsp->seq_data_type != Seq_code_gap) {
4187                  target_bsp->seq_data = SeqDataFree (target_bsp->seq_data, target_bsp->seq_data_type);
4188                  target_bsp->seq_data = (SeqDataPtr) BSDup((ByteStorePtr) source_bsp->seq_data);
4189                  target_bsp->seq_data_type = source_bsp->seq_data_type;
4190                  target_bsp->length = source_bsp->length;
4191                  BioseqRawPack (target_bsp);
4192                  BioseqUnlock (target_bsp);
4193                  ObjMgrSetDirtyFlag (master_entityID, TRUE);
4194                  ObjMgrSendMsg (OM_MSG_UPDATE, master_entityID, master_itemID, master_itemtype);
4195               }
4196            }
4197            SeqAlignSetFree (salp2);
4198            SeqIdFree (target_id);
4199            SeqIdFree (source_id);
4200            /**************************** Next Salp ****/
4201            salp=NULL;
4202            if (sap_copy) {
4203 	      salp = (SeqAlignPtr)(sap_copy->data);
4204 	      salp = salp->next;
4205            }
4206            if (salp)
4207               LaunchAlignViewer(salp);
4208         }
4209      }
4210   }
4211   return;
4212 }
4213 
what_seqalign(SeqAlignPtr salp)4214 static Int2 what_seqalign (SeqAlignPtr salp)
4215 {
4216   DenseSegPtr   dsp;
4217   CompSegPtr    csp;
4218   Int4          numseg;
4219   Int2          dim;
4220   Int4Ptr       startsi;
4221   BoolPtr       starts;
4222   Boolean       start1, start2, start3, start4;
4223 
4224   if (salp->segtype == 2)
4225   {
4226      dsp = (DenseSegPtr)salp->segs;
4227      startsi = dsp->starts;
4228      numseg = dsp->numseg;
4229      dim = dsp->dim;
4230      start1=(Boolean)(startsi[0]>-1);
4231      start2=(Boolean)(startsi[1]>-1);
4232      start3=(Boolean)(startsi[(numseg*dim)-2]>-1);
4233      start4=(Boolean)(startsi[(numseg*dim)-1]>-1);
4234   }
4235   else if (salp->segtype == COMPSEG) {
4236      csp = (CompSegPtr)salp->segs;
4237      starts = csp->starts;
4238      numseg = csp->numseg;
4239      dim = csp->dim;
4240      start1=starts[0];
4241      start2=starts[1];
4242      start3=starts[(numseg*dim)-2];
4243      start4=starts[(numseg*dim)-1];
4244   }
4245   else
4246      return 0;
4247   if (!start3) {
4248      if (start1)
4249         return 2;
4250      else if(!start2)
4251          return 4; /* extension to the right */
4252      return 5; /* HS XXX modify behavior of code.. now uses whole sequence for merge */
4253      return 3; /* Could merge either before or after .. by default it's after */
4254   } else if (!start1) {
4255       /* start3 == TRUE */
4256      return 1;
4257   } else  if(start1 && start4) { /* start3==TRUE already */
4258       return 5; /* nothing new, just take sequence from new one */
4259   } else if (start1 && start3)
4260       return 6;
4261   return 0;
4262 }
4263 
SeqAlignFirstLength(SeqAlignPtr salp)4264 static Int4 SeqAlignFirstLength (SeqAlignPtr salp)
4265 {
4266   Int4          len = 0;
4267   DenseSegPtr   dsp;
4268   CompSegPtr    csp;
4269 
4270   if (salp->segtype == 2)
4271   {
4272      dsp = (DenseSegPtr)salp->segs;
4273      len = (Int4)*(dsp->lens);
4274   }
4275   else if (salp->segtype == COMPSEG) {
4276      csp = (CompSegPtr)salp->segs;
4277      len = (Int4)*(csp->lens);
4278   }
4279   return len;
4280 }
4281 
SeqAlignLastLength(SeqAlignPtr salp)4282 static Int4 SeqAlignLastLength (SeqAlignPtr salp)
4283 {
4284   Int4          len = 0;
4285   DenseSegPtr   dsp;
4286   CompSegPtr    csp;
4287 
4288   if (salp->segtype == 2)
4289   {
4290      dsp = (DenseSegPtr)salp->segs;
4291      len = (Int4)dsp->lens[dsp->numseg-1];
4292   }
4293   else if (salp->segtype == COMPSEG) {
4294      csp = (CompSegPtr)salp->segs;
4295      len = (Int4)csp->lens[csp->numseg-1];
4296   }
4297   return len;
4298 }
4299 
get_bestpos_formerge(SeqAlignPtr salp,Int4Ptr from,Int4Ptr to)4300 static Boolean get_bestpos_formerge (SeqAlignPtr salp, Int4Ptr from, Int4Ptr to)
4301 {
4302   Int2          j;
4303   Boolean       insert_before=FALSE,
4304                 insert_after=FALSE;
4305   Int4          from1, to1, from2, to2;
4306   BioseqPtr     bsp;
4307   SeqIdPtr      sip;
4308 
4309   *from = -1;
4310   *to = -1;
4311   if (salp == NULL)
4312      return FALSE;
4313   AlnMgrIndexSingleChildSeqAlign(salp);
4314   AlnMgrGetNthSeqRangeInSA(salp, 1, &from1, &to1);
4315   AlnMgrGetNthSeqRangeInSA(salp, 2, &from2, &to2);
4316   if (from1 == 0)
4317   {
4318      if (from2 != 0)
4319      {
4320         *from = 0;
4321         *to = from2 - 1;
4322      } else
4323      {
4324         *from = from2;
4325         *to = to2;
4326      }
4327   } else if (from2 == 0)
4328   {
4329      if (from1 != 0)
4330      {
4331         *from = to2 + 1;
4332         sip = AlnMgrGetNthSeqIdPtr(salp, 2);
4333         bsp = BioseqLockById(sip);
4334         if (bsp != NULL)
4335            *to = bsp->length -1;
4336         BioseqUnlock(bsp);
4337         SeqIdFree(sip);
4338      } else
4339      {
4340         *from = from2;
4341         *to = to2;
4342      }
4343   }
4344   *to+=1; /* create a bug to fix a bug -- SW */
4345   return FALSE; /* above fix put in 1/29/01 since coordinates were not correct -- SW */
4346   j=what_seqalign(salp);
4347   if (j==1 || j==3)
4348   { /* when j==3, there is also a bit afterwards that could be merged.*/
4349      insert_before = TRUE;
4350      *from = SeqAlignStart(salp, 1);
4351      *to = *from + SeqAlignFirstLength (salp)-1; /* HS bug fix */
4352      return TRUE;
4353   }
4354   if (j==2 || j==4)
4355   {
4356      insert_after = TRUE;
4357      *from = SeqAlignStop (salp, 1) - SeqAlignLastLength (salp) + 1;
4358      *to = SeqAlignStop (salp, 1);
4359      return TRUE;
4360   }
4361   if (j==5 || j==6) { /* copy over the whole seqalign. .. nothing new */
4362       *from = SeqAlignStart(salp,1);
4363       *to = SeqAlignStop(salp,1);
4364   }
4365   return FALSE;
4366 }
4367 
DoMergeBtn(ButtoN b)4368 static void DoMergeBtn (ButtoN b)
4369 {
4370   WindoW             w;
4371   SeqEditViewFormPtr wdp;
4372   EditAlignDataPtr   adp;
4373   SeqAnnotPtr        sap_copy;
4374   SeqAlignPtr        salp;
4375   CompSegPtr         csp;
4376   SeqIdPtr           target_id,
4377                      source_id,
4378                      merge_id;
4379   BioseqPtr          merge_bsp;
4380   ValNodePtr         sqloc_list=NULL;
4381   Char               str [32];
4382   Int4               from, to;
4383   Uint2              master_entityID,
4384                      master_itemID,
4385                      master_itemtype;
4386   Boolean            keep_protID=TRUE,
4387                      spliteditmode,
4388                      ok=FALSE;
4389 
4390 
4391   w = (WindoW)ParentWindow (b);
4392   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
4393   adp = (EditAlignDataPtr) wdp->data;
4394   if (adp != NULL) {
4395      if (wdp->keep_protid1)
4396         keep_protID = GetStatus(wdp->keep_protid1);
4397      salp = (SeqAlignPtr) adp->sap_align->data;
4398      if (salp->segtype == COMPSEG) {
4399         csp = (CompSegPtr) salp->segs;
4400         if (csp->ids != NULL && csp->ids->next!=NULL) {
4401            target_id = SeqIdDup(csp->ids);
4402            source_id = SeqIdDup(csp->ids->next);
4403            master_entityID = adp->master.entityID;
4404            master_itemID = adp->master.itemID;
4405            master_itemtype = adp->master.itemtype;
4406            sap_copy = (SeqAnnotPtr) AsnIoMemCopy ((Pointer) adp->sap_original, (AsnReadFunc) SeqAnnotAsnRead, (AsnWriteFunc) SeqAnnotAsnWrite);
4407            GetTitle (wdp->fromtxt, str, sizeof (str));
4408            StrToLong (str, &from);
4409            from--;
4410            GetTitle (wdp->totxt, str, sizeof (str));
4411            StrToLong (str, &to);
4412            to--;
4413            merge_bsp = BioseqCopy (NULL, source_id, from, to, Seq_strand_plus, TRUE);
4414 
4415            adp->sap_align->data = NULL;
4416            sqloc_list = adp->sqloc_list;
4417            adp->sqloc_list = NULL;
4418            spliteditmode = adp->spliteditmode;
4419 
4420            Hide (w);
4421            Update ();
4422 
4423            if (merge_bsp)
4424            {
4425               merge_id = merge_bsp->id;
4426               ok= MergeFunc (target_id, source_id, merge_id, salp, from, to, sqloc_list, spliteditmode, keep_protID);
4427               if (ok) {
4428                  ObjMgrSetDirtyFlag (master_entityID, TRUE);
4429                  ObjMgrSendMsg (OM_MSG_UPDATE, master_entityID, master_itemID, master_itemtype);
4430               }
4431            }
4432            SeqIdFree (target_id);
4433            SeqIdFree (source_id);
4434            Remove (w);
4435            /**************************** Next Salp ****/
4436            salp=NULL;
4437            if (sap_copy) {
4438               salp = (SeqAlignPtr)(sap_copy->data);
4439               salp = salp->next;
4440            }
4441            if (salp)
4442               LaunchAlignViewer(salp);
4443         }
4444      }
4445   }
4446   return;
4447 }
4448 
DoCopyFeatBtn(ButtoN b)4449 static void DoCopyFeatBtn (ButtoN b)
4450 {
4451   WindoW             w;
4452   SeqEditViewFormPtr wdp;
4453   EditAlignDataPtr   adp;
4454   SeqAnnotPtr        sap_copy;
4455   SeqAlignPtr        salp,
4456                      salp2;
4457   CompSegPtr         csp;
4458   PropaStructPtr     psp;
4459   SeqIdPtr           target_id,
4460                      source_id;
4461   Uint2              entityID;
4462   Uint4              itemID;
4463   Boolean            val = FALSE;
4464 
4465   w = (WindoW)ParentWindow (b);
4466   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
4467   adp = (EditAlignDataPtr) wdp->data;
4468   if (adp != NULL) {
4469      if (wdp->gap_choicebn) {
4470         val = GetStatus(wdp->gap_choicebn);
4471         if (val)
4472            adp->gap_choice = TAKE_GAP_CHOICE;
4473         else
4474            adp->gap_choice = IGNORE_GAP_CHOICE;
4475      }
4476      val = FALSE;
4477      if (wdp->keep_protid2)
4478         val = GetStatus(wdp->keep_protid2);
4479      adp->stoptransl = 0;
4480      sap_copy = (SeqAnnotPtr) AsnIoMemCopy ((Pointer) adp->sap_original, (AsnReadFunc) SeqAnnotAsnRead, (AsnWriteFunc) SeqAnnotAsnWrite);
4481      salp = (SeqAlignPtr) adp->sap_align->data;
4482      if (salp->segtype == COMPSEG) {
4483         csp = (CompSegPtr) salp->segs;
4484         if (csp->ids != NULL && csp->ids->next!=NULL) {
4485            target_id = SeqIdDup (csp->ids);
4486            source_id = SeqIdDup (csp->ids->next);
4487 
4488            salp2 = SeqAlignBoolSegToDenseSeg (salp);
4489            psp = CreatePropaStruc (target_id, source_id, salp2);
4490 
4491            if (psp) {
4492               psp->gap_choice = adp->gap_choice;
4493               psp->stoptransl = adp->stoptransl;
4494               psp->keep_protID = val;
4495 
4496               Hide (w);
4497               Update ();
4498               Remove (w);
4499               Nlm_RemoveDyingWindows ();
4500 
4501               PropagateFeatureByApply (psp);
4502               psp->sap->data = NULL;
4503               psp->sap = SeqAnnotFree (psp->sap);
4504               psp->target_sep = NULL;
4505               psp->source_seqfeat = NULL;
4506               psp->target_seqfeat = NULL;
4507               MemFree(psp);
4508            }
4509 
4510            entityID = BioseqFindEntity (target_id, &itemID);
4511            SeqAlignSetFree (salp2);
4512            ObjMgrSetDirtyFlag (entityID, TRUE);
4513            ObjMgrSendMsg (OM_MSG_UPDATE, entityID, itemID, OBJ_BIOSEQ);
4514            SeqIdFree (target_id);
4515            SeqIdFree (source_id);
4516 
4517            /**************************** Next Salp ****/
4518            salp=NULL;
4519            if (sap_copy) {
4520               salp = (SeqAlignPtr)(sap_copy->data);
4521               salp = salp->next;
4522            }
4523            /**************************** Next Salp ****/
4524            if (salp)
4525               LaunchAlignViewer (salp);
4526         }
4527      }
4528   }
4529   return;
4530 }
4531 
4532 
LaunchAlignEdit(ButtoN b)4533 static void LaunchAlignEdit (ButtoN b)
4534 {
4535   SeqEditViewFormPtr wdp;
4536   EditAlignDataPtr   adp;
4537   SeqAlignPtr        salp;
4538 
4539   wdp = (SeqEditViewFormPtr) GetObjectExtra ((WindoW)ParentWindow (b));
4540   adp = (EditAlignDataPtr) wdp->data;
4541   if (adp != NULL)
4542   {
4543      salp = (SeqAlignPtr)adp->sap_align->data;
4544      salp = SeqAlignBoolSegToDenseSeg (salp);
4545      if (salp != NULL)
4546         LaunchAlignEditor (salp);
4547   }
4548   return;
4549 }
4550 
CloseThisWindowProc(ButtoN b)4551 static void CloseThisWindowProc (ButtoN b)
4552 {
4553   WindoW             w;
4554   SeqEditViewFormPtr wdp;
4555   EditAlignDataPtr   adp;
4556 
4557   w = (WindoW)ParentWindow (b);
4558   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
4559   adp = (EditAlignDataPtr) wdp->data;
4560   if (adp != NULL) {
4561      EditAlignDataFree (adp);
4562      wdp->data = NULL;
4563   }
4564   Hide (w);
4565   Update ();
4566   Remove (w);
4567 }
4568 
SkipThisWindowProc(ButtoN b)4569 static void SkipThisWindowProc (ButtoN b)
4570 {
4571   WindoW             w;
4572   SeqEditViewFormPtr wdp;
4573   EditAlignDataPtr   adp;
4574   SeqAlignPtr        salp;
4575 
4576   w = (WindoW)ParentWindow (b);
4577   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
4578   adp = (EditAlignDataPtr) wdp->data;
4579   if (adp->sap_original) {
4580      salp = (SeqAlignPtr)(adp->sap_original->data);
4581      salp = salp->next;
4582   }
4583   if (adp != NULL) {
4584      EditAlignDataFree (adp);
4585      wdp->data = NULL;
4586   }
4587   Hide (w);
4588   Update ();
4589   Remove (w);
4590   if (salp)
4591      LaunchAlignViewer(salp);
4592 }
4593 
4594 
4595 /***************************************************************
4596 ***  switch_featOrder
4597 ***
4598 *****************************************************************/
switch_featOrder(EditAlignDataPtr adp,Uint1 choice)4599 static void switch_featOrder (EditAlignDataPtr adp, Uint1 choice)
4600 {
4601   Int2  oldstyle;
4602   Int2  j;
4603   Int4  groupNum;
4604 
4605   if (choice) {
4606      oldstyle = GetMuskCurrentSt ();
4607      SetMuskCurrentSt (GetMuskStyleName (adp->styleNum));
4608      for(j =0; j<FEATDEF_ANY; j++)
4609      {
4610         adp->featOrder[j] = (Uint1)GetMuskCParam(j, MSM_FORDER, MSM_NUM);
4611         groupNum = (Uint1)GetMuskCParam(j, MSM_FGROUP, MSM_NUM);
4612         adp->groupOrder[j] = (Uint1)GetMuskCParam(MSM_GROUPS, (Int2)groupNum, MSM_NUM);
4613      }
4614      SetMuskCurrentSt (GetMuskStyleName (oldstyle));
4615   }
4616   else
4617      for(j=0; j<FEATDEF_ANY; ++j) adp->featOrder[j] = choice;
4618 }
4619 
ChangeRMCProc(GrouP g)4620 static void ChangeRMCProc (GrouP g)
4621 
4622 {
4623   Int2                val;
4624   SeqEditViewFormPtr  wdp;
4625 
4626   wdp = (SeqEditViewFormPtr) GetObjectExtra (g);
4627   if (wdp == NULL) return;
4628   val = GetValue (wdp->replaceMergeCopyGroup);
4629   switch (val) {
4630     case 1 :
4631       SafeHide (wdp->rmcExtra [1]);
4632       SafeHide (wdp->rmcExtra [2]);
4633       SafeShow (wdp->rmcExtra [0]);
4634       SafeEnable (wdp->acceptBtn);
4635       break;
4636     case 2 :
4637       SafeHide (wdp->rmcExtra [0]);
4638       SafeHide (wdp->rmcExtra [2]);
4639       SafeShow (wdp->rmcExtra [1]);
4640       SafeEnable (wdp->acceptBtn);
4641       break;
4642     case 3 :
4643       SafeHide (wdp->rmcExtra [0]);
4644       SafeHide (wdp->rmcExtra [1]);
4645       SafeShow (wdp->rmcExtra [2]);
4646       SafeEnable (wdp->acceptBtn);
4647       break;
4648     default :
4649       SafeHide (wdp->rmcExtra [1]);
4650       SafeHide (wdp->rmcExtra [0]);
4651       SafeHide (wdp->rmcExtra [2]);
4652       SafeDisable (wdp->acceptBtn);
4653       break;
4654   }
4655 }
4656 
AcceptSeqAlignViewForm(ButtoN b)4657 static void AcceptSeqAlignViewForm (ButtoN b)
4658 
4659 {
4660   Int2                val;
4661   SeqEditViewFormPtr  wdp;
4662 
4663   wdp = (SeqEditViewFormPtr) GetObjectExtra (b);
4664   if (wdp == NULL) return;
4665   val = GetValue (wdp->replaceMergeCopyGroup);
4666   switch (val) {
4667     case 1 :
4668       DoReplaceBtn (b);
4669       break;
4670     case 2 :
4671       DoMergeBtn (b);
4672       break;
4673     case 3 :
4674       DoCopyFeatBtn (b);
4675       break;
4676     default :
4677       break;
4678   }
4679 }
4680 
CreateSeqAlignViewForm(Int2 left,Int2 top,CharPtr windowname,SeqAlignPtr salp,Pointer dummy)4681 static ForM CreateSeqAlignViewForm (Int2 left, Int2 top, CharPtr windowname, SeqAlignPtr salp, Pointer dummy)
4682 {
4683   VieweR             view = NULL;
4684   SeqEditViewProcsPtr  svpp;
4685   WindoW             w;
4686   SeqEditViewFormPtr wdp;
4687   EditAlignDataPtr   adp;
4688   GrouP              g, g2, h;
4689   ButtoN             mergebtn;
4690   SelStructPtr       ssp;
4691   Int4               start = 0,
4692                      stop;
4693   Int2               wid, hgt;
4694   ValNodePtr         vnp;
4695   AlignNodePtr       anp;
4696 
4697   Char strid1[16], strid2[16];
4698   Char str [64];
4699   Int2 j;
4700 
4701   wdp = (SeqEditViewFormPtr) MemNew (sizeof (SeqEditViewForm));
4702   w = FixedWindow (left, top, (Int2)(-10), (Int2)(-10),  windowname, NULL /*, ResizeAlignDataWindow */);
4703   SetObjectExtra (w, (Pointer) wdp, CleanupSequenceEditorForm);
4704   wdp->form = (ForM) w;
4705   wdp->formmessage = SalsaFormMessage;
4706   svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
4707   if (svpp != NULL) {
4708       SetActivate (w, svpp->activateForm);
4709       wdp->appmessage = svpp->handleMessages;
4710   }
4711   wdp->pnl = NULL;
4712   wdp->data = NULL;
4713 
4714   adp = EditAlignDataInit (NULL, 100, 12, MARGINLEFT25, 10, NULL, FALSE, 3);
4715   adp->Cn3D_On = FALSE;
4716   if (svpp)
4717      adp->Cn3D_On =svpp->Cn3D_On;
4718   if (dummy != NULL) {
4719      ssp = (SelStructPtr) dummy;
4720      adp->input_entityID = ssp->entityID;
4721      adp->input_itemID = ssp->itemID;
4722      adp->input_itemtype = ssp->itemtype;
4723      if (ssp->region!=NULL)
4724         start = (Int4)SeqLocStart((SeqLocPtr)ssp->region);
4725   }
4726   else {
4727      adp->input_entityID = 0;
4728      adp->input_itemID = 0;
4729      adp->input_itemtype = 0;
4730   }
4731   if (salp != NULL)
4732   {
4733      if (svpp != NULL)
4734         adp->showfeat = svpp->showfeat;
4735      switch_featOrder (adp, 1);
4736      adp = SeqAlignToEditAlignData (adp, salp, start, NULL, (Uint1)(FALSE));
4737   }
4738   if (adp == NULL)
4739      return NULL;
4740   adp->wdp = (Pointer) wdp;
4741 
4742   if (adp->anp_list && adp->master.region)
4743   {
4744      j=0;
4745      for (vnp=adp->anp_list; vnp!=NULL; vnp=vnp->next) {
4746         if (vnp->choice != OBJ_SEQANNOT) {
4747            anp = (AlignNodePtr) vnp->data.ptrvalue;
4748            j++;
4749            if (j==1)
4750               SeqIdWrite (anp->sip, strid1, PRINTID_REPORT, 16);
4751            else if (j==2)
4752               SeqIdWrite (anp->sip, strid2, PRINTID_REPORT, 16);
4753         }
4754      }
4755   }
4756 
4757              /* Panel for aligned sequences *
4758              ********************************/
4759   wid = (Int2)(adp->pnlWidth*adp->charw+adp->margin.right);
4760   hgt = (Int2)(adp->pnlLine * adp->lineheight + adp->margin.bottom);
4761   view = CreateViewer(w, wid, hgt, TRUE, TRUE);
4762   wdp->graph = view;
4763   wdp->data = (ValNodePtr) adp;
4764 
4765   g = HiddenGroup (w, -1, 0, NULL);
4766   SetGroupSpacing (g, 5, 5);
4767 
4768   wdp->replaceMergeCopyGroup = HiddenGroup (g, 3, 0, ChangeRMCProc);
4769   SetObjectExtra (wdp->replaceMergeCopyGroup, (Pointer) wdp, NULL);
4770   SetGroupSpacing (wdp->replaceMergeCopyGroup, 10, 5);
4771   RadioButton (wdp->replaceMergeCopyGroup, "Replace");
4772   mergebtn = RadioButton (wdp->replaceMergeCopyGroup, "Merge");
4773   RadioButton (wdp->replaceMergeCopyGroup, "Copy Features");
4774 
4775   h = HiddenGroup (g, 0, 0, NULL);
4776 
4777   wdp->rmcExtra [0] = HiddenGroup (h, 5, 0, NULL);
4778   sprintf (str, "'%s' by '%s'", strid1, strid2);
4779   StaticPrompt (wdp->rmcExtra [0], str, 0, 0, programFont, 'l');
4780   Hide (wdp->rmcExtra [0]);
4781 
4782   wdp->rmcExtra [1] = HiddenGroup (h, 6, 0, NULL);
4783   get_bestpos_formerge (salp, &start, &stop);
4784   StaticPrompt (wdp->rmcExtra [1], "From ", 0, popupMenuHeight, programFont, 'l');
4785   sprintf (str, "%d", (int) (start+1));
4786   wdp->fromtxt = DialogText (wdp->rmcExtra [1], str, 5, NULL);
4787   StaticPrompt (wdp->rmcExtra [1], " To ", 0, popupMenuHeight, programFont, 'l');
4788   sprintf (str, "%d", (int) (stop+1));
4789   wdp->totxt = DialogText (wdp->rmcExtra [1], str, 5, NULL);
4790   sprintf (str, " of '%s' with '%s'", strid2, strid1);
4791   StaticPrompt (wdp->rmcExtra [1], str, 0, popupMenuHeight, programFont, 'l');
4792 /*****
4793   if (start < 0 && stop < 0) {
4794      Disable (mergebtn);
4795      Disable (wdp->fromtxt);
4796      Disable (wdp->totxt);
4797   }
4798 ******/
4799   wdp->keep_protid1 = CheckBox (wdp->rmcExtra [1], "Keep Protein ID", NULL);
4800   SetStatus (wdp->keep_protid1, TRUE);
4801   Hide (wdp->rmcExtra [1]);
4802 
4803   wdp->rmcExtra [2] = HiddenGroup (h, 6, 0, NULL);
4804   sprintf (str, "From '%s' To '%s'", strid2, strid1);
4805   StaticPrompt (wdp->rmcExtra [2], str, 0, popupMenuHeight, programFont, 'l');
4806   sprintf (str, "'%s' contains exons and introns", strid2);
4807   wdp->gap_choicebn = CheckBox (wdp->rmcExtra [2], str, NULL);
4808   wdp->keep_protid2 = CheckBox (wdp->rmcExtra [2], "Keep Protein ID", NULL);
4809   Hide (wdp->rmcExtra [2]);
4810 
4811   AlignObjects (ALIGN_CENTER, (HANDLE) wdp->replaceMergeCopyGroup,
4812                 (HANDLE) wdp->rmcExtra [0], (HANDLE) wdp->rmcExtra [1],
4813                 (HANDLE) wdp->rmcExtra [2], NULL);
4814 
4815   g2 = HiddenGroup (w, 4, 0, NULL);
4816   wdp->acceptBtn = PushButton (g2, "Accept", AcceptSeqAlignViewForm);
4817   SetObjectExtra (wdp->acceptBtn, (Pointer) wdp, NULL);
4818   Disable (wdp->acceptBtn);
4819   PushButton (g2, "Preview Alignment", LaunchAlignEdit);
4820   PushButton (g2, "Cancel", CloseThisWindowProc);
4821   if (salp->next)
4822      PushButton (g2, "Skip", SkipThisWindowProc);
4823 
4824   AlignObjects (ALIGN_CENTER, (HANDLE) view, (HANDLE) g, (HANDLE) g2, NULL);
4825   RealizeWindow (w);
4826 
4827              /* register Panel & adp in SeqEditViewFormPtr *
4828              ***************************************/
4829   ViewForGraph (view, adp->input_entityID, adp, wid, adp->anp_list);
4830   return (ForM) w;
4831 }
4832 
4833 /************************************************
4834 ***
4835 ***   SeqEditFunc : to launch BIOSEQ editor
4836 ***
4837 ************************************************/
SeqEditFunc(Pointer data)4838 extern Int2 LIBCALLBACK SeqEditFunc (Pointer data)
4839 {
4840   BioseqPtr           bsp = NULL;
4841   OMProcControlPtr    ompcp;
4842   ForM                f;
4843   Int2                top;
4844   SeqIdPtr            sip;
4845   Char                str [64];
4846 
4847   ompcp = (OMProcControlPtr) data;
4848   if (ompcp == NULL || ompcp->proc == NULL)
4849      return OM_MSG_RET_ERROR;
4850   switch (ompcp->input_itemtype) {
4851     case OBJ_BIOSEQ :
4852       bsp = (BioseqPtr) ompcp->input_data;
4853       break;
4854    case 0 :
4855       return OM_MSG_RET_ERROR;
4856     default :
4857       return OM_MSG_RET_ERROR;
4858   }
4859   if (bsp == NULL) {
4860      return OM_MSG_RET_ERROR;
4861   }
4862 
4863   sip = SeqIdFindWorst (bsp->id);
4864   SeqIdWrite (sip, str, PRINTID_REPORT, 64);
4865 
4866 #ifdef WIN_MAC
4867   top = 53;
4868 #else
4869   top = 33;
4870 #endif
4871   f = CreateSeqEditorWindow (33, top, str, BioseqLockById (sip));
4872   if (f != NULL)
4873   {
4874      Show (f);
4875      Update ();
4876      Select (f);
4877      return OM_MSG_RET_DONE;
4878   }
4879 
4880   return OM_MSG_RET_ERROR;
4881 }
4882 
4883 
OpenNewAlignmentEditor(SeqAlignPtr salp,Uint2 input_entityID)4884 extern void OpenNewAlignmentEditor (SeqAlignPtr salp, Uint2 input_entityID)
4885 {
4886   Int2                  top;
4887   ForM                  f;
4888   ModalAcceptCancelData acd;
4889   WindoW                w;
4890   GrouP                 h, c;
4891   PrompT                ppt;
4892   ButtoN                b;
4893   SeqAnnotPtr           sanp;
4894 
4895   if (salp == NULL)
4896   {
4897     return;
4898   }
4899   if (salp->segtype != SAS_DENSEG)
4900   {
4901     w = ModalWindow (-50, -33, -10, -10, NULL);
4902     h = HiddenGroup (w, -1, 0, NULL);
4903     SetGroupSpacing (h, 10, 10);
4904     ppt = StaticPrompt (h, "Warning!  You have a pairwise alignment.  Some functions may not be available.",
4905                         0, dialogTextHeight, programFont, 'l');
4906     c = HiddenGroup (h, 4, 0, NULL);
4907     b = PushButton (c, "Continue anyway", ModalAcceptButton);
4908     SetObjectExtra (b, &acd, NULL);
4909     b = PushButton (c, "Convert alignment", ModalThirdOptionButton);
4910     SetObjectExtra (b, &acd, NULL);
4911     b = PushButton (c, "Cancel", ModalCancelButton);
4912     SetObjectExtra (b, &acd, NULL);
4913 
4914     acd.accepted = FALSE;
4915     acd.cancelled = FALSE;
4916     acd.third_option = FALSE;
4917 
4918     AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) c, NULL);
4919     RealizeWindow (w);
4920     Show (w);
4921     Update ();
4922 
4923     while (!acd.accepted && ! acd.cancelled && ! acd.third_option)
4924     {
4925       ProcessExternalEvent ();
4926       Update ();
4927     }
4928     ProcessAnEvent ();
4929     Remove (w);
4930     if (acd.cancelled)
4931     {
4932       return;
4933     }
4934     else if (acd.third_option)
4935     {
4936       WatchCursor();
4937       Update();
4938       sanp = GetSeqAnnotForAlignment (salp);
4939       ConvertPairwiseToMultipleAlignment (salp);
4940       ObjMgrSetDirtyFlag (input_entityID, TRUE);
4941       ObjMgrSendMsg (OM_MSG_UPDATE, input_entityID, 0, 0);
4942       salp = sanp->data;
4943       ArrowCursor();
4944       Update();
4945     }
4946   }
4947 
4948 #ifdef WIN_MAC
4949   top = 53;
4950 #else
4951   top = 33;
4952 #endif
4953 
4954 
4955   f = CreateAlnEditorWindow (33, top, "Alignment Assistant", salp,
4956                              input_entityID);
4957 
4958   if (f != NULL)
4959   {
4960      Show (f);
4961      Update ();
4962      Select (f);
4963   }
4964 }
4965 
4966 
4967 /************************************************
4968 ***
4969 ***   AlgEditFunc : to launch SEQALIGN editor
4970 ***
4971 ************************************************/
AlgEditFunc(Pointer data)4972 extern Int2 LIBCALLBACK AlgEditFunc (Pointer data)
4973 {
4974   WindoW              w = NULL;
4975   SeqAlignPtr         salp = NULL;
4976   SeqEditViewFormPtr  wdp = NULL;
4977   OMProcControlPtr    ompcp;
4978   SeqAnnotPtr         sap, sap2;
4979 
4980   ompcp = (OMProcControlPtr) data;
4981   if (ompcp == NULL || ompcp->proc == NULL) {
4982      ErrPostEx (SEV_ERROR, 0, 0, "Data NULL [1]");
4983      return OM_MSG_RET_ERROR;
4984   }
4985   switch (ompcp->input_itemtype) {
4986     case OBJ_SEQALIGN :
4987       salp = (SeqAlignPtr) ompcp->input_data;
4988       break;
4989    case 0 :
4990       return OM_MSG_RET_ERROR;
4991     default :
4992       return OM_MSG_RET_ERROR;
4993   }
4994   if (salp == NULL) {
4995      ErrPostEx (SEV_ERROR, 0, 0, "Data NULL [2]");
4996      return OM_MSG_RET_ERROR;
4997   }
4998 /********** TRICK in case there is a list of SeqAlign *********/
4999   if (salp->next!=NULL) {
5000      sap = SeqAnnotForSeqAlign (salp);
5001      sap2 = (SeqAnnotPtr) AsnIoMemCopy ((Pointer) sap, (AsnReadFunc) SeqAnnotAsnRead, (AsnWriteFunc) SeqAnnotAsnWrite);
5002      salp = (SeqAlignPtr) sap2->data;
5003      salp->next = NULL;
5004      sap->data=NULL;
5005      sap = SeqAnnotFree (sap);
5006      sap2->data=NULL;
5007      sap2 = SeqAnnotFree (sap2);
5008   }
5009 /********** TRICK *********/
5010 
5011   OpenNewAlignmentEditor (salp, ompcp->input_entityID);
5012   return OM_MSG_RET_DONE;
5013 }
5014 
5015 /* opens window for editing alignment */
5016 static Int2
FinishOpeningEditAlignmentWindow(SeqAlignPtr salp,Uint2 input_entityID,Uint4 input_itemID,Uint2 input_itemtype,Uint2 procid,Uint2 proctype)5017 FinishOpeningEditAlignmentWindow
5018 (SeqAlignPtr salp,
5019  Uint2       input_entityID,
5020  Uint4       input_itemID,
5021  Uint2       input_itemtype,
5022  Uint2       procid,
5023  Uint2       proctype)
5024 {
5025   SelStruct           ss;
5026   Char                str [64];
5027   WindoW              w;
5028   SeqEditViewFormPtr  wdp = NULL;
5029   OMUserDataPtr       omudp;
5030   SeqAnnotPtr         sap;
5031 
5032   ss.entityID = input_entityID;
5033   ss.itemID = input_itemID;
5034   ss.itemtype = input_itemtype;
5035   ss.regiontype =0;
5036   ss.region = NULL;
5037 
5038   SeqIdWrite (SeqAlignId(salp, 0), str, PRINTID_REPORT, 64);
5039 
5040   w = (WindoW) CreateSeqAlignEditForm (-40, -90, str, salp, &ss);
5041   if (w != NULL)
5042   {
5043     wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
5044     if (wdp != NULL)
5045     {
5046       wdp->input_entityID = input_entityID;
5047       wdp->input_itemID = input_itemID;
5048       wdp->input_itemtype = input_itemtype;
5049       wdp->this_itemtype = OBJ_SEQALIGN;
5050       wdp->this_subtype = 0;
5051       wdp->procid = procid;
5052       wdp->proctype = proctype;
5053       wdp->userkey = OMGetNextUserKey ();
5054       omudp = ObjMgrAddUserData (input_entityID, procid, OMPROC_EDIT, wdp->userkey);
5055       if (omudp != NULL)
5056       {
5057         omudp->userdata.ptrvalue = (Pointer) wdp;
5058         omudp->messagefunc = BioseqEditMsgFunc;
5059       }
5060       checkEntityIDForMsg (wdp);
5061     }
5062     Show (w);
5063     Update ();
5064     CaptureSlateFocus ((SlatE) wdp->pnl);
5065     Select (w);
5066 
5067     if (salp->segtype == 1) {
5068       SeqAlignPtr tmp, newsalp;
5069       Boolean ok;
5070       EditAlignDataPtr   adp;
5071 
5072       adp = GetAlignDataPanel(wdp->pnl);
5073       for ( tmp=salp; tmp!=NULL; tmp=tmp->next)
5074       {
5075         if (tmp->type<1)
5076         {
5077           sap=adp->sap_original;
5078           if (sap)
5079           {
5080             newsalp = (SeqAlignPtr)sap->data;
5081             ok = SeqAlignIDCache (newsalp, SeqAlignId (tmp, 1));
5082             if (ok)
5083             {
5084 /*
5085               if (adp->sap1_original)
5086                  SeqAlignIDCache ((SeqAlignPtr)adp->sap1_original->data, SeqIdFindBest (bsp->id, 0));
5087 */
5088               repopulate_panel (w, adp, newsalp);
5089             }
5090           }
5091         }
5092       }
5093     }
5094     return OM_MSG_RET_DONE;
5095   }
5096   return OM_MSG_RET_ERROR;
5097 }
5098 
OldAlignmentEditor(IteM i)5099 extern void OldAlignmentEditor (IteM i)
5100 {
5101   BaseFormPtr  bfp;
5102   BioseqPtr    bsp = NULL;
5103   ValNodePtr   seq_annot_list;
5104   SeqAnnotPtr  sap;
5105   SeqAlignPtr  salp = NULL;
5106   Int2         rval;
5107 
5108 #ifdef WIN_MAC
5109   bfp = currentFormDataPtr;
5110 #else
5111   bfp = GetObjectExtra (i);
5112 #endif
5113 
5114   if (bfp == NULL) return;
5115 
5116   bsp = GetBioseqGivenIDs (bfp->input_entityID,
5117                            bfp->input_itemID,
5118                            bfp->input_itemtype);
5119   if (bsp == NULL) return;
5120   seq_annot_list = FindAlignSeqAnnotsForBioseq (bsp);
5121   if (seq_annot_list != NULL && seq_annot_list->data.ptrvalue != NULL)
5122   {
5123     sap = (SeqAnnotPtr) seq_annot_list->data.ptrvalue;
5124     if (sap->type == 2)
5125     {
5126       salp = (SeqAlignPtr) sap->data;
5127     }
5128   }
5129   if (salp == NULL)
5130   {
5131     Message (MSG_ERROR, "No alignments found for this Bioseq!");
5132     return;
5133   }
5134 
5135   if (salp->dim == 2)
5136   {
5137   	rval = FinishOpeningEditAlignmentWindow (salp,
5138   	                                         bfp->input_entityID,
5139   	                                         bfp->input_itemID,
5140   	                                         bfp->input_itemtype,
5141   	                                         0, OMPROC_EDIT);
5142   }
5143   else
5144   {
5145     while (salp != NULL)
5146     {
5147   	  rval = FinishOpeningEditAlignmentWindow (salp,
5148   	                                           bfp->input_entityID,
5149   	                                           bfp->input_itemID,
5150   	                                           bfp->input_itemtype,
5151   	                                           0, OMPROC_EDIT);
5152   	  salp = salp->next;
5153     }
5154   }
5155 }
5156 
5157 /************************************************
5158 ***
5159 ***   AnnotAlgEditFunc : to launch SEQANNOT editor
5160 ***
5161 ************************************************/
AnnotAlgEditFunc(Pointer data)5162 extern Int2 LIBCALLBACK AnnotAlgEditFunc (Pointer data)
5163 {
5164   SeqAnnotPtr         sap;
5165   SeqAlignPtr         salp = NULL;
5166   OMProcControlPtr    ompcp;
5167   Int2                rval = OM_MSG_RET_ERROR;
5168 
5169   ompcp = (OMProcControlPtr) data;
5170   if (ompcp == NULL || ompcp->proc == NULL) {
5171      ErrPostEx (SEV_ERROR, 0, 0, "Data NULL [1]");
5172      return OM_MSG_RET_ERROR;
5173   }
5174   switch (ompcp->input_itemtype) {
5175     case OBJ_SEQANNOT :
5176       sap = (SeqAnnotPtr) ompcp->input_data;
5177       break;
5178    case 0 :
5179       return OM_MSG_RET_ERROR;
5180     default :
5181       return OM_MSG_RET_ERROR;
5182   }
5183   if (sap == NULL) {
5184      ErrPostEx (SEV_ERROR, 0, 0, "Data NULL [2]");
5185      return OM_MSG_RET_ERROR;
5186   }
5187   if (sap->data==NULL || sap->type!=2) {
5188      return OM_MSG_RET_ERROR;
5189   }
5190   salp = (SeqAlignPtr)sap->data;
5191 
5192 /****************************************/
5193 {
5194   SeqEditViewProcsPtr svpp;
5195 
5196   svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
5197   if (svpp != NULL) {
5198      if (svpp->Cn3D_On)
5199         salp = DenseSegToDenseDiag (salp);
5200   }
5201 }
5202 /*******************************************/
5203 
5204   if (salp == NULL)
5205      return OM_MSG_RET_ERROR;
5206 
5207   if (salp->dim == 2 || salp->segtype != SAS_DENSEG)
5208   {
5209     OpenNewAlignmentEditor (salp, ompcp->input_entityID);
5210   }
5211   else
5212   {
5213     while (salp != NULL)
5214     {
5215       OpenNewAlignmentEditor (salp, ompcp->input_entityID);
5216   	  salp = salp->next;
5217     }
5218   }
5219   return rval;
5220 }
5221 
AlgViewFunc(Pointer data)5222 extern Int2 LIBCALLBACK AlgViewFunc (Pointer data)
5223 {
5224   WindoW              w;
5225   SeqAlignPtr         salp = NULL;
5226   SeqEditViewFormPtr  wdp = NULL;
5227   OMProcControlPtr    ompcp;
5228   OMUserDataPtr       omudp;
5229   Char                str [64];
5230   SelStruct           ss;
5231 
5232   ompcp = (OMProcControlPtr) data;
5233   if (ompcp == NULL || ompcp->proc == NULL) {
5234      ErrPostEx (SEV_ERROR, 0, 0, "Data NULL [1]");
5235      return OM_MSG_RET_ERROR;
5236   }
5237   switch (ompcp->input_itemtype) {
5238     case OBJ_SEQALIGN :
5239       salp = (SeqAlignPtr) ompcp->input_data;
5240       break;
5241    case 0 :
5242       return OM_MSG_RET_ERROR;
5243     default :
5244       return OM_MSG_RET_ERROR;
5245   }
5246   if (salp == NULL) {
5247      ErrPostEx (SEV_ERROR, 0, 0, "Data NULL [2]");
5248      return OM_MSG_RET_ERROR;
5249   }
5250   ss.entityID = ompcp->input_entityID;
5251   ss.itemID = ompcp->input_itemID;
5252   ss.itemtype = ompcp->input_itemtype;
5253   ss.regiontype =0;
5254   ss.region = NULL;
5255   SeqIdWrite (SeqAlignId(salp, 0), str, PRINTID_REPORT, 64);
5256   w = (WindoW) CreateSeqAlignViewForm (-50, -33, str, salp, &ss);
5257   if (w == NULL) {
5258      return OM_MSG_RET_ERROR;
5259   }
5260   wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
5261   if (wdp != NULL) {
5262      wdp->input_entityID = ompcp->input_entityID;
5263      wdp->input_itemID = ompcp->input_itemID;
5264      wdp->input_itemtype = ompcp->input_itemtype;
5265      wdp->this_itemtype = OBJ_SEQALIGN;
5266      wdp->this_subtype = 0;
5267      wdp->procid = ompcp->proc->procid;
5268      wdp->proctype = ompcp->proc->proctype;
5269      wdp->userkey = OMGetNextUserKey ();
5270      omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid, OMPROC_EDIT, wdp->userkey);
5271      if (omudp != NULL) {
5272         omudp->userdata.ptrvalue = (Pointer) wdp;
5273         omudp->messagefunc = BioseqEditMsgFunc;
5274      }
5275      checkEntityIDForMsg (wdp);
5276   }
5277   Show (w);
5278   Update ();
5279   Select (w);
5280   return OM_MSG_RET_DONE;
5281 }
5282 
5283 /***********************************************************
5284 ***
5285 *** Launch Editors
5286 ***
5287 ***
5288 ************************************************************/
LaunchAnnotAlignEditor(SeqAnnotPtr sap)5289 extern void LaunchAnnotAlignEditor (SeqAnnotPtr sap)
5290 {
5291   Uint2            entityID,
5292                    itemID;
5293   Int2             handled;
5294   Uint2            options;
5295 
5296   if (sap != NULL) {
5297      entityID = ObjMgrRegister (OBJ_SEQANNOT, (Pointer) sap);
5298      options = ObjMgrGetOptions(entityID);
5299      options |= OM_OPT_FREE_IF_NO_VIEW;
5300      ObjMgrSetOptions(options, entityID);
5301      itemID = GetItemIDGivenPointer (entityID, OBJ_SEQANNOT, (Pointer) sap);
5302      handled = GatherProcLaunch (OMPROC_EDIT, FALSE, entityID, itemID, OBJ_SEQANNOT, 0, 0, OBJ_SEQANNOT, 0);
5303   }
5304 }
5305 
LaunchAlignEditor(SeqAlignPtr salp)5306 extern void LaunchAlignEditor (SeqAlignPtr salp)
5307 {
5308   Uint2            entityID,
5309                    itemID;
5310   Int2             handled;
5311   Uint2            options;
5312 
5313   if (salp != NULL) {
5314      entityID = ObjMgrRegister (OBJ_SEQALIGN, (Pointer) salp);
5315      options = ObjMgrGetOptions(entityID);
5316      options |= OM_OPT_FREE_IF_NO_VIEW;
5317      ObjMgrSetOptions(options, entityID);
5318      itemID = GetItemIDGivenPointer (entityID, OBJ_SEQALIGN, (Pointer) salp);
5319      handled = GatherProcLaunch (OMPROC_EDIT, FALSE, entityID, itemID, OBJ_SEQALIGN, 0, 0, OBJ_SEQALIGN, 0);
5320   }
5321 }
5322 
LaunchAlignViewer(SeqAlignPtr salp)5323 extern void LaunchAlignViewer (SeqAlignPtr salp)
5324 {
5325   Uint2            entityID,
5326                    itemID;
5327   Int2             handled;
5328   Uint2            options;
5329 
5330   if (salp != NULL) {
5331      entityID = ObjMgrRegister (OBJ_SEQALIGN, (Pointer) salp);
5332      options = ObjMgrGetOptions(entityID);
5333      options |= OM_OPT_FREE_IF_NO_VIEW;
5334      ObjMgrSetOptions(options, entityID);
5335      itemID = GetItemIDGivenPointer (entityID, OBJ_SEQALIGN, (Pointer) salp);
5336      handled = GatherProcLaunch (OMPROC_VIEW, FALSE, entityID, itemID, OBJ_SEQALIGN, 0, 0, OBJ_SEQALIGN, 0);
5337   }
5338 }
5339 
LaunchAlignEditorFromDesktop(Pointer data)5340 extern Int2 LIBCALLBACK LaunchAlignEditorFromDesktop (Pointer data)
5341 {
5342   OMProcControlPtr ompcp;
5343   SeqEntryPtr      sep;
5344   SeqAlignPtr      salp;
5345 
5346   ompcp = (OMProcControlPtr) data;
5347   sep=ReadLocalAlignment(SALSAA_CONTIGUOUS, NULL);
5348   if (!sep)
5349      return 0;
5350   salp = (SeqAlignPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN);
5351   if (salp != NULL) {
5352      LaunchAlignEditor (salp);
5353   }
5354   return OM_MSG_RET_OK;
5355 }
5356 
LaunchAlignEditorFromDesktop2(Pointer data)5357 extern Int2 LIBCALLBACK LaunchAlignEditorFromDesktop2 (Pointer data)
5358 {
5359   OMProcControlPtr ompcp;
5360   SeqEntryPtr      sep;
5361   SeqAlignPtr      salp;
5362 
5363   ompcp = (OMProcControlPtr) data;
5364   sep=ReadLocalAlignment(SALSAA_INTERLEAVE, NULL);
5365   if (!sep)
5366      return 0;
5367   salp = (SeqAlignPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN);
5368   if (salp != NULL) {
5369      LaunchAlignEditor (salp);
5370   }
5371   return OM_MSG_RET_OK;
5372 }
5373 
5374 
5375 /**********************************************************/
5376 
SeqAlignDeleteInSeqEntryCallBack(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)5377 static void SeqAlignDeleteInSeqEntryCallBack (SeqEntryPtr sep, Pointer mydata,
5378                                           Int4 index, Int2 indent)
5379 {
5380   BioseqPtr          bsp;
5381   BioseqSetPtr       bssp;
5382   SeqAnnotPtr        sap,
5383                      pre;
5384   BoolPtr            dirtyp;
5385 
5386   if (sep != NULL && sep->data.ptrvalue && mydata != NULL) {
5387      dirtyp = (BoolPtr)mydata;
5388      if (IS_Bioseq(sep)) {
5389         bsp = (BioseqPtr) sep->data.ptrvalue;
5390         if (bsp!=NULL) {
5391            sap=bsp->annot;
5392            pre=NULL;
5393            while (sap) {
5394               if (sap->type == 2) {
5395                  if (pre==NULL) {
5396                     bsp->annot = sap->next;
5397                     sap->next=NULL;
5398                     sap = SeqAnnotFree (sap);
5399                     if (bsp->annot)
5400                        sap=bsp->annot->next;
5401                  }
5402                  else {
5403                     pre=sap->next;
5404                     sap->next=NULL;
5405                     sap = SeqAnnotFree (sap);
5406                     if (pre)
5407                        sap=pre->next;
5408                  }
5409                  *dirtyp=TRUE;
5410               }
5411               else {
5412                  pre=sap;
5413                  sap=sap->next;
5414               }
5415            }
5416         }
5417      }
5418      else if(IS_Bioseq_set(sep)) {
5419         bssp = (BioseqSetPtr)sep->data.ptrvalue;
5420         if (bssp!=NULL) {
5421            sap=bssp->annot;
5422            pre=NULL;
5423            while (sap) {
5424               if (sap->type == 2) {
5425                  if (pre==NULL) {
5426                     bssp->annot = sap->next;
5427                     sap->next=NULL;
5428                     sap = SeqAnnotFree (sap);
5429                     if (bssp->annot)
5430                        sap=bssp->annot->next;
5431                  }
5432                  else {
5433                     pre=sap->next;
5434                     sap->next=NULL;
5435                     sap = SeqAnnotFree (sap);
5436                     if (pre)
5437                        sap=pre->next;
5438                  }
5439                  *dirtyp=TRUE;
5440               }
5441               else {
5442                  pre=sap;
5443                  sap=sap->next;
5444               }
5445            }
5446         }
5447      }
5448   }
5449 }
5450 
UpdateSeqAlign(Pointer data)5451 extern Int2 LIBCALLBACK UpdateSeqAlign (Pointer data)
5452 {
5453 
5454   OMProcControlPtr  ompcp;
5455   SeqAlignPtr       salp=NULL,
5456                     salpnew;
5457   SeqAnnotPtr       sap=NULL,
5458                     sapcopy;
5459   SeqEntryPtr       sep=NULL,
5460                     sepnew=NULL;
5461   Uint2             entityID,
5462                     itemID;
5463   MsgAnswer         ans;
5464   SeqSubmitPtr      ssp;
5465   Boolean           ok = TRUE,
5466                     dirty = FALSE;
5467 
5468   ompcp = (OMProcControlPtr) data;
5469   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
5470 
5471   if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
5472 
5473   switch(ompcp->input_itemtype)
5474     {
5475     case OBJ_BIOSEQ :
5476       sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
5477       break;
5478     case OBJ_BIOSEQSET :
5479       sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
5480       break;
5481     case OBJ_SEQENTRY :
5482       sep = ompcp->input_data;
5483       break;
5484     case OBJ_SEQSUB :
5485       ssp = ompcp->input_data;
5486       if(ssp->datatype==1)
5487          sep = (SeqEntryPtr)ssp->data;
5488       break;
5489     case 0 :
5490       return OM_MSG_RET_ERROR;
5491     default :
5492       return OM_MSG_RET_ERROR;
5493   }
5494   if (sep==NULL)
5495      return OM_MSG_RET_ERROR;
5496   entityID = ObjMgrGetEntityIDForChoice (sep);
5497   if (entityID < 1)
5498      return OM_MSG_RET_ERROR;
5499 
5500   sepnew = ReadAnyAlignment (FALSE, NULL);
5501   if (sepnew) {
5502      salpnew = (SeqAlignPtr) FindSeqAlignInSeqEntry (sepnew, OBJ_SEQALIGN);
5503      if (salpnew) {
5504         ok = ValidateSeqAlignandACCInSeqEntry (sepnew, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE);
5505         if (ok) {
5506            salp = (SeqAlignPtr) FindSeqAlignInSeqEntry (sep, OBJ_SEQALIGN);
5507            if (salp) {
5508               ans = Message (MSG_OKC, "Do you wish to replace (OK) or add (Cancel) the alignment in your SeqEntry?");
5509               if (ans == ANS_OK)
5510               {
5511                  SeqEntryExplore (sep, &dirty, SeqAlignDeleteInSeqEntryCallBack);
5512               }
5513            }
5514            sap=SeqAnnotForSeqAlign(salpnew);
5515            sapcopy = (SeqAnnotPtr) AsnIoMemCopy (sap, (AsnReadFunc) SeqAnnotAsnRead, (AsnWriteFunc) SeqAnnotAsnWrite);
5516            SeqAlignAddInSeqEntry (sep, sapcopy);
5517            sap->data=NULL;
5518            MemFree(sap);
5519            ObjMgrSetDirtyFlag (entityID, TRUE);
5520            itemID = GetItemIDGivenPointer (entityID, OBJ_SEQENTRY, (Pointer) sep);
5521            ObjMgrSendMsg (OM_MSG_UPDATE, entityID, itemID, OBJ_SEQENTRY);
5522         }
5523      }
5524      ObjMgrFree (OBJ_SEQENTRY, (Pointer)sepnew);
5525      sepnew=NULL;
5526   }
5527   return OM_MSG_RET_OK;
5528 }
5529 
5530 
5531 
InsertSeqProc(IteM i)5532 static void InsertSeqProc (IteM i)
5533 {
5534   WindoW w;
5535   GrouP  g1, g2;
5536   PrompT insprt;
5537   TexT   instxt;
5538   ButtoN insbt, cnclbt;
5539   SeqEditViewFormPtr wdp;
5540 
5541   wdp = (SeqEditViewFormPtr) GetObjectExtra ((WindoW)ParentWindow (i));
5542   w = MovableModalWindow (-50, -33, -10, -10, "Insert Sequence", NULL);
5543 
5544   SetObjectExtra (w, (Pointer) wdp, NULL);
5545 
5546   g1 = HiddenGroup (w, 2, 0, NULL);
5547   insprt = StaticPrompt (g1, "Sequence:", 0, dialogTextHeight, programFont, 'l');
5548   instxt = DialogText (g1, "", (Int2)19, NULL);
5549 
5550   g2 = HiddenGroup (w, 2, 0, NULL);
5551   SetGroupSpacing (g2, 10, 5);
5552   insbt = PushButton (g2, "Insert", InsertSequenceButton);
5553   SetObjectExtra (insbt, (Pointer) instxt, NULL);
5554   cnclbt = PushButton (g2, "Cancel", CancelButton);
5555   AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2, NULL);
5556 
5557   Show (w);
5558   Select (w);
5559 }
5560 
5561 
CancelButton(ButtoN b)5562 static void CancelButton (ButtoN b)
5563 {
5564 	Remove ( (WindoW)ParentWindow (b) );
5565 }
5566 
InsertSequenceButton(ButtoN b)5567 static void InsertSequenceButton (ButtoN b)
5568 {
5569    SeqEditViewFormPtr wdp;
5570    EditAlignDataPtr   adp;
5571    CharPtr            str, strtmp;
5572 
5573    wdp = (SeqEditViewFormPtr) GetObjectExtra ((WindoW)ParentWindow (b));
5574    if (wdp==NULL) return;
5575    if ( ( adp = GetAlignDataPanel (wdp->pnl) ) == NULL ) return;
5576 
5577    str = SaveStringFromText ( (TexT)GetObjectExtra(b) );
5578    strtmp = char_to_insert (str, StringLen (str), adp->mol_type);
5579    if (insertchar_atcaret (strtmp, adp))
5580    {
5581         adp->dirty = TRUE;
5582         ObjMgrSetDirtyFlag (adp->caret.entityID, TRUE);
5583         ObjMgrSendMsg (OM_MSG_UPDATE, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype);
5584    }
5585    MemFree (strtmp);
5586    MemFree (str);
5587 
5588    Remove ( (WindoW)ParentWindow (b) );
5589    return;
5590 }
5591 
5592 
SeqAlignBestHit(SeqAlignPtr salp,BioseqPtr bsp1,BioseqPtr bsp2,Int4 threshold,CharPtr PNTR message,Int4Ptr nonly)5593 static SeqAlignPtr LIBCALL SeqAlignBestHit (SeqAlignPtr salp, BioseqPtr bsp1, BioseqPtr bsp2, Int4 threshold, CharPtr PNTR message, Int4Ptr nonly)
5594 {
5595    AMFreqPtr         afp;
5596    Int4              alln;
5597    AMAlignIndex2Ptr  amaip;
5598    Int4              beg;
5599    Int4              ctr;
5600    Int4              end;
5601    Boolean           found;
5602    Int4              gaps;
5603    Int4              i;
5604    Int4              j;
5605    Int4              last;
5606    Int4              len;
5607    Int4              n;
5608    Int4              nctr;
5609    Char              newstr[256];
5610    Int4              mismatches;
5611    Uint1             res;
5612    SeqAlignPtr       sap;
5613    SeqAlignPtr       sap_new;
5614    SeqAlignPtr       sap_new2;
5615    SeqAlignPtr       sap_orig;
5616    SeqPortPtr        spp;
5617    Int4              start1;
5618    Int4              start2;
5619    Int4              stop1;
5620    Int4              stop2;
5621    Uint1             strand;
5622 
5623    if (salp == NULL)
5624       return NULL;
5625    sap = NULL;
5626    if (salp->next != NULL)
5627    {
5628       sap_orig = SeqAlignDup(salp);
5629       AlnMgr2IndexLite(salp);
5630       AlnMgr2SortAlnSetByNthRowPos(salp, 1);
5631       SPI_RemoveInconsistentAlnsFromSet(salp, 10, 1, SPI_LEFT);
5632       amaip = (AMAlignIndex2Ptr)(salp->saip);
5633       last = 0;
5634       sap_new = NULL;
5635       for (i=0; i<amaip->numsaps-1; i++)
5636       {
5637          amaip->saps[i]->next = NULL;
5638          AlnMgr2GetNthSeqRangeInSA(amaip->saps[i], 1, &start1, &stop1);
5639          AlnMgr2GetNthSeqRangeInSA(amaip->saps[i+1], 1, &start2, &stop2);
5640          strand = AlnMgr2GetNthStrand(amaip->saps[i], 1);
5641          if (strand == Seq_strand_minus)
5642          {
5643             if (start1 <= stop2)
5644                AlnMgr2TruncateSeqAlign(amaip->saps[i], stop2+1, start1, 1);
5645             SeqAlignFree(amaip->saps[i]->next);
5646             amaip->saps[i]->next = NULL;
5647          } else
5648          {
5649             if (stop1 >= start2)
5650                AlnMgr2TruncateSeqAlign(amaip->saps[i], start1, start2-1, 1);
5651             SeqAlignFree(amaip->saps[i]->next);
5652             amaip->saps[i]->next = NULL;
5653          }
5654       }
5655       amaip->saps[amaip->numsaps-1]->next = NULL;
5656       for (i=0; i<amaip->numsaps-1; i++)
5657       {
5658          if (sap_new == NULL)
5659             sap_new = SeqAlignDup(amaip->saps[i]);
5660          sap_new2 = AlnMgr2MergeTwoAlignments(sap_new, amaip->saps[i+1]);
5661          if (sap_new2 == NULL)
5662             sap_new = amaip->saps[i];
5663          else
5664          {
5665             SeqAlignFree(sap_new);
5666             sap_new = sap_new2;
5667             sap_new2 = NULL;
5668          }
5669       }
5670       AlnMgr2IndexSingleChildSeqAlign(sap_new);
5671       if (AlnMgr2GetAlnLength(sap_orig, FALSE) >= AlnMgr2GetAlnLength(sap_new, FALSE))
5672       {
5673          SeqAlignFree(sap_new);
5674          sap_new = SeqAlignDup(sap_orig);
5675       }
5676       salp = sap_new;
5677    }
5678    sap = salp;
5679    AlnMgr2IndexSingleChildSeqAlign(sap);
5680    AlnMgr2ExtendToCoords(sap, 0, -1, 1);
5681    AlnMgr2GetNthSeqRangeInSA(sap, 1, &start1, &stop1);
5682    len = stop1 - start1 + 1; /* the actual length of sequence1 covered by aln */
5683    afp = AlnMgr2ComputeFreqMatrix(sap, 0, -1, 0);
5684    gaps = 0;
5685    mismatches = n = 0;
5686    alln = 0;
5687    for (i=0; i<afp->len; i++)
5688    {
5689       if (afp->freq[5][i] > 0)
5690          alln++;
5691       found = FALSE;
5692       for (j=0; !found && j<afp->size; j++)
5693       {
5694          if (afp->freq[0][i] > 0)
5695          {
5696             gaps++;
5697             found = TRUE;
5698          } else if (afp->freq[j][i] == 1 && afp->freq[5][i] == 0)
5699          {
5700             mismatches++;
5701             found = TRUE;
5702          } else if (afp->freq[j][i] == 1 && afp->freq[5][i] == 1)
5703          {
5704             n++;
5705             found = TRUE;
5706          }
5707       }
5708    }
5709    if (alln > 0 && (gaps>0 || mismatches>0 || n > 0))
5710    {
5711       spp = SeqPortNew(bsp1, 0, bsp1->length-1, Seq_strand_plus, Seq_code_ncbi4na);
5712       beg = end = 0;
5713       ctr = 0;
5714       nctr = 0;
5715       while ((res = SeqPortGetResidue(spp)) != SEQPORT_EOF)
5716       {
5717          if (res == 15)
5718          {
5719             if (beg == ctr)
5720                beg++;
5721             else
5722             {
5723                end++;
5724                nctr++;
5725             }
5726          } else
5727             end = 0;
5728          ctr++;
5729       }
5730       nctr = nctr - end;
5731       if (beg > 0 || end > 0)
5732       {
5733          sprintf(newstr, "The local sequence has %d terminal N%s. ", beg+end, beg+end!=1?"s":"");
5734          StringCat(*message, newstr);
5735       }
5736       if (nctr > 0)
5737       {
5738          sprintf(newstr, "The local sequence has %d internal N%s. ", nctr, nctr!=1?"s":"");
5739          StringCat(*message, newstr);
5740       }
5741       SeqPortFree(spp);
5742    }
5743    if ((*message[0] != '\0') && len == bsp1->length && gaps == 0 && mismatches == 0)
5744    {
5745       if (nctr > 0)
5746          *nonly = nctr+beg+end;
5747       else
5748          *nonly = -(beg+end);
5749       sprintf(newstr, "\nThere are no other differences between the local and database sequences.");
5750       StringCat(*message, newstr);
5751       return sap;
5752    } else
5753       *nonly = 0;
5754    if (len < bsp1->length)
5755    {
5756       sprintf(newstr, "%sThe alignment to the database sequence does not cover all of the local sequence. ", *message[0]=='\0'?"":"\n");
5757       StringCat(*message, newstr);
5758       spp = SeqPortNew(bsp1, len, bsp1->length-1, Seq_strand_plus, Seq_code_ncbi4na);
5759       alln = TRUE;
5760       while (alln && (res = SeqPortGetResidue(spp)) != SEQPORT_EOF)
5761       {
5762          if (res != 15)
5763             alln = FALSE;
5764       }
5765       if (alln)
5766          sprintf(newstr, "\nThe unaligned sequence consists only of Ns. ");
5767       else
5768          sprintf(newstr, "\nThere are non-N residues in the unaligned sequence. ");
5769       StringCat(*message, newstr);
5770       SeqPortFree(spp);
5771    }
5772    if (gaps > 0 || mismatches > 0 || n > 0)
5773    {
5774       sprintf(newstr, "%sThe alignment to the database sequence has %d gap%s, %d mismatch%s, and %d N-mismatch%s. ", afp->len<bsp1->length?"\n":"", gaps, (gaps!=1?"s":""), mismatches, (mismatches!=1?"es":""), n, (n!=1?"es":""));
5775       StringCat(*message, newstr);
5776       len = StringLen (*message);
5777    }
5778    return sap;
5779 }
5780 
SeqAlignStartUpdate(SeqAlignPtr salp,SeqIdPtr target_sip,Int4 offset,Int4 len,Uint1 strand)5781 static void SeqAlignStartUpdate (SeqAlignPtr salp, SeqIdPtr target_sip, Int4 offset, Int4 len, Uint1 strand)
5782 {
5783   SeqAlignPtr salptmp;
5784   DenseSegPtr dsp;
5785   SeqIdPtr    pre, sip, next;
5786   Int4Ptr     lenp,
5787               startp;
5788   Uint1Ptr    strandp;
5789   Int4        len_sum,
5790               start;
5791   Int2        index, k, j;
5792 
5793   if (salp==NULL || offset<=0)
5794      return;
5795   for (salptmp=salp; salptmp!=NULL; salptmp=salptmp->next)
5796   {
5797      if (salptmp->segtype == 2)
5798      {
5799         dsp = (DenseSegPtr) salptmp->segs;
5800         pre = NULL;
5801         index=0;
5802         sip=dsp->ids;
5803         while (sip)
5804         {
5805            next=sip->next;
5806            if (SeqIdForSameBioseq(target_sip, sip))
5807            {
5808               if (strand == Seq_strand_minus)
5809               {
5810                  strandp=dsp->strands;
5811                  if (strandp != NULL) {
5812                    strandp+=index;
5813                    for (j=0; j < dsp->numseg; j++)
5814                    {
5815                       if (*strandp == Seq_strand_minus)
5816                          *strandp = Seq_strand_plus;
5817                       else if (*strandp == Seq_strand_plus)
5818                          *strandp = Seq_strand_minus;
5819                       strandp+=dsp->dim;
5820                    }
5821                 } else
5822                 {
5823                    dsp->strands = (Uint1Ptr)MemNew(dsp->dim*dsp->numseg*sizeof(Uint1));
5824                    for (j=0; j<dsp->dim*dsp->numseg; j++)
5825                       dsp->strands[j] = Seq_strand_plus;
5826                    for(j=0; j<dsp->numseg; j++)
5827                       dsp->strands[j*dsp->dim + index] = Seq_strand_minus;
5828                 }
5829                  lenp=dsp->lens;
5830                  startp=dsp->starts;
5831                  start=startp[index];
5832                  len_sum=0;
5833                  j=dsp->dim*dsp->numseg-dsp->dim;
5834                  k=dsp->numseg-1;
5835                  for (j=0; j<dsp->numseg; j++) {
5836                    if (startp[j*dsp->dim + index]>=0) {
5837                        startp[j*dsp->dim + index]=len-startp[j*dsp->dim + index]-dsp->lens[j]+1;
5838                    }
5839                  }
5840               } else
5841               {
5842                  for (j=0; j<dsp->numseg; j++) {
5843                     if (dsp->starts[dsp->dim*j+index] != -1)
5844                         dsp->starts[dsp->dim*j+index] += offset;
5845                  }
5846               }
5847            }
5848            pre=sip;
5849            sip=next;
5850            index++;
5851         }
5852      }
5853   }
5854 }
5855 
5856 
SWSeqIdReplaceID(SeqIdPtr sip_head,SeqIdPtr sip1,SeqIdPtr sip2)5857 static SeqIdPtr SWSeqIdReplaceID(SeqIdPtr sip_head, SeqIdPtr sip1, SeqIdPtr sip2)
5858 {
5859    Boolean   found;
5860    SeqIdPtr  sip;
5861    SeqIdPtr  sip_prev;
5862 
5863    sip = sip_head;
5864    sip_prev = NULL;
5865    found = FALSE;
5866    while (sip != NULL && !found)
5867    {
5868       if (SeqIdComp(sip, sip1) == SIC_YES)
5869          found = TRUE;
5870       else
5871       {
5872          sip_prev = sip;
5873          sip = sip->next;
5874       }
5875    }
5876    if (!found)
5877       return sip_head;
5878    if (sip_prev == NULL)
5879    {
5880       sip2->next = sip_head->next;
5881       SeqIdFree(sip_head);
5882       return sip2;
5883    } else
5884    {
5885       sip_prev->next = sip2;
5886       sip2->next = sip->next;
5887       SeqIdFree(sip);
5888       return sip_head;
5889    }
5890 }
5891 
5892 /**********************************************************************
5893  *
5894  * nrSeqIdIsInValNodeList (vnp, sip)
5895  *
5896  * This function checks to see if SeqIdPtr sip points to the same Bioseq
5897  * as the SeqIdPtr values in ValNode list vnp's data.ptrvalues.
5898  *
5899  * Return values:
5900  *       TRUE if a match was found
5901  *       FALSE if no match was found
5902  **********************************************************************/
nrSeqIdIsInValNodeList(ValNodePtr vnp,SeqIdPtr sip)5903 static Boolean nrSeqIdIsInValNodeList (ValNodePtr vnp, SeqIdPtr sip)
5904 {
5905   ValNodePtr vnptmp=NULL;
5906   SeqIdPtr   siptmp;
5907   Boolean    rval = FALSE;
5908 
5909   if (sip == NULL)
5910   {
5911     return FALSE;
5912   }
5913 
5914   for (vnptmp=vnp; vnptmp!=NULL && !rval; vnptmp=vnptmp->next) {
5915     siptmp=(SeqIdPtr)vnptmp->data.ptrvalue;
5916     if (SeqIdForSameBioseq(sip, siptmp))
5917     {
5918       rval = TRUE;
5919     }
5920   }
5921 
5922   return rval;
5923 }
5924 
5925 
5926 /**********************************************************************
5927  *
5928  * nrSeqIdAdd (vnp, sip)
5929  *
5930  * This function checks to see if SeqIdPtr sip points to the same Bioseq
5931  * as the SeqIdPtr values in ValNode list vnp's data.ptrvalues.
5932  * If not, sip is added to the list.
5933  *
5934  * Return value:
5935  *       A ValNodeList pointing to SeqIDPtr values
5936  **********************************************************************/
nrSeqIdAdd(ValNodePtr vnp,SeqIdPtr sip)5937 static ValNodePtr nrSeqIdAdd (ValNodePtr vnp, SeqIdPtr sip)
5938 {
5939   if (sip == NULL)
5940   {
5941     return vnp;
5942   }
5943 
5944   if (!nrSeqIdIsInValNodeList (vnp, sip))
5945   {
5946     ValNodeAddPointer(&vnp, 0, sip);
5947   }
5948 
5949   return vnp;
5950 }
5951 
5952 
CalculateAlignmentDisplayPosition(SeqAlignPtr sap,Int4 aln_pos,Int4 row)5953 static Int4 CalculateAlignmentDisplayPosition (SeqAlignPtr sap, Int4 aln_pos, Int4 row)
5954 {
5955   Int4 seq_pos;
5956 
5957   /* calculate alignment position */
5958   if (sap == NULL)
5959   {
5960     return aln_pos;
5961   }
5962   seq_pos = AlnMgr2MapSeqAlignToBioseq(sap, aln_pos, row);
5963   while ((seq_pos == ALNMGR_GAP || seq_pos == ALNMGR_ROW_UNDEFINED) && aln_pos > 1) { /* count back if we in the gap */
5964     aln_pos--;
5965     seq_pos = AlnMgr2MapSeqAlignToBioseq(sap, aln_pos, 1);
5966   }
5967   if (seq_pos == ALNMGR_GAP || seq_pos == ALNMGR_ROW_UNDEFINED)
5968       seq_pos = 1;  /* Gap at the begining of the alignment */
5969   return seq_pos;
5970 }
5971 
5972 
SWPrintFarpointerAln(SeqAlignPtr sap,FILE * fp)5973 static void SWPrintFarpointerAln(SeqAlignPtr sap, FILE *fp)
5974 {
5975    Uint1Ptr    buf, seqbuf;
5976    Char        dig [6];
5977    Int4        i;
5978    Int4        l;
5979    Int4        len;
5980    Int4        linesize = 70;
5981    SeqIdPtr    sip;
5982    SeqIdPtr    sip2;
5983    Int4        alnbuflen;
5984    Uint1       strand1, strand2;
5985    Char        textid1[16];
5986    Char        textid2[16];
5987    Int4        seq_pos;
5988 
5989    if (sap == NULL || fp == NULL)
5990       return;
5991    if (sap->saip == NULL)
5992       AlnMgr2IndexSingleChildSeqAlign(sap);
5993    buf = (Uint1Ptr)MemNew(linesize * sizeof(Uint1));
5994    seqbuf = (Uint1Ptr)MemNew(linesize * sizeof(Uint1));
5995 
5996    for (i=0; i<16; i++)
5997    {
5998       textid1[i] = textid2[i] = ' ';
5999    }
6000    sip = AlnMgr2GetNthSeqIdPtr(sap, 1);
6001    SeqIdWrite(sip, textid1, PRINTID_TEXTID_ACC_VER, 15);
6002    sip2 = AlnMgr2GetNthSeqIdPtr(sap, 2);
6003    SeqIdWrite(sip2, textid2, PRINTID_TEXTID_ACC_VER, 15);
6004    for (i=0; i<15; i++)
6005    {
6006       if (textid1[i] == '\0')
6007          textid1[i] = ' ';
6008       if (textid2[i] == '\0')
6009          textid2[i] = ' ';
6010    }
6011    textid1[15] = '\0';
6012    textid2[15] = '\0';
6013 
6014    len = AlnMgr2GetAlnLength(sap, FALSE);
6015    strand1 = AlnMgr2GetNthStrand(sap, 1);
6016    strand2 = AlnMgr2GetNthStrand(sap, 2);
6017 
6018    for (l = 0; l < len; l+= linesize)
6019    {
6020      alnbuflen = linesize;
6021      AlignmentIntervalToString (sap, 1, l, l + linesize - 1, 1, FALSE, seqbuf, buf, &alnbuflen, TRUE);
6022      StringUpper ((char *)buf);
6023      seq_pos = CalculateAlignmentDisplayPosition (sap, l, 1);
6024      sprintf (dig, "%5d", seq_pos + 1);
6025 
6026      fprintf(fp, "%s%c%s %s\n", textid1, strand1 == Seq_strand_plus?'>':'<', dig, buf);
6027      alnbuflen = linesize;
6028      AlignmentIntervalToString (sap, 2, l, l + linesize - 1, 1, FALSE, seqbuf, buf, &alnbuflen, TRUE);
6029      StringUpper ((char *)buf);
6030      seq_pos = CalculateAlignmentDisplayPosition (sap, l, 2);
6031      sprintf (dig, "%5d", seq_pos + 1);
6032      fprintf(fp, "%s%c%s %s\n", textid2, strand2 == Seq_strand_plus?'>':'<', dig, buf);
6033      fprintf (fp, "\n");
6034    }
6035 
6036    sip = SeqIdFree(sip);
6037    sip2 = SeqIdFree (sip2);
6038    buf = MemFree(buf);
6039    seqbuf = MemFree (seqbuf);
6040 }
6041 
6042 
6043 typedef enum {
6044     FARPOINTER_LOOKUP_NO_ERROR = 0,
6045     FARPOINTER_LOOKUP_NOT_FOUND,
6046     FARPOINTER_LOOKUP_NONLY,
6047     FARPOINTER_LOOKUP_BAD_ALN
6048 } EFarPointerError;
6049 
6050 typedef struct farpointer {
6051   SeqIdPtr    sip_local;
6052   SeqIdPtr    sip_db;
6053   BioseqPtr   bsp_local;
6054   BioseqPtr   bsp_db;
6055   SeqAlignPtr salp;
6056   Boolean     revcomp;
6057   CharPtr     err_msg;
6058   Int4        nonly;
6059   EFarPointerError err_type;
6060 }FarPointerData, PNTR FarPointerPtr;
6061 
6062 typedef struct farpointerwin
6063 {
6064   FORM_MESSAGE_BLOCK
6065 
6066   ParData ParFmt;
6067   ColData ColFmt[3];
6068 
6069   DoC        doc;
6070   BoolPtr    selected;
6071   Int2       lineheight;
6072 
6073   FarPointerPtr far_pointer_list;
6074   Int4          num_sequences;
6075 } FarPointerWinData, PNTR FarPointerWinPtr;
6076 
6077 
FarPointerFree(FarPointerPtr p)6078 static FarPointerPtr FarPointerFree (FarPointerPtr p)
6079 {
6080   if (p != NULL) {
6081     p->sip_local = SeqIdFree (p->sip_local);
6082     p->sip_db = SeqIdFree (p->sip_db);
6083     BioseqUnlock (p->bsp_local);
6084     if (p->bsp_local != NULL) {
6085       p->bsp_local->idx.deleteme = TRUE;
6086     }
6087     p->bsp_local = NULL;
6088     BioseqUnlock (p->bsp_db);
6089     p->bsp_db = NULL;
6090     p->salp = SeqAlignFree (p->salp);
6091     p->err_msg = MemFree (p->err_msg);
6092     p = MemFree (p);
6093   }
6094   return p;
6095 }
6096 
6097 
FreeFarPointerData(FarPointerPtr fpp,Int4 num)6098 static FarPointerPtr FreeFarPointerData (FarPointerPtr fpp, Int4 num)
6099 {
6100   Int4 i;
6101 
6102   if (fpp != NULL) {
6103     for (i = 0; i < num; i++) {
6104       fpp[i].sip_local = SeqIdFree (fpp[i].sip_local);
6105       fpp[i].sip_db = SeqIdFree (fpp[i].sip_db);
6106       BioseqUnlock (fpp[i].bsp_local);
6107       if (fpp[i].bsp_local != NULL) {
6108         fpp[i].bsp_local->idx.deleteme = TRUE;
6109       }
6110       fpp[i].bsp_local = NULL;
6111       BioseqUnlock (fpp[i].bsp_db);
6112       fpp[i].bsp_db = NULL;
6113       fpp[i].salp = SeqAlignFree (fpp[i].salp);
6114       fpp[i].err_msg = MemFree (fpp[i].err_msg);
6115     }
6116     fpp = MemFree (fpp);
6117   }
6118   return fpp;
6119 }
6120 
CleanupFarPointerWinProc(GraphiC g,Pointer data)6121 static void CleanupFarPointerWinProc (GraphiC g, Pointer data)
6122 {
6123   FarPointerWinPtr fpwp;
6124 
6125   if (data != NULL)
6126   {
6127     fpwp = (FarPointerWinPtr) data;
6128     fpwp->selected = MemFree (fpwp->selected);
6129     fpwp = MemFree (fpwp);
6130   }
6131 }
6132 
GetDisplayGroupNum(FarPointerPtr fpp)6133 static Int4 GetDisplayGroupNum (FarPointerPtr fpp)
6134 {
6135   if (fpp == NULL) return -1;
6136   else if (fpp->sip_db == NULL) return 4;
6137   else if (fpp->bsp_db == NULL) return 3;
6138   else if (fpp->nonly < 0) return 1;
6139   else if (fpp->err_msg != NULL) return 0;
6140   else return 2;
6141 }
6142 
GetSeqNumFromListPos(Int4 list_pos,FarPointerPtr fpp,Int4 num)6143 static Int4 GetSeqNumFromListPos (Int4 list_pos, FarPointerPtr fpp, Int4 num)
6144 {
6145   Int4       seq_num, list_offset = 0, group_num;
6146 
6147   if (fpp == NULL || num < list_pos)
6148   {
6149     return 0;
6150   }
6151 
6152   /* TO DO: sort items by how they are listed */
6153 
6154   for (group_num = 0; group_num < 5; group_num++) {
6155     for (seq_num = 0; seq_num < num; seq_num++) {
6156       if (GetDisplayGroupNum(fpp + seq_num) == group_num) {
6157         if (list_offset == list_pos) {
6158           return seq_num;
6159         }
6160         list_offset++;
6161       }
6162     }
6163   }
6164   return 0;
6165 }
6166 
ReleaseFarPointer(DoC d,PoinT pt)6167 static void ReleaseFarPointer (DoC d, PoinT pt)
6168 
6169 {
6170   Int2            col;
6171   FarPointerWinPtr  fpwp;
6172   Int2            item;
6173   RecT            rct;
6174   Int2            row;
6175   Int4            seq_num, group_num;
6176 
6177   fpwp = (FarPointerWinPtr) GetObjectExtra (d);
6178   if (fpwp != NULL && fpwp->selected != NULL) {
6179     MapDocPoint (d, pt, &item, &row, &col, &rct);
6180     rct.left += 1;
6181     rct.right = rct.left + fpwp->lineheight;
6182     rct.bottom = rct.top + (rct.right - rct.left);
6183     if (row == 1 && col == 3 && PtInRect (pt, &rct))
6184     {
6185       seq_num = GetSeqNumFromListPos (item - 1, fpwp->far_pointer_list, fpwp->num_sequences);
6186       if (seq_num > -1 && seq_num < fpwp->num_sequences)
6187       {
6188         group_num = GetDisplayGroupNum(fpwp->far_pointer_list + seq_num);
6189         if (group_num == 3 || group_num == 4) {
6190           /* can never replace non-far pointers */
6191           fpwp->selected[seq_num] = FALSE;
6192         } else if (fpwp->selected [seq_num]) {
6193           fpwp->selected [seq_num] = FALSE;
6194         } else {
6195           fpwp->selected [seq_num] = TRUE;
6196         }
6197         InsetRect (&rct, -1, -1);
6198         InvalRect (&rct);
6199         Update ();
6200       }
6201     }
6202   }
6203 }
6204 
DrawFarPointer(DoC d,RectPtr r,Int2 item,Int2 firstLine)6205 static void DrawFarPointer (DoC d, RectPtr r, Int2 item, Int2 firstLine)
6206 
6207 {
6208   FarPointerWinPtr fpwp;
6209   RecT             rct;
6210   RecT             doc_rect;
6211   Int4             seq_num, group_num;
6212 
6213   fpwp = (FarPointerWinPtr) GetObjectExtra (d);
6214 
6215   if (fpwp == NULL || r == NULL
6216       || item < 1 || item > fpwp->num_sequences
6217       || firstLine != 0)
6218   {
6219     return;
6220   }
6221 
6222   rct = *r;
6223   rct.right --;
6224   rct.left = rct.right - fpwp->lineheight;
6225   rct.bottom = rct.top + (rct.right - rct.left);
6226 
6227   /* make sure we don't draw a box where we aren't drawing text */
6228   ObjectRect (fpwp->doc, &doc_rect);
6229   InsetRect (&doc_rect, 4, 4);
6230   if (rct.bottom > doc_rect.bottom)
6231   {
6232     return;
6233   }
6234 
6235   seq_num = GetSeqNumFromListPos (item - 1, fpwp->far_pointer_list, fpwp->num_sequences);
6236   if (seq_num > -1 && seq_num < fpwp->num_sequences) {
6237     group_num = GetDisplayGroupNum(fpwp->far_pointer_list + seq_num);
6238     if (group_num != 3 && group_num != 4) {
6239       FrameRect (&rct);
6240 
6241       if (fpwp->selected != NULL && fpwp->selected [seq_num]) {
6242         MoveTo (rct.left, rct.top);
6243         LineTo (rct.right - 1, rct.bottom - 1);
6244         MoveTo (rct.left, rct.bottom - 1);
6245         LineTo (rct.right - 1, rct.top);
6246       }
6247     }
6248   }
6249 }
6250 
GetTextForOneFarPointerData(FarPointerPtr fpp,CharPtr doc_line)6251 static void GetTextForOneFarPointerData (FarPointerPtr fpp, CharPtr doc_line)
6252 {
6253   CharPtr      cp;
6254 
6255   if (fpp == NULL || doc_line == NULL) return;
6256 
6257   SeqIdWrite (fpp->sip_local, doc_line, PRINTID_TEXTID_ACC_ONLY, 255);
6258   if (fpp->sip_db == NULL) {
6259     StringCat (doc_line, "\tNot a far pointer\t\n");
6260   } else if (fpp->bsp_db == NULL) {
6261     StringCat (doc_line, "\tNot found in GenBank\t\n");
6262   } else if (fpp->err_msg != NULL) {
6263     /* replace carriage returns with spaces */
6264     cp = StringChr (fpp->err_msg, '\n');
6265     while (cp != NULL) {
6266       *cp = ' ';
6267       cp = StringChr (cp + 1, '\n');
6268     }
6269     /* replace tabs with spaces */
6270     cp = StringChr (fpp->err_msg, '\t');
6271     while (cp != NULL) {
6272       *cp = ' ';
6273       cp = StringChr (cp + 1, '\t');
6274     }
6275 
6276     StringCat (doc_line, "\t");
6277     StringCat (doc_line, fpp->err_msg);
6278     StringCat (doc_line, "\t\n");
6279   } else {
6280     StringCat (doc_line, "\t\t\n");
6281   }
6282 }
6283 
RedrawFarPointerWin(FarPointerWinPtr fpwp)6284 static void RedrawFarPointerWin (FarPointerWinPtr fpwp)
6285 {
6286   Int4         i, group_num;
6287   Char         doc_line [500];
6288 
6289   if (fpwp == NULL)
6290   {
6291     return;
6292   }
6293 
6294   Reset (fpwp->doc);
6295 
6296   for (group_num = 0; group_num < 5; group_num++) {
6297     for (i = 0; i < fpwp->num_sequences; i++) {
6298       if (GetDisplayGroupNum(fpwp->far_pointer_list + i) == group_num) {
6299         GetTextForOneFarPointerData (fpwp->far_pointer_list + i, doc_line);
6300         AppendText (fpwp->doc, doc_line, &(fpwp->ParFmt), fpwp->ColFmt, Nlm_programFont);
6301         if (group_num == 2) {
6302           fpwp->selected [i] = TRUE;
6303         } else {
6304           fpwp->selected [i] = FALSE;
6305         }
6306       }
6307     }
6308   }
6309 
6310 
6311   UpdateDocument (fpwp->doc, 0, 0);
6312 }
6313 
ExportBadAlignments(ButtoN b)6314 static void ExportBadAlignments (ButtoN b)
6315 {
6316   FarPointerWinPtr   fpwp;
6317   Char               path [PATH_MAX];
6318   FILE               *fp;
6319   Int4               i;
6320   Char               str[50];
6321 
6322   fpwp = (FarPointerWinPtr) GetObjectExtra (b);
6323   if (fpwp == NULL) return;
6324 
6325   if (GetOutputFileName (path, sizeof (path), NULL)) {
6326     fp = FileOpen (path, "w");
6327     if (fp == NULL) {
6328       Message (MSG_ERROR, "Unable to open %s", path);
6329       return;
6330     }
6331     for (i = 0; i < fpwp->num_sequences; i++) {
6332       if (fpwp->far_pointer_list[i].salp != NULL
6333           && fpwp->far_pointer_list[i].err_msg != NULL) {
6334         SeqIdWrite (fpwp->far_pointer_list[i].sip_local, str, PRINTID_FASTA_LONG, sizeof (str) - 1);
6335         fprintf (fp, "%s\n", str);
6336         fprintf (fp, "%s\n", fpwp->far_pointer_list[i].err_msg);
6337         WriteAlignmentInterleaveToFileEx (fpwp->far_pointer_list[i].salp, fp,
6338                                         60, TRUE, TRUE);
6339       }
6340     }
6341   }
6342   FileClose (fp);
6343 }
6344 
6345 
ExportFASTAForUnselectedUpdates(ButtoN b)6346 static void ExportFASTAForUnselectedUpdates (ButtoN b)
6347 {
6348   FarPointerWinPtr   fpwp;
6349   Char               path [PATH_MAX];
6350   FILE               *fp;
6351   Int4               i;
6352 
6353   fpwp = (FarPointerWinPtr) GetObjectExtra (b);
6354   if (fpwp == NULL) return;
6355 
6356   if (GetOutputFileName (path, sizeof (path), NULL)) {
6357     fp = FileOpen (path, "w");
6358     if (fp == NULL) {
6359       Message (MSG_ERROR, "Unable to open %s", path);
6360       return;
6361     }
6362     for (i = 0; i < fpwp->num_sequences; i++) {
6363       if (fpwp->far_pointer_list[i].bsp_local != NULL
6364           && !fpwp->selected[i]) {
6365         EditBioseqToFasta (fpwp->far_pointer_list[i].bsp_local, fp, 0, fpwp->far_pointer_list[i].bsp_local->length - 1);
6366       }
6367     }
6368   }
6369   FileClose (fp);
6370 }
6371 
ExportFarPointerErrorMessages(ButtoN b)6372 static void ExportFarPointerErrorMessages (ButtoN b)
6373 {
6374   FarPointerWinPtr   fpwp;
6375   Char               path [PATH_MAX];
6376   FILE               *fp;
6377   Int4               i;
6378   Char               str[50];
6379 
6380   fpwp = (FarPointerWinPtr) GetObjectExtra (b);
6381   if (fpwp == NULL) return;
6382 
6383   TmpNam (path);
6384   fp = FileOpen (path, "w");
6385   if (fp == NULL) {
6386     Message (MSG_ERROR, "Unable to open %s", path);
6387     return;
6388   }
6389   for (i = 0; i < fpwp->num_sequences; i++) {
6390     if (fpwp->far_pointer_list[i].err_msg != NULL
6391         && fpwp->far_pointer_list[i].sip_local != NULL) {
6392         SeqIdWrite (fpwp->far_pointer_list[i].sip_local, str, PRINTID_FASTA_LONG, sizeof (str) - 1);
6393         fprintf (fp, "%s\t%s\n", str, fpwp->far_pointer_list[i].err_msg);
6394     }
6395   }
6396   FileClose (fp);
6397   LaunchGeneralTextViewer (path, "FarPointer Errors");
6398   FileRemove (path);
6399 }
6400 
6401 
DisplayFarPointerData(FarPointerPtr fpp,Int4 num)6402 static Boolean DisplayFarPointerData (FarPointerPtr fpp, Int4 num)
6403 {
6404   WindoW w;
6405   ModalAcceptCancelData acd;
6406   FarPointerWinPtr   fpwp;
6407   ButtoN             b;
6408   GrouP              h, g, c;
6409   RecT               r;
6410   Int4               i;
6411 
6412   if (fpp == NULL) {
6413     return FALSE;
6414   }
6415 
6416   fpwp = (FarPointerWinPtr) MemNew (sizeof (FarPointerWinData));
6417 
6418   fpwp->far_pointer_list = fpp;
6419   fpwp->num_sequences = num;
6420   fpwp->selected = (BoolPtr) MemNew (sizeof(Boolean) * num);
6421 
6422   /* initialize document paragraph format */
6423   fpwp->ParFmt.openSpace = FALSE;
6424   fpwp->ParFmt.keepWithNext = FALSE;
6425   fpwp->ParFmt.keepTogether = FALSE;
6426   fpwp->ParFmt.newPage = FALSE;
6427   fpwp->ParFmt.tabStops = FALSE;
6428   fpwp->ParFmt.minLines = 0;
6429   fpwp->ParFmt.minHeight = 0;
6430 
6431   /* initialize document column format */
6432   fpwp->ColFmt[0].pixWidth = 0;
6433   fpwp->ColFmt[0].pixInset = 0;
6434   fpwp->ColFmt[0].charWidth = 80;
6435   fpwp->ColFmt[0].charInset = 0;
6436   fpwp->ColFmt[0].font = NULL;
6437   fpwp->ColFmt[0].just = 'l';
6438   fpwp->ColFmt[0].wrap = TRUE;
6439   fpwp->ColFmt[0].bar = FALSE;
6440   fpwp->ColFmt[0].underline = FALSE;
6441   fpwp->ColFmt[0].left = FALSE;
6442   fpwp->ColFmt[0].last = FALSE;
6443   fpwp->ColFmt[1].pixWidth = 0;
6444   fpwp->ColFmt[1].pixInset = 0;
6445   fpwp->ColFmt[1].charWidth = 80;
6446   fpwp->ColFmt[1].charInset = 0;
6447   fpwp->ColFmt[1].font = NULL;
6448   fpwp->ColFmt[1].just = 'l';
6449   fpwp->ColFmt[1].wrap = TRUE;
6450   fpwp->ColFmt[1].bar = FALSE;
6451   fpwp->ColFmt[1].underline = FALSE;
6452   fpwp->ColFmt[1].left = FALSE;
6453   fpwp->ColFmt[1].last = FALSE;
6454   fpwp->ColFmt[2].pixWidth = 0;
6455   fpwp->ColFmt[2].pixInset = 0;
6456   fpwp->ColFmt[2].charWidth = 80;
6457   fpwp->ColFmt[2].charInset = 0;
6458   fpwp->ColFmt[2].font = NULL;
6459   fpwp->ColFmt[2].just = 'l';
6460   fpwp->ColFmt[2].wrap = TRUE;
6461   fpwp->ColFmt[2].bar = FALSE;
6462   fpwp->ColFmt[2].underline = FALSE;
6463   fpwp->ColFmt[2].left = FALSE;
6464   fpwp->ColFmt[2].last = TRUE;
6465 
6466   w = MovableModalWindow (50, 33, -10, -10, "Far Pointer Sequences", NULL);
6467   SetObjectExtra (w, fpwp, CleanupFarPointerWinProc);
6468   fpwp->form = (ForM) w;
6469 
6470   h = HiddenGroup (w, -1, 0, NULL);
6471   SetGroupSpacing (h, 10, 10);
6472 
6473   fpwp->doc = DocumentPanel (h, stdCharWidth * 50, stdLineHeight * 20);
6474   SetObjectExtra (fpwp->doc, fpwp, NULL);
6475   SetDocAutoAdjust (fpwp->doc, TRUE);
6476   SetDocProcs (fpwp->doc, NULL, NULL, ReleaseFarPointer, NULL);
6477   SetDocShade (fpwp->doc, DrawFarPointer, NULL, NULL, NULL);
6478 
6479   SelectFont (Nlm_programFont);
6480   fpwp->lineheight = LineHeight ();
6481 
6482   ObjectRect (fpwp->doc, &r);
6483   InsetRect (&r, 4, 4);
6484   fpwp->ColFmt[0].pixWidth = (r.right - r.left - fpwp->lineheight) / 2;
6485   fpwp->ColFmt[1].pixWidth = (r.right - r.left - fpwp->lineheight) / 2;
6486   fpwp->ColFmt[2].pixWidth = fpwp->lineheight;
6487 
6488   g = HiddenGroup (h, 4, 0, NULL);
6489   b = PushButton (g, "Export Bad Alignments", ExportBadAlignments);
6490   SetObjectExtra (b, fpwp, NULL);
6491   Disable (b);
6492   for (i = 0; i < fpwp->num_sequences; i++) {
6493     if (fpwp->far_pointer_list[i].salp != NULL && fpwp->far_pointer_list[i].err_msg != NULL) {
6494       Enable (b);
6495       break;
6496     }
6497   }
6498   b = PushButton (g, "Export FASTA for Unselected Sequences", ExportFASTAForUnselectedUpdates);
6499   SetObjectExtra (b, fpwp, NULL);
6500 
6501   b = PushButton (g, "Export FarPointer Error Messages", ExportFarPointerErrorMessages);
6502   SetObjectExtra (b, fpwp, NULL);
6503 
6504   c = HiddenGroup (h, 2, 0, NULL);
6505   b = PushButton (c, "Replace Selected Sequences", ModalAcceptButton);
6506   SetObjectExtra (b, &acd, NULL);
6507   b = PushButton (c, "Cancel", ModalCancelButton);
6508   SetObjectExtra (b, &acd, NULL);
6509 
6510   AlignObjects (ALIGN_CENTER, (HANDLE) fpwp->doc,
6511                               (HANDLE) g,
6512                               (HANDLE) c,
6513                               NULL);
6514   RedrawFarPointerWin (fpwp);
6515   Show (w);
6516   Select (w);
6517   ArrowCursor();
6518   Update ();
6519 
6520   acd.accepted = FALSE;
6521   acd.cancelled = FALSE;
6522   while (!acd.accepted && ! acd.cancelled)
6523   {
6524     ProcessExternalEvent ();
6525     Update ();
6526   }
6527   ProcessAnEvent ();
6528 
6529   if (acd.accepted)
6530   {
6531     Hide (w);
6532     for (i = 0; i < num; i++) {
6533       if (!fpwp->selected[i]) {
6534         fpp[i].salp = SeqAlignFree (fpp[i].salp);
6535         BioseqUnlock (fpp[i].bsp_db);
6536         fpp[i].bsp_db = NULL;
6537         fpp[i].sip_db = SeqIdFree (fpp[i].sip_db);
6538         /* make sure local sequence is not deleted */
6539         BioseqUnlock (fpp[i].bsp_local);
6540         fpp[i].bsp_local = NULL;
6541       }
6542     }
6543 
6544   }
6545   Remove (w);
6546   WatchCursor();
6547   Update();
6548   return acd.accepted;
6549 }
6550 
6551 
FindFarPointerID(CharPtr str)6552 static CharPtr FindFarPointerID (CharPtr str)
6553 {
6554   CharPtr tmp = NULL;
6555   if (StringHasNoText (str)) return NULL;
6556 
6557   if (StringNICmp (str, "acc", 3) == 0) {
6558     tmp = str + 3;
6559   } else {
6560     tmp = StringSearch (str, "|acc");
6561     if (tmp != NULL) {
6562       tmp += 4;
6563     }
6564   }
6565   return tmp;
6566 }
6567 
6568 
InitOneFarPointerData(FarPointerPtr p,SeqAlignPtr salp,Int4 pos)6569 static void InitOneFarPointerData (FarPointerPtr p, SeqAlignPtr salp, Int4 pos)
6570 {
6571   CharPtr             tmp, id_start, dot_pos;
6572   Char                str [150];
6573   Int4                gi = 0;
6574   Int4                version;
6575   BLAST_OptionsBlkPtr options;
6576   SeqAlignPtr         tmp_salp;
6577 
6578   if (p == NULL || salp == NULL) {
6579     return;
6580   }
6581 
6582   p->sip_local = AlnMgr2GetNthSeqIdPtr(salp, pos + 1);
6583   p->sip_db = NULL;
6584   p->bsp_local = NULL;
6585   p->bsp_db = NULL;
6586   p->salp = NULL;
6587   p->revcomp = FALSE;
6588   p->nonly = 0;
6589   p->err_type = FARPOINTER_LOOKUP_NO_ERROR;
6590 
6591   /* is this a farpointer ID? */
6592   SeqIdWrite (p->sip_local, str, PRINTID_FASTA_LONG, sizeof (str) - 1);
6593   tmp = FindFarPointerID (str);
6594   if (tmp!=NULL) {
6595     if (*tmp == '|')
6596         tmp++;
6597     id_start = tmp;
6598 
6599     /* look for next pipe char, carriage return, or end of string */
6600     while (*tmp!='\0' && *tmp != '|' && *tmp!='\n')
6601       tmp++;
6602     *tmp = '\0';
6603 
6604     /* check for version */
6605     version = 0;
6606     dot_pos = StringChr (id_start, '.');
6607     if (dot_pos != NULL) {
6608       *dot_pos = '\0';
6609       version = atoi (dot_pos + 1);
6610     }
6611     if (StringSpn (id_start, "0123456789") == StringLen (id_start)) {
6612       /* all numbers, is GI */
6613       gi = (Int4)atol(id_start);
6614       if (gi>0) {
6615         p->sip_db = ValNodeNew (NULL);
6616         if (p->sip_db) {
6617           p->sip_db->choice = SEQID_GI;
6618           p->sip_db->data.intvalue = (Int4)gi;
6619         }
6620       }
6621     } else if (IS_ntdb_accession(id_start) || IS_protdb_accession(id_start)) {
6622       p->sip_db = SeqIdFromAccession (id_start, version, NULL);
6623     }
6624     if (p->sip_db != NULL) {
6625       p->bsp_local = BioseqLockById(p->sip_local);
6626       p->bsp_db = BioseqLockById(p->sip_db);
6627       if (p->bsp_local != NULL
6628           && p->bsp_db != NULL
6629           && p->bsp_local->length > 0
6630           && p->bsp_db->length > 0) {
6631         options = BLASTOptionNew("blastn", TRUE);
6632         options->filter_string = StringSave("m L;R");
6633         tmp_salp = BlastTwoSequences (p->bsp_local, p->bsp_db, "blastn", options);
6634         options = BLASTOptionDelete(options);
6635         if (tmp_salp == NULL) {
6636           p->err_msg = StringSave ("No alignment found!");
6637           p->err_type = FARPOINTER_LOOKUP_BAD_ALN;
6638         } else {
6639           p->err_msg = (CharPtr) MemNew (sizeof(Char) * 1000);
6640           p->err_msg[0] = 0;
6641           p->salp = SeqAlignBestHit (tmp_salp,
6642                                     p->bsp_local,
6643                                     p->bsp_db,
6644                                     100, &(p->err_msg),
6645                                     &(p->nonly));
6646           if (p->err_msg[0] == '\0')
6647             p->err_msg = MemFree (p->err_msg);
6648           else if (p->nonly < 0)
6649             p->err_type = FARPOINTER_LOOKUP_NONLY;
6650           else
6651             p->err_type = FARPOINTER_LOOKUP_BAD_ALN;
6652         }
6653       }
6654     }
6655   }
6656 }
6657 
6658 
DoOneFarPointerDataReplacement(FarPointerPtr p,SeqAlignPtr salp)6659 static void DoOneFarPointerDataReplacement (FarPointerPtr p, SeqAlignPtr salp)
6660 {
6661   Int4                offset, len, start1, start2, stop1, stop2;
6662   Uint1               strand;
6663   DenseSegPtr         dsp;
6664   SeqIdPtr            sip, presip = NULL;
6665 
6666   if (p == NULL || p->bsp_db == NULL || salp == NULL || salp->segtype != SAS_DENSEG
6667       || (dsp = (DenseSegPtr) salp->segs) == NULL) {
6668     return;
6669   }
6670 
6671   /* adjust alignment for difference between snippet and actual sequence */
6672   offset = SeqAlignStart(p->salp, 1)-SeqAlignStart(p->salp, 0);
6673   if ((SeqAlignStrand(p->salp, 0)==Seq_strand_minus && SeqAlignStrand(p->salp, 1) != Seq_strand_minus)
6674       || (SeqAlignStrand(p->salp, 1)==Seq_strand_minus && SeqAlignStrand(p->salp, 0) != Seq_strand_minus))
6675   {
6676     /* strand is reversed */
6677     strand=Seq_strand_minus;
6678     AlnMgr2IndexSingleChildSeqAlign(p->salp);
6679     AlnMgr2GetNthSeqRangeInSA(p->salp, 1, &start1, &stop1);
6680     AlnMgr2GetNthSeqRangeInSA(p->salp, 2, &start2, &stop2);
6681     len = stop2 + start1;
6682     if (offset < 0)
6683     {
6684       offset = 0 - offset;
6685     }
6686   } else {
6687     strand=Seq_strand_plus;
6688     len = 0;
6689   }
6690   SeqAlignStartUpdate (salp, p->sip_local, abs(offset), len, strand);
6691 
6692   /* replace local ID in dsp->ids with database ID */
6693   sip = dsp->ids;
6694   while (sip != NULL && SeqIdComp (sip, p->sip_local) != SIC_YES) {
6695     presip = sip;
6696     sip = sip->next;
6697   }
6698 
6699   p->sip_db->next = sip->next;
6700   sip->next = NULL;
6701   if (presip == NULL) {
6702     dsp->ids = SeqIdFree (dsp->ids);
6703     dsp->ids = p->sip_db;
6704   } else {
6705     presip->next = SeqIdFree (presip->next);
6706     presip->next = p->sip_db;
6707   }
6708   p->sip_db = NULL;
6709 
6710 }
6711 
6712 
UpdateOneSeqAlignFarPointer(SeqAlignPtr salp,Int4 pos)6713 NLM_EXTERN Boolean UpdateOneSeqAlignFarPointer (SeqAlignPtr salp, Int4 pos)
6714 {
6715   FarPointerPtr p;
6716   Boolean        rval = FALSE;
6717 
6718   p = (FarPointerPtr) MemNew (sizeof (FarPointerData));
6719   InitOneFarPointerData (p, salp, pos);
6720   if (p->sip_db != NULL
6721       && p->bsp_db != NULL
6722       && p->salp != NULL
6723       && p->nonly == 0
6724       && p->err_msg == NULL) {
6725     DoOneFarPointerDataReplacement (p, salp);
6726     rval = TRUE;
6727   }
6728   p = FarPointerFree (p);
6729   return rval;
6730 }
6731 
6732 
6733 /* This function will replace a sequence in an alignment record with one
6734  * downloaded from GenBank.  It will also adjust the alignment starts
6735  * for that sequence if the GenBank sequence is not identical to the
6736  * sequence in the alignment (salp).
6737  * vnp is a ValNodePtr to a list of sequence IDs for Bioseqs to be deleted
6738  * later.
6739  */
CCNormalizeSeqAlignId(SeqAlignPtr salp,ValNodePtr vnp)6740 static ValNodePtr CCNormalizeSeqAlignId (SeqAlignPtr salp, ValNodePtr vnp)
6741 {
6742   Int4 num_rows, i;
6743   FarPointerPtr far_pointer_list = NULL;
6744   CharPtr       missing_cont_fmt = "The alignment contains %s that can not be found in GenBank.\nPlease check the accession number.\nContinue anyway?\n";
6745   CharPtr       missing_fmt = "The alignment contains %s that can not be found in GenBank.\nPlease check the accession number.\n";
6746   Int4                gi = 0;
6747   DenseSegPtr         dsp;
6748   Int4                offset, len, start1, start2, stop1, stop2;
6749   SeqIdPtr            sip, presip;
6750   Uint1               strand;
6751 
6752   if (salp == NULL || salp->segtype != 2) {
6753     return vnp;
6754   }
6755 
6756   dsp = (DenseSegPtr) salp->segs;
6757 
6758   AlnMgr2IndexSingleChildSeqAlign(salp);
6759   num_rows = AlnMgr2GetNumRows(salp);
6760 
6761   far_pointer_list = (FarPointerPtr) MemNew (num_rows * sizeof (FarPointerData));
6762 
6763   for (i = 0; i < num_rows; i++) {
6764     InitOneFarPointerData (far_pointer_list + i, salp, i);
6765   }
6766 
6767   if (DisplayFarPointerData (far_pointer_list, num_rows)) {
6768     /* for each entry that still has a bioseq, do the replacement */
6769     presip = NULL;
6770     for (i = 0, sip = dsp->ids; i < num_rows && sip != NULL; i++, sip = sip->next) {
6771       if (far_pointer_list[i].bsp_db == NULL) {
6772         continue;
6773       }
6774       offset = SeqAlignStart(far_pointer_list[i].salp, 1)-SeqAlignStart(far_pointer_list[i].salp, 0);
6775       if ((SeqAlignStrand(far_pointer_list[i].salp, 0)==Seq_strand_minus && SeqAlignStrand(far_pointer_list[i].salp, 1) != Seq_strand_minus)
6776           || (SeqAlignStrand(far_pointer_list[i].salp, 1)==Seq_strand_minus && SeqAlignStrand(far_pointer_list[i].salp, 0) != Seq_strand_minus))
6777       {
6778         /* strand is reversed */
6779         strand=Seq_strand_minus;
6780         AlnMgr2IndexSingleChildSeqAlign(far_pointer_list[i].salp);
6781         AlnMgr2GetNthSeqRangeInSA(far_pointer_list[i].salp, 1, &start1, &stop1);
6782         AlnMgr2GetNthSeqRangeInSA(far_pointer_list[i].salp, 2, &start2, &stop2);
6783         len = stop2 + start1;
6784         if (offset < 0)
6785         {
6786           offset = 0 - offset;
6787         }
6788       } else {
6789         strand=Seq_strand_plus;
6790         len = 0;
6791       }
6792       SeqAlignStartUpdate (salp, far_pointer_list[i].sip_local, abs(offset), len, strand);
6793 
6794       dsp->ids = SWSeqIdReplaceID(dsp->ids, far_pointer_list[i].sip_local, far_pointer_list[i].sip_db);
6795       /* set to NULL so that we don't free it later */
6796       far_pointer_list[i].sip_db = NULL;
6797 
6798       if (presip)
6799         sip = presip->next;
6800       else
6801         sip = dsp->ids;
6802       /* We add the ID of the sequence we are replacing to a list
6803        * of sequences that will be deleted later.
6804        * We can't delete the sequence now, in case it is present
6805        * in more than one alignment for this record.
6806        */
6807       vnp = nrSeqIdAdd (vnp, far_pointer_list[i].sip_local);
6808       /* set to NULL so that we don't free it later */
6809       far_pointer_list[i].sip_local = NULL;
6810     }
6811   } else {
6812     for (i = 0, sip = dsp->ids; i < num_rows && sip != NULL; i++, sip = sip->next) {
6813       if (far_pointer_list[i].bsp_db != NULL) {
6814         BioseqUnlock (far_pointer_list[i].bsp_db);
6815         far_pointer_list[i].bsp_db->idx.deleteme = TRUE;
6816       }
6817       if (far_pointer_list[i].bsp_local != NULL) {
6818         BioseqUnlock (far_pointer_list[i].bsp_local);
6819         far_pointer_list[i].bsp_local = NULL;
6820       }
6821     }
6822   }
6823 
6824   far_pointer_list = FreeFarPointerData(far_pointer_list, num_rows);
6825 
6826   return vnp;
6827 }
6828 
6829 static ValNodePtr errorp = NULL;
6830 
6831 /******************************************************************
6832 Output error message according to code defined in alignval.h.
6833 id refers to seqid of the sequence that causes the error
6834 and idcontext refers to other sequences in the same segment.
6835 Intvalue is used to indicate 1) the segment where the sequence
6836 with error is, or 2) the segtype in case of segtype error.
6837 Please note that not all errors report all three
6838 parameters(id, idcontext, Intvalue)
6839 ******************************************************************/
ValMessage(Int1 MessageCode,ErrSev errlevel,SeqIdPtr id,SeqIdPtr idcontext,Int4 Intvalue)6840 static void ValMessage (Int1 MessageCode, ErrSev errlevel, SeqIdPtr id, SeqIdPtr idcontext , Int4 Intvalue)
6841 {
6842 
6843   Char     buf[256],
6844            buf3[64],
6845            string1[64],
6846            string2[252];
6847 
6848   string1[0] = '\0';
6849   string2[0] = '\0';
6850   SeqIdWrite(id, buf, PRINTID_FASTA_LONG, sizeof(buf)-1);
6851   switch(MessageCode)
6852   {
6853     case Err_SeqId:
6854       sprintf(string1, "SeqId");
6855       sprintf(string2, "Invalid Seq_id: %s\n", buf);
6856       break;
6857 
6858     case Err_Strand_Rev:
6859       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6860       sprintf(string1, "Strand");
6861       sprintf(string2, "Alignment strand is reversed in segment %d for Seq ID: %s in the context of%s\n", Intvalue, buf, buf3);
6862       break;
6863 
6864     case Err_Denseg_Len_Start:
6865       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6866       sprintf(string1, "Start/Length");
6867       sprintf(string2, "Error in length and/or starts in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
6868       break;
6869 
6870     case  Err_Start_Less_Than_Zero:
6871         //LCOV_EXCL_START
6872         //not reachable with valid ASN.1 for C++ Toolkit
6873       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6874       sprintf(string1, "Start");
6875       sprintf(string2, "Start point is less than zero in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
6876       break;
6877       //LCOV_EXCL_STOP
6878 
6879     case Err_Start_More_Than_Biolen:
6880       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6881       sprintf(string1, "Start");
6882       sprintf(string2, "Start point is greater than total bioseq length in segment %d for sequence ID: %s in the context of%s\n", Intvalue, buf, buf3);
6883       break;
6884 
6885     case Err_End_Less_Than_Zero:
6886       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6887       sprintf(string1, "Length");
6888       sprintf(string2, "End point is less than zero in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
6889       break;
6890 
6891     case Err_End_More_Than_Biolen:
6892       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6893       sprintf(string1, "Length");
6894       sprintf(string2, "End point is greater than total bioseq length in segment %d for sequence ID: %s in the context of%s\n", Intvalue, buf, buf3);
6895       break;
6896 
6897     case Err_Len_Less_Than_Zero:
6898       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6899       sprintf(string1, "Length");
6900       sprintf(string2, "Segment length is less than zero in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
6901       break;
6902 
6903     case Err_Len_More_Than_Biolen:
6904       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6905       sprintf(string1, "Length");
6906       sprintf(string2, "Segment length is greater than total bioseq length in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
6907       break;
6908 
6909     case Err_Sum_Len_Start:
6910       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6911       sprintf(string1, "Start");
6912       sprintf(string2, "Sum of start point and segment is greater than total bioseq length in segment %d  for sequence ID: %s in the context of %s\n",  Intvalue, buf, buf3);
6913       break;
6914 
6915     case Err_SeqAlign_DimSeqId_Not_Match:
6916       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6917       sprintf(string1, "SeqId");
6918       sprintf(string2, "The number of SeqId does not match the dimensions for sequence ID's %s\n", buf3);
6919       break;
6920 
6921     case Err_Segs_DimSeqId_Not_Match:
6922       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6923       sprintf(string1, "SeqId");
6924       sprintf(string2, "The number of SeqId does not match the dimensions in segment %d for  sequence ID's %s\n", Intvalue, buf3);
6925       break;
6926 
6927     case Err_Fastalike:
6928       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6929       sprintf(string1, "Fasta");
6930       sprintf(string2, "This may be a fasta-like alignment for SeqId: %s in the context of %s\n", buf, buf3);
6931       break;
6932 
6933     case Err_Null_Segs:
6934       sprintf(string1, "Segs");
6935       sprintf(string2, "This alignment contains a null segs\n");
6936       break;
6937 
6938     case Err_Segment_Gap:
6939       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6940       sprintf(string1, "Segs");
6941       sprintf(string2, "Segment %d is a gap for all sequence with the following ID's: %s\n", Intvalue, buf3);
6942       break;
6943 
6944     case Err_Segs_Dim_One:
6945       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6946       sprintf(string1, "Segs");
6947       sprintf(string2, "There is only one dimension in segment %d for  sequence ID's %s\n", Intvalue, buf3);
6948       break;
6949 
6950     case Err_SeqAlign_Dim_One:
6951       SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
6952       sprintf(string1, "Dim");
6953       sprintf(string2, "There is only one dimension for sequence ID's %s\n", buf3);
6954       break;
6955 
6956     case Err_Segtype :
6957       sprintf(string1, "Segs");
6958       sprintf(string2, "This alignment has a undefined or unsupported Seqalign segtype %d\n", Intvalue);
6959       break;
6960 
6961     default:
6962       break;
6963   }
6964   if (StringLen(string1) > 0)
6965      errorp = BlastConstructErrorMessage (string1, string2, errlevel, &errorp);
6966 }
6967 
6968 /******************************************************************
6969 validate each alignment sequentially.
6970 This function will subject the seqalign to all validation functions
6971 ******************************************************************/
6972 /*********************************************************/
delete_bioseqs(ValNodePtr ids,Uint2 entityID)6973 static void delete_bioseqs (ValNodePtr ids, Uint2 entityID)
6974 {
6975   SeqEntryPtr  sep_top;
6976   SeqEntryPtr  sep_del;
6977   ValNodePtr   vnp;
6978   SeqIdPtr     sip;
6979   SeqLocPtr    slp;
6980   BioseqPtr    bsp;
6981   ObjMgrDataPtr  omdptop;
6982   ObjMgrData     omdata;
6983   Uint2          parenttype;
6984   Pointer        parentptr;
6985 
6986   if (ids == NULL)
6987      return;
6988   sep_top = GetTopSeqEntryForEntityID (entityID);
6989   SaveSeqEntryObjMgrData (sep_top, &omdptop, &omdata);
6990   GetSeqEntryParent (sep_top, &parentptr, &parenttype);
6991 
6992   vnp=ids;
6993   while (vnp!=NULL)
6994   {
6995      sip = (SeqIdPtr) vnp->data.ptrvalue;
6996      if (sip!=NULL) {
6997         slp = (SeqLocPtr)ValNodeNew (NULL);
6998         slp->choice = SEQLOC_WHOLE;
6999         slp->data.ptrvalue = sip;
7000         bsp = GetBioseqGivenSeqLoc (slp, entityID);
7001         if (bsp!=NULL) {
7002            sep_del=GetBestTopParentForData (entityID, bsp);
7003            RemoveSeqEntryFromSeqEntry (sep_top, sep_del, FALSE);
7004         }
7005         slp->data.ptrvalue = NULL;
7006         SeqLocFree (slp);
7007      }
7008      vnp=vnp->next;
7009   }
7010   SeqMgrLinkSeqEntry (sep_top, parenttype, parentptr);
7011   RestoreSeqEntryObjMgrData (sep_top, omdptop, &omdata);
7012   RenormalizeNucProtSets (sep_top, TRUE);
7013 
7014   for (vnp=ids; vnp!=NULL; vnp=vnp->next) {
7015      SeqIdFree ((SeqIdPtr) vnp->data.ptrvalue);
7016      vnp->data.ptrvalue = NULL;
7017   }
7018   ValNodeFree (ids);
7019   return;
7020 }
7021 
7022 
check_dbid_seqalign(SeqAlignPtr salp)7023 static Boolean check_dbid_seqalign (SeqAlignPtr salp)
7024 {
7025   DenseSegPtr dsp;
7026   SeqIdPtr    sip, next;
7027   Char        str [52];
7028   CharPtr     TmpBuff, tmp;
7029   Int4        j, k;
7030   Boolean     found = FALSE;
7031 
7032   if (salp!=NULL)
7033   {
7034      if (salp->segtype == 2)
7035      {
7036         dsp = (DenseSegPtr) salp->segs;
7037         sip = dsp->ids;
7038         while (!found && sip != NULL)
7039         {
7040            next = sip->next;
7041            sip->next = NULL;
7042            SeqIdWrite (sip, str, PRINTID_FASTA_LONG, 50);
7043            sip->next = next;
7044            tmp = FindFarPointerID (str);
7045            if (tmp!=NULL) {
7046               if (*tmp == '|')
7047                  tmp++;
7048               TmpBuff = tmp;
7049               while (*tmp!='\0' && *tmp != '|' && *tmp!='\n' && *tmp != '.')
7050                  tmp++;
7051               *tmp = '\0';
7052 
7053               j = StringLen (TmpBuff);
7054               for(k =0; k < j; k++) {
7055                  if(!isdigit(TmpBuff[k])) {
7056                     break;
7057                  }
7058               }
7059               if(k != j) {
7060                 found=(IS_ntdb_accession(TmpBuff) || IS_protdb_accession(TmpBuff));
7061               }
7062            }
7063            sip = next;
7064         }
7065      }
7066   }
7067   return found;
7068 }
7069 
7070 
7071 /***************************************************************************************
7072 ***
7073 ***  ValidateSeqAlignandACC
7074 ***	calls ValidateSeqAlign (in api directory)
7075 ***	and tests for occurrence of ACC string in sequence ID.
7076 ***	ACC|ACC# will be compared with the corresponding sequence (ACC#)
7077 ***	in the database and replaced by a far pointer if the sequences
7078 ***	are identical.
7079 ***
7080 ***************************************************************************************/
7081 typedef struct saval {
7082   Boolean     message;
7083   Boolean     msg_success;
7084   Boolean     find_remote_bsp;
7085   Boolean     find_acc_bsp;
7086   Boolean     delete_salp;
7087   Boolean     delete_bsp;
7088   Boolean     retdel;
7089   ValNodePtr  ids;
7090   Uint2       entityID;
7091   Boolean     dirty;
7092 } SaVal, PNTR SaValPtr;
7093 
7094 
7095 static Boolean
ValidateSeqAlignandACCEx(SeqAlignPtr salp,Uint2 entityID,Boolean message,Boolean msg_success,Boolean find_remote_bsp,Boolean find_acc_bsp,Boolean delete_bsp,Boolean delete_salp,BoolPtr dirty,ValNodePtr PNTR id_list)7096 ValidateSeqAlignandACCEx
7097 (SeqAlignPtr salp, Uint2 entityID, Boolean message,
7098  Boolean msg_success, Boolean find_remote_bsp,Boolean find_acc_bsp,
7099  Boolean delete_bsp, Boolean delete_salp, BoolPtr dirty,
7100  ValNodePtr PNTR id_list) /* added id_list so that we could defer deleting bioseqs */
7101 {
7102   SeqAlignPtr  pre,
7103                salptmp;
7104   SaVal        sv;
7105   SaValPtr     svp;
7106   MsgAnswer    ans;
7107   Int2         err_count=0,
7108                salp_count=0;
7109   Boolean      ok;
7110   SeqEntryPtr  this_scope, orig_scope;
7111 
7112   if(salp!=NULL)
7113   {
7114     this_scope = GetTopSeqEntryForEntityID (salp->idx.entityID);
7115     orig_scope = SeqEntrySetScope (this_scope);
7116     /* initialize SaVal structure */
7117     sv.message = message;
7118     sv.msg_success = msg_success;
7119     sv.find_remote_bsp = find_remote_bsp;
7120     sv.find_acc_bsp = find_acc_bsp;
7121     sv.delete_salp = delete_salp;
7122     sv.delete_bsp = delete_bsp;
7123     sv.retdel = TRUE;
7124     sv.ids = NULL;
7125     sv.entityID = entityID;
7126     sv.dirty = FALSE;
7127     svp = &sv;
7128 
7129     pre=NULL;
7130     salptmp=salp;
7131     while (salptmp)
7132     {
7133       salp_count++;
7134       if(salp->segtype==5)
7135       {
7136         ValidateSeqAlignandACCEx ((SeqAlignPtr) (salptmp->segs), entityID,
7137                                   message, msg_success, find_remote_bsp,
7138                                   find_acc_bsp, delete_bsp, delete_salp,
7139                                   &svp->dirty, id_list);
7140       }
7141       else if (salp->segtype<1 || salp->segtype>4)
7142       {
7143         ValMessage (Err_Segtype, SEV_ERROR, NULL, NULL, salptmp->segtype);
7144       }
7145       else
7146       {
7147         ValidateSeqAlign (salptmp, svp->entityID, svp->message,
7148                           svp->msg_success, svp->find_remote_bsp,
7149                           svp->delete_bsp, svp->delete_salp, &svp->dirty);
7150         if (svp->find_acc_bsp)
7151         {
7152 	        ok = check_dbid_seqalign (salptmp);
7153 	        if (ok)
7154 	        {
7155 	          if (id_list != NULL)
7156 	          {
7157 	            svp->ids = *id_list;
7158 	          }
7159             svp->ids = CCNormalizeSeqAlignId (salptmp, svp->ids);
7160             if (svp->ids!=NULL && svp->entityID > 0) {
7161               if (svp->delete_bsp)
7162               {
7163                 delete_bioseqs (svp->ids, svp->entityID);
7164                 svp->ids = NULL;
7165               }
7166               svp->dirty = TRUE;
7167             }
7168           }
7169         }
7170       }
7171    	  if (errorp)
7172    	  {
7173         if(svp->message)
7174   	    {
7175           BlastErrorPrint (errorp);
7176           errorp = BlastErrorChainDestroy (errorp);
7177         }
7178         if (svp->delete_salp)
7179         {
7180           if (pre==NULL)
7181           {
7182             salp=salptmp->next;
7183             salptmp->next = NULL;
7184             SeqAlignFree (salptmp);
7185             salptmp = salp;
7186           }
7187           else
7188           {
7189             pre->next = salptmp->next;
7190             salptmp->next = NULL;
7191             SeqAlignFree (salptmp);
7192             salptmp = pre->next;
7193           }
7194         }
7195         else
7196         {
7197          	salptmp = salptmp->next;
7198         }
7199         err_count++;
7200         svp->retdel=FALSE;
7201       }
7202       else
7203       {
7204         salptmp = salptmp->next;
7205       }
7206     }
7207     if (err_count==0 && svp->msg_success)
7208     {
7209       if (salp_count>1)
7210         ans = Message (MSG_OK, "Validation test of %d alignments succeded", salp_count);
7211       else
7212         ans = Message (MSG_OK, "Validation test of the alignment succeded");
7213     }
7214     if (dirty)
7215       *dirty = svp->dirty;
7216 
7217     SeqEntrySetScope (orig_scope);
7218   }
7219   if (id_list != NULL)
7220   {
7221     *id_list = svp->ids;
7222   }
7223   return svp->retdel;
7224 }
7225 
ValidateSeqAlignandACC(SeqAlignPtr salp,Uint2 entityID,Boolean message,Boolean msg_success,Boolean find_remote_bsp,Boolean find_acc_bsp,Boolean delete_bsp,Boolean delete_salp,BoolPtr dirty)7226 NLM_EXTERN Boolean ValidateSeqAlignandACC (SeqAlignPtr salp, Uint2 entityID, Boolean message,
7227                          Boolean msg_success, Boolean find_remote_bsp,Boolean find_acc_bsp,
7228                          Boolean delete_bsp, Boolean delete_salp, BoolPtr dirty)
7229 {
7230   return ValidateSeqAlignandACCEx (salp, entityID, message, msg_success,
7231                                    find_remote_bsp, find_acc_bsp, delete_bsp,
7232                                    delete_salp, dirty, NULL);
7233 }
7234 
7235 /***************************************************************************
7236  *
7237  * ValidateAllAlignmentsInAnnotList (sap, svp)
7238  *
7239  * This function validates all of the alignments in the annotation list
7240  * (there may be multiple alignments, especially when there is an alignment
7241  * of segmented sequences), and then deletes the local versions of sequences
7242  * which have been replaced by farpointers.
7243  * We wait to remove the sequences in case the sequence is used in more than
7244  * one alignment, which may be the case if an alignment of segmented sets
7245  * contains a far pointer, and that far pointer points to a sequence that is
7246  * not actually a segmented set.
7247  *
7248  ***************************************************************************/
ValidateAllAlignmentsInAnnotList(SeqAnnotPtr sap,SaValPtr svp)7249 static void ValidateAllAlignmentsInAnnotList (SeqAnnotPtr sap, SaValPtr svp)
7250 {
7251   SeqAlignPtr salp;
7252   ValNodePtr  id_list = NULL;
7253 
7254   if (svp == NULL)
7255   {
7256     return;
7257   }
7258 
7259   while (sap != NULL)
7260   {
7261     if (sap->type == 2 && sap->data != NULL)
7262     {
7263       salp = (SeqAlignPtr) sap->data;
7264       ValidateSeqAlignandACCEx (salp, svp->entityID, svp->message,
7265                                 svp->msg_success, svp->find_remote_bsp,
7266                                 svp->find_acc_bsp, FALSE,
7267                                 svp->delete_salp, &svp->dirty,
7268                                 &id_list);
7269     }
7270     sap = sap->next;
7271   }
7272   if (svp->delete_bsp)
7273   {
7274     delete_bioseqs (id_list, svp->entityID);
7275   }
7276 }
7277 
7278 
7279 
7280 /***************************************************************************
7281  *
7282  * ValidateSeqAlignandACCCallback (sep, mydata, index, indent)
7283  *
7284  * This function is a callback for SeqEntryExplore used by
7285  * ValidateSeqAlignandACCInSeqEntry.  It will validate the alignments
7286  * found in the record.
7287  * This function used to only validate the first alignment found on a
7288  * SeqEntry.  It was repaired to validate all alignments on the SeqEntry
7289  * on May 27, 2005 by Colleen Bollin.
7290  *
7291  ***************************************************************************/
ValidateSeqAlignandACCCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)7292 static void ValidateSeqAlignandACCCallback (SeqEntryPtr sep, Pointer mydata,
7293                                           Int4 index, Int2 indent)
7294 {
7295   BioseqPtr          bsp;
7296   BioseqSetPtr       bssp;
7297   SaValPtr           svp = NULL;
7298   SeqAnnotPtr        sap = NULL;
7299 
7300   if (sep != NULL && sep->data.ptrvalue && mydata != NULL) {
7301      svp = (SaValPtr)mydata;
7302      if (IS_Bioseq(sep)) {
7303         bsp = (BioseqPtr) sep->data.ptrvalue;
7304         if (bsp!=NULL) {
7305            sap = bsp->annot;
7306         }
7307      }
7308      else if(IS_Bioseq_set(sep)) {
7309         bssp = (BioseqSetPtr)sep->data.ptrvalue;
7310         if (bssp!=NULL) {
7311            sap = bssp->annot;
7312         }
7313      }
7314   }
7315   ValidateAllAlignmentsInAnnotList (sap, svp);
7316 }
7317 
7318 
ValidateSeqAlignandACCInSeqEntry(SeqEntryPtr sep,Boolean message,Boolean msg_success,Boolean find_remote_bsp,Boolean find_acc_bsp,Boolean delete_bsp,Boolean delete_salp)7319 NLM_EXTERN Boolean ValidateSeqAlignandACCInSeqEntry (SeqEntryPtr sep, Boolean message,
7320                                  Boolean msg_success, Boolean find_remote_bsp, Boolean find_acc_bsp,
7321                                  Boolean delete_bsp, Boolean delete_salp)
7322 {
7323   SeqEntryPtr      sep_head;
7324   Uint2            entityID;
7325   SaVal            sv;
7326   Boolean          success=TRUE;
7327 
7328   entityID = ObjMgrGetEntityIDForChoice (sep);
7329   if (entityID > 0) {
7330      sep_head = GetTopSeqEntryForEntityID (entityID);
7331      if (sep_head != NULL) {
7332         sv.message = message;
7333         sv.msg_success = msg_success;
7334         sv.find_remote_bsp = find_remote_bsp;
7335         sv.find_acc_bsp = find_acc_bsp;
7336         sv.delete_salp = delete_salp;
7337         sv.delete_bsp = delete_bsp;
7338         sv.retdel = TRUE;
7339         sv.ids = NULL;
7340         sv.entityID = entityID;
7341         sv.dirty = FALSE;
7342         SeqEntryExplore (sep_head, (Pointer)&sv, ValidateSeqAlignandACCCallback);
7343         if (sv.dirty) {
7344            ObjMgrSetDirtyFlag (entityID, TRUE);
7345            ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
7346         }
7347         success = sv.retdel;
7348      }
7349   }
7350   return success;
7351 }
7352 
7353 
7354 /* we need to iterate through the actual SeqEntries, because theoretically the
7355  * same SeqID should appear in the SeqEntry with the new alignment and again
7356  * in the SeqEntry of the original record.
7357  */
FindBioseqInSep(SeqEntryPtr sep,SeqIdPtr sip)7358 static BioseqPtr FindBioseqInSep (SeqEntryPtr sep, SeqIdPtr sip)
7359 {
7360   BioseqPtr    bsp = NULL;
7361   BioseqSetPtr bssp;
7362   SeqEntryPtr  this_sep;
7363 
7364   if (sep == NULL || sip == NULL) return NULL;
7365 
7366   if (IS_Bioseq (sep))
7367   {
7368   	bsp = (BioseqPtr) sep->data.ptrvalue;
7369 	if (! BioseqMatch(bsp, sip))
7370 	{
7371 	  bsp = NULL;
7372 	}
7373   }
7374   else if (IS_Bioseq_set (sep))
7375   {
7376   	bssp = (BioseqSetPtr) sep->data.ptrvalue;
7377     for (this_sep = bssp->seq_set; this_sep != NULL && bsp == NULL; this_sep = this_sep->next)
7378     {
7379       bsp = FindBioseqInSep (this_sep, sip);
7380     }
7381   }
7382   return bsp;
7383 }
7384 
7385 
CalculateAlignmentOffsets(SeqEntryPtr sepnew,SeqEntryPtr sepold)7386 NLM_EXTERN void CalculateAlignmentOffsets (SeqEntryPtr sepnew, SeqEntryPtr sepold)
7387 {
7388   SeqAlignPtr         salpnew;
7389   DenseSegPtr         dsp;
7390   SeqIdPtr            sip_temp, sip_next;
7391   BioseqPtr           bsp1, bsp2;
7392   BLAST_OptionsBlkPtr options;
7393   SeqAlignPtr         seqalign = NULL;
7394   SeqAlignPtr         bestsalp = NULL;
7395   Int4                start1, start2, stop1, stop2;
7396   CharPtr             errstr = NULL;
7397   Uint1               strand;
7398   Int4                offset, len, nonly;
7399   BioseqPtr           copybsp1, copybsp2;
7400   SeqIdPtr            tmp_id_1, tmp_id_2;
7401 
7402   if (sepnew == NULL || sepold == NULL)
7403   {
7404   	return;
7405   }
7406   /* this function needs to look at the bioseqs we have created while reading in the
7407    * alignment, align them with the existing bioseqs, and adjust the alignment start
7408    * positions if necessary.
7409    */
7410 
7411   salpnew = (SeqAlignPtr) FindSeqAlignInSeqEntry (sepnew, OBJ_SEQALIGN);
7412   if (salpnew == NULL)
7413   {
7414   	return;
7415   }
7416 
7417   if (salpnew->segtype != 2) return;
7418   dsp = (DenseSegPtr) salpnew->segs;
7419   if (dsp == NULL) return;
7420 
7421   /* create IDs to use when copying Bioseqs.
7422    * BioseqCopyEx makes a copy of these for the Bioseq it creates,
7423    * so we can reuse them and then free them at the end of the for-next loop.
7424    */
7425   tmp_id_1 = MakeSeqID ("lcl|tmp_1_for_update");
7426   tmp_id_2 = MakeSeqID ("lcl|tmp_2_for_update");
7427 
7428   for (sip_temp = dsp->ids; sip_temp != NULL; sip_temp = sip_next)
7429   {
7430   	sip_next = sip_temp->next;
7431   	sip_temp->next = NULL;
7432 
7433   	/* find bsp1 in sepnew, bsp2 in sepold */
7434     bsp1 = FindBioseqInSep (sepnew, sip_temp);
7435     bsp2 = FindBioseqInSep (sepold, sip_temp);
7436 
7437     if (bsp1 != NULL && bsp2 != NULL)
7438     {
7439   	  /* create alignment between old and new bioseqs */
7440   	  /* new bioseq will have same ID as old bioseq, so BLAST won't work
7441   	   * because it's looking for IDs using indexing.
7442   	   * Create a temporary copy of the two bioseqs with different IDS,
7443   	   * add them to the BioseqIndex, BLAST them, then remove them
7444   	   * from the index and delete them.
7445   	   */
7446       copybsp1 = BioseqCopyEx (tmp_id_1, bsp1, 0, bsp1->length - 1, Seq_strand_plus, FALSE);
7447       copybsp2 = BioseqCopyEx (tmp_id_2, bsp2, 0, bsp2->length - 1 , Seq_strand_plus, FALSE);
7448       SeqMgrAddToBioseqIndex (copybsp1);
7449       SeqMgrAddToBioseqIndex (copybsp2);
7450 
7451       options = BLASTOptionNew("blastn", TRUE);
7452       options->filter_string = StringSave("m L;R");
7453       seqalign = BlastTwoSequences (copybsp1, copybsp2, "blastn", options);
7454       if (errstr != NULL)
7455         MemFree(errstr);
7456       errstr = (CharPtr)MemNew(1000*sizeof(Char));
7457       bestsalp = SeqAlignBestHit (seqalign, copybsp1, copybsp2, 100, &errstr, &nonly);
7458 
7459       /* we don't need the copies after this, and we don't want them in the BioseqIndex
7460        * (or BLAST might get confused the next time through the loop).
7461        */
7462   	  copybsp1->idx.deleteme = TRUE;
7463   	  copybsp2->idx.deleteme = TRUE;
7464   	  SeqMgrDeleteFromBioseqIndex (copybsp1);
7465   	  SeqMgrDeleteFromBioseqIndex (copybsp2);
7466 
7467   	  /* update start position in alignment */
7468       offset = SeqAlignStart(bestsalp, 1)-SeqAlignStart(bestsalp, 0);
7469       if ((SeqAlignStrand(bestsalp, 0)==Seq_strand_minus && SeqAlignStrand(bestsalp, 1) != Seq_strand_minus) || (SeqAlignStrand(bestsalp, 1)==Seq_strand_minus && SeqAlignStrand(bestsalp, 0) != Seq_strand_minus))
7470       {
7471         strand=Seq_strand_minus;
7472         AlnMgr2IndexSingleChildSeqAlign(bestsalp);
7473         AlnMgr2GetNthSeqRangeInSA(bestsalp, 1, &start1, &stop1);
7474         AlnMgr2GetNthSeqRangeInSA(bestsalp, 2, &start2, &stop2);
7475         len = stop2 + start1;
7476         if (offset < 0)
7477         {
7478           offset = 0 - offset;
7479         }
7480       }
7481       else
7482       {
7483         strand=Seq_strand_plus;
7484         len = offset;
7485       }
7486       SeqAlignStartUpdate (salpnew, sip_temp, abs(offset), len, strand);
7487     }
7488   	sip_temp->next = sip_next;
7489   }
7490   SeqIdFree (tmp_id_1);
7491   SeqIdFree (tmp_id_2);
7492 
7493   if (errstr != NULL)
7494   {
7495   	MemFree (errstr);
7496   }
7497 }
7498 
7499 
CheckAlignmentSequenceLengths(SeqAlignPtr salp)7500 NLM_EXTERN Boolean CheckAlignmentSequenceLengths (SeqAlignPtr salp)
7501 {
7502   Int4 i, num_rows, num_bad = 0;
7503   Int4 from, to;
7504   SeqIdPtr sip;
7505   BioseqPtr bsp;
7506   ValNodePtr sip_list = NULL, vnp;
7507   Char       path [PATH_MAX];
7508   FILE       *fp;
7509   Char       str[50];
7510   Boolean    retval = TRUE;
7511 
7512   if (salp == NULL) return FALSE;
7513 
7514   num_rows = AlnMgr2GetNumRows(salp);
7515 
7516   for (i = 0; i < num_rows; i++) {
7517     AlnMgr2GetNthSeqRangeInSA(salp, i + 1, &from, &to);
7518     sip = AlnMgr2GetNthSeqIdPtr(salp, i + 1);
7519     bsp = BioseqFind (sip);
7520     if (bsp != NULL) {
7521       if (from > to) to = from;
7522       if (bsp->length < to) {
7523         ValNodeAddPointer (&sip_list, 0, sip);
7524         num_bad++;
7525       } else {
7526         sip = SeqIdFree (sip);
7527       }
7528     }
7529   }
7530   if (sip_list != NULL) {
7531     TmpNam (path);
7532     fp = FileOpen (path, "w");
7533     if (fp == NULL) {
7534       Message (MSG_ERROR, "Unable to open %s", path);
7535     } else {
7536       vnp = sip_list;
7537       while (vnp != NULL) {
7538         SeqIdWrite (vnp->data.ptrvalue, str, PRINTID_FASTA_LONG, sizeof (str) - 1);
7539         fprintf (fp, "%s\n", str);
7540         vnp->data.ptrvalue = SeqIdFree (vnp->data.ptrvalue);
7541         vnp = vnp->next;
7542       }
7543       FileClose (fp);
7544       LaunchGeneralTextViewer (path, "Short Sequences");
7545       FileRemove (path);
7546     }
7547     if (Message(MSG_YN, "%d sequence%s too short for this alignment.  Do you wish to continue?",
7548                 num_bad, num_bad > 1 ? "s are" : " is") == ANS_NO) {
7549       retval = FALSE;
7550     }
7551     sip_list = ValNodeFree (sip_list);
7552   }
7553   return retval;
7554 }
7555 
7556 
7557 /******************************************************************
7558 call back function for REGISTER_ALIGNVALIDATION defined in sequin4.c.
7559 Starting point for seqalign validation if user clicked on
7560 SeqalignValidation under menu Filer/Alignment.
7561 Either individual alignment or alignment block
7562 should be highlighted for this validation to work
7563 ******************************************************************/
7564 
ValidateSeqAlignandACCFromData(Pointer data)7565 NLM_EXTERN Int2 LIBCALLBACK ValidateSeqAlignandACCFromData (Pointer data)
7566 {
7567 
7568   OMProcControlPtr  ompcp;
7569   SeqAlignPtr       salp=NULL;
7570   SeqAnnotPtr       sap=NULL;
7571   SeqEntryPtr       sep=NULL;
7572 
7573   ompcp = (OMProcControlPtr) data;
7574   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
7575 
7576   if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
7577 
7578   switch(ompcp->input_itemtype)
7579     {
7580     case OBJ_BIOSEQ :
7581       sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
7582       break;
7583     case OBJ_BIOSEQSET :
7584       sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
7585       break;
7586       /*if clicked on alignment block*/
7587     case OBJ_SEQANNOT:
7588       sap=(SeqAnnotPtr) (ompcp->input_data);
7589       break;
7590       /*if clicked on individual alignment*/
7591     case OBJ_SEQALIGN:
7592       salp=(SeqAlignPtr) (ompcp->input_data);
7593       break;
7594     case 0 :
7595       return OM_MSG_RET_ERROR;
7596     default :
7597       return OM_MSG_RET_ERROR;
7598   }
7599 
7600   ErrSetMessageLevel(SEV_ERROR);
7601   if(sap!=NULL)
7602   {
7603      salp=is_salp_in_sap(sap, 2);
7604      ValidateSeqAlignandACC (salp, 0, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL);
7605   }
7606   if (salp!=NULL) {
7607      ValidateSeqAlignandACC (salp, 0, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL);
7608   }
7609   if (sep!=NULL) {
7610      ValidateSeqAlignandACCInSeqEntry (sep, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE);
7611   }
7612   return OM_MSG_RET_DONE;
7613 }
7614 
7615 
7616 
7617 
7618 
7619