X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAppJmol.java;h=2447a2f7402f0642d862d481368b94582ea172ac;hb=57738a1f3c19b1c3a00bd3ac5108f8cd0af32f99;hp=af25653a997b35c4bf080e0a4c0dcb8cb3297e8e;hpb=2783208dc83a836be2cac47efb9877949909e781;p=jalview.git diff --git a/src/jalview/gui/AppJmol.java b/src/jalview/gui/AppJmol.java index af25653..2447a2f 100644 --- a/src/jalview/gui/AppJmol.java +++ b/src/jalview/gui/AppJmol.java @@ -20,37 +20,39 @@ */ package jalview.gui; -import jalview.bin.Cache; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.PDBEntry; -import jalview.datamodel.SequenceI; -import jalview.gui.StructureViewer.ViewerType; -import jalview.structures.models.AAStructureBindingModel; -import jalview.util.BrowserLauncher; -import jalview.util.MessageManager; -import jalview.util.Platform; -import jalview.ws.dbsources.Pdb; +import java.util.Locale; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; import java.io.File; -import java.util.ArrayList; import java.util.List; -import java.util.Vector; +import java.util.Map; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JInternalFrame; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.SwingUtilities; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; +import jalview.api.AlignmentViewPanel; +import jalview.bin.Console; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceI; +import jalview.datamodel.StructureViewerModel; +import jalview.datamodel.StructureViewerModel.StructureData; +import jalview.fts.service.alphafold.AlphafoldRestClient; +import jalview.gui.ImageExporter.ImageWriterI; +import jalview.gui.StructureViewer.ViewerType; +import jalview.structure.StructureCommand; +import jalview.structures.models.AAStructureBindingModel; +import jalview.util.BrowserLauncher; +import jalview.util.ImageMaker; +import jalview.util.MessageManager; +import jalview.util.Platform; + public class AppJmol extends StructureViewerBase { // ms to wait for Jmol to load files @@ -58,7 +60,7 @@ public class AppJmol extends StructureViewerBase private static final String SPACE = " "; - private static final String BACKSLASH = "\""; + private static final String QUOTE = "\""; AppJmolBinding jmb; @@ -87,48 +89,55 @@ public class AppJmol extends StructureViewerBase * @param bounds * @param viewid */ - public AppJmol(String[] files, String[] ids, SequenceI[][] seqs, - AlignmentPanel ap, boolean usetoColour, boolean useToAlign, - boolean leaveColouringToJmol, String loadStatus, Rectangle bounds, - String viewid) + public AppJmol(StructureViewerModel viewerModel, AlignmentPanel ap, + String sessionFile, String viewid) { - PDBEntry[] pdbentrys = new PDBEntry[files.length]; - for (int i = 0; i < pdbentrys.length; i++) - { - // PDBEntry pdbentry = new PDBEntry(files[i], ids[i]); - PDBEntry pdbentry = new PDBEntry(ids[i], null, PDBEntry.Type.PDB, - files[i]); + Map pdbData = viewerModel.getFileData(); + PDBEntry[] pdbentrys = new PDBEntry[pdbData.size()]; + SequenceI[][] seqs = new SequenceI[pdbData.size()][]; + int i = 0; + for (StructureData data : pdbData.values()) + { + PDBEntry pdbentry = new PDBEntry(data.getPdbId(), null, + PDBEntry.Type.PDB, data.getFilePath()); pdbentrys[i] = pdbentry; + List sequencesForPdb = data.getSeqList(); + seqs[i] = sequencesForPdb + .toArray(new SequenceI[sequencesForPdb.size()]); + i++; } - // / TODO: check if protocol is needed to be set, and if chains are + + // TODO: check if protocol is needed to be set, and if chains are // autodiscovered. jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(), pdbentrys, seqs, null); jmb.setLoadingFromArchive(true); addAlignmentPanel(ap); - if (useToAlign) + if (viewerModel.isAlignWithPanel()) { useAlignmentPanelForSuperposition(ap); } initMenus(); - if (leaveColouringToJmol || !usetoColour) + boolean useToColour = viewerModel.isColourWithAlignPanel(); + boolean leaveColouringToJmol = viewerModel.isColourByViewer(); + if (leaveColouringToJmol || !useToColour) { jmb.setColourBySequence(false); seqColour.setSelected(false); viewerColour.setSelected(true); } - else if (usetoColour) + else if (useToColour) { useAlignmentPanelForColourbyseq(ap); jmb.setColourBySequence(true); seqColour.setSelected(true); viewerColour.setSelected(false); } - this.setBounds(bounds); + + this.setBounds(viewerModel.getX(), viewerModel.getY(), + viewerModel.getWidth(), viewerModel.getHeight()); setViewId(viewid); - // jalview.gui.Desktop.addInternalFrame(this, "Loading File", - // bounds.width,bounds.height); this.addInternalFrameListener(new InternalFrameAdapter() { @@ -139,7 +148,10 @@ public class AppJmol extends StructureViewerBase closeViewer(false); } }); - initJmol(loadStatus); // pdbentry, seq, JBPCHECK! + StringBuilder cmd = new StringBuilder(); + cmd.append("load FILES ").append(QUOTE) + .append(Platform.escapeBackslashes(sessionFile)).append(QUOTE); + initJmol(cmd.toString()); } @Override @@ -147,23 +159,14 @@ public class AppJmol extends StructureViewerBase { super.initMenus(); - viewerActionMenu.setText(MessageManager.getString("label.jmol")); - viewerColour .setText(MessageManager.getString("label.colour_with_jmol")); viewerColour.setToolTipText(MessageManager .getString("label.let_jmol_manage_structure_colours")); } - IProgressIndicator progressBar = null; - - @Override - protected IProgressIndicator getIProgressIndicator() - { - return progressBar; - } /** - * add a single PDB structure to a new or existing Jmol view + * display a single PDB structure in a new Jmol view * * @param pdbentry * @param seq @@ -173,47 +176,28 @@ public class AppJmol extends StructureViewerBase public AppJmol(PDBEntry pdbentry, SequenceI[] seq, String[] chains, final AlignmentPanel ap) { - progressBar = ap.alignFrame; - String pdbId = pdbentry.getId(); - - /* - * If the PDB file is already loaded, the user may just choose to add to an - * existing viewer (or cancel) - */ - if (addAlreadyLoadedFile(seq, chains, ap, pdbId)) - { - return; - } + setProgressIndicator(ap.alignFrame); - /* - * Check if there are other Jmol views involving this alignment and prompt - * user about adding this molecule to one of them - */ - if (addToExistingViewer(pdbentry, seq, chains, ap, pdbId)) - { - return; - } - - /* - * If the options above are declined or do not apply, open a new viewer - */ - openNewJmol(ap, new PDBEntry[] { pdbentry }, new SequenceI[][] { seq }); + openNewJmol(ap, alignAddedStructures, new PDBEntry[] { pdbentry }, + new SequenceI[][] + { seq }); } - private void openNewJmol(AlignmentPanel ap, PDBEntry[] pdbentrys, - SequenceI[][] seqs) + private void openNewJmol(AlignmentPanel ap, boolean alignAdded, + PDBEntry[] pdbentrys, SequenceI[][] seqs) { - progressBar = ap.alignFrame; + setProgressIndicator(ap.alignFrame); jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(), pdbentrys, seqs, null); addAlignmentPanel(ap); useAlignmentPanelForColourbyseq(ap); + alignAddedStructures = alignAdded; if (pdbentrys.length > 1) { - alignAddedStructures = true; useAlignmentPanelForSuperposition(ap); } + jmb.setColourBySequence(true); setSize(400, 400); // probably should be a configurable/dynamic default here initMenus(); @@ -234,19 +218,21 @@ public class AppJmol extends StructureViewerBase } /** - * create a new Jmol containing several structures superimposed using the - * given alignPanel. + * create a new Jmol containing several structures optionally superimposed + * using the given alignPanel. * * @param ap + * @param alignAdded + * - true to superimpose * @param pe * @param seqs */ - public AppJmol(AlignmentPanel ap, PDBEntry[] pe, SequenceI[][] seqs) + public AppJmol(AlignmentPanel ap, boolean alignAdded, PDBEntry[] pe, + SequenceI[][] seqs) { - openNewJmol(ap, pe, seqs); + openNewJmol(ap, alignAdded, pe, seqs); } - void initJmol(String command) { jmb.setFinishedInit(false); @@ -272,55 +258,18 @@ public class AppJmol extends StructureViewerBase { command = ""; } - jmb.evalStateCommand(command); - jmb.evalStateCommand("set hoverDelay=0.1"); + jmb.executeCommand(new StructureCommand(command), false); + jmb.executeCommand(new StructureCommand("set hoverDelay=0.1"), false); jmb.setFinishedInit(true); } - boolean allChainsSelected = false; - - @Override - void showSelectedChains() - { - Vector toshow = new Vector<>(); - for (int i = 0; i < chainMenu.getItemCount(); i++) - { - if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem) - { - JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i); - if (item.isSelected()) - { - toshow.addElement(item.getText()); - } - } - } - jmb.centerViewer(toshow); - } - - @Override - public void closeViewer(boolean closeExternalViewer) - { - // Jmol does not use an external viewer - if (jmb != null) - { - jmb.closeViewer(); - } - setAlignmentPanel(null); - _aps.clear(); - _alignwith.clear(); - _colourwith.clear(); - // TODO: check for memory leaks where instance isn't finalised because jmb - // holds a reference to the window - jmb = null; - } - @Override public void run() { _started = true; try { - List files = fetchPdbFiles(); + List files = jmb.fetchPdbFiles(this); if (files.size() > 0) { showFilesInViewer(files); @@ -345,8 +294,8 @@ public class AppJmol extends StructureViewerBase StringBuilder fileList = new StringBuilder(); for (String s : files) { - fileList.append(SPACE).append(BACKSLASH) - .append(Platform.escapeString(s)).append(BACKSLASH); + fileList.append(SPACE).append(QUOTE) + .append(Platform.escapeBackslashes(s)).append(QUOTE); } String filesString = fileList.toString(); @@ -358,10 +307,12 @@ public class AppJmol extends StructureViewerBase } catch (OutOfMemoryError oomerror) { new OOMWarning("When trying to open the Jmol viewer!", oomerror); - Cache.log.debug("File locations are " + filesString); + Console.debug("File locations are " + filesString); } catch (Exception ex) { - Cache.log.error("Couldn't open Jmol viewer!", ex); + Console.error("Couldn't open Jmol viewer!", ex); + ex.printStackTrace(); + return; } } else @@ -370,20 +321,23 @@ public class AppJmol extends StructureViewerBase cmd.append("loadingJalviewdata=true\nload APPEND "); cmd.append(filesString); cmd.append("\nloadingJalviewdata=null"); - final String command = cmd.toString(); + final StructureCommand command = new StructureCommand(cmd.toString()); lastnotify = jmb.getLoadNotifiesHandled(); try { - jmb.evalStateCommand(command); + jmb.executeCommand(command, false); } catch (OutOfMemoryError oomerror) { new OOMWarning("When trying to add structures to the Jmol viewer!", oomerror); - Cache.log.debug("File locations are " + filesString); + Console.debug("File locations are " + filesString); + return; } catch (Exception ex) { - Cache.log.error("Couldn't add files to Jmol viewer!", ex); + Console.error("Couldn't add files to Jmol viewer!", ex); + ex.printStackTrace(); + return; } } @@ -397,9 +351,11 @@ public class AppJmol extends StructureViewerBase { try { - Cache.log.debug("Waiting around for jmb notify."); - Thread.sleep(waitFor); + Console.debug("Waiting around for jmb notify."); waitTotal += waitFor; + + // Thread.sleep() throws an exception in JS + Thread.sleep(waitFor); } catch (Exception e) { } @@ -416,12 +372,12 @@ public class AppJmol extends StructureViewerBase } // refresh the sequence colours for the new structure(s) - for (AlignmentPanel ap : _colourwith) + for (AlignmentViewPanel ap : _colourwith) { jmb.updateColours(ap); } // do superposition if asked to - if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures) + if (alignAddedStructures) { alignAddedStructures(); } @@ -438,7 +394,7 @@ public class AppJmol extends StructureViewerBase @Override public void run() { - if (jmb.viewer.isScriptExecuting()) + if (jmb.jmolViewer.isScriptExecuting()) { SwingUtilities.invokeLater(this); try @@ -451,184 +407,56 @@ public class AppJmol extends StructureViewerBase } else { - alignStructs_withAllAlignPanels(); + alignStructsWithAllAlignPanels(); } } }); - alignAddedStructures = false; + } /** - * Retrieves and saves as file any modelled PDB entries for which we do not - * already have a file saved. Returns a list of absolute paths to structure - * files which were either retrieved, or already stored but not modelled in - * the structure viewer (i.e. files to add to the viewer display). + * Outputs the Jmol viewer image as an image file, after prompting the user to + * choose a file and (for EPS) choice of Text or Lineart character rendering + * (unless a preference for this is set) * - * @return + * @param type */ - List fetchPdbFiles() - { - // todo - record which pdbids were successfully imported. - StringBuilder errormsgs = new StringBuilder(); - - List files = new ArrayList<>(); - String pdbid = ""; - try - { - String[] filesInViewer = jmb.getStructureFiles(); - // TODO: replace with reference fetching/transfer code (validate PDBentry - // as a DBRef?) - Pdb pdbclient = new Pdb(); - for (int pi = 0; pi < jmb.getPdbCount(); pi++) - { - String file = jmb.getPdbEntry(pi).getFile(); - if (file == null) - { - // retrieve the pdb and store it locally - AlignmentI pdbseq = null; - pdbid = jmb.getPdbEntry(pi).getId(); - long hdl = pdbid.hashCode() - System.currentTimeMillis(); - if (progressBar != null) - { - progressBar.setProgressBar(MessageManager - .formatMessage("status.fetching_pdb", new String[] - { pdbid }), hdl); - } - try - { - pdbseq = pdbclient.getSequenceRecords(pdbid); - } catch (OutOfMemoryError oomerror) - { - new OOMWarning("Retrieving PDB id " + pdbid, oomerror); - } catch (Exception ex) - { - ex.printStackTrace(); - errormsgs.append("'").append(pdbid).append("'"); - } finally - { - if (progressBar != null) - { - progressBar.setProgressBar( - MessageManager.getString("label.state_completed"), - hdl); - } - } - if (pdbseq != null) - { - // just transfer the file name from the first sequence's first - // PDBEntry - file = new File(pdbseq.getSequenceAt(0).getAllPDBEntries() - .elementAt(0).getFile()).getAbsolutePath(); - jmb.getPdbEntry(pi).setFile(file); - files.add(file); - } - else - { - errormsgs.append("'").append(pdbid).append("' "); - } - } - else - { - if (filesInViewer != null && filesInViewer.length > 0) - { - addingStructures = true; // already files loaded. - for (int c = 0; c < filesInViewer.length; c++) - { - if (filesInViewer[c].equals(file)) - { - file = null; - break; - } - } - } - if (file != null) - { - files.add(file); - } - } - } - } catch (OutOfMemoryError oomerror) - { - new OOMWarning("Retrieving PDB files: " + pdbid, oomerror); - } catch (Exception ex) - { - ex.printStackTrace(); - errormsgs.append("When retrieving pdbfiles : current was: '") - .append(pdbid).append("'"); - } - if (errormsgs.length() > 0) - { - JvOptionPane.showInternalMessageDialog(Desktop.desktop, - MessageManager.formatMessage( - "label.pdb_entries_couldnt_be_retrieved", new String[] - { errormsgs.toString() }), - MessageManager.getString("label.couldnt_load_file"), - JvOptionPane.ERROR_MESSAGE); - } - return files; - } - - @Override - public void eps_actionPerformed(ActionEvent e) - { - makePDBImage(jalview.util.ImageMaker.TYPE.EPS); - } - @Override - public void png_actionPerformed(ActionEvent e) - { - makePDBImage(jalview.util.ImageMaker.TYPE.PNG); - } - - void makePDBImage(jalview.util.ImageMaker.TYPE type) + public void makePDBImage(ImageMaker.TYPE type) { int width = getWidth(); int height = getHeight(); - - jalview.util.ImageMaker im; - - if (type == jalview.util.ImageMaker.TYPE.PNG) - { - im = new jalview.util.ImageMaker(this, - jalview.util.ImageMaker.TYPE.PNG, "Make PNG image from view", - width, height, null, null, null, 0, false); - } - else if (type == jalview.util.ImageMaker.TYPE.EPS) - { - im = new jalview.util.ImageMaker(this, - jalview.util.ImageMaker.TYPE.EPS, "Make EPS file from view", - width, height, null, this.getTitle(), null, 0, false); - } - else + ImageWriterI writer = new ImageWriterI() { - - im = new jalview.util.ImageMaker(this, - jalview.util.ImageMaker.TYPE.SVG, "Make SVG file from PCA", - width, height, null, this.getTitle(), null, 0, false); - } - - if (im.getGraphics() != null) - { - jmb.viewer.renderScreenImage(im.getGraphics(), width, height); - im.writeImage(); - } + @Override + public void exportImage(Graphics g) throws Exception + { + jmb.jmolViewer.renderScreenImage(g, width, height); + } + }; + String view = MessageManager.getString("action.view") + .toLowerCase(Locale.ROOT); + ImageExporter exporter = new ImageExporter(writer, + getProgressIndicator(), type, getTitle()); + exporter.doExport(null, this, width, height, view); } @Override - public void showHelp_actionPerformed(ActionEvent actionEvent) + public void showHelp_actionPerformed() { try { - BrowserLauncher - .openURL("http://jmol.sourceforge.net/docs/JmolUserGuide/"); + BrowserLauncher // BH 2018 + .openURL("http://wiki.jmol.org");// http://jmol.sourceforge.net/docs/JmolUserGuide/"); } catch (Exception ex) { + System.err.println("Show Jmol help failed with: " + ex.getMessage()); } } + @Override public void showConsole(boolean showConsole) { - if (showConsole) { if (splitPane == null) @@ -694,7 +522,8 @@ public class AppJmol extends StructureViewerBase } } } - else if (jmb == null || jmb.viewer == null || !jmb.isFinishedInit()) + else if (jmb == null || jmb.jmolViewer == null + || !jmb.isFinishedInit()) { g.setColor(Color.black); g.fillRect(0, 0, currentSize.width, currentSize.height); @@ -705,7 +534,7 @@ public class AppJmol extends StructureViewerBase } else { - jmb.viewer.renderScreenImage(g, currentSize.width, + jmb.jmolViewer.renderScreenImage(g, currentSize.width, currentSize.height); } } @@ -718,12 +547,6 @@ public class AppJmol extends StructureViewerBase } @Override - public String getStateInfo() - { - return jmb == null ? null : jmb.viewer.getStateInfo(); - } - - @Override public ViewerType getViewerType() { return ViewerType.JMOL;