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.util.MappingUtils;
38 import jalview.util.MessageManager;
39 import jalview.ws.sifts.SiftsClient;
40 import jalview.ws.sifts.SiftsException;
41 import jalview.ws.sifts.SiftsSettings;
43 import java.io.PrintStream;
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.Collections;
47 import java.util.Enumeration;
48 import java.util.HashMap;
49 import java.util.IdentityHashMap;
50 import java.util.List;
52 import java.util.Vector;
55 import MCview.PDBChain;
56 import MCview.PDBfile;
58 public class StructureSelectionManager
60 public final static String NEWLINE = System.lineSeparator();
62 static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
64 private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
66 private boolean processSecondaryStructure = false;
68 private boolean secStructServices = false;
70 private boolean addTempFacAnnot = false;
72 private IProgressIndicator progressIndicator;
74 private long progressSessionId;
77 * Set of any registered mappings between (dataset) sequences.
79 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
81 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
83 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
86 * @return true if will try to use external services for processing secondary
89 public boolean isSecStructServices()
91 return secStructServices;
95 * control use of external services for processing secondary structure
97 * @param secStructServices
99 public void setSecStructServices(boolean secStructServices)
101 this.secStructServices = secStructServices;
105 * flag controlling addition of any kind of structural annotation
107 * @return true if temperature factor annotation will be added
109 public boolean isAddTempFacAnnot()
111 return addTempFacAnnot;
115 * set flag controlling addition of structural annotation
117 * @param addTempFacAnnot
119 public void setAddTempFacAnnot(boolean addTempFacAnnot)
121 this.addTempFacAnnot = addTempFacAnnot;
126 * @return if true, the structure manager will attempt to add secondary
127 * structure lines for unannotated sequences
130 public boolean isProcessSecondaryStructure()
132 return processSecondaryStructure;
136 * Control whether structure manager will try to annotate mapped sequences
137 * with secondary structure from PDB data.
141 public void setProcessSecondaryStructure(boolean enable)
143 processSecondaryStructure = enable;
147 * debug function - write all mappings to stdout
149 public void reportMapping()
151 if (mappings.isEmpty())
153 System.err.println("reportMapping: No PDB/Sequence mappings.");
157 System.err.println("reportMapping: There are " + mappings.size()
160 for (StructureMapping sm : mappings)
162 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
168 * map between the PDB IDs (or structure identifiers) used by Jalview and the
169 * absolute filenames for PDB data that corresponds to it
171 Map<String, String> pdbIdFileName = new HashMap<String, String>();
173 Map<String, String> pdbFileNameId = new HashMap<String, String>();
175 public void registerPDBFile(String idForFile, String absoluteFile)
177 pdbIdFileName.put(idForFile, absoluteFile);
178 pdbFileNameId.put(absoluteFile, idForFile);
181 public String findIdForPDBFile(String idOrFile)
183 String id = pdbFileNameId.get(idOrFile);
187 public String findFileForPDBId(String idOrFile)
189 String id = pdbIdFileName.get(idOrFile);
193 public boolean isPDBFileRegistered(String idOrFile)
195 return pdbFileNameId.containsKey(idOrFile)
196 || pdbIdFileName.containsKey(idOrFile);
199 private static StructureSelectionManager nullProvider = null;
201 public static StructureSelectionManager getStructureSelectionManager(
202 StructureSelectionManagerProvider context)
206 if (nullProvider == null)
208 if (instances != null)
212 .getString("error.implementation_error_structure_selection_manager_null"),
213 new NullPointerException(MessageManager
214 .getString("exception.ssm_context_is_null")));
218 nullProvider = new StructureSelectionManager();
223 if (instances == null)
225 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
227 StructureSelectionManager instance = instances.get(context);
228 if (instance == null)
230 if (nullProvider != null)
232 instance = nullProvider;
236 instance = new StructureSelectionManager();
238 instances.put(context, instance);
244 * flag controlling whether SeqMappings are relayed from received sequence
245 * mouse over events to other sequences
247 boolean relaySeqMappings = true;
250 * Enable or disable relay of seqMapping events to other sequences. You might
251 * want to do this if there are many sequence mappings and the host computer
256 public void setRelaySeqMappings(boolean relay)
258 relaySeqMappings = relay;
262 * get the state of the relay seqMappings flag.
264 * @return true if sequence mouse overs are being relayed to other mapped
267 public boolean isRelaySeqMappingsEnabled()
269 return relaySeqMappings;
272 Vector listeners = new Vector();
275 * register a listener for alignment sequence mouseover events
279 public void addStructureViewerListener(Object svl)
281 if (!listeners.contains(svl))
283 listeners.addElement(svl);
288 * Returns the file name for a mapped PDB id (or null if not mapped).
293 public String alreadyMappedToFile(String pdbid)
295 for (StructureMapping sm : mappings)
297 if (sm.getPdbId().equals(pdbid))
306 * Import structure data and register a structure mapping for broadcasting
307 * colouring, mouseovers and selection events (convenience wrapper).
310 * - one or more sequences to be mapped to pdbFile
311 * @param targetChains
312 * - optional chain specification for mapping each sequence to pdb
313 * (may be nill, individual elements may be nill)
315 * - structure data resource
317 * - how to resolve data from resource
318 * @return null or the structure data parsed as a pdb file
320 synchronized public PDBfile setMapping(SequenceI[] sequence,
321 String[] targetChains, String pdbFile, String protocol)
323 return setMapping(true, sequence, targetChains, pdbFile, protocol);
327 * create sequence structure mappings between each sequence and the given
328 * pdbFile (retrieved via the given protocol).
330 * @param forStructureView
331 * when true, record the mapping for use in mouseOvers
333 * @param sequenceArray
334 * - one or more sequences to be mapped to pdbFile
335 * @param targetChainIds
336 * - optional chain specification for mapping each sequence to pdb
337 * (may be nill, individual elements may be nill)
339 * - structure data resource
341 * - how to resolve data from resource
342 * @return null or the structure data parsed as a pdb file
344 synchronized public PDBfile setMapping(boolean forStructureView,
345 SequenceI[] sequenceArray, String[] targetChainIds,
350 * There will be better ways of doing this in the future, for now we'll use
351 * the tried and tested MCview pdb mapping
353 boolean parseSecStr = processSecondaryStructure;
354 if (isPDBFileRegistered(pdbFile))
356 for (SequenceI sq : sequenceArray)
359 while (ds.getDatasetSequence() != null)
361 ds = ds.getDatasetSequence();
364 if (ds.getAnnotation() != null)
366 for (AlignmentAnnotation ala : ds.getAnnotation())
368 // false if any annotation present from this structure
369 // JBPNote this fails for jmol/chimera view because the *file* is
370 // passed, not the structure data ID -
371 if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
380 boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
381 SiftsClient siftsClient = null;
384 pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
387 if (pdb.id != null && pdb.id.trim().length() > 0
388 && AppletFormatAdapter.FILE.equals(protocol))
390 registerPDBFile(pdb.id.trim(), pdbFile);
392 } catch (Exception ex)
394 ex.printStackTrace();
402 siftsClient = new SiftsClient(pdb);
404 } catch (SiftsException e)
406 isMapUsingSIFTs = false;
410 String targetChainId;
411 for (int s = 0; s < sequenceArray.length; s++)
413 boolean infChain = true;
414 final SequenceI seq = sequenceArray[s];
415 if (targetChainIds != null && targetChainIds[s] != null)
418 targetChainId = targetChainIds[s];
420 else if (seq.getName().indexOf("|") > -1)
422 targetChainId = seq.getName().substring(
423 seq.getName().lastIndexOf("|") + 1);
424 if (targetChainId.length() > 1)
426 if (targetChainId.trim().length() == 0)
432 // not a valid chain identifier
443 * Attempt pairwise alignment of the sequence with each chain in the PDB,
444 * and remember the highest scoring chain
447 AlignSeq maxAlignseq = null;
448 String maxChainId = " ";
449 PDBChain maxChain = null;
450 boolean first = true;
451 for (PDBChain chain : pdb.chains)
453 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
456 continue; // don't try to map chains don't match.
458 // TODO: correctly determine sequence type for mixed na/peptide
460 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
461 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
464 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
465 // as.calcScoreMatrix();
466 // as.traceAlignment();
468 if (first || as.maxscore > max
469 || (as.maxscore == max && chain.id.equals(targetChainId)))
475 maxChainId = chain.id;
478 if (maxChain == null)
483 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
485 pdbFile = "INLINE" + pdb.id;
488 ArrayList<StructureMapping> seqToStrucMapping = null;
491 setProgressBar(null);
492 setProgressBar("Obtaining mapping with SIFTS");
495 jalview.datamodel.Mapping sqmpping = maxAlignseq
496 .getMappingFromS1(false);
497 seqToStrucMapping = new ArrayList<StructureMapping>();
498 if (targetChainId != null && !targetChainId.trim().isEmpty())
500 StructureMapping curChainMapping = siftsClient
501 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
502 seqToStrucMapping.add(curChainMapping);
503 maxChainId = targetChainId;
504 PDBChain chain = pdb.findChain(targetChainId);
507 chain.transferResidueAnnotation(curChainMapping, sqmpping);
512 for (PDBChain chain : pdb.chains)
514 StructureMapping curChainMapping = siftsClient
515 .getSiftsStructureMapping(seq, pdbFile, chain.id);
516 seqToStrucMapping.add(curChainMapping);
517 maxChainId = chain.id;
518 chain.transferResidueAnnotation(curChainMapping, sqmpping);
521 } catch (SiftsException e)
525 .println(">>>>>>> SIFTs mapping could not be obtained... Now mapping with NW alignment");
526 setProgressBar(null);
527 setProgressBar("SIFTs mapping could not be obtained... Now mapping with NW alignment");
528 seqToStrucMapping = getNWMappings(seq, pdbFile, maxChainId,
529 maxChain, pdb, maxAlignseq);
534 setProgressBar(null);
535 setProgressBar("Obtaining mapping with NW alignment");
536 seqToStrucMapping = getNWMappings(seq, pdbFile,
537 maxChainId, maxChain, pdb,
541 if (forStructureView)
543 // mappings.add(seqToStrucMapping);
544 mappings.addAll(seqToStrucMapping);
550 private ArrayList<StructureMapping> getNWMappings(SequenceI seq,
552 String maxChainId, PDBChain maxChain, PDBfile pdb,
553 AlignSeq maxAlignseq)
555 final StringBuilder mappingDetails = new StringBuilder(128);
556 mappingDetails.append(NEWLINE).append(
557 "Sequence \u27f7 Structure mapping details");
558 mappingDetails.append(NEWLINE);
560 .append("Method: inferred with Needleman & Wunsch alignment");
561 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
562 .append(NEWLINE).append("Sequence = ")
563 .append(maxChain.sequence.getSequenceAsString());
564 mappingDetails.append(NEWLINE).append("No of residues = ")
565 .append(maxChain.residues.size()).append(NEWLINE)
567 PrintStream ps = new PrintStream(System.out)
570 public void print(String x)
572 mappingDetails.append(x);
576 public void println()
578 mappingDetails.append(NEWLINE);
582 maxAlignseq.printAlignment(ps);
584 mappingDetails.append(NEWLINE).append("PDB start/end ");
585 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
587 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
588 mappingDetails.append(NEWLINE).append("SEQ start/end ");
589 mappingDetails.append(
590 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
592 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
593 + (seq.getStart() - 1)));
594 mappingDetails.append(NEWLINE);
595 maxChain.makeExactMapping(maxAlignseq, seq);
596 jalview.datamodel.Mapping sqmpping = maxAlignseq
597 .getMappingFromS1(false);
598 maxChain.transferRESNUMFeatures(seq, null);
600 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
606 Atom tmp = maxChain.atoms.elementAt(index);
607 if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
609 resNum = tmp.resNumber;
610 if (tmp.alignmentMapping >= -1)
612 // TODO (JAL-1836) address root cause: negative residue no in PDB
614 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
620 } while (index < maxChain.atoms.size());
622 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
623 pdb.id, maxChainId, mapping, mappingDetails.toString());
624 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
625 ArrayList<StructureMapping> mappings = new ArrayList<StructureMapping>();
626 mappings.add(nwMapping);
630 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
632 listeners.removeElement(svl);
633 if (svl instanceof SequenceListener)
635 for (int i = 0; i < listeners.size(); i++)
637 if (listeners.elementAt(i) instanceof StructureListener)
639 ((StructureListener) listeners.elementAt(i))
640 .releaseReferences(svl);
645 if (pdbfiles == null)
651 * Remove mappings to the closed listener's PDB files, but first check if
652 * another listener is still interested
654 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
656 StructureListener sl;
657 for (int i = 0; i < listeners.size(); i++)
659 if (listeners.elementAt(i) instanceof StructureListener)
661 sl = (StructureListener) listeners.elementAt(i);
662 for (String pdbfile : sl.getPdbFile())
664 pdbs.remove(pdbfile);
670 * Rebuild the mappings set, retaining only those which are for 'other' PDB
675 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
676 for (StructureMapping sm : mappings)
678 if (!pdbs.contains(sm.pdbfile))
689 * Propagate mouseover of a single position in a structure
695 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
697 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
698 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
699 mouseOverStructure(atoms);
703 * Propagate mouseover or selection of multiple positions in a structure
707 public void mouseOverStructure(List<AtomSpec> atoms)
709 if (listeners == null)
711 // old or prematurely sent event
714 boolean hasSequenceListener = false;
715 for (int i = 0; i < listeners.size(); i++)
717 if (listeners.elementAt(i) instanceof SequenceListener)
719 hasSequenceListener = true;
722 if (!hasSequenceListener)
727 SearchResults results = new SearchResults();
728 for (AtomSpec atom : atoms)
730 SequenceI lastseq = null;
732 for (StructureMapping sm : mappings)
734 if (sm.pdbfile.equals(atom.getPdbFile())
735 && sm.pdbchain.equals(atom.getChain()))
737 int indexpos = sm.getSeqPos(atom.getPdbResNum());
738 if (lastipos != indexpos && lastseq != sm.sequence)
740 results.addResult(sm.sequence, indexpos, indexpos);
742 lastseq = sm.sequence;
743 // construct highlighted sequence list
744 for (AlignedCodonFrame acf : seqmappings)
746 acf.markMappedRegion(sm.sequence, indexpos, results);
752 for (Object li : listeners)
754 if (li instanceof SequenceListener)
756 ((SequenceListener) li).highlightSequence(results);
762 * highlight regions associated with a position (indexpos) in seq
765 * the sequence that the mouse over occurred on
767 * the absolute position being mouseovered in seq (0 to seq.length())
769 * the sequence position (if -1, seq.findPosition is called to
770 * resolve the residue number)
772 public void mouseOverSequence(SequenceI seq, int indexpos, int index,
775 boolean hasSequenceListeners = handlingVamsasMo
776 || !seqmappings.isEmpty();
777 SearchResults results = null;
780 index = seq.findPosition(indexpos);
782 for (int i = 0; i < listeners.size(); i++)
784 Object listener = listeners.elementAt(i);
785 if (listener == source)
787 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
788 // Temporary fudge with SequenceListener.getVamsasSource()
791 if (listener instanceof StructureListener)
793 highlightStructure((StructureListener) listener, seq, index);
797 if (listener instanceof SequenceListener)
799 final SequenceListener seqListener = (SequenceListener) listener;
800 if (hasSequenceListeners
801 && seqListener.getVamsasSource() != source)
803 if (relaySeqMappings)
807 results = MappingUtils.buildSearchResults(seq, index,
810 if (handlingVamsasMo)
812 results.addResult(seq, index, index);
815 if (!results.isEmpty())
817 seqListener.highlightSequence(results);
822 else if (listener instanceof VamsasListener && !handlingVamsasMo)
824 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
827 else if (listener instanceof SecondaryStructureListener)
829 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
837 * Send suitable messages to a StructureListener to highlight atoms
838 * corresponding to the given sequence position.
844 protected void highlightStructure(StructureListener sl, SequenceI seq,
847 if (!sl.isListeningFor(seq))
852 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
853 for (StructureMapping sm : mappings)
855 if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
857 atomNo = sm.getAtomNum(index);
861 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
862 .getPDBResNum(index), atomNo));
866 sl.highlightAtoms(atoms);
870 * true if a mouse over event from an external (ie Vamsas) source is being
873 boolean handlingVamsasMo = false;
878 * as mouseOverSequence but only route event to SequenceListeners
882 * in an alignment sequence
884 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
887 handlingVamsasMo = true;
888 long msg = sequenceI.hashCode() * (1 + position);
892 mouseOverSequence(sequenceI, position, -1, source);
894 handlingVamsasMo = false;
897 public Annotation[] colourSequenceFromStructure(SequenceI seq,
901 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
902 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
904 * Annotation [] annotations = new Annotation[seq.getLength()];
906 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
907 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
908 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
910 * for (int j = 0; j < mappings.length; j++) {
912 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
913 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
914 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
915 * "+mappings[j].pdbfile);
917 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
918 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
920 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
921 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
922 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
923 * mappings[j].pdbfile); }
925 * annotations[index] = new Annotation("X",null,' ',0,col); } return
926 * annotations; } } } }
928 * return annotations;
932 public void structureSelectionChanged()
936 public void sequenceSelectionChanged()
940 public void sequenceColoursChanged(Object source)
942 StructureListener sl;
943 for (int i = 0; i < listeners.size(); i++)
945 if (listeners.elementAt(i) instanceof StructureListener)
947 sl = (StructureListener) listeners.elementAt(i);
948 sl.updateColours(source);
953 public StructureMapping[] getMapping(String pdbfile)
955 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
956 for (StructureMapping sm : mappings)
958 if (sm.pdbfile.equals(pdbfile))
963 return tmp.toArray(new StructureMapping[tmp.size()]);
967 * Returns a readable description of all mappings for the given pdbfile to any
968 * of the given sequences
974 public String printMappings(String pdbfile, List<SequenceI> seqs)
976 if (pdbfile == null || seqs == null || seqs.isEmpty())
981 StringBuilder sb = new StringBuilder(64);
982 for (StructureMapping sm : mappings)
984 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
986 sb.append(sm.mappingDetails);
988 // separator makes it easier to read multiple mappings
989 sb.append("=====================");
995 return sb.toString();
999 * Remove the given mapping
1003 public void deregisterMapping(AlignedCodonFrame acf)
1007 boolean removed = seqmappings.remove(acf);
1008 if (removed && seqmappings.isEmpty())
1010 System.out.println("All mappings removed");
1016 * Add each of the given codonFrames to the stored set, if not aready present.
1020 public void registerMappings(List<AlignedCodonFrame> mappings)
1022 if (mappings != null)
1024 for (AlignedCodonFrame acf : mappings)
1026 registerMapping(acf);
1032 * Add the given mapping to the stored set, unless already stored.
1034 public void registerMapping(AlignedCodonFrame acf)
1038 if (!seqmappings.contains(acf))
1040 seqmappings.add(acf);
1046 * Resets this object to its initial state by removing all registered
1047 * listeners, codon mappings, PDB file mappings
1049 public void resetAll()
1051 if (mappings != null)
1055 if (seqmappings != null)
1057 seqmappings.clear();
1059 if (sel_listeners != null)
1061 sel_listeners.clear();
1063 if (listeners != null)
1067 if (commandListeners != null)
1069 commandListeners.clear();
1071 if (view_listeners != null)
1073 view_listeners.clear();
1075 if (pdbFileNameId != null)
1077 pdbFileNameId.clear();
1079 if (pdbIdFileName != null)
1081 pdbIdFileName.clear();
1085 public void addSelectionListener(SelectionListener selecter)
1087 if (!sel_listeners.contains(selecter))
1089 sel_listeners.add(selecter);
1093 public void removeSelectionListener(SelectionListener toremove)
1095 if (sel_listeners.contains(toremove))
1097 sel_listeners.remove(toremove);
1101 public synchronized void sendSelection(
1102 jalview.datamodel.SequenceGroup selection,
1103 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1105 for (SelectionListener slis : sel_listeners)
1109 slis.selection(selection, colsel, source);
1114 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1116 public synchronized void sendViewPosition(
1117 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1118 int startSeq, int endSeq)
1121 if (view_listeners != null && view_listeners.size() > 0)
1123 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1125 while (listeners.hasMoreElements())
1127 AlignmentViewPanelListener slis = listeners.nextElement();
1130 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1138 * release all references associated with this manager provider
1140 * @param jalviewLite
1142 public static void release(StructureSelectionManagerProvider jalviewLite)
1144 // synchronized (instances)
1146 if (instances == null)
1150 StructureSelectionManager mnger = (instances.get(jalviewLite));
1153 instances.remove(jalviewLite);
1157 } catch (Throwable x)
1164 public void registerPDBEntry(PDBEntry pdbentry)
1166 if (pdbentry.getFile() != null
1167 && pdbentry.getFile().trim().length() > 0)
1169 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1173 public void addCommandListener(CommandListener cl)
1175 if (!commandListeners.contains(cl))
1177 commandListeners.add(cl);
1181 public boolean hasCommandListener(CommandListener cl)
1183 return this.commandListeners.contains(cl);
1186 public boolean removeCommandListener(CommandListener l)
1188 return commandListeners.remove(l);
1192 * Forward a command to any command listeners (except for the command's
1196 * the command to be broadcast (in its form after being performed)
1198 * if true, the command was being 'undone'
1201 public void commandPerformed(CommandI command, boolean undo,
1202 VamsasSource source)
1204 for (CommandListener listener : commandListeners)
1206 listener.mirrorCommand(command, undo, this, source);
1211 * Returns a new CommandI representing the given command as mapped to the
1212 * given sequences. If no mapping could be made, or the command is not of a
1213 * mappable kind, returns null.
1221 public CommandI mapCommand(CommandI command, boolean undo,
1222 final AlignmentI mapTo, char gapChar)
1224 if (command instanceof EditCommand)
1226 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1227 mapTo, gapChar, seqmappings);
1229 else if (command instanceof OrderCommand)
1231 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1232 mapTo, seqmappings);
1237 public IProgressIndicator getProgressIndicator()
1239 return progressIndicator;
1242 public void setProgressIndicator(IProgressIndicator progressIndicator)
1244 this.progressIndicator = progressIndicator;
1247 public long getProgressSessionId()
1249 return progressSessionId;
1252 public void setProgressSessionId(long progressSessionId)
1254 this.progressSessionId = progressSessionId;
1257 public void setProgressBar(String message)
1259 progressIndicator.setProgressBar(message, progressSessionId);
1262 public List<AlignedCodonFrame> getSequenceMappings()