featureGroup show/hide and newView methods for applet's javascript API
[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(null);
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(null);
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    * create a new view derived from the current view
1779    * @param viewtitle
1780    * @return frame for the new view
1781    */
1782   public AlignFrame newView(String viewtitle)
1783   {
1784     AlignmentI newal;
1785     if (viewport.hasHiddenRows)
1786     {
1787       newal = new Alignment(viewport.getAlignment().
1788                             getHiddenSequences()
1789                             .getFullAlignment().
1790                             getSequencesArray());
1791     }
1792     else
1793     {
1794       newal = new Alignment(viewport.alignment.getSequencesArray());
1795     }
1796
1797     if (viewport.alignment.getAlignmentAnnotation() != null)
1798     {
1799       for (int i = 0; i < viewport.alignment.getAlignmentAnnotation().length; i++)
1800       {
1801         if (!viewport.alignment.getAlignmentAnnotation()[i].autoCalculated)
1802         {
1803           newal.addAnnotation(viewport.alignment.getAlignmentAnnotation()[i]);
1804         }
1805       }
1806     }
1807
1808     AlignFrame newaf = new AlignFrame(newal,
1809                                       viewport.applet,
1810                                       "",
1811                                       false);
1812
1813     newaf.viewport.sequenceSetID = alignPanel.av.getSequenceSetId();
1814     PaintRefresher.Register(alignPanel, alignPanel.av.getSequenceSetId());
1815     PaintRefresher.Register(newaf.alignPanel,
1816                             newaf.alignPanel.av.getSequenceSetId());
1817
1818     PaintRefresher.Register(newaf.alignPanel.idPanel.idCanvas,
1819                             newaf.alignPanel.av.getSequenceSetId());
1820     PaintRefresher.Register(newaf.alignPanel.seqPanel.seqCanvas,
1821                             newaf.alignPanel.av.getSequenceSetId());
1822
1823     Vector comps = (Vector) PaintRefresher.components.get(viewport.
1824         getSequenceSetId());
1825     int viewSize = -1;
1826     for (int i = 0; i < comps.size(); i++)
1827     {
1828       if (comps.elementAt(i) instanceof AlignmentPanel)
1829       {
1830         viewSize++;
1831       }
1832     }
1833
1834     String title = new String(this.getTitle());
1835     if (viewtitle!=null)
1836     {
1837       title = viewtitle+" ( "+title+")";
1838     } else {
1839       if (title.indexOf("(View") > -1)
1840       {
1841         title = title.substring(0, title.indexOf("(View"));
1842       }
1843       title += "(View " + viewSize + ")";
1844     }
1845
1846     newaf.setTitle(title.toString());
1847
1848     newaf.viewport.historyList = viewport.historyList;
1849     newaf.viewport.redoList = viewport.redoList;
1850     return newaf;
1851   }
1852   /**
1853    * 
1854    * @return list of feature groups on the view
1855    */
1856   public String[] getFeatureGroups()
1857   {
1858     FeatureRenderer fr = null;
1859     if (alignPanel!=null && (fr=alignPanel.getFeatureRenderer())!=null)
1860     {
1861       return fr.getGroups();
1862     }
1863     return null;
1864   }
1865   /**
1866    * get sequence feature groups that are hidden or shown
1867    * @param visible true is visible
1868    * @return list
1869    */
1870   public String[] getFeatureGroupsOfState(boolean visible)
1871   {
1872     FeatureRenderer fr = null;
1873     if (alignPanel!=null && (fr=alignPanel.getFeatureRenderer())!=null)
1874     {
1875       return fr.getGroups(visible);
1876     }
1877     return null;
1878   }
1879   /**
1880    * Change the display state for the given feature groups
1881    * @param groups list of group strings
1882    * @param state visible or invisible
1883    */
1884   public void setFeatureGroupState(String[] groups, boolean state) {
1885     FeatureRenderer fr = null;
1886     this.sequenceFeatures.setState(true);
1887     viewport.showSequenceFeatures(true);
1888     if (alignPanel!=null && (fr=alignPanel.getFeatureRenderer())!=null)
1889     {
1890       fr.setGroupState(groups, state);
1891       alignPanel.seqPanel.seqCanvas.repaint();
1892       if (alignPanel.overviewPanel != null)
1893       {
1894         alignPanel.overviewPanel.updateOverviewImage();
1895       }
1896     }
1897   }
1898   public void seqLimits_itemStateChanged()
1899   {
1900     viewport.setShowJVSuffix(seqLimits.getState());
1901     alignPanel.fontChanged();
1902     alignPanel.paintAlignment(true);
1903   }
1904
1905   protected void colourTextMenuItem_actionPerformed()
1906   {
1907     viewport.setColourText(colourTextMenuItem.getState());
1908     alignPanel.paintAlignment(true);
1909   }
1910
1911   protected void wrapMenuItem_actionPerformed()
1912   {
1913     viewport.setWrapAlignment(wrapMenuItem.getState());
1914     alignPanel.setWrapAlignment(wrapMenuItem.getState());
1915     scaleAbove.setEnabled(wrapMenuItem.getState());
1916     scaleLeft.setEnabled(wrapMenuItem.getState());
1917     scaleRight.setEnabled(wrapMenuItem.getState());
1918     alignPanel.paintAlignment(true);
1919   }
1920
1921   public void overviewMenuItem_actionPerformed()
1922   {
1923     if (alignPanel.overviewPanel != null)
1924     {
1925       return;
1926     }
1927
1928     Frame frame = new Frame();
1929     OverviewPanel overview = new OverviewPanel(alignPanel);
1930     frame.add(overview);
1931     // +50 must allow for applet frame window
1932     jalview.bin.JalviewLite.addFrame(frame, "Overview " + this.getTitle(),
1933                                      overview.getPreferredSize().width,
1934                                      overview.getPreferredSize().height + 50);
1935
1936     frame.pack();
1937     frame.addWindowListener(new WindowAdapter()
1938     {
1939       public void windowClosing(WindowEvent e)
1940       {
1941         alignPanel.setOverviewPanel(null);
1942       };
1943     });
1944
1945     alignPanel.setOverviewPanel(overview);
1946
1947   }
1948
1949   void changeColour(ColourSchemeI cs)
1950   {
1951     int threshold = 0;
1952
1953     if (cs != null)
1954     {
1955       if (viewport.getAbovePIDThreshold())
1956       {
1957         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");
1958
1959         cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());
1960
1961         viewport.setGlobalColourScheme(cs);
1962       }
1963       else
1964       {
1965         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
1966       }
1967
1968       if (viewport.getConservationSelected())
1969       {
1970
1971         Alignment al = (Alignment) viewport.alignment;
1972         Conservation c = new Conservation("All",
1973                                           ResidueProperties.propHash, 3,
1974                                           al.getSequences(), 0,
1975                                           al.getWidth() - 1);
1976
1977         c.calculate();
1978         c.verdict(false, viewport.ConsPercGaps);
1979
1980         cs.setConservation(c);
1981
1982         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,
1983             "Background"));
1984
1985       }
1986       else
1987       {
1988         cs.setConservation(null);
1989       }
1990
1991       cs.setConsensus(viewport.hconsensus);
1992
1993     }
1994     viewport.setGlobalColourScheme(cs);
1995
1996     if (viewport.getColourAppliesToAllGroups())
1997     {
1998       Vector groups = viewport.alignment.getGroups();
1999       for (int i = 0; i < groups.size(); i++)
2000       {
2001         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
2002
2003         if (cs == null)
2004         {
2005           sg.cs = null;
2006           continue;
2007         }
2008         if (cs instanceof ClustalxColourScheme)
2009         {
2010           sg.cs = new ClustalxColourScheme(
2011               sg.getSequences(viewport.hiddenRepSequences),
2012               sg.getWidth());
2013         }
2014         else
2015         {
2016           try
2017           {
2018             sg.cs = (ColourSchemeI) cs.getClass().newInstance();
2019           }
2020           catch (Exception ex)
2021           {
2022             ex.printStackTrace();
2023             sg.cs = cs;
2024           }
2025         }
2026
2027         if (viewport.getAbovePIDThreshold()
2028             || cs instanceof PIDColourScheme
2029             || cs instanceof Blosum62ColourScheme)
2030         {
2031           sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());
2032           sg.cs.setConsensus(AAFrequency.calculate(
2033               sg.getSequences(viewport.hiddenRepSequences), 0, sg.getWidth()));
2034         }
2035         else
2036         {
2037           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2038         }
2039
2040         if (viewport.getConservationSelected())
2041         {
2042           Conservation c = new Conservation("Group",
2043                                             ResidueProperties.propHash, 3,
2044                                             sg.getSequences(viewport.
2045               hiddenRepSequences), 0,
2046                                             viewport.alignment.getWidth() - 1);
2047           c.calculate();
2048           c.verdict(false, viewport.ConsPercGaps);
2049           sg.cs.setConservation(c);
2050         }
2051         else
2052         {
2053           sg.cs.setConservation(null);
2054           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2055         }
2056
2057       }
2058     }
2059
2060     if (alignPanel.getOverviewPanel() != null)
2061     {
2062       alignPanel.getOverviewPanel().updateOverviewImage();
2063     }
2064
2065     jalview.structure.StructureSelectionManager.getStructureSelectionManager()
2066         .sequenceColoursChanged(alignPanel);
2067
2068     alignPanel.paintAlignment(true);
2069   }
2070
2071   protected void modifyPID_actionPerformed()
2072   {
2073     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme != null)
2074     {
2075       SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),
2076                                      "Background");
2077       SliderPanel.showPIDSlider();
2078     }
2079   }
2080
2081   protected void modifyConservation_actionPerformed()
2082   {
2083     if (viewport.getConservationSelected() && viewport.globalColourScheme != null)
2084     {
2085       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,
2086                                         "Background");
2087       SliderPanel.showConservationSlider();
2088     }
2089   }
2090
2091   protected void conservationMenuItem_actionPerformed()
2092   {
2093     viewport.setConservationSelected(conservationMenuItem.getState());
2094
2095     viewport.setAbovePIDThreshold(false);
2096     abovePIDThreshold.setState(false);
2097
2098     changeColour(viewport.getGlobalColourScheme());
2099
2100     modifyConservation_actionPerformed();
2101   }
2102
2103   public void abovePIDThreshold_actionPerformed()
2104   {
2105     viewport.setAbovePIDThreshold(abovePIDThreshold.getState());
2106
2107     conservationMenuItem.setState(false);
2108     viewport.setConservationSelected(false);
2109
2110     changeColour(viewport.getGlobalColourScheme());
2111
2112     modifyPID_actionPerformed();
2113   }
2114
2115   public void sortPairwiseMenuItem_actionPerformed()
2116   {
2117     SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
2118     AlignmentSorter.sortByPID(viewport.getAlignment(),
2119                               viewport.getAlignment().getSequenceAt(0));
2120     addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
2121                                     viewport.alignment));
2122     alignPanel.paintAlignment(true);
2123   }
2124
2125   public void sortIDMenuItem_actionPerformed()
2126   {
2127     //  addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,
2128     //                                HistoryItem.SORT));
2129     AlignmentSorter.sortByID(viewport.getAlignment());
2130     alignPanel.paintAlignment(true);
2131   }
2132
2133   public void sortGroupMenuItem_actionPerformed()
2134   {
2135     //  addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,
2136     //                                 HistoryItem.SORT));
2137     AlignmentSorter.sortByGroup(viewport.getAlignment());
2138     alignPanel.paintAlignment(true);
2139
2140   }
2141
2142   public void removeRedundancyMenuItem_actionPerformed()
2143   {
2144     new RedundancyPanel(alignPanel);
2145   }
2146
2147   public void pairwiseAlignmentMenuItem_actionPerformed()
2148   {
2149     if (viewport.getSelectionGroup() != null
2150         && viewport.getSelectionGroup().getSize() > 1)
2151     {
2152       Frame frame = new Frame();
2153       frame.add(new PairwiseAlignPanel(alignPanel));
2154       jalview.bin.JalviewLite.addFrame(frame, "Pairwise Alignment", 600, 500);
2155     }
2156   }
2157
2158   public void PCAMenuItem_actionPerformed()
2159   {
2160     //are the sequences aligned?
2161     if (!viewport.alignment.isAligned())
2162     {
2163       SequenceI current;
2164       int Width = viewport.getAlignment().getWidth();
2165
2166       for (int i = 0; i < viewport.getAlignment().getSequences().size();
2167            i++)
2168       {
2169         current = viewport.getAlignment().getSequenceAt(i);
2170
2171         if (current.getLength() < Width)
2172         {
2173           current.insertCharAt(Width - 1, viewport.getGapCharacter());
2174         }
2175       }
2176       alignPanel.paintAlignment(true);
2177     }
2178
2179     if ( (viewport.getSelectionGroup() != null &&
2180           viewport.getSelectionGroup().getSize() < 4 &&
2181           viewport.getSelectionGroup().getSize() > 0)
2182         || viewport.getAlignment().getHeight() < 4)
2183     {
2184       return;
2185     }
2186
2187     try
2188     {
2189       new PCAPanel(viewport);
2190     }
2191     catch (java.lang.OutOfMemoryError ex)
2192     {
2193     }
2194
2195   }
2196
2197   public void averageDistanceTreeMenuItem_actionPerformed()
2198   {
2199     NewTreePanel("AV", "PID", "Average distance tree using PID");
2200   }
2201
2202   public void neighbourTreeMenuItem_actionPerformed()
2203   {
2204     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
2205   }
2206
2207   protected void njTreeBlosumMenuItem_actionPerformed()
2208   {
2209     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
2210   }
2211
2212   protected void avTreeBlosumMenuItem_actionPerformed()
2213   {
2214     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
2215   }
2216
2217   void NewTreePanel(String type, String pwType, String title)
2218   {
2219     //are the sequences aligned?
2220     if (!viewport.alignment.isAligned())
2221     {
2222       SequenceI current;
2223       int Width = viewport.getAlignment().getWidth();
2224
2225       for (int i = 0; i < viewport.getAlignment().getSequences().size();
2226            i++)
2227       {
2228         current = viewport.getAlignment().getSequenceAt(i);
2229
2230         if (current.getLength() < Width)
2231         {
2232           current.insertCharAt(Width - 1, viewport.getGapCharacter());
2233         }
2234       }
2235       alignPanel.paintAlignment(true);
2236
2237     }
2238
2239     if ( (viewport.getSelectionGroup() != null &&
2240           viewport.getSelectionGroup().getSize() > 1)
2241         || (viewport.getSelectionGroup() == null
2242             && viewport.alignment.getHeight() > 1))
2243     {
2244       final TreePanel tp = new TreePanel(viewport,
2245                                          type,
2246                                          pwType);
2247
2248       addTreeMenuItem(tp, title);
2249
2250       jalview.bin.JalviewLite.addFrame(tp, title, 600, 500);
2251     }
2252   }
2253
2254   void loadTree_actionPerformed()
2255   {
2256     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
2257     cap.setText("Paste your Newick tree file here.");
2258     cap.setTreeImport();
2259     Frame frame = new Frame();
2260     frame.add(cap);
2261     jalview.bin.JalviewLite.addFrame(frame, "Paste Newick file ", 400, 300);
2262   }
2263
2264   public void loadTree(jalview.io.NewickFile tree, String treeFile)
2265   {
2266     TreePanel tp = new TreePanel(viewport,
2267                                  treeFile,
2268                                  "From File - ",
2269                                  tree);
2270     jalview.bin.JalviewLite.addFrame(tp, treeFile, 600, 500);
2271     addTreeMenuItem(tp, treeFile);
2272   }
2273
2274   void addTreeMenuItem(final TreePanel treePanel, String title)
2275   {
2276     final MenuItem item = new MenuItem(title);
2277     sortByTreeMenu.add(item);
2278     item.addActionListener(new java.awt.event.ActionListener()
2279     {
2280       public void actionPerformed(ActionEvent evt)
2281       {
2282         //  addHistoryItem(new HistoryItem("Sort", viewport.alignment,
2283         //                                 HistoryItem.SORT));
2284         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());
2285         alignPanel.paintAlignment(true);
2286       }
2287     });
2288
2289     treePanel.addWindowListener(new WindowAdapter()
2290     {
2291       public void windowClosing(WindowEvent e)
2292       {
2293         sortByTreeMenu.remove(item);
2294       };
2295     });
2296   }
2297
2298   protected void documentation_actionPerformed()
2299   {
2300     showURL("http://www.jalview.org/help.html", "HELP");
2301   }
2302
2303   protected void about_actionPerformed()
2304   {
2305
2306     class AboutPanel
2307         extends Canvas
2308     {
2309       String version;
2310       public AboutPanel(String version)
2311       {
2312         this.version = version;
2313       }
2314
2315       public void paint(Graphics g)
2316       {
2317         g.setColor(Color.white);
2318         g.fillRect(0, 0, getSize().width, getSize().height);
2319         g.setFont(new Font("Helvetica", Font.PLAIN, 12));
2320         FontMetrics fm = g.getFontMetrics();
2321         int fh = fm.getHeight();
2322         int y = 5, x = 7;
2323         g.setColor(Color.black);
2324         g.setFont(new Font("Helvetica", Font.BOLD, 14));
2325         g.drawString("Jalview - Release " + version, 200, y += fh);
2326         g.setFont(new Font("Helvetica", Font.PLAIN, 12));
2327         g.drawString("Authors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",
2328                      x, y += fh * 2);
2329         g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",
2330                      x, y += fh);
2331         g.drawString(
2332             "For any issues relating to Jalview, email help@jalview.org", x,
2333             y += fh);
2334         g.drawString("If  you use JalView, please cite:", x, y += fh + 8);
2335         g.drawString("\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"",
2336                      x, y += fh);
2337         g.drawString("Bioinformatics,  2004 20;426-7.", x, y += fh);
2338       }
2339     }
2340
2341     String version = "test";
2342     java.net.URL url = getClass().getResource("/.build_properties");
2343     if (url != null)
2344     {
2345       try
2346       {
2347         BufferedReader reader = new BufferedReader(new InputStreamReader(
2348             url.openStream()));
2349         String line;
2350         while ( (line = reader.readLine()) != null)
2351         {
2352           if (line.indexOf("VERSION") > -1)
2353           {
2354             version = line.substring(line.indexOf("=") + 1);
2355           }
2356         }
2357       }
2358       catch (Exception ex)
2359       {
2360         ex.printStackTrace();
2361       }
2362     }
2363
2364     Frame frame = new Frame();
2365     frame.add(new AboutPanel(version));
2366     jalview.bin.JalviewLite.addFrame(frame, "Jalview", 580, 200);
2367
2368   }
2369
2370   public void showURL(String url, String target)
2371   {
2372     if (viewport.applet == null)
2373     {
2374       System.out.println("Not running as applet - no browser available.");
2375     }
2376     else
2377     {
2378       try
2379       {
2380         System.out.println("Show url: " + url);
2381         viewport.applet.getAppletContext().showDocument(new java.net.URL(url),
2382             target);
2383       }
2384       catch (Exception ex)
2385       {
2386         ex.printStackTrace();
2387       }
2388     }
2389   }
2390
2391   //////////////////////////////////////////////////////////////////////////////////
2392   //JBuilder Graphics here
2393
2394    MenuBar alignFrameMenuBar = new MenuBar();
2395    Menu fileMenu = new Menu("File");
2396    MenuItem loadApplication = new MenuItem("View in Full Application");
2397    MenuItem loadTree = new MenuItem("Load Associated Tree ...");
2398    MenuItem loadAnnotations = new MenuItem(
2399       "Load Features/Annotations ...");
2400    MenuItem outputFeatures = new MenuItem("Export Features ...");
2401    MenuItem outputAnnotations = new MenuItem("Export Annotations ...");
2402
2403    MenuItem closeMenuItem = new MenuItem("Close");
2404    Menu editMenu = new Menu("Edit");
2405    Menu viewMenu = new Menu("View");
2406    Menu colourMenu = new Menu("Colour");
2407    Menu calculateMenu = new Menu("Calculate");
2408    MenuItem selectAllSequenceMenuItem = new MenuItem("Select all");
2409    MenuItem deselectAllSequenceMenuItem = new MenuItem("Deselect All");
2410    MenuItem invertSequenceMenuItem = new MenuItem("Invert Selection");
2411    MenuItem remove2LeftMenuItem = new MenuItem();
2412    MenuItem remove2RightMenuItem = new MenuItem();
2413    MenuItem removeGappedColumnMenuItem = new MenuItem();
2414    MenuItem removeAllGapsMenuItem = new MenuItem();
2415    CheckboxMenuItem viewBoxesMenuItem = new CheckboxMenuItem();
2416    CheckboxMenuItem viewTextMenuItem = new CheckboxMenuItem();
2417    MenuItem sortPairwiseMenuItem = new MenuItem();
2418    MenuItem sortIDMenuItem = new MenuItem();
2419    MenuItem sortGroupMenuItem = new MenuItem();
2420    MenuItem removeRedundancyMenuItem = new MenuItem();
2421    MenuItem pairwiseAlignmentMenuItem = new MenuItem();
2422    MenuItem PCAMenuItem = new MenuItem();
2423    MenuItem averageDistanceTreeMenuItem = new MenuItem();
2424    MenuItem neighbourTreeMenuItem = new MenuItem();
2425   BorderLayout borderLayout1 = new BorderLayout();
2426   public Label statusBar = new Label();
2427    Menu outputTextboxMenu = new Menu();
2428    MenuItem clustalColour = new MenuItem();
2429    MenuItem zappoColour = new MenuItem();
2430    MenuItem taylorColour = new MenuItem();
2431    MenuItem hydrophobicityColour = new MenuItem();
2432    MenuItem helixColour = new MenuItem();
2433    MenuItem strandColour = new MenuItem();
2434    MenuItem turnColour = new MenuItem();
2435    MenuItem buriedColour = new MenuItem();
2436    MenuItem userDefinedColour = new MenuItem();
2437    MenuItem PIDColour = new MenuItem();
2438    MenuItem BLOSUM62Colour = new MenuItem();
2439   MenuItem njTreeBlosumMenuItem = new MenuItem();
2440   MenuItem avDistanceTreeBlosumMenuItem = new MenuItem();
2441    CheckboxMenuItem annotationPanelMenuItem = new CheckboxMenuItem();
2442    CheckboxMenuItem colourTextMenuItem = new CheckboxMenuItem();
2443    MenuItem alProperties = new MenuItem("Alignment Properties...");
2444   MenuItem overviewMenuItem = new MenuItem();
2445    MenuItem undoMenuItem = new MenuItem();
2446    MenuItem redoMenuItem = new MenuItem();
2447    CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
2448   MenuItem noColourmenuItem = new MenuItem();
2449    CheckboxMenuItem wrapMenuItem = new CheckboxMenuItem();
2450    CheckboxMenuItem renderGapsMenuItem = new CheckboxMenuItem();
2451   MenuItem findMenuItem = new MenuItem();
2452    CheckboxMenuItem abovePIDThreshold = new CheckboxMenuItem();
2453    MenuItem nucleotideColour = new MenuItem();
2454   MenuItem deleteGroups = new MenuItem();
2455   MenuItem delete = new MenuItem();
2456   MenuItem copy = new MenuItem();
2457   MenuItem cut = new MenuItem();
2458   Menu pasteMenu = new Menu();
2459   MenuItem pasteNew = new MenuItem();
2460   MenuItem pasteThis = new MenuItem();
2461    CheckboxMenuItem applyToAllGroups = new CheckboxMenuItem();
2462    MenuItem font = new MenuItem();
2463    CheckboxMenuItem scaleAbove = new CheckboxMenuItem();
2464    CheckboxMenuItem scaleLeft = new CheckboxMenuItem();
2465    CheckboxMenuItem scaleRight = new CheckboxMenuItem();
2466   MenuItem modifyPID = new MenuItem();
2467   MenuItem modifyConservation = new MenuItem();
2468    CheckboxMenuItem autoCalculate
2469       = new CheckboxMenuItem("Autocalculate Consensus", true);
2470    Menu sortByTreeMenu = new Menu();
2471   Menu sort = new Menu();
2472   Menu calculate = new Menu();
2473   MenuItem inputText = new MenuItem();
2474   Menu helpMenu = new Menu();
2475   MenuItem documentation = new MenuItem();
2476   MenuItem about = new MenuItem();
2477    CheckboxMenuItem seqLimits = new CheckboxMenuItem();
2478   Panel embeddedMenu;
2479   Label embeddedEdit;
2480   Label embeddedSelect;
2481   Label embeddedView;
2482   Label embeddedFormat;
2483   Label embeddedColour;
2484   Label embeddedFile;
2485   Label embeddedHelp;
2486   Label embeddedCalculate;
2487   FlowLayout flowLayout1;
2488
2489   private void jbInit()
2490       throws Exception
2491   {
2492
2493     setMenuBar(alignFrameMenuBar);
2494
2495     MenuItem item;
2496
2497     // dynamically fill save as menu with available formats
2498     for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length;
2499          i++)
2500     {
2501
2502       item = new MenuItem(jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]);
2503
2504       item.addActionListener(new java.awt.event.ActionListener()
2505       {
2506         public void actionPerformed(ActionEvent e)
2507         {
2508           outputText_actionPerformed(e);
2509         }
2510       });
2511
2512       outputTextboxMenu.add(item);
2513     }
2514     closeMenuItem.addActionListener(this);
2515     loadApplication.addActionListener(this);
2516
2517     loadTree.addActionListener(this);
2518     loadAnnotations.addActionListener(this);
2519     outputFeatures.addActionListener(this);
2520     outputAnnotations.addActionListener(this);
2521     selectAllSequenceMenuItem.addActionListener(this);
2522     deselectAllSequenceMenuItem.addActionListener(this);
2523     invertSequenceMenuItem.addActionListener(this);
2524     remove2LeftMenuItem.setLabel("Remove Left");
2525     remove2LeftMenuItem.addActionListener(this);
2526     remove2RightMenuItem.setLabel("Remove Right");
2527     remove2RightMenuItem.addActionListener(this);
2528     removeGappedColumnMenuItem.setLabel("Remove Empty Columns");
2529     removeGappedColumnMenuItem.addActionListener(this);
2530     removeAllGapsMenuItem.setLabel("Remove All Gaps");
2531     removeAllGapsMenuItem.addActionListener(this);
2532     viewBoxesMenuItem.setLabel("Boxes");
2533     viewBoxesMenuItem.setState(true);
2534     viewBoxesMenuItem.addItemListener(this);
2535     viewTextMenuItem.setLabel("Text");
2536     viewTextMenuItem.setState(true);
2537     viewTextMenuItem.addItemListener(this);
2538     sortPairwiseMenuItem.setLabel("by Pairwise Identity");
2539     sortPairwiseMenuItem.addActionListener(this);
2540     sortIDMenuItem.setLabel("by ID");
2541     sortIDMenuItem.addActionListener(this);
2542     sortGroupMenuItem.setLabel("by Group");
2543     sortGroupMenuItem.addActionListener(this);
2544     removeRedundancyMenuItem.setLabel("Remove Redundancy...");
2545     removeRedundancyMenuItem.addActionListener(this);
2546     pairwiseAlignmentMenuItem.setLabel("Pairwise Alignments...");
2547     pairwiseAlignmentMenuItem.addActionListener(this);
2548     PCAMenuItem.setLabel("Principal Component Analysis");
2549     PCAMenuItem.addActionListener(this);
2550     averageDistanceTreeMenuItem.setLabel(
2551         "Average Distance Using % Identity");
2552     averageDistanceTreeMenuItem.addActionListener(this);
2553     neighbourTreeMenuItem.setLabel("Neighbour Joining Using % Identity");
2554     neighbourTreeMenuItem.addActionListener(this);
2555     statusBar.setBackground(Color.white);
2556     statusBar.setFont(new java.awt.Font("Verdana", 0, 11));
2557     statusBar.setText("Status bar");
2558     outputTextboxMenu.setLabel("Output to Textbox");
2559     clustalColour.setLabel("Clustalx");
2560
2561     clustalColour.addActionListener(this);
2562     zappoColour.setLabel("Zappo");
2563     zappoColour.addActionListener(this);
2564     taylorColour.setLabel("Taylor");
2565     taylorColour.addActionListener(this);
2566     hydrophobicityColour.setLabel("Hydrophobicity");
2567     hydrophobicityColour.addActionListener(this);
2568     helixColour.setLabel("Helix Propensity");
2569     helixColour.addActionListener(this);
2570     strandColour.setLabel("Strand Propensity");
2571     strandColour.addActionListener(this);
2572     turnColour.setLabel("Turn Propensity");
2573     turnColour.addActionListener(this);
2574     buriedColour.setLabel("Buried Index");
2575     buriedColour.addActionListener(this);
2576     userDefinedColour.setLabel("User Defined...");
2577     userDefinedColour.addActionListener(this);
2578     PIDColour.setLabel("Percentage Identity");
2579     PIDColour.addActionListener(this);
2580     BLOSUM62Colour.setLabel("BLOSUM62 Score");
2581     BLOSUM62Colour.addActionListener(this);
2582     avDistanceTreeBlosumMenuItem.setLabel(
2583         "Average Distance Using BLOSUM62");
2584     avDistanceTreeBlosumMenuItem.addActionListener(this);
2585     njTreeBlosumMenuItem.setLabel("Neighbour Joining Using BLOSUM62");
2586     njTreeBlosumMenuItem.addActionListener(this);
2587     annotationPanelMenuItem.setLabel("Show Annotations");
2588     annotationPanelMenuItem.addItemListener(this);
2589     colourTextMenuItem.setLabel("Colour Text");
2590     colourTextMenuItem.addItemListener(this);
2591     alProperties.addActionListener(this);
2592     overviewMenuItem.setLabel("Overview Window");
2593     overviewMenuItem.addActionListener(this);
2594     undoMenuItem.setEnabled(false);
2595     undoMenuItem.setLabel("Undo");
2596     undoMenuItem.addActionListener(this);
2597     redoMenuItem.setEnabled(false);
2598     redoMenuItem.setLabel("Redo");
2599     redoMenuItem.addActionListener(this);
2600     conservationMenuItem.setLabel("by Conservation");
2601     conservationMenuItem.addItemListener(this);
2602     noColourmenuItem.setLabel("None");
2603     noColourmenuItem.addActionListener(this);
2604     wrapMenuItem.setLabel("Wrap");
2605     wrapMenuItem.addItemListener(this);
2606     renderGapsMenuItem.setLabel("Show Gaps");
2607     renderGapsMenuItem.setState(true);
2608     renderGapsMenuItem.addItemListener(this);
2609     findMenuItem.setLabel("Find...");
2610     findMenuItem.addActionListener(this);
2611     abovePIDThreshold.setLabel("Above Identity Threshold");
2612     abovePIDThreshold.addItemListener(this);
2613     nucleotideColour.setLabel("Nucleotide");
2614     nucleotideColour.addActionListener(this);
2615     deleteGroups.setLabel("Undefine Groups");
2616     deleteGroups.addActionListener(this);
2617     copy.setLabel("Copy");
2618     copy.addActionListener(this);
2619     cut.setLabel("Cut");
2620     cut.addActionListener(this);
2621     delete.setLabel("Delete");
2622     delete.addActionListener(this);
2623     pasteMenu.setLabel("Paste");
2624     pasteNew.setLabel("To New Alignment");
2625     pasteNew.addActionListener(this);
2626     pasteThis.setLabel("Add To This Alignment");
2627     pasteThis.addActionListener(this);
2628     applyToAllGroups.setLabel("Apply Colour To All Groups");
2629     applyToAllGroups.setState(true);
2630     applyToAllGroups.addItemListener(this);
2631     font.setLabel("Font...");
2632     font.addActionListener(this);
2633     scaleAbove.setLabel("Scale Above");
2634     scaleAbove.setState(true);
2635     scaleAbove.setEnabled(false);
2636     scaleAbove.addItemListener(this);
2637     scaleLeft.setEnabled(false);
2638     scaleLeft.setState(true);
2639     scaleLeft.setLabel("Scale Left");
2640     scaleLeft.addItemListener(this);
2641     scaleRight.setEnabled(false);
2642     scaleRight.setState(true);
2643     scaleRight.setLabel("Scale Right");
2644     scaleRight.addItemListener(this);
2645     modifyPID.setLabel("Modify Identity Threshold...");
2646     modifyPID.addActionListener(this);
2647     modifyConservation.setLabel("Modify Conservation Threshold...");
2648     modifyConservation.addActionListener(this);
2649     sortByTreeMenu.setLabel("By Tree Order");
2650     sort.setLabel("Sort");
2651     calculate.setLabel("Calculate Tree");
2652     autoCalculate.addItemListener(this);
2653     inputText.setLabel("Input from textbox");
2654     inputText.addActionListener(this);
2655
2656     helpMenu.setLabel("Help");
2657     documentation.setLabel("Documentation");
2658     documentation.addActionListener(this);
2659
2660     about.setLabel("About...");
2661     about.addActionListener(this);
2662     seqLimits.setState(true);
2663     seqLimits.setLabel("Show Sequence Limits");
2664     seqLimits.addItemListener(this);
2665     featureSettings.setLabel("Feature Settings...");
2666     featureSettings.addActionListener(this);
2667     sequenceFeatures.setLabel("Sequence Features");
2668     sequenceFeatures.addItemListener(this);
2669     sequenceFeatures.setState(false);
2670     annotationColour.setLabel("by Annotation...");
2671     annotationColour.addActionListener(this);
2672     invertSequenceMenuItem.setLabel("Invert Sequence Selection");
2673     invertColSel.setLabel("Invert Column Selection");
2674     menu1.setLabel("Show");
2675     showColumns.setLabel("All Columns ");
2676     showSeqs.setLabel("All Sequences");
2677     menu2.setLabel("Hide");
2678     hideColumns.setLabel("Selected Columns");
2679     hideSequences.setLabel("Selected Sequences");
2680     invertColSel.addActionListener(this);
2681     showColumns.addActionListener(this);
2682     showSeqs.addActionListener(this);
2683     hideColumns.addActionListener(this);
2684     hideSequences.addActionListener(this);
2685     formatMenu.setLabel("Format");
2686     selectMenu.setLabel("Select");
2687     newView.setLabel("New View");
2688     newView.addActionListener(this);
2689     alignFrameMenuBar.add(fileMenu);
2690     alignFrameMenuBar.add(editMenu);
2691     alignFrameMenuBar.add(selectMenu);
2692     alignFrameMenuBar.add(viewMenu);
2693     alignFrameMenuBar.add(formatMenu);
2694     alignFrameMenuBar.add(colourMenu);
2695     alignFrameMenuBar.add(calculateMenu);
2696     alignFrameMenuBar.add(helpMenu);
2697
2698     fileMenu.add(inputText);
2699     fileMenu.add(loadTree);
2700     fileMenu.add(loadAnnotations);
2701
2702     fileMenu.addSeparator();
2703     fileMenu.add(outputTextboxMenu);
2704     fileMenu.add(outputFeatures);
2705     fileMenu.add(outputAnnotations);
2706
2707     if (jalviewServletURL != null)
2708     {
2709       fileMenu.add(loadApplication);
2710     }
2711
2712     fileMenu.addSeparator();
2713     fileMenu.add(closeMenuItem);
2714
2715     editMenu.add(undoMenuItem);
2716     editMenu.add(redoMenuItem);
2717     editMenu.add(cut);
2718     editMenu.add(copy);
2719     editMenu.add(pasteMenu);
2720     editMenu.add(delete);
2721     editMenu.addSeparator();
2722     editMenu.add(remove2LeftMenuItem);
2723     editMenu.add(remove2RightMenuItem);
2724     editMenu.add(removeGappedColumnMenuItem);
2725     editMenu.add(removeAllGapsMenuItem);
2726     editMenu.add(removeRedundancyMenuItem);
2727     viewMenu.add(newView);
2728     viewMenu.addSeparator();
2729     viewMenu.add(menu1);
2730     viewMenu.add(menu2);
2731     viewMenu.addSeparator();
2732     viewMenu.add(annotationPanelMenuItem);
2733     viewMenu.addSeparator();
2734     viewMenu.add(sequenceFeatures);
2735     viewMenu.add(featureSettings);
2736     viewMenu.addSeparator();
2737     viewMenu.add(alProperties);
2738     viewMenu.addSeparator();
2739     viewMenu.add(overviewMenuItem);
2740     colourMenu.add(applyToAllGroups);
2741     colourMenu.addSeparator();
2742     colourMenu.add(noColourmenuItem);
2743     colourMenu.add(clustalColour);
2744     colourMenu.add(BLOSUM62Colour);
2745     colourMenu.add(PIDColour);
2746     colourMenu.add(zappoColour);
2747     colourMenu.add(taylorColour);
2748     colourMenu.add(hydrophobicityColour);
2749     colourMenu.add(helixColour);
2750     colourMenu.add(strandColour);
2751     colourMenu.add(turnColour);
2752     colourMenu.add(buriedColour);
2753     colourMenu.add(nucleotideColour);
2754     colourMenu.add(userDefinedColour);
2755     colourMenu.addSeparator();
2756     colourMenu.add(conservationMenuItem);
2757     colourMenu.add(modifyConservation);
2758     colourMenu.add(abovePIDThreshold);
2759     colourMenu.add(modifyPID);
2760     colourMenu.add(annotationColour);
2761     calculateMenu.add(sort);
2762     calculateMenu.add(calculate);
2763     calculateMenu.addSeparator();
2764     calculateMenu.add(pairwiseAlignmentMenuItem);
2765     calculateMenu.add(PCAMenuItem);
2766     calculateMenu.add(autoCalculate);
2767     this.add(statusBar, BorderLayout.SOUTH);
2768     pasteMenu.add(pasteNew);
2769     pasteMenu.add(pasteThis);
2770     sort.add(sortIDMenuItem);
2771     sort.add(sortByTreeMenu);
2772     sort.add(sortGroupMenuItem);
2773     sort.add(sortPairwiseMenuItem);
2774     calculate.add(averageDistanceTreeMenuItem);
2775     calculate.add(neighbourTreeMenuItem);
2776     calculate.add(avDistanceTreeBlosumMenuItem);
2777     calculate.add(njTreeBlosumMenuItem);
2778     helpMenu.add(documentation);
2779     helpMenu.add(about);
2780     menu1.add(showColumns);
2781     menu1.add(showSeqs);
2782     menu2.add(hideColumns);
2783     menu2.add(hideSequences);
2784     formatMenu.add(font);
2785     formatMenu.add(seqLimits);
2786     formatMenu.add(wrapMenuItem);
2787     formatMenu.add(scaleAbove);
2788     formatMenu.add(scaleLeft);
2789     formatMenu.add(scaleRight);
2790     formatMenu.add(viewBoxesMenuItem);
2791     formatMenu.add(viewTextMenuItem);
2792     formatMenu.add(colourTextMenuItem);
2793     formatMenu.add(renderGapsMenuItem);
2794     selectMenu.add(findMenuItem);
2795     selectMenu.addSeparator();
2796     selectMenu.add(selectAllSequenceMenuItem);
2797     selectMenu.add(deselectAllSequenceMenuItem);
2798     selectMenu.add(invertSequenceMenuItem);
2799     selectMenu.add(invertColSel);
2800     selectMenu.add(deleteGroups);
2801   }
2802
2803   public void setEmbedded()
2804   {
2805
2806     embeddedMenu = new Panel();
2807     embeddedEdit = new Label("Edit");
2808     embeddedSelect = new Label("Select");
2809     embeddedView = new Label("View");
2810     embeddedFormat = new Label("Format");
2811     embeddedColour = new Label("Colour");
2812     embeddedFile = new Label("File");
2813     embeddedHelp = new Label("Help");
2814     embeddedCalculate = new Label("Calculate");
2815     flowLayout1 = new FlowLayout();
2816     embeddedMenu.setBackground(Color.lightGray);
2817     embeddedMenu.setLayout(flowLayout1);
2818     embeddedEdit.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2819     embeddedSelect.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2820     embeddedView.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2821     embeddedFormat.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2822     embeddedColour.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2823     embeddedFile.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2824     embeddedHelp.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2825     embeddedCalculate.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
2826     embeddedMenu.add(embeddedFile);
2827     embeddedMenu.add(embeddedEdit);
2828     embeddedMenu.add(embeddedSelect);
2829     embeddedMenu.add(embeddedView);
2830     embeddedMenu.add(embeddedFormat);
2831     embeddedMenu.add(embeddedColour);
2832     embeddedMenu.add(embeddedCalculate);
2833     embeddedMenu.add(embeddedHelp);
2834     flowLayout1.setAlignment(FlowLayout.LEFT);
2835     flowLayout1.setHgap(2);
2836     flowLayout1.setVgap(0);
2837     embeddedFile.addMouseListener(this);
2838     embeddedEdit.addMouseListener(this);
2839     embeddedSelect.addMouseListener(this);
2840     embeddedView.addMouseListener(this);
2841     embeddedFormat.addMouseListener(this);
2842     embeddedColour.addMouseListener(this);
2843     embeddedCalculate.addMouseListener(this);
2844     embeddedHelp.addMouseListener(this);
2845
2846     fileMenu.remove(closeMenuItem);
2847     fileMenu.remove(3); // Seperator
2848
2849     viewport.applet.setLayout(new BorderLayout());
2850     viewport.applet.add(embeddedMenu, BorderLayout.NORTH);
2851     viewport.applet.add(statusBar, BorderLayout.SOUTH);
2852
2853     alignPanel.setSize(viewport.applet.getSize().width,
2854                        viewport.applet.getSize().height
2855                        - embeddedMenu.HEIGHT - statusBar.HEIGHT);
2856
2857     viewport.applet.add(alignPanel, BorderLayout.CENTER);
2858     viewport.applet.validate();
2859
2860   }
2861
2862   PopupMenu filePopup, editPopup, searchPopup,
2863   viewPopup, formatPopup, colourPopup, calculatePopup, helpPopup;
2864   MenuItem featureSettings = new MenuItem();
2865   CheckboxMenuItem sequenceFeatures = new CheckboxMenuItem();
2866   MenuItem annotationColour = new MenuItem();
2867   MenuItem invertColSel = new MenuItem();
2868   Menu menu1 = new Menu();
2869   MenuItem showColumns = new MenuItem();
2870   MenuItem showSeqs = new MenuItem();
2871   Menu menu2 = new Menu();
2872   MenuItem hideColumns = new MenuItem();
2873   MenuItem hideSequences = new MenuItem();
2874   Menu formatMenu = new Menu();
2875   Menu selectMenu = new Menu();
2876   MenuItem newView = new MenuItem();
2877
2878   public void mousePressed(MouseEvent evt)
2879   {
2880     PopupMenu popup = null;
2881     Label source = (Label) evt.getSource();
2882     if (source == embeddedFile)
2883     {
2884       popup = filePopup = genPopupMenu(filePopup, fileMenu);
2885     }
2886     else if (source == embeddedEdit)
2887     {
2888       popup = editPopup = genPopupMenu(editPopup, editMenu);
2889     }
2890     else if (source == embeddedSelect)
2891     {
2892       popup = searchPopup = genPopupMenu(searchPopup, selectMenu);
2893     }
2894     else if (source == embeddedView)
2895     {
2896       popup = viewPopup = genPopupMenu(viewPopup, viewMenu);
2897     }
2898     else if (source == embeddedFormat)
2899     {
2900       popup = formatPopup = genPopupMenu(formatPopup, formatMenu);
2901     }
2902     else if (source == embeddedColour)
2903     {
2904       popup = colourPopup = genPopupMenu(colourPopup, colourMenu);
2905     }
2906     else if (source == embeddedCalculate)
2907     {
2908       popup = calculatePopup = genPopupMenu(calculatePopup, calculateMenu);
2909     }
2910     else if (source == embeddedHelp)
2911     {
2912       popup = helpPopup = genPopupMenu(helpPopup, helpMenu);
2913     }
2914
2915     embeddedMenu.add(popup);
2916     popup.show(embeddedMenu,
2917                source.getBounds().x,
2918                source.getBounds().y + source.getBounds().getSize().height);
2919   }
2920
2921   PopupMenu genPopupMenu(PopupMenu popup, Menu original)
2922   {
2923     if (popup != null)
2924     {
2925       return popup;
2926     }
2927     popup = new PopupMenu();
2928     int m, mSize = original.getItemCount();
2929     for (m = 0; m < mSize; m++)
2930     {
2931       popup.add(original.getItem(m));
2932       mSize--;
2933       m--;
2934     }
2935
2936     return popup;
2937   }
2938
2939   public void mouseClicked(MouseEvent evt)
2940   {}
2941
2942   public void mouseReleased(MouseEvent evt)
2943   {}
2944
2945   public void mouseEntered(MouseEvent evt)
2946   {}
2947
2948   public void mouseExited(MouseEvent evt)
2949   {}
2950
2951 }