gde_linux/CORE/CutCopyPaste.c

668 lines
14 KiB
C
Executable File

#include <stdio.h>
#include <malloc.h>
#include <strings.h>
#include <xview/xview.h>
#include <xview/scrollbar.h>
#include <xview/panel.h>
#include <xview/window.h>
#include <xview/notice.h>
#include <xview/textsw.h>
#include "menudefs.h"
#include "defines.h"
/*
Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
All rights reserved.
*/
EditCut(item,event)
Panel_item item;
Event *event;
{
extern Frame frame;
extern Canvas EditCan,EditNameCan;
extern Panel_item left_foot,right_foot;
extern NA_Alignment *DataSet,*Clipboard;
char buffer[80];
int j,numselected=0,numshifted = 0;
if(TestSelection() == SELECT_REGION)
return(EditSubCut(item,event));
for(j=0;j<Clipboard->numelements;j++)
{
FreeNASeq(Clipboard->element[j]);
InitNASeq(&(Clipboard->element[j]),TEXT);
}
Clipboard->numelements = 0;
for(j=0;j<DataSet->numelements;j++)
if(DataSet->element[j].selected)
{
if(numselected >= Clipboard->maxnumelements-1)
{
Clipboard->maxnumelements += 10;
Clipboard->element = (NA_Sequence*)Realloc
(Clipboard->element,
Clipboard->maxnumelements*sizeof(NA_Sequence));
}
Clipboard->element[(Clipboard->numelements)] =
DataSet->element[j];
/*
* Map sequences back into their global positions, as we will
* normailze the alignment after they are copied out.
*/
Clipboard->element[(Clipboard->numelements)++].offset+=
DataSet->rel_offset;
numselected++;
}
for(j=0;j<DataSet->numelements;j++)
if(DataSet->element[j].selected)
numshifted++;
else
DataSet->element[j-numshifted] =
DataSet->element[j];
DataSet->numelements -= numshifted;
NormalizeOffset(DataSet);
SetNADData(DataSet,EditCan,EditNameCan);
Regroup(DataSet);
RepaintAll(TRUE);
sprintf(buffer,"%d sequence in Sequence Clipboard",numselected);
xv_set(frame,FRAME_RIGHT_FOOTER,buffer,0);
xv_set(right_foot,PANEL_LABEL_STRING,buffer,0);
return(XV_OK);
}
EditCopy(item,event)
Panel_item item;
Event *event;
{
extern Frame frame;
extern Canvas EditCan,EditNameCan;
extern NA_Alignment *DataSet,*Clipboard;
extern Panel_item left_foot,right_foot;
char buffer[80];
int i,j,numselected=0,numshifted = 0,this;
if(TestSelection() == SELECT_REGION)
return(EditSubCopy(item,event));
for(j=0;j<Clipboard->numelements;j++)
{
FreeNASeq(Clipboard->element[j]);
InitNASeq(&(Clipboard->element[j]),TEXT);
}
Clipboard->numelements = 0;
for(j=0;j<DataSet->numelements;j++)
if(DataSet->element[j].selected)
{
this = Clipboard->numelements;
if(numselected >= Clipboard->maxnumelements-1)
{
Clipboard->maxnumelements += 10;
Clipboard->element = (NA_Sequence*)Realloc
(Clipboard->element,
Clipboard->maxnumelements*sizeof(NA_Sequence));
InitNASeq(&(Clipboard->element
[this]),
DataSet->element[j].elementtype);
}
Clipboard->element[this] = DataSet->element[j];
/*
* Handle comments
*/
if(DataSet->element[j].comments)
{
Clipboard->element[this].comments = (char*)
strdup(DataSet->element[j].comments);
Clipboard->element[this].comments_maxlen =
Clipboard->element[this].comments_len;
}
/*
* And baggage
*/
if(DataSet->element[j].baggage)
{
Clipboard->element[this].baggage = (char*)
strdup(DataSet->element[j].baggage);
Clipboard->element[this].baggage_maxlen =
Clipboard->element[this].baggage_len;
}
Clipboard->element[this].cmask = NULL;
Clipboard->element[this].sequence
= (NA_Base*)Calloc(DataSet->element[j].seqmaxlen,
sizeof(NA_Base));
for(i=0;i<DataSet->element[j].seqlen;i++)
Clipboard->element[Clipboard->numelements].
sequence[i] = DataSet->element[j].sequence[i];
/*
putelem(&(Clipboard->element[Clipboard->
numelements]),i,
getelem(&(DataSet->element[j]),i));
*/
/*
* Map sequences back into their global positions, as we will
* normailze the alignment after they are copied out.
*/
Clipboard->element[(Clipboard->numelements)].offset +=
DataSet->rel_offset;
(Clipboard->numelements)++;
numselected++;
}
sprintf(buffer,"%d sequence in Clipboard",numselected);
xv_set(frame,FRAME_RIGHT_FOOTER,buffer,0);
xv_set(right_foot,PANEL_LABEL_STRING,buffer,0);
return(XV_OK);
}
EditPaste(item,event)
Panel_item item;
Event *event;
{
extern Frame frame;
extern Canvas EditCan,EditNameCan;
extern NA_Alignment *DataSet,*Clipboard;
extern Panel_item left_foot,right_foot;
extern TextClipSize;
int j,last = -1;
if(TextClipSize != 0)
{
if(Clipboard->numelements == 0)
return(EditSubPaste(item,event));
else if(notice_prompt(frame,NULL,NOTICE_MESSAGE_STRINGS,
"You have data in both clipboards, do you",
"wish to paste from the...",
NULL,
NOTICE_BUTTON,"Sequence clipboard",1,
NOTICE_BUTTON,"Text clipboard",2,
0) == 2)
return(EditSubPaste(item,event));
}
for(j=0;j<DataSet->numelements;j++)
if(DataSet->element[j].selected)
last = j;
if(DataSet->maxnumelements <= DataSet->numelements+
Clipboard->numelements)
{
DataSet->maxnumelements+=Clipboard->numelements;
DataSet->element =(NA_Sequence*)Realloc(DataSet->element,
DataSet->maxnumelements*sizeof(NA_Sequence));
}
for(j=DataSet->numelements-1;j>=last+1;j--)
DataSet->element[j+Clipboard->numelements] =
DataSet->element[j];
for(j=0;j<Clipboard->numelements;j++)
{
DataSet->element[last+1+j] = Clipboard->element[j];
/*
* be sure to bring them back into alignment with the rest
*/
DataSet->element[last+1+j].offset -= DataSet->rel_offset;
}
DataSet->numelements += Clipboard->numelements;
/*
for(j=0;j<Clipboard->numelements;j++)
{
FreeNASeq(Clipboard->element[j]);
InitNASeq(&(Clipboard->element[j]),TEXT);
}
*/
Clipboard->numelements = 0;
NormalizeOffset(DataSet);
SetNADData(DataSet,EditCan,EditNameCan);
Regroup(DataSet);
RepaintAll(TRUE);
xv_set(frame,FRAME_RIGHT_FOOTER,"Clipboard empty",0);
xv_set(right_foot,PANEL_LABEL_STRING,"Clipboard empty",0);
return(XV_OK);
}
Regroup(alignment)
NA_Alignment *alignment;
{
int j,group,last;
for(j=0;j<alignment->numelements;j++)
{
alignment->element[j].groupf = NULL;
alignment->element[j].groupb = NULL;
}
for(group = 1;group <= alignment->numgroups;group++)
{
last = -1;
for(j=0;j<alignment->numelements;j++)
if(alignment->element[j].groupid == group)
{
if(last != -1)
{
alignment->element[j].groupb =
&(alignment->element[last]);
alignment->element[last].groupf =
&(alignment->element[j]);
}
last = j;
}
}
return;
}
EditSubCut(item,event)
Panel_item item;
Event *event;
{
extern Frame frame;
extern Canvas EditCan,EditNameCan;
extern NA_Alignment *DataSet,*Clipboard;
extern Panel_item left_foot,right_foot;
extern char **TextClip;
extern int TextClipSize,TextClipLength;
int blank_space = 0;
NA_Sequence *this_elem;
char buffer[80];
int j,i,k,numselected=0,numshifted = 0,columns=0;
/*
* Check how many columns selected
*/
if(DataSet->selection_mask == NULL)
return;
for(j=0;j<DataSet->maxlen;j++)
if(DataSet->selection_mask[j] == '1')
columns++;
if(columns == 0)
return;
/*
* Free old Text clipboard
*/
if(SubCutViolate())
{
Warning("Cut violates current protections");
return XV_OK;
}
for(j=0;j<TextClipSize;j++)
Cfree(TextClip[j]);
TextClipSize = 0;
for(j=0;j<DataSet->numelements;j++)
if(DataSet->element[j].subselected)
TextClipSize++;
if(TextClipSize == 0)
return;
TextClip = (char**)Calloc(TextClipSize,sizeof(char*));
for(j=0;j<TextClipSize;j++)
TextClip[j] = (char *)Calloc(columns,sizeof(char));
for(j=0;j<DataSet->numelements;j++)
if(DataSet->element[j].subselected)
{
this_elem = &(DataSet->element[j]);
/*
* Need to check protections
*/
for(i=0,blank_space = 0;i<this_elem->offset;i++)
if(DataSet->selection_mask[i] == '1')
TextClip[numselected][blank_space++] =
(char)getelem(this_elem,i);
for(i=0,k=0;i<this_elem->seqlen;i++)
{
if(DataSet->selection_mask[i+this_elem->offset]
== '1')
{
if(this_elem->tmatrix)
TextClip[numselected][k++] =
this_elem->tmatrix[
(char)getelem(this_elem,
i+this_elem->offset)];
else
TextClip[numselected][k++] =
(char)getelem(this_elem,
i+this_elem->offset);
}
if((k!=0) && (i<this_elem->seqlen-1))
{
this_elem->sequence[1+i-k] =
this_elem->sequence[1+i];
if(this_elem->cmask)
{
this_elem->cmask[1+i-k] =
this_elem->cmask[1+i];
}
}
}
numselected++;
this_elem->seqlen -= k;
this_elem->offset -= blank_space;
/*
* This might cause problems later on if the selection mask is
* not cleaned...Make sure you test for subselected, not just
* for a non-0 mask.
*/
this_elem->subselected = FALSE;
}
TextClipLength = columns;
NormalizeOffset(DataSet);
SetNADData(DataSet,EditCan,EditNameCan);
Regroup(DataSet);
RepaintAll(TRUE);
sprintf(buffer,"%d bytes in Text Clipboard",numselected*columns);
xv_set(frame,FRAME_RIGHT_FOOTER,buffer,0);
xv_set(right_foot,PANEL_LABEL_STRING,buffer,0);
return(XV_OK);
}
SubCutViolate()
{
int i,j;
NA_Sequence *this_elem;
extern NA_Alignment *DataSet;
char base,tbase;
int GAP=FALSE,UNAMB=FALSE,AMB=FALSE,prot;
for(j=0;j<DataSet->numelements;j++)
{
this_elem = &(DataSet->element[j]);
prot = this_elem->protect;
if((this_elem->subselected)&& (this_elem->elementtype!=TEXT))
{
for(i=0;i<DataSet->maxlen;i++)
if(DataSet->selection_mask[i] == '1')
{
base = (char)getelem(this_elem,i);
if(this_elem->tmatrix)
tbase = (this_elem->tmatrix[base])|32;
switch(this_elem->elementtype)
{
case DNA:
case RNA:
if((base&15) == 0)
GAP=TRUE;
else if(tbase == 'n')
AMB=TRUE;
else
UNAMB = TRUE;
break;
case PROTEIN:
if(base == '-' ||
base == '~' ||
base == ' ')
GAP=TRUE;
else if(base == 'X' ||
base == 'x')
AMB=TRUE;
else
UNAMB = TRUE;
break;
case MASK:
if(base == '0')
GAP = TRUE;
else
UNAMB = TRUE;
break;
default:
break;
}
if(((prot & PROT_WHITE_SPACE)==0) && GAP)
return(TRUE);
else if(((prot & PROT_GREY_SPACE)==0) && AMB)
return(TRUE);
else if(((prot & PROT_BASE_CHANGES)==0) &&
UNAMB)
return(TRUE);
}
}
}
return FALSE;
}
EditSubPaste(item,event)
Panel_item item;
Event *event;
{
extern Frame frame;
extern Canvas EditCan,EditNameCan;
extern NA_Alignment *DataSet,*Clipboard;
extern Panel_item left_foot,right_foot;
extern char **TextClip;
extern int TextClipSize,TextClipLength;
int *temp_cmask,cursorx,cursory;
NA_Sequence *this_elem;
char buffer[80];
int j,i,k,violate = FALSE;
if(DataSet->selection_mask == NULL)
return(XV_OK);
if(TextClipSize == 0 || TextClipLength==0)
return(XV_OK);
cursorx = ((NA_DisplayData*)(DataSet->na_ddata))->cursor_x;
cursory = ((NA_DisplayData*)(DataSet->na_ddata))->cursor_y;
if(cursory + TextClipSize > DataSet->numelements)
{
Warning("Can't paste a block there.");
return(XV_OK);
}
for(j=0;j<TextClipSize;j++)
{
this_elem = &(DataSet->element[j+cursory]);
violate |= InsertViolate(DataSet,this_elem,
TextClip[j],cursorx,TextClipLength);
}
if(violate == FALSE)
{
for(j=0;j<TextClipSize;j++)
{
this_elem = &(DataSet->element[j+cursory]);
InsertNA(this_elem,TextClip[j],TextClipLength,cursorx);
}
}
RepaintAll(TRUE);
sprintf(buffer,"%d bytes in Text Clipboard",TextClipLength *
TextClipSize);
xv_set(frame,FRAME_RIGHT_FOOTER,buffer,0);
xv_set(right_foot,PANEL_LABEL_STRING,buffer,0);
return(XV_OK);
}
EditSubCopy(item,event)
Panel_item item;
Event *event;
{
extern Frame frame;
extern Canvas EditCan,EditNameCan;
extern NA_Alignment *DataSet,*Clipboard;
extern Panel_item left_foot,right_foot;
extern char **TextClip;
extern int TextClipSize,TextClipLength;
int blank_space = 0;
NA_Sequence *this_elem;
char buffer[80];
int j,i,k,numselected=0,numshifted = 0,columns=0;
/*
* Check how many columns selected
*/
if(DataSet->selection_mask == NULL)
return;
for(j=0;j<DataSet->maxlen;j++)
if(DataSet->selection_mask[j] == '1')
columns++;
if(columns == 0)
return;
/*
* Free old Text clipboard
*/
for(j=0;j<TextClipSize;j++)
Cfree(TextClip[j]);
TextClipSize = 0;
for(j=0;j<DataSet->numelements;j++)
if(DataSet->element[j].subselected)
TextClipSize++;
if(TextClipSize == 0)
return;
TextClip = (char**)Calloc(TextClipSize,sizeof(char*));
for(j=0;j<TextClipSize;j++)
TextClip[j] = (char *)Calloc(columns,sizeof(char));
for(j=0;j<DataSet->numelements;j++)
if(DataSet->element[j].subselected)
{
this_elem = &(DataSet->element[j]);
/*
* Need to check protections
*/
for(i=0,blank_space = 0;i<this_elem->offset;i++)
if(DataSet->selection_mask[i] == '1')
TextClip[numselected][blank_space++] =
(char)getelem(this_elem,i);
for(i=0,k=0;i<this_elem->seqlen;i++)
{
if(DataSet->selection_mask[i+this_elem->offset]
== '1')
{
if(this_elem->tmatrix)
TextClip[numselected][k++] =
this_elem->tmatrix[
(char)getelem(this_elem,
i+this_elem->offset)];
else
TextClip[numselected][k++] =
(char)getelem(this_elem,
i+this_elem->offset);
}
}
numselected++;
this_elem->subselected = FALSE;
}
TextClipLength = columns;
SetNADData(DataSet,EditCan,EditNameCan);
RepaintAll(TRUE);
sprintf(buffer,"%d bytes in Text Clipboard",numselected*columns);
xv_set(frame,FRAME_RIGHT_FOOTER,buffer,0);
xv_set(right_foot,PANEL_LABEL_STRING,buffer,0);
return(XV_OK);
}
int TestSelection()
{
int j,select_mode = 0,selected = 0,subselected = 0;
extern NA_Alignment *DataSet;
extern Frame frame;
for(j=0;j<((NA_Alignment*)DataSet)->numelements;j++)
{
selected|=((NA_Alignment*)DataSet)->element[j].selected;
subselected|=((NA_Alignment*)DataSet)->element[j].subselected;
}
if (!(selected || subselected))
Warning("Warning, no sequences selected");
if(selected && !subselected)
select_mode = SELECTED;
if(!selected && subselected)
select_mode = SELECT_REGION;
if(selected && subselected)
select_mode = notice_prompt(frame,NULL,NOTICE_MESSAGE_STRINGS,
"Do you want to use the...",NULL,
NOTICE_BUTTON,"Selected sequences",SELECTED,
NOTICE_BUTTON,"Selected regions",SELECT_REGION,
NULL);
/*
for(j=0;j<((NA_Alignment*)DataSet)->numelements;j++)
{
if(select_mode == SELECT_REGION)
((NA_Alignment*)DataSet)->element[j].selected = FALSE;
else
((NA_Alignment*)DataSet)->element[j].subselected = FALSE;
}
*/
return(select_mode);
}