JAL-3081 sort annotations by order read from project after reloading
[jalview.git] / src / jalview / project / Jalview2XML.java
index c017d11..eaabd47 100644 (file)
@@ -24,6 +24,7 @@ import static jalview.math.RotatableMatrix.Axis.X;
 import static jalview.math.RotatableMatrix.Axis.Y;
 import static jalview.math.RotatableMatrix.Axis.Z;
 
+import jalview.analysis.AnnotationSorter;
 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.analysis.Conservation;
 import jalview.analysis.PCA;
@@ -3622,7 +3623,7 @@ public class Jalview2XML
 
     // ////////////////////////////////
     // LOAD ANNOTATIONS
-    List<JvAnnotRow> autoAlan = new ArrayList<>();
+    List<AlignmentAnnotation> addedAnnotation = new ArrayList<>();
 
     /*
      * store any annotations which forward reference a group's ID
@@ -3713,7 +3714,11 @@ public class Jalview2XML
             }
           }
         }
-        jalview.datamodel.AlignmentAnnotation jaa = null;
+
+        /*
+         * construct the Jalview AlignmentAnnotation, add to alignment
+         */
+        AlignmentAnnotation jaa = null;
 
         if (annotation.isGraph())
         {
@@ -3811,9 +3816,10 @@ public class Jalview2XML
           jaa.autoCalculated = true; // means annotation will be marked for
           // update at end of load.
         }
-        if (annotation.getGraphHeight() != null)
+        Integer graphHeight = annotation.getGraphHeight();
+        if (graphHeight != null)
         {
-          jaa.graphHeight = annotation.getGraphHeight().intValue();
+          jaa.graphHeight = graphHeight.intValue();
         }
         jaa.belowAlignment = annotation.isBelowAlignment();
         jaa.setCalcId(annotation.getCalcId());
@@ -3825,17 +3831,16 @@ public class Jalview2XML
             jaa.setProperty(prop.getName(), prop.getValue());
           }
         }
-        if (jaa.autoCalculated)
-        {
-          autoAlan.add(new JvAnnotRow(i, jaa));
-        }
-        else
-        // if (!autoForView)
+        if (!jaa.autoCalculated)
         {
-          // add autocalculated group annotation and any user created annotation
-          // for the view
+          // TODO ensure Consensus etc is enabled if found in project?
+          /*
+           * add autocalculated group annotation and any user created annotation
+           * for the view
+           */
           al.addAnnotation(jaa);
         }
+        addedAnnotation.add(jaa);
       }
     }
     // ///////////////////////
@@ -4028,10 +4033,16 @@ public class Jalview2XML
     if (isnewview)
     {
       af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view,
-              uniqueSeqSetId, viewId, autoAlan);
-      // TODO resort annotations here to their order in the project?
+              uniqueSeqSetId, viewId);
+      // TODO restore autocalc preferences if overridden earlier?
+      /*
+       * resort annotations to their order in the project
+       * (also sets height and visibility for autocalc'd annotation)
+       */
       av = af.getViewport();
+      new AnnotationSorter(av).sort(addedAnnotation);
       ap = af.alignPanel;
+      ap.adjustAnnotationHeight();
     }
 
     /*
@@ -4839,7 +4850,7 @@ public class Jalview2XML
   AlignFrame loadViewport(String file, List<JSeq> JSEQ,
           List<SequenceI> hiddenSeqs, AlignmentI al,
           JalviewModel jm, Viewport view, String uniqueSeqSetId,
-          String viewId, List<JvAnnotRow> autoAlan)
+          String viewId)
   {
     AlignFrame af = null;
     af = new AlignFrame(al, safeInt(view.getWidth()),
@@ -5196,8 +5207,6 @@ public class Jalview2XML
               safeInt(view.getWidth()), safeInt(view.getHeight()));
       // recompute any autoannotation
       af.alignPanel.updateAnnotation(false, true);
-      reorderAutoannotation(af, al, autoAlan);
-      af.sortAnnotations(false);
       af.alignPanel.alignmentChanged();
     }
     else
@@ -5324,106 +5333,6 @@ public class Jalview2XML
     return cs;
   }
 
-  private void reorderAutoannotation(AlignFrame af, AlignmentI al,
-          List<JvAnnotRow> autoAlan)
-  {
-    // copy over visualization settings for autocalculated annotation in the
-    // view
-    if (al.getAlignmentAnnotation() != null)
-    {
-      /**
-       * Kludge for magic autoannotation names (see JAL-811)
-       */
-      String[] magicNames = new String[] { "Consensus", "Quality",
-          "Conservation" };
-      JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
-      Hashtable<String, JvAnnotRow> visan = new Hashtable<>();
-      for (String nm : magicNames)
-      {
-        visan.put(nm, nullAnnot);
-      }
-      for (JvAnnotRow auan : autoAlan)
-      {
-        visan.put(auan.template.label
-                + (auan.template.getCalcId() == null ? ""
-                        : "\t" + auan.template.getCalcId()),
-                auan);
-      }
-      int hSize = al.getAlignmentAnnotation().length;
-      List<JvAnnotRow> reorder = new ArrayList<>();
-      // work through any autoCalculated annotation already on the view
-      // removing it if it should be placed in a different location on the
-      // annotation panel.
-      List<String> remains = new ArrayList<>(visan.keySet());
-      for (int h = 0; h < hSize; h++)
-      {
-        jalview.datamodel.AlignmentAnnotation jalan = al
-                .getAlignmentAnnotation()[h];
-        if (jalan.autoCalculated)
-        {
-          String k;
-          JvAnnotRow valan = visan.get(k = jalan.label);
-          if (jalan.getCalcId() != null)
-          {
-            valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
-          }
-
-          if (valan != null)
-          {
-            // delete the auto calculated row from the alignment
-            al.deleteAnnotation(jalan, false);
-            remains.remove(k);
-            hSize--;
-            h--;
-            if (valan != nullAnnot)
-            {
-              if (jalan != valan.template)
-              {
-                // newly created autoannotation row instance
-                // so keep a reference to the visible annotation row
-                // and copy over all relevant attributes
-                if (valan.template.graphHeight >= 0)
-
-                {
-                  jalan.graphHeight = valan.template.graphHeight;
-                }
-                jalan.visible = valan.template.visible;
-              }
-              reorder.add(new JvAnnotRow(valan.order, jalan));
-            }
-          }
-        }
-      }
-      // Add any (possibly stale) autocalculated rows that were not appended to
-      // the view during construction
-      for (String other : remains)
-      {
-        JvAnnotRow othera = visan.get(other);
-        if (othera != nullAnnot && othera.template.getCalcId() != null
-                && othera.template.getCalcId().length() > 0)
-        {
-          reorder.add(othera);
-        }
-      }
-      // now put the automatic annotation in its correct place
-      int s = 0, srt[] = new int[reorder.size()];
-      JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
-      for (JvAnnotRow jvar : reorder)
-      {
-        rws[s] = jvar;
-        srt[s++] = jvar.order;
-      }
-      reorder.clear();
-      jalview.util.QuickSort.sort(srt, rws);
-      // and re-insert the annotation at its correct position
-      for (JvAnnotRow jvar : rws)
-      {
-        al.addAnnotation(jvar.template, jvar.order);
-      }
-      af.alignPanel.adjustAnnotationHeight();
-    }
-  }
-
   Hashtable skipList = null;
 
   /**