check command.string[i] is not null
[jalview.git] / src / jalview / commands / EditCommand.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.commands;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 /**\r
24  *\r
25  * <p>Title: EditCommmand</p>\r
26  *\r
27  * <p>Description: Essential information for performing\r
28  * undo and redo for cut/paste insert/delete gap\r
29  * which can be stored in the HistoryList </p>\r
30  *\r
31  * <p>Copyright: Copyright (c) 2006</p>\r
32  *\r
33  * <p>Company: Dundee University</p>\r
34  *\r
35  * @author not attributable\r
36  * @version 1.0\r
37  */\r
38 public class EditCommand implements CommandI\r
39 {\r
40   public static String INSERT_GAP = "InsertGap";\r
41   public static String DELETE_GAP = "DeleteGap";\r
42   public static String CUT = "Cut";\r
43   public static String PASTE = "Paste";\r
44 \r
45   Edit[] edits;\r
46 \r
47   String description;\r
48 \r
49   public EditCommand()\r
50   {}\r
51 \r
52   public EditCommand(String description)\r
53   {\r
54     this.description = description;\r
55   }\r
56 \r
57   public EditCommand(String description,\r
58                      String command,\r
59                      SequenceI[] seqs,\r
60                      int position,\r
61                      int number,\r
62                      char gapChar)\r
63   {\r
64     this.description = description;\r
65 \r
66     if (command.equalsIgnoreCase(INSERT_GAP)\r
67         || command.equalsIgnoreCase(DELETE_GAP))\r
68     {\r
69       edits = new Edit[] { new Edit(command, seqs, position, number, gapChar)};\r
70     }\r
71 \r
72     performEdit(0);\r
73   }\r
74 \r
75   public EditCommand( String description,\r
76                       String command,\r
77                       SequenceI[] seqs,\r
78                       int position,\r
79                       int number,\r
80                       AlignmentI al)\r
81    {\r
82      this.description = description;\r
83      if ( command.equalsIgnoreCase(CUT) || command.equalsIgnoreCase(PASTE))\r
84      {\r
85        edits = new Edit[]{new Edit(command, seqs, position, number, al)};\r
86      }\r
87 \r
88      performEdit(0);\r
89   }\r
90 \r
91 \r
92   public String getDescription()\r
93   {\r
94     return description;\r
95   }\r
96 \r
97   public int getSize()\r
98   {\r
99     return edits==null?0:edits.length;\r
100   }\r
101 \r
102 \r
103   public void appendEdit(String command,\r
104                          SequenceI[] seqs,\r
105                          int position,\r
106                          int number,\r
107                          char gapChar,\r
108                          boolean performEdit)\r
109   {\r
110     Edit edit = new Edit(command, seqs, position, number, gapChar);\r
111 \r
112     if (edits != null)\r
113     {\r
114       Edit[] temp = new Edit[edits.length + 1];\r
115       System.arraycopy(edits, 0, temp, 0, edits.length);\r
116       edits = temp;\r
117       edits[edits.length - 1] = edit;\r
118     }\r
119     else\r
120       edits = new Edit[] {  edit  };\r
121 \r
122     if (performEdit)\r
123       performEdit(edits.length - 1);\r
124   }\r
125 \r
126   void performEdit(int commandIndex)\r
127   {\r
128     int eSize = edits.length;\r
129     for (int e = commandIndex; e < eSize; e++)\r
130     {\r
131       if (edits[e].command.equals(INSERT_GAP))\r
132       {\r
133         insertGap(edits[e]);\r
134       }\r
135       else if (edits[e].command.equals(DELETE_GAP))\r
136       {\r
137         deleteGap(edits[e]);\r
138       }\r
139       else if(edits[e].command.equals(CUT))\r
140       {\r
141         cut(edits[e]);\r
142       }\r
143       else if(edits[e].command.equals(PASTE))\r
144       {\r
145         paste(edits[e]);\r
146       }\r
147     }\r
148   }\r
149 \r
150   public void doCommand()\r
151   {\r
152     performEdit(0);\r
153   }\r
154 \r
155   public void undoCommand()\r
156   {\r
157     int e = 0, eSize = edits.length;\r
158     for (e = eSize-1; e > -1; e--)\r
159     {\r
160       if (edits[e].command.equals(INSERT_GAP))\r
161       {\r
162         deleteGap(edits[e]);\r
163       }\r
164       else if (edits[e].command.equals(DELETE_GAP))\r
165       {\r
166         insertGap(edits[e]);\r
167       }\r
168       else if (edits[e].command.equals(CUT))\r
169       {\r
170         paste(edits[e]);\r
171       }\r
172       else if (edits[e].command.equals(PASTE))\r
173       {\r
174         cut(edits[e]);\r
175       }\r
176     }\r
177   }\r
178 \r
179   void insertGap(Edit command)\r
180   {\r
181     for(int s=0; s<command.seqs.length; s++)\r
182     {\r
183         command.seqs[s].insertCharAt(command.position,\r
184                                      command.number,\r
185                                      command.gapChar);\r
186     }\r
187   }\r
188 \r
189   void deleteGap(Edit command)\r
190   {\r
191     for (int s = 0; s < command.seqs.length; s++)\r
192     {\r
193       command.seqs[s].deleteChars(command.position, command.position+command.number);\r
194     }\r
195   }\r
196 \r
197   void cut(Edit command)\r
198   {\r
199     command.string = new String [command.seqs.length];\r
200 \r
201     for(int i=0; i<command.seqs.length; i++)\r
202     {\r
203       if(command.seqs[i].getLength()>command.position)\r
204       {\r
205         command.string[i] = command.seqs[i].getSequence(command.position,\r
206             command.position + command.number);\r
207 \r
208         System.out.println("CUT:"+command.string[i]+":");\r
209 \r
210         command.seqs[i].deleteChars(command.position,\r
211                                     command.position + command.number);\r
212       }\r
213 \r
214       if(command.seqs[i].getLength()<1)\r
215       {\r
216         command.al.deleteSequence(command.seqs[i]);\r
217       }\r
218     }\r
219   }\r
220 \r
221   void paste(Edit command)\r
222   {\r
223     StringBuffer tmp;\r
224     for(int i=0; i<command.seqs.length; i++)\r
225     {\r
226       if(command.seqs[i].getLength()<1)\r
227       {\r
228         // ie this sequence was deleted, we need to\r
229         // read it to the alignment\r
230         if (command.alIndex[i] < command.al.getHeight())\r
231           command.al.getSequences().insertElementAt(command.seqs[i],\r
232               command.alIndex[i]);\r
233         else\r
234           command.al.addSequence(command.seqs[i]);\r
235       }\r
236       tmp = new StringBuffer(command.seqs[i].getSequence());\r
237 \r
238       if(command.string!=null && command.string[i]!=null)\r
239       {\r
240         tmp.insert(command.position, command.string[i]);\r
241         command.string[i] = null;\r
242       }\r
243       command.seqs[i].setSequence(tmp.toString());\r
244     }\r
245 \r
246     command.string = null;\r
247   }\r
248 \r
249   class Edit\r
250   {\r
251     AlignmentI al;\r
252     String command;\r
253     String [] string;\r
254     SequenceI[] seqs;\r
255     int [] alIndex;\r
256     int position, number;\r
257     char gapChar;\r
258 \r
259     Edit(String command,\r
260          SequenceI[] seqs,\r
261          int position,\r
262          int number,\r
263          char gapChar)\r
264     {\r
265       this.command = command;\r
266       this.seqs = seqs;\r
267       this.position = position;\r
268       this.number = number;\r
269       this.gapChar = gapChar;\r
270     }\r
271 \r
272 \r
273     Edit(String command,\r
274          SequenceI[] seqs,\r
275          int position,\r
276          int number,\r
277          AlignmentI al)\r
278     {\r
279       this.command = command;\r
280       this.seqs = seqs;\r
281       this.position = position;\r
282       this.number = number;\r
283       this.al = al;\r
284       alIndex = new int[seqs.length];\r
285       for(int i=0; i<seqs.length; i++)\r
286         alIndex[i] = al.findIndex(seqs[i]);\r
287     }\r
288 \r
289   }\r
290 \r
291 }\r