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