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