+ * Add a link to show feature details for each sequence feature
+ *
+ * @param features
+ * @param column
+ * @param seq
+ */
+ protected void addFeatureDetails(List<SequenceFeature> features,
+ SequenceI seq, int column)
+ {
+ /*
+ * 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)
+ {
+ addFeatureDetailsMenuItem(details, name, sf);
+ }
+
+ if (mf != null)
+ {
+ name = mf.fromSeq == seq ? mf.mapping.getTo().getName()
+ : mf.fromSeq.getName();
+ for (final SequenceFeature sf : mf.features)
+ {
+ addFeatureDetailsMenuItem(details, name, sf);
+ }
+ }
+ }
+
+ /**
+ * A helper method to add one menu item whose action is to show details for one
+ * feature
+ *
+ * @param details
+ * @param seqName
+ * @param sf
+ */
+ void addFeatureDetailsMenuItem(JMenu details, final String seqName,
+ final SequenceFeature sf)
+ {
+ int start = sf.getBegin();
+ int end = sf.getEnd();
+ String desc = null;
+ if (start == end)
+ {
+ desc = String.format("%s %d", sf.getType(), start);
+ }
+ else
+ {
+ desc = String.format("%s %d-%d", sf.getType(), start, end);
+ }
+ String tooltip = desc;
+ String description = sf.getDescription();
+ if (description != null)
+ {
+ description = StringUtils.stripHtmlTags(description);
+ if (description.length() > 12)
+ {
+ desc = desc + " " + description.substring(0, 12) + "..";
+ }
+ else
+ {
+ desc = desc + " " + description;
+ }
+ tooltip = tooltip + " " + description;
+ }
+ if (sf.getFeatureGroup() != null)
+ {
+ tooltip = tooltip + (" (" + sf.getFeatureGroup() + ")");
+ }
+ JMenuItem item = new JMenuItem(desc);
+ item.setToolTipText(tooltip);
+ item.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showFeatureDetails(seqName, sf);
+ }
+ });
+ details.add(item);
+ }
+
+ /**
+ * Opens a panel showing a text report of feature dteails
+ *
+ * @param seqName
+ *
+ * @param sf
+ */
+ protected void showFeatureDetails(String seqName, SequenceFeature sf)
+ {
+ JInternalFrame details;
+ if (Platform.isJS())
+ {
+ details = new JInternalFrame();
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.setOpaque(true);
+ panel.setBackground(Color.white);
+ // TODO JAL-3026 set style of table correctly for feature details
+ JLabel reprt = new JLabel(MessageManager
+ .formatMessage("label.html_content", new Object[]
+ { sf.getDetailsReport(seqName) }));
+ reprt.setBackground(Color.WHITE);
+ reprt.setOpaque(true);
+ panel.add(reprt, BorderLayout.CENTER);
+ details.setContentPane(panel);
+ details.pack();
+ }
+ else
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
+ CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
+ // 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(seqName));
+ details = cap;
+ }
+ Desktop.addInternalFrame(details,
+ MessageManager.getString("label.feature_details"), 500, 500);
+ }
+
+ /**
+ * Adds a 'Link' menu item with a sub-menu item for each hyperlink provided.
+ * 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. If no links are found, the menu is not added.
+ *
+ * @param seq
+ * @param features
+ */
+ void addLinks(final SequenceI seq, List<SequenceFeature> features)
+ {
+ JMenu linkMenu = buildLinkMenu(forIdPanel ? seq : null, features);
+
+ // only add link menu if it has entries
+ if (linkMenu.getItemCount() > 0)
+ {
+ if (forIdPanel)
+ {
+ 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.