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