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