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