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