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.id != null && pdb.id.trim().length() > 0
391 && AppletFormatAdapter.FILE.equals(protocol))
393 registerPDBFile(pdb.id.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.chains)
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.id;
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.chains)
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);
540 PDBChain chain = pdb.findChain(targetChainId);
543 chain.transferResidueAnnotation(curChainMapping, sqmpping);
545 return curChainMapping;
546 } catch (SiftsException e)
548 System.err.println(e.getMessage());
549 System.err.println(">>> Now switching mapping with NW alignment...");
550 setProgressBar(null);
551 setProgressBar(">>> Now switching mapping with NW alignment...");
552 return getNWMappings(seq, pdbFile, maxChainId, maxChain, pdb,
557 private StructureMapping getNWMappings(SequenceI seq,
559 String maxChainId, PDBChain maxChain, PDBfile pdb,
560 AlignSeq maxAlignseq)
562 final StringBuilder mappingDetails = new StringBuilder(128);
563 mappingDetails.append(NEWLINE).append(
564 "Sequence \u27f7 Structure mapping details");
565 mappingDetails.append(NEWLINE);
567 .append("Method: inferred with Needleman & Wunsch alignment");
568 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
569 .append(NEWLINE).append("Sequence = ")
570 .append(maxChain.sequence.getSequenceAsString());
571 mappingDetails.append(NEWLINE).append("No of residues = ")
572 .append(maxChain.residues.size()).append(NEWLINE)
574 PrintStream ps = new PrintStream(System.out)
577 public void print(String x)
579 mappingDetails.append(x);
583 public void println()
585 mappingDetails.append(NEWLINE);
589 maxAlignseq.printAlignment(ps);
591 mappingDetails.append(NEWLINE).append("PDB start/end ");
592 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
594 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
595 mappingDetails.append(NEWLINE).append("SEQ start/end ");
596 mappingDetails.append(
597 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
599 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
600 + (seq.getStart() - 1)));
601 mappingDetails.append(NEWLINE);
602 maxChain.makeExactMapping(maxAlignseq, seq);
603 jalview.datamodel.Mapping sqmpping = maxAlignseq
604 .getMappingFromS1(false);
605 maxChain.transferRESNUMFeatures(seq, null);
607 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
614 Atom tmp = maxChain.atoms.elementAt(index);
615 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
616 && tmp.alignmentMapping != -1)
618 resNum = tmp.resNumber;
619 insCode = tmp.insCode;
620 if (tmp.alignmentMapping >= -1)
622 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
628 } while (index < maxChain.atoms.size());
630 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
631 pdb.id, maxChainId, mapping, mappingDetails.toString());
632 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
636 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
638 listeners.removeElement(svl);
639 if (svl instanceof SequenceListener)
641 for (int i = 0; i < listeners.size(); i++)
643 if (listeners.elementAt(i) instanceof StructureListener)
645 ((StructureListener) listeners.elementAt(i))
646 .releaseReferences(svl);
651 if (pdbfiles == null)
657 * Remove mappings to the closed listener's PDB files, but first check if
658 * another listener is still interested
660 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
662 StructureListener sl;
663 for (int i = 0; i < listeners.size(); i++)
665 if (listeners.elementAt(i) instanceof StructureListener)
667 sl = (StructureListener) listeners.elementAt(i);
668 for (String pdbfile : sl.getPdbFile())
670 pdbs.remove(pdbfile);
676 * Rebuild the mappings set, retaining only those which are for 'other' PDB
681 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
682 for (StructureMapping sm : mappings)
684 if (!pdbs.contains(sm.pdbfile))
695 * Propagate mouseover of a single position in a structure
701 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
703 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
704 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
705 mouseOverStructure(atoms);
709 * Propagate mouseover or selection of multiple positions in a structure
713 public void mouseOverStructure(List<AtomSpec> atoms)
715 if (listeners == null)
717 // old or prematurely sent event
720 boolean hasSequenceListener = false;
721 for (int i = 0; i < listeners.size(); i++)
723 if (listeners.elementAt(i) instanceof SequenceListener)
725 hasSequenceListener = true;
728 if (!hasSequenceListener)
733 SearchResults results = new SearchResults();
734 for (AtomSpec atom : atoms)
736 SequenceI lastseq = null;
738 for (StructureMapping sm : mappings)
740 if (sm.pdbfile.equals(atom.getPdbFile())
741 && sm.pdbchain.equals(atom.getChain()))
743 int indexpos = sm.getSeqPos(atom.getPdbResNum());
744 if (lastipos != indexpos && lastseq != sm.sequence)
746 results.addResult(sm.sequence, indexpos, indexpos);
748 lastseq = sm.sequence;
749 // construct highlighted sequence list
750 for (AlignedCodonFrame acf : seqmappings)
752 acf.markMappedRegion(sm.sequence, indexpos, results);
758 for (Object li : listeners)
760 if (li instanceof SequenceListener)
762 ((SequenceListener) li).highlightSequence(results);
768 * highlight regions associated with a position (indexpos) in seq
771 * the sequence that the mouse over occurred on
773 * the absolute position being mouseovered in seq (0 to seq.length())
775 * the sequence position (if -1, seq.findPosition is called to
776 * resolve the residue number)
778 public void mouseOverSequence(SequenceI seq, int indexpos, int index,
781 boolean hasSequenceListeners = handlingVamsasMo
782 || !seqmappings.isEmpty();
783 SearchResults results = null;
786 index = seq.findPosition(indexpos);
788 for (int i = 0; i < listeners.size(); i++)
790 Object listener = listeners.elementAt(i);
791 if (listener == source)
793 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
794 // Temporary fudge with SequenceListener.getVamsasSource()
797 if (listener instanceof StructureListener)
799 highlightStructure((StructureListener) listener, seq, index);
803 if (listener instanceof SequenceListener)
805 final SequenceListener seqListener = (SequenceListener) listener;
806 if (hasSequenceListeners
807 && seqListener.getVamsasSource() != source)
809 if (relaySeqMappings)
813 results = MappingUtils.buildSearchResults(seq, index,
816 if (handlingVamsasMo)
818 results.addResult(seq, index, index);
821 if (!results.isEmpty())
823 seqListener.highlightSequence(results);
828 else if (listener instanceof VamsasListener && !handlingVamsasMo)
830 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
833 else if (listener instanceof SecondaryStructureListener)
835 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
843 * Send suitable messages to a StructureListener to highlight atoms
844 * corresponding to the given sequence position.
850 protected void highlightStructure(StructureListener sl, SequenceI seq,
853 if (!sl.isListeningFor(seq))
858 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
859 for (StructureMapping sm : mappings)
861 if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
863 atomNo = sm.getAtomNum(index);
867 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
868 .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(Set<AlignedCodonFrame> set)
1030 for (AlignedCodonFrame acf : set)
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);