JAL-1636 typed collections now in ResidueProperties
[jalview.git] / src / jalview / ext / jmol / JalviewJmolBinding.java
index 1a8fa2d..30998bd 100644 (file)
@@ -32,9 +32,12 @@ import jalview.datamodel.SequenceI;
 import jalview.io.AppletFormatAdapter;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
+import jalview.structure.AtomSpec;
 import jalview.structure.StructureListener;
 import jalview.structure.StructureMapping;
 import jalview.structure.StructureSelectionManager;
+import jalview.structures.models.SequenceStructureBindingModel;
+import jalview.util.MessageManager;
 
 import java.awt.Color;
 import java.awt.Container;
@@ -43,8 +46,8 @@ import java.awt.event.ComponentListener;
 import java.io.File;
 import java.net.URL;
 import java.security.AccessControlException;
-import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
@@ -56,26 +59,13 @@ import org.jmol.api.JmolViewer;
 import org.jmol.constant.EnumCallback;
 import org.jmol.popup.JmolPopup;
 
-public abstract class JalviewJmolBinding implements StructureListener,
+public abstract class JalviewJmolBinding extends SequenceStructureBindingModel implements StructureListener,
         JmolStatusListener, SequenceStructureBinding,
         JmolSelectionListener, ComponentListener,
         StructureSelectionManagerProvider
 
 {
   /**
-   * set if Jmol state is being restored from some source - instructs binding
-   * not to apply default display style when structure set is updated for first
-   * time.
-   */
-  private boolean loadingFromArchive = false;
-  
-  /**
-   * second flag to indicate if the jmol viewer should ignore sequence colouring
-   * events from the structure manager because the GUI is still setting up
-   */
-  private boolean loadingFinished = true;
-
-  /**
    * state flag used to check if the Jmol viewer's paint method can be called
    */
   private boolean finishedInit = false;
@@ -243,7 +233,9 @@ public abstract class JalviewJmolBinding implements StructureListener,
               + (1 + getModelNum((String) chainFile.get(lbl))) + " or ");
     }
     if (cmd.length() > 0)
+    {
       cmd.setLength(cmd.length() - 4);
+    }
     evalStateCommand("select *;restrict " + cmd + ";cartoon;center " + cmd);
   }
 
@@ -330,13 +322,15 @@ public abstract class JalviewJmolBinding implements StructureListener,
 
     String[] files = getPdbFile();
     // check to see if we are still waiting for Jmol files
-    long starttime=System.currentTimeMillis();
-    boolean waiting=true;
-    do {
-      waiting=false;
-      for (String file:files)
+    long starttime = System.currentTimeMillis();
+    boolean waiting = true;
+    do
+    {
+      waiting = false;
+      for (String file : files)
       {
-        try {
+        try
+        {
           // HACK - in Jalview 2.8 this call may not be threadsafe so we catch
           // every possible exception
           StructureMapping[] sm = ssm.getMapping(file);
@@ -353,10 +347,12 @@ public abstract class JalviewJmolBinding implements StructureListener,
         }
       }
       // we wait around for a reasonable time before we give up
-    } while (waiting && System.currentTimeMillis()<(10000+1000*files.length+starttime));
+    } while (waiting
+            && System.currentTimeMillis() < (10000 + 1000 * files.length + starttime));
     if (waiting)
     {
-      System.err.println("RUNTIME PROBLEM: Jmol seems to be taking a long time to process all the structures.");
+      System.err
+              .println("RUNTIME PROBLEM: Jmol seems to be taking a long time to process all the structures.");
       return;
     }
     StringBuffer selectioncom = new StringBuffer();
@@ -420,7 +416,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
         // Jmol callback has completed.
         if (mapping == null || mapping.length < 1)
         {
-          throw new Error("Implementation error - Jmol seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016");
+          throw new Error(MessageManager.getString("error.implementation_error_jmol_getting_data"));
         }
         int lastPos = -1;
         for (int s = 0; s < sequence[pdbfnum].length; s++)
@@ -486,7 +482,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
           }
         }
       }
-      
+
       // TODO: consider bailing if nmatched less than 4 because superposition
       // not
       // well defined.
@@ -558,14 +554,17 @@ public abstract class JalviewJmolBinding implements StructureListener,
             {
               selectioncom.append("|");
             }
-          } else {
+          }
+          else
+          {
             selcom[pdbfnum] = null;
           }
         }
       }
       for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
       {
-        if (pdbfnum == refStructure || selcom[pdbfnum]==null || selcom[refStructure]==null)
+        if (pdbfnum == refStructure || selcom[pdbfnum] == null
+                || selcom[refStructure] == null)
         {
           continue;
         }
@@ -574,7 +573,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
         command.append(chainNames[pdbfnum]);
         command.append(") against reference (");
         command.append(chainNames[refStructure]);
-        command.append(")\";\ncompare "+nSeconds);
+        command.append(")\";\ncompare " + nSeconds);
         command.append("{");
         command.append(1 + pdbfnum);
         command.append(".1} {");
@@ -633,8 +632,10 @@ public abstract class JalviewJmolBinding implements StructureListener,
   public void colourBySequence(boolean showFeatures,
           jalview.api.AlignmentViewPanel alignmentv)
   {
-    if (!colourBySequence || !loadingFinished)
+    if (!colourBySequence || !isLoadingFinished())
+    {
       return;
+    }
     if (ssm == null)
     {
       return;
@@ -653,10 +654,12 @@ public abstract class JalviewJmolBinding implements StructureListener,
     for (jalview.structure.StructureMappingcommandSet cpdbbyseq : JmolCommands
             .getColourBySequenceCommand(ssm, files, sequence, sr, fr,
                     alignment))
+    {
       for (String cbyseq : cpdbbyseq.commands)
       {
         evalStateCommand(cbyseq);
       }
+    }
   }
 
   public boolean isColourBySequence()
@@ -706,7 +709,9 @@ public abstract class JalviewJmolBinding implements StructureListener,
           String pdbfile)
   {
     if (getModelNum(pdbfile) < 0)
+    {
       return null;
+    }
     // TODO: verify atomIndex is selecting correct model.
     return new Color(viewer.getAtomArgb(atomIndex));
   }
@@ -739,7 +744,9 @@ public abstract class JalviewJmolBinding implements StructureListener,
     for (int i = 0; i < mfn.length; i++)
     {
       if (mfn[i].equalsIgnoreCase(modelFileName))
+      {
         return i;
+      }
     }
     return -1;
   }
@@ -835,64 +842,76 @@ public abstract class JalviewJmolBinding implements StructureListener,
     jmolpopup.show(x, y);
   }
 
-  // jmol/ssm only
-  public void highlightAtom(int atomIndex, int pdbResNum, String chain,
-          String pdbfile)
+  /**
+   * Highlight the specified atoms in the structure.
+   * 
+   * @param atoms
+   */
+  @Override
+  public void highlightAtoms(List<AtomSpec> atoms)
   {
     if (modelFileNames == null)
     {
       return;
     }
 
-    // look up file model number for this pdbfile
-    int mdlNum = 0;
-    String fn;
-    // may need to adjust for URLencoding here - we don't worry about that yet.
-    while (mdlNum < modelFileNames.length
-            && !pdbfile.equals(modelFileNames[mdlNum]))
-    {
-      // System.out.println("nomatch:"+pdbfile+"\nmodelfn:"+fn);
-      mdlNum++;
-    }
-    if (mdlNum == modelFileNames.length)
+    for (AtomSpec atom : atoms)
     {
-      return;
-    }
+      String pdbfile = atom.getPdbId();
+      int pdbResNum = atom.getPdbResNum();
+      String chain = atom.getChain();
+
+      // look up file model number for this pdbfile
+      int mdlNum = 0;
+      String fn;
+      // may need to adjust for URLencoding here - we don't worry about that
+      // yet.
+      while (mdlNum < modelFileNames.length
+              && !pdbfile.equals(modelFileNames[mdlNum]))
+      {
+        // System.out.println("nomatch:"+pdbfile+"\nmodelfn:"+fn);
+        mdlNum++;
+      }
+      if (mdlNum == modelFileNames.length)
+      {
+        return;
+      }
 
-    jmolHistory(false);
-    // if (!pdbfile.equals(pdbentry.getFile()))
-    // return;
-    if (resetLastRes.length() > 0)
-    {
-      viewer.evalStringQuiet(resetLastRes.toString());
-    }
+      jmolHistory(false);
+      // if (!pdbfile.equals(pdbentry.getFile()))
+      // return;
+      if (resetLastRes.length() > 0)
+      {
+        viewer.evalStringQuiet(resetLastRes.toString());
+      }
 
-    eval.setLength(0);
-    eval.append("select " + pdbResNum); // +modelNum
+      eval.setLength(0);
+      eval.append("select " + pdbResNum); // +modelNum
 
-    resetLastRes.setLength(0);
-    resetLastRes.append("select " + pdbResNum); // +modelNum
+      resetLastRes.setLength(0);
+      resetLastRes.append("select " + pdbResNum); // +modelNum
 
-    eval.append(":");
-    resetLastRes.append(":");
-    if (!chain.equals(" "))
-    {
-      eval.append(chain);
-      resetLastRes.append(chain);
-    }
-    {
-      eval.append(" /" + (mdlNum + 1));
-      resetLastRes.append("/" + (mdlNum + 1));
-    }
-    eval.append(";wireframe 100;" + eval.toString() + " and not hetero;");
+      eval.append(":");
+      resetLastRes.append(":");
+      if (!chain.equals(" "))
+      {
+        eval.append(chain);
+        resetLastRes.append(chain);
+      }
+      {
+        eval.append(" /" + (mdlNum + 1));
+        resetLastRes.append("/" + (mdlNum + 1));
+      }
+      eval.append(";wireframe 100;" + eval.toString() + " and not hetero;");
 
-    resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
-            + " and not hetero; spacefill 0;");
+      resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
+              + " and not hetero; spacefill 0;");
 
-    eval.append("spacefill 200;select none");
+      eval.append("spacefill 200;select none");
 
-    viewer.evalStringQuiet(eval.toString());
-    jmolHistory(true);
+      viewer.evalStringQuiet(eval.toString());
+      jmolHistory(true);
+    }
 
   }
 
@@ -948,8 +967,10 @@ public abstract class JalviewJmolBinding implements StructureListener,
     String chainId;
 
     if (strInfo.indexOf(":") > -1)
+    {
       chainId = strInfo.substring(strInfo.indexOf(":") + 1,
               strInfo.indexOf("."));
+    }
     else
     {
       chainId = " ";
@@ -987,7 +1008,9 @@ public abstract class JalviewJmolBinding implements StructureListener,
       ;
     }
     if (lastMessage == null || !lastMessage.equals(strInfo))
+    {
       ssm.mouseOverStructure(pdbResNum, chainId, pdbfilename);
+    }
 
     lastMessage = strInfo;
   }
@@ -1021,13 +1044,17 @@ public abstract class JalviewJmolBinding implements StructureListener,
     int chainSeparator = strInfo.indexOf(":");
     int p = 0;
     if (chainSeparator == -1)
+    {
       chainSeparator = strInfo.indexOf(".");
+    }
 
     String picked = strInfo.substring(strInfo.indexOf("]") + 1,
             chainSeparator);
     String mdlString = "";
     if ((p = strInfo.indexOf(":")) > -1)
+    {
       picked += strInfo.substring(p + 1, strInfo.indexOf("."));
+    }
 
     if ((p = strInfo.indexOf("/")) > -1)
     {
@@ -1275,7 +1302,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
             for (int i = 0; i < pdb.chains.size(); i++)
             {
               String chid = new String(pdb.id + ":"
-                      + ((MCview.PDBChain) pdb.chains.elementAt(i)).id);
+                      + pdb.chains.elementAt(i).id);
               chainFile.put(chid, fileName);
               chainNames.addElement(chid);
             }
@@ -1368,21 +1395,23 @@ public abstract class JalviewJmolBinding implements StructureListener,
     colourBySequence = false;
 
     if (cs == null)
+    {
       return;
+    }
 
-    String res;
     int index;
     Color col;
     jmolHistory(false);
     // TODO: Switch between nucleotide or aa selection expressions
-    Enumeration en = ResidueProperties.aa3Hash.keys();
-    StringBuffer command = new StringBuffer("select *;color white;");
-    while (en.hasMoreElements())
+    StringBuilder command = new StringBuilder(128);
+    command.append("select *;color white;");
+    for (String res : ResidueProperties.aa3Hash.keySet())
     {
-      res = en.nextElement().toString();
-      index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();
+      index = ResidueProperties.aa3Hash.get(res).intValue();
       if (index > 20)
+      {
         continue;
+      }
 
       col = cs.findColour(ResidueProperties.aa[index].charAt(0));
 
@@ -1501,30 +1530,6 @@ public abstract class JalviewJmolBinding implements StructureListener,
     showConsole(false);
   }
 
-  public void setLoadingFromArchive(boolean loadingFromArchive)
-  {
-    this.loadingFromArchive = loadingFromArchive;
-  }
-  
-  /**
-   * 
-   * @return true if Jmol is still restoring state or loading is still going on (see setFinsihedLoadingFromArchive)
-   */
-  public boolean isLoadingFromArchive()
-  {
-    return loadingFromArchive && !loadingFinished;
-  }
-
-  /**
-   * modify flag which controls if sequence colouring events are honoured by the binding. 
-   * Should be true for normal operation
-   * @param finishedLoading
-   */
-  public void setFinishedLoadingFromArchive(boolean finishedLoading)
-  {
-    loadingFinished = finishedLoading;
-  }
-
   public void setBackgroundColour(java.awt.Color col)
   {
     jmolHistory(false);
@@ -1602,9 +1607,7 @@ public abstract class JalviewJmolBinding implements StructureListener,
   {
     if (pe < 0 || pe >= pdbentry.length)
     {
-      throw new Error(
-              "Implementation error - no corresponding pdbentry (for index "
-                      + pe + ") to add sequences mappings to");
+      throw new Error(MessageManager.formatMessage("error.implementation_error_no_pdbentry_from_index", new String[]{Integer.valueOf(pe).toString()}));
     }
     final String nullChain = "TheNullChain";
     Vector s = new Vector();