Merge branch 'feature/JAL-3181linkOrdering' into develop
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 28 Mar 2019 07:56:40 +0000 (07:56 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 28 Mar 2019 07:56:40 +0000 (07:56 +0000)
1  2 
src/jalview/gui/PopupMenu.java

@@@ -46,7 -46,6 +46,7 @@@ import jalview.schemes.Blosum62ColourSc
  import jalview.schemes.ColourSchemeI;
  import jalview.schemes.ColourSchemes;
  import jalview.schemes.PIDColourScheme;
 +import jalview.schemes.ResidueColourScheme;
  import jalview.util.GroupUrlLink;
  import jalview.util.GroupUrlLink.UrlStringTooLongException;
  import jalview.util.MessageManager;
@@@ -69,19 -68,15 +69,17 @@@ import java.util.SortedMap
  import java.util.TreeMap;
  import java.util.Vector;
  
 +import javax.swing.ButtonGroup;
  import javax.swing.JCheckBoxMenuItem;
  import javax.swing.JColorChooser;
  import javax.swing.JMenu;
  import javax.swing.JMenuItem;
  import javax.swing.JPopupMenu;
 +import javax.swing.JRadioButtonMenuItem;
  
  /**
-  * DOCUMENT ME!
-  * 
-  * @author $author$
-  * @version $Revision: 1.118 $
+  * The popup menu that is displayed on right-click on a sequence id, or in the
+  * sequence alignment.
   */
  public class PopupMenu extends JPopupMenu implements ColourChangeListener
  {
@@@ -95,8 -90,6 +93,8 @@@
  
    protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
  
 +  protected JRadioButtonMenuItem annotationColour;
 +
    protected JMenuItem modifyConservation = new JMenuItem();
  
    AlignmentPanel ap;
    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,
+    * or database cross-references, depending on which links are enabled in user
+    * preferences.
+    * 
+    * @param seq
+    * @param features
+    * @return
+    */
+   static JMenu buildLinkMenu(final SequenceI seq,
+           List<SequenceFeature> features)
+   {
+     JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
+     List<String> nlinks = null;
+     if (seq != null)
+     {
+       nlinks = Preferences.sequenceUrlLinks.getLinksForMenu();
+       UrlLink.sort(nlinks);
+     }
+     else
+     {
+       nlinks = new ArrayList<>();
+     }
+     if (features != null)
+     {
+       for (SequenceFeature sf : features)
+       {
+         if (sf.links != null)
+         {
+           for (String link : sf.links)
+           {
+             nlinks.add(link);
+           }
+         }
+       }
+     }
+     /*
+      * instantiate the hyperlinklink templates from sequence data;
+      * note the order of the templates is preserved in the map
+      */
+     Map<String, List<String>> linkset = new LinkedHashMap<>();
+     for (String link : nlinks)
+     {
+       UrlLink urlLink = null;
+       try
+       {
+         urlLink = new UrlLink(link);
+       } catch (Exception foo)
+       {
+         Cache.log.error("Exception for URLLink '" + link + "'", foo);
+         continue;
+       }
+       if (!urlLink.isValid())
+       {
+         Cache.log.error(urlLink.getInvalidMessage());
+         continue;
+       }
+       urlLink.createLinksFromSeq(seq, linkset);
+     }
+     /*
+      * construct menu items for the hyperlinks (still preserving
+      * the order of the sorted templates)
+      */
+     addUrlLinks(linkMenu, linkset.values());
+     return linkMenu;
+   }
+   /**
+    * A helper method that builds menu items from the given links, with action
+    * handlers to open the link URL, and adds them to the linkMenu. Each provided
+    * link should be a list whose second item is the menu text, and whose fourth
+    * item is the URL to open when the menu item is selected.
+    * 
+    * @param linkMenu
+    * @param linkset
+    */
+   static private void addUrlLinks(JMenu linkMenu,
+           Collection<List<String>> linkset)
+   {
+     for (List<String> linkstrset : linkset)
+     {
+       final String url = linkstrset.get(3);
+       JMenuItem item = new JMenuItem(linkstrset.get(1));
+       item.setToolTipText(MessageManager
+               .formatMessage("label.open_url_param", new Object[]
+               { url }));
+       item.addActionListener(new ActionListener()
+       {
+         @Override
+         public void actionPerformed(ActionEvent e)
+         {
+           new Thread(new Runnable()
+           {
+             @Override
+             public void run()
+             {
+               showLink(url);
+             }
+           }).start();
+         }
+       });
+       linkMenu.add(item);
+     }
+   }
+   /**
+    * Opens the provided url in the default web browser, or shows an error
+    * message if this fails
+    * 
+    * @param url
+    */
+   static void showLink(String url)
+   {
+     try
+     {
+       jalview.util.BrowserLauncher.openURL(url);
+     } catch (Exception ex)
+     {
+       JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+               MessageManager.getString("label.web_browser_not_found_unix"),
+               MessageManager.getString("label.web_browser_not_found"),
+               JvOptionPane.WARNING_MESSAGE);
+       ex.printStackTrace();
+     }
+   }
+   /**
+    * add a late bound groupURL item to the given linkMenu
+    * 
+    * @param linkMenu
+    * @param label
+    *          - menu label string
+    * @param urlgenerator
+    *          GroupURLLink used to generate URL
+    * @param urlstub
+    *          Object array returned from the makeUrlStubs function.
+    */
+   static void addshowLink(JMenu linkMenu, String label,
+           final GroupUrlLink urlgenerator, final Object[] urlstub)
+   {
+     JMenuItem item = new JMenuItem(label);
+     item.setToolTipText(MessageManager
+             .formatMessage("label.open_url_seqs_param", new Object[]
+             { urlgenerator.getUrl_prefix(),
+                 urlgenerator.getNumberInvolved(urlstub) }));
+     // TODO: put in info about what is being sent.
+     item.addActionListener(new ActionListener()
+     {
+       @Override
+       public void actionPerformed(ActionEvent e)
+       {
+         new Thread(new Runnable()
+         {
+           @Override
+           public void run()
+           {
+             try
+             {
+               showLink(urlgenerator.constructFrom(urlstub));
+             } catch (UrlStringTooLongException e2)
+             {
+             }
+           }
+         }).start();
+       }
+     });
+     linkMenu.add(item);
+   }
+   /**
     * Creates a new PopupMenu object.
     * 
     * @param ap
          }
        }
      }
 -    // for the case when no sequences are even visible
 +
 +    /*
 +     * offer 'Reveal All'
 +     * - in the IdPanel (seq not null) if any sequence is hidden
 +     * - in the IdPanel or SeqPanel if all sequences are hidden (seq is null)
 +     */
      if (alignPanel.av.hasHiddenRows())
      {
 +      boolean addOption = seq != null;
 +      if (!addOption && alignPanel.av.getAlignment().getHeight() == 0)
 +      {
 +        addOption = true;
 +      }
 +      if (addOption)
        {
          menuItem = new JMenuItem(
                  MessageManager.getString("action.reveal_all"));
              }
            }
          });
 -
          add(menuItem);
        }
      }
     * When seq is not null, these are links for the sequence id, which may be to
     * external web sites for the sequence accession, and/or links embedded in
     * non-positional features. When seq is null, only links embedded in the
-    * provided features are added.
+    * provided features are added. If no links are found, the menu is not added.
     * 
     * @param seq
     * @param features
     */
    void addLinks(final SequenceI seq, List<SequenceFeature> features)
    {
-     JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
-     List<String> nlinks = null;
-     if (seq != null)
-     {
-       nlinks = Preferences.sequenceUrlLinks.getLinksForMenu();
-     }
-     else
-     {
-       nlinks = new ArrayList<>();
-     }
-     if (features != null)
-     {
-       for (SequenceFeature sf : features)
-       {
-         if (sf.links != null)
-         {
-           for (String link : sf.links)
-           {
-             nlinks.add(link);
-           }
-         }
-       }
-     }
-     Map<String, List<String>> linkset = new LinkedHashMap<>();
-     for (String link : nlinks)
-     {
-       UrlLink urlLink = null;
-       try
-       {
-         urlLink = new UrlLink(link);
-       } catch (Exception foo)
-       {
-         Cache.log.error("Exception for URLLink '" + link + "'", foo);
-         continue;
-       }
-       if (!urlLink.isValid())
-       {
-         Cache.log.error(urlLink.getInvalidMessage());
-         continue;
-       }
-       urlLink.createLinksFromSeq(seq, linkset);
-     }
-     addshowLinks(linkMenu, linkset.values());
+     JMenu linkMenu = buildLinkMenu(seq, features);
  
      // only add link menu if it has entries
      if (linkMenu.getItemCount() > 0)
      }
    }
  
-   private void addshowLinks(JMenu linkMenu,
-           Collection<List<String>> linkset)
-   {
-     for (List<String> linkstrset : linkset)
-     {
-       // split linkstr into label and url
-       addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
-     }
-   }
-   /**
-    * add a show URL menu item to the given linkMenu
-    * 
-    * @param linkMenu
-    * @param label
-    *          - menu label string
-    * @param url
-    *          - url to open
-    */
-   private void addshowLink(JMenu linkMenu, String label, final String url)
-   {
-     JMenuItem item = new JMenuItem(label);
-     item.setToolTipText(MessageManager.formatMessage("label.open_url_param",
-             new Object[]
-             { url }));
-     item.addActionListener(new ActionListener()
-     {
-       @Override
-       public void actionPerformed(ActionEvent e)
-       {
-         new Thread(new Runnable()
-         {
-           @Override
-           public void run()
-           {
-             showLink(url);
-           }
-         }).start();
-       }
-     });
-     linkMenu.add(item);
-   }
-   /**
-    * add a late bound groupURL item to the given linkMenu
-    * 
-    * @param linkMenu
-    * @param label
-    *          - menu label string
-    * @param urlgenerator
-    *          GroupURLLink used to generate URL
-    * @param urlstub
-    *          Object array returned from the makeUrlStubs function.
-    */
-   private void addshowLink(JMenu linkMenu, String label,
-           final GroupUrlLink urlgenerator, final Object[] urlstub)
-   {
-     JMenuItem item = new JMenuItem(label);
-     item.setToolTipText(MessageManager
-             .formatMessage("label.open_url_seqs_param", new Object[]
-             { urlgenerator.getUrl_prefix(),
-                 urlgenerator.getNumberInvolved(urlstub) }));
-     // TODO: put in info about what is being sent.
-     item.addActionListener(new ActionListener()
-     {
-       @Override
-       public void actionPerformed(ActionEvent e)
-       {
-         new Thread(new Runnable()
-         {
-           @Override
-           public void run()
-           {
-             try
-             {
-               showLink(urlgenerator.constructFrom(urlstub));
-             } catch (UrlStringTooLongException e2)
-             {
-             }
-           }
-         }).start();
-       }
-     });
-     linkMenu.add(item);
-   }
    /**
     * DOCUMENT ME!
     * 
        }
      });
  
 +    annotationColour = new JRadioButtonMenuItem(
 +            MessageManager.getString("action.by_annotation"));
 +    annotationColour.setName(ResidueColourScheme.ANNOTATION_COLOUR);
 +    annotationColour.setEnabled(false);
 +    annotationColour.setToolTipText(
 +            MessageManager.getString("label.by_annotation_tooltip"));
 +
      modifyConservation.setText(MessageManager
              .getString("label.modify_conservation_threshold"));
      modifyConservation.addActionListener(new ActionListener()
      colourMenu.add(textColour);
      colourMenu.addSeparator();
  
 -    ColourMenuHelper.addMenuItems(colourMenu, this, sg, false);
 +    ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this, sg,
 +            false);
 +    bg.add(annotationColour);
 +    colourMenu.add(annotationColour);
  
      colourMenu.addSeparator();
      colourMenu.add(conservationMenuItem);
      refresh();
    }
  
-   public void showLink(String url)
-   {
-     try
-     {
-       jalview.util.BrowserLauncher.openURL(url);
-     } catch (Exception ex)
-     {
-       JvOptionPane.showInternalMessageDialog(Desktop.desktop,
-               MessageManager.getString("label.web_browser_not_found_unix"),
-               MessageManager.getString("label.web_browser_not_found"),
-               JvOptionPane.WARNING_MESSAGE);
-       ex.printStackTrace();
-     }
-   }
    void hideSequences(boolean representGroup)
    {
      ap.av.hideSequences(sequence, representGroup);
       * switch to the chosen colour scheme (or null for None)
       */
      ColourSchemeI colourScheme = ColourSchemes.getInstance()
 -            .getColourScheme(colourSchemeName, sg,
 +            .getColourScheme(colourSchemeName, ap.av, sg,
                      ap.av.getHiddenRepSequences());
      sg.setColourScheme(colourScheme);
      if (colourScheme instanceof Blosum62ColourScheme