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