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