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