From c46ac1bbccd595dfeb504220b465023d38815223 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Tue, 28 Oct 2014 15:51:46 +0000 Subject: [PATCH] JAL-1264 refactor to add menu options to _both_ sequence and selection pop-ups, plus unit tests. --- src/jalview/gui/PopupMenu.java | 115 +++++++++++--------- test/jalview/gui/PopupMenuTest.java | 201 ++++++++++++++++++++++++++++++++++- 2 files changed, 263 insertions(+), 53 deletions(-) diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index ad7726d..3da4494 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -62,7 +62,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.List; @@ -190,11 +189,17 @@ public class PopupMenu extends JPopupMenu JMenu outputMenu = new JMenu(); - JMenu showAnnotationsMenu = new JMenu(); + JMenu seqShowAnnotationsMenu = new JMenu(); - JMenu hideAnnotationsMenu = new JMenu(); + JMenu seqHideAnnotationsMenu = new JMenu(); - JMenuItem addReferenceAnnotations = new JMenuItem(); + JMenuItem seqAddReferenceAnnotations = new JMenuItem(); + + JMenu groupShowAnnotationsMenu = new JMenu(); + + JMenu groupHideAnnotationsMenu = new JMenu(); + + JMenuItem groupAddReferenceAnnotations = new JMenuItem(); JMenuItem sequenceFeature = new JMenuItem(); @@ -282,17 +287,26 @@ public class PopupMenu extends JPopupMenu /* * Build menus for annotation types that may be shown or hidden, and for - * 'reference annotations' that may be added to the alignment. The scope is - * annotations for the current selection group (if there is one), else the - * current sequence (if there is one), else not applicable (e.g. for popup - * menu within the sequence). + * 'reference annotations' that may be added to the alignment. First for the + * currently selected sequence (if there is one): */ - final List sequenceScope = getSequenceScope(seq); - if (!sequenceScope.isEmpty()) - { - buildAnnotationTypesMenus(sequenceScope); - configureReferenceAnnotationsMenu(addReferenceAnnotations, sequenceScope); - } + final List selectedSequence = (seq == null ? Collections + . emptyList() : Arrays.asList(seq)); + buildAnnotationTypesMenus(seqShowAnnotationsMenu, + seqHideAnnotationsMenu, selectedSequence); + configureReferenceAnnotationsMenu(seqAddReferenceAnnotations, + selectedSequence); + + /* + * And repeat for the current selection group (if there is one): + */ + final List selectedGroup = (ap.av.getSelectionGroup() == null ? Collections + . emptyList() : ap.av.getSelectionGroup() + .getSequences()); + buildAnnotationTypesMenus(groupShowAnnotationsMenu, + groupHideAnnotationsMenu, selectedGroup); + configureReferenceAnnotationsMenu(groupAddReferenceAnnotations, + selectedGroup); try { @@ -809,9 +823,10 @@ public class PopupMenu extends JPopupMenu } /** - * Add annotation types to a 'Show annotations' or 'Hide annotations' menu. + * Add annotation types to 'Show annotations' and/or 'Hide annotations' menus. * "All" is added first, followed by a separator. Then add any annotation - * types associated with the current selection. + * types associated with the current selection. Separate menus are built for + * the selected sequence group (if any), and the selected sequence. *

* Some annotation rows are always rendered together - these can be identified * by a common graphGroup property > -1. Only one of each group will be marked @@ -820,29 +835,32 @@ public class PopupMenu extends JPopupMenu *

* IUPredWS (Long), IUPredWS (Short) * - * @param forSequences + * @param seq */ - protected void buildAnnotationTypesMenus(List forSequences) + protected void buildAnnotationTypesMenus(JMenu showMenu, JMenu hideMenu, + List forSequences) { - showAnnotationsMenu.removeAll(); - hideAnnotationsMenu.removeAll(); + showMenu.removeAll(); + hideMenu.removeAll(); + final List all = Arrays.asList(ALL_ANNOTATIONS); - addAnnotationTypeToShowHide(showAnnotationsMenu, forSequences, "", all, - true, true); - addAnnotationTypeToShowHide(hideAnnotationsMenu, forSequences, "", all, - true, false); - showAnnotationsMenu.addSeparator(); - hideAnnotationsMenu.addSeparator(); + addAnnotationTypeToShowHide(showMenu, forSequences, "", all, true, true); + addAnnotationTypeToShowHide(hideMenu, forSequences, "", all, true, + false); + showMenu.addSeparator(); + hideMenu.addSeparator(); final AlignmentAnnotation[] annotations = ap.getAlignment() .getAlignmentAnnotation(); /* * Find shown/hidden annotations types, distinguished by source (calcId), - * and grouped by graphGroup. + * and grouped by graphGroup. Using LinkedHashMap means we will retrieve in + * the insertion order, which is the order of the annotations on the + * alignment. */ - Map>> shownTypes = new HashMap>>(); - Map>> hiddenTypes = new HashMap>>(); + Map>> shownTypes = new LinkedHashMap>>(); + Map>> hiddenTypes = new LinkedHashMap>>(); AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes, AlignmentAnnotationUtils.asList(annotations), @@ -852,23 +870,23 @@ public class PopupMenu extends JPopupMenu { for (List type : hiddenTypes.get(calcId)) { - addAnnotationTypeToShowHide(showAnnotationsMenu, forSequences, + addAnnotationTypeToShowHide(showMenu, forSequences, calcId, type, false, true); } } // grey out 'show annotations' if none are hidden - showAnnotationsMenu.setEnabled(!hiddenTypes.isEmpty()); + showMenu.setEnabled(!hiddenTypes.isEmpty()); for (String calcId : shownTypes.keySet()) { for (List type : shownTypes.get(calcId)) { - addAnnotationTypeToShowHide(hideAnnotationsMenu, forSequences, + addAnnotationTypeToShowHide(hideMenu, forSequences, calcId, type, false, false); } } // grey out 'hide annotations' if none are shown - hideAnnotationsMenu.setEnabled(!shownTypes.isEmpty()); + hideMenu.setEnabled(!shownTypes.isEmpty()); } /** @@ -1445,9 +1463,13 @@ public class PopupMenu extends JPopupMenu }); outputMenu.setText(MessageManager.getString("label.out_to_textbox") + "..."); - showAnnotationsMenu.setText(MessageManager + seqShowAnnotationsMenu.setText(MessageManager .getString("label.show_annotations")); - hideAnnotationsMenu.setText(MessageManager + seqHideAnnotationsMenu.setText(MessageManager + .getString("label.hide_annotations")); + groupShowAnnotationsMenu.setText(MessageManager + .getString("label.show_annotations")); + groupHideAnnotationsMenu.setText(MessageManager .getString("label.hide_annotations")); sequenceFeature.setText(MessageManager .getString("label.create_sequence_feature")); @@ -1498,22 +1520,15 @@ public class PopupMenu extends JPopupMenu // groupMenu.add(chooseAnnotations); /* - * Add show/hide annotations to either Selection menu (if a selection group - * in force), else to the Sequence menu. + * Add show/hide annotations to the Sequence menu, and to the Selection menu + * (if a selection group is in force). */ - SequenceGroup sg = this.ap.av.getSelectionGroup(); - if (sg != null && sg.getSize() > 0) - { - groupMenu.add(showAnnotationsMenu); - groupMenu.add(hideAnnotationsMenu); - groupMenu.add(addReferenceAnnotations); - } - else - { - sequenceMenu.add(showAnnotationsMenu); - sequenceMenu.add(hideAnnotationsMenu); - sequenceMenu.add(addReferenceAnnotations); - } + sequenceMenu.add(seqShowAnnotationsMenu); + sequenceMenu.add(seqHideAnnotationsMenu); + sequenceMenu.add(seqAddReferenceAnnotations); + groupMenu.add(groupShowAnnotationsMenu); + groupMenu.add(groupHideAnnotationsMenu); + groupMenu.add(groupAddReferenceAnnotations); groupMenu.add(editMenu); groupMenu.add(outputMenu); groupMenu.add(sequenceFeature); diff --git a/test/jalview/gui/PopupMenuTest.java b/test/jalview/gui/PopupMenuTest.java index ea1dfb0..1d219df 100644 --- a/test/jalview/gui/PopupMenuTest.java +++ b/test/jalview/gui/PopupMenuTest.java @@ -9,11 +9,15 @@ import jalview.datamodel.SequenceI; import jalview.io.AppletFormatAdapter; import jalview.util.MessageManager; +import java.awt.Component; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import javax.swing.JMenu; import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JSeparator; import org.junit.Before; import org.junit.Test; @@ -121,9 +125,7 @@ public class PopupMenuTest public void testConfigureReferenceAnnotationsMenu() { JMenuItem menu = new JMenuItem(); - List seqs = new ArrayList(); - - seqs = parentPanel.getAlignment().getSequences(); + List seqs = parentPanel.getAlignment().getSequences(); // make up new annotations and add to dataset sequences // PDB.secondary structure on Sequence0 @@ -147,4 +149,197 @@ public class PopupMenuTest String expected = "
Add annotations for
JMOL/secondary structure
PBD/Temp
"; assertEquals(expected, menu.getToolTipText()); } + + /** + * Test for building menu options including 'show' and 'hide' annotation + * types. + */ + @Test + public void testBuildAnnotationTypesMenus() + { + JMenu showMenu = new JMenu(); + JMenu hideMenu = new JMenu(); + List seqs = parentPanel.getAlignment().getSequences(); + + // make up new annotations and add to sequences and to the alignment + + // PDB.secondary structure on Sequence0 + AlignmentAnnotation annotation = new AlignmentAnnotation( + "secondary structure", "", 0); + annotation.setCalcId("PDB"); + annotation.visible = true; + seqs.get(0).addAlignmentAnnotation(annotation); + parentPanel.getAlignment().addAnnotation(annotation); + + // JMOL.secondary structure on Sequence0 - hidden + annotation = new AlignmentAnnotation("secondary structure", "", 0); + annotation.setCalcId("JMOL"); + annotation.visible = false; + seqs.get(0).addAlignmentAnnotation(annotation); + parentPanel.getAlignment().addAnnotation(annotation); + + // Jpred.SSP on Sequence0 - hidden + annotation = new AlignmentAnnotation("SSP", "", 0); + annotation.setCalcId("JPred"); + annotation.visible = false; + seqs.get(0).addAlignmentAnnotation(annotation); + parentPanel.getAlignment().addAnnotation(annotation); + + // PDB.Temp on Sequence1 + annotation = new AlignmentAnnotation("Temp", "", 0); + annotation.setCalcId("PDB"); + annotation.visible = true; + seqs.get(1).addAlignmentAnnotation(annotation); + parentPanel.getAlignment().addAnnotation(annotation); + + /* + * Expect menu options to show "secondary structure" and "SSP", and to hide + * "secondary structure" and "Temp". Tooltip should be calcId. + */ + testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs); + + assertTrue(showMenu.isEnabled()); + assertTrue(hideMenu.isEnabled()); + + Component[] showOptions = showMenu.getMenuComponents(); + Component[] hideOptions = hideMenu.getMenuComponents(); + + assertEquals(4, showOptions.length); // includes 'All' and separator + assertEquals(4, hideOptions.length); + assertEquals("All", + ((JMenuItem) showOptions[0]).getText()); + assertTrue(showOptions[1] instanceof JPopupMenu.Separator); + assertEquals(JSeparator.HORIZONTAL, + ((JSeparator) showOptions[1]).getOrientation()); + assertEquals("secondary structure", + ((JMenuItem) showOptions[2]).getText()); + assertEquals("JMOL", ((JMenuItem) showOptions[2]).getToolTipText()); + assertEquals("SSP", ((JMenuItem) showOptions[3]).getText()); + assertEquals("JPred", ((JMenuItem) showOptions[3]).getToolTipText()); + + assertEquals("All", + ((JMenuItem) hideOptions[0]).getText()); + assertTrue(hideOptions[1] instanceof JPopupMenu.Separator); + assertEquals(JSeparator.HORIZONTAL, + ((JSeparator) hideOptions[1]).getOrientation()); + assertEquals("secondary structure", + ((JMenuItem) hideOptions[2]).getText()); + assertEquals("PDB", ((JMenuItem) hideOptions[2]).getToolTipText()); + assertEquals("Temp", ((JMenuItem) hideOptions[3]).getText()); + assertEquals("PDB", ((JMenuItem) hideOptions[3]).getToolTipText()); + } + + /** + * Test for building menu options with only 'hide' annotation types enabled. + */ + @Test + public void testBuildAnnotationTypesMenus_showDisabled() + { + JMenu showMenu = new JMenu(); + JMenu hideMenu = new JMenu(); + List seqs = parentPanel.getAlignment().getSequences(); + + // make up new annotations and add to sequences and to the alignment + + // PDB.secondary structure on Sequence0 + AlignmentAnnotation annotation = new AlignmentAnnotation( + "secondary structure", "", 0); + annotation.setCalcId("PDB"); + annotation.visible = true; + seqs.get(0).addAlignmentAnnotation(annotation); + parentPanel.getAlignment().addAnnotation(annotation); + + // PDB.Temp on Sequence1 + annotation = new AlignmentAnnotation("Temp", "", 0); + annotation.setCalcId("PDB"); + annotation.visible = true; + seqs.get(1).addAlignmentAnnotation(annotation); + parentPanel.getAlignment().addAnnotation(annotation); + + /* + * Expect menu options to hide "secondary structure" and "Temp". Tooltip + * should be calcId. 'Show' menu should be disabled. + */ + testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs); + + assertFalse(showMenu.isEnabled()); + assertTrue(hideMenu.isEnabled()); + + Component[] showOptions = showMenu.getMenuComponents(); + Component[] hideOptions = hideMenu.getMenuComponents(); + + assertEquals(2, showOptions.length); // includes 'All' and separator + assertEquals(4, hideOptions.length); + assertEquals("All", ((JMenuItem) showOptions[0]).getText()); + assertTrue(showOptions[1] instanceof JPopupMenu.Separator); + assertEquals(JSeparator.HORIZONTAL, + ((JSeparator) showOptions[1]).getOrientation()); + + assertEquals("All", ((JMenuItem) hideOptions[0]).getText()); + assertTrue(hideOptions[1] instanceof JPopupMenu.Separator); + assertEquals(JSeparator.HORIZONTAL, + ((JSeparator) hideOptions[1]).getOrientation()); + assertEquals("secondary structure", + ((JMenuItem) hideOptions[2]).getText()); + assertEquals("PDB", ((JMenuItem) hideOptions[2]).getToolTipText()); + assertEquals("Temp", ((JMenuItem) hideOptions[3]).getText()); + assertEquals("PDB", ((JMenuItem) hideOptions[3]).getToolTipText()); + } + + /** + * Test for building menu options with only 'show' annotation types enabled. + */ + @Test + public void testBuildAnnotationTypesMenus_hideDisabled() + { + JMenu showMenu = new JMenu(); + JMenu hideMenu = new JMenu(); + List seqs = parentPanel.getAlignment().getSequences(); + + // make up new annotations and add to sequences and to the alignment + + // PDB.secondary structure on Sequence0 + AlignmentAnnotation annotation = new AlignmentAnnotation( + "secondary structure", "", 0); + annotation.setCalcId("PDB"); + annotation.visible = false; + seqs.get(0).addAlignmentAnnotation(annotation); + parentPanel.getAlignment().addAnnotation(annotation); + + // PDB.Temp on Sequence1 + annotation = new AlignmentAnnotation("Temp", "", 0); + annotation.setCalcId("PDB2"); + annotation.visible = false; + seqs.get(1).addAlignmentAnnotation(annotation); + parentPanel.getAlignment().addAnnotation(annotation); + + /* + * Expect menu options to show "secondary structure" and "Temp". Tooltip + * should be calcId. 'hide' menu should be disabled. + */ + testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs); + + assertTrue(showMenu.isEnabled()); + assertFalse(hideMenu.isEnabled()); + + Component[] showOptions = showMenu.getMenuComponents(); + Component[] hideOptions = hideMenu.getMenuComponents(); + + assertEquals(4, showOptions.length); // includes 'All' and separator + assertEquals(2, hideOptions.length); + assertEquals("All", ((JMenuItem) showOptions[0]).getText()); + assertTrue(showOptions[1] instanceof JPopupMenu.Separator); + assertEquals(JSeparator.HORIZONTAL, + ((JSeparator) showOptions[1]).getOrientation()); + assertEquals("secondary structure", + ((JMenuItem) showOptions[2]).getText()); + assertEquals("PDB", ((JMenuItem) showOptions[2]).getToolTipText()); + assertEquals("Temp", ((JMenuItem) showOptions[3]).getText()); + assertEquals("PDB2", ((JMenuItem) showOptions[3]).getToolTipText()); + + assertEquals("All", ((JMenuItem) hideOptions[0]).getText()); + assertTrue(hideOptions[1] instanceof JPopupMenu.Separator); + assertEquals(JSeparator.HORIZONTAL, + ((JSeparator) hideOptions[1]).getOrientation()); + } } -- 1.7.10.2