Wrap alignment with annotations
[jalview.git] / src / jalview / appletgui / AlignFrame.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 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 \r
20 package jalview.appletgui;\r
21 \r
22 import jalview.jbappletgui.GAlignFrame;\r
23 import jalview.schemes.*;\r
24 import jalview.datamodel.*;\r
25 import jalview.analysis.*;\r
26 import jalview.io.*;\r
27 import java.awt.*;\r
28 import java.awt.event.*;\r
29 import java.util.*;\r
30 import java.io.InputStreamReader;\r
31 import java.io.BufferedReader;\r
32 \r
33 public class AlignFrame\r
34     extends GAlignFrame\r
35 {\r
36   final AlignmentPanel alignPanel;\r
37   final AlignViewport viewport;\r
38   public static int NEW_WINDOW_WIDTH = 700;\r
39   public static int NEW_WINDOW_HEIGHT = 500;\r
40   jalview.bin.JalviewLite applet;\r
41 \r
42 \r
43   public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet)\r
44   {\r
45     this.applet = applet;\r
46     viewport = new AlignViewport(al, applet);\r
47     alignPanel = new AlignmentPanel(this, viewport);\r
48     add(alignPanel);\r
49     alignPanel.validate();\r
50 \r
51     if(applet!=null)\r
52     {\r
53       String treeFile = applet.getParameter("treeFile");\r
54       if (treeFile != null)\r
55       {\r
56         try\r
57         {\r
58           treeFile = treeFile;\r
59           jalview.io.NewickFile fin = new jalview.io.NewickFile(applet.\r
60               getCodeBase() + treeFile, "URL");\r
61           fin.parse();\r
62 \r
63           if (fin.getTree() != null)\r
64           {\r
65             TreePanel tp = null;\r
66             tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
67                                fin, "FromFile", applet.getCodeBase() + treeFile);\r
68             jalview.bin.JalviewLite.addFrame(tp, treeFile, 600, 500);\r
69             addTreeMenuItem(tp, treeFile);\r
70           }\r
71         }\r
72         catch (Exception ex)\r
73         {\r
74           ex.printStackTrace();\r
75         }\r
76       }\r
77 \r
78       String param = applet.getParameter("sortBy");\r
79       if (param != null)\r
80       {\r
81         if (param.equalsIgnoreCase("Id"))\r
82           sortIDMenuItem_actionPerformed(null);\r
83         else if (param.equalsIgnoreCase("Pairwise Identity"))\r
84           sortPairwiseMenuItem_actionPerformed(null);\r
85       }\r
86 \r
87       param = applet.getParameter("wrap");\r
88       if (param != null)\r
89       {\r
90         if (param.equalsIgnoreCase("true"))\r
91         {\r
92           wrapMenuItem.setState(true);\r
93           wrapMenuItem_actionPerformed(null);\r
94         }\r
95       }\r
96     }\r
97 \r
98     this.addWindowListener(new WindowAdapter()\r
99     {\r
100       public void windowClosing(WindowEvent e)\r
101           {\r
102             closeMenuItem_actionPerformed(null);\r
103           }\r
104     });\r
105 \r
106     viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
107     {\r
108      public void propertyChange(java.beans.PropertyChangeEvent evt)\r
109      {\r
110        if (evt.getPropertyName().equals("alignment"))\r
111        {\r
112          alignmentChanged();\r
113        }\r
114      }\r
115    });\r
116   }\r
117 \r
118   public void inputText_actionPerformed(ActionEvent e)\r
119   {\r
120     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, applet);\r
121     Frame frame = new Frame();\r
122     frame.add(cap);\r
123     jalview.bin.JalviewLite.addFrame(frame, "Cut & Paste Input", 500, 500);\r
124   }\r
125 \r
126   protected void outputText_actionPerformed(ActionEvent e)\r
127   {\r
128     CutAndPasteTransfer cap = new CutAndPasteTransfer(false, applet);\r
129     Frame frame = new Frame();\r
130     frame.add(cap);\r
131     jalview.bin.JalviewLite.addFrame(frame,\r
132                                      "Alignment output - " + e.getActionCommand(),\r
133                                      600, 500);\r
134     cap.setText(new FormatAdapter().formatSequences(e.getActionCommand(),\r
135                                               viewport.getAlignment().\r
136                                               getSequences()));\r
137   }\r
138 \r
139   public void closeMenuItem_actionPerformed(ActionEvent e)\r
140   {\r
141     PaintRefresher.components.remove(viewport.alignment);\r
142     dispose();\r
143     if(PaintRefresher.components.size()==0 && applet==null)\r
144       System.exit(0);\r
145   }\r
146 \r
147   Stack historyList = new Stack();\r
148   Stack redoList = new Stack();\r
149 \r
150   void updateEditMenuBar()\r
151   {\r
152     if (historyList.size() > 0)\r
153     {\r
154       undoMenuItem.setEnabled(true);\r
155       HistoryItem hi = (HistoryItem) historyList.peek();\r
156       undoMenuItem.setLabel("Undo " + hi.getDescription());\r
157     }\r
158     else\r
159     {\r
160       undoMenuItem.setEnabled(false);\r
161       undoMenuItem.setLabel("Undo");\r
162     }\r
163 \r
164     if (redoList.size() > 0)\r
165     {\r
166       redoMenuItem.setEnabled(true);\r
167       HistoryItem hi = (HistoryItem) redoList.peek();\r
168       redoMenuItem.setLabel("Redo " + hi.getDescription());\r
169     }\r
170     else\r
171     {\r
172       redoMenuItem.setEnabled(false);\r
173       redoMenuItem.setLabel("Redo");\r
174     }\r
175   }\r
176 \r
177   public void addHistoryItem(HistoryItem hi)\r
178   {\r
179     historyList.push(hi);\r
180     updateEditMenuBar();\r
181   }\r
182 \r
183   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
184   {\r
185     HistoryItem hi = (HistoryItem) historyList.pop();\r
186     redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment,\r
187                                   HistoryItem.HIDE));\r
188     restoreHistoryItem(hi);\r
189     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
190   }\r
191 \r
192   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
193   {\r
194     HistoryItem hi = (HistoryItem) redoList.pop();\r
195     restoreHistoryItem(hi);\r
196     updateEditMenuBar();\r
197     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
198   }\r
199 \r
200   // used by undo and redo\r
201   void restoreHistoryItem(HistoryItem hi)\r
202   {\r
203     if (hi.getType() == HistoryItem.SORT)\r
204     {\r
205       for (int i = 0; i < hi.getSequences().size(); i++)\r
206       {\r
207         viewport.alignment.getSequences().setElementAt(hi.getSequences().\r
208             elementAt(i), i);\r
209       }\r
210     }\r
211     else\r
212     {\r
213       for (int i = 0; i < hi.getSequences().size(); i++)\r
214       {\r
215         SequenceI restore = (SequenceI) hi.getSequences().elementAt(i);\r
216         if (restore.getLength() == 0)\r
217         {\r
218           // log.System.out.println(hi.getHidden().elementAt(i));\r
219           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
220           viewport.alignment.getSequences().insertElementAt(\r
221               restore,\r
222               hi.getAlignIndex(i));\r
223         }\r
224         else\r
225         {\r
226           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
227         }\r
228       }\r
229       if (hi.getType() == HistoryItem.PASTE)\r
230       {\r
231         for (int i = viewport.alignment.getHeight() - 1;\r
232              i > hi.getSequences().size() - 1; i--)\r
233         {\r
234           viewport.alignment.deleteSequence(i);\r
235         }\r
236       }\r
237     }\r
238 \r
239     updateEditMenuBar();\r
240 \r
241     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
242   }\r
243 \r
244   public void moveSelectedSequences(boolean up)\r
245   {\r
246     SequenceGroup sg = viewport.getSelectionGroup();\r
247     if (sg == null)\r
248     {\r
249       return;\r
250     }\r
251 \r
252     if (up)\r
253     {\r
254       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
255       {\r
256         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
257         if (!sg.sequences.contains(seq))\r
258         {\r
259           continue;\r
260         }\r
261 \r
262         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
263         if (sg.sequences.contains(temp))\r
264         {\r
265           continue;\r
266         }\r
267 \r
268         viewport.alignment.getSequences().setElementAt(temp, i);\r
269         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
270       }\r
271     }\r
272     else\r
273     {\r
274       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
275       {\r
276         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
277         if (!sg.sequences.contains(seq))\r
278         {\r
279           continue;\r
280         }\r
281 \r
282         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
283         if (sg.sequences.contains(temp))\r
284         {\r
285           continue;\r
286         }\r
287 \r
288         viewport.alignment.getSequences().setElementAt(temp, i);\r
289         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
290       }\r
291     }\r
292 \r
293     alignPanel.repaint();\r
294   }\r
295 \r
296   StringBuffer copiedSequences;\r
297   protected void copy_actionPerformed(ActionEvent e)\r
298   {\r
299     if (viewport.getSelectionGroup() == null)\r
300     {\r
301       return;\r
302     }\r
303 \r
304     SequenceGroup sg = viewport.getSelectionGroup();\r
305     copiedSequences = new StringBuffer();\r
306     Hashtable orderedSeqs = new Hashtable();\r
307     for (int i = 0; i < sg.getSize(); i++)\r
308     {\r
309       SequenceI seq = sg.getSequenceAt(i);\r
310       int index = viewport.alignment.findIndex(seq);\r
311       orderedSeqs.put(index + "", seq);\r
312     }\r
313 \r
314     int index = 0, startRes, endRes;\r
315     char ch;\r
316 \r
317     for (int i = 0; i < sg.getSize(); i++)\r
318     {\r
319         SequenceI seq = null;\r
320 \r
321         while (seq == null)\r
322         {\r
323             if (orderedSeqs.containsKey(index + ""))\r
324             {\r
325                 seq = (SequenceI) orderedSeqs.get(index + "");\r
326                 index++;\r
327 \r
328                 break;\r
329             }\r
330             else\r
331             {\r
332                 index++;\r
333             }\r
334         }\r
335 \r
336         //FIND START RES\r
337         //Returns residue following index if gap\r
338         startRes = seq.findPosition(sg.getStartRes());\r
339 \r
340         //FIND END RES\r
341         //Need to find the residue preceeding index if gap\r
342         endRes = 0;\r
343 \r
344         for (int j = 0; j < sg.getEndRes()+1 && j < seq.getLength(); j++)\r
345         {\r
346           ch = seq.getCharAt(j);\r
347           if (!jalview.util.Comparison.isGap( (ch)))\r
348           {\r
349             endRes++;\r
350           }\r
351         }\r
352 \r
353         if(endRes>0)\r
354         {\r
355           endRes += seq.getStart() -1;\r
356         }\r
357 \r
358         copiedSequences.append(seq.getName() + "\t" +\r
359             startRes + "\t" +\r
360             endRes + "\t" +\r
361             seq.getSequence(sg.getStartRes(),\r
362                 sg.getEndRes() + 1) + "\n");\r
363     }\r
364 \r
365   }\r
366 \r
367   protected void pasteNew_actionPerformed(ActionEvent e)\r
368   {\r
369     paste(true);\r
370   }\r
371 \r
372   protected void pasteThis_actionPerformed(ActionEvent e)\r
373   {\r
374     addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
375                                    HistoryItem.PASTE));\r
376     paste(false);\r
377   }\r
378 \r
379   void paste(boolean newAlignment)\r
380   {\r
381     try\r
382     {\r
383       if (copiedSequences == null)\r
384       {\r
385         return;\r
386       }\r
387 \r
388       StringTokenizer st = new StringTokenizer(copiedSequences.toString());\r
389       Vector seqs = new Vector();\r
390       while (st.hasMoreElements())\r
391       {\r
392         String name = st.nextToken();\r
393         int start = Integer.parseInt(st.nextToken());\r
394         int end = Integer.parseInt(st.nextToken());\r
395         Sequence sequence = new Sequence(name, st.nextToken(), start, end);\r
396 \r
397         if (!newAlignment)\r
398         {\r
399           viewport.alignment.addSequence(sequence);\r
400         }\r
401         else\r
402         {\r
403           seqs.addElement(sequence);\r
404         }\r
405       }\r
406 \r
407       if (newAlignment)\r
408       {\r
409         SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
410         for (int i = 0; i < seqs.size(); i++)\r
411         {\r
412           newSeqs[i] = (SequenceI) seqs.elementAt(i);\r
413         }\r
414 \r
415         AlignFrame af = new AlignFrame(new Alignment(newSeqs), applet);\r
416         String newtitle = new String("Copied sequences");\r
417         if (getTitle().startsWith("Copied sequences"))\r
418         {\r
419           newtitle = getTitle();\r
420         }\r
421         else\r
422         {\r
423           newtitle = newtitle.concat("- from " + getTitle());\r
424         }\r
425         jalview.bin.JalviewLite.addFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
426                                          NEW_WINDOW_HEIGHT);\r
427       }\r
428       else\r
429       {\r
430         viewport.setEndSeq(viewport.alignment.getHeight());\r
431         viewport.alignment.getWidth();\r
432         viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
433       }\r
434 \r
435     }\r
436     catch (Exception ex)\r
437     {} // could be anything being pasted in here\r
438 \r
439   }\r
440 \r
441   protected void cut_actionPerformed(ActionEvent e)\r
442   {\r
443     copy_actionPerformed(null);\r
444     delete_actionPerformed(null);\r
445   }\r
446 \r
447   protected void delete_actionPerformed(ActionEvent e)\r
448   {\r
449     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
450                                    HistoryItem.HIDE));\r
451     if (viewport.getSelectionGroup() == null)\r
452     {\r
453       return;\r
454     }\r
455 \r
456 \r
457     SequenceGroup sg = viewport.getSelectionGroup();\r
458     boolean allSequences = false;\r
459     if(sg.sequences.size()==viewport.alignment.getHeight())\r
460           allSequences = true;\r
461 \r
462     for (int i = 0; i < sg.sequences.size(); i++)\r
463     {\r
464       SequenceI seq = sg.getSequenceAt(i);\r
465       int index = viewport.getAlignment().findIndex(seq);\r
466       seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
467 \r
468       // If the cut affects all sequences, remove highlighted columns\r
469       if (allSequences)\r
470       {\r
471         viewport.getColumnSelection().removeElements(sg.getStartRes(),\r
472                                                      sg.getEndRes() + 1);\r
473       }\r
474 \r
475 \r
476       if (seq.getSequence().length() < 1)\r
477       {\r
478         viewport.getAlignment().deleteSequence(seq);\r
479       }\r
480       else\r
481       {\r
482         viewport.getAlignment().getSequences().setElementAt(seq, index);\r
483       }\r
484     }\r
485 \r
486     viewport.setSelectionGroup(null);\r
487     viewport.alignment.deleteGroup(sg);\r
488     viewport.resetSeqLimits(alignPanel.seqPanel.seqCanvas.getSize().height);\r
489     if (viewport.getAlignment().getHeight() < 1)\r
490     {\r
491       try\r
492       {\r
493         this.setVisible(false);\r
494       }\r
495       catch (Exception ex)\r
496       {}\r
497     }\r
498     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
499 \r
500   }\r
501 \r
502   protected void deleteGroups_actionPerformed(ActionEvent e)\r
503   {\r
504     viewport.alignment.deleteAllGroups();\r
505     viewport.setSelectionGroup(null);\r
506 \r
507     alignPanel.repaint();\r
508   }\r
509 \r
510   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
511   {\r
512     SequenceGroup sg = new SequenceGroup();\r
513     for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)\r
514     {\r
515       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
516     }\r
517     sg.setEndRes(viewport.alignment.getWidth()-1);\r
518     viewport.setSelectionGroup(sg);\r
519     alignPanel.repaint();\r
520     PaintRefresher.Refresh(null, viewport.alignment);\r
521   }\r
522 \r
523   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
524   {\r
525     viewport.setSelectionGroup(null);\r
526     viewport.getColumnSelection().clear();\r
527     viewport.setSelectionGroup(null);\r
528     alignPanel.repaint();\r
529     PaintRefresher.Refresh(null, viewport.alignment);\r
530   }\r
531 \r
532   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
533   {\r
534     SequenceGroup sg = viewport.getSelectionGroup();\r
535     for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)\r
536     {\r
537       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
538     }\r
539 \r
540     PaintRefresher.Refresh(null, viewport.alignment);\r
541   }\r
542 \r
543   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
544   {\r
545     ColumnSelection colSel = viewport.getColumnSelection();\r
546     if (colSel.size() > 0)\r
547     {\r
548       addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
549                                      HistoryItem.HIDE));\r
550       int min = colSel.getMin();\r
551       viewport.getAlignment().trimLeft(min);\r
552       colSel.compensateForEdit(0, min);\r
553 \r
554       if (viewport.getSelectionGroup() != null)\r
555       {\r
556         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
557       }\r
558 \r
559       Vector groups = viewport.alignment.getGroups();\r
560       for (int i = 0; i < groups.size(); i++)\r
561       {\r
562         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
563         if (!sg.adjustForRemoveLeft(min))\r
564         {\r
565           viewport.alignment.deleteGroup(sg);\r
566         }\r
567       }\r
568       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
569     }\r
570   }\r
571 \r
572   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
573   {\r
574     ColumnSelection colSel = viewport.getColumnSelection();\r
575     if (colSel.size() > 0)\r
576     {\r
577       addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
578                                      HistoryItem.HIDE));\r
579       int max = colSel.getMax();\r
580       viewport.getAlignment().trimRight(max);\r
581       if (viewport.getSelectionGroup() != null)\r
582       {\r
583         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
584       }\r
585 \r
586       Vector groups = viewport.alignment.getGroups();\r
587       for (int i = 0; i < groups.size(); i++)\r
588       {\r
589         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
590         if (!sg.adjustForRemoveRight(max))\r
591         {\r
592           viewport.alignment.deleteGroup(sg);\r
593         }\r
594       }\r
595       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
596     }\r
597 \r
598   }\r
599 \r
600   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
601   {\r
602     addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
603                                    viewport.alignment,\r
604                                    HistoryItem.HIDE));\r
605 \r
606     //This is to maintain viewport position on first residue\r
607     //of first sequence\r
608     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
609     int startRes = seq.findPosition(viewport.startRes);\r
610 \r
611     viewport.getAlignment().removeGaps();\r
612 \r
613     viewport.setStartRes(seq.findIndex(startRes)-1);\r
614 \r
615     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
616   }\r
617 \r
618   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
619   {\r
620     addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
621                                    HistoryItem.HIDE));\r
622 \r
623     //This is to maintain viewport position on first residue\r
624     //of first sequence\r
625     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
626     int startRes = seq.findPosition(viewport.startRes);\r
627 \r
628     SequenceI current;\r
629     int jSize;\r
630 \r
631     Vector seqs=null;\r
632 \r
633     int start=0, end = viewport.alignment.getWidth();\r
634 \r
635     if (viewport.getSelectionGroup() != null\r
636         && viewport.getSelectionGroup().sequences != null\r
637         && viewport.getSelectionGroup().sequences.size()>0)\r
638     {\r
639       seqs = viewport.getSelectionGroup().sequences;\r
640       start = viewport.getSelectionGroup().getStartRes();\r
641       end = viewport.getSelectionGroup().getEndRes()+1;\r
642     }\r
643     else\r
644       seqs = viewport.alignment.getSequences();\r
645 \r
646     for (int i = 0; i < seqs.size(); i++)\r
647     {\r
648       current = (SequenceI) seqs.elementAt(i);\r
649       jSize = current.getLength();\r
650 \r
651       // Removing a range is much quicker than removing gaps\r
652       // one by one for long sequences\r
653       int j = start;\r
654       int rangeStart=-1, rangeEnd=-1;\r
655 \r
656       do\r
657       {\r
658         if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
659         {\r
660           if(rangeStart==-1)\r
661            {\r
662              rangeStart = j;\r
663              rangeEnd = j+1;\r
664            }\r
665            else\r
666            {\r
667              rangeEnd++;\r
668            }\r
669            j++;\r
670         }\r
671         else\r
672         {\r
673           if(rangeStart>-1)\r
674           {\r
675             current.deleteChars(rangeStart, rangeEnd);\r
676             j-=rangeEnd-rangeStart;\r
677             jSize-=rangeEnd-rangeStart;\r
678             rangeStart = -1;\r
679             rangeEnd = -1;\r
680           }\r
681           else\r
682             j++;\r
683         }\r
684       }\r
685       while (j < end && j < jSize);\r
686       if(rangeStart>-1)\r
687       {\r
688        current.deleteChars(rangeStart, rangeEnd);\r
689       }\r
690     }\r
691     viewport.setStartRes(seq.findIndex(startRes)-1);\r
692     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
693   }\r
694 \r
695   public void alignmentChanged()\r
696   {\r
697     viewport.updateConsensus();\r
698     viewport.updateConservation ();\r
699     resetAllColourSchemes();\r
700     if(alignPanel.overviewPanel!=null)\r
701       alignPanel.overviewPanel.updateOverviewImage();\r
702     alignPanel.repaint();\r
703   }\r
704 \r
705   void resetAllColourSchemes()\r
706   {\r
707     ColourSchemeI cs = viewport.globalColourScheme;\r
708     if(cs!=null)\r
709     {\r
710       if (cs instanceof ClustalxColourScheme)\r
711       {\r
712         ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).\r
713             resetClustalX(viewport.alignment.getSequences(),\r
714                           viewport.alignment.getWidth());\r
715       }\r
716 \r
717       cs.setConsensus(viewport.vconsensus);\r
718       if (cs.conservationApplied())\r
719       {\r
720         Alignment al = (Alignment) viewport.alignment;\r
721         Conservation c = new Conservation("All",\r
722                                           ResidueProperties.propHash, 3,\r
723                                           al.getSequences(), 0,\r
724                                           al.getWidth() - 1);\r
725         c.calculate();\r
726         c.verdict(false, viewport.ConsPercGaps);\r
727 \r
728         cs.setConservation(c);\r
729       }\r
730     }\r
731 \r
732     int s, sSize = viewport.alignment.getGroups().size();\r
733     for(s=0; s<sSize; s++)\r
734     {\r
735       SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);\r
736       if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)\r
737       {\r
738         ((ClustalxColourScheme)sg.cs).resetClustalX(sg.sequences, sg.getWidth());\r
739       }\r
740       sg.recalcConservation();\r
741     }\r
742   }\r
743 \r
744 \r
745 \r
746   public void findMenuItem_actionPerformed(ActionEvent e)\r
747   {\r
748     Finder finder = new Finder(alignPanel);\r
749   }\r
750 \r
751   public void font_actionPerformed(ActionEvent e)\r
752   {\r
753     new FontChooser(alignPanel);\r
754   }\r
755 \r
756   protected void fullSeqId_actionPerformed(ActionEvent e)\r
757   {\r
758     viewport.setShowFullId(fullSeqId.getState());\r
759     alignPanel.fontChanged();\r
760     alignPanel.repaint();\r
761   }\r
762 \r
763   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
764   {\r
765     viewport.setColourText(colourTextMenuItem.getState());\r
766     alignPanel.repaint();\r
767   }\r
768 \r
769   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
770   {\r
771     viewport.setWrapAlignment(wrapMenuItem.getState());\r
772     alignPanel.setWrapAlignment(wrapMenuItem.getState());\r
773     scaleAbove.setEnabled(wrapMenuItem.getState());\r
774     scaleLeft.setEnabled(wrapMenuItem.getState());\r
775     scaleRight.setEnabled(wrapMenuItem.getState());\r
776     alignPanel.repaint();\r
777   }\r
778 \r
779   protected void scaleAbove_actionPerformed(ActionEvent e)\r
780   {\r
781     viewport.setScaleAboveWrapped(scaleAbove.getState());\r
782     alignPanel.repaint();\r
783   }\r
784 \r
785   protected void scaleLeft_actionPerformed(ActionEvent e)\r
786   {\r
787     viewport.setScaleLeftWrapped(scaleLeft.getState());\r
788     alignPanel.repaint();\r
789   }\r
790 \r
791   protected void scaleRight_actionPerformed(ActionEvent e)\r
792   {\r
793     viewport.setScaleRightWrapped(scaleRight.getState());\r
794     alignPanel.repaint();\r
795   }\r
796 \r
797   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
798   {\r
799     viewport.setShowBoxes(viewBoxesMenuItem.getState());\r
800     alignPanel.repaint();\r
801   }\r
802 \r
803   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
804   {\r
805     viewport.setShowText(viewTextMenuItem.getState());\r
806     alignPanel.repaint();\r
807   }\r
808 \r
809   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
810   {\r
811     viewport.setRenderGaps(renderGapsMenuItem.getState());\r
812     alignPanel.repaint();\r
813   }\r
814 \r
815   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
816   {\r
817     viewport.setShowAnnotation(annotationPanelMenuItem.getState());\r
818     alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState());\r
819   }\r
820 \r
821   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
822   {\r
823     if (alignPanel.overviewPanel != null)\r
824     {\r
825       return;\r
826     }\r
827 \r
828     Frame frame = new Frame();\r
829     OverviewPanel overview = new OverviewPanel(alignPanel);\r
830     frame.add(overview);\r
831     // +50 must allow for applet frame window\r
832     jalview.bin.JalviewLite.addFrame(frame, "Overview " + this.getTitle(),\r
833                                      overview.preferredSize().width,\r
834                                      overview.preferredSize().height + 50);\r
835 \r
836     frame.pack();\r
837     frame.addWindowListener(new WindowAdapter()\r
838     {\r
839       public void windowClosing(WindowEvent e)\r
840       {\r
841         alignPanel.setOverviewPanel(null);\r
842       };\r
843     });\r
844 \r
845     alignPanel.setOverviewPanel(overview);\r
846 \r
847   }\r
848 \r
849   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
850   {\r
851     changeColour(null);\r
852   }\r
853 \r
854   public void clustalColour_actionPerformed(ActionEvent e)\r
855   {\r
856     abovePIDThreshold.setState(false);\r
857     changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(),\r
858                                           viewport.alignment.getWidth()));\r
859   }\r
860 \r
861   public void zappoColour_actionPerformed(ActionEvent e)\r
862   {\r
863     changeColour(new ZappoColourScheme());\r
864   }\r
865 \r
866   public void taylorColour_actionPerformed(ActionEvent e)\r
867   {\r
868     changeColour(new TaylorColourScheme());\r
869   }\r
870 \r
871   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
872   {\r
873     changeColour(new HydrophobicColourScheme());\r
874   }\r
875 \r
876   public void helixColour_actionPerformed(ActionEvent e)\r
877   {\r
878     changeColour(new HelixColourScheme());\r
879   }\r
880 \r
881   public void strandColour_actionPerformed(ActionEvent e)\r
882   {\r
883     changeColour(new StrandColourScheme());\r
884   }\r
885 \r
886   public void turnColour_actionPerformed(ActionEvent e)\r
887   {\r
888     changeColour(new TurnColourScheme());\r
889   }\r
890 \r
891   public void buriedColour_actionPerformed(ActionEvent e)\r
892   {\r
893     changeColour(new BuriedColourScheme());\r
894   }\r
895 \r
896   public void nucleotideColour_actionPerformed(ActionEvent e)\r
897   {\r
898     changeColour(new NucleotideColourScheme());\r
899   }\r
900 \r
901   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
902   {\r
903     viewport.setColourAppliesToAllGroups(applyToAllGroups.getState());\r
904   }\r
905 \r
906   void changeColour(ColourSchemeI cs)\r
907   {\r
908     int threshold = 0;\r
909 \r
910     if(cs!=null)\r
911     {\r
912       if (viewport.getAbovePIDThreshold())\r
913       {\r
914         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");\r
915 \r
916         cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());\r
917 \r
918         viewport.setGlobalColourScheme(cs);\r
919       }\r
920       else\r
921       {\r
922         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
923       }\r
924 \r
925       if (viewport.getConservationSelected())\r
926       {\r
927 \r
928         Alignment al = (Alignment) viewport.alignment;\r
929         Conservation c = new Conservation("All",\r
930                                           ResidueProperties.propHash, 3,\r
931                                           al.getSequences(), 0,\r
932                                           al.getWidth() - 1);\r
933 \r
934         c.calculate();\r
935         c.verdict(false, viewport.ConsPercGaps);\r
936 \r
937         cs.setConservation(c);\r
938 \r
939         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
940             "Background"));\r
941 \r
942       }\r
943       else\r
944       {\r
945         cs.setConservation(null);\r
946       }\r
947 \r
948       cs.setConsensus(viewport.vconsensus);\r
949 \r
950     }\r
951     viewport.setGlobalColourScheme(cs);\r
952 \r
953     if (viewport.getColourAppliesToAllGroups())\r
954     {\r
955       Vector groups = viewport.alignment.getGroups();\r
956       for (int i = 0; i < groups.size(); i++)\r
957       {\r
958         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
959 \r
960         if(cs==null)\r
961         {\r
962           sg.cs = null;\r
963           continue;\r
964         }\r
965         if (cs instanceof ClustalxColourScheme)\r
966         {\r
967           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
968         }\r
969         else\r
970         {\r
971           try\r
972           {\r
973             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
974           }\r
975           catch (Exception ex)\r
976           {\r
977             ex.printStackTrace();\r
978             sg.cs = cs;\r
979           }\r
980         }\r
981 \r
982         if (viewport.getAbovePIDThreshold()\r
983             || cs instanceof PIDColourScheme\r
984             || cs instanceof Blosum62ColourScheme)\r
985         {\r
986           sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());\r
987           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
988         }\r
989         else\r
990           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
991 \r
992         if (viewport.getConservationSelected())\r
993         {\r
994           Conservation c = new Conservation("Group",\r
995                                             ResidueProperties.propHash, 3,\r
996                                             sg.sequences, 0,\r
997                                             viewport.alignment.getWidth() - 1);\r
998           c.calculate();\r
999           c.verdict(false, viewport.ConsPercGaps);\r
1000           sg.cs.setConservation(c);\r
1001         }\r
1002         else\r
1003         {\r
1004           sg.cs.setConservation(null);\r
1005           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1006         }\r
1007 \r
1008       }\r
1009     }\r
1010 \r
1011 \r
1012     if (alignPanel.getOverviewPanel() != null)\r
1013     {\r
1014       alignPanel.getOverviewPanel().updateOverviewImage();\r
1015     }\r
1016 \r
1017     alignPanel.repaint();\r
1018   }\r
1019 \r
1020 \r
1021 \r
1022   protected void modifyPID_actionPerformed(ActionEvent e)\r
1023   {\r
1024     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
1025     {\r
1026       SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),\r
1027                                      "Background");\r
1028       SliderPanel.showPIDSlider();\r
1029     }\r
1030   }\r
1031 \r
1032   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1033   {\r
1034     if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
1035     {\r
1036       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,\r
1037                                         "Background");\r
1038       SliderPanel.showConservationSlider();\r
1039     }\r
1040   }\r
1041 \r
1042   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1043   {\r
1044     viewport.setConservationSelected(conservationMenuItem.getState());\r
1045 \r
1046     viewport.setAbovePIDThreshold(false);\r
1047     abovePIDThreshold.setState(false);\r
1048 \r
1049     changeColour(viewport.getGlobalColourScheme());\r
1050 \r
1051     modifyConservation_actionPerformed(null);\r
1052   }\r
1053 \r
1054   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1055   {\r
1056     viewport.setAbovePIDThreshold(abovePIDThreshold.getState());\r
1057 \r
1058     conservationMenuItem.setState(false);\r
1059     viewport.setConservationSelected(false);\r
1060 \r
1061     changeColour(viewport.getGlobalColourScheme());\r
1062 \r
1063     modifyPID_actionPerformed(null);\r
1064   }\r
1065 \r
1066   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1067   {\r
1068     UserDefinedColours chooser = new UserDefinedColours(alignPanel, null);\r
1069   }\r
1070 \r
1071   public void PIDColour_actionPerformed(ActionEvent e)\r
1072   {\r
1073     changeColour(new PIDColourScheme());\r
1074   }\r
1075 \r
1076   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1077   {\r
1078     changeColour(new Blosum62ColourScheme());\r
1079   }\r
1080 \r
1081   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1082   {\r
1083     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1084                                    HistoryItem.SORT));\r
1085     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1086                               viewport.getAlignment().getSequenceAt(0));\r
1087     alignPanel.repaint();\r
1088   }\r
1089 \r
1090   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1091   {\r
1092     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1093                                    HistoryItem.SORT));\r
1094     AlignmentSorter.sortByID(viewport.getAlignment());\r
1095     alignPanel.repaint();\r
1096   }\r
1097 \r
1098   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1099   {\r
1100     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1101                                    HistoryItem.SORT));\r
1102     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1103     alignPanel.repaint();\r
1104 \r
1105   }\r
1106 \r
1107   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1108   {\r
1109     RedundancyPanel sp = new RedundancyPanel(alignPanel);\r
1110     Frame frame = new Frame();\r
1111     frame.add(sp);\r
1112     jalview.bin.JalviewLite.addFrame(frame, "Redundancy threshold selection",\r
1113                                      400, 120);\r
1114 \r
1115   }\r
1116 \r
1117   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1118   {\r
1119     if (viewport.getSelectionGroup().getSize() > 1)\r
1120     {\r
1121       Frame frame = new Frame();\r
1122       frame.add(new PairwiseAlignPanel(alignPanel));\r
1123       jalview.bin.JalviewLite.addFrame(frame, "Pairwise Alignment", 600, 500);\r
1124     }\r
1125   }\r
1126 \r
1127   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1128   {\r
1129     //are the sequences aligned?\r
1130     if (!viewport.alignment.isAligned())\r
1131     {\r
1132       SequenceI current;\r
1133       int Width = viewport.getAlignment().getWidth();\r
1134 \r
1135       for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
1136            i++)\r
1137       {\r
1138         current = viewport.getAlignment().getSequenceAt(i);\r
1139 \r
1140         if (current.getLength() < Width)\r
1141         {\r
1142           current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
1143         }\r
1144       }\r
1145       alignPanel.repaint();\r
1146     }\r
1147 \r
1148     if ( (viewport.getSelectionGroup() != null &&\r
1149           viewport.getSelectionGroup().getSize() < 4 &&\r
1150           viewport.getSelectionGroup().getSize() > 0)\r
1151         || viewport.getAlignment().getHeight() < 4)\r
1152     {\r
1153       return;\r
1154     }\r
1155 \r
1156     try\r
1157     {\r
1158       new PCAPanel(viewport);\r
1159     }\r
1160     catch (java.lang.OutOfMemoryError ex)\r
1161     {\r
1162     }\r
1163 \r
1164   }\r
1165 \r
1166   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1167   {\r
1168     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1169   }\r
1170 \r
1171   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1172   {\r
1173     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1174   }\r
1175 \r
1176   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1177   {\r
1178     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1179   }\r
1180 \r
1181   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1182   {\r
1183     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62PID");\r
1184   }\r
1185 \r
1186   void NewTreePanel(String type, String pwType, String title)\r
1187   {\r
1188     //are the sequences aligned?\r
1189     if (!viewport.alignment.isAligned())\r
1190     {\r
1191       SequenceI current;\r
1192       int Width = viewport.getAlignment().getWidth();\r
1193 \r
1194       for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
1195            i++)\r
1196       {\r
1197         current = viewport.getAlignment().getSequenceAt(i);\r
1198 \r
1199         if (current.getLength() < Width)\r
1200         {\r
1201           current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
1202         }\r
1203       }\r
1204       alignPanel.repaint();\r
1205 \r
1206     }\r
1207 \r
1208     final TreePanel tp;\r
1209     if (viewport.getSelectionGroup() != null &&\r
1210         viewport.getSelectionGroup().getSize() > 3)\r
1211     {\r
1212       tp = new TreePanel(viewport, viewport.getSelectionGroup().sequences, type,\r
1213                          pwType,\r
1214                          0, viewport.alignment.getWidth());\r
1215     }\r
1216     else\r
1217     {\r
1218       tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
1219                          type, pwType, 0, viewport.alignment.getWidth());\r
1220     }\r
1221 \r
1222     addTreeMenuItem(tp, title);\r
1223 \r
1224     jalview.bin.JalviewLite.addFrame(tp, title, 600, 500);\r
1225   }\r
1226 \r
1227   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1228   {\r
1229     final MenuItem item = new MenuItem(title);\r
1230     sortByTreeMenu.add(item);\r
1231     item.addActionListener(new java.awt.event.ActionListener()\r
1232     {\r
1233       public void actionPerformed(ActionEvent e)\r
1234       {\r
1235         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
1236                                        HistoryItem.SORT));\r
1237         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());\r
1238         alignPanel.repaint();\r
1239       }\r
1240     });\r
1241 \r
1242     treePanel.addWindowListener(new WindowAdapter()\r
1243     {\r
1244       public void windowClosing(WindowEvent e)\r
1245       {\r
1246         sortByTreeMenu.remove(item);\r
1247       };\r
1248     });\r
1249   }\r
1250 \r
1251   protected void documentation_actionPerformed(ActionEvent e)\r
1252   {\r
1253     jalview.bin.JalviewLite.showURL("http://www.jalview.org/help.html");\r
1254   }\r
1255 \r
1256   protected void about_actionPerformed(ActionEvent e)\r
1257   {\r
1258 \r
1259     class AboutPanel extends Canvas\r
1260     {\r
1261       String version;\r
1262       public AboutPanel(String version)\r
1263       { this.version = version; }\r
1264 \r
1265       public void paint(Graphics g)\r
1266       {\r
1267         g.setColor(Color.white);\r
1268         g.fillRect(0, 0, getSize().width, getSize().height);\r
1269         g.setFont(new Font("Helvetica", Font.PLAIN, 12));\r
1270         FontMetrics fm = g.getFontMetrics();\r
1271         int fh = fm.getHeight();\r
1272         int y = 5, x = 7;\r
1273         g.setColor(Color.black);\r
1274         g.setFont(new Font("Helvetica", Font.BOLD, 14));\r
1275         g.drawString("Jalview - Release "+version, 200, y += fh);\r
1276         g.setFont(new Font("Helvetica", Font.PLAIN, 12));\r
1277         g.drawString("Authors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",\r
1278                      x, y += fh * 2);\r
1279         g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",\r
1280                      x, y += fh);\r
1281         g.drawString(\r
1282             "For any issues relating to Jalview, email help@jalview.org", x,\r
1283             y += fh);\r
1284         g.drawString("If  you use JalView, please cite:", x, y += fh + 8);\r
1285         g.drawString("\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"",\r
1286                      x, y += fh);\r
1287         g.drawString("Bioinformatics,  2004 12;426-7.", x, y += fh);\r
1288       }\r
1289     }\r
1290 \r
1291     String version = "test";\r
1292     java.net.URL url = getClass().getResource("/.build_properties");\r
1293     if (url != null)\r
1294     {\r
1295       try\r
1296       {\r
1297         BufferedReader reader = new BufferedReader(new InputStreamReader(\r
1298             url.openStream()));\r
1299         String line;\r
1300         while ( (line = reader.readLine()) != null)\r
1301         {\r
1302           if (line.indexOf("VERSION") > -1)\r
1303           {\r
1304             version = line.substring(line.indexOf("=") + 1);\r
1305           }\r
1306         }\r
1307       }\r
1308       catch (Exception ex)\r
1309       {\r
1310         ex.printStackTrace();\r
1311       }\r
1312     }\r
1313 \r
1314 \r
1315     Frame frame = new Frame();\r
1316     frame.add(new AboutPanel(version));\r
1317     jalview.bin.JalviewLite.addFrame(frame, "Jalview", 580, 200);\r
1318 \r
1319   }\r
1320 }\r