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