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