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