Parse HTML links from jalview features file
authoramwaterhouse <Andrew Waterhouse>
Fri, 23 Jun 2006 15:33:56 +0000 (15:33 +0000)
committeramwaterhouse <Andrew Waterhouse>
Fri, 23 Jun 2006 15:33:56 +0000 (15:33 +0000)
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/FeatureRenderer.java
src/jalview/appletgui/FeatureSettings.java
src/jalview/appletgui/Tooltip.java
src/jalview/gui/AlignFrame.java
src/jalview/io/FeaturesFile.java

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