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