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