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