JAL-2089 patch broken merge to master for Release 2.10.0b1
[jalview.git] / src / jalview / ext / rbvi / chimera / JalviewChimeraBinding.java
index b648bea..7ba9186 100644 (file)
  */
 package jalview.ext.rbvi.chimera;
 
-import java.awt.Color;
-import java.net.BindException;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager;
-import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel;
-import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
-import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
-
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureRenderer;
 import jalview.api.SequenceRenderer;
@@ -49,6 +37,18 @@ import jalview.structure.StructureSelectionManager;
 import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.MessageManager;
 
+import java.awt.Color;
+import java.net.BindException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager;
+import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel;
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
+
 public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 {
   // Chimera clause to exclude alternate locations in atom selection
@@ -101,16 +101,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   private String lastCommand;
 
-  private boolean loadedInline;
-
-  /**
-   * current set of model filenames loaded
-   */
-  String[] modelFileNames = null;
-
-  String lastMousedOverAtomSpec;
-
-  private List<String> lastReply;
+  String lastHighlightCommand;
 
   /*
    * incremented every time a load notification is successfully handled -
@@ -608,11 +599,17 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    */
   public void sendChimeraCommand(final String command, boolean logResponse)
   {
+    if (viewer == null)
+    {
+      // ? thread running after viewer shut down
+      return;
+    }
     viewerCommandHistory(false);
     if (lastCommand == null || !lastCommand.equals(command))
     {
       // trim command or it may never find a match in the replyLog!!
-      lastReply = viewer.sendChimeraCommand(command.trim(), logResponse);
+      List<String> lastReply = viewer.sendChimeraCommand(command.trim(),
+              logResponse);
       if (logResponse && debug)
       {
         log("Response from command ('" + command + "') was:\n" + lastReply);
@@ -710,17 +707,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   // End StructureListener
   // //////////////////////////
 
-  public Color getColour(int atomIndex, int pdbResNum, String chain,
-          String pdbfile)
-  {
-    if (getModelNum(pdbfile) < 0)
-    {
-      return null;
-    }
-    log("get model / residue colour attribute unimplemented");
-    return null;
-  }
-
   /**
    * returns the current featureRenderer that should be used to colour the
    * structures
@@ -790,15 +776,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   }
 
   /**
-   * map from string to applet
-   */
-  public Map getRegistryInfo()
-  {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  /**
    * returns the current sequenceRenderer that should be used to colour the
    * structures
    * 
@@ -810,22 +787,22 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
           AlignmentViewPanel alignment);
 
   /**
-   * Construct and send a command to highlight zero, one or more atoms.
-   * 
-   * <pre>
-   * Done by generating a command like (to 'highlight' position 44)
-   *   show #0:44.C
-   * </pre>
+   * Construct and send a command to highlight zero, one or more atoms. We do
+   * this by sending an "rlabel" command to show the residue label at that
+   * position.
    */
   @Override
   public void highlightAtoms(List<AtomSpec> atoms)
   {
-    if (atoms == null)
+    if (atoms == null || atoms.size() == 0)
     {
       return;
     }
-    StringBuilder atomSpecs = new StringBuilder();
+
+    StringBuilder cmd = new StringBuilder(128);
     boolean first = true;
+    boolean found = false;
+
     for (AtomSpec atom : atoms)
     {
       int pdbResNum = atom.getPdbResNum();
@@ -834,39 +811,46 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       List<ChimeraModel> cms = chimeraMaps.get(pdbfile);
       if (cms != null && !cms.isEmpty())
       {
-        /*
-         * Formatting as #0:34.A,#1:33.A doesn't work as desired, so instead we
-         * concatenate multiple 'show' commands
-         */
-        atomSpecs.append(first ? "" : ";show ");
+        if (first)
+        {
+          cmd.append("rlabel #").append(cms.get(0).getModelNumber())
+                  .append(":");
+        }
+        else
+        {
+          cmd.append(",");
+        }
         first = false;
-        atomSpecs.append("#" + cms.get(0).getModelNumber());
-        atomSpecs.append(":" + pdbResNum);
+        cmd.append(pdbResNum);
         if (!chain.equals(" "))
         {
-          atomSpecs.append("." + chain);
+          cmd.append(".").append(chain);
         }
+        found = true;
       }
     }
-    String atomSpec = atomSpecs.toString();
+    String command = cmd.toString();
 
     /*
-     * Avoid repeated commands for the same residue
+     * avoid repeated commands for the same residue
      */
-    if (atomSpec.equals(lastMousedOverAtomSpec))
+    if (command.equals(lastHighlightCommand))
     {
       return;
     }
 
-    StringBuilder command = new StringBuilder(32);
-    viewerCommandHistory(false);
-    if (atomSpec.length() > 0)
+    /*
+     * unshow the label for the previous residue
+     */
+    if (lastHighlightCommand != null)
     {
-      command.append("show ").append(atomSpec);
-      viewer.sendChimeraCommand(command.toString(), false);
+      viewer.sendChimeraCommand("~" + lastHighlightCommand, false);
     }
-    viewerCommandHistory(true);
-    this.lastMousedOverAtomSpec = atomSpec;
+    if (found)
+    {
+      viewer.sendChimeraCommand(command, false);
+    }
+    this.lastHighlightCommand = command;
   }
 
   /**
@@ -989,6 +973,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    */
   public abstract void refreshGUI();
 
+  @Override
   public void setLoadingFromArchive(boolean loadingFromArchive)
   {
     this.loadingFromArchive = loadingFromArchive;
@@ -999,6 +984,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    * @return true if Chimeral is still restoring state or loading is still going
    *         on (see setFinsihedLoadingFromArchive)
    */
+  @Override
   public boolean isLoadingFromArchive()
   {
     return loadingFromArchive && !loadingFinished;
@@ -1010,6 +996,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    * 
    * @param finishedLoading
    */
+  @Override
   public void setFinishedLoadingFromArchive(boolean finishedLoading)
   {
     loadingFinished = finishedLoading;
@@ -1110,4 +1097,32 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   {
     sendChimeraCommand("focus", false);
   }
+
+  /**
+   * Send a 'show' command for all atoms in the currently selected columns
+   * 
+   * TODO: pull up to abstract structure viewer interface
+   * 
+   * @param vp
+   */
+  public void highlightSelection(AlignmentViewPanel vp)
+  {
+    List<Integer> cols = vp.getAlignViewport().getColumnSelection()
+            .getSelected();
+    AlignmentI alignment = vp.getAlignment();
+    StructureSelectionManager sm = getSsm();
+    for (SequenceI seq : alignment.getSequences())
+    {
+      /*
+       * convert selected columns into sequence positions
+       */
+      int[] positions = new int[cols.size()];
+      int i = 0;
+      for (Integer col : cols)
+      {
+        positions[i++] = seq.findPosition(col);
+      }
+      sm.highlightStructure(this, seq, positions);
+    }
+  }
 }