Copy and paste uses FASTA format
[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       System.out.println("null here");\r
564       return;\r
565     }\r
566 \r
567     SequenceGroup sg = viewport.getSelectionGroup();\r
568 \r
569     Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
570 \r
571     Hashtable orderedSeqs = new Hashtable();\r
572     SequenceI [] seqs = new SequenceI[sg.getSize()];\r
573 \r
574     for (int i = 0; i < sg.getSize(); i++)\r
575     {\r
576       SequenceI seq = sg.getSequenceAt(i);\r
577       int index = viewport.alignment.findIndex(seq);\r
578       orderedSeqs.put(index + "", seq);\r
579     }\r
580 \r
581     int index = 0, startRes, endRes;\r
582     char ch;\r
583 \r
584     for (int i = 0; i < sg.getSize(); i++)\r
585     {\r
586       SequenceI seq = null;\r
587 \r
588       while (seq == null)\r
589       {\r
590         if (orderedSeqs.containsKey(index + ""))\r
591         {\r
592           seq = (SequenceI) orderedSeqs.get(index + "");\r
593           index++;\r
594 \r
595           break;\r
596         }\r
597         else\r
598         {\r
599           index++;\r
600         }\r
601       }\r
602 \r
603 \r
604       //FIND START RES\r
605       //Returns residue following index if gap\r
606       startRes = seq.findPosition(sg.getStartRes());\r
607 \r
608       //FIND END RES\r
609       //Need to find the residue preceeding index if gap\r
610       endRes = 0;\r
611 \r
612       for (int j = 0; j < sg.getEndRes() + 1 && j < seq.getLength(); j++)\r
613       {\r
614         ch = seq.getCharAt(j);\r
615         if (!jalview.util.Comparison.isGap( (ch)))\r
616         {\r
617           endRes++;\r
618         }\r
619       }\r
620 \r
621       if (endRes > 0)\r
622       {\r
623         endRes += seq.getStart() - 1;\r
624       }\r
625 \r
626       seqs[i] = new Sequence(seq.getName(),\r
627                              seq.getSequence(sg.getStartRes(), sg.getEndRes()+1),\r
628                              startRes,\r
629                              endRes);\r
630     }\r
631 \r
632     System.out.println("BLOBL"+FastaFile.print(seqs));\r
633 \r
634     c.setContents(new StringSelection(FastaFile.print(seqs)), null);\r
635   }\r
636 \r
637   /**\r
638    * DOCUMENT ME!\r
639    *\r
640    * @param e DOCUMENT ME!\r
641    */\r
642   protected void pasteNew_actionPerformed(ActionEvent e)\r
643   {\r
644     paste(true);\r
645   }\r
646 \r
647   /**\r
648    * DOCUMENT ME!\r
649    *\r
650    * @param e DOCUMENT ME!\r
651    */\r
652   protected void pasteThis_actionPerformed(ActionEvent e)\r
653   {\r
654     addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
655                                    HistoryItem.PASTE));\r
656     paste(false);\r
657   }\r
658 \r
659   /**\r
660    * DOCUMENT ME!\r
661    *\r
662    * @param newAlignment DOCUMENT ME!\r
663    */\r
664   void paste(boolean newAlignment)\r
665   {\r
666     try\r
667     {\r
668       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
669       Transferable contents = c.getContents(this);\r
670 \r
671       if (contents == null)\r
672       {\r
673         return;\r
674       }\r
675 \r
676       String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
677 \r
678       String format = IdentifyFile.Identify(str, "Paste");\r
679       SequenceI[] sequences = FormatAdapter.readFile(str, "Paste", format);\r
680 \r
681 \r
682       if (newAlignment)\r
683       {\r
684         AlignFrame af = new AlignFrame(new Alignment(sequences));\r
685         String newtitle = new String("Copied sequences");\r
686 \r
687         if (title.startsWith("Copied sequences"))\r
688         {\r
689           newtitle = title;\r
690         }\r
691         else\r
692         {\r
693           newtitle = newtitle.concat("- from " + title);\r
694         }\r
695 \r
696         Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
697                                  NEW_WINDOW_HEIGHT);\r
698       }\r
699       else\r
700       {\r
701         //!newAlignment\r
702         for (int i = 0; i < sequences.length; i++)\r
703           viewport.alignment.addSequence(sequences[i]);\r
704 \r
705         viewport.setEndSeq(viewport.alignment.getHeight());\r
706         viewport.alignment.getWidth();\r
707         viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
708       }\r
709     }\r
710     catch (Exception ex)\r
711     {\r
712         // could be anything being pasted in here\r
713     }\r
714 \r
715 \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 \r
737     if (viewport.getSelectionGroup() == null)\r
738     {\r
739       return;\r
740     }\r
741 \r
742     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
743                                    HistoryItem.HIDE));\r
744 \r
745     SequenceGroup sg = viewport.getSelectionGroup();\r
746     boolean allSequences = false;\r
747     if (sg.sequences.size() == viewport.alignment.getHeight())\r
748     {\r
749       allSequences = true;\r
750     }\r
751 \r
752     for (int i = 0; i < sg.sequences.size(); i++)\r
753     {\r
754       SequenceI seq = sg.getSequenceAt(i);\r
755       int index = viewport.getAlignment().findIndex(seq);\r
756       seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
757 \r
758       // If the cut affects all sequences, remove highlighted columns\r
759       if (allSequences)\r
760       {\r
761         viewport.getColumnSelection().removeElements(sg.getStartRes(),\r
762             sg.getEndRes() + 1);\r
763       }\r
764 \r
765       if (seq.getSequence().length() < 1)\r
766       {\r
767         viewport.getAlignment().deleteSequence(seq);\r
768       }\r
769       else\r
770       {\r
771         viewport.getAlignment().getSequences().setElementAt(seq, index);\r
772       }\r
773     }\r
774 \r
775     viewport.setSelectionGroup(null);\r
776     viewport.alignment.deleteGroup(sg);\r
777 \r
778     viewport.firePropertyChange("alignment", null,\r
779                                   viewport.getAlignment().getSequences());\r
780 \r
781 \r
782 \r
783     if (viewport.getAlignment().getHeight() < 1)\r
784     {\r
785       try\r
786       {\r
787         this.setClosed(true);\r
788       }\r
789       catch (Exception ex)\r
790       {\r
791       }\r
792     }\r
793   }\r
794 \r
795   /**\r
796    * DOCUMENT ME!\r
797    *\r
798    * @param e DOCUMENT ME!\r
799    */\r
800   protected void deleteGroups_actionPerformed(ActionEvent e)\r
801   {\r
802     viewport.alignment.deleteAllGroups();\r
803     viewport.setSelectionGroup(null);\r
804     alignPanel.repaint();\r
805   }\r
806 \r
807   /**\r
808    * DOCUMENT ME!\r
809    *\r
810    * @param e DOCUMENT ME!\r
811    */\r
812   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
813   {\r
814     SequenceGroup sg = new SequenceGroup();\r
815 \r
816     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
817          i++)\r
818     {\r
819       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
820     }\r
821 \r
822     sg.setEndRes(viewport.alignment.getWidth() - 1);\r
823     viewport.setSelectionGroup(sg);\r
824     PaintRefresher.Refresh(null, viewport.alignment);\r
825   }\r
826 \r
827   /**\r
828    * DOCUMENT ME!\r
829    *\r
830    * @param e DOCUMENT ME!\r
831    */\r
832   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
833   {\r
834     viewport.setSelectionGroup(null);\r
835     viewport.getColumnSelection().clear();\r
836     viewport.setSelectionGroup(null);\r
837     alignPanel.annotationPanel.activeRes = null;\r
838     PaintRefresher.Refresh(null, viewport.alignment);\r
839   }\r
840 \r
841   /**\r
842    * DOCUMENT ME!\r
843    *\r
844    * @param e DOCUMENT ME!\r
845    */\r
846   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
847   {\r
848     SequenceGroup sg = viewport.getSelectionGroup();\r
849 \r
850     if (sg == null)\r
851     {\r
852       selectAllSequenceMenuItem_actionPerformed(null);\r
853 \r
854       return;\r
855     }\r
856 \r
857     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
858          i++)\r
859     {\r
860       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
861     }\r
862 \r
863     PaintRefresher.Refresh(null, viewport.alignment);\r
864   }\r
865 \r
866   /**\r
867    * DOCUMENT ME!\r
868    *\r
869    * @param e DOCUMENT ME!\r
870    */\r
871   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
872   {\r
873     ColumnSelection colSel = viewport.getColumnSelection();\r
874 \r
875     if (colSel.size() > 0)\r
876     {\r
877       addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
878                                      HistoryItem.HIDE));\r
879 \r
880       int min = colSel.getMin();\r
881       viewport.getAlignment().trimLeft(min);\r
882       colSel.compensateForEdit(0, min);\r
883 \r
884       if (viewport.getSelectionGroup() != null)\r
885       {\r
886         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
887       }\r
888 \r
889       Vector groups = viewport.alignment.getGroups();\r
890 \r
891       for (int i = 0; i < groups.size(); i++)\r
892       {\r
893         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
894 \r
895         if (!sg.adjustForRemoveLeft(min))\r
896         {\r
897           viewport.alignment.deleteGroup(sg);\r
898         }\r
899       }\r
900 \r
901       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
902     }\r
903   }\r
904 \r
905   /**\r
906    * DOCUMENT ME!\r
907    *\r
908    * @param e DOCUMENT ME!\r
909    */\r
910   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
911   {\r
912     ColumnSelection colSel = viewport.getColumnSelection();\r
913 \r
914     if (colSel.size() > 0)\r
915     {\r
916       addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
917                                      HistoryItem.HIDE));\r
918 \r
919       int max = colSel.getMax();\r
920       viewport.getAlignment().trimRight(max);\r
921 \r
922       if (viewport.getSelectionGroup() != null)\r
923       {\r
924         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
925       }\r
926 \r
927       Vector groups = viewport.alignment.getGroups();\r
928 \r
929       for (int i = 0; i < groups.size(); i++)\r
930       {\r
931         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
932 \r
933         if (!sg.adjustForRemoveRight(max))\r
934         {\r
935           viewport.alignment.deleteGroup(sg);\r
936         }\r
937       }\r
938 \r
939       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
940     }\r
941   }\r
942 \r
943   /**\r
944    * DOCUMENT ME!\r
945    *\r
946    * @param e DOCUMENT ME!\r
947    */\r
948   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
949   {\r
950     addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
951                                    viewport.alignment, HistoryItem.HIDE));\r
952 \r
953     //This is to maintain viewport position on first residue\r
954     //of first sequence\r
955     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
956     int startRes = seq.findPosition(viewport.startRes);\r
957 \r
958     viewport.getAlignment().removeGaps();\r
959 \r
960     viewport.setStartRes(seq.findIndex(startRes)-1);\r
961 \r
962    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
963   }\r
964 \r
965   /**\r
966    * DOCUMENT ME!\r
967    *\r
968    * @param e DOCUMENT ME!\r
969    */\r
970   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
971   {\r
972     addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
973                                    HistoryItem.HIDE));\r
974 \r
975     //This is to maintain viewport position on first residue\r
976     //of first sequence\r
977     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
978     int startRes = seq.findPosition(viewport.startRes);\r
979 \r
980 \r
981     SequenceI current;\r
982     int jSize;\r
983 \r
984     Vector seqs = null;\r
985 \r
986     int start = 0;\r
987     int end = viewport.alignment.getWidth();\r
988 \r
989     if (viewport.getSelectionGroup() != null\r
990         && viewport.getSelectionGroup().sequences != null\r
991         && viewport.getSelectionGroup().sequences.size() > 0)\r
992     {\r
993       seqs = viewport.getSelectionGroup().sequences;\r
994       start = viewport.getSelectionGroup().getStartRes();\r
995       end = viewport.getSelectionGroup().getEndRes()+1;\r
996     }\r
997     else\r
998     {\r
999       seqs = viewport.alignment.getSequences();\r
1000     }\r
1001 \r
1002     for (int i = 0; i < seqs.size(); i++)\r
1003     {\r
1004       current = (SequenceI) seqs.elementAt(i);\r
1005       jSize = current.getLength();\r
1006 \r
1007       // Removing a range is much quicker than removing gaps\r
1008       // one by one for long sequences\r
1009       int j = start;\r
1010       int rangeStart=-1, rangeEnd=-1;\r
1011 \r
1012       do\r
1013       {\r
1014         if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
1015         {\r
1016           if(rangeStart==-1)\r
1017            {\r
1018              rangeStart = j;\r
1019              rangeEnd = j+1;\r
1020            }\r
1021            else\r
1022            {\r
1023              rangeEnd++;\r
1024            }\r
1025            j++;\r
1026         }\r
1027         else\r
1028         {\r
1029           if(rangeStart>-1)\r
1030           {\r
1031             current.deleteChars(rangeStart, rangeEnd);\r
1032             j-=rangeEnd-rangeStart;\r
1033             jSize-=rangeEnd-rangeStart;\r
1034             rangeStart = -1;\r
1035             rangeEnd = -1;\r
1036           }\r
1037           else\r
1038             j++;\r
1039         }\r
1040       }\r
1041       while (j < end && j < jSize);\r
1042       if(rangeStart>-1)\r
1043       {\r
1044        current.deleteChars(rangeStart, rangeEnd);\r
1045       }\r
1046     }\r
1047 \r
1048     viewport.setStartRes(seq.findIndex(startRes)-1);\r
1049 \r
1050     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
1051   }\r
1052 \r
1053  public void alignmentChanged()\r
1054  {\r
1055    if(viewport.vconsensus!=null)\r
1056    {\r
1057      viewport.updateConsensus();\r
1058      viewport.updateConservation();\r
1059    }\r
1060    resetAllColourSchemes();\r
1061    if(alignPanel.overviewPanel!=null)\r
1062      alignPanel.overviewPanel.updateOverviewImage();\r
1063 \r
1064    alignPanel.repaint();\r
1065  }\r
1066 \r
1067   void resetAllColourSchemes()\r
1068   {\r
1069     ColourSchemeI cs = viewport.globalColourScheme;\r
1070     if(cs!=null)\r
1071     {\r
1072       if (cs instanceof ClustalxColourScheme)\r
1073       {\r
1074         ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).\r
1075             resetClustalX(viewport.alignment.getSequences(),\r
1076                           viewport.alignment.getWidth());\r
1077       }\r
1078 \r
1079       cs.setConsensus(viewport.vconsensus);\r
1080       if (cs.conservationApplied())\r
1081       {\r
1082         Alignment al = (Alignment) viewport.alignment;\r
1083         Conservation c = new Conservation("All",\r
1084                                           ResidueProperties.propHash, 3,\r
1085                                           al.getSequences(), 0,\r
1086                                           al.getWidth() - 1);\r
1087         c.calculate();\r
1088         c.verdict(false, viewport.ConsPercGaps);\r
1089 \r
1090         cs.setConservation(c);\r
1091       }\r
1092     }\r
1093 \r
1094     int s, sSize = viewport.alignment.getGroups().size();\r
1095     for(s=0; s<sSize; s++)\r
1096     {\r
1097       SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);\r
1098       if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)\r
1099       {\r
1100         ((ClustalxColourScheme)sg.cs).resetClustalX(sg.sequences, sg.getWidth());\r
1101       }\r
1102       sg.recalcConservation();\r
1103     }\r
1104   }\r
1105 \r
1106   /**\r
1107    * DOCUMENT ME!\r
1108    *\r
1109    * @param e DOCUMENT ME!\r
1110    */\r
1111   public void padGapsMenuitem_actionPerformed(ActionEvent e)\r
1112   {\r
1113     addHistoryItem(new HistoryItem("Pad Gaps", viewport.alignment,\r
1114                                    HistoryItem.HIDE));\r
1115 \r
1116     SequenceI current;\r
1117     int Width = viewport.getAlignment().getWidth();\r
1118 \r
1119     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
1120          i++)\r
1121     {\r
1122       current = viewport.getAlignment().getSequenceAt(i);\r
1123 \r
1124       if (current.getLength() < Width)\r
1125       {\r
1126         current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
1127       }\r
1128     }\r
1129 \r
1130     alignmentChanged();\r
1131   }\r
1132 \r
1133   /**\r
1134    * DOCUMENT ME!\r
1135    *\r
1136    * @param e DOCUMENT ME!\r
1137    */\r
1138   public void findMenuItem_actionPerformed(ActionEvent e)\r
1139   {\r
1140     JInternalFrame frame = new JInternalFrame();\r
1141     Finder finder = new Finder(viewport, alignPanel, frame);\r
1142     frame.setContentPane(finder);\r
1143     Desktop.addInternalFrame(frame, "Find", 340, 110);\r
1144     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
1145   }\r
1146 \r
1147   /**\r
1148    * DOCUMENT ME!\r
1149    *\r
1150    * @param e DOCUMENT ME!\r
1151    */\r
1152   public void font_actionPerformed(ActionEvent e)\r
1153   {\r
1154     FontChooser fc = new FontChooser(alignPanel);\r
1155   }\r
1156 \r
1157   /**\r
1158    * DOCUMENT ME!\r
1159    *\r
1160    * @param e DOCUMENT ME!\r
1161    */\r
1162   protected void fullSeqId_actionPerformed(ActionEvent e)\r
1163   {\r
1164     viewport.setShowFullId(fullSeqId.isSelected());\r
1165 \r
1166     alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());\r
1167     alignPanel.repaint();\r
1168   }\r
1169 \r
1170   /**\r
1171    * DOCUMENT ME!\r
1172    *\r
1173    * @param e DOCUMENT ME!\r
1174    */\r
1175   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
1176   {\r
1177     viewport.setColourText(colourTextMenuItem.isSelected());\r
1178     alignPanel.repaint();\r
1179   }\r
1180 \r
1181   /**\r
1182    * DOCUMENT ME!\r
1183    *\r
1184    * @param e DOCUMENT ME!\r
1185    */\r
1186   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
1187   {\r
1188     viewport.setWrapAlignment(wrapMenuItem.isSelected());\r
1189     alignPanel.setWrapAlignment(wrapMenuItem.isSelected());\r
1190     scaleAbove.setVisible(wrapMenuItem.isSelected());\r
1191     scaleLeft.setVisible(wrapMenuItem.isSelected());\r
1192     scaleRight.setVisible(wrapMenuItem.isSelected());\r
1193     alignPanel.repaint();\r
1194   }\r
1195 \r
1196   /**\r
1197    * DOCUMENT ME!\r
1198    *\r
1199    * @param e DOCUMENT ME!\r
1200    */\r
1201   protected void scaleAbove_actionPerformed(ActionEvent e)\r
1202   {\r
1203     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
1204     alignPanel.repaint();\r
1205   }\r
1206 \r
1207   /**\r
1208    * DOCUMENT ME!\r
1209    *\r
1210    * @param e DOCUMENT ME!\r
1211    */\r
1212   protected void scaleLeft_actionPerformed(ActionEvent e)\r
1213   {\r
1214     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
1215     alignPanel.repaint();\r
1216   }\r
1217 \r
1218   /**\r
1219    * DOCUMENT ME!\r
1220    *\r
1221    * @param e DOCUMENT ME!\r
1222    */\r
1223   protected void scaleRight_actionPerformed(ActionEvent e)\r
1224   {\r
1225     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
1226     alignPanel.repaint();\r
1227   }\r
1228 \r
1229   /**\r
1230    * DOCUMENT ME!\r
1231    *\r
1232    * @param e DOCUMENT ME!\r
1233    */\r
1234   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
1235   {\r
1236     viewport.setShowBoxes(viewBoxesMenuItem.isSelected());\r
1237     alignPanel.repaint();\r
1238   }\r
1239 \r
1240   /**\r
1241    * DOCUMENT ME!\r
1242    *\r
1243    * @param e DOCUMENT ME!\r
1244    */\r
1245   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
1246   {\r
1247     viewport.setShowText(viewTextMenuItem.isSelected());\r
1248     alignPanel.repaint();\r
1249   }\r
1250 \r
1251   /**\r
1252    * DOCUMENT ME!\r
1253    *\r
1254    * @param e DOCUMENT ME!\r
1255    */\r
1256   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
1257   {\r
1258     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
1259     alignPanel.repaint();\r
1260   }\r
1261 \r
1262   /**\r
1263    * DOCUMENT ME!\r
1264    *\r
1265    * @param evt DOCUMENT ME!\r
1266    */\r
1267   public void sequenceFeatures_actionPerformed(ActionEvent evt)\r
1268   {\r
1269     viewport.showSequenceFeatures(sequenceFeatures.isSelected());\r
1270 \r
1271     if (viewport.showSequenceFeatures &&\r
1272         ! ( (Alignment) viewport.alignment).featuresAdded)\r
1273     {\r
1274       SequenceFeatureFetcher sft = new SequenceFeatureFetcher(viewport.\r
1275           alignment,\r
1276           alignPanel);\r
1277       ( (Alignment) viewport.alignment).featuresAdded = true;\r
1278     }\r
1279 \r
1280     alignPanel.repaint();\r
1281   }\r
1282 \r
1283   /**\r
1284    * DOCUMENT ME!\r
1285    *\r
1286    * @param e DOCUMENT ME!\r
1287    */\r
1288   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
1289   {\r
1290     if (annotationPanelMenuItem.isSelected() &&\r
1291         viewport.getWrapAlignment())\r
1292     {\r
1293       annotationPanelMenuItem.setSelected(false);\r
1294 \r
1295       return;\r
1296     }\r
1297 \r
1298     viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());\r
1299     alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());\r
1300   }\r
1301 \r
1302   /**\r
1303    * DOCUMENT ME!\r
1304    *\r
1305    * @param e DOCUMENT ME!\r
1306    */\r
1307   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
1308   {\r
1309     if (alignPanel.overviewPanel != null)\r
1310     {\r
1311       return;\r
1312     }\r
1313 \r
1314     JInternalFrame frame = new JInternalFrame();\r
1315     OverviewPanel overview = new OverviewPanel(alignPanel);\r
1316     frame.setContentPane(overview);\r
1317     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
1318                              frame.getWidth(), frame.getHeight());\r
1319     frame.pack();\r
1320     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
1321     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
1322     {\r
1323       public void internalFrameClosed(\r
1324           javax.swing.event.InternalFrameEvent evt)\r
1325       {\r
1326         alignPanel.setOverviewPanel(null);\r
1327       }\r
1328       ;\r
1329     });\r
1330 \r
1331     alignPanel.setOverviewPanel(overview);\r
1332   }\r
1333 \r
1334   /**\r
1335    * DOCUMENT ME!\r
1336    *\r
1337    * @param e DOCUMENT ME!\r
1338    */\r
1339   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
1340   {\r
1341     changeColour(null);\r
1342   }\r
1343 \r
1344   /**\r
1345    * DOCUMENT ME!\r
1346    *\r
1347    * @param e DOCUMENT ME!\r
1348    */\r
1349   public void clustalColour_actionPerformed(ActionEvent e)\r
1350   {\r
1351     changeColour(new ClustalxColourScheme(\r
1352         viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
1353   }\r
1354 \r
1355   /**\r
1356    * DOCUMENT ME!\r
1357    *\r
1358    * @param e DOCUMENT ME!\r
1359    */\r
1360   public void zappoColour_actionPerformed(ActionEvent e)\r
1361   {\r
1362     changeColour(new ZappoColourScheme());\r
1363   }\r
1364 \r
1365   /**\r
1366    * DOCUMENT ME!\r
1367    *\r
1368    * @param e DOCUMENT ME!\r
1369    */\r
1370   public void taylorColour_actionPerformed(ActionEvent e)\r
1371   {\r
1372     changeColour(new TaylorColourScheme());\r
1373   }\r
1374 \r
1375   /**\r
1376    * DOCUMENT ME!\r
1377    *\r
1378    * @param e DOCUMENT ME!\r
1379    */\r
1380   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
1381   {\r
1382     changeColour(new HydrophobicColourScheme());\r
1383   }\r
1384 \r
1385   /**\r
1386    * DOCUMENT ME!\r
1387    *\r
1388    * @param e DOCUMENT ME!\r
1389    */\r
1390   public void helixColour_actionPerformed(ActionEvent e)\r
1391   {\r
1392     changeColour(new HelixColourScheme());\r
1393   }\r
1394 \r
1395   /**\r
1396    * DOCUMENT ME!\r
1397    *\r
1398    * @param e DOCUMENT ME!\r
1399    */\r
1400   public void strandColour_actionPerformed(ActionEvent e)\r
1401   {\r
1402     changeColour(new StrandColourScheme());\r
1403   }\r
1404 \r
1405   /**\r
1406    * DOCUMENT ME!\r
1407    *\r
1408    * @param e DOCUMENT ME!\r
1409    */\r
1410   public void turnColour_actionPerformed(ActionEvent e)\r
1411   {\r
1412     changeColour(new TurnColourScheme());\r
1413   }\r
1414 \r
1415   /**\r
1416    * DOCUMENT ME!\r
1417    *\r
1418    * @param e DOCUMENT ME!\r
1419    */\r
1420   public void buriedColour_actionPerformed(ActionEvent e)\r
1421   {\r
1422     changeColour(new BuriedColourScheme());\r
1423   }\r
1424 \r
1425   /**\r
1426    * DOCUMENT ME!\r
1427    *\r
1428    * @param e DOCUMENT ME!\r
1429    */\r
1430   public void nucleotideColour_actionPerformed(ActionEvent e)\r
1431   {\r
1432     changeColour(new NucleotideColourScheme());\r
1433   }\r
1434 \r
1435   /**\r
1436    * DOCUMENT ME!\r
1437    *\r
1438    * @param e DOCUMENT ME!\r
1439    */\r
1440   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
1441   {\r
1442     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
1443   }\r
1444 \r
1445   /**\r
1446    * DOCUMENT ME!\r
1447    *\r
1448    * @param cs DOCUMENT ME!\r
1449    */\r
1450   void changeColour(ColourSchemeI cs)\r
1451   {\r
1452     int threshold = 0;\r
1453 \r
1454     if(cs!=null)\r
1455     {\r
1456       if (viewport.getAbovePIDThreshold())\r
1457       {\r
1458         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,\r
1459                                                    "Background");\r
1460 \r
1461         cs.setThreshold(threshold,\r
1462                         viewport.getIgnoreGapsConsensus());\r
1463 \r
1464         viewport.setGlobalColourScheme(cs);\r
1465       }\r
1466       else\r
1467       {\r
1468         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1469       }\r
1470 \r
1471       if (viewport.getConservationSelected())\r
1472       {\r
1473 \r
1474         Alignment al = (Alignment) viewport.alignment;\r
1475         Conservation c = new Conservation("All",\r
1476                                           ResidueProperties.propHash, 3,\r
1477                                           al.getSequences(), 0,\r
1478                                           al.getWidth() - 1);\r
1479 \r
1480         c.calculate();\r
1481         c.verdict(false, viewport.ConsPercGaps);\r
1482 \r
1483         cs.setConservation(c);\r
1484 \r
1485         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
1486             "Background"));\r
1487       }\r
1488       else\r
1489       {\r
1490         cs.setConservation(null);\r
1491       }\r
1492 \r
1493       cs.setConsensus(viewport.vconsensus);\r
1494     }\r
1495 \r
1496     viewport.setGlobalColourScheme(cs);\r
1497 \r
1498     if (viewport.getColourAppliesToAllGroups())\r
1499     {\r
1500       Vector groups = viewport.alignment.getGroups();\r
1501 \r
1502       for (int i = 0; i < groups.size(); i++)\r
1503       {\r
1504         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
1505 \r
1506         if (cs == null)\r
1507         {\r
1508           sg.cs = null;\r
1509           continue;\r
1510         }\r
1511 \r
1512         if (cs instanceof ClustalxColourScheme)\r
1513         {\r
1514           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
1515         }\r
1516         else if (cs instanceof UserColourScheme)\r
1517         {\r
1518           sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());\r
1519         }\r
1520         else\r
1521         {\r
1522           try\r
1523           {\r
1524             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
1525           }\r
1526           catch (Exception ex)\r
1527           {\r
1528           }\r
1529         }\r
1530 \r
1531         if (viewport.getAbovePIDThreshold()\r
1532             || cs instanceof PIDColourScheme\r
1533             || cs instanceof Blosum62ColourScheme)\r
1534         {\r
1535          sg.cs.setThreshold(threshold,\r
1536                 viewport.getIgnoreGapsConsensus());\r
1537 \r
1538           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1539               sg.getWidth()));\r
1540         }\r
1541         else\r
1542           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1543 \r
1544 \r
1545         if (viewport.getConservationSelected())\r
1546         {\r
1547           Conservation c = new Conservation("Group",\r
1548                                             ResidueProperties.propHash, 3,\r
1549                                             sg.sequences, 0,\r
1550                                             viewport.alignment.getWidth() - 1);\r
1551           c.calculate();\r
1552           c.verdict(false, viewport.ConsPercGaps);\r
1553           sg.cs.setConservation(c);\r
1554         }\r
1555         else\r
1556           sg.cs.setConservation(null);\r
1557       }\r
1558     }\r
1559 \r
1560     if (alignPanel.getOverviewPanel() != null)\r
1561     {\r
1562       alignPanel.getOverviewPanel().updateOverviewImage();\r
1563     }\r
1564 \r
1565     alignPanel.repaint();\r
1566   }\r
1567 \r
1568   /**\r
1569    * DOCUMENT ME!\r
1570    *\r
1571    * @param e DOCUMENT ME!\r
1572    */\r
1573   protected void modifyPID_actionPerformed(ActionEvent e)\r
1574   {\r
1575     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
1576     {\r
1577       SliderPanel.setPIDSliderSource(alignPanel,\r
1578                                      viewport.getGlobalColourScheme(),\r
1579                                      "Background");\r
1580       SliderPanel.showPIDSlider();\r
1581     }\r
1582   }\r
1583 \r
1584   /**\r
1585    * DOCUMENT ME!\r
1586    *\r
1587    * @param e DOCUMENT ME!\r
1588    */\r
1589   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1590   {\r
1591     if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
1592     {\r
1593       SliderPanel.setConservationSlider(alignPanel,\r
1594                                         viewport.globalColourScheme,\r
1595                                         "Background");\r
1596       SliderPanel.showConservationSlider();\r
1597     }\r
1598   }\r
1599 \r
1600   /**\r
1601    * DOCUMENT ME!\r
1602    *\r
1603    * @param e DOCUMENT ME!\r
1604    */\r
1605   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1606   {\r
1607     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
1608 \r
1609     viewport.setAbovePIDThreshold(false);\r
1610     abovePIDThreshold.setSelected(false);\r
1611 \r
1612     changeColour(viewport.getGlobalColourScheme());\r
1613 \r
1614     modifyConservation_actionPerformed(null);\r
1615   }\r
1616 \r
1617   /**\r
1618    * DOCUMENT ME!\r
1619    *\r
1620    * @param e DOCUMENT ME!\r
1621    */\r
1622   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1623   {\r
1624     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
1625 \r
1626     conservationMenuItem.setSelected(false);\r
1627     viewport.setConservationSelected(false);\r
1628 \r
1629     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
1630 \r
1631     changeColour(viewport.getGlobalColourScheme());\r
1632 \r
1633     modifyPID_actionPerformed(null);\r
1634   }\r
1635 \r
1636   /**\r
1637    * DOCUMENT ME!\r
1638    *\r
1639    * @param e DOCUMENT ME!\r
1640    */\r
1641   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1642   {\r
1643     if (e.getActionCommand().equals("User Defined..."))\r
1644     {\r
1645       new UserDefinedColours(alignPanel, null);\r
1646     }\r
1647     else\r
1648     {\r
1649       UserColourScheme udc = (UserColourScheme) UserDefinedColours.\r
1650           getUserColourSchemes().get(e.getActionCommand());\r
1651 \r
1652       changeColour(udc);\r
1653     }\r
1654   }\r
1655 \r
1656   public void updateUserColourMenu()\r
1657   {\r
1658 \r
1659     Component[] menuItems = colourMenu.getMenuComponents();\r
1660     int i, iSize = menuItems.length;\r
1661     for (i = 0; i < iSize; i++)\r
1662     {\r
1663       if (menuItems[i].getName() != null &&\r
1664           menuItems[i].getName().equals("USER_DEFINED"))\r
1665       {\r
1666         colourMenu.remove(menuItems[i]);\r
1667         iSize--;\r
1668       }\r
1669     }\r
1670     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)\r
1671     {\r
1672       java.util.Enumeration userColours = jalview.gui.UserDefinedColours.\r
1673           getUserColourSchemes().keys();\r
1674 \r
1675       while (userColours.hasMoreElements())\r
1676       {\r
1677         final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.\r
1678             nextElement().toString());\r
1679         radioItem.setName("USER_DEFINED");\r
1680         radioItem.addMouseListener(new MouseAdapter()\r
1681             {\r
1682               public void mousePressed(MouseEvent evt)\r
1683               {\r
1684                 if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))\r
1685                 {\r
1686                   radioItem.removeActionListener(radioItem.getActionListeners()[0]);\r
1687 \r
1688                   int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,\r
1689                       "Remove from default list?",\r
1690                       "Remove user defined colour",\r
1691                       JOptionPane.YES_NO_OPTION);\r
1692                   if(option == JOptionPane.YES_OPTION)\r
1693                   {\r
1694                     jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());\r
1695                     colourMenu.remove(radioItem);\r
1696                   }\r
1697                   else\r
1698                     radioItem.addActionListener(new ActionListener()\r
1699                     {\r
1700                       public void actionPerformed(ActionEvent evt)\r
1701                       {\r
1702                         userDefinedColour_actionPerformed(evt);\r
1703                       }\r
1704                     });\r
1705                 }\r
1706               }\r
1707             });\r
1708         radioItem.addActionListener(new ActionListener()\r
1709         {\r
1710           public void actionPerformed(ActionEvent evt)\r
1711           {\r
1712             userDefinedColour_actionPerformed(evt);\r
1713           }\r
1714         });\r
1715 \r
1716         colourMenu.insert(radioItem, 15);\r
1717         colours.add(radioItem);\r
1718       }\r
1719     }\r
1720   }\r
1721 \r
1722   /**\r
1723    * DOCUMENT ME!\r
1724    *\r
1725    * @param e DOCUMENT ME!\r
1726    */\r
1727   public void PIDColour_actionPerformed(ActionEvent e)\r
1728   {\r
1729     changeColour(new PIDColourScheme());\r
1730   }\r
1731 \r
1732   /**\r
1733    * DOCUMENT ME!\r
1734    *\r
1735    * @param e DOCUMENT ME!\r
1736    */\r
1737   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1738   {\r
1739     changeColour(new Blosum62ColourScheme());\r
1740   }\r
1741 \r
1742   /**\r
1743    * DOCUMENT ME!\r
1744    *\r
1745    * @param e DOCUMENT ME!\r
1746    */\r
1747   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1748   {\r
1749     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1750                                    HistoryItem.SORT));\r
1751     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1752                               viewport.getAlignment().getSequenceAt(0));\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 sortIDMenuItem_actionPerformed(ActionEvent e)\r
1762   {\r
1763     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1764                                    HistoryItem.SORT));\r
1765     AlignmentSorter.sortByID(viewport.getAlignment());\r
1766     alignPanel.repaint();\r
1767   }\r
1768 \r
1769   /**\r
1770    * DOCUMENT ME!\r
1771    *\r
1772    * @param e DOCUMENT ME!\r
1773    */\r
1774   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1775   {\r
1776     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1777                                    HistoryItem.SORT));\r
1778 \r
1779     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1780     alignPanel.repaint();\r
1781   }\r
1782 \r
1783   /**\r
1784    * DOCUMENT ME!\r
1785    *\r
1786    * @param e DOCUMENT ME!\r
1787    */\r
1788   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1789   {\r
1790     RedundancyPanel sp = new RedundancyPanel(alignPanel, this);\r
1791     JInternalFrame frame = new JInternalFrame();\r
1792     frame.setContentPane(sp);\r
1793     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
1794                              100, false);\r
1795   }\r
1796 \r
1797   /**\r
1798    * DOCUMENT ME!\r
1799    *\r
1800    * @param e DOCUMENT ME!\r
1801    */\r
1802   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1803   {\r
1804     if ( (viewport.getSelectionGroup() == null) ||\r
1805         (viewport.getSelectionGroup().getSize() < 2))\r
1806     {\r
1807       JOptionPane.showInternalMessageDialog(this,\r
1808                                             "You must select at least 2 sequences.",\r
1809                                             "Invalid Selection",\r
1810                                             JOptionPane.WARNING_MESSAGE);\r
1811     }\r
1812     else\r
1813     {\r
1814       JInternalFrame frame = new JInternalFrame();\r
1815       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
1816       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
1817     }\r
1818   }\r
1819 \r
1820   /**\r
1821    * DOCUMENT ME!\r
1822    *\r
1823    * @param e DOCUMENT ME!\r
1824    */\r
1825   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1826   {\r
1827     if ( ( (viewport.getSelectionGroup() != null) &&\r
1828           (viewport.getSelectionGroup().getSize() < 4) &&\r
1829           (viewport.getSelectionGroup().getSize() > 0)) ||\r
1830         (viewport.getAlignment().getHeight() < 4))\r
1831     {\r
1832       JOptionPane.showInternalMessageDialog(this,\r
1833                                             "Principal component analysis must take\n" +\r
1834                                             "at least 4 input sequences.",\r
1835                                             "Sequence selection insufficient",\r
1836                                             JOptionPane.WARNING_MESSAGE);\r
1837 \r
1838       return;\r
1839     }\r
1840 \r
1841       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
1842       JInternalFrame frame = new JInternalFrame();\r
1843       frame.setContentPane(pcaPanel);\r
1844       Desktop.addInternalFrame(frame, "Principal component analysis",\r
1845                                400, 400);\r
1846   }\r
1847 \r
1848   /**\r
1849    * DOCUMENT ME!\r
1850    *\r
1851    * @param e DOCUMENT ME!\r
1852    */\r
1853   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1854   {\r
1855     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1856   }\r
1857 \r
1858   /**\r
1859    * DOCUMENT ME!\r
1860    *\r
1861    * @param e DOCUMENT ME!\r
1862    */\r
1863   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1864   {\r
1865     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1866   }\r
1867 \r
1868   /**\r
1869    * DOCUMENT ME!\r
1870    *\r
1871    * @param e DOCUMENT ME!\r
1872    */\r
1873   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1874   {\r
1875     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1876   }\r
1877 \r
1878   /**\r
1879    * DOCUMENT ME!\r
1880    *\r
1881    * @param e DOCUMENT ME!\r
1882    */\r
1883   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1884   {\r
1885     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");\r
1886   }\r
1887 \r
1888   /**\r
1889    * DOCUMENT ME!\r
1890    *\r
1891    * @param type DOCUMENT ME!\r
1892    * @param pwType DOCUMENT ME!\r
1893    * @param title DOCUMENT ME!\r
1894    */\r
1895   void NewTreePanel(String type, String pwType, String title)\r
1896   {\r
1897     final TreePanel tp;\r
1898 \r
1899     if ( (viewport.getSelectionGroup() != null) &&\r
1900         (viewport.getSelectionGroup().getSize() > 3))\r
1901     {\r
1902       int s = 0;\r
1903       SequenceGroup sg = viewport.getSelectionGroup();\r
1904 \r
1905       /* Decide if the selection is a column region */\r
1906       while (s < sg.sequences.size())\r
1907       {\r
1908         if ( ( (SequenceI) sg.sequences.elementAt(s++)).getLength() <\r
1909             sg.getEndRes())\r
1910         {\r
1911           JOptionPane.showMessageDialog(Desktop.desktop,\r
1912                                         "The selected region to create a tree may\nonly contain residues or gaps.\n" +\r
1913                                         "Try using the Pad function in the edit menu,\n" +\r
1914                                         "or one of the multiple sequence alignment web services.",\r
1915                                         "Sequences in selection are not aligned",\r
1916                                         JOptionPane.WARNING_MESSAGE);\r
1917 \r
1918           return;\r
1919         }\r
1920       }\r
1921 \r
1922       title = title + " on region";\r
1923       tp = new TreePanel(viewport,\r
1924                          viewport.getSelectionGroup().sequences, type, pwType,\r
1925                          sg.getStartRes(), sg.getEndRes());\r
1926     }\r
1927     else\r
1928     {\r
1929       //are the sequences aligned?\r
1930       if (!viewport.alignment.isAligned())\r
1931       {\r
1932         JOptionPane.showMessageDialog(Desktop.desktop,\r
1933                                       "The sequences must be aligned before creating a tree.\n" +\r
1934                                       "Try using the Pad function in the edit menu,\n" +\r
1935                                       "or one of the multiple sequence alignment web services.",\r
1936                                       "Sequences not aligned",\r
1937                                       JOptionPane.WARNING_MESSAGE);\r
1938 \r
1939         return;\r
1940       }\r
1941 \r
1942       tp = new TreePanel(viewport,\r
1943                          viewport.getAlignment().getSequences(), type, pwType,\r
1944                          0,\r
1945                          viewport.alignment.getWidth());\r
1946     }\r
1947 \r
1948     addTreeMenuItem(tp, title);\r
1949     viewport.setCurrentTree(tp.getTree());\r
1950 \r
1951     Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);\r
1952   }\r
1953 \r
1954   /**\r
1955    * DOCUMENT ME!\r
1956    *\r
1957    * @param title DOCUMENT ME!\r
1958    * @param order DOCUMENT ME!\r
1959    */\r
1960   public void addSortByOrderMenuItem(String title, final AlignmentOrder order)\r
1961   {\r
1962     final JMenuItem item = new JMenuItem("by " + title);\r
1963     sort.add(item);\r
1964     item.addActionListener(new java.awt.event.ActionListener()\r
1965     {\r
1966       public void actionPerformed(ActionEvent e)\r
1967       {\r
1968         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
1969                                        HistoryItem.SORT));\r
1970 \r
1971         // TODO: JBPNote - have to map order entries to curent SequenceI pointers\r
1972         AlignmentSorter.sortBy(viewport.getAlignment(), order);\r
1973         alignPanel.repaint();\r
1974       }\r
1975     });\r
1976   }\r
1977 \r
1978   /**\r
1979    * Maintain the Order by->Displayed Tree menu.\r
1980    * Creates a new menu item for a TreePanel with an appropriate\r
1981    * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added\r
1982    * to remove the menu item when the treePanel is closed, and adjust\r
1983    * the tree leaf to sequence mapping when the alignment is modified.\r
1984    * @param treePanel Displayed tree window.\r
1985    * @param title SortBy menu item title.\r
1986    */\r
1987   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1988   {\r
1989     final JMenuItem item = new JMenuItem(title);\r
1990 \r
1991     treeCount++;\r
1992 \r
1993     if (treeCount == 1)\r
1994     {\r
1995       sort.add(sortByTreeMenu);\r
1996     }\r
1997 \r
1998     sortByTreeMenu.add(item);\r
1999     item.addActionListener(new java.awt.event.ActionListener()\r
2000     {\r
2001       public void actionPerformed(ActionEvent e)\r
2002       {\r
2003         addHistoryItem(new HistoryItem("Tree Sort",\r
2004                                        viewport.alignment, HistoryItem.SORT));\r
2005         AlignmentSorter.sortByTree(viewport.getAlignment(),\r
2006                                    treePanel.getTree());\r
2007         alignPanel.repaint();\r
2008       }\r
2009     });\r
2010 \r
2011     treePanel.addInternalFrameListener(new javax.swing.event.\r
2012                                        InternalFrameAdapter()\r
2013     {\r
2014       public void internalFrameClosed(\r
2015           javax.swing.event.InternalFrameEvent evt)\r
2016       {\r
2017         treeCount--;\r
2018         sortByTreeMenu.remove(item);\r
2019 \r
2020         if (treeCount == 0)\r
2021         {\r
2022           sort.remove(sortByTreeMenu);\r
2023         }\r
2024       }\r
2025       ;\r
2026     });\r
2027   }\r
2028 \r
2029   /**\r
2030    * Work out whether the whole set of sequences\r
2031    * or just the selected set will be submitted for multiple alignment.\r
2032    *\r
2033    */\r
2034   private SequenceI[] gatherSequencesForAlignment()\r
2035   {\r
2036     // Now, check we have enough sequences\r
2037     SequenceI[] msa = null;\r
2038 \r
2039     if ( (viewport.getSelectionGroup() != null) &&\r
2040         (viewport.getSelectionGroup().getSize() > 1))\r
2041     {\r
2042       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2043       SequenceGroup seqs = viewport.getSelectionGroup();\r
2044       int sz;\r
2045       msa = new SequenceI[sz = seqs.getSize()];\r
2046 \r
2047       for (int i = 0; i < sz; i++)\r
2048       {\r
2049         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2050       }\r
2051     }\r
2052     else\r
2053     {\r
2054       Vector seqs = viewport.getAlignment().getSequences();\r
2055 \r
2056       if (seqs.size() > 1)\r
2057       {\r
2058         msa = new SequenceI[seqs.size()];\r
2059 \r
2060         for (int i = 0; i < seqs.size(); i++)\r
2061         {\r
2062           msa[i] = (SequenceI) seqs.elementAt(i);\r
2063         }\r
2064       }\r
2065     }\r
2066     return msa;\r
2067   }\r
2068 \r
2069   /**\r
2070    * Decides what is submitted to a secondary structure prediction service,\r
2071    * the currently selected sequence, or the currently selected alignment\r
2072    * (where the first sequence in the set is the one that the prediction\r
2073    * will be for).\r
2074    */\r
2075   SequenceI[] gatherSeqOrMsaForSecStrPrediction()\r
2076   {\r
2077     SequenceI seq = null;\r
2078     SequenceI[] msa = null;\r
2079 \r
2080     if ( (viewport.getSelectionGroup() != null) &&\r
2081         (viewport.getSelectionGroup().getSize() > 0))\r
2082     {\r
2083       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2084       SequenceGroup seqs = viewport.getSelectionGroup();\r
2085 \r
2086       if ( (seqs.getSize() == 1) || !viewport.alignment.isAligned())\r
2087       {\r
2088         seq = (SequenceI) seqs.getSequenceAt(0);\r
2089       }\r
2090       else\r
2091       {\r
2092         int sz;\r
2093         msa = new SequenceI[sz = seqs.getSize()];\r
2094 \r
2095         for (int i = 0; i < sz; i++)\r
2096         {\r
2097           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2098         }\r
2099       }\r
2100     }\r
2101     else\r
2102     {\r
2103       Vector seqs = viewport.getAlignment().getSequences();\r
2104 \r
2105       if ( (seqs.size() == 1) || !viewport.alignment.isAligned())\r
2106       {\r
2107         seq = (SequenceI) seqs.elementAt(0);\r
2108       }\r
2109       else\r
2110       {\r
2111         msa = new SequenceI[seqs.size()];\r
2112 \r
2113         for (int i = 0; i < seqs.size(); i++)\r
2114         {\r
2115           msa[i] = (SequenceI) seqs.elementAt(i);\r
2116         }\r
2117       }\r
2118     }\r
2119     if (msa != null)\r
2120     {\r
2121       return msa;\r
2122     }\r
2123     else\r
2124     {\r
2125       if (seq != null)\r
2126       {\r
2127         return new SequenceI[]\r
2128             {\r
2129             seq};\r
2130       }\r
2131     }\r
2132     return null;\r
2133   }\r
2134   /**\r
2135    * DOCUMENT ME!\r
2136    *\r
2137    * @param e DOCUMENT ME!\r
2138    */\r
2139   protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
2140   {\r
2141     // Pick the tree file\r
2142     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
2143         getProperty(\r
2144             "LAST_DIRECTORY"));\r
2145     chooser.setFileView(new JalviewFileView());\r
2146     chooser.setDialogTitle("Select a newick-like tree file");\r
2147     chooser.setToolTipText("Load a tree file");\r
2148 \r
2149     int value = chooser.showOpenDialog(null);\r
2150 \r
2151     if (value == JalviewFileChooser.APPROVE_OPTION)\r
2152     {\r
2153       String choice = chooser.getSelectedFile().getPath();\r
2154       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
2155 \r
2156       try\r
2157       {\r
2158         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,\r
2159             "File");\r
2160         viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());\r
2161       }\r
2162       catch (Exception ex)\r
2163       {\r
2164         JOptionPane.showMessageDialog(Desktop.desktop,\r
2165                                       "Problem reading tree file",\r
2166                                       ex.getMessage(),\r
2167                                       JOptionPane.WARNING_MESSAGE);\r
2168         ex.printStackTrace();\r
2169       }\r
2170     }\r
2171   }\r
2172 \r
2173 \r
2174   public TreePanel ShowNewickTree(NewickFile nf, String title)\r
2175   {\r
2176     return ShowNewickTree(nf,title,600,500,4,5);\r
2177   }\r
2178   /**\r
2179    * DOCUMENT ME!\r
2180    *\r
2181    * @param nf DOCUMENT ME!\r
2182    * @param title DOCUMENT ME!\r
2183    *\r
2184    * @return DOCUMENT ME!\r
2185    */\r
2186   public TreePanel ShowNewickTree(NewickFile nf, String title, int w,int h,int x, int y)\r
2187   {\r
2188     TreePanel tp = null;\r
2189 \r
2190     try\r
2191     {\r
2192       nf.parse();\r
2193 \r
2194       if (nf.getTree() != null)\r
2195       {\r
2196         tp = new TreePanel(viewport,\r
2197                            viewport.getAlignment().getSequences(), nf,\r
2198                            "FromFile",\r
2199                            title);\r
2200 \r
2201         tp.setSize(w,h);\r
2202 \r
2203         if(x>0 && y>0)\r
2204           tp.setLocation(x,y);\r
2205 \r
2206 \r
2207         Desktop.addInternalFrame(tp, title, w, h);\r
2208         addTreeMenuItem(tp, title);\r
2209       }\r
2210     }\r
2211     catch (Exception ex)\r
2212     {\r
2213       ex.printStackTrace();\r
2214     }\r
2215 \r
2216     return tp;\r
2217   }\r
2218 \r
2219   class PrintThread\r
2220       extends Thread\r
2221   {\r
2222     public void run()\r
2223     {\r
2224       PrinterJob printJob = PrinterJob.getPrinterJob();\r
2225       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
2226       printJob.setPrintable(alignPanel, pf);\r
2227 \r
2228       if (printJob.printDialog())\r
2229       {\r
2230         try\r
2231         {\r
2232           printJob.print();\r
2233         }\r
2234         catch (Exception PrintException)\r
2235         {\r
2236           PrintException.printStackTrace();\r
2237         }\r
2238       }\r
2239     }\r
2240   }\r
2241 \r
2242   /**\r
2243    * Generates menu items and listener event actions for web service clients\r
2244    *\r
2245    */\r
2246   public void BuildWebServiceMenu()\r
2247   {\r
2248     if ( (Desktop.discoverer.services != null)\r
2249         && (Desktop.discoverer.services.size() > 0))\r
2250     {\r
2251       Vector msaws = (Vector) Desktop.discoverer.services.get("MsaWS");\r
2252       Vector secstrpr = (Vector) Desktop.discoverer.services.get("SecStrPred");\r
2253       Vector wsmenu = new Vector();\r
2254       if (msaws != null)\r
2255       {\r
2256         // Add any Multiple Sequence Alignment Services\r
2257         final JMenu msawsmenu = new JMenu("Alignment");\r
2258         for (int i = 0, j = msaws.size(); i < j; i++)\r
2259         {\r
2260           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.\r
2261               get(i);\r
2262           final JMenuItem method = new JMenuItem(sh.getName());\r
2263           method.addActionListener(new ActionListener()\r
2264           {\r
2265             public void actionPerformed(ActionEvent e)\r
2266             {\r
2267               SequenceI[] msa = gatherSequencesForAlignment();\r
2268               MsaWSClient ct = new jalview.ws.MsaWSClient(sh, title, msa,\r
2269                   false, true);\r
2270 \r
2271             }\r
2272 \r
2273           });\r
2274           msawsmenu.add(method);\r
2275           // Deal with services that we know accept partial alignments.\r
2276           if (sh.getName().indexOf("lustal") > -1)\r
2277           {\r
2278             // We know that ClustalWS can accept partial alignments for refinement.\r
2279             final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");\r
2280             methodR.addActionListener(new ActionListener()\r
2281             {\r
2282               public void actionPerformed(ActionEvent e)\r
2283               {\r
2284                 SequenceI[] msa = gatherSequencesForAlignment();\r
2285                 MsaWSClient ct = new jalview.ws.MsaWSClient(sh, title, msa,\r
2286                     true, true);\r
2287 \r
2288               }\r
2289 \r
2290             });\r
2291             msawsmenu.add(methodR);\r
2292 \r
2293           }\r
2294         }\r
2295         wsmenu.add(msawsmenu);\r
2296       }\r
2297       if (secstrpr != null)\r
2298       {\r
2299         // Add any secondary structure prediction services\r
2300         final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");\r
2301         for (int i = 0, j = secstrpr.size(); i < j; i++)\r
2302         {\r
2303           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)\r
2304               secstrpr.get(i);\r
2305           final JMenuItem method = new JMenuItem(sh.getName());\r
2306           method.addActionListener(new ActionListener()\r
2307           {\r
2308             public void actionPerformed(ActionEvent e)\r
2309             {\r
2310               SequenceI[] msa = gatherSeqOrMsaForSecStrPrediction();\r
2311               if (msa.length == 1)\r
2312               {\r
2313                 // Single Sequence prediction\r
2314                 jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
2315                     title, msa[0]);\r
2316               }\r
2317               else\r
2318               {\r
2319                 if (msa.length > 1)\r
2320                 {\r
2321                   // Single Sequence prediction\r
2322                   jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
2323                       title, msa);\r
2324                 }\r
2325               }\r
2326             }\r
2327           });\r
2328           secstrmenu.add(method);\r
2329         }\r
2330         wsmenu.add(secstrmenu);\r
2331       }\r
2332       this.webService.removeAll();\r
2333       for (int i = 0, j = wsmenu.size(); i < j; i++)\r
2334       {\r
2335         webService.add( (JMenu) wsmenu.get(i));\r
2336       }\r
2337     }\r
2338     else\r
2339     {\r
2340       this.webService.removeAll();\r
2341       this.webService.add(this.webServiceNoServices);\r
2342     }\r
2343     // TODO: add in rediscovery function\r
2344     // TODO: reduce code redundancy.\r
2345     // TODO: group services by location as well as function.\r
2346   }\r
2347 \r
2348 }\r