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