Reset browser every time
[jalview.git] / src / jalview / gui / 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 package jalview.gui;\r
20 \r
21 import java.beans.*;\r
22 import java.io.*;\r
23 import java.util.*;\r
24 \r
25 import java.awt.*;\r
26 import java.awt.datatransfer.*;\r
27 import java.awt.event.*;\r
28 import java.awt.print.*;\r
29 import javax.swing.*;\r
30 import javax.swing.event.*;\r
31 \r
32 import jalview.analysis.*;\r
33 import jalview.datamodel.*;\r
34 import jalview.io.*;\r
35 import jalview.jbgui.*;\r
36 import jalview.schemes.*;\r
37 import jalview.ws.*;\r
38 \r
39 /**\r
40  * DOCUMENT ME!\r
41  *\r
42  * @author $author$\r
43  * @version $Revision$\r
44  */\r
45 public class AlignFrame\r
46     extends GAlignFrame\r
47 {\r
48   /** DOCUMENT ME!! */\r
49   public static final int NEW_WINDOW_WIDTH = 700;\r
50 \r
51   /** DOCUMENT ME!! */\r
52   public static final int NEW_WINDOW_HEIGHT = 500;\r
53   final AlignmentPanel alignPanel;\r
54   final AlignViewport viewport;\r
55 \r
56   /** DOCUMENT ME!! */\r
57   public String currentFileFormat = null;\r
58   Stack historyList = new Stack();\r
59   Stack redoList = new Stack();\r
60   private int treeCount = 0;\r
61 \r
62   /**\r
63    * Creates a new AlignFrame object.\r
64    *\r
65    * @param al DOCUMENT ME!\r
66    */\r
67   public AlignFrame(AlignmentI al)\r
68   {\r
69     viewport = new AlignViewport(al);\r
70 \r
71     alignPanel = new AlignmentPanel(this, viewport);\r
72     alignPanel.annotationPanel.adjustPanelHeight();\r
73     alignPanel.annotationSpaceFillerHolder.setPreferredSize(alignPanel.\r
74         annotationPanel.getPreferredSize());\r
75     alignPanel.annotationScroller.setPreferredSize(alignPanel.annotationPanel.\r
76         getPreferredSize());\r
77     alignPanel.setAnnotationVisible(viewport.getShowAnnotation());\r
78 \r
79     getContentPane().add(alignPanel, java.awt.BorderLayout.CENTER);\r
80 \r
81     addInternalFrameListener(new InternalFrameAdapter()\r
82     {\r
83       public void internalFrameActivated(InternalFrameEvent evt)\r
84       {\r
85         javax.swing.SwingUtilities.invokeLater(new Runnable()\r
86         {\r
87           public void run()\r
88           {\r
89             alignPanel.requestFocus();\r
90           }\r
91         });\r
92       }\r
93     });\r
94     addServiceListeners();\r
95   }\r
96 \r
97   /* Set up intrinsic listeners for dynamically generated GUI bits. */\r
98   private void addServiceListeners()\r
99   {\r
100 \r
101     final AlignFrame thisFrame = this;\r
102     final java.beans.PropertyChangeListener thisListener;\r
103     // Do this once to get current state\r
104     thisFrame.BuildWebServiceMenu();\r
105     Desktop.discoverer.addPropertyChangeListener(\r
106         thisListener = new java.beans.PropertyChangeListener()\r
107     {\r
108       public void propertyChange(PropertyChangeEvent evt)\r
109       {\r
110         // System.out.println("Discoverer property change.");\r
111         if (evt.getPropertyName().equals("services"))\r
112         {\r
113           // System.out.println("Rebuilding web service menu");\r
114           thisFrame.BuildWebServiceMenu();\r
115         }\r
116       }\r
117     });\r
118     addInternalFrameListener(new javax.swing.event.\r
119                              InternalFrameAdapter()\r
120     {\r
121       public void internalFrameClosed(\r
122           javax.swing.event.InternalFrameEvent evt)\r
123       {\r
124         // System.out.println("deregistering discoverer listener");\r
125         Desktop.discoverer.removePropertyChangeListener(thisListener);\r
126       }\r
127       ;\r
128     });\r
129 \r
130   }\r
131 \r
132   /**\r
133    * DOCUMENT ME!\r
134    *\r
135    * @param String DOCUMENT ME!\r
136    */\r
137 \r
138   public void parseGroupsFile(String file)\r
139   {\r
140     try\r
141     {\r
142       BufferedReader in = new BufferedReader(new FileReader(file));\r
143       SequenceI seq = null;\r
144       String line, text, token;\r
145       UserColourScheme ucs;\r
146       int index, start, end;\r
147       StringTokenizer st;\r
148       SequenceGroup sg;\r
149       while ( (line = in.readLine()) != null)\r
150       {\r
151         st = new StringTokenizer(line, "\t");\r
152         if (st.countTokens() != 6)\r
153         {\r
154           System.out.println("Groups file " + file +\r
155                              " is invalid. Read help file.");\r
156           System.exit(1);\r
157         }\r
158 \r
159         while (st.hasMoreElements())\r
160         {\r
161           text = st.nextToken();\r
162           token = st.nextToken();\r
163           if (!token.equals("ID_NOT_SPECIFIED"))\r
164           {\r
165             index = viewport.alignment.findIndex(viewport.alignment.findName(\r
166                 token));\r
167             st.nextToken();\r
168           }\r
169           else\r
170           {\r
171             index = Integer.parseInt(st.nextToken());\r
172           }\r
173 \r
174           start = Integer.parseInt(st.nextToken());\r
175           end = Integer.parseInt(st.nextToken());\r
176           ucs = new UserColourScheme(st.nextToken());\r
177 \r
178           seq = viewport.alignment.getSequenceAt(index);\r
179           start = seq.findIndex(start) - 1;\r
180           end = seq.findIndex(end) - 1;\r
181 \r
182           sg = new SequenceGroup(text, ucs, true, true, false, start, end);\r
183           sg.addSequence(seq, true);\r
184 \r
185           viewport.alignment.addGroup(sg);\r
186         }\r
187       }\r
188 \r
189     }\r
190     catch (Exception ex)\r
191     {\r
192       System.out.println("Error parsing groups file: " + ex);\r
193     }\r
194   }\r
195 \r
196   /**\r
197    * DOCUMENT ME!\r
198    *\r
199    * @param e DOCUMENT ME!\r
200    */\r
201   public void saveAlignmentMenu_actionPerformed(ActionEvent e)\r
202   {\r
203     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
204         getProperty(\r
205             "LAST_DIRECTORY"),\r
206         new String[]\r
207         {\r
208         "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",\r
209         "jar"\r
210     },\r
211         new String[]\r
212         {\r
213         "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"\r
214     }, currentFileFormat);\r
215 \r
216     chooser.setAcceptAllFileFilterUsed(false);\r
217     chooser.setFileView(new JalviewFileView());\r
218     chooser.setDialogTitle("Save Alignment to file");\r
219     chooser.setToolTipText("Save");\r
220 \r
221     int value = chooser.showSaveDialog(this);\r
222 \r
223     if (value == JalviewFileChooser.APPROVE_OPTION)\r
224     {\r
225       currentFileFormat = chooser.getSelectedFormat();\r
226       jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",\r
227                                     currentFileFormat);\r
228 \r
229       String choice = chooser.getSelectedFile().getPath();\r
230       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
231 \r
232       saveAlignment(choice, currentFileFormat);\r
233     }\r
234   }\r
235 \r
236   public boolean saveAlignment(String file, String format)\r
237   {\r
238     if (format.equalsIgnoreCase("Jalview"))\r
239     {\r
240       String shortName = title;\r
241 \r
242       if (shortName.indexOf(java.io.File.separatorChar) > -1)\r
243       {\r
244         shortName = shortName.substring(shortName.lastIndexOf(\r
245             java.io.File.separatorChar) + 1);\r
246       }\r
247 \r
248       Jalview2XML.SaveAlignment(this, file, shortName);\r
249 \r
250       // USE Jalview2XML to save this file\r
251       return true;\r
252     }\r
253     else\r
254     {\r
255       String output = FormatAdapter.formatSequences(format,\r
256           viewport.getAlignment().\r
257           getSequences());\r
258       if (output == null)\r
259       {\r
260         return false;\r
261       }\r
262 \r
263       try\r
264       {\r
265         java.io.PrintWriter out = new java.io.PrintWriter(\r
266             new java.io.FileWriter(file));\r
267         out.println(output);\r
268         out.close();\r
269         return true;\r
270       }\r
271       catch (Exception ex)\r
272       {\r
273         ex.printStackTrace();\r
274       }\r
275     }\r
276     return false;\r
277   }\r
278 \r
279   /**\r
280    * DOCUMENT ME!\r
281    *\r
282    * @param e DOCUMENT ME!\r
283    */\r
284   protected void outputText_actionPerformed(ActionEvent e)\r
285   {\r
286     CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
287     Desktop.addInternalFrame(cap,\r
288                              "Alignment output - " + e.getActionCommand(), 600,\r
289                              500);\r
290     cap.setText(FormatAdapter.formatSequences(e.getActionCommand(),\r
291                                               viewport.getAlignment().\r
292                                               getSequences()));\r
293   }\r
294 \r
295   /**\r
296    * DOCUMENT ME!\r
297    *\r
298    * @param e DOCUMENT ME!\r
299    */\r
300   protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
301   {\r
302     new HTMLOutput(viewport);\r
303   }\r
304 \r
305   public void createImageMap(File file, String image)\r
306   {\r
307     alignPanel.makePNGImageMap(file, image);\r
308   }\r
309 \r
310   /**\r
311    * DOCUMENT ME!\r
312    *\r
313    * @param e DOCUMENT ME!\r
314    */\r
315   public void createPNG(File f)\r
316   {\r
317     alignPanel.makePNG(f);\r
318   }\r
319 \r
320   /**\r
321    * DOCUMENT ME!\r
322    *\r
323    * @param e DOCUMENT ME!\r
324    */\r
325   public void createEPS(File f)\r
326   {\r
327     alignPanel.makeEPS(f);\r
328   }\r
329 \r
330   /**\r
331    * DOCUMENT ME!\r
332    *\r
333    * @param e DOCUMENT ME!\r
334    */\r
335   public void printMenuItem_actionPerformed(ActionEvent e)\r
336   {\r
337     //Putting in a thread avoids Swing painting problems\r
338     PrintThread thread = new PrintThread();\r
339     thread.start();\r
340   }\r
341 \r
342   /**\r
343    * DOCUMENT ME!\r
344    *\r
345    * @param e DOCUMENT ME!\r
346    */\r
347   public void closeMenuItem_actionPerformed(ActionEvent e)\r
348   {\r
349     try\r
350     {\r
351       this.setClosed(true);\r
352     }\r
353     catch (Exception ex)\r
354     {\r
355     }\r
356   }\r
357 \r
358   /**\r
359    * DOCUMENT ME!\r
360    */\r
361   void updateEditMenuBar()\r
362   {\r
363     if (historyList.size() > 0)\r
364     {\r
365       undoMenuItem.setEnabled(true);\r
366 \r
367       HistoryItem hi = (HistoryItem) historyList.peek();\r
368       undoMenuItem.setText("Undo " + hi.getDescription());\r
369     }\r
370     else\r
371     {\r
372       undoMenuItem.setEnabled(false);\r
373       undoMenuItem.setText("Undo");\r
374     }\r
375 \r
376     if (redoList.size() > 0)\r
377     {\r
378       redoMenuItem.setEnabled(true);\r
379 \r
380       HistoryItem hi = (HistoryItem) redoList.peek();\r
381       redoMenuItem.setText("Redo " + hi.getDescription());\r
382     }\r
383     else\r
384     {\r
385       redoMenuItem.setEnabled(false);\r
386       redoMenuItem.setText("Redo");\r
387     }\r
388   }\r
389 \r
390   /**\r
391    * DOCUMENT ME!\r
392    *\r
393    * @param hi DOCUMENT ME!\r
394    */\r
395   public void addHistoryItem(HistoryItem hi)\r
396   {\r
397     historyList.push(hi);\r
398     updateEditMenuBar();\r
399   }\r
400 \r
401   /**\r
402    * DOCUMENT ME!\r
403    *\r
404    * @param e DOCUMENT ME!\r
405    */\r
406   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
407   {\r
408     HistoryItem hi = (HistoryItem) historyList.pop();\r
409     redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment,\r
410                                   HistoryItem.HIDE));\r
411     restoreHistoryItem(hi);\r
412   }\r
413 \r
414   /**\r
415    * DOCUMENT ME!\r
416    *\r
417    * @param e DOCUMENT ME!\r
418    */\r
419   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
420   {\r
421     HistoryItem hi = (HistoryItem) redoList.pop();\r
422     restoreHistoryItem(hi);\r
423     updateEditMenuBar();\r
424     viewport.updateConsensus();\r
425     alignPanel.repaint();\r
426     alignPanel.repaint();\r
427   }\r
428 \r
429   // used by undo and redo\r
430   void restoreHistoryItem(HistoryItem hi)\r
431   {\r
432     if (hi.getType() == HistoryItem.SORT)\r
433     {\r
434       for (int i = 0; i < hi.getSequences().size(); i++)\r
435       {\r
436         viewport.alignment.getSequences().setElementAt(hi.getSequences()\r
437             .elementAt(i),\r
438             i);\r
439       }\r
440     }\r
441     else\r
442     {\r
443       for (int i = 0; i < hi.getSequences().size(); i++)\r
444       {\r
445         SequenceI restore = (SequenceI) hi.getSequences().elementAt(i);\r
446 \r
447         if (restore.getLength() == 0)\r
448         {\r
449           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
450           viewport.alignment.getSequences().insertElementAt(restore,\r
451               hi.getAlignIndex(i));\r
452         }\r
453         else\r
454         {\r
455           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
456         }\r
457       }\r
458 \r
459       if (hi.getType() == HistoryItem.PASTE)\r
460       {\r
461         for (int i = viewport.alignment.getHeight() - 1;\r
462              i > (hi.getSequences().size() - 1); i--)\r
463         {\r
464           viewport.alignment.deleteSequence(i);\r
465         }\r
466       }\r
467     }\r
468 \r
469     updateEditMenuBar();\r
470 \r
471     viewport.updateConsensus();\r
472     viewport.updateConservation();\r
473     alignPanel.repaint();\r
474     viewport.firePropertyChange("alignment", null,\r
475                                 viewport.getAlignment().getSequences());\r
476   }\r
477 \r
478   /**\r
479    * DOCUMENT ME!\r
480    *\r
481    * @param up DOCUMENT ME!\r
482    */\r
483   public void moveSelectedSequences(boolean up)\r
484   {\r
485     SequenceGroup sg = viewport.getSelectionGroup();\r
486 \r
487     if (sg == null)\r
488     {\r
489       return;\r
490     }\r
491 \r
492     if (up)\r
493     {\r
494       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
495       {\r
496         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
497 \r
498         if (!sg.sequences.contains(seq))\r
499         {\r
500           continue;\r
501         }\r
502 \r
503         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
504 \r
505         if (sg.sequences.contains(temp))\r
506         {\r
507           continue;\r
508         }\r
509 \r
510         viewport.alignment.getSequences().setElementAt(temp, i);\r
511         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
512       }\r
513     }\r
514     else\r
515     {\r
516       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
517       {\r
518         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
519 \r
520         if (!sg.sequences.contains(seq))\r
521         {\r
522           continue;\r
523         }\r
524 \r
525         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
526 \r
527         if (sg.sequences.contains(temp))\r
528         {\r
529           continue;\r
530         }\r
531 \r
532         viewport.alignment.getSequences().setElementAt(temp, i);\r
533         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
534       }\r
535     }\r
536 \r
537     alignPanel.repaint();\r
538   }\r
539 \r
540   /**\r
541    * DOCUMENT ME!\r
542    *\r
543    * @param e DOCUMENT ME!\r
544    */\r
545   protected void copy_actionPerformed(ActionEvent e)\r
546   {\r
547     if (viewport.getSelectionGroup() == null)\r
548     {\r
549       return;\r
550     }\r
551 \r
552     SequenceGroup sg = viewport.getSelectionGroup();\r
553 \r
554     Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
555     StringBuffer buffer = new StringBuffer();\r
556 \r
557     Hashtable orderedSeqs = new Hashtable();\r
558 \r
559     for (int i = 0; i < sg.getSize(); i++)\r
560     {\r
561       SequenceI seq = sg.getSequenceAt(i);\r
562       int index = viewport.alignment.findIndex(seq);\r
563       orderedSeqs.put(index + "", seq);\r
564     }\r
565 \r
566     int index = 0, startRes, endRes;\r
567     char ch;\r
568 \r
569     for (int i = 0; i < sg.getSize(); i++)\r
570     {\r
571       SequenceI seq = null;\r
572 \r
573       while (seq == null)\r
574       {\r
575         if (orderedSeqs.containsKey(index + ""))\r
576         {\r
577           seq = (SequenceI) orderedSeqs.get(index + "");\r
578           index++;\r
579 \r
580           break;\r
581         }\r
582         else\r
583         {\r
584           index++;\r
585         }\r
586       }\r
587       //FIND START RES\r
588       //Returns residue following index if gap\r
589       startRes = seq.findPosition(sg.getStartRes());\r
590 \r
591       //FIND END RES\r
592       //Need to find the residue preceeding index if gap\r
593       endRes = 0;\r
594 \r
595       for (int j = 0; j < sg.getEndRes() + 1 && j < seq.getLength(); j++)\r
596       {\r
597         ch = seq.getCharAt(j);\r
598         if (!jalview.util.Comparison.isGap( (ch)))\r
599         {\r
600           endRes++;\r
601         }\r
602       }\r
603 \r
604       if (endRes > 0)\r
605       {\r
606         endRes += seq.getStart() - 1;\r
607       }\r
608 \r
609       buffer.append(seq.getName() + "\t" +\r
610                     startRes + "\t" +\r
611                     endRes + "\t" +\r
612                     seq.getSequence(sg.getStartRes(),\r
613                                     sg.getEndRes() + 1) + "\n");\r
614     }\r
615 \r
616     c.setContents(new StringSelection(buffer.toString()), null);\r
617   }\r
618 \r
619   /**\r
620    * DOCUMENT ME!\r
621    *\r
622    * @param e DOCUMENT ME!\r
623    */\r
624   protected void pasteNew_actionPerformed(ActionEvent e)\r
625   {\r
626     paste(true);\r
627   }\r
628 \r
629   /**\r
630    * DOCUMENT ME!\r
631    *\r
632    * @param e DOCUMENT ME!\r
633    */\r
634   protected void pasteThis_actionPerformed(ActionEvent e)\r
635   {\r
636     addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
637                                    HistoryItem.PASTE));\r
638     paste(false);\r
639   }\r
640 \r
641   /**\r
642    * DOCUMENT ME!\r
643    *\r
644    * @param newAlignment DOCUMENT ME!\r
645    */\r
646   void paste(boolean newAlignment)\r
647   {\r
648     try\r
649     {\r
650       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
651       Transferable contents = c.getContents(this);\r
652 \r
653       if (contents == null)\r
654       {\r
655         return;\r
656       }\r
657 \r
658       String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
659       StringTokenizer st = new StringTokenizer(str);\r
660       ArrayList seqs = new ArrayList();\r
661 \r
662       while (st.hasMoreElements())\r
663       {\r
664         String name = st.nextToken();\r
665         int start = Integer.parseInt(st.nextToken());\r
666         int end = Integer.parseInt(st.nextToken());\r
667         Sequence sequence = new Sequence(name, st.nextToken(), start,\r
668                                          end);\r
669 \r
670         if (!newAlignment)\r
671         {\r
672           viewport.alignment.addSequence(sequence);\r
673         }\r
674         else\r
675         {\r
676           seqs.add(sequence);\r
677         }\r
678       }\r
679 \r
680       if (newAlignment)\r
681       {\r
682         SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
683         seqs.toArray(newSeqs);\r
684 \r
685         AlignFrame af = new AlignFrame(new Alignment(newSeqs));\r
686         String newtitle = new String("Copied sequences");\r
687 \r
688         if (title.startsWith("Copied sequences"))\r
689         {\r
690           newtitle = title;\r
691         }\r
692         else\r
693         {\r
694           newtitle = newtitle.concat("- from " + title);\r
695         }\r
696 \r
697         Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
698                                  NEW_WINDOW_HEIGHT);\r
699       }\r
700       else\r
701       {\r
702         viewport.firePropertyChange("alignment", null,\r
703                                     viewport.getAlignment().getSequences());\r
704         viewport.setEndSeq(viewport.alignment.getHeight());\r
705         viewport.alignment.getWidth();\r
706         viewport.updateConservation();\r
707         viewport.updateConsensus();\r
708         alignPanel.repaint();\r
709       }\r
710     }\r
711     catch (Exception ex)\r
712     {\r
713     }\r
714 \r
715     // could be anything being pasted in here\r
716   }\r
717 \r
718   /**\r
719    * DOCUMENT ME!\r
720    *\r
721    * @param e DOCUMENT ME!\r
722    */\r
723   protected void cut_actionPerformed(ActionEvent e)\r
724   {\r
725     copy_actionPerformed(null);\r
726     delete_actionPerformed(null);\r
727   }\r
728 \r
729   /**\r
730    * DOCUMENT ME!\r
731    *\r
732    * @param e DOCUMENT ME!\r
733    */\r
734   protected void delete_actionPerformed(ActionEvent e)\r
735   {\r
736     boolean seqsdeleted = false;\r
737 \r
738     if (viewport.getSelectionGroup() == null)\r
739     {\r
740       return;\r
741     }\r
742 \r
743     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
744                                    HistoryItem.HIDE));\r
745 \r
746     SequenceGroup sg = viewport.getSelectionGroup();\r
747     boolean allSequences = false;\r
748     if (sg.sequences.size() == viewport.alignment.getHeight())\r
749     {\r
750       allSequences = true;\r
751     }\r
752 \r
753     for (int i = 0; i < sg.sequences.size(); i++)\r
754     {\r
755       SequenceI seq = sg.getSequenceAt(i);\r
756       int index = viewport.getAlignment().findIndex(seq);\r
757       seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
758 \r
759       // If the cut affects all sequences, remove highlighted columns\r
760       if (allSequences)\r
761       {\r
762         viewport.getColumnSelection().removeElements(sg.getStartRes(),\r
763             sg.getEndRes() + 1);\r
764       }\r
765 \r
766       if (seq.getSequence().length() < 1)\r
767       {\r
768         seqsdeleted = true;\r
769         viewport.getAlignment().deleteSequence(seq);\r
770       }\r
771       else\r
772       {\r
773         viewport.getAlignment().getSequences().setElementAt(seq, index);\r
774       }\r
775     }\r
776 \r
777     viewport.setSelectionGroup(null);\r
778     viewport.alignment.deleteGroup(sg);\r
779 \r
780     if (seqsdeleted)\r
781     {\r
782       viewport.firePropertyChange("alignment", null,\r
783                                   viewport.getAlignment().getSequences());\r
784     }\r
785 \r
786     viewport.resetSeqLimits(alignPanel.seqPanel.seqCanvas.getHeight());\r
787 \r
788     if (viewport.getAlignment().getHeight() < 1)\r
789     {\r
790       try\r
791       {\r
792         this.setClosed(true);\r
793       }\r
794       catch (Exception ex)\r
795       {\r
796       }\r
797     }\r
798 \r
799     viewport.updateConservation();\r
800     viewport.updateConsensus();\r
801     alignPanel.repaint();\r
802   }\r
803 \r
804   /**\r
805    * DOCUMENT ME!\r
806    *\r
807    * @param e DOCUMENT ME!\r
808    */\r
809   protected void deleteGroups_actionPerformed(ActionEvent e)\r
810   {\r
811     viewport.alignment.deleteAllGroups();\r
812     viewport.setSelectionGroup(null);\r
813     alignPanel.repaint();\r
814   }\r
815 \r
816   /**\r
817    * DOCUMENT ME!\r
818    *\r
819    * @param e DOCUMENT ME!\r
820    */\r
821   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
822   {\r
823     SequenceGroup sg = new SequenceGroup();\r
824 \r
825     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
826          i++)\r
827     {\r
828       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
829     }\r
830 \r
831     sg.setEndRes(viewport.alignment.getWidth() - 1);\r
832     viewport.setSelectionGroup(sg);\r
833     PaintRefresher.Refresh(null, viewport.alignment);\r
834   }\r
835 \r
836   /**\r
837    * DOCUMENT ME!\r
838    *\r
839    * @param e DOCUMENT ME!\r
840    */\r
841   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
842   {\r
843     viewport.setSelectionGroup(null);\r
844     viewport.getColumnSelection().clear();\r
845     viewport.setSelectionGroup(null);\r
846     alignPanel.annotationPanel.activeRes = null;\r
847     PaintRefresher.Refresh(null, viewport.alignment);\r
848   }\r
849 \r
850   /**\r
851    * DOCUMENT ME!\r
852    *\r
853    * @param e DOCUMENT ME!\r
854    */\r
855   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
856   {\r
857     SequenceGroup sg = viewport.getSelectionGroup();\r
858 \r
859     if (sg == null)\r
860     {\r
861       selectAllSequenceMenuItem_actionPerformed(null);\r
862 \r
863       return;\r
864     }\r
865 \r
866     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
867          i++)\r
868     {\r
869       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
870     }\r
871 \r
872     PaintRefresher.Refresh(null, viewport.alignment);\r
873   }\r
874 \r
875   /**\r
876    * DOCUMENT ME!\r
877    *\r
878    * @param e DOCUMENT ME!\r
879    */\r
880   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
881   {\r
882     ColumnSelection colSel = viewport.getColumnSelection();\r
883 \r
884     if (colSel.size() > 0)\r
885     {\r
886       addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
887                                      HistoryItem.HIDE));\r
888 \r
889       int min = colSel.getMin();\r
890       viewport.getAlignment().trimLeft(min);\r
891       colSel.compensateForEdit(0, min);\r
892 \r
893       if (viewport.getSelectionGroup() != null)\r
894       {\r
895         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
896       }\r
897 \r
898       Vector groups = viewport.alignment.getGroups();\r
899 \r
900       for (int i = 0; i < groups.size(); i++)\r
901       {\r
902         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
903 \r
904         if (!sg.adjustForRemoveLeft(min))\r
905         {\r
906           viewport.alignment.deleteGroup(sg);\r
907         }\r
908       }\r
909 \r
910       alignPanel.repaint();\r
911     }\r
912   }\r
913 \r
914   /**\r
915    * DOCUMENT ME!\r
916    *\r
917    * @param e DOCUMENT ME!\r
918    */\r
919   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
920   {\r
921     ColumnSelection colSel = viewport.getColumnSelection();\r
922 \r
923     if (colSel.size() > 0)\r
924     {\r
925       addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
926                                      HistoryItem.HIDE));\r
927 \r
928       int max = colSel.getMax();\r
929       viewport.getAlignment().trimRight(max);\r
930 \r
931       if (viewport.getSelectionGroup() != null)\r
932       {\r
933         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
934       }\r
935 \r
936       Vector groups = viewport.alignment.getGroups();\r
937 \r
938       for (int i = 0; i < groups.size(); i++)\r
939       {\r
940         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
941 \r
942         if (!sg.adjustForRemoveRight(max))\r
943         {\r
944           viewport.alignment.deleteGroup(sg);\r
945         }\r
946       }\r
947 \r
948       alignPanel.repaint();\r
949     }\r
950   }\r
951 \r
952   /**\r
953    * DOCUMENT ME!\r
954    *\r
955    * @param e DOCUMENT ME!\r
956    */\r
957   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
958   {\r
959     addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
960                                    viewport.alignment, HistoryItem.HIDE));\r
961 \r
962     viewport.getAlignment().removeGaps();\r
963     viewport.updateConservation();\r
964     viewport.updateConsensus();\r
965     alignPanel.repaint();\r
966   }\r
967 \r
968   /**\r
969    * DOCUMENT ME!\r
970    *\r
971    * @param e DOCUMENT ME!\r
972    */\r
973   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
974   {\r
975     addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
976                                    HistoryItem.HIDE));\r
977 \r
978     SequenceI current;\r
979     int jSize;\r
980 \r
981     Vector seqs = null;\r
982 \r
983     int start = 0;\r
984     int end = viewport.alignment.getWidth();\r
985 \r
986     if (viewport.getSelectionGroup() != null\r
987         && viewport.getSelectionGroup().sequences != null\r
988         && viewport.getSelectionGroup().sequences.size() > 0)\r
989     {\r
990       seqs = viewport.getSelectionGroup().sequences;\r
991       start = viewport.getSelectionGroup().getStartRes();\r
992       end = viewport.getSelectionGroup().getEndRes();\r
993     }\r
994     else\r
995     {\r
996       seqs = viewport.alignment.getSequences();\r
997     }\r
998 \r
999     for (int i = 0; i < seqs.size(); i++)\r
1000     {\r
1001       current = (SequenceI) seqs.elementAt(i);\r
1002       jSize = current.getLength();\r
1003 \r
1004       int j = start;\r
1005 \r
1006       do\r
1007       {\r
1008         if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
1009         {\r
1010           current.deleteCharAt(j);\r
1011           j--;\r
1012           jSize--;\r
1013         }\r
1014         j++;\r
1015       }\r
1016       while (j < end && j < jSize);\r
1017     }\r
1018 \r
1019     viewport.updateConservation();\r
1020     viewport.updateConsensus();\r
1021     alignPanel.repaint();\r
1022   }\r
1023 \r
1024   /**\r
1025    * DOCUMENT ME!\r
1026    *\r
1027    * @param e DOCUMENT ME!\r
1028    */\r
1029   public void padGapsMenuitem_actionPerformed(ActionEvent e)\r
1030   {\r
1031     addHistoryItem(new HistoryItem("Pad Gaps", viewport.alignment,\r
1032                                    HistoryItem.HIDE));\r
1033 \r
1034     SequenceI current;\r
1035     int Width = viewport.getAlignment().getWidth();\r
1036 \r
1037     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
1038          i++)\r
1039     {\r
1040       current = viewport.getAlignment().getSequenceAt(i);\r
1041 \r
1042       if (current.getLength() < Width)\r
1043       {\r
1044         current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
1045       }\r
1046     }\r
1047 \r
1048     viewport.updateConservation();\r
1049     viewport.updateConsensus();\r
1050     alignPanel.repaint();\r
1051   }\r
1052 \r
1053   /**\r
1054    * DOCUMENT ME!\r
1055    *\r
1056    * @param e DOCUMENT ME!\r
1057    */\r
1058   public void findMenuItem_actionPerformed(ActionEvent e)\r
1059   {\r
1060     JInternalFrame frame = new JInternalFrame();\r
1061     Finder finder = new Finder(viewport, alignPanel, frame);\r
1062     frame.setContentPane(finder);\r
1063     Desktop.addInternalFrame(frame, "Find", 340, 110);\r
1064     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
1065   }\r
1066 \r
1067   /**\r
1068    * DOCUMENT ME!\r
1069    *\r
1070    * @param e DOCUMENT ME!\r
1071    */\r
1072   public void font_actionPerformed(ActionEvent e)\r
1073   {\r
1074     FontChooser fc = new FontChooser(alignPanel);\r
1075   }\r
1076 \r
1077   /**\r
1078    * DOCUMENT ME!\r
1079    *\r
1080    * @param e DOCUMENT ME!\r
1081    */\r
1082   protected void fullSeqId_actionPerformed(ActionEvent e)\r
1083   {\r
1084     viewport.setShowFullId(fullSeqId.isSelected());\r
1085 \r
1086     alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());\r
1087     alignPanel.repaint();\r
1088   }\r
1089 \r
1090   /**\r
1091    * DOCUMENT ME!\r
1092    *\r
1093    * @param e DOCUMENT ME!\r
1094    */\r
1095   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
1096   {\r
1097     viewport.setColourText(colourTextMenuItem.isSelected());\r
1098     alignPanel.repaint();\r
1099   }\r
1100 \r
1101   /**\r
1102    * DOCUMENT ME!\r
1103    *\r
1104    * @param e DOCUMENT ME!\r
1105    */\r
1106   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
1107   {\r
1108     viewport.setWrapAlignment(wrapMenuItem.isSelected());\r
1109     alignPanel.setWrapAlignment(wrapMenuItem.isSelected());\r
1110     scaleAbove.setVisible(wrapMenuItem.isSelected());\r
1111     scaleLeft.setVisible(wrapMenuItem.isSelected());\r
1112     scaleRight.setVisible(wrapMenuItem.isSelected());\r
1113     alignPanel.repaint();\r
1114   }\r
1115 \r
1116   /**\r
1117    * DOCUMENT ME!\r
1118    *\r
1119    * @param e DOCUMENT ME!\r
1120    */\r
1121   protected void scaleAbove_actionPerformed(ActionEvent e)\r
1122   {\r
1123     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
1124     alignPanel.repaint();\r
1125   }\r
1126 \r
1127   /**\r
1128    * DOCUMENT ME!\r
1129    *\r
1130    * @param e DOCUMENT ME!\r
1131    */\r
1132   protected void scaleLeft_actionPerformed(ActionEvent e)\r
1133   {\r
1134     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
1135     alignPanel.repaint();\r
1136   }\r
1137 \r
1138   /**\r
1139    * DOCUMENT ME!\r
1140    *\r
1141    * @param e DOCUMENT ME!\r
1142    */\r
1143   protected void scaleRight_actionPerformed(ActionEvent e)\r
1144   {\r
1145     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
1146     alignPanel.repaint();\r
1147   }\r
1148 \r
1149   /**\r
1150    * DOCUMENT ME!\r
1151    *\r
1152    * @param e DOCUMENT ME!\r
1153    */\r
1154   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
1155   {\r
1156     viewport.setShowBoxes(viewBoxesMenuItem.isSelected());\r
1157     alignPanel.repaint();\r
1158   }\r
1159 \r
1160   /**\r
1161    * DOCUMENT ME!\r
1162    *\r
1163    * @param e DOCUMENT ME!\r
1164    */\r
1165   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
1166   {\r
1167     viewport.setShowText(viewTextMenuItem.isSelected());\r
1168     alignPanel.repaint();\r
1169   }\r
1170 \r
1171   /**\r
1172    * DOCUMENT ME!\r
1173    *\r
1174    * @param e DOCUMENT ME!\r
1175    */\r
1176   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
1177   {\r
1178     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
1179     alignPanel.repaint();\r
1180   }\r
1181 \r
1182   /**\r
1183    * DOCUMENT ME!\r
1184    *\r
1185    * @param evt DOCUMENT ME!\r
1186    */\r
1187   public void sequenceFeatures_actionPerformed(ActionEvent evt)\r
1188   {\r
1189     viewport.showSequenceFeatures(sequenceFeatures.isSelected());\r
1190 \r
1191     if (viewport.showSequenceFeatures &&\r
1192         ! ( (Alignment) viewport.alignment).featuresAdded)\r
1193     {\r
1194       SequenceFeatureFetcher sft = new SequenceFeatureFetcher(viewport.\r
1195           alignment,\r
1196           alignPanel);\r
1197       ( (Alignment) viewport.alignment).featuresAdded = true;\r
1198     }\r
1199 \r
1200     alignPanel.repaint();\r
1201   }\r
1202 \r
1203   /**\r
1204    * DOCUMENT ME!\r
1205    *\r
1206    * @param e DOCUMENT ME!\r
1207    */\r
1208   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
1209   {\r
1210     if (annotationPanelMenuItem.isSelected() &&\r
1211         viewport.getWrapAlignment())\r
1212     {\r
1213       annotationPanelMenuItem.setSelected(false);\r
1214 \r
1215       return;\r
1216     }\r
1217 \r
1218     viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());\r
1219     alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());\r
1220   }\r
1221 \r
1222   /**\r
1223    * DOCUMENT ME!\r
1224    *\r
1225    * @param e DOCUMENT ME!\r
1226    */\r
1227   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
1228   {\r
1229     if (alignPanel.overviewPanel != null)\r
1230     {\r
1231       return;\r
1232     }\r
1233 \r
1234     JInternalFrame frame = new JInternalFrame();\r
1235     OverviewPanel overview = new OverviewPanel(alignPanel);\r
1236     frame.setContentPane(overview);\r
1237     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
1238                              frame.getWidth(), frame.getHeight());\r
1239     frame.pack();\r
1240     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
1241     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
1242     {\r
1243       public void internalFrameClosed(\r
1244           javax.swing.event.InternalFrameEvent evt)\r
1245       {\r
1246         alignPanel.setOverviewPanel(null);\r
1247       }\r
1248       ;\r
1249     });\r
1250 \r
1251     alignPanel.setOverviewPanel(overview);\r
1252   }\r
1253 \r
1254   /**\r
1255    * DOCUMENT ME!\r
1256    *\r
1257    * @param e DOCUMENT ME!\r
1258    */\r
1259   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
1260   {\r
1261     changeColour(null);\r
1262   }\r
1263 \r
1264   /**\r
1265    * DOCUMENT ME!\r
1266    *\r
1267    * @param e DOCUMENT ME!\r
1268    */\r
1269   public void clustalColour_actionPerformed(ActionEvent e)\r
1270   {\r
1271     changeColour(new ClustalxColourScheme(\r
1272         viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
1273   }\r
1274 \r
1275   /**\r
1276    * DOCUMENT ME!\r
1277    *\r
1278    * @param e DOCUMENT ME!\r
1279    */\r
1280   public void zappoColour_actionPerformed(ActionEvent e)\r
1281   {\r
1282     changeColour(new ZappoColourScheme());\r
1283   }\r
1284 \r
1285   /**\r
1286    * DOCUMENT ME!\r
1287    *\r
1288    * @param e DOCUMENT ME!\r
1289    */\r
1290   public void taylorColour_actionPerformed(ActionEvent e)\r
1291   {\r
1292     changeColour(new TaylorColourScheme());\r
1293   }\r
1294 \r
1295   /**\r
1296    * DOCUMENT ME!\r
1297    *\r
1298    * @param e DOCUMENT ME!\r
1299    */\r
1300   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
1301   {\r
1302     changeColour(new HydrophobicColourScheme());\r
1303   }\r
1304 \r
1305   /**\r
1306    * DOCUMENT ME!\r
1307    *\r
1308    * @param e DOCUMENT ME!\r
1309    */\r
1310   public void helixColour_actionPerformed(ActionEvent e)\r
1311   {\r
1312     changeColour(new HelixColourScheme());\r
1313   }\r
1314 \r
1315   /**\r
1316    * DOCUMENT ME!\r
1317    *\r
1318    * @param e DOCUMENT ME!\r
1319    */\r
1320   public void strandColour_actionPerformed(ActionEvent e)\r
1321   {\r
1322     changeColour(new StrandColourScheme());\r
1323   }\r
1324 \r
1325   /**\r
1326    * DOCUMENT ME!\r
1327    *\r
1328    * @param e DOCUMENT ME!\r
1329    */\r
1330   public void turnColour_actionPerformed(ActionEvent e)\r
1331   {\r
1332     changeColour(new TurnColourScheme());\r
1333   }\r
1334 \r
1335   /**\r
1336    * DOCUMENT ME!\r
1337    *\r
1338    * @param e DOCUMENT ME!\r
1339    */\r
1340   public void buriedColour_actionPerformed(ActionEvent e)\r
1341   {\r
1342     changeColour(new BuriedColourScheme());\r
1343   }\r
1344 \r
1345   /**\r
1346    * DOCUMENT ME!\r
1347    *\r
1348    * @param e DOCUMENT ME!\r
1349    */\r
1350   public void nucleotideColour_actionPerformed(ActionEvent e)\r
1351   {\r
1352     changeColour(new NucleotideColourScheme());\r
1353   }\r
1354 \r
1355   /**\r
1356    * DOCUMENT ME!\r
1357    *\r
1358    * @param e DOCUMENT ME!\r
1359    */\r
1360   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
1361   {\r
1362     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
1363   }\r
1364 \r
1365   /**\r
1366    * DOCUMENT ME!\r
1367    *\r
1368    * @param cs DOCUMENT ME!\r
1369    */\r
1370   void changeColour(ColourSchemeI cs)\r
1371   {\r
1372     int threshold = 0;\r
1373 \r
1374     if (viewport.getAbovePIDThreshold())\r
1375     {\r
1376       threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,\r
1377                                                  "Background");\r
1378 \r
1379       if (cs instanceof ResidueColourScheme)\r
1380       {\r
1381         ( (ResidueColourScheme) cs).setThreshold(threshold,\r
1382                                                  viewport.\r
1383                                                  getIgnoreGapsConsensus());\r
1384       }\r
1385       else if (cs instanceof ScoreColourScheme)\r
1386       {\r
1387         ( (ScoreColourScheme) cs).setThreshold(threshold,\r
1388                                                viewport.getIgnoreGapsConsensus());\r
1389       }\r
1390 \r
1391       viewport.setGlobalColourScheme(cs);\r
1392     }\r
1393     else if (cs instanceof ResidueColourScheme)\r
1394     {\r
1395       ( (ResidueColourScheme) cs).setThreshold(0,\r
1396                                                viewport.getIgnoreGapsConsensus());\r
1397     }\r
1398 \r
1399 \r
1400     if (viewport.getConservationSelected())\r
1401     {\r
1402       ConservationColourScheme ccs = null;\r
1403 \r
1404       Alignment al = (Alignment) viewport.alignment;\r
1405       Conservation c = new Conservation("All",\r
1406                                         ResidueProperties.propHash, 3,\r
1407                                         al.getSequences(), 0,\r
1408                                         al.getWidth() - 1);\r
1409 \r
1410       c.calculate();\r
1411       c.verdict(false, viewport.ConsPercGaps);\r
1412 \r
1413       ccs = new ConservationColourScheme(c, cs);\r
1414 \r
1415       ccs.setConsensus(viewport.vconsensus);\r
1416 \r
1417       viewport.setGlobalColourScheme(ccs);\r
1418 \r
1419       ccs.inc = SliderPanel.setConservationSlider(alignPanel, ccs,\r
1420                                                   "Background");\r
1421     }\r
1422     else\r
1423     {\r
1424       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
1425       if (cs != null)\r
1426       {\r
1427         cs.setConsensus(viewport.vconsensus);\r
1428       }\r
1429 \r
1430       viewport.setGlobalColourScheme(cs);\r
1431     }\r
1432 \r
1433     if (viewport.getColourAppliesToAllGroups())\r
1434     {\r
1435       Vector groups = viewport.alignment.getGroups();\r
1436 \r
1437       for (int i = 0; i < groups.size(); i++)\r
1438       {\r
1439         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
1440 \r
1441         if (cs == null)\r
1442         {\r
1443           sg.cs = null;\r
1444         }\r
1445         else if (cs instanceof ClustalxColourScheme)\r
1446         {\r
1447           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
1448         }\r
1449         else if (cs instanceof UserColourScheme)\r
1450         {\r
1451           sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());\r
1452         }\r
1453         else\r
1454         {\r
1455           try\r
1456           {\r
1457             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
1458           }\r
1459           catch (Exception ex)\r
1460           {\r
1461           }\r
1462         }\r
1463 \r
1464         if (viewport.getAbovePIDThreshold())\r
1465         {\r
1466           if (sg.cs instanceof ResidueColourScheme)\r
1467           {\r
1468             ( (ResidueColourScheme) sg.cs).setThreshold(threshold,\r
1469                 viewport.getIgnoreGapsConsensus());\r
1470           }\r
1471 \r
1472           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1473               sg.getWidth()));\r
1474         }\r
1475 \r
1476         if (viewport.getConservationSelected())\r
1477         {\r
1478           Conservation c = new Conservation("Group",\r
1479                                             ResidueProperties.propHash, 3,\r
1480                                             sg.sequences, 0,\r
1481                                             viewport.alignment.getWidth() - 1);\r
1482           c.calculate();\r
1483           c.verdict(false, viewport.ConsPercGaps);\r
1484 \r
1485           ConservationColourScheme ccs = new ConservationColourScheme(c,\r
1486               sg.cs);\r
1487 \r
1488           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
1489           ccs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1490                                                  sg.getWidth()));\r
1491           sg.cs = ccs;\r
1492         }\r
1493         else if (cs != null)\r
1494         {\r
1495           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
1496           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1497               sg.getWidth()));\r
1498         }\r
1499       }\r
1500     }\r
1501 \r
1502     if (alignPanel.getOverviewPanel() != null)\r
1503     {\r
1504       alignPanel.getOverviewPanel().updateOverviewImage();\r
1505     }\r
1506 \r
1507     alignPanel.repaint();\r
1508   }\r
1509 \r
1510   /**\r
1511    * DOCUMENT ME!\r
1512    *\r
1513    * @param e DOCUMENT ME!\r
1514    */\r
1515   protected void modifyPID_actionPerformed(ActionEvent e)\r
1516   {\r
1517     if (viewport.getAbovePIDThreshold())\r
1518     {\r
1519       SliderPanel.setPIDSliderSource(alignPanel,\r
1520                                      viewport.getGlobalColourScheme(),\r
1521                                      "Background");\r
1522       SliderPanel.showPIDSlider();\r
1523     }\r
1524   }\r
1525 \r
1526   /**\r
1527    * DOCUMENT ME!\r
1528    *\r
1529    * @param e DOCUMENT ME!\r
1530    */\r
1531   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1532   {\r
1533     if (viewport.getConservationSelected())\r
1534     {\r
1535       SliderPanel.setConservationSlider(alignPanel,\r
1536                                         viewport.globalColourScheme,\r
1537                                         "Background");\r
1538       SliderPanel.showConservationSlider();\r
1539     }\r
1540   }\r
1541 \r
1542   /**\r
1543    * DOCUMENT ME!\r
1544    *\r
1545    * @param e DOCUMENT ME!\r
1546    */\r
1547   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1548   {\r
1549     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
1550 \r
1551     viewport.setAbovePIDThreshold(false);\r
1552     abovePIDThreshold.setSelected(false);\r
1553 \r
1554     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
1555 \r
1556     if (cs instanceof ConservationColourScheme)\r
1557     {\r
1558       changeColour( ( (ConservationColourScheme) cs).cs);\r
1559     }\r
1560     else\r
1561     {\r
1562       changeColour(cs);\r
1563     }\r
1564 \r
1565     modifyConservation_actionPerformed(null);\r
1566   }\r
1567 \r
1568   /**\r
1569    * DOCUMENT ME!\r
1570    *\r
1571    * @param e DOCUMENT ME!\r
1572    */\r
1573   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1574   {\r
1575     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
1576 \r
1577     conservationMenuItem.setSelected(false);\r
1578     viewport.setConservationSelected(false);\r
1579 \r
1580     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
1581 \r
1582     if (cs instanceof ConservationColourScheme)\r
1583     {\r
1584       changeColour( ( (ConservationColourScheme) cs).cs);\r
1585     }\r
1586     else\r
1587     {\r
1588       changeColour(cs);\r
1589     }\r
1590 \r
1591     modifyPID_actionPerformed(null);\r
1592   }\r
1593 \r
1594   /**\r
1595    * DOCUMENT ME!\r
1596    *\r
1597    * @param e DOCUMENT ME!\r
1598    */\r
1599   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1600   {\r
1601     if (e.getActionCommand().equals("User Defined..."))\r
1602     {\r
1603       new UserDefinedColours(alignPanel, null);\r
1604     }\r
1605     else\r
1606     {\r
1607       UserColourScheme udc = (UserColourScheme) UserDefinedColours.\r
1608           getUserColourSchemes().get(e.getActionCommand());\r
1609 \r
1610       changeColour(udc);\r
1611     }\r
1612   }\r
1613 \r
1614   public void updateUserColourMenu()\r
1615   {\r
1616 \r
1617     Component[] menuItems = colourMenu.getMenuComponents();\r
1618     int i, iSize = menuItems.length;\r
1619     for (i = 0; i < iSize; i++)\r
1620     {\r
1621       if (menuItems[i].getName() != null &&\r
1622           menuItems[i].getName().equals("USER_DEFINED"))\r
1623       {\r
1624         colourMenu.remove(menuItems[i]);\r
1625         iSize--;\r
1626       }\r
1627     }\r
1628     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)\r
1629     {\r
1630       java.util.Enumeration userColours = jalview.gui.UserDefinedColours.\r
1631           getUserColourSchemes().keys();\r
1632 \r
1633       while (userColours.hasMoreElements())\r
1634       {\r
1635         final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.\r
1636             nextElement().toString());\r
1637         radioItem.setName("USER_DEFINED");\r
1638         radioItem.addMouseListener(new MouseAdapter()\r
1639             {\r
1640               public void mousePressed(MouseEvent evt)\r
1641               {\r
1642                 if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))\r
1643                 {\r
1644                   radioItem.removeActionListener(radioItem.getActionListeners()[0]);\r
1645 \r
1646                   int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,\r
1647                       "Remove from default list?",\r
1648                       "Remove user defined colour",\r
1649                       JOptionPane.YES_NO_OPTION);\r
1650                   if(option == JOptionPane.YES_OPTION)\r
1651                   {\r
1652                     jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());\r
1653                     colourMenu.remove(radioItem);\r
1654                   }\r
1655                   else\r
1656                     radioItem.addActionListener(new ActionListener()\r
1657                     {\r
1658                       public void actionPerformed(ActionEvent evt)\r
1659                       {\r
1660                         userDefinedColour_actionPerformed(evt);\r
1661                       }\r
1662                     });\r
1663                 }\r
1664               }\r
1665             });\r
1666         radioItem.addActionListener(new ActionListener()\r
1667         {\r
1668           public void actionPerformed(ActionEvent evt)\r
1669           {\r
1670             userDefinedColour_actionPerformed(evt);\r
1671           }\r
1672         });\r
1673 \r
1674         colourMenu.insert(radioItem, 15);\r
1675         colours.add(radioItem);\r
1676       }\r
1677     }\r
1678   }\r
1679 \r
1680   /**\r
1681    * DOCUMENT ME!\r
1682    *\r
1683    * @param e DOCUMENT ME!\r
1684    */\r
1685   public void PIDColour_actionPerformed(ActionEvent e)\r
1686   {\r
1687     changeColour(new PIDColourScheme());\r
1688   }\r
1689 \r
1690   /**\r
1691    * DOCUMENT ME!\r
1692    *\r
1693    * @param e DOCUMENT ME!\r
1694    */\r
1695   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1696   {\r
1697     changeColour(new Blosum62ColourScheme());\r
1698   }\r
1699 \r
1700   /**\r
1701    * DOCUMENT ME!\r
1702    *\r
1703    * @param e DOCUMENT ME!\r
1704    */\r
1705   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1706   {\r
1707     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1708                                    HistoryItem.SORT));\r
1709     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1710                               viewport.getAlignment().getSequenceAt(0));\r
1711     alignPanel.repaint();\r
1712   }\r
1713 \r
1714   /**\r
1715    * DOCUMENT ME!\r
1716    *\r
1717    * @param e DOCUMENT ME!\r
1718    */\r
1719   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1720   {\r
1721     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1722                                    HistoryItem.SORT));\r
1723     AlignmentSorter.sortByID(viewport.getAlignment());\r
1724     alignPanel.repaint();\r
1725   }\r
1726 \r
1727   /**\r
1728    * DOCUMENT ME!\r
1729    *\r
1730    * @param e DOCUMENT ME!\r
1731    */\r
1732   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1733   {\r
1734     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1735                                    HistoryItem.SORT));\r
1736 \r
1737     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1738     alignPanel.repaint();\r
1739   }\r
1740 \r
1741   /**\r
1742    * DOCUMENT ME!\r
1743    *\r
1744    * @param e DOCUMENT ME!\r
1745    */\r
1746   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1747   {\r
1748     RedundancyPanel sp = new RedundancyPanel(alignPanel, this);\r
1749     JInternalFrame frame = new JInternalFrame();\r
1750     frame.setContentPane(sp);\r
1751     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
1752                              100, false);\r
1753   }\r
1754 \r
1755   /**\r
1756    * DOCUMENT ME!\r
1757    *\r
1758    * @param e DOCUMENT ME!\r
1759    */\r
1760   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1761   {\r
1762     if ( (viewport.getSelectionGroup() == null) ||\r
1763         (viewport.getSelectionGroup().getSize() < 2))\r
1764     {\r
1765       JOptionPane.showInternalMessageDialog(this,\r
1766                                             "You must select at least 2 sequences.",\r
1767                                             "Invalid Selection",\r
1768                                             JOptionPane.WARNING_MESSAGE);\r
1769     }\r
1770     else\r
1771     {\r
1772       JInternalFrame frame = new JInternalFrame();\r
1773       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
1774       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
1775     }\r
1776   }\r
1777 \r
1778   /**\r
1779    * DOCUMENT ME!\r
1780    *\r
1781    * @param e DOCUMENT ME!\r
1782    */\r
1783   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1784   {\r
1785     if ( ( (viewport.getSelectionGroup() != null) &&\r
1786           (viewport.getSelectionGroup().getSize() < 4) &&\r
1787           (viewport.getSelectionGroup().getSize() > 0)) ||\r
1788         (viewport.getAlignment().getHeight() < 4))\r
1789     {\r
1790       JOptionPane.showInternalMessageDialog(this,\r
1791                                             "Principal component analysis must take\n" +\r
1792                                             "at least 4 input sequences.",\r
1793                                             "Sequence selection insufficient",\r
1794                                             JOptionPane.WARNING_MESSAGE);\r
1795 \r
1796       return;\r
1797     }\r
1798 \r
1799     try\r
1800     {\r
1801       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
1802       JInternalFrame frame = new JInternalFrame();\r
1803       frame.setContentPane(pcaPanel);\r
1804       Desktop.addInternalFrame(frame, "Principal component analysis",\r
1805                                400, 400);\r
1806     }\r
1807     catch (java.lang.OutOfMemoryError ex)\r
1808     {\r
1809       JOptionPane.showInternalMessageDialog(this,\r
1810                                             "Too many sequences selected\nfor Principal Component Analysis!!",\r
1811                                             "Out of memory",\r
1812                                             JOptionPane.WARNING_MESSAGE);\r
1813     }\r
1814   }\r
1815 \r
1816   /**\r
1817    * DOCUMENT ME!\r
1818    *\r
1819    * @param e DOCUMENT ME!\r
1820    */\r
1821   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1822   {\r
1823     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1824   }\r
1825 \r
1826   /**\r
1827    * DOCUMENT ME!\r
1828    *\r
1829    * @param e DOCUMENT ME!\r
1830    */\r
1831   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1832   {\r
1833     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1834   }\r
1835 \r
1836   /**\r
1837    * DOCUMENT ME!\r
1838    *\r
1839    * @param e DOCUMENT ME!\r
1840    */\r
1841   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1842   {\r
1843     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1844   }\r
1845 \r
1846   /**\r
1847    * DOCUMENT ME!\r
1848    *\r
1849    * @param e DOCUMENT ME!\r
1850    */\r
1851   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1852   {\r
1853     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");\r
1854   }\r
1855 \r
1856   /**\r
1857    * DOCUMENT ME!\r
1858    *\r
1859    * @param type DOCUMENT ME!\r
1860    * @param pwType DOCUMENT ME!\r
1861    * @param title DOCUMENT ME!\r
1862    */\r
1863   void NewTreePanel(String type, String pwType, String title)\r
1864   {\r
1865     final TreePanel tp;\r
1866 \r
1867     if ( (viewport.getSelectionGroup() != null) &&\r
1868         (viewport.getSelectionGroup().getSize() > 3))\r
1869     {\r
1870       int s = 0;\r
1871       SequenceGroup sg = viewport.getSelectionGroup();\r
1872 \r
1873       /* Decide if the selection is a column region */\r
1874       while (s < sg.sequences.size())\r
1875       {\r
1876         if ( ( (SequenceI) sg.sequences.elementAt(s++)).getLength() <\r
1877             sg.getEndRes())\r
1878         {\r
1879           JOptionPane.showMessageDialog(Desktop.desktop,\r
1880                                         "The selected region to create a tree may\nonly contain residues or gaps.\n" +\r
1881                                         "Try using the Pad function in the edit menu,\n" +\r
1882                                         "or one of the multiple sequence alignment web services.",\r
1883                                         "Sequences in selection are not aligned",\r
1884                                         JOptionPane.WARNING_MESSAGE);\r
1885 \r
1886           return;\r
1887         }\r
1888       }\r
1889 \r
1890       title = title + " on region";\r
1891       tp = new TreePanel(viewport,\r
1892                          viewport.getSelectionGroup().sequences, type, pwType,\r
1893                          sg.getStartRes(), sg.getEndRes());\r
1894     }\r
1895     else\r
1896     {\r
1897       //are the sequences aligned?\r
1898       if (!viewport.alignment.isAligned())\r
1899       {\r
1900         JOptionPane.showMessageDialog(Desktop.desktop,\r
1901                                       "The sequences must be aligned before creating a tree.\n" +\r
1902                                       "Try using the Pad function in the edit menu,\n" +\r
1903                                       "or one of the multiple sequence alignment web services.",\r
1904                                       "Sequences not aligned",\r
1905                                       JOptionPane.WARNING_MESSAGE);\r
1906 \r
1907         return;\r
1908       }\r
1909 \r
1910       tp = new TreePanel(viewport,\r
1911                          viewport.getAlignment().getSequences(), type, pwType,\r
1912                          0,\r
1913                          viewport.alignment.getWidth());\r
1914     }\r
1915 \r
1916     addTreeMenuItem(tp, title);\r
1917     viewport.setCurrentTree(tp.getTree());\r
1918 \r
1919     Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);\r
1920   }\r
1921 \r
1922   /**\r
1923    * DOCUMENT ME!\r
1924    *\r
1925    * @param title DOCUMENT ME!\r
1926    * @param order DOCUMENT ME!\r
1927    */\r
1928   public void addSortByOrderMenuItem(String title, final AlignmentOrder order)\r
1929   {\r
1930     final JMenuItem item = new JMenuItem("by " + title);\r
1931     sort.add(item);\r
1932     item.addActionListener(new java.awt.event.ActionListener()\r
1933     {\r
1934       public void actionPerformed(ActionEvent e)\r
1935       {\r
1936         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
1937                                        HistoryItem.SORT));\r
1938 \r
1939         // TODO: JBPNote - have to map order entries to curent SequenceI pointers\r
1940         AlignmentSorter.sortBy(viewport.getAlignment(), order);\r
1941         alignPanel.repaint();\r
1942       }\r
1943     });\r
1944   }\r
1945 \r
1946   /**\r
1947    * Maintain the Order by->Displayed Tree menu.\r
1948    * Creates a new menu item for a TreePanel with an appropriate\r
1949    * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added\r
1950    * to remove the menu item when the treePanel is closed, and adjust\r
1951    * the tree leaf to sequence mapping when the alignment is modified.\r
1952    * @param treePanel Displayed tree window.\r
1953    * @param title SortBy menu item title.\r
1954    */\r
1955   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1956   {\r
1957     final JMenuItem item = new JMenuItem(title);\r
1958 \r
1959     treeCount++;\r
1960 \r
1961     if (treeCount == 1)\r
1962     {\r
1963       sort.add(sortByTreeMenu);\r
1964     }\r
1965 \r
1966     sortByTreeMenu.add(item);\r
1967     item.addActionListener(new java.awt.event.ActionListener()\r
1968     {\r
1969       public void actionPerformed(ActionEvent e)\r
1970       {\r
1971         addHistoryItem(new HistoryItem("Tree Sort",\r
1972                                        viewport.alignment, HistoryItem.SORT));\r
1973         AlignmentSorter.sortByTree(viewport.getAlignment(),\r
1974                                    treePanel.getTree());\r
1975         alignPanel.repaint();\r
1976       }\r
1977     });\r
1978 \r
1979     treePanel.addInternalFrameListener(new javax.swing.event.\r
1980                                        InternalFrameAdapter()\r
1981     {\r
1982       public void internalFrameClosed(\r
1983           javax.swing.event.InternalFrameEvent evt)\r
1984       {\r
1985         treeCount--;\r
1986         sortByTreeMenu.remove(item);\r
1987 \r
1988         if (treeCount == 0)\r
1989         {\r
1990           sort.remove(sortByTreeMenu);\r
1991         }\r
1992       }\r
1993       ;\r
1994     });\r
1995     viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
1996     {\r
1997       public void propertyChange(PropertyChangeEvent evt)\r
1998       {\r
1999         if (evt.getPropertyName().equals("alignment"))\r
2000         {\r
2001           treePanel.getTree().UpdatePlaceHolders( (Vector) evt.getNewValue());\r
2002           treePanel.repaint();\r
2003         }\r
2004       }\r
2005     });\r
2006   }\r
2007 \r
2008   /**\r
2009    * Work out whether the whole set of sequences\r
2010    * or just the selected set will be submitted for multiple alignment.\r
2011    *\r
2012    */\r
2013   private SequenceI[] gatherSequencesForAlignment()\r
2014   {\r
2015     // Now, check we have enough sequences\r
2016     SequenceI[] msa = null;\r
2017 \r
2018     if ( (viewport.getSelectionGroup() != null) &&\r
2019         (viewport.getSelectionGroup().getSize() > 1))\r
2020     {\r
2021       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2022       SequenceGroup seqs = viewport.getSelectionGroup();\r
2023       int sz;\r
2024       msa = new SequenceI[sz = seqs.getSize()];\r
2025 \r
2026       for (int i = 0; i < sz; i++)\r
2027       {\r
2028         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2029       }\r
2030     }\r
2031     else\r
2032     {\r
2033       Vector seqs = viewport.getAlignment().getSequences();\r
2034 \r
2035       if (seqs.size() > 1)\r
2036       {\r
2037         msa = new SequenceI[seqs.size()];\r
2038 \r
2039         for (int i = 0; i < seqs.size(); i++)\r
2040         {\r
2041           msa[i] = (SequenceI) seqs.elementAt(i);\r
2042         }\r
2043       }\r
2044     }\r
2045     return msa;\r
2046   }\r
2047 \r
2048   /**\r
2049    * Decides what is submitted to a secondary structure prediction service,\r
2050    * the currently selected sequence, or the currently selected alignment\r
2051    * (where the first sequence in the set is the one that the prediction\r
2052    * will be for).\r
2053    */\r
2054   SequenceI[] gatherSeqOrMsaForSecStrPrediction()\r
2055   {\r
2056     SequenceI seq = null;\r
2057     SequenceI[] msa = null;\r
2058 \r
2059     if ( (viewport.getSelectionGroup() != null) &&\r
2060         (viewport.getSelectionGroup().getSize() > 0))\r
2061     {\r
2062       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2063       SequenceGroup seqs = viewport.getSelectionGroup();\r
2064 \r
2065       if ( (seqs.getSize() == 1) || !viewport.alignment.isAligned())\r
2066       {\r
2067         seq = (SequenceI) seqs.getSequenceAt(0);\r
2068       }\r
2069       else\r
2070       {\r
2071         int sz;\r
2072         msa = new SequenceI[sz = seqs.getSize()];\r
2073 \r
2074         for (int i = 0; i < sz; i++)\r
2075         {\r
2076           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2077         }\r
2078       }\r
2079     }\r
2080     else\r
2081     {\r
2082       Vector seqs = viewport.getAlignment().getSequences();\r
2083 \r
2084       if ( (seqs.size() == 1) || !viewport.alignment.isAligned())\r
2085       {\r
2086         seq = (SequenceI) seqs.elementAt(0);\r
2087       }\r
2088       else\r
2089       {\r
2090         msa = new SequenceI[seqs.size()];\r
2091 \r
2092         for (int i = 0; i < seqs.size(); i++)\r
2093         {\r
2094           msa[i] = (SequenceI) seqs.elementAt(i);\r
2095         }\r
2096       }\r
2097     }\r
2098     if (msa != null)\r
2099     {\r
2100       return msa;\r
2101     }\r
2102     else\r
2103     {\r
2104       if (seq != null)\r
2105       {\r
2106         return new SequenceI[]\r
2107             {\r
2108             seq};\r
2109       }\r
2110     }\r
2111     return null;\r
2112   }\r
2113   /**\r
2114    * DOCUMENT ME!\r
2115    *\r
2116    * @param e DOCUMENT ME!\r
2117    */\r
2118   protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
2119   {\r
2120     // Pick the tree file\r
2121     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
2122         getProperty(\r
2123             "LAST_DIRECTORY"));\r
2124     chooser.setFileView(new JalviewFileView());\r
2125     chooser.setDialogTitle("Select a newick-like tree file");\r
2126     chooser.setToolTipText("Load a tree file");\r
2127 \r
2128     int value = chooser.showOpenDialog(null);\r
2129 \r
2130     if (value == JalviewFileChooser.APPROVE_OPTION)\r
2131     {\r
2132       String choice = chooser.getSelectedFile().getPath();\r
2133       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
2134 \r
2135       try\r
2136       {\r
2137         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,\r
2138             "File");\r
2139         viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());\r
2140       }\r
2141       catch (Exception ex)\r
2142       {\r
2143         JOptionPane.showMessageDialog(Desktop.desktop,\r
2144                                       "Problem reading tree file",\r
2145                                       ex.getMessage(),\r
2146                                       JOptionPane.WARNING_MESSAGE);\r
2147         ex.printStackTrace();\r
2148       }\r
2149     }\r
2150   }\r
2151 \r
2152   /**\r
2153    * DOCUMENT ME!\r
2154    *\r
2155    * @param nf DOCUMENT ME!\r
2156    * @param title DOCUMENT ME!\r
2157    *\r
2158    * @return DOCUMENT ME!\r
2159    */\r
2160   public TreePanel ShowNewickTree(NewickFile nf, String title)\r
2161   {\r
2162     TreePanel tp = null;\r
2163 \r
2164     try\r
2165     {\r
2166       nf.parse();\r
2167 \r
2168       if (nf.getTree() != null)\r
2169       {\r
2170         tp = new TreePanel(viewport,\r
2171                            viewport.getAlignment().getSequences(), nf,\r
2172                            "FromFile",\r
2173                            title);\r
2174         Desktop.addInternalFrame(tp, title, 600, 500);\r
2175         addTreeMenuItem(tp, title);\r
2176       }\r
2177     }\r
2178     catch (Exception ex)\r
2179     {\r
2180       ex.printStackTrace();\r
2181     }\r
2182 \r
2183     return tp;\r
2184   }\r
2185 \r
2186   class PrintThread\r
2187       extends Thread\r
2188   {\r
2189     public void run()\r
2190     {\r
2191       PrinterJob printJob = PrinterJob.getPrinterJob();\r
2192       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
2193       printJob.setPrintable(alignPanel, pf);\r
2194 \r
2195       if (printJob.printDialog())\r
2196       {\r
2197         try\r
2198         {\r
2199           printJob.print();\r
2200         }\r
2201         catch (Exception PrintException)\r
2202         {\r
2203           PrintException.printStackTrace();\r
2204         }\r
2205       }\r
2206     }\r
2207   }\r
2208 \r
2209   /**\r
2210    * Generates menu items and listener event actions for web service clients\r
2211    *\r
2212    */\r
2213   public void BuildWebServiceMenu()\r
2214   {\r
2215     if ( (Desktop.discoverer.services != null)\r
2216         && (Desktop.discoverer.services.size() > 0))\r
2217     {\r
2218       Vector msaws = (Vector) Desktop.discoverer.services.get("MsaWS");\r
2219       Vector secstrpr = (Vector) Desktop.discoverer.services.get("SecStrPred");\r
2220       Vector wsmenu = new Vector();\r
2221       if (msaws != null)\r
2222       {\r
2223         // Add any Multiple Sequence Alignment Services\r
2224         final JMenu msawsmenu = new JMenu("Alignment");\r
2225         for (int i = 0, j = msaws.size(); i < j; i++)\r
2226         {\r
2227           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.\r
2228               get(i);\r
2229           final JMenuItem method = new JMenuItem(sh.getName());\r
2230           method.addActionListener(new ActionListener()\r
2231           {\r
2232             public void actionPerformed(ActionEvent e)\r
2233             {\r
2234               SequenceI[] msa = gatherSequencesForAlignment();\r
2235               MsaWSClient ct = new jalview.ws.MsaWSClient(sh, title, msa,\r
2236                   false, true);\r
2237 \r
2238             }\r
2239 \r
2240           });\r
2241           msawsmenu.add(method);\r
2242           // Deal with services that we know accept partial alignments.\r
2243           if (sh.getName().indexOf("lustal") > -1)\r
2244           {\r
2245             // We know that ClustalWS can accept partial alignments for refinement.\r
2246             final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");\r
2247             methodR.addActionListener(new ActionListener()\r
2248             {\r
2249               public void actionPerformed(ActionEvent e)\r
2250               {\r
2251                 SequenceI[] msa = gatherSequencesForAlignment();\r
2252                 MsaWSClient ct = new jalview.ws.MsaWSClient(sh, title, msa,\r
2253                     true, true);\r
2254 \r
2255               }\r
2256 \r
2257             });\r
2258             msawsmenu.add(methodR);\r
2259 \r
2260           }\r
2261         }\r
2262         wsmenu.add(msawsmenu);\r
2263       }\r
2264       if (secstrpr != null)\r
2265       {\r
2266         // Add any secondary structure prediction services\r
2267         final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");\r
2268         for (int i = 0, j = secstrpr.size(); i < j; i++)\r
2269         {\r
2270           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)\r
2271               secstrpr.get(i);\r
2272           final JMenuItem method = new JMenuItem(sh.getName());\r
2273           method.addActionListener(new ActionListener()\r
2274           {\r
2275             public void actionPerformed(ActionEvent e)\r
2276             {\r
2277               SequenceI[] msa = gatherSeqOrMsaForSecStrPrediction();\r
2278               if (msa.length == 1)\r
2279               {\r
2280                 // Single Sequence prediction\r
2281                 jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
2282                     title, msa[0]);\r
2283               }\r
2284               else\r
2285               {\r
2286                 if (msa.length > 1)\r
2287                 {\r
2288                   // Single Sequence prediction\r
2289                   jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
2290                       title, msa);\r
2291                 }\r
2292               }\r
2293             }\r
2294           });\r
2295           secstrmenu.add(method);\r
2296         }\r
2297         wsmenu.add(secstrmenu);\r
2298       }\r
2299       this.webService.removeAll();\r
2300       for (int i = 0, j = wsmenu.size(); i < j; i++)\r
2301       {\r
2302         webService.add( (JMenu) wsmenu.get(i));\r
2303       }\r
2304     }\r
2305     else\r
2306     {\r
2307       this.webService.removeAll();\r
2308       this.webService.add(this.webServiceNoServices);\r
2309     }\r
2310     // TODO: add in rediscovery function\r
2311     // TODO: reduce code redundancy.\r
2312     // TODO: group services by location as well as function.\r
2313   }\r
2314 \r
2315 }\r