From bceadbb394604c88ac18e2dcf4b33e735377d7ac Mon Sep 17 00:00:00 2001 From: amwaterhouse Date: Fri, 23 Jun 2006 15:33:56 +0000 Subject: [PATCH 1/1] Parse HTML links from jalview features file --- src/jalview/appletgui/AlignFrame.java | 8 +- src/jalview/appletgui/FeatureRenderer.java | 54 +------------- src/jalview/appletgui/FeatureSettings.java | 1 + src/jalview/appletgui/Tooltip.java | 3 +- src/jalview/gui/AlignFrame.java | 3 +- src/jalview/io/FeaturesFile.java | 109 ++++++++++++++++++++++++---- 6 files changed, 108 insertions(+), 70 deletions(-) diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index d7bf91a..a68c797 100755 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -150,11 +150,14 @@ public class AlignFrame extends Frame implements ActionListener, public void parseFeaturesFile(String file, String type) { + Hashtable featureLinks = new Hashtable(); boolean featuresFile = false; try{ featuresFile = new jalview.io.FeaturesFile(file, type).parse(viewport.alignment, alignPanel.seqPanel.seqCanvas. - getFeatureRenderer().featureColours); + getFeatureRenderer().featureColours, + featureLinks, + true); } catch(Exception ex) { @@ -163,6 +166,9 @@ public class AlignFrame extends Frame implements ActionListener, if(featuresFile) { + if(featureLinks.size()>0) + alignPanel.seqPanel.seqCanvas + .getFeatureRenderer().featureLinks = featureLinks; viewport.showSequenceFeatures = true; sequenceFeatures.setState(true); alignPanel.repaint(); diff --git a/src/jalview/appletgui/FeatureRenderer.java b/src/jalview/appletgui/FeatureRenderer.java index aa3f830..0f9f393 100755 --- a/src/jalview/appletgui/FeatureRenderer.java +++ b/src/jalview/appletgui/FeatureRenderer.java @@ -35,6 +35,7 @@ public class FeatureRenderer { AlignViewport av; + Hashtable featureColours = new Hashtable(); // A higher level for grouping features of a // particular type @@ -66,20 +67,11 @@ public class FeatureRenderer public FeatureRenderer(AlignViewport av) { this.av = av; - initColours(); if(!System.getProperty("java.version").startsWith("1.1")) transparencySetter = new TransparencySetter(); } - public void addFeatureLink(String feature, String link) - { - if(featureLinks == null) - featureLinks = new Hashtable(); - - featureLinks.put(feature, link); - } - public void transferSettings(FeatureRenderer fr) { @@ -402,50 +394,6 @@ public class FeatureRenderer renderOrder[data.length - i - 1] = type; } } - - Hashtable featureColours = new Hashtable(); - void initColours() - { - featureColours.put("active site", new Color(255, 75, 0)); - featureColours.put("binding site", new Color(245, 85, 0)); - featureColours.put("calcium-binding region", new Color(235, 95, 0)); - featureColours.put("chain", new Color(225, 105, 0)); - featureColours.put("coiled-coil region", new Color(215, 115, 0)); - featureColours.put("compositionally biased region", new Color(205, 125, 0)); - featureColours.put("cross-link", new Color(195, 135, 0)); - featureColours.put("disulfide bond", new Color(185, 145, 0)); - featureColours.put("DNA-binding region", new Color(175, 155, 0)); - featureColours.put("domain", new Color(165, 165, 0)); - featureColours.put("glycosylation site", new Color(155, 175, 0)); - featureColours.put("helix", new Color(145, 185, 0)); - featureColours.put("initiator methionine", new Color(135, 195, 5)); - featureColours.put("lipid moiety-binding region", new Color(125, 205, 15)); - featureColours.put("metal ion-binding site", new Color(115, 215, 25)); - featureColours.put("modified residue", new Color(105, 225, 35)); - featureColours.put("mutagenesis site", new Color(95, 235, 45)); - featureColours.put("non-consecutive residues", new Color(85, 245, 55)); - featureColours.put("non-terminal residue", new Color(75, 255, 65)); - featureColours.put("nucleotide phosphate-binding region", - new Color(65, 245, 75)); - featureColours.put("peptide", new Color(55, 235, 85)); - featureColours.put("propeptide", new Color(45, 225, 95)); - featureColours.put("region of interest", new Color(35, 215, 105)); - featureColours.put("repeat", new Color(25, 205, 115)); - featureColours.put("selenocysteine", new Color(15, 195, 125)); - featureColours.put("sequence conflict", new Color(5, 185, 135)); - featureColours.put("sequence variant", new Color(0, 175, 145)); - featureColours.put("short sequence motif", new Color(0, 165, 155)); - featureColours.put("signal peptide", new Color(0, 155, 165)); - featureColours.put("site", new Color(0, 145, 175)); - featureColours.put("splice variant", new Color(0, 135, 185)); - featureColours.put("strand", new Color(0, 125, 195)); - featureColours.put("topological domain", new Color(0, 115, 205)); - featureColours.put("transit peptide", new Color(0, 105, 215)); - featureColours.put("transmembrane region", new Color(0, 95, 225)); - featureColours.put("turn", new Color(0, 85, 235)); - featureColours.put("unsure residue", new Color(0, 75, 245)); - featureColours.put("zinc finger region", new Color(0, 65, 255)); - } } class TransparencySetter diff --git a/src/jalview/appletgui/FeatureSettings.java b/src/jalview/appletgui/FeatureSettings.java index f2f0943..a733e24 100755 --- a/src/jalview/appletgui/FeatureSettings.java +++ b/src/jalview/appletgui/FeatureSettings.java @@ -490,6 +490,7 @@ public class FeatureSettings extends Panel implements ItemListener, public MyCheckbox(String label, boolean checked, boolean haslink) { super(label, checked); + FontMetrics fm = av.nullFrame.getFontMetrics(av.nullFrame.getFont()); stringWidth = fm.stringWidth(label); this.hasLink = haslink; diff --git a/src/jalview/appletgui/Tooltip.java b/src/jalview/appletgui/Tooltip.java index 065544c1..b25abd5 100755 --- a/src/jalview/appletgui/Tooltip.java +++ b/src/jalview/appletgui/Tooltip.java @@ -59,8 +59,7 @@ public class Tooltip extends Canvas implements MouseListener, g.drawString(tip[i].substring(0, lindex), 3, (i+1)*fontHeight-3); x+=fm.stringWidth(tip[i].substring(0, lindex)+3); } - // g.drawString("(right click)", linkImage.getWidth(this)+6, (i+1)*fontHeight-3); - g.drawImage(linkImage, x, i * fontHeight, this); + g.drawImage(linkImage, x, i * fontHeight+1, this); } else g.drawString(tip[i], 3, (i+1)*fontHeight - 3); diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index b0b2b85..c058f09 100755 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -2701,7 +2701,8 @@ public boolean parseFeaturesFile(String file, String type) try{ featuresFile = new FeaturesFile(file, type).parse(viewport.alignment.getDataset(), alignPanel.seqPanel.seqCanvas. - getFeatureRenderer().featureColours); + getFeatureRenderer().featureColours, + false); } catch(Exception ex) { diff --git a/src/jalview/io/FeaturesFile.java b/src/jalview/io/FeaturesFile.java index a83dff8..9431011 100755 --- a/src/jalview/io/FeaturesFile.java +++ b/src/jalview/io/FeaturesFile.java @@ -65,12 +65,29 @@ public class FeaturesFile extends AlignFile } /** - * DOCUMENT ME! + * The Application can render HTML, but the applet will + * remove HTML tags and replace links with %LINK% + * Both need to read links in HTML however + * + * @throws IOException DOCUMENT ME! + */ + public boolean parse(AlignmentI align, + Hashtable colours, + boolean removeHTML) + { + return parse(align, colours, null, removeHTML); + } + /** + * The Application can render HTML, but the applet will + * remove HTML tags and replace links with %LINK% + * Both need to read links in HTML however * * @throws IOException DOCUMENT ME! */ - public boolean parse(AlignmentI align, Hashtable colours) - throws IOException + public boolean parse(AlignmentI align, + Hashtable colours, + Hashtable featureLink, + boolean removeHTML) { String line = null; try @@ -82,7 +99,8 @@ public class FeaturesFile extends AlignFile float score; StringTokenizer st; SequenceFeature sf; - String featureGroup = null; + String featureGroup = null, groupLink = null; + Hashtable typeLink = new Hashtable(); boolean GFFFile = true; @@ -99,6 +117,11 @@ public class FeaturesFile extends AlignFile if (type.equalsIgnoreCase("startgroup")) { featureGroup = st.nextToken(); + if (st.hasMoreElements()) + { + groupLink = st.nextToken(); + featureLink.put(featureGroup, groupLink); + } } else if (type.equalsIgnoreCase("endgroup")) { @@ -106,11 +129,21 @@ public class FeaturesFile extends AlignFile //but at present theres no way of showing more than 1 group st.nextToken(); featureGroup = null; + groupLink = null; } else { UserColourScheme ucs = new UserColourScheme(st.nextToken()); colours.put(type, ucs.findColour("A")); + if (st.hasMoreElements()) + { + String link = st.nextToken(); + typeLink.put(type, link); + if(featureLink==null) + featureLink = new Hashtable(); + featureLink.put(type, link); + } + } continue; } @@ -201,7 +234,20 @@ public class FeaturesFile extends AlignFile sf = new SequenceFeature(type, desc, "", start, end, featureGroup); - seq.getDatasetSequence().addSequenceFeature(sf); + seq.addSequenceFeature(sf); + + if(groupLink!=null && removeHTML) + { + sf.addLink(groupLink); + sf.description += "%LINK%"; + } + if(typeLink.containsKey(type) && removeHTML) + { + sf.addLink(typeLink.get(type).toString()); + sf.description += "%LINK%"; + } + + parseDescriptionHTML(sf, removeHTML); //If we got here, its not a GFFFile GFFFile = false; @@ -212,14 +258,40 @@ public class FeaturesFile extends AlignFile { System.out.println(line); ex.printStackTrace(); - System.out.println("Error parsing groups file: " + ex +"\n"+line); + System.out.println("Error parsing feature file: " + ex +"\n"+line); return false; } return true; - } + void parseDescriptionHTML(SequenceFeature sf, boolean removeHTML) + { + StringBuffer sb = new StringBuffer(); + StringTokenizer st = new StringTokenizer(sf.getDescription(), "<"); + String token, link; + while(st.hasMoreElements()) + { + token = st.nextToken("<>"); + if(token.equalsIgnoreCase("html") || token.startsWith("/")) + continue; + + if(token.startsWith("a href=")) + { + link = token.substring(token.indexOf("\"")+1, token.length()-1); + String label = st.nextToken("<>"); + sf.addLink(label+"|"+link); + sb.append(label+"%LINK%"); + } + else if(token.equalsIgnoreCase("br")) + sb.append("\n"); + else + sb.append(token); + } + + if(removeHTML) + sf.description = sb.toString(); + } /** * DOCUMENT ME! @@ -278,12 +350,15 @@ public class FeaturesFile extends AlignFile do { - if (groups.size() > 0) + + + if (groups.size() > 0 && groupIndex < groups.size()) { group = groups.elementAt(groupIndex).toString(); out.append("\nSTARTGROUP\t" + group + "\n"); } - + else + group = null; for (int i = 0; i < seqs.length; i++) { @@ -295,7 +370,13 @@ public class FeaturesFile extends AlignFile if (!visible.containsKey(next[j].type)) continue; - if (group != null && !next[j].featureGroup.equals(group)) + if (group != null + && (next[j].featureGroup==null + || !next[j].featureGroup.equals(group)) + ) + continue; + + if(group==null && next[j].featureGroup!=null) continue; if(next[j].description==null || next[j].description.equals("")) @@ -312,14 +393,16 @@ public class FeaturesFile extends AlignFile } } - if(groups.size()>0) + if(group!=null) { out.append("ENDGROUP\t"+group+"\n"); + groupIndex++; } + else + break; - groupIndex++; } - while(groupIndex < groups.size()); + while(groupIndex < groups.size()+1); return out.toString(); -- 1.7.10.2