Sequence is char []
[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 final int INSERT_GAP = 0;\r
41   public static final int DELETE_GAP = 1;\r
42   public static final int CUT = 2;\r
43   public static final int PASTE = 3;\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                      int 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==INSERT_GAP || command==DELETE_GAP)\r
67     {\r
68       edits = new Edit[] { new Edit(command, seqs, position, number, gapChar)};\r
69     }\r
70 \r
71     performEdit(0);\r
72   }\r
73 \r
74   public EditCommand( String description,\r
75                       int command,\r
76                       SequenceI[] seqs,\r
77                       int position,\r
78                       int number,\r
79                       AlignmentI al)\r
80    {\r
81      this.description = description;\r
82      if ( command==CUT || command==PASTE)\r
83      {\r
84        edits = new Edit[]{new Edit(command, seqs, position, number, al)};\r
85      }\r
86 \r
87      performEdit(0);\r
88   }\r
89 \r
90 \r
91   public String getDescription()\r
92   {\r
93     return description;\r
94   }\r
95 \r
96   public int getSize()\r
97   {\r
98     return edits==null?0:edits.length;\r
99   }\r
100 \r
101   public AlignmentI getAlignment()\r
102   {\r
103     return edits[0].al;\r
104   }\r
105 \r
106 \r
107   public void appendEdit(int command,\r
108                          SequenceI[] seqs,\r
109                          int position,\r
110                          int number,\r
111                          char gapChar,\r
112                          boolean performEdit)\r
113   {\r
114     Edit edit = new Edit(command, seqs, position, number, gapChar);\r
115 \r
116     if (edits != null)\r
117     {\r
118       Edit[] temp = new Edit[edits.length + 1];\r
119       System.arraycopy(edits, 0, temp, 0, edits.length);\r
120       edits = temp;\r
121       edits[edits.length - 1] = edit;\r
122     }\r
123     else\r
124       edits = new Edit[] {  edit  };\r
125 \r
126     if (performEdit)\r
127       performEdit(edits.length - 1);\r
128   }\r
129 \r
130   void performEdit(int commandIndex)\r
131   {\r
132     int eSize = edits.length;\r
133     for (int e = commandIndex; e < eSize; e++)\r
134     {\r
135       if (edits[e].command==INSERT_GAP)\r
136       {\r
137         insertGap(edits[e]);\r
138       }\r
139       else if (edits[e].command==DELETE_GAP)\r
140       {\r
141         deleteGap(edits[e]);\r
142       }\r
143       else if(edits[e].command==CUT)\r
144       {\r
145         cut(edits[e]);\r
146       }\r
147       else if(edits[e].command==PASTE)\r
148       {\r
149         paste(edits[e]);\r
150       }\r
151     }\r
152   }\r
153 \r
154   public void doCommand()\r
155   {\r
156     performEdit(0);\r
157   }\r
158 \r
159   public void undoCommand()\r
160   {\r
161     int e = 0, eSize = edits.length;\r
162     for (e = eSize-1; e > -1; e--)\r
163     {\r
164       if (edits[e].command==INSERT_GAP)\r
165       {\r
166         deleteGap(edits[e]);\r
167       }\r
168       else if (edits[e].command==DELETE_GAP)\r
169       {\r
170         insertGap(edits[e]);\r
171       }\r
172       else if (edits[e].command==CUT)\r
173       {\r
174         paste(edits[e]);\r
175       }\r
176       else if (edits[e].command==PASTE)\r
177       {\r
178         cut(edits[e]);\r
179       }\r
180     }\r
181   }\r
182 \r
183   void insertGap(Edit command)\r
184   {\r
185     for(int s=0; s<command.seqs.length; s++)\r
186     {\r
187         command.seqs[s].insertCharAt(command.position,\r
188                                      command.number,\r
189                                      command.gapChar);\r
190     }\r
191   }\r
192 \r
193   void deleteGap(Edit command)\r
194   {\r
195     for (int s = 0; s < command.seqs.length; s++)\r
196     {\r
197       command.seqs[s].deleteChars(command.position, command.position+command.number);\r
198     }\r
199   }\r
200 \r
201   void cut(Edit command)\r
202   {\r
203     command.string = new char [command.seqs.length][];\r
204 \r
205     for(int i=0; i<command.seqs.length; i++)\r
206     {\r
207       if(command.seqs[i].getLength()>command.position)\r
208       {\r
209         command.string[i] = command.seqs[i].getSequence(command.position,\r
210             command.position + command.number);\r
211 \r
212         command.seqs[i].deleteChars(command.position,\r
213                                     command.position + command.number);\r
214       }\r
215 \r
216       if(command.seqs[i].getLength()<1)\r
217       {\r
218         command.al.deleteSequence(command.seqs[i]);\r
219       }\r
220     }\r
221   }\r
222 \r
223   void paste(Edit command)\r
224   {\r
225     StringBuffer tmp;\r
226     for(int i=0; i<command.seqs.length; i++)\r
227     {\r
228       if(command.seqs[i].getLength()<1)\r
229       {\r
230         // ie this sequence was deleted, we need to\r
231         // read it to the alignment\r
232         if (command.alIndex[i] < command.al.getHeight())\r
233           command.al.getSequences().insertElementAt(command.seqs[i],\r
234               command.alIndex[i]);\r
235         else\r
236           command.al.addSequence(command.seqs[i]);\r
237       }\r
238       tmp = new StringBuffer();\r
239       tmp.append(command.seqs[i].getSequence());\r
240 \r
241       if(command.string!=null && command.string[i]!=null)\r
242       {\r
243         if(command.position>=tmp.length())\r
244         {\r
245           //This occurs if padding is on, and residues\r
246           //are removed from end of alignment\r
247           int length = command.position-tmp.length();\r
248           while (length > 0)\r
249           {\r
250             tmp.append(command.gapChar);\r
251             length--;\r
252           }\r
253         }\r
254         tmp.insert(command.position, command.string[i]);\r
255         command.string[i] = null;\r
256       }\r
257       command.seqs[i].setSequence(tmp.toString());\r
258     }\r
259 \r
260     command.string = null;\r
261   }\r
262 \r
263   class Edit\r
264   {\r
265     AlignmentI al;\r
266     int command;\r
267     char [][] string;\r
268     SequenceI[] seqs;\r
269     int [] alIndex;\r
270     int position, number;\r
271     char gapChar;\r
272 \r
273     Edit(int command,\r
274          SequenceI[] seqs,\r
275          int position,\r
276          int number,\r
277          char gapChar)\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.gapChar = gapChar;\r
284     }\r
285 \r
286 \r
287     Edit(int command,\r
288          SequenceI[] seqs,\r
289          int position,\r
290          int number,\r
291          AlignmentI al)\r
292     {\r
293       this.gapChar = al.getGapCharacter();\r
294       this.command = command;\r
295       this.seqs = seqs;\r
296       this.position = position;\r
297       this.number = number;\r
298       this.al = al;\r
299       alIndex = new int[seqs.length];\r
300       for(int i=0; i<seqs.length; i++)\r
301         alIndex[i] = al.findIndex(seqs[i]);\r
302     }\r
303 \r
304   }\r
305 \r
306 }\r