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