Update overview in alignmentChanged
[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     if(alignPanel.overviewPanel!=null)\r
660       alignPanel.overviewPanel.updateOverviewImage();\r
661     alignPanel.repaint();\r
662   }\r
663 \r
664   void resetAllColourSchemes()\r
665   {\r
666     ColourSchemeI cs = viewport.globalColourScheme;\r
667     if(cs!=null)\r
668     {\r
669       if (cs instanceof ClustalxColourScheme)\r
670       {\r
671         ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).\r
672             resetClustalX(viewport.alignment.getSequences(),\r
673                           viewport.alignment.getWidth());\r
674       }\r
675 \r
676       cs.setConsensus(viewport.vconsensus);\r
677       if (cs.conservationApplied())\r
678       {\r
679         Alignment al = (Alignment) viewport.alignment;\r
680         Conservation c = new Conservation("All",\r
681                                           ResidueProperties.propHash, 3,\r
682                                           al.getSequences(), 0,\r
683                                           al.getWidth() - 1);\r
684         c.calculate();\r
685         c.verdict(false, viewport.ConsPercGaps);\r
686 \r
687         cs.setConservation(c);\r
688       }\r
689     }\r
690 \r
691     int s, sSize = viewport.alignment.getGroups().size();\r
692     for(s=0; s<sSize; s++)\r
693     {\r
694       SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);\r
695       if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)\r
696       {\r
697         ((ClustalxColourScheme)sg.cs).resetClustalX(sg.sequences, sg.getWidth());\r
698       }\r
699       sg.recalcConservation();\r
700     }\r
701   }\r
702 \r
703 \r
704 \r
705   public void findMenuItem_actionPerformed(ActionEvent e)\r
706   {\r
707     Finder finder = new Finder(alignPanel);\r
708   }\r
709 \r
710   public void font_actionPerformed(ActionEvent e)\r
711   {\r
712     Frame frame = new Frame();\r
713     FontChooser fc = new FontChooser(alignPanel, frame);\r
714     frame.add(fc);\r
715     jalview.bin.JalviewLite.addFrame(frame, "Change Font", 440, 100);\r
716 \r
717   }\r
718 \r
719   protected void fullSeqId_actionPerformed(ActionEvent e)\r
720   {\r
721     viewport.setShowFullId(fullSeqId.getState());\r
722     alignPanel.fontChanged();\r
723     alignPanel.repaint();\r
724   }\r
725 \r
726   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
727   {\r
728     viewport.setColourText(colourTextMenuItem.getState());\r
729     alignPanel.repaint();\r
730   }\r
731 \r
732   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
733   {\r
734     viewport.setWrapAlignment(wrapMenuItem.getState());\r
735     alignPanel.setWrapAlignment(wrapMenuItem.getState());\r
736     scaleAbove.setEnabled(wrapMenuItem.getState());\r
737     scaleLeft.setEnabled(wrapMenuItem.getState());\r
738     scaleRight.setEnabled(wrapMenuItem.getState());\r
739     alignPanel.repaint();\r
740   }\r
741 \r
742   protected void scaleAbove_actionPerformed(ActionEvent e)\r
743   {\r
744     viewport.setScaleAboveWrapped(scaleAbove.getState());\r
745     alignPanel.repaint();\r
746   }\r
747 \r
748   protected void scaleLeft_actionPerformed(ActionEvent e)\r
749   {\r
750     viewport.setScaleLeftWrapped(scaleLeft.getState());\r
751     alignPanel.repaint();\r
752   }\r
753 \r
754   protected void scaleRight_actionPerformed(ActionEvent e)\r
755   {\r
756     viewport.setScaleRightWrapped(scaleRight.getState());\r
757     alignPanel.repaint();\r
758   }\r
759 \r
760   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
761   {\r
762     viewport.setShowBoxes(viewBoxesMenuItem.getState());\r
763     alignPanel.repaint();\r
764   }\r
765 \r
766   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
767   {\r
768     viewport.setShowText(viewTextMenuItem.getState());\r
769     alignPanel.repaint();\r
770   }\r
771 \r
772   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
773   {\r
774     viewport.setRenderGaps(renderGapsMenuItem.getState());\r
775     alignPanel.repaint();\r
776   }\r
777 \r
778   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
779   {\r
780     if (annotationPanelMenuItem.getState() && viewport.getWrapAlignment())\r
781     {\r
782       annotationPanelMenuItem.setState(false);\r
783       return;\r
784     }\r
785     viewport.setShowAnnotation(annotationPanelMenuItem.getState());\r
786     alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState());\r
787   }\r
788 \r
789   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
790   {\r
791     if (alignPanel.overviewPanel != null)\r
792     {\r
793       return;\r
794     }\r
795 \r
796     Frame frame = new Frame();\r
797     OverviewPanel overview = new OverviewPanel(alignPanel);\r
798     frame.add(overview);\r
799     // +50 must allow for applet frame window\r
800     jalview.bin.JalviewLite.addFrame(frame, "Overview " + this.getTitle(),\r
801                                      overview.preferredSize().width,\r
802                                      overview.preferredSize().height + 50);\r
803 \r
804     frame.pack();\r
805     frame.addWindowListener(new WindowAdapter()\r
806     {\r
807       public void windowClosing(WindowEvent e)\r
808       {\r
809         alignPanel.setOverviewPanel(null);\r
810       };\r
811     });\r
812 \r
813     alignPanel.setOverviewPanel(overview);\r
814 \r
815   }\r
816 \r
817   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
818   {\r
819     changeColour(null);\r
820   }\r
821 \r
822   public void clustalColour_actionPerformed(ActionEvent e)\r
823   {\r
824     abovePIDThreshold.setState(false);\r
825     changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(),\r
826                                           viewport.alignment.getWidth()));\r
827   }\r
828 \r
829   public void zappoColour_actionPerformed(ActionEvent e)\r
830   {\r
831     changeColour(new ZappoColourScheme());\r
832   }\r
833 \r
834   public void taylorColour_actionPerformed(ActionEvent e)\r
835   {\r
836     changeColour(new TaylorColourScheme());\r
837   }\r
838 \r
839   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
840   {\r
841     changeColour(new HydrophobicColourScheme());\r
842   }\r
843 \r
844   public void helixColour_actionPerformed(ActionEvent e)\r
845   {\r
846     changeColour(new HelixColourScheme());\r
847   }\r
848 \r
849   public void strandColour_actionPerformed(ActionEvent e)\r
850   {\r
851     changeColour(new StrandColourScheme());\r
852   }\r
853 \r
854   public void turnColour_actionPerformed(ActionEvent e)\r
855   {\r
856     changeColour(new TurnColourScheme());\r
857   }\r
858 \r
859   public void buriedColour_actionPerformed(ActionEvent e)\r
860   {\r
861     changeColour(new BuriedColourScheme());\r
862   }\r
863 \r
864   public void nucleotideColour_actionPerformed(ActionEvent e)\r
865   {\r
866     changeColour(new NucleotideColourScheme());\r
867   }\r
868 \r
869   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
870   {\r
871     viewport.setColourAppliesToAllGroups(applyToAllGroups.getState());\r
872   }\r
873 \r
874   void changeColour(ColourSchemeI cs)\r
875   {\r
876     int threshold = 0;\r
877 \r
878     if(cs!=null)\r
879     {\r
880       if (viewport.getAbovePIDThreshold())\r
881       {\r
882         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");\r
883 \r
884         cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());\r
885 \r
886         viewport.setGlobalColourScheme(cs);\r
887       }\r
888       else\r
889       {\r
890         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
891       }\r
892 \r
893       if (viewport.getConservationSelected())\r
894       {\r
895 \r
896         Alignment al = (Alignment) viewport.alignment;\r
897         Conservation c = new Conservation("All",\r
898                                           ResidueProperties.propHash, 3,\r
899                                           al.getSequences(), 0,\r
900                                           al.getWidth() - 1);\r
901 \r
902         c.calculate();\r
903         c.verdict(false, viewport.ConsPercGaps);\r
904 \r
905         cs.setConservation(c);\r
906 \r
907         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
908             "Background"));\r
909 \r
910       }\r
911       else\r
912       {\r
913         cs.setConservation(null);\r
914       }\r
915 \r
916       cs.setConsensus(viewport.vconsensus);\r
917 \r
918     }\r
919     viewport.setGlobalColourScheme(cs);\r
920 \r
921     if (viewport.getColourAppliesToAllGroups())\r
922     {\r
923       Vector groups = viewport.alignment.getGroups();\r
924       for (int i = 0; i < groups.size(); i++)\r
925       {\r
926         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
927 \r
928         if(cs==null)\r
929         {\r
930           sg.cs = null;\r
931           continue;\r
932         }\r
933         if (cs instanceof ClustalxColourScheme)\r
934         {\r
935           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
936         }\r
937         else\r
938         {\r
939           try\r
940           {\r
941             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
942           }\r
943           catch (Exception ex)\r
944           {\r
945             ex.printStackTrace();\r
946             sg.cs = cs;\r
947           }\r
948         }\r
949 \r
950         if (viewport.getAbovePIDThreshold()\r
951             || cs instanceof PIDColourScheme\r
952             || cs instanceof Blosum62ColourScheme)\r
953         {\r
954           sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());\r
955           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
956         }\r
957         else\r
958           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
959 \r
960         if (viewport.getConservationSelected())\r
961         {\r
962           Conservation c = new Conservation("Group",\r
963                                             ResidueProperties.propHash, 3,\r
964                                             sg.sequences, 0,\r
965                                             viewport.alignment.getWidth() - 1);\r
966           c.calculate();\r
967           c.verdict(false, viewport.ConsPercGaps);\r
968           sg.cs.setConservation(c);\r
969         }\r
970         else\r
971         {\r
972           sg.cs.setConservation(null);\r
973           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
974         }\r
975 \r
976       }\r
977     }\r
978 \r
979 \r
980     if (alignPanel.getOverviewPanel() != null)\r
981     {\r
982       alignPanel.getOverviewPanel().updateOverviewImage();\r
983     }\r
984 \r
985     alignPanel.repaint();\r
986   }\r
987 \r
988 \r
989 \r
990   protected void modifyPID_actionPerformed(ActionEvent e)\r
991   {\r
992     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
993     {\r
994       SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),\r
995                                      "Background");\r
996       SliderPanel.showPIDSlider();\r
997     }\r
998   }\r
999 \r
1000   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1001   {\r
1002     if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
1003     {\r
1004       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,\r
1005                                         "Background");\r
1006       SliderPanel.showConservationSlider();\r
1007     }\r
1008   }\r
1009 \r
1010   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1011   {\r
1012     viewport.setConservationSelected(conservationMenuItem.getState());\r
1013 \r
1014     viewport.setAbovePIDThreshold(false);\r
1015     abovePIDThreshold.setState(false);\r
1016 \r
1017     changeColour(viewport.getGlobalColourScheme());\r
1018 \r
1019     modifyConservation_actionPerformed(null);\r
1020   }\r
1021 \r
1022   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1023   {\r
1024     viewport.setAbovePIDThreshold(abovePIDThreshold.getState());\r
1025 \r
1026     conservationMenuItem.setState(false);\r
1027     viewport.setConservationSelected(false);\r
1028 \r
1029     changeColour(viewport.getGlobalColourScheme());\r
1030 \r
1031     modifyPID_actionPerformed(null);\r
1032   }\r
1033 \r
1034   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1035   {\r
1036     UserDefinedColours chooser = new UserDefinedColours(alignPanel, null);\r
1037   }\r
1038 \r
1039   public void PIDColour_actionPerformed(ActionEvent e)\r
1040   {\r
1041     changeColour(new PIDColourScheme());\r
1042   }\r
1043 \r
1044   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1045   {\r
1046     changeColour(new Blosum62ColourScheme());\r
1047   }\r
1048 \r
1049   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1050   {\r
1051     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1052                                    HistoryItem.SORT));\r
1053     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1054                               viewport.getAlignment().getSequenceAt(0));\r
1055     alignPanel.repaint();\r
1056   }\r
1057 \r
1058   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1059   {\r
1060     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1061                                    HistoryItem.SORT));\r
1062     AlignmentSorter.sortByID(viewport.getAlignment());\r
1063     alignPanel.repaint();\r
1064   }\r
1065 \r
1066   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1067   {\r
1068     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1069                                    HistoryItem.SORT));\r
1070     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1071     alignPanel.repaint();\r
1072 \r
1073   }\r
1074 \r
1075   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1076   {\r
1077     RedundancyPanel sp = new RedundancyPanel(alignPanel);\r
1078     Frame frame = new Frame();\r
1079     frame.add(sp);\r
1080     jalview.bin.JalviewLite.addFrame(frame, "Redundancy threshold selection",\r
1081                                      400, 120);\r
1082 \r
1083   }\r
1084 \r
1085   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1086   {\r
1087     if (viewport.getSelectionGroup().getSize() > 1)\r
1088     {\r
1089       Frame frame = new Frame();\r
1090       frame.add(new PairwiseAlignPanel(alignPanel));\r
1091       jalview.bin.JalviewLite.addFrame(frame, "Pairwise Alignment", 600, 500);\r
1092     }\r
1093   }\r
1094 \r
1095   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1096   {\r
1097 \r
1098     if ( (viewport.getSelectionGroup() != null &&\r
1099           viewport.getSelectionGroup().getSize() < 4 &&\r
1100           viewport.getSelectionGroup().getSize() > 0)\r
1101         || viewport.getAlignment().getHeight() < 4)\r
1102     {\r
1103       return;\r
1104     }\r
1105 \r
1106     try\r
1107     {\r
1108       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
1109       Frame frame = new Frame();\r
1110       frame.add(pcaPanel);\r
1111       jalview.bin.JalviewLite.addFrame(frame, "Principal component analysis",\r
1112                                        400, 400);\r
1113     }\r
1114     catch (java.lang.OutOfMemoryError ex)\r
1115     {\r
1116     }\r
1117 \r
1118   }\r
1119 \r
1120   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1121   {\r
1122     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1123   }\r
1124 \r
1125   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1126   {\r
1127     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1128   }\r
1129 \r
1130   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1131   {\r
1132     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1133   }\r
1134 \r
1135   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1136   {\r
1137     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62PID");\r
1138   }\r
1139 \r
1140   void NewTreePanel(String type, String pwType, String title)\r
1141   {\r
1142     //are the sequences aligned?\r
1143     if (!viewport.alignment.isAligned())\r
1144     {\r
1145       SequenceI current;\r
1146       int Width = viewport.getAlignment().getWidth();\r
1147 \r
1148       for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
1149            i++)\r
1150       {\r
1151         current = viewport.getAlignment().getSequenceAt(i);\r
1152 \r
1153         if (current.getLength() < Width)\r
1154         {\r
1155           current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
1156         }\r
1157       }\r
1158       alignPanel.repaint();\r
1159 \r
1160     }\r
1161 \r
1162     final TreePanel tp;\r
1163     if (viewport.getSelectionGroup() != null &&\r
1164         viewport.getSelectionGroup().getSize() > 3)\r
1165     {\r
1166       tp = new TreePanel(viewport, viewport.getSelectionGroup().sequences, type,\r
1167                          pwType,\r
1168                          0, viewport.alignment.getWidth());\r
1169     }\r
1170     else\r
1171     {\r
1172       tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
1173                          type, pwType, 0, viewport.alignment.getWidth());\r
1174     }\r
1175 \r
1176     addTreeMenuItem(tp, title);\r
1177 \r
1178     jalview.bin.JalviewLite.addFrame(tp, title, 600, 500);\r
1179   }\r
1180 \r
1181   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1182   {\r
1183     final MenuItem item = new MenuItem(title);\r
1184     sortByTreeMenu.add(item);\r
1185     item.addActionListener(new java.awt.event.ActionListener()\r
1186     {\r
1187       public void actionPerformed(ActionEvent e)\r
1188       {\r
1189         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
1190                                        HistoryItem.SORT));\r
1191         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());\r
1192         alignPanel.repaint();\r
1193       }\r
1194     });\r
1195 \r
1196     treePanel.addWindowListener(new WindowAdapter()\r
1197     {\r
1198       public void windowClosing(WindowEvent e)\r
1199       {\r
1200         sortByTreeMenu.remove(item);\r
1201       };\r
1202     });\r
1203   }\r
1204 \r
1205   protected void documentation_actionPerformed(ActionEvent e)\r
1206   {\r
1207     jalview.bin.JalviewLite.showURL("http://www.jalview.org/help.html");\r
1208   }\r
1209 \r
1210   protected void about_actionPerformed(ActionEvent e)\r
1211   {\r
1212 \r
1213     class AboutPanel extends Canvas\r
1214     {\r
1215       String version;\r
1216       public AboutPanel(String version)\r
1217       { this.version = version; }\r
1218 \r
1219       public void paint(Graphics g)\r
1220       {\r
1221         g.setColor(Color.white);\r
1222         g.fillRect(0, 0, getSize().width, getSize().height);\r
1223         g.setFont(new Font("Helvetica", Font.PLAIN, 12));\r
1224         FontMetrics fm = g.getFontMetrics();\r
1225         int fh = fm.getHeight();\r
1226         int y = 5, x = 7;\r
1227         g.setColor(Color.black);\r
1228         g.setFont(new Font("Helvetica", Font.BOLD, 14));\r
1229         g.drawString("Jalview - Release "+version, 200, y += fh);\r
1230         g.setFont(new Font("Helvetica", Font.PLAIN, 12));\r
1231         g.drawString("Authors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",\r
1232                      x, y += fh * 2);\r
1233         g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",\r
1234                      x, y += fh);\r
1235         g.drawString(\r
1236             "For any issues relating to Jalview, email help@jalview.org", x,\r
1237             y += fh);\r
1238         g.drawString("If  you use JalView, please cite:", x, y += fh + 8);\r
1239         g.drawString("\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"",\r
1240                      x, y += fh);\r
1241         g.drawString("Bioinformatics,  2004 12;426-7.", x, y += fh);\r
1242       }\r
1243     }\r
1244 \r
1245     String version = "test";\r
1246     java.net.URL url = getClass().getResource("/.build_properties");\r
1247     if (url != null)\r
1248     {\r
1249       try\r
1250       {\r
1251         BufferedReader reader = new BufferedReader(new InputStreamReader(\r
1252             url.openStream()));\r
1253         String line;\r
1254         while ( (line = reader.readLine()) != null)\r
1255         {\r
1256           if (line.indexOf("VERSION") > -1)\r
1257           {\r
1258             version = line.substring(line.indexOf("=") + 1);\r
1259           }\r
1260         }\r
1261       }\r
1262       catch (Exception ex)\r
1263       {\r
1264         ex.printStackTrace();\r
1265       }\r
1266     }\r
1267 \r
1268 \r
1269     Frame frame = new Frame();\r
1270     frame.add(new AboutPanel(version));\r
1271     jalview.bin.JalviewLite.addFrame(frame, "Jalview", 580, 200);\r
1272 \r
1273   }\r
1274 }\r