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