1 /* saled.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: saled.c
27 *
28 * Author: Colombe Chappey
29 *
30 * Version Creation Date: 1/27/96
31 *
32 * $Revision: 6.60 $
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 <saled.h>
46 #include <salutil.h>
47 #include <salsap.h>
48 #include <salfiles.h>
49 #include <salpanel.h>
50 #include <salstruc.h>
51 #include <salparam.h>
52 #include <edutil.h>
53 #include <dlogutil.h>
54 #include <aliread.h>
55 #include <alignmgr2.h>
56
57 #define SIDLAND 1
58 #define SEQLAND 2
59 #define BADLAND 3
60 #define HOLDDNLAND 4
61 #define HOLDUPLAND 5
62
63 #define NOCLICK 0
64 #define CLICKID_BIOSEQ 1
65 #define CLICKID_SEQFEAT 2
66 #define CLICKID_FEAT 3
67 #define CLICKSEQ_BIOSEQ 4
68 #define CLICKSEQ_SEQFEAT 5
69 #define CLICKSEQ_FEAT 6
70
71 #define MOUSE_NOACTION 0
72 #define MOUSE_CLICK 1
73 #define MOUSE_DRAG 2
74 #define MOUSE_RELEASE 3
75
76 /**********************************************************/
77
78 static Int4 timerCount = 0;
79 static Boolean typing_timerInUse = FALSE;
80 static Boolean deleting_timerInUse = FALSE;
81 static Boolean selecting_timerInUse= FALSE;
82
83 static void click_caret (RecT *rp, Int4 position, SelStructPtr csp, SelStructPtr caret, EditAlignDataPtr adp, Int2 line);
84
BioseqLength(SeqIdPtr sip)85 static Int4 BioseqLength (SeqIdPtr sip)
86 {
87 BioseqPtr bsp;
88 Int4 position = APPEND_RESIDUE;
89
90 bsp=BioseqLockById(sip);
91 if (bsp) {
92 position=bsp->length-1;
93 BioseqUnlock(bsp);
94 }
95 return position;
96 }
97 /*********************************************************
98 ***
99 *** ??????
100 ***
101 **********************************************************/
OBJ_(Uint2 feattype)102 extern Uint2 OBJ_ (Uint2 feattype)
103 {
104 if ( feattype == FEATDEF_BAD ) return OBJ_BIOSEQ;
105 return OBJ_SEQFEAT;
106 }
107
108 /******************************************************************/
get_client_rect(PaneL p,RectPtr prc)109 static void get_client_rect (PaneL p, RectPtr prc)
110 {
111 ObjectRect (p, prc);
112 InsetRect (prc, HRZ_BORDER_WIDTH, VER_BORDER_WIDTH);
113 }
114
115 /******************************************************************/
locate_region(SelStructPtr ssp,Int4 from,Int4 to,SeqIdPtr sip,Uint1 strand,Boolean is_fuzz)116 extern SelStructPtr locate_region (SelStructPtr ssp, Int4 from, Int4 to, SeqIdPtr sip, Uint1 strand, Boolean is_fuzz)
117 {
118 SeqLocPtr slp=NULL;
119 SeqIdPtr siptmp=NULL;
120
121 if (sip)
122 siptmp = SeqIdDup(sip);
123 if (ssp->region != NULL)
124 ssp->region = SeqLocFree ((SeqLocPtr) ssp->region);
125 if (is_fuzz)
126 slp = fuzz_loc (from, to, strand, siptmp, TRUE, TRUE);
127 else {
128 slp = SeqLocIntNew (from, to, strand, siptmp);
129 }
130 if ( slp != NULL ) {
131 ssp->regiontype = OM_REGION_SEQLOC;
132 ssp->region = (Pointer) slp;
133 }
134 else
135 ssp->regiontype = 0;
136 if (siptmp)
137 SeqIdFree (siptmp);
138 return ssp;
139 }
140
141 /******************************************************************/
change_to_seqpos(SelStructPtr ssp,SeqAlignPtr salp,ValNodePtr sqloc_list)142 static SelStructPtr change_to_seqpos (SelStructPtr ssp, SeqAlignPtr salp, ValNodePtr sqloc_list)
143 {
144 SelStructPtr tmp = ssp;
145 SeqLocPtr slp;
146 SeqIntPtr sit;
147 SeqIdPtr sip;
148
149 slp = (SeqLocPtr) tmp->region;
150 if (slp) {
151 sit = (SeqIntPtr) slp->data.ptrvalue;
152 sip = SeqLocId (slp);
153 sit->from = AlignCoordToSeqCoord (SeqLocStart(slp), sip, salp, sqloc_list, 0);
154 if (sit->from < 0)
155 sit->from = 0;
156 sit->to = AlignCoordToSeqCoord (SeqLocStop(slp), sip, salp, sqloc_list, 0);
157 if (sit->to < 0)
158 sit->to = BioseqLength (sip);
159 }
160 return tmp;
161 }
162
163 /******************************************************************/
replace_region(SelStructPtr ssp,Uint2 ssp_ed,Uint2 ssp_id,Uint2 ssp_it,Int4 from,Int4 to,SeqIdPtr sip,Uint1 strand,Boolean is_fuzz)164 extern SelStructPtr replace_region (SelStructPtr ssp, Uint2 ssp_ed, Uint2 ssp_id, Uint2 ssp_it, Int4 from, Int4 to, SeqIdPtr sip, Uint1 strand, Boolean is_fuzz)
165 {
166 if (from < 0 || sip == NULL)
167 return NULL;
168 ssp->entityID = ssp_ed;
169 ssp->itemID = ssp_id;
170 ssp->itemtype = ssp_it;
171 if (ssp->regiontype == OM_REGION_SEQLOC)
172 ssp->regiontype = 0;
173 if (ssp->region != NULL)
174 ssp->region = SeqLocFree ((SeqLocPtr) ssp->region);
175 ssp = locate_region (ssp, from, to, sip, strand, is_fuzz);
176 ssp->next = NULL;
177 ssp->prev = NULL;
178 return ssp;
179 }
180
181 /******************************************************************/
nextlineup(Int2 line,Uint2Ptr itemtype,Uint2Ptr itemsubtype)182 static Int2 nextlineup (Int2 line, Uint2Ptr itemtype, Uint2Ptr itemsubtype)
183 {
184 Int2 j;
185 for (j = line-1; j >= 0; j--)
186 {
187 if (itemtype[j] == itemtype[line]
188 && itemsubtype[j] == itemsubtype[line]) break;
189 }
190 return j;
191 }
nextlinedown(Int2 line,Int2 to,Uint2Ptr itemtype,Uint2Ptr itemsubtype)192 static Int2 nextlinedown (Int2 line, Int2 to, Uint2Ptr itemtype, Uint2Ptr itemsubtype)
193 {
194 Int2 j;
195 for (j = line+1; j <= to; j++) {
196 if (itemtype[j] == itemtype[line]
197 && itemsubtype[j] == itemsubtype[line]) break;
198 }
199 if (j > to) return -1;
200 return j;
201 }
202
moveup_scrollbar(PaneL pnl,Int2 adpvoffset,Int2 offset)203 static Int2 moveup_scrollbar (PaneL pnl, Int2 adpvoffset, Int2 offset)
204 {
205 if (adpvoffset > offset)
206 {
207 adpvoffset -= offset;
208 SeqEdSetValueScrollBar (pnl, (Int2)adpvoffset);
209 }
210 return adpvoffset;
211 }
212
movedown_scrollbar(PaneL pnl,Int2 adpvoffset,Int2 offset)213 static Int2 movedown_scrollbar (PaneL pnl, Int2 adpvoffset, Int2 offset)
214 {
215 adpvoffset += offset;
216 SeqEdSetValueScrollBar (pnl, (Int2)(adpvoffset));
217 return adpvoffset;
218 }
219
220 /******************************************************************
221 ***
222 *** GoToButton
223 *** LookAtButton
224 ***
225 *******************************************************************/
GoToFunc(SeqEditViewFormPtr wdp)226 static void GoToFunc (SeqEditViewFormPtr wdp)
227 {
228 WindoW temport;
229 PaneL pnl;
230 EditAlignDataPtr adp;
231 RecT rp;
232 Char str [16];
233 Int4 line, column;
234 Int4 val;
235 Boolean goOn;
236
237 if (wdp==NULL)
238 return;
239 pnl = wdp->pnl;
240 if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
241 temport = SavePort (pnl);
242 Select (pnl);
243
244 GetTitle (wdp->gototxt, str, 15);
245 goOn = CCStrToLong (str, &val);
246 if (!goOn) {
247 RestorePort (temport);
248 CaptureSlateFocus ((SlatE) pnl);
249 return;
250 }
251 ResetClip ();
252 if (val < 0) {
253 val = 0;
254 sprintf (str, "%ld", (long) val);
255 SetTitle (wdp->gototxt, str);
256 }
257 else if (val > adp->length) {
258 val = adp->length;
259 sprintf (str, "%ld", (long) val);
260 SetTitle (wdp->gototxt, str);
261 }
262 if (val < adp->hoffset || val >= adp->hoffset + adp->visibleLength)
263 {
264 adp->voffset = hoffset2voffset(adp, adp->anp_list, adp->visibleWidth, 0, adp->length-1, val);
265 data_collect_arrange (adp, TRUE);
266 SeqEdSetValueScrollBar (pnl, (Int2) adp->voffset);
267 }
268 get_client_rect (pnl, &rp);
269 SeqPosToLineColumn (adp->caret.itemID, adp->caret.entityID, adp->caret.itemtype, val, &line, &column, adp->hoffset, adp);
270 click_caret (&rp, val, &(adp->caret), &(adp->caret), adp, line);
271 if (!adp->display_panel)
272 to_update_prompt (pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
273 RestorePort (temport);
274 CaptureSlateFocus ((SlatE) pnl);
275 }
276
GoToButton(ButtoN b)277 extern void GoToButton (ButtoN b)
278 {
279 SeqEditViewFormPtr wdp;
280
281 wdp = (SeqEditViewFormPtr) GetObjectExtra ((WindoW)ParentWindow (b));
282 GoToFunc (wdp);
283 }
284
LookAtButton(ButtoN b)285 extern void LookAtButton (ButtoN b)
286 {
287 WindoW temport;
288 PaneL pnl;
289 SeqEditViewFormPtr wdp;
290 EditAlignDataPtr adp;
291 Char str [16];
292 Int4 val;
293 Boolean goOn;
294
295 wdp = (SeqEditViewFormPtr) GetObjectExtra ((WindoW)ParentWindow (b));
296 pnl = wdp->pnl;
297 if ( ( adp = GetAlignDataPanel (pnl) ) == NULL ) return;
298 temport = SavePort (pnl);
299 Select (pnl);
300
301 GetTitle (wdp->lookattxt, str, 15);
302 goOn = CCStrToLong (str, &val);
303 if (!goOn) return;
304
305 ResetClip ();
306 if (val < 0) {
307 val = 0;
308 sprintf (str, "%ld", (long) val);
309 SetTitle (wdp->lookattxt, str);
310 }
311 else if (val > adp->length) {
312 val = adp->length;
313 sprintf (str, "%ld", (long) val);
314 SetTitle (wdp->lookattxt, str);
315 }
316 if (val < adp->hoffset || val >= adp->hoffset + adp->visibleLength)
317 {
318 adp->voffset = hoffset2voffset(adp, adp->anp_list, adp->visibleWidth, 0, adp->length-1, val);
319 data_collect_arrange (adp, TRUE);
320 SeqEdSetValueScrollBar (pnl, (Int2) adp->voffset);
321 }
322 inval_panel (pnl, -1, -1);
323 RestorePort (temport);
324 CaptureSlateFocus ((SlatE) pnl);
325 }
326
checkfeatdel(SeqLocPtr slp,ValNodePtr feathead)327 static Boolean checkfeatdel (SeqLocPtr slp, ValNodePtr feathead)
328 {
329 ValNodePtr vnpfeat;
330 SelEdStructPtr feat;
331 SeqLocPtr slpfeat;
332 Int4 lg;
333 Boolean include;
334 Boolean overlap;
335
336 for (vnpfeat = feathead; vnpfeat != NULL; vnpfeat = vnpfeat->next)
337 {
338 feat = (SelEdStructPtr) vnpfeat->data.ptrvalue;
339 while ( feat != NULL )
340 {
341 slpfeat = (SeqLocPtr) feat->region;
342 include = include_ssp (slp, slpfeat);
343 if (include)
344 return FALSE;
345 overlap = overlapp_ssp (slp, slpfeat);
346 if (overlap) {
347 lg = 0;
348 if (SeqLocStart(slp) > SeqLocStart(slpfeat))
349 lg += SeqLocStart(slp) - SeqLocStart(slpfeat);
350 if (SeqLocStop(slpfeat) > SeqLocStop(slp))
351 lg += SeqLocStop(slpfeat) - SeqLocStop(slp);
352 if (lg < 2) {
353 return FALSE;
354 }
355 }
356 feat = feat->next;
357 }
358 }
359 return TRUE;
360 }
361
CutBtn(ButtoN b)362 static void CutBtn (ButtoN b)
363 {
364 WindoW wdialog;
365 DialogBoxDataPtr dbdp;
366 EditAlignDataPtr adp;
367 SelStructPtr ssp;
368 SeqLocPtr slp;
369 BioseqPtr bsp;
370
371 wdialog = ParentWindow (b);
372 Hide (wdialog);
373 Update();
374 dbdp = (DialogBoxDataPtr) GetObjectExtra (wdialog);
375 if ( ( adp = GetAlignEditData (dbdp->w) ) == NULL ) return;
376 WatchCursor ();
377 ssp = (SelStructPtr) adp->extra_data;
378 slp = (SeqLocPtr) ssp->region;
379 if (slp!=NULL) {
380 bsp = BioseqCopy (NULL, SeqLocId(slp), SeqLocStart(slp), SeqLocStop(slp), Seq_strand_plus, TRUE);
381 if (bsp == NULL) {
382 ErrPostEx (SEV_ERROR, 0, 0, "fail at BioseqCopy [9]");
383 }
384 else {
385 ObjMgrAddToClipBoard (0, (Pointer) bsp);
386 SeqDeleteByLoc (slp, TRUE, adp->spliteditmode);
387 adp->dirty = TRUE;
388 ObjMgrSetDirtyFlag (ssp->entityID, TRUE);
389 ObjMgrSendMsg(OM_MSG_UPDATE, ssp->entityID, ssp->itemID, ssp->itemtype);
390 ObjMgrDeSelect(ssp->entityID, ssp->itemID, ssp->itemtype, ssp->regiontype, ssp->region);
391 }
392 adp->extra_data = NULL;
393 }
394 ArrowCursor ();
395 Remove (wdialog);
396 Update ();
397 }
398
do_cut_dialog(WindoW w)399 static void do_cut_dialog (WindoW w)
400 {
401 WindoW wdialog;
402 DialogBoxDataPtr dbdp;
403 GrouP g1;
404
405 wdialog = FixedWindow (-50, -33, -10, -10, "Cut", StdCloseWindowProc);
406 dbdp = (DialogBoxDataPtr) MemNew (sizeof (DialogBoxData));
407 SetObjectExtra (wdialog, (Pointer) dbdp, StdCleanupExtraProc);
408 dbdp->w = w;
409 g1 = HiddenGroup (wdialog, 2, 0, NULL);
410 StaticPrompt (g1, "Cut is going to delete a feature",0,popupMenuHeight,systemFont, 'l');
411 g1 = HiddenGroup (wdialog, 2, 0, NULL);
412 PushButton (g1, "Process", CutBtn);
413 PushButton (g1, "Dismiss", StdCancelButtonProc);
414 RealizeWindow (wdialog);
415 Show (wdialog);
416 return;
417 }
418
do_cut(PaneL pnl,EditAlignDataPtr adp,SelStructPtr ssp,Boolean cut)419 extern Boolean do_cut (PaneL pnl, EditAlignDataPtr adp, SelStructPtr ssp, Boolean cut)
420 {
421 BioseqPtr bsp;
422 SeqLocPtr slp;
423 SeqIntPtr sit;
424 Int4 to;
425
426 StringToClipboard (NULL);
427 if (ssp == NULL) {
428 ErrPostEx (SEV_ERROR, 0, 0, "Can not cut [1]");
429 return FALSE;
430 }
431 if (ssp->itemtype != OBJ_BIOSEQ) {
432 ErrPostEx (SEV_ERROR, 0, 0, "Can not cut [2]");
433 return FALSE;
434 }
435 slp = (SeqLocPtr) ssp->region;
436 if (slp == NULL) {
437 ErrPostEx (SEV_ERROR, 0, 0, "Can not cut [3]");
438 return FALSE;
439 }
440 if (SeqLocStop(slp) == APPEND_RESIDUE) {
441 to = BioseqLength (SeqLocId(slp));
442 if (to > 0) {
443 sit = (SeqIntPtr) slp->data.ptrvalue;
444 sit->to = to;
445 }
446 else {
447 ErrPostEx (SEV_ERROR, 0, 0, "Can not cut [6]");
448 return FALSE;
449 }
450 }
451 if (SeqLocLen(slp) <= 0 || SeqLocLen(slp) >= adp->length) {
452 ErrPostEx (SEV_ERROR, 0, 0, "Can not cut [5]");
453 return FALSE;
454 }
455
456 if ( !checkfeatdel (slp, adp->seqfeat) ) {
457 adp->extra_data = (Pointer) ssp;
458 do_cut_dialog ((WindoW)ParentWindow(pnl));
459 return TRUE;
460 }
461 if (cut) {
462 WatchCursor ();
463 bsp = BioseqCopy (NULL, SeqLocId(slp), SeqLocStart(slp), SeqLocStop(slp), Seq_strand_plus, TRUE);
464 ArrowCursor ();
465 if (bsp == NULL) {
466 ErrPostEx (SEV_ERROR, 0, 0, "Can not cut [4]");
467 return FALSE;
468 }
469 }
470 WatchCursor ();
471 if (cut)
472 ObjMgrAddToClipBoard (0, (Pointer) bsp);
473 SeqDeleteByLoc (slp, TRUE, adp->spliteditmode);
474 adp->dirty = TRUE;
475 ObjMgrSetDirtyFlag (ssp->entityID, TRUE);
476 ObjMgrSendMsg (OM_MSG_UPDATE, ssp->entityID, ssp->itemID, ssp->itemtype);
477 ObjMgrDeSelect (ssp->entityID, ssp->itemID, ssp->itemtype, ssp->regiontype, ssp->region);
478 ArrowCursor ();
479 Update ();
480 return TRUE;
481 }
482
483 /******************************************************************/
do_paste(PaneL pnl,EditAlignDataPtr adp,SeqIdPtr sourceid)484 extern Boolean do_paste (PaneL pnl, EditAlignDataPtr adp, SeqIdPtr sourceid)
485 {
486 SelStructPtr caret;
487 SeqLocPtr slpcaret;
488 Int4 caretpos;
489 Boolean ok;
490
491 caret = &(adp->caret);
492 slpcaret = (SeqLocPtr) caret->region;
493 if ( slpcaret == NULL ) {
494 ErrPostEx (SEV_ERROR, 0, 0, "Fail in do_paste [1]");
495 return FALSE;
496 }
497 caretpos = SeqLocStart (slpcaret);
498 if ( caretpos < 0 ) {
499 ErrPostEx (SEV_ERROR, 0, 0, "Fail in do_paste [2]");
500 return FALSE;
501 }
502 if ( caretpos == adp->length ) caretpos = -2;
503
504 WatchCursor ();
505 ok = BioseqInsert (sourceid, FIRST_RESIDUE, LAST_RESIDUE, Seq_strand_plus, SeqLocId (slpcaret), caretpos, TRUE, TRUE, adp->spliteditmode);
506 ArrowCursor ();
507 if (!ok) {
508 ErrPostEx (SEV_ERROR, 0, 0, "Fail in do_paste [3]");
509 return FALSE;
510 }
511 Update ();
512 return TRUE;
513 }
514
515 /******************************************************************/
do_copy(IteM i)516 extern void do_copy (IteM i)
517 {
518 SelStructPtr ssp = NULL;
519 SeqLocPtr slp;
520 BioseqPtr bsp;
521 Int4 from, to;
522
523 WatchCursor ();
524 StringToClipboard (NULL);
525 if ( checkOMss_for_itemtype (OBJ_BIOSEQ) ) {
526 ssp = ObjMgrGetSelected ();
527 for (; ssp != NULL; ssp = ssp->next)
528 if ( ssp->itemtype == OBJ_BIOSEQ && checkssp_for_editor (ssp) )
529 break;
530 if ( ssp != NULL ) {
531 slp = (SeqLocPtr) ssp->region;
532 from = SeqLocStart(slp);
533 to = SeqLocStop(slp);
534 if (to < 0)
535 to = BioseqLength (SeqLocId(slp));
536 if (to > 0) {
537 bsp=BioseqCopy(NULL, SeqLocId(slp), from, to, Seq_strand_plus, TRUE);
538 if (bsp != NULL)
539 ObjMgrAddToClipBoard (0, (Pointer) bsp);
540 }
541 }
542 }
543 ArrowCursor ();
544 return;
545 }
546
CleanBufferProc(ValNodePtr bufvnp,Int2 nbseq,Int4 buflength)547 static Int4 CleanBufferProc (ValNodePtr bufvnp, Int2 nbseq, Int4 buflength)
548 {
549 TextAlignBufPtr tdp;
550 CharPtr PNTR str;
551 ValNodePtr vnp;
552 Boolean goOn = TRUE;
553 Int2 j;
554
555 str = (CharPtr PNTR) MemNew ((size_t) ((nbseq +1) * sizeof(CharPtr)));
556 for (vnp =bufvnp, j =0; vnp !=NULL && j <nbseq; vnp =vnp->next, j++) {
557 tdp = (TextAlignBufPtr) vnp->data.ptrvalue;
558 str[j] = tdp->buf;
559 }
560 while (goOn) {
561 for (j = 0; j < nbseq; j++) {
562 if ( *(str[j] +buflength -1) != '-') break;
563 }
564 goOn = (Boolean) (j == nbseq);
565 if (goOn) {
566 for (j=0; j<nbseq; j++)
567 {
568 *(str[j] +buflength -1) = '\0';
569 }
570 buflength--;
571 }
572 }
573 MemFree (str);
574 return buflength;
575 }
576
AlignDataGapAddProc(Char ch,Int4 cursorx,ValNodePtr linebuff,Int4 bufferlength,Uint2 entityID,Uint2 itemID)577 static Boolean AlignDataGapAddProc (Char ch, Int4 cursorx, ValNodePtr linebuff, Int4 bufferlength, Uint2 entityID, Uint2 itemID)
578 {
579 TextAlignBufPtr tap;
580 ValNodePtr vnp;
581 CharPtr buf;
582 Boolean insert = FALSE;
583 Int4 k;
584
585 for (vnp = linebuff; vnp != NULL; vnp = vnp->next)
586 {
587 tap = (TextAlignBufPtr) vnp->data.ptrvalue;
588 if (tap != NULL) {
589 if (OBJ_(tap->feattype) == OBJ_BIOSEQ) {
590 buf = (CharPtr) tap->buf;
591 if((tap->seqEntityID == entityID && tap->bsp_itemID == itemID)
592 || is_selectedbyID(tap->seqEntityID,tap->bsp_itemID,OBJ_BIOSEQ))
593 {
594 for (k = bufferlength; k > cursorx; k--)
595 buf [k] = buf [k-1];
596 buf [cursorx] = ch;
597 buf [bufferlength +1] = '\0';
598 insert = TRUE;
599 }
600 else {
601 buf [bufferlength] = '-';
602 buf [bufferlength +1] = '\0';
603 }
604 }
605 }
606 }
607 return insert;
608 }
609
610 /******************************************************************
611 ***
612 *** CLICK - DRAG - RELEASE procedure
613 ***
614 ******************************************************************/
update_prompt(PaneL pnl,CharPtr label,Int4 position)615 static void update_prompt (PaneL pnl, CharPtr label, Int4 position)
616 {
617 WindoW w;
618 SeqEditViewFormPtr wdp;
619 SelStructPtr ssp;
620 Char str[128];
621 Int4 from, to;
622 Int2 k;
623
624 w = getwindow_frompanel (pnl);
625 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
626 ResetClip ();
627 if (position >= 0) {
628 sprintf (str, "%s Position %ld", label, (long)position);
629 SetTitle (wdp->pos, str);
630 }
631 else if (position == LAST_RESIDUE) {
632 sprintf (str, "%s", label);
633 SetTitle (wdp->pos, str);
634 }
635 else {
636 k = checkOMss_for_itemtype (OBJ_BIOSEQ);
637 if (k == 1) {
638 ssp = getOMselect_for_itemtype (OBJ_BIOSEQ);
639 from = SeqLocStart ((SeqLocPtr) ssp->region);
640 to = SeqLocStop ((SeqLocPtr) ssp->region);
641 sprintf (str, "%s Selection %ld - %ld", label, (long)(from+1), (long)(to+1));
642 SetTitle (wdp->pos, str);
643 }
644 else {
645 sprintf (str, " ");
646 SetTitle (wdp->pos, str);
647 }
648 }
649 }
650
update_promptsel(PaneL pnl,CharPtr label)651 static void update_promptsel (PaneL pnl, CharPtr label)
652 {
653 WindoW w;
654 SeqEditViewFormPtr wdp;
655
656 w = getwindow_frompanel (pnl);
657 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
658 ResetClip ();
659 SetTitle (wdp->pos, label);
660 }
661
seqid_tolabel(SeqIdPtr sip,Uint1 choice)662 static CharPtr seqid_tolabel (SeqIdPtr sip, Uint1 choice)
663 {
664 BioseqPtr bsp;
665 SeqIdPtr tmp = NULL;
666 Char str[120];
667 CharPtr strp;
668
669 str[0] = '\0';
670 if (choice && choice <= PRINTID_GIcc && sip)
671 {
672 bsp = BioseqLockById(sip);
673 if (bsp!=NULL)
674 {
675 if (choice==PRINTID_GIcc)
676 tmp = SeqIdFindBest (bsp->id, 0);
677 else
678 tmp = SeqIdFindWorst (bsp->id);
679 if (tmp)
680 {
681 SeqIdWrite (tmp, str, choice, 120);
682 BioseqUnlock(bsp);
683 strp = StringSave (str);
684 return strp;
685 }
686 BioseqUnlock(bsp);
687 }
688 }
689 if (choice!=0 && sip) {
690 SeqIdWrite (sip, str, choice, 120);
691 strp = StringSave (str);
692 return strp;
693 }
694 strp = StringSave (str);
695 return strp;
696 }
697
to_update_prompt(PaneL pnl,SelStructPtr ssp,SeqAlignPtr salp,ValNodePtr sqloc_list,Boolean sel,Uint1 choice)698 extern void to_update_prompt (PaneL pnl, SelStructPtr ssp, SeqAlignPtr salp, ValNodePtr sqloc_list, Boolean sel, Uint1 choice)
699 {
700 SeqIdPtr sip;
701 Int4 pos, posto;
702 CharPtr seqid=NULL;
703 Char str[255];
704 Char tmp[252];
705 CharPtr strp;
706 SeqLocPtr slp;
707 SelStructPtr selp;
708
709 if (ssp==NULL)
710 return;
711 if (ssp->region == NULL)
712 return;
713
714 str[0] = '0';
715 slp = (SeqLocPtr) ssp->region;
716 sip = SeqLocId(slp);
717 if (choice == 0)
718 choice = PRINTID_FASTA_LONG; /*PRINTID_TEXTID_ACCESSION;*/
719 seqid = seqid_tolabel (sip, choice);
720 selp = is_selectedbyID (ssp->entityID, ssp->itemID, ssp->itemtype);
721 if (selp != NULL)
722 {
723 strp = str;
724 pos = SeqLocStart((SeqLocPtr)selp->region);
725 posto = SeqLocStop((SeqLocPtr)selp->region);
726 if (posto == APPEND_RESIDUE)
727 posto = BioseqLength (sip);
728 if (selp->next == NULL)
729 sprintf (tmp, "%s Selection %ld - %ld", seqid, (long)(pos+1), (long)(posto+1));
730 else
731 sprintf (tmp, "%s Selections %ld - %ld", seqid, (long)(pos+1), (long)(posto+1));
732 strp = StringMove (strp, tmp);
733 selp = selp->next;
734 while (selp != NULL && (StringLen(str) < 200)) {
735 if (checkssp_for_editor (selp) && is_sameId (selp->entityID, selp->itemID, selp->itemtype, 255, ssp->entityID, ssp->itemID, ssp->itemtype, 255))
736 {
737 pos = SeqLocStart((SeqLocPtr)selp->region);
738 posto = SeqLocStop((SeqLocPtr)selp->region);
739 sprintf (tmp, ", %ld - %ld", (long)(pos+1), (long)(posto+1));
740 strp = StringMove (strp, tmp);
741 }
742 selp = selp->next;
743 }
744 update_promptsel (pnl, str);
745 }
746 else {
747 if (salp != NULL) {
748 pos = AlignCoordToSeqCoord (SeqLocStart(slp), sip, salp, sqloc_list, 1);
749 if (pos == APPEND_RESIDUE)
750 pos = BioseqLength (sip);
751 }
752 else pos = SeqLocStart(slp);
753 if (sel) {
754 if (salp != NULL) {
755 posto = AlignCoordToSeqCoord (SeqLocStop(slp), sip, salp, sqloc_list, 0);
756 }
757 else posto = SeqLocStop(slp);
758 if (posto == APPEND_RESIDUE)
759 posto = BioseqLength (sip);
760 sprintf (str, "%s Selection %ld - %ld", seqid, (long)(pos+1), (long)(posto+1));
761 update_promptsel (pnl, str);
762 }
763 else {
764 update_prompt (pnl, seqid, pos);
765 }
766 }
767 if (seqid)
768 MemFree (seqid);
769 return;
770 }
771
update_edititem(PaneL pnl)772 extern void update_edititem (PaneL pnl)
773 {
774 WindoW w;
775 EditAlignDataPtr adp;
776 SeqEditViewFormPtr wdp;
777 Int2 k;
778
779 w = getwindow_frompanel (pnl);
780 if ((adp = GetAlignEditData (w)) == NULL)
781 return;
782 if (adp->edit_mode == SEQ_EDIT || adp->edit_mode == ALIGN_EDIT)
783 {
784 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
785 ResetClip ();
786 k = checkOMss_for_itemtype (OBJ_BIOSEQ);
787 if (k > 0) {
788 Enable (wdp->cutitem);
789 Enable (wdp->copyitem);
790 }
791 else {
792 Disable (wdp->cutitem);
793 Disable (wdp->copyitem);
794 }
795 }
796 }
797
update_savefeatitem(PaneL pnl)798 static void update_savefeatitem (PaneL pnl)
799 {
800 WindoW w;
801 EditAlignDataPtr adp;
802 SeqEditViewFormPtr wdp;
803 Int2 k;
804
805 w = getwindow_frompanel (pnl);
806 if ((adp = GetAlignEditData (w)) == NULL)
807 return;
808 if (adp->edit_mode == SEQ_EDIT || adp->edit_mode == ALIGN_EDIT) {
809 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
810 ResetClip ();
811 k = checkOMss_for_itemtype(OBJ_SEQFEAT);
812 if (k > 0) {
813 Enable (wdp->savefeatitem);
814 Enable (wdp->savefeatbt);
815 }
816 else {
817 Disable (wdp->savefeatitem);
818 Disable (wdp->savefeatbt);
819 }
820 }
821 }
822
update_translateitem(PaneL pnl,ValNodePtr seqfeathead,ValNodePtr feathead)823 extern void update_translateitem (PaneL pnl, ValNodePtr seqfeathead, ValNodePtr feathead)
824 {
825 WindoW w;
826 SeqEditViewFormPtr wdp;
827 Int2 k;
828
829 w = getwindow_frompanel (pnl);
830 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
831 ResetClip ();
832 k = checkCDSselect_forprotein (seqfeathead, feathead, FALSE);
833 if (k == 0) {
834 Disable (wdp->translateitem);
835 Disable (wdp->translatebt);
836 }
837 else {
838 Enable (wdp->translateitem);
839 Enable (wdp->translatebt);
840 }
841 }
842
update_codonstartbt(PaneL pnl,ValNodePtr seqfeathead,ValNodePtr feathead)843 extern void update_codonstartbt (PaneL pnl, ValNodePtr seqfeathead, ValNodePtr feathead)
844 {
845 WindoW w;
846 SeqEditViewFormPtr wdp;
847 SelEdStructPtr feat;
848 Char str[128];
849 Int2 k;
850
851 w = getwindow_frompanel (pnl);
852 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
853 ResetClip ();
854 k = checkCDSselect_forprotein (seqfeathead, feathead, TRUE);
855 if (k == 1) {
856 feat = getCDSselect (seqfeathead, feathead);
857 sprintf (str, "Codon start %d", (int)(feat->codonstart));
858 SetTitle (wdp->codonstitem, str);
859 Enable (wdp->codonstitem);
860 }
861 else {
862 sprintf (str, "Codon start");
863 SetTitle (wdp->codonstitem, str);
864 Disable (wdp->codonstitem);
865 }
866 }
867
on_time(WindoW w)868 extern void on_time (WindoW w)
869 {
870 EditAlignDataPtr adp;
871
872 if ((adp = GetAlignEditData (w)) == NULL) return;
873 timerCount++;
874 if (typing_timerInUse || deleting_timerInUse) {
875 if (adp->edit_item.entityID != 0 && timerCount > 40) {
876 typing_timerInUse = FALSE;
877 deleting_timerInUse = FALSE;
878 timerCount = 0;
879 ObjMgrSendMsg (OM_MSG_UPDATE, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype);
880 }
881 }
882 else if (selecting_timerInUse) {
883 if (timerCount > 80) {
884 selecting_timerInUse = FALSE;
885 timerCount = 0;
886 ObjMgrSendMsg (OM_MSG_SELECT, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype);
887 }
888 }
889 return;
890 }
891
update_select_when_release(EditAlignDataPtr adp)892 static void update_select_when_release (EditAlignDataPtr adp)
893 {
894 if (selecting_timerInUse) {
895 selecting_timerInUse = FALSE;
896 timerCount = 0;
897 ObjMgrSendMsg (OM_MSG_SELECT, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype);
898 }
899 return;
900 }
901
click_id(PaneL pnl,SelStructPtr csp,EditAlignDataPtr adp)902 static void click_id (PaneL pnl, SelStructPtr csp, EditAlignDataPtr adp)
903 {
904 SelStructPtr spp;
905 SeqIdPtr sip;
906 Int4 from, to;
907 Int4 start, stop;
908 ValNodePtr vnp;
909 AlignNodePtr anp;
910 SeqLocPtr slp;
911 SeqAlignPtr salp = (SeqAlignPtr) adp->sap_align->data;
912
913 if ( csp == NULL ) {
914 ErrPostEx (SEV_ERROR, 0, 0, "fail in click_id [1]");
915 return;
916 }
917 Select (pnl);
918 spp = is_selectedbyID (csp->entityID, csp->itemID, csp->itemtype);
919 if (spp != NULL) {
920 ObjMgrDeSelectAll ();
921 if (! adp->display_panel)
922 to_update_prompt (pnl, &(adp->caret), salp, adp->sqloc_list, FALSE, adp->printid);
923 }
924 else if (shftKey && ctrlKey)
925 {
926 spp=ObjMgrGetSelected();
927 if(spp!=NULL) {
928 for(; spp!=NULL; spp=spp->next){
929 if(spp->entityID==csp->entityID && spp->itemID==csp->itemID)
930 break;
931 }
932 if (spp == NULL) {
933 spp=ObjMgrGetSelected();
934 slp=(SeqLocPtr)spp->region;
935 start=SeqCoordToAlignCoord(SeqLocStart(slp), SeqLocId(slp), salp, 0, 0);
936 stop=SeqCoordToAlignCoord(SeqLocStop(slp), SeqLocId(slp), salp, 0, 0);
937 sip = SeqLocId ((SeqLocPtr)csp->region);
938 from=AlignCoordToSeqCoord (start, sip, salp, adp->sqloc_list, 0);
939 to=AlignCoordToSeqCoord (stop, sip, salp, adp->sqloc_list, 0);
940 slp = SeqLocIntNew(from, to, SeqLocStrand((SeqLocPtr)csp->region), sip);
941 ObjMgrAlsoSelect (csp->entityID, csp->itemID, csp->itemtype, OM_REGION_SEQLOC, (Pointer)slp);
942 }
943 }
944 }
945 else if (shftKey)
946 {
947 csp = change_to_seqpos (csp, salp, adp->sqloc_list);
948 for(spp=ObjMgrGetSelected(); spp!=NULL; spp=spp->next)
949 if (spp->entityID!=csp->entityID || spp->itemID!=csp->itemID)
950 break;
951 if (spp == NULL)
952 {
953 ObjMgrAlsoSelect (csp->entityID, csp->itemID, csp->itemtype, csp->regiontype, csp->region);
954 }
955 else {
956 for (vnp=adp->anp_list; vnp != NULL; vnp = vnp->next) {
957 anp = (AlignNodePtr) vnp->data.ptrvalue;
958 if (anp != NULL)
959 if (anp->seq_entityID==spp->entityID && anp->bsp_itemID == spp->itemID )
960 break;
961 }
962 if (vnp!=NULL) {
963 vnp = vnp->next;
964 for (; vnp!=NULL; vnp = vnp->next) {
965 anp = (AlignNodePtr) vnp->data.ptrvalue;
966 if (anp!=NULL) {
967 spp = is_selectedbyID (anp->seq_entityID, anp->bsp_itemID, OBJ_BIOSEQ);
968 if (spp==NULL) {
969 slp = CollectSeqLocFromAlignNode(anp);
970 if (slp!=NULL)
971 {
972 ObjMgrAlsoSelect (anp->seq_entityID, anp->bsp_itemID, OBJ_BIOSEQ, OM_REGION_SEQLOC, (Pointer)slp);
973 }
974 if (anp->seq_entityID==csp->entityID && anp->bsp_itemID == csp->itemID )
975 break;
976 }
977 }
978 }
979 }
980 }
981 }
982 else if (ctrlKey)
983 {
984 csp = change_to_seqpos (csp, salp, adp->sqloc_list);
985 ObjMgrAlsoSelect (csp->entityID, csp->itemID, csp->itemtype, csp->regiontype, csp->region);
986 }
987 else {
988 csp = change_to_seqpos (csp, salp, adp->sqloc_list);
989 ObjMgrSelect (csp->entityID, csp->itemID, csp->itemtype, csp->regiontype, csp->region);
990 }
991 Update ();
992 return;
993 }
994
995 /******************************************************************/
click_caret(RecT * rp,Int4 position,SelStructPtr csp,SelStructPtr caret,EditAlignDataPtr adp,Int2 line)996 static void click_caret (RecT *rp, Int4 position, SelStructPtr csp, SelStructPtr caret, EditAlignDataPtr adp, Int2 line)
997 {
998 SeqIdPtr sip;
999
1000 if (csp != NULL) {
1001 if ( caret->regiontype != 0 )
1002 inval_selstructpos(adp,caret->entityID, caret->itemID, caret->itemtype, rp, SeqLocStart ((SeqLocPtr)caret->region));
1003 sip = SeqIdDup (SeqLocId((SeqLocPtr)csp->region));
1004 replace_region (caret, csp->entityID, csp->itemID, csp->itemtype, position, position, sip, SeqLocStrand((SeqLocPtr)csp->region), FALSE);
1005 SeqIdFree (sip);
1006 adp->caret_orig = position;
1007 adp->cur_pat = NULL;
1008 inval_selstructpos (adp, caret->entityID, caret->itemID, caret->itemtype, rp, position);
1009 }
1010 }
1011
1012 /******************************************************************/
click_feat(PaneL pnl,Int4 position,SelStructPtr csp,EditAlignDataPtr adp,Int2 line)1013 static void click_feat (PaneL pnl, Int4 position, SelStructPtr csp, EditAlignDataPtr adp, Int2 line)
1014 {
1015 RecT rp;
1016 SeqLocPtr slp;
1017 SeqAlignPtr salp;
1018 Int4 start, stop;
1019 Int2 width;
1020
1021 if ( csp == NULL ) {
1022 ErrPostEx (SEV_ERROR, 0, 0, "fail in click_feat [1]");
1023 return;
1024 }
1025 get_client_rect (pnl, &rp);
1026 if ( ! shftKey ) {
1027 width = adp->visibleWidth;
1028 if (adp->columnpcell > 0)
1029 width += (Int2) adp->visibleWidth / (Int2) adp->columnpcell;
1030 }
1031 salp = (SeqAlignPtr) adp->sap_align->data;
1032 slp = (SeqLocPtr) csp->region;
1033 start = SeqLocStart(slp);
1034 stop = SeqLocStop(slp);
1035 start = SeqCoordToAlignCoord (start, SeqLocId(slp), salp, 0, 0);
1036 stop = SeqCoordToAlignCoord (stop, SeqLocId(slp), salp, 0, 0);
1037 if (position > start && position < stop)
1038 adp->click_feat = 3;
1039 else if (position <= start && position > start- 2)
1040 adp->click_feat = 1;
1041 else if (position >= stop && position < stop + 2)
1042 adp->click_feat = 2;
1043 else adp->click_feat = 0;
1044 adp->feat_line = line;
1045 inval_selstructloc_forfeat (adp, csp->entityID, csp->itemID, csp->itemtype, 255, &rp, start, stop);
1046 csp = change_to_seqpos (csp, salp, adp->sqloc_list);
1047 if ( ! shftKey )
1048 {
1049 ObjMgrSelect (csp->entityID,csp->itemID, csp->itemtype, csp->regiontype, csp->region);
1050 }
1051 else
1052 {
1053 ObjMgrAlsoSelect (csp->entityID, csp->itemID, csp->itemtype, csp->regiontype, csp->region);
1054 }
1055 }
1056
1057 /******************************************************************/
invalminmax(RecT * rp,SelStructPtr spp,Int4 position,EditAlignDataPtr adp)1058 static void invalminmax (RecT *rp, SelStructPtr spp, Int4 position, EditAlignDataPtr adp)
1059 {
1060 SeqLocPtr slp;
1061 Int4 pos,
1062 posmin, posmax;
1063
1064 slp = (SeqLocPtr) spp->region;
1065 if ( position > adp->caret_orig )
1066 {
1067 pos = MIN((Int4)SeqLocStart(slp),(Int4)SeqLocStop(slp));
1068 posmin = MIN(pos,(Int4) adp->edit_pos);
1069 posmax = MAX(pos,(Int4) adp->edit_pos);
1070 inval_selstructloc (adp, spp->entityID, spp->itemID, spp->itemtype, 255, rp, posmin, posmax);
1071 }
1072 else if ( position < adp->caret_orig )
1073 {
1074 pos = MAX((Int4)SeqLocStart(slp),(Int4)SeqLocStop(slp));
1075 posmin = MIN(pos,(Int4) adp->edit_pos);
1076 posmax = MAX(pos,(Int4) adp->edit_pos);
1077 inval_selstructloc (adp, spp->entityID, spp->itemID, spp->itemtype, 255, rp, posmin, posmax);
1078 }
1079 }
1080
1081
1082 /******************************************************************/
get_closest_selection(SelStructPtr caret,SeqAlignPtr salp,SelStructPtr current_point,ValNodePtr sqloc_list)1083 static SelStructPtr get_closest_selection (SelStructPtr caret, SeqAlignPtr salp, SelStructPtr current_point, ValNodePtr sqloc_list)
1084 {
1085 SelStructPtr ssp,
1086 car,
1087 this_selection=NULL;
1088 Int4 position;
1089 Int4 val , valmin = INT4_MAX;
1090
1091 car = SelStructDup (caret);
1092 car = change_to_seqpos (car, salp, sqloc_list);
1093 if (car)
1094 {
1095 ssp = ObjMgrGetSelected();
1096 if (ssp==NULL)
1097 this_selection = current_point;
1098 else
1099 {
1100 position = SeqLocStart((SeqLocPtr)car->region);
1101 for (; ssp != NULL; ssp = ssp->next)
1102 {
1103 if ( checkssp_for_editor (ssp) && is_sameId (ssp->entityID, ssp->itemID, ssp->itemtype, 255, car->entityID, car->itemID, car->itemtype, 255) )
1104 {
1105 val = (Int4)(ABS(SeqLocStart((SeqLocPtr)ssp->region)-position)+ABS(SeqLocStop((SeqLocPtr)ssp->region)-position));
1106
1107 if ( val < valmin )
1108 {
1109 this_selection = ssp;
1110 valmin = val;
1111 }
1112 }
1113 }
1114 }
1115 SelStructDel (car);
1116 }
1117 return this_selection;
1118 }
1119
1120
1121 /******************************************************************
1122 ***
1123 *** Open and Extend this_selection by AlsoSeqlect
1124 ***
1125 **************** *******************************************/
extend_selectregion(EditAlignDataPtr adp,SelStructPtr this_selection,Int4 position,Int4 old_caret_pos,Boolean IsOtherSel,PaneL pnl)1126 static Boolean extend_selectregion (EditAlignDataPtr adp, SelStructPtr this_selection, Int4 position,Int4 old_caret_pos, Boolean IsOtherSel, PaneL pnl)
1127 {
1128 SeqIdPtr sip;
1129 SeqLocPtr slp;
1130 SeqAlignPtr salp;
1131 Int4 from, to, itmp;
1132 Uint2 sspei, sspii, sspit;
1133 Boolean retval=FALSE;
1134
1135 sspei = (Uint2) adp->caret.entityID;
1136 sspii = (Uint2) adp->caret.itemID;
1137 sspit = (Uint2) adp->caret.itemtype;
1138 if (is_sameId (this_selection->entityID, this_selection->itemID, this_selection->itemtype, 255, sspei, sspii, sspit, 255))
1139 {
1140 salp = (SeqAlignPtr) adp->sap_align->data;
1141 sip = SeqLocId((SeqLocPtr)adp->caret.region);
1142 if (!IsOtherSel){/*no previous close selection*/
1143 /*Create a SelStruct between old_caret_pos and position*/
1144 from = AlignCoordToSeqCoord (old_caret_pos, sip, salp, adp->sqloc_list, 0);
1145 to = AlignCoordToSeqCoord (position, sip, salp, adp->sqloc_list, 0);
1146 if (from > to){
1147 itmp=to; to=from; from=itmp;
1148 }
1149 slp = SeqLocIntNew (from, to, Seq_strand_plus, sip);
1150 retval=ObjMgrAlsoSelect (this_selection->entityID, this_selection->itemID,
1151 this_selection->itemtype, OM_REGION_SEQLOC, slp);
1152 }
1153 }
1154 return retval;
1155 }
1156
1157 /******************************************************************/
dragcaret_selectrgn(PaneL pnl,Int4 position,SelStructPtr spp,SelStructPtr caret,EditAlignDataPtr adp,Int2 line)1158 static void dragcaret_selectrgn (PaneL pnl, Int4 position, SelStructPtr spp, SelStructPtr caret, EditAlignDataPtr adp, Int2 line)
1159 {
1160 SeqLocPtr slp;
1161 SeqAlignPtr salp;
1162 SeqIdPtr sip;
1163 RecT rp;
1164 float hratio;
1165
1166 if ( spp == NULL) {
1167 /*********
1168 ErrPostEx (SEV_ERROR, 0, 0, "fail in dragcaret_selectrgn [2]");
1169 *********/
1170 return;
1171 }
1172 get_client_rect (pnl, &rp);
1173 hratio = (float)adp->hoffset / (float)adp->length;
1174 salp = (SeqAlignPtr) adp->sap_align->data;
1175 selecting_timerInUse = TRUE;
1176 if ( position == adp->caret_orig )
1177 {
1178 invalminmax (&rp, spp, position, adp);
1179 inval_selstructloc (adp, spp->entityID, spp->itemID, spp->itemtype, 255, &rp, SeqLocStart((SeqLocPtr) spp->region), SeqLocStop((SeqLocPtr) spp->region));
1180 adp->caret_line = line;
1181 data_collect_arrange (adp, TRUE);
1182 SeqEdSetCorrectBarMax (pnl, adp, hratio);
1183 if (!adp->display_panel)
1184 to_update_prompt (pnl, spp, NULL, adp->sqloc_list, FALSE, adp->printid);
1185 ObjMgrDeSelect (spp->entityID, spp->itemID, spp->itemtype, spp->regiontype, spp->region);
1186 }
1187 else {
1188 slp = (SeqLocPtr) spp->region;
1189 sip = SeqLocId (slp);
1190 invalminmax (&rp, spp, position, adp);
1191 position = AlignCoordToSeqCoord (position, sip, salp, adp->sqloc_list, 0);
1192 if ( position > adp->caret_orig )
1193 {
1194 if (position < 0) position =BioseqLength (sip);
1195 slp = SeqLocIntNew (SeqLocStart(slp), position, Seq_strand_plus, sip);
1196 }
1197 else
1198 {
1199 if (position < 0) position = 0;
1200 slp = SeqLocIntNew (position, SeqLocStop(slp), Seq_strand_plus, sip);
1201 }
1202 ObjMgrAlsoSelect (spp->entityID, spp->itemID, spp->itemtype, OM_REGION_SEQLOC, slp);
1203 adp->caret_line = line;
1204 if (!adp->display_panel)
1205 to_update_prompt (pnl, spp, salp, adp->sqloc_list, TRUE, adp->printid);
1206 }
1207 return;
1208 }
1209
1210
1211
1212 /******************************************************************/
drag_feat(PaneL pnl,Int4 position,SelEdStructPtr feat,EditAlignDataPtr adp,Int2 line,Int2 feattype,SelEdStructPtr prec,SelEdStructPtr next,SelStructPtr selssp)1213 static void drag_feat (PaneL pnl, Int4 position, SelEdStructPtr feat, EditAlignDataPtr adp, Int2 line, Int2 feattype, SelEdStructPtr prec, SelEdStructPtr next, SelStructPtr selssp)
1214 {
1215 SeqLocPtr slp;
1216 SeqLocPtr slpprec = NULL, slpnext = NULL;
1217 SeqIntPtr sitfeat;
1218 SeqAlignPtr salp;
1219 RecT rp;
1220 Int4 linebefmv, lineaftmv, line2befmv, line2aftmv;
1221 Int4 column;
1222 Int2 width;
1223 Int4 oldposfrom, oldposto;
1224 Int4 oldseqfrom, oldseqto;
1225 Int4 minpos, maxpos;
1226 Boolean updateline = FALSE;
1227 SeqLocPtr selslp;
1228 SeqIntPtr selsit;
1229 float hratio;
1230
1231 if ( adp->click_feat == 0 ) return;
1232 if ( feat == NULL) {
1233 ErrPostEx (SEV_ERROR, 0, 0, "fail in drag_feat [0]");
1234 return;
1235 }
1236 get_client_rect (pnl, &rp);
1237 width = adp->visibleWidth;
1238 if (adp->columnpcell > 0)
1239 width += (Int2) adp->visibleWidth / (Int2) adp->columnpcell;
1240 slp = (SeqLocPtr) feat->region;
1241 if (slp == NULL) {
1242 ErrPostEx (SEV_ERROR, 0, 0, "fail in drag_feat [2.1]");
1243 return;
1244 }
1245 sitfeat = (SeqIntPtr) slp->data.ptrvalue;
1246 if (sitfeat == NULL) {
1247 ErrPostEx (SEV_ERROR, 0, 0, "fail in drag_feat [2.2]");
1248 return;
1249 }
1250 hratio = (float)adp->hoffset / (float)adp->length;
1251 salp = (SeqAlignPtr) adp->sap_align->data;
1252 oldseqfrom = SeqLocStart (slp);
1253 oldseqto = SeqLocStop (slp);
1254 oldposfrom = SeqCoordToAlignCoord(oldseqfrom, SeqLocId(slp), salp, 0, 0);
1255 oldposto = SeqCoordToAlignCoord(oldseqto, SeqLocId(slp), salp, 0, 0);
1256 if (prec != NULL)
1257 slpprec = (SeqLocPtr) prec->region;
1258 if (next != NULL)
1259 slpnext = (SeqLocPtr) next->region;
1260 if ( adp->click_feat == 1 )
1261 {
1262 if ( position >= 0 && position <= oldposto)
1263 {
1264 sitfeat->from=AlignCoordToSeqCoord(position,SeqLocId(slp), salp, adp->sqloc_list, 0);
1265 if (!overlapp_ssp (slp, slpprec) && !overlapp_ssp (slp, slpnext))
1266 {
1267 if ((feattype == SEQFEAT_CDREGION || feattype == FEATDEF_CDS)
1268 && feat->data != NULL ) {
1269 sesp_to_pept (feat, salp, adp->sqloc_list, FALSE);
1270 inval_selstruct (adp, feat->entityID, feat->itemID, feat->itemtype, FEATDEF_TRSL, &rp, adp->margin.left, (Int2) (width *adp->charw));
1271 }
1272 minpos = MIN (oldposfrom, position);
1273 maxpos = MAX (oldposfrom, position) + 1;
1274 inval_selstructloc_forfeat (adp, feat->entityID, feat->itemID, feat->itemtype, feattype, &rp, minpos, maxpos);
1275 updateline = TRUE;
1276 }
1277 else sitfeat->from = oldseqfrom;
1278 }
1279 }
1280 else if ( adp->click_feat == 2 )
1281 {
1282 if ( position < adp->length && position >= oldposfrom)
1283 {
1284 sitfeat->to =AlignCoordToSeqCoord(position,SeqLocId(slp), salp, adp->sqloc_list, 0);
1285 if (!overlapp_ssp (slp, slpprec) && !overlapp_ssp (slp, slpnext))
1286 {
1287 if ((feattype == SEQFEAT_CDREGION || feattype == FEATDEF_CDS)
1288 && feat->data != NULL ) {
1289 sesp_to_pept (feat, salp, adp->sqloc_list, FALSE);
1290 inval_selstruct (adp, feat->entityID, feat->itemID, feat->itemtype, FEATDEF_TRSL, &rp, adp->margin.left, (Int2) (width *adp->charw));
1291 }
1292 minpos = MIN (oldposto, position) - 1;
1293 maxpos = MAX (oldposto, position);
1294 inval_selstructloc_forfeat (adp, feat->entityID, feat->itemID, feat->itemtype, feattype, &rp, minpos, maxpos);
1295 updateline = TRUE;
1296 }
1297 else sitfeat->to = oldseqto;
1298 }
1299 }
1300 else if ( adp->click_feat == 3 )
1301 {
1302 if (oldposfrom >= adp->feat_pos - position
1303 && oldposto + position - adp->feat_pos < adp->length)
1304 {
1305 if(position < adp->feat_pos && oldposfrom > adp->feat_pos -position)
1306 {
1307 sitfeat->from -= (adp->feat_pos - position);
1308 sitfeat->to -= (adp->feat_pos - position);
1309 }
1310 else if (oldposto + adp->feat_pos - position < adp->length)
1311 {
1312 sitfeat->from += (position - adp->feat_pos);
1313 sitfeat->to += (position - adp->feat_pos);
1314 }
1315 if (!overlapp_ssp (slp, slpprec) && !overlapp_ssp (slp, slpnext))
1316 {
1317 if ((feattype == SEQFEAT_CDREGION || feattype == FEATDEF_CDS)
1318 && feat->data != NULL ) {
1319 sesp_to_pept (feat, salp, adp->sqloc_list, FALSE);
1320 inval_selstruct (adp, feat->entityID, feat->itemID, feat->itemtype, FEATDEF_TRSL, &rp, adp->margin.left, (Int2) (width *adp->charw));
1321 }
1322 maxpos = SeqCoordToAlignCoord(sitfeat->from, SeqLocId(slp), salp, 0, 0);
1323 minpos = MIN (oldposfrom, maxpos);
1324 maxpos = MAX (oldposfrom, sitfeat->from) + 1;
1325 inval_selstructloc_forfeat (adp, feat->entityID, feat->itemID, feat->itemtype, feattype, &rp, minpos, maxpos);
1326 maxpos = SeqCoordToAlignCoord(sitfeat->to, SeqLocId(slp), salp, 0, 0);
1327 minpos = MIN (oldposto, maxpos) - 1;
1328 maxpos = MAX (oldposto, maxpos);
1329 inval_selstructloc_forfeat (adp, feat->entityID, feat->itemID, feat->itemtype, feattype, &rp, minpos, maxpos);
1330 updateline = TRUE;
1331 }
1332 else {
1333 sitfeat->from = oldseqfrom;
1334 sitfeat->to = oldseqto;
1335 }
1336 }
1337 }
1338 selslp = (SeqLocPtr) selssp->region;
1339 selsit = (SeqIntPtr) selslp->data.ptrvalue;
1340 selsit->from = sitfeat->from;
1341 selsit->to = sitfeat->to;
1342
1343 if (updateline)
1344 {
1345 SeqPosToLineColumn (feat->itemID, feat->entityID, feat->itemtype,
1346 oldposfrom, &linebefmv, &column, adp->hoffset, adp);
1347 SeqPosToLineColumn (feat->itemID, feat->entityID, feat->itemtype,
1348 oldposto, &line2befmv, &column, adp->hoffset, adp);
1349 SeqPosToLineColumn (feat->itemID, feat->entityID, feat->itemtype,
1350 SeqLocStart(slp), &lineaftmv, &column, adp->hoffset, adp);
1351 SeqPosToLineColumn (feat->itemID, feat->entityID, feat->itemtype,
1352 SeqLocStop(slp), &line2aftmv,&column, adp->hoffset, adp);
1353 if ( lineaftmv > linebefmv )
1354 {
1355 ResetClip ();
1356 inval_rect (rp.left, (Int2)(rp.top+ linebefmv *adp->lineheight),
1357 rp.right, rp.bottom);
1358 data_collect_arrange (adp, TRUE);
1359 SeqEdSetCorrectBarMax (pnl, adp, hratio);
1360 adp->voffset = moveup_scrollbar (pnl, adp->voffset, 1);
1361 Update ();
1362
1363 }
1364 else if ( lineaftmv < linebefmv )
1365 {
1366 ResetClip ();
1367 inval_rect (rp.left, (Int2)(rp.top+ lineaftmv *adp->lineheight),
1368 rp.right, rp.bottom);
1369 data_collect_arrange (adp, TRUE);
1370 SeqEdSetCorrectBarMax (pnl, adp, hratio);
1371 adp->voffset = movedown_scrollbar (pnl, adp->voffset, (Int2)(1));
1372 Update ();
1373 }
1374 if ( line2aftmv < line2befmv ) {
1375 inval_rect (rp.left, (Int2)(rp.top+ line2befmv *adp->lineheight),
1376 rp.right, rp.bottom);
1377 data_collect_arrange (adp, TRUE);
1378 SeqEdSetCorrectBarMax (pnl, adp, hratio);
1379 }
1380 else if ( line2aftmv > line2befmv ) {
1381 inval_rect (rp.left, (Int2)(rp.top+ line2aftmv *adp->lineheight),
1382 rp.right, rp.bottom);
1383 data_collect_arrange (adp, TRUE);
1384 SeqEdSetCorrectBarMax (pnl, adp, hratio);
1385 }
1386 adp->feat_line = line;
1387 }
1388 adp->dirty = TRUE;
1389 return;
1390 }
1391
1392 /******************************************************************/
release_caret(PaneL pnl,Int4 position,SelStructPtr csp,SelStructPtr caret,EditAlignDataPtr adp,Int2 line)1393 static void release_caret (PaneL pnl, Int4 position, SelStructPtr csp, SelStructPtr caret, EditAlignDataPtr adp, Int2 line)
1394 {
1395 RecT rp;
1396
1397 if ( csp == NULL ) {
1398 return;
1399 }
1400 if ( adp->caret.regiontype == 0 || adp->caret.region == NULL) {
1401 /*****
1402 ErrPostEx (SEV_ERROR, 0, 0, "fail in release_caret [2]");
1403 *****/
1404 return;
1405 }
1406 if ( !is_samessp (caret, csp) ) {
1407 get_client_rect (pnl, &rp);
1408 click_caret (&rp, position, csp, caret, adp, line);
1409 if (!adp->display_panel)
1410 to_update_prompt (pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
1411 ObjMgrDeSelectAll ();
1412 }
1413 update_select_when_release (adp);
1414 }
1415
1416 /******************************************************************/
make_bspssp(SelStructPtr csp,ValNodePtr anp_list,Int4 from,Int4 to)1417 static SelStructPtr make_bspssp (SelStructPtr csp, ValNodePtr anp_list, Int4 from, Int4 to)
1418 {
1419 SeqIdPtr sip;
1420 Uint1 strand;
1421
1422 sip = (SeqIdPtr) SeqIdFromAlignNode (anp_list, csp->entityID, csp->itemID,
1423 csp->itemtype);
1424 if (sip == NULL) return NULL;
1425 strand = StrandFromAlignNode (anp_list, csp->entityID, csp->itemID,
1426 csp->itemtype);
1427 locate_region (csp, from, to, sip, strand, FALSE);
1428
1429 return csp;
1430 }
1431
1432 /******************************************************************/
get_featId_fromid(SelStructPtr csp,ValNodePtr feathead,Int2 itemsubtype)1433 static SeqIdPtr get_featId_fromid (SelStructPtr csp, ValNodePtr feathead, Int2 itemsubtype)
1434 {
1435 SelEdStructPtr feat;
1436 SeqLocPtr slp;
1437
1438 feat = get_feat_fromid (feathead, itemsubtype, csp->entityID, csp->itemID, -1, NULL);
1439 if (feat == NULL)
1440 return NULL;
1441 slp = (SeqLocPtr) feat->region;
1442 if (slp == NULL)
1443 return NULL;
1444 return SeqLocId(slp);
1445 }
1446 /******************************************************************/
make_featssp(SelStructPtr csp,ValNodePtr feathead,Int2 itemsubtype,Int4 position,Int4 from,Int4 to)1447 static SelStructPtr make_featssp (SelStructPtr csp, ValNodePtr feathead, Int2 itemsubtype, Int4 position, Int4 from, Int4 to)
1448 {
1449 SelEdStructPtr feat;
1450 SeqLocPtr slp;
1451
1452 feat = get_feat_fromid (feathead, itemsubtype, csp->entityID, csp->itemID, position, NULL);
1453 if (feat == NULL ) return NULL;
1454 slp = (SeqLocPtr) feat->region;
1455 if (slp == NULL) return NULL;
1456 if (from < 0) {
1457 locate_region (csp, SeqLocStart(slp), SeqLocStop(slp), SeqLocId (slp),
1458 SeqLocStrand(slp), FALSE);
1459 }
1460 else
1461 locate_region (csp, from, to, SeqLocId(slp), SeqLocStrand(slp), FALSE);
1462 return csp;
1463 }
1464
1465 /******************************************************************/
make_bufssp(SelStructPtr csp,SelStructPtr bufhead,Int2 itemsubtype)1466 static SelStructPtr make_bufssp (SelStructPtr csp, SelStructPtr bufhead, Int2 itemsubtype)
1467 {
1468 SelStructPtr buf;
1469 SelStructPtr ssp;
1470 SeqLocPtr slp = NULL;
1471 Uint2 subtype, type;
1472 Boolean locate = FALSE;
1473
1474 if (itemsubtype==SEQFEAT_CDREGION) {
1475 subtype = SEQFEAT_CDREGION; type = OBJ_SEQFEAT;
1476 }
1477 else if (itemsubtype==FEATDEF_CDS) {
1478 subtype = FEATDEF_CDS; type = OBJ_SEQFEAT;
1479 }
1480 else {
1481 subtype = FEATDEF_BAD; type = OBJ_BIOSEQ;
1482 }
1483 for (buf = bufhead; buf != NULL; buf = buf->next) {
1484 ssp = (SelStructPtr) buf->region;
1485 if ( buf->itemtype == subtype && ssp->itemtype == type) {
1486 slp = (SeqLocPtr) ssp->region;
1487 }
1488 else slp = NULL;
1489 if ( buf->itemtype == itemsubtype && slp != NULL ) {
1490 ssp = (SelStructPtr) buf->region;
1491 if ( is_samessp(ssp, csp) ) {
1492 locate_region(csp, SeqLocStart(slp), SeqLocStop(slp),
1493 SeqLocId(slp), SeqLocStrand(slp), FALSE);
1494 locate = TRUE;
1495 break;
1496 }
1497 }
1498 }
1499 if (!locate) return NULL;
1500 return csp;
1501 }
1502
1503 /*********************************************************
1504 ***
1505 *** locate_point
1506 ***
1507 **********************************************************/
locate_point(PoinT pt,RecT rp,Uint4 * item_id,Uint2 * the_entity_id,Uint2 * item_type,Uint2 * item_subtype,Int4 * position,Int2 * line,EditAlignDataPtr adp)1508 extern Uint1 locate_point (PoinT pt, RecT rp, Uint4 *item_id, Uint2 *the_entity_id, Uint2 *item_type, Uint2 *item_subtype, Int4 *position, Int2 *line, EditAlignDataPtr adp)
1509 {
1510 Uint4 itemid = 0;
1511 Uint2 seqEntityid = 0;
1512 Uint2 itemtype = 0;
1513 Uint2 itemsubtype = 0;
1514 Int4 pos = -1;
1515 Int4 x = -1;
1516 Int4 dx;
1517 Int2 ligne = -1;
1518 Uint1 what = BADLAND;
1519
1520 *item_id = *the_entity_id = (Uint4) 0;
1521 *item_type= *item_subtype = (Uint2) 0;
1522 *position = (Int4) -1;
1523 *line = (Int2) -1;
1524 if ( pt.x < rp.left || pt.x > rp.right ) return 0;
1525 ligne = (pt.y - rp.top) / adp->lineheight;
1526 if ( ligne >= 0 && ligne < adp->pnlLine ) {
1527 itemid = adp->item_id [ligne];
1528 seqEntityid = adp->seqEntity_id [ligne];
1529 itemtype = adp->itemtype [ligne];
1530 itemsubtype = adp->itemsubtype [ligne];
1531 }
1532 if (ligne > adp->pnlLine) {
1533 return HOLDDNLAND;
1534 }
1535 if (ligne < 0) {
1536 return HOLDUPLAND;
1537 }
1538 pos = (pt.x - rp.left - adp->margin.left);
1539 /**
1540 WriteLog ("locate ii %d ei %d it %d ist %d\n", adp->item_id [ligne], adp->seqEntity_id [ligne], adp->itemtype [ligne], adp->itemsubtype [ligne]);
1541 **/
1542 if ( adp->seqEntity_id [ligne] > 0 && adp->item_id [ligne] > 0 )
1543 {
1544 if ( pos >= 0 )
1545 {
1546 x = (Int4) (pos + (adp->charw/6)) / adp->charw;
1547 if (adp->columnpcell > 0)
1548 {
1549 dx = (Int4) x / (Int4) adp->columnpcell;
1550 dx = (Int4) (x -dx) / (Int4) adp->columnpcell;
1551 x -= dx;
1552 }
1553 x += adp->hoffset - adp->bufferstart
1554 + adp->alignline[ligne] * adp->visibleWidth;
1555 if (adp->colonne[x]==-1 && adp->seqnumber==1 && x>adp->length) {
1556 x = adp->length;
1557 } else {
1558 x = adp->colonne[x];
1559 }
1560 }
1561 else if ( pos < 0 && pos > -adp->charw )
1562 {
1563 x = adp->hoffset - adp->bufferstart
1564 + adp->alignline[ligne] * adp->visibleWidth;
1565 x = adp->colonne[x];
1566 }
1567 /* else WriteLog ("locate_point in margin\n"); */
1568 if ( x >= 0 && x <= adp->length )
1569 what = SEQLAND;
1570 else if ( x < 0 )
1571 what = SIDLAND;
1572 }
1573 if ( what == SIDLAND )
1574 {
1575 *item_id = itemid;
1576 *the_entity_id = (Uint2) seqEntityid;
1577 *item_type = (Uint2) itemtype;
1578 *item_subtype = (Uint2) itemsubtype;
1579 *position = (Int4) -1;
1580 *line = (Int2) ligne;
1581 }
1582 else if ( what == SEQLAND )
1583 {
1584 *item_id = itemid;
1585 *the_entity_id = (Uint2) seqEntityid;
1586 *item_type = (Uint2) itemtype;
1587 *item_subtype = (Uint2) itemsubtype;
1588 *position = (Int4) x;
1589 *line = (Int2) ligne;
1590 }
1591 return what;
1592 }
1593
on_click(PaneL pnl,PoinT pt)1594 extern void on_click (PaneL pnl, PoinT pt)
1595 {
1596 EditAlignDataPtr adp;
1597 SeqAlignPtr salp;
1598 SeqIdPtr the_sip;
1599 SelStruct sp;
1600 SelStructPtr ssp = NULL;
1601 SelStructPtr this_selection = NULL;
1602 RecT rp;
1603 Int4 position;
1604 Int4 pos_inseq;
1605 Int2 line;
1606 Uint2 itemsubtype;
1607 Uint1 what;
1608
1609 if ( ( adp = GetAlignDataPanel (pnl)) == NULL ) return;
1610 if ( adp->seqnumber == 0 ) return;
1611 get_client_rect (pnl, &rp);
1612 sp.regiontype = 0;
1613 sp.region = NULL;
1614 what = locate_point (pt, rp, &sp.itemID, &sp.entityID, &sp.itemtype,
1615 &itemsubtype, &position, &line, adp);
1616 if ( what >= BADLAND )
1617 return;
1618 if ( position > adp->length +1) {
1619 ErrPostEx (SEV_ERROR, 0, 0, "position> length");
1620 return;
1621 }
1622 adp->select_block = NULL;
1623 adp->mouse_mode = MOUSE_CLICK;
1624 /***
1625 WriteLog("click what %d %d %d %d %d pos %d lin %d \n", (int) what,
1626 (int) sp.itemID, (int) sp.entityID, (int)sp.itemtype, (int)itemsubtype,
1627 (int) position, (int)line);
1628 ****/
1629 salp = (SeqAlignPtr) adp->sap_align->data;
1630 switch (what)
1631 {
1632 case SIDLAND:
1633 if ( itemsubtype == FEATDEF_BAD )
1634 {
1635 ssp = make_bspssp (&sp, adp->anp_list, 0, -2);
1636 adp->clickwhat = CLICKID_BIOSEQ;
1637 if (dblClick) {
1638 if (adp->edit_mode==SEQ_VIEW || adp->edit_mode==SEQ_EDIT || adp->edit_mode==ALIGN_EDIT) {
1639 WatchCursor ();
1640 Update ();
1641 GatherProcLaunch (OMPROC_EDIT, FALSE, sp.entityID, sp.itemID, OBJ_BIOSEQ, 0, 0, OBJ_BIOSEQ, 0);
1642 ArrowCursor ();
1643 Update ();
1644 ssp= NULL;
1645 }
1646 }
1647 }
1648 else if (sp.itemtype == OBJ_SEQFEAT)
1649 {
1650 if (dblClick)
1651 {
1652 WatchCursor ();
1653 Update ();
1654 GatherProcLaunch (OMPROC_EDIT, FALSE, sp.entityID, sp.itemID, sp.itemtype, 0, 0, sp.itemtype, 0);
1655 ArrowCursor ();
1656 Update ();
1657 ssp = NULL;
1658 }
1659 else {
1660 the_sip = get_featId_fromid(&sp, adp->seqfeat, itemsubtype);
1661 pos_inseq = AlignCoordToSeqCoord (position, the_sip, salp, adp->sqloc_list, 0);
1662 ssp = make_featssp (&sp, adp->seqfeat, itemsubtype, pos_inseq, -1, -1);
1663 adp->clickwhat = CLICKID_SEQFEAT;
1664 }
1665 }
1666 else if( itemsubtype >=EDITDEF_RF1 && itemsubtype<=EDITDEF_RF6 )
1667 {
1668 ssp = make_bufssp (&sp, adp->buffer, itemsubtype);
1669 adp->clickwhat = CLICKID_FEAT;
1670 }
1671 if (ssp != NULL) {
1672 click_id (pnl, ssp, adp);
1673 }
1674 break;
1675 case SEQLAND:
1676 if ( position >=0 ) {
1677 adp->clickwhat = CLICKSEQ_BIOSEQ;
1678 if(adp->edit_mode==SEQ_VIEW || adp->edit_mode==SEQ_EDIT || adp->edit_mode == ALIGN_EDIT)
1679 {
1680 if ( itemsubtype == FEATDEF_BAD )
1681 {
1682 if (!shftKey) {
1683 ssp=make_bspssp (&sp, adp->anp_list, position, position);
1684 click_caret (&rp, position, ssp, &(adp->caret), adp, line);
1685 if (!ctrlKey)
1686 ObjMgrDeSelectAll ();
1687 }
1688 else
1689 {
1690 this_selection = get_closest_selection(&(adp->caret),salp, &sp, adp->sqloc_list);
1691 if (this_selection!=NULL) {
1692 extend_selectregion (adp, this_selection, position, adp->caret_orig, FALSE, pnl);
1693 }
1694 }
1695 if (!adp->display_panel)
1696 to_update_prompt(pnl,&(adp->caret), salp, adp->sqloc_list, FALSE, adp->printid);
1697 adp->edit_pos = position;
1698 adp->caret_line = line;
1699 }
1700 else if (sp.itemtype == OBJ_SEQFEAT)
1701 {
1702 if (dblClick)
1703 {
1704 WatchCursor ();
1705 Update ();
1706 GatherProcLaunch (OMPROC_EDIT, FALSE, sp.entityID, sp.itemID, sp.itemtype, 0, 0, sp.itemtype, 0);
1707 ArrowCursor ();
1708 Update ();
1709 }
1710 else {
1711 the_sip = get_featId_fromid(&sp, adp->seqfeat, itemsubtype);
1712 pos_inseq = AlignCoordToSeqCoord (position, the_sip, salp, adp->sqloc_list, 0);
1713 ssp = make_featssp (&sp, adp->seqfeat, itemsubtype, pos_inseq, -1, -1);
1714 if (ssp != NULL)
1715 {
1716 click_feat (pnl, position, ssp, adp, line);
1717 adp->feat_pos = position;
1718 adp->clickwhat = CLICKSEQ_SEQFEAT;
1719 }
1720 }
1721 }
1722 }
1723 }
1724 break;
1725 default:
1726 adp->clickwhat = NOCLICK;
1727 break;
1728 }
1729 Update ();
1730 }
1731
1732 /**************************************
1733 ***
1734 *** Drag Procedure
1735 *** 2: drag on sequence
1736 ***
1737 ***************************************/
1738 /*if CtrlKey is pushed and the user clicks within a selected region,
1739 don't move the caret*/
getcurrentcaretpos(Int4 position,Uint2 eID,Uint2 iID,Uint2 itype,Boolean direction)1740 static Int4 getcurrentcaretpos (Int4 position, Uint2 eID, Uint2 iID, Uint2 itype, Boolean direction)
1741 {
1742 SelStructPtr sspsel=NULL;
1743
1744 if (ctrlKey){
1745 sspsel=ObjMgrGetSelected();
1746 if (sspsel != NULL)
1747 {
1748 for (; sspsel != NULL; sspsel = sspsel->next)
1749 {
1750 if ( checkssp_for_editor (sspsel) && is_sameId (sspsel->entityID, sspsel->itemID, sspsel->itemtype, 255, eID, iID, itype, 255) )
1751 {
1752 if ( (position>= SeqLocStart((SeqLocPtr)sspsel->region)) &&
1753 (position<= SeqLocStop((SeqLocPtr)sspsel->region))){
1754 if (direction)
1755 return SeqLocStart((SeqLocPtr)sspsel->region);
1756 else
1757 return SeqLocStop((SeqLocPtr)sspsel->region);
1758 }
1759 }
1760 }
1761 }
1762 }
1763 return -1;
1764 }
1765
on_drag(PaneL pnl,PoinT pt)1766 extern void on_drag (PaneL pnl, PoinT pt)
1767 {
1768 EditAlignDataPtr adp;
1769 SeqAlignPtr salp;
1770 SeqIdPtr the_sip;
1771 SelStruct sp;
1772 SelStructPtr this_selection = NULL;
1773 RecT rp;
1774 Int4 position;
1775 Int2 line;
1776 Uint2 itemsubtype;
1777 Int4 from, to,
1778 caret_origseq, new_caret_orig;
1779 SeqLocPtr slp;
1780 Uint1 direction = Seq_strand_plus;
1781
1782
1783 if ( ( adp = GetAlignDataPanel (pnl)) == NULL ) return;
1784 if ( adp->seqnumber == 0 ) return;
1785 get_client_rect (pnl, &rp);
1786 sp.regiontype = 0;
1787 sp.region = NULL;
1788 locate_point (pt, rp, &sp.itemID, &sp.entityID, &sp.itemtype, &itemsubtype, &position, &line, adp);
1789 if ( position > adp->length) {
1790 ErrPostEx (SEV_ERROR, 0, 0, "position> length");
1791 return;
1792 }
1793 salp = (SeqAlignPtr) adp->sap_align->data;
1794 switch ( adp->clickwhat )
1795 {
1796 case CLICKID_BIOSEQ:
1797 break;
1798 case CLICKID_SEQFEAT:
1799 break;
1800 case CLICKID_FEAT:
1801 break;
1802 case CLICKSEQ_BIOSEQ:
1803 if (position>=0) {
1804 if (position != adp->edit_pos || adp->mouse_mode == MOUSE_DRAG)
1805 {
1806 this_selection = &sp;
1807 if (is_sameId (this_selection->entityID, this_selection->itemID,
1808 this_selection->itemtype, 255, adp->caret.entityID, adp->caret.itemID,
1809 adp->caret.itemtype, 255))
1810 {
1811 if (position < adp->edit_pos) {
1812 direction = Seq_strand_minus;
1813 }
1814 the_sip = SeqLocId((SeqLocPtr)adp->caret.region);
1815 if (the_sip) {
1816 caret_origseq = AlignCoordToSeqCoord (adp->caret_orig, the_sip, salp, adp->sqloc_list, 0);
1817 if (adp->mouse_mode == MOUSE_CLICK)
1818 {
1819 new_caret_orig = getcurrentcaretpos (caret_origseq, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype, (Boolean)(direction==Seq_strand_plus));
1820 if (new_caret_orig<0)
1821 new_caret_orig=caret_origseq;
1822 else if (caret_origseq != new_caret_orig) {
1823 adp->caret_orig = SeqCoordToAlignCoord (new_caret_orig, the_sip, salp, 0, 0);
1824 }
1825 }
1826 else {
1827 new_caret_orig=caret_origseq;
1828 }
1829 from = new_caret_orig;
1830 to = AlignCoordToSeqCoord (position, the_sip, salp, adp->sqloc_list, 0);
1831 if (from > to) {
1832 from = to;
1833 to = new_caret_orig;
1834 }
1835 slp = SeqLocIntNew (from, to, direction, the_sip);
1836 ObjMgrAlsoSelect (this_selection->entityID, this_selection->itemID,
1837 this_selection->itemtype, OM_REGION_SEQLOC, slp);
1838 adp->edit_pos = position;
1839 adp->mouse_mode = MOUSE_DRAG;
1840 }
1841 }
1842 }
1843 else if (adp->mouse_mode == MOUSE_CLICK)
1844 adp->mouse_mode = MOUSE_DRAG;
1845 }
1846 break;
1847
1848 case CLICKSEQ_SEQFEAT:
1849 /********************
1850 if ( select != NULL )
1851 {
1852 sspei = (Uint2) select->entityID;
1853 sspii = (Uint2) select->itemID;
1854 sspit = (Uint2) select->itemtype;
1855 sspist= (Uint2) select->regiontype;
1856 if (position >= 0 && position < adp->length && sspit == OBJ_SEQFEAT)
1857 {
1858 ssp = is_selectedbyID (sspei, sspii, sspit);
1859 if ( ssp == NULL )
1860 {
1861 click_feat (pnl, position, adp->select, adp, line);
1862 ssp = is_selectedbyID (sspei, sspii, sspit);
1863 }
1864 if ( ssp != NULL && position != adp->feat_pos )
1865 {
1866 prec = NULL;
1867 pos_inseq = AlignCoordToSeqCoord (adp->feat_pos, SeqLocId((SeqLocPtr)ssp->region), salp, adp->sqloc_list, 0);
1868 feat = get_feat_fromid (adp->seqfeat, sspist, sspei, sspii, pos_inseq, &prec);
1869 if ( feat != NULL )
1870 {
1871 drag_feat (pnl, position, feat, adp, line, sspist, prec, feat->next, ssp);
1872 }
1873 adp->feat_pos = position;
1874 }
1875 }
1876 }
1877 **********************/
1878 break;
1879
1880 case NOCLICK:
1881 break;
1882 default:
1883 break;
1884 }
1885 Update ();
1886 }
1887
1888 /**************************************
1889 ***
1890 *** Hold Procedure
1891 *** 4: hold on sequence
1892 *** 5: hold on sequence
1893 ***
1894 ***************************************/
on_hold(PaneL pnl,PoinT pt)1895 extern void on_hold (PaneL pnl, PoinT pt)
1896 {
1897 EditAlignDataPtr adp;
1898 SeqAlignPtr salp;
1899 RecT rp;
1900 SelStruct sp;
1901 SelStructPtr this_selection = NULL;
1902 Int4 position;
1903 Int2 line;
1904 Uint2 itemsubtype;
1905 Uint1 what;
1906
1907 SelEdStructPtr feat, prec;
1908
1909 if ( ( adp = GetAlignDataPanel (pnl)) == NULL ) return;
1910 if ( adp->seqnumber == 0 ) return;
1911 get_client_rect (pnl, &rp);
1912 sp.regiontype = 0;
1913 sp.region = NULL;
1914 what = locate_point (pt, rp, &sp.itemID, &sp.entityID, &sp.itemtype, &itemsubtype, &position, &line, adp);
1915 ResetClip ();
1916 salp = (SeqAlignPtr) adp->sap_align->data;
1917 if ( what == HOLDDNLAND ) {
1918 if (adp->voffset >= adp->nlines-1) return;
1919 adp->voffset = movedown_scrollbar (pnl, adp->voffset, (Int2)1);
1920 Update ();
1921 if ( adp->clickwhat == CLICKSEQ_BIOSEQ)
1922 {
1923 position = adp->edit_pos + adp->visibleWidth;
1924 if (position > adp->length) position = adp->length;
1925 adp->caret_line++;
1926 dragcaret_selectrgn (pnl, position, get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list), &(adp->caret), adp, adp->caret_line);
1927 setposition_tossp (&(adp->caret), position, position);
1928 adp->edit_pos = position;
1929 }
1930 else if (adp->clickwhat== CLICKSEQ_SEQFEAT || adp->clickwhat == CLICKSEQ_FEAT)
1931 {
1932 prec = NULL;
1933 this_selection = get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list);
1934 feat = get_feat_fromid (adp->feat, this_selection->regiontype, this_selection->entityID, this_selection->itemID, adp->feat_pos, &prec);
1935 if ( feat != NULL )
1936 {
1937 adp->feat_line++;
1938 position = adp->feat_pos + adp->visibleWidth;
1939 drag_feat (pnl, position, feat, adp, adp->feat_line, this_selection->regiontype, prec, feat->next, NULL);
1940 }
1941 adp->feat_pos = position;
1942 }
1943 }
1944 else if ( what == HOLDUPLAND )
1945 {
1946 if (adp->voffset == 0 || adp->hoffset == 0) return;
1947 adp->voffset = moveup_scrollbar (pnl, adp->voffset, (Int2)1);
1948 Update ();
1949 if ( adp->clickwhat == CLICKSEQ_BIOSEQ)
1950 {
1951 position = adp->edit_pos - adp->visibleWidth;
1952 if (position < 0) position = 0;
1953 adp->caret_line--;
1954 dragcaret_selectrgn (pnl,position,get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list),&(adp->caret), adp, adp->caret_line);
1955 setposition_tossp (&(adp->caret), position, position);
1956 adp->edit_pos = position;
1957 }
1958 else if (adp->clickwhat == CLICKSEQ_SEQFEAT || adp->clickwhat == CLICKSEQ_FEAT)
1959 {
1960 this_selection = get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list);
1961 feat = get_feat_fromid (adp->feat, this_selection->regiontype, this_selection->entityID, this_selection->itemID, adp->feat_pos, &prec);
1962 if ( feat != NULL )
1963 {
1964 adp->feat_line--;
1965 position = adp->feat_pos - adp->visibleWidth;
1966 drag_feat (pnl, position, feat, adp, adp->feat_line, this_selection->regiontype, prec, feat->next, NULL);
1967 }
1968 adp->feat_pos = position;
1969 }
1970 }
1971 Update ();
1972 }
1973
1974 /**************************************
1975 ***
1976 *** Release Procedure
1977 ***
1978 ***************************************/
on_release(PaneL pnl,PoinT pt)1979 extern void on_release (PaneL pnl, PoinT pt)
1980 {
1981 EditAlignDataPtr adp;
1982 SelStruct sp;
1983 SelStructPtr ssp = NULL;
1984 RecT rp;
1985 Int2 line;
1986 Int4 position;
1987 Uint2 itemsubtype;
1988
1989 if ( ( adp = GetAlignDataPanel (pnl)) == NULL ) return;
1990 if ( adp->seqnumber == 0 ) return;
1991 get_client_rect (pnl, &rp);
1992 sp.regiontype = 0;
1993 sp.region = NULL;
1994 locate_point (pt, rp, &sp.itemID, &sp.entityID, &sp.itemtype, &itemsubtype, &position, &line, adp);
1995 if ( position > adp->length +1) {
1996 ErrPostEx (SEV_ERROR, 0, 0, "position> length");
1997 return;
1998 }
1999 switch ( adp->clickwhat )
2000 {
2001 case CLICKID_BIOSEQ:
2002 break;
2003 case CLICKSEQ_BIOSEQ:
2004 if ( position >= 0 && adp->mouse_mode == MOUSE_DRAG) {
2005 ssp = make_bspssp (&sp, adp->anp_list, position, position);
2006 if (ssp != NULL) {
2007 release_caret (pnl, position, ssp, &adp->caret, adp, line);
2008 adp->edit_pos = position;
2009 }
2010 }
2011 break;
2012 case NOCLICK:
2013 ObjMgrDeSelectAll ();
2014 break;
2015 default:
2016 break;
2017 }
2018 adp->clickwhat = NOCLICK;
2019 adp->mouse_mode = MOUSE_RELEASE;
2020 if (!adp->display_panel) {
2021 update_edititem (pnl);
2022 update_savefeatitem (pnl);
2023 update_translateitem (pnl, adp->seqfeat, adp->feat);
2024 update_codonstartbt (pnl, adp->seqfeat, adp->feat);
2025 }
2026 Update ();
2027 }
2028
2029 #define FINDNEXT 14
2030 #define FINDPREV 16
2031 #define SNLM_DEL 8
2032 #define NLM_RETURN 13
2033
2034 /*-----------------------*/
gap_insert(EditAlignDataPtr adp)2035 static Boolean gap_insert (EditAlignDataPtr adp)
2036 {
2037 Int4 position;
2038 Int4 oldbufferlength;
2039 Int2 newvisibleLine,
2040 oldvisibleLine;
2041 Boolean insert = FALSE;
2042
2043 if ( (adp->bufferlength+1) >= adp->minbufferlength + adp->editbuffer) {
2044 ErrPostEx (SEV_ERROR, 0, 0, "Save alignment before");
2045 return FALSE;
2046 }
2047 position = SeqLocStart((SeqLocPtr)adp->caret.region);
2048 insert = AlignDataGapAddProc ('-', position, adp->linebuff, adp->bufferlength, adp->caret.entityID, adp->caret.itemID);
2049 if (insert)
2050 {
2051 oldbufferlength = adp->bufferlength;
2052 adp->bufferlength = CleanBufferProc(adp->linebuff, adp->seqnumber, adp->bufferlength +1);
2053 adp->edit_pos++;
2054 adp->colonne [adp->bufferlength] =adp->colonne [adp->bufferlength -1] +1;
2055 oldvisibleLine =1 +MIN ((Int2) ((oldbufferlength-1) / adp->visibleWidth), (Int2) ((adp->pnlLine -3)/ (adp->seqnumber +1 +2)));
2056 newvisibleLine =1 +MIN ((Int2) ((adp->bufferlength-1) / adp->visibleWidth), (Int2) ((adp->pnlLine -3)/ (adp->seqnumber +1 +2)));
2057 if ( newvisibleLine < 1)
2058 newvisibleLine = 1;
2059 if (newvisibleLine != oldvisibleLine)
2060 {
2061 adp->visibleLength =adp->visibleWidth * newvisibleLine;
2062 }
2063 if(oldbufferlength<adp->bufferlength && adp->length<adp->minbufferlength)
2064 {
2065 adp->length++;
2066 }
2067 return TRUE;
2068 }
2069 return FALSE;
2070 }
2071
on_key(SlatE s,Char ch)2072 extern void on_key (SlatE s, Char ch)
2073 {
2074 PaneL pnl;
2075 EditAlignDataPtr adp;
2076 SeqAlignPtr salp;
2077 RecT rp;
2078 SeqLocPtr slp;
2079 SelStructPtr ssp;
2080 Int4 caretstart;
2081 Int4 new_caretstart;
2082 Int4 k;
2083 Int4 line, oldline,
2084 column, oldcolumn;
2085 Int4 j;
2086 Boolean is_caretvisible;
2087 Boolean minusstrand;
2088 CharPtr str;
2089 Int4 width;
2090
2091 if ( (int) ch == 0 ) return;
2092
2093 pnl = (PaneL) s;
2094 Select (pnl);
2095 if ( (adp = GetAlignDataPanel (pnl)) == NULL ) return;
2096 if ( adp->seqnumber == 0 ) return;
2097 get_client_rect (pnl, &rp);
2098 if ( adp->caret.regiontype == 0 || adp->caret.region == NULL ) {
2099 return;
2100 }
2101 slp = (SeqLocPtr) adp->caret.region;
2102 caretstart = SeqLocStart(slp);
2103 if (caretstart < 0) {
2104 ErrPostEx (SEV_ERROR, 0, 0, "CARET position negative");
2105 return;
2106 }
2107 is_caretvisible = (Boolean)(caretstart >= adp->hoffset
2108 && caretstart <= adp->hoffset + adp->visibleLength);
2109 if (!is_caretvisible)
2110 {
2111 adp->voffset=(Int2)(caretstart /(adp->visibleWidth));
2112 ResetClip ();
2113 SeqEdSetValueScrollBar (pnl, (Int2) adp->voffset);
2114 data_collect_arrange (adp, TRUE);
2115 Select (pnl);
2116 inval_panel (pnl, -1, -1);
2117 Update ();
2118 }
2119 width = adp->visibleWidth;
2120 if (adp->columnpcell > 0)
2121 width += (Int2) adp->visibleWidth / (Int2) adp->columnpcell;
2122 salp = (SeqAlignPtr) adp->sap_align->data;
2123 if (!ctrlKey && adp->edit_mode == SEQ_EDIT )
2124 {
2125 if ( (str = char_to_insert (&ch, 1, adp->mol_type)) != NULL)
2126 {
2127 if (adp->input_format == OBJ_BIOSEQ)
2128 {
2129 ssp = ObjMgrGetSelected ();
2130 if ( checkssp_for_editor(ssp) && ssp->itemtype == OBJ_BIOSEQ)
2131 {
2132 do_cut (pnl, adp, ssp, FALSE);
2133 }
2134 else ssp = NULL;
2135 if (insertchar_atcaret (str, adp))
2136 {
2137 adp->dirty = TRUE;
2138 ObjMgrSetDirtyFlag (adp->caret.entityID, TRUE);
2139
2140 ObjMgrSendMsg (OM_MSG_UPDATE, adp->caret.entityID, adp->caret.itemID, adp->caret.itemtype);
2141
2142 if (adp->edit_item.entityID == 0)
2143 {
2144 adp->edit_item.entityID = adp->caret.entityID;
2145 adp->edit_item.itemID = adp->caret.itemID;
2146 adp->edit_item.itemtype = adp->caret.itemtype;
2147 }
2148 else if (adp->edit_item.entityID != adp->caret.entityID && adp->edit_item.itemID != adp->caret.itemID) {
2149 ErrPostEx (SEV_ERROR, 0, 0, "Warning in SetWindowTimer");
2150 adp->edit_item.entityID = 0;
2151 adp->edit_item.itemID = 0;
2152 adp->edit_item.itemtype = 0;
2153 }
2154 if (! typing_timerInUse)
2155 {
2156 typing_timerInUse = TRUE;
2157 timerCount = 0;
2158 }
2159 }
2160 MemFree (str);
2161 }
2162 else if (adp->input_format == OBJ_SEQALIGN)
2163 {
2164 Beep ();
2165 }
2166 return;
2167 }
2168 }
2169 if (!ctrlKey && adp->edit_mode == ALIGN_EDIT )
2170 {
2171 if (ch=='-') {
2172 if (adp->length < adp->minbufferlength) {
2173 if (gap_insert (adp)) {
2174 setposition_tossp (&adp->caret, caretstart+1, caretstart+1);
2175 adp->dirty = TRUE;
2176 inval_panel (pnl, -1, -1);
2177 }
2178 }
2179 return;
2180 }
2181 }
2182
2183 switch ((int) TO_UPPER(ch))
2184 {
2185 case SNLM_DEL:
2186 case NLM_DEL:
2187 if ( adp->edit_mode == SEQ_EDIT )
2188 {
2189 k = checkOMss_for_itemtype (OBJ_BIOSEQ);
2190 if ( k > 0 ) {
2191 ssp = getOMselect_for_itemtype (OBJ_BIOSEQ);
2192 }
2193 else {
2194 ssp = (SelStructPtr) MemNew (sizeof (SelStruct));
2195 ssp->entityID = adp->caret.entityID;
2196 ssp->itemID = adp->caret.itemID;
2197 ssp->itemtype = adp->caret.itemtype;
2198 locate_region (ssp, caretstart - 1, caretstart - 1, SeqLocId(slp), Seq_strand_plus, FALSE);
2199 ObjMgrSelect (ssp->entityID, ssp->itemID, ssp->itemtype,
2200 ssp->regiontype, ssp->region);
2201 }
2202 if ( ssp != NULL ) {
2203 if (adp->input_format == OBJ_BIOSEQ)
2204 {
2205 if (do_cut (pnl, adp, ssp, FALSE))
2206 {
2207 if (adp->edit_item.entityID == 0)
2208 {
2209 adp->edit_item.entityID = adp->caret.entityID;
2210 adp->edit_item.itemID = adp->caret.itemID;
2211 adp->edit_item.itemtype = adp->caret.itemtype;
2212 }
2213 else if (adp->edit_item.entityID != adp->caret.entityID && adp->edit_item.itemID != adp->caret.itemID) {
2214 ErrPostEx (SEV_ERROR, 0, 0, "Warning in SetWindowTimer");
2215 adp->edit_item.entityID = 0;
2216 adp->edit_item.itemID = 0;
2217 adp->edit_item.itemtype = 0;
2218 }
2219 if (! deleting_timerInUse) {
2220 deleting_timerInUse = TRUE;
2221 timerCount = 0;
2222 }
2223 }
2224 }
2225 else if (adp->input_format == OBJ_SEQALIGN)
2226 {
2227 Beep ();
2228 }
2229 }
2230 }
2231 break;
2232
2233 case NLM_LEFT:
2234 if (ctrlKey) {
2235 adp->cur_pat = ShowPrecPattern(adp->match_pat, adp->cur_pat, adp->edit_pos);
2236 }
2237 else if ( SeqLocStart(slp) > 0 )
2238 {
2239 minusstrand=(Boolean)(SeqLocStrand((SeqLocPtr)adp->caret.region) == Seq_strand_minus);
2240 if (minusstrand)
2241 new_caretstart = caretstart+1;
2242 else
2243 new_caretstart = caretstart-1;
2244 SeqPosToLineColumn (adp->caret.itemID, adp->caret.entityID, adp->caret.itemtype, caretstart, &oldline, &oldcolumn, adp->hoffset, adp);
2245 SeqPosToLineColumn (adp->caret.itemID, adp->caret.entityID, adp->caret.itemtype, new_caretstart, &line, &column, adp->hoffset, adp);
2246 setposition_tossp (&adp->caret, new_caretstart, new_caretstart);
2247 if ( oldline>=0 && ( abs(oldcolumn - column) >2 || column <0))
2248 inval_rect((Int2)(rp.left+adp->margin.left+(oldcolumn-2)*adp->charw),
2249 (Int2)(rp.top + adp->lineheight * oldline),
2250 (Int2)(rp.left+ adp->margin.left + (oldcolumn+2)*adp->charw),
2251 (Int2)(rp.top + adp->lineheight * (oldline+1)));
2252 if ( line>=0 && column>=0 ) {
2253 inval_rect((Int2)(rp.left +adp->margin.left +(column-2)*adp->charw),
2254 (Int2)(rp.top + adp->lineheight * line),
2255 (Int2)(rp.left + adp->margin.left + (column+2)*adp->charw),
2256 (Int2)(rp.top + adp->lineheight * (line+1)));
2257 }
2258 caretstart = SeqLocStart(slp);
2259 if ( ! shftKey ) {
2260 slp = (SeqLocPtr) adp->caret.region;
2261 if (!adp->display_panel) {
2262 to_update_prompt (pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
2263 }
2264 adp->caret_orig = caretstart;
2265 if (minusstrand)
2266 adp->edit_pos--;
2267 else
2268 adp->edit_pos++;
2269 ObjMgrDeSelectAll ();
2270 }
2271 else {
2272 dragcaret_selectrgn (pnl, caretstart, get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list), &(adp->caret), adp, line);
2273 adp->edit_pos --;
2274 }
2275 }
2276 break;
2277
2278 case NLM_RIGHT:
2279 if (ctrlKey) {
2280 adp->cur_pat = ShowNextPattern(adp->match_pat, adp->cur_pat, adp->edit_pos);
2281 }
2282 else if ( SeqLocStart(slp) < adp->length )
2283 {
2284 minusstrand=(Boolean)(SeqLocStrand((SeqLocPtr)adp->caret.region) == Seq_strand_minus);
2285 if (minusstrand)
2286 new_caretstart = caretstart-1;
2287 else
2288 new_caretstart = caretstart+1;
2289 SeqPosToLineColumn (adp->caret.itemID, adp->caret.entityID, adp->caret.itemtype, caretstart, &oldline, &oldcolumn, adp->hoffset, adp);
2290 SeqPosToLineColumn (adp->caret.itemID, adp->caret.entityID, adp->caret.itemtype, new_caretstart, &line, &column, adp->hoffset, adp);
2291 setposition_tossp (&adp->caret, new_caretstart, new_caretstart);
2292 if ( oldline>=0 && ( abs(oldcolumn - column) >2 || column <0))
2293 {
2294 inval_rect ((Int2) (rp.left +adp->margin.left +(oldcolumn-2) *adp->charw), (Int2)(rp.top + adp->lineheight * oldline), (Int2)(rp.left+ adp->margin.left + (oldcolumn+2)*adp->charw), (Int2)(rp.top + adp->lineheight * (oldline+1)));
2295 }
2296 if ( line>=0 && column>=0 ) {
2297 inval_rect ((Int2) (rp.left +adp->margin.left +(column-3) *adp->charw), (Int2)(rp.top + adp->lineheight * line), (Int2)(rp.left + adp->margin.left + (column+2)*adp->charw), (Int2)(rp.top + adp->lineheight * (line+1)));
2298 }
2299 caretstart = SeqLocStart(slp);
2300 if ( ! shftKey ) {
2301 slp = (SeqLocPtr) adp->caret.region;
2302 if (!adp->display_panel)
2303 to_update_prompt(pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
2304 adp->caret_orig = caretstart;
2305 if (minusstrand)
2306 adp->edit_pos += 1;
2307 else
2308 adp->edit_pos -= 1;
2309 ObjMgrDeSelectAll ();
2310 }
2311 else {
2312 dragcaret_selectrgn (pnl, caretstart, get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list), &(adp->caret), adp, line);
2313 adp->edit_pos ++;
2314 }
2315 }
2316 break;
2317
2318 case NLM_UP:
2319 SeqPosToLineColumn (adp->caret.itemID, adp->caret.entityID,
2320 adp->caret.itemtype, caretstart, &line, &column,
2321 adp->hoffset, adp);
2322 adp->caret_line = line;
2323 j = nextlineup (adp->caret_line, adp->itemtype, adp->itemsubtype);
2324 if ( j < 0 )
2325 {
2326 Int4 pos;
2327 if (adp->voffset != 0 && adp->hoffset != 0)
2328 {
2329 ResetClip ();
2330 adp->voffset = moveup_scrollbar (pnl, adp->voffset, 1);
2331 Update ();
2332 if (is_samess_ses (&(adp->caret), (SelEdStructPtr) adp->firstssp->region) )
2333 {
2334 pos = SeqLocStart(slp) - adp->visibleWidth;
2335 if (pos < 0) pos = 0;
2336 adp->caret_line = 0;
2337 if ( ! shftKey ) {
2338 click_caret (&rp, pos, &(adp->caret), &(adp->caret), adp, adp->caret_line);
2339 if (!adp->display_panel)
2340 to_update_prompt (pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
2341 ObjMgrDeSelectAll ();
2342 }
2343 else {
2344 dragcaret_selectrgn (pnl, pos, get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list), &(adp->caret), adp, adp->caret_line);
2345 setposition_tossp (&(adp->caret), pos, pos);
2346 adp->edit_pos = pos;
2347 }
2348 }
2349 }
2350 }
2351 else if ( j != adp->caret_line )
2352 {
2353 SeqIdPtr sip;
2354 Uint2 eid, it;
2355 Uint4 iid;
2356 eid = adp->caret.entityID;
2357 iid = adp->caret.itemID;
2358 it = adp->caret.itemtype;
2359 SeqPosToLineColumn (iid, eid, it, caretstart, &oldline,
2360 &oldcolumn, adp->hoffset, adp);
2361 if (adp->alignline[adp->caret_line] != adp->alignline[j])
2362 {
2363 line=abs(adp->alignline[adp->caret_line] -adp->alignline[j]);
2364 caretstart = caretstart -(line *adp->visibleWidth);
2365 if (caretstart < 0) caretstart = 0;
2366 setposition_tossp (&(adp->caret), caretstart, caretstart);
2367 }
2368 else
2369 caretstart = SeqLocStart(slp);
2370 if (adp->seqEntity_id[adp->caret_line] != adp->seqEntity_id[j]
2371 || adp->item_id[adp->caret_line] != adp->item_id[j])
2372 {
2373 eid = adp->seqEntity_id[j];
2374 iid = adp->item_id[j];
2375 it = adp->itemtype[j];
2376 adp->caret.entityID = eid;
2377 adp->caret.itemID = iid;
2378 adp->caret.itemtype = it;
2379 sip=(SeqIdPtr)SeqIdFromAlignNode(adp->anp_list,eid, iid, it);
2380 replace_region (&(adp->caret), eid, iid, it, caretstart, caretstart, sip, Seq_strand_plus, FALSE);
2381 }
2382 adp->caret_line = j;
2383 SeqPosToLineColumn (iid, eid, it, caretstart, &line, &column,
2384 adp->hoffset, adp);
2385 inval_rect((Int2)(rp.left+adp->margin.left+(column-2)* adp->charw), (Int2)(rp.top + adp->lineheight * oldline), (Int2)(rp.left+ adp->margin.left + (column+2)*adp->charw), (Int2)(rp.top + adp->lineheight * (oldline+1)));
2386 inval_rect((Int2)(rp.left+adp->margin.left+(column-2)* adp->charw), (Int2)(rp.top + adp->lineheight * line), (Int2)(rp.left + adp->margin.left + (column+2)*adp->charw), (Int2)(rp.top + adp->lineheight * (line+1)));
2387 if ( ! shftKey )
2388 {
2389 slp = (SeqLocPtr) adp->caret.region;
2390 if (!adp->display_panel)
2391 to_update_prompt (pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
2392 adp->caret_orig = caretstart;
2393 adp->edit_pos = caretstart;
2394 ObjMgrDeSelectAll ();
2395 }
2396 else {
2397 dragcaret_selectrgn (pnl, caretstart, get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list), &(adp->caret), adp, line);
2398 adp->edit_pos -= adp->visibleWidth;
2399 }
2400 }
2401 break;
2402
2403 case NLM_DOWN:
2404 SeqPosToLineColumn (adp->caret.itemID, adp->caret.entityID,
2405 adp->caret.itemtype, caretstart, &line, &column,
2406 adp->hoffset, adp);
2407 adp->caret_line = line;
2408 j = nextlinedown (adp->caret_line, adp->pnlLine, adp->itemtype, adp->itemsubtype);
2409 if ( j < 0 )
2410 {
2411 Int4 pos;
2412 if (adp->voffset < adp->nlines-1)
2413 {
2414 ResetClip ();
2415 adp->voffset = movedown_scrollbar (pnl, adp->voffset, (Int2)1);
2416 Update ();
2417 if (is_samess_ses (&(adp->caret), adp->lastses) )
2418 {
2419 pos = SeqLocStart(slp) + adp->visibleWidth;
2420 if (pos > adp->length) pos = adp->length;
2421 adp->caret_line = adp->pnlLine -1;
2422 if ( ! shftKey ) {
2423 click_caret (&rp, pos, &(adp->caret), &(adp->caret), adp, adp->caret_line);
2424 if (!adp->display_panel)
2425 to_update_prompt (pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
2426 ObjMgrDeSelectAll ();
2427 }
2428 else {
2429 dragcaret_selectrgn (pnl, pos, get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list), &(adp->caret), adp, adp->caret_line);
2430 setposition_tossp (&(adp->caret), pos, pos);
2431 adp->edit_pos = pos;
2432 }
2433 }
2434 }
2435 }
2436 else if (j != adp->caret_line )
2437 {
2438 SeqIdPtr sip;
2439 Uint2 eid, it;
2440 Uint4 iid;
2441 eid = adp->caret.entityID;
2442 iid = adp->caret.itemID;
2443 it = adp->caret.itemtype;
2444 SeqPosToLineColumn (adp->caret.itemID, adp->caret.entityID,
2445 adp->caret.itemtype, caretstart, &oldline,
2446 &oldcolumn, adp->hoffset, adp);
2447 if (adp->alignline[adp->caret_line] != adp->alignline[j])
2448 {
2449 line=abs(adp->alignline[adp->caret_line] -adp->alignline[j]);
2450 caretstart = caretstart + (line * adp->visibleWidth);
2451 if (caretstart > adp->length)
2452 caretstart = adp->length;
2453 setposition_tossp (&(adp->caret), caretstart, caretstart);
2454 }
2455 else
2456 caretstart = SeqLocStart(slp);
2457 if (adp->seqEntity_id[adp->caret_line] != adp->seqEntity_id[j]
2458 || adp->item_id[adp->caret_line] != adp->item_id[j])
2459 {
2460 eid = adp->seqEntity_id[j];
2461 iid = adp->item_id[j];
2462 it = adp->itemtype[j];
2463 adp->caret.entityID = eid;
2464 adp->caret.itemID = iid;
2465 adp->caret.itemtype = it;
2466 sip=(SeqIdPtr)SeqIdFromAlignNode(adp->anp_list,eid, iid, it);
2467 replace_region (&(adp->caret), eid, iid, it, caretstart, caretstart, sip, Seq_strand_plus, FALSE);
2468 }
2469 adp->caret_line = j;
2470
2471 SeqPosToLineColumn (iid, eid, it, caretstart, &line, &column,
2472 adp->hoffset, adp);
2473 inval_rect ((Int2) (rp.left+adp->margin.left +(column-2) * adp->charw), (Int2)(rp.top + adp->lineheight * oldline), (Int2)(rp.left+ adp->margin.left + (column+2)*adp->charw), (Int2)(rp.top + adp->lineheight * (oldline+1)));
2474 inval_rect((Int2)(rp.left+adp->margin.left+(column-2) * adp->charw), (Int2)(rp.top + adp->lineheight * line), (Int2)(rp.left + adp->margin.left + (column+2)*adp->charw), (Int2)(rp.top + adp->lineheight * (line+1)));
2475 if ( ! shftKey ) {
2476 slp = (SeqLocPtr) adp->caret.region;
2477 if (!adp->display_panel)
2478 to_update_prompt (pnl, &(adp->caret), (SeqAlignPtr) adp->sap_align->data, adp->sqloc_list, FALSE, adp->printid);
2479 adp->caret_orig = caretstart;
2480 adp->edit_pos = caretstart;
2481 ObjMgrDeSelectAll ();
2482 }
2483 else {
2484 dragcaret_selectrgn(pnl, caretstart, get_closest_selection(&(adp->caret), salp, NULL, adp->sqloc_list), &(adp->caret), adp, line);
2485 adp->edit_pos += adp->visibleWidth;
2486 }
2487 }
2488 break;
2489
2490 case FINDNEXT:
2491 adp->cur_pat = ShowNextPattern(adp->match_pat, adp->cur_pat, adp->edit_pos);
2492 break;
2493
2494 case FINDPREV:
2495 adp->cur_pat = ShowPrecPattern(adp->match_pat, adp->cur_pat, adp->edit_pos);
2496 break;
2497
2498 case NLM_RETURN:
2499 {
2500 WindoW w;
2501 SeqEditViewFormPtr wdp;
2502
2503 w = getwindow_frompanel (pnl);
2504 wdp = (SeqEditViewFormPtr) GetObjectExtra (w);
2505 GoToFunc (wdp);
2506 }
2507 break;
2508
2509 case NLM_ESC:
2510 break;
2511
2512 default:
2513 Beep ();
2514 break;
2515 }
2516 if (!adp->display_panel)
2517 update_edititem (pnl);
2518 Update ();
2519 }
2520
2521
2522 const char *nucleotide_alphabet = "ABCDGHKMRSTUVWYabcdghkmrstuvwy";
2523 const char *protein_alphabet = "ABCDEFGHIKLMPQRSTUVWXYZabcdefghiklmpqrstuvwxyz";
2524
2525 typedef struct alnsettingsdlg {
2526 DIALOG_MESSAGE_BLOCK
2527 TexT missing;
2528 TexT match;
2529 TexT beginning_gap;
2530 TexT middle_gap;
2531 TexT end_gap;
2532
2533 PopuP sequence_type;
2534 } AlnSettingsDlgData, PNTR AlnSettingsDlgPtr;
2535
AlnSettingsDlgToData(DialoG d)2536 static Pointer AlnSettingsDlgToData (DialoG d)
2537 {
2538 AlnSettingsDlgPtr dlg;
2539 TSequenceInfoPtr sequence_info;
2540
2541 dlg = (AlnSettingsDlgPtr) GetObjectExtra (d);
2542 if (dlg == NULL) return NULL;
2543
2544 sequence_info = SequenceInfoNew ();
2545 if (sequence_info == NULL) return NULL;
2546
2547 sequence_info->missing = MemFree (sequence_info->missing);
2548 sequence_info->missing = SaveStringFromText (dlg->missing);
2549
2550 sequence_info->beginning_gap = MemFree (sequence_info->beginning_gap);
2551 sequence_info->beginning_gap = SaveStringFromText (dlg->beginning_gap);
2552
2553 sequence_info->middle_gap = MemFree (sequence_info->middle_gap);
2554 sequence_info->middle_gap = SaveStringFromText (dlg->middle_gap);
2555
2556 sequence_info->end_gap = MemFree (sequence_info->end_gap);
2557 sequence_info->end_gap = SaveStringFromText (dlg->end_gap);
2558
2559 sequence_info->match = MemFree (sequence_info->match);
2560 sequence_info->match = SaveStringFromText (dlg->match);
2561
2562 if (dlg->sequence_type != NULL)
2563 {
2564 if (GetValue (dlg->sequence_type) == 1) {
2565 sequence_info->alphabet = nucleotide_alphabet;
2566 } else {
2567 sequence_info->alphabet = protein_alphabet;
2568 }
2569 }
2570 else
2571 {
2572 sequence_info->alphabet = nucleotide_alphabet;
2573 }
2574
2575 return sequence_info;
2576 }
2577
2578
DataToAlnSettingsDlg(DialoG d,Pointer data)2579 static void DataToAlnSettingsDlg (DialoG d, Pointer data)
2580 {
2581 AlnSettingsDlgPtr dlg;
2582 TSequenceInfoPtr sequence_info;
2583
2584 dlg = (AlnSettingsDlgPtr) GetObjectExtra (d);
2585 if (dlg == NULL) return;
2586
2587 sequence_info = (TSequenceInfoPtr) data;
2588
2589 if (sequence_info == NULL)
2590 {
2591 SetTitle (dlg->missing, "?Nn");
2592 SetTitle (dlg->beginning_gap, "-.Nn?");
2593 SetTitle (dlg->middle_gap, "-.");
2594 SetTitle (dlg->end_gap, "-.Nn?");
2595 SetTitle (dlg->match, ":");
2596 if (dlg->sequence_type != NULL)
2597 {
2598 SetValue (dlg->sequence_type, 1);
2599 }
2600 }
2601 else
2602 {
2603 SetTitle (dlg->missing, sequence_info->missing);
2604 SetTitle (dlg->beginning_gap, sequence_info->beginning_gap);
2605 SetTitle (dlg->middle_gap, sequence_info->middle_gap);
2606 SetTitle (dlg->end_gap, sequence_info->end_gap);
2607 SetTitle (dlg->match, sequence_info->match);
2608
2609 if (dlg->sequence_type != NULL)
2610 {
2611 if (StringCmp (sequence_info->alphabet, protein_alphabet) == 0)
2612 {
2613 SetValue (dlg->sequence_type, 2);
2614 }
2615 else
2616 {
2617 SetValue (dlg->sequence_type, 1);
2618 }
2619 }
2620 }
2621 }
2622
2623
TestAlnSettingsDlg(DialoG d)2624 static ValNodePtr TestAlnSettingsDlg (DialoG d)
2625 {
2626 ValNodePtr err_list = NULL;
2627 TSequenceInfoPtr sequence_info;
2628 CharPtr cp;
2629 CharPtr fmt = "Character %c cannot appear in both %s and %s.";
2630 CharPtr err_str;
2631 CharPtr missing_name = "Ambiguous/Unknown";
2632 CharPtr middle_gap_name = "Middle Gap";
2633 CharPtr match_name = "Match";
2634
2635 sequence_info = DialogToPointer (d);
2636 if (sequence_info == NULL) return NULL;
2637
2638 /* missing and match cannot appear in middle gap list */
2639 cp = sequence_info->missing;
2640 while (cp != NULL && *cp != 0)
2641 {
2642 if (StringChr (sequence_info->middle_gap, *cp))
2643 {
2644 err_str = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt)
2645 + StringLen (missing_name)
2646 + StringLen (middle_gap_name)));
2647 sprintf (err_str, fmt, *cp, missing_name, middle_gap_name);
2648 ValNodeAddPointer (&err_list, 0, err_str);
2649 }
2650 cp++;
2651 }
2652
2653 cp = sequence_info->match;
2654 while (cp != NULL && *cp != 0)
2655 {
2656 if (StringChr (sequence_info->middle_gap, *cp))
2657 {
2658 err_str = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt)
2659 + StringLen (match_name)
2660 + StringLen (middle_gap_name)));
2661 sprintf (err_str, fmt, *cp, match_name, middle_gap_name);
2662 ValNodeAddPointer (&err_list, 0, err_str);
2663 }
2664 cp++;
2665 }
2666
2667 /* missing and match cannot share characters */
2668 cp = sequence_info->missing;
2669 while (cp != NULL && *cp != 0)
2670 {
2671 if (StringChr (sequence_info->match, *cp))
2672 {
2673 err_str = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt)
2674 + StringLen (missing_name)
2675 + StringLen (match_name)));
2676 sprintf (err_str, fmt, *cp, missing_name, match_name);
2677 ValNodeAddPointer (&err_list, 0, err_str);
2678 }
2679 cp++;
2680 }
2681
2682 return err_list;
2683 }
2684
2685
2686 static CharPtr aln_settings_help = "\
2687 Beginning Gap: When some of the sequences in an \
2688 alignment are shorter or longer than others, beginning \
2689 gap characters are added to the beginning of the sequence \
2690 to maintain the correct spacing. These will not appear \
2691 in your sequence file.\n\
2692 Middle Gap: These characters are used to maintain the spacing \
2693 inside an alignment. These are not nucleotides and will \
2694 not appear as part of your sequence file.\n\
2695 End Gap: When some of the sequences in an alignment are shorter \
2696 or longer than others, end gap characters are added to the end \
2697 of the sequence to maintain the correct spacing. These will \
2698 not appear in your sequence file.\n\
2699 Ambiguous/Unknown: These characters are used to represent \
2700 indeterminate/ambiguous nucleotides. These will appear in your \
2701 sequence file as 'n'.\n\
2702 Match: These characters are used to indicate positions where \
2703 sequences are identical to the first sequence. These will be \
2704 replaced by the actual characters from the first sequence.";
2705
2706
AlnSettingsDlg(GrouP h,Boolean allow_sequence_type)2707 NLM_EXTERN DialoG AlnSettingsDlg (GrouP h, Boolean allow_sequence_type)
2708 {
2709 AlnSettingsDlgPtr dlg;
2710 GrouP p, g, p_msg;
2711
2712 dlg = (AlnSettingsDlgPtr) MemNew (sizeof (AlnSettingsDlgData));
2713 p = HiddenGroup (h, -1, 0, NULL);
2714 SetObjectExtra (p, dlg, StdCleanupExtraProc);
2715 SetGroupSpacing (p, 10, 10);
2716
2717 dlg->dialog = (DialoG) p;
2718 dlg->todialog = DataToAlnSettingsDlg;
2719 dlg->fromdialog = AlnSettingsDlgToData;
2720 dlg->testdialog = TestAlnSettingsDlg;
2721
2722 g = HiddenGroup (p, 2, 0, NULL);
2723 StaticPrompt (g, "Ambiguous/Unknown", 0, dialogTextHeight, programFont, 'c');
2724 dlg->missing = DialogText (g, "?Nn", 5, NULL);
2725 StaticPrompt (g, "Match", 0, dialogTextHeight, programFont, 'c');
2726 dlg->match = DialogText (g, ".", 5, NULL);
2727 StaticPrompt (g, "Beginning Gap", 0, dialogTextHeight, programFont, 'c');
2728 dlg->beginning_gap = DialogText (g, "-.?nN", 5, NULL);
2729 StaticPrompt (g, "Middle Gap", 0, dialogTextHeight, programFont, 'c');
2730 dlg->middle_gap = DialogText (g, "-", 5, NULL);
2731 StaticPrompt (g, "End Gap", 0, dialogTextHeight, programFont, 'c');
2732 dlg->end_gap = DialogText (g, "-.?nN", 5, NULL);
2733 if (allow_sequence_type) {
2734 StaticPrompt (g, "Sequence Type", 0, dialogTextHeight, programFont, 'c');
2735 dlg->sequence_type = PopupList (g, TRUE, NULL);
2736 PopupItem (dlg->sequence_type, "Nucleotide");
2737 PopupItem (dlg->sequence_type, "Protein");
2738 SetValue (dlg->sequence_type, 1);
2739 }
2740
2741 p_msg = MultiLinePrompt (p, aln_settings_help, 750, systemFont);
2742
2743 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) p_msg, NULL);
2744
2745 return (DialoG) p;
2746 }
2747
2748
2749 typedef struct alignmentoptionsform
2750 {
2751 Boolean accepted;
2752 Boolean done;
2753 } AlignmentOptionsFormData, PNTR AlignmentOptionsFormPtr;
2754
AcceptAlignmentOptions(ButtoN b)2755 static void AcceptAlignmentOptions (ButtoN b)
2756 {
2757 AlignmentOptionsFormPtr aofp;
2758
2759 aofp = (AlignmentOptionsFormPtr) GetObjectExtra (b);
2760 if (aofp == NULL) return;
2761 aofp->accepted = TRUE;
2762 aofp->done = TRUE;
2763 }
2764
CancelAlignmentOptions(ButtoN b)2765 static void CancelAlignmentOptions (ButtoN b)
2766 {
2767 AlignmentOptionsFormPtr aofp;
2768
2769 aofp = (AlignmentOptionsFormPtr) GetObjectExtra (b);
2770 if (aofp == NULL) return;
2771 aofp->accepted = FALSE;
2772 aofp->done = TRUE;
2773 }
2774
2775
GetAlignmentOptions(Uint1Ptr moltype,TSequenceInfoPtr sequence_info)2776 NLM_EXTERN TSequenceInfoPtr GetAlignmentOptions (Uint1Ptr moltype, TSequenceInfoPtr sequence_info)
2777 {
2778 ButtoN b;
2779 GrouP c, h;
2780 WindoW w;
2781 AlignmentOptionsFormData aofd;
2782 DialoG d;
2783 ValNodePtr err_list;
2784
2785 aofd.accepted = FALSE;
2786 aofd.done = FALSE;
2787 w = ModalWindow (-50, -33, -10, -10, NULL);
2788
2789 h = HiddenGroup (w, -1, 0, NULL);
2790 SetGroupSpacing (h, 10, 10);
2791
2792 d = AlnSettingsDlg (h, moltype == NULL ? FALSE : TRUE);
2793 PointerToDialog (d, sequence_info);
2794
2795 c = HiddenGroup (h, 4, 0, NULL);
2796 b = DefaultButton (c, "Accept", AcceptAlignmentOptions);
2797 SetObjectExtra (b, &aofd, NULL);
2798 b = PushButton (c, "Cancel", CancelAlignmentOptions);
2799 SetObjectExtra (b, &aofd, NULL);
2800
2801 AlignObjects (ALIGN_CENTER, (HANDLE) d, (HANDLE) c, NULL);
2802 RealizeWindow (w);
2803 Show (w);
2804 Update ();
2805
2806 while (!aofd.done) {
2807 while (!aofd.done)
2808 {
2809 ProcessExternalEvent ();
2810 Update ();
2811 }
2812 ProcessAnEvent ();
2813 if (!aofd.accepted)
2814 {
2815 Remove (w);
2816 return NULL;
2817 }
2818
2819 err_list = TestDialog (d);
2820 if (err_list != NULL) {
2821 Message (MSG_ERROR, err_list->data.ptrvalue);
2822 err_list = ValNodeFreeData (err_list);
2823 aofd.done = FALSE;
2824 aofd.accepted = FALSE;
2825 }
2826 }
2827 sequence_info = DialogToPointer (d);
2828 if (sequence_info == NULL) return NULL;
2829 if (StringCmp (sequence_info->alphabet, protein_alphabet) == 0) {
2830 if (moltype != NULL) {
2831 *moltype = Seq_mol_aa;
2832 }
2833 } else {
2834 if (moltype != NULL) {
2835 *moltype = Seq_mol_na;
2836 }
2837 }
2838
2839 Remove (w);
2840 return sequence_info;
2841 }
2842
2843
RemoveSequenceFromAlignmentFile(TAlignmentFilePtr afp,CharPtr str)2844 static void RemoveSequenceFromAlignmentFile (TAlignmentFilePtr afp, CharPtr str)
2845 {
2846 int pos, k;
2847
2848 if (afp == NULL) {
2849 return;
2850 }
2851 for (pos = 0; pos < afp->num_sequences; pos++) {
2852 if (StringCmp (str, afp->ids[pos]) == 0) {
2853 free (afp->ids[pos]);
2854 for (k = pos + 1; k < afp->num_sequences; k++) {
2855 afp->ids[k - 1] = afp->ids[k];
2856 }
2857 free (afp->sequences[pos]);
2858 for (k = pos + 1; k < afp->num_sequences; k++) {
2859 afp->sequences[k - 1] = afp->sequences[k];
2860 }
2861 afp->num_sequences--;
2862 if (pos < afp->num_organisms) {
2863 free (afp->organisms[pos]);
2864 for (k = pos + 1; k < afp->num_organisms; k++) {
2865 afp->organisms[k - 1] = afp->organisms[k];
2866 }
2867 afp->num_organisms--;
2868 }
2869 if (pos < afp->num_deflines) {
2870 free (afp->deflines[pos]);
2871 for (k = pos + 1; k < afp->num_deflines; k++) {
2872 afp->deflines[k - 1] = afp->deflines[k];
2873 }
2874 afp->num_deflines--;
2875 }
2876 }
2877 }
2878 }
2879
2880
FixToFarPointer(TAlignmentFilePtr afp,Int4 index)2881 static void FixToFarPointer (TAlignmentFilePtr afp, Int4 index)
2882 {
2883 CharPtr tmp_id_str;
2884
2885 if (afp == NULL || index < -1 || index >= afp->num_sequences)
2886 {
2887 return;
2888 }
2889 tmp_id_str = (CharPtr) MemNew (sizeof (Char) * (StringLen (afp->ids [index]) + 4));
2890 if (tmp_id_str == NULL)
2891 {
2892 return;
2893 }
2894 sprintf (tmp_id_str, "acc%s", afp->ids [index]);
2895 MemFree (afp->ids [index]);
2896 afp->ids[index] = tmp_id_str;
2897 }
2898
2899
RemoveNthSequenceFromAlignment(TAlignmentFilePtr afp,Int4 n)2900 static void RemoveNthSequenceFromAlignment (TAlignmentFilePtr afp, Int4 n)
2901 {
2902 Int4 i;
2903
2904 if (afp == NULL || n < 0) {
2905 return;
2906 }
2907
2908 if (afp->deflines != NULL && n < afp->num_deflines) {
2909 afp->deflines[n] = MemFree (afp->deflines[n]);
2910 for (i = n + 1; i < afp->num_deflines; i++) {
2911 afp->deflines[i - 1] = afp->deflines[i];
2912 }
2913 afp->deflines[afp->num_deflines - 1] = NULL;
2914 afp->num_deflines--;
2915 }
2916
2917 if (afp->organisms != NULL && n < afp->num_organisms) {
2918 afp->organisms[n] = MemFree (afp->organisms[n]);
2919 for (i = n + 1; i < afp->num_organisms; i++) {
2920 afp->organisms[i - 1] = afp->organisms[i];
2921 }
2922 afp->organisms[afp->num_organisms - 1] = NULL;
2923 afp->num_organisms--;
2924 }
2925
2926 if (afp->sequences != NULL && n < afp->num_sequences) {
2927 afp->sequences[n] = MemFree (afp->sequences[n]);
2928 afp->ids[n] = MemFree (afp->ids[n]);
2929 for (i = n + 1; i < afp->num_sequences; i++) {
2930 afp->sequences[i - 1] = afp->sequences[i];
2931 afp->ids[i - 1] = afp->ids[i];
2932 }
2933 afp->sequences[afp->num_sequences - 1] = NULL;
2934 afp->ids[afp->num_sequences - 1] = NULL;
2935 afp->num_sequences--;
2936 }
2937 }
2938
2939
FixAlignmentIdsOkCancel(ButtoN b)2940 static void FixAlignmentIdsOkCancel (ButtoN b)
2941 {
2942 BoolPtr bp;
2943
2944 bp = (BoolPtr) GetObjectExtra (b);
2945 if (bp != NULL)
2946 {
2947 *bp = TRUE;
2948 }
2949 }
2950
EnableTextID(GrouP g)2951 static void EnableTextID (GrouP g)
2952 {
2953 TexT id_text;
2954
2955 id_text = (TexT) GetObjectExtra (g);
2956 if (id_text != NULL)
2957 {
2958 if (GetValue (g) > 5)
2959 {
2960 Enable (id_text);
2961 }
2962 else
2963 {
2964 Disable (id_text);
2965 }
2966 }
2967 }
2968
2969
ReplaceAlignmentIDsFromFile(TAlignmentFilePtr afp,Int4 index)2970 static Boolean ReplaceAlignmentIDsFromFile (TAlignmentFilePtr afp, Int4 index)
2971 {
2972 ReadBufferData rbd;
2973 Char path [PATH_MAX];
2974 CharPtr line, cp, first_id, second_id;
2975 Int4 k;
2976 Boolean found_id;
2977 ValNodePtr err_list = NULL;
2978 CharPtr err_msg = NULL;
2979 CharPtr err_msg_prefix = "Unable to find ";
2980 CharPtr err_msg_suffix = " from file in alignment";
2981 Int4 err_msg_len = 0;
2982 ValNodePtr vnp;
2983
2984 if (afp == NULL || index < -1 || index >= afp->num_sequences)
2985 {
2986 return FALSE;
2987 }
2988
2989 rbd.fp = NULL;
2990 while (rbd.fp == NULL)
2991 {
2992 if (!GetInputFileName (path, sizeof (path), NULL, NULL))
2993 {
2994 return FALSE;
2995 }
2996 rbd.fp = FileOpen (path, "r");
2997 if (rbd.fp == NULL)
2998 {
2999 Message (MSG_ERROR, "Unable to open %s", path);
3000 }
3001 }
3002
3003 rbd.current_data = NULL;
3004
3005 line = AbstractReadFunction (&rbd);
3006 while (line != NULL)
3007 {
3008 cp = line;
3009 while (isspace ((Int4)(*cp)))
3010 {
3011 cp++;
3012 }
3013 if (*cp != 0)
3014 {
3015 first_id = cp;
3016 while (!isspace ((Int4)(*cp)) && *cp != 0)
3017 {
3018 cp++;
3019 }
3020 while (isspace ((Int4)(*cp)))
3021 {
3022 *cp = 0;
3023 cp++;
3024 }
3025 second_id = cp;
3026 TrimSpacesAroundString (second_id);
3027 if (*second_id != 0)
3028 {
3029 found_id = FALSE;
3030 for (k = index; k < afp->num_sequences && ! found_id; k++)
3031 {
3032 if (StringCmp (afp->ids[k], first_id) == 0)
3033 {
3034 found_id = TRUE;
3035 MemFree (afp->ids[k]);
3036 afp->ids[k] = StringSave (second_id);
3037 }
3038 else if (StringCmp (afp->ids[k], second_id) == 0)
3039 {
3040 found_id = TRUE;
3041 MemFree (afp->ids[k]);
3042 afp->ids[k] = StringSave (first_id);
3043 }
3044 }
3045 if (!found_id)
3046 {
3047 ValNodeAddPointer (&err_list, 0, StringSave (first_id));
3048 ValNodeAddPointer (&err_list, 0, StringSave (second_id));
3049 err_msg_len += StringLen (first_id) + StringLen (second_id) + 8;
3050 }
3051 }
3052 }
3053
3054 line = AbstractReadFunction (&rbd);
3055 }
3056 FileClose (rbd.fp);
3057 if (err_list != NULL)
3058 {
3059 err_msg_len += StringLen (err_msg_prefix) + StringLen (err_msg_suffix) + 6;
3060 err_msg = (CharPtr) MemNew (err_msg_len * sizeof (Char));
3061 if (err_msg != NULL)
3062 {
3063 sprintf (err_msg, "%s", err_msg_prefix);
3064 vnp = err_list;
3065 while (vnp != NULL && vnp->next != NULL)
3066 {
3067 StringCat (err_msg, (CharPtr) vnp->data.ptrvalue);
3068 StringCat (err_msg, " or ");
3069 StringCat (err_msg, (CharPtr) vnp->next->data.ptrvalue);
3070
3071 if (vnp->next->next != NULL)
3072 {
3073 StringCat (err_msg, ", ");
3074 }
3075 if (vnp->next->next != NULL && vnp->next->next->next != NULL && vnp->next->next->next->next == NULL)
3076 {
3077 StringCat (err_msg, " and ");
3078 }
3079 vnp = vnp->next->next;
3080 }
3081 StringCat (err_msg, err_msg_suffix);
3082 Message (MSG_ERROR, err_msg);
3083 MemFree (err_msg);
3084 }
3085 }
3086 return TRUE;
3087 }
3088
3089
FixAlignmentIDs(TAlignmentFilePtr afp,Int4 index,BoolPtr all_far,BoolPtr all_skip,BoolPtr removed)3090 static Boolean FixAlignmentIDs (TAlignmentFilePtr afp, Int4 index, BoolPtr all_far, BoolPtr all_skip, BoolPtr removed)
3091 {
3092 WindoW w;
3093 GrouP h, choice_grp, c;
3094 ButtoN b;
3095 Boolean done = FALSE;
3096 Boolean cancelled = FALSE;
3097 PrompT p;
3098 CharPtr prompt_str;
3099 CharPtr prompt_str_fmt = "Unable to find sequence %s from alignment in set.";
3100 TexT id_text;
3101 CharPtr id_str;
3102 Int2 fix_choice;
3103
3104 if (afp == NULL || index < -1 || index >= afp->num_sequences)
3105 {
3106 return FALSE;
3107 }
3108
3109 id_str = afp->ids[index];
3110 if (StringHasNoText (id_str))
3111 {
3112 return FALSE;
3113 }
3114
3115 w = MovableModalWindow (-20, -13, -10, -10, "Source Assistant", NULL);
3116 h = HiddenGroup(w, -1, 0, NULL);
3117 SetGroupSpacing (h, 10, 10);
3118
3119 prompt_str = (CharPtr) MemNew ((StringLen (prompt_str_fmt) + StringLen (id_str)) * sizeof (Char));
3120 if (prompt_str != NULL)
3121 {
3122 sprintf (prompt_str, prompt_str_fmt, id_str);
3123 }
3124 p = StaticPrompt (h, prompt_str, 0, dialogTextHeight, systemFont, 'c');
3125 choice_grp = HiddenGroup (h, 0, 7, EnableTextID);
3126 RadioButton (choice_grp, "This is a far pointer");
3127 RadioButton (choice_grp, "All unmatched sequences are far pointers");
3128 RadioButton (choice_grp, "Read in a file that maps alignment IDs to sequence IDs");
3129 RadioButton (choice_grp, "Remove this sequence from the alignment");
3130 RadioButton (choice_grp, "Remove all unmatched sequences from the alignment");
3131 RadioButton (choice_grp, "Use this ID for this sequence");
3132 id_text = DialogText (choice_grp, "", 20, NULL);
3133 Disable (id_text);
3134 SetValue (choice_grp, 1);
3135 SetObjectExtra (choice_grp, id_text, NULL);
3136 c = HiddenGroup (h, 2, 0, NULL);
3137 b = PushButton(c, "OK", FixAlignmentIdsOkCancel);
3138 SetObjectExtra (b, &done, NULL);
3139 b = PushButton(c, "Cancel", FixAlignmentIdsOkCancel);
3140 SetObjectExtra (b, &cancelled, NULL);
3141 AlignObjects (ALIGN_CENTER, (HANDLE) p, (HANDLE) choice_grp, (HANDLE) c, NULL);
3142
3143 Show(w);
3144 Select (w);
3145 while (!done && !cancelled)
3146 {
3147 while (!done && !cancelled)
3148 {
3149 ProcessExternalEvent ();
3150 Update ();
3151 }
3152 ProcessAnEvent ();
3153 if (!cancelled)
3154 {
3155 fix_choice = GetValue (choice_grp);
3156 switch (fix_choice)
3157 {
3158 case 1:
3159 /* far pointer */
3160 FixToFarPointer (afp, index);
3161 break;
3162 case 2:
3163 /* all far pointers */
3164 if (all_far != NULL)
3165 {
3166 *all_far = TRUE;
3167 }
3168 FixToFarPointer (afp, index);
3169 break;
3170 case 3:
3171 /* read in file with replacements */
3172 if (!ReplaceAlignmentIDsFromFile (afp, index))
3173 {
3174 done = FALSE;
3175 }
3176 break;
3177 case 4:
3178 /* skip */
3179 RemoveNthSequenceFromAlignment (afp, index);
3180 if (removed != NULL) {
3181 *removed = TRUE;
3182 }
3183 break;
3184 case 5:
3185 /* skip all */
3186 RemoveNthSequenceFromAlignment (afp, index);
3187 if (all_skip != NULL)
3188 {
3189 *all_skip = TRUE;
3190 }
3191 if (removed != NULL) {
3192 *removed = TRUE;
3193 }
3194 break;
3195 case 6:
3196 /* use single replacement */
3197 id_str = SaveStringFromText (id_text);
3198 if (StringHasNoText (id_str))
3199 {
3200 MemFree (id_str);
3201 Message (MSG_ERROR, "You did not specify text for the ID!");
3202 done = FALSE;
3203 }
3204 else
3205 {
3206 MemFree (afp->ids [index]);
3207 afp->ids [index] = id_str;
3208 }
3209 break;
3210 }
3211 }
3212 }
3213 Remove (w);
3214 if (cancelled)
3215 {
3216 return FALSE;
3217 }
3218 else
3219 {
3220 return TRUE;
3221 }
3222 }
3223
3224
CorrectAlignmentIDs(TAlignmentFilePtr afp,Uint1 moltype)3225 NLM_EXTERN Boolean CorrectAlignmentIDs (TAlignmentFilePtr afp, Uint1 moltype)
3226 {
3227 Int4 index;
3228 CharPtr seq_data;
3229 BioseqPtr bsp;
3230 Char prot_str[200];
3231 Boolean all_far = FALSE;
3232 Boolean all_skip = FALSE;
3233 Boolean removed;
3234 SeqEntryPtr nucprot_sep;
3235 BioseqSetPtr nucprot_bssp;
3236
3237 for (index = 0; index < afp->num_sequences; index++) {
3238 seq_data = AlignmentStringToSequenceString (afp->sequences [index], moltype);
3239 if (! StringHasNoText (seq_data))
3240 {
3241 if (StringNCmp (afp->ids[index], "acc", 3) != 0)
3242 {
3243 bsp = BioseqFromAlignmentID (&(afp->ids[index]));
3244
3245 if (bsp != NULL && moltype == Seq_mol_aa && !ISA_aa (bsp->mol))
3246 {
3247 /* IDs in alignment are for nucleotide sequences but this is
3248 * protein sequence - if single prot in nuc-prot set, replace
3249 * with protein sequence ID. Otherwise set to NULL - don't
3250 * want this ID in our alignment */
3251 nucprot_sep = GetBestTopParentForData (bsp->idx.entityID, bsp);
3252 bsp = NULL;
3253 if (nucprot_sep != NULL && IS_Bioseq_set (nucprot_sep) && nucprot_sep->data.ptrvalue != NULL)
3254 {
3255 nucprot_bssp = nucprot_sep->data.ptrvalue;
3256 if (nucprot_bssp->seq_set != NULL
3257 && nucprot_bssp->seq_set->next != NULL
3258 && nucprot_bssp->seq_set->next->next == NULL
3259 && IS_Bioseq (nucprot_bssp->seq_set->next))
3260 {
3261 bsp = (BioseqPtr) nucprot_bssp->seq_set->next->data.ptrvalue;
3262 SeqIdWrite (SeqIdFindBest (bsp->id, 0), prot_str, PRINTID_FASTA_LONG, sizeof (prot_str) - 1);
3263 afp->ids[index] = MemFree (afp->ids[index]);
3264 afp->ids[index] = StringSave (prot_str);
3265 }
3266 }
3267 }
3268
3269 if (bsp == NULL)
3270 {
3271 if (all_far)
3272 {
3273 FixToFarPointer (afp, index);
3274 }
3275 else if (all_skip)
3276 {
3277 RemoveNthSequenceFromAlignment(afp, index);
3278 index--;
3279 }
3280 else
3281 {
3282 removed = FALSE;
3283 if (!FixAlignmentIDs (afp, index, &all_far, &all_skip, &removed))
3284 {
3285 /* bail - user does not want to fix IDs */
3286 return FALSE;
3287 }
3288 if (removed) {
3289 index--;
3290 }
3291 }
3292 }
3293
3294 }
3295 }
3296 MemFree (seq_data);
3297 }
3298 return TRUE;
3299 }
3300
3301
ReadAlignmentForSeqEntry(SeqEntryPtr sep,Boolean is_nuc,Boolean allow_options,Boolean from_clipboard)3302 NLM_EXTERN SeqAlignPtr ReadAlignmentForSeqEntry (SeqEntryPtr sep, Boolean is_nuc, Boolean allow_options, Boolean from_clipboard)
3303 {
3304 Char path [PATH_MAX];
3305 FILE *fp;
3306 SeqAlignPtr salp=NULL,
3307 salpnew, salp_return = NULL;
3308 SeqEntryPtr sepnew=NULL;
3309 Boolean ok = TRUE,
3310 dirty = FALSE;
3311 TSequenceInfoPtr default_info, sequence_info;
3312 ReadBufferData rbd;
3313 TErrorInfoPtr error_list;
3314 TAlignmentFilePtr afp;
3315 Uint1 moltype;
3316 ErrSev sev;
3317 SeqEntryPtr scope;
3318 CharPtr str;
3319
3320 if (sep == NULL) return NULL;
3321
3322 if (from_clipboard) {
3323 if (!Nlm_ClipboardHasString()) {
3324 Message (MSG_ERROR, "Clipboard is empty!");
3325 return NULL;
3326 }
3327 TmpNam (path);
3328 fp = FileOpen (path, "w");
3329 str = ClipboardToString();
3330 fprintf (fp, "%s", str);
3331 FileClose (fp);
3332 str = MemFree (str);
3333 } else if (! GetInputFileName (path, sizeof (path),"","TEXT")) {
3334 return NULL;
3335 }
3336 fp = FileOpen (path, "r");
3337 if (fp == NULL)
3338 {
3339 Message (MSG_ERROR, "Unable to open %s", path);
3340 if (from_clipboard) {
3341 FileRemove (path);
3342 }
3343 return NULL;
3344 }
3345
3346 default_info = SequenceInfoNew ();
3347 if (is_nuc) {
3348 default_info->alphabet = nucleotide_alphabet;
3349 } else {
3350 default_info->alphabet = protein_alphabet;
3351 }
3352 default_info->beginning_gap = MemFree (default_info->beginning_gap);
3353 default_info->beginning_gap = StringSave ("-.Nn?");
3354 default_info->middle_gap = MemFree (default_info->middle_gap);
3355 default_info->middle_gap = StringSave ("-.#");
3356 default_info->end_gap = MemFree (default_info->end_gap);
3357 default_info->end_gap = StringSave ("-.Nn?");
3358 default_info->match = MemFree (default_info->match);
3359 default_info->match = StringSave (":");
3360 default_info->missing = MemFree (default_info->missing);
3361 default_info->missing = StringSave ("?Nn");
3362
3363 if (allow_options) {
3364 sequence_info = GetAlignmentOptions (&moltype, default_info);
3365 SequenceInfoFree (default_info);
3366 if (sequence_info == NULL) return NULL;
3367 default_info = sequence_info;
3368 }
3369
3370 WatchCursor();
3371 error_list = NULL;
3372
3373 rbd.fp = fp;
3374 rbd.current_data = NULL;
3375 afp = ReadAlignmentFile ( AbstractReadFunction,
3376 (Pointer) &rbd,
3377 AbstractReportError,
3378 (Pointer) &error_list,
3379 default_info);
3380 FileClose (fp);
3381 if (from_clipboard) {
3382 FileRemove (path);
3383 }
3384 SequenceInfoFree (default_info);
3385 default_info = NULL;
3386 if (afp != NULL)
3387 {
3388 RemoveSequenceFromAlignmentFile (afp, "Consensus");
3389 SeqEntrySetScope (sep);
3390 if (CorrectAlignmentIDs (afp, moltype))
3391 {
3392 sepnew = MakeSequinDataFromAlignmentEx (afp, moltype, TRUE);
3393 }
3394 }
3395 if (sepnew == NULL) {
3396 ProduceAlignmentNotes (afp, error_list);
3397 }
3398 ErrorInfoFree (error_list);
3399 AlignmentFileFree (afp);
3400 if (sepnew)
3401 {
3402 salpnew = (SeqAlignPtr) FindSeqAlignInSeqEntry (sepnew, OBJ_SEQALIGN);
3403 if (salpnew) {
3404 sev = ErrSetMessageLevel (SEV_FATAL);
3405
3406 scope = SeqEntrySetScope (NULL);
3407 /* adjust the start positions for the sequences read in from the alignments. */
3408 CalculateAlignmentOffsets (sepnew, sep);
3409 /* ValidateSeqAlignandACCInSeqEntry will readjust the start positions for
3410 * the alignments for far pointer sequences.
3411 */
3412 SeqEntrySetScope (scope);
3413 ok = ValidateSeqAlignandACCInSeqEntry (sepnew, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE);
3414
3415 ErrSetMessageLevel (sev);
3416
3417 if (ok) {
3418 AlnMgr2IndexSeqAlignEx(salpnew, FALSE);
3419 ok = CheckAlignmentSequenceLengths (salpnew);
3420 }
3421
3422 if (ok) {
3423 /* make copy, otherwise it will be removed when we delete sep_new */
3424 salp_return = (SeqAlignPtr) AsnIoMemCopy (salpnew, (AsnReadFunc) SeqAlignAsnRead,
3425 (AsnWriteFunc) SeqAlignAsnWrite);
3426 }
3427 }
3428 /* this statement will free salpnew as part of sepnew */
3429 ObjMgrFree (OBJ_SEQENTRY, (Pointer)sepnew);
3430 sepnew=NULL;
3431 }
3432 ArrowCursor();
3433 Update ();
3434 return salp_return;
3435 }
3436
3437
ReportPotentialDupIDs(TAlignmentFilePtr afp,FILE * fp)3438 static void ReportPotentialDupIDs (TAlignmentFilePtr afp, FILE *fp)
3439 {
3440 int seq_index, k;
3441 int curr_seg;
3442 int num_sequences;
3443 Int4Ptr seq_len;
3444 BoolPtr may_be_dup;
3445 Int4 a, b;
3446
3447 if (afp == NULL || afp->sequences == NULL || afp->num_sequences == 0) {
3448 return;
3449 }
3450
3451 num_sequences = afp->num_sequences / afp->num_segments;
3452
3453 may_be_dup = (BoolPtr) MemNew (sizeof (Boolean) * num_sequences);
3454 for (seq_index = 0; seq_index < num_sequences; seq_index++) {
3455 may_be_dup[seq_index] = FALSE;
3456 }
3457
3458 seq_len = (Int4Ptr) MemNew (sizeof (Int4) * afp->num_sequences);
3459 for (seq_index = 0; seq_index < afp->num_sequences; seq_index++) {
3460 seq_len[seq_index] = StringLen (afp->sequences[seq_index]);
3461 }
3462
3463 for (curr_seg = 0; curr_seg < afp->num_segments; curr_seg++) {
3464 for (seq_index = 0; seq_index < num_sequences - 1; seq_index++) {
3465 for (k = seq_index + 1; k < num_sequences; k++) {
3466 a = curr_seg * num_sequences + seq_index;
3467 b = curr_seg * num_sequences + k;
3468 if (seq_len[a] != seq_len[b]) {
3469 if (seq_len[a] % seq_len [b] == 0) {
3470 may_be_dup[seq_index] = TRUE;
3471 } else if (seq_len[b] % seq_len[a] == 0) {
3472 may_be_dup[k] = TRUE;
3473 }
3474 }
3475 }
3476 }
3477 }
3478 seq_len = MemFree (seq_len);
3479
3480 for (seq_index = 0; seq_index < num_sequences; seq_index ++)
3481 {
3482 if (may_be_dup[seq_index]) {
3483 fprintf (fp, "Please check your file - %s may have been used as an ID for multiple sequences.\n", afp->ids[seq_index]);
3484 }
3485 }
3486
3487 may_be_dup = MemFree (may_be_dup);
3488 }
3489
3490
PrintExtraErrorInstructions(FILE * fp,CharPtr message)3491 static void PrintExtraErrorInstructions (FILE *fp, CharPtr message)
3492 {
3493 CharPtr explanation, end;
3494 Char tmp = '\0';
3495 if (fp == NULL || message == NULL) return;
3496
3497 if (StringStr (message, "bad characters") == NULL
3498 && StringStr (message, " found at position ") == NULL) {
3499 return;
3500 }
3501
3502 explanation = StringRChr (message, '(');
3503 if (explanation == NULL) return;
3504 if (StringNCmp (explanation, "(expect only ", 13) == 0) {
3505 end = StringStr (explanation + 13, " here)");
3506 if (end != NULL) {
3507 tmp = *end;
3508 *end = 0;
3509 }
3510 fprintf (fp,
3511 "Try changing the sequence character specifications for %s.\n",
3512 explanation + 13);
3513 if (StringNCmp (explanation + 13, "beginning", 9) == 0) {
3514 fprintf (fp,
3515 "\nWhen some of the sequences in an alignment are shorter or "
3516 "longer than others, beginning gap characters are added to "
3517 "the beginning of the sequence to maintain the correct spacing."
3518 " These will not appear in your sequence file.\n");
3519 } else if (StringNCmp (explanation + 13, "end", 3) == 0) {
3520 fprintf (fp,
3521 "\nWhen some of the sequences in an alignment are shorter or "
3522 "longer than others, end gap characters are added to "
3523 "the end of the sequence to maintain the correct spacing."
3524 " These will not appear in your sequence file.\n");
3525 } else {
3526 fprintf (fp,
3527 "\nMiddle gap characters are used to maintain the spacing "
3528 "inside an alignment. These are not nucleotides and will "
3529 "not appear as part of your sequence file.\n"
3530 "Ambiguous/unknown characters are used to represent indeterminate/ambiguous "
3531 "nucleotides. These will appear in your sequence file as 'n'.\n"
3532 "Match characters are used to indicate positions where "
3533 "sequences are identical to the first sequence. These will be "
3534 "replaced by the actual characters from the first sequence.\n");
3535 }
3536 if (end != NULL) {
3537 *end = tmp;
3538 }
3539 } else if (StringCmp (explanation,
3540 "(can't specify match chars in first sequence).") == 0) {
3541 fprintf (fp, "Try changing the match character specification.\n");
3542 fprintf (fp,
3543 "\nMatch characters are used to indicate positions where "
3544 "sequences are identical to the first sequence. These will be "
3545 "replaced by the actual characters from the first sequence.\n");
3546 }
3547 }
3548
3549
PrintError(FILE * fp,TErrorInfoPtr eip)3550 static void PrintError (FILE *fp, TErrorInfoPtr eip)
3551 {
3552 if (eip == NULL || fp == NULL) return;
3553
3554 fprintf (fp, "*****\nError category %d\n", eip->category);
3555 if (eip->line_num > -1) {
3556 fprintf (fp, "Line number %d\n", eip->line_num);
3557 }
3558 if (eip->id != NULL) {
3559 fprintf (fp, "Sequence ID %s\n", eip->id);
3560 }
3561 if (eip->message != NULL) {
3562 fprintf (fp, "%s\n", eip->message);
3563 PrintExtraErrorInstructions (fp, eip->message);
3564 }
3565 }
3566
CountNucleotides(CharPtr sequence)3567 static Int4 CountNucleotides (CharPtr sequence)
3568 {
3569 Int4 num = 0;
3570 CharPtr cp;
3571
3572 if (sequence == NULL) return 0;
3573 for (cp = sequence; *cp != 0; cp++)
3574 {
3575 if (*cp != '-')
3576 {
3577 num++;
3578 }
3579 }
3580 return num;
3581 }
3582
WalkErrorList(TErrorInfoPtr list,FILE * fp)3583 static void WalkErrorList (TErrorInfoPtr list, FILE *fp)
3584 {
3585 TErrorInfoPtr eip;
3586
3587 if (list == NULL || fp == NULL) return;
3588
3589 for (eip = list; eip != NULL; eip = eip->next) {
3590 PrintError (fp, eip);
3591 }
3592
3593 }
3594
3595
PrintAlignmentSummary(TAlignmentFilePtr afp,FILE * fp)3596 static void PrintAlignmentSummary (TAlignmentFilePtr afp, FILE *fp)
3597 {
3598 Int4 index;
3599
3600 if (fp == NULL) return;
3601
3602 if (afp == NULL) {
3603 fprintf (fp, "Catastrophic failure during reading\n");
3604 } else {
3605 fprintf (fp, "Found %d sequences\n", afp->num_sequences);
3606 fprintf (fp, "Found %d organisms\n", afp->num_organisms);
3607 if (afp->num_sequences == afp->num_segments * afp->num_organisms)
3608 {
3609 for (index = 0; index < afp->num_sequences; index++)
3610 {
3611 fprintf (fp, "\t%s\t%d nucleotides\t", afp->ids [index],
3612 CountNucleotides (afp->sequences[index]));
3613 if (index / afp->num_segments < afp->num_organisms) {
3614 fprintf (fp, "%s\n", afp->organisms [index / afp->num_segments]);
3615 } else {
3616 fprintf (fp, "No organism information\n");
3617 }
3618 }
3619 }
3620 else
3621 {
3622 for (index = 0; index < afp->num_sequences; index++)
3623 {
3624 fprintf (fp, "\t%s\t%d nucleotides\t", afp->ids [index],
3625 CountNucleotides (afp->sequences[index]));
3626 if (index < afp->num_organisms) {
3627 fprintf (fp, "%s\n", afp->organisms [index]);
3628 } else {
3629 fprintf (fp, "No organism information\n");
3630 }
3631 }
3632 while (index < afp->num_organisms) {
3633 fprintf (fp, "Unclaimed organism: %s\n", afp->organisms [index]);
3634 index++;
3635 }
3636 }
3637 }
3638 }
3639
3640
3641 NLM_EXTERN void
ProduceAlignmentNotes(TAlignmentFilePtr afp,TErrorInfoPtr error_list)3642 ProduceAlignmentNotes
3643 (TAlignmentFilePtr afp,
3644 TErrorInfoPtr error_list)
3645 {
3646 Char path [PATH_MAX];
3647 FILE *fp;
3648 Boolean ok_to_import = FALSE;
3649
3650 TmpNam (path);
3651 fp = FileOpen (path, "wb");
3652 if (fp == NULL) return;
3653
3654
3655 if (afp != NULL && DoSequenceLengthsMatch (afp)) {
3656 ok_to_import = TRUE;
3657 }
3658
3659
3660 if (ok_to_import && error_list != NULL) {
3661 fprintf (fp, "Congratulations, you have successfully created a sequin file;\nhowever, I had trouble reading part of your file.\nPlease check your data carefully before submitting to be sure that all of your sequences\nwere included correctly.\nIf your file is incomplete, or contains incorrect sequences, please use the error report below\nto find the problem.\n");
3662 }
3663 ReportPotentialDupIDs (afp, fp);
3664
3665 WalkErrorList (error_list, fp);
3666 PrintAlignmentSummary (afp, fp);
3667
3668 FileClose (fp);
3669 LaunchGeneralTextViewer (path, "Alignment reading summary");
3670 FileRemove (path);
3671 }
3672
3673