#include #include #include #include #include #include #include #include #include #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;jnumelements;j++) { FreeNASeq(Clipboard->element[j]); InitNASeq(&(Clipboard->element[j]),TEXT); } Clipboard->numelements = 0; for(j=0;jnumelements;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;jnumelements;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;jnumelements;j++) { FreeNASeq(Clipboard->element[j]); InitNASeq(&(Clipboard->element[j]),TEXT); } Clipboard->numelements = 0; for(j=0;jnumelements;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;ielement[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;jnumelements;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;jnumelements;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;jnumelements;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;jnumelements;j++) { alignment->element[j].groupf = NULL; alignment->element[j].groupb = NULL; } for(group = 1;group <= alignment->numgroups;group++) { last = -1; for(j=0;jnumelements;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;jmaxlen;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;jnumelements;j++) if(DataSet->element[j].subselected) TextClipSize++; if(TextClipSize == 0) return; TextClip = (char**)Calloc(TextClipSize,sizeof(char*)); for(j=0;jnumelements;j++) if(DataSet->element[j].subselected) { this_elem = &(DataSet->element[j]); /* * Need to check protections */ for(i=0,blank_space = 0;ioffset;i++) if(DataSet->selection_mask[i] == '1') TextClip[numselected][blank_space++] = (char)getelem(this_elem,i); for(i=0,k=0;iseqlen;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) && (iseqlen-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;jnumelements;j++) { this_elem = &(DataSet->element[j]); prot = this_elem->protect; if((this_elem->subselected)&& (this_elem->elementtype!=TEXT)) { for(i=0;imaxlen;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;jelement[j+cursory]); violate |= InsertViolate(DataSet,this_elem, TextClip[j],cursorx,TextClipLength); } if(violate == FALSE) { for(j=0;jelement[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;jmaxlen;j++) if(DataSet->selection_mask[j] == '1') columns++; if(columns == 0) return; /* * Free old Text clipboard */ for(j=0;jnumelements;j++) if(DataSet->element[j].subselected) TextClipSize++; if(TextClipSize == 0) return; TextClip = (char**)Calloc(TextClipSize,sizeof(char*)); for(j=0;jnumelements;j++) if(DataSet->element[j].subselected) { this_elem = &(DataSet->element[j]); /* * Need to check protections */ for(i=0,blank_space = 0;ioffset;i++) if(DataSet->selection_mask[i] == '1') TextClip[numselected][blank_space++] = (char)getelem(this_elem,i); for(i=0,k=0;iseqlen;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); }