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