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