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.LinkedHashSet;
51 import java.util.List;
54 import java.util.Vector;
57 import MCview.PDBChain;
58 import MCview.PDBfile;
60 public class StructureSelectionManager
62 public final static String NEWLINE = System.lineSeparator();
64 static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
66 private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
68 private boolean processSecondaryStructure = false;
70 private boolean secStructServices = false;
72 private boolean addTempFacAnnot = false;
74 private IProgressIndicator progressIndicator;
76 private SiftsClient siftsClient = null;
78 private long progressSessionId;
81 * Set of any registered mappings between (dataset) sequences.
83 public Set<AlignedCodonFrame> seqmappings = new LinkedHashSet<AlignedCodonFrame>();
85 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
87 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
90 * @return true if will try to use external services for processing secondary
93 public boolean isSecStructServices()
95 return secStructServices;
99 * control use of external services for processing secondary structure
101 * @param secStructServices
103 public void setSecStructServices(boolean secStructServices)
105 this.secStructServices = secStructServices;
109 * flag controlling addition of any kind of structural annotation
111 * @return true if temperature factor annotation will be added
113 public boolean isAddTempFacAnnot()
115 return addTempFacAnnot;
119 * set flag controlling addition of structural annotation
121 * @param addTempFacAnnot
123 public void setAddTempFacAnnot(boolean addTempFacAnnot)
125 this.addTempFacAnnot = addTempFacAnnot;
130 * @return if true, the structure manager will attempt to add secondary
131 * structure lines for unannotated sequences
134 public boolean isProcessSecondaryStructure()
136 return processSecondaryStructure;
140 * Control whether structure manager will try to annotate mapped sequences
141 * with secondary structure from PDB data.
145 public void setProcessSecondaryStructure(boolean enable)
147 processSecondaryStructure = enable;
151 * debug function - write all mappings to stdout
153 public void reportMapping()
155 if (mappings.isEmpty())
157 System.err.println("reportMapping: No PDB/Sequence mappings.");
161 System.err.println("reportMapping: There are " + mappings.size()
164 for (StructureMapping sm : mappings)
166 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
172 * map between the PDB IDs (or structure identifiers) used by Jalview and the
173 * absolute filenames for PDB data that corresponds to it
175 Map<String, String> pdbIdFileName = new HashMap<String, String>();
177 Map<String, String> pdbFileNameId = new HashMap<String, String>();
179 public void registerPDBFile(String idForFile, String absoluteFile)
181 pdbIdFileName.put(idForFile, absoluteFile);
182 pdbFileNameId.put(absoluteFile, idForFile);
185 public String findIdForPDBFile(String idOrFile)
187 String id = pdbFileNameId.get(idOrFile);
191 public String findFileForPDBId(String idOrFile)
193 String id = pdbIdFileName.get(idOrFile);
197 public boolean isPDBFileRegistered(String idOrFile)
199 return pdbFileNameId.containsKey(idOrFile)
200 || pdbIdFileName.containsKey(idOrFile);
203 private static StructureSelectionManager nullProvider = null;
205 public static StructureSelectionManager getStructureSelectionManager(
206 StructureSelectionManagerProvider context)
210 if (nullProvider == null)
212 if (instances != null)
216 .getString("error.implementation_error_structure_selection_manager_null"),
217 new NullPointerException(MessageManager
218 .getString("exception.ssm_context_is_null")));
222 nullProvider = new StructureSelectionManager();
227 if (instances == null)
229 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
231 StructureSelectionManager instance = instances.get(context);
232 if (instance == null)
234 if (nullProvider != null)
236 instance = nullProvider;
240 instance = new StructureSelectionManager();
242 instances.put(context, instance);
248 * flag controlling whether SeqMappings are relayed from received sequence
249 * mouse over events to other sequences
251 boolean relaySeqMappings = true;
254 * Enable or disable relay of seqMapping events to other sequences. You might
255 * want to do this if there are many sequence mappings and the host computer
260 public void setRelaySeqMappings(boolean relay)
262 relaySeqMappings = relay;
266 * get the state of the relay seqMappings flag.
268 * @return true if sequence mouse overs are being relayed to other mapped
271 public boolean isRelaySeqMappingsEnabled()
273 return relaySeqMappings;
276 Vector listeners = new Vector();
279 * register a listener for alignment sequence mouseover events
283 public void addStructureViewerListener(Object svl)
285 if (!listeners.contains(svl))
287 listeners.addElement(svl);
292 * Returns the file name for a mapped PDB id (or null if not mapped).
297 public String alreadyMappedToFile(String pdbid)
299 for (StructureMapping sm : mappings)
301 if (sm.getPdbId().equals(pdbid))
310 * Import structure data and register a structure mapping for broadcasting
311 * colouring, mouseovers and selection events (convenience wrapper).
314 * - one or more sequences to be mapped to pdbFile
315 * @param targetChains
316 * - optional chain specification for mapping each sequence to pdb
317 * (may be nill, individual elements may be nill)
319 * - structure data resource
321 * - how to resolve data from resource
322 * @return null or the structure data parsed as a pdb file
324 synchronized public PDBfile setMapping(SequenceI[] sequence,
325 String[] targetChains, String pdbFile, String protocol)
327 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 PDBfile 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)))
384 boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
387 pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
390 if (pdb.getId() != null && pdb.getId().trim().length() > 0
391 && AppletFormatAdapter.FILE.equals(protocol))
393 registerPDBFile(pdb.getId().trim(), pdbFile);
395 } catch (Exception ex)
397 ex.printStackTrace();
405 siftsClient = new SiftsClient(pdb);
407 } catch (SiftsException e)
409 isMapUsingSIFTs = false;
413 String targetChainId;
414 for (int s = 0; s < sequenceArray.length; s++)
416 boolean infChain = true;
417 final SequenceI seq = sequenceArray[s];
418 if (targetChainIds != null && targetChainIds[s] != null)
421 targetChainId = targetChainIds[s];
423 else if (seq.getName().indexOf("|") > -1)
425 targetChainId = seq.getName().substring(
426 seq.getName().lastIndexOf("|") + 1);
427 if (targetChainId.length() > 1)
429 if (targetChainId.trim().length() == 0)
435 // not a valid chain identifier
446 * Attempt pairwise alignment of the sequence with each chain in the PDB,
447 * and remember the highest scoring chain
450 AlignSeq maxAlignseq = null;
451 String maxChainId = " ";
452 PDBChain maxChain = null;
453 boolean first = true;
454 for (PDBChain chain : pdb.getChains())
456 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
459 continue; // don't try to map chains don't match.
461 // TODO: correctly determine sequence type for mixed na/peptide
463 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
464 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
467 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
468 // as.calcScoreMatrix();
469 // as.traceAlignment();
471 if (first || as.maxscore > max
472 || (as.maxscore == max && chain.id.equals(targetChainId)))
478 maxChainId = chain.id;
481 if (maxChain == null)
486 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
488 pdbFile = "INLINE" + pdb.getId();
491 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
494 setProgressBar(null);
495 setProgressBar("Obtaining mapping with SIFTS");
496 jalview.datamodel.Mapping sqmpping = maxAlignseq
497 .getMappingFromS1(false);
498 if (targetChainId != null && !targetChainId.trim().isEmpty())
500 StructureMapping mapping = getStructureMapping(seq, pdbFile,
501 targetChainId, pdb, maxChain, sqmpping, maxAlignseq);
502 seqToStrucMapping.add(mapping);
506 for (PDBChain chain : pdb.getChains())
508 StructureMapping mapping = getStructureMapping(seq, pdbFile,
509 chain.id, pdb, chain, sqmpping, maxAlignseq);
510 seqToStrucMapping.add(mapping);
516 setProgressBar(null);
517 setProgressBar("Obtaining mapping with NW alignment");
518 seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
519 maxChain, pdb, maxAlignseq));
522 if (forStructureView)
524 mappings.addAll(seqToStrucMapping);
530 private StructureMapping getStructureMapping(SequenceI seq,
531 String pdbFile, String targetChainId, PDBfile pdb,
532 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
533 AlignSeq maxAlignseq)
535 String maxChainId = targetChainId;
538 StructureMapping curChainMapping = siftsClient
539 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
542 PDBChain chain = pdb.findChain(targetChainId);
545 chain.transferResidueAnnotation(curChainMapping, sqmpping);
547 } catch (Exception e)
551 return curChainMapping;
552 } catch (SiftsException e)
554 System.err.println(e.getMessage());
555 System.err.println(">>> Now switching mapping with NW alignment...");
556 setProgressBar(null);
557 setProgressBar(">>> Now switching mapping with NW alignment...");
558 return getNWMappings(seq, pdbFile, maxChainId, maxChain, pdb,
563 private StructureMapping getNWMappings(SequenceI seq,
565 String maxChainId, PDBChain maxChain, PDBfile pdb,
566 AlignSeq maxAlignseq)
568 final StringBuilder mappingDetails = new StringBuilder(128);
569 mappingDetails.append(NEWLINE).append(
570 "Sequence \u27f7 Structure mapping details");
571 mappingDetails.append(NEWLINE);
573 .append("Method: inferred with Needleman & Wunsch alignment");
574 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
575 .append(NEWLINE).append("Sequence = ")
576 .append(maxChain.sequence.getSequenceAsString());
577 mappingDetails.append(NEWLINE).append("No of residues = ")
578 .append(maxChain.residues.size()).append(NEWLINE)
580 PrintStream ps = new PrintStream(System.out)
583 public void print(String x)
585 mappingDetails.append(x);
589 public void println()
591 mappingDetails.append(NEWLINE);
595 maxAlignseq.printAlignment(ps);
597 mappingDetails.append(NEWLINE).append("PDB start/end ");
598 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
600 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
601 mappingDetails.append(NEWLINE).append("SEQ start/end ");
602 mappingDetails.append(
603 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
605 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
606 + (seq.getStart() - 1)));
607 mappingDetails.append(NEWLINE);
608 maxChain.makeExactMapping(maxAlignseq, seq);
609 jalview.datamodel.Mapping sqmpping = maxAlignseq
610 .getMappingFromS1(false);
611 maxChain.transferRESNUMFeatures(seq, null);
613 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
620 Atom tmp = maxChain.atoms.elementAt(index);
621 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
622 && tmp.alignmentMapping != -1)
624 resNum = tmp.resNumber;
625 insCode = tmp.insCode;
626 if (tmp.alignmentMapping >= -1)
628 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
634 } while (index < maxChain.atoms.size());
636 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
637 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
638 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
642 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
644 listeners.removeElement(svl);
645 if (svl instanceof SequenceListener)
647 for (int i = 0; i < listeners.size(); i++)
649 if (listeners.elementAt(i) instanceof StructureListener)
651 ((StructureListener) listeners.elementAt(i))
652 .releaseReferences(svl);
657 if (pdbfiles == null)
663 * Remove mappings to the closed listener's PDB files, but first check if
664 * another listener is still interested
666 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
668 StructureListener sl;
669 for (int i = 0; i < listeners.size(); i++)
671 if (listeners.elementAt(i) instanceof StructureListener)
673 sl = (StructureListener) listeners.elementAt(i);
674 for (String pdbfile : sl.getPdbFile())
676 pdbs.remove(pdbfile);
682 * Rebuild the mappings set, retaining only those which are for 'other' PDB
687 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
688 for (StructureMapping sm : mappings)
690 if (!pdbs.contains(sm.pdbfile))
701 * Propagate mouseover of a single position in a structure
707 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
709 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
710 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
711 mouseOverStructure(atoms);
715 * Propagate mouseover or selection of multiple positions in a structure
719 public void mouseOverStructure(List<AtomSpec> atoms)
721 if (listeners == null)
723 // old or prematurely sent event
726 boolean hasSequenceListener = false;
727 for (int i = 0; i < listeners.size(); i++)
729 if (listeners.elementAt(i) instanceof SequenceListener)
731 hasSequenceListener = true;
734 if (!hasSequenceListener)
739 SearchResults results = new SearchResults();
740 for (AtomSpec atom : atoms)
742 SequenceI lastseq = null;
744 for (StructureMapping sm : mappings)
746 if (sm.pdbfile.equals(atom.getPdbFile())
747 && sm.pdbchain.equals(atom.getChain()))
749 int indexpos = sm.getSeqPos(atom.getPdbResNum());
750 if (lastipos != indexpos && lastseq != sm.sequence)
752 results.addResult(sm.sequence, indexpos, indexpos);
754 lastseq = sm.sequence;
755 // construct highlighted sequence list
756 for (AlignedCodonFrame acf : seqmappings)
758 acf.markMappedRegion(sm.sequence, indexpos, results);
764 for (Object li : listeners)
766 if (li instanceof SequenceListener)
768 ((SequenceListener) li).highlightSequence(results);
774 * highlight regions associated with a position (indexpos) in seq
777 * the sequence that the mouse over occurred on
779 * the absolute position being mouseovered in seq (0 to seq.length())
781 * the sequence position (if -1, seq.findPosition is called to
782 * resolve the residue number)
784 public void mouseOverSequence(SequenceI seq, int indexpos, int index,
787 boolean hasSequenceListeners = handlingVamsasMo
788 || !seqmappings.isEmpty();
789 SearchResults results = null;
792 index = seq.findPosition(indexpos);
794 for (int i = 0; i < listeners.size(); i++)
796 Object listener = listeners.elementAt(i);
797 if (listener == source)
799 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
800 // Temporary fudge with SequenceListener.getVamsasSource()
803 if (listener instanceof StructureListener)
805 highlightStructure((StructureListener) listener, seq, index);
809 if (listener instanceof SequenceListener)
811 final SequenceListener seqListener = (SequenceListener) listener;
812 if (hasSequenceListeners
813 && seqListener.getVamsasSource() != source)
815 if (relaySeqMappings)
819 results = MappingUtils.buildSearchResults(seq, index,
822 if (handlingVamsasMo)
824 results.addResult(seq, index, index);
827 if (!results.isEmpty())
829 seqListener.highlightSequence(results);
834 else if (listener instanceof VamsasListener && !handlingVamsasMo)
836 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
839 else if (listener instanceof SecondaryStructureListener)
841 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
849 * Send suitable messages to a StructureListener to highlight atoms
850 * corresponding to the given sequence position.
856 protected void highlightStructure(StructureListener sl, SequenceI seq,
859 if (!sl.isListeningFor(seq))
864 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
865 for (StructureMapping sm : mappings)
867 if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
869 atomNo = sm.getAtomNum(index);
873 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
874 .getPDBResNum(index), atomNo));
878 sl.highlightAtoms(atoms);
882 * true if a mouse over event from an external (ie Vamsas) source is being
885 boolean handlingVamsasMo = false;
890 * as mouseOverSequence but only route event to SequenceListeners
894 * in an alignment sequence
896 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
899 handlingVamsasMo = true;
900 long msg = sequenceI.hashCode() * (1 + position);
904 mouseOverSequence(sequenceI, position, -1, source);
906 handlingVamsasMo = false;
909 public Annotation[] colourSequenceFromStructure(SequenceI seq,
913 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
914 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
916 * Annotation [] annotations = new Annotation[seq.getLength()];
918 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
919 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
920 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
922 * for (int j = 0; j < mappings.length; j++) {
924 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
925 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
926 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
927 * "+mappings[j].pdbfile);
929 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
930 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
932 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
933 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
934 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
935 * mappings[j].pdbfile); }
937 * annotations[index] = new Annotation("X",null,' ',0,col); } return
938 * annotations; } } } }
940 * return annotations;
944 public void structureSelectionChanged()
948 public void sequenceSelectionChanged()
952 public void sequenceColoursChanged(Object source)
954 StructureListener sl;
955 for (int i = 0; i < listeners.size(); i++)
957 if (listeners.elementAt(i) instanceof StructureListener)
959 sl = (StructureListener) listeners.elementAt(i);
960 sl.updateColours(source);
965 public StructureMapping[] getMapping(String pdbfile)
967 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
968 for (StructureMapping sm : mappings)
970 if (sm.pdbfile.equals(pdbfile))
975 return tmp.toArray(new StructureMapping[tmp.size()]);
979 * Returns a readable description of all mappings for the given pdbfile to any
980 * of the given sequences
986 public String printMappings(String pdbfile, List<SequenceI> seqs)
988 if (pdbfile == null || seqs == null || seqs.isEmpty())
993 StringBuilder sb = new StringBuilder(64);
994 for (StructureMapping sm : mappings)
996 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
998 sb.append(sm.mappingDetails);
1000 // separator makes it easier to read multiple mappings
1001 sb.append("=====================");
1007 return sb.toString();
1011 * Remove the given mapping
1015 public void deregisterMapping(AlignedCodonFrame acf)
1019 boolean removed = seqmappings.remove(acf);
1020 if (removed && seqmappings.isEmpty())
1022 System.out.println("All mappings removed");
1028 * Add each of the given codonFrames to the stored set, if not aready present.
1032 public void registerMappings(Set<AlignedCodonFrame> set)
1036 for (AlignedCodonFrame acf : set)
1038 registerMapping(acf);
1044 * Add the given mapping to the stored set, unless already stored.
1046 public void registerMapping(AlignedCodonFrame acf)
1050 if (!seqmappings.contains(acf))
1052 seqmappings.add(acf);
1058 * Resets this object to its initial state by removing all registered
1059 * listeners, codon mappings, PDB file mappings
1061 public void resetAll()
1063 if (mappings != null)
1067 if (seqmappings != null)
1069 seqmappings.clear();
1071 if (sel_listeners != null)
1073 sel_listeners.clear();
1075 if (listeners != null)
1079 if (commandListeners != null)
1081 commandListeners.clear();
1083 if (view_listeners != null)
1085 view_listeners.clear();
1087 if (pdbFileNameId != null)
1089 pdbFileNameId.clear();
1091 if (pdbIdFileName != null)
1093 pdbIdFileName.clear();
1097 public void addSelectionListener(SelectionListener selecter)
1099 if (!sel_listeners.contains(selecter))
1101 sel_listeners.add(selecter);
1105 public void removeSelectionListener(SelectionListener toremove)
1107 if (sel_listeners.contains(toremove))
1109 sel_listeners.remove(toremove);
1113 public synchronized void sendSelection(
1114 jalview.datamodel.SequenceGroup selection,
1115 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1117 for (SelectionListener slis : sel_listeners)
1121 slis.selection(selection, colsel, source);
1126 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1128 public synchronized void sendViewPosition(
1129 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1130 int startSeq, int endSeq)
1133 if (view_listeners != null && view_listeners.size() > 0)
1135 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1137 while (listeners.hasMoreElements())
1139 AlignmentViewPanelListener slis = listeners.nextElement();
1142 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1150 * release all references associated with this manager provider
1152 * @param jalviewLite
1154 public static void release(StructureSelectionManagerProvider jalviewLite)
1156 // synchronized (instances)
1158 if (instances == null)
1162 StructureSelectionManager mnger = (instances.get(jalviewLite));
1165 instances.remove(jalviewLite);
1169 } catch (Throwable x)
1176 public void registerPDBEntry(PDBEntry pdbentry)
1178 if (pdbentry.getFile() != null
1179 && pdbentry.getFile().trim().length() > 0)
1181 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1185 public void addCommandListener(CommandListener cl)
1187 if (!commandListeners.contains(cl))
1189 commandListeners.add(cl);
1193 public boolean hasCommandListener(CommandListener cl)
1195 return this.commandListeners.contains(cl);
1198 public boolean removeCommandListener(CommandListener l)
1200 return commandListeners.remove(l);
1204 * Forward a command to any command listeners (except for the command's
1208 * the command to be broadcast (in its form after being performed)
1210 * if true, the command was being 'undone'
1213 public void commandPerformed(CommandI command, boolean undo,
1214 VamsasSource source)
1216 for (CommandListener listener : commandListeners)
1218 listener.mirrorCommand(command, undo, this, source);
1223 * Returns a new CommandI representing the given command as mapped to the
1224 * given sequences. If no mapping could be made, or the command is not of a
1225 * mappable kind, returns null.
1233 public CommandI mapCommand(CommandI command, boolean undo,
1234 final AlignmentI mapTo, char gapChar)
1236 if (command instanceof EditCommand)
1238 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1239 mapTo, gapChar, seqmappings);
1241 else if (command instanceof OrderCommand)
1243 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1244 mapTo, seqmappings);
1249 public IProgressIndicator getProgressIndicator()
1251 return progressIndicator;
1254 public void setProgressIndicator(IProgressIndicator progressIndicator)
1256 this.progressIndicator = progressIndicator;
1259 public long getProgressSessionId()
1261 return progressSessionId;
1264 public void setProgressSessionId(long progressSessionId)
1266 this.progressSessionId = progressSessionId;
1269 public void setProgressBar(String message)
1271 progressIndicator.setProgressBar(message, progressSessionId);