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