public static final int DELETE_GAP = 1;
public static final int CUT = 2;
public static final int PASTE = 3;
+ public static final int REPLACE = 4;
Edit[] edits;
new Edit(command, seqs, position, number, al)};
}
- performEdit(0);
+ performEdit(0, null);
+ }
+
+ public EditCommand(String description,
+ int command,
+ String replace,
+ SequenceI[] seqs,
+ int position,
+ int number,
+ AlignmentI al)
+ {
+ this.description = description;
+ if (command == REPLACE)
+ {
+ edits = new Edit[]
+ { new Edit(command, seqs, position, number, al, replace)};
+ }
+
+ performEdit(0, null);
}
final public String getDescription()
return edits[0].al;
}
+ /**
+ * append a new editCommand
+ * Note. this shouldn't be called if the edit is an operation affects more alignment objects than the one referenced
+ * in al (for example, cut or pasting whole sequences). Use the form with an additional AlignmentI[] views parameter.
+ * @param command
+ * @param seqs
+ * @param position
+ * @param number
+ * @param al
+ * @param performEdit
+ */
+ final public void appendEdit(int command,
+ SequenceI[] seqs,
+ int position,
+ int number,
+ AlignmentI al,
+ boolean performEdit)
+ {
+ appendEdit(command, seqs, position, number, al, performEdit, null);
+ }
+ /**
+ * append a new edit command with a set of alignment views that may be operated on
+ * @param command
+ * @param seqs
+ * @param position
+ * @param number
+ * @param al
+ * @param performEdit
+ * @param views
+ */
final public void appendEdit(int command,
SequenceI[] seqs,
int position,
int number,
AlignmentI al,
- boolean performEdit)
+ boolean performEdit, AlignmentI[] views)
{
Edit edit = new Edit(command, seqs, position, number, al.getGapCharacter());
if (al.getHeight() == seqs.length)
if (performEdit)
{
- performEdit(edits.length - 1);
+ performEdit(edits.length - 1, views);
}
}
- final void performEdit(int commandIndex)
+ final void performEdit(int commandIndex, AlignmentI[] views)
{
int eSize = edits.length;
for (int e = commandIndex; e < eSize; e++)
{
- if (edits[e].command == INSERT_GAP)
+ switch(edits[e].command)
{
+ case INSERT_GAP:
insertGap(edits[e]);
- }
- else if (edits[e].command == DELETE_GAP)
- {
+ break;
+ case DELETE_GAP:
deleteGap(edits[e]);
- }
- else if (edits[e].command == CUT)
- {
- cut(edits[e]);
- }
- else if (edits[e].command == PASTE)
- {
- paste(edits[e]);
+ break;
+ case CUT:
+ cut(edits[e], views);
+ break;
+ case PASTE:
+ paste(edits[e], views);
+ break;
+ case REPLACE:
+ replace(edits[e]);
+ break;
}
}
}
- final public void doCommand()
+ final public void doCommand(AlignmentI[] views)
{
- performEdit(0);
+ performEdit(0,views);
}
- final public void undoCommand()
+ final public void undoCommand(AlignmentI[] views)
{
int e = 0, eSize = edits.length;
for (e = eSize - 1; e > -1; e--)
{
- if (edits[e].command == INSERT_GAP)
+ switch (edits[e].command)
{
+ case INSERT_GAP:
deleteGap(edits[e]);
- }
- else if (edits[e].command == DELETE_GAP)
- {
+ break;
+ case DELETE_GAP:
insertGap(edits[e]);
- }
- else if (edits[e].command == CUT)
- {
- paste(edits[e]);
- }
- else if (edits[e].command == PASTE)
- {
- cut(edits[e]);
+ break;
+ case CUT:
+ paste(edits[e], views);
+ break;
+ case PASTE:
+ cut(edits[e], views);
+ break;
+ case REPLACE:
+ replace(edits[e]);
+ break;
}
}
}
command.gapChar);
}
- adjustAnnotations(command, true, false);
+ adjustAnnotations(command, true, false, null);
}
final void deleteGap(Edit command)
command.position + command.number);
}
- adjustAnnotations(command, false, false);
+ adjustAnnotations(command, false, false, null);
}
- void cut(Edit command)
+ void cut(Edit command, AlignmentI[] views)
{
boolean seqDeleted=false;
command.string = new char[command.seqs.length][];
}
}
- adjustAnnotations(command, false, seqDeleted);
+ adjustAnnotations(command, false, seqDeleted, views);
}
- void paste(Edit command)
+ void paste(Edit command, AlignmentI[] views)
{
StringBuffer tmp;
boolean newDSNeeded;
adjustFeatures(command, i, start, end, true);
}
}
- adjustAnnotations(command, true, seqWasDeleted);
+ adjustAnnotations(command, true, seqWasDeleted, views);
command.string = null;
}
- final void adjustAnnotations(Edit command, boolean insert, boolean modifyVisibility)
+ void replace(Edit command)
+ {
+ StringBuffer tmp;
+ String oldstring;
+ int start = command.position;
+ int end = command.number;
+
+ command.number = start + command.string[0].length;
+ for (int i = 0; i < command.seqs.length; i++)
+ {
+ oldstring = command.seqs[i].getSequenceAsString();
+ tmp = new StringBuffer(oldstring.substring(0, start));
+ tmp.append(command.string[i]);
+ tmp.append(oldstring.substring(end));
+ command.seqs[i].setSequence(tmp.toString());
+ command.string[i] = oldstring.substring(start, end).toCharArray();
+ tmp = null;
+ oldstring = null;
+ }
+ }
+
+ final void adjustAnnotations(Edit command, boolean insert, boolean modifyVisibility, AlignmentI[] views)
{
AlignmentAnnotation[] annotations = null;
// remove rows
tmp = command.seqs[s].getAnnotation();
if (tmp!=null) {
- command.deletedAnnotationRows.put(command.seqs[s], tmp);
+ int alen=tmp.length;
for (int aa =0; aa<tmp.length; aa++)
{
- command.al.deleteAnnotation(tmp[aa]);
+ if (!command.al.deleteAnnotation(tmp[aa]))
+ {
+ // strip out annotation not in the current al (will be put back on insert in all views)
+ tmp[aa] = null;
+ alen--;
+ }
}
command.seqs[s].setAlignmentAnnotation(null);
+ if (alen!=tmp.length)
+ {
+ // save the non-null annotation references only
+ AlignmentAnnotation[] saved = new AlignmentAnnotation[alen];
+ for (int aa=0,aapos=0;aa<tmp.length;aa++)
+ {
+ if (tmp[aa]!=null)
+ {
+ saved[aapos++] = tmp[aa];
+ tmp[aa] = null;
+ }
+ }
+ tmp = saved;
+ command.deletedAnnotationRows.put(command.seqs[s], saved);
+ // and then remove any annotation in the other views
+ for (int alview=0; views!=null && alview<views.length; alview++)
+ {
+ if (views[alview]!=command.al)
+ {
+ AlignmentAnnotation[] toremove = views[alview].getAlignmentAnnotation();
+ if (toremove==null || toremove.length==0)
+ {
+ continue;
+ }
+ // remove any alignment annotation on this sequence that's on that alignment view.
+ for (int aa = 0; aa<toremove.length; aa++)
+ {
+ if (toremove[aa].sequenceRef==command.seqs[s])
+ {
+ views[alview].deleteAnnotation(toremove[aa]);
+ }
+ }
+ }
+ }
+ } else {
+ // save all the annotation
+ command.deletedAnnotationRows.put(command.seqs[s], tmp);
+ }
}
} else {
// recover rows
if (revealed!=null) {
for (int aa =0; aa<revealed.length; aa++)
{
+ // iterate through al adding original annotation
command.al.addAnnotation(revealed[aa]);
}
for (int aa =0; aa<revealed.length; aa++)
{
command.al.setAnnotationIndex(revealed[aa], aa);
}
+ // and then duplicate added annotation on every other alignment view
+ for (int vnum=0; views!=null && vnum<views.length; vnum++)
+ {
+ if (views[vnum]!=command.al)
+ {
+ int avwidth = views[vnum].getWidth()+1;
+ // duplicate in this view
+ for (int a=0; a<revealed.length; a++)
+ {
+ AlignmentAnnotation newann = new AlignmentAnnotation(revealed[a]);
+ command.seqs[s].addAlignmentAnnotation(newann);
+ newann.padAnnotation(avwidth);
+ views[vnum].addAnnotation(newann);
+ views[vnum].setAnnotationIndex(newann, a);
+ }
+ }
+ }
}
}
}
}
int tSize = 0;
-
+ if (annotations[a].annotations == null)
+ {
+ // nothing to edit here ?
+ continue;
+ }
aSize = annotations[a].annotations.length;
if (insert)
{
for (int aa = 0; aa < temp.length; aa++)
{
temp[aa] = new Annotation(
- command.al.getGapCharacter()+"",
+ command.gapChar+"",
null, ' ', 0);
}
}
0, temp, 0, copylen); //command.position);
Annotation[] deleted = new Annotation[command.number];
- if (copylen>command.position) {
+ if (copylen>=command.position) {
copylen = Math.min(command.number, annotations[a].annotations.length-command.position);
if (copylen>0)
{
fullAlignmentHeight = (al.getHeight() == seqs.length);
}
- }
+ Edit(int command,
+ SequenceI[] seqs,
+ int position,
+ int number,
+ AlignmentI al,
+ String replace)
+ {
+ this.command = command;
+ this.seqs = seqs;
+ this.position = position;
+ this.number = number;
+ this.al = al;
+ this.gapChar = al.getGapCharacter();
+ string = new char[seqs.length][];
+ for (int i = 0; i < seqs.length; i++)
+ {
+ string[i] = replace.toCharArray();
+ }
+
+ fullAlignmentHeight = (al.getHeight() == seqs.length);
+ }
+ }
}