{
return loadFile(filepath);
}
+
+ @Override
+ public StructureCommandI closeViewer()
+ {
+ return null; // not an external viewer
+ }
}
return new StructureCommand("load", filepath, "", "0", "pse");
}
+ @Override
+ public StructureCommandI closeViewer()
+ {
+ // https://pymolwiki.org/index.php/Quit
+ return new StructureCommand("quit");
+ }
+
}
return launched;
}
- public void exitPymol()
- {
- if (isPymolLaunched() && pymolProcess != null)
- {
- sendCommand(new StructureCommand("quit"), false);
- }
- pymolProcess = null;
- // currentModelsMap.clear();
- this.pymolXmlRpcPort = 0;
- }
-
/**
* Sends the command to Pymol; if requested, tries to get and return any
* replies, else returns null
return sb.toString();
}
- public boolean launchPymol()
+ public Process launchPymol()
{
// todo pull up much of this
// Do nothing if already launched
if (isPymolLaunched())
{
- return true;
+ return pymolProcess;
}
String error = "Error message: ";
break;
} catch (Exception e)
{
- // pPymol could not be started using this path
+ // Pymol could not be started using this path
error += e.getMessage();
}
}
- if (error.length() == 0)
+
+ if (pymolProcess != null)
{
this.pymolXmlRpcPort = getPortNumber();
- System.out.println(
- "PyMOL XMLRPC started on port " + pymolXmlRpcPort);
- return (pymolXmlRpcPort > 0);
+ if (pymolXmlRpcPort > 0)
+ {
+ Cache.log.info("PyMOL XMLRPC started on port " + pymolXmlRpcPort);
+ }
+ else
+ {
+ error += "Failed to read PyMOL XMLRPC port number";
+ Cache.log.error(error);
+ pymolProcess.destroy();
+ pymolProcess = null;
+ }
}
- // logger.warn(error);
- return false;
+ return pymolProcess;
}
private int getPortNumber()
}
} catch (Exception e)
{
- System.err.println(
- "Failed to get REST port number from " + responses + ": "
- + e.getMessage());
+ Cache.log.error("Failed to get REST port number from " + responses
+ + ": " + e.getMessage());
// logger.error("Failed to get REST port number from " + responses + ": "
// + e.getMessage());
} finally
}
if (port == 0)
{
- System.err.println("Failed to start PyMOL with XMLRPC, response was: "
+ Cache.log.error("Failed to start PyMOL with XMLRPC, response was: "
+ responses);
}
- System.err.println("PyMOL started with XMLRPC on port " + port);
+ Cache.log.error("PyMOL started with XMLRPC on port " + port);
return port;
}
return new StructureCommand("open chimera:" + filepath);
}
+ @Override
+ public StructureCommandI closeViewer()
+ {
+ // https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/stop.html
+ return new StructureCommand("stop really");
+ }
+
}
// this version of the command has no dependency on file extension
return new StructureCommand("open " + filepath + " format session");
}
+
+ @Override
+ public StructureCommandI closeViewer()
+ {
+ // https://www.cgl.ucsf.edu/chimerax/docs/user/commands/exit.html
+ return new StructureCommand("exit");
+ }
}
import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
import jalview.api.AlignmentViewPanel;
-import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.PDBEntry;
String lastHighlightCommand;
- private Thread chimeraMonitor;
-
/**
* Open a PDB structure file in Chimera and set up mappings from Jalview.
*
}
/**
- * 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 = chimeraManager.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();
- }
-
- /**
* Start a dedicated HttpServer to listen for Chimera notifications, and tell it
* to start listening
*/
public void closeViewer(boolean closeChimera)
{
super.closeViewer(closeChimera);
- if (closeChimera)
- {
- chimeraManager.exitChimera();
- }
if (this.chimeraListener != null)
{
chimeraListener.shutdown();
chimeraListener = null;
}
+ chimeraManager.clearOnChimeraExit();
chimeraManager = null;
-
- if (chimeraMonitor != null)
- {
- chimeraMonitor.interrupt();
- }
}
/**
boolean launched = chimeraManager.launchChimera(getChimeraPaths());
if (launched)
{
- startChimeraProcessMonitor();
+ startExternalViewerMonitor(chimeraManager.getChimeraProcess());
}
else
{
atomSpecs.add(spec);
} catch (IllegalArgumentException e)
{
- System.err.println("Failed to parse atomspec: " + atomSpec);
+ Cache.log.error("Failed to parse atomspec: " + atomSpec);
}
}
return atomSpecs;
import java.util.Map;
import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.ext.pymol.PymolCommands;
private PymolManager pymolManager;
- private Thread pymolMonitor;
-
/*
* full paths to structure files opened in PyMOL
*/
public void closeViewer(boolean closePymol)
{
super.closeViewer(closePymol);
- if (closePymol)
- {
- pymolManager.exitPymol();
- }
pymolManager = null;
-
- if (pymolMonitor != null)
- {
- pymolMonitor.interrupt();
- }
}
public boolean launchPymol()
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!");
+ Cache.log.error("Failed to launch PyMOL!");
}
- return launched;
+ return pymol != null;
}
public void openFile(PDBEntry pe)
* @return
*/
StructureCommandI openSession(String filepath);
+
+ /**
+ * Returns a command to ask the viewer to close down
+ * @return
+ */
+ StructureCommandI closeViewer();
}
public String fileLoadingError;
+ protected Thread externalViewerMonitor;
+
/**
* Constructor
*
boolean getReply);
/**
- * A helper method that converts list of commands to a vararg array
- *
- * @param commands
- * @param getReply
- * @param msg
- */
- protected List<String> executeCommands(
- List<StructureCommandI> commands,
- boolean getReply, String msg)
- {
- return executeCommands(getReply, msg,
- commands.toArray(new StructureCommandI[commands.size()]));
- }
-
- /**
* Executes one or more structure viewer commands. If a progress message is
* provided, it is shown first, and removed after all commands have been run.
*
+ * @param commands
* @param getReply
* @param msg
- * @param commands
- * @return
*/
- protected List<String> executeCommands(boolean getReply, String msg,
- StructureCommandI[] commands)
+ protected List<String> executeCommands(List<StructureCommandI> commands,
+ boolean getReply, String msg)
{
- // todo: tidy this up
-
/*
* show progress message if specified
*/
final JalviewStructureDisplayI theViewer = getViewer();
final long handle = msg == null ? 0 : theViewer.startProgressBar(msg);
-
+
List<String> response = getReply ? new ArrayList<>() : null;
try
{
/**
* Closes Jalview's structure viewer panel and releases associated resources.
* If it is managing an external viewer program, and {@code forceClose} is
- * true, also shuts down that program.
+ * true, also asks that program to close.
*
* @param forceClose
*/
getSsm().removeStructureViewerListener(this, this.getStructureFiles());
releaseUIResources();
- // add external viewer shutdown in overrides
- // todo - or can maybe pull up to here
+ /*
+ * end the thread that closes this panel if the external viewer closes
+ */
+ if (externalViewerMonitor != null)
+ {
+ externalViewerMonitor.interrupt();
+ externalViewerMonitor = null;
+ }
+
+ if (forceClose)
+ {
+ StructureCommandI cmd = getCommandGenerator().closeViewer();
+ if (cmd != null)
+ {
+ executeCommand(cmd, false);
+ }
+ }
}
/**
String[] files = getStructureFiles();
return files == null ? 0 : files.length;
}
+
+ /**
+ * Starts a thread that waits for the external viewer program process to
+ * finish, so that we can then close the associated resources. This avoids
+ * leaving orphaned viewer panels in Jalview if the user closes the external
+ * viewer.
+ *
+ * @param p
+ */
+ protected void startExternalViewerMonitor(Process p)
+ {
+ externalViewerMonitor = 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
+ }
+ }
+ });
+ externalViewerMonitor.start();
+ }
}