+/*\r
+ * Jalview - A Sequence Alignment Editor and Viewer\r
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\r
+ */\r
+package jalview.commands;\r
+\r
+import jalview.datamodel.*;\r
+\r
+/**\r
+ *\r
+ * <p>Title: EditCommmand</p>\r
+ *\r
+ * <p>Description: Essential information for performing\r
+ * undo and redo for cut/paste insert/delete gap\r
+ * which can be stored in the HistoryList </p>\r
+ *\r
+ * <p>Copyright: Copyright (c) 2006</p>\r
+ *\r
+ * <p>Company: Dundee University</p>\r
+ *\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
+public class EditCommand implements CommandI\r
+{\r
+ public static String INSERT_GAP = "InsertGap";\r
+ public static String DELETE_GAP = "DeleteGap";\r
+ public static String CUT = "Cut";\r
+ public static String PASTE = "Paste";\r
+\r
+ Edit[] edits;\r
+\r
+ String description;\r
+\r
+ public EditCommand()\r
+ {}\r
+\r
+ public EditCommand(String description)\r
+ {\r
+ this.description = description;\r
+ }\r
+\r
+ public EditCommand(String description,\r
+ String command,\r
+ SequenceI[] seqs,\r
+ int position,\r
+ int number,\r
+ char gapChar)\r
+ {\r
+ this.description = description;\r
+\r
+ if (command.equalsIgnoreCase(INSERT_GAP)\r
+ || command.equalsIgnoreCase(DELETE_GAP))\r
+ {\r
+ edits = new Edit[] { new Edit(command, seqs, position, number, gapChar)};\r
+ }\r
+\r
+ performEdit(0);\r
+ }\r
+\r
+ public EditCommand( String description,\r
+ String command,\r
+ SequenceI[] seqs,\r
+ int position,\r
+ int number,\r
+ AlignmentI al)\r
+ {\r
+ this.description = description;\r
+ if ( command.equalsIgnoreCase(CUT) || command.equalsIgnoreCase(PASTE))\r
+ {\r
+ edits = new Edit[]{new Edit(command, seqs, position, number, al)};\r
+ }\r
+\r
+ performEdit(0);\r
+ }\r
+\r
+\r
+ public String getDescription()\r
+ {\r
+ return description;\r
+ }\r
+\r
+ public int getSize()\r
+ {\r
+ return edits==null?0:edits.length;\r
+ }\r
+\r
+\r
+ public void appendEdit(String command,\r
+ SequenceI[] seqs,\r
+ int position,\r
+ int number,\r
+ char gapChar,\r
+ boolean performEdit)\r
+ {\r
+ Edit edit = new Edit(command, seqs, position, number, gapChar);\r
+\r
+ if (edits != null)\r
+ {\r
+ Edit[] temp = new Edit[edits.length + 1];\r
+ System.arraycopy(edits, 0, temp, 0, edits.length);\r
+ edits = temp;\r
+ edits[edits.length - 1] = edit;\r
+ }\r
+ else\r
+ edits = new Edit[] { edit };\r
+\r
+ if (performEdit)\r
+ performEdit(edits.length - 1);\r
+ }\r
+\r
+ void performEdit(int commandIndex)\r
+ {\r
+ int eSize = edits.length;\r
+ for (int e = commandIndex; e < eSize; e++)\r
+ {\r
+ if (edits[e].command.equals(INSERT_GAP))\r
+ {\r
+ insertGap(edits[e]);\r
+ }\r
+ else if (edits[e].command.equals(DELETE_GAP))\r
+ {\r
+ deleteGap(edits[e]);\r
+ }\r
+ else if(edits[e].command.equals(CUT))\r
+ {\r
+ cut(edits[e]);\r
+ }\r
+ else if(edits[e].command.equals(PASTE))\r
+ {\r
+ paste(edits[e]);\r
+ }\r
+ }\r
+ }\r
+\r
+ public void doCommand()\r
+ {\r
+ performEdit(0);\r
+ }\r
+\r
+ public void undoCommand()\r
+ {\r
+ int e = 0, eSize = edits.length;\r
+ for (e = eSize-1; e > -1; e--)\r
+ {\r
+ if (edits[e].command.equals(INSERT_GAP))\r
+ {\r
+ deleteGap(edits[e]);\r
+ }\r
+ else if (edits[e].command.equals(DELETE_GAP))\r
+ {\r
+ insertGap(edits[e]);\r
+ }\r
+ else if (edits[e].command.equals(CUT))\r
+ {\r
+ paste(edits[e]);\r
+ }\r
+ else if (edits[e].command.equals(PASTE))\r
+ {\r
+ cut(edits[e]);\r
+ }\r
+ }\r
+ }\r
+\r
+ void insertGap(Edit command)\r
+ {\r
+ for(int s=0; s<command.seqs.length; s++)\r
+ {\r
+ command.seqs[s].insertCharAt(command.position,\r
+ command.number,\r
+ command.gapChar);\r
+ }\r
+ }\r
+\r
+ void deleteGap(Edit command)\r
+ {\r
+ for (int s = 0; s < command.seqs.length; s++)\r
+ {\r
+ command.seqs[s].deleteChars(command.position, command.position+command.number);\r
+ }\r
+ }\r
+\r
+ void cut(Edit command)\r
+ {\r
+ command.string = new String [command.seqs.length];\r
+\r
+ for(int i=0; i<command.seqs.length; i++)\r
+ {\r
+ command.string[i] = command.seqs[i].getSequence(command.position,\r
+ command.position + command.number);\r
+\r
+ command.seqs[i].deleteChars(command.position,\r
+ command.position+command.number);\r
+\r
+ if(command.seqs[i].getLength()<1)\r
+ {\r
+ command.al.deleteSequence(command.seqs[i]);\r
+ }\r
+ }\r
+ }\r
+\r
+ void paste(Edit command)\r
+ {\r
+ StringBuffer tmp;\r
+ for(int i=0; i<command.seqs.length; i++)\r
+ {\r
+ if(command.seqs[i].getLength()<1)\r
+ {\r
+ // ie this sequence was deleted, we need to\r
+ // read it to the alignment\r
+ if (command.alIndex[i] < command.al.getHeight())\r
+ command.al.getSequences().insertElementAt(command.seqs[i],\r
+ command.alIndex[i]);\r
+ else\r
+ command.al.addSequence(command.seqs[i]);\r
+ }\r
+ tmp = new StringBuffer(command.seqs[i].getSequence());\r
+ if(command.string!=null)\r
+ {\r
+ tmp.insert(command.position, command.string[i]);\r
+ command.string[i] = null;\r
+ }\r
+ command.seqs[i].setSequence(tmp.toString());\r
+ }\r
+\r
+ command.string = null;\r
+ }\r
+\r
+ class Edit\r
+ {\r
+ AlignmentI al;\r
+ String command;\r
+ String [] string;\r
+ SequenceI[] seqs;\r
+ int [] alIndex;\r
+ int position, number;\r
+ char gapChar;\r
+\r
+ Edit(String command,\r
+ SequenceI[] seqs,\r
+ int position,\r
+ int number,\r
+ char gapChar)\r
+ {\r
+ this.command = command;\r
+ this.seqs = seqs;\r
+ this.position = position;\r
+ this.number = number;\r
+ this.gapChar = gapChar;\r
+ }\r
+\r
+\r
+ Edit(String command,\r
+ SequenceI[] seqs,\r
+ int position,\r
+ int number,\r
+ AlignmentI al)\r
+ {\r
+ this.command = command;\r
+ this.seqs = seqs;\r
+ this.position = position;\r
+ this.number = number;\r
+ this.al = al;\r
+ alIndex = new int[seqs.length];\r
+ for(int i=0; i<seqs.length; i++)\r
+ alIndex[i] = al.findIndex(seqs[i]);\r
+ }\r
+\r
+ }\r
+\r
+}\r