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