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