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