JAL-2744 simple Feature Details report from Popup menu
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 28 Sep 2017 08:52:45 +0000 (09:52 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 28 Sep 2017 08:52:45 +0000 (09:52 +0100)
resources/lang/Messages.properties
src/jalview/datamodel/SequenceFeature.java
src/jalview/gui/PopupMenu.java

index 7295104..5620386 100644 (file)
@@ -1321,3 +1321,4 @@ label.select_hidden_colour = Select hidden colour
 label.overview = Overview
 label.reset_to_defaults = Reset to defaults
 label.oview_calc = Recalculating overview...
+label.feature_details = Feature details
\ No newline at end of file
index 9c4087e..6834341 100755 (executable)
@@ -25,6 +25,7 @@ import jalview.datamodel.features.FeatureLocationI;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.TreeMap;
 import java.util.Vector;
 
 /**
@@ -52,6 +53,16 @@ public class SequenceFeature implements FeatureLocationI
   private static final String LOCATION = "!Location";
 
   /*
+   * map of otherDetails special keys, and their value fields' delimiter
+   */
+  private static final Map<String, String> INFO_KEYS = new HashMap<>();
+
+  static
+  {
+    INFO_KEYS.put("CSQ", ",");
+  }
+
+  /*
    * ATTRIBUTES is reserved for the GFF 'column 9' data, formatted as
    * name1=value1;name2=value2,value3;...etc
    */
@@ -535,4 +546,58 @@ public class SequenceFeature implements FeatureLocationI
   {
     return begin == 0 && end == 0;
   }
+
+  /**
+   * Answers a formatted text report of feature details
+   * 
+   * @return
+   */
+  public String getDetailsReport()
+  {
+    StringBuilder sb = new StringBuilder(128);
+    if (begin == end)
+    {
+      sb.append(String.format("%s %d %s", type, begin, description));
+    }
+    else
+    {
+      sb.append(String.format("%s %d-%d %s", type, begin, end, description));
+    }
+    if (featureGroup != null)
+    {
+      sb.append(" (").append(featureGroup).append(")");
+    }
+    sb.append("\n\n");
+
+    if (otherDetails != null)
+    {
+      TreeMap<String, Object> ordered = new TreeMap<>(
+              String.CASE_INSENSITIVE_ORDER);
+      ordered.putAll(otherDetails);
+
+      for (Entry<String, Object> entry : ordered.entrySet())
+      {
+        String key = entry.getKey();
+        if (ATTRIBUTES.equals(key))
+        {
+          continue; // to avoid double reporting
+        }
+        if (INFO_KEYS.containsKey(key))
+        {
+          /*
+           * split selected INFO data by delimiter over multiple lines
+           */
+          sb.append(key).append("\n");
+          String delimiter = INFO_KEYS.get(key);
+          sb.append(entry.getValue().toString().replace(delimiter, "\n"));
+        }
+        else
+        {
+          sb.append(key + "=" + entry.getValue().toString() + "\n");
+        }
+      }
+    }
+    String text = sb.toString();
+    return text;
+  }
 }
index 21db7d7..b574ddd 100644 (file)
@@ -514,6 +514,69 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
     }
 
     addLinks(seq, features);
+
+    if (seq == null)
+    {
+      addFeatureDetails(features);
+    }
+  }
+
+  /**
+   * Add a link to show feature details for each sequence feature
+   * 
+   * @param features
+   */
+  protected void addFeatureDetails(List<SequenceFeature> features)
+  {
+    if (features.isEmpty())
+    {
+      return;
+    }
+    JMenu details = new JMenu(
+            MessageManager.getString("label.feature_details"));
+    add(details);
+
+    for (final SequenceFeature sf : features)
+    {
+      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);
+      }
+      if (sf.getFeatureGroup() != null)
+      {
+        desc = desc + " (" + sf.getFeatureGroup() + ")";
+      }
+      JMenuItem item = new JMenuItem(desc);
+      item.addActionListener(new ActionListener()
+      {
+        @Override
+        public void actionPerformed(ActionEvent e)
+        {
+          showFeatureDetails(sf);
+        }
+      });
+      details.add(item);
+    }
+  }
+
+  /**
+   * Opens a panel showing a text report of feature dteails
+   * 
+   * @param sf
+   */
+  protected void showFeatureDetails(SequenceFeature sf)
+  {
+    CutAndPasteTransfer cap = new CutAndPasteTransfer();
+    cap.setText(sf.getDetailsReport());
+    Desktop.addInternalFrame(cap,
+            MessageManager.getString("label.feature_details"), 500, 500);
   }
 
   /**