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