From 725dd79ff4976e8e30a638a6f7dfa45eea818d57 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 22 Nov 2019 15:14:13 +0000 Subject: [PATCH] JAL-819 menu options to reinstate missing auto-calculated annotation --- src/jalview/api/AlignViewportI.java | 25 ++++ src/jalview/datamodel/AlignmentAnnotation.java | 31 +++-- src/jalview/gui/AlignFrame.java | 164 ++++++++++++++++++++++++ src/jalview/gui/AnnotationLabels.java | 2 +- src/jalview/jbgui/GAlignFrame.java | 24 ++-- src/jalview/viewmodel/AlignmentViewport.java | 139 ++++++++++---------- 6 files changed, 295 insertions(+), 90 deletions(-) diff --git a/src/jalview/api/AlignViewportI.java b/src/jalview/api/AlignViewportI.java index 785dd14..707d03d 100644 --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@ -528,4 +528,29 @@ public interface AlignViewportI extends ViewStyleI * - a group defined on sequences in the alignment held by the view */ void addSequenceGroup(SequenceGroup sequenceGroup); + + /** + * Creates an empty Conservation annotation and adds it to the alignment + */ + void initConservation(); + + /** + * Creates an empty Quality annotation and adds it to the alignment + */ + void initQuality(); + + /** + * Creates an empty Consensus annotation and adds it to the alignment + */ + void initConsensus(); + + /** + * Creates an empty Occupancy annotation and adds it to the alignment + */ + void initOccupancy(); + + /** + * Creates an empty RNA Structure annotation and adds it to the alignment + */ + void initRNAStructure(); } diff --git a/src/jalview/datamodel/AlignmentAnnotation.java b/src/jalview/datamodel/AlignmentAnnotation.java index 2ee4503..a898746 100755 --- a/src/jalview/datamodel/AlignmentAnnotation.java +++ b/src/jalview/datamodel/AlignmentAnnotation.java @@ -1647,20 +1647,27 @@ public class AlignmentAnnotation } } + /** + * Answers a (possibly empty) iterable list of those annotations in the supplied + * list whose reference sequence, calcId or label matches the supplied + * parameters. Null parameter values are ignored. + * + * @param list + * @param seq + * @param calcId + * @param label + * @return + */ public static Iterable findAnnotations( Iterable list, SequenceI seq, String calcId, String label) { - - ArrayList aa = new ArrayList<>(); + List aa = new ArrayList<>(); for (AlignmentAnnotation ann : list) { - if ((calcId == null || (ann.getCalcId() != null - && ann.getCalcId().equals(calcId))) - && (seq == null || (ann.sequenceRef != null - && ann.sequenceRef == seq)) - && (label == null - || (ann.label != null && ann.label.equals(label)))) + if ((calcId == null || calcId.equals(ann.getCalcId())) + && (seq == null || seq == ann.sequenceRef) + && (label == null || label.equals(ann.label))) { aa.add(ann); } @@ -1693,6 +1700,14 @@ public class AlignmentAnnotation return false; } + /** + * Returns a (possibly empty) iterable set of annotations in the given list + * whose calcId matches the given value (which may not be null) + * + * @param list + * @param calcId + * @return + */ public static Iterable findAnnotation( List list, String calcId) { diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index fcb6572..a44df97 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -893,6 +893,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, scaleLeft.setVisible(av.getWrapAlignment()); scaleRight.setVisible(av.getWrapAlignment()); annotationPanelMenuItem.setState(av.isShowAnnotation()); + /* * Show/hide annotations only enabled if annotation panel is shown */ @@ -908,6 +909,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, showConsensusHistogram.setSelected(av.isShowConsensusHistogram()); showSequenceLogo.setSelected(av.isShowSequenceLogo()); normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo()); + buildAutoAnnotationMenu(av); ColourMenuHelper.setColourSelected(colourMenu, av.getGlobalColourScheme()); @@ -928,6 +930,168 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } /** + * Adds menu items for the Autocalculated Annotation sub-menu + * + * @param av + */ + void buildAutoAnnotationMenu(AlignViewport av) + { + autoAnnMenu.removeAll(); + autoAnnMenu.add(showAutoFirst); + autoAnnMenu.add(showAutoLast); + autoAnnMenu.addSeparator(); + autoAnnMenu.add(applyAutoAnnotationSettings); + autoAnnMenu.add(showConsensusHistogram); + autoAnnMenu.add(showSequenceLogo); + autoAnnMenu.add(normaliseSequenceLogo); + autoAnnMenu.addSeparator(); + + /* + * add options to reinstate any deleted auto-calculated annotations + */ + boolean hasConservation = false; + boolean hasQuality = false; + boolean hasConsensus = false; + boolean hasOccupancy = false; + boolean hasRnaStruct = false; + AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation(); + if (anns == null) + { + return; + } + for (int i = 0; i < anns.length; i++) + { + if (anns[i].autoCalculated) + { + // TODO JAL-3485 should let these strings be constants instead + if ("Conservation".equals(anns[i].label)) + { + hasConservation = true; + } + else if ("Quality".equals(anns[i].label)) + { + hasQuality = true; + } + else if ("Consensus".equals(anns[i].label)) + { + hasConsensus = true; + } + else if ("Occupancy".equals(anns[i].label)) + { + hasOccupancy = true; + } + else if ("StrucConsensus".equals(anns[i].label)) + { + hasRnaStruct = true; + } + } + } + boolean added = false; + + /* + * a shareable action to refresh stuff; NB action listeners + * get run in reverse order to that in which they are added! + */ + ActionListener refresher = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + alignPanel.adjustAnnotationHeight(); + av.alignmentChanged(alignPanel); + buildAutoAnnotationMenu(av); + } + }; + + if (!av.isNucleotide()) + { + if (!hasConservation) + { + JMenuItem mi = new JMenuItem("Conservation"); + mi.addActionListener(refresher); + mi.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + av.initConservation(); + } + }); + autoAnnMenu.add(mi); + added = true; + } + if (!hasQuality) + { + JMenuItem mi = new JMenuItem("Quality"); + mi.addActionListener(refresher); + mi.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + av.initQuality(); + } + }); + autoAnnMenu.add(mi); + added = true; + } + } + if (!hasConsensus) + { + JMenuItem mi = new JMenuItem("Consensus"); + mi.addActionListener(refresher); + mi.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + av.initConsensus(); + } + }); + autoAnnMenu.add(mi); + added = true; + } + if (!hasOccupancy) + { + JMenuItem mi = new JMenuItem("Occupancy"); + mi.addActionListener(refresher); + mi.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + av.initOccupancy(); + } + }); + autoAnnMenu.add(mi); + added = true; + } + if (!hasRnaStruct && av.isNucleotide() + && av.getAlignment().hasRNAStructure()) + { + JMenuItem mi = new JMenuItem("Structure Consensus"); + mi.addActionListener(refresher); + mi.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + av.initRNAStructure(); + } + }); + autoAnnMenu.add(mi); + added = true; + } + + if (added) + { + autoAnnMenu.addSeparator(); + } + autoAnnMenu.add(showGroupConservation); + autoAnnMenu.add(showGroupConsensus); + } + + /** * Set the enabled state of the 'Run Groovy' option in the Calculate menu * * @param b diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java index 6da6cc3..af76d26 100755 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@ -278,7 +278,7 @@ public class AnnotationLabels extends JPanel { aa[selectedRow].scaleColLabel = !aa[selectedRow].scaleColLabel; } - + ap.alignFrame.setMenusForViewport(); ap.refresh(fullRepaint); } diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 075b490..63bc050 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -207,6 +207,12 @@ public class GAlignFrame extends JInternalFrame private SplitContainerI splitFrame; + protected JMenu autoAnnMenu; + + protected JRadioButtonMenuItem showAutoFirst; + + protected JRadioButtonMenuItem showAutoLast; + public GAlignFrame() { try @@ -875,9 +881,9 @@ public class GAlignFrame extends JInternalFrame }); ButtonGroup buttonGroup = new ButtonGroup(); - final JRadioButtonMenuItem showAutoFirst = new JRadioButtonMenuItem( + showAutoFirst = new JRadioButtonMenuItem( MessageManager.getString("label.show_first")); - final JRadioButtonMenuItem showAutoLast = new JRadioButtonMenuItem( + showAutoLast = new JRadioButtonMenuItem( MessageManager.getString("label.show_last")); buttonGroup.add(showAutoFirst); buttonGroup.add(showAutoLast); @@ -1709,7 +1715,7 @@ public class GAlignFrame extends JInternalFrame selectHighlighted.addActionListener(al); JMenu tooltipSettingsMenu = new JMenu( MessageManager.getString("label.sequence_id_tooltip")); - JMenu autoAnnMenu = new JMenu( + autoAnnMenu = new JMenu( MessageManager.getString("label.autocalculated_annotation")); JMenu exportImageMenu = new JMenu( @@ -1805,17 +1811,7 @@ public class GAlignFrame extends JInternalFrame annotationsMenu.add(sortAnnBySequence); annotationsMenu.add(sortAnnByLabel); annotationsMenu.addSeparator(); - autoAnnMenu.add(showAutoFirst); - autoAnnMenu.add(showAutoLast); - autoAnnMenu.addSeparator(); - autoAnnMenu.add(applyAutoAnnotationSettings); - autoAnnMenu.add(showConsensusHistogram); - autoAnnMenu.add(showSequenceLogo); - autoAnnMenu.add(normaliseSequenceLogo); - autoAnnMenu.addSeparator(); - autoAnnMenu.add(showGroupConservation); - autoAnnMenu.add(showGroupConsensus); - annotationsMenu.add(autoAnnMenu); + annotationsMenu.add(autoAnnMenu); // autoAnnMenu is populated later sort.add(sortIDMenuItem); sort.add(sortLengthMenuItem); diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 8dcd1b3..9de0b94 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -1931,18 +1931,31 @@ public abstract class AlignmentViewport { if (!alignment.isNucleotide()) { - initConservation(); - initQuality(); + if (showConservation && conservation == null) + { + initConservation(); + } + if (showQuality && quality == null) + { + initQuality(); + } } else { - initRNAStructure(); + if (showConsensus && alignment.hasRNAStructure() + && strucConsensus == null) + { + initRNAStructure(); + } + } + if (showConsensus) + { + initConsensus(); + } + if (showOccupancy) + { + initOccupancy(); } - consensus = new AlignmentAnnotation("Consensus", - MessageManager.getString("label.consensus_descr"), - new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); - initConsensus(consensus); - initGapCounts(); initComplementConsensus(); } @@ -1988,84 +2001,76 @@ public abstract class AlignmentViewport return false; } + @Override + public void initConsensus() + { + consensus = new AlignmentAnnotation("Consensus", + MessageManager.getString("label.consensus_descr"), + new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); + initConsensus(consensus); + } + private void initConsensus(AlignmentAnnotation aa) { - aa.hasText = true; - aa.autoCalculated = true; + consensus = new AlignmentAnnotation("Consensus", + MessageManager.getString("label.consensus_descr"), + new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); + consensus.hasText = true; + consensus.autoCalculated = true; if (showConsensus) { - alignment.addAnnotation(aa); + alignment.addAnnotation(consensus); } } - // these should be extracted from the view model - style and settings for - // derived annotation - private void initGapCounts() + @Override + public void initOccupancy() { - if (showOccupancy) - { - gapcounts = new AlignmentAnnotation("Occupancy", - MessageManager.getString("label.occupancy_descr"), - new Annotation[1], 0f, alignment.getHeight(), - AlignmentAnnotation.BAR_GRAPH); - gapcounts.hasText = true; - gapcounts.autoCalculated = true; - gapcounts.scaleColLabel = true; - gapcounts.graph = AlignmentAnnotation.BAR_GRAPH; + gapcounts = new AlignmentAnnotation("Occupancy", + MessageManager.getString("label.occupancy_descr"), + new Annotation[1], 0f, alignment.getHeight(), + AlignmentAnnotation.BAR_GRAPH); + gapcounts.hasText = true; + gapcounts.autoCalculated = true; + gapcounts.scaleColLabel = true; + gapcounts.graph = AlignmentAnnotation.BAR_GRAPH; - alignment.addAnnotation(gapcounts); - } + alignment.addAnnotation(gapcounts); } - private void initConservation() + @Override + public void initConservation() { - if (showConservation) - { - if (conservation == null) - { - conservation = new AlignmentAnnotation("Conservation", - MessageManager.formatMessage("label.conservation_descr", - getConsPercGaps()), - new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); - conservation.hasText = true; - conservation.autoCalculated = true; - alignment.addAnnotation(conservation); - } - } + conservation = new AlignmentAnnotation("Conservation", + MessageManager.formatMessage("label.conservation_descr", + getConsPercGaps()), + new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); + conservation.hasText = true; + conservation.autoCalculated = true; + alignment.addAnnotation(conservation); } - private void initQuality() + @Override + public void initQuality() { - if (showQuality) - { - if (quality == null) - { - quality = new AlignmentAnnotation("Quality", - MessageManager.getString("label.quality_descr"), - new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); - quality.hasText = true; - quality.autoCalculated = true; - alignment.addAnnotation(quality); - } - } + quality = new AlignmentAnnotation("Quality", + MessageManager.getString("label.quality_descr"), + new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); + quality.hasText = true; + quality.autoCalculated = true; + alignment.addAnnotation(quality); } - private void initRNAStructure() + @Override + public void initRNAStructure() { - if (alignment.hasRNAStructure() && strucConsensus == null) - { - strucConsensus = new AlignmentAnnotation("StrucConsensus", - MessageManager.getString("label.strucconsensus_descr"), - new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); - strucConsensus.hasText = true; - strucConsensus.autoCalculated = true; - - if (showConsensus) - { - alignment.addAnnotation(strucConsensus); - } - } + strucConsensus = new AlignmentAnnotation("StrucConsensus", + MessageManager.getString("label.strucconsensus_descr"), + new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); + strucConsensus.hasText = true; + strucConsensus.autoCalculated = true; + alignment.addAnnotation(strucConsensus); } /* -- 1.7.10.2