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