1 /* salpanel.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: salpanel.c
27 *
28 * Author: Colombe Chappey
29 *
30 * Version Creation Date: 1/27/96
31 *
32 * $Revision: 6.104 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44 #include <saledit.h>
45 #include <salpanel.h>
46 #include <salutil.h>
47 #include <salfiles.h>
48 #include <salstruc.h>
49 #include <fstyle.h>
50 #include <salmedia.h>
51 #include <sequtil.h>
52 #include <alignmgr.h>
53 #include <alignmgr2.h>
54 #include <edutil.h>
55 #include <dlogutil.h>
56 #include <import.h>
57 #include <seqpanel.h>
58 #include <cdrgn.h>
59
60 #define OBJ_VIRT 254
61
62 static Uint1 rectSym [] = {
63 0xFE, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFE, 0x00
64 };
65 static Uint1 diamondSym [] = {
66 0x10, 0x28, 0x44, 0x82, 0x44, 0x28, 0x10, 0x00
67 };
68 static Uint1 ovalSym [] = {
69 0x38, 0x44, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00
70 };
71 static Uint1 leftTriSym [] = {
72 0x06, 0x1A, 0x62, 0x82, 0x62, 0x1A, 0x06, 0x00
73 };
74 static Uint1 rightTriSym [] = {
75 0xC0, 0xB0, 0x8C, 0x82, 0x8C, 0xB0, 0xC0, 0x00
76 };
77 static Uint1 upTriSym [] = {
78 0x10, 0x28, 0x28, 0x44, 0x44, 0x82, 0xFE, 0x00
79 };
80 static Uint1 downTriSym [] = {
81 0xFE, 0x82, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00
82 };
83 static Uint1 rectFillSym [] = {
84 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x00
85 };
86 static Uint1 diamondFillSym [] = {
87 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00
88 };
89 static Uint1 ovalFillSym [] = {
90 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x00
91 };
92 static Uint1 leftTriFillSym [] = {
93 0x06, 0x1E, 0x7E, 0xFE, 0x7E, 0x1E, 0x06, 0x00
94 };
95 static Uint1 rightTriFillSym [] = {
96 0xC0, 0xF0, 0xFC, 0xFE, 0xFC, 0xF0, 0xC0, 0x00
97 };
98 static Uint1 upTriFillSym [] = {
99 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00
100 };
101 static Uint1 downTriFillSym [] = {
102 0xFE, 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x00
103 };
104 static Uint1 rightOvalSym [] = {
105 0x18, 0x14, 0x12, 0x12, 0x12, 0x14, 0x18, 0x00
106 };
107 static Uint1 leftOvalSym [] = {
108 0x38, 0x44, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00
109 };
110 static Uint1 rightOvalFillSym [] = {
111 0x18, 0x1C, 0x1E, 0x1E, 0x1E, 0x1C, 0x18, 0x00
112 };
113 static Uint1 leftOvalFillSym [] = {
114 0x30, 0x50, 0x90, 0x90, 0x90, 0x50, 0x30, 0x00
115 };
116
117 /*######################################################################
118 #
119 # functions for setting up the color for different object
120 #
121 ######################################################################*/
122 #define RGB_B(x) (Uint1)((x)&255);
123 #define RGB_G(x) (Uint1)(((x)>>8)&255);
124 #define RGB_R(x) (Uint1)(((x)>>16)&255);
125
convert_color(Int4 val,Uint1Ptr color)126 static Boolean convert_color(Int4 val, Uint1Ptr color)
127 {
128
129 if(val<0 || color == NULL)
130 return FALSE;
131 color[0] = RGB_R(val);
132 color[1] = RGB_G(val);
133 color[2] = RGB_B(val);
134 return TRUE;
135 }
136
getcolor_fromstyles(Uint2 itemsubtype)137 static Uint4 getcolor_fromstyles (Uint2 itemsubtype)
138 {
139 Int4 c_val;
140 Uint1 color [3];
141
142 c_val = GetMuskCParam (itemsubtype, MSM_SEGMENT, MSM_COLOR);
143 if ( convert_color (c_val, color) )
144 return GetColorRGB (color[0], color[1], color[2]);
145 return GetColorRGB (0, 0, 0);
146 }
147
getcolorforvirtfeat(Uint2 item)148 static Uint4 getcolorforvirtfeat (Uint2 item)
149 {
150 return GetColorRGB ((Uint1)((item % 3) * 40),
151 (Uint1)(255-(item % 3) * 40),
152 (Uint1)((item % 3) * 40));
153 }
154
155 /**********************************************
156 *** GetAlignEditData
157 **********************************************/
getwindow_frompanel(PaneL pnl)158 extern WindoW getwindow_frompanel (PaneL pnl)
159 {
160 /*
161 #ifdef WIN_MAC
162 w = FrontWindow ();
163 #else
164 w = ParentWindow (pnl);
165 #endif
166 */
167 return ParentWindow (pnl);
168 }
169
GetPanelFromWindow(WindoW w)170 extern PaneL GetPanelFromWindow (WindoW w)
171 {
172 SeqEditViewFormPtr wdp;
173
174 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
175 if (wdp == NULL) {
176 return NULL;
177 }
178 if ( wdp->pnl == NULL ) {
179 return NULL;
180 }
181 return wdp->pnl;
182 }
183
GetAlignEditData(WindoW w)184 extern EditAlignDataPtr GetAlignEditData (WindoW w)
185 {
186 PaneL pnl;
187 EditAlignDataPtr adp;
188
189 pnl = GetPanelFromWindow (w);
190 if (pnl == NULL) return NULL;
191 GetPanelExtra (pnl, &adp);
192 if ( adp == NULL )
193 return NULL;
194 if ( adp->firstssp == NULL )
195 return NULL;
196 return adp;
197 }
198
GetAlignDataPanel(PaneL pnl)199 extern EditAlignDataPtr GetAlignDataPanel (PaneL pnl)
200 {
201 EditAlignDataPtr adp;
202
203 if ( pnl == NULL )
204 return NULL;
205 GetPanelExtra (pnl, &adp);
206 if ( adp == NULL )
207 return NULL;
208 if ( adp->firstssp == NULL )
209 return NULL;
210 return adp;
211 }
212
213 /**********************************************
214 *** AlignDataSet_Restore
215 *** Inval Rect
216 *** RestorePort
217 **********************************************/
get_client_rect(PaneL p,RectPtr prc)218 static void get_client_rect (PaneL p, RectPtr prc)
219 {
220 ObjectRect (p, prc);
221 InsetRect (prc, HRZ_BORDER_WIDTH, VER_BORDER_WIDTH);
222 }
223
get_client_rectxy(PaneL p,RectPtr prc,Int2 x,Int2 y)224 static void get_client_rectxy (PaneL p, RectPtr prc, Int2 x, Int2 y)
225 {
226 ObjectRect (p, prc);
227 InsetRect (prc, x, y);
228 }
229
230 /**************************************************************
231 ***
232 ***
233 **************************************************************/
get_firstline(SelEdStructPtr sesp1,SelStructPtr buffer)234 static SelStructPtr get_firstline (SelEdStructPtr sesp1, SelStructPtr buffer)
235 {
236 SelEdStructPtr sesp;
237 SelStructPtr buf;
238
239 if (buffer == NULL) {
240 ErrPostEx (SEV_ERROR, 0, 0, "fail in get_firstline [25]");
241 return NULL;
242 }
243 if (sesp1 == NULL) {
244 return buffer;
245 }
246 for (buf=buffer; buf!=NULL; buf=buf->next)
247 {
248 sesp = (SelEdStructPtr) buf->region;
249 if (is_sameId (sesp1->entityID, sesp1->itemID, sesp1->itemtype, 255, sesp->entityID, sesp->itemID, sesp->itemtype, 255) )
250 break;
251 }
252 if (buf == NULL) {
253 return buffer;
254 }
255 return buf;
256 }
257
258 /*********************************************************************
259 *** FindNextSegment
260 *********************************************************************/
FindNextSegment(SelEdStructPtr current)261 static SelEdStructPtr FindNextSegment (SelEdStructPtr current)
262 {
263 Uint2 ei, ii;
264 if ( current->next == NULL ) return NULL;
265 ei = current->entityID;
266 ii = current->itemID;
267 current = current->next;
268 while ( current != NULL )
269 {
270 if (current->entityID == ei && current->itemID == ii) break;
271 current = current->next;
272 }
273 return current;
274 }
275
get_substring(CharPtr str,Int4 drw_start,Int4 drw_width)276 static CharPtr get_substring (CharPtr str, Int4 drw_start, Int4 drw_width)
277 {
278 Int4 width;
279 Int4 stringlens;
280 CharPtr strp;
281
282 if (str == NULL )
283 return NULL;
284 if (str[0]=='\0')
285 return NULL;
286 stringlens = StringLen (str);
287 if ( drw_start >= stringlens ) {
288 return NULL; }
289 strp = str + drw_start;
290 stringlens = StringLen (strp);
291 if (stringlens == 0)
292 return NULL;
293 width = MIN ((Int4) drw_width, (Int4) stringlens);
294 if ( !not_empty_string (strp, width) )
295 return NULL;
296 return strp;
297 }
298
go_to_next_to_draw(EditAlignDataPtr adp,Boolean next,Int4 offset)299 static SelStructPtr go_to_next_to_draw (EditAlignDataPtr adp, Boolean next, Int4 offset)
300 {
301 TextAlignBufPtr curtdp;
302 SelStructPtr curvnp;
303 SelEdStructPtr curssp = NULL;
304 ValNodePtr vnp = NULL;
305 Int4 from_inbuf; /* alignment coordinates in buffer */
306 Int4 from_inseq; /* alignment coordinates in buffer */
307 Int4 drw_width; /* length of drw_str */
308 Uint2 itemsubtype;
309 CharPtr curstr = NULL;
310 Int4 offsettmp;
311
312 if (adp->voffset == 0)
313 return adp->buffer;
314 if (offset == 0)
315 return adp->firstssp;
316 from_inseq = adp->hoffset;
317 from_inbuf = adp->hoffset - adp->bufferstart;
318 drw_width = MIN ((Int4) adp->visibleWidth, (Int4) (adp->bufferlength - from_inbuf));
319 if ( drw_width <= 0 ) {
320 return NULL;
321 }
322 curvnp = adp->buffer;
323 offsettmp = 0;
324 while (offsettmp < offset && from_inseq < adp->length)
325 {
326 curssp = (SelEdStructPtr) curvnp->region;
327 itemsubtype = curvnp->itemtype;
328 if (itemsubtype == EDITDEF_SCA)
329 offsettmp++;
330 else if (itemsubtype == EDITDEF_SCB)
331 offsettmp;
332 else if (curssp->itemtype ==OBJ_BIOSEQ) /*&&itemsubtype==FEATDEF_BAD)*/
333
334 {
335 vnp = (ValNodePtr) curssp->data;
336 curtdp = (TextAlignBufPtr) vnp->data.ptrvalue;
337 curstr = get_substring(curtdp->buf, from_inbuf, drw_width);
338 if ( curstr != NULL )
339 offsettmp++;
340 }
341 if (offsettmp < offset) {
342 if (next)
343 curvnp = curvnp->next;
344 else
345 curvnp = curvnp->prev;
346 }
347 if (offsettmp < offset && curvnp == NULL)
348 {
349 if (next) {
350 curvnp = adp->buffer;
351 adp->hoffset += adp->visibleWidth;
352 from_inbuf += drw_width;
353 from_inseq += drw_width;
354 } else {
355 curvnp = adp->buffertail;
356 adp->hoffset -= adp->visibleWidth;
357 from_inbuf -= drw_width;
358 from_inseq -= drw_width;
359 }
360 if (from_inseq >= adp->length) break;
361 if (from_inseq <= 0 || from_inbuf <= 0 || adp->hoffset<=0) break;
362 drw_width = MIN ((Int4) adp->visibleWidth,
363 (Int4)(adp->bufferlength -(adp->hoffset -adp->bufferstart)));
364 }
365 }
366 if (from_inseq < 0 || from_inbuf < 0 || adp->hoffset<0) {
367 adp->hoffset = adp->bufferstart;
368 return adp->buffer;
369 }
370 if (from_inseq >= adp->length)
371 return NULL;
372 return curvnp;
373 }
374
375
next_to_draw(EditAlignDataPtr adp,Boolean next)376 static SelStructPtr next_to_draw (EditAlignDataPtr adp, Boolean next)
377 {
378 TextAlignBufPtr curtdp;
379 SelStructPtr curvnp;
380 SelStructPtr ssptmp;
381 SelEdStructPtr curssp = NULL;
382 ValNodePtr vnp = NULL;
383 SeqLocPtr curslp;
384 SeqIdPtr sip;
385 CharPtr curstr = NULL;
386 Int4 start, stop;
387 Int4 start2, stop2;
388 Int4 from_inbuf; /* alignment coordinates in buffer */
389 Int4 from_inseq; /* alignment coordinates in buffer */
390 Int4 drw_width; /* length of drw_str */
391 Int4 chklocp;
392 Uint2 itemsubtype;
393 SeqAlignPtr salp = (SeqAlignPtr) adp->sap_align->data;
394 Boolean empty_line;
395
396 if (next) {
397 if ( adp->firstssp->next == NULL)
398 {
399 adp->hoffset += adp->visibleWidth;
400 return adp->buffer;
401 }
402 else {
403 ssptmp = adp->firstssp->next;
404 }
405 }
406 if (!next) {
407 if ( adp->firstssp->prev == NULL)
408 {
409 if (adp->hoffset == 0) {
410 adp->voffset = 0;
411 return adp->buffer;
412 }
413 adp->hoffset -= adp->visibleWidth;
414 ssptmp = adp->buffertail;
415 }
416 else ssptmp = adp->firstssp->prev;
417 }
418 from_inseq = adp->hoffset;
419 from_inbuf = adp->hoffset - adp->bufferstart;
420 drw_width = MIN ((Int4) adp->visibleWidth,
421 (Int4) (adp->bufferlength - from_inbuf));
422 if ( drw_width <= 0 ) {
423 return NULL;
424 }
425 empty_line = FALSE;
426 curvnp = ssptmp;
427 while ( from_inseq < adp->length )
428 {
429 curssp = (SelEdStructPtr) curvnp->region;
430 itemsubtype = curvnp->itemtype;
431 if (itemsubtype == EDITDEF_SCA)
432 return curvnp;
433 if (itemsubtype == EDITDEF_SCB)
434 return curvnp;
435 if (itemsubtype == FEATDEF_TRSL)
436 {
437 if (!empty_line ) {
438 while (curssp!=NULL)
439 {
440 if (curssp->region !=NULL) {
441 curslp = (SeqLocPtr) curssp->region;
442 sip = SeqLocId (curslp);
443 start2=SeqLocStart(curslp);
444 chklocp =chkloc(sip, start2, adp->sqloc_list, &start2);
445 start= SeqCoordToAlignCoord(start2, sip, salp, 0, chklocp);
446 stop2=SeqLocStop(curslp);
447 chklocp =chkloc(sip, stop2, adp->sqloc_list, &stop2);
448 stop = SeqCoordToAlignCoord(stop2, sip, salp, 0, chklocp);
449 if (start<=stop && start<from_inseq+drw_width && stop>from_inseq)
450 return curvnp;
451 }
452 curssp = FindNextSegment (curssp);
453 }
454 }
455 }
456 else if (itemsubtype>=EDITDEF_RF1 && itemsubtype<=EDITDEF_RF6)
457 {
458 if (curssp->region !=NULL && !empty_line) {
459 curslp = (SeqLocPtr) curssp->region;
460 if ( SeqLocStop (curslp) > from_inseq && curssp->data != NULL)
461 return curvnp;
462 }
463 }
464 else if (curssp->itemtype ==OBJ_BIOSEQ) /*&&itemsubtype==FEATDEF_BAD)*/
465
466 {
467 if (curssp->data !=NULL) {
468 vnp = (ValNodePtr) curssp->data;
469 curtdp = (TextAlignBufPtr) vnp->data.ptrvalue;
470 curstr = get_substring(curtdp->buf, from_inbuf, drw_width);
471 if ( curstr != NULL )
472 if (adp->draw_emptyline || (!adp->draw_emptyline && !stringhasnochar(curstr, 0, drw_width) )) {
473 empty_line = FALSE;
474 return curvnp;
475 }
476 else
477 empty_line = TRUE;
478 }
479 }
480 else if (curssp->itemtype==OBJ_SEQFEAT && itemsubtype==FEATDEF_PROT)
481 {
482 if (curssp->data !=NULL && !empty_line) {
483 vnp = (ValNodePtr) curssp->data;
484 curtdp = (TextAlignBufPtr) vnp->data.ptrvalue;
485 curstr = get_substring(curtdp->buf, from_inbuf, drw_width);
486 if ( curstr != NULL )
487 return curvnp;
488 }
489 }
490 else if (curssp->itemtype ==OBJ_SEQFEAT)
491 {
492 if ( !empty_line ) {
493 while (curssp!=NULL)
494 {
495 if (curssp->region !=NULL) {
496 curslp = (SeqLocPtr) curssp->region;
497 sip = SeqLocId (curslp);
498 start2=SeqLocStart(curslp);
499 chklocp =chkloc(sip, start2, adp->sqloc_list, &start2);
500 start= SeqCoordToAlignCoord(start2, sip, salp, 0, chklocp);
501 stop2=SeqLocStop(curslp);
502 chklocp =chkloc(sip, stop2, adp->sqloc_list, &stop2);
503 stop = SeqCoordToAlignCoord(stop2, sip, salp, 0, chklocp);
504 if (start<=stop && start<from_inseq+drw_width && stop>=from_inseq)
505 return curvnp;
506 }
507 curssp = FindNextSegment (curssp);
508 }
509 }
510 }
511 else if (itemsubtype == EDITDEF_CPL)
512 {
513 if (curssp->data !=NULL && !empty_line) {
514 vnp = (ValNodePtr) curssp->data;
515 curtdp = (TextAlignBufPtr) vnp->data.ptrvalue;
516 curstr = get_substring (curtdp->buf, from_inbuf, drw_width);
517 if ( curstr != NULL )
518 return curvnp;
519 }
520 }
521
522 else if( itemsubtype==SEQFEAT_GENE || itemsubtype==SEQFEAT_RNA
523 || itemsubtype==SEQFEAT_CDREGION)
524 {
525 if ( !empty_line ) {
526 while (curssp!=NULL)
527 {
528 if (curssp->region !=NULL) {
529 curslp = (SeqLocPtr) curssp->region;
530 sip = SeqLocId (curslp);
531 start2=SeqLocStart(curslp);
532 chklocp =chkloc(sip, start2, adp->sqloc_list, &start2);
533 start= SeqCoordToAlignCoord(start2, sip, salp, 0, chklocp);
534 stop2=SeqLocStop(curslp);
535 chklocp =chkloc(sip, stop2, adp->sqloc_list, &stop2);
536 stop = SeqCoordToAlignCoord(stop2, sip, salp, 0, chklocp);
537 if (start<=stop && start<from_inseq+drw_width && stop>from_inseq)
538 return curvnp;
539 }
540 curssp = FindNextSegment (curssp);
541 }
542 }
543 }
544 else {
545 /**
546 ErrPostEx (SEV_ERROR, 0, 0, "fail in next_to_draw [46] subtype %ld type %ld", (long) itemsubtype, (long) curssp->itemtype);
547 **/
548 return NULL;
549 }
550 if (next)
551 curvnp = curvnp->next;
552 else
553 curvnp = curvnp->prev;
554 if (curvnp == NULL)
555 {
556 if (next) {
557 curvnp = adp->buffer;
558 adp->hoffset += adp->visibleWidth;
559 from_inbuf += drw_width;
560 from_inseq += drw_width;
561 } else {
562 curvnp = adp->buffertail;
563 adp->hoffset -= adp->visibleWidth;
564 from_inbuf -= drw_width;
565 from_inseq -= drw_width;
566 }
567 if (from_inseq >= adp->length) break;
568 drw_width = MIN ((Int4) adp->visibleWidth,
569 (Int4)(adp->bufferlength -(adp->hoffset -adp->bufferstart)));
570 }
571 }
572 return NULL;
573 }
574
575 /********************************************************
576 *** SetupScrollBar
577 ***
578 ***
579 *********************************************************/
SeqEdGetSlateScrollBar(PaneL pnl)580 extern BaR SeqEdGetSlateScrollBar (PaneL pnl)
581 {
582 EditAlignDataPtr adp;
583
584 if (pnl)
585 {
586 adp=GetAlignDataPanel (pnl);
587 if(adp!=NULL)
588 {
589 if (adp->vscrollbar_mode) {
590 return GetSlateVScrollBar ((SlatE)pnl);
591 }
592 return GetSlateHScrollBar ((SlatE)pnl);
593 }
594 }
595 return NULL;
596 }
597
SeqEdGetValueScrollBar(PaneL pnl)598 extern Int4 SeqEdGetValueScrollBar (PaneL pnl)
599 {
600 return GetBarValue(SeqEdGetSlateScrollBar(pnl));
601 }
602
SeqEdSetValueScrollBar(PaneL pnl,Int4 value)603 extern void SeqEdSetValueScrollBar (PaneL pnl, Int4 value)
604 {
605 SetBarValue(SeqEdGetSlateScrollBar(pnl), value);
606 }
607
SeqEdCorrectBarPage(PaneL pnl,Int4 page1,Int4 page2)608 extern void SeqEdCorrectBarPage (PaneL pnl, Int4 page1, Int4 page2)
609 {
610 BaR sb;
611
612 sb = SeqEdGetSlateScrollBar (pnl);
613 CorrectBarPage (sb, page1, page2);
614 }
615
SeqEdCorrectBarValue(PaneL pnl,Int4 value)616 extern void SeqEdCorrectBarValue (PaneL pnl, Int4 value)
617 {
618 BaR sb;
619
620 sb = SeqEdGetSlateScrollBar (pnl);
621 CorrectBarValue (sb, value);
622 }
623
SeqEdCorrectBarMax(PaneL pnl,Int4 value)624 extern void SeqEdCorrectBarMax (PaneL pnl, Int4 value)
625 {
626 BaR sb;
627
628 sb = SeqEdGetSlateScrollBar (pnl);
629 CorrectBarMax (sb, value);
630 }
631
SeqEdSetCorrectBarMax(PaneL pnl,EditAlignDataPtr adp,float hratio)632 extern void SeqEdSetCorrectBarMax (PaneL pnl, EditAlignDataPtr adp, float hratio)
633 {
634 BaR sb;
635 Int4 cbm = 0;
636
637 if (adp->nlines < 11) {
638 adp->voffset = 0;
639 adp->hoffset = 0;
640 adp->firstssp = get_firstline (NULL, adp->buffer);
641 }
642 else {
643 adp->hoffset = (Int4)(hratio * (float)adp->length);
644 adp->voffset = hoffset2voffset (adp, adp->anp_list, adp->visibleWidth, 0, adp->length-1, adp->hoffset);
645 }
646
647 if (adp->nlines < 0)
648 cbm = 0;
649 else
650 cbm = MAX ((Int4) 0, (Int4) (adp->nlines -1));
651 sb = SeqEdGetSlateScrollBar (pnl);
652 CorrectBarMax (sb, cbm);
653 SetBarValue (sb, (Int4)(adp->voffset));
654 }
655
count_feature_buf_line(ValNodePtr fnp_list,Int4 g_left,Int4 g_right,ValNodePtr PNTR feature_line)656 static void count_feature_buf_line (ValNodePtr fnp_list, Int4 g_left, Int4 g_right, ValNodePtr PNTR feature_line)
657 {
658 FeatNodePtr fnp;
659 Int4 c_left, c_right;
660 ValNodePtr vnp;
661 Boolean found;
662
663 if(fnp_list == NULL)
664 return;
665
666 while(fnp_list)
667 {
668 fnp = (FeatNodePtr)fnp_list->data.ptrvalue;
669 c_left = fnp->extremes.left;
670 c_right = fnp->extremes.right;
671 if(!(c_left > g_right || c_right < g_left))
672 {
673 found = FALSE;
674 for(vnp = *feature_line; vnp != NULL && !found; vnp = vnp->next)
675 {
676 if(vnp->data.intvalue == (Int4)(fnp->itemID))
677 found = TRUE;
678 }
679 if(!found)
680 ValNodeAddInt(feature_line, 0, (Int4)(fnp->itemID));
681 }
682 fnp_list = fnp_list->next;
683 }
684 }
685
CountTextAlignNodeNum(AlignNodePtr anp,Int4 m_left,Int4 m_right)686 static Int4 CountTextAlignNodeNum(AlignNodePtr anp, Int4 m_left, Int4 m_right)
687 {
688 Int4 num_line = 0;
689 Int4 g_left, g_right;
690
691 AlignSegPtr asp;
692 ValNodePtr feature_line, curr; /*the number of lines for a feature*/
693
694 g_left = anp->extremes.left;
695 g_right = anp->extremes.right;
696 if(m_left > g_right || m_right < g_left)
697 return 0;
698
699 num_line = 1;
700 feature_line = NULL;
701
702 /*process the GAPs and the DIAGs segs*/
703 for(asp = anp->segs; asp !=NULL; asp = asp->next)
704 {
705 g_left = asp->gr.left;
706 g_right = asp->gr.right;
707 if(!(g_left > m_right || g_right < m_left))
708 {
709 switch(asp->type)
710 {
711 case GAP_SEG:
712 break;
713
714 case REG_SEG:
715 case DIAG_SEG:
716 g_left = MAX(m_left, g_left);
717 g_right = MIN(m_right, g_right);
718 count_feature_buf_line (asp->cnp, g_left, g_right, &feature_line);
719 break;
720 default:
721 break;
722 }
723 }
724 if(g_left > m_right)
725 break;
726 }
727 if(feature_line != NULL)
728 {
729 for(curr = feature_line; curr != NULL; curr = curr->next)
730 ++num_line;
731 ValNodeFree(feature_line);
732 }
733
734 return num_line;
735 }
addline_perblock(EditAlignDataPtr adp,Int4 diffs)736 static Int4 addline_perblock (EditAlignDataPtr adp, Int4 diffs)
737 {
738 Int4 line = 0;
739 ValNodePtr vnp;
740 SeqParamPtr prm;
741 Int1 j;
742
743 if (adp->draw_scale) line += (Int4) diffs;
744 if (adp->draw_bars) line += (Int4) diffs;
745 for (vnp = adp->params; vnp != NULL; vnp = vnp->next)
746 {
747 prm = (SeqParamPtr) vnp->data.ptrvalue;
748 if ( prm->complement ) line += (Int4) diffs;
749 for (j=0; j<=6; j++)
750 if (prm->rf[j]) line += (Int4) diffs;
751 }
752 return line;
753 }
754
feat_linenum(Int4 slp_start,Int4 slp_stop,Int4 line_len,Int4 left,Int4 right)755 static Int4 feat_linenum (Int4 slp_start, Int4 slp_stop, Int4 line_len, Int4 left,
756 Int4 right)
757 {
758 Int4 modstart;
759 Int4 modstop;
760
761 slp_start = MAX (slp_start, left);
762 modstart = slp_start % line_len;
763 if ( modstart > 0) slp_start -= modstart;
764
765 slp_stop = MIN (slp_stop, right);
766 modstop = slp_stop % line_len;
767 if ( modstop > 0) slp_stop += line_len;
768
769 return (Int4)((slp_stop - slp_start) / line_len);
770 }
771
CountFeatNum(ValNodePtr adpfeat,Int4 line_len,Int4 left,Int4 right)772 static Int4 CountFeatNum (ValNodePtr adpfeat, Int4 line_len, Int4 left, Int4 right){
773 ValNodePtr vnp;
774 SelEdStructPtr sesp;
775 SeqLocPtr slp;
776 Int4 line = 0;
777
778 for (vnp = adpfeat; vnp != NULL; vnp = vnp->next)
779 {
780 sesp = (SelEdStructPtr) vnp->data.ptrvalue;
781 for (; sesp != NULL; sesp = sesp->next)
782 {
783 if (vnp->choice ==FEATDEF_CDS && sesp->regiontype ==OM_REGION_SEQLOC
784 && sesp->region !=NULL)
785 {
786 slp = (SeqLocPtr) sesp->region;;
787 if (SeqLocStart(slp) > right || SeqLocStop(slp) < left)
788 line+=0;
789 else {
790 line+= feat_linenum (SeqLocStart(slp), SeqLocStop(slp), line_len, left, right);
791 }
792 }
793 }
794 }
795 return line;
796 }
count_nline(EditAlignDataPtr adp,ValNodePtr anp_list,Int4 line_len,Int4 left,Int4 right,Int4 voffset)797 static Int4 count_nline (EditAlignDataPtr adp, ValNodePtr anp_list, Int4 line_len, Int4 left, Int4 right, Int4 voffset)
798 {
799 AlignNodePtr anp;
800 Int4 c_start, c_stop;
801 Int4 line_num = 0;
802 Int4 h_block = 0;
803 ValNodePtr curr;
804
805 if(anp_list == NULL)
806 return h_block;
807 if(voffset == 0)
808 return h_block;
809 anp = (AlignNodePtr)anp_list->data.ptrvalue;
810 if(left == -1)
811 left = anp->extremes.left;
812 if(right == -1)
813 right = anp->extremes.right;
814 if(left > anp->extremes.right || right < anp->extremes.left)
815 return h_block;
816 left = MAX(left, anp->extremes.left);
817 right = MIN(right, anp->extremes.right);
818 if (left >= right)
819 return h_block;
820 c_start = left;
821 while(line_num < voffset)
822 {
823 c_stop = MIN(right, (c_start+line_len-1));
824 for(curr = anp_list; curr != NULL; curr = curr->next)
825 {
826 anp = (AlignNodePtr)curr->data.ptrvalue;
827 line_num += CountTextAlignNodeNum(anp, c_start, c_stop);
828 }
829 line_num += (Int4) addline_perblock (adp, 1);
830 line_num += (Int4) CountFeatNum (adp->feat, line_len, c_start, c_stop);
831 line_num += (Int4) CountFeatNum (adp->seqfeat, line_len, c_start, c_stop);
832 if (line_num > voffset) break;
833 ++h_block;
834 c_start = c_stop+1;
835 }
836 return c_start;
837 }
838
hoffset2voffset(EditAlignDataPtr adp,ValNodePtr anp_list,Int4 line_len,Int4 left,Int4 right,Int4 hoffset)839 extern Int4 hoffset2voffset (EditAlignDataPtr adp, ValNodePtr anp_list, Int4 line_len, Int4 left, Int4 right, Int4 hoffset)
840 {
841 AlignNodePtr anp;
842 Int4 c_start, c_stop;
843 Int4 line_num = 0;
844 Int4 preline;
845 Int4 h_block = 0;
846 ValNodePtr curr;
847
848 if(anp_list == NULL)
849 return h_block;
850 if(hoffset == 0)
851 return h_block;
852 anp = (AlignNodePtr)anp_list->data.ptrvalue;
853 if(left == -1)
854 left = anp->extremes.left;
855 if(right == -1)
856 right = anp->extremes.right;
857 if(left > anp->extremes.right || right < anp->extremes.left)
858 return h_block;
859 left = MAX(left, anp->extremes.left);
860 right = MIN(right, anp->extremes.right);
861 if (left >= right)
862 return h_block;
863 c_start = left;
864 while(c_start<hoffset)
865 {
866 preline = line_num;
867 c_stop = MIN(right, (c_start+line_len-1));
868 for(curr = anp_list; curr != NULL; curr = curr->next)
869 {
870 anp = (AlignNodePtr)curr->data.ptrvalue;
871 line_num += CountTextAlignNodeNum(anp, c_start, c_stop);
872 }
873 line_num += (Int4) addline_perblock (adp, 1);
874 line_num += (Int4) CountFeatNum (adp->feat, line_len, c_start, c_stop);
875 line_num += (Int4) CountFeatNum (adp->seqfeat, line_len, c_start, c_stop);
876 ++h_block;
877 c_start = c_stop+1;
878 }
879
880 preline = line_num;
881 return preline;
882 }
883
884
885 /*******************************************
886 *** Scrolling functions
887 ***
888 *** function test whether in/out buffer:
889 *** not used
890 ***
891 ********************************************/
VscrlProc(BaR sb,SlatE s,Int4 newval,Int4 oldval)892 extern void VscrlProc (BaR sb, SlatE s, Int4 newval, Int4 oldval)
893 {
894 EditAlignDataPtr adp;
895 RecT r;
896 Int4 pixels;
897 WindoW tempPort;
898 Int4 temp;
899 Int4 x;
900 Int4 oldhoffset;
901
902 if ( s == NULL ) {
903 return;
904 }
905 if ( (adp = GetAlignDataPanel ((PaneL) s)) == NULL )
906 return;
907 if ( adp->seqnumber == 0 )
908 return;
909 tempPort = SavePort ((PaneL) s);
910 Select ((PaneL) s);
911 ObjectRect ((PaneL) s, &r);
912 if ((newval > oldval && newval - oldval <= adp->vPage )
913 || (newval < oldval && oldval - newval <= adp->vPage ))
914 {
915 InsetRect (&r, HRZ_BORDER_WIDTH, VER_BORDER_WIDTH);
916 pixels = (oldval - newval) * adp->lineheight;
917 r.bottom = r.top + adp->pnlLine * adp->lineheight +1;
918 r.top = r.top + 1;
919 ScrollRect (&r, 0, pixels);
920 }
921 adp->voffset = GetBarValue (sb);
922 if (abs(newval - oldval) == 1)
923 {
924 oldhoffset = adp->hoffset;
925 temp = oldhoffset + adp->visibleWidth + adp->visibleLength;
926 temp = MIN (temp, adp->bufferstart + adp->bufferlength);
927 if ((oldhoffset + adp->visibleWidth > adp->bufferstart
928 && temp < adp->bufferstart + adp->bufferlength)
929 || temp == adp->length)
930 {
931 adp->firstssp = next_to_draw (adp, (Boolean)((newval-oldval)>0));
932 }
933 else {
934 data_collect_arrange (adp, TRUE);
935 if (temp < adp->length)
936 InvalRect (&r);
937 }
938 if (adp->hoffset == 0 && adp->firstssp->prev == NULL && adp->voffset != 0)
939 {
940 adp->voffset = 0;
941 CorrectBarValue (sb, (Int4) 0);
942 }
943 if (adp->seqnumber == 1
944 && adp->hoffset+adp->visibleWidth>adp->length
945 && adp->voffset<adp->nlines)
946 {
947 adp->voffset = adp->nlines;
948 CorrectBarValue (sb, (Int4) adp->nlines);
949 }
950 }
951 else {
952 Int4 tmp;
953 x = adp->seqnumber;
954 if (adp->draw_scale) x++;
955 if (adp->draw_bars) x++;
956
957 if (adp->showfeat)
958 {
959 adp->hoffset = count_nline (adp, adp->anp_list, adp->visibleWidth, 0, adp->length-1, (Int4)((FloatLo)adp->voffset));
960 }
961 else
962 {
963 if (adp->seqnumber > 1)
964 adp->hoffset = adp->visibleWidth * (Int4)((FloatLo)adp->voffset / (adp->seqnumber + 2));
965 else
966 adp->hoffset = adp->visibleWidth * (Int4)((FloatLo)adp->voffset);
967 }
968
969 /* Use adp->int4value2 to disable line number counting when scrolling */
970 tmp = adp->int4value2;
971 adp->int4value2 = -1;
972 if (adp->hoffset > adp->bufferstart
973 && adp->hoffset+adp->visibleLength+ adp->visibleWidth < adp->bufferstart +adp->bufferlength)
974 {
975 data_collect_arrange (adp, FALSE);
976 } else {
977 data_collect_arrange (adp, TRUE);
978 }
979 adp->int4value2 = tmp;
980
981 if (x == 0) {
982 adp->firstssp=go_to_next_to_draw(adp, TRUE, (Int4)0);
983 } else {
984 adp->firstssp=go_to_next_to_draw(adp, TRUE, (Int4)(adp->voffset%x));
985 }
986 InvalRect (&r);
987 }
988 RestorePort(tempPort);
989 Update ();
990 }
991
HscrlProc(BaR sb,SlatE s,Int4 newval,Int4 oldval)992 extern void HscrlProc (BaR sb, SlatE s, Int4 newval, Int4 oldval)
993 {
994 EditAlignDataPtr adp;
995 RecT r;
996 Int4 pixels;
997 WindoW tempPort;
998
999 if ( s == NULL ) {
1000 return;
1001 }
1002 if ( (adp = GetAlignDataPanel ((PaneL) s)) == NULL ) return;
1003 if ( adp->seqnumber == 0 ) return;
1004 tempPort = SavePort ((PaneL) s);
1005 Select ((PaneL) s);
1006 ObjectRect ((PaneL) s, &r);
1007 if ((newval > oldval && newval - oldval <= adp->hPage )
1008 || (newval < oldval && oldval - newval <= adp->hPage ))
1009 {
1010 InsetRect (&r, HRZ_BORDER_WIDTH, VER_BORDER_WIDTH);
1011 pixels = (oldval - newval) * adp->charw +1;
1012 ScrollRect (&r, pixels, 0);
1013 } else {
1014 InvalRect (&r);
1015 }
1016 adp->hoffset = GetBarValue (sb);
1017 RestorePort(tempPort);
1018 Update ();
1019 }
1020
1021 /*******************************************************************
1022 ***
1023 *** do_resize
1024 ***
1025 *******************************************************************/
do_resize_panel(PaneL pnl,EditAlignDataPtr adp,Int4 width,Int4 height,Boolean rearrange)1026 extern void do_resize_panel (PaneL pnl, EditAlignDataPtr adp, Int4 width, Int4 height, Boolean rearrange)
1027 {
1028 Int4 old_voffset;
1029 Int4 new_buffer;
1030 Int4 j;
1031 Int4 lg;
1032 Int4 old_visibleWidth;
1033 Int4 x, y;
1034 float hratio;
1035
1036 x = (width - adp->margin.right) / adp->charw;
1037 if (x < 0)
1038 x = 0;
1039 hratio = (float)adp->hoffset / (float)adp->length;
1040 adp->pnlWidth = x;
1041 if (adp->pnlWidth < adp->marginleft + 10) {
1042 adp->firstssp = NULL;
1043 return;
1044 }
1045 x = (height - adp->margin.bottom) / adp->lineheight;
1046 if (x < 0)
1047 x = 0;
1048 adp->pnlLine = x;
1049 if (adp->pnlLine < 3) {
1050 adp->firstssp = NULL;
1051 return;
1052 }
1053 y = 0; x = 0;
1054 if (adp->columnpcell > 0) {
1055 y = (Int4) (adp->pnlWidth -adp->marginleft) / (Int4) adp->columnpcell;
1056 x = (Int4) (adp->pnlWidth -adp->marginleft -y) % (Int4)(adp->columnpcell);
1057 if (x == 9)
1058 x = -1;
1059 }
1060 old_visibleWidth = adp->visibleWidth;
1061 adp->visibleWidth = (Int4) (adp->pnlWidth -adp->marginleft -y -x);
1062 if (adp->visibleWidth < 10) {
1063 adp->firstssp = NULL;
1064 return;
1065 }
1066 if ( adp->seqnumber == 0 )
1067 return;
1068 if (old_visibleWidth != adp->visibleWidth) {
1069 old_voffset = adp->voffset;
1070 adp->voffset = (Int4)(((float)old_visibleWidth/(float)adp->visibleWidth) * (float)old_voffset);
1071 }
1072 new_buffer = adp->pnlLine * adp->visibleWidth;
1073 if (new_buffer * 3 > adp->minbufferlength)
1074 {
1075 adp->minbufferlength = new_buffer * 3;
1076 if ( adp->colonne != NULL )
1077 MemFree (adp->colonne);
1078 adp->colonne = NULL;
1079 lg = adp->minbufferlength + adp->editbuffer + 4;
1080 adp->colonne = (Int4Ptr) MemNew ((size_t) (lg * sizeof(Int4)));
1081 for (j=0; j<adp->minbufferlength +adp->editbuffer; j++) adp->colonne[j] = -1;
1082 rearrange = TRUE;
1083 }
1084 adp->vPage = /* adp->pnlLine - 1; */ 1;
1085 adp->hPage = adp->visibleWidth - 1;
1086 data_collect_arrange (adp, rearrange);
1087 SeqEdSetCorrectBarMax (pnl, adp, hratio);
1088 SeqEdCorrectBarPage (pnl, adp->vPage, adp->vPage);
1089 SeqEdCorrectBarValue (pnl, SeqEdGetValueScrollBar (pnl));
1090 }
1091
do_resize_window(PaneL pnl,EditAlignDataPtr adp,Boolean rearrange)1092 extern void do_resize_window (PaneL pnl, EditAlignDataPtr adp, Boolean rearrange)
1093 {
1094 SeqEditViewFormPtr wdp;
1095 WindoW w;
1096 RecT rw; /* window rect */
1097 RecT rp; /* panel rect */
1098 RecT rb; /* buttons rect */
1099 RecT rct; /* new rect for panel */
1100 Int4 buttonwidth,
1101 buttonheight;
1102 Int4 x, y;
1103
1104 w = getwindow_frompanel (pnl);
1105 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
1106 if (wdp == NULL)
1107 return;
1108 ObjectRect (w, &rw);
1109 get_client_rect (pnl, &rp);
1110 GetPosition (pnl, &rp);
1111 x = adp->xoff;
1112 y = rw.bottom - rw.top;
1113 LoadRect ( &rct, x, adp->yoff, (Int4)(rw.right - rw.left - adp->x),
1114 (Int4)(y - adp->y));
1115 SetPosition (pnl, &rct );
1116 AdjustPrnt (pnl, &rct, FALSE);
1117 ObjectRect (pnl, &rp );
1118
1119 GetPosition ((GrouP) wdp->btngp, &rb);
1120 buttonwidth = rb.right - rb.left;
1121 buttonheight = rb.bottom - rb.top;
1122 LoadRect (&rb, x, (Int4)(y -buttonheight - adp->ybutt - 1),
1123 (Int4)(x+ buttonwidth), (Int4)(y-adp->ybutt-1));
1124 SetPosition(wdp->btngp, &rb);
1125 AdjustPrnt (wdp->btngp, &rb, FALSE);
1126
1127 ResetClip ();
1128 Update ();
1129 InsetRect (&rp, 4, 4);
1130 do_resize_panel (pnl, adp, (Int4)(rp.right - rp.left), (Int4)(rp.bottom - rp.top), rearrange);
1131 return;
1132 }
1133
1134 /***********************************************************************/
1135 /***********************************************************************/
1136 /***********************************************************************/
1137
1138 /***********************************************************************/
1139 /***********************************************************************/
1140 /***********************************************************************/
1141 /***********************************************************************
1142 *** Draw Scale
1143 *** draw_scale
1144 *** draw_bars
1145 ***
1146 ***********************************************************************/
draw_scale(EditAlignDataPtr adp,Int4 hoffset,Int4 scalelength,PoinT * ptlh)1147 static void draw_scale (EditAlignDataPtr adp, Int4 hoffset, Int4 scalelength, PoinT *ptlh)
1148 {
1149 Char str[128];
1150 Int4 scal;
1151 Int4 ptx, pty;
1152 Int4 j;
1153 Int4 marqueediff;
1154
1155 if ( !adp->draw_scale ) return;
1156 SetColor (adp->colorRefs[COLOR_SCALE]);
1157 ptx = ptlh->x + adp->margin.left + (Int4)(adp->charw * 0.5) - 2;
1158 pty = ptlh->y + adp->ascent;
1159 marqueediff = (Int4)( 2.00 / 6.00 * adp->lineheight);
1160 for ( j = hoffset; j < hoffset + scalelength; j++)
1161 {
1162 if ( adp->colonne[j] > -1)
1163 {
1164 scal = (Int4)(adp->gr.left + 1 + adp->colonne[j]);
1165 if (scal % 10 == 0)
1166 {
1167 sprintf (str, "%d", (int)scal);
1168 MoveTo ((Int4)(ptx - StringWidth(str) + (adp->charw/2) +1),
1169 (Int4)(pty + marqueediff));
1170 PaintString (str);
1171 }
1172 }
1173 if (adp->columnpcell > 0 && j > hoffset)
1174 if ((Int4) j % (Int4) adp->columnpcell == 0) ptx += adp->charw;
1175 ptx += adp->charw;
1176 }
1177 Black();
1178 return ;
1179 }
1180
draw_bars(EditAlignDataPtr adp,Int4 hoffset,Int4 scalelength,PoinT * ptlh)1181 static void draw_bars (EditAlignDataPtr adp, Int4 hoffset, Int4 scalelength, PoinT *ptlh)
1182 {
1183 Int4 scal;
1184 Int4 ptx;
1185 Int4 y;
1186 Int4 j;
1187 Int4 marqueelong, marqueeshort, marqueediff;
1188
1189 if ( !adp->draw_bars ) return;
1190 SetColor (adp->colorRefs[COLOR_SCALE]);
1191 ptx = ptlh->x + adp->margin.left + (Int4)(adp->charw * 0.5) - 1;
1192 y = ptlh->y + (Int4) (2.00 / 6.00 * adp->lineheight);
1193 marqueelong = (Int4) (4.00 / 6.00 * adp->lineheight);
1194 marqueeshort= (Int4) (2.00 / 6.00 * adp->lineheight);
1195 marqueediff = (Int4) (2.00 / 6.00 * adp->lineheight);
1196 for ( j = hoffset; j < hoffset + scalelength; j++)
1197 {
1198 if ( adp->colonne[j] > -1)
1199 {
1200 scal = (Int4)(adp->gr.left + 1 + adp->colonne[j]);
1201 if (scal % 10 == 0)
1202 {
1203 MoveTo (ptx , y );
1204 LineTo (ptx , (Int4)(y + marqueelong));
1205 }
1206 else if (scal % 5 == 0)
1207 {
1208 MoveTo (ptx , (Int4)(y + marqueediff));
1209 LineTo (ptx , (Int4)(y + marqueediff + marqueeshort));
1210 }
1211 }
1212 if (adp->columnpcell > 0 && j > hoffset)
1213 if ((Int4) j % (Int4) adp->columnpcell == 0) ptx += adp->charw;
1214 ptx += adp->charw;
1215 }
1216 Black();
1217 return ;
1218 }
1219
1220 /***********************************************************************
1221 *** draw_id
1222 ************************************************************************/
draw_id(EditAlignDataPtr adp,PoinT * pt,Int4 index,CharPtr strid,Uint1 strand,Int4 pos,Uint2 itemtype,Boolean idselected,Boolean is_master,Int4 group)1223 static void draw_id (EditAlignDataPtr adp, PoinT *pt, Int4 index, CharPtr strid, Uint1 strand, Int4 pos, Uint2 itemtype, Boolean idselected, Boolean is_master, Int4 group)
1224 {
1225 Char str[128], str1[128];
1226 RecT rct;
1227 CharPtr tmp;
1228 Int4 stringlens;
1229 Int4 j;
1230 Int4 total = 0;
1231 Int4 posspace;
1232
1233 /*!!!!!!!!!!!!!!!!!!!!!!!!!!*/ idselected = FALSE;
1234
1235 if (adp->length < 1000) { posspace = 4;
1236 } else if (adp->length < 10000) { posspace = 5;
1237 } else if (adp->length < 100000) { posspace = 6;
1238 } else if (adp->length < 1000000) { posspace = 7;
1239 } else { posspace = 8;
1240 }
1241
1242 if (adp->marginwithindex) total += 3;
1243 if (adp->marginwithgroup) total += 4;
1244 if (adp->marginwithpos) total += posspace;
1245 total += 2;
1246
1247 str[0] = '\0';
1248 tmp = str;
1249 if (adp->marginwithindex && index > 0) {
1250 sprintf (str1, "%3d ",(int) index);
1251 } else {
1252 sprintf (str1, " ");
1253 }
1254 tmp = StringMove (tmp, str1);
1255 tmp[0] = '\0';
1256
1257 adp->marginwithgroup = FALSE;
1258 if (adp->marginwithgroup) {
1259 if (group >= 0)
1260 sprintf (str1, "%4d ",(int) group);
1261 else sprintf (str1, " ");
1262 tmp = StringMove (tmp, str1);
1263 tmp[0] = '\0';
1264 }
1265
1266 if (strid != NULL && strid[0]!='\0') {
1267 stringlens = (Int4)(StringLen (strid));
1268 /******!!!!!!!!!!!!!!!
1269 if (stringlens > 4) {
1270 if (strid[0] == 'l' && strid[1] == 'c' && strid[2] == 'l') {
1271 strid += 4;
1272 stringlens -= 4;
1273 }
1274 }
1275 !!!!!!!!!!!!!!!!!*********/
1276 for (j=0; j<stringlens; j++)
1277 str1 [j] = strid [j];
1278 str1 [j] = '\0';
1279 if (stringlens < adp->size_labels) {
1280 for (j=stringlens; j<adp->size_labels; j++)
1281 str1 [j] = ' ';
1282 str1 [j] = '\0';
1283 stringlens = (Int4)(StringLen (str1));
1284 }
1285 stringlens = MIN (adp->marginleft - total, stringlens);
1286 str1 [stringlens] = '\0';
1287 tmp = StringMove (tmp, str1);
1288 }
1289 else if (adp->marginleft > 20) {
1290 sprintf (str1, " ");
1291 tmp = StringMove (tmp, str1);
1292 }
1293 /*
1294 symbol[0] = ' ';
1295 if (strand == Seq_strand_minus)
1296 symbol[1] = '<';
1297 else
1298 symbol[1] = '>';
1299 symbol[2] = '\0';
1300 tmp = StringMove (tmp, symbol);
1301 */
1302 if (adp->marginwithpos) {
1303 if (posspace <= 4) {
1304 if (pos > 0)
1305 sprintf (str1, "%4ld ", (long) pos);
1306 else sprintf (str1, " ");
1307 } else if (posspace == 5) {
1308 if (pos > 0)
1309 sprintf (str1, "%5ld ", (long) pos);
1310 else sprintf (str1, " ");
1311 } else if (posspace == 6) {
1312 if (pos > 0)
1313 sprintf (str1, "%6ld ", (long) pos);
1314 else sprintf (str1, " ");
1315 } else {
1316 if (pos > 0)
1317 sprintf (str1, "%7ld ", (long) pos);
1318 else sprintf (str1, " ");
1319 }
1320 tmp = StringMove (tmp, str1);
1321 }
1322 *tmp = '\0';
1323
1324 stringlens = (Int4)(StringLen(str));
1325 if (stringlens < adp->marginleft -1)
1326 for (j = stringlens; j < adp->marginleft; j++, tmp++)
1327 *tmp = ' ';
1328 str [adp->marginleft -1] = ' ';
1329 str [adp->marginleft] = '\0';
1330 if ( itemtype != OBJ_BIOSEQ && adp->displaytype )
1331 SelectColor (162, 163, 82);
1332 else if (is_master && !adp->all_sequences)
1333 SetColor (adp->colorRefs[COLOR_ID_MASTER]);
1334 else
1335 SetColor (adp->colorRefs[COLOR_ID]);
1336 if ( !idselected )
1337 {
1338 Black();
1339 MoveTo (pt->x, (Int4)(pt->y + adp->ascent));
1340 PaintString (str);
1341 }
1342 else {
1343 InvertColors ();
1344 LoadRect(&rct, pt->x, pt->y, (Int4)(pt->x +stringlens *adp->charw -2),
1345 (Int4)(pt->y + adp->lineheight));
1346 EraseRect (&rct);
1347 MoveTo (pt->x, (Int4)(pt->y +adp->ascent));
1348 PaintString (str);
1349 InvertColors();
1350 }
1351 Black();
1352 return;
1353 }
1354
1355 /******************************************************************
1356 *** paint_caret, draw caret : draws caret
1357 ***
1358 *** Now caret is a T between basis of letters
1359 *** Before it was a bar between letters:
1360
1361 pt1.x = pt.x + ( column + marginleft ) * charw -1;
1362 pt1.y = pt.y;
1363 pt2.x = pt1.x;
1364 pt2.y = pt1.y + lineheight -2;
1365 ***
1366 *******************************************************************/
paint_caret(PoinT pt,Int4 column,Int4 charw,Int4 lineheight,Int4 marginleft)1367 static void paint_caret (PoinT pt, Int4 column, Int4 charw, Int4 lineheight, Int4 marginleft)
1368 {
1369 PoinT pt1, pt2;
1370 Int4 lenv = 3;
1371 Int4 lenh = 2;
1372 Int4 row;
1373
1374 Red ();
1375 WidePen (2);
1376 row = pt.x + ( column + marginleft ) * charw -1;
1377 pt1.x = row;
1378 pt1.y = pt.y + lineheight -1;
1379 pt2.x = row;
1380 pt2.y = pt1.y -lenv;
1381 DrawLine (pt1, pt2);
1382 pt2.x = row +lenh;
1383 pt2.y = pt1.y;
1384 DrawLine (pt1, pt2);
1385 pt2.x = row -lenh;
1386 pt2.y = pt1.y;
1387 DrawLine (pt1, pt2);
1388 WidePen (1);
1389 Black ();
1390 }
1391
draw_caret(EditAlignDataPtr adp,SelEdStructPtr sesp,PoinT pt,Int4 line)1392 static void draw_caret (EditAlignDataPtr adp, SelEdStructPtr sesp, PoinT pt, Int4 line)
1393 {
1394 SeqLocPtr slp;
1395 Int4 column;
1396
1397 if (!adp->display_panel)
1398 {
1399 if ( is_samess_ses (&(adp->caret), sesp))
1400 {
1401 slp = (SeqLocPtr) adp->caret.region;
1402 if(SeqPosInLineColumn (SeqLocStart(slp), adp->alignline[line], &column, adp->hoffset, adp) )
1403 {
1404 paint_caret (pt, column, adp->charw, adp->lineheight, adp->marginleft);
1405 }
1406 }
1407 }
1408 }
1409
1410 /*********************************************************************
1411 *** PaintSubseq : paint visible sequence
1412 **********************************************************************/
1413 /*browse a structure to find out the colour number idx (zero-based)
1414 seq_color is a field in MediaInfo structure; see cn3dmsg.h*/
1415
GiveClrFromIdx(Int4 idx,ValNodePtr seq_color)1416 static ResidueColorCellPtr GiveClrFromIdx(Int4 idx,ValNodePtr seq_color)
1417 {
1418 Int4 i;
1419
1420 i=0;
1421 while(seq_color){
1422 if (i==idx) {
1423 return((ResidueColorCellPtr)seq_color->data.ptrvalue);
1424 }
1425 seq_color=seq_color->next;
1426 i++;
1427 }
1428
1429 return NULL;
1430 }
1431
PaintSubseq(Int4 k,Int4 lg,Int4 from,PoinT * pt,CharPtr vstr,Boolean invert,EditAlignDataPtr adp,Boolean draw_diff,CharPtr * masterstr,Boolean cmplt,ValNodePtr seq_color,SeqIdPtr sip)1432 static void PaintSubseq (Int4 k, Int4 lg, Int4 from, PoinT *pt, CharPtr vstr, Boolean invert, EditAlignDataPtr adp, Boolean draw_diff, CharPtr *masterstr, Boolean cmplt, ValNodePtr seq_color,SeqIdPtr sip)
1433 {
1434 CharPtr strPtr;
1435 Char str[512];
1436 Uint4 curColor;
1437 Int4 to = k + lg;
1438 Int4 caret_color = 0;
1439 CharPtr masterstrptr = NULL;
1440 RecT rct;
1441 Uint4 blackColor = GetColorRGB(0,0,0), whiteColor = GetColorRGB(255, 255, 255),
1442 newColor;
1443
1444 Boolean pretty = (Boolean) (seq_color!=NULL);
1445 ResidueColorCellPtr rgb;
1446 Int4 from2;
1447
1448 dashedstring ((CharPtr) str, 512);
1449 strPtr = str;
1450
1451 if (pretty) {
1452 from2=AlignCoordToSeqCoord (from, sip,
1453 (SeqAlignPtr)adp->sap_align->data, adp->sqloc_list, 0);
1454
1455 if (from2!=GAP_RESIDUE)
1456 rgb=GiveClrFromIdx(from2,seq_color);
1457 else rgb=NULL;
1458
1459
1460 if(rgb != NULL ){
1461 curColor = GetColorRGB (rgb->rgb[0], rgb->rgb[1],rgb->rgb[2]);
1462 }
1463 else curColor =blackColor;
1464 }
1465 else {
1466 curColor = adp->colorRefs[(Uint1)(vstr[k] - '*')];
1467 }
1468 if (curColor == (Uint4)172)
1469 curColor = blackColor;
1470
1471 if (masterstr != NULL) {
1472 if (*masterstr != NULL)
1473 masterstrptr = *masterstr;
1474 }
1475
1476 while ( k < to )
1477 {
1478 if (pretty) {
1479 from2=AlignCoordToSeqCoord (k+from, sip,
1480 (SeqAlignPtr)adp->sap_align->data, adp->sqloc_list, 0);
1481
1482 if (from2!=GAP_RESIDUE)
1483 rgb=GiveClrFromIdx(from2,seq_color);
1484 else rgb=NULL;
1485
1486 if(rgb != NULL ){
1487 newColor= GetColorRGB (rgb->rgb[0], rgb->rgb[1],rgb->rgb[2]);
1488 }
1489 else newColor=blackColor ;
1490 if (vstr[k] == '-') newColor=blackColor ;
1491 }
1492 else {
1493 newColor = adp->colorRefs[(Uint1)(vstr[k] - '*')];
1494 }
1495 /* if (newColor == (Uint4)172)
1496 newColor = blackColor; */
1497 /* yanli comment it out so that residues */
1498 /* with magenta color can be seen in salsa */
1499 if (newColor == whiteColor) newColor = blackColor;
1500 /* yanli added this so that residues colored with white */
1501 /* in Cn3D(with color by Domain) are drawn as black in salsa to be visible */
1502
1503 if ( adp->colonne [from +k -adp->bufferstart] < 0 )
1504 {
1505 *strPtr = 0;
1506 strPtr = str;
1507 if (cmplt)
1508 strPtr = complement_string (strPtr);
1509 MoveTo ((Int4)(pt->x +adp->margin.left), (Int4)(pt->y + adp->ascent));
1510 PaintString (strPtr);
1511 pt->x += caret_color * adp->charw;
1512 caret_color = 1;
1513 strPtr = str;
1514 Black();
1515 if ((from +k -adp->bufferstart) > adp->length)
1516 return;
1517 pt->x += adp->intersalpwidth * adp->charw;
1518 k += adp->intersalpwidth;
1519 SetColor (curColor);
1520 }
1521 else if (curColor != newColor)
1522 {
1523 *strPtr = 0;
1524 strPtr = str;
1525 if (cmplt)
1526 strPtr = complement_string (strPtr);
1527 MoveTo ((Int4)(pt->x +adp->margin.left), (Int4)(pt->y +adp->ascent));
1528 if (invert)
1529 {
1530 SetColor (adp->colorRefs[COLOR_SELECT]);
1531 InvertColors ();
1532 LoadRect (&rct, (Int4)(pt->x+adp->margin.left), pt->y, (Int4)(pt->x +adp->margin.left+ caret_color*adp->charw), (Int4)(pt->y +adp->lineheight -1));
1533 EraseRect (&rct);
1534 InvertColors ();
1535 if (adp->colorRefs[COLOR_SELECT]==blackColor)
1536 White();
1537 else {
1538 Black ();
1539 }
1540 }
1541 else {
1542 SetColor (curColor);
1543 }
1544 PaintString (strPtr);
1545 pt->x += caret_color *adp->charw;
1546 caret_color = 1;
1547 strPtr = str;
1548 if ( draw_diff && masterstrptr != NULL )
1549 {
1550 if (vstr[k] !='-') {
1551 if (ISA_na(adp->mol_type)) {
1552 if ((*masterstrptr == vstr[k]) && (vstr[k]<65 || vstr[k]>91))
1553 *strPtr = '.';
1554 else
1555 *strPtr = vstr[k];
1556 }
1557 else {
1558 if (TO_LOWER(*masterstrptr) == TO_LOWER(vstr[k])) {
1559 *strPtr = '.';
1560 } else {
1561 *strPtr = vstr[k];
1562 }
1563 }
1564 }
1565 else
1566 *strPtr = vstr[k];
1567 masterstrptr++;
1568 }
1569 else
1570 *strPtr = vstr[k];
1571 strPtr++;
1572 if (adp->columnpcell > 0)
1573 {
1574 if ((Int4) (k+1) % (Int4) adp->columnpcell == 0) {
1575 *strPtr = ' ';
1576 strPtr++;
1577 caret_color++;
1578 }
1579 }
1580 curColor = newColor;
1581 k++;
1582 }
1583 else {
1584 if ( draw_diff && masterstrptr != NULL )
1585 {
1586 if (vstr[k] !='-') {
1587 if (ISA_na(adp->mol_type)) {
1588 if ((*masterstrptr == vstr[k]) && (vstr[k]<65 || vstr[k]>91))
1589 *strPtr = '.';
1590 else
1591 *strPtr = vstr[k];
1592 }
1593 else {
1594 if (TO_LOWER(*masterstrptr) == TO_LOWER(vstr[k])) {
1595 *strPtr = '.';
1596 } else {
1597 *strPtr = vstr[k];
1598 }
1599 }
1600 }
1601 else
1602 *strPtr = vstr[k];
1603 masterstrptr++;
1604 }
1605 else
1606 *strPtr = vstr[k];
1607 strPtr++;
1608 caret_color++;
1609 if (adp->columnpcell > 0)
1610 {
1611 if ((Int4) (k+1) % (Int4) adp->columnpcell == 0)
1612 {
1613 *strPtr = ' ';
1614 strPtr++;
1615 caret_color++;
1616 }
1617 }
1618 k++;
1619 }
1620 }
1621 *strPtr = 0;
1622 strPtr = str;
1623 if (cmplt)
1624 strPtr = complement_string (strPtr);
1625 MoveTo ((Int4)(pt->x +adp->margin.left), (Int4)(pt->y +adp->ascent));
1626 if (invert)
1627 {
1628 SetColor (adp->colorRefs[COLOR_SELECT]);
1629 InvertColors ();
1630 LoadRect (&rct, (Int4)(pt->x+adp->margin.left), pt->y, (Int4)(pt->x +adp->margin.left+ caret_color*adp->charw), (Int4)(pt->y +adp->lineheight -1));
1631 EraseRect (&rct);
1632 InvertColors ();
1633 if(adp->colorRefs[COLOR_SELECT]==blackColor)
1634 White();
1635 else {
1636 Black ();
1637 }
1638 }
1639 else {
1640 SetColor (curColor);
1641 }
1642 PaintString (strPtr);
1643 Black ();
1644 pt->x += caret_color *adp->charw;
1645 *masterstr = masterstrptr;
1646 return;
1647 }
1648
1649 /*****************************************************************
1650 *** draw_seq
1651 ******************************************************************/
deleteseqloc(ValNodePtr head,ValNodePtr delp)1652 static ValNodePtr deleteseqloc (ValNodePtr head, ValNodePtr delp)
1653 {
1654 ValNodePtr next = NULL,
1655 pre = NULL,
1656 tmp = NULL;
1657
1658 tmp = head;
1659 while (tmp!=NULL)
1660 {
1661 next = tmp->next;
1662 if (tmp == delp)
1663 {
1664 if (pre==NULL) {
1665 head = next;
1666 }
1667 else {
1668 pre->next = next;
1669 }
1670 tmp->next = NULL;
1671 SeqLocFree ((SeqLocPtr)tmp->data.ptrvalue);
1672 tmp->data.ptrvalue = NULL;
1673 ValNodeFree (tmp);
1674 }
1675 else
1676 pre = tmp;
1677 tmp = next;
1678 }
1679 return head;
1680 }
1681
1682
simplifySeqLocList(ValNodePtr valnode)1683 static ValNodePtr simplifySeqLocList (ValNodePtr valnode)
1684 {
1685 ValNodePtr vnpa = NULL,
1686 vnpb = NULL;
1687 SeqLocPtr slpa,
1688 slpb;
1689 SeqIntPtr sint;
1690 Boolean check = TRUE,
1691 loopin = TRUE;
1692
1693 while (check)
1694 {
1695 check = FALSE;
1696 loopin = TRUE;
1697 vnpa = valnode;
1698 while (vnpa != NULL && loopin)
1699 {
1700 for (vnpb = vnpa->next; vnpb != NULL; vnpb = vnpb->next)
1701 {
1702 slpa = (SeqLocPtr)vnpa->data.ptrvalue;
1703 slpb = (SeqLocPtr)vnpb->data.ptrvalue;
1704 if (SeqLocCompare (slpa, slpb) == SLC_A_IN_B) {
1705 valnode = deleteseqloc (valnode, vnpa);
1706 check = TRUE;
1707 loopin = FALSE;
1708 break;
1709 }
1710 else if (SeqLocCompare (slpa, slpb) == SLC_B_IN_A) {
1711 valnode = deleteseqloc (valnode, vnpb);
1712 check = TRUE;
1713 loopin = FALSE;
1714 break;
1715 }
1716 else if (SeqLocCompare (slpa, slpb) == SLC_A_EQ_B) {
1717 valnode = deleteseqloc (valnode, vnpb);
1718 check = TRUE;
1719 loopin = FALSE;
1720 break;
1721 }
1722 else if (SeqLocCompare (slpa, slpb) == SLC_A_OVERLAP_B) {
1723 sint = (SeqIntPtr) slpa->data.ptrvalue;
1724 if (SeqLocStart(slpa) < SeqLocStart(slpb)) {
1725 sint->to = SeqLocStop(slpb);
1726 }
1727 else {
1728 sint = (SeqIntPtr) slpa->data.ptrvalue;
1729 sint->from = SeqLocStart(slpb);
1730 }
1731 valnode = deleteseqloc (valnode, vnpb);
1732 check = TRUE;
1733 loopin = FALSE;
1734 break;
1735 }
1736 else if (SeqLocStop(slpa) == SeqLocStart(slpb)-1) {
1737 sint = (SeqIntPtr) slpa->data.ptrvalue;
1738 sint->to = SeqLocStop(slpb);
1739 valnode = deleteseqloc (valnode, vnpb);
1740 check = TRUE;
1741 loopin = FALSE;
1742 break;
1743 }
1744 else if (SeqLocStart(slpa) == SeqLocStop(slpb)+1) {
1745 sint = (SeqIntPtr) slpa->data.ptrvalue;
1746 sint->from = SeqLocStart(slpb);
1747 valnode = deleteseqloc (valnode, vnpb);
1748 check = TRUE;
1749 loopin = FALSE;
1750 break;
1751 }
1752 }
1753 if (loopin && vnpa != NULL)
1754 vnpa = vnpa->next;
1755 }
1756 }
1757 return valnode;
1758 }
1759
1760
getnextpos(ValNodePtr vnp,Int4 * stop)1761 static Int4 getnextpos (ValNodePtr vnp, Int4 *stop)
1762 {
1763 ValNodePtr tmp;
1764 SeqLocPtr slp;
1765 SeqIntPtr sint;
1766 Int4 valmin = (Int4)(INT4_MAX-2),
1767 val = (Int4)-1,
1768 val2 = (Int4)-1;
1769
1770 for (tmp=vnp; tmp!=NULL; tmp=tmp->next)
1771 {
1772 slp = (SeqLocPtr) tmp->data.ptrvalue;
1773 if (SeqLocStart(slp) < valmin) {
1774 valmin = SeqLocStart(slp);
1775 }
1776 }
1777 if (valmin < (Int4)(INT4_MAX-2))
1778 {
1779 for (tmp=vnp; tmp!=NULL; tmp=tmp->next)
1780 {
1781 slp = (SeqLocPtr) tmp->data.ptrvalue;
1782 if (SeqLocStart(slp) == valmin) {
1783 val = SeqLocStart(slp);
1784 val2 = SeqLocStop (slp);
1785 sint = (SeqIntPtr) slp->data.ptrvalue;
1786 sint->from = INT4_MAX;
1787 sint->to = INT4_MAX;
1788 break;
1789 }
1790 }
1791 }
1792 *stop = val2;
1793 return val;
1794 }
1795
draw_seq(EditAlignDataPtr adp,SelEdStructPtr sesp,Int4 from,Int4 drw_width,PoinT ptlh,CharPtr drw_str,Boolean draw_diff,CharPtr masterstr,Boolean cplmt,Uint2 itemtype,Boolean check_selection)1796 static void draw_seq (EditAlignDataPtr adp, SelEdStructPtr sesp, Int4 from, Int4 drw_width, PoinT ptlh, CharPtr drw_str, Boolean draw_diff, CharPtr masterstr, Boolean cplmt, Uint2 itemtype, Boolean check_selection)
1797 {
1798 SelStructPtr ssptmp;
1799 SeqIdPtr sip;
1800 Int4 start, stop;
1801 Int4 left, right;
1802 Int4 seg_lg;
1803 Int4 k,
1804 k1;
1805 Int4 chklocp;
1806 Int4 iCount = 0;
1807 SeqLocPtr slp;
1808 ValNodePtr startp = NULL;
1809
1810 SeqIdPtr sesp_sip= NULL;
1811 SeqIntPtr sinp = NULL;
1812
1813 SeqEditViewProcsPtr svpp;
1814 ValNodePtr vnp_seqinfo;
1815 ValNodePtr vnp_color = NULL;
1816 SeqIdPtr vnpcn3d_sip = NULL;
1817 MediaInfoPtr MIPtr;
1818
1819
1820 adp->start_select = -1;
1821 start = stop = -1;
1822 ssptmp = NULL;
1823 if (check_selection)
1824 {
1825 ssptmp = ObjMgrGetSelected ();
1826 for (; ssptmp != NULL; ssptmp = ssptmp->next)
1827 {
1828 if ( checkssp_for_editor (ssptmp) && is_samess_ses (ssptmp, sesp) )
1829 {
1830 sip = SeqLocId ((SeqLocPtr) ssptmp->region);
1831 start = SeqLocStart ((SeqLocPtr) ssptmp->region);
1832 adp->start_select = start;
1833 chklocp =chkloc(sip, start, adp->sqloc_list, &start);
1834 start = SeqCoordToAlignCoord (start, sip, (SeqAlignPtr) adp->sap_align->data, 0, chklocp);
1835 stop = SeqLocStop ((SeqLocPtr) ssptmp->region);
1836 chklocp =chkloc(sip, stop, adp->sqloc_list, &stop);
1837 stop = SeqCoordToAlignCoord (stop, sip, (SeqAlignPtr) adp->sap_align->data, 0, chklocp);
1838 /******
1839 if (start<=stop && (start < from + drw_width && (stop + 1) > from))
1840 ******/
1841 if ((start < from + drw_width && (stop + 1) > from))
1842 {
1843 if(start<=stop)
1844 slp = SeqLocIntNew (start, stop, Seq_strand_plus, sip);
1845 else
1846 slp = SeqLocIntNew (stop, start, Seq_strand_plus, sip);
1847 ValNodeAddPointer (&startp, 0, (Pointer)slp);
1848 iCount ++;
1849 }
1850 }
1851 }
1852 }
1853
1854
1855 svpp = (SeqEditViewProcsPtr) GetAppProperty ("SeqEditDisplayForm");
1856
1857 if(sesp->regiontype == 1){
1858 slp = (SeqLocPtr)sesp->region;
1859 sinp = (SeqIntPtr)slp->data.ptrvalue;
1860 sesp_sip = sinp->id;
1861 }
1862 if (svpp) {
1863 if (svpp->Cn3D_On && sesp_sip) {
1864 vnp_seqinfo = svpp->seqinfo;
1865
1866 while(vnp_seqinfo){
1867 MIPtr=(MediaInfoPtr)vnp_seqinfo->data.ptrvalue;
1868 /* if (MIPtr->entityID==sesp->entityID && MIPtr->itemID==sesp->itemID){
1869 vnp_color=MIPtr->seq_color;
1870 vnpcn3d_sip = MIPtr->sip;
1871 break;
1872 } */ /* yanli comment it out, instead doing the following */
1873
1874 if(SeqIdForSameBioseq(sesp_sip, MIPtr->sip)){
1875 vnp_color=MIPtr->seq_color;
1876 vnpcn3d_sip = MIPtr->sip;
1877 /* do not break so as to get the latest one */
1878 }
1879 vnp_seqinfo=vnp_seqinfo->next;
1880 }
1881 }
1882 }
1883 if (iCount > 0) {
1884 k = 0;
1885 k1 = from;
1886 startp = simplifySeqLocList (startp);
1887 start = getnextpos (startp, &stop);
1888 while ( k < drw_width && start >= 0) {
1889 if ( k + from < start )
1890 {
1891 left = (Int4) k1;
1892 right= start;
1893 seg_lg = MIN (right - left, drw_width);
1894 PaintSubseq (k, seg_lg, from, &ptlh, drw_str, FALSE, adp, draw_diff, &masterstr, cplmt, vnp_color,vnpcn3d_sip);
1895 k += seg_lg;
1896 }
1897 else if ( k +from >= start && k +from < stop + 1)
1898 {
1899 left = (Int4) MAX (k1, start);
1900 right= (Int4) MIN (from + drw_width, stop + 1);
1901 seg_lg = MIN (right - left, drw_width);
1902 PaintSubseq (k, seg_lg, from, &ptlh, drw_str, TRUE, adp, draw_diff, &masterstr, cplmt, vnp_color,vnpcn3d_sip);
1903 k += seg_lg;
1904 k1 = stop + 1;
1905 start = getnextpos (startp, &stop);
1906 }
1907 }
1908 if ( k < drw_width)
1909 {
1910 left = (Int4) k1;
1911 right= (Int4) from + drw_width;
1912 seg_lg = MIN (right - left, drw_width);
1913 PaintSubseq (k, seg_lg, from, &ptlh, drw_str, FALSE, adp, draw_diff, &masterstr, cplmt, vnp_color,vnpcn3d_sip);
1914 }
1915 }
1916 else {
1917 PaintSubseq (0, drw_width, from, &ptlh, drw_str, FALSE, adp, draw_diff, &masterstr, cplmt, vnp_color,vnpcn3d_sip);
1918 }
1919 if (startp != NULL)
1920 ValNodeFree (startp);
1921 return;
1922 }
1923
1924 /*****************************************************************
1925 *** draw_line
1926 ******************************************************************/
draw_line(EditAlignDataPtr adp,Int4 start,Int4 stop,Uint1 strand,PoinT * pt,Int4 from,Int4 drw_width,Int4 line,Int4 alignline,Uint4 color,Uint2 wideline,Boolean selected,Boolean partialstart,Boolean partialstop,BoolPtr gapline)1927 static void draw_line (EditAlignDataPtr adp, Int4 start, Int4 stop, Uint1 strand, PoinT *pt, Int4 from, Int4 drw_width, Int4 line, Int4 alignline, Uint4 color, Uint2 wideline, Boolean selected, Boolean partialstart, Boolean partialstop, BoolPtr gapline)
1928 {
1929 PoinT pt1, pt2,
1930 pttmp;
1931 PoinT oldpt1, oldpt2;
1932 FloatLo hgt = (FloatLo)(2.5 / 4.0);
1933 RecT leftrct, rightrct;
1934 Int4 left, right;
1935 Int4 yline;
1936 Int4 column;
1937 Int4 above, below;
1938 Int4 j, k;
1939 Int4 col1;
1940 Uint1 startin, stopin;
1941 BoolPtr gap;
1942
1943 left = (Int4) MAX ((Int4) from, (Int4) start);
1944 SeqPosInLineColumn (left, alignline, &column, adp->hoffset, adp);
1945 yline = pt->y + (Int4) (hgt * adp->ascent);
1946 pt1.x = pt->x + (column + adp->marginleft) * adp->charw;
1947 pt1.y = yline;
1948
1949 if (adp->columnpcell > 0) {
1950 col1 = column - (column-1)/adp->columnpcell;
1951 }
1952 right = (Int4) MIN ((Int4)from+drw_width-1, (Int4)stop);
1953 SeqPosInLineColumn (right, alignline, &column, adp->hoffset, adp);
1954 pt2.x = pt->x + (column + adp->marginleft + 1) * adp->charw;
1955 pt2.y = yline;
1956
1957 startin = stopin = 0;
1958 if ( start >= from ) {
1959 if (strand == Seq_strand_minus)
1960 startin = 1;
1961 else
1962 startin = 2;
1963 }
1964 if (stop < from+drw_width && stop != start) {
1965 if (strand == Seq_strand_minus)
1966 stopin = 1;
1967 else
1968 stopin = 2;
1969 }
1970 oldpt1.x = pt1.x;
1971 oldpt1.y = pt1.y;
1972 oldpt2.x = pt2.x;
1973 oldpt2.y = pt2.y;
1974 if (start<stop) {
1975 if (startin)
1976 pt1.x += 5;
1977
1978 SetColor (color);
1979 if (gapline == NULL) {
1980 if (stopin)
1981 pt2.x -= 5;
1982 WidePen (wideline);
1983 DrawLine (pt1, pt2);
1984 }
1985 else {
1986 pttmp.y = yline;
1987 j=k=left;
1988 for (j=0, gap=gapline; j<col1; j++)
1989 gap++;
1990 while (j<right) {
1991 if (*gap) {
1992 while (*gap && k<right) {
1993 gap++;
1994 k++;
1995 }
1996 WidePen (1);
1997 Dashed ();
1998 }
1999 else {
2000 while (!(*gap) && k<right) {
2001 gap++;
2002 k++;
2003 }
2004 WidePen (wideline);
2005 }
2006 SeqPosInLineColumn (k, alignline, &column, adp->hoffset, adp);
2007 if (k==right && stopin == 0) {
2008 column++;
2009 }
2010 pttmp.x = pt->x + (column + adp->marginleft) * adp->charw;
2011 DrawLine (pt1, pttmp);
2012 Solid ();
2013 pt1.x = pttmp.x;
2014 j = k;
2015 }
2016 }
2017 }
2018 if (selected) {
2019 #ifdef WIN_MAC
2020 above = 2;
2021 below = 4;
2022 #endif
2023 #ifdef WIN_MSWIN
2024 above = 3;
2025 below = 3;
2026 #endif
2027 #ifdef WIN_MOTIF
2028 above = 3;
2029 below = 3;
2030 #endif
2031 WidePen (1);
2032 Black ();
2033 pt1.y = pt2.y = yline + below;
2034 DrawLine (pt1, pt2);
2035 pt1.y = pt2.y = yline - above;
2036 DrawLine (pt1, pt2);
2037 White ();
2038 pt1.y = pt2.y = yline + below - 1;
2039 DrawLine (pt1, pt2);
2040 pt1.y = pt2.y = yline - above + 1;
2041 DrawLine (pt1, pt2);
2042 }
2043 WidePen (1);
2044 SetColor (color);
2045 pt1.x = oldpt1.x;
2046 pt1.y = oldpt1.y;
2047 pt2.x = oldpt2.x;
2048 pt2.y = oldpt2.y;
2049 if (startin == 1) {
2050 #ifdef WIN_MAC
2051 LoadRect(&leftrct, pt1.x , (Int2)(pt1.y -3), (Int2)(pt1.x +7), (Int4)(pt1.y +4) );
2052 OffsetRect (&leftrct, 0, 1);
2053 #endif
2054 #ifdef WIN_MSWIN
2055 LoadRect(&leftrct, pt1.x , (Int2)(pt1.y -3), (Int2)(pt1.x +7), (Int2)(pt1.y +4) );
2056 #endif
2057 #ifdef WIN_MOTIF
2058 LoadRect(&leftrct, pt1.x , (Int2)(pt1.y -3), (Int2)(pt1.x +7), (Int2) (pt1.y +4) );
2059 #endif
2060 if (partialstart)
2061 CopyBits (&leftrct, leftTriSym);
2062 else
2063 CopyBits (&leftrct, leftTriFillSym);
2064 }
2065 else if (startin == 2) {
2066 #ifdef WIN_MAC
2067 LoadRect(&leftrct, pt1.x , (Int2)(pt1.y -3), (Int2)(pt1.x +7), (Int2)(pt1.y +4));
2068 OffsetRect (&leftrct, 0, 1);
2069 #endif
2070 #ifdef WIN_MSWIN
2071 LoadRect(&leftrct, pt1.x , (Int2)(pt1.y -3), (Int2)(pt1.x +7), (Int2)(pt1.y +4));
2072 #endif
2073 #ifdef WIN_MOTIF
2074 LoadRect(&leftrct, pt1.x , (Int2)(pt1.y -3), (Int2)(pt1.x +7), (Int2)(pt1.y +4));
2075 #endif
2076 if (partialstart)
2077 CopyBits (&leftrct, rectSym);
2078 else
2079 CopyBits (&leftrct, rectFillSym);
2080 }
2081 if (stopin == 1) {
2082 #ifdef WIN_MAC
2083 LoadRect(&rightrct, (Int2)(pt2.x -7), (Int2)(pt2.y -3), pt2.x, (Int2)(pt2.y +4));
2084 OffsetRect (&rightrct, 0, 1);
2085 #endif
2086 #ifdef WIN_MSWIN
2087 LoadRect(&rightrct, (Int2)(pt2.x -7), (Int2)(pt2.y -3), pt2.x, (Int2)(pt2.y +4));
2088 #endif
2089 #ifdef WIN_MOTIF
2090 LoadRect(&rightrct, (Int2)(pt2.x -7), (Int2)(pt2.y -3), pt2.x, (Int2)(pt2.y +4));
2091 #endif
2092 if (partialstop)
2093 CopyBits (&leftrct, rectSym);
2094 else
2095 CopyBits (&rightrct, rectFillSym);
2096 }
2097 else if (stopin == 2) {
2098 #ifdef WIN_MAC
2099 LoadRect (&rightrct, (Int2)(pt2.x -7), (Int2)(pt2.y -3), pt2.x, (Int2)(pt2.y +4));
2100 OffsetRect (&rightrct, 0, 1);
2101 #endif
2102 #ifdef WIN_MSWIN
2103 LoadRect (&rightrct, (Int2)(pt2.x -7), (Int2)(pt2.y -3), pt2.x, (Int2)(pt2.y +4));
2104 #endif
2105 #ifdef WIN_MOTIF
2106 LoadRect (&rightrct, (Int2)(pt2.x -7), (Int2)(pt2.y -3), pt2.x, (Int2)(pt2.y +4));
2107 #endif
2108 if (partialstop)
2109 CopyBits (&rightrct,rightTriSym);
2110 else
2111 CopyBits (&rightrct,rightTriFillSym);
2112 }
2113 Black ();
2114 WidePen (1);
2115 }
2116
2117 /*********************************************************************
2118 *** draw_cds
2119 *********************************************************************/
draw_trans(EditAlignDataPtr adp,SelEdStructPtr cds,CharPtr trans,PoinT * pt,Int4 from,Int4 drw_width,Uint2 offset)2120 static void draw_trans (EditAlignDataPtr adp, SelEdStructPtr cds, CharPtr trans, PoinT *pt, Int4 from, Int4 drw_width, Uint2 offset)
2121 {
2122 SeqLocPtr slp;
2123 CharPtr transtr;
2124 CharPtr strPtr, transPtr;
2125 Int4 left, right;
2126 Int2 k;
2127
2128 if ( trans == NULL || cds == NULL ) return;
2129 slp = (SeqLocPtr) cds->region;
2130 if (slp == NULL) return;
2131 left = (Int4) MAX ((Int4) from, (Int4) SeqLocStart(slp));
2132 right = (Int4) MIN ((Int4) from+drw_width, (Int4) SeqLocStop(slp)+1);
2133 if (right < left) {
2134 ErrPostEx (SEV_ERROR, 0, 0, "fail in draw_trans: left %ld right %ld", (long) left, (long) right);
2135 }
2136 transtr = (CharPtr)MemNew ((size_t)(512 * (sizeof (Char))));
2137 emptystring (transtr, 512);
2138 transtr[0] = ' ';
2139 transtr[511] = '\0';
2140 strPtr = transtr;
2141 strPtr += (Int2) (left - from);
2142 transPtr = trans;
2143 transPtr += cds->offset; /*!!!!!!!!!!!!! += cds->codonstart ?? */
2144 if (SeqLocStart(slp) < from)
2145 transPtr += (Int2)(from - SeqLocStart(slp));
2146 if (adp->prot_mode == MPROTAA) {
2147 for (k =0; k < (right - left); k++, strPtr++, transPtr++) {
2148 if ( *transPtr=='M' || *transPtr=='*') *strPtr = *transPtr;
2149 }
2150 }
2151 else {
2152 for (k =0; k < (right - left); k++, strPtr++, transPtr++) {
2153 *strPtr = *transPtr;
2154 }
2155 }
2156 strPtr++;
2157 *strPtr= '\0';
2158 draw_seq (adp, cds, from, drw_width, *pt, transtr, FALSE, NULL, TRUE, OBJ_SEQFEAT, FALSE);
2159 transtr = (CharPtr)MemFree (transtr);
2160 return;
2161 }
2162
2163 /*********************************************************************
2164 *** draw_pept
2165 *********************************************************************/
draw_pept(EditAlignDataPtr adp,SelEdStructPtr cds,PoinT * pt,Int4 from,Int4 drw_width,Int2 line,Uint2 offset)2166 static void draw_pept (EditAlignDataPtr adp, SelEdStructPtr cds, PoinT *pt, Int4 from, Int4 drw_width, Int2 line, Uint2 offset)
2167 {
2168 ValNodePtr pept;
2169
2170 if (cds!=NULL) {
2171 pept = cds->data;
2172 if (pept != NULL) {
2173 if (pept->data.ptrvalue != NULL) {
2174 draw_trans (adp, cds, (CharPtr) pept->data.ptrvalue, pt, from, drw_width, offset);
2175 }
2176 }
2177 }
2178 }
2179
2180 /*********************************************************************
2181 *** draw_feat
2182 *********************************************************************/
draw_feat(EditAlignDataPtr adp,Uint2 eid,Uint2 iid,Uint2 it,Uint2 choice,Int4 start,Int4 stop,Uint1 strand,CharPtr label,PoinT * pt,Int4 from,Int4 drw_width,Int2 line,Int4 alignline,Uint4 color,Boolean partialstart,Boolean partialstop,BoolPtr gapline)2183 static void draw_feat (EditAlignDataPtr adp, Uint2 eid, Uint2 iid, Uint2 it, Uint2 choice, Int4 start, Int4 stop, Uint1 strand, CharPtr label, PoinT *pt, Int4 from, Int4 drw_width, Int2 line, Int4 alignline, Uint4 color, Boolean partialstart, Boolean partialstop, BoolPtr gapline)
2184 {
2185 Char str[128];
2186 Uint2 wideline;
2187 Boolean featselect;
2188
2189 if ( start > stop || start >= from + drw_width || stop < from )
2190 return;
2191 if (it == OBJ_VIRT)
2192 {
2193 wideline = 5;
2194 if (choice == SEQFEAT_CDREGION )
2195 sprintf (str, "CDS %d", (int) iid);
2196 else if (choice == SEQFEAT_GENE)
2197 sprintf (str, "gene %d", (int) iid);
2198 else if (choice == SEQFEAT_RNA)
2199 sprintf (str, "mRNA %d", (int) iid);
2200 str[15] = '\0';
2201 draw_id (adp, pt, -1, str, strand, 0, 3, FALSE, FALSE, -1);
2202 }
2203 else {
2204 wideline = 3;
2205 draw_id (adp, pt, -1, label, strand, 0, 3, FALSE, FALSE, -1);
2206 }
2207 featselect = (Boolean) (is_selectedbyID (eid, iid, it) != NULL);
2208 draw_line (adp, start, stop, strand, pt, from, drw_width, line, alignline, color, wideline, featselect, partialstart, partialstop, gapline);
2209 }
2210
what_inline(EditAlignDataPtr adp,Int4 line,Uint2 ei,Uint4 ii,Uint2 it,Uint2 ist,Uint2 al)2211 static void what_inline (EditAlignDataPtr adp, Int4 line, Uint2 ei, Uint4 ii, Uint2 it, Uint2 ist, Uint2 al)
2212 {
2213 adp->seqEntity_id [line] = ei;
2214 adp->item_id [line] = ii;
2215 adp->itemtype[line] = it;
2216 adp->itemsubtype[line] = ist;
2217 adp->alignline [line]= al;
2218 }
2219
id_is_invalid(EditAlignDataPtr adp,PoinT ptlh)2220 static Boolean id_is_invalid (EditAlignDataPtr adp, PoinT ptlh)
2221 {
2222 RecT rect;
2223 LoadRect(&rect, ptlh.x, ptlh.y,
2224 (Int2)(ptlh.x + adp->marginleft * adp->charw),
2225 (Int2)(ptlh.y + adp->lineheight));
2226 return RectInRgn (&rect, updateRgn);
2227 }
2228
row_is_invalid(EditAlignDataPtr adp,PoinT ptlh)2229 static Boolean row_is_invalid (EditAlignDataPtr adp, PoinT ptlh)
2230 {
2231 RecT rect;
2232 LoadRect (&rect, (Int2)(ptlh.x + adp->margin.left - adp->charw), ptlh.y,
2233 (Int2)(ptlh.x + adp->pnlWidth * adp->charw + 1),
2234 (Int2)(ptlh.y + adp->lineheight));
2235 return RectInRgn (&rect, updateRgn);
2236 }
2237
rang(Uint2 format,SelEdStructPtr ssp)2238 static Int2 rang (Uint2 format, SelEdStructPtr ssp)
2239 {
2240 if (format == OBJ_BIOSEQ)
2241 return ssp->entityID;
2242 if (format == OBJ_SEQALIGN)
2243 return ssp->itemID;
2244 return 0;
2245 }
2246
getparam(ValNodePtr vnprm,Uint2 eID,Uint2 iID,Uint1 choice)2247 static Int2 getparam (ValNodePtr vnprm, Uint2 eID, Uint2 iID, Uint1 choice)
2248 {
2249 ValNodePtr vnp;
2250 SeqParamPtr prm;
2251
2252 for (vnp = vnprm; vnp != NULL; vnp = vnp->next) {
2253 prm = (SeqParamPtr) vnp->data.ptrvalue;
2254 if (prm->entityID == eID && prm->itemID == iID)
2255 {
2256 if (choice == 1)
2257 return prm->group;
2258 }
2259 }
2260 return -1;
2261 }
2262
seqid_tolabel(SeqIdPtr sip,Uint1 choice)2263 static CharPtr seqid_tolabel (SeqIdPtr sip, Uint1 choice)
2264 {
2265 BioseqPtr bsp;
2266 SeqIdPtr tmp = NULL;
2267 Char str[120];
2268 CharPtr strp;
2269 Uint4 val;
2270
2271 str[0] = '\0';
2272 if (choice && choice <= PRINTID_GIcc)
2273 {
2274 bsp = BioseqLockById(sip);
2275 if (bsp!=NULL)
2276 {
2277 if (choice==PRINTID_GIcc)
2278 tmp = SeqIdFindBest (bsp->id, 0);
2279 else
2280 tmp = bsp->id;
2281 if (tmp)
2282 {
2283 SeqIdWrite (tmp, str, PRINTID_TEXTID_ACCESSION, 120);
2284 val=WHICH_db_accession(str);
2285 if (val==0)
2286 choice = PRINTID_FASTA_SHORT;
2287
2288 SeqIdWrite (tmp, str, choice, 120);
2289 BioseqUnlock(bsp);
2290 strp = StringSave (str);
2291 return strp;
2292 }
2293 BioseqUnlock(bsp);
2294 }
2295 }
2296 if (choice!=0 && sip) {
2297 SeqIdWrite (sip, str, choice, 120);
2298 strp = StringSave (str);
2299 return strp;
2300 }
2301 strp = StringSave (str);
2302 return strp;
2303 }
2304
2305 /*****************************************************************
2306 ***
2307 *** Draw Alignment in Panel p
2308 ***
2309 ******************************************************************/
2310 static Char strcmpl[] = "complement";
2311
on_draw(PaneL p)2312 extern void on_draw (PaneL p)
2313 {
2314 PoinT ptlh; /* PoinT at the top of lineheight */
2315 RecT rp; /* Panel Rect */
2316 EditAlignDataPtr adp;
2317 TextAlignBufPtr curtdp;
2318 SelStructPtr curvnp;
2319 SelEdStructPtr curssp = NULL;
2320 ValNodePtr vnp = NULL;
2321 SeqLocPtr curslp;
2322 SeqLocPtr sip;
2323 SeqAlignPtr salp;
2324
2325 Int4 from_inbuf; /* alignment coordinates in buffer */
2326 Int4 from_inseq; /* alignment coordinates in buffer */
2327 Int4 stringlens;
2328 Int4 start, stop;
2329 Int4 start2, stop2;
2330
2331 Int4 line; /* current line */
2332 Int4 curalgline;
2333 Int4 drw_width; /* length of drw_str */
2334 Int4 group;
2335 Int4 chklocp,
2336 chklocp2;
2337 Uint2 itemsubtype;
2338 Uint4 offset;
2339
2340 CharPtr stridp;
2341 CharPtr curstr = NULL;
2342 CharPtr masterbuf =NULL,
2343 masterstr =NULL;
2344 Int2 oldstyle;
2345
2346 Boolean invalid_id;
2347 Boolean invalid_row;
2348 Boolean is_master, draw_diff;
2349 Boolean first = TRUE;
2350 Boolean line_drawn;
2351 Boolean empty_line;
2352
2353 Int1 gapinline;
2354 BoolPtr gapline,
2355 gaplinep;
2356
2357 if ( (adp = GetAlignDataPanel (p)) == NULL )
2358 return;
2359 if ( adp->seqnumber == 0 )
2360 return;
2361
2362 salp = (SeqAlignPtr) adp->sap_align->data;
2363
2364 if ( adp->firstssp == NULL ) {
2365 adp->firstssp = get_firstline (NULL, adp->buffer);
2366 }
2367 if ( adp->firstssp == NULL )
2368 return;
2369 if ( adp->firstssp->region == NULL )
2370 return;
2371 from_inseq = adp->hoffset;
2372 from_inbuf = adp->hoffset - adp->bufferstart;
2373 drw_width = MIN ((Int4) adp->visibleWidth,
2374 (Int4) (adp->bufferlength - from_inbuf));
2375 if ( drw_width <= 0 || adp->bufferstart < 0 ) {
2376 return;
2377 }
2378
2379 oldstyle = GetMuskCurrentSt ();
2380 SetMuskCurrentSt (GetMuskStyleName (adp->styleNum));
2381
2382 line = (drw_width +2) * sizeof(Boolean);
2383 gapline = (BoolPtr) MemNew ((size_t)(line));
2384 MemSet ((Pointer)gapline, (int)(FALSE), (size_t)(line));
2385 gaplinep = NULL;
2386 gapinline = LINE_NOGAP;
2387 empty_line = FALSE;
2388
2389 curssp = (SelEdStructPtr) adp->firstssp->region;
2390 if (curssp->itemtype ==OBJ_SEQFEAT) {
2391 for (curvnp=adp->firstssp; curvnp!=NULL; curvnp=curvnp->prev) {
2392 curssp = (SelEdStructPtr) curvnp->region;
2393 if (curssp->itemtype==OBJ_BIOSEQ) /*&&curvnp->itemtype==FEATDEF_BAD)*/
2394 {
2395 if (curssp->data !=NULL) {
2396 vnp = (ValNodePtr) curssp->data;
2397 curtdp = (TextAlignBufPtr) vnp->data.ptrvalue;
2398 curstr = get_substring(curtdp->buf, from_inbuf, drw_width);
2399 if ( curstr != NULL )
2400 {
2401 gapinline=getgapsfromstring(curstr, 0, drw_width, &gapline);
2402 empty_line =(Boolean)(gapinline == LINE_ONLYGAP);
2403 if (gapinline == LINE_NOGAP)
2404 gaplinep = NULL;
2405 else
2406 gaplinep = gapline;
2407 }
2408 }
2409 break;
2410 }
2411 }
2412 }
2413 get_client_rect (p, &rp);
2414 SelectFont ((FonT)(adp->font));
2415 ptlh.x = rp.left;
2416 ptlh.y = rp.top;
2417 line = 0;
2418 curalgline = 0;
2419 adp->visibleLength = drw_width;
2420 masterbuf = get_master (adp->linebuff, adp->master.entityID,
2421 adp->master.itemID, adp->master.itemtype);
2422
2423 curvnp = adp->firstssp;
2424 while ( line < adp->pnlLine )
2425 {
2426
2427 curssp = (SelEdStructPtr) curvnp->region;
2428 if (curssp !=NULL) {
2429 adp->lastses = curssp;
2430 itemsubtype = curvnp->itemtype;
2431 invalid_row = row_is_invalid(adp, ptlh);
2432 invalid_id = id_is_invalid (adp, ptlh);
2433 if (itemsubtype == EDITDEF_SCA)
2434 {
2435 what_inline(adp, line, LINE0, LINE0, LINE0, LINE0, curalgline);
2436 if ( invalid_row ) {
2437 draw_scale (adp, from_inbuf, adp->visibleWidth, &ptlh);
2438 }
2439 line++;
2440 ptlh.y += adp->lineheight;
2441 }
2442 else if (itemsubtype == EDITDEF_SCB)
2443 {
2444 what_inline(adp, line, LINE0, LINE0, LINE0, LINE0, curalgline);
2445 if ( invalid_row ) {
2446 draw_bars (adp, from_inbuf, adp->visibleWidth, &ptlh);
2447 }
2448 line++;
2449 ptlh.y += adp->lineheight;
2450 }
2451 else if (itemsubtype>=EDITDEF_RF1 && itemsubtype<=EDITDEF_RF6)
2452 {
2453 if (curssp->data !=NULL && !empty_line) {
2454 curslp = (SeqLocPtr) curssp->region;
2455 vnp = (ValNodePtr) curssp->data;
2456 if ( SeqLocStop (curslp) > from_inseq && vnp != NULL)
2457 {
2458 what_inline (adp, line, curssp->entityID, curssp->itemID,
2459 curssp->itemtype, itemsubtype, curalgline);
2460 curstr = (CharPtr) vnp->data.ptrvalue;
2461 offset = (Uint2)(itemsubtype - EDITDEF_RF1) % (Uint2)3;
2462 if (itemsubtype>=EDITDEF_RF1 && itemsubtype<EDITDEF_RF4)
2463 draw_id (adp, &ptlh, rang(adp->input_format, curssp), NULL, Seq_strand_plus, 0, curssp->itemtype, FALSE, FALSE, -1);
2464 else
2465 draw_id (adp, &ptlh, rang(adp->input_format, curssp), NULL, Seq_strand_minus, 0, curssp->itemtype, FALSE, FALSE, -1);
2466
2467 if ( invalid_row )
2468 {
2469 draw_trans (adp, curssp, curstr, &ptlh, from_inseq, drw_width, offset);
2470 }
2471 }
2472 line++;
2473 ptlh.y += adp->lineheight;
2474 }
2475 }
2476 else if ( itemsubtype == FEATDEF_TRSL )
2477 {
2478 if (!empty_line) {
2479 first = TRUE;
2480 line_drawn = FALSE;
2481 while ( curssp != NULL && curssp->data != NULL)
2482 {
2483 curslp = (SeqLocPtr) curssp->region;
2484 sip = SeqLocId (curslp);
2485 start2 = SeqLocStart(curslp);
2486 chklocp =chkloc(sip, start2, adp->sqloc_list, &start2);
2487 start= SeqCoordToAlignCoord (start2, sip, salp, 0, chklocp);
2488 stop2 = SeqLocStop(curslp);
2489 chklocp =chkloc(sip, stop2, adp->sqloc_list, &stop2);
2490 stop = SeqCoordToAlignCoord (stop2, sip, salp, 0, chklocp);
2491 if (start < from_inseq + drw_width && stop >= from_inseq)
2492 {
2493 if ( invalid_row ) {
2494 draw_pept (adp, curssp, &ptlh, from_inseq, drw_width, line, 0);
2495 }
2496 if (first) {
2497 what_inline (adp, line, curssp->entityID, curssp->itemID, curssp->itemtype, itemsubtype, curalgline);
2498 line_drawn = TRUE;
2499 first = FALSE;
2500 }
2501 }
2502 curssp = FindNextSegment (curssp);
2503 }
2504 if (line_drawn) {
2505 line++;
2506 ptlh.y += adp->lineheight;
2507 }
2508 }
2509 }
2510 else if ( itemsubtype == EDITDEF_CPL )
2511 {
2512 if (curssp->data !=NULL && !empty_line)
2513 {
2514 vnp = (ValNodePtr) curssp->data;
2515 curtdp = (TextAlignBufPtr) vnp->data.ptrvalue;
2516 curstr = get_substring (curtdp->buf, from_inbuf, drw_width);
2517 if ( curstr != NULL ) /* !!!!!!! */
2518 {
2519 what_inline (adp, line, curssp->entityID, curssp->itemID,
2520 curssp->itemtype, itemsubtype, curalgline);
2521 if ( invalid_id && (( !adp->displaytype
2522 && curssp->itemtype != OBJ_BIOSEQ) || adp->displaytype))
2523 draw_id (adp, &ptlh, -1, strcmpl, 255, 0, curssp->itemtype, FALSE, FALSE, -1);
2524 if ( invalid_row && (( !adp->displaytype
2525 && curssp->itemtype != OBJ_BIOSEQ) || adp->displaytype) )
2526 {
2527 draw_seq (adp, curssp, from_inseq, drw_width, ptlh, curstr, draw_diff, masterstr, TRUE, itemsubtype, FALSE);
2528 }
2529 line++;
2530 ptlh.y += adp->lineheight;
2531 }
2532 }
2533 }
2534 else if (curssp->itemtype == OBJ_BIOSEQ)
2535 {
2536 if (curssp->data !=NULL) {
2537 vnp = (ValNodePtr) curssp->data;
2538 curtdp = (TextAlignBufPtr) vnp->data.ptrvalue;
2539 curstr = get_substring(curtdp->buf, from_inbuf, drw_width);
2540 if ( curstr != NULL )
2541 {
2542 gapinline=getgapsfromstring(curstr, 0, drw_width, &gapline);
2543 empty_line =(Boolean)(gapinline == LINE_ONLYGAP);
2544 if (gapinline == LINE_NOGAP)
2545 gaplinep = NULL;
2546 else
2547 gaplinep = gapline;
2548 if (adp->draw_emptyline || (!adp->draw_emptyline && !empty_line)) {
2549 what_inline (adp, line, curssp->entityID, curssp->itemID,
2550 curssp->itemtype, itemsubtype, curalgline);
2551 is_master = is_samess_ses (&(adp->master), curssp);
2552 draw_diff=!(!adp->charmode || (adp->charmode && is_master));
2553 masterstr = NULL;
2554 if ( draw_diff ) {
2555 stringlens = StringLen (masterbuf);
2556 if ( from_inbuf < stringlens )
2557 masterstr = masterbuf + from_inbuf;
2558 }
2559 if ( invalid_id ) {
2560 if (adp->displaytype)
2561 {
2562 if (adp->marginwithgroup)
2563 group=getparam(adp->params,curssp->entityID, curssp->itemID, 1);
2564 else group = -1;
2565 sip = SeqLocId((SeqLocPtr) curssp->region);
2566 start=AlignCoordToSeqCoord(from_inseq, sip,salp, adp->sqloc_list, 0) +1;
2567 stridp = seqid_tolabel (sip, adp->printid);
2568 /* seqid_to_label calls BioseqLockById, which will
2569 * refresh the Desktop if it is open and will change
2570 * the font setting - need to put the font back.
2571 */
2572 SelectFont ((FonT)(adp->font));
2573 draw_id (adp, &ptlh, rang(adp->input_format, curssp), stridp, curtdp->strand, start, curssp->itemtype, FALSE, is_master, group);
2574 }
2575 }
2576 if ( invalid_row && adp->displaytype )
2577 {
2578 draw_seq (adp, curssp, from_inseq, drw_width, ptlh, curstr, draw_diff, masterstr, FALSE, curssp->itemtype, TRUE);
2579 draw_caret (adp, curssp, ptlh, line);
2580 }
2581 line++;
2582 ptlh.y += adp->lineheight;
2583 }
2584 }
2585 }
2586 }
2587 else if (curssp->itemtype==OBJ_SEQFEAT && itemsubtype==FEATDEF_PROT)
2588 {
2589 if (curssp->data !=NULL && !empty_line)
2590 {
2591 vnp = (ValNodePtr) curssp->data;
2592 curtdp = (TextAlignBufPtr) vnp->data.ptrvalue;
2593 curstr = get_substring(curtdp->buf, from_inbuf, drw_width);
2594 if ( curstr != NULL )
2595 {
2596 what_inline (adp, line, curssp->entityID, curssp->itemID, curssp->itemtype, itemsubtype, curalgline);
2597 draw_id (adp, &ptlh, -1, curtdp->label, curtdp->strand, 0, curssp->itemtype, FALSE, FALSE, -1);
2598 if ( invalid_row ) {
2599 draw_seq (adp, curssp, from_inseq, drw_width, ptlh, curstr, draw_diff, masterstr, FALSE, curssp->itemtype, FALSE);
2600 }
2601 line++;
2602 ptlh.y += adp->lineheight;
2603 }
2604 }
2605 }
2606 else if ( curssp->itemtype ==OBJ_SEQFEAT )
2607 {
2608 if (!empty_line) {
2609 first = TRUE;
2610 line_drawn = FALSE;
2611 while (curssp!=NULL)
2612 {
2613 curslp = (SeqLocPtr) curssp->region;
2614 sip = SeqLocId (curslp);
2615 start2 = SeqLocStart(curslp);
2616 chklocp = chkloc(sip, start2, adp->sqloc_list, &start2);
2617 start= SeqCoordToAlignCoord (start2, sip, salp, 0, chklocp);
2618 stop2 = SeqLocStop(curslp);
2619 chklocp2 = chkloc(sip, stop2, adp->sqloc_list, &stop2);
2620 stop = SeqCoordToAlignCoord (stop2, sip, salp, 0, chklocp2);
2621 if (start <= stop && start < from_inseq + drw_width && stop >= from_inseq)
2622 {
2623 if ( invalid_row )
2624 {
2625 draw_feat (adp, curssp->entityID, curssp->itemID, curssp->itemtype, itemsubtype, start, stop, SeqLocStrand(curslp), curssp->label, &ptlh, from_inseq, drw_width, line, curalgline, (Uint4) getcolor_fromstyles(itemsubtype), (Boolean)(chklocp==-1), (Boolean)(chklocp2==APPEND_RESIDUE), gaplinep);
2626 }
2627 if (first) {
2628 what_inline(adp, line, curssp->entityID, curssp->itemID,
2629 curssp->itemtype, itemsubtype, curalgline);
2630 line_drawn = TRUE;
2631 first = FALSE;
2632 }
2633 }
2634 curssp = FindNextSegment (curssp);
2635 }
2636 if (line_drawn) {
2637 line++;
2638 ptlh.y += adp->lineheight;
2639 }
2640 }
2641 }
2642 else if( itemsubtype==SEQFEAT_GENE || itemsubtype==SEQFEAT_RNA
2643 || itemsubtype==SEQFEAT_CDREGION)
2644 {
2645 if (!empty_line) {
2646 first = TRUE;
2647 line_drawn = FALSE;
2648 while (curssp!=NULL)
2649 {
2650 curslp = (SeqLocPtr) curssp->region;
2651 sip = SeqLocId (curslp);
2652 start2 = SeqLocStart(curslp);
2653 chklocp =chkloc(sip, start2, adp->sqloc_list, &start2);
2654 start= SeqCoordToAlignCoord (start2, sip, salp, 0, chklocp);
2655 stop2 = SeqLocStop(curslp);
2656 chklocp2 =chkloc(sip, stop2, adp->sqloc_list, &stop2);
2657 stop = SeqCoordToAlignCoord (stop2, sip, salp, 0, chklocp);
2658 if (start <= from_inseq + drw_width && stop >= from_inseq)
2659 {
2660 if ( invalid_row )
2661 {
2662 draw_feat (adp, curssp->entityID, curssp->itemID, curssp->itemtype, itemsubtype, start, stop, SeqLocStrand(curslp), curssp->label, &ptlh, from_inseq, drw_width, line, curalgline, (Uint4) getcolorforvirtfeat(curssp->itemID), (Boolean)(chklocp==-1), (Boolean)(chklocp2==APPEND_RESIDUE), gaplinep);
2663 }
2664 if (first) {
2665 what_inline (adp, line, curssp->entityID, curssp->itemID,
2666 curssp->itemtype, itemsubtype, curalgline);
2667 line_drawn = TRUE;
2668 first = FALSE;
2669 }
2670 }
2671 curssp = FindNextSegment (curssp);
2672 }
2673 if (line_drawn) {
2674 line++;
2675 ptlh.y += adp->lineheight;
2676 }
2677 }
2678 }
2679 else {
2680 /**
2681 ErrPostEx (SEV_ERROR, 0, 0, "fail in on_draw [46] subtype %ld type %ld", (long) itemsubtype, (long) curssp->itemtype);
2682 **/
2683 return;
2684 }
2685 if (line == adp->pnlLine)
2686 break;
2687 curvnp = curvnp->next;
2688 if (curvnp == NULL)
2689 {
2690 if (adp->rowpcell > 0
2691 && ((Int4)(curalgline+1) % (Int4)adp->rowpcell) == 0)
2692 {
2693 what_inline(adp,line,LINE0,LINE0, LINE0, LINE0, curalgline);
2694 ptlh.y += adp->lineheight;
2695 line++;
2696 }
2697 curvnp = adp->buffer;
2698 curalgline++;
2699 /*****************
2700 *******************/
2701 if (curalgline>500)
2702 break;
2703 /*****************
2704 *******************/
2705
2706 from_inbuf += drw_width;
2707 from_inseq += drw_width;
2708 if (from_inseq >= adp->length)
2709 break;
2710 drw_width = MIN ((Int4) adp->visibleWidth, (Int4)(adp->bufferlength
2711 - (adp->hoffset -adp->bufferstart) - adp->visibleLength));
2712 adp->visibleLength += drw_width;
2713 }
2714 }
2715 }
2716 MemFree (gapline);
2717 SetMuskCurrentSt (GetMuskStyleName (oldstyle));
2718 return;
2719 }
2720
2721 /* This section of code is used for feature propagation */
2722 typedef struct fprdata {
2723 FORM_MESSAGE_BLOCK
2724 BioseqPtr bsp;
2725 SeqAlignPtr salp;
2726 Int4 aln_length;
2727 Int4 log10_aln_length;
2728 VieweR details;
2729 SegmenT dtpict;
2730 Int4 scaleX;
2731 GrouP allOrSel;
2732 GrouP gapSplit;
2733 DialoG sequence_list_dlg;
2734 ButtoN stopCDS;
2735 ButtoN transPast;
2736 ButtoN fixCDS;
2737 ButtoN fuseJoints;
2738 ButtoN accept;
2739 ButtoN leave_dlg_up;
2740 } FprData, PNTR FprDataPtr;
2741
2742 typedef struct ivalinfo {
2743 Int4 start1;
2744 Int4 stop1;
2745 Int4 start2;
2746 Int4 stop2;
2747 struct ivalinfo PNTR next;
2748 } IvalInfo, PNTR IvalInfoPtr;
2749
IvalInfoFree(IvalInfoPtr ival)2750 static IvalInfoPtr IvalInfoFree (
2751 IvalInfoPtr ival
2752 )
2753
2754 {
2755 IvalInfoPtr next;
2756
2757 while (ival != NULL) {
2758 next = ival->next;
2759 MemFree (ival);
2760 ival = next;
2761 }
2762 return NULL;
2763 }
2764
GetAlignmentIntervals(SeqAlignPtr sap,Int4 row1,Int4 row2,Int4 from,Int4 to)2765 static IvalInfoPtr GetAlignmentIntervals (SeqAlignPtr sap, Int4 row1, Int4 row2, Int4 from, Int4 to)
2766 {
2767 AlnMsg2Ptr amp1;
2768 AlnMsg2Ptr amp2;
2769 IvalInfoPtr ival;
2770 IvalInfoPtr ival_head = NULL;
2771 IvalInfoPtr ival_prev = NULL;
2772 Int4 from_aln;
2773 Int4 start;
2774 Int4 stop;
2775 Int4 tmp;
2776 Int4 to_aln;
2777 Int4 seg_i, seg_n, seg_start, seg_stop;
2778
2779 if (sap == NULL || sap->saip == NULL)
2780 return NULL;
2781 AlnMgr2GetNthSeqRangeInSA(sap, row1, &start, &stop);
2782 if (from < start)
2783 from = start;
2784 if (to > stop)
2785 to = stop;
2786 from_aln = AlnMgr2MapBioseqToSeqAlign(sap, from, row1);
2787 to_aln = AlnMgr2MapBioseqToSeqAlign(sap, to, row1);
2788 if (from_aln > to_aln)
2789 {
2790 tmp = from_aln;
2791 from_aln = to_aln;
2792 to_aln = tmp;
2793 }
2794 seg_n = AlnMgr2GetNumSegs(sap);
2795 for (seg_i=1; seg_i<=seg_n; seg_i++) {
2796 AlnMgr2GetNthSegmentRange(sap, seg_i, &seg_start, &seg_stop);
2797 if (seg_start > to_aln) continue;
2798 if (seg_stop < from_aln) continue;
2799 if (seg_start < from_aln) seg_start = from_aln;
2800 if (seg_stop > to_aln) seg_stop = to_aln;
2801
2802 amp1 = AlnMsgNew2();
2803 amp1->from_aln = seg_start;
2804 amp1->to_aln = seg_stop;
2805 amp1->row_num = row1;
2806 amp2 = AlnMsgNew2();
2807 amp2->from_aln = seg_start;
2808 amp2->to_aln = seg_stop;
2809 amp2->row_num = row2;
2810 AlnMgr2GetNextAlnBit(sap, amp1);
2811 AlnMgr2GetNextAlnBit(sap, amp2);
2812 if (amp1->type == AM_SEQ && amp2->type == AM_SEQ) {
2813 ival = (IvalInfoPtr)MemNew(sizeof(IvalInfo));
2814 ival->start1 = amp1->from_row;
2815 ival->stop1 = amp1->to_row;
2816 ival->start2 = amp2->from_row;
2817 ival->stop2 = amp2->to_row;
2818 if (ival_head == NULL)
2819 ival_head = ival_prev = ival;
2820 else {
2821 ival_prev->next = ival;
2822 ival_prev = ival;
2823 }
2824 }
2825 AlnMsgFree2(amp1);
2826 AlnMsgFree2(amp2);
2827 }
2828 return ival_head;
2829 }
2830
MergeAdjacentIntervals(IvalInfoPtr list)2831 static IvalInfoPtr MergeAdjacentIntervals (
2832 IvalInfoPtr list
2833 )
2834
2835 {
2836 IvalInfoPtr curr, last, next;
2837
2838 if (list != NULL) {
2839 curr = list->next;
2840 last = list;
2841 while (curr != NULL) {
2842 next = curr->next;
2843 if (curr->start2 == last->stop2 + 1) {
2844 last->stop2 = MAX (curr->stop2, last->stop2);
2845 MemFree (curr);
2846 last->next = next;
2847 } else {
2848 last = curr;
2849 }
2850 curr = next;
2851 }
2852 }
2853 return list;
2854 }
2855
MergeAdjacentSeqLocIntervals(SeqLocPtr location)2856 static SeqLocPtr MergeAdjacentSeqLocIntervals (SeqLocPtr location)
2857
2858 {
2859 SeqLocPtr head = NULL;
2860 SeqIntPtr sinp, last_sinp;
2861 SeqLocPtr slp;
2862 SeqPntPtr spp, last_spp;
2863 SeqLocPtr last_slp = NULL;
2864 Int4 last_from = -1, last_to = -1;
2865 Uint1 last_strand = 0;
2866 SeqIdPtr last_id = NULL;
2867
2868 head = NULL;
2869 slp = SeqLocFindNext (location, NULL);
2870 while (slp != NULL) {
2871 switch (slp->choice) {
2872 case SEQLOC_INT :
2873 sinp = (SeqIntPtr) slp->data.ptrvalue;
2874 if (sinp != NULL) {
2875 if (last_slp != NULL && last_strand == sinp->strand && last_id != NULL
2876 && SeqIdComp (sinp->id, last_id) == SIC_YES
2877 && ((last_from <= sinp->from + 1 && last_to >= sinp->from - 1)
2878 || (last_from <= sinp->to + 1 && last_to >= sinp->to - 1)
2879 || (last_from >= sinp->from - 1 && last_to <= sinp->to + 1)
2880 || (last_from <= sinp->from + 1 && last_to >= sinp->to - 1)))
2881 {
2882 /* intervals are adjacent, so expand previous interval */
2883 if (last_slp->choice == SEQLOC_INT) {
2884 last_sinp = last_slp->data.ptrvalue;
2885 if (last_sinp != NULL) {
2886 last_from = MIN (sinp->from, last_sinp->from);
2887 last_sinp->from = last_from;
2888 last_to = MAX (sinp->to, last_sinp->to);
2889 last_sinp->to = last_to;
2890 }
2891 } else if (last_slp->choice == SEQLOC_PNT) {
2892 /* change previous entry from point to interval that includes point */
2893 spp = (SeqPntPtr)last_slp->data.ptrvalue;
2894 if (spp != NULL) {
2895 last_sinp = SeqIntNew ();
2896 last_from = MIN (spp->point, sinp->from);
2897 last_sinp->from = last_from;
2898 last_to = MAX (sinp->to, spp->point);
2899 last_sinp->to = last_to;
2900 last_sinp->strand = sinp->strand;
2901 last_sinp->id = SeqIdDup (sinp->id);
2902 last_slp->choice = SEQLOC_INT;
2903 last_slp->data.ptrvalue = last_sinp;
2904 SeqPntFree (spp);
2905 }
2906 }
2907 } else {
2908 /* add new interval */
2909 last_sinp = SeqIntNew ();
2910 last_sinp->from = sinp->from;
2911 last_from = sinp->from;
2912 last_sinp->to = sinp->to;
2913 last_to = sinp->to;
2914 last_sinp->strand = sinp->strand;
2915 last_strand = sinp->strand;
2916 last_sinp->id = SeqIdDup (sinp->id);
2917 last_id = last_sinp->id;
2918 last_slp = ValNodeAddPointer (&head, SEQLOC_INT, (Pointer) last_sinp);
2919 }
2920 }
2921 break;
2922 case SEQLOC_PNT:
2923 spp = (SeqPntPtr)slp->data.ptrvalue;
2924 if (spp != NULL) {
2925 if (last_slp != NULL && last_strand == spp->strand && last_id != NULL
2926 && SeqIdComp (spp->id, last_id) == SIC_YES
2927 && last_to >= spp->point - 1)
2928 {
2929 /* intervals are adjacent, so expand previous interval */
2930 if (last_slp->choice == SEQLOC_INT) {
2931 last_sinp = last_slp->data.ptrvalue;
2932 if (last_sinp != NULL) {
2933 last_to = MAX (spp->point, last_sinp->to);
2934 last_sinp->to = last_to;
2935 last_from = MIN (spp->point, last_sinp->from);
2936 last_sinp->from = last_from;
2937 }
2938 } else if (last_slp->choice == SEQLOC_PNT) {
2939 /* change previous entry from point to interval that includes point */
2940 last_spp = (SeqPntPtr)last_slp->data.ptrvalue;
2941 if (last_spp != NULL) {
2942 last_sinp = SeqIntNew ();
2943 last_from = MIN (spp->point, last_spp->point);
2944 last_sinp->from = last_from;
2945 last_to = MAX (last_spp->point, spp->point);
2946 last_sinp->to = last_to;
2947 last_sinp->strand = spp->strand;
2948 last_sinp->id = SeqIdDup (spp->id);
2949 last_slp->choice = SEQLOC_INT;
2950 last_slp->data.ptrvalue = last_sinp;
2951 SeqPntFree (spp);
2952 }
2953 }
2954 } else {
2955 /* add new point */
2956 last_spp = SeqPntNew ();
2957 last_spp->point = spp->point;
2958 last_to = spp->point;
2959 last_from = spp->point;
2960 last_spp->strand = spp->strand;
2961 last_strand = spp->strand;
2962 last_spp->id = SeqIdDup (spp->id);
2963 last_slp = ValNodeAddPointer (&head, SEQLOC_PNT, (Pointer) last_spp);
2964 }
2965 }
2966 break;
2967 default:
2968 break;
2969 }
2970 slp = SeqLocFindNext (location, slp);
2971 }
2972
2973 if (head == NULL) return NULL;
2974 if (head->next == NULL) return head;
2975
2976 slp = ValNodeNew (NULL);
2977 slp->choice = SEQLOC_MIX;
2978 slp->data.ptrvalue = (Pointer) head;
2979 slp->next = NULL;
2980
2981 return slp;
2982 }
2983
2984 /* We need to be able to propagate features with locations on multiple segments
2985 * whose IDs may be found in separate alignments.
2986 * To do this, we will take the location of the master feature and for each sublocation,
2987 * we will find the sequence ID of the sublocation. We will find the alignment that
2988 * contains the master feature sublocation sequence ID and construct a propagated
2989 * sublocation for each sequence in the same alignment as the master feature sublocation
2990 * sequence ID and add this to a list.
2991 * Once we have created all of the propagated sublocations, we will reconstitute the
2992 * total locations for the propagated features by associating each propagated sublocation
2993 * with other propagated sublocations with the same sequence ID or having a sequence ID
2994 * that belongs to the same segmented set.
2995 * We can then use the list of total locations to construct the propagated features.
2996 */
2997
MapSubLoc(SeqLocPtr master_subloc,SeqAlignPtr salp,Int4 master_row,Int4 prop_row,Boolean gapSplit)2998 static SeqLocPtr MapSubLoc
2999 (SeqLocPtr master_subloc,
3000 SeqAlignPtr salp,
3001 Int4 master_row,
3002 Int4 prop_row,
3003 Boolean gapSplit)
3004 {
3005 SeqLocPtr prop_loc = NULL;
3006 SeqIdPtr prop_sip;
3007 SeqIntPtr sinp;
3008 IvalInfoPtr ival_head, ival;
3009 SeqPntPtr spp;
3010 Uint1 strand;
3011 BioseqPtr prop_bsp;
3012
3013 if (master_subloc == NULL || salp == NULL || master_row < 1 || prop_row < 1)
3014 {
3015 return NULL;
3016 }
3017
3018 prop_sip = AlnMgr2GetNthSeqIdPtr (salp, prop_row);
3019 if (prop_sip == NULL) return NULL;
3020 prop_bsp = BioseqFind (prop_sip);
3021 if (prop_bsp != NULL)
3022 {
3023 prop_sip = SeqIdFindBest (prop_bsp->id, SEQID_GENBANK);
3024 prop_sip = SeqIdDup (prop_sip);
3025 }
3026
3027 switch (master_subloc->choice) {
3028 case SEQLOC_INT :
3029 sinp = (SeqIntPtr) master_subloc->data.ptrvalue;
3030 if (sinp != NULL) {
3031 strand = sinp->strand;
3032 ival_head = GetAlignmentIntervals (salp, master_row, prop_row, sinp->from, sinp->to);
3033 ival_head = MergeAdjacentIntervals (ival_head);
3034 if (ival_head != NULL) {
3035
3036 /* what if one or the other interval maps into a gap? */
3037
3038 if (gapSplit) {
3039 for (ival = ival_head; ival != NULL; ival = ival->next) {
3040 sinp = SeqIntNew ();
3041 sinp->from = ival->start2;
3042 sinp->to = ival->stop2;
3043 sinp->strand = strand;
3044 sinp->id = SeqIdDup (prop_sip);
3045 ValNodeAddPointer (&prop_loc, SEQLOC_INT, (Pointer) sinp);
3046 }
3047 prop_sip = SeqIdFree (prop_sip);
3048 } else {
3049 sinp = SeqIntNew ();
3050 sinp->from = ival_head->start2;
3051 for (ival = ival_head; ival->next != NULL; ival = ival->next) continue;
3052 sinp->to = ival->stop2;
3053 sinp->strand = strand;
3054 sinp->id = prop_sip;
3055 prop_sip = NULL;
3056 ValNodeAddPointer (&prop_loc, SEQLOC_INT, (Pointer) sinp);
3057 }
3058
3059 }
3060 IvalInfoFree (ival_head);
3061 }
3062 break;
3063 case SEQLOC_PNT :
3064 spp = (SeqPntPtr) master_subloc->data.ptrvalue;
3065 if (spp != NULL) {
3066 strand = spp->strand;
3067 ival_head = GetAlignmentIntervals (salp, master_row, prop_row, spp->point, spp->point);
3068 if (ival_head != NULL) {
3069
3070 spp = SeqPntNew ();
3071 spp->point = ival_head->start2;
3072 spp->strand = strand;
3073 spp->id = prop_sip;
3074 prop_sip = NULL;
3075 ValNodeAddPointer (&prop_loc, SEQLOC_PNT, (Pointer) spp);
3076
3077 }
3078 IvalInfoFree (ival_head);
3079 }
3080 break;
3081 case SEQLOC_PACKED_PNT :
3082 /* not yet implemented */
3083 break;
3084 default :
3085 break;
3086 }
3087 prop_sip = SeqIdFree (prop_sip);
3088
3089 return prop_loc;
3090 }
3091
3092 typedef struct loclist
3093 {
3094 SeqIdPtr sip_list;
3095 SeqLocPtr slp;
3096 } LocListData, PNTR LocListPtr;
3097
FindLocListForSeqId(ValNodePtr loc_list,SeqIdPtr sip)3098 static LocListPtr FindLocListForSeqId (ValNodePtr loc_list, SeqIdPtr sip)
3099 {
3100 SeqIdPtr search_sip, find_sip;
3101 LocListPtr llp;
3102 ValNodePtr vnp;
3103
3104 for (vnp = loc_list; vnp != NULL; vnp = vnp->next)
3105 {
3106 llp = (LocListPtr) vnp->data.ptrvalue;
3107 if (llp != NULL && llp->slp != NULL)
3108 {
3109 for (search_sip = llp->sip_list; search_sip != NULL; search_sip = search_sip->next)
3110 {
3111 for (find_sip = sip; find_sip != NULL; find_sip = find_sip->next)
3112 {
3113 if (SeqIdComp (find_sip, search_sip) == SIC_YES)
3114 {
3115 return llp;
3116 }
3117 }
3118 }
3119 }
3120 }
3121 return NULL;
3122 }
3123
3124 /* Compare the Sequence ID of this location with the sequence IDs of other locations in the
3125 * list. If the sequence ID matches that of another loclist, add to that loclist,
3126 * otherwise add a new loclist entry with the sequence ID of this sequence and the sequence IDs
3127 * of other sequences in the same segset if the segset flag is set.
3128 */
AssociatePropagatedSubloc(ValNodePtr subloc_list,SeqLocPtr prop_loc,Boolean segset)3129 static ValNodePtr AssociatePropagatedSubloc (ValNodePtr subloc_list, SeqLocPtr prop_loc, Boolean segset)
3130 {
3131 ValNodePtr vnp;
3132 LocListPtr llp = NULL;
3133 SeqIdPtr prop_sip;
3134 BioseqPtr prop_bsp;
3135 BioseqSetPtr parent_set;
3136 SeqEntryPtr sep;
3137
3138 if (prop_loc == NULL) return subloc_list;
3139 prop_sip = SeqLocId (prop_loc);
3140 if (prop_sip == NULL)
3141 {
3142 SeqLocFree (prop_loc);
3143 return subloc_list;
3144 }
3145
3146 llp = FindLocListForSeqId (subloc_list, prop_sip);
3147 if (llp != NULL)
3148 {
3149 ValNodeAddPointer (&(llp->slp), prop_loc->choice, prop_loc->data.ptrvalue);
3150 prop_loc = ValNodeFree (prop_loc);
3151 }
3152 else
3153 {
3154 llp = (LocListPtr) MemNew (sizeof (LocListData));
3155 if (llp != NULL)
3156 {
3157 llp->sip_list = SeqIdDup (prop_sip);
3158 llp->slp = prop_loc;
3159 if (segset)
3160 {
3161 prop_bsp = BioseqFind (prop_sip);
3162 if (prop_bsp != NULL && prop_bsp->idx.parenttype == OBJ_BIOSEQSET)
3163 {
3164 parent_set = prop_bsp->idx.parentptr;
3165 if (parent_set != NULL && parent_set->_class == BioseqseqSet_class_parts)
3166 {
3167 /* add other IDs from set to list */
3168 for (sep = parent_set->seq_set; sep != NULL; sep = sep->next)
3169 {
3170 if (IS_Bioseq (sep))
3171 {
3172 prop_bsp = (BioseqPtr) sep->data.ptrvalue;
3173 prop_sip = SeqIdDup (prop_bsp->id);
3174 ValNodeAddPointer (&(llp->sip_list), prop_sip->choice, prop_sip->data.ptrvalue);
3175 prop_sip = ValNodeFree (prop_sip);
3176 }
3177 }
3178 }
3179 }
3180 }
3181 vnp = ValNodeAddPointer (&subloc_list, 0, llp);
3182 }
3183 }
3184 return subloc_list;
3185 }
3186
FreeLocList(ValNodePtr loc_list)3187 static ValNodePtr FreeLocList (ValNodePtr loc_list)
3188 {
3189 LocListPtr llp;
3190
3191 if (loc_list == NULL) return NULL;
3192 loc_list->next = FreeLocList (loc_list->next);
3193 llp = loc_list->data.ptrvalue;
3194 if (llp != NULL)
3195 {
3196 SeqIdFree (llp->sip_list);
3197 SeqLocFree (llp->slp);
3198 MemFree (llp);
3199 }
3200 ValNodeFree (loc_list);
3201 return NULL;
3202 }
3203
GetMasterRow(SeqAlignPtr salp,SeqIdPtr sip)3204 static Int4 GetMasterRow (SeqAlignPtr salp, SeqIdPtr sip)
3205 {
3206 Int4 master_row = -1;
3207 SeqIdPtr sip_next;
3208
3209 if (salp == NULL || sip == NULL)
3210 {
3211 return -1;
3212 }
3213
3214 while (sip != NULL && master_row == -1)
3215 {
3216 sip_next = sip->next;
3217 sip->next = NULL;
3218 master_row = AlnMgr2GetFirstNForSip (salp, sip);
3219 sip->next = sip_next;
3220 sip = sip_next;
3221 }
3222 return master_row;
3223 }
3224
3225 static Boolean
NthAlignmentSequenceInSeqPropList(SeqAlignPtr salp,Int4 n,ValNodePtr seq_for_prop)3226 NthAlignmentSequenceInSeqPropList
3227 (SeqAlignPtr salp,
3228 Int4 n,
3229 ValNodePtr seq_for_prop)
3230 {
3231 SeqIdPtr sip;
3232 ValNodePtr seq_vnp;
3233 BioseqPtr bsp;
3234 SeqEntryPtr sep;
3235 BioseqSetPtr bssp;
3236
3237 if (salp == NULL || seq_for_prop == NULL)
3238 {
3239 return FALSE;
3240 }
3241
3242 sip = AlnMgr2GetNthSeqIdPtr(salp, n);
3243 for (seq_vnp = seq_for_prop; seq_vnp != NULL; seq_vnp = seq_vnp->next)
3244 {
3245 if (SeqIdIn (sip, (SeqIdPtr) seq_vnp->data.ptrvalue))
3246 {
3247 return TRUE;
3248 }
3249 /* check for segments */
3250 bsp = BioseqFind (seq_vnp->data.ptrvalue);
3251 if (bsp != NULL && bsp->repr == Seq_repr_seg)
3252 {
3253 sep = SeqMgrGetSeqEntryForData (bsp);
3254 sep = sep->next; /* parts should be next */
3255 if (sep != NULL && IS_Bioseq_set (sep))
3256 {
3257 bssp = (BioseqSetPtr) sep->data.ptrvalue;
3258 if (bssp != NULL && bssp->_class == BioseqseqSet_class_parts)
3259 {
3260 for (sep = bssp->seq_set; sep != NULL; sep = sep->next)
3261 {
3262 if (IS_Bioseq (sep))
3263 {
3264 bsp = (BioseqPtr) sep->data.ptrvalue;
3265 if (bsp != NULL && SeqIdIn (sip, bsp->id))
3266 {
3267 return TRUE;
3268 }
3269 }
3270 }
3271 }
3272 }
3273 }
3274 }
3275
3276
3277 return FALSE;
3278 }
3279
AddNullLocToLists(ValNodePtr loc_list)3280 static void AddNullLocToLists (ValNodePtr loc_list)
3281 {
3282 ValNodePtr vnp;
3283 LocListPtr llp;
3284
3285 for (vnp = loc_list; vnp != NULL; vnp = vnp->next)
3286 {
3287 llp = (LocListPtr) vnp->data.ptrvalue;
3288 if (llp != NULL)
3289 {
3290 ValNodeAddPointer (&(llp->slp), SEQLOC_NULL, NULL);
3291 }
3292 }
3293 }
3294
3295
GetPropagatedSublocations(SeqLocPtr master_location,Boolean gap_split,ValNodePtr prop_loc_list,ValNodePtr seq_for_prop,BoolPtr warned_about_master)3296 static ValNodePtr GetPropagatedSublocations
3297 (SeqLocPtr master_location,
3298 Boolean gap_split,
3299 ValNodePtr prop_loc_list,
3300 ValNodePtr seq_for_prop,
3301 BoolPtr warned_about_master)
3302 {
3303 SeqLocPtr master_subloc;
3304 SeqIdPtr master_subloc_id;
3305 BioseqPtr master_subloc_bsp;
3306 SeqLocPtr tmp_loc;
3307 SeqAlignPtr salp;
3308 Int4 master_row, num_rows, prop_row;
3309 SeqLocPtr prop_loc;
3310
3311 if (master_location == NULL) return prop_loc_list;
3312
3313 master_subloc = SeqLocFindNext (master_location, NULL);
3314 while (master_subloc != NULL)
3315 {
3316 if (master_subloc->choice == SEQLOC_NULL) {
3317 /* don't need to propagate, just add nulls to each item in list */
3318 AddNullLocToLists (prop_loc_list);
3319 } else {
3320 master_subloc_id = SeqLocId (master_subloc);
3321 master_subloc_bsp = BioseqFind (master_subloc_id);
3322 master_subloc_id = master_subloc_bsp->id;
3323 if (master_subloc_bsp != NULL)
3324 {
3325 if (master_subloc_bsp->repr == Seq_repr_seg)
3326 {
3327 if (warned_about_master != NULL && ! *warned_about_master)
3328 {
3329 Message (MSG_OK, "Warning - you are propagating a feature that "
3330 "contains locations on the master sequence. These locations"
3331 " will be mapped to the segments in the propagated features.");
3332 *warned_about_master = TRUE;
3333 }
3334 /* this is a location on the master segment */
3335 tmp_loc = SegLocToParts (master_subloc_bsp, master_subloc);
3336 prop_loc_list = GetPropagatedSublocations (tmp_loc, gap_split, prop_loc_list,
3337 seq_for_prop, warned_about_master);
3338 tmp_loc = SeqLocFree (tmp_loc);
3339 }
3340 else
3341 {
3342 salp = FindAlignmentsForBioseq (master_subloc_bsp);
3343 while (salp != NULL)
3344 {
3345 master_row = GetMasterRow (salp, master_subloc_id);
3346 num_rows = AlnMgr2GetNumRows (salp);
3347 for (prop_row = 1; prop_row <= num_rows; prop_row++)
3348 {
3349 if (prop_row == master_row) continue;
3350 if (! NthAlignmentSequenceInSeqPropList (salp, prop_row, seq_for_prop))
3351 {
3352 continue;
3353 }
3354
3355 prop_loc = MapSubLoc (master_subloc, salp, master_row, prop_row, gap_split);
3356 prop_loc_list = AssociatePropagatedSubloc (prop_loc_list, prop_loc, TRUE);
3357 }
3358 salp = salp->next;
3359 }
3360 }
3361 }
3362 }
3363 master_subloc = SeqLocFindNext (master_location, master_subloc);
3364 }
3365 return prop_loc_list;
3366 }
3367
MapLocForProp(SeqLocPtr master_location,Boolean gapSplit,ValNodePtr seq_for_prop,BoolPtr warned_about_master)3368 static ValNodePtr MapLocForProp
3369 (SeqLocPtr master_location,
3370 Boolean gapSplit,
3371 ValNodePtr seq_for_prop,
3372 BoolPtr warned_about_master)
3373 {
3374 ValNodePtr prop_loc_list = NULL, vnp;
3375 LocListPtr llp;
3376 SeqLocPtr slp;
3377
3378 if (master_location == NULL)
3379 {
3380 return NULL;
3381 }
3382
3383 prop_loc_list = GetPropagatedSublocations (master_location, gapSplit, prop_loc_list,
3384 seq_for_prop, warned_about_master);
3385
3386 /* now fix locations in prop_loc_list (add SEQLOC_MIX header to the locations that
3387 * are mixed)
3388 */
3389 for (vnp = prop_loc_list; vnp != NULL; vnp = vnp->next)
3390 {
3391 llp = (LocListPtr) vnp->data.ptrvalue;
3392 if (llp != NULL)
3393 {
3394 if (llp->slp != NULL)
3395 {
3396 if (llp->slp->next != NULL)
3397 {
3398 slp = ValNodeNew (NULL);
3399 slp->choice = SEQLOC_MIX;
3400 slp->data.ptrvalue = llp->slp;
3401 llp->slp = slp;
3402 }
3403 }
3404 }
3405 }
3406 return prop_loc_list;
3407 }
3408
3409
GetSegIdList(BioseqPtr master_seg)3410 static SeqIdPtr GetSegIdList (BioseqPtr master_seg)
3411 {
3412 SeqIdPtr sip_list = NULL, sip_last = NULL, sip;
3413 SeqLocPtr slp;
3414 if (master_seg == NULL)
3415 {
3416 return NULL;
3417 }
3418 if (master_seg->repr != Seq_repr_seg)
3419 {
3420 sip_list = SeqIdDupList (master_seg->id);
3421 }
3422 else
3423 {
3424 for (slp = master_seg->seq_ext; slp != NULL; slp = slp->next)
3425 {
3426 sip = SeqIdDup (SeqLocId (slp));
3427 if (sip_last == NULL)
3428 {
3429 sip_list = sip;
3430 }
3431 else
3432 {
3433 sip_last->next = sip;
3434 }
3435 sip_last = sip;
3436 }
3437 }
3438 return sip_list;
3439 }
3440
PropagateCodeBreaks(CdRegionPtr crp,SeqIdPtr sip,ValNodePtr codebreak_location_list,ValNodePtr codebreak_choice_list)3441 static void PropagateCodeBreaks
3442 (CdRegionPtr crp,
3443 SeqIdPtr sip,
3444 ValNodePtr codebreak_location_list,
3445 ValNodePtr codebreak_choice_list)
3446 {
3447 CodeBreakPtr cbp, last_cbp = NULL;
3448 ValNodePtr choice_vnp, cbp_vnp;
3449 LocListPtr llp;
3450 BioseqPtr cds_bsp;
3451 SeqIdPtr sip_list;
3452
3453 if (crp == NULL || codebreak_location_list == NULL || crp->code_break == NULL)
3454 {
3455 return;
3456 }
3457
3458 crp->code_break = CodeBreakFree (crp->code_break);
3459
3460 cds_bsp = BioseqFind (sip);
3461 if (cds_bsp == NULL)
3462 {
3463 return;
3464 }
3465
3466 sip_list = GetSegIdList (cds_bsp);
3467
3468 for (cbp_vnp = codebreak_location_list, choice_vnp = codebreak_choice_list;
3469 cbp_vnp != NULL && choice_vnp != NULL;
3470 cbp_vnp = cbp_vnp->next, choice_vnp = choice_vnp->next)
3471 {
3472 llp = FindLocListForSeqId (cbp_vnp->data.ptrvalue, sip_list);
3473 if (llp != NULL)
3474 {
3475 cbp = CodeBreakNew ();
3476 if (cbp != NULL)
3477 {
3478 cbp->loc = llp->slp;
3479 llp->slp = NULL;
3480 MemCpy (&(cbp->aa), choice_vnp->data.ptrvalue, sizeof (cbp->aa));
3481 if (last_cbp == NULL)
3482 {
3483 crp->code_break = cbp;
3484 }
3485 else
3486 {
3487 last_cbp->next = cbp;
3488 }
3489 }
3490 }
3491 }
3492 SeqIdFree (sip_list);
3493 }
3494
PropagateAnticodons(tRNAPtr trp,SeqIdPtr sip,ValNodePtr anticodon_location_list)3495 static void PropagateAnticodons
3496 (tRNAPtr trp,
3497 SeqIdPtr sip,
3498 ValNodePtr anticodon_location_list)
3499 {
3500 LocListPtr llp;
3501 BioseqPtr trna_bsp;
3502 SeqIdPtr sip_list;
3503
3504 if (trp == NULL || anticodon_location_list == NULL || trp->anticodon == NULL)
3505 {
3506 return;
3507 }
3508
3509 trp->anticodon = SeqLocFree (trp->anticodon);
3510
3511 trna_bsp = BioseqFind (sip);
3512 if (trna_bsp == NULL)
3513 {
3514 return;
3515 }
3516 sip_list = GetSegIdList (trna_bsp);
3517
3518 llp = FindLocListForSeqId (anticodon_location_list, sip_list);
3519 if (llp != NULL)
3520 {
3521 trp->anticodon = llp->slp;
3522 llp->slp = NULL;
3523 }
3524
3525 SeqIdFree (sip_list);
3526 }
3527
3528
ExtendLocToEnd(SeqLocPtr location,BioseqPtr bsp,Uint1 strand)3529 static void ExtendLocToEnd (
3530 SeqLocPtr location,
3531 BioseqPtr bsp,
3532 Uint1 strand
3533 )
3534
3535 {
3536 SeqIntPtr sinp;
3537 SeqLocPtr slp, last = NULL;
3538
3539 slp = SeqLocFindNext (location, NULL);
3540 while (slp != NULL) {
3541 last = slp;
3542 slp = SeqLocFindNext (location, slp);
3543 }
3544 if (last == NULL) return;
3545
3546 switch (last->choice) {
3547 case SEQLOC_INT :
3548 sinp = (SeqIntPtr) last->data.ptrvalue;
3549 if (sinp != NULL) {
3550 if (strand == Seq_strand_minus) {
3551 sinp->from = 0;
3552 } else {
3553 sinp->to = bsp->length - 1;
3554 }
3555 }
3556 case SEQLOC_PNT :
3557 /* not yet implemented */
3558 break;
3559 case SEQLOC_PACKED_PNT :
3560 /* not yet implemented */
3561 break;
3562 default :
3563 break;
3564 }
3565 }
3566
TruncateCDS(SeqFeatPtr sfp,Uint1 frame,BioseqPtr pbsp)3567 static void TruncateCDS (
3568 SeqFeatPtr sfp,
3569 Uint1 frame,
3570 BioseqPtr pbsp
3571 )
3572
3573 {
3574 Int4 len;
3575 SeqIntPtr sinp;
3576 SeqLocPtr slp;
3577 Int4 total = 0;
3578
3579 if (frame > 0) {
3580 frame--;
3581 }
3582 slp = SeqLocFindNext (sfp->location, NULL);
3583 while (slp != NULL) {
3584 len = SeqLocLen (slp);
3585
3586 if (len + total - frame <= (pbsp->length + 1) * 3) {
3587 total += len;
3588 } else {
3589 if (slp->choice == SEQLOC_INT) {
3590 sinp = (SeqIntPtr) slp->data.ptrvalue;
3591 if (sinp != NULL) {
3592 len = (pbsp->length + 1) * 3 - total;
3593 if (sinp->strand == Seq_strand_minus) {
3594 sinp->from = sinp->to - len + 1;
3595 } else {
3596 sinp->to = sinp->from + len - 1;
3597 }
3598 }
3599 }
3600 return;
3601 }
3602
3603 slp = SeqLocFindNext (sfp->location, slp);
3604 }
3605 }
3606
3607 /*------------------------------------------------------------------*/
3608 /* */
3609 /* PropagateCDS () - Called from DoFeatProp() for CDS-specific */
3610 /* feature propagation. */
3611 /* */
3612 /*------------------------------------------------------------------*/
3613
PropagateCDS(SeqFeatPtr dup,ProtRefPtr prp,BioseqPtr newbsp,Boolean stopCDS,Boolean transPast,Boolean cds3end,Uint1 frame,Uint1 strand)3614 static void PropagateCDS (SeqFeatPtr dup,
3615 ProtRefPtr prp,
3616 BioseqPtr newbsp,
3617 Boolean stopCDS,
3618 Boolean transPast,
3619 Boolean cds3end,
3620 Uint1 frame,
3621 Uint1 strand)
3622 {
3623 Uint2 entityID;
3624 MolInfoPtr mip;
3625 Boolean partial3;
3626 Boolean partial5;
3627 BioseqPtr pbsp;
3628 SeqDescrPtr sdp;
3629 SeqIdPtr sip;
3630 SeqFeatXrefPtr xref;
3631 Boolean xtend;
3632
3633 /* Check parameters */
3634
3635 if (dup == NULL || dup->data.choice != SEQFEAT_CDREGION || prp == NULL)
3636 return;
3637
3638 /* Extend the location to the end if that was checked */
3639
3640 if (transPast && (cds3end || !DoesCDSEndWithStopCodon (dup)))
3641 ExtendLocToEnd (dup->location, newbsp, strand);
3642
3643 /**/
3644
3645 prp = AsnIoMemCopy ((Pointer) prp,
3646 (AsnReadFunc) ProtRefAsnRead,
3647 (AsnWriteFunc) ProtRefAsnWrite);
3648
3649 xref = SeqFeatXrefNew ();
3650 if (xref == NULL)
3651 return;
3652 xref->data.choice = SEQFEAT_PROT;
3653 xref->data.value.ptrvalue = (Pointer) prp;
3654 xref->next = dup->xref;
3655 dup->xref = xref;
3656
3657 entityID = ObjMgrGetEntityIDForPointer (newbsp);
3658 PromoteXrefsEx (dup, newbsp, entityID, (Boolean) (! stopCDS), FALSE, FALSE);
3659
3660 /* Truncate new CDS based on new protein length */
3661
3662 sip = SeqLocId (dup->product);
3663 if (sip == NULL)
3664 return;
3665
3666 pbsp = BioseqFindCore (sip);
3667 if (pbsp == NULL)
3668 return;
3669
3670 TruncateCDS (dup, frame, pbsp);
3671
3672 /**/
3673
3674 CheckSeqLocForPartial (dup->location, &partial5, &partial3);
3675 if (cds3end) {
3676 xtend = FALSE;
3677 if (strand == Seq_strand_minus) {
3678 if (SeqLocStop (dup->location) == 0) {
3679 xtend = TRUE;
3680 }
3681 } else {
3682 if (SeqLocStop (dup->location) == newbsp->length - 1) {
3683 xtend = TRUE;
3684 }
3685 }
3686 if (xtend) {
3687 partial3 = TRUE;
3688 SetSeqLocPartial (dup->location, partial5, partial3);
3689 for (sdp = pbsp->descr; sdp != NULL; sdp = sdp->next) {
3690 if (sdp->choice != Seq_descr_molinfo) continue;
3691 mip = (MolInfoPtr) sdp->data.ptrvalue;
3692 if (mip == NULL) continue;
3693 if (partial5 && partial3) {
3694 mip->completeness = 5;
3695 } else if (partial5) {
3696 mip->completeness = 3;
3697 } else if (partial3) {
3698 mip->completeness = 4;
3699 }
3700 }
3701 }
3702 }
3703
3704 /* Set partial flag */
3705
3706 dup->partial = (Boolean) (partial5 || partial3);
3707 }
3708
3709
CheckForProteinAlignment(ByteStorePtr bs,BioseqPtr match_prot)3710 static SeqAlignPtr CheckForProteinAlignment (ByteStorePtr bs, BioseqPtr match_prot)
3711 {
3712 BioseqPtr newBsp;
3713 SeqAlignPtr salp;
3714 SeqEntryPtr nwsep;
3715 Boolean revcomp;
3716 ErrSev oldsev;
3717
3718 if (bs == NULL || match_prot == NULL)
3719 {
3720 return NULL;
3721 }
3722 newBsp = BioseqNew ();
3723 if (newBsp == NULL) {
3724 return NULL;
3725 }
3726
3727 newBsp->id = SeqIdParse ("lcl|ProtAlign");
3728 newBsp->repr = Seq_repr_raw;
3729 newBsp->mol = Seq_mol_aa;
3730 newBsp->seq_data_type = Seq_code_ncbieaa;
3731 newBsp->seq_data = (SeqDataPtr) bs;
3732 newBsp->length = BSLen (bs);
3733
3734 /* create SeqEntry for temporary protein bioseq to live in */
3735 nwsep = SeqEntryNew ();
3736 nwsep->choice = 1;
3737 nwsep->data.ptrvalue = newBsp;
3738 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) newBsp, nwsep);
3739
3740 oldsev = ErrSetMessageLevel (SEV_MAX);
3741 salp = Sequin_GlobalAlign2Seq (match_prot, newBsp, &revcomp);
3742 ErrSetMessageLevel (oldsev);
3743
3744 SeqMgrDeleteFromBioseqIndex (newBsp);
3745 /* the calling function will free bs */
3746 newBsp->seq_data = NULL;
3747 nwsep = SeqEntryFree (nwsep);
3748 return salp;
3749 }
3750
3751 /*------------------------------------------------------------------*/
3752 /* */
3753 /* CalculateReadingFrame () -- Calculates a sequence's reading */
3754 /* frame by seeing which frame */
3755 /* generates the most amino acids */
3756 /* when converted to a protein. */
3757 /* */
3758 /*------------------------------------------------------------------*/
3759
CalculateReadingFrame(SeqFeatPtr sfp,Boolean partial3,BioseqPtr match_prot)3760 static Uint1 CalculateReadingFrame (SeqFeatPtr sfp, Boolean partial3, BioseqPtr match_prot)
3761 {
3762 ByteStorePtr bs;
3763 CdRegionPtr crp;
3764 Int4 len;
3765 Int4 max;
3766 Uint1 frame, orig_frame;
3767 Int2 i;
3768 CharPtr protstr;
3769 SeqAlignPtr salp = NULL;
3770 Boolean best_is_aligned = FALSE;
3771
3772 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
3773
3774 max = 0;
3775 frame = 0;
3776
3777 if (! partial3 && crp->frame != 0)
3778 {
3779 bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
3780 if (bs != NULL)
3781 {
3782 protstr = BSMerge (bs, NULL);
3783 BSFree (bs);
3784 if (protstr != NULL) {
3785 len = StringLen (protstr);
3786 if (len > 0 && protstr [len - 1] == '*') {
3787 MemFree (protstr);
3788 return crp->frame;
3789 }
3790 MemFree (protstr);
3791 }
3792 }
3793 }
3794 orig_frame = crp->frame;
3795 if (orig_frame == 0) {
3796 orig_frame = 1;
3797 }
3798 for (i = 1; i <= 3; i++) {
3799 crp->frame = (Uint1) i;
3800 bs = ProteinFromCdRegionEx (sfp, FALSE, FALSE);
3801 salp = CheckForProteinAlignment (bs, match_prot);
3802 len = BSLen (bs);
3803 BSFree (bs);
3804 if (salp == NULL)
3805 {
3806 /* if no alignment, take longest protein */
3807 if (! best_is_aligned && (len > max || (len == max && i == orig_frame))) {
3808 max = len;
3809 frame = (Uint1) i;
3810 }
3811 } else if (!best_is_aligned) {
3812 /* if this is the first alignment encountered, use this */
3813 max = len;
3814 frame = (Uint1) i;
3815 best_is_aligned = TRUE;
3816 } else if (len > max) {
3817 /* if this is not the first alignment, but the sequence is longer, use this */
3818 max = len;
3819 frame = (Uint1) i;
3820 }
3821 salp = SeqAlignFree (salp);
3822 }
3823
3824 return frame;
3825 }
3826
3827 /* we don't want to propagate Prot features if the target
3828 * sequence already has one.
3829 */
OkToPropagate(SeqFeatPtr sfp,BioseqPtr bsp)3830 static Boolean OkToPropagate(SeqFeatPtr sfp, BioseqPtr bsp)
3831 {
3832 SeqMgrFeatContext fcontext;
3833
3834 if (sfp == NULL || bsp == NULL) return FALSE;
3835 /* never ok if a gap */
3836 if (sfp->idx.subtype == FEATDEF_gap) return FALSE;
3837 /* always ok if not a Prot feature */
3838 if (sfp->idx.subtype != FEATDEF_PROT) return TRUE;
3839 /* always ok if not a protein sequence */
3840 if (ISA_na (bsp->mol)) return TRUE;
3841 sfp = SeqMgrGetNextFeature (bsp, NULL, 0, FEATDEF_PROT, &fcontext);
3842 if (sfp == NULL)
3843 return TRUE;
3844 else
3845 return FALSE;
3846 }
3847
3848
GetSegSetId(SeqLocPtr slp)3849 static SeqIdPtr GetSegSetId (SeqLocPtr slp)
3850 {
3851 SeqLocPtr sub_slp;
3852 SeqIdPtr master_sip, part_sip;
3853 BioseqPtr seg_bsp;
3854 BioseqSetPtr parent_set;
3855 BioseqSetPtr last_parent_set = NULL;
3856 SeqEntryPtr sep;
3857 BioseqPtr parent_bsp;
3858
3859 if (slp == NULL) return NULL;
3860 master_sip = SeqLocId (slp);
3861 if (master_sip != NULL || slp->choice != SEQLOC_MIX)
3862 {
3863 return master_sip;
3864 }
3865 /* make sure all parts are from the same segmented set */
3866 for (sub_slp = slp->data.ptrvalue; sub_slp != NULL; sub_slp = sub_slp->next)
3867 {
3868 part_sip = SeqLocId (sub_slp);
3869 seg_bsp = BioseqFind (part_sip);
3870 if (seg_bsp == NULL || seg_bsp->idx.parenttype != OBJ_BIOSEQSET
3871 || seg_bsp->idx.parentptr == NULL)
3872 {
3873 return NULL;
3874 }
3875 parent_set = (BioseqSetPtr) seg_bsp->idx.parentptr;
3876 if (parent_set->_class != BioseqseqSet_class_parts
3877 || parent_set->idx.parenttype != OBJ_BIOSEQSET
3878 || parent_set->idx.parentptr == NULL)
3879 {
3880 return NULL;
3881 }
3882 if (last_parent_set == NULL)
3883 {
3884 last_parent_set = parent_set;
3885 }
3886 else if (last_parent_set != parent_set)
3887 {
3888 return NULL;
3889 }
3890 }
3891 if (last_parent_set == NULL)
3892 {
3893 return NULL;
3894 }
3895 parent_set = (BioseqSetPtr) last_parent_set->idx.parentptr;
3896 if (parent_set->_class != BioseqseqSet_class_segset)
3897 {
3898 return NULL;
3899 }
3900 for (sep = parent_set->seq_set; sep != NULL && ! IS_Bioseq (sep); sep = sep->next)
3901 {
3902 }
3903 if (sep == NULL) return NULL;
3904 parent_bsp = sep->data.ptrvalue;
3905 if (parent_bsp == NULL) return NULL;
3906 master_sip = parent_bsp->id;
3907 return master_sip;
3908 }
3909
3910 /* for each feature, find all propagated locations and create features using
3911 * those locations.
3912 */
3913 extern void
PropagateOneFeat(SeqFeatPtr sfp,Boolean gapSplit,Boolean fuse_joints,Boolean stopCDS,Boolean transPast,Boolean cds3end,ValNodePtr seq_for_prop,BoolPtr warned_about_master)3914 PropagateOneFeat
3915 (SeqFeatPtr sfp,
3916 Boolean gapSplit,
3917 Boolean fuse_joints,
3918 Boolean stopCDS,
3919 Boolean transPast,
3920 Boolean cds3end,
3921 ValNodePtr seq_for_prop, /* ValNode data.ptrvalue points to SeqId */
3922 BoolPtr warned_about_master)
3923 {
3924 ValNodePtr feature_location_list, vnp;
3925 ValNodePtr codebreak_location_list = NULL;
3926 ValNodePtr codebreak_choice_list = NULL;
3927 ValNodePtr anticodon_location_list = NULL;
3928 CodeBreakPtr cbp;
3929 CdRegionPtr crp;
3930 SeqFeatPtr dup;
3931 Uint1 frame = 0;
3932 BioseqPtr newbsp;
3933 SeqLocPtr newloc, mergedloc;
3934 Boolean partial5;
3935 Boolean partial3;
3936 RnaRefPtr rrp;
3937 SeqEntryPtr sep;
3938 SeqIdPtr sip;
3939 tRNAPtr trp;
3940 LocListPtr llp;
3941 Uint1 strand;
3942 ProtRefPtr prp = NULL;
3943 BioseqPtr pbsp = NULL;
3944 SeqFeatPtr prot;
3945
3946 if (sfp == NULL || sfp->location == NULL) return;
3947
3948 feature_location_list = MapLocForProp (sfp->location, gapSplit,
3949 seq_for_prop, warned_about_master);
3950 if (feature_location_list == NULL) return;
3951
3952 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
3953
3954 /* also need to propagate locations for CDS code breaks and tRNA anticodons */
3955 if (sfp->data.choice == SEQFEAT_CDREGION)
3956 {
3957 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
3958 if (crp != NULL)
3959 {
3960 for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next)
3961 {
3962 vnp = MapLocForProp (cbp->loc, gapSplit, seq_for_prop, warned_about_master);
3963 ValNodeAddPointer (&codebreak_location_list, 0, vnp);
3964 ValNodeAddPointer (&codebreak_choice_list, 0, &(cbp->aa));
3965 }
3966 }
3967 sip = SeqLocId (sfp->product);
3968 if (sip != NULL)
3969 {
3970 pbsp = BioseqFindCore (sip);
3971 if (pbsp != NULL)
3972 {
3973 prot = SeqMgrGetBestProteinFeature (pbsp, NULL);
3974 if (prot != NULL && prot->data.choice == SEQFEAT_PROT)
3975 {
3976 prp = (ProtRefPtr) prot->data.value.ptrvalue;
3977 }
3978 }
3979 }
3980 }
3981 else if (sfp->data.choice == SEQFEAT_RNA)
3982 {
3983 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
3984 if (rrp != NULL && rrp->ext.choice == 2)
3985 {
3986 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
3987 if (trp != NULL && trp->anticodon != NULL)
3988 {
3989 anticodon_location_list = MapLocForProp (trp->anticodon, gapSplit,
3990 seq_for_prop, warned_about_master);
3991 }
3992 }
3993 }
3994
3995 for (vnp = feature_location_list; vnp != NULL; vnp = vnp->next)
3996 {
3997 llp = (LocListPtr) vnp->data.ptrvalue;
3998 if (llp == NULL)
3999 {
4000 continue;
4001 }
4002 newloc = llp->slp;
4003 llp->slp = NULL;
4004 if (newloc == NULL)
4005 {
4006 continue;
4007 }
4008
4009 mergedloc = NULL;
4010 if (fuse_joints)
4011 {
4012 mergedloc = MergeAdjacentSeqLocIntervals (newloc);
4013 if (mergedloc != NULL)
4014 {
4015 SeqLocFree (newloc);
4016 newloc = mergedloc;
4017 }
4018 }
4019
4020 /* if we have a mixed location with multiple sequences, SeqLocId will
4021 * return NULL.
4022 * We should check to see if we are trying to create a feature for
4023 * a segset, in which case we'll want the Bioseq for the master segment.
4024 */
4025 sip = GetSegSetId (newloc);
4026
4027 dup = AsnIoMemCopy ((Pointer) sfp,
4028 (AsnReadFunc) SeqFeatAsnRead,
4029 (AsnWriteFunc) SeqFeatAsnWrite);
4030 SeqLocFree (dup->location);
4031 dup->location = newloc;
4032 SetSeqLocPartial (dup->location, partial5, partial3);
4033
4034 /* do not propagate feature IDs or links */
4035 ClearFeatIDs (dup);
4036 ClearFeatIDXrefs (dup);
4037
4038 /* clean up product before we look for (and maybe don't find) the newbsp */
4039 if (dup->product != NULL)
4040 dup->product = SeqLocFree (dup->product);
4041
4042 switch (dup->data.choice) {
4043 case SEQFEAT_CDREGION :
4044 crp = (CdRegionPtr) dup->data.value.ptrvalue;
4045 if (crp != NULL) {
4046 crp->frame = CalculateReadingFrame (dup, partial3, pbsp);
4047 frame = crp->frame;
4048
4049 PropagateCodeBreaks (crp, sip,
4050 codebreak_location_list,
4051 codebreak_choice_list);
4052 }
4053 break;
4054 case SEQFEAT_RNA :
4055 rrp = (RnaRefPtr) dup->data.value.ptrvalue;
4056 if (rrp != NULL && rrp->ext.choice == 2) {
4057 trp = (tRNAPtr) rrp->ext.value.ptrvalue;
4058 if (trp != NULL && trp->anticodon != NULL)
4059 {
4060 PropagateAnticodons (trp, sip, anticodon_location_list);
4061 }
4062 }
4063 break;
4064 default :
4065 break;
4066 }
4067
4068 newbsp = BioseqFindCore (sip);
4069 if (newbsp == NULL)
4070 return;
4071
4072 /* need to call OkToPropagate with sfp instead of dup
4073 * because dup has not been indexed yet, so subtype isn't set.
4074 */
4075 if (OkToPropagate(sfp, newbsp))
4076 {
4077 sep = SeqMgrGetSeqEntryForData (newbsp);
4078 if (sep == NULL)
4079 return;
4080 CreateNewFeature (sep, NULL, dup->data.choice, dup);
4081
4082 /* If we're doing a CDS propagation, then */
4083 /* do the extra stuff related to that. */
4084
4085 if (SEQFEAT_CDREGION == dup->data.choice)
4086 {
4087 strand = SeqLocStrand (dup->location);
4088
4089 PropagateCDS (dup, prp, newbsp, stopCDS, transPast, cds3end, frame, strand);
4090 }
4091 }
4092 else
4093 {
4094 SeqFeatFree (dup);
4095 }
4096 }
4097
4098 feature_location_list = FreeLocList (feature_location_list);
4099 anticodon_location_list = FreeLocList (anticodon_location_list);
4100 for (vnp = codebreak_location_list; vnp != NULL; vnp = vnp->next)
4101 {
4102 vnp->data.ptrvalue = FreeLocList (vnp->data.ptrvalue);
4103 }
4104 codebreak_location_list = ValNodeFree (codebreak_location_list);
4105 codebreak_choice_list = ValNodeFree (codebreak_choice_list);
4106
4107 }
4108
CDSgoesToEnd(BioseqPtr bsp,SeqMgrFeatContext PNTR fcontext)4109 static Boolean CDSgoesToEnd (
4110 BioseqPtr bsp,
4111 SeqMgrFeatContext PNTR fcontext
4112 )
4113
4114 {
4115 if (fcontext->strand == Seq_strand_minus) {
4116 if (fcontext->left == 0 && fcontext->partialR) return TRUE;
4117 } else {
4118 if (fcontext->right == bsp->length - 1 && fcontext->partialR) return TRUE;
4119 }
4120 return FALSE;
4121 }
4122
DoFixCDS(SeqFeatPtr sfp,Pointer userdata)4123 extern void DoFixCDS (
4124 SeqFeatPtr sfp,
4125 Pointer userdata
4126 )
4127
4128 {
4129 BaseFormPtr bfp;
4130 ByteStorePtr bs;
4131 BioseqPtr bsp;
4132 Boolean change_partials = FALSE;
4133 SeqMgrFeatContext context;
4134 CdRegionPtr crp;
4135 size_t len;
4136 Boolean partial5;
4137 Boolean partial3;
4138 SeqIntPtr sintp;
4139 SeqLocPtr slp;
4140 CharPtr str;
4141
4142 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return;
4143 bfp = (BaseFormPtr) userdata;
4144 if (SeqMgrGetDesiredFeature (bfp->input_entityID, NULL,
4145 0, 0, sfp, &context) != sfp) return;
4146 bsp = context.bsp;
4147 if (bsp == NULL) return;
4148
4149 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
4150 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
4151 if (crp->frame > 1) {
4152 if (context.strand == Seq_strand_minus) {
4153 if (context.right == bsp->length - 1) {
4154 partial5 = TRUE;
4155 change_partials = TRUE;
4156 }
4157 } else {
4158 if (context.left == 0) {
4159 partial5 = TRUE;
4160 change_partials = TRUE;
4161 }
4162 }
4163 }
4164 bs = ProteinFromCdRegion (sfp, TRUE);
4165 if (bs != NULL) {
4166 str = BSMerge (bs, NULL);
4167 BSFree (bs);
4168 if (str != NULL) {
4169 if (*str == '-') {
4170 if (! partial5) {
4171 partial5 = TRUE;
4172 change_partials = TRUE;
4173 }
4174 }
4175 len = StringLen (str);
4176 if (len > 0 && str [len - 1] != '*') {
4177 if (context.strand == Seq_strand_minus) {
4178 } else {
4179 if (bsp->length - context.right < 3) {
4180 slp = SeqLocFindNext (sfp->location, NULL);
4181 while (slp != NULL) {
4182 if (slp->choice == SEQLOC_INT) {
4183 sintp = (SeqIntPtr) slp->data.ptrvalue;
4184 if (sintp != NULL) {
4185 if (sintp->to == context.right) {
4186 sintp->to = bsp->length - 1;
4187 }
4188 }
4189 }
4190 slp = SeqLocFindNext (sfp->location, slp);
4191 }
4192 }
4193 partial3 = TRUE;
4194 change_partials = TRUE;
4195 }
4196 }
4197 MemFree (str);
4198 }
4199 }
4200 if (change_partials) {
4201 SetSeqLocPartial (sfp->location, partial5, partial3);
4202 ResynchCDSPartials (sfp, NULL);
4203 }
4204 }
4205
4206 extern SeqFeatPtr
GetNextFeatureOnSegOrMaster(BioseqPtr bsp,SeqFeatPtr sfp,Uint4 itemID,Uint4 index,SeqMgrFeatContextPtr fcontext)4207 GetNextFeatureOnSegOrMaster
4208 (BioseqPtr bsp, SeqFeatPtr sfp, Uint4 itemID, Uint4 index, SeqMgrFeatContextPtr fcontext)
4209 {
4210 BioseqSetPtr bssp;
4211 SeqEntryPtr sep;
4212 BioseqPtr master_bsp = NULL;
4213 SeqFeatPtr next_sfp;
4214 SeqLocPtr slp;
4215 SeqIdPtr loc_id;
4216 Boolean on_this_segment = FALSE;
4217
4218 if (bsp == NULL)
4219 {
4220 return NULL;
4221 }
4222 if (bsp->idx.parenttype != OBJ_BIOSEQSET || bsp->idx.parentptr == NULL)
4223 {
4224 return SeqMgrGetNextFeature (bsp, sfp, itemID, index, fcontext);
4225 }
4226
4227 bssp = (BioseqSetPtr) bsp->idx.parentptr;
4228 if (bssp == NULL || bssp->_class != BioseqseqSet_class_parts
4229 || bssp->idx.parenttype != OBJ_BIOSEQSET || bsp->idx.parentptr == NULL)
4230 {
4231 return SeqMgrGetNextFeature (bsp, sfp, itemID, index, fcontext);
4232 }
4233
4234 bssp = bssp->idx.parentptr;
4235 if (bssp->_class != BioseqseqSet_class_segset)
4236 {
4237 return SeqMgrGetNextFeature (bsp, sfp, itemID, index, fcontext);
4238 }
4239
4240 for (sep = bssp->seq_set; sep != NULL && master_bsp == NULL; sep = sep->next)
4241 {
4242 if (IS_Bioseq (sep))
4243 {
4244 master_bsp = sep->data.ptrvalue;
4245 if (master_bsp != NULL && master_bsp->repr != Seq_repr_seg)
4246 {
4247 master_bsp = NULL;
4248 }
4249 }
4250 }
4251
4252 if (master_bsp == NULL)
4253 {
4254 return SeqMgrGetNextFeature (bsp, sfp, itemID, index, fcontext);
4255 }
4256
4257 next_sfp = SeqMgrGetNextFeature (master_bsp, sfp, itemID, index, fcontext);
4258 if (next_sfp == NULL) return NULL;
4259
4260 while (next_sfp != NULL && !on_this_segment)
4261 {
4262 for (slp = SeqLocFindNext (next_sfp->location, NULL);
4263 slp != NULL && ! on_this_segment; slp = SeqLocFindNext (next_sfp->location, slp))
4264 {
4265 loc_id = SeqLocId (slp);
4266 if (SeqIdIn (loc_id, bsp->id))
4267 {
4268 on_this_segment = TRUE;
4269 }
4270 }
4271 if (!on_this_segment)
4272 {
4273 next_sfp = SeqMgrGetNextFeature (master_bsp, next_sfp, itemID, index, fcontext);
4274 }
4275 }
4276
4277 return next_sfp;
4278 }
4279
4280
FeatureInAlignmentInterval(SeqFeatPtr sfp,BioseqPtr master_bsp,SeqAlignPtr salp_list)4281 static Boolean FeatureInAlignmentInterval (SeqFeatPtr sfp, BioseqPtr master_bsp, SeqAlignPtr salp_list)
4282 {
4283 SeqAlignPtr s;
4284 Boolean rval = FALSE;
4285 Int4 start, stop, tmp, i, aln_start, aln_stop;
4286 SeqIdPtr sip;
4287
4288 if (sfp == NULL) {
4289 return FALSE;
4290 }
4291
4292 start = SeqLocStart (sfp->location);
4293 stop = SeqLocStop (sfp->location);
4294 if (start > stop ) {
4295 tmp = start;
4296 start = stop;
4297 stop = tmp;
4298 }
4299
4300 for (s = salp_list; s != NULL && !rval; s = s->next) {
4301 /* find position of master in alignment */
4302 for (i = 0; i < s->dim; i++) {
4303 sip = AlnMgrGetNthSeqIdPtr(s, i + 1);
4304 if (SeqIdIn (sip, master_bsp->id)) {
4305 AlnMgr2GetNthSeqRangeInSA(s, i + 1, &aln_start, &aln_stop);
4306 if (aln_start > aln_stop) {
4307 tmp = aln_start;
4308 aln_start = aln_stop;
4309 aln_stop = tmp;
4310 }
4311 if (stop < aln_start || start > aln_stop) {
4312 /* outside */
4313 } else {
4314 rval = TRUE;
4315 }
4316 break;
4317 }
4318 }
4319 }
4320 return rval;
4321 }
4322
4323
AreAllFeaturesCoveredByAlignmentIntervals(SelStructPtr sel,BioseqPtr bsp)4324 static Boolean AreAllFeaturesCoveredByAlignmentIntervals (SelStructPtr sel, BioseqPtr bsp)
4325 {
4326 SelStructPtr ssp;
4327 SeqAlignPtr salp, salp_next;
4328 Boolean rval = TRUE;
4329 SeqFeatPtr sfp;
4330 SeqMgrFeatContext fcontext;
4331
4332 salp = FindAlignmentsForBioseq (bsp);
4333 if (salp == NULL) {
4334 return FALSE;
4335 }
4336
4337 if (sel != NULL) {
4338 for (ssp = sel; ssp != NULL && rval; ssp = ssp->next) {
4339 sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &fcontext);
4340 if (sfp != NULL) {
4341 rval = FeatureInAlignmentInterval (sfp, bsp, salp);
4342 }
4343 }
4344 } else {
4345 sfp = GetNextFeatureOnSegOrMaster (bsp, NULL, 0, 0, &fcontext);
4346 while (sfp != NULL && rval) {
4347 rval = FeatureInAlignmentInterval (sfp, bsp, salp);
4348 sfp = GetNextFeatureOnSegOrMaster (bsp, sfp, 0, 0, &fcontext);
4349 }
4350 }
4351
4352 while (salp != NULL) {
4353 salp_next = salp->next;
4354 salp->next = NULL;
4355 salp = SeqAlignFree (salp);
4356 salp = salp_next;
4357 }
4358 return rval;
4359 }
4360
4361
AcceptFeatProp(ButtoN b)4362 static void AcceptFeatProp (
4363 ButtoN b
4364 )
4365
4366 {
4367 BioseqPtr bsp;
4368 Boolean cds3end;
4369 DenseSegPtr dsp;
4370 Uint2 entityID;
4371 SeqMgrFeatContext fcontext;
4372 FprDataPtr fdp;
4373 Boolean fixCDS;
4374 Boolean gapSplit;
4375 SeqAlignPtr salp;
4376 SeqEntryPtr sep;
4377 SeqFeatPtr sfp;
4378 SeqIdPtr sip;
4379 SeqIdPtr sip_head;
4380 SeqIdPtr sip_new;
4381 SeqIdPtr sip_prev;
4382 SeqIdPtr sip_tmp;
4383 Boolean stopCDS;
4384 Boolean transPast;
4385 Boolean fuse_joints = FALSE;
4386 Boolean warned_about_master = FALSE;
4387 ValNodePtr seq_for_prop = NULL;
4388 SelStructPtr sel = NULL, ssp;
4389
4390 fdp = (FprDataPtr) GetObjectExtra (b);
4391 if (fdp == NULL) return;
4392 SafeHide (fdp->form);
4393
4394 bsp = fdp->bsp;
4395 salp = fdp->salp;
4396 if (bsp == NULL || salp == NULL) {
4397 Remove (fdp->form);
4398 return;
4399 }
4400
4401
4402 if (GetValue (fdp->allOrSel) == 2) {
4403 sel = ObjMgrGetSelected ();
4404 if (sel == NULL) {
4405 Message (MSG_ERROR, "You have not selected features to propagate!");
4406 SafeShow (fdp->form);
4407 return;
4408 }
4409 }
4410
4411 if (!AreAllFeaturesCoveredByAlignmentIntervals(sel, bsp)) {
4412 if (sel == NULL) {
4413 Message (MSG_ERROR, "Your alignment does not cover all features on the sequence. Unable to propagate.");
4414 } else {
4415 Message (MSG_ERROR, "Your alignment does not cover all selected features. Unable to propagate");
4416 }
4417 SafeShow (fdp->form);
4418 return;
4419 }
4420
4421 if (GetValue (fdp->gapSplit) == 1) {
4422 gapSplit = FALSE;
4423 } else {
4424 gapSplit= TRUE;
4425 }
4426 if (GetStatus (fdp->stopCDS)) {
4427 stopCDS = TRUE;
4428 } else {
4429 stopCDS = FALSE;
4430 }
4431 if (GetStatus (fdp->transPast)) {
4432 transPast = TRUE;
4433 } else {
4434 transPast = FALSE;
4435 }
4436 if (GetStatus (fdp->fixCDS)) {
4437 fixCDS = TRUE;
4438 } else {
4439 fixCDS = FALSE;
4440 }
4441 if (GetStatus (fdp->fuseJoints)) {
4442 fuse_joints = TRUE;
4443 } else {
4444 fuse_joints = FALSE;
4445 }
4446
4447 seq_for_prop = DialogToPointer (fdp->sequence_list_dlg);
4448 if (seq_for_prop != NULL && seq_for_prop->next == NULL)
4449 {
4450 for (sip = bsp->id; sip != NULL; sip = sip->next)
4451 {
4452 if (SeqIdIn (sip, (SeqIdPtr) seq_for_prop->data.ptrvalue))
4453 {
4454 Message (MSG_ERROR, "Can't propagate from a sequence to itself!");
4455 SafeShow (fdp->form);
4456 return;
4457 }
4458 }
4459 }
4460
4461 SeqEntrySetScope (NULL);
4462
4463 /* need to find alignment for each feature and row within that alignment for the feature */
4464
4465 dsp = (DenseSegPtr)(salp->segs);
4466 sip = SeqIdFindBest (bsp->id, 0);
4467 sip_tmp = dsp->ids;
4468 sip_head = sip_prev = NULL;
4469 while (sip_tmp != NULL)
4470 {
4471 if (SeqIdComp(sip_tmp, bsp->id) == SIC_YES)
4472 sip_new = SeqIdDup(sip);
4473 else
4474 sip_new = SeqIdDup(sip_tmp);
4475 if (sip_head != NULL)
4476 {
4477 sip_prev->next = sip_new;
4478 sip_prev = sip_new;
4479 } else
4480 sip_head = sip_prev = sip_new;
4481 sip_tmp = sip_tmp->next;
4482 }
4483 dsp->ids = sip_head;
4484
4485 if (sel != NULL) {
4486 for (ssp = sel; ssp != NULL; ssp = ssp->next) {
4487 sfp = SeqMgrGetDesiredFeature (ssp->entityID, NULL, ssp->itemID, 0, NULL, &fcontext);
4488 if (sfp != NULL) {
4489 cds3end = CDSgoesToEnd (bsp, &fcontext);
4490 PropagateOneFeat (sfp, gapSplit, fuse_joints, stopCDS, transPast,
4491 cds3end, seq_for_prop, &warned_about_master);
4492 }
4493 }
4494 } else {
4495
4496 /* propagate all features on bioseq */
4497
4498 sfp = GetNextFeatureOnSegOrMaster (bsp, NULL, 0, 0, &fcontext);
4499 while (sfp != NULL) {
4500 cds3end = CDSgoesToEnd (bsp, &fcontext);
4501 PropagateOneFeat (sfp, gapSplit, fuse_joints, stopCDS, transPast,
4502 cds3end, seq_for_prop, &warned_about_master);
4503
4504 sfp = GetNextFeatureOnSegOrMaster (bsp, sfp, 0, 0, &fcontext);
4505 }
4506 }
4507
4508 seq_for_prop = ValNodeFree (seq_for_prop);
4509 if (fixCDS) {
4510 entityID = ObjMgrGetEntityIDForPointer (bsp);
4511 sep = GetTopSeqEntryForEntityID (entityID);
4512 fdp->input_entityID = entityID;
4513 /* reindex before calling DoFixCDS */
4514 SeqMgrIndexFeatures (entityID, NULL);
4515 VisitFeaturesInSep (sep, fdp, DoFixCDS);
4516 }
4517
4518 entityID = ObjMgrGetEntityIDForPointer (bsp);
4519 ObjMgrSetDirtyFlag (entityID, TRUE);
4520 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
4521
4522 if (GetStatus (fdp->leave_dlg_up)) {
4523 SafeShow (fdp->form);
4524 } else {
4525 Remove (fdp->form);
4526 Update();
4527 }
4528 }
4529
SetFeaturePropagateAccept(Pointer userdata)4530 static void SetFeaturePropagateAccept (Pointer userdata)
4531 {
4532 FprDataPtr fdp;
4533 ValNodePtr err_list;
4534
4535 fdp = (FprDataPtr) userdata;
4536 if (fdp == NULL)
4537 {
4538 return;
4539 }
4540 err_list = TestDialog (fdp->sequence_list_dlg);
4541 if (err_list == NULL)
4542 {
4543 Enable (fdp->accept);
4544 }
4545 else
4546 {
4547 Disable (fdp->accept);
4548 }
4549 ValNodeFree (err_list);
4550 }
4551
FeaturePropagateFormMessage(ForM f,Int2 mssg)4552 static void FeaturePropagateFormMessage (ForM f, Int2 mssg)
4553
4554 {
4555 BaseFormPtr bfp;
4556 StdEditorProcsPtr sepp;
4557
4558 bfp = (BaseFormPtr) GetObjectExtra (f);
4559 if (bfp == NULL) return;
4560 switch (mssg) {
4561 case VIB_MSG_CLOSE :
4562 Remove (f);
4563 break;
4564 default :
4565 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4566 if (sepp != NULL && sepp->handleMessages != NULL) {
4567 sepp->handleMessages (f, mssg);
4568 }
4569 break;
4570 }
4571 }
4572
4573 #ifdef WIN_MAC
UpdateSequenceFormActivated(WindoW w)4574 extern void UpdateSequenceFormActivated (WindoW w)
4575
4576 {
4577 HANDLE openItem;
4578 HANDLE closeItem;
4579 BoolPtr pInitialFormsActive;
4580
4581 currentFormDataPtr = (VoidPtr) GetObjectExtra (w);
4582
4583 pInitialFormsActive = GetAppProperty (SEQFORM_INIT_ACTIVE);
4584 if (pInitialFormsActive != NULL)
4585 {
4586 *pInitialFormsActive = FALSE;
4587 }
4588
4589 openItem = (HANDLE) GetAppProperty (SEQFORM_OPEN_ITEM);
4590 closeItem = (HANDLE) GetAppProperty (SEQFORM_CLOSE_ITEM);
4591
4592 RepeatProcOnHandles (Enable,
4593 (HANDLE) openItem,
4594 (HANDLE) closeItem,
4595 NULL);
4596 }
4597
UpdateSequenceFormActivate(WindoW w)4598 extern void UpdateSequenceFormActivate (WindoW w)
4599
4600 {
4601 BaseFormPtr bfp;
4602
4603 bfp = (BaseFormPtr) GetObjectExtra (w);
4604 if (bfp != NULL) {
4605 if (bfp->activate != NULL) {
4606 bfp->activate (w);
4607 }
4608 }
4609 }
4610 #endif
4611
4612
FeaturePropagateFormMsgFunc(OMMsgStructPtr ommsp)4613 static Int2 LIBCALLBACK FeaturePropagateFormMsgFunc (OMMsgStructPtr ommsp)
4614 {
4615 OMUserDataPtr omudp;
4616 FprDataPtr fp = NULL;
4617
4618 omudp = (OMUserDataPtr)(ommsp->omuserdata);
4619 if (omudp == NULL) return OM_MSG_RET_ERROR;
4620 fp = (FprDataPtr) omudp->userdata.ptrvalue;
4621 if (fp == NULL) return OM_MSG_RET_ERROR;
4622
4623 switch (ommsp->message)
4624 {
4625 case OM_MSG_UPDATE:
4626 break;
4627 case OM_MSG_DESELECT:
4628 break;
4629
4630 case OM_MSG_SELECT:
4631 break;
4632 case OM_MSG_DEL:
4633 Remove (fp->form);
4634 break;
4635 case OM_MSG_HIDE:
4636 break;
4637 case OM_MSG_SHOW:
4638 break;
4639 case OM_MSG_FLUSH:
4640 Remove (fp->form);
4641 break;
4642 default:
4643 break;
4644 }
4645 return OM_MSG_RET_OK;
4646 }
4647
4648
CleanupFeaturePropagateForm(GraphiC g,VoidPtr data)4649 static void CleanupFeaturePropagateForm (GraphiC g, VoidPtr data)
4650
4651 {
4652 FprDataPtr fp;
4653
4654 fp = (FprDataPtr) data;
4655 if (fp != NULL) {
4656 ObjMgrFreeUserData (fp->input_entityID, fp->procid, fp->proctype, fp->userkey);
4657 }
4658 StdCleanupFormProc (g, data);
4659 }
4660
4661
FeaturePropagateForm(BioseqPtr bsp,SeqAlignPtr salp,Uint4 selFeatItemID)4662 extern ForM FeaturePropagateForm (
4663 BioseqPtr bsp,
4664 SeqAlignPtr salp,
4665 Uint4 selFeatItemID
4666 )
4667
4668 {
4669 ButtoN b;
4670 GrouP c;
4671 GrouP seq_choice_grp;
4672 FprDataPtr fdp;
4673 GrouP g;
4674 PrompT ppt;
4675 SeqIdPtr sip;
4676 Char strid [41];
4677 Char txt [128];
4678 WindoW w;
4679 OMUserDataPtr omudp;
4680
4681 if (bsp == NULL) return NULL;
4682 fdp = (FprDataPtr) MemNew (sizeof (FprData));
4683 if (fdp == NULL) return NULL;
4684 w = FixedWindow (-50, -33, -10, -10, "Feature Propagate", NULL);
4685 if (w == NULL) return NULL;
4686
4687 SetObjectExtra (w, (Pointer) fdp, CleanupFeaturePropagateForm);
4688 fdp->form = (ForM) w;
4689 fdp->formmessage = FeaturePropagateFormMessage;
4690
4691 #ifdef WIN_MAC
4692 fdp->activate = UpdateSequenceFormActivated;
4693 SetActivate (w, UpdateSequenceFormActivate);
4694 #endif
4695
4696 /* register to receive update messages */
4697 fdp->input_entityID = bsp->idx.entityID;
4698 fdp->userkey = OMGetNextUserKey ();
4699 fdp->procid = 0;
4700 fdp->proctype = OMPROC_EDIT;
4701 omudp = ObjMgrAddUserData (fdp->input_entityID, fdp->procid, fdp->proctype, fdp->userkey);
4702 if (omudp != NULL) {
4703 omudp->userdata.ptrvalue = (Pointer) fdp;
4704 omudp->messagefunc = FeaturePropagateFormMsgFunc;
4705 }
4706
4707 fdp->bsp = bsp;
4708 fdp->salp = salp;
4709
4710 sip = SeqIdFindWorst (bsp->id);
4711 SeqIdWrite (sip, strid, PRINTID_REPORT, sizeof (strid) - 1);
4712 if (ISA_na (bsp->mol)) {
4713 sprintf (txt, "Propagate from %s to", strid);
4714 } else {
4715 sprintf (txt, "Propagate from %s to", strid);
4716 }
4717
4718 g = HiddenGroup (w, -1, 0, NULL);
4719 SetGroupSpacing (g, 5, 5);
4720
4721 seq_choice_grp = HiddenGroup (g, 0, 2, NULL);
4722 ppt = StaticPrompt (seq_choice_grp, txt, 0, 0, programFont, 'c');
4723 fdp->sequence_list_dlg = SequenceSelectionDialog (seq_choice_grp,
4724 SetFeaturePropagateAccept,
4725 fdp,
4726 TRUE,
4727 ISA_na (bsp->mol),
4728 ISA_aa (bsp->mol),
4729 fdp->input_entityID);
4730
4731 fdp->allOrSel = HiddenGroup (g, 2, 0, NULL);
4732 RadioButton (fdp->allOrSel, "All Features");
4733 b = RadioButton (fdp->allOrSel, "Selected Feature");
4734 #if 1
4735 SetValue (fdp->allOrSel, 1);
4736 #else
4737 if (ObjMgrGetSelected () != NULL) {
4738 SetValue (fdp->allOrSel, 2);
4739 } else {
4740 SetValue (fdp->allOrSel, 1);
4741 }
4742 #endif
4743
4744 fdp->gapSplit = HiddenGroup (g, 2, 0, NULL);
4745 RadioButton (fdp->gapSplit, "Extend over gaps");
4746 RadioButton (fdp->gapSplit, "Split at gaps");
4747 SetValue (fdp->gapSplit, 1);
4748
4749 fdp->stopCDS = CheckBox (g, "Stop CDS translation at internal stop codon", NULL);
4750 SetStatus (fdp->stopCDS, FALSE);
4751
4752 fdp->transPast = CheckBox (g, "Translate CDS after partial 3' boundary", NULL);
4753
4754 fdp->fixCDS = CheckBox (g, "Cleanup CDS partials after propagation", NULL);
4755 SetStatus (fdp->fixCDS, TRUE);
4756
4757 fdp->fuseJoints = CheckBox (g, "Fuse adjacent propagated intervals", NULL);
4758 SetStatus (fdp->fuseJoints, FALSE);
4759
4760 c = HiddenGroup (w, 4, 0, NULL);
4761 fdp->accept = DefaultButton (c, "Accept", AcceptFeatProp);
4762 SetObjectExtra (fdp->accept, (Pointer) fdp, NULL);
4763 PushButton (c, "Cancel", StdCancelButtonProc);
4764 fdp->leave_dlg_up = CheckBox (c, "Leave Dialog Up", NULL);
4765
4766 AlignObjects (ALIGN_CENTER, (HANDLE) seq_choice_grp, (HANDLE) fdp->allOrSel,
4767 (HANDLE) fdp->gapSplit, (HANDLE) fdp->stopCDS,
4768 (HANDLE) fdp->transPast, (HANDLE) fdp->fixCDS,
4769 (HANDLE) fdp->fuseJoints,
4770 (HANDLE) c, NULL);
4771 RealizeWindow (w);
4772 SendMessageToDialog (fdp->sequence_list_dlg, NUM_VIB_MSG + 1);
4773
4774
4775 return (ForM) w;
4776 }
4777
4778 typedef struct batchapplyfeaturedetailsdlg
4779 {
4780 DIALOG_MESSAGE_BLOCK
4781
4782 TexT defline;
4783 TexT geneName;
4784 TexT geneDesc;
4785 TexT protName;
4786 TexT protDesc;
4787 TexT rnaName;
4788 TexT featcomment;
4789 DialoG featdef_choice_dlg;
4790 DialoG rnaType;
4791 PopuP reading_frame;
4792 Int4 feattype;
4793 Nlm_ChangeNotifyProc change_notify;
4794 Pointer change_userdata;
4795 } BatchApplyFeatureDetailsDlgData, PNTR BatchApplyFeatureDetailsDlgPtr;
4796
4797 extern BatchApplyFeatureDetailsPtr
BatchApplyFeatureDetailsFree(BatchApplyFeatureDetailsPtr bafdp)4798 BatchApplyFeatureDetailsFree
4799 (BatchApplyFeatureDetailsPtr bafdp)
4800 {
4801 if (bafdp != NULL)
4802 {
4803 bafdp->defline = MemFree (bafdp->defline);
4804 bafdp->geneName = MemFree (bafdp->geneName);
4805 bafdp->geneDesc = MemFree (bafdp->geneDesc);
4806 bafdp->protName = MemFree (bafdp->protName);
4807 bafdp->protDesc = MemFree (bafdp->protDesc);
4808 bafdp->rnaType = RnaTypeFree (bafdp->rnaType);
4809 bafdp->rnaName = MemFree (bafdp->rnaName);
4810 bafdp->featcomment = MemFree (bafdp->featcomment);
4811 bafdp->featdef_name = MemFree (bafdp->featdef_name);
4812 bafdp = MemFree (bafdp);
4813 }
4814 return bafdp;
4815 }
4816
BatchApplyFeatureDetailsNew(void)4817 extern BatchApplyFeatureDetailsPtr BatchApplyFeatureDetailsNew (void)
4818 {
4819 BatchApplyFeatureDetailsPtr bafdp;
4820
4821 bafdp = (BatchApplyFeatureDetailsPtr) MemNew (sizeof (BatchApplyFeatureDetailsData));
4822 if (bafdp != NULL)
4823 {
4824 bafdp->defline = NULL;
4825 bafdp->geneName = NULL;
4826 bafdp->geneDesc = NULL;
4827 bafdp->protName = NULL;
4828 bafdp->protDesc = NULL;
4829 bafdp->rnaName = NULL;
4830 bafdp->featcomment = NULL;
4831 bafdp->featdef_name = NULL;
4832 bafdp->featdef_choice = FEATDEF_GENE;
4833 bafdp->reading_frame = 4;
4834 bafdp->rnaType = NULL;
4835 }
4836 return bafdp;
4837 }
4838
BatchApplyFeatureDetailsToDialog(DialoG d,Pointer data)4839 static void BatchApplyFeatureDetailsToDialog (DialoG d, Pointer data)
4840 {
4841 BatchApplyFeatureDetailsDlgPtr dlg;
4842 BatchApplyFeatureDetailsPtr bafdp;
4843 ValNode vn;
4844
4845 dlg = (BatchApplyFeatureDetailsDlgPtr) GetObjectExtra (d);
4846 bafdp = (BatchApplyFeatureDetailsPtr) data;
4847
4848 if (dlg == NULL)
4849 {
4850 return;
4851 }
4852
4853 vn.next = NULL;
4854
4855 if (bafdp == NULL)
4856 {
4857 SafeSetTitle (dlg->defline, "");
4858 SafeSetTitle (dlg->geneName, "");
4859 SafeSetTitle (dlg->geneDesc, "");
4860 SafeSetTitle (dlg->protName, "");
4861 SafeSetTitle (dlg->protDesc, "");
4862 SafeSetTitle (dlg->rnaName, "");
4863 SafeSetTitle (dlg->featcomment, "");
4864 SafeSetValue (dlg->reading_frame, 4);
4865 if (dlg->featdef_choice_dlg != NULL)
4866 {
4867 vn.choice = FEATDEF_GENE;
4868 vn.data.ptrvalue = NULL;
4869 PointerToDialog (dlg->featdef_choice_dlg, &vn);
4870 }
4871 PointerToDialog (dlg->rnaType, NULL);
4872 }
4873 else
4874 {
4875 if (StringHasNoText (bafdp->defline))
4876 {
4877 SafeSetTitle (dlg->defline, "");
4878 }
4879 else
4880 {
4881 SafeSetTitle (dlg->defline, bafdp->defline);
4882 }
4883
4884 if (StringHasNoText (bafdp->geneName))
4885 {
4886 SafeSetTitle (dlg->geneName, "");
4887 }
4888 else
4889 {
4890 SafeSetTitle (dlg->geneName, bafdp->geneName);
4891 }
4892
4893 if (StringHasNoText (bafdp->protName))
4894 {
4895 SafeSetTitle (dlg->protName, "");
4896 }
4897 else
4898 {
4899 SafeSetTitle (dlg->protName, bafdp->protName);
4900 }
4901
4902 if (StringHasNoText (bafdp->protDesc))
4903 {
4904 SafeSetTitle (dlg->protDesc, "");
4905 }
4906 else
4907 {
4908 SafeSetTitle (dlg->protDesc, bafdp->protDesc);
4909 }
4910
4911 if (StringHasNoText (bafdp->rnaName))
4912 {
4913 SafeSetTitle (dlg->rnaName, "");
4914 }
4915 else
4916 {
4917 SafeSetTitle (dlg->rnaName, bafdp->rnaName);
4918 }
4919
4920 if (StringHasNoText (bafdp->featcomment))
4921 {
4922 SafeSetTitle (dlg->featcomment, "");
4923 }
4924 else
4925 {
4926 SafeSetTitle (dlg->featcomment, bafdp->featcomment);
4927 }
4928
4929 SafeSetValue (dlg->reading_frame, bafdp->reading_frame);
4930 if (dlg->featdef_choice_dlg != NULL)
4931 {
4932 vn.choice = bafdp->featdef_choice;
4933 vn.data.ptrvalue = NULL;
4934 PointerToDialog (dlg->featdef_choice_dlg, &vn);
4935 }
4936 PointerToDialog (dlg->rnaType, bafdp->rnaType);
4937 }
4938 if (dlg->change_notify != NULL)
4939 {
4940 (dlg->change_notify)(dlg->change_userdata);
4941 }
4942 }
4943
BatchApplyFeatureDetailsDialogToData(DialoG d)4944 static Pointer BatchApplyFeatureDetailsDialogToData (DialoG d)
4945 {
4946 BatchApplyFeatureDetailsDlgPtr dlg;
4947 BatchApplyFeatureDetailsPtr bafdp;
4948 ValNodePtr vnp;
4949
4950 dlg = (BatchApplyFeatureDetailsDlgPtr) GetObjectExtra (d);
4951 if (dlg == NULL)
4952 {
4953 return NULL;
4954 }
4955
4956 bafdp = BatchApplyFeatureDetailsNew ();
4957 if (bafdp == NULL)
4958 {
4959 return NULL;
4960 }
4961
4962 if (dlg->defline == NULL || TextHasNoText (dlg->defline))
4963 {
4964 bafdp->defline = NULL;
4965 }
4966 else
4967 {
4968 bafdp->defline = SaveStringFromTextAndStripNewlines (dlg->defline);
4969 }
4970
4971 if (dlg->geneName == NULL || TextHasNoText (dlg->geneName))
4972 {
4973 bafdp->geneName = NULL;
4974 }
4975 else
4976 {
4977 bafdp->geneName = SaveStringFromText (dlg->geneName);
4978 }
4979
4980 if (dlg->geneDesc == NULL || TextHasNoText (dlg->geneDesc))
4981 {
4982 bafdp->geneDesc = NULL;
4983 }
4984 else
4985 {
4986 bafdp->geneDesc = SaveStringFromText (dlg->geneDesc);
4987 }
4988
4989 if (dlg->protName == NULL || TextHasNoText (dlg->protName))
4990 {
4991 bafdp->protName = NULL;
4992 }
4993 else
4994 {
4995 bafdp->protName = SaveStringFromText (dlg->protName);
4996 }
4997
4998 if (dlg->protDesc == NULL || TextHasNoText (dlg->protDesc))
4999 {
5000 bafdp->protDesc = NULL;
5001 }
5002 else
5003 {
5004 bafdp->protDesc = SaveStringFromText (dlg->protDesc);
5005 }
5006
5007 if (dlg->rnaName == NULL || TextHasNoText (dlg->rnaName))
5008 {
5009 bafdp->rnaName = NULL;
5010 }
5011 else
5012 {
5013 bafdp->rnaName = SaveStringFromText (dlg->rnaName);
5014 }
5015
5016 if (dlg->featcomment == NULL || TextHasNoText (dlg->featcomment))
5017 {
5018 bafdp->featcomment = NULL;
5019 }
5020 else
5021 {
5022 bafdp->featcomment = SaveStringFromTextAndStripNewlines (dlg->featcomment);
5023 }
5024
5025 if (dlg->reading_frame == NULL)
5026 {
5027 bafdp->reading_frame = 4;
5028 }
5029 else
5030 {
5031 bafdp->reading_frame = GetValue (dlg->reading_frame);
5032 }
5033
5034 if (dlg->featdef_choice_dlg == NULL)
5035 {
5036 bafdp->featdef_choice = FEATDEF_GENE;
5037 }
5038 else
5039 {
5040 vnp = DialogToPointer (dlg->featdef_choice_dlg);
5041 if (vnp != NULL)
5042 {
5043 bafdp->featdef_choice = vnp->choice;
5044 bafdp->featdef_name = StringSave (vnp->data.ptrvalue);
5045 vnp = ValNodeFreeData (vnp);
5046 }
5047 else
5048 {
5049 bafdp->featdef_choice = FEATDEF_GENE;
5050 bafdp->featdef_name = StringSave ("Gene");
5051 }
5052 }
5053
5054 bafdp->rnaType = DialogToPointer (dlg->rnaType);
5055
5056 return bafdp;
5057 }
5058
BatchApplyFeatureDetailsMessage(DialoG d,Int2 mssg)5059 static void BatchApplyFeatureDetailsMessage (DialoG d, Int2 mssg)
5060
5061 {
5062 BatchApplyFeatureDetailsDlgPtr dlg;
5063
5064 dlg = (BatchApplyFeatureDetailsDlgPtr) GetObjectExtra (d);
5065 if (dlg != NULL) {
5066 switch (mssg) {
5067 case VIB_MSG_INIT :
5068 /* reset list */
5069 PointerToDialog (d, NULL);
5070 break;
5071 case VIB_MSG_ENTER :
5072 if (dlg->feattype == ADD_TITLE) {
5073 Select (dlg->defline);
5074 } else if (dlg->feattype == ADD_RRNA) {
5075 Select (dlg->rnaName);
5076 } else {
5077 Select (dlg->geneName);
5078 }
5079 break;
5080 default :
5081 break;
5082 }
5083 }
5084 }
5085
5086 /* This section of code is used for managing lists of features.
5087 * Sometimes the features will be displayed alphabetically, sometimes
5088 * they will be displayed alphabetically with a list of the most used features
5089 * also appearing at the top of the list.
5090 */
5091
5092 /* This is used to compare feature names with the special alphabetical order */
CompareFeatureNames(CharPtr cp1,CharPtr cp2)5093 static int CompareFeatureNames (CharPtr cp1, CharPtr cp2)
5094 {
5095 /* NULL name goes at the end */
5096 if (cp1 == NULL && cp2 == NULL) return 0;
5097 if (cp1 == NULL) return 1;
5098 if (cp2 == NULL) return -1;
5099
5100 /* starts with a space goes at the beginning */
5101 if (cp1 [0] == ' ' && cp2 [0] == ' ') return 0;
5102 if (cp1 [0] == ' ') return -1;
5103 if (cp2 [0] == ' ') return 1;
5104
5105 /* Is "All" or [ALL FEATURES] goes at the beginning */
5106 if ((StringCmp (cp1, "All") == 0
5107 || StringCmp (cp1, "[ALL FEATURES]") == 0)
5108 && (StringCmp (cp2, "All") == 0
5109 || StringCmp (cp2, "[ALL FEATURES]") == 0))
5110 {
5111 return 0;
5112 }
5113 if (StringCmp (cp1, "All") == 0
5114 || StringCmp (cp1, "[ALL FEATURES]") == 0)
5115 {
5116 return -1;
5117 }
5118 if (StringCmp (cp2, "All") == 0
5119 || StringCmp (cp2, "[ALL FEATURES]") == 0)
5120 {
5121 return 1;
5122 }
5123
5124 /* starts with a number -> goes at the end */
5125 if (cp1 [0] >= '0' && cp1 [0] <= '9'
5126 && cp2 [0] >= '0' && cp2 [0] <= '9')
5127 {
5128 return StringICmp (cp1, cp2);
5129 }
5130 if (cp1 [0] >= '0' && cp1 [0] <= '9')
5131 {
5132 return 1;
5133 }
5134 if (cp2 [0] >= '0' && cp2 [0] <= '9')
5135 {
5136 return -1;
5137 }
5138
5139 /* starts with a tilde or dash - sort with other tildes, put before numbers after alphas */
5140 if (cp1 [0] == '~' && cp2 [0] == '~')
5141 {
5142 return StringICmp (cp1 + 1, cp2 + 1);
5143 }
5144 if (cp1 [0] == '~') return 1;
5145 if (cp2 [0] == '~') return -1;
5146
5147 if (cp1 [0] == '-' && cp2 [0] == '-')
5148 {
5149 return StringICmp (cp1 + 1, cp2 + 1);
5150 }
5151 if (cp1 [0] == '-') return 1;
5152 if (cp2 [0] == '-') return -1;
5153
5154 return StringICmp (cp1, cp2);
5155 }
5156
CompareFeatureValNodeStrings(VoidPtr ptr1,VoidPtr ptr2)5157 extern int LIBCALLBACK CompareFeatureValNodeStrings (VoidPtr ptr1, VoidPtr ptr2)
5158 {
5159 ValNodePtr vnp1, vnp2;
5160
5161 if (ptr1 == NULL || ptr2 == NULL) return 0;
5162
5163 vnp1 = *((ValNodePtr PNTR) ptr1);
5164 vnp2 = *((ValNodePtr PNTR) ptr2);
5165
5166 if (vnp1 == NULL || vnp2 == NULL) return 0;
5167
5168 return CompareFeatureNames (vnp1->data.ptrvalue, vnp2->data.ptrvalue);
5169 }
5170
CompareImpFeatEnumFieldAssoc(VoidPtr ptr1,VoidPtr ptr2)5171 extern int LIBCALLBACK CompareImpFeatEnumFieldAssoc (VoidPtr ptr1, VoidPtr ptr2)
5172 {
5173 ValNodePtr vnp1, vnp2;
5174 EnumFieldAssocPtr ap1, ap2;
5175
5176 if (ptr1 == NULL || ptr2 == NULL) return 0;
5177
5178 vnp1 = *((ValNodePtr PNTR) ptr1);
5179 vnp2 = *((ValNodePtr PNTR) ptr2);
5180 if (vnp1 == NULL || vnp2 == NULL) return 0;
5181
5182 ap1 = (EnumFieldAssocPtr) vnp1->data.ptrvalue;
5183 ap2 = (EnumFieldAssocPtr) vnp2->data.ptrvalue;
5184 if (ap1 == NULL || ap2 == NULL) return 0;
5185
5186 return CompareFeatureNames (ap1->name, ap2->name);
5187 }
5188
SortEnumFieldAssocPtrArray(EnumFieldAssocPtr alist,CompareFunc compar)5189 extern void SortEnumFieldAssocPtrArray (EnumFieldAssocPtr alist, CompareFunc compar)
5190 {
5191 ValNodePtr head, vnp;
5192 EnumFieldAssocPtr ap;
5193 Int4 index;
5194
5195 /* first, create ValNode list so we can sort the data */
5196 head = NULL;
5197 for (ap = alist; ap != NULL && ap->name != NULL; ap++)
5198 {
5199 vnp = ValNodeNew (head);
5200 if (vnp == NULL) return;
5201 vnp->data.ptrvalue = MemNew (sizeof (EnumFieldAssoc));
5202 if (vnp->data.ptrvalue == NULL) return;
5203 MemCpy (vnp->data.ptrvalue, ap, sizeof (EnumFieldAssoc));
5204 if (head == NULL) head = vnp;
5205 }
5206
5207 /* Now sort the ValNode list */
5208 head = SortValNode (head, compar);
5209
5210 /* Now repopulate the EnumFieldAssoc list */
5211 index = 0;
5212 for (vnp = head; vnp != NULL; vnp = vnp->next)
5213 {
5214 MemCpy (alist + index++, vnp->data.ptrvalue, sizeof (EnumFieldAssoc));
5215 }
5216
5217 /* And free the ValNode list */
5218 ValNodeFreeData (head);
5219 }
5220
AddTextToComment(ButtoN b,CharPtr text)5221 static void AddTextToComment (ButtoN b, CharPtr text)
5222 {
5223 BatchApplyFeatureDetailsDlgPtr dlg;
5224 CharPtr orig_comment;
5225 CharPtr new_comment;
5226 RnaTypeData rtd;
5227
5228 dlg = (BatchApplyFeatureDetailsDlgPtr) GetObjectExtra (b);
5229 if (dlg == NULL || StringHasNoText (text))
5230 {
5231 return;
5232 }
5233
5234 orig_comment = SaveStringFromText (dlg->featcomment);
5235 if (StringHasNoText (orig_comment))
5236 {
5237 SetTitle (dlg->featcomment, text);
5238 }
5239 else
5240 {
5241 new_comment = (CharPtr) MemNew ((StringLen (orig_comment) + StringLen (text) + 3) * sizeof (Char));
5242 if (new_comment != NULL)
5243 {
5244 StringCpy (new_comment, orig_comment);
5245 StringCat (new_comment, "; ");
5246 StringCat (new_comment, text);
5247 SetTitle (dlg->featcomment, new_comment);
5248 new_comment = MemFree (new_comment);
5249 }
5250 }
5251 orig_comment = MemFree (orig_comment);
5252
5253 rtd.ncrna_class = NULL;
5254 rtd.rna_featdef = FEATDEF_misc_RNA;
5255 PointerToDialog (dlg->rnaType, &rtd);
5256 }
5257
Add18SITS28SToComment(ButtoN b)5258 static void Add18SITS28SToComment (ButtoN b)
5259 {
5260 AddTextToComment (b, "contains 18S ribosomal RNA, internal transcribed spacer 1, 5.8S ribosomal RNA, internal transcribed spacer 2, and 28S ribosomal RNA");
5261 }
5262
Add16SIGS23SToComment(ButtoN b)5263 static void Add16SIGS23SToComment (ButtoN b)
5264 {
5265 AddTextToComment (b, "contains 16S ribosomal RNA, 16S-23S ribosomal RNA intergenic spacer, and 23S ribosomal RNA");
5266 }
5267
5268
OkToAcceptBatchApplyFeatureDetails(DialoG d)5269 extern Boolean OkToAcceptBatchApplyFeatureDetails (DialoG d)
5270 {
5271 BatchApplyFeatureDetailsDlgPtr dlg;
5272 ValNodePtr vnp;
5273 Boolean rval = TRUE;
5274
5275 dlg = (BatchApplyFeatureDetailsDlgPtr) GetObjectExtra (d);
5276 if (dlg == NULL) return FALSE;
5277
5278 if (dlg->feattype == ADD_IMP)
5279 {
5280 vnp = DialogToPointer (dlg->featdef_choice_dlg);
5281 if (vnp == NULL)
5282 {
5283 rval = FALSE;
5284 }
5285 vnp = ValNodeFree (vnp);
5286 }
5287 return rval;
5288 }
5289
5290 extern DialoG
BatchApplyFeatureDetailsDialog(GrouP parent,Int4 feattype,Nlm_ChangeNotifyProc change_notify,Pointer change_userdata)5291 BatchApplyFeatureDetailsDialog (GrouP parent, Int4 feattype, Nlm_ChangeNotifyProc change_notify, Pointer change_userdata)
5292 {
5293 BatchApplyFeatureDetailsDlgPtr dlg;
5294 GrouP p, r = NULL, text_group = NULL, comment_btns_grp = NULL;
5295 ButtoN comment_btn;
5296 Nlm_EnumFieldAssocPtr ap;
5297 Int4 j;
5298 Boolean is_indexer = FALSE;
5299 RnaTypeData rtd;
5300
5301 dlg = (BatchApplyFeatureDetailsDlgPtr) MemNew (sizeof (BatchApplyFeatureDetailsDlgData));
5302 if (dlg == NULL)
5303 {
5304 return NULL;
5305 }
5306
5307 if (GetAppProperty ("InternalNcbiSequin") != NULL)
5308 {
5309 is_indexer = TRUE;
5310 }
5311
5312 p = HiddenGroup (parent, -1, 0, NULL);
5313 SetGroupSpacing (p, 10, 10);
5314 SetObjectExtra (p, dlg, StdCleanupExtraProc);
5315
5316 dlg->dialog = (DialoG) p;
5317 dlg->todialog = BatchApplyFeatureDetailsToDialog;
5318 dlg->fromdialog = BatchApplyFeatureDetailsDialogToData;
5319 dlg->dialogmessage = NULL;
5320 dlg->testdialog = NULL;
5321
5322 dlg->feattype = feattype;
5323
5324 dlg->change_notify = change_notify;
5325 dlg->change_userdata = change_userdata;
5326
5327 /* codon start controls */
5328 if (dlg->feattype == ADD_CDS)
5329 {
5330 r = HiddenGroup (p, 2, 0, NULL);
5331 StaticPrompt (r, "Codon Start", 0, dialogTextHeight, programFont, 'l');
5332 dlg->reading_frame = PopupList (r, TRUE, NULL);
5333 PopupItem (dlg->reading_frame, "1");
5334 PopupItem (dlg->reading_frame, "2");
5335 PopupItem (dlg->reading_frame, "3");
5336 PopupItem (dlg->reading_frame, "Best");
5337 SetValue (dlg->reading_frame, 4);
5338 }
5339 else if (dlg->feattype == ADD_RRNA)
5340 {
5341 dlg->rnaType = RnaTypeDialog (p, FALSE, change_notify, change_userdata);
5342 rtd.ncrna_class = NULL;
5343 rtd.rna_featdef = FEATDEF_rRNA;
5344 PointerToDialog (dlg->rnaType, &rtd);
5345 }
5346
5347 text_group = HiddenGroup (p, 0, 2, NULL);
5348 if (dlg->feattype == ADD_TITLE) {
5349 StaticPrompt (text_group, "Title", 0, 0, programFont, 'c');
5350 dlg->defline = ScrollText (text_group, 20, 4, programFont, TRUE, NULL);
5351 } else {
5352 text_group = HiddenGroup (p, 2, 0, NULL);
5353 if (dlg->feattype == ADD_CDS) {
5354 StaticPrompt (text_group, "Gene Symbol", 0, dialogTextHeight, programFont, 'l');
5355 dlg->geneName = DialogText (text_group, "", 20, NULL);
5356 if (is_indexer)
5357 {
5358 StaticPrompt (text_group, "Gene Description", 0, dialogTextHeight, programFont, 'l');
5359 dlg->geneDesc = DialogText (text_group, "", 20, NULL);
5360 }
5361
5362 StaticPrompt (text_group, "Protein Name", 0, dialogTextHeight, programFont, 'l');
5363 dlg->protName = DialogText (text_group, "", 20, NULL);
5364 StaticPrompt (text_group, "Protein Description", 0, dialogTextHeight, programFont, 'l');
5365 dlg->protDesc = DialogText (text_group, "", 20, NULL);
5366 } else if (dlg->feattype == ADD_RRNA) {
5367 StaticPrompt (text_group, "RNA Name", 0, dialogTextHeight, programFont, 'l');
5368 dlg->rnaName = DialogText (text_group, "", 20, NULL);
5369 StaticPrompt (text_group, "Gene Symbol", 0, dialogTextHeight, programFont, 'l');
5370 dlg->geneName = DialogText (text_group, "", 20, NULL);
5371 if (is_indexer)
5372 {
5373 StaticPrompt (text_group, "Gene Description", 0, dialogTextHeight, programFont, 'l');
5374 dlg->geneDesc = DialogText (text_group, "", 20, NULL);
5375 }
5376 } else if (dlg->feattype == ADD_IMP) {
5377 StaticPrompt (text_group, "Type", 0, 6 * Nlm_stdLineHeight, programFont, 'l');
5378 ap = import_featdef_alist (FALSE, FALSE, FALSE);
5379 SortEnumFieldAssocPtrArray (ap, CompareImpFeatEnumFieldAssoc);
5380 /* replace first item with Gene */
5381 ap [0].name = MemFree (ap [0].name);
5382 ap [0].name = StringSave ("Gene");
5383 ap [0].value = FEATDEF_GENE;
5384
5385 dlg->featdef_choice_dlg = EnumAssocSelectionDialog (text_group, ap,
5386 "feat_detail",
5387 FALSE, dlg->change_notify, dlg->change_userdata);
5388 /* clean up enumassoc list - not needed any more */
5389 for (j = 0; ap [j].name != NULL; j++) {
5390 MemFree (ap [j].name);
5391 }
5392 MemFree (ap);
5393
5394 StaticPrompt (text_group, "Gene Symbol", 0, dialogTextHeight, programFont, 'l');
5395 dlg->geneName = DialogText (text_group, "", 20, NULL);
5396 if (is_indexer)
5397 {
5398 StaticPrompt (text_group, "Gene Description", 0, dialogTextHeight, programFont, 'l');
5399 dlg->geneDesc = DialogText (text_group, "", 20, NULL);
5400 }
5401 }
5402 StaticPrompt (text_group, "Comment", 0, 4 * Nlm_stdLineHeight, programFont, 'l');
5403 dlg->featcomment = ScrollText (text_group, 20, 4, programFont, TRUE, NULL);
5404
5405 }
5406
5407 if (dlg->feattype == ADD_RRNA && is_indexer)
5408 {
5409 comment_btns_grp = HiddenGroup (p, 2, 0, NULL);
5410 comment_btn = PushButton (comment_btns_grp, "Add '18S-ITS-5.8S-ITS-28S' to comment", Add18SITS28SToComment);
5411 SetObjectExtra (comment_btn, dlg, NULL);
5412 comment_btn = PushButton (comment_btns_grp, "Add '16S-IGS-23S' to comment", Add16SIGS23SToComment);
5413 SetObjectExtra (comment_btn, dlg, NULL);
5414 }
5415
5416 AlignObjects (ALIGN_CENTER, (HANDLE) text_group, (HANDLE) r, (HANDLE) comment_btns_grp, NULL);
5417
5418 return (DialoG) p;
5419 }
5420
5421 typedef struct alreadyhas {
5422 Boolean rsult;
5423 Uint1 featchoice;
5424 Uint1 descchoice;
5425 Uint1 rnatype;
5426 } AlreadyHas, PNTR AlreadyHasPtr;
5427
SeeIfAlreadyHasGatherFunc(GatherContextPtr gcp)5428 static Boolean SeeIfAlreadyHasGatherFunc (GatherContextPtr gcp)
5429
5430 {
5431 AlreadyHasPtr ahp;
5432 RnaRefPtr rrp;
5433 ValNodePtr sdp;
5434 SeqFeatPtr sfp;
5435
5436 if (gcp == NULL) return TRUE;
5437
5438 ahp = (AlreadyHasPtr) gcp->userdata;
5439 if (ahp == NULL ) return TRUE;
5440
5441 if (gcp->thistype == OBJ_SEQFEAT && ahp->featchoice != 0) {
5442 sfp = (SeqFeatPtr) gcp->thisitem;
5443 if (sfp != NULL && sfp->data.choice == ahp->featchoice && sfp->data.value.ptrvalue != NULL) {
5444 if (sfp->data.choice == SEQFEAT_RNA) {
5445 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
5446 if (rrp->type != ahp->rnatype) return TRUE;
5447 }
5448 ahp->rsult = TRUE;
5449 return FALSE;
5450 }
5451 } else if (gcp->thistype == OBJ_SEQDESC && ahp->descchoice != 0) {
5452 sdp = (ValNodePtr) gcp->thisitem;
5453 if (sdp != NULL && sdp->choice == ahp->descchoice && sdp->data.ptrvalue != NULL) {
5454 ahp->rsult = TRUE;
5455 return FALSE;
5456 }
5457 }
5458 return TRUE;
5459 }
5460
AlreadyHasFeatOrDesc(SeqEntryPtr sep,Uint1 featchoice,Uint1 descchoice,Uint1 rnatype)5461 static Boolean AlreadyHasFeatOrDesc (SeqEntryPtr sep, Uint1 featchoice, Uint1 descchoice, Uint1 rnatype)
5462
5463 {
5464 AlreadyHas ah;
5465 BioseqPtr bsp;
5466 GatherScope gs;
5467 SeqEntryPtr nsep;
5468 SeqIdPtr sip;
5469 SeqLocPtr slp;
5470
5471 ah.rsult = FALSE;
5472 ah.featchoice = featchoice;
5473 ah.descchoice = descchoice;
5474 ah.rnatype = rnatype;
5475 if (sep == NULL) return FALSE;
5476 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
5477 gs.seglevels = 1;
5478 gs.get_feats_location = TRUE;
5479 MemSet ((Pointer) (gs.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
5480 gs.ignore[OBJ_BIOSEQ] = FALSE;
5481 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
5482 gs.ignore[OBJ_SEQFEAT] = FALSE;
5483 gs.ignore[OBJ_SEQDESC] = FALSE;
5484 gs.ignore[OBJ_SEQANNOT] = FALSE;
5485 gs.scope = sep;
5486 if (descchoice != 0) {
5487 nsep = FindNucSeqEntry (sep);
5488 if (nsep != NULL && IS_Bioseq (nsep)) {
5489 bsp = (BioseqPtr) nsep->data.ptrvalue;
5490 if (bsp != NULL) {
5491 slp = ValNodeNew (NULL);
5492 slp->choice = SEQLOC_WHOLE;
5493 sip = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0)));
5494 slp->data.ptrvalue = sip;
5495 gs.target = slp;
5496 }
5497 }
5498 }
5499 GatherSeqEntry (sep, (Pointer) (&ah), SeeIfAlreadyHasGatherFunc, &gs);
5500 gs.target = SeqLocFree (gs.target);
5501 return ah.rsult;
5502 }
5503
AddGeneXrefToFeat(SeqFeatPtr sfp,CharPtr str)5504 static void AddGeneXrefToFeat (SeqFeatPtr sfp, CharPtr str)
5505 {
5506 SeqFeatXrefPtr xref;
5507 GeneRefPtr grp;
5508
5509 if (sfp == NULL || StringHasNoText (str)) return;
5510
5511 /* add gene xref to feature */
5512 xref = SeqFeatXrefNew ();
5513 if (xref != NULL)
5514 {
5515 grp = CreateNewGeneRef (str, NULL, NULL, FALSE);
5516 if (grp != NULL)
5517 {
5518 xref->data.choice = SEQFEAT_GENE;
5519 xref->data.value.ptrvalue = grp;
5520 xref->next = sfp->xref;
5521 sfp->xref = xref;
5522 }
5523 }
5524 }
5525
ApplyGene(CharPtr gene_name,BatchApplyFeatureDetailsPtr feature_details_data,SeqEntryPtr gene_sep,SeqFeatPtr sfp,SeqLocPtr slp)5526 static SeqFeatPtr ApplyGene
5527 (CharPtr gene_name,
5528 BatchApplyFeatureDetailsPtr feature_details_data,
5529 SeqEntryPtr gene_sep,
5530 SeqFeatPtr sfp,
5531 SeqLocPtr slp)
5532 {
5533 GeneRefPtr grp;
5534 SeqFeatPtr gene_sfp;
5535 SeqFeatXrefPtr xref;
5536 SeqMgrFeatContext fcontext;
5537 BioseqPtr bsp = NULL;
5538 SeqFeatPtr other_feat;
5539 SeqFeatPtr overlap_gene;
5540 Boolean added_xrefs = FALSE;
5541 SeqFeatPtr misc_feat = NULL;
5542 SeqLocPtr overlap_loc;
5543 Boolean partial5, partial3;
5544
5545 if (feature_details_data == NULL || gene_sep == NULL || slp == NULL
5546 || (StringHasNoText (gene_name) && StringHasNoText (feature_details_data->geneDesc))) return NULL;
5547
5548 CheckSeqLocForPartial (slp, &partial5, &partial3);
5549
5550 /* we need a location to use when we're checking for feature-stealing genes */
5551 if (sfp != NULL)
5552 {
5553 overlap_loc = sfp->location;
5554 }
5555 else
5556 {
5557 misc_feat = CreateNewFeature (gene_sep, NULL, SEQFEAT_COMMENT, NULL);
5558 if (NULL == misc_feat)
5559 return NULL;
5560 misc_feat->location = SeqLocCopy (slp);
5561
5562 misc_feat->partial = (partial5 || partial3);
5563 overlap_loc = misc_feat->location;
5564 }
5565
5566 /* first, add gene xrefs to all features on bioseq that are contained in the location */
5567 /* maintain list of features that had xrefs before, should not remove them later */
5568 if (IS_Bioseq (gene_sep))
5569 {
5570 bsp = (BioseqPtr) gene_sep->data.ptrvalue;
5571 }
5572 else if (sfp != NULL)
5573 {
5574 bsp = BioseqFindFromSeqLoc (sfp->location);
5575 }
5576 if (bsp != NULL)
5577 {
5578 other_feat = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
5579 while (other_feat != NULL)
5580 {
5581 if (other_feat != sfp && other_feat->data.choice != SEQFEAT_GENE)
5582 {
5583 for (xref = other_feat->xref;
5584 xref != NULL && xref->data.choice != SEQFEAT_GENE;
5585 xref = xref->next)
5586 {}
5587 if (xref == NULL
5588 && SeqLocCompare (other_feat->location, overlap_loc) == SLC_A_EQ_B)
5589 {
5590 overlap_gene = SeqMgrGetOverlappingGene (other_feat->location, NULL);
5591 if (overlap_gene != NULL)
5592 {
5593 AddGeneXrefToFeat (other_feat, fcontext.label);
5594 added_xrefs = TRUE;
5595 }
5596 }
5597 }
5598 other_feat = SeqMgrGetNextFeature (bsp, other_feat, 0, 0, &fcontext);
5599 }
5600 }
5601
5602 if (misc_feat != NULL)
5603 {
5604 misc_feat->idx.deleteme = TRUE;
5605 DeleteMarkedObjects (0, OBJ_SEQENTRY, gene_sep);
5606 }
5607
5608 grp = CreateNewGeneRef (gene_name, NULL, feature_details_data->geneDesc, FALSE);
5609 if (NULL == grp)
5610 return NULL;
5611
5612 gene_sfp = CreateNewFeature (gene_sep, NULL, SEQFEAT_GENE, NULL);
5613 if (NULL == gene_sfp)
5614 return NULL;
5615
5616 gene_sfp->data.value.ptrvalue = (Pointer) grp;
5617 gene_sfp->location = slp;
5618 gene_sfp->partial = partial5 | partial3;
5619
5620 if (added_xrefs && sfp != NULL)
5621 {
5622 /* add gene xref to feature */
5623 AddGeneXrefToFeat (sfp, gene_name);
5624 }
5625
5626 return gene_sfp;
5627 }
5628
5629 static void
SetFrameForCodingRegion(SeqFeatPtr sfp,BioseqPtr bsp,BatchApplyFeatureDetailsPtr feature_details_data,Int4Ptr errcount,ValNodePtr PNTR ambigList)5630 SetFrameForCodingRegion
5631 (SeqFeatPtr sfp,
5632 BioseqPtr bsp,
5633 BatchApplyFeatureDetailsPtr feature_details_data,
5634 Int4Ptr errcount,
5635 ValNodePtr PNTR ambigList)
5636 {
5637 CdRegionPtr crp;
5638 ByteStorePtr bs;
5639 Uint1 frame;
5640 Int2 i;
5641 Int4 len;
5642 Int4 lens [4];
5643 Int4 max;
5644 Char str [128];
5645 SeqIdPtr sip;
5646
5647 if (sfp == NULL
5648 || sfp->data.choice != SEQFEAT_CDREGION
5649 || sfp->data.value.ptrvalue == NULL
5650 || bsp == NULL
5651 || feature_details_data == NULL
5652 || errcount == NULL || ambigList == NULL)
5653 {
5654 return;
5655 }
5656
5657 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
5658
5659 if (feature_details_data->reading_frame < 1
5660 || feature_details_data->reading_frame > 3)
5661 {
5662 max = 0;
5663 frame = 0;
5664 for (i = 1; i <= 3; i++) {
5665 crp->frame = (Uint1) i;
5666 bs = ProteinFromCdRegionEx (sfp, FALSE, FALSE);
5667 len = BSLen (bs);
5668 BSFree (bs);
5669 lens [i] = len;
5670 if (len > max) {
5671 max = len;
5672 frame = (Uint1) i;
5673 }
5674 }
5675 str [0] = '\0';
5676 sip = SeqIdFindBest (bsp->id, 0);
5677 SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str) - 1);
5678 for (i = 1; i <= 3; i++) {
5679 if (lens [i] == max && i != frame) {
5680 (*errcount)++;
5681 ValNodeCopyStr (ambigList, 0, str);
5682 }
5683 }
5684 crp->frame = frame;
5685 }
5686 else
5687 {
5688 crp->frame = feature_details_data->reading_frame;
5689 }
5690 }
5691
5692 static void
AddProductForCDS(SeqFeatPtr sfp,BatchApplyFeatureDetailsPtr feature_details_data,SeqEntryPtr sep,SeqEntryPtr nsep,Uint2 entityID)5693 AddProductForCDS
5694 (SeqFeatPtr sfp,
5695 BatchApplyFeatureDetailsPtr feature_details_data,
5696 SeqEntryPtr sep,
5697 SeqEntryPtr nsep,
5698 Uint2 entityID)
5699 {
5700 ByteStorePtr bs;
5701 Char ch;
5702 ValNodePtr descr;
5703 Int2 i;
5704 MolInfoPtr mip;
5705 SeqEntryPtr old;
5706 CharPtr prot;
5707 ProtRefPtr prp;
5708 SeqEntryPtr psep;
5709 CharPtr ptr;
5710 ValNodePtr vnp;
5711 SeqEntryPtr parent_sep;
5712 SeqFeatPtr prot_sfp;
5713 BioseqPtr bsp;
5714 Boolean partial5, partial3;
5715
5716 if (sfp == NULL
5717 || sfp->data.choice != SEQFEAT_CDREGION
5718 || feature_details_data == NULL
5719 || sep == NULL || nsep == NULL)
5720 {
5721 return;
5722 }
5723
5724 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
5725
5726 /* determine the parent of this sequence (for use when segmented) */
5727 parent_sep = NULL;
5728 if (IS_Bioseq (sep))
5729 {
5730 parent_sep = GetBestTopParentForData (entityID, sep->data.ptrvalue);
5731 }
5732 if (parent_sep == NULL)
5733 {
5734 parent_sep = sep;
5735 }
5736
5737 /* Create corresponding protein sequence data for the CDS */
5738
5739 bs = ProteinFromCdRegionEx (sfp, TRUE, FALSE);
5740 if (NULL == bs)
5741 return;
5742
5743 prot = BSMerge (bs, NULL);
5744 bs = BSFree (bs);
5745 if (NULL == prot)
5746 return;
5747
5748 ptr = prot;
5749 ch = *ptr;
5750 while (ch != '\0') {
5751 *ptr = TO_UPPER (ch);
5752 ptr++;
5753 ch = *ptr;
5754 }
5755 i = (Int2) StringLen (prot);
5756 if (i > 0 && prot [i - 1] == '*') {
5757 prot [i - 1] = '\0';
5758 }
5759 bs = BSNew (1000);
5760 if (bs != NULL) {
5761 ptr = prot;
5762 BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
5763 }
5764
5765 /* Create the product protein Bioseq */
5766
5767 bsp = BioseqNew ();
5768 if (NULL == bsp)
5769 return;
5770
5771 bsp->repr = Seq_repr_raw;
5772 bsp->mol = Seq_mol_aa;
5773 bsp->seq_data_type = Seq_code_ncbieaa;
5774 bsp->seq_data = (SeqDataPtr) bs;
5775 bsp->length = BSLen (bs);
5776 bs = NULL;
5777 old = SeqEntrySetScope (NULL);
5778 bsp->id = MakeNewProteinSeqId (sfp->location, NULL);
5779 SeqMgrAddToBioseqIndex (bsp);
5780 SeqEntrySetScope (old);
5781
5782 /* Create a new SeqEntry for the Prot Bioseq */
5783
5784 psep = SeqEntryNew ();
5785 if (NULL == psep)
5786 return;
5787
5788 psep->choice = 1;
5789 psep->data.ptrvalue = (Pointer) bsp;
5790 SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, psep);
5791
5792 /* Add a descriptor to the protein Bioseq */
5793
5794 mip = MolInfoNew ();
5795 if (NULL == mip)
5796 return;
5797
5798 mip->biomol = 8;
5799 mip->tech = 8;
5800 if (partial5 && partial3) {
5801 mip->completeness = 5;
5802 } else if (partial5) {
5803 mip->completeness = 3;
5804 } else if (partial3) {
5805 mip->completeness = 4;
5806 }
5807 vnp = CreateNewDescriptor (psep, Seq_descr_molinfo);
5808 if (NULL == vnp)
5809 return;
5810
5811 vnp->data.ptrvalue = (Pointer) mip;
5812
5813 /**/
5814
5815 descr = ExtractBioSourceAndPubs (parent_sep);
5816
5817 AddSeqEntryToSeqEntry (parent_sep, psep, TRUE);
5818 nsep = FindNucSeqEntry (parent_sep);
5819 ReplaceBioSourceAndPubs (parent_sep, descr);
5820 SetSeqFeatProduct (sfp, bsp);
5821
5822 /* create a full-length protein feature for the new protein sequence */
5823 if (! StringHasNoText (feature_details_data->protName)
5824 && ! StringHasNoText (feature_details_data->protDesc))
5825 {
5826 prp = CreateNewProtRef (feature_details_data->protName,
5827 feature_details_data->protDesc,
5828 NULL, NULL);
5829 }
5830 else if (!StringHasNoText (feature_details_data->protName))
5831 {
5832 prp = CreateNewProtRef (feature_details_data->protName, NULL, NULL, NULL);
5833 }
5834 else if (!StringHasNoText (feature_details_data->protDesc))
5835 {
5836 prp = CreateNewProtRef (NULL, feature_details_data->protDesc, NULL, NULL);
5837 }
5838 else
5839 {
5840 prp = ProtRefNew ();
5841 }
5842
5843 if (prp != NULL) {
5844 prot_sfp = CreateNewFeature (psep, NULL, SEQFEAT_PROT, NULL);
5845 if (prot_sfp != NULL) {
5846 prot_sfp->data.value.ptrvalue = (Pointer) prp;
5847 SetSeqLocPartial (prot_sfp->location, partial5, partial3);
5848 prot_sfp->partial = (partial5 || partial3);
5849 }
5850 }
5851 }
5852
5853
5854 static SeqFeatPtr
ApplyOneCodingRegion(BatchApplyFeatureDetailsPtr feature_details_data,BioseqPtr bsp,SeqEntryPtr sep,SeqEntryPtr nsep,Uint2 entityID,Boolean suppressDups)5855 ApplyOneCodingRegion
5856 (BatchApplyFeatureDetailsPtr feature_details_data,
5857 BioseqPtr bsp,
5858 SeqEntryPtr sep,
5859 SeqEntryPtr nsep,
5860 Uint2 entityID,
5861 Boolean suppressDups)
5862 {
5863 CdRegionPtr crp;
5864 Int2 genCode;
5865 SeqFeatPtr sfp;
5866 SeqEntryPtr parent_sep;
5867
5868 if (feature_details_data == NULL || sep == NULL || nsep == NULL)
5869 {
5870 return NULL;
5871 }
5872
5873 /* If necessary then check for duplication before adding */
5874 if (suppressDups &&
5875 entityID > 0 &&
5876 AlreadyHasFeatOrDesc (sep, SEQFEAT_CDREGION, 0, 0))
5877 return NULL;
5878
5879 /* determine the parent of this sequence (for use when segmented) */
5880 parent_sep = NULL;
5881 if (IS_Bioseq (sep))
5882 {
5883 parent_sep = GetBestTopParentForData (entityID, sep->data.ptrvalue);
5884 }
5885 if (parent_sep == NULL)
5886 {
5887 parent_sep = sep;
5888 }
5889
5890 /*Create a new CDS feature */
5891
5892 genCode = SeqEntryToGeneticCode (parent_sep, NULL, NULL, 0);
5893 crp = CreateNewCdRgn (1, FALSE, genCode);
5894 if (NULL == crp)
5895 return NULL;
5896
5897 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_CDREGION, NULL);
5898
5899 if (NULL == sfp)
5900 return NULL;
5901
5902 sfp->data.value.ptrvalue = (Pointer) crp;
5903
5904 return sfp;
5905 }
5906
5907
5908 typedef struct hasrna {
5909 Boolean hasrna;
5910 RnaTypePtr rtp;
5911 } HasRnaData, PNTR HasRnaPtr;
5912
AlreadyHasRNACallback(SeqFeatPtr sfp,Pointer userdata)5913 static void AlreadyHasRNACallback (SeqFeatPtr sfp, Pointer userdata)
5914 {
5915 HasRnaPtr hp;
5916
5917 if (sfp == NULL || sfp->data.choice != SEQFEAT_RNA || userdata == NULL)
5918 {
5919 return;
5920 }
5921
5922 hp = (HasRnaPtr) userdata;
5923
5924 if (!hp->hasrna && MatchesRnaType (sfp, hp->rtp))
5925 {
5926 hp->hasrna = TRUE;
5927 }
5928 }
5929
5930
AlreadyHasRNA(SeqEntryPtr sep,RnaTypePtr rtp)5931 extern Boolean AlreadyHasRNA (SeqEntryPtr sep, RnaTypePtr rtp)
5932 {
5933 HasRnaData hrd;
5934
5935 hrd.rtp = NULL;
5936 hrd.hasrna = FALSE;
5937 VisitFeaturesInSep (sep, &hrd, AlreadyHasRNACallback);
5938 return hrd.hasrna;
5939 }
5940
5941
ApplyOneRNA(BatchApplyFeatureDetailsPtr feature_details_data,SeqEntryPtr sep,SeqEntryPtr nsep,Uint2 entityID,Boolean suppressDups)5942 static SeqFeatPtr ApplyOneRNA
5943 (BatchApplyFeatureDetailsPtr feature_details_data,
5944 SeqEntryPtr sep,
5945 SeqEntryPtr nsep,
5946 Uint2 entityID,
5947 Boolean suppressDups)
5948 {
5949 RnaRefPtr rrp;
5950 SeqFeatPtr sfp;
5951
5952 if (feature_details_data == NULL || sep == NULL || nsep == NULL)
5953 {
5954 return NULL;
5955 }
5956
5957 if (suppressDups && entityID > 0 && AlreadyHasRNA (sep, feature_details_data->rnaType))
5958 {
5959 return NULL;
5960 }
5961
5962 rrp = RnaRefNew ();
5963 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_RNA, NULL);
5964 if (sfp != NULL) {
5965 sfp->data.value.ptrvalue = (Pointer) rrp;
5966 }
5967 ApplyRnaTypeToSeqFeat (sfp, feature_details_data->rnaType);
5968 if (! StringHasNoText (feature_details_data->rnaName)) {
5969 ApplyProductToRNA (sfp, feature_details_data->rnaName);
5970 }
5971
5972 return sfp;
5973 }
5974
GBQualListCopy(GBQualPtr gbqual_list)5975 static GBQualPtr GBQualListCopy (GBQualPtr gbqual_list)
5976 {
5977 GBQualPtr gbqual_orig, gbqual_newlist = NULL, gbqual_new = NULL;
5978
5979 gbqual_orig = gbqual_list;
5980 while (gbqual_orig != NULL)
5981 {
5982 if (gbqual_newlist == NULL)
5983 {
5984 gbqual_newlist = GBQualNew ();
5985 gbqual_new = gbqual_newlist;
5986 }
5987 else
5988 {
5989 gbqual_new->next = GBQualNew ();
5990 gbqual_new = gbqual_new->next;
5991 }
5992
5993 if (gbqual_new == NULL)
5994 {
5995 gbqual_orig = NULL;
5996 }
5997 else
5998 {
5999 gbqual_new->qual = StringSave (gbqual_orig->qual);
6000 gbqual_new->val = StringSave (gbqual_orig->val);
6001 gbqual_orig = gbqual_orig->next;
6002 }
6003 }
6004
6005 return gbqual_newlist;
6006 }
6007
ApplyOtherFeature(BatchApplyFeatureDetailsPtr feature_details_data,SeqEntryPtr nsep,GBQualPtr gbqual_list)6008 static SeqFeatPtr ApplyOtherFeature
6009 (BatchApplyFeatureDetailsPtr feature_details_data,
6010 SeqEntryPtr nsep,
6011 GBQualPtr gbqual_list)
6012 {
6013 ImpFeatPtr ifp;
6014 SeqFeatPtr sfp = NULL;
6015
6016 if (feature_details_data == NULL
6017 || nsep == NULL
6018 || feature_details_data->featdef_choice == FEATDEF_GENE)
6019 {
6020 return NULL;
6021 }
6022
6023 ifp = ImpFeatNew ();
6024 if (ifp == NULL)
6025 {
6026 return NULL;
6027 }
6028
6029 ifp->key = StringSave (feature_details_data->featdef_name);
6030 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_IMP, NULL);
6031 if (sfp != NULL) {
6032 sfp->data.value.ptrvalue = (Pointer) ifp;
6033 sfp->qual = GBQualListCopy (gbqual_list);
6034 }
6035 return sfp;
6036 }
6037
GetImpFeatureGBQuals(BatchApplyFeatureDetailsPtr feature_details_data)6038 static GBQualPtr GetImpFeatureGBQuals (BatchApplyFeatureDetailsPtr feature_details_data)
6039 {
6040 WindoW w;
6041 DialoG dlg;
6042 GrouP h, c;
6043 ButtoN b;
6044 ModalAcceptCancelData acd;
6045 GBQualPtr gbqual_list = NULL;
6046
6047 if (feature_details_data == NULL
6048 || feature_details_data->featdef_choice == FEATDEF_GENE)
6049 {
6050 return NULL;
6051 }
6052
6053 w = MovableModalWindow(-20, -13, -10, -10, "Qualifiers", NULL);
6054 h = HiddenGroup (w, -1, 0, NULL);
6055 SetGroupSpacing (h, 10, 10);
6056 dlg = CreateImportFields (h, feature_details_data->featdef_name, NULL, FALSE);
6057 c = HiddenGroup (h, 2, 0, NULL);
6058 b = PushButton(c, "OK", ModalAcceptButton);
6059 SetObjectExtra (b, &acd, NULL);
6060 b = PushButton(c, "Cancel", ModalCancelButton);
6061 SetObjectExtra (b, &acd, NULL);
6062 AlignObjects (ALIGN_CENTER, (HANDLE) dlg, (HANDLE) c, NULL);
6063 RealizeWindow (w);
6064 Show (w);
6065 Select (w);
6066 acd.accepted = FALSE;
6067 acd.cancelled = FALSE;
6068 while (!acd.accepted && ! acd.cancelled)
6069 {
6070 ProcessExternalEvent ();
6071 Update ();
6072 }
6073 ProcessAnEvent ();
6074
6075 if (acd.accepted)
6076 {
6077 gbqual_list = DialogToPointer (dlg);
6078 }
6079
6080 Remove (w);
6081
6082 return gbqual_list;
6083 }
6084
6085 typedef struct applyalignmentfeature
6086 {
6087 FORM_MESSAGE_BLOCK
6088 DialoG location_dlg;
6089 DialoG feature_details;
6090 ButtoN accept;
6091 ButtoN leave_dlg_up;
6092 SeqEntryPtr sep;
6093 SeqAlignPtr salp;
6094 Int4 feattype;
6095 Uint2 entityID;
6096 } ApplyAlignmentFeatureDlgData, PNTR ApplyAlignmentFeatureDlgPtr;
6097
6098 static Boolean
OkToContinueWithFeatureApply(SeqLocPtr seqloc_list,SeqAlignPtr salp)6099 OkToContinueWithFeatureApply
6100 (SeqLocPtr seqloc_list,
6101 SeqAlignPtr salp)
6102 {
6103 Int4 num_missing = 0, seq_num, start_num;
6104 SeqLocPtr slp;
6105 SeqIdPtr sip;
6106 Int4Ptr found_list;
6107 Boolean found_this;
6108 Int4 msg_len = 0;
6109 CharPtr msg_txt = NULL;
6110 CharPtr msg_start = "The following sequence(s) are all gaps at this position: ";
6111 CharPtr msg_end = ". Do you want to continue?";
6112 ValNodePtr id_list = NULL, id_vnp;
6113 Char id_txt [255];
6114 Boolean rval = TRUE;
6115 BioseqPtr bsp;
6116
6117 if (salp == NULL || seqloc_list == NULL)
6118 {
6119 return FALSE;
6120 }
6121
6122 found_list = (Int4Ptr) MemNew (salp->dim * sizeof (Int4));
6123 if (found_list == NULL)
6124 {
6125 return FALSE;
6126 }
6127
6128 for (seq_num = 1; seq_num <= salp->dim; seq_num++)
6129 {
6130 found_list [seq_num - 1] = 0;
6131 }
6132
6133 for (slp = seqloc_list, start_num = 1; slp != NULL; slp = slp->next, start_num++)
6134 {
6135 if (slp->choice == SEQLOC_NULL)
6136 {
6137 continue;
6138 }
6139 found_this = FALSE;
6140 if (start_num <= salp->dim)
6141 {
6142 sip = AlnMgr2GetNthSeqIdPtr (salp, start_num);
6143 if (SeqIdComp (sip, SeqLocId (slp)) == SIC_YES)
6144 {
6145 found_list [start_num - 1] = 1;
6146 found_this = TRUE;
6147 }
6148 }
6149
6150 for (seq_num = 1; seq_num <= salp->dim && ! found_this; seq_num++)
6151 {
6152 sip = AlnMgr2GetNthSeqIdPtr (salp, seq_num);
6153 if (SeqIdComp (sip, SeqLocId (slp)) == SIC_YES)
6154 {
6155 found_list [seq_num - 1] = 1;
6156 found_this = TRUE;
6157 }
6158 }
6159 }
6160
6161 for (seq_num = 1; seq_num <= salp->dim; seq_num++)
6162 {
6163 if (found_list [seq_num - 1] == 0)
6164 {
6165 sip = AlnMgr2GetNthSeqIdPtr (salp, seq_num);
6166 bsp = BioseqFind (sip);
6167 if (bsp != NULL && bsp->id != NULL)
6168 {
6169 sip = SeqIdFindBest (bsp->id, 0);
6170 }
6171 SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt));
6172 msg_len += StringLen (id_txt) + 3;
6173 ValNodeAddPointer (&id_list, 0, StringSave (id_txt));
6174 }
6175 }
6176
6177 if (msg_len > 0)
6178 {
6179 msg_len += StringLen (msg_start) + StringLen (msg_end);
6180 msg_txt = (CharPtr) MemNew (msg_len * sizeof (Char));
6181 if (msg_txt != NULL)
6182 {
6183 StringCpy (msg_txt, msg_start);
6184 for (id_vnp = id_list; id_vnp != NULL; id_vnp = id_vnp->next)
6185 {
6186 StringCat (msg_txt, id_vnp->data.ptrvalue);
6187 if (id_vnp->next != NULL)
6188 {
6189 StringCat (msg_txt, ", ");
6190 }
6191 }
6192 StringCat (msg_txt, msg_end);
6193 if (ANS_NO == Message (MSG_YN, msg_txt))
6194 {
6195 rval = FALSE;
6196 }
6197 msg_txt = MemFree (msg_txt);
6198 }
6199 }
6200 id_list = ValNodeFreeData (id_list);
6201 found_list = MemFree (found_list);
6202
6203 return rval;
6204 }
6205
DoApplyFeatureToAlignment(ButtoN b)6206 static void DoApplyFeatureToAlignment (ButtoN b)
6207 {
6208 ApplyAlignmentFeatureDlgPtr aafdp;
6209 BatchApplyFeatureDetailsPtr feature_details_data;
6210 SeqLocPtr seqloc_list, slp_next, slp_this, gene_slp;
6211 Int4 errcount = 0;
6212 ValNodePtr ambigList = NULL;
6213 Boolean suppressDups = FALSE;
6214 Boolean partial5, partial3;
6215 SeqEntryPtr sep, nsep, gene_sep;
6216 BioseqPtr bsp;
6217 SeqFeatPtr sfp, gene_sfp;
6218 GBQualPtr gbqual_list = NULL;
6219 Boolean found_null = FALSE;
6220
6221 aafdp = (ApplyAlignmentFeatureDlgPtr) GetObjectExtra (b);
6222 if (aafdp == NULL)
6223 {
6224 return;
6225 }
6226
6227 feature_details_data = (BatchApplyFeatureDetailsPtr) DialogToPointer (aafdp->feature_details);
6228 seqloc_list = (SeqLocPtr) DialogToPointer (aafdp->location_dlg);
6229
6230 if (! OkToContinueWithFeatureApply (seqloc_list, aafdp->salp))
6231 {
6232 /* Free data and loclist */
6233 feature_details_data = BatchApplyFeatureDetailsFree (feature_details_data);
6234 slp_this = seqloc_list;
6235 while (slp_this != NULL)
6236 {
6237 slp_next = slp_this->next;
6238 slp_this->next = NULL;
6239 slp_this = SeqLocFree (slp_this);
6240 slp_this = slp_next;
6241 }
6242 return;
6243 }
6244
6245 if (feature_details_data == NULL || seqloc_list == NULL)
6246 {
6247 /* Free data and loclist */
6248 feature_details_data = BatchApplyFeatureDetailsFree (feature_details_data);
6249 slp_this = seqloc_list;
6250 while (slp_this != NULL)
6251 {
6252 slp_next = slp_this->next;
6253 slp_this->next = NULL;
6254 slp_this = SeqLocFree (slp_this);
6255 slp_this = slp_next;
6256 }
6257 return;
6258 }
6259
6260 if (aafdp->feattype == ADD_IMP)
6261 {
6262 gbqual_list = GetImpFeatureGBQuals (feature_details_data);
6263 }
6264
6265 slp_this = seqloc_list;
6266 while (slp_this != NULL)
6267 {
6268 slp_next = slp_this->next;
6269 slp_this->next = NULL;
6270 sfp = NULL;
6271
6272 bsp = BioseqFindFromSeqLoc (slp_this);
6273 sep = SeqMgrGetSeqEntryForData (bsp);
6274
6275 if (sep != NULL)
6276 {
6277 nsep = FindNucSeqEntry (sep);
6278 if (nsep != NULL)
6279 {
6280 if (aafdp->feattype == ADD_CDS)
6281 {
6282 sfp = ApplyOneCodingRegion (feature_details_data, bsp, sep, nsep,
6283 aafdp->entityID, suppressDups);
6284 }
6285 else if (aafdp->feattype == ADD_RRNA)
6286 {
6287 sfp = ApplyOneRNA (feature_details_data, sep, nsep,
6288 aafdp->entityID, suppressDups);
6289 }
6290 else if (aafdp->feattype == ADD_IMP)
6291 {
6292 sfp = ApplyOtherFeature (feature_details_data, nsep, gbqual_list);
6293 }
6294 }
6295 }
6296 if (sfp != NULL)
6297 {
6298 /* set location */
6299 sfp->location = SeqLocFree (sfp->location);
6300 sfp->location = slp_this;
6301 CheckSeqLocForPartial (slp_this, &partial5, &partial3);
6302 sfp->partial = partial5 || partial3;
6303
6304 if (aafdp->feattype == ADD_CDS)
6305 {
6306 SetFrameForCodingRegion (sfp, bsp, feature_details_data,
6307 &errcount, &ambigList);
6308 AddProductForCDS (sfp, feature_details_data, sep, nsep, aafdp->entityID);
6309 }
6310 else if (aafdp->feattype == ADD_RRNA)
6311 {
6312 /* ConvertToOldRNAFormat (sfp); */
6313 }
6314 }
6315
6316 if (sfp != NULL
6317 || (aafdp->feattype == ADD_IMP
6318 && feature_details_data->featdef_choice == FEATDEF_GENE
6319 && sep != NULL))
6320 {
6321 if (! StringHasNoText (feature_details_data->geneName) || ! StringHasNoText (feature_details_data->geneDesc))
6322 {
6323 /* Create a Gene ref feature on the nuc seq or segment */
6324 /* we can only create a feature where the sep->choice is 1 */
6325 if (sep->choice == 1)
6326 {
6327 gene_sep = sep;
6328 }
6329 else
6330 {
6331 /* if we have added a product, nsep may no longer point to the nucseq entry */
6332 gene_sep = FindNucSeqEntry (sep);
6333 }
6334
6335 if (aafdp->entityID > 0
6336 && suppressDups
6337 && AlreadyHasFeatOrDesc (gene_sep, SEQFEAT_GENE, 0, 0))
6338 {
6339 /* do not create */
6340 }
6341 else
6342 {
6343 CheckSeqLocForPartial (slp_this, &partial5, &partial3);
6344
6345 if (sfp == NULL)
6346 {
6347 gene_slp = slp_this;
6348 }
6349 else
6350 {
6351 gene_slp = SeqLocMerge (bsp, slp_this, NULL, TRUE, FALSE, FALSE);
6352 SetSeqLocPartial (gene_slp, partial5, partial3);
6353 }
6354 gene_sfp = ApplyGene (feature_details_data->geneName,
6355 feature_details_data,
6356 gene_sep, sfp, gene_slp);
6357 gene_sfp->partial = partial5 || partial3;
6358
6359 if (sfp == NULL)
6360 {
6361 sfp = gene_sfp;
6362 }
6363 }
6364 }
6365 }
6366
6367 if (sfp == NULL)
6368 {
6369 /* remove location that will not be used */
6370 slp_this = SeqLocFree (slp_this);
6371 }
6372 else
6373 {
6374 /* add comment */
6375 AddToComment (sfp, feature_details_data->featcomment);
6376 }
6377
6378 slp_this = slp_next;
6379 }
6380
6381 feature_details_data = BatchApplyFeatureDetailsFree (feature_details_data);
6382
6383 /* free gbqual_list */
6384 gbqual_list = GBQualFree (gbqual_list);
6385
6386 ObjMgrSetDirtyFlag (aafdp->entityID, TRUE);
6387 ObjMgrSendMsg (OM_MSG_UPDATE, aafdp->entityID, 0, 0);
6388
6389 if (!GetStatus (aafdp->leave_dlg_up))
6390 {
6391 Remove (aafdp->form);
6392 }
6393 }
6394
6395
EnableApplyFeatureAccept(Pointer data)6396 static void EnableApplyFeatureAccept (Pointer data)
6397 {
6398 ApplyAlignmentFeatureDlgPtr aafdp;
6399
6400 aafdp = (ApplyAlignmentFeatureDlgPtr) data;
6401 if (aafdp == NULL) return;
6402
6403 if (OkToAcceptBatchApplyFeatureDetails (aafdp->feature_details))
6404 {
6405 Enable (aafdp->accept);
6406 }
6407 else
6408 {
6409 Disable (aafdp->accept);
6410 }
6411 }
6412
6413
ApplyFeatureToAlignment(Uint2 entityID,SeqAlignPtr salp,SeqLocPtr slp,Int4 feattype)6414 extern void ApplyFeatureToAlignment (Uint2 entityID, SeqAlignPtr salp, SeqLocPtr slp, Int4 feattype)
6415 {
6416 ApplyAlignmentFeatureDlgPtr aafdp;
6417 WindoW w;
6418 GrouP h, c;
6419 Boolean nucsOK = TRUE; /* LATER, figure out whether alignment */
6420 Boolean protsOK = TRUE; /* contains nucs or prots */
6421 ButtoN b;
6422
6423 aafdp = (ApplyAlignmentFeatureDlgPtr) MemNew (sizeof (ApplyAlignmentFeatureDlgData));
6424 if (aafdp == NULL) return;
6425
6426 aafdp->sep = GetTopSeqEntryForEntityID (entityID);
6427 if (aafdp->sep == NULL)
6428 {
6429 aafdp = MemFree (aafdp);
6430 return;
6431 }
6432 aafdp->entityID = entityID;
6433 aafdp->feattype = feattype;
6434 aafdp->salp = salp;
6435
6436 w = FixedWindow (-50, -33, -10, -10, "Apply Features to Alignment", StdCloseWindowProc);
6437 SetObjectExtra (w, aafdp, StdCleanupExtraProc);
6438 SetObjectExtra (w, aafdp, NULL);
6439 aafdp->form = (ForM) w;
6440 aafdp->input_entityID = entityID;
6441
6442 h = HiddenGroup (w, -1, 0, NULL);
6443 SetGroupSpacing (h, 10, 10);
6444
6445 aafdp->location_dlg = CreateIntervalEditorDialogExEx (h, "Location",
6446 4, 2, aafdp->sep,
6447 nucsOK, protsOK,
6448 TRUE, TRUE, TRUE, NULL, NULL,
6449 TRUE, FALSE, NULL, NULL,
6450 TRUE);
6451 PointerToDialog (aafdp->location_dlg, slp);
6452
6453 aafdp->feature_details = BatchApplyFeatureDetailsDialog (h, feattype, EnableApplyFeatureAccept, aafdp);
6454
6455 c = HiddenGroup (h, 3, 0, NULL);
6456 aafdp->accept = PushButton (c, "Accept", DoApplyFeatureToAlignment);
6457 SetObjectExtra (aafdp->accept, aafdp, NULL);
6458 b = PushButton (c, "Cancel", StdCancelButtonProc);
6459 aafdp->leave_dlg_up = CheckBox (c, "Leave Dialog Up", NULL);
6460
6461 AlignObjects (ALIGN_CENTER, (HANDLE) aafdp->location_dlg,
6462 (HANDLE) aafdp->feature_details,
6463 (HANDLE) c,
6464 NULL);
6465
6466 EnableApplyFeatureAccept (aafdp);
6467 Show (w);
6468 }
6469
6470
GetSeqAnnotForAlignment(SeqAlignPtr sap)6471 extern SeqAnnotPtr GetSeqAnnotForAlignment (SeqAlignPtr sap)
6472 {
6473 SeqAnnotPtr sanp = NULL;
6474 BioseqPtr bsp;
6475 BioseqSetPtr bssp;
6476 Boolean found = FALSE;
6477
6478 if (sap == NULL)
6479 {
6480 return NULL;
6481 }
6482
6483 if (sap->idx.parenttype == OBJ_BIOSEQ)
6484 {
6485 bsp = (BioseqPtr) sap->idx.parentptr;
6486 if (bsp != NULL)
6487 {
6488 sanp = bsp->annot;
6489 }
6490 }
6491 else if (sap->idx.parenttype == OBJ_BIOSEQSET)
6492 {
6493 bssp = (BioseqSetPtr) sap->idx.parentptr;
6494 if (bssp != NULL)
6495 {
6496 sanp = bssp->annot;
6497 }
6498 }
6499 else if (sap->idx.parenttype == OBJ_SEQANNOT)
6500 {
6501 sanp = (SeqAnnotPtr) sap->idx.parentptr;
6502 }
6503 while (sanp != NULL && !found)
6504 {
6505 if (sanp->type == 2 && sanp->data == sap)
6506 {
6507 found = TRUE;
6508 }
6509 else
6510 {
6511 sanp = sanp->next;
6512 }
6513 }
6514 return sanp;
6515 }
6516
ConvertPairwiseToMultipleAlignment(SeqAlignPtr sap)6517 extern void ConvertPairwiseToMultipleAlignment (SeqAlignPtr sap)
6518 {
6519 SeqAlignPtr salp, salp_next;
6520
6521 salp = sap;
6522 while (salp != NULL)
6523 {
6524 if (salp->saip != NULL)
6525 {
6526 SeqAlignIndexFree(salp->saip);
6527 salp->saip = NULL;
6528 }
6529 salp = salp->next;
6530 }
6531 AlnMgr2IndexSeqAlign (sap);
6532
6533 salp = AlnMgr2GetSubAlign (sap, 0, -1, 0, FALSE);
6534 if (salp == NULL) return;
6535 AlnMgr2IndexSeqAlign (salp);
6536
6537 if (sap->idx.prevlink != NULL) {
6538 *(sap->idx.prevlink) = (Pointer) salp;
6539 }
6540
6541 while (sap != NULL) {
6542 salp_next = sap->next;
6543 sap->next = NULL;
6544 SeqAlignFree (sap);
6545 sap = salp_next;
6546 }
6547 }
6548