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