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