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