JAL-2843 save/restore colour feature by attribute, and feature filters, to Jalview...
[jalview.git] / src / jalview / gui / FeatureSettings.java
index 811b377..6182885 100644 (file)
@@ -22,29 +22,20 @@ package jalview.gui;
 
 import jalview.api.FeatureColourI;
 import jalview.api.FeatureSettingsControllerI;
-import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
-import jalview.datamodel.features.FeatureMatcher;
 import jalview.datamodel.features.FeatureMatcherI;
 import jalview.datamodel.features.FeatureMatcherSet;
 import jalview.datamodel.features.FeatureMatcherSetI;
 import jalview.gui.Help.HelpId;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
-import jalview.schemabinding.version2.CompoundMatcher;
 import jalview.schemabinding.version2.Filter;
 import jalview.schemabinding.version2.JalviewUserColours;
-import jalview.schemabinding.version2.MatchCondition;
 import jalview.schemabinding.version2.MatcherSet;
-import jalview.schemabinding.version2.types.ColourNoValueColourType;
-import jalview.schemabinding.version2.types.ColourThreshTypeType;
-import jalview.schemabinding.version2.types.FeatureMatcherByType;
 import jalview.schemes.FeatureColour;
-import jalview.util.Format;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
-import jalview.util.matcher.Condition;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean;
 import jalview.ws.DasSequenceFeatureFetcher;
@@ -75,7 +66,6 @@ import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -189,290 +179,6 @@ public class FeatureSettings extends JPanel
   Map<String, float[]> typeWidth = null;
 
   /**
-   * Populates an XML model of the feature colour scheme for one feature type
-   * 
-   * @param featureType
-   * @param fcol
-   * @return
-   */
-  protected static jalview.schemabinding.version2.Colour marshalColour(
-          String featureType, FeatureColourI fcol)
-  {
-    jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
-    if (fcol.isSimpleColour())
-    {
-      col.setRGB(Format.getHexString(fcol.getColour()));
-    }
-    else
-    {
-      col.setRGB(Format.getHexString(fcol.getMaxColour()));
-      col.setMin(fcol.getMin());
-      col.setMax(fcol.getMax());
-      col.setMinRGB(jalview.util.Format.getHexString(fcol.getMinColour()));
-      col.setAutoScale(fcol.isAutoScaled());
-      col.setThreshold(fcol.getThreshold());
-      col.setColourByLabel(fcol.isColourByLabel());
-      col.setThreshType(fcol.isAboveThreshold() ? ColourThreshTypeType.ABOVE
-              : (fcol.isBelowThreshold() ? ColourThreshTypeType.BELOW
-                      : ColourThreshTypeType.NONE));
-      if (fcol.isColourByAttribute())
-      {
-        col.setAttributeName(fcol.getAttributeName());
-      }
-      Color noColour = fcol.getNoColour();
-      if (noColour == null)
-      {
-        col.setNoValueColour(ColourNoValueColourType.NONE);
-      }
-      else if (noColour == fcol.getMaxColour())
-      {
-        col.setNoValueColour(ColourNoValueColourType.MAX);
-      }
-      else
-      {
-        col.setNoValueColour(ColourNoValueColourType.MIN);
-      }
-    }
-    col.setName(featureType);
-    return col;
-  }
-
-  /**
-   * Populates an XML model of the feature filter(s) for one feature type
-   * 
-   * @param firstMatcher
-   *          the first (or only) match condition)
-   * @param filter
-   *          remaining match conditions (if any)
-   * @param and
-   *          if true, conditions are and-ed, else or-ed
-   */
-  protected static MatcherSet marshalFilter(FeatureMatcherI firstMatcher,
-          Iterator<FeatureMatcherI> filters, boolean and)
-  {
-    MatcherSet result = new MatcherSet();
-
-    if (filters.hasNext())
-    {
-      /*
-       * compound matcher
-       */
-      CompoundMatcher compound = new CompoundMatcher();
-      compound.setAnd(and);
-      MatcherSet matcher1 = marshalFilter(firstMatcher,
-              Collections.emptyIterator(), and);
-      compound.addMatcherSet(matcher1);
-      FeatureMatcherI nextMatcher = filters.next();
-      MatcherSet matcher2 = marshalFilter(nextMatcher, filters, and);
-      compound.addMatcherSet(matcher2);
-      result.setCompoundMatcher(compound);
-    }
-    else
-    {
-      /*
-       * single condition matcher
-       */
-      MatchCondition matcherModel = new MatchCondition();
-      matcherModel.setCondition(
-              firstMatcher.getMatcher().getCondition().getStableName());
-      matcherModel.setValue(firstMatcher.getMatcher().getPattern());
-      if (firstMatcher.isByAttribute())
-      {
-        matcherModel.setBy(FeatureMatcherByType.BYATTRIBUTE);
-        matcherModel.setAttributeName(firstMatcher.getAttribute());
-      }
-      else if (firstMatcher.isByLabel())
-      {
-        matcherModel.setBy(FeatureMatcherByType.BYLABEL);
-      }
-      else if (firstMatcher.isByScore())
-      {
-        matcherModel.setBy(FeatureMatcherByType.BYSCORE);
-      }
-      result.setMatchCondition(matcherModel);
-    }
-
-    return result;
-  }
-
-  /**
-   * Loads one XML model of a feature filter to a Jalview object
-   * 
-   * @param colourModel
-   * @return
-   */
-  protected static FeatureMatcherSetI unmarshalFilter(Filter filterModel)
-  {
-    FeatureMatcherSetI result = new FeatureMatcherSet();
-    MatcherSet matcherSetModel = filterModel.getMatcherSet();
-    try
-    {
-      unmarshalFilterConditions(result, matcherSetModel, true);
-    } catch (IllegalStateException e)
-    {
-      // mixing AND and OR conditions perhaps
-      System.err.println(
-              String.format("Error reading filter conditions for '%s': %s",
-                      filterModel.getFeatureType(), e.getMessage()));
-      // return as much as was parsed up to the error
-    }
-
-    return result;
-  }
-
-  /**
-   * Adds feature match conditions to matcherSet as unmarshalled from XML
-   * (possibly recursively for compound conditions)
-   * 
-   * @param matcherSet
-   * @param matcherSetModel
-   * @param and
-   *          if true, multiple conditions are AND-ed, else they are OR-ed
-   * @throws IllegalStateException
-   *           if AND and OR conditions are mixed
-   */
-  protected static void unmarshalFilterConditions(
-          FeatureMatcherSetI matcherSet, MatcherSet matcherSetModel,
-          boolean and)
-  {
-    MatchCondition mc = matcherSetModel.getMatchCondition();
-    if (mc != null)
-    {
-      /*
-       * single condition
-       */
-      FeatureMatcherByType filterBy = mc.getBy();
-      Condition cond = Condition.fromString(mc.getCondition());
-      String pattern = mc.getValue();
-      FeatureMatcherI matchCondition = null;
-      if (filterBy == FeatureMatcherByType.BYLABEL)
-      {
-        matchCondition = FeatureMatcher.byLabel(cond, pattern);
-      }
-      else if (filterBy == FeatureMatcherByType.BYSCORE)
-      {
-        matchCondition = FeatureMatcher.byScore(cond, pattern);
-
-      }
-      else if (filterBy == FeatureMatcherByType.BYATTRIBUTE)
-      {
-        String[] attNames = mc.getAttributeName();
-        matchCondition = FeatureMatcher.byAttribute(cond, pattern,
-                attNames);
-      }
-
-      /*
-       * note this throws IllegalStateException if AND-ing to a 
-       * previously OR-ed compound condition, or vice versa
-       */
-      if (and)
-      {
-        matcherSet.and(matchCondition);
-      }
-      else
-      {
-        matcherSet.or(matchCondition);
-      }
-    }
-    else
-    {
-      /*
-       * compound condition
-       */
-      MatcherSet[] matchers = matcherSetModel.getCompoundMatcher()
-              .getMatcherSet();
-      boolean anded = matcherSetModel.getCompoundMatcher().getAnd();
-      if (matchers.length == 2)
-      {
-        unmarshalFilterConditions(matcherSet, matchers[0], anded);
-        unmarshalFilterConditions(matcherSet, matchers[1], anded);
-      }
-      else
-      {
-        System.err.println("Malformed compound filter condition");
-      }
-    }
-  }
-
-  /**
-   * Loads one XML model of a feature colour to a Jalview object
-   * 
-   * @param colourModel
-   * @return
-   */
-  protected static FeatureColourI unmarshalColour(
-          jalview.schemabinding.version2.Colour colourModel)
-  {
-    FeatureColourI colour = null;
-
-    if (colourModel.hasMax())
-    {
-      Color mincol = null;
-      Color maxcol = null;
-      Color noValueColour = null;
-
-      try
-      {
-        mincol = new Color(Integer.parseInt(colourModel.getMinRGB(), 16));
-        maxcol = new Color(Integer.parseInt(colourModel.getRGB(), 16));
-      } catch (Exception e)
-      {
-        Cache.log.warn("Couldn't parse out graduated feature color.", e);
-      }
-
-      ColourNoValueColourType noCol = colourModel.getNoValueColour();
-      if (noCol == ColourNoValueColourType.MIN)
-      {
-        noValueColour = mincol;
-      }
-      else if (noCol == ColourNoValueColourType.MAX)
-      {
-        noValueColour = maxcol;
-      }
-
-      colour = new FeatureColour(mincol, maxcol, noValueColour,
-              colourModel.getMin(),
-              colourModel.getMax());
-      String[] attributes = colourModel.getAttributeName();
-      if (attributes != null && attributes.length > 0)
-      {
-        colour.setAttributeName(attributes);
-      }
-      if (colourModel.hasAutoScale())
-      {
-        colour.setAutoScaled(colourModel.getAutoScale());
-      }
-      if (colourModel.hasColourByLabel())
-      {
-        colour.setColourByLabel(colourModel.getColourByLabel());
-      }
-      if (colourModel.hasThreshold())
-      {
-        colour.setThreshold(colourModel.getThreshold());
-      }
-      ColourThreshTypeType ttyp = colourModel.getThreshType();
-      if (ttyp != null)
-      {
-        if (ttyp == ColourThreshTypeType.ABOVE)
-        {
-          colour.setAboveThreshold(true);
-        }
-        else if (ttyp == ColourThreshTypeType.BELOW)
-        {
-          colour.setBelowThreshold(true);
-        }
-      }
-    }
-    else
-    {
-      Color color = new Color(Integer.parseInt(colourModel.getRGB(), 16));
-      colour = new FeatureColour(color);
-    }
-
-    return colour;
-  }
-
-  /**
    * Constructor
    * 
    * @param af
@@ -1178,7 +884,7 @@ public class FeatureSettings extends JPanel
         for (int i = jucs.getColourCount() - 1; i >= 0; i--)
         {
           jalview.schemabinding.version2.Colour newcol = jucs.getColour(i);
-          FeatureColourI colour = unmarshalColour(newcol);
+          FeatureColourI colour = Jalview2XML.unmarshalColour(newcol);
           fr.setColour(newcol.getName(), colour);
           fr.setOrder(newcol.getName(), i / (float) jucs.getColourCount());
         }
@@ -1191,10 +897,12 @@ public class FeatureSettings extends JPanel
         {
           jalview.schemabinding.version2.Filter filterModel = jucs
                   .getFilter(i);
-          FeatureMatcherSetI filter = unmarshalFilter(filterModel);
+          String featureType = filterModel.getFeatureType();
+          FeatureMatcherSetI filter = Jalview2XML.unmarshalFilter(featureType,
+                  filterModel.getMatcherSet());
           if (!filter.isEmpty())
           {
-            fr.setFeatureFilter(filterModel.getFeatureType(), filter);
+            fr.setFeatureFilter(featureType, filter);
           }
         }
 
@@ -1264,7 +972,7 @@ public class FeatureSettings extends JPanel
         for (String featureType : sortedTypes)
         {
           FeatureColourI fcol = fr.getFeatureStyle(featureType);
-          jalview.schemabinding.version2.Colour col = marshalColour(
+          jalview.schemabinding.version2.Colour col = Jalview2XML.marshalColour(
                   featureType, fcol);
           ucs.addColour(col);
         }
@@ -1279,7 +987,7 @@ public class FeatureSettings extends JPanel
           {
             Iterator<FeatureMatcherI> iterator = filter.getMatchers().iterator();
             FeatureMatcherI firstMatcher = iterator.next();
-            MatcherSet ms = marshalFilter(firstMatcher, iterator,
+            MatcherSet ms = Jalview2XML.marshalFilter(firstMatcher, iterator,
                     filter.isAnded());
             Filter filterModel = new Filter();
             filterModel.setFeatureType(featureType);