JAL-3906 use indicate to highlight current mousedOver residue in Jalview in a Pymol...
[jalview.git] / src / jalview / gui / PymolBindingModel.java
index fcf586a..6aba7b6 100644 (file)
@@ -6,12 +6,14 @@ import java.util.List;
 import java.util.Map;
 
 import jalview.api.AlignmentViewPanel;
+import jalview.bin.Console;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.ext.pymol.PymolCommands;
 import jalview.ext.pymol.PymolManager;
 import jalview.gui.StructureViewer.ViewerType;
 import jalview.structure.AtomSpec;
+import jalview.structure.AtomSpecModel;
 import jalview.structure.StructureCommand;
 import jalview.structure.StructureCommandI;
 import jalview.structure.StructureSelectionManager;
@@ -28,8 +30,6 @@ public class PymolBindingModel extends AAStructureBindingModel
 
   private PymolManager pymolManager;
 
-  private Thread pymolMonitor;
-
   /*
    * full paths to structure files opened in PyMOL
    */
@@ -70,15 +70,14 @@ public class PymolBindingModel extends AAStructureBindingModel
   public void highlightAtoms(List<AtomSpec> atoms)
   {
     /*
-     * https://pymolwiki.org/index.php/Label#examples
+     * https://pymolwiki.org/index.php/indicate#examples
      */
     StringBuilder sb = new StringBuilder();
     for (AtomSpec atom : atoms)
     {
       // todo promote to StructureCommandsI.showLabel()
-      // todo handle CA|P correctly
       String modelId = getModelIdForFile(atom.getPdbFile());
-      sb.append(String.format(" %s//%s/%d/CA", modelId,
+      sb.append(String.format(" %s//%s/%d/*", modelId,
               atom.getChain(),
               atom.getPdbResNum()));
     }
@@ -87,26 +86,16 @@ public class PymolBindingModel extends AAStructureBindingModel
     {
       return;
     }
-    StructureCommandI command = new StructureCommand("label", labelSpec, LABEL_FORMAT);
+    StructureCommandI command = new StructureCommand("indicate", labelSpec);
     executeCommand(command, false);
 
-    /*
-     * and remove the label(s) previously shown
-     */
-    if (lastLabelSpec != null)
-    {
-      command = new StructureCommand("label", lastLabelSpec, "");
-      executeCommand(command, false);
-    }
-
     lastLabelSpec = labelSpec;
   }
 
   @Override
-  public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
+  public SequenceRenderer getSequenceRenderer(AlignmentViewPanel avp)
   {
-    // pull up?
-    return new SequenceRenderer(alignment.getAlignViewport());
+    return new SequenceRenderer(avp.getAlignViewport());
   }
 
   @Override
@@ -129,33 +118,17 @@ public class PymolBindingModel extends AAStructureBindingModel
     return ViewerType.PYMOL;
   }
 
-  public boolean isPymolRunning()
+  @Override
+  public boolean isViewerRunning()
   {
     return pymolManager.isPymolLaunched();
   }
 
+  @Override
   public void closeViewer(boolean closePymol)
   {
-    getSsm().removeStructureViewerListener(this, this.getStructureFiles());
-    if (closePymol)
-    {
-      pymolManager.exitPymol();
-    }
+    super.closeViewer(closePymol);
     pymolManager = null;
-
-    if (pymolMonitor != null)
-    {
-      pymolMonitor.interrupt();
-    }
-    releaseUIResources();
-  }
-
-  public boolean openSession(String pymolSessionFile)
-  {
-    StructureCommandI cmd = getCommandGenerator()
-            .loadFile(pymolSessionFile);
-    executeCommand(cmd, false);
-    return true;
   }
 
   public boolean launchPymol()
@@ -165,16 +138,17 @@ public class PymolBindingModel extends AAStructureBindingModel
       return true;
     }
 
-    boolean launched = pymolManager.launchPymol();
-    if (launched)
+    Process pymol = pymolManager.launchPymol();
+    if (pymol != null)
     {
       // start listening for PyMOL selections - how??
+      startExternalViewerMonitor(pymol);
     }
     else
     {
-      System.err.println("Failed to launch PyMOL!");
+      Console.error("Failed to launch PyMOL!");
     }
-    return launched;
+    return pymol != null;
   }
 
   public void openFile(PDBEntry pe)
@@ -187,6 +161,21 @@ public class PymolBindingModel extends AAStructureBindingModel
      * a second parameter sets the pdbid as the loaded PyMOL object name
      */
     String pdbId = pe.getId();
+    try {
+      String safePDBId = java.net.URLEncoder.encode(pdbId,"UTF-8");
+      pdbId = safePDBId.replace('%', '_');
+      pdbId = pdbId.replace("-", "__");
+      char fc = pdbId.charAt(0);
+      // put an 's' before any numerics
+      if (fc>='0' && fc<='9')
+      {
+        pdbId = 's'+pdbId;
+      }
+//      pdbId.replace('-', 0)
+    } catch (Exception x)
+    {
+      Console.error("Unxpected encoding exception for '"+pdbId+"'",x);
+    }
     cmd.addParameter(pdbId);
 
     executeCommand(cmd, false);
@@ -221,4 +210,28 @@ public class PymolBindingModel extends AAStructureBindingModel
     return ".pse";
   }
 
+  @Override
+  public String getHelpURL()
+  {
+    return "https://pymolwiki.org/";
+  }
+
+  /**
+   * Constructs and sends commands to set atom properties for visible Jalview
+   * features on residues mapped to structure
+   * 
+   * @param avp
+   * @return
+   */
+  public int sendFeaturesToViewer(AlignmentViewPanel avp)
+  {
+    // todo pull up this and JalviewChimeraBinding variant
+    Map<String, Map<Object, AtomSpecModel>> featureValues = buildFeaturesMap(
+            avp);
+    List<StructureCommandI> commands = getCommandGenerator()
+            .setAttributes(featureValues);
+    executeCommands(commands, false, null);
+    return commands.size();
+  }
+
 }