0957d28d1042e22f693c54055e504a0bf2f9800b
[jalview.git] / src / jalview / gui / PopupMenu.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import jalview.analysis.AAFrequency;
24 import jalview.analysis.Conservation;
25 import jalview.commands.ChangeCaseCommand;
26 import jalview.commands.EditCommand;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.AlignmentView;
30 import jalview.datamodel.Annotation;
31 import jalview.datamodel.DBRefEntry;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.Sequence;
34 import jalview.datamodel.SequenceFeature;
35 import jalview.datamodel.SequenceGroup;
36 import jalview.datamodel.SequenceI;
37 import jalview.io.FormatAdapter;
38 import jalview.io.SequenceAnnotationReport;
39 import jalview.schemes.AnnotationColourGradient;
40 import jalview.schemes.Blosum62ColourScheme;
41 import jalview.schemes.BuriedColourScheme;
42 import jalview.schemes.ClustalxColourScheme;
43 import jalview.schemes.HelixColourScheme;
44 import jalview.schemes.HydrophobicColourScheme;
45 import jalview.schemes.NucleotideColourScheme;
46 import jalview.schemes.PIDColourScheme;
47 import jalview.schemes.PurinePyrimidineColourScheme;
48 import jalview.schemes.ResidueProperties;
49 import jalview.schemes.StrandColourScheme;
50 import jalview.schemes.TaylorColourScheme;
51 import jalview.schemes.TurnColourScheme;
52 import jalview.schemes.UserColourScheme;
53 import jalview.schemes.ZappoColourScheme;
54 import jalview.util.GroupUrlLink;
55 import jalview.util.GroupUrlLink.UrlStringTooLongException;
56 import jalview.util.MessageManager;
57 import jalview.util.UrlLink;
58
59 import java.awt.Color;
60 import java.awt.event.ActionEvent;
61 import java.awt.event.ActionListener;
62 import java.util.Hashtable;
63 import java.util.List;
64 import java.util.Vector;
65
66 import javax.swing.ButtonGroup;
67 import javax.swing.JCheckBoxMenuItem;
68 import javax.swing.JColorChooser;
69 import javax.swing.JMenu;
70 import javax.swing.JMenuItem;
71 import javax.swing.JOptionPane;
72 import javax.swing.JPopupMenu;
73 import javax.swing.JRadioButtonMenuItem;
74
75 /**
76  * DOCUMENT ME!
77  * 
78  * @author $author$
79  * @version $Revision: 1.118 $
80  */
81 public class PopupMenu extends JPopupMenu
82 {
83   JMenu groupMenu = new JMenu();
84
85   JMenuItem groupName = new JMenuItem();
86
87   protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();
88
89   protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();
90
91   protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();
92
93   protected JRadioButtonMenuItem hydrophobicityColour = new JRadioButtonMenuItem();
94
95   protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();
96
97   protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();
98
99   protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
100
101   protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
102
103   protected JCheckBoxMenuItem abovePIDColour = new JCheckBoxMenuItem();
104
105   protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();
106
107   protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();
108
109   protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();
110
111   protected JRadioButtonMenuItem purinePyrimidineColour = new JRadioButtonMenuItem();
112
113   protected JRadioButtonMenuItem RNAInteractionColour = new JRadioButtonMenuItem();
114
115   // protected JRadioButtonMenuItem covariationColour = new
116   // JRadioButtonMenuItem();
117
118   JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();
119
120   protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
121
122   AlignmentPanel ap;
123
124   JMenu sequenceMenu = new JMenu();
125
126   JMenuItem sequenceName = new JMenuItem();
127
128   JMenuItem sequenceDetails = new JMenuItem();
129
130   JMenuItem sequenceSelDetails = new JMenuItem();
131
132   SequenceI sequence;
133
134   JMenuItem createGroupMenuItem = new JMenuItem();
135
136   JMenuItem unGroupMenuItem = new JMenuItem();
137
138   JMenuItem outline = new JMenuItem();
139
140   JRadioButtonMenuItem nucleotideMenuItem = new JRadioButtonMenuItem();
141
142   JMenu colourMenu = new JMenu();
143
144   JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem();
145
146   JCheckBoxMenuItem showText = new JCheckBoxMenuItem();
147
148   JCheckBoxMenuItem showColourText = new JCheckBoxMenuItem();
149
150   JCheckBoxMenuItem displayNonconserved = new JCheckBoxMenuItem();
151
152   JMenu editMenu = new JMenu();
153
154   JMenuItem cut = new JMenuItem();
155
156   JMenuItem copy = new JMenuItem();
157
158   JMenuItem upperCase = new JMenuItem();
159
160   JMenuItem lowerCase = new JMenuItem();
161
162   JMenuItem toggle = new JMenuItem();
163
164   JMenu pdbMenu = new JMenu();
165
166   JMenuItem pdbFromFile = new JMenuItem();
167
168   // JBPNote: Commented these out - Should add these services via the web
169   // services menu system.
170   // JMenuItem ContraFold = new JMenuItem();
171
172   // JMenuItem RNAFold = new JMenuItem();
173
174   JMenuItem enterPDB = new JMenuItem();
175
176   JMenuItem discoverPDB = new JMenuItem();
177
178   JMenu outputMenu = new JMenu();
179
180   JMenuItem sequenceFeature = new JMenuItem();
181
182   JMenuItem textColour = new JMenuItem();
183
184   JMenu jMenu1 = new JMenu();
185
186   JMenu structureMenu = new JMenu();
187
188   JMenu viewStructureMenu = new JMenu();
189
190   // JMenu colStructureMenu = new JMenu();
191   JMenuItem editSequence = new JMenuItem();
192
193   // JMenuItem annotationMenuItem = new JMenuItem();
194
195   JMenu groupLinksMenu;
196
197   /**
198    * Creates a new PopupMenu object.
199    * 
200    * @param ap
201    *          DOCUMENT ME!
202    * @param seq
203    *          DOCUMENT ME!
204    */
205   public PopupMenu(final AlignmentPanel ap, Sequence seq, Vector links)
206   {
207     this(ap, seq, links, null);
208   }
209
210   /**
211    * 
212    * @param ap
213    * @param seq
214    * @param links
215    * @param groupLinks
216    */
217   public PopupMenu(final AlignmentPanel ap, final SequenceI seq,
218           Vector links, Vector groupLinks)
219   {
220     // /////////////////////////////////////////////////////////
221     // If this is activated from the sequence panel, the user may want to
222     // edit or annotate a particular residue. Therefore display the residue menu
223     //
224     // If from the IDPanel, we must display the sequence menu
225     // ////////////////////////////////////////////////////////
226     this.ap = ap;
227     sequence = seq;
228
229     ButtonGroup colours = new ButtonGroup();
230     colours.add(noColourmenuItem);
231     colours.add(clustalColour);
232     colours.add(zappoColour);
233     colours.add(taylorColour);
234     colours.add(hydrophobicityColour);
235     colours.add(helixColour);
236     colours.add(strandColour);
237     colours.add(turnColour);
238     colours.add(buriedColour);
239     colours.add(abovePIDColour);
240     colours.add(userDefinedColour);
241     colours.add(PIDColour);
242     colours.add(BLOSUM62Colour);
243     colours.add(purinePyrimidineColour);
244     colours.add(RNAInteractionColour);
245     // colours.add(covariationColour);
246
247     for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++)
248     {
249       JMenuItem item = new JMenuItem(
250               jalview.io.FormatAdapter.WRITEABLE_FORMATS[i]);
251
252       item.addActionListener(new java.awt.event.ActionListener()
253       {
254         public void actionPerformed(ActionEvent e)
255         {
256           outputText_actionPerformed(e);
257         }
258       });
259
260       outputMenu.add(item);
261     }
262
263     try
264     {
265       jbInit();
266     } catch (Exception e)
267     {
268       e.printStackTrace();
269     }
270
271     JMenuItem menuItem;
272     if (seq != null)
273     {
274       sequenceMenu.setText(sequence.getName());
275
276       if (seq.getDatasetSequence().getPDBId() != null
277               && seq.getDatasetSequence().getPDBId().size() > 0)
278       {
279         java.util.Enumeration e = seq.getDatasetSequence().getPDBId()
280                 .elements();
281
282         while (e.hasMoreElements())
283         {
284           final PDBEntry pdb = (PDBEntry) e.nextElement();
285
286           menuItem = new JMenuItem();
287           menuItem.setText(pdb.getId());
288           menuItem.addActionListener(new java.awt.event.ActionListener()
289           {
290             public void actionPerformed(ActionEvent e)
291             {
292               // TODO re JAL-860: optionally open dialog or provide a menu entry
293               // allowing user to open just one structure per sequence
294               // new AppJmol(pdb, ap.av.collateForPDB(new PDBEntry[]
295               // { pdb })[0], null, ap);
296               new StructureViewer(ap.getStructureSelectionManager())
297                       .viewStructures(pdb,
298                               ap.av.collateForPDB(new PDBEntry[]
299                               { pdb })[0], null, ap);
300             }
301
302           });
303           viewStructureMenu.add(menuItem);
304
305           /*
306            * menuItem = new JMenuItem(); menuItem.setText(pdb.getId());
307            * menuItem.addActionListener(new java.awt.event.ActionListener() {
308            * public void actionPerformed(ActionEvent e) {
309            * colourByStructure(pdb.getId()); } });
310            * colStructureMenu.add(menuItem);
311            */
312         }
313       }
314       else
315       {
316         if (ap.av.getAlignment().isNucleotide() == false)
317         {
318           structureMenu.remove(viewStructureMenu);
319         }
320         // structureMenu.remove(colStructureMenu);
321       }
322
323       if (ap.av.getAlignment().isNucleotide() == true)
324       {
325         AlignmentAnnotation[] aa = ap.av.getAlignment()
326                 .getAlignmentAnnotation();
327         for (int i = 0; i < aa.length; i++)
328         {
329           if (aa[i].getRNAStruc() != null)
330           {
331             final String rnastruc = aa[i].getRNAStruc();
332             final String structureLine = aa[i].label;
333             menuItem = new JMenuItem();
334             menuItem.setText(MessageManager.formatMessage(
335                     "label.2d_rna_structure_line", new String[]
336                     { structureLine }));
337             menuItem.addActionListener(new java.awt.event.ActionListener()
338
339             {
340               public void actionPerformed(ActionEvent e)
341               {
342                 // System.out.println("1:"+structureLine);
343                 System.out.println("1:sname" + seq.getName());
344                 System.out.println("2:seq" + seq);
345
346                 // System.out.println("3:"+seq.getSequenceAsString());
347                 System.out.println("3:strucseq" + rnastruc);
348                 // System.out.println("4:struc"+seq.getRNA());
349                 System.out.println("5:name" + seq.getName());
350                 System.out.println("6:ap" + ap);
351                 new AppVarna(structureLine, seq, seq.getSequenceAsString(),
352                         rnastruc, seq.getName(), ap);
353                 // new AppVarna(seq.getName(),seq,rnastruc,seq.getRNA(),
354                 // seq.getName(), ap);
355                 System.out.println("end");
356               }
357             });
358             viewStructureMenu.add(menuItem);
359           }
360         }
361
362         // SequenceFeatures[] test = seq.getSequenceFeatures();
363
364         if (seq.getAnnotation() != null)
365         {
366           AlignmentAnnotation seqAnno[] = seq.getAnnotation();
367           for (int i = 0; i < seqAnno.length; i++)
368           {
369             if (seqAnno[i].getRNAStruc() != null)
370             {
371               final String rnastruc = seqAnno[i].getRNAStruc();
372
373               // TODO: make rnastrucF a bit more nice
374               menuItem = new JMenuItem();
375               menuItem.setText(MessageManager.formatMessage(
376                       "label.2d_rna_sequence_name", new String[]
377                       { seq.getName() }));
378               menuItem.addActionListener(new java.awt.event.ActionListener()
379               {
380                 public void actionPerformed(ActionEvent e)
381                 {
382                   // TODO: VARNA does'nt print gaps in the sequence
383
384                   new AppVarna(seq.getName() + " structure", seq, seq
385                           .getSequenceAsString(), rnastruc, seq.getName(),
386                           ap);
387                 }
388               });
389               viewStructureMenu.add(menuItem);
390             }
391           }
392         }
393
394       }
395
396       menuItem = new JMenuItem(
397               MessageManager.getString("action.hide_sequences"));
398       menuItem.addActionListener(new java.awt.event.ActionListener()
399       {
400         public void actionPerformed(ActionEvent e)
401         {
402           hideSequences(false);
403         }
404       });
405       add(menuItem);
406
407       if (ap.av.getSelectionGroup() != null
408               && ap.av.getSelectionGroup().getSize() > 1)
409       {
410         menuItem = new JMenuItem(MessageManager.formatMessage(
411                 "label.represent_group_with", new String[]
412                 { seq.getName() }));
413         menuItem.addActionListener(new java.awt.event.ActionListener()
414         {
415           public void actionPerformed(ActionEvent e)
416           {
417             hideSequences(true);
418           }
419         });
420         sequenceMenu.add(menuItem);
421       }
422
423       if (ap.av.hasHiddenRows())
424       {
425         final int index = ap.av.getAlignment().findIndex(seq);
426
427         if (ap.av.adjustForHiddenSeqs(index)
428                 - ap.av.adjustForHiddenSeqs(index - 1) > 1)
429         {
430           menuItem = new JMenuItem(
431                   MessageManager.getString("action.reveal_sequences"));
432           menuItem.addActionListener(new ActionListener()
433           {
434             public void actionPerformed(ActionEvent e)
435             {
436               ap.av.showSequence(index);
437               if (ap.overviewPanel != null)
438               {
439                 ap.overviewPanel.updateOverviewImage();
440               }
441             }
442           });
443           add(menuItem);
444         }
445       }
446     }
447     // for the case when no sequences are even visible
448     if (ap.av.hasHiddenRows())
449     {
450       {
451         menuItem = new JMenuItem(
452                 MessageManager.getString("action.reveal_all"));
453         menuItem.addActionListener(new ActionListener()
454         {
455           public void actionPerformed(ActionEvent e)
456           {
457             ap.av.showAllHiddenSeqs();
458             if (ap.overviewPanel != null)
459             {
460               ap.overviewPanel.updateOverviewImage();
461             }
462           }
463         });
464
465         add(menuItem);
466       }
467
468     }
469
470     SequenceGroup sg = ap.av.getSelectionGroup();
471     boolean isDefinedGroup = (sg != null) ? ap.av.getAlignment()
472             .getGroups().contains(sg) : false;
473
474     if (sg != null && sg.getSize() > 0)
475     {
476       groupName.setText(MessageManager.formatMessage("label.name_param",
477               new String[]
478               { sg.getName() }));
479       groupName.setText(MessageManager
480               .getString("label.edit_name_and_description_current_group"));
481
482       if (sg.cs instanceof ZappoColourScheme)
483       {
484         zappoColour.setSelected(true);
485       }
486       else if (sg.cs instanceof TaylorColourScheme)
487       {
488         taylorColour.setSelected(true);
489       }
490       else if (sg.cs instanceof PIDColourScheme)
491       {
492         PIDColour.setSelected(true);
493       }
494       else if (sg.cs instanceof Blosum62ColourScheme)
495       {
496         BLOSUM62Colour.setSelected(true);
497       }
498       else if (sg.cs instanceof UserColourScheme)
499       {
500         userDefinedColour.setSelected(true);
501       }
502       else if (sg.cs instanceof HydrophobicColourScheme)
503       {
504         hydrophobicityColour.setSelected(true);
505       }
506       else if (sg.cs instanceof HelixColourScheme)
507       {
508         helixColour.setSelected(true);
509       }
510       else if (sg.cs instanceof StrandColourScheme)
511       {
512         strandColour.setSelected(true);
513       }
514       else if (sg.cs instanceof TurnColourScheme)
515       {
516         turnColour.setSelected(true);
517       }
518       else if (sg.cs instanceof BuriedColourScheme)
519       {
520         buriedColour.setSelected(true);
521       }
522       else if (sg.cs instanceof ClustalxColourScheme)
523       {
524         clustalColour.setSelected(true);
525       }
526       else if (sg.cs instanceof PurinePyrimidineColourScheme)
527       {
528         purinePyrimidineColour.setSelected(true);
529       }
530
531       /*
532        * else if (sg.cs instanceof CovariationColourScheme) {
533        * covariationColour.setSelected(true); }
534        */
535       else
536       {
537         noColourmenuItem.setSelected(true);
538       }
539
540       if (sg.cs != null && sg.cs.conservationApplied())
541       {
542         conservationMenuItem.setSelected(true);
543       }
544       displayNonconserved.setSelected(sg.getShowNonconserved());
545       showText.setSelected(sg.getDisplayText());
546       showColourText.setSelected(sg.getColourText());
547       showBoxes.setSelected(sg.getDisplayBoxes());
548       // add any groupURLs to the groupURL submenu and make it visible
549       if (groupLinks != null && groupLinks.size() > 0)
550       {
551         buildGroupURLMenu(sg, groupLinks);
552       }
553       // Add a 'show all structures' for the current selection
554       Hashtable<String, PDBEntry> pdbe = new Hashtable<String, PDBEntry>(), reppdb = new Hashtable<String, PDBEntry>();
555       SequenceI sqass = null;
556       for (SequenceI sq : ap.av.getSequenceSelection())
557       {
558         Vector<PDBEntry> pes = (Vector<PDBEntry>) sq.getDatasetSequence()
559                 .getPDBId();
560         if (pes != null && pes.size() > 0)
561         {
562           reppdb.put(pes.get(0).getId(), pes.get(0));
563           for (PDBEntry pe : pes)
564           {
565             pdbe.put(pe.getId(), pe);
566             if (sqass == null)
567             {
568               sqass = sq;
569             }
570           }
571         }
572       }
573       if (pdbe.size() > 0)
574       {
575         final PDBEntry[] pe = pdbe.values().toArray(
576                 new PDBEntry[pdbe.size()]), pr = reppdb.values().toArray(
577                 new PDBEntry[reppdb.size()]);
578         final JMenuItem gpdbview, rpdbview;
579         if (pdbe.size() == 1)
580         {
581           structureMenu.add(gpdbview = new JMenuItem(MessageManager
582                   .formatMessage("label.view_structure_for", new String[]
583                   { sqass.getDisplayId(false) })));
584         }
585         else
586         {
587           structureMenu.add(gpdbview = new JMenuItem(MessageManager
588                   .formatMessage("label.view_all_structures", new String[]
589                   { new Integer(pdbe.size()).toString() })));
590         }
591         gpdbview.setToolTipText(MessageManager
592                 .getString("label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment"));
593         gpdbview.addActionListener(new ActionListener()
594         {
595
596           @Override
597           public void actionPerformed(ActionEvent e)
598           {
599             new StructureViewer(ap.getStructureSelectionManager())
600                     .viewStructures(ap, pe, ap.av.collateForPDB(pe));
601           }
602         });
603         if (reppdb.size() > 1 && reppdb.size() < pdbe.size())
604         {
605           structureMenu.add(rpdbview = new JMenuItem(MessageManager
606                   .formatMessage(
607                           "label.view_all_representative_structures",
608                           new String[]
609                           { new Integer(reppdb.size()).toString() })));
610           rpdbview.setToolTipText(MessageManager
611                   .getString("label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment"));
612           rpdbview.addActionListener(new ActionListener()
613           {
614
615             @Override
616             public void actionPerformed(ActionEvent e)
617             {
618               new StructureViewer(ap.getStructureSelectionManager())
619                       .viewStructures(ap, pr, ap.av.collateForPDB(pr));
620             }
621           });
622         }
623       }
624     }
625     else
626     {
627       groupMenu.setVisible(false);
628       editMenu.setVisible(false);
629     }
630
631     if (!isDefinedGroup)
632     {
633       createGroupMenuItem.setVisible(true);
634       unGroupMenuItem.setVisible(false);
635       jMenu1.setText(MessageManager.getString("action.edit_new_group"));
636     }
637     else
638     {
639       createGroupMenuItem.setVisible(false);
640       unGroupMenuItem.setVisible(true);
641       jMenu1.setText(MessageManager.getString("action.edit_group"));
642     }
643
644     if (seq == null)
645     {
646       sequenceMenu.setVisible(false);
647       structureMenu.setVisible(false);
648     }
649
650     if (links != null && links.size() > 0)
651     {
652
653       JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
654       Vector linkset = new Vector();
655       for (int i = 0; i < links.size(); i++)
656       {
657         String link = links.elementAt(i).toString();
658         UrlLink urlLink = null;
659         try
660         {
661           urlLink = new UrlLink(link);
662         } catch (Exception foo)
663         {
664           jalview.bin.Cache.log.error("Exception for URLLink '" + link
665                   + "'", foo);
666           continue;
667         }
668         ;
669         if (!urlLink.isValid())
670         {
671           jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
672           continue;
673         }
674         final String label = urlLink.getLabel();
675         if (seq != null && urlLink.isDynamic())
676         {
677
678           // collect matching db-refs
679           DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(
680                   seq.getDBRef(), new String[]
681                   { urlLink.getTarget() });
682           // collect id string too
683           String id = seq.getName();
684           String descr = seq.getDescription();
685           if (descr != null && descr.length() < 1)
686           {
687             descr = null;
688           }
689
690           if (dbr != null)
691           {
692             for (int r = 0; r < dbr.length; r++)
693             {
694               if (id != null && dbr[r].getAccessionId().equals(id))
695               {
696                 // suppress duplicate link creation for the bare sequence ID
697                 // string with this link
698                 id = null;
699               }
700               // create Bare ID link for this RUL
701               String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(),
702                       true);
703               if (urls != null)
704               {
705                 for (int u = 0; u < urls.length; u += 2)
706                 {
707                   if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
708                   {
709                     linkset.addElement(urls[u] + "|" + urls[u + 1]);
710                     addshowLink(linkMenu, label + "|" + urls[u],
711                             urls[u + 1]);
712                   }
713                 }
714               }
715             }
716           }
717           if (id != null)
718           {
719             // create Bare ID link for this RUL
720             String[] urls = urlLink.makeUrls(id, true);
721             if (urls != null)
722             {
723               for (int u = 0; u < urls.length; u += 2)
724               {
725                 if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
726                 {
727                   linkset.addElement(urls[u] + "|" + urls[u + 1]);
728                   addshowLink(linkMenu, label, urls[u + 1]);
729                 }
730               }
731             }
732           }
733           // Create urls from description but only for URL links which are regex
734           // links
735           if (descr != null && urlLink.getRegexReplace() != null)
736           {
737             // create link for this URL from description where regex matches
738             String[] urls = urlLink.makeUrls(descr, true);
739             if (urls != null)
740             {
741               for (int u = 0; u < urls.length; u += 2)
742               {
743                 if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
744                 {
745                   linkset.addElement(urls[u] + "|" + urls[u + 1]);
746                   addshowLink(linkMenu, label, urls[u + 1]);
747                 }
748               }
749             }
750           }
751         }
752         else
753         {
754           if (!linkset.contains(label + "|" + urlLink.getUrl_prefix()))
755           {
756             linkset.addElement(label + "|" + urlLink.getUrl_prefix());
757             // Add a non-dynamic link
758             addshowLink(linkMenu, label, urlLink.getUrl_prefix());
759           }
760         }
761       }
762       if (sequence != null)
763       {
764         sequenceMenu.add(linkMenu);
765       }
766       else
767       {
768         add(linkMenu);
769       }
770     }
771   }
772
773   private void buildGroupURLMenu(SequenceGroup sg, Vector groupLinks)
774   {
775
776     // TODO: usability: thread off the generation of group url content so root
777     // menu appears asap
778     // sequence only URLs
779     // ID/regex match URLs
780     groupLinksMenu = new JMenu(
781             MessageManager.getString("action.group_link"));
782     JMenu[] linkMenus = new JMenu[]
783     { null, new JMenu(MessageManager.getString("action.ids")),
784         new JMenu(MessageManager.getString("action.sequences")),
785         new JMenu(MessageManager.getString("action.ids_sequences")) }; // three
786                                                                        // types
787                                                                        // of url
788                                                                        // that
789                                                                        // might
790                                                                        // be
791     // created.
792     SequenceI[] seqs = ap.av.getSelectionAsNewSequence();
793     String[][] idandseqs = GroupUrlLink.formStrings(seqs);
794     Hashtable commonDbrefs = new Hashtable();
795     for (int sq = 0; sq < seqs.length; sq++)
796     {
797
798       int start = seqs[sq].findPosition(sg.getStartRes()), end = seqs[sq]
799               .findPosition(sg.getEndRes());
800       // just collect ids from dataset sequence
801       // TODO: check if IDs collected from selecton group intersects with the
802       // current selection, too
803       SequenceI sqi = seqs[sq];
804       while (sqi.getDatasetSequence() != null)
805       {
806         sqi = sqi.getDatasetSequence();
807       }
808       DBRefEntry[] dbr = sqi.getDBRef();
809       if (dbr != null && dbr.length > 0)
810       {
811         for (int d = 0; d < dbr.length; d++)
812         {
813           String src = dbr[d].getSource(); // jalview.util.DBRefUtils.getCanonicalName(dbr[d].getSource()).toUpperCase();
814           Object[] sarray = (Object[]) commonDbrefs.get(src);
815           if (sarray == null)
816           {
817             sarray = new Object[2];
818             sarray[0] = new int[]
819             { 0 };
820             sarray[1] = new String[seqs.length];
821
822             commonDbrefs.put(src, sarray);
823           }
824
825           if (((String[]) sarray[1])[sq] == null)
826           {
827             if (!dbr[d].hasMap()
828                     || (dbr[d].getMap().locateMappedRange(start, end) != null))
829             {
830               ((String[]) sarray[1])[sq] = dbr[d].getAccessionId();
831               ((int[]) sarray[0])[0]++;
832             }
833           }
834         }
835       }
836     }
837     // now create group links for all distinct ID/sequence sets.
838     boolean addMenu = false; // indicates if there are any group links to give
839                              // to user
840     for (int i = 0; i < groupLinks.size(); i++)
841     {
842       String link = groupLinks.elementAt(i).toString();
843       GroupUrlLink urlLink = null;
844       try
845       {
846         urlLink = new GroupUrlLink(link);
847       } catch (Exception foo)
848       {
849         jalview.bin.Cache.log.error("Exception for GroupURLLink '" + link
850                 + "'", foo);
851         continue;
852       }
853       ;
854       if (!urlLink.isValid())
855       {
856         jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
857         continue;
858       }
859       final String label = urlLink.getLabel();
860       boolean usingNames = false;
861       // Now see which parts of the group apply for this URL
862       String ltarget = urlLink.getTarget(); // jalview.util.DBRefUtils.getCanonicalName(urlLink.getTarget());
863       Object[] idset = (Object[]) commonDbrefs.get(ltarget.toUpperCase());
864       String[] seqstr, ids; // input to makeUrl
865       if (idset != null)
866       {
867         int numinput = ((int[]) idset[0])[0];
868         String[] allids = ((String[]) idset[1]);
869         seqstr = new String[numinput];
870         ids = new String[numinput];
871         for (int sq = 0, idcount = 0; sq < seqs.length; sq++)
872         {
873           if (allids[sq] != null)
874           {
875             ids[idcount] = allids[sq];
876             seqstr[idcount++] = idandseqs[1][sq];
877           }
878         }
879       }
880       else
881       {
882         // just use the id/seq set
883         seqstr = idandseqs[1];
884         ids = idandseqs[0];
885         usingNames = true;
886       }
887       // and try and make the groupURL!
888
889       Object[] urlset = null;
890       try
891       {
892         urlset = urlLink.makeUrlStubs(ids, seqstr,
893                 "FromJalview" + System.currentTimeMillis(), false);
894       } catch (UrlStringTooLongException e)
895       {
896       }
897       if (urlset != null)
898       {
899         int type = urlLink.getGroupURLType() & 3;
900         // System.out.println(urlLink.getGroupURLType()
901         // +" "+((String[])urlset[3])[0]);
902         // first two bits ofurlLink type bitfield are sequenceids and sequences
903         // TODO: FUTURE: ensure the groupURL menu structure can be generalised
904         addshowLink(linkMenus[type], label
905                 + (((type & 1) == 1) ? ("("
906                         + (usingNames ? "Names" : ltarget) + ")") : ""),
907                 urlLink, urlset);
908         addMenu = true;
909       }
910     }
911     if (addMenu)
912     {
913       groupLinksMenu = new JMenu(
914               MessageManager.getString("action.group_link"));
915       for (int m = 0; m < linkMenus.length; m++)
916       {
917         if (linkMenus[m] != null
918                 && linkMenus[m].getMenuComponentCount() > 0)
919         {
920           groupLinksMenu.add(linkMenus[m]);
921         }
922       }
923
924       groupMenu.add(groupLinksMenu);
925     }
926   }
927
928   /**
929    * add a show URL menu item to the given linkMenu
930    * 
931    * @param linkMenu
932    * @param label
933    *          - menu label string
934    * @param url
935    *          - url to open
936    */
937   private void addshowLink(JMenu linkMenu, String label, final String url)
938   {
939     JMenuItem item = new JMenuItem(label);
940     item.setToolTipText(MessageManager.formatMessage(
941             "label.open_url_param", new String[]
942             { url }));
943     item.addActionListener(new java.awt.event.ActionListener()
944     {
945       public void actionPerformed(ActionEvent e)
946       {
947         new Thread(new Runnable()
948         {
949
950           public void run()
951           {
952             showLink(url);
953           }
954
955         }).start();
956       }
957     });
958
959     linkMenu.add(item);
960   }
961
962   /**
963    * add a late bound groupURL item to the given linkMenu
964    * 
965    * @param linkMenu
966    * @param label
967    *          - menu label string
968    * @param urlgenerator
969    *          GroupURLLink used to generate URL
970    * @param urlstub
971    *          Object array returned from the makeUrlStubs function.
972    */
973   private void addshowLink(JMenu linkMenu, String label,
974           final GroupUrlLink urlgenerator, final Object[] urlstub)
975   {
976     JMenuItem item = new JMenuItem(label);
977     item.setToolTipText(MessageManager.formatMessage(
978             "label.open_url_seqs_param",
979             new Object[]
980             { urlgenerator.getUrl_prefix(),
981                 urlgenerator.getNumberInvolved(urlstub) }));
982     // TODO: put in info about what is being sent.
983     item.addActionListener(new java.awt.event.ActionListener()
984     {
985       public void actionPerformed(ActionEvent e)
986       {
987         new Thread(new Runnable()
988         {
989
990           public void run()
991           {
992             try
993             {
994               showLink(urlgenerator.constructFrom(urlstub));
995             } catch (UrlStringTooLongException e)
996             {
997             }
998           }
999
1000         }).start();
1001       }
1002     });
1003
1004     linkMenu.add(item);
1005   }
1006
1007   /**
1008    * DOCUMENT ME!
1009    * 
1010    * @throws Exception
1011    *           DOCUMENT ME!
1012    */
1013   private void jbInit() throws Exception
1014   {
1015     groupMenu.setText(MessageManager.getString("label.group"));
1016     groupMenu.setText(MessageManager.getString("label.selection"));
1017     groupName.setText(MessageManager.getString("label.name"));
1018     groupName.addActionListener(new java.awt.event.ActionListener()
1019     {
1020       public void actionPerformed(ActionEvent e)
1021       {
1022         groupName_actionPerformed();
1023       }
1024     });
1025     sequenceMenu.setText(MessageManager.getString("label.sequence"));
1026     sequenceName.setText(MessageManager
1027             .getString("label.edit_name_description"));
1028     sequenceName.addActionListener(new java.awt.event.ActionListener()
1029     {
1030       public void actionPerformed(ActionEvent e)
1031       {
1032         sequenceName_actionPerformed();
1033       }
1034     });
1035     sequenceDetails.setText(MessageManager
1036             .getString("label.sequence_details") + "...");
1037     sequenceDetails.addActionListener(new java.awt.event.ActionListener()
1038     {
1039       public void actionPerformed(ActionEvent e)
1040       {
1041         sequenceDetails_actionPerformed();
1042       }
1043     });
1044     sequenceSelDetails.setText(MessageManager
1045             .getString("label.sequence_details") + "...");
1046     sequenceSelDetails
1047             .addActionListener(new java.awt.event.ActionListener()
1048             {
1049               public void actionPerformed(ActionEvent e)
1050               {
1051                 sequenceSelectionDetails_actionPerformed();
1052               }
1053             });
1054     PIDColour.setFocusPainted(false);
1055     unGroupMenuItem
1056             .setText(MessageManager.getString("action.remove_group"));
1057     unGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
1058     {
1059       public void actionPerformed(ActionEvent e)
1060       {
1061         unGroupMenuItem_actionPerformed();
1062       }
1063     });
1064     createGroupMenuItem.setText(MessageManager
1065             .getString("action.create_group"));
1066     createGroupMenuItem
1067             .addActionListener(new java.awt.event.ActionListener()
1068             {
1069               public void actionPerformed(ActionEvent e)
1070               {
1071                 createGroupMenuItem_actionPerformed();
1072               }
1073             });
1074
1075     outline.setText(MessageManager.getString("action.border_colour"));
1076     outline.addActionListener(new java.awt.event.ActionListener()
1077     {
1078       public void actionPerformed(ActionEvent e)
1079       {
1080         outline_actionPerformed();
1081       }
1082     });
1083     nucleotideMenuItem
1084             .setText(MessageManager.getString("label.nucleotide"));
1085     nucleotideMenuItem.addActionListener(new ActionListener()
1086     {
1087       public void actionPerformed(ActionEvent e)
1088       {
1089         nucleotideMenuItem_actionPerformed();
1090       }
1091     });
1092     colourMenu.setText(MessageManager.getString("label.group_colour"));
1093     showBoxes.setText(MessageManager.getString("action.boxes"));
1094     showBoxes.setState(true);
1095     showBoxes.addActionListener(new ActionListener()
1096     {
1097       public void actionPerformed(ActionEvent e)
1098       {
1099         showBoxes_actionPerformed();
1100       }
1101     });
1102     showText.setText(MessageManager.getString("action.text"));
1103     showText.setState(true);
1104     showText.addActionListener(new ActionListener()
1105     {
1106       public void actionPerformed(ActionEvent e)
1107       {
1108         showText_actionPerformed();
1109       }
1110     });
1111     showColourText.setText(MessageManager.getString("label.colour_text"));
1112     showColourText.addActionListener(new ActionListener()
1113     {
1114       public void actionPerformed(ActionEvent e)
1115       {
1116         showColourText_actionPerformed();
1117       }
1118     });
1119     displayNonconserved.setText(MessageManager
1120             .getString("label.show_non_conversed"));
1121     displayNonconserved.setState(true);
1122     displayNonconserved.addActionListener(new ActionListener()
1123     {
1124       public void actionPerformed(ActionEvent e)
1125       {
1126         showNonconserved_actionPerformed();
1127       }
1128     });
1129     editMenu.setText(MessageManager.getString("action.edit"));
1130     cut.setText(MessageManager.getString("action.cut"));
1131     cut.addActionListener(new ActionListener()
1132     {
1133       public void actionPerformed(ActionEvent e)
1134       {
1135         cut_actionPerformed();
1136       }
1137     });
1138     upperCase.setText(MessageManager.getString("label.to_upper_case"));
1139     upperCase.addActionListener(new ActionListener()
1140     {
1141       public void actionPerformed(ActionEvent e)
1142       {
1143         changeCase(e);
1144       }
1145     });
1146     copy.setText(MessageManager.getString("action.copy"));
1147     copy.addActionListener(new ActionListener()
1148     {
1149       public void actionPerformed(ActionEvent e)
1150       {
1151         copy_actionPerformed();
1152       }
1153     });
1154     lowerCase.setText(MessageManager.getString("label.to_lower_case"));
1155     lowerCase.addActionListener(new ActionListener()
1156     {
1157       public void actionPerformed(ActionEvent e)
1158       {
1159         changeCase(e);
1160       }
1161     });
1162     toggle.setText(MessageManager.getString("label.toggle_case"));
1163     toggle.addActionListener(new ActionListener()
1164     {
1165       public void actionPerformed(ActionEvent e)
1166       {
1167         changeCase(e);
1168       }
1169     });
1170     pdbMenu.setText(MessageManager
1171             .getString("label.associate_structure_with_sequence"));
1172     pdbFromFile.setText(MessageManager.getString("label.from_file"));
1173     pdbFromFile.addActionListener(new ActionListener()
1174     {
1175       public void actionPerformed(ActionEvent e)
1176       {
1177         pdbFromFile_actionPerformed();
1178       }
1179     });
1180     // RNAFold.setText("From RNA Fold with predict2D");
1181     // RNAFold.addActionListener(new ActionListener()
1182     // {
1183     // public void actionPerformed(ActionEvent e)
1184     // {
1185     // try {
1186     // RNAFold_actionPerformed();
1187     // } catch (Exception e1) {
1188     // // TODO Auto-generated catch block
1189     // e1.printStackTrace();
1190     // }
1191     // }
1192     // });
1193     // ContraFold.setText("From Contra Fold with predict2D");
1194     // ContraFold.addActionListener(new ActionListener()
1195     // {
1196     // public void actionPerformed(ActionEvent e)
1197     // {
1198     // try {
1199     // ContraFold_actionPerformed();
1200     // } catch (Exception e1) {
1201     // // TODO Auto-generated catch block
1202     // e1.printStackTrace();
1203     // }
1204     // }
1205     // });
1206     enterPDB.setText(MessageManager.getString("label.enter_pdb_id"));
1207     enterPDB.addActionListener(new ActionListener()
1208     {
1209       public void actionPerformed(ActionEvent e)
1210       {
1211         enterPDB_actionPerformed();
1212       }
1213     });
1214     discoverPDB.setText(MessageManager.getString("label.discover_pdb_ids"));
1215     discoverPDB.addActionListener(new ActionListener()
1216     {
1217       public void actionPerformed(ActionEvent e)
1218       {
1219         discoverPDB_actionPerformed();
1220       }
1221     });
1222     outputMenu.setText(MessageManager.getString("label.out_to_textbox")
1223             + "...");
1224     sequenceFeature.setText(MessageManager
1225             .getString("label.create_sequence_feature"));
1226     sequenceFeature.addActionListener(new ActionListener()
1227     {
1228       public void actionPerformed(ActionEvent e)
1229       {
1230         sequenceFeature_actionPerformed();
1231       }
1232     });
1233     textColour.setText(MessageManager.getString("label.text_colour"));
1234     textColour.addActionListener(new ActionListener()
1235     {
1236       public void actionPerformed(ActionEvent e)
1237       {
1238         textColour_actionPerformed();
1239       }
1240     });
1241     jMenu1.setText(MessageManager.getString("label.group"));
1242     structureMenu.setText(MessageManager.getString("label.structure"));
1243     viewStructureMenu.setText(MessageManager
1244             .getString("label.view_structure"));
1245     // colStructureMenu.setText("Colour By Structure");
1246     editSequence.setText(MessageManager.getString("label.edit_sequence")
1247             + "...");
1248     editSequence.addActionListener(new ActionListener()
1249     {
1250       public void actionPerformed(ActionEvent actionEvent)
1251       {
1252         editSequence_actionPerformed(actionEvent);
1253       }
1254     });
1255
1256     /*
1257      * annotationMenuItem.setText("By Annotation");
1258      * annotationMenuItem.addActionListener(new ActionListener() { public void
1259      * actionPerformed(ActionEvent actionEvent) {
1260      * annotationMenuItem_actionPerformed(actionEvent); } });
1261      */
1262     groupMenu.add(sequenceSelDetails);
1263     add(groupMenu);
1264     add(sequenceMenu);
1265     this.add(structureMenu);
1266     groupMenu.add(editMenu);
1267     groupMenu.add(outputMenu);
1268     groupMenu.add(sequenceFeature);
1269     groupMenu.add(createGroupMenuItem);
1270     groupMenu.add(unGroupMenuItem);
1271     groupMenu.add(jMenu1);
1272     sequenceMenu.add(sequenceName);
1273     sequenceMenu.add(sequenceDetails);
1274     colourMenu.add(textColour);
1275     colourMenu.add(noColourmenuItem);
1276     colourMenu.add(clustalColour);
1277     colourMenu.add(BLOSUM62Colour);
1278     colourMenu.add(PIDColour);
1279     colourMenu.add(zappoColour);
1280     colourMenu.add(taylorColour);
1281     colourMenu.add(hydrophobicityColour);
1282     colourMenu.add(helixColour);
1283     colourMenu.add(strandColour);
1284     colourMenu.add(turnColour);
1285     colourMenu.add(buriedColour);
1286     colourMenu.add(nucleotideMenuItem);
1287     if (ap.getAlignment().isNucleotide())
1288     {
1289       // JBPNote - commented since the colourscheme isn't functional
1290       // colourMenu.add(RNAInteractionColour);
1291       colourMenu.add(purinePyrimidineColour);
1292     }
1293     // colourMenu.add(covariationColour);
1294     colourMenu.add(userDefinedColour);
1295
1296     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
1297     {
1298       java.util.Enumeration userColours = jalview.gui.UserDefinedColours
1299               .getUserColourSchemes().keys();
1300
1301       while (userColours.hasMoreElements())
1302       {
1303         JMenuItem item = new JMenuItem(userColours.nextElement().toString());
1304         item.addActionListener(new ActionListener()
1305         {
1306           public void actionPerformed(ActionEvent evt)
1307           {
1308             userDefinedColour_actionPerformed(evt);
1309           }
1310         });
1311         colourMenu.add(item);
1312       }
1313     }
1314
1315     colourMenu.addSeparator();
1316     colourMenu.add(abovePIDColour);
1317     colourMenu.add(conservationMenuItem);
1318     // colourMenu.add(annotationMenuItem);
1319     editMenu.add(copy);
1320     editMenu.add(cut);
1321     editMenu.add(editSequence);
1322     editMenu.add(upperCase);
1323     editMenu.add(lowerCase);
1324     editMenu.add(toggle);
1325     pdbMenu.add(pdbFromFile);
1326     // JBPNote: These shouldn't be added here - should appear in a generic
1327     // 'apply web service to this sequence menu'
1328     // pdbMenu.add(RNAFold);
1329     // pdbMenu.add(ContraFold);
1330     pdbMenu.add(enterPDB);
1331     pdbMenu.add(discoverPDB);
1332     jMenu1.add(groupName);
1333     jMenu1.add(colourMenu);
1334     jMenu1.add(showBoxes);
1335     jMenu1.add(showText);
1336     jMenu1.add(showColourText);
1337     jMenu1.add(outline);
1338     jMenu1.add(displayNonconserved);
1339     structureMenu.add(pdbMenu);
1340     structureMenu.add(viewStructureMenu);
1341     // structureMenu.add(colStructureMenu);
1342     noColourmenuItem.setText(MessageManager.getString("label.none"));
1343     noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
1344     {
1345       public void actionPerformed(ActionEvent e)
1346       {
1347         noColourmenuItem_actionPerformed();
1348       }
1349     });
1350
1351     clustalColour.setText(MessageManager
1352             .getString("label.clustalx_colours"));
1353     clustalColour.addActionListener(new java.awt.event.ActionListener()
1354     {
1355       public void actionPerformed(ActionEvent e)
1356       {
1357         clustalColour_actionPerformed();
1358       }
1359     });
1360     zappoColour.setText(MessageManager.getString("label.zappo"));
1361     zappoColour.addActionListener(new java.awt.event.ActionListener()
1362     {
1363       public void actionPerformed(ActionEvent e)
1364       {
1365         zappoColour_actionPerformed();
1366       }
1367     });
1368     taylorColour.setText(MessageManager.getString("label.taylor"));
1369     taylorColour.addActionListener(new java.awt.event.ActionListener()
1370     {
1371       public void actionPerformed(ActionEvent e)
1372       {
1373         taylorColour_actionPerformed();
1374       }
1375     });
1376     hydrophobicityColour.setText(MessageManager
1377             .getString("label.hydrophobicity"));
1378     hydrophobicityColour
1379             .addActionListener(new java.awt.event.ActionListener()
1380             {
1381               public void actionPerformed(ActionEvent e)
1382               {
1383                 hydrophobicityColour_actionPerformed();
1384               }
1385             });
1386     helixColour.setText(MessageManager.getString("label.helix_propensity"));
1387     helixColour.addActionListener(new java.awt.event.ActionListener()
1388     {
1389       public void actionPerformed(ActionEvent e)
1390       {
1391         helixColour_actionPerformed();
1392       }
1393     });
1394     strandColour.setText(MessageManager
1395             .getString("label.strand_propensity"));
1396     strandColour.addActionListener(new java.awt.event.ActionListener()
1397     {
1398       public void actionPerformed(ActionEvent e)
1399       {
1400         strandColour_actionPerformed();
1401       }
1402     });
1403     turnColour.setText(MessageManager.getString("label.turn_propensity"));
1404     turnColour.addActionListener(new java.awt.event.ActionListener()
1405     {
1406       public void actionPerformed(ActionEvent e)
1407       {
1408         turnColour_actionPerformed();
1409       }
1410     });
1411     buriedColour.setText(MessageManager.getString("label.buried_index"));
1412     buriedColour.addActionListener(new java.awt.event.ActionListener()
1413     {
1414       public void actionPerformed(ActionEvent e)
1415       {
1416         buriedColour_actionPerformed();
1417       }
1418     });
1419     abovePIDColour.setText(MessageManager
1420             .getString("label.above_identity_percentage"));
1421     abovePIDColour.addActionListener(new java.awt.event.ActionListener()
1422     {
1423       public void actionPerformed(ActionEvent e)
1424       {
1425         abovePIDColour_actionPerformed();
1426       }
1427     });
1428     userDefinedColour.setText(MessageManager
1429             .getString("action.user_defined"));
1430     userDefinedColour.addActionListener(new java.awt.event.ActionListener()
1431     {
1432       public void actionPerformed(ActionEvent e)
1433       {
1434         userDefinedColour_actionPerformed(e);
1435       }
1436     });
1437     PIDColour
1438             .setText(MessageManager.getString("label.percentage_identity"));
1439     PIDColour.addActionListener(new java.awt.event.ActionListener()
1440     {
1441       public void actionPerformed(ActionEvent e)
1442       {
1443         PIDColour_actionPerformed();
1444       }
1445     });
1446     BLOSUM62Colour.setText(MessageManager.getString("label.blosum62"));
1447     BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
1448     {
1449       public void actionPerformed(ActionEvent e)
1450       {
1451         BLOSUM62Colour_actionPerformed();
1452       }
1453     });
1454     purinePyrimidineColour.setText(MessageManager
1455             .getString("label.purine_pyrimidine"));
1456     purinePyrimidineColour
1457             .addActionListener(new java.awt.event.ActionListener()
1458             {
1459               public void actionPerformed(ActionEvent e)
1460               {
1461                 purinePyrimidineColour_actionPerformed();
1462               }
1463             });
1464
1465     /*
1466      * covariationColour.addActionListener(new java.awt.event.ActionListener() {
1467      * public void actionPerformed(ActionEvent e) {
1468      * covariationColour_actionPerformed(); } });
1469      */
1470
1471     conservationMenuItem.setText(MessageManager
1472             .getString("label.conservation"));
1473     conservationMenuItem
1474             .addActionListener(new java.awt.event.ActionListener()
1475             {
1476               public void actionPerformed(ActionEvent e)
1477               {
1478                 conservationMenuItem_actionPerformed();
1479               }
1480             });
1481   }
1482
1483   protected void sequenceSelectionDetails_actionPerformed()
1484   {
1485     createSequenceDetailsReport(ap.av.getSequenceSelection());
1486   }
1487
1488   protected void sequenceDetails_actionPerformed()
1489   {
1490     createSequenceDetailsReport(new SequenceI[]
1491     { sequence });
1492   }
1493
1494   public void createSequenceDetailsReport(SequenceI[] sequences)
1495   {
1496     CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
1497     StringBuffer contents = new StringBuffer();
1498     for (SequenceI seq : sequences)
1499     {
1500       contents.append("<p><h2>"
1501               + MessageManager
1502                       .formatMessage(
1503                               "label.create_sequence_details_report_annotation_for",
1504                               new String[]
1505                               { seq.getDisplayId(true) }) + "</h2></p><p>");
1506       new SequenceAnnotationReport(null)
1507               .createSequenceAnnotationReport(
1508                       contents,
1509                       seq,
1510                       true,
1511                       true,
1512                       false,
1513                       (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr.minmax
1514                               : null);
1515       contents.append("</p>");
1516     }
1517     cap.setText("<html>" + contents.toString() + "</html>");
1518
1519     Desktop.instance.addInternalFrame(cap, MessageManager.formatMessage(
1520             "label.sequece_details_for",
1521             (sequences.length == 1 ? new String[]
1522             { sequences[0].getDisplayId(true) } : new String[]
1523             { MessageManager.getString("label.selection") })), 500, 400);
1524
1525   }
1526
1527   protected void showNonconserved_actionPerformed()
1528   {
1529     getGroup().setShowNonconserved(displayNonconserved.isSelected());
1530     refresh();
1531   }
1532
1533   /**
1534    * call to refresh view after settings change
1535    */
1536   void refresh()
1537   {
1538     ap.updateAnnotation();
1539     ap.paintAlignment(true);
1540
1541     PaintRefresher.Refresh(this, ap.av.getSequenceSetId());
1542   }
1543
1544   /**
1545    * DOCUMENT ME!
1546    * 
1547    * @param e
1548    *          DOCUMENT ME!
1549    */
1550   protected void clustalColour_actionPerformed()
1551   {
1552     SequenceGroup sg = getGroup();
1553     sg.cs = new ClustalxColourScheme(sg, ap.av.getHiddenRepSequences());
1554     refresh();
1555   }
1556
1557   /**
1558    * DOCUMENT ME!
1559    * 
1560    * @param e
1561    *          DOCUMENT ME!
1562    */
1563   protected void zappoColour_actionPerformed()
1564   {
1565     getGroup().cs = new ZappoColourScheme();
1566     refresh();
1567   }
1568
1569   /**
1570    * DOCUMENT ME!
1571    * 
1572    * @param e
1573    *          DOCUMENT ME!
1574    */
1575   protected void taylorColour_actionPerformed()
1576   {
1577     getGroup().cs = new TaylorColourScheme();
1578     refresh();
1579   }
1580
1581   /**
1582    * DOCUMENT ME!
1583    * 
1584    * @param e
1585    *          DOCUMENT ME!
1586    */
1587   protected void hydrophobicityColour_actionPerformed()
1588   {
1589     getGroup().cs = new HydrophobicColourScheme();
1590     refresh();
1591   }
1592
1593   /**
1594    * DOCUMENT ME!
1595    * 
1596    * @param e
1597    *          DOCUMENT ME!
1598    */
1599   protected void helixColour_actionPerformed()
1600   {
1601     getGroup().cs = new HelixColourScheme();
1602     refresh();
1603   }
1604
1605   /**
1606    * DOCUMENT ME!
1607    * 
1608    * @param e
1609    *          DOCUMENT ME!
1610    */
1611   protected void strandColour_actionPerformed()
1612   {
1613     getGroup().cs = new StrandColourScheme();
1614     refresh();
1615   }
1616
1617   /**
1618    * DOCUMENT ME!
1619    * 
1620    * @param e
1621    *          DOCUMENT ME!
1622    */
1623   protected void turnColour_actionPerformed()
1624   {
1625     getGroup().cs = new TurnColourScheme();
1626     refresh();
1627   }
1628
1629   /**
1630    * DOCUMENT ME!
1631    * 
1632    * @param e
1633    *          DOCUMENT ME!
1634    */
1635   protected void buriedColour_actionPerformed()
1636   {
1637     getGroup().cs = new BuriedColourScheme();
1638     refresh();
1639   }
1640
1641   /**
1642    * DOCUMENT ME!
1643    * 
1644    * @param e
1645    *          DOCUMENT ME!
1646    */
1647   public void nucleotideMenuItem_actionPerformed()
1648   {
1649     getGroup().cs = new NucleotideColourScheme();
1650     refresh();
1651   }
1652
1653   protected void purinePyrimidineColour_actionPerformed()
1654   {
1655     getGroup().cs = new PurinePyrimidineColourScheme();
1656     refresh();
1657   }
1658
1659   /*
1660    * protected void covariationColour_actionPerformed() { getGroup().cs = new
1661    * CovariationColourScheme(sequence.getAnnotation()[0]); refresh(); }
1662    */
1663   /**
1664    * DOCUMENT ME!
1665    * 
1666    * @param e
1667    *          DOCUMENT ME!
1668    */
1669   protected void abovePIDColour_actionPerformed()
1670   {
1671     SequenceGroup sg = getGroup();
1672     if (sg.cs == null)
1673     {
1674       return;
1675     }
1676
1677     if (abovePIDColour.isSelected())
1678     {
1679       sg.cs.setConsensus(AAFrequency.calculate(
1680               sg.getSequences(ap.av.getHiddenRepSequences()),
1681               sg.getStartRes(), sg.getEndRes() + 1));
1682
1683       int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup()
1684               .getName());
1685
1686       sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
1687
1688       SliderPanel.showPIDSlider();
1689     }
1690     else
1691     // remove PIDColouring
1692     {
1693       sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
1694     }
1695
1696     refresh();
1697   }
1698
1699   /**
1700    * DOCUMENT ME!
1701    * 
1702    * @param e
1703    *          DOCUMENT ME!
1704    */
1705   protected void userDefinedColour_actionPerformed(ActionEvent e)
1706   {
1707     SequenceGroup sg = getGroup();
1708
1709     if (e.getSource().equals(userDefinedColour))
1710     {
1711       new UserDefinedColours(ap, sg);
1712     }
1713     else
1714     {
1715       UserColourScheme udc = (UserColourScheme) UserDefinedColours
1716               .getUserColourSchemes().get(e.getActionCommand());
1717
1718       sg.cs = udc;
1719     }
1720     refresh();
1721   }
1722
1723   /**
1724    * DOCUMENT ME!
1725    * 
1726    * @param e
1727    *          DOCUMENT ME!
1728    */
1729   protected void PIDColour_actionPerformed()
1730   {
1731     SequenceGroup sg = getGroup();
1732     sg.cs = new PIDColourScheme();
1733     sg.cs.setConsensus(AAFrequency.calculate(
1734             sg.getSequences(ap.av.getHiddenRepSequences()),
1735             sg.getStartRes(), sg.getEndRes() + 1));
1736     refresh();
1737   }
1738
1739   /**
1740    * DOCUMENT ME!
1741    * 
1742    * @param e
1743    *          DOCUMENT ME!
1744    */
1745   protected void BLOSUM62Colour_actionPerformed()
1746   {
1747     SequenceGroup sg = getGroup();
1748
1749     sg.cs = new Blosum62ColourScheme();
1750
1751     sg.cs.setConsensus(AAFrequency.calculate(
1752             sg.getSequences(ap.av.getHiddenRepSequences()),
1753             sg.getStartRes(), sg.getEndRes() + 1));
1754
1755     refresh();
1756   }
1757
1758   /**
1759    * DOCUMENT ME!
1760    * 
1761    * @param e
1762    *          DOCUMENT ME!
1763    */
1764   protected void noColourmenuItem_actionPerformed()
1765   {
1766     getGroup().cs = null;
1767     refresh();
1768   }
1769
1770   /**
1771    * DOCUMENT ME!
1772    * 
1773    * @param e
1774    *          DOCUMENT ME!
1775    */
1776   protected void conservationMenuItem_actionPerformed()
1777   {
1778     SequenceGroup sg = getGroup();
1779     if (sg.cs == null)
1780     {
1781       return;
1782     }
1783
1784     if (conservationMenuItem.isSelected())
1785     {
1786       // JBPNote: Conservation name shouldn't be i18n translated
1787       Conservation c = new Conservation("Group",
1788               ResidueProperties.propHash, 3, sg.getSequences(ap.av
1789                       .getHiddenRepSequences()), sg.getStartRes(),
1790               sg.getEndRes() + 1);
1791
1792       c.calculate();
1793       c.verdict(false, ap.av.getConsPercGaps());
1794
1795       sg.cs.setConservation(c);
1796
1797       SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
1798       SliderPanel.showConservationSlider();
1799     }
1800     else
1801     // remove ConservationColouring
1802     {
1803       sg.cs.setConservation(null);
1804     }
1805
1806     refresh();
1807   }
1808
1809   public void annotationMenuItem_actionPerformed(ActionEvent actionEvent)
1810   {
1811     SequenceGroup sg = getGroup();
1812     if (sg == null)
1813     {
1814       return;
1815     }
1816
1817     AnnotationColourGradient acg = new AnnotationColourGradient(
1818             sequence.getAnnotation()[0], null,
1819             AnnotationColourGradient.NO_THRESHOLD);
1820
1821     acg.setPredefinedColours(true);
1822     sg.cs = acg;
1823
1824     refresh();
1825   }
1826
1827   /**
1828    * DOCUMENT ME!
1829    * 
1830    * @param e
1831    *          DOCUMENT ME!
1832    */
1833   protected void groupName_actionPerformed()
1834   {
1835
1836     SequenceGroup sg = getGroup();
1837     EditNameDialog dialog = new EditNameDialog(sg.getName(),
1838             sg.getDescription(), "       "
1839                     + MessageManager.getString("label.group_name") + " ",
1840             MessageManager.getString("label.group_description") + " ",
1841             MessageManager.getString("label.edit_group_name_description"),
1842             ap.alignFrame);
1843
1844     if (!dialog.accept)
1845     {
1846       return;
1847     }
1848
1849     sg.setName(dialog.getName());
1850     sg.setDescription(dialog.getDescription());
1851     refresh();
1852   }
1853
1854   /**
1855    * Get selection group - adding it to the alignment if necessary.
1856    * 
1857    * @return sequence group to operate on
1858    */
1859   SequenceGroup getGroup()
1860   {
1861     SequenceGroup sg = ap.av.getSelectionGroup();
1862     // this method won't add a new group if it already exists
1863     if (sg != null)
1864     {
1865       ap.av.getAlignment().addGroup(sg);
1866     }
1867
1868     return sg;
1869   }
1870
1871   /**
1872    * DOCUMENT ME!
1873    * 
1874    * @param e
1875    *          DOCUMENT ME!
1876    */
1877   void sequenceName_actionPerformed()
1878   {
1879     EditNameDialog dialog = new EditNameDialog(sequence.getName(),
1880             sequence.getDescription(),
1881             "       " + MessageManager.getString("label.sequence_name")
1882                     + " ",
1883             MessageManager.getString("label.sequence_description") + " ",
1884             MessageManager
1885                     .getString("label.edit_sequence_name_description"),
1886             ap.alignFrame);
1887
1888     if (!dialog.accept)
1889     {
1890       return;
1891     }
1892
1893     if (dialog.getName() != null)
1894     {
1895       if (dialog.getName().indexOf(" ") > -1)
1896       {
1897         JOptionPane
1898                 .showMessageDialog(
1899                         ap,
1900                         MessageManager
1901                                 .getString("label.spaces_converted_to_backslashes"),
1902                         MessageManager
1903                                 .getString("label.no_spaces_allowed_sequence_name"),
1904                         JOptionPane.WARNING_MESSAGE);
1905       }
1906
1907       sequence.setName(dialog.getName().replace(' ', '_'));
1908       ap.paintAlignment(false);
1909     }
1910
1911     sequence.setDescription(dialog.getDescription());
1912
1913     ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
1914             .getSequences());
1915
1916   }
1917
1918   /**
1919    * DOCUMENT ME!
1920    * 
1921    * @param e
1922    *          DOCUMENT ME!
1923    */
1924   void unGroupMenuItem_actionPerformed()
1925   {
1926     SequenceGroup sg = ap.av.getSelectionGroup();
1927     ap.av.getAlignment().deleteGroup(sg);
1928     ap.av.setSelectionGroup(null);
1929     refresh();
1930   }
1931
1932   void createGroupMenuItem_actionPerformed()
1933   {
1934     getGroup(); // implicitly creates group - note - should apply defaults / use
1935                 // standard alignment window logic for this
1936     refresh();
1937   }
1938
1939   /**
1940    * DOCUMENT ME!
1941    * 
1942    * @param e
1943    *          DOCUMENT ME!
1944    */
1945   protected void outline_actionPerformed()
1946   {
1947     SequenceGroup sg = getGroup();
1948     Color col = JColorChooser.showDialog(this,
1949             MessageManager.getString("label.select_outline_colour"),
1950             Color.BLUE);
1951
1952     if (col != null)
1953     {
1954       sg.setOutlineColour(col);
1955     }
1956
1957     refresh();
1958   }
1959
1960   /**
1961    * DOCUMENT ME!
1962    * 
1963    * @param e
1964    *          DOCUMENT ME!
1965    */
1966   public void showBoxes_actionPerformed()
1967   {
1968     getGroup().setDisplayBoxes(showBoxes.isSelected());
1969     refresh();
1970   }
1971
1972   /**
1973    * DOCUMENT ME!
1974    * 
1975    * @param e
1976    *          DOCUMENT ME!
1977    */
1978   public void showText_actionPerformed()
1979   {
1980     getGroup().setDisplayText(showText.isSelected());
1981     refresh();
1982   }
1983
1984   /**
1985    * DOCUMENT ME!
1986    * 
1987    * @param e
1988    *          DOCUMENT ME!
1989    */
1990   public void showColourText_actionPerformed()
1991   {
1992     getGroup().setColourText(showColourText.isSelected());
1993     refresh();
1994   }
1995
1996   public void showLink(String url)
1997   {
1998     try
1999     {
2000       jalview.util.BrowserLauncher.openURL(url);
2001     } catch (Exception ex)
2002     {
2003       JOptionPane.showInternalMessageDialog(Desktop.desktop,
2004               MessageManager.getString("label.web_browser_not_found_unix"),
2005               MessageManager.getString("label.web_browser_not_found"),
2006               JOptionPane.WARNING_MESSAGE);
2007
2008       ex.printStackTrace();
2009     }
2010   }
2011
2012   void hideSequences(boolean representGroup)
2013   {
2014     SequenceGroup sg = ap.av.getSelectionGroup();
2015     if (sg == null || sg.getSize() < 1)
2016     {
2017       ap.av.hideSequence(new SequenceI[]
2018       { sequence });
2019       return;
2020     }
2021
2022     ap.av.setSelectionGroup(null);
2023
2024     if (representGroup)
2025     {
2026       ap.av.hideRepSequences(sequence, sg);
2027
2028       return;
2029     }
2030
2031     int gsize = sg.getSize();
2032     SequenceI[] hseqs;
2033
2034     hseqs = new SequenceI[gsize];
2035
2036     int index = 0;
2037     for (int i = 0; i < gsize; i++)
2038     {
2039       hseqs[index++] = sg.getSequenceAt(i);
2040     }
2041
2042     ap.av.hideSequence(hseqs);
2043     // refresh(); TODO: ? needed ?
2044     ap.av.sendSelection();
2045   }
2046
2047   public void copy_actionPerformed()
2048   {
2049     ap.alignFrame.copy_actionPerformed(null);
2050   }
2051
2052   public void cut_actionPerformed()
2053   {
2054     ap.alignFrame.cut_actionPerformed(null);
2055   }
2056
2057   void changeCase(ActionEvent e)
2058   {
2059     Object source = e.getSource();
2060     SequenceGroup sg = ap.av.getSelectionGroup();
2061
2062     if (sg != null)
2063     {
2064       int[][] startEnd = ap.av.getVisibleRegionBoundaries(sg.getStartRes(),
2065               sg.getEndRes() + 1);
2066
2067       String description;
2068       int caseChange;
2069
2070       if (source == toggle)
2071       {
2072         description = MessageManager.getString("label.toggle_case");
2073         caseChange = ChangeCaseCommand.TOGGLE_CASE;
2074       }
2075       else if (source == upperCase)
2076       {
2077         description = MessageManager.getString("label.to_upper_case");
2078         caseChange = ChangeCaseCommand.TO_UPPER;
2079       }
2080       else
2081       {
2082         description = MessageManager.getString("label.to_lower_case");
2083         caseChange = ChangeCaseCommand.TO_LOWER;
2084       }
2085
2086       ChangeCaseCommand caseCommand = new ChangeCaseCommand(description,
2087               sg.getSequencesAsArray(ap.av.getHiddenRepSequences()),
2088               startEnd, caseChange);
2089
2090       ap.alignFrame.addHistoryItem(caseCommand);
2091
2092       ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
2093               .getSequences());
2094
2095     }
2096   }
2097
2098   public void outputText_actionPerformed(ActionEvent e)
2099   {
2100     CutAndPasteTransfer cap = new CutAndPasteTransfer();
2101     cap.setForInput(null);
2102     Desktop.addInternalFrame(cap, MessageManager.formatMessage(
2103             "label.alignment_output_command", new String[]
2104             { e.getActionCommand() }), 600, 500);
2105
2106     String[] omitHidden = null;
2107
2108     System.out.println("PROMPT USER HERE"); // TODO: decide if a prompt happens
2109     // or we simply trust the user wants
2110     // wysiwig behaviour
2111
2112     cap.setText(new FormatAdapter().formatSequences(e.getActionCommand(), ap.av, true));
2113   }
2114
2115   public void pdbFromFile_actionPerformed()
2116   {
2117     jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(
2118             jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
2119     chooser.setFileView(new jalview.io.JalviewFileView());
2120     chooser.setDialogTitle(MessageManager.formatMessage(
2121             "label.select_pdb_file_for", new String[]
2122             { sequence.getDisplayId(false) }));
2123     chooser.setToolTipText(MessageManager.formatMessage(
2124             "label.load_pdb_file_associate_with_sequence", new String[]
2125             { sequence.getDisplayId(false) }));
2126
2127     int value = chooser.showOpenDialog(null);
2128
2129     if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
2130     {
2131       String choice = chooser.getSelectedFile().getPath();
2132       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
2133       new AssociatePdbFileWithSeq().associatePdbWithSeq(choice,
2134               jalview.io.AppletFormatAdapter.FILE, sequence, true);
2135     }
2136
2137   }
2138
2139   // JBNote: commented out - these won't be instantiated here...!
2140   // public void RNAFold_actionPerformed() throws Exception
2141   // {
2142   // Predict2D P2D = new Predict2D();
2143   // P2D.getStructure2DFromRNAFold("toto");
2144   // }
2145   //
2146   // public void ContraFold_actionPerformed() throws Exception
2147   // {
2148   // Predict2D P2D = new Predict2D();
2149   // P2D.getStructure2DFromContraFold("toto");
2150   // }
2151   public void enterPDB_actionPerformed()
2152   {
2153     String id = JOptionPane.showInternalInputDialog(Desktop.desktop,
2154             MessageManager.getString("label.enter_pdb_id"),
2155             MessageManager.getString("label.enter_pdb_id"),
2156             JOptionPane.QUESTION_MESSAGE);
2157
2158     if (id != null && id.length() > 0)
2159     {
2160       PDBEntry entry = new PDBEntry();
2161       entry.setId(id.toUpperCase());
2162       sequence.getDatasetSequence().addPDBId(entry);
2163     }
2164   }
2165
2166   public void discoverPDB_actionPerformed()
2167   {
2168
2169     final SequenceI[] sequences = ((ap.av.getSelectionGroup() == null) ? new SequenceI[]
2170     { sequence }
2171             : ap.av.getSequenceSelection());
2172     Thread discpdb = new Thread(new Runnable()
2173     {
2174       public void run()
2175       {
2176
2177         new jalview.ws.DBRefFetcher(sequences, ap.alignFrame)
2178                 .fetchDBRefs(false);
2179       }
2180
2181     });
2182     discpdb.start();
2183   }
2184
2185   public void sequenceFeature_actionPerformed()
2186   {
2187     SequenceGroup sg = ap.av.getSelectionGroup();
2188     if (sg == null)
2189     {
2190       return;
2191     }
2192
2193     int rsize = 0, gSize = sg.getSize();
2194     SequenceI[] rseqs, seqs = new SequenceI[gSize];
2195     SequenceFeature[] tfeatures, features = new SequenceFeature[gSize];
2196
2197     for (int i = 0; i < gSize; i++)
2198     {
2199       int start = sg.getSequenceAt(i).findPosition(sg.getStartRes());
2200       int end = sg.findEndRes(sg.getSequenceAt(i));
2201       if (start <= end)
2202       {
2203         seqs[rsize] = sg.getSequenceAt(i).getDatasetSequence();
2204         features[rsize] = new SequenceFeature(null, null, null, start, end,
2205                 "Jalview");
2206         rsize++;
2207       }
2208     }
2209     rseqs = new SequenceI[rsize];
2210     tfeatures = new SequenceFeature[rsize];
2211     System.arraycopy(seqs, 0, rseqs, 0, rsize);
2212     System.arraycopy(features, 0, tfeatures, 0, rsize);
2213     features = tfeatures;
2214     seqs = rseqs;
2215     if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
2216             features, true, ap))
2217     {
2218       ap.alignFrame.setShowSeqFeatures(true);
2219       ap.highlightSearchResults(null);
2220     }
2221   }
2222
2223   public void textColour_actionPerformed()
2224   {
2225     SequenceGroup sg = getGroup();
2226     if (sg != null)
2227     {
2228       new TextColourChooser().chooseColour(ap, sg);
2229     }
2230   }
2231
2232   public void colourByStructure(String pdbid)
2233   {
2234     Annotation[] anots = ap.av.getStructureSelectionManager()
2235             .colourSequenceFromStructure(sequence, pdbid);
2236
2237     AlignmentAnnotation an = new AlignmentAnnotation("Structure",
2238             "Coloured by " + pdbid, anots);
2239
2240     ap.av.getAlignment().addAnnotation(an);
2241     an.createSequenceMapping(sequence, 0, true);
2242     // an.adjustForAlignment();
2243     ap.av.getAlignment().setAnnotationIndex(an, 0);
2244
2245     ap.adjustAnnotationHeight();
2246
2247     sequence.addAlignmentAnnotation(an);
2248
2249   }
2250
2251   public void editSequence_actionPerformed(ActionEvent actionEvent)
2252   {
2253     SequenceGroup sg = ap.av.getSelectionGroup();
2254
2255     if (sg != null)
2256     {
2257       if (sequence == null)
2258         sequence = (Sequence) sg.getSequenceAt(0);
2259
2260       EditNameDialog dialog = new EditNameDialog(
2261               sequence.getSequenceAsString(sg.getStartRes(),
2262                       sg.getEndRes() + 1), null,
2263               MessageManager.getString("label.edit_sequence"), null,
2264               MessageManager.getString("label.edit_sequence"),
2265               ap.alignFrame);
2266
2267       if (dialog.accept)
2268       {
2269         EditCommand editCommand = new EditCommand(
2270                 MessageManager.getString("label.edit_sequences"),
2271                 EditCommand.REPLACE, dialog.getName().replace(' ',
2272                         ap.av.getGapCharacter()),
2273                 sg.getSequencesAsArray(ap.av.getHiddenRepSequences()),
2274                 sg.getStartRes(), sg.getEndRes() + 1, ap.av.getAlignment());
2275
2276         ap.alignFrame.addHistoryItem(editCommand);
2277
2278         ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
2279                 .getSequences());
2280       }
2281     }
2282   }
2283
2284 }