cc7ce484d62835cfad46eb437d098b5f1f12fb5c
[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 Software\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.util.*;\r
23 \r
24 import java.awt.*;\r
25 import java.awt.datatransfer.*;\r
26 import java.awt.event.*;\r
27 import java.awt.print.*;\r
28 import javax.swing.*;\r
29 import javax.swing.event.*;\r
30 \r
31 import jalview.analysis.*;\r
32 import jalview.datamodel.*;\r
33 import jalview.io.*;\r
34 import jalview.jbgui.*;\r
35 import jalview.schemes.*;\r
36 import jalview.ws.*;\r
37 \r
38 public class AlignFrame\r
39     extends GAlignFrame\r
40 {\r
41   public static final int NEW_WINDOW_WIDTH = 700;\r
42   public static final int NEW_WINDOW_HEIGHT = 500;\r
43   final AlignmentPanel alignPanel;\r
44   final AlignViewport viewport;\r
45   public String currentFileFormat = "Jalview";\r
46   Stack historyList = new Stack();\r
47   Stack redoList = new Stack();\r
48   private int treeCount = 0;\r
49 \r
50   public AlignFrame(AlignmentI al)\r
51   {\r
52     viewport = new AlignViewport(al);\r
53 \r
54     alignPanel = new AlignmentPanel(this, viewport);\r
55     alignPanel.annotationPanel.adjustPanelHeight();\r
56     alignPanel.annotationSpaceFillerHolder.setPreferredSize(alignPanel.\r
57         annotationPanel.getPreferredSize());\r
58     alignPanel.annotationScroller.setPreferredSize(alignPanel.annotationPanel.\r
59         getPreferredSize());\r
60     alignPanel.setAnnotationVisible(viewport.getShowAnnotation());\r
61 \r
62     getContentPane().add(alignPanel, java.awt.BorderLayout.CENTER);\r
63 \r
64     addInternalFrameListener(new InternalFrameAdapter()\r
65     {\r
66       public void internalFrameActivated(InternalFrameEvent evt)\r
67       {\r
68         javax.swing.SwingUtilities.invokeLater(new Runnable()\r
69         {\r
70           public void run()\r
71           {\r
72             alignPanel.requestFocus();\r
73           }\r
74         });\r
75       }\r
76     });\r
77   }\r
78 \r
79   public void saveAlignmentMenu_actionPerformed(ActionEvent e)\r
80   {\r
81     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
82         getProperty(\r
83             "LAST_DIRECTORY"),\r
84         new String[]\r
85         {\r
86         "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",\r
87         "jar"\r
88     },\r
89         new String[]\r
90         {\r
91         "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"\r
92     }, currentFileFormat);\r
93 \r
94     chooser.setAcceptAllFileFilterUsed(false);\r
95     chooser.setFileView(new JalviewFileView());\r
96     chooser.setDialogTitle("Save Alignment to file");\r
97     chooser.setToolTipText("Save");\r
98 \r
99     int value = chooser.showSaveDialog(this);\r
100 \r
101     if (value == JalviewFileChooser.APPROVE_OPTION)\r
102     {\r
103       currentFileFormat = chooser.getSelectedFormat();\r
104       jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",\r
105                                     currentFileFormat);\r
106 \r
107       if (currentFileFormat.equals("Jalview"))\r
108       {\r
109         String shortName = title;\r
110 \r
111         if (shortName.indexOf(java.io.File.separatorChar) > -1)\r
112         {\r
113           shortName = shortName.substring(shortName.lastIndexOf(\r
114               java.io.File.separatorChar) + 1);\r
115         }\r
116 \r
117         String choice = chooser.getSelectedFile().getPath();\r
118         Jalview2XML.SaveAlignment(this, choice, shortName);\r
119 \r
120         // USE Jalview2XML to save this file\r
121         return;\r
122       }\r
123 \r
124       String choice = chooser.getSelectedFile().getPath();\r
125       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
126 \r
127       String output = FormatAdapter.formatSequences(currentFileFormat,\r
128           viewport.getAlignment().getSequences());\r
129 \r
130       try\r
131       {\r
132         java.io.PrintWriter out = new java.io.PrintWriter(new java.io.\r
133             FileWriter(\r
134                 choice));\r
135         out.println(output);\r
136         out.close();\r
137       }\r
138       catch (Exception ex)\r
139       {\r
140       }\r
141     }\r
142   }\r
143 \r
144   protected void outputText_actionPerformed(ActionEvent e)\r
145   {\r
146     CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
147     Desktop.addInternalFrame(cap,\r
148                              "Alignment output - " + e.getActionCommand(), 600,\r
149                              500);\r
150     cap.setText(FormatAdapter.formatSequences(e.getActionCommand(),\r
151                                               viewport.getAlignment().\r
152                                               getSequences()));\r
153   }\r
154 \r
155   protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
156   {\r
157     new HTMLOutput(viewport);\r
158   }\r
159 \r
160   protected void createPNG_actionPerformed(ActionEvent e)\r
161   {\r
162     alignPanel.makePNG();\r
163   }\r
164 \r
165   protected void epsFile_actionPerformed(ActionEvent e)\r
166   {\r
167     alignPanel.makeEPS();\r
168   }\r
169 \r
170   public void printMenuItem_actionPerformed(ActionEvent e)\r
171   {\r
172     //Putting in a thread avoids Swing painting problems\r
173     PrintThread thread = new PrintThread();\r
174     thread.start();\r
175   }\r
176 \r
177   public void closeMenuItem_actionPerformed(ActionEvent e)\r
178   {\r
179     try\r
180     {\r
181       this.setClosed(true);\r
182     }\r
183     catch (Exception ex)\r
184     {\r
185     }\r
186   }\r
187 \r
188   void updateEditMenuBar()\r
189   {\r
190     if (historyList.size() > 0)\r
191     {\r
192       undoMenuItem.setEnabled(true);\r
193 \r
194       HistoryItem hi = (HistoryItem) historyList.peek();\r
195       undoMenuItem.setText("Undo " + hi.getDescription());\r
196     }\r
197     else\r
198     {\r
199       undoMenuItem.setEnabled(false);\r
200       undoMenuItem.setText("Undo");\r
201     }\r
202 \r
203     if (redoList.size() > 0)\r
204     {\r
205       redoMenuItem.setEnabled(true);\r
206 \r
207       HistoryItem hi = (HistoryItem) redoList.peek();\r
208       redoMenuItem.setText("Redo " + hi.getDescription());\r
209     }\r
210     else\r
211     {\r
212       redoMenuItem.setEnabled(false);\r
213       redoMenuItem.setText("Redo");\r
214     }\r
215   }\r
216 \r
217   public void addHistoryItem(HistoryItem hi)\r
218   {\r
219     historyList.push(hi);\r
220     updateEditMenuBar();\r
221   }\r
222 \r
223   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
224   {\r
225     HistoryItem hi = (HistoryItem) historyList.pop();\r
226     redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment,\r
227                                   HistoryItem.HIDE));\r
228     restoreHistoryItem(hi);\r
229   }\r
230 \r
231   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
232   {\r
233     HistoryItem hi = (HistoryItem) redoList.pop();\r
234     restoreHistoryItem(hi);\r
235     updateEditMenuBar();\r
236     viewport.updateConsensus();\r
237     alignPanel.repaint();\r
238     alignPanel.repaint();\r
239   }\r
240 \r
241   // used by undo and redo\r
242   void restoreHistoryItem(HistoryItem hi)\r
243   {\r
244     if (hi.getType() == HistoryItem.SORT)\r
245     {\r
246       for (int i = 0; i < hi.getSequences().size(); i++)\r
247       {\r
248         viewport.alignment.getSequences().setElementAt(hi.getSequences()\r
249             .elementAt(i),\r
250             i);\r
251       }\r
252     }\r
253     else\r
254     {\r
255       for (int i = 0; i < hi.getSequences().size(); i++)\r
256       {\r
257         SequenceI restore = (SequenceI) hi.getSequences().elementAt(i);\r
258 \r
259         if (restore.getLength() == 0)\r
260         {\r
261           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
262           viewport.alignment.getSequences().insertElementAt(restore,\r
263               hi.getAlignIndex(i));\r
264         }\r
265         else\r
266         {\r
267           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
268         }\r
269       }\r
270 \r
271       if (hi.getType() == HistoryItem.PASTE)\r
272       {\r
273         for (int i = viewport.alignment.getHeight() - 1;\r
274              i > (hi.getSequences().size() - 1); i--)\r
275         {\r
276           viewport.alignment.deleteSequence(i);\r
277         }\r
278       }\r
279     }\r
280 \r
281     updateEditMenuBar();\r
282 \r
283     viewport.updateConsensus();\r
284     viewport.updateConservation();\r
285     alignPanel.repaint();\r
286     viewport.firePropertyChange("alignment", null,\r
287                                 viewport.getAlignment().getSequences());\r
288   }\r
289 \r
290   public void moveSelectedSequences(boolean up)\r
291   {\r
292     SequenceGroup sg = viewport.getSelectionGroup();\r
293 \r
294     if (sg == null)\r
295     {\r
296       return;\r
297     }\r
298 \r
299     if (up)\r
300     {\r
301       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
302       {\r
303         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
304 \r
305         if (!sg.sequences.contains(seq))\r
306         {\r
307           continue;\r
308         }\r
309 \r
310         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
311 \r
312         if (sg.sequences.contains(temp))\r
313         {\r
314           continue;\r
315         }\r
316 \r
317         viewport.alignment.getSequences().setElementAt(temp, i);\r
318         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
319       }\r
320     }\r
321     else\r
322     {\r
323       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
324       {\r
325         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
326 \r
327         if (!sg.sequences.contains(seq))\r
328         {\r
329           continue;\r
330         }\r
331 \r
332         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
333 \r
334         if (sg.sequences.contains(temp))\r
335         {\r
336           continue;\r
337         }\r
338 \r
339         viewport.alignment.getSequences().setElementAt(temp, i);\r
340         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
341       }\r
342     }\r
343 \r
344     alignPanel.repaint();\r
345   }\r
346 \r
347   protected void copy_actionPerformed(ActionEvent e)\r
348   {\r
349     if (viewport.getSelectionGroup() == null)\r
350     {\r
351       return;\r
352     }\r
353 \r
354     SequenceGroup sg = viewport.getSelectionGroup();\r
355 \r
356     Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
357     StringBuffer buffer = new StringBuffer();\r
358 \r
359     Hashtable orderedSeqs = new Hashtable();\r
360 \r
361     for (int i = 0; i < sg.getSize(); i++)\r
362     {\r
363       SequenceI seq = sg.getSequenceAt(i);\r
364       int index = viewport.alignment.findIndex(seq);\r
365       orderedSeqs.put(index + "", seq);\r
366     }\r
367 \r
368     int index = 0;\r
369 \r
370     for (int i = 0; i < sg.getSize(); i++)\r
371     {\r
372       SequenceI seq = null;\r
373 \r
374       while (seq == null)\r
375       {\r
376         if (orderedSeqs.containsKey(index + ""))\r
377         {\r
378           seq = (SequenceI) orderedSeqs.get(index + "");\r
379           index++;\r
380 \r
381           break;\r
382         }\r
383         else\r
384         {\r
385           index++;\r
386         }\r
387       }\r
388 \r
389       buffer.append(seq.getName() + "\t" +\r
390                     seq.findPosition(sg.getStartRes()) + "\t" +\r
391                     seq.findPosition(sg.getEndRes()) + "\t" +\r
392                     sg.getSequenceAt(i).getSequence(sg.getStartRes(),\r
393           sg.getEndRes() + 1) + "\n");\r
394     }\r
395 \r
396     c.setContents(new StringSelection(buffer.toString()), null);\r
397   }\r
398 \r
399   protected void pasteNew_actionPerformed(ActionEvent e)\r
400   {\r
401     paste(true);\r
402   }\r
403 \r
404   protected void pasteThis_actionPerformed(ActionEvent e)\r
405   {\r
406     addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
407                                    HistoryItem.PASTE));\r
408     paste(false);\r
409   }\r
410 \r
411   void paste(boolean newAlignment)\r
412   {\r
413     try\r
414     {\r
415       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
416       Transferable contents = c.getContents(this);\r
417 \r
418       if (contents == null)\r
419       {\r
420         return;\r
421       }\r
422 \r
423       String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
424       StringTokenizer st = new StringTokenizer(str);\r
425       ArrayList seqs = new ArrayList();\r
426 \r
427       while (st.hasMoreElements())\r
428       {\r
429         String name = st.nextToken();\r
430         int start = Integer.parseInt(st.nextToken());\r
431         int end = Integer.parseInt(st.nextToken());\r
432         Sequence sequence = new Sequence(name, st.nextToken(), start,\r
433                                          end);\r
434 \r
435         if (!newAlignment)\r
436         {\r
437           viewport.alignment.addSequence(sequence);\r
438         }\r
439         else\r
440         {\r
441           seqs.add(sequence);\r
442         }\r
443       }\r
444 \r
445       if (newAlignment)\r
446       {\r
447         SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
448         seqs.toArray(newSeqs);\r
449 \r
450         AlignFrame af = new AlignFrame(new Alignment(newSeqs));\r
451         String newtitle = new String("Copied sequences");\r
452 \r
453         if (title.startsWith("Copied sequences"))\r
454         {\r
455           newtitle = title;\r
456         }\r
457         else\r
458         {\r
459           newtitle = newtitle.concat("- from " + title);\r
460         }\r
461 \r
462         Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
463                                  NEW_WINDOW_HEIGHT);\r
464       }\r
465       else\r
466       {\r
467         viewport.firePropertyChange("alignment", null,\r
468                                     viewport.getAlignment().getSequences());\r
469         viewport.setEndSeq(viewport.alignment.getHeight());\r
470         viewport.alignment.getWidth();\r
471         viewport.updateConservation();\r
472         viewport.updateConsensus();\r
473         alignPanel.repaint();\r
474       }\r
475     }\r
476     catch (Exception ex)\r
477     {\r
478     }\r
479 \r
480     // could be anything being pasted in here\r
481   }\r
482 \r
483   protected void cut_actionPerformed(ActionEvent e)\r
484   {\r
485     copy_actionPerformed(null);\r
486     delete_actionPerformed(null);\r
487   }\r
488 \r
489   protected void delete_actionPerformed(ActionEvent e)\r
490   {\r
491     boolean seqsdeleted = false;\r
492 \r
493     if (viewport.getSelectionGroup() == null)\r
494     {\r
495       return;\r
496     }\r
497 \r
498     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
499                                    HistoryItem.HIDE));\r
500 \r
501     SequenceGroup sg = viewport.getSelectionGroup();\r
502 \r
503     for (int i = 0; i < sg.sequences.size(); i++)\r
504     {\r
505       SequenceI seq = sg.getSequenceAt(i);\r
506       int index = viewport.getAlignment().findIndex(seq);\r
507       seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
508 \r
509       if (seq.getSequence().length() < 1)\r
510       {\r
511         seqsdeleted = true;\r
512         viewport.getAlignment().deleteSequence(seq);\r
513       }\r
514       else\r
515       {\r
516         viewport.getAlignment().getSequences().setElementAt(seq, index);\r
517       }\r
518     }\r
519 \r
520     viewport.setSelectionGroup(null);\r
521     viewport.alignment.deleteGroup(sg);\r
522 \r
523     if (seqsdeleted)\r
524     {\r
525       viewport.firePropertyChange("alignment", null,\r
526                                   viewport.getAlignment().getSequences());\r
527     }\r
528 \r
529     viewport.resetSeqLimits(alignPanel.seqPanel.seqCanvas.getHeight());\r
530 \r
531     if (viewport.getAlignment().getHeight() < 1)\r
532     {\r
533       try\r
534       {\r
535         this.setClosed(true);\r
536       }\r
537       catch (Exception ex)\r
538       {\r
539       }\r
540     }\r
541 \r
542     viewport.updateConservation();\r
543     viewport.updateConsensus();\r
544     alignPanel.repaint();\r
545   }\r
546 \r
547   protected void deleteGroups_actionPerformed(ActionEvent e)\r
548   {\r
549     viewport.alignment.deleteAllGroups();\r
550     viewport.setSelectionGroup(null);\r
551     alignPanel.repaint();\r
552   }\r
553 \r
554   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
555   {\r
556     SequenceGroup sg = new SequenceGroup();\r
557 \r
558     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
559          i++)\r
560     {\r
561       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
562     }\r
563 \r
564     sg.setEndRes(viewport.alignment.getWidth());\r
565     viewport.setSelectionGroup(sg);\r
566     PaintRefresher.Refresh(null, viewport.alignment);\r
567   }\r
568 \r
569   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
570   {\r
571     viewport.setSelectionGroup(null);\r
572     viewport.getColumnSelection().clear();\r
573     viewport.setSelectionGroup(null);\r
574     alignPanel.annotationPanel.activeRes=null;\r
575     PaintRefresher.Refresh(null, viewport.alignment);\r
576   }\r
577 \r
578   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
579   {\r
580     SequenceGroup sg = viewport.getSelectionGroup();\r
581     if(sg==null)\r
582     {\r
583       selectAllSequenceMenuItem_actionPerformed(null);\r
584       return;\r
585     }\r
586 \r
587     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
588          i++)\r
589     {\r
590       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
591     }\r
592 \r
593     PaintRefresher.Refresh(null, viewport.alignment);\r
594   }\r
595 \r
596   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
597   {\r
598     ColumnSelection colSel = viewport.getColumnSelection();\r
599 \r
600     if (colSel.size() > 0)\r
601     {\r
602       addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
603                                      HistoryItem.HIDE));\r
604 \r
605       int min = colSel.getMin();\r
606       viewport.getAlignment().trimLeft(min);\r
607       colSel.compensateForEdit(0, min);\r
608 \r
609       if (viewport.getSelectionGroup() != null)\r
610       {\r
611         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
612       }\r
613 \r
614       Vector groups = viewport.alignment.getGroups();\r
615 \r
616       for (int i = 0; i < groups.size(); i++)\r
617       {\r
618         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
619 \r
620         if (!sg.adjustForRemoveLeft(min))\r
621         {\r
622           viewport.alignment.deleteGroup(sg);\r
623         }\r
624       }\r
625 \r
626       alignPanel.repaint();\r
627     }\r
628   }\r
629 \r
630   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
631   {\r
632     ColumnSelection colSel = viewport.getColumnSelection();\r
633 \r
634     if (colSel.size() > 0)\r
635     {\r
636       addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
637                                      HistoryItem.HIDE));\r
638 \r
639       int max = colSel.getMax();\r
640       viewport.getAlignment().trimRight(max);\r
641 \r
642       if (viewport.getSelectionGroup() != null)\r
643       {\r
644         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
645       }\r
646 \r
647       Vector groups = viewport.alignment.getGroups();\r
648 \r
649       for (int i = 0; i < groups.size(); i++)\r
650       {\r
651         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
652 \r
653         if (!sg.adjustForRemoveRight(max))\r
654         {\r
655           viewport.alignment.deleteGroup(sg);\r
656         }\r
657       }\r
658 \r
659       alignPanel.repaint();\r
660     }\r
661   }\r
662 \r
663   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
664   {\r
665     addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
666                                    viewport.alignment, HistoryItem.HIDE));\r
667 \r
668     viewport.getAlignment().removeGaps();\r
669     viewport.updateConservation();\r
670     viewport.updateConsensus();\r
671     alignPanel.repaint();\r
672   }\r
673 \r
674   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
675   {\r
676     addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
677                                    HistoryItem.HIDE));\r
678 \r
679     SequenceI current;\r
680     int jSize;\r
681 \r
682     Vector seqs=null;\r
683 \r
684     int start=0, end = viewport.alignment.getWidth();\r
685 \r
686     if(viewport.getSelectionGroup()!=null)\r
687     {\r
688       seqs = viewport.getSelectionGroup().sequences;\r
689       start = viewport.getSelectionGroup().getStartRes();\r
690       end = viewport.getSelectionGroup().getEndRes();\r
691     }\r
692     else\r
693       seqs = viewport.alignment.getSequences();\r
694 \r
695     for (int i = 0; i <seqs.size(); i++)\r
696     {\r
697       current = (SequenceI)seqs.elementAt(i);\r
698       jSize = current.getLength();\r
699 \r
700       int j = start;\r
701       do\r
702       {\r
703         if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
704         {\r
705           current.deleteCharAt(j);\r
706           j--;\r
707           jSize--;\r
708         }\r
709         j++;\r
710       }\r
711       while(j < end);\r
712     }\r
713 \r
714     viewport.updateConservation();\r
715     viewport.updateConsensus();\r
716     alignPanel.repaint();\r
717   }\r
718 \r
719   public void padGapsMenuitem_actionPerformed(ActionEvent e)\r
720   {\r
721     addHistoryItem(new HistoryItem("Pad Gaps", viewport.alignment,\r
722                                    HistoryItem.HIDE));\r
723 \r
724     SequenceI current;\r
725     int Width = viewport.getAlignment().getWidth();\r
726 \r
727     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
728          i++)\r
729     {\r
730       current = viewport.getAlignment().getSequenceAt(i);\r
731 \r
732       if (current.getLength() < Width)\r
733       {\r
734         current.insertCharAt(Width-1, viewport.getGapCharacter());\r
735       }\r
736     }\r
737 \r
738     viewport.updateConservation();\r
739     viewport.updateConsensus();\r
740     alignPanel.repaint();\r
741   }\r
742 \r
743   public void findMenuItem_actionPerformed(ActionEvent e)\r
744   {\r
745     JInternalFrame frame = new JInternalFrame();\r
746     Finder finder = new Finder(viewport, alignPanel, frame);\r
747     frame.setContentPane(finder);\r
748     Desktop.addInternalFrame(frame, "Find", 340, 110);\r
749     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
750   }\r
751 \r
752   public void font_actionPerformed(ActionEvent e)\r
753   {\r
754     FontChooser fc = new FontChooser(alignPanel);\r
755   }\r
756 \r
757   protected void fullSeqId_actionPerformed(ActionEvent e)\r
758   {\r
759     viewport.setShowFullId(fullSeqId.isSelected());\r
760 \r
761     alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());\r
762     alignPanel.repaint();\r
763   }\r
764 \r
765   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
766   {\r
767     viewport.setColourText(colourTextMenuItem.isSelected());\r
768     alignPanel.repaint();\r
769   }\r
770 \r
771   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
772   {\r
773     viewport.setWrapAlignment(wrapMenuItem.isSelected());\r
774     alignPanel.setWrapAlignment(wrapMenuItem.isSelected());\r
775     scaleAbove.setVisible(wrapMenuItem.isSelected());\r
776     scaleLeft.setVisible(wrapMenuItem.isSelected());\r
777     scaleRight.setVisible(wrapMenuItem.isSelected());\r
778     alignPanel.repaint();\r
779   }\r
780 \r
781   protected void scaleAbove_actionPerformed(ActionEvent e)\r
782   {\r
783     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
784     alignPanel.repaint();\r
785   }\r
786 \r
787   protected void scaleLeft_actionPerformed(ActionEvent e)\r
788   {\r
789     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
790     alignPanel.repaint();\r
791   }\r
792 \r
793   protected void scaleRight_actionPerformed(ActionEvent e)\r
794   {\r
795     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
796     alignPanel.repaint();\r
797   }\r
798 \r
799   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
800   {\r
801     viewport.setShowBoxes(viewBoxesMenuItem.isSelected());\r
802     alignPanel.repaint();\r
803   }\r
804 \r
805   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
806   {\r
807     viewport.setShowText(viewTextMenuItem.isSelected());\r
808     alignPanel.repaint();\r
809   }\r
810 \r
811   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
812   {\r
813     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
814     alignPanel.repaint();\r
815   }\r
816 \r
817   public void sequenceFeatures_actionPerformed(ActionEvent evt)\r
818   {\r
819     viewport.showSequenceFeatures(sequenceFeatures.isSelected());\r
820 \r
821     if (viewport.showSequenceFeatures &&\r
822         ! ( (Alignment) viewport.alignment).featuresAdded)\r
823     {\r
824       SequenceFeatureFetcher sft = new SequenceFeatureFetcher(viewport.\r
825           alignment,\r
826           alignPanel);\r
827       ( (Alignment) viewport.alignment).featuresAdded = true;\r
828     }\r
829 \r
830     alignPanel.repaint();\r
831   }\r
832 \r
833   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
834   {\r
835     if (annotationPanelMenuItem.isSelected() &&\r
836         viewport.getWrapAlignment())\r
837     {\r
838       annotationPanelMenuItem.setSelected(false);\r
839 \r
840       return;\r
841     }\r
842 \r
843     viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());\r
844     alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());\r
845   }\r
846 \r
847   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
848   {\r
849     if (alignPanel.overviewPanel != null)\r
850     {\r
851       return;\r
852     }\r
853 \r
854     JInternalFrame frame = new JInternalFrame();\r
855     OverviewPanel overview = new OverviewPanel(alignPanel);\r
856     frame.setContentPane(overview);\r
857     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
858                              frame.getWidth(), frame.getHeight());\r
859     frame.pack();\r
860     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
861     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
862     {\r
863       public void internalFrameClosed(\r
864           javax.swing.event.InternalFrameEvent evt)\r
865       {\r
866         alignPanel.setOverviewPanel(null);\r
867       }\r
868       ;\r
869     });\r
870 \r
871     alignPanel.setOverviewPanel(overview);\r
872   }\r
873 \r
874   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
875   {\r
876     changeColour(null);\r
877   }\r
878 \r
879   public void clustalColour_actionPerformed(ActionEvent e)\r
880   {\r
881     changeColour(new ClustalxColourScheme(\r
882         viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
883   }\r
884 \r
885   public void zappoColour_actionPerformed(ActionEvent e)\r
886   {\r
887     changeColour(new ZappoColourScheme());\r
888   }\r
889 \r
890   public void taylorColour_actionPerformed(ActionEvent e)\r
891   {\r
892     changeColour(new TaylorColourScheme());\r
893   }\r
894 \r
895   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
896   {\r
897     changeColour(new HydrophobicColourScheme());\r
898   }\r
899 \r
900   public void helixColour_actionPerformed(ActionEvent e)\r
901   {\r
902     changeColour(new HelixColourScheme());\r
903   }\r
904 \r
905   public void strandColour_actionPerformed(ActionEvent e)\r
906   {\r
907     changeColour(new StrandColourScheme());\r
908   }\r
909 \r
910   public void turnColour_actionPerformed(ActionEvent e)\r
911   {\r
912     changeColour(new TurnColourScheme());\r
913   }\r
914 \r
915   public void buriedColour_actionPerformed(ActionEvent e)\r
916   {\r
917     changeColour(new BuriedColourScheme());\r
918   }\r
919 \r
920   public void nucleotideColour_actionPerformed(ActionEvent e)\r
921   {\r
922     changeColour(new NucleotideColourScheme());\r
923   }\r
924 \r
925   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
926   {\r
927     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
928   }\r
929 \r
930   void changeColour(ColourSchemeI cs)\r
931   {\r
932     int threshold = 0;\r
933 \r
934     if (viewport.getAbovePIDThreshold())\r
935     {\r
936       threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,\r
937                                                  "Background");\r
938 \r
939       if (cs instanceof ResidueColourScheme)\r
940       {\r
941         ( (ResidueColourScheme) cs).setThreshold(threshold);\r
942       }\r
943       else if (cs instanceof ScoreColourScheme)\r
944       {\r
945         ( (ScoreColourScheme) cs).setThreshold(threshold);\r
946       }\r
947 \r
948       viewport.setGlobalColourScheme(cs);\r
949     }\r
950     else if (cs instanceof ResidueColourScheme)\r
951     {\r
952       ( (ResidueColourScheme) cs).setThreshold(0);\r
953     }\r
954     else if (cs instanceof ScoreColourScheme)\r
955     {\r
956       ( (ScoreColourScheme) cs).setThreshold(0);\r
957     }\r
958 \r
959     if (viewport.getConservationSelected())\r
960     {\r
961       ConservationColourScheme ccs = null;\r
962 \r
963       Alignment al = (Alignment) viewport.alignment;\r
964       Conservation c = new Conservation("All",\r
965                                         ResidueProperties.propHash, 3,\r
966                                         al.getSequences(), 0,\r
967                                         al.getWidth() - 1);\r
968 \r
969       c.calculate();\r
970       c.verdict(false, viewport.ConsPercGaps);\r
971 \r
972       ccs = new ConservationColourScheme(c, cs);\r
973 \r
974       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
975       ccs.setConsensus(viewport.vconsensus);\r
976       viewport.setGlobalColourScheme(ccs);\r
977 \r
978       ccs.inc = SliderPanel.setConservationSlider(alignPanel, ccs,\r
979                                                   "Background");\r
980     }\r
981     else\r
982     {\r
983       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
984       if (cs != null)\r
985       {\r
986         cs.setConsensus(viewport.vconsensus);\r
987       }\r
988 \r
989       viewport.setGlobalColourScheme(cs);\r
990     }\r
991 \r
992     if (viewport.getColourAppliesToAllGroups())\r
993     {\r
994       Vector groups = viewport.alignment.getGroups();\r
995 \r
996       for (int i = 0; i < groups.size(); i++)\r
997       {\r
998         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
999 \r
1000         if (cs == null)\r
1001         {\r
1002           sg.cs = null;\r
1003         }\r
1004         else if (cs instanceof ClustalxColourScheme)\r
1005         {\r
1006           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
1007         }\r
1008         else if (cs instanceof UserColourScheme)\r
1009         {\r
1010           sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());\r
1011         }\r
1012         else\r
1013         {\r
1014           try\r
1015           {\r
1016             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
1017           }\r
1018           catch (Exception ex)\r
1019           {\r
1020           }\r
1021         }\r
1022 \r
1023         if (viewport.getAbovePIDThreshold())\r
1024         {\r
1025           if (sg.cs instanceof ResidueColourScheme)\r
1026           {\r
1027             ( (ResidueColourScheme) sg.cs).setThreshold(threshold);\r
1028           }\r
1029           else if (sg.cs instanceof ScoreColourScheme)\r
1030           {\r
1031             ( (ScoreColourScheme) sg.cs).setThreshold(threshold);\r
1032           }\r
1033 \r
1034           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1035               sg.getWidth()));\r
1036         }\r
1037 \r
1038         if (viewport.getConservationSelected())\r
1039         {\r
1040           Conservation c = new Conservation("Group",\r
1041                                             ResidueProperties.propHash, 3,\r
1042                                             sg.sequences, 0,\r
1043                                             viewport.alignment.getWidth() - 1);\r
1044           c.calculate();\r
1045           c.verdict(false, viewport.ConsPercGaps);\r
1046 \r
1047           ConservationColourScheme ccs = new ConservationColourScheme(c,\r
1048               sg.cs);\r
1049 \r
1050           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
1051           ccs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1052                                                  sg.getWidth()));\r
1053           sg.cs = ccs;\r
1054         }\r
1055         else if (cs != null)\r
1056         {\r
1057           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
1058           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1059               sg.getWidth()));\r
1060         }\r
1061       }\r
1062     }\r
1063 \r
1064     if (alignPanel.getOverviewPanel() != null)\r
1065     {\r
1066       alignPanel.getOverviewPanel().updateOverviewImage();\r
1067     }\r
1068 \r
1069     alignPanel.repaint();\r
1070   }\r
1071 \r
1072   protected void modifyPID_actionPerformed(ActionEvent e)\r
1073   {\r
1074     if (viewport.getAbovePIDThreshold())\r
1075     {\r
1076       SliderPanel.setPIDSliderSource(alignPanel,\r
1077                                      viewport.getGlobalColourScheme(),\r
1078                                      "Background");\r
1079       SliderPanel.showPIDSlider();\r
1080     }\r
1081   }\r
1082 \r
1083   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1084   {\r
1085     if (viewport.getConservationSelected())\r
1086     {\r
1087       SliderPanel.setConservationSlider(alignPanel,\r
1088                                         viewport.globalColourScheme,\r
1089                                         "Background");\r
1090       SliderPanel.showConservationSlider();\r
1091     }\r
1092   }\r
1093 \r
1094   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1095   {\r
1096     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
1097 \r
1098     viewport.setAbovePIDThreshold(false);\r
1099     abovePIDThreshold.setSelected(false);\r
1100 \r
1101     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
1102 \r
1103     if (cs instanceof ConservationColourScheme)\r
1104     {\r
1105       changeColour( ( (ConservationColourScheme) cs).cs);\r
1106     }\r
1107     else\r
1108     {\r
1109       changeColour(cs);\r
1110     }\r
1111 \r
1112     modifyConservation_actionPerformed(null);\r
1113   }\r
1114 \r
1115   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1116   {\r
1117     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
1118 \r
1119     conservationMenuItem.setSelected(false);\r
1120     viewport.setConservationSelected(false);\r
1121 \r
1122     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
1123 \r
1124     if (cs instanceof ConservationColourScheme)\r
1125     {\r
1126       changeColour( ( (ConservationColourScheme) cs).cs);\r
1127     }\r
1128     else\r
1129     {\r
1130       changeColour(cs);\r
1131     }\r
1132 \r
1133     modifyPID_actionPerformed(null);\r
1134   }\r
1135 \r
1136   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1137   {\r
1138     new UserDefinedColours(alignPanel, null);\r
1139   }\r
1140 \r
1141   public void PIDColour_actionPerformed(ActionEvent e)\r
1142   {\r
1143     changeColour(new PIDColourScheme());\r
1144   }\r
1145 \r
1146   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1147   {\r
1148     changeColour(new Blosum62ColourScheme());\r
1149   }\r
1150 \r
1151   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1152   {\r
1153     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1154                                    HistoryItem.SORT));\r
1155     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1156                               viewport.getAlignment().getSequenceAt(0));\r
1157     alignPanel.repaint();\r
1158   }\r
1159 \r
1160   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1161   {\r
1162     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1163                                    HistoryItem.SORT));\r
1164     AlignmentSorter.sortByID(viewport.getAlignment());\r
1165     alignPanel.repaint();\r
1166   }\r
1167 \r
1168   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1169   {\r
1170     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1171                                    HistoryItem.SORT));\r
1172 \r
1173     //  AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1174     AlignmentSorter.sortGroups(viewport.getAlignment());\r
1175     alignPanel.repaint();\r
1176   }\r
1177 \r
1178   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1179   {\r
1180     RedundancyPanel sp = new RedundancyPanel(alignPanel, this);\r
1181     JInternalFrame frame = new JInternalFrame();\r
1182     frame.setContentPane(sp);\r
1183     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
1184                              100, false);\r
1185   }\r
1186 \r
1187   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1188   {\r
1189     if ( (viewport.getSelectionGroup() == null) ||\r
1190         (viewport.getSelectionGroup().getSize() < 2))\r
1191     {\r
1192       JOptionPane.showInternalMessageDialog(this,\r
1193                                             "You must select at least 2 sequences.",\r
1194                                             "Invalid Selection",\r
1195                                             JOptionPane.WARNING_MESSAGE);\r
1196     }\r
1197     else\r
1198     {\r
1199       JInternalFrame frame = new JInternalFrame();\r
1200       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
1201       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
1202     }\r
1203   }\r
1204 \r
1205   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1206   {\r
1207     if ( ( (viewport.getSelectionGroup() != null) &&\r
1208           (viewport.getSelectionGroup().getSize() < 4) &&\r
1209           (viewport.getSelectionGroup().getSize() > 0)) ||\r
1210         (viewport.getAlignment().getHeight() < 4))\r
1211     {\r
1212       JOptionPane.showInternalMessageDialog(this,\r
1213                                             "Principal component analysis must take\n" +\r
1214                                             "at least 4 input sequences.",\r
1215                                             "Sequence selection insufficient",\r
1216                                             JOptionPane.WARNING_MESSAGE);\r
1217 \r
1218       return;\r
1219     }\r
1220 \r
1221     try\r
1222     {\r
1223       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
1224       JInternalFrame frame = new JInternalFrame();\r
1225       frame.setContentPane(pcaPanel);\r
1226       Desktop.addInternalFrame(frame, "Principal component analysis",\r
1227                                400, 400);\r
1228     }\r
1229     catch (java.lang.OutOfMemoryError ex)\r
1230     {\r
1231       JOptionPane.showInternalMessageDialog(this,\r
1232                                             "Too many sequences selected\nfor Principal Component Analysis!!",\r
1233                                             "Out of memory",\r
1234                                             JOptionPane.WARNING_MESSAGE);\r
1235     }\r
1236   }\r
1237 \r
1238   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1239   {\r
1240     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1241   }\r
1242 \r
1243   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1244   {\r
1245     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1246   }\r
1247 \r
1248   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1249   {\r
1250     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1251   }\r
1252 \r
1253   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1254   {\r
1255     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");\r
1256   }\r
1257 \r
1258   void NewTreePanel(String type, String pwType, String title)\r
1259   {\r
1260     final TreePanel tp;\r
1261 \r
1262     if ( (viewport.getSelectionGroup() != null) &&\r
1263         (viewport.getSelectionGroup().getSize() > 3))\r
1264     {\r
1265       int s = 0;\r
1266       SequenceGroup sg = viewport.getSelectionGroup();\r
1267 \r
1268       /* Decide if the selection is a column region */\r
1269       while (s < sg.sequences.size())\r
1270       {\r
1271         if ( ( (SequenceI) sg.sequences.elementAt(s++)).getLength() <\r
1272             sg.getEndRes())\r
1273         {\r
1274           JOptionPane.showMessageDialog(Desktop.desktop,\r
1275                                         "The selected region to create a tree may\nonly contain residues or gaps.\n" +\r
1276                                         "Try using the Pad function in the edit menu,\n" +\r
1277                                         "or one of the multiple sequence alignment web services.",\r
1278                                         "Sequences in selection are not aligned",\r
1279                                         JOptionPane.WARNING_MESSAGE);\r
1280 \r
1281           return;\r
1282         }\r
1283       }\r
1284 \r
1285       title = title + " on region";\r
1286       tp = new TreePanel(viewport,\r
1287                          viewport.getSelectionGroup().sequences, type, pwType,\r
1288                          sg.getStartRes(), sg.getEndRes());\r
1289     }\r
1290     else\r
1291     {\r
1292       //are the sequences aligned?\r
1293       if (!viewport.alignment.isAligned())\r
1294       {\r
1295         JOptionPane.showMessageDialog(Desktop.desktop,\r
1296                                       "The sequences must be aligned before creating a tree.\n" +\r
1297                                       "Try using the Pad function in the edit menu,\n" +\r
1298                                       "or one of the multiple sequence alignment web services.",\r
1299                                       "Sequences not aligned",\r
1300                                       JOptionPane.WARNING_MESSAGE);\r
1301 \r
1302         return;\r
1303       }\r
1304 \r
1305       tp = new TreePanel(viewport,\r
1306                          viewport.getAlignment().getSequences(), type, pwType,\r
1307                          0,\r
1308                          viewport.alignment.getWidth());\r
1309     }\r
1310 \r
1311     addTreeMenuItem(tp, title);\r
1312     viewport.setCurrentTree(tp.getTree());\r
1313 \r
1314     Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);\r
1315   }\r
1316 \r
1317   public void addSortByOrderMenuItem(String title, final AlignmentOrder order)\r
1318   {\r
1319     final JMenuItem item = new JMenuItem("by " + title);\r
1320     sort.add(item);\r
1321     item.addActionListener(new java.awt.event.ActionListener()\r
1322     {\r
1323       public void actionPerformed(ActionEvent e)\r
1324       {\r
1325         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
1326                                        HistoryItem.SORT));\r
1327 \r
1328         // TODO: JBPNote - have to map order entries to curent SequenceI pointers\r
1329         AlignmentSorter.sortBy(viewport.getAlignment(), order);\r
1330         alignPanel.repaint();\r
1331       }\r
1332     });\r
1333   }\r
1334 \r
1335   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1336   {\r
1337     final JMenuItem item = new JMenuItem(title);\r
1338 \r
1339     treeCount++;\r
1340 \r
1341     if (treeCount == 1)\r
1342     {\r
1343       sort.add(sortByTreeMenu);\r
1344     }\r
1345 \r
1346     sortByTreeMenu.add(item);\r
1347     item.addActionListener(new java.awt.event.ActionListener()\r
1348     {\r
1349       public void actionPerformed(ActionEvent e)\r
1350       {\r
1351         addHistoryItem(new HistoryItem("Tree Sort",\r
1352                                        viewport.alignment, HistoryItem.SORT));\r
1353         AlignmentSorter.sortByTree(viewport.getAlignment(),\r
1354                                    treePanel.getTree());\r
1355         alignPanel.repaint();\r
1356       }\r
1357     });\r
1358 \r
1359     treePanel.addInternalFrameListener(new javax.swing.event.\r
1360                                        InternalFrameAdapter()\r
1361     {\r
1362       public void internalFrameClosed(\r
1363           javax.swing.event.InternalFrameEvent evt)\r
1364       {\r
1365         treeCount--;\r
1366         sortByTreeMenu.remove(item);\r
1367 \r
1368         if (treeCount == 0)\r
1369         {\r
1370           sort.remove(sortByTreeMenu);\r
1371         }\r
1372       }\r
1373       ;\r
1374     });\r
1375     viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
1376     {\r
1377       public void propertyChange(PropertyChangeEvent evt)\r
1378       {\r
1379         if (evt.getPropertyName().equals("alignment"))\r
1380         {\r
1381           treePanel.getTree().UpdatePlaceHolders( (Vector) evt.getNewValue());\r
1382           treePanel.repaint();\r
1383         }\r
1384       }\r
1385     });\r
1386   }\r
1387 \r
1388   public void clustalAlignMenuItem_actionPerformed(ActionEvent e)\r
1389   {\r
1390     // TODO:resolve which menu item was actually selected\r
1391     // Now, check we have enough sequences\r
1392     SequenceI[] msa = null;\r
1393 \r
1394     if ( (viewport.getSelectionGroup() != null) &&\r
1395         (viewport.getSelectionGroup().getSize() > 1))\r
1396     {\r
1397       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1398       SequenceGroup seqs = viewport.getSelectionGroup();\r
1399       int sz;\r
1400       msa = new SequenceI[sz = seqs.getSize()];\r
1401 \r
1402       for (int i = 0; i < sz; i++)\r
1403       {\r
1404         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1405       }\r
1406     }\r
1407     else\r
1408     {\r
1409       Vector seqs = viewport.getAlignment().getSequences();\r
1410 \r
1411       if (seqs.size() > 1)\r
1412       {\r
1413         msa = new SequenceI[seqs.size()];\r
1414 \r
1415         for (int i = 0; i < seqs.size(); i++)\r
1416         {\r
1417           msa[i] = (SequenceI) seqs.elementAt(i);\r
1418         }\r
1419       }\r
1420     }\r
1421 \r
1422     if (msa != null)\r
1423     {\r
1424       jalview.ws.MsaWSClient ct = new jalview.ws.MsaWSClient("ClustalWS",\r
1425           title, msa, false, true);\r
1426     }\r
1427   }\r
1428 \r
1429   public void ClustalRealign_actionPerformed(ActionEvent e)\r
1430   {\r
1431     // TODO:resolve which menu item was actually selected\r
1432     // Now, check we have enough sequences\r
1433     SequenceI[] msa = null;\r
1434 \r
1435     if ( (viewport.getSelectionGroup() != null) &&\r
1436         (viewport.getSelectionGroup().getSize() > 1))\r
1437     {\r
1438       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1439       SequenceGroup seqs = viewport.getSelectionGroup();\r
1440       int sz;\r
1441       msa = new SequenceI[sz = seqs.getSize()];\r
1442 \r
1443       for (int i = 0; i < sz; i++)\r
1444       {\r
1445         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1446       }\r
1447     }\r
1448     else\r
1449     {\r
1450       Vector seqs = viewport.getAlignment().getSequences();\r
1451 \r
1452       if (seqs.size() > 1)\r
1453       {\r
1454         msa = new SequenceI[seqs.size()];\r
1455 \r
1456         for (int i = 0; i < seqs.size(); i++)\r
1457         {\r
1458           msa[i] = (SequenceI) seqs.elementAt(i);\r
1459         }\r
1460       }\r
1461     }\r
1462 \r
1463     if (msa != null)\r
1464     {\r
1465       jalview.ws.MsaWSClient ct = new jalview.ws.MsaWSClient("ClustalWS",\r
1466           title, msa, true, true);\r
1467     }\r
1468   }\r
1469 \r
1470   protected void jpred_actionPerformed(ActionEvent e)\r
1471   {\r
1472     SequenceI seq = null;\r
1473     SequenceI[] msa = null;\r
1474 \r
1475     if ( (viewport.getSelectionGroup() != null) &&\r
1476         (viewport.getSelectionGroup().getSize() > 0))\r
1477     {\r
1478       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1479       SequenceGroup seqs = viewport.getSelectionGroup();\r
1480 \r
1481       if ( (seqs.getSize() == 1) || !viewport.alignment.isAligned())\r
1482       {\r
1483         seq = (SequenceI) seqs.getSequenceAt(0);\r
1484       }\r
1485       else\r
1486       {\r
1487         int sz;\r
1488         msa = new SequenceI[sz = seqs.getSize()];\r
1489 \r
1490         for (int i = 0; i < sz; i++)\r
1491         {\r
1492           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1493         }\r
1494       }\r
1495     }\r
1496     else\r
1497     {\r
1498       Vector seqs = viewport.getAlignment().getSequences();\r
1499 \r
1500       if ( (seqs.size() == 1) || !viewport.alignment.isAligned())\r
1501       {\r
1502         seq = (SequenceI) seqs.elementAt(0);\r
1503       }\r
1504       else\r
1505       {\r
1506         msa = new SequenceI[seqs.size()];\r
1507 \r
1508         for (int i = 0; i < seqs.size(); i++)\r
1509         {\r
1510           msa[i] = (SequenceI) seqs.elementAt(i);\r
1511         }\r
1512       }\r
1513     }\r
1514 \r
1515     if (msa != null)\r
1516     {\r
1517       JPredClient ct = new JPredClient(title, msa);\r
1518     }\r
1519     else if (seq != null)\r
1520     {\r
1521       JPredClient ct = new JPredClient(title, seq);\r
1522     }\r
1523     else\r
1524     {\r
1525       System.err.print(\r
1526           "JALVIEW ERROR! - Unexpected JPred selection state!\n");\r
1527     }\r
1528   }\r
1529 \r
1530   protected void msaAlignMenuItem_actionPerformed(ActionEvent e)\r
1531   {\r
1532     // TODO:resolve which menu item was actually selected\r
1533     // Now, check we have enough sequences\r
1534     SequenceI[] msa = null;\r
1535 \r
1536     if ( (viewport.getSelectionGroup() != null) &&\r
1537         (viewport.getSelectionGroup().getSize() > 1))\r
1538     {\r
1539       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1540       SequenceGroup seqs = viewport.getSelectionGroup();\r
1541       int sz;\r
1542       msa = new SequenceI[sz = seqs.getSize()];\r
1543 \r
1544       for (int i = 0; i < sz; i++)\r
1545       {\r
1546         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1547       }\r
1548     }\r
1549     else\r
1550     {\r
1551       Vector seqs = viewport.getAlignment().getSequences();\r
1552 \r
1553       if (seqs.size() > 1)\r
1554       {\r
1555         msa = new SequenceI[seqs.size()];\r
1556 \r
1557         for (int i = 0; i < seqs.size(); i++)\r
1558         {\r
1559           msa[i] = (SequenceI) seqs.elementAt(i);\r
1560         }\r
1561       }\r
1562     }\r
1563 \r
1564     if (msa != null)\r
1565     {\r
1566       MsaWSClient ct = new jalview.ws.MsaWSClient("MuscleWS", title, msa,\r
1567                                                   false, true);\r
1568     }\r
1569   }\r
1570 \r
1571   protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
1572   {\r
1573     // Pick the tree file\r
1574     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
1575         getProperty(\r
1576             "LAST_DIRECTORY"));\r
1577     chooser.setFileView(new JalviewFileView());\r
1578     chooser.setDialogTitle("Select a newick-like tree file");\r
1579     chooser.setToolTipText("Load a tree file");\r
1580 \r
1581     int value = chooser.showOpenDialog(null);\r
1582 \r
1583     if (value == JalviewFileChooser.APPROVE_OPTION)\r
1584     {\r
1585       String choice = chooser.getSelectedFile().getPath();\r
1586       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
1587 \r
1588       try\r
1589       {\r
1590         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,\r
1591             "File");\r
1592         viewport.setCurrentTree( ShowNewickTree(fin, choice).getTree() );\r
1593       }\r
1594       catch (Exception ex)\r
1595       {\r
1596         JOptionPane.showMessageDialog(Desktop.desktop,\r
1597                                       "Problem reading tree file",\r
1598                                       ex.getMessage(),\r
1599                                       JOptionPane.WARNING_MESSAGE);\r
1600         ex.printStackTrace();\r
1601       }\r
1602     }\r
1603   }\r
1604 \r
1605   public TreePanel ShowNewickTree(NewickFile nf, String title)\r
1606   {\r
1607     TreePanel tp = null;\r
1608     try\r
1609     {\r
1610       nf.parse();\r
1611       if (nf.getTree() != null)\r
1612       {\r
1613         tp = new TreePanel(viewport,\r
1614                                      viewport.getAlignment().getSequences(), nf,\r
1615                                      "FromFile",\r
1616                                      title);\r
1617         Desktop.addInternalFrame(tp, title, 600, 500);\r
1618         addTreeMenuItem(tp, title);\r
1619       }\r
1620     }\r
1621     catch (Exception ex)\r
1622     {\r
1623       ex.printStackTrace();\r
1624     }\r
1625     return tp;\r
1626   }\r
1627 \r
1628   class PrintThread\r
1629       extends Thread\r
1630   {\r
1631     public void run()\r
1632     {\r
1633       PrinterJob printJob = PrinterJob.getPrinterJob();\r
1634       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
1635       printJob.setPrintable(alignPanel, pf);\r
1636 \r
1637       if (printJob.printDialog())\r
1638       {\r
1639         try\r
1640         {\r
1641           printJob.print();\r
1642         }\r
1643         catch (Exception PrintException)\r
1644         {\r
1645           PrintException.printStackTrace();\r
1646         }\r
1647       }\r
1648     }\r
1649   }\r
1650 }\r