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