Reading features files readded as ref to FeatureRenderer is required
[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             newseq.setDatasetSequence(sequences[i].getDatasetSequence());\r
764 \r
765         }\r
766         viewport.setEndSeq(viewport.alignment.getHeight());\r
767         viewport.alignment.getWidth();\r
768         viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
769       }\r
770     }\r
771     catch (Exception ex)\r
772     {\r
773       ex.printStackTrace();\r
774         System.out.println("Exception whilst pasting: "+ex);\r
775         // could be anything being pasted in here\r
776     }\r
777 \r
778 \r
779   }\r
780 \r
781   /**\r
782    * DOCUMENT ME!\r
783    *\r
784    * @param e DOCUMENT ME!\r
785    */\r
786   protected void cut_actionPerformed(ActionEvent e)\r
787   {\r
788     copy_actionPerformed(null);\r
789     delete_actionPerformed(null);\r
790   }\r
791 \r
792   /**\r
793    * DOCUMENT ME!\r
794    *\r
795    * @param e DOCUMENT ME!\r
796    */\r
797   protected void delete_actionPerformed(ActionEvent e)\r
798   {\r
799 \r
800     if (viewport.getSelectionGroup() == null)\r
801     {\r
802       return;\r
803     }\r
804 \r
805     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
806                                    HistoryItem.HIDE));\r
807 \r
808     SequenceGroup sg = viewport.getSelectionGroup();\r
809     boolean allSequences = false;\r
810     if (sg.sequences.size() == viewport.alignment.getHeight())\r
811     {\r
812       allSequences = true;\r
813     }\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 index = viewport.getAlignment().findIndex(seq);\r
819       seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
820 \r
821       // If the cut affects all sequences, remove highlighted columns\r
822       if (allSequences)\r
823       {\r
824         viewport.getColumnSelection().removeElements(sg.getStartRes(),\r
825             sg.getEndRes() + 1);\r
826       }\r
827 \r
828       if (seq.getSequence().length() < 1)\r
829       {\r
830         viewport.getAlignment().deleteSequence(seq);\r
831       }\r
832       else\r
833       {\r
834         viewport.getAlignment().getSequences().setElementAt(seq, index);\r
835       }\r
836     }\r
837 \r
838     viewport.setSelectionGroup(null);\r
839     viewport.alignment.deleteGroup(sg);\r
840 \r
841     viewport.firePropertyChange("alignment", null,\r
842                                   viewport.getAlignment().getSequences());\r
843 \r
844 \r
845 \r
846     if (viewport.getAlignment().getHeight() < 1)\r
847     {\r
848       try\r
849       {\r
850         this.setClosed(true);\r
851       }\r
852       catch (Exception ex)\r
853       {\r
854       }\r
855     }\r
856   }\r
857 \r
858   /**\r
859    * DOCUMENT ME!\r
860    *\r
861    * @param e DOCUMENT ME!\r
862    */\r
863   protected void deleteGroups_actionPerformed(ActionEvent e)\r
864   {\r
865     viewport.alignment.deleteAllGroups();\r
866     viewport.setSelectionGroup(null);\r
867     alignPanel.repaint();\r
868   }\r
869 \r
870   /**\r
871    * DOCUMENT ME!\r
872    *\r
873    * @param e DOCUMENT ME!\r
874    */\r
875   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
876   {\r
877     SequenceGroup sg = new SequenceGroup();\r
878 \r
879     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
880          i++)\r
881     {\r
882       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
883     }\r
884 \r
885     sg.setEndRes(viewport.alignment.getWidth() - 1);\r
886     viewport.setSelectionGroup(sg);\r
887     PaintRefresher.Refresh(null, viewport.alignment);\r
888   }\r
889 \r
890   /**\r
891    * DOCUMENT ME!\r
892    *\r
893    * @param e DOCUMENT ME!\r
894    */\r
895   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
896   {\r
897     viewport.setSelectionGroup(null);\r
898     viewport.getColumnSelection().clear();\r
899     viewport.setSelectionGroup(null);\r
900     alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);\r
901     alignPanel.annotationPanel.activeRes = null;\r
902     PaintRefresher.Refresh(null, viewport.alignment);\r
903   }\r
904 \r
905   /**\r
906    * DOCUMENT ME!\r
907    *\r
908    * @param e DOCUMENT ME!\r
909    */\r
910   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
911   {\r
912     SequenceGroup sg = viewport.getSelectionGroup();\r
913 \r
914     if (sg == null)\r
915     {\r
916       selectAllSequenceMenuItem_actionPerformed(null);\r
917 \r
918       return;\r
919     }\r
920 \r
921     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
922          i++)\r
923     {\r
924       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
925     }\r
926 \r
927     PaintRefresher.Refresh(null, viewport.alignment);\r
928   }\r
929 \r
930   /**\r
931    * DOCUMENT ME!\r
932    *\r
933    * @param e DOCUMENT ME!\r
934    */\r
935   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
936   {\r
937     ColumnSelection colSel = viewport.getColumnSelection();\r
938 \r
939     if (colSel.size() > 0)\r
940     {\r
941       addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
942                                      HistoryItem.HIDE));\r
943 \r
944       int min = colSel.getMin();\r
945       viewport.getAlignment().trimLeft(min);\r
946       colSel.compensateForEdit(0, min);\r
947 \r
948       if (viewport.getSelectionGroup() != null)\r
949       {\r
950         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
951       }\r
952 \r
953       Vector groups = viewport.alignment.getGroups();\r
954 \r
955       for (int i = 0; i < groups.size(); i++)\r
956       {\r
957         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
958 \r
959         if (!sg.adjustForRemoveLeft(min))\r
960         {\r
961           viewport.alignment.deleteGroup(sg);\r
962         }\r
963       }\r
964 \r
965       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
966     }\r
967   }\r
968 \r
969   /**\r
970    * DOCUMENT ME!\r
971    *\r
972    * @param e DOCUMENT ME!\r
973    */\r
974   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
975   {\r
976     ColumnSelection colSel = viewport.getColumnSelection();\r
977 \r
978     if (colSel.size() > 0)\r
979     {\r
980       addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
981                                      HistoryItem.HIDE));\r
982 \r
983       int max = colSel.getMax();\r
984       viewport.getAlignment().trimRight(max);\r
985 \r
986       if (viewport.getSelectionGroup() != null)\r
987       {\r
988         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
989       }\r
990 \r
991       Vector groups = viewport.alignment.getGroups();\r
992 \r
993       for (int i = 0; i < groups.size(); i++)\r
994       {\r
995         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
996 \r
997         if (!sg.adjustForRemoveRight(max))\r
998         {\r
999           viewport.alignment.deleteGroup(sg);\r
1000         }\r
1001       }\r
1002 \r
1003       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
1004     }\r
1005   }\r
1006 \r
1007   /**\r
1008    * DOCUMENT ME!\r
1009    *\r
1010    * @param e DOCUMENT ME!\r
1011    */\r
1012   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
1013   {\r
1014     addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
1015                                    viewport.alignment, HistoryItem.HIDE));\r
1016 \r
1017     //This is to maintain viewport position on first residue\r
1018     //of first sequence\r
1019     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
1020     int startRes = seq.findPosition(viewport.startRes);\r
1021 \r
1022     viewport.getAlignment().removeGaps();\r
1023 \r
1024     viewport.setStartRes(seq.findIndex(startRes)-1);\r
1025 \r
1026    viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
1027   }\r
1028 \r
1029   /**\r
1030    * DOCUMENT ME!\r
1031    *\r
1032    * @param e DOCUMENT ME!\r
1033    */\r
1034   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
1035   {\r
1036     addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
1037                                    HistoryItem.HIDE));\r
1038 \r
1039     //This is to maintain viewport position on first residue\r
1040     //of first sequence\r
1041     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
1042     int startRes = seq.findPosition(viewport.startRes);\r
1043 \r
1044 \r
1045     SequenceI current;\r
1046     int jSize;\r
1047 \r
1048     Vector seqs = null;\r
1049 \r
1050     int start = 0;\r
1051     int end = viewport.alignment.getWidth();\r
1052 \r
1053     if (viewport.getSelectionGroup() != null\r
1054         && viewport.getSelectionGroup().sequences != null\r
1055         && viewport.getSelectionGroup().sequences.size() > 0)\r
1056     {\r
1057       seqs = viewport.getSelectionGroup().sequences;\r
1058       start = viewport.getSelectionGroup().getStartRes();\r
1059       end = viewport.getSelectionGroup().getEndRes()+1;\r
1060     }\r
1061     else\r
1062     {\r
1063       seqs = viewport.alignment.getSequences();\r
1064     }\r
1065 \r
1066     for (int i = 0; i < seqs.size(); i++)\r
1067     {\r
1068       current = (SequenceI) seqs.elementAt(i);\r
1069       jSize = current.getLength();\r
1070 \r
1071       // Removing a range is much quicker than removing gaps\r
1072       // one by one for long sequences\r
1073       int j = start;\r
1074       int rangeStart=-1, rangeEnd=-1;\r
1075 \r
1076       do\r
1077       {\r
1078         if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
1079         {\r
1080           if(rangeStart==-1)\r
1081            {\r
1082              rangeStart = j;\r
1083              rangeEnd = j+1;\r
1084            }\r
1085            else\r
1086            {\r
1087              rangeEnd++;\r
1088            }\r
1089            j++;\r
1090         }\r
1091         else\r
1092         {\r
1093           if(rangeStart>-1)\r
1094           {\r
1095             current.deleteChars(rangeStart, rangeEnd);\r
1096             j-=rangeEnd-rangeStart;\r
1097             jSize-=rangeEnd-rangeStart;\r
1098             rangeStart = -1;\r
1099             rangeEnd = -1;\r
1100           }\r
1101           else\r
1102             j++;\r
1103         }\r
1104       }\r
1105       while (j < end && j < jSize);\r
1106       if(rangeStart>-1)\r
1107       {\r
1108        current.deleteChars(rangeStart, rangeEnd);\r
1109       }\r
1110     }\r
1111 \r
1112     viewport.setStartRes(seq.findIndex(startRes)-1);\r
1113 \r
1114     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
1115   }\r
1116 \r
1117  public void alignmentChanged()\r
1118  {\r
1119    if(viewport.vconsensus!=null)\r
1120    {\r
1121      viewport.updateConsensus();\r
1122      viewport.updateConservation();\r
1123    }\r
1124    resetAllColourSchemes();\r
1125    if(alignPanel.overviewPanel!=null)\r
1126      alignPanel.overviewPanel.updateOverviewImage();\r
1127 \r
1128    viewport.alignment.adjustSequenceAnnotations();\r
1129 \r
1130    alignPanel.repaint();\r
1131  }\r
1132 \r
1133   void resetAllColourSchemes()\r
1134   {\r
1135     ColourSchemeI cs = viewport.globalColourScheme;\r
1136     if(cs!=null)\r
1137     {\r
1138       if (cs instanceof ClustalxColourScheme)\r
1139       {\r
1140         ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).\r
1141             resetClustalX(viewport.alignment.getSequences(),\r
1142                           viewport.alignment.getWidth());\r
1143       }\r
1144 \r
1145       cs.setConsensus(viewport.vconsensus);\r
1146       if (cs.conservationApplied())\r
1147       {\r
1148         Alignment al = (Alignment) viewport.alignment;\r
1149         Conservation c = new Conservation("All",\r
1150                                           ResidueProperties.propHash, 3,\r
1151                                           al.getSequences(), 0,\r
1152                                           al.getWidth() - 1);\r
1153         c.calculate();\r
1154         c.verdict(false, viewport.ConsPercGaps);\r
1155 \r
1156         cs.setConservation(c);\r
1157       }\r
1158     }\r
1159 \r
1160     int s, sSize = viewport.alignment.getGroups().size();\r
1161     for(s=0; s<sSize; s++)\r
1162     {\r
1163       SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);\r
1164       if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)\r
1165       {\r
1166         ((ClustalxColourScheme)sg.cs).resetClustalX(sg.sequences, sg.getWidth());\r
1167       }\r
1168       sg.recalcConservation();\r
1169     }\r
1170   }\r
1171 \r
1172   /**\r
1173    * DOCUMENT ME!\r
1174    *\r
1175    * @param e DOCUMENT ME!\r
1176    */\r
1177   public void padGapsMenuitem_actionPerformed(ActionEvent e)\r
1178   {\r
1179     addHistoryItem(new HistoryItem("Pad Gaps", viewport.alignment,\r
1180                                    HistoryItem.HIDE));\r
1181     if (viewport.getAlignment().padGaps())\r
1182       alignmentChanged();\r
1183   }\r
1184 \r
1185   /**\r
1186    * DOCUMENT ME!\r
1187    *\r
1188    * @param e DOCUMENT ME!\r
1189    */\r
1190   public void findMenuItem_actionPerformed(ActionEvent e)\r
1191   {\r
1192     JInternalFrame frame = new JInternalFrame();\r
1193     Finder finder = new Finder(viewport, alignPanel, frame);\r
1194     frame.setContentPane(finder);\r
1195     Desktop.addInternalFrame(frame, "Find", 340, 110);\r
1196     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
1197   }\r
1198 \r
1199   /**\r
1200    * DOCUMENT ME!\r
1201    *\r
1202    * @param e DOCUMENT ME!\r
1203    */\r
1204   public void font_actionPerformed(ActionEvent e)\r
1205   {\r
1206     new FontChooser(alignPanel);\r
1207   }\r
1208 \r
1209   public void smoothFont_actionPerformed(ActionEvent e)\r
1210   {\r
1211     viewport.antiAlias = smoothFont.isSelected();\r
1212     alignPanel.annotationPanel.image = null;\r
1213     alignPanel.repaint();\r
1214   }\r
1215 \r
1216 \r
1217   /**\r
1218    * DOCUMENT ME!\r
1219    *\r
1220    * @param e DOCUMENT ME!\r
1221    */\r
1222   protected void seqLimit_actionPerformed(ActionEvent e)\r
1223   {\r
1224     viewport.setShowJVSuffix(seqLimits.isSelected());\r
1225 \r
1226     alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());\r
1227     alignPanel.repaint();\r
1228   }\r
1229 \r
1230 \r
1231   /**\r
1232    * DOCUMENT ME!\r
1233    *\r
1234    * @param e DOCUMENT ME!\r
1235    */\r
1236   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
1237   {\r
1238     viewport.setColourText(colourTextMenuItem.isSelected());\r
1239     alignPanel.repaint();\r
1240   }\r
1241 \r
1242   /**\r
1243    * DOCUMENT ME!\r
1244    *\r
1245    * @param e DOCUMENT ME!\r
1246    */\r
1247   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
1248   {\r
1249     viewport.setWrapAlignment(wrapMenuItem.isSelected());\r
1250     alignPanel.setWrapAlignment(wrapMenuItem.isSelected());\r
1251     scaleAbove.setVisible(wrapMenuItem.isSelected());\r
1252     scaleLeft.setVisible(wrapMenuItem.isSelected());\r
1253     scaleRight.setVisible(wrapMenuItem.isSelected());\r
1254     alignPanel.repaint();\r
1255   }\r
1256 \r
1257   /**\r
1258    * DOCUMENT ME!\r
1259    *\r
1260    * @param e DOCUMENT ME!\r
1261    */\r
1262   protected void scaleAbove_actionPerformed(ActionEvent e)\r
1263   {\r
1264     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
1265     alignPanel.repaint();\r
1266   }\r
1267 \r
1268   /**\r
1269    * DOCUMENT ME!\r
1270    *\r
1271    * @param e DOCUMENT ME!\r
1272    */\r
1273   protected void scaleLeft_actionPerformed(ActionEvent e)\r
1274   {\r
1275     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
1276     alignPanel.repaint();\r
1277   }\r
1278 \r
1279   /**\r
1280    * DOCUMENT ME!\r
1281    *\r
1282    * @param e DOCUMENT ME!\r
1283    */\r
1284   protected void scaleRight_actionPerformed(ActionEvent e)\r
1285   {\r
1286     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
1287     alignPanel.repaint();\r
1288   }\r
1289 \r
1290   /**\r
1291    * DOCUMENT ME!\r
1292    *\r
1293    * @param e DOCUMENT ME!\r
1294    */\r
1295   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
1296   {\r
1297     viewport.setShowBoxes(viewBoxesMenuItem.isSelected());\r
1298     alignPanel.repaint();\r
1299   }\r
1300 \r
1301   /**\r
1302    * DOCUMENT ME!\r
1303    *\r
1304    * @param e DOCUMENT ME!\r
1305    */\r
1306   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
1307   {\r
1308     viewport.setShowText(viewTextMenuItem.isSelected());\r
1309     alignPanel.repaint();\r
1310   }\r
1311 \r
1312   /**\r
1313    * DOCUMENT ME!\r
1314    *\r
1315    * @param e DOCUMENT ME!\r
1316    */\r
1317   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
1318   {\r
1319     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
1320     alignPanel.repaint();\r
1321   }\r
1322 \r
1323   /**\r
1324    * DOCUMENT ME!\r
1325    *\r
1326    * @param evt DOCUMENT ME!\r
1327    */\r
1328   public void sequenceFeatures_actionPerformed(ActionEvent evt)\r
1329   {\r
1330     viewport.showSequenceFeatures(sequenceFeatures.isSelected());\r
1331 \r
1332     if (viewport.showSequenceFeatures)\r
1333     {\r
1334       new SequenceFeatureFetcher(viewport.\r
1335          alignment,\r
1336           alignPanel);\r
1337     }\r
1338 \r
1339     featureSettings.setEnabled(true);\r
1340 \r
1341     alignPanel.repaint();\r
1342   }\r
1343 \r
1344   /**\r
1345    * DOCUMENT ME!\r
1346    *\r
1347    * @param e DOCUMENT ME!\r
1348    */\r
1349   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
1350   {\r
1351     viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());\r
1352     alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());\r
1353   }\r
1354 \r
1355   /**\r
1356    * DOCUMENT ME!\r
1357    *\r
1358    * @param e DOCUMENT ME!\r
1359    */\r
1360   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
1361   {\r
1362     if (alignPanel.overviewPanel != null)\r
1363     {\r
1364       return;\r
1365     }\r
1366 \r
1367     JInternalFrame frame = new JInternalFrame();\r
1368     OverviewPanel overview = new OverviewPanel(alignPanel);\r
1369     frame.setContentPane(overview);\r
1370     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
1371                              frame.getWidth(), frame.getHeight());\r
1372     frame.pack();\r
1373     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
1374     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
1375     {\r
1376       public void internalFrameClosed(\r
1377           javax.swing.event.InternalFrameEvent evt)\r
1378       {\r
1379         alignPanel.setOverviewPanel(null);\r
1380       }\r
1381       ;\r
1382     });\r
1383 \r
1384     alignPanel.setOverviewPanel(overview);\r
1385   }\r
1386 \r
1387   /**\r
1388    * DOCUMENT ME!\r
1389    *\r
1390    * @param e DOCUMENT ME!\r
1391    */\r
1392   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
1393   {\r
1394     changeColour(null);\r
1395   }\r
1396 \r
1397   /**\r
1398    * DOCUMENT ME!\r
1399    *\r
1400    * @param e DOCUMENT ME!\r
1401    */\r
1402   public void clustalColour_actionPerformed(ActionEvent e)\r
1403   {\r
1404     changeColour(new ClustalxColourScheme(\r
1405         viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
1406   }\r
1407 \r
1408   /**\r
1409    * DOCUMENT ME!\r
1410    *\r
1411    * @param e DOCUMENT ME!\r
1412    */\r
1413   public void zappoColour_actionPerformed(ActionEvent e)\r
1414   {\r
1415     changeColour(new ZappoColourScheme());\r
1416   }\r
1417 \r
1418   /**\r
1419    * DOCUMENT ME!\r
1420    *\r
1421    * @param e DOCUMENT ME!\r
1422    */\r
1423   public void taylorColour_actionPerformed(ActionEvent e)\r
1424   {\r
1425     changeColour(new TaylorColourScheme());\r
1426   }\r
1427 \r
1428   /**\r
1429    * DOCUMENT ME!\r
1430    *\r
1431    * @param e DOCUMENT ME!\r
1432    */\r
1433   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
1434   {\r
1435     changeColour(new HydrophobicColourScheme());\r
1436   }\r
1437 \r
1438   /**\r
1439    * DOCUMENT ME!\r
1440    *\r
1441    * @param e DOCUMENT ME!\r
1442    */\r
1443   public void helixColour_actionPerformed(ActionEvent e)\r
1444   {\r
1445     changeColour(new HelixColourScheme());\r
1446   }\r
1447 \r
1448   /**\r
1449    * DOCUMENT ME!\r
1450    *\r
1451    * @param e DOCUMENT ME!\r
1452    */\r
1453   public void strandColour_actionPerformed(ActionEvent e)\r
1454   {\r
1455     changeColour(new StrandColourScheme());\r
1456   }\r
1457 \r
1458   /**\r
1459    * DOCUMENT ME!\r
1460    *\r
1461    * @param e DOCUMENT ME!\r
1462    */\r
1463   public void turnColour_actionPerformed(ActionEvent e)\r
1464   {\r
1465     changeColour(new TurnColourScheme());\r
1466   }\r
1467 \r
1468   /**\r
1469    * DOCUMENT ME!\r
1470    *\r
1471    * @param e DOCUMENT ME!\r
1472    */\r
1473   public void buriedColour_actionPerformed(ActionEvent e)\r
1474   {\r
1475     changeColour(new BuriedColourScheme());\r
1476   }\r
1477 \r
1478   /**\r
1479    * DOCUMENT ME!\r
1480    *\r
1481    * @param e DOCUMENT ME!\r
1482    */\r
1483   public void nucleotideColour_actionPerformed(ActionEvent e)\r
1484   {\r
1485     changeColour(new NucleotideColourScheme());\r
1486   }\r
1487 \r
1488   public void annotationColour_actionPerformed(ActionEvent e)\r
1489   {\r
1490     new AnnotationColourChooser(viewport, alignPanel);\r
1491   }\r
1492 \r
1493 \r
1494   /**\r
1495    * DOCUMENT ME!\r
1496    *\r
1497    * @param e DOCUMENT ME!\r
1498    */\r
1499   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
1500   {\r
1501     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
1502   }\r
1503 \r
1504   /**\r
1505    * DOCUMENT ME!\r
1506    *\r
1507    * @param cs DOCUMENT ME!\r
1508    */\r
1509   void changeColour(ColourSchemeI cs)\r
1510   {\r
1511     int threshold = 0;\r
1512 \r
1513     if(cs!=null)\r
1514     {\r
1515       if (viewport.getAbovePIDThreshold())\r
1516       {\r
1517         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,\r
1518                                                    "Background");\r
1519 \r
1520         cs.setThreshold(threshold,\r
1521                         viewport.getIgnoreGapsConsensus());\r
1522 \r
1523         viewport.setGlobalColourScheme(cs);\r
1524       }\r
1525       else\r
1526       {\r
1527         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1528       }\r
1529 \r
1530       if (viewport.getConservationSelected())\r
1531       {\r
1532 \r
1533         Alignment al = (Alignment) viewport.alignment;\r
1534         Conservation c = new Conservation("All",\r
1535                                           ResidueProperties.propHash, 3,\r
1536                                           al.getSequences(), 0,\r
1537                                           al.getWidth() - 1);\r
1538 \r
1539         c.calculate();\r
1540         c.verdict(false, viewport.ConsPercGaps);\r
1541 \r
1542         cs.setConservation(c);\r
1543 \r
1544         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
1545             "Background"));\r
1546       }\r
1547       else\r
1548       {\r
1549         cs.setConservation(null);\r
1550       }\r
1551 \r
1552       cs.setConsensus(viewport.vconsensus);\r
1553     }\r
1554 \r
1555     viewport.setGlobalColourScheme(cs);\r
1556 \r
1557     if (viewport.getColourAppliesToAllGroups())\r
1558     {\r
1559       Vector groups = viewport.alignment.getGroups();\r
1560 \r
1561       for (int i = 0; i < groups.size(); i++)\r
1562       {\r
1563         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
1564 \r
1565         if (cs == null)\r
1566         {\r
1567           sg.cs = null;\r
1568           continue;\r
1569         }\r
1570 \r
1571         if (cs instanceof ClustalxColourScheme)\r
1572         {\r
1573           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
1574         }\r
1575         else if (cs instanceof UserColourScheme)\r
1576         {\r
1577           sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());\r
1578         }\r
1579         else\r
1580         {\r
1581           try\r
1582           {\r
1583             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
1584           }\r
1585           catch (Exception ex)\r
1586           {\r
1587           }\r
1588         }\r
1589 \r
1590         if (viewport.getAbovePIDThreshold()\r
1591             || cs instanceof PIDColourScheme\r
1592             || cs instanceof Blosum62ColourScheme)\r
1593         {\r
1594          sg.cs.setThreshold(threshold,\r
1595                 viewport.getIgnoreGapsConsensus());\r
1596 \r
1597           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1598               sg.getWidth()));\r
1599         }\r
1600         else\r
1601           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1602 \r
1603 \r
1604         if (viewport.getConservationSelected())\r
1605         {\r
1606           Conservation c = new Conservation("Group",\r
1607                                             ResidueProperties.propHash, 3,\r
1608                                             sg.sequences, 0,\r
1609                                             viewport.alignment.getWidth() - 1);\r
1610           c.calculate();\r
1611           c.verdict(false, viewport.ConsPercGaps);\r
1612           sg.cs.setConservation(c);\r
1613         }\r
1614         else\r
1615           sg.cs.setConservation(null);\r
1616       }\r
1617     }\r
1618 \r
1619     if (alignPanel.getOverviewPanel() != null)\r
1620     {\r
1621       alignPanel.getOverviewPanel().updateOverviewImage();\r
1622     }\r
1623 \r
1624     alignPanel.repaint();\r
1625   }\r
1626 \r
1627   /**\r
1628    * DOCUMENT ME!\r
1629    *\r
1630    * @param e DOCUMENT ME!\r
1631    */\r
1632   protected void modifyPID_actionPerformed(ActionEvent e)\r
1633   {\r
1634     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
1635     {\r
1636       SliderPanel.setPIDSliderSource(alignPanel,\r
1637                                      viewport.getGlobalColourScheme(),\r
1638                                      "Background");\r
1639       SliderPanel.showPIDSlider();\r
1640     }\r
1641   }\r
1642 \r
1643   /**\r
1644    * DOCUMENT ME!\r
1645    *\r
1646    * @param e DOCUMENT ME!\r
1647    */\r
1648   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1649   {\r
1650     if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
1651     {\r
1652       SliderPanel.setConservationSlider(alignPanel,\r
1653                                         viewport.globalColourScheme,\r
1654                                         "Background");\r
1655       SliderPanel.showConservationSlider();\r
1656     }\r
1657   }\r
1658 \r
1659   /**\r
1660    * DOCUMENT ME!\r
1661    *\r
1662    * @param e DOCUMENT ME!\r
1663    */\r
1664   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1665   {\r
1666     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
1667 \r
1668     viewport.setAbovePIDThreshold(false);\r
1669     abovePIDThreshold.setSelected(false);\r
1670 \r
1671     changeColour(viewport.getGlobalColourScheme());\r
1672 \r
1673     modifyConservation_actionPerformed(null);\r
1674   }\r
1675 \r
1676   /**\r
1677    * DOCUMENT ME!\r
1678    *\r
1679    * @param e DOCUMENT ME!\r
1680    */\r
1681   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1682   {\r
1683     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
1684 \r
1685     conservationMenuItem.setSelected(false);\r
1686     viewport.setConservationSelected(false);\r
1687 \r
1688     changeColour(viewport.getGlobalColourScheme());\r
1689 \r
1690     modifyPID_actionPerformed(null);\r
1691   }\r
1692 \r
1693   /**\r
1694    * DOCUMENT ME!\r
1695    *\r
1696    * @param e DOCUMENT ME!\r
1697    */\r
1698   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1699   {\r
1700     if (e.getActionCommand().equals("User Defined..."))\r
1701     {\r
1702       new UserDefinedColours(alignPanel, null);\r
1703     }\r
1704     else\r
1705     {\r
1706       UserColourScheme udc = (UserColourScheme) UserDefinedColours.\r
1707           getUserColourSchemes().get(e.getActionCommand());\r
1708 \r
1709       changeColour(udc);\r
1710     }\r
1711   }\r
1712 \r
1713   public void updateUserColourMenu()\r
1714   {\r
1715 \r
1716     Component[] menuItems = colourMenu.getMenuComponents();\r
1717     int i, iSize = menuItems.length;\r
1718     for (i = 0; i < iSize; i++)\r
1719     {\r
1720       if (menuItems[i].getName() != null &&\r
1721           menuItems[i].getName().equals("USER_DEFINED"))\r
1722       {\r
1723         colourMenu.remove(menuItems[i]);\r
1724         iSize--;\r
1725       }\r
1726     }\r
1727     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)\r
1728     {\r
1729       java.util.Enumeration userColours = jalview.gui.UserDefinedColours.\r
1730           getUserColourSchemes().keys();\r
1731 \r
1732       while (userColours.hasMoreElements())\r
1733       {\r
1734         final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(userColours.\r
1735             nextElement().toString());\r
1736         radioItem.setName("USER_DEFINED");\r
1737         radioItem.addMouseListener(new MouseAdapter()\r
1738             {\r
1739               public void mousePressed(MouseEvent evt)\r
1740               {\r
1741                 if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))\r
1742                 {\r
1743                   radioItem.removeActionListener(radioItem.getActionListeners()[0]);\r
1744 \r
1745                   int option = JOptionPane.showInternalConfirmDialog(jalview.gui.Desktop.desktop,\r
1746                       "Remove from default list?",\r
1747                       "Remove user defined colour",\r
1748                       JOptionPane.YES_NO_OPTION);\r
1749                   if(option == JOptionPane.YES_OPTION)\r
1750                   {\r
1751                     jalview.gui.UserDefinedColours.removeColourFromDefaults(radioItem.getText());\r
1752                     colourMenu.remove(radioItem);\r
1753                   }\r
1754                   else\r
1755                     radioItem.addActionListener(new ActionListener()\r
1756                     {\r
1757                       public void actionPerformed(ActionEvent evt)\r
1758                       {\r
1759                         userDefinedColour_actionPerformed(evt);\r
1760                       }\r
1761                     });\r
1762                 }\r
1763               }\r
1764             });\r
1765         radioItem.addActionListener(new ActionListener()\r
1766         {\r
1767           public void actionPerformed(ActionEvent evt)\r
1768           {\r
1769             userDefinedColour_actionPerformed(evt);\r
1770           }\r
1771         });\r
1772 \r
1773         colourMenu.insert(radioItem, 15);\r
1774         colours.add(radioItem);\r
1775       }\r
1776     }\r
1777   }\r
1778 \r
1779   /**\r
1780    * DOCUMENT ME!\r
1781    *\r
1782    * @param e DOCUMENT ME!\r
1783    */\r
1784   public void PIDColour_actionPerformed(ActionEvent e)\r
1785   {\r
1786     changeColour(new PIDColourScheme());\r
1787   }\r
1788 \r
1789   /**\r
1790    * DOCUMENT ME!\r
1791    *\r
1792    * @param e DOCUMENT ME!\r
1793    */\r
1794   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1795   {\r
1796     changeColour(new Blosum62ColourScheme());\r
1797   }\r
1798 \r
1799   /**\r
1800    * DOCUMENT ME!\r
1801    *\r
1802    * @param e DOCUMENT ME!\r
1803    */\r
1804   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1805   {\r
1806     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1807                                    HistoryItem.SORT));\r
1808     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1809                               viewport.getAlignment().getSequenceAt(0));\r
1810     alignPanel.repaint();\r
1811   }\r
1812 \r
1813   /**\r
1814    * DOCUMENT ME!\r
1815    *\r
1816    * @param e DOCUMENT ME!\r
1817    */\r
1818   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1819   {\r
1820     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1821                                    HistoryItem.SORT));\r
1822     AlignmentSorter.sortByID(viewport.getAlignment());\r
1823     alignPanel.repaint();\r
1824   }\r
1825 \r
1826   /**\r
1827    * DOCUMENT ME!\r
1828    *\r
1829    * @param e DOCUMENT ME!\r
1830    */\r
1831   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1832   {\r
1833     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1834                                    HistoryItem.SORT));\r
1835 \r
1836     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1837     alignPanel.repaint();\r
1838   }\r
1839 \r
1840   /**\r
1841    * DOCUMENT ME!\r
1842    *\r
1843    * @param e DOCUMENT ME!\r
1844    */\r
1845   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1846   {\r
1847     RedundancyPanel sp = new RedundancyPanel(alignPanel, this);\r
1848     JInternalFrame frame = new JInternalFrame();\r
1849     frame.setContentPane(sp);\r
1850     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
1851                              100, false);\r
1852   }\r
1853 \r
1854   /**\r
1855    * DOCUMENT ME!\r
1856    *\r
1857    * @param e DOCUMENT ME!\r
1858    */\r
1859   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1860   {\r
1861     if ( (viewport.getSelectionGroup() == null) ||\r
1862         (viewport.getSelectionGroup().getSize() < 2))\r
1863     {\r
1864       JOptionPane.showInternalMessageDialog(this,\r
1865                                             "You must select at least 2 sequences.",\r
1866                                             "Invalid Selection",\r
1867                                             JOptionPane.WARNING_MESSAGE);\r
1868     }\r
1869     else\r
1870     {\r
1871       JInternalFrame frame = new JInternalFrame();\r
1872       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
1873       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
1874     }\r
1875   }\r
1876 \r
1877   /**\r
1878    * DOCUMENT ME!\r
1879    *\r
1880    * @param e DOCUMENT ME!\r
1881    */\r
1882   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1883   {\r
1884     if ( ( (viewport.getSelectionGroup() != null) &&\r
1885           (viewport.getSelectionGroup().getSize() < 4) &&\r
1886           (viewport.getSelectionGroup().getSize() > 0)) ||\r
1887         (viewport.getAlignment().getHeight() < 4))\r
1888     {\r
1889       JOptionPane.showInternalMessageDialog(this,\r
1890                                             "Principal component analysis must take\n" +\r
1891                                             "at least 4 input sequences.",\r
1892                                             "Sequence selection insufficient",\r
1893                                             JOptionPane.WARNING_MESSAGE);\r
1894 \r
1895       return;\r
1896     }\r
1897 \r
1898      new PCAPanel(viewport);\r
1899   }\r
1900 \r
1901   /**\r
1902    * DOCUMENT ME!\r
1903    *\r
1904    * @param e DOCUMENT ME!\r
1905    */\r
1906   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1907   {\r
1908     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1909   }\r
1910 \r
1911   /**\r
1912    * DOCUMENT ME!\r
1913    *\r
1914    * @param e DOCUMENT ME!\r
1915    */\r
1916   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1917   {\r
1918     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1919   }\r
1920 \r
1921   /**\r
1922    * DOCUMENT ME!\r
1923    *\r
1924    * @param e DOCUMENT ME!\r
1925    */\r
1926   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1927   {\r
1928     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1929   }\r
1930 \r
1931   /**\r
1932    * DOCUMENT ME!\r
1933    *\r
1934    * @param e DOCUMENT ME!\r
1935    */\r
1936   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1937   {\r
1938     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");\r
1939   }\r
1940 \r
1941   /**\r
1942    * DOCUMENT ME!\r
1943    *\r
1944    * @param type DOCUMENT ME!\r
1945    * @param pwType DOCUMENT ME!\r
1946    * @param title DOCUMENT ME!\r
1947    */\r
1948   void NewTreePanel(String type, String pwType, String title)\r
1949   {\r
1950     final TreePanel tp;\r
1951 \r
1952     if ( (viewport.getSelectionGroup() != null) &&\r
1953         (viewport.getSelectionGroup().getSize() > 3))\r
1954     {\r
1955       int s = 0;\r
1956       SequenceGroup sg = viewport.getSelectionGroup();\r
1957 \r
1958       /* Decide if the selection is a column region */\r
1959       while (s < sg.sequences.size())\r
1960       {\r
1961         if ( ( (SequenceI) sg.sequences.elementAt(s++)).getLength() <\r
1962             sg.getEndRes())\r
1963         {\r
1964           JOptionPane.showMessageDialog(Desktop.desktop,\r
1965                                         "The selected region to create a tree may\nonly contain residues or gaps.\n" +\r
1966                                         "Try using the Pad function in the edit menu,\n" +\r
1967                                         "or one of the multiple sequence alignment web services.",\r
1968                                         "Sequences in selection are not aligned",\r
1969                                         JOptionPane.WARNING_MESSAGE);\r
1970 \r
1971           return;\r
1972         }\r
1973       }\r
1974 \r
1975       title = title + " on region";\r
1976       tp = new TreePanel(viewport,\r
1977                          viewport.getSelectionGroup().sequences, type, pwType,\r
1978                          sg.getStartRes(), sg.getEndRes());\r
1979     }\r
1980     else\r
1981     {\r
1982       //are the sequences aligned?\r
1983       if (!viewport.alignment.isAligned())\r
1984       {\r
1985         JOptionPane.showMessageDialog(Desktop.desktop,\r
1986                                       "The sequences must be aligned before creating a tree.\n" +\r
1987                                       "Try using the Pad function in the edit menu,\n" +\r
1988                                       "or one of the multiple sequence alignment web services.",\r
1989                                       "Sequences not aligned",\r
1990                                       JOptionPane.WARNING_MESSAGE);\r
1991 \r
1992         return;\r
1993       }\r
1994 \r
1995       tp = new TreePanel(viewport,\r
1996                          viewport.getAlignment().getSequences(), type, pwType,\r
1997                          0,\r
1998                          viewport.alignment.getWidth());\r
1999     }\r
2000 \r
2001     addTreeMenuItem(tp, title);\r
2002     viewport.setCurrentTree(tp.getTree());\r
2003 \r
2004     Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);\r
2005   }\r
2006 \r
2007   /**\r
2008    * DOCUMENT ME!\r
2009    *\r
2010    * @param title DOCUMENT ME!\r
2011    * @param order DOCUMENT ME!\r
2012    */\r
2013   public void addSortByOrderMenuItem(String title, final AlignmentOrder order)\r
2014   {\r
2015     final JMenuItem item = new JMenuItem("by " + title);\r
2016     sort.add(item);\r
2017     item.addActionListener(new java.awt.event.ActionListener()\r
2018     {\r
2019       public void actionPerformed(ActionEvent e)\r
2020       {\r
2021         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
2022                                        HistoryItem.SORT));\r
2023 \r
2024         // TODO: JBPNote - have to map order entries to curent SequenceI pointers\r
2025         AlignmentSorter.sortBy(viewport.getAlignment(), order);\r
2026         alignPanel.repaint();\r
2027       }\r
2028     });\r
2029   }\r
2030 \r
2031   /**\r
2032    * Maintain the Order by->Displayed Tree menu.\r
2033    * Creates a new menu item for a TreePanel with an appropriate\r
2034    * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added\r
2035    * to remove the menu item when the treePanel is closed, and adjust\r
2036    * the tree leaf to sequence mapping when the alignment is modified.\r
2037    * @param treePanel Displayed tree window.\r
2038    * @param title SortBy menu item title.\r
2039    */\r
2040   void addTreeMenuItem(final TreePanel treePanel, String title)\r
2041   {\r
2042     final JMenuItem item = new JMenuItem(title);\r
2043 \r
2044     treeCount++;\r
2045 \r
2046     if (treeCount == 1)\r
2047     {\r
2048       sort.add(sortByTreeMenu);\r
2049     }\r
2050 \r
2051     sortByTreeMenu.add(item);\r
2052     item.addActionListener(new java.awt.event.ActionListener()\r
2053     {\r
2054       public void actionPerformed(ActionEvent e)\r
2055       {\r
2056         addHistoryItem(new HistoryItem("Tree Sort",\r
2057                                        viewport.alignment, HistoryItem.SORT));\r
2058         AlignmentSorter.sortByTree(viewport.getAlignment(),\r
2059                                    treePanel.getTree());\r
2060         alignPanel.repaint();\r
2061       }\r
2062     });\r
2063 \r
2064     treePanel.addInternalFrameListener(new javax.swing.event.\r
2065                                        InternalFrameAdapter()\r
2066     {\r
2067       public void internalFrameClosed(\r
2068           javax.swing.event.InternalFrameEvent evt)\r
2069       {\r
2070         treeCount--;\r
2071         sortByTreeMenu.remove(item);\r
2072 \r
2073         if (treeCount == 0)\r
2074         {\r
2075           sort.remove(sortByTreeMenu);\r
2076         }\r
2077       }\r
2078       ;\r
2079     });\r
2080   }\r
2081 \r
2082   /**\r
2083    * Work out whether the whole set of sequences\r
2084    * or just the selected set will be submitted for multiple alignment.\r
2085    *\r
2086    */\r
2087   private SequenceI[] gatherSequencesForAlignment()\r
2088   {\r
2089     // Now, check we have enough sequences\r
2090     SequenceI[] msa = null;\r
2091 \r
2092     if ( (viewport.getSelectionGroup() != null) &&\r
2093         (viewport.getSelectionGroup().getSize() > 1))\r
2094     {\r
2095       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2096       SequenceGroup seqs = viewport.getSelectionGroup();\r
2097       int sz;\r
2098       msa = new SequenceI[sz = seqs.getSize()];\r
2099 \r
2100       for (int i = 0; i < sz; i++)\r
2101       {\r
2102         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2103       }\r
2104     }\r
2105     else\r
2106     {\r
2107       Vector seqs = viewport.getAlignment().getSequences();\r
2108 \r
2109       if (seqs.size() > 1)\r
2110       {\r
2111         msa = new SequenceI[seqs.size()];\r
2112 \r
2113         for (int i = 0; i < seqs.size(); i++)\r
2114         {\r
2115           msa[i] = (SequenceI) seqs.elementAt(i);\r
2116         }\r
2117       }\r
2118     }\r
2119     return msa;\r
2120   }\r
2121 \r
2122   /**\r
2123    * Decides what is submitted to a secondary structure prediction service,\r
2124    * the currently selected sequence, or the currently selected alignment\r
2125    * (where the first sequence in the set is the one that the prediction\r
2126    * will be for).\r
2127    */\r
2128   SequenceI[] gatherSeqOrMsaForSecStrPrediction()\r
2129   {\r
2130     SequenceI seq = null;\r
2131     SequenceI[] msa = null;\r
2132 \r
2133     if ( (viewport.getSelectionGroup() != null) &&\r
2134         (viewport.getSelectionGroup().getSize() > 0))\r
2135     {\r
2136       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
2137       SequenceGroup seqs = viewport.getSelectionGroup();\r
2138 \r
2139       if ( (seqs.getSize() == 1) || !viewport.alignment.isAligned())\r
2140       {\r
2141         seq = (SequenceI) seqs.getSequenceAt(0);\r
2142       }\r
2143       else\r
2144       {\r
2145         int sz;\r
2146         msa = new SequenceI[sz = seqs.getSize()];\r
2147 \r
2148         for (int i = 0; i < sz; i++)\r
2149         {\r
2150           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
2151         }\r
2152       }\r
2153     }\r
2154     else\r
2155     {\r
2156       Vector seqs = viewport.getAlignment().getSequences();\r
2157 \r
2158       if ( (seqs.size() == 1) || !viewport.alignment.isAligned())\r
2159       {\r
2160         seq = (SequenceI) seqs.elementAt(0);\r
2161       }\r
2162       else\r
2163       {\r
2164         msa = new SequenceI[seqs.size()];\r
2165 \r
2166         for (int i = 0; i < seqs.size(); i++)\r
2167         {\r
2168           msa[i] = (SequenceI) seqs.elementAt(i);\r
2169         }\r
2170       }\r
2171     }\r
2172     if (msa != null)\r
2173     {\r
2174       return msa;\r
2175     }\r
2176     else\r
2177     {\r
2178       if (seq != null)\r
2179       {\r
2180         return new SequenceI[]\r
2181             {\r
2182             seq};\r
2183       }\r
2184     }\r
2185     return null;\r
2186   }\r
2187   /**\r
2188    * DOCUMENT ME!\r
2189    *\r
2190    * @param e DOCUMENT ME!\r
2191    */\r
2192   protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
2193   {\r
2194     // Pick the tree file\r
2195     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
2196         getProperty(\r
2197             "LAST_DIRECTORY"));\r
2198     chooser.setFileView(new JalviewFileView());\r
2199     chooser.setDialogTitle("Select a newick-like tree file");\r
2200     chooser.setToolTipText("Load a tree file");\r
2201 \r
2202     int value = chooser.showOpenDialog(null);\r
2203 \r
2204     if (value == JalviewFileChooser.APPROVE_OPTION)\r
2205     {\r
2206       String choice = chooser.getSelectedFile().getPath();\r
2207       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
2208 \r
2209       try\r
2210       {\r
2211         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,\r
2212             "File");\r
2213         viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());\r
2214       }\r
2215       catch (Exception ex)\r
2216       {\r
2217         JOptionPane.showMessageDialog(Desktop.desktop,\r
2218                                       "Problem reading tree file",\r
2219                                       ex.getMessage(),\r
2220                                       JOptionPane.WARNING_MESSAGE);\r
2221         ex.printStackTrace();\r
2222       }\r
2223     }\r
2224   }\r
2225 \r
2226 \r
2227   public TreePanel ShowNewickTree(NewickFile nf, String title)\r
2228   {\r
2229     return ShowNewickTree(nf,title,600,500,4,5);\r
2230   }\r
2231   /**\r
2232    * DOCUMENT ME!\r
2233    *\r
2234    * @param nf DOCUMENT ME!\r
2235    * @param title DOCUMENT ME!\r
2236    *\r
2237    * @return DOCUMENT ME!\r
2238    */\r
2239   public TreePanel ShowNewickTree(NewickFile nf, String title, int w,int h,int x, int y)\r
2240   {\r
2241     TreePanel tp = null;\r
2242 \r
2243     try\r
2244     {\r
2245       nf.parse();\r
2246 \r
2247       if (nf.getTree() != null)\r
2248       {\r
2249         tp = new TreePanel(viewport,\r
2250                            viewport.getAlignment().getSequences(), nf,\r
2251                            "FromFile",\r
2252                            title);\r
2253 \r
2254         tp.setSize(w,h);\r
2255 \r
2256         if(x>0 && y>0)\r
2257           tp.setLocation(x,y);\r
2258 \r
2259 \r
2260         Desktop.addInternalFrame(tp, title, w, h);\r
2261         addTreeMenuItem(tp, title);\r
2262       }\r
2263     }\r
2264     catch (Exception ex)\r
2265     {\r
2266       ex.printStackTrace();\r
2267     }\r
2268 \r
2269     return tp;\r
2270   }\r
2271 \r
2272   class PrintThread\r
2273       extends Thread\r
2274   {\r
2275     public void run()\r
2276     {\r
2277       PrinterJob printJob = PrinterJob.getPrinterJob();\r
2278       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
2279       printJob.setPrintable(alignPanel, pf);\r
2280 \r
2281       if (printJob.printDialog())\r
2282       {\r
2283         try\r
2284         {\r
2285           printJob.print();\r
2286         }\r
2287         catch (Exception PrintException)\r
2288         {\r
2289           PrintException.printStackTrace();\r
2290         }\r
2291       }\r
2292     }\r
2293   }\r
2294 \r
2295   /**\r
2296    * Generates menu items and listener event actions for web service clients\r
2297    *\r
2298    */\r
2299   public void BuildWebServiceMenu()\r
2300   {\r
2301     if ( (Discoverer.services != null)\r
2302         && (Discoverer.services.size() > 0))\r
2303     {\r
2304       Vector msaws = (Vector) Discoverer.services.get("MsaWS");\r
2305       Vector secstrpr = (Vector) Discoverer.services.get("SecStrPred");\r
2306       Vector wsmenu = new Vector();\r
2307       if (msaws != null)\r
2308       {\r
2309         // Add any Multiple Sequence Alignment Services\r
2310         final JMenu msawsmenu = new JMenu("Alignment");\r
2311         for (int i = 0, j = msaws.size(); i < j; i++)\r
2312         {\r
2313           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.\r
2314               get(i);\r
2315           final JMenuItem method = new JMenuItem(sh.getName());\r
2316           method.addActionListener(new ActionListener()\r
2317           {\r
2318             public void actionPerformed(ActionEvent e)\r
2319             {\r
2320               SequenceI[] msa = gatherSequencesForAlignment();\r
2321               new jalview.ws.MsaWSClient(sh, title, msa,\r
2322                   false, true, viewport.getAlignment().getDataset());\r
2323 \r
2324             }\r
2325 \r
2326           });\r
2327           msawsmenu.add(method);\r
2328           // Deal with services that we know accept partial alignments.\r
2329           if (sh.getName().indexOf("lustal") > -1)\r
2330           {\r
2331             // We know that ClustalWS can accept partial alignments for refinement.\r
2332             final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");\r
2333             methodR.addActionListener(new ActionListener()\r
2334             {\r
2335               public void actionPerformed(ActionEvent e)\r
2336               {\r
2337                 SequenceI[] msa = gatherSequencesForAlignment();\r
2338                 new jalview.ws.MsaWSClient(sh, title, msa,\r
2339                     true, true, viewport.getAlignment().getDataset());\r
2340 \r
2341               }\r
2342 \r
2343             });\r
2344             msawsmenu.add(methodR);\r
2345 \r
2346           }\r
2347         }\r
2348         wsmenu.add(msawsmenu);\r
2349       }\r
2350       if (secstrpr != null)\r
2351       {\r
2352         // Add any secondary structure prediction services\r
2353         final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");\r
2354         for (int i = 0, j = secstrpr.size(); i < j; i++)\r
2355         {\r
2356           final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)\r
2357               secstrpr.get(i);\r
2358           final JMenuItem method = new JMenuItem(sh.getName());\r
2359           method.addActionListener(new ActionListener()\r
2360           {\r
2361             public void actionPerformed(ActionEvent e)\r
2362             {\r
2363               SequenceI[] msa = gatherSeqOrMsaForSecStrPrediction();\r
2364               if (msa.length == 1)\r
2365               {\r
2366                 // Single Sequence prediction\r
2367                 new jalview.ws.JPredClient(sh,title, msa[0]);\r
2368               }\r
2369               else\r
2370               {\r
2371                 if (msa.length > 1)\r
2372                 {\r
2373                   // Single Sequence prediction\r
2374                   jalview.ws.JPredClient ct = new jalview.ws.JPredClient(sh,\r
2375                       title, msa);\r
2376                 }\r
2377               }\r
2378             }\r
2379           });\r
2380           secstrmenu.add(method);\r
2381         }\r
2382         wsmenu.add(secstrmenu);\r
2383       }\r
2384       this.webService.removeAll();\r
2385       for (int i = 0, j = wsmenu.size(); i < j; i++)\r
2386       {\r
2387         webService.add( (JMenu) wsmenu.get(i));\r
2388       }\r
2389     }\r
2390     else\r
2391     {\r
2392       this.webService.removeAll();\r
2393       this.webService.add(this.webServiceNoServices);\r
2394     }\r
2395     // TODO: add in rediscovery function\r
2396     // TODO: reduce code redundancy.\r
2397     // TODO: group services by location as well as function.\r
2398   }\r
2399 \r
2400  /* public void vamsasStore_actionPerformed(ActionEvent e)\r
2401   {\r
2402     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
2403         getProperty("LAST_DIRECTORY"));\r
2404 \r
2405     chooser.setFileView(new JalviewFileView());\r
2406     chooser.setDialogTitle("Export to Vamsas file");\r
2407     chooser.setToolTipText("Export");\r
2408 \r
2409     int value = chooser.showSaveDialog(this);\r
2410 \r
2411     if (value == JalviewFileChooser.APPROVE_OPTION)\r
2412     {\r
2413       jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(viewport);\r
2414       //vs.store(chooser.getSelectedFile().getAbsolutePath()   );\r
2415       vs.storeJalview( chooser.getSelectedFile().getAbsolutePath(), this);\r
2416     }\r
2417   }*/\r
2418 \r
2419   public void featureSettings_actionPerformed(ActionEvent e)\r
2420   {\r
2421     new FeatureSettings(viewport, alignPanel);\r
2422   }\r
2423 \r
2424 \r
2425 \r
2426 public void showTranslation_actionPerformed(ActionEvent e)\r
2427 {\r
2428   int s, sSize = viewport.alignment.getHeight();\r
2429   SequenceI [] newSeq = new SequenceI[sSize];\r
2430 \r
2431   int res, resSize;\r
2432   StringBuffer protein;\r
2433   String seq;\r
2434   for(s=0; s<sSize; s++)\r
2435   {\r
2436     protein = new StringBuffer();\r
2437     seq = AlignSeq.extractGaps("-. ", viewport.alignment.getSequenceAt(s).getSequence());\r
2438     resSize = seq.length();\r
2439     for(res = 0; res < resSize; res+=3)\r
2440     {\r
2441       String codon = seq.substring(res, res+3);\r
2442       codon = codon.replace('U', 'T');\r
2443       String aa = ResidueProperties.codonTranslate(codon);\r
2444       if(aa==null)\r
2445         protein.append(viewport.getGapCharacter());\r
2446       else if(aa.equals("STOP"))\r
2447         protein.append("X");\r
2448       else\r
2449         protein.append( aa );\r
2450     }\r
2451     newSeq[s] = new Sequence(viewport.alignment.getSequenceAt(s).getName(), protein.toString());\r
2452   }\r
2453 \r
2454 \r
2455   AlignmentI al = new Alignment(newSeq);\r
2456   al.setDataset(null);\r
2457 \r
2458 \r
2459   ////////////////////////////////\r
2460   // Copy annotations across\r
2461   jalview.datamodel.AlignmentAnnotation[] annotations\r
2462       = viewport.alignment.getAlignmentAnnotation();\r
2463   int a, aSize;\r
2464   for (int i = 0; i < annotations.length; i++)\r
2465   {\r
2466 \r
2467     if (annotations[i].label.equals("Quality") ||\r
2468         annotations[i].label.equals("Conservation") ||\r
2469         annotations[i].label.equals("Consensus"))\r
2470     {\r
2471       continue;\r
2472     }\r
2473 \r
2474 \r
2475     aSize = viewport.alignment.getWidth()/3;\r
2476     jalview.datamodel.Annotation [] anots =\r
2477         new jalview.datamodel.Annotation[aSize];\r
2478 \r
2479     for(a=0; a<viewport.alignment.getWidth(); a++)\r
2480     {\r
2481      if( annotations[i].annotations[a]==null\r
2482       || annotations[i].annotations[a]==null)\r
2483        continue;\r
2484 \r
2485       anots[a/3] = new Annotation(\r
2486      annotations[i].annotations[a].displayCharacter,\r
2487      annotations[i].annotations[a].description,\r
2488      annotations[i].annotations[a].secondaryStructure,\r
2489      annotations[i].annotations[a].value,\r
2490      annotations[i].annotations[a].colour);\r
2491     }\r
2492 \r
2493     jalview.datamodel.AlignmentAnnotation aa\r
2494           = new jalview.datamodel.AlignmentAnnotation(annotations[i].label,\r
2495        annotations[i].description, anots );\r
2496      al.addAnnotation(aa);\r
2497   }\r
2498 \r
2499 \r
2500     AlignFrame af = new AlignFrame(al);\r
2501     Desktop.addInternalFrame(af, "Translation of "+this.getTitle(),\r
2502                              NEW_WINDOW_WIDTH,\r
2503                              NEW_WINDOW_HEIGHT);\r
2504 \r
2505 \r
2506    // AlignViewport newViewport = new AlignViewport(al);\r
2507    // AlignmentPanel ap = new AlignmentPanel(this, newViewport);\r
2508    // tabbedPane.add("Protein", ap);\r
2509    // viewports.add(newViewport);\r
2510   //  alignPanels.add(ap);\r
2511 \r
2512     ///Dataset tab\r
2513   /////////////////////////\r
2514 \r
2515   //  AlignViewport ds = new AlignViewport(al.getDataset());\r
2516   //  ds.setDataset(true);\r
2517   //  AlignmentPanel dap = new AlignmentPanel(this, ds);\r
2518   //  tabbedPane.add("Dataset", dap);\r
2519   //  viewports.add(ds);\r
2520   //  alignPanels.add(dap);\r
2521   /////////////////////////\r
2522 \r
2523 \r
2524 }\r
2525 \r
2526 /*public void tabSelected()\r
2527  {\r
2528   int index = tabbedPane.getSelectedIndex();\r
2529   viewport = (AlignViewport)viewports.elementAt(index);\r
2530   alignPanel = (AlignmentPanel)alignPanels.elementAt(index);\r
2531  }*/\r
2532 \r
2533 /**\r
2534  * DOCUMENT ME!\r
2535  *\r
2536  * @param String DOCUMENT ME!\r
2537  */\r
2538 public boolean parseGroupsFile(String file)\r
2539 {\r
2540     try\r
2541     {\r
2542       BufferedReader in = new BufferedReader(new FileReader(file));\r
2543       SequenceI seq = null;\r
2544       String line, type, desc, token;\r
2545 \r
2546       int index, start, end;\r
2547       StringTokenizer st;\r
2548       SequenceFeature sf;\r
2549       int lineNo = 0;\r
2550       while ( (line = in.readLine()) != null)\r
2551       {\r
2552         lineNo++;\r
2553         st = new StringTokenizer(line, "\t");\r
2554         if (st.countTokens() == 2)\r
2555         {\r
2556           type = st.nextToken();\r
2557           UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
2558           alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(type, ucs.findColour("A"));\r
2559           continue;\r
2560         }\r
2561 \r
2562         while (st.hasMoreElements())\r
2563         {\r
2564           desc = st.nextToken();\r
2565           token = st.nextToken();\r
2566           if (!token.equals("ID_NOT_SPECIFIED"))\r
2567           {\r
2568             index = viewport.alignment.findIndex(viewport.alignment.findName(token));\r
2569             st.nextToken();\r
2570           }\r
2571           else\r
2572           {\r
2573             index = Integer.parseInt(st.nextToken());\r
2574           }\r
2575 \r
2576           start = Integer.parseInt(st.nextToken());\r
2577           end = Integer.parseInt(st.nextToken());\r
2578 \r
2579           seq = viewport.alignment.getSequenceAt(index);\r
2580           start = seq.findIndex(start) - 1;\r
2581           end = seq.findIndex(end) - 1;\r
2582 \r
2583           type = st.nextToken();\r
2584 \r
2585           if (alignPanel.seqPanel.seqCanvas.getFeatureRenderer().getColour(type) == null)\r
2586           {\r
2587             // Probably the old style groups file\r
2588             UserColourScheme ucs = new UserColourScheme(type);\r
2589             alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(type, ucs.findColour("A"));\r
2590           }\r
2591 \r
2592           sf = new SequenceFeature(type, desc, "", start, end);\r
2593 \r
2594           seq.getDatasetSequence().addSequenceFeature(sf);\r
2595         }\r
2596       }\r
2597     }\r
2598     catch (Exception ex)\r
2599     {\r
2600       System.out.println("Error parsing groups file: " + ex);\r
2601       return false;\r
2602     }\r
2603 \r
2604     viewport.showSequenceFeatures = true;\r
2605     alignPanel.repaint();\r
2606     return true;\r
2607 }\r
2608 \r
2609 public void dragEnter(DropTargetDragEvent evt)\r
2610 {}\r
2611 \r
2612 public void dragExit(DropTargetEvent evt)\r
2613 {}\r
2614 \r
2615 public void dragOver(DropTargetDragEvent evt)\r
2616 {}\r
2617 \r
2618 public void dropActionChanged(DropTargetDragEvent evt)\r
2619 {}\r
2620 \r
2621 public void drop(DropTargetDropEvent evt)\r
2622 {\r
2623     Transferable t = evt.getTransferable();\r
2624     java.util.List files = null;\r
2625 \r
2626     try\r
2627     {\r
2628       DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");\r
2629       if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))\r
2630       {\r
2631         //Works on Windows and MacOSX\r
2632         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);\r
2633         files = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);\r
2634       }\r
2635       else if (t.isDataFlavorSupported(uriListFlavor))\r
2636       {\r
2637         // This is used by Unix drag system\r
2638         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);\r
2639         String data = (String) t.getTransferData(uriListFlavor);\r
2640         files = new java.util.ArrayList(1);\r
2641         for (java.util.StringTokenizer st = new java.util.StringTokenizer(\r
2642             data,\r
2643             "\r\n");\r
2644              st.hasMoreTokens(); )\r
2645         {\r
2646           String s = st.nextToken();\r
2647           if (s.startsWith("#"))\r
2648           {\r
2649             // the line is a comment (as per the RFC 2483)\r
2650             continue;\r
2651           }\r
2652 \r
2653           java.net.URI uri = new java.net.URI(s);\r
2654           java.io.File file = new java.io.File(uri);\r
2655           files.add(file);\r
2656         }\r
2657       }\r
2658     }\r
2659     catch (Exception e)\r
2660     {\r
2661       e.printStackTrace();\r
2662     }\r
2663 \r
2664     if (files != null)\r
2665     {\r
2666       try\r
2667       {\r
2668         boolean isAnnotation = false;\r
2669 \r
2670         for (int i = 0; i < files.size(); i++)\r
2671         {\r
2672           String file = files.get(i).toString();\r
2673 \r
2674           isAnnotation = new AnnotationReader().readAnnotationFile(viewport.alignment, file);\r
2675 \r
2676           if( !isAnnotation )\r
2677           {\r
2678             boolean isGroupsFile = parseGroupsFile(file);\r
2679             if (!isGroupsFile)\r
2680             {\r
2681               String protocol = "File";\r
2682               String format = jalview.io.IdentifyFile.Identify(file, protocol);\r
2683               SequenceI[] sequences = new FormatAdapter().readFile(file, protocol, format);\r
2684 \r
2685               FastaFile ff = new FastaFile();\r
2686               Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
2687               c.setContents(new StringSelection(ff.print(sequences)), this);\r
2688 \r
2689               this.paste(false);\r
2690 \r
2691             }\r
2692           }\r
2693         }\r
2694 \r
2695         if(isAnnotation)\r
2696         {\r
2697           int height = alignPanel.annotationPanel.adjustPanelHeight();\r
2698           alignPanel.annotationScroller.setPreferredSize(\r
2699               new Dimension(alignPanel.annotationScroller.getWidth(),\r
2700                             height));\r
2701 \r
2702           alignPanel.annotationSpaceFillerHolder.setPreferredSize(new Dimension(\r
2703               alignPanel.annotationSpaceFillerHolder.getWidth(),\r
2704               height));\r
2705 \r
2706           alignPanel.addNotify();\r
2707         }\r
2708       }\r
2709       catch (Exception ex)\r
2710       {\r
2711         ex.printStackTrace();\r
2712       }\r
2713     }\r
2714 }\r
2715 \r
2716 }\r