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