3253-omnibus save
[jalview.git] / src / jalview / gui / PopupMenu.java
index 3145f7c..2e6e1b8 100644 (file)
@@ -24,15 +24,16 @@ import jalview.analysis.AAFrequency;
 import jalview.analysis.AlignmentAnnotationUtils;
 import jalview.analysis.AlignmentUtils;
 import jalview.analysis.Conservation;
+import jalview.api.AlignViewportI;
 import jalview.bin.Cache;
 import jalview.commands.ChangeCaseCommand;
 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.MappedFeatures;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
@@ -48,12 +49,14 @@ import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemes;
 import jalview.schemes.PIDColourScheme;
 import jalview.schemes.ResidueColourScheme;
+import jalview.util.Comparison;
 import jalview.util.GroupUrlLink;
 import jalview.util.GroupUrlLink.UrlStringTooLongException;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.util.StringUtils;
 import jalview.util.UrlLink;
+import jalview.viewmodel.seqfeatures.FeatureRendererModel;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -68,6 +71,7 @@ import java.util.Hashtable;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.Vector;
@@ -89,6 +93,24 @@ import javax.swing.JScrollPane;
  */
 public class PopupMenu extends JPopupMenu implements ColourChangeListener
 {
+  /*
+   * maximum length of feature description to include in popup menu item text
+   */
+  private static final int FEATURE_DESC_MAX = 40;
+
+  /*
+   * 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();
@@ -103,28 +125,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();
@@ -137,18 +145,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();
@@ -165,22 +167,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,
@@ -191,7 +185,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"));
@@ -317,9 +311,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   }
 
   /**
-   * For the popup menu on the idPanel.
-   * 
-   * Add a late bound groupURL item to the given linkMenu
+   * add a late bound groupURL item to the given linkMenu
    * 
    * @param linkMenu
    * @param label
@@ -351,15 +343,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
           {
             try
             {
-              // Object[] { int[] { number of matches seqs },
-              // boolean[] { which matched },
-              // StringBuffer[] { segment generated from inputs },
-              // String[] { url }
-              // }
-
-              // TODO bug: urlstub is { int[], boolean[] } but constructFrom
-              // requires something else.
-
               showLink(urlgenerator.constructFrom(urlstub));
             } catch (UrlStringTooLongException e2)
             {
@@ -374,42 +357,55 @@ 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
+   *              the panel in which the mouse is clicked
    * @param seq
-   * @param features
-   *          non-positional features (for seq not null), or positional features
-   *          at residue (for seq equal to null)
+   *              the sequence under the mouse
+   * @throws NullPointerException
+   *                                if seq is null
    */
-  public PopupMenu(final AlignmentPanel ap, SequenceI seq,
-          List<SequenceFeature> features)
+  public PopupMenu(final AlignmentPanel ap, SequenceI seq, int column)
   {
-    this(ap, seq, features, null);
+    this(false, ap, seq, column, null);
   }
 
   /**
-   * Constructor
+   * Constructor for a PopupMenu for a click in the sequence id panel
    * 
    * @param alignPanel
+   *                     the panel in which the mouse is clicked
    * @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
+   *                     the sequence under the mouse click
    * @param groupLinks
-   *          not implemented -- empty list
+   *                     templates for sequence external links
+   * @throws NullPointerException
+   *                                if seq is null
    */
   public PopupMenu(final AlignmentPanel alignPanel, final SequenceI seq,
-          List<SequenceFeature> features, List<String> groupLinks)
+          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, -1, groupLinks);
+  }
+
+  /**
+   * Private constructor that constructs a popup menu for either sequence ID
+   * Panel, or alignment context
+   * 
+   * @param fromIdPanel
+   * @param alignPanel
+   * @param seq
+   * @param column
+   *                      aligned column position (0...)
+   * @param groupLinks
+   */
+  private PopupMenu(boolean fromIdPanel,
+          final AlignmentPanel alignPanel,
+          final SequenceI seq, final int column, List<String> groupLinks)
+  {
+    Objects.requireNonNull(seq);
+    this.forIdPanel = fromIdPanel;
     this.ap = alignPanel;
     sequence = seq;
 
@@ -434,9 +430,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 && seq != null
+            ? Arrays.asList(seq)
+            : Collections.<SequenceI> emptyList());
     buildAnnotationTypesMenus(seqShowAnnotationsMenu,
             seqHideAnnotationsMenu, selectedSequence);
     configureReferenceAnnotationsMenu(seqAddReferenceAnnotations,
@@ -461,9 +457,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())
       {
@@ -618,7 +614,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()
         {
@@ -670,7 +666,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       // add any groupURLs to the groupURL submenu and make it visible
       if (groupLinks != null && groupLinks.size() > 0)
       {
-        // not implemented -- empty list
         buildGroupURLMenu(sg, groupLinks);
       }
       // Add a 'show all structures' for the current selection
@@ -711,27 +706,57 @@ 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);
     }
 
+    addLinksAndFeatures(seq, column);
+  }
+
+  /**
+   * Adds
+   * <ul>
+   * <li>configured sequence database links (ID panel popup menu)</li>
+   * <li>non-positional feature links (ID panel popup menu)</li>
+   * <li>positional feature links (alignment panel popup menu)</li>
+   * <li>feature details links (alignment panel popup menu)</li>
+   * </ul>
+   * If this panel is also showed complementary (CDS/protein) features, then links
+   * to their feature details are also added.
+   * 
+   * @param seq
+   * @param column
+   */
+  void addLinksAndFeatures(final SequenceI seq, final int column)
+  {
+    List<SequenceFeature> features = null;
+    if (forIdPanel)
+    {
+      features = sequence.getFeatures().getNonPositionalFeatures();
+    }
+    else
+    {
+      features = ap.getFeatureRenderer().findFeaturesAtColumn(sequence,
+              column + 1);
+    }
+
     addLinks(seq, features);
 
-    if (seq == null)
+    if (!forIdPanel)
     {
-      addFeatureDetails(features);
+      addFeatureDetails(features, seq, column);
     }
   }
 
@@ -739,69 +764,121 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
    * Add a link to show feature details for each sequence feature
    * 
    * @param features
+   * @param column
+   * @param seq
    */
-  protected void addFeatureDetails(List<SequenceFeature> features)
+  protected void addFeatureDetails(List<SequenceFeature> features,
+          SequenceI seq, int column)
   {
-    if (features == null || features.isEmpty())
+    /*
+     * add features in CDS/protein complement at the corresponding
+     * position if configured to do so
+   */
+    MappedFeatures mf = null;
+    if (ap.av.isShowComplementFeatures())
     {
+      if (!Comparison.isGap(sequence.getCharAt(column)))
+  {
+        AlignViewportI complement = ap.getAlignViewport()
+                .getCodingComplement();
+        AlignFrame af = Desktop.getAlignFrameFor(complement);
+        FeatureRendererModel fr2 = af.getFeatureRenderer();
+        int seqPos = sequence.findPosition(column);
+        mf = fr2.findComplementFeaturesAtResidue(sequence, seqPos);
+      }
+    }
+
+    if (features.isEmpty() && mf == null)
+    {
+      /*
+       * no features to show at this position
+       */
       return;
     }
     JMenu details = new JMenu(
             MessageManager.getString("label.feature_details"));
     add(details);
 
+    String name = seq.getName();
     for (final SequenceFeature sf : features)
     {
-      int start = sf.getBegin();
-      int end = sf.getEnd();
-      String desc = null;
-      if (start == end)
+      addFeatureDetailsMenuItem(details, name, sf);
+    }
+
+    if (mf != null)
+    {
+      name = mf.fromSeq == seq ? mf.mapping.getTo().getName()
+              : mf.fromSeq.getName();
+      for (final SequenceFeature sf : mf.features)
       {
-        desc = String.format("%s %d", sf.getType(), start);
+        addFeatureDetailsMenuItem(details, name, sf);
       }
-      else
+    }
+  }
+
+  /**
+   * A helper method to add one menu item whose action is to show details for one
+   * feature. The menu text includes feature description, but this may be
+   * truncated.
+   * 
+   * @param details
+   * @param seqName
+   * @param sf
+   */
+  void addFeatureDetailsMenuItem(JMenu details, final String seqName,
+          final SequenceFeature sf)
+  {
+      int start = sf.getBegin();
+      int end = sf.getEnd();
+    StringBuilder desc = new StringBuilder();
+    desc.append(sf.getType()).append(" ").append(String.valueOf(start));
+    if (start != end)
       {
-        desc = String.format("%s %d-%d", sf.getType(), start, end);
+      desc.append("-").append(String.valueOf(end));
       }
-      String tooltip = desc;
       String description = sf.getDescription();
       if (description != null)
       {
+      desc.append(" ");
         description = StringUtils.stripHtmlTags(description);
-        if (description.length() > 12)
+
+      /*
+       * truncate overlong descriptions unless they contain an href
+       * (as truncation could leave corrupted html)
+       */
+      boolean hasLink = description.indexOf("a href") > -1;
+      if (description.length() > FEATURE_DESC_MAX && !hasLink)
         {
-          desc = desc + " " + description.substring(0, 12) + "..";
+        description = description.substring(0, FEATURE_DESC_MAX) + "...";
         }
-        else
-        {
-          desc = desc + " " + description;
+      desc.append(description);
         }
-        tooltip = tooltip + " " + description;
-      }
-      if (sf.getFeatureGroup() != null)
+    String featureGroup = sf.getFeatureGroup();
+    if (featureGroup != null)
       {
-        tooltip = tooltip + (" (" + sf.getFeatureGroup() + ")");
+      desc.append(" (").append(featureGroup).append(")");
       }
-      JMenuItem item = new JMenuItem(desc);
-      item.setToolTipText(tooltip);
+    String htmlText = JvSwingUtils.wrapTooltip(true, desc.toString());
+    JMenuItem item = new JMenuItem(htmlText);
       item.addActionListener(new ActionListener()
       {
         @Override
         public void actionPerformed(ActionEvent e)
         {
-          showFeatureDetails(sf);
+        showFeatureDetails(seqName, sf);
         }
       });
       details.add(item);
     }
-  }
 
   /**
    * Opens a panel showing a text report of feature dteails
    * 
+   * @param seqName
+   * 
    * @param sf
    */
-  protected void showFeatureDetails(SequenceFeature sf)
+  protected void showFeatureDetails(String seqName, SequenceFeature sf)
   {
     JInternalFrame details;
     if (Platform.isJS())
@@ -813,7 +890,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       // TODO JAL-3026 set style of table correctly for feature details
       JLabel reprt = new JLabel(MessageManager
               .formatMessage("label.html_content", new Object[]
-              { sf.getDetailsReport() }));
+              { sf.getDetailsReport(seqName) }));
       reprt.setBackground(Color.WHITE);
       reprt.setOpaque(true);
       panel.add(reprt, BorderLayout.CENTER);
@@ -831,7 +908,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       // it appears Java's CSS does not support border-collaps :-(
       cap.addStylesheetRule("table { border-collapse: collapse;}");
       cap.addStylesheetRule("table, td, th {border: 1px solid black;}");
-      cap.setText(sf.getDetailsReport());
+      cap.setText(sf.getDetailsReport(seqName));
       details = cap;
     }
     Desktop.addInternalFrame(details,
@@ -850,12 +927,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);
       }
@@ -996,12 +1073,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     showOrHideMenu.add(item);
   }
 
-  /**
-   *
-   * @param sg
-   * @param groupLinks
-   *          not implemented -- empty list
-   */
   private void buildGroupURLMenu(SequenceGroup sg, List<String> groupLinks)
   {
 
@@ -1009,7 +1080,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,
@@ -1063,15 +1134,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
         }
       }
     }
-    if (groupLinks.size() == 0)
-    {
-      return;
-    }
     // now create group links for all distinct ID/sequence sets.
     boolean addMenu = false; // indicates if there are any group links to give
                              // to user
-
-    // not implmeented -- empty list
     for (String link : groupLinks)
     {
       GroupUrlLink urlLink = null;
@@ -1083,7 +1148,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
         Cache.log.error("Exception for GroupURLLink '" + link + "'", foo);
         continue;
       }
-      ;
       if (!urlLink.isValid())
       {
         Cache.log.error(urlLink.getInvalidMessage());
@@ -1124,7 +1188,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       {
         urlset = urlLink.makeUrlStubs(ids, seqstr,
                 "FromJalview" + System.currentTimeMillis(), false);
-        // { int[], boolean[] } only here
       } catch (UrlStringTooLongException e)
       {
       }
@@ -1176,7 +1239,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()
     {
@@ -1186,8 +1250,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
@@ -1196,24 +1260,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());
       }
     });
 
@@ -1238,7 +1302,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
@@ -1288,7 +1353,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
@@ -1306,7 +1371,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
@@ -1343,7 +1408,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()
     {
@@ -1353,10 +1418,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)
@@ -1374,7 +1439,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()
     {
@@ -1396,8 +1461,16 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
 
       }
     });
-    hideInsertions
-            .setText(MessageManager.getString("label.hide_insertions"));
+
+    groupMenu.add(sequenceSelDetails);
+    add(groupMenu);
+    add(sequenceMenu);
+    add(rnaStructureMenu);
+    add(chooseStructure);
+    if (forIdPanel)
+    {
+      JMenuItem hideInsertions = new JMenuItem(
+              MessageManager.getString("label.hide_insertions"));
     hideInsertions.addActionListener(new ActionListener()
     {
 
@@ -1407,14 +1480,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
         hideInsertions_actionPerformed(e);
       }
     });
-
-    groupMenu.add(sequenceSelDetails);
-    add(groupMenu);
-    add(sequenceMenu);
-    add(rnaStructureMenu);
-    add(pdbStructureDialog);
-    if (sequence != null)
-    {
       add(hideInsertions);
     }
     // annotations configuration panel suppressed for now
@@ -1435,7 +1500,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);
@@ -1449,17 +1514,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);
   }
 
   /**
@@ -1722,11 +1783,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)
   {
     StringBuilder contents = new StringBuilder(128);
@@ -1936,7 +1992,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   }
 
   /**
-   * Shows a dialog where sequence name and description may be edited
+   * 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()
   {
@@ -2008,8 +2066,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
       {
         getGroup().setOutlineColour(c);
         refresh();
+      }
       };
-    };
     JalviewColourChooser.showColourChooser(Desktop.getDesktopPane(),
             title, Color.BLUE, listener);
   }
@@ -2171,25 +2229,6 @@ 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);
-
-  }
-
   /**
    * Shows a dialog where sequence characters may be edited. Any changes are
    * applied, and added as an available 'Undo' item in the edit commands
@@ -2199,16 +2238,16 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
   {
     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(),
-                      sg.getEndRes() + 1),
+              seq.getSequenceAsString(sg.getStartRes(), sg.getEndRes() + 1),
               null, MessageManager.getString("label.edit_sequence"), null);
       dialog.showDialog(ap.alignFrame,
               MessageManager.getString("label.edit_sequence"),