Merge branch 'features/JAL-1333' into Release_2_8_2_Branch
[jalview.git] / src / jalview / gui / Jalview2XML.java
index 3499f6d..f3bc42e 100644 (file)
@@ -1,19 +1,21 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
  * Copyright (C) 2014 The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
  * Jalview is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
  *  
  * Jalview is distributed in the hope that it will be useful, but 
  * WITHOUT ANY WARRANTY; without even the implied warranty 
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
  * PURPOSE.  See the GNU General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
 package jalview.gui;
@@ -30,6 +32,7 @@ import javax.swing.*;
 
 import org.exolab.castor.xml.*;
 
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
@@ -39,6 +42,7 @@ import jalview.schemabinding.version2.*;
 import jalview.schemes.*;
 import jalview.util.Platform;
 import jalview.util.jarInputStreamProvider;
+import jalview.viewmodel.AlignmentViewport;
 import jalview.ws.jws2.Jws2Discoverer;
 import jalview.ws.jws2.dm.AAConSettings;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
@@ -278,6 +282,8 @@ public class Jalview2XML
       return;
     }
 
+    Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
+
     try
     {
 
@@ -332,6 +338,7 @@ public class Jalview2XML
           }
 
           int ap, apSize = af.alignPanels.size();
+
           for (ap = 0; ap < apSize; ap++)
           {
             AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
@@ -343,9 +350,21 @@ public class Jalview2XML
             }
 
             SaveState(apanel, fileName, jout);
+
+            String dssid = getDatasetIdRef(af.getViewport().getAlignment()
+                    .getDataset());
+            if (!dsses.containsKey(dssid))
+            {
+              dsses.put(dssid, af);
+            }
+
           }
         }
       }
+
+      writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
+              jout);
+
       try
       {
         jout.flush();
@@ -375,6 +394,7 @@ public class Jalview2XML
       int ap, apSize = af.alignPanels.size();
       FileOutputStream fos = new FileOutputStream(jarFile);
       JarOutputStream jout = new JarOutputStream(fos);
+      Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
       for (ap = 0; ap < apSize; ap++)
       {
         AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
@@ -385,8 +405,14 @@ public class Jalview2XML
           jfileName = jfileName + ".xml";
         }
         SaveState(apanel, jfileName, jout);
+        String dssid = getDatasetIdRef(af.getViewport().getAlignment()
+                .getDataset());
+        if (!dsses.containsKey(dssid))
+        {
+          dsses.put(dssid, af);
+        }
       }
-
+      writeDatasetFor(dsses, fileName, jout);
       try
       {
         jout.flush();
@@ -404,6 +430,22 @@ public class Jalview2XML
     }
   }
 
+  private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
+          String fileName, JarOutputStream jout)
+  {
+
+    for (String dssids : dsses.keySet())
+    {
+      AlignFrame _af = dsses.get(dssids);
+      String jfileName = fileName + " Dataset for " + _af.getTitle();
+      if (!jfileName.endsWith(".xml"))
+      {
+        jfileName = jfileName + ".xml";
+      }
+      SaveState(_af.alignPanel, jfileName, true, jout);
+    }
+  }
+
   /**
    * create a JalviewModel from an algnment view and marshall it to a
    * JarOutputStream
@@ -420,25 +462,27 @@ public class Jalview2XML
   public JalviewModel SaveState(AlignmentPanel ap, String fileName,
           JarOutputStream jout)
   {
-    return SaveState(ap, fileName, false,jout);
+    return SaveState(ap, fileName, false, jout);
   }
+
   /**
-  * create a JalviewModel from an algnment view and marshall it to a
-  * JarOutputStream
-  * 
-  * @param ap
-  *          panel to create jalview model for
-  * @param fileName
-  *          name of alignment panel written to output stream
-  * @param storeDS
-  *          when true, only write the dataset for the alignment, not the data associated with the view.
-  * @param jout
-  *          jar output stream
-  * @param out
-  *          jar entry name
-  */
-  public JalviewModel SaveState(AlignmentPanel ap, String fileName, boolean storeDS,
-          JarOutputStream jout)
+   * create a JalviewModel from an algnment view and marshall it to a
+   * JarOutputStream
+   * 
+   * @param ap
+   *          panel to create jalview model for
+   * @param fileName
+   *          name of alignment panel written to output stream
+   * @param storeDS
+   *          when true, only write the dataset for the alignment, not the data
+   *          associated with the view.
+   * @param jout
+   *          jar output stream
+   * @param out
+   *          jar entry name
+   */
+  public JalviewModel SaveState(AlignmentPanel ap, String fileName,
+          boolean storeDS, JarOutputStream jout)
   {
     initSeqRefs();
     Vector jmolViewIds = new Vector(); //
@@ -450,7 +494,8 @@ public class Jalview2XML
     object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
 
     object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
-    object.setVersion(jalview.bin.Cache.getDefault("VERSION","Development Build"));
+    object.setVersion(jalview.bin.Cache.getDefault("VERSION",
+            "Development Build"));
 
     jalview.datamodel.AlignmentI jal = av.getAlignment();
 
@@ -493,11 +538,12 @@ public class Jalview2XML
 
     // SAVE SEQUENCES
     String id = "";
-    jalview.datamodel.SequenceI jds,jdatasq;
+    jalview.datamodel.SequenceI jds, jdatasq;
     for (int i = 0; i < jal.getHeight(); i++)
     {
       jds = jal.getSequenceAt(i);
-      jdatasq=jds.getDatasetSequence() == null ? jds : jds.getDatasetSequence();
+      jdatasq = jds.getDatasetSequence() == null ? jds : jds
+              .getDatasetSequence();
       id = seqHash(jds);
 
       if (seqRefIds.get(id) != null)
@@ -841,17 +887,19 @@ public class Jalview2XML
     IdentityHashMap groupRefs = new IdentityHashMap();
     if (storeDS)
     {
-        for (SequenceI sq:jal.getSequences())
+      for (SequenceI sq : jal.getSequences())
+      {
+        // Store annotation on dataset sequences only
+        jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
+        if (aa != null && aa.length > 0)
         {
-       // Store annotation on dataset sequences only
-          jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
-          if (aa!=null && aa.length>0)
-          {
-            storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
-                    vamsasSet);
-          }
+          storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
+                  vamsasSet);
         }
-    } else {
+      }
+    }
+    else
+    {
       if (jal.getAlignmentAnnotation() != null)
       {
         // Store the annotation shown on the alignment.
@@ -897,10 +945,10 @@ public class Jalview2XML
           }
           else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
           {
-            groups[i]
-                    .setColour(ColourSchemeProperty
-                            .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
-                                    .getBaseColour()));
+            groups[i].setColour("AnnotationColourGradient");
+            groups[i].setAnnotationColours(constructAnnotationColours(
+                    (jalview.schemes.AnnotationColourGradient) sg.cs,
+                    userColours, jms));
           }
           else if (sg.cs instanceof jalview.schemes.UserColourScheme)
           {
@@ -973,28 +1021,11 @@ public class Jalview2XML
       }
       else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
       {
-        jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
-                .getGlobalColourScheme();
-
-        AnnotationColours ac = new AnnotationColours();
-        ac.setAboveThreshold(acg.getAboveThreshold());
-        ac.setThreshold(acg.getAnnotationThreshold());
-        ac.setAnnotation(acg.getAnnotation());
-        if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
-        {
-          ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
-                  userColours, jms));
-        }
-        else
-        {
-          ac.setColourScheme(ColourSchemeProperty.getColourName(acg
-                  .getBaseColour()));
-        }
+        AnnotationColours ac = constructAnnotationColours(
+                (jalview.schemes.AnnotationColourGradient) av
+                        .getGlobalColourScheme(),
+                userColours, jms);
 
-        ac.setMaxColour(acg.getMaxColour().getRGB());
-        ac.setMinColour(acg.getMinColour().getRGB());
-        ac.setPerSequence(acg.isSeqAssociated());
-        ac.setPredefinedColours(acg.isPredefinedColours());
         view.setAnnotationColours(ac);
         view.setBgColour("AnnotationColourGradient");
       }
@@ -1214,7 +1245,35 @@ public class Jalview2XML
     return object;
   }
 
-  private void storeAlignmentAnnotation(AlignmentAnnotation[] aa, IdentityHashMap groupRefs, AlignmentViewport av, Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
+  private AnnotationColours constructAnnotationColours(
+          AnnotationColourGradient acg, Vector userColours,
+          JalviewModelSequence jms)
+  {
+    AnnotationColours ac = new AnnotationColours();
+    ac.setAboveThreshold(acg.getAboveThreshold());
+    ac.setThreshold(acg.getAnnotationThreshold());
+    ac.setAnnotation(acg.getAnnotation());
+    if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
+    {
+      ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
+              userColours, jms));
+    }
+    else
+    {
+      ac.setColourScheme(ColourSchemeProperty.getColourName(acg
+              .getBaseColour()));
+    }
+
+    ac.setMaxColour(acg.getMaxColour().getRGB());
+    ac.setMinColour(acg.getMinColour().getRGB());
+    ac.setPerSequence(acg.isSeqAssociated());
+    ac.setPredefinedColours(acg.isPredefinedColours());
+    return ac;
+  }
+
+  private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
+          IdentityHashMap groupRefs, AlignmentViewport av,
+          Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
   {
 
     for (int i = 0; i < aa.length; i++)
@@ -1346,11 +1405,12 @@ public class Jalview2XML
       }
       if (!storeDS || (storeDS && !aa[i].autoCalculated))
       {
-        // skip autocalculated annotation - these are only provided for alignments
+        // skip autocalculated annotation - these are only provided for
+        // alignments
         vamsasSet.addAnnotation(an);
       }
     }
-    
+
   }
 
   private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
@@ -1736,7 +1796,7 @@ public class Jalview2XML
     try
     {
       // create list to store references for any new Jmol viewers created
-      newStructureViewers=new Vector<AppJmol>();
+      newStructureViewers = new Vector<JalviewStructureDisplayI>();
       // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
       // Workaround is to make sure caller implements the JarInputStreamProvider
       // interface
@@ -1744,13 +1804,13 @@ public class Jalview2XML
 
       jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
       af = LoadJalviewAlign(jprovider);
-      
+
     } catch (MalformedURLException e)
     {
       errorMessage = "Invalid URL format for '" + file + "'";
       reportErrors();
-    }
-    finally {
+    } finally
+    {
       try
       {
         SwingUtilities.invokeAndWait(new Runnable()
@@ -1836,7 +1896,7 @@ public class Jalview2XML
       frefedSequence = new Vector();
     }
 
-    jalview.gui.AlignFrame af= null,_af = null;
+    jalview.gui.AlignFrame af = null, _af = null;
     Hashtable gatherToThisFrame = new Hashtable();
     final String file = jprovider.getFilename();
     try
@@ -1867,8 +1927,7 @@ public class Jalview2XML
             if (object.getJalviewModelSequence().getViewportCount() > 0)
             {
               af = _af;
-              if (object.getJalviewModelSequence().getViewportCount() > 1
-                      && af.viewport.gatherViewsHere)
+              if (af.viewport.gatherViewsHere)
               {
                 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
               }
@@ -2094,8 +2153,9 @@ public class Jalview2XML
 
     JalviewModelSequence jms = object.getJalviewModelSequence();
 
-    Viewport view = (jms.getViewportCount()>0) ? jms.getViewport(0) : null;
-    
+    Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
+            : null;
+
     // ////////////////////////////////
     // LOAD SEQUENCES
 
@@ -2501,14 +2561,13 @@ public class Jalview2XML
         }
       }
     }
-
     // ///////////////////////
     // LOAD GROUPS
     // Create alignment markup and styles for this view
     if (jms.getJGroupCount() > 0)
     {
       JGroup[] groups = jms.getJGroup();
-
+      boolean addAnnotSchemeGroup = false;
       for (int i = 0; i < groups.length; i++)
       {
         ColourSchemeI cs = null;
@@ -2519,6 +2578,12 @@ public class Jalview2XML
           {
             cs = GetUserColourScheme(jms, groups[i].getColour());
           }
+          else if (groups[i].getColour().equals("AnnotationColourGradient")
+                  && groups[i].getAnnotationColours() != null)
+          {
+            addAnnotSchemeGroup = true;
+            cs = null;
+          }
           else
           {
             cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
@@ -2617,10 +2682,15 @@ public class Jalview2XML
           }
         }
         al.addGroup(sg);
-
+        if (addAnnotSchemeGroup)
+        {
+          // reconstruct the annotation colourscheme
+          sg.cs = constructAnnotationColour(
+                  groups[i].getAnnotationColours(), null, al, jms, false);
+        }
       }
     }
-    if (view==null)
+    if (view == null)
     {
       // only dataset in this model, so just return.
       return null;
@@ -2668,6 +2738,13 @@ public class Jalview2XML
 
       }
     }
+    /**
+     * indicate that annotation colours are applied across all groups (pre
+     * Jalview 2.8.1 behaviour)
+     */
+    boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
+            object.getVersion());
+
     AlignmentPanel ap = null;
     boolean isnewview = true;
     if (viewId != null)
@@ -3056,10 +3133,11 @@ public class Jalview2XML
                   @Override
                   public void run()
                   {
-                    AppJmol sview = null;
+                    JalviewStructureDisplayI sview = null;
                     try
                     {
-                      sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
+                      // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
+                      sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
                               useinJmolsuperpos, usetoColourbyseq,
                               jmolColouring, fileloc, rect, vid);
                       addNewStructureViewer(sview);
@@ -3132,25 +3210,84 @@ public class Jalview2XML
     // and finally return.
     return af;
   }
-  Vector<AppJmol> newStructureViewers=null;
-  protected void addNewStructureViewer(AppJmol sview)
+
+  /**
+   * 
+   * @param supported
+   *          - minimum version we are comparing against
+   * @param version
+   *          - version of data being processsed.
+   * @return true if version is development/null or evaluates to the same or
+   *         later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
+   */
+  private boolean isVersionStringLaterThan(String supported, String version)
+  {
+    if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
+            || version.equalsIgnoreCase("Test")
+            || version.equalsIgnoreCase("AUTOMATED BUILD"))
+    {
+      System.err.println("Assuming project file with "
+              + (version == null ? "null" : version)
+              + " is compatible with Jalview version " + supported);
+      return true;
+    }
+    else
+    {
+      StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
+              version, ".");
+      while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
+      {
+        // convert b to decimal to catch bugfix releases within a series
+        String curT = currentV.nextToken().toLowerCase().replace('b', '.');
+        String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
+        try
+        {
+          if (Float.valueOf(curT) > Float.valueOf(fileT))
+          {
+            // current version is newer than the version that wrote the file
+            return false;
+          }
+        } catch (NumberFormatException nfe)
+        {
+          System.err
+                  .println("** WARNING: Version comparison failed for tokens ("
+                          + curT
+                          + ") and ("
+                          + fileT
+                          + ")\n** Current: '"
+                          + supported + "' and Version: '" + version + "'");
+        }
+      }
+      if (currentV.hasMoreElements())
+      {
+        // fileV has no minor version but identical series to current
+        return false;
+      }
+    }
+    return true;
+  }
+
+  Vector<JalviewStructureDisplayI> newStructureViewers = null;
+
+  protected void addNewStructureViewer(JalviewStructureDisplayI sview)
   {
-    if (newStructureViewers!=null)
+    if (newStructureViewers != null)
     {
-      sview.jmb.setFinishedLoadingFromArchive(false);
+      sview.getBinding().setFinishedLoadingFromArchive(false);
       newStructureViewers.add(sview);
     }
   }
+
   protected void setLoadingFinishedForNewStructureViewers()
   {
-    if (newStructureViewers!=null)
+    if (newStructureViewers != null)
     {
-      for (AppJmol sview:newStructureViewers)
+      for (JalviewStructureDisplayI sview : newStructureViewers)
       {
-        sview.jmb.setFinishedLoadingFromArchive(true);
+        sview.getBinding().setFinishedLoadingFromArchive(true);
       }
       newStructureViewers.clear();
-      newStructureViewers=null;
+      newStructureViewers = null;
     }
   }
 
@@ -3267,111 +3404,11 @@ public class Jalview2XML
       }
       else if (view.getBgColour().startsWith("Annotation"))
       {
-        // int find annotation
-        if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
-        {
-          for (int i = 0; i < af.viewport.getAlignment()
-                  .getAlignmentAnnotation().length; i++)
-          {
-            if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
-                    .equals(view.getAnnotationColours().getAnnotation()))
-            {
-              if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
-                      .getThreshold() == null)
-              {
-                af.viewport.getAlignment().getAlignmentAnnotation()[i]
-                        .setThreshold(new jalview.datamodel.GraphLine(view
-                                .getAnnotationColours().getThreshold(),
-                                "Threshold", java.awt.Color.black)
-
-                        );
-              }
-
-              if (view.getAnnotationColours().getColourScheme()
-                      .equals("None"))
-              {
-                cs = new AnnotationColourGradient(af.viewport
-                        .getAlignment().getAlignmentAnnotation()[i],
-                        new java.awt.Color(view.getAnnotationColours()
-                                .getMinColour()), new java.awt.Color(view
-                                .getAnnotationColours().getMaxColour()),
-                        view.getAnnotationColours().getAboveThreshold());
-              }
-              else if (view.getAnnotationColours().getColourScheme()
-                      .startsWith("ucs"))
-              {
-                cs = new AnnotationColourGradient(af.viewport
-                        .getAlignment().getAlignmentAnnotation()[i],
-                        GetUserColourScheme(jms, view
-                                .getAnnotationColours().getColourScheme()),
-                        view.getAnnotationColours().getAboveThreshold());
-              }
-              else
-              {
-                cs = new AnnotationColourGradient(af.viewport
-                        .getAlignment().getAlignmentAnnotation()[i],
-                        ColourSchemeProperty.getColour(al, view
-                                .getAnnotationColours().getColourScheme()),
-                        view.getAnnotationColours().getAboveThreshold());
-              }
-              if (view.getAnnotationColours().hasPerSequence())
-              {
-                ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
-              }
-              if (view.getAnnotationColours().hasPredefinedColours())
-              {
-                ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
-              }
-              // Also use these settings for all the groups
-              if (al.getGroups() != null)
-              {
-                for (int g = 0; g < al.getGroups().size(); g++)
-                {
-                  jalview.datamodel.SequenceGroup sg = al.getGroups()
-                          .get(g);
-
-                  if (sg.cs == null)
-                  {
-                    continue;
-                  }
-
-                  /*
-                   * if
-                   * (view.getAnnotationColours().getColourScheme().equals("None"
-                   * )) { sg.cs = new AnnotationColourGradient(
-                   * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
-                   * java.awt.Color(view.getAnnotationColours().
-                   * getMinColour()), new
-                   * java.awt.Color(view.getAnnotationColours().
-                   * getMaxColour()),
-                   * view.getAnnotationColours().getAboveThreshold()); } else
-                   */
-                  {
-                    sg.cs = new AnnotationColourGradient(af.viewport
-                            .getAlignment().getAlignmentAnnotation()[i],
-                            sg.cs, view.getAnnotationColours()
-                                    .getAboveThreshold());
-                    if (cs instanceof AnnotationColourGradient) 
-                    {
-                      if (view.getAnnotationColours().hasPerSequence())
-                      { 
-                        ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
-                      }
-                      if (view.getAnnotationColours().hasPredefinedColours())
-                      {
-                        ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
-                      }
-                    }
-                  }
-
-                }
-              }
+        AnnotationColours viewAnnColour = view.getAnnotationColours();
+        cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
 
-              break;
-            }
+        // annpos
 
-          }
-        }
       }
       else
       {
@@ -3565,6 +3602,131 @@ public class Jalview2XML
     return af;
   }
 
+  private ColourSchemeI constructAnnotationColour(
+          AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
+          JalviewModelSequence jms, boolean checkGroupAnnColour)
+  {
+    boolean propagateAnnColour = false;
+    ColourSchemeI cs = null;
+    AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
+    if (checkGroupAnnColour && al.getGroups() != null
+            && al.getGroups().size() > 0)
+    {
+      // pre 2.8.1 behaviour
+      // check to see if we should transfer annotation colours
+      propagateAnnColour = true;
+      for (jalview.datamodel.SequenceGroup sg : al.getGroups())
+      {
+        if (sg.cs instanceof AnnotationColourGradient)
+        {
+          propagateAnnColour = false;
+        }
+      }
+    }
+    // int find annotation
+    if (annAlignment.getAlignmentAnnotation() != null)
+    {
+      for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
+      {
+        if (annAlignment.getAlignmentAnnotation()[i].label
+                .equals(viewAnnColour.getAnnotation()))
+        {
+          if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
+          {
+            annAlignment.getAlignmentAnnotation()[i]
+                    .setThreshold(new jalview.datamodel.GraphLine(
+                            viewAnnColour.getThreshold(), "Threshold",
+                            java.awt.Color.black)
+
+                    );
+          }
+
+          if (viewAnnColour.getColourScheme().equals("None"))
+          {
+            cs = new AnnotationColourGradient(
+                    annAlignment.getAlignmentAnnotation()[i],
+                    new java.awt.Color(viewAnnColour.getMinColour()),
+                    new java.awt.Color(viewAnnColour.getMaxColour()),
+                    viewAnnColour.getAboveThreshold());
+          }
+          else if (viewAnnColour.getColourScheme().startsWith("ucs"))
+          {
+            cs = new AnnotationColourGradient(
+                    annAlignment.getAlignmentAnnotation()[i],
+                    GetUserColourScheme(jms,
+                            viewAnnColour.getColourScheme()),
+                    viewAnnColour.getAboveThreshold());
+          }
+          else
+          {
+            cs = new AnnotationColourGradient(
+                    annAlignment.getAlignmentAnnotation()[i],
+                    ColourSchemeProperty.getColour(al,
+                            viewAnnColour.getColourScheme()),
+                    viewAnnColour.getAboveThreshold());
+          }
+          if (viewAnnColour.hasPerSequence())
+          {
+            ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
+                    .isPerSequence());
+          }
+          if (viewAnnColour.hasPredefinedColours())
+          {
+            ((AnnotationColourGradient) cs)
+                    .setPredefinedColours(viewAnnColour
+                            .isPredefinedColours());
+          }
+          if (propagateAnnColour && al.getGroups() != null)
+          {
+            // Also use these settings for all the groups
+            for (int g = 0; g < al.getGroups().size(); g++)
+            {
+              jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
+
+              if (sg.cs == null)
+              {
+                continue;
+              }
+
+              /*
+               * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
+               * new AnnotationColourGradient(
+               * annAlignment.getAlignmentAnnotation()[i], new
+               * java.awt.Color(viewAnnColour. getMinColour()), new
+               * java.awt.Color(viewAnnColour. getMaxColour()),
+               * viewAnnColour.getAboveThreshold()); } else
+               */
+              {
+                sg.cs = new AnnotationColourGradient(
+                        annAlignment.getAlignmentAnnotation()[i], sg.cs,
+                        viewAnnColour.getAboveThreshold());
+                if (cs instanceof AnnotationColourGradient)
+                {
+                  if (viewAnnColour.hasPerSequence())
+                  {
+                    ((AnnotationColourGradient) cs)
+                            .setSeqAssociated(viewAnnColour.isPerSequence());
+                  }
+                  if (viewAnnColour.hasPredefinedColours())
+                  {
+                    ((AnnotationColourGradient) cs)
+                            .setPredefinedColours(viewAnnColour
+                                    .isPredefinedColours());
+                  }
+                }
+              }
+
+            }
+          }
+
+          break;
+        }
+
+      }
+    }
+    return cs;
+  }
+
   private void reorderAutoannotation(AlignFrame af, Alignment al,
           ArrayList<JvAnnotRow> autoAlan)
   {
@@ -3811,14 +3973,18 @@ public class Jalview2XML
         { // make this dataset sequence sq's dataset sequence
           sq.setDatasetSequence(dsq);
           // and update the current dataset alignment
-          if (ds==null) {
-            if (dseqs!=null) {
+          if (ds == null)
+          {
+            if (dseqs != null)
+            {
               if (!dseqs.contains(dsq))
               {
                 dseqs.add(dsq);
               }
-            } else {
-              if (ds.findIndex(dsq)<0)
+            }
+            else
+            {
+              if (ds.findIndex(dsq) < 0)
               {
                 ds.addSequence(dsq);
               }
@@ -3854,7 +4020,8 @@ public class Jalview2XML
         }
         // TODO: merges will never happen if we 'know' we have the real dataset
         // sequence - this should be detected when id==dssid
-        System.err.println("DEBUG Notice:  Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
+        System.err
+                .println("DEBUG Notice:  Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
         // + (pre ? "prepended" : "") + " "
         // + (post ? "appended" : ""));
       }