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