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