added tree as an applet to application servlet parameter
[jalview.git] / src / jalview / appletgui / AlignFrame.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19
20 package jalview.appletgui;
21
22 import java.io.*;
23 import java.net.*;
24 import java.util.*;
25
26 import java.awt.*;
27 import java.awt.event.*;
28
29 import jalview.analysis.*;
30 import jalview.commands.*;
31 import jalview.datamodel.*;
32 import jalview.io.*;
33 import jalview.schemes.*;
34
35 public class AlignFrame
36     extends Frame implements ActionListener,
37     ItemListener, KeyListener, MouseListener
38 {
39   public AlignmentPanel alignPanel;
40   public AlignViewport viewport;
41   int DEFAULT_WIDTH = 700;
42   int DEFAULT_HEIGHT = 500;
43
44   String jalviewServletURL;
45
46   public AlignFrame(AlignmentI al,
47                     jalview.bin.JalviewLite applet,
48                     String title,
49                     boolean embedded)
50   {
51
52     if (applet != null)
53     {
54       jalviewServletURL = applet.getParameter("APPLICATION_URL");
55     }
56
57     try
58     {
59       jbInit();
60     }
61     catch (Exception ex)
62     {
63       ex.printStackTrace();
64     }
65
66     viewport = new AlignViewport(al, applet);
67     alignPanel = new AlignmentPanel(this, viewport);
68
69     viewport.updateConservation(alignPanel);
70     viewport.updateConsensus(alignPanel);
71
72     annotationPanelMenuItem.setState(viewport.showAnnotation);
73
74     seqLimits.setState(viewport.showJVSuffix);
75
76     if (applet != null)
77     {
78       String param = applet.getParameter("sortBy");
79       if (param != null)
80       {
81         if (param.equalsIgnoreCase("Id"))
82         {
83           sortIDMenuItem_actionPerformed();
84         }
85         else if (param.equalsIgnoreCase("Pairwise Identity"))
86         {
87           sortPairwiseMenuItem_actionPerformed();
88         }
89       }
90
91       param = applet.getParameter("wrap");
92       if (param != null)
93       {
94         if (param.equalsIgnoreCase("true"))
95         {
96           wrapMenuItem.setState(true);
97           wrapMenuItem_actionPerformed();
98         }
99       }
100
101       try
102       {
103         param = applet.getParameter("windowWidth");
104         if (param != null)
105         {
106           int width = Integer.parseInt(param);
107           DEFAULT_WIDTH = width;
108         }
109         param = applet.getParameter("windowHeight");
110         if (param != null)
111         {
112           int height = Integer.parseInt(param);
113           DEFAULT_HEIGHT = height;
114         }
115       }
116       catch (Exception ex)
117       {}
118
119     }
120
121     //Some JVMS send keyevents to Top frame or lowest panel,
122     //Havent worked out why yet. So add to both this frame and seqCanvas for now
123     this.addKeyListener(this);
124     alignPanel.seqPanel.seqCanvas.addKeyListener(this);
125     alignPanel.idPanel.idCanvas.addKeyListener(this);
126     alignPanel.scalePanel.addKeyListener(this);
127     alignPanel.annotationPanel.addKeyListener(this);
128
129     if (embedded)
130     {
131       setEmbedded();
132     }
133     else
134     {
135       add(alignPanel, BorderLayout.CENTER);
136       jalview.bin.JalviewLite.addFrame(this, title, DEFAULT_WIDTH,
137                                        DEFAULT_HEIGHT);
138     }
139     alignPanel.validate();
140     alignPanel.paintAlignment(true);
141   }
142
143   public AlignViewport getAlignViewport()
144   {
145     return viewport;
146   }
147
148   public SeqCanvas getSeqcanvas()
149   {
150     return alignPanel.seqPanel.seqCanvas;
151   }
152
153   /**
154    * DOCUMENT ME!
155    *
156    * @param String DOCUMENT ME!
157    */
158
159   public void parseFeaturesFile(String file, String type)
160   {
161     Hashtable featureLinks = new Hashtable();
162     boolean featuresFile = false;
163     try
164     {
165       featuresFile = new jalview.io.FeaturesFile(file,
166           type).parse(viewport.alignment,
167                       alignPanel.seqPanel.seqCanvas.
168                       getFeatureRenderer().featureColours,
169                       featureLinks,
170                       true);
171     }
172     catch (Exception ex)
173     {
174       ex.printStackTrace();
175     }
176
177     if (featuresFile)
178     {
179       if (featureLinks.size() > 0)
180       {
181         alignPanel.seqPanel.seqCanvas
182             .getFeatureRenderer().featureLinks = featureLinks;
183       }
184       viewport.showSequenceFeatures = true;
185       sequenceFeatures.setState(true);
186       alignPanel.paintAlignment(true);
187     }
188
189   }
190
191   public void keyPressed(KeyEvent evt)
192   {
193     if (viewport.cursorMode &&
194         ( (evt.getKeyCode() >= KeyEvent.VK_0 &&
195            evt.getKeyCode() <= KeyEvent.VK_9)
196          ||
197          (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0 &&
198           evt.getKeyCode() <= KeyEvent.VK_NUMPAD9)
199         )
200         && Character.isDigit(evt.getKeyChar()))
201             alignPanel.seqPanel.numberPressed(evt.getKeyChar());
202
203
204     switch (evt.getKeyCode())
205     {
206       case 27: // escape key
207         deselectAllSequenceMenuItem_actionPerformed();
208         break;
209       case KeyEvent.VK_X:
210         if (evt.isControlDown() || evt.isMetaDown())
211         {
212           cut_actionPerformed();
213         }
214         break;
215       case KeyEvent.VK_C:
216         if (viewport.cursorMode && !evt.isControlDown())
217         {
218           alignPanel.seqPanel.setCursorColumn();
219         }
220         if (evt.isControlDown() || evt.isMetaDown())
221         {
222           copy_actionPerformed();
223         }
224         break;
225       case KeyEvent.VK_V:
226         if (evt.isControlDown())
227         {
228           paste(evt.isShiftDown());
229         }
230         break;
231       case KeyEvent.VK_A:
232         if (evt.isControlDown() || evt.isMetaDown())
233         {
234           selectAllSequenceMenuItem_actionPerformed();
235         }
236         break;
237       case KeyEvent.VK_DOWN:
238         if (viewport.cursorMode)
239         {
240           alignPanel.seqPanel.moveCursor(0, 1);
241         }
242         else
243         {
244           moveSelectedSequences(false);
245         }
246         break;
247
248       case KeyEvent.VK_UP:
249         if (viewport.cursorMode)
250         {
251           alignPanel.seqPanel.moveCursor(0, -1);
252         }
253         else
254         {
255           moveSelectedSequences(true);
256         }
257         break;
258
259       case KeyEvent.VK_LEFT:
260         if (evt.isAltDown() || !viewport.cursorMode)
261           slideSequences(false,
262                          alignPanel.seqPanel.getKeyboardNo1());
263         else
264           alignPanel.seqPanel.moveCursor( -1, 0);
265         break;
266
267       case KeyEvent.VK_RIGHT:
268         if (evt.isAltDown() || !viewport.cursorMode)
269           slideSequences(true,
270                          alignPanel.seqPanel.getKeyboardNo1());
271         else
272           alignPanel.seqPanel.moveCursor( 1, 0);
273             break;
274
275       case KeyEvent.VK_SPACE:
276         if (viewport.cursorMode)
277         {
278           alignPanel.seqPanel.insertGapAtCursor(evt.isControlDown()
279                                                 || evt.isShiftDown()
280                                                 || evt.isAltDown()
281               );
282         }
283         break;
284
285       case KeyEvent.VK_DELETE:
286       case KeyEvent.VK_BACK_SPACE:
287         if (viewport.cursorMode)
288         {
289           alignPanel.seqPanel.deleteGapAtCursor(evt.isControlDown()
290                                                 || evt.isShiftDown()
291                                                 || evt.isAltDown());
292         }
293         else
294         {
295           cut_actionPerformed();
296           alignPanel.seqPanel.seqCanvas.repaint();
297         }
298         break;
299
300       case KeyEvent.VK_S:
301         if (viewport.cursorMode)
302         {
303           alignPanel.seqPanel.setCursorRow();
304         }
305         break;
306       case KeyEvent.VK_P:
307         if (viewport.cursorMode)
308         {
309           alignPanel.seqPanel.setCursorPosition();
310         }
311         break;
312
313       case KeyEvent.VK_ENTER:
314       case KeyEvent.VK_COMMA:
315         if (viewport.cursorMode)
316         {
317           alignPanel.seqPanel.setCursorRowAndColumn();
318         }
319         break;
320
321       case KeyEvent.VK_Q:
322         if (viewport.cursorMode)
323         {
324           alignPanel.seqPanel.setSelectionAreaAtCursor(true);
325         }
326         break;
327       case KeyEvent.VK_M:
328         if (viewport.cursorMode)
329         {
330           alignPanel.seqPanel.setSelectionAreaAtCursor(false);
331         }
332         break;
333
334       case KeyEvent.VK_F2:
335         viewport.cursorMode = !viewport.cursorMode;
336         statusBar.setText("Keyboard editing mode is " +
337                           (viewport.cursorMode ? "on" : "off"));
338         if (viewport.cursorMode)
339         {
340           alignPanel.seqPanel.seqCanvas.cursorX = viewport.startRes;
341           alignPanel.seqPanel.seqCanvas.cursorY = viewport.startSeq;
342         }
343         break;
344
345       case KeyEvent.VK_F:
346         if (evt.isControlDown())
347         {
348           findMenuItem_actionPerformed();
349         }
350         break;
351
352       case KeyEvent.VK_H:
353       {
354         boolean toggleSeqs = !evt.isControlDown();
355         boolean toggleCols = !evt.isShiftDown();
356         boolean hide = false;
357         SequenceGroup sg = viewport.getSelectionGroup();
358
359         if (toggleSeqs)
360         {
361           if (sg != null && sg.getSize() != viewport.alignment.getHeight())
362           {
363             hide = true;
364             viewport.hideAllSelectedSeqs();
365           }
366           else if (! (toggleCols && viewport.colSel.getSelected().size() > 0))
367           {
368             viewport.showAllHiddenSeqs();
369           }
370         }
371
372         if (toggleCols)
373         {
374           if (viewport.colSel.getSelected().size() > 0)
375           {
376             viewport.hideSelectedColumns();
377             if (!toggleSeqs)
378             {
379               viewport.selectionGroup = sg;
380             }
381           }
382           else if (!hide)
383           {
384             viewport.showAllHiddenColumns();
385           }
386         }
387         break;
388       }
389
390       case KeyEvent.VK_PAGE_UP:
391         if (viewport.wrapAlignment)
392         {
393           alignPanel.scrollUp(true);
394         }
395         else
396         {
397           alignPanel.setScrollValues(viewport.startRes,
398                                      viewport.startSeq
399                                      - viewport.endSeq + viewport.startSeq);
400         }
401         break;
402
403       case KeyEvent.VK_PAGE_DOWN:
404         if (viewport.wrapAlignment)
405         {
406           alignPanel.scrollUp(false);
407         }
408         else
409         {
410           alignPanel.setScrollValues(viewport.startRes,
411                                      viewport.startSeq
412                                      + viewport.endSeq - viewport.startSeq);
413         }
414         break;
415
416       case KeyEvent.VK_Z:
417         if (evt.isControlDown())
418         {
419           undoMenuItem_actionPerformed();
420         }
421         break;
422
423       case KeyEvent.VK_Y:
424         if (evt.isControlDown())
425         {
426           redoMenuItem_actionPerformed();
427         }
428         break;
429
430       case KeyEvent.VK_L:
431         if (evt.isControlDown())
432         {
433           trimAlignment(true);
434         }
435         break;
436
437       case KeyEvent.VK_R:
438         if (evt.isControlDown())
439         {
440           trimAlignment(false);
441         }
442         break;
443
444       case KeyEvent.VK_E:
445         if (evt.isControlDown())
446         {
447           if (evt.isShiftDown())
448           {
449             this.removeAllGapsMenuItem_actionPerformed();
450           }
451           else
452           {
453             removeGappedColumnMenuItem_actionPerformed();
454           }
455         }
456         break;
457       case KeyEvent.VK_I:
458         if (evt.isControlDown())
459         {
460           if (evt.isAltDown())
461           {
462             viewport.invertColumnSelection();
463           }
464           else
465           {
466             this.invertSequenceMenuItem_actionPerformed();
467           }
468         }
469         break;
470
471       case KeyEvent.VK_U:
472         if (evt.isControlDown())
473         {
474           this.deleteGroups_actionPerformed();
475         }
476         break;
477
478       case KeyEvent.VK_T:
479         if (evt.isControlDown())
480         {
481           newView();
482         }
483         break;
484
485     }
486     alignPanel.paintAlignment(true);
487   }
488
489   public void keyReleased(KeyEvent evt)
490   {}
491
492   public void keyTyped(KeyEvent evt)
493   {}
494
495   public void itemStateChanged(ItemEvent evt)
496   {
497     if (evt.getSource() == colourTextMenuItem)
498     {
499       colourTextMenuItem_actionPerformed();
500     }
501     else if (evt.getSource() == wrapMenuItem)
502     {
503       wrapMenuItem_actionPerformed();
504     }
505     else if (evt.getSource() == scaleAbove)
506     {
507       viewport.setScaleAboveWrapped(scaleAbove.getState());
508     }
509     else if (evt.getSource() == scaleLeft)
510     {
511       viewport.setScaleLeftWrapped(scaleLeft.getState());
512     }
513     else if (evt.getSource() == scaleRight)
514     {
515       viewport.setScaleRightWrapped(scaleRight.getState());
516     }
517     else if (evt.getSource() == seqLimits)
518     {
519       seqLimits_itemStateChanged();
520     }
521     else if (evt.getSource() == viewBoxesMenuItem)
522     {
523       viewport.setShowBoxes(viewBoxesMenuItem.getState());
524     }
525     else if (evt.getSource() == viewTextMenuItem)
526     {
527       viewport.setShowText(viewTextMenuItem.getState());
528     }
529     else if (evt.getSource() == renderGapsMenuItem)
530     {
531       viewport.setRenderGaps(renderGapsMenuItem.getState());
532     }
533     else if (evt.getSource() == annotationPanelMenuItem)
534     {
535       viewport.setShowAnnotation(annotationPanelMenuItem.getState());
536       alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState());
537     }
538     else if (evt.getSource() == sequenceFeatures)
539     {
540       viewport.showSequenceFeatures(sequenceFeatures.getState());
541       alignPanel.seqPanel.seqCanvas.repaint();
542     }
543     else if (evt.getSource() == conservationMenuItem)
544     {
545       conservationMenuItem_actionPerformed();
546     }
547     else if (evt.getSource() == abovePIDThreshold)
548     {
549       abovePIDThreshold_actionPerformed();
550     }
551     else if (evt.getSource() == applyToAllGroups)
552     {
553       viewport.setColourAppliesToAllGroups(applyToAllGroups.getState());
554     }
555     else if (evt.getSource() == autoCalculate)
556     {
557       viewport.autocalculateConsensus = autoCalculate.getState();
558     }
559
560     alignPanel.paintAlignment(true);
561   }
562
563   public void actionPerformed(ActionEvent evt)
564   {
565     Object source = evt.getSource();
566
567     if (source == inputText)
568     {
569       inputText_actionPerformed();
570     }
571     else if (source == loadTree)
572     {
573       loadTree_actionPerformed();
574     }
575     else if (source == loadApplication)
576     {
577       launchFullApplication();
578     }
579     else if (source == loadAnnotations)
580     {
581       loadAnnotations();
582     }
583     else if (source == outputAnnotations)
584     {
585       outputAnnotations(true);
586     }
587     else if (source == outputFeatures)
588     {
589       outputFeatures(true, "Jalview");
590     }
591     else if (source == closeMenuItem)
592     {
593       closeMenuItem_actionPerformed();
594     }
595     else if (source == copy)
596     {
597       copy_actionPerformed();
598     }
599     else if (source == undoMenuItem)
600     {
601       undoMenuItem_actionPerformed();
602     }
603     else if (source == redoMenuItem)
604     {
605       redoMenuItem_actionPerformed();
606     }
607     else if (source == inputText)
608     {
609       inputText_actionPerformed();
610     }
611     else if (source == closeMenuItem)
612     {
613       closeMenuItem_actionPerformed();
614     }
615     else if (source == undoMenuItem)
616     {
617       undoMenuItem_actionPerformed();
618     }
619     else if (source == redoMenuItem)
620     {
621       redoMenuItem_actionPerformed();
622     }
623     else if (source == copy)
624     {
625       copy_actionPerformed();
626     }
627     else if (source == pasteNew)
628     {
629       pasteNew_actionPerformed();
630     }
631     else if (source == pasteThis)
632     {
633       pasteThis_actionPerformed();
634     }
635     else if (source == cut)
636     {
637       cut_actionPerformed();
638     }
639     else if (source == delete)
640     {
641       delete_actionPerformed();
642     }
643     else if (source == deleteGroups)
644     {
645       deleteGroups_actionPerformed();
646     }
647     else if (source == selectAllSequenceMenuItem)
648     {
649       selectAllSequenceMenuItem_actionPerformed();
650     }
651     else if (source == deselectAllSequenceMenuItem)
652     {
653       deselectAllSequenceMenuItem_actionPerformed();
654     }
655     else if (source == invertSequenceMenuItem)
656     {
657       invertSequenceMenuItem_actionPerformed();
658     }
659     else if (source == invertColSel)
660     {
661       viewport.invertColumnSelection();
662       alignPanel.paintAlignment(true);
663     }
664     else if (source == remove2LeftMenuItem)
665     {
666       trimAlignment(true);
667     }
668     else if (source == remove2RightMenuItem)
669     {
670       trimAlignment(false);
671     }
672     else if (source == removeGappedColumnMenuItem)
673     {
674       removeGappedColumnMenuItem_actionPerformed();
675     }
676     else if (source == removeAllGapsMenuItem)
677     {
678       removeAllGapsMenuItem_actionPerformed();
679     }
680     else if (source == findMenuItem)
681     {
682       findMenuItem_actionPerformed();
683     }
684     else if (source == font)
685     {
686       new FontChooser(alignPanel);
687     }
688     else if (source == newView)
689     {
690       newView();
691     }
692     else if (source == showColumns)
693     {
694       viewport.showAllHiddenColumns();
695       alignPanel.paintAlignment(true);
696     }
697     else if (source == showSeqs)
698     {
699       viewport.showAllHiddenSeqs();
700     }
701     else if (source == hideColumns)
702     {
703       viewport.hideSelectedColumns();
704       alignPanel.paintAlignment(true);
705     }
706     else if (source == hideSequences && viewport.getSelectionGroup() != null)
707     {
708       viewport.hideAllSelectedSeqs();
709     }
710     else if (source == featureSettings)
711     {
712       new FeatureSettings(alignPanel);
713     }
714     else if(source== alProperties)
715     {
716         StringBuffer contents = new StringBuffer();
717
718         float avg  = 0;
719         int min=Integer.MAX_VALUE, max=0;
720         for(int i=0; i<viewport.alignment.getHeight(); i++)
721         {
722           int size = viewport.alignment.getSequenceAt(i).getEnd()
723               -viewport.alignment.getSequenceAt(i).getStart();
724           avg += size;
725           if(size>max)
726             max = size;
727           if(size<min)
728             min = size;
729         }
730         avg = avg/(float)viewport.alignment.getHeight();
731
732         contents.append("\nSequences: "+ viewport.alignment.getHeight());
733         contents.append("\nMinimum Sequence Length: "+min);
734         contents.append("\nMaximum Sequence Length: "+max);
735         contents.append("\nAverage Length: "+(int)avg);
736
737         if (((Alignment)viewport.alignment).alignmentProperties != null)
738         {
739           Hashtable props = ((Alignment)viewport.alignment).alignmentProperties;
740           Enumeration en = props.keys();
741           while(en.hasMoreElements())
742           {
743             String key = en.nextElement().toString();
744             contents.append("\n"+key+"\t"+props.get(key));
745           }
746         }
747
748         CutAndPasteTransfer cap = new CutAndPasteTransfer(false, this);
749         cap.setText(contents.toString());
750         Frame frame = new Frame();
751         frame.add(cap);
752         jalview.bin.JalviewLite.addFrame(frame,
753                                          "Alignment Properties: "+getTitle()
754                                          , 400, 250);
755     }
756     else if (source == overviewMenuItem)
757     {
758       overviewMenuItem_actionPerformed();
759     }
760     else if (source == noColourmenuItem)
761     {
762       changeColour(null);
763     }
764     else if (source == clustalColour)
765     {
766       abovePIDThreshold.setState(false);
767       changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(),
768                                             viewport.alignment.getWidth()));
769     }
770     else if (source == zappoColour)
771     {
772       changeColour(new ZappoColourScheme());
773     }
774     else if (source == taylorColour)
775     {
776       changeColour(new TaylorColourScheme());
777     }
778     else if (source == hydrophobicityColour)
779     {
780       changeColour(new HydrophobicColourScheme());
781     }
782     else if (source == helixColour)
783     {
784       changeColour(new HelixColourScheme());
785     }
786     else if (source == strandColour)
787     {
788       changeColour(new StrandColourScheme());
789     }
790     else if (source == turnColour)
791     {
792       changeColour(new TurnColourScheme());
793     }
794     else if (source == buriedColour)
795     {
796       changeColour(new BuriedColourScheme());
797     }
798     else if (source == nucleotideColour)
799     {
800       changeColour(new NucleotideColourScheme());
801     }
802     else if (source == modifyPID)
803     {
804       modifyPID_actionPerformed();
805     }
806     else if (source == modifyConservation)
807     {
808       modifyConservation_actionPerformed();
809     }
810     else if (source == userDefinedColour)
811     {
812       new UserDefinedColours(alignPanel, null);
813     }
814     else if (source == PIDColour)
815     {
816       changeColour(new PIDColourScheme());
817     }
818     else if (source == BLOSUM62Colour)
819     {
820       changeColour(new Blosum62ColourScheme());
821     }
822     else if (source == annotationColour)
823     {
824       new AnnotationColourChooser(viewport, alignPanel);
825     }
826     else if (source == sortPairwiseMenuItem)
827     {
828       sortPairwiseMenuItem_actionPerformed();
829     }
830     else if (source == sortIDMenuItem)
831     {
832       sortIDMenuItem_actionPerformed();
833     }
834     else if (source == sortGroupMenuItem)
835     {
836       sortGroupMenuItem_actionPerformed();
837     }
838     else if (source == removeRedundancyMenuItem)
839     {
840       removeRedundancyMenuItem_actionPerformed();
841     }
842     else if (source == pairwiseAlignmentMenuItem)
843     {
844       pairwiseAlignmentMenuItem_actionPerformed();
845     }
846     else if (source == PCAMenuItem)
847     {
848       PCAMenuItem_actionPerformed();
849     }
850     else if (source == averageDistanceTreeMenuItem)
851     {
852       averageDistanceTreeMenuItem_actionPerformed();
853     }
854     else if (source == neighbourTreeMenuItem)
855     {
856       neighbourTreeMenuItem_actionPerformed();
857     }
858     else if (source == njTreeBlosumMenuItem)
859     {
860       njTreeBlosumMenuItem_actionPerformed();
861     }
862     else if (source == avDistanceTreeBlosumMenuItem)
863     {
864       avTreeBlosumMenuItem_actionPerformed();
865     }
866     else if (source == documentation)
867     {
868       documentation_actionPerformed();
869     }
870     else if (source == about)
871     {
872       about_actionPerformed();
873     }
874
875   }
876
877   public void inputText_actionPerformed()
878   {
879     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
880     Frame frame = new Frame();
881     frame.add(cap);
882     jalview.bin.JalviewLite.addFrame(frame, "Cut & Paste Input", 500, 500);
883   }
884
885   protected void outputText_actionPerformed(ActionEvent e)
886   {
887     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
888     Frame frame = new Frame();
889     frame.add(cap);
890     jalview.bin.JalviewLite.addFrame(frame,
891                                      "Alignment output - " + e.getActionCommand(),
892                                      600, 500);
893     cap.setText(new AppletFormatAdapter().formatSequences(e.getActionCommand(),
894         viewport.getAlignment(),
895         viewport.showJVSuffix));
896   }
897
898   public void loadAnnotations()
899   {
900     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
901     cap.setText("Paste your features / annotations file here.");
902     cap.setAnnotationImport();
903     Frame frame = new Frame();
904     frame.add(cap);
905     jalview.bin.JalviewLite.addFrame(frame, "Paste Annotations ", 400, 300);
906
907   }
908
909   public String outputAnnotations(boolean displayTextbox)
910   {
911     String annotation = new AnnotationFile().printAnnotations(
912         viewport.showAnnotation ? viewport.alignment.getAlignmentAnnotation() : null,
913         viewport.alignment.getGroups(),
914          ((Alignment) viewport.alignment).alignmentProperties);
915
916     if (displayTextbox)
917     {
918       CutAndPasteTransfer cap = new CutAndPasteTransfer(false, this);
919       Frame frame = new Frame();
920       frame.add(cap);
921       jalview.bin.JalviewLite.addFrame(frame,
922                                        "Annotations",
923                                        600, 500);
924       cap.setText(annotation);
925     }
926
927     return annotation;
928   }
929
930   public String outputFeatures(boolean displayTextbox, String format)
931   {
932     String features;
933     if (format.equalsIgnoreCase("Jalview"))
934     {
935       features = new FeaturesFile().printJalviewFormat(
936           viewport.alignment.getSequencesArray(),
937           viewport.featuresDisplayed);
938     }
939     else
940     {
941       features = new FeaturesFile().printGFFFormat(
942           viewport.alignment.getSequencesArray(),
943           viewport.featuresDisplayed);
944     }
945
946     if (displayTextbox)
947     {
948       CutAndPasteTransfer cap = new CutAndPasteTransfer(false, this);
949       Frame frame = new Frame();
950       frame.add(cap);
951       jalview.bin.JalviewLite.addFrame(frame,
952                                        "Features",
953                                        600, 500);
954
955       cap.setText(features);
956     }
957
958     return features;
959   }
960
961   void launchFullApplication()
962   {
963     StringBuffer url = new StringBuffer(jalviewServletURL);
964
965     url.append("?open=" +
966                appendProtocol(viewport.applet.getParameter("file")));
967
968     if (viewport.applet.getParameter("features") != null)
969     {
970       url.append("&features=");
971       url.append(appendProtocol(viewport.applet.getParameter("features")));
972     }
973
974     if (viewport.applet.getParameter("annotations") != null)
975     {
976       url.append("&annotations=");
977       url.append(appendProtocol(viewport.applet.getParameter("annotations")));
978     }
979
980     if (viewport.applet.getParameter("jnetfile") != null)
981     {
982       url.append("&annotations=");
983       url.append(appendProtocol(viewport.applet.getParameter("jnetfile")));
984     }
985
986     if (viewport.applet.getParameter("defaultColour") != null)
987     {
988       url.append("&colour=" +
989                  removeWhiteSpace(viewport.applet.getParameter("defaultColour"))
990           );
991     }
992
993     if (viewport.applet.getParameter("userDefinedColour") != null)
994     {
995       url.append("&colour=" +
996                  removeWhiteSpace(viewport.applet.getParameter(
997           "userDefinedColour"))
998           );
999     }
1000     if (viewport.applet.getParameter("tree")!=null)
1001     {
1002       url.append("&tree="+appendProtocol(viewport.applet.getParameter("tree")));
1003     }
1004     if (viewport.applet.getParameter("treeFile")!=null)
1005     {
1006       url.append("&tree="+appendProtocol(viewport.applet.getParameter("treeFile")));
1007     }
1008
1009     showURL(url.toString(), "FULL_APP");
1010   }
1011
1012   String removeWhiteSpace(String colour)
1013   {
1014     StringBuffer sb = new StringBuffer();
1015     for (int i = 0; i < colour.length(); i++)
1016     {
1017       if (Character.isWhitespace(colour.charAt(i)))
1018       {
1019         sb.append("%20");
1020       }
1021       else
1022       {
1023         sb.append(colour.charAt(i));
1024       }
1025     }
1026
1027     return sb.toString();
1028   }
1029
1030   String appendProtocol(String url)
1031   {
1032     try
1033     {
1034       new URL(url);
1035     }
1036     catch (java.net.MalformedURLException ex)
1037     {
1038       url = viewport.applet.getCodeBase() + url;
1039     }
1040     return url;
1041   }
1042
1043   public void closeMenuItem_actionPerformed()
1044   {
1045     PaintRefresher.RemoveComponent(alignPanel);
1046     PaintRefresher.RemoveComponent(alignPanel.seqPanel.seqCanvas);
1047     PaintRefresher.RemoveComponent(alignPanel.idPanel.idCanvas);
1048
1049     if (PaintRefresher.components.size() == 0 && viewport.applet == null)
1050     {
1051       System.exit(0);
1052     }
1053
1054     this.dispose();
1055   }
1056
1057   /**
1058    * DOCUMENT ME!
1059    */
1060   void updateEditMenuBar()
1061   {
1062
1063     if (viewport.historyList.size() > 0)
1064     {
1065       undoMenuItem.setEnabled(true);
1066       CommandI command = (CommandI) viewport.historyList.peek();
1067       undoMenuItem.setLabel("Undo " + command.getDescription());
1068     }
1069     else
1070     {
1071       undoMenuItem.setEnabled(false);
1072       undoMenuItem.setLabel("Undo");
1073     }
1074
1075     if (viewport.redoList.size() > 0)
1076     {
1077       redoMenuItem.setEnabled(true);
1078
1079       CommandI command = (CommandI) viewport.redoList.peek();
1080       redoMenuItem.setLabel("Redo " + command.getDescription());
1081     }
1082     else
1083     {
1084       redoMenuItem.setEnabled(false);
1085       redoMenuItem.setLabel("Redo");
1086     }
1087   }
1088
1089   public void addHistoryItem(CommandI command)
1090   {
1091     if (command.getSize() > 0)
1092     {
1093       viewport.historyList.push(command);
1094       viewport.redoList.removeAllElements();
1095       updateEditMenuBar();
1096       viewport.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1097     }
1098   }
1099   /**
1100    * DOCUMENT ME!
1101    *
1102    * @param e DOCUMENT ME!
1103    */
1104   protected void undoMenuItem_actionPerformed()
1105   {
1106     if (viewport.historyList.size() < 1)
1107     {
1108       return;
1109     }
1110
1111     CommandI command = (CommandI) viewport.historyList.pop();
1112     viewport.redoList.push(command);
1113     command.undoCommand(null);
1114
1115     AlignViewport originalSource = getOriginatingSource(command);
1116
1117     originalSource.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1118     updateEditMenuBar();
1119     originalSource.firePropertyChange("alignment", null,
1120                                       originalSource.alignment.getSequences());
1121   }
1122
1123   /**
1124    * DOCUMENT ME!
1125    *
1126    * @param e DOCUMENT ME!
1127    */
1128   protected void redoMenuItem_actionPerformed()
1129   {
1130     if (viewport.redoList.size() < 1)
1131     {
1132       return;
1133     }
1134
1135     CommandI command = (CommandI) viewport.redoList.pop();
1136     viewport.historyList.push(command);
1137     command.doCommand(null);
1138
1139     AlignViewport originalSource = getOriginatingSource(command);
1140     originalSource.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1141
1142     updateEditMenuBar();
1143     originalSource.firePropertyChange("alignment", null,
1144                                       originalSource.alignment.getSequences());
1145   }
1146
1147   AlignViewport getOriginatingSource(CommandI command)
1148   {
1149     AlignViewport originalSource = null;
1150     //For sequence removal and addition, we need to fire
1151     //the property change event FROM the viewport where the
1152     //original alignment was altered
1153     AlignmentI al = null;
1154     if (command instanceof EditCommand)
1155     {
1156       EditCommand editCommand = (EditCommand) command;
1157       al = editCommand.getAlignment();
1158       Vector comps = (Vector) PaintRefresher.components
1159           .get(viewport.getSequenceSetId());
1160       for (int i = 0; i < comps.size(); i++)
1161       {
1162         if (comps.elementAt(i) instanceof AlignmentPanel)
1163         {
1164           if (al == ( (AlignmentPanel) comps.elementAt(i)).av.alignment)
1165           {
1166             originalSource = ( (AlignmentPanel) comps.elementAt(i)).av;
1167             break;
1168           }
1169         }
1170       }
1171     }
1172
1173     if (originalSource == null)
1174     {
1175       //The original view is closed, we must validate
1176       //the current view against the closed view first
1177       if (al != null)
1178       {
1179         PaintRefresher.validateSequences(al, viewport.alignment);
1180       }
1181
1182       originalSource = viewport;
1183     }
1184
1185     return originalSource;
1186   }
1187
1188   public void moveSelectedSequences(boolean up)
1189   {
1190     SequenceGroup sg = viewport.getSelectionGroup();
1191     if (sg == null)
1192     {
1193       return;
1194     }
1195
1196     if (up)
1197     {
1198       for (int i = 1; i < viewport.alignment.getHeight(); i++)
1199       {
1200         SequenceI seq = viewport.alignment.getSequenceAt(i);
1201         if (!sg.getSequences(null).contains(seq))
1202         {
1203           continue;
1204         }
1205
1206         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);
1207         if (sg.getSequences(null).contains(temp))
1208         {
1209           continue;
1210         }
1211
1212         viewport.alignment.getSequences().setElementAt(temp, i);
1213         viewport.alignment.getSequences().setElementAt(seq, i - 1);
1214       }
1215     }
1216     else
1217     {
1218       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)
1219       {
1220         SequenceI seq = viewport.alignment.getSequenceAt(i);
1221         if (!sg.getSequences(viewport.hiddenRepSequences).contains(seq))
1222         {
1223           continue;
1224         }
1225
1226         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);
1227         if (sg.getSequences(viewport.hiddenRepSequences).contains(temp))
1228         {
1229           continue;
1230         }
1231
1232         viewport.alignment.getSequences().setElementAt(temp, i);
1233         viewport.alignment.getSequences().setElementAt(seq, i + 1);
1234       }
1235     }
1236
1237     alignPanel.paintAlignment(true);
1238   }
1239
1240   synchronized void slideSequences(boolean right, int size)
1241   {
1242     Vector sg = new Vector();
1243     if(viewport.cursorMode)
1244     {
1245       sg.addElement(viewport.alignment.getSequenceAt(
1246           alignPanel.seqPanel.seqCanvas.cursorY));
1247     }
1248     else if(viewport.getSelectionGroup()!=null
1249         && viewport.getSelectionGroup().getSize()!=viewport.alignment.getHeight())
1250    {
1251      sg = viewport.getSelectionGroup().getSequences(
1252          viewport.hiddenRepSequences);
1253    }
1254
1255     if(sg.size()<1)
1256     {
1257       return;
1258     }
1259
1260     Vector invertGroup = new Vector();
1261
1262     for (int i = 0; i < viewport.alignment.getHeight(); i++)
1263     {
1264       if(!sg.contains(viewport.alignment.getSequenceAt(i)))
1265          invertGroup.addElement(viewport.alignment.getSequenceAt(i));
1266     }
1267
1268     SequenceI[] seqs1 = new SequenceI[sg.size()];
1269     for (int i = 0; i < sg.size(); i++)
1270       seqs1[i] = (SequenceI) sg.elementAt(i);
1271
1272     SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1273     for (int i = 0; i < invertGroup.size(); i++)
1274       seqs2[i] = (SequenceI) invertGroup.elementAt(i);
1275
1276     SlideSequencesCommand ssc;
1277     if (right)
1278       ssc = new SlideSequencesCommand("Slide Sequences",
1279                                       seqs2, seqs1, size,
1280                                       viewport.getGapCharacter()
1281           );
1282     else
1283       ssc = new SlideSequencesCommand("Slide Sequences",
1284                                       seqs1, seqs2, size,
1285                                       viewport.getGapCharacter()
1286           );
1287
1288     int groupAdjustment = 0;
1289     if (ssc.getGapsInsertedBegin() && right)
1290     {
1291       if (viewport.cursorMode)
1292         alignPanel.seqPanel.moveCursor(size, 0);
1293       else
1294         groupAdjustment = size;
1295     }
1296     else if (!ssc.getGapsInsertedBegin() && !right)
1297     {
1298       if (viewport.cursorMode)
1299         alignPanel.seqPanel.moveCursor( -size, 0);
1300       else
1301         groupAdjustment = -size;
1302     }
1303
1304     if (groupAdjustment != 0)
1305     {
1306       viewport.getSelectionGroup().setStartRes(
1307           viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1308       viewport.getSelectionGroup().setEndRes(
1309           viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1310     }
1311
1312
1313     boolean appendHistoryItem = false;
1314     if(viewport.historyList!=null
1315        && viewport.historyList.size()>0
1316       && viewport.historyList.peek() instanceof SlideSequencesCommand)
1317     {
1318       appendHistoryItem = ssc.appendSlideCommand(
1319           (SlideSequencesCommand)viewport.historyList.peek())
1320           ;
1321     }
1322
1323     if(!appendHistoryItem)
1324       addHistoryItem(ssc);
1325
1326     repaint();
1327   }
1328
1329   static StringBuffer copiedSequences;
1330   static Vector copiedHiddenColumns;
1331   protected void copy_actionPerformed()
1332   {
1333     if (viewport.getSelectionGroup() == null)
1334     {
1335       return;
1336     }
1337
1338     SequenceGroup sg = viewport.getSelectionGroup();
1339     copiedSequences = new StringBuffer();
1340     Hashtable orderedSeqs = new Hashtable();
1341     for (int i = 0; i < sg.getSize(); i++)
1342     {
1343       SequenceI seq = sg.getSequenceAt(i);
1344       int index = viewport.alignment.findIndex(seq);
1345       orderedSeqs.put(index + "", seq);
1346     }
1347
1348     int index = 0, startRes, endRes;
1349     char ch;
1350
1351     if (viewport.hasHiddenColumns && viewport.getSelectionGroup() != null)
1352     {
1353       copiedHiddenColumns = new Vector();
1354       int hiddenOffset = viewport.getSelectionGroup().getStartRes();
1355       for (int i = 0; i < viewport.getColumnSelection().getHiddenColumns().size();
1356            i++)
1357       {
1358         int[] region = (int[])
1359             viewport.getColumnSelection().getHiddenColumns().elementAt(i);
1360
1361         copiedHiddenColumns.addElement(new int[]
1362                                        {region[0] - hiddenOffset,
1363                                        region[1] - hiddenOffset});
1364       }
1365     }
1366     else
1367     {
1368       copiedHiddenColumns = null;
1369     }
1370
1371     for (int i = 0; i < sg.getSize(); i++)
1372     {
1373       SequenceI seq = null;
1374
1375       while (seq == null)
1376       {
1377         if (orderedSeqs.containsKey(index + ""))
1378         {
1379           seq = (SequenceI) orderedSeqs.get(index + "");
1380           index++;
1381
1382           break;
1383         }
1384         else
1385         {
1386           index++;
1387         }
1388       }
1389
1390       //FIND START RES
1391       //Returns residue following index if gap
1392       startRes = seq.findPosition(sg.getStartRes());
1393
1394       //FIND END RES
1395       //Need to find the residue preceeding index if gap
1396       endRes = 0;
1397
1398       for (int j = 0; j < sg.getEndRes() + 1 && j < seq.getLength(); j++)
1399       {
1400         ch = seq.getCharAt(j);
1401         if (!jalview.util.Comparison.isGap( (ch)))
1402         {
1403           endRes++;
1404         }
1405       }
1406
1407       if (endRes > 0)
1408       {
1409         endRes += seq.getStart() - 1;
1410       }
1411
1412       copiedSequences.append(seq.getName() + "\t" +
1413                              startRes + "\t" +
1414                              endRes + "\t" +
1415                              seq.getSequenceAsString(sg.getStartRes(),
1416           sg.getEndRes() + 1) + "\n");
1417     }
1418
1419   }
1420
1421   protected void pasteNew_actionPerformed()
1422   {
1423     paste(true);
1424   }
1425
1426   protected void pasteThis_actionPerformed()
1427   {
1428     paste(false);
1429   }
1430
1431   void paste(boolean newAlignment)
1432   {
1433     try
1434     {
1435
1436       if (copiedSequences == null)
1437       {
1438         return;
1439       }
1440
1441       StringTokenizer st = new StringTokenizer(copiedSequences.toString());
1442       Vector seqs = new Vector();
1443       while (st.hasMoreElements())
1444       {
1445         String name = st.nextToken();
1446         int start = Integer.parseInt(st.nextToken());
1447         int end = Integer.parseInt(st.nextToken());
1448         seqs.addElement(new Sequence(name, st.nextToken(), start, end));
1449       }
1450       SequenceI[] newSeqs = new SequenceI[seqs.size()];
1451       for (int i = 0; i < seqs.size(); i++)
1452       {
1453         newSeqs[i] = (SequenceI) seqs.elementAt(i);
1454       }
1455
1456       if (newAlignment)
1457       {
1458         String newtitle = new String("Copied sequences");
1459         if (getTitle().startsWith("Copied sequences"))
1460         {
1461           newtitle = getTitle();
1462         }
1463         else
1464         {
1465           newtitle = newtitle.concat("- from " + getTitle());
1466         }
1467         AlignFrame af = new AlignFrame(new Alignment(newSeqs),
1468                                        viewport.applet,
1469                                        newtitle,
1470                                        false);
1471         if (copiedHiddenColumns != null)
1472         {
1473           for (int i = 0; i < copiedHiddenColumns.size(); i++)
1474           {
1475             int[] region = (int[]) copiedHiddenColumns.elementAt(i);
1476             af.viewport.hideColumns(region[0], region[1]);
1477           }
1478         }
1479
1480         jalview.bin.JalviewLite.addFrame(af, newtitle, DEFAULT_WIDTH,
1481                                          DEFAULT_HEIGHT);
1482       }
1483       else
1484       {
1485         addSequences(newSeqs);
1486       }
1487
1488     }
1489     catch (Exception ex)
1490     {} // could be anything being pasted in here
1491
1492   }
1493
1494   void addSequences(SequenceI[] seqs)
1495   {
1496     for (int i = 0; i < seqs.length; i++)
1497     {
1498       viewport.alignment.addSequence(seqs[i]);
1499     }
1500
1501     //!newAlignment
1502     addHistoryItem(new EditCommand(
1503         "Add sequences",
1504         EditCommand.PASTE,
1505         seqs,
1506         0,
1507         viewport.alignment.getWidth(),
1508         viewport.alignment)
1509         );
1510
1511     viewport.setEndSeq(viewport.alignment.getHeight());
1512     viewport.alignment.getWidth();
1513     viewport.firePropertyChange("alignment", null,
1514                                 viewport.alignment.getSequences());
1515
1516   }
1517
1518   protected void cut_actionPerformed()
1519   {
1520     copy_actionPerformed();
1521     delete_actionPerformed();
1522   }
1523
1524   protected void delete_actionPerformed()
1525   {
1526
1527     SequenceGroup sg = viewport.getSelectionGroup();
1528     if (sg == null)
1529     {
1530       return;
1531     }
1532
1533     Vector seqs = new Vector();
1534     SequenceI seq;
1535     for (int i = 0; i < sg.getSize(); i++)
1536     {
1537       seq = sg.getSequenceAt(i);
1538       seqs.addElement(seq);
1539     }
1540
1541     // If the cut affects all sequences, remove highlighted columns
1542     if (sg.getSize() == viewport.alignment.getHeight())
1543     {
1544       viewport.getColumnSelection().removeElements(sg.getStartRes(),
1545           sg.getEndRes() + 1);
1546     }
1547
1548     SequenceI[] cut = new SequenceI[seqs.size()];
1549     for (int i = 0; i < seqs.size(); i++)
1550     {
1551       cut[i] = (SequenceI) seqs.elementAt(i);
1552     }
1553
1554     /*
1555          //ADD HISTORY ITEM
1556      */
1557     addHistoryItem(new EditCommand("Cut Sequences",
1558                                    EditCommand.CUT,
1559                                    cut,
1560                                    sg.getStartRes(),
1561                                    sg.getEndRes() - sg.getStartRes() + 1,
1562                                    viewport.alignment));
1563
1564     viewport.setSelectionGroup(null);
1565     viewport.alignment.deleteGroup(sg);
1566
1567     viewport.firePropertyChange("alignment", null,
1568                                 viewport.getAlignment().getSequences());
1569
1570     if (viewport.getAlignment().getHeight() < 1)
1571     {
1572       this.setVisible(false);
1573     }
1574   }
1575
1576   protected void deleteGroups_actionPerformed()
1577   {
1578     viewport.alignment.deleteAllGroups();
1579     viewport.sequenceColours = null;
1580     viewport.setSelectionGroup(null);
1581
1582     alignPanel.paintAlignment(true);
1583   }
1584
1585   public void selectAllSequenceMenuItem_actionPerformed()
1586   {
1587     SequenceGroup sg = new SequenceGroup();
1588     for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
1589     {
1590       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);
1591     }
1592     sg.setEndRes(viewport.alignment.getWidth() - 1);
1593     viewport.setSelectionGroup(sg);
1594     alignPanel.paintAlignment(true);
1595     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1596   }
1597
1598   public void deselectAllSequenceMenuItem_actionPerformed()
1599   {
1600     if (viewport.cursorMode)
1601     {
1602       alignPanel.seqPanel.keyboardNo1 = null;
1603       alignPanel.seqPanel.keyboardNo2 = null;
1604     }
1605     viewport.setSelectionGroup(null);
1606     viewport.getColumnSelection().clear();
1607     viewport.setSelectionGroup(null);
1608     alignPanel.idPanel.idCanvas.searchResults = null;
1609     alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);
1610     alignPanel.paintAlignment(true);
1611     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1612   }
1613
1614   public void invertSequenceMenuItem_actionPerformed()
1615   {
1616     SequenceGroup sg = viewport.getSelectionGroup();
1617     for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
1618     {
1619       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
1620     }
1621
1622     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1623   }
1624
1625   void trimAlignment(boolean trimLeft)
1626   {
1627     ColumnSelection colSel = viewport.getColumnSelection();
1628     int column;
1629
1630     if (colSel.size() > 0)
1631     {
1632       if (trimLeft)
1633       {
1634         column = colSel.getMin();
1635       }
1636       else
1637       {
1638         column = colSel.getMax();
1639       }
1640
1641       SequenceI[] seqs;
1642       if (viewport.getSelectionGroup() != null)
1643       {
1644         seqs = viewport.getSelectionGroup().getSequencesAsArray(viewport.
1645             hiddenRepSequences);
1646       }
1647       else
1648       {
1649         seqs = viewport.alignment.getSequencesArray();
1650       }
1651
1652       TrimRegionCommand trimRegion;
1653       if (trimLeft)
1654       {
1655         trimRegion = new TrimRegionCommand("Remove Left",
1656                                            TrimRegionCommand.TRIM_LEFT,
1657                                            seqs,
1658                                            column,
1659                                            viewport.alignment,
1660                                            viewport.colSel,
1661                                            viewport.selectionGroup);
1662         viewport.setStartRes(0);
1663       }
1664       else
1665       {
1666         trimRegion = new TrimRegionCommand("Remove Right",
1667                                            TrimRegionCommand.TRIM_RIGHT,
1668                                            seqs,
1669                                            column,
1670                                            viewport.alignment,
1671                                            viewport.colSel,
1672                                            viewport.selectionGroup);
1673       }
1674
1675       statusBar.setText("Removed " + trimRegion.getSize() + " columns.");
1676
1677       addHistoryItem(trimRegion);
1678
1679       Vector groups = viewport.alignment.getGroups();
1680
1681       for (int i = 0; i < groups.size(); i++)
1682       {
1683         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
1684
1685         if ( (trimLeft && !sg.adjustForRemoveLeft(column))
1686             || (!trimLeft && !sg.adjustForRemoveRight(column)))
1687         {
1688           viewport.alignment.deleteGroup(sg);
1689         }
1690       }
1691
1692       viewport.firePropertyChange("alignment", null,
1693                                   viewport.getAlignment().getSequences());
1694     }
1695   }
1696
1697   public void removeGappedColumnMenuItem_actionPerformed()
1698   {
1699     int start = 0, end = viewport.alignment.getWidth() - 1;
1700
1701     SequenceI[] seqs;
1702     if (viewport.getSelectionGroup() != null)
1703     {
1704       seqs = viewport.getSelectionGroup().getSequencesAsArray(viewport.
1705           hiddenRepSequences);
1706       start = viewport.getSelectionGroup().getStartRes();
1707       end = viewport.getSelectionGroup().getEndRes();
1708     }
1709     else
1710     {
1711       seqs = viewport.alignment.getSequencesArray();
1712     }
1713
1714     RemoveGapColCommand removeGapCols =
1715         new RemoveGapColCommand("Remove Gapped Columns",
1716                                 seqs,
1717                                 start, end,
1718                                 viewport.alignment);
1719
1720     addHistoryItem(removeGapCols);
1721
1722     statusBar.setText("Removed " + removeGapCols.getSize() + " empty columns.");
1723
1724     //This is to maintain viewport position on first residue
1725     //of first sequence
1726     SequenceI seq = viewport.alignment.getSequenceAt(0);
1727     int startRes = seq.findPosition(viewport.startRes);
1728     // ShiftList shifts;
1729     // viewport.getAlignment().removeGaps(shifts=new ShiftList());
1730     // edit.alColumnChanges=shifts.getInverse();
1731     // if (viewport.hasHiddenColumns)
1732     //   viewport.getColumnSelection().compensateForEdits(shifts);
1733     viewport.setStartRes(seq.findIndex(startRes) - 1);
1734     viewport.firePropertyChange("alignment", null,
1735                                 viewport.getAlignment().getSequences());
1736
1737   }
1738
1739   public void removeAllGapsMenuItem_actionPerformed()
1740   {
1741     int start = 0, end = viewport.alignment.getWidth() - 1;
1742
1743     SequenceI[] seqs;
1744     if (viewport.getSelectionGroup() != null)
1745     {
1746       seqs = viewport.getSelectionGroup().getSequencesAsArray(viewport.
1747           hiddenRepSequences);
1748       start = viewport.getSelectionGroup().getStartRes();
1749       end = viewport.getSelectionGroup().getEndRes();
1750     }
1751     else
1752     {
1753       seqs = viewport.alignment.getSequencesArray();
1754     }
1755
1756     //This is to maintain viewport position on first residue
1757     //of first sequence
1758     SequenceI seq = viewport.alignment.getSequenceAt(0);
1759     int startRes = seq.findPosition(viewport.startRes);
1760
1761     addHistoryItem(new RemoveGapsCommand("Remove Gaps",
1762                                          seqs,
1763                                          start, end,
1764                                          viewport.alignment));
1765
1766     viewport.setStartRes(seq.findIndex(startRes) - 1);
1767
1768     viewport.firePropertyChange("alignment", null,
1769                                 viewport.getAlignment().getSequences());
1770
1771   }
1772
1773   public void findMenuItem_actionPerformed()
1774   {
1775     new Finder(alignPanel);
1776   }
1777
1778   public void newView()
1779   {
1780     AlignmentI newal;
1781     if (viewport.hasHiddenRows)
1782     {
1783       newal = new Alignment(viewport.getAlignment().
1784                             getHiddenSequences()
1785                             .getFullAlignment().
1786                             getSequencesArray());
1787     }
1788     else
1789     {
1790       newal = new Alignment(viewport.alignment.getSequencesArray());
1791     }
1792
1793     if (viewport.alignment.getAlignmentAnnotation() != null)
1794     {
1795       for (int i = 0; i < viewport.alignment.getAlignmentAnnotation().length; i++)
1796       {
1797         if (!viewport.alignment.getAlignmentAnnotation()[i].autoCalculated)
1798         {
1799           newal.addAnnotation(viewport.alignment.getAlignmentAnnotation()[i]);
1800         }
1801       }
1802     }
1803
1804     AlignFrame newaf = new AlignFrame(newal,
1805                                       viewport.applet,
1806                                       "",
1807                                       false);
1808
1809     newaf.viewport.sequenceSetID = alignPanel.av.getSequenceSetId();
1810     PaintRefresher.Register(alignPanel, alignPanel.av.getSequenceSetId());
1811     PaintRefresher.Register(newaf.alignPanel,
1812                             newaf.alignPanel.av.getSequenceSetId());
1813
1814     PaintRefresher.Register(newaf.alignPanel.idPanel.idCanvas,
1815                             newaf.alignPanel.av.getSequenceSetId());
1816     PaintRefresher.Register(newaf.alignPanel.seqPanel.seqCanvas,
1817                             newaf.alignPanel.av.getSequenceSetId());
1818
1819     Vector comps = (Vector) PaintRefresher.components.get(viewport.
1820         getSequenceSetId());
1821     int viewSize = -1;
1822     for (int i = 0; i < comps.size(); i++)
1823     {
1824       if (comps.elementAt(i) instanceof AlignmentPanel)
1825       {
1826         viewSize++;
1827       }
1828     }
1829
1830     String title = new String(this.getTitle());
1831     if (title.indexOf("(View") > -1)
1832     {
1833       title = title.substring(0, title.indexOf("(View"));
1834     }
1835
1836     title += "(View " + viewSize + ")";
1837
1838     newaf.setTitle(title.toString());
1839
1840     newaf.viewport.historyList = viewport.historyList;
1841     newaf.viewport.redoList = viewport.redoList;
1842
1843   }
1844
1845   public void seqLimits_itemStateChanged()
1846   {
1847     viewport.setShowJVSuffix(seqLimits.getState());
1848     alignPanel.fontChanged();
1849     alignPanel.paintAlignment(true);
1850   }
1851
1852   protected void colourTextMenuItem_actionPerformed()
1853   {
1854     viewport.setColourText(colourTextMenuItem.getState());
1855     alignPanel.paintAlignment(true);
1856   }
1857
1858   protected void wrapMenuItem_actionPerformed()
1859   {
1860     viewport.setWrapAlignment(wrapMenuItem.getState());
1861     alignPanel.setWrapAlignment(wrapMenuItem.getState());
1862     scaleAbove.setEnabled(wrapMenuItem.getState());
1863     scaleLeft.setEnabled(wrapMenuItem.getState());
1864     scaleRight.setEnabled(wrapMenuItem.getState());
1865     alignPanel.paintAlignment(true);
1866   }
1867
1868   public void overviewMenuItem_actionPerformed()
1869   {
1870     if (alignPanel.overviewPanel != null)
1871     {
1872       return;
1873     }
1874
1875     Frame frame = new Frame();
1876     OverviewPanel overview = new OverviewPanel(alignPanel);
1877     frame.add(overview);
1878     // +50 must allow for applet frame window
1879     jalview.bin.JalviewLite.addFrame(frame, "Overview " + this.getTitle(),
1880                                      overview.getPreferredSize().width,
1881                                      overview.getPreferredSize().height + 50);
1882
1883     frame.pack();
1884     frame.addWindowListener(new WindowAdapter()
1885     {
1886       public void windowClosing(WindowEvent e)
1887       {
1888         alignPanel.setOverviewPanel(null);
1889       };
1890     });
1891
1892     alignPanel.setOverviewPanel(overview);
1893
1894   }
1895
1896   void changeColour(ColourSchemeI cs)
1897   {
1898     int threshold = 0;
1899
1900     if (cs != null)
1901     {
1902       if (viewport.getAbovePIDThreshold())
1903       {
1904         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");
1905
1906         cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());
1907
1908         viewport.setGlobalColourScheme(cs);
1909       }
1910       else
1911       {
1912         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
1913       }
1914
1915       if (viewport.getConservationSelected())
1916       {
1917
1918         Alignment al = (Alignment) viewport.alignment;
1919         Conservation c = new Conservation("All",
1920                                           ResidueProperties.propHash, 3,
1921                                           al.getSequences(), 0,
1922                                           al.getWidth() - 1);
1923
1924         c.calculate();
1925         c.verdict(false, viewport.ConsPercGaps);
1926
1927         cs.setConservation(c);
1928
1929         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,
1930             "Background"));
1931
1932       }
1933       else
1934       {
1935         cs.setConservation(null);
1936       }
1937
1938       cs.setConsensus(viewport.hconsensus);
1939
1940     }
1941     viewport.setGlobalColourScheme(cs);
1942
1943     if (viewport.getColourAppliesToAllGroups())
1944     {
1945       Vector groups = viewport.alignment.getGroups();
1946       for (int i = 0; i < groups.size(); i++)
1947       {
1948         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
1949
1950         if (cs == null)
1951         {
1952           sg.cs = null;
1953           continue;
1954         }
1955         if (cs instanceof ClustalxColourScheme)
1956         {
1957           sg.cs = new ClustalxColourScheme(
1958               sg.getSequences(viewport.hiddenRepSequences),
1959               sg.getWidth());
1960         }
1961         else
1962         {
1963           try
1964           {
1965             sg.cs = (ColourSchemeI) cs.getClass().newInstance();
1966           }
1967           catch (Exception ex)
1968           {
1969             ex.printStackTrace();
1970             sg.cs = cs;
1971           }
1972         }
1973
1974         if (viewport.getAbovePIDThreshold()
1975             || cs instanceof PIDColourScheme
1976             || cs instanceof Blosum62ColourScheme)
1977         {
1978           sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());
1979           sg.cs.setConsensus(AAFrequency.calculate(
1980               sg.getSequences(viewport.hiddenRepSequences), 0, sg.getWidth()));
1981         }
1982         else
1983         {
1984           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
1985         }
1986
1987         if (viewport.getConservationSelected())
1988         {
1989           Conservation c = new Conservation("Group",
1990                                             ResidueProperties.propHash, 3,
1991                                             sg.getSequences(viewport.
1992               hiddenRepSequences), 0,
1993                                             viewport.alignment.getWidth() - 1);
1994           c.calculate();
1995           c.verdict(false, viewport.ConsPercGaps);
1996           sg.cs.setConservation(c);
1997         }
1998         else
1999         {
2000           sg.cs.setConservation(null);
2001           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2002         }
2003
2004       }
2005     }
2006
2007     if (alignPanel.getOverviewPanel() != null)
2008     {
2009       alignPanel.getOverviewPanel().updateOverviewImage();
2010     }
2011
2012     jalview.structure.StructureSelectionManager.getStructureSelectionManager()
2013         .sequenceColoursChanged(alignPanel);
2014
2015     alignPanel.paintAlignment(true);
2016   }
2017
2018   protected void modifyPID_actionPerformed()
2019   {
2020     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme != null)
2021     {
2022       SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),
2023                                      "Background");
2024       SliderPanel.showPIDSlider();
2025     }
2026   }
2027
2028   protected void modifyConservation_actionPerformed()
2029   {
2030     if (viewport.getConservationSelected() && viewport.globalColourScheme != null)
2031     {
2032       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,
2033                                         "Background");
2034       SliderPanel.showConservationSlider();
2035     }
2036   }
2037
2038   protected void conservationMenuItem_actionPerformed()
2039   {
2040     viewport.setConservationSelected(conservationMenuItem.getState());
2041
2042     viewport.setAbovePIDThreshold(false);
2043     abovePIDThreshold.setState(false);
2044
2045     changeColour(viewport.getGlobalColourScheme());
2046
2047     modifyConservation_actionPerformed();
2048   }
2049
2050   public void abovePIDThreshold_actionPerformed()
2051   {
2052     viewport.setAbovePIDThreshold(abovePIDThreshold.getState());
2053
2054     conservationMenuItem.setState(false);
2055     viewport.setConservationSelected(false);
2056
2057     changeColour(viewport.getGlobalColourScheme());
2058
2059     modifyPID_actionPerformed();
2060   }
2061
2062   public void sortPairwiseMenuItem_actionPerformed()
2063   {
2064     SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
2065     AlignmentSorter.sortByPID(viewport.getAlignment(),
2066                               viewport.getAlignment().getSequenceAt(0));
2067     addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
2068                                     viewport.alignment));
2069     alignPanel.paintAlignment(true);
2070   }
2071
2072   public void sortIDMenuItem_actionPerformed()
2073   {
2074     //  addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,
2075     //                                HistoryItem.SORT));
2076     AlignmentSorter.sortByID(viewport.getAlignment());
2077     alignPanel.paintAlignment(true);
2078   }
2079
2080   public void sortGroupMenuItem_actionPerformed()
2081   {
2082     //  addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,
2083     //                                 HistoryItem.SORT));
2084     AlignmentSorter.sortByGroup(viewport.getAlignment());
2085     alignPanel.paintAlignment(true);
2086
2087   }
2088
2089   public void removeRedundancyMenuItem_actionPerformed()
2090   {
2091     new RedundancyPanel(alignPanel);
2092   }
2093
2094   public void pairwiseAlignmentMenuItem_actionPerformed()
2095   {
2096     if (viewport.getSelectionGroup() != null
2097         && viewport.getSelectionGroup().getSize() > 1)
2098     {
2099       Frame frame = new Frame();
2100       frame.add(new PairwiseAlignPanel(alignPanel));
2101       jalview.bin.JalviewLite.addFrame(frame, "Pairwise Alignment", 600, 500);
2102     }
2103   }
2104
2105   public void PCAMenuItem_actionPerformed()
2106   {
2107     //are the sequences aligned?
2108     if (!viewport.alignment.isAligned())
2109     {
2110       SequenceI current;
2111       int Width = viewport.getAlignment().getWidth();
2112
2113       for (int i = 0; i < viewport.getAlignment().getSequences().size();
2114            i++)
2115       {
2116         current = viewport.getAlignment().getSequenceAt(i);
2117
2118         if (current.getLength() < Width)
2119         {
2120           current.insertCharAt(Width - 1, viewport.getGapCharacter());
2121         }
2122       }
2123       alignPanel.paintAlignment(true);
2124     }
2125
2126     if ( (viewport.getSelectionGroup() != null &&
2127           viewport.getSelectionGroup().getSize() < 4 &&
2128           viewport.getSelectionGroup().getSize() > 0)
2129         || viewport.getAlignment().getHeight() < 4)
2130     {
2131       return;
2132     }
2133
2134     try
2135     {
2136       new PCAPanel(viewport);
2137     }
2138     catch (java.lang.OutOfMemoryError ex)
2139     {
2140     }
2141
2142   }
2143
2144   public void averageDistanceTreeMenuItem_actionPerformed()
2145   {
2146     NewTreePanel("AV", "PID", "Average distance tree using PID");
2147   }
2148
2149   public void neighbourTreeMenuItem_actionPerformed()
2150   {
2151     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
2152   }
2153
2154   protected void njTreeBlosumMenuItem_actionPerformed()
2155   {
2156     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
2157   }
2158
2159   protected void avTreeBlosumMenuItem_actionPerformed()
2160   {
2161     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
2162   }
2163
2164   void NewTreePanel(String type, String pwType, String title)
2165   {
2166     //are the sequences aligned?
2167     if (!viewport.alignment.isAligned())
2168     {
2169       SequenceI current;
2170       int Width = viewport.getAlignment().getWidth();
2171
2172       for (int i = 0; i < viewport.getAlignment().getSequences().size();
2173            i++)
2174       {
2175         current = viewport.getAlignment().getSequenceAt(i);
2176
2177         if (current.getLength() < Width)
2178         {
2179           current.insertCharAt(Width - 1, viewport.getGapCharacter());
2180         }
2181       }
2182       alignPanel.paintAlignment(true);
2183
2184     }
2185
2186     if ( (viewport.getSelectionGroup() != null &&
2187           viewport.getSelectionGroup().getSize() > 1)
2188         || (viewport.getSelectionGroup() == null
2189             && viewport.alignment.getHeight() > 1))
2190     {
2191       final TreePanel tp = new TreePanel(viewport,
2192                                          type,
2193                                          pwType);
2194
2195       addTreeMenuItem(tp, title);
2196
2197       jalview.bin.JalviewLite.addFrame(tp, title, 600, 500);
2198     }
2199   }
2200
2201   void loadTree_actionPerformed()
2202   {
2203     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
2204     cap.setText("Paste your Newick tree file here.");
2205     cap.setTreeImport();
2206     Frame frame = new Frame();
2207     frame.add(cap);
2208     jalview.bin.JalviewLite.addFrame(frame, "Paste Newick file ", 400, 300);
2209   }
2210
2211   public void loadTree(jalview.io.NewickFile tree, String treeFile)
2212   {
2213     TreePanel tp = new TreePanel(viewport,
2214                                  treeFile,
2215                                  "From File - ",
2216                                  tree);
2217     jalview.bin.JalviewLite.addFrame(tp, treeFile, 600, 500);
2218     addTreeMenuItem(tp, treeFile);
2219   }
2220
2221   void addTreeMenuItem(final TreePanel treePanel, String title)
2222   {
2223     final MenuItem item = new MenuItem(title);
2224     sortByTreeMenu.add(item);
2225     item.addActionListener(new java.awt.event.ActionListener()
2226     {
2227       public void actionPerformed(ActionEvent evt)
2228       {
2229         //  addHistoryItem(new HistoryItem("Sort", viewport.alignment,
2230         //                                 HistoryItem.SORT));
2231         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());
2232         alignPanel.paintAlignment(true);
2233       }
2234     });
2235
2236     treePanel.addWindowListener(new WindowAdapter()
2237     {
2238       public void windowClosing(WindowEvent e)
2239       {
2240         sortByTreeMenu.remove(item);
2241       };
2242     });
2243   }
2244
2245   protected void documentation_actionPerformed()
2246   {
2247     showURL("http://www.jalview.org/help.html", "HELP");
2248   }
2249
2250   protected void about_actionPerformed()
2251   {
2252
2253     class AboutPanel
2254         extends Canvas
2255     {
2256       String version;
2257       public AboutPanel(String version)
2258       {
2259         this.version = version;
2260       }
2261
2262       public void paint(Graphics g)
2263       {
2264         g.setColor(Color.white);
2265         g.fillRect(0, 0, getSize().width, getSize().height);
2266         g.setFont(new Font("Helvetica", Font.PLAIN, 12));
2267         FontMetrics fm = g.getFontMetrics();
2268         int fh = fm.getHeight();
2269         int y = 5, x = 7;
2270         g.setColor(Color.black);
2271         g.setFont(new Font("Helvetica", Font.BOLD, 14));
2272         g.drawString("Jalview - Release " + version, 200, y += fh);
2273         g.setFont(new Font("Helvetica", Font.PLAIN, 12));
2274         g.drawString("Authors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",
2275                      x, y += fh * 2);
2276         g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",
2277                      x, y += fh);
2278         g.drawString(
2279             "For any issues relating to Jalview, email help@jalview.org", x,
2280             y += fh);
2281         g.drawString("If  you use JalView, please cite:", x, y += fh + 8);
2282         g.drawString("\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"",
2283                      x, y += fh);
2284         g.drawString("Bioinformatics,  2004 20;426-7.", x, y += fh);
2285       }
2286     }
2287
2288     String version = "test";
2289     java.net.URL url = getClass().getResource("/.build_properties");
2290     if (url != null)
2291     {
2292       try
2293       {
2294         BufferedReader reader = new BufferedReader(new InputStreamReader(
2295             url.openStream()));
2296         String line;
2297         while ( (line = reader.readLine()) != null)
2298         {
2299           if (line.indexOf("VERSION") > -1)
2300           {
2301             version = line.substring(line.indexOf("=") + 1);
2302           }
2303         }
2304       }
2305       catch (Exception ex)
2306       {
2307         ex.printStackTrace();
2308       }
2309     }
2310
2311     Frame frame = new Frame();
2312     frame.add(new AboutPanel(version));
2313     jalview.bin.JalviewLite.addFrame(frame, "Jalview", 580, 200);
2314
2315   }
2316
2317   public void showURL(String url, String target)
2318   {
2319     if (viewport.applet == null)
2320     {
2321       System.out.println("Not running as applet - no browser available.");
2322     }
2323     else
2324     {
2325       try
2326       {
2327         System.out.println("Show url: " + url);
2328         viewport.applet.getAppletContext().showDocument(new java.net.URL(url),
2329             target);
2330       }
2331       catch (Exception ex)
2332       {
2333         ex.printStackTrace();
2334       }
2335     }
2336   }
2337
2338   //////////////////////////////////////////////////////////////////////////////////
2339   //JBuilder Graphics here
2340
2341    MenuBar alignFrameMenuBar = new MenuBar();
2342    Menu fileMenu = new Menu("File");
2343    MenuItem loadApplication = new MenuItem("View in Full Application");
2344    MenuItem loadTree = new MenuItem("Load Associated Tree ...");
2345    MenuItem loadAnnotations = new MenuItem(
2346       "Load Features/Annotations ...");
2347    MenuItem outputFeatures = new MenuItem("Export Features ...");
2348    MenuItem outputAnnotations = new MenuItem("Export Annotations ...");
2349
2350    MenuItem closeMenuItem = new MenuItem("Close");
2351    Menu editMenu = new Menu("Edit");
2352    Menu viewMenu = new Menu("View");
2353    Menu colourMenu = new Menu("Colour");
2354    Menu calculateMenu = new Menu("Calculate");
2355    MenuItem selectAllSequenceMenuItem = new MenuItem("Select all");
2356    MenuItem deselectAllSequenceMenuItem = new MenuItem("Deselect All");
2357    MenuItem invertSequenceMenuItem = new MenuItem("Invert Selection");
2358    MenuItem remove2LeftMenuItem = new MenuItem();
2359    MenuItem remove2RightMenuItem = new MenuItem();
2360    MenuItem removeGappedColumnMenuItem = new MenuItem();
2361    MenuItem removeAllGapsMenuItem = new MenuItem();
2362    CheckboxMenuItem viewBoxesMenuItem = new CheckboxMenuItem();
2363    CheckboxMenuItem viewTextMenuItem = new CheckboxMenuItem();
2364    MenuItem sortPairwiseMenuItem = new MenuItem();
2365    MenuItem sortIDMenuItem = new MenuItem();
2366    MenuItem sortGroupMenuItem = new MenuItem();
2367    MenuItem removeRedundancyMenuItem = new MenuItem();
2368    MenuItem pairwiseAlignmentMenuItem = new MenuItem();
2369    MenuItem PCAMenuItem = new MenuItem();
2370    MenuItem averageDistanceTreeMenuItem = new MenuItem();
2371    MenuItem neighbourTreeMenuItem = new MenuItem();
2372   BorderLayout borderLayout1 = new BorderLayout();
2373   public Label statusBar = new Label();
2374    Menu outputTextboxMenu = new Menu();
2375    MenuItem clustalColour = new MenuItem();
2376    MenuItem zappoColour = new MenuItem();
2377    MenuItem taylorColour = new MenuItem();
2378    MenuItem hydrophobicityColour = new MenuItem();
2379    MenuItem helixColour = new MenuItem();
2380    MenuItem strandColour = new MenuItem();
2381    MenuItem turnColour = new MenuItem();
2382    MenuItem buriedColour = new MenuItem();
2383    MenuItem userDefinedColour = new MenuItem();
2384    MenuItem PIDColour = new MenuItem();
2385    MenuItem BLOSUM62Colour = new MenuItem();
2386   MenuItem njTreeBlosumMenuItem = new MenuItem();
2387   MenuItem avDistanceTreeBlosumMenuItem = new MenuItem();
2388    CheckboxMenuItem annotationPanelMenuItem = new CheckboxMenuItem();
2389    CheckboxMenuItem colourTextMenuItem = new CheckboxMenuItem();
2390    MenuItem alProperties = new MenuItem("Alignment Properties...");
2391   MenuItem overviewMenuItem = new MenuItem();
2392    MenuItem undoMenuItem = new MenuItem();
2393    MenuItem redoMenuItem = new MenuItem();
2394    CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
2395   MenuItem noColourmenuItem = new MenuItem();
2396    CheckboxMenuItem wrapMenuItem = new CheckboxMenuItem();
2397    CheckboxMenuItem renderGapsMenuItem = new CheckboxMenuItem();
2398   MenuItem findMenuItem = new MenuItem();
2399    CheckboxMenuItem abovePIDThreshold = new CheckboxMenuItem();
2400    MenuItem nucleotideColour = new MenuItem();
2401   MenuItem deleteGroups = new MenuItem();
2402   MenuItem delete = new MenuItem();
2403   MenuItem copy = new MenuItem();
2404   MenuItem cut = new MenuItem();
2405   Menu pasteMenu = new Menu();
2406   MenuItem pasteNew = new MenuItem();
2407   MenuItem pasteThis = new MenuItem();
2408    CheckboxMenuItem applyToAllGroups = new CheckboxMenuItem();
2409    MenuItem font = new MenuItem();
2410    CheckboxMenuItem scaleAbove = new CheckboxMenuItem();
2411    CheckboxMenuItem scaleLeft = new CheckboxMenuItem();
2412    CheckboxMenuItem scaleRight = new CheckboxMenuItem();
2413   MenuItem modifyPID = new MenuItem();
2414   MenuItem modifyConservation = new MenuItem();
2415    CheckboxMenuItem autoCalculate
2416       = new CheckboxMenuItem("Autocalculate Consensus", true);
2417    Menu sortByTreeMenu = new Menu();
2418   Menu sort = new Menu();
2419   Menu calculate = new Menu();
2420   MenuItem inputText = new MenuItem();
2421   Menu helpMenu = new Menu();
2422   MenuItem documentation = new MenuItem();
2423   MenuItem about = new MenuItem();
2424    CheckboxMenuItem seqLimits = new CheckboxMenuItem();
2425   Panel embeddedMenu;
2426   Label embeddedEdit;
2427   Label embeddedSelect;
2428   Label embeddedView;
2429   Label embeddedFormat;
2430   Label embeddedColour;
2431   Label embeddedFile;
2432   Label embeddedHelp;
2433   Label embeddedCalculate;
2434   FlowLayout flowLayout1;
2435
2436   private void jbInit()
2437       throws Exception
2438   {
2439
2440     setMenuBar(alignFrameMenuBar);
2441
2442     MenuItem item;
2443
2444     // dynamically fill save as menu with available formats
2445     for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length;
2446          i++)
2447     {
2448
2449       item = new MenuItem(jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]);
2450
2451       item.addActionListener(new java.awt.event.ActionListener()
2452       {
2453         public void actionPerformed(ActionEvent e)
2454         {
2455           outputText_actionPerformed(e);
2456         }
2457       });
2458
2459       outputTextboxMenu.add(item);
2460     }
2461     closeMenuItem.addActionListener(this);
2462     loadApplication.addActionListener(this);
2463
2464     loadTree.addActionListener(this);
2465     loadAnnotations.addActionListener(this);
2466     outputFeatures.addActionListener(this);
2467     outputAnnotations.addActionListener(this);
2468     selectAllSequenceMenuItem.addActionListener(this);
2469     deselectAllSequenceMenuItem.addActionListener(this);
2470     invertSequenceMenuItem.addActionListener(this);
2471     remove2LeftMenuItem.setLabel("Remove Left");
2472     remove2LeftMenuItem.addActionListener(this);
2473     remove2RightMenuItem.setLabel("Remove Right");
2474     remove2RightMenuItem.addActionListener(this);
2475     removeGappedColumnMenuItem.setLabel("Remove Empty Columns");
2476     removeGappedColumnMenuItem.addActionListener(this);
2477     removeAllGapsMenuItem.setLabel("Remove All Gaps");
2478     removeAllGapsMenuItem.addActionListener(this);
2479     viewBoxesMenuItem.setLabel("Boxes");
2480     viewBoxesMenuItem.setState(true);
2481     viewBoxesMenuItem.addItemListener(this);
2482     viewTextMenuItem.setLabel("Text");
2483     viewTextMenuItem.setState(true);
2484     viewTextMenuItem.addItemListener(this);
2485     sortPairwiseMenuItem.setLabel("by Pairwise Identity");
2486     sortPairwiseMenuItem.addActionListener(this);
2487     sortIDMenuItem.setLabel("by ID");
2488     sortIDMenuItem.addActionListener(this);
2489     sortGroupMenuItem.setLabel("by Group");
2490     sortGroupMenuItem.addActionListener(this);
2491     removeRedundancyMenuItem.setLabel("Remove Redundancy...");
2492     removeRedundancyMenuItem.addActionListener(this);
2493     pairwiseAlignmentMenuItem.setLabel("Pairwise Alignments...");
2494     pairwiseAlignmentMenuItem.addActionListener(this);
2495     PCAMenuItem.setLabel("Principal Component Analysis");
2496     PCAMenuItem.addActionListener(this);
2497     averageDistanceTreeMenuItem.setLabel(
2498         "Average Distance Using % Identity");
2499     averageDistanceTreeMenuItem.addActionListener(this);
2500     neighbourTreeMenuItem.setLabel("Neighbour Joining Using % Identity");
2501     neighbourTreeMenuItem.addActionListener(this);
2502     statusBar.setBackground(Color.white);
2503     statusBar.setFont(new java.awt.Font("Verdana", 0, 11));
2504     statusBar.setText("Status bar");
2505     outputTextboxMenu.setLabel("Output to Textbox");
2506     clustalColour.setLabel("Clustalx");
2507
2508     clustalColour.addActionListener(this);
2509     zappoColour.setLabel("Zappo");
2510     zappoColour.addActionListener(this);
2511     taylorColour.setLabel("Taylor");
2512     taylorColour.addActionListener(this);
2513     hydrophobicityColour.setLabel("Hydrophobicity");
2514     hydrophobicityColour.addActionListener(this);
2515     helixColour.setLabel("Helix Propensity");
2516     helixColour.addActionListener(this);
2517     strandColour.setLabel("Strand Propensity");
2518     strandColour.addActionListener(this);
2519     turnColour.setLabel("Turn Propensity");
2520     turnColour.addActionListener(this);
2521     buriedColour.setLabel("Buried Index");
2522     buriedColour.addActionListener(this);
2523     userDefinedColour.setLabel("User Defined...");
2524     userDefinedColour.addActionListener(this);
2525     PIDColour.setLabel("Percentage Identity");
2526     PIDColour.addActionListener(this);
2527     BLOSUM62Colour.setLabel("BLOSUM62 Score");
2528     BLOSUM62Colour.addActionListener(this);
2529     avDistanceTreeBlosumMenuItem.setLabel(
2530         "Average Distance Using BLOSUM62");
2531     avDistanceTreeBlosumMenuItem.addActionListener(this);
2532     njTreeBlosumMenuItem.setLabel("Neighbour Joining Using BLOSUM62");
2533     njTreeBlosumMenuItem.addActionListener(this);
2534     annotationPanelMenuItem.setLabel("Show Annotations");
2535     annotationPanelMenuItem.addItemListener(this);
2536     colourTextMenuItem.setLabel("Colour Text");
2537     colourTextMenuItem.addItemListener(this);
2538     alProperties.addActionListener(this);
2539     overviewMenuItem.setLabel("Overview Window");
2540     overviewMenuItem.addActionListener(this);
2541     undoMenuItem.setEnabled(false);
2542     undoMenuItem.setLabel("Undo");
2543     undoMenuItem.addActionListener(this);
2544     redoMenuItem.setEnabled(false);
2545     redoMenuItem.setLabel("Redo");
2546     redoMenuItem.addActionListener(this);
2547     conservationMenuItem.setLabel("by Conservation");
2548     conservationMenuItem.addItemListener(this);
2549     noColourmenuItem.setLabel("None");
2550     noColourmenuItem.addActionListener(this);
2551     wrapMenuItem.setLabel("Wrap");
2552     wrapMenuItem.addItemListener(this);
2553     renderGapsMenuItem.setLabel("Show Gaps");
2554     renderGapsMenuItem.setState(true);
2555     renderGapsMenuItem.addItemListener(this);
2556     findMenuItem.setLabel("Find...");
2557     findMenuItem.addActionListener(this);
2558     abovePIDThreshold.setLabel("Above Identity Threshold");
2559     abovePIDThreshold.addItemListener(this);
2560     nucleotideColour.setLabel("Nucleotide");
2561     nucleotideColour.addActionListener(this);
2562     deleteGroups.setLabel("Undefine Groups");
2563     deleteGroups.addActionListener(this);
2564     copy.setLabel("Copy");
2565     copy.addActionListener(this);
2566     cut.setLabel("Cut");
2567     cut.addActionListener(this);
2568     delete.setLabel("Delete");
2569     delete.addActionListener(this);
2570     pasteMenu.setLabel("Paste");
2571     pasteNew.setLabel("To New Alignment");
2572     pasteNew.addActionListener(this);
2573     pasteThis.setLabel("Add To This Alignment");
2574     pasteThis.addActionListener(this);
2575     applyToAllGroups.setLabel("Apply Colour To All Groups");
2576     applyToAllGroups.setState(true);
2577     applyToAllGroups.addItemListener(this);
2578     font.setLabel("Font...");
2579     font.addActionListener(this);
2580     scaleAbove.setLabel("Scale Above");
2581     scaleAbove.setState(true);
2582     scaleAbove.setEnabled(false);
2583     scaleAbove.addItemListener(this);
2584     scaleLeft.setEnabled(false);
2585     scaleLeft.setState(true);
2586     scaleLeft.setLabel("Scale Left");
2587     scaleLeft.addItemListener(this);
2588     scaleRight.setEnabled(false);
2589     scaleRight.setState(true);
2590     scaleRight.setLabel("Scale Right");
2591     scaleRight.addItemListener(this);
2592     modifyPID.setLabel("Modify Identity Threshold...");
2593     modifyPID.addActionListener(this);
2594     modifyConservation.setLabel("Modify Conservation Threshold...");
2595     modifyConservation.addActionListener(this);
2596     sortByTreeMenu.setLabel("By Tree Order");
2597     sort.setLabel("Sort");
2598     calculate.setLabel("Calculate Tree");
2599     autoCalculate.addItemListener(this);
2600     inputText.setLabel("Input from textbox");
2601     inputText.addActionListener(this);
2602
2603     helpMenu.setLabel("Help");
2604     documentation.setLabel("Documentation");
2605     documentation.addActionListener(this);
2606
2607     about.setLabel("About...");
2608     about.addActionListener(this);
2609     seqLimits.setState(true);
2610     seqLimits.setLabel("Show Sequence Limits");
2611     seqLimits.addItemListener(this);
2612     featureSettings.setLabel("Feature Settings...");
2613     featureSettings.addActionListener(this);
2614     sequenceFeatures.setLabel("Sequence Features");
2615     sequenceFeatures.addItemListener(this);
2616     sequenceFeatures.setState(false);
2617     annotationColour.setLabel("by Annotation...");
2618     annotationColour.addActionListener(this);
2619     invertSequenceMenuItem.setLabel("Invert Sequence Selection");
2620     invertColSel.setLabel("Invert Column Selection");
2621     menu1.setLabel("Show");
2622     showColumns.setLabel("All Columns ");
2623     showSeqs.setLabel("All Sequences");
2624     menu2.setLabel("Hide");
2625     hideColumns.setLabel("Selected Columns");
2626     hideSequences.setLabel("Selected Sequences");
2627     invertColSel.addActionListener(this);
2628     showColumns.addActionListener(this);
2629     showSeqs.addActionListener(this);
2630     hideColumns.addActionListener(this);
2631     hideSequences.addActionListener(this);
2632     formatMenu.setLabel("Format");
2633     selectMenu.setLabel("Select");
2634     newView.setLabel("New View");
2635     newView.addActionListener(this);
2636     alignFrameMenuBar.add(fileMenu);
2637     alignFrameMenuBar.add(editMenu);
2638     alignFrameMenuBar.add(selectMenu);
2639     alignFrameMenuBar.add(viewMenu);
2640     alignFrameMenuBar.add(formatMenu);
2641     alignFrameMenuBar.add(colourMenu);
2642     alignFrameMenuBar.add(calculateMenu);
2643     alignFrameMenuBar.add(helpMenu);
2644
2645     fileMenu.add(inputText);
2646     fileMenu.add(loadTree);
2647     fileMenu.add(loadAnnotations);
2648
2649     fileMenu.addSeparator();
2650     fileMenu.add(outputTextboxMenu);
2651     fileMenu.add(outputFeatures);
2652     fileMenu.add(outputAnnotations);
2653
2654     if (jalviewServletURL != null)
2655     {
2656       fileMenu.add(loadApplication);
2657     }
2658
2659     fileMenu.addSeparator();
2660     fileMenu.add(closeMenuItem);
2661
2662     editMenu.add(undoMenuItem);
2663     editMenu.add(redoMenuItem);
2664     editMenu.add(cut);
2665     editMenu.add(copy);
2666     editMenu.add(pasteMenu);
2667     editMenu.add(delete);
2668     editMenu.addSeparator();
2669     editMenu.add(remove2LeftMenuItem);
2670     editMenu.add(remove2RightMenuItem);
2671     editMenu.add(removeGappedColumnMenuItem);
2672     editMenu.add(removeAllGapsMenuItem);
2673     editMenu.add(removeRedundancyMenuItem);
2674     viewMenu.add(newView);
2675     viewMenu.addSeparator();
2676     viewMenu.add(menu1);
2677     viewMenu.add(menu2);
2678     viewMenu.addSeparator();
2679     viewMenu.add(annotationPanelMenuItem);
2680     viewMenu.addSeparator();
2681     viewMenu.add(sequenceFeatures);
2682     viewMenu.add(featureSettings);
2683     viewMenu.addSeparator();
2684     viewMenu.add(alProperties);
2685     viewMenu.addSeparator();
2686     viewMenu.add(overviewMenuItem);
2687     colourMenu.add(applyToAllGroups);
2688     colourMenu.addSeparator();
2689     colourMenu.add(noColourmenuItem);
2690     colourMenu.add(clustalColour);
2691     colourMenu.add(BLOSUM62Colour);
2692     colourMenu.add(PIDColour);
2693     colourMenu.add(zappoColour);
2694     colourMenu.add(taylorColour);
2695     colourMenu.add(hydrophobicityColour);
2696     colourMenu.add(helixColour);
2697     colourMenu.add(strandColour);
2698     colourMenu.add(turnColour);
2699     colourMenu.add(buriedColour);
2700     colourMenu.add(nucleotideColour);
2701     colourMenu.add(userDefinedColour);
2702     colourMenu.addSeparator();
2703     colourMenu.add(conservationMenuItem);
2704     colourMenu.add(modifyConservation);
2705     colourMenu.add(abovePIDThreshold);
2706     colourMenu.add(modifyPID);
2707     colourMenu.add(annotationColour);
2708     calculateMenu.add(sort);
2709     calculateMenu.add(calculate);
2710     calculateMenu.addSeparator();
2711     calculateMenu.add(pairwiseAlignmentMenuItem);
2712     calculateMenu.add(PCAMenuItem);
2713     calculateMenu.add(autoCalculate);
2714     this.add(statusBar, BorderLayout.SOUTH);
2715     pasteMenu.add(pasteNew);
2716     pasteMenu.add(pasteThis);
2717     sort.add(sortIDMenuItem);
2718     sort.add(sortByTreeMenu);
2719     sort.add(sortGroupMenuItem);
2720     sort.add(sortPairwiseMenuItem);
2721     calculate.add(averageDistanceTreeMenuItem);
2722     calculate.add(neighbourTreeMenuItem);
2723     calculate.add(avDistanceTreeBlosumMenuItem);
2724     calculate.add(njTreeBlosumMenuItem);
2725     helpMenu.add(documentation);
2726     helpMenu.add(about);
2727     menu1.add(showColumns);
2728     menu1.add(showSeqs);
2729     menu2.add(hideColumns);
2730     menu2.add(hideSequences);
2731     formatMenu.add(font);
2732     formatMenu.add(seqLimits);
2733     formatMenu.add(wrapMenuItem);
2734     formatMenu.add(scaleAbove);
2735     formatMenu.add(scaleLeft);
2736     formatMenu.add(scaleRight);
2737     formatMenu.add(viewBoxesMenuItem);
2738     formatMenu.add(viewTextMenuItem);
2739     formatMenu.add(colourTextMenuItem);
2740     formatMenu.add(renderGapsMenuItem);
2741     selectMenu.add(findMenuItem);
2742     selectMenu.addSeparator();
2743     selectMenu.add(selectAllSequenceMenuItem);
2744     selectMenu.add(deselectAllSequenceMenuItem);
2745     selectMenu.add(invertSequenceMenuItem);
2746     selectMenu.add(invertColSel);
2747     selectMenu.add(deleteGroups);
2748   }
2749
2750   public void setEmbedded()
2751   {
2752
2753     embeddedMenu = new Panel();
2754     embeddedEdit = new Label("Edit");
2755     embeddedSelect = new Label("Select");
2756     embeddedView = new Label("View");
2757     embeddedFormat = new Label("Format");
2758     embeddedColour = new Label("Colour");
2759     embeddedFile = new Label("File");
2760     embeddedHelp = new Label("Help");
2761     embeddedCalculate = new Label("Calculate");
2762     flowLayout1 = new FlowLayout();
2763     embeddedMenu.setBackground(Color.lightGray);
2764     embeddedMenu.setLayout(flowLayout1);
2765     embeddedEdit.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2766     embeddedSelect.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2767     embeddedView.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2768     embeddedFormat.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2769     embeddedColour.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2770     embeddedFile.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2771     embeddedHelp.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2772     embeddedCalculate.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2773     embeddedMenu.add(embeddedFile);
2774     embeddedMenu.add(embeddedEdit);
2775     embeddedMenu.add(embeddedSelect);
2776     embeddedMenu.add(embeddedView);
2777     embeddedMenu.add(embeddedFormat);
2778     embeddedMenu.add(embeddedColour);
2779     embeddedMenu.add(embeddedCalculate);
2780     embeddedMenu.add(embeddedHelp);
2781     flowLayout1.setAlignment(FlowLayout.LEFT);
2782     flowLayout1.setHgap(2);
2783     flowLayout1.setVgap(0);
2784     embeddedFile.addMouseListener(this);
2785     embeddedEdit.addMouseListener(this);
2786     embeddedSelect.addMouseListener(this);
2787     embeddedView.addMouseListener(this);
2788     embeddedFormat.addMouseListener(this);
2789     embeddedColour.addMouseListener(this);
2790     embeddedCalculate.addMouseListener(this);
2791     embeddedHelp.addMouseListener(this);
2792
2793     fileMenu.remove(closeMenuItem);
2794     fileMenu.remove(3); // Seperator
2795
2796     viewport.applet.setLayout(new BorderLayout());
2797     viewport.applet.add(embeddedMenu, BorderLayout.NORTH);
2798     viewport.applet.add(statusBar, BorderLayout.SOUTH);
2799
2800     alignPanel.setSize(viewport.applet.getSize().width,
2801                        viewport.applet.getSize().height
2802                        - embeddedMenu.HEIGHT - statusBar.HEIGHT);
2803
2804     viewport.applet.add(alignPanel, BorderLayout.CENTER);
2805     viewport.applet.validate();
2806
2807   }
2808
2809   PopupMenu filePopup, editPopup, searchPopup,
2810   viewPopup, formatPopup, colourPopup, calculatePopup, helpPopup;
2811   MenuItem featureSettings = new MenuItem();
2812   CheckboxMenuItem sequenceFeatures = new CheckboxMenuItem();
2813   MenuItem annotationColour = new MenuItem();
2814   MenuItem invertColSel = new MenuItem();
2815   Menu menu1 = new Menu();
2816   MenuItem showColumns = new MenuItem();
2817   MenuItem showSeqs = new MenuItem();
2818   Menu menu2 = new Menu();
2819   MenuItem hideColumns = new MenuItem();
2820   MenuItem hideSequences = new MenuItem();
2821   Menu formatMenu = new Menu();
2822   Menu selectMenu = new Menu();
2823   MenuItem newView = new MenuItem();
2824
2825   public void mousePressed(MouseEvent evt)
2826   {
2827     PopupMenu popup = null;
2828     Label source = (Label) evt.getSource();
2829     if (source == embeddedFile)
2830     {
2831       popup = filePopup = genPopupMenu(filePopup, fileMenu);
2832     }
2833     else if (source == embeddedEdit)
2834     {
2835       popup = editPopup = genPopupMenu(editPopup, editMenu);
2836     }
2837     else if (source == embeddedSelect)
2838     {
2839       popup = searchPopup = genPopupMenu(searchPopup, selectMenu);
2840     }
2841     else if (source == embeddedView)
2842     {
2843       popup = viewPopup = genPopupMenu(viewPopup, viewMenu);
2844     }
2845     else if (source == embeddedFormat)
2846     {
2847       popup = formatPopup = genPopupMenu(formatPopup, formatMenu);
2848     }
2849     else if (source == embeddedColour)
2850     {
2851       popup = colourPopup = genPopupMenu(colourPopup, colourMenu);
2852     }
2853     else if (source == embeddedCalculate)
2854     {
2855       popup = calculatePopup = genPopupMenu(calculatePopup, calculateMenu);
2856     }
2857     else if (source == embeddedHelp)
2858     {
2859       popup = helpPopup = genPopupMenu(helpPopup, helpMenu);
2860     }
2861
2862     embeddedMenu.add(popup);
2863     popup.show(embeddedMenu,
2864                source.getBounds().x,
2865                source.getBounds().y + source.getBounds().getSize().height);
2866   }
2867
2868   PopupMenu genPopupMenu(PopupMenu popup, Menu original)
2869   {
2870     if (popup != null)
2871     {
2872       return popup;
2873     }
2874     popup = new PopupMenu();
2875     int m, mSize = original.getItemCount();
2876     for (m = 0; m < mSize; m++)
2877     {
2878       popup.add(original.getItem(m));
2879       mSize--;
2880       m--;
2881     }
2882
2883     return popup;
2884   }
2885
2886   public void mouseClicked(MouseEvent evt)
2887   {}
2888
2889   public void mouseReleased(MouseEvent evt)
2890   {}
2891
2892   public void mouseEntered(MouseEvent evt)
2893   {}
2894
2895   public void mouseExited(MouseEvent evt)
2896   {}
2897
2898 }