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