tidied up system.out messages and moved many to stderr.
[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.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       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
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.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());
403         viewport.setEndSeq(viewport.alignment.getHeight());
404         viewport.alignment.getWidth();
405         viewport.updateConservation();
406         viewport.updateConsensus();
407         alignPanel.repaint();
408       }
409
410     }catch(Exception ex){}// could be anything being pasted in here
411
412   }
413
414
415   protected void cut_actionPerformed(ActionEvent e)
416   {
417     copy_actionPerformed(null);
418     delete_actionPerformed(null);
419   }
420
421   protected void delete_actionPerformed(ActionEvent e)
422   {
423     boolean seqsdeleted=false;
424     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment, HistoryItem.HIDE));
425
426     if (viewport.getSelectionGroup() == null)
427       return;
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     abovePIDThreshold.setSelected(false);
741     changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(), viewport.alignment.getWidth()));
742   }
743
744   public void zappoColour_actionPerformed(ActionEvent e)
745   {
746     changeColour(new ZappoColourScheme());
747   }
748
749   public void taylorColour_actionPerformed(ActionEvent e)
750   {
751     changeColour(new TaylorColourScheme());
752   }
753
754
755   public void hydrophobicityColour_actionPerformed(ActionEvent e)
756   {
757     changeColour( new HydrophobicColourScheme() );
758   }
759
760   public void helixColour_actionPerformed(ActionEvent e)
761   {
762     changeColour(new HelixColourScheme() );
763   }
764
765
766   public void strandColour_actionPerformed(ActionEvent e)
767   {
768     changeColour(new StrandColourScheme());
769   }
770
771
772   public void turnColour_actionPerformed(ActionEvent e)
773   {
774     changeColour(new TurnColourScheme());
775   }
776
777
778   public void buriedColour_actionPerformed(ActionEvent e)
779   {
780     changeColour(new BuriedColourScheme() );
781   }
782
783   public void nucleotideColour_actionPerformed(ActionEvent e)
784   {
785     changeColour(new NucleotideColourScheme());
786   }
787
788
789   protected void applyToAllGroups_actionPerformed(ActionEvent e)
790   {
791     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());
792   }
793
794
795
796   void changeColour(ColourSchemeI cs)
797   {
798     int threshold = 0;
799
800     if ( viewport.getAbovePIDThreshold() )
801     {
802       threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");
803
804       if (cs instanceof ResidueColourScheme)
805         ( (ResidueColourScheme) cs).setThreshold(threshold);
806       else if (cs instanceof ScoreColourScheme)
807         ( (ScoreColourScheme) cs).setThreshold(threshold);
808
809       viewport.setGlobalColourScheme(cs);
810     }
811     else if (cs instanceof ResidueColourScheme)
812       ( (ResidueColourScheme) cs).setThreshold(0);
813     else if (cs instanceof ScoreColourScheme)
814       ( (ScoreColourScheme) cs).setThreshold(0);
815
816
817
818     if (viewport.getConservationSelected())
819     {
820       ConservationColourScheme ccs = null;
821
822       Alignment al = (Alignment) viewport.alignment;
823       Conservation c = new Conservation("All",
824                                         ResidueProperties.propHash, 3,
825                                         al.getSequences(), 0,
826                                         al.getWidth() - 1);
827
828       c.calculate();
829       c.verdict(false, viewport.ConsPercGaps);
830
831       ccs = new ConservationColourScheme(c, cs);
832
833       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!
834       ccs.setConsensus( viewport.vconsensus );
835       viewport.setGlobalColourScheme(ccs);
836
837       SliderPanel.setConservationSlider(alignPanel, ccs, "Background");
838
839     }
840     else
841     {
842         // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!
843         if (cs != null)
844           cs.setConsensus(viewport.vconsensus);
845         viewport.setGlobalColourScheme(cs);
846     }
847
848
849     if(viewport.getColourAppliesToAllGroups())
850     {
851       Vector groups = viewport.alignment.getGroups();
852       for(int i=0; i<groups.size(); i++)
853       {
854         SequenceGroup sg = (SequenceGroup)groups.elementAt(i);
855
856         if (cs instanceof ClustalxColourScheme)
857         {
858           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());
859         }
860         else if(cs!=null)
861         {
862           try{
863             sg.cs = (ColourSchemeI) cs.getClass().newInstance();
864           }catch(Exception ex){ex.printStackTrace();}
865         }
866
867         if(viewport.getAbovePIDThreshold())
868         {
869           if (sg.cs instanceof ResidueColourScheme)
870             ( (ResidueColourScheme) sg.cs).setThreshold(threshold);
871           else if (sg.cs instanceof ScoreColourScheme)
872             ( (ScoreColourScheme) sg.cs).setThreshold(threshold);
873
874            sg.cs.setConsensus( AAFrequency.calculate(sg.sequences, 0, sg.getWidth()) );
875         }
876
877         if( viewport.getConservationSelected() )
878         {
879           Conservation c = new Conservation("Group",
880                                             ResidueProperties.propHash, 3,
881                                             sg.sequences, 0, viewport.alignment.getWidth()-1);
882           c.calculate();
883           c.verdict(false, viewport.ConsPercGaps);
884           ConservationColourScheme ccs = new ConservationColourScheme(c, sg.cs);
885
886           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!
887           ccs.setConsensus( AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));
888           sg.cs = ccs;
889         }
890         else if(cs!=null)
891         {
892           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!
893           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));
894         }
895
896       }
897     }
898
899     if(alignPanel.getOverviewPanel()!=null)
900       alignPanel.getOverviewPanel().updateOverviewImage();
901     alignPanel.repaint();
902   }
903
904   protected void modifyPID_actionPerformed(ActionEvent e)
905   {
906       if(viewport.getAbovePIDThreshold())
907       {
908         SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),
909                                    "Background");
910         SliderPanel.showPIDSlider();
911       }
912   }
913
914   protected void modifyConservation_actionPerformed(ActionEvent e)
915   {
916     if(viewport.getConservationSelected())
917     {
918       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,
919                                         "Background");
920       SliderPanel.showConservationSlider();
921     }
922   }
923
924
925   protected  void conservationMenuItem_actionPerformed(ActionEvent e)
926   {
927     viewport.setConservationSelected(conservationMenuItem.isSelected());
928
929     viewport.setAbovePIDThreshold(false);
930     abovePIDThreshold.setSelected(false);
931
932    ColourSchemeI cs = viewport.getGlobalColourScheme();
933    if(cs instanceof ConservationColourScheme )
934      changeColour( ((ConservationColourScheme)cs).cs );
935     else
936       changeColour( cs );
937
938     modifyConservation_actionPerformed(null);
939   }
940
941   public void abovePIDThreshold_actionPerformed(ActionEvent e)
942   {
943     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());
944
945     conservationMenuItem.setSelected(false);
946     viewport.setConservationSelected(false);
947
948     ColourSchemeI cs = viewport.getGlobalColourScheme();
949
950     if(cs instanceof ConservationColourScheme )
951         changeColour( ((ConservationColourScheme)cs).cs );
952     else
953         changeColour( cs );
954
955     modifyPID_actionPerformed(null);
956   }
957
958
959
960   public void userDefinedColour_actionPerformed(ActionEvent e)
961   {
962     UserDefinedColours chooser = new UserDefinedColours( alignPanel, null);
963   }
964
965   public void PIDColour_actionPerformed(ActionEvent e)
966   {
967     changeColour( new PIDColourScheme() );
968   }
969
970
971   public void BLOSUM62Colour_actionPerformed(ActionEvent e)
972   {
973     changeColour(new Blosum62ColourScheme() );
974   }
975
976
977
978   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
979   {
980     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment, HistoryItem.SORT));
981     AlignmentSorter.sortByPID(viewport.getAlignment(), viewport.getAlignment().getSequenceAt(0));
982     alignPanel.repaint();
983   }
984
985   public void sortIDMenuItem_actionPerformed(ActionEvent e)
986   {
987     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment, HistoryItem.SORT));
988     AlignmentSorter.sortByID( viewport.getAlignment() );
989     alignPanel.repaint();
990   }
991
992   public void sortGroupMenuItem_actionPerformed(ActionEvent e)
993   {
994     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment, HistoryItem.SORT));
995     AlignmentSorter.sortByGroup(viewport.getAlignment());
996     AlignmentSorter.sortGroups(viewport.getAlignment());
997     alignPanel.repaint();
998   }
999
1000   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
1001   {
1002     RedundancyPanel sp = new RedundancyPanel(alignPanel);
1003     JInternalFrame frame = new JInternalFrame();
1004     frame.setContentPane(sp);
1005     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400, 100, false);
1006
1007   }
1008
1009   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
1010   {
1011     if(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 BLOSUM62PID");
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.",
1076                                     "Sequences not aligned", JOptionPane.WARNING_MESSAGE);
1077       return;
1078     }
1079
1080     final TreePanel tp;
1081     if (viewport.getSelectionGroup() != null &&
1082         viewport.getSelectionGroup().getSize() > 3)
1083     {
1084       tp = new TreePanel(viewport, viewport.getSelectionGroup().sequences, type,
1085                          pwType,
1086                          0, viewport.alignment.getWidth());
1087     }
1088     else
1089     {
1090       tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),
1091                          type, pwType, 0, viewport.alignment.getWidth());
1092     }
1093
1094    addTreeMenuItem(tp, title);
1095
1096    Desktop.addInternalFrame(tp, title, 600, 500);
1097   }
1098
1099   public void addSortByOrderMenuItem(String title, final AlignmentOrder order) {
1100     final JMenuItem item = new JMenuItem("by "+title);
1101     sort.add(item);
1102     item.addActionListener(new java.awt.event.ActionListener()
1103     {
1104       public void actionPerformed(ActionEvent e)
1105       {
1106         addHistoryItem(new HistoryItem("Sort", viewport.alignment,
1107                                        HistoryItem.SORT));
1108         // TODO: JBPNote - have to map order entries to curent SequenceI pointers
1109         AlignmentSorter.sortBy(viewport.getAlignment(), order);
1110         alignPanel.repaint();
1111       }
1112     });
1113   }
1114
1115   void addTreeMenuItem(final TreePanel treePanel, String title)
1116   {
1117     final JMenuItem item = new JMenuItem(title);
1118
1119     treeCount++;
1120
1121     if (treeCount==1)
1122       sort.add(sortByTreeMenu);
1123
1124     sortByTreeMenu.add(item);
1125     item.addActionListener(new java.awt.event.ActionListener()
1126     {
1127       public void actionPerformed(ActionEvent e)
1128       {
1129         addHistoryItem(new HistoryItem("Tree Sort", viewport.alignment,
1130                                        HistoryItem.SORT));
1131         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());
1132         alignPanel.repaint();
1133       }
1134     });
1135
1136     treePanel.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
1137     {
1138       public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt)
1139       {
1140         treeCount--;
1141         sortByTreeMenu.remove(item);
1142         if (treeCount==0)
1143           sort.remove(sortByTreeMenu);
1144       };
1145     });
1146     viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
1147       public void propertyChange(PropertyChangeEvent evt)
1148       {
1149         if (evt.getPropertyName().equals("alignment")) {
1150           treePanel.getTree().UpdatePlaceHolders( (Vector) evt.getNewValue());
1151           treePanel.repaint();
1152         }
1153       }
1154
1155     }
1156     );
1157   }
1158
1159
1160   public void clustalAlignMenuItem_actionPerformed(ActionEvent e)
1161   {
1162       // TODO:resolve which menu item was actually selected
1163       // Now, check we have enough sequences
1164         SequenceI[] msa=null;
1165         if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup().getSize()>1)
1166         {
1167           // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!
1168           SequenceGroup seqs = viewport.getSelectionGroup();
1169           int sz;
1170           msa = new SequenceI[sz=seqs.getSize()];
1171           for (int i = 0; i < sz; i++)
1172           {
1173             msa[i] = (SequenceI) seqs.getSequenceAt(i);
1174           }
1175
1176           }
1177         else
1178         {
1179           Vector seqs = viewport.getAlignment().getSequences();
1180
1181           if (seqs.size() > 1) {
1182             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           }
1189
1190         }
1191         if (msa!=null) {
1192           jalview.ws.MsaWSClient ct = new jalview.ws.MsaWSClient("ClustalWS", title, msa, true, true);
1193         }
1194   }
1195
1196   protected void jpred_actionPerformed(ActionEvent e)
1197 {
1198     SequenceI seq=null;
1199     SequenceI[] msa=null;
1200
1201     if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup().getSize()>0)
1202     {
1203       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!
1204       SequenceGroup seqs = viewport.getSelectionGroup();
1205       if (seqs.getSize() == 1 || !viewport.alignment.isAligned())
1206       {
1207         seq = (SequenceI)seqs.getSequenceAt(0);
1208       }
1209       else
1210       {
1211         int sz;
1212         msa = new SequenceI[sz=seqs.getSize()];
1213         for (int i = 0; i < sz; i++)
1214         {
1215           msa[i] = (SequenceI) seqs.getSequenceAt(i);
1216         }
1217       }
1218     }
1219     else
1220     {
1221       Vector seqs = viewport.getAlignment().getSequences();
1222
1223       if (seqs.size() == 1 || !viewport.alignment.isAligned())
1224       {
1225         seq = (SequenceI) seqs.elementAt(0);
1226       }
1227       else
1228       {
1229         msa = new SequenceI[seqs.size()];
1230         for (int i = 0; i < seqs.size(); i++)
1231         {
1232           msa[i] = (SequenceI) seqs.elementAt(i);
1233         }
1234       }
1235     }
1236     if (msa!=null) {
1237       JPredClient ct = new JPredClient(title, msa);
1238     } else
1239     if (seq!=null) {
1240       JPredClient ct = new JPredClient(title, seq);
1241     } else {
1242       System.err.print("JALVIEW ERROR! - Unexpected JPred selection state!\n");
1243     }
1244   }
1245   protected void msaAlignMenuItem_actionPerformed(ActionEvent e)
1246   {
1247     // TODO:resolve which menu item was actually selected
1248     // Now, check we have enough sequences
1249     SequenceI[] msa=null;
1250     if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup().getSize()>1)
1251       {
1252         // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!
1253         SequenceGroup seqs = viewport.getSelectionGroup();
1254         int sz;
1255         msa = new SequenceI[sz=seqs.getSize()];
1256         for (int i = 0; i < sz; i++)
1257         {
1258           msa[i] = (SequenceI) seqs.getSequenceAt(i);
1259         }
1260
1261
1262       }
1263       else
1264       {
1265         Vector seqs = viewport.getAlignment().getSequences();
1266
1267         if (seqs.size() > 1) {
1268           msa = new SequenceI[seqs.size()];
1269           for (int i = 0; i < seqs.size(); i++)
1270           {
1271             msa[i] = (SequenceI) seqs.elementAt(i);
1272           }
1273
1274         }
1275
1276       }
1277       if (msa!=null) {
1278         MsaWSClient ct = new jalview.ws.MsaWSClient("MuscleWS",title, msa, true, true);
1279       }
1280   }
1281     protected void LoadtreeMenuItem_actionPerformed(ActionEvent e) {
1282     // Pick the tree file
1283     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1284         getProperty("LAST_DIRECTORY"));
1285     chooser.setFileView(new JalviewFileView());
1286     chooser.setDialogTitle("Select a newick-like tree file");
1287     chooser.setToolTipText("Load a tree file");
1288     int value = chooser.showOpenDialog(null);
1289     if (value == JalviewFileChooser.APPROVE_OPTION)
1290     {
1291       String choice = chooser.getSelectedFile().getPath();
1292       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
1293       try
1294       {
1295         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice, "File");
1296         ShowNewickTree(fin, choice);
1297       }
1298       catch (Exception ex)
1299       {
1300         JOptionPane.showMessageDialog(Desktop.desktop,
1301                                       "Problem reading tree file",
1302                                       ex.getMessage(),
1303                                       JOptionPane.WARNING_MESSAGE);
1304         ex.printStackTrace();
1305       }
1306     }
1307   }
1308
1309   public void ShowNewickTree(NewickFile nf, String title)
1310   {
1311     try{
1312       nf.parse();
1313       if (nf.getTree() != null)
1314       {
1315         TreePanel tp = new TreePanel(viewport,
1316                                      viewport.getAlignment().getSequences(),
1317                                      nf, "FromFile", title);
1318         Desktop.addInternalFrame(tp, title, 600, 500);
1319         addTreeMenuItem(tp, title);
1320         viewport.setCurrentTree(tp.getTree());
1321       }
1322      }catch(Exception ex){ex.printStackTrace();}
1323   }
1324
1325 }