2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.structure;
23 import jalview.analysis.AlignSeq;
24 import jalview.api.StructureSelectionManagerProvider;
25 import jalview.commands.CommandI;
26 import jalview.commands.EditCommand;
27 import jalview.commands.OrderCommand;
28 import jalview.datamodel.AlignedCodonFrame;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.Annotation;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.SearchResults;
34 import jalview.datamodel.SequenceI;
35 import jalview.gui.IProgressIndicator;
36 import jalview.io.AppletFormatAdapter;
37 import jalview.io.StructureFile;
38 import jalview.util.MappingUtils;
39 import jalview.util.MessageManager;
40 import jalview.ws.sifts.SiftsClient;
41 import jalview.ws.sifts.SiftsException;
42 import jalview.ws.sifts.SiftsSettings;
44 import java.io.PrintStream;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Collections;
48 import java.util.Enumeration;
49 import java.util.HashMap;
50 import java.util.IdentityHashMap;
51 import java.util.List;
53 import java.util.Vector;
56 import MCview.PDBChain;
57 import MCview.PDBfile;
59 public class StructureSelectionManager
61 public final static String NEWLINE = System.lineSeparator();
63 static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
65 private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
67 private boolean processSecondaryStructure = false;
69 private boolean secStructServices = false;
71 private boolean addTempFacAnnot = false;
73 private IProgressIndicator progressIndicator;
75 private SiftsClient siftsClient = null;
77 private long progressSessionId;
80 * Set of any registered mappings between (dataset) sequences.
82 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
84 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
86 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
89 * @return true if will try to use external services for processing secondary
92 public boolean isSecStructServices()
94 return secStructServices;
98 * control use of external services for processing secondary structure
100 * @param secStructServices
102 public void setSecStructServices(boolean secStructServices)
104 this.secStructServices = secStructServices;
108 * flag controlling addition of any kind of structural annotation
110 * @return true if temperature factor annotation will be added
112 public boolean isAddTempFacAnnot()
114 return addTempFacAnnot;
118 * set flag controlling addition of structural annotation
120 * @param addTempFacAnnot
122 public void setAddTempFacAnnot(boolean addTempFacAnnot)
124 this.addTempFacAnnot = addTempFacAnnot;
129 * @return if true, the structure manager will attempt to add secondary
130 * structure lines for unannotated sequences
133 public boolean isProcessSecondaryStructure()
135 return processSecondaryStructure;
139 * Control whether structure manager will try to annotate mapped sequences
140 * with secondary structure from PDB data.
144 public void setProcessSecondaryStructure(boolean enable)
146 processSecondaryStructure = enable;
150 * debug function - write all mappings to stdout
152 public void reportMapping()
154 if (mappings.isEmpty())
156 System.err.println("reportMapping: No PDB/Sequence mappings.");
160 System.err.println("reportMapping: There are " + mappings.size()
163 for (StructureMapping sm : mappings)
165 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
171 * map between the PDB IDs (or structure identifiers) used by Jalview and the
172 * absolute filenames for PDB data that corresponds to it
174 Map<String, String> pdbIdFileName = new HashMap<String, String>();
176 Map<String, String> pdbFileNameId = new HashMap<String, String>();
178 public void registerPDBFile(String idForFile, String absoluteFile)
180 pdbIdFileName.put(idForFile, absoluteFile);
181 pdbFileNameId.put(absoluteFile, idForFile);
184 public String findIdForPDBFile(String idOrFile)
186 String id = pdbFileNameId.get(idOrFile);
190 public String findFileForPDBId(String idOrFile)
192 String id = pdbIdFileName.get(idOrFile);
196 public boolean isPDBFileRegistered(String idOrFile)
198 return pdbFileNameId.containsKey(idOrFile)
199 || pdbIdFileName.containsKey(idOrFile);
202 private static StructureSelectionManager nullProvider = null;
204 public static StructureSelectionManager getStructureSelectionManager(
205 StructureSelectionManagerProvider context)
209 if (nullProvider == null)
211 if (instances != null)
215 .getString("error.implementation_error_structure_selection_manager_null"),
216 new NullPointerException(MessageManager
217 .getString("exception.ssm_context_is_null")));
221 nullProvider = new StructureSelectionManager();
226 if (instances == null)
228 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
230 StructureSelectionManager instance = instances.get(context);
231 if (instance == null)
233 if (nullProvider != null)
235 instance = nullProvider;
239 instance = new StructureSelectionManager();
241 instances.put(context, instance);
247 * flag controlling whether SeqMappings are relayed from received sequence
248 * mouse over events to other sequences
250 boolean relaySeqMappings = true;
253 * Enable or disable relay of seqMapping events to other sequences. You might
254 * want to do this if there are many sequence mappings and the host computer
259 public void setRelaySeqMappings(boolean relay)
261 relaySeqMappings = relay;
265 * get the state of the relay seqMappings flag.
267 * @return true if sequence mouse overs are being relayed to other mapped
270 public boolean isRelaySeqMappingsEnabled()
272 return relaySeqMappings;
275 Vector listeners = new Vector();
278 * register a listener for alignment sequence mouseover events
282 public void addStructureViewerListener(Object svl)
284 if (!listeners.contains(svl))
286 listeners.addElement(svl);
291 * Returns the file name for a mapped PDB id (or null if not mapped).
296 public String alreadyMappedToFile(String pdbid)
298 for (StructureMapping sm : mappings)
300 if (sm.getPdbId().equals(pdbid))
309 * Import structure data and register a structure mapping for broadcasting
310 * colouring, mouseovers and selection events (convenience wrapper).
313 * - one or more sequences to be mapped to pdbFile
314 * @param targetChains
315 * - optional chain specification for mapping each sequence to pdb
316 * (may be nill, individual elements may be nill)
318 * - structure data resource
320 * - how to resolve data from resource
321 * @return null or the structure data parsed as a pdb file
323 synchronized public StructureFile setMapping(SequenceI[] sequence,
324 String[] targetChains, String pdbFile, String protocol)
326 return setMapping(true, sequence, targetChains, pdbFile, protocol);
331 * create sequence structure mappings between each sequence and the given
332 * pdbFile (retrieved via the given protocol).
334 * @param forStructureView
335 * when true, record the mapping for use in mouseOvers
337 * @param sequenceArray
338 * - one or more sequences to be mapped to pdbFile
339 * @param targetChainIds
340 * - optional chain specification for mapping each sequence to pdb
341 * (may be nill, individual elements may be nill)
343 * - structure data resource
345 * - how to resolve data from resource
346 * @return null or the structure data parsed as a pdb file
348 synchronized public StructureFile setMapping(boolean forStructureView,
349 SequenceI[] sequenceArray, String[] targetChainIds,
354 * There will be better ways of doing this in the future, for now we'll use
355 * the tried and tested MCview pdb mapping
357 boolean parseSecStr = processSecondaryStructure;
358 if (isPDBFileRegistered(pdbFile))
360 for (SequenceI sq : sequenceArray)
363 while (ds.getDatasetSequence() != null)
365 ds = ds.getDatasetSequence();
368 if (ds.getAnnotation() != null)
370 for (AlignmentAnnotation ala : ds.getAnnotation())
372 // false if any annotation present from this structure
373 // JBPNote this fails for jmol/chimera view because the *file* is
374 // passed, not the structure data ID -
375 if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
383 StructureFile pdb = null;
384 boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
388 if (pdbFile != null && isCIFFile(pdbFile))
390 pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr,
391 secStructServices, pdbFile, protocol);
395 pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
399 if (pdb.getId() != null && pdb.getId().trim().length() > 0
400 && AppletFormatAdapter.FILE.equals(protocol))
402 registerPDBFile(pdb.getId().trim(), pdbFile);
404 } catch (Exception ex)
406 ex.printStackTrace();
414 siftsClient = new SiftsClient(pdb);
416 } catch (SiftsException e)
418 isMapUsingSIFTs = false;
422 String targetChainId;
423 for (int s = 0; s < sequenceArray.length; s++)
425 boolean infChain = true;
426 final SequenceI seq = sequenceArray[s];
427 if (targetChainIds != null && targetChainIds[s] != null)
430 targetChainId = targetChainIds[s];
432 else if (seq.getName().indexOf("|") > -1)
434 targetChainId = seq.getName().substring(
435 seq.getName().lastIndexOf("|") + 1);
436 if (targetChainId.length() > 1)
438 if (targetChainId.trim().length() == 0)
444 // not a valid chain identifier
455 * Attempt pairwise alignment of the sequence with each chain in the PDB,
456 * and remember the highest scoring chain
459 AlignSeq maxAlignseq = null;
460 String maxChainId = " ";
461 PDBChain maxChain = null;
462 boolean first = true;
463 for (PDBChain chain : pdb.getChains())
465 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
468 continue; // don't try to map chains don't match.
470 // TODO: correctly determine sequence type for mixed na/peptide
472 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
473 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
476 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
477 // as.calcScoreMatrix();
478 // as.traceAlignment();
480 if (first || as.maxscore > max
481 || (as.maxscore == max && chain.id.equals(targetChainId)))
487 maxChainId = chain.id;
490 if (maxChain == null)
495 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
497 pdbFile = "INLINE" + pdb.getId();
500 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
503 setProgressBar(null);
504 setProgressBar("Obtaining mapping with SIFTS");
505 jalview.datamodel.Mapping sqmpping = maxAlignseq
506 .getMappingFromS1(false);
507 if (targetChainId != null && !targetChainId.trim().isEmpty())
509 StructureMapping mapping = getStructureMapping(seq, pdbFile,
510 targetChainId, pdb, maxChain, sqmpping, maxAlignseq);
511 seqToStrucMapping.add(mapping);
515 for (PDBChain chain : pdb.getChains())
517 StructureMapping mapping = getStructureMapping(seq, pdbFile,
518 chain.id, pdb, chain, sqmpping, maxAlignseq);
519 seqToStrucMapping.add(mapping);
525 setProgressBar(null);
526 setProgressBar("Obtaining mapping with NW alignment");
527 seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
528 maxChain, pdb, maxAlignseq));
531 if (forStructureView)
533 mappings.addAll(seqToStrucMapping);
539 private boolean isCIFFile(String filename)
541 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
543 return "cif".equalsIgnoreCase(fileExt);
546 private StructureMapping getStructureMapping(SequenceI seq,
547 String pdbFile, String targetChainId, StructureFile pdb,
548 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
549 AlignSeq maxAlignseq)
551 String maxChainId = targetChainId;
554 StructureMapping curChainMapping = siftsClient
555 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
558 PDBChain chain = pdb.findChain(targetChainId);
561 chain.transferResidueAnnotation(curChainMapping, sqmpping);
563 } catch (Exception e)
567 return curChainMapping;
568 } catch (SiftsException e)
570 System.err.println(e.getMessage());
571 System.err.println(">>> Now switching mapping with NW alignment...");
572 setProgressBar(null);
573 setProgressBar(">>> Now switching mapping with NW alignment...");
574 return getNWMappings(seq, pdbFile, maxChainId, maxChain, pdb,
579 private StructureMapping getNWMappings(SequenceI seq,
581 String maxChainId, PDBChain maxChain, StructureFile pdb,
582 AlignSeq maxAlignseq)
584 final StringBuilder mappingDetails = new StringBuilder(128);
585 mappingDetails.append(NEWLINE).append(
586 "Sequence \u27f7 Structure mapping details");
587 mappingDetails.append(NEWLINE);
589 .append("Method: inferred with Needleman & Wunsch alignment");
590 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
591 .append(NEWLINE).append("Sequence = ")
592 .append(maxChain.sequence.getSequenceAsString());
593 mappingDetails.append(NEWLINE).append("No of residues = ")
594 .append(maxChain.residues.size()).append(NEWLINE)
596 PrintStream ps = new PrintStream(System.out)
599 public void print(String x)
601 mappingDetails.append(x);
605 public void println()
607 mappingDetails.append(NEWLINE);
611 maxAlignseq.printAlignment(ps);
613 mappingDetails.append(NEWLINE).append("PDB start/end ");
614 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
616 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
617 mappingDetails.append(NEWLINE).append("SEQ start/end ");
618 mappingDetails.append(
619 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
621 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
622 + (seq.getStart() - 1)));
623 mappingDetails.append(NEWLINE);
624 maxChain.makeExactMapping(maxAlignseq, seq);
625 jalview.datamodel.Mapping sqmpping = maxAlignseq
626 .getMappingFromS1(false);
627 maxChain.transferRESNUMFeatures(seq, null);
629 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
636 Atom tmp = maxChain.atoms.elementAt(index);
637 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
638 && tmp.alignmentMapping != -1)
640 resNum = tmp.resNumber;
641 insCode = tmp.insCode;
642 if (tmp.alignmentMapping >= -1)
644 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
650 } while (index < maxChain.atoms.size());
652 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
653 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
654 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
658 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
660 listeners.removeElement(svl);
661 if (svl instanceof SequenceListener)
663 for (int i = 0; i < listeners.size(); i++)
665 if (listeners.elementAt(i) instanceof StructureListener)
667 ((StructureListener) listeners.elementAt(i))
668 .releaseReferences(svl);
673 if (pdbfiles == null)
679 * Remove mappings to the closed listener's PDB files, but first check if
680 * another listener is still interested
682 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
684 StructureListener sl;
685 for (int i = 0; i < listeners.size(); i++)
687 if (listeners.elementAt(i) instanceof StructureListener)
689 sl = (StructureListener) listeners.elementAt(i);
690 for (String pdbfile : sl.getPdbFile())
692 pdbs.remove(pdbfile);
698 * Rebuild the mappings set, retaining only those which are for 'other' PDB
703 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
704 for (StructureMapping sm : mappings)
706 if (!pdbs.contains(sm.pdbfile))
717 * Propagate mouseover of a single position in a structure
723 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
725 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
726 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
727 mouseOverStructure(atoms);
731 * Propagate mouseover or selection of multiple positions in a structure
735 public void mouseOverStructure(List<AtomSpec> atoms)
737 if (listeners == null)
739 // old or prematurely sent event
742 boolean hasSequenceListener = false;
743 for (int i = 0; i < listeners.size(); i++)
745 if (listeners.elementAt(i) instanceof SequenceListener)
747 hasSequenceListener = true;
750 if (!hasSequenceListener)
755 SearchResults results = new SearchResults();
756 for (AtomSpec atom : atoms)
758 SequenceI lastseq = null;
760 for (StructureMapping sm : mappings)
762 if (sm.pdbfile.equals(atom.getPdbFile())
763 && sm.pdbchain.equals(atom.getChain()))
765 int indexpos = sm.getSeqPos(atom.getPdbResNum());
766 if (lastipos != indexpos && lastseq != sm.sequence)
768 results.addResult(sm.sequence, indexpos, indexpos);
770 lastseq = sm.sequence;
771 // construct highlighted sequence list
772 for (AlignedCodonFrame acf : seqmappings)
774 acf.markMappedRegion(sm.sequence, indexpos, results);
780 for (Object li : listeners)
782 if (li instanceof SequenceListener)
784 ((SequenceListener) li).highlightSequence(results);
790 * highlight regions associated with a position (indexpos) in seq
793 * the sequence that the mouse over occurred on
795 * the absolute position being mouseovered in seq (0 to seq.length())
797 * the sequence position (if -1, seq.findPosition is called to
798 * resolve the residue number)
800 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
803 boolean hasSequenceListeners = handlingVamsasMo
804 || !seqmappings.isEmpty();
805 SearchResults results = null;
808 seqPos = seq.findPosition(indexpos);
810 for (int i = 0; i < listeners.size(); i++)
812 Object listener = listeners.elementAt(i);
813 if (listener == source)
815 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
816 // Temporary fudge with SequenceListener.getVamsasSource()
819 if (listener instanceof StructureListener)
821 highlightStructure((StructureListener) listener, seq, seqPos);
825 if (listener instanceof SequenceListener)
827 final SequenceListener seqListener = (SequenceListener) listener;
828 if (hasSequenceListeners
829 && seqListener.getVamsasSource() != source)
831 if (relaySeqMappings)
835 results = MappingUtils.buildSearchResults(seq, seqPos,
838 if (handlingVamsasMo)
840 results.addResult(seq, seqPos, seqPos);
843 if (!results.isEmpty())
845 seqListener.highlightSequence(results);
850 else if (listener instanceof VamsasListener && !handlingVamsasMo)
852 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
855 else if (listener instanceof SecondaryStructureListener)
857 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
865 * Send suitable messages to a StructureListener to highlight atoms
866 * corresponding to the given sequence position(s)
872 public void highlightStructure(StructureListener sl, SequenceI seq,
875 if (!sl.isListeningFor(seq))
880 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
881 for (StructureMapping sm : mappings)
883 if (sm.sequence == seq
884 || sm.sequence == seq.getDatasetSequence()
885 || (sm.sequence.getDatasetSequence() != null && sm.sequence
886 .getDatasetSequence() == seq.getDatasetSequence()))
888 for (int index : positions)
890 atomNo = sm.getAtomNum(index);
894 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
895 .getPDBResNum(index), atomNo));
900 sl.highlightAtoms(atoms);
904 * true if a mouse over event from an external (ie Vamsas) source is being
907 boolean handlingVamsasMo = false;
912 * as mouseOverSequence but only route event to SequenceListeners
916 * in an alignment sequence
918 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
921 handlingVamsasMo = true;
922 long msg = sequenceI.hashCode() * (1 + position);
926 mouseOverSequence(sequenceI, position, -1, source);
928 handlingVamsasMo = false;
931 public Annotation[] colourSequenceFromStructure(SequenceI seq,
935 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
936 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
938 * Annotation [] annotations = new Annotation[seq.getLength()];
940 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
941 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
942 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
944 * for (int j = 0; j < mappings.length; j++) {
946 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
947 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
948 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
949 * "+mappings[j].pdbfile);
951 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
952 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
954 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
955 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
956 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
957 * mappings[j].pdbfile); }
959 * annotations[index] = new Annotation("X",null,' ',0,col); } return
960 * annotations; } } } }
962 * return annotations;
966 public void structureSelectionChanged()
970 public void sequenceSelectionChanged()
974 public void sequenceColoursChanged(Object source)
976 StructureListener sl;
977 for (int i = 0; i < listeners.size(); i++)
979 if (listeners.elementAt(i) instanceof StructureListener)
981 sl = (StructureListener) listeners.elementAt(i);
982 sl.updateColours(source);
987 public StructureMapping[] getMapping(String pdbfile)
989 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
990 for (StructureMapping sm : mappings)
992 if (sm.pdbfile.equals(pdbfile))
997 return tmp.toArray(new StructureMapping[tmp.size()]);
1001 * Returns a readable description of all mappings for the given pdbfile to any
1002 * of the given sequences
1008 public String printMappings(String pdbfile, List<SequenceI> seqs)
1010 if (pdbfile == null || seqs == null || seqs.isEmpty())
1015 StringBuilder sb = new StringBuilder(64);
1016 for (StructureMapping sm : mappings)
1018 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1020 sb.append(sm.mappingDetails);
1022 // separator makes it easier to read multiple mappings
1023 sb.append("=====================");
1029 return sb.toString();
1033 * Remove the given mapping
1037 public void deregisterMapping(AlignedCodonFrame acf)
1041 boolean removed = seqmappings.remove(acf);
1042 if (removed && seqmappings.isEmpty())
1044 System.out.println("All mappings removed");
1050 * Add each of the given codonFrames to the stored set, if not aready present.
1054 public void registerMappings(List<AlignedCodonFrame> mappings)
1056 if (mappings != null)
1058 for (AlignedCodonFrame acf : mappings)
1060 registerMapping(acf);
1066 * Add the given mapping to the stored set, unless already stored.
1068 public void registerMapping(AlignedCodonFrame acf)
1072 if (!seqmappings.contains(acf))
1074 seqmappings.add(acf);
1080 * Resets this object to its initial state by removing all registered
1081 * listeners, codon mappings, PDB file mappings
1083 public void resetAll()
1085 if (mappings != null)
1089 if (seqmappings != null)
1091 seqmappings.clear();
1093 if (sel_listeners != null)
1095 sel_listeners.clear();
1097 if (listeners != null)
1101 if (commandListeners != null)
1103 commandListeners.clear();
1105 if (view_listeners != null)
1107 view_listeners.clear();
1109 if (pdbFileNameId != null)
1111 pdbFileNameId.clear();
1113 if (pdbIdFileName != null)
1115 pdbIdFileName.clear();
1119 public void addSelectionListener(SelectionListener selecter)
1121 if (!sel_listeners.contains(selecter))
1123 sel_listeners.add(selecter);
1127 public void removeSelectionListener(SelectionListener toremove)
1129 if (sel_listeners.contains(toremove))
1131 sel_listeners.remove(toremove);
1135 public synchronized void sendSelection(
1136 jalview.datamodel.SequenceGroup selection,
1137 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1139 for (SelectionListener slis : sel_listeners)
1143 slis.selection(selection, colsel, source);
1148 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1150 public synchronized void sendViewPosition(
1151 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1152 int startSeq, int endSeq)
1155 if (view_listeners != null && view_listeners.size() > 0)
1157 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1159 while (listeners.hasMoreElements())
1161 AlignmentViewPanelListener slis = listeners.nextElement();
1164 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1172 * release all references associated with this manager provider
1174 * @param jalviewLite
1176 public static void release(StructureSelectionManagerProvider jalviewLite)
1178 // synchronized (instances)
1180 if (instances == null)
1184 StructureSelectionManager mnger = (instances.get(jalviewLite));
1187 instances.remove(jalviewLite);
1191 } catch (Throwable x)
1198 public void registerPDBEntry(PDBEntry pdbentry)
1200 if (pdbentry.getFile() != null
1201 && pdbentry.getFile().trim().length() > 0)
1203 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1207 public void addCommandListener(CommandListener cl)
1209 if (!commandListeners.contains(cl))
1211 commandListeners.add(cl);
1215 public boolean hasCommandListener(CommandListener cl)
1217 return this.commandListeners.contains(cl);
1220 public boolean removeCommandListener(CommandListener l)
1222 return commandListeners.remove(l);
1226 * Forward a command to any command listeners (except for the command's
1230 * the command to be broadcast (in its form after being performed)
1232 * if true, the command was being 'undone'
1235 public void commandPerformed(CommandI command, boolean undo,
1236 VamsasSource source)
1238 for (CommandListener listener : commandListeners)
1240 listener.mirrorCommand(command, undo, this, source);
1245 * Returns a new CommandI representing the given command as mapped to the
1246 * given sequences. If no mapping could be made, or the command is not of a
1247 * mappable kind, returns null.
1255 public CommandI mapCommand(CommandI command, boolean undo,
1256 final AlignmentI mapTo, char gapChar)
1258 if (command instanceof EditCommand)
1260 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1261 mapTo, gapChar, seqmappings);
1263 else if (command instanceof OrderCommand)
1265 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1266 mapTo, seqmappings);
1271 public IProgressIndicator getProgressIndicator()
1273 return progressIndicator;
1276 public void setProgressIndicator(IProgressIndicator progressIndicator)
1278 this.progressIndicator = progressIndicator;
1281 public long getProgressSessionId()
1283 return progressSessionId;
1286 public void setProgressSessionId(long progressSessionId)
1288 this.progressSessionId = progressSessionId;
1291 public void setProgressBar(String message)
1293 if (progressIndicator == null)
1297 progressIndicator.setProgressBar(message, progressSessionId);
1300 public List<AlignedCodonFrame> getSequenceMappings()