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