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