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[]>();
613 Atom tmp = maxChain.atoms.elementAt(index);
614 if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
616 resNum = tmp.resNumber;
617 if (tmp.alignmentMapping >= -1)
619 // TODO (JAL-1836) address root cause: negative residue no in PDB
621 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
627 } while (index < maxChain.atoms.size());
629 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
630 pdb.id, maxChainId, mapping, mappingDetails.toString());
631 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
635 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
637 listeners.removeElement(svl);
638 if (svl instanceof SequenceListener)
640 for (int i = 0; i < listeners.size(); i++)
642 if (listeners.elementAt(i) instanceof StructureListener)
644 ((StructureListener) listeners.elementAt(i))
645 .releaseReferences(svl);
650 if (pdbfiles == null)
656 * Remove mappings to the closed listener's PDB files, but first check if
657 * another listener is still interested
659 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
661 StructureListener sl;
662 for (int i = 0; i < listeners.size(); i++)
664 if (listeners.elementAt(i) instanceof StructureListener)
666 sl = (StructureListener) listeners.elementAt(i);
667 for (String pdbfile : sl.getPdbFile())
669 pdbs.remove(pdbfile);
675 * Rebuild the mappings set, retaining only those which are for 'other' PDB
680 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
681 for (StructureMapping sm : mappings)
683 if (!pdbs.contains(sm.pdbfile))
694 * Propagate mouseover of a single position in a structure
700 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
702 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
703 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
704 mouseOverStructure(atoms);
708 * Propagate mouseover or selection of multiple positions in a structure
712 public void mouseOverStructure(List<AtomSpec> atoms)
714 if (listeners == null)
716 // old or prematurely sent event
719 boolean hasSequenceListener = false;
720 for (int i = 0; i < listeners.size(); i++)
722 if (listeners.elementAt(i) instanceof SequenceListener)
724 hasSequenceListener = true;
727 if (!hasSequenceListener)
732 SearchResults results = new SearchResults();
733 for (AtomSpec atom : atoms)
735 SequenceI lastseq = null;
737 for (StructureMapping sm : mappings)
739 if (sm.pdbfile.equals(atom.getPdbFile())
740 && sm.pdbchain.equals(atom.getChain()))
742 int indexpos = sm.getSeqPos(atom.getPdbResNum());
743 if (lastipos != indexpos && lastseq != sm.sequence)
745 results.addResult(sm.sequence, indexpos, indexpos);
747 lastseq = sm.sequence;
748 // construct highlighted sequence list
749 for (AlignedCodonFrame acf : seqmappings)
751 acf.markMappedRegion(sm.sequence, indexpos, results);
757 for (Object li : listeners)
759 if (li instanceof SequenceListener)
761 ((SequenceListener) li).highlightSequence(results);
767 * highlight regions associated with a position (indexpos) in seq
770 * the sequence that the mouse over occurred on
772 * the absolute position being mouseovered in seq (0 to seq.length())
774 * the sequence position (if -1, seq.findPosition is called to
775 * resolve the residue number)
777 public void mouseOverSequence(SequenceI seq, int indexpos, int index,
780 boolean hasSequenceListeners = handlingVamsasMo
781 || !seqmappings.isEmpty();
782 SearchResults results = null;
785 index = seq.findPosition(indexpos);
787 for (int i = 0; i < listeners.size(); i++)
789 Object listener = listeners.elementAt(i);
790 if (listener == source)
792 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
793 // Temporary fudge with SequenceListener.getVamsasSource()
796 if (listener instanceof StructureListener)
798 highlightStructure((StructureListener) listener, seq, index);
802 if (listener instanceof SequenceListener)
804 final SequenceListener seqListener = (SequenceListener) listener;
805 if (hasSequenceListeners
806 && seqListener.getVamsasSource() != source)
808 if (relaySeqMappings)
812 results = MappingUtils.buildSearchResults(seq, index,
815 if (handlingVamsasMo)
817 results.addResult(seq, index, index);
820 if (!results.isEmpty())
822 seqListener.highlightSequence(results);
827 else if (listener instanceof VamsasListener && !handlingVamsasMo)
829 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
832 else if (listener instanceof SecondaryStructureListener)
834 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
842 * Send suitable messages to a StructureListener to highlight atoms
843 * corresponding to the given sequence position.
849 protected void highlightStructure(StructureListener sl, SequenceI seq,
852 if (!sl.isListeningFor(seq))
857 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
858 for (StructureMapping sm : mappings)
860 if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
862 atomNo = sm.getAtomNum(index);
866 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
867 .getPDBResNum(index), atomNo));
871 sl.highlightAtoms(atoms);
875 * true if a mouse over event from an external (ie Vamsas) source is being
878 boolean handlingVamsasMo = false;
883 * as mouseOverSequence but only route event to SequenceListeners
887 * in an alignment sequence
889 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
892 handlingVamsasMo = true;
893 long msg = sequenceI.hashCode() * (1 + position);
897 mouseOverSequence(sequenceI, position, -1, source);
899 handlingVamsasMo = false;
902 public Annotation[] colourSequenceFromStructure(SequenceI seq,
906 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
907 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
909 * Annotation [] annotations = new Annotation[seq.getLength()];
911 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
912 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
913 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
915 * for (int j = 0; j < mappings.length; j++) {
917 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
918 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
919 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
920 * "+mappings[j].pdbfile);
922 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
923 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
925 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
926 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
927 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
928 * mappings[j].pdbfile); }
930 * annotations[index] = new Annotation("X",null,' ',0,col); } return
931 * annotations; } } } }
933 * return annotations;
937 public void structureSelectionChanged()
941 public void sequenceSelectionChanged()
945 public void sequenceColoursChanged(Object source)
947 StructureListener sl;
948 for (int i = 0; i < listeners.size(); i++)
950 if (listeners.elementAt(i) instanceof StructureListener)
952 sl = (StructureListener) listeners.elementAt(i);
953 sl.updateColours(source);
958 public StructureMapping[] getMapping(String pdbfile)
960 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
961 for (StructureMapping sm : mappings)
963 if (sm.pdbfile.equals(pdbfile))
968 return tmp.toArray(new StructureMapping[tmp.size()]);
972 * Returns a readable description of all mappings for the given pdbfile to any
973 * of the given sequences
979 public String printMappings(String pdbfile, List<SequenceI> seqs)
981 if (pdbfile == null || seqs == null || seqs.isEmpty())
986 StringBuilder sb = new StringBuilder(64);
987 for (StructureMapping sm : mappings)
989 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
991 sb.append(sm.mappingDetails);
993 // separator makes it easier to read multiple mappings
994 sb.append("=====================");
1000 return sb.toString();
1004 * Remove the given mapping
1008 public void deregisterMapping(AlignedCodonFrame acf)
1012 boolean removed = seqmappings.remove(acf);
1013 if (removed && seqmappings.isEmpty())
1015 System.out.println("All mappings removed");
1021 * Add each of the given codonFrames to the stored set, if not aready present.
1025 public void registerMappings(Set<AlignedCodonFrame> set)
1029 for (AlignedCodonFrame acf : set)
1031 registerMapping(acf);
1037 * Add the given mapping to the stored set, unless already stored.
1039 public void registerMapping(AlignedCodonFrame acf)
1043 if (!seqmappings.contains(acf))
1045 seqmappings.add(acf);
1051 * Resets this object to its initial state by removing all registered
1052 * listeners, codon mappings, PDB file mappings
1054 public void resetAll()
1056 if (mappings != null)
1060 if (seqmappings != null)
1062 seqmappings.clear();
1064 if (sel_listeners != null)
1066 sel_listeners.clear();
1068 if (listeners != null)
1072 if (commandListeners != null)
1074 commandListeners.clear();
1076 if (view_listeners != null)
1078 view_listeners.clear();
1080 if (pdbFileNameId != null)
1082 pdbFileNameId.clear();
1084 if (pdbIdFileName != null)
1086 pdbIdFileName.clear();
1090 public void addSelectionListener(SelectionListener selecter)
1092 if (!sel_listeners.contains(selecter))
1094 sel_listeners.add(selecter);
1098 public void removeSelectionListener(SelectionListener toremove)
1100 if (sel_listeners.contains(toremove))
1102 sel_listeners.remove(toremove);
1106 public synchronized void sendSelection(
1107 jalview.datamodel.SequenceGroup selection,
1108 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1110 for (SelectionListener slis : sel_listeners)
1114 slis.selection(selection, colsel, source);
1119 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1121 public synchronized void sendViewPosition(
1122 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1123 int startSeq, int endSeq)
1126 if (view_listeners != null && view_listeners.size() > 0)
1128 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1130 while (listeners.hasMoreElements())
1132 AlignmentViewPanelListener slis = listeners.nextElement();
1135 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1143 * release all references associated with this manager provider
1145 * @param jalviewLite
1147 public static void release(StructureSelectionManagerProvider jalviewLite)
1149 // synchronized (instances)
1151 if (instances == null)
1155 StructureSelectionManager mnger = (instances.get(jalviewLite));
1158 instances.remove(jalviewLite);
1162 } catch (Throwable x)
1169 public void registerPDBEntry(PDBEntry pdbentry)
1171 if (pdbentry.getFile() != null
1172 && pdbentry.getFile().trim().length() > 0)
1174 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1178 public void addCommandListener(CommandListener cl)
1180 if (!commandListeners.contains(cl))
1182 commandListeners.add(cl);
1186 public boolean hasCommandListener(CommandListener cl)
1188 return this.commandListeners.contains(cl);
1191 public boolean removeCommandListener(CommandListener l)
1193 return commandListeners.remove(l);
1197 * Forward a command to any command listeners (except for the command's
1201 * the command to be broadcast (in its form after being performed)
1203 * if true, the command was being 'undone'
1206 public void commandPerformed(CommandI command, boolean undo,
1207 VamsasSource source)
1209 for (CommandListener listener : commandListeners)
1211 listener.mirrorCommand(command, undo, this, source);
1216 * Returns a new CommandI representing the given command as mapped to the
1217 * given sequences. If no mapping could be made, or the command is not of a
1218 * mappable kind, returns null.
1226 public CommandI mapCommand(CommandI command, boolean undo,
1227 final AlignmentI mapTo, char gapChar)
1229 if (command instanceof EditCommand)
1231 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1232 mapTo, gapChar, seqmappings);
1234 else if (command instanceof OrderCommand)
1236 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1237 mapTo, seqmappings);
1242 public IProgressIndicator getProgressIndicator()
1244 return progressIndicator;
1247 public void setProgressIndicator(IProgressIndicator progressIndicator)
1249 this.progressIndicator = progressIndicator;
1252 public long getProgressSessionId()
1254 return progressSessionId;
1257 public void setProgressSessionId(long progressSessionId)
1259 this.progressSessionId = progressSessionId;
1262 public void setProgressBar(String message)
1264 progressIndicator.setProgressBar(message, progressSessionId);