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