Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.gui

File PopupMenu.java

 

Coverage histogram

../../img/srcFileCovDistChart4.png
45% of files have more coverage

Code metrics

178
660
94
1
2,183
1,631
201
0.3
7.02
94
2.14

Classes

Class Line # Actions
PopupMenu 91 660 201 570
0.3884120338.8%
 

Contributing tests

This file is covered by 13 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ 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.AlignmentAnnotationUtils;
25    import jalview.analysis.AlignmentUtils;
26    import jalview.analysis.Conservation;
27    import jalview.bin.Cache;
28    import jalview.bin.Jalview;
29    import jalview.commands.ChangeCaseCommand;
30    import jalview.commands.EditCommand;
31    import jalview.commands.EditCommand.Action;
32    import jalview.datamodel.AlignmentAnnotation;
33    import jalview.datamodel.AlignmentI;
34    import jalview.datamodel.Annotation;
35    import jalview.datamodel.DBRefEntry;
36    import jalview.datamodel.HiddenColumns;
37    import jalview.datamodel.PDBEntry;
38    import jalview.datamodel.SequenceFeature;
39    import jalview.datamodel.SequenceGroup;
40    import jalview.datamodel.SequenceI;
41    import jalview.gui.ColourMenuHelper.ColourChangeListener;
42    import jalview.gui.JalviewColourChooser.ColourChooserListener;
43    import jalview.io.FileFormatI;
44    import jalview.io.FileFormats;
45    import jalview.io.FormatAdapter;
46    import jalview.io.SequenceAnnotationReport;
47    import jalview.schemes.Blosum62ColourScheme;
48    import jalview.schemes.ColourSchemeI;
49    import jalview.schemes.ColourSchemes;
50    import jalview.schemes.PIDColourScheme;
51    import jalview.util.GroupUrlLink;
52    import jalview.util.GroupUrlLink.UrlStringTooLongException;
53    import jalview.util.MessageManager;
54    import jalview.util.StringUtils;
55    import jalview.util.UrlLink;
56    import jalview.util.dialogrunner.RunResponse;
57   
58    import java.awt.BorderLayout;
59    import java.awt.Color;
60    import java.awt.event.ActionEvent;
61    import java.awt.event.ActionListener;
62    import java.util.ArrayList;
63    import java.util.Arrays;
64    import java.util.BitSet;
65    import java.util.Collection;
66    import java.util.Collections;
67    import java.util.Hashtable;
68    import java.util.LinkedHashMap;
69    import java.util.List;
70    import java.util.Map;
71    import java.util.SortedMap;
72    import java.util.TreeMap;
73    import java.util.Vector;
74   
75    import javax.swing.JCheckBoxMenuItem;
76    import javax.swing.JComponent;
77    import javax.swing.JInternalFrame;
78    import javax.swing.JLabel;
79    import javax.swing.JMenu;
80    import javax.swing.JMenuItem;
81    import javax.swing.JPanel;
82    import javax.swing.JPopupMenu;
83    import javax.swing.JScrollPane;
84   
85    /**
86    * DOCUMENT ME!
87    *
88    * @author $author$
89    * @version $Revision: 1.118 $
90    */
 
91    public class PopupMenu extends JPopupMenu implements ColourChangeListener
92    {
93    JMenu groupMenu = new JMenu();
94   
95    JMenuItem groupName = new JMenuItem();
96   
97    protected JCheckBoxMenuItem abovePIDColour = new JCheckBoxMenuItem();
98   
99    protected JMenuItem modifyPID = new JMenuItem();
100   
101    protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
102   
103    protected JMenuItem modifyConservation = new JMenuItem();
104   
105    AlignmentPanel ap;
106   
107    JMenu sequenceMenu = new JMenu();
108   
109    JMenuItem sequenceName = new JMenuItem();
110   
111    JMenuItem sequenceDetails = new JMenuItem();
112   
113    JMenuItem sequenceSelDetails = new JMenuItem();
114   
115    JMenuItem makeReferenceSeq = new JMenuItem();
116   
117    JMenuItem chooseAnnotations = new JMenuItem();
118   
119    SequenceI sequence;
120   
121    JMenuItem createGroupMenuItem = new JMenuItem();
122   
123    JMenuItem unGroupMenuItem = new JMenuItem();
124   
125    JMenuItem outline = new JMenuItem();
126   
127    JMenu colourMenu = new JMenu();
128   
129    JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem();
130   
131    JCheckBoxMenuItem showText = new JCheckBoxMenuItem();
132   
133    JCheckBoxMenuItem showColourText = new JCheckBoxMenuItem();
134   
135    JCheckBoxMenuItem displayNonconserved = new JCheckBoxMenuItem();
136   
137    JMenu editMenu = new JMenu();
138   
139    JMenuItem cut = new JMenuItem();
140   
141    JMenuItem copy = new JMenuItem();
142   
143    JMenuItem upperCase = new JMenuItem();
144   
145    JMenuItem lowerCase = new JMenuItem();
146   
147    JMenuItem toggle = new JMenuItem();
148   
149    JMenu pdbMenu = new JMenu();
150   
151    JMenu outputMenu = new JMenu();
152   
153    JMenu seqShowAnnotationsMenu = new JMenu();
154   
155    JMenu seqHideAnnotationsMenu = new JMenu();
156   
157    JMenuItem seqAddReferenceAnnotations = new JMenuItem(
158    MessageManager.getString("label.add_reference_annotations"));
159   
160    JMenu groupShowAnnotationsMenu = new JMenu();
161   
162    JMenu groupHideAnnotationsMenu = new JMenu();
163   
164    JMenuItem groupAddReferenceAnnotations = new JMenuItem(
165    MessageManager.getString("label.add_reference_annotations"));
166   
167    JMenuItem sequenceFeature = new JMenuItem();
168   
169    JMenuItem textColour = new JMenuItem();
170   
171    JMenu jMenu1 = new JMenu();
172   
173    JMenuItem pdbStructureDialog = new JMenuItem();
174   
175    JMenu rnaStructureMenu = new JMenu();
176   
177    JMenuItem editSequence = new JMenuItem();
178   
179    JMenu groupLinksMenu;
180   
181    JMenuItem hideInsertions = new JMenuItem();
182   
183    /**
184    * Creates a new PopupMenu object.
185    *
186    * @param ap
187    * @param seq
188    * @param features
189    * non-positional features (for seq not null), or positional features
190    * at residue (for seq equal to null)
191    */
 
192  18 toggle public PopupMenu(final AlignmentPanel ap, SequenceI seq,
193    List<SequenceFeature> features)
194    {
195  18 this(ap, seq, features, null);
196    }
197   
198    /**
199    * Constructor
200    *
201    * @param alignPanel
202    * @param seq
203    * the sequence under the cursor if in the Id panel, null if in the
204    * sequence panel
205    * @param features
206    * non-positional features if in the Id panel, features at the
207    * clicked residue if in the sequence panel
208    * @param groupLinks
209    */
 
210  18 toggle public PopupMenu(final AlignmentPanel alignPanel, final SequenceI seq,
211    List<SequenceFeature> features, List<String> groupLinks)
212    {
213    // /////////////////////////////////////////////////////////
214    // If this is activated from the sequence panel, the user may want to
215    // edit or annotate a particular residue. Therefore display the residue menu
216    //
217    // If from the IDPanel, we must display the sequence menu
218    // ////////////////////////////////////////////////////////
219  18 this.ap = alignPanel;
220  18 sequence = seq;
221   
222  18 for (String ff : FileFormats.getInstance().getWritableFormats(true))
223    {
224  198 JMenuItem item = new JMenuItem(ff);
225   
226  198 item.addActionListener(new ActionListener()
227    {
 
228  0 toggle @Override
229    public void actionPerformed(ActionEvent e)
230    {
231  0 outputText_actionPerformed(e);
232    }
233    });
234   
235  198 outputMenu.add(item);
236    }
237   
238    /*
239    * Build menus for annotation types that may be shown or hidden, and for
240    * 'reference annotations' that may be added to the alignment. First for the
241    * currently selected sequence (if there is one):
242    */
243  18 final List<SequenceI> selectedSequence = (seq == null
244    ? Collections.<SequenceI> emptyList()
245    : Arrays.asList(seq));
246  18 buildAnnotationTypesMenus(seqShowAnnotationsMenu,
247    seqHideAnnotationsMenu, selectedSequence);
248  18 configureReferenceAnnotationsMenu(seqAddReferenceAnnotations,
249    selectedSequence);
250   
251    /*
252    * And repeat for the current selection group (if there is one):
253    */
254  18 final List<SequenceI> selectedGroup = (alignPanel.av.getSelectionGroup() == null
255    ? Collections.<SequenceI> emptyList()
256    : alignPanel.av.getSelectionGroup().getSequences());
257  18 buildAnnotationTypesMenus(groupShowAnnotationsMenu,
258    groupHideAnnotationsMenu, selectedGroup);
259  18 configureReferenceAnnotationsMenu(groupAddReferenceAnnotations,
260    selectedGroup);
261   
262  18 try
263    {
264  18 jbInit();
265    } catch (Exception e)
266    {
267  0 e.printStackTrace();
268    }
269   
270  18 JMenuItem menuItem;
271  18 if (seq != null)
272    {
273  4 sequenceMenu.setText(sequence.getName());
274  4 if (seq == alignPanel.av.getAlignment().getSeqrep())
275    {
276  0 makeReferenceSeq.setText(
277    MessageManager.getString("action.unmark_as_reference"));
278    }
279    else
280    {
281  4 makeReferenceSeq.setText(
282    MessageManager.getString("action.set_as_reference"));
283    }
284   
285  4 if (!alignPanel.av.getAlignment().isNucleotide())
286    {
287  4 remove(rnaStructureMenu);
288    }
289    else
290    {
291  0 int origCount = rnaStructureMenu.getItemCount();
292    /*
293    * add menu items to 2D-render any alignment or sequence secondary
294    * structure annotation
295    */
296  0 AlignmentAnnotation[] aas = alignPanel.av.getAlignment()
297    .getAlignmentAnnotation();
298  0 if (aas != null)
299    {
300  0 for (final AlignmentAnnotation aa : aas)
301    {
302  0 if (aa.isValidStruc() && aa.sequenceRef == null)
303    {
304    /*
305    * valid alignment RNA secondary structure annotation
306    */
307  0 menuItem = new JMenuItem();
308  0 menuItem.setText(MessageManager.formatMessage(
309    "label.2d_rna_structure_line", new Object[]
310    { aa.label }));
311  0 menuItem.addActionListener(new ActionListener()
312    {
 
313  0 toggle @Override
314    public void actionPerformed(ActionEvent e)
315    {
316  0 new AppVarna(seq, aa, alignPanel);
317    }
318    });
319  0 rnaStructureMenu.add(menuItem);
320    }
321    }
322    }
323   
324  0 if (seq.getAnnotation() != null)
325    {
326  0 AlignmentAnnotation seqAnns[] = seq.getAnnotation();
327  0 for (final AlignmentAnnotation aa : seqAnns)
328    {
329  0 if (aa.isValidStruc())
330    {
331    /*
332    * valid sequence RNA secondary structure annotation
333    */
334    // TODO: make rnastrucF a bit more nice
335  0 menuItem = new JMenuItem();
336  0 menuItem.setText(MessageManager.formatMessage(
337    "label.2d_rna_sequence_name", new Object[]
338    { seq.getName() }));
339  0 menuItem.addActionListener(new ActionListener()
340    {
 
341  0 toggle @Override
342    public void actionPerformed(ActionEvent e)
343    {
344    // TODO: VARNA does'nt print gaps in the sequence
345  0 new AppVarna(seq, aa, alignPanel);
346    }
347    });
348  0 rnaStructureMenu.add(menuItem);
349    }
350    }
351    }
352  0 if (rnaStructureMenu.getItemCount() == origCount)
353    {
354  0 remove(rnaStructureMenu);
355    }
356    }
357   
358  4 menuItem = new JMenuItem(
359    MessageManager.getString("action.hide_sequences"));
360  4 menuItem.addActionListener(new ActionListener()
361    {
 
362  0 toggle @Override
363    public void actionPerformed(ActionEvent e)
364    {
365  0 hideSequences(false);
366    }
367    });
368  4 add(menuItem);
369   
370  4 if (alignPanel.av.getSelectionGroup() != null
371    && alignPanel.av.getSelectionGroup().getSize() > 1)
372    {
373  1 menuItem = new JMenuItem(MessageManager
374    .formatMessage("label.represent_group_with", new Object[]
375    { seq.getName() }));
376  1 menuItem.addActionListener(new ActionListener()
377    {
 
378  0 toggle @Override
379    public void actionPerformed(ActionEvent e)
380    {
381  0 hideSequences(true);
382    }
383    });
384  1 sequenceMenu.add(menuItem);
385    }
386   
387  4 if (alignPanel.av.hasHiddenRows())
388    {
389  0 final int index = alignPanel.av.getAlignment().findIndex(seq);
390   
391  0 if (alignPanel.av.adjustForHiddenSeqs(index)
392    - alignPanel.av.adjustForHiddenSeqs(index - 1) > 1)
393    {
394  0 menuItem = new JMenuItem(
395    MessageManager.getString("action.reveal_sequences"));
396  0 menuItem.addActionListener(new ActionListener()
397    {
 
398  0 toggle @Override
399    public void actionPerformed(ActionEvent e)
400    {
401  0 alignPanel.av.showSequence(index);
402  0 if (alignPanel.overviewPanel != null)
403    {
404  0 alignPanel.overviewPanel.updateOverviewImage();
405    }
406    }
407    });
408  0 add(menuItem);
409    }
410    }
411    }
412    // for the case when no sequences are even visible
413  18 if (alignPanel.av.hasHiddenRows())
414    {
415    {
416  0 menuItem = new JMenuItem(
417    MessageManager.getString("action.reveal_all"));
418  0 menuItem.addActionListener(new ActionListener()
419    {
 
420  0 toggle @Override
421    public void actionPerformed(ActionEvent e)
422    {
423  0 alignPanel.av.showAllHiddenSeqs();
424  0 if (alignPanel.overviewPanel != null)
425    {
426  0 alignPanel.overviewPanel.updateOverviewImage();
427    }
428    }
429    });
430   
431  0 add(menuItem);
432    }
433    }
434   
435  18 SequenceGroup sg = alignPanel.av.getSelectionGroup();
436  18 boolean isDefinedGroup = (sg != null)
437    ? alignPanel.av.getAlignment().getGroups().contains(sg)
438    : false;
439   
440  18 if (sg != null && sg.getSize() > 0)
441    {
442  4 groupName.setText(MessageManager
443    .getString("label.edit_name_and_description_current_group"));
444   
445  4 ColourMenuHelper.setColourSelected(colourMenu, sg.getColourScheme());
446   
447  4 conservationMenuItem.setEnabled(!sg.isNucleotide());
448   
449  4 if (sg.cs != null)
450    {
451  4 if (sg.cs.conservationApplied())
452    {
453  0 conservationMenuItem.setSelected(true);
454    }
455  4 if (sg.cs.getThreshold() > 0)
456    {
457  0 abovePIDColour.setSelected(true);
458    }
459    }
460  4 modifyConservation.setEnabled(conservationMenuItem.isSelected());
461  4 modifyPID.setEnabled(abovePIDColour.isSelected());
462  4 displayNonconserved.setSelected(sg.getShowNonconserved());
463  4 showText.setSelected(sg.getDisplayText());
464  4 showColourText.setSelected(sg.getColourText());
465  4 showBoxes.setSelected(sg.getDisplayBoxes());
466    // add any groupURLs to the groupURL submenu and make it visible
467  4 if (groupLinks != null && groupLinks.size() > 0)
468    {
469  0 buildGroupURLMenu(sg, groupLinks);
470    }
471    // Add a 'show all structures' for the current selection
472  4 Hashtable<String, PDBEntry> pdbe = new Hashtable<>(), reppdb = new Hashtable<>();
473   
474  4 SequenceI sqass = null;
475  4 for (SequenceI sq : alignPanel.av.getSequenceSelection())
476    {
477  5 Vector<PDBEntry> pes = sq.getDatasetSequence().getAllPDBEntries();
478  5 if (pes != null && pes.size() > 0)
479    {
480  0 reppdb.put(pes.get(0).getId(), pes.get(0));
481  0 for (PDBEntry pe : pes)
482    {
483  0 pdbe.put(pe.getId(), pe);
484  0 if (sqass == null)
485    {
486  0 sqass = sq;
487    }
488    }
489    }
490    }
491  4 if (pdbe.size() > 0)
492    {
493  0 final PDBEntry[] pe = pdbe.values()
494    .toArray(new PDBEntry[pdbe.size()]),
495    pr = reppdb.values().toArray(new PDBEntry[reppdb.size()]);
496  0 final JMenuItem gpdbview, rpdbview;
497    }
498    }
499    else
500    {
501  14 groupMenu.setVisible(false);
502  14 editMenu.setVisible(false);
503    }
504   
505  18 if (!isDefinedGroup)
506    {
507  18 createGroupMenuItem.setVisible(true);
508  18 unGroupMenuItem.setVisible(false);
509  18 jMenu1.setText(MessageManager.getString("action.edit_new_group"));
510    }
511    else
512    {
513  0 createGroupMenuItem.setVisible(false);
514  0 unGroupMenuItem.setVisible(true);
515  0 jMenu1.setText(MessageManager.getString("action.edit_group"));
516    }
517   
518  18 if (seq == null)
519    {
520  14 sequenceMenu.setVisible(false);
521  14 pdbStructureDialog.setVisible(false);
522  14 rnaStructureMenu.setVisible(false);
523    }
524   
525  18 addLinks(seq, features);
526   
527  18 if (seq == null)
528    {
529  14 addFeatureDetails(features);
530    }
531    }
532   
533    /**
534    * Add a link to show feature details for each sequence feature
535    *
536    * @param features
537    */
 
538  14 toggle protected void addFeatureDetails(List<SequenceFeature> features)
539    {
540  14 if (features == null || features.isEmpty())
541    {
542  14 return;
543    }
544  0 JMenu details = new JMenu(
545    MessageManager.getString("label.feature_details"));
546  0 add(details);
547   
548  0 for (final SequenceFeature sf : features)
549    {
550  0 int start = sf.getBegin();
551  0 int end = sf.getEnd();
552  0 String desc = null;
553  0 if (start == end)
554    {
555  0 desc = String.format("%s %d", sf.getType(), start);
556    }
557    else
558    {
559  0 desc = String.format("%s %d-%d", sf.getType(), start, end);
560    }
561  0 String tooltip = desc;
562  0 String description = sf.getDescription();
563  0 if (description != null)
564    {
565  0 description = StringUtils.stripHtmlTags(description);
566  0 if (description.length() > 12)
567    {
568  0 desc = desc + " " + description.substring(0, 12) + "..";
569    }
570    else
571    {
572  0 desc = desc + " " + description;
573    }
574  0 tooltip = tooltip + " " + description;
575    }
576  0 if (sf.getFeatureGroup() != null)
577    {
578  0 tooltip = tooltip + (" (" + sf.getFeatureGroup() + ")");
579    }
580  0 JMenuItem item = new JMenuItem(desc);
581  0 item.setToolTipText(tooltip);
582  0 item.addActionListener(new ActionListener()
583    {
 
584  0 toggle @Override
585    public void actionPerformed(ActionEvent e)
586    {
587  0 showFeatureDetails(sf);
588    }
589    });
590  0 details.add(item);
591    }
592    }
593   
594    /**
595    * Opens a panel showing a text report of feature dteails
596    *
597    * @param sf
598    */
 
599  0 toggle protected void showFeatureDetails(SequenceFeature sf)
600    {
601  0 JInternalFrame details;
602  0 if (/** @j2sNative true || */ false)
603    {
604  0 details = new JInternalFrame();
605  0 JPanel panel = new JPanel(new BorderLayout());
606  0 panel.setOpaque(true);
607  0 panel.setBackground(Color.white);
608    // TODO JAL-3026 set style of table correctly for feature details
609  0 JLabel reprt = new JLabel(MessageManager.formatMessage("label.html_content",
610    new Object[]
611    { sf.getDetailsReport()}));
612  0 reprt.setBackground(Color.WHITE);
613  0 reprt.setOpaque(true);
614  0 panel.add(reprt,BorderLayout.CENTER);
615  0 details.setContentPane(panel);
616  0 details.pack();
617    }
618    else
619    {
620  0 CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
621    // it appears Java's CSS does not support border-collaps :-(
622  0 cap.addStylesheetRule("table { border-collapse: collapse;}");
623  0 cap.addStylesheetRule("table, td, th {border: 1px solid black;}");
624  0 cap.setText(sf.getDetailsReport());
625  0 details = cap;
626    }
627  0 Desktop.addInternalFrame(details,
628    MessageManager.getString("label.feature_details"), 500, 500);
629    }
630   
631    /**
632    * Adds a 'Link' menu item with a sub-menu item for each hyperlink provided.
633    * When seq is not null, these are links for the sequence id, which may be to
634    * external web sites for the sequence accession, and/or links embedded in
635    * non-positional features. When seq is null, only links embedded in the
636    * provided features are added.
637    *
638    * @param seq
639    * @param features
640    */
 
641  18 toggle void addLinks(final SequenceI seq, List<SequenceFeature> features)
642    {
643  18 JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
644   
645  18 List<String> nlinks = null;
646  18 if (seq != null)
647    {
648  4 nlinks = Preferences.sequenceUrlLinks.getLinksForMenu();
649    }
650    else
651    {
652  14 nlinks = new ArrayList<>();
653    }
654   
655  17 if (features != null)
656    {
657  0 for (SequenceFeature sf : features)
658    {
659  0 if (sf.links != null)
660    {
661  0 for (String link : sf.links)
662    {
663  0 nlinks.add(link);
664    }
665    }
666    }
667    }
668   
669  18 Map<String, List<String>> linkset = new LinkedHashMap<>();
670   
671  18 for (String link : nlinks)
672    {
673  20 UrlLink urlLink = null;
674  20 try
675    {
676  20 urlLink = new UrlLink(link);
677    } catch (Exception foo)
678    {
679  0 Cache.log.error("Exception for URLLink '" + link + "'", foo);
680  0 continue;
681    }
682   
683  20 if (!urlLink.isValid())
684    {
685  0 Cache.log.error(urlLink.getInvalidMessage());
686  0 continue;
687    }
688   
689  20 urlLink.createLinksFromSeq(seq, linkset);
690    }
691   
692  18 addshowLinks(linkMenu, linkset.values());
693   
694    // only add link menu if it has entries
695  18 if (linkMenu.getItemCount() > 0)
696    {
697  4 if (sequence != null)
698    {
699  4 sequenceMenu.add(linkMenu);
700    }
701    else
702    {
703  0 add(linkMenu);
704    }
705    }
706    }
707   
708    /**
709    * Add annotation types to 'Show annotations' and/or 'Hide annotations' menus.
710    * "All" is added first, followed by a separator. Then add any annotation
711    * types associated with the current selection. Separate menus are built for
712    * the selected sequence group (if any), and the selected sequence.
713    * <p>
714    * Some annotation rows are always rendered together - these can be identified
715    * by a common graphGroup property > -1. Only one of each group will be marked
716    * as visible (to avoid duplication of the display). For such groups we add a
717    * composite type name, e.g.
718    * <p>
719    * IUPredWS (Long), IUPredWS (Short)
720    *
721    * @param seq
722    */
 
723  39 toggle protected void buildAnnotationTypesMenus(JMenu showMenu, JMenu hideMenu,
724    List<SequenceI> forSequences)
725    {
726  39 showMenu.removeAll();
727  39 hideMenu.removeAll();
728   
729  39 final List<String> all = Arrays
730    .asList(new String[]
731    { MessageManager.getString("label.all") });
732  39 addAnnotationTypeToShowHide(showMenu, forSequences, "", all, true,
733    true);
734  39 addAnnotationTypeToShowHide(hideMenu, forSequences, "", all, true,
735    false);
736  39 showMenu.addSeparator();
737  39 hideMenu.addSeparator();
738   
739  39 final AlignmentAnnotation[] annotations = ap.getAlignment()
740    .getAlignmentAnnotation();
741   
742    /*
743    * Find shown/hidden annotations types, distinguished by source (calcId),
744    * and grouped by graphGroup. Using LinkedHashMap means we will retrieve in
745    * the insertion order, which is the order of the annotations on the
746    * alignment.
747    */
748  39 Map<String, List<List<String>>> shownTypes = new LinkedHashMap<>();
749  39 Map<String, List<List<String>>> hiddenTypes = new LinkedHashMap<>();
750  39 AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
751    AlignmentAnnotationUtils.asList(annotations), forSequences);
752   
753  39 for (String calcId : hiddenTypes.keySet())
754    {
755  4 for (List<String> type : hiddenTypes.get(calcId))
756    {
757  4 addAnnotationTypeToShowHide(showMenu, forSequences, calcId, type,
758    false, true);
759    }
760    }
761    // grey out 'show annotations' if none are hidden
762  39 showMenu.setEnabled(!hiddenTypes.isEmpty());
763   
764  39 for (String calcId : shownTypes.keySet())
765    {
766  2 for (List<String> type : shownTypes.get(calcId))
767    {
768  4 addAnnotationTypeToShowHide(hideMenu, forSequences, calcId, type,
769    false, false);
770    }
771    }
772    // grey out 'hide annotations' if none are shown
773  39 hideMenu.setEnabled(!shownTypes.isEmpty());
774    }
775   
776    /**
777    * Returns a list of sequences - either the current selection group (if there
778    * is one), else the specified single sequence.
779    *
780    * @param seq
781    * @return
782    */
 
783  0 toggle protected List<SequenceI> getSequenceScope(SequenceI seq)
784    {
785  0 List<SequenceI> forSequences = null;
786  0 final SequenceGroup selectionGroup = ap.av.getSelectionGroup();
787  0 if (selectionGroup != null && selectionGroup.getSize() > 0)
788    {
789  0 forSequences = selectionGroup.getSequences();
790    }
791    else
792    {
793  0 forSequences = seq == null ? Collections.<SequenceI> emptyList()
794    : Arrays.asList(seq);
795    }
796  0 return forSequences;
797    }
798   
799    /**
800    * Add one annotation type to the 'Show Annotations' or 'Hide Annotations'
801    * menus.
802    *
803    * @param showOrHideMenu
804    * the menu to add to
805    * @param forSequences
806    * the sequences whose annotations may be shown or hidden
807    * @param calcId
808    * @param types
809    * the label to add
810    * @param allTypes
811    * if true this is a special label meaning 'All'
812    * @param actionIsShow
813    * if true, the select menu item action is to show the annotation
814    * type, else hide
815    */
 
816  86 toggle protected void addAnnotationTypeToShowHide(JMenu showOrHideMenu,
817    final List<SequenceI> forSequences, String calcId,
818    final List<String> types, final boolean allTypes,
819    final boolean actionIsShow)
820    {
821  86 String label = types.toString(); // [a, b, c]
822  86 label = label.substring(1, label.length() - 1); // a, b, c
823  86 final JMenuItem item = new JMenuItem(label);
824  86 item.setToolTipText(calcId);
825  86 item.addActionListener(new ActionListener()
826    {
 
827  0 toggle @Override
828    public void actionPerformed(ActionEvent e)
829    {
830  0 AlignmentUtils.showOrHideSequenceAnnotations(ap.getAlignment(),
831    types, forSequences, allTypes, actionIsShow);
832  0 refresh();
833    }
834    });
835  86 showOrHideMenu.add(item);
836    }
837   
 
838  0 toggle private void buildGroupURLMenu(SequenceGroup sg, List<String> groupLinks)
839    {
840   
841    // TODO: usability: thread off the generation of group url content so root
842    // menu appears asap
843    // sequence only URLs
844    // ID/regex match URLs
845  0 groupLinksMenu = new JMenu(
846    MessageManager.getString("action.group_link"));
847    // three types of url that might be created.
848  0 JMenu[] linkMenus = new JMenu[] { null,
849    new JMenu(MessageManager.getString("action.ids")),
850    new JMenu(MessageManager.getString("action.sequences")),
851    new JMenu(MessageManager.getString("action.ids_sequences")) };
852   
853  0 SequenceI[] seqs = ap.av.getSelectionAsNewSequence();
854  0 String[][] idandseqs = GroupUrlLink.formStrings(seqs);
855  0 Hashtable<String, Object[]> commonDbrefs = new Hashtable<>();
856  0 for (int sq = 0; sq < seqs.length; sq++)
857    {
858   
859  0 int start = seqs[sq].findPosition(sg.getStartRes()),
860    end = seqs[sq].findPosition(sg.getEndRes());
861    // just collect ids from dataset sequence
862    // TODO: check if IDs collected from selecton group intersects with the
863    // current selection, too
864  0 SequenceI sqi = seqs[sq];
865  0 while (sqi.getDatasetSequence() != null)
866    {
867  0 sqi = sqi.getDatasetSequence();
868    }
869  0 DBRefEntry[] dbr = sqi.getDBRefs();
870  0 if (dbr != null && dbr.length > 0)
871    {
872  0 for (int d = 0; d < dbr.length; d++)
873    {
874  0 String src = dbr[d].getSource(); // jalview.util.DBRefUtils.getCanonicalName(dbr[d].getSource()).toUpperCase();
875  0 Object[] sarray = commonDbrefs.get(src);
876  0 if (sarray == null)
877    {
878  0 sarray = new Object[2];
879  0 sarray[0] = new int[] { 0 };
880  0 sarray[1] = new String[seqs.length];
881   
882  0 commonDbrefs.put(src, sarray);
883    }
884   
885  0 if (((String[]) sarray[1])[sq] == null)
886    {
887  0 if (!dbr[d].hasMap() || (dbr[d].getMap()
888    .locateMappedRange(start, end) != null))
889    {
890  0 ((String[]) sarray[1])[sq] = dbr[d].getAccessionId();
891  0 ((int[]) sarray[0])[0]++;
892    }
893    }
894    }
895    }
896    }
897    // now create group links for all distinct ID/sequence sets.
898  0 boolean addMenu = false; // indicates if there are any group links to give
899    // to user
900  0 for (String link : groupLinks)
901    {
902  0 GroupUrlLink urlLink = null;
903  0 try
904    {
905  0 urlLink = new GroupUrlLink(link);
906    } catch (Exception foo)
907    {
908  0 Cache.log.error("Exception for GroupURLLink '" + link + "'", foo);
909  0 continue;
910    }
911  0 ;
912  0 if (!urlLink.isValid())
913    {
914  0 Cache.log.error(urlLink.getInvalidMessage());
915  0 continue;
916    }
917  0 final String label = urlLink.getLabel();
918  0 boolean usingNames = false;
919    // Now see which parts of the group apply for this URL
920  0 String ltarget = urlLink.getTarget(); // jalview.util.DBRefUtils.getCanonicalName(urlLink.getTarget());
921  0 Object[] idset = commonDbrefs.get(ltarget.toUpperCase());
922  0 String[] seqstr, ids; // input to makeUrl
923  0 if (idset != null)
924    {
925  0 int numinput = ((int[]) idset[0])[0];
926  0 String[] allids = ((String[]) idset[1]);
927  0 seqstr = new String[numinput];
928  0 ids = new String[numinput];
929  0 for (int sq = 0, idcount = 0; sq < seqs.length; sq++)
930    {
931  0 if (allids[sq] != null)
932    {
933  0 ids[idcount] = allids[sq];
934  0 seqstr[idcount++] = idandseqs[1][sq];
935    }
936    }
937    }
938    else
939    {
940    // just use the id/seq set
941  0 seqstr = idandseqs[1];
942  0 ids = idandseqs[0];
943  0 usingNames = true;
944    }
945    // and try and make the groupURL!
946   
947  0 Object[] urlset = null;
948  0 try
949    {
950  0 urlset = urlLink.makeUrlStubs(ids, seqstr,
951    "FromJalview" + System.currentTimeMillis(), false);
952    } catch (UrlStringTooLongException e)
953    {
954    }
955  0 if (urlset != null)
956    {
957  0 int type = urlLink.getGroupURLType() & 3;
958    // first two bits ofurlLink type bitfield are sequenceids and sequences
959    // TODO: FUTURE: ensure the groupURL menu structure can be generalised
960  0 addshowLink(linkMenus[type],
961  0 label + (((type & 1) == 1)
962  0 ? ("(" + (usingNames ? "Names" : ltarget) + ")")
963    : ""),
964    urlLink, urlset);
965  0 addMenu = true;
966    }
967    }
968  0 if (addMenu)
969    {
970  0 groupLinksMenu = new JMenu(
971    MessageManager.getString("action.group_link"));
972  0 for (int m = 0; m < linkMenus.length; m++)
973    {
974  0 if (linkMenus[m] != null
975    && linkMenus[m].getMenuComponentCount() > 0)
976    {
977  0 groupLinksMenu.add(linkMenus[m]);
978    }
979    }
980   
981  0 groupMenu.add(groupLinksMenu);
982    }
983    }
984   
 
985  18 toggle private void addshowLinks(JMenu linkMenu,
986    Collection<List<String>> linkset)
987    {
988  18 for (List<String> linkstrset : linkset)
989    {
990    // split linkstr into label and url
991  12 addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
992    }
993    }
994   
995    /**
996    * add a show URL menu item to the given linkMenu
997    *
998    * @param linkMenu
999    * @param label
1000    * - menu label string
1001    * @param url
1002    * - url to open
1003    */
 
1004  12 toggle private void addshowLink(JMenu linkMenu, String label, final String url)
1005    {
1006  12 JMenuItem item = new JMenuItem(label);
1007  12 item.setToolTipText(MessageManager.formatMessage("label.open_url_param",
1008    new Object[]
1009    { url }));
1010  12 item.addActionListener(new ActionListener()
1011    {
 
1012  0 toggle @Override
1013    public void actionPerformed(ActionEvent e)
1014    {
1015  0 new Thread(new Runnable()
1016    {
1017   
 
1018  0 toggle @Override
1019    public void run()
1020    {
1021  0 showLink(url);
1022    }
1023   
1024    }).start();
1025    }
1026    });
1027   
1028  12 linkMenu.add(item);
1029    }
1030   
1031    /**
1032    * add a late bound groupURL item to the given linkMenu
1033    *
1034    * @param linkMenu
1035    * @param label
1036    * - menu label string
1037    * @param urlgenerator
1038    * GroupURLLink used to generate URL
1039    * @param urlstub
1040    * Object array returned from the makeUrlStubs function.
1041    */
 
1042  0 toggle private void addshowLink(JMenu linkMenu, String label,
1043    final GroupUrlLink urlgenerator, final Object[] urlstub)
1044    {
1045  0 JMenuItem item = new JMenuItem(label);
1046  0 item.setToolTipText(MessageManager
1047    .formatMessage("label.open_url_seqs_param", new Object[]
1048    { urlgenerator.getUrl_prefix(),
1049    urlgenerator.getNumberInvolved(urlstub) }));
1050    // TODO: put in info about what is being sent.
1051  0 item.addActionListener(new ActionListener()
1052    {
 
1053  0 toggle @Override
1054    public void actionPerformed(ActionEvent e)
1055    {
1056  0 new Thread(new Runnable()
1057    {
1058   
 
1059  0 toggle @Override
1060    public void run()
1061    {
1062  0 try
1063    {
1064  0 showLink(urlgenerator.constructFrom(urlstub));
1065    } catch (UrlStringTooLongException e2)
1066    {
1067    }
1068    }
1069   
1070    }).start();
1071    }
1072    });
1073   
1074  0 linkMenu.add(item);
1075    }
1076   
1077    /**
1078    * DOCUMENT ME!
1079    *
1080    * @throws Exception
1081    * DOCUMENT ME!
1082    */
 
1083  18 toggle private void jbInit() throws Exception
1084    {
1085  18 groupMenu.setText(MessageManager.getString("label.selection"));
1086  18 groupName.setText(MessageManager.getString("label.name"));
1087  18 groupName.addActionListener(new ActionListener()
1088    {
 
1089  0 toggle @Override
1090    public void actionPerformed(ActionEvent e)
1091    {
1092  0 groupName_actionPerformed();
1093    }
1094    });
1095  18 sequenceMenu.setText(MessageManager.getString("label.sequence"));
1096  18 sequenceName.setText(
1097    MessageManager.getString("label.edit_name_description"));
1098  18 sequenceName.addActionListener(new ActionListener()
1099    {
 
1100  0 toggle @Override
1101    public void actionPerformed(ActionEvent e)
1102    {
1103  0 sequenceName_actionPerformed();
1104    }
1105    });
1106  18 chooseAnnotations
1107    .setText(MessageManager.getString("action.choose_annotations"));
1108  18 chooseAnnotations.addActionListener(new ActionListener()
1109    {
 
1110  0 toggle @Override
1111    public void actionPerformed(ActionEvent e)
1112    {
1113  0 chooseAnnotations_actionPerformed(e);
1114    }
1115    });
1116  18 sequenceDetails
1117    .setText(MessageManager.getString("label.sequence_details"));
1118  18 sequenceDetails.addActionListener(new ActionListener()
1119    {
 
1120  0 toggle @Override
1121    public void actionPerformed(ActionEvent e)
1122    {
1123  0 sequenceDetails_actionPerformed();
1124    }
1125    });
1126  18 sequenceSelDetails
1127    .setText(MessageManager.getString("label.sequence_details"));
1128  18 sequenceSelDetails.addActionListener(new ActionListener()
1129    {
 
1130  0 toggle @Override
1131    public void actionPerformed(ActionEvent e)
1132    {
1133  0 sequenceSelectionDetails_actionPerformed();
1134    }
1135    });
1136   
1137  18 unGroupMenuItem
1138    .setText(MessageManager.getString("action.remove_group"));
1139  18 unGroupMenuItem.addActionListener(new ActionListener()
1140    {
 
1141  0 toggle @Override
1142    public void actionPerformed(ActionEvent e)
1143    {
1144  0 unGroupMenuItem_actionPerformed();
1145    }
1146    });
1147  18 createGroupMenuItem
1148    .setText(MessageManager.getString("action.create_group"));
1149  18 createGroupMenuItem.addActionListener(new ActionListener()
1150    {
 
1151  0 toggle @Override
1152    public void actionPerformed(ActionEvent e)
1153    {
1154  0 createGroupMenuItem_actionPerformed();
1155    }
1156    });
1157   
1158  18 outline.setText(MessageManager.getString("action.border_colour"));
1159  18 outline.addActionListener(new ActionListener()
1160    {
 
1161  0 toggle @Override
1162    public void actionPerformed(ActionEvent e)
1163    {
1164  0 outline_actionPerformed();
1165    }
1166    });
1167  18 showBoxes.setText(MessageManager.getString("action.boxes"));
1168  18 showBoxes.setState(true);
1169  18 showBoxes.addActionListener(new ActionListener()
1170    {
 
1171  0 toggle @Override
1172    public void actionPerformed(ActionEvent e)
1173    {
1174  0 showBoxes_actionPerformed();
1175    }
1176    });
1177  18 showText.setText(MessageManager.getString("action.text"));
1178  18 showText.setState(true);
1179  18 showText.addActionListener(new ActionListener()
1180    {
 
1181  0 toggle @Override
1182    public void actionPerformed(ActionEvent e)
1183    {
1184  0 showText_actionPerformed();
1185    }
1186    });
1187  18 showColourText.setText(MessageManager.getString("label.colour_text"));
1188  18 showColourText.addActionListener(new ActionListener()
1189    {
 
1190  0 toggle @Override
1191    public void actionPerformed(ActionEvent e)
1192    {
1193  0 showColourText_actionPerformed();
1194    }
1195    });
1196  18 displayNonconserved
1197    .setText(MessageManager.getString("label.show_non_conserved"));
1198  18 displayNonconserved.setState(true);
1199  18 displayNonconserved.addActionListener(new ActionListener()
1200    {
 
1201  0 toggle @Override
1202    public void actionPerformed(ActionEvent e)
1203    {
1204  0 showNonconserved_actionPerformed();
1205    }
1206    });
1207  18 editMenu.setText(MessageManager.getString("action.edit"));
1208  18 cut.setText(MessageManager.getString("action.cut"));
1209  18 cut.addActionListener(new ActionListener()
1210    {
 
1211  0 toggle @Override
1212    public void actionPerformed(ActionEvent e)
1213    {
1214  0 cut_actionPerformed();
1215    }
1216    });
1217  18 upperCase.setText(MessageManager.getString("label.to_upper_case"));
1218  18 upperCase.addActionListener(new ActionListener()
1219    {
 
1220  0 toggle @Override
1221    public void actionPerformed(ActionEvent e)
1222    {
1223  0 changeCase(e);
1224    }
1225    });
1226  18 copy.setText(MessageManager.getString("action.copy"));
1227  18 copy.addActionListener(new ActionListener()
1228    {
 
1229  0 toggle @Override
1230    public void actionPerformed(ActionEvent e)
1231    {
1232  0 copy_actionPerformed();
1233    }
1234    });
1235  18 lowerCase.setText(MessageManager.getString("label.to_lower_case"));
1236  18 lowerCase.addActionListener(new ActionListener()
1237    {
 
1238  0 toggle @Override
1239    public void actionPerformed(ActionEvent e)
1240    {
1241  0 changeCase(e);
1242    }
1243    });
1244  18 toggle.setText(MessageManager.getString("label.toggle_case"));
1245  18 toggle.addActionListener(new ActionListener()
1246    {
 
1247  0 toggle @Override
1248    public void actionPerformed(ActionEvent e)
1249    {
1250  0 changeCase(e);
1251    }
1252    });
1253  18 outputMenu.setText(
1254    MessageManager.getString("label.out_to_textbox") + "...");
1255  18 seqShowAnnotationsMenu
1256    .setText(MessageManager.getString("label.show_annotations"));
1257  18 seqHideAnnotationsMenu
1258    .setText(MessageManager.getString("label.hide_annotations"));
1259  18 groupShowAnnotationsMenu
1260    .setText(MessageManager.getString("label.show_annotations"));
1261  18 groupHideAnnotationsMenu
1262    .setText(MessageManager.getString("label.hide_annotations"));
1263  18 sequenceFeature.setText(
1264    MessageManager.getString("label.create_sequence_feature"));
1265  18 sequenceFeature.addActionListener(new ActionListener()
1266    {
 
1267  0 toggle @Override
1268    public void actionPerformed(ActionEvent e)
1269    {
1270  0 sequenceFeature_actionPerformed();
1271    }
1272    });
1273  18 jMenu1.setText(MessageManager.getString("label.group"));
1274  18 pdbStructureDialog.setText(
1275    MessageManager.getString("label.show_pdbstruct_dialog"));
1276  18 pdbStructureDialog.addActionListener(new ActionListener()
1277    {
 
1278  0 toggle @Override
1279    public void actionPerformed(ActionEvent actionEvent)
1280    {
1281  0 SequenceI[] selectedSeqs = new SequenceI[] { sequence };
1282  0 if (ap.av.getSelectionGroup() != null)
1283    {
1284  0 selectedSeqs = ap.av.getSequenceSelection();
1285    }
1286  0 new StructureChooser(selectedSeqs, sequence, ap);
1287    }
1288    });
1289   
1290  18 rnaStructureMenu
1291    .setText(MessageManager.getString("label.view_rna_structure"));
1292   
1293    // colStructureMenu.setText("Colour By Structure");
1294  18 editSequence.setText(
1295    MessageManager.getString("label.edit_sequence") + "...");
1296  18 editSequence.addActionListener(new ActionListener()
1297    {
 
1298  0 toggle @Override
1299    public void actionPerformed(ActionEvent actionEvent)
1300    {
1301  0 editSequence_actionPerformed();
1302    }
1303    });
1304  18 makeReferenceSeq.setText(
1305    MessageManager.getString("label.mark_as_representative"));
1306  18 makeReferenceSeq.addActionListener(new ActionListener()
1307    {
1308   
 
1309  0 toggle @Override
1310    public void actionPerformed(ActionEvent actionEvent)
1311    {
1312  0 makeReferenceSeq_actionPerformed(actionEvent);
1313   
1314    }
1315    });
1316  18 hideInsertions
1317    .setText(MessageManager.getString("label.hide_insertions"));
1318  18 hideInsertions.addActionListener(new ActionListener()
1319    {
1320   
 
1321  0 toggle @Override
1322    public void actionPerformed(ActionEvent e)
1323    {
1324  0 hideInsertions_actionPerformed(e);
1325    }
1326    });
1327   
1328  18 groupMenu.add(sequenceSelDetails);
1329  18 add(groupMenu);
1330  18 add(sequenceMenu);
1331  18 add(rnaStructureMenu);
1332  18 add(pdbStructureDialog);
1333  18 if (sequence != null)
1334    {
1335  4 add(hideInsertions);
1336    }
1337    // annotations configuration panel suppressed for now
1338    // groupMenu.add(chooseAnnotations);
1339   
1340    /*
1341    * Add show/hide annotations to the Sequence menu, and to the Selection menu
1342    * (if a selection group is in force).
1343    */
1344  18 sequenceMenu.add(seqShowAnnotationsMenu);
1345  18 sequenceMenu.add(seqHideAnnotationsMenu);
1346  18 sequenceMenu.add(seqAddReferenceAnnotations);
1347  18 groupMenu.add(groupShowAnnotationsMenu);
1348  18 groupMenu.add(groupHideAnnotationsMenu);
1349  18 groupMenu.add(groupAddReferenceAnnotations);
1350  18 groupMenu.add(editMenu);
1351  18 groupMenu.add(outputMenu);
1352  18 groupMenu.add(sequenceFeature);
1353  18 groupMenu.add(createGroupMenuItem);
1354  18 groupMenu.add(unGroupMenuItem);
1355  18 groupMenu.add(jMenu1);
1356  18 sequenceMenu.add(sequenceName);
1357  18 sequenceMenu.add(sequenceDetails);
1358  18 sequenceMenu.add(makeReferenceSeq);
1359   
1360  18 initColourMenu();
1361  18 buildColourMenu();
1362   
1363  18 editMenu.add(copy);
1364  18 editMenu.add(cut);
1365  18 editMenu.add(editSequence);
1366  18 editMenu.add(upperCase);
1367  18 editMenu.add(lowerCase);
1368  18 editMenu.add(toggle);
1369    // JBPNote: These shouldn't be added here - should appear in a generic
1370    // 'apply web service to this sequence menu'
1371    // pdbMenu.add(RNAFold);
1372    // pdbMenu.add(ContraFold);
1373  18 jMenu1.add(groupName);
1374  18 jMenu1.add(colourMenu);
1375  18 jMenu1.add(showBoxes);
1376  18 jMenu1.add(showText);
1377  18 jMenu1.add(showColourText);
1378  18 jMenu1.add(outline);
1379  18 jMenu1.add(displayNonconserved);
1380    }
1381   
1382    /**
1383    * Constructs the entries for the colour menu
1384    */
 
1385  18 toggle protected void initColourMenu()
1386    {
1387  18 colourMenu.setText(MessageManager.getString("label.group_colour"));
1388  18 textColour.setText(MessageManager.getString("label.text_colour"));
1389  18 textColour.addActionListener(new ActionListener()
1390    {
 
1391  0 toggle @Override
1392    public void actionPerformed(ActionEvent e)
1393    {
1394  0 textColour_actionPerformed();
1395    }
1396    });
1397   
1398  18 abovePIDColour.setText(
1399    MessageManager.getString("label.above_identity_threshold"));
1400  18 abovePIDColour.addActionListener(new ActionListener()
1401    {
 
1402  0 toggle @Override
1403    public void actionPerformed(ActionEvent e)
1404    {
1405  0 abovePIDColour_actionPerformed(abovePIDColour.isSelected());
1406    }
1407    });
1408   
1409  18 modifyPID.setText(
1410    MessageManager.getString("label.modify_identity_threshold"));
1411  18 modifyPID.addActionListener(new ActionListener()
1412    {
 
1413  0 toggle @Override
1414    public void actionPerformed(ActionEvent e)
1415    {
1416  0 modifyPID_actionPerformed();
1417    }
1418    });
1419   
1420  18 conservationMenuItem
1421    .setText(MessageManager.getString("action.by_conservation"));
1422  18 conservationMenuItem.addActionListener(new ActionListener()
1423    {
 
1424  0 toggle @Override
1425    public void actionPerformed(ActionEvent e)
1426    {
1427  0 conservationMenuItem_actionPerformed(
1428    conservationMenuItem.isSelected());
1429    }
1430    });
1431   
1432  18 modifyConservation.setText(MessageManager
1433    .getString("label.modify_conservation_threshold"));
1434  18 modifyConservation.addActionListener(new ActionListener()
1435    {
 
1436  0 toggle @Override
1437    public void actionPerformed(ActionEvent e)
1438    {
1439  0 modifyConservation_actionPerformed();
1440    }
1441    });
1442    }
1443   
1444    /**
1445    * Builds the group colour sub-menu, including any user-defined colours which
1446    * were loaded at startup or during the Jalview session
1447    */
 
1448  18 toggle protected void buildColourMenu()
1449    {
1450  18 SequenceGroup sg = ap.av.getSelectionGroup();
1451  18 if (sg == null)
1452    {
1453    /*
1454    * popup menu with no sequence group scope
1455    */
1456  14 return;
1457    }
1458  4 colourMenu.removeAll();
1459  4 colourMenu.add(textColour);
1460  4 colourMenu.addSeparator();
1461   
1462  4 ColourMenuHelper.addMenuItems(colourMenu, this, sg, false);
1463   
1464  4 colourMenu.addSeparator();
1465  4 colourMenu.add(conservationMenuItem);
1466  4 colourMenu.add(modifyConservation);
1467  4 colourMenu.add(abovePIDColour);
1468  4 colourMenu.add(modifyPID);
1469    }
1470   
 
1471  0 toggle protected void modifyConservation_actionPerformed()
1472    {
1473  0 SequenceGroup sg = getGroup();
1474  0 if (sg.cs != null)
1475    {
1476  0 SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
1477  0 SliderPanel.showConservationSlider();
1478    }
1479    }
1480   
 
1481  0 toggle protected void modifyPID_actionPerformed()
1482    {
1483  0 SequenceGroup sg = getGroup();
1484  0 if (sg.cs != null)
1485    {
1486    // int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup()
1487    // .getName());
1488    // sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus());
1489  0 SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup().getName());
1490  0 SliderPanel.showPIDSlider();
1491    }
1492    }
1493   
1494    /**
1495    * Check for any annotations on the underlying dataset sequences (for the
1496    * current selection group) which are not 'on the alignment'.If any are found,
1497    * enable the option to add them to the alignment. The criteria for 'on the
1498    * alignment' is finding an alignment annotation on the alignment, matched on
1499    * calcId, label and sequenceRef.
1500    *
1501    * A tooltip is also constructed that displays the source (calcId) and type
1502    * (label) of the annotations that can be added.
1503    *
1504    * @param menuItem
1505    * @param forSequences
1506    */
 
1507  42 toggle protected void configureReferenceAnnotationsMenu(JMenuItem menuItem,
1508    List<SequenceI> forSequences)
1509    {
1510  42 menuItem.setEnabled(false);
1511   
1512    /*
1513    * Temporary store to hold distinct calcId / type pairs for the tooltip.
1514    * Using TreeMap means calcIds are shown in alphabetical order.
1515    */
1516  42 SortedMap<String, String> tipEntries = new TreeMap<>();
1517  42 final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
1518  42 AlignmentI al = this.ap.av.getAlignment();
1519  42 AlignmentUtils.findAddableReferenceAnnotations(forSequences, tipEntries,
1520    candidates, al);
1521  42 if (!candidates.isEmpty())
1522    {
1523  2 StringBuilder tooltip = new StringBuilder(64);
1524  2 tooltip.append(MessageManager.getString("label.add_annotations_for"));
1525   
1526    /*
1527    * Found annotations that could be added. Enable the menu item, and
1528    * configure its tooltip and action.
1529    */
1530  2 menuItem.setEnabled(true);
1531  2 for (String calcId : tipEntries.keySet())
1532    {
1533  4 tooltip.append("<br/>" + calcId + "/" + tipEntries.get(calcId));
1534    }
1535  2 String tooltipText = JvSwingUtils.wrapTooltip(true,
1536    tooltip.toString());
1537  2 menuItem.setToolTipText(tooltipText);
1538   
1539  2 menuItem.addActionListener(new ActionListener()
1540    {
 
1541  0 toggle @Override
1542    public void actionPerformed(ActionEvent e)
1543    {
1544  0 addReferenceAnnotations_actionPerformed(candidates);
1545    }
1546    });
1547    }
1548    }
1549   
1550    /**
1551    * Add annotations to the sequences and to the alignment.
1552    *
1553    * @param candidates
1554    * a map whose keys are sequences on the alignment, and values a list
1555    * of annotations to add to each sequence
1556    */
 
1557  0 toggle protected void addReferenceAnnotations_actionPerformed(
1558    Map<SequenceI, List<AlignmentAnnotation>> candidates)
1559    {
1560  0 final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup();
1561  0 final AlignmentI alignment = this.ap.getAlignment();
1562  0 AlignmentUtils.addReferenceAnnotations(candidates, alignment,
1563    selectionGroup);
1564  0 refresh();
1565    }
1566   
 
1567  0 toggle protected void makeReferenceSeq_actionPerformed(ActionEvent actionEvent)
1568    {
1569  0 if (!ap.av.getAlignment().hasSeqrep())
1570    {
1571    // initialise the display flags so the user sees something happen
1572  0 ap.av.setDisplayReferenceSeq(true);
1573  0 ap.av.setColourByReferenceSeq(true);
1574  0 ap.av.getAlignment().setSeqrep(sequence);
1575    }
1576    else
1577    {
1578  0 if (ap.av.getAlignment().getSeqrep() == sequence)
1579    {
1580  0 ap.av.getAlignment().setSeqrep(null);
1581    }
1582    else
1583    {
1584  0 ap.av.getAlignment().setSeqrep(sequence);
1585    }
1586    }
1587  0 refresh();
1588    }
1589   
 
1590  3 toggle protected void hideInsertions_actionPerformed(ActionEvent actionEvent)
1591    {
1592  3 HiddenColumns hidden = ap.av.getAlignment().getHiddenColumns();
1593  3 BitSet inserts = new BitSet();
1594   
1595  3 boolean markedPopup = false;
1596    // mark inserts in current selection
1597  3 if (ap.av.getSelectionGroup() != null)
1598    {
1599    // mark just the columns in the selection group to be hidden
1600  1 inserts.set(ap.av.getSelectionGroup().getStartRes(),
1601    ap.av.getSelectionGroup().getEndRes() + 1); // TODO why +1?
1602   
1603    // now clear columns without gaps
1604  1 for (SequenceI sq : ap.av.getSelectionGroup().getSequences())
1605    {
1606  2 if (sq == sequence)
1607    {
1608  1 markedPopup = true;
1609    }
1610  2 inserts.and(sq.getInsertionsAsBits());
1611    }
1612  1 hidden.clearAndHideColumns(inserts, ap.av.getSelectionGroup().getStartRes(),
1613    ap.av.getSelectionGroup().getEndRes());
1614    }
1615   
1616    // now mark for sequence under popup if we haven't already done it
1617  2 else if (!markedPopup && sequence != null)
1618    {
1619  2 inserts.or(sequence.getInsertionsAsBits());
1620   
1621    // and set hidden columns accordingly
1622  2 hidden.hideColumns(inserts);
1623    }
1624  3 refresh();
1625    }
1626   
 
1627  0 toggle protected void sequenceSelectionDetails_actionPerformed()
1628    {
1629  0 createSequenceDetailsReport(ap.av.getSequenceSelection());
1630    }
1631   
 
1632  0 toggle protected void sequenceDetails_actionPerformed()
1633    {
1634  0 createSequenceDetailsReport(new SequenceI[] { sequence });
1635    }
1636   
 
1637  0 toggle public void createSequenceDetailsReport(SequenceI[] sequences)
1638    {
1639  0 StringBuilder contents = new StringBuilder(128);
1640  0 contents.append("<html><body>");
1641  0 for (SequenceI seq : sequences)
1642    {
1643  0 contents.append("<p><h2>" + MessageManager.formatMessage(
1644    "label.create_sequence_details_report_annotation_for",
1645    new Object[]
1646    { seq.getDisplayId(true) }) + "</h2></p><p>");
1647  0 new SequenceAnnotationReport(null).createSequenceAnnotationReport(
1648    contents, seq, true, true, ap.getSeqPanel().seqCanvas.fr);
1649  0 contents.append("</p>");
1650    }
1651  0 contents.append("</body></html>");
1652  0 String report = contents.toString();
1653   
1654  0 JInternalFrame frame;
1655  0 if (Jalview.isJS())
1656    {
1657  0 JLabel textLabel = new JLabel();
1658  0 textLabel.setText(report);
1659  0 textLabel.setBackground(Color.WHITE);
1660  0 JPanel pane = new JPanel(new BorderLayout());
1661  0 ((JPanel) pane).setOpaque(true);
1662  0 pane.setBackground(Color.WHITE);
1663  0 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
1664  0 frame = new JInternalFrame();
1665  0 frame.getContentPane().add(new JScrollPane(pane));
1666    }
1667    else
1668    {
1669  0 CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
1670  0 cap.setText(report);
1671  0 frame = cap;
1672    }
1673   
1674  0 Desktop.addInternalFrame(frame,
1675    MessageManager.formatMessage("label.sequence_details_for",
1676  0 (sequences.length == 1 ? new Object[]
1677    { sequences[0].getDisplayId(true) }
1678    : new Object[]
1679    { MessageManager
1680    .getString("label.selection") })),
1681    500, 400);
1682    }
1683   
 
1684  0 toggle protected void showNonconserved_actionPerformed()
1685    {
1686  0 getGroup().setShowNonconserved(displayNonconserved.isSelected());
1687  0 refresh();
1688    }
1689   
1690    /**
1691    * call to refresh view after settings change
1692    */
 
1693  12 toggle void refresh()
1694    {
1695  12 ap.updateAnnotation();
1696    // removed paintAlignment(true) here:
1697    // updateAnnotation calls paintAlignment already, so don't need to call
1698    // again
1699   
1700  12 PaintRefresher.Refresh(this, ap.av.getSequenceSetId());
1701    }
1702   
1703    /*
1704    * protected void covariationColour_actionPerformed() { getGroup().cs = new
1705    * CovariationColourScheme(sequence.getAnnotation()[0]); refresh(); }
1706    */
1707    /**
1708    * DOCUMENT ME!
1709    *
1710    * @param selected
1711    *
1712    * @param e
1713    * DOCUMENT ME!
1714    */
 
1715  3 toggle public void abovePIDColour_actionPerformed(boolean selected)
1716    {
1717  3 SequenceGroup sg = getGroup();
1718  3 if (sg.cs == null)
1719    {
1720  0 return;
1721    }
1722   
1723  3 if (selected)
1724    {
1725  3 sg.cs.setConsensus(AAFrequency.calculate(
1726    sg.getSequences(ap.av.getHiddenRepSequences()),
1727    sg.getStartRes(), sg.getEndRes() + 1));
1728   
1729  3 int threshold = SliderPanel.setPIDSliderSource(ap,
1730    sg.getGroupColourScheme(), getGroup().getName());
1731   
1732  3 sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus());
1733   
1734  3 SliderPanel.showPIDSlider();
1735    }
1736    else
1737    // remove PIDColouring
1738    {
1739  0 sg.cs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
1740  0 SliderPanel.hidePIDSlider();
1741    }
1742  3 modifyPID.setEnabled(selected);
1743   
1744  3 refresh();
1745    }
1746   
1747    /**
1748    * Open a panel where the user can choose which types of sequence annotation
1749    * to show or hide.
1750    *
1751    * @param e
1752    */
 
1753  0 toggle protected void chooseAnnotations_actionPerformed(ActionEvent e)
1754    {
1755    // todo correct way to guard against opening a duplicate panel?
1756  0 new AnnotationChooser(ap);
1757    }
1758   
1759    /**
1760    * DOCUMENT ME!
1761    *
1762    * @param e
1763    * DOCUMENT ME!
1764    */
 
1765  3 toggle public void conservationMenuItem_actionPerformed(boolean selected)
1766    {
1767  3 SequenceGroup sg = getGroup();
1768  3 if (sg.cs == null)
1769    {
1770  0 return;
1771    }
1772   
1773  3 if (selected)
1774    {
1775    // JBPNote: Conservation name shouldn't be i18n translated
1776  3 Conservation c = new Conservation("Group",
1777    sg.getSequences(ap.av.getHiddenRepSequences()),
1778    sg.getStartRes(), sg.getEndRes() + 1);
1779   
1780  3 c.calculate();
1781  3 c.verdict(false, ap.av.getConsPercGaps());
1782  3 sg.cs.setConservation(c);
1783   
1784  3 SliderPanel.setConservationSlider(ap, sg.getGroupColourScheme(),
1785    sg.getName());
1786  3 SliderPanel.showConservationSlider();
1787    }
1788    else
1789    // remove ConservationColouring
1790    {
1791  0 sg.cs.setConservation(null);
1792  0 SliderPanel.hideConservationSlider();
1793    }
1794  3 modifyConservation.setEnabled(selected);
1795   
1796  3 refresh();
1797    }
1798   
1799    /**
1800    * Shows a dialog where group name and description may be edited
1801    */
 
1802  0 toggle protected void groupName_actionPerformed()
1803    {
1804  0 SequenceGroup sg = getGroup();
1805  0 EditNameDialog dialog = new EditNameDialog(sg.getName(),
1806    sg.getDescription(),
1807    MessageManager.getString("label.group_name"),
1808    MessageManager.getString("label.group_description"));
1809  0 dialog.showDialog(ap.alignFrame,
1810    MessageManager.getString("label.edit_group_name_description"),
1811    new RunResponse(JvOptionPane.OK_OPTION)
1812    {
 
1813  0 toggle @Override
1814    public void run()
1815    {
1816  0 sg.setName(dialog.getName());
1817  0 sg.setDescription(dialog.getDescription());
1818  0 refresh();
1819    }
1820    });
1821    }
1822   
1823    /**
1824    * Get selection group - adding it to the alignment if necessary.
1825    *
1826    * @return sequence group to operate on
1827    */
 
1828  12 toggle SequenceGroup getGroup()
1829    {
1830  12 SequenceGroup sg = ap.av.getSelectionGroup();
1831    // this method won't add a new group if it already exists
1832  12 if (sg != null)
1833    {
1834  12 ap.av.getAlignment().addGroup(sg);
1835    }
1836   
1837  12 return sg;
1838    }
1839   
1840    /**
1841    * Shows a dialog where sequence name and description may be edited
1842    */
 
1843  0 toggle void sequenceName_actionPerformed()
1844    {
1845  0 EditNameDialog dialog = new EditNameDialog(sequence.getName(),
1846    sequence.getDescription(),
1847    MessageManager.getString("label.sequence_name"),
1848    MessageManager.getString("label.sequence_description"));
1849  0 dialog.showDialog(ap.alignFrame,
1850    MessageManager.getString(
1851    "label.edit_sequence_name_description"),
1852    new RunResponse(JvOptionPane.OK_OPTION)
1853    {
 
1854  0 toggle @Override
1855    public void run()
1856    {
1857  0 if (dialog.getName() != null)
1858    {
1859  0 if (dialog.getName().indexOf(" ") > -1)
1860    {
1861  0 JvOptionPane.showMessageDialog(ap,
1862    MessageManager.getString(
1863    "label.spaces_converted_to_underscores"),
1864    MessageManager.getString(
1865    "label.no_spaces_allowed_sequence_name"),
1866    JvOptionPane.WARNING_MESSAGE);
1867    }
1868  0 sequence.setName(dialog.getName().replace(' ', '_'));
1869  0 ap.paintAlignment(false, false);
1870    }
1871  0 sequence.setDescription(dialog.getDescription());
1872  0 ap.av.firePropertyChange("alignment", null,
1873    ap.av.getAlignment().getSequences());
1874    }
1875    });
1876    }
1877   
1878    /**
1879    * DOCUMENT ME!
1880    *
1881    * @param e
1882    * DOCUMENT ME!
1883    */
 
1884  0 toggle void unGroupMenuItem_actionPerformed()
1885    {
1886  0 SequenceGroup sg = ap.av.getSelectionGroup();
1887  0 ap.av.getAlignment().deleteGroup(sg);
1888  0 ap.av.setSelectionGroup(null);
1889  0 refresh();
1890    }
1891   
 
1892  0 toggle void createGroupMenuItem_actionPerformed()
1893    {
1894  0 getGroup(); // implicitly creates group - note - should apply defaults / use
1895    // standard alignment window logic for this
1896  0 refresh();
1897    }
1898   
1899    /**
1900    * Offers a colour chooser and sets the selected colour as the group outline
1901    */
 
1902  0 toggle protected void outline_actionPerformed()
1903    {
1904  0 String title = MessageManager
1905    .getString("label.select_outline_colour");
1906  0 ColourChooserListener listener = new ColourChooserListener()
1907    {
 
1908  0 toggle @Override
1909    public void colourSelected(Color c)
1910    {
1911  0 getGroup().setOutlineColour(c);
1912  0 refresh();
1913    };
1914    };
1915  0 JalviewColourChooser.showColourChooser(Desktop.getDesktop(),
1916    title, Color.BLUE, listener);
1917    }
1918   
1919    /**
1920    * DOCUMENT ME!
1921    *
1922    * @param e
1923    * DOCUMENT ME!
1924    */
 
1925  0 toggle public void showBoxes_actionPerformed()
1926    {
1927  0 getGroup().setDisplayBoxes(showBoxes.isSelected());
1928  0 refresh();
1929    }
1930   
1931    /**
1932    * DOCUMENT ME!
1933    *
1934    * @param e
1935    * DOCUMENT ME!
1936    */
 
1937  0 toggle public void showText_actionPerformed()
1938    {
1939  0 getGroup().setDisplayText(showText.isSelected());
1940  0 refresh();
1941    }
1942   
1943    /**
1944    * DOCUMENT ME!
1945    *
1946    * @param e
1947    * DOCUMENT ME!
1948    */
 
1949  0 toggle public void showColourText_actionPerformed()
1950    {
1951  0 getGroup().setColourText(showColourText.isSelected());
1952  0 refresh();
1953    }
1954   
 
1955  0 toggle public void showLink(String url)
1956    {
1957  0 try
1958    {
1959  0 jalview.util.BrowserLauncher.openURL(url);
1960    } catch (Exception ex)
1961    {
1962  0 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1963    MessageManager.getString("label.web_browser_not_found_unix"),
1964    MessageManager.getString("label.web_browser_not_found"),
1965    JvOptionPane.WARNING_MESSAGE);
1966   
1967  0 ex.printStackTrace();
1968    }
1969    }
1970   
 
1971  0 toggle void hideSequences(boolean representGroup)
1972    {
1973  0 ap.av.hideSequences(sequence, representGroup);
1974    }
1975   
 
1976  0 toggle public void copy_actionPerformed()
1977    {
1978  0 ap.alignFrame.copy_actionPerformed(null);
1979    }
1980   
 
1981  0 toggle public void cut_actionPerformed()
1982    {
1983  0 ap.alignFrame.cut_actionPerformed(null);
1984    }
1985   
 
1986  0 toggle void changeCase(ActionEvent e)
1987    {
1988  0 Object source = e.getSource();
1989  0 SequenceGroup sg = ap.av.getSelectionGroup();
1990   
1991  0 if (sg != null)
1992    {
1993  0 List<int[]> startEnd = ap.av.getVisibleRegionBoundaries(
1994    sg.getStartRes(), sg.getEndRes() + 1);
1995   
1996  0 String description;
1997  0 int caseChange;
1998   
1999  0 if (source == toggle)
2000    {
2001  0 description = MessageManager.getString("label.toggle_case");
2002  0 caseChange = ChangeCaseCommand.TOGGLE_CASE;
2003    }
2004  0 else if (source == upperCase)
2005    {
2006  0 description = MessageManager.getString("label.to_upper_case");
2007  0 caseChange = ChangeCaseCommand.TO_UPPER;
2008    }
2009    else
2010    {
2011  0 description = MessageManager.getString("label.to_lower_case");
2012  0 caseChange = ChangeCaseCommand.TO_LOWER;
2013    }
2014   
2015  0 ChangeCaseCommand caseCommand = new ChangeCaseCommand(description,
2016    sg.getSequencesAsArray(ap.av.getHiddenRepSequences()),
2017    startEnd, caseChange);
2018   
2019  0 ap.alignFrame.addHistoryItem(caseCommand);
2020   
2021  0 ap.av.firePropertyChange("alignment", null,
2022    ap.av.getAlignment().getSequences());
2023   
2024    }
2025    }
2026   
 
2027  0 toggle public void outputText_actionPerformed(ActionEvent e)
2028    {
2029  0 CutAndPasteTransfer cap = new CutAndPasteTransfer();
2030  0 cap.setForInput(null);
2031  0 Desktop.addInternalFrame(cap, MessageManager
2032    .formatMessage("label.alignment_output_command", new Object[]
2033    { e.getActionCommand() }), 600, 500);
2034   
2035  0 String[] omitHidden = null;
2036   
2037  0 System.out.println("PROMPT USER HERE"); // TODO: decide if a prompt happens
2038    // or we simply trust the user wants
2039    // wysiwig behaviour
2040   
2041  0 FileFormatI fileFormat = FileFormats.getInstance()
2042    .forName(e.getActionCommand());
2043  0 cap.setText(
2044    new FormatAdapter(ap).formatSequences(fileFormat, ap, true));
2045    }
2046   
 
2047  0 toggle public void sequenceFeature_actionPerformed()
2048    {
2049  0 SequenceGroup sg = ap.av.getSelectionGroup();
2050  0 if (sg == null)
2051    {
2052  0 return;
2053    }
2054   
2055  0 List<SequenceI> seqs = new ArrayList<>();
2056  0 List<SequenceFeature> features = new ArrayList<>();
2057   
2058    /*
2059    * assemble dataset sequences, and template new sequence features,
2060    * for the amend features dialog
2061    */
2062  0 int gSize = sg.getSize();
2063  0 for (int i = 0; i < gSize; i++)
2064    {
2065  0 int start = sg.getSequenceAt(i).findPosition(sg.getStartRes());
2066  0 int end = sg.findEndRes(sg.getSequenceAt(i));
2067  0 if (start <= end)
2068    {
2069  0 seqs.add(sg.getSequenceAt(i).getDatasetSequence());
2070  0 features.add(new SequenceFeature(null, null, start, end, null));
2071    }
2072    }
2073   
2074    /*
2075    * an entirely gapped region will generate empty lists of sequence / features
2076    */
2077  0 if (!seqs.isEmpty())
2078    {
2079  0 new FeatureEditor(ap, seqs, features, true).showDialog();
2080    }
2081    }
2082   
 
2083  0 toggle public void textColour_actionPerformed()
2084    {
2085  0 SequenceGroup sg = getGroup();
2086  0 if (sg != null)
2087    {
2088  0 new TextColourChooser().chooseColour(ap, sg);
2089    }
2090    }
2091   
 
2092  0 toggle public void colourByStructure(String pdbid)
2093    {
2094  0 Annotation[] anots = ap.av.getStructureSelectionManager()
2095    .colourSequenceFromStructure(sequence, pdbid);
2096   
2097  0 AlignmentAnnotation an = new AlignmentAnnotation("Structure",
2098    "Coloured by " + pdbid, anots);
2099   
2100  0 ap.av.getAlignment().addAnnotation(an);
2101  0 an.createSequenceMapping(sequence, 0, true);
2102    // an.adjustForAlignment();
2103  0 ap.av.getAlignment().setAnnotationIndex(an, 0);
2104   
2105  0 ap.adjustAnnotationHeight();
2106   
2107  0 sequence.addAlignmentAnnotation(an);
2108   
2109    }
2110   
2111    /**
2112    * Shows a dialog where sequence characters may be edited. Any changes are
2113    * applied, and added as an available 'Undo' item in the edit commands
2114    * history.
2115    */
 
2116  0 toggle public void editSequence_actionPerformed()
2117    {
2118  0 SequenceGroup sg = ap.av.getSelectionGroup();
2119   
2120  0 if (sg != null)
2121    {
2122  0 if (sequence == null)
2123    {
2124  0 sequence = sg.getSequenceAt(0);
2125    }
2126   
2127  0 EditNameDialog dialog = new EditNameDialog(
2128    sequence.getSequenceAsString(sg.getStartRes(),
2129    sg.getEndRes() + 1),
2130    null, MessageManager.getString("label.edit_sequence"), null);
2131  0 dialog.showDialog(ap.alignFrame,
2132    MessageManager.getString("label.edit_sequence"),
2133    new RunResponse(JvOptionPane.OK_OPTION)
2134    {
 
2135  0 toggle @Override
2136    public void run()
2137    {
2138  0 EditCommand editCommand = new EditCommand(
2139    MessageManager.getString("label.edit_sequences"),
2140    Action.REPLACE,
2141    dialog.getName().replace(' ',
2142    ap.av.getGapCharacter()),
2143    sg.getSequencesAsArray(
2144    ap.av.getHiddenRepSequences()),
2145    sg.getStartRes(), sg.getEndRes() + 1,
2146    ap.av.getAlignment());
2147  0 ap.alignFrame.addHistoryItem(editCommand);
2148  0 ap.av.firePropertyChange("alignment", null,
2149    ap.av.getAlignment().getSequences());
2150    }
2151    });
2152    }
2153    }
2154   
2155    /**
2156    * Action on user selecting an item from the colour menu (that does not have
2157    * its bespoke action handler)
2158    *
2159    * @return
2160    */
 
2161  3 toggle @Override
2162    public void changeColour_actionPerformed(String colourSchemeName)
2163    {
2164  3 SequenceGroup sg = getGroup();
2165    /*
2166    * switch to the chosen colour scheme (or null for None)
2167    */
2168  3 ColourSchemeI colourScheme = ColourSchemes.getInstance()
2169    .getColourScheme(colourSchemeName, sg,
2170    ap.av.getHiddenRepSequences());
2171  3 sg.setColourScheme(colourScheme);
2172  3 if (colourScheme instanceof Blosum62ColourScheme
2173    || colourScheme instanceof PIDColourScheme)
2174    {
2175  0 sg.cs.setConsensus(AAFrequency.calculate(
2176    sg.getSequences(ap.av.getHiddenRepSequences()),
2177    sg.getStartRes(), sg.getEndRes() + 1));
2178    }
2179   
2180  3 refresh();
2181    }
2182   
2183    }