X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FStructureViewerBase.java;h=ed42ffa7c98761275a3e42a9015e8dc12e183c9e;hb=d76c189f5d49526a39d03e291f84400b95c177b2;hp=4f746cbed4330f609ccbfb97d2b0ff804f29190e;hpb=8f08ed712138cea8987594a62b6053a0bfdba327;p=jalview.git diff --git a/src/jalview/gui/StructureViewerBase.java b/src/jalview/gui/StructureViewerBase.java index 4f746cb..ed42ffa 100644 --- a/src/jalview/gui/StructureViewerBase.java +++ b/src/jalview/gui/StructureViewerBase.java @@ -26,6 +26,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.beans.PropertyVetoException; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; @@ -46,7 +47,9 @@ import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import jalview.api.AlignmentViewPanel; +import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; +import jalview.bin.Console; import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; @@ -86,6 +89,29 @@ public abstract class StructureViewerBase extends GStructureViewer } /** + * Singleton list of all (open) instances of structureViewerBase + * TODO: JAL-3362 - review and adopt the swingJS-safe singleton pattern so each structure viewer base instance is kept to its own JalviewJS parent + */ + private static List svbs = new ArrayList<>(); + + /** + * + * @return list with all existing StructureViewers instance + */ + public static List getAllStructureViewerBases() + { + List goodSvbs = new ArrayList<>(); + for (JalviewStructureDisplayI s : svbs) + { + if (s != null && !goodSvbs.contains(s)) + { + goodSvbs.add(s); + } + } + return goodSvbs; + } + + /** * list of sequenceSet ids associated with the view */ protected List _aps = new ArrayList<>(); @@ -134,6 +160,8 @@ public abstract class StructureViewerBase extends GStructureViewer public StructureViewerBase() { super(); + setFrameIcon(null); + svbs.add(this); } /** @@ -155,9 +183,11 @@ public abstract class StructureViewerBase extends GStructureViewer { alignAddedStructures = alignAdded; } - + /** - * called by the binding model to indicate when adding structures is happening or has been completed + * called by the binding model to indicate when adding structures is happening + * or has been completed + * * @param addingStructures */ public synchronized void setAddingStructures(boolean addingStructures) @@ -175,6 +205,7 @@ public abstract class StructureViewerBase extends GStructureViewer return _aps.contains(ap2.av.getSequenceSetId()); } + @Override public boolean isUsedforaligment(AlignmentViewPanel ap2) { @@ -442,8 +473,9 @@ public abstract class StructureViewerBase extends GStructureViewer { return; } - AlignmentPanel alignPanel = (AlignmentPanel) apanel; // Implementation error if this - // cast fails + AlignmentPanel alignPanel = (AlignmentPanel) apanel; // Implementation error + // if this + // cast fails useAlignmentPanelForSuperposition(alignPanel); addStructure(pdbentry, seq, chains, alignPanel.alignFrame); } @@ -580,9 +612,8 @@ public abstract class StructureViewerBase extends GStructureViewer public void changeColour_actionPerformed(String colourSchemeName) { AlignmentI al = getAlignmentPanel().av.getAlignment(); - ColourSchemeI cs = ColourSchemes.getInstance() - .getColourScheme(colourSchemeName, getAlignmentPanel().av, al, - null); + ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme( + colourSchemeName, getAlignmentPanel().av, al, null); getBinding().colourByJalviewColourScheme(cs); } @@ -814,7 +845,7 @@ public abstract class StructureViewerBase extends GStructureViewer { sp.append("'" + alignPanel.getViewName() + "' "); } - Cache.log.info("Couldn't align structures with the " + sp.toString() + Console.info("Couldn't align structures with the " + sp.toString() + "associated alignment panels.", e); } return reply; @@ -1037,14 +1068,17 @@ public abstract class StructureViewerBase extends GStructureViewer { return false; } - int p=0; - for (String pdbid:pdbids) { + int p = 0; + for (String pdbid : pdbids) + { StructureMapping sm[] = getBinding().getSsm().getMapping(pdbid); - if (sm!=null && sm.length>0 && sm[0]!=null) { + if (sm != null && sm.length > 0 && sm[0] != null) + { p++; } } - // only return true if there is a mapping for every structure file we have loaded + // only return true if there is a mapping for every structure file we have + // loaded if (p == 0 || p != pdbids.length) { return false; @@ -1136,12 +1170,12 @@ public abstract class StructureViewerBase extends GStructureViewer { String filePath = null; Pdb pdbclient = new Pdb(); - EBIAlfaFold afclient = new EBIAlfaFold(); + EBIAlfaFold afclient = new EBIAlfaFold(); AlignmentI pdbseq = null; String pdbid = processingEntry.getId(); long handle = System.currentTimeMillis() + Thread.currentThread().hashCode(); - + /* * Write 'fetching PDB' progress on AlignFrame as we are not yet visible */ @@ -1156,31 +1190,40 @@ public abstract class StructureViewerBase extends GStructureViewer { if (afclient.isValidReference(pdbid)) { - pdbseq = afclient.getSequenceRecords(pdbid); - } else { - if (processingEntry.hasRetrievalUrl()) + pdbseq = afclient.getSequenceRecords(pdbid, + processingEntry.getRetrievalUrl()); + } + else + { + if (processingEntry.hasRetrievalUrl()) + { + String safePDBId = java.net.URLEncoder.encode(pdbid, "UTF-8") + .replace("%", "__"); + + // retrieve from URL to new local tmpfile + File tmpFile = File.createTempFile(safePDBId, + "." + (PDBEntry.Type.MMCIF.toString().equals( + processingEntry.getType().toString()) ? "cif" + : "pdb")); + String fromUrl = processingEntry.getRetrievalUrl(); + UrlDownloadClient.download(fromUrl, tmpFile); + + // may not need this check ? + String file = tmpFile.getAbsolutePath(); + if (file != null) { - // retrieve from URL to new local tmpfile - File tmpFile = File.createTempFile(pdbid, - "." + (PDBEntry.Type.MMCIF.toString().equals( - processingEntry.getType().toString()) ? "cif" - : "pdb")); - String fromUrl = processingEntry.getRetrievalUrl(); - UrlDownloadClient.download(fromUrl, tmpFile); - - // may not need this check ? - String file = tmpFile.getAbsolutePath(); - if (file != null) - { - pdbseq = EBIAlfaFold.importDownloadedStructureFromUrl(fromUrl,tmpFile,pdbid,null,null,null); - } - } else { - pdbseq = pdbclient.getSequenceRecords(pdbid); + pdbseq = EBIAlfaFold.importDownloadedStructureFromUrl(fromUrl, + tmpFile, pdbid, null, null, null); } + } + else + { + pdbseq = pdbclient.getSequenceRecords(pdbid); + } } } catch (Exception e) { - System.err.println( + jalview.bin.Console.errPrintln( "Error retrieving PDB id " + pdbid + ": " + e.getMessage()); } finally { @@ -1210,8 +1253,43 @@ public abstract class StructureViewerBase extends GStructureViewer */ public File saveSession() { - // TODO: a wait loop to ensure the file is written fully before returning? - return getBinding() == null ? null : getBinding().saveSession(); + if (getBinding() == null) + { + return null; + } + File session = getBinding().saveSession(); + long l = session.length(); + int wait = 50; + do + { + try + { + Thread.sleep(5); + } catch (InterruptedException e) + { + } + long nextl = session.length(); + if (nextl != l) + { + wait = 50; + l = nextl; + } + } while (--wait > 0); + return session; + } + + private static boolean quitClose = false; + + public static void setQuitClose(boolean b) + { + quitClose = b; + } + + @Override + public boolean stillRunning() + { + AAStructureBindingModel binding = getBinding(); + return binding != null && binding.isViewerRunning(); } /** @@ -1226,24 +1304,48 @@ public abstract class StructureViewerBase extends GStructureViewer public void closeViewer(boolean forceClose) { AAStructureBindingModel binding = getBinding(); - if (binding != null && binding.isViewerRunning()) + if (stillRunning()) { if (!forceClose) { String viewerName = getViewerName(); - String prompt = MessageManager - .formatMessage("label.confirm_close_viewer", new Object[] - { binding.getViewerTitle(viewerName, false), viewerName }); - prompt = JvSwingUtils.wrapTooltip(true, prompt); - int confirm = JvOptionPane.showConfirmDialog(this, prompt, - MessageManager.getString("label.close_viewer"), - JvOptionPane.YES_NO_CANCEL_OPTION); + + int confirm = JvOptionPane.CANCEL_OPTION; + if (QuitHandler.quitting()) + { + // already asked about closing external windows + confirm = quitClose ? JvOptionPane.YES_OPTION + : JvOptionPane.NO_OPTION; + } + else + { + String prompt = MessageManager + .formatMessage("label.confirm_close_viewer", new Object[] + { binding.getViewerTitle(viewerName, false), + viewerName }); + prompt = JvSwingUtils.wrapTooltip(true, prompt); + String title = MessageManager.getString("label.close_viewer"); + confirm = showCloseDialog(title, prompt); + } + /* * abort closure if user hits escape or Cancel */ if (confirm == JvOptionPane.CANCEL_OPTION || confirm == JvOptionPane.CLOSED_OPTION) { + // abort possible quit handling if CANCEL chosen + if (confirm == JvOptionPane.CANCEL_OPTION) + { + try + { + // this is a bit futile + this.setClosed(false); + } catch (PropertyVetoException e) + { + } + QuitHandler.abortQuit(); + } return; } forceClose = confirm == JvOptionPane.YES_OPTION; @@ -1260,26 +1362,49 @@ public abstract class StructureViewerBase extends GStructureViewer // TODO: check for memory leaks where instance isn't finalised because jmb // holds a reference to the window // jmb = null; + + try { + svbs.remove(this); + } catch (Throwable t) + { + Console.info("Unexpected exception when deregistering structure viewer",t); + } dispose(); } + private int showCloseDialog(final String title, final String prompt) + { + int confirmResponse = JvOptionPane.CANCEL_OPTION; + confirmResponse = JvOptionPane.showConfirmDialog(this, prompt, + MessageManager.getString("label.close_viewer"), + JvOptionPane.YES_NO_CANCEL_OPTION, + JvOptionPane.WARNING_MESSAGE); + return confirmResponse; + } + @Override public void showHelp_actionPerformed() { + /* try { - String url = getBinding().getHelpURL(); - if (url != null) - { - BrowserLauncher.openURL(url); - } - } catch (IOException ex) + */ + String url = getBinding().getHelpURL(); + if (url != null) + { + BrowserLauncher.openURL(url); + } + /* + } + catch (IOException ex) { System.err .println("Show " + getViewerName() + " failed with: " + ex.getMessage()); } + */ } + @Override public boolean hasViewerActionsMenu() { @@ -1287,4 +1412,5 @@ public abstract class StructureViewerBase extends GStructureViewer && viewerActionMenu.getItemCount() > 0 && viewerActionMenu.isVisible(); } + }