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