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 SiftsClient siftsClient = null;
76 private long progressSessionId;
79 * Set of any registered mappings between (dataset) sequences.
81 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
83 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
85 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
88 * @return true if will try to use external services for processing secondary
91 public boolean isSecStructServices()
93 return secStructServices;
97 * control use of external services for processing secondary structure
99 * @param secStructServices
101 public void setSecStructServices(boolean secStructServices)
103 this.secStructServices = secStructServices;
107 * flag controlling addition of any kind of structural annotation
109 * @return true if temperature factor annotation will be added
111 public boolean isAddTempFacAnnot()
113 return addTempFacAnnot;
117 * set flag controlling addition of structural annotation
119 * @param addTempFacAnnot
121 public void setAddTempFacAnnot(boolean addTempFacAnnot)
123 this.addTempFacAnnot = addTempFacAnnot;
128 * @return if true, the structure manager will attempt to add secondary
129 * structure lines for unannotated sequences
132 public boolean isProcessSecondaryStructure()
134 return processSecondaryStructure;
138 * Control whether structure manager will try to annotate mapped sequences
139 * with secondary structure from PDB data.
143 public void setProcessSecondaryStructure(boolean enable)
145 processSecondaryStructure = enable;
149 * debug function - write all mappings to stdout
151 public void reportMapping()
153 if (mappings.isEmpty())
155 System.err.println("reportMapping: No PDB/Sequence mappings.");
159 System.err.println("reportMapping: There are " + mappings.size()
162 for (StructureMapping sm : mappings)
164 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
170 * map between the PDB IDs (or structure identifiers) used by Jalview and the
171 * absolute filenames for PDB data that corresponds to it
173 Map<String, String> pdbIdFileName = new HashMap<String, String>();
175 Map<String, String> pdbFileNameId = new HashMap<String, String>();
177 public void registerPDBFile(String idForFile, String absoluteFile)
179 pdbIdFileName.put(idForFile, absoluteFile);
180 pdbFileNameId.put(absoluteFile, idForFile);
183 public String findIdForPDBFile(String idOrFile)
185 String id = pdbFileNameId.get(idOrFile);
189 public String findFileForPDBId(String idOrFile)
191 String id = pdbIdFileName.get(idOrFile);
195 public boolean isPDBFileRegistered(String idOrFile)
197 return pdbFileNameId.containsKey(idOrFile)
198 || pdbIdFileName.containsKey(idOrFile);
201 private static StructureSelectionManager nullProvider = null;
203 public static StructureSelectionManager getStructureSelectionManager(
204 StructureSelectionManagerProvider context)
208 if (nullProvider == null)
210 if (instances != null)
214 .getString("error.implementation_error_structure_selection_manager_null"),
215 new NullPointerException(MessageManager
216 .getString("exception.ssm_context_is_null")));
220 nullProvider = new StructureSelectionManager();
225 if (instances == null)
227 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
229 StructureSelectionManager instance = instances.get(context);
230 if (instance == null)
232 if (nullProvider != null)
234 instance = nullProvider;
238 instance = new StructureSelectionManager();
240 instances.put(context, instance);
246 * flag controlling whether SeqMappings are relayed from received sequence
247 * mouse over events to other sequences
249 boolean relaySeqMappings = true;
252 * Enable or disable relay of seqMapping events to other sequences. You might
253 * want to do this if there are many sequence mappings and the host computer
258 public void setRelaySeqMappings(boolean relay)
260 relaySeqMappings = relay;
264 * get the state of the relay seqMappings flag.
266 * @return true if sequence mouse overs are being relayed to other mapped
269 public boolean isRelaySeqMappingsEnabled()
271 return relaySeqMappings;
274 Vector listeners = new Vector();
277 * register a listener for alignment sequence mouseover events
281 public void addStructureViewerListener(Object svl)
283 if (!listeners.contains(svl))
285 listeners.addElement(svl);
290 * Returns the file name for a mapped PDB id (or null if not mapped).
295 public String alreadyMappedToFile(String pdbid)
297 for (StructureMapping sm : mappings)
299 if (sm.getPdbId().equals(pdbid))
308 * Import structure data and register a structure mapping for broadcasting
309 * colouring, mouseovers and selection events (convenience wrapper).
312 * - one or more sequences to be mapped to pdbFile
313 * @param targetChains
314 * - optional chain specification for mapping each sequence to pdb
315 * (may be nill, individual elements may be nill)
317 * - structure data resource
319 * - how to resolve data from resource
320 * @return null or the structure data parsed as a pdb file
322 synchronized public PDBfile setMapping(SequenceI[] sequence,
323 String[] targetChains, String pdbFile, String protocol)
325 return setMapping(true, sequence, targetChains, pdbFile, protocol);
329 * create sequence structure mappings between each sequence and the given
330 * pdbFile (retrieved via the given protocol).
332 * @param forStructureView
333 * when true, record the mapping for use in mouseOvers
335 * @param sequenceArray
336 * - one or more sequences to be mapped to pdbFile
337 * @param targetChainIds
338 * - optional chain specification for mapping each sequence to pdb
339 * (may be nill, individual elements may be nill)
341 * - structure data resource
343 * - how to resolve data from resource
344 * @return null or the structure data parsed as a pdb file
346 synchronized public PDBfile setMapping(boolean forStructureView,
347 SequenceI[] sequenceArray, String[] targetChainIds,
352 * There will be better ways of doing this in the future, for now we'll use
353 * the tried and tested MCview pdb mapping
355 boolean parseSecStr = processSecondaryStructure;
356 if (isPDBFileRegistered(pdbFile))
358 for (SequenceI sq : sequenceArray)
361 while (ds.getDatasetSequence() != null)
363 ds = ds.getDatasetSequence();
366 if (ds.getAnnotation() != null)
368 for (AlignmentAnnotation ala : ds.getAnnotation())
370 // false if any annotation present from this structure
371 // JBPNote this fails for jmol/chimera view because the *file* is
372 // passed, not the structure data ID -
373 if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
382 boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
385 pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
388 if (pdb.id != null && pdb.id.trim().length() > 0
389 && AppletFormatAdapter.FILE.equals(protocol))
391 registerPDBFile(pdb.id.trim(), pdbFile);
393 } catch (Exception ex)
395 ex.printStackTrace();
403 siftsClient = new SiftsClient(pdb);
405 } catch (SiftsException e)
407 isMapUsingSIFTs = false;
411 String targetChainId;
412 for (int s = 0; s < sequenceArray.length; s++)
414 boolean infChain = true;
415 final SequenceI seq = sequenceArray[s];
416 if (targetChainIds != null && targetChainIds[s] != null)
419 targetChainId = targetChainIds[s];
421 else if (seq.getName().indexOf("|") > -1)
423 targetChainId = seq.getName().substring(
424 seq.getName().lastIndexOf("|") + 1);
425 if (targetChainId.length() > 1)
427 if (targetChainId.trim().length() == 0)
433 // not a valid chain identifier
444 * Attempt pairwise alignment of the sequence with each chain in the PDB,
445 * and remember the highest scoring chain
448 AlignSeq maxAlignseq = null;
449 String maxChainId = " ";
450 PDBChain maxChain = null;
451 boolean first = true;
452 for (PDBChain chain : pdb.chains)
454 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
457 continue; // don't try to map chains don't match.
459 // TODO: correctly determine sequence type for mixed na/peptide
461 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
462 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
465 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
466 // as.calcScoreMatrix();
467 // as.traceAlignment();
469 if (first || as.maxscore > max
470 || (as.maxscore == max && chain.id.equals(targetChainId)))
476 maxChainId = chain.id;
479 if (maxChain == null)
484 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
486 pdbFile = "INLINE" + pdb.id;
489 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
492 setProgressBar(null);
493 setProgressBar("Obtaining mapping with SIFTS");
494 jalview.datamodel.Mapping sqmpping = maxAlignseq
495 .getMappingFromS1(false);
496 if (targetChainId != null && !targetChainId.trim().isEmpty())
498 StructureMapping mapping = getStructureMapping(seq, pdbFile,
499 targetChainId, pdb, maxChain, sqmpping, maxAlignseq);
500 seqToStrucMapping.add(mapping);
504 for (PDBChain chain : pdb.chains)
506 StructureMapping mapping = getStructureMapping(seq, pdbFile,
507 chain.id, pdb, chain, sqmpping, maxAlignseq);
508 seqToStrucMapping.add(mapping);
514 setProgressBar(null);
515 setProgressBar("Obtaining mapping with NW alignment");
516 seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
517 maxChain, pdb, maxAlignseq));
520 if (forStructureView)
522 mappings.addAll(seqToStrucMapping);
528 private StructureMapping getStructureMapping(SequenceI seq,
529 String pdbFile, String targetChainId, PDBfile pdb,
530 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
531 AlignSeq maxAlignseq)
533 String maxChainId = targetChainId;
536 StructureMapping curChainMapping = siftsClient
537 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
538 PDBChain chain = pdb.findChain(targetChainId);
541 chain.transferResidueAnnotation(curChainMapping, sqmpping);
543 return curChainMapping;
544 } catch (SiftsException e)
546 System.err.println(e.getMessage());
547 System.err.println(">>> Now switching mapping with NW alignment...");
548 setProgressBar(null);
549 setProgressBar(">>> Now switching mapping with NW alignment...");
550 return getNWMappings(seq, pdbFile, maxChainId, maxChain, pdb,
555 private StructureMapping getNWMappings(SequenceI seq,
557 String maxChainId, PDBChain maxChain, PDBfile pdb,
558 AlignSeq maxAlignseq)
560 final StringBuilder mappingDetails = new StringBuilder(128);
561 mappingDetails.append(NEWLINE).append(
562 "Sequence \u27f7 Structure mapping details");
563 mappingDetails.append(NEWLINE);
565 .append("Method: inferred with Needleman & Wunsch alignment");
566 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
567 .append(NEWLINE).append("Sequence = ")
568 .append(maxChain.sequence.getSequenceAsString());
569 mappingDetails.append(NEWLINE).append("No of residues = ")
570 .append(maxChain.residues.size()).append(NEWLINE)
572 PrintStream ps = new PrintStream(System.out)
575 public void print(String x)
577 mappingDetails.append(x);
581 public void println()
583 mappingDetails.append(NEWLINE);
587 maxAlignseq.printAlignment(ps);
589 mappingDetails.append(NEWLINE).append("PDB start/end ");
590 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
592 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
593 mappingDetails.append(NEWLINE).append("SEQ start/end ");
594 mappingDetails.append(
595 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
597 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
598 + (seq.getStart() - 1)));
599 mappingDetails.append(NEWLINE);
600 maxChain.makeExactMapping(maxAlignseq, seq);
601 jalview.datamodel.Mapping sqmpping = maxAlignseq
602 .getMappingFromS1(false);
603 maxChain.transferRESNUMFeatures(seq, null);
605 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
611 Atom tmp = maxChain.atoms.elementAt(index);
612 if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
614 resNum = tmp.resNumber;
615 if (tmp.alignmentMapping >= -1)
617 // TODO (JAL-1836) address root cause: negative residue no in PDB
619 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
625 } while (index < maxChain.atoms.size());
627 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
628 pdb.id, maxChainId, mapping, mappingDetails.toString());
629 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
633 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
635 listeners.removeElement(svl);
636 if (svl instanceof SequenceListener)
638 for (int i = 0; i < listeners.size(); i++)
640 if (listeners.elementAt(i) instanceof StructureListener)
642 ((StructureListener) listeners.elementAt(i))
643 .releaseReferences(svl);
648 if (pdbfiles == null)
654 * Remove mappings to the closed listener's PDB files, but first check if
655 * another listener is still interested
657 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
659 StructureListener sl;
660 for (int i = 0; i < listeners.size(); i++)
662 if (listeners.elementAt(i) instanceof StructureListener)
664 sl = (StructureListener) listeners.elementAt(i);
665 for (String pdbfile : sl.getPdbFile())
667 pdbs.remove(pdbfile);
673 * Rebuild the mappings set, retaining only those which are for 'other' PDB
678 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
679 for (StructureMapping sm : mappings)
681 if (!pdbs.contains(sm.pdbfile))
692 * Propagate mouseover of a single position in a structure
698 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
700 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
701 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
702 mouseOverStructure(atoms);
706 * Propagate mouseover or selection of multiple positions in a structure
710 public void mouseOverStructure(List<AtomSpec> atoms)
712 if (listeners == null)
714 // old or prematurely sent event
717 boolean hasSequenceListener = false;
718 for (int i = 0; i < listeners.size(); i++)
720 if (listeners.elementAt(i) instanceof SequenceListener)
722 hasSequenceListener = true;
725 if (!hasSequenceListener)
730 SearchResults results = new SearchResults();
731 for (AtomSpec atom : atoms)
733 SequenceI lastseq = null;
735 for (StructureMapping sm : mappings)
737 if (sm.pdbfile.equals(atom.getPdbFile())
738 && sm.pdbchain.equals(atom.getChain()))
740 int indexpos = sm.getSeqPos(atom.getPdbResNum());
741 if (lastipos != indexpos && lastseq != sm.sequence)
743 results.addResult(sm.sequence, indexpos, indexpos);
745 lastseq = sm.sequence;
746 // construct highlighted sequence list
747 for (AlignedCodonFrame acf : seqmappings)
749 acf.markMappedRegion(sm.sequence, indexpos, results);
755 for (Object li : listeners)
757 if (li instanceof SequenceListener)
759 ((SequenceListener) li).highlightSequence(results);
765 * highlight regions associated with a position (indexpos) in seq
768 * the sequence that the mouse over occurred on
770 * the absolute position being mouseovered in seq (0 to seq.length())
772 * the sequence position (if -1, seq.findPosition is called to
773 * resolve the residue number)
775 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
778 boolean hasSequenceListeners = handlingVamsasMo
779 || !seqmappings.isEmpty();
780 SearchResults results = null;
783 seqPos = seq.findPosition(indexpos);
785 for (int i = 0; i < listeners.size(); i++)
787 Object listener = listeners.elementAt(i);
788 if (listener == source)
790 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
791 // Temporary fudge with SequenceListener.getVamsasSource()
794 if (listener instanceof StructureListener)
796 highlightStructure((StructureListener) listener, seq, seqPos);
800 if (listener instanceof SequenceListener)
802 final SequenceListener seqListener = (SequenceListener) listener;
803 if (hasSequenceListeners
804 && seqListener.getVamsasSource() != source)
806 if (relaySeqMappings)
810 results = MappingUtils.buildSearchResults(seq, seqPos,
813 if (handlingVamsasMo)
815 results.addResult(seq, seqPos, seqPos);
818 if (!results.isEmpty())
820 seqListener.highlightSequence(results);
825 else if (listener instanceof VamsasListener && !handlingVamsasMo)
827 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
830 else if (listener instanceof SecondaryStructureListener)
832 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
840 * Send suitable messages to a StructureListener to highlight atoms
841 * corresponding to the given sequence position(s)
847 public void highlightStructure(StructureListener sl, SequenceI seq,
850 if (!sl.isListeningFor(seq))
855 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
856 for (StructureMapping sm : mappings)
858 if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
860 for (int index : positions)
862 atomNo = sm.getAtomNum(index);
866 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
867 .getPDBResNum(index), atomNo));
872 sl.highlightAtoms(atoms);
876 * true if a mouse over event from an external (ie Vamsas) source is being
879 boolean handlingVamsasMo = false;
884 * as mouseOverSequence but only route event to SequenceListeners
888 * in an alignment sequence
890 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
893 handlingVamsasMo = true;
894 long msg = sequenceI.hashCode() * (1 + position);
898 mouseOverSequence(sequenceI, position, -1, source);
900 handlingVamsasMo = false;
903 public Annotation[] colourSequenceFromStructure(SequenceI seq,
907 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
908 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
910 * Annotation [] annotations = new Annotation[seq.getLength()];
912 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
913 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
914 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
916 * for (int j = 0; j < mappings.length; j++) {
918 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
919 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
920 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
921 * "+mappings[j].pdbfile);
923 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
924 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
926 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
927 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
928 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
929 * mappings[j].pdbfile); }
931 * annotations[index] = new Annotation("X",null,' ',0,col); } return
932 * annotations; } } } }
934 * return annotations;
938 public void structureSelectionChanged()
942 public void sequenceSelectionChanged()
946 public void sequenceColoursChanged(Object source)
948 StructureListener sl;
949 for (int i = 0; i < listeners.size(); i++)
951 if (listeners.elementAt(i) instanceof StructureListener)
953 sl = (StructureListener) listeners.elementAt(i);
954 sl.updateColours(source);
959 public StructureMapping[] getMapping(String pdbfile)
961 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
962 for (StructureMapping sm : mappings)
964 if (sm.pdbfile.equals(pdbfile))
969 return tmp.toArray(new StructureMapping[tmp.size()]);
973 * Returns a readable description of all mappings for the given pdbfile to any
974 * of the given sequences
980 public String printMappings(String pdbfile, List<SequenceI> seqs)
982 if (pdbfile == null || seqs == null || seqs.isEmpty())
987 StringBuilder sb = new StringBuilder(64);
988 for (StructureMapping sm : mappings)
990 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
992 sb.append(sm.mappingDetails);
994 // separator makes it easier to read multiple mappings
995 sb.append("=====================");
1001 return sb.toString();
1005 * Remove the given mapping
1009 public void deregisterMapping(AlignedCodonFrame acf)
1013 boolean removed = seqmappings.remove(acf);
1014 if (removed && seqmappings.isEmpty())
1016 System.out.println("All mappings removed");
1022 * Add each of the given codonFrames to the stored set, if not aready present.
1026 public void registerMappings(List<AlignedCodonFrame> mappings)
1028 if (mappings != null)
1030 for (AlignedCodonFrame acf : mappings)
1032 registerMapping(acf);
1038 * Add the given mapping to the stored set, unless already stored.
1040 public void registerMapping(AlignedCodonFrame acf)
1044 if (!seqmappings.contains(acf))
1046 seqmappings.add(acf);
1052 * Resets this object to its initial state by removing all registered
1053 * listeners, codon mappings, PDB file mappings
1055 public void resetAll()
1057 if (mappings != null)
1061 if (seqmappings != null)
1063 seqmappings.clear();
1065 if (sel_listeners != null)
1067 sel_listeners.clear();
1069 if (listeners != null)
1073 if (commandListeners != null)
1075 commandListeners.clear();
1077 if (view_listeners != null)
1079 view_listeners.clear();
1081 if (pdbFileNameId != null)
1083 pdbFileNameId.clear();
1085 if (pdbIdFileName != null)
1087 pdbIdFileName.clear();
1091 public void addSelectionListener(SelectionListener selecter)
1093 if (!sel_listeners.contains(selecter))
1095 sel_listeners.add(selecter);
1099 public void removeSelectionListener(SelectionListener toremove)
1101 if (sel_listeners.contains(toremove))
1103 sel_listeners.remove(toremove);
1107 public synchronized void sendSelection(
1108 jalview.datamodel.SequenceGroup selection,
1109 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1111 for (SelectionListener slis : sel_listeners)
1115 slis.selection(selection, colsel, source);
1120 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1122 public synchronized void sendViewPosition(
1123 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1124 int startSeq, int endSeq)
1127 if (view_listeners != null && view_listeners.size() > 0)
1129 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1131 while (listeners.hasMoreElements())
1133 AlignmentViewPanelListener slis = listeners.nextElement();
1136 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1144 * release all references associated with this manager provider
1146 * @param jalviewLite
1148 public static void release(StructureSelectionManagerProvider jalviewLite)
1150 // synchronized (instances)
1152 if (instances == null)
1156 StructureSelectionManager mnger = (instances.get(jalviewLite));
1159 instances.remove(jalviewLite);
1163 } catch (Throwable x)
1170 public void registerPDBEntry(PDBEntry pdbentry)
1172 if (pdbentry.getFile() != null
1173 && pdbentry.getFile().trim().length() > 0)
1175 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1179 public void addCommandListener(CommandListener cl)
1181 if (!commandListeners.contains(cl))
1183 commandListeners.add(cl);
1187 public boolean hasCommandListener(CommandListener cl)
1189 return this.commandListeners.contains(cl);
1192 public boolean removeCommandListener(CommandListener l)
1194 return commandListeners.remove(l);
1198 * Forward a command to any command listeners (except for the command's
1202 * the command to be broadcast (in its form after being performed)
1204 * if true, the command was being 'undone'
1207 public void commandPerformed(CommandI command, boolean undo,
1208 VamsasSource source)
1210 for (CommandListener listener : commandListeners)
1212 listener.mirrorCommand(command, undo, this, source);
1217 * Returns a new CommandI representing the given command as mapped to the
1218 * given sequences. If no mapping could be made, or the command is not of a
1219 * mappable kind, returns null.
1227 public CommandI mapCommand(CommandI command, boolean undo,
1228 final AlignmentI mapTo, char gapChar)
1230 if (command instanceof EditCommand)
1232 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1233 mapTo, gapChar, seqmappings);
1235 else if (command instanceof OrderCommand)
1237 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1238 mapTo, seqmappings);
1243 public IProgressIndicator getProgressIndicator()
1245 return progressIndicator;
1248 public void setProgressIndicator(IProgressIndicator progressIndicator)
1250 this.progressIndicator = progressIndicator;
1253 public long getProgressSessionId()
1255 return progressSessionId;
1258 public void setProgressSessionId(long progressSessionId)
1260 this.progressSessionId = progressSessionId;
1263 public void setProgressBar(String message)
1265 progressIndicator.setProgressBar(message, progressSessionId);
1268 public List<AlignedCodonFrame> getSequenceMappings()