JAL-3010 offer 'apply to all {parent SO term} features' where applicable
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 19 Apr 2019 16:45:56 +0000 (17:45 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 19 Apr 2019 16:45:56 +0000 (17:45 +0100)
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/jalview/gui/FeatureTypeSettings.java

index 384737d..46bd9c1 100644 (file)
@@ -1339,7 +1339,7 @@ label.cached_structures = Cached Structures
 label.free_text_search = Free Text Search
 label.summary_view = Summary View
 label.summary_view_tip = Show only top level ontology terms
-label.apply_to_subtypes = Apply changes also to sub-types of ''{0}''
+label.apply_to_subtypes = Apply changes to all ''{0}'' features
 label.apply_also_to = Apply also to:
 label.backupfiles_confirm_delete = Confirm delete
 label.backupfiles_confirm_delete_old_files = Delete the following older backup files? (see the Backups tab in Preferences for more options)
index 0722293..9bed798 100644 (file)
@@ -1340,7 +1340,7 @@ label.cached_structures = Estructuras en Cach
 label.free_text_search = Búsqueda de texto libre
 label.summary_view = Vista Resumida
 label.summary_view_tip = Mostrar solo términos de ontología de nivel mayor
-label.apply_to_subtypes = Aplicar cambios también a subtipos de ''{0}''
+label.apply_to_subtypes = Aplicar cambios también a todas características de tipo ''{0}''
 label.apply_also_to = Aplicar también a:
 label.backupfiles_confirm_delete = Confirmar borrar
 label.backupfiles_confirm_delete_old_files = ¿Borrar los siguientes archivos? (ver la pestaña 'Copias' de la ventana de Preferencias para más opciones)
index 0b8b2b2..538c93c 100644 (file)
@@ -22,6 +22,7 @@ package jalview.gui;
 
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureColourI;
+import jalview.bin.Cache;
 import jalview.datamodel.GraphLine;
 import jalview.datamodel.features.FeatureAttributes;
 import jalview.datamodel.features.FeatureAttributes.Datatype;
@@ -30,6 +31,7 @@ import jalview.datamodel.features.FeatureMatcherI;
 import jalview.datamodel.features.FeatureMatcherSet;
 import jalview.datamodel.features.FeatureMatcherSetI;
 import jalview.io.gff.SequenceOntologyFactory;
+import jalview.io.gff.SequenceOntologyI;
 import jalview.schemes.FeatureColour;
 import jalview.util.ColorUtils;
 import jalview.util.MessageManager;
@@ -83,6 +85,11 @@ import javax.swing.plaf.basic.BasicArrowButton;
  */
 public class FeatureTypeSettings extends JalviewDialog
 {
+  /*
+   * 'top level' Sequence Ontology terms
+   */
+  private final static String SO_ROOTS = "sequence_variant,sequence_attribute,sequence_collection,sequence_feature";
+
   private final static String LABEL_18N = MessageManager
           .getString("label.label");
 
@@ -213,14 +220,20 @@ public class FeatureTypeSettings extends JalviewDialog
   private JPanel chooseFiltersPanel;
 
   /*
-   * feature types present in Feature Renderer which are
-   * sub-types of the one this editor is acting on
+   * the root Sequence Ontology terms (if any) that is a parent of
+   * the current feature type
+   */
+  private String rootSOTerm;
+
+  /*
+   * feature types present in Feature Renderer which have the same Sequence
+   * Ontology root parent as the one this editor is acting on
    */
-  private final List<String> subTypes;
+  private final List<String> peerSoTerms;
 
   /*
    * if true, filter or colour settings are also applied to 
-   * any feature sub-types in the Sequence Ontology
+   * any sub-types of rootSOTerm in the Sequence Ontology
    */
   private boolean applyFiltersToSubtypes;
 
@@ -238,13 +251,7 @@ public class FeatureTypeSettings extends JalviewDialog
     this.featureType = theType;
     ap = fr.ap;
 
-    /*
-     * determine sub-types (if any) of this feature type
-     */
-    List<String> types = fr.getRenderOrder();
-    subTypes = SequenceOntologyFactory.getInstance()
-            .getChildTerms(this.featureType, types);
-    Collections.sort(subTypes); // sort for ease of reading in tooltip
+    peerSoTerms = findSequenceOntologyPeers(this.featureType);
 
     /*
      * save original colours and filters for this feature type
@@ -254,14 +261,14 @@ public class FeatureTypeSettings extends JalviewDialog
     originalFilters.put(theType, fr.getFeatureFilter(theType));
     originalColours = new HashMap<>();
     originalColours.put(theType, fr.getFeatureColours().get(theType));
-    for (String child : subTypes)
+    for (String child : peerSoTerms)
     {
       originalFilters.put(child, fr.getFeatureFilter(child));
       originalColours.put(child, fr.getFeatureColours().get(child));
     }
 
     adjusting = true;
-    
+
     try
     {
       initialise();
@@ -270,15 +277,15 @@ public class FeatureTypeSettings extends JalviewDialog
       ex.printStackTrace();
       return;
     }
-    
+
     updateColoursTab();
-    
+
     updateFiltersTab();
-    
+
     adjusting = false;
-    
+
     colourChanged(false);
-    
+
     String title = MessageManager
             .formatMessage("label.display_settings_for", new String[]
             { theType });
@@ -287,6 +294,53 @@ public class FeatureTypeSettings extends JalviewDialog
   }
 
   /**
+   * Answers a (possibly empty) list of feature types known to the Feature
+   * Renderer which share a top level Sequence Ontology parent with the current
+   * feature type. The current type is not included.
+   * 
+   * @return
+   */
+  protected List<String> findSequenceOntologyPeers(String featureType)
+  {
+    List<String> peers = new ArrayList<>();
+
+    /*
+     * first find the SO term (if any) that is the root
+     * parent of the current type
+     */
+    SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+    String[] roots = Cache.getDefault("SO_ROOTS", SO_ROOTS).split(",");
+    rootSOTerm = null;
+    for (String root : roots)
+    {
+      if (so.isA(featureType, root.trim()))
+      {
+        rootSOTerm = root;
+        break;
+      }
+    }
+    if (rootSOTerm == null)
+    {
+      /*
+       * feature type is not an SO term
+       */
+      return peers;
+    }
+
+    List<String> types = fr.getRenderOrder();
+    for (String type : types)
+    {
+      if (!type.equals(featureType) && so.isA(type, rootSOTerm))
+      {
+        peers.add(type);
+      }
+
+    }
+    Collections.sort(peers); // sort for ease of reading in tooltip
+    return peers;
+  }
+
+  /**
    * Configures the widgets on the Colours tab according to the current feature
    * colour scheme
    */
@@ -771,9 +825,9 @@ public class FeatureTypeSettings extends JalviewDialog
             MessageManager.getString("action.colour"), true);
 
     /*
-     * option to apply colour to sub-types as well (if there are any)
+     * option to apply colour to peer types as well (if there are any)
      */
-    if (!subTypes.isEmpty())
+    if (!peerSoTerms.isEmpty())
     {
       applyColourToSubtypes = false;
       colourByPanel.add(initSubtypesPanel(false));
@@ -888,7 +942,7 @@ public class FeatureTypeSettings extends JalviewDialog
     JPanel toSubtypes = new JPanel(new FlowLayout(FlowLayout.LEFT));
     toSubtypes.setBackground(Color.WHITE);
     JCheckBox applyToSubtypesCB = new JCheckBox(MessageManager
-            .formatMessage("label.apply_to_subtypes", featureType));
+            .formatMessage("label.apply_to_subtypes", rootSOTerm));
     applyToSubtypesCB.setToolTipText(getSubtypesTooltip());
     applyToSubtypesCB.addActionListener(new ActionListener()
     {
@@ -961,7 +1015,7 @@ public class FeatureTypeSettings extends JalviewDialog
     fr.setColour(featureType, acg);
     if (applyColourToSubtypes)
     {
-      for (String child : subTypes)
+      for (String child : peerSoTerms)
       {
         fr.setColour(child, acg);
       }
@@ -1145,7 +1199,7 @@ public class FeatureTypeSettings extends JalviewDialog
        */
       adjusting = true;
       float f = Float.parseFloat(thresholdValue.getText());
-      f = Float.max(f,  this.min);
+      f = Float.max(f, this.min);
       f = Float.min(f, this.max);
       thresholdValue.setText(String.valueOf(f));
       slider.setValue((int) (f * scaleFactor));
@@ -1277,9 +1331,9 @@ public class FeatureTypeSettings extends JalviewDialog
     outerPanel.setBackground(Color.white);
 
     /*
-     * option to apply colour to sub-types as well (if there are any)
+     * option to apply colour to peer types as well (if there are any)
      */
-    if (!subTypes.isEmpty())
+    if (!peerSoTerms.isEmpty())
     {
       applyFiltersToSubtypes = false;
       outerPanel.add(initSubtypesPanel(true));
@@ -1316,10 +1370,6 @@ public class FeatureTypeSettings extends JalviewDialog
     JPanel andOrPanel = new JPanel(new BorderLayout());
     andOrPanel.setBackground(Color.white);
 
-//    JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
-//    andOrPanel.add(panel1, BorderLayout.WEST);
-//    panel1.setBackground(Color.white);
-//    panel1.setBorder(BorderFactory.createLineBorder(debugBorderColour));
     andFilters = new JRadioButton(MessageManager.getString("label.and"));
     orFilters = new JRadioButton(MessageManager.getString("label.or"));
     ActionListener actionListener = new ActionListener()
@@ -1352,9 +1402,9 @@ public class FeatureTypeSettings extends JalviewDialog
    */
   protected String getSubtypesTooltip()
   {
-    StringBuilder sb = new StringBuilder(20 * subTypes.size());
+    StringBuilder sb = new StringBuilder(20 * peerSoTerms.size());
     sb.append(MessageManager.getString("label.apply_also_to"));
-    for (String child : subTypes)
+    for (String child : peerSoTerms)
     {
       sb.append("<br>").append(child);
     }
@@ -1898,7 +1948,7 @@ public class FeatureTypeSettings extends JalviewDialog
     fr.setFeatureFilter(featureType, combined.isEmpty() ? null : combined);
     if (applyFiltersToSubtypes)
     {
-      for (String child : subTypes)
+      for (String child : peerSoTerms)
       {
         fr.setFeatureFilter(child, combined.isEmpty() ? null : combined);
       }