723 lines
17 KiB
C
723 lines
17 KiB
C
|
/*
|
||
|
** Change log:
|
||
|
**
|
||
|
** 1/10/91 SD Added calculateConsensusLength to extend, unextend, undo_unextend
|
||
|
** 29/4/92 SD Changes related to general speed up in edUtils.c
|
||
|
** 18/5/92 SD Construct (*nc=*++nc) not liked by dec
|
||
|
*/
|
||
|
|
||
|
#include "edUtils.h"
|
||
|
#include "fortran.h"
|
||
|
#include "tagUtils.h"
|
||
|
#include "contigEditor.h"
|
||
|
#include "undo.h"
|
||
|
#include "select.h"
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#define LEFT 1
|
||
|
#define RIGHT 2
|
||
|
|
||
|
|
||
|
tagStruct *force_get_tag(EdStruct *xx, int seq, char *type)
|
||
|
/*
|
||
|
** find a control tag of a particular type
|
||
|
** Create one if one doesn't exist
|
||
|
*/
|
||
|
{
|
||
|
tagStruct *t;
|
||
|
|
||
|
t = (tagStruct *)findTagByType(xx,seq,type);
|
||
|
|
||
|
if (t == NULL) {
|
||
|
/*
|
||
|
** create one
|
||
|
*/
|
||
|
t = newTag();
|
||
|
strncpy(t->tagrec.type.c,type,4);
|
||
|
t->flags = TAG_INSERTED;
|
||
|
insertTag(xx,seq,t);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Force comment to be in memory
|
||
|
*/
|
||
|
force_comment(t);
|
||
|
|
||
|
return t;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
int extend(EdStruct *xx, int seq, int dir, int time)
|
||
|
{
|
||
|
int c = (DBgetComp(xx,seq)==COMPLEMENTED);
|
||
|
char t_type[4];
|
||
|
tagStruct *t;
|
||
|
int use_tag;
|
||
|
char extend_char;
|
||
|
int l;
|
||
|
|
||
|
if (DBgetLength(xx,seq) >= (int)*saveState.maxgel) return 1;
|
||
|
|
||
|
use_tag = (c && dir==LEFT || !c && dir==RIGHT )?RIGHT: LEFT;
|
||
|
strncpy(t_type,
|
||
|
(use_tag==RIGHT )?TAG_TYPE_RCUT:TAG_TYPE_LCUT,4);
|
||
|
|
||
|
/*
|
||
|
** Find appropriate tag,
|
||
|
** create one if one doesn't exist
|
||
|
*/
|
||
|
t = force_get_tag(xx,seq,t_type);
|
||
|
|
||
|
/*
|
||
|
** No cutoff - ignore request
|
||
|
*/
|
||
|
l = t->newcommentlen;
|
||
|
if (! l)
|
||
|
return 1;
|
||
|
|
||
|
/*
|
||
|
** Determine character to extend
|
||
|
*/
|
||
|
if (use_tag==LEFT) {
|
||
|
/* Get character off end of cutoff */
|
||
|
extend_char = t->newcomment[l-1];
|
||
|
t->newcomment[l-1]='\0';
|
||
|
t->newcommentlen--;
|
||
|
} else {
|
||
|
/* Get character off start of cutoff */
|
||
|
int i;
|
||
|
extend_char = t->newcomment[0];
|
||
|
for (i=0;t->newcomment[i];i++)
|
||
|
t->newcomment[i] = t->newcomment[i+1];
|
||
|
t->newcommentlen--;
|
||
|
}
|
||
|
t->flags |= TAG_COMMENT_CHANGED;
|
||
|
|
||
|
/*
|
||
|
** complement if necessary
|
||
|
*/
|
||
|
if (use_tag != dir) {
|
||
|
int_f i=1;
|
||
|
sqcom_(&extend_char,&i,(int_f)1);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (dir==LEFT){
|
||
|
int i,j;
|
||
|
char *s;
|
||
|
|
||
|
/*
|
||
|
** insert base at start of sequence
|
||
|
*/
|
||
|
s=DBgetSeq(xx,seq);
|
||
|
for (j = DBgetLength(xx,seq)+1; j > 1; j--)
|
||
|
s[j-1] = s[j-2];
|
||
|
s[0] = extend_char;
|
||
|
DBsetLength(xx,seq,DBgetLength(xx,seq)+1);
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED|DB_FLAG_REL_MODIFIED);
|
||
|
selectInsertBase(xx,seq,1);
|
||
|
|
||
|
/*
|
||
|
** shift sequence left
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
/*
|
||
|
** insert base at end of sequence
|
||
|
*/
|
||
|
char *s;
|
||
|
int l=DBgetLength(xx,seq);
|
||
|
s=DBgetSeq(xx,seq);
|
||
|
s[l] = extend_char;
|
||
|
DBsetLength(xx,seq,l+1);
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED|DB_FLAG_REL_MODIFIED);
|
||
|
selectInsertBase(xx,seq,l+1);
|
||
|
}
|
||
|
|
||
|
if (use_tag == LEFT) {
|
||
|
/*
|
||
|
** shift position of all tags right 1
|
||
|
*/
|
||
|
tagStruct *t;
|
||
|
t = (tagStruct *) DBgetTags(xx,seq);
|
||
|
while (t != NULL) {
|
||
|
if (!(t->flags & TAG_DELETED) &&
|
||
|
t->tagrec.position) {
|
||
|
t->tagrec.position++;
|
||
|
t->flags |= TAG_POSITION_CHANGED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
}
|
||
|
t = t->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Modify raw data stuff
|
||
|
*/
|
||
|
{
|
||
|
tagStruct *t;
|
||
|
char type[5];
|
||
|
char name[FILE_NAME_LENGTH+1];
|
||
|
int llen,lcut,wlen;
|
||
|
t = (tagStruct *) DBgetTags(xx,seq);
|
||
|
force_comment(t);
|
||
|
sscanf(t->newcomment,"%6d%6d%6d%*s",&llen,&lcut,&wlen);
|
||
|
strncpy(type,&t->newcomment[18],4);
|
||
|
strncpy(name,&t->newcomment[22],FILE_NAME_LENGTH);
|
||
|
wlen++;
|
||
|
if (use_tag==LEFT) lcut--;
|
||
|
sprintf(t->newcomment,"%6d%6d%6d",llen,lcut,wlen);
|
||
|
strncat(t->newcomment,type,4);
|
||
|
strncat(t->newcomment,name,FILE_NAME_LENGTH);
|
||
|
t->newcommentlen = (int)strlen(t->newcomment);
|
||
|
t->flags |= TAG_COMMENT_CHANGED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (dir == RIGHT) xx->cursorPos++;
|
||
|
|
||
|
/*
|
||
|
** Lengths are a changing
|
||
|
*/
|
||
|
calculateConsensusLength(xx);
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
int unextend(EdStruct *xx, int seq, int dir, int time)
|
||
|
{
|
||
|
|
||
|
int c = (DBgetComp(xx,seq)==COMPLEMENTED);
|
||
|
char t_type[4];
|
||
|
tagStruct *t;
|
||
|
int use_tag;
|
||
|
char extend_char[2];
|
||
|
char external_buff[100];
|
||
|
char internal_buff[100];
|
||
|
char *ec = extend_char;
|
||
|
char *eb = external_buff;
|
||
|
char *ib = internal_buff;
|
||
|
int l;
|
||
|
int end_char_inserted = 0;
|
||
|
|
||
|
use_tag = (c && dir==LEFT || !c && dir==RIGHT )?RIGHT: LEFT;
|
||
|
strncpy(t_type,
|
||
|
(use_tag==RIGHT )?TAG_TYPE_RCUT:TAG_TYPE_LCUT,4);
|
||
|
|
||
|
/*
|
||
|
** Find appropriate tag,
|
||
|
** create one if one doesn't exist
|
||
|
*/
|
||
|
t = force_get_tag(xx,seq,t_type);
|
||
|
|
||
|
/*
|
||
|
** Process tag information
|
||
|
** collating *DE? flags and *INS flags
|
||
|
** and adjusting other flags accordingly
|
||
|
*/
|
||
|
{
|
||
|
tagStruct *t;
|
||
|
int ipos;
|
||
|
|
||
|
t = (tagStruct *) DBgetTags(xx,seq);
|
||
|
ipos = normalisePos(xx,seq,(dir==LEFT)?1:DBgetLength(xx,seq),1);
|
||
|
|
||
|
while (t != NULL) {
|
||
|
if (!(t->flags & TAG_DELETED) &&
|
||
|
t->tagrec.position == ipos &&
|
||
|
strncmp(t->tagrec.type.c,TAG_TYPE_INSERT,3)==0) {
|
||
|
/*
|
||
|
** Handle unextending past inserts
|
||
|
*/
|
||
|
end_char_inserted++;
|
||
|
t->flags |= TAG_DELETED;
|
||
|
t->time = time;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
}else if (!(t->flags & TAG_DELETED) &&
|
||
|
strncmp(t->tagrec.type.c, TAG_TYPE_DELETE,3)==0) {
|
||
|
/*
|
||
|
** Handle unextending past deletes
|
||
|
*/
|
||
|
if (use_tag==LEFT && t->tagrec.position == ipos ||
|
||
|
use_tag==RIGHT && t->tagrec.position == (ipos+1)) {
|
||
|
*eb++ = t->tagrec.type.c[3];
|
||
|
t->time = time;
|
||
|
t->flags |= TAG_DELETED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
} else if (use_tag==RIGHT && t->tagrec.position == ipos) {
|
||
|
*ib++ = t->tagrec.type.c[3];
|
||
|
t->time = time;
|
||
|
t->flags |= TAG_DELETED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
} else if (use_tag == LEFT) {
|
||
|
t->tagrec.position--;
|
||
|
t->flags |= TAG_POSITION_CHANGED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
}
|
||
|
} else if (!(t->flags & TAG_DELETED) &&
|
||
|
t->tagrec.position <= ipos &&
|
||
|
t->tagrec.position + t->tagrec.length > ipos){
|
||
|
/*
|
||
|
** Handle unextending past other tags
|
||
|
*/
|
||
|
t->tagrec.length--;
|
||
|
t->flags |= TAG_LENGTH_CHANGED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
} else if (!(t->flags & TAG_DELETED) &&
|
||
|
use_tag==LEFT && t->tagrec.position) {
|
||
|
/*
|
||
|
** Handle all other positional adjustments
|
||
|
*/
|
||
|
t->tagrec.position--;
|
||
|
t->flags |= TAG_POSITION_CHANGED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
}
|
||
|
t = t->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (dir==LEFT){
|
||
|
int i,j;
|
||
|
char *s;
|
||
|
int l=DBgetLength(xx,seq);
|
||
|
|
||
|
/*
|
||
|
** get base at start of sequence
|
||
|
*/
|
||
|
s=DBgetSeq(xx,seq);
|
||
|
*ec++ = s[0];
|
||
|
for (j = 2; j <= l; j++)
|
||
|
s[j-2] = s[j-1];
|
||
|
DBsetLength(xx,seq,l-1);
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED|DB_FLAG_REL_MODIFIED);
|
||
|
selectDeleteBase(xx,seq,1);
|
||
|
|
||
|
/*
|
||
|
** shift sequence right
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
} else {
|
||
|
/*
|
||
|
** get base at end of sequence
|
||
|
*/
|
||
|
char *s;
|
||
|
int l=DBgetLength(xx,seq);
|
||
|
s=DBgetSeq(xx,seq);
|
||
|
*ec++ = s[l-1];
|
||
|
DBsetLength(xx,seq,l-1);
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED|DB_FLAG_REL_MODIFIED);
|
||
|
selectDeleteBase(xx,seq,l);
|
||
|
}
|
||
|
|
||
|
*eb='\0';
|
||
|
*ib='\0';
|
||
|
*ec='\0';
|
||
|
|
||
|
if (end_char_inserted) {
|
||
|
/*
|
||
|
** Throw it away
|
||
|
*/
|
||
|
*extend_char = '\0';
|
||
|
} else {
|
||
|
/*
|
||
|
** complement if necessary
|
||
|
*/
|
||
|
if (use_tag != dir) {
|
||
|
int_f i=1;
|
||
|
sqcom_(extend_char,&i,(int_fl)1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Insert unextend character on end of appropriate tag
|
||
|
*/
|
||
|
l = (int)(strlen(extend_char) + strlen(external_buff) +
|
||
|
strlen(internal_buff));
|
||
|
if (l) {
|
||
|
char *newercomment;
|
||
|
newercomment = (char *) TAG_MALLOC( t->newcommentlen + l + 1);
|
||
|
if (use_tag==LEFT) {
|
||
|
/* add buffers to end of cutoff */
|
||
|
strcpy(newercomment,t->newcomment);
|
||
|
strcat(newercomment,external_buff);
|
||
|
strcat(newercomment,extend_char);
|
||
|
strcat(newercomment,internal_buff);
|
||
|
} else {
|
||
|
/* add buffer to start of cutoff */
|
||
|
strcpy(newercomment,internal_buff);
|
||
|
strcat(newercomment,extend_char);
|
||
|
strcat(newercomment,external_buff);
|
||
|
strcat(newercomment,t->newcomment);
|
||
|
}
|
||
|
TAG_FREE(t->newcomment);
|
||
|
t->newcomment = newercomment;
|
||
|
t->newcommentlen = (int)strlen(t->newcomment);
|
||
|
t->flags |= TAG_COMMENT_CHANGED;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Modify raw data stuff
|
||
|
*/
|
||
|
if (l) {
|
||
|
tagStruct *t;
|
||
|
char type[5];
|
||
|
char name[FILE_NAME_LENGTH];
|
||
|
int llen,lcut,wlen;
|
||
|
t = (tagStruct *) DBgetTags(xx,seq);
|
||
|
force_comment(t);
|
||
|
sscanf(t->newcomment,"%6d%6d%6d%*s",&llen,&lcut,&wlen);
|
||
|
strncpy(type,&t->newcomment[18],4);
|
||
|
strncpy(name,&t->newcomment[22],FILE_NAME_LENGTH);
|
||
|
wlen -= l;
|
||
|
if (use_tag==LEFT) lcut+=l;
|
||
|
sprintf(t->newcomment,"%6d%6d%6d",llen,lcut,wlen);
|
||
|
strncat(t->newcomment,type,4);
|
||
|
strncat(t->newcomment,name,FILE_NAME_LENGTH);
|
||
|
t->newcommentlen = (int)strlen(t->newcomment);
|
||
|
t->flags |= TAG_COMMENT_CHANGED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
}
|
||
|
|
||
|
if (dir == RIGHT) xx->cursorPos--;
|
||
|
|
||
|
/*
|
||
|
** Lengths are a changing
|
||
|
*/
|
||
|
calculateConsensusLength(xx);
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
int undo_unextend(EdStruct *xx, int seq, int dir, int time)
|
||
|
{
|
||
|
|
||
|
int c = (DBgetComp(xx,seq)==COMPLEMENTED);
|
||
|
char t_type[4];
|
||
|
tagStruct *t;
|
||
|
int use_tag;
|
||
|
char extend_char;
|
||
|
int l;
|
||
|
int lextend;
|
||
|
int end_char_inserted = 0;
|
||
|
int added_internal = 0;
|
||
|
int added_external = 0;
|
||
|
|
||
|
use_tag = (c && dir==LEFT || !c && dir==RIGHT )?RIGHT: LEFT;
|
||
|
strncpy(t_type,
|
||
|
(use_tag==RIGHT )?TAG_TYPE_RCUT:TAG_TYPE_LCUT,4);
|
||
|
|
||
|
/*
|
||
|
** Process tag information
|
||
|
** collating *DE? flags and *INS flags
|
||
|
** and adjusting other flags accordingly
|
||
|
*/
|
||
|
{
|
||
|
tagStruct *t;
|
||
|
int ipos;
|
||
|
|
||
|
t = (tagStruct *) DBgetTags(xx,seq);
|
||
|
ipos = normalisePos(xx,seq,(dir==LEFT)?1:DBgetLength(xx,seq),1);
|
||
|
if (use_tag==RIGHT) ipos++;
|
||
|
|
||
|
while (t != NULL) {
|
||
|
if ((t->time == time) &&
|
||
|
strncmp(t->tagrec.type.c,TAG_TYPE_INSERT,3)==0) {
|
||
|
/*
|
||
|
** Handle unextending past inserts
|
||
|
*/
|
||
|
end_char_inserted++;
|
||
|
extend_char = normaliseBase(xx,seq,t->tagrec.type.c[3]);
|
||
|
/*
|
||
|
extend_char = t->tagrec.type.c[3];
|
||
|
*/
|
||
|
t->flags &= ~TAG_DELETED;
|
||
|
t->time = 0;
|
||
|
}else if ((t->time == time) &&
|
||
|
strncmp(t->tagrec.type.c, TAG_TYPE_DELETE,3)==0) {
|
||
|
/*
|
||
|
** Handle unextending past deletes
|
||
|
*/
|
||
|
if (use_tag==LEFT && t->tagrec.position == ipos ||
|
||
|
use_tag==RIGHT && t->tagrec.position == (ipos+1)) {
|
||
|
added_external++;
|
||
|
} else {
|
||
|
added_internal++;
|
||
|
}
|
||
|
t->flags &= ~TAG_DELETED;
|
||
|
t->time = 0;
|
||
|
} else if (!(t->flags & TAG_DELETED) &&
|
||
|
use_tag==LEFT && t->tagrec.position) {
|
||
|
/*
|
||
|
** Handle all other positional adjustments
|
||
|
*/
|
||
|
t->tagrec.position++;
|
||
|
}
|
||
|
t = t->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Find appropriate tag,
|
||
|
** create one if one doesn't exist
|
||
|
*/
|
||
|
t = force_get_tag(xx,seq,t_type);
|
||
|
|
||
|
/*
|
||
|
** No cutoff - ignore request
|
||
|
*/
|
||
|
l = t->newcommentlen;
|
||
|
if (! l)
|
||
|
return 1;
|
||
|
|
||
|
/*
|
||
|
** Determine character to extend
|
||
|
*/
|
||
|
lextend = added_internal+added_external+1-end_char_inserted;
|
||
|
if (use_tag==LEFT) {
|
||
|
/* Get character off end of cutoff */
|
||
|
if (!end_char_inserted) {
|
||
|
extend_char = t->newcomment[l-1-added_internal];
|
||
|
if (use_tag != dir) {
|
||
|
int_f i=1;
|
||
|
sqcom_(&extend_char,&i,(int_fl)1);
|
||
|
}
|
||
|
}
|
||
|
t->newcomment[l-lextend]='\0';
|
||
|
t->newcommentlen = l-lextend;
|
||
|
} else {
|
||
|
/* Get character off start of cutoff */
|
||
|
char *nc;
|
||
|
if (!end_char_inserted) {
|
||
|
extend_char = t->newcomment[added_internal];
|
||
|
if (use_tag != dir) {
|
||
|
int_f i=1;
|
||
|
sqcom_(&extend_char,&i,(int_fl)1);
|
||
|
}
|
||
|
}
|
||
|
for (nc=t->newcomment;*nc=nc[lextend];nc++);
|
||
|
t->newcommentlen -= lextend;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
if (dir==LEFT){
|
||
|
int i,j;
|
||
|
char *s;
|
||
|
|
||
|
/*
|
||
|
** insert base at start of sequence
|
||
|
*/
|
||
|
s=DBgetSeq(xx,seq);
|
||
|
for (j = DBgetLength(xx,seq)+1; j > 1; j--)
|
||
|
s[j-1] = s[j-2];
|
||
|
s[0] = extend_char;
|
||
|
DBsetLength(xx,seq,DBgetLength(xx,seq)+1);
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED|DB_FLAG_REL_MODIFIED);
|
||
|
selectInsertBase(xx,seq,1);
|
||
|
|
||
|
/*
|
||
|
** shift sequence left
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
/*
|
||
|
** insert base at end of sequence
|
||
|
*/
|
||
|
char *s;
|
||
|
int l=DBgetLength(xx,seq);
|
||
|
s=DBgetSeq(xx,seq);
|
||
|
s[l] = extend_char;
|
||
|
DBsetLength(xx,seq,l+1);
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_SEQ_MODIFIED|DB_FLAG_REL_MODIFIED);
|
||
|
selectInsertBase(xx,seq,l+1);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Modify raw data stuff
|
||
|
*/
|
||
|
{
|
||
|
tagStruct *t;
|
||
|
char type[5];
|
||
|
char name[FILE_NAME_LENGTH+1];
|
||
|
int llen,lcut,wlen;
|
||
|
t = (tagStruct *) DBgetTags(xx,seq);
|
||
|
force_comment(t);
|
||
|
sscanf(t->newcomment,"%6d%6d%6d%*s",&llen,&lcut,&wlen);
|
||
|
strncpy(type,&t->newcomment[18],4);
|
||
|
strncpy(name,&t->newcomment[22],FILE_NAME_LENGTH);
|
||
|
wlen+=lextend;
|
||
|
if (use_tag==LEFT) lcut-=lextend;
|
||
|
sprintf(t->newcomment,"%6d%6d%6d",llen,lcut,wlen);
|
||
|
strncat(t->newcomment,type,4);
|
||
|
strncat(t->newcomment,name,FILE_NAME_LENGTH);
|
||
|
t->newcommentlen = (int)strlen(t->newcomment);
|
||
|
t->flags |= TAG_COMMENT_CHANGED;
|
||
|
DBsetFlags(xx,seq,DBgetFlags(xx,seq)|DB_FLAG_TAG_MODIFIED);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (dir == RIGHT) xx->cursorPos++;
|
||
|
|
||
|
/*
|
||
|
** Lengths are a changing
|
||
|
*/
|
||
|
calculateConsensusLength(xx);
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void meta_arrow (Widget widget, XEvent *event, int key)
|
||
|
/*
|
||
|
** Handle cut-off adjust
|
||
|
*/
|
||
|
{
|
||
|
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
|
int e_time = get_uniq_id(NULL);
|
||
|
int seq,pos;
|
||
|
int seq_length;
|
||
|
|
||
|
seq = xx->cursorSeq;
|
||
|
pos = xx->cursorPos;
|
||
|
seq_length = DBgetLength(xx,seq);
|
||
|
|
||
|
/*
|
||
|
** determine which operation is to take place
|
||
|
*/
|
||
|
if (key==LEFT) {
|
||
|
if (seq) {
|
||
|
if (pos==1) {
|
||
|
if (! extend(xx,seq,LEFT,e_time)) {
|
||
|
recordEdit (&bucketStack, xx, undoExtend, seq, pos,LEFT,e_time);
|
||
|
redisplayWithCursor(xx);
|
||
|
}
|
||
|
} else if (pos>seq_length) {
|
||
|
if (! unextend(xx,seq,RIGHT,e_time)) {
|
||
|
recordEdit (&bucketStack, xx, undoUnextend, seq, pos, RIGHT, e_time);
|
||
|
redisplayWithCursor(xx);
|
||
|
}
|
||
|
} else
|
||
|
caretLeft(widget,event,NULL,0);
|
||
|
} else
|
||
|
caretLeft(widget,event,NULL,0);
|
||
|
} else {
|
||
|
if (seq) {
|
||
|
if (pos==1) {
|
||
|
if (! unextend(xx,seq,LEFT,e_time)) {
|
||
|
redisplayWithCursor(xx);
|
||
|
recordEdit (&bucketStack, xx, undoUnextend, seq, pos, LEFT,e_time);
|
||
|
}
|
||
|
} else if (pos>seq_length) {
|
||
|
if (! extend(xx,seq,RIGHT,e_time)) {
|
||
|
redisplayWithCursor(xx);
|
||
|
recordEdit (&bucketStack, xx, undoExtend, seq, pos, RIGHT, e_time);
|
||
|
}
|
||
|
} else
|
||
|
caretRight(widget,event,NULL,0);
|
||
|
} else
|
||
|
caretRight(widget,event,NULL,0);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void meta_left (Widget widget, XEvent *event, String *params,
|
||
|
Cardinal *num_params)
|
||
|
{
|
||
|
meta_arrow(widget,event,LEFT);
|
||
|
}
|
||
|
|
||
|
void meta_right (Widget widget, XEvent *event, String *params,
|
||
|
Cardinal *num_params)
|
||
|
{
|
||
|
meta_arrow(widget,event,RIGHT);
|
||
|
}
|
||
|
|
||
|
void meta_up (Widget widget, XEvent *event, String *params,
|
||
|
Cardinal *num_params)
|
||
|
/*
|
||
|
** Handle cut-off adjust
|
||
|
*/
|
||
|
{
|
||
|
EdStruct *xx = widgetToEdStruct(XtParent(widget));
|
||
|
|
||
|
dump_tags(xx,xx->cursorSeq);
|
||
|
|
||
|
}
|