Merge branch 'develop' into features/JAL-2295setChimeraAttributes
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 2 Dec 2016 15:17:37 +0000 (15:17 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 2 Dec 2016 15:17:37 +0000 (15:17 +0000)
Conflicts:
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java

src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/AppJmolBinding.java
src/jalview/gui/JalviewChimeraBindingModel.java
src/jalview/structures/models/AAStructureBindingModel.java

index 699ca59..85ae718 100644 (file)
@@ -380,6 +380,8 @@ public class ChimeraManager
       sendChimeraCommand("stop really", false);
       try
       {
+        // TODO is this too violent? could it force close the process
+        // before it has done an orderly shutdown?
         chimera.destroy();
       } catch (Exception ex)
       {
@@ -891,4 +893,9 @@ public class ChimeraManager
   {
     return busy;
   }
+
+  public Process getChimeraProcess()
+  {
+    return chimera;
+  }
 }
index 1ff0466..75ddc9c 100644 (file)
@@ -23,6 +23,7 @@ package jalview.ext.rbvi.chimera;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureRenderer;
 import jalview.api.SequenceRenderer;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
@@ -118,6 +119,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    */
   private long loadNotifiesHandled = 0;
 
+  private Thread chimeraMonitor;
+
   /**
    * Open a PDB structure file in Chimera and set up mappings from Jalview.
    * 
@@ -201,8 +204,38 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
           PDBEntry[] pdbentry, SequenceI[][] sequenceIs, DataSourceType protocol)
   {
     super(ssm, pdbentry, sequenceIs, protocol);
-    viewer = new ChimeraManager(
-            new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true));
+    viewer = new ChimeraManager(new StructureManager(true));
+  }
+
+  /**
+   * Starts a thread that waits for the Chimera process to finish, so that we
+   * can then close the associated resources. This avoids leaving orphaned
+   * Chimera viewer panels in Jalview if the user closes Chimera.
+   */
+  protected void startChimeraProcessMonitor()
+  {
+    final Process p = viewer.getChimeraProcess();
+    chimeraMonitor = new Thread(new Runnable()
+    {
+
+      @Override
+      public void run()
+      {
+        try
+        {
+          p.waitFor();
+          JalviewStructureDisplayI display = getViewer();
+          if (display != null)
+          {
+            display.closeViewer(false);
+          }
+        } catch (InterruptedException e)
+        {
+          // exit thread if Chimera Viewer is closed in Jalview
+        }
+      }
+    });
+    chimeraMonitor.start();
   }
 
   /**
@@ -289,6 +322,10 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     }
     viewer = null;
 
+    if (chimeraMonitor != null)
+    {
+      chimeraMonitor.interrupt();
+    }
     releaseUIResources();
   }
 
@@ -569,23 +606,29 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   /**
    * Launch Chimera, unless an instance linked to this object is already
-   * running. Returns true if chimera is successfully launched, or already
+   * running. Returns true if Chimera is successfully launched, or already
    * running, else false.
    * 
    * @return
    */
   public boolean launchChimera()
   {
-    if (!viewer.isChimeraLaunched())
-    {
-      return viewer.launchChimera(StructureManager.getChimeraPaths());
-    }
     if (viewer.isChimeraLaunched())
     {
       return true;
     }
-    log("Failed to launch Chimera!");
-    return false;
+
+    boolean launched = viewer.launchChimera(StructureManager
+            .getChimeraPaths());
+    if (launched)
+    {
+      startChimeraProcessMonitor();
+    }
+    else
+    {
+      log("Failed to launch Chimera!");
+    }
+    return launched;
   }
 
   /**
index 4d7f7cf..75e0c5e 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.gui;
 
 import jalview.api.AlignmentViewPanel;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
@@ -208,4 +209,10 @@ public class AppJmolBinding extends JalviewJmolBinding
     // TODO Auto-generated method stub
     return null;
   }
+
+  @Override
+  public JalviewStructureDisplayI getViewer()
+  {
+    return appJmolWindow;
+  }
 }
index c1f15e5..8d11ca0 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.gui;
 
 import jalview.api.AlignmentViewPanel;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.ext.rbvi.chimera.JalviewChimeraBinding;
@@ -148,5 +149,9 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
 
   }
 
-
+  @Override
+  public JalviewStructureDisplayI getViewer()
+  {
+    return cvf;
+  }
 }
index 6846de0..063eacf 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.structures.models;
 
 import jalview.api.StructureSelectionManagerProvider;
+import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
@@ -678,4 +679,13 @@ public abstract class AAStructureBindingModel extends
    */
   public abstract List<String> getChainNames();
 
+  /**
+   * Returns the Jalview panel hosting the structure viewer (if any)
+   * 
+   * @return
+   */
+  public JalviewStructureDisplayI getViewer()
+  {
+    return null;
+  }
 }