X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FStructureViewerBase.java;h=8eaeed2f659f8d9a75691f86b34feae3567eef32;hb=e8dba2ced1a06b2b4e8bd90d5d79817668e3f46b;hp=c52be92becd51371c359f0624dfc5787f3d1466b;hpb=865633cd6ddc767e82ac3fd265ac2d9400a25198;p=jalview.git diff --git a/src/jalview/gui/StructureViewerBase.java b/src/jalview/gui/StructureViewerBase.java index c52be92..8eaeed2 100644 --- a/src/jalview/gui/StructureViewerBase.java +++ b/src/jalview/gui/StructureViewerBase.java @@ -20,10 +20,12 @@ */ package jalview.gui; +import jalview.api.AlignViewportI; +import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; -import jalview.datamodel.ColumnSelection; +import jalview.datamodel.HiddenColumns; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; import jalview.gui.StructureViewer.ViewerType; @@ -34,6 +36,7 @@ import jalview.io.JalviewFileView; import jalview.jbgui.GStructureViewer; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemes; +import jalview.structure.StructureMapping; import jalview.structures.models.AAStructureBindingModel; import jalview.util.MessageManager; @@ -83,18 +86,18 @@ public abstract class StructureViewerBase extends GStructureViewer /** * list of sequenceSet ids associated with the view */ - protected List _aps = new ArrayList(); + protected List _aps = new ArrayList<>(); /** * list of alignment panels to use for superposition */ - protected Vector _alignwith = new Vector(); + protected Vector _alignwith = new Vector<>(); /** * list of alignment panels that are used for colouring structures by aligned * sequences */ - protected Vector _colourwith = new Vector(); + protected Vector _colourwith = new Vector<>(); private String viewId = null; @@ -102,9 +105,9 @@ public abstract class StructureViewerBase extends GStructureViewer protected boolean alignAddedStructures = false; - protected boolean _started = false; + protected volatile boolean _started = false; - protected boolean addingStructures = false; + protected volatile boolean addingStructures = false; protected Thread worker = null; @@ -113,12 +116,40 @@ public abstract class StructureViewerBase extends GStructureViewer protected JMenu viewSelectionMenu; /** + * set after sequence colouring has been applied for this structure viewer. + * used to determine if the final sequence/structure mapping has been + * determined + */ + protected volatile boolean seqColoursApplied = false; + + /** * Default constructor */ public StructureViewerBase() { super(); } + + /** + * @return true if added structures should be aligned to existing one(s) + */ + @Override + public boolean isAlignAddedStructures() + { + return alignAddedStructures; + } + + /** + * + * @param true + * if added structures should be aligned to existing one(s) + */ + @Override + public void setAlignAddedStructures(boolean alignAdded) + { + alignAddedStructures = alignAdded; + } + /** * * @param ap2 @@ -135,9 +166,10 @@ public abstract class StructureViewerBase extends GStructureViewer return (_alignwith != null) && _alignwith.contains(ap2); } - public boolean isUsedforcolourby(AlignmentPanel ap2) + @Override + public boolean isUsedforcolourby(AlignmentViewPanel avp) { - return (_colourwith != null) && _colourwith.contains(ap2); + return (_colourwith != null) && _colourwith.contains(avp); } /** @@ -169,7 +201,7 @@ public abstract class StructureViewerBase extends GStructureViewer { if (_alignwith == null) { - _alignwith = new Vector(); + _alignwith = new Vector<>(); } if (_alignwith.size() == 0 && ap != null) { @@ -309,6 +341,8 @@ public abstract class StructureViewerBase extends GStructureViewer public abstract ViewerType getViewerType(); + protected abstract IProgressIndicator getIProgressIndicator(); + /** * add a new structure (with associated sequences and chains) to this viewer, * retrieving it if necessary first. @@ -323,7 +357,7 @@ public abstract class StructureViewerBase extends GStructureViewer */ protected void addStructure(final PDBEntry pdbentry, final SequenceI[] seqs, final String[] chains, - final boolean align, final IProgressIndicator alignFrame) + final IProgressIndicator alignFrame) { if (pdbentry.getFile() == null) { @@ -347,7 +381,7 @@ public abstract class StructureViewerBase extends GStructureViewer } } // and call ourselves again. - addStructure(pdbentry, seqs, chains, align, alignFrame); + addStructure(pdbentry, seqs, chains, alignFrame); } }).start(); return; @@ -355,89 +389,46 @@ public abstract class StructureViewerBase extends GStructureViewer } // otherwise, start adding the structure. getBinding().addSequenceAndChain(new PDBEntry[] { pdbentry }, - new SequenceI[][] { seqs }, new String[][] { chains }); + new SequenceI[][] + { seqs }, new String[][] { chains }); addingStructures = true; _started = false; - alignAddedStructures = align; worker = new Thread(this); worker.start(); return; } - /** - * Presents a dialog with the option to add an align a structure to an - * existing structure view - * - * @param pdbId - * @param view - * @return YES, NO or CANCEL JvOptionPane code - */ - protected int chooseAlignStructureToViewer(String pdbId, - StructureViewerBase view) - { - int option = JvOptionPane.showInternalConfirmDialog(Desktop.desktop, - MessageManager.formatMessage("label.add_pdbentry_to_view", - new Object[] { pdbId, view.getTitle() }), - MessageManager - .getString("label.align_to_existing_structure_view"), - JvOptionPane.YES_NO_CANCEL_OPTION); - return option; - } - protected boolean hasPdbId(String pdbId) { return getBinding().hasPdbId(pdbId); } - protected abstract List getViewersFor( - AlignmentPanel alp); - /** - * Check for any existing views involving this alignment and give user the - * option to add and align this molecule to one of them - * - * @param pdbentry - * @param seq - * @param chains - * @param apanel - * @param pdbId - * @return true if user adds to a view, or cancels entirely, else false + * Returns a list of any viewer of the instantiated type. The list is + * restricted to those linked to the given alignment panel if it is not null. */ - protected boolean addToExistingViewer(PDBEntry pdbentry, SequenceI[] seq, - String[] chains, final AlignmentPanel apanel, String pdbId) + protected List getViewersFor(AlignmentPanel alp) { - for (StructureViewerBase view : getViewersFor(apanel)) - { - // TODO: highlight the view somehow - /* - * JAL-1742 exclude view with this structure already mapped (don't offer - * to align chain B to chain A of the same structure) - */ - if (view.hasPdbId(pdbId)) - { - continue; - } - int option = chooseAlignStructureToViewer(pdbId, view); - if (option == JvOptionPane.CANCEL_OPTION) - { - return true; - } - else if (option == JvOptionPane.YES_OPTION) - { - view.useAlignmentPanelForSuperposition(apanel); - view.addStructure(pdbentry, seq, chains, true, apanel.alignFrame); - return true; - } - else - { - // NO_OPTION - offer the next viewer if any - } - } + return Desktop.instance.getStructureViewers(alp, this.getClass()); + } + @Override + public void addToExistingViewer(PDBEntry pdbentry, SequenceI[] seq, + String[] chains, final AlignmentViewPanel apanel, String pdbId) + { /* - * nothing offered and selected + * JAL-1742 exclude view with this structure already mapped (don't offer + * to align chain B to chain A of the same structure); code may defend + * against this possibility before we reach here */ - return false; + if (hasPdbId(pdbId)) + { + return; + } + AlignmentPanel alignPanel = (AlignmentPanel) apanel; // Implementation error if this + // cast fails + useAlignmentPanelForSuperposition(alignPanel); + addStructure(pdbentry, seq, chains, alignPanel.alignFrame); } /** @@ -449,15 +440,18 @@ public abstract class StructureViewerBase extends GStructureViewer * @param apanel * @param pdbFilename */ - protected void addSequenceMappingsToStructure(SequenceI[] seq, - String[] chains, final AlignmentPanel apanel, String pdbFilename) + public void addSequenceMappingsToStructure(SequenceI[] seq, + String[] chains, final AlignmentViewPanel alpanel, + String pdbFilename) { + AlignmentPanel apanel = (AlignmentPanel) alpanel; + // TODO : Fix multiple seq to one chain issue here. /* * create the mappings */ apanel.getStructureSelectionManager().setMapping(seq, chains, - pdbFilename, DataSourceType.FILE); + pdbFilename, DataSourceType.FILE, getIProgressIndicator()); /* * alert the FeatureRenderer to show new (PDB RESNUM) features @@ -465,7 +459,9 @@ public abstract class StructureViewerBase extends GStructureViewer if (apanel.getSeqPanel().seqCanvas.fr != null) { apanel.getSeqPanel().seqCanvas.fr.featuresAdded(); - apanel.paintAlignment(true); + // note - we don't do a refresh for structure here because we do it + // explicitly for all panels later on + apanel.paintAlignment(true, false); } /* @@ -488,55 +484,28 @@ public abstract class StructureViewerBase extends GStructureViewer */ viewer.useAlignmentPanelForColourbyseq(apanel); viewer.buildActionMenu(); - apanel.getStructureSelectionManager().sequenceColoursChanged( - apanel); + apanel.getStructureSelectionManager() + .sequenceColoursChanged(apanel); break; } } } } - /** - * Check if the PDB file is already loaded, if so offer to add it to the - * existing viewer - * - * @param seq - * @param chains - * @param apanel - * @param pdbId - * @return true if the user chooses to add to a viewer, or to cancel entirely - */ - protected boolean addAlreadyLoadedFile(SequenceI[] seq, String[] chains, - final AlignmentPanel apanel, String pdbId) + @Override + public boolean addAlreadyLoadedFile(SequenceI[] seq, String[] chains, + final AlignmentViewPanel apanel, String pdbId) { - boolean finished = false; String alreadyMapped = apanel.getStructureSelectionManager() .alreadyMappedToFile(pdbId); - if (alreadyMapped != null) - { - /* - * the PDB file is already loaded - */ - int option = JvOptionPane.showInternalConfirmDialog(Desktop.desktop, - MessageManager.formatMessage( - "label.pdb_entry_is_already_displayed", - new Object[] { pdbId }), MessageManager - .formatMessage( - "label.map_sequences_to_visible_window", - new Object[] { pdbId }), - JvOptionPane.YES_NO_CANCEL_OPTION); - if (option == JvOptionPane.CANCEL_OPTION) - { - finished = true; - } - else if (option == JvOptionPane.YES_OPTION) - { - addSequenceMappingsToStructure(seq, chains, apanel, alreadyMapped); - finished = true; - } + if (alreadyMapped == null) + { + return false; } - return finished; + + addSequenceMappingsToStructure(seq, chains, apanel, alreadyMapped); + return true; } void setChainMenuItems(List chainNames) @@ -596,8 +565,9 @@ public abstract class StructureViewerBase extends GStructureViewer public void changeColour_actionPerformed(String colourSchemeName) { AlignmentI al = getAlignmentPanel().av.getAlignment(); - ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme( - colourSchemeName, al, null); + ColourSchemeI cs = ColourSchemes.getInstance() + .getColourScheme(colourSchemeName, getAlignmentPanel().av, al, + null); getBinding().setJalviewColourScheme(cs); } @@ -714,11 +684,11 @@ public abstract class StructureViewerBase extends GStructureViewer if (_colourwith == null) { - _colourwith = new Vector(); + _colourwith = new Vector<>(); } if (_alignwith == null) { - _alignwith = new Vector(); + _alignwith = new Vector<>(); } ViewSelectionMenu seqColourBy = new ViewSelectionMenu( @@ -741,6 +711,36 @@ public abstract class StructureViewerBase extends GStructureViewer }); viewMenu.add(seqColourBy); + showAlignmentOnly = new JCheckBoxMenuItem( + MessageManager.getString("label.show_alignment_only")); + showAlignmentOnly.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + hideHiddenRegions.setEnabled(showAlignmentOnly.isSelected()); + getBinding().setShowAlignmentOnly(showAlignmentOnly.isSelected()); + getBinding().showStructures(getAlignmentPanel().getAlignViewport(), + true); + } + }); + viewMenu.add(showAlignmentOnly); + + hideHiddenRegions = new JCheckBoxMenuItem( + MessageManager.getString("label.hide_hidden_regions")); + hideHiddenRegions.setEnabled(false); + hideHiddenRegions.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + getBinding().setHideHiddenRegions(hideHiddenRegions.isSelected()); + getBinding().showStructures(getAlignmentPanel().getAlignViewport(), + false); + } + }); + viewMenu.add(hideHiddenRegions); + final ItemListener handler = new ItemListener() { @Override @@ -779,19 +779,13 @@ public abstract class StructureViewerBase extends GStructureViewer buildColourMenu(); } - @Override - public void setJalviewColourScheme(ColourSchemeI cs) { - getBinding().setJalviewColourScheme(cs); - } - /** * Sends commands to the structure viewer to superimpose structures based on * currently associated alignments. May optionally return an error message for * the operation. */ @Override - protected String alignStructs_actionPerformed( - ActionEvent actionEvent) + protected String alignStructs_actionPerformed(ActionEvent actionEvent) { return alignStructs_withAllAlignPanels(); } @@ -802,39 +796,41 @@ public abstract class StructureViewerBase extends GStructureViewer { return null; } - + if (_alignwith.size() == 0) { _alignwith.add(getAlignmentPanel()); } - + String reply = null; try { AlignmentI[] als = new Alignment[_alignwith.size()]; - ColumnSelection[] alc = new ColumnSelection[_alignwith.size()]; + HiddenColumns[] alc = new HiddenColumns[_alignwith.size()]; int[] alm = new int[_alignwith.size()]; int a = 0; - - for (AlignmentPanel ap : _alignwith) + + for (AlignmentViewPanel alignPanel : _alignwith) { - als[a] = ap.av.getAlignment(); + AlignViewportI av = alignPanel.getAlignViewport(); + als[a] = av.getAlignment(); alm[a] = -1; - alc[a++] = ap.av.getColumnSelection(); + alc[a++] = av.getAlignment().getHiddenColumns(); } reply = getBinding().superposeStructures(als, alm, alc); if (reply != null) { - String text = MessageManager.formatMessage( - "error.superposition_failed", reply); + String text = MessageManager + .formatMessage("error.superposition_failed", reply); statusBar.setText(text); } } catch (Exception e) { StringBuffer sp = new StringBuffer(); - for (AlignmentPanel ap : _alignwith) + for (AlignmentViewPanel avp : _alignwith) { - sp.append("'" + ap.alignFrame.getTitle() + "' "); + sp.append( + "'" + ((AlignmentPanel) avp).alignFrame.getTitle() + "' "); } Cache.log.info("Couldn't align structures with the " + sp.toString() + "associated alignment panels.", e); @@ -853,6 +849,7 @@ public abstract class StructureViewerBase extends GStructureViewer getBinding().setBackgroundColour(col); } } + @Override public void viewerColour_actionPerformed(ActionEvent actionEvent) { @@ -862,18 +859,21 @@ public abstract class StructureViewerBase extends GStructureViewer getBinding().setColourBySequence(false); } } + @Override public void chainColour_actionPerformed(ActionEvent actionEvent) { chainColour.setSelected(true); getBinding().colourByChain(); } + @Override public void chargeColour_actionPerformed(ActionEvent actionEvent) { chargeColour.setSelected(true); getBinding().colourByCharge(); } + @Override public void seqColour_actionPerformed(ActionEvent actionEvent) { @@ -881,7 +881,7 @@ public abstract class StructureViewerBase extends GStructureViewer binding.setColourBySequence(seqColour.isSelected()); if (_colourwith == null) { - _colourwith = new Vector(); + _colourwith = new Vector<>(); } if (binding.isColourBySequence()) { @@ -894,24 +894,26 @@ public abstract class StructureViewerBase extends GStructureViewer } } // Set the colour using the current view for the associated alignframe - for (AlignmentPanel ap : _colourwith) + for (AlignmentViewPanel avp : _colourwith) { - binding.colourBySequence(ap); + binding.colourBySequence(avp); } + seqColoursApplied = true; } } + @Override public void pdbFile_actionPerformed(ActionEvent actionEvent) { JalviewFileChooser chooser = new JalviewFileChooser( Cache.getProperty("LAST_DIRECTORY")); - + chooser.setFileView(new JalviewFileView()); chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file")); chooser.setToolTipText(MessageManager.getString("action.save")); - + int value = chooser.showSaveDialog(this); - + if (value == JalviewFileChooser.APPROVE_OPTION) { BufferedReader in = null; @@ -921,7 +923,7 @@ public abstract class StructureViewerBase extends GStructureViewer in = new BufferedReader( new FileReader(getBinding().getStructureFiles()[0])); File outFile = chooser.getSelectedFile(); - + PrintWriter out = new PrintWriter(new FileOutputStream(outFile)); String data; while ((data = in.readLine()) != null) @@ -950,6 +952,7 @@ public abstract class StructureViewerBase extends GStructureViewer } } } + @Override public void viewMapping_actionPerformed(ActionEvent actionEvent) { @@ -975,6 +978,7 @@ public abstract class StructureViewerBase extends GStructureViewer /** * Configures the title and menu items of the viewer panel. */ + @Override public void updateTitleAndMenus() { AAStructureBindingModel binding = getBinding(); @@ -984,7 +988,7 @@ public abstract class StructureViewerBase extends GStructureViewer return; } setChainMenuItems(binding.getChainNames()); - + this.setTitle(binding.getViewerTitle(getViewerName(), true)); /* @@ -1015,4 +1019,54 @@ public abstract class StructureViewerBase extends GStructureViewer seqColour_actionPerformed(null); } } + + @Override + public String toString() + { + return getTitle(); + } + + @Override + public boolean hasMapping() + { + if (worker != null && (addingStructures || _started)) + { + return false; + } + if (getBinding() == null) + { + if (_aps == null || _aps.size() == 0) + { + // viewer has been closed, but we did at some point run. + return true; + } + return false; + } + String[] pdbids = getBinding().getStructureFiles(); + if (pdbids == null) + { + return false; + } + int p=0; + for (String pdbid:pdbids) { + StructureMapping sm[] = getBinding().getSsm().getMapping(pdbid); + 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 + if (p == 0 || p != pdbids.length) + { + return false; + } + // and that coloring has been applied + return seqColoursApplied; + } + + @Override + public void raiseViewer() + { + toFront(); + } + }