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