2285 lines
52 KiB
C
2285 lines
52 KiB
C
/*
|
||
Title: edUtils
|
||
|
||
File: edUtils.c
|
||
Purpose: C language utilities for contig editor
|
||
Last update: 5 April 1993
|
||
*/
|
||
|
||
|
||
/*
|
||
9/7/91 SD Added Trace Title field to call manageTrace
|
||
26/7/91 SD Tightened up editing options:
|
||
1. Allow only insertion and deletion of asterisks from consensus
|
||
This means no replacement. This CANNOT be overridden
|
||
2. Do not allow edits when cursor is not visible on the screen
|
||
28/7/91 SD Use FILE_NAME_LENGTH for trace file name length in showTrace
|
||
1/10/91 SD Removed static from calculateConsensusLength
|
||
Removed LLINOL and LLINOR from call to dojoin_
|
||
|
||
28/4/92 SD General Speedup
|
||
20/8/92 SD save state variable for returning what happened during edit/join
|
||
01/03/93 SD New dump contig command
|
||
05/04/93 JKB Check for editorState (disable edits after 'Leave Editor').
|
||
|
||
*/
|
||
|
||
|
||
#define CHKPNT(W,S) \
|
||
{ XSync(XtDisplay(W),False); fprintf(stderr,"CHKPNT: %s\n",S); }
|
||
|
||
|
||
/* ---- Includes ---- */
|
||
|
||
#include <stdio.h>
|
||
#include <ctype.h>
|
||
#include <stdlib.h>
|
||
#include <X11/Intrinsic.h>
|
||
#include <X11/StringDefs.h>
|
||
#include <X11/Xaw/Text.h>
|
||
#include <X11/Xaw/AsciiSrc.h>
|
||
#include <X11/Xlib.h> /* IMPORT: XBell */
|
||
#include "Sheet.h"
|
||
|
||
#include "edUtils.h"
|
||
#include "contigEditor.h"
|
||
#include "tman_main.h"
|
||
#include "main.h"
|
||
#include "select.h"
|
||
#include "tagUtils.h"
|
||
#include "undo.h"
|
||
#include "extend.h"
|
||
#include "fortran.h"
|
||
#include "fort.h"
|
||
#include "misc.h"
|
||
|
||
|
||
/* ------ External variables ------- */
|
||
extern int_f save_state;
|
||
extern enum States {StateDown=0,StateUp} editorState;
|
||
|
||
/*
|
||
** Static variables
|
||
** defining the state of the contig editor
|
||
*/
|
||
#define MAXEDSTATES 2
|
||
static int EdStructCount = 0;
|
||
static EdStruct edstate[MAXEDSTATES] = {
|
||
{
|
||
/* oldMax */ 0,
|
||
/* DB_flags */ DB_ACCESS_UPDATE |
|
||
DB_DELAYED_READ |
|
||
DB_DATA_TYPE_DNA,
|
||
/* DB_gelCount */ 0,
|
||
/* DB_contigNum */ 0,
|
||
/* DBlist */ NULL,
|
||
/* DBorder */ NULL,
|
||
/* DB */ NULL,
|
||
/* displayPos */ 1,
|
||
/* displayWidth */ DEFAULT_DISPLAY_WIDTH,
|
||
/* displayHeight */ 0,
|
||
/* cursorPos */ 1,
|
||
/* cursorSeq */ 0,
|
||
/* rulerDisplayed */ 1,
|
||
/* consensusDisplayed */ 1,
|
||
/* fontWidth */ 0,
|
||
/* fontHeight */ 0,
|
||
/* edWid */ NULL,
|
||
/* namesWid */ NULL,
|
||
/* sequencesWid */ NULL,
|
||
/* scrollButtonsWid */ NULL,
|
||
/* sliderWid */ NULL,
|
||
/* displayedConsensus */ "",
|
||
/* select_made */ 0,
|
||
/* select_seq */ 0,
|
||
/* select_start_pos */ 0,
|
||
/* select_end_pos */ 0,
|
||
/* select_tag */ NULL,
|
||
/* reveal_cutoffs */ 0,
|
||
/* showDifferences */ 0
|
||
},
|
||
{
|
||
/* oldMax */ 0,
|
||
/* DB_flags */ DB_ACCESS_UPDATE |
|
||
DB_DELAYED_READ |
|
||
DB_DATA_TYPE_DNA,
|
||
/* DB_gelCount */ 0,
|
||
/* DB_contigNum */ 0,
|
||
/* DBlist */ NULL,
|
||
/* DBorder */ NULL,
|
||
/* DB */ NULL,
|
||
/* displayPos */ 1,
|
||
/* displayWidth */ DEFAULT_DISPLAY_WIDTH,
|
||
/* displayHeight */ 0,
|
||
/* cursorPos */ 1,
|
||
/* cursorSeq */ 0,
|
||
/* rulerDisplayed */ 1,
|
||
/* consensusDisplayed */ 1,
|
||
/* fontWidth */ 0,
|
||
/* fontHeight */ 0,
|
||
/* edWid */ NULL,
|
||
/* namesWid */ NULL,
|
||
/* sequencesWid */ NULL,
|
||
/* scrollButtonsWid */ NULL,
|
||
/* sliderWid */ NULL,
|
||
/* displayedConsensus */ "",
|
||
/* select_made */ 0,
|
||
/* select_seq */ 0,
|
||
/* select_start_pos */ 0,
|
||
/* select_end_pos */ 0,
|
||
/* select_tag */ NULL,
|
||
/* reveal_cutoffs */ 0,
|
||
/* showDifferences */ 0
|
||
}
|
||
};
|
||
|
||
static void bell()
|
||
/*
|
||
** Make a silly beep
|
||
*/
|
||
{
|
||
XBell (GetDisplay(),100);
|
||
}
|
||
|
||
|
||
|
||
void calculateConsensusLength(EdStruct *xx)
|
||
/*
|
||
** Calculate dynamic consensus length
|
||
*/
|
||
{
|
||
int sequenceEnd,i;
|
||
|
||
DBsetLength(xx,0,0);
|
||
for (i=1; i <= xx->DB_gelCount; i++) {
|
||
sequenceEnd = DBgetRelPos(xx,i) + DBgetLength(xx,i) -1;
|
||
if (DBgetLength(xx,0) < sequenceEnd) DBsetLength(xx,0,sequenceEnd);
|
||
}
|
||
}
|
||
|
||
EdStructPtr getFreeEdStruct()
|
||
/*
|
||
** Get the next free EdStruct
|
||
*/
|
||
{
|
||
if (EdStructCount == MAXEDSTATES)
|
||
return NULL;
|
||
else
|
||
return &edstate[EdStructCount++];
|
||
}
|
||
|
||
EdStructPtr intToEdStruct(int i)
|
||
/*
|
||
** Given an integer,
|
||
** return the corresponding edit structure
|
||
*/
|
||
{
|
||
return &edstate[i];
|
||
}
|
||
|
||
EdStructPtr widgetToEdStruct(Widget w)
|
||
/*
|
||
** Given a widget,
|
||
** return the corresponding edit structure
|
||
*/
|
||
{
|
||
int i;
|
||
if (w==NULL)
|
||
return NULL;
|
||
else
|
||
for (i=0;i<EdStructCount;i++)
|
||
if (w==edstate[i].edWid)
|
||
return &edstate[i];
|
||
return NULL;
|
||
}
|
||
|
||
/* ---- Private Functions ---- */
|
||
|
||
/************************************************/
|
||
|
||
|
||
|
||
|
||
char *DBgetSeq(EdStruct *xx, int seq)
|
||
/*
|
||
** Force reading in the sequence for seq
|
||
*/
|
||
{
|
||
int i;
|
||
|
||
/* already in memory? */
|
||
if (!seq || DBgetFlags(xx,seq) & DB_FLAG_SEQ_IN_MEMORY)
|
||
return DB_Seq(xx,seq);
|
||
|
||
/* allocate memory */
|
||
if ((DBsetSeq(xx,seq,(char *) malloc((int)*saveState.maxgel)))==NULL)
|
||
return NULL;
|
||
|
||
/* force reading */
|
||
i = DBgetNumber(xx,seq);
|
||
readw_(saveState.idevw,&i,DB_Seq(xx,seq),saveState.maxgel,*saveState.maxgel);
|
||
|
||
/* mark as read */
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_IN_MEMORY);
|
||
|
||
return DB_Seq(xx,seq);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
tagStruct *DBgetTags (EdStruct *xx, int seq)
|
||
/*
|
||
** Force tags into memory
|
||
*/
|
||
{
|
||
int i;
|
||
|
||
/* already in memory? */
|
||
if (!seq || DBgetFlags(xx,seq) & DB_FLAG_TAG_IN_MEMORY)
|
||
return (tagStruct *) DB_Tags(xx,seq);
|
||
|
||
/* read in tag list */
|
||
i = DBgetNumber(xx,seq);
|
||
DBsetTags(xx,seq,readTagList(i));
|
||
|
||
/* mark as read */
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_IN_MEMORY);
|
||
|
||
return (tagStruct *) DB_Tags(xx,seq);
|
||
}
|
||
|
||
|
||
|
||
char *DBgetName(EdStruct *xx, int seq)
|
||
/*
|
||
** Force reading in the sequence for seq
|
||
*/
|
||
{
|
||
int i;
|
||
char buf[NAMELEN+1];
|
||
|
||
/* already in memory? */
|
||
if (!seq || DBgetFlags(xx,seq) & DB_FLAG_NAME_IN_MEMORY)
|
||
return DB_Name(xx,seq);
|
||
|
||
/* allocate memory */
|
||
if ((DBsetName(xx,seq,(char *) malloc(sizeof(char)*(NAMELEN+1))))==NULL)
|
||
return NULL;
|
||
|
||
/* force reading */
|
||
i = DBgetNumber(xx,seq);
|
||
readn_(saveState.idevn,&i,buf,DB_NAMELEN); buf[10]='\0';
|
||
sprintf(DB_Name(xx,seq),"%*d %-*s",
|
||
DB_GELNOLEN,(DBgetComp(xx,seq)==COMPLEMENTED)?-DBgetNumber(xx,seq):DBgetNumber(xx,seq),
|
||
DB_NAMELEN, buf);
|
||
|
||
/* mark as read */
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_NAME_IN_MEMORY);
|
||
|
||
return DB_Name(xx,seq);
|
||
}
|
||
|
||
|
||
|
||
|
||
int initialiseDB(
|
||
EdStruct *xx,
|
||
int_f *idevr, /* unit number for relationships */
|
||
int_f *idevw, /* unit number for working versions of sequences */
|
||
int_f *idevn, /* unit number for sequence names */
|
||
int_f *relpg, /* relative positions of gels in sequences */
|
||
int_f *lngthg, /* lengths of sequences */
|
||
int_f *lnbr, /* left neighbours */
|
||
int_f *rnbr, /* right neighbours */
|
||
int_f *maxgel, /* maximum length of gel */
|
||
int_f *idbsiz, /* size of database */
|
||
int_f *llino /* left-most gel in contig */
|
||
)
|
||
/*
|
||
** Create an internal database and
|
||
** read all relevant data into it
|
||
*/
|
||
{
|
||
int i,c;
|
||
|
||
/*
|
||
** Reset things
|
||
*/
|
||
xx->showDifferences = 0;
|
||
|
||
/*
|
||
** determine gel number
|
||
*/
|
||
{
|
||
int dummy,numContigs;
|
||
int firstGel;
|
||
|
||
readr_(idevr,idbsiz,&dummy,&numContigs,&dummy,&dummy);
|
||
xx->DB_contigNum = (int)*idbsiz-numContigs;
|
||
readr_(idevr,&xx->DB_contigNum,&dummy,&dummy,&firstGel,&dummy);
|
||
while (xx->DB_contigNum < (int)*idbsiz && firstGel!=(int)*llino) {
|
||
xx->DB_contigNum++;
|
||
readr_(idevr,&xx->DB_contigNum,&dummy,&dummy,&firstGel,&dummy);
|
||
}
|
||
|
||
}
|
||
|
||
/*
|
||
** count number of gels in contig
|
||
*/
|
||
for (xx->DB_gelCount=1,i=(int) *llino;
|
||
xx->DB_gelCount<(int)*idbsiz && (int)rnbr[i-1];
|
||
xx->DB_gelCount++,i=(int)rnbr[i-1]);
|
||
|
||
if ((xx->DB = (DBStruct *) calloc (xx->DB_gelCount+1, sizeof(DBStruct)))==NULL)
|
||
goto disaster;
|
||
if ((xx->DBlist = (int *) calloc (xx->DB_gelCount+1, sizeof(int) ))==NULL)
|
||
goto disaster;
|
||
if ((xx->DBorder = (int *) calloc (xx->DB_gelCount+1, sizeof(int) ))==NULL)
|
||
goto disaster;
|
||
|
||
/*
|
||
** read information into local database
|
||
*/
|
||
for (c=1,i=(int) *llino;
|
||
c<(int)*idbsiz && i;
|
||
c++,i=(int)rnbr[i-1]) {
|
||
|
||
DBsetRelPos(xx,c,relpg[i-1]);
|
||
DBsetLength(xx,c,abs(lngthg[i-1]));
|
||
DBsetComp(xx,c,(lngthg[i-1]<0)?-1:1);
|
||
DBsetNumber(xx,c,i);
|
||
DBsetFlags(xx,c,DB_FLAG_NONE);
|
||
|
||
xx->DBorder[c] = c;
|
||
|
||
if (xx->DB_flags & DB_STORAGE_INTERNAL) {
|
||
if (DBgetSeq(xx,c)==NULL) goto disaster;
|
||
if (DBgetName(xx,c)==NULL) goto disaster;
|
||
(void)DBgetTags(xx,c);
|
||
}
|
||
|
||
}
|
||
/*
|
||
** Set up consensus
|
||
*/
|
||
{
|
||
DBsetRelPos(xx,0,1);
|
||
DBsetComp(xx,0,UNCOMPLEMENTED);
|
||
calculateConsensusLength(xx);
|
||
if ((DBsetSeq(xx,0,(char *) malloc(MAX_DISPLAY_WIDTH)))==NULL)
|
||
goto disaster;
|
||
if ((DBsetName(xx,0,(char *) malloc(sizeof(char)*(NAMELEN+1))))==NULL)
|
||
goto disaster;
|
||
sprintf(DB_Name(xx,0),"%*s %-*s",
|
||
DB_GELNOLEN," ",
|
||
DB_NAMELEN, "CONSENSUS");
|
||
xx->DBorder[0] = 0;
|
||
}
|
||
|
||
return 0;
|
||
|
||
disaster:
|
||
|
||
freeDB(xx);
|
||
return 1;
|
||
}
|
||
|
||
void freeDB(EdStruct *xx)
|
||
/*
|
||
** Free an internal database
|
||
*/
|
||
{
|
||
int i;
|
||
|
||
if (xx->DB != NULL)
|
||
for (i=0; i <= xx->DB_gelCount; i++) {
|
||
free(DB_Name(xx,i));
|
||
free(DB_Seq(xx,i));
|
||
destroyTagList(DB_Tags(xx,i));
|
||
}
|
||
|
||
free(xx->DB);
|
||
free(xx->DBlist);
|
||
free(xx->DBorder);
|
||
|
||
xx->DB = NULL;
|
||
xx->DBlist = NULL;
|
||
xx->DBorder = NULL;
|
||
}
|
||
|
||
|
||
void saveDB(
|
||
EdStruct *xx,
|
||
int_f *idevr, /* unit number for relationships */
|
||
int_f *idevw, /* unit number for working versions of sequences */
|
||
int_f *idevn, /* unit number for sequence names */
|
||
int_f *relpg, /* relative positions of gels in sequences */
|
||
int_f *lngthg, /* lengths of sequences */
|
||
int_f *lnbr, /* left neighbours */
|
||
int_f *rnbr, /* right neighbours */
|
||
int_f *maxgel /* maximum length of gel */
|
||
)
|
||
/*
|
||
** Save an internal database
|
||
*/
|
||
{
|
||
int i;
|
||
int N,leftN,rightN;
|
||
int flag;
|
||
|
||
for (i=1; i<=xx->DB_gelCount; i++) {
|
||
/*
|
||
** update relationships
|
||
*/
|
||
N = DBgetNumber(xx,xx->DBorder[i]);
|
||
relpg[N-1] = DBgetRelPos(xx,xx->DBorder[i]);
|
||
lngthg[N-1] = (DBgetComp(xx,xx->DBorder[i])==COMPLEMENTED)?-DBgetLength(xx,xx->DBorder[i]):DBgetLength(xx,xx->DBorder[i]);
|
||
if (i==1)
|
||
leftN = 0;
|
||
else
|
||
leftN = DBgetNumber(xx,xx->DBorder[i-1]);
|
||
if (i==xx->DB_gelCount)
|
||
rightN = 0;
|
||
else
|
||
rightN = DBgetNumber(xx,xx->DBorder[i+1]);
|
||
lnbr[N-1] = leftN;
|
||
rnbr[N-1] = rightN;
|
||
writer_(idevr,&N,&relpg[N-1],&lngthg[N-1],&lnbr[N-1],&rnbr[N-1]);
|
||
|
||
flag = DBgetFlags(xx,xx->DBorder[i]);
|
||
/*
|
||
** update working versions
|
||
*/
|
||
if (flag&(DB_FLAG_SEQ_IN_MEMORY|DB_FLAG_SEQ_MODIFIED))
|
||
writew_(idevw,&N,DB_Seq(xx,xx->DBorder[i]),maxgel,*maxgel);
|
||
/*
|
||
** update tag list
|
||
*/
|
||
if (flag&(DB_FLAG_TAG_IN_MEMORY|DB_FLAG_TAG_MODIFIED)) {
|
||
writeTagList(xx, xx->DBorder[i]);
|
||
destroyTagList(DB_Tags(xx,xx->DBorder[i]));
|
||
DBsetTags(xx,xx->DBorder[i],readTagList(DBgetNumber(xx,xx->DBorder[i])));
|
||
}
|
||
|
||
/*
|
||
** Preserve only ``sequence in memory flag''
|
||
*/
|
||
DBsetFlags(xx,xx->DBorder[i],
|
||
flag&(DB_FLAG_SEQ_IN_MEMORY ||
|
||
DB_FLAG_NAME_IN_MEMORY ||
|
||
DB_FLAG_TAG_IN_MEMORY));
|
||
|
||
}
|
||
|
||
/*
|
||
** update contig relationships
|
||
*/
|
||
calculateConsensusLength(xx);
|
||
relpg[xx->DB_contigNum-1] = DBgetLength(xx,0);
|
||
lngthg[xx->DB_contigNum-1] = 0;
|
||
lnbr[xx->DB_contigNum-1] = DBgetNumber(xx,xx->DBorder[1]);
|
||
rnbr[xx->DB_contigNum-1] = DBgetNumber(xx,xx->DBorder[xx->DB_gelCount]);
|
||
writer_(idevr,
|
||
&xx->DB_contigNum,
|
||
&relpg[xx->DB_contigNum-1],
|
||
&lngthg[xx->DB_contigNum-1],
|
||
&lnbr[xx->DB_contigNum-1],
|
||
&rnbr[xx->DB_contigNum-1]
|
||
);
|
||
flushl_(idevr);
|
||
flushl_(idevw);
|
||
flushl_(idevn); /* not needed really */
|
||
flushl_(&devils_.idevt);
|
||
flushl_(&devils_.idevc);
|
||
|
||
cleanUpStack(&bucketStack);
|
||
|
||
/* update save state */
|
||
if(xx == intToEdStruct(0))
|
||
save_state |= (int_f)1;
|
||
else
|
||
save_state |= (int_f)2;
|
||
|
||
|
||
}
|
||
|
||
void joinDB(
|
||
int_f *idevr, /* unit number for relationships */
|
||
int_f *idevw, /* unit number for working versions of sequences */
|
||
int_f *idevn, /* unit number for sequence names */
|
||
int_f *relpg, /* relative positions of gels in sequences */
|
||
int_f *lngthg, /* lengths of sequences */
|
||
int_f *lnbr, /* left neighbours */
|
||
int_f *rnbr, /* right neighbours */
|
||
int_f *maxgel, /* maximum length of gel */
|
||
int_f *llinol,
|
||
int_f *lnconl,
|
||
int_f *llinor,
|
||
int_f *lnconr,
|
||
int_f *ngels,
|
||
int_f *nconts,
|
||
int_f *idbsiz
|
||
)
|
||
{
|
||
int_f relx;
|
||
int i;
|
||
|
||
/*
|
||
** Save an internal databases
|
||
*/
|
||
for (i=0;i<2;i++)
|
||
saveDB(
|
||
intToEdStruct(i),
|
||
idevr,
|
||
idevw,
|
||
idevn,
|
||
relpg,
|
||
lngthg,
|
||
lnbr,
|
||
rnbr,
|
||
maxgel
|
||
);
|
||
relx = editorLockedPos(1/*force*/);
|
||
if (relx<0) {
|
||
relx = 1-relx;
|
||
dojoin_(relpg,lngthg,lnbr,rnbr,ngels,nconts,lnconl,lnconr,
|
||
idbsiz,idevr,idevw,&relx);
|
||
} else {
|
||
relx = 1+relx;
|
||
dojoin_(relpg,lngthg,lnbr,rnbr,ngels,nconts,lnconr,lnconl,
|
||
idbsiz,idevr,idevw,&relx);
|
||
}
|
||
|
||
save_state |= (int_f)4;
|
||
|
||
}
|
||
|
||
|
||
static int linesInRegion(EdStruct *xx, int pos, int width)
|
||
/*
|
||
** Return number of sequences on screen
|
||
*/
|
||
{
|
||
int i, count;
|
||
|
||
for (i=1,count=0 ;
|
||
i<=xx->DB_gelCount && DBgetRelPos(xx,xx->DBorder[i])<(pos+width) ;
|
||
i++) {
|
||
if (DBgetRelPos(xx,xx->DBorder[i])+DBgetLength(xx,xx->DBorder[i])>pos &&
|
||
DBgetLength(xx,xx->DBorder[i])) count++;
|
||
}
|
||
count += xx->consensusDisplayed;
|
||
|
||
return count;
|
||
|
||
}
|
||
|
||
|
||
static int linesOnScreen (EdStruct *xx, int pos, int width)
|
||
/*
|
||
** Return number of sequences on screen
|
||
*/
|
||
{
|
||
int i, count;
|
||
|
||
for (i=1,count=0 ; i<=xx->DB_gelCount ; i++) {
|
||
int relPos, length;
|
||
int len_lcut, len_rcut;
|
||
|
||
if (xx->reveal_cutoffs) {
|
||
len_lcut = lenLCut(xx,xx->DBorder[i]);
|
||
len_rcut = lenRCut(xx,xx->DBorder[i]);
|
||
} else
|
||
len_lcut = len_rcut = 0;
|
||
relPos = DBgetRelPos(xx,xx->DBorder[i]) - len_lcut;
|
||
length = DBgetLength(xx,xx->DBorder[i]) + len_lcut + len_rcut;
|
||
if (relPos < pos+width && relPos+length>pos)
|
||
count++;
|
||
}
|
||
count += xx->consensusDisplayed;
|
||
|
||
return count;
|
||
}
|
||
|
||
|
||
|
||
#ifdef notdef
|
||
static int maxLinesOnScreen_x (EdStruct *xx, int width)
|
||
/*
|
||
** Given width, return maximum number of lines on screen
|
||
*/
|
||
{
|
||
int i,max,linesAtX,X;
|
||
|
||
max = linesOnScreen(xx,1,width);
|
||
for (i=1 ; i <= xx->DB_gelCount ; i++) {
|
||
X=DBgetRelPos(xx,i)-width+1;
|
||
if (X<=1) continue;
|
||
linesAtX=linesOnScreen(xx,X,width);
|
||
if (linesAtX>max) max = linesAtX;
|
||
}
|
||
max += xx->consensusDisplayed;
|
||
|
||
return max;
|
||
}
|
||
#endif
|
||
|
||
int *sequencesInRegion(EdStruct *xx,int pos, int width)
|
||
/*
|
||
** Return a pointer to list of sequences in region of contig
|
||
*/
|
||
{
|
||
int i, count;
|
||
|
||
for (i=1,count=0 ; i<=xx->DB_gelCount && DBgetRelPos(xx,xx->DBorder[i])<(pos+width) ; i++) {
|
||
if (DBgetRelPos(xx,xx->DBorder[i])+DBgetLength(xx,xx->DBorder[i])>pos && DBgetLength(xx,xx->DBorder[i]))
|
||
xx->DBlist[count++]=xx->DBorder[i];
|
||
}
|
||
if (xx->consensusDisplayed) xx->DBlist[count++] = 0;
|
||
|
||
return xx->DBlist;
|
||
|
||
}
|
||
|
||
|
||
int *sequencesOnScreen(EdStruct *xx,int pos, int width)
|
||
/*
|
||
** Return a pointer to list of sequences on screen
|
||
*/
|
||
{
|
||
int i, count;
|
||
|
||
for (i=1,count=0 ; i<=xx->DB_gelCount ; i++) {
|
||
int relPos, length;
|
||
int len_lcut, len_rcut;
|
||
|
||
if (xx->reveal_cutoffs) {
|
||
len_lcut = lenLCut(xx,xx->DBorder[i]);
|
||
len_rcut = lenRCut(xx,xx->DBorder[i]);
|
||
} else
|
||
len_lcut = len_rcut = 0;
|
||
relPos = DBgetRelPos(xx,xx->DBorder[i]) - len_lcut;
|
||
length = DBgetLength(xx,xx->DBorder[i]) + len_lcut + len_rcut;
|
||
if (relPos < pos+width && relPos+length>pos)
|
||
xx->DBlist[count++]=xx->DBorder[i];
|
||
}
|
||
if (xx->consensusDisplayed) xx->DBlist[count++] = 0;
|
||
|
||
return xx->DBlist;
|
||
|
||
}
|
||
|
||
void DBgetSequence(EdStruct *xx, int seq, int pos, int width, char *str)
|
||
/*
|
||
** get part of a sequence from its `pos' base for `width' bases
|
||
** Bases number from 0?
|
||
*/
|
||
{
|
||
char *src;
|
||
int length = DBgetLength(xx,seq);
|
||
int i;
|
||
|
||
src = DBgetSeq(xx,seq);
|
||
|
||
/* Lefthand cut off */
|
||
if (pos<0) {
|
||
i = (width<-pos)?width:-pos;
|
||
getLCut(xx,seq, -pos, i, str);
|
||
} else
|
||
i=0;
|
||
|
||
/*copy sequence*/
|
||
for (;
|
||
i<width && (pos+i)<length;
|
||
i++) {
|
||
str[i]=src[pos+i];
|
||
}
|
||
|
||
/* Righthand cut off */
|
||
if (i<width) {
|
||
getRCut(xx,seq, pos+i-length, width-i, &str[i]);
|
||
}
|
||
|
||
str[width]='\0';
|
||
|
||
}
|
||
|
||
|
||
|
||
void DBcalcConsensus (EdStruct *xx,int pos, int width, char *str, int mode)
|
||
/*
|
||
** calculate the consensus for position `pos' in contig,
|
||
** for `width' characters
|
||
*/
|
||
{
|
||
/*
|
||
** When calculating the consensus,
|
||
** handle DNA differently from protein
|
||
** switch (xx->DB_flags & DB_DATA_TYPE) {
|
||
** case DB_DATA_TYPE_DNA: do dna stuff
|
||
** case DB_DATA_TYPE_PROTEIN: do protein stuff
|
||
** default : do dna stuff???
|
||
** }
|
||
** BASES = 6 for dna, 26 for protein (specified by fortran variable IDM?)
|
||
*/
|
||
int_f scores[MAX_DISPLAY_WIDTH][BASES];
|
||
int_f index,score;
|
||
int_f i,j,k;
|
||
int_f seven=BASES;
|
||
int jlow,klow,jhigh /* ,khigh */;
|
||
int chunk; /* do in chucks of MAX_DISPLAY_WIDTH */
|
||
int cwidth;
|
||
|
||
for (chunk=0; chunk<width; chunk+=MAX_DISPLAY_WIDTH) {
|
||
cwidth = width - chunk;
|
||
if (cwidth>MAX_DISPLAY_WIDTH) cwidth=MAX_DISPLAY_WIDTH;
|
||
/*now do for pos+chunk to pos+chunk+cwidth*/
|
||
|
||
for (i=0;i<MAX_DISPLAY_WIDTH;i++)
|
||
for (j=0;j<BASES;j++) scores[i][j] = 0;
|
||
|
||
for (i=1 ;
|
||
i<=xx->DB_gelCount &&
|
||
DBgetRelPos(xx,xx->DBorder[i])<(pos+chunk+cwidth) ;
|
||
i++)
|
||
{
|
||
if (DBgetRelPos(xx,xx->DBorder[i]) +
|
||
DBgetLength(xx,xx->DBorder[i]) > (pos+chunk) &&
|
||
DBgetLength(xx,xx->DBorder[i]) &&
|
||
(mode == BOTH_STRANDS ||
|
||
mode == DBgetComp(xx,xx->DBorder[i])))
|
||
{
|
||
if (DBgetRelPos(xx,xx->DBorder[i]) < (pos+chunk))
|
||
{
|
||
klow = (pos+chunk) - DBgetRelPos(xx,xx->DBorder[i]);
|
||
jlow = 0;
|
||
}
|
||
else
|
||
{
|
||
klow = 0;
|
||
jlow = DBgetRelPos(xx,xx->DBorder[i]) - (pos+chunk);
|
||
}
|
||
|
||
if (DBgetRelPos(xx,xx->DBorder[i]) +
|
||
DBgetLength(xx,xx->DBorder[i]) > pos+chunk+cwidth)
|
||
{
|
||
/*khigh = klow + cwidth;*/
|
||
jhigh = cwidth;
|
||
}
|
||
else
|
||
{
|
||
/*khigh = DBgetLength(xx,xx->DBorder[i]);*/
|
||
jhigh = jlow + DBgetLength(xx,xx->DBorder[i]) - klow;
|
||
}
|
||
|
||
{
|
||
char s[MAX_DISPLAY_WIDTH+1];
|
||
DBgetSequence(xx,xx->DBorder[i],klow,jhigh-jlow,s);
|
||
for (j=jlow,k=0; j<jhigh; j++,k++)
|
||
{
|
||
if (*saveState.idm == 26) {
|
||
pcon1_(&s[k],&scores[j][0]);
|
||
} else {
|
||
index = indexs_(&s[k],&score);
|
||
scores[j][index-1] += score;
|
||
/* No longer needed
|
||
scores[j][BASES-1] += score;
|
||
*/
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
for (i=0;i<cwidth;i++){
|
||
if (*saveState.idm == 26)
|
||
munotp_(&str[chunk+i],(int_fl)1,&scores[i][0]);
|
||
else
|
||
gtconc_(&str[chunk+i],(int_fl)1,&scores[i][0],&seven,&pcCut);
|
||
}
|
||
}
|
||
str[width]='\0';
|
||
|
||
}
|
||
|
||
|
||
|
||
int positionInContig(EdStruct *xx, int seq, int pos)
|
||
/*
|
||
** returns relative position in a sequence as an
|
||
** absolute position in the contig
|
||
*/
|
||
{
|
||
return DBgetRelPos(xx,seq) + pos - 1;
|
||
}
|
||
|
||
static int onScreen (EdStruct *xx, int seq, int pos)
|
||
/*
|
||
** returns true if base in `seq' at position `pos' is currently
|
||
** being displayed on screen
|
||
*/
|
||
{
|
||
int posInContig;
|
||
|
||
posInContig = positionInContig(xx,seq,pos);
|
||
return (posInContig >= xx->displayPos &&
|
||
posInContig < xx->displayPos + xx->displayWidth );
|
||
}
|
||
|
||
|
||
#ifdef notdef
|
||
static void getJoinedData(EdStruct *xx, int *leftPos, int* rightPos)
|
||
/*
|
||
** get information about relative positions of two joined contigs
|
||
*/
|
||
{
|
||
int offset = editorLockedPos(0/*don't force recalculation*/);
|
||
EdStruct *otherxx;
|
||
|
||
otherxx = intToEdStruct(0);
|
||
if (otherxx==xx) {
|
||
otherxx = intToEdStruct(1);
|
||
*leftPos = min(1,1-offset);
|
||
*rightPos = max(DBgetLength(xx,0),DBgetLength(otherxx,0)-offset);
|
||
} else {
|
||
*leftPos = min(1,1+offset);
|
||
*rightPos = max(DBgetLength(xx,0),DBgetLength(otherxx,0)+offset);
|
||
}
|
||
}
|
||
#endif /*notdef*/
|
||
|
||
#ifdef notdef
|
||
static int getJoinedLength(EdStruct *xx)
|
||
/*
|
||
** Get the combined length of the two joined contigs
|
||
*/
|
||
{
|
||
int leftPos, rightPos;
|
||
getJoinedData(xx,&leftPos,&rightPos);
|
||
return rightPos - leftPos;
|
||
}
|
||
|
||
static int getJoinedLeftPos(EdStruct *xx)
|
||
/*
|
||
** Get the position (relative to xx) of the leftmost base in
|
||
** the joined contig
|
||
*/
|
||
{
|
||
int leftPos, rightPos;
|
||
getJoinedData(xx,&leftPos,&rightPos);
|
||
return leftPos;
|
||
}
|
||
|
||
static int getJoinedRightPos(EdStruct *xx)
|
||
/*
|
||
** Get the position (relative to xx) of the rightmost base in
|
||
** the joined contig
|
||
*/
|
||
{
|
||
int leftPos, rightPos;
|
||
getJoinedData(xx,&leftPos,&rightPos);
|
||
return rightPos;
|
||
}
|
||
#endif
|
||
|
||
static void extents(EdStruct *xx, int *left, int *right)
|
||
/*
|
||
** Get maximum extents of sequence, taking into account cutoffs.
|
||
*/
|
||
{
|
||
|
||
if (xx->reveal_cutoffs) {
|
||
int eleft, eright;
|
||
int i;
|
||
|
||
eleft = eright = 0;
|
||
|
||
for (i=1; i<=xx->DB_gelCount ; i++) {
|
||
int thisleft,thisright;
|
||
|
||
thisleft = DBgetRelPos(xx,xx->DBorder[i]) - lenLCut(xx,xx->DBorder[i]);
|
||
thisright = DBgetRelPos(xx,xx->DBorder[i]) + DBgetLength(xx,xx->DBorder[i]) + lenRCut(xx,xx->DBorder[i]) - 1;
|
||
|
||
if (eleft > thisleft)
|
||
eleft = thisleft;
|
||
if (eright < thisright)
|
||
eright = thisright;
|
||
}
|
||
|
||
*left = eleft;
|
||
*right = eright;
|
||
|
||
} else {
|
||
*left = 1;
|
||
*right = DBgetLength(xx,0);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
static void joinedExtents(EdStruct *xx, int *leftPos, int* rightPos)
|
||
/*
|
||
** get information about relative positions of two joined contigs
|
||
*/
|
||
{
|
||
int offset = editorLockedPos(0/*don't force recalculation*/);
|
||
EdStruct *otherxx;
|
||
int left,right;
|
||
int otherleft,otherright;
|
||
|
||
otherxx = intToEdStruct(0);
|
||
extents(xx,&left,&right);
|
||
if (otherxx==xx) {
|
||
otherxx = intToEdStruct(1);
|
||
extents(otherxx,&otherleft,&otherright);
|
||
*leftPos = min(left,otherleft-offset);
|
||
*rightPos = max(right,otherright-offset);
|
||
} else {
|
||
extents(otherxx,&otherleft,&otherright);
|
||
*leftPos = min(left,otherleft+offset);
|
||
*rightPos = max(right,otherright+offset);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
static void getExtents(EdStruct *xx, int *left, int *right)
|
||
{
|
||
if (inJoinMode() && editorLocked())
|
||
joinedExtents(xx,left,right);
|
||
else {
|
||
extents(xx,left,right);
|
||
if (inJoinMode() && !editorLocked()) {
|
||
*right += xx->displayWidth - 2;
|
||
*left -= xx->displayWidth - 1;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
/***************************************************/
|
||
/**/
|
||
/**/
|
||
|
||
|
||
|
||
|
||
|
||
static void setSliderPos (EdStruct *xx, int pos)
|
||
/*
|
||
** set slider as a position in contig
|
||
*/
|
||
{
|
||
float percentSet;
|
||
float percentShown;
|
||
int left, right;
|
||
getExtents(xx,&left,&right);
|
||
percentSet = (float)(pos-left)/(float)(right-left+1+1-xx->displayWidth);
|
||
percentShown = (float)xx->displayWidth/(float)(right-left+1+1);
|
||
|
||
XawScrollbarSetThumb(xx->sliderWid,percentSet,percentShown);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
static void incDisplayPosP (EdStruct *xx, int distance)
|
||
/*
|
||
** Increase the leftmost base position on the screen by a symbolic amount
|
||
*/
|
||
{
|
||
int oldPos = xx->displayPos;
|
||
int left,right;
|
||
switch (distance) {
|
||
case D_screen : xx->displayPos += xx->displayWidth; break;
|
||
case D_halfScreen : xx->displayPos += xx->displayWidth/2; break;
|
||
case D_character : xx->displayPos += 1; break;
|
||
}
|
||
getExtents(xx,&left,&right);
|
||
if (xx->displayPos > right + 2 - xx->displayWidth)
|
||
xx->displayPos = right + 2 - xx->displayWidth;
|
||
if (oldPos!=xx->displayPos)
|
||
redisplaySequences (xx,xx->namesWid, xx->sequencesWid, xx->displayPos, xx->displayWidth);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
static void decDisplayPosP (EdStruct *xx, int distance)
|
||
/*
|
||
** Decrease the leftmost base position on the screen by a symbolic ammount
|
||
*/
|
||
{
|
||
int oldPos = xx->displayPos;
|
||
int left,right;
|
||
switch (distance) {
|
||
case D_screen : xx->displayPos -= xx->displayWidth; break;
|
||
case D_halfScreen : xx->displayPos -= xx->displayWidth/2; break;
|
||
case D_character : xx->displayPos -= 1; break;
|
||
}
|
||
getExtents(xx,&left,&right);
|
||
if (xx->displayPos < left)
|
||
xx->displayPos = left;
|
||
if (oldPos!=xx->displayPos)
|
||
redisplaySequences (xx,xx->namesWid, xx->sequencesWid, xx->displayPos, xx->displayWidth);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
static void setDisplayPosPercentP (EdStruct *xx, float percent)
|
||
/*
|
||
** Set the leftmost base position on the screen given a percentage
|
||
*/
|
||
{
|
||
int oldPos = xx->displayPos;
|
||
int left,right;
|
||
getExtents(xx,&left,&right);
|
||
xx->displayPos = (int)((float) (right-left+1+1-xx->displayWidth) * percent) + left;
|
||
if (oldPos!=xx->displayPos)
|
||
redisplaySequences (xx,xx->namesWid, xx->sequencesWid, xx->displayPos, xx->displayWidth);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
static void positionCursor(EdStruct *xx, Widget w, int seq, int pos)
|
||
/*
|
||
** position the cursor int sequence seq at position pos
|
||
** and indicate cursor if on screen
|
||
*/
|
||
{
|
||
if (onScreen(xx,seq,pos)) {
|
||
int screenRow,screenColumn;
|
||
int *seqList;
|
||
|
||
screenColumn = positionInContig(xx,seq,pos) - xx->displayPos;
|
||
seqList = sequencesOnScreen(xx,xx->displayPos, xx->displayWidth);
|
||
for(screenRow=0;
|
||
screenRow<xx->displayHeight && seqList[screenRow] != seq;
|
||
screenRow++);
|
||
XawSheetDisplayCursor(w,True);
|
||
XawSheetPositionCursor(w,screenColumn,screenRow+xx->rulerDisplayed);
|
||
} else
|
||
XawSheetDisplayCursor(w,False);
|
||
}
|
||
|
||
static void redisplayDisagreement()
|
||
/*
|
||
** Recalculate and redisplay all disagreements
|
||
*/
|
||
{
|
||
char spare[MAX_DISPLAY_WIDTH];
|
||
EdStruct *xx[2];
|
||
int i;
|
||
|
||
if (inJoinMode()) {
|
||
xx[0] = intToEdStruct(0);
|
||
xx[1] = intToEdStruct(1);
|
||
for (i=0;i<xx[0]->displayWidth;i++)
|
||
spare[i]=(xx[0]->displayedConsensus[i] ==
|
||
xx[1]->displayedConsensus[i])?' ':'!';
|
||
XawSheetPutText(disagreeWid,0,0,xx[0]->displayWidth,spare);
|
||
}
|
||
}
|
||
|
||
|
||
void redisplaySequences (EdStruct *xx, Widget namesWid, Widget sequencesWid,
|
||
int pos, int width)
|
||
/*
|
||
** Redisplay the whole sequence display
|
||
*/
|
||
{
|
||
Arg args[10];
|
||
int nargs;
|
||
int *seqList;
|
||
|
||
setSliderPos(xx,pos);
|
||
|
||
/*
|
||
** Set Up Text Window sizes
|
||
*/
|
||
xx->displayHeight = linesOnScreen(xx,pos,width);
|
||
seqList = sequencesOnScreen(xx,pos, width);
|
||
|
||
/*
|
||
** Update names list
|
||
*/
|
||
nargs = 0;
|
||
XtSetArg(args[nargs], XtNrows, xx->displayHeight+xx->rulerDisplayed); nargs++;
|
||
XtSetValues(namesWid, args, nargs);
|
||
{
|
||
int i;
|
||
XawSheetInk splodge[NAMELEN];
|
||
for (i=0 ; i < NAMELEN ; i++) splodge[i].sh = sh_inverse;
|
||
for (i=0 ; i < xx->displayHeight ; i++ ) {
|
||
if (DBgetFlags(xx,seqList[i]) & DB_FLAG_SELECTED)
|
||
XawSheetPutJazzyText(namesWid,0,(i+xx->rulerDisplayed),NAMELEN,DBgetName(xx,seqList[i]),splodge);
|
||
else
|
||
XawSheetPutText(namesWid,0,(i+xx->rulerDisplayed),NAMELEN,DBgetName(xx,seqList[i]));
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Update sequence list
|
||
*/
|
||
nargs = 0;
|
||
XtSetArg(args[nargs], XtNrows, xx->displayHeight+xx->rulerDisplayed); nargs++;
|
||
XtSetValues(sequencesWid, args, nargs);
|
||
{
|
||
int i;
|
||
char spare[MAX_DISPLAY_WIDTH];
|
||
if (xx->rulerDisplayed) {
|
||
char *k;
|
||
int j,lower,times;
|
||
lower = (pos - pos%10);
|
||
times = width/10 + 2;
|
||
for (j=0,k=spare;j<times;j++,k+=10,lower+=10) sprintf(k,"%10d",lower);
|
||
XawSheetPutText(sequencesWid,0,0,width,&spare[9+pos%10]);
|
||
}
|
||
|
||
DBcalcConsensus(xx,pos,width,xx->displayedConsensus,BOTH_STRANDS);
|
||
for (i=0 ; i < xx->displayHeight ; i++ ) {
|
||
char * ptr;
|
||
XawSheetInk splodge[MAX_DISPLAY_WIDTH];
|
||
|
||
if (seqList[i]==0){
|
||
ptr = xx->displayedConsensus;
|
||
}else{
|
||
DBgetSequence(xx,seqList[i],pos-DBgetRelPos(xx,seqList[i]),width,spare);
|
||
ptr = spare;
|
||
}
|
||
if (xx->showDifferences) {
|
||
int j;
|
||
for (j=0;j<width;j++) if (spare[j]==xx->displayedConsensus[j])
|
||
spare[j]='.';
|
||
}
|
||
getTagSplodge(xx,seqList[i],pos-DBgetRelPos(xx,seqList[i]),width,splodge);
|
||
XawSheetPutJazzyText(sequencesWid,0,(i+xx->rulerDisplayed),width,ptr,splodge);
|
||
}
|
||
|
||
}
|
||
|
||
positionCursor(xx,sequencesWid,xx->cursorSeq,xx->cursorPos);
|
||
redisplaySelection(xx);
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
static void dumpSequence(EdStruct *xx, int seq, int pos, int width, char *str)
|
||
/*
|
||
** get part of a sequence from its `pos' base for `width' bases
|
||
** Bases number from 0?
|
||
*/
|
||
{
|
||
char *src;
|
||
int length = DBgetLength(xx,seq);
|
||
int i,j;
|
||
|
||
src = DBgetSeq(xx,seq);
|
||
|
||
/* Lefthand cut off */
|
||
if (pos<0) {
|
||
i = (width<-pos)?width:-pos;
|
||
getLCut(xx,seq, -pos, i, str);
|
||
for(j=0;j<i;j++) if (isupper(str[j])) str[j] = tolower(str[j]);
|
||
} else
|
||
i=0;
|
||
|
||
/*copy sequence*/
|
||
for (;
|
||
i<width && (pos+i)<length;
|
||
i++) {
|
||
str[i]=src[pos+i];
|
||
}
|
||
|
||
/* Righthand cut off */
|
||
if (i<width) {
|
||
getRCut(xx,seq, pos+i-length, width-i, &str[i]);
|
||
for(j=i;j<width;j++) if (isupper(str[j])) str[j] = tolower(str[j]);
|
||
}
|
||
|
||
str[width]='\0';
|
||
|
||
}
|
||
|
||
void dumpLine(EdStruct *xx, FILE *fp, int pos, int width)
|
||
/*
|
||
** Print out a section
|
||
*/
|
||
{
|
||
int *seqList;
|
||
int i;
|
||
char spare[MAX_DISPLAY_WIDTH];
|
||
char consensus[MAX_DISPLAY_WIDTH];
|
||
int displayHeight;
|
||
|
||
displayHeight = linesOnScreen(xx,pos,width);
|
||
seqList = sequencesOnScreen(xx,pos, width);
|
||
|
||
|
||
if (xx->rulerDisplayed) {
|
||
char *k;
|
||
int j,lower,times;
|
||
lower = (pos - pos%10);
|
||
times = width/10 + 2;
|
||
for (j=0,k=spare;j<times;j++,k+=10,lower+=10) sprintf(k,"%10d",lower);
|
||
fprintf(fp,"%*.*s %*.*s\n",
|
||
NAMELEN,NAMELEN," ",
|
||
width,width,&spare[9+pos%10]);
|
||
}
|
||
DBcalcConsensus(xx,pos,width,consensus,BOTH_STRANDS);
|
||
|
||
for (i=0 ; i < displayHeight ; i++ ) {
|
||
char * ptr;
|
||
|
||
if (DBgetFlags(xx,seqList[i]) & DB_FLAG_SELECTED)
|
||
fprintf(fp,"%*.*s * ",NAMELEN,NAMELEN, DBgetName(xx,seqList[i]));
|
||
else
|
||
fprintf(fp,"%*.*s ",NAMELEN,NAMELEN, DBgetName(xx,seqList[i]));
|
||
|
||
if (seqList[i]==0){
|
||
ptr = consensus;
|
||
}else{
|
||
dumpSequence(xx,seqList[i],pos-DBgetRelPos(xx,seqList[i]),width,spare);
|
||
ptr = spare;
|
||
}
|
||
if (xx->showDifferences) {
|
||
int j;
|
||
for (j=0;j<width;j++) if (spare[j]==consensus[j])
|
||
spare[j]='.';
|
||
}
|
||
fprintf(fp,"%*.*s\n",width,width,ptr);
|
||
}
|
||
|
||
fprintf(fp,"\n");
|
||
|
||
}
|
||
|
||
|
||
void dumpRegion(EdStruct *xx, FILE *fp, int start, int end, int width)
|
||
{
|
||
for(;start<=end;start+=width)
|
||
dumpLine(xx, fp, start, (end-start+1<width)?end-start+1:width);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
void dumpContig(EdStruct *xx)
|
||
{
|
||
int left,right;
|
||
|
||
static int i = 0;
|
||
char fn[1024];
|
||
FILE *fp;
|
||
|
||
i++;
|
||
sprintf(fn,"dump.%d.%d",getpid(),i);
|
||
|
||
if ( (fp = fopen(fn,"w")) != NULL ) {
|
||
extents(xx, &left, &right);
|
||
bell();
|
||
dumpRegion(xx,fp,left,right,60);
|
||
bell();
|
||
fclose(fp);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
int createEdDisplay(EdStruct *xx, Widget namesWid, Widget sequencesWid, int seq, int pos)
|
||
/*
|
||
** Create the initial sequence display
|
||
*/
|
||
{
|
||
int i;
|
||
|
||
/*
|
||
** Initial position on screen
|
||
*/
|
||
xx->cursorSeq = 0;
|
||
xx->cursorPos = pos;
|
||
|
||
for (i=1; i<=xx->DB_gelCount; i++) {
|
||
if (DBgetNumber(xx,i) == seq) {
|
||
xx->cursorSeq = i;
|
||
xx->cursorPos = pos;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*
|
||
** Display.
|
||
** set xx->displayPos to force repositioning of cursor
|
||
*/
|
||
xx->displayPos = positionInContig(xx,xx->cursorSeq,xx->cursorPos) +
|
||
2*xx->displayWidth;
|
||
redisplayWithCursor(xx);
|
||
return 0;
|
||
}
|
||
|
||
|
||
void incDisplayPos (EdStruct *xx, int distance)
|
||
/*
|
||
** Increase the leftmost base position on the screen by a symbolic ammount
|
||
*/
|
||
{
|
||
if (editorLocked()) {
|
||
incDisplayPosP(intToEdStruct(0), distance);
|
||
incDisplayPosP(intToEdStruct(1), distance);
|
||
} else
|
||
incDisplayPosP(xx, distance);
|
||
|
||
redisplayDisagreement();
|
||
}
|
||
|
||
|
||
void decDisplayPos (EdStruct *xx, int distance)
|
||
/*
|
||
** Decrease the leftmost base position on the screen by a symbolic ammount
|
||
*/
|
||
{
|
||
if (editorLocked()) {
|
||
decDisplayPosP(intToEdStruct(0), distance);
|
||
decDisplayPosP(intToEdStruct(1), distance);
|
||
} else
|
||
decDisplayPosP(xx, distance);
|
||
|
||
redisplayDisagreement();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
void setDisplayPosPercent (EdStruct *xx, float percent)
|
||
/*
|
||
** Set the leftmost base position on the screen given a percentage
|
||
*/
|
||
{
|
||
if (editorLocked()) {
|
||
setDisplayPosPercentP(intToEdStruct(0),percent);
|
||
setDisplayPosPercentP(intToEdStruct(1),percent);
|
||
} else
|
||
setDisplayPosPercentP(xx,percent);
|
||
|
||
redisplayDisagreement();
|
||
}
|
||
|
||
void setDisplayPos(EdStruct *xx, int pos)
|
||
/*
|
||
** centralise pos on screen
|
||
*/
|
||
{
|
||
if (pos==1) pos = 2; /*if pos==1 no redraw is done. So force*/
|
||
|
||
if (editorLocked()) {
|
||
int offset = editorLockedPos(0/*don't force recalculation*/);
|
||
EdStruct *otherxx;
|
||
otherxx = intToEdStruct(0);
|
||
if (otherxx == xx) {
|
||
otherxx = intToEdStruct(1);
|
||
otherxx->displayPos = pos + offset;
|
||
} else {
|
||
otherxx->displayPos = pos - offset;
|
||
}
|
||
}
|
||
|
||
xx->displayPos = pos;
|
||
decDisplayPos(xx,D_halfScreen);
|
||
|
||
}
|
||
|
||
static void showCursor(EdStruct *xx, int seq, int pos)
|
||
/*
|
||
** ensure that the cursor is visible on the screen
|
||
*/
|
||
{
|
||
if (onScreen(xx,seq,pos))
|
||
positionCursor(xx,xx->sequencesWid,seq,pos);
|
||
else {
|
||
setDisplayPos(xx,positionInContig(xx,seq,pos));
|
||
/*
|
||
if (xx->displayPos > positionInContig(xx,seq,pos))
|
||
decDisplayPos(xx,D_halfScreen);
|
||
else
|
||
incDisplayPos(xx,D_halfScreen);
|
||
xx->displayPos = positionInContig(xx,seq,pos) - (xx->displayWidth/2);
|
||
if (xx->displayPos < 1) xx->displayPos = 1;
|
||
if (xx->displayPos > (DBgetLength(xx,0)+2 - xx->displayWidth))
|
||
xx->displayPos = (DBgetLength(xx,0)+2 - xx->displayWidth);
|
||
redisplaySequences (xx,xx->namesWid, xx->sequencesWid, xx->displayPos, xx->displayWidth);
|
||
*/
|
||
}
|
||
}
|
||
|
||
void redisplayWithCursor(EdStruct *xx)
|
||
/*
|
||
** Redisplay screen, ensuring cursor display
|
||
*/
|
||
{
|
||
if (onScreen(xx,xx->cursorSeq,xx->cursorPos)) {
|
||
redisplaySequences (xx,xx->namesWid, xx->sequencesWid, xx->displayPos, xx->displayWidth);
|
||
redisplayDisagreement();
|
||
} else
|
||
showCursor(xx,xx->cursorSeq,xx->cursorPos);
|
||
}
|
||
|
||
void caretRight (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
/*
|
||
** Move cursor right
|
||
*/
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
|
||
if (xx->cursorPos<=DBgetLength(xx,xx->cursorSeq)) {
|
||
xx->cursorPos++;
|
||
showCursor(xx,xx->cursorSeq, xx->cursorPos);
|
||
} else
|
||
bell();
|
||
|
||
}
|
||
|
||
|
||
void caretLeft (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
/*
|
||
** Move cursor left
|
||
*/
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
|
||
|
||
if (xx->cursorPos>1) {
|
||
xx->cursorPos--;
|
||
showCursor(xx,xx->cursorSeq, xx->cursorPos);
|
||
} else
|
||
bell();
|
||
|
||
}
|
||
|
||
void caretDown (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
/*
|
||
** Move cursor down,
|
||
** cycle if necessary
|
||
*/
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
|
||
int *seqList,seqCount;
|
||
int posInContig;
|
||
int i;
|
||
|
||
posInContig = positionInContig(xx,xx->cursorSeq,xx->cursorPos);
|
||
seqList = sequencesInRegion(xx,posInContig-1,2);
|
||
seqCount = linesInRegion(xx,posInContig-1,2);
|
||
for(i=0;
|
||
i<seqCount && seqList[i]!=xx->cursorSeq;
|
||
i++);
|
||
|
||
i++;
|
||
if (i == seqCount) i = 0;
|
||
|
||
xx->cursorSeq = seqList[i];
|
||
xx->cursorPos = posInContig - DBgetRelPos(xx,xx->cursorSeq) + 1;
|
||
if (xx->cursorPos<1)
|
||
xx->cursorPos = 1;
|
||
else
|
||
if (xx->cursorPos > DBgetLength(xx,xx->cursorSeq)+1)
|
||
xx->cursorPos = DBgetLength(xx,xx->cursorSeq)+1;
|
||
showCursor(xx,xx->cursorSeq, xx->cursorPos);
|
||
|
||
}
|
||
|
||
void caretUp (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
/*
|
||
** Move cursor up,
|
||
** cycle if necessary
|
||
*/
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
|
||
int *seqList,seqCount;
|
||
int posInContig;
|
||
int i;
|
||
|
||
posInContig = positionInContig(xx,xx->cursorSeq,xx->cursorPos);
|
||
seqList = sequencesInRegion(xx,posInContig-1,2);
|
||
seqCount = linesInRegion(xx,posInContig-1,2);
|
||
for(i=0;
|
||
i<seqCount && seqList[i]!=xx->cursorSeq;
|
||
i++);
|
||
|
||
if (i==0) i = seqCount;
|
||
i--;
|
||
|
||
xx->cursorSeq = seqList[i];
|
||
xx->cursorPos = posInContig - DBgetRelPos(xx,xx->cursorSeq) + 1;
|
||
if (xx->cursorPos<1)
|
||
xx->cursorPos = 1;
|
||
else
|
||
if (xx->cursorPos > DBgetLength(xx,xx->cursorSeq)+1)
|
||
xx->cursorPos = DBgetLength(xx,xx->cursorSeq)+1;
|
||
showCursor(xx,xx->cursorSeq, xx->cursorPos);
|
||
|
||
}
|
||
|
||
|
||
static void deleteBase (EdStruct *xx, int seq, int pos)
|
||
/*
|
||
** delete a single base in a sequence
|
||
** and update the screen if necessary
|
||
*/
|
||
{
|
||
if (seq && pos) {
|
||
int j;
|
||
char *s;
|
||
char deletedBase;
|
||
s=DBgetSeq(xx,seq);
|
||
deletedBase = s[pos-1];
|
||
for (j = pos; j < DBgetLength(xx,seq); j++)
|
||
s[j-1] = s[j];
|
||
DBsetLength(xx,seq,DBgetLength(xx,seq)-1);
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED|DB_FLAG_REL_MODIFIED);
|
||
tagDeleteBase(xx,seq,pos,&deletedBase);
|
||
selectDeleteBase(xx, seq, pos);
|
||
}
|
||
else if (seq) {
|
||
/*
|
||
** deletion at position 0 - shift left sequence
|
||
*/
|
||
int i,j;
|
||
|
||
if (DBgetRelPos(xx,seq)==1) {
|
||
for (i=1; i <= xx->DB_gelCount; i++) {
|
||
if (seq == xx->DBorder[i]) {
|
||
for (j=i;j>1;j--)
|
||
xx->DBorder[j] = xx->DBorder[j-1];
|
||
xx->DBorder[1] = seq;
|
||
} else
|
||
DBsetRelPos(xx,xx->DBorder[i],DBgetRelPos(xx,xx->DBorder[i])+1);
|
||
}
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_REL_MODIFIED);
|
||
|
||
} else {
|
||
DBsetRelPos(xx,seq,DBgetRelPos(xx,seq)-1);
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_REL_MODIFIED);
|
||
|
||
for (i=1; seq != xx->DBorder[i] && i <= xx->DB_gelCount; i++);
|
||
for (j=i; DBgetRelPos(xx,xx->DBorder[j-1]) > DBgetRelPos(xx,seq) ;j--)
|
||
xx->DBorder[j] = xx->DBorder[j-1];
|
||
xx->DBorder[j] = seq;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
void deleteKey (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
/*
|
||
** delete a character
|
||
*/
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
|
||
int i;
|
||
char ch;
|
||
|
||
if (!(xx->DB_flags & DB_ACCESS_UPDATE)) return;
|
||
if (! onScreen(xx, xx->cursorSeq, xx->cursorPos)) {
|
||
/*
|
||
** When cursor is currently displayed on the screen,
|
||
** give a warning tone, and recentre screen on cursor
|
||
*/
|
||
showCursor(xx,xx->cursorSeq, xx->cursorPos);
|
||
bell();
|
||
} else if (positionInContig(xx,xx->cursorSeq,xx->cursorPos)==1 && !xx->cursorSeq) {
|
||
bell();
|
||
} else if (xx->cursorSeq) {
|
||
if (editModeIsSuperman()) {
|
||
if (xx->cursorPos==1)
|
||
ch = ' ';
|
||
else {
|
||
char *s;
|
||
s = DBgetSeq(xx,xx->cursorSeq);
|
||
ch = s[xx->cursorPos-2];
|
||
}
|
||
|
||
recordEdit(&bucketStack,xx,undoDelete,xx->cursorSeq,xx->cursorPos-1,ch,0);
|
||
|
||
deleteBase (xx,xx->cursorSeq, xx->cursorPos-1);
|
||
|
||
calculateConsensusLength(xx);
|
||
|
||
if (xx->cursorPos>1) xx->cursorPos--;
|
||
redisplayWithCursor(xx);
|
||
|
||
} else bell();
|
||
} else {
|
||
char consensus[2];
|
||
DBcalcConsensus(xx,xx->cursorPos-1,1,consensus,BOTH_STRANDS);
|
||
if (*consensus != '*') {
|
||
/*
|
||
** Only allow deletion from consensus when it's an asterisk
|
||
*/
|
||
bell();
|
||
} else {
|
||
recordEdit(&bucketStack,xx,undoMark,0,xx->cursorPos,'\0',0);
|
||
for (i=1; i<=xx->DB_gelCount; i++) {
|
||
if (DBgetRelPos(xx,i) + DBgetLength(xx,i) <= xx->cursorPos) ;
|
||
else if (DBgetRelPos(xx,i) >= xx->cursorPos) {
|
||
recordEdit(&bucketStack,xx,undoDelete,i,0,' ',0);
|
||
deleteBase (xx,i, 0);
|
||
}
|
||
else {
|
||
char *s;
|
||
s=DBgetSeq(xx,i);
|
||
ch = s[xx->cursorPos-DBgetRelPos(xx,i)-1];
|
||
recordEdit(&bucketStack,xx,undoDelete,i,xx->cursorPos-DBgetRelPos(xx,i),ch,0);
|
||
deleteBase (xx,i, xx->cursorPos-DBgetRelPos(xx,i));
|
||
}
|
||
|
||
}
|
||
recordEdit(&bucketStack,xx,undoMark,0,0,'\0',0);
|
||
|
||
DBsetLength(xx,0,DBgetLength(xx,0)-1);
|
||
redisplaySequences (xx,xx->namesWid, xx->sequencesWid, xx->displayPos, xx->displayWidth);
|
||
redisplayDisagreement();
|
||
xx->cursorPos--;
|
||
redisplayWithCursor(xx);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
static void insertBase (EdStruct *xx, int seq, int pos, char base)
|
||
/*
|
||
** insert a single base in a sequence
|
||
** and update the screen if necessary
|
||
*/
|
||
{
|
||
if (seq && base!=' ') {
|
||
int j;
|
||
char *s;
|
||
int len = DBgetLength(xx,seq);
|
||
/* don't let user overrun maximum gel length */
|
||
if (len<(int)*saveState.maxgel) {
|
||
s=DBgetSeq(xx,seq);
|
||
for (j = len+1; j > pos; j--)
|
||
s[j-1] = s[j-2];
|
||
s[pos-1] = base;
|
||
DBsetLength(xx,seq,len+1);
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED|DB_FLAG_REL_MODIFIED);
|
||
tagInsertBase(xx,seq,pos,&base);
|
||
selectInsertBase(xx, seq, pos);
|
||
}
|
||
}
|
||
else if (seq) {
|
||
/*
|
||
** space inserted at start: shift sequence right
|
||
*/
|
||
int i,j;
|
||
|
||
if (DBgetRelPos(xx,seq)==1)
|
||
for (i=1; i<xx->DB_gelCount && DBgetRelPos(xx,xx->DBorder[i+1])==1;i++);
|
||
else
|
||
i=0;
|
||
if (i==1) {
|
||
for (i=2; i <= xx->DB_gelCount; i++) {
|
||
DBsetRelPos(xx,xx->DBorder[i],DBgetRelPos(xx,xx->DBorder[i])-1);
|
||
}
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_REL_MODIFIED);
|
||
|
||
} else {
|
||
DBsetRelPos(xx,seq,DBgetRelPos(xx,seq)+1);
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_REL_MODIFIED);
|
||
|
||
for (i=1; seq != xx->DBorder[i] && i <= xx->DB_gelCount; i++);
|
||
for (j=i; j < xx->DB_gelCount && DBgetRelPos(xx,xx->DBorder[j+1]) < DBgetRelPos(xx,seq) ; j++)
|
||
xx->DBorder[j] = xx->DBorder[j+1];
|
||
xx->DBorder[j] = seq;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
static void insertChar (EdStruct *xx,int seq, int pos, char key)
|
||
/*
|
||
** insert a character
|
||
*/
|
||
{
|
||
int i;
|
||
|
||
/* Insert the base to the right of the caret */
|
||
/* perform a check to see that sequences aren't too long */
|
||
if (seq) {
|
||
/* don't let user overrun maximum gel length */
|
||
if (editModeIsSuperman() &&
|
||
DBgetLength(xx,seq)<(int)*saveState.maxgel) {
|
||
|
||
recordEdit(&bucketStack,xx,undoInsert,seq,pos,key,0);
|
||
|
||
insertBase(xx, seq, pos, key);
|
||
|
||
calculateConsensusLength(xx);
|
||
|
||
if (key!=' ') xx->cursorPos = ++pos;
|
||
redisplayWithCursor(xx);
|
||
} else bell();
|
||
} else if (key == '*') {
|
||
/*
|
||
** Only allow insertion of asterisks from consensus
|
||
*/
|
||
recordEdit(&bucketStack,xx,undoMark,0,pos,'\0',0);
|
||
for (i=1; i<=xx->DB_gelCount; i++) {
|
||
int len = DBgetLength(xx,i);
|
||
int relPos = DBgetRelPos(xx,i);
|
||
if (relPos + len < pos ||
|
||
len>=(int)*saveState.maxgel) ;
|
||
else if (relPos > pos) {
|
||
recordEdit(&bucketStack,xx,undoInsert,i,0,key,0);
|
||
insertBase(xx, i,0,' ');
|
||
}
|
||
else if (len) {
|
||
recordEdit(&bucketStack,xx,undoInsert,i, pos-relPos+1,key,0);
|
||
insertBase(xx, i, pos-relPos+1, key);
|
||
}
|
||
}
|
||
recordEdit(&bucketStack,xx,undoMark,0,0,'\0',0);
|
||
|
||
DBsetLength(xx,0,DBgetLength(xx,0)+1);
|
||
|
||
xx->cursorPos = ++pos;
|
||
redisplayWithCursor(xx);
|
||
} else {
|
||
bell();
|
||
}
|
||
}
|
||
|
||
static void replaceBase (EdStruct *xx, int seq, int pos, char base)
|
||
/*
|
||
** replace a single base in a sequence
|
||
** and update the screen if necessary
|
||
*/
|
||
{
|
||
if (seq) {
|
||
char *s;
|
||
char deletedBase;
|
||
s=DBgetSeq(xx,seq);
|
||
deletedBase=s[pos-1];
|
||
s[pos-1] = base;
|
||
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED);
|
||
tagReplaceBase(xx,seq,pos,&deletedBase, &base);
|
||
}
|
||
|
||
}
|
||
|
||
static void replaceChar (EdStruct *xx, int seq, int pos, char key)
|
||
/*
|
||
** replace a character
|
||
*/
|
||
{
|
||
/* int i,j; */
|
||
char ch;
|
||
|
||
/*
|
||
** Don't allow replacing past end of sequence
|
||
*/
|
||
if (DBgetLength(xx,seq) < pos) {
|
||
bell();
|
||
return;
|
||
}
|
||
if (seq) {
|
||
char *s;
|
||
s=DBgetSeq(xx,seq);
|
||
|
||
ch = s[pos-1];
|
||
recordEdit(&bucketStack,xx,undoReplace,seq,pos,ch,0);
|
||
|
||
replaceBase(xx,seq, pos, key);
|
||
|
||
xx->cursorPos = ++pos;
|
||
redisplayWithCursor(xx);
|
||
|
||
} else {
|
||
bell();
|
||
/*
|
||
** Don't allow replacements on consensus at ANY stage
|
||
**
|
||
** recordEdit(&bucketStack,xx,undoMark,0,pos,'\0',0);
|
||
** for (i=1; i<=xx->DB_gelCount; i++) {
|
||
** if (DBgetRelPos(xx,i) + DBgetLength(xx,i) <= pos) ;
|
||
** else if (DBgetRelPos(xx,i) > pos) ;
|
||
** else if (DBgetLength(xx,i)) {
|
||
** char *s;
|
||
** s=DBgetSeq(xx,i);
|
||
** ch = s[pos-DBgetRelPos(xx,i)];
|
||
** recordEdit(&bucketStack,xx,undoReplace,i,pos-DBgetRelPos(xx,i)+1,ch,0);
|
||
** replaceBase(xx,i, pos-DBgetRelPos(xx,i)+1, key);
|
||
** }
|
||
** }
|
||
** recordEdit(&bucketStack,xx,undoMark,0,0,'\0',0);
|
||
**
|
||
**
|
||
** xx->cursorPos = ++pos;
|
||
** redisplayWithCursor(xx);
|
||
*/
|
||
}
|
||
}
|
||
|
||
static int validKey(char key)
|
||
{
|
||
static char validKeys[] = "CcTtAaGg1234DVBHKLMNRY5678-*";
|
||
if (*saveState.idm == 26)
|
||
return (key!=' ');
|
||
else
|
||
return (strchr(validKeys,key) != NULL);
|
||
}
|
||
|
||
void keyPress (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
/*
|
||
** Handle a key press
|
||
*/
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
|
||
char keys[8];
|
||
char key;
|
||
KeySym keySym;
|
||
int charCount;
|
||
XComposeStatus compose;
|
||
/*
|
||
** validkeys is different when database is for DNA and when
|
||
** database is for protein
|
||
**
|
||
** switch (xx->DB_flags & DB_DATA_TYPE) {
|
||
** case DB_DATA_TYPE_DNA: do dna stuff
|
||
** case DB_DATA_TYPE_PROTEIN: do protein stuff
|
||
** default : do dna stuff???
|
||
** }
|
||
** BASES = 6 for dna, 26 for protein (specified by fortran variable IDM?)
|
||
static char validKeys[] = "CcTtAaGg1234DVBHKLMNRY5678-*";
|
||
*/
|
||
|
||
if (!(xx->DB_flags & DB_ACCESS_UPDATE)) return;
|
||
|
||
charCount = XLookupString((XKeyEvent *)event, keys,
|
||
(int)sizeof(keys), &keySym,&compose);
|
||
key = keys[0];
|
||
if (charCount==1) {
|
||
if (! onScreen(xx, xx->cursorSeq, xx->cursorPos)) {
|
||
/*
|
||
** When cursor is currently displayed on the screen,
|
||
** give a warning tone, and recentre screen on cursor
|
||
*/
|
||
showCursor(xx,xx->cursorSeq, xx->cursorPos);
|
||
bell();
|
||
} else if (validKey(key)) {
|
||
if (editModeIsInsert())
|
||
insertChar (xx,xx->cursorSeq, xx->cursorPos, key);
|
||
else
|
||
replaceChar (xx,xx->cursorSeq, xx->cursorPos, key);
|
||
}
|
||
else {
|
||
if (xx->cursorSeq && xx->cursorPos==1 && key == ' ' && editModeIsInsert())
|
||
insertChar (xx,xx->cursorSeq, xx->cursorPos, key);
|
||
else bell();
|
||
}
|
||
}
|
||
}
|
||
|
||
void buttonDown (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
/*
|
||
** An attempt has been made to reposition the cursor
|
||
*/
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
#define left_margin 4
|
||
#define top_margin 4
|
||
|
||
int x,y;
|
||
int *seqList;
|
||
|
||
if (editorState == StateDown) return;
|
||
|
||
if (widget != xx->sequencesWid) return;
|
||
|
||
x = (event->xbutton.x-left_margin) / xx->fontWidth;
|
||
y = (event->xbutton.y-top_margin) / xx->fontHeight - xx->rulerDisplayed;
|
||
|
||
|
||
if (y>=0 && y < xx->displayHeight && x>=0 && x < xx->displayWidth) {
|
||
seqList = sequencesOnScreen(xx,xx->displayPos,xx->displayWidth);
|
||
xx->cursorSeq = seqList[y];
|
||
xx->cursorPos = xx->displayPos - DBgetRelPos(xx,xx->cursorSeq) + x + 1;
|
||
if (xx->cursorPos<1)
|
||
xx->cursorPos = 1;
|
||
else
|
||
if (xx->cursorPos > DBgetLength(xx,xx->cursorSeq)+1)
|
||
xx->cursorPos = DBgetLength(xx,xx->cursorSeq)+1;
|
||
positionCursor(xx,widget,xx->cursorSeq,xx->cursorPos);
|
||
}
|
||
|
||
}
|
||
|
||
static void undoLastEdit (EdStruct *xx, int command, int seq, int pos, char ch, int t)
|
||
/*
|
||
** Undo a command
|
||
*/
|
||
{
|
||
switch (command) {
|
||
case undoDelete:
|
||
insertBase(xx, seq,pos,ch);
|
||
break;
|
||
case undoInsert:
|
||
deleteBase(xx,seq,(ch==' ')?0:pos);
|
||
break;
|
||
case undoReplace:
|
||
replaceBase(xx,seq,pos,ch);
|
||
break;
|
||
case undoExtend:
|
||
unextend(xx,seq,ch);
|
||
break;
|
||
case undoUnextend:
|
||
undo_unextend(xx,seq,ch,t);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void undoLastCommand()
|
||
/*
|
||
** Undo last keypress that modified contig
|
||
*/
|
||
{
|
||
EdStruct *xx;
|
||
int command;
|
||
int seq;
|
||
int pos;
|
||
char ch;
|
||
int t;
|
||
|
||
retrieveEdit(&bucketStack,&xx,&command,&seq,&pos,&ch,&t);
|
||
if (command == undoNullCommand) {
|
||
bell();
|
||
return;
|
||
}
|
||
else if (command == undoMark) {
|
||
|
||
retrieveEdit(&bucketStack,&xx,&command,&seq,&pos,&ch,&t);
|
||
while (command != undoMark) {
|
||
undoLastEdit(xx,command,seq,pos,ch,t);
|
||
retrieveEdit(&bucketStack,&xx,&command,&seq,&pos,&ch,&t);
|
||
}
|
||
|
||
xx->cursorSeq = 0;
|
||
xx->cursorPos = pos;
|
||
|
||
} else {
|
||
|
||
undoLastEdit(xx,command,seq,pos,ch,t);
|
||
|
||
xx->cursorSeq = seq;
|
||
xx->cursorPos = pos+(command==undoDelete);
|
||
|
||
}
|
||
|
||
calculateConsensusLength(xx);
|
||
redisplayWithCursor(xx);
|
||
}
|
||
|
||
static int showTrace(EdStruct *xx, int seq, int pos, int baseSpacing)
|
||
{
|
||
|
||
char fileName[200];
|
||
tagStruct *t;
|
||
/*
|
||
int traceNo;
|
||
*/
|
||
int t_len; /* number of bases in trace */
|
||
int t_lcut; /* left cut off of usable data */
|
||
int t_ulen; /* length of usable data */
|
||
char t_type[5]; /* type of trace */
|
||
char t_fname[FILE_NAME_LENGTH+1]; /* file name of trace */
|
||
char *rawData;
|
||
int baseNum;
|
||
|
||
t = (tagStruct *) DBgetTags(xx,seq);
|
||
|
||
force_comment(t);
|
||
|
||
if (! t->newcommentlen) return 1;
|
||
sscanf(t->newcomment,"%6d%6d%6d%*s",&t_len,&t_lcut,&t_ulen);
|
||
strncpy(t_type,&t->newcomment[18],4);
|
||
strncpy(t_fname,&t->newcomment[22],FILE_NAME_LENGTH);
|
||
|
||
t_type[4] = '\0';
|
||
{ /* convert fortran string to c string */
|
||
int i;
|
||
for (i=FILE_NAME_LENGTH-1;i>=0 && (!t_fname[i] || isspace(t_fname[i]));i--) ;
|
||
t_fname[++i] = '\0';
|
||
}
|
||
|
||
/* skip if no raw data file for trace */
|
||
if (t_fname[0] == '\0') return 1;
|
||
|
||
/* check trace file exists */
|
||
if ( ! file_exists(t_fname) ) {
|
||
char *s;
|
||
/* try in rawData */
|
||
/*
|
||
** get environment details
|
||
*/
|
||
rawData = (char *)getenv ("RAWDATA");
|
||
if (rawData == NULL) return 1;
|
||
/*
|
||
sprintf (fileName,"%s/%s",rawData,t_fname);
|
||
*/
|
||
if ((s=findfile(t_fname,rawData))==NULL) return 1;
|
||
strcpy (fileName,s);
|
||
} else
|
||
/* ok */
|
||
strcpy (fileName,t_fname);
|
||
|
||
if (DBgetComp(xx,seq) == UNCOMPLEMENTED) {
|
||
baseNum = origpos(xx, seq, pos) + t_lcut;
|
||
manageTrace(t_type, fileName, baseNum, t_lcut, t_ulen, /*not complemented*/0, baseSpacing, DBgetName(xx,seq));
|
||
} else {
|
||
baseNum = t_len - t_lcut - origpos(xx, seq, normalisePos(xx,seq,pos,1));
|
||
manageTrace(t_type, fileName, baseNum, t_lcut, t_ulen, /*complemented*/1, baseSpacing, DBgetName(xx,seq));
|
||
}
|
||
|
||
|
||
return 0;
|
||
}
|
||
|
||
void invokeTrace (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
int baseSpacing = xx->fontWidth * 2;
|
||
|
||
if (xx->cursorSeq) {
|
||
showTrace(
|
||
xx,
|
||
xx->cursorSeq,
|
||
xx->cursorPos,
|
||
baseSpacing);
|
||
} else {
|
||
int *seqList;
|
||
int i;
|
||
seqList = sequencesOnScreen(xx,xx->cursorPos,1);
|
||
for (i=0; i<xx->displayHeight && seqList[i]; i++)
|
||
showTrace(
|
||
xx,
|
||
seqList[i],
|
||
xx->cursorPos-DBgetRelPos(xx,seqList[i])+1,
|
||
baseSpacing);
|
||
|
||
}
|
||
}
|
||
|
||
void countDisagreements(int *overlapLength, int *wingeCount)
|
||
{
|
||
int left0,right0;
|
||
int left1/*,right1*/;
|
||
int length0,length1;
|
||
int offset = editorLockedPos(1/*force recalculation*/);
|
||
int i;
|
||
EdStruct *xx[2];
|
||
char *ol0,*ol1;
|
||
|
||
xx[0] = intToEdStruct(0);
|
||
xx[1] = intToEdStruct(1);
|
||
|
||
if (offset < 0) {
|
||
left0 = 1-offset;
|
||
left1 = 1;
|
||
} else {
|
||
left0 = 1;
|
||
left1 = 1+offset;
|
||
}
|
||
length0 = DBgetLength(xx[0],0);
|
||
length1 = DBgetLength(xx[1],0);
|
||
if (offset+length0 < length1) {
|
||
right0 = length0;
|
||
/*
|
||
right1 = length0-offset;
|
||
*/
|
||
} else {
|
||
right0 = length1-offset;
|
||
/*
|
||
right1 = length1;
|
||
*/
|
||
}
|
||
*overlapLength = right0 - left0+1;
|
||
*wingeCount = 0;
|
||
|
||
if (*overlapLength > 0) {
|
||
ol0 = (char *) malloc(*overlapLength+1);
|
||
ol1 = (char *) malloc(*overlapLength+1);
|
||
DBcalcConsensus(xx[0],left0,*overlapLength,ol0,BOTH_STRANDS);
|
||
DBcalcConsensus(xx[1],left1,*overlapLength,ol1,BOTH_STRANDS);
|
||
for (i=0;i<*overlapLength;i++) if(ol0[i]!=ol1[i])(*wingeCount)++;
|
||
free(ol0);
|
||
free(ol1);
|
||
}
|
||
}
|
||
|
||
|
||
void selectRead (Widget widget, XEvent *event, String *params,
|
||
Cardinal *num_params)
|
||
/*
|
||
** A gel reading name has been selected - toggle highlighting
|
||
*/
|
||
{
|
||
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
#define left_margin 4
|
||
#define top_margin 4
|
||
|
||
int y;
|
||
int *seqList;
|
||
|
||
if (editorState == StateDown) return;
|
||
|
||
if (widget != xx->namesWid) return;
|
||
|
||
y = (event->xbutton.y-top_margin) / xx->fontHeight - xx->rulerDisplayed;
|
||
|
||
if (y>=0 && y < xx->displayHeight) {
|
||
int flag;
|
||
seqList = sequencesOnScreen(xx,xx->displayPos,xx->displayWidth);
|
||
flag = DBgetFlags(xx,seqList[y]);
|
||
flag ^= DB_FLAG_SELECTED;
|
||
DBsetFlags(xx,seqList[y],flag);
|
||
redisplaySequences (xx,xx->namesWid, xx->sequencesWid, xx->displayPos, xx->displayWidth);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
/*************************************************************
|
||
**
|
||
** Fast accessing routines... utilising binary search
|
||
**
|
||
*************************************************************/
|
||
|
||
int posToIndex(EdStruct *xx, int pos)
|
||
/*
|
||
** Find the first sequence that starts at or to the right of a
|
||
** given position
|
||
*/
|
||
{
|
||
int Min, Max, Mid;
|
||
|
||
/* binary search */
|
||
/* Min, Max, Mid refer to pairs of numbers: ie MAX --> [MAX-1],[MAX] */
|
||
Min = 1;
|
||
Max = xx->DB_gelCount + 1;
|
||
|
||
do {
|
||
int r1,r2;
|
||
|
||
Mid = (Max+Min)/2;
|
||
|
||
/* compare */
|
||
r1 = (Mid==1)?(pos-1):DBgetRelPos(xx,xx->DBorder[Mid-1]);
|
||
r2 = (Mid==xx->DB_gelCount+1)?(pos+1):DBgetRelPos(xx,xx->DBorder[Mid]);
|
||
|
||
if (r1 < pos && r2 >= pos)
|
||
return (Mid==xx->DB_gelCount+1)?(0):Mid;
|
||
|
||
if (r1 < pos)
|
||
Min = Mid+1;
|
||
else
|
||
Max = Mid-1;
|
||
|
||
} while (Max>=Min);
|
||
|
||
return 0;
|
||
|
||
}
|
||
|
||
|
||
int posToSeq(EdStruct *xx, int pos)
|
||
/*
|
||
** Find the first sequence that starts at or to the right of a
|
||
** given position
|
||
*/
|
||
{
|
||
int ind;
|
||
|
||
ind = posToIndex(xx,pos);
|
||
if (ind)
|
||
return xx->DBorder[ind];
|
||
else
|
||
return 0;
|
||
|
||
}
|
||
|
||
|
||
int seqToIndex(EdStruct *xx, int seq)
|
||
/*
|
||
**
|
||
*/
|
||
{
|
||
int i;
|
||
int ind;
|
||
|
||
ind = posToIndex(xx,DBgetRelPos(xx,seq));
|
||
|
||
if (ind) {
|
||
for (i=ind; i<=xx->DB_gelCount && xx->DBorder[i]!=seq;i++) ;
|
||
|
||
if (i<=xx->DB_gelCount) return i;
|
||
}
|
||
|
||
return 0;
|
||
|
||
}
|
||
|
||
|
||
|
||
|