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