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