+ addshowLinks(linkMenu, linkset.values());
+
+ if (sequence != null)
+ {
+ sequenceMenu.add(linkMenu);
+ }
+ else
+ {
+ add(linkMenu);
+ }
+ }
+
+
+
+ /**
+ * 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. Separate menus are built for
+ * the selected sequence group (if any), and the selected sequence.
+ * <p>
+ * 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
+ * as visible (to avoid duplication of the display). For such groups we add a
+ * composite type name, e.g.
+ * <p>
+ * IUPredWS (Long), IUPredWS (Short)
+ *
+ * @param seq
+ */
+ protected void buildAnnotationTypesMenus(JMenu showMenu, JMenu hideMenu,
+ List<SequenceI> forSequences)
+ {
+ showMenu.removeAll();
+ hideMenu.removeAll();
+
+ final List<String> all = Arrays.asList(new String[] { MessageManager
+ .getString("label.all") });
+ 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. Using LinkedHashMap means we will retrieve in
+ * the insertion order, which is the order of the annotations on the
+ * alignment.
+ */
+ Map<String, List<List<String>>> shownTypes = new LinkedHashMap<String, List<List<String>>>();
+ Map<String, List<List<String>>> hiddenTypes = new LinkedHashMap<String, List<List<String>>>();
+ AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
+ AlignmentAnnotationUtils.asList(annotations), forSequences);
+
+ for (String calcId : hiddenTypes.keySet())
+ {
+ for (List<String> type : hiddenTypes.get(calcId))
+ {
+ addAnnotationTypeToShowHide(showMenu, forSequences, calcId, type,
+ false, true);
+ }
+ }
+ // grey out 'show annotations' if none are hidden
+ showMenu.setEnabled(!hiddenTypes.isEmpty());
+
+ for (String calcId : shownTypes.keySet())
+ {
+ for (List<String> type : shownTypes.get(calcId))
+ {
+ addAnnotationTypeToShowHide(hideMenu, forSequences, calcId, type,
+ false, false);
+ }
+ }
+ // grey out 'hide annotations' if none are shown
+ hideMenu.setEnabled(!shownTypes.isEmpty());
+ }
+
+ /**
+ * Returns a list of sequences - either the current selection group (if there
+ * is one), else the specified single sequence.
+ *
+ * @param seq
+ * @return
+ */
+ protected List<SequenceI> getSequenceScope(SequenceI seq)
+ {
+ List<SequenceI> forSequences = null;
+ final SequenceGroup selectionGroup = ap.av.getSelectionGroup();
+ if (selectionGroup != null && selectionGroup.getSize() > 0)
+ {
+ forSequences = selectionGroup.getSequences();
+ }
+ else
+ {
+ forSequences = seq == null ? Collections.<SequenceI> emptyList()
+ : Arrays.asList(seq);
+ }
+ return forSequences;
+ }
+
+ /**
+ * Add one annotation type to the 'Show Annotations' or 'Hide Annotations'
+ * menus.
+ *
+ * @param showOrHideMenu
+ * the menu to add to
+ * @param forSequences
+ * the sequences whose annotations may be shown or hidden
+ * @param calcId
+ * @param types
+ * the label to add
+ * @param allTypes
+ * if true this is a special label meaning 'All'
+ * @param actionIsShow
+ * if true, the select menu item action is to show the annotation
+ * type, else hide
+ */
+ protected void addAnnotationTypeToShowHide(JMenu showOrHideMenu,
+ final List<SequenceI> forSequences, String calcId,
+ final List<String> types, final boolean allTypes,
+ final boolean actionIsShow)
+ {
+ String label = types.toString(); // [a, b, c]
+ label = label.substring(1, label.length() - 1); // a, b, c
+ final JMenuItem item = new JMenuItem(label);
+ item.setToolTipText(calcId);
+ item.addActionListener(new java.awt.event.ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ AlignmentUtils.showOrHideSequenceAnnotations(ap.getAlignment(),
+ types, forSequences, allTypes, actionIsShow);
+ refresh();
+ }
+ });
+ showOrHideMenu.add(item);
+ }
+
+ private void buildGroupURLMenu(SequenceGroup sg, List<String> groupLinks)
+ {
+
+ // TODO: usability: thread off the generation of group url content so root
+ // menu appears asap
+ // sequence only URLs
+ // ID/regex match URLs
+ groupLinksMenu = new JMenu(
+ MessageManager.getString("action.group_link"));
+ // three types of url that might be created.
+ JMenu[] linkMenus = new JMenu[] { null,
+ new JMenu(MessageManager.getString("action.ids")),
+ new JMenu(MessageManager.getString("action.sequences")),
+ new JMenu(MessageManager.getString("action.ids_sequences")) };
+
+ SequenceI[] seqs = ap.av.getSelectionAsNewSequence();
+ String[][] idandseqs = GroupUrlLink.formStrings(seqs);
+ Hashtable<String, Object[]> commonDbrefs = new Hashtable<String, Object[]>();
+ for (int sq = 0; sq < seqs.length; sq++)
+ {
+
+ int start = seqs[sq].findPosition(sg.getStartRes()), end = seqs[sq]
+ .findPosition(sg.getEndRes());
+ // just collect ids from dataset sequence
+ // TODO: check if IDs collected from selecton group intersects with the
+ // current selection, too
+ SequenceI sqi = seqs[sq];
+ while (sqi.getDatasetSequence() != null)
+ {
+ sqi = sqi.getDatasetSequence();
+ }
+ DBRefEntry[] dbr = sqi.getDBRefs();
+ if (dbr != null && dbr.length > 0)
+ {
+ for (int d = 0; d < dbr.length; d++)