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