From 054cc21f3aad9e37c464b1af6c62dbee6ca624b1 Mon Sep 17 00:00:00 2001
From: gmungoc
Date: Tue, 12 Apr 2016 13:00:38 +0100
Subject: [PATCH] JAL-1723 tooltip dbrefs sorted and limited to two per source
---
src/jalview/appletgui/APopupMenu.java | 6 +-
src/jalview/gui/IdPanel.java | 4 +-
src/jalview/gui/PopupMenu.java | 3 +-
src/jalview/gui/SeqPanel.java | 2 +-
src/jalview/io/SequenceAnnotationReport.java | 181 +++++++++++++++++++-------
5 files changed, 141 insertions(+), 55 deletions(-)
diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java
index 748954a..7fc88bc 100644
--- a/src/jalview/appletgui/APopupMenu.java
+++ b/src/jalview/appletgui/APopupMenu.java
@@ -537,6 +537,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
MenuItem item = new MenuItem(label);
item.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
ap.alignFrame.showURL(url, target);
@@ -545,6 +546,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
linkMenu.add(item);
}
+ @Override
public void itemStateChanged(ItemEvent evt)
{
if (evt.getSource() == abovePIDColour)
@@ -569,6 +571,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
}
}
+ @Override
public void actionPerformed(ActionEvent evt)
{
Object source = evt.getSource();
@@ -850,7 +853,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);
- StringBuffer contents = new StringBuffer();
+ StringBuilder contents = new StringBuilder(128);
for (SequenceI seq : sequences)
{
contents.append(MessageManager.formatMessage(
@@ -861,7 +864,6 @@ public class APopupMenu extends java.awt.PopupMenu implements
seq,
true,
true,
- false,
(ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr
.getMinMax() : null);
contents.append("
");
diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java
index bbffbab..c3ede0b 100755
--- a/src/jalview/gui/IdPanel.java
+++ b/src/jalview/gui/IdPanel.java
@@ -108,8 +108,8 @@ public class IdPanel extends JPanel implements MouseListener,
if (seq > -1 && seq < av.getAlignment().getHeight())
{
SequenceI sequence = av.getAlignment().getSequenceAt(seq);
- StringBuffer tip = new StringBuffer(64);
- seqAnnotReport.createSequenceAnnotationReport(tip, sequence,
+ StringBuilder tip = new StringBuilder(64);
+ seqAnnotReport.createTooltipAnnotationReport(tip, sequence,
av.isShowDBRefs(), av.isShowNPFeats(),
sp.seqCanvas.fr.getMinMax());
setToolTipText(JvSwingUtils.wrapTooltip(true,
diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java
index ab8c398..008de18 100644
--- a/src/jalview/gui/PopupMenu.java
+++ b/src/jalview/gui/PopupMenu.java
@@ -1738,7 +1738,7 @@ public class PopupMenu extends JPopupMenu
public void createSequenceDetailsReport(SequenceI[] sequences)
{
CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
- StringBuffer contents = new StringBuffer();
+ StringBuilder contents = new StringBuilder(128);
for (SequenceI seq : sequences)
{
contents.append(""
@@ -1753,7 +1753,6 @@ public class PopupMenu extends JPopupMenu
seq,
true,
true,
- false,
(ap.getSeqPanel().seqCanvas.fr != null) ? ap
.getSeqPanel().seqCanvas.fr.getMinMax()
: null);
diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java
index cce2ee0..e94e94f 100644
--- a/src/jalview/gui/SeqPanel.java
+++ b/src/jalview/gui/SeqPanel.java
@@ -121,7 +121,7 @@ public class SeqPanel extends JPanel implements MouseListener,
private final SequenceAnnotationReport seqARep;
- StringBuffer tooltipText = new StringBuffer();
+ StringBuilder tooltipText = new StringBuilder();
String tmpString;
diff --git a/src/jalview/io/SequenceAnnotationReport.java b/src/jalview/io/SequenceAnnotationReport.java
index d3a1d09..96d71f6 100644
--- a/src/jalview/io/SequenceAnnotationReport.java
+++ b/src/jalview/io/SequenceAnnotationReport.java
@@ -26,6 +26,9 @@ import jalview.datamodel.SequenceI;
import jalview.util.UrlLink;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Hashtable;
import java.util.List;
@@ -38,6 +41,29 @@ public class SequenceAnnotationReport
{
final String linkImageURL;
+ /*
+ * Comparator to order DBRefEntry by Source + accession id (case-insensitive)
+ */
+ private static Comparator comparator = new Comparator()
+ {
+ @Override
+ public int compare(DBRefEntry ref1, DBRefEntry ref2)
+ {
+ String s1 = ref1.getSource();
+ String s2 = ref2.getSource();
+ int comp = s1 == null ? -1 : (s2 == null ? 1 : s1
+ .compareToIgnoreCase(s2));
+ if (comp == 0)
+ {
+ String a1 = ref1.getAccessionId();
+ String a2 = ref2.getAccessionId();
+ comp = a1 == null ? -1 : (a2 == null ? 1 : a1
+ .compareToIgnoreCase(a2));
+ }
+ return comp;
+ }
+ };
+
public SequenceAnnotationReport(String linkImageURL)
{
this.linkImageURL = linkImageURL;
@@ -47,19 +73,14 @@ public class SequenceAnnotationReport
* appends the features at rpos to the given stringbuffer ready for display in
* a tooltip
*
- * @param tooltipText2
+ * @param tooltipText
* @param linkImageURL
* @param rpos
* @param features
+ * @param minmax
* TODO refactor to Jalview 'utilities' somehow.
*/
- public void appendFeatures(final StringBuffer tooltipText2, int rpos,
- List features)
- {
- appendFeatures(tooltipText2, rpos, features, null);
- }
-
- public void appendFeatures(final StringBuffer tooltipText2, int rpos,
+ public void appendFeatures(final StringBuilder tooltipText, int rpos,
List features, Hashtable minmax)
{
String tmpString;
@@ -71,33 +92,33 @@ public class SequenceAnnotationReport
{
if (feature.getBegin() == rpos || feature.getEnd() == rpos)
{
- if (tooltipText2.length() > 6)
+ if (tooltipText.length() > 6)
{
- tooltipText2.append("
");
+ tooltipText.append("
");
}
- tooltipText2.append("disulfide bond " + feature.getBegin()
+ tooltipText.append("disulfide bond " + feature.getBegin()
+ ":" + feature.getEnd());
}
}
else
{
- if (tooltipText2.length() > 6)
+ if (tooltipText.length() > 6)
{
- tooltipText2.append("
");
+ tooltipText.append("
");
}
// TODO: remove this hack to display link only features
boolean linkOnly = feature.getValue("linkonly") != null;
if (!linkOnly)
{
- tooltipText2.append(feature.getType() + " ");
+ tooltipText.append(feature.getType() + " ");
if (rpos != 0)
{
// we are marking a positional feature
- tooltipText2.append(feature.begin);
+ tooltipText.append(feature.begin);
}
if (feature.begin != feature.end)
{
- tooltipText2.append(" " + feature.end);
+ tooltipText.append(" " + feature.end);
}
if (feature.getDescription() != null
@@ -125,7 +146,7 @@ public class SequenceAnnotationReport
if (startTag > -1)
{
- tooltipText2.append("; " + tmpString);
+ tooltipText.append("; " + tmpString);
}
else
{
@@ -137,13 +158,13 @@ public class SequenceAnnotationReport
tmpString = tmpString.replaceAll("<", "<");
tmpString = tmpString.replaceAll(">", ">");
- tooltipText2.append("; ");
- tooltipText2.append(tmpString);
+ tooltipText.append("; ");
+ tooltipText.append(tmpString);
}
else
{
- tooltipText2.append("; " + tmpString);
+ tooltipText.append("; " + tmpString);
}
}
}
@@ -154,7 +175,7 @@ public class SequenceAnnotationReport
.get(feature.getType()));
if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
{
- tooltipText2.append(" Score=" + feature.getScore());
+ tooltipText.append(" Score=" + feature.getScore());
}
}
if (feature.getValue("status") != null)
@@ -162,7 +183,7 @@ public class SequenceAnnotationReport
String status = feature.getValue("status").toString();
if (status.length() > 0)
{
- tooltipText2.append("; (" + feature.getValue("status")
+ tooltipText.append("; (" + feature.getValue("status")
+ ")");
}
}
@@ -172,7 +193,7 @@ public class SequenceAnnotationReport
{
if (linkImageURL != null)
{
- tooltipText2.append(" ");
+ tooltipText.append(" ");
}
else
{
@@ -182,7 +203,7 @@ public class SequenceAnnotationReport
{
for (String[] urllink : createLinksFrom(null, urlstring))
{
- tooltipText2.append("
60)
+ {
+ tip.insert(0, "");
+ }
}
- public void createSequenceAnnotationReport(final StringBuffer tip,
+ public int createSequenceAnnotationReport(final StringBuilder tip,
+ SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
+ Hashtable minmax)
+ {
+ return createSequenceAnnotationReport(tip, sequence, showDbRefs,
+ showNpFeats, minmax, false);
+ }
+
+ /**
+ * Adds an html-formatted sequence annotation report to the provided string
+ * buffer, and returns the longest line length added
+ *
+ * @param sb
+ * @param sequence
+ * @param showDbRefs
+ * if true, include database references
+ * @param showNpFeats
+ * if true, include non-positional sequence features
+ * @param minmax
+ * @param summary
+ * if true, build a shortened summary report (for tooltip)
+ * @return
+ */
+ int createSequenceAnnotationReport(final StringBuilder sb,
SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
- boolean tableWrap, Hashtable minmax)
+ Hashtable minmax, boolean summary)
{
String tmp;
- tip.append("");
+ sb.append("");
int maxWidth = 0;
if (sequence.getDescription() != null)
{
tmp = sequence.getDescription();
- tip.append("
" + tmp);
+ sb.append("
").append(tmp);
maxWidth = Math.max(maxWidth, tmp.length());
}
SequenceI ds = sequence;
@@ -347,14 +397,55 @@ public class SequenceAnnotationReport
ds = ds.getDatasetSequence();
}
DBRefEntry[] dbrefs = ds.getDBRefs();
+ Arrays.sort(dbrefs, comparator);
if (showDbRefs && dbrefs != null)
{
- for (int i = 0; i < dbrefs.length; i++)
+ boolean ellipsis = false;
+ String lastSource = null;
+ int countForSource = 0;
+ for (DBRefEntry ref : dbrefs)
{
- tip.append("
");
- tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
- tip.append(tmp);
- maxWidth = Math.max(maxWidth, tmp.length());
+ String source = ref.getSource();
+ if (source == null)
+ {
+ // shouldn't happen
+ continue;
+ }
+ boolean sourceChanged = !source.equals(lastSource);
+ if (sourceChanged)
+ {
+ countForSource = 0;
+ }
+ lastSource = source;
+ countForSource++;
+ if (countForSource == 1 || !summary)
+ {
+ sb.append("
");
+ }
+ if (countForSource < 3 || !summary)
+ {
+ String accessionId = ref.getAccessionId();
+ int len = accessionId.length() + 1;
+ if (countForSource > 1 && summary)
+ {
+ sb.append(", ").append(accessionId);
+ len++;
+ }
+ else
+ {
+ sb.append(source).append(" ").append(accessionId);
+ len += source.length();
+ }
+ maxWidth = Math.max(maxWidth, len);
+ }
+ if (countForSource == 3 && summary)
+ {
+ sb.append(", ...");
+ ellipsis = true;
+ }
+ }
+ if (ellipsis) {
+ sb.append("
(Output Sequence Details to list all database references)");
}
}
@@ -366,21 +457,15 @@ public class SequenceAnnotationReport
{
if (features[i].begin == 0 && features[i].end == 0)
{
- int sz = -tip.length();
- List tfeat = new ArrayList();
- tfeat.add(features[i]);
- appendFeatures(tip, 0, tfeat, minmax);
- sz += tip.length();
+ int sz = -sb.length();
+ List tfeat = Collections
+ .singletonList(features[i]);
+ appendFeatures(sb, 0, tfeat, minmax);
+ sz += sb.length();
maxWidth = Math.max(maxWidth, sz);
}
}
}
-
- if (tableWrap && maxWidth > 60)
- {
- tip.insert(0, "");
- }
-
+ return maxWidth;
}
}
--
1.7.10.2