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