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