Conservation colour scheme is no more
[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 \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(cs!=null)\r
1375     {\r
1376       if (viewport.getAbovePIDThreshold())\r
1377       {\r
1378         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,\r
1379                                                    "Background");\r
1380 \r
1381         cs.setThreshold(threshold,\r
1382                         viewport.getIgnoreGapsConsensus());\r
1383 \r
1384         viewport.setGlobalColourScheme(cs);\r
1385       }\r
1386       else\r
1387       {\r
1388         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1389       }\r
1390 \r
1391       if (viewport.getConservationSelected())\r
1392       {\r
1393 \r
1394         Alignment al = (Alignment) viewport.alignment;\r
1395         Conservation c = new Conservation("All",\r
1396                                           ResidueProperties.propHash, 3,\r
1397                                           al.getSequences(), 0,\r
1398                                           al.getWidth() - 1);\r
1399 \r
1400         c.calculate();\r
1401         c.verdict(false, viewport.ConsPercGaps);\r
1402 \r
1403         cs.setConservation(c);\r
1404 \r
1405         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
1406             "Background"));\r
1407       }\r
1408       else\r
1409       {\r
1410         cs.setConservation(null);\r
1411       }\r
1412 \r
1413       cs.setConsensus(viewport.vconsensus);\r
1414     }\r
1415 \r
1416     viewport.setGlobalColourScheme(cs);\r
1417 \r
1418     if (viewport.getColourAppliesToAllGroups())\r
1419     {\r
1420       Vector groups = viewport.alignment.getGroups();\r
1421 \r
1422       for (int i = 0; i < groups.size(); i++)\r
1423       {\r
1424         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
1425 \r
1426         if (cs == null)\r
1427         {\r
1428           sg.cs = null;\r
1429           continue;\r
1430         }\r
1431 \r
1432         if (cs instanceof ClustalxColourScheme)\r
1433         {\r
1434           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
1435         }\r
1436         else if (cs instanceof UserColourScheme)\r
1437         {\r
1438           sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());\r
1439         }\r
1440         else\r
1441         {\r
1442           try\r
1443           {\r
1444             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
1445           }\r
1446           catch (Exception ex)\r
1447           {\r
1448           }\r
1449         }\r
1450 \r
1451         if (viewport.getAbovePIDThreshold())\r
1452         {\r
1453          sg.cs.setThreshold(threshold,\r
1454                 viewport.getIgnoreGapsConsensus());\r
1455 \r
1456           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1457               sg.getWidth()));\r
1458         }\r
1459         else\r
1460           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1461 \r
1462 \r
1463         if (viewport.getConservationSelected())\r
1464         {\r
1465           Conservation c = new Conservation("Group",\r
1466                                             ResidueProperties.propHash, 3,\r
1467                                             sg.sequences, 0,\r
1468                                             viewport.alignment.getWidth() - 1);\r
1469           c.calculate();\r
1470           c.verdict(false, viewport.ConsPercGaps);\r
1471           sg.cs.setConservation(c);\r
1472         }\r
1473         else\r
1474           sg.cs.setConservation(null);\r
1475       }\r
1476     }\r
1477 \r
1478     if (alignPanel.getOverviewPanel() != null)\r
1479     {\r
1480       alignPanel.getOverviewPanel().updateOverviewImage();\r
1481     }\r
1482 \r
1483     alignPanel.repaint();\r
1484   }\r
1485 \r
1486   /**\r
1487    * DOCUMENT ME!\r
1488    *\r
1489    * @param e DOCUMENT ME!\r
1490    */\r
1491   protected void modifyPID_actionPerformed(ActionEvent e)\r
1492   {\r
1493     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
1494     {\r
1495       SliderPanel.setPIDSliderSource(alignPanel,\r
1496                                      viewport.getGlobalColourScheme(),\r
1497                                      "Background");\r
1498       SliderPanel.showPIDSlider();\r
1499     }\r
1500   }\r
1501 \r
1502   /**\r
1503    * DOCUMENT ME!\r
1504    *\r
1505    * @param e DOCUMENT ME!\r
1506    */\r
1507   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1508   {\r
1509     if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
1510     {\r
1511       SliderPanel.setConservationSlider(alignPanel,\r
1512                                         viewport.globalColourScheme,\r
1513                                         "Background");\r
1514       SliderPanel.showConservationSlider();\r
1515     }\r
1516   }\r
1517 \r
1518   /**\r
1519    * DOCUMENT ME!\r
1520    *\r
1521    * @param e DOCUMENT ME!\r
1522    */\r
1523   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1524   {\r
1525     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
1526 \r
1527     viewport.setAbovePIDThreshold(false);\r
1528     abovePIDThreshold.setSelected(false);\r
1529 \r
1530     changeColour(viewport.getGlobalColourScheme());\r
1531 \r
1532     modifyConservation_actionPerformed(null);\r
1533   }\r
1534 \r
1535   /**\r
1536    * DOCUMENT ME!\r
1537    *\r
1538    * @param e DOCUMENT ME!\r
1539    */\r
1540   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1541   {\r
1542     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
1543 \r
1544     conservationMenuItem.setSelected(false);\r
1545     viewport.setConservationSelected(false);\r
1546 \r
1547     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
1548 \r
1549     changeColour(viewport.getGlobalColourScheme());\r
1550 \r
1551     modifyPID_actionPerformed(null);\r
1552   }\r
1553 \r
1554   /**\r
1555    * DOCUMENT ME!\r
1556    *\r
1557    * @param e DOCUMENT ME!\r
1558    */\r
1559   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1560   {\r
1561     if (e.getActionCommand().equals("User Defined..."))\r
1562     {\r
1563       new UserDefinedColours(alignPanel, null);\r
1564     }\r
1565     else\r
1566     {\r
1567       UserColourScheme udc = (UserColourScheme) UserDefinedColours.\r
1568           getUserColourSchemes().get(e.getActionCommand());\r
1569 \r
1570       changeColour(udc);\r
1571     }\r
1572   }\r
1573 \r
1574   public void updateUserColourMenu()\r
1575   {\r
1576 \r
1577     Component[] menuItems = colourMenu.getMenuComponents();\r
1578     int i, iSize = menuItems.length;\r
1579     for (i = 0; i < iSize; i++)\r
1580     {\r
1581       if (menuItems[i].getName() != null &&\r
1582           menuItems[i].getName().equals("USER_DEFINED"))\r
1583       {\r
1584         colourMenu.remove(menuItems[i]);\r
1585         iSize--;\r
1586       }\r
1587     }\r
1588     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)\r
1589     {\r
1590       java.util.Enumeration userColours = jalview.gui.UserDefinedColours.\r
1591           getUserColourSchemes().keys();\r
1592 \r
1593       while (userColours.hasMoreElements())\r
1594       {\r
1595         final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.\r
1596             nextElement().toString());\r
1597         radioItem.setName("USER_DEFINED");\r
1598         radioItem.addMouseListener(new MouseAdapter()\r
1599             {\r
1600               public void mousePressed(MouseEvent evt)\r
1601               {\r
1602                 if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))\r
1603                 {\r
1604                   radioItem.removeActionListener(radioItem.getActionListeners()[0]);\r
1605 \r
1606                   int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,\r
1607                       "Remove from default list?",\r
1608                       "Remove user defined colour",\r
1609                       JOptionPane.YES_NO_OPTION);\r
1610                   if(option == JOptionPane.YES_OPTION)\r
1611                   {\r
1612                     jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());\r
1613                     colourMenu.remove(radioItem);\r
1614                   }\r
1615                   else\r
1616                     radioItem.addActionListener(new ActionListener()\r
1617                     {\r
1618                       public void actionPerformed(ActionEvent evt)\r
1619                       {\r
1620                         userDefinedColour_actionPerformed(evt);\r
1621                       }\r
1622                     });\r
1623                 }\r
1624               }\r
1625             });\r
1626         radioItem.addActionListener(new ActionListener()\r
1627         {\r
1628           public void actionPerformed(ActionEvent evt)\r
1629           {\r
1630             userDefinedColour_actionPerformed(evt);\r
1631           }\r
1632         });\r
1633 \r
1634         colourMenu.insert(radioItem, 15);\r
1635         colours.add(radioItem);\r
1636       }\r
1637     }\r
1638   }\r
1639 \r
1640   /**\r
1641    * DOCUMENT ME!\r
1642    *\r
1643    * @param e DOCUMENT ME!\r
1644    */\r
1645   public void PIDColour_actionPerformed(ActionEvent e)\r
1646   {\r
1647     changeColour(new PIDColourScheme());\r
1648   }\r
1649 \r
1650   /**\r
1651    * DOCUMENT ME!\r
1652    *\r
1653    * @param e DOCUMENT ME!\r
1654    */\r
1655   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1656   {\r
1657     changeColour(new Blosum62ColourScheme());\r
1658   }\r
1659 \r
1660   /**\r
1661    * DOCUMENT ME!\r
1662    *\r
1663    * @param e DOCUMENT ME!\r
1664    */\r
1665   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1666   {\r
1667     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1668                                    HistoryItem.SORT));\r
1669     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1670                               viewport.getAlignment().getSequenceAt(0));\r
1671     alignPanel.repaint();\r
1672   }\r
1673 \r
1674   /**\r
1675    * DOCUMENT ME!\r
1676    *\r
1677    * @param e DOCUMENT ME!\r
1678    */\r
1679   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1680   {\r
1681     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1682                                    HistoryItem.SORT));\r
1683     AlignmentSorter.sortByID(viewport.getAlignment());\r
1684     alignPanel.repaint();\r
1685   }\r
1686 \r
1687   /**\r
1688    * DOCUMENT ME!\r
1689    *\r
1690    * @param e DOCUMENT ME!\r
1691    */\r
1692   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1693   {\r
1694     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1695                                    HistoryItem.SORT));\r
1696 \r
1697     AlignmentSorter.sortByGroup(viewport.getAlignment());\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 removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1707   {\r
1708     RedundancyPanel sp = new RedundancyPanel(alignPanel, this);\r
1709     JInternalFrame frame = new JInternalFrame();\r
1710     frame.setContentPane(sp);\r
1711     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
1712                              100, false);\r
1713   }\r
1714 \r
1715   /**\r
1716    * DOCUMENT ME!\r
1717    *\r
1718    * @param e DOCUMENT ME!\r
1719    */\r
1720   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1721   {\r
1722     if ( (viewport.getSelectionGroup() == null) ||\r
1723         (viewport.getSelectionGroup().getSize() < 2))\r
1724     {\r
1725       JOptionPane.showInternalMessageDialog(this,\r
1726                                             "You must select at least 2 sequences.",\r
1727                                             "Invalid Selection",\r
1728                                             JOptionPane.WARNING_MESSAGE);\r
1729     }\r
1730     else\r
1731     {\r
1732       JInternalFrame frame = new JInternalFrame();\r
1733       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
1734       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
1735     }\r
1736   }\r
1737 \r
1738   /**\r
1739    * DOCUMENT ME!\r
1740    *\r
1741    * @param e DOCUMENT ME!\r
1742    */\r
1743   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1744   {\r
1745     if ( ( (viewport.getSelectionGroup() != null) &&\r
1746           (viewport.getSelectionGroup().getSize() < 4) &&\r
1747           (viewport.getSelectionGroup().getSize() > 0)) ||\r
1748         (viewport.getAlignment().getHeight() < 4))\r
1749     {\r
1750       JOptionPane.showInternalMessageDialog(this,\r
1751                                             "Principal component analysis must take\n" +\r
1752                                             "at least 4 input sequences.",\r
1753                                             "Sequence selection insufficient",\r
1754                                             JOptionPane.WARNING_MESSAGE);\r
1755 \r
1756       return;\r
1757     }\r
1758 \r
1759     try\r
1760     {\r
1761       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
1762       JInternalFrame frame = new JInternalFrame();\r
1763       frame.setContentPane(pcaPanel);\r
1764       Desktop.addInternalFrame(frame, "Principal component analysis",\r
1765                                400, 400);\r
1766     }\r
1767     catch (java.lang.OutOfMemoryError ex)\r
1768     {\r
1769       JOptionPane.showInternalMessageDialog(this,\r
1770                                             "Too many sequences selected\nfor Principal Component Analysis!!",\r
1771                                             "Out of memory",\r
1772                                             JOptionPane.WARNING_MESSAGE);\r
1773     }\r
1774   }\r
1775 \r
1776   /**\r
1777    * DOCUMENT ME!\r
1778    *\r
1779    * @param e DOCUMENT ME!\r
1780    */\r
1781   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1782   {\r
1783     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1784   }\r
1785 \r
1786   /**\r
1787    * DOCUMENT ME!\r
1788    *\r
1789    * @param e DOCUMENT ME!\r
1790    */\r
1791   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1792   {\r
1793     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1794   }\r
1795 \r
1796   /**\r
1797    * DOCUMENT ME!\r
1798    *\r
1799    * @param e DOCUMENT ME!\r
1800    */\r
1801   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1802   {\r
1803     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1804   }\r
1805 \r
1806   /**\r
1807    * DOCUMENT ME!\r
1808    *\r
1809    * @param e DOCUMENT ME!\r
1810    */\r
1811   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1812   {\r
1813     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");\r
1814   }\r
1815 \r
1816   /**\r
1817    * DOCUMENT ME!\r
1818    *\r
1819    * @param type DOCUMENT ME!\r
1820    * @param pwType DOCUMENT ME!\r
1821    * @param title DOCUMENT ME!\r
1822    */\r
1823   void NewTreePanel(String type, String pwType, String title)\r
1824   {\r
1825     final TreePanel tp;\r
1826 \r
1827     if ( (viewport.getSelectionGroup() != null) &&\r
1828         (viewport.getSelectionGroup().getSize() > 3))\r
1829     {\r
1830       int s = 0;\r
1831       SequenceGroup sg = viewport.getSelectionGroup();\r
1832 \r
1833       /* Decide if the selection is a column region */\r
1834       while (s < sg.sequences.size())\r
1835       {\r
1836         if ( ( (SequenceI) sg.sequences.elementAt(s++)).getLength() <\r
1837             sg.getEndRes())\r
1838         {\r
1839           JOptionPane.showMessageDialog(Desktop.desktop,\r
1840                                         "The selected region to create a tree may\nonly contain residues or gaps.\n" +\r
1841                                         "Try using the Pad function in the edit menu,\n" +\r
1842                                         "or one of the multiple sequence alignment web services.",\r
1843                                         "Sequences in selection are not aligned",\r
1844                                         JOptionPane.WARNING_MESSAGE);\r
1845 \r
1846           return;\r
1847         }\r
1848       }\r
1849 \r
1850       title = title + " on region";\r
1851       tp = new TreePanel(viewport,\r
1852                          viewport.getSelectionGroup().sequences, type, pwType,\r
1853                          sg.getStartRes(), sg.getEndRes());\r
1854     }\r
1855     else\r
1856     {\r
1857       //are the sequences aligned?\r
1858       if (!viewport.alignment.isAligned())\r
1859       {\r
1860         JOptionPane.showMessageDialog(Desktop.desktop,\r
1861                                       "The sequences must be aligned before creating a tree.\n" +\r
1862                                       "Try using the Pad function in the edit menu,\n" +\r
1863                                       "or one of the multiple sequence alignment web services.",\r
1864                                       "Sequences not aligned",\r
1865                                       JOptionPane.WARNING_MESSAGE);\r
1866 \r
1867         return;\r
1868       }\r
1869 \r
1870       tp = new TreePanel(viewport,\r
1871                          viewport.getAlignment().getSequences(), type, pwType,\r
1872                          0,\r
1873                          viewport.alignment.getWidth());\r
1874     }\r
1875 \r
1876     addTreeMenuItem(tp, title);\r
1877     viewport.setCurrentTree(tp.getTree());\r
1878 \r
1879     Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);\r
1880   }\r
1881 \r
1882   /**\r
1883    * DOCUMENT ME!\r
1884    *\r
1885    * @param title DOCUMENT ME!\r
1886    * @param order DOCUMENT ME!\r
1887    */\r
1888   public void addSortByOrderMenuItem(String title, final AlignmentOrder order)\r
1889   {\r
1890     final JMenuItem item = new JMenuItem("by " + title);\r
1891     sort.add(item);\r
1892     item.addActionListener(new java.awt.event.ActionListener()\r
1893     {\r
1894       public void actionPerformed(ActionEvent e)\r
1895       {\r
1896         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
1897                                        HistoryItem.SORT));\r
1898 \r
1899         // TODO: JBPNote - have to map order entries to curent SequenceI pointers\r
1900         AlignmentSorter.sortBy(viewport.getAlignment(), order);\r
1901         alignPanel.repaint();\r
1902       }\r
1903     });\r
1904   }\r
1905 \r
1906   /**\r
1907    * Maintain the Order by->Displayed Tree menu.\r
1908    * Creates a new menu item for a TreePanel with an appropriate\r
1909    * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added\r
1910    * to remove the menu item when the treePanel is closed, and adjust\r
1911    * the tree leaf to sequence mapping when the alignment is modified.\r
1912    * @param treePanel Displayed tree window.\r
1913    * @param title SortBy menu item title.\r
1914    */\r
1915   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1916   {\r
1917     final JMenuItem item = new JMenuItem(title);\r
1918 \r
1919     treeCount++;\r
1920 \r
1921     if (treeCount == 1)\r
1922     {\r
1923       sort.add(sortByTreeMenu);\r
1924     }\r
1925 \r
1926     sortByTreeMenu.add(item);\r
1927     item.addActionListener(new java.awt.event.ActionListener()\r
1928     {\r
1929       public void actionPerformed(ActionEvent e)\r
1930       {\r
1931         addHistoryItem(new HistoryItem("Tree Sort",\r
1932                                        viewport.alignment, HistoryItem.SORT));\r
1933         AlignmentSorter.sortByTree(viewport.getAlignment(),\r
1934                                    treePanel.getTree());\r
1935         alignPanel.repaint();\r
1936       }\r
1937     });\r
1938 \r
1939     treePanel.addInternalFrameListener(new javax.swing.event.\r
1940                                        InternalFrameAdapter()\r
1941     {\r
1942       public void internalFrameClosed(\r
1943           javax.swing.event.InternalFrameEvent evt)\r
1944       {\r
1945         treeCount--;\r
1946         sortByTreeMenu.remove(item);\r
1947 \r
1948         if (treeCount == 0)\r
1949         {\r
1950           sort.remove(sortByTreeMenu);\r
1951         }\r
1952       }\r
1953       ;\r
1954     });\r
1955     viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
1956     {\r
1957       public void propertyChange(PropertyChangeEvent evt)\r
1958       {\r
1959         if (evt.getPropertyName().equals("alignment"))\r
1960         {\r
1961           treePanel.getTree().UpdatePlaceHolders( (Vector) evt.getNewValue());\r
1962           treePanel.repaint();\r
1963         }\r
1964       }\r
1965     });\r
1966   }\r
1967 \r
1968   /**\r
1969    * Work out whether the whole set of sequences\r
1970    * or just the selected set will be submitted for multiple alignment.\r
1971    *\r
1972    */\r
1973   private SequenceI[] gatherSequencesForAlignment()\r
1974   {\r
1975     // Now, check we have enough sequences\r
1976     SequenceI[] msa = null;\r
1977 \r
1978     if ( (viewport.getSelectionGroup() != null) &&\r
1979         (viewport.getSelectionGroup().getSize() > 1))\r
1980     {\r
1981       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1982       SequenceGroup seqs = viewport.getSelectionGroup();\r
1983       int sz;\r
1984       msa = new SequenceI[sz = seqs.getSize()];\r
1985 \r
1986       for (int i = 0; i < sz; i++)\r
1987       {\r
1988         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1989       }\r
1990     }\r
1991     else\r
1992     {\r
1993       Vector seqs = viewport.getAlignment().getSequences();\r
1994 \r
1995       if (seqs.size() > 1)\r
1996       {\r
1997         msa = new SequenceI[seqs.size()];\r
1998 \r
1999         for (int i = 0; i < seqs.size(); i++)\r
2000         {\r
2001           msa[i] = (SequenceI) seqs.elementAt(i);\r
2002         }\r
2003       }\r
2004     }\r
2005     return msa;\r
2006   }\r
2007 \r
2008   /**\r
2009    * Decides what is submitted to a secondary structure prediction service,\r
2010    * the currently selected sequence, or the currently selected alignment\r
2011    * (where the first sequence in the set is the one that the prediction\r
2012    * will be for).\r
2013    */\r
2014   SequenceI[] gatherSeqOrMsaForSecStrPrediction()\r
2015   {\r
2016     SequenceI seq = null;\r
2017     SequenceI[] msa = null;\r
2018 \r
2019     if ( (viewport.getSelectionGroup() != null) &&\r
2020         (viewport.getSelectionGroup().getSize() > 0))\r
2021     {\r
2022       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2023       SequenceGroup seqs = viewport.getSelectionGroup();\r
2024 \r
2025       if ( (seqs.getSize() == 1) || !viewport.alignment.isAligned())\r
2026       {\r
2027         seq = (SequenceI) seqs.getSequenceAt(0);\r
2028       }\r
2029       else\r
2030       {\r
2031         int sz;\r
2032         msa = new SequenceI[sz = seqs.getSize()];\r
2033 \r
2034         for (int i = 0; i < sz; i++)\r
2035         {\r
2036           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2037         }\r
2038       }\r
2039     }\r
2040     else\r
2041     {\r
2042       Vector seqs = viewport.getAlignment().getSequences();\r
2043 \r
2044       if ( (seqs.size() == 1) || !viewport.alignment.isAligned())\r
2045       {\r
2046         seq = (SequenceI) seqs.elementAt(0);\r
2047       }\r
2048       else\r
2049       {\r
2050         msa = new SequenceI[seqs.size()];\r
2051 \r
2052         for (int i = 0; i < seqs.size(); i++)\r
2053         {\r
2054           msa[i] = (SequenceI) seqs.elementAt(i);\r
2055         }\r
2056       }\r
2057     }\r
2058     if (msa != null)\r
2059     {\r
2060       return msa;\r
2061     }\r
2062     else\r
2063     {\r
2064       if (seq != null)\r
2065       {\r
2066         return new SequenceI[]\r
2067             {\r
2068             seq};\r
2069       }\r
2070     }\r
2071     return null;\r
2072   }\r
2073   /**\r
2074    * DOCUMENT ME!\r
2075    *\r
2076    * @param e DOCUMENT ME!\r
2077    */\r
2078   protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
2079   {\r
2080     // Pick the tree file\r
2081     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
2082         getProperty(\r
2083             "LAST_DIRECTORY"));\r
2084     chooser.setFileView(new JalviewFileView());\r
2085     chooser.setDialogTitle("Select a newick-like tree file");\r
2086     chooser.setToolTipText("Load a tree file");\r
2087 \r
2088     int value = chooser.showOpenDialog(null);\r
2089 \r
2090     if (value == JalviewFileChooser.APPROVE_OPTION)\r
2091     {\r
2092       String choice = chooser.getSelectedFile().getPath();\r
2093       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
2094 \r
2095       try\r
2096       {\r
2097         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,\r
2098             "File");\r
2099         viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());\r
2100       }\r
2101       catch (Exception ex)\r
2102       {\r
2103         JOptionPane.showMessageDialog(Desktop.desktop,\r
2104                                       "Problem reading tree file",\r
2105                                       ex.getMessage(),\r
2106                                       JOptionPane.WARNING_MESSAGE);\r
2107         ex.printStackTrace();\r
2108       }\r
2109     }\r
2110   }\r
2111 \r
2112   /**\r
2113    * DOCUMENT ME!\r
2114    *\r
2115    * @param nf DOCUMENT ME!\r
2116    * @param title DOCUMENT ME!\r
2117    *\r
2118    * @return DOCUMENT ME!\r
2119    */\r
2120   public TreePanel ShowNewickTree(NewickFile nf, String title)\r
2121   {\r
2122     TreePanel tp = null;\r
2123 \r
2124     try\r
2125     {\r
2126       nf.parse();\r
2127 \r
2128       if (nf.getTree() != null)\r
2129       {\r
2130         tp = new TreePanel(viewport,\r
2131                            viewport.getAlignment().getSequences(), nf,\r
2132                            "FromFile",\r
2133                            title);\r
2134         Desktop.addInternalFrame(tp, title, 600, 500);\r
2135         addTreeMenuItem(tp, title);\r
2136       }\r
2137     }\r
2138     catch (Exception ex)\r
2139     {\r
2140       ex.printStackTrace();\r
2141     }\r
2142 \r
2143     return tp;\r
2144   }\r
2145 \r
2146   class PrintThread\r
2147       extends Thread\r
2148   {\r
2149     public void run()\r
2150     {\r
2151       PrinterJob printJob = PrinterJob.getPrinterJob();\r
2152       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
2153       printJob.setPrintable(alignPanel, pf);\r
2154 \r
2155       if (printJob.printDialog())\r
2156       {\r
2157         try\r
2158         {\r
2159           printJob.print();\r
2160         }\r
2161         catch (Exception PrintException)\r
2162         {\r
2163           PrintException.printStackTrace();\r
2164         }\r
2165       }\r
2166     }\r
2167   }\r
2168 \r
2169   /**\r
2170    * Generates menu items and listener event actions for web service clients\r
2171    *\r
2172    */\r
2173   public void BuildWebServiceMenu()\r
2174   {\r
2175     if ( (Desktop.discoverer.services != null)\r
2176         && (Desktop.discoverer.services.size() > 0))\r
2177     {\r
2178       Vector msaws = (Vector) Desktop.discoverer.services.get("MsaWS");\r
2179       Vector secstrpr = (Vector) Desktop.discoverer.services.get("SecStrPred");\r
2180       Vector wsmenu = new Vector();\r
2181       if (msaws != null)\r
2182       {\r
2183         // Add any Multiple Sequence Alignment Services\r
2184         final JMenu msawsmenu = new JMenu("Alignment");\r
2185         for (int i = 0, j = msaws.size(); i < j; i++)\r
2186         {\r
2187           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.\r
2188               get(i);\r
2189           final JMenuItem method = new JMenuItem(sh.getName());\r
2190           method.addActionListener(new ActionListener()\r
2191           {\r
2192             public void actionPerformed(ActionEvent e)\r
2193             {\r
2194               SequenceI[] msa = gatherSequencesForAlignment();\r
2195               MsaWSClient ct = new jalview.ws.MsaWSClient(sh, title, msa,\r
2196                   false, true);\r
2197 \r
2198             }\r
2199 \r
2200           });\r
2201           msawsmenu.add(method);\r
2202           // Deal with services that we know accept partial alignments.\r
2203           if (sh.getName().indexOf("lustal") > -1)\r
2204           {\r
2205             // We know that ClustalWS can accept partial alignments for refinement.\r
2206             final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");\r
2207             methodR.addActionListener(new ActionListener()\r
2208             {\r
2209               public void actionPerformed(ActionEvent e)\r
2210               {\r
2211                 SequenceI[] msa = gatherSequencesForAlignment();\r
2212                 MsaWSClient ct = new jalview.ws.MsaWSClient(sh, title, msa,\r
2213                     true, true);\r
2214 \r
2215               }\r
2216 \r
2217             });\r
2218             msawsmenu.add(methodR);\r
2219 \r
2220           }\r
2221         }\r
2222         wsmenu.add(msawsmenu);\r
2223       }\r
2224       if (secstrpr != null)\r
2225       {\r
2226         // Add any secondary structure prediction services\r
2227         final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");\r
2228         for (int i = 0, j = secstrpr.size(); i < j; i++)\r
2229         {\r
2230           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)\r
2231               secstrpr.get(i);\r
2232           final JMenuItem method = new JMenuItem(sh.getName());\r
2233           method.addActionListener(new ActionListener()\r
2234           {\r
2235             public void actionPerformed(ActionEvent e)\r
2236             {\r
2237               SequenceI[] msa = gatherSeqOrMsaForSecStrPrediction();\r
2238               if (msa.length == 1)\r
2239               {\r
2240                 // Single Sequence prediction\r
2241                 jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
2242                     title, msa[0]);\r
2243               }\r
2244               else\r
2245               {\r
2246                 if (msa.length > 1)\r
2247                 {\r
2248                   // Single Sequence prediction\r
2249                   jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
2250                       title, msa);\r
2251                 }\r
2252               }\r
2253             }\r
2254           });\r
2255           secstrmenu.add(method);\r
2256         }\r
2257         wsmenu.add(secstrmenu);\r
2258       }\r
2259       this.webService.removeAll();\r
2260       for (int i = 0, j = wsmenu.size(); i < j; i++)\r
2261       {\r
2262         webService.add( (JMenu) wsmenu.get(i));\r
2263       }\r
2264     }\r
2265     else\r
2266     {\r
2267       this.webService.removeAll();\r
2268       this.webService.add(this.webServiceNoServices);\r
2269     }\r
2270     // TODO: add in rediscovery function\r
2271     // TODO: reduce code redundancy.\r
2272     // TODO: group services by location as well as function.\r
2273   }\r
2274 \r
2275 }\r