~ubuntu-branches/ubuntu/gutsy/ncbi-tools6/gutsy

« back to all changes in this revision

Viewing changes to desktop/seqpanel.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese
  • Date: 2005-09-27 15:38:20 UTC
  • mfrom: (1.1.3 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050927153820-1t1sta0qirjpxaar
Tags: 6.1.20050429-1ubuntu1
GL/GLU Transition

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: seqpanel.c,v 6.110 2004/10/15 18:01:13 bollin Exp $
 
1
/* $Id: seqpanel.c,v 6.144 2005/04/27 20:09:54 bollin Exp $
2
2
* ===========================================================================
3
3
*
4
4
*                            PUBLIC DOMAIN NOTICE
42
42
#include <salfiles.h>
43
43
#include <edutil.h>
44
44
#include <subutil.h>
45
 
#include <blastdef.h>
46
 
#include <blast.h>
47
45
#include <actutils.h>
48
 
 
 
46
#include <algo/blast/api/twoseq_api.h>
 
47
#include <alignval.h>
49
48
 
50
49
enum ESeqNum   { eNumNone=1, eNumSide=2, eNumTop=3 };
51
50
enum EDrawGrid { eDrawGridOn=1, eDrawGridOff=2 };
127
126
  Boolean           current_pattern_translate; /*This indicates whether the most recent search
128
127
                                             * in the Find dialog was a translation search.
129
128
                                             */
 
129
  Int4              current_pattern_translate_frame_choice; /* This indicates the frame
 
130
                                             * for the translated search for the most recent
 
131
                                             * search in the Find dialog.
 
132
                                             */
130
133
  ValNodePtr        match_list;             /* This holds a list of SeqLocs that contain 
131
134
                                             * current_pattern.
132
135
                                             */
146
149
                                             * we have pulled a feature interval onto or off
147
150
                                             * of a new line.
148
151
                                             */
 
152
                                             
 
153
  ValNodePtr        gapvnp;                 /* used for indexing gap features */                                             
149
154
  
150
155
} SeqEdFormData, PNTR SeqEdFormPtr;
151
156
 
246
251
  InvalRect (&r_redraw);
247
252
}
248
253
 
249
 
 
250
254
static Int4 x_Coord(BioseqViewPtr bvp, Int4 pos, Int4 row)  
251
255
{
252
256
  if (bvp->seqAlignMode) {
957
961
}
958
962
 
959
963
 
960
 
extern void 
 
964
static void 
961
965
AlignmentIntervalToString 
962
966
(SeqAlignPtr salp,
963
967
 Int4        row,
967
971
 Boolean     view_whole_entity,
968
972
 Uint1Ptr    seqbuf,
969
973
 Uint1Ptr    alnbuf,
970
 
 Int4 PNTR   alnbuffer_len)
 
974
 Int4 PNTR   alnbuffer_len,
 
975
 Boolean     show_substitutions)
971
976
{
972
977
  Int4       aln_len = AlnMgr2GetAlnLength(salp, FALSE);
973
978
  SeqIdPtr   sip     = AlnMgr2GetNthSeqIdPtr(salp, row);
1010
1015
    seqstart = AlnMgr2MapSeqAlignToBioseq(salp, start, row);
1011
1016
    seqstop  = AlnMgr2MapSeqAlignToBioseq(salp, stop,  row);
1012
1017
  }
1013
 
 
 
1018
  
1014
1019
  if (strand == Seq_strand_minus) {
1015
1020
    i = stop;
1016
1021
    while (seqstart == ALNMGR_GAP && i > 0) { /* count backward if we are in the gap */
1024
1029
      seqstart = AlnMgr2MapSeqAlignToBioseq(salp, i, row);
1025
1030
    }
1026
1031
  }
1027
 
  if (seqstop == -1 || seqstop>=bsp->length) seqstop = bsp->length - 1;  /* -1 means exeed sequence length */
 
1032
  
 
1033
  if (seqstop == -1 || seqstop>=bsp->length)
 
1034
  {
 
1035
    seqstop = bsp->length - 1;  /* -1 means exeed sequence length */
 
1036
  }
1028
1037
  
1029
1038
  if (strand == Seq_strand_minus) {
1030
1039
    i = start;
1040
1049
    }
1041
1050
  }
1042
1051
  
1043
 
  
1044
1052
  if (seqstart == ALNMGR_GAP  &&  seqstop == ALNMGR_GAP) seqstart = seqstop = 0;  /* whole line are gaps */
1045
1053
  if (seqstop  < 0) seqstop  = bsp->length - 1;
1046
1054
  if (seqstart < 0) seqstart = seqstop;
1047
1055
  if (strand == Seq_strand_minus) {
 
1056
    if (seqstop - seqstart > alnbuf_len)
 
1057
    {
 
1058
      seqstart = seqstop - alnbuf_len;
 
1059
    }
 
1060
  } else {
1048
1061
    if (seqstop - seqstart > alnbuf_len) 
1049
 
      seqstart = seqstop - alnbuf_len;
1050
 
  } else {
1051
 
    if (seqstop - seqstart > alnbuf_len) seqstop = seqstart + alnbuf_len;  /* not to exeed the current line */
 
1062
    {
 
1063
      seqstop = seqstart + alnbuf_len;  /* not to exeed the current line */
 
1064
    }
1052
1065
  }
1053
1066
 
1054
 
 
1055
1067
  spp = SeqPortFromAlignmentInterval (seqstart, seqstop, strand, bsp);
1056
1068
  SeqPortRead  (spp, seqbuf, seqstop - seqstart + 1);
1057
1069
  if (seqbuf [stop - start] == 0) {
1088
1100
 
1089
1101
    if (seq_pos >= 0) {
1090
1102
      alnbuf [aln_pos - start] = TO_LOWER (seqbuf[k]);
1091
 
      /* Handle mismatches (insert dots when matched) */
1092
 
      if (row != target_row  &&  ! view_whole_entity  &&  target_row != ROW_UNDEFINED)  {
1093
 
        if(target_pos >= 0  && target_pos < bsp_target->length) { /* no gap in the target sequence */
1094
 
          if (seqbuf[k] == target_buf[i]) {
1095
 
            alnbuf[aln_pos - start] = GAP_CHAR;
 
1103
      if (show_substitutions)
 
1104
      {
 
1105
        /* Handle mismatches (insert dots when matched) */
 
1106
        if (row != target_row  &&  ! view_whole_entity  &&  target_row != ROW_UNDEFINED)  {
 
1107
          if(target_pos >= 0  && target_pos < bsp_target->length) { /* no gap in the target sequence */
 
1108
            if (seqbuf[k] == target_buf[i]) {
 
1109
              alnbuf[aln_pos - start] = GAP_CHAR;
 
1110
            }
1096
1111
          }
1097
 
        }
1098
 
      } /* mismatches */
 
1112
        }   /* mismatches */
 
1113
      }
1099
1114
      k++;
1100
1115
    }
1101
1116
    if (target_pos >= 0) {
1118
1133
  }
1119
1134
}
1120
1135
 
 
1136
 
 
1137
static Boolean isSelected(Int2 itemID, BioseqViewPtr bvp)
 
1138
{
 
1139
    ValNodePtr vnp;
 
1140
 
 
1141
    for (vnp = bvp->Selection; vnp != NULL; vnp = vnp->next) {
 
1142
      if (vnp->data.intvalue == itemID  &&  vnp->choice == 1) return TRUE;
 
1143
    }
 
1144
    return FALSE;
 
1145
}
 
1146
 
 
1147
 
1121
1148
static void DrawAlignment
1122
1149
(Int2 x, Int2 y, Int4 line, Int4 row, Uint1Ptr buf, Uint1Ptr seqbuf,
1123
1150
 Uint1Ptr alnbuf, BioseqViewPtr bvp, Int4 aln_idx)
1132
1159
  SeqIdPtr    best_id;
1133
1160
  SeqAlignPtr tmp_salp;
1134
1161
  Int4        i;
 
1162
  RecT        rct;
 
1163
  Boolean     invert = FALSE;
1135
1164
  
1136
1165
  for (i=0, tmp_salp = bvp->salp; i < aln_idx && tmp_salp != NULL; i++, tmp_salp = tmp_salp->next)
1137
1166
  {     
1141
1170
  bsp = BioseqLockById(sip);
1142
1171
 
1143
1172
  AlignmentIntervalToString (tmp_salp, row, start, stop, bvp->TargetRow,
1144
 
                             bvp->viewWholeEntity, seqbuf, alnbuf, &alnbuf_len);
 
1173
                             bvp->viewWholeEntity, seqbuf, alnbuf, &alnbuf_len,
 
1174
                             bvp->showAlnSubstitutions);
1145
1175
  
1146
1176
  /* finally draw everything */
1147
1177
  best_id = SeqIdFindBestAccession (bsp->id);
1156
1186
  PaintStringEx (alnlabel, x+10, y);                                   /* Draw sequence label */
1157
1187
 
1158
1188
  Black ();
 
1189
  
 
1190
  if (isSelected (bsp->idx.itemID, bvp))
 
1191
  {
 
1192
    InvertColors ();
 
1193
    LoadRect (&rct, x + SEQ_X_OFFSET + bvp->SeqStartPosX, y,
 
1194
              x + SEQ_X_OFFSET + bvp->SeqStartPosX 
 
1195
                + bvp->BlocksAtLine * SEQ_GROUP_SIZE * bvp->CharWidth
 
1196
                + (bvp->BlocksAtLine - 1) * bvp->CharWidth,
 
1197
              y - bvp->LineHeight);
 
1198
    EraseRect (&rct);
 
1199
    invert = TRUE;
 
1200
  }
 
1201
 
1159
1202
  block = 0;
1160
1203
  for (block = 0;  block != bvp->BlocksAtLine;  block++) {
1161
1204
    Int4 len  = SEQ_GROUP_SIZE;
1169
1212
    PaintStringEx ( (CharPtr)buf, x+SEQ_X_OFFSET+bvp->SeqStartPosX+block*SEQ_GROUP_SIZE*bvp->CharWidth+block*bvp->CharWidth, y);
1170
1213
  }
1171
1214
  BioseqUnlock (bsp);
 
1215
  if (invert)
 
1216
  {
 
1217
    InvertColors ();
 
1218
  }
1172
1219
}  /* DrawAlignment*/
1173
1220
 
1174
1221
static Int2 SeqPos2XCoord(Int2 x, Int4 seqXPos, BioseqViewPtr bvp);
1396
1443
}
1397
1444
 
1398
1445
 
1399
 
static Boolean isSelected(Int2 itemID, BioseqViewPtr bvp)
1400
 
{
1401
 
    ValNodePtr vnp;
1402
 
 
1403
 
    for (vnp = bvp->Selection; vnp != NULL; vnp = vnp->next) {
1404
 
      if (vnp->data.intvalue == itemID  &&  vnp->choice == 1) return TRUE;
1405
 
    }
1406
 
    return FALSE;
1407
 
}
1408
 
 
1409
 
 
1410
1446
static void DrawMismatchBox (Int4 x, Int4 y, Int4 lineheight, Int4 charwidth)
1411
1447
{
1412
1448
  PoinT pt1, pt2;
2277
2313
          DrawAlignSideLineNumbers(x, y, splp->bioSeqLine, splp->row, bvp);
2278
2314
          DrawAlignment(x, y, splp->bioSeqLine, splp->row, buf, seqbuf, alnbuf, bvp, aln_idx);                /* Draw the alignment   */
2279
2315
          if (bvp->DrawGrid) DrawLtGrid(x, y+bvp->LineSpace/2, r.right, y+bvp->LineSpace/2);
 
2316
          if (bvp->last_aln_row_clicked == splp->row)
 
2317
          {
 
2318
            DrawSequenceCaret (x, y, splp->bioSeqLine, bvp);
 
2319
          }
2280
2320
          break;
2281
2321
        case eTypeAlignDivider:
2282
2322
          DrawAlignmentDivider (x, y, bvp);
2383
2423
{
2384
2424
  PaneL pnl = AutonomousPanel4 (g, w, h, onDrawSeqPanel, onVScrollBarSeqPanel, NULL, sizeof (BioseqViewPtr), onCloseSeqPanel, NULL);
2385
2425
  SetPanelClick(pnl, onSeqViewClick, NULL, NULL, onSeqViewRelease);
 
2426
  
2386
2427
  return pnl;
2387
2428
}
2388
2429
 
2455
2496
  sefp->last_journal_entry->prev = sefp->undo_list;
2456
2497
}
2457
2498
 
2458
 
static Boolean AddJournalEntry 
 
2499
static Boolean AddJournalEntryEx
2459
2500
(ESeqEdJournalAction action,
2460
2501
 Int4                offset,
2461
2502
 Int4                num_chars,
2462
2503
 CharPtr             char_data,
2463
 
 SeqEdFormPtr        sefp)
 
2504
 SeqEdFormPtr        sefp,
 
2505
 Boolean             is_unknown_gap)
2464
2506
{
2465
2507
  SeqEdJournalPtr sejp, prev, end, next;
2466
2508
  Boolean         rval = FALSE;
2494
2536
  sejp = SeqEdJournalNewSeqEdit (action, offset, num_chars, char_data, 
2495
2537
                                 sefp->spliteditmode, sefp->bfp->bvd.bsp, 
2496
2538
                                 sefp->bfp->bvd.bsp->mol, sefp->input_entityID);
 
2539
  sejp->unknown_gap = is_unknown_gap;
2497
2540
  prev = end->prev;
2498
2541
  prev->next = sejp;
2499
2542
  sejp->prev = prev;
2514
2557
  return rval;
2515
2558
}
2516
2559
 
 
2560
static Boolean AddJournalEntry 
 
2561
(ESeqEdJournalAction action,
 
2562
 Int4                offset,
 
2563
 Int4                num_chars,
 
2564
 CharPtr             char_data,
 
2565
 SeqEdFormPtr        sefp)
 
2566
{
 
2567
  return AddJournalEntryEx (action, offset, num_chars, char_data, sefp, FALSE);
 
2568
}
 
2569
 
2517
2570
/* This function initializes a previously allocated chapter.  The sequenceLineOffset
2518
2571
 * position values are set with new values, and the paragraphs are set to an
2519
2572
 * unindexed state.
3153
3206
  Update ();
3154
3207
}
3155
3208
 
3156
 
static void DrawMarker (Int4 x, Int4 y, Int4 line_height)
3157
 
{
3158
 
  PoinT p1, p2;
3159
 
  
3160
 
  p1.x = x;
3161
 
  p1.y = y;
3162
 
  p2.x = x + line_height;
3163
 
  p2.y = y - line_height;
3164
 
  DrawLine (p1, p2);  
3165
 
}
3166
3209
 
3167
3210
/* This function draws the currently visible paragraph lines. */
3168
3211
static void DrawSeqChapters (BioseqViewPtr bvp)
3602
3645
}
3603
3646
 
3604
3647
 
 
3648
static void PrintTranslatedFrame(CharPtr file_line, Int4 line, Int4 frame, BioseqViewPtr bvp)
 
3649
{
 
3650
  SeqFeatPtr    fake_cds;
 
3651
  ByteStorePtr  bs;
 
3652
  CharPtr       frame_str;
 
3653
  Uint1         strand; 
 
3654
  Int4          seqStart; 
 
3655
  Int4          bsStart, bsFinish, j;
 
3656
  Int4          pPos, frame_len;
 
3657
  Char          tmp[2];
 
3658
  Char          label[50];
 
3659
  Int4          offset;
 
3660
  Int4          line_pos;
 
3661
 
 
3662
  if (file_line == NULL || bvp == NULL) return;
 
3663
  
 
3664
  MemSet (file_line, ' ', bvp->CharsAtLine + SEQ_ED_PRINT_SEQ_OFFSET);
 
3665
  file_line [bvp->CharsAtLine + SEQ_ED_PRINT_SEQ_OFFSET] = 0;
 
3666
  
 
3667
    
 
3668
  seqStart  = line    * bvp->CharsAtLine;
 
3669
  
 
3670
  /* determine start of line */
 
3671
  if (frame < 4)
 
3672
  {
 
3673
    offset = 3 - ((line * bvp->CharsAtLine) % 3) + frame - 1;   
 
3674
        strand = Seq_strand_plus;
 
3675
  }
 
3676
  else
 
3677
  {
 
3678
    offset = 7 - frame + ((bvp->bsp->length - (line * bvp->CharsAtLine)) % 3);
 
3679
        strand = Seq_strand_minus;
 
3680
  }
 
3681
  
 
3682
  if (offset > 2)
 
3683
  {
 
3684
        offset = offset % 3;
 
3685
  }
 
3686
  
 
3687
  if (offset == 2 && line > 0)
 
3688
  {
 
3689
        offset -= 3;
 
3690
  }
 
3691
 
 
3692
  bsStart = seqStart + offset;
 
3693
  bsFinish = (line + 1) * bvp->CharsAtLine + offset;
 
3694
  frame_len = bsFinish - bsStart + 1;
 
3695
  bsFinish -= frame_len % 3;
 
3696
  
 
3697
  if (frame_len % 3 == 2 && bsFinish + 3 < bvp->bsp->length)
 
3698
  {
 
3699
        bsFinish += 3;
 
3700
  }
 
3701
  /* must not extend past end of sequence */
 
3702
  while (bsFinish > bvp->bsp->length - 1)
 
3703
  {
 
3704
        bsFinish -= 3;
 
3705
  }
 
3706
  /* should not extend past end of line */
 
3707
  while (bsFinish > seqStart + bvp->CharsAtLine)
 
3708
  {
 
3709
        bsFinish -= 3;
 
3710
  }
 
3711
  frame_len = bsFinish - bsStart + 1;  
 
3712
  
 
3713
  fake_cds = make_fake_cds(bvp->bsp, bsStart, bsFinish, strand);
 
3714
  
 
3715
  bs = ProteinFromCdRegionEx(fake_cds, TRUE, FALSE);
 
3716
  SeqFeatFree(fake_cds);
 
3717
  if(bs == NULL) return;
 
3718
  frame_str = BSMerge (bs, NULL);
 
3719
  bs = BSFree (bs);
 
3720
  if (frame_str == NULL) return;
 
3721
  frame_len = StringLen (frame_str);
 
3722
  
 
3723
  if (frame < 4)
 
3724
  {
 
3725
    sprintf(label, "frame +%d", frame);
 
3726
  }
 
3727
  else
 
3728
  {
 
3729
        sprintf (label, "frame %d", 3 - frame);
 
3730
  }
 
3731
  StringNCpy ((CharPtr)file_line, label, StringLen (label));
 
3732
 
 
3733
 
 
3734
  tmp[1] = '\0';
 
3735
  if (frame < 4)
 
3736
  {
 
3737
    for (j = offset + 1, pPos = 0;  j < bsFinish && pPos < frame_len;  j+=3, pPos ++) 
 
3738
    {
 
3739
      line_pos = SEQ_ED_PRINT_SEQ_OFFSET + j;
 
3740
      if (frame_str [pPos] != 0 && line_pos < SEQ_ED_PRINT_SEQ_OFFSET + bvp->CharsAtLine)
 
3741
        file_line [line_pos] = frame_str[pPos];
 
3742
    }
 
3743
  }
 
3744
  else
 
3745
  {
 
3746
    for (j = offset + 1, pPos = frame_len - 1;  j < bsFinish && pPos > -1;  j+=3, pPos --) 
 
3747
    {
 
3748
      line_pos = SEQ_ED_PRINT_SEQ_OFFSET + j;
 
3749
      if (frame_str [pPos] != 0 && line_pos < SEQ_ED_PRINT_SEQ_OFFSET + bvp->CharsAtLine)
 
3750
        file_line [line_pos] = frame_str[pPos];
 
3751
    }
 
3752
  }
 
3753
  MemFree (frame_str);
 
3754
}
 
3755
 
 
3756
 
3605
3757
static void PrintFrame (CharPtr file_line, Int4 frame, Int4 seq_pos, Int4 seq_end, Int4 CharsAtLine)
3606
3758
{
3607
3759
  Int4 offset, i;
3704
3856
  Uint1Ptr      file_line;
3705
3857
  Char          label[SEQ_ED_PRINT_SEQ_OFFSET];
3706
3858
  ValNodePtr    curr_para_strings = NULL;
3707
 
  ValNodePtr    prev_para_strings = NULL;
3708
3859
  Int4          line_shift;
3709
3860
  
3710
3861
  if (sefp == NULL) return;
3801
3952
                         splp->protProduct, bvp->bsp, bvp);
3802
3953
            SeqEdPrintTextLineToFile ((CharPtr)file_line, from, to, seq_pos, fp);
3803
3954
            break;
 
3955
          case eTypeFrame1:
 
3956
            PrintTranslatedFrame((CharPtr)file_line, splp->bioSeqLine, 1, bvp);
 
3957
            SeqEdPrintTextLineToFile ((CharPtr)file_line, from, to, seq_pos, fp);
 
3958
            break;
 
3959
          case eTypeFrame2:
 
3960
            PrintTranslatedFrame((CharPtr)file_line, splp->bioSeqLine, 2, bvp);
 
3961
            SeqEdPrintTextLineToFile ((CharPtr)file_line, from, to, seq_pos, fp);
 
3962
            break;
 
3963
          case eTypeFrame3:
 
3964
            PrintTranslatedFrame((CharPtr)file_line, splp->bioSeqLine, 3, bvp);
 
3965
            SeqEdPrintTextLineToFile ((CharPtr)file_line, from, to, seq_pos, fp);
 
3966
            break;
 
3967
          case eTypeFrame4:
 
3968
            PrintTranslatedFrame((CharPtr)file_line, splp->bioSeqLine, 4, bvp);
 
3969
            SeqEdPrintTextLineToFile ((CharPtr)file_line, from, to, seq_pos, fp);
 
3970
            break;
 
3971
          case eTypeFrame5:
 
3972
            PrintTranslatedFrame((CharPtr)file_line, splp->bioSeqLine, 5, bvp);
 
3973
            SeqEdPrintTextLineToFile ((CharPtr)file_line, from, to, seq_pos, fp);
 
3974
            break;
 
3975
          case eTypeFrame6:
 
3976
            PrintTranslatedFrame((CharPtr)file_line, splp->bioSeqLine, 6, bvp);
 
3977
            SeqEdPrintTextLineToFile ((CharPtr)file_line, from, to, seq_pos, fp);
 
3978
            break;
3804
3979
        }
3805
3980
      }
3806
3981
      fprintf (fp, "\n");      
3827
4002
        sefp->edit_pos_start = 0;
3828
4003
        sefp->edit_pos_end = 0;
3829
4004
        sefp->current_pattern = NULL;
 
4005
        sefp->gapvnp = NULL;
3830
4006
  }
3831
4007
  InitJournal (sefp);
3832
4008
  return sefp;
3855
4031
 
3856
4032
static void SeqEdUpdateStatus (SeqEdFormPtr sefp)
3857
4033
{
3858
 
  Char str[255];
 
4034
  Char      str[255];
 
4035
  Int4      seq_pos, seq_end_pos;
 
4036
  SeqIdPtr  sip;
 
4037
  BioseqPtr bsp;
 
4038
  Char      tmp_buf[42];
 
4039
  Int4      aln_pos, aln_end_pos, aln_len;
 
4040
  
3859
4041
  if (sefp == NULL || sefp->position_label == NULL) return;
3860
4042
  
3861
 
  if (sefp->edit_pos_start == sefp->edit_pos_end)
 
4043
  if (sefp->bfp != NULL && sefp->bfp->bvd.salp != NULL && sefp->bfp->bvd.seqAlignMode)
3862
4044
  {
3863
 
        sprintf (str, "Position %d", sefp->edit_pos_start);
 
4045
    if (sefp->bfp->bvd.last_aln_row_clicked > 0)
 
4046
    {
 
4047
      sip = AlnMgr2GetNthSeqIdPtr(sefp->bfp->bvd.salp, sefp->bfp->bvd.last_aln_row_clicked);
 
4048
      bsp = BioseqFind (sip);
 
4049
      if (bsp != NULL) {
 
4050
        sip = SeqIdFindBestAccession (bsp->id);
 
4051
      }
 
4052
      SeqIdWrite (sip, tmp_buf, PRINTID_TEXTID_ACCESSION, sizeof(tmp_buf) - 1);
 
4053
      
 
4054
      aln_pos = sefp->edit_pos_start;
 
4055
      aln_end_pos = sefp->edit_pos_end;
 
4056
      seq_pos = AlnMgr2MapSeqAlignToBioseq (sefp->bfp->bvd.salp, 
 
4057
                                            aln_pos,
 
4058
                                            sefp->bfp->bvd.last_aln_row_clicked);
 
4059
      seq_end_pos = AlnMgr2MapSeqAlignToBioseq (sefp->bfp->bvd.salp, 
 
4060
                                            aln_end_pos,
 
4061
                                            sefp->bfp->bvd.last_aln_row_clicked);
 
4062
      while (aln_pos > -1 && seq_pos < 0)
 
4063
      {
 
4064
        aln_pos--;
 
4065
        seq_pos = AlnMgr2MapSeqAlignToBioseq (sefp->bfp->bvd.salp, 
 
4066
                                              aln_pos,
 
4067
                                              sefp->bfp->bvd.last_aln_row_clicked);
 
4068
      }
 
4069
 
 
4070
      aln_len = AlnMgr2GetAlnLength(sefp->bfp->bvd.salp, FALSE); 
 
4071
      while (aln_end_pos < aln_len && seq_end_pos < 0)
 
4072
      {        
 
4073
        seq_end_pos = AlnMgr2MapSeqAlignToBioseq (sefp->bfp->bvd.salp, 
 
4074
                                                  aln_end_pos,
 
4075
                                                  sefp->bfp->bvd.last_aln_row_clicked);
 
4076
        aln_end_pos ++;                                                  
 
4077
      }
 
4078
      
 
4079
      if (seq_pos < 0 && seq_end_pos >= 0)
 
4080
      {
 
4081
        seq_pos = 0;
 
4082
      }
 
4083
      
 
4084
      if (seq_pos < 0)
 
4085
      {
 
4086
        sprintf (str, "%s", tmp_buf);
 
4087
      }
 
4088
      else if (seq_pos == seq_end_pos)
 
4089
      {
 
4090
        sprintf (str, "%s %d", tmp_buf, seq_pos);
 
4091
      }
 
4092
      else
 
4093
      {
 
4094
        sprintf (str, "%s %d-%d", tmp_buf, seq_pos + 1, seq_end_pos);
 
4095
      }
 
4096
    }
 
4097
    else 
 
4098
    {
 
4099
      str[0] = 0;
 
4100
    }
3864
4101
  }
3865
4102
  else
3866
4103
  {
3867
 
        sprintf (str, "Selected %d - %d", sefp->edit_pos_start + 1, sefp->edit_pos_end);
 
4104
    if (sefp->edit_pos_start == sefp->edit_pos_end)
 
4105
    {
 
4106
          sprintf (str, "Position %d", sefp->edit_pos_start);
 
4107
    }
 
4108
    else
 
4109
    {
 
4110
          sprintf (str, "Selected %d - %d", sefp->edit_pos_start + 1, sefp->edit_pos_end);
 
4111
    }
3868
4112
  }
3869
4113
  SetTitle (sefp->position_label, str); 
3870
4114
}
4019
4263
      rval = 0;
4020
4264
    }
4021
4265
  }
4022
 
  else if (pt.y > rp.bottom)
 
4266
  else if (pt.y >= rp.bottom - sefp->bfp->bvd.LineHeight)
4023
4267
  {
4024
4268
    screen_lines = (rp.bottom - rp.top) / sefp->bfp->bvd.LineHeight;
4025
4269
        if (start < max)
4192
4436
  }     
4193
4437
}
4194
4438
 
 
4439
static Int4 FindBestNonGapPosition (Int4 seq_offset, BioseqPtr bsp, Boolean push_left)
 
4440
{
 
4441
  DeltaSeqPtr dsp;
 
4442
  Int4        cum_offset = 0, seg_len;
 
4443
  SeqLocPtr   slp;
 
4444
  SeqLitPtr   slip;
 
4445
  
 
4446
  if (seq_offset < 0 || bsp == NULL)
 
4447
  {
 
4448
    return 0;
 
4449
  }
 
4450
  else if (seq_offset > bsp->length)
 
4451
  {
 
4452
    return bsp->length;
 
4453
  }
 
4454
  else if (bsp->repr != Seq_repr_delta
 
4455
      || bsp->seq_ext_type != 4)
 
4456
  {
 
4457
    return seq_offset;
 
4458
  }
 
4459
  
 
4460
  dsp = (DeltaSeqPtr) bsp->seq_ext;
 
4461
  while (dsp != NULL)
 
4462
  {
 
4463
    seg_len = 0;
 
4464
                if (dsp->choice == 1) 
 
4465
                {  /* SeqLoc */
 
4466
                  slp = (SeqLocPtr)(dsp->data.ptrvalue);
 
4467
                  seg_len = SeqLocLen (slp);
 
4468
                  if (seq_offset >= cum_offset && seq_offset < cum_offset + seg_len)
 
4469
                  {
 
4470
                    return seq_offset;
 
4471
                  }
 
4472
                  cum_offset += seg_len;
 
4473
                }
 
4474
                else if (dsp->choice == 2)
 
4475
                {
 
4476
                  slip = (SeqLitPtr) (dsp->data.ptrvalue);
 
4477
                  seg_len = slip->length;
 
4478
                  if (seq_offset >= cum_offset && seq_offset < cum_offset + seg_len)
 
4479
                  {
 
4480
                    if (slip->seq_data == NULL && slip->fuzz != NULL && slip->fuzz->choice == 4)
 
4481
                    {
 
4482
                      if (push_left)
 
4483
                      {
 
4484
                        return cum_offset;
 
4485
                      }
 
4486
                      else
 
4487
                      {
 
4488
                        return cum_offset + seg_len;
 
4489
                      }
 
4490
                    }
 
4491
                    else
 
4492
                    {
 
4493
                      return seq_offset;
 
4494
                    }
 
4495
                  }
 
4496
                  cum_offset += seg_len;
 
4497
                }
 
4498
                dsp = dsp->next;
 
4499
  }
 
4500
  return cum_offset;
 
4501
}
 
4502
 
 
4503
static void RemapSeqEdIntervalForGap (SeqEdFormPtr sefp)
 
4504
{
 
4505
  Int4        start_remap, end_remap;
 
4506
  
 
4507
  if (sefp == NULL || sefp->bfp == NULL 
 
4508
      || sefp->bfp->bvd.bsp == NULL
 
4509
      || sefp->bfp->bvd.bsp->repr != Seq_repr_delta
 
4510
      || sefp->bfp->bvd.bsp->seq_ext_type != 4)
 
4511
  {
 
4512
    return;
 
4513
  }
 
4514
  
 
4515
  /* cannot select nucleotides inside a gap of unknown length.
 
4516
   * selection must include all of a gap of unknown length or none
 
4517
   * of a gap of unknown length.
 
4518
   */
 
4519
  
 
4520
  start_remap = FindBestNonGapPosition (sefp->edit_pos_start, 
 
4521
                                        sefp->bfp->bvd.bsp,
 
4522
                                        TRUE);
 
4523
  if (sefp->edit_pos_start == sefp->edit_pos_end)
 
4524
  {
 
4525
    sefp->edit_pos_start = start_remap;
 
4526
    sefp->edit_pos_end = start_remap;
 
4527
    sefp->edit_pos_orig = start_remap;
 
4528
  }
 
4529
  else
 
4530
  {
 
4531
    end_remap = FindBestNonGapPosition (sefp->edit_pos_end,
 
4532
                                        sefp->bfp->bvd.bsp,
 
4533
                                        FALSE);
 
4534
    if (sefp->edit_pos_start == sefp->edit_pos_orig)
 
4535
    {
 
4536
      sefp->edit_pos_orig = start_remap;
 
4537
    }
 
4538
    else
 
4539
    {
 
4540
      sefp->edit_pos_orig = end_remap;
 
4541
    }
 
4542
    sefp->edit_pos_start = start_remap;
 
4543
    sefp->edit_pos_end = end_remap;
 
4544
  }
 
4545
   
 
4546
}
 
4547
 
4195
4548
static void SeqEdOnClick (PaneL pnl, PoinT pt)
4196
4549
{
4197
4550
  WindoW            w;
4238
4591
      sefp->edit_pos_end = sefp->edit_pos_start;
4239
4592
      sefp->edit_pos_orig = sefp->edit_pos_start;
4240
4593
    }
 
4594
    RemapSeqEdIntervalForGap (sefp);
4241
4595
    Select (sefp->bfp->bvd.seqView);
4242
4596
    inval_panel (sefp->bfp->bvd.seqView, -1, -1);
4243
4597
    SeqEdUpdateStatus (sefp);
4245
4599
  } 
4246
4600
  else if (splp->lineType == eTypeFeature) 
4247
4601
  {
 
4602
    /* make sure this is a feature that is "real" (i.e., not a gap, which we can't edit) */
 
4603
    sfp = SeqMgrGetDesiredFeature (0, sefp->bfp->bvd.bsp, splp->idx, 0, NULL, &fcontext);
 
4604
    if (sfp == NULL || sfp->idx.subtype == FEATDEF_gap)
 
4605
    {
 
4606
      return;
 
4607
    }
4248
4608
    if (is_double_click) 
4249
4609
    {
4250
4610
      sefp->feature_to_drag = NULL;
4251
4611
      sefp->feature_orig_loc = SeqLocFree (sefp->feature_orig_loc);
4252
 
      sfp = SeqMgrGetDesiredFeature (0, sefp->bfp->bvd.bsp, splp->idx, 0, NULL, &fcontext);
4253
4612
 
4254
4613
      WatchCursor ();
4255
4614
      Update ();
4666
5025
        }
4667
5026
        if (drag_pos < sefp->edit_pos_orig)
4668
5027
        {
4669
 
          sefp->edit_pos_start = drag_pos;
 
5028
      sefp->edit_pos_start = drag_pos;
4670
5029
          sefp->edit_pos_end = sefp->edit_pos_orig;
4671
5030
        }
4672
5031
        else
4674
5033
          sefp->edit_pos_start = sefp->edit_pos_orig;
4675
5034
          sefp->edit_pos_end = drag_pos;        
4676
5035
        }
 
5036
        RemapSeqEdIntervalForGap (sefp);
4677
5037
        if (direction != 0)
4678
5038
    {
4679
5039
      sb  = GetSlateVScrollBar ((SlatE)sefp->bfp->bvd.seqView);
4763
5123
}
4764
5124
 
4765
5125
 
 
5126
static void SeqAlnToggleItemSelection (BioseqViewPtr bvp, Int2 itemID)
 
5127
{
 
5128
  ValNodePtr vnp;
 
5129
  
 
5130
  for (vnp = bvp->Selection; vnp != NULL; vnp = vnp->next)
 
5131
  {
 
5132
    if (vnp->data.intvalue == itemID)
 
5133
    {
 
5134
      if (vnp->choice == 1)
 
5135
      {
 
5136
        vnp->choice = 0;
 
5137
      }
 
5138
      else
 
5139
      {
 
5140
        vnp->choice = 1;
 
5141
      }
 
5142
      return;    
 
5143
    }
 
5144
  }
 
5145
  ValNodeAddInt (&bvp->Selection, 1, itemID);
 
5146
}
 
5147
 
 
5148
 
 
5149
static void SeqAlnOnClick (PaneL pnl, PoinT pt)
 
5150
{
 
5151
  WindoW            w;
 
5152
  SeqEdFormPtr      sefp;
 
5153
  Int4              direction;
 
5154
  Int4              x, y;
 
5155
  SeqPanLinePtr     splp;
 
5156
  SeqIdPtr          sip;
 
5157
  BioseqPtr         bsp;
 
5158
  Boolean           is_double_click;
 
5159
  Boolean           is_ctrl;
 
5160
  Int4              aln_pos;
 
5161
        
 
5162
  w = ParentWindow(pnl);
 
5163
  if (w == NULL) return;
 
5164
  sefp = (SeqEdFormPtr) GetObjectExtra (w);
 
5165
  if (sefp == NULL) return;
 
5166
  
 
5167
  is_double_click = dblClick;
 
5168
  is_ctrl = ctrlKey;
 
5169
  
 
5170
  direction = SeqEdGetLineForPosition (sefp, pt, &x, &y);
 
5171
  if (y < 0 || y > sefp->bfp->bvd.TotalLines - 1 || direction != 0)
 
5172
  {
 
5173
    return;
 
5174
  }
 
5175
  splp = sefp->bfp->bvd.SeqPanLines [y];
 
5176
  if (splp->lineType == eTypeAlignSequence)
 
5177
  {
 
5178
    sip = AlnMgr2GetNthSeqIdPtr(sefp->bfp->bvd.salp, splp->row);
 
5179
    bsp = BioseqFind (sip);
 
5180
    if (bsp != NULL)
 
5181
    {
 
5182
      if (!is_ctrl)
 
5183
      {
 
5184
        sefp->bfp->bvd.Selection = ValNodeFree (sefp->bfp->bvd.Selection);
 
5185
      }
 
5186
      SeqAlnToggleItemSelection (&(sefp->bfp->bvd), bsp->idx.itemID);
 
5187
      inval_panel (sefp->bfp->bvd.seqView, -1, -1);
 
5188
      
 
5189
      aln_pos = x + splp->bioSeqLine * sefp->bfp->bvd.CharsAtLine;
 
5190
      sefp->edit_pos_start = aln_pos;
 
5191
      sefp->edit_pos_end = sefp->edit_pos_start;
 
5192
      sefp->edit_pos_orig = sefp->edit_pos_start;
 
5193
      sefp->bfp->bvd.last_aln_row_clicked = splp->row;
 
5194
      SeqEdUpdateStatus (sefp);
 
5195
    }
 
5196
  } 
 
5197
  CaptureSlateFocus ((SlatE) sefp->bfp->bvd.seqView);     
 
5198
 
 
5199
}
 
5200
 
 
5201
static void SeqAlnOnDrag (PaneL pnl, PoinT pt)
 
5202
{
 
5203
  WindoW        w;
 
5204
  SeqEdFormPtr  sefp;
 
5205
  Boolean       is_double_click, is_ctrl;
 
5206
  Int4          direction;
 
5207
  SeqPanLinePtr splp;
 
5208
  Int4          x, y, drag_pos, old_scroll_pos;
 
5209
  BaR           sb;
 
5210
  
 
5211
  w = ParentWindow(pnl);
 
5212
  if (w == NULL) return;
 
5213
  sefp = (SeqEdFormPtr) GetObjectExtra (w);
 
5214
  if (sefp == NULL) return;
 
5215
  
 
5216
  is_double_click = dblClick;
 
5217
  is_ctrl = ctrlKey;
 
5218
  
 
5219
  direction = SeqEdGetLineForPosition (sefp, pt, &x, &y);
 
5220
  if (y < 0 || y > sefp->bfp->bvd.TotalLines - 1)
 
5221
  {
 
5222
    return;
 
5223
  }
 
5224
  splp = sefp->bfp->bvd.SeqPanLines [y];
 
5225
  if (splp->lineType == eTypeAlignSequence 
 
5226
      && splp->row == sefp->bfp->bvd.last_aln_row_clicked)
 
5227
  {
 
5228
        drag_pos = x + splp->bioSeqLine * sefp->bfp->bvd.CharsAtLine;
 
5229
        if (drag_pos >= sefp->edit_pos_orig) 
 
5230
        {
 
5231
          drag_pos++;
 
5232
        }
 
5233
        if (drag_pos < 0)
 
5234
        {
 
5235
          drag_pos = 0;
 
5236
        }
 
5237
        if (drag_pos > sefp->bfp->bvd.bsp->length)
 
5238
        {
 
5239
          drag_pos = sefp->bfp->bvd.bsp->length;
 
5240
        }
 
5241
        if (drag_pos < sefp->edit_pos_orig)
 
5242
        {
 
5243
      sefp->edit_pos_start = drag_pos;
 
5244
          sefp->edit_pos_end = sefp->edit_pos_orig;
 
5245
        }
 
5246
        else
 
5247
        {
 
5248
          sefp->edit_pos_start = sefp->edit_pos_orig;
 
5249
          sefp->edit_pos_end = drag_pos;        
 
5250
        }
 
5251
  }
 
5252
  if (direction != 0)
 
5253
  {
 
5254
    sb  = GetSlateVScrollBar ((SlatE)sefp->bfp->bvd.seqView);
 
5255
    old_scroll_pos = GetBarValue (sb);
 
5256
    SetBarValue (sb, old_scroll_pos + direction);
 
5257
  }
 
5258
  Select (sefp->bfp->bvd.seqView);
 
5259
  inval_panel (sefp->bfp->bvd.seqView, -1, -1);
 
5260
  SeqEdUpdateStatus (sefp);
 
5261
}
 
5262
 
 
5263
 
 
5264
static void SetSeqAlnPanelClick (SeqEdFormPtr sefp)
 
5265
{
 
5266
  if (sefp == NULL) return;
 
5267
/*  SetPanelClick(sefp->bfp->bvd.seqView, SeqAlnOnClick, SeqEdOnDrag, NULL, SeqEdOnRelease);*/
 
5268
  SetPanelClick(sefp->bfp->bvd.seqView, SeqAlnOnClick, SeqAlnOnDrag, NULL, NULL);
 
5269
}
 
5270
 
 
5271
 
4766
5272
static void ResizeSeqEdView (SeqEdFormPtr sefp)
4767
5273
{
4768
5274
  RecT r;
4776
5282
  if (sefp == NULL) return;
4777
5283
  
4778
5284
  bvp = &(sefp->bfp->bvd);
 
5285
  if (bvp->seqAlignMode)
 
5286
  {
 
5287
    ResizeSeqView (bvp);
 
5288
    SetSeqAlnPanelClick (sefp);
 
5289
    return;
 
5290
  }
4779
5291
  sb = GetSlateVScrollBar ((SlatE)bvp->seqView);
4780
5292
  scroll_pos = GetBarValue(sb);
4781
5293
  splp = SeqEdGetSeqPanelLineForOffset (scroll_pos, bvp);
4814
5326
  temport = SavePort(w);
4815
5327
  Select (sefp->bfp->bvd.seqView);
4816
5328
  RepositionSeqEdPanel (w);
4817
 
  ResizeSeqEdView (sefp);
 
5329
  if (sefp->bfp->bvd.seqAlignMode)
 
5330
  {
 
5331
    ResizeSeqView (&(sefp->bfp->bvd));
 
5332
    SetSeqAlnPanelClick (sefp);
 
5333
  }
 
5334
  else
 
5335
  {
 
5336
    ResizeSeqEdView (sefp);
 
5337
  }
4818
5338
  Select (sefp->bfp->bvd.seqView);
4819
5339
  inval_panel (sefp->bfp->bvd.seqView, -1, -1);
4820
5340
  RestorePort (temport);
5134
5654
  inval_panel (sefp->bfp->bvd.seqView, -1, -1);  
5135
5655
}
5136
5656
 
 
5657
static void SeqEdDeleteDeltaSeq (SeqEdFormPtr sefp, Boolean save_clip)
 
5658
{
 
5659
  Int4        curr_pos = 0, slip_start, delete_start, delete_len;
 
5660
  ESeqEdJournalAction action;
 
5661
  SeqLocPtr   slp;
 
5662
  SeqLitPtr   slip = NULL;
 
5663
  DeltaSeqPtr dsp, dsp_next;
 
5664
  Boolean     ok_to_continue = TRUE;
 
5665
  Boolean     is_unknown_gap;
 
5666
  CharPtr     clip_string = NULL, tmp_string;
 
5667
  Int4        clip_len = 0;
 
5668
  
 
5669
  if (sefp == NULL
 
5670
      || sefp->bfp->bvd.bsp == NULL || sefp->bfp->bvd.bsp->repr != Seq_repr_delta
 
5671
      || sefp->bfp->bvd.bsp->seq_ext_type != 4 || sefp->bfp->bvd.bsp->seq_ext == NULL
 
5672
      || sefp->edit_pos_start < 0)
 
5673
  {
 
5674
    return;
 
5675
  }
 
5676
  
 
5677
  dsp = (DeltaSeqPtr) sefp->bfp->bvd.bsp->seq_ext;
 
5678
  while (dsp != NULL && curr_pos < sefp->edit_pos_end && ok_to_continue)
 
5679
  {
 
5680
    dsp_next = dsp->next;
 
5681
    if (dsp->data.ptrvalue == NULL) continue;
 
5682
    slip_start = curr_pos;
 
5683
    slip = NULL;
 
5684
                if (dsp->choice == 1) 
 
5685
                {  /* SeqLoc */
 
5686
                  slp = (SeqLocPtr)(dsp->data.ptrvalue);
 
5687
      curr_pos += SeqLocLen (slp);
 
5688
                }
 
5689
                else if (dsp->choice == 2)
 
5690
                {
 
5691
                  slip = (SeqLitPtr) (dsp->data.ptrvalue);
 
5692
                  curr_pos += slip->length;
 
5693
                }
 
5694
                if (slip != NULL && curr_pos > sefp->edit_pos_start)
 
5695
                {
 
5696
                  is_unknown_gap = FALSE;
 
5697
                  if (slip->seq_data == NULL)
 
5698
                  {
 
5699
                    action = eSeqEdDeleteGap;
 
5700
                    if (slip->fuzz != NULL && slip->fuzz->choice == 4)
 
5701
                    {
 
5702
                      is_unknown_gap = TRUE;
 
5703
                    }
 
5704
                  }
 
5705
                  else
 
5706
                  {
 
5707
                    action = eSeqEdDelete;
 
5708
                  }
 
5709
                  if (slip_start < sefp->edit_pos_start)
 
5710
                  {
 
5711
                    delete_start = sefp->edit_pos_start;
 
5712
                  }
 
5713
                  else
 
5714
                  {
 
5715
                    delete_start = slip_start;
 
5716
                  }
 
5717
                  if (sefp->edit_pos_end > slip_start + slip->length)
 
5718
                  {
 
5719
                    delete_len = slip->length - (delete_start - slip_start);
 
5720
                  }
 
5721
                  else
 
5722
                  {
 
5723
                    delete_len = sefp->edit_pos_end - delete_start;
 
5724
                  }
 
5725
                  if (is_unknown_gap && (delete_start > slip_start || delete_len < slip->length))
 
5726
                  {
 
5727
                    /* don't delete part of an unknown gap.  delete if all is selected,
 
5728
                     * otherwise leave it alone */
 
5729
                     if (delete_start > slip_start)
 
5730
                     {
 
5731
                       /* we won't be deleting in the unknown gap, so move the cursor to the end */
 
5732
                       sefp->edit_pos_start = slip_start + slip->length;
 
5733
                     }
 
5734
                  }
 
5735
                  else
 
5736
                  {
 
5737
        ok_to_continue = AddJournalEntryEx (action, delete_start - clip_len,
 
5738
                                            delete_len, NULL,
 
5739
                                            sefp, is_unknown_gap);
 
5740
        clip_len += delete_len;
 
5741
        tmp_string = (CharPtr) MemNew ((clip_len + 1) * sizeof (Char));
 
5742
        if (tmp_string != NULL)
 
5743
        {
 
5744
          if (clip_string != NULL)
 
5745
          {
 
5746
            StringCpy (tmp_string, clip_string);
 
5747
          }
 
5748
          if (action == eSeqEdDeleteGap)
 
5749
          {
 
5750
            MemSet (tmp_string + clip_len - delete_len, 'N', delete_len);
 
5751
          }
 
5752
          else
 
5753
          {
 
5754
            StringNCpy (tmp_string, sefp->last_journal_entry->char_data, delete_len);
 
5755
          }
 
5756
          tmp_string [clip_len] = 0;
 
5757
          
 
5758
          clip_string = MemFree (clip_string);
 
5759
          clip_string = tmp_string;
 
5760
        }
 
5761
                  }
 
5762
                }
 
5763
                dsp = dsp_next;
 
5764
  }
 
5765
  if (clip_string != NULL)
 
5766
  {
 
5767
    if (save_clip)
 
5768
    {
 
5769
      StringToClipboard (clip_string);
 
5770
    }
 
5771
    clip_string = MemFree (clip_string);
 
5772
  }
 
5773
  sefp->edit_pos_end = sefp->edit_pos_start;
 
5774
}
 
5775
 
 
5776
static void SeqEdCutDeltaSeq (SeqEdFormPtr sefp)
 
5777
{
 
5778
  SeqEdDeleteDeltaSeq (sefp, TRUE);
 
5779
}
 
5780
 
 
5781
static void SeqEdDelete (SeqEdFormPtr sefp, Boolean save_clip)
 
5782
{  
 
5783
  if (sefp == NULL || sefp->edit_pos_start == sefp->edit_pos_end) return;
 
5784
  
 
5785
  if (sefp->bfp->bvd.bsp->repr == Seq_repr_delta)
 
5786
  {
 
5787
    /* construct separate journal entries for gaps and non-gaps */
 
5788
    SeqEdDeleteDeltaSeq (sefp, save_clip);
 
5789
  }
 
5790
  else
 
5791
  {
 
5792
    if (AddJournalEntry (eSeqEdDelete, sefp->edit_pos_start,
 
5793
                         sefp->edit_pos_end - sefp->edit_pos_start,
 
5794
                         NULL, sefp))
 
5795
    {
 
5796
      sefp->edit_pos_end = sefp->edit_pos_start;
 
5797
      if (save_clip)
 
5798
      {
 
5799
        StringToClipboard (sefp->last_journal_entry->char_data);
 
5800
      }
 
5801
    }
 
5802
  }
 
5803
}
 
5804
 
 
5805
static void SeqEdCut (SeqEdFormPtr sefp)
 
5806
{
 
5807
  SeqEdDelete (sefp, TRUE);
 
5808
  ResizeSeqEdView (sefp);
 
5809
  Select (sefp->bfp->bvd.seqView);
 
5810
  inval_panel (sefp->bfp->bvd.seqView, -1, -1);
 
5811
  SeqEdUpdateStatus (sefp);
 
5812
}
 
5813
 
 
5814
static void SeqEdCutMenuItem (IteM i)
 
5815
{
 
5816
  SeqEdFormPtr sefp;
 
5817
 
 
5818
  if (i == NULL) return;
 
5819
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
 
5820
 
 
5821
  SeqEdCut (sefp);      
 
5822
}
 
5823
 
5137
5824
static void SeqEdPaste (SeqEdFormPtr sefp)
5138
5825
{
5139
5826
  CharPtr      str;
5147
5834
  if (insert_str == NULL) return;
5148
5835
  if (sefp->edit_pos_start != sefp->edit_pos_end)
5149
5836
  {
5150
 
    AddJournalEntry (eSeqEdDelete, sefp->edit_pos_start,
5151
 
                     sefp->edit_pos_end - sefp->edit_pos_start,
5152
 
                     NULL, sefp);
5153
 
    sefp->edit_pos_end = sefp->edit_pos_start;
 
5837
    SeqEdDelete (sefp, FALSE);
5154
5838
  }
5155
5839
  if (AddJournalEntry (eSeqEdInsert, sefp->edit_pos_start,
5156
5840
                           StringLen (insert_str), insert_str, sefp))
5174
5858
  SeqEdPaste (sefp);    
5175
5859
}
5176
5860
 
5177
 
static void SeqEdCut (SeqEdFormPtr sefp)
5178
 
{  
5179
 
  if (sefp == NULL || sefp->edit_pos_start == sefp->edit_pos_end) return;
5180
 
  
5181
 
  if (AddJournalEntry (eSeqEdDelete, sefp->edit_pos_start,
5182
 
                       sefp->edit_pos_end - sefp->edit_pos_start,
5183
 
                       NULL, sefp))
5184
 
  {
5185
 
    sefp->edit_pos_end = sefp->edit_pos_start;
5186
 
    StringToClipboard (sefp->last_journal_entry->char_data);
 
5861
static void ChooseGapType (GrouP g)
 
5862
{
 
5863
  TexT t;
 
5864
  
 
5865
  t = GetObjectExtra (g);
 
5866
  if (t == NULL)
 
5867
  {
 
5868
    return;
 
5869
  }
 
5870
  if (GetValue (g) == 2)
 
5871
  {
 
5872
    Enable (t);
 
5873
  }
 
5874
  else
 
5875
  {
 
5876
    Disable (t);
 
5877
  }
 
5878
}
 
5879
 
 
5880
static void MakeGapFeats (
 
5881
  BioseqPtr bsp,
 
5882
  Pointer userdata
 
5883
)
 
5884
 
 
5885
{
 
5886
  Char             buf [32];
 
5887
  Int4             currpos = 0;
 
5888
  BioseqPtr        fakebsp = NULL;
 
5889
  IntFuzzPtr       fuzz;
 
5890
  ValNodePtr PNTR  gapvnp;
 
5891
  ImpFeatPtr       ifp;
 
5892
  SeqLitPtr        litp;
 
5893
  SeqAnnotPtr      sap = NULL;
 
5894
  SeqFeatPtr       sfp;
 
5895
  SeqIdPtr         sip;
 
5896
  SeqLocPtr        slp;
 
5897
  ValNodePtr       vnp;
 
5898
 
 
5899
  if (bsp == NULL || bsp->repr != Seq_repr_delta) return;
 
5900
  gapvnp = (ValNodePtr PNTR) userdata;
 
5901
  sip = SeqIdFindBest (bsp->id, 0);
 
5902
  if (sip == NULL) return;
 
5903
 
 
5904
  for (vnp = (ValNodePtr)(bsp->seq_ext); vnp != NULL; vnp = vnp->next) {
 
5905
    if (vnp->choice == 1) {
 
5906
      slp = (SeqLocPtr) vnp->data.ptrvalue;
 
5907
      if (slp == NULL) continue;
 
5908
      currpos += SeqLocLen (slp);
 
5909
    }
 
5910
    if (vnp->choice == 2) {
 
5911
      litp = (SeqLitPtr) vnp->data.ptrvalue;
 
5912
      if (litp == NULL) continue;
 
5913
      if (litp->seq_data == NULL && litp->length > 0) {
 
5914
        if (fakebsp == NULL) {
 
5915
          /* to be freed with MemFree, not BioseqFree */
 
5916
          fakebsp = MemNew (sizeof (Bioseq));
 
5917
          if (fakebsp == NULL) return;
 
5918
          sap = SeqAnnotNew ();
 
5919
          if (sap == NULL) return;
 
5920
          sap->type = 1;
 
5921
          fakebsp->annot = sap;
 
5922
          ValNodeAddPointer (gapvnp, 0, (Pointer) fakebsp);
 
5923
        }
 
5924
        ifp = ImpFeatNew ();
 
5925
        if (ifp == NULL) continue;
 
5926
        ifp->key = StringSave ("gap");
 
5927
        sfp = SeqFeatNew ();
 
5928
        if (sfp == NULL) continue;
 
5929
        sfp->data.choice = SEQFEAT_IMP;
 
5930
        sfp->data.value.ptrvalue = (Pointer) ifp;
 
5931
        sfp->next = (SeqFeatPtr) sap->data;
 
5932
        sap->data = (Pointer) sfp;
 
5933
        fuzz = litp->fuzz;
 
5934
        if (fuzz != NULL && fuzz->choice == 4 && fuzz->a == 0) {
 
5935
          AddQualifierToFeature (sfp, "estimated_length", "unknown");
 
5936
          sfp->location = AddIntervalToLocation (NULL, sip, currpos, currpos + litp->length - 1, FALSE, FALSE);
 
5937
        } else {
 
5938
          sprintf (buf, "%ld", (long) litp->length);
 
5939
          AddQualifierToFeature (sfp, "estimated_length", buf);
 
5940
          sfp->location = AddIntervalToLocation (NULL, sip, currpos, currpos + litp->length - 1, FALSE, FALSE);
 
5941
        }
 
5942
      }
 
5943
      currpos += litp->length;
 
5944
    }
 
5945
  }
 
5946
}
 
5947
 
 
5948
static void FreeSeqEdFormGapFeatList (SeqEdFormPtr sefp)
 
5949
{
 
5950
  BioseqPtr   bsp;
 
5951
  SeqAnnotPtr sap, sapnext;
 
5952
 
 
5953
  if (sefp == NULL || sefp->gapvnp == NULL)
 
5954
  {
 
5955
    return;
 
5956
  }
 
5957
  
 
5958
  bsp = (BioseqPtr) sefp->gapvnp->data.ptrvalue;
 
5959
  if (bsp != NULL) {
 
5960
    sap = bsp->annot;
 
5961
    while (sap != NULL) {
 
5962
      sapnext = sap->next;
 
5963
      SeqAnnotFree (sap);
 
5964
      sap = sapnext;
 
5965
    }
 
5966
  }
 
5967
  /* frees fake Bioseq that was created by MemNew, not BioseqNew */
 
5968
  sefp->gapvnp = ValNodeFreeData (sefp->gapvnp);
 
5969
}
 
5970
 
 
5971
static void SeqEdReindexGaps (SeqEdFormPtr sefp, BioseqPtr edit_bsp)
 
5972
{
 
5973
  FreeSeqEdFormGapFeatList (sefp);
 
5974
  
 
5975
  MakeGapFeats (edit_bsp, &(sefp->gapvnp));
 
5976
  SeqMgrClearFeatureIndexes (sefp->input_entityID, NULL);
 
5977
  SeqMgrIndexFeaturesExEx (sefp->input_entityID, NULL, FALSE, FALSE, sefp->gapvnp);
 
5978
}
 
5979
 
 
5980
static void SeqEdInsertGapMenuItem (IteM i)
 
5981
{
 
5982
  SeqEdFormPtr          sefp;
 
5983
  ModalAcceptCancelData acd;
 
5984
  WindoW                w;
 
5985
  GrouP                 h, g, k, gap_type_grp, c;
 
5986
  TexT                  gap_len_txt;
 
5987
  ButtoN                b;
 
5988
  Boolean               done;
 
5989
  CharPtr               gap_len_str;
 
5990
  Int4                  gap_type, gap_len;
 
5991
  Boolean               is_unknown_gap;
 
5992
  Boolean               changed = FALSE;
 
5993
 
 
5994
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
 
5995
  if (sefp == NULL || sefp->edit_pos_start < 0)
 
5996
  {
 
5997
    return;
 
5998
  }
 
5999
  
 
6000
  w = MovableModalWindow(-20, -13, -10, -10, "Insert Gap", NULL);
 
6001
  h = HiddenGroup (w, -1, 0, NULL);
 
6002
  
 
6003
  g = HiddenGroup (h, 2, 0, NULL);
 
6004
  gap_type_grp = HiddenGroup (g, 0, 2, ChooseGapType);
 
6005
  RadioButton (gap_type_grp, "Unknown length");
 
6006
  RadioButton (gap_type_grp, "Known length:");
 
6007
  k = HiddenGroup (g, 0, 2, NULL);
 
6008
  StaticPrompt (k, "", 0, popupMenuHeight, programFont, 'l');
 
6009
  gap_len_txt = DialogText (k, "100", 5, NULL);
 
6010
  
 
6011
  SetObjectExtra (gap_type_grp, gap_len_txt, NULL);
 
6012
  SetValue (gap_type_grp, 1);
 
6013
  ChooseGapType (gap_type_grp);
 
6014
  
 
6015
  c = HiddenGroup (h, 2, 0, NULL);
 
6016
  b = PushButton (c, "Accept", ModalAcceptButton);
 
6017
  SetObjectExtra (b, &acd, NULL);
 
6018
  b = PushButton (c, "Cancel", ModalCancelButton);
 
6019
  SetObjectExtra (b, &acd, NULL);
 
6020
  AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
 
6021
  Show (w);
 
6022
  Select (w);
 
6023
  
 
6024
  done = FALSE;
 
6025
  while (!done)
 
6026
  {
 
6027
    acd.accepted = FALSE;
 
6028
    acd.cancelled = FALSE;
 
6029
    while (!acd.accepted && ! acd.cancelled)
 
6030
    {
 
6031
      ProcessExternalEvent ();
 
6032
      Update ();
 
6033
    }
 
6034
    ProcessAnEvent ();
 
6035
    if (acd.cancelled)
 
6036
    {
 
6037
      done = TRUE;
 
6038
    }
 
6039
    else
 
6040
    {
 
6041
      gap_type = GetValue (gap_type_grp);
 
6042
      if (gap_type == 2)
 
6043
      {
 
6044
        is_unknown_gap = FALSE;
 
6045
      }
 
6046
      else
 
6047
      {
 
6048
        is_unknown_gap = TRUE;
 
6049
      }
 
6050
      gap_len = 100;
 
6051
      if (! is_unknown_gap)
 
6052
      {
 
6053
        gap_len = 0;
 
6054
        gap_len_str = SaveStringFromText (gap_len_txt);
 
6055
        if (!StringHasNoText (gap_len_str))
 
6056
        {
 
6057
          gap_len = atoi (gap_len_str);
 
6058
        }
 
6059
        gap_len_str = MemFree (gap_len_str);
 
6060
      }
 
6061
      if (gap_len < 1)
 
6062
      {
 
6063
        Message (MSG_ERROR, "Gap length must be greater than zero!");
 
6064
      }
 
6065
      else
 
6066
      {
 
6067
        RemapSeqEdIntervalForGap (sefp);
 
6068
        SeqEdDelete (sefp, FALSE);
 
6069
        AddJournalEntryEx (eSeqEdInsertGap, sefp->edit_pos_start,
 
6070
                                            gap_len, NULL,
 
6071
                                            sefp, is_unknown_gap);
 
6072
        SeqEdReindexGaps (sefp, sefp->bfp->bvd.bsp);
 
6073
        changed = TRUE;
 
6074
 
 
6075
        done = TRUE;
 
6076
      }
 
6077
    }
 
6078
  }
 
6079
  Remove (w);
 
6080
  if (changed)
 
6081
  {
5187
6082
    ResizeSeqEdView (sefp);
5188
6083
    Select (sefp->bfp->bvd.seqView);
5189
6084
    inval_panel (sefp->bfp->bvd.seqView, -1, -1);
5190
 
    SeqEdUpdateStatus (sefp);
5191
 
  } 
5192
 
}
5193
 
 
5194
 
static void SeqEdCutMenuItem (IteM i)
5195
 
{
5196
 
  SeqEdFormPtr sefp;
5197
 
 
5198
 
  if (i == NULL) return;
5199
 
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
5200
 
 
5201
 
  SeqEdCut (sefp);      
 
6085
  }
5202
6086
}
5203
6087
 
5204
6088
static void SeqEdCopy (SeqEdFormPtr sefp)
5294
6178
    {
5295
6179
      if (sefp->edit_pos_start != sefp->edit_pos_end)
5296
6180
      {
5297
 
        AddJournalEntry (eSeqEdDelete, sefp->edit_pos_start,
5298
 
                         sefp->edit_pos_end - sefp->edit_pos_start,
5299
 
                         NULL, sefp);
5300
 
        sefp->edit_pos_end = sefp->edit_pos_start;
 
6181
        SeqEdDelete (sefp, FALSE);
5301
6182
      }
5302
6183
      if (AddJournalEntry (eSeqEdInsert, sefp->edit_pos_start,
5303
6184
                           StringLen (str), str, sefp))
5319
6200
          new_pos--;
5320
6201
          break;
5321
6202
        case NLM_RIGHT:
5322
 
          new_pos++;
5323
 
          break;
5324
 
        case NLM_UP:
5325
 
          new_pos -= sefp->bfp->bvd.CharsAtLine;
5326
 
          break;
5327
 
        case NLM_DOWN:
5328
 
          new_pos += sefp->bfp->bvd.CharsAtLine;
5329
 
          if (new_pos > sefp->bfp->bvd.bsp->length
5330
 
              && new_pos - sefp->bfp->bvd.bsp->length < sefp->bfp->bvd.CharsAtLine)
5331
 
          {
 
6203
            new_pos++;
 
6204
            break;
 
6205
          case NLM_UP:
 
6206
            new_pos -= sefp->bfp->bvd.CharsAtLine;
 
6207
            break;
 
6208
          case NLM_DOWN:
 
6209
            new_pos += sefp->bfp->bvd.CharsAtLine;
 
6210
            if (new_pos > sefp->bfp->bvd.bsp->length
 
6211
                && new_pos - sefp->bfp->bvd.bsp->length < sefp->bfp->bvd.CharsAtLine)
 
6212
            {
5332
6213
            new_pos = sefp->bfp->bvd.bsp->length;
5333
6214
          }
5334
 
          break;
 
6215
            break;
5335
6216
        case NLM_DEL:
5336
6217
          /* handle deletion */
5337
6218
          if (sefp->edit_pos_end == sefp->edit_pos_start)
5343
6224
              return;
5344
6225
            }
5345
6226
          }
5346
 
          if (AddJournalEntry (eSeqEdDelete, sefp->edit_pos_start,
5347
 
                               sefp->edit_pos_end - sefp->edit_pos_start,
5348
 
                               NULL, sefp))
5349
 
          {
5350
 
            sefp->edit_pos_end = sefp->edit_pos_start;
5351
 
            ResizeSeqEdView (sefp);
5352
 
            Select (sefp->bfp->bvd.seqView);
5353
 
            inval_panel (pnl, -1, -1);
5354
 
          }
 
6227
          RemapSeqEdIntervalForGap (sefp);
 
6228
          SeqEdDelete (sefp, FALSE);
 
6229
          ResizeSeqEdView (sefp);
 
6230
          Select (sefp->bfp->bvd.seqView);
 
6231
                inval_panel (pnl, -1, -1);
5355
6232
          break;
5356
6233
        case '\b':
5357
 
          /* handle backspace */
5358
 
          if (sefp->edit_pos_start == sefp->edit_pos_end)
5359
 
          {
5360
 
            if (sefp->edit_pos_start == 0)
 
6234
            /* handle backspace */
 
6235
            if (sefp->edit_pos_start == sefp->edit_pos_end)
5361
6236
            {
5362
 
              del_start = -1;
5363
 
            }
 
6237
              if (sefp->edit_pos_start == 0)
 
6238
              {
 
6239
                del_start = -1;
 
6240
            }
 
6241
              else
 
6242
              {
 
6243
              del_start = sefp->edit_pos_start - 1;
 
6244
              del_stop = sefp->edit_pos_start;
 
6245
                }
 
6246
          }
5364
6247
            else
5365
6248
            {
5366
 
              del_start = sefp->edit_pos_start - 1;
5367
 
              del_stop = sefp->edit_pos_start;
5368
 
            }
5369
 
          }
5370
 
          else
5371
 
          {
5372
6249
            del_start = sefp->edit_pos_start;
5373
 
            del_stop = sefp->edit_pos_end;
5374
 
          }
 
6250
            del_stop = sefp->edit_pos_end;
 
6251
              }
5375
6252
                  
5376
 
         if (del_start >= 0)
5377
 
         {
5378
 
           if (AddJournalEntry (eSeqEdDelete, del_start, del_stop - del_start, NULL, sefp))
5379
 
           {
5380
 
             sefp->edit_pos_start = del_start;
5381
 
             sefp->edit_pos_end = del_start;
5382
 
             new_pos = del_start;
5383
 
             ResizeSeqEdView (sefp);
5384
 
             Select (sefp->bfp->bvd.seqView);
5385
 
             inval_panel (pnl, -1, -1);
5386
 
           }
5387
 
         }
5388
 
         break;
5389
 
       }
5390
 
       if (new_pos < 0 || new_pos > sefp->bfp->bvd.bsp->length)
5391
 
       {
5392
 
         Beep ();
5393
 
       }
5394
 
       else
5395
 
       {
5396
 
         sefp->edit_pos_start = new_pos;
5397
 
         sefp->edit_pos_end = new_pos;
5398
 
         sb = GetSlateVScrollBar (s);
5399
 
         if (sb != NULL)
5400
 
         {
5401
 
           scroll_pos = SeqEdGetScrollPosForSequencePos (sefp->edit_pos_start, &(sefp->bfp->bvd));
5402
 
           SetBarValue (sb, scroll_pos);
5403
 
         }
5404
 
         Select (sefp->bfp->bvd.seqView);
5405
 
         inval_panel (pnl, -1, -1);
5406
 
       }
5407
 
     }
5408
 
     SeqEdUpdateStatus (sefp);
 
6253
          if (del_start >= 0)
 
6254
          {
 
6255
            sefp->edit_pos_start = del_start;
 
6256
            sefp->edit_pos_end = del_stop;
 
6257
            RemapSeqEdIntervalForGap (sefp);
 
6258
            new_pos = sefp->edit_pos_start;
 
6259
            SeqEdDelete (sefp, FALSE);
 
6260
            ResizeSeqEdView (sefp);
 
6261
            Select (sefp->bfp->bvd.seqView);
 
6262
            inval_panel (pnl, -1, -1);
 
6263
              }
 
6264
              break;
 
6265
      }
 
6266
      if (new_pos < 0 || new_pos > sefp->bfp->bvd.bsp->length)
 
6267
      {
 
6268
        Beep ();
 
6269
      }
 
6270
      else
 
6271
      {
 
6272
        sefp->edit_pos_start = new_pos;
 
6273
            sefp->edit_pos_end = new_pos;
 
6274
        sb = GetSlateVScrollBar (s);
 
6275
        if (sb != NULL)
 
6276
            {
 
6277
              scroll_pos = SeqEdGetScrollPosForSequencePos (sefp->edit_pos_start, &(sefp->bfp->bvd));
 
6278
          SetBarValue (sb, scroll_pos);
 
6279
            }
 
6280
        Select (sefp->bfp->bvd.seqView);
 
6281
            inval_panel (pnl, -1, -1);
 
6282
      }
 
6283
    }
 
6284
    SeqEdUpdateStatus (sefp);
5409
6285
  }
5410
6286
}
5411
6287
 
5437
6313
  if (sefp != NULL)
5438
6314
  {
5439
6315
    ObjMgrFreeUserData (sefp->input_entityID, sefp->procid, sefp->proctype, sefp->userkey);
 
6316
    FreeSeqEdFormGapFeatList (sefp);
5440
6317
  }
5441
6318
 
5442
6319
  StdCleanupFormProc (g, data);
5517
6394
 
5518
6395
  if (UnplayJournal (&sefp->last_journal_entry, 1))
5519
6396
  {
 
6397
    RemapSeqEdIntervalForGap (sefp);
5520
6398
    SetUndoRedoStatus (sefp);
5521
6399
    ResizeSeqEdView (sefp);
5522
6400
    Select (sefp->bfp->bvd.seqView);
5533
6411
 
5534
6412
  if (PlayJournal (sefp->last_journal_entry->next, &sefp->last_journal_entry, 1, NULL))
5535
6413
  {
 
6414
    RemapSeqEdIntervalForGap (sefp);
5536
6415
    SetUndoRedoStatus (sefp);
5537
6416
    ResizeSeqEdView (sefp);
5538
6417
    Select (sefp->bfp->bvd.seqView);
5729
6608
      *dp = *sp;
5730
6609
      dp++;
5731
6610
    }
5732
 
    else if (isalpha (*sp))
 
6611
    else if (isalpha ((Int4)(*sp)))
5733
6612
    {
5734
6613
      *dp = TO_UPPER (*sp);
5735
6614
      dp++;
5745
6624
  return strp;
5746
6625
}
5747
6626
 
 
6627
typedef struct finddlgdata
 
6628
{
 
6629
  FORM_MESSAGE_BLOCK
 
6630
  WindoW      w; 
 
6631
  TexT        pattern_txt;
 
6632
  GrouP       search_choice_grp;
 
6633
  ButtoN      reverse_complement_btn;
 
6634
  PopuP       frame_choice_popup;
 
6635
  PrompT      prompt;
 
6636
 
 
6637
} FindDlgData, PNTR FindDlgPtr;
 
6638
 
 
6639
static void LIBCALLBACK MatchProc (Int4 position, CharPtr name, CharPtr pattern,
 
6640
                       Int2 cutSite, Uint1 strand, Pointer userdata)
 
6641
 
 
6642
{
 
6643
  ValNodePtr PNTR loc_list;
 
6644
  
 
6645
  loc_list = (ValNodePtr PNTR) userdata;
 
6646
  if (loc_list == NULL) return;
 
6647
  
 
6648
  ValNodeAddInt (loc_list, 0, position);
 
6649
}
 
6650
 
 
6651
static void ConvertIntListToLocList (ValNodePtr loc_list, BioseqPtr bsp, Int4 pattern_len)
 
6652
{
 
6653
  ValNodePtr vnp;
 
6654
  Int4       start;
 
6655
  Int4       stop;
 
6656
  SeqLocPtr  slp;
 
6657
  
 
6658
  if (loc_list == NULL || bsp == NULL || pattern_len == 0)
 
6659
  {
 
6660
    return;
 
6661
  }
 
6662
  
 
6663
  for (vnp = loc_list; vnp != NULL; vnp = vnp->next)
 
6664
  {
 
6665
    start = vnp->data.intvalue;
 
6666
    stop = start + pattern_len - 1;
 
6667
    slp = SeqLocIntNew(start, stop, Seq_strand_plus, SeqIdDup(bsp->id));
 
6668
    vnp->data.ptrvalue = slp;
 
6669
  }
 
6670
}
 
6671
 
 
6672
 
 
6673
static ValNodePtr FindSeqMatch (BioseqPtr bsp, CharPtr pattern)
 
6674
 
 
6675
{
 
6676
  SeqSearchPtr  tbl;
 
6677
  ValNodePtr    pattern_loc_list = NULL;
 
6678
  SeqPortPtr    spp;
 
6679
  Uchar         buf[2];
 
6680
  Int2          ctr;
 
6681
 
 
6682
  if (bsp == NULL || StringHasNoText (pattern))
 
6683
  {
 
6684
    return NULL;
 
6685
  }
 
6686
  
 
6687
  tbl = SeqSearchNew (MatchProc, &pattern_loc_list);
 
6688
  if (tbl == NULL) return NULL;
 
6689
 
 
6690
  SeqSearchAddNucleotidePattern (tbl, "Find", pattern, 1, SEQ_SEARCH_JUST_TOP_STRAND); 
 
6691
 
 
6692
  spp = SeqPortNew (bsp, 0, bsp->length-1, Seq_strand_plus, Seq_code_iupacna);
 
6693
  SeqPortSeek (spp, 0, SEEK_SET);
 
6694
  ctr = SeqPortRead (spp, buf, 1);
 
6695
  while (ctr > 0)
 
6696
  {
 
6697
    SeqSearchProcessCharacter (tbl, buf[0]);
 
6698
    ctr = SeqPortRead (spp, buf, 1);
 
6699
  }
 
6700
 
 
6701
  SeqSearchFree (tbl);
 
6702
  ConvertIntListToLocList (pattern_loc_list, bsp, StringLen (pattern));
 
6703
  return pattern_loc_list;
 
6704
}
 
6705
 
 
6706
static ValNodePtr MergeIntLists (ValNodePtr list1, ValNodePtr list2)
 
6707
{
 
6708
  ValNodePtr vnp1, vnp2, new_list = NULL;
 
6709
  
 
6710
  vnp1 = list1;
 
6711
  vnp2 = list2;
 
6712
  
 
6713
  while (vnp1 != NULL || vnp2 != NULL)
 
6714
  {
 
6715
    if (vnp1 == NULL)
 
6716
    {
 
6717
      ValNodeAddInt (&new_list, 0, vnp2->data.intvalue);
 
6718
      vnp2 = vnp2->next;
 
6719
    }
 
6720
    else if (vnp2 == NULL)
 
6721
    {
 
6722
      ValNodeAddInt (&new_list, 0, vnp1->data.intvalue);
 
6723
      vnp1 = vnp1->next;
 
6724
    }
 
6725
    else if (vnp1->data.intvalue < vnp2->data.intvalue)
 
6726
    {
 
6727
      ValNodeAddInt (&new_list, 0, vnp1->data.intvalue);
 
6728
      vnp1 = vnp1->next;
 
6729
    }
 
6730
    else if (vnp2->data.intvalue < vnp1->data.intvalue)
 
6731
    {
 
6732
      ValNodeAddInt (&new_list, 0, vnp2->data.intvalue);
 
6733
      vnp2 = vnp2->next;
 
6734
    }
 
6735
    else
 
6736
    {
 
6737
      /* values are equal, take only one */
 
6738
      ValNodeAddInt (&new_list, 0, vnp1->data.intvalue);
 
6739
      vnp1 = vnp1->next;
 
6740
      vnp2 = vnp2->next;
 
6741
    }
 
6742
  }
 
6743
  return new_list;
 
6744
}
 
6745
 
 
6746
static ValNodePtr FindTranslationMatchOneFrame 
 
6747
(BioseqPtr       bsp,
 
6748
 CharPtr         pattern,
 
6749
 Int4            frame)
 
6750
{
 
6751
  SeqFeatPtr    fake_cds;
 
6752
  Uint1         strand;
 
6753
  Int4          start;
 
6754
  Int4          stop;
 
6755
  ByteStorePtr  bs;
 
6756
  CharPtr       frame_str;
 
6757
  CharPtr       cp;
 
6758
  ValNodePtr    pattern_loc_list = NULL, vnp;
 
6759
  Int4          prot_pos;
 
6760
  TextFsaPtr    tfp;
 
6761
  Int2          state;
 
6762
  ValNodePtr    matches;
 
6763
  Uchar         ch;
 
6764
  Int4          pattern_len;
 
6765
  CharPtr       scratch_pattern;
 
6766
  
 
6767
  if (bsp == NULL || StringHasNoText (pattern))
 
6768
  {
 
6769
    return NULL;
 
6770
  }
 
6771
  
 
6772
  switch (frame)
 
6773
  {
 
6774
    case 1:
 
6775
      start = 0;
 
6776
      stop = bsp->length - 1;
 
6777
      strand = Seq_strand_plus;
 
6778
      break;
 
6779
    case 2:
 
6780
      start = 1;
 
6781
      stop = bsp->length - 1;
 
6782
      strand = Seq_strand_plus;
 
6783
      break;
 
6784
    case 3:
 
6785
      start = 2;
 
6786
      stop = bsp->length - 1;
 
6787
      strand = Seq_strand_plus;
 
6788
      break;
 
6789
    case 4:
 
6790
      start = 0;
 
6791
      stop = bsp->length - 1;
 
6792
      strand = Seq_strand_minus;
 
6793
      break;
 
6794
    case 5:
 
6795
      start = 0;
 
6796
      stop = bsp->length - 2;
 
6797
      strand = Seq_strand_minus;
 
6798
      break;
 
6799
    case 6:
 
6800
      start = 0;
 
6801
      stop = bsp->length - 3;
 
6802
      strand = Seq_strand_minus;
 
6803
      break;
 
6804
    default:
 
6805
      return NULL;
 
6806
      break;
 
6807
  } 
 
6808
  
 
6809
  fake_cds = make_fake_cds(bsp, start, stop, strand);
 
6810
  
 
6811
  bs = ProteinFromCdRegionEx(fake_cds, TRUE, FALSE);
 
6812
  SeqFeatFree(fake_cds);
 
6813
  if(bs == NULL) return NULL;
 
6814
  frame_str = BSMerge (bs, NULL);
 
6815
  bs = BSFree (bs);
 
6816
  if (frame_str == NULL) return NULL;
 
6817
  scratch_pattern = StringSave (pattern);
 
6818
  if (strand == Seq_strand_minus)
 
6819
  {
 
6820
    reverse_string (scratch_pattern);
 
6821
  }
 
6822
  
 
6823
  tfp = TextFsaNew ();
 
6824
  TextFsaAdd (tfp, scratch_pattern);
 
6825
  
 
6826
  state = 0;
 
6827
  cp = frame_str;
 
6828
  ch = *cp;
 
6829
  if (strand == Seq_strand_minus)
 
6830
  {
 
6831
    prot_pos = stop + 1;
 
6832
  }
 
6833
  else
 
6834
  {
 
6835
    prot_pos = start;
 
6836
  }
 
6837
  pattern_len = StringLen (scratch_pattern);
 
6838
  while (ch != '\0') {
 
6839
    matches = NULL;
 
6840
    state = TextFsaNext (tfp, state, ch, &matches);
 
6841
    if (matches != NULL) 
 
6842
    {
 
6843
      if (strand == Seq_strand_minus)
 
6844
      {
 
6845
        /* need to add locations in reverse order */
 
6846
        vnp = ValNodeNew(NULL);
 
6847
        if (vnp != NULL)
 
6848
        {
 
6849
          vnp->next = pattern_loc_list;
 
6850
          vnp->data.intvalue = prot_pos - 3;
 
6851
          pattern_loc_list = vnp;
 
6852
        }
 
6853
      }
 
6854
      else
 
6855
      {
 
6856
        ValNodeAddInt (&pattern_loc_list, 0, prot_pos + 3 - (3 * pattern_len));    
 
6857
      }
 
6858
    }
 
6859
    cp++;
 
6860
    ch = *cp;
 
6861
    if (strand == Seq_strand_minus)
 
6862
    {
 
6863
      prot_pos -= 3;
 
6864
    }
 
6865
    else
 
6866
    {
 
6867
      prot_pos += 3;
 
6868
    }
 
6869
  }
 
6870
 
 
6871
  MemFree (frame_str);
 
6872
  MemFree (scratch_pattern);
 
6873
  
 
6874
  return pattern_loc_list;
 
6875
}
 
6876
 
 
6877
static ValNodePtr FindTranslation (BioseqPtr bsp, CharPtr pattern, Int4 pick_frame)
 
6878
{
 
6879
  Int4       i;
 
6880
  ValNodePtr loc_list = NULL;
 
6881
  ValNodePtr new_list, comb_list;
 
6882
  if (bsp == NULL || StringHasNoText (pattern))
 
6883
  {
 
6884
    return NULL;
 
6885
  }
 
6886
  
 
6887
  if (pick_frame < 1 || pick_frame > 6)
 
6888
  {
 
6889
    for (i = 1; i <= 6; i++)
 
6890
    {
 
6891
      new_list = FindTranslationMatchOneFrame (bsp, pattern, i);
 
6892
      comb_list = MergeIntLists (loc_list, new_list);
 
6893
      ValNodeFree (new_list);
 
6894
      ValNodeFree (loc_list);
 
6895
      loc_list = comb_list;
 
6896
    }
 
6897
  }
 
6898
  else
 
6899
  {
 
6900
    loc_list = FindTranslationMatchOneFrame (bsp, pattern, pick_frame);
 
6901
  }
 
6902
  ConvertIntListToLocList (loc_list, bsp, StringLen (pattern));
 
6903
  return loc_list;  
 
6904
}
 
6905
 
 
6906
static void CleanPattern (CharPtr pattern, Int4 search_choice)
 
6907
{
 
6908
  CharPtr cp;
 
6909
  
 
6910
  if (pattern == NULL) return;
 
6911
  for (cp = pattern; *cp != 0; cp++)
 
6912
  {
 
6913
    if (search_choice == 3)
 
6914
    {
 
6915
      *cp = toupper (*cp);
 
6916
    }
 
6917
    else
 
6918
    {
 
6919
      *cp = tolower (*cp);
 
6920
    }
 
6921
  }
 
6922
}
 
6923
 
5748
6924
static void FindPatternButton (ButtoN b)
5749
6925
{
5750
6926
  SeqEdFormPtr       sefp;
5751
 
  DialogBoxDataPtr   dbdp;
 
6927
  FindDlgPtr         fdp;
5752
6928
  WindoW             wdialog;
5753
 
  ValNodePtr         seqloc_list = NULL;
5754
 
  SeqIdPtr           sip;
5755
 
  SeqLocPtr          slp;
5756
6929
  CharPtr            strp;
5757
6930
  Int4               count;
5758
6931
  Char               str[255];
 
6932
  Uint1              pick_frame;
 
6933
  Int4               search_choice = 0;
5759
6934
  
5760
6935
  if (b == NULL) return;
5761
6936
  sefp = (SeqEdFormPtr) GetObjectExtra (b);
5762
6937
  if (sefp == NULL) return;
5763
6938
  wdialog = ParentWindow (b);
5764
 
  dbdp = (DialogBoxDataPtr) GetObjectExtra (wdialog);
5765
 
  strp = GetPatternFromDialogText (dbdp->txt1);
 
6939
  fdp = (FindDlgPtr) GetObjectExtra (wdialog);
 
6940
  strp = GetPatternFromDialogText (fdp->pattern_txt);
 
6941
 
 
6942
  if (fdp->search_choice_grp != NULL)
 
6943
  {
 
6944
    search_choice = GetValue (fdp->search_choice_grp);
 
6945
  }
 
6946
  
 
6947
  CleanPattern (strp, search_choice);
 
6948
  if (GetStatus (fdp->reverse_complement_btn) && search_choice != 3)
 
6949
  {
 
6950
    complement_string (strp);
 
6951
    reverse_string (strp);
 
6952
  }
 
6953
  
5766
6954
  if (strp == NULL) {
5767
 
     SetTitle (dbdp->prompt, "No item found");
 
6955
     SetTitle (fdp->prompt, "No item found");
5768
6956
     return;
5769
6957
  }
 
6958
  
5770
6959
  if (sefp->current_pattern != NULL) {
5771
 
     if ((StringStr(sefp->current_pattern, strp)) 
 
6960
    if ((StringStr(sefp->current_pattern, strp)) 
5772
6961
         && (StringLen(sefp->current_pattern) == StringLen (strp))
5773
 
         && (dbdp->bt2 == NULL || sefp->current_pattern_translate == GetStatus (dbdp->bt2))
5774
 
         && (dbdp->bt == NULL || sefp->current_pattern_revcomp == GetStatus (dbdp->bt)))
5775
 
     {
5776
 
        MemFree (strp);
5777
 
        ShowNextSeqEdPattern (sefp);
5778
 
        return;
5779
 
     }
5780
 
     else {
5781
 
        MemFree (sefp->current_pattern);
5782
 
     }
 
6962
         && (fdp->search_choice_grp == NULL
 
6963
             || (search_choice == 1 && !sefp->current_pattern_translate
 
6964
              && sefp->current_pattern_revcomp == GetStatus (fdp->reverse_complement_btn))
 
6965
             || (search_choice == 3 && sefp->current_pattern_translate
 
6966
              && sefp->current_pattern_translate_frame_choice == GetValue (fdp->frame_choice_popup))))
 
6967
    {
 
6968
      MemFree (strp);
 
6969
      ShowNextSeqEdPattern (sefp);
 
6970
      return;
 
6971
    }
 
6972
    else 
 
6973
    {
 
6974
      MemFree (sefp->current_pattern);
 
6975
    }
5783
6976
  }
5784
6977
  sefp->current_pattern = strp;
5785
6978
  if (sefp->match_list != NULL)
5786
6979
     sefp->match_list = MatchListFree (sefp->match_list);
5787
 
  if (dbdp->bt!=NULL)
5788
 
     sefp->current_pattern_revcomp = (Boolean) GetStatus (dbdp->bt);
5789
 
  if (dbdp->bt2!=NULL)
5790
 
     sefp->current_pattern_translate = (Boolean) GetStatus (dbdp->bt2);
 
6980
  if (search_choice == 1)
 
6981
  {
 
6982
    sefp->current_pattern_revcomp = (Boolean) GetStatus (fdp->reverse_complement_btn);
 
6983
    sefp->current_pattern_translate = FALSE;
 
6984
  }
 
6985
  else if (search_choice == 3)
 
6986
  {
 
6987
    sefp->current_pattern_translate = TRUE;
 
6988
    sefp->current_pattern_translate_frame_choice = GetValue (fdp->frame_choice_popup);
 
6989
  }
5791
6990
  
5792
 
  /* construct "list" of seqlocs to search for pattern */
5793
 
  sip = SeqIdFindBest(sefp->bfp->bvd.bsp->id, 0);
5794
 
  if (sip == NULL) return; 
5795
 
  slp = SeqLocIntNew (0, sefp->bfp->bvd.bsp->length - 1, Seq_strand_plus, sip);
5796
 
  ValNodeAddPointer (&(seqloc_list), 0, slp);
5797
 
 
5798
 
  if (sefp->current_pattern_translate && !sefp->current_pattern_revcomp) 
 
6991
  if (sefp->current_pattern_translate) 
5799
6992
  {
5800
 
     sefp->match_list = JK_NTPattern2 (strp, seqloc_list, sefp->current_pattern_revcomp,
5801
 
                                       ObjMgrGetEntityIDForPointer (sefp->bfp->bvd.bsp));
 
6993
    pick_frame = sefp->current_pattern_translate_frame_choice;
 
6994
    if (pick_frame > 0)
 
6995
    {
 
6996
      pick_frame --;
 
6997
    }
 
6998
    sefp->match_list = FindTranslation (sefp->bfp->bvd.bsp, strp, pick_frame);
5802
6999
  }
5803
7000
  else 
5804
7001
  {
5805
 
    sefp->match_list = JK_NTPattern (strp, seqloc_list, sefp->current_pattern_revcomp, sefp->bfp->bvd.bsp->mol);
 
7002
    sefp->match_list = FindSeqMatch (sefp->bfp->bvd.bsp, strp);
5806
7003
  }
5807
7004
  if (sefp->match_list != NULL) {
5808
7005
    count = ValNodeLen (sefp->match_list);
5809
7006
    if (count ==0)
5810
 
      SetTitle (dbdp->prompt, "No item found");
 
7007
      SetTitle (fdp->prompt, "No item found");
5811
7008
    else if (count ==1) {
5812
 
      SetTitle (dbdp->prompt, "1 item found");
 
7009
      SetTitle (fdp->prompt, "1 item found");
5813
7010
    } else {
5814
7011
      sprintf (str, "%d items found   -   next=CTRL->, previous=CTRL<- ", (int) count);
5815
 
      SetTitle (dbdp->prompt, str);
 
7012
      SetTitle (fdp->prompt, str);
5816
7013
    }
5817
7014
    ShowNextSeqEdPattern (sefp);
5818
7015
  }
5819
7016
  else {
5820
 
     SetTitle (dbdp->prompt, "No item found");
 
7017
     SetTitle (fdp->prompt, "No item found");
5821
7018
  }
5822
7019
  Update ();
5823
7020
  return;  
5824
7021
        
5825
7022
}
5826
7023
 
 
7024
static void ChangeSearchChoice (GrouP g)
 
7025
{
 
7026
  WindoW     wdialog;
 
7027
  FindDlgPtr fdp;
 
7028
  Int4       val;
 
7029
  
 
7030
  wdialog = ParentWindow (g);
 
7031
  fdp = (FindDlgPtr) GetObjectExtra (wdialog);
 
7032
  if (fdp == NULL) return;
 
7033
  val = GetValue (g);
 
7034
  if (val == 1)
 
7035
  {
 
7036
    Enable (fdp->reverse_complement_btn);
 
7037
    Disable (fdp->frame_choice_popup);
 
7038
  }
 
7039
  else
 
7040
  {
 
7041
    Disable (fdp->reverse_complement_btn);
 
7042
    Enable (fdp->frame_choice_popup);
 
7043
  }
 
7044
}
 
7045
 
5827
7046
static void SeqEdFindPatternDialog (IteM i)
5828
7047
{
5829
7048
  WindoW             w, wdialog;
5830
 
  DialogBoxDataPtr   dbdp;
 
7049
  FindDlgPtr         fdp;
5831
7050
  SeqEdFormPtr       sefp;
5832
 
  GrouP              g1, g2, g3;
 
7051
  GrouP              h, g1, g2;
5833
7052
  ButtoN             b;
 
7053
  PrompT             p1;
5834
7054
 
5835
7055
  if (i == NULL) return;
5836
7056
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
5839
7059
  w = ParentWindow (i);
5840
7060
  
5841
7061
  wdialog=FixedWindow (-50, -33, -10, -10, "Find", StdCloseWindowProc);
5842
 
  dbdp = (DialogBoxDataPtr) MemNew (sizeof (DialogBoxData));
5843
 
  SetObjectExtra (wdialog, (Pointer) dbdp, StdCleanupExtraProc);
5844
 
  dbdp->w = w;
5845
 
  dbdp->bt = NULL;
5846
 
  dbdp->bt2 = NULL;
5847
 
 
5848
 
  g1 = HiddenGroup (wdialog, 1, 0, NULL);
5849
 
  StaticPrompt (g1, "Find pattern:", 0, popupMenuHeight, programFont, 'l');
5850
 
 
5851
 
  g1 = HiddenGroup (wdialog, 1, 0, NULL);
5852
 
  dbdp->txt1 = ScrollText (g1, 25, 8, programFont, TRUE, NULL);
5853
 
  g3 = HiddenGroup (wdialog, 1, 0, NULL);
5854
 
  dbdp->prompt = StaticPrompt (g3, "", (Int2)(25*stdCharWidth), stdLineHeight, programFont, 'l'); 
 
7062
  fdp = (FindDlgPtr) MemNew (sizeof (FindDlgData));
 
7063
  SetObjectExtra (wdialog, (Pointer) fdp, StdCleanupExtraProc);
 
7064
  fdp->w = w;
 
7065
  fdp->search_choice_grp = NULL;
 
7066
  
 
7067
  h = HiddenGroup (wdialog, -1, 0, NULL);
 
7068
 
 
7069
  p1 = StaticPrompt (h, "Find pattern:", 0, popupMenuHeight, programFont, 'l');
 
7070
 
 
7071
  fdp->pattern_txt = ScrollText (h, 25, 8, programFont, TRUE, NULL);
 
7072
  fdp->prompt = StaticPrompt (h, "", (Int2)(25*stdCharWidth), stdLineHeight, programFont, 'l'); 
5855
7073
  if (ISA_na(sefp->bfp->bvd.bsp->mol))
5856
7074
  {
5857
 
     g2 = HiddenGroup (wdialog, 4, 0, NULL);
5858
 
     dbdp->bt = CheckBox (g2, "reverse complement", NULL);  
5859
 
     SetStatus (dbdp->bt, FALSE);
5860
 
     dbdp->bt2 = CheckBox (g2, "translate sequence", NULL);
5861
 
     SetStatus (dbdp->bt2, FALSE); 
5862
 
     b = PushButton (g2, "Find Next", FindPatternButton);
5863
 
     SetObjectExtra (b, sefp, NULL); 
5864
 
     PushButton (g2, "Dismiss", StdCancelButtonProc);
 
7075
    fdp->search_choice_grp = NormalGroup (h, 2, 0, "Search in", systemFont, ChangeSearchChoice);
 
7076
    RadioButton (fdp->search_choice_grp, "Nucleotide sequence");
 
7077
    fdp->reverse_complement_btn = CheckBox (fdp->search_choice_grp, "reverse complement", NULL);
 
7078
    SetStatus (fdp->reverse_complement_btn, FALSE);
 
7079
    RadioButton (fdp->search_choice_grp, "Translated frame");
 
7080
    fdp->frame_choice_popup = PopupList (fdp->search_choice_grp, TRUE, NULL);
 
7081
    PopupItem (fdp->frame_choice_popup, "Any");
 
7082
    PopupItem (fdp->frame_choice_popup, "+1");
 
7083
    PopupItem (fdp->frame_choice_popup, "+2");
 
7084
    PopupItem (fdp->frame_choice_popup, "+3");
 
7085
    PopupItem (fdp->frame_choice_popup, "-1");
 
7086
    PopupItem (fdp->frame_choice_popup, "-2");
 
7087
    PopupItem (fdp->frame_choice_popup, "-3");
 
7088
    SetValue (fdp->frame_choice_popup, 1);
 
7089
    Disable (fdp->frame_choice_popup);
 
7090
    SetValue (fdp->search_choice_grp, 1);
 
7091
    
 
7092
    g1 = fdp->search_choice_grp;
 
7093
    g2 = HiddenGroup (h, 2, 0, NULL);
 
7094
    b = PushButton (g2, "Find Next", FindPatternButton);
 
7095
    SetObjectExtra (b, sefp, NULL); 
 
7096
    PushButton (g2, "Dismiss", StdCancelButtonProc);
5865
7097
  }
5866
7098
  else {
5867
 
     g2 = HiddenGroup (wdialog, 2, 0, NULL);
5868
 
     b = PushButton (g2, "Find Next", FindPatternButton); 
5869
 
     SetObjectExtra (b, sefp, NULL); 
5870
 
     PushButton (g2, "Close", StdCancelButtonProc);
 
7099
    g1 = HiddenGroup (h, 2, 0, NULL);
 
7100
    b = PushButton (g1, "Find Next", FindPatternButton); 
 
7101
    SetObjectExtra (b, sefp, NULL); 
 
7102
    PushButton (g1, "Close", StdCancelButtonProc);
5871
7103
  }
 
7104
  
 
7105
  AlignObjects (ALIGN_CENTER, (HANDLE) p1, (HANDLE) fdp->pattern_txt, (HANDLE)fdp->prompt,
 
7106
                (HANDLE) fdp->search_choice_grp, (HANDLE) g2, NULL);
5872
7107
  RealizeWindow (wdialog);
5873
7108
  Show (wdialog);
5874
7109
  return;
6110
7345
  SetObjectExtra (localItem, sefp, NULL);
6111
7346
  localItem = CommandItem (edit_menu, "Translate CDS", SeqEdTranslateCDSItem);
6112
7347
  SetObjectExtra (localItem, sefp, NULL);
 
7348
  if (sefp->bfp != NULL 
 
7349
      && sefp->bfp->bvd.bsp != NULL
 
7350
      && sefp->bfp->bvd.bsp->repr == Seq_repr_delta
 
7351
      && sefp->bfp->bvd.bsp->seq_ext_type == 4)
 
7352
  {
 
7353
    localItem = CommandItem (edit_menu, "Insert Gap", SeqEdInsertGapMenuItem);
 
7354
    SetObjectExtra (localItem, sefp, NULL);
 
7355
  }
 
7356
  
6113
7357
 
6114
7358
  /* View menu */
6115
7359
  edit_menu = PulldownMenu (w, "View");
6229
7473
  PopuP              pop;
6230
7474
  Char               str [16];
6231
7475
  Int2               window_width = 650;
6232
 
  Int2               wid, 
6233
 
                     window_hgt = 300,
6234
 
                     hgt,
 
7476
  Int2               window_hgt = 300,
6235
7477
                     charwidth,
6236
7478
                     lineheight;
6237
7479
  FonT               font;
6241
7483
  Uint1              seqtype;
6242
7484
  ButtoN             b;
6243
7485
  
6244
 
  if (bsp==NULL || bsp->repr != Seq_repr_raw)
 
7486
  if (bsp==NULL || (bsp->repr != Seq_repr_raw && bsp->repr != Seq_repr_delta))
6245
7487
  {
6246
7488
    return NULL;
6247
7489
  }
6261
7503
  {
6262
7504
    seqtype = Seq_code_ncbieaa;
6263
7505
  }
6264
 
 
6265
 
  if (bsp->seq_data_type != seqtype)
 
7506
  if (bsp->seq_data_type != seqtype && bsp->repr != Seq_repr_delta)
6266
7507
  {
6267
7508
    BioseqRawConvert(bsp, seqtype);
6268
7509
  }
6284
7525
  SetObjectExtra (w, (Pointer) sefp, CleanupSeqEdForm);
6285
7526
  sefp->form = (ForM) w;
6286
7527
  sefp->formmessage = SeqEdFormMessage;
6287
 
  wid = (Int2)(window_width/charwidth);
6288
 
  hgt = (Int2)(window_hgt / lineheight);
6289
7528
 
6290
7529
  sefp->input_entityID = ObjMgrGetEntityIDForPointer (bsp);
6291
7530
 
6394
7633
  return (ForM) w;
6395
7634
}
6396
7635
 
 
7636
static Int4 GetScrollPosForAlnPos (Int4 aln_pos, BioseqViewPtr bvp)
 
7637
{
 
7638
  Int4 aln_line = 0, display_line, mult;
 
7639
  
 
7640
  if (bvp == NULL || aln_pos < 0)
 
7641
  {
 
7642
    return 0;
 
7643
  }
 
7644
  
 
7645
  aln_line = aln_pos / bvp->CharsAtLine;
 
7646
  if (aln_line >= bvp->TotalLines)
 
7647
  {
 
7648
    return bvp->TotalLines - 1;
 
7649
  }
 
7650
  
 
7651
  if (bvp->SeqPanLines[aln_line]->bioSeqLine > 0)
 
7652
  {
 
7653
    mult = aln_line / bvp->SeqPanLines[aln_line]->bioSeqLine;
 
7654
    if (mult > 1)
 
7655
    {
 
7656
      display_line = aln_line * mult;
 
7657
    }
 
7658
    else
 
7659
    {
 
7660
      display_line = aln_line;
 
7661
    }
 
7662
  }
 
7663
  else
 
7664
  {
 
7665
    display_line = aln_line;
 
7666
  }
 
7667
  
 
7668
  if (display_line >= bvp->TotalLines)
 
7669
  {
 
7670
    display_line = bvp->TotalLines - 1;
 
7671
  }
 
7672
  
 
7673
  while (bvp->SeqPanLines[display_line]->bioSeqLine > aln_line
 
7674
         && display_line > -1)
 
7675
  {
 
7676
    display_line --;
 
7677
  }
 
7678
  
 
7679
  while (bvp->SeqPanLines[display_line]->bioSeqLine < aln_line 
 
7680
         && display_line < bvp->TotalLines - 1)
 
7681
  {
 
7682
    display_line++;
 
7683
  }
 
7684
 
 
7685
  if (bvp->SeqPanLines[display_line]->bioSeqLine == aln_line)
 
7686
  {
 
7687
    while (display_line > -1 
 
7688
           && bvp->SeqPanLines[display_line]->bioSeqLine == aln_line)
 
7689
    {
 
7690
      display_line --;
 
7691
    }
 
7692
    display_line++;
 
7693
  }
 
7694
  return display_line;
 
7695
}
 
7696
 
 
7697
static void SeqAlnSelectItem (BioseqViewPtr bvp, Int2 itemID)
 
7698
{
 
7699
  ValNodePtr vnp;
 
7700
  
 
7701
  for (vnp = bvp->Selection; vnp != NULL; vnp = vnp->next)
 
7702
  {
 
7703
    if (vnp->data.intvalue == itemID)
 
7704
    {
 
7705
      vnp->choice = 1;
 
7706
      return;    
 
7707
    }
 
7708
  }
 
7709
  ValNodeAddInt (&bvp->Selection, 1, itemID);
 
7710
}
 
7711
 
 
7712
static void SeqAlnUnselectItem (BioseqViewPtr bvp, Int2 itemID)
 
7713
{
 
7714
  ValNodePtr vnp;
 
7715
  
 
7716
  for (vnp = bvp->Selection; vnp != NULL; vnp = vnp->next)
 
7717
  {
 
7718
    if (vnp->data.intvalue == itemID)
 
7719
    {
 
7720
      vnp->choice = 0;
 
7721
      return;    
 
7722
    }
 
7723
  }
 
7724
}
 
7725
 
 
7726
static void SeqAlnScrollToAlnPos (SeqEdFormPtr sefp, Int4 pos)
 
7727
{
 
7728
  BaR          sb;
 
7729
  Int4         scroll_pos, bmax;
 
7730
  WindoW       currentport, temport;
 
7731
  Int4         aln_len;
 
7732
 
 
7733
  if (sefp == NULL 
 
7734
      || sefp->bfp == NULL
 
7735
      || sefp->bfp->bvd.salp == NULL)
 
7736
  {
 
7737
    return;
 
7738
  }
 
7739
  aln_len = AlnMgr2GetAlnLength(sefp->bfp->bvd.salp, FALSE); 
 
7740
 
 
7741
  if (pos < 0)
 
7742
  {
 
7743
    pos = 0;
 
7744
  }
 
7745
  else if (pos > aln_len)
 
7746
  {
 
7747
    pos = aln_len;
 
7748
  }
 
7749
 
 
7750
  sb = GetSlateVScrollBar ((SlatE) sefp->bfp->bvd.seqView);
 
7751
  if (sb == NULL) return;
 
7752
  bmax = GetBarMax (sb);
 
7753
 
 
7754
  scroll_pos = GetScrollPosForAlnPos (pos, &(sefp->bfp->bvd));
 
7755
  if (scroll_pos > bmax)
 
7756
  {
 
7757
    scroll_pos = bmax;
 
7758
  }
 
7759
  
 
7760
  SetBarValue (sb, scroll_pos);
 
7761
  currentport = ParentWindow (sefp->bfp->bvd.seqView);
 
7762
  temport = SavePort (currentport);
 
7763
  Select (sefp->bfp->bvd.seqView);
 
7764
  inval_panel (sefp->bfp->bvd.seqView, -1, -1); 
 
7765
  RestorePort (temport);
 
7766
}
 
7767
 
 
7768
static void SeqAlnGoToAlnPosBtn (ButtoN b)
 
7769
{
 
7770
  SeqEdFormPtr sefp;
 
7771
  Int4         aln_pos;
 
7772
  Char         str [16];
 
7773
 
 
7774
  sefp = (SeqEdFormPtr) GetObjectExtra ((WindoW)ParentWindow (b));
 
7775
  if (sefp == NULL || sefp->bfp == NULL) return;
 
7776
  
 
7777
  GetTitle (sefp->goto_txt, str, 15);
 
7778
  if (! CCStrToLong (str, &aln_pos))
 
7779
  {
 
7780
        return;
 
7781
  }
 
7782
  
 
7783
  SeqAlnScrollToAlnPos (sefp, aln_pos);
 
7784
}
 
7785
 
 
7786
static void SeqAlnGoToSeqPosBtn (ButtoN b)
 
7787
{
 
7788
  SeqEdFormPtr sefp;
 
7789
  Int4         seq_pos, aln_pos;
 
7790
  Char         str [16];
 
7791
  SeqIdPtr     sip;
 
7792
  BioseqPtr    bsp;
 
7793
 
 
7794
  sefp = (SeqEdFormPtr) GetObjectExtra ((WindoW)ParentWindow (b));
 
7795
  if (sefp == NULL 
 
7796
      || sefp->bfp == NULL
 
7797
      || sefp->bfp->bvd.salp == NULL)
 
7798
  {
 
7799
    return;
 
7800
  }
 
7801
 
 
7802
  sip = AlnMgr2GetNthSeqIdPtr(sefp->bfp->bvd.salp, sefp->bfp->bvd.TargetRow);
 
7803
  bsp = BioseqFind (sip);
 
7804
  if (bsp == NULL)
 
7805
  {
 
7806
    return;
 
7807
  }
 
7808
  
 
7809
  GetTitle (sefp->lookat_txt, str, 15);
 
7810
  if (! CCStrToLong (str, &seq_pos))
 
7811
  {
 
7812
        return;
 
7813
  }
 
7814
  
 
7815
  if (seq_pos < 0)
 
7816
  {
 
7817
    seq_pos = 0;
 
7818
  }
 
7819
  else if (seq_pos >= bsp->length)
 
7820
  {
 
7821
    seq_pos = bsp->length - 1;
 
7822
  }
 
7823
  
 
7824
  aln_pos = AlnMgr2MapBioseqToSeqAlign (sefp->bfp->bvd.salp,
 
7825
                                        seq_pos, 
 
7826
                                        sefp->bfp->bvd.TargetRow);
 
7827
  
 
7828
  SeqAlnScrollToAlnPos (sefp, aln_pos);
 
7829
}
 
7830
 
 
7831
static void SeqAlnClose (SeqEdFormPtr sefp)
 
7832
 
 
7833
{  
 
7834
  if (sefp == NULL) return;
 
7835
  Hide (sefp->form);
 
7836
  Remove (sefp->form); 
 
7837
  Update ();    
 
7838
}
 
7839
 
 
7840
static void SeqAlnCloseButton (ButtoN b)
 
7841
 
 
7842
{
 
7843
  SeqEdFormPtr  sefp;
 
7844
  
 
7845
  sefp = (SeqEdFormPtr) GetObjectExtra (b);
 
7846
  SeqAlnClose (sefp);
 
7847
}
 
7848
 
 
7849
static void SeqAlnCloseMenuItem (IteM i)
 
7850
 
 
7851
{
 
7852
  SeqEdFormPtr  sefp;
 
7853
  
 
7854
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
 
7855
  SeqAlnClose (sefp);
 
7856
}
 
7857
 
 
7858
static Int4 FindMaxLabelLen (SeqAlignPtr salp)
 
7859
{
 
7860
  SeqIdPtr  sip;
 
7861
  BioseqPtr bsp;
 
7862
  Char      tmpbuf[42];
 
7863
  Int4      i;
 
7864
  Int4      max_len = 0;
 
7865
  Int4      len;
 
7866
 
 
7867
  if (salp == NULL) return 0;
 
7868
  for (i = 0; i < salp->dim; i++) {
 
7869
    sip = AlnMgr2GetNthSeqIdPtr(salp, i + 1);
 
7870
    bsp = BioseqFind (sip);
 
7871
    if (bsp != NULL) {
 
7872
      sip = SeqIdFindBestAccession (bsp->id);
 
7873
    }
 
7874
    SeqIdWrite (sip, tmpbuf, PRINTID_TEXTID_ACCESSION, 41);
 
7875
    len = StringLen (tmpbuf) + 1;
 
7876
    if (len > max_len) {
 
7877
      max_len = len;
 
7878
    }
 
7879
  }
 
7880
  return max_len;
 
7881
}
 
7882
 
 
7883
static CharPtr GetSeqAlignLabels (SeqAlignPtr salp, Int4Ptr label_len)
 
7884
{
 
7885
  CharPtr   labels;
 
7886
  BioseqPtr bsp;
 
7887
  SeqIdPtr  sip;
 
7888
  Int4      i;
 
7889
 
 
7890
  if (salp == NULL || label_len == NULL) {
 
7891
    return NULL;
 
7892
  }
 
7893
 
 
7894
  *label_len = FindMaxLabelLen (salp);
 
7895
  if (*label_len < 1) return NULL;
 
7896
 
 
7897
  labels = (CharPtr) MemNew ((*label_len + 1) * salp->dim * sizeof (Char));
 
7898
  if (labels == NULL) return NULL;
 
7899
  MemSet (labels, 0, *label_len * salp->dim * sizeof (Char));
 
7900
 
 
7901
  for (i = 0; i < salp->dim; i++) {
 
7902
    sip = AlnMgr2GetNthSeqIdPtr(salp, i + 1);
 
7903
    bsp = BioseqFind (sip);
 
7904
    if (bsp != NULL) {
 
7905
      sip = SeqIdFindBestAccession (bsp->id);
 
7906
    }
 
7907
    SeqIdWrite (sip, labels + i * (*label_len + 1) * sizeof (Char),
 
7908
                PRINTID_TEXTID_ACCESSION, *label_len);
 
7909
  }
 
7910
  return labels;
 
7911
}
 
7912
 
 
7913
extern void 
 
7914
WriteAlignmentInterleaveToFile 
 
7915
(SeqAlignPtr salp,
 
7916
 FILE        *fp,
 
7917
 Int4        seq_chars_per_row,
 
7918
 Boolean     show_substitutions)
 
7919
{
 
7920
  Int4     row, start, stop;
 
7921
  Uint1Ptr alnbuf;
 
7922
  Uint1Ptr seqbuf;
 
7923
  Int4     alnbuf_len;
 
7924
  Int4     aln_len = AlnMgr2GetAlnLength(salp, FALSE);
 
7925
  CharPtr  alnlabels;
 
7926
  CharPtr  printed_line;
 
7927
  Int4     printed_line_len;
 
7928
  CharPtr  label_pos;
 
7929
  Int4     label_len = 0;
 
7930
 
 
7931
  if (salp == NULL || fp == NULL) return;
 
7932
 
 
7933
  alnlabels = GetSeqAlignLabels (salp, &label_len);
 
7934
  if (alnlabels != NULL) {
 
7935
    alnbuf = (Uint1Ptr) MemNew ((seq_chars_per_row + 1)* sizeof (Uint1));
 
7936
    if (alnbuf != NULL) {
 
7937
      seqbuf = (Uint1Ptr) MemNew ((seq_chars_per_row + 1) * sizeof (Uint1));
 
7938
      if (seqbuf != NULL) {
 
7939
        printed_line_len = label_len + 1 + seq_chars_per_row + 3;
 
7940
        printed_line = (CharPtr) MemNew (printed_line_len * sizeof (Char));
 
7941
        if (printed_line != NULL) {
 
7942
          printed_line [ printed_line_len - 1] = 0;
 
7943
          printed_line [ printed_line_len - 2] = '\n';
 
7944
          start = 0;
 
7945
          stop = seq_chars_per_row - 1;
 
7946
          while (start < aln_len) {
 
7947
            for (row = 1; row <= salp->dim; row++) {
 
7948
              MemSet (printed_line, ' ', printed_line_len - 2);
 
7949
              label_pos = alnlabels + (row - 1) * (label_len + 1) * sizeof (Char);
 
7950
              MemCpy (printed_line, label_pos, StringLen (label_pos));
 
7951
              AlignmentIntervalToString (salp, row, start, stop, 1, TRUE, 
 
7952
                                         seqbuf, alnbuf, &alnbuf_len,
 
7953
                                         show_substitutions);
 
7954
              MemCpy (printed_line + label_len + 1, alnbuf, alnbuf_len);
 
7955
              fprintf (fp, printed_line);
 
7956
            }
 
7957
            fprintf (fp, "\n");
 
7958
            start = stop + 1;
 
7959
            stop += seq_chars_per_row;
 
7960
          }
 
7961
          MemFree (printed_line);
 
7962
        }
 
7963
        MemFree (seqbuf);
 
7964
      }
 
7965
      MemFree (alnbuf);
 
7966
    }
 
7967
    MemFree (alnlabels);
 
7968
  }
 
7969
}
 
7970
 
 
7971
extern void WriteAlignmentContiguousToFile
 
7972
(SeqAlignPtr salp,
 
7973
 FILE        *fp,
 
7974
 Int4        seq_chars_per_row,
 
7975
 Boolean     show_substitutions)
 
7976
{
 
7977
  Int4         num_segments;
 
7978
  SeqAlignPtr  tmp_salp;
 
7979
  Int4         idx;
 
7980
  CharPtr PNTR alnlabels = NULL;
 
7981
  Int4Ptr      label_len = NULL;
 
7982
  Int4Ptr      aln_len = NULL;
 
7983
  Uint1Ptr     alnbuf = NULL;
 
7984
  Uint1Ptr     seqbuf = NULL;
 
7985
  CharPtr      printed_line = NULL;
 
7986
  Int4         alnbuf_len;
 
7987
  Int4         printed_line_len;
 
7988
  CharPtr      label_pos;
 
7989
  Int4         row, start, stop;
 
7990
  
 
7991
  if (salp == NULL || fp == NULL) return;
 
7992
  
 
7993
  num_segments = 0;
 
7994
  for (tmp_salp = salp; tmp_salp != NULL; tmp_salp = tmp_salp->next)
 
7995
  {
 
7996
        num_segments++;
 
7997
  }
 
7998
  
 
7999
  
 
8000
  /* get labels and lengths for all segments */
 
8001
  alnlabels = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num_segments);
 
8002
  label_len = (Int4Ptr) MemNew (sizeof (Int4) * num_segments);
 
8003
  aln_len = (Int4Ptr) MemNew (sizeof (Int4) * num_segments);
 
8004
  if (alnlabels != NULL && label_len != NULL && aln_len != NULL)
 
8005
  {     
 
8006
    for (tmp_salp = salp, idx = 0; tmp_salp != NULL && idx < num_segments; tmp_salp = tmp_salp->next, idx++)
 
8007
    {
 
8008
          alnlabels [idx] = GetSeqAlignLabels (tmp_salp, &label_len[idx]);
 
8009
      aln_len [idx]= AlnMgr2GetAlnLength(tmp_salp, FALSE);
 
8010
 
 
8011
    }
 
8012
 
 
8013
    /* get buffers */
 
8014
    alnbuf = (Uint1Ptr) MemNew (seq_chars_per_row * sizeof (Uint1));
 
8015
    seqbuf = (Uint1Ptr) MemNew (seq_chars_per_row * sizeof (Uint1));
 
8016
    printed_line_len = seq_chars_per_row + 3;
 
8017
    printed_line = (CharPtr) MemNew (printed_line_len * sizeof (Char));
 
8018
    if (alnbuf != NULL && seqbuf != NULL && printed_line != NULL) {
 
8019
      printed_line [ printed_line_len - 1] = 0;
 
8020
      printed_line [ printed_line_len - 2] = '\n';
 
8021
 
 
8022
      for (row = 1; row <= salp->dim; row++) {
 
8023
        if (salp->next != NULL)
 
8024
        {
 
8025
          fprintf (fp, "[\n");
 
8026
        }
 
8027
        for (tmp_salp = salp, idx = 0;
 
8028
             tmp_salp != NULL && idx < num_segments;
 
8029
             tmp_salp = tmp_salp->next, idx++)
 
8030
        {
 
8031
          label_pos = alnlabels [idx] + (row - 1) * (label_len[idx] + 1) * sizeof (Char);
 
8032
          fprintf (fp, ">%s\n", label_pos);
 
8033
          start = 0;
 
8034
          stop = seq_chars_per_row - 1;
 
8035
          while (start < aln_len [idx]) {
 
8036
            MemSet (printed_line, ' ', printed_line_len - 2);
 
8037
            AlignmentIntervalToString (tmp_salp, row, start, stop, 1, TRUE, 
 
8038
                                       seqbuf, alnbuf, &alnbuf_len,
 
8039
                                       show_substitutions);
 
8040
            MemCpy (printed_line, alnbuf, alnbuf_len);
 
8041
            fprintf (fp, printed_line);
 
8042
            start = stop + 1;
 
8043
            stop += seq_chars_per_row;
 
8044
          }
 
8045
          fprintf (fp, "\n");
 
8046
        }
 
8047
        if (salp->next != NULL)
 
8048
        {
 
8049
          fprintf (fp, "]\n");
 
8050
        }
 
8051
      }
 
8052
    }
 
8053
    MemFree (alnbuf);
 
8054
    MemFree (seqbuf);
 
8055
    MemFree (printed_line);
 
8056
  }
 
8057
  MemFree (label_len);  
 
8058
  MemFree (alnlabels);
 
8059
  MemFree (aln_len);
 
8060
}
 
8061
 
 
8062
static void SeqAlnExportAln (SeqEdFormPtr sefp, Boolean interleave)
 
8063
{
 
8064
  FILE *fp;
 
8065
  Char  path[PATH_MAX];
 
8066
  
 
8067
  if (sefp == NULL || sefp->bfp == NULL || sefp->bfp->bvd.salp == NULL)
 
8068
  {
 
8069
    return;
 
8070
  }
 
8071
 
 
8072
  if (! GetOutputFileName (path, sizeof (path), "")) return;
 
8073
  fp = FileOpen (path, "w");
 
8074
  if (fp == NULL) 
 
8075
  {
 
8076
    Message (MSG_ERROR, "Unable to open %s", path);
 
8077
    return;
 
8078
  }
 
8079
  if (interleave)
 
8080
  {
 
8081
    WriteAlignmentInterleaveToFile (sefp->bfp->bvd.salp, fp,
 
8082
                                    sefp->bfp->bvd.CharsAtLine,
 
8083
                                    sefp->bfp->bvd.showAlnSubstitutions);
 
8084
  } else {
 
8085
    WriteAlignmentContiguousToFile (sefp->bfp->bvd.salp, fp, 
 
8086
                                    sefp->bfp->bvd.CharsAtLine,
 
8087
                                    sefp->bfp->bvd.showAlnSubstitutions);
 
8088
  }
 
8089
  
 
8090
  FileClose (fp);
 
8091
}
 
8092
 
 
8093
static void SeqAlnExportAlnMenuItem (IteM i, Boolean interleave)
 
8094
{
 
8095
  SeqEdFormPtr  sefp;
 
8096
  
 
8097
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
 
8098
  SeqAlnExportAln (sefp, interleave);
 
8099
}
 
8100
 
 
8101
static void SeqAlnExportInterleave (IteM i)
 
8102
{
 
8103
  SeqAlnExportAlnMenuItem (i, TRUE);
 
8104
}
 
8105
 
 
8106
static void SeqAlnExportContiguous (IteM i)
 
8107
{
 
8108
  SeqAlnExportAlnMenuItem (i, FALSE);
 
8109
}
 
8110
 
 
8111
static void SeqAlnShowSubstitutionsMenuItem (IteM i)
 
8112
{
 
8113
  SeqEdFormPtr  sefp;
 
8114
  WindoW        temport;
 
8115
  
 
8116
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
 
8117
  if (sefp != NULL && sefp->bfp != NULL)
 
8118
  {
 
8119
    sefp->bfp->bvd.showAlnSubstitutions = GetStatus (i);
 
8120
    temport = SavePort(sefp->form);
 
8121
    Select (sefp->bfp->bvd.seqView);
 
8122
    inval_panel (sefp->bfp->bvd.seqView, -1, -1);
 
8123
    RestorePort (temport);
 
8124
    Update ();
 
8125
  }
 
8126
}
 
8127
 
 
8128
static void RemoveSequencesFromAlignment (IteM i)
 
8129
{
 
8130
  SeqEdFormPtr  sefp;
 
8131
  Int4          n;
 
8132
  SeqIdPtr      sip;
 
8133
  BioseqPtr     bsp;
 
8134
  SeqEntryPtr   sep;
 
8135
  ValNodePtr    sip_list = NULL, vnp;
 
8136
  
 
8137
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
 
8138
  
 
8139
  if (sefp != NULL && sefp->bfp != NULL && sefp->bfp->bvd.salp != NULL)
 
8140
  {
 
8141
    sep = GetTopSeqEntryForEntityID (sefp->input_entityID);
 
8142
    /* first, check for pairwise alignments */
 
8143
    for (n = 1; n < sefp->bfp->bvd.salp->dim; n++)
 
8144
    {
 
8145
      sip = AlnMgr2GetNthSeqIdPtr(sefp->bfp->bvd.salp, n);
 
8146
      bsp = BioseqFind (sip);
 
8147
      if (bsp != NULL && isSelected (bsp->idx.itemID, &(sefp->bfp->bvd)))
 
8148
      {
 
8149
        if (IsSequenceFirstInPairwise (sep, sip))
 
8150
              {
 
8151
                    Message (MSG_ERROR, "One of the selected sequences is the first in a pairwise alignment."
 
8152
                    "  You must convert the alignment to a multiple alignment before trying to remove this sequence.");
 
8153
                    sip_list = ValNodeFree (sip_list);
 
8154
          return;
 
8155
              }
 
8156
              else
 
8157
              {
 
8158
                ValNodeAddPointer (&sip_list, bsp->idx.itemID, sip);
 
8159
              }
 
8160
      }
 
8161
    }
 
8162
    
 
8163
    for (vnp = sip_list; vnp != NULL; vnp = vnp->next)
 
8164
    {
 
8165
      SeqAlignBioseqDeleteById (sefp->bfp->bvd.salp, vnp->data.ptrvalue);
 
8166
      SeqAlnUnselectItem (&(sefp->bfp->bvd), vnp->choice);
 
8167
    }
 
8168
    sip_list = ValNodeFree (sip_list);
 
8169
    DeleteMarkedObjects (sefp->input_entityID, 0, NULL);
 
8170
    ObjMgrSetDirtyFlag (sefp->input_entityID, TRUE);
 
8171
    ObjMgrSendMsg (OM_MSG_UPDATE, sefp->input_entityID, 0, 0);  
 
8172
    /* reindex alignment */
 
8173
    SAIndex2Free2(sefp->bfp->bvd.salp->saip);
 
8174
    sefp->bfp->bvd.salp->saip = NULL;
 
8175
    AlnMgr2IndexSeqAlign(sefp->bfp->bvd.salp);
 
8176
    /* update alignment editor window */
 
8177
    ResizeSeqEditorWindow ((WindoW)sefp->form);
 
8178
  }
 
8179
}
 
8180
 
 
8181
typedef struct setalntarget 
 
8182
{
 
8183
  SeqEdFormPtr sefp;
 
8184
  Int4         target;  
 
8185
} SetAlnTargetData, PNTR SetAlnTargetPtr;
 
8186
 
 
8187
static void SeqAlnSetTarget (IteM i)
 
8188
{
 
8189
  SetAlnTargetPtr satp;
 
8190
  
 
8191
  satp = (SetAlnTargetPtr) GetObjectExtra (i);
 
8192
  if (satp != NULL && satp->sefp != NULL
 
8193
      && satp->sefp->bfp != NULL
 
8194
      && satp->sefp->bfp->bvd.salp != NULL
 
8195
      && satp->target > 0
 
8196
      && satp->target <= satp->sefp->bfp->bvd.salp->dim)
 
8197
  {
 
8198
    satp->sefp->bfp->bvd.TargetRow = satp->target;
 
8199
    ResizeSeqEditorWindow ((WindoW) satp->sefp->form);
 
8200
  }
 
8201
}
 
8202
 
 
8203
static void SeqAlnValidateAlignment (IteM i)
 
8204
{
 
8205
  SeqEdFormPtr    sefp;
 
8206
 
 
8207
  sefp = (SeqEdFormPtr) GetObjectExtra (i);
 
8208
  if (sefp == NULL) return;
 
8209
  
 
8210
  ValidateSeqAlign (sefp->bfp->bvd.salp, 0, TRUE, TRUE, TRUE, FALSE, FALSE, NULL);
 
8211
}
 
8212
 
 
8213
static void CreateAlnMenus (WindoW w)
 
8214
 
 
8215
{
 
8216
  MenU            edit_menu;
 
8217
  IteM            localItem;
 
8218
  MenU            sub;
 
8219
  SeqEdFormPtr    sefp;
 
8220
  Int4            n;
 
8221
  SetAlnTargetPtr satp;
 
8222
  Char            label [128];
 
8223
  SeqIdPtr        sip;
 
8224
  BioseqPtr       bsp;
 
8225
  
 
8226
  if (w == NULL) return;
 
8227
  sefp = (SeqEdFormPtr) GetObjectExtra (w);
 
8228
  if (sefp == NULL) return;
 
8229
  
 
8230
  /* File Menu */
 
8231
  edit_menu = PulldownMenu (w, "File");
 
8232
  sub = SubMenu (edit_menu, "Export");
 
8233
  localItem = CommandItem (sub, "Interleave", SeqAlnExportInterleave);
 
8234
  SetObjectExtra (localItem, sefp, NULL);
 
8235
  localItem = CommandItem (sub, "Contiguous", SeqAlnExportContiguous);
 
8236
  SetObjectExtra (localItem, sefp, NULL);
 
8237
  
 
8238
  localItem = CommandItem (edit_menu, "Close", SeqAlnCloseMenuItem);
 
8239
  SetObjectExtra (localItem, sefp, NULL);
 
8240
  
 
8241
  /* Edit Menu */
 
8242
  edit_menu = PulldownMenu (w, "Edit");
 
8243
  localItem = CommandItem (edit_menu, "Remove Sequences From Alignment", 
 
8244
                           RemoveSequencesFromAlignment);
 
8245
  SetObjectExtra (localItem, sefp, NULL);
 
8246
  localItem = CommandItem (edit_menu, "Validate Alignemtn", SeqAlnValidateAlignment);
 
8247
  SetObjectExtra (localItem, sefp, NULL);
 
8248
 
 
8249
  /* View menu */
 
8250
  edit_menu = PulldownMenu (w, "View");
 
8251
  sub = SubMenu (edit_menu, "Target");
 
8252
  for (n = 1; n <= sefp->bfp->bvd.salp->dim; n++)
 
8253
  {
 
8254
    sip = AlnMgr2GetNthSeqIdPtr(sefp->bfp->bvd.salp, n);
 
8255
    bsp = BioseqFind (sip);
 
8256
    if (bsp != NULL)
 
8257
    {
 
8258
      sip = SeqIdFindBestAccession (bsp->id);
 
8259
    }
 
8260
    SeqIdWrite (sip, label, PRINTID_REPORT, sizeof (label) - 1);
 
8261
    localItem = CommandItem (sub, label, SeqAlnSetTarget);
 
8262
    satp = (SetAlnTargetPtr) MemNew (sizeof (SetAlnTargetData));
 
8263
    if (satp != NULL)
 
8264
    {
 
8265
      satp->sefp = sefp;
 
8266
      satp->target = n;
 
8267
    }
 
8268
    SetObjectExtra (localItem, satp, StdCleanupExtraProc);
 
8269
  }
 
8270
  localItem = StatusItem (edit_menu, "Show Substitutions", SeqAlnShowSubstitutionsMenuItem);
 
8271
  SetObjectExtra (localItem, sefp, NULL);
 
8272
}
 
8273
 
 
8274
extern ForM CreateAlnEditorWindow (Int2 left, Int2 top, CharPtr windowname, SeqAlignPtr salp, Uint2 entityID)
 
8275
{
 
8276
  SeqEdFormPtr       sefp;
 
8277
  WindoW             w;
 
8278
  GrouP              g;
 
8279
  Char               str [16];
 
8280
  Int2               window_width = 650;
 
8281
  Int2               window_hgt = 300,
 
8282
                     charwidth,
 
8283
                     lineheight;
 
8284
  FonT               font;
 
8285
  Int4               btns_across;
 
8286
  OMUserDataPtr      omudp;
 
8287
  SeqIdPtr           sip;
 
8288
  
 
8289
  if (salp == NULL)
 
8290
  {
 
8291
    return NULL;
 
8292
  }
 
8293
  sefp = SeqEdFormNew ();
 
8294
  if (sefp == NULL) 
 
8295
  {
 
8296
    return NULL;
 
8297
  }
 
8298
  
 
8299
#ifdef WIN_MAC
 
8300
  font = ParseFont ("Monaco, 9");
 
8301
#endif
 
8302
#ifdef WIN_MSWIN
 
8303
  font = ParseFont ("Courier, 9");
 
8304
#endif
 
8305
#ifdef WIN_MOTIF
 
8306
  font = ParseFont ("fixed, 12");
 
8307
#endif
 
8308
  SelectFont (font);
 
8309
  charwidth  = CharWidth ('0');
 
8310
  lineheight = FontHeight () + SEQ_Y_OFFSET;
 
8311
 
 
8312
  w = DocumentWindow (left, top, (Int2)(-10), (Int2)(-10),  windowname, NULL, ResizeSeqEditorWindow);
 
8313
  SetObjectExtra (w, (Pointer) sefp, CleanupSeqEdForm);
 
8314
  sefp->form = (ForM) w;
 
8315
  sefp->formmessage = SeqEdFormMessage;
 
8316
 
 
8317
  sefp->input_entityID = entityID;
 
8318
 
 
8319
  /* initialize view pointer   */
 
8320
  sefp->bfp = (BioseqViewFormPtr) MemNew (sizeof (BioseqViewForm));
 
8321
  if (sefp->bfp == NULL) return NULL; 
 
8322
  
 
8323
  sefp->bfp->bvd.seqAlignMode = TRUE;
 
8324
  sefp->bfp->bvd.salp = salp;
 
8325
  AlnMgr2IndexSeqAlign(sefp->bfp->bvd.salp);
 
8326
  sip = AlnMgr2GetNthSeqIdPtr(sefp->bfp->bvd.salp, 1);
 
8327
  sefp->bfp->bvd.bsp = BioseqFind (sip);
 
8328
  sefp->bfp->bvd.TargetRow = 1;
 
8329
  sefp->bfp->bvd.DrawGrid = FALSE;
 
8330
  sefp->bfp->bvd.SeqStartPosX = (FindMaxLabelLen (sefp->bfp->bvd.salp) + 10) * charwidth; 
 
8331
  sefp->bfp->bvd.CharHeight = FontHeight ();
 
8332
  sefp->bfp->bvd.displayFont = font;
 
8333
  sefp->bfp->bvd.LineHeight = lineheight;
 
8334
  sefp->bfp->bvd.CharWidth = charwidth;
 
8335
  sefp->bfp->bvd.seq_entityID = sefp->input_entityID;
 
8336
  sefp->bfp->bvd.on_the_fly = FALSE;
 
8337
  sefp->bfp->bvd.showAlnSubstitutions = FALSE;
 
8338
 
 
8339
  CreateAlnMenus (w);
 
8340
   
 
8341
        btns_across = 4;
 
8342
  sefp->upper_button_group = HiddenGroup (w, -10, -10, NULL);
 
8343
  SetGroupSpacing (sefp->upper_button_group, 10, 3);
 
8344
  
 
8345
  g = HiddenGroup (sefp->upper_button_group, btns_across, 0, NULL);                  
 
8346
  SetGroupSpacing (g, 10, 3);
 
8347
  sprintf (str, "%ld", (long) sefp->edit_pos_start);
 
8348
  sefp->goto_btn = PushButton (g, "Go to alignment position:", SeqAlnGoToAlnPosBtn);
 
8349
  sefp->goto_txt = DialogText (g, str, (Int2)6, NULL);
 
8350
  sefp->lookat_btn = PushButton (g, "Go to sequence position:", SeqAlnGoToSeqPosBtn);
 
8351
  sefp->lookat_txt = DialogText (g, str, (Int2)6, NULL);
 
8352
  
 
8353
  /* numbering location and grid controls */  
 
8354
  StaticPrompt (g, " Numbering: ", 0, popupMenuHeight, programFont, 'l');
 
8355
  sefp->bfp->bvd.newNumControl = PopupList (g, TRUE, ChangeSeqEditControls);
 
8356
  SetObjectExtra (sefp->bfp->bvd.newNumControl, sefp, NULL);
 
8357
  PopupItem (sefp->bfp->bvd.newNumControl, "None");
 
8358
  PopupItem (sefp->bfp->bvd.newNumControl, "Side");
 
8359
  PopupItem (sefp->bfp->bvd.newNumControl, "Top");
 
8360
  SetValue (sefp->bfp->bvd.newNumControl, 3);    
 
8361
  StaticPrompt (g, " Grid: ", 0, popupMenuHeight, programFont, 'l');
 
8362
  sefp->bfp->bvd.newGridControl = PopupList (g, TRUE, ChangeSeqEditControls);
 
8363
  SetObjectExtra (sefp->bfp->bvd.newGridControl, sefp, NULL);
 
8364
  PopupItem (sefp->bfp->bvd.newGridControl, "On");
 
8365
  PopupItem (sefp->bfp->bvd.newGridControl, "Off");
 
8366
  SetValue (sefp->bfp->bvd.newGridControl, 2);
 
8367
  
 
8368
  g = HiddenGroup (w, 1, 0, NULL);
 
8369
                      
 
8370
  sefp->position_label = StaticPrompt (g, "", window_width, dialogTextHeight, programFont, 'l');
 
8371
  SeqEdUpdateStatus (sefp);
 
8372
  
 
8373
  g = HiddenGroup (w, 1, 0, NULL);
 
8374
 
 
8375
  sefp->bfp->bvd.seqView = AutonomousPanel4 (g, window_width, window_hgt, onDrawSeqPanel, onVScrollBarSeqPanel, NULL, sizeof (BioseqViewPtr), onCloseSeqPanel, NULL);
 
8376
 
 
8377
  SetObjectExtra (sefp->bfp->bvd.seqView, sefp->bfp, NULL);
 
8378
  
 
8379
  sefp->lower_button_group = HiddenGroup (w, 6, 0, NULL);
 
8380
  SetGroupSpacing (sefp->lower_button_group, 10, 3);
 
8381
  StaticPrompt (sefp->lower_button_group, "Features:", 0, dialogTextHeight, programFont, 'l');
 
8382
  sefp->bfp->bvd.newFeatControl = PopupList (sefp->lower_button_group, TRUE, ChangeSeqEditControls);
 
8383
  PopupItem (sefp->bfp->bvd.newFeatControl, "Target Sequence");
 
8384
  PopupItem (sefp->bfp->bvd.newFeatControl, "Hidden");
 
8385
  PopupItem (sefp->bfp->bvd.newFeatControl, "All Sequences");
 
8386
  SetValue (sefp->bfp->bvd.newFeatControl, 2);
 
8387
  SetObjectExtra (sefp->bfp->bvd.newFeatControl, sefp, NULL);
 
8388
  sefp->accept = PushButton (sefp->lower_button_group, "Close", SeqAlnCloseButton);
 
8389
  SetObjectExtra (sefp->accept, sefp, NULL);
 
8390
  ResizeSeqView (&(sefp->bfp->bvd));
 
8391
  RealizeWindow (w);
 
8392
/*  SetSlateChar ((SlatE) sefp->bfp->bvd.seqView, SeqEdOnKey); */
 
8393
  SetSeqAlnPanelClick (sefp);
 
8394
  
 
8395
  /* register to receive update messages */
 
8396
  sefp->userkey = OMGetNextUserKey ();
 
8397
  sefp->procid = 0;
 
8398
  sefp->proctype = OMPROC_EDIT;
 
8399
  omudp = ObjMgrAddUserData (sefp->input_entityID, sefp->procid, sefp->proctype, sefp->userkey);
 
8400
  if (omudp != NULL) {
 
8401
    omudp->userdata.ptrvalue = (Pointer) sefp;
 
8402
    omudp->messagefunc = SeqEditMsgFunc;
 
8403
  }
 
8404
 
 
8405
  return (ForM) w;
 
8406
}
 
8407
 
6397
8408
 
6398
8409
BioseqPageData seqpnlPageData = {
6399
8410
  "Sequence", TRUE, TRUE, TRUE, FALSE, -1,
6424
8435
  {
6425
8436
        if (move_up)
6426
8437
        {
6427
 
          if (coord >= len)
 
8438
          if (coord >= len - 1)
6428
8439
          {
6429
 
                return len;
 
8440
                return len - 1;
6430
8441
          }
6431
8442
          else
6432
8443
          {
6480
8491
}
6481
8492
 
6482
8493
 
6483
 
static void SeqEdRemapLocation (SeqAlignPtr salp, SeqLocPtr slp, Int4 seq_len)
 
8494
NLM_EXTERN void SeqEdRemapLocation (SeqAlignPtr salp, SeqLocPtr slp, Int4 seq_len)
6484
8495
 
6485
8496
{
6486
8497
 
6549
8560
  }
6550
8561
}
6551
8562
 
6552
 
 
6553
 
static void SeqEdFixProteinFeatures (BioseqPtr oldbsp, BioseqPtr newbsp)
 
8563
NLM_EXTERN Boolean SeqEdFixProteinFeatures (BioseqPtr oldbsp, BioseqPtr newbsp, Boolean force_fix)
6554
8564
{
6555
8565
  SeqAlignPtr       salp = NULL;
6556
8566
  Boolean           revcomp = FALSE;
6557
8567
  SeqFeatPtr        sfp;
6558
8568
  SeqMgrFeatContext fcontext;
 
8569
  Boolean           tried_to_get_alignment = FALSE;
6559
8570
  Boolean           unmappable_feats = FALSE;
6560
 
  Boolean           tried_to_get_alignment = FALSE;
 
8571
  SeqLocPtr         slp_tmp = NULL;
6561
8572
  
6562
 
  if (oldbsp == NULL || newbsp == NULL) return;
 
8573
  if (oldbsp == NULL || newbsp == NULL) return FALSE;
6563
8574
 
6564
8575
  /* get alignment between old and new proteins */
6565
8576
 
6566
 
  if (ISA_na (oldbsp->mol) != ISA_na (newbsp->mol)) return;
 
8577
  if (ISA_na (oldbsp->mol) != ISA_na (newbsp->mol)) return FALSE;
6567
8578
 
6568
8579
  /* iterate through the features on the old protein.  Full length features
6569
8580
   * should be set to the new length.  Other features should be mapped through
6570
8581
   * the alignment (if possible), otherwise warn the user that they could not
6571
8582
   * be remapped. */      
 
8583
 
 
8584
  if (!force_fix)
 
8585
  {
 
8586
    for (sfp = SeqMgrGetNextFeature (oldbsp, NULL, 0, 0, &fcontext);
 
8587
         sfp != NULL && !unmappable_feats;
 
8588
         sfp = SeqMgrGetNextFeature (oldbsp, sfp, 0, 0, &fcontext))
 
8589
    {
 
8590
      if (sfp->idx.subtype != FEATDEF_PROT)
 
8591
      {
 
8592
        if (salp == NULL)
 
8593
        {
 
8594
          salp = Sequin_GlobalAlign2Seq (oldbsp, newbsp, &revcomp);
 
8595
        }
 
8596
        if (salp == NULL)
 
8597
        {
 
8598
          unmappable_feats = TRUE;
 
8599
        } 
 
8600
        else
 
8601
        {
 
8602
          slp_tmp = (SeqLocPtr) AsnIoMemCopy (sfp->location,
 
8603
                                              (AsnReadFunc) SeqLocAsnRead,
 
8604
                                              (AsnWriteFunc) SeqLocAsnWrite);
 
8605
          SeqEdRemapLocation (salp, slp_tmp, newbsp->length);                   
 
8606
          if (slp_tmp == NULL)
 
8607
          {
 
8608
            unmappable_feats = TRUE;
 
8609
          }
 
8610
          else
 
8611
          {
 
8612
            slp_tmp = SeqLocFree (slp_tmp);
 
8613
          }
 
8614
        }
 
8615
      }
 
8616
    }
 
8617
    if (unmappable_feats)
 
8618
    {
 
8619
      return FALSE;
 
8620
    }
 
8621
  }
6572
8622
  
6573
8623
  for (sfp = SeqMgrGetNextFeature (oldbsp, NULL, 0, 0, &fcontext);
6574
8624
       sfp != NULL;
6575
8625
       sfp = SeqMgrGetNextFeature (oldbsp, sfp, 0, 0, &fcontext))
6576
8626
  {
6577
 
        if (LocationMatchesEntireSequence (sfp->location, oldbsp))
6578
 
        {
6579
 
          /* make new location match new sequence length */
6580
 
          MakeLocationMatchEntireSequence (sfp->location, newbsp);
6581
 
        }
6582
 
        else
6583
 
        {
6584
 
          if (salp == NULL && !tried_to_get_alignment)
6585
 
          {
6586
 
        salp = Sqn_GlobalAlign2Seq (oldbsp, newbsp, &revcomp);
6587
 
        tried_to_get_alignment = TRUE;  
6588
 
          }
6589
 
          if (salp != NULL)
6590
 
          {
6591
 
            SeqEdRemapLocation (salp, sfp->location, newbsp->length);                   
6592
 
          }
6593
 
          else
6594
 
          {
6595
 
                unmappable_feats = TRUE;
6596
 
          }
6597
 
        }
 
8627
    if (sfp->idx.subtype == FEATDEF_PROT)
 
8628
    {
 
8629
      /* make new location match new sequence length */
 
8630
      MakeLocationMatchEntireSequence (sfp->location, newbsp);
 
8631
    }
 
8632
    else
 
8633
    {
 
8634
      if (salp == NULL && !tried_to_get_alignment)
 
8635
      {
 
8636
        salp = Sequin_GlobalAlign2Seq (oldbsp, newbsp, &revcomp);
 
8637
        tried_to_get_alignment = TRUE;
 
8638
      }
 
8639
      if (salp != NULL)
 
8640
      {
 
8641
        SeqEdRemapLocation (salp, sfp->location, newbsp->length);                       
 
8642
      }
 
8643
      else
 
8644
      {
 
8645
        unmappable_feats = TRUE;
 
8646
      }
 
8647
    }
6598
8648
  } 
6599
8649
        
6600
8650
  if (salp != NULL)
6603
8653
  }
6604
8654
  if (unmappable_feats)
6605
8655
  {
6606
 
        Message (MSG_ERROR, "Unable to construct alignment between old and new "
6607
 
                  "proteins - you will need to adjust the protein features "
6608
 
                  "manually.");
 
8656
    return FALSE;
 
8657
  }
 
8658
  else
 
8659
  {
 
8660
    return TRUE;
6609
8661
  }
6610
8662
}
6611
8663
 
6624
8676
  Uint1         seq_data_type;
6625
8677
  Int4          old_length;
6626
8678
  BioseqPtr     newbsp;
 
8679
  ProtRefPtr    prp;
 
8680
  SeqFeatPtr    prot_sfp;
6627
8681
  
6628
8682
  if (featbsp == NULL || sfp == NULL || sfp->location == NULL 
6629
 
      || sfp->idx.subtype != FEATDEF_CDS) 
 
8683
      || sfp->data.choice != SEQFEAT_CDREGION) 
6630
8684
  {
6631
8685
        return;
6632
8686
  }
6695
8749
              slp->data.ptrvalue = SeqIdDup (new_prot_id);
6696
8750
            }
6697
8751
            sfp->product = slp;
 
8752
            
 
8753
            /* create full length protein feature */
 
8754
        prp = ProtRefNew ();
 
8755
        prot_sfp = CreateNewFeature (new_prot_sep, NULL, SEQFEAT_PROT, NULL);
 
8756
        if (prot_sfp != NULL) {
 
8757
          prot_sfp->data.value.ptrvalue = (Pointer) prp;
 
8758
        }
6698
8759
      }
6699
8760
      else
6700
8761
      {
6701
8762
        /* propagate features to new protein */
6702
 
        SeqEdFixProteinFeatures (old_prot, newbsp);
 
8763
        if (!SeqEdFixProteinFeatures (old_prot, newbsp, TRUE))
 
8764
        {
 
8765
          Message (MSG_ERROR, "Unable to construct alignment between old and new "
 
8766
                  "proteins - you will need to adjust the protein features "
 
8767
                  "manually.");
 
8768
        }
6703
8769
                
6704
8770
        /* then replace old protein with new */
6705
8771
        seq_data_type = old_prot->seq_data_type;
6883
8949
  switch (sejp->action)
6884
8950
  {
6885
8951
        case eSeqEdInsert:
 
8952
    case eSeqEdInsertGap:
6886
8953
      rval = SeqEdInsert (sejp);
6887
8954
          break;
6888
8955
        case eSeqEdDelete:
 
8956
    case eSeqEdDeleteGap:
6889
8957
          slp = SeqLocIntNew (sejp->offset, sejp->offset + sejp->num_chars - 1,
6890
8958
                              Seq_strand_plus, sejp->bsp->id);
6891
8959
      spp = SeqPortNewByLoc (slp, Seq_code_iupacna);
6947
9015
  switch (sejp->action)
6948
9016
  {
6949
9017
        case eSeqEdDelete:
 
9018
    case eSeqEdDeleteGap:
6950
9019
      rval = SeqEdInsert (sejp);
6951
9020
          break;
6952
9021
        case eSeqEdInsert:
 
9022
    case eSeqEdInsertGap:
6953
9023
          slp = SeqLocIntNew (sejp->offset, sejp->offset + sejp->num_chars - 1,
6954
9024
                              Seq_strand_plus, sejp->bsp->id);
6955
9025
      spp = SeqPortNewByLoc (slp, Seq_code_iupacna);
6999
9069
  return rval;
7000
9070
}
7001
9071
 
 
9072
 
 
9073
static SeqAlignPtr LIBCALLBACK GetSeqAlign (BioseqPtr bsp1, BioseqPtr bsp2)
 
9074
{
 
9075
   BLAST_SummaryOptions *options = NULL;
 
9076
   SeqAlignPtr           salp = NULL;
 
9077
   
 
9078
   if (bsp1 == NULL || bsp2 == NULL) return NULL;
 
9079
 
 
9080
   BLAST_SummaryOptionsInit(&options);
 
9081
   if (bsp1->length > 10000 || bsp2->length > 10000)
 
9082
   {
 
9083
      options->filter_string = StringSave ("m L");
 
9084
      options->word_size = 20;
 
9085
      options->cutoff_evalue = act_get_eval (60);
 
9086
      options->hint = eNone;
 
9087
   }
 
9088
   else
 
9089
   {
 
9090
    options->filter_string = StringSave ("m F");
 
9091
   }
 
9092
   if (ISA_na (bsp1->mol))
 
9093
   {
 
9094
     options->program = eBlastn;
 
9095
   }
 
9096
   else
 
9097
   {
 
9098
     options->program = eBlastp;
 
9099
   }
 
9100
 
 
9101
   BLAST_TwoSequencesSearch(options, bsp1, bsp2, &salp);
 
9102
   BLAST_SummaryOptionsFree(options);
 
9103
   return salp;
 
9104
}
 
9105
 
 
9106
NLM_EXTERN SeqAlignPtr Sequin_GlobalAlign2Seq (BioseqPtr bsp1, BioseqPtr bsp2, BoolPtr revcomp)
 
9107
{
 
9108
   return Sqn_GlobalAlign2SeqEx (bsp1, bsp2, revcomp, GetSeqAlign);
 
9109
}