X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fcommands%2FEditCommand.java;h=414cea71832a0d7e2d78174e6d08a51116fb62f5;hb=11cce1c1e065d4430400ad414460ae643b51fbfe;hp=45b19afd180419e65aa67bde723fae03dd4b0912;hpb=2a6873d5bfdd3c0f501545dbf4b07c184a7352b5;p=jalview.git
diff --git a/src/jalview/commands/EditCommand.java b/src/jalview/commands/EditCommand.java
index 45b19af..414cea7 100644
--- a/src/jalview/commands/EditCommand.java
+++ b/src/jalview/commands/EditCommand.java
@@ -1,20 +1,19 @@
/*
- * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Jalview. If not, see
Title: EditCommmand
- * - *Description: Essential information for performing - * undo and redo for cut/paste insert/delete gap - * which can be stored in the HistoryList
- * - *Copyright: Copyright (c) 2006
- * - *Company: Dundee University
- * + * + *+ * Title: EditCommmand + *
+ * + *+ * Description: Essential information for performing undo and redo for cut/paste + * insert/delete gap which can be stored in the HistoryList + *
+ * + *+ * Copyright: Copyright (c) 2006 + *
+ * + *+ * Company: Dundee University + *
+ * * @author not attributable * @version 1.0 */ -public class EditCommand - implements CommandI +public class EditCommand implements CommandI { public static final int INSERT_GAP = 0; + 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; String description; public EditCommand() - {} + { + } public EditCommand(String description) { this.description = description; } - public EditCommand(String description, - int command, - SequenceI[] seqs, - int position, - int number, - AlignmentI al) + public EditCommand(String description, int command, SequenceI[] seqs, + int position, int number, AlignmentI al) { this.description = description; if (command == CUT || command == PASTE) { edits = new Edit[] - { - new Edit(command, seqs, position, number, al)}; + { 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() @@ -90,14 +109,42 @@ public class EditCommand return edits[0].al; } - final public void appendEdit(int command, - SequenceI[] seqs, - int position, - int number, - AlignmentI al, - boolean performEdit) + /** + * 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, AlignmentI[] views) { - Edit edit = new Edit(command, seqs, position, number, al.getGapCharacter()); + Edit edit = new Edit(command, seqs, position, number, al + .getGapCharacter()); if (al.getHeight() == seqs.length) { edit.al = al; @@ -114,95 +161,98 @@ public class EditCommand else { edits = new Edit[] - { - edit}; + { edit }; } 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; } } } final void insertGap(Edit command) { + for (int s = 0; s < command.seqs.length; s++) { - command.seqs[s].insertCharAt(command.position, - command.number, - command.gapChar); + command.seqs[s].insertCharAt(command.position, command.number, + command.gapChar); } - adjustAnnotations(command, true, false); + adjustAnnotations(command, true, false, null); } final void deleteGap(Edit command) { for (int s = 0; s < command.seqs.length; s++) { - command.seqs[s].deleteChars(command.position, - command.position + command.number); + command.seqs[s].deleteChars(command.position, 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; + boolean seqDeleted = false; command.string = new char[command.seqs.length][]; for (int i = 0; i < command.seqs.length; i++) @@ -210,50 +260,62 @@ public class EditCommand if (command.seqs[i].getLength() > command.position) { command.string[i] = command.seqs[i].getSequence(command.position, - command.position + command.number); - - if (command.seqs[i].getDatasetSequence() != null - || command.seqs[i].getSequenceFeatures() != null) + command.position + command.number); + SequenceI oldds = command.seqs[i].getDatasetSequence(); + if (command.oldds != null && command.oldds[i] != null) + { + // we are redoing an undone cut. + command.seqs[i].setDatasetSequence(null); + } + command.seqs[i].deleteChars(command.position, command.position + + command.number); + if (command.oldds != null && command.oldds[i] != null) + { + // oldds entry contains the cut dataset sequence. + command.seqs[i].setDatasetSequence(command.oldds[i]); + command.oldds[i] = oldds; + } + else { - for (int s = command.position; s < command.position + command.number; - s++) + // modify the oldds if necessary + if (oldds != command.seqs[i].getDatasetSequence() + || command.seqs[i].getSequenceFeatures() != null) { - if (jalview.schemes.ResidueProperties - .aaIndex[command.seqs[i].getCharAt(s)] != 23) + if (command.oldds == null) { - adjustFeatures(command, i, - command.seqs[i].findPosition(command.position), - command.seqs[i].findPosition(command.position + - command.number), - false); - break; + command.oldds = new SequenceI[command.seqs.length]; } + command.oldds[i] = oldds; + adjustFeatures(command, i, command.seqs[i] + .findPosition(command.position), command.seqs[i] + .findPosition(command.position + command.number), false); } } - command.seqs[i].deleteChars(command.position, - command.position + command.number); } if (command.seqs[i].getLength() < 1) { command.al.deleteSequence(command.seqs[i]); - seqDeleted=true; + seqDeleted = true; } } - adjustAnnotations(command, false, seqDeleted); + adjustAnnotations(command, false, seqDeleted, views); } - void paste(Edit command) + void paste(Edit command, AlignmentI[] views) { StringBuffer tmp; boolean newDSNeeded; - boolean seqWasDeleted=false; + boolean newDSWasNeeded; + int newstart, newend; + boolean seqWasDeleted = false; int start = 0, end = 0; for (int i = 0; i < command.seqs.length; i++) { newDSNeeded = false; + newDSWasNeeded = command.oldds != null && command.oldds[i] != null; if (command.seqs[i].getLength() < 1) { // ie this sequence was deleted, we need to @@ -261,23 +323,28 @@ public class EditCommand if (command.alIndex[i] < command.al.getHeight()) { command.al.getSequences().insertElementAt(command.seqs[i], - command.alIndex[i]); + command.alIndex[i]); } else { command.al.addSequence(command.seqs[i]); } - seqWasDeleted=true; + seqWasDeleted = true; } + newstart = command.seqs[i].getStart(); + newend = command.seqs[i].getEnd(); + tmp = new StringBuffer(); tmp.append(command.seqs[i].getSequence()); + // Undo of a delete does not replace original dataset sequence on to + // alignment sequence. if (command.string != null && command.string[i] != null) { if (command.position >= tmp.length()) { - //This occurs if padding is on, and residues - //are removed from end of alignment + // This occurs if padding is on, and residues + // are removed from end of alignment int length = command.position - tmp.length(); while (length > 0) { @@ -286,50 +353,102 @@ public class EditCommand } } tmp.insert(command.position, command.string[i]); - for (int s = 0; s < command.string[i].length; s++) { - if (jalview.schemes.ResidueProperties.aaIndex[command.string[i][s]] != - 23) + if (jalview.schemes.ResidueProperties.aaIndex[command.string[i][s]] != 23) { - newDSNeeded = true; - start = command.seqs[i].findPosition(command.position); - end = command.seqs[i].findPosition(command.position + - command.number); - break; + if (!newDSNeeded) + { + newDSNeeded = true; + start = command.seqs[i].findPosition(command.position); + end = command.seqs[i].findPosition(command.position + + command.number); + } + if (command.seqs[i].getStart() == start) + newstart--; + else + newend++; } } command.string[i] = null; } command.seqs[i].setSequence(tmp.toString()); - + command.seqs[i].setStart(newstart); + command.seqs[i].setEnd(newend); if (newDSNeeded) { if (command.seqs[i].getDatasetSequence() != null) - { // use new ds mechanism here - Sequence ds = new Sequence(command.seqs[i].getName(), - jalview.analysis.AlignSeq.extractGaps( - jalview.util.Comparison.GapChars, - command.seqs[i].getSequenceAsString() - ), - command.seqs[i].getStart(), - command.seqs[i].getEnd()); - ds.setDescription(command.seqs[i].getDescription()); + { + SequenceI ds; + if (newDSWasNeeded) + { + ds = command.oldds[i]; + } + else + { + // make a new DS sequence + // use new ds mechanism here + ds = new Sequence(command.seqs[i].getName(), + jalview.analysis.AlignSeq.extractGaps( + jalview.util.Comparison.GapChars, + command.seqs[i].getSequenceAsString()), + command.seqs[i].getStart(), command.seqs[i].getEnd()); + ds.setDescription(command.seqs[i].getDescription()); + } + if (command.oldds == null) + { + command.oldds = new SequenceI[command.seqs.length]; + } + command.oldds[i] = command.seqs[i].getDatasetSequence(); command.seqs[i].setDatasetSequence(ds); } - 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; + // TODO TUTORIAL - Fix for replacement with different length of sequence (or + // whole sequence) + // TODO Jalview 2.4 bugfix change to an aggregate command - original + // sequence string is cut, new string is pasted in. + command.number = start + command.string[0].length; + for (int i = 0; i < command.seqs.length; i++) + { + /** + * cut addHistoryItem(new EditCommand("Cut Sequences", EditCommand.CUT, + * cut, sg.getStartRes(), sg.getEndRes()-sg.getStartRes()+1, + * viewport.alignment)); + * + */ + /** + * then addHistoryItem(new EditCommand( "Add sequences", + * EditCommand.PASTE, sequences, 0, alignment.getWidth(), alignment) ); + * + */ + 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; if (modifyVisibility && !insert) @@ -350,32 +469,108 @@ public class EditCommand if (modifyVisibility) { // Rows are only removed or added to sequence object. - if (!insert) { + if (!insert) + { // remove rows tmp = command.seqs[s].getAnnotation(); - if (tmp!=null) { - command.deletedAnnotationRows.put(command.seqs[s], tmp); - for (int aa =0; aa