JAL-1153 new runtime property set to first non-null annotation element colour
[jalview.git] / src / jalview / gui / Jalview2XML.java
index d9aca36..bde3035 100644 (file)
@@ -510,7 +510,8 @@ public class Jalview2XML
 
         if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
         {
-          jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(jal.getSequenceAt(i)).getSequencesInOrder(jal);
+          jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(
+                  jal.getSequenceAt(i)).getSequencesInOrder(jal);
 
           for (int h = 0; h < reps.length; h++)
           {
@@ -617,8 +618,8 @@ public class Jalview2XML
 
                 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
                 {
-//                  if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
-                  if (jds==jmol.jmb.sequence[peid][smap])
+                  // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
+                  if (jds == jmol.jmb.sequence[peid][smap])
                   {
                     StructureState state = new StructureState();
                     state.setVisible(true);
@@ -870,8 +871,10 @@ public class Jalview2XML
 
         an.setLabel(aa[i].label);
 
-        if (aa[i] == av.getAlignmentQualityAnnot() || aa[i] == av.getAlignmentConservationAnnotation()
-                || aa[i] == av.getAlignmentConsensusAnnotation() || aa[i].autoCalculated)
+        if (aa[i] == av.getAlignmentQualityAnnot()
+                || aa[i] == av.getAlignmentConservationAnnotation()
+                || aa[i] == av.getAlignmentConsensusAnnotation()
+                || aa[i].autoCalculated)
         {
           // new way of indicating autocalculated annotation -
           an.setAutoCalculated(aa[i].autoCalculated);
@@ -881,7 +884,7 @@ public class Jalview2XML
           an.setScore(aa[i].getScore());
         }
 
-        if (aa[i].getCalcId()!=null)
+        if (aa[i].getCalcId() != null)
         {
           calcIdSet.add(aa[i].getCalcId());
           an.setCalcId(aa[i].getCalcId());
@@ -941,7 +944,7 @@ public class Jalview2XML
     {
       JGroup[] groups = new JGroup[jal.getGroups().size()];
       int i = -1;
-      for (jalview.datamodel.SequenceGroup sg:jal.getGroups())
+      for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
       {
         groups[++i] = new JGroup();
 
@@ -1195,7 +1198,8 @@ public class Jalview2XML
         fs.addSetting(setting);
         settingsAdded.addElement(key);
       }
-      en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keySet().iterator();
+      en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
+              .keySet().iterator();
       Vector groupsAdded = new Vector();
       while (en.hasNext())
       {
@@ -1236,12 +1240,18 @@ public class Jalview2XML
         }
       }
     }
-    if (calcIdSet.size()>0)
+    if (calcIdSet.size() > 0)
     {
-      for (String calcId:calcIdSet)
+      for (String calcId : calcIdSet)
       {
-        if (calcId.trim().length()>0) {
-          view.addCalcIdParam(createCalcIdParam(calcId, av));
+        if (calcId.trim().length() > 0)
+        {
+          CalcIdParam cidp = createCalcIdParam(calcId, av);
+          // Some calcIds have no parameters.
+          if (cidp != null)
+          {
+            view.addCalcIdParam(cidp);
+          }
         }
       }
     }
@@ -1286,7 +1296,7 @@ public class Jalview2XML
       vCalcIdParam.addServiceURL(settings.getServiceURI());
       // generic URI allowing a third party to resolve another instance of the
       // service used for this calculation
-      for (String urls:settings.getServiceURLs())
+      for (String urls : settings.getServiceURLs())
       {
         vCalcIdParam.addServiceURL(urls);
       }
@@ -1305,8 +1315,8 @@ public class Jalview2XML
       // need to be able to recover 1) settings 2) user-defined presets or
       // recreate settings from preset 3) predefined settings provided by
       // service - or settings that can be transferred (or discarded)
-      vCalcIdParam.setParameters(settings
-              .getWsParamFile());
+      vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
+              "|\\n|"));
       vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
       // todo - decide if updateImmediately is needed for any projects.
 
@@ -1320,41 +1330,55 @@ public class Jalview2XML
   {
     if (calcIdParam.getVersion().equals("1.0"))
     {
-      Jws2Instance service=Jws2Discoverer.getDiscoverer().getPreferredServiceFor(calcIdParam.getServiceURL());
-      if (service!=null)
+      Jws2Instance service = Jws2Discoverer.getDiscoverer()
+              .getPreferredServiceFor(calcIdParam.getServiceURL());
+      if (service != null)
       {
-        WsParamSetI parmSet=null;
-        try {
-          service.getParamStore().parseServiceParameterFile(calcIdParam.getName(), calcIdParam.getDescription(), calcIdParam.getServiceURL(), calcIdParam.getParameters());
+        WsParamSetI parmSet = null;
+        try
+        {
+          parmSet = service.getParamStore().parseServiceParameterFile(
+                  calcIdParam.getName(), calcIdParam.getDescription(),
+                  calcIdParam.getServiceURL(),
+                  calcIdParam.getParameters().replace("|\\n|", "\n"));
         } catch (IOException x)
         {
-          warn("Couldn't parse parameter data for "+calcIdParam.getCalcId(), x);
+          warn("Couldn't parse parameter data for "
+                  + calcIdParam.getCalcId(), x);
           return false;
         }
-        List<ArgumentI> argList=null;
-        if (calcIdParam.getName().length()>0) {
-          parmSet = service.getParamStore().getPreset(calcIdParam.getName());
-          if (parmSet!=null)
+        List<ArgumentI> argList = null;
+        if (calcIdParam.getName().length() > 0)
+        {
+          parmSet = service.getParamStore()
+                  .getPreset(calcIdParam.getName());
+          if (parmSet != null)
           {
-            // TODO : check we have a good match with settings in AACons - otherwise we'll need to create a new preset
+            // TODO : check we have a good match with settings in AACons -
+            // otherwise we'll need to create a new preset
           }
         }
-        else {
+        else
+        {
           argList = parmSet.getArguments();
-          parmSet=null;
+          parmSet = null;
         }
-        AAConsSettings settings = new AAConsSettings(calcIdParam.isAutoUpdate(), service, parmSet, argList);
-        av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings, calcIdParam.isNeedsUpdate());
-      } else {
+        AAConsSettings settings = new AAConsSettings(
+                calcIdParam.isAutoUpdate(), service, parmSet, argList);
+        av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
+                calcIdParam.isNeedsUpdate());
+        return true;
+      }
+      else
+      {
         warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
         return false;
       }
     }
-    else
-      throw new Error("Unsupported Version for calcIdparam "
-              + calcIdParam.toString());
-    return false;
+    throw new Error("Unsupported Version for calcIdparam "
+            + calcIdParam.toString());
   }
+
   /**
    * External mapping between jalview objects and objects yielding a valid and
    * unique object ID string. This is null for normal Jalview project IO, but
@@ -1366,7 +1390,7 @@ public class Jalview2XML
   /**
    * Construct a unique ID for jvobj using either existing bindings or if none
    * exist, the result of the hashcode call for the object.
-   *
+   * 
    * @param jvobj
    *          jalview data object
    * @return unique ID for referring to jvobj
@@ -1397,7 +1421,7 @@ public class Jalview2XML
 
   /**
    * return local jalview object mapped to ID, if it exists
-   *
+   * 
    * @param idcode
    *          (may be null)
    * @return null or object bound to idcode
@@ -1633,7 +1657,7 @@ public class Jalview2XML
 
   /**
    * Load a jalview project archive from a jar file
-   *
+   * 
    * @param file
    *          - HTTP URL or filename
    */
@@ -1703,7 +1727,7 @@ public class Jalview2XML
    * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
    * themselves. Any null fields will be initialised with default values,
    * non-null fields are left alone.
-   *
+   * 
    * @param jprovider
    * @return
    */
@@ -1924,7 +1948,7 @@ public class Jalview2XML
         }
         ;
         out.close();
-        String t=outFile.getAbsolutePath();
+        String t = outFile.getAbsolutePath();
         alreadyLoadedPDB.put(pdbId, t);
         return t;
       }
@@ -1961,7 +1985,7 @@ public class Jalview2XML
 
   /**
    * Load alignment frame from jalview XML DOM object
-   *
+   * 
    * @param object
    *          DOM
    * @param file
@@ -2022,8 +2046,7 @@ public class Jalview2XML
           hiddenSeqs = new Vector();
         }
 
-        hiddenSeqs.addElement(seqRefIds
-                .get(seqId));
+        hiddenSeqs.addElement(seqRefIds.get(seqId));
       }
 
     }
@@ -2244,16 +2267,19 @@ public class Jalview2XML
         // Construct new annotation from model.
         AnnotationElement[] ae = an[i].getAnnotationElement();
         jalview.datamodel.Annotation[] anot = null;
-
+        java.awt.Color firstColour=null;
+        int anpos;
         if (!an[i].getScoreOnly())
         {
           anot = new jalview.datamodel.Annotation[al.getWidth()];
           for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
           {
-            if (ae[aa].getPosition() >= anot.length)
+            anpos = ae[aa].getPosition();
+
+            if (anpos >= anot.length)
               continue;
 
-            anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
+            anot[anpos] = new jalview.datamodel.Annotation(
 
             ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
                     (ae[aa].getSecondaryStructure() == null || ae[aa]
@@ -2269,8 +2295,12 @@ public class Jalview2XML
             // {
             // anot[ae[aa].getPosition()].displayCharacter = "";
             // }
-            anot[ae[aa].getPosition()].colour = new java.awt.Color(
+            anot[anpos].colour = new java.awt.Color(
                     ae[aa].getColour());
+            if (firstColour==null)
+            {
+              firstColour=anot[anpos].colour;
+            }
           }
         }
         jalview.datamodel.AlignmentAnnotation jaa = null;
@@ -2286,7 +2316,7 @@ public class Jalview2XML
                   an[i].getGraphType());
 
           jaa.graphGroup = an[i].getGraphGroup();
-
+          jaa._linecolour=firstColour;
           if (an[i].getThresholdLine() != null)
           {
             jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
@@ -2306,25 +2336,22 @@ public class Jalview2XML
         {
           jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
                   an[i].getDescription(), anot);
+          jaa._linecolour=firstColour;
         }
-        if (autoForView)
+        // register new annotation
+        if (an[i].getId() != null)
         {
-          // register new annotation
-          if (an[i].getId() != null)
-          {
-            annotationIds.put(an[i].getId(), jaa);
-            jaa.annotationId = an[i].getId();
-          }
-          // recover sequence association
-          if (an[i].getSequenceRef() != null)
+          annotationIds.put(an[i].getId(), jaa);
+          jaa.annotationId = an[i].getId();
+        }
+        // recover sequence association
+        if (an[i].getSequenceRef() != null)
+        {
+          if (al.findName(an[i].getSequenceRef()) != null)
           {
-            if (al.findName(an[i].getSequenceRef()) != null)
-            {
-              jaa.createSequenceMapping(
-                      al.findName(an[i].getSequenceRef()), 1, true);
-              al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
-                      jaa);
-            }
+            jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
+                    1, true);
+            al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
           }
         }
         // and make a note of any group association
@@ -2367,7 +2394,7 @@ public class Jalview2XML
         }
         if (an[i].hasBelowAlignment())
         {
-          jaa.belowAlignment=an[i].isBelowAlignment();
+          jaa.belowAlignment = an[i].isBelowAlignment();
         }
         jaa.setCalcId(an[i].getCalcId());
 
@@ -2734,13 +2761,12 @@ public class Jalview2XML
               }
               if (ids[p].getFile() != null)
               {
-                File mapkey=new File(ids[p].getFile());
+                File mapkey = new File(ids[p].getFile());
                 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
                         .get(mapkey);
                 if (seqstrmaps == null)
                 {
-                  ((Hashtable) jmoldat[2]).put(
-                          mapkey,
+                  ((Hashtable) jmoldat[2]).put(mapkey,
                           seqstrmaps = new Object[]
                           { pdbFile, ids[p].getId(), new Vector(),
                               new Vector() });
@@ -2837,25 +2863,28 @@ public class Jalview2XML
               {
                 newFileLoc = new StringBuffer();
               }
-              do {
+              do
+              {
                 // look for next filename in load statement
-              newFileLoc.append(state.substring(cp,
-                      ncp = (state.indexOf("\"", ncp + 1) + 1)));
-              String oldfilenam = state.substring(ncp,
-                      ecp = state.indexOf("\"", ncp));
-              // recover the new mapping data for this old filename
-              // have to normalize filename - since Jmol and jalview do filename
-              // translation differently.
-              Object[] filedat = oldFiles.get(new File(oldfilenam));
-              newFileLoc.append(Platform.escapeString((String) filedat[0]));
-              pdbfilenames.addElement((String) filedat[0]);
-              pdbids.addElement((String) filedat[1]);
-              seqmaps.addElement(((Vector<SequenceI>) filedat[2])
-                      .toArray(new SequenceI[0]));
-              newFileLoc.append("\"");
-              cp = ecp + 1; // advance beyond last \" and set cursor so we can
-                            // look for next file statement.
-              } while ((ncp=state.indexOf("/*file*/",cp))>-1);
+                newFileLoc.append(state.substring(cp,
+                        ncp = (state.indexOf("\"", ncp + 1) + 1)));
+                String oldfilenam = state.substring(ncp,
+                        ecp = state.indexOf("\"", ncp));
+                // recover the new mapping data for this old filename
+                // have to normalize filename - since Jmol and jalview do
+                // filename
+                // translation differently.
+                Object[] filedat = oldFiles.get(new File(oldfilenam));
+                newFileLoc.append(Platform
+                        .escapeString((String) filedat[0]));
+                pdbfilenames.addElement((String) filedat[0]);
+                pdbids.addElement((String) filedat[1]);
+                seqmaps.addElement(((Vector<SequenceI>) filedat[2])
+                        .toArray(new SequenceI[0]));
+                newFileLoc.append("\"");
+                cp = ecp + 1; // advance beyond last \" and set cursor so we can
+                              // look for next file statement.
+              } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
             }
             if (cp > 0)
             {
@@ -2991,8 +3020,7 @@ public class Jalview2XML
             }
             if (usetoColourbyseq)
             {
-              comp.useAlignmentPanelForColourbyseq(ap,
-                      !jmolColouring);
+              comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
             }
             else
             {
@@ -3019,8 +3047,8 @@ public class Jalview2XML
 
     for (int i = 0; i < JSEQ.length; i++)
     {
-      af.viewport.setSequenceColour(af.viewport.getAlignment().getSequenceAt(i),
-              new java.awt.Color(JSEQ[i].getColour()));
+      af.viewport.setSequenceColour(af.viewport.getAlignment()
+              .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
     }
 
     af.viewport.gatherViewsHere = view.getGatheredViews();
@@ -3142,8 +3170,8 @@ public class Jalview2XML
               if (view.getAnnotationColours().getColourScheme()
                       .equals("None"))
               {
-                cs = new AnnotationColourGradient(
-                        af.viewport.getAlignment().getAlignmentAnnotation()[i],
+                cs = new AnnotationColourGradient(af.viewport
+                        .getAlignment().getAlignmentAnnotation()[i],
                         new java.awt.Color(view.getAnnotationColours()
                                 .getMinColour()), new java.awt.Color(view
                                 .getAnnotationColours().getMaxColour()),
@@ -3152,16 +3180,16 @@ public class Jalview2XML
               else if (view.getAnnotationColours().getColourScheme()
                       .startsWith("ucs"))
               {
-                cs = new AnnotationColourGradient(
-                        af.viewport.getAlignment().getAlignmentAnnotation()[i],
+                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],
+                cs = new AnnotationColourGradient(af.viewport
+                        .getAlignment().getAlignmentAnnotation()[i],
                         ColourSchemeProperty.getColour(al, view
                                 .getAnnotationColours().getColourScheme()),
                         view.getAnnotationColours().getAboveThreshold());
@@ -3172,8 +3200,8 @@ public class Jalview2XML
               {
                 for (int g = 0; g < al.getGroups().size(); g++)
                 {
-                  jalview.datamodel.SequenceGroup sg = al
-                          .getGroups().get(g);
+                  jalview.datamodel.SequenceGroup sg = al.getGroups()
+                          .get(g);
 
                   if (sg.cs == null)
                   {
@@ -3192,8 +3220,8 @@ public class Jalview2XML
                    * view.getAnnotationColours().getAboveThreshold()); } else
                    */
                   {
-                    sg.cs = new AnnotationColourGradient(
-                            af.viewport.getAlignment().getAlignmentAnnotation()[i],
+                    sg.cs = new AnnotationColourGradient(af.viewport
+                            .getAlignment().getAlignmentAnnotation()[i],
                             sg.cs, view.getAnnotationColours()
                                     .getAboveThreshold());
                   }
@@ -3241,8 +3269,8 @@ public class Jalview2XML
     }
     if (view.hasIgnoreGapsinConsensus())
     {
-      af.viewport.setIgnoreGapsConsensus(view
-              .getIgnoreGapsinConsensus(), null);
+      af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
+              null);
     }
     if (view.hasFollowHighlight())
     {
@@ -3368,7 +3396,23 @@ public class Jalview2XML
                 );
       }
     }
-
+    if (view.getCalcIdParam() != null)
+    {
+      for (CalcIdParam calcIdParam : view.getCalcIdParam())
+      {
+        if (calcIdParam != null)
+        {
+          if (recoverCalcIdParam(calcIdParam, af.viewport))
+          {
+          }
+          else
+          {
+            warn("Couldn't recover parameters for "
+                    + calcIdParam.getCalcId());
+          }
+        }
+      }
+    }
     af.setMenusFromViewport(af.viewport);
     // TODO: we don't need to do this if the viewport is aready visible.
     Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
@@ -3398,21 +3442,34 @@ public class Jalview2XML
       }
       for (JvAnnotRow auan : autoAlan)
       {
-        visan.put(auan.template.label, auan);
+        visan.put(auan.template.label
+                + (auan.template.getCalcId() == null ? "" : "\t"
+                        + auan.template.getCalcId()), auan);
       }
       int hSize = al.getAlignmentAnnotation().length;
       ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
+      // 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)
         {
-          JvAnnotRow valan = visan.get(jalan.label);
+          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(al.getAlignmentAnnotation()[h], false);
+            al.deleteAnnotation(jalan, false);
+            remains.remove(k);
             hSize--;
             h--;
             if (valan != nullAnnot)
@@ -3434,6 +3491,18 @@ public class Jalview2XML
           }
         }
       }
+      // 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)