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 long progressSessionId;
79 * Set of any registered mappings between (dataset) sequences.
81 public Set<AlignedCodonFrame> seqmappings = new LinkedHashSet<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();
383 SiftsClient siftsClient = null;
386 pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
389 if (pdb.id != null && pdb.id.trim().length() > 0
390 && AppletFormatAdapter.FILE.equals(protocol))
392 registerPDBFile(pdb.id.trim(), pdbFile);
394 } catch (Exception ex)
396 ex.printStackTrace();
404 siftsClient = new SiftsClient(pdb);
406 } catch (SiftsException e)
408 isMapUsingSIFTs = false;
412 String targetChainId;
413 for (int s = 0; s < sequenceArray.length; s++)
415 boolean infChain = true;
416 final SequenceI seq = sequenceArray[s];
417 if (targetChainIds != null && targetChainIds[s] != null)
420 targetChainId = targetChainIds[s];
422 else if (seq.getName().indexOf("|") > -1)
424 targetChainId = seq.getName().substring(
425 seq.getName().lastIndexOf("|") + 1);
426 if (targetChainId.length() > 1)
428 if (targetChainId.trim().length() == 0)
434 // not a valid chain identifier
445 * Attempt pairwise alignment of the sequence with each chain in the PDB,
446 * and remember the highest scoring chain
449 AlignSeq maxAlignseq = null;
450 String maxChainId = " ";
451 PDBChain maxChain = null;
452 boolean first = true;
453 for (PDBChain chain : pdb.chains)
455 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
458 continue; // don't try to map chains don't match.
460 // TODO: correctly determine sequence type for mixed na/peptide
462 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
463 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
466 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
467 // as.calcScoreMatrix();
468 // as.traceAlignment();
470 if (first || as.maxscore > max
471 || (as.maxscore == max && chain.id.equals(targetChainId)))
477 maxChainId = chain.id;
480 if (maxChain == null)
485 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
487 pdbFile = "INLINE" + pdb.id;
490 ArrayList<StructureMapping> seqToStrucMapping = null;
493 setProgressBar(null);
494 setProgressBar("Obtaining mapping with SIFTS");
497 jalview.datamodel.Mapping sqmpping = maxAlignseq
498 .getMappingFromS1(false);
499 seqToStrucMapping = new ArrayList<StructureMapping>();
500 if (targetChainId != null && !targetChainId.trim().isEmpty())
502 StructureMapping curChainMapping = siftsClient
503 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
504 seqToStrucMapping.add(curChainMapping);
505 maxChainId = targetChainId;
506 PDBChain chain = pdb.findChain(targetChainId);
509 chain.transferResidueAnnotation(curChainMapping, sqmpping);
514 for (PDBChain chain : pdb.chains)
516 StructureMapping curChainMapping = siftsClient
517 .getSiftsStructureMapping(seq, pdbFile, chain.id);
518 seqToStrucMapping.add(curChainMapping);
519 maxChainId = chain.id;
520 chain.transferResidueAnnotation(curChainMapping, sqmpping);
523 } catch (SiftsException e)
525 System.err.println(e.getMessage());
527 .println(">>> Now switching mapping with NW alignment...");
528 setProgressBar(null);
529 setProgressBar(">>> Now switching mapping with NW alignment...");
530 seqToStrucMapping = getNWMappings(seq, pdbFile, maxChainId,
531 maxChain, pdb, maxAlignseq);
536 setProgressBar(null);
537 setProgressBar("Obtaining mapping with NW alignment");
538 seqToStrucMapping = getNWMappings(seq, pdbFile,
539 maxChainId, maxChain, pdb,
543 if (forStructureView)
545 // mappings.add(seqToStrucMapping);
546 mappings.addAll(seqToStrucMapping);
552 private ArrayList<StructureMapping> getNWMappings(SequenceI seq,
554 String maxChainId, PDBChain maxChain, PDBfile pdb,
555 AlignSeq maxAlignseq)
557 final StringBuilder mappingDetails = new StringBuilder(128);
558 mappingDetails.append(NEWLINE).append(
559 "Sequence \u27f7 Structure mapping details");
560 mappingDetails.append(NEWLINE);
562 .append("Method: inferred with Needleman & Wunsch alignment");
563 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
564 .append(NEWLINE).append("Sequence = ")
565 .append(maxChain.sequence.getSequenceAsString());
566 mappingDetails.append(NEWLINE).append("No of residues = ")
567 .append(maxChain.residues.size()).append(NEWLINE)
569 PrintStream ps = new PrintStream(System.out)
572 public void print(String x)
574 mappingDetails.append(x);
578 public void println()
580 mappingDetails.append(NEWLINE);
584 maxAlignseq.printAlignment(ps);
586 mappingDetails.append(NEWLINE).append("PDB start/end ");
587 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
589 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
590 mappingDetails.append(NEWLINE).append("SEQ start/end ");
591 mappingDetails.append(
592 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
594 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
595 + (seq.getStart() - 1)));
596 mappingDetails.append(NEWLINE);
597 maxChain.makeExactMapping(maxAlignseq, seq);
598 jalview.datamodel.Mapping sqmpping = maxAlignseq
599 .getMappingFromS1(false);
600 maxChain.transferRESNUMFeatures(seq, null);
602 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
608 Atom tmp = maxChain.atoms.elementAt(index);
609 if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
611 resNum = tmp.resNumber;
612 if (tmp.alignmentMapping >= -1)
614 // TODO (JAL-1836) address root cause: negative residue no in PDB
616 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
622 } while (index < maxChain.atoms.size());
624 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
625 pdb.id, maxChainId, mapping, mappingDetails.toString());
626 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
627 ArrayList<StructureMapping> mappings = new ArrayList<StructureMapping>();
628 mappings.add(nwMapping);
632 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
634 listeners.removeElement(svl);
635 if (svl instanceof SequenceListener)
637 for (int i = 0; i < listeners.size(); i++)
639 if (listeners.elementAt(i) instanceof StructureListener)
641 ((StructureListener) listeners.elementAt(i))
642 .releaseReferences(svl);
647 if (pdbfiles == null)
653 * Remove mappings to the closed listener's PDB files, but first check if
654 * another listener is still interested
656 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
658 StructureListener sl;
659 for (int i = 0; i < listeners.size(); i++)
661 if (listeners.elementAt(i) instanceof StructureListener)
663 sl = (StructureListener) listeners.elementAt(i);
664 for (String pdbfile : sl.getPdbFile())
666 pdbs.remove(pdbfile);
672 * Rebuild the mappings set, retaining only those which are for 'other' PDB
677 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
678 for (StructureMapping sm : mappings)
680 if (!pdbs.contains(sm.pdbfile))
691 * Propagate mouseover of a single position in a structure
697 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
699 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
700 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
701 mouseOverStructure(atoms);
705 * Propagate mouseover or selection of multiple positions in a structure
709 public void mouseOverStructure(List<AtomSpec> atoms)
711 if (listeners == null)
713 // old or prematurely sent event
716 boolean hasSequenceListener = false;
717 for (int i = 0; i < listeners.size(); i++)
719 if (listeners.elementAt(i) instanceof SequenceListener)
721 hasSequenceListener = true;
724 if (!hasSequenceListener)
729 SearchResults results = new SearchResults();
730 for (AtomSpec atom : atoms)
732 SequenceI lastseq = null;
734 for (StructureMapping sm : mappings)
736 if (sm.pdbfile.equals(atom.getPdbFile())
737 && sm.pdbchain.equals(atom.getChain()))
739 int indexpos = sm.getSeqPos(atom.getPdbResNum());
740 if (lastipos != indexpos && lastseq != sm.sequence)
742 results.addResult(sm.sequence, indexpos, indexpos);
744 lastseq = sm.sequence;
745 // construct highlighted sequence list
746 for (AlignedCodonFrame acf : seqmappings)
748 acf.markMappedRegion(sm.sequence, indexpos, results);
754 for (Object li : listeners)
756 if (li instanceof SequenceListener)
758 ((SequenceListener) li).highlightSequence(results);
764 * highlight regions associated with a position (indexpos) in seq
767 * the sequence that the mouse over occurred on
769 * the absolute position being mouseovered in seq (0 to seq.length())
771 * the sequence position (if -1, seq.findPosition is called to
772 * resolve the residue number)
774 public void mouseOverSequence(SequenceI seq, int indexpos, int index,
777 boolean hasSequenceListeners = handlingVamsasMo
778 || !seqmappings.isEmpty();
779 SearchResults results = null;
782 index = seq.findPosition(indexpos);
784 for (int i = 0; i < listeners.size(); i++)
786 Object listener = listeners.elementAt(i);
787 if (listener == source)
789 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
790 // Temporary fudge with SequenceListener.getVamsasSource()
793 if (listener instanceof StructureListener)
795 highlightStructure((StructureListener) listener, seq, index);
799 if (listener instanceof SequenceListener)
801 final SequenceListener seqListener = (SequenceListener) listener;
802 if (hasSequenceListeners
803 && seqListener.getVamsasSource() != source)
805 if (relaySeqMappings)
809 results = MappingUtils.buildSearchResults(seq, index,
812 if (handlingVamsasMo)
814 results.addResult(seq, index, index);
817 if (!results.isEmpty())
819 seqListener.highlightSequence(results);
824 else if (listener instanceof VamsasListener && !handlingVamsasMo)
826 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
829 else if (listener instanceof SecondaryStructureListener)
831 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
839 * Send suitable messages to a StructureListener to highlight atoms
840 * corresponding to the given sequence position.
846 protected void highlightStructure(StructureListener sl, SequenceI seq,
849 if (!sl.isListeningFor(seq))
854 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
855 for (StructureMapping sm : mappings)
857 if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
859 atomNo = sm.getAtomNum(index);
863 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
864 .getPDBResNum(index), atomNo));
868 sl.highlightAtoms(atoms);
872 * true if a mouse over event from an external (ie Vamsas) source is being
875 boolean handlingVamsasMo = false;
880 * as mouseOverSequence but only route event to SequenceListeners
884 * in an alignment sequence
886 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
889 handlingVamsasMo = true;
890 long msg = sequenceI.hashCode() * (1 + position);
894 mouseOverSequence(sequenceI, position, -1, source);
896 handlingVamsasMo = false;
899 public Annotation[] colourSequenceFromStructure(SequenceI seq,
903 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
904 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
906 * Annotation [] annotations = new Annotation[seq.getLength()];
908 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
909 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
910 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
912 * for (int j = 0; j < mappings.length; j++) {
914 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
915 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
916 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
917 * "+mappings[j].pdbfile);
919 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
920 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
922 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
923 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
924 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
925 * mappings[j].pdbfile); }
927 * annotations[index] = new Annotation("X",null,' ',0,col); } return
928 * annotations; } } } }
930 * return annotations;
934 public void structureSelectionChanged()
938 public void sequenceSelectionChanged()
942 public void sequenceColoursChanged(Object source)
944 StructureListener sl;
945 for (int i = 0; i < listeners.size(); i++)
947 if (listeners.elementAt(i) instanceof StructureListener)
949 sl = (StructureListener) listeners.elementAt(i);
950 sl.updateColours(source);
955 public StructureMapping[] getMapping(String pdbfile)
957 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
958 for (StructureMapping sm : mappings)
960 if (sm.pdbfile.equals(pdbfile))
965 return tmp.toArray(new StructureMapping[tmp.size()]);
969 * Returns a readable description of all mappings for the given pdbfile to any
970 * of the given sequences
976 public String printMappings(String pdbfile, List<SequenceI> seqs)
978 if (pdbfile == null || seqs == null || seqs.isEmpty())
983 StringBuilder sb = new StringBuilder(64);
984 for (StructureMapping sm : mappings)
986 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
988 sb.append(sm.mappingDetails);
990 // separator makes it easier to read multiple mappings
991 sb.append("=====================");
997 return sb.toString();
1001 * Remove the given mapping
1005 public void deregisterMapping(AlignedCodonFrame acf)
1009 boolean removed = seqmappings.remove(acf);
1010 if (removed && seqmappings.isEmpty())
1012 System.out.println("All mappings removed");
1018 * Add each of the given codonFrames to the stored set, if not aready present.
1022 public void registerMappings(Set<AlignedCodonFrame> set)
1026 for (AlignedCodonFrame acf : set)
1028 registerMapping(acf);
1034 * Add the given mapping to the stored set, unless already stored.
1036 public void registerMapping(AlignedCodonFrame acf)
1040 if (!seqmappings.contains(acf))
1042 seqmappings.add(acf);
1048 * Resets this object to its initial state by removing all registered
1049 * listeners, codon mappings, PDB file mappings
1051 public void resetAll()
1053 if (mappings != null)
1057 if (seqmappings != null)
1059 seqmappings.clear();
1061 if (sel_listeners != null)
1063 sel_listeners.clear();
1065 if (listeners != null)
1069 if (commandListeners != null)
1071 commandListeners.clear();
1073 if (view_listeners != null)
1075 view_listeners.clear();
1077 if (pdbFileNameId != null)
1079 pdbFileNameId.clear();
1081 if (pdbIdFileName != null)
1083 pdbIdFileName.clear();
1087 public void addSelectionListener(SelectionListener selecter)
1089 if (!sel_listeners.contains(selecter))
1091 sel_listeners.add(selecter);
1095 public void removeSelectionListener(SelectionListener toremove)
1097 if (sel_listeners.contains(toremove))
1099 sel_listeners.remove(toremove);
1103 public synchronized void sendSelection(
1104 jalview.datamodel.SequenceGroup selection,
1105 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1107 for (SelectionListener slis : sel_listeners)
1111 slis.selection(selection, colsel, source);
1116 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1118 public synchronized void sendViewPosition(
1119 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1120 int startSeq, int endSeq)
1123 if (view_listeners != null && view_listeners.size() > 0)
1125 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1127 while (listeners.hasMoreElements())
1129 AlignmentViewPanelListener slis = listeners.nextElement();
1132 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1140 * release all references associated with this manager provider
1142 * @param jalviewLite
1144 public static void release(StructureSelectionManagerProvider jalviewLite)
1146 // synchronized (instances)
1148 if (instances == null)
1152 StructureSelectionManager mnger = (instances.get(jalviewLite));
1155 instances.remove(jalviewLite);
1159 } catch (Throwable x)
1166 public void registerPDBEntry(PDBEntry pdbentry)
1168 if (pdbentry.getFile() != null
1169 && pdbentry.getFile().trim().length() > 0)
1171 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1175 public void addCommandListener(CommandListener cl)
1177 if (!commandListeners.contains(cl))
1179 commandListeners.add(cl);
1183 public boolean hasCommandListener(CommandListener cl)
1185 return this.commandListeners.contains(cl);
1188 public boolean removeCommandListener(CommandListener l)
1190 return commandListeners.remove(l);
1194 * Forward a command to any command listeners (except for the command's
1198 * the command to be broadcast (in its form after being performed)
1200 * if true, the command was being 'undone'
1203 public void commandPerformed(CommandI command, boolean undo,
1204 VamsasSource source)
1206 for (CommandListener listener : commandListeners)
1208 listener.mirrorCommand(command, undo, this, source);
1213 * Returns a new CommandI representing the given command as mapped to the
1214 * given sequences. If no mapping could be made, or the command is not of a
1215 * mappable kind, returns null.
1223 public CommandI mapCommand(CommandI command, boolean undo,
1224 final AlignmentI mapTo, char gapChar)
1226 if (command instanceof EditCommand)
1228 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1229 mapTo, gapChar, seqmappings);
1231 else if (command instanceof OrderCommand)
1233 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1234 mapTo, seqmappings);
1239 public IProgressIndicator getProgressIndicator()
1241 return progressIndicator;
1244 public void setProgressIndicator(IProgressIndicator progressIndicator)
1246 this.progressIndicator = progressIndicator;
1249 public long getProgressSessionId()
1251 return progressSessionId;
1254 public void setProgressSessionId(long progressSessionId)
1256 this.progressSessionId = progressSessionId;
1259 public void setProgressBar(String message)
1261 progressIndicator.setProgressBar(message, progressSessionId);