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