JAL-3187 add sequence to feature details table (and refactor PopupMenu)
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 17 Jun 2019 12:17:20 +0000 (13:17 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 17 Jun 2019 12:17:20 +0000 (13:17 +0100)
src/jalview/datamodel/SequenceFeature.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/SeqPanel.java
test/jalview/datamodel/SequenceFeatureTest.java
test/jalview/gui/PopupMenuTest.java

index 7052f34..e7e1342 100755 (executable)
@@ -345,6 +345,11 @@ public class SequenceFeature implements FeatureLocationI
     return featureGroup;
   }
 
+  /**
+   * Adds a hyperlink for the feature. This should have the format label|url.
+   * 
+   * @param labelLink
+   */
   public void addLink(String labelLink)
   {
     if (links == null)
@@ -602,9 +607,11 @@ public class SequenceFeature implements FeatureLocationI
   /**
    * Answers an html-formatted report of feature details
    * 
+   * @param sequence
+   * 
    * @return
    */
-  public String getDetailsReport()
+  public String getDetailsReport(SequenceI sequence)
   {
     FeatureSourceI metadata = FeatureSources.getInstance()
             .getSource(source);
@@ -612,9 +619,10 @@ public class SequenceFeature implements FeatureLocationI
     StringBuilder sb = new StringBuilder(128);
     sb.append("<br>");
     sb.append("<table>");
+    sb.append(String.format(ROW_DATA, "Location", sequence.getName(),
+            begin == end ? begin
+                    : begin + (isContactFeature() ? ":" : "-") + end));
     sb.append(String.format(ROW_DATA, "Type", type, ""));
-    sb.append(String.format(ROW_DATA, "Start/end", begin == end ? begin
-            : begin + (isContactFeature() ? ":" : "-") + end, ""));
     String desc = StringUtils.stripHtmlTags(description);
     sb.append(String.format(ROW_DATA, "Description", desc, ""));
     if (!Float.isNaN(score) && score != 0f)
index 702773b..06e35cd 100644 (file)
@@ -30,7 +30,6 @@ import jalview.commands.EditCommand;
 import jalview.commands.EditCommand.Action;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Annotation;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.PDBEntry;
@@ -83,6 +82,19 @@ import javax.swing.JRadioButtonMenuItem;
  */
 public class PopupMenu extends JPopupMenu implements ColourChangeListener
 {
+  /*
+   * true for ID Panel menu, false for alignment panel menu
+   */
+  private final boolean forIdPanel;
+
+  private final AlignmentPanel ap;
+
+  /*
+   * the sequence under the cursor when clicked
+   * (additional sequences may be selected)
+   */
+  private final SequenceI sequence;
+
   JMenu groupMenu = new JMenu();
 
   JMenuItem groupName = new JMenuItem();
@@ -97,28 +109,14 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
 
   protected JMenuItem modifyConservation = new JMenuItem();
 
-  AlignmentPanel ap;
-
   JMenu sequenceMenu = new JMenu();
 
-  JMenuItem sequenceName = new JMenuItem();
-
-  JMenuItem sequenceDetails = new JMenuItem();
-
-  JMenuItem sequenceSelDetails = new JMenuItem();
-
   JMenuItem makeReferenceSeq = new JMenuItem();
 
-  JMenuItem chooseAnnotations = new JMenuItem();
-
-  SequenceI sequence;
-
   JMenuItem createGroupMenuItem = new JMenuItem();
 
   JMenuItem unGroupMenuItem = new JMenuItem();
 
-  JMenuItem outline = new JMenuItem();
-
   JMenu colourMenu = new JMenu();
 
   JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem();
@@ -131,18 +129,12 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
 
   JMenu editMenu = new JMenu();
 
-  JMenuItem cut = new JMenuItem();
-
-  JMenuItem copy = new JMenuItem();
-
   JMenuItem upperCase = new JMenuItem();
 
   JMenuItem lowerCase = new JMenuItem();
 
   JMenuItem toggle = new JMenuItem();
 
-  JMenu pdbMenu = new JMenu();
-
   JMenu outputMenu = new JMenu();
 
   JMenu seqShowAnnotationsMenu = new JMenu();
@@ -159,22 +151,14 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   JMenuItem groupAddReferenceAnnotations = new JMenuItem(
           MessageManager.getString("label.add_reference_annotations"));
 
-  JMenuItem sequenceFeature = new JMenuItem();
-
   JMenuItem textColour = new JMenuItem();
 
-  JMenu jMenu1 = new JMenu();
+  JMenu editGroupMenu = new JMenu();
 
-  JMenuItem pdbStructureDialog = new JMenuItem();
+  JMenuItem chooseStructure = new JMenuItem();
 
   JMenu rnaStructureMenu = new JMenu();
 
-  JMenuItem editSequence = new JMenuItem();
-
-  JMenu groupLinksMenu;
-
-  JMenuItem hideInsertions = new JMenuItem();
-
   /**
    * Constructs a menu with sub-menu items for any hyperlinks for the sequence
    * and/or features provided. Hyperlinks may include a lookup by sequence id,
@@ -185,7 +169,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
    * @param features
    * @return
    */
-  static JMenu buildLinkMenu(final SequenceI seq,
+  protected static JMenu buildLinkMenu(final SequenceI seq,
           List<SequenceFeature> features)
   {
     JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
@@ -357,41 +341,50 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   }
 
   /**
-   * Creates a new PopupMenu object.
+   * Constructor for a PopupMenu for a click in the alignment panel (on a residue)
    * 
    * @param ap
    * @param seq
    * @param features
-   *          non-positional features (for seq not null), or positional features
-   *          at residue (for seq equal to null)
+   *                   sequence features overlapping the clicked residue
    */
   public PopupMenu(final AlignmentPanel ap, SequenceI seq,
           List<SequenceFeature> features)
   {
-    this(ap, seq, features, null);
+    this(false, ap, seq, features, null);
   }
 
   /**
-   * Constructor
+   * Constructor for a PopupMenu for a click in the sequence id panel
    * 
    * @param alignPanel
    * @param seq
-   *          the sequence under the cursor if in the Id panel, null if in the
-   *          sequence panel
    * @param features
-   *          non-positional features if in the Id panel, features at the
-   *          clicked residue if in the sequence panel
+   *                     non-positional features for the sequence
    * @param groupLinks
    */
   public PopupMenu(final AlignmentPanel alignPanel, final SequenceI seq,
           List<SequenceFeature> features, List<String> groupLinks)
   {
-    // /////////////////////////////////////////////////////////
-    // If this is activated from the sequence panel, the user may want to
-    // edit or annotate a particular residue. Therefore display the residue menu
-    //
-    // If from the IDPanel, we must display the sequence menu
-    // ////////////////////////////////////////////////////////
+    this(true, alignPanel, seq, features, groupLinks);
+  }
+
+  /**
+   * Private constructor that constructs a popup menu for either sequence ID
+   * Panel, or alignment context
+   * 
+   * @param fromIdPanel
+   * @param alignPanel
+   * @param seq
+   * @param features
+   * @param groupLinks
+   */
+  private PopupMenu(boolean fromIdPanel,
+          final AlignmentPanel alignPanel,
+          final SequenceI seq, List<SequenceFeature> features,
+          List<String> groupLinks)
+  {
+    this.forIdPanel = fromIdPanel;
     this.ap = alignPanel;
     sequence = seq;
 
@@ -416,9 +409,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
      * 'reference annotations' that may be added to the alignment. First for the
      * currently selected sequence (if there is one):
      */
-    final List<SequenceI> selectedSequence = (seq == null
-            ? Collections.<SequenceI> emptyList()
-            : Arrays.asList(seq));
+    final List<SequenceI> selectedSequence = (forIdPanel
+            ? Arrays.asList(seq)
+            : Collections.<SequenceI> emptyList());
     buildAnnotationTypesMenus(seqShowAnnotationsMenu,
             seqHideAnnotationsMenu, selectedSequence);
     configureReferenceAnnotationsMenu(seqAddReferenceAnnotations,
@@ -443,9 +436,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       e.printStackTrace();
     }
 
-    JMenuItem menuItem;
-    if (seq != null)
+    if (forIdPanel)
     {
+      JMenuItem menuItem;
       sequenceMenu.setText(sequence.getName());
       if (seq == alignPanel.av.getAlignment().getSeqrep())
       {
@@ -600,7 +593,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       }
       if (addOption)
       {
-        menuItem = new JMenuItem(
+        JMenuItem menuItem = new JMenuItem(
                 MessageManager.getString("action.reveal_all"));
         menuItem.addActionListener(new ActionListener()
         {
@@ -692,25 +685,25 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     {
       createGroupMenuItem.setVisible(true);
       unGroupMenuItem.setVisible(false);
-      jMenu1.setText(MessageManager.getString("action.edit_new_group"));
+      editGroupMenu.setText(MessageManager.getString("action.edit_new_group"));
     }
     else
     {
       createGroupMenuItem.setVisible(false);
       unGroupMenuItem.setVisible(true);
-      jMenu1.setText(MessageManager.getString("action.edit_group"));
+      editGroupMenu.setText(MessageManager.getString("action.edit_group"));
     }
 
-    if (seq == null)
+    if (!forIdPanel)
     {
       sequenceMenu.setVisible(false);
-      pdbStructureDialog.setVisible(false);
+      chooseStructure.setVisible(false);
       rnaStructureMenu.setVisible(false);
     }
 
     addLinks(seq, features);
 
-    if (seq == null)
+    if (!forIdPanel)
     {
       addFeatureDetails(features);
     }
@@ -785,10 +778,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   protected void showFeatureDetails(SequenceFeature sf)
   {
     CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
-    // it appears Java's CSS does not support border-collaps :-(
+    // it appears Java's CSS does not support border-collapse :-(
     cap.addStylesheetRule("table { border-collapse: collapse;}");
     cap.addStylesheetRule("table, td, th {border: 1px solid black;}");
-    cap.setText(sf.getDetailsReport());
+    cap.setText(sf.getDetailsReport(sequence));
 
     Desktop.addInternalFrame(cap,
             MessageManager.getString("label.feature_details"), 500, 500);
@@ -806,12 +799,12 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
    */
   void addLinks(final SequenceI seq, List<SequenceFeature> features)
   {
-    JMenu linkMenu = buildLinkMenu(seq, features);
+    JMenu linkMenu = buildLinkMenu(forIdPanel ? seq : null, features);
 
     // only add link menu if it has entries
     if (linkMenu.getItemCount() > 0)
     {
-      if (sequence != null)
+      if (forIdPanel)
       {
         sequenceMenu.add(linkMenu);
       }
@@ -959,7 +952,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     // menu appears asap
     // sequence only URLs
     // ID/regex match URLs
-    groupLinksMenu = new JMenu(
+    JMenu groupLinksMenu = new JMenu(
             MessageManager.getString("action.group_link"));
     // three types of url that might be created.
     JMenu[] linkMenus = new JMenu[] { null,
@@ -1118,7 +1111,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       }
     });
     sequenceMenu.setText(MessageManager.getString("label.sequence"));
-    sequenceName.setText(
+
+    JMenuItem sequenceName = new JMenuItem(
             MessageManager.getString("label.edit_name_description"));
     sequenceName.addActionListener(new ActionListener()
     {
@@ -1128,8 +1122,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
         sequenceName_actionPerformed();
       }
     });
-    chooseAnnotations
-            .setText(MessageManager.getString("action.choose_annotations"));
+    JMenuItem chooseAnnotations = new JMenuItem(
+            MessageManager.getString("action.choose_annotations"));
     chooseAnnotations.addActionListener(new ActionListener()
     {
       @Override
@@ -1138,24 +1132,24 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
         chooseAnnotations_actionPerformed(e);
       }
     });
-    sequenceDetails
-            .setText(MessageManager.getString("label.sequence_details"));
+    JMenuItem sequenceDetails = new JMenuItem(
+            MessageManager.getString("label.sequence_details"));
     sequenceDetails.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        sequenceDetails_actionPerformed();
+        createSequenceDetailsReport(new SequenceI[] { sequence });
       }
     });
-    sequenceSelDetails
-            .setText(MessageManager.getString("label.sequence_details"));
+    JMenuItem sequenceSelDetails = new JMenuItem(
+            MessageManager.getString("label.sequence_details"));
     sequenceSelDetails.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        sequenceSelectionDetails_actionPerformed();
+        createSequenceDetailsReport(ap.av.getSequenceSelection());
       }
     });
 
@@ -1180,7 +1174,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       }
     });
 
-    outline.setText(MessageManager.getString("action.border_colour"));
+    JMenuItem outline = new JMenuItem(
+            MessageManager.getString("action.border_colour"));
     outline.addActionListener(new ActionListener()
     {
       @Override
@@ -1230,7 +1225,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       }
     });
     editMenu.setText(MessageManager.getString("action.edit"));
-    cut.setText(MessageManager.getString("action.cut"));
+    JMenuItem cut = new JMenuItem(MessageManager.getString("action.cut"));
     cut.addActionListener(new ActionListener()
     {
       @Override
@@ -1248,7 +1243,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
         changeCase(e);
       }
     });
-    copy.setText(MessageManager.getString("action.copy"));
+    JMenuItem copy = new JMenuItem(MessageManager.getString("action.copy"));
     copy.addActionListener(new ActionListener()
     {
       @Override
@@ -1285,7 +1280,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
             .setText(MessageManager.getString("label.show_annotations"));
     groupHideAnnotationsMenu
             .setText(MessageManager.getString("label.hide_annotations"));
-    sequenceFeature.setText(
+    JMenuItem sequenceFeature = new JMenuItem(
             MessageManager.getString("label.create_sequence_feature"));
     sequenceFeature.addActionListener(new ActionListener()
     {
@@ -1295,10 +1290,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
         sequenceFeature_actionPerformed();
       }
     });
-    jMenu1.setText(MessageManager.getString("label.group"));
-    pdbStructureDialog.setText(
+    editGroupMenu.setText(MessageManager.getString("label.group"));
+    chooseStructure.setText(
             MessageManager.getString("label.show_pdbstruct_dialog"));
-    pdbStructureDialog.addActionListener(new ActionListener()
+    chooseStructure.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent actionEvent)
@@ -1316,7 +1311,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
             .setText(MessageManager.getString("label.view_rna_structure"));
 
     // colStructureMenu.setText("Colour By Structure");
-    editSequence.setText(
+    JMenuItem editSequence = new JMenuItem(
             MessageManager.getString("label.edit_sequence") + "...");
     editSequence.addActionListener(new ActionListener()
     {
@@ -1338,25 +1333,25 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
 
       }
     });
-    hideInsertions
-            .setText(MessageManager.getString("label.hide_insertions"));
-    hideInsertions.addActionListener(new ActionListener()
-    {
-
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        hideInsertions_actionPerformed(e);
-      }
-    });
 
     groupMenu.add(sequenceSelDetails);
     add(groupMenu);
     add(sequenceMenu);
     add(rnaStructureMenu);
-    add(pdbStructureDialog);
-    if (sequence != null)
+    add(chooseStructure);
+    if (forIdPanel)
     {
+      JMenuItem hideInsertions = new JMenuItem(
+              MessageManager.getString("label.hide_insertions"));
+      hideInsertions.addActionListener(new ActionListener()
+      {
+
+        @Override
+        public void actionPerformed(ActionEvent e)
+        {
+          hideInsertions_actionPerformed(e);
+        }
+      });
       add(hideInsertions);
     }
     // annotations configuration panel suppressed for now
@@ -1377,7 +1372,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     groupMenu.add(sequenceFeature);
     groupMenu.add(createGroupMenuItem);
     groupMenu.add(unGroupMenuItem);
-    groupMenu.add(jMenu1);
+    groupMenu.add(editGroupMenu);
     sequenceMenu.add(sequenceName);
     sequenceMenu.add(sequenceDetails);
     sequenceMenu.add(makeReferenceSeq);
@@ -1391,17 +1386,13 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     editMenu.add(upperCase);
     editMenu.add(lowerCase);
     editMenu.add(toggle);
-    // JBPNote: These shouldn't be added here - should appear in a generic
-    // 'apply web service to this sequence menu'
-    // pdbMenu.add(RNAFold);
-    // pdbMenu.add(ContraFold);
-    jMenu1.add(groupName);
-    jMenu1.add(colourMenu);
-    jMenu1.add(showBoxes);
-    jMenu1.add(showText);
-    jMenu1.add(showColourText);
-    jMenu1.add(outline);
-    jMenu1.add(displayNonconserved);
+    editGroupMenu.add(groupName);
+    editGroupMenu.add(colourMenu);
+    editGroupMenu.add(showBoxes);
+    editGroupMenu.add(showText);
+    editGroupMenu.add(showColourText);
+    editGroupMenu.add(outline);
+    editGroupMenu.add(displayNonconserved);
   }
 
   /**
@@ -1664,11 +1655,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     createSequenceDetailsReport(ap.av.getSequenceSelection());
   }
 
-  protected void sequenceDetails_actionPerformed()
-  {
-    createSequenceDetailsReport(new SequenceI[] { sequence });
-  }
-
   public void createSequenceDetailsReport(SequenceI[] sequences)
   {
     CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
@@ -1856,10 +1842,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   }
 
   /**
-   * DOCUMENT ME!
-   * 
-   * @param e
-   *          DOCUMENT ME!
+   * Shows a dialog where the sequence name and description may be edited. If a
+   * name containing spaces is entered, these are converted to underscores, with a
+   * warning message.
    */
   void sequenceName_actionPerformed()
   {
@@ -1877,9 +1862,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       return;
     }
 
-    if (dialog.getName() != null)
+    String name = dialog.getName();
+    if (name != null)
     {
-      if (dialog.getName().indexOf(" ") > -1)
+      if (name.indexOf(" ") > -1)
       {
         JvOptionPane.showMessageDialog(ap,
                 MessageManager
@@ -1887,9 +1873,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
                 MessageManager
                         .getString("label.no_spaces_allowed_sequence_name"),
                 JvOptionPane.WARNING_MESSAGE);
+        name = name.replace(' ', '_');
       }
 
-      sequence.setName(dialog.getName().replace(' ', '_'));
+      sequence.setName(name);
       ap.paintAlignment(false, false);
     }
 
@@ -2105,38 +2092,20 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     }
   }
 
-  public void colourByStructure(String pdbid)
-  {
-    Annotation[] anots = ap.av.getStructureSelectionManager()
-            .colourSequenceFromStructure(sequence, pdbid);
-
-    AlignmentAnnotation an = new AlignmentAnnotation("Structure",
-            "Coloured by " + pdbid, anots);
-
-    ap.av.getAlignment().addAnnotation(an);
-    an.createSequenceMapping(sequence, 0, true);
-    // an.adjustForAlignment();
-    ap.av.getAlignment().setAnnotationIndex(an, 0);
-
-    ap.adjustAnnotationHeight();
-
-    sequence.addAlignmentAnnotation(an);
-
-  }
-
   public void editSequence_actionPerformed(ActionEvent actionEvent)
   {
     SequenceGroup sg = ap.av.getSelectionGroup();
 
+    SequenceI seq = sequence;
     if (sg != null)
     {
-      if (sequence == null)
+      if (seq == null)
       {
-        sequence = sg.getSequenceAt(0);
+        seq = sg.getSequenceAt(0);
       }
 
       EditNameDialog dialog = new EditNameDialog(
-              sequence.getSequenceAsString(sg.getStartRes(),
+              seq.getSequenceAsString(sg.getStartRes(),
                       sg.getEndRes() + 1),
               null, MessageManager.getString("label.edit_sequence"), null,
               MessageManager.getString("label.edit_sequence"),
index bc17cc2..e7bd200 100644 (file)
@@ -2257,7 +2257,7 @@ public class SeqPanel extends JPanel
     List<SequenceFeature> features = ap.getFeatureRenderer()
             .findFeaturesAtColumn(sequence, column + 1);
 
-    PopupMenu pop = new PopupMenu(ap, null, features);
+    PopupMenu pop = new PopupMenu(ap, sequence, features);
     pop.show(this, evt.getX(), evt.getY());
   }
 
index 9111e5a..2774a16 100644 (file)
@@ -277,43 +277,45 @@ public class SequenceFeatureTest
   @Test(groups = { "Functional" })
   public void testGetDetailsReport()
   {
+    SequenceI seq = new Sequence("TestSeq", "PLRFQMD");
+
     // single locus, no group, no score
     SequenceFeature sf = new SequenceFeature("variant", "G,C", 22, 22, null);
-    String expected = "<br><table><tr><td>Type</td><td>variant</td><td></td></tr>"
-            + "<tr><td>Start/end</td><td>22</td><td></td></tr>"
+    String expected = "<br><table><tr><td>Location</td><td>TestSeq</td><td>22</td></tr>"
+            + "<tr><td>Type</td><td>variant</td><td></td></tr>"
             + "<tr><td>Description</td><td>G,C</td><td></td></tr></table>";
-    assertEquals(expected, sf.getDetailsReport());
+    assertEquals(expected, sf.getDetailsReport(seq));
 
     // contact feature
     sf = new SequenceFeature("Disulphide Bond", "a description", 28, 31,
             null);
-    expected = "<br><table><tr><td>Type</td><td>Disulphide Bond</td><td></td></tr>"
-            + "<tr><td>Start/end</td><td>28:31</td><td></td></tr>"
+    expected = "<br><table><tr><td>Location</td><td>TestSeq</td><td>28:31</td></tr>"
+            + "<tr><td>Type</td><td>Disulphide Bond</td><td></td></tr>"
             + "<tr><td>Description</td><td>a description</td><td></td></tr></table>";
-    assertEquals(expected, sf.getDetailsReport());
+    assertEquals(expected, sf.getDetailsReport(seq));
 
     sf = new SequenceFeature("variant", "G,C", 22, 33,
             12.5f, "group");
     sf.setValue("Parent", "ENSG001");
     sf.setValue("Child", "ENSP002");
-    expected = "<br><table><tr><td>Type</td><td>variant</td><td></td></tr>"
-            + "<tr><td>Start/end</td><td>22-33</td><td></td></tr>"
+    expected = "<br><table><tr><td>Location</td><td>TestSeq</td><td>22-33</td></tr>"
+            + "<tr><td>Type</td><td>variant</td><td></td></tr>"
             + "<tr><td>Description</td><td>G,C</td><td></td></tr>"
             + "<tr><td>Score</td><td>12.5</td><td></td></tr>"
             + "<tr><td>Group</td><td>group</td><td></td></tr>"
             + "<tr><td>Child</td><td></td><td>ENSP002</td></tr>"
             + "<tr><td>Parent</td><td></td><td>ENSG001</td></tr></table>";
-    assertEquals(expected, sf.getDetailsReport());
+    assertEquals(expected, sf.getDetailsReport(seq));
 
     /*
      * feature with embedded html link in description
      */
     String desc = "<html>Fer2 Status: True Positive <a href=\"http://pfam.xfam.org/family/PF00111\">Pfam 8_8</a></html>";
     sf = new SequenceFeature("Pfam", desc, 8, 83, "Uniprot");
-    expected = "<br><table><tr><td>Type</td><td>Pfam</td><td></td></tr>"
-            + "<tr><td>Start/end</td><td>8-83</td><td></td></tr>"
+    expected = "<br><table><tr><td>Location</td><td>TestSeq</td><td>8-83</td></tr>"
+            + "<tr><td>Type</td><td>Pfam</td><td></td></tr>"
             + "<tr><td>Description</td><td>Fer2 Status: True Positive <a href=\"http://pfam.xfam.org/family/PF00111\">Pfam 8_8</a></td><td></td></tr>"
             + "<tr><td>Group</td><td>Uniprot</td><td></td></tr></table>";
-    assertEquals(expected, sf.getDetailsReport());
+    assertEquals(expected, sf.getDetailsReport(seq));
   }
 }
index df30935..df86494 100644 (file)
@@ -91,6 +91,8 @@ public class PopupMenuTest
   public void setUp() throws IOException
   {
     Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Cache.initLogger();
+
     String inMenuString = ("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
             + SEQUENCE_ID
             + "$"
@@ -534,7 +536,6 @@ public class PopupMenuTest
      * note dbref GENE3D is matched to link Gene3D, the latter is displayed
      */
     linkMenu = PopupMenu.buildLinkMenu(seq1, noFeatures);
-    assertEquals(linkText, linkMenu.getText());
     linkItems = linkMenu.getMenuComponents();
     assertEquals(3, linkItems.length);
     assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText());
@@ -553,10 +554,31 @@ public class PopupMenuTest
     Preferences.sequenceUrlLinks = factory.createUrlProvider();
 
     linkMenu = PopupMenu.buildLinkMenu(seq1, noFeatures);
-    assertEquals(linkText, linkMenu.getText());
     linkItems = linkMenu.getMenuComponents();
     assertEquals(1, linkItems.length);
     assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText());
+
+    /*
+     * if sequence is null, only feature links are shown (alignment popup submenu)
+     */
+    linkMenu = PopupMenu.buildLinkMenu(null, noFeatures);
+    linkItems = linkMenu.getMenuComponents();
+    assertEquals(0, linkItems.length);
+
+    List<SequenceFeature> features = new ArrayList<>();
+    SequenceFeature sf = new SequenceFeature("type", "desc", 1, 20, null);
+    features.add(sf);
+    linkMenu = PopupMenu.buildLinkMenu(null, features);
+    linkItems = linkMenu.getMenuComponents();
+    assertEquals(0, linkItems.length); // feature has no links
+
+    sf.addLink("Pfam family|http://pfam.xfam.org/family/PF00111");
+    linkMenu = PopupMenu.buildLinkMenu(null, features);
+    linkItems = linkMenu.getMenuComponents();
+    assertEquals(1, linkItems.length);
+    JMenuItem item = (JMenuItem) linkItems[0];
+    assertEquals("Pfam family", item.getText());
+    // ? no way to verify URL, compiled into link's actionListener
   }
 
   @Test(groups = { "Functional" })