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[]>();
612 Atom tmp = maxChain.atoms.elementAt(index);
613 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
614 && tmp.alignmentMapping != -1)
616 resNum = tmp.resNumber;
617 insCode = tmp.insCode;
618 if (tmp.alignmentMapping >= -1)
620 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
626 } while (index < maxChain.atoms.size());
628 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
629 pdb.id, maxChainId, mapping, mappingDetails.toString());
630 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
634 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
636 listeners.removeElement(svl);
637 if (svl instanceof SequenceListener)
639 for (int i = 0; i < listeners.size(); i++)
641 if (listeners.elementAt(i) instanceof StructureListener)
643 ((StructureListener) listeners.elementAt(i))
644 .releaseReferences(svl);
649 if (pdbfiles == null)
655 * Remove mappings to the closed listener's PDB files, but first check if
656 * another listener is still interested
658 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
660 StructureListener sl;
661 for (int i = 0; i < listeners.size(); i++)
663 if (listeners.elementAt(i) instanceof StructureListener)
665 sl = (StructureListener) listeners.elementAt(i);
666 for (String pdbfile : sl.getPdbFile())
668 pdbs.remove(pdbfile);
674 * Rebuild the mappings set, retaining only those which are for 'other' PDB
679 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
680 for (StructureMapping sm : mappings)
682 if (!pdbs.contains(sm.pdbfile))
693 * Propagate mouseover of a single position in a structure
699 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
701 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
702 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
703 mouseOverStructure(atoms);
707 * Propagate mouseover or selection of multiple positions in a structure
711 public void mouseOverStructure(List<AtomSpec> atoms)
713 if (listeners == null)
715 // old or prematurely sent event
718 boolean hasSequenceListener = false;
719 for (int i = 0; i < listeners.size(); i++)
721 if (listeners.elementAt(i) instanceof SequenceListener)
723 hasSequenceListener = true;
726 if (!hasSequenceListener)
731 SearchResults results = new SearchResults();
732 for (AtomSpec atom : atoms)
734 SequenceI lastseq = null;
736 for (StructureMapping sm : mappings)
738 if (sm.pdbfile.equals(atom.getPdbFile())
739 && sm.pdbchain.equals(atom.getChain()))
741 int indexpos = sm.getSeqPos(atom.getPdbResNum());
742 if (lastipos != indexpos && lastseq != sm.sequence)
744 results.addResult(sm.sequence, indexpos, indexpos);
746 lastseq = sm.sequence;
747 // construct highlighted sequence list
748 for (AlignedCodonFrame acf : seqmappings)
750 acf.markMappedRegion(sm.sequence, indexpos, results);
756 for (Object li : listeners)
758 if (li instanceof SequenceListener)
760 ((SequenceListener) li).highlightSequence(results);
766 * highlight regions associated with a position (indexpos) in seq
769 * the sequence that the mouse over occurred on
771 * the absolute position being mouseovered in seq (0 to seq.length())
773 * the sequence position (if -1, seq.findPosition is called to
774 * resolve the residue number)
776 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
779 boolean hasSequenceListeners = handlingVamsasMo
780 || !seqmappings.isEmpty();
781 SearchResults results = null;
784 seqPos = seq.findPosition(indexpos);
786 for (int i = 0; i < listeners.size(); i++)
788 Object listener = listeners.elementAt(i);
789 if (listener == source)
791 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
792 // Temporary fudge with SequenceListener.getVamsasSource()
795 if (listener instanceof StructureListener)
797 highlightStructure((StructureListener) listener, seq, seqPos);
801 if (listener instanceof SequenceListener)
803 final SequenceListener seqListener = (SequenceListener) listener;
804 if (hasSequenceListeners
805 && seqListener.getVamsasSource() != source)
807 if (relaySeqMappings)
811 results = MappingUtils.buildSearchResults(seq, seqPos,
814 if (handlingVamsasMo)
816 results.addResult(seq, seqPos, seqPos);
819 if (!results.isEmpty())
821 seqListener.highlightSequence(results);
826 else if (listener instanceof VamsasListener && !handlingVamsasMo)
828 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
831 else if (listener instanceof SecondaryStructureListener)
833 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
841 * Send suitable messages to a StructureListener to highlight atoms
842 * corresponding to the given sequence position(s)
848 public void highlightStructure(StructureListener sl, SequenceI seq,
851 if (!sl.isListeningFor(seq))
856 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
857 for (StructureMapping sm : mappings)
859 if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
861 for (int index : positions)
863 atomNo = sm.getAtomNum(index);
867 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
868 .getPDBResNum(index), atomNo));
873 sl.highlightAtoms(atoms);
877 * true if a mouse over event from an external (ie Vamsas) source is being
880 boolean handlingVamsasMo = false;
885 * as mouseOverSequence but only route event to SequenceListeners
889 * in an alignment sequence
891 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
894 handlingVamsasMo = true;
895 long msg = sequenceI.hashCode() * (1 + position);
899 mouseOverSequence(sequenceI, position, -1, source);
901 handlingVamsasMo = false;
904 public Annotation[] colourSequenceFromStructure(SequenceI seq,
908 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
909 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
911 * Annotation [] annotations = new Annotation[seq.getLength()];
913 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
914 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
915 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
917 * for (int j = 0; j < mappings.length; j++) {
919 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
920 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
921 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
922 * "+mappings[j].pdbfile);
924 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
925 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
927 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
928 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
929 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
930 * mappings[j].pdbfile); }
932 * annotations[index] = new Annotation("X",null,' ',0,col); } return
933 * annotations; } } } }
935 * return annotations;
939 public void structureSelectionChanged()
943 public void sequenceSelectionChanged()
947 public void sequenceColoursChanged(Object source)
949 StructureListener sl;
950 for (int i = 0; i < listeners.size(); i++)
952 if (listeners.elementAt(i) instanceof StructureListener)
954 sl = (StructureListener) listeners.elementAt(i);
955 sl.updateColours(source);
960 public StructureMapping[] getMapping(String pdbfile)
962 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
963 for (StructureMapping sm : mappings)
965 if (sm.pdbfile.equals(pdbfile))
970 return tmp.toArray(new StructureMapping[tmp.size()]);
974 * Returns a readable description of all mappings for the given pdbfile to any
975 * of the given sequences
981 public String printMappings(String pdbfile, List<SequenceI> seqs)
983 if (pdbfile == null || seqs == null || seqs.isEmpty())
988 StringBuilder sb = new StringBuilder(64);
989 for (StructureMapping sm : mappings)
991 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
993 sb.append(sm.mappingDetails);
995 // separator makes it easier to read multiple mappings
996 sb.append("=====================");
1002 return sb.toString();
1006 * Remove the given mapping
1010 public void deregisterMapping(AlignedCodonFrame acf)
1014 boolean removed = seqmappings.remove(acf);
1015 if (removed && seqmappings.isEmpty())
1017 System.out.println("All mappings removed");
1023 * Add each of the given codonFrames to the stored set, if not aready present.
1027 public void registerMappings(List<AlignedCodonFrame> mappings)
1029 if (mappings != null)
1031 for (AlignedCodonFrame acf : mappings)
1033 registerMapping(acf);
1039 * Add the given mapping to the stored set, unless already stored.
1041 public void registerMapping(AlignedCodonFrame acf)
1045 if (!seqmappings.contains(acf))
1047 seqmappings.add(acf);
1053 * Resets this object to its initial state by removing all registered
1054 * listeners, codon mappings, PDB file mappings
1056 public void resetAll()
1058 if (mappings != null)
1062 if (seqmappings != null)
1064 seqmappings.clear();
1066 if (sel_listeners != null)
1068 sel_listeners.clear();
1070 if (listeners != null)
1074 if (commandListeners != null)
1076 commandListeners.clear();
1078 if (view_listeners != null)
1080 view_listeners.clear();
1082 if (pdbFileNameId != null)
1084 pdbFileNameId.clear();
1086 if (pdbIdFileName != null)
1088 pdbIdFileName.clear();
1092 public void addSelectionListener(SelectionListener selecter)
1094 if (!sel_listeners.contains(selecter))
1096 sel_listeners.add(selecter);
1100 public void removeSelectionListener(SelectionListener toremove)
1102 if (sel_listeners.contains(toremove))
1104 sel_listeners.remove(toremove);
1108 public synchronized void sendSelection(
1109 jalview.datamodel.SequenceGroup selection,
1110 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1112 for (SelectionListener slis : sel_listeners)
1116 slis.selection(selection, colsel, source);
1121 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1123 public synchronized void sendViewPosition(
1124 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1125 int startSeq, int endSeq)
1128 if (view_listeners != null && view_listeners.size() > 0)
1130 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1132 while (listeners.hasMoreElements())
1134 AlignmentViewPanelListener slis = listeners.nextElement();
1137 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1145 * release all references associated with this manager provider
1147 * @param jalviewLite
1149 public static void release(StructureSelectionManagerProvider jalviewLite)
1151 // synchronized (instances)
1153 if (instances == null)
1157 StructureSelectionManager mnger = (instances.get(jalviewLite));
1160 instances.remove(jalviewLite);
1164 } catch (Throwable x)
1171 public void registerPDBEntry(PDBEntry pdbentry)
1173 if (pdbentry.getFile() != null
1174 && pdbentry.getFile().trim().length() > 0)
1176 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1180 public void addCommandListener(CommandListener cl)
1182 if (!commandListeners.contains(cl))
1184 commandListeners.add(cl);
1188 public boolean hasCommandListener(CommandListener cl)
1190 return this.commandListeners.contains(cl);
1193 public boolean removeCommandListener(CommandListener l)
1195 return commandListeners.remove(l);
1199 * Forward a command to any command listeners (except for the command's
1203 * the command to be broadcast (in its form after being performed)
1205 * if true, the command was being 'undone'
1208 public void commandPerformed(CommandI command, boolean undo,
1209 VamsasSource source)
1211 for (CommandListener listener : commandListeners)
1213 listener.mirrorCommand(command, undo, this, source);
1218 * Returns a new CommandI representing the given command as mapped to the
1219 * given sequences. If no mapping could be made, or the command is not of a
1220 * mappable kind, returns null.
1228 public CommandI mapCommand(CommandI command, boolean undo,
1229 final AlignmentI mapTo, char gapChar)
1231 if (command instanceof EditCommand)
1233 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1234 mapTo, gapChar, seqmappings);
1236 else if (command instanceof OrderCommand)
1238 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1239 mapTo, seqmappings);
1244 public IProgressIndicator getProgressIndicator()
1246 return progressIndicator;
1249 public void setProgressIndicator(IProgressIndicator progressIndicator)
1251 this.progressIndicator = progressIndicator;
1254 public long getProgressSessionId()
1256 return progressSessionId;
1259 public void setProgressSessionId(long progressSessionId)
1261 this.progressSessionId = progressSessionId;
1264 public void setProgressBar(String message)
1266 progressIndicator.setProgressBar(message, progressSessionId);
1269 public List<AlignedCodonFrame> getSequenceMappings()