Merge branch 'features/pca_jaxb_datasetrefs_JAL-3171_JAL-3063_JAL-1767' into develop
[jalview.git] / src / jalview / gui / FeatureSettings.java
index 811b377..dbe3317 100644 (file)
@@ -22,33 +22,22 @@ 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;
-import jalview.ws.dbsources.das.api.jalviewSourceI;
+import jalview.xml.binding.jalview.JalviewUserColours;
+import jalview.xml.binding.jalview.JalviewUserColours.Colour;
+import jalview.xml.binding.jalview.JalviewUserColours.Filter;
+import jalview.xml.binding.jalview.ObjectFactory;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -75,7 +64,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;
@@ -84,7 +72,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.Vector;
 
 import javax.help.HelpSetException;
 import javax.swing.AbstractCellEditor;
@@ -92,7 +79,6 @@ import javax.swing.BorderFactory;
 import javax.swing.Icon;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
-import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JColorChooser;
 import javax.swing.JDialog;
 import javax.swing.JInternalFrame;
@@ -106,17 +92,24 @@ import javax.swing.JSlider;
 import javax.swing.JTable;
 import javax.swing.ListSelectionModel;
 import javax.swing.SwingConstants;
-import javax.swing.SwingUtilities;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import javax.swing.table.AbstractTableModel;
 import javax.swing.table.TableCellEditor;
 import javax.swing.table.TableCellRenderer;
 import javax.swing.table.TableColumn;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
 
 public class FeatureSettings extends JPanel
         implements FeatureSettingsControllerI
 {
+  private static final String SEQUENCE_FEATURE_COLOURS = MessageManager
+          .getString("label.sequence_feature_colours");
+
   /*
    * column indices of fields in Feature Settings table
    */
@@ -134,12 +127,6 @@ public class FeatureSettings extends JPanel
 
   private static final int MIN_HEIGHT = 400;
 
-  DasSourceBrowser dassourceBrowser;
-
-  DasSequenceFeatureFetcher dasFeatureFetcher;
-
-  JPanel dasSettingsPane = new JPanel();
-
   final FeatureRenderer fr;
 
   public final AlignFrame af;
@@ -189,290 +176,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
@@ -515,7 +218,8 @@ public class FeatureSettings extends JPanel
           FeatureMatcherSet o = (FeatureMatcherSet) table.getValueAt(row,
                   column);
           tip = o.isEmpty()
-                  ? MessageManager.getString("label.filters_tooltip")
+                  ? MessageManager
+                          .getString("label.configure_feature_tooltip")
                   : o.toString();
           break;
         default:
@@ -616,9 +320,6 @@ public class FeatureSettings extends JPanel
     // MessageManager.getString("label.feature_settings_click_drag")));
     scrollPane.setViewportView(table);
 
-    dassourceBrowser = new DasSourceBrowser(this);
-    dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);
-
     if (af.getViewport().isShowSequenceFeatures() || !fr.hasRenderOrder())
     {
       fr.findAllFeatures(true); // display everything!
@@ -667,7 +368,6 @@ public class FeatureSettings extends JPanel
                       javax.swing.event.InternalFrameEvent evt)
               {
                 fr.removePropertyChangeListener(change);
-                dassourceBrowser.fs = null;
               };
             });
     frame.setLayer(JLayeredPane.PALETTE_LAYER);
@@ -715,69 +415,6 @@ public class FeatureSettings extends JPanel
     });
     men.add(dens);
 
-    /*
-     * variable colour options include colour by label, by score,
-     * by selected attribute text, or attribute value
-     */
-    final JCheckBoxMenuItem mxcol = new JCheckBoxMenuItem(
-            MessageManager.getString("label.variable_colour"));
-    mxcol.setSelected(!featureColour.isSimpleColour());
-    men.add(mxcol);
-    mxcol.addActionListener(new ActionListener()
-    {
-      JColorChooser colorChooser;
-
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        if (e.getSource() == mxcol)
-        {
-          if (featureColour.isSimpleColour())
-          {
-            FeatureTypeSettings fc = new FeatureTypeSettings(me.fr, type);
-            fc.addActionListener(this);
-          }
-          else
-          {
-            // bring up simple color chooser
-            colorChooser = new JColorChooser();
-            String title = MessageManager
-                    .getString("label.select_colour");
-            JDialog dialog = JColorChooser.createDialog(me,
-                    title, true, // modal
-                    colorChooser, this, // OK button handler
-                    null); // no CANCEL button handler
-            colorChooser.setColor(featureColour.getMaxColour());
-            dialog.setVisible(true);
-          }
-        }
-        else
-        {
-          if (e.getSource() instanceof FeatureTypeSettings)
-          {
-            /*
-             * update after OK in feature colour dialog; the updated
-             * colour will have already been set in the FeatureRenderer
-             */
-            FeatureColourI fci = fr.getFeatureColours().get(type);
-            table.setValueAt(fci, rowSelected, 1);
-            table.validate();
-          }
-          else
-          {
-            // probably the color chooser!
-            table.setValueAt(new FeatureColour(colorChooser.getColor()),
-                    rowSelected, 1);
-            table.validate();
-            me.updateFeatureRenderer(
-                    ((FeatureTableModel) table.getModel()).getData(),
-                    false);
-          }
-        }
-      }
-
-    });
-
     JMenuItem selCols = new JMenuItem(
             MessageManager.getString("label.select_columns_containing"));
     selCols.addActionListener(new ActionListener()
@@ -1153,7 +790,7 @@ public class FeatureSettings extends JPanel
   void load()
   {
     JalviewFileChooser chooser = new JalviewFileChooser("fc",
-            "Sequence Feature Colours");
+            SEQUENCE_FEATURE_COLOURS);
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(
             MessageManager.getString("label.load_feature_colours"));
@@ -1164,56 +801,76 @@ public class FeatureSettings extends JPanel
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
       File file = chooser.getSelectedFile();
+      load(file);
+    }
+  }
 
-      try
-      {
-        InputStreamReader in = new InputStreamReader(
-                new FileInputStream(file), "UTF-8");
+  /**
+   * Loads feature colours and filters from XML stored in the given file
+   * 
+   * @param file
+   */
+  void load(File file)
+  {
+    try
+    {
+      InputStreamReader in = new InputStreamReader(
+              new FileInputStream(file), "UTF-8");
 
-        JalviewUserColours jucs = JalviewUserColours.unmarshal(in);
+      JAXBContext jc = JAXBContext
+              .newInstance("jalview.xml.binding.jalview");
+      javax.xml.bind.Unmarshaller um = jc.createUnmarshaller();
+      XMLStreamReader streamReader = XMLInputFactory.newInstance()
+              .createXMLStreamReader(in);
+      JAXBElement<JalviewUserColours> jbe = um.unmarshal(streamReader,
+              JalviewUserColours.class);
+      JalviewUserColours jucs = jbe.getValue();
 
-        /*
-         * load feature colours
-         */
-        for (int i = jucs.getColourCount() - 1; i >= 0; i--)
-        {
-          jalview.schemabinding.version2.Colour newcol = jucs.getColour(i);
-          FeatureColourI colour = unmarshalColour(newcol);
-          fr.setColour(newcol.getName(), colour);
-          fr.setOrder(newcol.getName(), i / (float) jucs.getColourCount());
-        }
+      // JalviewUserColours jucs = JalviewUserColours.unmarshal(in);
 
-        /*
-         * load feature filters; loaded filters will replace any that are
-         * currently defined, other defined filters are left unchanged 
-         */
-        for (int i = 0; i < jucs.getFilterCount(); i++)
-        {
-          jalview.schemabinding.version2.Filter filterModel = jucs
-                  .getFilter(i);
-          FeatureMatcherSetI filter = unmarshalFilter(filterModel);
-          if (!filter.isEmpty())
-          {
-            fr.setFeatureFilter(filterModel.getFeatureType(), filter);
-          }
-        }
+      /*
+       * load feature colours
+       */
+      for (int i = jucs.getColour().size() - 1; i >= 0; i--)
+      {
+        Colour newcol = jucs.getColour().get(i);
+        FeatureColourI colour = jalview.project.Jalview2XML
+                .parseColour(newcol);
+        fr.setColour(newcol.getName(), colour);
+        fr.setOrder(newcol.getName(), i / (float) jucs.getColour().size());
+      }
 
-        /*
-         * update feature settings table
-         */
-        if (table != null)
+      /*
+       * load feature filters; loaded filters will replace any that are
+       * currently defined, other defined filters are left unchanged 
+       */
+      for (int i = 0; i < jucs.getFilter().size(); i++)
+      {
+        Filter filterModel = jucs.getFilter().get(i);
+        String featureType = filterModel.getFeatureType();
+        FeatureMatcherSetI filter = jalview.project.Jalview2XML
+                .parseFilter(featureType, filterModel.getMatcherSet());
+        if (!filter.isEmpty())
         {
-          resetTable(null);
-          Object[][] data = ((FeatureTableModel) table.getModel())
-                  .getData();
-          ensureOrder(data);
-          updateFeatureRenderer(data, false);
-          table.repaint();
+          fr.setFeatureFilter(featureType, filter);
         }
-      } catch (Exception ex)
+      }
+
+      /*
+       * update feature settings table
+       */
+      if (table != null)
       {
-        System.out.println("Error loading User Colour File\n" + ex);
+        resetTable(null);
+        Object[][] data = ((FeatureTableModel) table.getModel())
+                .getData();
+        ensureOrder(data);
+        updateFeatureRenderer(data, false);
+        table.repaint();
       }
+    } catch (Exception ex)
+    {
+      System.out.println("Error loading User Colour File\n" + ex);
     }
   }
 
@@ -1224,7 +881,7 @@ public class FeatureSettings extends JPanel
   void save()
   {
     JalviewFileChooser chooser = new JalviewFileChooser("fc",
-            "Sequence Feature Colours");
+            SEQUENCE_FEATURE_COLOURS);
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(
             MessageManager.getString("label.save_feature_colours"));
@@ -1234,77 +891,97 @@ public class FeatureSettings extends JPanel
 
     if (value == JalviewFileChooser.APPROVE_OPTION)
     {
-      String choice = chooser.getSelectedFile().getPath();
-      JalviewUserColours ucs = new JalviewUserColours();
-      ucs.setSchemeName("Sequence Features");
-      try
-      {
-        PrintWriter out = new PrintWriter(new OutputStreamWriter(
-                new FileOutputStream(choice), "UTF-8"));
+      save(chooser.getSelectedFile());
+    }
+  }
 
-        /*
-         * sort feature types by colour order, from 0 (highest)
-         * to 1 (lowest)
-         */
-        Set<String> fr_colours = fr.getAllFeatureColours();
-        String[] sortedTypes = fr_colours
-                .toArray(new String[fr_colours.size()]);
-        Arrays.sort(sortedTypes, new Comparator<String>()
-        {
-          @Override
-          public int compare(String type1, String type2)
-          {
-            return Float.compare(fr.getOrder(type1), fr.getOrder(type2));
-          }
-        });
+  /**
+   * Saves feature colours and filters to the given file
+   * 
+   * @param file
+   */
+  void save(File file)
+  {
+    JalviewUserColours ucs = new JalviewUserColours();
+    ucs.setSchemeName("Sequence Features");
+    try
+    {
+      PrintWriter out = new PrintWriter(new OutputStreamWriter(
+              new FileOutputStream(file), "UTF-8"));
 
-        /*
-         * save feature colours
-         */
-        for (String featureType : sortedTypes)
+      /*
+       * sort feature types by colour order, from 0 (highest)
+       * to 1 (lowest)
+       */
+      Set<String> fr_colours = fr.getAllFeatureColours();
+      String[] sortedTypes = fr_colours
+              .toArray(new String[fr_colours.size()]);
+      Arrays.sort(sortedTypes, new Comparator<String>()
+      {
+        @Override
+        public int compare(String type1, String type2)
         {
-          FeatureColourI fcol = fr.getFeatureStyle(featureType);
-          jalview.schemabinding.version2.Colour col = marshalColour(
-                  featureType, fcol);
-          ucs.addColour(col);
+          return Float.compare(fr.getOrder(type1), fr.getOrder(type2));
         }
+      });
 
-        /*
-         * save any feature filters
-         */
-        for (String featureType : sortedTypes)
-        {
-          FeatureMatcherSetI filter = fr.getFeatureFilter(featureType);
-          if (filter != null && !filter.isEmpty())
-          {
-            Iterator<FeatureMatcherI> iterator = filter.getMatchers().iterator();
-            FeatureMatcherI firstMatcher = iterator.next();
-            MatcherSet ms = marshalFilter(firstMatcher, iterator,
-                    filter.isAnded());
-            Filter filterModel = new Filter();
-            filterModel.setFeatureType(featureType);
-            filterModel.setMatcherSet(ms);
-            ucs.addFilter(filterModel);
-          }
-        }
+      /*
+       * save feature colours
+       */
+      for (String featureType : sortedTypes)
+      {
+        FeatureColourI fcol = fr.getFeatureStyle(featureType);
+        Colour col = jalview.project.Jalview2XML.marshalColour(featureType,
+                fcol);
+        ucs.getColour().add(col);
+      }
 
-        ucs.marshal(out);
-        out.close();
-      } catch (Exception ex)
+      /*
+       * save any feature filters
+       */
+      for (String featureType : sortedTypes)
       {
-        ex.printStackTrace();
+        FeatureMatcherSetI filter = fr.getFeatureFilter(featureType);
+        if (filter != null && !filter.isEmpty())
+        {
+          Iterator<FeatureMatcherI> iterator = filter.getMatchers().iterator();
+          FeatureMatcherI firstMatcher = iterator.next();
+          jalview.xml.binding.jalview.FeatureMatcherSet ms = jalview.project.Jalview2XML
+                  .marshalFilter(firstMatcher, iterator,
+                  filter.isAnded());
+          Filter filterModel = new Filter();
+          filterModel.setFeatureType(featureType);
+          filterModel.setMatcherSet(ms);
+          ucs.getFilter().add(filterModel);
+        }
       }
+      JAXBContext jaxbContext = JAXBContext
+              .newInstance(JalviewUserColours.class);
+      Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
+      jaxbMarshaller.marshal(
+              new ObjectFactory().createJalviewUserColours(ucs), out);
+
+      // jaxbMarshaller.marshal(object, pout);
+      // marshaller.marshal(object);
+      out.flush();
+
+      // ucs.marshal(out);
+      out.close();
+    } catch (Exception ex)
+    {
+      ex.printStackTrace();
     }
   }
 
   public void invertSelection()
   {
-    for (int i = 0; i < table.getRowCount(); i++)
+    Object[][] data = ((FeatureTableModel) table.getModel()).getData();
+    for (int i = 0; i < data.length; i++)
     {
-      Boolean value = (Boolean) table.getValueAt(i, SHOW_COLUMN);
-
-      table.setValueAt(new Boolean(!value.booleanValue()), i, SHOW_COLUMN);
+      data[i][SHOW_COLUMN] = !(Boolean) data[i][SHOW_COLUMN];
     }
+    updateFeatureRenderer(data, true);
+    table.repaint();
   }
 
   public void orderByAvWidth()
@@ -1428,8 +1105,6 @@ public class FeatureSettings extends JPanel
     JPanel settingsPane = new JPanel();
     settingsPane.setLayout(new BorderLayout());
 
-    dasSettingsPane.setLayout(new BorderLayout());
-
     JPanel bigPanel = new JPanel();
     bigPanel.setLayout(new BorderLayout());
 
@@ -1544,6 +1219,8 @@ public class FeatureSettings extends JPanel
     JButton loadColours = new JButton(
             MessageManager.getString("label.load_colours"));
     loadColours.setFont(JvSwingUtils.getLabelFont());
+    loadColours.setToolTipText(
+            MessageManager.getString("label.load_colours_tooltip"));
     loadColours.addActionListener(new ActionListener()
     {
       @Override
@@ -1556,6 +1233,8 @@ public class FeatureSettings extends JPanel
     JButton saveColours = new JButton(
             MessageManager.getString("label.save_colours"));
     saveColours.setFont(JvSwingUtils.getLabelFont());
+    saveColours.setToolTipText(
+            MessageManager.getString("label.save_colours_tooltip"));
     saveColours.addActionListener(new ActionListener()
     {
       @Override
@@ -1580,38 +1259,6 @@ public class FeatureSettings extends JPanel
     transparency.setMaximum(70);
     transparency.setToolTipText(
             MessageManager.getString("label.transparency_tip"));
-    fetchDAS.setText(MessageManager.getString("label.fetch_das_features"));
-    fetchDAS.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        fetchDAS_actionPerformed(e);
-      }
-    });
-    saveDAS.setText(MessageManager.getString("action.save_as_default"));
-    saveDAS.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        saveDAS_actionPerformed(e);
-      }
-    });
-
-    JPanel dasButtonPanel = new JPanel();
-    dasButtonPanel.setBorder(BorderFactory.createEtchedBorder());
-    dasSettingsPane.setBorder(null);
-    cancelDAS.setEnabled(false);
-    cancelDAS.setText(MessageManager.getString("action.cancel_fetch"));
-    cancelDAS.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        cancelDAS_actionPerformed(e);
-      }
-    });
 
     JPanel transPanel = new JPanel(new GridLayout(1, 2));
     bigPanel.add(transPanel, BorderLayout.SOUTH);
@@ -1631,172 +1278,11 @@ public class FeatureSettings extends JPanel
     buttonPanel.add(loadColours);
     buttonPanel.add(saveColours);
     bigPanel.add(scrollPane, BorderLayout.CENTER);
-    dasSettingsPane.add(dasButtonPanel, BorderLayout.SOUTH);
-    dasButtonPanel.add(fetchDAS);
-    dasButtonPanel.add(cancelDAS);
-    dasButtonPanel.add(saveDAS);
     settingsPane.add(bigPanel, BorderLayout.CENTER);
     settingsPane.add(buttonPanel, BorderLayout.SOUTH);
     this.add(settingsPane);
   }
 
-  public void fetchDAS_actionPerformed(ActionEvent e)
-  {
-    fetchDAS.setEnabled(false);
-    cancelDAS.setEnabled(true);
-    dassourceBrowser.setGuiEnabled(false);
-    Vector<jalviewSourceI> selectedSources = dassourceBrowser
-            .getSelectedSources();
-    doDasFeatureFetch(selectedSources, true, true);
-  }
-
-  /**
-   * get the features from selectedSources for all or the current selection
-   * 
-   * @param selectedSources
-   * @param checkDbRefs
-   * @param promptFetchDbRefs
-   */
-  private void doDasFeatureFetch(List<jalviewSourceI> selectedSources,
-          boolean checkDbRefs, boolean promptFetchDbRefs)
-  {
-    SequenceI[] dataset, seqs;
-    int iSize;
-    AlignmentViewport vp = af.getViewport();
-    if (vp.getSelectionGroup() != null
-            && vp.getSelectionGroup().getSize() > 0)
-    {
-      iSize = vp.getSelectionGroup().getSize();
-      dataset = new SequenceI[iSize];
-      seqs = vp.getSelectionGroup().getSequencesInOrder(vp.getAlignment());
-    }
-    else
-    {
-      iSize = vp.getAlignment().getHeight();
-      seqs = vp.getAlignment().getSequencesArray();
-    }
-
-    dataset = new SequenceI[iSize];
-    for (int i = 0; i < iSize; i++)
-    {
-      dataset[i] = seqs[i].getDatasetSequence();
-    }
-
-    cancelDAS.setEnabled(true);
-    dasFeatureFetcher = new jalview.ws.DasSequenceFeatureFetcher(dataset,
-            this, selectedSources, checkDbRefs, promptFetchDbRefs);
-    af.getViewport().setShowSequenceFeatures(true);
-    af.showSeqFeatures.setSelected(true);
-  }
-
-  /**
-   * blocking call to initialise the das source browser
-   */
-  public void initDasSources()
-  {
-    dassourceBrowser.initDasSources();
-  }
-
-  /**
-   * examine the current list of das sources and return any matching the given
-   * nicknames in sources
-   * 
-   * @param sources
-   *          Vector of Strings to resolve to DAS source nicknames.
-   * @return sources that are present in source list.
-   */
-  public List<jalviewSourceI> resolveSourceNicknames(Vector<String> sources)
-  {
-    return dassourceBrowser.sourceRegistry.resolveSourceNicknames(sources);
-  }
-
-  /**
-   * get currently selected das sources. ensure you have called initDasSources
-   * before calling this.
-   * 
-   * @return vector of selected das source nicknames
-   */
-  public Vector<jalviewSourceI> getSelectedSources()
-  {
-    return dassourceBrowser.getSelectedSources();
-  }
-
-  /**
-   * properly initialise DAS fetcher and then initiate a new thread to fetch
-   * features from the named sources (rather than any turned on by default)
-   * 
-   * @param sources
-   * @param block
-   *          if true then runs in same thread, otherwise passes to the Swing
-   *          executor
-   */
-  public void fetchDasFeatures(Vector<String> sources, boolean block)
-  {
-    initDasSources();
-    List<jalviewSourceI> resolved = dassourceBrowser.sourceRegistry
-            .resolveSourceNicknames(sources);
-    if (resolved.size() == 0)
-    {
-      resolved = dassourceBrowser.getSelectedSources();
-    }
-    if (resolved.size() > 0)
-    {
-      final List<jalviewSourceI> dassources = resolved;
-      fetchDAS.setEnabled(false);
-      // cancelDAS.setEnabled(true); doDasFetch does this.
-      Runnable fetcher = new Runnable()
-      {
-
-        @Override
-        public void run()
-        {
-          doDasFeatureFetch(dassources, true, false);
-
-        }
-      };
-      if (block)
-      {
-        fetcher.run();
-      }
-      else
-      {
-        SwingUtilities.invokeLater(fetcher);
-      }
-    }
-  }
-
-  public void saveDAS_actionPerformed(ActionEvent e)
-  {
-    dassourceBrowser
-            .saveProperties(jalview.bin.Cache.applicationProperties);
-  }
-
-  public void complete()
-  {
-    fetchDAS.setEnabled(true);
-    cancelDAS.setEnabled(false);
-    dassourceBrowser.setGuiEnabled(true);
-
-  }
-
-  public void cancelDAS_actionPerformed(ActionEvent e)
-  {
-    if (dasFeatureFetcher != null)
-    {
-      dasFeatureFetcher.cancel();
-    }
-    complete();
-  }
-
-  public void noDasSourceActive()
-  {
-    complete();
-    JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
-            MessageManager.getString("label.no_das_sources_selected_warn"),
-            MessageManager.getString("label.no_das_sources_selected_title"),
-            JvOptionPane.DEFAULT_OPTION, JvOptionPane.INFORMATION_MESSAGE);
-  }
-
   // ///////////////////////////////////////////////////////////////////////
   // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
   // ///////////////////////////////////////////////////////////////////////
@@ -1805,7 +1291,7 @@ public class FeatureSettings extends JPanel
     private String[] columnNames = {
         MessageManager.getString("label.feature_type"),
         MessageManager.getString("action.colour"),
-        MessageManager.getString("label.filter"),
+        MessageManager.getString("label.configuration"),
         MessageManager.getString("label.show") };
 
     private Object[][] data;
@@ -2141,14 +1627,17 @@ public class FeatureSettings extends JPanel
         {
           // bring up graduated chooser.
           chooser = new FeatureTypeSettings(me.fr, type);
-          chooser.setRequestFocusEnabled(true);
-          chooser.requestFocus();
+          /**
+           * @j2sNative
+           */
+          {
+            chooser.setRequestFocusEnabled(true);
+            chooser.requestFocus();
+          }
           chooser.addActionListener(this);
-          chooser.showTab(true);
+          // Make the renderer reappear.
+          fireEditingStopped();
         }
-        // Make the renderer reappear.
-        fireEditingStopped();
-
       }
       else
       {
@@ -2270,7 +1759,6 @@ public class FeatureSettings extends JPanel
                   chooser.getWidth(), chooser.getHeight());
           chooser.validate();
         }
-        chooser.showTab(false);
         fireEditingStopped();
       }
       else if (e.getSource() instanceof Component)