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